From bac41a7b9a0a9254fa30f8bb6e6038ab71a483e2 Mon Sep 17 00:00:00 2001
From: Apple <opensource@apple.com>
Date: Tue, 11 Sep 2001 00:42:18 +0000
Subject: [PATCH] Security-28.tar.gz

---
 APPLE_LICENSE                                 |   372 +
 AppleCSP/AES/aescsp.cpp                       |   241 +
 AppleCSP/AES/aescspi.h                        |   101 +
 AppleCSP/AES/boxes-ref.c                      |   228 +
 AppleCSP/AES/boxes-ref.h                      |    51 +
 AppleCSP/AES/rijndael-alg-ref.c               |   606 +
 AppleCSP/AES/rijndael-alg-ref.h               |    85 +
 AppleCSP/AES/rijndaelApi.c                    |   268 +
 AppleCSP/AES/rijndaelApi.h                    |   116 +
 AppleCSP/AES/vRijndael-alg-ref.c              |   684 +
 AppleCSP/AppleCSP.pbxproj/.cvsignore          |     1 +
 AppleCSP/AppleCSP.pbxproj/project.pbxproj     |  2061 +++
 AppleCSP/AppleCSP/.cvsignore                  |     1 +
 AppleCSP/AppleCSP/AppleCSP.cpp                |   684 +
 AppleCSP/AppleCSP/AppleCSP.h                  |    86 +
 AppleCSP/AppleCSP/AppleCSPContext.cpp         |   254 +
 AppleCSP/AppleCSP/AppleCSPContext.h           |   179 +
 AppleCSP/AppleCSP/AppleCSPSession.h           |   238 +
 AppleCSP/AppleCSP/AppleCSPUtils.cpp           |   561 +
 AppleCSP/AppleCSP/AppleCSPUtils.h             |   175 +
 AppleCSP/AppleCSP/BinaryKey.h                 |    89 +
 AppleCSP/AppleCSP/BlockCryptor.cpp            |   609 +
 AppleCSP/AppleCSP/BlockCryptor.h              |   181 +
 AppleCSP/AppleCSP/DigestObject.h              |    62 +
 AppleCSP/AppleCSP/NullDigest.h                |    75 +
 AppleCSP/AppleCSP/RawSigner.h                 |    95 +
 AppleCSP/AppleCSP/SignatureContext.cpp        |   128 +
 AppleCSP/AppleCSP/SignatureContext.h          |    83 +
 AppleCSP/AppleCSP/YarrowConnection.cpp        |    48 +
 AppleCSP/AppleCSP/YarrowConnection.h          |    46 +
 AppleCSP/AppleCSP/cspdebugging.c              |    83 +
 AppleCSP/AppleCSP/cspdebugging.h              |   160 +
 AppleCSP/AppleCSP/cssmplugin.exp              |     4 +
 AppleCSP/AppleCSP/deriveKey.cpp               |   218 +
 AppleCSP/AppleCSP/pkcs_7_8.cpp                |   324 +
 AppleCSP/AppleCSP/pkcs_7_8.h                  |    81 +
 AppleCSP/AppleCSP/rotty.mcp                   |   Bin 0 -> 85911 bytes
 AppleCSP/AppleCSP/wrapKey.cpp                 |   601 +
 AppleCSP/AppleCSP/wrapKeyCms.cpp              |   466 +
 AppleCSP/AppleCSPPlugin.cpp                   |    31 +
 AppleCSP/BSafeCSP/algmaker.cpp                |   333 +
 AppleCSP/BSafeCSP/bsafeAsymmetric.cpp         |    87 +
 AppleCSP/BSafeCSP/bsafeContext.cpp            |   448 +
 AppleCSP/BSafeCSP/bsafeKeyGen.cpp             |   449 +
 AppleCSP/BSafeCSP/bsafePKCS1.cpp              |   137 +
 AppleCSP/BSafeCSP/bsafePKCS1.h                |    73 +
 AppleCSP/BSafeCSP/bsafeSymmetric.cpp          |   289 +
 AppleCSP/BSafeCSP/bsafecsp.h                  |    58 +
 AppleCSP/BSafeCSP/bsafecspi.h                 |   453 +
 AppleCSP/BSafeCSP/bsobjects.h                 |    64 +
 AppleCSP/BSafeCSP/memory.cpp                  |    53 +
 AppleCSP/BSafeCSP/miscalgorithms.cpp          |   152 +
 AppleCSP/BSafeCSP/test/t-dsa.cpp              |   143 +
 AppleCSP/BSafeCSP/test/t-rsa.cpp              |   129 +
 AppleCSP/BSafeCSP/test/t.cpp                  |   113 +
 AppleCSP/CVSVersionInfo.txt                   |     5 +
 AppleCSP/ComCryption/ascContext.cpp           |   347 +
 AppleCSP/ComCryption/ascContext.h             |    61 +
 AppleCSP/ComCryption/ascFactory.h             |    34 +
 AppleCSP/CryptKit/.cvsignore                  |     2 +
 AppleCSP/CryptKit/ByteRep.txt                 |   293 +
 AppleCSP/CryptKitCSP/CryptKitDER.cpp          |   765 +
 AppleCSP/CryptKitCSP/CryptKitSpace.h          |    37 +
 AppleCSP/CryptKitCSP/FEEAsymmetricContext.cpp |   439 +
 AppleCSP/CryptKitCSP/FEEAsymmetricContext.h   |   126 +
 AppleCSP/CryptKitCSP/FEECSPUtils.cpp          |   248 +
 AppleCSP/CryptKitCSP/FEECSPUtils.h            |    92 +
 AppleCSP/CryptKitCSP/FEEKeys.cpp              |   306 +
 AppleCSP/CryptKitCSP/FEEKeys.h                |   102 +
 AppleCSP/CryptKitCSP/FEESignatureObject.cpp   |   242 +
 AppleCSP/CryptKitCSP/FEESignatureObject.h     |   147 +
 AppleCSP/CryptKitCSP/cryptkitcsp.cpp          |   154 +
 AppleCSP/CryptKitCSP/cryptkitcsp.h            |    59 +
 AppleCSP/MiscCSPAlgs/DES.c                    |   542 +
 AppleCSP/MiscCSPAlgs/DES.h                    |    65 +
 AppleCSP/MiscCSPAlgs/DigestContext.cpp        |    49 +
 AppleCSP/MiscCSPAlgs/DigestContext.h          |    51 +
 AppleCSP/MiscCSPAlgs/MD2Object.cpp            |    55 +
 AppleCSP/MiscCSPAlgs/MD2Object.h              |    46 +
 AppleCSP/MiscCSPAlgs/MD5.c                    |   365 +
 AppleCSP/MiscCSPAlgs/MD5.h                    |    67 +
 AppleCSP/MiscCSPAlgs/MacContext.cpp           |   173 +
 AppleCSP/MiscCSPAlgs/MacContext.h             |    87 +
 AppleCSP/MiscCSPAlgs/SHA1.c                   |   168 +
 AppleCSP/MiscCSPAlgs/SHA1.h                   |    69 +
 AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.cpp      |   134 +
 AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.h        |    68 +
 AppleCSP/MiscCSPAlgs/SHA1_priv.c              |   316 +
 AppleCSP/MiscCSPAlgs/SHA1_priv.h              |    54 +
 AppleCSP/MiscCSPAlgs/desContext.cpp           |   214 +
 AppleCSP/MiscCSPAlgs/desContext.h             |    93 +
 AppleCSP/MiscCSPAlgs/miscAlgFactory.cpp       |   281 +
 AppleCSP/MiscCSPAlgs/miscAlgFactory.h         |    47 +
 AppleCSP/MiscCSPAlgs/platform.h               |    61 +
 AppleCSP/MiscCSPAlgs/rc2Context.cpp           |   122 +
 AppleCSP/MiscCSPAlgs/rc2Context.h             |    57 +
 AppleCSP/MiscCSPAlgs/rc4Context.cpp           |    95 +
 AppleCSP/MiscCSPAlgs/rc4Context.h             |    62 +
 AppleCSP/MiscCSPAlgs/rc5Context.cpp           |   120 +
 AppleCSP/MiscCSPAlgs/rc5Context.h             |    56 +
 AppleCSP/PBKDF2/HMACSHA1.c                    |   144 +
 AppleCSP/PBKDF2/HMACSHA1.h                    |    75 +
 AppleCSP/PBKDF2/pbkdf2.c                      |   105 +
 AppleCSP/PBKDF2/pbkdf2.h                      |    79 +
 AppleCSP/RSA_DSA/RSA_DSA_csp.cpp              |   195 +
 AppleCSP/RSA_DSA/RSA_DSA_csp.h                |    53 +
 AppleCSP/RSA_DSA/RSA_DSA_keys.cpp             |   578 +
 AppleCSP/RSA_DSA/RSA_DSA_keys.h               |   190 +
 AppleCSP/RSA_DSA/RSA_DSA_signature.cpp        |   348 +
 AppleCSP/RSA_DSA/RSA_DSA_signature.h          |   131 +
 AppleCSP/RSA_DSA/RSA_DSA_utils.cpp            |   365 +
 AppleCSP/RSA_DSA/RSA_DSA_utils.h              |   107 +
 AppleCSP/RSA_DSA/RSA_asymmetric.cpp           |   167 +
 AppleCSP/RSA_DSA/RSA_asymmetric.h             |    70 +
 AppleCSP/TODO                                 |     1 +
 AppleCSP/open_ssl/bio/bio_lib.c               |   552 +
 AppleCSP/open_ssl/bio/bss_file.c              |   328 +
 AppleCSP/open_ssl/bn/bn_add.c                 |   325 +
 AppleCSP/open_ssl/bn/bn_asm.c                 |   855 +
 AppleCSP/open_ssl/bn/bn_blind.c               |   162 +
 AppleCSP/open_ssl/bn/bn_ctx.c                 |   162 +
 AppleCSP/open_ssl/bn/bn_div.c                 |   398 +
 AppleCSP/open_ssl/bn/bn_err.c                 |   137 +
 AppleCSP/open_ssl/bn/bn_exp.c                 |   767 +
 AppleCSP/open_ssl/bn/bn_exp2.c                |   217 +
 AppleCSP/open_ssl/bn/bn_gcd.c                 |   228 +
 AppleCSP/open_ssl/bn/bn_lcl.h                 |   339 +
 AppleCSP/open_ssl/bn/bn_lib.c                 |   776 +
 AppleCSP/open_ssl/bn/bn_mont.c                |   357 +
 AppleCSP/open_ssl/bn/bn_mpi.c                 |   147 +
 AppleCSP/open_ssl/bn/bn_mul.c                 |   812 +
 AppleCSP/open_ssl/bn/bn_prime.c               |   483 +
 AppleCSP/open_ssl/bn/bn_prime.h               |   343 +
 AppleCSP/open_ssl/bn/bn_print.c               |   350 +
 AppleCSP/open_ssl/bn/bn_rand.c                |   159 +
 AppleCSP/open_ssl/bn/bn_recp.c                |   238 +
 AppleCSP/open_ssl/bn/bn_shift.c               |   218 +
 AppleCSP/open_ssl/bn/bn_sqr.c                 |   306 +
 AppleCSP/open_ssl/bn/bn_word.c                |   212 +
 AppleCSP/open_ssl/bn/bnspeed.c                |   251 +
 AppleCSP/open_ssl/bn/bntest.c                 |  1096 ++
 AppleCSP/open_ssl/bn/divtest.c                |    59 +
 AppleCSP/open_ssl/bn/exp.c                    |    80 +
 AppleCSP/open_ssl/bn/expspeed.c               |   233 +
 AppleCSP/open_ssl/bn/exptest.c                |   205 +
 AppleCSP/open_ssl/bn/vms-helper.c             |    84 +
 AppleCSP/open_ssl/buffer/buf_err.c            |   113 +
 AppleCSP/open_ssl/buffer/buffer.c             |   162 +
 AppleCSP/open_ssl/cryptlib.c                  |   350 +
 AppleCSP/open_ssl/cryptlib.h                  |   114 +
 AppleCSP/open_ssl/dsa/dsa_asn1.c              |   120 +
 AppleCSP/open_ssl/dsa/dsa_err.c               |   124 +
 AppleCSP/open_ssl/dsa/dsa_gen.c               |   312 +
 AppleCSP/open_ssl/dsa/dsa_key.c               |   129 +
 AppleCSP/open_ssl/dsa/dsa_lib.c               |   266 +
 AppleCSP/open_ssl/dsa/dsa_ossl.c              |   339 +
 AppleCSP/open_ssl/dsa/dsa_sign.c              |   112 +
 AppleCSP/open_ssl/dsa/dsa_vrf.c               |   114 +
 AppleCSP/open_ssl/err/err.c                   |   781 +
 AppleCSP/open_ssl/err/err_prn.c               |   123 +
 AppleCSP/open_ssl/ex_data.c                   |   241 +
 AppleCSP/open_ssl/lhash/lhash.c               |   479 +
 AppleCSP/open_ssl/mem.c                       |   279 +
 AppleCSP/open_ssl/misc/md2_dgst.c             |   223 +
 AppleCSP/open_ssl/misc/rc2_cbc.c              |   256 +
 AppleCSP/open_ssl/misc/rc2_locl.h             |   174 +
 AppleCSP/open_ssl/misc/rc2_skey.c             |   156 +
 AppleCSP/open_ssl/misc/rc4_enc.c              |   332 +
 AppleCSP/open_ssl/misc/rc4_skey.c             |   140 +
 AppleCSP/open_ssl/misc/rc5_enc.c              |   243 +
 AppleCSP/open_ssl/misc/rc5_locl.h             |   205 +
 AppleCSP/open_ssl/misc/rc5_skey.c             |   131 +
 AppleCSP/open_ssl/openssl/asn1.h              |  1085 ++
 AppleCSP/open_ssl/openssl/bio.h               |   685 +
 AppleCSP/open_ssl/openssl/bn.h                |   530 +
 AppleCSP/open_ssl/openssl/buffer.h            |   116 +
 AppleCSP/open_ssl/openssl/crypto.h            |   391 +
 AppleCSP/open_ssl/openssl/dsa.h               |   259 +
 AppleCSP/open_ssl/openssl/e_os.h              |   464 +
 AppleCSP/open_ssl/openssl/e_os2.h             |    56 +
 AppleCSP/open_ssl/openssl/err.h               |   285 +
 AppleCSP/open_ssl/openssl/evp.h               |   761 +
 AppleCSP/open_ssl/openssl/lhash.h             |   163 +
 AppleCSP/open_ssl/openssl/md2.h               |    91 +
 AppleCSP/open_ssl/openssl/objects.h           |  1050 ++
 AppleCSP/open_ssl/openssl/openssl_pkcs7.h     |   516 +
 AppleCSP/open_ssl/openssl/opensslconf.h       |    93 +
 AppleCSP/open_ssl/openssl/opensslv.h          |    50 +
 AppleCSP/open_ssl/openssl/rand.h              |   135 +
 AppleCSP/open_ssl/openssl/rc2.h               |   123 +
 AppleCSP/open_ssl/openssl/rc4.h               |   109 +
 AppleCSP/open_ssl/openssl/rc5.h               |   150 +
 AppleCSP/open_ssl/openssl/rsa.h               |   356 +
 AppleCSP/open_ssl/openssl/safestack.h         |   147 +
 AppleCSP/open_ssl/openssl/sha.h               |   137 +
 AppleCSP/open_ssl/openssl/stack.h             |   125 +
 AppleCSP/open_ssl/openssl/x509.h              |  1222 ++
 AppleCSP/open_ssl/openssl/x509_vfy.h          |   380 +
 .../open_ssl/opensslUtils/openRsaSnacc.cpp    |   637 +
 AppleCSP/open_ssl/opensslUtils/openRsaSnacc.h |   105 +
 .../open_ssl/opensslUtils/opensslUtils.cpp    |   119 +
 AppleCSP/open_ssl/opensslUtils/opensslUtils.h |    54 +
 AppleCSP/open_ssl/rsa/rsa_chk.c               |   202 +
 AppleCSP/open_ssl/rsa/rsa_eay.c               |   513 +
 AppleCSP/open_ssl/rsa/rsa_err.c               |   166 +
 AppleCSP/open_ssl/rsa/rsa_gen.c               |   215 +
 AppleCSP/open_ssl/rsa/rsa_lib.c               |   351 +
 AppleCSP/open_ssl/rsa/rsa_none.c              |   116 +
 AppleCSP/open_ssl/rsa/rsa_null.c              |   167 +
 AppleCSP/open_ssl/rsa/rsa_pk1.c               |   242 +
 AppleCSP/open_ssl/rsa/rsa_saos.c              |   162 +
 AppleCSP/open_ssl/rsa/rsa_sign.c              |   239 +
 AppleCSP/open_ssl/rsa/rsa_ssl.c               |   172 +
 AppleCSP/open_ssl/stack/stack.c               |   329 +
 AppleCSPDL/AppleCSPDL.pbproj/.cvsignore       |     1 +
 AppleCSPDL/AppleCSPDL.pbproj/project.pbxproj  |   481 +
 AppleCSPDL/AppleCSPDLPlugin.cpp               |    31 +
 AppleCSPDL/CSPDLDatabase.cpp                  |    36 +
 AppleCSPDL/CSPDLDatabase.h                    |    40 +
 AppleCSPDL/CSPDLPlugin.cpp                    |    76 +
 AppleCSPDL/CSPDLPlugin.h                      |    55 +
 AppleCSPDL/CVSVersionInfo.txt                 |     5 +
 AppleCSPDL/KeySchema.h                        |    64 +
 AppleCSPDL/KeySchema.m4                       |   137 +
 AppleCSPDL/SSCSPDLSession.cpp                 |    62 +
 AppleCSPDL/SSCSPDLSession.h                   |    53 +
 AppleCSPDL/SSCSPSession.cpp                   |   490 +
 AppleCSPDL/SSCSPSession.h                     |   165 +
 AppleCSPDL/SSContext.cpp                      |   282 +
 AppleCSPDL/SSContext.h                        |   137 +
 AppleCSPDL/SSDLSession.cpp                    |   620 +
 AppleCSPDL/SSDLSession.h                      |   157 +
 AppleCSPDL/SSDatabase.cpp                     |   212 +
 AppleCSPDL/SSDatabase.h                       |   128 +
 AppleCSPDL/SSFactory.cpp                      |    77 +
 AppleCSPDL/SSFactory.h                        |    39 +
 AppleCSPDL/SSKey.cpp                          |   337 +
 AppleCSPDL/SSKey.h                            |    78 +
 AppleCSPDL/cssmplugin.exp                     |     4 +
 AppleDL/.cvsignore                            |     1 +
 AppleDL/AppleCSPDL.mcp                        |   Bin 0 -> 28375 bytes
 AppleDL/AppleDL.pbxproj/.cvsignore            |     1 +
 AppleDL/AppleDL.pbxproj/project.pbxproj       |   247 +
 AppleDL/AppleDLPlugin.cpp                     |    31 +
 AppleDL/AppleFileDL.cpp                       |    81 +
 AppleDL/AppleFileDL.h                         |    46 +
 AppleDL/CVSVersionInfo.txt                    |     5 +
 AppleDL/FORMAT                                |   153 +
 AppleDL/ISSUES                                |    61 +
 AppleDL/TODO                                  |    49 +
 AppleDL/cssmplugin.exp                        |     4 +
 AppleX509CL/.cvsignore                        |     2 +
 AppleX509CL/AppleX509CL.cpp                   |    63 +
 AppleX509CL/AppleX509CL.h                     |    48 +
 AppleX509CL/AppleX509CL.mcp                   |   Bin 0 -> 103293 bytes
 .../AppleX509CL.pbproj/project.pbxproj        |   531 +
 AppleX509CL/AppleX509CLPlugin.cpp             |    31 +
 AppleX509CL/AppleX509CLSession.cpp            |    87 +
 AppleX509CL/AppleX509CLSession.h              |   312 +
 AppleX509CL/CLCachedEntry.cpp                 |    67 +
 AppleX509CL/CLCachedEntry.h                   |   129 +
 AppleX509CL/CLCertExtensions.cpp              |  1249 ++
 AppleX509CL/CLCertExtensions.h                |    64 +
 AppleX509CL/CSPAttacher.cpp                   |   179 +
 AppleX509CL/CSPAttacher.h                     |    47 +
 AppleX509CL/CVSVersionInfo.txt                |     5 +
 AppleX509CL/CertBuilder.cpp                   |   133 +
 AppleX509CL/CertBuilder.h                     |    82 +
 AppleX509CL/CertFields.cpp                    |  1291 ++
 AppleX509CL/DecodedCert.cpp                   |   283 +
 AppleX509CL/DecodedCert.h                     |   233 +
 AppleX509CL/LockedMap.h                       |    93 +
 AppleX509CL/Session_CRL.cpp                   |   232 +
 AppleX509CL/Session_Cert.cpp                  |   348 +
 AppleX509CL/Session_Crypto.cpp                |   312 +
 AppleX509CL/SnaccUtils.cpp                    |   834 +
 AppleX509CL/SnaccUtils.h                      |   124 +
 AppleX509CL/TODO                              |     1 +
 AppleX509CL/cldebugging.c                     |    91 +
 AppleX509CL/cldebugging.h                     |   156 +
 AppleX509CL/cssmplugin.exp                    |     4 +
 AppleX509TP/AppleTP.cpp                       |    62 +
 AppleX509TP/AppleTP.h                         |    48 +
 AppleX509TP/AppleTP.pbproj/project.pbxproj    |   445 +
 AppleX509TP/AppleTPSession.cpp                |   243 +
 AppleX509TP/AppleTPSession.h                  |   187 +
 AppleX509TP/AppleX509TPPlugin.cpp             |    31 +
 AppleX509TP/CVSVersionInfo.txt                |     5 +
 AppleX509TP/TPCertInfo.cpp                    |   407 +
 AppleX509TP/TPCertInfo.h                      |   155 +
 AppleX509TP/certGroupUtils.cpp                |   441 +
 AppleX509TP/certGroupUtils.h                  |   135 +
 AppleX509TP/cssmplugin.exp                    |     4 +
 AppleX509TP/iSignRootCerts.c                  |   218 +
 AppleX509TP/rootCerts.h                       |    70 +
 AppleX509TP/sslRootCerts.c                    |  1426 ++
 AppleX509TP/tpCertGroup.cpp                   |   645 +
 AppleX509TP/tpPolicies.cpp                    |   813 +
 AppleX509TP/tpPolicies.h                      |    66 +
 AppleX509TP/tpTime.c                          |   234 +
 AppleX509TP/tpTime.h                          |    62 +
 AppleX509TP/tpdebugging.c                     |    83 +
 AppleX509TP/tpdebugging.h                     |   160 +
 CVSVersionInfo.txt                            |     5 +
 Keychain/CCallbackMgr.cp                      |   313 +
 Keychain/CCallbackMgr.h                       |   120 +
 Keychain/DLDBListCFPref.cpp                   |   274 +
 Keychain/DLDBListCFPref.h                     |   149 +
 Keychain/DefaultKeychain.cpp                  |    97 +
 Keychain/DefaultKeychain.h                    |    88 +
 Keychain/Globals.cpp                          |    50 +
 Keychain/Globals.h                            |    73 +
 Keychain/Item.cpp                             |   959 +
 Keychain/Item.h                               |   162 +
 Keychain/KCCursor.cpp                         |   167 +
 Keychain/KCCursor.h                           |    83 +
 Keychain/KCEventNotifier.cpp                  |    87 +
 Keychain/KCEventNotifier.h                    |    68 +
 Keychain/KCEventObserver.cpp                  |    88 +
 Keychain/KCEventObserver.h                    |    68 +
 Keychain/KCExceptions.h                       |    91 +
 Keychain/KCUtilities.cpp                      |    93 +
 Keychain/KCUtilities.h                        |    70 +
 Keychain/Keychains.cpp                        |   632 +
 Keychain/Keychains.h                          |   205 +
 Keychain/PrimaryKey.cpp                       |   127 +
 Keychain/PrimaryKey.h                         |    68 +
 Keychain/Refs.h                               |   126 +
 Keychain/Schema.h                             |    56 +
 Keychain/Schema.m4                            |   307 +
 Keychain/SecKeychainAPI.cpp                   |   736 +
 Keychain/SecKeychainAPI.h                     |   883 +
 Keychain/SecKeychainAPIPriv.h                 |    73 +
 Keychain/StorageManager.cpp                   |   370 +
 Keychain/StorageManager.h                     |   111 +
 Keychain/cssmdatetime.cpp                     |   262 +
 Keychain/cssmdatetime.h                       |    67 +
 Network/connectionpool.cpp                    |    94 +
 Network/connectionpool.h                      |    59 +
 Network/file-protocol.cpp                     |   139 +
 Network/file-protocol.h                       |    76 +
 Network/ftp-protocol.cpp                      |   566 +
 Network/ftp-protocol.h                        |   192 +
 Network/ftp-proxy-protocol.cpp                |    57 +
 Network/ftp-proxy-protocol.h                  |    59 +
 Network/http-protocol.cpp                     |   511 +
 Network/http-protocol.h                       |   163 +
 Network/http-proxy-protocol.cpp               |    57 +
 Network/http-proxy-protocol.h                 |    56 +
 Network/https-protocol.cpp                    |   208 +
 Network/https-protocol.h                      |   108 +
 Network/https-proxy-protocol.cpp              |   210 +
 Network/https-proxy-protocol.h                |    95 +
 Network/multiobserver.cpp                     |    70 +
 Network/multiobserver.h                       |    63 +
 Network/netconnection.cpp                     |   215 +
 Network/netconnection.h                       |   155 +
 Network/neterror.cpp                          |    41 +
 Network/neterror.h                            |    50 +
 Network/netmanager.cpp                        |   294 +
 Network/netmanager.h                          |   144 +
 Network/netparameters.h                       |    75 +
 Network/networkchooser.cpp                    |    91 +
 Network/networkchooser.h                      |    75 +
 Network/observer.cpp                          |    37 +
 Network/observer.h                            |    84 +
 Network/parameters.cpp                        |    44 +
 Network/parameters.h                          |   120 +
 Network/protocol.cpp                          |    72 +
 Network/protocol.h                            |    76 +
 Network/simplemanager.cpp                     |    55 +
 Network/simplemanager.h                       |    58 +
 Network/target.cpp                            |   116 +
 Network/target.h                              |   101 +
 Network/transfer.cpp                          |   148 +
 Network/transfer.h                            |   148 +
 Network/xfercore.cpp                          |   405 +
 Network/xfercore.h                            |   139 +
 SecureTransport/CVSVersionInfo.txt            |     5 +
 SecureTransport/LICENSE.txt                   |     1 +
 SecureTransport/ModuleAttacher.cpp            |   253 +
 SecureTransport/ModuleAttacher.h              |    48 +
 SecureTransport/README                        |     1 +
 .../SecureTransport.pbproj/project.pbxproj    |  1647 ++
 SecureTransport/SecureTransport/CipherSuite.h |    79 +
 .../SecureTransport/SecureTransport.h         |   573 +
 SecureTransport/appleCdsa.c                   |  1508 ++
 SecureTransport/appleGlue.c                   |   181 +
 SecureTransport/appleSession.c                |    92 +
 SecureTransport/cipherSpecs.c                 |   532 +
 SecureTransport/cppUtils.cpp                  |    36 +
 SecureTransport/digests.c                     |   280 +
 SecureTransport/hdskcert.c                    |   594 +
 SecureTransport/hdskchgc.c                    |   140 +
 SecureTransport/hdskfini.c                    |   250 +
 SecureTransport/hdskhelo.c                    |   375 +
 SecureTransport/hdskkeys.c                    |   545 +
 SecureTransport/hdskkyex.c                    |  1165 ++
 SecureTransport/nullciph.c                    |   105 +
 SecureTransport/privateInc/appleCdsa.h        |   219 +
 SecureTransport/privateInc/appleGlue.h        |    77 +
 SecureTransport/privateInc/appleSession.h     |    65 +
 SecureTransport/privateInc/cipherSpecs.h      |    55 +
 SecureTransport/privateInc/cryptType.h        |   208 +
 SecureTransport/privateInc/digests.h          |    57 +
 SecureTransport/privateInc/ssl.h              |    37 +
 SecureTransport/privateInc/ssl2.h             |   118 +
 SecureTransport/privateInc/sslBER.h           |    69 +
 SecureTransport/privateInc/sslBuildFlags.h    |    82 +
 SecureTransport/privateInc/sslDebug.h         |   212 +
 SecureTransport/privateInc/sslKeychain.h      |   109 +
 SecureTransport/privateInc/sslPriv.h          |    88 +
 SecureTransport/privateInc/sslalert.h         |    82 +
 SecureTransport/privateInc/sslalloc.h         |    93 +
 SecureTransport/privateInc/sslctx.h           |   385 +
 SecureTransport/privateInc/sslerrs.h          |    84 +
 SecureTransport/privateInc/sslhdshk.h         |   166 +
 SecureTransport/privateInc/sslmd5.h           |    82 +
 SecureTransport/privateInc/sslrec.h           |    76 +
 SecureTransport/privateInc/sslsess.h          |    60 +
 SecureTransport/privateInc/ssltrspt.h         |    61 +
 SecureTransport/privateInc/sslutil.h          |    67 +
 SecureTransport/privateInc/st_sha.h           |    53 +
 SecureTransport/privateInc/symCipher.h        |    65 +
 SecureTransport/secureTransport.exp           |    21 +
 SecureTransport/securetransport++.cpp         |   302 +
 SecureTransport/securetransport++.h           |   109 +
 SecureTransport/sha.c                         |   237 +
 SecureTransport/ssl2map.c                     |    62 +
 SecureTransport/ssl2mesg.c                    |   897 +
 SecureTransport/ssl2prot.c                    |   527 +
 SecureTransport/ssl2rec.c                     |   457 +
 SecureTransport/sslBER.cpp                    |   170 +
 SecureTransport/sslDebug.c                    |    94 +
 SecureTransport/sslKeychain.c                 |   563 +
 SecureTransport/sslalert.c                    |   189 +
 SecureTransport/sslalloc.c                    |   190 +
 SecureTransport/sslctx.c                      |   732 +
 SecureTransport/sslhdshk.c                    |   788 +
 SecureTransport/sslmd5.c                      |   354 +
 SecureTransport/sslrec.c                      |   539 +
 SecureTransport/sslsess.c                     |   301 +
 SecureTransport/ssltrspt.c                    |   552 +
 SecureTransport/sslutil.c                     |   157 +
 SecureTransport/symCipher.c                   |   397 +
 Security.exp                                  |    32 +
 Security.pbproj/.cvsignore                    |     2 +
 Security.pbproj/project.pbxproj               | 14900 ++++++++++++++++
 SecurityASN1/CVSVersionInfo.txt               |     5 +
 SecurityASN1/Makefile                         |    63 +
 SecurityASN1/PkcsCms.pbproj/project.pbxproj   |   805 +
 SecurityASN1/asn/appleoids.asn                |   167 +
 SecurityASN1/asn/asn-useful.asn1              |   105 +
 SecurityASN1/asn/pkcs1.asn1                   |   205 +
 SecurityASN1/asn/pkcs1oids.asn                |    46 +
 SecurityASN1/asn/pkcs5.asn1                   |   141 +
 SecurityASN1/asn/pkcs7.asn                    |    63 +
 SecurityASN1/asn/pkcs8.asn                    |    40 +
 SecurityASN1/asn/pkcs9oids.asn                |    19 +
 SecurityASN1/asn/sm_cms.asn                   |   431 +
 SecurityASN1/asn/sm_ess.asn                   |   238 +
 SecurityASN1/asn/sm_vdatypes.asn              |    13 +
 SecurityASN1/asn/sm_x411mtsas.asn             |   158 +
 SecurityASN1/asn/sm_x411ub.asn                |   131 +
 SecurityASN1/asn/sm_x501if.asn                |    48 +
 SecurityASN1/asn/sm_x501ud.asn                |   136 +
 SecurityASN1/asn/sm_x509af.asn                |   215 +
 SecurityASN1/asn/sm_x509ce.asn                |   265 +
 SecurityASN1/asn/sm_x509cmn.asn               |    41 +
 SecurityASN1/asn/sm_x520sa.asn                |   196 +
 SecurityASN1/c++/.cvsignore                   |     1 +
 SecurityASN1/c++/appleoids.cpp                |  2984 ++++
 SecurityASN1/c++/pkcs1oids.cpp                |   593 +
 SecurityASN1/c++/pkcs7.cpp                    |   514 +
 SecurityASN1/c++/pkcs8.cpp                    |   541 +
 SecurityASN1/c++/pkcs9oids.cpp                |    34 +
 SecurityASN1/c++/sm_cms.cpp                   | 10963 ++++++++++++
 SecurityASN1/c++/sm_ess.cpp                   |  6921 +++++++
 SecurityASN1/c++/sm_vdatypes.cpp              |    90 +
 SecurityASN1/c++/sm_x411mtsas.cpp             |  5045 ++++++
 SecurityASN1/c++/sm_x411ub.cpp                |    34 +
 SecurityASN1/c++/sm_x501if.cpp                |  3553 ++++
 SecurityASN1/c++/sm_x501ud.cpp                |    34 +
 SecurityASN1/c++/sm_x509af.cpp                | 10047 +++++++++++
 SecurityASN1/c++/sm_x509ce.cpp                |  7109 ++++++++
 SecurityASN1/c++/sm_x509cmn.cpp               |  1149 ++
 SecurityASN1/c++/sm_x520sa.cpp                |   324 +
 SecurityASN1/inc/.cvsignore                   |     0
 SecurityASN1/inc/appleoids.h                  |   429 +
 SecurityASN1/inc/pkcs1oids.h                  |   110 +
 SecurityASN1/inc/pkcs7.h                      |   117 +
 SecurityASN1/inc/pkcs8.h                      |    84 +
 SecurityASN1/inc/pkcs9oids.h                  |    45 +
 SecurityASN1/inc/sm_cms.h                     |  1544 ++
 SecurityASN1/inc/sm_ess.h                     |  1096 ++
 SecurityASN1/inc/sm_vdatypes.h                |    48 +
 SecurityASN1/inc/sm_x411mtsas.h               |   696 +
 SecurityASN1/inc/sm_x411ub.h                  |   139 +
 SecurityASN1/inc/sm_x501if.h                  |   543 +
 SecurityASN1/inc/sm_x501ud.h                  |   133 +
 SecurityASN1/inc/sm_x509af.h                  |  1252 ++
 SecurityASN1/inc/sm_x509ce.h                  |  1098 ++
 SecurityASN1/inc/sm_x509cmn.h                 |   171 +
 SecurityASN1/inc/sm_x520sa.h                  |   334 +
 SecuritySNACCRuntime/.cvsignore               |     1 +
 SecuritySNACCRuntime/Apple_README             |    44 +
 SecuritySNACCRuntime/COPYING                  |   339 +
 SecuritySNACCRuntime/CVSVersionInfo.txt       |     5 +
 SecuritySNACCRuntime/ChangeLog                |   761 +
 SecuritySNACCRuntime/INSTALL                  |   146 +
 SecuritySNACCRuntime/MacOSX-Install           |    13 +
 SecuritySNACCRuntime/MacOSX-configure         |     6 +
 SecuritySNACCRuntime/MacOSX-make              |    12 +
 SecuritySNACCRuntime/NEWS                     |   160 +
 SecuritySNACCRuntime/README                   |   230 +
 SecuritySNACCRuntime/VDADER_RULES.TXT         |    24 +
 SecuritySNACCRuntime/acconfig.h               |    79 +
 SecuritySNACCRuntime/asn1specs/any.asn1       |   116 +
 .../asn1specs/asn-useful.asn1                 |    99 +
 .../asn1specs/asn1module.asn1                 |   673 +
 SecuritySNACCRuntime/asn1specs/err-test.asn1  |   237 +
 SecuritySNACCRuntime/asn1specs/ex1.asn1       |    40 +
 SecuritySNACCRuntime/asn1specs/install-sh     |   238 +
 SecuritySNACCRuntime/asn1specs/makefile       |    47 +
 SecuritySNACCRuntime/asn1specs/p-rec.asn1     |    56 +
 .../asn1specs/rfc1155-smi.asn1                |   155 +
 .../asn1specs/rfc1157-snmp.asn1               |   166 +
 .../asn1specs/rfc1213-mib2.asn1               |  2663 +++
 SecuritySNACCRuntime/asn1specs/tbl.asn1       |   171 +
 SecuritySNACCRuntime/c++-examples/any/README  |    96 +
 .../c++-examples/any/example.C                |   142 +
 .../c++-examples/any/genber.C                 |   220 +
 .../c++-examples/any/makefile                 |   169 +
 SecuritySNACCRuntime/c++-examples/makefile    |    36 +
 .../c++-examples/simple/README                |   111 +
 .../c++-examples/simple/example.C             |   142 +
 .../c++-examples/simple/genber.C              |   126 +
 .../c++-examples/simple/good-pr.ber           |   Bin 0 -> 145 bytes
 .../c++-examples/simple/makefile              |   158 +
 SecuritySNACCRuntime/c++-examples/snmp/README |   132 +
 .../c++-examples/snmp/makefile                |   115 +
 .../c++-examples/test-lib/README              |    43 +
 .../c++-examples/test-lib/makefile            |    68 +
 .../c++-examples/test-lib/test-lib.C          |   815 +
 SecuritySNACCRuntime/c++-lib/README           |    34 +
 SecuritySNACCRuntime/c++-lib/c++/asn-any.cpp  |   330 +
 SecuritySNACCRuntime/c++-lib/c++/asn-bits.cpp |   579 +
 SecuritySNACCRuntime/c++-lib/c++/asn-bool.cpp |   197 +
 SecuritySNACCRuntime/c++-lib/c++/asn-enum.cpp |   171 +
 SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp  |   279 +
 SecuritySNACCRuntime/c++-lib/c++/asn-len.cpp  |   214 +
 SecuritySNACCRuntime/c++-lib/c++/asn-list.cpp |   376 +
 SecuritySNACCRuntime/c++-lib/c++/asn-null.cpp |   171 +
 SecuritySNACCRuntime/c++-lib/c++/asn-octs.cpp |   496 +
 SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp  |   465 +
 SecuritySNACCRuntime/c++-lib/c++/asn-real.cpp |   933 +
 SecuritySNACCRuntime/c++-lib/c++/asn-tag.cpp  |   129 +
 SecuritySNACCRuntime/c++-lib/c++/asn-type.cpp |   199 +
 .../c++-lib/c++/asn-useful.cpp                |  1491 ++
 SecuritySNACCRuntime/c++-lib/c++/hash.cpp     |   291 +
 SecuritySNACCRuntime/c++-lib/c++/meta.cpp     |   464 +
 SecuritySNACCRuntime/c++-lib/c++/print.cpp    |   109 +
 SecuritySNACCRuntime/c++-lib/c++/str-stk.cpp  |   142 +
 SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp   |  1103 ++
 SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c  |   139 +
 SecuritySNACCRuntime/c++-lib/dependencies     |   792 +
 SecuritySNACCRuntime/c++-lib/inc/asn-any.h    |   203 +
 SecuritySNACCRuntime/c++-lib/inc/asn-bits.h   |   188 +
 SecuritySNACCRuntime/c++-lib/inc/asn-bool.h   |   177 +
 SecuritySNACCRuntime/c++-lib/inc/asn-buf.h    |   216 +
 SecuritySNACCRuntime/c++-lib/inc/asn-config.h |   213 +
 SecuritySNACCRuntime/c++-lib/inc/asn-enum.h   |   118 +
 SecuritySNACCRuntime/c++-lib/inc/asn-incl.h   |   121 +
 SecuritySNACCRuntime/c++-lib/inc/asn-int.h    |   124 +
 SecuritySNACCRuntime/c++-lib/inc/asn-len.h    |   130 +
 SecuritySNACCRuntime/c++-lib/inc/asn-list.h   |   197 +
 SecuritySNACCRuntime/c++-lib/inc/asn-null.h   |   111 +
 SecuritySNACCRuntime/c++-lib/inc/asn-octs.h   |   194 +
 SecuritySNACCRuntime/c++-lib/inc/asn-oid.h    |   194 +
 SecuritySNACCRuntime/c++-lib/inc/asn-real.h   |   132 +
 SecuritySNACCRuntime/c++-lib/inc/asn-tag.h    |   273 +
 SecuritySNACCRuntime/c++-lib/inc/asn-type.h   |   172 +
 SecuritySNACCRuntime/c++-lib/inc/asn-useful.h |   480 +
 SecuritySNACCRuntime/c++-lib/inc/cdsaUtils.h  |    77 +
 SecuritySNACCRuntime/c++-lib/inc/config.h     |   182 +
 SecuritySNACCRuntime/c++-lib/inc/hash.h       |   106 +
 SecuritySNACCRuntime/c++-lib/inc/init.h       |    48 +
 SecuritySNACCRuntime/c++-lib/inc/meta.h       |   284 +
 SecuritySNACCRuntime/c++-lib/inc/policy.h     |    45 +
 SecuritySNACCRuntime/c++-lib/inc/print.h      |    88 +
 .../c++-lib/inc/sm_vdasnacc.h                 |   389 +
 .../c++-lib/inc/sm_vdatypes.h                 |    66 +
 SecuritySNACCRuntime/c++-lib/inc/snacc.h      |   215 +
 SecuritySNACCRuntime/c++-lib/inc/str-stk.h    |   107 +
 SecuritySNACCRuntime/c++-lib/inc/tcl-if.h     |   117 +
 SecuritySNACCRuntime/c++-lib/install-sh       |   238 +
 SecuritySNACCRuntime/c++-lib/makefile         |   326 +
 .../c++-lib/src/asn-useful.cpp                |  1487 ++
 .../c++-lib/src/cdsaUtils.cpp                 |   190 +
 .../c++-lib/src/sm_buffer.cpp                 |   896 +
 .../c++-lib/src/sm_vdasnacc.cpp               |   560 +
 SecuritySNACCRuntime/c++-lib/src/tkAppInit.c  |   136 +
 SecuritySNACCRuntime/c++-lib/stamp-useful     |     1 +
 SecuritySNACCRuntime/c-examples/any/README    |   113 +
 SecuritySNACCRuntime/c-examples/any/example.c |   188 +
 SecuritySNACCRuntime/c-examples/any/genber.c  |   191 +
 SecuritySNACCRuntime/c-examples/any/makefile  |   150 +
 SecuritySNACCRuntime/c-examples/makefile      |    53 +
 SecuritySNACCRuntime/c-examples/simple/README |   134 +
 .../c-examples/simple/expbuf-ex.c             |   196 +
 .../c-examples/simple/genber.c                |   181 +
 .../c-examples/simple/good-pr.ber             |   Bin 0 -> 145 bytes
 .../c-examples/simple/makefile                |   204 +
 .../c-examples/simple/minbuf-ex.c             |   189 +
 .../c-examples/simple/sbuf-ex.c               |   181 +
 SecuritySNACCRuntime/c-examples/snmp/README   |   124 +
 SecuritySNACCRuntime/c-examples/snmp/makefile |    97 +
 .../c-examples/test-lib/README                |    43 +
 .../c-examples/test-lib/makefile              |    56 +
 .../c-examples/test-lib/test-lib.c            |   962 +
 SecuritySNACCRuntime/c-lib/.cvsignore         |     5 +
 SecuritySNACCRuntime/c-lib/README             |    36 +
 SecuritySNACCRuntime/c-lib/asn-useful.c       |   892 +
 SecuritySNACCRuntime/c-lib/asn-useful.h       |   343 +
 SecuritySNACCRuntime/c-lib/boot/asn-useful.c  |   799 +
 SecuritySNACCRuntime/c-lib/boot/asn-useful.h  |   295 +
 SecuritySNACCRuntime/c-lib/boot/tbl.c         |  2137 +++
 SecuritySNACCRuntime/c-lib/boot/tbl.h         |   362 +
 SecuritySNACCRuntime/c-lib/dependencies       |  2011 +++
 SecuritySNACCRuntime/c-lib/inc/asn-any.h      |   149 +
 SecuritySNACCRuntime/c-lib/inc/asn-bits.h     |    96 +
 SecuritySNACCRuntime/c-lib/inc/asn-bool.h     |    73 +
 SecuritySNACCRuntime/c-lib/inc/asn-config.h   |   248 +
 SecuritySNACCRuntime/c-lib/inc/asn-enum.h     |    76 +
 SecuritySNACCRuntime/c-lib/inc/asn-incl.h     |    69 +
 SecuritySNACCRuntime/c-lib/inc/asn-int.h      |   111 +
 SecuritySNACCRuntime/c-lib/inc/asn-len.h      |   141 +
 SecuritySNACCRuntime/c-lib/inc/asn-list.h     |   160 +
 SecuritySNACCRuntime/c-lib/inc/asn-null.h     |    75 +
 SecuritySNACCRuntime/c-lib/inc/asn-octs.h     |    86 +
 SecuritySNACCRuntime/c-lib/inc/asn-oid.h      |    99 +
 SecuritySNACCRuntime/c-lib/inc/asn-real.h     |    79 +
 SecuritySNACCRuntime/c-lib/inc/asn-tag.h      |   260 +
 SecuritySNACCRuntime/c-lib/inc/asn-useful.h   |   343 +
 SecuritySNACCRuntime/c-lib/inc/exp-buf.h      |   168 +
 SecuritySNACCRuntime/c-lib/inc/gen-buf.h      |   110 +
 SecuritySNACCRuntime/c-lib/inc/hash.h         |    89 +
 SecuritySNACCRuntime/c-lib/inc/mem.h          |    61 +
 SecuritySNACCRuntime/c-lib/inc/min-buf.h      |   100 +
 SecuritySNACCRuntime/c-lib/inc/nibble-alloc.h |    86 +
 SecuritySNACCRuntime/c-lib/inc/print.h        |    62 +
 SecuritySNACCRuntime/c-lib/inc/sbuf.h         |   249 +
 SecuritySNACCRuntime/c-lib/inc/str-stk.h      |   135 +
 SecuritySNACCRuntime/c-lib/inc/tbl-dbg.h      |    29 +
 SecuritySNACCRuntime/c-lib/inc/tbl-dec.h      |    57 +
 SecuritySNACCRuntime/c-lib/inc/tbl-enc.h      |    56 +
 SecuritySNACCRuntime/c-lib/inc/tbl-free.h     |    57 +
 .../c-lib/inc/tbl-gen-c-hdr.h                 |    55 +
 SecuritySNACCRuntime/c-lib/inc/tbl-gen.h      |    42 +
 SecuritySNACCRuntime/c-lib/inc/tbl-incl.h     |    79 +
 SecuritySNACCRuntime/c-lib/inc/tbl-print.h    |    57 +
 SecuritySNACCRuntime/c-lib/inc/tbl-util.h     |    75 +
 SecuritySNACCRuntime/c-lib/inc/tbl.h          |   362 +
 SecuritySNACCRuntime/c-lib/install-sh         |   238 +
 SecuritySNACCRuntime/c-lib/makefile           |   401 +
 SecuritySNACCRuntime/c-lib/src/asn-any.c      |   269 +
 SecuritySNACCRuntime/c-lib/src/asn-bits.c     |   450 +
 SecuritySNACCRuntime/c-lib/src/asn-bool.c     |   157 +
 SecuritySNACCRuntime/c-lib/src/asn-enum.c     |   101 +
 SecuritySNACCRuntime/c-lib/src/asn-int.c      |   399 +
 SecuritySNACCRuntime/c-lib/src/asn-len.c      |   233 +
 SecuritySNACCRuntime/c-lib/src/asn-list.c     |   486 +
 SecuritySNACCRuntime/c-lib/src/asn-null.c     |   133 +
 SecuritySNACCRuntime/c-lib/src/asn-octs.c     |   338 +
 SecuritySNACCRuntime/c-lib/src/asn-oid.c      |   348 +
 SecuritySNACCRuntime/c-lib/src/asn-real.c     |   884 +
 SecuritySNACCRuntime/c-lib/src/asn-tag.c      |   176 +
 SecuritySNACCRuntime/c-lib/src/asn-useful.c   |   892 +
 SecuritySNACCRuntime/c-lib/src/exp-buf.c      |   896 +
 SecuritySNACCRuntime/c-lib/src/hash.c         |   274 +
 SecuritySNACCRuntime/c-lib/src/nibble-alloc.c |   231 +
 SecuritySNACCRuntime/c-lib/src/print.c        |   105 +
 SecuritySNACCRuntime/c-lib/src/sbuf.c         |   405 +
 SecuritySNACCRuntime/c-lib/src/str-stk.c      |    59 +
 SecuritySNACCRuntime/c-lib/src/tbl-dbg.c      |   466 +
 SecuritySNACCRuntime/c-lib/src/tbl-dec.c      |   456 +
 SecuritySNACCRuntime/c-lib/src/tbl-enc.c      |   346 +
 SecuritySNACCRuntime/c-lib/src/tbl-free.c     |   163 +
 SecuritySNACCRuntime/c-lib/src/tbl-gen.c      |   669 +
 SecuritySNACCRuntime/c-lib/src/tbl-print.c    |   194 +
 SecuritySNACCRuntime/c-lib/src/tbl-util.c     |   443 +
 SecuritySNACCRuntime/c-lib/src/tbl.c          |  2137 +++
 SecuritySNACCRuntime/c-lib/stamp-tbl          |     1 +
 SecuritySNACCRuntime/c-lib/stamp-useful       |     1 +
 SecuritySNACCRuntime/c-lib/tbl.c              |  2137 +++
 SecuritySNACCRuntime/c-lib/tbl.h              |   362 +
 SecuritySNACCRuntime/c-lib/tbl.h.patch        |    23 +
 SecuritySNACCRuntime/compiler/README          |   111 +
 .../compiler/back-ends/.cvsignore             |     1 +
 .../compiler/back-ends/c++-gen/gen-any.c      |   309 +
 .../compiler/back-ends/c++-gen/gen-any.h      |    53 +
 .../compiler/back-ends/c++-gen/gen-code.c     |  5556 ++++++
 .../compiler/back-ends/c++-gen/gen-code.h     |    63 +
 .../compiler/back-ends/c++-gen/gen-vals.c     |   325 +
 .../compiler/back-ends/c++-gen/gen-vals.h     |    83 +
 .../compiler/back-ends/c++-gen/kwd.c          |   112 +
 .../compiler/back-ends/c++-gen/kwd.h          |    53 +
 .../compiler/back-ends/c++-gen/rules.c        |   366 +
 .../compiler/back-ends/c++-gen/rules.h        |    71 +
 .../compiler/back-ends/c++-gen/types.c        |   677 +
 .../compiler/back-ends/c++-gen/types.h        |    53 +
 .../compiler/back-ends/c-gen/gen-any.c        |   338 +
 .../compiler/back-ends/c-gen/gen-any.h        |    58 +
 .../compiler/back-ends/c-gen/gen-any2.c       |   335 +
 .../compiler/back-ends/c-gen/gen-code.c       |   267 +
 .../compiler/back-ends/c-gen/gen-code.h       |    57 +
 .../compiler/back-ends/c-gen/gen-code2.c      |   264 +
 .../compiler/back-ends/c-gen/gen-dec.c        |  1912 ++
 .../compiler/back-ends/c-gen/gen-dec.h        |    60 +
 .../compiler/back-ends/c-gen/gen-enc.c        |   852 +
 .../compiler/back-ends/c-gen/gen-enc.h        |    60 +
 .../compiler/back-ends/c-gen/gen-free.c       |   514 +
 .../compiler/back-ends/c-gen/gen-free.h       |    57 +
 .../compiler/back-ends/c-gen/gen-print.c      |   547 +
 .../compiler/back-ends/c-gen/gen-print.h      |    55 +
 .../compiler/back-ends/c-gen/gen-type.c       |   401 +
 .../compiler/back-ends/c-gen/gen-type.h       |    57 +
 .../compiler/back-ends/c-gen/gen-vals.c       |   238 +
 .../compiler/back-ends/c-gen/gen-vals.h       |    59 +
 .../compiler/back-ends/c-gen/gen-vals2.c      |   235 +
 .../compiler/back-ends/c-gen/kwd.c            |   100 +
 .../compiler/back-ends/c-gen/kwd.h            |    52 +
 .../compiler/back-ends/c-gen/kwd2.c           |    97 +
 .../compiler/back-ends/c-gen/rules.c          |   564 +
 .../compiler/back-ends/c-gen/rules.h          |    69 +
 .../compiler/back-ends/c-gen/rules2.c         |   561 +
 .../compiler/back-ends/c-gen/type-info.c      |  1315 ++
 .../compiler/back-ends/c-gen/type-info.h      |    98 +
 .../compiler/back-ends/c-gen/util.c           |   227 +
 .../compiler/back-ends/c-gen/util.h           |    65 +
 .../compiler/back-ends/cond.c                 |    76 +
 .../compiler/back-ends/cond.h                 |    49 +
 .../compiler/back-ends/idl-gen/gen-any.c      |   294 +
 .../compiler/back-ends/idl-gen/gen-any.h      |    47 +
 .../compiler/back-ends/idl-gen/gen-code.c     |   498 +
 .../compiler/back-ends/idl-gen/gen-code.h     |    46 +
 .../compiler/back-ends/idl-gen/gen-vals.c     |   217 +
 .../compiler/back-ends/idl-gen/gen-vals.h     |    59 +
 .../compiler/back-ends/idl-gen/rules.c        |   353 +
 .../compiler/back-ends/idl-gen/rules.h        |    65 +
 .../compiler/back-ends/idl-gen/types.c        |   675 +
 .../compiler/back-ends/idl-gen/types.h        |    47 +
 .../compiler/back-ends/str-util.c             |   606 +
 .../compiler/back-ends/str-util.h             |    95 +
 .../compiler/back-ends/tag-util.c             |   536 +
 .../compiler/back-ends/tag-util.h             |    60 +
 SecuritySNACCRuntime/compiler/boot/tbl.c      |   592 +
 SecuritySNACCRuntime/compiler/boot/tbl.h      |   242 +
 SecuritySNACCRuntime/compiler/core/.cvsignore |     1 +
 .../compiler/core/asn1module.h                |  1028 ++
 SecuritySNACCRuntime/compiler/core/define.c   |   220 +
 SecuritySNACCRuntime/compiler/core/define.h   |    57 +
 .../compiler/core/dependency.c                |   750 +
 .../compiler/core/dependency.h                |    29 +
 .../compiler/core/do-macros.c                 |   732 +
 .../compiler/core/do-macros.h                 |    33 +
 SecuritySNACCRuntime/compiler/core/err-chk.c  |   996 ++
 SecuritySNACCRuntime/compiler/core/err-chk.h  |    34 +
 SecuritySNACCRuntime/compiler/core/exports.c  |   117 +
 SecuritySNACCRuntime/compiler/core/exports.h  |    52 +
 SecuritySNACCRuntime/compiler/core/gen-tbls.c |   741 +
 SecuritySNACCRuntime/compiler/core/gen-tbls.h |    40 +
 SecuritySNACCRuntime/compiler/core/lex-asn1.c |  3496 ++++
 SecuritySNACCRuntime/compiler/core/lex-asn1.l |   523 +
 .../compiler/core/lex-stuff.h                 |    56 +
 .../compiler/core/lib-types.c                 |    66 +
 .../compiler/core/lib-types.h                 |    47 +
 .../compiler/core/link-types.c                |  1273 ++
 .../compiler/core/link-types.h                |    34 +
 .../compiler/core/link-values.c               |  1266 ++
 .../compiler/core/link-values.h               |    34 +
 SecuritySNACCRuntime/compiler/core/mem.c      |    97 +
 SecuritySNACCRuntime/compiler/core/meta.c     |    57 +
 SecuritySNACCRuntime/compiler/core/meta.h     |    60 +
 .../compiler/core/normalize.c                 |   860 +
 .../compiler/core/normalize.h                 |    30 +
 SecuritySNACCRuntime/compiler/core/oid.c      |   270 +
 SecuritySNACCRuntime/compiler/core/oid.h      |    32 +
 .../compiler/core/parse-asn1.c                |  4619 +++++
 .../compiler/core/parse-asn1.h                |   183 +
 .../compiler/core/parse-asn1.y                |  3196 ++++
 SecuritySNACCRuntime/compiler/core/parser.h   |    36 +
 SecuritySNACCRuntime/compiler/core/print.c    |  2767 +++
 SecuritySNACCRuntime/compiler/core/print.h    |   136 +
 SecuritySNACCRuntime/compiler/core/print2.c   |  2764 +++
 .../compiler/core/recursive.c                 |   199 +
 .../compiler/core/recursive.h                 |    29 +
 .../compiler/core/snacc-util.c                |  1334 ++
 .../compiler/core/snacc-util.h                |   139 +
 SecuritySNACCRuntime/compiler/core/snacc.c    |  1361 ++
 SecuritySNACCRuntime/compiler/core/tbl.c      |   574 +
 SecuritySNACCRuntime/compiler/core/tbl.h      |   224 +
 .../compiler/core/tblCompiler.c               |   574 +
 .../compiler/core/val-parser.c                |   734 +
 .../compiler/core/val-parser.h                |    37 +
 SecuritySNACCRuntime/compiler/dependencies    |  1232 ++
 SecuritySNACCRuntime/compiler/install-sh      |   238 +
 SecuritySNACCRuntime/compiler/makefile        |   386 +
 SecuritySNACCRuntime/compiler/stamp-tbl       |     1 +
 SecuritySNACCRuntime/compiler/tbl.c           |   592 +
 SecuritySNACCRuntime/compiler/tbl.h           |   242 +
 SecuritySNACCRuntime/config.cache             |    63 +
 SecuritySNACCRuntime/config.h                 |   182 +
 SecuritySNACCRuntime/config.h.in              |   160 +
 SecuritySNACCRuntime/config.log               |    76 +
 SecuritySNACCRuntime/config.status            |   350 +
 SecuritySNACCRuntime/configure                |  4458 +++++
 SecuritySNACCRuntime/configure.in             |   189 +
 SecuritySNACCRuntime/doc/asn1-defs.tex        |   910 +
 SecuritySNACCRuntime/doc/c++-gen.tex          |   720 +
 SecuritySNACCRuntime/doc/c++-lib.tex          |   973 +
 SecuritySNACCRuntime/doc/c-gen.tex            |   772 +
 SecuritySNACCRuntime/doc/c-lib.tex            |  1384 ++
 SecuritySNACCRuntime/doc/coding.tex           |   105 +
 SecuritySNACCRuntime/doc/corba.bib            |    35 +
 SecuritySNACCRuntime/doc/design.tex           |   761 +
 SecuritySNACCRuntime/doc/editor.tex           |   462 +
 SecuritySNACCRuntime/doc/future-work.tex      |    80 +
 SecuritySNACCRuntime/doc/idl-gen.tex          |    19 +
 SecuritySNACCRuntime/doc/install-sh           |   238 +
 SecuritySNACCRuntime/doc/intro-1.1.tex        |   407 +
 SecuritySNACCRuntime/doc/intro-1.2.tex        |   422 +
 SecuritySNACCRuntime/doc/makefile             |   237 +
 SecuritySNACCRuntime/doc/makefile.tex         |   121 +
 SecuritySNACCRuntime/doc/meta.tex             |   670 +
 SecuritySNACCRuntime/doc/misc-hyph.tex        |    23 +
 SecuritySNACCRuntime/doc/mkchdr.1             |    60 +
 SecuritySNACCRuntime/doc/modifying.tex        |    49 +
 SecuritySNACCRuntime/doc/ptbl.1               |    64 +
 SecuritySNACCRuntime/doc/pval.1               |    63 +
 SecuritySNACCRuntime/doc/snacc.1              |   305 +
 SecuritySNACCRuntime/doc/snacc.bib            |   269 +
 SecuritySNACCRuntime/doc/snacc.n              |   242 +
 SecuritySNACCRuntime/doc/snacc.tex            |   172 +
 SecuritySNACCRuntime/doc/snacced.1            |   248 +
 SecuritySNACCRuntime/doc/tcl.bib              |    21 +
 SecuritySNACCRuntime/doc/tcl.tex              |   456 +
 SecuritySNACCRuntime/doc/ttab.tex             |   532 +
 SecuritySNACCRuntime/doc/tumble.sed           |     4 +
 SecuritySNACCRuntime/doc/version.tex          |     1 +
 SecuritySNACCRuntime/install-sh               |   238 +
 SecuritySNACCRuntime/makefile                 |   225 +
 SecuritySNACCRuntime/makehead                 |   116 +
 SecuritySNACCRuntime/makehead.in              |   113 +
 SecuritySNACCRuntime/makehead.static          |   134 +
 SecuritySNACCRuntime/maketail                 |    78 +
 SecuritySNACCRuntime/mkinstalldirs            |    32 +
 SecuritySNACCRuntime/policy.h                 |    45 +
 SecuritySNACCRuntime/snacc.h                  |   186 +
 .../snacc.pbproj/project.pbxproj              |  1372 ++
 SecuritySNACCRuntime/stamp-h                  |     1 +
 SecuritySNACCRuntime/stamp-h.in               |     1 +
 SecuritySNACCRuntime/tbl-example/README       |    89 +
 SecuritySNACCRuntime/tbl-example/dependencies |     0
 SecuritySNACCRuntime/tbl-example/example.c    |   201 +
 SecuritySNACCRuntime/tbl-example/makefile     |    88 +
 SecuritySNACCRuntime/tbl-example/p-rec.ber    |   Bin 0 -> 145 bytes
 SecuritySNACCRuntime/tbl-example/p-rec.h      |    64 +
 SecuritySNACCRuntime/tbl-example/p-rec.tt     |   Bin 0 -> 1612 bytes
 SecuritySNACCRuntime/tbl-tools/makefile       |    55 +
 SecuritySNACCRuntime/tcl-asn/README           |    75 +
 SecuritySNACCRuntime/tcl-asn/asnwish.c        |    29 +
 SecuritySNACCRuntime/tcl-asn/beredit          |   372 +
 SecuritySNACCRuntime/tcl-asn/makefile         |    90 +
 SecuritySNACCRuntime/tcl-asn/tclasn.c         |  1185 ++
 SecuritySNACCRuntime/tcl-example/dependencies |     0
 SecuritySNACCRuntime/tcl-example/edex0.asn1   |    39 +
 SecuritySNACCRuntime/tcl-example/edex1.asn1   |    78 +
 SecuritySNACCRuntime/tcl-example/makefile     |   102 +
 SecuritySNACCRuntime/tcl-lib/bindings.tcl     |    30 +
 SecuritySNACCRuntime/tcl-lib/help.tcl         |    48 +
 SecuritySNACCRuntime/tcl-lib/make-snacced     |    16 +
 SecuritySNACCRuntime/tcl-lib/makefile         |    69 +
 SecuritySNACCRuntime/tcl-lib/selbox.tcl       |   362 +
 SecuritySNACCRuntime/tcl-lib/snacced.tcl      |  1604 ++
 SecuritySNACCRuntime/tcl-lib/tkuti.tcl        |    21 +
 SecuritySNACCRuntime/tcl-lib/uti.tcl          |    15 +
 SecuritySNACCRuntime/tcl-p.c                  |    50 +
 SecuritySNACCRuntime/version.h                |    21 +
 SecurityServer/AZNTest.cpp                    |    77 +
 SecurityServer/Authorization/AuthSession.h    |   171 +
 .../Authorization/Authorization.cpp           |   196 +
 SecurityServer/Authorization/Authorization.h  |   408 +
 .../Authorization/AuthorizationEngine.cpp     |  1076 ++
 .../Authorization/AuthorizationEngine.h       |   312 +
 .../Authorization/AuthorizationPlugin.h       |   217 +
 .../Authorization/AuthorizationTags.h         |    65 +
 .../Authorization/AuthorizationTrampoline.cpp |   130 +
 .../Authorization/AuthorizationWalkers.h      |    61 +
 .../Authorization/authorization.plist         |    91 +
 .../Authorization/trampolineClient.cpp        |   217 +
 .../Authorization/trampolineServer.cpp        |    62 +
 SecurityServer/BLOBFORMAT                     |    64 +
 SecurityServer/CVSVersionInfo.txt             |     5 +
 .../MacYarrow.pbproj/project.pbxproj          |  1680 ++
 .../MacYarrow/YarrowServer/MacYarrow_OSX.cpp  |   294 +
 .../MacYarrow/YarrowServer/MacYarrow_OSX.h    |    81 +
 .../YarrowServer/YarrowLib_OS9.mcp.exp        |     1 +
 .../MacYarrow/YarrowServer/YarrowServer_OS9.c |   328 +
 .../MacYarrow/YarrowServer/YarrowServer_OS9.h |    70 +
 .../YarrowServer/YarrowServer_OSX.cpp         |   196 +
 .../MacYarrow/YarrowServer/YarrowServer_OSX.h |    44 +
 SecurityServer/MacYarrow/YarrowServer/debug.c |    91 +
 SecurityServer/MacYarrow/YarrowServer/debug.h |   135 +
 .../MacYarrow/YarrowServer/entropyFile.h      |    70 +
 .../MacYarrow/YarrowServer/entropyFileOS9.c   |   189 +
 .../MacYarrow/YarrowServer/entropyFileUnix.c  |   189 +
 .../MacYarrow/YarrowServer/kdebug_private.h   |   108 +
 .../MacYarrow/YarrowServer/prefixDebug.h      |    19 +
 .../MacYarrow/YarrowServer/prefixRelease.h    |    19 +
 .../MacYarrow/YarrowServer/systemEntropy.c    |   270 +
 .../MacYarrow/YarrowServer/systemEntropy.h    |    60 +
 .../MacYarrow/testHarness/clientTest.cpp      |    85 +
 .../MacYarrow/testHarness/serverDaemon.cpp    |    55 +
 SecurityServer/MacYarrow/yarrowseed.cpp       |    55 +
 SecurityServer/MacYarrow/yarrowseed.h         |    45 +
 SecurityServer/MacYarrow/zlib/ChangeLog       |     1 +
 SecurityServer/MacYarrow/zlib/README          |     1 +
 SecurityServer/MacYarrow/zlib/adler32.c       |    66 +
 SecurityServer/MacYarrow/zlib/algorithm.txt   |     1 +
 SecurityServer/MacYarrow/zlib/compress.c      |    86 +
 SecurityServer/MacYarrow/zlib/crc32.c         |   180 +
 SecurityServer/MacYarrow/zlib/deflate.c       |  1368 ++
 SecurityServer/MacYarrow/zlib/deflate.h       |   336 +
 SecurityServer/MacYarrow/zlib/infblock.c      |   416 +
 SecurityServer/MacYarrow/zlib/infblock.h      |    57 +
 SecurityServer/MacYarrow/zlib/infcodes.c      |   275 +
 SecurityServer/MacYarrow/zlib/infcodes.h      |    45 +
 SecurityServer/MacYarrow/zlib/inffast.c       |   188 +
 SecurityServer/MacYarrow/zlib/inffast.h       |    35 +
 SecurityServer/MacYarrow/zlib/inffixed.h      |   169 +
 SecurityServer/MacYarrow/zlib/inflate.c       |   384 +
 SecurityServer/MacYarrow/zlib/inftrees.c      |   473 +
 SecurityServer/MacYarrow/zlib/inftrees.h      |    76 +
 SecurityServer/MacYarrow/zlib/infutil.c       |   105 +
 SecurityServer/MacYarrow/zlib/infutil.h       |   116 +
 SecurityServer/MacYarrow/zlib/trees.c         |  1232 ++
 SecurityServer/MacYarrow/zlib/trees.h         |   146 +
 SecurityServer/MacYarrow/zlib/uncompr.c       |    76 +
 SecurityServer/MacYarrow/zlib/zconf.h         |   297 +
 SecurityServer/MacYarrow/zlib/zlib.h          |   911 +
 SecurityServer/MacYarrow/zlib/zlib.mcp        |   Bin 0 -> 38665 bytes
 SecurityServer/MacYarrow/zlib/zutil.c         |   243 +
 SecurityServer/MacYarrow/zlib/zutil.h         |   238 +
 SecurityServer/Makefile                       |    35 +
 SecurityServer/Makefile.startup               |    53 +
 SecurityServer/SecurityAgentClient.cpp        |   685 +
 SecurityServer/SecurityAgentClient.h          |   189 +
 SecurityServer/SecurityServer.order           |   103 +
 .../SecurityServer.pbxproj/.cvsignore         |     1 +
 .../SecurityServer.pbxproj/project.pbxproj    |  4284 +++++
 SecurityServer/SecurityServerClient.h         |    24 +
 .../English.lproj/InfoPlist.strings           |     6 +
 .../English.lproj/MainMenu.nib/classes.nib    |   Bin 0 -> 316 bytes
 .../English.lproj/MainMenu.nib/objects.nib    |   Bin 0 -> 2226 bytes
 .../SettingsDialog/SecuritySettings.icns      |   Bin 0 -> 38637 bytes
 .../SecuritySettings.pbproj/.cvsignore        |     1 +
 .../SecuritySettings.pbproj/project.pbxproj   |   336 +
 .../SettingsDialog/SettingsWindow.h           |    29 +
 .../SettingsDialog/SettingsWindow.m           |    53 +
 SecurityServer/SettingsDialog/main.m          |     5 +
 .../StartupItems/Localizable.strings          |    11 +
 SecurityServer/StartupItems/SecurityServer    |    13 +
 .../StartupItems/StartupParameters.plist      |    10 +
 SecurityServer/TODO                           |    18 +
 SecurityServer/acl_keychain.cpp               |   147 +
 SecurityServer/acl_keychain.h                 |    67 +
 SecurityServer/acls.cpp                       |   158 +
 SecurityServer/acls.h                         |    90 +
 SecurityServer/agentquery.cpp                 |   207 +
 SecurityServer/agentquery.h                   |   138 +
 SecurityServer/authority.cpp                  |   216 +
 SecurityServer/authority.h                    |   116 +
 SecurityServer/cfnotifier.cpp                 |   166 +
 SecurityServer/cfnotifier.h                   |    42 +
 SecurityServer/connection.cpp                 |   341 +
 SecurityServer/connection.h                   |   123 +
 SecurityServer/dbcrypto.cpp                   |   375 +
 SecurityServer/dbcrypto.h                     |    68 +
 SecurityServer/key.cpp                        |   257 +
 SecurityServer/key.h                          |   103 +
 SecurityServer/main.cpp                       |   232 +
 SecurityServer/process.cpp                    |   203 +
 SecurityServer/process.h                      |    94 +
 SecurityServer/secagent.defs                  |    98 +
 SecurityServer/secagent_types.h               |    54 +
 SecurityServer/securityserver.h               |    51 +
 SecurityServer/server.cpp                     |   263 +
 SecurityServer/server.h                       |   120 +
 SecurityServer/session.cpp                    |   360 +
 SecurityServer/session.h                      |   152 +
 SecurityServer/ssblob.cpp                     |    52 +
 SecurityServer/ssblob.h                       |   181 +
 SecurityServer/ssclient.cpp                   |   116 +
 SecurityServer/ssclient.h                     |   277 +
 SecurityServer/sstransit.cpp                  |   533 +
 SecurityServer/sstransit.h                    |    99 +
 SecurityServer/tests/AZNTest.cpp              |    77 +
 SecurityServer/tests/auth.plist               |    19 +
 SecurityServer/tests/exectest.cpp             |   114 +
 SecurityServer/tests/testacls.cpp             |   403 +
 SecurityServer/tests/testauth.cpp             |   126 +
 SecurityServer/tests/testblobs.cpp            |   282 +
 SecurityServer/tests/testclient.cpp           |   281 +
 SecurityServer/tests/testclient.h             |    69 +
 SecurityServer/tests/testcrypto.cpp           |   184 +
 SecurityServer/tests/testutils.cpp            |   240 +
 SecurityServer/tests/testutils.h              |    90 +
 SecurityServer/transition.cpp                 |   610 +
 SecurityServer/ucsp.defs                      |   226 +
 SecurityServer/ucsp_types.h                   |    75 +
 SecurityServer/xdatabase.cpp                  |   584 +
 SecurityServer/xdatabase.h                    |   191 +
 SecurityServer/yarrowMigTypes.h               |    40 +
 cdsa/CVSVersionInfo.txt                       |     5 +
 cdsa/TODO                                     |     1 +
 cdsa/cdsa.cpp                                 |    69 +
 cdsa/cdsa.pbxproj/.cvsignore                  |     1 +
 cdsa/cdsa.pbxproj/project.pbxproj             |  4774 +++++
 cdsa/cdsa/certextensions.h                    |   298 +
 cdsa/cdsa/cssm.h                              |    37 +
 cdsa/cdsa/cssmaci.h                           |    61 +
 cdsa/cdsa/cssmapi.h                           |  1181 ++
 cdsa/cdsa/cssmapple.h                         |   413 +
 cdsa/cdsa/cssmcli.h                           |   243 +
 cdsa/cdsa/cssmconfig.h                        |    71 +
 cdsa/cdsa/cssmcspi.h                          |   368 +
 cdsa/cdsa/cssmdli.h                           |   152 +
 cdsa/cdsa/cssmerr.h                           |   809 +
 cdsa/cdsa/cssmkrapi.h                         |   229 +
 cdsa/cdsa/cssmkrspi.h                         |   112 +
 cdsa/cdsa/cssmspi.h                           |   151 +
 cdsa/cdsa/cssmtpi.h                           |   203 +
 cdsa/cdsa/cssmtype.h                          |  2074 +++
 cdsa/cdsa/eisl.h                              |   328 +
 cdsa/cdsa/emmspi.h                            |    94 +
 cdsa/cdsa/emmtype.h                           |    54 +
 cdsa/cdsa/mds.h                               |   149 +
 cdsa/cdsa/mds_schema.h                        |   192 +
 cdsa/cdsa/oidsalg.h                           |    63 +
 cdsa/cdsa/oidsattr.h                          |   120 +
 cdsa/cdsa/oidsbase.h                          |   174 +
 cdsa/cdsa/oidscert.h                          |   156 +
 cdsa/cdsa/oidscrl.h                           |    91 +
 cdsa/cdsa/x509defs.h                          |   231 +
 cdsa/cdsa_client.cpp                          |    52 +
 cdsa/cdsa_client/DLDBList.cpp                 |    53 +
 cdsa/cdsa_client/DLDBList.h                   |    76 +
 cdsa/cdsa_client/aclclient.h                  |    65 +
 cdsa/cdsa_client/aclsupport.cpp               |   331 +
 cdsa/cdsa_client/aclsupport.h                 |    97 +
 cdsa/cdsa_client/cryptoclient.cpp             |   150 +
 cdsa/cdsa_client/cryptoclient.h               |   127 +
 cdsa/cdsa_client/cspclient.cpp                |   181 +
 cdsa/cdsa_client/cspclient.h                  |   187 +
 cdsa/cdsa_client/cssmclient.cpp               |   444 +
 cdsa/cdsa_client/cssmclient.h                 |   364 +
 cdsa/cdsa_client/dlclient.cpp                 |   510 +
 cdsa/cdsa_client/dlclient.h                   |   484 +
 cdsa/cdsa_client/genkey.cpp                   |    93 +
 cdsa/cdsa_client/genkey.h                     |    83 +
 cdsa/cdsa_client/keychainacl.cpp              |   133 +
 cdsa/cdsa_client/keychainacl.h                |    89 +
 cdsa/cdsa_client/keyclient.cpp                |   103 +
 cdsa/cdsa_client/keyclient.h                  |   106 +
 cdsa/cdsa_client/macclient.cpp                |    95 +
 cdsa/cdsa_client/macclient.h                  |    90 +
 cdsa/cdsa_client/multidldb.cpp                |   234 +
 cdsa/cdsa_client/multidldb.h                  |   101 +
 cdsa/cdsa_client/osxsigner.cpp                |    94 +
 cdsa/cdsa_client/osxsigner.h                  |   101 +
 cdsa/cdsa_client/securestorage.cpp            |   596 +
 cdsa/cdsa_client/securestorage.h              |   347 +
 cdsa/cdsa_client/signclient.cpp               |    95 +
 cdsa/cdsa_client/signclient.h                 |    91 +
 cdsa/cdsa_client/wrapkey.cpp                  |   223 +
 cdsa/cdsa_client/wrapkey.h                    |   122 +
 cdsa/cdsa_pluginlib.cpp                       |    44 +
 cdsa/cdsa_pluginlib/.cvsignore                |     1 +
 cdsa/cdsa_pluginlib/ACsession.h               |    60 +
 cdsa/cdsa_pluginlib/CLsession.h               |    60 +
 cdsa/cdsa_pluginlib/CSPsession.cpp            |  1026 ++
 cdsa/cdsa_pluginlib/CSPsession.h              |   552 +
 cdsa/cdsa_pluginlib/DLsession.cpp             |    57 +
 cdsa/cdsa_pluginlib/DLsession.h               |    66 +
 cdsa/cdsa_pluginlib/TPsession.h               |    60 +
 cdsa/cdsa_pluginlib/c++plugin.h               |    42 +
 cdsa/cdsa_pluginlib/csputilities.cpp          |   141 +
 cdsa/cdsa_pluginlib/cssmplugin.cpp            |   161 +
 cdsa/cdsa_pluginlib/cssmplugin.h              |   129 +
 cdsa/cdsa_pluginlib/generator.cfg             |    59 +
 cdsa/cdsa_pluginlib/generator.mk              |    28 +
 cdsa/cdsa_pluginlib/generator.pl              |   258 +
 cdsa/cdsa_pluginlib/pluginsession.cpp         |    88 +
 cdsa/cdsa_pluginlib/pluginsession.h           |    96 +
 cdsa/cdsa_pluginlib/pluginspi.h               |    93 +
 cdsa/cdsa_utilities.cpp                       |   126 +
 cdsa/cdsa_utilities/.cvsignore                |     1 +
 cdsa/cdsa_utilities/AppleDatabase.cpp         |  2225 +++
 cdsa/cdsa_utilities/AppleDatabase.h           |   662 +
 cdsa/cdsa_utilities/AtomicFile.cpp            |  1017 ++
 cdsa/cdsa_utilities/AtomicFile.h              |   224 +
 cdsa/cdsa_utilities/Database.cpp              |   231 +
 cdsa/cdsa_utilities/Database.h                |   251 +
 cdsa/cdsa_utilities/DatabaseSession.cpp       |   347 +
 cdsa/cdsa_utilities/DatabaseSession.h         |   149 +
 cdsa/cdsa_utilities/DbContext.cpp             |   128 +
 cdsa/cdsa_utilities/DbContext.h               |    76 +
 cdsa/cdsa_utilities/DbIndex.cpp               |   471 +
 cdsa/cdsa_utilities/DbIndex.h                 |   196 +
 cdsa/cdsa_utilities/DbName.cpp                |    96 +
 cdsa/cdsa_utilities/DbName.h                  |   116 +
 cdsa/cdsa_utilities/DbQuery.cpp               |    30 +
 cdsa/cdsa_utilities/DbQuery.h                 |    45 +
 cdsa/cdsa_utilities/DbValue.cpp               |   554 +
 cdsa/cdsa_utilities/DbValue.h                 |   213 +
 cdsa/cdsa_utilities/MetaAttribute.cpp         |   154 +
 cdsa/cdsa_utilities/MetaAttribute.h           |   150 +
 cdsa/cdsa_utilities/MetaRecord.cpp            |   493 +
 cdsa/cdsa_utilities/MetaRecord.h              |   176 +
 cdsa/cdsa_utilities/NOTES                     |     0
 cdsa/cdsa_utilities/ReadWriteSection.h        |   237 +
 cdsa/cdsa_utilities/SampleGroup.cpp           |   294 +
 cdsa/cdsa_utilities/SampleGroup.h             |   141 +
 cdsa/cdsa_utilities/SelectionPredicate.cpp    |    51 +
 cdsa/cdsa_utilities/SelectionPredicate.h      |    52 +
 cdsa/cdsa_utilities/acl_any.cpp               |    61 +
 cdsa/cdsa_utilities/acl_any.h                 |    62 +
 cdsa/cdsa_utilities/acl_codesigning.cpp       |   148 +
 cdsa/cdsa_utilities/acl_codesigning.h         |    91 +
 cdsa/cdsa_utilities/acl_comment.cpp           |    96 +
 cdsa/cdsa_utilities/acl_comment.h             |    73 +
 cdsa/cdsa_utilities/acl_keychain.cpp          |    90 +
 cdsa/cdsa_utilities/acl_keychain.h            |    90 +
 cdsa/cdsa_utilities/acl_password.cpp          |   108 +
 cdsa/cdsa_utilities/acl_password.h            |    71 +
 cdsa/cdsa_utilities/acl_process.cpp           |   150 +
 cdsa/cdsa_utilities/acl_process.h             |    95 +
 cdsa/cdsa_utilities/acl_threshold.cpp         |   170 +
 cdsa/cdsa_utilities/acl_threshold.h           |    83 +
 cdsa/cdsa_utilities/bufferfifo.cpp            |    78 +
 cdsa/cdsa_utilities/bufferfifo.h              |    69 +
 cdsa/cdsa_utilities/buffers.cpp               |   100 +
 cdsa/cdsa_utilities/buffers.h                 |   156 +
 cdsa/cdsa_utilities/callback.cpp              |   113 +
 cdsa/cdsa_utilities/callback.h                |   113 +
 cdsa/cdsa_utilities/codesigning.cpp           |    36 +
 cdsa/cdsa_utilities/codesigning.h             |   141 +
 cdsa/cdsa_utilities/constdata.cpp             |    38 +
 cdsa/cdsa_utilities/constdata.h               |    83 +
 cdsa/cdsa_utilities/context.cpp               |   172 +
 cdsa/cdsa_utilities/context.h                 |   342 +
 cdsa/cdsa_utilities/cssmacl.cpp               |   528 +
 cdsa/cdsa_utilities/cssmacl.h                 |   355 +
 cdsa/cdsa_utilities/cssmaclpod.cpp            |    85 +
 cdsa/cdsa_utilities/cssmaclpod.h              |   246 +
 cdsa/cdsa_utilities/cssmalloc.cpp             |   164 +
 cdsa/cdsa_utilities/cssmalloc.h               |   368 +
 cdsa/cdsa_utilities/cssmcred.cpp              |    71 +
 cdsa/cdsa_utilities/cssmcred.h                |   164 +
 cdsa/cdsa_utilities/cssmdata.cpp              |   128 +
 cdsa/cdsa_utilities/cssmdata.h                |   423 +
 cdsa/cdsa_utilities/cssmdates.cpp             |    27 +
 cdsa/cdsa_utilities/cssmdates.h               |    53 +
 cdsa/cdsa_utilities/cssmdb.cpp                |   316 +
 cdsa/cdsa_utilities/cssmdb.h                  |   657 +
 cdsa/cdsa_utilities/cssmerrno.cpp             |    95 +
 cdsa/cdsa_utilities/cssmerrno.h               |    54 +
 cdsa/cdsa_utilities/cssmlist.cpp              |   248 +
 cdsa/cdsa_utilities/cssmlist.h                |   251 +
 cdsa/cdsa_utilities/cssmwalkers.cpp           |    25 +
 cdsa/cdsa_utilities/cssmwalkers.h             |   130 +
 cdsa/cdsa_utilities/daemon.cpp                |    86 +
 cdsa/cdsa_utilities/daemon.h                  |    48 +
 cdsa/cdsa_utilities/debugging.cpp             |   455 +
 cdsa/cdsa_utilities/debugging.h               |   122 +
 cdsa/cdsa_utilities/debugsupport.h            |   202 +
 cdsa/cdsa_utilities/devrandom.cpp             |    55 +
 cdsa/cdsa_utilities/devrandom.h               |    51 +
 cdsa/cdsa_utilities/fdsel.cpp                 |    90 +
 cdsa/cdsa_utilities/fdsel.h                   |    74 +
 cdsa/cdsa_utilities/generator.mk              |    26 +
 cdsa/cdsa_utilities/generator.pl              |    84 +
 cdsa/cdsa_utilities/globalizer.cpp            |   143 +
 cdsa/cdsa_utilities/globalizer.h              |   205 +
 cdsa/cdsa_utilities/guids.cpp                 |    43 +
 cdsa/cdsa_utilities/handleobject.cpp          |   118 +
 cdsa/cdsa_utilities/handleobject.h            |   152 +
 cdsa/cdsa_utilities/headermap.cpp             |   141 +
 cdsa/cdsa_utilities/headermap.h               |    87 +
 cdsa/cdsa_utilities/hosts.cpp                 |   145 +
 cdsa/cdsa_utilities/hosts.h                   |    76 +
 cdsa/cdsa_utilities/inetreply.cpp             |    85 +
 cdsa/cdsa_utilities/inetreply.h               |    94 +
 cdsa/cdsa_utilities/ip++.cpp                  |   317 +
 cdsa/cdsa_utilities/ip++.h                    |   244 +
 cdsa/cdsa_utilities/logging.cpp               |   106 +
 cdsa/cdsa_utilities/logging.h                 |    67 +
 cdsa/cdsa_utilities/mach++.cpp                |   300 +
 cdsa/cdsa_utilities/mach++.h                  |   265 +
 cdsa/cdsa_utilities/mach_notify.c             |   560 +
 cdsa/cdsa_utilities/mach_notify.h             |   130 +
 cdsa/cdsa_utilities/machrunloopserver.cpp     |   173 +
 cdsa/cdsa_utilities/machrunloopserver.h       |    79 +
 cdsa/cdsa_utilities/machserver.cpp            |   472 +
 cdsa/cdsa_utilities/machserver.h              |   208 +
 cdsa/cdsa_utilities/memutils.h                |   229 +
 cdsa/cdsa_utilities/os9utils.cpp              |    34 +
 cdsa/cdsa_utilities/os9utils.h                |    74 +
 cdsa/cdsa_utilities/osxsigning.cpp            |   247 +
 cdsa/cdsa_utilities/osxsigning.h              |   135 +
 cdsa/cdsa_utilities/powerwatch.cpp            |   128 +
 cdsa/cdsa_utilities/powerwatch.h              |    81 +
 cdsa/cdsa_utilities/refcount.h                |    98 +
 cdsa/cdsa_utilities/selector.cpp              |   197 +
 cdsa/cdsa_utilities/selector.h                |   117 +
 cdsa/cdsa_utilities/socks++.cpp               |   149 +
 cdsa/cdsa_utilities/socks++.h                 |   213 +
 cdsa/cdsa_utilities/socks++4.cpp              |   128 +
 cdsa/cdsa_utilities/socks++4.h                |    80 +
 cdsa/cdsa_utilities/socks++5.cpp              |   202 +
 cdsa/cdsa_utilities/socks++5.h                |   119 +
 cdsa/cdsa_utilities/streams.cpp               |   138 +
 cdsa/cdsa_utilities/streams.h                 |   181 +
 cdsa/cdsa_utilities/threading.cpp             |   310 +
 cdsa/cdsa_utilities/threading.h               |   418 +
 cdsa/cdsa_utilities/threading_internal.h      |    98 +
 cdsa/cdsa_utilities/timeflow.cpp              |    94 +
 cdsa/cdsa_utilities/timeflow.h                |   153 +
 cdsa/cdsa_utilities/tqueue.cpp                |    25 +
 cdsa/cdsa_utilities/tqueue.h                  |   139 +
 cdsa/cdsa_utilities/typedvalue.cpp            |    32 +
 cdsa/cdsa_utilities/typedvalue.h              |    80 +
 cdsa/cdsa_utilities/uniformrandom.cpp         |    31 +
 cdsa/cdsa_utilities/uniformrandom.h           |    54 +
 cdsa/cdsa_utilities/unix++.cpp                |   179 +
 cdsa/cdsa_utilities/unix++.h                  |   123 +
 cdsa/cdsa_utilities/url.cpp                   |   145 +
 cdsa/cdsa_utilities/url.h                     |    76 +
 cdsa/cdsa_utilities/utilities.cpp             |   233 +
 cdsa/cdsa_utilities/utilities.h               |   749 +
 cdsa/cdsa_utilities/utility_config.h          |   112 +
 cdsa/cdsa_utilities/walkers.cpp               |    55 +
 cdsa/cdsa_utilities/walkers.h                 |   328 +
 cdsa/cssm/.cvsignore                          |     1 +
 cdsa/cssm/MDS                                 |     5 +
 cdsa/cssm/attachfactory.cpp                   |   113 +
 cdsa/cssm/attachfactory.h                     |    79 +
 cdsa/cssm/attachment.cpp                      |   196 +
 cdsa/cssm/attachment.h                        |   201 +
 cdsa/cssm/builtin_modules.cpp                 |    43 +
 cdsa/cssm/cspattachment.cpp                   |    25 +
 cdsa/cssm/cspattachment.h                     |    39 +
 cdsa/cssm/cssm.cpp                            |   217 +
 cdsa/cssm/cssmcontext.cpp                     |   199 +
 cdsa/cssm/cssmcontext.h                       |   110 +
 cdsa/cssm/cssmint.h                           |    74 +
 cdsa/cssm/cssmmds.cpp                         |   111 +
 cdsa/cssm/cssmmds.h                           |    73 +
 cdsa/cssm/generator.cfg                       |    13 +
 cdsa/cssm/generator.mk                        |    26 +
 cdsa/cssm/generator.pl                        |   228 +
 cdsa/cssm/manager.cpp                         |   206 +
 cdsa/cssm/manager.h                           |   109 +
 cdsa/cssm/modload_plugin.cpp                  |    61 +
 cdsa/cssm/modload_plugin.h                    |    90 +
 cdsa/cssm/modload_static.cpp                  |    29 +
 cdsa/cssm/modload_static.h                    |    54 +
 cdsa/cssm/modloader.cpp                       |    75 +
 cdsa/cssm/modloader.h                         |   100 +
 cdsa/cssm/module.cpp                          |   157 +
 cdsa/cssm/module.h                            |    91 +
 cdsa/cssm/oidsalg.c                           |   149 +
 cdsa/cssm/oidsattr.c                          |   216 +
 cdsa/cssm/oidscert.cpp                        |   198 +
 cdsa/cssm/oidscrl.cpp                         |   117 +
 cdsa/cssm/transition.cpp                      |   507 +
 cdsa/generator.mk                             |    77 +
 cdsa/mds/.cvsignore                           |     2 +
 cdsa/mds/MDSDatabase.cpp                      |   221 +
 cdsa/mds/MDSDatabase.h                        |   158 +
 cdsa/mds/MDSModule.cpp                        |    76 +
 cdsa/mds/MDSModule.h                          |    41 +
 cdsa/mds/MDSPrefs.cpp                         |   143 +
 cdsa/mds/MDSPrefs.h                           |    47 +
 cdsa/mds/MDSSchema.cpp                        |   114 +
 cdsa/mds/MDSSchema.h                          |    66 +
 cdsa/mds/MDSSession.cpp                       |   402 +
 cdsa/mds/MDSSession.h                         |    70 +
 cdsa/mds/NOTES                                |    85 +
 cdsa/mds/mds.mcp                              |   Bin 0 -> 28375 bytes
 cdsa/mds/mdsapi.cpp                           |   395 +
 checkpw/checkpw.c                             |   252 +
 checkpw/checkpw.h                             |    47 +
 symbol_strip.sh                               |    31 +
 1305 files changed, 399096 insertions(+)
 create mode 100644 APPLE_LICENSE
 create mode 100644 AppleCSP/AES/aescsp.cpp
 create mode 100644 AppleCSP/AES/aescspi.h
 create mode 100644 AppleCSP/AES/boxes-ref.c
 create mode 100644 AppleCSP/AES/boxes-ref.h
 create mode 100644 AppleCSP/AES/rijndael-alg-ref.c
 create mode 100644 AppleCSP/AES/rijndael-alg-ref.h
 create mode 100644 AppleCSP/AES/rijndaelApi.c
 create mode 100644 AppleCSP/AES/rijndaelApi.h
 create mode 100644 AppleCSP/AES/vRijndael-alg-ref.c
 create mode 100644 AppleCSP/AppleCSP.pbxproj/.cvsignore
 create mode 100644 AppleCSP/AppleCSP.pbxproj/project.pbxproj
 create mode 100644 AppleCSP/AppleCSP/.cvsignore
 create mode 100644 AppleCSP/AppleCSP/AppleCSP.cpp
 create mode 100644 AppleCSP/AppleCSP/AppleCSP.h
 create mode 100644 AppleCSP/AppleCSP/AppleCSPContext.cpp
 create mode 100644 AppleCSP/AppleCSP/AppleCSPContext.h
 create mode 100644 AppleCSP/AppleCSP/AppleCSPSession.h
 create mode 100644 AppleCSP/AppleCSP/AppleCSPUtils.cpp
 create mode 100644 AppleCSP/AppleCSP/AppleCSPUtils.h
 create mode 100644 AppleCSP/AppleCSP/BinaryKey.h
 create mode 100644 AppleCSP/AppleCSP/BlockCryptor.cpp
 create mode 100644 AppleCSP/AppleCSP/BlockCryptor.h
 create mode 100644 AppleCSP/AppleCSP/DigestObject.h
 create mode 100644 AppleCSP/AppleCSP/NullDigest.h
 create mode 100644 AppleCSP/AppleCSP/RawSigner.h
 create mode 100644 AppleCSP/AppleCSP/SignatureContext.cpp
 create mode 100644 AppleCSP/AppleCSP/SignatureContext.h
 create mode 100644 AppleCSP/AppleCSP/YarrowConnection.cpp
 create mode 100644 AppleCSP/AppleCSP/YarrowConnection.h
 create mode 100644 AppleCSP/AppleCSP/cspdebugging.c
 create mode 100644 AppleCSP/AppleCSP/cspdebugging.h
 create mode 100644 AppleCSP/AppleCSP/cssmplugin.exp
 create mode 100644 AppleCSP/AppleCSP/deriveKey.cpp
 create mode 100644 AppleCSP/AppleCSP/pkcs_7_8.cpp
 create mode 100644 AppleCSP/AppleCSP/pkcs_7_8.h
 create mode 100644 AppleCSP/AppleCSP/rotty.mcp
 create mode 100644 AppleCSP/AppleCSP/wrapKey.cpp
 create mode 100644 AppleCSP/AppleCSP/wrapKeyCms.cpp
 create mode 100644 AppleCSP/AppleCSPPlugin.cpp
 create mode 100644 AppleCSP/BSafeCSP/algmaker.cpp
 create mode 100644 AppleCSP/BSafeCSP/bsafeAsymmetric.cpp
 create mode 100644 AppleCSP/BSafeCSP/bsafeContext.cpp
 create mode 100644 AppleCSP/BSafeCSP/bsafeKeyGen.cpp
 create mode 100644 AppleCSP/BSafeCSP/bsafePKCS1.cpp
 create mode 100644 AppleCSP/BSafeCSP/bsafePKCS1.h
 create mode 100644 AppleCSP/BSafeCSP/bsafeSymmetric.cpp
 create mode 100644 AppleCSP/BSafeCSP/bsafecsp.h
 create mode 100644 AppleCSP/BSafeCSP/bsafecspi.h
 create mode 100644 AppleCSP/BSafeCSP/bsobjects.h
 create mode 100644 AppleCSP/BSafeCSP/memory.cpp
 create mode 100644 AppleCSP/BSafeCSP/miscalgorithms.cpp
 create mode 100644 AppleCSP/BSafeCSP/test/t-dsa.cpp
 create mode 100644 AppleCSP/BSafeCSP/test/t-rsa.cpp
 create mode 100644 AppleCSP/BSafeCSP/test/t.cpp
 create mode 100644 AppleCSP/CVSVersionInfo.txt
 create mode 100644 AppleCSP/ComCryption/ascContext.cpp
 create mode 100644 AppleCSP/ComCryption/ascContext.h
 create mode 100644 AppleCSP/ComCryption/ascFactory.h
 create mode 100644 AppleCSP/CryptKit/.cvsignore
 create mode 100644 AppleCSP/CryptKit/ByteRep.txt
 create mode 100644 AppleCSP/CryptKitCSP/CryptKitDER.cpp
 create mode 100755 AppleCSP/CryptKitCSP/CryptKitSpace.h
 create mode 100644 AppleCSP/CryptKitCSP/FEEAsymmetricContext.cpp
 create mode 100644 AppleCSP/CryptKitCSP/FEEAsymmetricContext.h
 create mode 100644 AppleCSP/CryptKitCSP/FEECSPUtils.cpp
 create mode 100644 AppleCSP/CryptKitCSP/FEECSPUtils.h
 create mode 100644 AppleCSP/CryptKitCSP/FEEKeys.cpp
 create mode 100644 AppleCSP/CryptKitCSP/FEEKeys.h
 create mode 100644 AppleCSP/CryptKitCSP/FEESignatureObject.cpp
 create mode 100644 AppleCSP/CryptKitCSP/FEESignatureObject.h
 create mode 100644 AppleCSP/CryptKitCSP/cryptkitcsp.cpp
 create mode 100644 AppleCSP/CryptKitCSP/cryptkitcsp.h
 create mode 100644 AppleCSP/MiscCSPAlgs/DES.c
 create mode 100644 AppleCSP/MiscCSPAlgs/DES.h
 create mode 100644 AppleCSP/MiscCSPAlgs/DigestContext.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/DigestContext.h
 create mode 100644 AppleCSP/MiscCSPAlgs/MD2Object.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/MD2Object.h
 create mode 100644 AppleCSP/MiscCSPAlgs/MD5.c
 create mode 100644 AppleCSP/MiscCSPAlgs/MD5.h
 create mode 100644 AppleCSP/MiscCSPAlgs/MacContext.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/MacContext.h
 create mode 100644 AppleCSP/MiscCSPAlgs/SHA1.c
 create mode 100644 AppleCSP/MiscCSPAlgs/SHA1.h
 create mode 100644 AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.h
 create mode 100644 AppleCSP/MiscCSPAlgs/SHA1_priv.c
 create mode 100644 AppleCSP/MiscCSPAlgs/SHA1_priv.h
 create mode 100644 AppleCSP/MiscCSPAlgs/desContext.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/desContext.h
 create mode 100644 AppleCSP/MiscCSPAlgs/miscAlgFactory.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/miscAlgFactory.h
 create mode 100644 AppleCSP/MiscCSPAlgs/platform.h
 create mode 100644 AppleCSP/MiscCSPAlgs/rc2Context.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/rc2Context.h
 create mode 100644 AppleCSP/MiscCSPAlgs/rc4Context.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/rc4Context.h
 create mode 100644 AppleCSP/MiscCSPAlgs/rc5Context.cpp
 create mode 100644 AppleCSP/MiscCSPAlgs/rc5Context.h
 create mode 100644 AppleCSP/PBKDF2/HMACSHA1.c
 create mode 100644 AppleCSP/PBKDF2/HMACSHA1.h
 create mode 100644 AppleCSP/PBKDF2/pbkdf2.c
 create mode 100644 AppleCSP/PBKDF2/pbkdf2.h
 create mode 100644 AppleCSP/RSA_DSA/RSA_DSA_csp.cpp
 create mode 100644 AppleCSP/RSA_DSA/RSA_DSA_csp.h
 create mode 100644 AppleCSP/RSA_DSA/RSA_DSA_keys.cpp
 create mode 100644 AppleCSP/RSA_DSA/RSA_DSA_keys.h
 create mode 100644 AppleCSP/RSA_DSA/RSA_DSA_signature.cpp
 create mode 100644 AppleCSP/RSA_DSA/RSA_DSA_signature.h
 create mode 100644 AppleCSP/RSA_DSA/RSA_DSA_utils.cpp
 create mode 100644 AppleCSP/RSA_DSA/RSA_DSA_utils.h
 create mode 100644 AppleCSP/RSA_DSA/RSA_asymmetric.cpp
 create mode 100644 AppleCSP/RSA_DSA/RSA_asymmetric.h
 create mode 100644 AppleCSP/TODO
 create mode 100644 AppleCSP/open_ssl/bio/bio_lib.c
 create mode 100644 AppleCSP/open_ssl/bio/bss_file.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_add.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_asm.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_blind.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_ctx.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_div.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_err.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_exp.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_exp2.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_gcd.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_lcl.h
 create mode 100644 AppleCSP/open_ssl/bn/bn_lib.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_mont.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_mpi.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_mul.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_prime.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_prime.h
 create mode 100644 AppleCSP/open_ssl/bn/bn_print.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_rand.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_recp.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_shift.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_sqr.c
 create mode 100644 AppleCSP/open_ssl/bn/bn_word.c
 create mode 100644 AppleCSP/open_ssl/bn/bnspeed.c
 create mode 100644 AppleCSP/open_ssl/bn/bntest.c
 create mode 100644 AppleCSP/open_ssl/bn/divtest.c
 create mode 100644 AppleCSP/open_ssl/bn/exp.c
 create mode 100644 AppleCSP/open_ssl/bn/expspeed.c
 create mode 100644 AppleCSP/open_ssl/bn/exptest.c
 create mode 100644 AppleCSP/open_ssl/bn/vms-helper.c
 create mode 100644 AppleCSP/open_ssl/buffer/buf_err.c
 create mode 100644 AppleCSP/open_ssl/buffer/buffer.c
 create mode 100644 AppleCSP/open_ssl/cryptlib.c
 create mode 100644 AppleCSP/open_ssl/cryptlib.h
 create mode 100644 AppleCSP/open_ssl/dsa/dsa_asn1.c
 create mode 100644 AppleCSP/open_ssl/dsa/dsa_err.c
 create mode 100644 AppleCSP/open_ssl/dsa/dsa_gen.c
 create mode 100644 AppleCSP/open_ssl/dsa/dsa_key.c
 create mode 100644 AppleCSP/open_ssl/dsa/dsa_lib.c
 create mode 100644 AppleCSP/open_ssl/dsa/dsa_ossl.c
 create mode 100644 AppleCSP/open_ssl/dsa/dsa_sign.c
 create mode 100644 AppleCSP/open_ssl/dsa/dsa_vrf.c
 create mode 100644 AppleCSP/open_ssl/err/err.c
 create mode 100644 AppleCSP/open_ssl/err/err_prn.c
 create mode 100644 AppleCSP/open_ssl/ex_data.c
 create mode 100644 AppleCSP/open_ssl/lhash/lhash.c
 create mode 100644 AppleCSP/open_ssl/mem.c
 create mode 100644 AppleCSP/open_ssl/misc/md2_dgst.c
 create mode 100644 AppleCSP/open_ssl/misc/rc2_cbc.c
 create mode 100644 AppleCSP/open_ssl/misc/rc2_locl.h
 create mode 100644 AppleCSP/open_ssl/misc/rc2_skey.c
 create mode 100644 AppleCSP/open_ssl/misc/rc4_enc.c
 create mode 100644 AppleCSP/open_ssl/misc/rc4_skey.c
 create mode 100644 AppleCSP/open_ssl/misc/rc5_enc.c
 create mode 100644 AppleCSP/open_ssl/misc/rc5_locl.h
 create mode 100644 AppleCSP/open_ssl/misc/rc5_skey.c
 create mode 100644 AppleCSP/open_ssl/openssl/asn1.h
 create mode 100644 AppleCSP/open_ssl/openssl/bio.h
 create mode 100644 AppleCSP/open_ssl/openssl/bn.h
 create mode 100644 AppleCSP/open_ssl/openssl/buffer.h
 create mode 100644 AppleCSP/open_ssl/openssl/crypto.h
 create mode 100644 AppleCSP/open_ssl/openssl/dsa.h
 create mode 100644 AppleCSP/open_ssl/openssl/e_os.h
 create mode 100644 AppleCSP/open_ssl/openssl/e_os2.h
 create mode 100644 AppleCSP/open_ssl/openssl/err.h
 create mode 100644 AppleCSP/open_ssl/openssl/evp.h
 create mode 100644 AppleCSP/open_ssl/openssl/lhash.h
 create mode 100644 AppleCSP/open_ssl/openssl/md2.h
 create mode 100644 AppleCSP/open_ssl/openssl/objects.h
 create mode 100644 AppleCSP/open_ssl/openssl/openssl_pkcs7.h
 create mode 100644 AppleCSP/open_ssl/openssl/opensslconf.h
 create mode 100644 AppleCSP/open_ssl/openssl/opensslv.h
 create mode 100644 AppleCSP/open_ssl/openssl/rand.h
 create mode 100644 AppleCSP/open_ssl/openssl/rc2.h
 create mode 100644 AppleCSP/open_ssl/openssl/rc4.h
 create mode 100644 AppleCSP/open_ssl/openssl/rc5.h
 create mode 100644 AppleCSP/open_ssl/openssl/rsa.h
 create mode 100644 AppleCSP/open_ssl/openssl/safestack.h
 create mode 100644 AppleCSP/open_ssl/openssl/sha.h
 create mode 100644 AppleCSP/open_ssl/openssl/stack.h
 create mode 100644 AppleCSP/open_ssl/openssl/x509.h
 create mode 100644 AppleCSP/open_ssl/openssl/x509_vfy.h
 create mode 100644 AppleCSP/open_ssl/opensslUtils/openRsaSnacc.cpp
 create mode 100644 AppleCSP/open_ssl/opensslUtils/openRsaSnacc.h
 create mode 100644 AppleCSP/open_ssl/opensslUtils/opensslUtils.cpp
 create mode 100644 AppleCSP/open_ssl/opensslUtils/opensslUtils.h
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_chk.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_eay.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_err.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_gen.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_lib.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_none.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_null.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_pk1.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_saos.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_sign.c
 create mode 100644 AppleCSP/open_ssl/rsa/rsa_ssl.c
 create mode 100644 AppleCSP/open_ssl/stack/stack.c
 create mode 100644 AppleCSPDL/AppleCSPDL.pbproj/.cvsignore
 create mode 100644 AppleCSPDL/AppleCSPDL.pbproj/project.pbxproj
 create mode 100644 AppleCSPDL/AppleCSPDLPlugin.cpp
 create mode 100644 AppleCSPDL/CSPDLDatabase.cpp
 create mode 100644 AppleCSPDL/CSPDLDatabase.h
 create mode 100644 AppleCSPDL/CSPDLPlugin.cpp
 create mode 100644 AppleCSPDL/CSPDLPlugin.h
 create mode 100644 AppleCSPDL/CVSVersionInfo.txt
 create mode 100644 AppleCSPDL/KeySchema.h
 create mode 100644 AppleCSPDL/KeySchema.m4
 create mode 100644 AppleCSPDL/SSCSPDLSession.cpp
 create mode 100644 AppleCSPDL/SSCSPDLSession.h
 create mode 100644 AppleCSPDL/SSCSPSession.cpp
 create mode 100644 AppleCSPDL/SSCSPSession.h
 create mode 100644 AppleCSPDL/SSContext.cpp
 create mode 100644 AppleCSPDL/SSContext.h
 create mode 100644 AppleCSPDL/SSDLSession.cpp
 create mode 100644 AppleCSPDL/SSDLSession.h
 create mode 100644 AppleCSPDL/SSDatabase.cpp
 create mode 100644 AppleCSPDL/SSDatabase.h
 create mode 100644 AppleCSPDL/SSFactory.cpp
 create mode 100644 AppleCSPDL/SSFactory.h
 create mode 100644 AppleCSPDL/SSKey.cpp
 create mode 100644 AppleCSPDL/SSKey.h
 create mode 100644 AppleCSPDL/cssmplugin.exp
 create mode 100644 AppleDL/.cvsignore
 create mode 100644 AppleDL/AppleCSPDL.mcp
 create mode 100644 AppleDL/AppleDL.pbxproj/.cvsignore
 create mode 100644 AppleDL/AppleDL.pbxproj/project.pbxproj
 create mode 100644 AppleDL/AppleDLPlugin.cpp
 create mode 100644 AppleDL/AppleFileDL.cpp
 create mode 100644 AppleDL/AppleFileDL.h
 create mode 100644 AppleDL/CVSVersionInfo.txt
 create mode 100644 AppleDL/FORMAT
 create mode 100644 AppleDL/ISSUES
 create mode 100644 AppleDL/TODO
 create mode 100644 AppleDL/cssmplugin.exp
 create mode 100644 AppleX509CL/.cvsignore
 create mode 100644 AppleX509CL/AppleX509CL.cpp
 create mode 100644 AppleX509CL/AppleX509CL.h
 create mode 100644 AppleX509CL/AppleX509CL.mcp
 create mode 100644 AppleX509CL/AppleX509CL.pbproj/project.pbxproj
 create mode 100644 AppleX509CL/AppleX509CLPlugin.cpp
 create mode 100644 AppleX509CL/AppleX509CLSession.cpp
 create mode 100644 AppleX509CL/AppleX509CLSession.h
 create mode 100644 AppleX509CL/CLCachedEntry.cpp
 create mode 100644 AppleX509CL/CLCachedEntry.h
 create mode 100644 AppleX509CL/CLCertExtensions.cpp
 create mode 100644 AppleX509CL/CLCertExtensions.h
 create mode 100644 AppleX509CL/CSPAttacher.cpp
 create mode 100644 AppleX509CL/CSPAttacher.h
 create mode 100644 AppleX509CL/CVSVersionInfo.txt
 create mode 100644 AppleX509CL/CertBuilder.cpp
 create mode 100644 AppleX509CL/CertBuilder.h
 create mode 100644 AppleX509CL/CertFields.cpp
 create mode 100644 AppleX509CL/DecodedCert.cpp
 create mode 100644 AppleX509CL/DecodedCert.h
 create mode 100644 AppleX509CL/LockedMap.h
 create mode 100644 AppleX509CL/Session_CRL.cpp
 create mode 100644 AppleX509CL/Session_Cert.cpp
 create mode 100644 AppleX509CL/Session_Crypto.cpp
 create mode 100644 AppleX509CL/SnaccUtils.cpp
 create mode 100644 AppleX509CL/SnaccUtils.h
 create mode 100644 AppleX509CL/TODO
 create mode 100644 AppleX509CL/cldebugging.c
 create mode 100644 AppleX509CL/cldebugging.h
 create mode 100644 AppleX509CL/cssmplugin.exp
 create mode 100644 AppleX509TP/AppleTP.cpp
 create mode 100644 AppleX509TP/AppleTP.h
 create mode 100644 AppleX509TP/AppleTP.pbproj/project.pbxproj
 create mode 100644 AppleX509TP/AppleTPSession.cpp
 create mode 100644 AppleX509TP/AppleTPSession.h
 create mode 100644 AppleX509TP/AppleX509TPPlugin.cpp
 create mode 100644 AppleX509TP/CVSVersionInfo.txt
 create mode 100644 AppleX509TP/TPCertInfo.cpp
 create mode 100644 AppleX509TP/TPCertInfo.h
 create mode 100644 AppleX509TP/certGroupUtils.cpp
 create mode 100644 AppleX509TP/certGroupUtils.h
 create mode 100644 AppleX509TP/cssmplugin.exp
 create mode 100644 AppleX509TP/iSignRootCerts.c
 create mode 100644 AppleX509TP/rootCerts.h
 create mode 100644 AppleX509TP/sslRootCerts.c
 create mode 100644 AppleX509TP/tpCertGroup.cpp
 create mode 100644 AppleX509TP/tpPolicies.cpp
 create mode 100644 AppleX509TP/tpPolicies.h
 create mode 100644 AppleX509TP/tpTime.c
 create mode 100644 AppleX509TP/tpTime.h
 create mode 100644 AppleX509TP/tpdebugging.c
 create mode 100644 AppleX509TP/tpdebugging.h
 create mode 100644 CVSVersionInfo.txt
 create mode 100644 Keychain/CCallbackMgr.cp
 create mode 100644 Keychain/CCallbackMgr.h
 create mode 100644 Keychain/DLDBListCFPref.cpp
 create mode 100644 Keychain/DLDBListCFPref.h
 create mode 100644 Keychain/DefaultKeychain.cpp
 create mode 100644 Keychain/DefaultKeychain.h
 create mode 100644 Keychain/Globals.cpp
 create mode 100644 Keychain/Globals.h
 create mode 100644 Keychain/Item.cpp
 create mode 100644 Keychain/Item.h
 create mode 100644 Keychain/KCCursor.cpp
 create mode 100644 Keychain/KCCursor.h
 create mode 100644 Keychain/KCEventNotifier.cpp
 create mode 100644 Keychain/KCEventNotifier.h
 create mode 100644 Keychain/KCEventObserver.cpp
 create mode 100644 Keychain/KCEventObserver.h
 create mode 100644 Keychain/KCExceptions.h
 create mode 100644 Keychain/KCUtilities.cpp
 create mode 100644 Keychain/KCUtilities.h
 create mode 100644 Keychain/Keychains.cpp
 create mode 100644 Keychain/Keychains.h
 create mode 100644 Keychain/PrimaryKey.cpp
 create mode 100644 Keychain/PrimaryKey.h
 create mode 100644 Keychain/Refs.h
 create mode 100644 Keychain/Schema.h
 create mode 100644 Keychain/Schema.m4
 create mode 100644 Keychain/SecKeychainAPI.cpp
 create mode 100644 Keychain/SecKeychainAPI.h
 create mode 100644 Keychain/SecKeychainAPIPriv.h
 create mode 100644 Keychain/StorageManager.cpp
 create mode 100644 Keychain/StorageManager.h
 create mode 100644 Keychain/cssmdatetime.cpp
 create mode 100644 Keychain/cssmdatetime.h
 create mode 100644 Network/connectionpool.cpp
 create mode 100644 Network/connectionpool.h
 create mode 100644 Network/file-protocol.cpp
 create mode 100644 Network/file-protocol.h
 create mode 100644 Network/ftp-protocol.cpp
 create mode 100644 Network/ftp-protocol.h
 create mode 100644 Network/ftp-proxy-protocol.cpp
 create mode 100644 Network/ftp-proxy-protocol.h
 create mode 100644 Network/http-protocol.cpp
 create mode 100644 Network/http-protocol.h
 create mode 100644 Network/http-proxy-protocol.cpp
 create mode 100644 Network/http-proxy-protocol.h
 create mode 100644 Network/https-protocol.cpp
 create mode 100644 Network/https-protocol.h
 create mode 100644 Network/https-proxy-protocol.cpp
 create mode 100644 Network/https-proxy-protocol.h
 create mode 100644 Network/multiobserver.cpp
 create mode 100644 Network/multiobserver.h
 create mode 100644 Network/netconnection.cpp
 create mode 100644 Network/netconnection.h
 create mode 100644 Network/neterror.cpp
 create mode 100644 Network/neterror.h
 create mode 100644 Network/netmanager.cpp
 create mode 100644 Network/netmanager.h
 create mode 100644 Network/netparameters.h
 create mode 100644 Network/networkchooser.cpp
 create mode 100644 Network/networkchooser.h
 create mode 100644 Network/observer.cpp
 create mode 100644 Network/observer.h
 create mode 100644 Network/parameters.cpp
 create mode 100644 Network/parameters.h
 create mode 100644 Network/protocol.cpp
 create mode 100644 Network/protocol.h
 create mode 100644 Network/simplemanager.cpp
 create mode 100644 Network/simplemanager.h
 create mode 100644 Network/target.cpp
 create mode 100644 Network/target.h
 create mode 100644 Network/transfer.cpp
 create mode 100644 Network/transfer.h
 create mode 100644 Network/xfercore.cpp
 create mode 100644 Network/xfercore.h
 create mode 100644 SecureTransport/CVSVersionInfo.txt
 create mode 100644 SecureTransport/LICENSE.txt
 create mode 100644 SecureTransport/ModuleAttacher.cpp
 create mode 100644 SecureTransport/ModuleAttacher.h
 create mode 100644 SecureTransport/README
 create mode 100644 SecureTransport/SecureTransport.pbproj/project.pbxproj
 create mode 100644 SecureTransport/SecureTransport/CipherSuite.h
 create mode 100644 SecureTransport/SecureTransport/SecureTransport.h
 create mode 100644 SecureTransport/appleCdsa.c
 create mode 100644 SecureTransport/appleGlue.c
 create mode 100644 SecureTransport/appleSession.c
 create mode 100644 SecureTransport/cipherSpecs.c
 create mode 100644 SecureTransport/cppUtils.cpp
 create mode 100644 SecureTransport/digests.c
 create mode 100644 SecureTransport/hdskcert.c
 create mode 100644 SecureTransport/hdskchgc.c
 create mode 100644 SecureTransport/hdskfini.c
 create mode 100644 SecureTransport/hdskhelo.c
 create mode 100644 SecureTransport/hdskkeys.c
 create mode 100644 SecureTransport/hdskkyex.c
 create mode 100644 SecureTransport/nullciph.c
 create mode 100644 SecureTransport/privateInc/appleCdsa.h
 create mode 100644 SecureTransport/privateInc/appleGlue.h
 create mode 100644 SecureTransport/privateInc/appleSession.h
 create mode 100644 SecureTransport/privateInc/cipherSpecs.h
 create mode 100644 SecureTransport/privateInc/cryptType.h
 create mode 100644 SecureTransport/privateInc/digests.h
 create mode 100644 SecureTransport/privateInc/ssl.h
 create mode 100644 SecureTransport/privateInc/ssl2.h
 create mode 100644 SecureTransport/privateInc/sslBER.h
 create mode 100644 SecureTransport/privateInc/sslBuildFlags.h
 create mode 100644 SecureTransport/privateInc/sslDebug.h
 create mode 100644 SecureTransport/privateInc/sslKeychain.h
 create mode 100644 SecureTransport/privateInc/sslPriv.h
 create mode 100644 SecureTransport/privateInc/sslalert.h
 create mode 100644 SecureTransport/privateInc/sslalloc.h
 create mode 100644 SecureTransport/privateInc/sslctx.h
 create mode 100644 SecureTransport/privateInc/sslerrs.h
 create mode 100644 SecureTransport/privateInc/sslhdshk.h
 create mode 100644 SecureTransport/privateInc/sslmd5.h
 create mode 100644 SecureTransport/privateInc/sslrec.h
 create mode 100644 SecureTransport/privateInc/sslsess.h
 create mode 100644 SecureTransport/privateInc/ssltrspt.h
 create mode 100644 SecureTransport/privateInc/sslutil.h
 create mode 100644 SecureTransport/privateInc/st_sha.h
 create mode 100644 SecureTransport/privateInc/symCipher.h
 create mode 100644 SecureTransport/secureTransport.exp
 create mode 100644 SecureTransport/securetransport++.cpp
 create mode 100644 SecureTransport/securetransport++.h
 create mode 100644 SecureTransport/sha.c
 create mode 100644 SecureTransport/ssl2map.c
 create mode 100644 SecureTransport/ssl2mesg.c
 create mode 100644 SecureTransport/ssl2prot.c
 create mode 100644 SecureTransport/ssl2rec.c
 create mode 100644 SecureTransport/sslBER.cpp
 create mode 100644 SecureTransport/sslDebug.c
 create mode 100644 SecureTransport/sslKeychain.c
 create mode 100644 SecureTransport/sslalert.c
 create mode 100644 SecureTransport/sslalloc.c
 create mode 100644 SecureTransport/sslctx.c
 create mode 100644 SecureTransport/sslhdshk.c
 create mode 100644 SecureTransport/sslmd5.c
 create mode 100644 SecureTransport/sslrec.c
 create mode 100644 SecureTransport/sslsess.c
 create mode 100644 SecureTransport/ssltrspt.c
 create mode 100644 SecureTransport/sslutil.c
 create mode 100644 SecureTransport/symCipher.c
 create mode 100644 Security.exp
 create mode 100644 Security.pbproj/.cvsignore
 create mode 100644 Security.pbproj/project.pbxproj
 create mode 100644 SecurityASN1/CVSVersionInfo.txt
 create mode 100644 SecurityASN1/Makefile
 create mode 100644 SecurityASN1/PkcsCms.pbproj/project.pbxproj
 create mode 100644 SecurityASN1/asn/appleoids.asn
 create mode 100644 SecurityASN1/asn/asn-useful.asn1
 create mode 100644 SecurityASN1/asn/pkcs1.asn1
 create mode 100644 SecurityASN1/asn/pkcs1oids.asn
 create mode 100644 SecurityASN1/asn/pkcs5.asn1
 create mode 100644 SecurityASN1/asn/pkcs7.asn
 create mode 100644 SecurityASN1/asn/pkcs8.asn
 create mode 100644 SecurityASN1/asn/pkcs9oids.asn
 create mode 100644 SecurityASN1/asn/sm_cms.asn
 create mode 100644 SecurityASN1/asn/sm_ess.asn
 create mode 100644 SecurityASN1/asn/sm_vdatypes.asn
 create mode 100644 SecurityASN1/asn/sm_x411mtsas.asn
 create mode 100644 SecurityASN1/asn/sm_x411ub.asn
 create mode 100644 SecurityASN1/asn/sm_x501if.asn
 create mode 100644 SecurityASN1/asn/sm_x501ud.asn
 create mode 100644 SecurityASN1/asn/sm_x509af.asn
 create mode 100644 SecurityASN1/asn/sm_x509ce.asn
 create mode 100644 SecurityASN1/asn/sm_x509cmn.asn
 create mode 100644 SecurityASN1/asn/sm_x520sa.asn
 create mode 100644 SecurityASN1/c++/.cvsignore
 create mode 100644 SecurityASN1/c++/appleoids.cpp
 create mode 100644 SecurityASN1/c++/pkcs1oids.cpp
 create mode 100644 SecurityASN1/c++/pkcs7.cpp
 create mode 100644 SecurityASN1/c++/pkcs8.cpp
 create mode 100644 SecurityASN1/c++/pkcs9oids.cpp
 create mode 100644 SecurityASN1/c++/sm_cms.cpp
 create mode 100644 SecurityASN1/c++/sm_ess.cpp
 create mode 100644 SecurityASN1/c++/sm_vdatypes.cpp
 create mode 100644 SecurityASN1/c++/sm_x411mtsas.cpp
 create mode 100644 SecurityASN1/c++/sm_x411ub.cpp
 create mode 100644 SecurityASN1/c++/sm_x501if.cpp
 create mode 100644 SecurityASN1/c++/sm_x501ud.cpp
 create mode 100644 SecurityASN1/c++/sm_x509af.cpp
 create mode 100644 SecurityASN1/c++/sm_x509ce.cpp
 create mode 100644 SecurityASN1/c++/sm_x509cmn.cpp
 create mode 100644 SecurityASN1/c++/sm_x520sa.cpp
 create mode 100644 SecurityASN1/inc/.cvsignore
 create mode 100644 SecurityASN1/inc/appleoids.h
 create mode 100644 SecurityASN1/inc/pkcs1oids.h
 create mode 100644 SecurityASN1/inc/pkcs7.h
 create mode 100644 SecurityASN1/inc/pkcs8.h
 create mode 100644 SecurityASN1/inc/pkcs9oids.h
 create mode 100644 SecurityASN1/inc/sm_cms.h
 create mode 100644 SecurityASN1/inc/sm_ess.h
 create mode 100644 SecurityASN1/inc/sm_vdatypes.h
 create mode 100644 SecurityASN1/inc/sm_x411mtsas.h
 create mode 100644 SecurityASN1/inc/sm_x411ub.h
 create mode 100644 SecurityASN1/inc/sm_x501if.h
 create mode 100644 SecurityASN1/inc/sm_x501ud.h
 create mode 100644 SecurityASN1/inc/sm_x509af.h
 create mode 100644 SecurityASN1/inc/sm_x509ce.h
 create mode 100644 SecurityASN1/inc/sm_x509cmn.h
 create mode 100644 SecurityASN1/inc/sm_x520sa.h
 create mode 100644 SecuritySNACCRuntime/.cvsignore
 create mode 100644 SecuritySNACCRuntime/Apple_README
 create mode 100644 SecuritySNACCRuntime/COPYING
 create mode 100644 SecuritySNACCRuntime/CVSVersionInfo.txt
 create mode 100644 SecuritySNACCRuntime/ChangeLog
 create mode 100644 SecuritySNACCRuntime/INSTALL
 create mode 100755 SecuritySNACCRuntime/MacOSX-Install
 create mode 100644 SecuritySNACCRuntime/MacOSX-configure
 create mode 100644 SecuritySNACCRuntime/MacOSX-make
 create mode 100644 SecuritySNACCRuntime/NEWS
 create mode 100644 SecuritySNACCRuntime/README
 create mode 100644 SecuritySNACCRuntime/VDADER_RULES.TXT
 create mode 100644 SecuritySNACCRuntime/acconfig.h
 create mode 100644 SecuritySNACCRuntime/asn1specs/any.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/asn-useful.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/asn1module.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/err-test.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/ex1.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/install-sh
 create mode 100644 SecuritySNACCRuntime/asn1specs/makefile
 create mode 100644 SecuritySNACCRuntime/asn1specs/p-rec.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/rfc1155-smi.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/rfc1157-snmp.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/rfc1213-mib2.asn1
 create mode 100644 SecuritySNACCRuntime/asn1specs/tbl.asn1
 create mode 100644 SecuritySNACCRuntime/c++-examples/any/README
 create mode 100644 SecuritySNACCRuntime/c++-examples/any/example.C
 create mode 100644 SecuritySNACCRuntime/c++-examples/any/genber.C
 create mode 100644 SecuritySNACCRuntime/c++-examples/any/makefile
 create mode 100644 SecuritySNACCRuntime/c++-examples/makefile
 create mode 100644 SecuritySNACCRuntime/c++-examples/simple/README
 create mode 100644 SecuritySNACCRuntime/c++-examples/simple/example.C
 create mode 100644 SecuritySNACCRuntime/c++-examples/simple/genber.C
 create mode 100644 SecuritySNACCRuntime/c++-examples/simple/good-pr.ber
 create mode 100644 SecuritySNACCRuntime/c++-examples/simple/makefile
 create mode 100644 SecuritySNACCRuntime/c++-examples/snmp/README
 create mode 100644 SecuritySNACCRuntime/c++-examples/snmp/makefile
 create mode 100644 SecuritySNACCRuntime/c++-examples/test-lib/README
 create mode 100644 SecuritySNACCRuntime/c++-examples/test-lib/makefile
 create mode 100644 SecuritySNACCRuntime/c++-examples/test-lib/test-lib.C
 create mode 100644 SecuritySNACCRuntime/c++-lib/README
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-any.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-bits.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-bool.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-enum.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-len.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-list.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-null.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-octs.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-real.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-tag.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-type.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/asn-useful.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/hash.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/meta.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/print.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/str-stk.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c
 create mode 100644 SecuritySNACCRuntime/c++-lib/dependencies
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-any.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-bits.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-bool.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-buf.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-config.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-enum.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-incl.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-int.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-len.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-list.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-null.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-octs.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-oid.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-real.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-tag.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-type.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/asn-useful.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/cdsaUtils.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/config.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/hash.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/init.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/meta.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/policy.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/print.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/sm_vdasnacc.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/sm_vdatypes.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/snacc.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/str-stk.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/inc/tcl-if.h
 create mode 100644 SecuritySNACCRuntime/c++-lib/install-sh
 create mode 100644 SecuritySNACCRuntime/c++-lib/makefile
 create mode 100644 SecuritySNACCRuntime/c++-lib/src/asn-useful.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/src/cdsaUtils.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/src/sm_buffer.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/src/sm_vdasnacc.cpp
 create mode 100644 SecuritySNACCRuntime/c++-lib/src/tkAppInit.c
 create mode 100644 SecuritySNACCRuntime/c++-lib/stamp-useful
 create mode 100644 SecuritySNACCRuntime/c-examples/any/README
 create mode 100644 SecuritySNACCRuntime/c-examples/any/example.c
 create mode 100644 SecuritySNACCRuntime/c-examples/any/genber.c
 create mode 100644 SecuritySNACCRuntime/c-examples/any/makefile
 create mode 100644 SecuritySNACCRuntime/c-examples/makefile
 create mode 100644 SecuritySNACCRuntime/c-examples/simple/README
 create mode 100644 SecuritySNACCRuntime/c-examples/simple/expbuf-ex.c
 create mode 100644 SecuritySNACCRuntime/c-examples/simple/genber.c
 create mode 100644 SecuritySNACCRuntime/c-examples/simple/good-pr.ber
 create mode 100644 SecuritySNACCRuntime/c-examples/simple/makefile
 create mode 100644 SecuritySNACCRuntime/c-examples/simple/minbuf-ex.c
 create mode 100644 SecuritySNACCRuntime/c-examples/simple/sbuf-ex.c
 create mode 100644 SecuritySNACCRuntime/c-examples/snmp/README
 create mode 100644 SecuritySNACCRuntime/c-examples/snmp/makefile
 create mode 100644 SecuritySNACCRuntime/c-examples/test-lib/README
 create mode 100644 SecuritySNACCRuntime/c-examples/test-lib/makefile
 create mode 100644 SecuritySNACCRuntime/c-examples/test-lib/test-lib.c
 create mode 100644 SecuritySNACCRuntime/c-lib/.cvsignore
 create mode 100644 SecuritySNACCRuntime/c-lib/README
 create mode 100644 SecuritySNACCRuntime/c-lib/asn-useful.c
 create mode 100644 SecuritySNACCRuntime/c-lib/asn-useful.h
 create mode 100644 SecuritySNACCRuntime/c-lib/boot/asn-useful.c
 create mode 100644 SecuritySNACCRuntime/c-lib/boot/asn-useful.h
 create mode 100644 SecuritySNACCRuntime/c-lib/boot/tbl.c
 create mode 100644 SecuritySNACCRuntime/c-lib/boot/tbl.h
 create mode 100644 SecuritySNACCRuntime/c-lib/dependencies
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-any.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-bits.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-bool.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-config.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-enum.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-incl.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-int.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-len.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-list.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-null.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-octs.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-oid.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-real.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-tag.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/asn-useful.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/exp-buf.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/gen-buf.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/hash.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/mem.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/min-buf.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/nibble-alloc.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/print.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/sbuf.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/str-stk.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-dbg.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-dec.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-enc.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-free.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-gen-c-hdr.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-gen.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-incl.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-print.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl-util.h
 create mode 100644 SecuritySNACCRuntime/c-lib/inc/tbl.h
 create mode 100644 SecuritySNACCRuntime/c-lib/install-sh
 create mode 100644 SecuritySNACCRuntime/c-lib/makefile
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-any.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-bits.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-bool.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-enum.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-int.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-len.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-list.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-null.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-octs.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-oid.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-real.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-tag.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/asn-useful.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/exp-buf.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/hash.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/nibble-alloc.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/print.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/sbuf.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/str-stk.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/tbl-dbg.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/tbl-dec.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/tbl-enc.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/tbl-free.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/tbl-gen.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/tbl-print.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/tbl-util.c
 create mode 100644 SecuritySNACCRuntime/c-lib/src/tbl.c
 create mode 100644 SecuritySNACCRuntime/c-lib/stamp-tbl
 create mode 100644 SecuritySNACCRuntime/c-lib/stamp-useful
 create mode 100644 SecuritySNACCRuntime/c-lib/tbl.c
 create mode 100644 SecuritySNACCRuntime/c-lib/tbl.h
 create mode 100644 SecuritySNACCRuntime/c-lib/tbl.h.patch
 create mode 100644 SecuritySNACCRuntime/compiler/README
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/.cvsignore
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any2.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code2.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals2.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd2.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/rules2.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/util.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/c-gen/util.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/cond.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/cond.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/str-util.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/str-util.h
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/tag-util.c
 create mode 100644 SecuritySNACCRuntime/compiler/back-ends/tag-util.h
 create mode 100644 SecuritySNACCRuntime/compiler/boot/tbl.c
 create mode 100644 SecuritySNACCRuntime/compiler/boot/tbl.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/.cvsignore
 create mode 100644 SecuritySNACCRuntime/compiler/core/asn1module.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/define.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/define.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/dependency.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/dependency.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/do-macros.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/do-macros.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/err-chk.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/err-chk.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/exports.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/exports.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/gen-tbls.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/gen-tbls.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/lex-asn1.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/lex-asn1.l
 create mode 100644 SecuritySNACCRuntime/compiler/core/lex-stuff.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/lib-types.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/lib-types.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/link-types.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/link-types.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/link-values.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/link-values.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/mem.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/meta.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/meta.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/normalize.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/normalize.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/oid.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/oid.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/parse-asn1.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/parse-asn1.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/parse-asn1.y
 create mode 100644 SecuritySNACCRuntime/compiler/core/parser.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/print.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/print.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/print2.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/recursive.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/recursive.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/snacc-util.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/snacc-util.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/snacc.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/tbl.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/tbl.h
 create mode 100644 SecuritySNACCRuntime/compiler/core/tblCompiler.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/val-parser.c
 create mode 100644 SecuritySNACCRuntime/compiler/core/val-parser.h
 create mode 100644 SecuritySNACCRuntime/compiler/dependencies
 create mode 100644 SecuritySNACCRuntime/compiler/install-sh
 create mode 100644 SecuritySNACCRuntime/compiler/makefile
 create mode 100644 SecuritySNACCRuntime/compiler/stamp-tbl
 create mode 100644 SecuritySNACCRuntime/compiler/tbl.c
 create mode 100644 SecuritySNACCRuntime/compiler/tbl.h
 create mode 100644 SecuritySNACCRuntime/config.cache
 create mode 100644 SecuritySNACCRuntime/config.h
 create mode 100644 SecuritySNACCRuntime/config.h.in
 create mode 100644 SecuritySNACCRuntime/config.log
 create mode 100644 SecuritySNACCRuntime/config.status
 create mode 100644 SecuritySNACCRuntime/configure
 create mode 100644 SecuritySNACCRuntime/configure.in
 create mode 100644 SecuritySNACCRuntime/doc/asn1-defs.tex
 create mode 100644 SecuritySNACCRuntime/doc/c++-gen.tex
 create mode 100644 SecuritySNACCRuntime/doc/c++-lib.tex
 create mode 100644 SecuritySNACCRuntime/doc/c-gen.tex
 create mode 100644 SecuritySNACCRuntime/doc/c-lib.tex
 create mode 100644 SecuritySNACCRuntime/doc/coding.tex
 create mode 100644 SecuritySNACCRuntime/doc/corba.bib
 create mode 100644 SecuritySNACCRuntime/doc/design.tex
 create mode 100644 SecuritySNACCRuntime/doc/editor.tex
 create mode 100644 SecuritySNACCRuntime/doc/future-work.tex
 create mode 100644 SecuritySNACCRuntime/doc/idl-gen.tex
 create mode 100644 SecuritySNACCRuntime/doc/install-sh
 create mode 100644 SecuritySNACCRuntime/doc/intro-1.1.tex
 create mode 100644 SecuritySNACCRuntime/doc/intro-1.2.tex
 create mode 100644 SecuritySNACCRuntime/doc/makefile
 create mode 100644 SecuritySNACCRuntime/doc/makefile.tex
 create mode 100644 SecuritySNACCRuntime/doc/meta.tex
 create mode 100644 SecuritySNACCRuntime/doc/misc-hyph.tex
 create mode 100644 SecuritySNACCRuntime/doc/mkchdr.1
 create mode 100644 SecuritySNACCRuntime/doc/modifying.tex
 create mode 100644 SecuritySNACCRuntime/doc/ptbl.1
 create mode 100644 SecuritySNACCRuntime/doc/pval.1
 create mode 100644 SecuritySNACCRuntime/doc/snacc.1
 create mode 100644 SecuritySNACCRuntime/doc/snacc.bib
 create mode 100644 SecuritySNACCRuntime/doc/snacc.n
 create mode 100644 SecuritySNACCRuntime/doc/snacc.tex
 create mode 100644 SecuritySNACCRuntime/doc/snacced.1
 create mode 100644 SecuritySNACCRuntime/doc/tcl.bib
 create mode 100644 SecuritySNACCRuntime/doc/tcl.tex
 create mode 100644 SecuritySNACCRuntime/doc/ttab.tex
 create mode 100644 SecuritySNACCRuntime/doc/tumble.sed
 create mode 100644 SecuritySNACCRuntime/doc/version.tex
 create mode 100644 SecuritySNACCRuntime/install-sh
 create mode 100644 SecuritySNACCRuntime/makefile
 create mode 100644 SecuritySNACCRuntime/makehead
 create mode 100644 SecuritySNACCRuntime/makehead.in
 create mode 100644 SecuritySNACCRuntime/makehead.static
 create mode 100644 SecuritySNACCRuntime/maketail
 create mode 100644 SecuritySNACCRuntime/mkinstalldirs
 create mode 100644 SecuritySNACCRuntime/policy.h
 create mode 100644 SecuritySNACCRuntime/snacc.h
 create mode 100644 SecuritySNACCRuntime/snacc.pbproj/project.pbxproj
 create mode 100644 SecuritySNACCRuntime/stamp-h
 create mode 100644 SecuritySNACCRuntime/stamp-h.in
 create mode 100644 SecuritySNACCRuntime/tbl-example/README
 create mode 100644 SecuritySNACCRuntime/tbl-example/dependencies
 create mode 100644 SecuritySNACCRuntime/tbl-example/example.c
 create mode 100644 SecuritySNACCRuntime/tbl-example/makefile
 create mode 100644 SecuritySNACCRuntime/tbl-example/p-rec.ber
 create mode 100644 SecuritySNACCRuntime/tbl-example/p-rec.h
 create mode 100644 SecuritySNACCRuntime/tbl-example/p-rec.tt
 create mode 100644 SecuritySNACCRuntime/tbl-tools/makefile
 create mode 100644 SecuritySNACCRuntime/tcl-asn/README
 create mode 100644 SecuritySNACCRuntime/tcl-asn/asnwish.c
 create mode 100644 SecuritySNACCRuntime/tcl-asn/beredit
 create mode 100644 SecuritySNACCRuntime/tcl-asn/makefile
 create mode 100644 SecuritySNACCRuntime/tcl-asn/tclasn.c
 create mode 100644 SecuritySNACCRuntime/tcl-example/dependencies
 create mode 100644 SecuritySNACCRuntime/tcl-example/edex0.asn1
 create mode 100644 SecuritySNACCRuntime/tcl-example/edex1.asn1
 create mode 100644 SecuritySNACCRuntime/tcl-example/makefile
 create mode 100644 SecuritySNACCRuntime/tcl-lib/bindings.tcl
 create mode 100644 SecuritySNACCRuntime/tcl-lib/help.tcl
 create mode 100644 SecuritySNACCRuntime/tcl-lib/make-snacced
 create mode 100644 SecuritySNACCRuntime/tcl-lib/makefile
 create mode 100644 SecuritySNACCRuntime/tcl-lib/selbox.tcl
 create mode 100644 SecuritySNACCRuntime/tcl-lib/snacced.tcl
 create mode 100644 SecuritySNACCRuntime/tcl-lib/tkuti.tcl
 create mode 100644 SecuritySNACCRuntime/tcl-lib/uti.tcl
 create mode 100644 SecuritySNACCRuntime/tcl-p.c
 create mode 100644 SecuritySNACCRuntime/version.h
 create mode 100644 SecurityServer/AZNTest.cpp
 create mode 100644 SecurityServer/Authorization/AuthSession.h
 create mode 100644 SecurityServer/Authorization/Authorization.cpp
 create mode 100644 SecurityServer/Authorization/Authorization.h
 create mode 100644 SecurityServer/Authorization/AuthorizationEngine.cpp
 create mode 100644 SecurityServer/Authorization/AuthorizationEngine.h
 create mode 100644 SecurityServer/Authorization/AuthorizationPlugin.h
 create mode 100644 SecurityServer/Authorization/AuthorizationTags.h
 create mode 100644 SecurityServer/Authorization/AuthorizationTrampoline.cpp
 create mode 100644 SecurityServer/Authorization/AuthorizationWalkers.h
 create mode 100644 SecurityServer/Authorization/authorization.plist
 create mode 100644 SecurityServer/Authorization/trampolineClient.cpp
 create mode 100644 SecurityServer/Authorization/trampolineServer.cpp
 create mode 100644 SecurityServer/BLOBFORMAT
 create mode 100644 SecurityServer/CVSVersionInfo.txt
 create mode 100644 SecurityServer/MacYarrow/MacYarrow.pbproj/project.pbxproj
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/MacYarrow_OSX.cpp
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/MacYarrow_OSX.h
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/YarrowLib_OS9.mcp.exp
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/YarrowServer_OS9.c
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/YarrowServer_OS9.h
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.cpp
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.h
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/debug.c
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/debug.h
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/entropyFile.h
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/entropyFileOS9.c
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/entropyFileUnix.c
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/kdebug_private.h
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/prefixDebug.h
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/prefixRelease.h
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/systemEntropy.c
 create mode 100644 SecurityServer/MacYarrow/YarrowServer/systemEntropy.h
 create mode 100644 SecurityServer/MacYarrow/testHarness/clientTest.cpp
 create mode 100644 SecurityServer/MacYarrow/testHarness/serverDaemon.cpp
 create mode 100644 SecurityServer/MacYarrow/yarrowseed.cpp
 create mode 100644 SecurityServer/MacYarrow/yarrowseed.h
 create mode 100644 SecurityServer/MacYarrow/zlib/ChangeLog
 create mode 100644 SecurityServer/MacYarrow/zlib/README
 create mode 100644 SecurityServer/MacYarrow/zlib/adler32.c
 create mode 100644 SecurityServer/MacYarrow/zlib/algorithm.txt
 create mode 100644 SecurityServer/MacYarrow/zlib/compress.c
 create mode 100644 SecurityServer/MacYarrow/zlib/crc32.c
 create mode 100644 SecurityServer/MacYarrow/zlib/deflate.c
 create mode 100644 SecurityServer/MacYarrow/zlib/deflate.h
 create mode 100644 SecurityServer/MacYarrow/zlib/infblock.c
 create mode 100644 SecurityServer/MacYarrow/zlib/infblock.h
 create mode 100644 SecurityServer/MacYarrow/zlib/infcodes.c
 create mode 100644 SecurityServer/MacYarrow/zlib/infcodes.h
 create mode 100644 SecurityServer/MacYarrow/zlib/inffast.c
 create mode 100644 SecurityServer/MacYarrow/zlib/inffast.h
 create mode 100644 SecurityServer/MacYarrow/zlib/inffixed.h
 create mode 100644 SecurityServer/MacYarrow/zlib/inflate.c
 create mode 100644 SecurityServer/MacYarrow/zlib/inftrees.c
 create mode 100644 SecurityServer/MacYarrow/zlib/inftrees.h
 create mode 100644 SecurityServer/MacYarrow/zlib/infutil.c
 create mode 100644 SecurityServer/MacYarrow/zlib/infutil.h
 create mode 100644 SecurityServer/MacYarrow/zlib/trees.c
 create mode 100644 SecurityServer/MacYarrow/zlib/trees.h
 create mode 100644 SecurityServer/MacYarrow/zlib/uncompr.c
 create mode 100644 SecurityServer/MacYarrow/zlib/zconf.h
 create mode 100644 SecurityServer/MacYarrow/zlib/zlib.h
 create mode 100644 SecurityServer/MacYarrow/zlib/zlib.mcp
 create mode 100644 SecurityServer/MacYarrow/zlib/zutil.c
 create mode 100644 SecurityServer/MacYarrow/zlib/zutil.h
 create mode 100644 SecurityServer/Makefile
 create mode 100644 SecurityServer/Makefile.startup
 create mode 100644 SecurityServer/SecurityAgentClient.cpp
 create mode 100644 SecurityServer/SecurityAgentClient.h
 create mode 100644 SecurityServer/SecurityServer.order
 create mode 100644 SecurityServer/SecurityServer.pbxproj/.cvsignore
 create mode 100644 SecurityServer/SecurityServer.pbxproj/project.pbxproj
 create mode 100644 SecurityServer/SecurityServerClient.h
 create mode 100755 SecurityServer/SettingsDialog/English.lproj/InfoPlist.strings
 create mode 100755 SecurityServer/SettingsDialog/English.lproj/MainMenu.nib/classes.nib
 create mode 100755 SecurityServer/SettingsDialog/English.lproj/MainMenu.nib/objects.nib
 create mode 100755 SecurityServer/SettingsDialog/SecuritySettings.icns
 create mode 100644 SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore
 create mode 100755 SecurityServer/SettingsDialog/SecuritySettings.pbproj/project.pbxproj
 create mode 100755 SecurityServer/SettingsDialog/SettingsWindow.h
 create mode 100644 SecurityServer/SettingsDialog/SettingsWindow.m
 create mode 100755 SecurityServer/SettingsDialog/main.m
 create mode 100644 SecurityServer/StartupItems/Localizable.strings
 create mode 100755 SecurityServer/StartupItems/SecurityServer
 create mode 100644 SecurityServer/StartupItems/StartupParameters.plist
 create mode 100644 SecurityServer/TODO
 create mode 100644 SecurityServer/acl_keychain.cpp
 create mode 100644 SecurityServer/acl_keychain.h
 create mode 100644 SecurityServer/acls.cpp
 create mode 100644 SecurityServer/acls.h
 create mode 100644 SecurityServer/agentquery.cpp
 create mode 100644 SecurityServer/agentquery.h
 create mode 100644 SecurityServer/authority.cpp
 create mode 100644 SecurityServer/authority.h
 create mode 100644 SecurityServer/cfnotifier.cpp
 create mode 100644 SecurityServer/cfnotifier.h
 create mode 100644 SecurityServer/connection.cpp
 create mode 100644 SecurityServer/connection.h
 create mode 100644 SecurityServer/dbcrypto.cpp
 create mode 100644 SecurityServer/dbcrypto.h
 create mode 100644 SecurityServer/key.cpp
 create mode 100644 SecurityServer/key.h
 create mode 100644 SecurityServer/main.cpp
 create mode 100644 SecurityServer/process.cpp
 create mode 100644 SecurityServer/process.h
 create mode 100644 SecurityServer/secagent.defs
 create mode 100644 SecurityServer/secagent_types.h
 create mode 100644 SecurityServer/securityserver.h
 create mode 100644 SecurityServer/server.cpp
 create mode 100644 SecurityServer/server.h
 create mode 100644 SecurityServer/session.cpp
 create mode 100644 SecurityServer/session.h
 create mode 100644 SecurityServer/ssblob.cpp
 create mode 100644 SecurityServer/ssblob.h
 create mode 100644 SecurityServer/ssclient.cpp
 create mode 100644 SecurityServer/ssclient.h
 create mode 100644 SecurityServer/sstransit.cpp
 create mode 100644 SecurityServer/sstransit.h
 create mode 100644 SecurityServer/tests/AZNTest.cpp
 create mode 100644 SecurityServer/tests/auth.plist
 create mode 100644 SecurityServer/tests/exectest.cpp
 create mode 100644 SecurityServer/tests/testacls.cpp
 create mode 100644 SecurityServer/tests/testauth.cpp
 create mode 100644 SecurityServer/tests/testblobs.cpp
 create mode 100644 SecurityServer/tests/testclient.cpp
 create mode 100644 SecurityServer/tests/testclient.h
 create mode 100644 SecurityServer/tests/testcrypto.cpp
 create mode 100644 SecurityServer/tests/testutils.cpp
 create mode 100644 SecurityServer/tests/testutils.h
 create mode 100644 SecurityServer/transition.cpp
 create mode 100644 SecurityServer/ucsp.defs
 create mode 100644 SecurityServer/ucsp_types.h
 create mode 100644 SecurityServer/xdatabase.cpp
 create mode 100644 SecurityServer/xdatabase.h
 create mode 100644 SecurityServer/yarrowMigTypes.h
 create mode 100644 cdsa/CVSVersionInfo.txt
 create mode 100644 cdsa/TODO
 create mode 100644 cdsa/cdsa.cpp
 create mode 100644 cdsa/cdsa.pbxproj/.cvsignore
 create mode 100644 cdsa/cdsa.pbxproj/project.pbxproj
 create mode 100644 cdsa/cdsa/certextensions.h
 create mode 100644 cdsa/cdsa/cssm.h
 create mode 100644 cdsa/cdsa/cssmaci.h
 create mode 100644 cdsa/cdsa/cssmapi.h
 create mode 100644 cdsa/cdsa/cssmapple.h
 create mode 100644 cdsa/cdsa/cssmcli.h
 create mode 100644 cdsa/cdsa/cssmconfig.h
 create mode 100644 cdsa/cdsa/cssmcspi.h
 create mode 100644 cdsa/cdsa/cssmdli.h
 create mode 100644 cdsa/cdsa/cssmerr.h
 create mode 100644 cdsa/cdsa/cssmkrapi.h
 create mode 100644 cdsa/cdsa/cssmkrspi.h
 create mode 100644 cdsa/cdsa/cssmspi.h
 create mode 100644 cdsa/cdsa/cssmtpi.h
 create mode 100644 cdsa/cdsa/cssmtype.h
 create mode 100644 cdsa/cdsa/eisl.h
 create mode 100644 cdsa/cdsa/emmspi.h
 create mode 100644 cdsa/cdsa/emmtype.h
 create mode 100644 cdsa/cdsa/mds.h
 create mode 100644 cdsa/cdsa/mds_schema.h
 create mode 100644 cdsa/cdsa/oidsalg.h
 create mode 100644 cdsa/cdsa/oidsattr.h
 create mode 100644 cdsa/cdsa/oidsbase.h
 create mode 100644 cdsa/cdsa/oidscert.h
 create mode 100644 cdsa/cdsa/oidscrl.h
 create mode 100644 cdsa/cdsa/x509defs.h
 create mode 100644 cdsa/cdsa_client.cpp
 create mode 100644 cdsa/cdsa_client/DLDBList.cpp
 create mode 100644 cdsa/cdsa_client/DLDBList.h
 create mode 100644 cdsa/cdsa_client/aclclient.h
 create mode 100644 cdsa/cdsa_client/aclsupport.cpp
 create mode 100644 cdsa/cdsa_client/aclsupport.h
 create mode 100644 cdsa/cdsa_client/cryptoclient.cpp
 create mode 100644 cdsa/cdsa_client/cryptoclient.h
 create mode 100644 cdsa/cdsa_client/cspclient.cpp
 create mode 100644 cdsa/cdsa_client/cspclient.h
 create mode 100644 cdsa/cdsa_client/cssmclient.cpp
 create mode 100644 cdsa/cdsa_client/cssmclient.h
 create mode 100644 cdsa/cdsa_client/dlclient.cpp
 create mode 100644 cdsa/cdsa_client/dlclient.h
 create mode 100644 cdsa/cdsa_client/genkey.cpp
 create mode 100644 cdsa/cdsa_client/genkey.h
 create mode 100644 cdsa/cdsa_client/keychainacl.cpp
 create mode 100644 cdsa/cdsa_client/keychainacl.h
 create mode 100644 cdsa/cdsa_client/keyclient.cpp
 create mode 100644 cdsa/cdsa_client/keyclient.h
 create mode 100644 cdsa/cdsa_client/macclient.cpp
 create mode 100644 cdsa/cdsa_client/macclient.h
 create mode 100644 cdsa/cdsa_client/multidldb.cpp
 create mode 100644 cdsa/cdsa_client/multidldb.h
 create mode 100644 cdsa/cdsa_client/osxsigner.cpp
 create mode 100644 cdsa/cdsa_client/osxsigner.h
 create mode 100644 cdsa/cdsa_client/securestorage.cpp
 create mode 100644 cdsa/cdsa_client/securestorage.h
 create mode 100644 cdsa/cdsa_client/signclient.cpp
 create mode 100644 cdsa/cdsa_client/signclient.h
 create mode 100644 cdsa/cdsa_client/wrapkey.cpp
 create mode 100644 cdsa/cdsa_client/wrapkey.h
 create mode 100644 cdsa/cdsa_pluginlib.cpp
 create mode 100644 cdsa/cdsa_pluginlib/.cvsignore
 create mode 100644 cdsa/cdsa_pluginlib/ACsession.h
 create mode 100644 cdsa/cdsa_pluginlib/CLsession.h
 create mode 100644 cdsa/cdsa_pluginlib/CSPsession.cpp
 create mode 100644 cdsa/cdsa_pluginlib/CSPsession.h
 create mode 100644 cdsa/cdsa_pluginlib/DLsession.cpp
 create mode 100644 cdsa/cdsa_pluginlib/DLsession.h
 create mode 100644 cdsa/cdsa_pluginlib/TPsession.h
 create mode 100644 cdsa/cdsa_pluginlib/c++plugin.h
 create mode 100644 cdsa/cdsa_pluginlib/csputilities.cpp
 create mode 100644 cdsa/cdsa_pluginlib/cssmplugin.cpp
 create mode 100644 cdsa/cdsa_pluginlib/cssmplugin.h
 create mode 100644 cdsa/cdsa_pluginlib/generator.cfg
 create mode 100644 cdsa/cdsa_pluginlib/generator.mk
 create mode 100644 cdsa/cdsa_pluginlib/generator.pl
 create mode 100644 cdsa/cdsa_pluginlib/pluginsession.cpp
 create mode 100644 cdsa/cdsa_pluginlib/pluginsession.h
 create mode 100644 cdsa/cdsa_pluginlib/pluginspi.h
 create mode 100644 cdsa/cdsa_utilities.cpp
 create mode 100644 cdsa/cdsa_utilities/.cvsignore
 create mode 100644 cdsa/cdsa_utilities/AppleDatabase.cpp
 create mode 100644 cdsa/cdsa_utilities/AppleDatabase.h
 create mode 100644 cdsa/cdsa_utilities/AtomicFile.cpp
 create mode 100644 cdsa/cdsa_utilities/AtomicFile.h
 create mode 100644 cdsa/cdsa_utilities/Database.cpp
 create mode 100644 cdsa/cdsa_utilities/Database.h
 create mode 100644 cdsa/cdsa_utilities/DatabaseSession.cpp
 create mode 100644 cdsa/cdsa_utilities/DatabaseSession.h
 create mode 100644 cdsa/cdsa_utilities/DbContext.cpp
 create mode 100644 cdsa/cdsa_utilities/DbContext.h
 create mode 100644 cdsa/cdsa_utilities/DbIndex.cpp
 create mode 100644 cdsa/cdsa_utilities/DbIndex.h
 create mode 100644 cdsa/cdsa_utilities/DbName.cpp
 create mode 100644 cdsa/cdsa_utilities/DbName.h
 create mode 100644 cdsa/cdsa_utilities/DbQuery.cpp
 create mode 100644 cdsa/cdsa_utilities/DbQuery.h
 create mode 100644 cdsa/cdsa_utilities/DbValue.cpp
 create mode 100644 cdsa/cdsa_utilities/DbValue.h
 create mode 100644 cdsa/cdsa_utilities/MetaAttribute.cpp
 create mode 100644 cdsa/cdsa_utilities/MetaAttribute.h
 create mode 100644 cdsa/cdsa_utilities/MetaRecord.cpp
 create mode 100644 cdsa/cdsa_utilities/MetaRecord.h
 create mode 100644 cdsa/cdsa_utilities/NOTES
 create mode 100644 cdsa/cdsa_utilities/ReadWriteSection.h
 create mode 100644 cdsa/cdsa_utilities/SampleGroup.cpp
 create mode 100644 cdsa/cdsa_utilities/SampleGroup.h
 create mode 100644 cdsa/cdsa_utilities/SelectionPredicate.cpp
 create mode 100644 cdsa/cdsa_utilities/SelectionPredicate.h
 create mode 100644 cdsa/cdsa_utilities/acl_any.cpp
 create mode 100644 cdsa/cdsa_utilities/acl_any.h
 create mode 100644 cdsa/cdsa_utilities/acl_codesigning.cpp
 create mode 100644 cdsa/cdsa_utilities/acl_codesigning.h
 create mode 100644 cdsa/cdsa_utilities/acl_comment.cpp
 create mode 100644 cdsa/cdsa_utilities/acl_comment.h
 create mode 100644 cdsa/cdsa_utilities/acl_keychain.cpp
 create mode 100644 cdsa/cdsa_utilities/acl_keychain.h
 create mode 100644 cdsa/cdsa_utilities/acl_password.cpp
 create mode 100644 cdsa/cdsa_utilities/acl_password.h
 create mode 100644 cdsa/cdsa_utilities/acl_process.cpp
 create mode 100644 cdsa/cdsa_utilities/acl_process.h
 create mode 100644 cdsa/cdsa_utilities/acl_threshold.cpp
 create mode 100644 cdsa/cdsa_utilities/acl_threshold.h
 create mode 100644 cdsa/cdsa_utilities/bufferfifo.cpp
 create mode 100644 cdsa/cdsa_utilities/bufferfifo.h
 create mode 100644 cdsa/cdsa_utilities/buffers.cpp
 create mode 100644 cdsa/cdsa_utilities/buffers.h
 create mode 100644 cdsa/cdsa_utilities/callback.cpp
 create mode 100644 cdsa/cdsa_utilities/callback.h
 create mode 100644 cdsa/cdsa_utilities/codesigning.cpp
 create mode 100644 cdsa/cdsa_utilities/codesigning.h
 create mode 100644 cdsa/cdsa_utilities/constdata.cpp
 create mode 100644 cdsa/cdsa_utilities/constdata.h
 create mode 100644 cdsa/cdsa_utilities/context.cpp
 create mode 100644 cdsa/cdsa_utilities/context.h
 create mode 100644 cdsa/cdsa_utilities/cssmacl.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmacl.h
 create mode 100644 cdsa/cdsa_utilities/cssmaclpod.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmaclpod.h
 create mode 100644 cdsa/cdsa_utilities/cssmalloc.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmalloc.h
 create mode 100644 cdsa/cdsa_utilities/cssmcred.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmcred.h
 create mode 100644 cdsa/cdsa_utilities/cssmdata.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmdata.h
 create mode 100644 cdsa/cdsa_utilities/cssmdates.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmdates.h
 create mode 100644 cdsa/cdsa_utilities/cssmdb.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmdb.h
 create mode 100644 cdsa/cdsa_utilities/cssmerrno.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmerrno.h
 create mode 100644 cdsa/cdsa_utilities/cssmlist.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmlist.h
 create mode 100644 cdsa/cdsa_utilities/cssmwalkers.cpp
 create mode 100644 cdsa/cdsa_utilities/cssmwalkers.h
 create mode 100644 cdsa/cdsa_utilities/daemon.cpp
 create mode 100644 cdsa/cdsa_utilities/daemon.h
 create mode 100644 cdsa/cdsa_utilities/debugging.cpp
 create mode 100644 cdsa/cdsa_utilities/debugging.h
 create mode 100644 cdsa/cdsa_utilities/debugsupport.h
 create mode 100644 cdsa/cdsa_utilities/devrandom.cpp
 create mode 100644 cdsa/cdsa_utilities/devrandom.h
 create mode 100644 cdsa/cdsa_utilities/fdsel.cpp
 create mode 100644 cdsa/cdsa_utilities/fdsel.h
 create mode 100644 cdsa/cdsa_utilities/generator.mk
 create mode 100644 cdsa/cdsa_utilities/generator.pl
 create mode 100644 cdsa/cdsa_utilities/globalizer.cpp
 create mode 100644 cdsa/cdsa_utilities/globalizer.h
 create mode 100644 cdsa/cdsa_utilities/guids.cpp
 create mode 100644 cdsa/cdsa_utilities/handleobject.cpp
 create mode 100644 cdsa/cdsa_utilities/handleobject.h
 create mode 100644 cdsa/cdsa_utilities/headermap.cpp
 create mode 100644 cdsa/cdsa_utilities/headermap.h
 create mode 100644 cdsa/cdsa_utilities/hosts.cpp
 create mode 100644 cdsa/cdsa_utilities/hosts.h
 create mode 100644 cdsa/cdsa_utilities/inetreply.cpp
 create mode 100644 cdsa/cdsa_utilities/inetreply.h
 create mode 100644 cdsa/cdsa_utilities/ip++.cpp
 create mode 100644 cdsa/cdsa_utilities/ip++.h
 create mode 100644 cdsa/cdsa_utilities/logging.cpp
 create mode 100644 cdsa/cdsa_utilities/logging.h
 create mode 100644 cdsa/cdsa_utilities/mach++.cpp
 create mode 100644 cdsa/cdsa_utilities/mach++.h
 create mode 100644 cdsa/cdsa_utilities/mach_notify.c
 create mode 100644 cdsa/cdsa_utilities/mach_notify.h
 create mode 100644 cdsa/cdsa_utilities/machrunloopserver.cpp
 create mode 100644 cdsa/cdsa_utilities/machrunloopserver.h
 create mode 100644 cdsa/cdsa_utilities/machserver.cpp
 create mode 100644 cdsa/cdsa_utilities/machserver.h
 create mode 100644 cdsa/cdsa_utilities/memutils.h
 create mode 100644 cdsa/cdsa_utilities/os9utils.cpp
 create mode 100644 cdsa/cdsa_utilities/os9utils.h
 create mode 100644 cdsa/cdsa_utilities/osxsigning.cpp
 create mode 100644 cdsa/cdsa_utilities/osxsigning.h
 create mode 100644 cdsa/cdsa_utilities/powerwatch.cpp
 create mode 100644 cdsa/cdsa_utilities/powerwatch.h
 create mode 100644 cdsa/cdsa_utilities/refcount.h
 create mode 100644 cdsa/cdsa_utilities/selector.cpp
 create mode 100644 cdsa/cdsa_utilities/selector.h
 create mode 100644 cdsa/cdsa_utilities/socks++.cpp
 create mode 100644 cdsa/cdsa_utilities/socks++.h
 create mode 100644 cdsa/cdsa_utilities/socks++4.cpp
 create mode 100644 cdsa/cdsa_utilities/socks++4.h
 create mode 100644 cdsa/cdsa_utilities/socks++5.cpp
 create mode 100644 cdsa/cdsa_utilities/socks++5.h
 create mode 100644 cdsa/cdsa_utilities/streams.cpp
 create mode 100644 cdsa/cdsa_utilities/streams.h
 create mode 100644 cdsa/cdsa_utilities/threading.cpp
 create mode 100644 cdsa/cdsa_utilities/threading.h
 create mode 100644 cdsa/cdsa_utilities/threading_internal.h
 create mode 100644 cdsa/cdsa_utilities/timeflow.cpp
 create mode 100644 cdsa/cdsa_utilities/timeflow.h
 create mode 100644 cdsa/cdsa_utilities/tqueue.cpp
 create mode 100644 cdsa/cdsa_utilities/tqueue.h
 create mode 100644 cdsa/cdsa_utilities/typedvalue.cpp
 create mode 100644 cdsa/cdsa_utilities/typedvalue.h
 create mode 100644 cdsa/cdsa_utilities/uniformrandom.cpp
 create mode 100644 cdsa/cdsa_utilities/uniformrandom.h
 create mode 100644 cdsa/cdsa_utilities/unix++.cpp
 create mode 100644 cdsa/cdsa_utilities/unix++.h
 create mode 100644 cdsa/cdsa_utilities/url.cpp
 create mode 100644 cdsa/cdsa_utilities/url.h
 create mode 100644 cdsa/cdsa_utilities/utilities.cpp
 create mode 100644 cdsa/cdsa_utilities/utilities.h
 create mode 100644 cdsa/cdsa_utilities/utility_config.h
 create mode 100644 cdsa/cdsa_utilities/walkers.cpp
 create mode 100644 cdsa/cdsa_utilities/walkers.h
 create mode 100644 cdsa/cssm/.cvsignore
 create mode 100644 cdsa/cssm/MDS
 create mode 100644 cdsa/cssm/attachfactory.cpp
 create mode 100644 cdsa/cssm/attachfactory.h
 create mode 100644 cdsa/cssm/attachment.cpp
 create mode 100644 cdsa/cssm/attachment.h
 create mode 100644 cdsa/cssm/builtin_modules.cpp
 create mode 100644 cdsa/cssm/cspattachment.cpp
 create mode 100644 cdsa/cssm/cspattachment.h
 create mode 100644 cdsa/cssm/cssm.cpp
 create mode 100644 cdsa/cssm/cssmcontext.cpp
 create mode 100644 cdsa/cssm/cssmcontext.h
 create mode 100644 cdsa/cssm/cssmint.h
 create mode 100644 cdsa/cssm/cssmmds.cpp
 create mode 100644 cdsa/cssm/cssmmds.h
 create mode 100644 cdsa/cssm/generator.cfg
 create mode 100644 cdsa/cssm/generator.mk
 create mode 100644 cdsa/cssm/generator.pl
 create mode 100644 cdsa/cssm/manager.cpp
 create mode 100644 cdsa/cssm/manager.h
 create mode 100644 cdsa/cssm/modload_plugin.cpp
 create mode 100644 cdsa/cssm/modload_plugin.h
 create mode 100644 cdsa/cssm/modload_static.cpp
 create mode 100644 cdsa/cssm/modload_static.h
 create mode 100644 cdsa/cssm/modloader.cpp
 create mode 100644 cdsa/cssm/modloader.h
 create mode 100644 cdsa/cssm/module.cpp
 create mode 100644 cdsa/cssm/module.h
 create mode 100644 cdsa/cssm/oidsalg.c
 create mode 100644 cdsa/cssm/oidsattr.c
 create mode 100644 cdsa/cssm/oidscert.cpp
 create mode 100644 cdsa/cssm/oidscrl.cpp
 create mode 100644 cdsa/cssm/transition.cpp
 create mode 100644 cdsa/generator.mk
 create mode 100644 cdsa/mds/.cvsignore
 create mode 100644 cdsa/mds/MDSDatabase.cpp
 create mode 100644 cdsa/mds/MDSDatabase.h
 create mode 100644 cdsa/mds/MDSModule.cpp
 create mode 100644 cdsa/mds/MDSModule.h
 create mode 100644 cdsa/mds/MDSPrefs.cpp
 create mode 100644 cdsa/mds/MDSPrefs.h
 create mode 100644 cdsa/mds/MDSSchema.cpp
 create mode 100644 cdsa/mds/MDSSchema.h
 create mode 100644 cdsa/mds/MDSSession.cpp
 create mode 100644 cdsa/mds/MDSSession.h
 create mode 100644 cdsa/mds/NOTES
 create mode 100644 cdsa/mds/mds.mcp
 create mode 100644 cdsa/mds/mdsapi.cpp
 create mode 100644 checkpw/checkpw.c
 create mode 100644 checkpw/checkpw.h
 create mode 100755 symbol_strip.sh

diff --git a/APPLE_LICENSE b/APPLE_LICENSE
new file mode 100644
index 00000000..a0a84169
--- /dev/null
+++ b/APPLE_LICENSE
@@ -0,0 +1,372 @@
+APPLE PUBLIC SOURCE LICENSE
+Version 1.1 - April 19,1999
+
+Please read this License carefully before downloading this software.
+By downloading and using this software, you are agreeing to be bound
+by the terms of this License.  If you do not or cannot agree to the
+terms of this License, please do not download or use the software.
+
+1. General; Definitions.  This License applies to any program or other
+work which Apple Computer, Inc. ("Apple") publicly announces as
+subject to this Apple Public Source License and which contains a
+notice placed by Apple identifying such program or work as "Original
+Code" and stating that it is subject to the terms of this Apple Public
+Source License version 1.1 (or subsequent version thereof), as it may
+be revised from time to time by Apple ("License").  As used in this
+License:
+
+1.1 "Affected Original Code" means only those specific portions of
+Original Code that allegedly infringe upon any party's intellectual
+property rights or are otherwise the subject of a claim of
+infringement.
+
+1.2 "Applicable Patent Rights" mean: (a) in the case where Apple is
+the grantor of rights, (i) claims of patents that are now or hereafter
+acquired, owned by or assigned to Apple and (ii) that cover subject
+matter contained in the Original Code, but only to the extent
+necessary to use, reproduce and/or distribute the Original Code
+without infringement; and (b) in the case where You are the grantor of
+rights, (i) claims of patents that are now or hereafter acquired,
+owned by or assigned to You and (ii) that cover subject matter in Your
+Modifications, taken alone or in combination with Original Code.
+
+1.3 "Covered Code" means the Original Code, Modifications, the
+combination of Original Code and any Modifications, and/or any
+respective portions thereof.
+
+1.4 "Deploy" means to use, sublicense or distribute Covered Code other
+than for Your internal research and development (R&D), and includes
+without limitation, any and all internal use or distribution of
+Covered Code within Your business or organization except for R&D use,
+as well as direct or indirect sublicensing or distribution of Covered
+Code by You to any third party in any form or manner.
+
+1.5 "Larger Work" means a work which combines Covered Code or portions
+thereof with code not governed by the terms of this License.
+
+1.6 "Modifications" mean any addition to, deletion from, and/or change
+to, the substance and/or structure of Covered Code.  When code is
+released as a series of files, a Modification is: (a) any addition to
+or deletion from the contents of a file containing Covered Code;
+and/or (b) any new file or other representation of computer program
+statements that contains any part of Covered Code.
+
+1.7 "Original Code" means (a) the Source Code of a program or other
+work as originally made available by Apple under this License,
+including the Source Code of any updates or upgrades to such programs
+or works made available by Apple under this License, and that has been
+expressly identified by Apple as such in the header file(s) of such
+work; and (b) the object code compiled from such Source Code and
+originally made available by Apple under this License.
+
+1.8 "Source Code" means the human readable form of a program or other
+work that is suitable for making modifications to it, including all
+modules it contains, plus any associated interface definition files,
+scripts used to control compilation and installation of an executable
+(object code).
+
+1.9 "You" or "Your" means an individual or a legal entity exercising
+rights under this License.  For legal entities, "You" or "Your"
+includes any entity which controls, is controlled by, or is under
+common control with, You, where "control" means (a) the power, direct
+or indirect, to cause the direction or management of such entity,
+whether by contract or otherwise, or (b) ownership of fifty percent
+(50%) or more of the outstanding shares or beneficial ownership of
+such entity.
+
+2. Permitted Uses; Conditions & Restrictions.  Subject to the terms
+and conditions of this License, Apple hereby grants You, effective on
+the date You accept this License and download the Original Code, a
+world-wide, royalty-free, non- exclusive license, to the extent of
+Apple's Applicable Patent Rights and copyrights covering the Original
+Code, to do the following:
+
+2.1 You may use, copy, modify and distribute Original Code, with or
+without Modifications, solely for Your internal research and
+development, provided that You must in each instance:
+
+(a) retain and reproduce in all copies of Original Code the copyright
+and other proprietary notices and disclaimers of Apple as they appear
+in the Original Code, and keep intact all notices in the Original Code
+that refer to this License;
+
+(b) include a copy of this License with every copy of Source Code of
+Covered Code and documentation You distribute, and You may not offer
+or impose any terms on such Source Code that alter or restrict this
+License or the recipients' rights hereunder, except as permitted under
+Section 6; and
+
+(c) completely and accurately document all Modifications that you have
+made and the date of each such Modification, designate the version of
+the Original Code you used, prominently include a file carrying such
+information with the Modifications, and duplicate the notice in
+Exhibit A in each file of the Source Code of all such Modifications.
+
+2.2 You may Deploy Covered Code, provided that You must in each
+  instance:
+
+(a) satisfy all the conditions of Section 2.1 with respect to the
+Source Code of the Covered Code;
+
+(b) make all Your Deployed Modifications publicly available in Source
+Code form via electronic distribution (e.g. download from a web site)
+under the terms of this License and subject to the license grants set
+forth in Section 3 below, and any additional terms You may choose to
+offer under Section 6.  You must continue to make the Source Code of
+Your Deployed Modifications available for as long as you Deploy the
+Covered Code or twelve (12) months from the date of initial
+Deployment, whichever is longer;
+
+(c) if You Deploy Covered Code containing Modifications made by You,
+inform others of how to obtain those Modifications by filling out and
+submitting the information found at
+http://www.apple.com/publicsource/modifications.html, if available;
+and
+
+(d) if You Deploy Covered Code in object code, executable form only,
+include a prominent notice, in the code itself as well as in related
+documentation, stating that Source Code of the Covered Code is
+available under the terms of this License with information on how and
+where to obtain such Source Code.
+
+3. Your Grants.  In consideration of, and as a condition to, the
+licenses granted to You under this License:
+
+(a) You hereby grant to Apple and all third parties a non-exclusive,
+royalty-free license, under Your Applicable Patent Rights and other
+intellectual property rights owned or controlled by You, to use,
+reproduce, modify, distribute and Deploy Your Modifications of the
+same scope and extent as Apple's licenses under Sections 2.1 and 2.2;
+and
+
+(b) You hereby grant to Apple and its subsidiaries a non-exclusive,
+worldwide, royalty-free, perpetual and irrevocable license, under Your
+Applicable Patent Rights and other intellectual property rights owned
+or controlled by You, to use, reproduce, execute, compile, display,
+perform, modify or have modified (for Apple and/or its subsidiaries),
+sublicense and distribute Your Modifications, in any form, through
+multiple tiers of distribution.
+
+4. Larger Works.  You may create a Larger Work by combining Covered
+Code with other code not governed by the terms of this License and
+distribute the Larger Work as a single product.  In each such
+instance, You must make sure the requirements of this License are
+fulfilled for the Covered Code or any portion thereof.
+
+5. Limitations on Patent License.  Except as expressly stated in
+Section 2, no other patent rights, express or implied, are granted by
+Apple herein.  Modifications and/or Larger Works may require
+additional patent licenses from Apple which Apple may grant in its
+sole discretion.
+
+6. Additional Terms.  You may choose to offer, and to charge a fee
+for, warranty, support, indemnity or liability obligations and/or
+other rights consistent with the scope of the license granted herein
+("Additional Terms") to one or more recipients of Covered
+Code. However, You may do so only on Your own behalf and as Your sole
+responsibility, and not on behalf of Apple. You must obtain the
+recipient's agreement that any such Additional Terms are offered by
+You alone, and You hereby agree to indemnify, defend and hold Apple
+harmless for any liability incurred by or claims asserted against
+Apple by reason of any such Additional Terms.
+
+7. Versions of the License.  Apple may publish revised and/or new
+versions of this License from time to time.  Each version will be
+given a distinguishing version number.  Once Original Code has been
+published under a particular version of this License, You may continue
+to use it under the terms of that version. You may also choose to use
+such Original Code under the terms of any subsequent version of this
+License published by Apple.  No one other than Apple has the right to
+modify the terms applicable to Covered Code created under this
+License.
+
+8. NO WARRANTY OR SUPPORT.  The Original Code may contain in whole or
+in part pre-release, untested, or not fully tested works.  The
+Original Code may contain errors that could cause failures or loss of
+data, and may be incomplete or contain inaccuracies.  You expressly
+acknowledge and agree that use of the Original Code, or any portion
+thereof, is at Your sole and entire risk.  THE ORIGINAL CODE IS
+PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND
+AND APPLE AND APPLE'S LICENSOR(S) (FOR THE PURPOSES OF SECTIONS 8 AND
+9, APPLE AND APPLE'S LICENSOR(S) ARE COLLECTIVELY REFERRED TO AS
+"APPLE") EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+AND/OR CONDITIONS OF MERCHANTABILITY OR SATISFACTORY QUALITY AND
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+RIGHTS.  APPLE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE
+ORIGINAL CODE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
+THE ORIGINAL CODE WILL BE UNINTERRUPTED OR ERROR- FREE, OR THAT
+DEFECTS IN THE ORIGINAL CODE WILL BE CORRECTED.  NO ORAL OR WRITTEN
+INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED
+REPRESENTATIVE SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE
+SCOPE OF THIS WARRANTY.  You acknowledge that the Original Code is not
+intended for use in the operation of nuclear facilities, aircraft
+navigation, communication systems, or air traffic control machines in
+which case the failure of the Original Code could lead to death,
+personal injury, or severe physical or environmental damage.
+
+9. Liability.
+
+9.1 Infringement.  If any portion of, or functionality implemented by,
+the Original Code becomes the subject of a claim of infringement,
+Apple may, at its option: (a) attempt to procure the rights necessary
+for Apple and You to continue using the Affected Original Code; (b)
+modify the Affected Original Code so that it is no longer infringing;
+or (c) suspend Your rights to use, reproduce, modify, sublicense and
+distribute the Affected Original Code until a final determination of
+the claim is made by a court or governmental administrative agency of
+competent jurisdiction and Apple lifts the suspension as set forth
+below.  Such suspension of rights will be effective immediately upon
+Apple's posting of a notice to such effect on the Apple web site that
+is used for implementation of this License.  Upon such final
+determination being made, if Apple is legally able, without the
+payment of a fee or royalty, to resume use, reproduction,
+modification, sublicensing and distribution of the Affected Original
+Code, Apple will lift the suspension of rights to the Affected
+Original Code by posting a notice to such effect on the Apple web site
+that is used for implementation of this License.  If Apple suspends
+Your rights to Affected Original Code, nothing in this License shall
+be construed to restrict You, at Your option and subject to applicable
+law, from replacing the Affected Original Code with non-infringing
+code or independently negotiating for necessary rights from such third
+party.
+
+9.2 LIMITATION OF LIABILITY.  UNDER NO CIRCUMSTANCES SHALL APPLE BE
+LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO
+USE THE ORIGINAL CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY
+OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY
+OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF
+ANY REMEDY.  In no event shall Apple's total liability to You for all
+damages under this License exceed the amount of fifty dollars
+($50.00).
+
+10. Trademarks.  This License does not grant any rights to use the
+trademarks or trade names "Apple", "Apple Computer", "Mac OS X", "Mac
+OS X Server" or any other trademarks or trade names belonging to Apple
+(collectively "Apple Marks") and no Apple Marks may be used to endorse
+or promote products derived from the Original Code other than as
+permitted by and in strict compliance at all times with Apple's third
+party trademark usage guidelines which are posted at
+http://www.apple.com/legal/guidelinesfor3rdparties.html.
+
+11. Ownership.  Apple retains all rights, title and interest in and to
+the Original Code and any Modifications made by or on behalf of Apple
+("Apple Modifications"), and such Apple Modifications will not be
+automatically subject to this License.  Apple may, at its sole
+discretion, choose to license such Apple Modifications under this
+License, or on different terms from those contained in this License or
+may choose not to license them at all.  Apple's development, use,
+reproduction, modification, sublicensing and distribution of Covered
+Code will not be subject to this License.
+
+12. Termination.
+
+12.1 Termination.  This License and the rights granted hereunder will
+   terminate:
+
+(a) automatically without notice from Apple if You fail to comply with
+any term(s) of this License and fail to cure such breach within 30
+days of becoming aware of such breach; (b) immediately in the event of
+the circumstances described in Section 13.5(b); or (c) automatically
+without notice from Apple if You, at any time during the term of this
+License, commence an action for patent infringement against Apple.
+
+12.2 Effect of Termination.  Upon termination, You agree to
+immediately stop any further use, reproduction, modification,
+sublicensing and distribution of the Covered Code and to destroy all
+copies of the Covered Code that are in your possession or control.
+All sublicenses to the Covered Code which have been properly granted
+prior to termination shall survive any termination of this License.
+Provisions which, by their nature, should remain in effect beyond the
+termination of this License shall survive, including but not limited
+to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13.  Neither party will be
+liable to the other for compensation, indemnity or damages of any sort
+solely as a result of terminating this License in accordance with its
+terms, and termination of this License will be without prejudice to
+any other right or remedy of either party.
+
+13.  Miscellaneous.
+
+13.1 Government End Users.  The Covered Code is a "commercial item" as
+defined in FAR 2.101.  Government software and technical data rights
+in the Covered Code include only those rights customarily provided to
+the public as defined in this License. This customary commercial
+license in technical data and software is provided in accordance with
+FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for
+Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
+Commercial Items) and 227.7202-3 (Rights in Commercial Computer
+Software or Computer Software Documentation).  Accordingly, all U.S.
+Government End Users acquire Covered Code with only those rights set
+forth herein.
+
+13.2 Relationship of Parties.  This License will not be construed as
+creating an agency, partnership, joint venture or any other form of
+legal association between You and Apple, and You will not represent to
+the contrary, whether expressly, by implication, appearance or
+otherwise.
+
+13.3 Independent Development.  Nothing in this License will impair
+Apple's right to acquire, license, develop, have others develop for
+it, market and/or distribute technology or products that perform the
+same or similar functions as, or otherwise compete with,
+Modifications, Larger Works, technology or products that You may
+develop, produce, market or distribute.
+
+13.4 Waiver; Construction.  Failure by Apple to enforce any provision
+of this License will not be deemed a waiver of future enforcement of
+that or any other provision.  Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+will not apply to this License.
+
+13.5 Severability.  (a) If for any reason a court of competent
+jurisdiction finds any provision of this License, or portion thereof,
+to be unenforceable, that provision of the License will be enforced to
+the maximum extent permissible so as to effect the economic benefits
+and intent of the parties, and the remainder of this License will
+continue in full force and effect.  (b) Notwithstanding the foregoing,
+if applicable law prohibits or restricts You from fully and/or
+specifically complying with Sections 2 and/or 3 or prevents the
+enforceability of either of those Sections, this License will
+immediately terminate and You must immediately discontinue any use of
+the Covered Code and destroy all copies of it that are in your
+possession or control.
+
+13.6 Dispute Resolution.  Any litigation or other dispute resolution
+between You and Apple relating to this License shall take place in the
+Northern District of California, and You and Apple hereby consent to
+the personal jurisdiction of, and venue in, the state and federal
+courts within that District with respect to this License. The
+application of the United Nations Convention on Contracts for the
+International Sale of Goods is expressly excluded.
+
+13.7 Entire Agreement; Governing Law.  This License constitutes the
+entire agreement between the parties with respect to the subject
+matter hereof.  This License shall be governed by the laws of the
+United States and the State of California, except that body of
+California law concerning conflicts of law.
+
+Where You are located in the province of Quebec, Canada, the following
+clause applies: The parties hereby confirm that they have requested
+that this License and all related documents be drafted in English. Les
+parties ont exige que le present contrat et tous les documents
+connexes soient rediges en anglais.
+
+EXHIBIT A.
+
+"Portions Copyright (c) 1999-2000 Apple Computer, Inc.  All Rights
+Reserved.  This file contains Original Code and/or Modifications of
+Original Code as defined in and that are subject to the Apple Public
+Source License Version 1.1 (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.
+
+The 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 OR NON- INFRINGEMENT.  Please see the
+License for the specific language governing rights and limitations
+under the License."
diff --git a/AppleCSP/AES/aescsp.cpp b/AppleCSP/AES/aescsp.cpp
new file mode 100644
index 00000000..3a8be1ba
--- /dev/null
+++ b/AppleCSP/AES/aescsp.cpp
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * aescsp.cpp - glue between BlockCryptor and AES implementation
+ * Written by Doug Mitchell 10/3/2000
+ */
+ 
+#include "aescspi.h"
+#include "rijndaelApi.h"
+#include "rijndael-alg-ref.h"
+#include "cspdebugging.h"
+
+#define DEFAULT_BLOCK_SIZE		(MIN_AES_BLOCK_BITS / 8)
+
+#define DEBUG_ED		0		/* general encrypt/decrypt debug */
+#if		DEBUG_ED
+#define dprint(s) 	printf s
+#else
+#define dprint(s)
+#endif
+
+#define DEBUG_SIZES		0
+#if		DEBUG_SIZES
+#define logSize(s, final, encr, ibs, in, out) \
+	printf("%s final %d encr %d inbufsz %d inSize %d outSize %d\n",	\
+	s, final, encr, ibs, in, out)
+#else
+#define logSize(s, final, encr, ibs, in, out)
+#endif
+
+/*
+ * AES symmetric key generation.
+ * This algorithm has key size restrictions which don't fit with the 
+ * standard AppleSymmKeyGenContext model so we have to do some addditional
+ * checking.
+ */
+void AESKeyGenContext::generate(
+	const Context 	&context, 
+	CssmKey 		&symKey, 
+	CssmKey 		&dummyKey)
+{
+	uint32 reqKeySize = context.getInt(
+		CSSM_ATTRIBUTE_KEY_LENGTH, 
+		CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH);
+	switch(reqKeySize) {
+		case MIN_AES_KEY_BITS:
+		case MID_AES_KEY_BITS:
+		case MAX_AES_KEY_BITS:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE);
+	}
+	AppleSymmKeyGenContext::generateSymKey(
+		context, 
+		session(),
+		symKey);		
+}
+
+/*
+ * AES encrypt/decrypt.
+ */
+AESContext::~AESContext()
+{
+	deleteKey();
+	memset(mRawKey, 0, MAX_AES_KEY_BITS / 8);
+	mInitFlag = false;
+}
+	
+void AESContext::aesError(
+	int artn, 
+	const char *errStr)
+{
+	CSSM_RETURN crtn;
+	errorLog2("AESContext: %s : %d\n", errStr, artn);
+	switch(artn) {
+		case BAD_KEY_INSTANCE:
+		default:
+			crtn = CSSMERR_CSP_INTERNAL_ERROR;
+			break;
+		case BAD_KEY_MAT:
+			crtn = CSSMERR_CSP_INVALID_KEY;
+			break;
+	}
+	CssmError::throwMe(crtn);
+}
+
+void AESContext::deleteKey()
+{
+	if(mAesKey) {
+		memset(mAesKey, 0, sizeof(keyInstance));
+		session().free(mAesKey);
+		mAesKey = NULL;
+	}
+}
+
+/* 
+ * Standard CSPContext init, called from CSPFullPluginSession::init().
+ * Reusable, e.g., query followed by en/decrypt. Even reusable after context
+ * changed (i.e., new IV in Encrypted File System). 
+ */
+void AESContext::init( 
+	const Context &context, 
+	bool encrypting)
+{
+	if(mInitFlag && !opStarted()) {
+		return;
+	}
+	
+	UInt32 		keyLen;
+	UInt8 		*keyData = NULL;
+	unsigned	lastBlockSize = mBlockSize;		// may be 0 (first time thru)
+	bool		sameKeyAndBlockSizes = false;
+	
+	/* obtain key from context */
+	symmetricKeyBits(context, CSSM_ALGID_AES, 
+		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
+		keyData, keyLen);
+	
+	/* 
+	 * Validate context 
+	 * block size is optional 
+	 */
+	mBlockSize = context.getInt(CSSM_ATTRIBUTE_BLOCK_SIZE);
+	if(mBlockSize == 0) {
+		mBlockSize = DEFAULT_BLOCK_SIZE;		
+	}
+		
+	
+	/*
+	 * Delete existing key if key size or block size changed
+	 */
+	if((lastBlockSize == mBlockSize) && (mRawKeySize == keyLen)) {
+		sameKeyAndBlockSizes = true;
+	}
+	if((mAesKey != NULL) && !sameKeyAndBlockSizes) {
+		deleteKey();
+	}
+	
+	int opt128 = 0;
+	if((mBlockSize == (MIN_AES_BLOCK_BITS/8)) &&
+	   (keyLen == (MIN_AES_KEY_BITS/8)) &&
+	   doAES128) {
+		opt128 = 1;
+	}
+	
+	/* create new key if needed */
+	if(mAesKey == NULL) {
+		mAesKey = (keyInstance *)session().malloc(sizeof(keyInstance));
+	}
+	
+	/* init key only if key size, block size, or key bits have changed */
+	if(!sameKeyAndBlockSizes || memcmp(mRawKey, keyData, mRawKeySize)) {
+		int artn = makeKey((keyInstance *)mAesKey, 
+			keyLen * 8, 
+			mBlockSize * 8, 
+			(word8 *)keyData,
+			opt128);
+		if(artn < 0) {
+			aesError(artn, "makeKey");
+		}
+		
+		/* save this raw key data */
+		memmove(mRawKey, keyData, mRawKeySize); 
+		mRawKeySize = keyLen;
+	}
+
+	if(opt128) {
+		/* optimized path */
+		mEncryptFcn = rijndaelBlockEncrypt128;
+		mDecryptFcn = rijndaelBlockDecrypt128;
+	}
+	else {
+		/* common standard path */
+		mEncryptFcn = rijndaelBlockEncrypt;
+		mDecryptFcn = rijndaelBlockDecrypt;
+	}
+	
+	/* Finally, have BlockCryptor do its setup */
+	setup(mBlockSize, context);
+	mInitFlag = true;
+}	
+
+/*
+ * Functions called by BlockCryptor
+ */
+void AESContext::encryptBlock(
+	const void		*plainText,			// length implied (one block)
+	size_t			plainTextLen,
+	void 			*cipherText,	
+	size_t			&cipherTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen != mBlockSize) {
+		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+	}
+	if(cipherTextLen < mBlockSize) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	int artn = mEncryptFcn(mAesKey, 
+		(word8 *)plainText, 
+		(word8 *)cipherText);
+	if(artn < 0) {
+		aesError(artn, "rijndaelBlockEncrypt");
+	}
+	cipherTextLen = mBlockSize;
+}
+
+void AESContext::decryptBlock(
+	const void		*cipherText,		// length implied (one cipher block)
+	void			*plainText,	
+	size_t			&plainTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen < mBlockSize) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	int artn = mDecryptFcn(mAesKey, 
+		(word8 *)cipherText, 
+		(word8 *)plainText);
+	if(artn < 0) {
+		aesError(artn, "rijndaelBlockDecrypt");
+	}
+	plainTextLen = mBlockSize;
+}
+
diff --git a/AppleCSP/AES/aescspi.h b/AppleCSP/AES/aescspi.h
new file mode 100644
index 00000000..c6694b2b
--- /dev/null
+++ b/AppleCSP/AES/aescspi.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+
+//
+// aescspi.h - AES context class
+//
+#ifndef _H_AESCSPI
+#define _H_AESCSPI
+
+#include <Security/CSPsession.h>
+#include "AppleCSP.h"
+#include "AppleCSPContext.h"
+#include "AppleCSPSession.h"
+#include "BlockCryptor.h"
+#include "rijndaelApi.h"
+
+/* Symmetric encryption context */
+class AESContext : public BlockCryptor {
+public:
+	AESContext(AppleCSPSession &session) :
+		BlockCryptor(session),
+		mAesKey(NULL),
+		mBlockSize(0),
+		mInitFlag(false),
+		mRawKeySize(0)	{ }
+	~AESContext();
+	
+	// called by CSPFullPluginSession
+	void init(const Context &context, bool encoding = true);
+
+	// As an optimization, we allow reuse of a modified context. The main thing
+	// we avoid is a redundant key scheduling. We save the current raw keys bits
+	// in mRawKey and compare on re-init.
+	bool changed(const Context &context)	 { return true; }
+
+	// called by BlockCryptor
+	void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, throws on overflow
+		bool			final);
+	void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, throws on overflow
+		bool			final);
+	
+private:
+	void aesError(
+		int artn, 
+		const char *errStr);
+	void deleteKey();
+	
+	keyInstance			*mAesKey;			// keyInstance or keyInstance128
+	unsigned			mBlockSize;			// in BYTES
+	bool				mInitFlag;			// for easy reuse
+	aesCryptFcn			mEncryptFcn;
+	aesCryptFcn			mDecryptFcn;	
+	
+	/* raw key bits saved here and checked on re-init to avoid extra key schedule */
+	uint8				mRawKey[MAX_AES_KEY_BITS / 8];
+	uint32				mRawKeySize;
+};	/* AESContext */
+
+// symmetric key generation context
+class AESKeyGenContext : public AppleCSPContext, private AppleSymmKeyGenContext {
+public:
+	AESKeyGenContext(
+		AppleCSPSession &session) :
+			AppleCSPContext(session),
+			AppleSymmKeyGenContext(
+				MIN_AES_KEY_BITS,
+				MAX_AES_KEY_BITS,
+				true) { }
+	
+	void init(const Context &context, bool encoding = true) { }
+			
+	void generate(
+		const Context 	&context, 
+		CssmKey 		&symKey, 
+		CssmKey 		&dummyKey);
+
+};
+
+#endif //_H_AESCSPI
diff --git a/AppleCSP/AES/boxes-ref.c b/AppleCSP/AES/boxes-ref.c
new file mode 100644
index 00000000..ddc63573
--- /dev/null
+++ b/AppleCSP/AES/boxes-ref.c
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+#include "boxes-ref.h"
+
+#if			!AES_MUL_BY_LOOKUP
+const unsigned char Logtable[256] = {
+  0,   0,  25,   1,  50,   2,  26, 198,  75, 199,  27, 104,  51, 238, 223,   3, 
+100,   4, 224,  14,  52, 141, 129, 239,  76, 113,   8, 200, 248, 105,  28, 193, 
+125, 194,  29, 181, 249, 185,  39, 106,  77, 228, 166, 114, 154, 201,   9, 120, 
+101,  47, 138,   5,  33,  15, 225,  36,  18, 240, 130,  69,  53, 147, 218, 142, 
+150, 143, 219, 189,  54, 208, 206, 148,  19,  92, 210, 241,  64,  70, 131,  56, 
+102, 221, 253,  48, 191,   6, 139,  98, 179,  37, 226, 152,  34, 136, 145,  16, 
+126, 110,  72, 195, 163, 182,  30,  66,  58, 107,  40,  84, 250, 133,  61, 186, 
+ 43, 121,  10,  21, 155, 159,  94, 202,  78, 212, 172, 229, 243, 115, 167,  87, 
+175,  88, 168,  80, 244, 234, 214, 116,  79, 174, 233, 213, 231, 230, 173, 232, 
+ 44, 215, 117, 122, 235,  22,  11, 245,  89, 203,  95, 176, 156, 169,  81, 160, 
+127,  12, 246, 111,  23, 196,  73, 236, 216,  67,  31,  45, 164, 118, 123, 183, 
+204, 187,  62,  90, 251,  96, 177, 134,  59,  82, 161, 108, 170,  85,  41, 157, 
+151, 178, 135, 144,  97, 190, 220, 252, 188, 149, 207, 205,  55,  63,  91, 209, 
+ 83,  57, 132,  60,  65, 162, 109,  71,  20,  42, 158,  93,  86, 242, 211, 171, 
+ 68,  17, 146, 217,  35,  32,  46, 137, 180, 124, 184,  38, 119, 153, 227, 165, 
+103,  74, 237, 222, 197,  49, 254,  24,  13,  99, 140, 128, 192, 247, 112,   7, 
+};
+
+const unsigned char Alogtable[256] = {
+  1,   3,   5,  15,  17,  51,  85, 255,  26,  46, 114, 150, 161, 248,  19,  53, 
+ 95, 225,  56,  72, 216, 115, 149, 164, 247,   2,   6,  10,  30,  34, 102, 170, 
+229,  52,  92, 228,  55,  89, 235,  38, 106, 190, 217, 112, 144, 171, 230,  49, 
+ 83, 245,   4,  12,  20,  60,  68, 204,  79, 209, 104, 184, 211, 110, 178, 205, 
+ 76, 212, 103, 169, 224,  59,  77, 215,  98, 166, 241,   8,  24,  40, 120, 136, 
+131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206,  73, 219, 118, 154, 
+181, 196,  87, 249,  16,  48,  80, 240,  11,  29,  39, 105, 187, 214,  97, 163, 
+254,  25,  43, 125, 135, 146, 173, 236,  47, 113, 147, 174, 233,  32,  96, 160, 
+251,  22,  58,  78, 210, 109, 183, 194,  93, 231,  50,  86, 250,  21,  63,  65, 
+195,  94, 226,  61,  71, 201,  64, 192,  91, 237,  44, 116, 156, 191, 218, 117, 
+159, 186, 213, 100, 172, 239,  42, 126, 130, 157, 188, 223, 122, 142, 137, 128, 
+155, 182, 193,  88, 232,  35, 101, 175, 234,  37, 111, 177, 200,  67, 197,  84, 
+252,  31,  33,  99, 165, 244,   7,   9,  27,  45, 119, 153, 176, 203,  70, 202, 
+ 69, 207,  74, 222, 121, 139, 134, 145, 168, 227,  62,  66, 198,  81, 243,  14, 
+ 18,  54,  90, 238,  41, 123, 141, 140, 143, 138, 133, 148, 167, 242,  13,  23, 
+ 57,  75, 221, 124, 132, 151, 162, 253,  28,  36, 108, 180, 199,  82, 246,   1, 
+};
+#endif	/* AES_MUL_BY_LOOKUP */
+
+const unsigned char S[256] = {
+ 99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
+202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
+183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
+  4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
+  9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
+ 83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
+208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
+ 81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
+205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
+ 96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
+224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
+231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
+186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
+112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
+225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
+140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22, 
+};
+
+const unsigned char Si[256] = {
+ 82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243, 215, 251, 
+124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68, 196, 222, 233, 203, 
+ 84, 123, 148,  50, 166, 194,  35,  61, 238,  76, 149,  11,  66, 250, 195,  78, 
+  8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73, 109, 139, 209,  37, 
+114, 248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 204,  93, 101, 182, 146, 
+108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132, 
+144, 216, 171,   0, 140, 188, 211,  10, 247, 228,  88,   5, 184, 179,  69,   6, 
+208,  44,  30, 143, 202,  63,  15,   2, 193, 175, 189,   3,   1,  19, 138, 107, 
+ 58, 145,  17,  65,  79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 
+150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232,  28, 117, 223, 110, 
+ 71, 241,  26, 113,  29,  41, 197, 137, 111, 183,  98,  14, 170,  24, 190,  27, 
+252,  86,  62,  75, 198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244, 
+ 31, 221, 168,  51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95, 
+ 96,  81, 127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239, 
+160, 224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97, 
+ 23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12, 125, 
+};
+
+const unsigned char iG[4][4] = {
+{ 0x0e, 0x09, 0x0d, 0x0b }, 
+{ 0x0b, 0x0e, 0x09, 0x0d },
+{ 0x0d, 0x0b, 0x0e, 0x09 }, 
+{ 0x09, 0x0d, 0x0b, 0x0e } 
+};
+
+const unsigned long rcon[30] = { 
+  0x01,0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, };
+
+#if			AES_MUL_BY_LOOKUP
+
+/*
+ * Lookup tables for mul(). Only 6 multiplicands are used when calling this 
+ * function so we just have a table for each one.
+ */
+const word8 mulBy0x02[256] = {
+     0,   2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24,  26,  28,  30, 
+    32,  34,  36,  38,  40,  42,  44,  46,  48,  50,  52,  54,  56,  58,  60,  62, 
+    64,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,  90,  92,  94, 
+    96,  98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 
+   128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 
+   160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 
+   192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 
+   224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 
+    27,  25,  31,  29,  19,  17,  23,  21,  11,   9,  15,  13,   3,   1,   7,   5, 
+    59,  57,  63,  61,  51,  49,  55,  53,  43,  41,  47,  45,  35,  33,  39,  37, 
+    91,  89,  95,  93,  83,  81,  87,  85,  75,  73,  79,  77,  67,  65,  71,  69, 
+   123, 121, 127, 125, 115, 113, 119, 117, 107, 105, 111, 109,  99,  97, 103, 101, 
+   155, 153, 159, 157, 147, 145, 151, 149, 139, 137, 143, 141, 131, 129, 135, 133, 
+   187, 185, 191, 189, 179, 177, 183, 181, 171, 169, 175, 173, 163, 161, 167, 165, 
+   219, 217, 223, 221, 211, 209, 215, 213, 203, 201, 207, 205, 195, 193, 199, 197, 
+   251, 249, 255, 253, 243, 241, 247, 245, 235, 233, 239, 237, 227, 225, 231, 229, 
+   };
+
+const word8 mulBy0x03[256] = {
+     0,   3,   6,   5,  12,  15,  10,   9,  24,  27,  30,  29,  20,  23,  18,  17, 
+    48,  51,  54,  53,  60,  63,  58,  57,  40,  43,  46,  45,  36,  39,  34,  33, 
+    96,  99, 102, 101, 108, 111, 106, 105, 120, 123, 126, 125, 116, 119, 114, 113, 
+    80,  83,  86,  85,  92,  95,  90,  89,  72,  75,  78,  77,  68,  71,  66,  65, 
+   192, 195, 198, 197, 204, 207, 202, 201, 216, 219, 222, 221, 212, 215, 210, 209, 
+   240, 243, 246, 245, 252, 255, 250, 249, 232, 235, 238, 237, 228, 231, 226, 225, 
+   160, 163, 166, 165, 172, 175, 170, 169, 184, 187, 190, 189, 180, 183, 178, 177, 
+   144, 147, 150, 149, 156, 159, 154, 153, 136, 139, 142, 141, 132, 135, 130, 129, 
+   155, 152, 157, 158, 151, 148, 145, 146, 131, 128, 133, 134, 143, 140, 137, 138, 
+   171, 168, 173, 174, 167, 164, 161, 162, 179, 176, 181, 182, 191, 188, 185, 186, 
+   251, 248, 253, 254, 247, 244, 241, 242, 227, 224, 229, 230, 239, 236, 233, 234, 
+   203, 200, 205, 206, 199, 196, 193, 194, 211, 208, 213, 214, 223, 220, 217, 218, 
+    91,  88,  93,  94,  87,  84,  81,  82,  67,  64,  69,  70,  79,  76,  73,  74, 
+   107, 104, 109, 110, 103, 100,  97,  98, 115, 112, 117, 118, 127, 124, 121, 122, 
+    59,  56,  61,  62,  55,  52,  49,  50,  35,  32,  37,  38,  47,  44,  41,  42, 
+    11,   8,  13,  14,   7,   4,   1,   2,  19,  16,  21,  22,  31,  28,  25,  26, 
+   };
+
+const word8 mulBy0x0e[256] = {
+     0,  14,  28,  18,  56,  54,  36,  42, 112, 126, 108,  98,  72,  70,  84,  90, 
+   224, 238, 252, 242, 216, 214, 196, 202, 144, 158, 140, 130, 168, 166, 180, 186, 
+   219, 213, 199, 201, 227, 237, 255, 241, 171, 165, 183, 185, 147, 157, 143, 129, 
+    59,  53,  39,  41,   3,  13,  31,  17,  75,  69,  87,  89, 115, 125, 111,  97, 
+   173, 163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235, 249, 247, 
+    77,  67,  81,  95, 117, 123, 105, 103,  61,  51,  33,  47,   5,  11,  25,  23, 
+   118, 120, 106, 100,  78,  64,  82,  92,   6,   8,  26,  20,  62,  48,  34,  44, 
+   150, 152, 138, 132, 174, 160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204, 
+    65,  79,  93,  83, 121, 119, 101, 107,  49,  63,  45,  35,   9,   7,  21,  27, 
+   161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195, 233, 231, 245, 251, 
+   154, 148, 134, 136, 162, 172, 190, 176, 234, 228, 246, 248, 210, 220, 206, 192, 
+   122, 116, 102, 104,  66,  76,  94,  80,  10,   4,  22,  24,  50,  60,  46,  32, 
+   236, 226, 240, 254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182, 
+    12,   2,  16,  30,  52,  58,  40,  38, 124, 114,  96, 110,  68,  74,  88,  86, 
+    55,  57,  43,  37,  15,   1,  19,  29,  71,  73,  91,  85, 127, 113,  99, 109, 
+   215, 217, 203, 197, 239, 225, 243, 253, 167, 169, 187, 181, 159, 145, 131, 141, 
+   };
+
+const word8 mulBy0x0b[256] = {
+     0,  11,  22,  29,  44,  39,  58,  49,  88,  83,  78,  69, 116, 127,  98, 105, 
+   176, 187, 166, 173, 156, 151, 138, 129, 232, 227, 254, 245, 196, 207, 210, 217, 
+   123, 112, 109, 102,  87,  92,  65,  74,  35,  40,  53,  62,  15,   4,  25,  18, 
+   203, 192, 221, 214, 231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, 
+   246, 253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137, 148, 159, 
+    70,  77,  80,  91, 106,  97, 124, 119,  30,  21,   8,   3,  50,  57,  36,  47, 
+   141, 134, 155, 144, 161, 170, 183, 188, 213, 222, 195, 200, 249, 242, 239, 228, 
+    61,  54,  43,  32,  17,  26,   7,  12, 101, 110, 115, 120,  73,  66,  95,  84, 
+   247, 252, 225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149, 158, 
+    71,  76,  81,  90, 107,  96, 125, 118,  31,  20,   9,   2,  51,  56,  37,  46, 
+   140, 135, 154, 145, 160, 171, 182, 189, 212, 223, 194, 201, 248, 243, 238, 229, 
+    60,  55,  42,  33,  16,  27,   6,  13, 100, 111, 114, 121,  72,  67,  94,  85, 
+     1,  10,  23,  28,  45,  38,  59,  48,  89,  82,  79,  68, 117, 126,  99, 104, 
+   177, 186, 167, 172, 157, 150, 139, 128, 233, 226, 255, 244, 197, 206, 211, 216, 
+   122, 113, 108, 103,  86,  93,  64,  75,  34,  41,  52,  63,  14,   5,  24,  19, 
+   202, 193, 220, 215, 230, 237, 240, 251, 146, 153, 132, 143, 190, 181, 168, 163, 
+   };
+
+const word8 mulBy0x0d[256] = {
+     0,  13,  26,  23,  52,  57,  46,  35, 104, 101, 114, 127,  92,  81,  70,  75, 
+   208, 221, 202, 199, 228, 233, 254, 243, 184, 181, 162, 175, 140, 129, 150, 155, 
+   187, 182, 161, 172, 143, 130, 149, 152, 211, 222, 201, 196, 231, 234, 253, 240, 
+   107, 102, 113, 124,  95,  82,  69,  72,   3,  14,  25,  20,  55,  58,  45,  32, 
+   109,  96, 119, 122,  89,  84,  67,  78,   5,   8,  31,  18,  49,  60,  43,  38, 
+   189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207, 194, 225, 236, 251, 246, 
+   214, 219, 204, 193, 226, 239, 248, 245, 190, 179, 164, 169, 138, 135, 144, 157, 
+     6,  11,  28,  17,  50,  63,  40,  37, 110,  99, 116, 121,  90,  87,  64,  77, 
+   218, 215, 192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156, 145, 
+    10,   7,  16,  29,  62,  51,  36,  41,  98, 111, 120, 117,  86,  91,  76,  65, 
+    97, 108, 123, 118,  85,  88,  79,  66,   9,   4,  19,  30,  61,  48,  39,  42, 
+   177, 188, 171, 166, 133, 136, 159, 146, 217, 212, 195, 206, 237, 224, 247, 250, 
+   183, 186, 173, 160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252, 
+   103, 106, 125, 112,  83,  94,  73,  68,  15,   2,  21,  24,  59,  54,  33,  44, 
+    12,   1,  22,  27,  56,  53,  34,  47, 100, 105, 126, 115,  80,  93,  74,  71, 
+   220, 209, 198, 203, 232, 229, 242, 255, 180, 185, 174, 163, 128, 141, 154, 151, 
+   };
+
+const word8 mulBy0x09[256] = {
+     0,   9,  18,  27,  36,  45,  54,  63,  72,  65,  90,  83, 108, 101, 126, 119, 
+   144, 153, 130, 139, 180, 189, 166, 175, 216, 209, 202, 195, 252, 245, 238, 231, 
+    59,  50,  41,  32,  31,  22,  13,   4, 115, 122,  97, 104,  87,  94,  69,  76, 
+   171, 162, 185, 176, 143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, 
+   118, 127, 100, 109,  82,  91,  64,  73,  62,  55,  44,  37,  26,  19,   8,   1, 
+   230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188, 181, 138, 131, 152, 145, 
+    77,  68,  95,  86, 105,  96, 123, 114,   5,  12,  23,  30,  33,  40,  51,  58, 
+   221, 212, 207, 198, 249, 240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, 
+   236, 229, 254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146, 155, 
+   124, 117, 110, 103,  88,  81,  74,  67,  52,  61,  38,  47,  16,  25,   2,  11, 
+   215, 222, 197, 204, 243, 250, 225, 232, 159, 150, 141, 132, 187, 178, 169, 160, 
+    71,  78,  85,  92,  99, 106, 113, 120,  15,   6,  29,  20,  43,  34,  57,  48, 
+   154, 147, 136, 129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237, 
+    10,   3,  24,  17,  46,  39,  60,  53,  66,  75,  80,  89, 102, 111, 116, 125, 
+   161, 168, 179, 186, 133, 140, 151, 158, 233, 224, 251, 242, 205, 196, 223, 214, 
+    49,  56,  35,  42,  21,  28,   7,  14, 121, 112, 107,  98,  93,  84,  79,  70, 
+   };
+
+#endif		/* AES_MUL_BY_LOOKUP */
diff --git a/AppleCSP/AES/boxes-ref.h b/AppleCSP/AES/boxes-ref.h
new file mode 100644
index 00000000..ca261820
--- /dev/null
+++ b/AppleCSP/AES/boxes-ref.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+
+#ifndef	_AES_BOXES_H_
+#define _AES_BOXES_H_
+
+#include "rijndael-alg-ref.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define AES_MUL_BY_LOOKUP	1
+
+#if			AES_MUL_BY_LOOKUP
+extern const word8 mulBy0x02[256];
+extern const word8 mulBy0x03[256];
+extern const word8 mulBy0x0e[256];
+extern const word8 mulBy0x0b[256];
+extern const word8 mulBy0x0d[256];
+extern const word8 mulBy0x09[256];
+#else
+extern const unsigned char Logtable[256];
+extern const unsigned char Alogtable[256];
+#endif	/* AES_MUL_BY_LOOKUP */
+
+extern const unsigned char S[256];
+extern const unsigned char Si[256];
+extern const unsigned char iG[4][4];
+extern const unsigned long rcon[30];
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _AES_BOXES_H_ */
diff --git a/AppleCSP/AES/rijndael-alg-ref.c b/AppleCSP/AES/rijndael-alg-ref.c
new file mode 100644
index 00000000..96d809f3
--- /dev/null
+++ b/AppleCSP/AES/rijndael-alg-ref.c
@@ -0,0 +1,606 @@
+/*
+ * 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.
+ */
+
+
+/* rijndael-alg-ref.c   v2.0   August '99
+ * Reference ANSI C code
+ * authors: Paulo Barreto
+ *          Vincent Rijmen
+ *
+ * PPC and 128-bit block optimization by Doug Mitchell May 2001. 
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rijndael-alg-ref.h"
+#include <AppleCSP/cspdebugging.h>
+
+#define SC	((BC - 4) >> 1)
+
+#include "boxes-ref.h"
+
+static const word8 shifts[3][4][2] = {
+ { { 0, 0 },
+   { 1, 3 },
+   { 2, 2 },
+   { 3, 1 }
+ },
+ { { 0, 0 },
+   { 1, 5 },
+   { 2, 4 },
+   { 3, 3 }
+ },
+ { { 0, 0 },
+   { 1, 7 },
+   { 3, 5 },
+   { 4, 4 }
+ }
+}; 
+
+/* 128 bit key/word shift table in bits */
+static const word8 shifts128[4][2] = {
+ { 0,  0 },
+ { 8,  24 },
+ { 16, 16 },
+ { 24, 8 }
+};
+
+#if		!AES_MUL_BY_LOOKUP
+/*
+ * Profiling measurements showed that the mul routine is where a large propertion of 
+ * the time is spent. Since the first argument to  mul is always one of six 
+ * constants (2, 3, 0xe, etc.), we implement six 256x256 byte lookup tables to 
+ * do the multiplies. This eliminates the need for the log/antilog tables, so
+ * it's only adding one kilobyte of const data. Throughput improvement for this
+ * mod is a factor of 3.3 for encrypt and 4.1 for decrypt in the 128-bit optimized
+ * case. Improvement for the general case (with a 256 bit key) is 1.46 for encrypt
+ * and 1.88 for decrypt. (Decrypt wins more for this enhancement because the 
+ * InvMixColumn does four muls, vs. 2 muls for MixColumn). Measurements taken
+ * on a 500 MHz G4 with 1 MB of L2 cache. 
+
+/*
+ * The mod 255 op in mul is really expensive...
+ *
+ * We know that b <= (254 * 2), so there are only two cases. Either return b, 
+ * or return b-255. 
+ *
+ * On a G4 this single optimization results in a 24% speedup for encrypt and 
+ * a 25% speedup for decrypt. 
+ */
+static inline word8 mod255(word32 b)
+{
+	if(b >= 255) {
+		b -= 255;
+	}
+	return b;
+}
+
+word8 mul(word8 a, word8 b) {
+   /* multiply two elements of GF(2^m)
+    * needed for MixColumn and InvMixColumn
+    */
+	if (a && b) return Alogtable[mod255(Logtable[a] + Logtable[b])];
+	else return 0;
+}
+#endif	/* !AES_MUL_BY_LOOKUP */
+
+void KeyAddition(word8 a[4][MAXBC], word8 rk[4][MAXBC], word8 BC) {
+	/* Exor corresponding text input and round key input bytes
+	 */
+	int i, j;
+	
+	for(i = 0; i < 4; i++)
+   		for(j = 0; j < BC; j++) a[i][j] ^= rk[i][j];
+}
+
+void ShiftRow(word8 a[4][MAXBC], word8 d, word8 BC) {
+	/* Row 0 remains unchanged
+	 * The other three rows are shifted a variable amount
+	 */
+	word8 tmp[MAXBC];
+	int i, j;
+	
+	for(i = 1; i < 4; i++) {
+		for(j = 0; j < BC; j++) tmp[j] = a[i][(j + shifts[SC][i][d]) % BC];
+		for(j = 0; j < BC; j++) a[i][j] = tmp[j];
+	}
+}
+
+void Substitution(word8 a[4][MAXBC], const word8 box[256], word8 BC) {
+	/* Replace every byte of the input by the byte at that place
+	 * in the nonlinear S-box
+	 */
+	int i, j;
+	
+	for(i = 0; i < 4; i++)
+		for(j = 0; j < BC; j++) a[i][j] = box[a[i][j]] ;
+}
+   
+void MixColumn(word8 a[4][MAXBC], word8 BC) {
+	/* Mix the four bytes of every column in a linear way
+	 */
+	word8 b[4][MAXBC];
+	int i, j;
+		
+	for(j = 0; j < BC; j++) {
+		for(i = 0; i < 4; i++) {
+			#if		AES_MUL_BY_LOOKUP
+			b[i][j] = mulBy0x02[a[i][j]]
+				^ mulBy0x03[a[(i + 1) % 4][j]]
+				^ a[(i + 2) % 4][j]
+				^ a[(i + 3) % 4][j];
+			#else
+			b[i][j] = mul(2,a[i][j])
+				^ mul(3,a[(i + 1) % 4][j])
+				^ a[(i + 2) % 4][j]
+				^ a[(i + 3) % 4][j];
+			#endif
+		}
+	}
+	for(i = 0; i < 4; i++) {
+		for(j = 0; j < BC; j++) a[i][j] = b[i][j];
+	}
+}
+
+void InvMixColumn(word8 a[4][MAXBC], word8 BC) {
+	/* Mix the four bytes of every column in a linear way
+	 * This is the opposite operation of Mixcolumn
+	 */
+	word8 b[4][MAXBC];
+	int i, j;
+	
+	for(j = 0; j < BC; j++) {
+		for(i = 0; i < 4; i++) {         
+			#if		AES_MUL_BY_LOOKUP
+			b[i][j] = mulBy0x0e[a[i][j]]
+				^ mulBy0x0b[a[(i + 1) % 4][j]]
+				^ mulBy0x0d[a[(i + 2) % 4][j]]
+				^ mulBy0x09[a[(i + 3) % 4][j]];     
+			#else
+			b[i][j] = mul(0xe,a[i][j])
+				^ mul(0xb,a[(i + 1) % 4][j])                 
+				^ mul(0xd,a[(i + 2) % 4][j])
+				^ mul(0x9,a[(i + 3) % 4][j]);     
+			#endif
+		}
+	}
+	for(i = 0; i < 4; i++) {
+		for(j = 0; j < BC; j++) a[i][j] = b[i][j];
+	}
+}
+
+int rijndaelKeySched (
+	word8 k[4][MAXKC], 
+	int keyBits, 
+	int blockBits, 
+	word8 W[MAXROUNDS+1][4][MAXBC]) {
+	
+	/* Calculate the necessary round keys
+	 * The number of calculations depends on keyBits and blockBits
+	 */
+	int KC, BC, ROUNDS;
+	int i, j, t, rconpointer = 0;
+	word8 tk[4][MAXKC];   
+
+	switch (keyBits) {
+	case 128: KC = 4; break;
+	case 192: KC = 6; break;
+	case 256: KC = 8; break;
+	default : return (-1);
+	}
+
+	switch (blockBits) {
+	case 128: BC = 4; break;
+	case 192: BC = 6; break;
+	case 256: BC = 8; break;
+	default : return (-2);
+	}
+
+	switch (keyBits >= blockBits ? keyBits : blockBits) {
+	case 128: ROUNDS = 10; break;
+	case 192: ROUNDS = 12; break;
+	case 256: ROUNDS = 14; break;
+	default : return (-3); /* this cannot happen */
+	}
+
+	
+	for(j = 0; j < KC; j++)
+		for(i = 0; i < 4; i++)
+			tk[i][j] = k[i][j];
+	t = 0;
+	/* copy values into round key array */
+	for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
+		for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
+		
+	while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
+		/* calculate new values */
+		for(i = 0; i < 4; i++)
+			tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
+		tk[0][0] ^= rcon[rconpointer++];
+
+		if (KC != 8)
+			for(j = 1; j < KC; j++)
+				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
+		else {
+			for(j = 1; j < KC/2; j++)
+				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
+			for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
+			for(j = KC/2 + 1; j < KC; j++)
+				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
+	}
+	/* copy values into round key array */
+	for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
+		for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
+	}		
+
+	return 0;
+}
+      
+int rijndaelEncrypt (
+	word8 a[4][MAXBC], 
+	int keyBits, 
+	int blockBits, 
+	word8 rk[MAXROUNDS+1][4][MAXBC])
+{
+	/* Encryption of one block, general case. 
+	 */
+	int r, BC, ROUNDS;
+
+	switch (blockBits) {
+	case 128: BC = 4; break;
+	case 192: BC = 6; break;
+	case 256: BC = 8; break;
+	default : return (-2);
+	}
+
+	switch (keyBits >= blockBits ? keyBits : blockBits) {
+	case 128: ROUNDS = 10; break;
+	case 192: ROUNDS = 12; break;
+	case 256: ROUNDS = 14; break;
+	default : return (-3); /* this cannot happen */
+	}
+
+	/* begin with a key addition
+	 */
+	KeyAddition(a,rk[0],BC); 
+
+	/* ROUNDS-1 ordinary rounds
+	 */
+	for(r = 1; r < ROUNDS; r++) {
+		Substitution(a,S,BC);
+		ShiftRow(a,0,BC);
+		MixColumn(a,BC);
+		KeyAddition(a,rk[r],BC);
+	}
+	
+	/* Last round is special: there is no MixColumn
+	 */
+	Substitution(a,S,BC);
+	ShiftRow(a,0,BC);
+	KeyAddition(a,rk[ROUNDS],BC);
+
+	return 0;
+}   
+
+int rijndaelDecrypt (
+	word8 a[4][MAXBC], 
+	int keyBits, 
+	int blockBits, 
+	word8 rk[MAXROUNDS+1][4][MAXBC])
+{
+	int r, BC, ROUNDS;
+	
+	switch (blockBits) {
+	case 128: BC = 4; break;
+	case 192: BC = 6; break;
+	case 256: BC = 8; break;
+	default : return (-2);
+	}
+
+	switch (keyBits >= blockBits ? keyBits : blockBits) {
+	case 128: ROUNDS = 10; break;
+	case 192: ROUNDS = 12; break;
+	case 256: ROUNDS = 14; break;
+	default : return (-3); /* this cannot happen */
+	}
+
+	/* To decrypt: apply the inverse operations of the encrypt routine,
+	 *             in opposite order
+	 * 
+	 * (KeyAddition is an involution: it 's equal to its inverse)
+	 * (the inverse of Substitution with table S is Substitution with the 
+	 *  inverse table of S)
+	 * (the inverse of Shiftrow is Shiftrow over a suitable distance)
+	 */
+
+	/* First the special round:
+	 *   without InvMixColumn
+	 *   with extra KeyAddition
+	 */
+	KeyAddition(a,rk[ROUNDS],BC);
+	Substitution(a,Si,BC);
+	ShiftRow(a,1,BC);              
+	
+	/* ROUNDS-1 ordinary rounds
+	 */
+	for(r = ROUNDS-1; r > 0; r--) {
+		KeyAddition(a,rk[r],BC);
+		InvMixColumn(a,BC);      
+		Substitution(a,Si,BC);
+		ShiftRow(a,1,BC);                
+	}
+	
+	/* End with the extra key addition
+	 */
+	
+	KeyAddition(a,rk[0],BC);    
+
+	return 0;
+}
+
+/*
+ * All of these 128-bit-key-and-block routines require 32-bit word-aligned 
+ * char array pointers.ÊThe key schedule arrays are easy; they come from
+ * keyInstance which has a 4-byte-aligned element preceeding the key schedule.
+ * Others require manual alignment of a local variable by the caller.
+ */
+
+static inline void KeyAddition128(
+	word8 a[4][BC_128_OPT], 
+	word8 rk[4][MAXBC]) {
+	
+	/* these casts are endian-independent */
+	((word32 *)a)[0] ^= *((word32 *)(&rk[0]));
+	((word32 *)a)[1] ^= *((word32 *)(&rk[1]));
+	((word32 *)a)[2] ^= *((word32 *)(&rk[2]));
+	((word32 *)a)[3] ^= *((word32 *)(&rk[3]));
+}
+
+static void Substitution128(
+	word8 a[4][BC_128_OPT], 
+	const word8 box[256]) {
+	/* Replace every byte of the input by the byte at that place
+	 * in the nonlinear S-box
+	 */
+	int i, j;
+	
+	/* still to be optimized - larger S boxes? */
+	for(i = 0; i < 4; i++) {
+		for(j = 0; j < BC_128_OPT; j++) {
+			a[i][j] = box[a[i][j]];
+		}
+	}
+}
+
+#if	defined(__ppc__) && defined(__GNUC__)
+
+static inline void rotateWordLeft(
+	word8 *word,			// known to be word aligned
+	unsigned rotCount)		// in bits
+{
+	word32 lword = *((word32 *)word);
+	asm("rlwnm %0,%1,%2,0,31" : "=r"(lword) : "0"(lword), "r"(rotCount));
+	*((word32 *)word) = lword;
+}
+
+#else
+
+/* 
+ * Insert your machine/compiler dependent code here,
+ * or just use this, which works on any platform and compiler
+ * which supports the __attribute__((aligned(4))) directive. 
+ */
+static void rotateWordLeft(
+	word8 *word,			// known to be word aligned
+	unsigned rotCount)		// in bits
+{
+	word8 tmp[BC_128_OPT] __attribute__((aligned(4)));
+	unsigned bytes = rotCount / 8;
+	
+	tmp[0] = word[bytes     & (BC_128_OPT-1)];
+	tmp[1] = word[(1+bytes) & (BC_128_OPT-1)];
+	tmp[2] = word[(2+bytes) & (BC_128_OPT-1)];
+	tmp[3] = word[(3+bytes) & (BC_128_OPT-1)];
+	*((word32 *)word) = *((word32 *)tmp);
+}
+#endif
+
+static inline void ShiftRow128(
+	word8 a[4][BC_128_OPT], 
+	word8 d) {
+	/* Row 0 remains unchanged
+	 * The other three rows are shifted (actually rotated) a variable amount
+	 */
+	int i;
+	
+	for(i = 1; i < 4; i++) {
+		rotateWordLeft(a[i], shifts128[i][d]);
+	}
+}
+
+/*
+ * The following two routines are where most of the time is spent in this
+ * module. Further optimization would have to focus here. 
+ */
+static void MixColumn128(word8 a[4][BC_128_OPT]) {
+	/* Mix the four bytes of every column in a linear way
+	 */
+	word8 b[4][BC_128_OPT];
+	int i, j;
+	
+	for(j = 0; j < BC_128_OPT; j++) {
+		for(i = 0; i < 4; i++) {
+			#if		AES_MUL_BY_LOOKUP
+			b[i][j] = mulBy0x02[a[i][j]]
+				^ mulBy0x03[a[(i + 1) % 4][j]]
+				^ a[(i + 2) % 4][j]
+				^ a[(i + 3) % 4][j];
+			#else
+			b[i][j] = mul(2,a[i][j])
+				^ mul(3,a[(i + 1) % 4][j])
+				^ a[(i + 2) % 4][j]
+				^ a[(i + 3) % 4][j];
+			#endif
+		}
+	}
+	memmove(a, b, 4 * BC_128_OPT);
+}
+
+static void InvMixColumn128(word8 a[4][BC_128_OPT]) {
+	/* Mix the four bytes of every column in a linear way
+	 * This is the opposite operation of Mixcolumn
+	 */
+	word8 b[4][BC_128_OPT];
+	int i, j;
+	
+	for(j = 0; j < BC_128_OPT; j++) {
+		for(i = 0; i < 4; i++) {  
+			#if		AES_MUL_BY_LOOKUP
+			b[i][j] = mulBy0x0e[a[i][j]]
+				^ mulBy0x0b[a[(i + 1) % 4][j]]
+				^ mulBy0x0d[a[(i + 2) % 4][j]]
+				^ mulBy0x09[a[(i + 3) % 4][j]];     
+			#else
+			b[i][j] = mul(0xe,a[i][j])
+				^ mul(0xb,a[(i + 1) % 4][j])                 
+				^ mul(0xd,a[(i + 2) % 4][j])
+				^ mul(0x9,a[(i + 3) % 4][j]);     
+			#endif
+		}
+	}
+	memmove(a, b, 4 * BC_128_OPT);
+}
+
+int rijndaelKeySched128 (
+	word8 k[4][KC_128_OPT], 
+	word8 W[MAXROUNDS+1][4][MAXBC]) {
+	
+	/* Calculate the necessary round keys
+	 * The number of calculations depends on keyBits and blockBits
+	 */
+	int i, j, t, rconpointer = 0;
+	word8 tk[4][KC_128_OPT];   
+	unsigned numSchedRows = (ROUNDS_128_OPT + 1) * BC_128_OPT;
+	
+	for(j = 0; j < KC_128_OPT; j++)
+		for(i = 0; i < 4; i++)
+			tk[i][j] = k[i][j];
+	t = 0;
+	/* copy values into round key array */
+	for(j = 0; (j < KC_128_OPT) && (t < numSchedRows); j++, t++) {
+		for(i = 0; i < 4; i++) {
+			W[t / BC_128_OPT][i][t % BC_128_OPT] = tk[i][j];
+		}
+	}
+		
+	while (t < numSchedRows) { 
+		/* while not enough round key material calculated */
+		/* calculate new values */
+		for(i = 0; i < 4; i++) {
+			tk[i][0] ^= S[tk[(i+1)%4][KC_128_OPT-1]];
+		}
+		tk[0][0] ^= rcon[rconpointer++];
+
+		for(j = 1; j < KC_128_OPT; j++) {
+			for(i = 0; i < 4; i++) {
+				tk[i][j] ^= tk[i][j-1];
+			}
+		}
+
+		/* copy values into round key array */
+		for(j = 0; (j < KC_128_OPT) && (t < numSchedRows); j++, t++) {
+			for(i = 0; i < 4; i++) {
+				W[t / BC_128_OPT][i][t % BC_128_OPT] = tk[i][j];
+			}
+		}
+	}		
+
+	return 0;
+}
+
+int rijndaelEncrypt128 (
+	word8 a[4][BC_128_OPT], 
+	word8 rk[MAXROUNDS+1][4][MAXBC])
+{
+	/* Encryption of one block. 
+	 */
+	int r;
+
+	/* begin with a key addition
+	 */
+	KeyAddition128(a,rk[0]); 
+	
+	/* ROUNDS-1 ordinary rounds
+	 */
+	for(r = 1; r < ROUNDS_128_OPT; r++) {
+		Substitution128(a,S);
+		ShiftRow128(a,0);
+		MixColumn128(a);
+		KeyAddition128(a,rk[r]);
+	}
+	
+	/* Last round is special: there is no MixColumn
+	 */
+	Substitution128(a,S);
+	ShiftRow128(a,0);
+	KeyAddition128(a,rk[ROUNDS_128_OPT]);
+
+	return 0;
+}   
+
+int rijndaelDecrypt128 (
+	word8 a[4][BC_128_OPT], 
+	word8 rk[MAXROUNDS+1][4][MAXBC])
+{
+	int r;
+	
+	/* To decrypt: apply the inverse operations of the encrypt routine,
+	 *             in opposite order
+	 * 
+	 * (KeyAddition is an involution: it 's equal to its inverse)
+	 * (the inverse of Substitution with table S is Substitution with the 
+	 *  inverse table of S)
+	 * (the inverse of Shiftrow is Shiftrow over a suitable distance)
+	 */
+
+	/* First the special round:
+	 *   without InvMixColumn
+	 *   with extra KeyAddition
+	 */
+	KeyAddition128(a,rk[ROUNDS_128_OPT]);
+	Substitution128(a,Si);
+	ShiftRow128(a,1);              
+	
+	/* ROUNDS-1 ordinary rounds
+	 */
+	for(r = ROUNDS_128_OPT-1; r > 0; r--) {
+		KeyAddition128(a,rk[r]);
+		InvMixColumn128(a);      
+		Substitution128(a,Si);
+		ShiftRow128(a,1);                
+	}
+	
+	/* End with the extra key addition
+	 */
+	
+	KeyAddition128(a,rk[0]);    
+
+	return 0;
+}
+
diff --git a/AppleCSP/AES/rijndael-alg-ref.h b/AppleCSP/AES/rijndael-alg-ref.h
new file mode 100644
index 00000000..193f376c
--- /dev/null
+++ b/AppleCSP/AES/rijndael-alg-ref.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+
+/* rijndael-alg-ref.h   v2.0   August '99
+ * Reference ANSI C code
+ * authors: Paulo Barreto
+ *          Vincent Rijmen
+ */
+#ifndef __RIJNDAEL_ALG_H
+#define __RIJNDAEL_ALG_H
+
+#ifdef	__APPLE__
+#define MIN_AES_KEY_BITS		128
+#define MID_AES_KEY_BITS		192
+#define MAX_AES_KEY_BITS		256
+
+#define MIN_AES_BLOCK_BITS		128
+#define MID_AES_BLOCK_BITS		192
+#define MAX_AES_BLOCK_BITS		256
+#endif
+#define MAXBC				(MAX_AES_BLOCK_BITS/32)
+#define MAXKC				(MAX_AES_KEY_BITS/32)
+#define MAXROUNDS			14
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char		word8;	
+typedef unsigned short		word16;	
+typedef unsigned long		word32;
+
+
+int rijndaelKeySched (word8 k[4][MAXKC], int keyBits, int blockBits, 
+		word8 rk[MAXROUNDS+1][4][MAXBC]);
+int rijndaelEncrypt (word8 a[4][MAXBC], int keyBits, int blockBits, 
+		word8 rk[MAXROUNDS+1][4][MAXBC]);
+#ifndef	__APPLE__
+int rijndaelEncryptRound (word8 a[4][MAXBC], int keyBits, int blockBits, 
+		word8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
+#endif
+int rijndaelDecrypt (word8 a[4][MAXBC], int keyBits, int blockBits, 
+		word8 rk[MAXROUNDS+1][4][MAXBC]);
+#ifndef	__APPLE__
+int rijndaelDecryptRound (word8 a[4][MAXBC], int keyBits, int blockBits, 
+		word8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
+#endif
+
+/*
+ * Optimized routines for 128-bit block and key.
+ */
+#define ROUNDS_128_OPT	10
+#define BC_128_OPT		4
+#define KC_128_OPT		4
+
+/*
+ * These require 32-bit word-aligned a, k, and rk arrays 
+ */
+int rijndaelKeySched128 (word8 k[4][KC_128_OPT], 
+	word8 rk[MAXROUNDS+1][4][MAXBC]);
+int rijndaelEncrypt128 (word8 a[4][BC_128_OPT], 
+	word8 rk[MAXROUNDS+1][4][MAXBC]);
+int rijndaelDecrypt128 (word8 a[4][BC_128_OPT], 
+	word8 rk[MAXROUNDS+1][4][MAXBC]);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* __RIJNDAEL_ALG_H */
diff --git a/AppleCSP/AES/rijndaelApi.c b/AppleCSP/AES/rijndaelApi.c
new file mode 100644
index 00000000..9fbd1cfe
--- /dev/null
+++ b/AppleCSP/AES/rijndaelApi.c
@@ -0,0 +1,268 @@
+/*
+ * 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.
+ */
+
+
+/* 
+ * rijndaelApi.c  -  AES API layer
+ *
+ * Based on rijndael-api-ref.h v2.0 written by Paulo Barreto
+ * and Vincent Rijmen
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "rijndael-alg-ref.h"
+#include "rijndaelApi.h"
+
+#ifdef	ALTIVEC_ENABLE
+/* this goes somewhere else and gets init'd by the plugin object.... */
+/* as of 4/11/2001, the vectorized routines do NOT work */
+int gHasAltivec = 0;
+#endif
+
+int doAES128 = 1;
+
+#define CBC_DEBUG		0
+#if 	CBC_DEBUG
+static void dumpChainBuf(cipherInstance *cipher, char *op)
+{
+	int t,j;
+	int columns = cipher->blockLen / 32;
+
+	printf("chainBuf %s: ", op);
+	for (j = 0; j < columns; j++) {
+		for(t = 0; t < 4; t++) {
+			printf("%02x ", cipher->chainBlock[t][j]);
+		}
+	}
+	printf("\n");
+}
+#else
+#define dumpChainBuf(c, o)
+#endif
+
+int makeKey(	
+	keyInstance *key, 
+	int keyLen, 		// in BITS
+	int blockLen,		// in BITS
+	word8 *keyMaterial,
+	int enable128Opt)
+{
+	unsigned keyBytes;
+	unsigned  i;
+
+	if (key == NULL) {
+		return BAD_KEY_INSTANCE;
+	}
+	if(keyMaterial == NULL) {
+		return BAD_KEY_MAT;
+	}
+	if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 
+		key->keyLen = keyLen;
+	} else {
+		return BAD_KEY_MAT;
+	}
+	key->blockLen = blockLen;
+	key->columns = blockLen / 32;
+	
+	/* initialize key schedule */ 
+	if(enable128Opt && 
+			(keyLen == MIN_AES_KEY_BITS) && 
+			(blockLen == MIN_AES_BLOCK_BITS)) {
+		/* optimized, 128 bit key and block size */
+		word8 k[4][KC_128_OPT] __attribute__((aligned(4)));
+		
+		for(i = 0; i < (MIN_AES_KEY_BITS/8); i++) {
+			/* speed this up */
+			k[i % 4][i / 4] = keyMaterial[i]; 
+		}	
+		rijndaelKeySched128 (k, key->keySched);	
+		memset(k, 0, 4 * KC_128_OPT);
+	}
+	else {
+		/* general case */
+		word8 k[4][MAXKC];
+
+		keyBytes = keyLen / 8;
+		for(i = 0; i < keyBytes; i++) {
+			k[i % 4][i / 4] = keyMaterial[i]; 
+		}	
+		rijndaelKeySched (k, key->keyLen, key->blockLen, key->keySched);	
+		memset(k, 0, 4 * MAXKC);
+	}
+	return TRUE;
+}
+
+/*
+ * Simplified single-block encrypt/decrypt.
+ */
+#define AES_CONSISTENCY_CHECK		1
+
+int rijndaelBlockEncrypt(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer)
+{
+	int j, t;
+	word8 localBlock[4][MAXBC];		// working memory: encrypt/decrypt in place here
+	
+	#if		AES_CONSISTENCY_CHECK
+	if (key == NULL ||
+		(key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256) ||
+		(key->blockLen != 128 && key->blockLen != 192 && key->blockLen != 256)) {
+		return BAD_KEY_INSTANCE;
+	}
+	#endif	/* AES_CONSISTENCY_CHECK */
+	
+	#if	defined(__ppc__) && defined(ALTIVEC_ENABLE)
+	if(gHasAltivec && (key->blockLen == 128)) {
+		vBlockEncrypt128(key, input, outBuffer);
+		return 128; 
+	}
+	#endif
+	
+	for (j = 0; j < key->columns; j++) {
+		for(t = 0; t < 4; t++)
+		/* parse input stream into rectangular array */
+			localBlock[t][j] = input[4*j+t];
+	}
+	rijndaelEncrypt (localBlock, key->keyLen, key->blockLen, key->keySched);
+	for (j = 0; j < key->columns; j++) {
+		/* parse rectangular array into output ciphertext bytes */
+		for(t = 0; t < 4; t++)
+			outBuffer[4*j+t] = (word8) localBlock[t][j];
+	}
+	memset(localBlock, 0, 4 * MAXBC);
+	return key->blockLen;
+}
+
+int rijndaelBlockDecrypt(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer)
+{
+	int j, t;
+	word8 localBlock[4][MAXBC];		// working memory: encrypt/decrypt in place here
+
+	#if		AES_CONSISTENCY_CHECK
+	if (key == NULL ||
+		(key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256) ||
+		(key->blockLen != 128 && key->blockLen != 192 && key->blockLen != 256)) {
+		return BAD_KEY_INSTANCE;
+	}
+	#endif	/* AES_CONSISTENCY_CHECK */
+	
+	#if	defined(__ppc__) && defined(ALTIVEC_ENABLE)
+	if(gHasAltivec && (cipher->blockLen == 128)) {
+		vBlockDecrypt128(key, input, outBuffer);
+		return 128;
+	}
+	#endif
+	
+	for (j = 0; j < key->columns; j++) {
+		for(t = 0; t < 4; t++)
+		/* parse input stream into rectangular array */
+			localBlock[t][j] = input[4*j+t];
+	}
+	rijndaelDecrypt (localBlock, key->keyLen, key->blockLen, key->keySched);
+	for (j = 0; j < key->columns; j++) {
+		/* parse rectangular array into output ciphertext bytes */
+		for(t = 0; t < 4; t++)
+			outBuffer[4*j+t] = (word8) localBlock[t][j];
+	}
+	memset(localBlock, 0, 4 * MAXBC);
+	return key->blockLen;
+}
+
+/*
+ * Optimized routines for 128 bit block and 128 bit key.
+ */
+int rijndaelBlockEncrypt128(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer)
+{
+	int j;
+	word8 localBlock[4][BC_128_OPT] __attribute__((aligned(4)));
+	word8 *row0 = localBlock[0];
+	word8 *row1 = localBlock[1];
+	word8 *row2 = localBlock[2];
+	word8 *row3 = localBlock[3];
+	
+	/* parse input stream into rectangular array */
+	for (j = 0; j < BC_128_OPT; j++) {
+		*row0++ = *input++;
+		*row1++ = *input++;
+		*row2++ = *input++;
+		*row3++ = *input++;
+	}
+	rijndaelEncrypt128 (localBlock, key->keySched);
+	
+	/* parse rectangular array into output ciphertext bytes */
+	row0 = localBlock[0];
+	row1 = localBlock[1];
+	row2 = localBlock[2];
+	row3 = localBlock[3];
+
+	for (j = 0; j < BC_128_OPT; j++) {
+		*outBuffer++ = *row0++;
+		*outBuffer++ = *row1++;
+		*outBuffer++ = *row2++;
+		*outBuffer++ = *row3++;
+	}
+	memset(localBlock, 0, 4*BC_128_OPT);
+	return MIN_AES_BLOCK_BITS;
+}
+
+int rijndaelBlockDecrypt128(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer)
+{
+	int j;
+	word8 localBlock[4][BC_128_OPT] __attribute__((aligned(4)));	
+	word8 *row0 = localBlock[0];
+	word8 *row1 = localBlock[1];
+	word8 *row2 = localBlock[2];
+	word8 *row3 = localBlock[3];
+	
+	/* parse input stream into rectangular array */
+	for (j = 0; j < BC_128_OPT; j++) {
+		*row0++ = *input++;
+		*row1++ = *input++;
+		*row2++ = *input++;
+		*row3++ = *input++;
+	}
+	
+	rijndaelDecrypt128 (localBlock, key->keySched);
+	
+	/* parse rectangular array into output ciphertext bytes */
+	row0 = localBlock[0];
+	row1 = localBlock[1];
+	row2 = localBlock[2];
+	row3 = localBlock[3];
+
+	for (j = 0; j < BC_128_OPT; j++) {
+		*outBuffer++ = *row0++;
+		*outBuffer++ = *row1++;
+		*outBuffer++ = *row2++;
+		*outBuffer++ = *row3++;
+	}
+	memset(localBlock, 0, 4*BC_128_OPT);
+	return MIN_AES_BLOCK_BITS;
+}
+
diff --git a/AppleCSP/AES/rijndaelApi.h b/AppleCSP/AES/rijndaelApi.h
new file mode 100644
index 00000000..e1f36233
--- /dev/null
+++ b/AppleCSP/AES/rijndaelApi.h
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+/* 
+ * rijndaelApi.h  -  AES API layer
+ *
+ * Based on rijndael-api-ref.h v2.0 written by Paulo Barreto
+ * and Vincent Rijmen
+ */
+
+#ifndef	_RIJNDAEL_API_REF_H_
+#define _RIJNDAEL_API_REF_H_
+
+#include <stdio.h>
+#include "rijndael-alg-ref.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*  Error Codes  */
+#define     BAD_KEY_MAT        -1  /*  Key material not of correct 
+									   length */
+#define     BAD_KEY_INSTANCE   -2  /*  Key passed is not valid  */
+
+#define     MAX_AES_KEY_SIZE	(MAX_AES_KEY_BITS / 8)
+#define 	MAX_AES_BLOCK_SIZE	(MAX_AES_BLOCK_BITS / 8)
+#define     MAX_AES_IV_SIZE		MAX_AES_BLOCK_SIZE
+	
+#define		TRUE		1
+#define 	FALSE		0
+
+/*  The structure for key information */
+typedef struct {
+	word32   		keyLen;		/* Length of the key in bits */
+	word32  		blockLen;   /* Length of block in bits */
+	word32			columns;	/* optimization, blockLen / 32 */
+	word8 			keySched[MAXROUNDS+1][4][MAXBC];	
+} keyInstance;
+
+int makeKey(
+	keyInstance *key, 
+	int keyLen, 		// in BITS
+	int blockLen,		// in BITS
+	word8 *keyMaterial,
+	int enable128Opt);
+
+/*
+ * Simplified single-block encrypt/decrypt.
+ */
+int rijndaelBlockEncrypt(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer);
+int rijndaelBlockDecrypt(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer);
+	
+/*
+ * Optimized routines for 128 bit block and 128 bit key.
+ */
+int rijndaelBlockEncrypt128(
+	keyInstance 	*key, 
+	word8 			*input, 
+	word8 			*outBuffer);
+int rijndaelBlockDecrypt128(
+	keyInstance 	*key, 
+	word8 			*input, 
+	word8 			*outBuffer);
+
+#ifdef	__ppc__
+/* 
+ * dmitch addenda 4/11/2001: 128-bit only vectorized encrypt/decrypt with no CBC
+ */
+void vBlockEncrypt128(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer);
+void vBlockDecrypt128(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer);
+#endif	__ppc__
+	
+/* temp switch for runtime enable/disable */
+extern int doAES128;
+
+/* ptr to one of several (possibly optimized) encrypt/decrypt functions */
+typedef int (*aesCryptFcn)(
+	keyInstance *key, 
+	word8 *input, 
+	word8 *outBuffer);
+
+#ifdef	__cplusplus
+}
+#endif	// cplusplus
+
+#endif	// RIJNDAEL_API_REF
+
+
diff --git a/AppleCSP/AES/vRijndael-alg-ref.c b/AppleCSP/AES/vRijndael-alg-ref.c
new file mode 100644
index 00000000..88893836
--- /dev/null
+++ b/AppleCSP/AES/vRijndael-alg-ref.c
@@ -0,0 +1,684 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  vRijndael-alg-ref.c
+ *
+ *  Created by Robert A. Murley on Mon Jan 22 2001.
+ *  Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+ *
+ */
+
+#include "rijndaelApi.h"
+#include "rijndael-alg-ref.h"
+#include "boxes-ref.h"
+#include <string.h>
+
+/* debugger seems to have trouble with this code... */
+#define VAES_DEBUG	1
+#if		VAES_DEBUG
+#include <stdio.h>
+#define vdprintf(s)		printf s
+#else
+#define vdprintf(s)
+#endif
+
+#define SC	((BC - 4) >> 1)
+
+#if defined(__ppc__) && defined(ALTIVEC_ENABLE)
+
+typedef union {
+	unsigned char		s[4][8];
+	unsigned long		l[8];
+	vector unsigned char 	v[2];
+} doubleVec;
+
+typedef union {
+	unsigned long		s[4];
+	vector unsigned long	v;
+} vecLong;
+
+static word8 shifts[3][4][2] = {
+ { { 0, 0 },
+   { 1, 3 },
+   { 2, 2 },
+   { 3, 1 }
+ },
+ { { 0, 0 },
+   { 1, 5 },
+   { 2, 4 },
+   { 3, 3 }
+ },
+ { { 0, 0 },
+   { 1, 7 },
+   { 3, 5 },
+   { 4, 4 }
+ }
+};
+
+int vRijndaelKeySched ( vector unsigned char vk[2], int keyBits, int blockBits, 
+                unsigned char W[MAXROUNDS+1][4][MAXBC])
+{
+	/* Calculate the necessary round keys
+	 * The number of calculations depends on keyBits and blockBits
+	 */
+	int KC, BC, ROUNDS;
+	int i, j, t, rconpointer = 0;
+	doubleVec tk;
+	register  vector unsigned char v1, v2, mask;
+
+	switch (keyBits) {
+	case 128: KC = 4; break;
+	case 192: KC = 6; break;
+	case 256: KC = 8; break;
+	default : return (-1);
+	}
+
+	switch (blockBits) {
+	case 128: BC = 4; break;
+	case 192: BC = 6; break;
+	case 256: BC = 8; break;
+	default : return (-2);
+	}
+
+	switch (keyBits >= blockBits ? keyBits : blockBits) {
+	case 128: ROUNDS = 10; break;
+	case 192: ROUNDS = 12; break;
+	case 256: ROUNDS = 14; break;
+	default : return (-3); /* this cannot happen */
+	}
+
+	tk.v[0] = vk[0];
+	tk.v[1] = vk[1];
+	
+	t = 0;
+	/* copy values into round key array */
+	for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
+		for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk.s[i][j];
+		
+	while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
+		/* calculate new values */
+		for(i = 0; i < 4; i++)
+			tk.s[i][0] ^= *((word8 *)S + tk.s[(i+1)%4][KC-1]);
+		tk.s[0][0] ^= rcon[rconpointer++];
+
+		if (KC != 8) {
+			/* xor bytes 1-7 of each row with previous byte */
+			mask = (vector unsigned char) ( 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff );
+			for ( i = 0; i < 2; i++ ) {
+				v1 = vec_sld( tk.v[i], tk.v[i], 15 );
+				v2 = vec_and( v1, mask );
+				tk.v[i] = vec_xor( tk.v[i], v2 );
+			}
+		}
+		else {
+			/* xor bytes 1-3 of each row with previous byte */
+			mask = (vector unsigned char) ( 0, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0 );
+			for ( i = 0; i < 2; i++ ) {
+				v1 = vec_sld( tk.v[i], tk.v[i], 15 );
+				v2 = vec_and( v1, mask );
+				tk.v[i] = vec_xor( tk.v[i], v2 );
+				for(j = 0; j < 4; j++) tk.s[i][KC/2] ^= *((word8 *)S + tk.s[i][KC/2 - 1]);
+				/* xor bytes 5-7 of each row with previous byte */
+				mask = vec_sld( mask, mask, 4 );
+				v2 = vec_and( v1, mask );
+				tk.v[i] = vec_xor( tk.v[i], v2 );
+				mask = vec_sld( mask, mask, 4 );
+			}
+		}
+		/* copy values into round key array */
+		for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
+			for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk.s[i][j];
+	}		
+	return 0;
+}
+
+
+void vMakeKey(BYTE *keyMaterial, keyInstance *key)
+{
+        register vector unsigned char v1, v2, v3, mask;
+        vector unsigned char	  vk[2];
+
+        /* load and align input */
+        v1 = vec_ld( 0, (vector unsigned char *) keyMaterial );
+        v2 = vec_ld( 16, (vector unsigned char *) keyMaterial );
+        if ( (long) keyMaterial & 0x0fL )
+        {	// this is required if keyMaterial is not on a 16-byte boundary
+                v3 = vec_ld( 32, (vector unsigned char *) keyMaterial );
+                mask = vec_lvsl( 0, keyMaterial );
+                v1 = vec_perm( v1, v2, mask );
+                v2 = vec_perm( v2, v3, mask );
+        }
+
+        /* parse input stream into rectangular array */
+        vk[0] = vec_perm( v1, v2, (vector unsigned char) ( 0,  4,  8, 12, 16, 20, 24, 28,  1,  5,  9, 13, 17, 21, 25, 29 ) );
+        vk[1] = vec_perm( v1, v2, (vector unsigned char) ( 2,  6, 10, 14, 18, 22, 26, 30,  3,  7, 11, 15, 19, 23, 27, 31 ) );
+        vRijndaelKeySched (vk, key->keyLen, key->blockLen, key->keySched);
+        memset( (char *) vk, 0, 4 * MAXKC);
+}
+
+
+/*	This routine does 16 simultaneous lookups in a 256-byte table.	*/
+vector unsigned char rimskyKorsakov ( vector unsigned char v, vector unsigned char * table )
+{
+	register vector unsigned char	upperBits000, upperBits001, upperBits010, upperBits011,
+                                        upperBits100, upperBits101, upperBits110, upperBits111,
+                                        lookupBit00,  lookupBit01, lookupBit10, lookupBit11,
+                                        lookupBit0, lookupBit1, lookup,
+                                        maskForBit6, maskForBit7, maskForBit8, seven;
+	register vector unsigned char	*tabeven, *tabodd;
+
+	seven = vec_splat_u8 ( 7 );
+	tabeven = table++;
+	tabodd = table;
+
+//	Each variable contains the correct values for the corresponding bits 6, 7 and 8.
+	upperBits000 = vec_perm ( *tabeven, *tabodd, v );
+	tabeven += 2; tabodd += 2;
+	upperBits001 = vec_perm ( *tabeven, *tabodd, v );
+	tabeven += 2; tabodd += 2;
+	upperBits010 = vec_perm ( *tabeven, *tabodd, v );
+	tabeven += 2; tabodd += 2;
+	upperBits011 = vec_perm ( *tabeven, *tabodd, v );
+	tabeven += 2; tabodd += 2;
+	upperBits100 = vec_perm ( *tabeven, *tabodd, v ); 
+	tabeven += 2; tabodd += 2;
+	upperBits101 = vec_perm ( *tabeven, *tabodd, v );
+	tabeven += 2; tabodd += 2;
+	upperBits110 = vec_perm ( *tabeven, *tabodd, v );
+	tabeven += 2; tabodd += 2;
+	upperBits111 = vec_perm ( *tabeven, *tabodd, v );
+	
+//	Here we extract all the correct values for bit 6.
+	maskForBit6  = vec_sl  ( v, vec_splat_u8 ( 2 ) );
+	maskForBit6  = vec_sra ( maskForBit6, seven );
+	lookupBit00 = vec_sel ( upperBits000, upperBits001, maskForBit6 );
+	lookupBit01 = vec_sel ( upperBits010, upperBits011, maskForBit6 );
+	lookupBit10 = vec_sel ( upperBits100, upperBits101, maskForBit6 );
+	lookupBit11 = vec_sel ( upperBits110, upperBits111, maskForBit6 );
+
+//	Then we get the correct values for bit 7.
+	maskForBit7  = vec_sl  ( v, vec_splat_u8 ( 1 ) );
+	maskForBit7  = vec_sra ( maskForBit7, seven );
+	lookupBit0 = vec_sel ( lookupBit00, lookupBit01, maskForBit7 );
+	lookupBit1 = vec_sel ( lookupBit10, lookupBit11, maskForBit7 );
+
+//	Finally, the entire correct result vector.
+	maskForBit8 = vec_sra ( v, seven );
+	
+	lookup = vec_sel ( lookupBit0, lookupBit1, maskForBit8 );
+      
+    return lookup;
+}
+
+vector unsigned char vmul(vector unsigned char a, vector unsigned char b)
+{
+	register vector unsigned char x, y, zero;
+	register vector unsigned short xh, yh, zhi, zlo, two54, two55;
+	
+	zero = vec_splat_u8( 0 );
+	two55 = vec_splat_u16( -1 );
+	two55 = (vector unsigned short) vec_mergeh( zero, (vector unsigned char) two55 );
+	two54 = vec_sub( two55, vec_splat_u16( 1 ) ); 
+
+	x = rimskyKorsakov( a, (vector unsigned char *)Logtable );	// Logtable[a]
+	y = rimskyKorsakov( b, (vector unsigned char *)Logtable );	// Logtable[b]
+
+	//	Convert upper 8 bytes to shorts for addition ond modulo
+	xh = (vector unsigned short) vec_mergeh( zero, x );
+	yh = (vector unsigned short) vec_mergeh( zero, y );
+	xh = vec_add( xh, yh );			// xh = Logtable[a] + Logtable[b]
+	yh = vec_sub( xh, two55 );
+	zhi = vec_sel( xh, yh, vec_cmpgt( xh, two54 ) );	// xh%255
+
+	//	Convert lower 8 bytes to shorts for addition ond modulo
+	xh = (vector unsigned short) vec_mergel( zero, x );
+	yh = (vector unsigned short) vec_mergel( zero, y );
+	xh = vec_add( xh, yh );
+	yh = vec_sub( xh, two55 );
+	zlo = vec_sel( xh, yh, vec_cmpgt( xh, two54 ) );
+
+	x = vec_pack( zhi, zlo );			// recombine into single byte vector
+	x = rimskyKorsakov( x, (vector unsigned char *)Alogtable );		// Alogtable[x]
+	x = vec_sel( x, zero, vec_cmpeq( a, zero ) );	// check a = 0
+	x = vec_sel( x, zero, vec_cmpeq( b, zero ) );	// check b = 0
+	return x;
+}
+
+void vKeyAddition(vector unsigned char v[2], vector unsigned char rk[2])
+{
+	v[0] = vec_xor( v[0], rk[0] );		// first vector contains rows 0 and 1
+	v[1] = vec_xor( v[1], rk[1] );		// second vector contains rows 2 and 3
+}
+
+
+void vShiftRow(vector unsigned char v[2], word8 d, word8 BC)
+{
+	vecLong			sh;
+	register vector unsigned char mask, mask1, t;
+	register vector bool char c;
+	register int	i, j;
+	
+	sh.s[0] = 0;
+	for (i = 1; i < 4; i++)
+		sh.s[i] = shifts[SC][i][d] % BC;	//	contains the number of elements to shift each row
+		
+	// each vector contains two BC-byte long rows
+	j = 0;
+	for ( i = 0; i < 2; i++ ) {
+		mask = vec_lvsl( 0, (int *) sh.s[j++]);		//	mask for even row
+		mask1 = vec_lvsl( 0, (int *) sh.s[j++]);	//	mask for odd row
+		if (BC == 4) {
+			mask = vec_sld( mask, mask1, 8 );		//	combined rotation mask for both rows
+			mask = vec_and( mask, vec_splat_u8( 3 ) );
+		} else if (BC == 6) {
+			mask = vec_sld( mask, mask, 8 );
+			mask = vec_sld( mask, mask1, 8 );		//	combined rotation mask for both rows
+			t = vec_sub( mask, vec_splat_u8( 6 ) );
+			c = vec_cmpgt( mask, vec_splat_u8( 5 ) );
+			mask = vec_sel( mask, t, c );
+		} else {
+			mask = vec_sld( mask, mask1, 8 );		//	combined rotation mask for both rows
+			mask = vec_and( mask, vec_splat_u8( 7 ) );
+		}
+		mask1 = vec_sld( vec_splat_u8( 0 ), vec_splat_u8( 8 ), 8 );
+		mask = vec_add( mask, mask1 );
+		v[i] = vec_perm( v[i], v[i], mask );		//	rotate each row as required
+	}
+}
+
+void vSubstitution( vector unsigned char v[2], vector unsigned char box[16] )
+{
+	v[0] = rimskyKorsakov( v[0], box );		// first vector contains rows 0 and 1
+	v[1] = rimskyKorsakov( v[1], box );		// second vector contains rows 2 and 3
+}
+   
+void vMixColumn(vector unsigned char v[2])
+{
+	//	vector 0 contains row 0 in bytes 0-7 and row 1 in bytes 8-f
+	//	vector 1 contains row 2 in bytes 0-7 and row 3 in bytes 8-f
+
+	register vector unsigned char a0, a1, a2, a3, b0, b1, b2, b3;
+	register vector unsigned char two, three;
+	
+	two = vec_splat_u8( 2 );
+	three = vec_splat_u8( 3 );
+
+	a1 = vec_sld( v[0], v[1], 8 );		// equivalent to a[i+1] % 4
+	b1 = vec_sld( v[1], v[0], 8 );
+	a2 = vec_sld( a1, b1, 8 );		// equivalent to a[i+2] % 4
+	b2 = vec_sld( b1, a1, 8 );
+	a3 = vec_sld( a2, b2, 8 );		// equivalent to a[i+3] % 4
+	b3 = vec_sld( b2, a2, 8 );
+	
+	//	Calculations for rows 0 and 1
+	a0 = vmul( two, v[0] );				// mul(2,a[i][j])
+	a0 = vec_xor( a0, vmul( three, a1 ) );		// ^ mul(3,a[(i + 1) % 4][j])
+	a0 = vec_xor( a0, a2 );				// ^ a[(i + 2) % 4][j]
+	v[0]  = vec_xor( a0, a3 );			// ^ a[(i + 3) % 4][j]
+
+	//	Calculations for rows 2 and 3
+	b0 = vmul( two, v[1] );
+	b0 = vec_xor( b0, vmul( three, b1 ) );
+	b0 = vec_xor( b0, b2 );
+	v[1] = vec_xor( b0, b3 );
+}
+
+void vInvMixColumn(vector unsigned char v[2])
+{
+	//	vector 0 contains row 0 in bytes 0-7 and row 1 in bytes 8-f
+	//	vector 1 contains row 2 in bytes 0-7 and row 3 in bytes 8-f
+
+	register vector unsigned char a0, a1, a2, a3, b0, b1, b2, b3;
+	register vector unsigned char nine, eleven, thirteen, fourteen;;
+	
+	nine = vec_splat_u8( 0x9 );
+	eleven = vec_splat_u8( 0xb );
+	thirteen = vec_splat_u8( 0xd );
+	fourteen = vec_splat_u8( 0xe );
+
+	a1 = vec_sld( v[0], v[1], 8 );			// equivalent to a[i+1] % 4
+	b1 = vec_sld( v[1], v[0], 8 );
+	a2 = vec_sld( a1, b1, 8 );			// equivalent to a[i+2] % 4
+	b2 = vec_sld( b1, a1, 8 );
+	a3 = vec_sld( a2, b2, 8 );			// equivalent to a[i+3] % 4
+	b3 = vec_sld( b2, a2, 8 );
+	
+	//	Calculations for rows 0 and 1
+	a0 = vmul( fourteen, v[0] );				// mul(0xe,a[i][j])
+	a0 = vec_xor( a0, vmul( eleven, a1 ) );		// ^ mul(0xb,a[(i + 1) % 4][j])
+	a0 = vec_xor( a0, vmul( thirteen, a2 ) );	// ^ mul(0xd,a[(i + 2) % 4][j])
+	v[0]  = vec_xor( a0, vmul( nine, a3 ) );	// ^ mul(0x9,a[(i + 3) % 4][j])
+
+	//	Calculations for rows 2 and 3
+	b0 = vmul( fourteen, v[1] );
+	b0 = vec_xor( b0, vmul( eleven, b1 ) );
+	b0 = vec_xor( b0, vmul( thirteen, b2 ) );
+	v[1]  = vec_xor( b0, vmul( nine, b3 ) );
+}
+
+int vRijndaelEncrypt (vector unsigned char a[2], int keyBits, int blockBits, vector unsigned char rk[MAXROUNDS+1][2])
+{
+	/* Encryption of one block. 
+	 */
+	int r, BC, ROUNDS;
+
+	switch (blockBits) {
+	case 128: BC = 4; break;
+	case 192: BC = 6; break;
+	case 256: BC = 8; break;
+	default : return (-2);
+	}
+
+	switch (keyBits >= blockBits ? keyBits : blockBits) {
+	case 128: ROUNDS = 10; break;
+	case 192: ROUNDS = 12; break;
+	case 256: ROUNDS = 14; break;
+	default : return (-3); /* this cannot happen */
+	}
+
+        vKeyAddition( a, rk[0] ); 
+        for(r = 1; r < ROUNDS; r++) {
+                vSubstitution( a, (vector unsigned char *)S);
+                vShiftRow( a, 0, BC);
+                vMixColumn( a );
+                vKeyAddition( a, rk[r] ); 	
+        }
+        vSubstitution( a, (vector unsigned char *)S);
+        vShiftRow( a, 0, BC);
+        vKeyAddition( a, rk[ROUNDS] ); 
+
+	return 0;
+}   
+
+int vRijndaelDecrypt (vector unsigned char a[2], int keyBits, int blockBits, vector unsigned char rk[MAXROUNDS+1][2])
+{
+	int r, BC, ROUNDS;
+	
+	switch (blockBits) {
+	case 128: BC = 4; break;
+	case 192: BC = 6; break;
+	case 256: BC = 8; break;
+	default : return (-2);
+	}
+
+	switch (keyBits >= blockBits ? keyBits : blockBits) {
+	case 128: ROUNDS = 10; break;
+	case 192: ROUNDS = 12; break;
+	case 256: ROUNDS = 14; break;
+	default : return (-3); /* this cannot happen */
+	}
+		
+        vKeyAddition( a, rk[ROUNDS] ); 
+        vSubstitution( a, (vector unsigned char *)Si);
+        vShiftRow( a, 1, BC);
+        for(r = ROUNDS-1; r > 0; r--) {
+                vKeyAddition( a, rk[r] ); 
+                vInvMixColumn( a );
+                vSubstitution( a, (vector unsigned char *)Si);
+                vShiftRow( a, 1, BC);
+        }
+        vKeyAddition( a, rk[0] ); 
+
+	return 0;
+}
+
+#if 0
+/* Murley's code, to be deleted */
+void vBlockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
+{
+        register vector unsigned char v1, v2, v3, v4, mask;
+        register vector bool char cmp;
+
+        /* load and align input */
+        v1 = vec_ld( 0, (vector unsigned char *) input );
+        v2 = vec_ld( 16, (vector unsigned char *) input );
+        if ( (long) input & 0x0fL )
+        {	// this is required if input is not on a 16-byte boundary
+                v3 = vec_ld( 32, (vector unsigned char *) input );
+                mask = vec_lvsl( 0, input );
+                v1 = vec_perm( v1, v2, mask );
+                v2 = vec_perm( v2, v3, mask );
+        }
+
+        /* parse input stream into rectangular array */
+        v3 = vec_perm( v1, v2, (vector unsigned char) ( 0,  4,  8, 12, 16, 20, 24, 28,  1,  5,  9, 13, 17, 21, 25, 29 ) );
+        v4 = vec_perm( v1, v2, (vector unsigned char) ( 2,  6, 10, 14, 18, 22, 26, 30,  3,  7, 11, 15, 19, 23, 27, 31 ) );
+
+        /* store into cipher structure */
+        if (cipher->mode == MODE_CBC) {
+                v3 = vec_xor( v3, *((vector unsigned char *) cipher->chainBlock ) );
+                v4 = vec_xor( v4, *((vector unsigned char *) cipher->chainBlock + 1 ) );
+        }
+        vec_st( v3, 0, (vector unsigned char *) cipher->chainBlock );
+        vec_st( v4, 16, (vector unsigned char *) cipher->chainBlock );
+
+        vRijndaelEncrypt((vector unsigned char *) cipher->chainBlock, key->keyLen, cipher->blockLen, (vector unsigned char *) key->keySched);
+
+        v1 = vec_ld( 0, (vector unsigned char *) cipher->chainBlock );
+        v2 = vec_ld( 16, (vector unsigned char *) cipher->chainBlock );
+
+        /* parse rectangular array into output ciphertext bytes */
+        v3 = vec_perm( v1, v2, (vector unsigned char) ( 0,  8, 16, 24,  1,  9, 17, 25,  2, 10, 18, 26,  3, 11, 19, 27 ) );
+        v4 = vec_perm( v1, v2, (vector unsigned char) ( 4, 12, 20, 28,  5, 13, 21, 29,  6, 14, 22, 30,  7, 15, 23, 31 ) );
+
+        if ( (long) outBuffer & 0x0fL )
+        {
+                /* store output data into a non-aligned buffer */
+                mask = vec_lvsr( 0, outBuffer );
+                cmp = vec_cmpgt( mask, vec_splat_u8( 0x0f ) );
+                v1 = vec_perm( v3, v3, mask );
+                v2 = vec_perm( v4, v4, mask );
+                v3 = vec_ld( 0, (vector unsigned char *) outBuffer );
+                v4 = vec_sel( v3, v1, cmp );
+                vec_st( v4, 0, (vector unsigned char *) outBuffer );
+                v1 = vec_sel( v1, v2, cmp );
+                vec_st( v1, 16, (vector unsigned char *) outBuffer );
+                v3 = vec_ld( 32, (vector unsigned char *) outBuffer );
+                v2 = vec_sel( v2, v3, cmp );
+                vec_st( v2, 32, (vector unsigned char *) outBuffer );
+        } else {
+                // store output data into an aligned buffer
+                vec_st( v3, 0, (vector unsigned char *) outBuffer );
+                vec_st( v4, 16, (vector unsigned char *) outBuffer );
+        }
+        return;
+}
+
+void vBlockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
+{
+        // for vector machines
+        register vector unsigned char v1, v2, v3, v4, mask;
+        register vector bool char cmp;
+        vector unsigned  char	block[2], cblock[2];
+
+        /* load and align input */
+        v1 = vec_ld( 0, (vector unsigned char *) input );
+        v2 = vec_ld( 16, (vector unsigned char *) input );
+        if ( (long) input & 0x0fL )
+        {	// this is required if input is not on a 16-byte boundary
+                v3 = vec_ld( 32, (vector unsigned char *) input );
+                mask = vec_lvsl( 0, input );
+                v1 = vec_perm( v1, v2, mask );
+                v2 = vec_perm( v2, v3, mask );
+        }
+
+        /* parse input stream into rectangular array */
+        v3 = vec_perm( v1, v2, (vector unsigned char) ( 0,  4,  8, 12, 16, 20, 24, 28,  1,  5,  9, 13, 17, 21, 25, 29 ) );
+        v4 = vec_perm( v1, v2, (vector unsigned char) ( 2,  6, 10, 14, 18, 22, 26, 30,  3,  7, 11, 15, 19, 23, 27, 31 ) );
+        block[0] = v3;
+        block[1] = v4;
+
+        /* save a copy of incoming ciphertext for later chain */
+        if (cipher->mode == MODE_CBC) {
+                cblock[0] = v3;
+                cblock[1] = v4;
+        }
+                
+        vRijndaelDecrypt ((vector unsigned char *) block, key->keyLen, cipher->blockLen, (vector unsigned char *) key->keySched);
+        
+        v1 = block[0];
+        v2 = block[1];
+
+        /* exor with last ciphertext */
+        if (cipher->mode == MODE_CBC) {
+                v1 = vec_xor( v1, *((vector unsigned char *) cipher->chainBlock) );
+                v2 = vec_xor( v2, *((vector unsigned char *) cipher->chainBlock + 1) );
+                vec_st( cblock[0], 0, (vector unsigned char *) cipher->chainBlock );
+                vec_st( cblock[1], 16, (vector unsigned char *) cipher->chainBlock );
+        }
+        
+        /* parse rectangular array into output ciphertext bytes */
+        v3 = vec_perm( v1, v2, (vector unsigned char) ( 0,  8, 16, 24,  1,  9, 17, 25,  2, 10, 18, 26,  3, 11, 19, 27 ) );
+        v4 = vec_perm( v1, v2, (vector unsigned char) ( 4, 12, 20, 28,  5, 13, 21, 29,  6, 14, 22, 30,  7, 15, 23, 31 ) );
+
+        if ( (long) outBuffer & 0x0fL )
+        {	/* store output data into a non-aligned buffer */
+                mask = vec_lvsr( 0, outBuffer );
+                cmp = vec_cmpgt( mask, vec_splat_u8( 0x0f ) );
+                v1 = vec_perm( v3, v3, mask );
+                v2 = vec_perm( v4, v4, mask );
+                v3 = vec_ld( 0, (vector unsigned char *) outBuffer );
+                v4 = vec_sel( v3, v1, cmp );
+                vec_st( v4, 0, (vector unsigned char *) outBuffer );
+                v1 = vec_sel( v1, v2, cmp );
+                vec_st( v1, 16, (vector unsigned char *) outBuffer );
+                v3 = vec_ld( 32, (vector unsigned char *) outBuffer );
+                v2 = vec_sel( v2, v3, cmp );
+                vec_st( v2, 32, (vector unsigned char *) outBuffer );
+        } else {
+                // store output data into an aligned buffer
+                vec_st( v3, 0, (vector unsigned char *) outBuffer );
+                vec_st( v4, 16, (vector unsigned char *) outBuffer );
+        }
+}
+#endif	/* Murley's code, to be deleted */
+
+/* 
+ * dmitch addenda 4/11/2001: 128-bit only encrypt/decrypt with no CBC
+ */
+void vBlockEncrypt128(
+	keyInstance *key, 
+	BYTE *input, 
+	BYTE *outBuffer)
+{
+	vector unsigned char block[2];
+	register vector unsigned char v1, v2;
+	
+	if ( (long) input & 0x0fL ) {
+		BYTE	localBuf[16];
+		vdprintf(("vBlockEncrypt128: unaligned input\n"));
+		/* manually re-align - the compiler is supposed to 16-byte align this for us */
+		if((unsigned)localBuf & 0xf) {
+			vdprintf(("vBlockEncrypt128: unaligned localBuf!\n"));
+		}
+		memmove(localBuf, input, 16);
+		v1 = vec_ld(0, (vector unsigned char *)localBuf);
+	}
+	else {
+		vdprintf(("vBlockEncrypt128: aligned input\n"));
+		v1 = vec_ld( 0, (vector unsigned char *) input );
+	}
+
+	/* parse input stream into rectangular array */
+	/* FIXME - do we need to zero v2 (or something)? */
+	block[0] = vec_perm(v1, v2,
+		(vector unsigned char) ( 0,  4,  8, 12, 16, 20, 24, 28,  1,  
+		5,  9, 13, 17, 21, 25, 29 ) );
+	block[1] = vec_perm( v1, v2, 
+		(vector unsigned char) ( 2,  6, 10, 14, 18, 22, 26, 30,  3,  
+		7, 11, 15, 19, 23, 27, 31 ) );
+
+	vRijndaelEncrypt(block, key->keyLen, 128, (vector unsigned char *) key->keySched);
+
+	/* parse rectangular array into output ciphertext bytes */
+	v1 = vec_perm(block[0], block[1], 
+		(vector unsigned char) ( 0,  8, 16, 24,  1,  9, 17, 25,  2, 
+		10, 18, 26,  3, 11, 19, 27 ) );
+	v2 = vec_perm(block[0], block[1], 
+		(vector unsigned char) ( 4, 12, 20, 28,  5, 13, 21, 29,  6, 
+		14, 22, 30,  7, 15, 23, 31 ) );
+
+	if ( (long) outBuffer & 0x0fL )
+	{
+		/* store output data into a non-aligned buffer */
+		BYTE	localBuf[16];
+		vec_st(v1, 0, (vector unsigned char *) localBuf );
+		memmove(outBuffer, localBuf, 16);
+	} else {
+		/* store output data into an aligned buffer */
+		vec_st( v1, 0, (vector unsigned char *) outBuffer );
+	}
+	return;
+}
+
+void vBlockDecrypt128(
+	keyInstance *key, 
+	BYTE *input, 
+	BYTE *outBuffer)
+{
+	vector unsigned char block[2];
+	register vector unsigned char v1, v2;
+	
+	if ( (long) input & 0x0fL ) {
+		/* manually re-align - the compiler is supposed to 16-byte align this for us */
+		BYTE	localBuf[16];
+		vdprintf(("vBlockDecrypt128: unaligned input\n"));
+		if((unsigned)localBuf & 0xf) {
+			vdprintf(("vBlockDecrypt128: unaligned localBuf!\n"));
+		}
+		memmove(localBuf, input, 16);
+		v1 = vec_ld(0, (vector unsigned char *)localBuf);
+	}
+	else {
+		vdprintf(("vBlockDecrypt128: aligned input\n"));
+		v1 = vec_ld( 0, (vector unsigned char *) input );
+	}
+
+	/* parse input stream into rectangular array */
+	/* FIXME - do we need to zero v2 (or something)? */
+	block[0] = vec_perm(v1, v2,
+		(vector unsigned char) ( 0,  4,  8, 12, 16, 20, 24, 28,  1,  
+		5,  9, 13, 17, 21, 25, 29 ) );
+	block[1] = vec_perm( v1, v2, 
+		(vector unsigned char) ( 2,  6, 10, 14, 18, 22, 26, 30,  3,  
+		7, 11, 15, 19, 23, 27, 31 ) );
+
+	vRijndaelDecrypt(block, key->keyLen, 128, (vector unsigned char *) key->keySched);
+
+	/* parse rectangular array into output ciphertext bytes */
+	v1 = vec_perm(block[0], block[1], 
+		(vector unsigned char) ( 0,  8, 16, 24,  1,  9, 17, 25,  2, 
+		10, 18, 26,  3, 11, 19, 27 ) );
+	v2 = vec_perm(block[0], block[1], 
+		(vector unsigned char) ( 4, 12, 20, 28,  5, 13, 21, 29,  6, 
+		14, 22, 30,  7, 15, 23, 31 ) );
+
+	if ( (long) outBuffer & 0x0fL ) {
+		/* store output data into a non-aligned buffer */
+		BYTE	localBuf[16];
+		vec_st(v1, 0, (vector unsigned char *) localBuf );
+		memmove(outBuffer, localBuf, 16);
+	} else {
+		/* store output data into an aligned buffer */
+		vec_st( v1, 0, (vector unsigned char *) outBuffer );
+	}
+	return;
+}
+
+#endif	/* !ppc */
diff --git a/AppleCSP/AppleCSP.pbxproj/.cvsignore b/AppleCSP/AppleCSP.pbxproj/.cvsignore
new file mode 100644
index 00000000..0857ac37
--- /dev/null
+++ b/AppleCSP/AppleCSP.pbxproj/.cvsignore
@@ -0,0 +1 @@
+*.pbxuser
diff --git a/AppleCSP/AppleCSP.pbxproj/project.pbxproj b/AppleCSP/AppleCSP.pbxproj/project.pbxproj
new file mode 100644
index 00000000..1524298d
--- /dev/null
+++ b/AppleCSP/AppleCSP.pbxproj/project.pbxproj
@@ -0,0 +1,2061 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 32;
+	objects = {
+		00B7C42CFEC78220D0A17CE7 = {
+			isa = PBXFileReference;
+			path = pkcs_7_8.cpp;
+			refType = 4;
+		};
+		00B7C42EFEC7824FD0A17CE7 = {
+			isa = PBXFileReference;
+			path = pkcs_7_8.h;
+			refType = 4;
+		};
+		00B7C430FEC78562D0A17CE7 = {
+			isa = PBXFileReference;
+			path = wrapKey.cpp;
+			refType = 4;
+		};
+		00B7C431FEC78562D0A17CE7 = {
+			fileRef = 00B7C430FEC78562D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00B95717FEBDE93ED0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleCSPUtils.cpp;
+			refType = 4;
+		};
+		00B95718FEBDE93ED0A17CE7 = {
+			fileRef = 00B95717FEBDE93ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00B95719FEBDEC98D0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleCSPUtils.h;
+			refType = 4;
+		};
+		00B9571AFEBDEC98D0A17CE7 = {
+			fileRef = 00B95719FEBDEC98D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		00B9571BFEBDF916D0A17CE7 = {
+			isa = PBXFileReference;
+			path = BinaryKey.h;
+			refType = 4;
+		};
+		00B9571CFEBDF916D0A17CE7 = {
+			fileRef = 00B9571BFEBDF916D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		00BBA18BFED05E75D0A17CE7 = {
+			isa = PBXFileReference;
+			name = HMACSHA1.c;
+			path = PBKDF2/HMACSHA1.c;
+			refType = 2;
+		};
+		00BBA18CFED05E75D0A17CE7 = {
+			isa = PBXFileReference;
+			name = pbkdf2.c;
+			path = PBKDF2/pbkdf2.c;
+			refType = 2;
+		};
+		00BBA18DFED05E75D0A17CE7 = {
+			isa = PBXFileReference;
+			name = HMACSHA1.h;
+			path = PBKDF2/HMACSHA1.h;
+			refType = 2;
+		};
+		00BBA18EFED05E75D0A17CE7 = {
+			isa = PBXFileReference;
+			name = pbkdf2.h;
+			path = PBKDF2/pbkdf2.h;
+			refType = 2;
+		};
+		00BBA18FFED05E75D0A17CE7 = {
+			fileRef = 00BBA18DFED05E75D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		00BBA190FED05E75D0A17CE7 = {
+			fileRef = 00BBA18EFED05E75D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		00BBA191FED05E75D0A17CE7 = {
+			fileRef = 00BBA18BFED05E75D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00BBA192FED05E75D0A17CE7 = {
+			fileRef = 00BBA18CFED05E75D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00BBA193FED060CED0A17CE7 = {
+			isa = PBXFileReference;
+			path = deriveKey.cpp;
+			refType = 4;
+		};
+		00BBA194FED060CED0A17CE7 = {
+			fileRef = 00BBA193FED060CED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00FCF302FF28B8B011CD296C = {
+			isa = PBXFileReference;
+			path = wrapKeyCms.cpp;
+			refType = 4;
+		};
+		00FCF303FF28B8B011CD296C = {
+			fileRef = 00FCF302FF28B8B011CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0144AEB60054261D7F000001 = {
+			isa = PBXFileReference;
+			name = BlockCryptor.h;
+			path = AppleCSP/BlockCryptor.h;
+			refType = 2;
+		};
+		0144AEB70054261D7F000001 = {
+			fileRef = 0144AEB60054261D7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0144AEB80054359B7F000001 = {
+			isa = PBXFileReference;
+			path = BlockCryptor.cpp;
+			refType = 4;
+		};
+		0144AEB90054359B7F000001 = {
+			fileRef = 0144AEB80054359B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		015F469500433E457F000001 = {
+			isa = PBXFileReference;
+			path = FEECSPUtils.h;
+			refType = 4;
+		};
+		015F469600433E457F000001 = {
+			fileRef = 015F469500433E457F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		015F469700433ED37F000001 = {
+			isa = PBXFileReference;
+			path = FEECSPUtils.cpp;
+			refType = 4;
+		};
+		015F469800433ED37F000001 = {
+			fileRef = 015F469700433ED37F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		015F46990044518E7F000001 = {
+			isa = PBXFileReference;
+			name = FEEKeys.h;
+			path = CryptKitCSP/FEEKeys.h;
+			refType = 2;
+		};
+		015F469A0044518E7F000001 = {
+			fileRef = 015F46990044518E7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		015F469B0044580E7F000001 = {
+			isa = PBXFileReference;
+			path = FEEKeys.cpp;
+			refType = 4;
+		};
+		015F469C0044580E7F000001 = {
+			fileRef = 015F469B0044580E7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		015F469D00446C827F000001 = {
+			isa = PBXFileReference;
+			path = CryptKitSpace.h;
+			refType = 4;
+		};
+		015F469E00446C827F000001 = {
+			fileRef = 015F469D00446C827F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01847A450055487B7F000001 = {
+			isa = PBXFileReference;
+			path = FEEAsymmetricContext.h;
+			refType = 4;
+		};
+		01847A460055487B7F000001 = {
+			fileRef = 01847A450055487B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01847A4700554A6C7F000001 = {
+			isa = PBXFileReference;
+			name = FEEAsymmetricContext.cpp;
+			path = CryptKitCSP/FEEAsymmetricContext.cpp;
+			refType = 2;
+		};
+		01847A4800554A6C7F000001 = {
+			fileRef = 01847A4700554A6C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01C17D02FF16DCC911CD283A = {
+			children = (
+				2B8B5BBAFFF3E29A11CD283A,
+			);
+			isa = PBXGroup;
+			name = Frameworks;
+			refType = 4;
+		};
+		023E3603001F8EB211CD283A = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OTHER_LDFLAGS = "\U0001-dylib_file \"$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Security:$(SYMROOT)/Security.framework/Versions/A/Security\"";
+			};
+			isa = PBXBuildStyle;
+			name = "Build Folder";
+		};
+		0806BF29FFD847D411CD296C = {
+			isa = PBXBundleReference;
+			path = AppleCSP.bundle;
+			refType = 3;
+		};
+		0806BF2AFFD847D411CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		0806BF2BFFD847D411CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		09C40943FEAF7DAAD0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleCSP.cpp;
+			refType = 4;
+		};
+		09C40944FEAF7DAAD0A17CE7 = {
+			fileRef = 09C40943FEAF7DAAD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		09C40945FEAF7E09D0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleCSP.h;
+			refType = 4;
+		};
+		09C40946FEAF7E09D0A17CE7 = {
+			fileRef = 09C40945FEAF7E09D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0D5C9DCDFEAFAC09D0A17CE7 = {
+			isa = PBXFileReference;
+			name = debugging.c;
+			path = AppleCSP/debugging.c;
+			refType = 2;
+		};
+		0D5C9DCEFEAFAC09D0A17CE7 = {
+			isa = PBXFileReference;
+			name = debugging.h;
+			path = AppleCSP/debugging.h;
+			refType = 2;
+		};
+		0D5C9DCFFEAFAC09D0A17CE7 = {
+			fileRef = 0D5C9DCEFEAFAC09D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0D5C9DD0FEAFAC09D0A17CE7 = {
+			fileRef = 0D5C9DCDFEAFAC09D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0FD07C9DFE8A174411CD283A = {
+			buildStyles = (
+				0806BF2AFFD847D411CD296C,
+				0806BF2BFFD847D411CD296C,
+				023E3603001F8EB211CD283A,
+			);
+			isa = PBXProject;
+			mainGroup = 0FD07C9EFE8A174411CD283A;
+			productRefGroup = 0FD07CBFFE8A1A0011CD283A;
+			projectDirPath = .;
+			targets = (
+				0FD07C9FFE8A17DE11CD283A,
+				6D8679A7FE9E75CF11CD296C,
+				22FA741EFE8A468311CD283A,
+				22FA7434FE8A468311CD283A,
+			);
+		};
+		0FD07C9EFE8A174411CD283A = {
+			children = (
+				22FA7442FE8A470511CD283A,
+				22FA7784FE8A470511CD283A,
+				22FA7799FE8A470511CD283A,
+				22FA77F8FE8A470511CD283A,
+				17CFEF85FF8A5A84D0A17CE7,
+				01C17D02FF16DCC911CD283A,
+				0FD07CBFFE8A1A0011CD283A,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		0FD07C9FFE8A17DE11CD283A = {
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = world;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				1118B012FE8AE31F11CD296C,
+			);
+			isa = PBXAggregateTarget;
+			name = world;
+			productInstallPath = /;
+			productName = world;
+			shouldUseHeadermap = 0;
+		};
+		0FD07CBFFE8A1A0011CD283A = {
+			children = (
+				0806BF29FFD847D411CD296C,
+			);
+			isa = PBXGroup;
+			name = Products;
+			path = "";
+			refType = 3;
+		};
+		1118B012FE8AE31F11CD296C = {
+			isa = PBXTargetDependency;
+			target = 22FA741EFE8A468311CD283A;
+		};
+		17CFEF85FF8A5A84D0A17CE7 = {
+			children = (
+				1972C1CB00430D427F000001,
+				1972C1CC00430D427F000001,
+				1972C1C900430C1C7F000001,
+				1972C1A3004307DF7F000001,
+				1972C19B0043075C7F000001,
+				1972C19C0043075C7F000001,
+				1972C19D0043075C7F000001,
+				1972C19E0043075C7F000001,
+			);
+			isa = PBXGroup;
+			name = AES;
+			refType = 4;
+		};
+		1871086FFF1549F211CD283A = {
+			isa = PBXLibraryReference;
+			name = libCryptKit.a;
+			path = /MacOS9/Projects/build/libCryptKit.a;
+			refType = 0;
+		};
+		1972C192004306477F000001 = {
+			isa = PBXTargetDependency;
+			target = 6D8679A7FE9E75CF11CD296C;
+		};
+		1972C19B0043075C7F000001 = {
+			isa = PBXFileReference;
+			name = "rijndael-alg-ref.c";
+			path = "AES/rijndael-alg-ref.c";
+			refType = 4;
+		};
+		1972C19C0043075C7F000001 = {
+			isa = PBXFileReference;
+			name = "rijndael-alg-ref.h";
+			path = "AES/rijndael-alg-ref.h";
+			refType = 4;
+		};
+		1972C19D0043075C7F000001 = {
+			isa = PBXFileReference;
+			name = rijndaelApi.c;
+			path = AES/rijndaelApi.c;
+			refType = 4;
+		};
+		1972C19E0043075C7F000001 = {
+			isa = PBXFileReference;
+			name = rijndaelApi.h;
+			path = AES/rijndaelApi.h;
+			refType = 4;
+		};
+		1972C19F0043075C7F000001 = {
+			fileRef = 1972C19C0043075C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1A00043075C7F000001 = {
+			fileRef = 1972C19E0043075C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1A10043075C7F000001 = {
+			fileRef = 1972C19B0043075C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1A20043075C7F000001 = {
+			fileRef = 1972C19D0043075C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1A3004307DF7F000001 = {
+			isa = PBXFileReference;
+			name = "boxes-ref.h";
+			path = "AES/boxes-ref.h";
+			refType = 4;
+		};
+		1972C1A4004307DF7F000001 = {
+			fileRef = 1972C1A3004307DF7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1A5004308417F000001 = {
+			isa = PBXFileReference;
+			path = cryptkitcsp.cpp;
+			refType = 4;
+		};
+		1972C1A6004308417F000001 = {
+			isa = PBXFileReference;
+			path = cryptkitcsp.h;
+			refType = 4;
+		};
+		1972C1A7004308417F000001 = {
+			isa = PBXFileReference;
+			path = DigestContext.cpp;
+			refType = 4;
+		};
+		1972C1A8004308417F000001 = {
+			isa = PBXFileReference;
+			path = DigestContext.h;
+			refType = 4;
+		};
+		1972C1A9004308417F000001 = {
+			isa = PBXFileReference;
+			path = DigestObject.cpp;
+			refType = 4;
+		};
+		1972C1AA004308417F000001 = {
+			isa = PBXFileReference;
+			path = DigestObject.h;
+			refType = 4;
+		};
+		1972C1AB004308417F000001 = {
+			fileRef = 1972C1A6004308417F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1AC004308417F000001 = {
+			fileRef = 1972C1A8004308417F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1AD004308417F000001 = {
+			fileRef = 1972C1AA004308417F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1AE004308417F000001 = {
+			fileRef = 1972C1A5004308417F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1AF004308417F000001 = {
+			fileRef = 1972C1A7004308417F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1B0004308417F000001 = {
+			fileRef = 1972C1A9004308417F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1B1004308907F000001 = {
+			isa = PBXFileReference;
+			path = algmaker.cpp;
+			refType = 4;
+		};
+		1972C1B2004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsafeAsymmetric.cpp;
+			refType = 4;
+		};
+		1972C1B3004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsafeContext.cpp;
+			refType = 4;
+		};
+		1972C1B4004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsafecsp.h;
+			refType = 4;
+		};
+		1972C1B5004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsafecspi.h;
+			refType = 4;
+		};
+		1972C1B6004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsafeKeyGen.cpp;
+			refType = 4;
+		};
+		1972C1B7004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsafePKCS1.cpp;
+			refType = 4;
+		};
+		1972C1B8004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsafePKCS1.h;
+			refType = 4;
+		};
+		1972C1B9004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsafeSymmetric.cpp;
+			refType = 4;
+		};
+		1972C1BA004308907F000001 = {
+			isa = PBXFileReference;
+			path = bsobjects.h;
+			refType = 4;
+		};
+		1972C1BB004308907F000001 = {
+			isa = PBXFileReference;
+			path = memory.cpp;
+			refType = 4;
+		};
+		1972C1BC004308907F000001 = {
+			isa = PBXFileReference;
+			path = miscalgorithms.cpp;
+			refType = 4;
+		};
+		1972C1BD004308907F000001 = {
+			fileRef = 1972C1B4004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1BE004308907F000001 = {
+			fileRef = 1972C1B5004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1BF004308907F000001 = {
+			fileRef = 1972C1B8004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C0004308907F000001 = {
+			fileRef = 1972C1BA004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C1004308907F000001 = {
+			fileRef = 1972C1B1004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C2004308907F000001 = {
+			fileRef = 1972C1B2004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C3004308907F000001 = {
+			fileRef = 1972C1B3004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C4004308907F000001 = {
+			fileRef = 1972C1B6004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C5004308907F000001 = {
+			fileRef = 1972C1B7004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C6004308907F000001 = {
+			fileRef = 1972C1B9004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C7004308907F000001 = {
+			fileRef = 1972C1BB004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C8004308907F000001 = {
+			fileRef = 1972C1BC004308907F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1C900430C1C7F000001 = {
+			isa = PBXFileReference;
+			name = aescsp.cpp;
+			path = AES/aescsp.cpp;
+			refType = 4;
+		};
+		1972C1CA00430C1C7F000001 = {
+			fileRef = 1972C1C900430C1C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1CB00430D427F000001 = {
+			isa = PBXFileReference;
+			name = aescsp.h;
+			path = AES/aescsp.h;
+			refType = 4;
+		};
+		1972C1CC00430D427F000001 = {
+			isa = PBXFileReference;
+			name = aescspi.h;
+			path = AES/aescspi.h;
+			refType = 4;
+		};
+		1972C1CD00430D427F000001 = {
+			fileRef = 1972C1CB00430D427F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1CE00430D427F000001 = {
+			fileRef = 1972C1CC00430D427F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1CF004320A27F000001 = {
+			isa = PBXFileReference;
+			path = FEESignatureObject.h;
+			refType = 4;
+		};
+		1972C1D0004320A27F000001 = {
+			fileRef = 1972C1CF004320A27F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1D2004324407F000001 = {
+			isa = PBXFileReference;
+			path = FEESignatureObject.cpp;
+			refType = 4;
+		};
+		1972C1D3004324407F000001 = {
+			fileRef = 1972C1D2004324407F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1D400432DF47F000001 = {
+			isa = PBXFileReference;
+			name = FEESignatureContext.h;
+			path = CryptKitCSP/FEESignatureContext.h;
+			refType = 2;
+		};
+		1972C1D500432DF47F000001 = {
+			fileRef = 1972C1D400432DF47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1972C1D6004330C77F000001 = {
+			isa = PBXFileReference;
+			name = FEESignatureContext.cpp;
+			path = CryptKitCSP/FEESignatureContext.cpp;
+			refType = 2;
+		};
+		1972C1D7004330C77F000001 = {
+			fileRef = 1972C1D6004330C77F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1D96D506FEB620B6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = AppleCSPContext.h;
+			path = AppleCSP/AppleCSPContext.h;
+			refType = 2;
+		};
+		1D96D507FEB620B6D0A17CE7 = {
+			fileRef = 1D96D506FEB620B6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1D96D50FFEB63683D0A17CE7 = {
+			isa = PBXFileReference;
+			name = AppleCSPContext.cpp;
+			path = AppleCSP/AppleCSPContext.cpp;
+			refType = 2;
+		};
+		1D96D510FEB63683D0A17CE7 = {
+			fileRef = 1D96D50FFEB63683D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		1DF71D5FFF31105711CD283A = {
+			isa = PBXFileReference;
+			path = cssmplugin.exp;
+			refType = 4;
+		};
+		1DF71D60FF31105711CD283A = {
+			fileRef = 1DF71D5FFF31105711CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA741EFE8A468311CD283A = {
+			buildPhases = (
+				22FA741FFE8A468311CD283A,
+				22FA7420FE8A468311CD283A,
+				22FA7421FE8A468311CD283A,
+				22FA7422FE8A468311CD283A,
+				22FA7423FE8A468311CD283A,
+			);
+			buildSettings = {
+				DEPLOYMENT_OPTIMIZATION_CFLAGS = "-O2";
+				EXPORTED_SYMBOLS_FILE = AppleCSP/cssmplugin.exp;
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/BSafe.framework/Headers\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/BSafe.framework/Headers\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "-O1";
+				OTHER_CFLAGS = "-pipe -DVDADER_RULES -DALLOW_ZERO_PASSWORD";
+				OTHER_LDFLAGS = "-bundle -undefined error";
+				OTHER_REZFLAGS = "";
+				PRELINK_FLAGS = "-L$(SYMROOT)";
+				PRELINK_LIBS = "-lBSafe -lCryptKit -lstdc++";
+				PRODUCT_NAME = AppleCSP;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-format";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				1972C192004306477F000001,
+			);
+			isa = PBXBundleTarget;
+			name = AppleCSP;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Security";
+			productName = AppleCSP;
+			productReference = 0806BF29FFD847D411CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AppleCSP</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.applecsp</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>AppleCSP</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>AppleCSP 1.0</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		22FA741FFE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				09C40946FEAF7E09D0A17CE7,
+				0D5C9DCFFEAFAC09D0A17CE7,
+				1D96D507FEB620B6D0A17CE7,
+				27CADDA2FEB8CBB7D0A17CE7,
+				00B9571AFEBDEC98D0A17CE7,
+				00B9571CFEBDF916D0A17CE7,
+				00BBA18FFED05E75D0A17CE7,
+				00BBA190FED05E75D0A17CE7,
+				1972C1CD00430D427F000001,
+				1972C1CE00430D427F000001,
+				1972C19F0043075C7F000001,
+				1972C1A00043075C7F000001,
+				1972C1A4004307DF7F000001,
+				1972C1AB004308417F000001,
+				1972C1AC004308417F000001,
+				1972C1AD004308417F000001,
+				1972C1BD004308907F000001,
+				1972C1BE004308907F000001,
+				1972C1BF004308907F000001,
+				1972C1C0004308907F000001,
+				1972C1D0004320A27F000001,
+				1972C1D500432DF47F000001,
+				015F469600433E457F000001,
+				015F469A0044518E7F000001,
+				015F469E00446C827F000001,
+				0144AEB70054261D7F000001,
+				01847A460055487B7F000001,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		22FA7420FE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		22FA7421FE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				09C40944FEAF7DAAD0A17CE7,
+				0D5C9DD0FEAFAC09D0A17CE7,
+				1D96D510FEB63683D0A17CE7,
+				00B95718FEBDE93ED0A17CE7,
+				00B7C431FEC78562D0A17CE7,
+				00BBA191FED05E75D0A17CE7,
+				00BBA192FED05E75D0A17CE7,
+				00BBA194FED060CED0A17CE7,
+				00FCF303FF28B8B011CD296C,
+				1DF71D60FF31105711CD283A,
+				1972C1CA00430C1C7F000001,
+				1972C1A10043075C7F000001,
+				1972C1A20043075C7F000001,
+				1972C1AE004308417F000001,
+				1972C1AF004308417F000001,
+				1972C1B0004308417F000001,
+				1972C1C1004308907F000001,
+				1972C1C2004308907F000001,
+				1972C1C3004308907F000001,
+				1972C1C4004308907F000001,
+				1972C1C5004308907F000001,
+				1972C1C6004308907F000001,
+				1972C1C7004308907F000001,
+				1972C1C8004308907F000001,
+				1972C1D3004324407F000001,
+				1972C1D7004330C77F000001,
+				015F469800433ED37F000001,
+				015F469C0044580E7F000001,
+				0144AEB90054359B7F000001,
+				01847A4800554A6C7F000001,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		22FA7422FE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				2B8B5BBBFFF3E29A11CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		22FA7423FE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		22FA7434FE8A468311CD283A = {
+			buildPhases = (
+				22FA7435FE8A468311CD283A,
+				22FA7436FE8A468311CD283A,
+				22FA7437FE8A468311CD283A,
+				22FA7438FE8A468311CD283A,
+			);
+			buildSettings = {
+				DEPLOYMENT_OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"";
+				INSTALL_PATH = /usr/local/lib;
+				LIBRARY_SEARCH_PATHS = "";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				OTHER_CFLAGS = "-pipe";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libCryptKit.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLibraryTarget;
+			name = CryptKit;
+			productInstallPath = /usr/local/lib;
+			productName = libCryptKit.a;
+			productReference = 1871086FFF1549F211CD283A;
+			shouldUseHeadermap = 1;
+		};
+		22FA7435FE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				22FA7B38FE8A470611CD283A,
+				22FA7B39FE8A470611CD283A,
+				22FA7B3AFE8A470611CD283A,
+				22FA7B3BFE8A470611CD283A,
+				22FA7B3CFE8A470611CD283A,
+				22FA7B3DFE8A470611CD283A,
+				22FA7B3FFE8A470611CD283A,
+				22FA7B40FE8A470611CD283A,
+				22FA7B41FE8A470611CD283A,
+				22FA7B42FE8A470611CD283A,
+				22FA7B43FE8A470611CD283A,
+				22FA7B44FE8A470611CD283A,
+				22FA7B45FE8A470611CD283A,
+				22FA7B46FE8A470611CD283A,
+				22FA7B47FE8A470611CD283A,
+				22FA7B48FE8A470611CD283A,
+				22FA7B49FE8A470611CD283A,
+				22FA7B4AFE8A470611CD283A,
+				22FA7B4BFE8A470611CD283A,
+				22FA7B4CFE8A470611CD283A,
+				22FA7B4DFE8A470611CD283A,
+				22FA7B4EFE8A470611CD283A,
+				22FA7B4FFE8A470611CD283A,
+				22FA7B50FE8A470611CD283A,
+				22FA7B51FE8A470611CD283A,
+				22FA7B52FE8A470611CD283A,
+				22FA7B53FE8A470611CD283A,
+				22FA7B54FE8A470611CD283A,
+				22FA7B55FE8A470611CD283A,
+				22FA7B56FE8A470611CD283A,
+				22FA7B57FE8A470611CD283A,
+				22FA7B58FE8A470611CD283A,
+				22FA7B59FE8A470611CD283A,
+				22FA7B5AFE8A470611CD283A,
+				22FA7B63FE8A470611CD283A,
+				22FA7B64FE8A470611CD283A,
+				22FA7B65FE8A470611CD283A,
+				22FA7B66FE8A470611CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		22FA7436FE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				22FA7B67FE8A470611CD283A,
+				22FA7B68FE8A470611CD283A,
+				22FA7B69FE8A470611CD283A,
+				22FA7B6AFE8A470611CD283A,
+				22FA7B6BFE8A470611CD283A,
+				22FA7B6CFE8A470611CD283A,
+				22FA7B6DFE8A470611CD283A,
+				22FA7B6EFE8A470611CD283A,
+				22FA7B70FE8A470611CD283A,
+				22FA7B71FE8A470611CD283A,
+				22FA7B72FE8A470611CD283A,
+				22FA7B73FE8A470611CD283A,
+				22FA7B74FE8A470611CD283A,
+				22FA7B75FE8A470611CD283A,
+				22FA7B76FE8A470611CD283A,
+				22FA7B77FE8A470611CD283A,
+				22FA7B78FE8A470611CD283A,
+				22FA7B79FE8A470611CD283A,
+				22FA7B7AFE8A470611CD283A,
+				22FA7B7CFE8A470611CD283A,
+				22FA7B7DFE8A470611CD283A,
+				22FA7B7EFE8A470611CD283A,
+				22FA7B85FE8A470611CD283A,
+				22FA7B86FE8A470611CD283A,
+				22FA7B87FE8A470611CD283A,
+				22FA7B88FE8A470611CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		22FA7437FE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		22FA7438FE8A468311CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		22FA7442FE8A470511CD283A = {
+			children = (
+				09C40943FEAF7DAAD0A17CE7,
+				1D96D50FFEB63683D0A17CE7,
+				00B95717FEBDE93ED0A17CE7,
+				0144AEB80054359B7F000001,
+				0D5C9DCDFEAFAC09D0A17CE7,
+				00BBA193FED060CED0A17CE7,
+				00BBA18BFED05E75D0A17CE7,
+				00BBA18CFED05E75D0A17CE7,
+				00B7C42CFEC78220D0A17CE7,
+				00B7C430FEC78562D0A17CE7,
+				00FCF302FF28B8B011CD296C,
+				09C40945FEAF7E09D0A17CE7,
+				1D96D506FEB620B6D0A17CE7,
+				27CADDA1FEB8CBB7D0A17CE7,
+				00B95719FEBDEC98D0A17CE7,
+				00B9571BFEBDF916D0A17CE7,
+				0144AEB60054261D7F000001,
+				0D5C9DCEFEAFAC09D0A17CE7,
+				00BBA18DFED05E75D0A17CE7,
+				00BBA18EFED05E75D0A17CE7,
+				00B7C42EFEC7824FD0A17CE7,
+				1DF71D5FFF31105711CD283A,
+			);
+			isa = PBXGroup;
+			path = AppleCSP;
+			refType = 4;
+		};
+		22FA7784FE8A470511CD283A = {
+			children = (
+				1972C1B1004308907F000001,
+				1972C1B2004308907F000001,
+				1972C1B3004308907F000001,
+				1972C1B4004308907F000001,
+				1972C1B5004308907F000001,
+				1972C1B6004308907F000001,
+				1972C1B7004308907F000001,
+				1972C1B8004308907F000001,
+				1972C1B9004308907F000001,
+				1972C1BA004308907F000001,
+				1972C1BB004308907F000001,
+				1972C1BC004308907F000001,
+			);
+			isa = PBXGroup;
+			path = BSafeCSP;
+			refType = 4;
+		};
+		22FA7799FE8A470511CD283A = {
+			children = (
+				22FA779CFE8A470511CD283A,
+				22FA779DFE8A470511CD283A,
+				22FA77A0FE8A470511CD283A,
+				22FA77A1FE8A470511CD283A,
+				22FA77A2FE8A470511CD283A,
+				22FA77A3FE8A470511CD283A,
+				22FA77A4FE8A470511CD283A,
+				22FA77A5FE8A470511CD283A,
+				22FA77A6FE8A470511CD283A,
+				22FA77AAFE8A470511CD283A,
+				22FA77ABFE8A470511CD283A,
+				22FA77ACFE8A470511CD283A,
+				22FA77ADFE8A470511CD283A,
+				22FA77AEFE8A470511CD283A,
+				22FA77AFFE8A470511CD283A,
+				22FA77B0FE8A470511CD283A,
+				22FA77B1FE8A470511CD283A,
+				22FA77B2FE8A470511CD283A,
+				22FA77B3FE8A470511CD283A,
+				22FA77B4FE8A470511CD283A,
+				22FA77B5FE8A470511CD283A,
+				22FA77B6FE8A470511CD283A,
+				22FA77B8FE8A470511CD283A,
+				22FA77B9FE8A470511CD283A,
+				22FA77BAFE8A470511CD283A,
+				22FA77BBFE8A470511CD283A,
+				22FA77BCFE8A470511CD283A,
+				22FA77BDFE8A470511CD283A,
+				22FA77BEFE8A470511CD283A,
+				22FA77BFFE8A470511CD283A,
+				22FA77C0FE8A470511CD283A,
+				22FA77C1FE8A470511CD283A,
+				22FA77C2FE8A470511CD283A,
+				22FA77C3FE8A470511CD283A,
+				22FA77C4FE8A470511CD283A,
+				22FA77C5FE8A470511CD283A,
+				22FA77C6FE8A470511CD283A,
+				22FA77C7FE8A470511CD283A,
+				22FA77C8FE8A470511CD283A,
+				22FA77C9FE8A470511CD283A,
+				22FA77CAFE8A470511CD283A,
+				22FA77CBFE8A470511CD283A,
+				22FA77CCFE8A470511CD283A,
+				22FA77CDFE8A470511CD283A,
+				22FA77CEFE8A470511CD283A,
+				22FA77CFFE8A470511CD283A,
+				22FA77D0FE8A470511CD283A,
+				22FA77D1FE8A470511CD283A,
+				22FA77D2FE8A470511CD283A,
+				22FA77D3FE8A470511CD283A,
+				22FA77D4FE8A470511CD283A,
+				22FA77D5FE8A470511CD283A,
+				22FA77D6FE8A470511CD283A,
+				22FA77D7FE8A470511CD283A,
+				22FA77D8FE8A470511CD283A,
+				22FA77D9FE8A470511CD283A,
+				22FA77DCFE8A470511CD283A,
+				22FA77DDFE8A470511CD283A,
+				22FA77ECFE8A470511CD283A,
+				22FA77EDFE8A470511CD283A,
+				22FA77F0FE8A470511CD283A,
+				22FA77F1FE8A470511CD283A,
+				22FA77F2FE8A470511CD283A,
+				22FA77F3FE8A470511CD283A,
+				22FA77F6FE8A470511CD283A,
+				22FA77F7FE8A470511CD283A,
+			);
+			isa = PBXGroup;
+			path = CryptKit;
+			refType = 4;
+		};
+		22FA779CFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = byteRep.c;
+			refType = 4;
+		};
+		22FA779DFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = byteRep.h;
+			refType = 4;
+		};
+		22FA77A0FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = CipherFileDES.c;
+			refType = 4;
+		};
+		22FA77A1FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = CipherFileDES.h;
+			refType = 4;
+		};
+		22FA77A2FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = CipherFileFEED.c;
+			refType = 4;
+		};
+		22FA77A3FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = CipherFileFEED.h;
+			refType = 4;
+		};
+		22FA77A4FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = CipherFileTypes.h;
+			refType = 4;
+		};
+		22FA77A5FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = config.h;
+			refType = 4;
+		};
+		22FA77A6FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = Crypt.h;
+			refType = 4;
+		};
+		22FA77AAFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = curveParams.c;
+			refType = 4;
+		};
+		22FA77ABFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = curveParams.h;
+			refType = 4;
+		};
+		22FA77ACFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = DES.c;
+			refType = 4;
+		};
+		22FA77ADFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = DES.h;
+			refType = 4;
+		};
+		22FA77AEFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = ECDSA_Profile.h;
+			refType = 4;
+		};
+		22FA77AFFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = ECDSA_Verify_Prefix.h;
+			refType = 4;
+		};
+		22FA77B0FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = elliptic.c;
+			refType = 4;
+		};
+		22FA77B1FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = elliptic.h;
+			refType = 4;
+		};
+		22FA77B2FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = ellipticMeasure.h;
+			refType = 4;
+		};
+		22FA77B3FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = ellipticProj.c;
+			refType = 4;
+		};
+		22FA77B4FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = ellipticProj.h;
+			refType = 4;
+		};
+		22FA77B5FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = enc64.c;
+			refType = 4;
+		};
+		22FA77B6FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = enc64.h;
+			refType = 4;
+		};
+		22FA77B8FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = falloc.c;
+			refType = 4;
+		};
+		22FA77B9FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = falloc.h;
+			refType = 4;
+		};
+		22FA77BAFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeCipherFile.c;
+			refType = 4;
+		};
+		22FA77BBFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeCipherFile.h;
+			refType = 4;
+		};
+		22FA77BCFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeCipherFileAtom.c;
+			refType = 4;
+		};
+		22FA77BDFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeDebug.h;
+			refType = 4;
+		};
+		22FA77BEFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeDES.c;
+			refType = 4;
+		};
+		22FA77BFFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeDES.h;
+			refType = 4;
+		};
+		22FA77C0FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeDigitalSignature.c;
+			refType = 4;
+		};
+		22FA77C1FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeDigitalSignature.h;
+			refType = 4;
+		};
+		22FA77C2FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeECDSA.c;
+			refType = 4;
+		};
+		22FA77C3FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeECDSA.h;
+			refType = 4;
+		};
+		22FA77C4FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeFEED.c;
+			refType = 4;
+		};
+		22FA77C5FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeFEED.h;
+			refType = 4;
+		};
+		22FA77C6FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeFEEDExp.c;
+			refType = 4;
+		};
+		22FA77C7FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeFEEDExp.h;
+			refType = 4;
+		};
+		22FA77C8FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeFunctions.h;
+			refType = 4;
+		};
+		22FA77C9FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeHash.c;
+			refType = 4;
+		};
+		22FA77CAFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeHash.h;
+			refType = 4;
+		};
+		22FA77CBFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feePublicKey.c;
+			refType = 4;
+		};
+		22FA77CCFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feePublicKey.h;
+			refType = 4;
+		};
+		22FA77CDFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feePublicKeyPrivate.h;
+			refType = 4;
+		};
+		22FA77CEFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeRandom.c;
+			refType = 4;
+		};
+		22FA77CFFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeRandom.h;
+			refType = 4;
+		};
+		22FA77D0FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = feeTypes.h;
+			refType = 4;
+		};
+		22FA77D1FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantFFT.c;
+			refType = 4;
+		};
+		22FA77D2FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantIntegers.c;
+			refType = 4;
+		};
+		22FA77D3FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantIntegers.h;
+			refType = 4;
+		};
+		22FA77D4FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantPort_Generic.h;
+			refType = 4;
+		};
+		22FA77D5FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantPort_i486.h;
+			refType = 4;
+		};
+		22FA77D6FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantPort_i486.s;
+			refType = 4;
+		};
+		22FA77D7FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantPort_PPC.c;
+			refType = 4;
+		};
+		22FA77D8FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantPort_PPC.h;
+			refType = 4;
+		};
+		22FA77D9FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = giantPortCommon.h;
+			refType = 4;
+		};
+		22FA77DCFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = MD5.c;
+			refType = 4;
+		};
+		22FA77DDFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = MD5.h;
+			refType = 4;
+		};
+		22FA77ECFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = platform.c;
+			refType = 4;
+		};
+		22FA77EDFE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = platform.h;
+			refType = 4;
+		};
+		22FA77F0FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = SHA1.c;
+			refType = 4;
+		};
+		22FA77F1FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = SHA1.h;
+			refType = 4;
+		};
+		22FA77F2FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = SHA1_priv.c;
+			refType = 4;
+		};
+		22FA77F3FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = SHA1_priv.h;
+			refType = 4;
+		};
+		22FA77F6FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = utilities.c;
+			refType = 4;
+		};
+		22FA77F7FE8A470511CD283A = {
+			isa = PBXFileReference;
+			path = utilities.h;
+			refType = 4;
+		};
+		22FA77F8FE8A470511CD283A = {
+			children = (
+				1972C1A5004308417F000001,
+				1972C1A6004308417F000001,
+				1972C1A7004308417F000001,
+				1972C1A8004308417F000001,
+				1972C1A9004308417F000001,
+				1972C1AA004308417F000001,
+				015F469B0044580E7F000001,
+				015F46990044518E7F000001,
+				01847A4700554A6C7F000001,
+				01847A450055487B7F000001,
+				1972C1D6004330C77F000001,
+				1972C1D400432DF47F000001,
+				1972C1CF004320A27F000001,
+				1972C1D2004324407F000001,
+				015F469500433E457F000001,
+				015F469700433ED37F000001,
+				015F469D00446C827F000001,
+			);
+			isa = PBXGroup;
+			path = CryptKitCSP;
+			refType = 4;
+		};
+		22FA7B38FE8A470611CD283A = {
+			fileRef = 22FA779DFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B39FE8A470611CD283A = {
+			fileRef = 22FA77A1FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B3AFE8A470611CD283A = {
+			fileRef = 22FA77A3FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B3BFE8A470611CD283A = {
+			fileRef = 22FA77A4FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B3CFE8A470611CD283A = {
+			fileRef = 22FA77A5FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B3DFE8A470611CD283A = {
+			fileRef = 22FA77A6FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B3FFE8A470611CD283A = {
+			fileRef = 22FA77ABFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B40FE8A470611CD283A = {
+			fileRef = 22FA77ADFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B41FE8A470611CD283A = {
+			fileRef = 22FA77AEFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B42FE8A470611CD283A = {
+			fileRef = 22FA77AFFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B43FE8A470611CD283A = {
+			fileRef = 22FA77B1FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B44FE8A470611CD283A = {
+			fileRef = 22FA77B2FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B45FE8A470611CD283A = {
+			fileRef = 22FA77B4FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B46FE8A470611CD283A = {
+			fileRef = 22FA77B6FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B47FE8A470611CD283A = {
+			fileRef = 22FA77B9FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B48FE8A470611CD283A = {
+			fileRef = 22FA77BBFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B49FE8A470611CD283A = {
+			fileRef = 22FA77BDFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B4AFE8A470611CD283A = {
+			fileRef = 22FA77BFFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B4BFE8A470611CD283A = {
+			fileRef = 22FA77C1FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B4CFE8A470611CD283A = {
+			fileRef = 22FA77C3FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B4DFE8A470611CD283A = {
+			fileRef = 22FA77C5FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B4EFE8A470611CD283A = {
+			fileRef = 22FA77C7FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B4FFE8A470611CD283A = {
+			fileRef = 22FA77C8FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B50FE8A470611CD283A = {
+			fileRef = 22FA77CAFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B51FE8A470611CD283A = {
+			fileRef = 22FA77CCFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B52FE8A470611CD283A = {
+			fileRef = 22FA77CDFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B53FE8A470611CD283A = {
+			fileRef = 22FA77CFFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B54FE8A470611CD283A = {
+			fileRef = 22FA77D0FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B55FE8A470611CD283A = {
+			fileRef = 22FA77D3FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B56FE8A470611CD283A = {
+			fileRef = 22FA77D4FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B57FE8A470611CD283A = {
+			fileRef = 22FA77D5FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B58FE8A470611CD283A = {
+			fileRef = 22FA77D8FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B59FE8A470611CD283A = {
+			fileRef = 22FA77D9FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B5AFE8A470611CD283A = {
+			fileRef = 22FA77DDFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B63FE8A470611CD283A = {
+			fileRef = 22FA77EDFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B64FE8A470611CD283A = {
+			fileRef = 22FA77F1FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B65FE8A470611CD283A = {
+			fileRef = 22FA77F3FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B66FE8A470611CD283A = {
+			fileRef = 22FA77F7FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		22FA7B67FE8A470611CD283A = {
+			fileRef = 22FA779CFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B68FE8A470611CD283A = {
+			fileRef = 22FA77A0FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B69FE8A470611CD283A = {
+			fileRef = 22FA77A2FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B6AFE8A470611CD283A = {
+			fileRef = 22FA77AAFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B6BFE8A470611CD283A = {
+			fileRef = 22FA77ACFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B6CFE8A470611CD283A = {
+			fileRef = 22FA77B0FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B6DFE8A470611CD283A = {
+			fileRef = 22FA77B3FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B6EFE8A470611CD283A = {
+			fileRef = 22FA77B5FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B70FE8A470611CD283A = {
+			fileRef = 22FA77B8FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B71FE8A470611CD283A = {
+			fileRef = 22FA77BAFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B72FE8A470611CD283A = {
+			fileRef = 22FA77BCFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B73FE8A470611CD283A = {
+			fileRef = 22FA77BEFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B74FE8A470611CD283A = {
+			fileRef = 22FA77C0FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B75FE8A470611CD283A = {
+			fileRef = 22FA77C2FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B76FE8A470611CD283A = {
+			fileRef = 22FA77C4FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B77FE8A470611CD283A = {
+			fileRef = 22FA77C6FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B78FE8A470611CD283A = {
+			fileRef = 22FA77C9FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B79FE8A470611CD283A = {
+			fileRef = 22FA77CBFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B7AFE8A470611CD283A = {
+			fileRef = 22FA77CEFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B7CFE8A470611CD283A = {
+			fileRef = 22FA77D2FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B7DFE8A470611CD283A = {
+			fileRef = 22FA77D7FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B7EFE8A470611CD283A = {
+			fileRef = 22FA77DCFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B85FE8A470611CD283A = {
+			fileRef = 22FA77ECFE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B86FE8A470611CD283A = {
+			fileRef = 22FA77F0FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B87FE8A470611CD283A = {
+			fileRef = 22FA77F2FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		22FA7B88FE8A470611CD283A = {
+			fileRef = 22FA77F6FE8A470511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		27CADDA1FEB8CBB7D0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleCSPSession.h;
+			refType = 4;
+		};
+		27CADDA2FEB8CBB7D0A17CE7 = {
+			fileRef = 27CADDA1FEB8CBB7D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2B8B5BBAFFF3E29A11CD283A = {
+			isa = PBXFrameworkReference;
+			path = Security.framework;
+			refType = 3;
+		};
+		2B8B5BBBFFF3E29A11CD283A = {
+			fileRef = 2B8B5BBAFFF3E29A11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		6D8679A7FE9E75CF11CD296C = {
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = Libraries;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				6D8679A9FE9E75CF11CD296C,
+			);
+			isa = PBXAggregateTarget;
+			name = Libraries;
+			productInstallPath = /;
+			productName = Libraries;
+			shouldUseHeadermap = 0;
+		};
+		6D8679A9FE9E75CF11CD296C = {
+			isa = PBXTargetDependency;
+			target = 22FA7434FE8A468311CD283A;
+		};
+	};
+	rootObject = 0FD07C9DFE8A174411CD283A;
+}
diff --git a/AppleCSP/AppleCSP/.cvsignore b/AppleCSP/AppleCSP/.cvsignore
new file mode 100644
index 00000000..abaf517e
--- /dev/null
+++ b/AppleCSP/AppleCSP/.cvsignore
@@ -0,0 +1 @@
+rotty?Data
diff --git a/AppleCSP/AppleCSP/AppleCSP.cpp b/AppleCSP/AppleCSP/AppleCSP.cpp
new file mode 100644
index 00000000..7dfa2fbf
--- /dev/null
+++ b/AppleCSP/AppleCSP/AppleCSP.cpp
@@ -0,0 +1,684 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleCSP.cpp - top-level plugin and session implementation 
+//
+#include "AppleCSP.h"
+#include "AppleCSPSession.h"
+#include "AppleCSPUtils.h"
+#include <stdio.h> 
+#include "cspdebugging.h" 
+#include <Security/CSPsession.h>
+#include <Security/cssmalloc.h>
+#ifdef	BSAFE_CSP_ENABLE
+#include <BSafeCSP/bsafecsp.h>
+#include <BSafeCSP/bsafecspi.h>
+#endif
+#ifdef	CRYPTKIT_CSP_ENABLE
+#include <CryptKitCSP/cryptkitcsp.h>
+#include <CryptKitCSP/FEEKeys.h>
+#endif
+#include <MiscCSPAlgs/miscAlgFactory.h> 
+#ifdef	ASC_CSP_ENABLE
+#include <ComCryption/ascFactory.h>
+#endif
+#include <RSA_DSA/RSA_DSA_csp.h>
+#include <RSA_DSA/RSA_DSA_keys.h>
+#include "YarrowConnection.h"
+
+/* 
+ * For debugging, we allow use of FEE PRNG when Yarrow is not available
+ * (i.e., no SecurityServer is running).
+ */
+#ifdef	NDEBUG
+#define CSP_ALLOW_FEE_RNG		0
+#else
+#ifdef	CRYPTKIT_CSP_ENABLE
+#define CSP_ALLOW_FEE_RNG		1
+#else
+#define CSP_ALLOW_FEE_RNG		0
+#endif
+#endif
+
+
+//
+// Make and break the plugin object
+//
+AppleCSPPlugin::AppleCSPPlugin() :
+	normAllocator(CssmAllocator::standard(CssmAllocator::normal)),
+	privAllocator(CssmAllocator::standard(CssmAllocator::sensitive)),
+	#ifdef	BSAFE_CSP_ENABLE
+	bSafe4Factory(new BSafeFactory(&normAllocator, &privAllocator)),
+	#endif
+	#ifdef	CRYPTKIT_CSP_ENABLE
+	cryptKitFactory(new CryptKitFactory(&normAllocator, &privAllocator)),
+	#endif
+	miscAlgFactory(new MiscAlgFactory(&normAllocator, &privAllocator)),
+	#ifdef	ASC_CSP_ENABLE
+	ascAlgFactory(new AscAlgFactory(&normAllocator, &privAllocator)),
+	#endif
+	rsaDsaAlgFactory(new RSA_DSA_Factory(&normAllocator, &privAllocator))
+{
+	// misc. once-per-address-space cruft...
+}
+
+AppleCSPPlugin::~AppleCSPPlugin()
+{
+	#ifdef	BSAFE_CSP_ENABLE
+	delete bSafe4Factory;
+	#endif
+	#ifdef	CRYPTKIT_CSP_ENABLE
+	delete cryptKitFactory;
+	#endif
+	delete miscAlgFactory;
+	#ifdef	ASC_CSP_ENABLE
+	delete ascAlgFactory;
+	#endif
+	delete rsaDsaAlgFactory;
+}
+
+
+//
+// Create a new plugin session, our way
+//
+PluginSession *AppleCSPPlugin::makeSession(
+	CSSM_MODULE_HANDLE handle,
+    const CSSM_VERSION &version,
+    uint32 subserviceId,
+    CSSM_SERVICE_TYPE subserviceType,
+    CSSM_ATTACH_FLAGS attachFlags,
+    const CSSM_UPCALLS &upcalls)
+{
+    switch (subserviceType) {
+        case CSSM_SERVICE_CSP:
+            return new AppleCSPSession(handle,
+				*this,
+				version,
+				subserviceId,
+				subserviceType,
+				attachFlags,
+				upcalls);
+        default:
+            CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
+            return 0;	// placebo
+    }
+}
+
+
+//
+// Session constructor
+//
+AppleCSPSession::AppleCSPSession(
+	CSSM_MODULE_HANDLE handle,
+	AppleCSPPlugin &plug,
+	const CSSM_VERSION &version,
+	uint32 subserviceId,
+	CSSM_SERVICE_TYPE subserviceType,
+	CSSM_ATTACH_FLAGS attachFlags,
+	const CSSM_UPCALLS &upcalls)
+		: CSPFullPluginSession(handle, 
+			plug, 
+			version, 
+			subserviceId, 
+			subserviceType,
+			attachFlags, 
+			upcalls),
+		#ifdef	BSAFE_CSP_ENABLE
+		bSafe4Factory(*(dynamic_cast<BSafeFactory *>(plug.bSafe4Factory))), 
+		#endif
+		#ifdef	CRYPTKIT_CSP_ENABLE
+		cryptKitFactory(*(dynamic_cast<CryptKitFactory *>(plug.cryptKitFactory))),
+		#endif
+		miscAlgFactory(*(dynamic_cast<MiscAlgFactory *>(plug.miscAlgFactory))),
+		#ifdef	ASC_CSP_ENABLE
+		ascAlgFactory(*(dynamic_cast<AscAlgFactory *>(plug.ascAlgFactory))),
+		#endif
+		rsaDsaAlgFactory(*(dynamic_cast<RSA_DSA_Factory *>(plug.rsaDsaAlgFactory))),
+		normAllocator(plug.normAlloc()),
+		privAllocator(plug.privAlloc())
+{
+	// anything? 
+}
+
+AppleCSPSession::~AppleCSPSession()
+{
+	// anything?
+}
+
+//
+// Called at (CSSM) context create time. This is ignored; we do a full 
+// context setup later, at setupContext time. 
+//
+CSPFullPluginSession::CSPContext *
+AppleCSPSession::contextCreate(
+	CSSM_CC_HANDLE handle, 
+	const Context &context) 
+{
+	return NULL;
+}
+
+//
+// Called by CSPFullPluginSession when an op is actually commencing.
+// Context can safely assumed to be fully formed and stable for the
+// duration of the  op; thus we wait until now to set up our 
+// CSPContext as appropriate to the op.
+//
+void AppleCSPSession::setupContext(
+	CSPContext * &cspCtx,
+	const Context &context, 
+	bool encoding)
+{
+	/*
+	 * Note we leave the decision as to whether it's OK to 
+	 * reuse a context to the individual factories.
+	 */
+	#ifdef	BSAFE_CSP_ENABLE
+	/* Give BSAFE the firsrt shot if it's present */
+	if (bSafe4Factory.setup(*this, cspCtx, context)) {
+		CASSERT(cspCtx != NULL);
+		return;
+	}
+	#endif
+	if (rsaDsaAlgFactory.setup(*this, cspCtx, context)) {
+		CASSERT(cspCtx != NULL);
+		return;
+	}
+	if (miscAlgFactory.setup(*this, cspCtx, context)) {
+		CASSERT(cspCtx != NULL);
+		return;
+	}
+	#ifdef	CRYPTKIT_CSP_ENABLE
+	if (cryptKitFactory.setup(*this, cspCtx, context)) {
+		CASSERT(cspCtx != NULL);
+		return;
+	}
+	#endif
+	#ifdef	ASC_CSP_ENABLE
+	if (ascAlgFactory.setup(*this, cspCtx, context)) {
+		CASSERT(cspCtx != NULL);
+		return;
+	}
+	#endif
+	if(setup(cspCtx, context)) {
+		CASSERT(cspCtx != NULL);
+		return;
+	}
+	dprintf0("AppleCSPSession::setupContext: invalid algorithm\n");
+	CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+}
+
+/* 
+ * Used for generating crypto contexts at this level. 
+ * Analogous to AlgorithmFactory.setup().
+ */
+bool AppleCSPSession::setup(
+	CSPFullPluginSession::CSPContext * &cspCtx, 
+	const Context &context)
+{
+	if (cspCtx) {
+		return false;	// not ours or already set
+	}
+	
+	switch(context.type()) {
+		case CSSM_ALGCLASS_RANDOMGEN:
+			switch (context.algorithm()) {
+				case CSSM_ALGID_APPLE_YARROW:
+					cspCtx = new YarrowContext(*this);
+					return true;
+				/* other random algs here */
+				default:
+					return false;
+			}
+		/* other contexts here */
+		default:
+			return false;
+	}
+	/* NOT REACHED */
+	return false;
+
+}
+
+//
+// Context for CSSM_ALGID_APPLE_YARROW.
+//
+YarrowContext::YarrowContext(AppleCSPSession &session)
+	: AppleCSPContext(session)
+{
+	// nothing for now 
+}
+
+YarrowContext::~YarrowContext()
+{
+	// nothing for now 
+}
+
+//
+// Only job here is to snag the length and process the optional seed argument
+//
+void YarrowContext::init(
+	const Context &context, 
+	bool encoding)
+{
+	/* stash requested length for use later in outputSize() */
+	outSize = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE,
+		CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE);
+		
+	/* optional seed */
+	CssmCryptoData *cseed = context.get<CssmCryptoData>(CSSM_ATTRIBUTE_SEED);
+	if(cseed == NULL) {
+		/* we're done */
+		return;
+	}
+	CssmData seed = (*cseed)();
+	if((seed.Length == 0) ||
+	   (seed.Data == NULL)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SEED);
+	}
+	session().addEntropy((size_t)seed.Length, seed.Data);
+}
+
+void YarrowContext::final(
+	CssmData &out)
+{
+	session().getRandomBytes((size_t)out.Length, out.Data);
+}
+
+/***
+ *** Binary Key support.
+ ***/
+
+// Given a CSSM_DATA, extract its KeyRef. 
+static KeyRef CssmDataToKeyRef(
+	const CSSM_DATA &data)
+{
+	if(data.Length != sizeof(KeyRef)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
+	}
+	
+	uint8 *cp = data.Data;
+	KeyRef keyRef = cp[0];
+	keyRef |= ((KeyRef)cp[1]) << 8;
+	keyRef |= ((KeyRef)cp[2]) << 16;
+	keyRef |= ((KeyRef)cp[3]) << 24;
+	return keyRef;
+}
+
+// Place a KeyRef into a CSSM_DATA, mallocing if necessary.
+static void keyRefToCssmData(
+	KeyRef			keyRef,
+	CSSM_DATA		&data,
+	CssmAllocator	&allocator)
+{
+	setUpData(data, sizeof(keyRef), allocator);
+	
+	uint8 *cp = data.Data;
+	cp[0] = keyRef & 0xff;
+	cp[1] = (keyRef >> 8) & 0xff;
+	cp[2] = (keyRef >> 16) & 0xff;
+	cp[3] = (keyRef >> 24) & 0xff;
+}
+
+// Look up a BinaryKey by its KeyRef. Returns NULL if not 
+// found. refKeyMapLock held on entry and exit.
+BinaryKey *AppleCSPSession::lookupKeyRef(
+	KeyRef	keyRef)
+{
+	const BinaryKey *binKey;
+	
+	// use safe version, don't create new entry if this key
+	// isn't there
+	keyMap::iterator it = refKeyMap.find(keyRef);
+	if(it == refKeyMap.end()) {
+		return NULL;
+	}
+	binKey = it->second;
+	assert(binKey == reinterpret_cast<const BinaryKey *>(keyRef));
+	assert(binKey->mKeyRef == keyRef);
+	return const_cast<BinaryKey *>(binKey);
+}
+
+// add a BinaryKey to our refKeyMap. Sets up cssmKey
+// as appropriate.
+void AppleCSPSession::addRefKey(
+	BinaryKey	&binKey,
+	CssmKey		&cssmKey)
+{
+	// for now, KeyRef is just the address of the BinaryKey
+	KeyRef			keyRef = reinterpret_cast<KeyRef>(&binKey);
+	
+	binKey.mKeyRef = keyRef;
+	binKey.mKeyHeader = CssmKey::Header::overlay(cssmKey.KeyHeader);
+	{
+		StLock<Mutex> _(refKeyMapLock);
+		assert(lookupKeyRef(keyRef) == NULL);
+		refKeyMap[keyRef] = &binKey;
+	}
+	cssmKey.KeyHeader.BlobType = CSSM_KEYBLOB_REFERENCE;
+	cssmKey.KeyHeader.Format = CSSM_KEYBLOB_REF_FORMAT_INTEGER;
+	keyRefToCssmData(keyRef, cssmKey.KeyData, normAllocator);
+}
+	
+// Given a CssmKey in reference form, obtain the associated
+// BinaryKey. Throws CSSMERR_CSP_INVALID_KEY_REFERENCE if
+// key not found in session key map.
+BinaryKey & AppleCSPSession::lookupRefKey(
+	const CssmKey		&cssmKey)
+{
+	KeyRef 		keyRef;
+	BinaryKey	*binKey;
+
+	keyRef = CssmDataToKeyRef(cssmKey.KeyData);
+	{
+		StLock<Mutex> _(refKeyMapLock);
+		binKey = lookupKeyRef(keyRef);
+	}
+	if(binKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
+	}
+	assert(Guid::overlay(binKey->mKeyHeader.CspId) == plugin.myGuid());
+
+	/*
+	 * Verify sensitive fields have not changed between when the BinaryKey was
+	 * created/stored and when the caller passed in the ref key.
+	 * Some fields were changed by addRefKey, so make a local copy....
+	 */
+	CSSM_KEYHEADER localHdr = cssmKey.KeyHeader;
+	localHdr.BlobType = binKey->mKeyHeader.BlobType;
+	localHdr.Format = binKey->mKeyHeader.Format;
+	if(memcmp(&localHdr, &binKey->mKeyHeader, sizeof(CSSM_KEYHEADER))) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
+	}
+	return (*binKey);
+}
+
+// CSPFullPluginSession declares & implements this.
+// Note that we ignore the delete argument; since we don't
+// store anything, freeing is the same as deleting. 
+void AppleCSPSession::FreeKey(
+	const AccessCredentials *AccessCred,
+	CssmKey &KeyPtr,
+	CSSM_BOOL Delete)
+{
+	if((KeyPtr.blobType() == CSSM_KEYBLOB_REFERENCE) &&
+	   (KeyPtr.cspGuid() == plugin.myGuid())) {
+		// it's a ref key we generated - delete associated BinaryKey 
+		KeyRef keyRef = CssmDataToKeyRef(KeyPtr.KeyData);
+		{
+			StLock<Mutex> _(refKeyMapLock);
+			BinaryKey *binKey = lookupKeyRef(keyRef);
+			if(binKey != NULL) {
+				try {
+					refKeyMap.erase(keyRef);
+					delete binKey;
+				}
+				catch (...)  {
+					errorLog0("Error deleting/erasing known "
+							"ref key\n");
+				}
+			}
+		}
+	}
+	CSPFullPluginSession::FreeKey(AccessCred, KeyPtr, Delete);
+}
+
+/* Passthrough, used for key digest */
+void AppleCSPSession::PassThrough(
+	CSSM_CC_HANDLE CCHandle,
+	const Context &Context,
+	uint32 PassThroughId,
+	const void *InData,
+	void **OutData)
+{
+	*OutData = NULL;
+	
+	/* validate context */
+	if(Context.type() != CSSM_ALGCLASS_NONE) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
+	}
+
+	switch(PassThroughId) {
+		case CSSM_APPLECSP_KEYDIGEST:
+		{
+			CssmKey &key = Context.get<CssmKey>(
+				CSSM_ATTRIBUTE_KEY, 
+				CSSMERR_CSP_MISSING_ATTR_KEY);
+				
+			/* validate key as best we can */
+			switch(key.keyClass()) {
+				case CSSM_KEYCLASS_PUBLIC_KEY:
+				case CSSM_KEYCLASS_PRIVATE_KEY:
+				case CSSM_KEYCLASS_SESSION_KEY:
+					break;
+				default:
+					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+			}
+
+			/* 
+			 * Ref key: obtain binary and blob 
+			 * Raw key: already have the blob
+			 */
+			CssmData rawBlob;
+			bool allocdRawBlob = false;	
+			switch(key.blobType()) {
+				case CSSM_KEYBLOB_RAW:
+					/* trivial case */
+					rawBlob = CssmData::overlay(key.KeyData);
+					break;
+				case CSSM_KEYBLOB_REFERENCE:
+					{
+						BinaryKey &binKey = lookupRefKey(key);
+						CSSM_KEYBLOB_FORMAT rawFormat;
+						rawFormat = requestedKeyFormat(Context, key);
+						binKey.generateKeyBlob(privAllocator,
+							rawBlob,
+							rawFormat);
+					}
+					allocdRawBlob = true;		// remember - we need to free
+					break;
+				default:
+					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+			}
+			
+			/* obtain sha1 hash of rawBlob */
+			
+			void *digest = NULL;
+			CssmData *outHash = NULL;
+			try {
+				digest = normAllocator.malloc(SHA1_DIGEST_SIZE);
+				outHash = new CssmData(digest, SHA1_DIGEST_SIZE);
+			}
+			catch(...) {
+				if(allocdRawBlob) {
+					freeCssmData(rawBlob, privAllocator);
+				}
+				throw;
+			}
+			cspGenSha1Hash(rawBlob.data(), rawBlob.length(), digest);
+			if(allocdRawBlob) {
+				freeCssmData(rawBlob, privAllocator);
+			}
+			*OutData = outHash;
+			return;
+		}
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_PASSTHROUGH_ID);
+	}
+	/* NOT REACHED */
+}
+
+/*
+ * CSPSession version of QueryKeySizeInBits.
+ */
+void AppleCSPSession::getKeySize(const CssmKey &key, 
+	CSSM_KEY_SIZE &size)
+{
+	CSPKeyInfoProvider *provider = infoProvider(key);
+	provider->QueryKeySizeInBits(size);
+	delete provider;
+}
+
+/*
+ * Per-session RNG, which currently just redirects to YarrowConnection.
+ * CSP_ALLOW_FEE_RNG enables a fallback to the internal FEE-based PRNG if
+ * SecurityServer is not running. 
+ */
+ 
+#if	CSP_ALLOW_FEE_RNG
+#include <CryptKit/feeRandom.h>
+
+static Mutex feeRngMutex;
+static feeRand	feeRng = NULL;
+
+static void cspRandViaFee(size_t length, uint8 *cp)
+{
+	StLock<Mutex> _(feeRngMutex);
+	if(feeRng == NULL) {
+		feeRng = feeRandAlloc();
+	}
+	feeRandBytes(feeRng, cp, length);
+}
+#endif	/* CSP_ALLOW_FEE_RNG */
+
+void AppleCSPSession::getRandomBytes(size_t length, uint8 *cp)
+{
+	try {
+		cspGetRandomBytes(cp, (unsigned)length);
+	}
+	catch(...) {
+		#if		CSP_ALLOW_FEE_RNG
+		errorLog0("CSP: YarrowClient failure; using FEE RNG\n");
+		cspRandViaFee(length, cp);
+		#else
+		errorLog0("CSP: YarrowClient failure\n");
+		#endif
+	}
+}
+
+void AppleCSPSession::addEntropy(size_t length, const uint8 *cp)
+{
+	try {
+		cspAddEntropy(cp, (unsigned)length);
+	}
+	catch(...) {
+		#if		CSP_ALLOW_FEE_RNG
+		return;
+		#else
+		throw;
+		#endif
+	}
+}
+
+/***
+ *** CSPKeyInfoProvider support.
+ ***/
+ 
+/*
+ * Find a CSPKeyInfoProvider subclass for the specified key.
+ */
+CSPKeyInfoProvider *AppleCSPSession::infoProvider(
+	const CssmKey	&key)
+{
+	CSPKeyInfoProvider *provider = NULL;
+	try {	
+		provider = new RSAKeyInfoProvider(key);
+	}
+	catch(...) {
+	
+	}
+	if(provider != NULL) {
+		return provider;
+	}
+	
+	#ifdef	BSAFE_CSP_ENABLE
+	try {	
+		provider = new BSafe::BSafeKeyInfoProvider(key);
+	}
+	catch(...) {
+	
+	}
+	if(provider != NULL) {
+		return provider;
+	}
+	#endif
+	try {	
+		provider = new SymmetricKeyInfoProvider(key);
+	}
+	catch(...) {
+	
+	}
+	if(provider != NULL) {
+		return provider;
+	}
+	#ifdef	CRYPTKIT_CSP_ENABLE
+	try {	
+		provider = new CryptKit::FEEKeyInfoProvider(key);
+	}
+	catch(...) {
+	
+	}
+	if(provider != NULL) {
+		return provider;
+	}
+	#endif
+	CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+}
+
+/*
+ * CSPKeyInfoProvider for symmetric keys. 
+ */
+SymmetricKeyInfoProvider::SymmetricKeyInfoProvider(
+	const CssmKey &cssmKey) :
+		CSPKeyInfoProvider(cssmKey)
+{
+	if(mKey.blobType() != CSSM_KEYBLOB_RAW) {
+		errorLog0("KeyInfoProvider deals only with RAW keys!\n");
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	if(mKey.keyClass() == CSSM_KEYCLASS_SESSION_KEY) {
+		/* that's all we need to know */
+		return;
+	}
+	else {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+}
+
+/* cook up a Binary key */
+void SymmetricKeyInfoProvider::CssmKeyToBinary(
+	BinaryKey **binKey)
+{
+	CASSERT(mKey.keyClass() == CSSM_KEYCLASS_SESSION_KEY);
+	SymmetricBinaryKey *symBinKey = new SymmetricBinaryKey(
+		mKey.KeyHeader.LogicalKeySizeInBits);
+	copyCssmData(mKey, 
+		symBinKey->mKeyData, 
+		symBinKey->mAllocator);
+	*binKey = symBinKey;
+}
+
+/* obtain key size in bits */
+void SymmetricKeyInfoProvider::QueryKeySizeInBits(
+	CSSM_KEY_SIZE &keySize)
+{
+	/* FIXME - do we ever need to calculate RC2 effective size here? */
+	keySize.LogicalKeySizeInBits = keySize.EffectiveKeySizeInBits =
+		mKey.length() * 8;
+}
+
+
diff --git a/AppleCSP/AppleCSP/AppleCSP.h b/AppleCSP/AppleCSP/AppleCSP.h
new file mode 100644
index 00000000..554d39d9
--- /dev/null
+++ b/AppleCSP/AppleCSP/AppleCSP.h
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleCSP.h - top-level plugin and session classes
+//
+#ifndef _APPLE_CSP_H_
+#define _APPLE_CSP_H_
+
+#include <Security/cssmplugin.h>
+#include <Security/pluginsession.h>
+#include <Security/CSPsession.h>
+
+class AppleCSPSession;
+class AppleCSPContext; 
+
+/*
+ * AppleCSP-specific algorithm factory. 
+ */
+class AppleCSPAlgorithmFactory {
+public:
+	AppleCSPAlgorithmFactory() {};
+	virtual ~AppleCSPAlgorithmFactory() { };
+
+	// set ctx and return true if you can handle this
+	virtual bool setup(
+		AppleCSPSession 					&session,
+		CSPFullPluginSession::CSPContext 	* &cspCtx, 
+		const Context &context) = 0;
+		
+	/* probably other setup methods, e.g. by CSSM_ALGORITHMS instead of 
+	 * context */
+};
+
+class AppleCSPPlugin : public CssmPlugin {
+    friend class AppleCSPSession;
+	friend class AppleCSPContext;
+	
+public:
+    AppleCSPPlugin();
+    ~AppleCSPPlugin();
+
+    PluginSession *makeSession(CSSM_MODULE_HANDLE handle,
+                               const CSSM_VERSION &version,
+                               uint32 subserviceId,
+                               CSSM_SERVICE_TYPE subserviceType,
+                               CSSM_ATTACH_FLAGS attachFlags,
+                               const CSSM_UPCALLS &upcalls);
+
+	CssmAllocator 	&normAlloc()	{return normAllocator; }
+    CssmAllocator 	&privAlloc()	{return privAllocator; }
+
+private:
+    CssmAllocator 				&normAllocator;	
+    CssmAllocator 				&privAllocator;	
+	#ifdef	BSAFE_CSP_ENABLE
+    AppleCSPAlgorithmFactory	*bSafe4Factory;		// actually subclasses not visible
+													// in this header
+	#endif
+	#ifdef	CRYPTKIT_CSP_ENABLE
+	AppleCSPAlgorithmFactory	*cryptKitFactory;		
+	#endif
+	AppleCSPAlgorithmFactory	*miscAlgFactory;
+	#ifdef	ASC_CSP_ENABLE
+	AppleCSPAlgorithmFactory	*ascAlgFactory;
+	#endif
+	AppleCSPAlgorithmFactory	*rsaDsaAlgFactory;
+};
+
+
+#endif //_APPLE_CSP_H_
diff --git a/AppleCSP/AppleCSP/AppleCSPContext.cpp b/AppleCSP/AppleCSP/AppleCSPContext.cpp
new file mode 100644
index 00000000..0bccf355
--- /dev/null
+++ b/AppleCSP/AppleCSP/AppleCSPContext.cpp
@@ -0,0 +1,254 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleCSPContext.cpp - CSP-wide contexts 
+//
+
+#include "AppleCSPContext.h"
+#include "AppleCSPSession.h"
+#include "AppleCSPUtils.h"
+
+/*
+ * Empty destructor (just to avoid out-of-line copies)
+ */
+AppleCSPContext::~AppleCSPContext()
+{ }
+
+/* 
+ * get symmetric key bits - context.key can be either ref or raw.
+ * A convenience routine typically used by subclass's init().
+ */
+void AppleCSPContext::symmetricKeyBits(
+	const Context 	&context,
+	CSSM_ALGORITHMS	requiredAlg,	// throws if this doesn't match key alg
+	CSSM_KEYUSE 	intendedUse,	// throws if key usage doesn't match this
+	UInt8			*&keyBits,		// RETURNED (not mallocd or copied)
+	UInt32			&keyLen)		// RETURNED
+{
+	/* key must be present and it must be a session key matching caller's spec */
+    CssmKey &key = 
+		context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
+	if(key.keyClass() != CSSM_KEYCLASS_SESSION_KEY) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	if(key.algorithm() != requiredAlg) {
+		CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
+	}
+	cspValidateIntendedKeyUsage(&key.KeyHeader, intendedUse);
+	
+	/* extract raw bits one way or the other */
+	switch(key.blobType()) {
+		case CSSM_KEYBLOB_RAW:
+			/* easy case, the bits are right there in the CssmKey */
+			if(key.blobFormat() != CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+			}
+			keyLen = key.length();
+			keyBits = key.KeyData.Data;
+			break;
+			
+		case CSSM_KEYBLOB_REFERENCE:
+		{
+			/* do a lookup to get a binary key */
+			BinaryKey &binKey = mSession.lookupRefKey(key);
+			/* fails if this is not a SymmetricBinaryKey */
+			SymmetricBinaryKey *symBinKey =
+				dynamic_cast<SymmetricBinaryKey *>(&binKey);
+			if(symBinKey == NULL) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+			}
+			keyLen = symBinKey->mKeyData.Length;
+			keyBits = symBinKey->mKeyData.Data;
+			break;
+		}
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+	}
+	return;
+}
+
+// Called from subclass after it allocates its BinaryKeys.
+// Caller frees BinaryKeys if we throw any exception. 
+void AppleKeyPairGenContext::generate(
+	const Context 	&context, 
+	AppleCSPSession	&session,
+	CssmKey 		&pubKey, 
+	BinaryKey 		*pubBinKey,
+	CssmKey 		&privKey,
+	BinaryKey		*privBinKey)
+{
+	uint32			keySize;
+	cspKeyStorage 	privStorage;
+	cspKeyStorage 	pubStorage;
+	CssmKey::Header	&pubHdr  = pubKey.header(); 
+	CssmKey::Header	&privHdr = privKey.header(); 
+	
+	// validate context and key header args
+	pubStorage  = cspParseKeyAttr(CKT_Public,  pubHdr.KeyAttr);
+	privStorage = cspParseKeyAttr(CKT_Private, privHdr.KeyAttr);
+	cspValidateKeyUsageBits(CKT_Public,  pubHdr.KeyUsage);
+	cspValidateKeyUsageBits(CKT_Private, privHdr.KeyUsage);
+	
+	// have subclass generate the key pairs in the form of 
+	// its native BinaryKeys
+	generate(context, *pubBinKey, *privBinKey, keySize);
+
+	// FIXME - Any other header setup?
+	pubHdr.LogicalKeySizeInBits = 
+		privHdr.LogicalKeySizeInBits = keySize;
+	pubHdr.KeyAttr  &= ~KEY_ATTR_RETURN_MASK;
+	privHdr.KeyAttr &= ~KEY_ATTR_RETURN_MASK;
+		 
+	// Handle key formatting. Delete the BinaryKeys if
+	// we're not creating ref keys. 
+	switch(pubStorage) {
+		case CKS_Ref:
+			session.addRefKey(*pubBinKey, pubKey);
+			break;
+		case CKS_Data:
+			pubHdr.Format = requestedKeyFormat(context, pubKey);
+			pubBinKey->mKeyHeader  = pubHdr;
+			pubBinKey->generateKeyBlob(
+				session.normAlloc(),		// alloc in user space
+				CssmData::overlay(pubKey.KeyData),
+				pubHdr.Format);
+			delete pubBinKey;
+			break;
+		case CKS_None:
+			delete pubBinKey;
+			break;
+	}
+	switch(privStorage) {
+		case CKS_Ref:
+			session.addRefKey(*privBinKey, privKey);
+			break;
+		case CKS_Data:
+			privHdr.Format = requestedKeyFormat(context, privKey);
+			privBinKey->mKeyHeader = privHdr;
+			privBinKey->generateKeyBlob(
+				session.normAlloc(),		// alloc in user space
+				CssmData::overlay(privKey.KeyData),
+				privHdr.Format);
+			delete privBinKey;
+			break;
+		case CKS_None:
+			delete privBinKey;
+			break;
+	}
+}
+
+/*
+ * Called from subclass's generate method. Subclass is also a 
+ * AppleCSPContext.
+ */
+void AppleSymmKeyGenContext::generateSymKey(
+	const Context 	&context, 
+	AppleCSPSession	&session,		// for ref keys
+	CssmKey 		&cssmKey)		// RETURNED 
+{
+	/* there really is no legal way this should throw... */
+	uint32 reqKeySize = context.getInt(
+		CSSM_ATTRIBUTE_KEY_LENGTH, 
+		CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH);
+	if((reqKeySize < minSizeInBits) ||
+	   (reqKeySize > maxSizeInBits)) {
+		CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE);
+	}
+	if(mustBeByteSized) {
+		if((reqKeySize & 0x7) != 0) {
+			CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE);
+		}
+	}
+	
+	// validate KeyAtrr and KeyUsage already present in header
+	cspKeyStorage 	keyStorage;
+	CssmKey::Header	&hdr  = cssmKey.header(); 
+	
+	keyStorage = cspParseKeyAttr(CKT_Session,  hdr.KeyAttr);
+	cspValidateKeyUsageBits(CKT_Session, hdr.KeyUsage);
+	hdr.KeyAttr  &= ~KEY_ATTR_RETURN_MASK;
+	
+	hdr.LogicalKeySizeInBits = reqKeySize;
+	uint32 keySizeInBytes = (reqKeySize + 7) / 8;
+	SymmetricBinaryKey *binKey = NULL;
+	CssmData *keyData = NULL;
+	
+	switch(keyStorage) {
+		case CKS_None:
+			/* no way */
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+		case CKS_Ref:
+			/* cook up a symmetric binary key */
+			binKey = new SymmetricBinaryKey(reqKeySize);
+			keyData = &binKey->mKeyData;
+			break;
+		case CKS_Data:
+			/* key bytes --> caller's cssmKey */
+			keyData = &(CssmData::overlay(cssmKey.KeyData));
+			setUpCssmData(*keyData, keySizeInBytes, 
+				session.normAlloc());
+			break;
+	}
+	
+	// in any case, fill key bytes with random data
+	session.getRandomBytes(keySizeInBytes, keyData->Data);
+
+	if(keyStorage == CKS_Ref) {
+		session.addRefKey(*binKey, cssmKey);
+	}
+	else {
+		/* Raw data */
+		hdr.BlobType = CSSM_KEYBLOB_RAW;
+		hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING; 
+	}
+
+	// FIXME - any other header fields?
+}
+
+//
+// Symmetric Binary Key support
+//
+SymmetricBinaryKey::SymmetricBinaryKey(
+	unsigned keySizeInBits) :
+		mAllocator(CssmAllocator::standard(CssmAllocator::sensitive))
+{
+	setUpCssmData(mKeyData, (keySizeInBits + 7) / 8, mAllocator);
+}
+
+SymmetricBinaryKey::~SymmetricBinaryKey()
+{
+	freeCssmData(mKeyData, mAllocator);
+}
+
+void SymmetricBinaryKey::generateKeyBlob(
+	CssmAllocator 		&allocator,
+	CssmData			&blob,
+	CSSM_KEYBLOB_FORMAT	&format)	// CSSM_KEYBLOB_RAW_FORMAT_PKCS1, etc.
+{
+	switch(format) {
+		case CSSM_KEYBLOB_RAW_FORMAT_NONE:			// default
+		case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING:	// the one we can do
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SYMMETRIC_KEY_FORMAT);
+	}
+	copyCssmData(mKeyData, blob, allocator);
+	format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
+}
+
diff --git a/AppleCSP/AppleCSP/AppleCSPContext.h b/AppleCSP/AppleCSP/AppleCSPContext.h
new file mode 100644
index 00000000..b48fa4bf
--- /dev/null
+++ b/AppleCSP/AppleCSP/AppleCSPContext.h
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleCSPContext.h - CSP-wide contexts 
+//
+#ifndef _H_APPLE_CSP_CONTEXT
+#define _H_APPLE_CSP_CONTEXT
+
+#include <Security/utilities.h>
+#include <Security/CSPsession.h>
+#include "BinaryKey.h"
+
+//
+// Parent class for all CSPContexts implemented in this CSP.
+// Currently the only thing we add is a reference to our
+// creator's session.
+//
+class AppleCSPSession;
+
+class AppleCSPContext : public CSPFullPluginSession::CSPContext
+{
+public:
+	AppleCSPContext(AppleCSPSession &session)
+		: mSession(session) {}
+    
+    ~AppleCSPContext();
+		
+protected:
+	AppleCSPSession	&session() { return mSession; }
+	
+	/* 
+	 * get symmetric key bits - context.key can be either ref or raw.
+	 * A convenience routine typically used by symmetric contexts' 
+	 * init() routines. 
+	 */
+	void symmetricKeyBits(
+		const Context 	&context,
+		CSSM_ALGORITHMS	requiredAlg,	// throws if this doesn't match key alg
+		CSSM_KEYUSE 	intendedUse,	// throws if key usage doesn't match this
+		UInt8			*&keyBits,		// RETURNED (not mallocd or copied)
+		UInt32			&keyLen);		// RETURNED
+		
+private:
+	AppleCSPSession	&mSession;
+};
+
+//
+// Context for CSSM_ALGID_APPLE_YARROW.
+//
+class YarrowContext : public AppleCSPContext
+{
+public:
+	YarrowContext(AppleCSPSession &session);
+	virtual ~YarrowContext();
+	virtual void init(const Context &context, bool encoding = true);
+	void final(CssmData &out);
+	size_t outputSize(bool final, size_t inSize) { return outSize; }
+
+private:
+	uint32	outSize;
+};
+
+//
+// Classes which inherit from AppleCSPContext and which also perform
+// key pair generation inherit from this class as well.
+//
+class AppleKeyPairGenContext  {
+public:
+	//
+	// Subclass implements generate(const Context &, CssmKey &,
+	// CssmKey &). That method (called from CSPFullPluginSession)
+	// allocates two subclass-specific BinaryKeys and calls this
+	// method. This will eventually call down to generate(const Context &,
+	// BinaryKey &, BinaryKey &) and optionally to 
+	// BinaryKey::generateKeyBlob.
+	//
+	void generate(
+		const Context 	&context, 
+		AppleCSPSession	&session,		// for ref keys
+		CssmKey 		&pubKey, 
+		BinaryKey 		*pubBinKey,
+		CssmKey 		&privKey,
+		BinaryKey		*privBinKey);
+
+protected:
+	// Subclasses must implement this. It cooks up a key pair.
+	virtual void generate(
+		const Context 	&context,
+		BinaryKey		&pubBinKey,		// valid on successful return
+		BinaryKey		&privBinKey, 	// ditto
+		uint32 			&keySize) = 0;	// ditto
+};
+
+//
+// Classes which inherit from AppleCSPContext and which also perform
+// symmetric key generation inherit from this class as well.
+//
+class AppleSymmKeyGenContext  {
+public:
+	//
+	// Subclass implements generate(const Context &, CssmKey &, 
+	// CssmKey &). Note that the second CssmKey is a dummy 
+	// argument. That method merely calls generateSymKey, allowing us 
+	// to get to the associated AppleCSPSession if we need to 
+	// store reference keys. We take care of all attribute and 
+	// usage validation and of header formatting. Parameters for
+	// validation typlically specified in constructor via an
+	// algorithm factory. 
+	//
+	AppleSymmKeyGenContext(
+		uint32			minSize,	// in bits
+		uint32			maxSize,	// ditto
+		bool			byteSized)	// true --> key size must
+									//   be multiple of 8 bits
+		:	minSizeInBits(minSize),
+			maxSizeInBits(maxSize),
+			mustBeByteSized(byteSized)  {}
+			
+	void generateSymKey(
+		const Context 	&context, 
+		AppleCSPSession	&session,		// for ref keys
+		CssmKey 		&cssmKey);		// RETURNED 
+
+private:
+	uint32			minSizeInBits;
+	uint32			maxSizeInBits;
+	bool			mustBeByteSized;
+
+};
+
+/*
+ * Generic symmetric key generation context, for algorithms whose
+ * requirements can be expressed in min/max key size and 
+ * mustBeByteSized. Such algorithms just need create one of these
+ * from an algorithm factory.
+ */
+class AppleSymmKeyGenerator : public AppleCSPContext, private AppleSymmKeyGenContext {
+public:
+	AppleSymmKeyGenerator(
+		AppleCSPSession &session,
+		uint32			minSize,		// in bits
+		uint32			maxSize,		// ditto
+		bool			byteSized) :	// true --> key size must
+										//   be multiple of 8 bits
+			AppleCSPContext(session),
+			AppleSymmKeyGenContext(minSize, maxSize, byteSized) { }
+	
+	void init(const Context &context, bool encoding = true) { }
+			
+	/* this just passes the request up to AppleSymmKeyGenContext */
+	void generate(
+		const Context 	&context, 
+		CssmKey 		&symKey, 
+		CssmKey 		&dummyKey) {
+			AppleSymmKeyGenContext::generateSymKey(
+					context, 
+					session(),
+					symKey);
+		}
+
+};
+
+#endif	/* _H_APPLE_CSP_CONTEXT */
diff --git a/AppleCSP/AppleCSP/AppleCSPSession.h b/AppleCSP/AppleCSP/AppleCSPSession.h
new file mode 100644
index 00000000..db540b19
--- /dev/null
+++ b/AppleCSP/AppleCSP/AppleCSPSession.h
@@ -0,0 +1,238 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleCSPSession.h - top-level session class
+//
+#ifndef _APPLE_CSP_SESSION_H_
+#define _APPLE_CSP_SESSION_H_
+
+#include <Security/cssmplugin.h>
+#include <Security/pluginsession.h>
+#include <Security/CSPsession.h>
+#include <Security/threading.h>
+#include "BinaryKey.h"
+#include "AppleCSPUtils.h"
+
+class CSPKeyInfoProvider;
+
+/* avoid unnecessary includes.... */
+class AppleCSPPlugin;
+#ifdef	BSAFE_CSP_ENABLE
+class BSafeFactory;
+#endif
+#ifdef	CRYPTKIT_CSP_ENABLE
+class CryptKitFactory;
+#endif
+class MiscAlgFactory;
+#ifdef	ASC_CSP_ENABLE
+class AscAlgFactory;
+#endif
+class RSA_DSA_Factory;
+
+/* one per attach/detach */
+class AppleCSPSession : public CSPFullPluginSession {
+public:
+	
+	AppleCSPSession(
+		CSSM_MODULE_HANDLE 	handle,
+		AppleCSPPlugin 		&plug,
+		const CSSM_VERSION 	&Version,
+		uint32 				SubserviceID,
+		CSSM_SERVICE_TYPE 	SubServiceType,
+		CSSM_ATTACH_FLAGS 	AttachFlags,
+		const CSSM_UPCALLS 	&upcalls);
+
+	~AppleCSPSession();
+	
+	CSPContext *contextCreate(
+		CSSM_CC_HANDLE 		handle, 
+		const Context 		&context);
+	void setupContext(
+		CSPContext * 		&cspCtx, 
+		const Context 		&context, 
+		bool 				encoding);
+
+	// Functions declared in CSPFullPluginSession which we override.
+	
+	// Free a key. If this is a reference key
+	// we generated, remove it from refKeyMap. 
+	void FreeKey(const AccessCredentials *AccessCred,
+		CssmKey &KeyPtr,
+		CSSM_BOOL Delete);
+	
+	void UnwrapKey(CSSM_CC_HANDLE CCHandle,
+        const Context &Context,
+        const CssmKey *PublicKey,
+        const CssmKey &WrappedKey,
+        uint32 KeyUsage,
+        uint32 KeyAttr,
+        const CssmData *KeyLabel,
+        const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+        CssmKey &UnwrappedKey,
+        CssmData &DescriptiveData,
+        CSSM_PRIVILEGE Privilege);
+	void WrapKey(CSSM_CC_HANDLE CCHandle,
+        const Context &Context,
+        const AccessCredentials &AccessCred,
+        const CssmKey &Key,
+        const CssmData *DescriptiveData,
+        CssmKey &WrappedKey,
+        CSSM_PRIVILEGE Privilege);
+ 	void DeriveKey(CSSM_CC_HANDLE CCHandle,
+		const Context &Context,
+		CssmData &Param,
+		uint32 KeyUsage,
+		uint32 KeyAttr,
+		const CssmData *KeyLabel,
+		const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+		CssmKey &DerivedKey);
+	void PassThrough(CSSM_CC_HANDLE CCHandle,
+		const Context &Context,
+		uint32 PassThroughId,
+		const void *InData,
+		void **OutData);
+	void getKeySize(const CssmKey &key, 
+		CSSM_KEY_SIZE &size);
+
+	// add a BinaryKey to our refKeyMap. Sets up cssmKey
+	// as appropriate.
+	void addRefKey(
+		BinaryKey			&binKey,
+		CssmKey				&cssmKey);
+		
+	// Given a CssmKey in reference form, obtain the associated
+	// BinaryKey. 
+	BinaryKey &lookupRefKey(
+		const CssmKey		&cssmKey);
+
+	// CSP's RNG. THis is redirects to Yarrow.
+	void					getRandomBytes(size_t length, uint8 *cp);
+	void					addEntropy(size_t length, const uint8 *cp);  
+ 
+	CssmAllocator 			&normAlloc()  { return normAllocator; }	
+    CssmAllocator 			&privAlloc()  { return privAllocator; }
+		
+	#ifdef	BSAFE_CSP_ENABLE
+	BSafeFactory 			&bSafe4Factory;
+	#endif
+	#ifdef	CRYPTKIT_CSP_ENABLE
+	CryptKitFactory			&cryptKitFactory;
+	#endif
+	MiscAlgFactory			&miscAlgFactory;
+	#ifdef	ASC_CSP_ENABLE
+	AscAlgFactory			&ascAlgFactory;
+	#endif
+	RSA_DSA_Factory			&rsaDsaAlgFactory;
+	
+private:
+	// storage of binary keys (which apps know as reference keys)
+	typedef std::map<KeyRef, const BinaryKey *> keyMap;
+	keyMap					refKeyMap;
+	Mutex					refKeyMapLock;
+    CssmAllocator 			&normAllocator;	
+    CssmAllocator 			&privAllocator;	
+	
+	BinaryKey 				*lookupKeyRef(KeyRef keyRef);
+	void 					DeriveKey_PBKDF2(
+								const Context &Context,
+								const CssmData &Param,
+								CSSM_DATA *keyData);
+	
+	/* CMS wrap/unwrap, called out from standard wrap/unwrap */
+	void WrapKeyCms(
+		CSSM_CC_HANDLE CCHandle,
+		const Context &Context,
+		const AccessCredentials &AccessCred,
+		const CssmKey &UnwrappedKey,
+	CssmData &rawBlob,
+		bool allocdRawBlob,			// callee has to free rawBlob
+		const CssmData *DescriptiveData,
+		CssmKey &WrappedKey,
+		CSSM_PRIVILEGE Privilege);
+		
+	void UnwrapKeyCms(
+		CSSM_CC_HANDLE CCHandle,
+		const Context &Context,
+		const CssmKey &WrappedKey,
+		const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+		CssmKey &UnwrappedKey,
+		CssmData &DescriptiveData,
+		CSSM_PRIVILEGE Privilege,
+		cspKeyStorage keyStorage);
+
+
+	/* 
+	 * Used for generating crypto contexts at this level. 
+	 * Analogous to AlgorithmFactory.setup().
+	 */
+	bool setup(
+		CSPFullPluginSession::CSPContext * &cspCtx, 
+		const Context &context);
+
+	/*
+	 * Find a CSPKeyInfoProvider subclass for the specified key.
+	 */
+	CSPKeyInfoProvider *infoProvider(
+		const CssmKey	&key);
+		
+};	/* AppleCSPSession */
+
+/*
+ * Class to provide key-specific info. Each module dealing with keys
+ * implements one of these. It's sort of like a CSP-specific CSPContext
+ * without the Context object. AppleCSPSession finds one of these by
+ * querying module-specific subclasses, looking for one in which 
+ * the constructor succeeds. 
+ */
+class CSPKeyInfoProvider 
+{
+public:
+	CSPKeyInfoProvider(
+		const CssmKey &cssmKey) : mKey(cssmKey) { }
+	virtual ~CSPKeyInfoProvider() { }
+	
+	/* cook up a Binary key */
+	virtual void CssmKeyToBinary(
+		BinaryKey			**binKey) = 0;	// RETURNED
+		
+	/* obtain key size in bits */
+	virtual void QueryKeySizeInBits(
+		CSSM_KEY_SIZE		&keySize) = 0;	// RETURNED
+
+protected:
+	const CssmKey			&mKey;
+};
+
+/*
+ * CSPKeyInfoProvider for symmetric keys (handled directly by
+ * the session). 
+ */
+class SymmetricKeyInfoProvider : public CSPKeyInfoProvider 
+{
+public:
+	SymmetricKeyInfoProvider(
+		const CssmKey		&cssmKey);
+	~SymmetricKeyInfoProvider() { }
+	void CssmKeyToBinary(
+		BinaryKey			**binKey);	// RETURNED
+	void QueryKeySizeInBits(
+		CSSM_KEY_SIZE		&keySize);	// RETURNED
+};
+
+#endif //_APPLE_CSP_SESSION_H_
diff --git a/AppleCSP/AppleCSP/AppleCSPUtils.cpp b/AppleCSP/AppleCSP/AppleCSPUtils.cpp
new file mode 100644
index 00000000..c33dd3a2
--- /dev/null
+++ b/AppleCSP/AppleCSP/AppleCSPUtils.cpp
@@ -0,0 +1,561 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleCSPUtils.cpp - CSP-wide utility functions
+//
+
+#include "AppleCSPUtils.h"
+#include <Security/cssmerr.h>
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <string.h>
+#include <CryptKitCSP/FEECSPUtils.h>
+#include <MiscCSPAlgs/SHA1_MD5_Object.h>
+
+/*
+ * Validate key attribute bits per specified key type.
+ *
+ * Used to check requested key attributes for new keys and for validating
+ * incoming existing keys. For checking key attributes for new keys,
+ * assumes that KEYATTR_RETURN_xxx bits have been checked elsewhere
+ * and stripped off before coming here.
+ */
+void cspValidateKeyAttr(
+	cspKeyType 	keyType,
+	uint32 		keyAttr)
+{
+	uint32 sensitiveBit = (keyAttr & CSSM_KEYATTR_SENSITIVE)    ? 1 : 0;
+	uint32 extractBit   = (keyAttr & CSSM_KEYATTR_EXTRACTABLE)  ? 1 : 0;
+
+	/* first general CSP-wide checks */
+	if(keyAttr & KEY_ATTR_RETURN_MASK) {
+		//errorLog0(" KEY_ATTR_RETURN bits set\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+	}
+	if(keyAttr & CSSM_KEYATTR_PERMANENT) {
+		//errorLog0(" PERMANENT bit not supported\n");
+		CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK);
+	}
+	if(keyAttr & CSSM_KEYATTR_PRIVATE) {
+		CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK);
+	}
+	/* Anything else? */
+	
+	/* now check per keyType */
+	switch(keyType) {
+		case CKT_Session:
+			break;
+
+		case CKT_Public:
+			if(sensitiveBit || !extractBit) {
+				//errorLog0("Public keys must be extractable in the clear\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+			}
+			break;
+
+		case CKT_Private:
+			//if(!sensitiveBit) {
+			//	errorLog0("Private keys must have KEYATTR_SENSITIVE\n");
+			//	CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+			//}
+
+			/*
+			 * One more restriction - EXTRACTABLE - caller must check since
+			 * that involves KEYUSE bits.
+			 */
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	return;
+}
+
+/*
+ * Perform sanity check of incoming key attribute bits for a given
+ * key type, and return a cspKeyStorage value.
+ *
+ * Called from any routine which generates a new key. This specifically
+ * excludes WrapKey().
+ */
+cspKeyStorage cspParseKeyAttr(
+	cspKeyType 	keyType,
+	uint32 		keyAttr)
+{
+	uint32 sensitiveBit = (keyAttr & CSSM_KEYATTR_SENSITIVE)    ? 1 : 0;
+	uint32 rtnDataBit   = (keyAttr & CSSM_KEYATTR_RETURN_DATA)  ? 1 : 0;
+	uint32 rtnRefBit    = (keyAttr & CSSM_KEYATTR_RETURN_REF)   ? 1 : 0;
+	uint32 extractBit   = (keyAttr & CSSM_KEYATTR_EXTRACTABLE)  ? 1 : 0;
+
+	cspKeyStorage rtn;
+
+	/* first general CDSA-wide checks */
+	if(keyAttr & (CSSM_KEYATTR_ALWAYS_SENSITIVE |
+				  CSSM_KEYATTR_NEVER_EXTRACTABLE)) {
+		//errorLog0("ALWAYS_SENSITIVE, NEVER_EXTRACTABLE illegal at SPI\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+	}
+	switch(keyAttr & KEY_ATTR_RETURN_MASK) {
+		/* ensure only one bit is set */
+		case CSSM_KEYATTR_RETURN_DATA:
+			rtn = CKS_Data;
+			break;
+		case CSSM_KEYATTR_RETURN_REF:
+			rtn = CKS_Ref;
+			break;
+		case CSSM_KEYATTR_RETURN_NONE:
+			rtn = CKS_None;
+			break;
+		case CSSM_KEYATTR_RETURN_DEFAULT:
+			/* CSP default */
+			rtnRefBit = 1;
+			rtn = CKS_Ref;
+			break;
+		default:
+			//errorLog0("Multiple KEYATTR_RETURN bits set\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+	}
+
+	/* now CSP-wide checks for all key types */
+	if(keyType != CKT_Session) {
+		/* session keys modifiable, no others are */
+		if(keyAttr & CSSM_KEYATTR_MODIFIABLE) {
+			//errorLog0("CSSM_KEYATTR_MODIFIABLE not supported\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+		}
+	}
+	if(rtnDataBit) {
+		if(!extractBit) {
+			//errorLog0("RETURN_DATA and !EXTRACTABLE not supported\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+		}
+		if(sensitiveBit) {
+			//errorLog0("RETURN_DATA and SENSITIVE not supported\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+		}
+	}
+
+	/* now check per keyType. We're ust checking for things specific
+	 * to KEYATTR_RETURN_xxx; cspValidateKeyAttr will check other fields. */
+	 #if 0
+	 // nothing for now
+	switch(keyType) {
+		case CKT_Session:
+			break;
+
+		case MKT_Public:
+			break;
+
+		case MKT_Private:
+			if(rtnDataBit) {
+				errorLog0("Private keys must be generated by ref\n");
+				goto errorOut;
+			}
+			/*
+			 * One more restriction - EXTRACTABLE - caller must check since
+			 * that involves KEYUSE bits.
+			 */
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	#endif	// 0
+
+	/* validate other common static attributes */
+	cspValidateKeyAttr(keyType, (keyAttr & ~KEY_ATTR_RETURN_MASK));
+	return rtn;
+}
+
+
+/* used in cspValidateKeyUsageBits() */
+/*
+ * This is a vestige from OS9/ASA. In the real world there are in fact certs with
+ * keyUsage extensions which specify, e.g., verify and wrap. I think we'll just
+ * have to ignore the old exclusivity rules. 
+ */
+#define IGNORE_KEYUSE_EXCLUSIVITY	1
+#if		IGNORE_KEYUSE_EXCLUSIVITY
+#define checkExclusiveUsage(ku, cb, ob, em)
+#else
+static void checkExclusiveUsage(
+	uint32		keyUsage,		// requested usage word
+	uint32		checkBits,		// if any of these are set
+	uint32		otherBits,		// these are the only other bits which can be set
+	const char	*errMsg)
+{
+	if(keyUsage & checkBits) {
+		if(keyUsage & ~otherBits) {
+			errorLog0((char *)errMsg);
+			CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK);
+		}
+	}
+}
+#endif	/* IGNORE_KEYUSE_EXCLUSIVITY */
+
+/*
+ * Validate key usage bits for specified key type.
+ */
+void cspValidateKeyUsageBits (
+	cspKeyType	keyType,
+	uint32		keyUsage)
+{
+	/* general restrictions */
+	checkExclusiveUsage(keyUsage,
+		CSSM_KEYUSE_ANY,
+		CSSM_KEYUSE_ANY,
+		"CSSM_KEYUSE_ANY overload");
+	checkExclusiveUsage(keyUsage,
+			CSSM_KEYUSE_DERIVE,
+			CSSM_KEYUSE_DERIVE,
+			"CSSM_KEYUSE_DERIVE overload\n");
+
+	/* brute force per key type. */
+	switch(keyType) {
+		case CKT_Session:
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+					CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+					"session key usage: encrypt/decrypt overload\n");
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY |
+						CSSM_KEYUSE_SIGN_RECOVER | CSSM_KEYUSE_VERIFY_RECOVER,
+					CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY |
+						CSSM_KEYUSE_SIGN_RECOVER | CSSM_KEYUSE_VERIFY_RECOVER,
+					"session key usage: sign/verify overload\n");
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP,
+					CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP,
+					"session key usage: wrap/unwrap overload\n");
+			break;
+
+		case CKT_Public:
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_ENCRYPT,
+					CSSM_KEYUSE_ENCRYPT,
+					"public key usage: encrypt overload\n");
+			if(keyUsage & CSSM_KEYUSE_DECRYPT) {
+				errorLog0("public key usage: DECRYPT illegal\n");
+				CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK);
+			}
+			if(keyUsage & (CSSM_KEYUSE_SIGN | CSSM_KEYUSE_SIGN_RECOVER)) {
+				errorLog0("public key usage: SIGN illegal\n");
+				CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK);
+			}
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_VERIFY_RECOVER,
+					CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_VERIFY_RECOVER,
+					"public key usage: verify overload\n");
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_WRAP,
+					CSSM_KEYUSE_WRAP,
+					"public key usage: wrap overload\n");
+			if(keyUsage & CSSM_KEYUSE_UNWRAP) {
+				errorLog0("public key usage: UNWRAP illegal\n");
+				CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK);
+			}
+			break;
+
+		case CKT_Private:
+			if(keyUsage & CSSM_KEYUSE_ENCRYPT) {
+				errorLog0("private key usage: ENCRYPT illegal\n");
+				CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK);
+			}
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_DECRYPT,
+					CSSM_KEYUSE_DECRYPT,
+					"private key usage: decrypt overload\n");
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_SIGN | CSSM_KEYUSE_SIGN_RECOVER,
+					CSSM_KEYUSE_SIGN | CSSM_KEYUSE_SIGN_RECOVER,
+					"private key usage: sign overload\n");
+			if(keyUsage & (CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_VERIFY_RECOVER)) {
+				errorLog0("private key usage: VERIFY illegal\n");
+				CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK);
+			}
+			if(keyUsage & CSSM_KEYUSE_WRAP) {
+				errorLog0("private key usage: WRAP illegal\n");
+				CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK);
+			}
+			checkExclusiveUsage(keyUsage,
+					CSSM_KEYUSE_UNWRAP,
+					CSSM_KEYUSE_UNWRAP,
+					"private key usage: unwrap overload\n");
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+}
+
+/*
+ * Validate existing key's usage bits against intended use.
+ */
+
+/*
+ * For now, a key marked for KEYUSE_{WRAP|UNWRAP} can also be used for
+ * KEYUSE_{ENCRYPT|DECRYPT}. This is a temporary workaround for
+ * Radar 2716153.
+ */
+#define RELAXED_WRAP_USAGE		1
+
+void cspValidateIntendedKeyUsage(
+	const CSSM_KEYHEADER	*hdr,
+	CSSM_KEYUSE				intendedUsage)
+{
+	uint32 		keyUsage = hdr->KeyUsage;
+	cspKeyType	keyType;
+
+	/* first, the obvious */
+	if(keyUsage & CSSM_KEYUSE_ANY) {
+		/* OK for now */
+		return;
+	}
+	if(!(keyUsage & intendedUsage)) {
+		#if		RELAXED_WRAP_USAGE
+		if(! ( ( (keyUsage & CSSM_KEYUSE_WRAP) && 
+		         (intendedUsage == CSSM_KEYUSE_ENCRYPT)
+			   ) ||
+			   ( (keyUsage & CSSM_KEYUSE_UNWRAP) && 
+		         (intendedUsage == CSSM_KEYUSE_DECRYPT)
+			   )
+			 ) )
+		#endif
+		CssmError::throwMe(CSSMERR_CSP_KEY_USAGE_INCORRECT);
+	}
+
+	/* now validate all of the key's usage bits - this is mainly to
+	 * prevent and detect tampering */
+	switch(hdr->KeyClass) {
+		case CSSM_KEYCLASS_SESSION_KEY:
+			keyType = CKT_Session;
+			break;
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			keyType = CKT_Public;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			keyType = CKT_Private;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	try {
+		cspValidateKeyUsageBits(keyType, keyUsage);
+	}
+	catch (...) {
+		/* override error.... */
+		CssmError::throwMe(CSSMERR_CSP_KEY_USAGE_INCORRECT);
+	}
+}
+
+/*
+ * Set up a key header.
+ */
+void setKeyHeader(
+	CSSM_KEYHEADER &hdr,
+	const Guid &myGuid,
+	CSSM_ALGORITHMS alg, 
+	CSSM_KEYCLASS keyClass,
+	CSSM_KEYATTR_FLAGS attrs, 
+	CSSM_KEYUSE use)
+{
+    memset(&hdr, 0, sizeof(CSSM_KEYHEADER));
+    hdr.HeaderVersion = CSSM_KEYHEADER_VERSION;
+    hdr.CspId = myGuid;
+    hdr.AlgorithmId = alg;
+    hdr.KeyClass = keyClass;
+    hdr.KeyUsage = use;
+    hdr.KeyAttr = attrs;
+
+    // defaults (change as needed)
+    hdr.WrapAlgorithmId = CSSM_ALGID_NONE;
+}
+
+/*
+ * Ensure that indicated CssmData can handle 'length' bytes 
+ * of data. Malloc the Data ptr if necessary.
+ */
+void setUpCssmData(
+	CssmData			&data,
+	size_t				length,
+	CssmAllocator		&allocator)
+{
+	/* FIXME - I'm sure Perry has more elegant ways of doing this,
+	 * but I can't figure them out. */
+	if(data.Length == 0) {
+		data.Data = (uint8 *)allocator.malloc(length);
+	}
+	else if(data.Length < length) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_DATA);
+	}
+	data.Length = length;
+}
+
+void setUpData(
+	CSSM_DATA			&data,
+	size_t				length,
+	CssmAllocator		&allocator)
+{
+	setUpCssmData(CssmData::overlay(data), length, allocator);
+}
+
+void freeCssmData(
+	CssmData			&data, 
+	CssmAllocator		&allocator)
+{
+	if(data.Data) {
+		allocator.free(data.Data);
+		data.Data = NULL;
+	}
+	data.Length = 0;
+}
+	
+void freeData(
+	CSSM_DATA			*data, 
+	CssmAllocator		&allocator,
+	bool				freeStruct)		// free the CSSM_DATA itself
+{
+	if(data == NULL) {
+		return;
+	}
+	if(data->Data) {
+		allocator.free(data->Data);
+		data->Data = NULL;
+	}
+	data->Length = 0;
+	if(freeStruct) {
+		allocator.free(data);
+	}
+}
+
+/*
+ * Copy source to destination, mallocing destination if necessary.
+ */
+void copyCssmData(
+	const CssmData		&src,
+	CssmData			&dst,
+	CssmAllocator		&allocator)
+{
+	setUpCssmData(dst, src.Length, allocator);
+	memmove(dst.Data, src.Data, src.Length);
+}
+
+void copyData(
+	const CSSM_DATA		&src,
+	CSSM_DATA			&dst,
+	CssmAllocator		&allocator)
+{
+	copyCssmData(CssmData::overlay(src), 
+		CssmData::overlay(dst), 
+		allocator);
+}
+
+/*
+ * This takes care of mallocing the KeyLabel field. 
+ */
+void copyCssmHeader(
+	const CssmKey::Header	&src,
+	CssmKey::Header			&dst,
+	CssmAllocator			&allocator)
+{
+	dst = src;
+}
+
+/*
+ * Given a wrapped key, infer its raw format. 
+ * This is a real kludge; it only works as long as each {algorithm, keyClass}
+ * maps to exactly one format.  
+ */
+CSSM_KEYBLOB_FORMAT inferFormat(
+	const CssmKey		&wrappedKey)
+{
+	switch(wrappedKey.keyClass()) {
+		case CSSM_KEYCLASS_SESSION_KEY:
+			return CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			switch(wrappedKey.algorithm()) {
+				case CSSM_ALGID_RSA:
+					return CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
+				case CSSM_ALGID_DSA:
+					return CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
+				#ifdef	CRYPTKIT_CSP_ENABLE
+				case CSSM_ALGID_FEE:
+					return FEE_KEYBLOB_DEFAULT_FORMAT;
+				#endif
+				default:
+					/* punt */
+					return CSSM_KEYBLOB_RAW_FORMAT_NONE;
+			}
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			switch(wrappedKey.algorithm()) {
+				case CSSM_ALGID_RSA:
+					return CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
+				case CSSM_ALGID_DSA:
+					return CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
+				#ifdef	CRYPTKIT_CSP_ENABLE
+				case CSSM_ALGID_FEE:
+					return FEE_KEYBLOB_DEFAULT_FORMAT;
+				#endif
+				default:
+					/* punt */
+					return CSSM_KEYBLOB_RAW_FORMAT_NONE;
+			}
+		default:
+			/* punt */
+			return CSSM_KEYBLOB_RAW_FORMAT_NONE;
+	}
+}
+
+/*
+ * Given a key and a Context, obtain the optional associated 
+ * CSSM_ATTRIBUTE_{PUBLIC,PRIVATE,SYMMETRIC}_KEY_FORMAT attribute as a 
+ * CSSM_KEYBLOB_FORMAT.
+ */
+CSSM_KEYBLOB_FORMAT requestedKeyFormat(
+	const Context 	&context,
+	const CssmKey	&key)
+{
+	CSSM_ATTRIBUTE_TYPE attrType;
+	
+	switch(key.keyClass()) {
+		case CSSM_KEYCLASS_SESSION_KEY:
+			attrType = CSSM_ATTRIBUTE_SYMMETRIC_KEY_FORMAT;
+			break;
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			attrType = CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			attrType = CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT;
+			break;
+		default:
+			return CSSM_KEYBLOB_RAW_FORMAT_NONE;
+	}
+	/* not present ==> 0 ==> CSSM_KEYBLOB_RAW_FORMAT_NONE */
+	return context.getInt(attrType);
+}
+
+/* one-shot SHA1 digest */
+void cspGenSha1Hash(
+	const void 		*inData,
+	size_t			inDataLen,
+	void			*out)		// caller mallocs, digest goes here
+{
+	SHA1Object sha1;
+	
+	sha1.digestInit();
+	sha1.digestUpdate(inData, inDataLen);
+	sha1.digestFinal(out);
+}
diff --git a/AppleCSP/AppleCSP/AppleCSPUtils.h b/AppleCSP/AppleCSP/AppleCSPUtils.h
new file mode 100644
index 00000000..b6730aa1
--- /dev/null
+++ b/AppleCSP/AppleCSP/AppleCSPUtils.h
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleCSPUtils.h - CSP-wide utility functions
+//
+
+#ifndef	_H_APPLE_CSP_UTILS
+#define _H_APPLE_CSP_UTILS
+
+#include "cspdebugging.h"
+#include <Security/cssmtype.h>
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <Security/context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* Key type */
+typedef enum {
+	CKT_Session,
+	CKT_Private,
+	CKT_Public
+} cspKeyType;
+
+/* Key storage type returned from cspParseKeyAttr() */
+typedef enum {
+	 CKS_Ref,
+	 CKS_Data,
+	 CKS_None
+} cspKeyStorage;
+
+#define KEY_ATTR_RETURN_MASK	(CSSM_KEYATTR_RETURN_DATA |		\
+								 CSSM_KEYATTR_RETURN_REF  |		\
+								 CSSM_KEYATTR_RETURN_NONE)
+
+/*
+ * Validate key attribute bits per specified key type.
+ *
+ * Used to check requested key attributes for new keys and for validating
+ * incoming existing keys. For checking key attributes for new keys,
+ * assumes that KEYATTR_RETURN_xxx bits have been checked elsewhere
+ * and stripped off before coming here.
+ */
+void cspValidateKeyAttr(
+	cspKeyType 	keyType,
+	uint32 		keyAttr);
+
+/*
+ * Perform sanity check of incoming key attribute bits for a given
+ * key type, and return a malKeyStorage value.
+ *
+ * Called from any routine which generates a new key. This specifically
+ * excludes WrapKey().
+ */
+cspKeyStorage cspParseKeyAttr(
+	cspKeyType 	keyType,
+	uint32 		keyAttr);
+	
+/*
+ * Validate key usage bits for specified key type.
+ */
+void cspValidateKeyUsageBits (
+	cspKeyType	keyType,
+	uint32		keyUsage);
+
+/*
+ * Validate existing key's usage bits against intended use.
+ */
+void cspValidateIntendedKeyUsage(
+	const CSSM_KEYHEADER	*hdr,
+	CSSM_KEYUSE				intendedUsage);
+
+/*
+ * Set up a key header.
+ */
+void setKeyHeader(
+	CSSM_KEYHEADER &hdr,
+	const Guid &myGuid,
+	CSSM_ALGORITHMS alg, 
+	CSSM_KEYCLASS keyClass,
+	CSSM_KEYATTR_FLAGS attrs, 
+	CSSM_KEYUSE use);
+
+/*
+ * Ensure that indicated CssmData can handle 'length' bytes 
+ * of data. Malloc the Data ptr if necessary.
+ */
+void setUpCssmData(
+	CssmData			&data,
+	size_t				length,
+	CssmAllocator		&allocator);
+
+void setUpData(
+	CSSM_DATA			&data,
+	size_t				length,
+	CssmAllocator		&allocator);
+	
+void freeCssmData(
+	CssmData			&data, 
+	CssmAllocator		&allocator);
+	
+void freeData(
+	CSSM_DATA			*data, 
+	CssmAllocator		&allocator,
+	bool				freeStruct);		// free the CSSM_DATA itself
+
+/*
+ * Copy source to destination, mallocing destination if necessary.
+ */
+void copyCssmData(
+	const CssmData		&src,
+	CssmData			&dst,
+	CssmAllocator		&allocator);
+
+void copyData(
+	const CSSM_DATA		&src,
+	CSSM_DATA			&dst,
+	CssmAllocator		&allocator);
+
+/*
+ * This takes care of mallocing the and KeyLabel field. 
+ */
+void copyCssmHeader(
+	const CssmKey::Header	&src,
+	CssmKey::Header			&dst,
+	CssmAllocator			&allocator);
+	
+/*
+ * Given a wrapped key, infer its raw format. 
+ * This is a real kludge; it only works as long as each {algorithm, keyClass}
+ * maps to exactly one format.  
+ */
+CSSM_KEYBLOB_FORMAT inferFormat(
+	const CssmKey	&wrappedKey);
+
+/*
+ * Given a key and a Context, obtain the optional associated 
+ * CSSM_ATTRIBUTE_{PUBLIC,PRIVATE,SYMMETRIC}_KEY_FORMAT attribute as a 
+ * CSSM_KEYBLOB_FORMAT.
+ */
+CSSM_KEYBLOB_FORMAT requestedKeyFormat(
+	const Context 	&context,
+	const CssmKey	&key);
+	
+/* stateless function to calculate SHA-1 hash of a blob */
+
+#define SHA1_DIGEST_SIZE	20
+void cspGenSha1Hash(
+	const void 		*inData,
+	size_t			inDataLen,
+	void			*out);			// caller mallocs, digest goes here
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	//  _H_APPLE_CSP_UTILS
diff --git a/AppleCSP/AppleCSP/BinaryKey.h b/AppleCSP/AppleCSP/BinaryKey.h
new file mode 100644
index 00000000..604dabe8
--- /dev/null
+++ b/AppleCSP/AppleCSP/BinaryKey.h
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+
+//
+// BinaryKey.h - CSP-wide BinaryKey base class
+//
+
+#ifndef	_H_BINARY_KEY_
+#define _H_BINARY_KEY_
+
+#include <Security/utilities.h>
+#include <Security/cssmtype.h>
+
+// opaque key reference type 
+typedef uint32	KeyRef;
+
+// frame for Binary key; all modules (BSAFE, CryptKit) must subclass
+// this and add a member whose type is the native raw key object.
+// Subclasses must implement constructor, destructor, and generateKeyBlob().
+class BinaryKey
+{
+public:
+						BinaryKey() : mKeyRef(0) { }
+	virtual 			~BinaryKey() { mKeyRef = 0; }
+
+	/* 
+	 * Generate raw key blob.
+	 * The format argument is an in/out parameter and is optionally used
+	 * to reque4st a specific keyblob format for providers which can generate
+	 * multipleÊformats. This value comes from an optional
+	 * CSSM_ATTRIBUTE_{PUBLIC,PRIVATE,SYMMETRIC}_KEY_FORMAT attribute in the current
+	 * context. If so such attribute is present, the default value 
+	 * CSSM_KEYBLOB_RAW_FORMAT_NONE is specified as the default input param.
+	 */
+	virtual void		generateKeyBlob(
+		CssmAllocator 		&allocator,
+		CssmData			&blob,
+		CSSM_KEYBLOB_FORMAT	&format)	// in/out, CSSM_KEYBLOB_RAW_FORMAT_PKCS1, etc.
+		{
+			CssmError::throwMe(CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED); 
+		}
+		
+	CssmKey::Header		mKeyHeader;
+	KeyRef				mKeyRef;
+};
+
+// Binary key representing a symmetric key.
+class SymmetricBinaryKey : public BinaryKey
+{
+public:
+	SymmetricBinaryKey(
+		unsigned keySizeInBits);
+	~SymmetricBinaryKey();
+	void generateKeyBlob(
+		CssmAllocator 		&allocator,
+		CssmData			&blob,
+		CSSM_KEYBLOB_FORMAT	&format);	// CSSM_KEYBLOB_RAW_FORMAT_PKCS1, etc.
+
+	CssmData			mKeyData;
+	CssmAllocator 		&mAllocator;
+};
+
+/*
+ * Stateless function to cook up a BinaryKey given a 
+ * symmetric CssmKey in RAW format. Returns true on 
+ * success, false if we can't deal with this type of key, 
+ * throws exception on other runtime errors.
+ */
+bool symmetricCssmKeyToBinary(
+	const CssmKey		&cssmKey,
+	BinaryKey			**binKey);	// RETURNED
+
+#endif	// _H_BINARY_KEY_
+
diff --git a/AppleCSP/AppleCSP/BlockCryptor.cpp b/AppleCSP/AppleCSP/BlockCryptor.cpp
new file mode 100644
index 00000000..16af0f05
--- /dev/null
+++ b/AppleCSP/AppleCSP/BlockCryptor.cpp
@@ -0,0 +1,609 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * BlockCryptor.cpp - common context for block-oriented encryption algorithms
+ *
+ * Created March 5 2001 by dmitch
+ */
+
+#include "BlockCryptor.h"
+#include "BinaryKey.h"
+#include "AppleCSPSession.h"
+#include <Security/cssmalloc.h>
+#include <Security/utilities.h>
+#include <Security/cssmerr.h>
+#include <string.h>
+#include <Security/debugging.h>
+#include <Security/cssmdata.h>
+
+#define BlockCryptDebug(args...)	debug("blockCrypt", ## args)
+#define bprintf(args...)			debug("blockCryptBuf", ## args)
+#define ioprintf(args...)			debug("blockCryptIo", ## args)
+
+BlockCryptor::~BlockCryptor()
+{
+	if(mInBuf) {
+		memset(mInBuf, 0, mInBlockSize);
+		session().free(mInBuf);
+		mInBuf = NULL;
+	}
+	if(mChainBuf) {
+		memset(mChainBuf, 0, mInBlockSize);
+		session().free(mChainBuf);
+		mChainBuf = NULL;
+	}
+	mInBufSize = 0;
+}
+
+/* 
+ * Reusable setup functions called from subclass's init.
+ * This is the general purpose one....
+ */
+void BlockCryptor::setup(
+		size_t			blockSizeIn,	// block size of input 
+		size_t			blockSizeOut,	// block size of output 
+		bool			pkcsPad,		// this class performs PKCS{5,7} padding
+		bool			needsFinal,		// needs final update with valid data
+		BC_Mode			mode,			// ECB, CBC
+		const CssmData	*iv)			// init vector, required for CBC
+										//Ê  must be at least blockSizeIn bytes
+{
+	if(pkcsPad && needsFinal) {
+		BlockCryptDebug("BlockCryptor::setup pkcsPad && needsFinal");
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	mPkcsPadding = pkcsPad;
+	mMode = mode;
+	mNeedFinalData = needsFinal;
+	
+	/* set up inBuf, all configurations */
+	if(mInBuf != NULL) {
+		/* only reuse if same size */
+		if(mInBlockSize != blockSizeIn) {
+			session().free(mInBuf);
+			mInBuf = NULL;
+		}
+	}
+	if(mInBuf == NULL) {
+		mInBuf = (uint8 *)session().malloc(blockSizeIn);
+	}
+	
+	/* set up chain buf, decrypt/CBC only */
+	if((mMode == BCM_CBC) && !encoding()) {
+		if(mChainBuf != NULL) {
+			/* only reuse if same size */
+			if(mInBlockSize != blockSizeIn) {
+				session().free(mChainBuf);
+				mChainBuf = NULL;
+			}
+		}
+		if(mChainBuf == NULL) {
+			mChainBuf = (uint8 *)session().malloc(blockSizeIn);
+		}
+	}
+	
+	/* IV iff CBC mode, and ensure IV is big enough */
+	switch(mMode) {
+		case BCM_ECB:
+			if(iv != NULL) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR);
+			}
+			break;
+		case BCM_CBC:
+			if(iv == NULL) {
+				CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
+			}
+			if(blockSizeIn != blockSizeOut) {
+				/* no can do, must be same block sizes */
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
+			}
+			if(iv->Length < blockSizeIn) {
+				/* not enough IV */
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR);
+			}
+			/* save IV as appropriate */
+			if(encoding()) {
+				memmove(mInBuf, iv->Data, blockSizeIn);
+			}
+			else {
+				assert(mChainBuf != NULL);
+				memmove(mChainBuf, iv->Data, blockSizeIn);
+			}
+			break;
+	}
+
+	mInBlockSize = blockSizeIn;
+	mInBufSize = 0;
+	mOutBlockSize = blockSizeOut;
+	mOpStarted = false;
+}
+
+/*
+ * This one is used by simple, well-behaved algorithms which don't do their own
+ * padding and which rely on us to do everything but one-block-at-a-time
+ * encrypt and decrypt.
+ */
+void BlockCryptor::setup(
+	size_t			blockSize,		// block size of input and output
+	const Context 	&context)
+{
+	bool 		padEnable 	= false;
+	bool 		chainEnable = false;
+	bool 		ivEnable 	= false;
+	CssmData 	*iv			= NULL;
+	
+	/* 
+	 * Validate context 
+	 * IV optional per mode
+	 * pad optional per mode 
+	 * Currently we ignore extraneous attributes (e.g., it's OK to pass in
+	 * an IV if the mode doesn't specify it), mainly for simplifying test routines.
+	 */
+	CSSM_ENCRYPT_MODE cssmMode = context.getInt(CSSM_ATTRIBUTE_MODE);
+
+    switch (cssmMode) {
+		/* no mode attr --> 0 == CSSM_ALGMODE_NONE, not currently supported */
+ 		case CSSM_ALGMODE_CBCPadIV8:
+			padEnable = true;
+			ivEnable = true;
+			chainEnable = true;
+			break;
+
+		case CSSM_ALGMODE_CBC_IV8: 
+			ivEnable = true;
+			chainEnable = true;
+			break;
+			
+		case CSSM_ALGMODE_ECB:
+			break;
+			
+		case CSSM_ALGMODE_ECBPad:
+			padEnable = true;
+			break;
+			
+		default:
+			errorLog1("DESContext::init: illegal mode (%d)\n", (int)cssmMode);
+            CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
+	}
+	
+	if(padEnable) {
+		/* validate padding type */
+		uint32 padding = context.getInt(CSSM_ATTRIBUTE_PADDING); // 0 ==> PADDING_NONE
+		if(blockSize == 8) {
+			switch(padding) {
+				/* backwards compatibility - used to be PKCS1, should be PKCS5 or 7 */
+				case CSSM_PADDING_PKCS7:
+				case CSSM_PADDING_PKCS5:
+				case CSSM_PADDING_PKCS1:		//Êthis goes away soon
+					/* OK */
+					break;
+				default:
+					CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
+			}
+		}
+		else {
+			switch(padding) {
+				case CSSM_PADDING_PKCS5:		// this goes away soon
+				case CSSM_PADDING_PKCS7:
+					/* OK */
+					break;
+				default:
+					CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
+			}
+		}
+	}
+	if(ivEnable) {
+		/* make sure there's an IV in the context of sufficient length */
+		iv = context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR);
+		if(iv == NULL) {
+			CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
+		}
+		if(iv->Length < blockSize) {
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR);
+		}
+	}
+	setup(blockSize, 
+		blockSize, 
+		padEnable, 
+		false,				// needsFinal 
+		chainEnable ? BCM_CBC : BCM_ECB,
+		iv);
+}
+
+/*
+ * Update always leaves some data in mInBuf if:
+ *    mNeedsFinalData is true, or
+ *    decrypting and mPkcsPadding true. 
+ * Also, we always process all of the input (except on error). 
+ */
+void BlockCryptor::update(
+	void 			*inp, 
+	size_t 			&inSize, 			// in/out
+	void 			*outp, 
+	size_t 			&outSize)			// in/out
+{
+	UInt8 		*uInp = (UInt8 *)inp;
+	UInt8 		*uOutp = (UInt8 *)outp;
+	size_t	 	uInSize = inSize;		// input bytes to go
+	size_t 		uOutSize = 0;			// ouput bytes generated
+	size_t		uOutLeft = outSize;		// bytes remaining in outp
+	size_t 		toMove;
+	size_t		actMoved;
+	unsigned	i;
+	bool		needLeftOver = mNeedFinalData || (!encoding() && mPkcsPadding);
+	
+	assert(mInBuf != NULL);
+	mOpStarted = true;
+	
+	if(mInBufSize) {
+		/* attempt to fill mInBuf from inp */
+		toMove = mInBlockSize - mInBufSize;
+		if(toMove > uInSize) {
+			toMove = uInSize;
+		}
+		if(encoding() && (mMode == BCM_CBC)) {
+			/* xor into last cipherblock or IV */
+			for(i=0; i<toMove; i++) {
+				mInBuf[mInBufSize + i] ^= *uInp++;
+			}
+		}
+		else {
+			/* use incoming data as is */
+			memmove(mInBuf+mInBufSize, uInp, toMove);
+			uInp += toMove;
+		}
+		uInSize    -= toMove;
+		mInBufSize += toMove;
+		
+		/* 
+		 * Process inBuf if it's full, but skip if no more data in uInp and
+		 * inBuf might be needed (by us for unpadding on decrypt, or by
+		 * subclass for anything) for a final call 
+		 */
+		if((mInBufSize == mInBlockSize) && !((uInSize == 0) && needLeftOver)) {
+			actMoved = uOutLeft;
+			if(encoding()) {
+				encryptBlock(mInBuf, mInBlockSize, uOutp, actMoved, false);
+				if(mMode == BCM_CBC) {
+					/* save ciphertext for chaining next block */
+					assert(mInBlockSize == actMoved);
+					memmove(mInBuf, uOutp, mInBlockSize);
+				}
+			}
+			else {
+				decryptBlock(mInBuf, uOutp, actMoved, false);
+				if(mMode == BCM_CBC) {
+					/* xor in last ciphertext */
+					assert(mInBlockSize == actMoved);
+					for(i=0; i<mInBlockSize; i++) {
+						uOutp[i] ^= mChainBuf[i];
+					}
+					/* save this ciphertext for next chain */
+					memmove(mChainBuf, mInBuf, mInBlockSize);
+				}
+			}
+			uOutSize += actMoved;
+			uOutp    += actMoved;
+			uOutLeft -= actMoved;
+			mInBufSize = 0;
+			assert(uOutSize <= outSize);
+		}
+	}	/* processing mInBuf */
+	if(uInSize == 0) {
+		/* done */
+		outSize = uOutSize;
+		ioprintf("=== BlockCryptor::update encrypt %d   inSize 0x%lx  outSize 0x%lx",
+			encoding() ? 1 : 0, inSize, outSize);
+		return;
+	}
+	
+	/* 
+	 * en/decrypt even blocks in (remaining) inp.  
+	 */
+	unsigned leftOver = uInSize % mInBlockSize;
+	if((leftOver == 0) && needLeftOver) {
+		/* 
+		 * Even blocks coming in, but we really need to leave some data
+		 * in the buffer (because the subclass asked for it, or we're decrypting
+		 * with PKCS padding). Save one block for mInBuf.
+		 */
+		leftOver = mInBlockSize; 
+	}
+	toMove = uInSize - leftOver;
+	if(encoding()) {
+		while(toMove) {
+			actMoved = uOutLeft;
+			if(mMode == BCM_ECB) {
+				/* encrypt directly from input to output */
+				encryptBlock(uInp, mInBlockSize, uOutp, actMoved, false);
+			}
+			else {
+				/* xor into last ciphertext, encrypt the result */
+				for(i=0; i<mInBlockSize; i++) {
+					mInBuf[i] ^= uInp[i];
+				}
+				encryptBlock(mInBuf, mInBlockSize, uOutp, actMoved, false);
+				
+				/* save new ciphertext for next chain */
+				assert(actMoved == mInBlockSize);
+				memmove(mInBuf, uOutp, mInBlockSize);
+			}
+			uOutSize += actMoved;
+			uOutp    += actMoved;
+			uInp	 += mInBlockSize;
+			uOutLeft -= actMoved;
+			toMove   -= mInBlockSize; 
+			assert(uOutSize <= outSize);
+		}	/* main encrypt loop */
+	}	
+	else {
+		/* decrypting */
+		while(toMove) {
+			actMoved = uOutLeft;
+			if(mMode == BCM_CBC) {
+				/* save this ciphertext for chain; don't assume in != out */
+				memmove(mInBuf, uInp, mInBlockSize);
+				decryptBlock(uInp, uOutp, actMoved, false);
+				
+				/* chain in previous ciphertext */
+				assert(mInBlockSize == actMoved);
+				for(i=0; i<mInBlockSize; i++) {
+					uOutp[i] ^= mChainBuf[i];
+				}
+				
+				/* save current ciphertext for next block */
+				memmove(mChainBuf, mInBuf, mInBlockSize);
+			}
+			else {
+				/* ECB */
+				decryptBlock(uInp, uOutp, actMoved, false);
+			}
+			uOutSize += actMoved;
+			uOutp    += actMoved;
+			uInp	 += mInBlockSize;
+			uOutLeft -= actMoved;
+			toMove   -= mInBlockSize; 
+			assert(uOutSize <= outSize);
+		}	/* main decrypt loop */
+	}
+	
+	/* leftover bytes from inp --> mInBuf */
+	if(leftOver) {
+		if(encoding() && (mMode == BCM_CBC)) {
+			/* xor into last cipherblock or IV */
+			for(i=0; i<leftOver; i++) {
+				mInBuf[i] ^= *uInp++;
+			}
+		}
+		else {
+			memmove(mInBuf, uInp, leftOver);
+		}
+	}
+	mInBufSize = leftOver;
+	outSize = uOutSize;
+	ioprintf("=== BlockCryptor::update encrypt %d   inSize 0x%lx  outSize 0x%lx",
+		encoding() ? 1 : 0, inSize, outSize);
+}
+	
+void BlockCryptor::final(
+	CssmData 		&out)
+{
+	size_t 		uOutSize = 0;			// ouput bytes generated
+	size_t		actMoved;
+	size_t		uOutLeft = out.Length;	// bytes remaining in out
+	unsigned	i;
+	
+	assert(mInBuf != NULL);
+	mOpStarted = true;
+	if((mInBufSize == 0) && mNeedFinalData) {
+		/* only way this could happen: no update() called (at least not with 
+			* non-zero input data sizes) */
+		BlockCryptDebug("BlockCryptor::final with no mInBuf data");
+		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+	}
+	if(encoding()) {
+		UInt8 *ctext = out.Data;
+		
+		if(mPkcsPadding) {
+			/* 
+			Ê* PKCS5/7 padding: pad byte = size of padding. 
+			 * This assertion courtesy of the limitation on the mutual
+			 * exclusivity of mPkcsPadding and mNeedFinalData. 
+			 */
+			assert(mInBufSize < mInBlockSize);
+			size_t padSize = mInBlockSize - mInBufSize;
+			UInt8 *padPtr  = mInBuf + mInBufSize;
+			if(mMode == BCM_ECB) {
+				for(i=0; i<padSize; i++) {
+					*padPtr++ = padSize;
+				}
+			}
+			else {
+				for(i=0; i<padSize; i++) {
+					*padPtr++ ^= padSize;
+				}
+			}
+			mInBufSize = mInBlockSize;
+		}	/* PKCS padding */
+		
+		/*
+		 * Encrypt final mInBuf. If it's not full, the BlockCryptObject better know
+		 * how to pad....
+		 */
+		if(mInBufSize) {
+			actMoved = uOutLeft;
+			encryptBlock(mInBuf, mInBufSize, ctext, actMoved, true);
+			uOutSize += actMoved;
+			mInBufSize = 0;
+			assert(uOutSize <= out.length());
+		}
+		out.length(uOutSize);
+	}	/* encrypting */
+	
+	else {
+		if(mInBufSize == 0) {
+			if(mPkcsPadding) {
+				BlockCryptDebug("BlockCryptor::final decrypt/pad with no mInBuf data");
+				CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+			}
+			else {
+				/* simple decrypt op complete */
+				ioprintf("=== BlockCryptor::final  encrypt 0   outSize 0");
+				out.length(0);
+				return;
+			}
+		}
+		
+		/*
+		 * Decrypt - must have exactly one block of ciphertext.
+		 * We trust CSPContext, and our own outputSize(), to have set up
+		 * the current output buffer with enough space to handle the 
+		 * full size of the decrypt, even though - due to padding - we
+		 * might actually pass less than that amount back to caller. 
+		 */
+		if(mInBufSize != mInBlockSize) {
+			BlockCryptDebug("BlockCryptor::final unaligned ciphertext");
+			CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+		}
+		
+		UInt8 *ptext = out.Data;
+		actMoved = uOutLeft;
+		decryptBlock(mInBuf, ptext, actMoved, true);
+		if(mMode == BCM_CBC) {
+			/* chain in previous ciphertext one more time */
+			assert(mInBlockSize == actMoved);
+			for(i=0; i<mInBlockSize; i++) {
+				ptext[i] ^= mChainBuf[i];
+			}
+		}
+		if(mPkcsPadding) {
+			assert(actMoved == mOutBlockSize);
+
+			/* ensure integrity of padding byte(s) */
+			unsigned padSize = ptext[mOutBlockSize - 1];
+			if(padSize > mOutBlockSize) {
+				BlockCryptDebug("BlockCryptor::final malformed ciphertext (1)");
+				CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
+			}
+			UInt8 *padPtr = ptext + mOutBlockSize - padSize;
+			for(unsigned i=0; i<padSize; i++) {
+				if(*padPtr++ != padSize) {
+					BlockCryptDebug("BlockCryptor::final malformed ciphertext "
+							"(2)");
+					CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
+				}
+			}
+			actMoved -= padSize;
+		}
+		assert(actMoved <= out.length());
+		out.length(actMoved);
+	}	/* decrypting */
+	ioprintf("=== BlockCryptor::final  encrypt %d   outSize 0x%lx",
+		encoding() ? 1 : 0, out.Length);
+}
+
+/* 
+ * These three are only valid for algorithms for which encrypting one block 
+ * of plaintext always yields exactly one block of ciphertext, and vice versa 
+ * for decrypt. The block sizes for plaintext and ciphertext do NOT have to be 
+ * the same. Subclasses (e.g. FEED) which do not meet this criterion will have 
+ * to override.
+ */
+ 
+void BlockCryptor::minimumProgress(
+	size_t 			&inSize, 
+	size_t 			&outSize)
+{
+	/* each size = one block (including buffered input) */
+    inSize  = mInBlockSize - mInBufSize;
+	if(inSize == 0) {
+		/* i.e., we're holding a whole buffer */
+		inSize++;
+	}
+	outSize = mOutBlockSize;
+	bprintf("--- BlockCryptor::minProgres inSize 0x%lx outSize 0x%lx mInBufSize 0x%lx",
+		inSize, outSize, mInBufSize);
+}
+
+size_t BlockCryptor::inputSize(
+	size_t 			outSize)			// input for given output size
+{
+	size_t inSize;
+	
+	if(outSize < mOutBlockSize) {
+		/* 
+		 * Sometimes CSPFullPluginSession calls us like this....in this
+		 * case the legal inSize is just the remainder of the input buffer,
+		 * less one byte (in other words, the max we we gobble up without
+		 * producing any output). 
+		 */
+		inSize = mInBlockSize - mInBufSize;
+		if(inSize == 0) {
+			/* we have a full input buffer! How can this happen!? */
+			BlockCryptDebug("BlockCryptor::inputSize: HELP! zero inSize and outSize!\n");
+		}
+	}
+	else {
+		/* more-or-less normal case */
+		size_t wholeBlocks = outSize / mOutBlockSize;
+		assert(wholeBlocks >= 1);
+		inSize = (wholeBlocks * mInBlockSize) - mInBufSize;
+		if(inSize == 0) {
+			/* i.e., we're holding a whole buffer */
+			inSize++;
+		}
+	}
+	bprintf("--- BlockCryptor::inputSize  inSize 0x%lx outSize 0x%lx mInBufSize 0x%lx",
+		inSize, outSize, mInBufSize);
+	return inSize;
+}
+
+size_t BlockCryptor::outputSize(
+	bool 			final,
+	size_t 			inSize = 0) 		// output for given input size
+{
+	size_t rawBytes = inSize + mInBufSize;
+	// huh?Êdon't round this up!
+	//size_t rawBlocks = (rawBytes + mInBlockSize - 1) / mInBlockSize;
+	size_t rawBlocks = rawBytes / mInBlockSize;
+
+	/*
+	 * encrypting: always get one additional block on final() if we're padding 
+	 *             or (we presume) the subclass is padding. Note that we
+	 *			   truncated when calculating rawBlocks; to finish out on the 
+	 *			   final block, we (or our subclass) will either have to pad
+	 *			   out the current partial block, or cook up a full pad block if
+	 *			   mInBufSize is currently zero. Subclasses which pad some other
+	 *			   way need to override this method. 
+	 *
+	 * decrypting: outsize always <= insize
+	 */
+	if(encoding() && final && (mPkcsPadding || mNeedFinalData)) {
+		rawBlocks++;
+	}
+	
+	/* FIXME - optimize for needFinalData? (can squeak by with smaller outSize) */
+	size_t rtn = rawBlocks * mOutBlockSize;
+	bprintf("--- BlockCryptor::outputSize inSize 0x%lx outSize 0x%lx final %d "
+		"inBufSize 0x%lx", inSize, rtn, final, mInBufSize);
+	return rtn;
+}
+
+
+
diff --git a/AppleCSP/AppleCSP/BlockCryptor.h b/AppleCSP/AppleCSP/BlockCryptor.h
new file mode 100644
index 00000000..a5e403a1
--- /dev/null
+++ b/AppleCSP/AppleCSP/BlockCryptor.h
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * BlockCryptor.h - common context for block-oriented encryption algorithms
+ *
+ * Created March 5 2001 by dmitch
+ */
+
+#ifndef	_BLOCK_CRYPTOR_H_
+#define _BLOCK_CRYPTOR_H_
+
+#include "AppleCSPContext.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+/*
+ * Base class for AppleCSPContexts associated with BlockCryptObjects. 
+ * The main purpose of this class is to abstract out the very common work
+ * of buffering incoming data (per CSSM-style update, ..., final) and 
+ * doing single-block ops on the underlying encrypt/decrypt algorithm
+ * objects. Standard PKSC5 padding is handled here. All other chaining,
+ * padding, IV, et al, logic is handled by subclasses.
+ */
+class BlockCryptor : public AppleCSPContext
+{
+public:
+	BlockCryptor(
+		AppleCSPSession &session) : 
+			AppleCSPContext(session), 
+			mOpStarted(false),
+			mInBuf(NULL),
+			mChainBuf(NULL) { }
+	virtual ~BlockCryptor();
+	
+	/* 
+	 * Note standard init(const Context &context, bool encoding) is totally 
+	 * subclass-specific. 
+	 *
+	 * These are implemented here using the subclass's {en,de}cryptBlock functions.
+	 * Note PKCS5 padding is implemented here if mPkcs5Padding is true. PKCS5
+	 * padding can only be accomplished if the result of decrypting 
+	 * cipherBlockSize() bytes of ciphertext yields exactly plainBlockSize()
+	 * bytes of plaintext. (Sound odd? FEED does not meet that restriction...)
+	 */
+	void update(
+		void 			*inp, 
+		size_t 			&inSize, 			// in/out
+		void 			*outp, 
+		size_t 			&outSize);			// in/out
+		
+	void final(
+		CssmData 		&out);
+
+	/* 
+	 * Our implementation of these three query functions are only valid 
+	 * for algorithms for which encrypting one block of plaintext always 
+	 * yields exactly one block of ciphertext, and vice versa for decrypt.
+	 * The block sizes for plaintext and ciphertext do NOT have to be the same. 
+	 * Subclasses (e.g. FEED) which do not meet this criterion will have to override.
+	 */
+ 	virtual size_t inputSize(
+		size_t 			outSize);			// input for given output size
+	virtual size_t outputSize(
+		bool 			final = false, 
+		size_t 			inSize = 0); 		// output for given input size
+	virtual void minimumProgress(
+		size_t 			&in, 
+		size_t 			&out); 				// minimum progress chunks
+
+protected:
+	typedef enum {
+		BCM_ECB,			// no chaining
+		BCM_CBC				// requires inBlockSize == outBlockSize
+	} BC_Mode;
+	
+	/* accessors (see comments below re: the member variables) */
+	bool	pkcs5Padding()		{ return mPkcsPadding; }
+	bool	needFinalData()		{ return mNeedFinalData; }
+	void	*inBuf()			{ return mInBuf; }
+	size_t	inBufSize()			{ return mInBufSize; }
+	void	*chainBuf()			{ return mChainBuf; }
+	size_t	inBlockSize()		{ return mInBlockSize; }
+	size_t	outBlockSize()		{ return mOutBlockSize; }
+	BC_Mode	mode()				{ return mMode; }
+	bool	opStarted()			{ return mOpStarted; }
+	
+	/* 
+	 * Reusable setup functions called from subclass's init.
+	 * This is the general purpose one....
+	 */
+	void	setup(
+		size_t			blockSizeIn,	// block size of input in bytes
+		size_t			blockSizeOut,	// block size of output in bytes
+		bool			pkcsPad,		// this class performs PKCS{5,7} padding
+		bool			needsFinal,		// needs final update with valid data
+		BC_Mode			mode,			// ECB, CBC
+		const CssmData	*iv);			// init vector, required for CBC
+										//Ê  must be at least blockSizeIn bytes
+		
+	/*
+	 * This one is used by simple, well-behaved algorithms which don't do their own
+	 * padding and which rely on us to do everything but one-block-at-a-time
+	 * encrypt and decrypt.
+	 */
+	void BlockCryptor::setup(
+		size_t			blockSize,		// block size of input and output
+		const Context 	&context);
+
+	/***
+	 *** Routines to be implemented by subclass.
+	 ***/
+	 
+	/*
+	virtual void init(const Context &context, bool encoding = true);
+	*/
+
+	/* 
+	 * encrypt/decrypt exactly one block. Output buffers mallocd by caller.
+	 * On encrypt, it may be acceptable for plainTextLen to be less than
+	 * one plainBlockSize() if:
+	 *   -- final is true, and
+	 *   -- the subclass permits this. That is generally only true
+	 *      when the subclass implements some padding other than our
+	 *      standard PKCS5.
+	 *
+	 * The subclass throws CSSMERR_CSP_INPUT_LENGTH_ERROR if the above
+	 * conditions are not met.  
+	 */
+	virtual void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, subclass throws on overflow
+		bool			final) = 0;
+		
+	/*
+	 * Decrypt one block. Incoming cipherText length is ALWAYS cipherBlockSize(). 
+	 */
+	virtual void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, subclass throws on overflow
+		bool			final) = 0;
+
+private:
+	bool				mOpStarted;			// for optional use by subclasses when 
+											//   resuing context after encrypt/decrypt 
+											//   ops occur
+
+	/* these are all init'd via setup(), called from subclass-specific init */
+	bool				mPkcsPadding;		// PKCS{5,7} padding enabled
+	bool				mNeedFinalData;		// subclass needs an update(final) with
+											//   valid data; if true we always keep
+											//   some data in mInBuf after an update.
+											//   Mutually exclusive with mPkcsPadding. 
+	uint8 				*mInBuf;			// for buffering input
+	size_t				mInBufSize;			// valid bytes in mInBuf
+	uint8				*mChainBuf;			// for CBC, decrypting only
+	size_t				mInBlockSize;		// block size of input in bytes; also
+											//    mallocd size of mInBuf
+	size_t				mOutBlockSize;		// block size of output in bytes
+	BC_Mode				mMode;				// ECB, CBC
+		
+};
+
+#endif	/* _BLOCK_CRYPTOR_H_ */
diff --git a/AppleCSP/AppleCSP/DigestObject.h b/AppleCSP/AppleCSP/DigestObject.h
new file mode 100644
index 00000000..dbc749fb
--- /dev/null
+++ b/AppleCSP/AppleCSP/DigestObject.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * DigestObject.h - generic virtual Digest base class 
+ */
+
+#ifndef	_DIGEST_OBJECT_H_
+#define _DIGEST_OBJECT_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <Security/context.h>
+
+/* common virtual digest class */
+class DigestObject {
+public:
+	DigestObject() : mInitFlag(false), mIsDone(false) { }
+	virtual ~DigestObject() { }
+	
+	/* 
+	 * The remaining functions must be implemented by subclass. 
+	 */
+	/* init is reusable */
+	virtual void digestInit() = 0;
+
+	/* add some data */
+	virtual void digestUpdate(
+		const void *data, 
+		size_t 		len) = 0;
+	
+	/* obtain digest (once only per init, update, ... cycle) */
+	virtual void digestFinal(
+		void 		*digest) = 0;  	/* RETURNED, alloc'd by caller */
+										
+	virtual size_t digestSizeInBytes() const = 0;
+
+protected:
+	bool			mInitFlag;
+	bool			mIsDone;	
+			
+	bool			initFlag() 				{ return mInitFlag; }
+	void			setInitFlag(bool flag) 	{ mInitFlag = flag; }
+	bool			isDone() 				{ return mIsDone; }
+	void			setIsDone(bool done) 	{ mIsDone = done; }
+};
+
+#endif	/* _DIGEST_OBJECT_H_ */
diff --git a/AppleCSP/AppleCSP/NullDigest.h b/AppleCSP/AppleCSP/NullDigest.h
new file mode 100644
index 00000000..1b8cc6de
--- /dev/null
+++ b/AppleCSP/AppleCSP/NullDigest.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * NULLDigest.h - nop digest for use with raw signature algorithms.
+ *				   NullDigest(someData) = someData.
+ */
+ 
+#ifndef	_NULL_DIGEST_H_
+#define _NULL_DIGEST_H_
+
+#include <AppleCSP/DigestObject.h>
+#include <Security/cssmalloc.h>
+
+class NullDigest : public DigestObject
+{
+public:
+	NullDigest() : mInBuf(NULL), mInBufSize(0) 
+	{ 
+	}
+	
+	~NullDigest()
+	{
+		CssmAllocator::standard().free(mInBuf);
+	}
+	
+	void digestInit() 
+	{ 
+		/* reusable - reset */
+		CssmAllocator::standard().free(mInBuf);
+		mInBufSize = 0;
+		mInBuf = NULL;
+	}
+	
+	void digestUpdate(
+		const void *data, 
+		size_t 		len) 
+	{
+		mInBuf = CssmAllocator::standard().realloc(mInBuf, mInBufSize + len);
+		memmove((uint8 *)mInBuf + mInBufSize, data, len);
+		mInBufSize += len;
+	}
+	
+	virtual void digestFinal(
+		void 		*digest)
+	{
+		memmove(digest, mInBuf, mInBufSize);
+	}
+										
+	size_t digestSizeInBytes() const
+	{ 
+		return mInBufSize;
+	}
+
+private:
+	void		*mInBuf;
+	size_t		mInBufSize;
+};
+
+#endif	/* _NULL_DIGEST_H_ */
\ No newline at end of file
diff --git a/AppleCSP/AppleCSP/RawSigner.h b/AppleCSP/AppleCSP/RawSigner.h
new file mode 100644
index 00000000..30aed4d6
--- /dev/null
+++ b/AppleCSP/AppleCSP/RawSigner.h
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RawSigner.h - low-level virtual sign/verify object (no digest)
+ */
+ 
+#ifndef	_RAW_SIGNER_H_
+#define _RAW_SIGNER_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <Security/context.h>
+#include <Security/cssmalloc.h>
+
+class RawSigner {
+public:
+	RawSigner(
+		CssmAllocator	&alloc,
+		CSSM_ALGORITHMS	digestAlg)	:
+			mInitFlag(false), 
+			mIsSigning(false),
+			mDigestAlg(digestAlg),
+			mAlloc(alloc) { }
+	virtual ~RawSigner()  	{ }
+	
+	/* 
+	 * The use of our mDigestAlg variable is pretty crufty. For some algs, it's 
+	 * known and specified at construction time (e.g., CSSM_ALGID_MD5WithRSA). 
+	 * For some algs, it's set by CSPFullPluginSession via 
+	 * CSPContext::setDigestAlgorithm during raw sign/verify.
+	 */
+	void 			setDigestAlg(CSSM_ALGORITHMS alg)
+											{ mDigestAlg = alg; }
+
+	/* 
+	 * The remaining functions must be implemented by subclass. 
+	 */
+
+	/* reusable init */
+	virtual void signerInit(
+		const Context 	&context,
+		bool			isSigning) = 0;
+	
+	/* sign */
+	virtual void sign(
+		const void 		*data, 
+		size_t 			dataLen,
+		void			*sig,	
+		size_t			*sigLen) = 0;	/* IN/OUT */
+		
+	/* verify */
+	virtual void verify(
+		const void 		*data, 
+		size_t 			dataLen,
+		const void		*sig,			
+		size_t			sigLen) = 0;	
+		
+	/* works for both, but only used for signing */
+	virtual size_t maxSigSize() = 0;
+
+protected:
+	bool			mInitFlag;				// true after init
+	bool			mOpStarted;				// true after update
+	bool			mIsSigning;
+	CSSM_ALGORITHMS	mDigestAlg;				// for raw sign/verify
+	CssmAllocator	&mAlloc;
+	
+	bool			initFlag() 				{ return mInitFlag; }
+	void			setInitFlag(bool flag) 	{ mInitFlag = flag; }
+	bool			opStarted() 			{ return mOpStarted; }
+	void			setOpStarted(bool flag) { mOpStarted = flag; }
+	bool			isSigning()				{ return mIsSigning; }
+	void			setIsSigning(bool signing)
+											{ mIsSigning = signing; }
+	CSSM_ALGORITHMS	digestAlg()				{ return mDigestAlg; }
+	CssmAllocator	&alloc()				{ return mAlloc; }
+};
+
+
+#endif	/* _RAW_SIGNER_H_ */
diff --git a/AppleCSP/AppleCSP/SignatureContext.cpp b/AppleCSP/AppleCSP/SignatureContext.cpp
new file mode 100644
index 00000000..d32cc35e
--- /dev/null
+++ b/AppleCSP/AppleCSP/SignatureContext.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * SignatureContext.h - AppleCSPContext sublass for generic sign/verify
+ */
+
+#include "SignatureContext.h"
+#include "AppleCSPUtils.h"
+#include "AppleCSPSession.h"
+#include <Security/utilities.h>
+#include <Security/cssmtype.h>
+
+#include <Security/debugging.h>
+
+#define cspSigDebug(args...)	debug("cspSig", ## args)
+
+SignatureContext::~SignatureContext()
+{
+	delete &mDigest;
+	delete &mSigner;
+	mInitFlag = false;
+}
+
+/* both sign & verify */
+void SignatureContext::init(
+	const Context &context, 
+	bool isSigning)
+{
+	mDigest.digestInit();
+	mSigner.signerInit(context, isSigning);
+	mInitFlag = true;
+}
+
+/* both sign & verify */
+void SignatureContext::update(
+	const CssmData &data)
+{
+	mDigest.digestUpdate(data.Data, data.Length);
+}
+
+/* sign only */
+void SignatureContext::final(
+	CssmData &out)
+{	
+	void 		*digest;
+	size_t		digestLen;
+	void		*sig = out.data();
+	size_t		sigLen = out.length();
+	
+	/* first obtain the digest */
+	digestLen = mDigest.digestSizeInBytes();
+	digest = session().malloc(digestLen);
+	mDigest.digestFinal(digest);
+	
+	/* now sign */
+	try {
+		mSigner.sign(digest, 
+			digestLen,
+			sig,
+			&sigLen);
+	}
+	catch(...) {
+		session().free(digest);
+		throw;
+	}
+	session().free(digest);
+	if(out.length() < sigLen) {
+		cspSigDebug("SignatureContext: mallocd sig too small!");
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	out.length(sigLen);
+}
+
+/* verify only */
+void SignatureContext::final(
+	const CssmData &in)
+{	
+	void 		*digest;
+	size_t		digestLen;
+	
+	/* first obtain the digest */
+	digestLen = mDigest.digestSizeInBytes();
+	digest = session().malloc(digestLen);
+	mDigest.digestFinal(digest);
+	
+	/* now verify */
+	try {
+		mSigner.verify(digest, 
+			digestLen,
+			in.Data,
+			in.Length);
+	}
+	catch(...) {
+		session().free(digest);
+		throw;
+	}
+	session().free(digest);
+}
+
+size_t SignatureContext::outputSize(
+	bool final,
+	size_t inSize)
+{
+	return mSigner.maxSigSize();
+}
+
+/* for raw sign/verify - optionally called after init */ 
+void SignatureContext::setDigestAlgorithm(
+	CSSM_ALGORITHMS digestAlg)
+{
+	mSigner.setDigestAlg(digestAlg);
+}
diff --git a/AppleCSP/AppleCSP/SignatureContext.h b/AppleCSP/AppleCSP/SignatureContext.h
new file mode 100644
index 00000000..92f44247
--- /dev/null
+++ b/AppleCSP/AppleCSP/SignatureContext.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * SignatureContext.h - AppleCSPContext subclass for generic sign/verify
+ *
+ * This class performs all of the sign/verify operations in the CSP. The general
+ * scheme is that an instance of this class has references to one DigestObject
+ * and one RawSigner. Sign and Verify "updates" go to the DigestObject. The "final"
+ * operation consists of obtaining the final digest from the DigestObject and 
+ * performing a sign or verify on that data via the RawSigner. 
+ *
+ * This class knows nothing about any of the algorithms involved; all sign and 
+ * verify operations follow this same scheme. Various modules' AlgorithmFactories
+ * construct one of these objects by providing the appropriate DigestObject and
+ * RawSigner. 
+ *
+ * The seemingly special case of "raw RSA sign", in which the app calculates the 
+ * digest separately from the sign operation, is handled via the NullDigest object.
+ */
+ 
+#ifndef	_SIGNATURE_CONTEXT_H_
+#define _SIGNATURE_CONTEXT_H_
+
+#include <AppleCSP/RawSigner.h>
+#include <AppleCSP/DigestObject.h>
+#include <AppleCSP/AppleCSPContext.h>
+
+class SignatureContext : public AppleCSPContext  {
+public:
+	SignatureContext(
+		AppleCSPSession &session,
+		DigestObject	&digest,
+		RawSigner		&signer) : 
+			AppleCSPContext(session), 
+			mDigest(digest), 
+			mSigner(signer),
+			mInitFlag(false),
+			mOpStarted(false) { }
+			
+	~SignatureContext();
+	
+	/* called out from CSPFullPluginSession....
+	 * both sign & verify: */
+	void init(const Context &context, bool isSigning);
+	void update(const CssmData &data);
+	
+	/* sign only */
+	void final(CssmData &out);	
+	
+	/* verify only */
+	void final(const CssmData &in);	
+
+	size_t outputSize(bool final, size_t inSize);
+
+	/* for raw sign/verify - optionally called after init */ 
+	virtual void setDigestAlgorithm(CSSM_ALGORITHMS digestAlg);
+
+
+private:
+	DigestObject	&mDigest;
+	RawSigner		&mSigner;
+	bool			mInitFlag;			// true after init
+	bool			mOpStarted;			// true after update
+};
+
+
+#endif	/* _SIGNATURE_CONTEXT_H_ */
\ No newline at end of file
diff --git a/AppleCSP/AppleCSP/YarrowConnection.cpp b/AppleCSP/AppleCSP/YarrowConnection.cpp
new file mode 100644
index 00000000..86bd776b
--- /dev/null
+++ b/AppleCSP/AppleCSP/YarrowConnection.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * YarrowConnection.cpp - single, process-wide, thread-safe Yarrow client
+ */
+#include "YarrowConnection.h"
+#include <Security/globalizer.h>
+#include <Security/devrandom.h>
+#include <Security/cssmtype.h>
+
+/* instantiated by C++ runtime at library load/init time */
+class YarrowConnection : public DevRandomGenerator {
+public:
+    YarrowConnection() : DevRandomGenerator(getuid() == 0), writable(getuid() == 0) { }
+    const bool writable;
+};
+
+/* the single global thing */
+static ModuleNexus<YarrowConnection> yarrowConnection;
+
+
+/* and the exported functions */
+void cspGetRandomBytes(void *buf, unsigned len)
+{
+	yarrowConnection().random(buf, len);
+}
+
+void cspAddEntropy(const void *buf, unsigned len)
+{
+    if (yarrowConnection().writable)
+        yarrowConnection().addEntropy(buf, len);
+}
diff --git a/AppleCSP/AppleCSP/YarrowConnection.h b/AppleCSP/AppleCSP/YarrowConnection.h
new file mode 100644
index 00000000..a5521df9
--- /dev/null
+++ b/AppleCSP/AppleCSP/YarrowConnection.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * YarrowConnection.h - single, process-wide, thread-safe Yarrow client
+ */
+
+#ifndef	_YARROW_CONNECTION_H_
+#define _YARROW_CONNECTION_H_
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Both functions a CssmError::throwMe(CSSMERR_CSP_FUNCTION_FAILED) on failure. 
+ * 
+ * "Give me some random data". Caller mallocs the data. 
+ */
+extern void	cspGetRandomBytes(void *buf, unsigned len);
+
+/*
+ * Add some entropy to the pool. 
+ */
+extern void cspAddEntropy(const void *buf, unsigned len);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _YARROW_CONNECTION_H_ */
diff --git a/AppleCSP/AppleCSP/cspdebugging.c b/AppleCSP/AppleCSP/cspdebugging.c
new file mode 100644
index 00000000..bac414c5
--- /dev/null
+++ b/AppleCSP/AppleCSP/cspdebugging.c
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cspdebugging.c
+
+	Contains:	Debugging support.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first): 
+
+		03/10/98	dpm		Created.
+
+*/
+
+#include "cspdebugging.h"
+
+#if		!LOG_VIA_PRINTF
+
+#include <string.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* this one needs a writable string */
+static void logCom(unsigned char *str) {
+	c2pstr((char *)str);
+	DebugStr(str);
+}
+
+/* remaining ones can take constant strings */
+void dblog0(char *str)	{
+	Str255	outStr;
+	strcpy((char *)outStr, str);
+	logCom(outStr);
+}
+
+void dblog1(char *str, void *arg1)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1);
+	logCom(outStr);
+}
+
+void dblog2(char *str, void * arg1, void * arg2)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2);
+	logCom(outStr);
+}
+
+void dblog3(char *str, void * arg1, void * arg2, void * arg3)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2, arg3);
+	logCom(outStr);
+}
+
+void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2, arg3, arg4);
+	logCom(outStr);
+}
+
+#endif	/* !LOG_VIA_PRINTF */
+
+//int foobarSymbol;
diff --git a/AppleCSP/AppleCSP/cspdebugging.h b/AppleCSP/AppleCSP/cspdebugging.h
new file mode 100644
index 00000000..d9c0217c
--- /dev/null
+++ b/AppleCSP/AppleCSP/cspdebugging.h
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cspdebugging.h
+
+	Contains:	Debugging macros.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		06/02/98	dpm		Added DEBUG_THREAD_YIELD.
+		03/10/98	dpm		Created.
+
+*/
+
+#ifndef	_CSPDEBUGGING_H_
+#define _CSPDEBUGGING_H_
+
+#ifdef	NDEBUG
+#define DEBUG_ENABLE		0
+#define ERROR_LOG_ENABLE	0
+#else
+#define DEBUG_ENABLE		1
+#define ERROR_LOG_ENABLE	1
+#endif
+
+/* any other way? */
+#define LOG_VIA_PRINTF		1
+
+#if		DEBUG_ENABLE || ERROR_LOG_ENABLE
+
+#include <stdio.h>
+
+#if		!LOG_VIA_PRINTF
+
+#error Hey, figure out a debug mechanism
+
+#include <string.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* remaining ones can take constant strings */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern void dblog0(char *str);
+extern void dblog1(char *str, void * arg1);
+extern void dblog2(char *str, void * arg1, void * arg2);
+extern void dblog3(char *str, void * arg1, void * arg2, void * arg3);
+extern void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4);
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#else	/* LOG_VIA_PRINTF */
+
+#define dblog0(str)								printf(str)
+#define dblog1(str, arg1)						printf(str, arg1)
+#define dblog2(str, arg1, arg2)					printf(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)			printf(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)		printf(str, arg1, arg2, arg3, arg4)
+
+#endif	/* LOG_VIA_PRINTF */
+
+#else	/* log macros disabled */
+
+#define dblog0(str)
+#define dblog1(str, arg1)
+#define dblog2(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* DEBUG_ENABLE || ERROR_LOG_ENABLE */
+
+#if	DEBUG_ENABLE
+
+#define dprintf0(str)								dblog0(str)
+#define dprintf1(str, arg1)							dblog1(str, arg1)
+#define dprintf2(str, arg1, arg2)					dblog2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)				dblog3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)		dblog4(str, arg1, arg2, arg3,  arg4)
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+static inline volatile void _panic(const char *str)
+{
+	printf(str);
+	exit(1);
+}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#define CASSERT(expression) 							\
+  ((expression) ? (void)0 : 							\
+   (dprintf1 ("Assertion failed: " #expression 			\
+      ", file " __FILE__ ", line %d.\n", __LINE__), 	\
+    _panic("Assertion Failure")))
+
+#else	/* DEBUG_ENABLE */
+
+#define dprintf0(str)
+#define dprintf1(str, arg1)
+#define dprintf2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)
+
+#define CASSERT(expression)
+
+#endif	/* DEBUG_ENABLE */
+
+/*
+ * Error logging. This may well be platform dependent.
+ */
+#if		ERROR_LOG_ENABLE
+#define errorLog0(str)								dblog0(str);
+#define errorLog1(str, arg1)						dblog1(str, arg1)
+#define errorLog2(str, arg1, arg2)					dblog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)			dblog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)		dblog4(str, arg1, arg2, arg3, arg4)
+
+#else	/* ERROR_LOG_ENABLE */
+
+#define errorLog0(str)
+#define errorLog1(str, arg1)
+#define errorLog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* ERROR_LOG_ENABLE */
+
+#endif	/* _CSPDEBUGGING_H_ */
diff --git a/AppleCSP/AppleCSP/cssmplugin.exp b/AppleCSP/AppleCSP/cssmplugin.exp
new file mode 100644
index 00000000..f5046fbf
--- /dev/null
+++ b/AppleCSP/AppleCSP/cssmplugin.exp
@@ -0,0 +1,4 @@
+_CSSM_SPI_ModuleLoad
+_CSSM_SPI_ModuleAttach
+_CSSM_SPI_ModuleDetach
+_CSSM_SPI_ModuleUnload
diff --git a/AppleCSP/AppleCSP/deriveKey.cpp b/AppleCSP/AppleCSP/deriveKey.cpp
new file mode 100644
index 00000000..42fea236
--- /dev/null
+++ b/AppleCSP/AppleCSP/deriveKey.cpp
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+
+/*
+ 	File:		deriveKey.cpp
+	
+ 	Contains:	CSSM_DeriveKey functions
+
+ 	Copyright:	(C) 2000 by Apple Computer, Inc., all rights reserved
+
+ 	Written by:	Doug Mitchell <dmitch@apple.com>	
+*/
+
+#include <PBKDF2/HMACSHA1.h>
+#include <PBKDF2/pbkdf2.h>
+#include "AppleCSPSession.h"
+#include "AppleCSPUtils.h"
+#include "cspdebugging.h"
+#include <Security/context.h>
+#include <Security/utilities.h>
+
+/* minimum legal values */
+#define PBKDF2_MIN_SALT			8		/* bytes */
+#define PBKDF2_MIN_ITER_CNT		1000	/* iteration count */
+
+#define ALLOW_ZERO_PASSWORD		1 
+
+void AppleCSPSession::DeriveKey_PBKDF2(
+	const Context &context,
+	const CssmData &Param,
+	CSSM_DATA *keyData)
+{
+	/* validate algorithm-specific arguments */
+
+	/* Param must point to a CSSM_PKCS5_PBKDF2_PARAMS */
+	if(Param.Length != sizeof(CSSM_PKCS5_PBKDF2_PARAMS)) {
+		errorLog0("DeriveKey_PBKDF2: Param wrong size\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_INPUT_POINTER);
+	}
+	const CSSM_PKCS5_PBKDF2_PARAMS *pbkdf2Params = 
+		reinterpret_cast<const CSSM_PKCS5_PBKDF2_PARAMS *>(Param.Data);
+	if(pbkdf2Params == NULL) {
+		errorLog0("DeriveKey_PBKDF2: null Param.Data\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_DATA);
+	}
+	
+	uint32	passphraseLen = pbkdf2Params->Passphrase.Length;
+	uint8 	*passphrase = pbkdf2Params->Passphrase.Data;
+	
+	#if 	!ALLOW_ZERO_PASSWORD
+	/* passphrase required */
+	if(passphrase == NULL) {
+		errorLog0("DeriveKey_PBKDF2: null Passphrase\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_DATA);
+	}
+	if(passphraseLen == 0) {		
+		/* FIXME - enforce minimum length? */
+		errorLog0("DeriveKey_PBKDF2: zero length passphrase\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_INPUT_POINTER);
+	}
+	#endif	/* ALLOW_ZERO_PASSWORD */
+	
+	if(pbkdf2Params->PseudoRandomFunction != 
+			CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1) {
+		errorLog0("DeriveKey_PBKDF2: invalid PRF\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	
+	/* salt, from context, required */
+	CssmData salt = context.get<CssmData>(CSSM_ATTRIBUTE_SALT,
+		CSSMERR_CSP_MISSING_ATTR_SALT);
+	if((salt.Data == NULL) || (salt.Length < PBKDF2_MIN_SALT)){
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SALT);
+	}
+	
+	/* iteration count, from context, required */
+	uint32 iterCount = context.getInt(CSSM_ATTRIBUTE_ITERATION_COUNT,
+		CSSMERR_CSP_MISSING_ATTR_ITERATION_COUNT);
+	if(iterCount < PBKDF2_MIN_ITER_CNT) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ITERATION_COUNT);
+	}
+	
+	/* 
+	 * allocate a temp buffer, length 
+	 *    = MAX (hLen, saltLen + 4) + 2 * hLen
+	 *    = MAX (kSHA1DigestSize, saltLen + 4) + 2 * kSHA1DigestSize
+	 */
+	uint32 tempLen = salt.Length + 4;
+	if(tempLen < kSHA1DigestSize) {
+		tempLen = kSHA1DigestSize;
+	}
+	tempLen += (2 * kSHA1DigestSize);
+	CSSM_DATA tempData = {0, NULL};
+	setUpData(tempData, tempLen, privAllocator);
+	
+	/* go */
+	pbkdf2 (hmacsha1, 
+		kSHA1DigestSize,
+		passphrase, passphraseLen,
+		salt.Data, salt.Length,
+		iterCount,
+		keyData->Data, keyData->Length,
+		tempData.Data);
+	freeData(&tempData, privAllocator, false);
+}
+
+/*
+ * Member function initially declared for CSPAbstractPluginSession;
+ * we're overriding the null version in CSPFullPluginSession.
+ *
+ * Currently we only support one derive key algorithm - 
+ * CSSM_ALGID_PKCS5_PBKDF2, with PRF CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1 
+ * PRF. We'll generate any type of key (for now). 
+ */
+void AppleCSPSession::DeriveKey(
+	CSSM_CC_HANDLE CCHandle,
+	const Context &context,
+	CssmData &Param,
+	uint32 KeyUsage,
+	uint32 KeyAttr,
+	const CssmData *KeyLabel,
+	const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+	CssmKey &DerivedKey)
+{
+	/* validate input args, common to all algorithms */
+	switch(context.algorithm()) {
+		case CSSM_ALGID_PKCS5_PBKDF2:
+			break;
+		/* maybe more here, later */
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	DerivedKey.KeyData.Data = NULL;
+	DerivedKey.KeyData.Length = 0;
+	cspKeyStorage keyStorage = cspParseKeyAttr(CKT_Session, KeyAttr);
+	cspValidateKeyUsageBits(CKT_Session, KeyUsage);
+	
+	/* outgoing key type, required (though any algorithm is OK) */
+	uint32 keyType = context.getInt(CSSM_ATTRIBUTE_KEY_TYPE,
+		CSSMERR_CSP_MISSING_ATTR_KEY_TYPE);
+
+	/* outgoing key size, required - any nonzero value is OK */
+	uint32 reqKeySize = context.getInt(
+		CSSM_ATTRIBUTE_KEY_LENGTH, 
+		CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH);
+
+	/* cook up a place to put the key data */
+	uint32 keySizeInBytes = (reqKeySize + 7) / 8;
+	SymmetricBinaryKey *binKey = NULL;
+	CSSM_DATA_PTR keyData = NULL;
+	
+	switch(keyStorage) {
+		case CKS_None:
+			/* no way */
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+		case CKS_Ref:
+			/* cook up a symmetric binary key */
+			binKey = new SymmetricBinaryKey(reqKeySize);
+			keyData = &binKey->mKeyData;
+			break;
+		case CKS_Data:
+			/* key bytes --> caller's cssmKey */
+			keyData = &DerivedKey.KeyData;
+			setUpData(*keyData, keySizeInBytes, 
+				normAllocator);
+			break;
+	}
+
+	/* break off to algorithm-specific code, whose job it is
+	 * to fill in keyData->Data with keyData->Length bytes */
+	switch(context.algorithm()) {
+		case CSSM_ALGID_PKCS5_PBKDF2:
+			DeriveKey_PBKDF2(context,
+				Param,
+				keyData);
+			break;
+		/* maybe more here, later */
+		default:
+			assert(0);
+	}
+	
+	/* set up outgoing header */
+	KeyAttr &= ~KEY_ATTR_RETURN_MASK;
+	CSSM_KEYHEADER &hdr = DerivedKey.KeyHeader;
+	setKeyHeader(hdr,
+		plugin.myGuid(),
+		keyType,
+		CSSM_KEYCLASS_SESSION_KEY, 
+		KeyAttr, 
+		KeyUsage);
+	hdr.LogicalKeySizeInBits = reqKeySize;
+	
+	if(keyStorage == CKS_Ref) {
+		/* store and convert to ref key */
+		addRefKey(*binKey, DerivedKey);
+	}
+	else {
+		/* Raw data */
+		hdr.BlobType = CSSM_KEYBLOB_RAW;
+		hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING; 
+	}
+}
+
diff --git a/AppleCSP/AppleCSP/pkcs_7_8.cpp b/AppleCSP/AppleCSP/pkcs_7_8.cpp
new file mode 100644
index 00000000..4bcd419c
--- /dev/null
+++ b/AppleCSP/AppleCSP/pkcs_7_8.cpp
@@ -0,0 +1,324 @@
+/*
+ * 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.
+ */
+
+
+//
+// pkcs_7_8.cpp - encopde/decode key blobs in PKCS7 and 
+//				  PKCS8 format.
+//
+
+
+#include "pkcs_7_8.h"
+#include "AppleCSPUtils.h"
+#include <Security/threading.h>
+
+/*
+ * NOTE: snacc-generated code is believed to be not thread safe. Thus we
+ * use the Mutex snaccLock to single-thread access to snacc-generated code.
+ */
+
+static Mutex snaccLock;
+
+// bring in a ton of snacc-related stuff
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+
+// snacc-generated - snacc really should place these in pkcs[78].h
+#include <Security/sm_x501ud.h>
+#include <Security/sm_x411ub.h>
+#include <Security/sm_x411mtsas.h>
+#include <Security/sm_x501if.h>
+#include <Security/sm_x520sa.h>
+#include <Security/sm_x509cmn.h>
+#include <Security/sm_x509af.h>
+#include <Security/sm_x509ce.h>
+#include <Security/pkcs1oids.h>
+#include <Security/pkcs9oids.h>
+#include <Security/sm_cms.h>
+#include <Security/sm_ess.h>
+#include <Security/pkcs7.h>
+#include <Security/pkcs8.h>
+
+static void algAndModeToOid(
+	CSSM_ALGORITHMS		alg,
+	CSSM_ENCRYPT_MODE	mode,
+	AsnOid				&oid)		// to set
+{
+	switch(alg) {
+		case CSSM_ALGID_DES:
+			/* FIXME - plain old 56-bit DES doesn't have an OID! */
+		case CSSM_ALGID_3DES_3KEY_EDE:
+			oid.ReSet(des_ede3_cbc_arc);
+			break;
+		case CSSM_ALGID_RC2:
+			switch(mode) {
+				case CSSM_ALGMODE_CBCPadIV8:
+				case CSSM_ALGMODE_CBC_IV8:
+					oid.ReSet(rc2_cbc_arc);
+					break;
+				default:
+					oid.ReSet(rc2_ecb_arc);
+					break;
+			}
+			break;
+		case CSSM_ALGID_RC4:
+			oid.ReSet(rc4_arc);
+			break;
+		case CSSM_ALGID_RC5:
+			if(mode == CSSM_ALGMODE_CBCPadIV8) {
+				oid.ReSet(rc5_CBCPad_arc);
+			}
+			else {
+				oid.ReSet(rc5CBC_arc);
+			}
+			break;
+		case CSSM_ALGID_DESX:
+			oid.ReSet(desx_CBC_arc);
+			break;
+		case CSSM_ALGID_RSA:
+			oid.ReSet(rsaEncryption_arc);	// from pkcs1oids.h
+			break;
+		default:
+			errorLog2("algAndModeToOid: Unknown alg %d mode %d\n", (int)alg, 
+				(int)mode);
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	return;
+}
+
+
+/*
+ * PKCS 7 format:
+ *
+ *	EncryptedData ::= SEQUENCE {
+ *	 	version               INTEGER {edVer0(0)} (edVer0),
+ *		encryptedContentInfo  EncryptedContentInfo
+ *	}
+ *
+ *	EncryptedContentInfo ::= SEQUENCE {
+ * 		contentType     ContentType,
+ * 		contentEncryptionAlgorithm
+ *                 ContentEncryptionAlgorithmIdentifier,
+ * 		encryptedContent
+ *                 [0] IMPLICIT EncryptedContent OPTIONAL
+ * 	}
+ *
+ *  EncryptedContent ::= OCTET STRING
+ */
+ 
+#define PKCS7_BUFSIZE	128	/* plus sizeof encryptedContent */
+
+/*
+ * Given a symmetric CssmKey in raw format, and its encrypted blob,
+ * cook up a PKCS-7 encoded blob.
+ */
+void cspEncodePkcs7(
+	CSSM_ALGORITHMS		alg,			// encryption alg, used by PKCS7
+	CSSM_ENCRYPT_MODE	mode,			// ditto
+	const CssmData		&encryptedBlob,
+	CssmData			&encodedBlob,	// mallocd and RETURNED
+	CssmAllocator		&allocator)
+{
+	AsnBuf					buf;
+	char					*b;
+	unsigned				bLen;
+	EncryptedData1			ed;
+	EncryptedContentInfo1	*eci;
+	AlgorithmIdentifier		*algId;
+	AsnLen					len;
+	StLock<Mutex>			_(snaccLock);
+	
+	// init some values
+	ed.version.Set(EncryptedDataInt::edVer0);
+	eci = ed.encryptedContentInfo = new EncryptedContentInfo1;
+	eci->contentType = encryptedData;	// OID from pkcs7.h
+	algId = eci->contentEncryptionAlgorithm = new AlgorithmIdentifier;
+	
+	/* 
+	 * select an AsnOid based in key algorithm and mode.
+	 * Note we support more alg/mode combos that there are
+	 * assigned oids; no big deal - currently we don't even
+	 * parse the OID on decode anyway.
+	 */
+	 algAndModeToOid(alg, mode, algId->algorithm);
+	
+	// unlike pkcs8, this one is a pointer - it gets deleted by
+	// EncryptedContentInfo1's destructor
+	eci->encryptedContent = new AsnOcts(
+		(char *)encryptedBlob.Data, (size_t)encryptedBlob.Length);
+
+	// cook up an AsnBuf to stash the encoded blob in
+	bLen = PKCS7_BUFSIZE + encryptedBlob.Length;
+	b = (char *)allocator.malloc(bLen);
+	buf.Init(b, bLen);
+	buf.ResetInWriteRvsMode();
+	
+	// pkcs7 encode
+	len = ed.BEnc(buf);
+	
+	// malloc & copy back to encodedBlob
+	setUpCssmData(encodedBlob, len, allocator);
+	memmove(encodedBlob.Data, buf.DataPtr(), len);
+	allocator.free(b);
+}
+
+	
+/*
+ * Given a symmetric key in (encrypted, encoded) PKCS-7 format, 
+ * obtain its encrypted key blob.
+ */
+void cspDecodePkcs7(
+	const CssmKey		&wrappedKey,	// for inferring format
+	CssmData			&decodedBlob,	// mallocd and RETURNED
+	CSSM_KEYBLOB_FORMAT	&format,		// RETURNED
+	CssmAllocator		&allocator)
+{
+	const CssmData			&encodedBlob = 
+		CssmData::overlay(wrappedKey.KeyData);
+	ENV_TYPE				jbuf;
+	EncryptedData1			ed;
+	int						rtn;
+	AsnBuf					buf;
+	size_t					len = (size_t)encodedBlob.Length;
+	StLock<Mutex>			_(snaccLock);
+	
+	buf.InstallData((char *)encodedBlob.Data, len);
+	if((rtn = setjmp(jbuf)) == 0) {
+		int i;
+		EncryptedContentInfo1 *eci;
+		
+		ed.BDec(buf, len, jbuf);
+		
+		i = ed.version;
+		if(i != EncryptedDataInt::edVer0) {
+			errorLog1("cspDecodePkcs7: bad edDec.version (%d)\n", i);
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+		}
+		eci = ed.encryptedContentInfo;
+		if(!(eci->contentType == encryptedData)) {
+			errorLog0("cspDecodePkcs7: bad contentType\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+		}
+		
+		/* ignore encryption alg (for now) */
+
+		/* eci->encryptedContent is decodedBlob */
+		setUpCssmData(decodedBlob,
+			eci->encryptedContent->Len(),
+			allocator);
+		memmove(decodedBlob.Data, 
+			(char *)(*eci->encryptedContent),	
+			eci->encryptedContent->Len());
+	}
+	else {
+		errorLog1("cspDecodePkcs7: BDec threw %d\n", rtn);
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+
+	format = inferFormat(wrappedKey);
+}
+
+/*
+ * PKCS-8 format
+ *
+ *	EncryptedPrivateKeyInfo ::= SEQUENCE {
+ *   	encryptionAlgorithm AlgorithmIdentifier 
+ *				{{KeyEncryptionAlgorithms}},
+ *   	encryptedData EncryptedData 
+ *	}
+ *
+ *	EncryptedData ::= OCTET STRING
+ */
+ 
+#define PKCS8_BUFSIZE	64	/* plus sizeof encryptedBlob */
+
+/*
+ * Given an asymmetric CssmKey in raw format, and its encrypted blob,
+ * cook up a PKCS-8 encoded blob.
+ */
+void cspEncodePkcs8(
+	CSSM_ALGORITHMS		alg,			// encryption alg, used by PKCS8
+	CSSM_ENCRYPT_MODE	mode,			// ditto
+	const CssmData		&encryptedBlob,
+	CssmData			&encodedBlob,	// mallocd and RETURNED
+	CssmAllocator		&allocator)
+{
+	AsnBuf					buf;
+	char					*b;
+	unsigned				bLen;
+	EncryptedPrivateKeyInfo	epki;
+	AsnLen					len;
+	StLock<Mutex>			_(snaccLock);
+	
+	epki.encryptionAlgorithm = new AlgorithmIdentifier;
+	algAndModeToOid(alg, mode, epki.encryptionAlgorithm->algorithm);
+	epki.encryptedKey.Set((char *)encryptedBlob.Data, encryptedBlob.Length);
+
+	// cook up an AsnBuf to stash the encoded blob in
+	bLen = PKCS8_BUFSIZE + encryptedBlob.Length;
+	b = (char *)allocator.malloc(bLen);
+	buf.Init(b, bLen);
+	buf.ResetInWriteRvsMode();
+	
+	// pkcs8 encode
+	len = epki.BEnc(buf);
+	
+	// malloc & copy back to encodedBlob
+	setUpCssmData(encodedBlob, len, allocator);
+	memmove(encodedBlob.Data, buf.DataPtr(), len);
+	allocator.free(b);
+}
+
+/*
+ * Given a a private key in (encrypted, encoded) PKCS-8 format, 
+ * obtain its encrypted key blob.
+ */
+void cspDecodePkcs8(
+	const CssmKey		&wrappedKey,	// for inferring format
+	CssmData			&decodedBlob,	// mallocd and RETURNED
+	CSSM_KEYBLOB_FORMAT	&format,		// RETURNED
+	CssmAllocator		&allocator)
+{
+	const CssmData			&encodedBlob = 
+		CssmData::overlay(wrappedKey.KeyData);
+	ENV_TYPE				jbuf;
+	EncryptedData1			ed;
+	int						rtn;
+	AsnBuf					buf;
+	size_t					len = (size_t)encodedBlob.Length;
+	StLock<Mutex>			_(snaccLock);
+	
+	buf.InstallData((char *)encodedBlob.Data, len);
+	if((rtn = setjmp(jbuf)) == 0) {
+		EncryptedPrivateKeyInfo		epki;
+		
+		epki.BDec(buf, len, jbuf);
+		
+		/* skip algorithm - just snag encryptedKey */
+		len = epki.encryptedKey.Len();
+		setUpCssmData(decodedBlob, len,	allocator);
+		memmove(decodedBlob.Data, 
+			(char *)(epki.encryptedKey),	
+			len);
+	}
+	else {
+		errorLog1("cspDecodePkcs8: BDec threw %d\n", rtn);
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+
+	format = inferFormat(wrappedKey);
+}
diff --git a/AppleCSP/AppleCSP/pkcs_7_8.h b/AppleCSP/AppleCSP/pkcs_7_8.h
new file mode 100644
index 00000000..669ceb0d
--- /dev/null
+++ b/AppleCSP/AppleCSP/pkcs_7_8.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+
+//
+// pkcs_7_8.h - encode/decode key blobs in PKCS7 and 
+//				  PKCS8 format.
+//
+
+#ifndef	_PKCS_7_8_H_
+#define _PKCS_7_8_H_
+
+#include <Security/cssmtype.h>
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Given a symmetric CssmKey in raw format, and its encrypted blob,
+ * cook up a PKCS-7 encoded blob.
+ */
+void cspEncodePkcs7(
+	CSSM_ALGORITHMS		alg,			// encryption alg, used by PKCS7
+	CSSM_ENCRYPT_MODE	mode,			// ditto
+	const CssmData		&encryptedBlob,
+	CssmData			&encodedBlob,	// mallocd and RETURNED
+	CssmAllocator		&allocator);
+	
+/*
+ * Given a symmetric key in (encrypted, encoded) PKCS-7 format, 
+ * obtain its encrypted key blob.
+ */
+void cspDecodePkcs7(
+	const CssmKey		&wrappedKey,	// for inferring format
+	CssmData			&decodedBlob,	// mallocd and RETURNED
+	CSSM_KEYBLOB_FORMAT	&format,		// RETURNED
+	CssmAllocator		&allocator);
+
+/*
+ * Given an asymmetric CssmKey in raw format, and its encrypted blob,
+ * cook up a PKCS-8 encoded blob.
+ */
+void cspEncodePkcs8(
+	CSSM_ALGORITHMS		alg,			// encryption alg, used by PKCS8
+	CSSM_ENCRYPT_MODE	mode,			// ditto
+	const CssmData		&encryptedBlob,
+	CssmData			&encodedBlob,	// mallocd and RETURNED
+	CssmAllocator		&allocator);
+	
+/*
+ * Given a an asymmetric key in (encrypted, encoded) PKCS-8 format, 
+ * obtain its encrypted key blob.
+ */
+void cspDecodePkcs8(
+	const CssmKey		&wrappedKey,	// for inferring format
+	CssmData			&decodedBlob,	// mallocd and RETURNED
+	CSSM_KEYBLOB_FORMAT	&format,		// RETURNED
+	CssmAllocator		&allocator);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _PKCS_7_8_H_ */
\ No newline at end of file
diff --git a/AppleCSP/AppleCSP/rotty.mcp b/AppleCSP/AppleCSP/rotty.mcp
new file mode 100644
index 0000000000000000000000000000000000000000..96f2ec0f4918333a8e71882d2daadcb7f29f33eb
GIT binary patch
literal 85911
zcmeI531A#m{l{lEX^vj>qAi8eZGn~^BrUY14Oi3jN=ayFT3QO&Zj)`BHpzx$Q_5W~
z1w;h|1r@E}4IY0~P!#_aK~d2^iijd=K@b7u5){w=Kfm|h?9S}Ykw}Cd``Yik@4ok&
z-@NyGzu%iTvzwWwRI1gotRl;@kF@Ls$6EHnwU*U?4rOh2%qG*RCe@r=mFVnjNp;2>
zI#ZjIO=+iUKgnYQEh`qctVN3~YYBap&(=Cin`nc{6O_#Z^FbFl4{QgQf*6<vDnK1L
z88m>+pdOq8W`P;t7%&&i1{1(CPz#oV$zTAO3JwEPzzEO?q+ts|KOpVv4~_zrU_6jC
z2pkVi1FOO5U<<eiTmmizX9F4F3&8oH6)XoE!76YeSO8W6vA}U)4X6TbpdE|?X8?T5
z8Vs<TwHTZVrh}uwOd!5?EI0&=1}A~BU?NC?VsIjegM+~dU>q0&y1}8~9Iy=>1kMGM
zz>%N?8~{qe5YPh71ZRPAFdS?G?*P>R-?wT&608FWupSHrO`r@kgUi5Ha3B~7Hh>kN
z6C4hX03Bc$c&pRp9B>Cs{k3)hOFq-mFFXz&8aR5`j@xxb5vAfID*wvuRWI(|{oI2h
z>P}*~LfX$QAQ9ew`Lbo=;hEHL@$!{2eMu@VZA^7{HYH`svlrFYEo82n=Bh6$U!LsB
zNLa3#{=*uRP2HU>>2u?CE$cfIoh?d9u~9PB<daQ4#pH393VU$%DUG$B-Q7os4XRHx
zd1{>&j=yHcH3P1h`0(VV8|Qle&A7(>S!UCVcS}F>wl<~#Z0WI>i6q%_KHDUx5F%lw
z=A$^GB0f!Jwwm{(E<b67YCGR5Q-@JnVY*7n%m)evnNo`mFG(hvlbu}^GP&g@vy-UM
zYLq}fX)j62Y^xvVe$Dx0q@+^sQL206*<UG9dn*}c-UF5<wkB#?6J1@&u8Q+oWIpty
zHMI@#rPZfZQ&^1VB6S$qfb#le=f-4wS+|^p{)2Q9sk)(|PBp%GLEYljO<P);W#zJ}
zv7tuH4`kbu6fLKk?yE{$L|3_`+~rw2%8|rTiUD4y{6(f<Iq%5%O3vqU?iUPFvp3|;
zCJq`0<H2Mw1xy9gBv-oK?e-qb-3!D;Fx8A*l_RN-s*o;4mw7ekeiGHVsL`2QyI*}S
z)d6X*UE9*$l5R<~ww#yjr2*Ei?Mf#s*>wJg0mcE>u1zO9+gjQa>E0ebZ#~tswN&rs
zl-@}f7COCjp?y!hzOi=U(AsvKx;>eWFWlDAn(9o-ioO@AHmP^3NN($OQ1s$31<^g$
z0>LNCY?HIgo#H+?p~YA-$im>wCuuwAm#9dEF1+T+p=6CB8<VfJueHl#a<jlm*<SX<
zCWQ&uvD<!|7bf8ScIf-C<NNfKx(}Z&3MYU*41&E=RpA7%caGa0)#~|)u9l|w3clD}
zpV}6$?`}=ESc_UZyVCK-<i@sSd)lhf>sxL($7|a<Ql07e>^Ub}^$n}sALl1pTT`j_
z_>yF6hgH8SUQ<~!b*dIz6>ms%H6>crr{&4>tcHb)yt}$vFni7xtI9M7u9nucv8g4~
z#s=<4dRr|euI9<dOcTrp(**ehs=L~()iui&W!j<2v(1u^P9xx|5sfXat>;QNyDFM2
z*N4uo&L&G;2X9C;C20mXl+&A3-dGo3-rb&VX-kR{r>LgF^J(hT?B_(&vc`(mtO^Vr
zUz9j<W=rLq=E)faMkke-qMC|~=vucZgWyx+wceuY6;@UD2C~y{idDaJ#=?AbtYZ4=
zfAq%MWh+<9@iXnzB~JgHL%GMCx{T>n%e;+UuyFp$#dy+|92dxzSNZKAT7$~D|G%s;
z<6X2CYj}zr-8g+fx$h2gOurpe54{yW2hHC*zeJCmr%h6{IMJ4rUm(P5Qtexlo!p_Z
z7PTg~@k@kcM`w!fow`z;*8G+(!qrn$kH2b1I`Zh2th+frlr7Z$En}W3lMf4$>$^9`
zJw20P^DP(oMcfQ+^^x~0r(Zde)g2wJElr7ZOR8Oh-+URy(OutO<$Tpu<qF#-%l%0O
zan<~m_9|@znyq{`TjUB;Gukz&wzgDzl_&JQRnA0EWg^ze<EU2$%9$N9NAre>wy0RL
zuBCkoqgm74l}@$APfnhDPO7uH%c^dYL1mgvZ|bsEB={;wX76;mrF~-;lX+_r({*&H
zPxHH5TAR6Bm+nk-S!%#GCOhMLA4^Z#^s9q?IE<RZ`5jBUR<xplL$oJbt=i@BWgSdw
z+)3}W%*>kE%Y4r4ChZn)T%2sz-q6w|-*L6AmqWNZC6qIRDsp}^Lm5-GIVz_P6q&Y(
z^y1dkdK@U*6#cbod_`xHuSGMRGe))=lAWza6=w(eWK}gacO}+#r(0V2W`KP-OSP^~
zG;OJ9>gceVy1LZqPJP&@jwKydA2%i1n_H8q_43OeRnV4dZcQcl5>b81XjGq?Qrsoo
zrsdL`I{B^<d#akMswx?fbd_ps72R&`Zc2CMHmim^tBX?I?aj*Do%6_o&QwQjyXl?s
zR=yl|IxB9R^)8%uL0z5YEzA@(%Gt`Tr)SNID+|eaze#l_ua!FRtqqAS$&S|UjV<lk
z8kpS5v3t+~on5uORwAdzAo<QzI(@FCw(3}W)Jm(+n1TiNNDIjQ=K1FPXx%`4Q|Pj<
z?0DrTyLVqLKd~#M{m}yah+>pyJr~ceg?ng^%uh=!d;990J=`foO!Q@{^S?!*%HE!-
z?;BF){C>x+uFN?%nWclfZa?9B+^u8hi!;7s^Zc4>b0Y71Y56r({i-$kCwcsU%d-2a
zWdrLJJ)m)Qp~*7S8BAHSbZu%~?|gpCa@*tbfrn)R9|(qn!QcQe1dISf!2~b~IKN$z
z-!G}JLABA?7Uf(at9wCJxz`%rt7t9bx&H7I$h{`<lgYVG$-gb7mdcrH7e5tpQR!T2
z1l2EaUw#A$nd_{eYUlFAuRiA*Dp(|Qf#fT)sGiRF4v6RC%Wq%#9ijXbu!Aq91M9=O
zpcI@|@4K@;8|b@5`eM-U5V_ZcAu^$6kgL3~0hRj50TrQ;0hMaG?(}V=)S18E2&m6q
zpZW=Su37yAR<*P*mp+=yT0fC(b7qGcLFz;LC)G|LOwOGb?g`Yjbmck-_thc-UL-=o
zU8=)_T_nOnUFtnIDZD0;>fkVUYD0X&5%IN{Q|Z_%|Jb47ExYI3H1W~k7uvFCNMK8K
za9C$*gPZLi(z0VzK#NRxIJ+bQf>}urO8%kj)J6<iU>H05=Ld17#y5mbZBPJ9bx8P1
zb!hO4Kyc_fwSjKv4qKea`~8Pskmg9_25C;UPmtzF<OOL?eQuEERObY#Pi^ja`-o(%
z<5TJK_MF=MAoUe+duy&hCP;HCa)UIdIwwf|YJ;2Y3eub%eS<Vd#wSSqB|^F_G3E-=
z-2JJI7&LE?`s{Cl)UPHRr1`a;AkC@H4bq(I{2<K{$O%%P+CVqV2~yV=sTjg9NOL4|
zgEXhwCrEQ7@`5y{J~v2ns&j(Wr#5%IeMGX>@u_rqdrobBkopR^y){=L6Qns6xj~v!
zofD*fwZYAH1!>NXzCoHJ;}fL*5+U8r3DVsCeS*|SByi9~d;XbJ+*#FRgEU{MCrERu
zbAvReIzLEr1agAZr#7%h!9mKGiV;C75+Ok<)!{)Z5@A6q^&vqj)xkmP)P@A9BjRfv
zr_$fsr8YE3vjPF$ss#LkR4PJ(RH}o6G*cVgZ2usY9ixI&WWs~gB@xo?;2>4|hX<)6
z5;$o7LF()lY!~(m3R2lQBuJ$?G)P4tI7pq^z#at$sdL9U>dG`L7ZR{pq42QH%7q1Q
zRw^WfvqHgv?3D=#XRn~IHN7JKzL1p(4e(sC0DpIh`2~BnIwa(?LQxT#l?;#5Jh{l$
z2gj^SS9s)l1tZ4CKZ?C7qQ);IqO*!Z;#v!#CE`Swm5YonQPz{_61nK;5~;}O5}~N*
za%3W-%MlD2Jx3&LbVQ~H(Ulbo^-m=h99>c!8C@dOv*;4Zo<x^RF0%E=y00x=E4Zw0
ziA;~iM+76rM?~@$vfg7wjUPIK&X-w5p6Jr{b$(8ZPv*r{zJw>D@~d-WDPO`HMfvrf
z_{pz!M~;83XH5J>%xL&mI(E*l&54j8fsA+g2<WKDukge}ezh)ff0L0flN$qp5+Usq
zKXmS?`0StS@%|!#)^)txf45+}dptXT=MbOPjvwvWS-BAZ&I*Nlc~&mW*RxU~9-kEo
z_Is~Pi1&L1eMiYF;y)r;nb3I16$|h>mzZB{WUE6WBrBwyBREd7lHt*kCl}fJ;K*_5
z3XdPJV8r<N$C6h?)cA$ORaQ}CbfG2UyrGqeTx4{KP*0*u<f5ZXq#~nBgrcI$k%^2h
zM=)gc9Fefm5t$xDS5_?4Kb2T;bV+q&bcs;UqDv%u5?wC2$krnpa9+y#mdNyId_*u}
zd_+XnW8RaE_gGQmhmP!eEJ#sEbg_R#T!}<TL`ijcEQv%|6iIzZ{77|h<T$k<W8#ST
zj)qg|Z)d3ujgYKBfOjbYzo?Lkka&>ls7Mf*@ECAOgtQN-0KZrJhkLvu5@=n~p6}((
zZozg(BFM94=MbNkTWh&L((;CeNQC&bREPVtNQC*c)Q9-AR0sRCQyb#bj)<?-ol1Y(
zN^Pi5X9WU$MhW=&v{Z!nv{Xm=w8(_}v`ZqSed2Zg*BEO5aG!QW0<A0B^L^UcE!gfM
zJ}o<k_;hxuWd2M|{n?S%tFtotkJ~~;+}|bysZlciy~!TS`DP(VNzOg;ATjry@-P|S
zG0C>Zeb?MijZ7U;78IEX3yMgT1v4^X7R(6o>%yS+_P~OoCdz`2Oo#;?5&sr5V};mG
zY6Gn%mBIGP)CM2d-^*mjQ0s_5uw9&5UyC@E{%sOV1^bcI2HHX@gKd$i4L+{FEo8?~
zTZllgEu30kTR4?Yo3M@kQ#S8kpyr)*gXBEt-XNjeGjNcc_dFaV<vAM%2}!wg)(DgF
zoSDM}jWxqWB5kVv<}~wr*dSH<l%6>w28!wPc2KqF>>VWJcHU5#sIEDV9Hc}~i0&IL
zL6W&kh6uSxGvV-&jvz8Uas&~Ka0C&N1w~-HrQZC~Bt#~=U=9-UEHQ$Fa;A|WG52H=
zCKJ(jQRDPY*);!;=JO_&AUV&(5+sy6u>{F^Czc>7&%_cWB<67@mM|HQKZOYzn}&%*
z+SEI-1gXlISOUfL#1d5PnOK5^+!ITvOjOsLi6ux${=^a_nLDvW$Ymy$Ksf?A$`RDQ
z?mx;2Qx@R}va3uiVJf1m$-dc%B}kEHVhIw;nOK6v+!ITfOhn(^6N?0(&r>w=CYB&M
z&%_cWlsmBm$$2N1ASutp5+o$$jz5LTcqW!GLDyvMXD`{+@s}VqId>Pr#WE2SD3)EZ
z_%+Bgu>|RGPb{G_QC)K;mLMhh6HAa}?!*!y7ilJmlPE_}vE-gu0uPF^2uBcI&Wgov
zTvWYl#S$Qsomhg};+a^2gmNa9ATjsE5+)PTclX31{q*Zw?hVKwInTrrB$PX`1j%_P
zmLMt5#1bSV=5hQfOvW>@gbBJPYd?F*@to)jQj;^Wgo|Y&CQvN9V)1K`XJQG`;htDR
zWum&~Oe{f4@+X!c$=r!0LN3xwvVW8#h)j<hK?EZlK}4Jti{H4YdNZ*I50J@DEI~q^
zi6uxVXJQEwb5AT`G7)`uPb}OJj<~y$FX5R?@~d;Fk$eg71d?CxnL6^T-IIoYt;b9J
zMU0L7E1fvXug#epf&?=D?jxWlg!~H6RFGfoo&*AFgPZLHe*TX6A)hak8|;A+A>9^#
zbpqUHe`+HJO%wzUnp8?S`)dxi3;Sh5IDcnP@a9+Ngl)cnJ7E251AF8SQt6$~L;m#r
z-MU2k#_q(%q`LU>o2Jy*d!+nyWggq6!#D6!Zc*lGbYZPpkZSUrXZ?;SJzTi0DajM<
zQtk2-J$b~PDD~@vU-SIryv_5I5Od@<&rdF}d47G7DJk!<ctHk|a$jM;W&~>X6Asku
z*JkAx-0^MWnR*gg+Jgcm^+b_*ykSu1#B4q8oPQJidZr|On&2lJ*aW}6d7fPu)G4*2
zJh0Ju%wLe8>sf~);@7&o1NsU19?(zFb-=(U)D$ZA4hz^;XL2J=Jsj|qAe9!fE#e8t
z3&`cQpvAFSUyGB!8}ut(oRs%s-2qC{^(lGH=tH11y`UvQ{t75-R@@!}FNe1BoUZBc
z{!m_9YRl_b2b`m2<n>kqP5E{3LEF-UYLU4UK6tA<lG?I=3O^v(nrwpq89oFxv^gfP
zFCA+5Ech^eteCvEb$D$$$?H~Q7s5xRQytatTi^#Kt6O>fQ0zYV$W(hZZHqk#AJweO
z{{<h-(@HsR(OCFF+tU59N0Gc{bxd>FV)iYPSD_x9OfR6FMVG=4S-}%O;kUxarU%s1
z$D(h;58XI;fyj&gaq<#KxU@gs%~M-3tGpt0Jbl^@p9!DP-kfZPp9Vin9@qjG`y3vd
z_3D@4H^Pqqq~b5LnW(5${B!b2hKv3qHSZ^{W}OV;4BOG<Q`R=|AXuwkBYbLX*6$dT
ze)ON$EtWj96E5R>l=g>ypM}focuD=_)u)x(ANoB7pRWC(gx82!GqgXH$T5%B{!p?M
zevI~ql1=cL+8;_p|13R5C7*%M*5h6xV{xqZhmu|JIi_4*EIC*EL#e#Vwo3a$sXP<z
zIPDLmXTguxK2R#J6h6W5o8TwvW0l?mKS}#T=`Z2)v_F*o175A|UnZ~5ov;0&OkUMn
zqy3?5HGF~ghcbDC4^Pt-e<&0Ei?lzK-32Eq#2?BYgD=tkQ1%AAR{KM_jKxyz59JaI
zCu@HwmscCtX@4k}*8|ssYYCfokxLymF29|88L;6$B5wdZ&a3<-@>2ot5bQsQd^zBC
z!u>_Rj4{XTFZx!15pap~m4Md|_rHQ%{456l1o<k!Yli!OhkSK^732M%h7(K0LkL&o
ztTpoNc=$N@8S?CS_z7&zlxN4oB`(gg<dL=3fQ#VoU>zYcJJ_t1N6Eu?!q>^O<Ke%B
zC$#+sNZhTLH9ylq9Nr|)j)#l>W_b!d{0w+9HvWr$fXnNbH^5(p-vZxgxQxXn!ykpW
z#KwP#Y@o!&X813dVur!Dz#oK9gSQ&a@vJt(JK^ny-vCb;ekZ)caM6FZ;jh9wH6J_>
z-evd{cpA=e2jd@Bx8a-MTjAJY@Kx}0VzV#mfPWgk%_>Pg0ly!9t~{m~{uKPY`MYX%
zF%=fW&tI~uR`_A?3r^X!OgMgNUASV`O5sWPMQe7QA^dXq#p`w@gx?C^zG2r!;Sazs
z(e^(;^k1sypCM4|GCltc84tf)mgh{n^Wj%CrQ-|WG8XTYg&ADp?p^W_YWPj?E0c|h
z4e-0+(ziJLC*)V_`De)M@OSI^XDGgCU8Copp>yHy(euwx@yGW9(ooU=K0W^o{UH2W
zJ^u{-ANX~8{u%mz@ay&bGxSCH`}O=YOyc4OJ^u`=fZwR+gkg2?59oPjm^ktW_53qT
z;_fC>{zdrBdj1*qGx&$}{4?yI@DJ<xXZQs8NA#RCd@=kM!?(acs*g2X{O4nO{uwSd
z*`ep3;lF}^9FXM6eb%jtS|cWt-)1=eVSU2zHu6szE_V2o;r~l6enT4ZESt|LY8^O$
z{IiD7B>$Y@Vq2M0NC%$7<_<-z13ygudBb;-f5Gr)$i)_<kz!8?DALHI*~l1>My_Ea
zu|XQSoz0hp!KJ-lQPdjwee$mw{wle|DrwY#Y{V|4QQ`w%Q`8!@j{NI}%edTQxb*uQ
zhX0WKn}&;D-K+WNvE<(}d?C5mh%{QpdZ#e>^=!Vas5M&Jb)Vsnl7GkWzmeas`9X3H
zdcg1+^6wg+B>$e_5^E0{F71>)lMWKuA1G=a^bEPQn>40~%|nV>V<wXS$Z*mBW5W~V
z;@_k(m$G?SQESX?<Puk;F=B(CDr$`pzk0;*-Q+*h{NVBA(l^q<qW|ZLS_g~%#|)SD
zGgnDE_~UGTsi<|Z*!ywArA&@NI`|DXPbg{~GK&1yhMz?K8^fE)e{1+P<hu;Nll)1;
z<@iq-{txosX+HLF@}~`7OfI$~jorfL_ljC$WgMS1T>Rw^hD$%5GyGrV&uf0@B=Q#w
zUq=2%!_OiAli?pGmwAMA=>2S7Qq($Bj`OnS<4Vb2F?=fdtA;m_%lU>huA9wkidy4t
zA%ER)@wLAgF75iO=J6rqVpCFl78~(DQv7r_e^=Csiw}s6Nbygyk@<)e7hjWplH$_F
ze=BN@mvIq4AdR1`mJynt0k;*k#$N%C8O|JF7a5Mf*u{p^7Q3J36DGh*3||NrTaYFs
z;bn$j1ur+8xy0^oIKF8QFdTc>12sQv1YG79(qYoh!G@m(Kfv&AxY&qv*!$r_4ZjOM
z%y7{^+;GOnMz5s9skaX_{22I1!|UK;Bhumcl|9<<_rVV`{D0tM3>W<e8!q|}(fkN$
z|5(Fkz-7K59dR;zoZ&6-xZzjA#~c1>I5w4Z1mkEQW;niVOAL@EVn6!`!>7Pyz93Dk
zg-<ekBm79iuZB-HT=cV#q=^r}#b1RJL-sVyCzZmFGCU5iFq~MnD-CagPdEGuIQ^6~
zN%S9Wxah~ek|s&}XKH?AKlm)ev4_nVOFHrd__2nc37=#5`S7`he+*t__<iu>443vF
zulZzr%0`!@$@I@Y(eUMP`XFiYR`@(ct;sjTs|~*wKHqTWB)dlQDfqs<z;NtpFEqR!
zzR2)4_+rCvfG;upYjDO!(v)Apmm0nsj!#IMioe+SpW^h-Mz7+l;injW4t$y6*TEYM
zzY~6{;Sa;<r=+QWf;VbDO>DBlaD2gDX*g}SPcyt3zRK{+;2c}hv|He(8~!c$8pEG}
zpJDjl;Eb81qlh8<EW@$4{SL!L|60SZfv+=M+Mh7|G5C7J{{hF(Bvl*^XMe@9v7I!0
z3w(p&*TXj&{&n~!!+!y9G5lZf&6-ydb2j@+suVl48je1jv6NJKExg@u8ON02yWky~
zPcMd_ZTL~}PQw`=yUTE7?X=<I8_Zvlrb|2VMa6#uXN)DykQmu!xQy4ihT|jld4`M5
z^9{cVeu3fl!Y?%Z8Tdt-A1yv`vEkF<+YQGr>`M%1Kl@U{cfj!jNk`ugzufQ_;8$pV
z%rN*n4QCFp-(@&HWnXDH?X|Bm{9|zDBT2{nFZ|txKL^JrB+VQOe~;mF;qNv4EI4zq
zq?sJkzSi*1!ml&@`*8d~(oFIH_iH{&+KJsI%{mr-qv80b{Q<-2xBWrGKMBXCl4gm{
zn+<;j{vpk0kA#2N@Dt%5F&sa&Z!!ET_(u)@Je>YZn*DS54n?ime}jKq^JB-tZ#8@Y
z{5He!Q~MK!V?UerNjmn6@J|{32>jEAzXAV@=5t2Fv5}-X^WmQ}oH(#=HyoSUcNl&b
zoVH4u^IP~AG@l!Tb393NC&0gC_#*iK7%uI+({RSe{<7hB!@pwqui#%b{NHenC#gzw
zBB%IL_}2_4=IpN<&iL5(7=ADO8-_mx|EA{0mB6W!bX+C;TZS)(<8zXZ+X~;QsC67;
zWq;f7`{DN){yX@0G(Wx!PMxIVr@<dE{8adN4L=+HJ;U(}`$5CeVdF!Rj(-9E1I<r3
z0RBV6=fEE_{0#Vy3_l<KW5e+s`~M7=c0O$QbMT*Ne&P`LPYs_5$0sD6xC;I=!$s$#
zhD+b^MM)=OKl?Gme*^!8;W9?Q)cmBe@W%~54*n~{-vNKZaMAy3!-*RkU6M{>+-&?w
zarU!!8U7mlNzLaChclLv=FNaJ28uVppEg|l_8G&O8|>d3{w4UchGPT!4~D-C$3~K>
zMgQ}LPlq!elB&hu{%H6nICF=j>UY6kH2hQWmkei|ZS+d2rY-g>nyXi;ylQxy@;@8C
z2u?pG&2NRjZukxGzZgy&*nc%#?Ei-5H3Q(x5t3?-f&bm`mGFNUej)syhJOzJFT)v6
zoAHyhpcuZ}aBLgX)LOvU#cWf4CEQdj_zJwplrugt_LsDf_Qd)bek{Di@Md_a;a9=S
z48IdzZa97y>u)&yh@nf;qQl?=HQ(R1vi6ZRkF0fMjU#I(dmTuE4PYZU6RZW|n=N27
z*aF0t+CV!<fevss=mcFL4Y~niEb9zeU&y*b))R7$l5>-slk6QpV)Y~7<KR|s8@LI4
z7<>YJ5=abu8hi$P7KpFi4(<S)Gvr($=Lk7B$T>mIm2y6i^MK6%YTlpE2-koGU?DgW
zR0CqfS`3ze6Tm!B3zmYDK^>?Er+{Uk0h|h!gGR6d5EJTt_DSTcz-n+hSOX3RM}Uc7
z5{Lu*PJK@@nS2Tu2PS~2U>Z0IRDen_9S}Fx(SSI#W`bE@HXshHIbb}P3#!0z;CO&d
zEo^OJYYSUj*wn(N)((KJ)&0H?l4C1%zYklh`+L}0-Ot0;>i!+JR`=_$wYopYc&Ynq
z*j3$6WByS0=dicBkM=e4uLH(J-JiRM{2Sn#;9l@8@V{Uu_%^r?d<WbQ7(eSGa52~p
zE&=C(3&Ew}GH^LK7hC|Y0Ph6v0#|~oz}4X0;2Q8A@Lupfa4onFTo29%?*})48^H%a
zKTrZnK^d??F(?Q9!2lqs2n+;+z+i9y7y^cZVPH5I0S*Ks!6+~q90X!u3^*7Z0>*-M
zAOY5cCU7QL3z|U^Yyf9~cYuvx6KDaO!4}X8+CV!<fevss=mcFL4bB4HU@JHWY@>U>
z1doGXfhWMD;1}T6;5Xp6;Ah}5unRm1o&vuEPlIQ`@4>U+58yfQJa_^85&Q}K9J~l#
z0xyGCIQ9>~55Ys=N8r1ZFD3sz_%ZlD@Gy7)JV@Qi<Ub*=1NGn(KK~Rv0%)JQr^s>C
zJw)2C?itcAb&v3S$S(s8;8d`ja{8g}_0bP?Z%_I=2fho?Cv{(sKB@bPVuQJG>0cE%
z4jj*C`l{~d(N}f<j=rk<b@Wr+pOb#R3dD{lfD^$<U>;>}fWLvigMWb6D6b~}EBGh)
z7x*{$Gx!U2^T~IU*MJ3JA)rX^oyk2jxmPCl$mHIb+!K>~VR8>l-TQi-d=Xd-mVjC?
z5ljL{g2`Y4I08%oQ^7Pa9vlvi0u`VVOb0W-(cl;`6U+j$!Li^lZ~zzrhJs;W0B8h*
z!Ei7F90>Y@L0|<K308vBz$!2bj0VJu-1CxqU2>00?rq6EExDIv$H73b8k`Q+fHT0w
zU^~E$a&0Nslya>q*P?PwDc6#64Jp^MvSyIAkzBLNx=5}kF{foSZn7?sYf8D6lxs*?
zE6MevTsO+~qO39GT2ZbMWz8ekhjLvg*Mo8$DA#|oK9Or<x&D*uK3QYQ8b_}C<a$r8
zA>`UY)=6^RAlD0W9U|8ma=l>h1m6aCv7gurzme+^S(C}Nf~=8bohR!fxn7X#1i3zt
zb(&lo$Tfjn3&>hWt^;KKFY7Q_`^%bN*7~x>m$kjDljOQb*7mZdm-U^jwPa1N*7Df>
zzmjaegWQE?{6ZOD4l)50#m0Y}wy56^6vL;(=K$I?B~88<U|*G1uq};^zjX+C0+d-L
z&(aq)7t$}4y4Yevl`dsF0Qm-T#)i4P<agLfeb0qYs)Wte+%6xa?f~SslRpNASS2s*
zB7YhTy?A#?2RS}t4SPYKFBl&=2Na2K$T3IgzNmY-_`W1{Uv#A5v&lylz4+kqlrMsh
z=2#EI8{r3mC2)M3^9H?#x3f7|7##mn=MmxfCFhfpvGd>`fXkRkJbsaU93d$&iQic9
z2_*RA@bTo^!E5jd)}b<|sC6~5EGfo5YW;E~99h;e_Bk!^>F|m4mobQ)1fK**vDIvl
z{S@`F&G5+}4wrULnKOM3eT`iSpK9Ipnv{$Er|sVTSNa&+0Y3`F_>Z5f^$$Ic;g42j
z@mF6x6aGA$-+%mIr??1w1}1+QJ_3F;AQg#@V-&TD7Lw02{2k=84BtvFb|)2G#pYPr
zGY|d|_#E0Z8vX_NTyO+@CwUdXZbgrf9|!1L(eKHR2UFm0ke>iJelanp)|c3!SjItY
zM4O7GUGo6PE*2lI2BhM(Z00L!6`w<1V>t7QTCb87f0~W-hg2-~5nmw{Kfp$Gk&20B
zwT>13Yc{ojRQyLaOBJ<>nIF`;maLz&vrd=ylXlh{F6}(UaLJb$-b~(LxcJ+thTlfM
z-0-iEHyX~Iq}In|{bU?hn(`;fPc!@_@>PcalU#g=R5Fmw>55t<;_qt=$JS~+L{=hW
zi(g185nG<6s8u5ElJO>$B-n_3NhNJ;)(L}O#762!CE^3?6}3vPBX2VN7INt`spNBP
zl8Ra-cav{0{2}s<hX0a$li|;kw;299`DVlaMZQJz(m~{{hL0ha_K`{_v5`0@m5QIH
z6tzlaoI4B`Tb^yWw71i6k?k`4Lh`iXpCIox{4VmXhD-a!=SZcGvDv1mRr*Kra}D23
zexBxKBgoG;Tzvlm!<UlF@knK2OR+DhOxk#{qE?w4bGzYJkY8f>r^qig{Hx@b8U6_Q
z<(e0^eQJS$EF$}<>zk5!a-Og=UvTy5VG7FjP7CZN;TJ3o@C)y&;~Uew8@`F(*>xs5
zd6RwB-r2!ItN$Ylh+nWHFR{(|Mf1Y;tu39Yc7BDKo?F$J?p}{i<d^(Mhb!!~msr5~
zMJ&WG3bV#uGM0VWOyd_tF26`usXz6p;!hNtyPML56G&g$dvDNX(@61)d2)|MpGTG?
z6V1uaf-CF|!}nipqw$LYuKB{dzNo2fZ))vsF04EMtHZFzDK~yGkh_DndDd}bcSlF6
zGhMj;*y9H4EozYKJW`_lqOq>ZIw#q=r7O-wYI}2{Q~t_Zu2avgs&A}|*A#r^EgG7)
z^)N2Ku;p7H{WtXT$LZ$L6K`wl3I{J(;H|Ylz>^!^+D5#cN6X%;DqMTMo#U{l9J@HT
zA#%njq&H`QwQIZ533+hE+m~!sfemuysQ$fu?bsuZJYrJKvIPq##V0MOUQtcfP+PM?
zzE<8}Qp~dA^z|J1Ef)!&C{iSMgWPz^w)Q}dUwl{>_dsq6a@%_#Hx;={dmuLrxy!S1
z{<9VR=&3$&gA23zJa)+_N8g?<7pEUR8Q(F;bqDm9DsPhCK*`;PY-#eO*o*IrTX#3{
zYaW&0$#ph@8M(U?4_gA2><;Vh4g5;Xe9F_O%X7E+$IX@4SM+In+II7FW50RIUT!y3
z_Drt3onP%?m$;G>gUhd8#Y12G?JlwR3;LJX==sY9Qmf<+@!D-W^FYyyKbgju?bu>l
z#kL)5P;xjp=L^|d*|Aff)Fz`(eUjrP&G=ez+S@@>q$ScKecVhvzjVHP(>&EqwJ#g$
zGICCtCl~!2lz*Z2OQye>?y6(UF;(K1rs#L{b;~I?Q|D5OJ^P=s?3C*Ig%t}|n;(w3
zsui6lTeTcw<K(KQH=BMmRCgCvNCgYLO%_mhd)}sF7Y@6JSfIYKcHz+4_H?qdJ(=cd
zs~xSW&LsbO)4bZG-mN0JEosT_z1g`SyH8l4dui>8eWD|UP82NgpISh#j{noW3;Pu;
zP_V#0WP#FSYIY4#{jsgmW9nWuSI?@X^qAwe??YWJbfsW{f&~f|@K~TQ|9Q+&_^{7e
zKyGQv-RF67OSkabseNvI3mxj61p;1a(>o=5vov4q6n-_kHxFPRx4j={2=%>ZAM4%A
z)RpNkJo&O#e+w+l7Y5jt$tP_lK9%#F82uaM6{%F~`qVbwCvtM{`g;<ox}l*CwcA(k
z?A^Y8(xNX@zS6$dE{~Z<Iyj~Fc8B#*KFGMuKulr&+^fPoDkJ9ze(u#zSz24yd{gb-
z%WoHVeSt??V2}6#AHP93Kwf-T)0*h&N_JIjPUL;}wx+frUcYKhgX)orvhw;Que6FU
zQ$K}>?r5GwCb}eoix<=_Ufr~%rCDB~xvH_D#_A_`!8wqLZ+%?zf%{;YIM37DtAe-R
z{QP)ha8q+vVr_T2rL`r^vmGkhn#^xbOjk0NVjhyYh~jxXv1cdwe>d5#8B2!4`Qc9V
zQKP@YKtjzQX2#Yk^=(egiz|0eFP^^eW%J1@Ui0$wocf01>5GQQ&x@=n2kn%4cf(|V
z_vZrd8w+eor#q@DD>pM=RCIN>S2U&CDm%<yl~-<V-cmWEVn$_is;R3o(a}=bH^<zQ
zwCtE%{gQ1>Xq<k$bwB>OUA1lUV_#DKXD9dx;}Kt&K5peQ<$q=4j<<B#hor2s|B`K1
z`TR*r>dH)sy|mIEc-qbdR_)G8OX?=xm8pwSH^@_$)l@{?U{Bpenf;2XJHS)7K2z6^
zx*?vrMVY!1>V|vjrex~MsT=008$5m7l2w(J_6TY9v<p=K%9f;fT_c|-aYR)z;-pG@
z%qjQ$`?MuHS1i*#JmP2UnX-zPr0hdPcIrqaIa00S_N3w7Bih1DS!$V|YN}aNx2o8z
z?%qrrW9a3UQy(O0n5%I)8lCxGKYl<&gJs>jYAHEOc+M#?tK^gvuM!SRMfLR!c?+4a
z9sKI%QMh8^>J=4Dezn;$-q^dMv9YPMr6c&SF_fN;*6dC`tbSEo-nHvfql>nash1Ro
z{aNLJIH@9G9y}MIYiafJcx{{fHMjpyt>&?x(zCI}Jax}sQBU+NZ(LsEzjx0|*CE=c
zBe5yn7HsF}cFAHywMR~cA>xdv3|NSS(bE=c=Ft6}%D(cj&aTb~e|L@;oUb!g6-{zk
z5iHje`^erE=e2YMYvC`BBkU~WrSAyHyUqi`XRN;94?9kD-8w|7J0b!-T8$-o>g(&~
zM~U+1_9l{pZ*tT()Gg{0J*#RKMCpmDUx&c5`Ag$ba`g?XBKy@)ms%gCC#rrO0)09|
zt@ppj;<RHv?{`hf3vrXJfgatHnGTPysjQhgHF(sW8FT7X=h%LE&-H{)3O&~o*lpFk
zUg!x`)MGvT^4QNVy(v@U6+Y}TLxqml5Dutk@TO2rQF^w!^n{Ik&-H|#C(#qRW>Ni$
zSdA^`1<+AR>FG*tjFOA0=L$7^c@(99`gNeM&Xir7S|jJNhJ}kF=ff@@1sT=!p6C%B
z6&NW>S6F?6sjM(hQVx>s$viLnR`Beh$j${Fgz|N!uHsD&n&{Ch33U(DXwAvW_q3J7
z-gt(4E3c~hYKD4~&ZXRF9owGF2su9I`%!yp$dh>X_BAhE^X<6R%QbJXo<3Uh_Gttr
zIwQ`e{x)%!Dvy7w*Q$Y5?&VrFQcw7)E3@{A)Dylm?1i3CMLpK@R<Bh9?9=PDYJi^Y
zIHdB!j;2jLTB}Ct+0)jl?ug6hbf>z@yn!OWR+p@<Sr&QiE;5<bVStVH@-=TjuQ*fo
zZp|C0N38u;t$BMgUaCEN(3*EuOZzcL$G6Ry9d!3>l<Ny)?YchOW$QOPS23va5uixT
z2;mcW_G&s%i=!uOUQzcA^;LPKp6~``X7ETop(lb~^s6IOQIFfxoP5(ap4E7T-m{3d
zbLNZ^dLHPFo;PQoOnXwD&Hi56^HS#w7q&;#cx`8AM^BhX_gqh3ohc*Zf{7#i`ybV>
z&Sc291iY>aCCM%`bp#l)rLJ~<KvkyLb+<e)Qd_t^o!KFP^kg2BT`R)B`muV_9;K(R
z?#8sXgx*ByaeE@}>h#z?sr8!!OstA~q^EDb!VYUjp>7YiK;aoAd-wqDCCw{5gJdrm
zs6sRUdlo1>(=}t;{r#D)^25Wo=$VG<VTc*S@7F~A?y+Exj1MS#@W&G7H>QeZDhs4w
z0p%bCGZZXPut0<b4$Oo~k@^GA%&+$43OZunLiIjwf&Kl@yLihoDZAR($A`Pnz1~<L
zGjaB2r-E$30{fi>3Tur0ZpeGy;r)J%5q2IKh8;JWKXz@@s}XC3HBec1rTJ6c(@gy;
zQ@_c4UTr>~ZVgiMYs}}hCSPZk`WsB1;LnOBtv7#m-DKpNjlQJH-H&K+x7>E!p7L;|
zv#=>xpkRT51@>PH#Ijv4Uphb4-QLU}1!v3LEc3fb`O#UKej2E}4Q*BJDGS=WTf={-
z<yKVS1q<xU7I3dW_T_#S`W9}1pfzduUWM9%1qv1@SYY3@fcqLezlVMg5DPw=y60DJ
z7MKUYs;6-lmbLlDEtC{2@MbI!9Efj5YhmBL&jR8J&J4>BFV*{@<tynDAUA8dIbf9|
zWb^vzopAjEX?=TGKK4x-tZxw8J@ZQ~C8rFh<*F5)4}H_Ff|h~>3KrNqEg-ixom4#I
zomTOT&zO(JJly-$4xjqCdbszvuXa%1;Or~8>|aQIZ-M>&n_17py=Q#-T4mvJUF($p
zxgYK={#SUow>-|gHxKu=Dt>EOORTo8bk4Jjwo-o3cFJ?U>9}?+W|s1Hudmxj^7%;0
zTfF6mJYw-xxz=Cwhiu(V=r1+;-Q_m3O3dhYmlr*p)$b{P1Nmuf9bFvPU4A6TjUCdK
z-bnl1<t2y9O0A);D{U2>Dt#EI+cfYF@`{d5p1e@>;Tz#c>GDA=?}}@6`K*^kMwgd~
zCl>4S1IEJ5gY}1=3O`(zmkfuS*G3JMXB+m{<!6q99|uT7FJ^PSF27M^j+au)8a9;8
zQdJ)Nf&3Nz2~vv9E?^UHOLxh*xYl#`R$Kg3pe?PQaqB8CzZ|*kl#32md8zC_gmM`#
zS9yQ=3Bl;LbgTR=xvPBO<9s&ux%C;i8RyYgXYKRsWt5x09Pclu5@VmMWx2cskcK7M
z82dbZFnp_&Qho*-W1q)gfuAF#mNn`NY>a(I$(U@DQkpoAjkZtG2Sn$&fK;}cjcMl-
za!Pual%oHtY&*aEF$%6!#a5ZT-QKkGUSuo*slV7wx3hTUMEDI-ihj{)+WCV=;o>W#
zkw0Z)+WE&H!apFTw7;2+Zf9}Jlkg8pDdQ;ZEYstA%ANS+Tvcq9t|K3)%I!z-G3T{o
z{iU5oetsS0^R;~cGqduqFvfO`Dc_Wpzk3noC!6w)jC^duI?B-{slWJ@(f`>Il*{o*
z6_2nn?RouX%2%pltMqX4F{+()zxq7o=EX@n)?({F=<=7&qFnTnzPy+#rV*;V{>tYl
zzfhOI@L9_`bcik=at!4c>GJ+}z)N-c6nwyzI3blHZ)rVs-)y9OyOdIXA{#v}_3!^A
z<(H^ptMp#-!CKF4O_X1%%cr~qFVW?54}y#Dl1gRlPE_S}ul|d2@dHv>IUA$r1nJim
zs@VEEerrFj^%VUHF8)D!Ce23Mt-h+3a^r_beTwp<wf^5pzl<L~FpFb1Xg!A|D8EXy
zQ1%fv+CS?D5|1|VCaLTOHtV&XFaL=0cdKIS1@X5zy8MYBQ+|yp7d?Zt{;PLU{vKUk
zCUcRo=jZOB{Jo}pD!I02-RH%B-lxk4e3|@yt^cV*D3^JVH1&1(XkGs7Z{XMI@}qu1
z{uy0<KfYsMuglB+LayVq?y=J;f4?sO26l)UyUi`3T>42W7k`_e+iyQj`HiaBDns71
zzkVe)uua?@HHdN@kM&2O+ct4`Up3{Mb$h<Mj`ExMOm^&Ow)(hr4~qWpsB-HmX{R2q
z`f1F`_Wi2dF8_LVyw2*T`~fXr)<AB?>x&%A{;rlkp^V&&%L{*^{6SMbkKBw)Df6EF
zeN}EfvxMCA_Z#1%{3p8n`45qs@p`U`a+!BX&*Mu@e?Rd&<&UUhd-#FmroTVL_V&+A
zIq_ucxU;s4fBspQk6@gg@)yp8zoyEq`)+4k4pDZqK1yHh*R}kpZ*YE{smtsCPPy2N
zYz*;Lq}yp7+>e64s&cCwUo!KCb-f(x4OMQ($2oc~-u>FIDMuH{KCCgT=ln-0_=hf^
zxRG4XKUSJ!+W%DL#1MH|8_)CBpUu{uDD%M$ZHe4xz?ZM1T#tLrbw{Cxn3q&8`<wEc
z&ZGR_s@R^ikn^mbCvRTPxW{Z=KCPbeGnE}~UUnPh=G<AnEu-h=Ly5&$k(QtF)vTU7
zDkv}3<;NbL)l>c?<=Bp7&%T$fZqLn^tf!pVkW?yuqT4h3k*$=Ms$%P*E6}6IclJhn
vJ0|`|dS*NB8B^_?eGf4aD_6yKHFKINKlVW8!`MJoZk6sJFK<hE*LD975B?X;

literal 0
HcmV?d00001

diff --git a/AppleCSP/AppleCSP/wrapKey.cpp b/AppleCSP/AppleCSP/wrapKey.cpp
new file mode 100644
index 00000000..703419db
--- /dev/null
+++ b/AppleCSP/AppleCSP/wrapKey.cpp
@@ -0,0 +1,601 @@
+/*
+ * 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.
+ */
+
+
+//
+// wrapKey.cpp - wrap/unwrap key functions for AppleCSPSession
+//
+
+#include "AppleCSPSession.h"
+#include "AppleCSPUtils.h"
+#ifdef USE_SNACC
+#include "pkcs_7_8.h"
+#endif
+#include "cspdebugging.h"
+
+/*
+ * Wrap key function. Used for two things:
+ *
+ *  -- Encrypt and encode a private or session key for export to
+ *     a foreign system or program. Any type of keys may be used
+ *     for the  unwrapped key and the wrapping (encrypting) key,
+ *     as long as this CSP understands those keys. The context
+ *     must be of  class ALGCLASS_SYMMETRIC or ALGCLASS_ASYMMETRIC,
+ *     matching the wrapping key. 
+ *
+ *	   Private keys will be PKCS8 encoded; session keys will be 
+ *     PKCS7 encoded. Both input keys may be in raw or reference 
+ *     format. Wrapped key will have BlobType CSSM_KEYBLOB_WRAPPED.
+ * 
+ *  -- Convert a reference key to a RAW key (with no encrypting).
+ *     This is called a NULL wrap; no wrapping key need be present in
+ *     the context, but the context must be of class 
+ *	   ALGCLASS_SYMMETRIC and algorithm ALGID_NONE. 
+ *
+ * There are serious inconsistencies in the specification of wrap 
+ * algorithms to be used in the various CDSA specs (c914.pdf, 
+ * CSP Behavior spec) and between those specs and the PKCS standards
+ * PKCS7, PKCS8, RFC2630). Here is what this module implements:
+ *
+ * On a wrap key op, the caller can add a CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT
+ * attribute to the context to specify the wrapping algorithm to be used.
+ * If it's there, that's what we use if appropriate for the incoming key
+ * types. Otherwise we figure out a reasonable default from the incoming
+ * key types. The wrapped key always has the appropriate KeyHeader.Format
+ * field set indicating how it was wrapped. Defaults are shows below. 
+ *
+ * The format CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM is used to indicate
+ * a modified CMS-style wrapping which is similar to that specified in
+ * RFC2630, with some modification. 
+ *
+ * Default wrapping if none specified:
+ *
+ * UnwrappedKey type   WrappingKey type 	Format
+ * -----------------   ----------------		-------------------------
+ * 3DES		   		   3DES					CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
+ * any				   Other symmetric		CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7
+ * any				   Other asymmetric		CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8
+ */
+ 
+void AppleCSPSession::WrapKey(
+		CSSM_CC_HANDLE CCHandle,
+		const Context &Context,
+        const AccessCredentials &AccessCred,
+        const CssmKey &UnwrappedKey,
+        const CssmData *DescriptiveData,
+        CssmKey &WrappedKey,
+		CSSM_PRIVILEGE Privilege)
+{
+	CssmKey::Header 		&wrappedHdr   = WrappedKey.header();
+	bool 					isNullWrap = false;
+	CssmKey					*wrappingKey = NULL;
+	CSSM_KEYBLOB_FORMAT		wrapFormat;
+	
+	switch(UnwrappedKey.keyClass()) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+		case CSSM_KEYCLASS_SESSION_KEY:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	try {
+		/* wrapping key only required for non-NULL wrap */
+		CssmKey &wrappingKeyRef = 
+			Context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, 
+			CSSMERR_CSP_MISSING_ATTR_KEY);
+		wrappingKey = &wrappingKeyRef;
+	}
+	catch (const CssmError err) {
+		if((err.error == CSSMERR_CSP_MISSING_ATTR_KEY) &&
+		   (Context.algorithm() == CSSM_ALGID_NONE) &&
+		   (Context.type() == CSSM_ALGCLASS_SYMMETRIC)) {
+				// NULL wrap, OK
+				isNullWrap = true;
+		}
+		else {
+			errorLog0("WrapKey: missing wrapping key\n");
+			throw;
+		}
+	}
+	catch (...) {
+		throw;
+	}
+	
+	/*
+	 * Validate misc. params as best we can
+	 */
+	if(isNullWrap) {
+		wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE;
+	}
+	else {
+		/*
+		 * Can only wrap session and private keys. 
+		 */
+		if(UnwrappedKey.keyClass() == CSSM_KEYCLASS_PUBLIC_KEY) {
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+		}
+		cspValidateIntendedKeyUsage(&wrappingKey->KeyHeader, CSSM_KEYUSE_WRAP);
+
+		/*
+		 * make sure wrapping key type matches context
+		 */
+		CSSM_CONTEXT_TYPE wrapType;
+		switch(wrappingKey->KeyHeader.KeyClass) {
+			case CSSM_KEYCLASS_PUBLIC_KEY:
+			case CSSM_KEYCLASS_PRIVATE_KEY:
+				wrapType = CSSM_ALGCLASS_ASYMMETRIC;
+				break;
+			case CSSM_KEYCLASS_SESSION_KEY:
+				wrapType = CSSM_ALGCLASS_SYMMETRIC;
+				break;
+			default:
+				errorLog0("WrapKey: bad class of wrappingKey\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+		}
+		if(wrapType != Context.type()) {
+			errorLog0("WrapKey: mismatch wrappingKey/contextType\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
+		}
+		if(Context.algorithm() == CSSM_ALGID_NONE) {
+			errorLog0("WrapKey: null wrap alg, non-null key\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+		}
+
+		/*
+		 * Get optional wrap format, set default per incoming keys
+		 * Note: no such atrribute ==> 0 ==> FORMAT_NONE, which we
+		 * take to mean "use the default".
+		 */
+		wrapFormat = Context.getInt(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT);
+		if(wrapFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_NONE) {
+			/* figure out a default */
+			if(wrapType == CSSM_ALGCLASS_ASYMMETRIC) {
+				/* easy */
+#ifdef USE_SNACC
+				wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8;
+#else
+				wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM; 
+#endif
+			}
+			else {
+				CASSERT(wrapType == CSSM_ALGCLASS_SYMMETRIC);
+				if((wrappingKey->algorithm() == CSSM_ALGID_3DES_3KEY) &&
+				   (UnwrappedKey.algorithm() == CSSM_ALGID_3DES_3KEY)) {
+					/* apple custom CMS */
+					wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM; 
+				}
+				else {
+					/* normal case for symmetric wrapping keys */
+#ifdef USE_SNACC
+					wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7;
+#else
+					wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM; 
+#endif
+				}
+			}	/* default for symmetric wrapping key */
+		}		/* no format present or FORMAT_NONE */
+	}
+	
+	/* make sure we have a valid format here */
+	switch(wrapFormat) {
+#if 0
+		case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7:
+		case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8:
+#endif
+		case CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM:
+			break;
+		case CSSM_KEYBLOB_WRAPPED_FORMAT_NONE:
+			if(isNullWrap) {
+				/* only time this is OK */
+				break;
+			}
+			/* else fall thru */
+		default:
+			dprintf1("KeyWrap: invalid wrapFormat (%d)\n", (int)wrapFormat);
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT);
+	}
+	/* get the blob to be wrappped */
+	CssmData rawBlob;
+	bool allocdRawBlob = false;
+	CSSM_KEYBLOB_FORMAT rawFormat;
+	
+	switch(UnwrappedKey.blobType()) {
+		case CSSM_KEYBLOB_RAW:
+			/* trivial case */
+			rawBlob = CssmData::overlay(UnwrappedKey.KeyData);
+			rawFormat = UnwrappedKey.blobFormat();
+			break;
+		case CSSM_KEYBLOB_REFERENCE:
+			/* get binary key, then get blob from it */
+			{
+				BinaryKey &binKey = lookupRefKey(UnwrappedKey);
+				/*
+				 * Special case for null wrap - prevent caller from obtaining 
+				 * clear bits if CSSM_KEYATTR_SENSITIVE or !CSSM_KEYATTR_EXTRACTABLE.
+				 * Don't trust the caller's header; use the one in the BinaryKey.
+				 */
+				if(isNullWrap) {
+					CSSM_KEYATTR_FLAGS keyAttr = binKey.mKeyHeader.KeyAttr;
+					if((keyAttr & CSSM_KEYATTR_SENSITIVE) ||
+					   !(keyAttr & CSSM_KEYATTR_EXTRACTABLE)) {
+						CssmError::throwMe(
+							CSSMERR_CSP_INVALID_KEYATTR_MASK);
+					}
+				}
+				rawFormat = requestedKeyFormat(Context, UnwrappedKey);
+				binKey.generateKeyBlob(privAllocator,
+					rawBlob,
+					rawFormat);
+			}
+			allocdRawBlob = true;		// remember - we need to free
+			break;
+			
+		default:
+			errorLog0("WrapKey: bad unwrappedKey BlobType\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+
+	/*
+	 * Prepare outgoing header.
+	 */
+	copyCssmHeader(UnwrappedKey.header(), wrappedHdr, normAllocator);
+	wrappedHdr.WrapAlgorithmId = Context.algorithm(); 	// true for null 
+														// and non-Null 
+	wrappedHdr.Format = wrapFormat;
+	
+	/* 
+	 * special case - break out here for custom Apple CMS  
+	 */
+	if(!isNullWrap && (wrapFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM)) {
+		try {
+			WrapKeyCms(CCHandle,
+				Context,
+				AccessCred,
+				UnwrappedKey,
+				rawBlob,
+				allocdRawBlob,
+				DescriptiveData,
+				WrappedKey,
+				Privilege);
+		}
+		catch(...) {
+			if(allocdRawBlob) {
+				freeCssmData(rawBlob, privAllocator);
+			}
+			throw;
+		}
+		if(allocdRawBlob) {
+			freeCssmData(rawBlob, privAllocator);
+		}
+		return;
+	}
+
+	
+	/*
+	 * Generate wrapped blob. Careful, we need to conditionally free
+	 * rawBlob on error.
+	 */
+	CssmData encryptedBlob;
+	CssmData remData;
+	WrappedKey.KeyData.Data = NULL;		// ignore possible incoming KeyData
+	WrappedKey.KeyData.Length = 0;
+	
+	try {
+		if(isNullWrap) {
+			/* copy raw blob to caller's wrappedKey */
+			copyCssmData(rawBlob, 
+				CssmData::overlay(WrappedKey.KeyData), 
+				normAllocator);
+			wrappedHdr.BlobType = CSSM_KEYBLOB_RAW;
+			wrappedHdr.Format   = rawFormat; 
+		}
+#ifdef USE_SNACC
+		else {
+			/* encrypt rawBlob using caller's context, then encode to
+			 * WrappedKey.KeyData */
+			uint32 bytesEncrypted;
+			EncryptData(CCHandle,
+				Context,
+				&rawBlob,			// ClearBufs[]
+				1,					// ClearBufCount
+				&encryptedBlob,		// CipherBufs[],
+				1,					// CipherBufCount,
+				bytesEncrypted,
+				remData,
+				Privilege);
+	
+			// I'm not 100% sure about this....
+			assert(remData.Length == 0);
+			encryptedBlob.Length = bytesEncrypted;
+			if(wrapFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7) {
+				cspEncodePkcs7(Context.algorithm(),
+					Context.getInt(CSSM_ATTRIBUTE_MODE),
+					encryptedBlob,
+					CssmData::overlay(WrappedKey.KeyData), 
+					normAllocator);
+			}
+			else {
+				CASSERT(wrapFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8);
+				cspEncodePkcs8(Context.algorithm(),
+					Context.getInt(CSSM_ATTRIBUTE_MODE),
+					encryptedBlob,
+					CssmData::overlay(WrappedKey.KeyData),
+					normAllocator);
+			}
+			wrappedHdr.BlobType = CSSM_KEYBLOB_WRAPPED;
+			// OK to be zero or not present 
+			wrappedHdr.WrapMode = Context.getInt(
+				CSSM_ATTRIBUTE_MODE);
+		}
+#endif
+	}
+	catch (...) {
+		errorLog0("WrapKey: EncryptData() threw exception\n");
+		if(allocdRawBlob) {
+			freeCssmData(rawBlob, privAllocator);
+		}
+		/* mallocd in EncryptData, thus normAllocator */
+		freeCssmData(encryptedBlob, normAllocator);
+		freeCssmData(remData,normAllocator);
+		throw;
+	}
+	if(allocdRawBlob) {
+		freeCssmData(rawBlob, privAllocator);
+	}
+	freeCssmData(encryptedBlob, normAllocator);
+	freeCssmData(remData, normAllocator);
+}
+
+/*
+ * Unwrap key function. Used for:
+ *
+ * -- Given key of BlobType CSSM_KEYBLOB_WRAPPED, decode and decrypt
+ *    it, yielding a key in either raw or reference format. Unwrapping
+ *    key may be either raw or reference. The context must match
+ *    the unwrapping key (ALGCLASS_SYMMETRIC  or ALGCLASS_ASYMMETRIC).
+ *
+ *	  Private keys are assumed to be PKCS8 encoded; session keys  
+ *    are assumed to be PKCS7 encoded. 
+ *
+ * -- Convert a Raw key to a reference key (with no decrypting).
+ *    This is called a NULL unwrap; no unwrapping key need be present in
+ *    the context, but the context must be of class 
+ *    ALGCLASS_SYMMETRIC and algorithm ALGID_NONE.
+ */ 
+void AppleCSPSession::UnwrapKey(
+		CSSM_CC_HANDLE CCHandle,
+		const Context &Context,
+		const CssmKey *PublicKey,
+		const CssmKey &WrappedKey,
+		uint32 KeyUsage,
+		uint32 KeyAttr,
+		const CssmData *KeyLabel,
+		const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+		CssmKey &UnwrappedKey,
+		CssmData &DescriptiveData,
+		CSSM_PRIVILEGE Privilege)
+{
+	bool 					isNullUnwrap = false;
+	CssmKey					*unwrappingKey = NULL;
+	cspKeyType				keyType;				// CKT_Public, etc. 
+	CSSM_KEYBLOB_FORMAT		wrapFormat = WrappedKey.blobFormat();
+	
+	/* obtain unwrapping key if present */
+	try {
+		CssmKey &unwrappingKeyRef = 
+			Context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, 
+			CSSMERR_CSP_MISSING_ATTR_KEY);
+		unwrappingKey = &unwrappingKeyRef;
+	}
+	catch (const CssmError err) {
+		if((err.error == CSSMERR_CSP_MISSING_ATTR_KEY) &&
+		   (Context.algorithm() == CSSM_ALGID_NONE) &&
+		   (Context.type() == CSSM_ALGCLASS_SYMMETRIC)) {
+				// NULL unwrap, OK
+				isNullUnwrap = true;
+		}
+		else {
+			errorLog0("UnwrapKey: missing wrapping key\n");
+			throw;
+		}
+	}
+	catch (...) {
+		throw;
+	}
+
+	/* 
+	 * validate unwrappingKey 
+	 */
+	if(!isNullUnwrap) {
+		/* make sure unwrapping key type matches context */
+		CSSM_CONTEXT_TYPE unwrapType;
+		switch(unwrappingKey->KeyHeader.KeyClass) {
+			case CSSM_KEYCLASS_PUBLIC_KEY:
+			case CSSM_KEYCLASS_PRIVATE_KEY:
+				unwrapType = CSSM_ALGCLASS_ASYMMETRIC;
+				break;
+			case CSSM_KEYCLASS_SESSION_KEY:
+				unwrapType = CSSM_ALGCLASS_SYMMETRIC;
+				break;
+			default:
+				errorLog0("UnwrapKey: bad class of wrappingKey\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+		}
+		if(unwrapType != Context.type()) {
+			errorLog0("UnwrapKey: mismatch unwrappingKey/contextType\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
+		}
+		if(Context.algorithm() == CSSM_ALGID_NONE) {
+			errorLog0("UnwrapKey: null wrap alg, non-null key\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+		}
+		cspValidateIntendedKeyUsage(&unwrappingKey->KeyHeader, CSSM_KEYUSE_UNWRAP);
+	}
+
+	/* validate WrappedKey */
+	switch(WrappedKey.keyClass()) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			if(!isNullUnwrap) {
+				errorLog0("UnwrapKey: unwrap of public key illegal\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+			}
+			keyType = CKT_Public;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			keyType = CKT_Private;
+			break;
+		case CSSM_KEYCLASS_SESSION_KEY:
+			keyType = CKT_Session;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	if(isNullUnwrap) {
+		if(WrappedKey.blobType() != CSSM_KEYBLOB_RAW) {
+			errorLog0("UnwrapKey: expected raw blobType\n");
+			CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
+		}
+	}
+	else {
+		if(WrappedKey.blobType() != CSSM_KEYBLOB_WRAPPED) {
+			errorLog0("UnwrapKey: expected wrapped blobType\n");
+			CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
+		}
+	}
+
+	/* validate requested storage and usage */
+	cspKeyStorage keyStorage = cspParseKeyAttr(keyType, KeyAttr);
+	switch(keyStorage) {
+		case CKS_Ref:
+		case CKS_Data:
+			break;		// OK
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
+	}
+	cspValidateKeyUsageBits(keyType,  KeyUsage);
+
+	/* prepare outgoing header */
+	CssmKey::Header &unwrappedHdr = UnwrappedKey.header();
+	copyCssmHeader(WrappedKey.header(), unwrappedHdr, normAllocator);
+	unwrappedHdr.WrapAlgorithmId = Context.algorithm(); // true for null 
+														// and non-Null 
+	/* GUID must be appropriate */
+	unwrappedHdr.CspId = plugin.myGuid();
+
+	UnwrappedKey.KeyData.Data = NULL;	// ignore possible incoming KeyData
+	UnwrappedKey.KeyData.Length = 0;
+	
+	/* validate wrappedKey format */
+	if(!isNullUnwrap) {
+		switch(wrapFormat) {
+#ifdef USE_SNACC
+			case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7:
+			case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8:
+				break;
+#endif
+			case CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM:
+				UnwrapKeyCms(CCHandle,
+						Context,
+						WrappedKey,
+						CredAndAclEntry,
+						UnwrappedKey,
+						DescriptiveData,
+						Privilege,
+						keyStorage);
+				return;
+			default:
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT);
+		}
+	}
+
+	/* Get key blob, decoding and decrypting if necessary */
+	CssmData decodedBlob;
+	CssmData remData;
+	try {
+		if(isNullUnwrap) {
+			/* simple copy of raw blob */
+			copyData(WrappedKey.KeyData, 
+				UnwrappedKey.KeyData, 
+				normAllocator);
+			unwrappedHdr.BlobType = CSSM_KEYBLOB_RAW;
+			unwrappedHdr.Format   = wrapFormat; 
+		}
+#ifdef USE_SNACC
+		else {
+			/* decode wrapped blob, then decrypt to UnwrappedKey.KeyData
+			 * using caller's context */
+			CSSM_KEYBLOB_FORMAT rawFormat;
+			if(wrapFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7) {
+				cspDecodePkcs7(WrappedKey,
+					decodedBlob,
+					rawFormat,
+					normAllocator);
+			}
+			else {
+				cspDecodePkcs8(WrappedKey,
+					decodedBlob, 
+					rawFormat,
+					normAllocator);
+			}
+			uint32 bytesDecrypted;		
+			CssmData *unwrapData = 	
+				CssmData::overlay(&UnwrappedKey.KeyData);
+				
+			DecryptData(CCHandle,
+				Context,
+				&decodedBlob,		// CipherBufs[],
+				1,					// CipherBufCount,
+				unwrapData,			// ClearBufs[]
+				1,					// ClearBufCount
+				bytesDecrypted,
+				remData,
+				Privilege);
+	
+			// I'm not 100% sure about this....
+			assert(remData.Length == 0);
+			UnwrappedKey.KeyData.Length = bytesDecrypted;
+			unwrappedHdr.BlobType = CSSM_KEYBLOB_RAW;
+			unwrappedHdr.Format   = rawFormat;
+		}
+#endif
+	}
+	catch (...) {
+		errorLog0("UnwrapKey: DecryptData() threw exception\n");
+		freeCssmData(decodedBlob, normAllocator);
+		freeCssmData(remData, normAllocator);
+		throw;
+	}
+	freeCssmData(decodedBlob, normAllocator);
+	freeCssmData(remData, normAllocator);
+
+	/* 
+	 * One more thing: cook up a BinaryKey if caller wants a 
+	 * reference key.
+	 */
+	if(keyStorage == CKS_Ref) {
+		/*
+		 * We have a key in raw format; convert to BinaryKey.
+		 */
+		BinaryKey *binKey = NULL;
+		CSPKeyInfoProvider *provider = infoProvider(UnwrappedKey);
+		provider->CssmKeyToBinary(&binKey);
+		addRefKey(*binKey, UnwrappedKey);
+		delete provider;
+	}
+}
+
diff --git a/AppleCSP/AppleCSP/wrapKeyCms.cpp b/AppleCSP/AppleCSP/wrapKeyCms.cpp
new file mode 100644
index 00000000..4a92edfe
--- /dev/null
+++ b/AppleCSP/AppleCSP/wrapKeyCms.cpp
@@ -0,0 +1,466 @@
+/*
+ * 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.
+ */
+
+
+//
+// wrapKeyCms.cpp - wrap/unwrap key, CMS format 
+//
+
+#include "AppleCSPSession.h"
+#include "AppleCSPUtils.h"
+#include "cspdebugging.h"
+#include "pkcs_7_8.h"
+
+/*
+ *
+ * Here is the algorithm implemented in this module:
+ *
+ * Note that DEK is the wrapping key,
+ *
+ * 1. PRIVATE_KEY_BYTES is the private data to be wrapped. It consists of the 
+ *    following concatenation:
+ *
+ *    4-byte length of Descriptive Data, big-endian  |
+ *    Descriptive Data |
+ *    rawBlob.Data bytes
+ * 
+ * 2. Encrypt PRIVATE_KEY_BYTES using DEK (3DES) and IV in CBC mode with
+ *    PKCS1 padding.  Call the ciphertext TEMP1
+ * 
+ * 3. Let TEMP2 = IV || TEMP1.
+ * 
+ * 4. Reverse the order of the octets in TEMP2 call the result TEMP3.
+ * 
+ * 5. Encrypt TEMP3 using DEK with an IV of 0x4adda22c79e82105 in CBC mode
+ *    with PKCS1 padding call the result TEMP4.
+ * 
+ *    TEMP4 is wrappedKey.KeyData.
+ */
+
+/* true: cook up second CCHandle via a new HandleObject
+ * false - OK to reuse a CCHandle */
+#define USE_SECOND_CCHAND	0
+
+/* false : make copy of incoming context before changing IV
+ * true  : resuse OK */
+#define REUSE_CONTEXT		1
+
+/* lots'o'printfs in lieu of a debugger which works */
+#define VERBOSE_DEBUG		0
+
+static const uint8 magicCmsIv[] = 
+	{ 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
+
+#if		VERBOSE_DEBUG
+static void dumpBuf(
+	char				*title,
+	const CSSM_DATA		*d,
+	uint32 				maxLen)
+{
+	unsigned i;
+	uint32 len;
+	
+	if(title) {
+		printf("%s:  ", title);
+	}
+	if(d == NULL) {
+		printf("NO DATA\n");
+		return;
+	}
+	printf("Total Length: %d\n   ", d->Length);
+	len = maxLen;
+	if(d->Length < len) {
+		len = d->Length;
+	}
+	for(i=0; i<len; i++) {
+		printf("%02X ", d->Data[i]);
+		if((i % 16) == 15) {
+			printf("\n   ");
+		}
+	}
+	printf("\n");
+}
+#else
+#define dumpBuf(t, d, m)
+#endif	/* VERBOSE_DEBUG */
+
+
+/* serialize/deserialize uint32, big-endian. */
+static void serializeUint32(uint32 i, uint8 *buf)
+{
+	*buf++ = (uint8)(i >> 24);
+	*buf++ = (uint8)(i >> 16);
+	*buf++ = (uint8)(i >> 8);
+	*buf   = (uint8)i;
+}
+
+static uint32 deserializeUint32(const uint8 *buf) {
+    	uint32 result;
+
+    	result = ((uint32)buf[0] << 24) |
+				 ((uint32)buf[1] << 16) |
+				 ((uint32)buf[2] << 8)  |
+				  (uint32)buf[3];
+    	return result;
+}
+
+void AppleCSPSession::WrapKeyCms(
+	CSSM_CC_HANDLE CCHandle,
+	const Context &context,
+	const AccessCredentials &AccessCred,
+	const CssmKey &UnwrappedKey,
+	CssmData &rawBlob,
+	bool allocdRawBlob,			// callee has to free rawBlob
+	const CssmData *DescriptiveData,
+	CssmKey &WrappedKey,
+	CSSM_PRIVILEGE Privilege)
+{
+	uint32 ddLen;
+	CssmData PRIVATE_KEY_BYTES;
+	#if		!REUSE_CONTEXT
+	Context secondCtx(context.ContextType, context.AlgorithmType);
+	secondCtx.copyFrom(context, privAllocator);
+	#endif	/* REUSE_CONTEXT */
+	
+	/*
+	 * 1. PRIVATE_KEY_BYTES is the private data to be wrapped. It consists of the 
+	 *    following concatenation:
+	 *
+	 *    4-byte length of Descriptive Data, big-endian  |
+	 *    Descriptive Data | 
+	 *    rawBlob.Data bytes
+	 */
+	dumpBuf("wrap rawBlob", &rawBlob, 24);
+	dumpBuf("wrap DescriptiveData", DescriptiveData, 24);
+	
+	if(DescriptiveData == NULL) {
+		ddLen = 0;
+	}
+	else {
+		ddLen = DescriptiveData->Length;
+	}
+	uint32 pkbLen = 4 +  ddLen + rawBlob.Length;
+	setUpCssmData(PRIVATE_KEY_BYTES, pkbLen, privAllocator);
+	uint8 *cp = PRIVATE_KEY_BYTES.Data;
+	serializeUint32(ddLen, cp);
+	cp += 4;
+	if(ddLen != 0) {
+		memcpy(cp, DescriptiveData->Data, ddLen);
+		cp += ddLen;
+	}
+	memcpy(cp, rawBlob.Data, rawBlob.Length);
+	dumpBuf("wrap PRIVATE_KEY_BYTES", &PRIVATE_KEY_BYTES, 48);
+	
+	/* 2. Encrypt PRIVATE_KEY_BYTES using DEK (3DES) and IV in CBC mode with
+     *    PKCS1 padding.  Call the ciphertext TEMP1
+	 *
+	 * We'll just use the caller's context for this. Maybe we should 
+	 * validate mode, padding, IV?
+	 */
+	CssmData TEMP1;
+	uint32 bytesEncrypted;
+	CssmData remData;
+	EncryptData(CCHandle,
+		context,
+		&PRIVATE_KEY_BYTES,	// ClearBufs[]
+		1,					// ClearBufCount
+		&TEMP1,				// CipherBufs[],
+		1,					// CipherBufCount,
+		bytesEncrypted,
+		remData,
+		Privilege);
+	
+	// I'm not 100% sure about this....
+	assert(remData.Length == 0);
+	TEMP1.Length = bytesEncrypted;
+	dumpBuf("wrap TEMP1", &TEMP1, 48);
+	
+	/* 
+	 * 3. Let TEMP2 = IV || TEMP1.
+	 */
+	CssmData TEMP2;
+	CssmData &IV = context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR, 
+				CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
+	setUpCssmData(TEMP2, IV.Length + TEMP1.Length, privAllocator);
+	memcpy(TEMP2.Data, IV.Data, IV.Length);
+	memcpy(TEMP2.Data + IV.Length, TEMP1.Data, TEMP1.Length);
+	dumpBuf("wrap TEMP2", &TEMP2, 56);
+	
+	
+	/* 
+	 * 4. Reverse the order of the octets in TEMP2 call the result 
+	 *    TEMP3.
+	 */
+	CssmData TEMP3;
+	setUpCssmData(TEMP3, TEMP2.Length, privAllocator);
+	uint8 *cp2 = TEMP2.Data + TEMP2.Length - 1;
+	cp = TEMP3.Data;
+	for(uint32 i=0; i<TEMP2.Length; i++) {
+		*cp++ = *cp2--;
+	} 
+	dumpBuf("wrap TEMP3", &TEMP3, 64);
+
+	/* 
+     * 5. Encrypt TEMP3 using DEK with an IV of 0x4adda22c79e82105 in CBC mode
+	 *    with PKCS1 padding call the result TEMP4.
+	 * 
+	 *    TEMP4 is wrappedKey.KeyData.
+	 *
+	 * This is the tricky part - we're going to use the caller's context
+	 * again, but we're going to modify the IV. 
+	 * We're assuming here that the IV we got via context.get<CssmData>
+	 * actually is in the context and not a copy!
+	 */
+	#if		REUSE_CONTEXT
+	CssmData &IV2 = context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR, 
+				CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
+	#else
+	CssmData &IV2 = secondCtx.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR, 
+				CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
+	#endif	/* REUSE_CONTEXT */
+	
+	uint8 *savedIV = IV2.Data;
+	uint32 savedIVLen = IV2.Length;
+	IV2.Data = (uint8 *)magicCmsIv;
+	IV2.Length = 8;
+	CssmData &outBlob = CssmData::overlay(WrappedKey.KeyData);
+	outBlob.Length = 0;
+	outBlob.Data = NULL;
+	try {
+		EncryptData(CCHandle,
+			#if		REUSE_CONTEXT
+			context,
+			#else
+			secondCtx,
+			#endif	/* REUSE_CONTEXT */
+			
+			&TEMP3,	// ClearBufs[]
+			1,					// ClearBufCount
+			&outBlob,			// CipherBufs[],
+			1,					// CipherBufCount,
+			bytesEncrypted,
+			remData,
+			Privilege);
+	}
+	catch (...) {
+		IV2.Data = savedIV;
+		IV2.Length = savedIVLen;
+		throw;		// and leak
+	}
+	IV2.Data = savedIV;
+	IV2.Length = savedIVLen;
+
+	// I'm not 100% sure about this....
+	assert(remData.Length == 0);
+	outBlob.Length = bytesEncrypted;
+	dumpBuf("wrap outBlob", &outBlob, 64);
+	
+	/* outgoing header */
+	WrappedKey.KeyHeader.BlobType = CSSM_KEYBLOB_WRAPPED;
+	// OK to be zero or not present 
+	WrappedKey.KeyHeader.WrapMode = context.getInt(CSSM_ATTRIBUTE_MODE);
+	WrappedKey.KeyHeader.Format = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM;
+	
+	/* free resources */
+	freeCssmData(PRIVATE_KEY_BYTES, privAllocator);
+	freeCssmData(TEMP1, normAllocator);		// alloc via encrypt
+	freeCssmData(TEMP2, privAllocator); 
+	freeCssmData(TEMP3, privAllocator); 
+	if(allocdRawBlob) {
+		/* our caller mallocd this when dereferencing a ref key */
+		freeCssmData(rawBlob, privAllocator);
+	}
+}
+
+/* note we expect an IV present in the context though we don't use it
+ * FIXME - we should figure out how to add this attribute at this level
+ */
+ 
+/* safety trap - don't try to malloc anything bigger than this - we get 
+ * sizes from the processed bit stream.... */
+#define MAX_MALLOC_SIZE		0x10000
+
+void AppleCSPSession::UnwrapKeyCms(
+	CSSM_CC_HANDLE CCHandle,
+	const Context &Context,
+	const CssmKey &WrappedKey,
+	const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+	CssmKey &UnwrappedKey,
+	CssmData &DescriptiveData,
+	CSSM_PRIVILEGE Privilege,
+	cspKeyStorage keyStorage)
+{
+	/*
+	 * In reverse order, the steps from wrap...
+	 * 
+     * 5. Encrypt TEMP3 using DEK with an IV of 0x4adda22c79e82105 in CBC mode
+	 *    with PKCS1 padding call the result TEMP4.
+	 * 
+	 *    TEMP4 is wrappedKey.KeyData.
+	 */
+	const CssmData &wrappedBlob = CssmData::overlay(WrappedKey.KeyData);
+	dumpBuf("unwrap inBlob", &wrappedBlob, 64);
+	CssmData &IV1 = Context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR, 
+				CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
+	uint8 *savedIV = IV1.Data;
+	uint32 savedIvLen = IV1.Length;
+	IV1.Data = (uint8 *)magicCmsIv;
+	IV1.Length = 8;
+	CssmData TEMP3;
+	uint32 bytesDecrypted;
+	CssmData remData;
+	
+	try {
+		DecryptData(CCHandle,
+			Context,
+			&wrappedBlob,		// CipherBufs[],
+			1,					// CipherBufCount,
+			&TEMP3,				// ClearBufs[]
+			1,					// ClearBufCount
+			bytesDecrypted,
+			remData,
+			Privilege);
+	}
+	catch(...) {
+		IV1.Data = savedIV;
+		IV1.Length = savedIvLen;
+		throw;
+	}
+	IV1.Data = savedIV;
+	IV1.Length = savedIvLen;
+	// I'm not 100% sure about this....
+	assert(remData.Length == 0);
+	TEMP3.Length = bytesDecrypted;
+	dumpBuf("unwrap TEMP3", &TEMP3, 64);
+	
+	/* 
+	 * 4. Reverse the order of the octets in TEMP2 call the result 
+	 *    TEMP3.
+	 *
+	 * i.e., TEMP2 := reverse(TEMP3)
+	 */
+	CssmData TEMP2;
+	setUpCssmData(TEMP2, TEMP3.Length, privAllocator);
+	uint8 *src = TEMP3.Data + TEMP3.Length - 1;
+	uint8 *dst = TEMP2.Data;
+	for(uint32 i=0; i<TEMP2.Length; i++) {
+		*dst++ = *src--;
+	} 
+	dumpBuf("unwrap TEMP2", &TEMP2, 64);
+
+	/* 
+	 * 3. Let TEMP2 = IV || TEMP1.
+	 *
+	 * IV2 is first 8 bytes of TEMP2, remainder is TEMP1 
+	 */
+	if(TEMP2.Length <= 8) {
+		dprintf0("UnwrapKeyCms: short TEMP2\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+	CssmData IV2;
+	CssmData TEMP1;
+	setUpCssmData(IV2, 8, privAllocator);
+	setUpCssmData(TEMP1, TEMP2.Length - 8, privAllocator);
+	memcpy(IV2.Data, TEMP2.Data, 8);
+	memcpy(TEMP1.Data, TEMP2.Data + 8, TEMP1.Length);
+	dumpBuf("unwrap TEMP1", &TEMP1, 48);
+
+	/* 
+	 * 2. Encrypt PRIVATE_KEY_BYTES using DEK (3DES) and IV in CBC mode with
+     *    PKCS1 padding.  Call the ciphertext TEMP1
+	 *
+	 * i.e., decrypt TEMP1 to get PRIVATE_KEY_BYTES. Use IV2, not caller's 
+	 * IV. We already saved caller's IV in savediV and savedIvLen.
+	 */
+	IV1 = IV2;
+	CssmData PRIVATE_KEY_BYTES;
+	try {
+		DecryptData(CCHandle,
+			Context,
+			&TEMP1,				// CipherBufs[],
+			1,					// CipherBufCount,
+			&PRIVATE_KEY_BYTES,	// ClearBufs[]
+			1,					// ClearBufCount
+			bytesDecrypted,
+			remData,
+			Privilege);
+	}
+	catch(...) {
+		IV1.Data = savedIV;
+		IV1.Length = savedIvLen;
+		throw;
+	}
+	IV1.Data = savedIV;
+	// I'm not 100% sure about this....
+	assert(remData.Length == 0);
+	PRIVATE_KEY_BYTES.Length = bytesDecrypted;
+	dumpBuf("unwrap PRIVATE_KEY_BYTES", &PRIVATE_KEY_BYTES, 64);
+
+	/*
+	 * 1. PRIVATE_KEY_BYTES is the private data to be wrapped. It consists of the 
+	 *    following concatenation:
+	 *
+	 *    4-byte length of Descriptive Data, big-endian  |
+	 *    Descriptive Data | 
+	 *    rawBlob.Data bytes
+	 */
+	if(PRIVATE_KEY_BYTES.Length < 4) {
+		dprintf0("UnwrapKeyCms: short PRIVATE_KEY_BYTES\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+	uint8 *cp1 = PRIVATE_KEY_BYTES.Data;
+	uint32 ddLen = deserializeUint32(cp1);
+	cp1 += 4;
+	if(ddLen > MAX_MALLOC_SIZE) {
+		dprintf0("UnwrapKeyCms: preposterous ddLen in PRIVATE_KEY_BYTES\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+	setUpCssmData(DescriptiveData, ddLen, normAllocator);
+	memcpy(DescriptiveData.Data, cp1, ddLen);
+	cp1 += ddLen;
+	uint32 outBlobLen = PRIVATE_KEY_BYTES.Length - ddLen - 4;
+	if(ddLen > MAX_MALLOC_SIZE) {
+		dprintf0("UnwrapKeyCms: preposterous outBlobLen in PRIVATE_KEY_BYTES\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+	CssmData &outBlob = CssmData::overlay(UnwrappedKey.KeyData);
+	setUpCssmData(outBlob, outBlobLen, normAllocator);
+	memcpy(outBlob.Data, cp1, outBlobLen);
+
+	/* set up outgoing header */
+	UnwrappedKey.KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
+	UnwrappedKey.KeyHeader.Format   = inferFormat(UnwrappedKey);
+
+	/* 
+	 * Cook up a BinaryKey if caller wants a reference key.
+	 */
+	if(keyStorage == CKS_Ref) {
+		BinaryKey *binKey = NULL;
+		CSPKeyInfoProvider *provider = infoProvider(UnwrappedKey);
+		provider->CssmKeyToBinary(&binKey);
+		addRefKey(*binKey, UnwrappedKey);
+		delete provider;
+	}
+	/* free resources */
+	freeCssmData(PRIVATE_KEY_BYTES, normAllocator);	// alloc via decrypt
+	freeCssmData(TEMP1, privAllocator);		
+	freeCssmData(IV2, privAllocator);		
+	freeCssmData(TEMP2, privAllocator); 
+	freeCssmData(TEMP3, normAllocator);		// via decrypt 
+
+}
+
diff --git a/AppleCSP/AppleCSPPlugin.cpp b/AppleCSP/AppleCSPPlugin.cpp
new file mode 100644
index 00000000..d6c22cbd
--- /dev/null
+++ b/AppleCSP/AppleCSPPlugin.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 obtai
+n
+ * 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.
+ */
+
+
+//
+// Produce the "genuine plugin version" of the AppleCSP
+//
+#include <AppleCSP.h>
+
+
+//
+// Create the plugin object and generate the C layer hookup
+//
+ModuleNexus<AppleCSPPlugin> plugin;
+
+#include <Security/pluginspi.h>
diff --git a/AppleCSP/BSafeCSP/algmaker.cpp b/AppleCSP/BSafeCSP/algmaker.cpp
new file mode 100644
index 00000000..474e63b9
--- /dev/null
+++ b/AppleCSP/BSafeCSP/algmaker.cpp
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// algmaker - algorithm factory for BSafe 4
+//
+#include "bsafecspi.h"
+#include "bsafecsp.h"
+#include "AppleCSPSession.h"
+
+//
+// BSafe's Chooser table. 
+// These are references to all *BSafe algorithms* we use (and thus must link in)
+//
+const B_ALGORITHM_METHOD * const BSafe::bsChooser[] = {
+    // digests
+    &AM_SHA,
+    &AM_MD5,
+	&AM_MD2,
+
+    // organizational
+    &AM_CBC_ENCRYPT,
+    &AM_CBC_DECRYPT,
+    &AM_ECB_ENCRYPT,
+    &AM_ECB_DECRYPT,
+    &AM_OFB_ENCRYPT,
+    &AM_OFB_DECRYPT,
+
+    // DES & variants
+    &AM_DES_ENCRYPT,
+    &AM_DES_DECRYPT,
+    &AM_DESX_ENCRYPT,
+    &AM_DESX_DECRYPT,
+    &AM_DES_EDE_ENCRYPT,
+    &AM_DES_EDE_DECRYPT,
+
+    // RCn stuff
+    &AM_RC2_CBC_ENCRYPT,
+    &AM_RC2_CBC_DECRYPT,
+    &AM_RC2_ENCRYPT,
+    &AM_RC2_DECRYPT,
+    &AM_RC4_ENCRYPT,
+    &AM_RC4_DECRYPT,
+    &AM_RC5_ENCRYPT,
+    &AM_RC5_DECRYPT,
+    &AM_RC5_CBC_ENCRYPT,
+    &AM_RC5_CBC_DECRYPT,
+
+    // RSA
+    &AM_RSA_STRONG_KEY_GEN,
+    &AM_RSA_KEY_GEN,
+    &AM_RSA_CRT_ENCRYPT_BLIND,
+    &AM_RSA_CRT_DECRYPT_BLIND,
+    &AM_RSA_ENCRYPT,
+    &AM_RSA_DECRYPT,
+
+    // DSA
+    &AM_DSA_PARAM_GEN,
+    &AM_DSA_KEY_GEN,
+
+    // signatures
+    &AM_DSA_SIGN,
+    &AM_DSA_VERIFY,
+
+    // random number generation
+    &AM_MD5_RANDOM,
+    &AM_SHA_RANDOM,
+
+    // sentinel
+    (B_ALGORITHM_METHOD *)NULL_PTR
+};
+
+
+//
+// Makers
+//
+template <class Ctx>
+class Maker0 : public BSafe::MakerBase {
+public:
+	Ctx *make(AppleCSPSession &session, const Context &context) const
+	{ return new Ctx(session, context); }
+};
+
+template <class Ctx, class Arg>
+class Maker1 : public BSafe::MakerBase {
+	Arg arg;
+public:
+	Maker1(Arg a) : arg(a) { }
+	Ctx *make(AppleCSPSession &session, const Context &context) const
+	{ return new Ctx(session, context, arg); }
+};
+
+template <class Ctx, class Arg1, class Arg2>
+class Maker2 : public BSafe::MakerBase {
+	Arg1 arg1; Arg2 arg2;
+public:
+	Maker2(Arg1 a1, Arg2 a2) : arg1(a1), arg2(a2) { }
+	Ctx *make(AppleCSPSession &session, const Context &context) const
+	{ return new Ctx(session, context, arg1, arg2); }
+};
+
+template <class Ctx, class Arg1, class Arg2, class Arg3>
+class Maker3 : public BSafe::MakerBase {
+	Arg1 arg1; Arg2 arg2; Arg3 arg3;
+public:
+	Maker3(Arg1 a1, Arg2 a2, Arg3 a3) : 
+		arg1(a1), arg2(a2), arg3(a3) { }
+	Ctx *make(AppleCSPSession &session, const Context &context) const
+	{ return new Ctx(session, context, arg1, arg2, arg3); }
+};
+
+
+bug_const BSafe::MakerTable BSafe::algorithms[] = {
+    // signing algorithms
+	// constructor args: BSafe algorithm, signature size
+    { 
+		CSSM_ALGID_SHA1WithDSA, 
+		CSSM_ALGCLASS_SIGNATURE,
+		new Maker2<SigningContext, B_INFO_TYPE, size_t>
+			(AI_DSAWithSHA1, 48) 			// max size of 48 bytes
+	},
+    { 
+		CSSM_ALGID_SHA1WithRSA, 
+		CSSM_ALGCLASS_SIGNATURE,
+		new Maker2<SigningContext, B_INFO_TYPE, size_t>
+			(AI_SHA1WithRSAEncryption, 0) 	// size = RSA key size
+	},
+	
+    { 
+		CSSM_ALGID_MD5WithRSA, 
+		CSSM_ALGCLASS_SIGNATURE,
+		new Maker2<SigningContext, B_INFO_TYPE, size_t>
+			(AI_MD5WithRSAEncryption, 0) 	// size = RSA key size
+	},
+	
+    { 
+		CSSM_ALGID_MD2WithRSA, 
+		CSSM_ALGCLASS_SIGNATURE,
+		new Maker2<SigningContext, B_INFO_TYPE, size_t>
+			(AI_MD2WithRSAEncryption, 0) 	// size = RSA key size
+	},
+	
+    // MAC algorithms
+	// constructor args: BSafe algorithm, signature size
+    { 
+		CSSM_ALGID_SHA1HMAC,	
+		CSSM_ALGCLASS_MAC,
+		new Maker2<MacContext, B_INFO_TYPE, size_t>
+			(AI_SHA1, 20) 
+	},
+
+	// symmetric key generation
+	// constructor args: min/max key size in bits, mustBeByteSized
+    { 
+		CSSM_ALGID_RC2,	
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker3<SymmetricKeyGenContext, uint32, uint32, bool>
+			(1*8, 128*8, true) 
+	},
+    { 
+		CSSM_ALGID_RC4,	
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker3<SymmetricKeyGenContext, uint32, uint32, bool>
+			(1*8, 256*8, true) 
+	},
+    { 
+		CSSM_ALGID_RC5,	
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker3<SymmetricKeyGenContext, uint32, uint32, bool>
+			(1*8, 255*8, true) 
+	},
+    { 
+		CSSM_ALGID_DES,	
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker3<SymmetricKeyGenContext, uint32, uint32, bool>
+			(64, 64, true) 
+	},
+    { 
+		CSSM_ALGID_DESX,	
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker3<SymmetricKeyGenContext, uint32, uint32, bool>
+			(192, 192, true) 
+	},
+    { 
+		CSSM_ALGID_3DES_3KEY,	
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker3<SymmetricKeyGenContext, uint32, uint32, bool>
+			(192, 192, true) 
+	},
+    { 
+		CSSM_ALGID_SHA1HMAC,	
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker3<SymmetricKeyGenContext, uint32, uint32, bool>
+			(160, 2048, true) 
+	},
+	
+    // symmetric encryption algorithms
+	// constructor arg: block size (1 ==> stream cipher)
+    { 
+		CSSM_ALGID_DES,
+		CSSM_ALGCLASS_SYMMETRIC,		
+		new Maker1<BlockCipherContext, size_t>(8)
+	},
+    { 
+		CSSM_ALGID_DESX,
+		CSSM_ALGCLASS_SYMMETRIC,
+		new Maker1<BlockCipherContext, size_t>(8)
+	},
+    { 
+		CSSM_ALGID_3DES_3KEY_EDE,
+		CSSM_ALGCLASS_SYMMETRIC,
+		new Maker1<BlockCipherContext, size_t>(8)
+	},
+    { 
+		CSSM_ALGID_RC2,
+		CSSM_ALGCLASS_SYMMETRIC,
+		new Maker1<BlockCipherContext, size_t>(8)
+	},
+    { 
+		CSSM_ALGID_RC4,
+		CSSM_ALGCLASS_SYMMETRIC,
+		new Maker1<BlockCipherContext, size_t>(1)
+	},
+    { 
+		CSSM_ALGID_RC5,
+		CSSM_ALGCLASS_SYMMETRIC,
+		new Maker1<BlockCipherContext, size_t>(8)
+	},
+
+    // asymmetric encryption algorithms
+    { 
+		CSSM_ALGID_RSA,		
+		CSSM_ALGCLASS_ASYMMETRIC,
+		new Maker0<PublicKeyCipherContext>()
+	},
+    { 
+		CSSM_ALGID_DSA,
+		CSSM_ALGCLASS_ASYMMETRIC,
+		new Maker0<PublicKeyCipherContext>()
+	},
+	
+	// key pair generate algorithms
+    { 
+		CSSM_ALGID_RSA,		
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker0<BSafeKeyPairGenContext>()
+	},
+    { 
+		CSSM_ALGID_DSA,
+		CSSM_ALGCLASS_KEYGEN,
+		new Maker0<BSafeKeyPairGenContext>()
+	},
+	
+	// pseudo-random number generators
+	{ 
+		CSSM_ALGID_MD5Random,	
+		CSSM_ALGCLASS_RANDOMGEN,
+		new Maker1<RandomContext, B_INFO_TYPE>(AI_MD5Random) 
+	},
+	{ 
+		CSSM_ALGID_SHARandom, 
+		CSSM_ALGCLASS_RANDOMGEN,
+		new Maker1<RandomContext, B_INFO_TYPE>(AI_SHA1Random) 
+	},
+};
+
+const unsigned int BSafe::algorithmCount = sizeof(algorithms) / sizeof(algorithms[0]);
+
+
+//
+// BSafeFactory hookup
+//
+void BSafeFactory::setNormAllocator(CssmAllocator *alloc)
+{
+	BSafe::setNormAllocator(alloc);
+}
+void BSafeFactory::setPrivAllocator(CssmAllocator *alloc)
+{
+	BSafe::setPrivAllocator(alloc);
+}
+
+bool BSafeFactory::setup(
+	AppleCSPSession &session,
+	CSPFullPluginSession::CSPContext * &cspCtx, 
+	const Context &context)
+{
+	return BSafe::setup(session, cspCtx, context);
+}
+
+
+//
+// Algorithm setup
+//
+bool BSafe::setup(
+	AppleCSPSession &session,
+	CSPFullPluginSession::CSPContext * &cspCtx, 
+	const Context &context)
+{
+    for (const BSafe::MakerTable *alg = algorithms; 
+	     alg < algorithms + algorithmCount; 
+		 alg++) {
+        if ((alg->algorithmId == context.algorithm()) &&
+		    (alg->algClass == context.type())) {
+				if(cspCtx != NULL) {
+					/* we allow reuse */
+					return true;
+				}
+				// make new context
+				cspCtx = alg->maker->make(session, context);
+				return true;
+        }
+	}
+	/* not ours */
+    return false;
+}
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/bsafeAsymmetric.cpp b/AppleCSP/BSafeCSP/bsafeAsymmetric.cpp
new file mode 100644
index 00000000..7cffdd25
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsafeAsymmetric.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// bsafeAsymmetric.cpp - asymmetric encrypt/decrypt
+//
+#include "bsafecspi.h"
+
+#include <stdio.h>	// debug
+
+//
+// Public key {en,de}cryption (currently RSA only)
+//
+// FIXME:
+// We really should match the key algorithm to the en/decrypt
+// algorithm. Also: verify key usage bits. 
+void BSafe::PublicKeyCipherContext::init(const Context &context, bool encrypting)
+{
+	assert(context.algorithm() == CSSM_ALGID_RSA);
+	
+    if (reusing(encrypting))
+        return;		// all set to go
+    
+    switch (context.getInt(CSSM_ATTRIBUTE_MODE)) {
+        case CSSM_ALGMODE_PUBLIC_KEY:
+            setAlgorithm(AI_PKCS_RSAPublic);
+            break;
+        case CSSM_ALGMODE_PRIVATE_KEY:
+            setAlgorithm(AI_PKCS_RSAPrivate);
+            break;
+        case CSSM_ALGMODE_NONE:	
+		{
+			/* 
+			 * None specified (getInt returns zero in that case) - 
+			 * infer from key type 
+			 */
+			CssmKey &key = context.get<CssmKey>(
+				CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
+			B_INFO_TYPE bAlgType;
+			switch (key.keyClass()) {
+				case CSSM_KEYCLASS_PUBLIC_KEY:
+					bAlgType = AI_PKCS_RSAPublic;
+					break;
+				case CSSM_KEYCLASS_PRIVATE_KEY:
+					bAlgType = AI_PKCS_RSAPrivate;
+					break;
+				default:
+					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+			}
+            setAlgorithm(bAlgType);
+            break;
+		}
+        default:
+            CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
+    }
+
+    // put it all together
+    setKeyFromContext(context);		// set BSafe key
+    setRandom();					// some PK cryption algs need random input
+    cipherInit();					// common cipher init
+    //@@@ calculate output buffer size
+}
+
+// we assume asymmetric crypto algorithms are one-shot output non-repeating
+
+size_t BSafe::PublicKeyCipherContext::inputSize(size_t outSize)
+{
+    return 0xFFFFFFFF;	// perhaps not the biggest size_t, but big enough...
+}
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/bsafeContext.cpp b/AppleCSP/BSafeCSP/bsafeContext.cpp
new file mode 100644
index 00000000..a58f2afd
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsafeContext.cpp
@@ -0,0 +1,448 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// bsafeContext.cpp - implementation of class BSafe::BSafeContext
+//					  and some of its subclasses
+// 				
+
+#include "bsafecspi.h"
+#include "bsafePKCS1.h"
+#include <bkey.h>
+#include <balg.h>
+#include <algobj.h>
+#include "cspdebugging.h"
+
+#define DATA(cData)		POINTER(cData.data()), cData.length()
+
+A_SURRENDER_CTX * const BSafe::BSafeContext::bsSurrender = NULL;
+
+
+//
+// Construct an algorithm object
+//
+BSafe::BSafeContext::BSafeContext(AppleCSPSession &session)
+	: AppleCSPContext(session)
+{
+    bsAlgorithm = NULL;
+    bsKey = NULL;
+	bsBinKey = NULL;
+    bsRandom = NULL;
+    initialized = false;
+	opStarted = false;
+#ifdef SAFER
+    inUpdate = NULL;
+    inOutUpdate = NULL;
+    inFinal = NULL;
+    outFinal = NULL;
+    outFinalR = NULL;
+#endif //SAFER
+}
+
+BSafe::BSafeContext::~BSafeContext()
+{
+    reset();
+}
+
+void BSafe::BSafeContext::reset()
+{
+    B_DestroyAlgorithmObject(&bsAlgorithm);
+    B_DestroyAlgorithmObject(&bsRandom);
+	destroyBsKey();
+}
+
+/* 
+ * Clear key state. We only destroy bsKey if we don't have a 
+ * BinaryKey.
+ */
+void BSafe::BSafeContext::destroyBsKey()
+{
+	if(bsBinKey == NULL) {
+		B_DestroyKeyObject(&bsKey);
+	}
+	else {
+		// bsKey gets destroyed when bsBinKey gets deleted
+		bsBinKey = NULL;
+		bsKey = NULL;
+	}
+}
+
+void BSafe::check(int status, bool isKeyOp)
+{
+	if(status == 0) {
+		return;
+	}
+	dprintf1("BSAFE Error %d\n", status);
+    switch (status) {
+		case BE_ALLOC:
+			throw std::bad_alloc();
+		case BE_SIGNATURE:
+			CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
+		case BE_OUTPUT_LEN:
+			CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+		case BE_INPUT_LEN:
+			CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+		case BE_EXPONENT_EVEN:
+		case BE_EXPONENT_LEN:
+		case BE_EXPONENT_ONE:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+		case BE_DATA:
+		case BE_INPUT_DATA:
+			if(isKeyOp) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+			}
+			else {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_DATA);
+			}
+		case BE_MODULUS_LEN:
+		case BE_OVER_32K:
+		case BE_INPUT_COUNT:
+		case BE_CANCEL:
+			//@@@ later...
+        default:
+			//@@@ translate BSafe errors intelligently
+            CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+    }
+}
+
+
+void BSafe::BSafeContext::setAlgorithm(
+	B_INFO_TYPE bAlgType, 
+	const void *info)
+{
+    B_DestroyAlgorithmObject(&bsAlgorithm);	// clear any old BSafe algorithm
+    check(B_CreateAlgorithmObject(&bsAlgorithm));
+    check(B_SetAlgorithmInfo(bsAlgorithm, bAlgType, POINTER(info)));
+}
+
+/* safely create bsKey */
+void BSafe::BSafeContext::createBsKey()
+{
+	/* reset to initial key state - some keys can't be reused */
+    destroyBsKey();
+    check(B_CreateKeyObject(&bsKey));
+}
+
+/* form of *info varies per bKeyInfo */
+void BSafe::BSafeContext::setKeyAtom(
+	B_INFO_TYPE bKeyInfo, 
+	const void *info)
+{
+	/* debug only */
+	if((bKeyInfo == KI_RSAPublicBER) || (bKeyInfo == KI_RSAPublic)) {
+			printf("Aargh! Unhandled KI_RSAPublic!\n");
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+	assert(bKeyInfo != KI_RSAPublicBER);		// handled elsewhere for now
+	assert(bKeyInfo != KI_RSAPublic);			// handled elsewhere for now
+	createBsKey();
+    check(B_SetKeyInfo(bsKey, bKeyInfo, POINTER(info)), true);
+}
+
+//
+// Set outSize for RSA keys.
+//
+void BSafe::BSafeContext::setRsaOutSize(
+	bool isPubKey)
+{
+	assert(bsKey != NULL);
+
+	A_RSA_KEY *keyInfo;
+	if(isPubKey) {
+		keyInfo = getKey<A_RSA_KEY>(bsKey, KI_RSAPublic);
+	}
+	else {
+		keyInfo = getKey<A_RSA_KEY>(bsKey, KI_RSAPrivate);
+	}
+	mOutSize = (B_IntegerBits(keyInfo->modulus.data, 
+		keyInfo->modulus.len) + 7) / 8;
+}
+
+// 
+// Handle various forms of reference key. Symmetric
+// keys are stored as SymmetricBinaryKey, with raw key bytes
+// in keyData. Our asymmetric keys are stored as BSafeBinaryKeys,
+// with an embedded ready-to-use B_KEY_OBJ. 
+// 
+void BSafe::BSafeContext::setRefKey(CssmKey &key)
+{
+	bool isPubKey = false;
+	
+	switch(key.keyClass()) {
+		case CSSM_KEYCLASS_SESSION_KEY:
+		{
+			assert(key.blobFormat() == 
+				CSSM_KEYBLOB_REF_FORMAT_INTEGER);
+			
+			BinaryKey &binKey = session().lookupRefKey(key);
+			// fails if this is not a SymmetricBinaryKey
+			SymmetricBinaryKey *symBinKey =
+				dynamic_cast<SymmetricBinaryKey *>(&binKey);
+			if(symBinKey == NULL) {
+				errorLog0("BSafe::setRefKey(1): wrong BinaryKey subclass\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+			}
+			setKeyFromCssmData(KI_Item, symBinKey->mKeyData);
+			return;
+		}
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			isPubKey = true;		// and fall thru
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+		{
+			BinaryKey &binKey = session().lookupRefKey(key);
+			destroyBsKey();
+			bsBinKey = dynamic_cast<BSafeBinaryKey *>(&binKey);
+			/* this cast failing means that this is some other
+			 * kind of binary key */
+			if(bsBinKey == NULL) {
+				errorLog0("BSafe::setRefKey(2): wrong BinaryKey subclass\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+			}
+			assert(bsBinKey->bsKey() != NULL);
+			bsKey = bsBinKey->bsKey();
+			if(key.algorithm() == CSSM_ALGID_RSA) {
+				setRsaOutSize(isPubKey);
+			}
+			return;
+		}
+		default:
+		    CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+}
+
+void BSafe::BSafeContext::setKeyFromContext(
+	const Context &context, 
+	bool required)
+{
+    CssmKey &key = 
+		context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
+	
+	switch(key.blobType()) {
+		case CSSM_KEYBLOB_REFERENCE:
+			setRefKey(key);
+			return;
+		case CSSM_KEYBLOB_RAW:
+			break;		// to main routine
+		default:
+			CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
+	}
+	
+	bool isPubKey;
+	switch (key.keyClass()) {
+		case CSSM_KEYCLASS_SESSION_KEY:
+			/* symmetric, one format supported for all algs */
+			switch (key.blobFormat()) {
+				case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING:
+					setKeyFromCssmKey(KI_Item, key);
+					return;
+				default:
+					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+			}
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			isPubKey = true;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			isPubKey = false;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	
+	/* We know it's an asymmetric key; get some info */
+	B_INFO_TYPE infoType;
+	CSSM_KEYBLOB_FORMAT expectedFormat;
+	
+	if(!bsafeAlgToInfoType(key.algorithm(),
+		isPubKey,
+		infoType, 
+		expectedFormat)) {
+		/* unknown alg! */
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+	
+	/* 
+	 * Correct format? 
+	 * NOTE: if we end up supporting multiple incoming key formats, they'll
+	 * have to be handled here.
+	 */
+	if(expectedFormat != key.blobFormat()) {
+		errorLog1("setKeyFromContext: invalid blob format (%d)\n", 
+			(int)key.blobFormat());
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+	}
+	
+	/*
+	 * Most formats can be handled directly by BSAFE. Handle the special cases 
+	 * requiring additional processing here. 
+	 */
+	switch(expectedFormat)  {
+		case CSSM_KEYBLOB_RAW_FORMAT_PKCS1:
+			/* RSA public keys */
+			createBsKey();
+			BS_setKeyPkcs1(CssmData::overlay(key.KeyData), bsKey);
+			break;
+		default:
+			setKeyFromCssmKey(infoType, key);
+			break;
+	}
+	
+	/* 
+	 * One more thing - set mOutSize for RSA keys
+	 */
+	if(key.algorithm() == CSSM_ALGID_RSA) {
+		setRsaOutSize(isPubKey);	
+	}	
+}
+
+#define BSAFE_RANDSIZE	32
+
+void BSafe::BSafeContext::setRandom()
+{
+    if (bsRandom == NULL) {
+        check(B_CreateAlgorithmObject(&bsRandom));
+        check(B_SetAlgorithmInfo(bsRandom, AI_X962Random_V0, NULL_PTR));
+        check(B_RandomInit(bsRandom, chooser(), bsSurrender));
+        uint8 seed[BSAFE_RANDSIZE];
+		session().getRandomBytes(BSAFE_RANDSIZE, seed);
+        check(B_RandomUpdate(bsRandom, seed, sizeof(seed), bsSurrender));
+    }
+}
+
+
+//
+// Operational methods of BSafeContext
+//
+void BSafe::BSafeContext::init(const Context &, bool)
+{
+    // some algorithms don't need init(), because all is done in the context constructor
+}
+
+// update for input-only block/stream algorithms
+void BSafe::BSafeContext::update(const CssmData &data)
+{
+	opStarted = true;
+    check(inUpdate(bsAlgorithm, POINTER(data.data()), data.length(), bsSurrender));
+}
+
+// update for input/output block/stream algorithms
+void BSafe::BSafeContext::update(void *inp, size_t &inSize, void *outp, size_t &outSize)
+{
+    unsigned int length;
+	opStarted = true;
+    check(inOutUpdate(bsAlgorithm, POINTER(outp), &length, outSize,
+                               POINTER(inp), inSize, bsRandom, bsSurrender));
+    // always eat all input (inSize unchanged)
+    outSize = length;
+
+    // let the algorithm manager track I/O sizes, if needed
+    trackUpdate(inSize, outSize);
+}
+
+// output-generating final call
+void BSafe::BSafeContext::final(CssmData &out)
+{
+    unsigned int length;
+    if (outFinal) {
+        check(outFinal(bsAlgorithm, 
+			POINTER(out.data()), 
+			&length, 
+			out.length(), 
+			bsSurrender));
+	}
+    else {
+        check(outFinalR(bsAlgorithm, 
+			POINTER(out.data()), 
+			&length, 
+			out.length(),
+			bsRandom, 
+			bsSurrender));
+	}
+    out.length(length);
+	initialized = false;
+}
+
+// verifying final call (takes additional input)
+void BSafe::BSafeContext::final(const CssmData &in)
+{
+ 	int status;
+	
+	/* note sig verify errors can show up as lots of BSAFE statuses;
+	 * munge them all into the appropriate error */
+   if (inFinal) {
+        status = inFinal(bsAlgorithm, 
+			POINTER(in.data()), 
+			in.length(), 
+			bsSurrender);
+	}
+    else {
+        status = inFinalR(bsAlgorithm, 
+			POINTER(in.data()), 
+			in.length(), 
+			bsRandom, 
+			bsSurrender);
+	}
+	if(status != 0) {
+		if((mType == CSSM_ALGCLASS_SIGNATURE) && (mDirection == false)) {
+			/* yep, sig verify error */
+			CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
+		}
+		/* other error, use standard trap */
+		check(status);
+	}
+	initialized = false;
+}
+
+size_t BSafe::BSafeContext::outputSize(bool final, size_t inSize)
+{
+    // this default implementation only makes sense for single-output end-loaded algorithms
+    return final ? mOutSize : 0;
+}
+
+void BSafe::BSafeContext::trackUpdate(size_t, size_t)
+{ /* do nothing */ }
+
+//
+// Common features of CipherContexts.
+//
+void BSafe::CipherContext::cipherInit()
+{
+    // set handlers
+    if (encoding) {
+        inOutUpdate = B_EncryptUpdate;
+        outFinalR = B_EncryptFinal;
+    } else {
+        inOutUpdate = B_DecryptUpdate;
+        outFinalR = B_DecryptFinal;
+    }
+    outFinal = NULL;
+
+    // init the algorithm
+    check((encoding ? B_EncryptInit : B_DecryptInit)
+          (bsAlgorithm, bsKey, chooser(), bsSurrender));
+
+    // buffers start empty
+    pending = 0;
+
+    // state is now valid
+    initialized = true;
+	opStarted = false;
+}
+#endif	/* BSAFE_CSP_ENABLE */
+
diff --git a/AppleCSP/BSafeCSP/bsafeKeyGen.cpp b/AppleCSP/BSafeCSP/bsafeKeyGen.cpp
new file mode 100644
index 00000000..088f2098
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsafeKeyGen.cpp
@@ -0,0 +1,449 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// bsafeKeyGen.cpp - key generation routines
+//
+#include "bsafecspi.h"
+#include "bsafePKCS1.h"
+#include "cspdebugging.h"
+
+/*
+ * Stateless, private function to map a CSSM alg and pub/priv state
+ * to B_INFO_TYPE and format. Returns true on success, false on
+ * "I don't understand this algorithm". 
+ */
+bool BSafe::bsafeAlgToInfoType(
+	CSSM_ALGORITHMS		alg,
+	bool				isPublic,
+	B_INFO_TYPE			&infoType,	// RETURNED
+	CSSM_KEYBLOB_FORMAT	&format)	// RETURNED
+{
+ 	switch(alg) {
+		case CSSM_ALGID_RSA:
+			if(isPublic) {
+				infoType = RSA_PUB_KEYINFO_TYPE;
+				format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
+			}
+			else {
+				infoType = RSA_PRIV_KEYINFO_TYPE;
+				format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
+			}
+			return true;
+		case CSSM_ALGID_DSA:
+			format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
+			if(isPublic) {
+				infoType = DSA_PUB_KEYINFO_TYPE;
+			}
+			else {
+				infoType = DSA_PRIV_KEYINFO_TYPE;
+			}
+			return true;
+		default:
+			return false;
+	}
+}
+
+
+BSafe::BSafeBinaryKey::BSafeBinaryKey(
+	bool isPub,
+	uint32 Alg)
+	: mIsPublic(isPub),
+	  mAlg(Alg)
+{
+	BSafe::check(B_CreateKeyObject(&mBsKey), true);
+}
+
+BSafe::BSafeBinaryKey::~BSafeBinaryKey()
+{
+	B_DestroyKeyObject(&mBsKey);
+}
+
+void BSafe::BSafeBinaryKey::generateKeyBlob(
+		CssmAllocator 		&allocator,
+		CssmData			&blob,
+		CSSM_KEYBLOB_FORMAT	&format)		// input val ignored for now
+{
+ 	assert(mBsKey != NULL);
+
+	B_INFO_TYPE 	bsType;
+	if(!bsafeAlgToInfoType(mAlg, mIsPublic, bsType, format)) {
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	if(format == CSSM_KEYBLOB_RAW_FORMAT_PKCS1) {
+		/* special case, encode the PKCS1 format blob */
+		CssmRemoteData rData(
+			CssmAllocator::standard(CssmAllocator::sensitive), blob);
+		BS_GetKeyPkcs1(mBsKey, rData); 
+		rData.release();
+	}
+	else {
+		BSafeItem *info;
+		BSafe::check(
+			B_GetKeyInfo((POINTER *)&info, mBsKey, bsType), true);
+		blob = info->copy<CssmData>(allocator);
+	}
+}
+
+//
+// This is called from CSPFullPluginSession
+//
+void BSafe::BSafeKeyPairGenContext::generate(
+	const Context 	&context, 
+	CssmKey 		&pubKey, 
+	CssmKey 		&privKey)
+{
+	BSafeBinaryKey	*pubBinKey  = new BSafeBinaryKey(true, 
+		context.algorithm());
+	BSafeBinaryKey	*privBinKey = new BSafeBinaryKey(false, 
+		context.algorithm());
+	
+	try {
+		AppleKeyPairGenContext::generate(context, 
+			session(),
+			pubKey, 
+			pubBinKey, 
+			privKey, 
+			privBinKey);
+	}
+	catch (...) {
+		delete pubBinKey;
+		delete privBinKey;
+		throw;
+	}
+}
+
+//
+// Called from AppleKeyPairGenContext
+//
+void BSafe::BSafeKeyPairGenContext::generate(
+		const Context 	&context,
+		BinaryKey		&pubBinKey,		// valid on successful return
+		BinaryKey		&privBinKey,	// ditto
+		uint32			&keySize)		// ditto
+{
+	/* these casts throw exceptions if the keys are of the 
+	 * wrong classes, which is a major bogon, since we created
+	 * the keys in the above generate() function */
+	BSafeBinaryKey &bsPubBinKey = 
+		dynamic_cast<BSafeBinaryKey &>(pubBinKey);
+	BSafeBinaryKey &bsPrivBinKey = 
+		dynamic_cast<BSafeBinaryKey &>(privBinKey);
+	
+    if (!initialized) {
+		setupAlgorithm(context, keySize);
+        check(B_GenerateInit(bsAlgorithm, chooser(), bsSurrender), true);
+        initialized = true;
+    }
+
+	setRandom();
+    check(B_GenerateKeypair(bsAlgorithm, 
+		bsPubBinKey.bsKey(), 
+		bsPrivBinKey.bsKey(), 
+		bsRandom, 
+		bsSurrender), true);
+}
+
+void BSafe::BSafeKeyPairGenContext::setupAlgorithm(
+	const Context 	&context,
+	uint32			&keySize)
+{
+	switch(context.algorithm()) {
+		case CSSM_ALGID_RSA:
+		{
+			A_RSA_KEY_GEN_PARAMS genParams;
+			keySize = genParams.modulusBits = 
+				context.getInt(CSSM_ATTRIBUTE_KEY_LENGTH,
+							CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH);
+			if (CssmData *params = 
+				context.get<CssmData>(CSSM_ATTRIBUTE_ALG_PARAMS)) {
+				genParams.publicExponent = BSafeItem(*params);
+			} else {
+				static unsigned char exponent[] = { 1, 0, 1 };
+				genParams.publicExponent = BSafeItem(exponent, sizeof(exponent));
+			}
+			/*
+			 * For test purposes, we avoid the 'strong' key generate
+			 * algorithm if a CSSM_ALGMODE_CUSTOM mode atrtribute
+			 * is present in the context. This is not published and
+			 * not supported in the real world. 
+			 */
+			uint32 mode = context.getInt(CSSM_ATTRIBUTE_MODE);
+			if(mode == CSSM_ALGMODE_CUSTOM) {
+				setAlgorithm(AI_RSAKeyGen, &genParams);
+			}
+			else {
+				setAlgorithm(AI_RSAStrongKeyGen, &genParams);
+			}
+		}
+			break;
+		case CSSM_ALGID_DSA:
+		{
+			A_DSA_PARAMS genParams;
+			genParams.prime = 
+				BSafeItem(context.get<CssmData>(
+					CSSM_ATTRIBUTE_PRIME,
+					CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS));
+			genParams.subPrime = 
+				BSafeItem(context.get<CssmData>(
+					CSSM_ATTRIBUTE_SUBPRIME,
+					CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS));
+			genParams.base = 
+				BSafeItem(context.get<CssmData>(
+					CSSM_ATTRIBUTE_BASE,
+					CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS));
+			setAlgorithm(AI_DSAKeyGen, &genParams);
+			keySize = B_IntegerBits(genParams.prime.data, genParams.prime.len);
+		}
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+}
+
+//
+// DSA Parameter Generation
+//
+void BSafe::BSafeKeyPairGenContext::generate(
+	const Context &context, 
+	uint32 bitSize,
+    CssmData &params,
+    uint32 &attrCount, 
+	Context::Attr * &attrs)
+{
+	assert(context.algorithm() == CSSM_ALGID_DSA);
+	
+    B_ALGORITHM_OBJ genAlg = NULL;
+    B_ALGORITHM_OBJ result = NULL;
+
+    try {
+        check(B_CreateAlgorithmObject(&genAlg));
+
+        B_DSA_PARAM_GEN_PARAMS genParams;
+        genParams.primeBits = bitSize;
+        check(B_SetAlgorithmInfo(genAlg, AI_DSAParamGen, POINTER(&genParams)));
+        setRandom();
+        check(B_GenerateInit(genAlg, chooser(), bsSurrender), true);
+        check(B_CreateAlgorithmObject(&result));
+        check(B_GenerateParameters(genAlg, result, bsRandom, bsSurrender));
+
+        // get parameters out of algorithm object
+        A_DSA_PARAMS *kParams = NULL;
+        check(B_GetAlgorithmInfo((POINTER *)&kParams, result, AI_DSAKeyGen), true);
+
+        // shred them into context attribute form
+        attrs = normAllocator->alloc<Context::Attr>(3);
+        attrs[0] = Context::Attr(CSSM_ATTRIBUTE_PRIME,
+                   *BSafeItem(kParams->prime).copyp<CssmData>(*normAllocator));
+        attrs[1] = Context::Attr(CSSM_ATTRIBUTE_SUBPRIME,
+                   *BSafeItem(kParams->subPrime).copyp<CssmData>(*normAllocator));
+        attrs[2] = Context::Attr(CSSM_ATTRIBUTE_BASE,
+                   *BSafeItem(kParams->base).copyp<CssmData>(*normAllocator));
+        attrCount = 3;
+
+        // clean up
+        B_DestroyAlgorithmObject(&result);
+        B_DestroyAlgorithmObject(&genAlg);
+    } catch (...) {
+        // clean up
+        B_DestroyAlgorithmObject(&result);
+        B_DestroyAlgorithmObject(&genAlg);
+        throw;
+    }
+}
+
+/*
+ * CSPKeyInfoProvider for asymmetric BSAFE keys. 
+ */
+BSafe::BSafeKeyInfoProvider::BSafeKeyInfoProvider(
+	const CssmKey &cssmKey) :
+		CSPKeyInfoProvider(cssmKey)
+{
+	switch(mKey.keyClass()) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	switch(mKey.algorithm()) {
+		case CSSM_ALGID_RSA:
+		case CSSM_ALGID_DSA:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	/* OK, we'll handle this one */
+	return;
+}
+
+/* cook up a Binary key */
+void BSafe::BSafeKeyInfoProvider::CssmKeyToBinary(
+	BinaryKey **binKey)
+{
+	*binKey = NULL;
+	
+	const CSSM_KEYHEADER *hdr = &mKey.KeyHeader;
+	assert(hdr->BlobType == CSSM_KEYBLOB_RAW); 
+	
+	B_INFO_TYPE 		bsType;
+	CSSM_KEYBLOB_FORMAT	format;
+	bool 				isPub;
+	
+	switch(hdr->KeyClass) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			isPub = true;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			isPub = false;
+			break;
+		default:
+			// someone else's key
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	if(!bsafeAlgToInfoType(hdr->AlgorithmId, isPub, bsType, format)) {
+		// someone else's key
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	if(hdr->Format != format) {	
+		dprintf0("BSafe::cssmKeyToBinary: format mismatch\n");
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+	}
+		
+	BSafeBinaryKey *bsBinKey = new BSafeBinaryKey(isPub,
+		hdr->AlgorithmId);
+		
+	// set up key material as appropriate
+	if(format == CSSM_KEYBLOB_RAW_FORMAT_PKCS1) {
+		/* special case, decode the PKCS1 format blob */
+		BS_setKeyPkcs1(mKey, bsBinKey->bsKey());
+	}
+	else {
+		/* normal case, use key blob as is */
+		BSafeItem item(mKey.KeyData);
+		BSafe::check(
+			B_SetKeyInfo(bsBinKey->bsKey(), bsType, POINTER(&item)), true);
+	}
+	*binKey = bsBinKey;
+}
+		
+/* 
+ * Obtain key size in bits.
+ */
+void BSafe::BSafeKeyInfoProvider::QueryKeySizeInBits(
+	CSSM_KEY_SIZE &keySize)
+{
+	if(mKey.blobType() != CSSM_KEYBLOB_RAW) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+	}
+	
+	/* cook up BSAFE key */
+	B_KEY_OBJ bKey;
+	A_RSA_KEY *rsaKeyInfo = NULL;
+	A_DSA_PUBLIC_KEY *dsaPubKeyInfo = NULL;
+	A_DSA_PRIVATE_KEY *dsaPrivKeyInfo = NULL;
+	ITEM *sizeItem = NULL;
+	BSafe::check(B_CreateKeyObject(&bKey), true);
+	B_INFO_TYPE infoType;
+	
+	switch(mKey.algorithm()) {
+		case CSSM_ALGID_RSA:
+			switch(mKey.keyClass()) {
+				case CSSM_KEYCLASS_PUBLIC_KEY:
+					if(mKey.blobFormat() != 
+							CSSM_KEYBLOB_RAW_FORMAT_PKCS1) {
+						CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+					}
+					
+					/* convert from PKCS1 blob to raw key */
+					BS_setKeyPkcs1(mKey, bKey);
+					infoType = KI_RSAPublic;
+					/* break to common RSA code */
+					break;
+				case CSSM_KEYCLASS_PRIVATE_KEY:
+				{
+					if(mKey.blobFormat() != 
+							CSSM_KEYBLOB_RAW_FORMAT_PKCS8) {
+						CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+					}
+					
+					/* convert from PKCS8 blob to raw key */
+					BSafeItem item(mKey.KeyData);
+					BSafe::check(
+						B_SetKeyInfo(bKey, KI_PKCS_RSAPrivateBER,
+							POINTER(&item)), true);
+					infoType = KI_RSAPrivate;
+					break;
+				}
+				default:
+					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+			}
+			rsaKeyInfo = getKey<A_RSA_KEY>(bKey, infoType);
+			sizeItem = &rsaKeyInfo->modulus;
+			break;
+			
+		case CSSM_ALGID_DSA:
+			/* untested as of 9/11/00 */
+			if(mKey.blobFormat() != 
+					CSSM_KEYBLOB_RAW_FORMAT_FIPS186) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+			}
+			switch(mKey.keyClass()) {
+				case CSSM_KEYCLASS_PUBLIC_KEY:
+				{
+					BSafeItem item(mKey.KeyData);
+					BSafe::check(B_SetKeyInfo(bKey, 
+						DSA_PUB_KEYINFO_TYPE, 
+						(POINTER)&item), true);
+					
+					/* get the key bits */
+					dsaPubKeyInfo = getKey<A_DSA_PUBLIC_KEY>(bKey, 
+						KI_DSAPublic);
+					sizeItem = &dsaPubKeyInfo->params.prime;
+					break;
+				}
+				case CSSM_KEYCLASS_PRIVATE_KEY:
+				{
+					BSafeItem item(mKey.KeyData);
+					BSafe::check(B_SetKeyInfo(bKey, 
+						DSA_PRIV_KEYINFO_TYPE, 
+						(POINTER)&item), true);
+					
+					/* get the key bits */
+					dsaPrivKeyInfo = getKey<A_DSA_PRIVATE_KEY>(bKey, 
+						KI_DSAPrivate);
+					sizeItem = &dsaPrivKeyInfo->params.prime;
+					break;
+				}
+				default:
+					CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+			}
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	uint32 iSize = B_IntegerBits(sizeItem->data, sizeItem->len);
+	keySize.LogicalKeySizeInBits = iSize;
+	keySize.EffectiveKeySizeInBits = iSize;
+	B_DestroyKeyObject(&bKey);
+}
+
+#endif	/* BSAFE_CSP_ENABLE */
+
diff --git a/AppleCSP/BSafeCSP/bsafePKCS1.cpp b/AppleCSP/BSafeCSP/bsafePKCS1.cpp
new file mode 100644
index 00000000..80eaae27
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsafePKCS1.cpp
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+/*
+ * bsafePKCS1.cpp - support for PKCS1 format RSA public key blobs, which for some
+ * 					reason, BSAFE doesn't know about.
+ */
+
+#include "bsafePKCS1.h"
+#include "bsafecspi.h"
+#include "cspdebugging.h"
+#include "bsobjects.h"
+#include <Security/pkcs1oids.h>		/* for RSAPublicKey */
+#include <Security/cdsaUtils.h>
+#include <Security/cssmerrno.h>
+
+/*
+ * Simple conversion between BSAFE ITEM and snacc BigIntegerStr
+ */
+static void BS_ItemToSnaccBigInt(
+	const ITEM		&item,
+	BigIntegerStr	&snaccInt)
+{
+	snaccInt.Set(reinterpret_cast<const char *>(item.data), item.len);
+}
+
+/*  
+ * This one doesn't do a malloc - the ITEM is only valid as long as
+ * snaccInt is!
+ */
+static void BS_snaccBigIntToItem(
+	BigIntegerStr 		&snaccInt,	// not const - we're passing a ptr
+	ITEM				&item)
+{
+	char *cp = snaccInt;
+	item.data = reinterpret_cast<unsigned char *>(cp);
+	item.len = snaccInt.Len();
+}
+
+/*
+ * Given a PKCS1-formatted key blob, decode the blob into components and do 
+ * a B_SetKeyInfo on the specified BSAFE key.
+ */
+void BS_setKeyPkcs1(
+	const CssmData &pkcs1Blob, 
+	B_KEY_OBJ bsKey)
+{
+	/* DER-decode the blob */
+	RSAPublicKey snaccPubKey;
+	
+	try {
+		SC_decodeAsnObj(pkcs1Blob, snaccPubKey);
+	}
+	catch(CssmError cerror) {
+		CSSM_RETURN crtn = cerror.cssmError();
+		
+		errorLog1("BS_setKeyPkcs1: SC_decodeAsnObj returned %s\n",
+			cssmErrorString(crtn).c_str());
+		switch(crtn) {
+			case CSSMERR_CSSM_MEMORY_ERROR:
+				crtn = CSSMERR_CSP_MEMORY_ERROR;
+				break;
+			case CSSMERR_CSSM_INVALID_INPUT_POINTER:
+				crtn = CSSMERR_CSP_INVALID_KEY;
+			default:
+				break;
+		}
+		CssmError::throwMe(crtn);
+	}
+	
+	/* 
+	 * Convert BigIntegerStr modulus, publicExponent into
+	 * ITEMS in an A_RSA_KEY.
+	 */
+	A_RSA_KEY	rsaKey;
+	BS_snaccBigIntToItem(snaccPubKey.modulus, rsaKey.modulus);
+	BS_snaccBigIntToItem(snaccPubKey.publicExponent, rsaKey.exponent);
+	
+	BSafe::check(
+		B_SetKeyInfo(bsKey, KI_RSAPublic, POINTER(&rsaKey)), true);
+}
+
+/*
+ * Obtain public key blob info, PKCS1 format. 
+ */
+void BS_GetKeyPkcs1(
+	const B_KEY_OBJ bsKey, 
+	CssmOwnedData &pkcs1Blob)
+{
+	/* get modulus/exponent info from BSAFE */
+	A_RSA_KEY *rsaKey;
+	BSafe::check(
+		B_GetKeyInfo((POINTER *)&rsaKey, bsKey, KI_RSAPublic), true);
+		
+	/* Cook up a snacc-style RSAPublic key */
+	RSAPublicKey snaccPubKey;
+	BS_ItemToSnaccBigInt(rsaKey->modulus, snaccPubKey.modulus);
+	BS_ItemToSnaccBigInt(rsaKey->exponent, snaccPubKey.publicExponent);
+		
+	/* estimate max size, BER-encode */
+	size_t maxSize = 2 * (rsaKey->modulus.len + rsaKey->exponent.len);
+	try {
+		SC_encodeAsnObj(snaccPubKey, pkcs1Blob, maxSize);
+	}
+	catch(CssmError cerror) {
+		CSSM_RETURN crtn = cerror.cssmError();
+
+		errorLog1("BS_GetKeyPkcs1: SC_encodeAsnObj returned %s\n",
+			cssmErrorString(crtn).c_str());
+		switch(crtn) {
+			case CSSMERR_CSSM_MEMORY_ERROR:
+				crtn = CSSMERR_CSP_MEMORY_ERROR;
+				break;
+			default:
+				break;
+		}
+		CssmError::throwMe(crtn);
+	}
+}
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/bsafePKCS1.h b/AppleCSP/BSafeCSP/bsafePKCS1.h
new file mode 100644
index 00000000..cecdb612
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsafePKCS1.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+/*
+ * bsafePKCS1.h - support for PKCS1 format RSA public key blobs, which for some
+ * 					reason, BSAFE doesn't know about.
+ */
+
+#ifndef	_BSAFE_PKCS1_H_
+#define _BSAFE_PKCS1_H_
+
+#include <aglobal.h>
+#include <bsafe.h>
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+#include <Security/asn-type.h>
+#include <Security/cssmdata.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* DER-decode any AsnType object */
+CSSM_RETURN CL_decodeAsnObj(
+	const CssmData		&derEncoded,
+	AsnType				&asnObj);
+
+/* DER-encode any AsnType object. */
+CSSM_RETURN CL_encodeAsnObj(
+	AsnType				&asnObj,
+	CssmOwnedData		&derEncoded,
+	size_t				maxEncodedSize);
+
+/*
+ * Given a PKCS1-formatted key blob, decode the blob into components and do 
+ * a B_SetKeyInfo on the specified BSAFE key.
+ */
+void BS_setKeyPkcs1(
+	const CssmData 		&pkcs1Blob, 
+	B_KEY_OBJ 			bsKey);
+
+/*
+ * Obtain public key blob info, PKCS1 format. 
+ */
+void BS_GetKeyPkcs1(
+	const B_KEY_OBJ 	bsKey, 
+	CssmOwnedData 		&pkcs1Blob);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _BSAFE_PKCS1_H_ */
+
+#endif	/* BSAFE_CSP_ENABLE */
+
diff --git a/AppleCSP/BSafeCSP/bsafeSymmetric.cpp b/AppleCSP/BSafeCSP/bsafeSymmetric.cpp
new file mode 100644
index 00000000..e251ac34
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsafeSymmetric.cpp
@@ -0,0 +1,289 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// bsafeSymmetric.cpp - symmetric encryption contexts and algorithms
+//
+#include "bsafecspi.h"
+#include <Security/debugging.h>
+
+#define bbprintf(args...)	debug("BSafeBuf", ## args)
+
+#define VERBOSE_DEBUG	0
+#if		VERBOSE_DEBUG
+static void dumpBuf(
+	char				*title,
+	const CSSM_DATA		*d,
+	uint32 				maxLen)
+{
+	unsigned i;
+	uint32 len;
+	
+	if(title) {
+		printf("%s:  ", title);
+	}
+	if(d == NULL) {
+		printf("NO DATA\n");
+		return;
+	}
+	printf("Total Length: %d\n   ", d->Length);
+	len = maxLen;
+	if(d->Length < len) {
+		len = d->Length;
+	}
+	for(i=0; i<len; i++) {
+		printf("%02X ", d->Data[i]);
+		if((i % 16) == 15) {
+			printf("\n   ");
+		}
+	}
+	printf("\n");
+}
+#else
+#define dumpBuf(t, d, m)
+#endif	/* VERBOSE_DEBUG */
+
+void BSafe::SymmetricKeyGenContext::generate(
+	const Context 	&context, 
+	CssmKey 		&symKey, 
+	CssmKey 		&dummyKey)
+{
+	AppleSymmKeyGenContext::generateSymKey(
+		context, 
+		session(),
+		symKey);		
+}
+
+// FIXME:
+// We really should match the key algorithm to the en/decrypt
+// algorithm. Also: verify key usage bits. 
+void BSafe::BlockCipherContext::init(
+	const Context &context, 
+	bool encrypting)
+{
+	bool hasIV = false;
+	bool requirePad = false;
+	
+    if (reusing(encrypting))
+        return;	// all set to go
+		
+	cssmAlg = context.algorithm();
+    switch(cssmAlg) {
+		// most are handled below; break here to special cases
+		case CSSM_ALGID_RC4:
+			RC4init(context);
+			return;
+		case CSSM_ALGID_DES:
+		case CSSM_ALGID_DESX:
+		case CSSM_ALGID_3DES_3KEY_EDE:
+		case CSSM_ALGID_RC5:
+		case CSSM_ALGID_RC2:
+			break;
+		
+		/* others here... */
+        default:
+			// Should never have gotten this far
+			assert(0);
+            CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);		
+	}
+	
+	
+	// these variables are used in the switch below and need to 
+	// live until after setAlgorithm()
+	BSafeItem 		iv;
+    B_BLK_CIPHER_W_FEEDBACK_PARAMS spec;
+	A_RC5_PARAMS	rc5Params;
+	A_RC2_PARAMS	rc2Params;
+
+    // crypto algorithm
+    spec.encryptionParams = NULL_PTR;	// default, may change
+    switch (cssmAlg) {
+        case CSSM_ALGID_DES:
+            spec.encryptionMethodName = POINTER("des");
+            break;
+        case CSSM_ALGID_DESX:
+            spec.encryptionMethodName = POINTER("desx");
+            break;
+        case CSSM_ALGID_3DES_3KEY_EDE:
+            spec.encryptionMethodName = POINTER("des_ede");
+            break;
+        case CSSM_ALGID_RC5:
+            spec.encryptionMethodName = POINTER("rc5");
+			spec.encryptionParams = POINTER(&rc5Params);
+			rc5Params.version = 0x10;
+			// FIXME - get this from context attr
+			rc5Params.rounds = 1;
+			rc5Params.wordSizeInBits = 32;
+            break;
+        case CSSM_ALGID_RC2:
+		{
+            spec.encryptionMethodName = POINTER("rc2");
+			spec.encryptionParams = POINTER(&rc2Params);
+			// effective key size in bits - either from Context,
+			// or the key
+			uint32 bits = context.getInt(CSSM_ATTRIBUTE_EFFECTIVE_BITS);
+			if(bits == 0) {
+				// OK, try the key
+				CssmKey &key = context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, 
+					CSSMERR_CSP_MISSING_ATTR_KEY);
+				bits = key.KeyHeader.LogicalKeySizeInBits;
+			}
+			rc2Params.effectiveKeyBits = bits;
+            break;
+		}
+    }
+
+    // feedback mode
+	cssmMode = context.getInt(CSSM_ATTRIBUTE_MODE);
+    switch (cssmMode) {
+		/* no mode attr --> 0 == CSSM_ALGMODE_NONE, not currently supported */
+ 		case CSSM_ALGMODE_CBCPadIV8:
+			requirePad = true;
+			// and fall thru
+		case CSSM_ALGMODE_CBC_IV8: 
+		{
+            iv = context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR, 
+				CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
+            spec.feedbackMethodName = POINTER("cbc");
+            spec.feedbackParams = POINTER(&iv);
+			hasIV = true;
+            break;
+        }
+        case CSSM_ALGMODE_OFB_IV8: {
+            iv = context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR, 
+				CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
+            spec.feedbackMethodName = POINTER("ofb");
+            spec.feedbackParams = POINTER(&iv);
+			hasIV = true;
+            break;
+        }
+        case CSSM_ALGMODE_ECB: {
+            spec.feedbackMethodName = POINTER("ecb");
+            spec.feedbackParams = POINTER(&blockSize);
+            break;
+        }
+        default:
+			errorLog1("BSafe symmetric init: illegal mode (%d)\n", (int)cssmMode);
+            CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
+    }
+
+    // padding
+    spec.paddingParams = NULL_PTR;
+	/* no padding attr --> 0 == PADDING_NONE */
+	padEnable = false;
+    uint32 cssmPadding = context.getInt(CSSM_ATTRIBUTE_PADDING);
+	if(requirePad) {
+		switch(cssmPadding) {
+			case CSSM_PADDING_PKCS1:	// for backwards compatibility
+			case CSSM_PADDING_PKCS5:
+			case CSSM_PADDING_PKCS7:
+				spec.paddingMethodName = POINTER("pad");
+				padEnable = true;
+				break;
+			default:
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
+		}
+	}
+	else {
+		if(cssmPadding != CSSM_PADDING_NONE) {
+            CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
+		}
+		else {
+            spec.paddingMethodName = POINTER("nopad");
+		}
+	}
+
+    // put it all together
+    setAlgorithm(AI_FeedbackCipher, &spec);	// set BSafe algorithm
+    setKeyFromContext(context);				// set BSafe key
+    cipherInit();							// common cryption init
+}
+
+void BSafe::BlockCipherContext::RC4init(
+	const Context &context)
+{
+    setAlgorithm(AI_RC4, NULL);		// set BSafe algorithm
+    setKeyFromContext(context);		// set BSafe key
+	padEnable = false;
+    cipherInit();					// common cryption init
+}
+
+void BSafe::BlockCipherContext::trackUpdate(size_t inSize, size_t outSize)
+{
+	size_t newPending = pending + inSize;
+	pending = newPending % blockSize;
+	
+	/*
+	 * Most of the time, the max size buffered by BSAFE is 
+	 * blockSize - 1 bytes. When decrypting and padding is enabled,
+	 * BSAFE buffers up to a full block.
+	 */
+	if(!mDirection && 					//Êdecrypting
+	   padEnable &&						// padding
+	   (pending == 0) &&				// mod result was 0
+	   (newPending > 0)) {				// but nonzero total
+		/* BSAFE is holding a whole block in its buffer */
+		pending = blockSize;
+	}
+	bbprintf("===trackUpdte: %s; inSize=%d newPending=%d pending=%d", 
+		(mDirection ? "encrypt" : "decrypt"),
+		inSize, newPending, pending);
+}
+
+size_t BSafe::BlockCipherContext::inputSize(size_t outSize)
+{
+    // if we have an 'outSize' output buffer, how many input bytes may we feed in?
+    size_t wholeBlocks = outSize / blockSize;
+    return wholeBlocks * blockSize - pending + (blockSize - 1);
+}
+
+size_t BSafe::BlockCipherContext::outputSize(bool final, size_t inSize)
+{
+    // how much output buffer will we need for 'size' input bytes?
+	
+	size_t totalToGo = inSize + pending;
+	// total to go, rounded up to next block
+	size_t numBlocks = (totalToGo + blockSize - 1) / blockSize;
+	size_t outSize;
+	
+	/*
+	 * encrypting: may get one additional block on final() if padding
+	 * decrypting: outsize always <= insize 
+	 */
+	if(mDirection && 						// encrypting
+		final &&							// last time
+		padEnable &&  						// padding enabled
+		((totalToGo % blockSize) == 0)) {	// even ptext len
+			numBlocks++;					// extra pad block
+	}
+	outSize = numBlocks * blockSize;
+	bbprintf("===outputSize: %s; final=%d inSize=%d pending=%d outSize=%d", 
+		(mDirection ? "encrypt" : "decrypt"),
+		final, inSize, pending, outSize);
+	return outSize;
+}
+
+void BSafe::BlockCipherContext::minimumProgress(size_t &inSize, size_t &outSize)
+{
+    // eat up buffer, proceed one full block
+    inSize = blockSize - pending;
+    outSize = blockSize;
+}
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/bsafecsp.h b/AppleCSP/BSafeCSP/bsafecsp.h
new file mode 100644
index 00000000..b542b791
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsafecsp.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// bsafecsp - top C++ implementation layer for BSafe 4
+//
+#ifndef _H_BSAFECSP
+#define _H_BSAFECSP
+
+#include <Security/CSPsession.h>
+#include "AppleCSP.h"
+
+/* Can't include AppleCSPSession.h due to circular dependency */
+class AppleCSPSession;
+
+// no longer a subclass of AlgorithmFactory due to 
+// differing setup() methods
+class BSafeFactory : public AppleCSPAlgorithmFactory {
+public:
+	
+    BSafeFactory(
+		CssmAllocator *normAlloc = NULL, 
+		CssmAllocator *privAlloc = NULL)
+		{ 
+			setNormAllocator(normAlloc); 
+			setPrivAllocator(privAlloc); 
+		}
+	~BSafeFactory() { }
+	
+    bool setup(
+		AppleCSPSession &session,
+		CSPFullPluginSession::CSPContext * &cspCtx, 
+		const Context &context);
+
+    static void setNormAllocator(CssmAllocator *alloc);
+    static void setPrivAllocator(CssmAllocator *alloc);
+	
+};
+
+#endif //_H_BSAFECSP
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/bsafecspi.h b/AppleCSP/BSafeCSP/bsafecspi.h
new file mode 100644
index 00000000..18b42ce3
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsafecspi.h
@@ -0,0 +1,453 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// bsafecspi - implementation layer for C++ BSafe 4 interface
+//
+#ifndef _H_BSAFECSPI
+#define _H_BSAFECSPI
+
+#include <Security/CSPsession.h>
+#include "bsobjects.h"
+#include "AppleCSPContext.h"
+#include "AppleCSPSession.h"
+#include <aglobal.h>
+#include <bsafe.h>
+
+//
+// The BSafe class is more of a namespace than anything else.
+// Just think of it as the "static binder" for BSafe's objects.
+// Note that we keep a global, static allocator. We have to; BSafe
+// doesn't have any state management at that level.
+//
+class BSafe {
+    class BSafeContext; friend class BSafeContext;
+	class BSafeFactory; friend class BSafeFactory;
+
+public:
+    static void setNormAllocator(CssmAllocator *alloc)
+    { assert(!normAllocator); normAllocator = alloc; }
+    static void setPrivAllocator(CssmAllocator *alloc)
+    { assert(!privAllocator); privAllocator = alloc; }
+	
+	static bool setup(
+		AppleCSPSession &session,
+		CSPFullPluginSession::CSPContext * &cspCtx, 
+		const Context &context);
+
+private:
+    // BSafe's memory allocators
+    static CssmAllocator *normAllocator;
+    static CssmAllocator *privAllocator;
+    friend POINTER T_malloc(unsigned int);
+    friend void T_free(POINTER);
+    friend POINTER T_realloc(POINTER, unsigned int);
+    
+    static const B_ALGORITHM_METHOD * const bsChooser[];
+
+private:
+	// BSafe-specific BinaryKey class.
+	class BSafeBinaryKey : public BinaryKey {
+	
+	public:
+		BSafeBinaryKey(
+			bool 			isPub,
+			uint32			alg);	// CSSM_ALGID_{RSA,DSA}
+		~BSafeBinaryKey();
+		void generateKeyBlob(
+			CssmAllocator 		&allocator,
+			CssmData			&blob,
+			CSSM_KEYBLOB_FORMAT	&format);
+			
+		bool			isPublic() 	{ return mIsPublic; }
+		uint32			alg()		{ return mAlg; }
+		B_KEY_OBJ		bsKey()		{ return mBsKey; }
+		
+	private:
+		bool			mIsPublic;
+		uint32			mAlg;		// CSSM_ALGID_{RSA,DSA}
+		B_KEY_OBJ		mBsKey;
+	};
+	
+private:
+	//
+	// The BSafeContext class is the parent of all BSafe-used CSPContext objects.
+	// It implements the CSPContext operation functions (init, update, ...) in terms
+	// of pointer-to-member fields set by its subclasses. This may not be pretty, but
+	// it avoids every subclass having to re-implement all CSPContext operations.
+	// Beyond that, we implement a raftload of utility methods for our children.
+	//
+    class BSafeContext : public AppleCSPContext {
+        friend class BSafe;
+    public:
+        BSafeContext(AppleCSPSession &session);
+        virtual ~BSafeContext();
+        
+		// called by CSPFullPluginSession
+        void init(const Context &context, bool encoding = true);
+        void update(const CssmData &data);
+        void update(void *inp, size_t &inSize, void *outp, size_t &outSize);
+        void final(CssmData &out);
+        void final(const CssmData &in);
+        size_t outputSize(bool final, size_t inSize);
+
+    protected:
+		// install a BSafe algorithm into bsAlgorithm
+        void setAlgorithm(B_INFO_TYPE bAlgType, const void *info = NULL);
+		
+		// safely create bsKey 
+		void createBsKey();
+		
+		// set bsKey. The different versions are equivalent
+        void setKeyAtom(B_INFO_TYPE bKeyInfo, const void *info);
+        void setKeyFromItem(B_INFO_TYPE bKeyInfo, const BSafeItem &item)
+			{ setKeyAtom(bKeyInfo, &item); }
+        void setKeyFromCssmKey(B_INFO_TYPE bKeyInfo, const CssmKey &key)
+			{ BSafeItem item(key.KeyData); setKeyAtom(bKeyInfo, &item); }
+        void setKeyFromCssmData(B_INFO_TYPE bKeyInfo, const CssmData &keyData)
+			{ BSafeItem item(keyData); setKeyAtom(bKeyInfo, &item); }
+        void setKeyFromContext(const Context &context, bool required = true);
+	
+		void setRefKey(CssmKey &key);
+		void setRsaOutSize(bool isPubKey);
+		
+		// create mRandom to be a suitable random-generator BSafe object (if it isn't yet)
+        void setRandom();
+
+		// trackUpdate is called during crypto-output. Hook it to keep track of data flow
+        virtual void trackUpdate(size_t in, size_t out);
+
+		// destroy bsAlgorithm and bsKey so we can start over making them
+        void reset();
+
+		// clear key state
+		void destroyBsKey();
+		
+		// determine if we can reuse the current bsAlgorithm
+        bool reusing(bool encode = true)
+        {
+            if (initialized && !opStarted && 
+				(encode == encoding)) return true;
+            encoding = encode;
+            return false;
+        }
+
+    public:
+		//
+		// These pointers-to-member are called by the BSafeContext operations
+		// (update, final). They must be set by a subclasses's init() method.
+		// Not all members are used by all types of operations - check the 
+		// source when in doubt.
+		//
+        int (*inUpdate)(B_ALGORITHM_OBJ, POINTER, unsigned int, A_SURRENDER_CTX *);
+        int (*inOutUpdate)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
+                            POINTER, unsigned int, B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
+        int (*inFinal)(B_ALGORITHM_OBJ, POINTER, unsigned int, A_SURRENDER_CTX *);
+        int (*inFinalR)(B_ALGORITHM_OBJ, POINTER, unsigned int,
+                        B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
+        int (*outFinalR)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
+                        B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
+        int (*outFinal)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
+                        A_SURRENDER_CTX *);
+        
+    protected:
+
+        // un-consted bsChooser for BSafe's consumption. BSafe's Bad
+        static B_ALGORITHM_METHOD **chooser()
+        { return const_cast<B_ALGORITHM_METHOD **>(bsChooser); }
+
+		// a placeholder for a surrender context. Not currently used
+		// @@@ should perhaps test for pthread cancel? --> thread abstraction
+        static A_SURRENDER_CTX * const bsSurrender;
+
+    protected:
+        B_ALGORITHM_OBJ bsAlgorithm; // BSafe algorithm object or NULL
+        B_ALGORITHM_OBJ bsRandom;	// PRNG algorithm
+        bool encoding;				// encoding direction
+        bool initialized;			// method init() has completed
+		bool opStarted;				// method update() has been called
+									// generally means that we can't reuse
+									// the current bsAlgorithm
+		//
+		// We have a binKey only if the caller passed in a reference 
+		// key. In that case we avoid deleting bsKey - which is a copy
+		// of binKey.bsKey - because a BinaryKey is persistent
+		// relative to this context. 
+		//
+		BSafeBinaryKey	*bsBinKey;
+        B_KEY_OBJ 		bsKey;		// BSafe key object or NULL
+        
+        size_t 			mOutSize; 	// simple output size, if applicable
+    };	/* BSafeContext */
+
+	// contexts for BSafe digest operations
+    class DigestContext : public BSafeContext {
+    public:
+		// do all work in constructor. We have no directions; thus default init() works fine
+        DigestContext(
+			AppleCSPSession &session,
+			const Context &, 
+			B_INFO_TYPE bAlgInfo, 
+			size_t sz);
+    };
+
+	// common context features for BSafe cipher operations (both symmetric and asymmetric)
+    class CipherContext : public BSafeContext {
+	public:
+		CipherContext(
+			AppleCSPSession &session) :
+				BSafeContext(session), 
+				pending(0) {}
+			
+	protected:
+        size_t pending;				// bytes not eaten still pending (staged only)
+    public:
+        void cipherInit();			// common init code (must be called from init())
+    };            
+
+	// contexts for block cipher operations using symmetric algorithms
+    class BlockCipherContext : public CipherContext {
+        size_t blockSize;
+		uint32 cssmAlg;
+		uint32 cssmMode;
+		bool padEnable;
+    public:
+        BlockCipherContext(
+			AppleCSPSession &session,
+			const Context &, 
+			size_t sz) :
+				CipherContext(session),
+			 	blockSize(sz) { }
+        void init(const Context &context, bool encrypting);
+        size_t inputSize(size_t outSize);
+        size_t outputSize(bool final, size_t inSize);
+        void minimumProgress(size_t &in, size_t &out);
+        void trackUpdate(size_t in, size_t out);
+	private:
+		// special case for RC4
+		void RC4init(const Context &context);
+    };
+
+	// context for generating public/private key pairs
+    class BSafeKeyPairGenContext : public BSafeContext,
+					 private AppleKeyPairGenContext  {
+	public:
+		BSafeKeyPairGenContext(
+			AppleCSPSession &session,
+			const Context &) :
+				BSafeContext(session) {}
+
+		// generate alg params, not handled by PublicKeyGenerateContext
+		// For DSA only. 
+        void generate(
+			const Context 			&context, 
+			uint32 					bitSize, 
+			CssmData 				&params,
+			uint32 					&attrCount, 
+			Context::Attr * 		&attrs);
+			
+		// this one is specified in CSPFullPluginSession
+		void generate(
+			const Context 	&context, 
+			CssmKey 		&pubKey, 
+			CssmKey 		&privKey);
+			
+		// this one in AppleKeyPairGenContext
+		void generate(
+			const Context 	&context,
+			BinaryKey		&pubBinKey,	
+			BinaryKey		&privBinKey,
+			uint32			&keySize);
+	
+	private:
+		void setupAlgorithm(
+			const Context 	&context,
+			uint32			&keySize);
+			
+    };	/* BSafeKeyPairGenContext */
+
+	// public key cipher operations
+    class PublicKeyCipherContext : public CipherContext {
+    public:
+		PublicKeyCipherContext(
+			AppleCSPSession &session,
+			const Context &) :
+				CipherContext(session) { }
+        void init(const Context &context, bool encrypting);
+        size_t inputSize(size_t outSize);	// unlimited
+    };
+
+	// contexts for BSafe signing/verifying operations
+    class SigningContext : public BSafeContext {
+        B_INFO_TYPE algorithm;
+    public:
+        SigningContext(
+			AppleCSPSession &session,
+			const Context &,
+			B_INFO_TYPE bAlg, 
+			size_t sz) : 
+				BSafeContext(session),
+				algorithm(bAlg) { mOutSize = sz; }
+        void init(const Context &context, bool signing);
+    };
+
+	// contexts for BSafe MAC generation and verification
+    class MacContext : public BSafeContext {
+        B_INFO_TYPE algorithm;
+    public:
+        MacContext(
+			AppleCSPSession &session,
+			const Context &,
+            B_INFO_TYPE bAlg, 
+			size_t sz) : 
+				BSafeContext(session),
+				algorithm(bAlg) { mOutSize = sz; }
+        void init(const Context &context, bool signing);
+        void final(const CssmData &in);
+    };
+	
+	// contexts for BSafe's random number generation
+	class RandomContext : public BSafeContext {
+		B_INFO_TYPE algorithm;
+	public:
+		RandomContext(
+			AppleCSPSession &session,
+			const Context &, 
+			B_INFO_TYPE alg) :
+				BSafeContext(session),
+				algorithm(alg) { }
+		void init(const Context &context, bool);
+		void final(CssmData &data);
+	};
+
+	// symmetric key generation context
+	class SymmetricKeyGenContext : public BSafeContext,
+		private AppleSymmKeyGenContext {
+    public:
+		SymmetricKeyGenContext(
+			AppleCSPSession &session,
+			const Context 	&ctx,
+			uint32			minSizeInBits,
+			uint32			maxSizeInBits,
+			bool			mustBeByteSized) :
+				BSafeContext(session),
+				AppleSymmKeyGenContext(
+					minSizeInBits,
+					maxSizeInBits,
+					mustBeByteSized) { }
+					
+		void generate(
+			const Context 	&context, 
+			CssmKey 		&symKey, 
+			CssmKey 		&dummyKey);
+
+    };
+
+public:
+	/*
+	 * Stateless, private function to map a CSSM alg and pub/priv state
+	 * to B_INFO_TYPE and format. Returns true on success, false on
+	 * "I don't understand this algorithm". 
+	 */
+	static bool bsafeAlgToInfoType(
+		CSSM_ALGORITHMS		alg,
+		bool				isPublic,
+		B_INFO_TYPE			&infoType,	// RETURNED
+		CSSM_KEYBLOB_FORMAT	&format);	// RETURNED
+
+	/* check result of a BSafe call and throw on error */
+	static void check(int status, bool isKeyOp = false);
+		
+	/* moved here from BSafeContext - now works on any key */
+	template <class KI_Type>
+	static KI_Type *getKey(B_KEY_OBJ bKey, B_INFO_TYPE type)
+	{ 
+		POINTER p; 
+		check(B_GetKeyInfo(&p, bKey, type), true); 
+		return reinterpret_cast<KI_Type *>(p); 
+	}
+
+
+    //
+    // The context generation table - see algmaker.cpp.
+    //
+public:
+	// Base class for Maker classes
+	class MakerBase {
+	public:
+		virtual ~MakerBase() { }
+		virtual BSafeContext *make(
+			AppleCSPSession &session,
+			const Context &context) const = 0;
+	};
+
+	// One entry in Maker table
+	struct MakerTable {
+		CSSM_ALGORITHMS 	algorithmId;
+		CSSM_CONTEXT_TYPE	algClass;
+		const MakerBase 	*maker;
+		~MakerTable() { delete maker; }
+	};
+	
+private:
+	static bug_const MakerTable algorithms[];
+	static const unsigned int algorithmCount;
+	
+	/*
+	 * CSPKeyInfoProvider for BSafe keys
+	 */
+	class BSafeKeyInfoProvider : public CSPKeyInfoProvider 
+	{
+	public:
+		BSafeKeyInfoProvider(
+			const CssmKey		&cssmKey);
+		~BSafeKeyInfoProvider() { }
+		void CssmKeyToBinary(
+			BinaryKey			**binKey);	// RETURNED
+		void QueryKeySizeInBits(
+			CSSM_KEY_SIZE		&keySize);	// RETURNED
+	};
+
+}; /* BSAFE namespace */
+
+/*
+ * BSAFE Key Info types.
+ */
+#define BLOB_IS_PUB_KEY_INFO	0
+
+#if		BLOB_IS_PUB_KEY_INFO
+
+/* X beta values */
+#define RSA_PUB_KEYINFO_TYPE		KI_RSAPublicBER
+#define RSA_PRIV_KEYINFO_TYPE		KI_PKCS_RSAPrivateBER
+#define DSA_PUB_KEYINFO_TYPE		KI_DSAPublicBER
+#define DSA_PRIV_KEYINFO_TYPE		KI_DSAPrivateBER
+
+#else	/* BLOB_IS_PUB_KEY_INFO */
+
+#define RSA_PUB_KEYINFO_TYPE		KI_RSAPublic
+#define RSA_PRIV_KEYINFO_TYPE		KI_PKCS_RSAPrivateBER
+#define DSA_PUB_KEYINFO_TYPE		KI_DSAPublicBER
+#define DSA_PRIV_KEYINFO_TYPE		KI_DSAPrivateBER
+
+#endif
+
+#endif //_H_BSAFECSP
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/bsobjects.h b/AppleCSP/BSafeCSP/bsobjects.h
new file mode 100644
index 00000000..166a64c4
--- /dev/null
+++ b/AppleCSP/BSafeCSP/bsobjects.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// bsobjects - C++ adaptations of popular BSafe 4 object types
+//
+#ifndef _H_BSOBJECTS
+#define _H_BSOBJECTS
+
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <aglobal.h>
+#include <bsafe.h>
+
+//
+// A PodWrapper for BSafe's ITEM objects
+//
+class BSafeItem : public PodWrapper<BSafeItem, ITEM> {
+public:
+    BSafeItem() { ((ITEM *)this)->data = NULL; len = 0; }
+    BSafeItem(void *addr, size_t sz)
+    { ((ITEM *)this)->data = (unsigned char *)addr; len = sz; }
+    BSafeItem(const CSSM_DATA &cData)
+    { ((ITEM *)this)->data = cData.Data; len = cData.Length; }
+    BSafeItem(const ITEM &cData)
+    { *(ITEM *)this = cData; }
+
+    void operator = (const CssmData &cData)
+    { ((ITEM *)this)->data = (unsigned char *)cData.data(); len = cData.length(); }
+
+    void *data() const { return ((ITEM *)this)->data; }
+    size_t length() const { return len; }
+
+    template <class T>
+    T copy(CssmAllocator &alloc)
+    { return T(memcpy(alloc.malloc(length()), data(), length()), length()); }
+
+    template <class T>
+    T *copyp(CssmAllocator &alloc)
+    { return new(alloc) T(copy<T>(alloc)); }
+
+    void *operator new (size_t size, CssmAllocator &alloc)
+    { return alloc.malloc(size); }
+};
+
+#endif //_H_BSOBJECTS
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/memory.cpp b/AppleCSP/BSafeCSP/memory.cpp
new file mode 100644
index 00000000..7d4f3202
--- /dev/null
+++ b/AppleCSP/BSafeCSP/memory.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+
+//
+// memory - memory functions for BSafe
+//
+#include <bsafe.h>
+#include <aglobal.h>
+#include "bsafecspi.h"
+
+
+// declared in bsafecspi.h....
+CssmAllocator *BSafe::normAllocator;
+CssmAllocator *BSafe::privAllocator;	
+
+// We use the private allocator for all BSAFE-alalocated memory.
+// Memory allocated my BSAFE should never be visible by apps. 
+
+POINTER CALL_CONV T_malloc (unsigned int size)
+{
+    return reinterpret_cast<POINTER>(BSafe::privAllocator->malloc(size));
+}
+
+POINTER CALL_CONV T_realloc (POINTER p, unsigned int size)
+{
+    POINTER result;
+    if ((result = (POINTER)BSafe::privAllocator->realloc(p, size)) == NULL_PTR)
+    free (p);
+    return (result);
+}
+
+void CALL_CONV T_free (POINTER p)
+{
+    BSafe::privAllocator->free(p);
+}
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/miscalgorithms.cpp b/AppleCSP/BSafeCSP/miscalgorithms.cpp
new file mode 100644
index 00000000..4934cf22
--- /dev/null
+++ b/AppleCSP/BSafeCSP/miscalgorithms.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+#ifdef	BSAFE_CSP_ENABLE
+
+//
+// miscalgorithms - miscellaneous BSafe context creators and managers
+//
+#include "bsafecspi.h"
+
+#include <stdio.h>	// debug
+
+
+//
+// Digest algorithms.
+// NOTE: There is no init() method, since BSafe digest algorithms re-initialize
+// automatically and there is no directional difference.
+//
+BSafe::DigestContext::DigestContext(
+	AppleCSPSession &session,
+	const Context &, 
+	B_INFO_TYPE bAlgInfo, 
+	size_t sz)
+	: BSafeContext(session)
+{
+    mOutSize = sz;
+    inUpdate = B_DigestUpdate;
+    outFinal = B_DigestFinal;
+    setAlgorithm(bAlgInfo);
+    check(B_DigestInit(bsAlgorithm, bsKey, chooser(), bsSurrender));
+    initialized = true;
+}
+
+
+//
+// Signing/Verifying algorithms
+//
+// FIXME:
+// We really should match the key algorithm to the sign/vfy
+// algorithm. Also: verify key usage bits. 
+void BSafe::SigningContext::init(
+	const Context &context, 
+	bool signing)
+{
+    if (reusing(signing))
+        return;		// all set to go
+
+    setAlgorithm(algorithm, NULL);
+    setKeyFromContext(context);	// may set outSize for some keys
+
+    if (signing) {
+        check(B_SignInit(bsAlgorithm, bsKey, chooser(), bsSurrender));
+        setRandom();	// needed by some signing algorithms
+        inUpdate = B_SignUpdate;
+        outFinalR = B_SignFinal;
+        outFinal = NULL;
+    } else {
+        check(B_VerifyInit(bsAlgorithm, bsKey, chooser(), bsSurrender));
+        inUpdate = B_VerifyUpdate;
+        inFinalR = B_VerifyFinal;
+        inFinal = NULL;
+    }
+}
+
+
+//
+// MAC algorithms.
+// Note that BSafe treats MACs as digest algorithms - it has no MAC algorithm
+// class. Thus, verifying consists of "digesting" followed by comparing the result.
+//
+// FIXME : what kind of key do we expect here? For now, any old 
+// symmetric key will work...
+//
+void BSafe::MacContext::init(
+	const Context &context, 
+	bool signing)
+{
+    if (reusing(signing))
+        return;		// all set to go
+
+    B_DIGEST_SPECIFIER digestSpec;
+    digestSpec.digestInfoType = algorithm;
+    digestSpec.digestInfoParams = NULL;
+
+    setAlgorithm(AI_HMAC, &digestSpec);
+    setKeyFromContext(context);
+    check(B_DigestInit(bsAlgorithm, bsKey, chooser(), bsSurrender));
+    
+    if (signing) {
+        inUpdate = B_DigestUpdate;
+        outFinal = B_DigestFinal;
+    } else {
+        inUpdate = B_DigestUpdate;
+        // need not set xxFinal - we override final().
+    }
+}
+
+void BSafe::MacContext::final(const CssmData &in)
+{
+    // we need to perform a DigestFinal step into a temp buffer and compare to 'in'
+    void *digest = normAllocator->malloc(in.length());
+    unsigned int length;
+    check(B_DigestFinal(bsAlgorithm, POINTER(digest), &length, in.length(), bsSurrender));
+    bool verified = length == in.length() && !memcmp(digest, in.data(), in.length());
+    normAllocator->free(digest);
+	initialized = false;
+    if (!verified)
+        CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
+}
+
+
+//
+// Random-number generation algorithms.
+// Note that we don't use bsRandom, since that's our internal fixed "best to use" method,
+// not the one the user asked for.
+// NOTE: We freeze the output size at init().
+//
+void BSafe::RandomContext::init(const Context &context, bool)
+{
+	reset();	// throw away, we need to re-seed anyway
+	setAlgorithm(algorithm, NULL);	// MD5 generator mode (RSA proprietary)
+	check(B_RandomInit(bsAlgorithm, chooser(), bsSurrender));
+	
+	// set/freeze output size
+	mOutSize = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE);
+	
+	// seed the PRNG (if specified)
+	if (const CssmCryptoData *seed = context.get<CssmCryptoData>(CSSM_ATTRIBUTE_SEED)) {
+		const CssmData &seedValue = (*seed)();
+		check(B_RandomUpdate(bsAlgorithm, POINTER(seedValue.data()), seedValue.length(), bsSurrender));
+	}
+}
+
+void BSafe::RandomContext::final(CssmData &data)
+{
+	check(B_GenerateRandomBytes(bsAlgorithm, POINTER(data.data()), mOutSize, bsSurrender));
+}
+#endif	/* BSAFE_CSP_ENABLE */
diff --git a/AppleCSP/BSafeCSP/test/t-dsa.cpp b/AppleCSP/BSafeCSP/test/t-dsa.cpp
new file mode 100644
index 00000000..47d20b31
--- /dev/null
+++ b/AppleCSP/BSafeCSP/test/t-dsa.cpp
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+
+#include <bsafe.h>
+#include <aglobal.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+B_ALGORITHM_METHOD *chooser[] = {
+  &AM_DSA_KEY_GEN,
+  &AM_DSA_PARAM_GEN,
+  &AM_SHA_RANDOM,
+  NULL
+};
+
+void dumpItem(ITEM &item, const char *name);
+
+unsigned char seed[] = { 17, 205, 99, 13, 6, 199 };
+
+
+#define check(expr) \
+  if (status = (expr)) { printf("error %d at %d\n", status, __LINE__); abort(); } else /* ok */
+
+int main(int argc, char *argv[])
+{
+	int status;
+
+	int keySize = argv[1] ? atoi(argv[1]) : 512;
+	printf("Key size = %d bits\n", keySize);
+
+	B_ALGORITHM_OBJ pGen = NULL;
+	check(B_CreateAlgorithmObject(&pGen));
+	B_DSA_PARAM_GEN_PARAMS gParams;
+	gParams.primeBits = keySize;
+	check(B_SetAlgorithmInfo(pGen, AI_DSAParamGen, POINTER(&gParams)));
+
+	B_ALGORITHM_OBJ random = NULL; check(B_CreateAlgorithmObject(&random));
+	check(B_SetAlgorithmInfo(random, AI_X962Random_V0, NULL));
+	check(B_RandomInit(random, chooser, NULL));
+	check(B_RandomUpdate(random, seed, sizeof(seed), NULL));
+
+	check(B_GenerateInit(pGen, chooser, NULL));
+	B_ALGORITHM_OBJ result = NULL;
+	check(B_CreateAlgorithmObject(&result));
+	printf("Generating DSA parameters\n");
+	check(B_GenerateParameters(pGen, result, random, NULL));
+	printf("DSA generate complete, writing...\n");
+
+	A_DSA_PARAMS *dParams;
+	memset(&dParams, 0, sizeof(dParams));
+	check(B_GetAlgorithmInfo((POINTER *)&dParams, result, AI_DSAKeyGen));
+	dumpItem(dParams->prime, "prime");
+	dumpItem(dParams->subPrime, "subprime");
+	dumpItem(dParams->base, "base");
+
+#if 0
+	B_KEY_OBJ pubKey = NULL; check(B_CreateKeyObject(&pubKey));
+	B_KEY_OBJ privKey = NULL; check(B_CreateKeyObject(&privKey));
+
+	B_ALGORITHM_OBJ gen = NULL; check(B_CreateAlgorithmObject(&gen));
+	A_RSA_KEY_GEN_PARAMS args;
+	args.modulusBits = keySize;
+	args.publicExponent.data = exponent;
+	args.publicExponent.len = sizeof(exponent);
+	check(B_SetAlgorithmInfo(gen, AI_RSAStrongKeyGen, POINTER(&args)));
+	check(B_GenerateInit(gen, chooser, NULL));
+	check(B_GenerateKeypair(gen, pubKey, privKey, random, NULL));
+
+	B_ALGORITHM_OBJ enc = NULL; check(B_CreateAlgorithmObject(&enc));
+	check(B_SetAlgorithmInfo(enc, AI_PKCS_RSAPublic, NULL));
+	check(B_EncryptInit(enc, pubKey, chooser, NULL));
+	unsigned int inLen;
+	check(B_EncryptUpdate(enc, crypt, &inLen, sizeof(crypt),
+		POINTER(in), sizeof(in), random, NULL));
+	printf("EncryptUpdate output = %u\n", inLen);
+	check(B_EncryptFinal(enc, crypt, &inLen, sizeof(crypt), random, NULL));
+	printf("EncryptFinal output=%u\n", inLen);
+
+	B_ALGORITHM_OBJ dec = NULL; check(B_CreateAlgorithmObject(&dec));
+	check(B_SetAlgorithmInfo(dec, AI_PKCS_RSAPrivate, NULL));
+	check(B_DecryptInit(dec, privKey, chooser, NULL));
+	unsigned int outLen, outLen2;
+	check(B_DecryptUpdate(dec, out, &outLen, sizeof(out),
+		crypt, inLen, random, NULL));
+	printf("DecryptUpdate output = %u\n", outLen);
+	check(B_DecryptFinal(dec, out2, &outLen2, sizeof(out2), random, NULL));
+	printf("DecryptFinal output=%u %s\n", outLen2, (char*)out2);
+	B_DestroyKeyObject(&pubKey);
+	B_DestroyKeyObject(&privKey);
+#endif
+
+	exit(0);
+}
+
+void dumpItem(ITEM &item, const char *name)
+{
+  printf("%s [%d] ", name, item.len);
+  for (unsigned char *p = item.data; p < item.data + item.len; p++)
+    printf("%2.2x", *p);
+  printf("\n");
+}
+
+
+
+
+
+void T_free(POINTER p)
+{ free(p); }
+
+POINTER T_malloc(unsigned int size)
+{ return (POINTER)malloc(size); }
+
+POINTER T_realloc(POINTER p, unsigned int size)
+{ return (POINTER)realloc(p, size); }
+
+int T_memcmp(POINTER p1, POINTER p2, unsigned int size)
+{ return memcmp(p1, p2, size); }
+void T_memcpy(POINTER p1, POINTER p2, unsigned int size)
+{ memcpy(p1, p2, size); }
+void T_memmove(POINTER p1, POINTER p2, unsigned int size)
+{ memmove(p1, p2, size); }
+void T_memset(POINTER p1, int size, unsigned int val)
+{ memset(p1, size, val); }
+extern "C" int T_GetDynamicList()
+{ printf("GetDynamicList!\n"); abort(); }
diff --git a/AppleCSP/BSafeCSP/test/t-rsa.cpp b/AppleCSP/BSafeCSP/test/t-rsa.cpp
new file mode 100644
index 00000000..950c647e
--- /dev/null
+++ b/AppleCSP/BSafeCSP/test/t-rsa.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+
+#include <bsafe.h>
+#include <aglobal.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+B_ALGORITHM_METHOD *chooser[] = {
+  &AM_SHA_RANDOM,
+  &AM_RSA_KEY_GEN,
+  &AM_RSA_STRONG_KEY_GEN,
+  &AM_RSA_ENCRYPT,
+  &AM_RSA_DECRYPT,
+  &AM_RSA_CRT_ENCRYPT,
+  &AM_RSA_CRT_DECRYPT,
+  NULL
+};
+
+
+char in[] = "something wicked this way comes, "
+	"and it's a private key!";
+unsigned char crypt[1024];
+unsigned char out[1024], out2[1024];
+
+unsigned char seed[] = { 17, 22, 99, 205, 3 };
+
+unsigned char exponent[] = { 1, 0, 1 };
+
+#define check(expr) \
+  if (status = (expr)) { printf("error %d at %d\n", status, __LINE__); abort(); } else /* ok */
+
+int main(int argc, char *argv[])
+{
+	int status;
+
+	int keySize = argv[1] ? atoi(argv[1]) : 512;
+	printf("Key size = %d bits\n", keySize);
+
+	B_KEY_OBJ pubKey = NULL; check(B_CreateKeyObject(&pubKey));
+	B_KEY_OBJ privKey = NULL; check(B_CreateKeyObject(&privKey));
+
+	B_ALGORITHM_OBJ random = NULL; check(B_CreateAlgorithmObject(&random));
+	check(B_SetAlgorithmInfo(random, AI_X962Random_V0, NULL));
+	check(B_RandomInit(random, chooser, NULL));
+	check(B_RandomUpdate(random, seed, sizeof(seed), NULL));
+	for (int n = 0; n < 5; n++) {
+		unsigned char buf[4];
+		check(B_GenerateRandomBytes(random,
+			POINTER(buf), sizeof(buf), NULL));
+		printf("Randoms = ");
+		for (int n = 0; n < sizeof(buf); n++)
+			printf("%2.2x", buf[n]);
+		printf("\n");
+	}
+
+	B_ALGORITHM_OBJ gen = NULL; check(B_CreateAlgorithmObject(&gen));
+	A_RSA_KEY_GEN_PARAMS args;
+	args.modulusBits = keySize;
+	args.publicExponent.data = exponent;
+	args.publicExponent.len = sizeof(exponent);
+	check(B_SetAlgorithmInfo(gen, AI_RSAStrongKeyGen, POINTER(&args)));
+	check(B_GenerateInit(gen, chooser, NULL));
+	check(B_GenerateKeypair(gen, pubKey, privKey, random, NULL));
+
+	B_ALGORITHM_OBJ enc = NULL; check(B_CreateAlgorithmObject(&enc));
+	check(B_SetAlgorithmInfo(enc, AI_PKCS_RSAPublic, NULL));
+	check(B_EncryptInit(enc, pubKey, chooser, NULL));
+	unsigned int inLen;
+	check(B_EncryptUpdate(enc, crypt, &inLen, sizeof(crypt),
+		POINTER(in), sizeof(in), random, NULL));
+	printf("EncryptUpdate output = %u\n", inLen);
+	check(B_EncryptFinal(enc, crypt, &inLen, sizeof(crypt), random, NULL));
+	printf("EncryptFinal output=%u\n", inLen);
+
+	B_ALGORITHM_OBJ dec = NULL; check(B_CreateAlgorithmObject(&dec));
+	check(B_SetAlgorithmInfo(dec, AI_PKCS_RSAPrivate, NULL));
+	check(B_DecryptInit(dec, privKey, chooser, NULL));
+	unsigned int outLen, outLen2;
+	check(B_DecryptUpdate(dec, out, &outLen, sizeof(out),
+		crypt, inLen, random, NULL));
+	printf("DecryptUpdate output = %u\n", outLen);
+	check(B_DecryptFinal(dec, out2, &outLen2, sizeof(out2), random, NULL));
+	printf("DecryptFinal output=%u %s\n", outLen2, (char*)out2);
+	
+
+	B_DestroyKeyObject(&pubKey);
+	B_DestroyKeyObject(&privKey);
+	B_DestroyAlgorithmObject(&random);
+	exit(0);
+}
+
+void T_free(POINTER p)
+{ free(p); }
+
+POINTER T_malloc(unsigned int size)
+{ return (POINTER)malloc(size); }
+
+POINTER T_realloc(POINTER p, unsigned int size)
+{ return (POINTER)realloc(p, size); }
+
+int T_memcmp(POINTER p1, POINTER p2, unsigned int size)
+{ return memcmp(p1, p2, size); }
+void T_memcpy(POINTER p1, POINTER p2, unsigned int size)
+{ memcpy(p1, p2, size); }
+void T_memmove(POINTER p1, POINTER p2, unsigned int size)
+{ memmove(p1, p2, size); }
+void T_memset(POINTER p1, int size, unsigned int val)
+{ memset(p1, size, val); }
+extern "C" int T_GetDynamicList()
+{ printf("GetDynamicList!\n"); abort(); }
diff --git a/AppleCSP/BSafeCSP/test/t.cpp b/AppleCSP/BSafeCSP/test/t.cpp
new file mode 100644
index 00000000..3ed1c7f4
--- /dev/null
+++ b/AppleCSP/BSafeCSP/test/t.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+
+#include <bsafe.h>
+#include <aglobal.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+B_ALGORITHM_METHOD *chooser[] = {
+  &AM_SHA,
+  &AM_SHA_RANDOM,
+  NULL
+};
+
+void dumpItem(ITEM &item, const char *name);
+
+unsigned char seed[] = { 17, 205, 99, 13, 6, 199 };
+char data[] = "These are the times that try men's souls.";
+
+
+#define check(expr) \
+  if (status = (expr)) { printf("error %d at %d\n", status, __LINE__); abort(); } else /* ok */
+
+int main(int argc, char *argv[])
+{
+	int status;
+
+	ITEM key;
+	key.data = (unsigned char *)"Walla Walla Washington! Yeah, yeah, yeah!";
+	key.len = strlen((const char *)key.data);
+	B_KEY_OBJ bsKey = NULL;
+	check(B_CreateKeyObject(&bsKey));
+	check(B_SetKeyInfo(bsKey, KI_Item, POINTER(&key)));
+
+	B_ALGORITHM_OBJ macAlg = NULL;
+	check(B_CreateAlgorithmObject(&macAlg));
+	B_DIGEST_SPECIFIER macSpec;
+	macSpec.digestInfoType = AI_SHA1;
+	macSpec.digestInfoParams = NULL_PTR;
+	check(B_SetAlgorithmInfo(macAlg, AI_HMAC, POINTER(&macSpec)));
+
+	check(B_DigestInit(macAlg, bsKey, chooser, NULL));
+	check(B_DigestUpdate(macAlg,
+		POINTER(data), sizeof(data), NULL));
+	char mac[128];
+	unsigned int length;
+	check(B_DigestFinal(macAlg, POINTER(mac), &length, sizeof(mac),
+		NULL));
+	ITEM macItem; macItem.data = POINTER(mac); macItem.len = length;
+	dumpItem(macItem, "MAC");
+
+	check(B_DigestUpdate(macAlg, POINTER(data), 10, NULL));
+	check(B_DigestUpdate(macAlg,
+		POINTER(data+10), sizeof(data)-10, NULL));
+	check(B_DigestFinal(macAlg, POINTER(mac), &length, sizeof(mac),
+		NULL));
+	macItem.data = POINTER(mac); macItem.len = length;
+	dumpItem(macItem, "MAC");
+
+	printf("Done.\n");
+
+	exit(0);
+}
+
+void dumpItem(ITEM &item, const char *name)
+{
+  printf("%s [%d] ", name, item.len);
+  for (unsigned char *p = item.data; p < item.data + item.len; p++)
+    printf("%2.2x", *p);
+  printf("\n");
+}
+
+
+
+
+
+void T_free(POINTER p)
+{ free(p); }
+
+POINTER T_malloc(unsigned int size)
+{ return (POINTER)malloc(size); }
+
+POINTER T_realloc(POINTER p, unsigned int size)
+{ return (POINTER)realloc(p, size); }
+
+int T_memcmp(POINTER p1, POINTER p2, unsigned int size)
+{ return memcmp(p1, p2, size); }
+void T_memcpy(POINTER p1, POINTER p2, unsigned int size)
+{ memcpy(p1, p2, size); }
+void T_memmove(POINTER p1, POINTER p2, unsigned int size)
+{ memmove(p1, p2, size); }
+void T_memset(POINTER p1, int size, unsigned int val)
+{ memset(p1, size, val); }
+extern "C" int T_GetDynamicList()
+{ printf("GetDynamicList!\n"); abort(); }
diff --git a/AppleCSP/CVSVersionInfo.txt b/AppleCSP/CVSVersionInfo.txt
new file mode 100644
index 00000000..d3c98a4f
--- /dev/null
+++ b/AppleCSP/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:47 mb Exp $
+# $Name: Security-28 $
+ProjectName: AppleCSP
+ProjectVersion: 16
diff --git a/AppleCSP/ComCryption/ascContext.cpp b/AppleCSP/ComCryption/ascContext.cpp
new file mode 100644
index 00000000..0f4da113
--- /dev/null
+++ b/AppleCSP/ComCryption/ascContext.cpp
@@ -0,0 +1,347 @@
+/*
+ * ascContext.cpp - glue between BlockCrytpor and ComCryption (a.k.a. Apple
+ *				  Secure Compression). 
+ * Written by Doug Mitchell 4/4/2001
+ */
+ 
+#ifdef	ASC_CSP_ENABLE
+
+#include "ascContext.h"
+#include "ascFactory.h"
+#include <Security/debugging.h>
+#include <Security/logging.h>
+#include <Security/debugging.h>
+
+#define abprintf(args...)	debug("ascBuf", ## args)		/* buffer sizes */
+#define aioprintf(args...)	debug("ascIo", ## args)		/* all I/O */
+
+static CssmAllocator *ascAllocator;
+
+/*
+ * Comcryption-style memory allocator callbacks
+ */
+static void *ccMalloc(unsigned size)
+{
+	return ascAllocator->malloc(size);
+}
+static void ccFree(void *data)
+{
+	ascAllocator->free(data);
+}
+
+/* Given a ComCryption error, throw appropriate CssmError */
+static void throwComcrypt(
+	comcryptReturn 	crtn, 
+	const char		*op)		/* optional */
+{
+	CSSM_RETURN cerr = CSSM_OK;
+	const char *errStr = "Bad Error String";
+	
+	switch(crtn) {
+		case CCR_SUCCESS:
+			errStr = "CCR_SUCCESS";
+			break;
+		case CCR_OUTBUFFER_TOO_SMALL:
+			errStr = "CCR_OUTBUFFER_TOO_SMALL";
+			cerr = CSSMERR_CSP_OUTPUT_LENGTH_ERROR;
+			break;
+		case CCR_MEMORY_ERROR:
+			errStr = "CCR_MEMORY_ERROR";
+			cerr = CSSMERR_CSP_MEMORY_ERROR;
+			break;
+		case CCR_WRONG_VERSION:
+			errStr = "CCR_WRONG_VERSION";
+			cerr = CSSMERR_CSP_INVALID_DATA;
+			break;
+		case CCR_BAD_CIPHERTEXT:
+			errStr = "CCR_BAD_CIPHERTEXT";
+			cerr = CSSMERR_CSP_INVALID_DATA;
+			break;
+		case CCR_INTERNAL:
+		default:
+			errStr = "CCR_INTERNAL";
+			cerr = CSSMERR_CSP_INTERNAL_ERROR;
+			break;
+	}
+	if(op) {
+		Security::Syslog::error("Apple CSP %s: %s", op, errStr);
+	}
+	if(cerr) {
+		CssmError::throwMe(cerr);
+	}
+}
+
+/*
+ * Algorithm factory.
+ */
+ 
+AscAlgFactory::AscAlgFactory(
+	CssmAllocator *normAlloc, 
+	CssmAllocator *privAlloc)
+{
+	/* once-per-address-space init */
+	ascAllocator = privAlloc;
+	comMallocRegister(ccMalloc, ccFree);
+}
+
+bool AscAlgFactory::setup(
+	AppleCSPSession &session,
+	CSPFullPluginSession::CSPContext * &cspCtx, 
+	const Context &context)
+{
+	if(context.algorithm() != CSSM_ALGID_ASC) {
+		return false;
+	}
+	if(cspCtx != NULL) {
+		/* reusing one of ours; OK */
+		return true;
+	}
+	switch(context.type()) {
+		case CSSM_ALGCLASS_KEYGEN:
+			cspCtx = new AppleSymmKeyGenerator(session,
+				8,
+				COMCRYPT_MAX_KEYLENGTH * 8,
+				true);					// must be byte size
+			return true;
+		case CSSM_ALGCLASS_SYMMETRIC:
+			cspCtx = new ASCContext(session);
+			return true;
+		default:
+			break;
+	}
+	/* not ours */
+	return false;
+}
+
+ASCContext::~ASCContext()
+{
+	if(mCcObj != NULL) {
+		comcryptObjFree(mCcObj);
+	}
+}
+	
+/* 
+ * Standard CSPContext init, called from CSPFullPluginSession::init().
+ * Reusable, e.g., query followed by en/decrypt.
+ */
+void ASCContext::init( 
+	const Context &context, 
+	bool encrypting)
+{
+	UInt32 			keyLen;
+	UInt8 			*keyData 	= NULL;
+	comcryptReturn	crtn;
+	
+	/* obtain key from context */
+	symmetricKeyBits(context, CSSM_ALGID_ASC, 
+		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
+		keyData, keyLen);
+	if((keyLen < 1) || (keyLen > COMCRYPT_MAX_KEYLENGTH)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	mDecryptBufValid = false;
+	
+	/* All other context attributes ignored */
+	/* init the low-level state */
+	if(mCcObj == NULL) {
+		/* note we allow for context reuse */
+		mCcObj = comcryptAlloc();
+		if(mCcObj == NULL) {
+			CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+		}
+	}
+	 
+	crtn = comcryptInit(mCcObj, keyData, keyLen, CCO_DEFAULT);
+	if(crtn) {
+		throwComcrypt(crtn, "comcryptInit");
+	}
+}	
+
+/*
+ * All of these functions are called by CSPFullPluginSession.
+ */
+void ASCContext::update(
+	void 			*inp, 
+	size_t 			&inSize, 			// in/out
+	void 			*outp, 
+	size_t 			&outSize)			// in/out
+{
+	comcryptReturn crtn;
+	unsigned outLen;
+	unsigned char *inText  = (unsigned char *)inp;
+	unsigned char *outText = (unsigned char *)outp;
+	
+	if(encoding()) {
+		outLen = outSize;
+		crtn = comcryptData(mCcObj, 
+			inText, 
+			inSize,
+			outText,
+			&outLen,
+			CCE_MORE_TO_COME);		// not used on encrypt
+		if(crtn) {
+			throwComcrypt(crtn, "comcryptData");
+		}
+	}
+	else {
+		/* 
+		 * Deal with 1-byte buffer hack. First decrypt the existing buffer...
+		 */
+		if(inSize == 0) {
+			CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+		}
+		unsigned thisOutLen;
+		unsigned partialOutLen = 0;
+		if(mDecryptBufValid) {
+			thisOutLen = outSize;
+			crtn = deComcryptData(mCcObj,
+				&mDecryptBuf,
+				1,
+				outText,
+				&thisOutLen,
+				CCE_MORE_TO_COME);
+			mDecryptBufValid = false;
+			if(crtn) {
+				throwComcrypt(crtn, "deComcryptData (1)");
+			}
+			partialOutLen = thisOutLen;
+			outText      += thisOutLen;
+		}
+		
+		/*
+		 * Now decrypt remaining, less one byte (which is stored in the 
+		 * buffer).
+		 */
+		thisOutLen = outSize - partialOutLen;
+		crtn = deComcryptData(mCcObj,
+			inText, 
+			inSize - 1,
+			outText,
+			&thisOutLen,
+			CCE_MORE_TO_COME);
+		if(crtn) {
+			throwComcrypt(crtn, "deComcryptData (2)");
+		}
+		outLen = partialOutLen + thisOutLen;
+		mDecryptBuf = inText[inSize - 1];
+		mDecryptBufValid = true;
+	}
+	outSize = outLen;
+	aioprintf("=== ASC::update encrypt %d   inSize %ld  outSize %ld",
+		encoding() ? 1 : 0, inSize, outSize);
+}
+
+void ASCContext::final(
+	CssmData 		&out)	
+{
+	if(encoding()) {
+		out.length(0);
+	}
+	else {
+		/* decrypt buffer hack */
+		if(!mDecryptBufValid) {
+			CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+		}
+		comcryptReturn crtn;
+		unsigned outLen = out.Length;
+		crtn = deComcryptData(mCcObj,
+			&mDecryptBuf,
+			1,
+			(unsigned char *)out.Data,
+			&outLen,
+			CCE_END_OF_STREAM);
+		mDecryptBufValid = false;
+		if(crtn) {
+			throwComcrypt(crtn, "deComcryptData (3)");
+		}
+		out.length(outLen);
+	}
+	aioprintf("=== ASC::final  encrypt %d   outSize %ld",
+		encoding() ? 1 : 0, out.Length);
+}
+
+size_t ASCContext::inputSize(
+	size_t 			outSize)			// input for given output size
+{
+	size_t rtn = comcryptMaxInBufSize(mCcObj,
+		outSize,
+		encoding() ? CCOP_COMCRYPT : CCOP_DECOMCRYPT);
+	abprintf("--- ASCContext::inputSize  inSize %ld outSize %ld",
+		rtn, outSize);
+	return rtn;
+}
+
+/*
+ * ComCryption's buffer size calculation really does not lend itself to the 
+ * requirements here. For example, there is no guarantee that 
+ * inputSize(outputSize(x)) == x. We're just going to fudge it and make 
+ * apps (or CSPFullPluginSession) alloc plenty more than they need.
+ */
+#define ASC_OUTSIZE_FUDGE			1
+#define ASC_OUTSIZE_FUDGE_FACTOR	1.2
+
+size_t ASCContext::outputSize(
+	bool 			final, 
+	size_t 			inSize) 			// output for given input size
+{
+	unsigned effectiveInSize = inSize;
+	size_t rtn;
+	if(encoding()) {
+		rtn = comcryptMaxOutBufSize(mCcObj,
+			effectiveInSize,
+			CCOP_COMCRYPT,
+			final);
+		#if ASC_OUTSIZE_FUDGE
+		float newOutSize = rtn;
+		newOutSize *= ASC_OUTSIZE_FUDGE_FACTOR;
+		rtn = static_cast<size_t>(newOutSize);
+		#endif	/* ASC_OUTSIZE_FUDGE */
+	}
+	else {
+		if(final) {
+			if(mDecryptBufValid) {
+				effectiveInSize++;
+			}
+		}
+		else if(inSize && !mDecryptBufValid) {
+			/* not final and nothing buffered yet - lop off one */
+			effectiveInSize--;
+		}
+		rtn = comcryptMaxOutBufSize(mCcObj,
+			effectiveInSize,
+			CCOP_DECOMCRYPT,
+			final);
+	}
+	abprintf("--- ASCContext::outputSize inSize %ld outSize %ld final %d ",
+		inSize, rtn, final);
+	return rtn;
+}
+
+void ASCContext::minimumProgress(
+	size_t 			&in, 
+	size_t 			&out) 				// minimum progress chunks
+{
+	if(encoding()) {
+		in  = 1;
+		out = comcryptMaxOutBufSize(mCcObj,
+			1,
+			CCOP_COMCRYPT,
+			0);
+	}
+	else {
+		if(mDecryptBufValid) {
+			/* use "everything" */
+			in = 1;
+		}
+		else {
+			in = 0;
+		}
+		out = comcryptMaxOutBufSize(mCcObj,
+			in,
+			CCOP_DECOMCRYPT,
+			0);
+	}
+	abprintf("--- ASCContext::minProgres in %ld out %ld", in, out);
+}
+
+#endif	/* ASC_CSP_ENABLE */
diff --git a/AppleCSP/ComCryption/ascContext.h b/AppleCSP/ComCryption/ascContext.h
new file mode 100644
index 00000000..c699a6c0
--- /dev/null
+++ b/AppleCSP/ComCryption/ascContext.h
@@ -0,0 +1,61 @@
+/*
+ * ascContext.h - glue between BlockCrytpor and ComCryption (a.k.a. Apple
+ *				  Secure Compression). 
+ * Written by Doug Mitchell 4/4/2001
+ */
+
+#ifdef	ASC_CSP_ENABLE
+
+#ifndef _ASC_CONTEXT_H_
+#define _ASC_CONTEXT_H_
+
+#include "AppleCSPContext.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <ComCryption/comcryption.h>
+
+/* symmetric encrypt/decrypt context */
+class ASCContext : public AppleCSPContext {
+public:
+	ASCContext(AppleCSPSession &session) :
+		AppleCSPContext(session),
+		mCcObj(NULL)	{ }
+	~ASCContext();
+	
+	// called by CSPFullPluginSession
+	void init(
+		const Context 	&context, 
+		bool encoding = true);
+	void update(
+		void 			*inp, 
+		size_t 			&inSize, 			// in/out
+		void 			*outp, 
+		size_t 			&outSize);			// in/out
+	void final(
+		CssmData 		&out);
+
+ 	size_t inputSize(
+		size_t 			outSize);			// input for given output size
+	size_t outputSize(
+		bool 			final = false, 
+		size_t 			inSize = 0); 		// output for given input size
+	void minimumProgress(
+		size_t 			&in, 
+		size_t 			&out); 				// minimum progress chunks
+	
+private:
+	comcryptObj			mCcObj;
+	
+	/*
+	 * For first implementation, we have to cope with the fact that the final
+	 * decrypt call down to the comcryption engine requires *some* ciphertext.
+	 * On decrypt, we'll just save one byte on each update in preparation for
+	 * the final call. Hopefull we'll have time to fix deComcryptData() so this
+	 * is unneccesary.
+	 */
+	unsigned char		mDecryptBuf;
+	bool				mDecryptBufValid;
+	
+};	/* RC4Context */
+
+#endif 	/*_ASC_CONTEXT_H_ */
+#endif	/* ASC_CSP_ENABLE */
diff --git a/AppleCSP/ComCryption/ascFactory.h b/AppleCSP/ComCryption/ascFactory.h
new file mode 100644
index 00000000..bee8ea85
--- /dev/null
+++ b/AppleCSP/ComCryption/ascFactory.h
@@ -0,0 +1,34 @@
+//
+// ascAlgFactory.h - algorithm factory for ASC
+// Written by Doug Mitchell 4/4/2001
+//
+
+#ifdef	ASC_CSP_ENABLE
+
+#ifndef _ASC_ALG_FACTORY_H_
+#define _ASC_ALG_FACTORY_H_
+
+#include <Security/CSPsession.h>
+#include "AppleCSP.h"
+
+class AppleCSPSession;
+
+/* Algorithm factory */
+class AscAlgFactory : public AppleCSPAlgorithmFactory {
+public:
+	
+    AscAlgFactory(
+		CssmAllocator *normAlloc, 
+		CssmAllocator *privAlloc);
+	~AscAlgFactory() { }
+	
+    bool setup(
+		AppleCSPSession &session,
+		CSPFullPluginSession::CSPContext * &cspCtx, 
+		const Context &context);
+
+};
+
+
+#endif 	/*_ASC_ALG_FACTORY_H_ */
+#endif	/* ASC_CSP_ENABLE */
diff --git a/AppleCSP/CryptKit/.cvsignore b/AppleCSP/CryptKit/.cvsignore
new file mode 100644
index 00000000..ec052608
--- /dev/null
+++ b/AppleCSP/CryptKit/.cvsignore
@@ -0,0 +1,2 @@
+*Data
+*lib
diff --git a/AppleCSP/CryptKit/ByteRep.txt b/AppleCSP/CryptKit/ByteRep.txt
new file mode 100644
index 00000000..2ed46109
--- /dev/null
+++ b/AppleCSP/CryptKit/ByteRep.txt
@@ -0,0 +1,293 @@
+       FEE Portable Byte Representation of Public Key Strings and Signatures
+						Last Modified 15 March 2001
+
+This defines portable data formats shared by the C and Java implementation of FEE. This definition supercedes formats used prior to 20 Feb 2001.
+
+
+Primitive Data Types
+--------------------
+
+    int, unsigned int:
+     	4 bytes, M.S. byte first
+
+    short, feeUnichar, Java char:
+     	2 bytes, M.S. byte first
+
+    giant, GiantInteger:
+
+	type     contents	comment
+    ------	 --------	---------------------------------------
+	int	 	 numBytes	abs(numBytes) indicates size of n[] to
+							follow, in BYTES
+							sign of numBytes is sign bit of result
+	byte	 data 		n[0], MSB first for each element
+
+
+Curve Parameters (curveParams, Java CurveParams)
+------------------------------------------------
+
+    CURVE_PARAM_VERSION = 1:
+
+	type     contents
+	------	 --------
+	int	 	 CURVE_PARAM_VERSION = 1
+	int 	 minVersion of code to parse this struct = 1
+	unsigned q
+	int		 k
+	int		 spare
+	giant	 a
+	giant	 b
+	giant	 c
+	giant	 x1Plus
+	giant	 x1Minus
+	giant	 cOrderPlus
+	giant	 cOrderMinus
+	giant	 x1OrderPlus
+	giant	 x1OrderMinus
+
+	The last four fields are not always known; a value of (giant)0
+	indicates a "not known" condition. In this case, 4 bytes of
+	zero are written, indicating a giant with a length of zero.
+
+    CURVE_PARAM_VERSION = 2 (20 Jan 1998)
+
+	type     contents
+	------	 --------
+	int	 	 CURVE_PARAM_VERSION = 2
+	int 	 minVersion of code to parse this struct = 2
+	byte     primeType	/* new for version 2 */
+	unsigned q
+	int	 	 k
+	unsigned m		/* new for version 2 */
+	int		 spare
+	giant	 a
+	giant	 b
+	giant	 c
+	giant	 x1Plus
+	giant	 x1Minus
+	giant	 cOrderPlus
+	giant	 cOrderMinus
+	giant	 x1OrderPlus
+	giant	 x1OrderMinus
+	giant	 basePrime, if primeType == PT_GENERAL  /* new */
+
+	Note that as of version 2, the cOrder* and x1Order* fields are always
+	known.
+
+    CURVE_PARAM_VERSION = 3 (1 Sep 1998)
+
+	type     contents
+	------	 --------
+	int	 	 CURVE_PARAM_VERSION = 3
+	int 	 minVersion of code to parse this struct = 3
+	byte     primeType
+	byte     curveType	/* new for version 3 */
+	unsigned q
+	int	 	 k
+	unsigned m
+	int	 	 spare
+	giant	 a
+	giant	 b
+	giant	 c
+	giant	 x1Plus
+	giant	 x1Minus
+	giant	 cOrderPlus
+	giant	 cOrderMinus
+	giant	 x1OrderPlus
+	giant	 x1OrderMinus
+	giant	 basePrime, if primeType == PT_GENERAL
+
+
+Public Key String
+-----------------
+
+	PUBLIC_KEY_STRING_VERSION = 3:
+
+	A public key string is always encoded via enc64(); the raw data before 
+	enc64() is as follows.
+
+	type    	contents
+    ------		--------
+	int			PUBLIC_KEY_STRING_MAGIC (0xfeeddeef)
+	int 		PUBLIC_KEY_STRING_VERSION = 3
+	int     	minVersion of code to parse this key = 3
+	int			spare
+	curveParams	curve parameters
+	giant		plusX (public key, plus curve)
+	giant		minusX (public key, minus curve)
+	int			usageName length in unichars
+	feeUnichar[] usageName as array of unichars
+
+	PUBLIC_KEY_BLOB_VERSION = 4 (23 Mar 1998)
+
+	New for version 4 - exported blobs for both public and private keys. 
+	Public key strings are merely enc64() encoded versions of public 
+	key blobs and are identical to PUBLIC_KEY_STRING_VERSION 3 public 
+	key strings.
+
+    PUBLIC_KEY_BLOB_MAGIC : 0xfeeddeef - public
+                            0xfeeddeed - private
+    minVersion : 3 for public, 4 for private
+
+	type    	contents
+    ------		--------
+	int			PUBLIC_KEY_BLOB_MAGIC
+	int 		PUBLIC_KEY_BLOB_VERSION = 4
+	int     	minVersion of code to parse this key = 3 or 4
+	int			spare
+	curveParams	curve parameters
+
+	public key blob:
+	  giant		plusX (public key, plus curve)
+	  giant		minusX (public key, minus curve)
+	private key blob:
+	  int		privDataLen
+	  unsigned char privData[]
+
+	both private and public:
+
+	int				usageName length in unichars
+	feeUnichar[]	usageName as array of unichars
+
+	PUBLIC_KEY_BLOB_VERSION = 5 (2 Sep 1998)
+
+	Added plusY.
+	minVersion = 5.
+
+	type    	contents
+    ------		--------
+	int			PUBLIC_KEY_BLOB_MAGIC_{PRIV,PUB}
+	int 		PUBLIC_KEY_BLOB_VERSION = 5
+	int     	minVersion of code to parse this key = 5
+	int			spare
+	curveParams	curve parameters
+
+	public key blob:
+	  giant		plusX (public key, plus curve)
+	  giant		plusY (y-coord of public key, plus curve, may be zero)
+	  giant		minusX (public key, minus curve)
+	private key blob:
+	  giant		privGiant
+
+	both private and public:
+
+	int				usageName length in unichars
+	feeUnichar[]	usageName as array of unichars
+
+	PUBLIC_KEY_BLOB_VERSION = 6 (14 Mar 2001)
+
+    Deleted usageName.
+
+	type    	contents
+    ------		--------
+	int			PUBLIC_KEY_BLOB_MAGIC_{PRIV,PUB}
+	int 		PUBLIC_KEY_BLOB_VERSION = 5
+	int     	minVersion of code to parse this key = 5
+	int			spare
+	curveParams	curve parameters
+
+	public key blob:
+	  giant		plusX (public key, plus curve)
+	  giant		plusY (y-coord of public key, plus curve, may be zero)
+	  giant		minusX (public key, minus curve)
+	private key blob:
+	  giant		privGiant
+
+
+Digital Signature, ElGamal style
+--------------------------------
+
+	type    		contents
+	------			--------
+	int          	FEE_SIG_MAGIC (0xfee00516)
+	int          	FEE_SIG_VERSION = 3
+	int          	minVersion of code to parse this signature = 3
+	int          	spare
+	int				signer length in unichars (DELETED 2/20/01)
+	feeUnichar[]	signer as array of unichars (DELETED 2/20/01)
+	giant			u
+	giant			Pm.x
+
+	FEE_SIG_VERSION = 4 (15 March 2001)
+	Deleted signer.
+	
+	type    		contents
+	------			--------
+	int          	FEE_SIG_MAGIC (0xfee00516)
+	int          	FEE_SIG_VERSION = 4
+	int          	minVersion of code to parse this signature = 4
+	int          	spare
+	giant			u
+	giant			Pm.x
+
+Digital Signature, ECDSA style
+--------------------------------
+
+	type    	contents
+    ------		--------
+	int         FEE_ECDSA_MAGIC (0xfee00517)
+	int         FEE_ECDSA_VERSION = 1
+	int         minVersion of code to parse this signature = 1
+	int         spare
+	int			signer length in unichars (DELETED 2/20/01)
+	feeUnichar[] signer as array of unichars (DELETED 2/20/01)
+	giant		s
+	giant		x0
+
+	FEE_ECDSA_VERSION = 2 (15 March 2001)
+	Deleted signer.
+
+	type    	contents
+    ------		--------
+	int         FEE_ECDSA_MAGIC (0xfee00517)
+	int         FEE_ECDSA_VERSION = 2
+	int         minVersion of code to parse this signature = 2
+	int         spare
+	giant		s
+	giant		x0
+
+
+
+FEED (2:1) CipherText
+---------------------
+
+This data type uses an optimized form of Giants in that the sign, and hence 
+the number of 16-bit shorts (i.e., the size of n[]), is implied by the size 
+of p used in encryption and decryption. For a given curve parameter q (as 
+in p = 2**q - k), the number of shorts per giant transmitted is ((q/8 + 1)/2). 
+As in normal giants, the n[] array is transmitted m.s. byte first. During 
+encoding, unused elements in n[] - i.e., those appearing after 
+n[abs(sign) - 1] - are zero. Upon decoding, the sign of an incoming n[] 
+array can be inferred from the number of non-zero shorts.
+
+One block of ciphertext is formatted as follows. See "Fast Elliptic 
+Encryption (FEE) Algorithms", by Richard E. Crandall, July 1996, for 
+descriptions of Xm, Xc, and g.
+
+	type		  	  contents
+	---------------	  -----------------
+	optimized giant   Xm
+	optimized giant   Xc
+	byte		  	  g
+
+
+FEED (1:1) CipherText
+---------------------
+
+The first cipherblock is a FEED(2:1) encrypted copy of the initial 
+R and S arrays; this is basically a bunch of random bytes which are 
+used to cook up the giants R and S at both encrypt and decrypt time. 
+In 1:1 FEED ciphertext, this is encrypted with the recipient's public 
+key; the result is padded out to one 1:1 FEED Cipherblock.
+
+Subsequent cipherblocks are:
+
+	type		  	  contents
+	---------------	  -----------------
+	optimized giant   Xm
+	byte		  	  clueByte
+
+	clueByte contents:
+	    bit 0 : 0 ==> minus
+	            1 ==> plus
+	    bit 1 : 's' arg to elliptic_add()
diff --git a/AppleCSP/CryptKitCSP/CryptKitDER.cpp b/AppleCSP/CryptKitCSP/CryptKitDER.cpp
new file mode 100644
index 00000000..bd5182ea
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/CryptKitDER.cpp
@@ -0,0 +1,765 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CryptKitDER.h - snacc-based routines to create and parse DER-encoded FEE 
+ *				   keys and signatures
+ *
+ * Created 3/12/2001 by dmitch.
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+#include <CryptKit/CryptKitDER.h>
+#include <CryptKit/falloc.h>
+#include <CryptKit/feeDebug.h>
+#include <CryptKit/feeFunctions.h>
+#include <Security/cdsaUtils.h>
+#include <Security/appleoids.h>
+
+#define PRINT_SIG_GIANTS		0
+#define PRINT_CURVE_PARAMS		0
+#define PRINT_SIZES				0
+#if		PRINT_SIZES
+#define szprint(s)				printf s
+#else
+#define szprint(s)
+#endif
+
+/*
+ * Trivial exception class associated with a feeReturn.
+ */
+class feeException
+{
+protected:
+	feeException(feeReturn frtn, const char *op); 	
+public:
+	~feeException() 				{ }
+	feeReturn frtn() 				{ return mFrtn; }
+    static void throwMe(feeReturn frtn, const char *op = NULL) __attribute__((noreturn));
+private:
+	feeReturn mFrtn;
+};
+
+feeException::feeException(
+	feeReturn frtn, 
+	const char *op)
+		: mFrtn(frtn)
+{ 
+	if(op) {
+		dbgLog(("%s: %s\n", op, feeReturnString(frtn)));
+	}
+}
+
+void feeException::throwMe(feeReturn frtn, const char *op = NULL) { throw feeException(frtn, op); }
+
+/*
+ * ASN1 encoding rules specify that an integer's sign is indicated by the MSB
+ * of the first (MS) content byte. For a non-negative number, if the MSB of 
+ * the MS byte (of the unencoded number) is one, then the encoding starts with
+ * a byte of zeroes to indicate positive sign. For a negative number, the first
+ * nine bits can not be all 1 - if they are (in the undecoded number), leading 
+ * bytes of 0xff are trimmed off until the first nine bits are something other
+ * than one. Also, the first nine bits of the encoded number can not all be 
+ * zero. 
+ *
+ * CryptKit giants express their sign as part of the giantstruct.sign field. 
+ * The giantDigit array (giantstruct.n[]) is stored l.s. digit first. 
+ *
+ * These routines are independent of platform, endianness, and giatn digit size. 
+ */
+
+/* routines to guess maximum size of DER-encoded objects */ 
+static unsigned feeSizeOfSnaccGiant(
+	giant g)
+{
+	unsigned rtn = abs(g->sign) * GIANT_BYTES_PER_DIGIT;
+	szprint(("feeSizeOfSnaccGiant: sign %d size %d\n", g->sign, rtn + 4));
+	return rtn + 4;
+}
+
+static unsigned feeSizeofSnaccInt()
+{
+	return 7;
+}
+
+/* PUBLIC... */
+unsigned feeSizeOfDERSig(
+	giant g1,
+	giant g2)
+{
+	unsigned rtn = feeSizeOfSnaccGiant(g1);
+	rtn += feeSizeOfSnaccGiant(g2);
+	szprint(("feeSizeOfDERSig: size %d\n", rtn + 4));
+	return rtn + 4;
+}
+
+static unsigned feeSizeofSnaccCurveParams(const curveParams *cp)
+{
+	unsigned rtn = 5 * feeSizeofSnaccInt();	// primeType, curveType, q, k, m
+	rtn += 10 * feeSizeOfSnaccGiant(cp->basePrime);
+	szprint(("feeSizeofSnaccCurveParams: size %d\n", rtn));
+	return rtn;
+}
+
+static unsigned feeSizeOfSnaccPubKey(const curveParams *cp)
+{
+	unsigned rtn = 11;						// version plus sequence overhead
+	rtn += feeSizeofSnaccCurveParams(cp);
+	rtn += (3 * feeSizeOfSnaccGiant(cp->basePrime));
+	szprint(("feeSizeOfSnaccPubKey: size %d\n", rtn));
+	return rtn;
+}
+
+static unsigned feeSizeOfSnaccPrivKey(const curveParams *cp)
+{
+	unsigned rtn = 11;						// version plus sequence overhead
+	rtn += feeSizeofSnaccCurveParams(cp);
+	rtn += feeSizeOfSnaccGiant(cp->basePrime);
+	szprint(("feeSizeOfSnaccPrivKey: size %d\n", rtn));
+	return rtn;
+}
+
+/* perform 2's complement of byte array, expressed MS byte first */
+static void twosComplement(
+	unsigned char *bytePtr,		// points to MS byte
+	unsigned numBytes)
+{
+	unsigned char *outp = bytePtr + numBytes - 1;
+	unsigned char carry = 1;	// first time thru, carry = 1 to add one to 1's comp
+	for(unsigned byteDex=0; byteDex<numBytes; byteDex++) {
+		/* first complement, then add carry */
+		*outp = ~*outp + carry;
+		if(carry && (*outp == 0)) {
+			/* overflow/carry */
+			carry = 1;
+		}
+		else {
+			carry = 0;
+		}
+		outp--;
+	}
+}
+
+/*
+ * Convert a BigIntegerStr to a (mallocd) giant. 
+ * Only known exception is a feeException.
+ */
+static giant bigIntStrToGiant(
+	BigIntegerStr 	&bigInt)
+{
+	char *rawOcts = bigInt;
+	unsigned numBytes = bigInt.Len();
+	unsigned numGiantDigits;
+	int sign = 1;
+	giant grtn;
+	feeReturn frtn = FR_Success;
+	unsigned char *inp = NULL;
+	unsigned digitDex;			// index into g->giantDigit[]
+	
+	/* handle degenerate case (value of zero) */
+	if((numBytes == 0) || ((numBytes == 1) && rawOcts[0] == 0)) {
+		grtn = newGiant(1);
+		if(grtn == NULL) {
+			feeException::throwMe(FR_Memory, "newGiant(1)");
+		}
+		int_to_giant(0, grtn);
+		return grtn;
+	}
+	
+	/* make a copy of raw octets if we have to do two's complement */
+	unsigned char *byteArray = NULL;
+	bool didMalloc = false;
+	if(rawOcts[0] & 0x80) {
+		sign = -1;
+		numBytes++;
+		byteArray = (unsigned char *)fmalloc(numBytes);
+		didMalloc = true;
+		byteArray[0] = 0xff;
+		memmove(byteArray + 1, rawOcts, numBytes-1);
+		twosComplement(byteArray, numBytes);
+	}
+	else {
+		/* no copy */
+		char *foo = rawOcts;
+		byteArray = (unsigned char *)foo;
+	}
+	
+	/* cook up a new giant */
+	numGiantDigits = (numBytes + GIANT_BYTES_PER_DIGIT - 1) /
+			GIANT_BYTES_PER_DIGIT;
+	grtn = newGiant(numGiantDigits);
+	if(grtn == NULL) {
+		frtn = FR_Memory;
+		goto abort;
+	}
+
+	/* 
+	 * Convert byteArray to array of giantDigits
+	 * inp - raw input bytes, LSB last
+	 * grtn->n[] - output array of giantDigits, LSD first
+	 * Start at LS byte and LD digit
+	 */
+	digitDex = 0;					// index into g->giantDigit[]
+	giantDigit thisDigit;
+	inp = byteArray + numBytes - 1;	
+	unsigned dex;					// total byte counter
+	unsigned byteDex;				// index into one giantDigit
+	unsigned shiftCount;
+	for(dex=0; dex<numBytes; ) {	// increment dex inside
+		thisDigit = 0;
+		shiftCount = 0;
+		for(byteDex=0; byteDex<GIANT_BYTES_PER_DIGIT; byteDex++) {
+			thisDigit |= ((giantDigit)(*inp--) << shiftCount);
+			shiftCount += 8;
+			if(++dex == numBytes) {
+				/* must be partial giantDigit */
+				break;
+			}
+		}
+		CKASSERT(digitDex < numGiantDigits);
+		grtn->n[digitDex++] = thisDigit;
+	}
+	grtn->sign = (int)numGiantDigits * sign;
+	
+	/* trim leading (MS) zeroes */
+	gtrimSign(grtn);
+abort:
+	if(didMalloc) {
+		ffree(byteArray);
+	}
+	if(frtn) {
+		feeException::throwMe(frtn, "bigIntStrToGiant");
+	}
+	return grtn;
+}
+
+/*
+ * Convert a giant to an existing BigIntegerString.
+ * Only known exception is a feeException.
+ */
+static void giantToBigIntStr(
+	giant 			g,
+	BigIntegerStr 	&bigInt)
+{
+	unsigned char doPrepend = 0;	
+	unsigned numGiantDigits = abs(g->sign);
+	unsigned numBytes = numGiantDigits * GIANT_BYTES_PER_DIGIT;
+	giantDigit msGiantBit = 0;
+	if(isZero(g)) {
+		/* special degenerate case */
+		bigInt.ReSet("", 1);
+		return;
+	}
+	else {
+		msGiantBit = g->n[numGiantDigits - 1] >> (GIANT_BITS_PER_DIGIT - 1);
+	}
+	
+	/* prepend a byte of zero if necessary */
+	if((g->sign < 0) ||					// negative - to handle 2's complement 
+	   ((g->sign > 0) && msGiantBit)) {	// ensure MS byte is zero
+			doPrepend = 1;
+			numBytes++;
+	}
+	
+	unsigned char *rawBytes = (unsigned char *)fmalloc(numBytes);
+	if(rawBytes == NULL) {
+		feeException::throwMe(FR_Memory, "giantToBigIntStr fmalloc(rawBytes)");
+	}
+	unsigned char *outp = rawBytes;
+	if(doPrepend) {
+		*outp++ = 0;
+	}
+	
+	/* 
+	 * Convert array of giantDigits to bytes. 
+	 * outp point to MS output byte.
+	 */
+	int digitDex;			// index into g->giantDigit[]
+	unsigned byteDex;		// byte index into a giantDigit
+	for(digitDex=numGiantDigits-1; digitDex>=0; digitDex--) {
+		/* one loop per giantDigit, starting at MS end */
+		giantDigit thisDigit = g->n[digitDex];
+		unsigned char *bp = outp + GIANT_BYTES_PER_DIGIT - 1;
+		for(byteDex=0; byteDex<GIANT_BYTES_PER_DIGIT; byteDex++) {
+			/* one loop per byte within the digit, starting at LS end */
+			*bp-- = (unsigned char)(thisDigit) & 0xff;
+			thisDigit >>= 8;
+		}
+		outp += GIANT_BYTES_PER_DIGIT;
+	}
+	
+	/* do two's complement for negative giants */
+	if(g->sign < 0) {
+		twosComplement(rawBytes, numBytes);
+	}
+	
+	/* strip off redundant leading bits (nine zeroes or nine ones) */
+	outp = rawBytes;
+	unsigned char *endp = outp + numBytes - 1;
+	while((*outp == 0) &&			// m.s. byte zero
+	      (outp < endp) &&			// more bytes exist
+		  (!(outp[1] & 0x80))) {	// 9th bit is 0
+		outp++;
+		numBytes--;
+	}
+	while((*outp == 0xff) &&		// m.s. byte all ones
+	      (outp < endp) &&			// more bytes exist
+		  (outp[1] & 0x80)) {		// 9th bit is 1
+		outp++;
+		numBytes--;
+	}
+
+	/* rawBytes are the ASN-compliant contents */
+	bigInt.ReSet(reinterpret_cast<const char *>(outp), numBytes);
+	ffree(rawBytes);
+}
+
+/* curveParams : CryptKit <--> snacc */
+/* Only known exception is a feeException */
+static FEECurveParameters *feeCurveParamsToSnacc(
+	const curveParams *cp)
+{
+	#if 	PRINT_CURVE_PARAMS
+	printf("===encoding curveParams; cp:\n"); printCurveParams(cp);
+	#endif
+	FEECurveParameters *snaccCp = NULL;
+	try {
+		snaccCp = new FEECurveParameters();
+		AsnIntType val;
+		switch(cp->primeType) {
+			case FPT_Mersenne:
+				val = FEEPrimeType::pt_mersenne;
+				break;
+			case FPT_FEE:
+				val = FEEPrimeType::pt_fee;
+				break;
+			case FPT_General:
+				val = FEEPrimeType::pt_general;
+				break;
+			default:
+				feeException::throwMe(FR_Internal, "bad cp->primeType");
+		}
+		snaccCp->primeType.Set(val);
+		switch(cp->curveType) {
+			case FCT_Montgomery:
+				val = FEECurveType::ct_montgomery;
+				break;
+			case FCT_Weierstrass:
+				val = FEECurveType::ct_weierstrass;
+				break;
+			case FCT_General:
+				val = FEECurveType::ct_general;
+				break;
+			default:
+				feeException::throwMe(FR_Internal, "bad cp->curveType");
+		}
+		snaccCp->curveType.Set(val);
+		snaccCp->q.Set(cp->q);
+		snaccCp->k.Set(cp->k);
+		snaccCp->m.Set(cp->m);
+		giantToBigIntStr(cp->a, snaccCp->a);
+		giantToBigIntStr(cp->b, snaccCp->bb);
+		giantToBigIntStr(cp->c, snaccCp->c);
+		giantToBigIntStr(cp->x1Plus, snaccCp->x1Plus);
+		giantToBigIntStr(cp->x1Minus, snaccCp->x1Minus);
+		giantToBigIntStr(cp->cOrderPlus, snaccCp->cOrderPlus);
+		giantToBigIntStr(cp->cOrderMinus, snaccCp->cOrderMinus);
+		giantToBigIntStr(cp->x1OrderPlus, snaccCp->x1OrderPlus);
+		giantToBigIntStr(cp->x1OrderMinus, snaccCp->x1OrderMinus);
+		if(cp->primeType == FPT_General) {
+			snaccCp->basePrime = new BigIntegerStr();
+			giantToBigIntStr(cp->basePrime, *snaccCp->basePrime);
+		}
+	}
+	catch(feeException ferr) {
+		delete snaccCp;
+		throw;
+	}
+	catch(...) {
+		delete snaccCp;
+		feeException::throwMe(FR_Memory, "feeCurveParamsToSnacc catchall");	// ???
+	}
+	return snaccCp;
+}
+
+static curveParams *feeCurveParamsFromSnacc(
+	FEECurveParameters	&snaccCp)
+{
+	curveParams *cp = newCurveParams();
+	if(cp == NULL) {
+		feeException::throwMe(FR_Memory, "feeCurveParamsFromSnacc alloc cp");
+	}
+	AsnIntType val = snaccCp.primeType;
+	switch(val) {
+		case FEEPrimeType::pt_mersenne:
+			cp->primeType = FPT_Mersenne;
+			break;
+		case FEEPrimeType::pt_fee:
+			cp->primeType = FPT_FEE;
+			break;
+		case FEEPrimeType::pt_general:
+			cp->primeType = FPT_General;
+			break;
+		default:
+			feeException::throwMe(FR_BadPubKey, "feeCurveParamsFromSnacc bad primeType");
+	}
+	val = snaccCp.curveType;
+	switch(val) {
+		case FEECurveType::ct_montgomery:
+			cp->curveType = FCT_Montgomery;
+			break;
+		case FEECurveType::ct_weierstrass:
+			cp->curveType = FCT_Weierstrass;
+			break;
+		case FEECurveType::ct_general:
+			cp->curveType = FCT_General;
+			break;
+		default:
+			feeException::throwMe(FR_BadPubKey, "feeCurveParamsFromSnacc bad curveType");
+	}
+	cp->q 			   = snaccCp.q;
+	cp->k 			   = snaccCp.k;
+	cp->m 			   = snaccCp.m;
+	cp->a 			   = bigIntStrToGiant(snaccCp.a);
+	cp->b 			   = bigIntStrToGiant(snaccCp.bb);
+	cp->c              = bigIntStrToGiant(snaccCp.c);
+	cp->x1Plus         = bigIntStrToGiant(snaccCp.x1Plus);
+	cp->x1Minus        = bigIntStrToGiant(snaccCp.x1Minus);
+	cp->cOrderPlus     = bigIntStrToGiant(snaccCp.cOrderPlus);
+	cp->cOrderMinus    = bigIntStrToGiant(snaccCp.cOrderMinus);
+	cp->x1OrderPlus    = bigIntStrToGiant(snaccCp.x1OrderPlus);
+	cp->x1OrderMinus   = bigIntStrToGiant(snaccCp.x1OrderMinus);
+	if(snaccCp.basePrime != NULL) {
+		cp->basePrime  = bigIntStrToGiant(*snaccCp.basePrime);
+	}
+	
+	/* remaining fields inferred */
+	curveParamsInferFields(cp);
+	allocRecipGiants(cp);
+	#if 	PRINT_CURVE_PARAMS
+	printf("===decoding curveParams; cp:\n"); printCurveParams(cp);
+	#endif
+	return cp;
+}
+
+/***
+ *** Public routines. These are usable from C code; they never throw.
+ ***/
+ 
+/*
+ * Encode/decode the two FEE signature types. We malloc returned data via
+ * fmalloc(); caller must free via ffree().
+ */
+feeReturn feeDEREncodeElGamalSignature(
+	giant			u,
+	giant			PmX,
+	unsigned char	**encodedSig,		// fmallocd and RETURNED
+	unsigned		*encodedSigLen)		// RETURNED
+{
+	FEEElGamalSignature snaccSig;
+	CssmAutoData oData(CssmAllocator::standard(CssmAllocator::sensitive));
+	
+	try {
+		giantToBigIntStr(u, snaccSig.u);
+		giantToBigIntStr(PmX, snaccSig.pmX);
+	} 
+	catch(feeException ferr) {
+		return ferr.frtn();
+	}
+	try {
+		SC_encodeAsnObj(snaccSig, oData, feeSizeOfDERSig(u, PmX));
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return FR_BadSignatureFormat;
+	}
+	*encodedSig = (unsigned char *)fmalloc(oData.length());
+	*encodedSigLen = oData.length();
+	memmove(*encodedSig, oData.get().Data, oData.length()); 
+	#if	PRINT_SIG_GIANTS
+	printf("feeEncodeElGamalSignature:\n");
+	printf("   u   : "); printGiantHex(u);
+	printf("   PmX : "); printGiantHex(PmX);
+	printf("   u   : "); snaccSig.u.Print(cout); printf("\n");
+	printf("   PmX : "); snaccSig.pmX.Print(cout); printf("\n");
+	#endif
+	return FR_Success;
+}
+
+feeReturn feeDEREncodeECDSASignature(
+	giant			c,
+	giant			d,
+	unsigned char	**encodedSig,		// fmallocd and RETURNED
+	unsigned		*encodedSigLen)		// RETURNED
+{
+	FEEECDSASignature snaccSig;
+	CssmAutoData oData(CssmAllocator::standard(CssmAllocator::sensitive));
+	
+	try {
+		giantToBigIntStr(c, snaccSig.c);
+		giantToBigIntStr(d, snaccSig.d);
+	}
+	catch(feeException ferr) {
+		return ferr.frtn();
+	}
+	try {
+		SC_encodeAsnObj(snaccSig, oData, feeSizeOfDERSig(c, d));
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return FR_BadSignatureFormat;
+	}
+	*encodedSig = (unsigned char *)fmalloc(oData.length());
+	*encodedSigLen = oData.length();
+	memmove(*encodedSig, oData.get().Data, oData.length()); 
+	#if	PRINT_SIG_GIANTS
+	printf("feeEncodeECDSASignature:\n");
+	printf("   c   : "); printGiantHex(*c);
+	printf("   d   : "); printGiantHex(*d);
+	printf("   c   : "); snaccSig.c.Print(cout); printf("\n");
+	printf("   d   : "); snaccSig.d.Print(cout); printf("\n");
+	#endif
+	return FR_Success;
+}
+
+feeReturn feeDERDecodeElGamalSignature(
+	const unsigned char	*encodedSig,
+	unsigned			encodedSigLen,
+	giant				*u,				// newGiant'd and RETURNED
+	giant				*PmX)			// newGiant'd and RETURNED
+{
+	FEEElGamalSignature snaccSig;
+	CssmData cData((void *)encodedSig, encodedSigLen);
+	try {
+		SC_decodeAsnObj(cData, snaccSig);
+	}
+	catch(...) {
+		return FR_BadSignatureFormat;
+	}
+	try {
+		*u   = bigIntStrToGiant(snaccSig.u);
+		*PmX = bigIntStrToGiant(snaccSig.pmX);
+	}
+	catch(feeException ferr) {
+		return ferr.frtn();
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return FR_Memory;
+	}
+	#if	PRINT_SIG_GIANTS
+	printf("feeDecodeElGamalSignature:\n");
+	printf("   u   : "); printGiantHex(*u);
+	printf("   PmX : "); printGiantHex(*PmX);
+	printf("   u   : "); snaccSig.u.Print(cout); printf("\n");
+	printf("   PmX : "); snaccSig.pmX.Print(cout); printf("\n");
+	#endif
+	return FR_Success;
+}
+
+feeReturn feeDERDecodeECDSASignature(
+	const unsigned char	*encodedSig,
+	unsigned			encodedSigLen,
+	giant				*c,				// newGiant'd and RETURNED
+	giant				*d)				// newGiant'd and RETURNED
+{
+	FEEECDSASignature snaccSig;
+	CssmData cData((void *)encodedSig, encodedSigLen);
+	try {
+		SC_decodeAsnObj(cData, snaccSig);
+	}
+	catch(...) {
+		return FR_BadSignatureFormat;
+	}
+	try {
+		*c = bigIntStrToGiant(snaccSig.c);
+		*d = bigIntStrToGiant(snaccSig.d);
+	}
+	catch(feeException ferr) {
+		return ferr.frtn();
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return FR_Memory;
+	}
+	#if	PRINT_SIG_GIANTS
+	printf("feeDecodeECDSASignature:\n");
+	printf("   c   : "); printGiantHex(*c);
+	printf("   d   : "); printGiantHex(*d);
+	printf("   c   : "); snaccSig.c.Print(cout); printf("\n");
+	printf("   d   : "); snaccSig.d.Print(cout); printf("\n");
+	#endif
+	return FR_Success;
+}
+
+/*
+ * Encode/decode the FEE private and public keys. We malloc returned data via
+ * falloc(); caller must free via ffree(). Public C functions which never throw. 
+ */
+feeReturn feeDEREncodePublicKey(
+	int					version,
+	const curveParams	*cp,
+	giant				plusX,
+	giant				minusX,
+	giant				plusY,				// may be NULL
+	unsigned char		**keyBlob,			// fmallocd and RETURNED
+	unsigned			*keyBlobLen)		// RETURNED
+{
+	FEEPublicKey snaccKey;
+	
+	/* set up the SNACC object */
+	snaccKey.version.Set(version);
+	try {
+		snaccKey.curveParams = feeCurveParamsToSnacc(cp);
+		giantToBigIntStr(plusX, snaccKey.plusX);
+		giantToBigIntStr(minusX, snaccKey.minusX);
+		if(plusY != NULL) {
+			snaccKey.plusY = new BigIntegerStr();
+			giantToBigIntStr(plusY, *snaccKey.plusY);
+		}
+	}
+	catch(feeException ferr) {
+		return ferr.frtn();
+	}
+	
+	/* encode the SNACC object */
+	CssmAutoData oData(CssmAllocator::standard(CssmAllocator::sensitive));
+	
+	try {
+		SC_encodeAsnObj(snaccKey, oData, feeSizeOfSnaccPubKey(cp));
+	}
+	catch(...) {
+		/* FIXME - ???? */
+		return FR_Memory;
+	}
+	*keyBlob = (unsigned char *)fmalloc(oData.length());
+	*keyBlobLen = oData.length();
+	memmove(*keyBlob, oData.get().Data, oData.length()); 
+	return FR_Success;
+}
+
+feeReturn feeDEREncodePrivateKey(
+	int					version,
+	const curveParams	*cp,
+	const giant			privData,
+	unsigned char		**keyBlob,			// fmallocd and RETURNED
+	unsigned			*keyBlobLen)		// RETURNED
+{
+	FEEPrivateKey snaccKey;
+	
+	/* set up the SNACC object */
+	snaccKey.version.Set(version);
+	try {
+		snaccKey.curveParams = feeCurveParamsToSnacc(cp);
+		giantToBigIntStr(privData, snaccKey.privData);
+	}
+	catch(feeException ferr) {
+		return ferr.frtn();
+	}
+	
+	/* encode the SNACC object */
+	CssmAutoData oData(CssmAllocator::standard(CssmAllocator::sensitive));
+	
+	try {
+		SC_encodeAsnObj(snaccKey, oData, feeSizeOfSnaccPrivKey(cp));
+	}
+	catch(...) {
+		/* FIXME - ???? */
+		return FR_Memory;
+	}
+	*keyBlob = (unsigned char *)fmalloc(oData.length());
+	*keyBlobLen = oData.length();
+	memmove(*keyBlob, oData.get().Data, oData.length()); 
+	return FR_Success;
+}
+
+feeReturn feeDERDecodePublicKey(
+	const unsigned char	*keyBlob,
+	unsigned			keyBlobLen,
+	int					*version,			// this and remainder RETURNED
+	curveParams			**cp,
+	giant				*plusX,
+	giant				*minusX,
+	giant				*plusY)				// may be NULL
+{
+	FEEPublicKey snaccKey;
+	CssmData cData((unsigned char *)keyBlob, (size_t)keyBlobLen);
+	try {
+		SC_decodeAsnObj(cData, snaccKey);
+	}
+	catch(...) {
+		return FR_BadPubKey;
+	}
+	try {
+		*version = snaccKey.version;
+		*cp     = feeCurveParamsFromSnacc(*snaccKey.curveParams);
+		*plusX  = bigIntStrToGiant(snaccKey.plusX);
+		*minusX = bigIntStrToGiant(snaccKey.minusX);
+		if(snaccKey.plusY != NULL) {
+			/* optional */
+			*plusY = bigIntStrToGiant(*snaccKey.plusY);
+		}
+		else {
+			*plusY = newGiant(1);
+			int_to_giant(0, *plusY);
+		}
+	}
+	catch(feeException ferr) {
+		return ferr.frtn();
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return FR_Memory;
+	}
+	return FR_Success;
+}
+	
+feeReturn feeDERDecodePrivateKey(
+	const unsigned char	*keyBlob,
+	unsigned			keyBlobLen,
+	int					*version,			// this and remainder RETURNED
+	curveParams			**cp,
+	giant				*privData)			// RETURNED
+{
+	FEEPrivateKey snaccKey;
+	CssmData cData((unsigned char *)keyBlob, (size_t)keyBlobLen);
+	try {
+		SC_decodeAsnObj(cData, snaccKey);
+	}
+	catch(...) {
+		return FR_BadPubKey;
+	}
+	try {
+		*version  = snaccKey.version;
+		*cp       = feeCurveParamsFromSnacc(*snaccKey.curveParams);
+		*privData = bigIntStrToGiant(snaccKey.privData);
+	}
+	catch(feeException ferr) {
+		return ferr.frtn();
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return FR_Memory;
+	}
+	return FR_Success;
+}
+
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/CryptKitSpace.h b/AppleCSP/CryptKitCSP/CryptKitSpace.h
new file mode 100755
index 00000000..ac546d7c
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/CryptKitSpace.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  CryptKitSpace.h - bare-bones declaration of CryptKit namespace.
+ *
+ *  Created by dmitch on Wed Feb 21 2001.
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#ifndef	_CRYPT_KIT_SPACE_H_
+#define _CRYPT_KIT_SPACE_H_
+
+/* first make sure it exists */
+namespace CryptKit { }
+
+/* then make4 it easy to use */
+using namespace CryptKit;
+
+#endif	/* _CRYPT_KIT_SPACE_H_ */
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/FEEAsymmetricContext.cpp b/AppleCSP/CryptKitCSP/FEEAsymmetricContext.cpp
new file mode 100644
index 00000000..2876e8d4
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/FEEAsymmetricContext.cpp
@@ -0,0 +1,439 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * FEEAsymmetricContext.cpp - CSPContexts for FEE asymmetric encryption
+ *
+ * Created March 8 2001 by dmitch.
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#include "FEEAsymmetricContext.h"
+#include "FEECSPUtils.h"
+#include <Security/utilities.h>
+
+/* validate context for FEED and FEEDExp - no unexpected attributes allowed */
+static void validateFeedContext(
+	const Context &context)
+{
+	/* Note we cannot distinguish between zero and "not there" */
+	uint32 blockSize = context.getInt(CSSM_ATTRIBUTE_BLOCK_SIZE);
+	if(blockSize != 0) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_BLOCK_SIZE);
+	}
+	CSSM_ENCRYPT_MODE cssmMode = context.getInt(CSSM_ATTRIBUTE_MODE);
+	if(cssmMode != 0) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
+	}
+	#if 0
+	/* we allow this for CMS wrapping */
+	CssmData *iv = context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR);
+	if(iv != NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR);
+	}
+	#endif
+	CSSM_PADDING padding = context.getInt(CSSM_ATTRIBUTE_PADDING); 
+	if(padding != 0) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
+	}
+}
+
+/***
+ *** FEED - 1:1 FEED - encrypt n bytes of plaintext, get (roughly) n bytes
+ *** of ciphertext. Ciphertext is smaller than with FEED, but this is slower.
+ ***/
+CryptKit::FEEDContext::~FEEDContext()
+{
+	if(mFeeFeed) {
+		feeFEEDFree(mFeeFeed);
+		mFeeFeed = NULL;
+	}
+	if(mPrivKey && mAllocdPrivKey) {
+		feePubKeyFree(mPrivKey);
+	}
+	if(mPubKey && mAllocdPubKey) {
+		feePubKeyFree(mPubKey);
+	}
+	mPrivKey = NULL;
+	mPubKey  = NULL;
+	mInitFlag = false;
+}
+
+// called by CSPFullPluginSession; reusable
+void CryptKit::FEEDContext::init(
+	const Context &context, 
+	bool encoding)
+{
+	if(mInitFlag && !opStarted()) {
+		/* reusing - e.g. query followed by encrypt */
+		return;
+	}
+	
+	/* 
+	 * Fetch FEE keys from context. This is an unusual algorithm - it requires
+	 * two keys, one public and one private. The public key MUST be stored in
+	 * the context with attribute type CSSM_ATTRIBUTE_PUBLIC_KEY, and the private 
+	 * key with CSSM_ATTRIBUTE_KEY.
+	 *
+	 * For now, we require CSSM_KEYUSE_ANY for FEE keys used for this algorithm.
+	 * Otherwise we'd have to allow both KEYUSE_ENCRYPT and KEYUSE_DECRYPT for
+	 * both keys, and that would require some algorithm-specific hack in 
+	 * cspValidateKeyUsageBits() which I really don't want to do.
+	 */
+	if(mPrivKey == NULL) {
+		assert(!opStarted());
+		mPrivKey = contextToFeeKey(context,
+			session(),
+			CSSM_ATTRIBUTE_KEY,
+			CSSM_KEYCLASS_PRIVATE_KEY,
+			CSSM_KEYUSE_ANY,
+			mAllocdPrivKey);
+	}
+	else {
+		assert(opStarted());	
+	}
+	if(mPubKey == NULL) {
+		assert(!opStarted());
+		mPubKey = contextToFeeKey(context,
+			session(),
+			CSSM_ATTRIBUTE_PUBLIC_KEY,
+			CSSM_KEYCLASS_PUBLIC_KEY,
+			CSSM_KEYUSE_ANY,
+			mAllocdPubKey);
+	}
+	else {
+		assert(opStarted());	
+	}
+	
+	/* validate context - no other attributes allowed */
+	validateFeedContext(context);
+
+	if(mFeeFeed != NULL) {
+		/* not reusable */
+		assert(opStarted());
+		feeFEEDFree(mFeeFeed);
+		mFeeFeed = NULL;
+	}
+	
+	/* OK, looks good. Cook up a feeFEED object. */
+	mFeeFeed = feeFEEDNewWithPubKey(mPrivKey,
+		mPubKey,
+		encoding ? 1 : 0,
+		feeRandCallback,
+		&session());
+	if(mFeeFeed == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	/* finally, have BlockCryptor set up its stuff. */
+	unsigned plainBlockSize  = feeFEEDPlainBlockSize(mFeeFeed);
+	unsigned cipherBlockSize = feeFEEDCipherBlockSize(mFeeFeed);
+	setup(encoding ? plainBlockSize  : cipherBlockSize, // blockSizeIn
+		  encoding ? cipherBlockSize : plainBlockSize,	// blockSizeOut
+		  false,										// pkcsPad
+		  true,											// needsFinal
+		  BCM_ECB,
+		  NULL);										// IV
+	mInitFlag = true;
+}
+
+// called by BlockCryptor
+void CryptKit::FEEDContext::encryptBlock(
+	const void		*plainText,			// length implied (one block)
+	size_t			plainTextLen,
+	void			*cipherText,	
+	size_t			&cipherTextLen,		// in/out, throws on overflow
+	bool			final)
+{
+	feeReturn frtn;
+	unsigned actMoved;
+	
+	assert(mFeeFeed != NULL);
+	frtn = feeFEEDEncryptBlock(mFeeFeed,
+		(unsigned char *)plainText,
+		plainTextLen,
+		(unsigned char *)cipherText,
+		&actMoved,
+		final ? 1 : 0);
+	if(frtn) {
+		throwCryptKit(frtn, "feeFEEDEncryptBlock");
+	}
+	if(actMoved > cipherTextLen) {
+		/* Overflow already occurred! */
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	cipherTextLen = actMoved;
+}
+
+void CryptKit::FEEDContext::decryptBlock(
+	const void		*cipherText,		// length implied (one cipher block)
+	void			*plainText,	
+	size_t			&plainTextLen,		// in/out, throws on overflow
+	bool			final)
+{
+	feeReturn frtn;
+	unsigned actMoved;
+	
+	assert(mFeeFeed != NULL);
+	frtn = feeFEEDDecryptBlock(mFeeFeed,
+		(unsigned char *)cipherText,
+		inBlockSize(),
+		(unsigned char *)plainText,
+		&actMoved,
+		final ? 1 : 0);
+	if(frtn) {
+		throwCryptKit(frtn, "feeFEEDDecryptBlock");
+	}
+	if(actMoved > plainTextLen) {
+		/* Overflow already occurred! */
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	plainTextLen = actMoved;
+}
+
+/*
+ * Additional query size support, necessary because we don't conform to 
+ * BlockCryptor's standard one-to-one block scheme
+ */
+ 
+#define BUFFER_DEBUG	0
+#if		BUFFER_DEBUG
+#define bprintf(s)		printf s
+#else
+#define bprintf(s)
+#endif
+
+size_t CryptKit::FEEDContext::inputSize(
+	size_t 			outSize)			// input for given output size
+{
+	/*
+	 * We've been assured that this is NOT called for the final() op...
+	 */
+	unsigned inSize;
+	if(encoding()) {
+		inSize = feeFEEDPlainTextSize(mFeeFeed, outSize, 0);
+	}
+	else {
+		inSize = feeFEEDCipherTextSize(mFeeFeed, outSize, 0);
+	}
+	
+	/* account for possible pending buffered input */
+	if(inSize >= inBufSize()) {
+		inSize -= inBufSize();
+	}
+	
+	/* round up to next block size, then lop off one...anything from
+	 * blockSize*n to (blockSize*n)-1 has same effect */
+	unsigned inBlocks = ((inSize + inBlockSize()) / inBlockSize());
+	inSize = (inBlocks * inBlockSize()) - 1;
+	bprintf(("--- FEEDContext::inputSize  inSize 0x%x outSize 0x%x\n",
+		inSize, outSize));
+	return inSize;
+}
+
+size_t CryptKit::FEEDContext::outputSize(
+	bool 			final, 
+	size_t 			inSize) 			// output for given input size
+{
+	size_t rtn;
+	if(encoding()) {
+		rtn = feeFEEDCipherTextSize(mFeeFeed, inSize + inBufSize(), final ? 1 : 0);
+	}
+	else {
+		rtn = feeFEEDPlainTextSize(mFeeFeed, inSize + inBufSize(), final ? 1 : 0);
+	}
+	bprintf(("--- FEEDContext::outputSize inSize 0x%x outSize 0x%x final %d\n",
+		inSize, rtn, final));
+	return rtn;
+}
+
+void CryptKit::FEEDContext::minimumProgress(
+	size_t 			&in, 
+	size_t 			&out) 				// minimum progress chunks
+{
+	if(encoding()) {
+		/*
+		 * -- in  := one block plaintext
+		 * -- out := current cipher size for one block plaintext
+		 */
+		in  = inBlockSize();
+		out = feeFEEDCipherBufSize(mFeeFeed, 0);
+	}
+	else {
+		/*
+		 * -- in  := current cipher size for one block plaintext
+		 * -- out := one block plaintext
+		 */
+		in  = feeFEEDCipherBufSize(mFeeFeed, 0); 
+		out = outBlockSize();
+	}
+	
+	/* 
+	 * Either case - input adjusted for pending. Note inBufSize can be up to one 
+	 * input block size, leaving the temp result zero here....
+	 */
+	assert(in >= inBufSize());
+	in -= inBufSize();
+	
+	/* if it is zero, bump it up so caller can make something happen */
+	if(in == 0) {
+		in++;
+	}
+	bprintf(("--- FEEDContext::minProgres inSize 0x%x outSize 0x%x\n",
+		in, out));
+}
+
+/***
+ *** FEEDExp - 2:1 FEED - encrypt n bytes of plaintext, get (roughly) 2n bytes
+ *** of ciphertext. Ciphertext is larger than with FEED, but this is faster.
+ ***/
+CryptKit::FEEDExpContext::~FEEDExpContext()
+{
+	if(mFeeFeedExp) {
+		feeFEEDExpFree(mFeeFeedExp);
+		mFeeFeedExp = NULL;
+	}
+	if(mFeeKey && mAllocdFeeKey) {
+		feePubKeyFree(mFeeKey);
+	}
+	mFeeKey = NULL;
+	mInitFlag = false;
+}
+
+// called by CSPFullPluginSession; reusable
+void CryptKit::FEEDExpContext::init(
+	const Context &context, 
+	bool encoding)
+{
+	if(mInitFlag && !opStarted()) {
+		/* reusing - e.g. query followed by encrypt */
+		return;
+	}
+	
+	/* fetch FEE key from context */
+	CSSM_KEYCLASS 	keyClass;
+	CSSM_KEYUSE		keyUse;
+	
+	if(encoding) {
+		/* encrypting to public key */
+		keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+		keyUse   = CSSM_KEYUSE_ENCRYPT;
+	}
+	else {
+		/* decrypting with private key */
+		keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
+		keyUse   = CSSM_KEYUSE_DECRYPT;
+	}
+	if(mFeeKey == NULL) {
+		assert(!opStarted());
+		mFeeKey = contextToFeeKey(context,
+			session(),
+			CSSM_ATTRIBUTE_KEY,
+			keyClass,
+			keyUse,
+			mAllocdFeeKey);
+	}
+	else {
+		assert(opStarted());
+	}
+	
+	/* validate context - no other attributes allowed */
+	validateFeedContext(context);
+
+	/* OK, looks good. Cook up a feeFEEDExp object. */
+	if(mFeeFeedExp != NULL) {
+		/* not reusable */
+		assert(opStarted());
+		feeFEEDExpFree(mFeeFeedExp);
+		mFeeFeedExp = NULL;
+	}
+	mFeeFeedExp = feeFEEDExpNewWithPubKey(mFeeKey,
+		feeRandCallback,
+		&session());
+	if(mFeeFeedExp == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	/* finally, have BlockCryptor set up its stuff. */
+	unsigned plainBlockSize = feeFEEDExpPlainBlockSize(mFeeFeedExp);
+	unsigned cipherBlockSize = feeFEEDExpCipherBlockSize(mFeeFeedExp);
+	setup(encoding ? plainBlockSize  : cipherBlockSize, // blockSizeIn
+		  encoding ? cipherBlockSize : plainBlockSize,	// blockSizeOut
+		  false,										// pkcs5Pad
+		  true,											// needsFinal
+		  BCM_ECB,
+		  NULL);											// IV
+	mInitFlag = true;
+}
+
+// called by BlockCryptor
+void CryptKit::FEEDExpContext::encryptBlock(
+	const void		*plainText,			// length implied (one block)
+	size_t			plainTextLen,
+	void			*cipherText,	
+	size_t			&cipherTextLen,		// in/out, throws on overflow
+	bool			final)
+{
+	feeReturn frtn;
+	unsigned actMoved;
+	
+	assert(mFeeFeedExp != NULL);
+	frtn = feeFEEDExpEncryptBlock(mFeeFeedExp,
+		(unsigned char *)plainText,
+		plainTextLen,
+		(unsigned char *)cipherText,
+		&actMoved,
+		final ? 1 : 0);
+	if(frtn) {
+		throwCryptKit(frtn, "feeFEEDExpEncryptBlock");
+	}
+	if(actMoved > cipherTextLen) {
+		/* Overflow already occurred! */
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	cipherTextLen = actMoved;
+}
+
+void CryptKit::FEEDExpContext::decryptBlock(
+	const void		*cipherText,		// length implied (one cipher block)
+	void			*plainText,	
+	size_t			&plainTextLen,		// in/out, throws on overflow
+	bool			final)
+{
+	feeReturn frtn;
+	unsigned actMoved;
+	
+	assert(mFeeFeedExp != NULL);
+	frtn = feeFEEDExpDecryptBlock(mFeeFeedExp,
+		(unsigned char *)cipherText,
+		inBlockSize(),
+		(unsigned char *)plainText,
+		&actMoved,
+		final ? 1 : 0);
+	if(frtn) {
+		throwCryptKit(frtn, "feeFEEDExpDecryptBlock");
+	}
+	if(actMoved > plainTextLen) {
+		/* Overflow already occurred! */
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	plainTextLen = actMoved;
+}
+
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/FEEAsymmetricContext.h b/AppleCSP/CryptKitCSP/FEEAsymmetricContext.h
new file mode 100644
index 00000000..dfb0366b
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/FEEAsymmetricContext.h
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * FEEAsymmetricContext.h - CSPContexts for FEE asymmetric encryption
+ *
+ * Created March 8 2001 by dmitch.
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#ifndef _FEE_ASYMMETRIC_CONTEXT_H_
+#define _FEE_ASYMMETRIC_CONTEXT_H_
+
+#include <Security/CSPsession.h>
+#include "AppleCSP.h"
+#include "AppleCSPContext.h"
+#include "AppleCSPSession.h"
+#include "BlockCryptor.h"
+#include <CryptKit/feeFEED.h>
+#include <CryptKit/feeFEEDExp.h>
+
+namespace CryptKit {
+
+class FEEDContext : public BlockCryptor {
+public:
+	FEEDContext(AppleCSPSession &session) :
+		BlockCryptor(session),
+		mFeeFeed(NULL),
+		mPrivKey(NULL),
+		mPubKey(NULL),
+		mInitFlag(false) 	{ }
+	~FEEDContext();
+	
+	/* called by CSPFullPluginSession */
+	void init(const Context &context, bool encoding = true);
+
+	/* called by BlockCryptor */
+	void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, throws on overflow
+		bool			final);
+	void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, throws on overflow
+		bool			final);
+	
+	/*
+ 	 * Additional query size support, necessary because we don't conform to 
+	 * BlockCryptor's standard one-to-one block scheme
+	 */
+ 	size_t inputSize(
+		size_t 			outSize);			// input for given output size
+	size_t outputSize(
+		bool 			final = false, 
+		size_t 			inSize = 0); 		// output for given input size
+	void minimumProgress(
+		size_t 			&in, 
+		size_t 			&out); 				// minimum progress chunks
+
+
+private:
+		feeFEED			mFeeFeed;
+		feePubKey		mPrivKey;
+		bool			mAllocdPrivKey;
+		feePubKey		mPubKey;
+		bool			mAllocdPubKey;
+		bool			mInitFlag;			// allows easy reuse
+};	/* FEEDContext */
+
+
+class FEEDExpContext : public BlockCryptor {
+public:
+	FEEDExpContext(AppleCSPSession &session) :
+		BlockCryptor(session),
+		mFeeFeedExp(NULL),
+		mFeeKey(NULL),
+		mInitFlag(false) 	{ }
+
+	~FEEDExpContext();
+	
+	/* called by CSPFullPluginSession */
+	void init(const Context &context, bool encoding = true);
+
+	/* called by BlockCryptor */
+	void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, throws on overflow
+		bool			final);
+	void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, throws on overflow
+		bool			final);
+	
+private:
+		feeFEEDExp		mFeeFeedExp;
+		feePubKey		mFeeKey;
+		bool			mAllocdFeeKey;
+		bool			mInitFlag;			// allows easy reuse
+};	/* FEEDExpContext */
+
+} /* namespace CryptKit */
+
+#endif 	/* _FEE_ASYMMETRIC_CONTEXT_H_ */
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/FEECSPUtils.cpp b/AppleCSP/CryptKitCSP/FEECSPUtils.cpp
new file mode 100644
index 00000000..31ca5f44
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/FEECSPUtils.cpp
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * FEECSPUtils.h - Misc. utility function for FEE/CryptKit CSP. 
+ *
+ * Created 2/20/2001 by dmitch.
+ */
+ 
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#include <Security/utilities.h>
+#include <Security/debugging.h>
+#include <Security/logging.h>
+#include "FEECSPUtils.h"
+#include "FEEKeys.h"
+#include <CryptKit/feeFunctions.h>
+#include <CryptKit/feePublicKey.h>
+
+#define feeMiscDebug(args...)	debug("feeMisc", ## args)
+
+/* Given a FEE error, throw appropriate CssmError */
+void CryptKit::throwCryptKit(
+	feeReturn 	frtn, 
+	const char	*op)		/* optional */
+{
+	if(op) {
+		Security::Syslog::error("Apple CSP %s: %s", op, feeReturnString(frtn));
+	}
+	switch(frtn) {
+		case FR_Success:
+			return;
+		case FR_BadPubKey:
+		case FR_BadPubKeyString:
+		case FR_IncompatibleKey:
+		case FR_BadKeyBlob:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+		case FR_IllegalDepth:
+			CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE);
+		case FR_BadSignatureFormat:		/* signature corrupted */
+			CssmError::throwMe(CSSMERR_CSP_INVALID_SIGNATURE);
+		case FR_InvalidSignature:		/* signature intact, but not valid */
+			CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
+		case FR_IllegalArg:			/* illegal argument */
+			CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
+		case FR_BadCipherText:		/* malformed ciphertext */
+		case FR_BadEnc64:			/* bad enc64() format */
+			CssmError::throwMe(CSSMERR_CSP_INVALID_DATA);
+		case FR_Unimplemented:		/* unimplemented function */
+			CssmError::throwMe(CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED);
+		case FR_Memory:		/* unimplemented function */
+			CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+		case FR_ShortPrivData:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SEED);
+		case FR_IllegalCurve:		/* e.g., ECDSA with Montgomery curve */
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+
+		/* I don't think we should ever see these no matter what the 
+		 * caller throws at us */
+		case FR_WrongSignatureType:	/* ElGamal vs. ECDSA */
+		case FR_BadUsageName:		/* bad usageName */
+		case FR_BadCipherFile:
+		case FR_Internal:			/* internal library error */
+			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+}
+
+/* 
+ * Given a Context:
+ * -- obtain CSSM key of specified CSSM_ATTRIBUTE_TYPE
+ * -- validate keyClass
+ * -- validate keyUsage
+ * -- convert to feePubKey, allocating the feePubKey if necessary
+ */
+feePubKey CryptKit::contextToFeeKey(
+	const Context 		&context,
+	AppleCSPSession	 	&session,
+	CSSM_ATTRIBUTE_TYPE	attrType,	  // CSSM_ATTRIBUTE_KEY, CSSM_ATTRIBUTE_PUBLIC_KEY
+	CSSM_KEYCLASS		keyClass,	  // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
+	CSSM_KEYUSE			usage,		  // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
+	bool				&mallocdKey)  // RETURNED
+{
+    CssmKey &cssmKey = 
+		context.get<CssmKey>(attrType, CSSMERR_CSP_MISSING_ATTR_KEY);
+	const CSSM_KEYHEADER &hdr = cssmKey.KeyHeader;
+	if(hdr.AlgorithmId != CSSM_ALGID_FEE) {
+		CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
+	}
+	if(hdr.KeyClass != keyClass) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	cspValidateIntendedKeyUsage(&hdr, usage);
+	return cssmKeyToFee(cssmKey, session, mallocdKey);
+}
+
+/* 
+ * Convert a CssmKey to a feePubKey. May result in the creation of a new
+ * feePubKey (when cssmKey is a raw key); allocdKey is true in that case
+ * in which case the caller generally has to free the allocd key).
+ */
+feePubKey CryptKit::cssmKeyToFee(
+	const CssmKey	&cssmKey,
+	AppleCSPSession	&session,
+	bool			&allocdKey)	// RETURNED
+{
+	feePubKey feeKey = NULL;
+	allocdKey = false;
+	
+	const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
+	if(hdr->AlgorithmId != CSSM_ALGID_FEE) {
+		// someone else's key (should never happen)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	switch(hdr->BlobType) {
+		case CSSM_KEYBLOB_RAW:
+			feeKey = rawCssmKeyToFee(cssmKey);
+			allocdKey = true;
+			break;
+		case CSSM_KEYBLOB_REFERENCE:
+		{
+			BinaryKey &binKey = session.lookupRefKey(cssmKey);
+			FEEBinaryKey *feeBinKey = dynamic_cast<FEEBinaryKey *>(&binKey);
+			/* this cast failing means that this is some other
+			 * kind of binary key */
+			if(feeBinKey == NULL) {
+				feeMiscDebug("CryptKit::cssmKeyToFee: wrong BinaryKey subclass\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+			}
+			assert(feeBinKey->feeKey() != NULL);
+			feeKey = feeBinKey->feeKey();
+			break;
+		}
+		default:
+			CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
+	}
+	return feeKey;
+}
+
+/* 
+ * Convert a raw CssmKey to a newly alloc'd feePubKey.
+ */
+feePubKey CryptKit::rawCssmKeyToFee(
+	const CssmKey	&cssmKey)
+{
+	const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
+	assert(hdr->BlobType == CSSM_KEYBLOB_RAW); 
+	
+	if(hdr->AlgorithmId != CSSM_ALGID_FEE) {
+		// someone else's key (should never happen)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	bool derBlob;
+	switch(hdr->Format) {
+		case FEE_KEYBLOB_DEFAULT_FORMAT:
+			derBlob = true;
+			break;
+		case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING:
+			derBlob = false;
+			break;
+		default:
+			feeMiscDebug("CryptKit::rawCssmKeyToFee: format mismatch\n");
+			CssmError::throwMe(hdr->KeyClass == CSSM_KEYCLASS_PRIVATE_KEY ?
+				CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT :
+				CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT);
+	}
+	switch(hdr->KeyClass) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			break;
+		default:
+			// someone else's key
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	
+	feePubKey feeKey = feePubKeyAlloc();
+	if(feeKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+	}
+	feeReturn frtn = FR_Internal;
+	switch(hdr->KeyClass) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			if(derBlob) {
+				frtn = feePubKeyInitFromDERPubBlob(feeKey,
+					cssmKey.KeyData.Data,
+					cssmKey.KeyData.Length);
+			}
+			else {
+				frtn = feePubKeyInitFromPubBlob(feeKey,
+					cssmKey.KeyData.Data,
+					cssmKey.KeyData.Length);
+			}
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			if(derBlob) {
+				frtn = feePubKeyInitFromDERPrivBlob(feeKey,
+					cssmKey.KeyData.Data,
+					cssmKey.KeyData.Length);
+			}
+			else {
+				frtn = feePubKeyInitFromPrivBlob(feeKey,
+					cssmKey.KeyData.Data,
+					cssmKey.KeyData.Length);
+			}
+	}
+	if(frtn) {
+		feePubKeyFree(feeKey);
+		throwCryptKit(frtn, "feePubKeyInitFromKeyBlob");
+	}
+	return feeKey;
+}
+
+/*
+ * Glue function which allows C code to use AppleCSPSession 
+ * as an RNG. A ptr to this function gets passed down to 
+ * CryptKit C functions as a feeRandFcn.
+ */
+feeReturn CryptKit::feeRandCallback(
+	void *ref,					// actually an AppleCSPSession *
+	unsigned char *bytes,		// must be alloc'd by caller 
+	unsigned numBytes)
+{
+	AppleCSPSession *session = 
+		reinterpret_cast<AppleCSPSession *>(ref);
+	try {
+		session->getRandomBytes(numBytes, bytes);
+	}
+	catch(...) {
+		return FR_Internal;
+	}
+	return FR_Success;
+}
+
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/FEECSPUtils.h b/AppleCSP/CryptKitCSP/FEECSPUtils.h
new file mode 100644
index 00000000..07a83588
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/FEECSPUtils.h
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * FEECSPUtils.h - Misc. utility function for FEE/CryptKit CSP. 
+ *
+ * Created 2/20/2001 by dmitch.
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+ 
+#ifndef	_FEE_CSP_UTILS_H_
+#define _FEE_CSP_UTILS_H_
+
+#include "AppleCSPSession.h"
+#include <CryptKit/feeTypes.h>
+#include <Security/context.h>
+
+/*
+ * Default FEE keyblob format, indicating DER-encoding.
+ * FEE keys can optionally be generated by requesting 
+ * CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING, indicating native FEE key blobs.
+ */
+#define FEE_KEYBLOB_DEFAULT_FORMAT	CSSM_KEYBLOB_RAW_FORMAT_NONE
+
+namespace CryptKit {
+
+/* Given a FEE error, throw appropriate CssmError */
+void throwCryptKit(
+	feeReturn 	frtn, 
+	const char	*op);		/* optional */
+
+/* 
+ * Given a Context:
+ * -- obtain CSSM key of specified CSSM_ATTRIBUTE_TYPE
+ * -- validate keyClass
+ * -- validate keyUsage
+ * -- convert to feePubKey, allocating the feePubKey if necessary
+ */
+feePubKey contextToFeeKey(
+	const Context 		&context,
+	AppleCSPSession	 	&session,
+	CSSM_ATTRIBUTE_TYPE	attrType,	  // CSSM_ATTRIBUTE_KEY, CSSM_ATTRIBUTE_PUBLIC_KEY
+	CSSM_KEYCLASS		keyClass,	  // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
+	CSSM_KEYUSE			usage,		  // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
+	bool				&mallocdKey); // RETURNED
+
+/* 
+ * Convert a CssmKey to a feePubKey. May result in the creation of a new
+ * feePubKey (when cssmKey is a raw key); allocdKey is true in that case
+ * in which case the caller generally has to free the allocd key).
+ */
+feePubKey cssmKeyToFee(
+	const CssmKey	&cssmKey,
+	AppleCSPSession	&session,
+	bool			&allocdKey);	// RETURNED
+
+/* 
+ * Convert a raw CssmKey to a newly alloc'd feePubKey.
+ */
+feePubKey rawCssmKeyToFee(
+	const CssmKey	&cssmKey);
+
+/*
+ * Glue function which allows C code to use AppleCSPSession 
+ * as an RNG. A ptr to this function gets passed down to 
+ * CryptKit C functions as a feeRandFcn.
+ */
+feeReturn feeRandCallback(
+	void 			*ref,		// actually an AppleCSPSession *
+	unsigned char 	*bytes,		// must be alloc'd by caller 
+	unsigned 		numBytes);
+
+} /* namespace CryptKit */
+
+#endif	/* _FEE_CSP_UTILS_H_ */
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/FEEKeys.cpp b/AppleCSP/CryptKitCSP/FEEKeys.cpp
new file mode 100644
index 00000000..317e3e81
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/FEEKeys.cpp
@@ -0,0 +1,306 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * FEEKeys.cpp - FEE-related asymmetric key pair classes. 
+ *
+ * Created 2/21/2001 by dmitch.
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#include "FEEKeys.h"
+#include "FEECSPUtils.h"
+#include "CryptKitSpace.h"
+#include <CryptKit/feePublicKey.h>
+#include <CryptKit/falloc.h>
+#include <Security/cssmdata.h>
+#include "AppleCSPSession.h"
+#include "AppleCSPUtils.h"
+#include <assert.h>
+#include <Security/debugging.h>
+
+#define feeKeyDebug(args...)	debug("feeKey", ## args)
+
+/***
+ *** FEE-style BinaryKey
+ ***/
+ 
+/* constructor with optional existing feePubKey */
+CryptKit::FEEBinaryKey::FEEBinaryKey(feePubKey feeKey)
+	: mFeeKey(feeKey)
+{
+	if(mFeeKey == NULL) {
+		mFeeKey = feePubKeyAlloc();
+		if(mFeeKey == NULL) {
+			CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+		}
+	}
+}
+
+CryptKit::FEEBinaryKey::~FEEBinaryKey()
+{
+	if(mFeeKey) {
+		feePubKeyFree(mFeeKey);
+		mFeeKey = NULL;
+	}
+}
+
+void CryptKit::FEEBinaryKey::generateKeyBlob(
+		CssmAllocator 		&allocator,
+		CssmData			&blob,
+		CSSM_KEYBLOB_FORMAT	&format)
+{
+	unsigned char 	*keyBlob;
+	unsigned 		len;
+	feeReturn		frtn;
+	bool			derBlob;
+	
+	assert(mFeeKey != NULL);
+	switch(format) {
+		/* also case FEE_KEYBLOB_DEFAULT_FORMAT: */
+		case CSSM_KEYBLOB_RAW_FORMAT_NONE:
+			derBlob = true;
+			break;
+		case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING:
+			/* native non-DER-encoded blob */
+			derBlob = false;
+			break;
+		default:
+			feeKeyDebug("FEEBinaryKey::generateKeyBlob: bad format (%ld)\n", format);
+			CssmError::throwMe(feePubKeyIsPrivate(mFeeKey) ?
+				CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT :
+				CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT);
+	}
+	if(feePubKeyIsPrivate(mFeeKey)) {
+		if(derBlob) {
+			frtn = feePubKeyCreateDERPrivBlob(mFeeKey, &keyBlob, &len);
+		}
+		else {
+			frtn = feePubKeyCreatePrivBlob(mFeeKey, &keyBlob, &len);
+		}
+	}
+	else {
+		if(derBlob) {
+			frtn = feePubKeyCreateDERPubBlob(mFeeKey, &keyBlob, &len);
+		}
+		else {
+			frtn = feePubKeyCreatePubBlob(mFeeKey, &keyBlob, &len);
+		}
+	}
+	if(frtn) {
+		throwCryptKit(frtn, "feePubKeyCreate*Blob");
+	}
+	setUpCssmData(blob, len, allocator);
+	memmove(blob.data(), keyBlob, len);
+	blob.length(len);
+	ffree(keyBlob);
+	format = derBlob ? FEE_KEYBLOB_DEFAULT_FORMAT : 
+		CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
+}
+		
+/***
+ *** FEE-style AppleKeyPairGenContext
+ ***/
+
+/*
+ * This one is specified in, and called from, CSPFullPluginSession. Our
+ * only job is to prepare two subclass-specific BinaryKeys and call up to
+ * AppleKeyPairGenContext.
+ */
+void CryptKit::FEEKeyPairGenContext::generate(
+	const Context 	&context, 
+	CssmKey 		&pubKey, 
+	CssmKey 		&privKey)
+{
+	FEEBinaryKey *pubBinKey  = new FEEBinaryKey();
+	FEEBinaryKey *privBinKey = new FEEBinaryKey();
+	
+	try {
+		AppleKeyPairGenContext::generate(context, 
+			session(),
+			pubKey, 
+			pubBinKey, 
+			privKey, 
+			privBinKey);
+	}
+	catch (...) {
+		delete pubBinKey;
+		delete privBinKey;
+		throw;
+	}
+
+}
+	
+// this one is specified in, and called from, AppleKeyPairGenContext
+void CryptKit::FEEKeyPairGenContext::generate(
+	const Context 	&context,
+	BinaryKey		&pubBinKey,	
+	BinaryKey		&privBinKey,
+	uint32			&keyBits)
+{
+	/* 
+	 * These casts throw exceptions if the keys are of the 
+	 * wrong classes, which would be a major bogon, since we created
+	 * the keys in the above generate() function.
+	 */
+	FEEBinaryKey &fPubBinKey = 
+		dynamic_cast<FEEBinaryKey &>(pubBinKey);
+	FEEBinaryKey &fPrivBinKey = 
+		dynamic_cast<FEEBinaryKey &>(privBinKey);
+
+	/*
+	 * Two parameters from context. Key size in bits is required;
+	 * seed is optional. If not present, we cook up random private data. 
+	 */
+	keyBits = context.getInt(CSSM_ATTRIBUTE_KEY_LENGTH,
+				CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH);
+	CssmCryptoData *cseed = context.get<CssmCryptoData>(CSSM_ATTRIBUTE_SEED);
+	CssmData *seed;
+	bool haveSeed;
+	CssmAutoData aSeed(session());		// malloc on demand
+	if(cseed) {
+		/* caller specified seed */
+		haveSeed = true;
+		seed = &cseed->param();
+	}
+	else {
+		/* generate random seed */
+		haveSeed = false;
+		unsigned keyBytes = ((keyBits + 7) / 8) + 1;
+		aSeed.malloc(keyBytes);
+		session().getRandomBytes(keyBytes, aSeed);
+		seed = &aSeed.get();
+	}
+	
+	/* Curve and prime types - optional */
+	feePrimeType primeType = FPT_Default;
+	uint32 uPrimeType = context.getInt(CSSM_ATTRIBUTE_FEE_PRIME_TYPE);
+	switch(uPrimeType) {
+		case CSSM_FEE_PRIME_TYPE_DEFAULT:
+			break;
+		case CSSM_FEE_PRIME_TYPE_MERSENNE:
+			primeType = FPT_Mersenne;
+			break;
+		case CSSM_FEE_PRIME_TYPE_FEE:
+			primeType = FPT_FEE;
+			break;
+		case CSSM_FEE_PRIME_TYPE_GENERAL:
+			primeType = FPT_General;
+			break;
+		default:
+			/* FIXME - maybe we should be more specific */
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS);
+	}
+	feeCurveType curveType = FCT_Default;
+	uint32 uCurveType = context.getInt(CSSM_ATTRIBUTE_FEE_CURVE_TYPE);
+	switch(uCurveType) {
+		case CSSM_FEE_CURVE_TYPE_DEFAULT:
+			break;
+		case CSSM_FEE_CURVE_TYPE_MONTGOMERY:
+			curveType = FCT_Montgomery;
+			break;
+		case CSSM_FEE_CURVE_TYPE_WEIERSTRASS:
+			curveType = FCT_Weierstrass;
+			break;
+		default:
+			/* FIXME - maybe we should be more specific */
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS);
+	}
+	feeReturn frtn = feePubKeyInitFromPrivDataKeyBits( 
+		fPrivBinKey.feeKey(),
+		(unsigned char *)seed->data(),
+		seed->length(),
+		keyBits,
+		primeType,
+		curveType,
+		/* 
+		 * our random seed: trust it
+		 * caller's seed: hash it
+		 */
+		haveSeed ? 1 : 0);
+	if(frtn) {
+		throwCryptKit(frtn, "feePubKeyInitFromPrivDataKeyBits");
+	}
+	frtn = feePubKeyInitPubKeyFromPriv(fPrivBinKey.feeKey(), 
+		fPubBinKey.feeKey());
+	if(frtn) {
+		throwCryptKit(frtn, "feePubKeyInitPubKeyFromPriv");
+	}
+}
+
+
+/***
+ *** FEE-style CSPKeyInfoProvider.
+ ***/
+CryptKit::FEEKeyInfoProvider::FEEKeyInfoProvider(
+	const CssmKey &cssmKey) :
+		CSPKeyInfoProvider(cssmKey)
+{
+	switch(cssmKey.algorithm()) {
+		case CSSM_ALGID_FEE:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	switch(cssmKey.keyClass()) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			/* FIXME - verify proper CSSM_KEYBLOB_RAW_FORMAT_xx */
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	/* OK, we'll handle this one */
+	return;
+}
+
+/* Given a raw key, cook up a Binary key */
+void CryptKit::FEEKeyInfoProvider::CssmKeyToBinary(
+	BinaryKey **binKey)
+{
+	*binKey = NULL;
+	feePubKey feeKey = NULL;
+	
+	/* first cook up a feePubKey, then drop that into a BinaryKey */
+	feeKey = rawCssmKeyToFee(mKey);
+	FEEBinaryKey *feeBinKey = new FEEBinaryKey(feeKey);
+	*binKey = feeBinKey;
+}
+		
+/* 
+ * Obtain key size in bits.
+ * Currently only raw public keys are dealt with (they're the ones
+ * which come from certs, the only current use for this function).
+ * Note that if we need to handle ref keys, we'll need a session ref...
+ */
+void CryptKit::FEEKeyInfoProvider::QueryKeySizeInBits(
+	CSSM_KEY_SIZE &keySize)
+{
+	feePubKey feeKey = NULL;
+	
+	if(mKey.blobType() != CSSM_KEYBLOB_RAW) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+	}
+	feeKey = rawCssmKeyToFee(mKey);
+	keySize.LogicalKeySizeInBits = feePubKeyBitsize(feeKey);
+	keySize.EffectiveKeySizeInBits = keySize.LogicalKeySizeInBits;
+	feePubKeyFree(feeKey);
+}
+
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/FEEKeys.h b/AppleCSP/CryptKitCSP/FEEKeys.h
new file mode 100644
index 00000000..411969ae
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/FEEKeys.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * FEEKeys.h - FEE-related asymmetric key pair classes. 
+ *
+ * Created 2/21/2001 by dmitch.
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#ifndef	_FEE_KEYS_H_
+#define _FEE_KEYS_H_
+
+#include "AppleCSPContext.h"
+#include "AppleCSPSession.h"
+#include <CryptKitCSP/cryptkitcsp.h>
+#include <CryptKit/feeTypes.h>
+
+namespace CryptKit {
+
+/*
+ * FEE version of a BinaryKey.
+ */
+class FEEBinaryKey : public BinaryKey {
+public:
+	FEEBinaryKey(feePubKey feeKey = NULL);
+	~FEEBinaryKey();
+	void generateKeyBlob(
+		CssmAllocator 		&allocator,
+		CssmData			&blob,
+		CSSM_KEYBLOB_FORMAT	&format);
+
+	feePubKey				feeKey() { return mFeeKey; }
+private:
+	feePubKey				mFeeKey;
+};
+
+class FEEKeyPairGenContext : 
+	public AppleCSPContext, private AppleKeyPairGenContext  {
+public:
+	FEEKeyPairGenContext(
+		AppleCSPSession &session,
+		const Context &) :
+			AppleCSPContext(session) {}
+
+	~FEEKeyPairGenContext() { }
+	
+	/* no init functionality, but we need to implement it */
+	void init(
+		const Context &, 
+		bool) { }
+		
+	// this one is specified in, and called from, CSPFullPluginSession
+	void generate(
+		const Context 	&context, 
+		CssmKey 		&pubKey, 
+		CssmKey 		&privKey);
+		
+	// this one is specified in, and called from, AppleKeyPairGenContext
+	void generate(
+		const Context 	&context,
+		BinaryKey		&pubBinKey,	
+		BinaryKey		&privBinKey,
+		uint32			&keySize);
+	
+};	/* KeyPairGenContext */
+
+/*
+ * CSPKeyInfoProvider for FEE keys
+ */
+class FEEKeyInfoProvider : public CSPKeyInfoProvider 
+{
+public:
+	FEEKeyInfoProvider(
+		const CssmKey		&cssmKey);
+	~FEEKeyInfoProvider() { }
+	void CssmKeyToBinary(
+		BinaryKey			**binKey);	// RETURNED
+	void QueryKeySizeInBits(
+		CSSM_KEY_SIZE		&keySize);	// RETURNED
+};
+
+} /* namespace CryptKit */
+
+#endif	/* _FEE_KEYS_H_ */
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/FEESignatureObject.cpp b/AppleCSP/CryptKitCSP/FEESignatureObject.cpp
new file mode 100644
index 00000000..519c1f7b
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/FEESignatureObject.cpp
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * FEESignatureObject.cpp - implementations of FEE-style raw sign/verify classes
+ *
+ * Created 2/20/2001 by dmitch.
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#include <CryptKitCSP/FEESignatureObject.h>
+#include <CryptKit/feePublicKey.h>
+#include <CryptKit/feeDigitalSignature.h>
+#include <CryptKit/falloc.h>
+#include <stdexcept>
+#include <assert.h>
+#include <Security/debugging.h>
+
+#define feeSigObjDebug(args...)		debug("feeSig", ##args)
+
+CryptKit::FEESigner::~FEESigner()
+{
+	if(mWeMallocdFeeKey) {
+		assert(mFeeKey != NULL);
+		feePubKeyFree(mFeeKey);
+	}
+}
+
+/* 
+ * obtain key from context, validate, convert to native FEE key
+ */
+void CryptKit::FEESigner::keyFromContext(
+	const Context 	&context)
+{
+	if(initFlag() && (mFeeKey != NULL)) {
+		/* reusing context, OK */
+		return;
+	}
+	
+	CSSM_KEYCLASS 	keyClass;
+	CSSM_KEYUSE		keyUse;
+	if(isSigning()) {
+		/* signing with private key */
+		keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
+		keyUse   = CSSM_KEYUSE_SIGN;
+	}
+	else {
+		/* verifying with public key */
+		keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+		keyUse   = CSSM_KEYUSE_VERIFY;
+	}
+	if(mFeeKey == NULL) {
+		mFeeKey = contextToFeeKey(context,
+			mSession,
+			CSSM_ATTRIBUTE_KEY,
+			keyClass,
+			keyUse,
+			mWeMallocdFeeKey);
+	}
+}
+
+/* reusable init */
+void CryptKit::FEESigner::signerInit(
+	const Context 	&context,
+	bool			isSigning)
+{
+	setIsSigning(isSigning);
+	keyFromContext(context);
+	setInitFlag(true);
+}
+
+/*
+ * Note that, unlike the implementation in CryptKit/feePublicKey.c, we ignore
+ * the Pm which used to be used as salt for the digest. That made staged verification
+ * impossible and I do not believe it increased security. 
+ */
+void CryptKit::FEERawSigner::sign(
+	const void	 	*data, 
+	size_t 			dataLen,
+	void			*sig,	
+	size_t			*sigLen)	/* IN/OUT */
+{
+	feeSig 			fsig;
+	feeReturn		frtn;
+	unsigned char	*feeSig;
+	unsigned		feeSigLen;
+	
+	if(mFeeKey == NULL) {
+		throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)");
+	}
+	fsig = feeSigNewWithKey(mFeeKey, mRandFcn, mRandRef);
+	if(fsig == NULL) {
+		throwCryptKit(FR_BadPubKey, "FEERawSigner::sign");
+	}
+	frtn = feeSigSign(fsig,
+		(unsigned char *)data,
+		dataLen,
+		mFeeKey);
+	if(frtn == FR_Success) {
+		frtn = feeSigData(fsig, &feeSig, &feeSigLen);
+	}
+	feeSigFree(fsig);
+	if(frtn) {
+		throwCryptKit(frtn, "FEERawSigner::sign");
+	}
+	
+	/* copy out to caller and ffree */
+	if(*sigLen < feeSigLen) {
+		feeSigObjDebug("FEERawSigner sign overflow\n");
+		ffree(feeSig);
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	memmove(sig, feeSig, feeSigLen);
+	*sigLen = feeSigLen;
+	ffree(feeSig);
+}
+
+void CryptKit::FEERawSigner::verify(
+	const void	 	*data, 
+	size_t 			dataLen,
+	const void		*sig,			
+	size_t			sigLen)
+{
+	feeSig 		fsig;
+	feeReturn	frtn;
+	
+	if(mFeeKey == NULL) {
+		throwCryptKit(FR_BadPubKey, "FEERawSigner::verify (no key)");
+	}
+	frtn = feeSigParse((unsigned char *)sig, sigLen, &fsig);
+	if(frtn) {
+		throwCryptKit(frtn, "feeSigParse");
+	}
+	frtn = feeSigVerify(fsig,
+		(unsigned char *)data,
+		dataLen,
+		mFeeKey);
+	feeSigFree(fsig);
+	if(frtn) {
+		throwCryptKit(frtn, NULL);
+	}
+}
+
+size_t CryptKit::FEERawSigner::maxSigSize()
+{
+	unsigned 	rtn;
+	feeReturn 	frtn;
+	
+	frtn = feeSigSize(mFeeKey, &rtn);
+	if(frtn) {
+		throwCryptKit(frtn, "feeSigSize");
+	}
+	return rtn;
+}
+
+/* ECDSA - this is really easy. */
+
+void CryptKit::FEEECDSASigner::sign(
+	const void	 	*data, 
+	size_t 			dataLen,
+	void			*sig,	
+	size_t			*sigLen)	/* IN/OUT */
+{
+	unsigned char	*feeSig;
+	unsigned		feeSigLen;
+	feeReturn		frtn;
+	
+	if(mFeeKey == NULL) {
+		throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)");
+	}
+	frtn = feeECDSASign(mFeeKey,
+		(unsigned char *)data,   // data to be signed
+		dataLen,				// in bytes
+		mRandFcn, 
+		mRandRef,
+		&feeSig,
+		&feeSigLen);			
+	if(frtn) {
+		throwCryptKit(frtn, "feeECDSASign");
+	}
+	/* copy out to caller and ffree */
+	if(*sigLen < feeSigLen) {
+		feeSigObjDebug("feeECDSASign overflow\n");
+		ffree(feeSig);
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	memmove(sig, feeSig, feeSigLen);
+	*sigLen = feeSigLen;
+	ffree(feeSig);
+
+}
+
+void CryptKit::FEEECDSASigner::verify(
+	const void	*data, 
+	size_t 		dataLen,
+	const void	*sig,			
+	size_t		sigLen)
+{
+	feeReturn	frtn;
+
+	if(mFeeKey == NULL) {
+		throwCryptKit(FR_BadPubKey, "FEERawSigner::verify (no key)");
+	}
+	frtn = feeECDSAVerify((unsigned char *)sig,
+		sigLen,
+		(unsigned char *)data,
+		dataLen,
+		mFeeKey);
+	if(frtn) {
+		throwCryptKit(frtn, NULL);
+	}
+}
+
+size_t CryptKit::FEEECDSASigner::maxSigSize()
+{
+	unsigned 	rtn;
+	feeReturn 	frtn;
+	
+	frtn = feeECDSASigSize(mFeeKey, &rtn);
+	if(frtn) {
+		throwCryptKit(frtn, "feeECDSASigSize");
+	}
+	return rtn;
+}
+
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/FEESignatureObject.h b/AppleCSP/CryptKitCSP/FEESignatureObject.h
new file mode 100644
index 00000000..287974ec
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/FEESignatureObject.h
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * FEESignatureObject.h - FEE-based raw sign/verify classes
+ */
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#ifndef	_FEE_SIGNATURE_OBJECT_H_
+#define _FEE_SIGNATURE_OBJECT_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <CryptKit/feePublicKey.h>
+#include <CryptKit/feeECDSA.h>
+#include <CryptKitCSP/FEECSPUtils.h>
+#include <CryptKitCSP/CryptKitSpace.h>
+#include <AppleCSP/RawSigner.h>
+#include <AppleCSP/AppleCSPSession.h>
+
+namespace CryptKit {
+
+/* 
+ * Common raw FEE sign/verify class.
+ */
+class FEESigner : public RawSigner {
+public:
+	FEESigner(
+		feeRandFcn		randFcn,
+		void			*randRef,
+		AppleCSPSession &session,
+		CssmAllocator	&alloc) : 
+			RawSigner(alloc, CSSM_ALGID_NONE),
+			mFeeKey(NULL),
+			mWeMallocdFeeKey(false),
+			mRandFcn(randFcn),
+			mRandRef(randRef),
+			mSession(session) { }
+			
+	virtual ~FEESigner();
+	
+	/* reusable init */
+	void signerInit(
+		const Context 	&context,
+		bool			isSigning);
+	
+	/* 
+	 * obtain key from context, validate, convert to native FEE key
+	 */
+	void keyFromContext(
+		const Context 	&context);
+
+protected:
+		feePubKey		mFeeKey;
+		bool			mWeMallocdFeeKey;
+		feeRandFcn		mRandFcn;
+		void			*mRandRef;
+		AppleCSPSession	&mSession;
+};
+
+/* 
+ * And two implementations.
+ *
+ * Native FEE signature, ElGamal style.
+ */
+class FEERawSigner : public FEESigner
+{
+public:
+	FEERawSigner(
+		feeRandFcn		randFcn,
+		void			*randRef,
+		AppleCSPSession &session,
+		CssmAllocator	&alloc) : 
+			FEESigner(randFcn, randRef, session, alloc) { };
+			
+	~FEERawSigner() { }
+	
+	/* sign */
+	void sign(
+		const void	 	*data, 
+		size_t 			dataLen,
+		void			*sig,	
+		size_t			*sigLen);	/* IN/OUT */
+		
+	/* verify */
+	void verify(
+		const void 		*data, 
+		size_t 			dataLen,
+		const void		*sig,			
+		size_t			sigLen);	
+		
+	/* works for both, but only used for signing */
+	size_t maxSigSize();
+};
+
+/*
+ * FEE signature, ECDSA style.
+ */
+class FEEECDSASigner : public FEESigner
+{
+public:
+	FEEECDSASigner(
+		feeRandFcn		randFcn,
+		void			*randRef,
+		AppleCSPSession &session,
+		CssmAllocator	&alloc) : 
+			FEESigner(randFcn, randRef, session, alloc) { };
+			
+	~FEEECDSASigner() { }
+	
+	/* sign */
+	void sign(
+		const void	 	*data, 
+		size_t 			dataLen,
+		void			*sig,	
+		size_t			*sigLen);	/* IN/OUT */
+		
+	/* verify */
+	void verify(
+		const void	 	*data, 
+		size_t 			dataLen,
+		const void		*sig,			
+		size_t			sigLen);	
+		
+	/* works for both, but only used for signing */
+	size_t maxSigSize();
+};
+
+} /* namespace CryptKit */
+
+#endif	/* _FEE_SIGNATURE_OBJECT_H_ */
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/CryptKitCSP/cryptkitcsp.cpp b/AppleCSP/CryptKitCSP/cryptkitcsp.cpp
new file mode 100644
index 00000000..24827a03
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/cryptkitcsp.cpp
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+
+//
+// cryptkitcsp - top C++ implementation layer for CryptKit
+//
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#include "cryptkitcsp.h"
+#include "FEESignatureObject.h"			/* raw signer */
+#include <AppleCSP/SignatureContext.h>
+#include "FEEKeys.h"
+#include "FEEAsymmetricContext.h"
+#include <Security/cssmapple.h>
+#include <CryptKit/falloc.h>
+#include <CryptKit/feeFunctions.h>
+#include <MiscCSPAlgs/SHA1_MD5_Object.h>
+
+CssmAllocator *CryptKitFactory::normAllocator;
+CssmAllocator *CryptKitFactory::privAllocator;
+
+/*
+ * CryptKit-style memory allocator callbacks
+ */
+static void *ckMalloc(unsigned size)
+{
+	return CryptKitFactory::privAllocator->malloc(size);
+}
+static void ckFree(void *data)
+{
+	CryptKitFactory::privAllocator->free(data);
+}
+static void *ckRealloc(void *oldPtr, unsigned newSize)
+{
+	return CryptKitFactory::privAllocator->realloc(oldPtr, newSize);
+}
+
+//
+// Manage the CryptKit algorithm factory
+//
+
+CryptKitFactory::CryptKitFactory(CssmAllocator *normAlloc, CssmAllocator *privAlloc)
+{
+	setNormAllocator(normAlloc);
+	setPrivAllocator(privAlloc);
+	/* once-per-address space */
+	initCryptKit();
+	fallocRegister(ckMalloc, ckFree, ckRealloc);
+}
+
+CryptKitFactory::~CryptKitFactory()
+{
+	terminateCryptKit();
+}
+
+bool CryptKitFactory::setup(
+	AppleCSPSession &session,	
+	CSPFullPluginSession::CSPContext * &cspCtx, 
+	const Context &context)
+{
+	switch(context.type()) {
+		case CSSM_ALGCLASS_SIGNATURE:
+			switch(context.algorithm()) {
+				case CSSM_ALGID_FEE_MD5:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new MD5Object()),
+							*(new FEERawSigner(feeRandCallback, 
+								&session,
+								session,
+								*privAllocator)));
+					}
+					return true;
+				case CSSM_ALGID_FEE_SHA1:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new SHA1Object()),
+							*(new FEERawSigner(feeRandCallback, 
+								&session,
+								session,
+								*privAllocator)));
+					}
+					return true;
+				case CSSM_ALGID_SHA1WithECDSA:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new SHA1Object()),
+							*(new FEEECDSASigner(feeRandCallback, 
+								&session,
+								session,
+								*privAllocator)));
+					}
+					return true;
+				default:
+					break;
+			}
+			break;		
+
+		case CSSM_ALGCLASS_KEYGEN:
+			switch(context.algorithm()) {
+				case CSSM_ALGID_FEE:
+					if(cspCtx == NULL) {
+						cspCtx = new CryptKit::FEEKeyPairGenContext(session, context);
+					}
+					return true;
+				default:
+					break;
+			}
+			break;		
+
+		case CSSM_ALGCLASS_ASYMMETRIC:
+			switch(context.algorithm()) {
+				case CSSM_ALGID_FEEDEXP:
+					if(cspCtx == NULL) {
+						cspCtx = new CryptKit::FEEDExpContext(session);
+					}
+					return true;
+				case CSSM_ALGID_FEED:
+					if(cspCtx == NULL) {
+						cspCtx = new CryptKit::FEEDContext(session);
+					}
+					return true;
+				default:
+					break;
+			}
+			break;		
+		
+		/* more here - symmetric, etc. */
+		default:
+			break;
+	}
+	/* not implemented here */
+	return false;
+}
+
+#endif	/* CRYPTKIT_CSP_ENABLE */
+
+
diff --git a/AppleCSP/CryptKitCSP/cryptkitcsp.h b/AppleCSP/CryptKitCSP/cryptkitcsp.h
new file mode 100644
index 00000000..d13c2c0b
--- /dev/null
+++ b/AppleCSP/CryptKitCSP/cryptkitcsp.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+
+//
+// cryptkitcsp.h - AlgorithmFactory for CryptKit CSP
+//
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+
+#ifndef _H_CRYPTKITCSPLIB
+#define _H_CRYPTKITCSPLIB
+
+#include <Security/CSPsession.h>
+#include "AppleCSP.h"
+
+/* Can't include AppleCSPSession.h due to circular dependency */
+class AppleCSPSession;
+
+class CryptKitFactory : public AppleCSPAlgorithmFactory {
+public:
+    CryptKitFactory(CssmAllocator *normAlloc = NULL, CssmAllocator *privAlloc = NULL);
+	~CryptKitFactory();
+	
+    bool setup(
+		AppleCSPSession &session,
+		CSPFullPluginSession::CSPContext * &cspCtx, 
+		const Context &context);
+
+    static void setNormAllocator(CssmAllocator *alloc)
+    { assert(!normAllocator); normAllocator = alloc; }
+    static void setPrivAllocator(CssmAllocator *alloc)
+    { assert(!privAllocator); privAllocator = alloc; }
+
+    // memory allocators
+    static CssmAllocator *normAllocator;
+    static CssmAllocator *privAllocator;
+    
+};
+		
+/* convenience for clients.... */
+#include <CryptKitCSP/CryptKitSpace.h>
+
+#endif //_H_CRYPTKITCSPLIB
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/MiscCSPAlgs/DES.c b/AppleCSP/MiscCSPAlgs/DES.c
new file mode 100644
index 00000000..7f7d23d7
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/DES.c
@@ -0,0 +1,542 @@
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * DES.c - raw DES encryption engine
+ *
+ * Revision History
+ * ----------------
+ * 11/03/98     Michael Brouwer at Apple
+ *	Added braces to static array definition of si[][].
+ * 10/06/98		ap
+ *	Changed to compile with C++.
+ * 28 May 98	Doug Mitchel at Apple
+ *	Changed to use platform-dependent fmalloc(), ffree()
+ * 31 Mar 97	Doug Mitchell at Apple
+ *	Put per-instance data in struct _desInst
+ *	Changed setkey() to dessetkey() to avoid collision with libc version
+ * 21 Aug 96	Doug Mitchell at NeXT
+ *	Broke out from NSDESCryptor.m
+ * 22 Feb 96	Blaine Garst at NeXT
+ *	Created.
+ */
+
+#define STATIC_PERMS	0
+
+#include "DES.h"
+#if	!STATIC_PERMS
+#include <CryptKit/falloc.h>
+#endif
+#include <stdlib.h>
+
+#ifndef	NULL
+#define NULL	((void *)0)
+#endif	/* NULL */
+
+#define DES_DEBUG	0	/* enables some printfs */
+
+/* Sofware DES functions
+ * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
+ * the 1977 public-domain program by Jim Gillogly
+ */
+
+#ifdef	__LITTLE_ENDIAN__
+/* Byte swap a long */
+static unsigned int byteswap(unsigned int x) {
+        register char *cp,tmp;
+
+        cp = (char *)&x;
+        tmp = cp[3];
+        cp[3] = cp[0];
+        cp[0] = tmp;
+
+        tmp = cp[2];
+        cp[2] = cp[1];
+        cp[1] = tmp;
+
+        return x;
+}
+#endif
+
+/* Tables defined in the Data Encryption Standard documents */
+
+/* initial permutation IP */
+static const char ip[] = {
+	58, 50, 42, 34, 26, 18, 10,  2,
+	60, 52, 44, 36, 28, 20, 12,  4,
+	62, 54, 46, 38, 30, 22, 14,  6,
+	64, 56, 48, 40, 32, 24, 16,  8,
+	57, 49, 41, 33, 25, 17,  9,  1,
+	59, 51, 43, 35, 27, 19, 11,  3,
+	61, 53, 45, 37, 29, 21, 13,  5,
+	63, 55, 47, 39, 31, 23, 15,  7
+};
+
+/* final permutation IP^-1 */
+static const char fp[] = {
+	40,  8, 48, 16, 56, 24, 64, 32,
+	39,  7, 47, 15, 55, 23, 63, 31,
+	38,  6, 46, 14, 54, 22, 62, 30,
+	37,  5, 45, 13, 53, 21, 61, 29,
+	36,  4, 44, 12, 52, 20, 60, 28,
+	35,  3, 43, 11, 51, 19, 59, 27,
+	34,  2, 42, 10, 50, 18, 58, 26,
+	33,  1, 41,  9, 49, 17, 57, 25
+};
+
+/* expansion operation matrix
+ * This is for reference only; it is unused in the code
+ * as the f() function performs it implicitly for speed
+ */
+#ifdef notdef
+static char ei[] = {
+	32,  1,  2,  3,  4,  5,
+	 4,  5,  6,  7,  8,  9,
+	 8,  9, 10, 11, 12, 13,
+	12, 13, 14, 15, 16, 17,
+	16, 17, 18, 19, 20, 21,
+	20, 21, 22, 23, 24, 25,
+	24, 25, 26, 27, 28, 29,
+	28, 29, 30, 31, 32,  1
+};
+#endif
+
+/* permuted choice table (key) */
+static const char pc1[] = {
+	57, 49, 41, 33, 25, 17,  9,
+	 1, 58, 50, 42, 34, 26, 18,
+	10,  2, 59, 51, 43, 35, 27,
+	19, 11,  3, 60, 52, 44, 36,
+
+	63, 55, 47, 39, 31, 23, 15,
+	 7, 62, 54, 46, 38, 30, 22,
+	14,  6, 61, 53, 45, 37, 29,
+	21, 13,  5, 28, 20, 12,  4
+};
+
+/* number left rotations of pc1 */
+static const char totrot[] = {
+	1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
+};
+
+/* permuted choice key (table) */
+static const char pc2[] = {
+	14, 17, 11, 24,  1,  5,
+	 3, 28, 15,  6, 21, 10,
+	23, 19, 12,  4, 26,  8,
+	16,  7, 27, 20, 13,  2,
+	41, 52, 31, 37, 47, 55,
+	30, 40, 51, 45, 33, 48,
+	44, 49, 39, 56, 34, 53,
+	46, 42, 50, 36, 29, 32
+};
+
+/* The (in)famous S-boxes */
+static const char si[8][64] = {
+    {
+	/* S1 */
+	14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
+	 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
+	 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
+	15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13
+    },
+    {
+	/* S2 */
+	15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
+	 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
+	 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
+	13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9
+    },
+    {
+	/* S3 */
+	10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
+	13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
+	13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
+	 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12
+    },
+    {
+	/* S4 */
+	 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
+	13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
+	10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
+	 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14
+    },
+    {
+	/* S5 */
+	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
+	14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
+	 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
+	11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3
+    },
+    {
+	/* S6 */
+	12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
+	10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
+	 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
+	 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13
+    },
+    {
+	/* S7 */
+	 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
+	13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
+	 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
+	 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12
+    },
+    {
+	/* S8 */
+	13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
+	 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
+	 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
+	 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
+    }
+};
+
+/* 32-bit permutation function P used on the output of the S-boxes */
+static const char p32i[] = {
+	16,  7, 20, 21,
+	29, 12, 28, 17,
+	 1, 15, 23, 26,
+	 5, 18, 31, 10,
+	 2,  8, 24, 14,
+	32, 27,  3,  9,
+	19, 13, 30,  6,
+	22, 11,  4, 25
+};
+/* End of DES-defined tables */
+
+/* Lookup tables initialized once only at startup by desinit() */
+#if STATIC_PERMS
+static long sp[8][64];			/* Combined S and P boxes */
+static char iperm[16][16][8];	/* Initial and final permutations */
+static char fperm[16][16][8];
+static char perms_init = 0;
+#else
+static long (*sp)[64];		/* Combined S and P boxes */
+static char (*iperm)[16][8];	/* Initial and final permutations */
+static char (*fperm)[16][8];
+#endif
+
+/* bit 0 is left-most in byte */
+static const int bytebit[] = {
+	0200,0100,040,020,010,04,02,01
+};
+
+static const int nibblebit[] = {
+	 010,04,02,01
+};
+
+/* Allocate space and initialize DES lookup arrays
+ * mode == 0: standard Data Encryption Algorithm
+ * mode == 1: DEA without initial and final permutations for speed
+ * mode == 2: DEA without permutations and with 128-byte key (completely
+ *            independent subkeys for each round)
+ */
+/* Initialize the lookup table for the combined S and P boxes */
+static void spinit() {
+    char pbox[32];
+    int p,i,s,j,rowcol;
+    long val;
+
+    /* Compute pbox, the inverse of p32i.
+       * This is easier to work with
+       */
+    for(p=0;p<32;p++){
+        for(i=0;i<32;i++){
+            if(p32i[i]-1 == p){
+                pbox[p] = i;
+                break;
+            }
+        }
+    }
+    for(s = 0; s < 8; s++){			/* For each S-box */
+        for(i=0; i<64; i++){		/* For each possible input */
+            val = 0;
+            /* The row number is formed from the first and last
+               * bits; the column number is from the middle 4
+               */
+            rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
+            for(j=0;j<4;j++){	/* For each output bit */
+                if(si[s][rowcol] & (8 >> j)){
+                    val |= 1L << (31 - pbox[4*s + j]);
+                }
+            }
+            sp[s][i] = val;
+
+#if	DES_DEBUG
+            printf("sp[%d][%2d] = %08lx\n",s,i,sp[s][i]);
+#endif
+        }
+    }
+}
+
+/* initialize a perm array */
+static void perminit(char perm[16][16][8], const char p[64]) {
+        register int l, j, k;
+        int i,m;
+
+        /* Clear the permutation array */
+        for (i=0; i<16; i++)
+                for (j=0; j<16; j++)
+                        for (k=0; k<8; k++)
+                                perm[i][j][k]=0;
+
+        for (i=0; i<16; i++)		/* each input nibble position */
+                for (j = 0; j < 16; j++)/* each possible input nibble */
+                for (k = 0; k < 64; k++)/* each output bit position */
+                {   l = p[k] - 1;	/* where does this bit come from*/
+                        if ((l >> 2) != i)  /* does it come from input posn?*/
+                        continue;	/* if not, bit k is 0	 */
+                        if (!(j & nibblebit[l & 3]))
+                        continue;	/* any such bit in input? */
+                        m = k & 07;	/* which bit is this in the byte*/
+                        perm[i][j][k>>3] |= bytebit[m];
+                }
+}
+
+/*
+ * This is NOT thread-safe. Caler must ensure single-threaded access. */
+int desinit(desInst dinst, int mode) {
+	dinst->desmode = mode;
+
+	/*
+	 * Remainder only has to be done once.
+	 */
+	#if		STATIC_PERMS
+	/* statically allocated */
+	if(perms_init) {
+		return 0;
+	}
+	#else
+	/* malloc the perm tables */
+	if(sp != NULL){
+		/* Already initialized */
+		return 0;
+	}
+	if((sp = (long (*)[64])fmalloc(sizeof(long) * 8 * 64)) == NULL){
+		return -1;
+	}
+	iperm = (char (*)[16][8])fmalloc(sizeof(char) * 16 * 16 * 8);
+	if(iperm == NULL){
+		ffree((char *)sp);
+		return -1;
+	}
+	fperm = (char (*)[16][8])fmalloc(sizeof(char) * 16 * 16 * 8);
+	if(fperm == NULL){
+		ffree((char *)sp);
+		ffree((char *)iperm);
+		return -1;
+	}
+	#endif	/* STATIC_PERMS */
+	
+	/* common code to init the perm tables */
+	spinit();
+	perminit(iperm,ip);
+	perminit(fperm,fp);
+	#if		STATIC_PERMS
+	perms_init = 1;
+	#endif
+	return 0;
+}
+/* Free up storage used by DES */
+void desdone(desInst dinst) {
+	/*
+	 * no per-instance mallocd data
+	 */
+}
+/* Set key (initialize key schedule array) */
+void dessetkey(desInst dinst, char *key) {
+	char pc1m[56];		/* place to modify pc1 into */
+	char pcr[56];		/* place to rotate pc1 into */
+	register int i,j,l;
+	int m;
+
+	/* In mode 2, the 128 bytes of subkey are set directly from the
+	 * user's key, allowing him to use completely independent
+	 * subkeys for each round. Note that the user MUST specify a
+	 * full 128 bytes.
+	 *
+	 * I would like to think that this technique gives the NSA a real
+	 * headache, but I'm not THAT naive.
+	 */
+	if(dinst->desmode == 2){
+		for(i=0;i<16;i++)
+			for(j=0;j<8;j++)
+				dinst->kn[i][j] = *key++;
+		return;
+	}
+	/* Clear key schedule */
+	for (i=0; i<16; i++)
+		for (j=0; j<8; j++)
+			dinst->kn[i][j]=0;
+
+	for (j=0; j<56; j++) {		/* convert pc1 to bits of key */
+		l=pc1[j]-1;		/* integer bit location	 */
+		m = l & 07;		/* find bit		 */
+		pc1m[j]=(key[l>>3] &	/* find which key byte l is in */
+			bytebit[m])	/* and which bit of that byte */
+			? 1 : 0;	/* and store 1-bit result */
+	}
+	for (i=0; i<16; i++) {		/* key chunk for each iteration */
+		for (j=0; j<56; j++)	/* rotate pc1 the right amount */
+			pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
+			/* rotate left and right halves independently */
+		for (j=0; j<48; j++){	/* select bits individually */
+			/* check bit that goes to dinst->kn[j] */
+			if (pcr[pc2[j]-1]){
+				/* mask it in if it's there */
+				l= j % 6;
+				dinst->kn[i][j/6] |= bytebit[l] >> 2;
+			}
+		}
+	}
+#if	DES_DEBUG
+	for(i=0;i<16;i++) {
+		printf("dinst->kn[%d] = ", i);
+		for(j=0;j<8;j++) {
+			printf("%x ", dinst->kn[i][j]);
+		}
+		printf("\n");
+	}
+
+#endif	/* 1 */
+}
+
+/* The nonlinear function f(r,k), the heart of DES */
+static long int f(unsigned long r, unsigned char subkey[8]) {
+		/* 32 bits */
+	/* 48-bit key for this round */
+	register unsigned long rval,rt;
+#if	DES_DEBUG
+	printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
+		r,
+		subkey[0], subkey[1], subkey[2],
+		subkey[3], subkey[4], subkey[5],
+		subkey[6], subkey[7]);
+#endif
+	/* Run E(R) ^ K through the combined S & P boxes
+	 * This code takes advantage of a convenient regularity in
+	 * E, namely that each group of 6 bits in E(R) feeding
+	 * a single S-box is a contiguous segment of R.
+	 */
+	rt = (r >> 1) | ((r & 1) ? 0x80000000 : 0);
+	rval = 0;
+	rval |= sp[0][((rt >> 26) ^ *subkey++) & 0x3f];
+	rval |= sp[1][((rt >> 22) ^ *subkey++) & 0x3f];
+	rval |= sp[2][((rt >> 18) ^ *subkey++) & 0x3f];
+	rval |= sp[3][((rt >> 14) ^ *subkey++) & 0x3f];
+	rval |= sp[4][((rt >> 10) ^ *subkey++) & 0x3f];
+	rval |= sp[5][((rt >> 6) ^ *subkey++) & 0x3f];
+	rval |= sp[6][((rt >> 2) ^ *subkey++) & 0x3f];
+	rt = (r << 1) | ((r & 0x80000000) ? 1 : 0);
+	rval |= sp[7][(rt ^ *subkey) & 0x3f];
+#if	DES_DEBUG
+	printf(" %08lx\n",rval);
+#endif
+	return rval;
+}
+
+/* Do one DES cipher round */
+static void round(desInst dinst, int num, unsigned long int *block) {
+				/* i.e. the num-th one	 */
+
+    /* The rounds are numbered from 0 to 15. On even rounds
+       * the right half is fed to f() and the result exclusive-ORs
+       * the left half; on odd rounds the reverse is done.
+       */
+    if(num & 1){
+        block[1] ^= f(block[0],dinst->kn[num]);
+    } else {
+        block[0] ^= f(block[1],dinst->kn[num]);
+    }
+}
+
+/* Permute inblock with perm */
+static void permute(char *inblock, char perm[16][16][8], char *outblock) {
+    /* result into outblock,64 bits */
+    /* 2K bytes defining perm. */
+    register int i,j;
+    register char *ib, *ob;		/* ptr to input or output block */
+    register char *p, *q;
+
+    if(perm == NULL){
+        /* No permutation, just copy */
+        for(i=8; i!=0; i--)
+            *outblock++ = *inblock++;
+        return;
+    }
+    /* Clear output block	 */
+    for (i=8, ob = outblock; i != 0; i--)
+        *ob++ = 0;
+
+    ib = inblock;
+    for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
+        ob = outblock;
+        p = perm[j][(*ib >> 4) & 017];
+        q = perm[j + 1][*ib & 017];
+        for (i = 8; i != 0; i--){   /* and each output byte */
+            *ob++ |= *p++ | *q++;	/* OR the masks together*/
+        }
+    }
+}
+/* In-place encryption of 64-bit block */
+void endes(desInst dinst, char *block) {
+	register int i;
+	unsigned long work[2]; 		/* Working data storage */
+	long tmp;
+
+	permute(block,iperm,(char *)work);	/* Initial Permutation */
+#ifdef __LITTLE_ENDIAN__
+	work[0] = byteswap(work[0]);
+	work[1] = byteswap(work[1]);
+#endif
+
+	/* Do the 16 rounds */
+	for (i=0; i<16; i++)
+		round(dinst,i,work);
+
+	/* Left/right half swap */
+	tmp = work[0];
+	work[0] = work[1];
+	work[1] = tmp;
+
+#ifdef __LITTLE_ENDIAN__
+	work[0] = byteswap(work[0]);
+	work[1] = byteswap(work[1]);
+#endif
+	permute((char *)work,fperm,block);	/* Inverse initial permutation */
+}
+/* In-place decryption of 64-bit block */
+void dedes(desInst dinst, char *block) {
+	register int i;
+	unsigned long work[2];	/* Working data storage */
+	long tmp;
+
+	permute(block,iperm,(char *)work);	/* Initial permutation */
+
+#ifdef __LITTLE_ENDIAN__
+	work[0] = byteswap(work[0]);
+	work[1] = byteswap(work[1]);
+#endif
+
+	/* Left/right half swap */
+	tmp = work[0];
+	work[0] = work[1];
+	work[1] = tmp;
+
+	/* Do the 16 rounds in reverse order */
+	for (i=15; i >= 0; i--)
+		round(dinst,i,work);
+
+#ifdef __LITTLE_ENDIAN__
+	work[0] = byteswap(work[0]);
+	work[1] = byteswap(work[1]);
+#endif
+
+	permute((char *)work,fperm,block);	/* Inverse initial permutation */
+}
diff --git a/AppleCSP/MiscCSPAlgs/DES.h b/AppleCSP/MiscCSPAlgs/DES.h
new file mode 100644
index 00000000..570a4e70
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/DES.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * DES.h - raw DES encryption engine interface
+ *
+ * Revision History
+ * ----------------
+ * 31 Mar 97	Doug Mitchell at Apple
+ *	Put per-instance data in struct _desInst
+ * 21 Aug 96	Doug Mitchell at NeXT
+ *	Broke out from NSDESCryptor.m
+ * 22 Feb 96	Blaine Garst at NeXT
+ *	Created.
+ */
+
+#ifndef	_CK_DES_H_
+#define _CK_DES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DES_BLOCK_SIZE_BYTES		8	/* in bytes */
+#define DES_KEY_SIZE_BITS			56	/* effective key size in bits */
+#define DES_KEY_SIZE_BITS_EXTERNAL	64	/* clients actually pass in this much */
+#define DES_KEY_SIZE_BYTES_EXTERNAL	(DES_KEY_SIZE_BITS_EXTERNAL / 8)
+
+#define DES_MODE_STD	0	/* standard Data Encryption Algorithm */
+#define DES_MODE_FAST	1	/* DEA without initial and final */
+				/*    permutations for speed */
+#define DES_MODE_128	2	/* DEA without permutations and with */
+				/*    128-byte key (completely independent */
+				/*    subkeys for each round) */
+
+/*
+ * Per-instance data.
+ */
+struct _desInst {
+    	/* 8 16-bit subkeys for each of 16 rounds, initialized by setkey()
+    	 */
+	unsigned char kn[16][8];
+	int desmode;
+};
+
+typedef struct _desInst *desInst;
+
+/* Warning: desinit() is NOT thread safe. Caller must single-thread. */
+int desinit(desInst dinst, int mode);
+void dessetkey(desInst dinst, char *key);
+void endes(desInst dinst, char *block);
+void dedes(desInst dinst, char *block);
+void desdone(desInst dinst);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/*_CK_DES_H_*/
diff --git a/AppleCSP/MiscCSPAlgs/DigestContext.cpp b/AppleCSP/MiscCSPAlgs/DigestContext.cpp
new file mode 100644
index 00000000..be76041e
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/DigestContext.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+
+//
+// DigestContext.cpp 
+//
+#include "DigestContext.h"
+#include <AppleCSP/AppleCSPUtils.h>
+
+/* 
+ * Just field the expected/required calls from CSPFullPluginSession,
+ * and dispatch them to mDigest.
+ */
+void DigestContext::init(const Context &context, bool)
+{
+	mDigest.digestInit();
+}
+
+void DigestContext::update(const CssmData &data)
+{
+	mDigest.digestUpdate((const UInt8 *)data.data(), data.length());
+}
+
+void DigestContext::final(CssmData &data)
+{
+	data.length(mDigest.digestSizeInBytes());
+	mDigest.digestFinal((UInt8 *)data.data());
+}
+
+size_t DigestContext::outputSize(bool, size_t) 
+{
+	return mDigest.digestSizeInBytes();
+}
+
diff --git a/AppleCSP/MiscCSPAlgs/DigestContext.h b/AppleCSP/MiscCSPAlgs/DigestContext.h
new file mode 100644
index 00000000..5083ccb2
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/DigestContext.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+
+//
+// DigestContext.h 
+//
+
+#ifndef	_DIGEST_CONTEXT_H_
+#define _DIGEST_CONTEXT_H_
+
+#include <AppleCSP/DigestObject.h>
+#include "AppleCSPContext.h"
+#include <Security/utilities.h>
+
+/*
+ * This is just a shim to give AppleCSPContext functionality to a 
+ * DigestObject subclass (a reference to which is passed to our constructor).
+ */
+class DigestContext : public AppleCSPContext  {
+public:
+	DigestContext(
+		AppleCSPSession &session,
+		DigestObject &digest) : 
+			AppleCSPContext(session), mDigest(digest) { }
+	~DigestContext() { delete &mDigest; }
+	
+	void init(const Context &context, bool);
+	void update(const CssmData &data);
+	void final(CssmData &data);
+	size_t outputSize(bool, size_t);
+
+private:
+	DigestObject	&mDigest;
+};
+
+#endif	/* _CRYPTKIT_DIGEST_CONTEXT_H_ */
diff --git a/AppleCSP/MiscCSPAlgs/MD2Object.cpp b/AppleCSP/MiscCSPAlgs/MD2Object.cpp
new file mode 100644
index 00000000..0042b369
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/MD2Object.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+ 
+/*
+ * MD2Object.cpp
+ */
+#include "MD2Object.h"
+#include <stdexcept>
+#include <string.h>
+
+void MD2Object::digestInit()
+{
+	setIsDone(false);
+	MD2_Init(&mCtx);
+}
+
+void MD2Object::digestUpdate(
+	const void 	*data, 
+	size_t 		len)
+{
+	if(isDone()) {
+		throw std::runtime_error("MD2 digestUpdate after final");
+	}
+	MD2_Update(&mCtx, (unsigned char *)data, len);
+}
+
+void MD2Object::digestFinal(
+	void 		*digest)
+{
+	if(isDone()) {
+		throw std::runtime_error("MD2 digestFinal after final");
+	}
+	MD2_Final((unsigned char *)digest, &mCtx);
+	setIsDone(true);
+}
+
+UInt32 MD2Object::digestSizeInBytes() const
+{
+	return MD2_DIGEST_LENGTH;
+}
+
diff --git a/AppleCSP/MiscCSPAlgs/MD2Object.h b/AppleCSP/MiscCSPAlgs/MD2Object.h
new file mode 100644
index 00000000..a70d7cab
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/MD2Object.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * MD2Object.h - MD2 digest object
+ */
+
+#ifndef	_MD2_OBJECT_H_
+#define _MD2_OBJECT_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <AppleCSP/DigestObject.h>
+#include <openssl/md2.h>
+
+class MD2Object : public DigestObject
+{
+public:
+	MD2Object() { }
+	virtual ~MD2Object() { };
+	virtual void digestInit();
+	virtual void digestUpdate(
+		const void 	*data, 
+		size_t 		len);
+	virtual void digestFinal(
+		void 		*digest);
+	virtual size_t digestSizeInBytes() const;
+private:
+	MD2_CTX 		mCtx;
+};
+
+#endif	/* _MD2_OBJECT_H_ */
diff --git a/AppleCSP/MiscCSPAlgs/MD5.c b/AppleCSP/MiscCSPAlgs/MD5.c
new file mode 100644
index 00000000..baf80ad7
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/MD5.c
@@ -0,0 +1,365 @@
+/*
+	File:		MD5.c
+
+	Written by:	Colin Plumb
+
+	Copyright:	Copyright 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		 <7>	10/06/98	ap		Changed to compile with C++.
+
+	To Do:
+*/
+
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * MD5.c
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/*
+ * Revision History
+ * ----------------
+ * 06 Feb 1997	Doug Mitchell at Apple
+ *	Fixed endian-dependent cast in MD5Final()
+ *	Made byteReverse() tolerant of platform-dependent alignment
+ *		restrictions
+ */
+
+#include "MD5.h"
+#include "platform.h"
+#include <stdlib.h>
+
+static inline void intToByteRep(int i, unsigned char *buf)
+{
+	*buf++ = (unsigned char)((i >> 24) & 0xff);
+	*buf++ = (unsigned char)((i >> 16) & 0xff);
+	*buf++ = (unsigned char)((i >> 8)  & 0xff);
+	*buf   = (unsigned char)(i & 0xff);
+}
+
+#define MD5_DEBUG	0
+
+#if	MD5_DEBUG
+static inline void dumpCtx(struct MD5Context *ctx, char *label)
+{
+	int i;
+
+	printf("%s\n", label);
+	printf("buf = ");
+	for(i=0; i<4; i++) {
+		printf("%x:", ctx->buf[i]);
+	}
+	printf("\nbits: %d:%d\n", ctx->bits[0], ctx->bits[1]);
+	printf("in[]:\n   ");
+	for(i=0; i<64; i++) {
+		printf("%02x:", ctx->in[i]);
+		if((i % 16) == 15) {
+			printf("\n   ");
+		}
+	}
+	printf("\n");
+}
+#else	// MD5_DEBUG
+#define dumpCtx(ctx, label)
+#endif	// MD5_DEBUG
+
+static void MD5Transform(uint32 buf[4], uint32 const in[16]);
+
+#if __LITTLE_ENDIAN__
+#define byteReverse(buf, len)	/* Nothing */
+#else
+static void byteReverse(unsigned char *buf, unsigned longs);
+
+#ifndef ASM_MD5
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+#if		old_way
+    /*
+     * this code is NOT harmless on big-endian machine which require
+     * natural alignment. 
+     */
+    uint32 t;
+    do {
+	t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+	    ((unsigned) buf[1] << 8 | buf[0]);
+	*(uint32 *) buf = t;
+	buf += 4;
+    } while (--longs);
+#else	// new_way
+
+    unsigned char t;
+    do {
+        t = buf[0];
+	buf[0] = buf[3];
+	buf[3] = t;
+        t = buf[1];
+	buf[1] = buf[2];
+	buf[2] = t;
+	buf += 4;
+    } while (--longs);
+#endif // old_way
+}
+#endif // ASM_MD5
+#endif // __LITTLE_ENDIAN__
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(struct MD5Context *ctx)
+{
+    ctx->buf[0] = 0x67452301;
+    ctx->buf[1] = 0xefcdab89;
+    ctx->buf[2] = 0x98badcfe;
+    ctx->buf[3] = 0x10325476;
+
+    ctx->bits[0] = 0;
+    ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+{
+    uint32 t;
+
+    dumpCtx(ctx, "MD5.c update top");
+    /* Update bitcount */
+
+    t = ctx->bits[0];
+    if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+	ctx->bits[1]++;		/* Carry from low to high */
+    ctx->bits[1] += len >> 29;
+
+    t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
+
+    /* Handle any leading odd-sized chunks */
+
+    if (t) {
+	unsigned char *p = (unsigned char *) ctx->in + t;
+
+	t = 64 - t;
+	if (len < t) {
+	    memcpy(p, buf, len);
+	    return;
+	}
+	memcpy(p, buf, t);
+	byteReverse(ctx->in, 16);
+	MD5Transform(ctx->buf, (uint32 *) ctx->in);
+	dumpCtx(ctx, "update - return from transform (1)");
+	buf += t;
+	len -= t;
+    }
+    /* Process data in 64-byte chunks */
+
+    while (len >= 64) {
+	memcpy(ctx->in, buf, 64);
+	byteReverse(ctx->in, 16);
+	MD5Transform(ctx->buf, (uint32 *) ctx->in);
+	dumpCtx(ctx, "update - return from transform (2)");
+	buf += 64;
+	len -= 64;
+    }
+
+    /* Handle any remaining bytes of data. */
+
+    memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(unsigned char *digest, struct MD5Context *ctx)
+{
+    unsigned count;
+    unsigned char *p;
+
+    dumpCtx(ctx, "final top");
+
+    /* Compute number of bytes mod 64 */
+    count = (ctx->bits[0] >> 3) & 0x3F;
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    p = ctx->in + count;
+    *p++ = 0x80;
+    #if	MD5_DEBUG
+    printf("in[%d] = %x\n", count, ctx->in[count]);
+    #endif
+    /* Bytes of padding needed to make 64 bytes */
+    count = 64 - 1 - count;
+
+    /* Pad out to 56 mod 64 */
+    dumpCtx(ctx, "final, before pad");
+    if (count < 8) {
+	/* Two lots of padding:  Pad the first block to 64 bytes */
+	bzero(p, count);
+	byteReverse(ctx->in, 16);
+	MD5Transform(ctx->buf, (uint32 *) ctx->in);
+
+	/* Now fill the next block with 56 bytes */
+	bzero(ctx->in, 56);
+    } else {
+	/* Pad block to 56 bytes */
+	bzero(p, count - 8);
+    }
+    byteReverse(ctx->in, 14);
+
+    /* Append length in bits and transform */
+    #if		old_way
+     /*
+     * On a little endian machine, this writes the l.s. byte of
+     * the bit count to ctx->in[56] and the m.s byte of the bit count to
+     * ctx->in[63].
+     */
+    ((uint32 *) ctx->in)[14] = ctx->bits[0];
+    ((uint32 *) ctx->in)[15] = ctx->bits[1];
+    #else	// new_way
+    intToByteRep(ctx->bits[0], &ctx->in[56]);
+    intToByteRep(ctx->bits[1], &ctx->in[60]);
+    #endif	// new_way
+
+    dumpCtx(ctx, "last transform");
+    MD5Transform(ctx->buf, (uint32 *) ctx->in);
+    byteReverse((unsigned char *) ctx->buf, 4);
+    memcpy(digest, ctx->buf, MD5_DIGEST_SIZE);
+    dumpCtx(ctx, "final end");
+
+    bzero(ctx, sizeof(ctx));	/* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void MD5Transform(uint32 buf[4], uint32 const in[16])
+{
+    register uint32 a, b, c, d;
+
+    a = buf[0];
+    b = buf[1];
+    c = buf[2];
+    d = buf[3];
+
+    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+    buf[0] += a;
+    buf[1] += b;
+    buf[2] += c;
+    buf[3] += d;
+}
+
+#endif // ASM_MD5
diff --git a/AppleCSP/MiscCSPAlgs/MD5.h b/AppleCSP/MiscCSPAlgs/MD5.h
new file mode 100644
index 00000000..04e1f5f7
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/MD5.h
@@ -0,0 +1,67 @@
+/*
+	File:		MD5.h
+
+	Written by:	Colin Plumb
+
+	Copyright:	Copyright 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		 <8>	10/06/98	ap		Changed to compile with C++.
+
+	To Do:
+*/
+
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * MD5.h
+ * derived and used without need for permission from public domain source
+ */
+
+#ifndef	_CK_MD5_H_
+#define _CK_MD5_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __alpha
+typedef unsigned int uint32;
+#elif defined (macintosh)
+typedef unsigned int uint32;
+#else
+#include <Security/cssmconfig.h>
+//typedef unsigned long uint32;
+#endif
+
+struct MD5Context {
+	uint32 buf[4];
+	uint32 bits[2];			// bits[0] is low 32 bits of bit count
+	unsigned char in[64];
+};
+
+#define MD5_DIGEST_SIZE		16	/* in bytes */
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, unsigned char const *buf,
+	       unsigned len);
+void MD5Final(unsigned char *digest, struct MD5Context *context);
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+typedef struct MD5Context MD5_CTX;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/*_CK_MD5_H_*/
diff --git a/AppleCSP/MiscCSPAlgs/MacContext.cpp b/AppleCSP/MiscCSPAlgs/MacContext.cpp
new file mode 100644
index 00000000..2d41ae2d
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/MacContext.cpp
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+
+/*
+ * MacContext.cpp - AppleCSPContext for HMACSHA1
+ */
+
+#include "MacContext.h"
+#include <PBKDF2/HMACSHA1.h>
+#include <Security/cssmerr.h>
+#include <Security/utilities.h>
+#ifdef	CRYPTKIT_CSP_ENABLE
+#include <CryptKit/HmacSha1Legacy.h>
+#endif	/* CRYPTKIT_CSP_ENABLE */
+
+MacContext::~MacContext()
+{
+	if(mHmac) {
+		hmacFree(mHmac);
+		mHmac = NULL;
+	}
+}
+	
+/* called out from CSPFullPluginSession....
+ * both generate and verify: */
+void MacContext::init(const Context &context, bool isSigning)
+{
+	if(mHmac == NULL) {
+		mHmac = hmacAlloc();
+		if(mHmac == NULL) {
+			CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+		}
+	}
+	
+	/* obtain key from context */
+	UInt32 		keyLen;
+	UInt8 		*keyData 	= NULL;
+	
+	symmetricKeyBits(context, CSSM_ALGID_SHA1HMAC, 
+		isSigning ? CSSM_KEYUSE_SIGN : CSSM_KEYUSE_VERIFY,
+		keyData, keyLen);
+	if((keyLen < HMAC_MIN_KEY_SIZE) || (keyLen > HMAC_MAX_KEY_SIZE)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	CSSM_RETURN crtn = hmacInit(mHmac, keyData, keyLen);
+	if(crtn) {
+		CssmError::throwMe(crtn);
+	}
+}
+
+void MacContext::update(const CssmData &data)
+{
+	CSSM_RETURN crtn = hmacUpdate(mHmac,
+		data.data(),
+		data.length());
+	if(crtn) {
+		CssmError::throwMe(crtn);
+	}
+}
+
+/* generate only */
+void MacContext::final(CssmData &out)
+{
+	if(out.length() < kHMACSHA1DigestSize) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	hmacFinal(mHmac, out.data());
+}
+
+/* verify only */
+void MacContext::final(const CssmData &in)
+{
+	unsigned char mac[kHMACSHA1DigestSize];
+	hmacFinal(mHmac, mac);
+	if(memcmp(mac, in.data(), kHMACSHA1DigestSize)) {
+		CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
+	}
+}
+
+size_t MacContext::outputSize(bool final, size_t inSize)
+{
+	return kHMACSHA1DigestSize;
+}
+
+#ifdef 	CRYPTKIT_CSP_ENABLE
+
+MacLegacyContext::~MacLegacyContext()
+{
+	if(mHmac) {
+		hmacLegacyFree(mHmac);
+		mHmac = NULL;
+	}
+}
+	
+/* called out from CSPFullPluginSession....
+ * both generate and verify: */
+void MacLegacyContext::init(const Context &context, bool isSigning)
+{
+	if(mHmac == NULL) {
+		mHmac = hmacLegacyAlloc();
+		if(mHmac == NULL) {
+			CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+		}
+	}
+	
+	/* obtain key from context */
+	UInt32 		keyLen;
+	UInt8 		*keyData 	= NULL;
+	
+	/* FIXME - this may require a different key alg */
+	symmetricKeyBits(context, CSSM_ALGID_SHA1HMAC, 
+		isSigning ? CSSM_KEYUSE_SIGN : CSSM_KEYUSE_VERIFY,
+		keyData, keyLen);
+	if((keyLen < HMAC_MIN_KEY_SIZE) || (keyLen > HMAC_MAX_KEY_SIZE)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	OSStatus ortn = hmacLegacyInit(mHmac, keyData, keyLen);
+	if(ortn) {
+		MacOSError::throwMe(ortn);
+	}
+}
+
+void MacLegacyContext::update(const CssmData &data)
+{
+	OSStatus ortn = hmacLegacyUpdate(mHmac,
+		data.data(),
+		data.length());
+	if(ortn) {
+		MacOSError::throwMe(ortn);
+	}
+}
+
+/* generate only */
+void MacLegacyContext::final(CssmData &out)
+{
+	if(out.length() < kHMACSHA1DigestSize) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	hmacLegacyFinal(mHmac, out.data());
+}
+
+/* verify only */
+void MacLegacyContext::final(const CssmData &in)
+{
+	unsigned char mac[kHMACSHA1DigestSize];
+	hmacLegacyFinal(mHmac, mac);
+	if(memcmp(mac, in.data(), kHMACSHA1DigestSize)) {
+		CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
+	}
+}
+
+size_t MacLegacyContext::outputSize(bool final, size_t inSize)
+{
+	return kHMACSHA1DigestSize;
+}
+
+#endif	/* CRYPTKIT_CSP_ENABLE */
diff --git a/AppleCSP/MiscCSPAlgs/MacContext.h b/AppleCSP/MiscCSPAlgs/MacContext.h
new file mode 100644
index 00000000..4825e255
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/MacContext.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+/*
+ * MacContext.h - AppleCSPContext for HMACSHA1
+ */
+
+#ifndef	_MAC_CONTEXT_H_
+#define _MAC_CONTEXT_H_
+
+#include <AppleCSP/AppleCSPContext.h>
+#include <PBKDF2/HMACSHA1.h>
+
+#define HMAC_MIN_KEY_SIZE		20		/* in bytes */
+#define HMAC_MAX_KEY_SIZE		2048
+
+
+class MacContext : public AppleCSPContext  {
+public:
+	MacContext(
+		AppleCSPSession &session) : 
+			AppleCSPContext(session), mHmac(NULL) { }
+	~MacContext();
+	
+	/* called out from CSPFullPluginSession....
+	 * both generate and verify: */
+	void init(const Context &context, bool isSigning);
+	void update(const CssmData &data);
+	
+	/* generate only */
+	void final(CssmData &out);	
+	
+	/* verify only */
+	void final(const CssmData &in);	
+
+	size_t outputSize(bool final, size_t inSize);
+
+private:
+	hmacContextRef	mHmac;
+};
+
+#ifdef	CRYPTKIT_CSP_ENABLE
+#include <CryptKit/HmacSha1Legacy.h>
+
+/* This version is bug-for-bug compatible with a legacy implementation */
+
+class MacLegacyContext : public AppleCSPContext  {
+public:
+	MacLegacyContext(
+		AppleCSPSession &session) : 
+			AppleCSPContext(session), mHmac(NULL) { }
+	~MacLegacyContext();
+	
+	/* called out from CSPFullPluginSession....
+	 * both generate and verify: */
+	void init(const Context &context, bool isSigning);
+	void update(const CssmData &data);
+	
+	/* generate only */
+	void final(CssmData &out);	
+	
+	/* verify only */
+	void final(const CssmData &in);	
+
+	size_t outputSize(bool final, size_t inSize);
+
+private:
+	hmacLegacyContextRef	mHmac;
+};
+
+#endif	/* CRYPTKIT_CSP_ENABLE */
+
+#endif	/* _MAC_CONTEXT_H_ */
diff --git a/AppleCSP/MiscCSPAlgs/SHA1.c b/AppleCSP/MiscCSPAlgs/SHA1.c
new file mode 100644
index 00000000..ef94aa23
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/SHA1.c
@@ -0,0 +1,168 @@
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * SHA1.c - generic, portable SHA-1 hash object
+ *
+ * Revision History
+ * ----------------
+ * 10/06/98		ap
+ *	Changed to compile with C++.
+ * 07 Jan 1998	Doug Mitchell at Apple
+ *	Created.
+ */
+
+#include "SHA1.h"
+#include "SHA1_priv.h"
+#include "platform.h"
+
+/* for now map falloc to malloc, FIXME */
+#include <stdlib.h>
+#define fmalloc(s)	malloc(s)
+#define ffree(p)	free(p)
+
+/*
+ * Private data for this object. A sha1Obj handle is cast to a pointer
+ * to one of these.
+ */
+typedef struct {
+	SHS_INFO 	context;
+	int 		isDone;
+
+	/*
+	 * For storing partial blocks
+	 */
+	BYTE		dataBuf[SHS_BLOCKSIZE];
+	unsigned	bufBytes;		// valid bytes in dataBuf[p]
+} sha1Inst;
+
+/*
+ * Alloc and init an empty sha1 object.
+ */
+sha1Obj sha1Alloc(void)
+{
+	sha1Inst *sinst;
+
+	sinst = (sha1Inst *)fmalloc(sizeof(sha1Inst));
+	if(sinst == NULL) {
+		return NULL;
+	}
+	shsInit(&sinst->context);
+	sha1Reinit((sha1Obj)sinst);
+	return (sha1Obj)sinst;
+}
+
+/*
+ * Reusable init function.
+ */
+void sha1Reinit(sha1Obj sha1)
+{
+	sha1Inst *sinst = (sha1Inst *) sha1;
+
+	shsInit(&sinst->context);
+	sinst->isDone = 0;
+	sinst->bufBytes = 0;
+}
+
+/*
+ * Free an sha1 object.
+ */
+void sha1Free(sha1Obj sha1)
+{
+	sha1Inst *sinst = (sha1Inst *) sha1;
+
+	memset(sha1, 0, sizeof(sha1Inst));
+	ffree(sinst);
+}
+
+/*
+ * Add some data to the sha1 object.
+ */
+void sha1AddData(sha1Obj sha1,
+	const unsigned char *data,
+	unsigned dataLen)
+{
+	sha1Inst *sinst = (sha1Inst *) sha1;
+	unsigned toMove;
+	unsigned blocks;
+
+	if(sinst->isDone) {
+		/*
+		 * Log some kind of error here...
+		 */
+		return;
+	}
+
+	/*
+	 * First deal with partial buffered block
+	 */
+	if(sinst->bufBytes != 0) {
+		toMove = SHS_BLOCKSIZE - sinst->bufBytes;
+		if(toMove > dataLen) {
+			toMove = dataLen;
+		}
+		memmove(sinst->dataBuf+sinst->bufBytes, data, toMove);
+		data += toMove;
+		dataLen -= toMove;
+		sinst->bufBytes += toMove;
+		if(sinst->bufBytes == SHS_BLOCKSIZE) {
+		    shsUpdate(&sinst->context, sinst->dataBuf, SHS_BLOCKSIZE);
+		    sinst->bufBytes = 0;
+		}
+	}
+
+	/*
+	 * Now the bulk of the data, in a multiple of full blocks
+	 */
+	blocks = dataLen / SHS_BLOCKSIZE;
+	toMove = blocks * SHS_BLOCKSIZE;
+	if(toMove != 0) {
+	    shsUpdate(&sinst->context, data, toMove);
+	    data += toMove;
+	    dataLen -= toMove;
+	}
+
+	/*
+	 * Store any remainder in dataBuf
+	 */
+	if(dataLen != 0) {
+		memmove(sinst->dataBuf, data, dataLen);
+		sinst->bufBytes = dataLen;
+	}
+}
+
+/*
+ * Obtain a pointer to completed message digest, and the length of the digest.
+ */
+unsigned char *sha1Digest(sha1Obj sha1)
+{
+	sha1Inst *sinst = (sha1Inst *) sha1;
+
+	if(!sinst->isDone) {
+		/*
+		 * Deal with partial resid block
+		 */
+		if(sinst->bufBytes != 0) {
+			shsUpdate(&sinst->context, sinst->dataBuf,
+				sinst->bufBytes);
+			sinst->bufBytes = 0;
+		}
+		shsFinal(&sinst->context);
+		sinst->isDone = 1;
+	}
+	/*
+	 * FIXME - should do explicit conversion to char array....?
+	 */
+	return (unsigned char *)sinst->context.digest;
+}
+
+unsigned sha1DigestLen(void)
+{
+	return SHS_DIGESTSIZE;
+}
diff --git a/AppleCSP/MiscCSPAlgs/SHA1.h b/AppleCSP/MiscCSPAlgs/SHA1.h
new file mode 100644
index 00000000..823ff6b5
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/SHA1.h
@@ -0,0 +1,69 @@
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * SHA1.h - generic, portable SHA-1 hash object
+ *
+ * Revision History
+ * ----------------
+ * 05 Jan 1998	Doug Mitchell at Apple
+ *	Created.
+ */
+
+#ifndef	_CK_SHA1_H_
+#define _CK_SHA1_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Opaque sha1 object handle.
+ */
+typedef void *sha1Obj;
+
+/*
+ * Alloc and init an empty sha1 object.
+ */
+sha1Obj sha1Alloc(void);
+
+/*
+ * reinitialize an sha1 object for reuse.
+ */
+void sha1Reinit(sha1Obj sha1);
+
+/*
+ * Free an sha1 object.
+ */
+void sha1Free(sha1Obj sha1);
+
+/*
+ * Add some data to the sha1 object.
+ */
+void sha1AddData(sha1Obj sha1,
+	const unsigned char *data,
+	unsigned dataLen);
+
+/*
+ * Obtain a pointer to completed message digest. This disables further calls
+ * to sha1AddData(). This pointer is NOT malloc'd; the associated data
+ * persists only as long as this object does.
+ */
+unsigned char *sha1Digest(sha1Obj sha1);
+
+/*
+ * Obtain the length of the message digest.
+ */
+unsigned sha1DigestLen(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/*_CK_SHA1_H_*/
diff --git a/AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.cpp b/AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.cpp
new file mode 100644
index 00000000..978d0099
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * DigestObject.cpp - generic C++ implementations of SHA1 and MD5. 
+ *
+ * Created 2/19/2001 by dmitch.
+ */
+
+#include "SHA1_MD5_Object.h"
+#include <stdexcept>
+#include <string.h>
+
+/***
+ *** MD5
+ ***/
+void MD5Object::digestInit()
+{
+	mIsDone = false;
+	MD5Init(&mCtx);
+}
+
+void MD5Object::digestUpdate(
+	const void 	*data, 
+	size_t 		len)
+{
+	if(mIsDone) {
+		throw std::runtime_error("MD5 digestUpdate after final");
+	}
+	MD5Update(&mCtx, (unsigned char *)data, len);
+}
+
+void MD5Object::digestFinal(
+	void 		*digest)
+{
+	if(mIsDone) {
+		throw std::runtime_error("MD5 digestFinal after final");
+	}
+	MD5Final((unsigned char *)digest, &mCtx);
+	mIsDone = true;
+}
+
+UInt32 MD5Object::digestSizeInBytes() const
+{
+	return MD5_DIGEST_SIZE;
+}
+
+/***
+ *** SHA1
+ ***/
+void SHA1Object::digestInit()
+{
+	mIsDone = false;
+	shsInit(&mCtx);
+	mBufferCount = 0;
+}
+
+void SHA1Object::digestUpdate(
+	const void 	*data, 
+	size_t 		len)
+{
+	size_t cnt;
+	uint8 *uData = (uint8 *)data;
+	
+	if(mIsDone) { 
+		throw std::runtime_error("SHA1 digestUpdate after final");
+	}
+
+	// deal with miniscule input leaving still less than one block
+	if (mBufferCount + len < SHS_BLOCKSIZE) {
+		memcpy(mBuffer + mBufferCount, uData, len);
+		mBufferCount += len;
+		return;
+	}
+	
+	// fill possible partial existing buffer and process
+	if (mBufferCount > 0) {	
+		cnt = SHS_BLOCKSIZE - mBufferCount;
+		memcpy(mBuffer + mBufferCount, uData, cnt);
+		shsUpdate(&mCtx, mBuffer, SHS_BLOCKSIZE);
+		uData += cnt;
+		len   -= cnt;
+	}
+	
+	// process remaining whole buffer multiples
+	UInt32 blocks = len / SHS_BLOCKSIZE;
+	if(blocks) {
+		cnt = blocks * SHS_BLOCKSIZE;
+		shsUpdate(&mCtx, uData, cnt);
+		uData += cnt;
+		len   -= cnt;
+	}
+	
+	// keep remainder
+	mBufferCount = len;
+	if (len > 0) {
+		memcpy(mBuffer, uData, len);
+	}
+}
+
+void SHA1Object::digestFinal(
+	void 		*digest)
+{
+	if(mIsDone) {
+		throw std::runtime_error("SHA1 digestFinal after final");
+	}
+	if (mBufferCount > 0) {
+		shsUpdate(&mCtx, mBuffer, mBufferCount);
+	}
+	shsFinal(&mCtx);
+	memcpy(digest, mCtx.digest, SHS_DIGESTSIZE);
+	mIsDone = true;
+}
+
+UInt32 SHA1Object::digestSizeInBytes() const
+{
+	return SHS_DIGESTSIZE;
+}
+
diff --git a/AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.h b/AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.h
new file mode 100644
index 00000000..458cb127
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/SHA1_MD5_Object.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * SHA1_MD5_Object.h - SHA1, MD5 digest objects 
+ *
+ * Created 2/19/2001 by dmitch.
+ */
+
+#ifndef	_SHA1_MD5_OBJECT_H_
+#define _SHA1_MD5_OBJECT_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <AppleCSP/DigestObject.h>
+#include <MiscCSPAlgs/MD5.h>
+#include <CryptKit/SHA1_priv.h>
+
+class SHA1Object : public DigestObject
+{
+public:
+	SHA1Object() { }
+	virtual ~SHA1Object() { };
+	virtual void digestInit();
+	virtual void digestUpdate(
+		const void 	*data, 
+		size_t 		len);
+	virtual void digestFinal(
+		void 		*digest);
+	virtual size_t digestSizeInBytes() const;
+private:
+	SHS_INFO 		mCtx;
+	UInt8 			mBuffer[SHS_BLOCKSIZE];
+	size_t 			mBufferCount;
+
+};
+
+class MD5Object : public DigestObject
+{
+public:
+	MD5Object() { }
+	virtual ~MD5Object() { }
+	virtual void digestInit();
+	virtual void digestUpdate(
+		const void 	*data, 
+		size_t 		len);
+	virtual void digestFinal(
+		void 		*digest);
+	virtual size_t digestSizeInBytes() const;
+private:
+	MD5Context mCtx;
+};
+
+#endif	/* _SHA1_MD5_OBJECT_H_ */
diff --git a/AppleCSP/MiscCSPAlgs/SHA1_priv.c b/AppleCSP/MiscCSPAlgs/SHA1_priv.c
new file mode 100644
index 00000000..e8279988
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/SHA1_priv.c
@@ -0,0 +1,316 @@
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * SHA1_priv.c - low-level SHA-1 hash algorithm.
+ *
+ * Revision History
+ * ----------------
+ * 05 Jan 1998	Doug Mitchell at Apple
+ *	Created, based on source by Peter C. Gutmann.
+ *	Mods: made reentrant, added NIST fix to expand(), eliminated
+ *	unnecessary copy to local W[] array.
+ */
+
+
+/* NIST proposed Secure Hash Standard.
+
+   Written 2 September 1992, Peter C. Gutmann.
+   This implementation placed in the public domain.
+
+   Comments to pgut1@cs.aukuni.ac.nz */
+
+
+#include "SHA1_priv.h"
+#include "platform.h"
+#include <string.h>
+
+/* The SHS f()-functions */
+
+#define f1(x,y,z)   ( ( x & y ) | ( ~x & z ) )              /* Rounds  0-19 */
+#define f2(x,y,z)   ( x ^ y ^ z )                           /* Rounds 20-39 */
+#define f3(x,y,z)   ( ( x & y ) | ( x & z ) | ( y & z ) )   /* Rounds 40-59 */
+#define f4(x,y,z)   ( x ^ y ^ z )                           /* Rounds 60-79 */
+
+/* The SHS Mysterious Constants */
+
+#define K1  0x5A827999L     /* Rounds  0-19 */
+#define K2  0x6ED9EBA1L     /* Rounds 20-39 */
+#define K3  0x8F1BBCDCL     /* Rounds 40-59 */
+#define K4  0xCA62C1D6L     /* Rounds 60-79 */
+
+/* SHS initial values */
+
+#define h0init  0x67452301L
+#define h1init  0xEFCDAB89L
+#define h2init  0x98BADCFEL
+#define h3init  0x10325476L
+#define h4init  0xC3D2E1F0L
+
+/* 32-bit rotate - kludged with shifts */
+
+#define S(n,X)  ( ( X << n ) | ( X >> ( 32 - n ) ) )
+
+/* The initial expanding function */
+
+/*
+ * 06 Jan 1998. Added left circular shift per NIST FIPS-180-1 (at
+ * http://www.nist.gov/itl/div897/pubs/fip180-1.htm). Also see
+ * B. Schneier, Applied Cryptography, Second Edition, section 18.7
+ * for info on this addenda to the original NIST spec.
+ */
+#define expand(count) {	\
+    W[count] = W[count - 3] ^ W[count - 8] ^ W[count - 14] ^ W[count - 16]; \
+    W[count] = S(1, W[count]); \
+}
+
+/* The four SHS sub-rounds */
+
+#define subRound1(count)    \
+    { \
+    temp = S( 5, A ) + f1( B, C, D ) + E + W[ count ] + K1; \
+    E = D; \
+    D = C; \
+    C = S( 30, B ); \
+    B = A; \
+    A = temp; \
+    }
+
+#define subRound2(count)    \
+    { \
+    temp = S( 5, A ) + f2( B, C, D ) + E + W[ count ] + K2; \
+    E = D; \
+    D = C; \
+    C = S( 30, B ); \
+    B = A; \
+    A = temp; \
+    }
+
+#define subRound3(count)    \
+    { \
+    temp = S( 5, A ) + f3( B, C, D ) + E + W[ count ] + K3; \
+    E = D; \
+    D = C; \
+    C = S( 30, B ); \
+    B = A; \
+    A = temp; \
+    }
+
+#define subRound4(count)    \
+    { \
+    temp = S( 5, A ) + f4( B, C, D ) + E + W[ count ] + K4; \
+    E = D; \
+    D = C; \
+    C = S( 30, B ); \
+    B = A; \
+    A = temp; \
+    }
+
+/* Initialize the SHS values */
+
+void shsInit( SHS_INFO *shsInfo )
+    {
+    /* Set the h-vars to their initial values */
+    shsInfo->digest[ 0 ] = h0init;
+    shsInfo->digest[ 1 ] = h1init;
+    shsInfo->digest[ 2 ] = h2init;
+    shsInfo->digest[ 3 ] = h3init;
+    shsInfo->digest[ 4 ] = h4init;
+
+    /* Initialise bit count */
+    shsInfo->countLo = shsInfo->countHi = 0L;
+    }
+
+/* Perform the SHS transformation.  Note that this code, like MD5, seems to
+   break some optimizing compilers - it may be necessary to split it into
+   sections, eg based on the four subrounds */
+
+static void shsTransform( SHS_INFO *shsInfo )
+{
+    LONG *W, temp;
+    LONG A, B, C, D, E;
+
+    /* Step A.  Copy the data buffer into the local work buffer. */
+    /* 07 Jan 1998, dmitch: skip this bogus move, and let the caller
+     * copy data directly into the W[] array. To minimize changes,
+     * we'll just increase the size of shsInfo->data[] and make W
+     * a pointer here.
+     */
+    W = shsInfo->data;
+
+    /* Step B.  Expand the 16 words into 64 temporary data words */
+
+    /*
+     * Note: I tried optimizing this via a for loop, and for some reason,
+     * the "optimized" version ran slower on PPC than the original
+     * unrolled version. The optimized version does run faster on i486 than
+     * the unrolled version.
+     *
+     * Similarly, the set of subRounds, below, runs slower on i486 when
+     * optimized via 4 'for' loops. The "optimized" version of that is
+     * a wash on PPC.
+     *
+     * Conclusion: leave both of 'em unrolled. We could ifdef per machine,
+     * but this would get messy once we had more than two architectures.
+     * We may want to revisit this.  --dpm
+     */
+    expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 );
+    expand( 21 ); expand( 22 ); expand( 23 ); expand( 24 ); expand( 25 );
+    expand( 26 ); expand( 27 ); expand( 28 ); expand( 29 ); expand( 30 );
+    expand( 31 ); expand( 32 ); expand( 33 ); expand( 34 ); expand( 35 );
+    expand( 36 ); expand( 37 ); expand( 38 ); expand( 39 ); expand( 40 );
+    expand( 41 ); expand( 42 ); expand( 43 ); expand( 44 ); expand( 45 );
+    expand( 46 ); expand( 47 ); expand( 48 ); expand( 49 ); expand( 50 );
+    expand( 51 ); expand( 52 ); expand( 53 ); expand( 54 ); expand( 55 );
+    expand( 56 ); expand( 57 ); expand( 58 ); expand( 59 ); expand( 60 );
+    expand( 61 ); expand( 62 ); expand( 63 ); expand( 64 ); expand( 65 );
+    expand( 66 ); expand( 67 ); expand( 68 ); expand( 69 ); expand( 70 );
+    expand( 71 ); expand( 72 ); expand( 73 ); expand( 74 ); expand( 75 );
+    expand( 76 ); expand( 77 ); expand( 78 ); expand( 79 );
+
+    /* Step C.  Set up first buffer */
+    A = shsInfo->digest[ 0 ];
+    B = shsInfo->digest[ 1 ];
+    C = shsInfo->digest[ 2 ];
+    D = shsInfo->digest[ 3 ];
+    E = shsInfo->digest[ 4 ];
+
+    /* Step D.  Serious mangling, divided into four sub-rounds */
+    subRound1( 0 ); subRound1( 1 ); subRound1( 2 ); subRound1( 3 );
+    subRound1( 4 ); subRound1( 5 ); subRound1( 6 ); subRound1( 7 );
+    subRound1( 8 ); subRound1( 9 ); subRound1( 10 ); subRound1( 11 );
+    subRound1( 12 ); subRound1( 13 ); subRound1( 14 ); subRound1( 15 );
+    subRound1( 16 ); subRound1( 17 ); subRound1( 18 ); subRound1( 19 );
+    subRound2( 20 ); subRound2( 21 ); subRound2( 22 ); subRound2( 23 );
+    subRound2( 24 ); subRound2( 25 ); subRound2( 26 ); subRound2( 27 );
+    subRound2( 28 ); subRound2( 29 ); subRound2( 30 ); subRound2( 31 );
+    subRound2( 32 ); subRound2( 33 ); subRound2( 34 ); subRound2( 35 );
+    subRound2( 36 ); subRound2( 37 ); subRound2( 38 ); subRound2( 39 );
+    subRound3( 40 ); subRound3( 41 ); subRound3( 42 ); subRound3( 43 );
+    subRound3( 44 ); subRound3( 45 ); subRound3( 46 ); subRound3( 47 );
+    subRound3( 48 ); subRound3( 49 ); subRound3( 50 ); subRound3( 51 );
+    subRound3( 52 ); subRound3( 53 ); subRound3( 54 ); subRound3( 55 );
+    subRound3( 56 ); subRound3( 57 ); subRound3( 58 ); subRound3( 59 );
+    subRound4( 60 ); subRound4( 61 ); subRound4( 62 ); subRound4( 63 );
+    subRound4( 64 ); subRound4( 65 ); subRound4( 66 ); subRound4( 67 );
+    subRound4( 68 ); subRound4( 69 ); subRound4( 70 ); subRound4( 71 );
+    subRound4( 72 ); subRound4( 73 ); subRound4( 74 ); subRound4( 75 );
+    subRound4( 76 ); subRound4( 77 ); subRound4( 78 ); subRound4( 79 );
+
+    /* Step E.  Build message digest */
+    shsInfo->digest[ 0 ] += A;
+    shsInfo->digest[ 1 ] += B;
+    shsInfo->digest[ 2 ] += C;
+    shsInfo->digest[ 3 ] += D;
+    shsInfo->digest[ 4 ] += E;
+}
+
+/* __LITTLE_ENDIAN__ is in fact #defined on OS X on  PPC.... */
+//#ifdef __LITTLE_ENDIAN__
+#if 0
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+   array of longwords.  It is possible to make the code endianness-
+   independant by fiddling around with data at the byte level, but this
+   makes for very slow code, so we rely on the user to sort out endianness
+   at compile time */
+
+static void byteReverse( buffer, byteCount )
+  LONG *buffer;
+  int byteCount;
+
+    {
+    LONG value;
+    int count;
+
+    byteCount /= sizeof( LONG );
+    for( count = 0; count < byteCount; count++ )
+	{
+	value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
+	buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
+	}
+    }
+
+#else	/* __LITTLE_ENDIAN__ */
+
+/*
+ * Nop for big-endian machines
+ */
+#define byteReverse( buffer, byteCount )
+
+#endif /* __LITTLE_ENDIAN__ */
+
+
+/* Update SHS for a block of data.  This code assumes that the buffer size
+   is a multiple of SHS_BLOCKSIZE bytes long, which makes the code a lot
+   more efficient since it does away with the need to handle partial blocks
+   between calls to shsUpdate() */
+
+void shsUpdate(
+  SHS_INFO *shsInfo,
+  const BYTE *buffer,
+  int count)
+
+    {
+    /* Update bitcount */
+    if( ( shsInfo->countLo + ( ( LONG ) count << 3 ) ) < shsInfo->countLo )
+	shsInfo->countHi++; /* Carry from low to high bitCount */
+    shsInfo->countLo += ( ( LONG ) count << 3 );
+    shsInfo->countHi += ( ( LONG ) count >> 29 );
+
+    /* Process data in SHS_BLOCKSIZE chunks */
+    while( count >= SHS_BLOCKSIZE )
+	{
+	memcpy( shsInfo->data, buffer, SHS_BLOCKSIZE );
+	byteReverse( shsInfo->data, SHS_BLOCKSIZE );
+	shsTransform( shsInfo );
+	buffer += SHS_BLOCKSIZE;
+	count -= SHS_BLOCKSIZE;
+	}
+
+    /* Handle any remaining bytes of data.  This should only happen once
+       on the final lot of data */
+    memcpy( shsInfo->data, buffer, count );
+    }
+
+void shsFinal(SHS_INFO *shsInfo)
+    {
+    int count;
+    LONG lowBitcount = shsInfo->countLo, highBitcount = shsInfo->countHi;
+
+    /* Compute number of bytes mod 64 */
+    count = ( int ) ( ( shsInfo->countLo >> 3 ) & 0x3F );
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    ( ( BYTE * ) shsInfo->data )[ count++ ] = 0x80;
+
+    /* Pad out to 56 mod 64 */
+    if( count > 56 )
+	{
+	/* Two lots of padding:  Pad the first block to 64 bytes */
+	memset( ( BYTE * ) &shsInfo->data + count, 0, 64 - count );
+	byteReverse( shsInfo->data, SHS_BLOCKSIZE );
+	shsTransform( shsInfo );
+
+	/* Now fill the next block with 56 bytes */
+	memset( &shsInfo->data, 0, 56 );
+	}
+    else
+	/* Pad block to 56 bytes */
+	memset( ( BYTE * ) &shsInfo->data + count, 0, 56 - count );
+	byteReverse( shsInfo->data, SHS_BLOCKSIZE );
+
+    /* Append length in bits and transform */
+    shsInfo->data[ 14 ] = highBitcount;
+    shsInfo->data[ 15 ] = lowBitcount;
+
+    shsTransform( shsInfo );
+    byteReverse( shsInfo->data, SHS_DIGESTSIZE );
+    }
diff --git a/AppleCSP/MiscCSPAlgs/SHA1_priv.h b/AppleCSP/MiscCSPAlgs/SHA1_priv.h
new file mode 100644
index 00000000..77ab7e8f
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/SHA1_priv.h
@@ -0,0 +1,54 @@
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * SHA1_priv.h - private low-level API for SHA-1 hash algorithm
+ *
+ * Revision History
+ * ----------------
+ * 22 Aug 96	Doug Mitchell at NeXT
+ *	Created.
+ */
+
+/* Useful defines/typedefs */
+
+#ifndef	_CK_SHA1_PRIV_H_
+#define	_CK_SHA1_PRIV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char   BYTE;
+typedef unsigned long   LONG;
+
+/* The SHS block size and message digest sizes, in bytes */
+
+#define SHS_BLOCKSIZE   64
+#define SHS_DIGESTSIZE  20
+
+/* The structure for storing SHS info */
+
+typedef struct {
+	       LONG digest[ 5 ];            /* Message digest */
+	       LONG countLo, countHi;       /* 64-bit bit count */
+	       LONG data[ 80 ];             /* SHS data buffer */
+	       } SHS_INFO;
+
+extern void shsInit(SHS_INFO *shsInfo);
+extern void shsUpdate(SHS_INFO *shsInfo,
+	const BYTE *buffer,
+	int count);
+extern void shsFinal(SHS_INFO *shsInfo);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _CK_SHA1_PRIV_H_ */
diff --git a/AppleCSP/MiscCSPAlgs/desContext.cpp b/AppleCSP/MiscCSPAlgs/desContext.cpp
new file mode 100644
index 00000000..8913a57f
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/desContext.cpp
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * desContext.cpp - glue between BlockCrytpor and DES implementation
+ * Written by Doug Mitchell 3/28/2001
+ */
+ 
+#include "desContext.h"
+#include <Security/debugging.h>
+#include <Security/globalizer.h>
+#include <Security/threading.h>
+
+ModuleNexus<Mutex> desInitMutex;
+
+#define DESDebug(args...)	debug("desContext", ## args)
+
+/*
+ * DES encrypt/decrypt.
+ */
+DESContext::~DESContext()
+{
+	desdone(&DesInst);
+	memset(&DesInst, 0, sizeof(struct _desInst));
+}
+	
+/* 
+ * Standard CSPContext init, called from CSPFullPluginSession::init().
+ * Reusable, e.g., query followed by en/decrypt.
+ */
+void DESContext::init( 
+	const Context &context, 
+	bool encrypting)
+{
+	UInt32 		keyLen;
+	UInt8 		*keyData 	= NULL;
+	
+	/* obtain key from context */
+	symmetricKeyBits(context, CSSM_ALGID_DES, 
+		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,	
+		keyData, keyLen);
+	if(keyLen != (DES_KEY_SIZE_BITS_EXTERNAL / 8)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	/* init the low-level state */
+	{
+		StLock<Mutex> _(desInitMutex());
+		if(int irtn = desinit(&DesInst, DES_MODE_STD)) {
+			DESDebug("desinit returned %d\n", irtn);
+			CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+		}
+	}
+	dessetkey(&DesInst, (char *)keyData);
+
+	/* Finally, have BlockCryptor do its setup */
+	setup(DES_BLOCK_SIZE_BYTES, context);
+}	
+
+/*
+ * Functions called by BlockCryptor
+ * DES does encrypt/decrypt in place
+ */
+void DESContext::encryptBlock(
+	const void		*plainText,			// length implied (one block)
+	size_t			plainTextLen,
+	void			*cipherText,	
+	size_t			&cipherTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen != DES_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+	}
+	if(cipherTextLen < DES_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	if(plainText != cipherText) {
+		/* little optimization for callers who want to encrypt in place */
+		memmove(cipherText, plainText, DES_BLOCK_SIZE_BYTES);
+	}
+	endes(&DesInst, (char *)cipherText);
+	cipherTextLen = DES_BLOCK_SIZE_BYTES;
+}
+
+void DESContext::decryptBlock(
+	const void		*cipherText,		// length implied (one block)
+	void			*plainText,	
+	size_t			&plainTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen < DES_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	if(plainText != cipherText) {
+		/* little optimization for callers who want to decrypt in place */
+		memmove(plainText, cipherText, DES_BLOCK_SIZE_BYTES);
+	}
+	dedes(&DesInst, (char *)plainText);
+	plainTextLen = DES_BLOCK_SIZE_BYTES;
+}
+
+/***
+ *** Triple-DES - EDE, 24-bit key only
+ ***/
+ 
+DES3Context::~DES3Context()
+{
+	for(int i =0; i<3; i++) {
+		desdone(&DesInst[i]);
+		memset(&DesInst[i], 0, sizeof(struct _desInst));
+	}
+}
+
+/* 
+ * Standard CSPContext init, called from CSPFullPluginSession::init().
+ * Reusable, e.g., query followed by en/decrypt.
+ */
+void DES3Context::init( 
+	const Context &context, 
+	bool encrypting)
+{
+	UInt32 		keyLen;
+	UInt8 		*keyData 	= NULL;
+	
+	/* obtain key from context */
+	symmetricKeyBits(context, CSSM_ALGID_3DES_3KEY_EDE, 
+		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
+		keyData, keyLen);
+	if(keyLen != DES3_KEY_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	/* init the low-level state */
+	int irtn;
+	unsigned i;
+	{
+		StLock<Mutex> _(desInitMutex());
+		for(i=0; i<3; i++) {
+			if(irtn = desinit(&DesInst[i], DES_MODE_STD)) {
+				DESDebug("desinit returned %d\n", irtn);
+				CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+			}
+			dessetkey(&DesInst[i], (char *)keyData + (8 * i));
+		}
+	}
+	
+	/* Finally, have BlockCryptor do its setup */
+	setup(DES3_BLOCK_SIZE_BYTES, context);
+}	
+
+/*
+ * Functions called by BlockCryptor
+ * DES does encrypt/decrypt in place
+ */
+void DES3Context::encryptBlock(
+	const void		*plainText,			// length implied (one block)
+	size_t			plainTextLen,
+	void			*cipherText,	
+	size_t			&cipherTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen != DES3_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+	}
+	if(cipherTextLen < DES3_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	if(plainText != cipherText) {
+		/* little optimization for callers who want to encrypt in place */
+		memmove(cipherText, plainText, DES3_BLOCK_SIZE_BYTES);
+	}
+	
+	/* encrypt --> decrypt --> encrypt */
+	endes(&DesInst[0], (char *)cipherText);
+	dedes(&DesInst[1], (char *)cipherText);
+	endes(&DesInst[2], (char *)cipherText);
+	cipherTextLen = DES3_BLOCK_SIZE_BYTES;
+}
+
+void DES3Context::decryptBlock(
+	const void		*cipherText,		// length implied (one block)
+	void			*plainText,	
+	size_t			&plainTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen < DES3_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	if(plainText != cipherText) {
+		/* little optimization for callers who want to decrypt in place */
+		memmove(plainText, cipherText, DES3_BLOCK_SIZE_BYTES);
+	}
+	
+	/* decrypt --> encrypt -->decrypt */
+	dedes(&DesInst[2], (char *)plainText);
+	endes(&DesInst[1], (char *)plainText);
+	dedes(&DesInst[0], (char *)plainText);
+	plainTextLen = DES3_BLOCK_SIZE_BYTES;
+}
diff --git a/AppleCSP/MiscCSPAlgs/desContext.h b/AppleCSP/MiscCSPAlgs/desContext.h
new file mode 100644
index 00000000..efa49c87
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/desContext.h
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * desContext.h - glue between BlockCrytpor and DES/3DES implementations
+ * Written by Doug Mitchell 3/28/2001
+ */
+#ifndef _DES_CONTEXT_H_
+#define _DES_CONTEXT_H_
+
+#include <Security/CSPsession.h>
+#include "AppleCSP.h"
+#include "AppleCSPContext.h"
+#include "AppleCSPSession.h"
+#include "BlockCryptor.h"
+#include <MiscCSPAlgs/DES.h>
+
+/* DES Symmetric encryption context */
+class DESContext : public BlockCryptor {
+public:
+	DESContext(AppleCSPSession &session) :
+		BlockCryptor(session)	{ }
+	~DESContext();
+	
+	// called by CSPFullPluginSession
+	void init(const Context &context, bool encoding = true);
+
+	// called by BlockCryptor
+	void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, throws on overflow
+		bool			final);
+	void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, throws on overflow
+		bool			final);
+	
+private:
+	struct _desInst		DesInst;
+	
+};	/* DESContext */
+
+/* Triple-DES (EDE, 24 byte key) Symmetric encryption context */
+
+#define DES3_KEY_SIZE_BYTES		(3 * (DES_KEY_SIZE_BITS_EXTERNAL / 8))
+#define DES3_BLOCK_SIZE_BYTES	DES_BLOCK_SIZE_BYTES
+
+class DES3Context : public BlockCryptor {
+public:
+	DES3Context(AppleCSPSession &session) :
+		BlockCryptor(session)	{ }
+	~DES3Context();
+	
+	// called by CSPFullPluginSession
+	void init(const Context &context, bool encoding = true);
+
+	// called by BlockCryptor
+	void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, throws on overflow
+		bool			final);
+	void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, throws on overflow
+		bool			final);
+	
+private:
+	struct _desInst		DesInst[3];
+	
+};	/* DES3Context */
+
+#endif //_DES_CONTEXT_H_
diff --git a/AppleCSP/MiscCSPAlgs/miscAlgFactory.cpp b/AppleCSP/MiscCSPAlgs/miscAlgFactory.cpp
new file mode 100644
index 00000000..2e7e848b
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/miscAlgFactory.cpp
@@ -0,0 +1,281 @@
+/*
+ * 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.
+ */
+
+
+//
+// miscAlgFactory.h - miscellaneous algorithm factory
+// Written by Doug Mitchell 3/28/2001
+//
+
+#include "miscAlgFactory.h"
+#include <AES/aescspi.h>
+#include "desContext.h"
+#include "rc2Context.h"
+#include "rc4Context.h"
+#include "rc5Context.h"
+#include "MacContext.h"
+#include "DigestContext.h"
+#include "SHA1_MD5_Object.h"			/* raw digest */
+#include "MD2Object.h"
+#include <Security/cssmapple.h>
+
+/* 
+ * normally CSSM_ALGID_SHA1HMAC_LEGACY maps to a MacLegacyContext if 
+ * CRYPTKIT_CSP_ENABLE is true. For quick testing, we also map 
+ * CSSM_ALGID_SHA1HMAC to MacLegacyContext.
+ */
+#define HMAC_BOGUS_ENABLE	0
+
+/*
+ * These #defines are mainly to facilitate measuring the performance of our own
+ * implementation vs. the ones in BSafe. This factory gets called first; if
+ * we disable e.g. DES here the BSAFE version will be used.
+ */
+#ifdef	BSAFE_CSP_ENABLE
+
+#define MAF_DES_ENABLE		0
+#define MAF_DES3_ENABLE		0
+#define MAF_RC2_ENABLE		0
+#define MAF_RC4_ENABLE		0
+#define MAF_RC5_ENABLE		0
+#define MAF_MAC_ENABLE		0
+
+#else	/* !BSAFE_CSP_ENABLE, normal case */
+
+#define MAF_DES_ENABLE		1
+#define MAF_DES3_ENABLE		1
+#define MAF_RC2_ENABLE		1
+#define MAF_RC4_ENABLE		1
+#define MAF_RC5_ENABLE		1
+#define MAF_MAC_ENABLE		1
+
+#endif	/* BSAFE_CSP_ENABLE */
+
+#if	(!MAF_DES_ENABLE || !MAF_DES3_ENABLE || !MAF_RC2_ENABLE || !MAF_RC4_ENABLE || \
+		!MAF_RC5_ENABLE || !MAF_MAC_ENABLE)
+#warning	Internal DES/RC2/RC4/RC5/Mac implementation disabled! 
+#endif
+
+bool MiscAlgFactory::setup(
+	AppleCSPSession &session,
+	CSPFullPluginSession::CSPContext * &cspCtx, 
+	const Context &context)
+{
+	CSSM_CONTEXT_TYPE ctype = context.type();
+	CSSM_ALGORITHMS alg = context.algorithm();
+	
+	switch(ctype) {
+		case CSSM_ALGCLASS_SYMMETRIC:
+			switch(alg) {
+				case CSSM_ALGID_AES:
+					if(cspCtx == NULL) {
+						cspCtx = new AESContext(session);
+					}
+					return true;
+
+				#if		MAF_DES_ENABLE
+				case CSSM_ALGID_DES:
+					if(cspCtx == NULL) {
+						cspCtx = new DESContext(session);
+					}
+					return true;
+				#endif	/* MAF_DES_ENABLE */
+				
+				#if		MAF_DES3_ENABLE
+				/*
+				 * TripleDES: for some reason, cssmtype.h defines different symbols
+				 * for CSSM_ALGID_3DES_3KEY (key gen) and CSSM_ALGID_3DES_3KEY_EDE
+				 * (an encrypt alg with mode), but they define to the same value.
+				 */
+				case CSSM_ALGID_3DES_3KEY_EDE:
+					if(cspCtx == NULL) {
+						cspCtx = new DES3Context(session);
+					}
+					return true;
+				#endif
+				
+				#if		MAF_RC2_ENABLE
+				case CSSM_ALGID_RC2:
+					if(cspCtx == NULL) {
+						cspCtx = new RC2Context(session);
+					}
+					return true;
+				#endif
+				
+				#if		MAF_RC4_ENABLE
+				case CSSM_ALGID_RC4:
+					if(cspCtx == NULL) {
+						cspCtx = new RC4Context(session);
+					}
+					return true;
+				#endif
+				
+				#if		MAF_RC5_ENABLE
+				case CSSM_ALGID_RC5:
+					if(cspCtx == NULL) {
+						cspCtx = new RC5Context(session);
+					}
+					return true;
+				#endif
+				
+				default:
+					break;	// not our symmetric alg
+			}				// switch alg for symmetric 
+			break;			// from case CSSM_ALGCLASS_SYMMETRIC 
+			
+		/* digest algorithms always enabled here */
+		case CSSM_ALGCLASS_DIGEST:
+			switch(alg) {
+				case CSSM_ALGID_SHA1:
+					if(cspCtx == NULL) {
+						/* reuse is OK */
+						cspCtx = new DigestContext(session, 
+								*(new SHA1Object));
+					}
+					return true;
+				case CSSM_ALGID_MD5:
+					if(cspCtx == NULL) {
+						/* reuse is OK */
+						cspCtx = new DigestContext(session, 
+								*(new MD5Object));
+					}
+					return true;
+				case CSSM_ALGID_MD2:
+					if(cspCtx == NULL) {
+						/* reuse is OK */
+						cspCtx = new DigestContext(session, 
+								*(new MD2Object));
+					}
+					return true;
+				default:
+					break;		// not our digest alg
+			}					// switch digest alg
+			break;				// from case CSSM_ALGCLASS_DIGEST
+			
+		case CSSM_ALGCLASS_KEYGEN:
+			switch(alg) {
+				case CSSM_ALGID_AES:
+					if(cspCtx == NULL) {
+						cspCtx = new AESKeyGenContext(session);
+					}
+					return true;
+
+				#if		MAF_DES_ENABLE
+				case CSSM_ALGID_DES:
+					if(cspCtx == NULL) {
+						cspCtx = new AppleSymmKeyGenerator(session,
+							DES_KEY_SIZE_BITS_EXTERNAL,
+							DES_KEY_SIZE_BITS_EXTERNAL,
+							true);				// must be byte size
+					}
+					return true;
+				#endif	/* MAF_DES_ENABLE */
+				
+				#if		MAF_DES3_ENABLE
+				case CSSM_ALGID_3DES_3KEY_EDE:
+					if(cspCtx == NULL) {
+						cspCtx = new AppleSymmKeyGenerator(session,
+							DES3_KEY_SIZE_BYTES * 8,
+							DES3_KEY_SIZE_BYTES * 8,
+							true);			// must be byte size
+					}
+					return true;
+				#endif
+				
+				#if		MAF_RC2_ENABLE
+				case CSSM_ALGID_RC2:
+					if(cspCtx == NULL) {
+						cspCtx = new AppleSymmKeyGenerator(session,
+							RC2_MIN_KEY_SIZE_BYTES * 8,
+							RC2_MAX_KEY_SIZE_BYTES * 8,
+							true);				// must be byte size
+					}
+					return true;
+				#endif
+				
+				#if		MAF_RC4_ENABLE
+				case CSSM_ALGID_RC4:
+					if(cspCtx == NULL) {
+						cspCtx = new AppleSymmKeyGenerator(session,
+							RC4_MIN_KEY_SIZE_BYTES * 8,
+							RC4_MAX_KEY_SIZE_BYTES * 8,
+							true);				// must be byte size
+					}
+					return true;
+				#endif
+				
+				#if		MAF_RC5_ENABLE
+				case CSSM_ALGID_RC5:
+					if(cspCtx == NULL) {
+						cspCtx = new AppleSymmKeyGenerator(session,
+							RC5_MIN_KEY_SIZE_BYTES * 8,
+							RC5_MAX_KEY_SIZE_BYTES * 8,
+							true);				// must be byte size
+					}
+					return true;
+				#endif
+				
+				#if		MAF_MAC_ENABLE
+				case CSSM_ALGID_SHA1HMAC:
+					if(cspCtx == NULL) {
+						cspCtx = new AppleSymmKeyGenerator(session,
+							HMAC_MIN_KEY_SIZE * 8,
+							HMAC_MAX_KEY_SIZE * 8,
+							true);				// must be byte size
+					}
+					return true;
+				#endif
+				
+				default:
+					break;	// not our keygen alg
+			}				// switch alg for keygen
+			break;			// from case CSSM_ALGCLASS_KEYGEN
+			
+		case CSSM_ALGCLASS_MAC:
+			switch(alg) {
+				#if		MAF_MAC_ENABLE
+				case CSSM_ALGID_SHA1HMAC:
+					if(cspCtx == NULL) {
+						#if		HMAC_BOGUS_ENABLE
+						/* quick hack for Keychain Access testing */
+						cspCtx = new MacLegacyContext(session);
+						#else
+						cspCtx = new MacContext(session);
+						#endif
+					}
+					return true;
+				#endif
+				#if		CRYPTKIT_CSP_ENABLE
+				case CSSM_ALGID_SHA1HMAC_LEGACY:
+					if(cspCtx == NULL) {
+						cspCtx = new MacLegacyContext(session);
+					}
+					return true;
+				#endif
+				default:
+					/* not our mac alg */
+					break;
+			}
+			break;
+			
+		default:
+			break;			// not our context type
+	}						// switch context type
+	
+	/* not ours */
+	return false;
+}
diff --git a/AppleCSP/MiscCSPAlgs/miscAlgFactory.h b/AppleCSP/MiscCSPAlgs/miscAlgFactory.h
new file mode 100644
index 00000000..c368483e
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/miscAlgFactory.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+
+//
+// miscAlgFactory.h - miscellaneous algorithm factory
+// Written by Doug Mitchell 3/28/2001
+//
+#ifndef _MISC_ALG_FACTORY_H_
+#define _MISC_ALG_FACTORY_H_
+
+#include <Security/CSPsession.h>
+#include "AppleCSP.h"
+
+class AppleCSPSession;
+
+class MiscAlgFactory : public AppleCSPAlgorithmFactory {
+public:
+	
+    MiscAlgFactory(
+		CssmAllocator *normAlloc = NULL, 
+		CssmAllocator *privAlloc = NULL)
+		{ }
+	~MiscAlgFactory() { }
+	
+    bool setup(
+		AppleCSPSession &session,
+		CSPFullPluginSession::CSPContext * &cspCtx, 
+		const Context &context);
+
+};
+
+#endif //_MISC_ALG_FACTORY_H_
diff --git a/AppleCSP/MiscCSPAlgs/platform.h b/AppleCSP/MiscCSPAlgs/platform.h
new file mode 100644
index 00000000..ddc1b18e
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/platform.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
+ *
+ * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
+ * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
+ * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
+ * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
+ * EXPOSE YOU TO LIABILITY.
+ ***************************************************************************
+ *
+ * platform.h - platform-dependent C functions
+ *
+ * Revision History
+ * ----------------
+ *  6 Sep 96	Doug Mitchell at NeXT
+ *	Created.
+ */
+
+#ifndef	_CK_PLATFORM_H_
+#define _CK_PLATFORM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+/* many ways to determin macintosh - different for 68k, PPC/OS9, X */
+#if	defined(__POWERPC__) || defined(__CFM68K__) || defined(__APPLE__)
+	#undef	__MAC_BUILD__
+	#define	__MAC_BUILD__	1
+#endif
+
+/*
+ * Make sure endianness is defined...
+ */
+#if defined(__BIG_ENDIAN__) && defined(__LITTLE_ENDIAN__)
+#error Hey! multiply defined  endianness!
+#endif
+#if	!defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
+    #if	__MAC_BUILD__
+	#define	__BIG_ENDIAN__		1
+    #elif __i386__ || __i486__
+    	#define __LITTLE_ENDIAN__	1
+    #else
+    	#error Platform dependent work needed
+    #endif
+#endif	/* endian */
+
+#ifndef	NeXT
+    #define bcopy(s, d, l)	memmove(d, s, l)
+    #define bzero(s, l)		memset(s, 0, l)
+    #define bcmp(s, d, l)	memcmp(s, d, l)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/*_CK_PLATFORM_H_*/
diff --git a/AppleCSP/MiscCSPAlgs/rc2Context.cpp b/AppleCSP/MiscCSPAlgs/rc2Context.cpp
new file mode 100644
index 00000000..31169689
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/rc2Context.cpp
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * rc2Context.cpp - glue between BlockCrytpor and ssleay RC2 implementation
+ * Written by Doug Mitchell 04/03/2001
+ */
+ 
+#include <openssl/rc2.h>
+#include <misc/rc2_locl.h>
+#include "rc2Context.h"
+
+RC2Context::~RC2Context()
+{
+	memset(&rc2Key, 0, sizeof(RC2_KEY));
+}
+	
+/* 
+ * Standard CSPContext init, called from CSPFullPluginSession::init().
+ * Reusable, e.g., query followed by en/decrypt.
+ */
+void RC2Context::init( 
+	const Context &context, 
+	bool encrypting)
+{
+	UInt32 		keyLen;
+	UInt8 		*keyData 	= NULL;
+	UInt32		effectiveBits;
+	
+	/* obtain key from context */
+	symmetricKeyBits(context, CSSM_ALGID_RC2, 
+		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
+		keyData, keyLen);
+	if((keyLen < RC2_MIN_KEY_SIZE_BYTES) || (keyLen > RC2_MAX_KEY_SIZE_BYTES)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	/* 
+	 * Optional effective key size in bits - either from Context,
+	 * or the key
+	 */
+	effectiveBits = context.getInt(CSSM_ATTRIBUTE_EFFECTIVE_BITS);
+	if(effectiveBits == 0) {
+		CssmKey &key = context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, 
+			CSSMERR_CSP_MISSING_ATTR_KEY);
+		effectiveBits = key.KeyHeader.LogicalKeySizeInBits;
+	}
+
+	/* init the low-level state */
+	RC2_set_key(&rc2Key, keyLen, keyData, effectiveBits);
+
+	/* Finally, have BlockCryptor do its setup */
+	setup(RC2_BLOCK_SIZE_BYTES, context);
+}	
+
+/*
+ * Functions called by BlockCryptor
+ */
+void RC2Context::encryptBlock(
+	const void		*plainText,			// length implied (one block)
+	size_t			plainTextLen,
+	void			*cipherText,	
+	size_t			&cipherTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen != RC2_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+	}
+	if(cipherTextLen < RC2_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	
+	/*
+	 * Low-level code operates on array of unsigned 32-bit integers 
+	 */
+	RC2_INT	d[2];
+	RC2_INT l;
+	c2l((unsigned char *)plainText, l); d[0]=l;
+	c2l((unsigned char *)plainText, l); d[1]=l;
+	RC2_encrypt(d, &rc2Key);
+	l=d[0]; l2c(l, (unsigned char *)cipherText);
+	l=d[1]; l2c(l, (unsigned char *)cipherText);
+	cipherTextLen = RC2_BLOCK_SIZE_BYTES;
+}
+
+void RC2Context::decryptBlock(
+	const void		*cipherText,		// length implied (one block)
+	void			*plainText,	
+	size_t			&plainTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen < RC2_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	/*
+	 * Low-level code operates on array of unsigned 32-bit integers 
+	 */
+	RC2_INT	d[2];
+	RC2_INT l;
+	c2l((unsigned char *)cipherText, l); d[0]=l;
+	c2l((unsigned char *)cipherText, l); d[1]=l;
+	RC2_decrypt(d, &rc2Key);
+	l=d[0]; l2c(l, (unsigned char *)plainText);
+	l=d[1]; l2c(l, (unsigned char *)plainText);
+	plainTextLen = RC2_BLOCK_SIZE_BYTES;
+}
+
diff --git a/AppleCSP/MiscCSPAlgs/rc2Context.h b/AppleCSP/MiscCSPAlgs/rc2Context.h
new file mode 100644
index 00000000..9b5d762f
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/rc2Context.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * rc2Context.h - glue between BlockCrytpor and ssleay RC2 implementation
+ * Written by Doug Mitchell 4/3/2001
+ */
+#ifndef _RC2_CONTEXT_H_
+#define _RC2_CONTEXT_H_
+
+#include <AppleCSP/BlockCryptor.h>
+#include <openssl/rc2.h>
+
+/* RC2 Symmetric encryption context */
+class RC2Context : public BlockCryptor {
+public:
+	RC2Context(AppleCSPSession &session) :
+		BlockCryptor(session)	{ }
+	~RC2Context();
+	
+	// called by CSPFullPluginSession
+	void init(const Context &context, bool encoding = true);
+
+	// called by BlockCryptor
+	void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, throws on overflow
+		bool			final);
+	void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, throws on overflow
+		bool			final);
+	
+private:
+	RC2_KEY				rc2Key;
+	
+};	/* RC2Context */
+
+#endif //_RC2_CONTEXT_H_
diff --git a/AppleCSP/MiscCSPAlgs/rc4Context.cpp b/AppleCSP/MiscCSPAlgs/rc4Context.cpp
new file mode 100644
index 00000000..1cde9c37
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/rc4Context.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * rc4Context.cpp - glue between BlockCrytpor and ssleay RC4 implementation
+ * Written by Doug Mitchell 04/03/2001
+ */
+ 
+#include <openssl/rc4.h>
+#include "rc4Context.h"
+
+RC4Context::~RC4Context()
+{
+	memset(&rc4Key, 0, sizeof(RC4_KEY));
+}
+	
+/* 
+ * Standard CSPContext init, called from CSPFullPluginSession::init().
+ * Reusable, e.g., query followed by en/decrypt.
+ */
+void RC4Context::init( 
+	const Context &context, 
+	bool encrypting)
+{
+	UInt32 		keyLen;
+	UInt8 		*keyData 	= NULL;
+	
+	/* obtain key from context */
+	symmetricKeyBits(context, CSSM_ALGID_RC4, 
+		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
+		keyData, keyLen);
+	if((keyLen < RC4_MIN_KEY_SIZE_BYTES) || (keyLen > RC4_MAX_KEY_SIZE_BYTES)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	/* All other context attributes ignored */
+	/* init the low-level state */
+	RC4_set_key(&rc4Key, keyLen, keyData);
+}	
+
+/*
+ * All of these functions are called by CSPFullPluginSession.
+ */
+void RC4Context::update(
+	void 			*inp, 
+	size_t 			&inSize, 			// in/out
+	void 			*outp, 
+	size_t 			&outSize)			// in/out
+{
+	RC4(&rc4Key, inSize, (unsigned char *)inp, (unsigned char *)outp);
+	outSize = inSize;
+}
+
+/* remainding functions are trivial for any stream cipher */
+void RC4Context::final(
+	CssmData 		&out)	
+{
+	out.length(0);
+}
+
+size_t RC4Context::inputSize(
+	size_t 			outSize)			// input for given output size
+{
+	return outSize;
+}
+
+size_t RC4Context::outputSize(
+	bool 			final = false, 
+	size_t 			inSize = 0) 		// output for given input size
+{
+	return inSize;
+}
+
+void RC4Context::minimumProgress(
+	size_t 			&in, 
+	size_t 			&out) 				// minimum progress chunks
+{
+	in  = 1;
+	out = 1;
+}
diff --git a/AppleCSP/MiscCSPAlgs/rc4Context.h b/AppleCSP/MiscCSPAlgs/rc4Context.h
new file mode 100644
index 00000000..274f8acb
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/rc4Context.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * rc4Context.h - glue between BlockCrytpor and ssleay RC4 implementation
+ * Written by Doug Mitchell 4/3/2001
+ */
+#ifndef _RC4_CONTEXT_H_
+#define _RC4_CONTEXT_H_
+
+#include "AppleCSPContext.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <openssl/rc4.h>
+
+class RC4Context : public AppleCSPContext {
+public:
+	RC4Context(AppleCSPSession &session) :
+		AppleCSPContext(session)	{ }
+	~RC4Context();
+	
+	// called by CSPFullPluginSession
+	void init(
+		const Context 	&context, 
+		bool encoding = true);
+	void update(
+		void 			*inp, 
+		size_t 			&inSize, 			// in/out
+		void 			*outp, 
+		size_t 			&outSize);			// in/out
+	void final(
+		CssmData 		&out);
+
+ 	size_t inputSize(
+		size_t 			outSize);			// input for given output size
+	size_t outputSize(
+		bool 			final = false, 
+		size_t 			inSize = 0); 		// output for given input size
+	void minimumProgress(
+		size_t 			&in, 
+		size_t 			&out); 				// minimum progress chunks
+	
+private:
+	RC4_KEY				rc4Key;
+	
+};	/* RC4Context */
+
+#endif //_RC4_CONTEXT_H_
diff --git a/AppleCSP/MiscCSPAlgs/rc5Context.cpp b/AppleCSP/MiscCSPAlgs/rc5Context.cpp
new file mode 100644
index 00000000..5f4c340b
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/rc5Context.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * rc5Context.cpp - glue between BlockCrytpor and ssleay RC5 implementation
+ * Written by Doug Mitchell 04/03/2001
+ */
+ 
+#include <openssl/rc5.h>
+#include <misc/rc5_locl.h>
+#include "rc5Context.h"
+
+RC5Context::~RC5Context()
+{
+	memset(&rc5Key, 0, sizeof(RC5_32_KEY));
+}
+	
+/* 
+ * Standard CSPContext init, called from CSPFullPluginSession::init().
+ * Reusable, e.g., query followed by en/decrypt.
+ */
+void RC5Context::init( 
+	const Context &context, 
+	bool encrypting)
+{
+	UInt32 		keyLen;
+	UInt8 		*keyData 	= NULL;
+	UInt32		rounds = RC5_16_ROUNDS;
+	
+	/* obtain key from context */
+	symmetricKeyBits(context, CSSM_ALGID_RC5, 
+		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
+		keyData, keyLen);
+	if((keyLen < RC5_MIN_KEY_SIZE_BYTES) || (keyLen > RC5_MAX_KEY_SIZE_BYTES)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
+	}
+	
+	/* 
+	 * Optional rounds
+	 */
+	rounds = context.getInt(CSSM_ATTRIBUTE_ROUNDS);
+	if(rounds == 0) {
+		/* default */
+		rounds = RC5_16_ROUNDS;
+	}
+
+	/* init the low-level state */
+	RC5_32_set_key(&rc5Key, keyLen, keyData, rounds);
+
+	/* Finally, have BlockCryptor do its setup */
+	setup(RC5_BLOCK_SIZE_BYTES, context);
+}	
+
+/*
+ * Functions called by BlockCryptor
+ */
+void RC5Context::encryptBlock(
+	const void		*plainText,			// length implied (one block)
+	size_t			plainTextLen,
+	void			*cipherText,	
+	size_t			&cipherTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen != RC5_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
+	}
+	if(cipherTextLen < RC5_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	
+	/*
+	 * Low-level code operates on array of unsigned 32-bit integers 
+	 */
+	RC5_32_INT	d[2];
+	RC5_32_INT l;
+	c2l((unsigned char *)plainText, l); d[0]=l;
+	c2l((unsigned char *)plainText, l); d[1]=l;
+	RC5_32_encrypt(d, &rc5Key);
+	l=d[0]; l2c(l, (unsigned char *)cipherText);
+	l=d[1]; l2c(l, (unsigned char *)cipherText);
+	cipherTextLen = RC5_BLOCK_SIZE_BYTES;
+}
+
+void RC5Context::decryptBlock(
+	const void		*cipherText,		// length implied (one block)
+	void			*plainText,	
+	size_t			&plainTextLen,		// in/out, throws on overflow
+	bool			final)				// ignored
+{
+	if(plainTextLen < RC5_BLOCK_SIZE_BYTES) {
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	/*
+	 * Low-level code operates on array of unsigned 32-bit integers 
+	 */
+	RC5_32_INT	d[2];
+	RC5_32_INT l;
+	c2l((unsigned char *)cipherText, l); d[0]=l;
+	c2l((unsigned char *)cipherText, l); d[1]=l;
+	RC5_32_decrypt(d, &rc5Key);
+	l=d[0]; l2c(l, (unsigned char *)plainText);
+	l=d[1]; l2c(l, (unsigned char *)plainText);
+	plainTextLen = RC5_BLOCK_SIZE_BYTES;
+}
+
diff --git a/AppleCSP/MiscCSPAlgs/rc5Context.h b/AppleCSP/MiscCSPAlgs/rc5Context.h
new file mode 100644
index 00000000..7a09c0cf
--- /dev/null
+++ b/AppleCSP/MiscCSPAlgs/rc5Context.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * rc5Context.h - glue between BlockCrytpor and ssleay RC5 implementation
+ * Written by Doug Mitchell 4/3/2001
+ */
+#ifndef _RC5_CONTEXT_H_
+#define _RC5_CONTEXT_H_
+
+#include <AppleCSP/BlockCryptor.h>
+#include <openssl/rc5.h>
+
+class RC5Context : public BlockCryptor {
+public:
+	RC5Context(AppleCSPSession &session) :
+		BlockCryptor(session)	{ }
+	~RC5Context();
+	
+	// called by CSPFullPluginSession
+	void init(const Context &context, bool encoding = true);
+
+	// called by BlockCryptor
+	void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, throws on overflow
+		bool			final);
+	void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, throws on overflow
+		bool			final);
+	
+private:
+	RC5_32_KEY			rc5Key;
+	
+};	/* RC5Context */
+
+#endif //_RC2_CONTEXT_H_
diff --git a/AppleCSP/PBKDF2/HMACSHA1.c b/AppleCSP/PBKDF2/HMACSHA1.c
new file mode 100644
index 00000000..45a6a136
--- /dev/null
+++ b/AppleCSP/PBKDF2/HMACSHA1.c
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+
+/*
+ 	File:		HMACSHA1.c
+ 	Contains:	Apple Data Security Services HMACSHA1 function definition.
+ 	Copyright:	(C) 1999 by Apple Computer, Inc., all rights reserved
+ 	Written by:	Michael Brouwer <mb@apple.com>
+*/
+#include "HMACSHA1.h"
+#include <CryptKit/SHA1.h>
+#include <string.h>
+#include <stdlib.h>		// for malloc - maybe we should use CssmAllocator?
+#include <Security/cssmerr.h>
+
+struct hmacContext {
+	sha1Obj sha1Context;
+	UInt8 	k_opad[kSHA1BlockSize];
+};
+
+hmacContextRef hmacAlloc()
+{
+	hmacContextRef hmac = (hmacContextRef)malloc(sizeof(struct hmacContext));
+	memset(hmac, 0, sizeof(struct hmacContext));
+	return hmac;
+}
+
+void hmacFree(
+	hmacContextRef hmac)
+{
+	if(hmac != NULL) {
+		if(hmac->sha1Context != NULL) {
+			sha1Free (hmac->sha1Context);
+		}
+		memset(hmac, 0, sizeof(struct hmacContext));
+		free(hmac);
+	}
+}
+
+/* reusable init */
+CSSM_RETURN hmacInit(
+	hmacContextRef hmac,
+	const void *keyPtr,
+	UInt32 keyLen)
+{	
+	UInt8 	tk[kSHA1DigestSize];
+	UInt8 	*key;
+	UInt32 	byte;
+	UInt8 	k_ipad[kSHA1BlockSize];
+
+	if(hmac->sha1Context == NULL) {
+		hmac->sha1Context = sha1Alloc();
+		if(hmac->sha1Context == NULL) {
+			return CSSMERR_CSP_MEMORY_ERROR;
+		}
+	}
+	else {
+		sha1Reinit(hmac->sha1Context);
+	}
+	
+	/* If the key is longer than kSHA1BlockSize reset it to key=SHA1(key) */
+	if (keyLen <= kSHA1BlockSize)
+		key = (UInt8*)keyPtr;
+	else {
+		sha1AddData(hmac->sha1Context, (UInt8*)keyPtr, keyLen);
+		memcpy (tk, sha1Digest(hmac->sha1Context), kSHA1DigestSize);
+		key = tk;
+		keyLen = kSHA1DigestSize;
+		sha1Reinit (hmac->sha1Context);
+	}
+	
+	/* The HMAC_SHA_1 transform looks like:
+	   SHA1 (K XOR opad || SHA1 (K XOR ipad || text))
+	   Where K is a n byte key
+	   ipad is the byte 0x36 repeated 64 times.
+	   opad is the byte 0x5c repeated 64 times.
+	   text is the data being protected.
+	  */
+	/* Copy the key into k_ipad and k_opad while doing the XOR. */
+	for (byte = 0; byte < keyLen; byte++)
+	{
+		k_ipad[byte] = key[byte] ^ 0x36;
+		hmac->k_opad[byte] = key[byte] ^ 0x5c;
+	}
+	/* Fill the remainder of k_ipad and k_opad with 0 XORed with the appropriate value. */
+	if (keyLen < kSHA1BlockSize)
+	{
+		memset (k_ipad + keyLen, 0x36, kSHA1BlockSize - keyLen);
+		memset (hmac->k_opad + keyLen, 0x5c, kSHA1BlockSize - keyLen);
+	}
+	sha1AddData (hmac->sha1Context, k_ipad, kSHA1BlockSize);
+	return CSSM_OK;
+}
+
+CSSM_RETURN hmacUpdate(
+	hmacContextRef hmac,
+	const void *textPtr,
+	UInt32 textLen)
+{
+	sha1AddData (hmac->sha1Context, (UInt8*)textPtr, textLen);
+	return CSSM_OK;
+}
+
+CSSM_RETURN hmacFinal(
+	hmacContextRef hmac,
+	void *resultPtr)		// caller mallocs, must be HMACSHA1_OUT_SIZE bytes
+{
+	memcpy (resultPtr, sha1Digest (hmac->sha1Context), kSHA1DigestSize);
+	sha1Reinit (hmac->sha1Context);
+	/* Perform outer SHA1 */
+	sha1AddData (hmac->sha1Context, hmac->k_opad, kSHA1BlockSize);
+	sha1AddData (hmac->sha1Context, (UInt8*)resultPtr, kSHA1DigestSize);
+	memcpy (resultPtr, sha1Digest (hmac->sha1Context), kSHA1DigestSize);
+	return CSSM_OK;
+}
+
+/* one-shot, ignoring memory errors. */
+void
+hmacsha1 (const void *keyPtr, UInt32 keyLen,
+		  const void *textPtr, UInt32 textLen,
+		  void *resultPtr)
+{
+	hmacContextRef hmac = hmacAlloc();
+	hmacInit(hmac, keyPtr, keyLen);
+	hmacUpdate(hmac, textPtr, textLen);
+	hmacFinal(hmac, resultPtr);
+	hmacFree(hmac);
+}
+
diff --git a/AppleCSP/PBKDF2/HMACSHA1.h b/AppleCSP/PBKDF2/HMACSHA1.h
new file mode 100644
index 00000000..bf3e15b7
--- /dev/null
+++ b/AppleCSP/PBKDF2/HMACSHA1.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+
+/*
+ 	File:		HMACSHA1.h
+ 	Contains:	Apple Data Security Services HMACSHA1 function declaration.
+ 	Copyright:	(C) 1999 by Apple Computer, Inc., all rights reserved
+ 	Written by:	Michael Brouwer <mb@apple.com>
+*/
+#ifndef __HMACSHA1__
+#define __HMACSHA1__
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <Security/cssmtype.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define kHMACSHA1DigestSize  20
+
+/* XXX These should really be in SHA1.h */
+#define kSHA1DigestSize  	20
+#define kSHA1BlockSize  	64
+
+/* This function create an HMACSHA1 digest of kHMACSHA1DigestSize and outputs
+   it to resultPtr.  See RFC 2104 for details.  */
+void
+hmacsha1 (const void *keyPtr, UInt32 keyLen,
+		  const void *textPtr, UInt32 textLen,
+		  void *resultPtr);
+		  
+/*
+ * Staged version.
+ *
+ * Opaque reference to an hmacsha1 session 
+ */
+struct hmacContext;
+typedef struct hmacContext *hmacContextRef;
+
+hmacContextRef hmacAlloc();
+void hmacFree(
+	hmacContextRef hmac);
+CSSM_RETURN hmacInit(
+	hmacContextRef hmac,
+	const void *keyPtr,
+	UInt32 keyLen);
+CSSM_RETURN hmacUpdate(
+	hmacContextRef hmac,
+	const void *textPtr,
+	UInt32 textLen);
+CSSM_RETURN hmacFinal(
+	hmacContextRef hmac,
+	void *resultPtr);		// caller mallocs, must be kSHA1DigestSize bytes
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* __HMACSHA1__ */
diff --git a/AppleCSP/PBKDF2/pbkdf2.c b/AppleCSP/PBKDF2/pbkdf2.c
new file mode 100644
index 00000000..e6550600
--- /dev/null
+++ b/AppleCSP/PBKDF2/pbkdf2.c
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+
+/*
+ 	File:		pbkdf2.c
+ 	Contains:	Apple Data Security Services PKCS #5 PBKDF2 function definition.
+ 	Copyright:	(C) 1999 by Apple Computer, Inc., all rights reserved
+ 	Written by:	Michael Brouwer <mb@apple.com>
+*/
+#include "pbkdf2.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h>
+#include <string.h>
+/* Will write hLen bytes into dataPtr according to PKCS #5 2.0 spec.
+   See: http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-5.html for details. 
+   tempBuffer is a pointer to at least MAX (hLen, saltLen + 4) + hLen bytes. */
+static void 
+F (PRF prf, UInt32 hLen,
+   const void *passwordPtr, UInt32 passwordLen,
+   const void *saltPtr, UInt32 saltLen,
+   UInt32 iterationCount,
+   UInt32 blockNumber,
+   void *dataPtr,
+   void *tempBuffer)
+{
+	UInt8 *inBlock, *outBlock, *resultBlockPtr;
+	UInt32 iteration;
+	outBlock = (UInt8*)tempBuffer;
+	inBlock = outBlock + hLen;
+	/* Set up inBlock to contain Salt || INT (blockNumber). */
+	memcpy (inBlock, saltPtr, saltLen);
+#if TARGET_RT_LITTLE_ENDIAN
+	inBlock[saltLen + 0] = (UInt8)(blockNumber);
+	inBlock[saltLen + 1] = (UInt8)(blockNumber >> 8);
+	inBlock[saltLen + 2] = (UInt8)(blockNumber >> 16);
+	inBlock[saltLen + 3] = (UInt8)(blockNumber >> 24);
+#else /* if TARGET_RT_BIG_ENDIAN */
+	inBlock[saltLen + 0] = (UInt8)(blockNumber >> 24);
+	inBlock[saltLen + 1] = (UInt8)(blockNumber >> 16);
+	inBlock[saltLen + 2] = (UInt8)(blockNumber >> 8);
+	inBlock[saltLen + 3] = (UInt8)(blockNumber);
+#endif
+	/* Caculate U1 (result goes to outBlock) and copy it to resultBlockPtr. */
+	resultBlockPtr = (UInt8*)dataPtr;
+	prf (passwordPtr, passwordLen, inBlock, saltLen + 4, outBlock);
+	memcpy (resultBlockPtr, outBlock, hLen);
+	/* Calculate U2 though UiterationCount. */
+	for (iteration = 2; iteration <= iterationCount; iteration++)
+	{
+		UInt8 *tempBlock;
+		UInt32 byte;
+		/* Swap inBlock and outBlock pointers. */
+		tempBlock = inBlock;
+		inBlock = outBlock;
+		outBlock = tempBlock;
+		/* Now inBlock conatins Uiteration-1.  Calclulate Uiteration into outBlock. */
+		prf (passwordPtr, passwordLen, inBlock, hLen, outBlock);
+		/* Xor data in dataPtr (U1 \xor U2 \xor ... \xor Uiteration-1) with
+		   outBlock (Uiteration). */
+		for (byte = 0; byte < hLen; byte++)
+			resultBlockPtr[byte] ^= outBlock[byte];
+	}
+}
+void pbkdf2 (PRF prf, UInt32 hLen,
+			 const void *passwordPtr, UInt32 passwordLen,
+			 const void *saltPtr, UInt32 saltLen,
+			 UInt32 iterationCount,
+			 void *dkPtr, UInt32 dkLen,
+			 void *tempBuffer)
+{
+	UInt32 completeBlocks = dkLen / hLen;
+	UInt32 partialBlockSize = dkLen % hLen;
+	UInt32 blockNumber;
+	UInt8 *dataPtr = (UInt8*)dkPtr;
+	UInt8 *blkBuffer = (UInt8*)tempBuffer;
+	/* First cacluate all the complete hLen sized blocks required. */
+	for (blockNumber = 1; blockNumber <= completeBlocks; blockNumber++)
+	{
+		F (prf, hLen, passwordPtr, passwordLen, saltPtr, saltLen,
+		   iterationCount, blockNumber, dataPtr, blkBuffer + hLen);
+		dataPtr += hLen;
+	}
+	/* Finally if the requested output size was not an even multiple of hLen, calculate
+	   the final block and copy the first partialBlockSize bytes of it to the output. */
+	if (partialBlockSize > 0)
+	{
+		F (prf, hLen, passwordPtr, passwordLen, saltPtr, saltLen,
+		   iterationCount, blockNumber, blkBuffer, blkBuffer + hLen);
+		memcpy (dataPtr, blkBuffer, partialBlockSize);
+	}
+}
diff --git a/AppleCSP/PBKDF2/pbkdf2.h b/AppleCSP/PBKDF2/pbkdf2.h
new file mode 100644
index 00000000..66771702
--- /dev/null
+++ b/AppleCSP/PBKDF2/pbkdf2.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+
+/*
+ 	File:		pbkdf2.h
+ 	Contains:	Apple Data Security Services PKCS #5 PBKDF2 function declaration.
+ 	Copyright:	(C) 1999 by Apple Computer, Inc., all rights reserved
+ 	Written by:	Michael Brouwer <mb@apple.com>
+*/
+
+#ifndef __PBKDF2__
+#define __PBKDF2__
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* This function should generate a pseudo random octect stream
+   of hLen bytes long (The value hLen is specified as an argument to pbkdf2
+   and should be constant for any given prf function.) which is output in the buffer
+   pointed to by randomPtr (the caller of this function is responsible for allocation
+   of the buffer).
+   The inputs to the pseudo random function are the first keyLen octets pointed
+   to by keyPtr and the first textLen octets pointed to by textPtr.
+   Both keyLen and textLen can have any nonzero value.
+   A good prf would be a HMAC-SHA-1 algorithm where the keyPtr octets serve as
+   HMAC's "key" and the textPtr octets serve as HMAC's "text".  */
+typedef void (*PRF)(const void *keyPtr, UInt32 keyLen,
+					const void *textPtr, UInt32 textLen,
+					void *randomPtr);
+
+/* This function implements the PBKDF2 key derrivation algorithm described in
+   http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-5.html
+   The output is a derived key of dkLen bytes which is written to the buffer
+   pointed to by dkPtr.
+   The caller should ensure dkPtr is at least dkLen bytes long.
+   The Key is derived from passwordPtr (which is passwordLen bytes long) and from
+   saltPtr (which is saltLen bytes long).  The algorithm used is desacribed in
+   PKCS #5 version 2.0 and iterationCount iterations are performed.
+   The argument prf is a pointer to a psuedo random number generator declared above.
+   It should write exactly hLen bytes into its output buffer each time it is called.
+   The argument tempBuffer should point to a buffer MAX (hLen, saltLen + 4) + 2 * hLen
+   bytes long.  This buffer is used during the calculation for intermediate results.
+   Security Considerations:
+   The argument saltPtr should be a pointer to a buffer of at least 8 random bytes
+   (64 bits).  Thus saltLen should be >= 8.
+   For each session a new salt should be generated.
+   The value of iterationCount should be at least 1000 (one thousand).
+   A good prf would be a HMAC-SHA-1 algorithm where the password serves as
+   HMAC's "key" and the data serves as HMAC's "text".  */
+void pbkdf2 (PRF prf, UInt32 hLen,
+			 const void *passwordPtr, UInt32 passwordLen,
+			 const void *saltPtr, UInt32 saltLen,
+			 UInt32 iterationCount,
+			 void *dkPtr, UInt32 dkLen,
+			 void *tempBuffer);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* __PBKDF2__ */
diff --git a/AppleCSP/RSA_DSA/RSA_DSA_csp.cpp b/AppleCSP/RSA_DSA/RSA_DSA_csp.cpp
new file mode 100644
index 00000000..ba979894
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_DSA_csp.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_DSA_csp.cpp - Algorithm factory for RSA/DSA 
+ */
+ 
+#include "RSA_DSA_csp.h"
+#include "RSA_DSA_signature.h"					/* raw signer */
+#include <MiscCSPAlgs/SHA1_MD5_Object.h>		/* raw digest */
+#include <AppleCSP/SignatureContext.h>
+#include <AppleCSP/NullDigest.h>
+#include "RSA_DSA_Keys.h"
+#include "RSA_asymmetric.h"
+#include <MiscCSPAlgs/MD2Object.h>
+#include <Security/cssmapple.h>
+
+#define OPENSSL_DSA_ENABLE	1
+
+CssmAllocator *RSA_DSA_Factory::normAllocator;
+CssmAllocator *RSA_DSA_Factory::privAllocator;
+
+/* normally found in crypto.h, which has way too much useless cruft....move these to
+ * a local header.... */
+extern "C" {
+extern int CRYPTO_set_mem_functions(
+	void *(*m)(size_t),
+	void *(*r)(void *,size_t), 
+	void (*f)(void *));
+int CRYPTO_set_locked_mem_functions(
+	void *(*m)(size_t), 
+	void (*free_func)(void *));
+}
+
+/*
+ * openssl-style memory allocator callbacks
+ */
+static void *osMalloc(size_t size)
+{
+	return RSA_DSA_Factory::privAllocator->malloc(size);
+}
+static void osFree(void *data)
+{
+	RSA_DSA_Factory::privAllocator->free(data);
+}
+static void *osRealloc(void *oldPtr, size_t newSize)
+{
+	return RSA_DSA_Factory::privAllocator->realloc(oldPtr, newSize);
+}
+
+RSA_DSA_Factory::RSA_DSA_Factory(CssmAllocator *normAlloc, CssmAllocator *privAlloc)
+{
+	setNormAllocator(normAlloc);
+	setPrivAllocator(privAlloc);
+	/* once-per-address space */
+	CRYPTO_set_mem_functions(osMalloc, osRealloc, osFree);
+	CRYPTO_set_locked_mem_functions(osMalloc, osFree);
+	/* these should go in a lib somewhere */
+	ERR_load_RSA_strings();
+	ERR_load_BN_strings();
+	ERR_load_DSA_strings();
+}
+
+RSA_DSA_Factory::~RSA_DSA_Factory()
+{
+	// TBD terminateCryptKit();
+}
+
+bool RSA_DSA_Factory::setup(
+	AppleCSPSession &session,	
+	CSPFullPluginSession::CSPContext * &cspCtx, 
+	const Context &context)
+{
+	switch(context.type()) {
+		case CSSM_ALGCLASS_SIGNATURE:
+			switch(context.algorithm()) {
+				case CSSM_ALGID_SHA1WithRSA:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new SHA1Object()),
+							*(new RSASigner(*privAllocator,	
+								session,
+								CSSM_ALGID_SHA1)));
+					}
+					return true;
+				case CSSM_ALGID_MD5WithRSA:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new MD5Object()),
+							*(new RSASigner(*privAllocator,	
+								session,
+								CSSM_ALGID_MD5)));
+					}
+					return true;
+				case CSSM_ALGID_MD2WithRSA:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new MD2Object()),
+							*(new RSASigner(*privAllocator,	
+								session,
+								CSSM_ALGID_MD2)));
+					}
+					return true;
+				#if	OPENSSL_DSA_ENABLE
+				case CSSM_ALGID_SHA1WithDSA:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new SHA1Object()),
+							*(new DSASigner(*privAllocator,	
+								session,
+								CSSM_ALGID_SHA1)));
+					}
+					return true;
+				case CSSM_ALGID_DSA:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new NullDigest()),
+							*(new DSASigner(*privAllocator,	
+								session,
+								// set later via setDigestAlgorithm but not used by DSA
+								CSSM_ALGID_NONE)));	
+					}
+					return true;
+				#endif
+				case CSSM_ALGID_RSA:
+					if(cspCtx == NULL) {
+						cspCtx = new SignatureContext(session,
+							*(new NullDigest()),
+							*(new RSASigner(*privAllocator,	
+								session,
+								// set later via setDigestAlgorithm
+								CSSM_ALGID_NONE)));	
+					}
+					return true;
+				default:
+					break;
+			}
+			break;		
+		
+		case CSSM_ALGCLASS_KEYGEN:
+			switch(context.algorithm()) {
+				case CSSM_ALGID_RSA:
+					if(cspCtx == NULL) {
+						cspCtx = new RSAKeyPairGenContext(session, context);
+					}
+					return true;
+				#if	OPENSSL_DSA_ENABLE
+				case CSSM_ALGID_DSA:
+					if(cspCtx == NULL) {
+						cspCtx = new DSAKeyPairGenContext(session, context);
+					}
+					return true;
+				#endif
+				default:
+					break;
+			}
+			break;		
+
+		case CSSM_ALGCLASS_ASYMMETRIC:
+			switch(context.algorithm()) {
+				case CSSM_ALGID_RSA:
+					if(cspCtx == NULL) {
+						cspCtx = new RSA_CryptContext(session);
+					}
+					return true;
+				default:
+					break;
+			}
+			break;		
+		
+		/* more here - symmetric, etc. */
+		default:
+			break;
+	}
+	/* not implemented here */
+	return false;
+}
+
+
+
diff --git a/AppleCSP/RSA_DSA/RSA_DSA_csp.h b/AppleCSP/RSA_DSA/RSA_DSA_csp.h
new file mode 100644
index 00000000..ac796a3c
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_DSA_csp.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_DSA_csp.h - Algorithm factory for RSA/DSA
+ */
+ 
+#ifndef	_RSA_DSA_CSP_H_
+#define _RSA_DSA_CSP_H_
+
+#include <Security/CSPsession.h>
+#include <AppleCSP/AppleCSP.h>
+
+/* Can't include AppleCSPSession.h due to circular dependency */
+class AppleCSPSession;
+
+class RSA_DSA_Factory : public AppleCSPAlgorithmFactory {
+public:
+    RSA_DSA_Factory(CssmAllocator *normAlloc = NULL, CssmAllocator *privAlloc = NULL);
+	~RSA_DSA_Factory();
+	
+    bool setup(
+		AppleCSPSession &session,
+		CSPFullPluginSession::CSPContext * &cspCtx, 
+		const Context &context);
+
+    static void setNormAllocator(CssmAllocator *alloc)
+    { assert(!normAllocator); normAllocator = alloc; }
+    static void setPrivAllocator(CssmAllocator *alloc)
+    { assert(!privAllocator); privAllocator = alloc; }
+
+    // memory allocators
+    static CssmAllocator *normAllocator;
+    static CssmAllocator *privAllocator;
+    
+};
+
+#endif	/* _RSA_DSA_CSP_H_ */
diff --git a/AppleCSP/RSA_DSA/RSA_DSA_keys.cpp b/AppleCSP/RSA_DSA/RSA_DSA_keys.cpp
new file mode 100644
index 00000000..49e985a4
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_DSA_keys.cpp
@@ -0,0 +1,578 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_DSA_Keys.cpp - RSA, DSA related asymmetric key pair classes. 
+ */
+
+#include "RSA_DSA_Keys.h"
+#include <opensslUtils/opensslUtils.h>
+#include <opensslUtils/openRsaSnacc.h>
+#include <Security/cssmdata.h>
+#include <AppleCSP/AppleCSPSession.h>
+#include <AppleCSP/AppleCSPUtils.h>
+#include <assert.h>
+#include <Security/debugging.h>
+#include "RSA_DSA_utils.h"
+#include <AppleCSP/YarrowConnection.h>
+#include <Security/appleoids.h>
+#include <Security/cdsaUtils.h>
+
+#define RSA_PUB_EXPONENT	0x10001 	/* recommended by RSA */
+
+#define rsaKeyDebug(args...)	debug("rsaKey", ## args)
+
+/***
+ *** RSA-style BinaryKey
+ ***/
+ 
+/* constructor with optional existing RSA key */
+RSABinaryKey::RSABinaryKey(RSA *rsaKey)
+	: mRsaKey(rsaKey)
+{
+}
+
+RSABinaryKey::~RSABinaryKey()
+{
+	if(mRsaKey) {
+		RSA_free(mRsaKey);
+		mRsaKey = NULL;
+	}
+}
+
+void RSABinaryKey::generateKeyBlob(
+	CssmAllocator 		&allocator,
+	CssmData			&blob,
+	CSSM_KEYBLOB_FORMAT	&format)
+{
+	bool			isPub;
+	CSSM_RETURN		crtn;
+	
+	switch(mKeyHeader.KeyClass) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			isPub = true;
+			format = RSA_PUB_KEY_FORMAT;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			isPub = false;
+			format = RSA_PRIV_KEY_FORMAT;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+
+	CssmAutoData 	encodedKey(allocator);
+	if(isPub) {
+		crtn = RSAPublicKeyEncode(mRsaKey, encodedKey);
+	}
+	else {
+		crtn = RSAPrivateKeyEncode(mRsaKey, encodedKey);
+	}
+	if(crtn) {
+		CssmError::throwMe(crtn);
+	}
+	blob = encodedKey.release();
+}
+		
+/***
+ *** RSA-style AppleKeyPairGenContext
+ ***/
+
+/*
+ * This one is specified in, and called from, CSPFullPluginSession. Our
+ * only job is to prepare two subclass-specific BinaryKeys and call up to
+ * AppleKeyPairGenContext.
+ */
+void RSAKeyPairGenContext::generate(
+	const Context 	&context, 
+	CssmKey 		&pubKey, 
+	CssmKey 		&privKey)
+{
+	RSABinaryKey *pubBinKey  = new RSABinaryKey();
+	RSABinaryKey *privBinKey = new RSABinaryKey();
+	
+	try {
+		AppleKeyPairGenContext::generate(context, 
+			session(),
+			pubKey, 
+			pubBinKey, 
+			privKey, 
+			privBinKey);
+	}
+	catch (...) {
+		delete pubBinKey;
+		delete privBinKey;
+		throw;
+	}
+
+}
+	
+// this one is specified in, and called from, AppleKeyPairGenContext
+void RSAKeyPairGenContext::generate(
+	const Context 	&context,
+	BinaryKey		&pubBinKey,	
+	BinaryKey		&privBinKey,
+	uint32			&keyBits)
+{
+	/* 
+	 * These casts throw exceptions if the keys are of the 
+	 * wrong classes, which would be a major bogon, since we created
+	 * the keys in the above generate() function. 
+	 */
+	RSABinaryKey &rPubBinKey = 
+		dynamic_cast<RSABinaryKey &>(pubBinKey);
+	RSABinaryKey &rPrivBinKey = 
+		dynamic_cast<RSABinaryKey &>(privBinKey);
+
+	/*
+	 * One parameter from context: Key size in bits is required.
+	 * FIXME - get public exponent from context?
+	 */
+	keyBits = context.getInt(CSSM_ATTRIBUTE_KEY_LENGTH,
+				CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH);
+				
+	/* generate the private key */
+	rPrivBinKey.mRsaKey = RSA_generate_key(keyBits,
+		RSA_PUB_EXPONENT,
+		NULL,			// no callback
+		NULL);
+	if(rPrivBinKey.mRsaKey == NULL) {
+		rsaKeyDebug("RSA_generate_key returned NULL");
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);		// ???
+	}
+		
+	/* public key is subset of private key */
+	rPubBinKey.mRsaKey = RSA_new();
+	if(rPrivBinKey.mRsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);	
+	}
+	RSA *pub = rPubBinKey.mRsaKey;
+	RSA *priv = rPrivBinKey.mRsaKey;
+	pub->n = BN_dup(priv->n);
+	pub->e = BN_dup(priv->e);
+	if((pub->n == NULL) || (pub->e == NULL)) {
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);		
+	}
+}
+
+
+/***
+ *** RSA-style CSPKeyInfoProvider.
+ ***/
+RSAKeyInfoProvider::RSAKeyInfoProvider(
+	const CssmKey &cssmKey) :
+		CSPKeyInfoProvider(cssmKey)
+{
+	switch(cssmKey.algorithm()) {
+		case CSSM_ALGID_RSA:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	switch(cssmKey.keyClass()) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	/* OK, we'll handle this one */
+	return;
+}
+
+/* Given a raw key, cook up a Binary key */
+void RSAKeyInfoProvider::CssmKeyToBinary(
+	BinaryKey **binKey)
+{
+	*binKey = NULL;
+	RSA *rsaKey = NULL;
+	
+	/* first cook up an RSA key, then drop that into a BinaryKey */
+	rsaKey = rawCssmKeyToRsa(mKey);
+	RSABinaryKey *rsaBinKey = new RSABinaryKey(rsaKey);
+	*binKey = rsaBinKey;
+}
+		
+/* 
+ * Obtain key size in bits.
+ */
+void RSAKeyInfoProvider::QueryKeySizeInBits(
+	CSSM_KEY_SIZE &keySize)
+{
+	RSA *rsaKey = NULL;
+	
+	if(mKey.blobType() != CSSM_KEYBLOB_RAW) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+	}
+	rsaKey = rawCssmKeyToRsa(mKey);
+	keySize.LogicalKeySizeInBits = RSA_size(rsaKey) * 8;
+	keySize.EffectiveKeySizeInBits = keySize.LogicalKeySizeInBits;
+	RSA_free(rsaKey);
+}
+
+/***
+ *** DSA key support
+ ***/
+ 
+
+/***
+ *** DSA-style BinaryKey
+ ***/
+ 
+/* constructor with optional existing DSA key */
+DSABinaryKey::DSABinaryKey(DSA *dsaKey)
+	: mDsaKey(dsaKey)
+{
+}
+
+DSABinaryKey::~DSABinaryKey()
+{
+	if(mDsaKey) {
+		DSA_free(mDsaKey);
+		mDsaKey = NULL;
+	}
+}
+
+void DSABinaryKey::generateKeyBlob(
+	CssmAllocator 		&allocator,
+	CssmData			&blob,
+	CSSM_KEYBLOB_FORMAT	&format)
+{
+	bool			isPub;
+	CSSM_RETURN		crtn;
+	
+	switch(mKeyHeader.KeyClass) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			isPub = true;
+			format = DSA_PUB_KEY_FORMAT;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			isPub = false;
+			format = DSA_PRIV_KEY_FORMAT;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+
+	CssmAutoData 	encodedKey(allocator);
+	if(isPub) {
+		crtn = DSAPublicKeyEncode(mDsaKey, encodedKey);
+	}
+	else {
+		crtn = DSAPrivateKeyEncode(mDsaKey, encodedKey);
+	}
+	if(crtn) {
+		CssmError::throwMe(crtn);
+	}
+	blob = encodedKey.release();
+}
+		
+/***
+ *** DSA-style AppleKeyPairGenContext
+ ***/
+
+/*
+ * This one is specified in, and called from, CSPFullPluginSession. Our
+ * only job is to prepare two subclass-specific BinaryKeys and call up to
+ * AppleKeyPairGenContext.
+ */
+void DSAKeyPairGenContext::generate(
+	const Context 	&context, 
+	CssmKey 		&pubKey, 
+	CssmKey 		&privKey)
+{
+	DSABinaryKey *pubBinKey  = new DSABinaryKey();
+	DSABinaryKey *privBinKey = new DSABinaryKey();
+	
+	try {
+		AppleKeyPairGenContext::generate(context, 
+			session(),
+			pubKey, 
+			pubBinKey, 
+			privKey, 
+			privBinKey);
+	}
+	catch (...) {
+		delete pubBinKey;
+		delete privBinKey;
+		throw;
+	}
+
+}
+	
+/*
+ * This one is specified in, and called from, AppleKeyPairGenContext
+ */
+void DSAKeyPairGenContext::generate(
+	const Context 	&context,
+	BinaryKey		&pubBinKey,	
+	BinaryKey		&privBinKey,
+	uint32			&keyBits)
+{
+	/* 
+	 * These casts throw exceptions if the keys are of the 
+	 * wrong classes, which would be a major bogon, since we created
+	 * the keys in the above generate() function.
+	 */
+	DSABinaryKey &rPubBinKey = 
+		dynamic_cast<DSABinaryKey &>(pubBinKey);
+	DSABinaryKey &rPrivBinKey = 
+		dynamic_cast<DSABinaryKey &>(privBinKey);
+
+	/*
+	 * Parameters from context: 
+	 *   Key size in bits, required;
+	 *   {p,q,g} from generateParams, optional
+	 */
+	keyBits = context.getInt(CSSM_ATTRIBUTE_KEY_LENGTH,
+				CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH);
+	CssmData *paramData = context.get<CssmData>(CSSM_ATTRIBUTE_ALG_PARAMS);
+
+	DSAAlgParams algParams;
+	if(paramData != NULL) {
+		/* this contains the DER encoding of a DSAAlgParams */
+		try {
+			SC_decodeAsnObj(*paramData, algParams);
+		}
+		catch(...) {
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS);
+		}
+	}
+	else {
+		/* no alg params specified; generate them now using null (random) seed */
+		dsaGenParams(keyBits, NULL, 0, algParams);
+	}
+					
+	/* create key, stuff params into it */
+	rPrivBinKey.mDsaKey = DSA_new();
+	if(rPrivBinKey.mDsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);		
+	}
+	DSA *dsaKey = rPrivBinKey.mDsaKey;
+	dsaKey->p = bigIntStrToBn(algParams.p);
+	dsaKey->q = bigIntStrToBn(algParams.q);
+	dsaKey->g = bigIntStrToBn(algParams.g);
+	
+	/* generate the key (both public and private capabilities) */
+	int irtn = DSA_generate_key(dsaKey);
+	if(!irtn) {
+		throwRsaDsa("DSA_generate_key");
+	}
+	
+	/* public key is subset of private key */
+	rPubBinKey.mDsaKey = DSA_new();
+	if(rPrivBinKey.mDsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);	
+	}
+	DSA *pub     = rPubBinKey.mDsaKey;
+	DSA *priv    = rPrivBinKey.mDsaKey;
+	pub->p       = BN_dup(priv->p);
+	pub->q       = BN_dup(priv->q);
+	pub->g       = BN_dup(priv->g);
+	pub->pub_key = BN_dup(priv->pub_key);
+	if((pub->p == NULL) || (pub->q == NULL) || (pub->g == NULL) ||
+			(pub->pub_key == NULL)) {
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);		
+	}
+}
+
+/*
+ * Generate keygen parameters, stash them in a context attr array for later use
+ * when actually generating the keys.
+ */
+void DSAKeyPairGenContext::generate(
+	const Context &context, 
+	uint32 bitSize,
+    CssmData &params,
+    uint32 &attrCount, 
+	Context::Attr * &attrs)
+{
+	void *seed = NULL;
+	unsigned seedLen = 0;
+
+	/* optional seed from context */
+	CssmData *seedData = context.get<CssmData>(CSSM_ATTRIBUTE_SEED);
+	if(seedData) {
+		seed = seedData->data();
+		seedLen = seedData->length();
+	}
+
+	/* generate the params */
+	DSAAlgParams algParams;
+	dsaGenParams(bitSize, seed, seedLen, algParams);
+	
+	/*
+	 * Here comes the fun part. 
+	 * We "return" the DER encoding of these generated params in two ways:
+	 * 1. Copy out to app via the params argument, mallocing if Data ptr is NULL.
+	 *    The app must free this. 
+	 * 2. Cook up a 1-element Context::attr array containing one ALG_PARAM attr,
+	 *    a CSSM_DATA_PTR containing the DER encoding. We have to save a ptr to
+	 *    this attr array and free it, the CSSM_DATA it points to, and the DER
+	 *    encoding *that* points to, in our destructor. 
+	 *
+	 * First, DER encode.
+	 */
+	size_t maxSize = sizeofBigInt(algParams.p) + 
+					 sizeofBigInt(algParams.q) + 
+					 sizeofBigInt(algParams.g) +
+					 10;
+	CssmAutoData aDerData(session());
+	SC_encodeAsnObj(algParams, aDerData, maxSize);
+
+	/* copy/release that into a mallocd CSSM_DATA. */
+	CSSM_DATA_PTR derData = (CSSM_DATA_PTR)session().malloc(sizeof(CSSM_DATA));
+	*derData = aDerData.release();
+	
+	/* stuff that into a one-element Attr array which we keep after returning */
+	freeGenAttrs();
+	mGenAttrs = (Context::Attr *)session().malloc(sizeof(Context::Attr));
+	mGenAttrs->AttributeType   = CSSM_ATTRIBUTE_ALG_PARAMS;
+	mGenAttrs->AttributeLength = sizeof(CSSM_DATA);
+	mGenAttrs->Attribute.Data  = derData;
+
+	/* and "return" this stuff */
+	copyCssmData(CssmData::overlay(*derData), params, session());
+	attrCount = 1;
+	attrs = mGenAttrs;
+}
+
+/* free mGenAttrs and its referents if present */
+void DSAKeyPairGenContext::freeGenAttrs()
+{
+	if(mGenAttrs == NULL) {
+		return;
+	}
+	if(mGenAttrs->Attribute.Data) {
+		if(mGenAttrs->Attribute.Data->Data) {
+			session().free(mGenAttrs->Attribute.Data->Data);
+		}
+		session().free(mGenAttrs->Attribute.Data);
+	}
+	session().free(mGenAttrs);
+}
+
+/*
+ * Generate DSA algorithm parameters from optional seed input, returning result
+ * into DSAAlgParams.[pqg]. This is called from both GenerateParameters and from
+ * KeyPairGenerate (if no GenerateParameters has yet been called). 
+ */
+void DSAKeyPairGenContext::dsaGenParams(
+	uint32			keySizeInBits,
+	const void		*inSeed,			// optional
+	unsigned		inSeedLen,
+	DSAAlgParams	&algParams)
+{
+	unsigned char seedBuf[SHA1_DIGEST_SIZE];
+	void *seedPtr;
+	
+	/* validate key size */
+	if((keySizeInBits < DSA_MIN_KEY_SIZE) || 
+	   (keySizeInBits > DSA_MAX_KEY_SIZE) ||
+	   (keySizeInBits & DSA_KEY_BITS_MASK)) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH);
+	}
+	
+	/* seed from one of three sources */
+	if(inSeed == NULL) {
+		/* 20 random seed bytes */
+		session().getRandomBytes(SHA1_DIGEST_SIZE, seedBuf);
+		seedPtr = seedBuf;
+	}
+	else if(inSeedLen == SHA1_DIGEST_SIZE) {
+		/* perfect */
+		seedPtr = (void *)inSeed;
+	}
+	else {
+		/* hash caller's seed */
+		cspGenSha1Hash(inSeed, inSeedLen, seedBuf);
+		seedPtr = seedBuf;
+	}
+
+	DSA *dsaKey = DSA_generate_parameters(keySizeInBits,
+		(unsigned char *)seedPtr,	
+		SHA1_DIGEST_SIZE,
+		NULL,		// counter_ret
+		NULL,		// h_ret
+		NULL, 
+		NULL);
+	if(dsaKey == NULL) {
+		throwRsaDsa("DSA_generate_parameters");
+	}
+	
+	/* stuff dsaKey->[pqg] into a caller's DSAAlgParams */
+	bnToBigIntStr(dsaKey->p, algParams.p);
+	bnToBigIntStr(dsaKey->q, algParams.q);
+	bnToBigIntStr(dsaKey->g, algParams.g);
+	
+	DSA_free(dsaKey);
+}
+
+/***
+ *** DSA-style CSPKeyInfoProvider.
+ ***/
+DSAKeyInfoProvider::DSAKeyInfoProvider(
+	const CssmKey &cssmKey) :
+		CSPKeyInfoProvider(cssmKey)
+{
+	switch(cssmKey.algorithm()) {
+		case CSSM_ALGID_DSA:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	switch(cssmKey.keyClass()) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	/* OK, we'll handle this one */
+	return;
+}
+
+/* Given a raw key, cook up a Binary key */
+void DSAKeyInfoProvider::CssmKeyToBinary(
+	BinaryKey **binKey)
+{
+	*binKey = NULL;
+	DSA *dsaKey = NULL;
+	
+	/* first cook up an DSA key, then drop that into a BinaryKey */
+	dsaKey = rawCssmKeyToDsa(mKey);
+	DSABinaryKey *dsaBinKey = new DSABinaryKey(dsaKey);
+	*binKey = dsaBinKey;
+}
+		
+/* 
+ * Obtain key size in bits.
+ */
+void DSAKeyInfoProvider::QueryKeySizeInBits(
+	CSSM_KEY_SIZE &keySize)
+{
+	DSA *dsaKey = NULL;
+	
+	if(mKey.blobType() != CSSM_KEYBLOB_RAW) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
+	}
+	dsaKey = rawCssmKeyToDsa(mKey);
+	keySize.LogicalKeySizeInBits = BN_num_bits(dsaKey->p);
+	keySize.EffectiveKeySizeInBits = keySize.LogicalKeySizeInBits;
+	DSA_free(dsaKey);
+}
diff --git a/AppleCSP/RSA_DSA/RSA_DSA_keys.h b/AppleCSP/RSA_DSA/RSA_DSA_keys.h
new file mode 100644
index 00000000..8aff2600
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_DSA_keys.h
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_DSA_keys.h - key pair support for RSA/DSA
+ */
+ 
+#ifndef	_RSA_DSA_KEYS_H_
+#define _RSA_DSA_KEYS_H_
+
+#include <AppleCSP/AppleCSPContext.h>
+#include <AppleCSP/AppleCSPSession.h>
+#include <RSA_DSA/RSA_DSA_csp.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <Security/context.h>
+#include <opensslUtils/openRsaSnacc.h>
+#include <Security/appleoids.h>
+
+#define RSA_PUB_KEY_FORMAT		CSSM_KEYBLOB_RAW_FORMAT_PKCS1
+#define RSA_PRIV_KEY_FORMAT		CSSM_KEYBLOB_RAW_FORMAT_PKCS8
+
+#define DSA_PUB_KEY_FORMAT		CSSM_KEYBLOB_RAW_FORMAT_FIPS186
+#define DSA_PRIV_KEY_FORMAT		CSSM_KEYBLOB_RAW_FORMAT_FIPS186
+
+#define	DSA_MIN_KEY_SIZE		512
+#define DSA_MAX_KEY_SIZE		1024
+#define DSA_KEY_BITS_MASK		(64 - 1)	/* these bits must be zero */
+											/* i.e., aligned to 64 bits */
+/*
+ * RSA version of a BinaryKey.
+ */
+class RSABinaryKey : public BinaryKey {
+public:
+	RSABinaryKey(RSA *rsaKey = NULL);
+	~RSABinaryKey();
+	void generateKeyBlob(
+		CssmAllocator 		&allocator,
+		CssmData			&blob,
+		CSSM_KEYBLOB_FORMAT	&format);
+
+	RSA						*mRsaKey;
+};
+
+class RSAKeyPairGenContext : 
+	public AppleCSPContext, private AppleKeyPairGenContext  {
+public:
+	RSAKeyPairGenContext(
+		AppleCSPSession &session,
+		const Context &) :
+			AppleCSPContext(session) {}
+
+	~RSAKeyPairGenContext() { }
+	
+	/* no init functionality, but we need to implement it */
+	void init(
+		const Context &, 
+		bool) { }
+		
+	// this one is specified in, and called from, CSPFullPluginSession
+	void generate(
+		const Context 	&context, 
+		CssmKey 		&pubKey, 
+		CssmKey 		&privKey);
+		
+	// this one is specified in, and called from, AppleKeyPairGenContext
+	void generate(
+		const Context 	&context,
+		BinaryKey		&pubBinKey,	
+		BinaryKey		&privBinKey,
+		uint32			&keySize);
+	
+};	/* KeyPairGenContext */
+
+/*
+ * CSPKeyInfoProvider for RSA keys
+ */
+class RSAKeyInfoProvider : public CSPKeyInfoProvider 
+{
+public:
+	RSAKeyInfoProvider(
+		const CssmKey		&cssmKey);
+	~RSAKeyInfoProvider() { }
+	void CssmKeyToBinary(
+		BinaryKey			**binKey);	// RETURNED
+	void QueryKeySizeInBits(
+		CSSM_KEY_SIZE		&keySize);	// RETURNED
+};
+
+/*
+ * DSA version of a BinaryKey.
+ */
+class DSABinaryKey : public BinaryKey {
+public:
+	DSABinaryKey(DSA *dsaKey = NULL);
+	~DSABinaryKey();
+	void generateKeyBlob(
+		CssmAllocator 		&allocator,
+		CssmData			&blob,
+		CSSM_KEYBLOB_FORMAT	&format);
+
+	DSA						*mDsaKey;
+};
+
+class DSAKeyPairGenContext : 
+	public AppleCSPContext, private AppleKeyPairGenContext  {
+public:
+	DSAKeyPairGenContext(
+		AppleCSPSession &session,
+		const Context &) :
+			AppleCSPContext(session), mGenAttrs(NULL) {}
+
+	~DSAKeyPairGenContext() { freeGenAttrs(); }
+	
+	/* no init functionality, but we need to implement it */
+	void init(
+		const Context &, 
+		bool) { }
+		
+	// this one is specified in, and called from, CSPFullPluginSession
+	void generate(
+		const Context 	&context, 
+		CssmKey 		&pubKey, 
+		CssmKey 		&privKey);
+		
+	// this one is specified in, and called from, AppleKeyPairGenContext
+	void generate(
+		const Context 	&context,
+		BinaryKey		&pubBinKey,	
+		BinaryKey		&privBinKey,
+		uint32			&keySize);
+
+	// specified in, and called from, CSPFullPluginSessionÊ- generate parameters
+	void generate(
+		const Context 	&context, 
+		uint32 			bitSize,
+		CssmData 		&params,
+		uint32 			&attrCount, 
+		Context::Attr * &attrs);
+	
+	/*
+	 * Necessary to handle and deflect "context changed" notification which occurs
+	 * after the strange return from "generate parameters", when the plugin adds
+	 * the "returned" values to the Context.
+	 */
+	bool changed(const Context &context) { return true; }
+
+	void dsaGenParams(
+		uint32			keySizeInBits,
+		const void		*inSeed,			// optional
+		unsigned		inSeedLen,
+		DSAAlgParams	&algParams);
+	
+private:
+	/* gross hack to store attributes "returned" from GenParams */
+	Context::Attr		*mGenAttrs;
+	void				freeGenAttrs();
+};	/* KeyPairGenContext */
+
+/*
+ * CSPKeyInfoProvider for DSA keys
+ */
+class DSAKeyInfoProvider : public CSPKeyInfoProvider 
+{
+public:
+	DSAKeyInfoProvider(
+		const CssmKey		&cssmKey);
+	~DSAKeyInfoProvider() { }
+	void CssmKeyToBinary(
+		BinaryKey			**binKey);	// RETURNED
+	void QueryKeySizeInBits(
+		CSSM_KEY_SIZE		&keySize);	// RETURNED
+};
+
+#endif	/* _RSA_DSA_KEYS_H_ */
diff --git a/AppleCSP/RSA_DSA/RSA_DSA_signature.cpp b/AppleCSP/RSA_DSA/RSA_DSA_signature.cpp
new file mode 100644
index 00000000..f163fdfc
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_DSA_signature.cpp
@@ -0,0 +1,348 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_DSA_signature.cpp - openssl-based signature classes.  
+ */
+
+#include "RSA_DSA_signature.h"
+#include "RSA_DSA_utils.h"
+#include <stdexcept>
+#include <assert.h>
+#include <Security/debugging.h>
+#include <Security/cssmdata.h>
+#include <opensslUtils/opensslUtils.h>
+#include <opensslUtils/openRsaSnacc.h>
+
+#define rsaSigDebug(args...) 	debug("rsaSig", ## args)
+
+RSASigner::~RSASigner()
+{
+	if(mWeMallocdRsaKey) {
+		assert(mRsaKey != NULL);
+		RSA_free(mRsaKey);
+		mRsaKey = NULL;
+		mWeMallocdRsaKey = false;
+	}
+}
+	
+/* reusable init */
+void RSASigner::signerInit(
+	const Context 	&context,
+	bool			isSigning)
+{
+	setIsSigning(isSigning);
+	keyFromContext(context);
+	setInitFlag(true);
+}
+
+/* sign */
+void RSASigner::sign(
+	const void 		*data, 
+	size_t 			dataLen,
+	void			*sig,	
+	size_t			*sigLen)	/* IN/OUT */
+{
+	if(mRsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+
+	/* get encoded digest info */
+	CssmAutoData 	encodedInfo(alloc());
+	int irtn = generateDigestInfo(data,
+		dataLen,
+		digestAlg(),
+		encodedInfo,
+		RSA_size(mRsaKey));
+	if(irtn) {
+		rsaSigDebug("***digestInfo error\n");
+		throwOpensslErr(irtn);
+	}
+
+	/* signature := encrypted digest info */
+	irtn = RSA_private_encrypt(encodedInfo.length(), 
+		(unsigned char *)encodedInfo.data(),
+		(unsigned char *)sig, 
+		mRsaKey,
+		RSA_PKCS1_PADDING);
+	if(irtn < 0) {
+		throwRsaDsa("RSA_private_encrypt");
+	}
+	if((unsigned)irtn > *sigLen) {
+		rsaSigDebug("RSA_private_encrypt: sig overflow");
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	*sigLen = (unsigned)irtn;
+}
+
+/* verify */
+void RSASigner::verify(
+	const void 		*data, 
+	size_t 			dataLen,
+	const void		*sig,			
+	size_t			sigLen)
+{
+	const char *op = NULL;
+	bool throwSigVerify = false;
+	
+	if(mRsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+
+	/* get encoded digest info */
+	CssmAutoData 	encodedInfo(alloc());
+	int irtn = generateDigestInfo(data,
+		dataLen,
+		digestAlg(),
+		encodedInfo,
+		RSA_size(mRsaKey));
+	if(irtn) {
+		rsaSigDebug("***digestInfo error\n");
+		CssmError::throwMe(/* FIXME */CSSMERR_CSP_INTERNAL_ERROR);
+	}
+
+	/* malloc decrypted signature */
+	unsigned char *decryptSig = 
+		(unsigned char *)alloc().malloc(RSA_size(mRsaKey));
+	unsigned decryptSigLen;
+	
+	/* signature should be encrypted digest info; decrypt the signature  */
+	irtn = RSA_public_decrypt(sigLen, 
+		(unsigned char *)sig,
+		decryptSig, 
+		mRsaKey,
+		RSA_PKCS1_PADDING);
+	if(irtn < 0) {
+		op = "RSA_public_decrypt";
+		throwSigVerify = true;
+		goto abort;
+	}
+	decryptSigLen = (unsigned)irtn;
+	if(decryptSigLen != encodedInfo.length()) {
+		rsaSigDebug("***Decrypted signature length error (exp %ld, got %d)\n",
+			encodedInfo.length(), decryptSigLen);
+		throwSigVerify = true;
+		op = "RSA Sig length check";
+		goto abort;
+	}
+	if(memcmp(decryptSig, encodedInfo.data(), decryptSigLen)) {
+		rsaSigDebug("***Signature miscompare\n");
+		throwSigVerify = true;
+		op = "RSA Sig miscompare";
+		goto abort;
+	}
+	else {
+		irtn = 0;
+	}
+abort:
+	if(decryptSig != NULL) {
+		alloc().free(decryptSig);
+	}	
+	if(throwSigVerify) {
+		CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
+	}
+}
+		
+/* works for both, but only used for signing */
+size_t RSASigner::maxSigSize()
+{
+	if(mRsaKey == NULL) {
+		return 0;
+	}
+	return RSA_size(mRsaKey);
+}
+
+/* 
+ * obtain key from context, validate, convert to native RSA key
+ */
+void RSASigner::keyFromContext(
+	const Context 	&context)
+{
+	if(initFlag() && (mRsaKey != NULL)) {
+		/* reusing context, OK */
+		return;
+	}
+	
+	CSSM_KEYCLASS 	keyClass;
+	CSSM_KEYUSE		keyUse;
+	if(isSigning()) {
+		/* signing with private key */
+		keyClass = CSSM_KEYCLASS_PRIVATE_KEY; 
+		keyUse   = CSSM_KEYUSE_SIGN;
+	}
+	else {
+		/* verifying with public key */
+		keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+		keyUse   = CSSM_KEYUSE_VERIFY;
+	}
+	if(mRsaKey == NULL) {
+		mRsaKey = contextToRsaKey(context,
+			mSession,
+			keyClass,
+			keyUse,
+			mWeMallocdRsaKey);
+	}
+}
+
+DSASigner::~DSASigner()
+{
+	if(mWeMallocdDsaKey) {
+		assert(mDsaKey != NULL);
+		DSA_free(mDsaKey);
+		mDsaKey = NULL;
+		mWeMallocdDsaKey = false;
+	}
+}
+	
+/* reusable init */
+void DSASigner::signerInit(
+	const Context 	&context,
+	bool			isSigning)
+{
+	setIsSigning(isSigning);
+	keyFromContext(context);
+	setInitFlag(true);
+}
+
+/* sign */
+void DSASigner::sign(
+	const void 		*data, 
+	size_t 			dataLen,
+	void			*sig,	
+	size_t			*sigLen)	/* IN/OUT */
+{
+	if(mDsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	if(mDsaKey->priv_key == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	
+	/* get signature in internal format */
+	DSA_SIG *dsaSig = DSA_do_sign((unsigned char *)data, dataLen, mDsaKey);
+	if(dsaSig == NULL) {
+		throwRsaDsa("DSA_do_sign");
+	}
+	
+	/* DER encode the signature */
+	CssmAutoData 	encodedSig(alloc());
+	int irtn = DSASigEncode(dsaSig, encodedSig);
+	if(irtn) {
+		throwRsaDsa("DSASigEncode");
+	}
+	if(encodedSig.length() > *sigLen) {
+		throwRsaDsa("DSA sign overflow");
+	}
+	memmove(sig, encodedSig.data(), encodedSig.length());
+	*sigLen = encodedSig.length();
+	DSA_SIG_free(dsaSig);
+}
+
+/* verify */
+void DSASigner::verify(
+	const void 		*data, 
+	size_t 			dataLen,
+	const void		*sig,			
+	size_t			sigLen)
+{
+	bool 			throwSigVerify = false;
+	DSA_SIG 		*dsaSig = NULL;
+	CSSM_RETURN		crtn = CSSM_OK;
+	int					irtn;
+	
+	if(mDsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	if(mDsaKey->pub_key == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+
+	/* incoming sig is DER encoded....decode into internal format */
+	dsaSig = DSA_SIG_new();
+	crtn = DSASigDecode(dsaSig, sig, sigLen);
+	if(crtn) {
+		goto abort;
+	}
+
+	irtn = DSA_do_verify((unsigned char *)data, dataLen, dsaSig, mDsaKey);
+	if(!irtn) {
+		throwSigVerify = true;
+	}
+
+abort:
+	if(dsaSig != NULL) {
+		DSA_SIG_free(dsaSig);
+	}	
+	if(throwSigVerify) {
+		CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
+	}
+	else if(crtn) {
+		CssmError::throwMe(crtn);
+	}
+}
+		
+/* 
+ * Works for both, but only used for signing.
+ * DSA sig is a sequence of two 160-bit integers. 
+ */
+size_t DSASigner::maxSigSize()
+{
+	if(mDsaKey == NULL) {
+		return 0;
+	}
+	size_t outSize;
+	size_t sizeOfOneInt;
+	
+	sizeOfOneInt = (160 / 8) +		// the raw contents
+					1 +				// possible leading zero
+					2;				// tag + length (assume DER, not BER)
+	outSize = (2 * sizeOfOneInt) + 5;
+	return outSize;
+}
+
+/* 
+ * obtain key from context, validate, convert to native DSA key
+ */
+void DSASigner::keyFromContext(
+	const Context 	&context)
+{
+	if(initFlag() && (mDsaKey != NULL)) {
+		/* reusing context, OK */
+		return;
+	}
+	
+	CSSM_KEYCLASS 	keyClass;
+	CSSM_KEYUSE		keyUse;
+	if(isSigning()) {
+		/* signing with private key */
+		keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
+		keyUse   = CSSM_KEYUSE_SIGN;
+	}
+	else {
+		/* verifying with public key */
+		keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+		keyUse   = CSSM_KEYUSE_VERIFY;
+	}
+	if(mDsaKey == NULL) {
+		mDsaKey = contextToDsaKey(context,
+			mSession,
+			keyClass,
+			keyUse,
+			mWeMallocdDsaKey);
+	}
+}
diff --git a/AppleCSP/RSA_DSA/RSA_DSA_signature.h b/AppleCSP/RSA_DSA/RSA_DSA_signature.h
new file mode 100644
index 00000000..62ac9c74
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_DSA_signature.h
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_DSA_signature.h - openssl-based signature classes.  
+ */
+
+#ifndef	_RSA_DSA_SIGNATURE_H_
+#define _RSA_DSA_SIGNATURE_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <AppleCSP/RawSigner.h>
+#include <AppleCSP/AppleCSPSession.h>
+
+class RSASigner : public RawSigner {
+public:
+	RSASigner(
+		CssmAllocator	&alloc,
+		AppleCSPSession &session,
+		CSSM_ALGORITHMS	digestAlg) : 
+			RawSigner(alloc, digestAlg),
+			mRsaKey(NULL),
+			mWeMallocdRsaKey(false),
+			mSession(session) { }
+			
+	~RSASigner();
+	
+	/* reusable init */
+	void signerInit(
+		const Context 	&context,
+		bool			isSigning);
+	
+
+	/* sign */
+	void sign(
+		const void 		*data, 
+		size_t 			dataLen,
+		void			*sig,	
+		size_t			*sigLen);	/* IN/OUT */
+		
+	/* verify */
+	void verify(
+		const void 	*data, 
+		size_t 			dataLen,
+		const void		*sig,			
+		size_t			sigLen);	
+		
+	/* works for both, but only used for signing */
+	size_t maxSigSize();
+
+private:
+
+	/* 
+	 * obtain key from context, validate, convert to RSA key
+	 */
+	void keyFromContext(
+		const Context 	&context);
+
+	RSA					*mRsaKey;
+	bool				mWeMallocdRsaKey;
+	AppleCSPSession		&mSession;
+};
+
+class DSASigner : public RawSigner {
+public:
+	DSASigner(
+		CssmAllocator	&alloc,
+		AppleCSPSession &session,
+		CSSM_ALGORITHMS	digestAlg) : 
+			RawSigner(alloc, digestAlg),
+			mDsaKey(NULL),
+			mWeMallocdDsaKey(false),
+			mSession(session) { }
+			
+	~DSASigner();
+	
+	/* reusable init */
+	void signerInit(
+		const Context 	&context,
+		bool			isSigning);
+	
+
+	/* sign */
+	void sign(
+		const void 		*data, 
+		size_t 			dataLen,
+		void			*sig,	
+		size_t			*sigLen);	/* IN/OUT */
+		
+	/* verify */
+	void verify(
+		const void 	*data, 
+		size_t 			dataLen,
+		const void		*sig,			
+		size_t			sigLen);	
+		
+	/* works for both, but only used for signing */
+	size_t maxSigSize();
+
+private:
+
+	/* 
+	 * obtain key from context, validate, convert to DSA key
+	 */
+	void keyFromContext(
+		const Context 	&context);
+
+	DSA					*mDsaKey;
+	bool				mWeMallocdDsaKey;
+	AppleCSPSession		&mSession;
+};
+
+
+#endif	/* _RSA_DSA_SIGNATURE_H_ */
diff --git a/AppleCSP/RSA_DSA/RSA_DSA_utils.cpp b/AppleCSP/RSA_DSA/RSA_DSA_utils.cpp
new file mode 100644
index 00000000..30d723ee
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_DSA_utils.cpp
@@ -0,0 +1,365 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_DSA_utils.cpp
+ */
+
+#include "RSA_DSA_utils.h"
+#include "RSA_DSA_keys.h"
+#include <opensslUtils/openRsaSnacc.h>
+#include <Security/logging.h>
+#include <Security/debugging.h>
+#include <open_ssl/opensslUtils/opensslUtils.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/err.h>
+
+#define rsaMiscDebug(args...)	debug("rsaMisc", ## args)
+
+void throwRsaDsa(
+	const char *op)
+{
+	unsigned long e = logSslErrInfo(op);
+	CSSM_RETURN cerr = CSSM_OK;
+	
+	/* try to parse into something meaningful */
+	int reason = ERR_GET_REASON(e);
+	int lib = ERR_GET_LIB(e);
+	
+	/* first try the global ones */
+	switch(reason) {
+		case ERR_R_MALLOC_FAILURE:
+			cerr = CSSMERR_CSP_MEMORY_ERROR; break;
+		case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
+			/* internal */ break;
+		case ERR_R_PASSED_NULL_PARAMETER:
+			cerr = CSSMERR_CSP_INVALID_POINTER; break;
+		case ERR_R_NESTED_ASN1_ERROR:
+		case ERR_R_BAD_ASN1_OBJECT_HEADER:
+		case ERR_R_BAD_GET_ASN1_OBJECT_CALL:
+		case ERR_R_EXPECTING_AN_ASN1_SEQUENCE:
+		case ERR_R_ASN1_LENGTH_MISMATCH:
+		case ERR_R_MISSING_ASN1_EOS:
+			/* ASN - shouldn't happen, right? */
+			cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
+		default:
+			break;
+	}
+	if(cerr != CSSM_OK) {
+		CssmError::throwMe(cerr);
+	}
+	
+	/* now the lib-specific ones */
+	switch(lib) {
+		case ERR_R_BN_LIB:
+			/* all indicate serious internal error...right? */
+			cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
+		case ERR_R_RSA_LIB:
+			switch(reason) {
+				case RSA_R_ALGORITHM_MISMATCH:
+					cerr = CSSMERR_CSP_ALGID_MISMATCH; break;
+				case RSA_R_BAD_SIGNATURE:
+					cerr = CSSMERR_CSP_VERIFY_FAILED; break;
+				case RSA_R_DATA_TOO_LARGE:
+				case RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE:
+				case RSA_R_DATA_TOO_SMALL:
+				case RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE:
+				case RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY:
+					cerr = CSSMERR_CSP_INPUT_LENGTH_ERROR; break;
+				case RSA_R_KEY_SIZE_TOO_SMALL:
+					cerr = CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH; break;
+				case RSA_R_PADDING_CHECK_FAILED:
+					cerr = CSSMERR_CSP_INVALID_DATA; break;
+				case RSA_R_RSA_OPERATIONS_NOT_SUPPORTED:
+					cerr = CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED; break;
+				case RSA_R_UNKNOWN_ALGORITHM_TYPE:
+					cerr = CSSMERR_CSP_INVALID_ALGORITHM; break;
+				case RSA_R_WRONG_SIGNATURE_LENGTH:
+					cerr = CSSMERR_CSP_VERIFY_FAILED; break;
+				default:
+					cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
+			}
+			break;
+		case ERR_R_DSA_LIB:
+			switch(reason) {
+				case DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE:
+					cerr = CSSMERR_CSP_INPUT_LENGTH_ERROR; break;
+				default:
+					cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
+			}
+			break;
+		default:
+			cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
+	}
+	CssmError::throwMe(cerr);
+}
+	
+/*
+ * given an openssl-style error, throw appropriate CssmError.
+ */
+void throwOpensslErr(int irtn)
+{
+	/* FIXME */
+	CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+}
+
+/* 
+ * Given a Context:
+ * -- obtain CSSM key (there must only be one)
+ * -- validate keyClass
+ * -- validate keyUsage
+ * -- convert to RSA *, allocating the RSA key if necessary
+ */
+RSA *contextToRsaKey(
+	const Context 		&context,
+	AppleCSPSession	 	&session,
+	CSSM_KEYCLASS		keyClass,	  // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
+	CSSM_KEYUSE			usage,		  // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
+	bool				&mallocdKey)  // RETURNED
+{
+    CssmKey &cssmKey = 
+		context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
+	const CSSM_KEYHEADER &hdr = cssmKey.KeyHeader;
+	if(hdr.AlgorithmId != CSSM_ALGID_RSA) {
+		CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
+	}
+	if(hdr.KeyClass != keyClass) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	cspValidateIntendedKeyUsage(&hdr, usage);
+	return cssmKeyToRsa(cssmKey, session, mallocdKey);
+}
+/* 
+ * Convert a CssmKey to an RSA * key. May result in the creation of a new
+ * RSA (when cssmKey is a raw key); allocdKey is true in that case
+ * in which case the caller generally has to free the allocd key).
+ */
+RSA *cssmKeyToRsa(
+	const CssmKey	&cssmKey,
+	AppleCSPSession	&session,
+	bool			&allocdKey)		// RETURNED
+{
+	RSA *rsaKey = NULL;
+	allocdKey = false;
+	
+	const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
+	if(hdr->AlgorithmId != CSSM_ALGID_RSA) {
+		// someone else's key (should never happen)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	switch(hdr->BlobType) {
+		case CSSM_KEYBLOB_RAW:
+			rsaKey = rawCssmKeyToRsa(cssmKey);
+			allocdKey = true;
+			break;
+		case CSSM_KEYBLOB_REFERENCE:
+		{
+			BinaryKey &binKey = session.lookupRefKey(cssmKey);
+			RSABinaryKey *rsaBinKey = dynamic_cast<RSABinaryKey *>(&binKey);
+			/* this cast failing means that this is some other
+			 * kind of binary key */
+			if(rsaBinKey == NULL) {
+				rsaMiscDebug("cssmKeyToRsa: wrong BinaryKey subclass\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+			}
+			assert(rsaBinKey->mRsaKey != NULL);
+			rsaKey = rsaBinKey->mRsaKey;
+			break;
+		}
+		default:
+			CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
+	}
+	return rsaKey;
+}
+
+/* 
+ * Convert a raw CssmKey to a newly alloc'd RSA key.
+ */
+RSA *rawCssmKeyToRsa(
+	const CssmKey	&cssmKey)
+{
+	const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
+	bool isPub;
+	
+	assert(hdr->BlobType == CSSM_KEYBLOB_RAW); 
+	
+	if(hdr->AlgorithmId != CSSM_ALGID_RSA) {
+		// someone else's key (should never happen)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	switch(hdr->KeyClass) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			if(hdr->Format != RSA_PUB_KEY_FORMAT) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT);
+			}
+			isPub = true;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			if(hdr->Format != RSA_PRIV_KEY_FORMAT) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT);
+			}
+			isPub = false;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	
+	RSA *rsaKey = RSA_new();
+	if(rsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+	}
+	CSSM_RETURN crtn;
+	if(isPub) {
+		crtn = RSAPublicKeyDecode(rsaKey,
+			cssmKey.KeyData.Data, 
+			cssmKey.KeyData.Length);
+	}
+	else {
+		crtn = RSAPrivateKeyDecode(rsaKey, 
+			cssmKey.KeyData.Data, 
+			cssmKey.KeyData.Length);
+	}
+	if(crtn) {
+		CssmError::throwMe(crtn);
+	}
+	return rsaKey;
+}
+
+/* 
+ * Given a Context:
+ * -- obtain CSSM key (there must only be one)
+ * -- validate keyClass
+ * -- validate keyUsage
+ * -- convert to DSA *, allocating the DSA key if necessary
+ */
+DSA *contextToDsaKey(
+	const Context 		&context,
+	AppleCSPSession	 	&session,
+	CSSM_KEYCLASS		keyClass,	  // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
+	CSSM_KEYUSE			usage,		  // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
+	bool				&mallocdKey)  // RETURNED
+{
+    CssmKey &cssmKey = 
+		context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
+	const CSSM_KEYHEADER &hdr = cssmKey.KeyHeader;
+	if(hdr.AlgorithmId != CSSM_ALGID_DSA) {
+		CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
+	}
+	if(hdr.KeyClass != keyClass) {
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	cspValidateIntendedKeyUsage(&hdr, usage);
+	return cssmKeyToDsa(cssmKey, session, mallocdKey);
+}
+/* 
+ * Convert a CssmKey to an DSA * key. May result in the creation of a new
+ * DSA (when cssmKey is a raw key); allocdKey is true in that case
+ * in which case the caller generally has to free the allocd key).
+ */
+DSA *cssmKeyToDsa(
+	const CssmKey	&cssmKey,
+	AppleCSPSession	&session,
+	bool			&allocdKey)		// RETURNED
+{
+	DSA *dsaKey = NULL;
+	allocdKey = false;
+	
+	const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
+	if(hdr->AlgorithmId != CSSM_ALGID_DSA) {
+		// someone else's key (should never happen)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	switch(hdr->BlobType) {
+		case CSSM_KEYBLOB_RAW:
+			dsaKey = rawCssmKeyToDsa(cssmKey);
+			allocdKey = true;
+			break;
+		case CSSM_KEYBLOB_REFERENCE:
+		{
+			BinaryKey &binKey = session.lookupRefKey(cssmKey);
+			DSABinaryKey *dsaBinKey = dynamic_cast<DSABinaryKey *>(&binKey);
+			/* this cast failing means that this is some other
+			 * kind of binary key */
+			if(dsaBinKey == NULL) {
+				rsaMiscDebug("cssmKeyToDsa: wrong BinaryKey subclass\n");
+				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+			}
+			assert(dsaBinKey->mDsaKey != NULL);
+			dsaKey = dsaBinKey->mDsaKey;
+			break;
+		}
+		default:
+			CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
+	}
+	return dsaKey;
+}
+
+/* 
+ * Convert a raw CssmKey to a newly alloc'd DSA key.
+ */
+DSA *rawCssmKeyToDsa(
+	const CssmKey	&cssmKey)
+{
+	const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
+	bool isPub;
+	
+	assert(hdr->BlobType == CSSM_KEYBLOB_RAW); 
+	
+	if(hdr->AlgorithmId != CSSM_ALGID_DSA) {
+		// someone else's key (should never happen)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+	switch(hdr->KeyClass) {
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			if(hdr->Format != DSA_PUB_KEY_FORMAT) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT);
+			}
+			isPub = true;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			if(hdr->Format != DSA_PRIV_KEY_FORMAT) {
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT);
+			}
+			isPub = false;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
+	}
+	
+	DSA *dsaKey = DSA_new();
+	if(dsaKey == NULL) {
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+	}
+	CSSM_RETURN crtn;
+	if(isPub) {
+		crtn = DSAPublicKeyDecode(dsaKey,
+			cssmKey.KeyData.Data, 
+			cssmKey.KeyData.Length);
+	}
+	else {
+		crtn = DSAPrivateKeyDecode(dsaKey,
+			cssmKey.KeyData.Data, 
+			cssmKey.KeyData.Length);
+	}
+	if(crtn) {
+		CssmError::throwMe(crtn);
+	}
+	return dsaKey;
+}
diff --git a/AppleCSP/RSA_DSA/RSA_DSA_utils.h b/AppleCSP/RSA_DSA/RSA_DSA_utils.h
new file mode 100644
index 00000000..ec5a7193
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_DSA_utils.h
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_DSA_utils.h
+ */
+#ifndef	_RSA_DSA_UTILS_H_
+#define _RSA_DSA_UTILS_H_
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <AppleCSP/AppleCSPSession.h>
+#include <Security/context.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+void throwRsaDsa(
+	const char *op);
+	
+/*
+ * given an openssl-style error, throw appropriate CssmError.
+ */
+void throwOpensslErr(
+	int irtn);
+
+/* 
+ * Given a Context:
+ * -- obtain CSSM key (there must only be one)
+ * -- validate keyClass
+ * -- validate keyUsage
+ * -- convert to RSA *, allocating the RSA key if necessary
+ */
+RSA *contextToRsaKey(
+	const Context 		&context,
+	AppleCSPSession	 	&session,
+	CSSM_KEYCLASS		keyClass,	  // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
+	CSSM_KEYUSE			usage,		  // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
+	bool				&mallocdKey); // RETURNED
+
+/* 
+ * Convert a CssmKey to an RSA * key. May result in the creation of a new
+ * RSA (when cssmKey is a raw key); allocdKey is true in that case
+ * in which case the caller generally has to free the allocd key).
+ */
+RSA *cssmKeyToRsa(
+	const CssmKey	&cssmKey,
+	AppleCSPSession	&session,
+	bool			&allocdKey);	// RETURNED
+
+/* 
+ * Convert a raw CssmKey to a newly alloc'd RSA *.
+ */
+RSA *rawCssmKeyToRsa(
+	const CssmKey	&cssmKey);
+
+/* 
+ * Given a Context:
+ * -- obtain CSSM key (there must only be one)
+ * -- validate keyClass
+ * -- validate keyUsage
+ * -- convert to DSA *, allocating the DSA key if necessary
+ */
+DSA *contextToDsaKey(
+	const Context 		&context,
+	AppleCSPSession	 	&session,
+	CSSM_KEYCLASS		keyClass,	  // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
+	CSSM_KEYUSE			usage,		  // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
+	bool				&mallocdKey); // RETURNED
+
+/* 
+ * Convert a CssmKey to an DSA * key. May result in the creation of a new
+ * DSA (when cssmKey is a raw key); allocdKey is true in that case
+ * in which case the caller generally has to free the allocd key).
+ */
+DSA *cssmKeyToDsa(
+	const CssmKey	&cssmKey,
+	AppleCSPSession	&session,
+	bool			&allocdKey);	// RETURNED
+
+/* 
+ * Convert a raw CssmKey to a newly alloc'd DSA *.
+ */
+DSA *rawCssmKeyToDsa(
+	const CssmKey	&cssmKey);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/*_RSA_DSA_UTILS_H_ */
\ No newline at end of file
diff --git a/AppleCSP/RSA_DSA/RSA_asymmetric.cpp b/AppleCSP/RSA_DSA/RSA_asymmetric.cpp
new file mode 100644
index 00000000..81012ffc
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_asymmetric.cpp
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_asymmetric.cpp - CSPContext for RSA asymmetric encryption
+ */
+ 
+#include "RSA_asymmetric.h"
+#include "RSA_DSA_utils.h"
+#include <Security/debugging.h>
+
+#define rsaCryptDebug(args...)	debug("rsaCrypt", ## args)
+#define rbprintf(args...)		debug("rsaBuf", ## args)
+
+RSA_CryptContext::~RSA_CryptContext()
+{
+	if(mAllocdRsaKey) {
+		assert(mRsaKey != NULL);
+		RSA_free(mRsaKey);
+		mRsaKey = NULL;
+		mAllocdRsaKey = false;
+	}
+}
+	
+/* called by CSPFullPluginSession */
+void RSA_CryptContext::init(const Context &context, bool encoding = true)
+{
+	if(mInitFlag && !opStarted()) {
+		/* reusing - e.g. query followed by encrypt */
+		return;
+	}
+
+	/* optional mode to use alternate key class (e.g., decrypt with public key) */
+	CSSM_KEYCLASS  keyClass;
+    switch (context.getInt(CSSM_ATTRIBUTE_MODE)) {
+        case CSSM_ALGMODE_PUBLIC_KEY:
+			keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+            break;
+        case CSSM_ALGMODE_PRIVATE_KEY:
+			keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
+            break;
+        case CSSM_ALGMODE_NONE:	
+			/* default, not present in context: infer from op type */
+			keyClass = encoding ? CSSM_KEYCLASS_PUBLIC_KEY : CSSM_KEYCLASS_PRIVATE_KEY;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
+	}
+	
+	/* fetch key from context */
+	if(mRsaKey == NULL) {
+		assert(!opStarted());
+		mRsaKey = contextToRsaKey(context,
+			session(),
+			keyClass,
+			encoding ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
+			mAllocdRsaKey);
+	}
+	else {
+		assert(opStarted());	
+	}
+
+	/* validate context - TBD */
+	
+	/* finally, have BlockCryptor set up its stuff. */
+	unsigned cipherBlockSize = RSA_size(mRsaKey);
+	unsigned plainBlockSize = cipherBlockSize - 11;
+	setup(encoding ? plainBlockSize  : cipherBlockSize, // blockSizeIn
+		  encoding ? cipherBlockSize : plainBlockSize,	// blockSizeOut
+		  false,										// pkcs5Pad
+		  false,										// needsFinal
+		  BCM_ECB,
+		  NULL);											// IV
+	mInitFlag = true;
+
+}
+/* called by BlockCryptor */
+void RSA_CryptContext::encryptBlock(
+	const void		*plainText,			// length implied (one block)
+	size_t			plainTextLen,
+	void			*cipherText,	
+	size_t			&cipherTextLen,		// in/out, throws on overflow
+	bool			final)
+{
+	int irtn;
+	
+	if(mRsaKey->d == NULL) {
+		irtn =	RSA_public_encrypt(plainTextLen, 
+			(unsigned char *)plainText,
+			(unsigned char *)cipherText, 
+			mRsaKey,
+			RSA_PKCS1_PADDING);
+	}
+	else {
+		irtn =	RSA_private_encrypt(plainTextLen, 
+			(unsigned char *)plainText,
+			(unsigned char *)cipherText, 
+			mRsaKey,
+			RSA_PKCS1_PADDING);
+	}
+	if(irtn < 0) {
+		throwRsaDsa("RSA_public_encrypt");
+	}
+	else if((unsigned)irtn > cipherTextLen) {
+		rsaCryptDebug("RSA_public_encrypt overflow");
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	cipherTextLen = (size_t)irtn;
+}
+
+void RSA_CryptContext::decryptBlock(
+	const void		*cipherText,		// length implied (one cipher block)
+	void			*plainText,	
+	size_t			&plainTextLen,		// in/out, throws on overflow
+	bool			final)
+{
+	int irtn;
+	
+	if(mRsaKey->d == NULL) {
+		irtn = RSA_public_decrypt(inBlockSize(), 
+			(unsigned char *)cipherText,
+			(unsigned char *)plainText, 
+			mRsaKey,
+			RSA_PKCS1_PADDING);
+	}
+	else {
+		irtn = RSA_private_decrypt(inBlockSize(), 
+			(unsigned char *)cipherText,
+			(unsigned char *)plainText, 
+			mRsaKey,
+			RSA_PKCS1_PADDING);
+	}
+	if(irtn < 0) {
+		throwRsaDsa("RSA_private_decrypt");
+	}
+	else if((unsigned)irtn > plainTextLen) {
+		rsaCryptDebug("RSA_private_decrypt overflow");
+		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+	}
+	plainTextLen = (size_t)irtn;
+}
+
+size_t RSA_CryptContext::outputSize(
+	bool 			final,				// ignored
+	size_t 			inSize = 0) 		// output for given input size
+{
+	UInt32 rawBytes = inSize + inBufSize();
+	UInt32 rawBlocks = (rawBytes + inBlockSize() - 1) / inBlockSize();
+	rbprintf("--- RSA_CryptContext::outputSize inSize 0x%lx outSize 0x%lx mInBufSize 0x%lx",
+		inSize, rawBlocks * outBlockSize(), inBufSize());
+	return rawBlocks * outBlockSize();
+}
diff --git a/AppleCSP/RSA_DSA/RSA_asymmetric.h b/AppleCSP/RSA_DSA/RSA_asymmetric.h
new file mode 100644
index 00000000..3cbb4d75
--- /dev/null
+++ b/AppleCSP/RSA_DSA/RSA_asymmetric.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * RSA_asymmetric.h - CSPContext for RSA asymmetric encryption
+ */
+
+#ifndef _RSA_ASYMMETRIC_H_
+#define _RSA_ASYMMETRIC_H_
+
+#include <Security/CSPsession.h>
+#include <AppleCSP/AppleCSP.h>
+#include <AppleCSP/AppleCSPContext.h>
+#include <AppleCSP/AppleCSPSession.h>
+#include <AppleCSP/BlockCryptor.h>
+#include <openssl/rsa.h>
+
+class RSA_CryptContext : public BlockCryptor {
+public:
+	RSA_CryptContext(AppleCSPSession &session) :
+		BlockCryptor(session),
+		mRsaKey(NULL),
+		mAllocdRsaKey(false),
+		mInitFlag(false) 	{ }
+		
+	~RSA_CryptContext();
+	
+	/* called by CSPFullPluginSession */
+	void init(const Context &context, bool encoding = true);
+
+	/* called by BlockCryptor */
+	void encryptBlock(
+		const void		*plainText,			// length implied (one block)
+		size_t			plainTextLen,
+		void			*cipherText,	
+		size_t			&cipherTextLen,		// in/out, throws on overflow
+		bool			final);
+	void decryptBlock(
+		const void		*cipherText,		// length implied (one cipher block)
+		void			*plainText,	
+		size_t			&plainTextLen,		// in/out, throws on overflow
+		bool			final);
+
+	size_t RSA_CryptContext::outputSize(
+		bool 			final,				// ignored
+		size_t 			inSize = 0); 		// output for given input size
+
+private:
+		RSA				*mRsaKey;
+		bool			mAllocdRsaKey;
+		bool			mInitFlag;			// allows easy reuse
+};	/* RSA_CryptContext */
+
+
+#endif // _RSA_ASYMMETRIC_H_
diff --git a/AppleCSP/TODO b/AppleCSP/TODO
new file mode 100644
index 00000000..cbdab795
--- /dev/null
+++ b/AppleCSP/TODO
@@ -0,0 +1 @@
+Things TODO in AppleCSPDL
diff --git a/AppleCSP/open_ssl/bio/bio_lib.c b/AppleCSP/open_ssl/bio/bio_lib.c
new file mode 100644
index 00000000..4040be73
--- /dev/null
+++ b/AppleCSP/open_ssl/bio/bio_lib.c
@@ -0,0 +1,552 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bio/bio_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/stack.h>
+
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *bio_meth=NULL;
+static int bio_meth_num=0;
+
+BIO *BIO_new(const BIO_METHOD *method)
+	{
+	BIO *ret=NULL;
+
+	ret=(BIO *)Malloc(sizeof(BIO));
+	if (ret == NULL)
+		{
+		BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	if (!BIO_set(ret,method))
+		{
+		Free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
+int BIO_set(BIO *bio, const BIO_METHOD *method)
+	{
+	bio->method=method;
+	bio->callback=NULL;
+	bio->cb_arg=NULL;
+	bio->init=0;
+	bio->shutdown=1;
+	bio->flags=0;
+	bio->retry_reason=0;
+	bio->num=0;
+	bio->ptr=NULL;
+	bio->prev_bio=NULL;
+	bio->next_bio=NULL;
+	bio->references=1;
+	bio->num_read=0L;
+	bio->num_write=0L;
+	CRYPTO_new_ex_data(bio_meth,bio,&bio->ex_data);
+	if (method->create != NULL)
+		if (!method->create(bio))
+			return(0);
+	return(1);
+	}
+
+int BIO_free(BIO *a)
+	{
+	int ret=0,i;
+
+	if (a == NULL) return(0);
+
+	i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
+#ifdef REF_PRINT
+	REF_PRINT("BIO",a);
+#endif
+	if (i > 0) return(1);
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"BIO_free, bad reference count\n");
+		abort();
+		}
+#endif
+	if ((a->callback != NULL) &&
+		((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0))
+			return(i);
+
+	CRYPTO_free_ex_data(bio_meth,a,&a->ex_data);
+
+	if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
+	ret=a->method->destroy(a);
+	Free(a);
+	return(1);
+	}
+
+int BIO_read(BIO *b, void *out, int outl)
+	{
+	int i;
+	long (*cb)();
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL))
+		{
+		BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+	if ((cb != NULL) &&
+		((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
+			return(i);
+
+	if (!b->init)
+		{
+		BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED);
+		return(-2);
+		}
+
+	i=b->method->bread(b,out,outl);
+
+	if (i > 0) b->num_read+=(unsigned long)i;
+
+	if (cb != NULL)
+		i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
+			0L,(long)i);
+	return(i);
+	}
+
+int BIO_write(BIO *b, const void *in, int inl)
+	{
+	int i;
+	long (*cb)();
+
+	if (b == NULL)
+		return(0);
+
+	cb=b->callback;
+	if ((b->method == NULL) || (b->method->bwrite == NULL))
+		{
+		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	if ((cb != NULL) &&
+		((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
+			return(i);
+
+	if (!b->init)
+		{
+		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED);
+		return(-2);
+		}
+
+	i=b->method->bwrite(b,in,inl);
+
+	if (i > 0) b->num_write+=(unsigned long)i;
+
+	/* This is evil and not thread safe.  If the BIO has been freed,
+	 * we must not call the callback.  The only way to be able to
+	 * determine this is the reference count which is now invalid since
+	 * the memory has been free()ed.
+	 */
+	if (b->references <= 0) abort();
+	if (cb != NULL) /* && (b->references >= 1)) */
+		i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
+			0L,(long)i);
+	return(i);
+	}
+
+int BIO_puts(BIO *b, const char *in)
+	{
+	int i;
+	long (*cb)();
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
+		{
+		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+
+	if ((cb != NULL) &&
+		((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
+			return(i);
+
+	if (!b->init)
+		{
+		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED);
+		return(-2);
+		}
+
+	i=b->method->bputs(b,in);
+
+	if (cb != NULL)
+		i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
+			0L,(long)i);
+	return(i);
+	}
+
+int BIO_gets(BIO *b, char *in, int inl)
+	{
+	int i;
+	long (*cb)();
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
+		{
+		BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+
+	if ((cb != NULL) &&
+		((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
+			return(i);
+
+	if (!b->init)
+		{
+		BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);
+		return(-2);
+		}
+
+	i=b->method->bgets(b,in,inl);
+
+	if (cb != NULL)
+		i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
+			0L,(long)i);
+	return(i);
+	}
+
+long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
+	{
+	int i;
+
+	i=iarg;
+	return(BIO_ctrl(b,cmd,larg,(char *)&i));
+	}
+
+char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
+	{
+	char *p=NULL;
+
+	if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
+		return(NULL);
+	else
+		return(p);
+	}
+
+long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
+	{
+	long ret;
+	long (*cb)();
+
+	if (b == NULL) return(0);
+
+	if ((b->method == NULL) || (b->method->ctrl == NULL))
+		{
+		BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+
+	if ((cb != NULL) &&
+		((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
+		return(ret);
+
+	ret=b->method->ctrl(b,cmd,larg,parg);
+
+	if (cb != NULL)
+		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
+			larg,ret);
+	return(ret);
+	}
+
+long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)())
+	{
+	long ret;
+	long (*cb)();
+
+	if (b == NULL) return(0);
+
+	if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
+		{
+		BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
+		return(-2);
+		}
+
+	cb=b->callback;
+
+	if ((cb != NULL) &&
+		((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
+		return(ret);
+
+	ret=b->method->callback_ctrl(b,cmd,fp);
+
+	if (cb != NULL)
+		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
+			0,ret);
+	return(ret);
+	}
+
+/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
+ * do; but those macros have inappropriate return type, and for interfacing
+ * from other programming languages, C macros aren't much of a help anyway. */
+size_t BIO_ctrl_pending(BIO *bio)
+	{
+	return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
+	}
+
+size_t BIO_ctrl_wpending(BIO *bio)
+	{
+	return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
+	}
+
+
+/* put the 'bio' on the end of b's list of operators */
+BIO *BIO_push(BIO *b, BIO *bio)
+	{
+	BIO *lb;
+
+	if (b == NULL) return(bio);
+	lb=b;
+	while (lb->next_bio != NULL)
+		lb=lb->next_bio;
+	lb->next_bio=bio;
+	if (bio != NULL)
+		bio->prev_bio=lb;
+	/* called to do internal processing */
+	BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL);
+	return(b);
+	}
+
+/* Remove the first and return the rest */
+BIO *BIO_pop(BIO *b)
+	{
+	BIO *ret;
+
+	if (b == NULL) return(NULL);
+	ret=b->next_bio;
+
+	if (b->prev_bio != NULL)
+		b->prev_bio->next_bio=b->next_bio;
+	if (b->next_bio != NULL)
+		b->next_bio->prev_bio=b->prev_bio;
+
+	b->next_bio=NULL;
+	b->prev_bio=NULL;
+	BIO_ctrl(b,BIO_CTRL_POP,0,NULL);
+	return(ret);
+	}
+
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
+	{
+	BIO *b,*last;
+
+	b=last=bio;
+	for (;;)
+		{
+		if (!BIO_should_retry(b)) break;
+		last=b;
+		b=b->next_bio;
+		if (b == NULL) break;
+		}
+	if (reason != NULL) *reason=last->retry_reason;
+	return(last);
+	}
+
+int BIO_get_retry_reason(BIO *bio)
+	{
+	return(bio->retry_reason);
+	}
+
+BIO *BIO_find_type(BIO *bio, int type)
+	{
+	int mt,mask;
+
+	mask=type&0xff;
+	do	{
+		if (bio->method != NULL)
+			{
+			mt=bio->method->type;
+
+			if (!mask)
+				{
+				if (mt & type) return(bio);
+				}
+			else if (mt == type)
+				return(bio);
+			}
+		bio=bio->next_bio;
+		} while (bio != NULL);
+	return(NULL);
+	}
+
+void BIO_free_all(BIO *bio)
+	{
+	BIO *b;
+	int ref;
+
+	while (bio != NULL)
+		{
+		b=bio;
+		ref=b->references;
+		bio=bio->next_bio;
+		BIO_free(b);
+		/* Since ref count > 1, don't free anyone else. */
+		if (ref > 1) break;
+		}
+	}
+
+BIO *BIO_dup_chain(BIO *in)
+	{
+	BIO *ret=NULL,*eoc=NULL,*bio,*new;
+
+	for (bio=in; bio != NULL; bio=bio->next_bio)
+		{
+		if ((new=BIO_new(bio->method)) == NULL) goto err;
+		new->callback=bio->callback;
+		new->cb_arg=bio->cb_arg;
+		new->init=bio->init;
+		new->shutdown=bio->shutdown;
+		new->flags=bio->flags;
+
+		/* This will let SSL_s_sock() work with stdin/stdout */
+		new->num=bio->num;
+
+		if (!BIO_dup_state(bio,(char *)new))
+			{
+			BIO_free(new);
+			goto err;
+			}
+
+		/* copy app data */
+		if (!CRYPTO_dup_ex_data(bio_meth,&new->ex_data,&bio->ex_data))
+			goto err;
+
+		if (ret == NULL)
+			{
+			eoc=new;
+			ret=eoc;
+			}
+		else
+			{
+			BIO_push(eoc,new);
+			eoc=new;
+			}
+		}
+	return(ret);
+err:
+	if (ret != NULL)
+		BIO_free(ret);
+	return(NULL);	
+	}
+
+void BIO_copy_next_retry(BIO *b)
+	{
+	BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
+	b->retry_reason=b->next_bio->retry_reason;
+	}
+
+int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+	{
+	bio_meth_num++;
+	return(CRYPTO_get_ex_new_index(bio_meth_num-1,&bio_meth,
+		argl,argp,new_func,dup_func,free_func));
+	}
+
+int BIO_set_ex_data(BIO *bio, int idx, void *data)
+	{
+	return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
+	}
+
+void *BIO_get_ex_data(BIO *bio, int idx)
+	{
+	return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
+	}
+
+unsigned long BIO_number_read(BIO *bio)
+{
+	if(bio) return bio->num_read;
+	return 0;
+}
+
+unsigned long BIO_number_written(BIO *bio)
+{
+	if(bio) return bio->num_write;
+	return 0;
+}
diff --git a/AppleCSP/open_ssl/bio/bss_file.c b/AppleCSP/open_ssl/bio/bss_file.c
new file mode 100644
index 00000000..97ad27b7
--- /dev/null
+++ b/AppleCSP/open_ssl/bio/bss_file.c
@@ -0,0 +1,328 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bio/bss_file.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * 03-Dec-1997	rdenny@dc3.com  Fix bug preventing use of stdin/stdout
+ *		with binary data (e.g. asn1parse -inform DER < xxx) under
+ *		Windows
+ */
+
+#ifndef HEADER_BSS_FILE_C
+#define HEADER_BSS_FILE_C
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#if !defined(NO_STDIO)
+
+static int MS_CALLBACK file_write(BIO *h,char *buf,int num);
+static int MS_CALLBACK file_read(BIO *h,char *buf,int size);
+static int MS_CALLBACK file_puts(BIO *h,char *str);
+static int MS_CALLBACK file_gets(BIO *h,char *str,int size);
+static long MS_CALLBACK file_ctrl(BIO *h,int cmd,long arg1,char *arg2);
+static int MS_CALLBACK file_new(BIO *h);
+static int MS_CALLBACK file_free(BIO *data);
+static const BIO_METHOD methods_filep=
+	{
+	BIO_TYPE_FILE,
+	"FILE pointer",
+	file_write,
+	file_read,
+	file_puts,
+	file_gets,
+	file_ctrl,
+	file_new,
+	file_free,
+	NULL,
+	};
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+	{
+	BIO *ret;
+	FILE *file;
+
+	if ((file=fopen(filename,mode)) == NULL)
+		{
+		SYSerr(SYS_F_FOPEN,get_last_sys_error());
+		ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
+		BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
+		return(NULL);
+		}
+	if ((ret=BIO_new(BIO_s_file_internal())) == NULL)
+		return(NULL);
+
+	BIO_set_fp(ret,file,BIO_CLOSE);
+	return(ret);
+	}
+
+BIO *BIO_new_fp(FILE *stream, int close_flag)
+	{
+	BIO *ret;
+
+	if ((ret=BIO_new(BIO_s_file())) == NULL)
+		return(NULL);
+
+	BIO_set_fp(ret,stream,close_flag);
+	return(ret);
+	}
+
+const BIO_METHOD *BIO_s_file(void)
+	{
+	return(&methods_filep);
+	}
+
+static int MS_CALLBACK file_new(BIO *bi)
+	{
+	bi->init=0;
+	bi->num=0;
+	bi->ptr=NULL;
+	return(1);
+	}
+
+static int MS_CALLBACK file_free(BIO *a)
+	{
+	if (a == NULL) return(0);
+	if (a->shutdown)
+		{
+		if ((a->init) && (a->ptr != NULL))
+			{
+			fclose((FILE *)a->ptr);
+			a->ptr=NULL;
+			}
+		a->init=0;
+		}
+	return(1);
+	}
+	
+static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
+	{
+	int ret=0;
+
+	if (b->init && (out != NULL))
+		{
+		ret=fread(out,1,(int)outl,(FILE *)b->ptr);
+		}
+	return(ret);
+	}
+
+static int MS_CALLBACK file_write(BIO *b, char *in, int inl)
+	{
+	int ret=0;
+
+	if (b->init && (in != NULL))
+		{
+		if (fwrite(in,(int)inl,1,(FILE *)b->ptr))
+			ret=inl;
+		/* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
+		/* according to Tim Hudson <tjh@cryptsoft.com>, the commented
+		 * out version above can cause 'inl' write calls under
+		 * some stupid stdio implementations (VMS) */
+		}
+	return(ret);
+	}
+
+static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, char *ptr)
+	{
+	long ret=1;
+	FILE *fp=(FILE *)b->ptr;
+	FILE **fpp;
+	char p[4];
+
+	switch (cmd)
+		{
+	case BIO_C_FILE_SEEK:
+	case BIO_CTRL_RESET:
+		ret=(long)fseek(fp,num,0);
+		break;
+	case BIO_CTRL_EOF:
+		ret=(long)feof(fp);
+		break;
+	case BIO_C_FILE_TELL:
+	case BIO_CTRL_INFO:
+		ret=ftell(fp);
+		break;
+	case BIO_C_SET_FILE_PTR:
+		file_free(b);
+		b->shutdown=(int)num&BIO_CLOSE;
+		b->ptr=(char *)ptr;
+		b->init=1;
+#if defined(MSDOS) || defined(WINDOWS)
+		/* Set correct text/binary mode */
+		if (num & BIO_FP_TEXT)
+			_setmode(fileno((FILE *)ptr),_O_TEXT);
+		else
+			_setmode(fileno((FILE *)ptr),_O_BINARY);
+#endif
+		break;
+	case BIO_C_SET_FILENAME:
+		file_free(b);
+		b->shutdown=(int)num&BIO_CLOSE;
+		if (num & BIO_FP_APPEND)
+			{
+			if (num & BIO_FP_READ)
+				strcpy(p,"a+");
+			else	strcpy(p,"a");
+			}
+		else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
+			strcpy(p,"r+");
+		else if (num & BIO_FP_WRITE)
+			strcpy(p,"w");
+		else if (num & BIO_FP_READ)
+			strcpy(p,"r");
+		else
+			{
+			BIOerr(BIO_F_FILE_CTRL,BIO_R_BAD_FOPEN_MODE);
+			ret=0;
+			break;
+			}
+#if defined(MSDOS) || defined(WINDOWS)
+		if (!(num & BIO_FP_TEXT))
+			strcat(p,"b");
+		else
+			strcat(p,"t");
+#endif
+		fp=fopen(ptr,p);
+		if (fp == NULL)
+			{
+			SYSerr(SYS_F_FOPEN,get_last_sys_error());
+			ERR_add_error_data(5,"fopen('",ptr,"','",p,"')");
+			BIOerr(BIO_F_FILE_CTRL,ERR_R_SYS_LIB);
+			ret=0;
+			break;
+			}
+		b->ptr=(char *)fp;
+		b->init=1;
+		break;
+	case BIO_C_GET_FILE_PTR:
+		/* the ptr parameter is actually a FILE ** in this case. */
+		if (ptr != NULL)
+			{
+			fpp=(FILE **)ptr;
+			*fpp=(FILE *)b->ptr;
+			}
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret=(long)b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown=(int)num;
+		break;
+	case BIO_CTRL_FLUSH:
+		fflush((FILE *)b->ptr);
+		break;
+	case BIO_CTRL_DUP:
+		ret=1;
+		break;
+
+	case BIO_CTRL_WPENDING:
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_PUSH:
+	case BIO_CTRL_POP:
+	default:
+		ret=0;
+		break;
+		}
+	return(ret);
+	}
+
+static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
+	{
+	int ret=0;
+
+	buf[0]='\0';
+	fgets(buf,size,(FILE *)bp->ptr);
+	if (buf[0] != '\0')
+		ret=strlen(buf);
+	return(ret);
+	}
+
+static int MS_CALLBACK file_puts(BIO *bp, char *str)
+	{
+	int n,ret;
+
+	n=strlen(str);
+	ret=file_write(bp,str,n);
+	return(ret);
+	}
+
+#endif /* NO_STDIO */
+
+#endif /* HEADER_BSS_FILE_C */
+
+
diff --git a/AppleCSP/open_ssl/bn/bn_add.c b/AppleCSP/open_ssl/bn/bn_add.c
new file mode 100644
index 00000000..3abd7499
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_add.c
@@ -0,0 +1,325 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_add.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	const BIGNUM *tmp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	/*  a +  b	a+b
+	 *  a + -b	a-b
+	 * -a +  b	b-a
+	 * -a + -b	-(a+b)
+	 */
+	if (a->neg ^ b->neg)
+		{
+		/* only one is negative */
+		if (a->neg)
+			{ tmp=a; a=b; b=tmp; }
+
+		/* we are now a - b */
+
+		if (BN_ucmp(a,b) < 0)
+			{
+			if (!BN_usub(r,b,a)) return(0);
+			r->neg=1;
+			}
+		else
+			{
+			if (!BN_usub(r,a,b)) return(0);
+			r->neg=0;
+			}
+		return(1);
+		}
+
+	if (a->neg) /* both are neg */
+		r->neg=1;
+	else
+		r->neg=0;
+
+	if (!BN_uadd(r,a,b)) return(0);
+	return(1);
+	}
+
+/* unsigned add of b to a, r must be large enough */
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	register int i;
+	int max,min;
+	BN_ULONG *ap,*bp,*rp,carry,t1;
+	const BIGNUM *tmp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->top < b->top)
+		{ tmp=a; a=b; b=tmp; }
+	max=a->top;
+	min=b->top;
+
+	if (bn_wexpand(r,max+1) == NULL)
+		return(0);
+
+	r->top=max;
+
+
+	ap=a->d;
+	bp=b->d;
+	rp=r->d;
+	carry=0;
+
+	carry=bn_add_words(rp,ap,bp,min);
+	rp+=min;
+	ap+=min;
+	bp+=min;
+	i=min;
+
+	if (carry)
+		{
+		while (i < max)
+			{
+			i++;
+			t1= *(ap++);
+			if ((*(rp++)=(t1+1)&BN_MASK2) >= t1)
+				{
+				carry=0;
+				break;
+				}
+			}
+		if ((i >= max) && carry)
+			{
+			*(rp++)=1;
+			r->top++;
+			}
+		}
+	if (rp != ap)
+		{
+		for (; i<max; i++)
+			*(rp++)= *(ap++);
+		}
+	/* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
+	return(1);
+	}
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	int max,min;
+	register BN_ULONG t1,t2,*ap,*bp,*rp;
+	int i,carry;
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+	int dummy;
+#endif
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->top < b->top) /* hmm... should not be happening */
+		{
+		BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
+		return(0);
+		}
+
+	max=a->top;
+	min=b->top;
+	if (bn_wexpand(r,max) == NULL) return(0);
+
+	ap=a->d;
+	bp=b->d;
+	rp=r->d;
+
+#if 1
+	carry=0;
+	for (i=0; i<min; i++)
+		{
+		t1= *(ap++);
+		t2= *(bp++);
+		if (carry)
+			{
+			carry=(t1 <= t2);
+			t1=(t1-t2-1)&BN_MASK2;
+			}
+		else
+			{
+			carry=(t1 < t2);
+			t1=(t1-t2)&BN_MASK2;
+			}
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+		dummy=t1;
+#endif
+		*(rp++)=t1&BN_MASK2;
+		}
+#else
+	carry=bn_sub_words(rp,ap,bp,min);
+	ap+=min;
+	bp+=min;
+	rp+=min;
+	i=min;
+#endif
+	if (carry) /* subtracted */
+		{
+		while (i < max)
+			{
+			i++;
+			t1= *(ap++);
+			t2=(t1-1)&BN_MASK2;
+			*(rp++)=t2;
+			if (t1 > t2) break;
+			}
+		}
+#if 0
+	memcpy(rp,ap,sizeof(*rp)*(max-i));
+#else
+	if (rp != ap)
+		{
+		for (;;)
+			{
+			if (i++ >= max) break;
+			rp[0]=ap[0];
+			if (i++ >= max) break;
+			rp[1]=ap[1];
+			if (i++ >= max) break;
+			rp[2]=ap[2];
+			if (i++ >= max) break;
+			rp[3]=ap[3];
+			rp+=4;
+			ap+=4;
+			}
+		}
+#endif
+
+	r->top=max;
+	bn_fix_top(r);
+	return(1);
+	}
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+	{
+	int max;
+	int add=0,neg=0;
+	const BIGNUM *tmp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	/*  a -  b	a-b
+	 *  a - -b	a+b
+	 * -a -  b	-(a+b)
+	 * -a - -b	b-a
+	 */
+	if (a->neg)
+		{
+		if (b->neg)
+			{ tmp=a; a=b; b=tmp; }
+		else
+			{ add=1; neg=1; }
+		}
+	else
+		{
+		if (b->neg) { add=1; neg=0; }
+		}
+
+	if (add)
+		{
+		if (!BN_uadd(r,a,b)) return(0);
+		r->neg=neg;
+		return(1);
+		}
+
+	/* We are actually doing a - b :-) */
+
+	max=(a->top > b->top)?a->top:b->top;
+	if (bn_wexpand(r,max) == NULL) return(0);
+	if (BN_ucmp(a,b) < 0)
+		{
+		if (!BN_usub(r,b,a)) return(0);
+		r->neg=1;
+		}
+	else
+		{
+		if (!BN_usub(r,a,b)) return(0);
+		r->neg=0;
+		}
+	return(1);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_asm.c b/AppleCSP/open_ssl/bn/bn_asm.c
new file mode 100644
index 00000000..d5c137f3
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_asm.c
@@ -0,0 +1,855 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_asm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG c1=0;
+
+	assert(num >= 0);
+	if (num <= 0) return(c1);
+
+	while (num&~3)
+		{
+		mul_add(rp[0],ap[0],w,c1);
+		mul_add(rp[1],ap[1],w,c1);
+		mul_add(rp[2],ap[2],w,c1);
+		mul_add(rp[3],ap[3],w,c1);
+		ap+=4; rp+=4; num-=4;
+		}
+	if (num)
+		{
+		mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
+		mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
+		mul_add(rp[2],ap[2],w,c1); return c1;
+		}
+	
+	return(c1);
+	} 
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG c1=0;
+
+	assert(num >= 0);
+	if (num <= 0) return(c1);
+
+	while (num&~3)
+		{
+		mul(rp[0],ap[0],w,c1);
+		mul(rp[1],ap[1],w,c1);
+		mul(rp[2],ap[2],w,c1);
+		mul(rp[3],ap[3],w,c1);
+		ap+=4; rp+=4; num-=4;
+		}
+	if (num)
+		{
+		mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
+		mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
+		mul(rp[2],ap[2],w,c1);
+		}
+	return(c1);
+	} 
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+        {
+	assert(n >= 0);
+	if (n <= 0) return;
+	while (n&~3)
+		{
+		sqr(r[0],r[1],a[0]);
+		sqr(r[2],r[3],a[1]);
+		sqr(r[4],r[5],a[2]);
+		sqr(r[6],r[7],a[3]);
+		a+=4; r+=8; n-=4;
+		}
+	if (n)
+		{
+		sqr(r[0],r[1],a[0]); if (--n == 0) return;
+		sqr(r[2],r[3],a[1]); if (--n == 0) return;
+		sqr(r[4],r[5],a[2]);
+		}
+	}
+
+#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG c=0;
+	BN_ULONG bl,bh;
+
+	assert(num >= 0);
+	if (num <= 0) return((BN_ULONG)0);
+
+	bl=LBITS(w);
+	bh=HBITS(w);
+
+	for (;;)
+		{
+		mul_add(rp[0],ap[0],bl,bh,c);
+		if (--num == 0) break;
+		mul_add(rp[1],ap[1],bl,bh,c);
+		if (--num == 0) break;
+		mul_add(rp[2],ap[2],bl,bh,c);
+		if (--num == 0) break;
+		mul_add(rp[3],ap[3],bl,bh,c);
+		if (--num == 0) break;
+		ap+=4;
+		rp+=4;
+		}
+	return(c);
+	} 
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+	{
+	BN_ULONG carry=0;
+	BN_ULONG bl,bh;
+
+	assert(num >= 0);
+	if (num <= 0) return((BN_ULONG)0);
+
+	bl=LBITS(w);
+	bh=HBITS(w);
+
+	for (;;)
+		{
+		mul(rp[0],ap[0],bl,bh,carry);
+		if (--num == 0) break;
+		mul(rp[1],ap[1],bl,bh,carry);
+		if (--num == 0) break;
+		mul(rp[2],ap[2],bl,bh,carry);
+		if (--num == 0) break;
+		mul(rp[3],ap[3],bl,bh,carry);
+		if (--num == 0) break;
+		ap+=4;
+		rp+=4;
+		}
+	return(carry);
+	} 
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+        {
+	assert(n >= 0);
+	if (n <= 0) return;
+	for (;;)
+		{
+		sqr64(r[0],r[1],a[0]);
+		if (--n == 0) break;
+
+		sqr64(r[2],r[3],a[1]);
+		if (--n == 0) break;
+
+		sqr64(r[4],r[5],a[2]);
+		if (--n == 0) break;
+
+		sqr64(r[6],r[7],a[3]);
+		if (--n == 0) break;
+
+		a+=4;
+		r+=8;
+		}
+	}
+
+#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+	{
+	return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d));
+	}
+
+#else
+
+/* Divide h-l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+	{
+	BN_ULONG dh,dl,q,ret=0,th,tl,t;
+	int i,count=2;
+
+	if (d == 0) return(BN_MASK2);
+
+	i=BN_num_bits_word(d);
+	if ((i != BN_BITS2) && (h > (BN_ULONG)1<<i))
+		{
+#if !defined(NO_STDIO) && !defined(WIN16)
+		fprintf(stderr,"Division would overflow (%d)\n",i);
+#endif
+		abort();
+		}
+	i=BN_BITS2-i;
+	if (h >= d) h-=d;
+
+	if (i)
+		{
+		d<<=i;
+		h=(h<<i)|(l>>(BN_BITS2-i));
+		l<<=i;
+		}
+	dh=(d&BN_MASK2h)>>BN_BITS4;
+	dl=(d&BN_MASK2l);
+	for (;;)
+		{
+		if ((h>>BN_BITS4) == dh)
+			q=BN_MASK2l;
+		else
+			q=h/dh;
+
+		th=q*dh;
+		tl=dl*q;
+		for (;;)
+			{
+			t=h-th;
+			if ((t&BN_MASK2h) ||
+				((tl) <= (
+					(t<<BN_BITS4)|
+					((l&BN_MASK2h)>>BN_BITS4))))
+				break;
+			q--;
+			th-=dh;
+			tl-=dl;
+			}
+		t=(tl>>BN_BITS4);
+		tl=(tl<<BN_BITS4)&BN_MASK2h;
+		th+=t;
+
+		if (l < tl) th++;
+		l-=tl;
+		if (h < th)
+			{
+			h+=d;
+			q--;
+			}
+		h-=th;
+
+		if (--count == 0) break;
+
+		ret=q<<BN_BITS4;
+		h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2;
+		l=(l&BN_MASK2l)<<BN_BITS4;
+		}
+	ret|=q;
+	return(ret);
+	}
+#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+        {
+	BN_ULLONG ll=0;
+
+	assert(n >= 0);
+	if (n <= 0) return((BN_ULONG)0);
+
+	for (;;)
+		{
+		ll+=(BN_ULLONG)a[0]+b[0];
+		r[0]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		if (--n <= 0) break;
+
+		ll+=(BN_ULLONG)a[1]+b[1];
+		r[1]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		if (--n <= 0) break;
+
+		ll+=(BN_ULLONG)a[2]+b[2];
+		r[2]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		if (--n <= 0) break;
+
+		ll+=(BN_ULLONG)a[3]+b[3];
+		r[3]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		if (--n <= 0) break;
+
+		a+=4;
+		b+=4;
+		r+=4;
+		}
+	return((BN_ULONG)ll);
+	}
+#else /* !BN_LLONG */
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+        {
+	BN_ULONG c,l,t;
+
+	assert(n >= 0);
+	if (n <= 0) return((BN_ULONG)0);
+
+	c=0;
+	for (;;)
+		{
+		t=a[0];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[0])&BN_MASK2;
+		c+=(l < t);
+		r[0]=l;
+		if (--n <= 0) break;
+
+		t=a[1];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[1])&BN_MASK2;
+		c+=(l < t);
+		r[1]=l;
+		if (--n <= 0) break;
+
+		t=a[2];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[2])&BN_MASK2;
+		c+=(l < t);
+		r[2]=l;
+		if (--n <= 0) break;
+
+		t=a[3];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[3])&BN_MASK2;
+		c+=(l < t);
+		r[3]=l;
+		if (--n <= 0) break;
+
+		a+=4;
+		b+=4;
+		r+=4;
+		}
+	return((BN_ULONG)c);
+	}
+#endif /* !BN_LLONG */
+
+BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+        {
+	BN_ULONG t1,t2;
+	int c=0;
+
+	assert(n >= 0);
+	if (n <= 0) return((BN_ULONG)0);
+
+	for (;;)
+		{
+		t1=a[0]; t2=b[0];
+		r[0]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		if (--n <= 0) break;
+
+		t1=a[1]; t2=b[1];
+		r[1]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		if (--n <= 0) break;
+
+		t1=a[2]; t2=b[2];
+		r[2]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		if (--n <= 0) break;
+
+		t1=a[3]; t2=b[3];
+		r[3]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		if (--n <= 0) break;
+
+		a+=4;
+		b+=4;
+		r+=4;
+		}
+	return(c);
+	}
+
+#ifdef BN_MUL_COMBA
+
+#undef bn_mul_comba8
+#undef bn_mul_comba4
+#undef bn_sqr_comba8
+#undef bn_sqr_comba4
+
+/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
+/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
+#ifdef BN_LLONG
+#define mul_add_c(a,b,c0,c1,c2) \
+	t=(BN_ULLONG)a*b; \
+	t1=(BN_ULONG)Lw(t); \
+	t2=(BN_ULONG)Hw(t); \
+	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define mul_add_c2(a,b,c0,c1,c2) \
+	t=(BN_ULLONG)a*b; \
+	tt=(t+t)&BN_MASK; \
+	if (tt < t) c2++; \
+	t1=(BN_ULONG)Lw(tt); \
+	t2=(BN_ULONG)Hw(tt); \
+	c0=(c0+t1)&BN_MASK2;  \
+	if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c(a,i,c0,c1,c2) \
+	t=(BN_ULLONG)a[i]*a[i]; \
+	t1=(BN_ULONG)Lw(t); \
+	t2=(BN_ULONG)Hw(t); \
+	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+#elif defined(BN_UMULT_HIGH)
+
+#define mul_add_c(a,b,c0,c1,c2)	{	\
+	BN_ULONG ta=(a),tb=(b);		\
+	t1 = ta * tb;			\
+	t2 = BN_UMULT_HIGH(ta,tb);	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define mul_add_c2(a,b,c0,c1,c2) {	\
+	BN_ULONG ta=(a),tb=(b),t0;	\
+	t1 = BN_UMULT_HIGH(ta,tb);	\
+	t0 = ta * tb;			\
+	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
+	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define sqr_add_c(a,i,c0,c1,c2)	{	\
+	BN_ULONG ta=(a)[i];		\
+	t1 = ta * ta;			\
+	t2 = BN_UMULT_HIGH(ta,ta);	\
+	c0 += t1; t2 += (c0<t1)?1:0;	\
+	c1 += t2; c2 += (c1<t2)?1:0;	\
+	}
+
+#define sqr_add_c2(a,i,j,c0,c1,c2)	\
+	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+#else /* !BN_LLONG */
+#define mul_add_c(a,b,c0,c1,c2) \
+	t1=LBITS(a); t2=HBITS(a); \
+	bl=LBITS(b); bh=HBITS(b); \
+	mul64(t1,t2,bl,bh); \
+	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define mul_add_c2(a,b,c0,c1,c2) \
+	t1=LBITS(a); t2=HBITS(a); \
+	bl=LBITS(b); bh=HBITS(b); \
+	mul64(t1,t2,bl,bh); \
+	if (t2 & BN_TBIT) c2++; \
+	t2=(t2+t2)&BN_MASK2; \
+	if (t1 & BN_TBIT) t2++; \
+	t1=(t1+t1)&BN_MASK2; \
+	c0=(c0+t1)&BN_MASK2;  \
+	if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c(a,i,c0,c1,c2) \
+	sqr64(t1,t2,(a)[i]); \
+	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+#endif /* !BN_LLONG */
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+#ifdef BN_LLONG
+	BN_ULLONG t;
+#else
+	BN_ULONG bl,bh;
+#endif
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	mul_add_c(a[0],b[0],c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	mul_add_c(a[0],b[1],c2,c3,c1);
+	mul_add_c(a[1],b[0],c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	mul_add_c(a[2],b[0],c3,c1,c2);
+	mul_add_c(a[1],b[1],c3,c1,c2);
+	mul_add_c(a[0],b[2],c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	mul_add_c(a[0],b[3],c1,c2,c3);
+	mul_add_c(a[1],b[2],c1,c2,c3);
+	mul_add_c(a[2],b[1],c1,c2,c3);
+	mul_add_c(a[3],b[0],c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	mul_add_c(a[4],b[0],c2,c3,c1);
+	mul_add_c(a[3],b[1],c2,c3,c1);
+	mul_add_c(a[2],b[2],c2,c3,c1);
+	mul_add_c(a[1],b[3],c2,c3,c1);
+	mul_add_c(a[0],b[4],c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	mul_add_c(a[0],b[5],c3,c1,c2);
+	mul_add_c(a[1],b[4],c3,c1,c2);
+	mul_add_c(a[2],b[3],c3,c1,c2);
+	mul_add_c(a[3],b[2],c3,c1,c2);
+	mul_add_c(a[4],b[1],c3,c1,c2);
+	mul_add_c(a[5],b[0],c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	mul_add_c(a[6],b[0],c1,c2,c3);
+	mul_add_c(a[5],b[1],c1,c2,c3);
+	mul_add_c(a[4],b[2],c1,c2,c3);
+	mul_add_c(a[3],b[3],c1,c2,c3);
+	mul_add_c(a[2],b[4],c1,c2,c3);
+	mul_add_c(a[1],b[5],c1,c2,c3);
+	mul_add_c(a[0],b[6],c1,c2,c3);
+	r[6]=c1;
+	c1=0;
+	mul_add_c(a[0],b[7],c2,c3,c1);
+	mul_add_c(a[1],b[6],c2,c3,c1);
+	mul_add_c(a[2],b[5],c2,c3,c1);
+	mul_add_c(a[3],b[4],c2,c3,c1);
+	mul_add_c(a[4],b[3],c2,c3,c1);
+	mul_add_c(a[5],b[2],c2,c3,c1);
+	mul_add_c(a[6],b[1],c2,c3,c1);
+	mul_add_c(a[7],b[0],c2,c3,c1);
+	r[7]=c2;
+	c2=0;
+	mul_add_c(a[7],b[1],c3,c1,c2);
+	mul_add_c(a[6],b[2],c3,c1,c2);
+	mul_add_c(a[5],b[3],c3,c1,c2);
+	mul_add_c(a[4],b[4],c3,c1,c2);
+	mul_add_c(a[3],b[5],c3,c1,c2);
+	mul_add_c(a[2],b[6],c3,c1,c2);
+	mul_add_c(a[1],b[7],c3,c1,c2);
+	r[8]=c3;
+	c3=0;
+	mul_add_c(a[2],b[7],c1,c2,c3);
+	mul_add_c(a[3],b[6],c1,c2,c3);
+	mul_add_c(a[4],b[5],c1,c2,c3);
+	mul_add_c(a[5],b[4],c1,c2,c3);
+	mul_add_c(a[6],b[3],c1,c2,c3);
+	mul_add_c(a[7],b[2],c1,c2,c3);
+	r[9]=c1;
+	c1=0;
+	mul_add_c(a[7],b[3],c2,c3,c1);
+	mul_add_c(a[6],b[4],c2,c3,c1);
+	mul_add_c(a[5],b[5],c2,c3,c1);
+	mul_add_c(a[4],b[6],c2,c3,c1);
+	mul_add_c(a[3],b[7],c2,c3,c1);
+	r[10]=c2;
+	c2=0;
+	mul_add_c(a[4],b[7],c3,c1,c2);
+	mul_add_c(a[5],b[6],c3,c1,c2);
+	mul_add_c(a[6],b[5],c3,c1,c2);
+	mul_add_c(a[7],b[4],c3,c1,c2);
+	r[11]=c3;
+	c3=0;
+	mul_add_c(a[7],b[5],c1,c2,c3);
+	mul_add_c(a[6],b[6],c1,c2,c3);
+	mul_add_c(a[5],b[7],c1,c2,c3);
+	r[12]=c1;
+	c1=0;
+	mul_add_c(a[6],b[7],c2,c3,c1);
+	mul_add_c(a[7],b[6],c2,c3,c1);
+	r[13]=c2;
+	c2=0;
+	mul_add_c(a[7],b[7],c3,c1,c2);
+	r[14]=c3;
+	r[15]=c1;
+	}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+#ifdef BN_LLONG
+	BN_ULLONG t;
+#else
+	BN_ULONG bl,bh;
+#endif
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	mul_add_c(a[0],b[0],c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	mul_add_c(a[0],b[1],c2,c3,c1);
+	mul_add_c(a[1],b[0],c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	mul_add_c(a[2],b[0],c3,c1,c2);
+	mul_add_c(a[1],b[1],c3,c1,c2);
+	mul_add_c(a[0],b[2],c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	mul_add_c(a[0],b[3],c1,c2,c3);
+	mul_add_c(a[1],b[2],c1,c2,c3);
+	mul_add_c(a[2],b[1],c1,c2,c3);
+	mul_add_c(a[3],b[0],c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	mul_add_c(a[3],b[1],c2,c3,c1);
+	mul_add_c(a[2],b[2],c2,c3,c1);
+	mul_add_c(a[1],b[3],c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	mul_add_c(a[2],b[3],c3,c1,c2);
+	mul_add_c(a[3],b[2],c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	mul_add_c(a[3],b[3],c1,c2,c3);
+	r[6]=c1;
+	r[7]=c2;
+	}
+
+void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+	{
+#ifdef BN_LLONG
+	BN_ULLONG t,tt;
+#else
+	BN_ULONG bl,bh;
+#endif
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	sqr_add_c(a,0,c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	sqr_add_c2(a,1,0,c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	sqr_add_c(a,1,c3,c1,c2);
+	sqr_add_c2(a,2,0,c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	sqr_add_c2(a,3,0,c1,c2,c3);
+	sqr_add_c2(a,2,1,c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	sqr_add_c(a,2,c2,c3,c1);
+	sqr_add_c2(a,3,1,c2,c3,c1);
+	sqr_add_c2(a,4,0,c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	sqr_add_c2(a,5,0,c3,c1,c2);
+	sqr_add_c2(a,4,1,c3,c1,c2);
+	sqr_add_c2(a,3,2,c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	sqr_add_c(a,3,c1,c2,c3);
+	sqr_add_c2(a,4,2,c1,c2,c3);
+	sqr_add_c2(a,5,1,c1,c2,c3);
+	sqr_add_c2(a,6,0,c1,c2,c3);
+	r[6]=c1;
+	c1=0;
+	sqr_add_c2(a,7,0,c2,c3,c1);
+	sqr_add_c2(a,6,1,c2,c3,c1);
+	sqr_add_c2(a,5,2,c2,c3,c1);
+	sqr_add_c2(a,4,3,c2,c3,c1);
+	r[7]=c2;
+	c2=0;
+	sqr_add_c(a,4,c3,c1,c2);
+	sqr_add_c2(a,5,3,c3,c1,c2);
+	sqr_add_c2(a,6,2,c3,c1,c2);
+	sqr_add_c2(a,7,1,c3,c1,c2);
+	r[8]=c3;
+	c3=0;
+	sqr_add_c2(a,7,2,c1,c2,c3);
+	sqr_add_c2(a,6,3,c1,c2,c3);
+	sqr_add_c2(a,5,4,c1,c2,c3);
+	r[9]=c1;
+	c1=0;
+	sqr_add_c(a,5,c2,c3,c1);
+	sqr_add_c2(a,6,4,c2,c3,c1);
+	sqr_add_c2(a,7,3,c2,c3,c1);
+	r[10]=c2;
+	c2=0;
+	sqr_add_c2(a,7,4,c3,c1,c2);
+	sqr_add_c2(a,6,5,c3,c1,c2);
+	r[11]=c3;
+	c3=0;
+	sqr_add_c(a,6,c1,c2,c3);
+	sqr_add_c2(a,7,5,c1,c2,c3);
+	r[12]=c1;
+	c1=0;
+	sqr_add_c2(a,7,6,c2,c3,c1);
+	r[13]=c2;
+	c2=0;
+	sqr_add_c(a,7,c3,c1,c2);
+	r[14]=c3;
+	r[15]=c1;
+	}
+
+void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+	{
+#ifdef BN_LLONG
+	BN_ULLONG t,tt;
+#else
+	BN_ULONG bl,bh;
+#endif
+	BN_ULONG t1,t2;
+	BN_ULONG c1,c2,c3;
+
+	c1=0;
+	c2=0;
+	c3=0;
+	sqr_add_c(a,0,c1,c2,c3);
+	r[0]=c1;
+	c1=0;
+	sqr_add_c2(a,1,0,c2,c3,c1);
+	r[1]=c2;
+	c2=0;
+	sqr_add_c(a,1,c3,c1,c2);
+	sqr_add_c2(a,2,0,c3,c1,c2);
+	r[2]=c3;
+	c3=0;
+	sqr_add_c2(a,3,0,c1,c2,c3);
+	sqr_add_c2(a,2,1,c1,c2,c3);
+	r[3]=c1;
+	c1=0;
+	sqr_add_c(a,2,c2,c3,c1);
+	sqr_add_c2(a,3,1,c2,c3,c1);
+	r[4]=c2;
+	c2=0;
+	sqr_add_c2(a,3,2,c3,c1,c2);
+	r[5]=c3;
+	c3=0;
+	sqr_add_c(a,3,c1,c2,c3);
+	r[6]=c1;
+	r[7]=c2;
+	}
+#else /* !BN_MUL_COMBA */
+
+/* hmm... is it faster just to do a multiply? */
+#undef bn_sqr_comba4
+void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+	{
+	BN_ULONG t[8];
+	bn_sqr_normal(r,a,4,t);
+	}
+
+#undef bn_sqr_comba8
+void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+	{
+	BN_ULONG t[16];
+	bn_sqr_normal(r,a,8,t);
+	}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+	r[4]=bn_mul_words(    &(r[0]),a,4,b[0]);
+	r[5]=bn_mul_add_words(&(r[1]),a,4,b[1]);
+	r[6]=bn_mul_add_words(&(r[2]),a,4,b[2]);
+	r[7]=bn_mul_add_words(&(r[3]),a,4,b[3]);
+	}
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+	{
+	r[ 8]=bn_mul_words(    &(r[0]),a,8,b[0]);
+	r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);
+	r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]);
+	r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]);
+	r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]);
+	r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]);
+	r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]);
+	r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
+	}
+
+#endif /* !BN_MUL_COMBA */
diff --git a/AppleCSP/open_ssl/bn/bn_blind.c b/AppleCSP/open_ssl/bn/bn_blind.c
new file mode 100644
index 00000000..73ddc1c0
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_blind.c
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_blind.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod)
+	{
+	BN_BLINDING *ret=NULL;
+
+	bn_check_top(Ai);
+	bn_check_top(mod);
+
+	if ((ret=(BN_BLINDING *)Malloc(sizeof(BN_BLINDING))) == NULL)
+		{
+		BNerr(BN_F_BN_BLINDING_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	memset(ret,0,sizeof(BN_BLINDING));
+	if ((ret->A=BN_new()) == NULL) goto err;
+	if ((ret->Ai=BN_new()) == NULL) goto err;
+	if (!BN_copy(ret->A,A)) goto err;
+	if (!BN_copy(ret->Ai,Ai)) goto err;
+	ret->mod=mod;
+	return(ret);
+err:
+	if (ret != NULL) BN_BLINDING_free(ret);
+	return(NULL);
+	}
+
+void BN_BLINDING_free(BN_BLINDING *r)
+	{
+	if(r == NULL)
+	    return;
+
+	if (r->A  != NULL) BN_free(r->A );
+	if (r->Ai != NULL) BN_free(r->Ai);
+	Free(r);
+	}
+
+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
+	{
+	int ret=0;
+
+	if ((b->A == NULL) || (b->Ai == NULL))
+		{
+		BNerr(BN_F_BN_BLINDING_UPDATE,BN_R_NOT_INITIALIZED);
+		goto err;
+		}
+		
+	if (!BN_mod_mul(b->A,b->A,b->A,b->mod,ctx)) goto err;
+	if (!BN_mod_mul(b->Ai,b->Ai,b->Ai,b->mod,ctx)) goto err;
+
+	ret=1;
+err:
+	return(ret);
+	}
+
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+	{
+	bn_check_top(n);
+
+	if ((b->A == NULL) || (b->Ai == NULL))
+		{
+		BNerr(BN_F_BN_BLINDING_CONVERT,BN_R_NOT_INITIALIZED);
+		return(0);
+		}
+	return(BN_mod_mul(n,n,b->A,b->mod,ctx));
+	}
+
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+	{
+	int ret;
+
+	bn_check_top(n);
+	if ((b->A == NULL) || (b->Ai == NULL))
+		{
+		BNerr(BN_F_BN_BLINDING_INVERT,BN_R_NOT_INITIALIZED);
+		return(0);
+		}
+	if ((ret=BN_mod_mul(n,n,b->Ai,b->mod,ctx)) >= 0)
+		{
+		if (!BN_BLINDING_update(b,ctx))
+			return(0);
+		}
+	return(ret);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_ctx.c b/AppleCSP/open_ssl/bn/bn_ctx.c
new file mode 100644
index 00000000..bcb922cb
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_ctx.c
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_ctx.c */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef BN_CTX_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+
+
+BN_CTX *BN_CTX_new(void)
+	{
+	BN_CTX *ret;
+
+	ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
+	if (ret == NULL)
+		{
+		BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	BN_CTX_init(ret);
+	ret->flags=BN_FLG_MALLOCED;
+	return(ret);
+	}
+
+void BN_CTX_init(BN_CTX *ctx)
+	{
+	int i;
+	ctx->tos = 0;
+	ctx->flags = 0;
+	ctx->depth = 0;
+	ctx->too_many = 0;
+	for (i = 0; i < BN_CTX_NUM; i++)
+		BN_init(&(ctx->bn[i]));
+	}
+
+void BN_CTX_free(BN_CTX *ctx)
+	{
+	int i;
+
+	if (ctx == NULL) return;
+	assert(ctx->depth == 0);
+
+	for (i=0; i < BN_CTX_NUM; i++)
+		BN_clear_free(&(ctx->bn[i]));
+	if (ctx->flags & BN_FLG_MALLOCED)
+		Free(ctx);
+	}
+
+void BN_CTX_start(BN_CTX *ctx)
+	{
+	if (ctx->depth < BN_CTX_NUM_POS)
+		ctx->pos[ctx->depth] = ctx->tos;
+	ctx->depth++;
+	}
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx)
+	{
+	if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM)
+		{
+		if (!ctx->too_many)
+			{
+			BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+			/* disable error code until BN_CTX_end is called: */
+			ctx->too_many = 1;
+			}
+		return NULL;
+		}
+	return (&(ctx->bn[ctx->tos++]));
+	}
+
+void BN_CTX_end(BN_CTX *ctx)
+	{
+	if (ctx == NULL) return;
+	assert(ctx->depth > 0);
+	if (ctx->depth == 0)
+		/* should never happen, but we can tolerate it if not in
+		 * debug mode (could be a 'goto err' in the calling function
+		 * before BN_CTX_start was reached) */
+		BN_CTX_start(ctx);
+
+	ctx->too_many = 0;
+	ctx->depth--;
+	if (ctx->depth < BN_CTX_NUM_POS)
+		ctx->tos = ctx->pos[ctx->depth];
+	}
diff --git a/AppleCSP/open_ssl/bn/bn_div.c b/AppleCSP/open_ssl/bn/bn_div.c
new file mode 100644
index 00000000..a85fb3a4
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_div.c
@@ -0,0 +1,398 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_div.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* The old slow way */
+#if 0
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+	   BN_CTX *ctx)
+	{
+	int i,nm,nd;
+	int ret = 0;
+	BIGNUM *D;
+
+	bn_check_top(m);
+	bn_check_top(d);
+	if (BN_is_zero(d))
+		{
+		BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
+		return(0);
+		}
+
+	if (BN_ucmp(m,d) < 0)
+		{
+		if (rem != NULL)
+			{ if (BN_copy(rem,m) == NULL) return(0); }
+		if (dv != NULL) BN_zero(dv);
+		return(1);
+		}
+
+	BN_CTX_start(ctx);
+	D = BN_CTX_get(ctx);
+	if (dv == NULL) dv = BN_CTX_get(ctx);
+	if (rem == NULL) rem = BN_CTX_get(ctx);
+	if (D == NULL || dv == NULL || rem == NULL)
+		goto end;
+
+	nd=BN_num_bits(d);
+	nm=BN_num_bits(m);
+	if (BN_copy(D,d) == NULL) goto end;
+	if (BN_copy(rem,m) == NULL) goto end;
+
+	/* The next 2 are needed so we can do a dv->d[0]|=1 later
+	 * since BN_lshift1 will only work once there is a value :-) */
+	BN_zero(dv);
+	bn_wexpand(dv,1);
+	dv->top=1;
+
+	if (!BN_lshift(D,D,nm-nd)) goto end;
+	for (i=nm-nd; i>=0; i--)
+		{
+		if (!BN_lshift1(dv,dv)) goto end;
+		if (BN_ucmp(rem,D) >= 0)
+			{
+			dv->d[0]|=1;
+			if (!BN_usub(rem,rem,D)) goto end;
+			}
+/* CAN IMPROVE (and have now :=) */
+		if (!BN_rshift1(D,D)) goto end;
+		}
+	rem->neg=BN_is_zero(rem)?0:m->neg;
+	dv->neg=m->neg^d->neg;
+	ret = 1;
+ end:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+#else
+
+#if !defined(NO_ASM) && !defined(NO_INLINE_ASM) && !defined(PEDANTIC) && !defined(BN_DIV3W)
+# if defined(__GNUC__) && __GNUC__>=2
+#  if defined(__i386)
+   /*
+    * There were two reasons for implementing this template:
+    * - GNU C generates a call to a function (__udivdi3 to be exact)
+    *   in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
+    *   understand why...);
+    * - divl doesn't only calculate quotient, but also leaves
+    *   remainder in %edx which we can definitely use here:-)
+    *
+    *					<appro@fy.chalmers.se>
+    */
+#  define bn_div_words(n0,n1,d0)		\
+	({  asm volatile (			\
+		"divl	%4"			\
+		: "=a"(q), "=d"(rem)		\
+		: "a"(n1), "d"(n0), "g"(d0)	\
+		: "cc");			\
+	    q;					\
+	})
+#  define REMAINDER_IS_ALREADY_CALCULATED
+#  endif /* __<cpu> */
+# endif /* __GNUC__ */
+#endif /* NO_ASM */
+
+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+	   BN_CTX *ctx)
+	{
+	int norm_shift,i,j,loop;
+	BIGNUM *tmp,wnum,*snum,*sdiv,*res;
+	BN_ULONG *resp,*wnump;
+	BN_ULONG d0,d1;
+	int num_n,div_n;
+
+	bn_check_top(num);
+	bn_check_top(divisor);
+
+	if (BN_is_zero(divisor))
+		{
+		BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
+		return(0);
+		}
+
+	if (BN_ucmp(num,divisor) < 0)
+		{
+		if (rm != NULL)
+			{ if (BN_copy(rm,num) == NULL) return(0); }
+		if (dv != NULL) BN_zero(dv);
+		return(1);
+		}
+
+	BN_CTX_start(ctx);
+	tmp=BN_CTX_get(ctx);
+	tmp->neg=0;
+	snum=BN_CTX_get(ctx);
+	sdiv=BN_CTX_get(ctx);
+	if (dv == NULL)
+		res=BN_CTX_get(ctx);
+	else	res=dv;
+	if (res == NULL) goto err;
+
+	/* First we normalise the numbers */
+	norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+	BN_lshift(sdiv,divisor,norm_shift);
+	sdiv->neg=0;
+	norm_shift+=BN_BITS2;
+	BN_lshift(snum,num,norm_shift);
+	snum->neg=0;
+	div_n=sdiv->top;
+	num_n=snum->top;
+	loop=num_n-div_n;
+
+	/* Lets setup a 'window' into snum
+	 * This is the part that corresponds to the current
+	 * 'area' being divided */
+	BN_init(&wnum);
+	wnum.d=	 &(snum->d[loop]);
+	wnum.top= div_n;
+	wnum.max= snum->max+1; /* a bit of a lie */
+
+	/* Get the top 2 words of sdiv */
+	/* i=sdiv->top; */
+	d0=sdiv->d[div_n-1];
+	d1=(div_n == 1)?0:sdiv->d[div_n-2];
+
+	/* pointer to the 'top' of snum */
+	wnump= &(snum->d[num_n-1]);
+
+	/* Setup to 'res' */
+	res->neg= (num->neg^divisor->neg);
+	if (!bn_wexpand(res,(loop+1))) goto err;
+	res->top=loop;
+	resp= &(res->d[loop-1]);
+
+	/* space for temp */
+	if (!bn_wexpand(tmp,(div_n+1))) goto err;
+
+	if (BN_ucmp(&wnum,sdiv) >= 0)
+		{
+		if (!BN_usub(&wnum,&wnum,sdiv)) goto err;
+		*resp=1;
+		res->d[res->top-1]=1;
+		}
+	else
+		res->top--;
+	resp--;
+
+	for (i=0; i<loop-1; i++)
+		{
+		BN_ULONG q,l0;
+#ifdef BN_DIV3W
+		q=bn_div_3_words(wnump,d1,d0);
+#else
+		BN_ULONG n0,n1,rem=0;
+
+		n0=wnump[0];
+		n1=wnump[-1];
+		if (n0 == d0)
+			q=BN_MASK2;
+		else 			/* n0 < d0 */
+			{
+#ifdef BN_LLONG
+			BN_ULLONG t2;
+
+#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+			q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
+#else
+			q=bn_div_words(n0,n1,d0);
+#endif
+
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+			/*
+			 * rem doesn't have to be BN_ULLONG. The least we
+			 * know it's less that d0, isn't it?
+			 */
+			rem=(n1-q*d0)&BN_MASK2;
+#endif
+			t2=(BN_ULLONG)d1*q;
+
+			for (;;)
+				{
+				if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
+					break;
+				q--;
+				rem += d0;
+				if (rem < d0) break; /* don't let rem overflow */
+				t2 -= d1;
+				}
+#else /* !BN_LLONG */
+			BN_ULONG t2l,t2h,ql,qh;
+
+			q=bn_div_words(n0,n1,d0);
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+			rem=(n1-q*d0)&BN_MASK2;
+#endif
+
+#ifdef BN_UMULT_HIGH
+			t2l = d1 * q;
+			t2h = BN_UMULT_HIGH(d1,q);
+#else
+			t2l=LBITS(d1); t2h=HBITS(d1);
+			ql =LBITS(q);  qh =HBITS(q);
+			mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+#endif
+
+			for (;;)
+				{
+				if ((t2h < rem) ||
+					((t2h == rem) && (t2l <= wnump[-2])))
+					break;
+				q--;
+				rem += d0;
+				if (rem < d0) break; /* don't let rem overflow */
+				if (t2l < d1) t2h--; t2l -= d1;
+				}
+#endif /* !BN_LLONG */
+			}
+#endif /* !BN_DIV3W */
+
+		l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
+		wnum.d--; wnum.top++;
+		tmp->d[div_n]=l0;
+		for (j=div_n+1; j>0; j--)
+			if (tmp->d[j-1]) break;
+		tmp->top=j;
+
+		j=wnum.top;
+		BN_sub(&wnum,&wnum,tmp);
+
+		snum->top=snum->top+wnum.top-j;
+
+		if (wnum.neg)
+			{
+			q--;
+			j=wnum.top;
+			BN_add(&wnum,&wnum,sdiv);
+			snum->top+=wnum.top-j;
+			}
+		*(resp--)=q;
+		wnump--;
+		}
+	if (rm != NULL)
+		{
+		BN_rshift(rm,snum,norm_shift);
+		rm->neg=num->neg;
+		}
+	BN_CTX_end(ctx);
+	return(1);
+err:
+	BN_CTX_end(ctx);
+	return(0);
+	}
+
+#endif
+
+/* rem != m */
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+	{
+#if 0 /* The old slow way */
+	int i,nm,nd;
+	BIGNUM *dv;
+
+	if (BN_ucmp(m,d) < 0)
+		return((BN_copy(rem,m) == NULL)?0:1);
+
+	BN_CTX_start(ctx);
+	dv=BN_CTX_get(ctx);
+
+	if (!BN_copy(rem,m)) goto err;
+
+	nm=BN_num_bits(rem);
+	nd=BN_num_bits(d);
+	if (!BN_lshift(dv,d,nm-nd)) goto err;
+	for (i=nm-nd; i>=0; i--)
+		{
+		if (BN_cmp(rem,dv) >= 0)
+			{
+			if (!BN_sub(rem,rem,dv)) goto err;
+			}
+		if (!BN_rshift1(dv,dv)) goto err;
+		}
+	BN_CTX_end(ctx);
+	return(1);
+ err:
+	BN_CTX_end(ctx);
+	return(0);
+#else
+	return(BN_div(NULL,rem,m,d,ctx));
+#endif
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_err.c b/AppleCSP/open_ssl/bn/bn_err.c
new file mode 100644
index 00000000..012a5c0d
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_err.c
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+/* BEGIN ERROR CODES */
+#ifndef NO_ERR
+static ERR_STRING_DATA BN_str_functs[]=
+	{
+{ERR_PACK(0,BN_F_BN_BLINDING_CONVERT,0),	"BN_BLINDING_convert"},
+{ERR_PACK(0,BN_F_BN_BLINDING_INVERT,0),	"BN_BLINDING_invert"},
+{ERR_PACK(0,BN_F_BN_BLINDING_NEW,0),	"BN_BLINDING_new"},
+{ERR_PACK(0,BN_F_BN_BLINDING_UPDATE,0),	"BN_BLINDING_update"},
+{ERR_PACK(0,BN_F_BN_BN2DEC,0),	"BN_bn2dec"},
+{ERR_PACK(0,BN_F_BN_BN2HEX,0),	"BN_bn2hex"},
+{ERR_PACK(0,BN_F_BN_CTX_GET,0),	"BN_CTX_get"},
+{ERR_PACK(0,BN_F_BN_CTX_NEW,0),	"BN_CTX_new"},
+{ERR_PACK(0,BN_F_BN_DIV,0),	"BN_div"},
+{ERR_PACK(0,BN_F_BN_EXPAND2,0),	"bn_expand2"},
+{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0),	"BN_mod_exp_mont"},
+{ERR_PACK(0,BN_F_BN_MOD_INVERSE,0),	"BN_mod_inverse"},
+{ERR_PACK(0,BN_F_BN_MOD_MUL_RECIPROCAL,0),	"BN_mod_mul_reciprocal"},
+{ERR_PACK(0,BN_F_BN_MPI2BN,0),	"BN_mpi2bn"},
+{ERR_PACK(0,BN_F_BN_NEW,0),	"BN_new"},
+{ERR_PACK(0,BN_F_BN_RAND,0),	"BN_rand"},
+{ERR_PACK(0,BN_F_BN_USUB,0),	"BN_usub"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA BN_str_reasons[]=
+	{
+{BN_R_ARG2_LT_ARG3                       ,"arg2 lt arg3"},
+{BN_R_BAD_RECIPROCAL                     ,"bad reciprocal"},
+{BN_R_CALLED_WITH_EVEN_MODULUS           ,"called with even modulus"},
+{BN_R_DIV_BY_ZERO                        ,"div by zero"},
+{BN_R_ENCODING_ERROR                     ,"encoding error"},
+{BN_R_EXPAND_ON_STATIC_BIGNUM_DATA       ,"expand on static bignum data"},
+{BN_R_INVALID_LENGTH                     ,"invalid length"},
+{BN_R_NOT_INITIALIZED                    ,"not initialized"},
+{BN_R_NO_INVERSE                         ,"no inverse"},
+{BN_R_TOO_MANY_TEMPORARY_VARIABLES       ,"too many temporary variables"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_BN_strings(void)
+	{
+	static int init=1;
+
+	if (init)
+		{
+		init=0;
+#ifndef NO_ERR
+		ERR_load_strings(ERR_LIB_BN,BN_str_functs);
+		ERR_load_strings(ERR_LIB_BN,BN_str_reasons);
+#endif
+
+		}
+	}
diff --git a/AppleCSP/open_ssl/bn/bn_exp.c b/AppleCSP/open_ssl/bn/bn_exp.c
new file mode 100644
index 00000000..eb0de885
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_exp.c
@@ -0,0 +1,767 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_exp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#ifdef ATALLA
+# include <alloca.h>
+# include <atasi.h>
+# include <assert.h>
+# include <dlfcn.h>
+#endif
+
+#define TABLE_SIZE	16
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+	{
+	BIGNUM *t;
+	int r=0;
+
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(m);
+
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+	if (a == b)
+		{ if (!BN_sqr(t,a,ctx)) goto err; }
+	else
+		{ if (!BN_mul(t,a,b,ctx)) goto err; }
+	if (!BN_mod(ret,t,m,ctx)) goto err;
+	r=1;
+err:
+	BN_CTX_end(ctx);
+	return(r);
+	}
+
+#if 0
+/* this one works - simple but works */
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
+	{
+	int i,bits,ret=0;
+	BIGNUM *v,*tmp;
+
+	BN_CTX_start(ctx);
+	v = BN_CTX_get(ctx);
+	tmp = BN_CTX_get(ctx);
+	if (v == NULL || tmp == NULL) goto err;
+
+	if (BN_copy(v,a) == NULL) goto err;
+	bits=BN_num_bits(p);
+
+	if (BN_is_odd(p))
+		{ if (BN_copy(r,a) == NULL) goto err; }
+	else	{ if (!BN_one(r)) goto err; }
+
+	for (i=1; i<bits; i++)
+		{
+		if (!BN_sqr(tmp,v,ctx)) goto err;
+		if (!BN_mod(v,tmp,m,ctx)) goto err;
+		if (BN_is_bit_set(p,i))
+			{
+			if (!BN_mul(tmp,r,v,ctx)) goto err;
+			if (!BN_mod(r,tmp,m,ctx)) goto err;
+			}
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+#endif
+
+/* this one works - simple but works */
+int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
+	{
+	int i,bits,ret=0;
+	BIGNUM *v,*rr;
+
+	BN_CTX_start(ctx);
+	if ((r == a) || (r == p))
+		rr = BN_CTX_get(ctx);
+	else
+		rr = r;
+	if ((v = BN_CTX_get(ctx)) == NULL) goto err;
+
+	if (BN_copy(v,a) == NULL) goto err;
+	bits=BN_num_bits(p);
+
+	if (BN_is_odd(p))
+		{ if (BN_copy(rr,a) == NULL) goto err; }
+	else	{ if (!BN_one(rr)) goto err; }
+
+	for (i=1; i<bits; i++)
+		{
+		if (!BN_sqr(v,v,ctx)) goto err;
+		if (BN_is_bit_set(p,i))
+			{
+			if (!BN_mul(rr,rr,v,ctx)) goto err;
+			}
+		}
+	ret=1;
+err:
+	if (r != rr) BN_copy(r,rr);
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+#ifdef ATALLA
+
+/*
+ * This routine will dynamically check for the existance of an Atalla AXL-200
+ * SSL accelerator module.  If one is found, the variable
+ * asi_accelerator_present is set to 1 and the function pointers
+ * ptr_ASI_xxxxxx above will be initialized to corresponding ASI API calls.
+ */
+typedef int tfnASI_GetPerformanceStatistics(int reset_flag,
+					    unsigned int *ret_buf);
+typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf);
+typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey,
+				     unsigned char *output,
+				     unsigned char *input,
+				     unsigned int modulus_len);
+
+static tfnASI_GetHardwareConfig *ptr_ASI_GetHardwareConfig;
+static tfnASI_RSAPrivateKeyOpFn *ptr_ASI_RSAPrivateKeyOpFn;
+static tfnASI_GetPerformanceStatistics *ptr_ASI_GetPerformanceStatistics;
+static int asi_accelerator_present;
+static int tried_atalla;
+
+void atalla_initialize_accelerator_handle(void)
+	{
+	void *dl_handle;
+	int status;
+	unsigned int config_buf[1024]; 
+	static int tested;
+
+	if(tested)
+		return;
+
+	tested=1;
+
+	bzero((void *)config_buf, 1024);
+
+	/*
+	 * Check to see if the library is present on the system
+	 */
+	dl_handle = dlopen("atasi.so", RTLD_NOW);
+	if (dl_handle == (void *) NULL)
+		{
+/*		printf("atasi.so library is not present on the system\n");
+		printf("No HW acceleration available\n");*/
+		return;
+	        }
+
+	/*
+	 * The library is present.  Now we'll check to insure that the
+	 * LDM is up and running. First we'll get the address of the
+	 * function in the atasi library that we need to see if the
+	 * LDM is operating.
+	 */
+
+	ptr_ASI_GetHardwareConfig =
+	  (tfnASI_GetHardwareConfig *)dlsym(dl_handle,"ASI_GetHardwareConfig");
+
+	if (ptr_ASI_GetHardwareConfig)
+		{
+		/*
+		 * We found the call, now we'll get our config
+		 * status.  If we get a non 0 result, the LDM is not
+		 * running and we cannot use the Atalla ASI *
+		 * library.
+		 */
+		status = (*ptr_ASI_GetHardwareConfig)(0L, config_buf);
+		if (status != 0)
+			{
+			printf("atasi.so library is present but not initialized\n");
+			printf("No HW acceleration available\n");
+			return;
+			}    
+	        }
+	else
+		{
+/*		printf("We found the library, but not the function. Very Strange!\n");*/
+		return ;
+	      	}
+
+	/* 
+	 * It looks like we have acceleration capabilities.  Load up the
+	 * pointers to our ASI API calls.
+	 */
+	ptr_ASI_RSAPrivateKeyOpFn=
+	  (tfnASI_RSAPrivateKeyOpFn *)dlsym(dl_handle, "ASI_RSAPrivateKeyOpFn");
+	if (ptr_ASI_RSAPrivateKeyOpFn == NULL)
+		{
+/*		printf("We found the library, but no RSA function. Very Strange!\n");*/
+		return;
+	        }
+
+	ptr_ASI_GetPerformanceStatistics =
+	  (tfnASI_GetPerformanceStatistics *)dlsym(dl_handle, "ASI_GetPerformanceStatistics");
+	if (ptr_ASI_GetPerformanceStatistics == NULL)
+		{
+/*		printf("We found the library, but no stat function. Very Strange!\n");*/
+		return;
+	      }
+
+	/*
+	 * Indicate that acceleration is available
+	 */
+	asi_accelerator_present = 1;
+
+/*	printf("This system has acceleration!\n");*/
+
+	return;
+	}
+
+/* make sure this only gets called once when bn_mod_exp calls bn_mod_exp_mont */
+int BN_mod_exp_atalla(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m)
+	{
+	unsigned char *abin;
+	unsigned char *pbin;
+	unsigned char *mbin;
+	unsigned char *rbin;
+	int an,pn,mn,ret;
+	RSAPrivateKey keydata;
+
+	atalla_initialize_accelerator_handle();
+	if(!asi_accelerator_present)
+		return 0;
+
+
+/* We should be able to run without size testing */
+# define ASIZE	128
+	an=BN_num_bytes(a);
+	pn=BN_num_bytes(p);
+	mn=BN_num_bytes(m);
+
+	if(an <= ASIZE && pn <= ASIZE && mn <= ASIZE)
+	    {
+	    int size=mn;
+
+	    assert(an <= mn);
+	    abin=alloca(size);
+	    memset(abin,'\0',mn);
+	    BN_bn2bin(a,abin+size-an);
+
+	    pbin=alloca(pn);
+	    BN_bn2bin(p,pbin);
+
+	    mbin=alloca(size);
+	    memset(mbin,'\0',mn);
+	    BN_bn2bin(m,mbin+size-mn);
+
+	    rbin=alloca(size);
+
+	    memset(&keydata,'\0',sizeof keydata);
+	    keydata.privateExponent.data=pbin;
+	    keydata.privateExponent.len=pn;
+	    keydata.modulus.data=mbin;
+	    keydata.modulus.len=size;
+
+	    ret=(*ptr_ASI_RSAPrivateKeyOpFn)(&keydata,rbin,abin,keydata.modulus.len);
+/*fprintf(stderr,"!%s\n",BN_bn2hex(a));*/
+	    if(!ret)
+	        {
+		BN_bin2bn(rbin,keydata.modulus.len,r);
+/*fprintf(stderr,"?%s\n",BN_bn2hex(r));*/
+		return 1;
+	        }
+	    }
+	return 0;
+        }
+#endif /* def ATALLA */
+
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+	       BN_CTX *ctx)
+	{
+	int ret;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	bn_check_top(m);
+
+#ifdef ATALLA
+	if(BN_mod_exp_atalla(r,a,p,m))
+	    return 1;
+/* If it fails, try the other methods (but don't try atalla again) */
+	tried_atalla=1;
+#endif
+
+#ifdef MONT_MUL_MOD
+	/* I have finally been able to take out this pre-condition of
+	 * the top bit being set.  It was caused by an error in BN_div
+	 * with negatives.  There was also another problem when for a^b%m
+	 * a >= m.  eay 07-May-97 */
+/*	if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+	if (BN_is_odd(m))
+		{ ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); }
+	else
+#endif
+#ifdef RECP_MUL_MOD
+		{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }
+#else
+		{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }
+#endif
+
+#ifdef ATALLA
+	tried_atalla=0;
+#endif
+
+	return(ret);
+	}
+
+/* #ifdef RECP_MUL_MOD */
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+		    const BIGNUM *m, BN_CTX *ctx)
+	{
+	int i,j,bits,ret=0,wstart,wend,window,wvalue;
+	int start=1,ts=0;
+	BIGNUM *aa;
+	BIGNUM val[TABLE_SIZE];
+	BN_RECP_CTX recp;
+
+	bits=BN_num_bits(p);
+
+	if (bits == 0)
+		{
+		BN_one(r);
+		return(1);
+		}
+
+	BN_CTX_start(ctx);
+	if ((aa = BN_CTX_get(ctx)) == NULL) goto err;
+
+	BN_RECP_CTX_init(&recp);
+	if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
+
+	BN_init(&(val[0]));
+	ts=1;
+
+	if (!BN_mod(&(val[0]),a,m,ctx)) goto err;		/* 1 */
+	if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
+		goto err;				/* 2 */
+
+	if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
+		window=1;
+	else if (bits >= 256)
+		window=5;	/* max size of window */
+	else if (bits >= 128)
+		window=4;
+	else
+		window=3;
+
+	j=1<<(window-1);
+	for (i=1; i<j; i++)
+		{
+		BN_init(&val[i]);
+		if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
+			goto err;
+		}
+	ts=i;
+
+	start=1;	/* This is used to avoid multiplication etc
+			 * when there is only the value '1' in the
+			 * buffer. */
+	wvalue=0;	/* The 'value' of the window */
+	wstart=bits-1;	/* The top bit of the window */
+	wend=0;		/* The bottom bit of the window */
+
+	if (!BN_one(r)) goto err;
+
+	for (;;)
+		{
+		if (BN_is_bit_set(p,wstart) == 0)
+			{
+			if (!start)
+				if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+				goto err;
+			if (wstart == 0) break;
+			wstart--;
+			continue;
+			}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j=wstart;
+		wvalue=1;
+		wend=0;
+		for (i=1; i<window; i++)
+			{
+			if (wstart-i < 0) break;
+			if (BN_is_bit_set(p,wstart-i))
+				{
+				wvalue<<=(i-wend);
+				wvalue|=1;
+				wend=i;
+				}
+			}
+
+		/* wend is the size of the current window */
+		j=wend+1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i=0; i<j; i++)
+				{
+				if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+					goto err;
+				}
+		
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart-=wend+1;
+		wvalue=0;
+		start=0;
+		if (wstart < 0) break;
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	for (i=0; i<ts; i++)
+		BN_clear_free(&(val[i]));
+	BN_RECP_CTX_free(&recp);
+	return(ret);
+	}
+/* #endif */
+
+/* #ifdef MONT_MUL_MOD */
+int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
+		    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	int i,j,bits,ret=0,wstart,wend,window,wvalue;
+	int start=1,ts=0;
+	BIGNUM *d,*r;
+	BIGNUM *aa;
+	BIGNUM val[TABLE_SIZE];
+	BN_MONT_CTX *mont=NULL;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	bn_check_top(m);
+
+#ifdef ATALLA
+	if(!tried_atalla && BN_mod_exp_atalla(rr,a,p,m))
+	    return 1;
+/* If it fails, try the other methods */
+#endif
+
+	if (!(m->d[0] & 1))
+		{
+		BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
+		return(0);
+		}
+	bits=BN_num_bits(p);
+	if (bits == 0)
+		{
+		BN_one(rr);
+		return(1);
+		}
+	BN_CTX_start(ctx);
+	d = BN_CTX_get(ctx);
+	r = BN_CTX_get(ctx);
+	if (d == NULL || r == NULL) goto err;
+
+	/* If this is not done, things will break in the montgomery
+	 * part */
+
+#if 1
+	if (in_mont != NULL)
+		mont=in_mont;
+	else
+#endif
+		{
+		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+		}
+
+	BN_init(&val[0]);
+	ts=1;
+	if (BN_ucmp(a,m) >= 0)
+		{
+		BN_mod(&(val[0]),a,m,ctx);
+		aa= &(val[0]);
+		}
+	else
+		aa=a;
+	if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */
+	if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */
+
+	if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */
+		window=1;
+	else if (bits >= 256)
+		window=5;	/* max size of window */
+	else if (bits >= 128)
+		window=4;
+	else
+		window=3;
+
+	j=1<<(window-1);
+	for (i=1; i<j; i++)
+		{
+		BN_init(&(val[i]));
+		if (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,ctx))
+			goto err;
+		}
+	ts=i;
+
+	start=1;	/* This is used to avoid multiplication etc
+			 * when there is only the value '1' in the
+			 * buffer. */
+	wvalue=0;	/* The 'value' of the window */
+	wstart=bits-1;	/* The top bit of the window */
+	wend=0;		/* The bottom bit of the window */
+
+        if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+	for (;;)
+		{
+		if (BN_is_bit_set(p,wstart) == 0)
+			{
+			if (!start)
+				{
+				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+				goto err;
+				}
+			if (wstart == 0) break;
+			wstart--;
+			continue;
+			}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j=wstart;
+		wvalue=1;
+		wend=0;
+		for (i=1; i<window; i++)
+			{
+			if (wstart-i < 0) break;
+			if (BN_is_bit_set(p,wstart-i))
+				{
+				wvalue<<=(i-wend);
+				wvalue|=1;
+				wend=i;
+				}
+			}
+
+		/* wend is the size of the current window */
+		j=wend+1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i=0; i<j; i++)
+				{
+				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+					goto err;
+				}
+		
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul_montgomery(r,r,&(val[wvalue>>1]),mont,ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart-=wend+1;
+		wvalue=0;
+		start=0;
+		if (wstart < 0) break;
+		}
+	BN_from_montgomery(rr,r,mont,ctx);
+	ret=1;
+err:
+	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+	BN_CTX_end(ctx);
+	for (i=0; i<ts; i++)
+		BN_clear_free(&(val[i]));
+	return(ret);
+	}
+/* #endif */
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
+	     BN_CTX *ctx)
+	{
+	int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0;
+	int start=1;
+	BIGNUM *d;
+	BIGNUM val[TABLE_SIZE];
+
+	bits=BN_num_bits(p);
+
+	if (bits == 0)
+		{
+		BN_one(r);
+		return(1);
+		}
+
+	BN_CTX_start(ctx);
+	if ((d = BN_CTX_get(ctx)) == NULL) goto err;
+
+	BN_init(&(val[0]));
+	ts=1;
+	if (!BN_mod(&(val[0]),a,m,ctx)) goto err;		/* 1 */
+	if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx))
+		goto err;				/* 2 */
+
+	if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
+		window=1;
+	else if (bits >= 256)
+		window=5;	/* max size of window */
+	else if (bits >= 128)
+		window=4;
+	else
+		window=3;
+
+	j=1<<(window-1);
+	for (i=1; i<j; i++)
+		{
+		BN_init(&(val[i]));
+		if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx))
+			goto err;
+		}
+	ts=i;
+
+	start=1;	/* This is used to avoid multiplication etc
+			 * when there is only the value '1' in the
+			 * buffer. */
+	wvalue=0;	/* The 'value' of the window */
+	wstart=bits-1;	/* The top bit of the window */
+	wend=0;		/* The bottom bit of the window */
+
+	if (!BN_one(r)) goto err;
+
+	for (;;)
+		{
+		if (BN_is_bit_set(p,wstart) == 0)
+			{
+			if (!start)
+				if (!BN_mod_mul(r,r,r,m,ctx))
+				goto err;
+			if (wstart == 0) break;
+			wstart--;
+			continue;
+			}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j=wstart;
+		wvalue=1;
+		wend=0;
+		for (i=1; i<window; i++)
+			{
+			if (wstart-i < 0) break;
+			if (BN_is_bit_set(p,wstart-i))
+				{
+				wvalue<<=(i-wend);
+				wvalue|=1;
+				wend=i;
+				}
+			}
+
+		/* wend is the size of the current window */
+		j=wend+1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i=0; i<j; i++)
+				{
+				if (!BN_mod_mul(r,r,r,m,ctx))
+					goto err;
+				}
+		
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul(r,r,&(val[wvalue>>1]),m,ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart-=wend+1;
+		wvalue=0;
+		start=0;
+		if (wstart < 0) break;
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	for (i=0; i<ts; i++)
+		BN_clear_free(&(val[i]));
+	return(ret);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_exp2.c b/AppleCSP/open_ssl/bn/bn_exp2.c
new file mode 100644
index 00000000..4317bdba
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_exp2.c
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* I've done some timing with different table sizes.
+ * The main hassle is that even with bits set at 3, this requires
+ * 63 BIGNUMs to store the pre-calculated values.
+ *          512   1024 
+ * bits=1  75.4%  79.4%
+ * bits=2  61.2%  62.4%
+ * bits=3  61.3%  59.3%
+ * The lack of speed improvement is also a function of the pre-calculation
+ * which could be removed.
+ */
+#define EXP2_TABLE_BITS	2 /* 1  2  3  4  5  */
+#define EXP2_TABLE_SIZE	4 /* 2  4  8 16 32  */
+
+int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2,
+	     BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+	{
+	int i,j,k,bits,bits1,bits2,ret=0,wstart,wend,window,xvalue,yvalue;
+	int start=1,ts=0,x,y;
+	BIGNUM *d,*aa1,*aa2,*r;
+	BIGNUM val[EXP2_TABLE_SIZE][EXP2_TABLE_SIZE];
+	BN_MONT_CTX *mont=NULL;
+
+	bn_check_top(a1);
+	bn_check_top(p1);
+	bn_check_top(a2);
+	bn_check_top(p2);
+	bn_check_top(m);
+
+	if (!(m->d[0] & 1))
+		{
+		BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
+		return(0);
+		}
+	bits1=BN_num_bits(p1);
+	bits2=BN_num_bits(p2);
+	if ((bits1 == 0) && (bits2 == 0))
+		{
+		BN_one(rr);
+		return(1);
+		}
+
+	BN_CTX_start(ctx);
+	d = BN_CTX_get(ctx);
+	r = BN_CTX_get(ctx);
+	if (d == NULL || r == NULL) goto err;
+
+	bits=(bits1 > bits2)?bits1:bits2;
+
+	/* If this is not done, things will break in the montgomery
+	 * part */
+
+	if (in_mont != NULL)
+		mont=in_mont;
+	else
+		{
+		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+		}
+
+	BN_init(&(val[0][0]));
+	BN_init(&(val[1][1]));
+	BN_init(&(val[0][1]));
+	BN_init(&(val[1][0]));
+	ts=1;
+	if (BN_ucmp(a1,m) >= 0)
+		{
+		BN_mod(&(val[1][0]),a1,m,ctx);
+		aa1= &(val[1][0]);
+		}
+	else
+		aa1=a1;
+	if (BN_ucmp(a2,m) >= 0)
+		{
+		BN_mod(&(val[0][1]),a2,m,ctx);
+		aa2= &(val[0][1]);
+		}
+	else
+		aa2=a2;
+	if (!BN_to_montgomery(&(val[1][0]),aa1,mont,ctx)) goto err;
+	if (!BN_to_montgomery(&(val[0][1]),aa2,mont,ctx)) goto err;
+	if (!BN_mod_mul_montgomery(&(val[1][1]),
+		&(val[1][0]),&(val[0][1]),mont,ctx))
+		goto err;
+
+#if 0
+	if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */
+		window=1;
+	else if (bits > 250)
+		window=5;	/* max size of window */
+	else if (bits >= 120)
+		window=4;
+	else
+		window=3;
+#else
+	window=EXP2_TABLE_BITS;
+#endif
+
+	k=1<<window;
+	for (x=0; x<k; x++)
+		{
+		if (x >= 2)
+			{
+			BN_init(&(val[x][0]));
+			BN_init(&(val[x][1]));
+			if (!BN_mod_mul_montgomery(&(val[x][0]),
+				&(val[1][0]),&(val[x-1][0]),mont,ctx)) goto err;
+			if (!BN_mod_mul_montgomery(&(val[x][1]),
+				&(val[1][0]),&(val[x-1][1]),mont,ctx)) goto err;
+			}
+		for (y=2; y<k; y++)
+			{
+			BN_init(&(val[x][y]));
+			if (!BN_mod_mul_montgomery(&(val[x][y]),
+				&(val[x][y-1]),&(val[0][1]),mont,ctx))
+				goto err;
+			}
+		}
+	ts=k;
+
+	start=1;	/* This is used to avoid multiplication etc
+			 * when there is only the value '1' in the
+			 * buffer. */
+	xvalue=0;	/* The 'x value' of the window */
+	yvalue=0;	/* The 'y value' of the window */
+	wstart=bits-1;	/* The top bit of the window */
+	wend=0;		/* The bottom bit of the window */
+
+        if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+	for (;;)
+		{
+		xvalue=BN_is_bit_set(p1,wstart);
+		yvalue=BN_is_bit_set(p2,wstart);
+		if (!(xvalue || yvalue))
+			{
+			if (!start)
+				{
+				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+					goto err;
+				}
+			wstart--;
+			if (wstart < 0) break;
+			continue;
+			}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j=wstart;
+		/* xvalue=BN_is_bit_set(p1,wstart); already set */
+		/* yvalue=BN_is_bit_set(p1,wstart); already set */
+		wend=0;
+		for (i=1; i<window; i++)
+			{
+			if (wstart-i < 0) break;
+			xvalue+=xvalue;
+			xvalue|=BN_is_bit_set(p1,wstart-i);
+			yvalue+=yvalue;
+			yvalue|=BN_is_bit_set(p2,wstart-i);
+			}
+
+		/* i is the size of the current window */
+		/* add the 'bytes above' */
+		if (!start)
+			for (j=0; j<i; j++)
+				{
+				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+					goto err;
+				}
+		
+		/* wvalue will be an odd number < 2^window */
+		if (xvalue || yvalue)
+			{
+			if (!BN_mod_mul_montgomery(r,r,&(val[xvalue][yvalue]),
+				mont,ctx)) goto err;
+			}
+
+		/* move the 'window' down further */
+		wstart-=i;
+		start=0;
+		if (wstart < 0) break;
+		}
+	BN_from_montgomery(rr,r,mont,ctx);
+	ret=1;
+err:
+	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+	BN_CTX_end(ctx);
+	for (i=0; i<ts; i++)
+		{
+		for (j=0; j<ts; j++)
+			{
+			BN_clear_free(&(val[i][j]));
+			}
+		}
+	return(ret);
+	}
diff --git a/AppleCSP/open_ssl/bn/bn_gcd.c b/AppleCSP/open_ssl/bn/bn_gcd.c
new file mode 100644
index 00000000..f0d6eacc
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_gcd.c
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_gcd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
+
+int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*t;
+	int ret=0;
+
+	bn_check_top(in_a);
+	bn_check_top(in_b);
+
+	BN_CTX_start(ctx);
+	a = BN_CTX_get(ctx);
+	b = BN_CTX_get(ctx);
+	if (a == NULL || b == NULL) goto err;
+
+	if (BN_copy(a,in_a) == NULL) goto err;
+	if (BN_copy(b,in_b) == NULL) goto err;
+
+	if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; }
+	t=euclid(a,b);
+	if (t == NULL) goto err;
+
+	if (BN_copy(r,t) == NULL) goto err;
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
+	{
+	BIGNUM *t;
+	int shifts=0;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	for (;;)
+		{
+		if (BN_is_zero(b))
+			break;
+
+		if (BN_is_odd(a))
+			{
+			if (BN_is_odd(b))
+				{
+				if (!BN_sub(a,a,b)) goto err;
+				if (!BN_rshift1(a,a)) goto err;
+				if (BN_cmp(a,b) < 0)
+					{ t=a; a=b; b=t; }
+				}
+			else		/* a odd - b even */
+				{
+				if (!BN_rshift1(b,b)) goto err;
+				if (BN_cmp(a,b) < 0)
+					{ t=a; a=b; b=t; }
+				}
+			}
+		else			/* a is even */
+			{
+			if (BN_is_odd(b))
+				{
+				if (!BN_rshift1(a,a)) goto err;
+				if (BN_cmp(a,b) < 0)
+					{ t=a; a=b; b=t; }
+				}
+			else		/* a even - b even */
+				{
+				if (!BN_rshift1(a,a)) goto err;
+				if (!BN_rshift1(b,b)) goto err;
+				shifts++;
+				}
+			}
+		}
+	if (shifts)
+		{
+		if (!BN_lshift(a,a,shifts)) goto err;
+		}
+	return(a);
+err:
+	return(NULL);
+	}
+
+/* solves ax == 1 (mod n) */
+BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+	{
+	BIGNUM *A,*B,*X,*Y,*M,*D,*R=NULL;
+	BIGNUM *T,*ret=NULL;
+	int sign;
+
+	bn_check_top(a);
+	bn_check_top(n);
+
+	BN_CTX_start(ctx);
+	A = BN_CTX_get(ctx);
+	B = BN_CTX_get(ctx);
+	X = BN_CTX_get(ctx);
+	D = BN_CTX_get(ctx);
+	M = BN_CTX_get(ctx);
+	Y = BN_CTX_get(ctx);
+	if (Y == NULL) goto err;
+
+	if (in == NULL)
+		R=BN_new();
+	else
+		R=in;
+	if (R == NULL) goto err;
+
+	BN_zero(X);
+	BN_one(Y);
+	if (BN_copy(A,a) == NULL) goto err;
+	if (BN_copy(B,n) == NULL) goto err;
+	sign=1;
+
+	while (!BN_is_zero(B))
+		{
+		if (!BN_div(D,M,A,B,ctx)) goto err;
+		T=A;
+		A=B;
+		B=M;
+		/* T has a struct, M does not */
+
+		if (!BN_mul(T,D,X,ctx)) goto err;
+		if (!BN_add(T,T,Y)) goto err;
+		M=Y;
+		Y=X;
+		X=T;
+		sign= -sign;
+		}
+	if (sign < 0)
+		{
+		if (!BN_sub(Y,n,Y)) goto err;
+		}
+
+	if (BN_is_one(A))
+		{ if (!BN_mod(R,Y,n,ctx)) goto err; }
+	else
+		{
+		BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
+		goto err;
+		}
+	ret=R;
+err:
+	if ((ret == NULL) && (in == NULL)) BN_free(R);
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_lcl.h b/AppleCSP/open_ssl/bn/bn_lcl.h
new file mode 100644
index 00000000..a8fd07b1
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_lcl.h
@@ -0,0 +1,339 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BN_LCL_H
+#define HEADER_BN_LCL_H
+
+#include <openssl/bn.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha       16,16,16,16.64 */
+#define BN_MULL_SIZE_NORMAL			(16) /* 32 */
+#define BN_MUL_RECURSIVE_SIZE_NORMAL		(16) /* 32 less than */
+#define BN_SQR_RECURSIVE_SIZE_NORMAL		(16) /* 32 */
+#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL	(32) /* 32 */
+#define BN_MONT_CTX_SET_SIZE_WORD		(64) /* 32 */
+
+#if !defined(NO_ASM) && !defined(NO_INLINE_ASM) && !defined(PEDANTIC)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ *					<appro@fy.chalmers.se>
+ */
+# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+#  if defined(__DECC)
+#   include <c_asm.h>
+#   define BN_UMULT_HIGH(a,b)	(BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
+#  elif defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)	({	\
+	register BN_ULONG ret;		\
+	asm ("umulh	%1,%2,%0"	\
+	     : "=r"(ret)		\
+	     : "r"(a), "r"(b));		\
+	ret;			})
+#  endif	/* compiler */
+# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
+#  if defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)	({	\
+	register BN_ULONG ret;		\
+	asm ("mulhdu	%0,%1,%2"	\
+	     : "=r"(ret)		\
+	     : "r"(a), "r"(b));		\
+	ret;			})
+#  endif	/* compiler */
+# endif		/* cpu */
+#endif		/* NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+#define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
+#define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+/* This is used for internal error checking and is not normally used */
+#ifdef BN_DEBUG
+# include <assert.h>
+# define bn_check_top(a) assert ((a)->top >= 0 && (a)->top <= (a)->max);
+#else
+# define bn_check_top(a)
+#endif
+
+/* This macro is to add extra stuff for development checking */
+#ifdef BN_DEBUG
+#define	bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
+#else
+#define	bn_set_max(r)
+#endif
+
+/* These macros are used to 'take' a section of a bignum for read only use */
+#define bn_set_low(r,a,n) \
+	{ \
+	(r)->top=((a)->top > (n))?(n):(a)->top; \
+	(r)->d=(a)->d; \
+	(r)->neg=(a)->neg; \
+	(r)->flags|=BN_FLG_STATIC_DATA; \
+	bn_set_max(r); \
+	}
+
+#define bn_set_high(r,a,n) \
+	{ \
+	if ((a)->top > (n)) \
+		{ \
+		(r)->top=(a)->top-n; \
+		(r)->d= &((a)->d[n]); \
+		} \
+	else \
+		(r)->top=0; \
+	(r)->neg=(a)->neg; \
+	(r)->flags|=BN_FLG_STATIC_DATA; \
+	bn_set_max(r); \
+	}
+
+#ifdef BN_LLONG
+#define mul_add(r,a,w,c) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)w * (a) + (r) + (c); \
+	(r)= Lw(t); \
+	(c)= Hw(t); \
+	}
+
+#define mul(r,a,w,c) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)w * (a) + (c); \
+	(r)= Lw(t); \
+	(c)= Hw(t); \
+	}
+
+#define sqr(r0,r1,a) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)(a)*(a); \
+	(r0)=Lw(t); \
+	(r1)=Hw(t); \
+	}
+
+#elif defined(BN_UMULT_HIGH)
+#define mul_add(r,a,w,c) {		\
+	BN_ULONG high,low,ret,tmp=(a);	\
+	ret =  (r);			\
+	high=  BN_UMULT_HIGH(w,tmp);	\
+	ret += (c);			\
+	low =  (w) * tmp;		\
+	(c) =  (ret<(c))?1:0;		\
+	(c) += high;			\
+	ret += low;			\
+	(c) += (ret<low)?1:0;		\
+	(r) =  ret;			\
+	}
+
+#define mul(r,a,w,c)	{		\
+	BN_ULONG high,low,ret,ta=(a);	\
+	low =  (w) * ta;		\
+	high=  BN_UMULT_HIGH(w,ta);	\
+	ret =  low + (c);		\
+	(c) =  high;			\
+	(c) += (ret<low)?1:0;		\
+	(r) =  ret;			\
+	}
+
+#define sqr(r0,r1,a)	{		\
+	BN_ULONG tmp=(a);		\
+	(r0) = tmp * tmp;		\
+	(r1) = BN_UMULT_HIGH(tmp,tmp);	\
+	}
+
+#else
+/*************************************************************
+ * No long long type
+ */
+
+#define LBITS(a)	((a)&BN_MASK2l)
+#define HBITS(a)	(((a)>>BN_BITS4)&BN_MASK2l)
+#define	L2HBITS(a)	((BN_ULONG)((a)&BN_MASK2l)<<BN_BITS4)
+
+#define LLBITS(a)	((a)&BN_MASKl)
+#define LHBITS(a)	(((a)>>BN_BITS2)&BN_MASKl)
+#define	LL2HBITS(a)	((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
+
+#define mul64(l,h,bl,bh) \
+	{ \
+	BN_ULONG m,m1,lt,ht; \
+ \
+	lt=l; \
+	ht=h; \
+	m =(bh)*(lt); \
+	lt=(bl)*(lt); \
+	m1=(bl)*(ht); \
+	ht =(bh)*(ht); \
+	m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \
+	ht+=HBITS(m); \
+	m1=L2HBITS(m); \
+	lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
+	(l)=lt; \
+	(h)=ht; \
+	}
+
+#define sqr64(lo,ho,in) \
+	{ \
+	BN_ULONG l,h,m; \
+ \
+	h=(in); \
+	l=LBITS(h); \
+	h=HBITS(h); \
+	m =(l)*(h); \
+	l*=l; \
+	h*=h; \
+	h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
+	m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+	l=(l+m)&BN_MASK2; if (l < m) h++; \
+	(lo)=l; \
+	(ho)=h; \
+	}
+
+#define mul_add(r,a,bl,bh,c) { \
+	BN_ULONG l,h; \
+ \
+	h= (a); \
+	l=LBITS(h); \
+	h=HBITS(h); \
+	mul64(l,h,(bl),(bh)); \
+ \
+	/* non-multiply part */ \
+	l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+	(c)=(r); \
+	l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+	(c)=h&BN_MASK2; \
+	(r)=l; \
+	}
+
+#define mul(r,a,bl,bh,c) { \
+	BN_ULONG l,h; \
+ \
+	h= (a); \
+	l=LBITS(h); \
+	h=HBITS(h); \
+	mul64(l,h,(bl),(bh)); \
+ \
+	/* non-multiply part */ \
+	l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+	(c)=h&BN_MASK2; \
+	(r)=l&BN_MASK2; \
+	}
+#endif /* !BN_LLONG */
+
+void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
+void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r,BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r,BN_ULONG *a);
+int bn_cmp_words(BN_ULONG *a,BN_ULONG *b,int n);
+void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
+	int tn, int n,BN_ULONG *t);
+void bn_sqr_recursive(BN_ULONG *r,BN_ULONG *a, int n2, BN_ULONG *t);
+void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
+void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
+	BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,
+	BN_ULONG *t);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/bn/bn_lib.c b/AppleCSP/open_ssl/bn/bn_lib.c
new file mode 100644
index 00000000..9ec461ff
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_lib.c
@@ -0,0 +1,776 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
+
+#if		BN_PARAMS_ENABLE
+
+/* For a 32 bit machine
+ * 2 -   4 ==  128
+ * 3 -   8 ==  256
+ * 4 -  16 ==  512
+ * 5 -  32 == 1024
+ * 6 -  64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+static int bn_limit_bits=0;
+static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
+static int bn_limit_bits_low=0;
+static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
+static int bn_limit_bits_high=0;
+static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
+static int bn_limit_bits_mont=0;
+static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
+
+void BN_set_params(int mult, int high, int low, int mont)
+	{
+	if (mult >= 0)
+		{
+		if (mult > (sizeof(int)*8)-1)
+			mult=sizeof(int)*8-1;
+		bn_limit_bits=mult;
+		bn_limit_num=1<<mult;
+		}
+	if (high >= 0)
+		{
+		if (high > (sizeof(int)*8)-1)
+			high=sizeof(int)*8-1;
+		bn_limit_bits_high=high;
+		bn_limit_num_high=1<<high;
+		}
+	if (low >= 0)
+		{
+		if (low > (sizeof(int)*8)-1)
+			low=sizeof(int)*8-1;
+		bn_limit_bits_low=low;
+		bn_limit_num_low=1<<low;
+		}
+	if (mont >= 0)
+		{
+		if (mont > (sizeof(int)*8)-1)
+			mont=sizeof(int)*8-1;
+		bn_limit_bits_mont=mont;
+		bn_limit_num_mont=1<<mont;
+		}
+	}
+
+int BN_get_params(int which)
+	{
+	if      (which == 0) return(bn_limit_bits);
+	else if (which == 1) return(bn_limit_bits_high);
+	else if (which == 2) return(bn_limit_bits_low);
+	else if (which == 3) return(bn_limit_bits_mont);
+	else return(0);
+	}
+#endif	/* BN_PARAMS_ENABLE */
+
+BIGNUM *BN_value_one(void)
+	{
+	static BN_ULONG data_one=1L;
+	static BIGNUM const_one={&data_one,1,1,0};
+
+	return(&const_one);
+	}
+
+char *BN_options(void)
+	{
+	static int init=0;
+	static char data[16];
+
+	if (!init)
+		{
+		init++;
+#ifdef BN_LLONG
+		sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
+			(int)sizeof(BN_ULONG)*8);
+#else
+		sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
+			(int)sizeof(BN_ULONG)*8);
+#endif
+		}
+	return(data);
+	}
+
+int BN_num_bits_word(BN_ULONG l)
+	{
+	static const char bits[256]={
+		0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
+		5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+		};
+
+#if defined(SIXTY_FOUR_BIT_LONG)
+	if (l & 0xffffffff00000000L)
+		{
+		if (l & 0xffff000000000000L)
+			{
+			if (l & 0xff00000000000000L)
+				{
+				return(bits[(int)(l>>56)]+56);
+				}
+			else	return(bits[(int)(l>>48)]+48);
+			}
+		else
+			{
+			if (l & 0x0000ff0000000000L)
+				{
+				return(bits[(int)(l>>40)]+40);
+				}
+			else	return(bits[(int)(l>>32)]+32);
+			}
+		}
+	else
+#else
+#ifdef SIXTY_FOUR_BIT
+	if (l & 0xffffffff00000000LL)
+		{
+		if (l & 0xffff000000000000LL)
+			{
+			if (l & 0xff00000000000000LL)
+				{
+				return(bits[(int)(l>>56)]+56);
+				}
+			else	return(bits[(int)(l>>48)]+48);
+			}
+		else
+			{
+			if (l & 0x0000ff0000000000LL)
+				{
+				return(bits[(int)(l>>40)]+40);
+				}
+			else	return(bits[(int)(l>>32)]+32);
+			}
+		}
+	else
+#endif
+#endif
+		{
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+		if (l & 0xffff0000L)
+			{
+			if (l & 0xff000000L)
+				return(bits[(int)(l>>24L)]+24);
+			else	return(bits[(int)(l>>16L)]+16);
+			}
+		else
+#endif
+			{
+#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+			if (l & 0xff00L)
+				return(bits[(int)(l>>8)]+8);
+			else	
+#endif
+				return(bits[(int)(l   )]  );
+			}
+		}
+	}
+
+int BN_num_bits(const BIGNUM *a)
+	{
+	BN_ULONG l;
+	int i;
+
+	bn_check_top(a);
+
+	if (a->top == 0) return(0);
+	l=a->d[a->top-1];
+	i=(a->top-1)*BN_BITS2;
+	if (l == 0)
+		{
+#if !defined(NO_STDIO) && !defined(WIN16)
+		fprintf(stderr,"BAD TOP VALUE\n");
+#endif
+		abort();
+		}
+	return(i+BN_num_bits_word(l));
+	}
+
+void BN_clear_free(BIGNUM *a)
+	{
+	int i;
+
+	if (a == NULL) return;
+	if (a->d != NULL)
+		{
+		memset(a->d,0,a->max*sizeof(a->d[0]));
+		if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+			Free(a->d);
+		}
+	i=BN_get_flags(a,BN_FLG_MALLOCED);
+	memset(a,0,sizeof(BIGNUM));
+	if (i)
+		Free(a);
+	}
+
+void BN_free(BIGNUM *a)
+	{
+	if (a == NULL) return;
+	if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+		Free(a->d);
+	a->flags|=BN_FLG_FREE; /* REMOVE? */
+	if (a->flags & BN_FLG_MALLOCED)
+		Free(a);
+	}
+
+void BN_init(BIGNUM *a)
+	{
+	memset(a,0,sizeof(BIGNUM));
+	}
+
+BIGNUM *BN_new(void)
+	{
+	BIGNUM *ret;
+
+	if ((ret=(BIGNUM *)Malloc(sizeof(BIGNUM))) == NULL)
+		{
+		BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->flags=BN_FLG_MALLOCED;
+	ret->top=0;
+	ret->neg=0;
+	ret->max=0;
+	ret->d=NULL;
+	return(ret);
+	}
+
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'words' word number number.
+ * It is mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. If not, 'b' is returned. */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+	{
+	BN_ULONG *A,*a;
+	const BN_ULONG *B;
+	int i;
+
+	bn_check_top(b);
+
+	if (words > b->max)
+		{
+		bn_check_top(b);	
+		if (BN_get_flags(b,BN_FLG_STATIC_DATA))
+			{
+			BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+			return(NULL);
+			}
+		a=A=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(words+1));
+		if (A == NULL)
+			{
+			BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
+			return(NULL);
+			}
+#if 1
+		B=b->d;
+		/* Check if the previous number needs to be copied */
+		if (B != NULL)
+			{
+#if 0
+			/* This lot is an unrolled loop to copy b->top 
+			 * BN_ULONGs from B to A
+			 */
+/*
+ * I have nothing against unrolling but it's usually done for
+ * several reasons, namely:
+ * - minimize percentage of decision making code, i.e. branches;
+ * - avoid cache trashing;
+ * - make it possible to schedule loads earlier;
+ * Now let's examine the code below. The cornerstone of C is
+ * "programmer is always right" and that's what we love it for:-)
+ * For this very reason C compilers have to be paranoid when it
+ * comes to data aliasing and assume the worst. Yeah, but what
+ * does it mean in real life? This means that loop body below will
+ * be compiled to sequence of loads immediately followed by stores
+ * as compiler assumes the worst, something in A==B+1 style. As a
+ * result CPU pipeline is going to starve for incoming data. Secondly
+ * if A and B happen to share same cache line such code is going to
+ * cause severe cache trashing. Both factors have severe impact on
+ * performance of modern CPUs and this is the reason why this
+ * particular piece of code is #ifdefed away and replaced by more
+ * "friendly" version found in #else section below. This comment
+ * also applies to BN_copy function.
+ *
+ *					<appro@fy.chalmers.se>
+ */
+			for (i=b->top&(~7); i>0; i-=8)
+				{
+				A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
+				A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
+				A+=8;
+				B+=8;
+				}
+			switch (b->top&7)
+				{
+			case 7:
+				A[6]=B[6];
+			case 6:
+				A[5]=B[5];
+			case 5:
+				A[4]=B[4];
+			case 4:
+				A[3]=B[3];
+			case 3:
+				A[2]=B[2];
+			case 2:
+				A[1]=B[1];
+			case 1:
+				A[0]=B[0];
+			case 0:
+				/* I need the 'case 0' entry for utrix cc.
+				 * If the optimizer is turned on, it does the
+				 * switch table by doing
+				 * a=top&7
+				 * a--;
+				 * goto jump_table[a];
+				 * If top is 0, this makes us jump to 0xffffffc 
+				 * which is rather bad :-(.
+				 * eric 23-Apr-1998
+				 */
+				;
+				}
+#else
+			for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+				{
+				/*
+				 * The fact that the loop is unrolled
+				 * 4-wise is a tribute to Intel. It's
+				 * the one that doesn't have enough
+				 * registers to accomodate more data.
+				 * I'd unroll it 8-wise otherwise:-)
+				 *
+				 *		<appro@fy.chalmers.se>
+				 */
+				BN_ULONG a0,a1,a2,a3;
+				a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+				A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+				}
+			switch (b->top&3)
+				{
+				case 3:	A[2]=B[2];
+				case 2:	A[1]=B[1];
+				case 1:	A[0]=B[0];
+				case 0:	; /* ultrix cc workaround, see above */
+				}
+#endif
+			Free(b->d);
+			}
+
+		b->d=a;
+		b->max=words;
+
+		/* Now need to zero any data between b->top and b->max */
+
+		A= &(b->d[b->top]);
+		for (i=(b->max - b->top)>>3; i>0; i--,A+=8)
+			{
+			A[0]=0; A[1]=0; A[2]=0; A[3]=0;
+			A[4]=0; A[5]=0; A[6]=0; A[7]=0;
+			}
+		for (i=(b->max - b->top)&7; i>0; i--,A++)
+			A[0]=0;
+#else
+			memset(A,0,sizeof(BN_ULONG)*(words+1));
+			memcpy(A,b->d,sizeof(b->d[0])*b->top);
+			b->d=a;
+			b->max=words;
+#endif
+		
+/*		memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
+/*	{ int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
+
+		}
+	return(b);
+	}
+
+BIGNUM *BN_dup(const BIGNUM *a)
+	{
+	BIGNUM *r;
+
+	if (a == NULL) return NULL;
+
+	bn_check_top(a);
+
+	r=BN_new();
+	if (r == NULL) return(NULL);
+	return((BIGNUM *)BN_copy(r,a));
+	}
+
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
+	{
+	int i;
+	BN_ULONG *A;
+	const BN_ULONG *B;
+
+	bn_check_top(b);
+
+	if (a == b) return(a);
+	if (bn_wexpand(a,b->top) == NULL) return(NULL);
+
+#if 1
+	A=a->d;
+	B=b->d;
+	for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+		{
+		BN_ULONG a0,a1,a2,a3;
+		a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+		A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+		}
+	switch (b->top&3)
+		{
+		case 3: A[2]=B[2];
+		case 2: A[1]=B[1];
+		case 1: A[0]=B[0];
+		case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
+		}
+#else
+	memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
+#endif
+
+/*	memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
+	a->top=b->top;
+	if ((a->top == 0) && (a->d != NULL))
+		a->d[0]=0;
+	a->neg=b->neg;
+	return(a);
+	}
+
+void BN_clear(BIGNUM *a)
+	{
+	if (a->d != NULL)
+		memset(a->d,0,a->max*sizeof(a->d[0]));
+	a->top=0;
+	a->neg=0;
+	}
+
+BN_ULONG BN_get_word(BIGNUM *a)
+	{
+	int i,n;
+	BN_ULONG ret=0;
+
+	n=BN_num_bytes(a);
+	if (n > sizeof(BN_ULONG))
+		return(BN_MASK2);
+	for (i=a->top-1; i>=0; i--)
+		{
+#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
+		ret<<=BN_BITS4; /* stops the compiler complaining */
+		ret<<=BN_BITS4;
+#else
+		ret=0;
+#endif
+		ret|=a->d[i];
+		}
+	return(ret);
+	}
+
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+	{
+	int i,n;
+	if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
+
+	n=sizeof(BN_ULONG)/BN_BYTES;
+	a->neg=0;
+	a->top=0;
+	a->d[0]=(BN_ULONG)w&BN_MASK2;
+	if (a->d[0] != 0) a->top=1;
+	for (i=1; i<n; i++)
+		{
+		/* the following is done instead of
+		 * w>>=BN_BITS2 so compilers don't complain
+		 * on builds where sizeof(long) == BN_TYPES */
+#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
+		w>>=BN_BITS4;
+		w>>=BN_BITS4;
+#else
+		w=0;
+#endif
+		a->d[i]=(BN_ULONG)w&BN_MASK2;
+		if (a->d[i] != 0) a->top=i+1;
+		}
+	return(1);
+	}
+
+/* ignore negative */
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+	{
+	unsigned int i,m;
+	unsigned int n;
+	BN_ULONG l;
+
+	if (ret == NULL) ret=BN_new();
+	if (ret == NULL) return(NULL);
+	l=0;
+	n=len;
+	if (n == 0)
+		{
+		ret->top=0;
+		return(ret);
+		}
+	if (bn_expand(ret,(int)(n+2)*8) == NULL)
+		return(NULL);
+	i=((n-1)/BN_BYTES)+1;
+	m=((n-1)%(BN_BYTES));
+	ret->top=i;
+	while (n-- > 0)
+		{
+		l=(l<<8L)| *(s++);
+		if (m-- == 0)
+			{
+			ret->d[--i]=l;
+			l=0;
+			m=BN_BYTES-1;
+			}
+		}
+	/* need to call this due to clear byte at top if avoiding
+	 * having the top bit set (-ve number) */
+	bn_fix_top(ret);
+	return(ret);
+	}
+
+/* ignore negative */
+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
+	{
+	int n,i;
+	BN_ULONG l;
+
+	n=i=BN_num_bytes(a);
+	while (i-- > 0)
+		{
+		l=a->d[i/BN_BYTES];
+		*(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
+		}
+	return(n);
+	}
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+	{
+	int i;
+	BN_ULONG t1,t2,*ap,*bp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	i=a->top-b->top;
+	if (i != 0) return(i);
+	ap=a->d;
+	bp=b->d;
+	for (i=a->top-1; i>=0; i--)
+		{
+		t1= ap[i];
+		t2= bp[i];
+		if (t1 != t2)
+			return(t1 > t2?1:-1);
+		}
+	return(0);
+	}
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
+	{
+	int i;
+	int gt,lt;
+	BN_ULONG t1,t2;
+
+	if ((a == NULL) || (b == NULL))
+		{
+		if (a != NULL)
+			return(-1);
+		else if (b != NULL)
+			return(1);
+		else
+			return(0);
+		}
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->neg != b->neg)
+		{
+		if (a->neg)
+			return(-1);
+		else	return(1);
+		}
+	if (a->neg == 0)
+		{ gt=1; lt= -1; }
+	else	{ gt= -1; lt=1; }
+
+	if (a->top > b->top) return(gt);
+	if (a->top < b->top) return(lt);
+	for (i=a->top-1; i>=0; i--)
+		{
+		t1=a->d[i];
+		t2=b->d[i];
+		if (t1 > t2) return(gt);
+		if (t1 < t2) return(lt);
+		}
+	return(0);
+	}
+
+int BN_set_bit(BIGNUM *a, int n)
+	{
+	int i,j,k;
+
+	i=n/BN_BITS2;
+	j=n%BN_BITS2;
+	if (a->top <= i)
+		{
+		if (bn_wexpand(a,i+1) == NULL) return(0);
+		for(k=a->top; k<i+1; k++)
+			a->d[k]=0;
+		a->top=i+1;
+		}
+
+	a->d[i]|=(((BN_ULONG)1)<<j);
+	return(1);
+	}
+
+int BN_clear_bit(BIGNUM *a, int n)
+	{
+	int i,j;
+
+	i=n/BN_BITS2;
+	j=n%BN_BITS2;
+	if (a->top <= i) return(0);
+
+	a->d[i]&=(~(((BN_ULONG)1)<<j));
+	bn_fix_top(a);
+	return(1);
+	}
+
+int BN_is_bit_set(const BIGNUM *a, int n)
+	{
+	int i,j;
+
+	if (n < 0) return(0);
+	i=n/BN_BITS2;
+	j=n%BN_BITS2;
+	if (a->top <= i) return(0);
+	return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
+	}
+
+int BN_mask_bits(BIGNUM *a, int n)
+	{
+	int b,w;
+
+	w=n/BN_BITS2;
+	b=n%BN_BITS2;
+	if (w >= a->top) return(0);
+	if (b == 0)
+		a->top=w;
+	else
+		{
+		a->top=w+1;
+		a->d[w]&= ~(BN_MASK2<<b);
+		}
+	bn_fix_top(a);
+	return(1);
+	}
+
+int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
+	{
+	int i;
+	BN_ULONG aa,bb;
+
+	aa=a[n-1];
+	bb=b[n-1];
+	if (aa != bb) return((aa > bb)?1:-1);
+	for (i=n-2; i>=0; i--)
+		{
+		aa=a[i];
+		bb=b[i];
+		if (aa != bb) return((aa > bb)?1:-1);
+		}
+	return(0);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_mont.c b/AppleCSP/open_ssl/bn/bn_mont.c
new file mode 100644
index 00000000..69e573b3
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_mont.c
@@ -0,0 +1,357 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_mont.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * Details about Montgomery multiplication algorithms can be found at
+ * http://security.ece.orst.edu/publications.html, e.g.
+ * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
+ * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define MONT_WORD /* use the faster word-based algorithm */
+
+int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+			  BN_MONT_CTX *mont, BN_CTX *ctx)
+	{
+	BIGNUM *tmp,*tmp2;
+	int ret=0;
+
+	BN_CTX_start(ctx);
+	tmp = BN_CTX_get(ctx);
+	tmp2 = BN_CTX_get(ctx);
+	if (tmp == NULL || tmp2 == NULL) goto err;
+
+	bn_check_top(tmp);
+	bn_check_top(tmp2);
+
+	if (a == b)
+		{
+#if 0
+		bn_wexpand(tmp,a->top*2);
+		bn_wexpand(tmp2,a->top*4);
+		bn_sqr_recursive(tmp->d,a->d,a->top,tmp2->d);
+		tmp->top=a->top*2;
+		if (tmp->d[tmp->top-1] == 0)
+			tmp->top--;
+#else
+		if (!BN_sqr(tmp,a,ctx)) goto err;
+#endif
+		}
+	else
+		{
+		if (!BN_mul(tmp,a,b,ctx)) goto err;
+		}
+	/* reduce from aRR to aR */
+	if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
+	     BN_CTX *ctx)
+	{
+	int retn=0;
+
+#ifdef MONT_WORD
+	BIGNUM *n,*r;
+	BN_ULONG *ap,*np,*rp,n0,v,*nrp;
+	int al,nl,max,i,x,ri;
+
+	BN_CTX_start(ctx);
+	if ((r = BN_CTX_get(ctx)) == NULL) goto err;
+
+	if (!BN_copy(r,a)) goto err;
+	n= &(mont->N);
+
+	ap=a->d;
+	/* mont->ri is the size of mont->N in bits (rounded up
+	   to the word size) */
+	al=ri=mont->ri/BN_BITS2;
+	
+	nl=n->top;
+	if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
+
+	max=(nl+al+1); /* allow for overflow (no?) XXX */
+	if (bn_wexpand(r,max) == NULL) goto err;
+	if (bn_wexpand(ret,max) == NULL) goto err;
+
+	r->neg=a->neg^n->neg;
+	np=n->d;
+	rp=r->d;
+	nrp= &(r->d[nl]);
+
+	/* clear the top words of T */
+#if 1
+	for (i=r->top; i<max; i++) /* memset? XXX */
+		r->d[i]=0;
+#else
+	memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
+#endif
+
+	r->top=max;
+	n0=mont->n0;
+
+#ifdef BN_COUNT
+	printf("word BN_from_montgomery %d * %d\n",nl,nl);
+#endif
+	for (i=0; i<nl; i++)
+		{
+		v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+		nrp++;
+		rp++;
+		if (((nrp[-1]+=v)&BN_MASK2) >= v)
+			continue;
+		else
+			{
+			if (((++nrp[0])&BN_MASK2) != 0) continue;
+			if (((++nrp[1])&BN_MASK2) != 0) continue;
+			for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
+			}
+		}
+	bn_fix_top(r);
+	
+	/* mont->ri will be a multiple of the word size */
+#if 0
+	BN_rshift(ret,r,mont->ri);
+#else
+	x=ri;
+	rp=ret->d;
+	ap= &(r->d[x]);
+	if (r->top < x)
+		al=0;
+	else
+		al=r->top-x;
+	ret->top=al;
+	al-=4;
+	for (i=0; i<al; i+=4)
+		{
+		BN_ULONG t1,t2,t3,t4;
+		
+		t1=ap[i+0];
+		t2=ap[i+1];
+		t3=ap[i+2];
+		t4=ap[i+3];
+		rp[i+0]=t1;
+		rp[i+1]=t2;
+		rp[i+2]=t3;
+		rp[i+3]=t4;
+		}
+	al+=4;
+	for (; i<al; i++)
+		rp[i]=ap[i];
+#endif
+#else /* !MONT_WORD */ 
+	BIGNUM *t1,*t2;
+
+	BN_CTX_start(ctx);
+	t1 = BN_CTX_get(ctx);
+	t2 = BN_CTX_get(ctx);
+	if (t1 == NULL || t2 == NULL) goto err;
+	
+	if (!BN_copy(t1,a)) goto err;
+	BN_mask_bits(t1,mont->ri);
+
+	if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
+	BN_mask_bits(t2,mont->ri);
+
+	if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
+	if (!BN_add(t2,a,t1)) goto err;
+	BN_rshift(ret,t2,mont->ri);
+#endif /* MONT_WORD */
+
+	if (BN_ucmp(ret, &(mont->N)) >= 0)
+		{
+		BN_usub(ret,ret,&(mont->N));
+		}
+	retn=1;
+ err:
+	BN_CTX_end(ctx);
+	return(retn);
+	}
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+	{
+	BN_MONT_CTX *ret;
+
+	if ((ret=(BN_MONT_CTX *)Malloc(sizeof(BN_MONT_CTX))) == NULL)
+		return(NULL);
+
+	BN_MONT_CTX_init(ret);
+	ret->flags=BN_FLG_MALLOCED;
+	return(ret);
+	}
+
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+	{
+	ctx->ri=0;
+	BN_init(&(ctx->RR));
+	BN_init(&(ctx->N));
+	BN_init(&(ctx->Ni));
+	ctx->flags=0;
+	}
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
+	{
+	if(mont == NULL)
+	    return;
+
+	BN_free(&(mont->RR));
+	BN_free(&(mont->N));
+	BN_free(&(mont->Ni));
+	if (mont->flags & BN_FLG_MALLOCED)
+		Free(mont);
+	}
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+	{
+	BIGNUM Ri,*R;
+
+	BN_init(&Ri);
+	R= &(mont->RR);					/* grab RR as a temp */
+	BN_copy(&(mont->N),mod);			/* Set N */
+
+#ifdef MONT_WORD
+		{
+		BIGNUM tmod;
+		BN_ULONG buf[2];
+
+		mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
+		BN_zero(R);
+		BN_set_bit(R,BN_BITS2);			/* R */
+
+		buf[0]=mod->d[0]; /* tmod = N mod word size */
+		buf[1]=0;
+		tmod.d=buf;
+		tmod.top=1;
+		tmod.max=2;
+		tmod.neg=mod->neg;
+							/* Ri = R^-1 mod N*/
+		if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
+			goto err;
+		BN_lshift(&Ri,&Ri,BN_BITS2);		/* R*Ri */
+		if (!BN_is_zero(&Ri))
+			BN_sub_word(&Ri,1);
+		else /* if N mod word size == 1 */
+			BN_set_word(&Ri,BN_MASK2);  /* Ri-- (mod word size) */
+		BN_div(&Ri,NULL,&Ri,&tmod,ctx);	/* Ni = (R*Ri-1)/N,
+		                                 * keep only least significant word: */
+		mont->n0=Ri.d[0];
+		BN_free(&Ri);
+		}
+#else /* !MONT_WORD */
+		{ /* bignum version */
+		mont->ri=BN_num_bits(mod);
+		BN_zero(R);
+		BN_set_bit(R,mont->ri);			/* R = 2^ri */
+							/* Ri = R^-1 mod N*/
+		if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL)
+			goto err;
+		BN_lshift(&Ri,&Ri,mont->ri);		/* R*Ri */
+		BN_sub_word(&Ri,1);
+							/* Ni = (R*Ri-1) / N */
+		BN_div(&(mont->Ni),NULL,&Ri,mod,ctx);
+		BN_free(&Ri);
+		}
+#endif
+
+	/* setup RR for conversions */
+	BN_zero(&(mont->RR));
+	BN_set_bit(&(mont->RR),mont->ri*2);
+	BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx);
+
+	return(1);
+err:
+	return(0);
+	}
+
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
+	{
+	if (to == from) return(to);
+
+	BN_copy(&(to->RR),&(from->RR));
+	BN_copy(&(to->N),&(from->N));
+	BN_copy(&(to->Ni),&(from->Ni));
+	to->ri=from->ri;
+	to->n0=from->n0;
+	return(to);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_mpi.c b/AppleCSP/open_ssl/bn/bn_mpi.c
new file mode 100644
index 00000000..1aefdaaf
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_mpi.c
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_mpi.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_bn2mpi(const BIGNUM *a, unsigned char *d)
+	{
+	int bits;
+	int num=0;
+	int ext=0;
+	long l;
+
+	bits=BN_num_bits(a);
+	num=(bits+7)/8;
+	if (bits > 0)
+		{
+		ext=((bits & 0x07) == 0);
+		}
+	if (d == NULL)
+		return(num+4+ext);
+
+	l=num+ext;
+	d[0]=(unsigned char)(l>>24)&0xff;
+	d[1]=(unsigned char)(l>>16)&0xff;
+	d[2]=(unsigned char)(l>> 8)&0xff;
+	d[3]=(unsigned char)(l    )&0xff;
+	if (ext) d[4]=0;
+	num=BN_bn2bin(a,&(d[4+ext]));
+	if (a->neg)
+		d[4]|=0x80;
+	return(num+4+ext);
+	}
+
+BIGNUM *BN_mpi2bn(unsigned char *d, int n, BIGNUM *a)
+	{
+	long len;
+	int neg=0;
+
+	if (n < 4)
+		{
+		BNerr(BN_F_BN_MPI2BN,BN_R_INVALID_LENGTH);
+		return(NULL);
+		}
+	len=((long)d[0]<<24)|((long)d[1]<<16)|((int)d[2]<<8)|(int)d[3];
+	if ((len+4) != n)
+		{
+		BNerr(BN_F_BN_MPI2BN,BN_R_ENCODING_ERROR);
+		return(NULL);
+		}
+
+	if (a == NULL) a=BN_new();
+	if (a == NULL) return(NULL);
+
+	if (len == 0)
+		{
+		a->neg=0;
+		a->top=0;
+		return(a);
+		}
+	d+=4;
+	if ((*d) & 0x80)
+		neg=1;
+	if (BN_bin2bn(d,(int)len,a) == NULL)
+		return(NULL);
+	a->neg=neg;
+	if (neg)
+		{
+		BN_clear_bit(a,BN_num_bits(a)-1);
+		}
+	return(a);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_mul.c b/AppleCSP/open_ssl/bn/bn_mul.c
new file mode 100644
index 00000000..20987d95
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_mul.c
@@ -0,0 +1,812 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_mul.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#ifdef BN_RECURSION
+/* Karatsuba recursive multiplication algorithm
+ * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
+
+/* r is 2*n2 words in size,
+ * a and b are both n2 words in size.
+ * n2 must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n2 words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+	     BN_ULONG *t)
+	{
+	int n=n2/2,c1,c2;
+	unsigned int neg,zero;
+	BN_ULONG ln,lo,*p;
+
+# ifdef BN_COUNT
+	printf(" bn_mul_recursive %d * %d\n",n2,n2);
+# endif
+# ifdef BN_MUL_COMBA
+#  if 0
+	if (n2 == 4)
+		{
+		bn_mul_comba4(r,a,b);
+		return;
+		}
+#  endif
+	if (n2 == 8)
+		{
+		bn_mul_comba8(r,a,b);
+		return; 
+		}
+# endif /* BN_MUL_COMBA */
+	if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
+		{
+		/* This should not happen */
+		bn_mul_normal(r,a,n2,b,n2);
+		return;
+		}
+	/* r=(a[0]-a[1])*(b[1]-b[0]) */
+	c1=bn_cmp_words(a,&(a[n]),n);
+	c2=bn_cmp_words(&(b[n]),b,n);
+	zero=neg=0;
+	switch (c1*3+c2)
+		{
+	case -4:
+		bn_sub_words(t,      &(a[n]),a,      n); /* - */
+		bn_sub_words(&(t[n]),b,      &(b[n]),n); /* - */
+		break;
+	case -3:
+		zero=1;
+		break;
+	case -2:
+		bn_sub_words(t,      &(a[n]),a,      n); /* - */
+		bn_sub_words(&(t[n]),&(b[n]),b,      n); /* + */
+		neg=1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		zero=1;
+		break;
+	case 2:
+		bn_sub_words(t,      a,      &(a[n]),n); /* + */
+		bn_sub_words(&(t[n]),b,      &(b[n]),n); /* - */
+		neg=1;
+		break;
+	case 3:
+		zero=1;
+		break;
+	case 4:
+		bn_sub_words(t,      a,      &(a[n]),n);
+		bn_sub_words(&(t[n]),&(b[n]),b,      n);
+		break;
+		}
+
+# ifdef BN_MUL_COMBA
+	if (n == 4)
+		{
+		if (!zero)
+			bn_mul_comba4(&(t[n2]),t,&(t[n]));
+		else
+			memset(&(t[n2]),0,8*sizeof(BN_ULONG));
+		
+		bn_mul_comba4(r,a,b);
+		bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
+		}
+	else if (n == 8)
+		{
+		if (!zero)
+			bn_mul_comba8(&(t[n2]),t,&(t[n]));
+		else
+			memset(&(t[n2]),0,16*sizeof(BN_ULONG));
+		
+		bn_mul_comba8(r,a,b);
+		bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
+		}
+	else
+# endif /* BN_MUL_COMBA */
+		{
+		p= &(t[n2*2]);
+		if (!zero)
+			bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
+		else
+			memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
+		bn_mul_recursive(r,a,b,n,p);
+		bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p);
+		}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+
+	if (neg) /* if t[32] is negative */
+		{
+		c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+		}
+	else
+		{
+		/* Might have a carry */
+		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
+		}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 * c1 holds the carry bits
+	 */
+	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+	if (c1)
+		{
+		p= &(r[n+n2]);
+		lo= *p;
+		ln=(lo+c1)&BN_MASK2;
+		*p=ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < (BN_ULONG)c1)
+			{
+			do	{
+				p++;
+				lo= *p;
+				ln=(lo+1)&BN_MASK2;
+				*p=ln;
+				} while (ln == 0);
+			}
+		}
+	}
+
+/* n+tn is the word length
+ * t needs to be n*4 is size, as does r */
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
+	     int n, BN_ULONG *t)
+	{
+	int i,j,n2=n*2;
+	unsigned int c1,c2,neg,zero;
+	BN_ULONG ln,lo,*p;
+
+# ifdef BN_COUNT
+	printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n);
+# endif
+	if (n < 8)
+		{
+		i=tn+n;
+		bn_mul_normal(r,a,i,b,i);
+		return;
+		}
+
+	/* r=(a[0]-a[1])*(b[1]-b[0]) */
+	c1=bn_cmp_words(a,&(a[n]),n);
+	c2=bn_cmp_words(&(b[n]),b,n);
+	zero=neg=0;
+	switch (c1*3+c2)
+		{
+	case -4:
+		bn_sub_words(t,      &(a[n]),a,      n); /* - */
+		bn_sub_words(&(t[n]),b,      &(b[n]),n); /* - */
+		break;
+	case -3:
+		zero=1;
+		/* break; */
+	case -2:
+		bn_sub_words(t,      &(a[n]),a,      n); /* - */
+		bn_sub_words(&(t[n]),&(b[n]),b,      n); /* + */
+		neg=1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		zero=1;
+		/* break; */
+	case 2:
+		bn_sub_words(t,      a,      &(a[n]),n); /* + */
+		bn_sub_words(&(t[n]),b,      &(b[n]),n); /* - */
+		neg=1;
+		break;
+	case 3:
+		zero=1;
+		/* break; */
+	case 4:
+		bn_sub_words(t,      a,      &(a[n]),n);
+		bn_sub_words(&(t[n]),&(b[n]),b,      n);
+		break;
+		}
+		/* The zero case isn't yet implemented here. The speedup
+		   would probably be negligible. */
+# if 0
+	if (n == 4)
+		{
+		bn_mul_comba4(&(t[n2]),t,&(t[n]));
+		bn_mul_comba4(r,a,b);
+		bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
+		memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
+		}
+	else
+# endif
+	if (n == 8)
+		{
+		bn_mul_comba8(&(t[n2]),t,&(t[n]));
+		bn_mul_comba8(r,a,b);
+		bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
+		memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
+		}
+	else
+		{
+		p= &(t[n2*2]);
+		bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
+		bn_mul_recursive(r,a,b,n,p);
+		i=n/2;
+		/* If there is only a bottom half to the number,
+		 * just do it */
+		j=tn-i;
+		if (j == 0)
+			{
+			bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p);
+			memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
+			}
+		else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
+				{
+				bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
+					j,i,p);
+				memset(&(r[n2+tn*2]),0,
+					sizeof(BN_ULONG)*(n2-tn*2));
+				}
+		else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
+			{
+			memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
+			if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL)
+				{
+				bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
+				}
+			else
+				{
+				for (;;)
+					{
+					i/=2;
+					if (i < tn)
+						{
+						bn_mul_part_recursive(&(r[n2]),
+							&(a[n]),&(b[n]),
+							tn-i,i,p);
+						break;
+						}
+					else if (i == tn)
+						{
+						bn_mul_recursive(&(r[n2]),
+							&(a[n]),&(b[n]),
+							i,p);
+						break;
+						}
+					}
+				}
+			}
+		}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+
+	if (neg) /* if t[32] is negative */
+		{
+		c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+		}
+	else
+		{
+		/* Might have a carry */
+		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
+		}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 * c1 holds the carry bits
+	 */
+	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+	if (c1)
+		{
+		p= &(r[n+n2]);
+		lo= *p;
+		ln=(lo+c1)&BN_MASK2;
+		*p=ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < c1)
+			{
+			do	{
+				p++;
+				lo= *p;
+				ln=(lo+1)&BN_MASK2;
+				*p=ln;
+				} while (ln == 0);
+			}
+		}
+	}
+
+/* a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ */
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+	     BN_ULONG *t)
+	{
+	int n=n2/2;
+
+# ifdef BN_COUNT
+	printf(" bn_mul_low_recursive %d * %d\n",n2,n2);
+# endif
+
+	bn_mul_recursive(r,a,b,n,&(t[0]));
+	if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
+		{
+		bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
+		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+		bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
+		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+		}
+	else
+		{
+		bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
+		bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
+		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+		bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
+		}
+	}
+
+/* a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ * l is the low words of the output.
+ * t needs to be n2*3
+ */
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+	     BN_ULONG *t)
+	{
+	int i,n;
+	int c1,c2;
+	int neg,oneg,zero;
+	BN_ULONG ll,lc,*lp,*mp;
+
+# ifdef BN_COUNT
+	printf(" bn_mul_high %d * %d\n",n2,n2);
+# endif
+	n=n2/2;
+
+	/* Calculate (al-ah)*(bh-bl) */
+	neg=zero=0;
+	c1=bn_cmp_words(&(a[0]),&(a[n]),n);
+	c2=bn_cmp_words(&(b[n]),&(b[0]),n);
+	switch (c1*3+c2)
+		{
+	case -4:
+		bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
+		bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
+		break;
+	case -3:
+		zero=1;
+		break;
+	case -2:
+		bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
+		bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
+		neg=1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		zero=1;
+		break;
+	case 2:
+		bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
+		bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
+		neg=1;
+		break;
+	case 3:
+		zero=1;
+		break;
+	case 4:
+		bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
+		bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
+		break;
+		}
+		
+	oneg=neg;
+	/* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
+	/* r[10] = (a[1]*b[1]) */
+# ifdef BN_MUL_COMBA
+	if (n == 8)
+		{
+		bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
+		bn_mul_comba8(r,&(a[n]),&(b[n]));
+		}
+	else
+# endif
+		{
+		bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2]));
+		bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2]));
+		}
+
+	/* s0 == low(al*bl)
+	 * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
+	 * We know s0 and s1 so the only unknown is high(al*bl)
+	 * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
+	 * high(al*bl) == s1 - (r[0]+l[0]+t[0])
+	 */
+	if (l != NULL)
+		{
+		lp= &(t[n2+n]);
+		c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n));
+		}
+	else
+		{
+		c1=0;
+		lp= &(r[0]);
+		}
+
+	if (neg)
+		neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n));
+	else
+		{
+		bn_add_words(&(t[n2]),lp,&(t[0]),n);
+		neg=0;
+		}
+
+	if (l != NULL)
+		{
+		bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
+		}
+	else
+		{
+		lp= &(t[n2+n]);
+		mp= &(t[n2]);
+		for (i=0; i<n; i++)
+			lp[i]=((~mp[i])+1)&BN_MASK2;
+		}
+
+	/* s[0] = low(al*bl)
+	 * t[3] = high(al*bl)
+	 * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
+	 * r[10] = (a[1]*b[1])
+	 */
+	/* R[10] = al*bl
+	 * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
+	 * R[32] = ah*bh
+	 */
+	/* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
+	 * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
+	 * R[3]=r[1]+(carry/borrow)
+	 */
+	if (l != NULL)
+		{
+		lp= &(t[n2]);
+		c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n));
+		}
+	else
+		{
+		lp= &(t[n2+n]);
+		c1=0;
+		}
+	c1+=(int)(bn_add_words(&(t[n2]),lp,  &(r[0]),n));
+	if (oneg)
+		c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n));
+	else
+		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n));
+
+	c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n));
+	c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n));
+	if (oneg)
+		c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n));
+	else
+		c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n));
+	
+	if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
+		{
+		i=0;
+		if (c1 > 0)
+			{
+			lc=c1;
+			do	{
+				ll=(r[i]+lc)&BN_MASK2;
+				r[i++]=ll;
+				lc=(lc > ll);
+				} while (lc);
+			}
+		else
+			{
+			lc= -c1;
+			do	{
+				ll=r[i];
+				r[i++]=(ll-lc)&BN_MASK2;
+				lc=(lc > ll);
+				} while (lc);
+			}
+		}
+	if (c2 != 0) /* Add starting at r[1] */
+		{
+		i=n;
+		if (c2 > 0)
+			{
+			lc=c2;
+			do	{
+				ll=(r[i]+lc)&BN_MASK2;
+				r[i++]=ll;
+				lc=(lc > ll);
+				} while (lc);
+			}
+		else
+			{
+			lc= -c2;
+			do	{
+				ll=r[i];
+				r[i++]=(ll-lc)&BN_MASK2;
+				lc=(lc > ll);
+				} while (lc);
+			}
+		}
+	}
+#endif /* BN_RECURSION */
+
+int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+	{
+	int top,al,bl;
+	BIGNUM *rr;
+	int ret = 0;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+	int i;
+#endif
+#ifdef BN_RECURSION
+	BIGNUM *t;
+	int j,k;
+#endif
+
+#ifdef BN_COUNT
+	printf("BN_mul %d * %d\n",a->top,b->top);
+#endif
+
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(r);
+
+	al=a->top;
+	bl=b->top;
+	r->neg=a->neg^b->neg;
+
+	if ((al == 0) || (bl == 0))
+		{
+		BN_zero(r);
+		return(1);
+		}
+	top=al+bl;
+
+	BN_CTX_start(ctx);
+	if ((r == a) || (r == b))
+		{
+		if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
+		}
+	else
+		rr = r;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+	i = al-bl;
+#endif
+#ifdef BN_MUL_COMBA
+	if (i == 0)
+		{
+# if 0
+		if (al == 4)
+			{
+			if (bn_wexpand(rr,8) == NULL) goto err;
+			rr->top=8;
+			bn_mul_comba4(rr->d,a->d,b->d);
+			goto end;
+			}
+# endif
+		if (al == 8)
+			{
+			if (bn_wexpand(rr,16) == NULL) goto err;
+			rr->top=16;
+			bn_mul_comba8(rr->d,a->d,b->d);
+			goto end;
+			}
+		}
+#endif /* BN_MUL_COMBA */
+#ifdef BN_RECURSION
+	if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
+		{
+		if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
+			{
+			bn_wexpand(b,al);
+			b->d[bl]=0;
+			bl++;
+			i--;
+			}
+		else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
+			{
+			bn_wexpand(a,bl);
+			a->d[al]=0;
+			al++;
+			i++;
+			}
+		if (i == 0)
+			{
+			/* symmetric and > 4 */
+			/* 16 or larger */
+			j=BN_num_bits_word((BN_ULONG)al);
+			j=1<<(j-1);
+			k=j+j;
+			t = BN_CTX_get(ctx);
+			if (al == j) /* exact multiple */
+				{
+				bn_wexpand(t,k*2);
+				bn_wexpand(rr,k*2);
+				bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
+				}
+			else
+				{
+				bn_wexpand(a,k);
+				bn_wexpand(b,k);
+				bn_wexpand(t,k*4);
+				bn_wexpand(rr,k*4);
+				for (i=a->top; i<k; i++)
+					a->d[i]=0;
+				for (i=b->top; i<k; i++)
+					b->d[i]=0;
+				bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
+				}
+			rr->top=top;
+			goto end;
+			}
+		}
+#endif /* BN_RECURSION */
+	if (bn_wexpand(rr,top) == NULL) goto err;
+	rr->top=top;
+	bn_mul_normal(rr->d,a->d,al,b->d,bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+end:
+#endif
+	bn_fix_top(rr);
+	if (r != rr) BN_copy(r,rr);
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+	{
+	BN_ULONG *rr;
+
+#ifdef BN_COUNT
+	printf(" bn_mul_normal %d * %d\n",na,nb);
+#endif
+
+	if (na < nb)
+		{
+		int itmp;
+		BN_ULONG *ltmp;
+
+		itmp=na; na=nb; nb=itmp;
+		ltmp=a;   a=b;   b=ltmp;
+
+		}
+	rr= &(r[na]);
+	rr[0]=bn_mul_words(r,a,na,b[0]);
+
+	for (;;)
+		{
+		if (--nb <= 0) return;
+		rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
+		if (--nb <= 0) return;
+		rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
+		if (--nb <= 0) return;
+		rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
+		if (--nb <= 0) return;
+		rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
+		rr+=4;
+		r+=4;
+		b+=4;
+		}
+	}
+
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+	{
+#ifdef BN_COUNT
+	printf(" bn_mul_low_normal %d * %d\n",n,n);
+#endif
+	bn_mul_words(r,a,n,b[0]);
+
+	for (;;)
+		{
+		if (--n <= 0) return;
+		bn_mul_add_words(&(r[1]),a,n,b[1]);
+		if (--n <= 0) return;
+		bn_mul_add_words(&(r[2]),a,n,b[2]);
+		if (--n <= 0) return;
+		bn_mul_add_words(&(r[3]),a,n,b[3]);
+		if (--n <= 0) return;
+		bn_mul_add_words(&(r[4]),a,n,b[4]);
+		r+=4;
+		b+=4;
+		}
+	}
diff --git a/AppleCSP/open_ssl/bn/bn_prime.c b/AppleCSP/open_ssl/bn/bn_prime.c
new file mode 100644
index 00000000..a1dad1ec
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_prime.c
@@ -0,0 +1,483 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_prime.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+/* The quick sieve algorithm approach to weeding out primes is
+ * Philip Zimmermann's, as implemented in PGP.  I have had a read of
+ * his comments and implemented my own version.
+ */
+#include "bn_prime.h"
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+	const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
+static int probable_prime(BIGNUM *rnd, int bits);
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+	BIGNUM *add, BIGNUM *rem, BN_CTX *ctx);
+static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
+	BIGNUM *add, BIGNUM *rem, BN_CTX *ctx);
+
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BIGNUM *add,
+	     BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg)
+	{
+	BIGNUM *rnd=NULL;
+	BIGNUM t;
+	int found=0;
+	int i,j,c1=0;
+	BN_CTX *ctx;
+	int checks = BN_prime_checks_for_size(bits);
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+	if (ret == NULL)
+		{
+		if ((rnd=BN_new()) == NULL) goto err;
+		}
+	else
+		rnd=ret;
+	BN_init(&t);
+loop: 
+	/* make a random number and set the top and bottom bits */
+	if (add == NULL)
+		{
+		if (!probable_prime(rnd,bits)) goto err;
+		}
+	else
+		{
+		if (safe)
+			{
+			if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx))
+				 goto err;
+			}
+		else
+			{
+			if (!probable_prime_dh(rnd,bits,add,rem,ctx))
+				goto err;
+			}
+		}
+	/* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */
+	if (callback != NULL) callback(0,c1++,cb_arg);
+
+	if (!safe)
+		{
+		i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0);
+		if (i == -1) goto err;
+		if (i == 0) goto loop;
+		}
+	else
+		{
+		/* for "safe prime" generation,
+		 * check that (p-1)/2 is prime.
+		 * Since a prime is odd, We just
+		 * need to divide by 2 */
+		if (!BN_rshift1(&t,rnd)) goto err;
+
+		for (i=0; i<checks; i++)
+			{
+			j=BN_is_prime_fasttest(rnd,1,callback,ctx,cb_arg,0);
+			if (j == -1) goto err;
+			if (j == 0) goto loop;
+
+			j=BN_is_prime_fasttest(&t,1,callback,ctx,cb_arg,0);
+			if (j == -1) goto err;
+			if (j == 0) goto loop;
+
+			if (callback != NULL) callback(2,c1-1,cb_arg);
+			/* We have a safe prime test pass */
+			}
+		}
+	/* we have a prime :-) */
+	found = 1;
+err:
+	if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd);
+	BN_free(&t);
+	if (ctx != NULL) BN_CTX_free(ctx);
+	return(found ? rnd : NULL);
+	}
+
+int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *),
+	BN_CTX *ctx_passed, void *cb_arg)
+	{
+	return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0);
+	}
+
+int BN_is_prime_fasttest(const BIGNUM *a, int checks,
+		void (*callback)(int,int,void *),
+		BN_CTX *ctx_passed, void *cb_arg,
+		int do_trial_division)
+	{
+	int i, j, ret = -1;
+	int k;
+	BN_CTX *ctx = NULL;
+	BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
+	BN_MONT_CTX *mont = NULL;
+	const BIGNUM *A = NULL;
+
+	if (checks == BN_prime_checks)
+		checks = BN_prime_checks_for_size(BN_num_bits(a));
+
+	/* first look for small factors */
+	if (!BN_is_odd(a))
+		return(0);
+	if (do_trial_division)
+		{
+		for (i = 1; i < NUMPRIMES; i++)
+			if (BN_mod_word(a, primes[i]) == 0) 
+				return 0;
+		if (callback != NULL) callback(1, -1, cb_arg);
+		}
+
+	if (ctx_passed != NULL)
+		ctx = ctx_passed;
+	else
+		if ((ctx=BN_CTX_new()) == NULL)
+			goto err;
+	BN_CTX_start(ctx);
+
+	/* A := abs(a) */
+	if (a->neg)
+		{
+		BIGNUM *t;
+		if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+		BN_copy(t, a);
+		t->neg = 0;
+		A = t;
+		}
+	else
+		A = a;
+	A1 = BN_CTX_get(ctx);
+	A1_odd = BN_CTX_get(ctx);
+	check = BN_CTX_get(ctx);
+	if (check == NULL) goto err;
+
+	/* compute A1 := A - 1 */
+	if (!BN_copy(A1, A))
+		goto err;
+	if (!BN_sub_word(A1, 1))
+		goto err;
+	if (BN_is_zero(A1))
+		{
+		ret = 0;
+		goto err;
+		}
+
+	/* write  A1  as  A1_odd * 2^k */
+	k = 1;
+	while (!BN_is_bit_set(A1, k))
+		k++;
+	if (!BN_rshift(A1_odd, A1, k))
+		goto err;
+
+	/* Montgomery setup for computations mod A */
+	mont = BN_MONT_CTX_new();
+	if (mont == NULL)
+		goto err;
+	if (!BN_MONT_CTX_set(mont, A, ctx))
+		goto err;
+	
+	for (i = 0; i < checks; i++)
+		{
+		if (!BN_pseudo_rand(check, BN_num_bits(A1), 0, 0))
+			goto err;
+		if (BN_cmp(check, A1) >= 0)
+			if (!BN_sub(check, check, A1))
+				goto err;
+		if (!BN_add_word(check, 1))
+			goto err;
+		/* now 1 <= check < A */
+
+		j = witness(check, A, A1, A1_odd, k, ctx, mont);
+		if (j == -1) goto err;
+		if (j)
+			{
+			ret=0;
+			goto err;
+			}
+		if (callback != NULL) callback(1,i,cb_arg);
+		}
+	ret=1;
+err:
+	if (ctx != NULL)
+		{
+		BN_CTX_end(ctx);
+		if (ctx_passed == NULL)
+			BN_CTX_free(ctx);
+		}
+	if (mont != NULL)
+		BN_MONT_CTX_free(mont);
+
+	return(ret);
+	}
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+	const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont)
+	{
+	if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
+		return -1;
+	if (BN_is_one(w))
+		return 0; /* probably prime */
+	if (BN_cmp(w, a1) == 0)
+		return 0; /* w == -1 (mod a),  'a' is probably prime */
+	while (--k)
+		{
+		if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
+			return -1;
+		if (BN_is_one(w))
+			return 1; /* 'a' is composite, otherwise a previous 'w' would
+			           * have been == -1 (mod 'a') */
+		if (BN_cmp(w, a1) == 0)
+			return 0; /* w == -1 (mod a), 'a' is probably prime */
+		}
+	/* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
+	 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
+	return 1;
+	}
+
+static int probable_prime(BIGNUM *rnd, int bits)
+	{
+	int i;
+	BN_ULONG mods[NUMPRIMES];
+	BN_ULONG delta,d;
+
+again:
+	if (!BN_rand(rnd,bits,1,1)) return(0);
+	/* we now have a random number 'rand' to test. */
+	for (i=1; i<NUMPRIMES; i++)
+		mods[i]=BN_mod_word(rnd,(BN_ULONG)primes[i]);
+	delta=0;
+	loop: for (i=1; i<NUMPRIMES; i++)
+		{
+		/* check that rnd is not a prime and also
+		 * that gcd(rnd-1,primes) == 1 (except for 2) */
+		if (((mods[i]+delta)%primes[i]) <= 1)
+			{
+			d=delta;
+			delta+=2;
+			/* perhaps need to check for overflow of
+			 * delta (but delta can be up to 2^32)
+			 * 21-May-98 eay - added overflow check */
+			if (delta < d) goto again;
+			goto loop;
+			}
+		}
+	if (!BN_add_word(rnd,delta)) return(0);
+	return(1);
+	}
+
+static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
+	     BN_CTX *ctx)
+	{
+	int i,ret=0;
+	BIGNUM *t1;
+
+	BN_CTX_start(ctx);
+	if ((t1 = BN_CTX_get(ctx)) == NULL) goto err;
+
+	if (!BN_rand(rnd,bits,0,1)) goto err;
+
+	/* we need ((rnd-rem) % add) == 0 */
+
+	if (!BN_mod(t1,rnd,add,ctx)) goto err;
+	if (!BN_sub(rnd,rnd,t1)) goto err;
+	if (rem == NULL)
+		{ if (!BN_add_word(rnd,1)) goto err; }
+	else
+		{ if (!BN_add(rnd,rnd,rem)) goto err; }
+
+	/* we now have a random number 'rand' to test. */
+
+	loop: for (i=1; i<NUMPRIMES; i++)
+		{
+		/* check that rnd is a prime */
+		if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1)
+			{
+			if (!BN_add(rnd,rnd,add)) goto err;
+			goto loop;
+			}
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd,
+	     BIGNUM *rem, BN_CTX *ctx)
+	{
+	int i,ret=0;
+	BIGNUM *t1,*qadd,*q;
+
+	bits--;
+	BN_CTX_start(ctx);
+	t1 = BN_CTX_get(ctx);
+	q = BN_CTX_get(ctx);
+	qadd = BN_CTX_get(ctx);
+	if (qadd == NULL) goto err;
+
+	if (!BN_rshift1(qadd,padd)) goto err;
+		
+	if (!BN_rand(q,bits,0,1)) goto err;
+
+	/* we need ((rnd-rem) % add) == 0 */
+	if (!BN_mod(t1,q,qadd,ctx)) goto err;
+	if (!BN_sub(q,q,t1)) goto err;
+	if (rem == NULL)
+		{ if (!BN_add_word(q,1)) goto err; }
+	else
+		{
+		if (!BN_rshift1(t1,rem)) goto err;
+		if (!BN_add(q,q,t1)) goto err;
+		}
+
+	/* we now have a random number 'rand' to test. */
+	if (!BN_lshift1(p,q)) goto err;
+	if (!BN_add_word(p,1)) goto err;
+
+	loop: for (i=1; i<NUMPRIMES; i++)
+		{
+		/* check that p and q are prime */
+		/* check that for p and q
+		 * gcd(p-1,primes) == 1 (except for 2) */
+		if (	(BN_mod_word(p,(BN_ULONG)primes[i]) == 0) ||
+			(BN_mod_word(q,(BN_ULONG)primes[i]) == 0))
+			{
+			if (!BN_add(p,p,padd)) goto err;
+			if (!BN_add(q,q,qadd)) goto err;
+			goto loop;
+			}
+		}
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
diff --git a/AppleCSP/open_ssl/bn/bn_prime.h b/AppleCSP/open_ssl/bn/bn_prime.h
new file mode 100644
index 00000000..64907456
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_prime.h
@@ -0,0 +1,343 @@
+/*
+ * 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.
+ */
+
+
+/* Auto generated by bn_prime.pl */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef EIGHT_BIT
+#define NUMPRIMES 2048
+#else
+#define NUMPRIMES 54
+#endif
+static const unsigned int primes[NUMPRIMES]=
+	{
+	   2,   3,   5,   7,  11,  13,  17,  19,
+	  23,  29,  31,  37,  41,  43,  47,  53,
+	  59,  61,  67,  71,  73,  79,  83,  89,
+	  97, 101, 103, 107, 109, 113, 127, 131,
+	 137, 139, 149, 151, 157, 163, 167, 173,
+	 179, 181, 191, 193, 197, 199, 211, 223,
+	 227, 229, 233, 239, 241, 251,
+#ifndef EIGHT_BIT
+	 257, 263,
+	 269, 271, 277, 281, 283, 293, 307, 311,
+	 313, 317, 331, 337, 347, 349, 353, 359,
+	 367, 373, 379, 383, 389, 397, 401, 409,
+	 419, 421, 431, 433, 439, 443, 449, 457,
+	 461, 463, 467, 479, 487, 491, 499, 503,
+	 509, 521, 523, 541, 547, 557, 563, 569,
+	 571, 577, 587, 593, 599, 601, 607, 613,
+	 617, 619, 631, 641, 643, 647, 653, 659,
+	 661, 673, 677, 683, 691, 701, 709, 719,
+	 727, 733, 739, 743, 751, 757, 761, 769,
+	 773, 787, 797, 809, 811, 821, 823, 827,
+	 829, 839, 853, 857, 859, 863, 877, 881,
+	 883, 887, 907, 911, 919, 929, 937, 941,
+	 947, 953, 967, 971, 977, 983, 991, 997,
+	1009,1013,1019,1021,1031,1033,1039,1049,
+	1051,1061,1063,1069,1087,1091,1093,1097,
+	1103,1109,1117,1123,1129,1151,1153,1163,
+	1171,1181,1187,1193,1201,1213,1217,1223,
+	1229,1231,1237,1249,1259,1277,1279,1283,
+	1289,1291,1297,1301,1303,1307,1319,1321,
+	1327,1361,1367,1373,1381,1399,1409,1423,
+	1427,1429,1433,1439,1447,1451,1453,1459,
+	1471,1481,1483,1487,1489,1493,1499,1511,
+	1523,1531,1543,1549,1553,1559,1567,1571,
+	1579,1583,1597,1601,1607,1609,1613,1619,
+	1621,1627,1637,1657,1663,1667,1669,1693,
+	1697,1699,1709,1721,1723,1733,1741,1747,
+	1753,1759,1777,1783,1787,1789,1801,1811,
+	1823,1831,1847,1861,1867,1871,1873,1877,
+	1879,1889,1901,1907,1913,1931,1933,1949,
+	1951,1973,1979,1987,1993,1997,1999,2003,
+	2011,2017,2027,2029,2039,2053,2063,2069,
+	2081,2083,2087,2089,2099,2111,2113,2129,
+	2131,2137,2141,2143,2153,2161,2179,2203,
+	2207,2213,2221,2237,2239,2243,2251,2267,
+	2269,2273,2281,2287,2293,2297,2309,2311,
+	2333,2339,2341,2347,2351,2357,2371,2377,
+	2381,2383,2389,2393,2399,2411,2417,2423,
+	2437,2441,2447,2459,2467,2473,2477,2503,
+	2521,2531,2539,2543,2549,2551,2557,2579,
+	2591,2593,2609,2617,2621,2633,2647,2657,
+	2659,2663,2671,2677,2683,2687,2689,2693,
+	2699,2707,2711,2713,2719,2729,2731,2741,
+	2749,2753,2767,2777,2789,2791,2797,2801,
+	2803,2819,2833,2837,2843,2851,2857,2861,
+	2879,2887,2897,2903,2909,2917,2927,2939,
+	2953,2957,2963,2969,2971,2999,3001,3011,
+	3019,3023,3037,3041,3049,3061,3067,3079,
+	3083,3089,3109,3119,3121,3137,3163,3167,
+	3169,3181,3187,3191,3203,3209,3217,3221,
+	3229,3251,3253,3257,3259,3271,3299,3301,
+	3307,3313,3319,3323,3329,3331,3343,3347,
+	3359,3361,3371,3373,3389,3391,3407,3413,
+	3433,3449,3457,3461,3463,3467,3469,3491,
+	3499,3511,3517,3527,3529,3533,3539,3541,
+	3547,3557,3559,3571,3581,3583,3593,3607,
+	3613,3617,3623,3631,3637,3643,3659,3671,
+	3673,3677,3691,3697,3701,3709,3719,3727,
+	3733,3739,3761,3767,3769,3779,3793,3797,
+	3803,3821,3823,3833,3847,3851,3853,3863,
+	3877,3881,3889,3907,3911,3917,3919,3923,
+	3929,3931,3943,3947,3967,3989,4001,4003,
+	4007,4013,4019,4021,4027,4049,4051,4057,
+	4073,4079,4091,4093,4099,4111,4127,4129,
+	4133,4139,4153,4157,4159,4177,4201,4211,
+	4217,4219,4229,4231,4241,4243,4253,4259,
+	4261,4271,4273,4283,4289,4297,4327,4337,
+	4339,4349,4357,4363,4373,4391,4397,4409,
+	4421,4423,4441,4447,4451,4457,4463,4481,
+	4483,4493,4507,4513,4517,4519,4523,4547,
+	4549,4561,4567,4583,4591,4597,4603,4621,
+	4637,4639,4643,4649,4651,4657,4663,4673,
+	4679,4691,4703,4721,4723,4729,4733,4751,
+	4759,4783,4787,4789,4793,4799,4801,4813,
+	4817,4831,4861,4871,4877,4889,4903,4909,
+	4919,4931,4933,4937,4943,4951,4957,4967,
+	4969,4973,4987,4993,4999,5003,5009,5011,
+	5021,5023,5039,5051,5059,5077,5081,5087,
+	5099,5101,5107,5113,5119,5147,5153,5167,
+	5171,5179,5189,5197,5209,5227,5231,5233,
+	5237,5261,5273,5279,5281,5297,5303,5309,
+	5323,5333,5347,5351,5381,5387,5393,5399,
+	5407,5413,5417,5419,5431,5437,5441,5443,
+	5449,5471,5477,5479,5483,5501,5503,5507,
+	5519,5521,5527,5531,5557,5563,5569,5573,
+	5581,5591,5623,5639,5641,5647,5651,5653,
+	5657,5659,5669,5683,5689,5693,5701,5711,
+	5717,5737,5741,5743,5749,5779,5783,5791,
+	5801,5807,5813,5821,5827,5839,5843,5849,
+	5851,5857,5861,5867,5869,5879,5881,5897,
+	5903,5923,5927,5939,5953,5981,5987,6007,
+	6011,6029,6037,6043,6047,6053,6067,6073,
+	6079,6089,6091,6101,6113,6121,6131,6133,
+	6143,6151,6163,6173,6197,6199,6203,6211,
+	6217,6221,6229,6247,6257,6263,6269,6271,
+	6277,6287,6299,6301,6311,6317,6323,6329,
+	6337,6343,6353,6359,6361,6367,6373,6379,
+	6389,6397,6421,6427,6449,6451,6469,6473,
+	6481,6491,6521,6529,6547,6551,6553,6563,
+	6569,6571,6577,6581,6599,6607,6619,6637,
+	6653,6659,6661,6673,6679,6689,6691,6701,
+	6703,6709,6719,6733,6737,6761,6763,6779,
+	6781,6791,6793,6803,6823,6827,6829,6833,
+	6841,6857,6863,6869,6871,6883,6899,6907,
+	6911,6917,6947,6949,6959,6961,6967,6971,
+	6977,6983,6991,6997,7001,7013,7019,7027,
+	7039,7043,7057,7069,7079,7103,7109,7121,
+	7127,7129,7151,7159,7177,7187,7193,7207,
+	7211,7213,7219,7229,7237,7243,7247,7253,
+	7283,7297,7307,7309,7321,7331,7333,7349,
+	7351,7369,7393,7411,7417,7433,7451,7457,
+	7459,7477,7481,7487,7489,7499,7507,7517,
+	7523,7529,7537,7541,7547,7549,7559,7561,
+	7573,7577,7583,7589,7591,7603,7607,7621,
+	7639,7643,7649,7669,7673,7681,7687,7691,
+	7699,7703,7717,7723,7727,7741,7753,7757,
+	7759,7789,7793,7817,7823,7829,7841,7853,
+	7867,7873,7877,7879,7883,7901,7907,7919,
+	7927,7933,7937,7949,7951,7963,7993,8009,
+	8011,8017,8039,8053,8059,8069,8081,8087,
+	8089,8093,8101,8111,8117,8123,8147,8161,
+	8167,8171,8179,8191,8209,8219,8221,8231,
+	8233,8237,8243,8263,8269,8273,8287,8291,
+	8293,8297,8311,8317,8329,8353,8363,8369,
+	8377,8387,8389,8419,8423,8429,8431,8443,
+	8447,8461,8467,8501,8513,8521,8527,8537,
+	8539,8543,8563,8573,8581,8597,8599,8609,
+	8623,8627,8629,8641,8647,8663,8669,8677,
+	8681,8689,8693,8699,8707,8713,8719,8731,
+	8737,8741,8747,8753,8761,8779,8783,8803,
+	8807,8819,8821,8831,8837,8839,8849,8861,
+	8863,8867,8887,8893,8923,8929,8933,8941,
+	8951,8963,8969,8971,8999,9001,9007,9011,
+	9013,9029,9041,9043,9049,9059,9067,9091,
+	9103,9109,9127,9133,9137,9151,9157,9161,
+	9173,9181,9187,9199,9203,9209,9221,9227,
+	9239,9241,9257,9277,9281,9283,9293,9311,
+	9319,9323,9337,9341,9343,9349,9371,9377,
+	9391,9397,9403,9413,9419,9421,9431,9433,
+	9437,9439,9461,9463,9467,9473,9479,9491,
+	9497,9511,9521,9533,9539,9547,9551,9587,
+	9601,9613,9619,9623,9629,9631,9643,9649,
+	9661,9677,9679,9689,9697,9719,9721,9733,
+	9739,9743,9749,9767,9769,9781,9787,9791,
+	9803,9811,9817,9829,9833,9839,9851,9857,
+	9859,9871,9883,9887,9901,9907,9923,9929,
+	9931,9941,9949,9967,9973,10007,10009,10037,
+	10039,10061,10067,10069,10079,10091,10093,10099,
+	10103,10111,10133,10139,10141,10151,10159,10163,
+	10169,10177,10181,10193,10211,10223,10243,10247,
+	10253,10259,10267,10271,10273,10289,10301,10303,
+	10313,10321,10331,10333,10337,10343,10357,10369,
+	10391,10399,10427,10429,10433,10453,10457,10459,
+	10463,10477,10487,10499,10501,10513,10529,10531,
+	10559,10567,10589,10597,10601,10607,10613,10627,
+	10631,10639,10651,10657,10663,10667,10687,10691,
+	10709,10711,10723,10729,10733,10739,10753,10771,
+	10781,10789,10799,10831,10837,10847,10853,10859,
+	10861,10867,10883,10889,10891,10903,10909,10937,
+	10939,10949,10957,10973,10979,10987,10993,11003,
+	11027,11047,11057,11059,11069,11071,11083,11087,
+	11093,11113,11117,11119,11131,11149,11159,11161,
+	11171,11173,11177,11197,11213,11239,11243,11251,
+	11257,11261,11273,11279,11287,11299,11311,11317,
+	11321,11329,11351,11353,11369,11383,11393,11399,
+	11411,11423,11437,11443,11447,11467,11471,11483,
+	11489,11491,11497,11503,11519,11527,11549,11551,
+	11579,11587,11593,11597,11617,11621,11633,11657,
+	11677,11681,11689,11699,11701,11717,11719,11731,
+	11743,11777,11779,11783,11789,11801,11807,11813,
+	11821,11827,11831,11833,11839,11863,11867,11887,
+	11897,11903,11909,11923,11927,11933,11939,11941,
+	11953,11959,11969,11971,11981,11987,12007,12011,
+	12037,12041,12043,12049,12071,12073,12097,12101,
+	12107,12109,12113,12119,12143,12149,12157,12161,
+	12163,12197,12203,12211,12227,12239,12241,12251,
+	12253,12263,12269,12277,12281,12289,12301,12323,
+	12329,12343,12347,12373,12377,12379,12391,12401,
+	12409,12413,12421,12433,12437,12451,12457,12473,
+	12479,12487,12491,12497,12503,12511,12517,12527,
+	12539,12541,12547,12553,12569,12577,12583,12589,
+	12601,12611,12613,12619,12637,12641,12647,12653,
+	12659,12671,12689,12697,12703,12713,12721,12739,
+	12743,12757,12763,12781,12791,12799,12809,12821,
+	12823,12829,12841,12853,12889,12893,12899,12907,
+	12911,12917,12919,12923,12941,12953,12959,12967,
+	12973,12979,12983,13001,13003,13007,13009,13033,
+	13037,13043,13049,13063,13093,13099,13103,13109,
+	13121,13127,13147,13151,13159,13163,13171,13177,
+	13183,13187,13217,13219,13229,13241,13249,13259,
+	13267,13291,13297,13309,13313,13327,13331,13337,
+	13339,13367,13381,13397,13399,13411,13417,13421,
+	13441,13451,13457,13463,13469,13477,13487,13499,
+	13513,13523,13537,13553,13567,13577,13591,13597,
+	13613,13619,13627,13633,13649,13669,13679,13681,
+	13687,13691,13693,13697,13709,13711,13721,13723,
+	13729,13751,13757,13759,13763,13781,13789,13799,
+	13807,13829,13831,13841,13859,13873,13877,13879,
+	13883,13901,13903,13907,13913,13921,13931,13933,
+	13963,13967,13997,13999,14009,14011,14029,14033,
+	14051,14057,14071,14081,14083,14087,14107,14143,
+	14149,14153,14159,14173,14177,14197,14207,14221,
+	14243,14249,14251,14281,14293,14303,14321,14323,
+	14327,14341,14347,14369,14387,14389,14401,14407,
+	14411,14419,14423,14431,14437,14447,14449,14461,
+	14479,14489,14503,14519,14533,14537,14543,14549,
+	14551,14557,14561,14563,14591,14593,14621,14627,
+	14629,14633,14639,14653,14657,14669,14683,14699,
+	14713,14717,14723,14731,14737,14741,14747,14753,
+	14759,14767,14771,14779,14783,14797,14813,14821,
+	14827,14831,14843,14851,14867,14869,14879,14887,
+	14891,14897,14923,14929,14939,14947,14951,14957,
+	14969,14983,15013,15017,15031,15053,15061,15073,
+	15077,15083,15091,15101,15107,15121,15131,15137,
+	15139,15149,15161,15173,15187,15193,15199,15217,
+	15227,15233,15241,15259,15263,15269,15271,15277,
+	15287,15289,15299,15307,15313,15319,15329,15331,
+	15349,15359,15361,15373,15377,15383,15391,15401,
+	15413,15427,15439,15443,15451,15461,15467,15473,
+	15493,15497,15511,15527,15541,15551,15559,15569,
+	15581,15583,15601,15607,15619,15629,15641,15643,
+	15647,15649,15661,15667,15671,15679,15683,15727,
+	15731,15733,15737,15739,15749,15761,15767,15773,
+	15787,15791,15797,15803,15809,15817,15823,15859,
+	15877,15881,15887,15889,15901,15907,15913,15919,
+	15923,15937,15959,15971,15973,15991,16001,16007,
+	16033,16057,16061,16063,16067,16069,16073,16087,
+	16091,16097,16103,16111,16127,16139,16141,16183,
+	16187,16189,16193,16217,16223,16229,16231,16249,
+	16253,16267,16273,16301,16319,16333,16339,16349,
+	16361,16363,16369,16381,16411,16417,16421,16427,
+	16433,16447,16451,16453,16477,16481,16487,16493,
+	16519,16529,16547,16553,16561,16567,16573,16603,
+	16607,16619,16631,16633,16649,16651,16657,16661,
+	16673,16691,16693,16699,16703,16729,16741,16747,
+	16759,16763,16787,16811,16823,16829,16831,16843,
+	16871,16879,16883,16889,16901,16903,16921,16927,
+	16931,16937,16943,16963,16979,16981,16987,16993,
+	17011,17021,17027,17029,17033,17041,17047,17053,
+	17077,17093,17099,17107,17117,17123,17137,17159,
+	17167,17183,17189,17191,17203,17207,17209,17231,
+	17239,17257,17291,17293,17299,17317,17321,17327,
+	17333,17341,17351,17359,17377,17383,17387,17389,
+	17393,17401,17417,17419,17431,17443,17449,17467,
+	17471,17477,17483,17489,17491,17497,17509,17519,
+	17539,17551,17569,17573,17579,17581,17597,17599,
+	17609,17623,17627,17657,17659,17669,17681,17683,
+	17707,17713,17729,17737,17747,17749,17761,17783,
+	17789,17791,17807,17827,17837,17839,17851,17863,
+#endif
+	};
diff --git a/AppleCSP/open_ssl/bn/bn_print.c b/AppleCSP/open_ssl/bn/bn_print.c
new file mode 100644
index 00000000..4faf351b
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_print.c
@@ -0,0 +1,350 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_print.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include "bn_lcl.h"
+
+static const char *Hex="0123456789ABCDEF";
+
+/* Must 'Free' the returned data */
+char *BN_bn2hex(const BIGNUM *a)
+	{
+	int i,j,v,z=0;
+	char *buf;
+	char *p;
+
+	buf=(char *)Malloc(a->top*BN_BYTES*2+2);
+	if (buf == NULL)
+		{
+		BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	p=buf;
+	if (a->neg) *(p++)='-';
+	if (a->top == 0) *(p++)='0';
+	for (i=a->top-1; i >=0; i--)
+		{
+		for (j=BN_BITS2-8; j >= 0; j-=8)
+			{
+			/* strip leading zeros */
+			v=((int)(a->d[i]>>(long)j))&0xff;
+			if (z || (v != 0))
+				{
+				*(p++)=Hex[v>>4];
+				*(p++)=Hex[v&0x0f];
+				z=1;
+				}
+			}
+		}
+	*p='\0';
+err:
+	return(buf);
+	}
+
+/* Must 'Free' the returned data */
+char *BN_bn2dec(const BIGNUM *a)
+	{
+	int i=0,num;
+	char *buf=NULL;
+	char *p;
+	BIGNUM *t=NULL;
+	BN_ULONG *bn_data=NULL,*lp;
+
+	i=BN_num_bits(a)*3;
+	num=(i/10+i/1000+3)+1;
+	bn_data=(BN_ULONG *)Malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG));
+	buf=(char *)Malloc(num+3);
+	if ((buf == NULL) || (bn_data == NULL))
+		{
+		BNerr(BN_F_BN_BN2DEC,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if ((t=BN_dup(a)) == NULL) goto err;
+
+	p=buf;
+	lp=bn_data;
+	if (t->neg) *(p++)='-';
+	if (t->top == 0)
+		{
+		*(p++)='0';
+		*(p++)='\0';
+		}
+	else
+		{
+		i=0;
+		while (!BN_is_zero(t))
+			{
+			*lp=BN_div_word(t,BN_DEC_CONV);
+			lp++;
+			}
+		lp--;
+		/* We now have a series of blocks, BN_DEC_NUM chars
+		 * in length, where the last one needs truncation.
+		 * The blocks need to be reversed in order. */
+		sprintf(p,BN_DEC_FMT1,*lp);
+		while (*p) p++;
+		while (lp != bn_data)
+			{
+			lp--;
+			sprintf(p,BN_DEC_FMT2,*lp);
+			while (*p) p++;
+			}
+		}
+err:
+	if (bn_data != NULL) Free(bn_data);
+	if (t != NULL) BN_free(t);
+	return(buf);
+	}
+
+int BN_hex2bn(BIGNUM **bn, const char *a)
+	{
+	BIGNUM *ret=NULL;
+	BN_ULONG l=0;
+	int neg=0,h,m,i,j,k,c;
+	int num;
+
+	if ((a == NULL) || (*a == '\0')) return(0);
+
+	if (*a == '-') { neg=1; a++; }
+
+	for (i=0; isxdigit((unsigned char) a[i]); i++)
+		;
+
+	num=i+neg;
+	if (bn == NULL) return(num);
+
+	/* a is the start of the hex digits, and it is 'i' long */
+	if (*bn == NULL)
+		{
+		if ((ret=BN_new()) == NULL) return(0);
+		}
+	else
+		{
+		ret= *bn;
+		BN_zero(ret);
+		}
+
+	/* i is the number of hex digests; */
+	if (bn_expand(ret,i*4) == NULL) goto err;
+
+	j=i; /* least significant 'hex' */
+	m=0;
+	h=0;
+	while (j > 0)
+		{
+		m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j;
+		l=0;
+		for (;;)
+			{
+			c=a[j-m];
+			if ((c >= '0') && (c <= '9')) k=c-'0';
+			else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10;
+			else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10;
+			else k=0; /* paranoia */
+			l=(l<<4)|k;
+
+			if (--m <= 0)
+				{
+				ret->d[h++]=l;
+				break;
+				}
+			}
+		j-=(BN_BYTES*2);
+		}
+	ret->top=h;
+	bn_fix_top(ret);
+	ret->neg=neg;
+
+	*bn=ret;
+	return(num);
+err:
+	if (*bn == NULL) BN_free(ret);
+	return(0);
+	}
+
+int BN_dec2bn(BIGNUM **bn, const char *a)
+	{
+	BIGNUM *ret=NULL;
+	BN_ULONG l=0;
+	int neg=0,i,j;
+	int num;
+
+	if ((a == NULL) || (*a == '\0')) return(0);
+	if (*a == '-') { neg=1; a++; }
+
+	for (i=0; isdigit((unsigned char) a[i]); i++)
+		;
+
+	num=i+neg;
+	if (bn == NULL) return(num);
+
+	/* a is the start of the digits, and it is 'i' long.
+	 * We chop it into BN_DEC_NUM digits at a time */
+	if (*bn == NULL)
+		{
+		if ((ret=BN_new()) == NULL) return(0);
+		}
+	else
+		{
+		ret= *bn;
+		BN_zero(ret);
+		}
+
+	/* i is the number of digests, a bit of an over expand; */
+	if (bn_expand(ret,i*4) == NULL) goto err;
+
+	j=BN_DEC_NUM-(i%BN_DEC_NUM);
+	if (j == BN_DEC_NUM) j=0;
+	l=0;
+	while (*a)
+		{
+		l*=10;
+		l+= *a-'0';
+		a++;
+		if (++j == BN_DEC_NUM)
+			{
+			BN_mul_word(ret,BN_DEC_CONV);
+			BN_add_word(ret,l);
+			l=0;
+			j=0;
+			}
+		}
+	ret->neg=neg;
+
+	bn_fix_top(ret);
+	*bn=ret;
+	return(num);
+err:
+	if (*bn == NULL) BN_free(ret);
+	return(0);
+	}
+
+#ifndef NO_BIO
+#ifndef NO_FP_API
+int BN_print_fp(FILE *fp, const BIGNUM *a)
+	{
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		return(0);
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=BN_print(b,a);
+	BIO_free(b);
+	return(ret);
+	}
+#endif
+
+int BN_print(BIO *bp, const BIGNUM *a)
+	{
+	int i,j,v,z=0;
+	int ret=0;
+
+	if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end;
+	if ((a->top == 0) && (BIO_write(bp,"0",1) != 1)) goto end;
+	for (i=a->top-1; i >=0; i--)
+		{
+		for (j=BN_BITS2-4; j >= 0; j-=4)
+			{
+			/* strip leading zeros */
+			v=((int)(a->d[i]>>(long)j))&0x0f;
+			if (z || (v != 0))
+				{
+				if (BIO_write(bp,&(Hex[v]),1) != 1)
+					goto end;
+				z=1;
+				}
+			}
+		}
+	ret=1;
+end:
+	return(ret);
+	}
+#endif
+
+#ifdef BN_DEBUG
+void bn_dump1(FILE *o, const char *a, BN_ULONG *b,int n)
+	{
+	int i;
+	fprintf(o, "%s=", a);
+	for (i=n-1;i>=0;i--)
+		fprintf(o, "%08lX", b[i]); /* assumes 32-bit BN_ULONG */
+	fprintf(o, "\n");
+	}
+#endif
diff --git a/AppleCSP/open_ssl/bn/bn_rand.c b/AppleCSP/open_ssl/bn/bn_rand.c
new file mode 100644
index 00000000..8446be51
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_rand.c
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_rand.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+	{
+	unsigned char *buf=NULL;
+	int ret=0,bit,bytes,mask;
+	#ifndef	__APPLE__
+	time_t tim;
+	#endif
+	
+	bytes=(bits+7)/8;
+	bit=(bits-1)%8;
+	mask=0xff<<bit;
+
+	buf=(unsigned char *)Malloc(bytes);
+	if (buf == NULL)
+		{
+		BNerr(BN_F_BN_RAND,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* make a random number and set the top and bottom bits */
+	#ifndef	__APPLE__
+	/* we really don't need to do this, we have a good RNG */
+	time(&tim);
+	RAND_add(&tim,sizeof(tim),0);
+	#endif	/* __APPLE__ */
+	
+	if (pseudorand)
+		{
+		if (RAND_pseudo_bytes(buf, bytes) == -1)
+			goto err;
+		}
+	else
+		{
+		if (RAND_bytes(buf, bytes) <= 0)
+			goto err;
+		}
+
+	if (top)
+		{
+		if (bit == 0)
+			{
+			buf[0]=1;
+			buf[1]|=0x80;
+			}
+		else
+			{
+			buf[0]|=(3<<(bit-1));
+			buf[0]&= ~(mask<<1);
+			}
+		}
+	else
+		{
+		buf[0]|=(1<<bit);
+		buf[0]&= ~(mask<<1);
+		}
+	if (bottom) /* set bottom bits to whatever odd is */
+		buf[bytes-1]|=1;
+	if (!BN_bin2bn(buf,bytes,rnd)) goto err;
+	ret=1;
+err:
+	if (buf != NULL)
+		{
+		memset(buf,0,bytes);
+		Free(buf);
+		}
+	return(ret);
+	}
+
+int     BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
+	{
+	return bnrand(0, rnd, bits, top, bottom);
+	}
+
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+	{
+	return bnrand(1, rnd, bits, top, bottom);
+	}
diff --git a/AppleCSP/open_ssl/bn/bn_recp.c b/AppleCSP/open_ssl/bn/bn_recp.c
new file mode 100644
index 00000000..6fc6952a
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_recp.c
@@ -0,0 +1,238 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_recp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp)
+	{
+	BN_init(&(recp->N));
+	BN_init(&(recp->Nr));
+	recp->num_bits=0;
+	recp->flags=0;
+	}
+
+BN_RECP_CTX *BN_RECP_CTX_new(void)
+	{
+	BN_RECP_CTX *ret;
+
+	if ((ret=(BN_RECP_CTX *)Malloc(sizeof(BN_RECP_CTX))) == NULL)
+		return(NULL);
+
+	BN_RECP_CTX_init(ret);
+	ret->flags=BN_FLG_MALLOCED;
+	return(ret);
+	}
+
+void BN_RECP_CTX_free(BN_RECP_CTX *recp)
+	{
+	if(recp == NULL)
+	    return;
+
+	BN_free(&(recp->N));
+	BN_free(&(recp->Nr));
+	if (recp->flags & BN_FLG_MALLOCED)
+		Free(recp);
+	}
+
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
+	{
+	BN_copy(&(recp->N),d);
+	BN_zero(&(recp->Nr));
+	recp->num_bits=BN_num_bits(d);
+	recp->shift=0;
+	return(1);
+	}
+
+int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,
+	     BN_CTX *ctx)
+	{
+	int ret=0;
+	BIGNUM *a;
+
+	BN_CTX_start(ctx);
+	if ((a = BN_CTX_get(ctx)) == NULL) goto err;
+	if (y != NULL)
+		{
+		if (x == y)
+			{ if (!BN_sqr(a,x,ctx)) goto err; }
+		else
+			{ if (!BN_mul(a,x,y,ctx)) goto err; }
+		}
+	else
+		a=x; /* Just do the mod */
+
+	BN_div_recp(NULL,r,a,recp,ctx);
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp,
+	     BN_CTX *ctx)
+	{
+	int i,j,ret=0;
+	BIGNUM *a,*b,*d,*r;
+
+	BN_CTX_start(ctx);
+	a=BN_CTX_get(ctx);
+	b=BN_CTX_get(ctx);
+	if (dv != NULL)
+		d=dv;
+	else
+		d=BN_CTX_get(ctx);
+	if (rem != NULL)
+		r=rem;
+	else
+		r=BN_CTX_get(ctx);
+	if (a == NULL || b == NULL || d == NULL || r == NULL) goto err;
+
+	if (BN_ucmp(m,&(recp->N)) < 0)
+		{
+		BN_zero(d);
+		BN_copy(r,m);
+		BN_CTX_end(ctx);
+		return(1);
+		}
+
+	/* We want the remainder
+	 * Given input of ABCDEF / ab
+	 * we need multiply ABCDEF by 3 digests of the reciprocal of ab
+	 *
+	 */
+	i=BN_num_bits(m);
+
+	j=recp->num_bits<<1;
+	if (j>i) i=j;
+	j>>=1;
+
+	if (i != recp->shift)
+		recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N),
+			i,ctx);
+
+	if (!BN_rshift(a,m,j)) goto err;
+	if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err;
+	if (!BN_rshift(d,b,i-j)) goto err;
+	d->neg=0;
+	if (!BN_mul(b,&(recp->N),d,ctx)) goto err;
+	if (!BN_usub(r,m,b)) goto err;
+	r->neg=0;
+
+#if 1
+	j=0;
+	while (BN_ucmp(r,&(recp->N)) >= 0)
+		{
+		if (j++ > 2)
+			{
+			BNerr(BN_F_BN_MOD_MUL_RECIPROCAL,BN_R_BAD_RECIPROCAL);
+			goto err;
+			}
+		if (!BN_usub(r,r,&(recp->N))) goto err;
+		if (!BN_add_word(d,1)) goto err;
+		}
+#endif
+
+	r->neg=BN_is_zero(r)?0:m->neg;
+	d->neg=m->neg^recp->N.neg;
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	return(ret);
+	} 
+
+/* len is the expected size of the result
+ * We actually calculate with an extra word of precision, so
+ * we can do faster division if the remainder is not required.
+ */
+int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx)
+	{
+	int ret= -1;
+	BIGNUM t;
+
+	BN_init(&t);
+
+	BN_zero(&t);
+	if (!BN_set_bit(&t,len)) goto err;
+
+	if (!BN_div(r,NULL,&t,m,ctx)) goto err;
+	ret=len;
+err:
+	BN_free(&t);
+	return(ret);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bn_shift.c b/AppleCSP/open_ssl/bn/bn_shift.c
new file mode 100644
index 00000000..879a6757
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_shift.c
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_shift.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_lshift1(BIGNUM *r, BIGNUM *a)
+	{
+	register BN_ULONG *ap,*rp,t,c;
+	int i;
+
+	if (r != a)
+		{
+		r->neg=a->neg;
+		if (bn_wexpand(r,a->top+1) == NULL) return(0);
+		r->top=a->top;
+		}
+	else
+		{
+		if (bn_wexpand(r,a->top+1) == NULL) return(0);
+		}
+	ap=a->d;
+	rp=r->d;
+	c=0;
+	for (i=0; i<a->top; i++)
+		{
+		t= *(ap++);
+		*(rp++)=((t<<1)|c)&BN_MASK2;
+		c=(t & BN_TBIT)?1:0;
+		}
+	if (c)
+		{
+		*rp=1;
+		r->top++;
+		}
+	return(1);
+	}
+
+int BN_rshift1(BIGNUM *r, BIGNUM *a)
+	{
+	BN_ULONG *ap,*rp,t,c;
+	int i;
+
+	if (BN_is_zero(a))
+		{
+		BN_zero(r);
+		return(1);
+		}
+	if (a != r)
+		{
+		if (bn_wexpand(r,a->top) == NULL) return(0);
+		r->top=a->top;
+		r->neg=a->neg;
+		}
+	ap=a->d;
+	rp=r->d;
+	c=0;
+	for (i=a->top-1; i>=0; i--)
+		{
+		t=ap[i];
+		rp[i]=((t>>1)&BN_MASK2)|c;
+		c=(t&1)?BN_TBIT:0;
+		}
+	bn_fix_top(r);
+	return(1);
+	}
+
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
+	{
+	int i,nw,lb,rb;
+	BN_ULONG *t,*f;
+	BN_ULONG l;
+
+	r->neg=a->neg;
+	if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0);
+	nw=n/BN_BITS2;
+	lb=n%BN_BITS2;
+	rb=BN_BITS2-lb;
+	f=a->d;
+	t=r->d;
+	t[a->top+nw]=0;
+	if (lb == 0)
+		for (i=a->top-1; i>=0; i--)
+			t[nw+i]=f[i];
+	else
+		for (i=a->top-1; i>=0; i--)
+			{
+			l=f[i];
+			t[nw+i+1]|=(l>>rb)&BN_MASK2;
+			t[nw+i]=(l<<lb)&BN_MASK2;
+			}
+	memset(t,0,nw*sizeof(t[0]));
+/*	for (i=0; i<nw; i++)
+		t[i]=0;*/
+	r->top=a->top+nw+1;
+	bn_fix_top(r);
+	return(1);
+	}
+
+int BN_rshift(BIGNUM *r, BIGNUM *a, int n)
+	{
+	int i,j,nw,lb,rb;
+	BN_ULONG *t,*f;
+	BN_ULONG l,tmp;
+
+	nw=n/BN_BITS2;
+	rb=n%BN_BITS2;
+	lb=BN_BITS2-rb;
+	if (nw > a->top)
+		{
+		BN_zero(r);
+		return(1);
+		}
+	if (r != a)
+		{
+		r->neg=a->neg;
+		if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
+		}
+
+	f= &(a->d[nw]);
+	t=r->d;
+	j=a->top-nw;
+	r->top=j;
+
+	if (rb == 0)
+		{
+		for (i=j+1; i > 0; i--)
+			*(t++)= *(f++);
+		}
+	else
+		{
+		l= *(f++);
+		for (i=1; i<j; i++)
+			{
+			tmp =(l>>rb)&BN_MASK2;
+			l= *(f++);
+			*(t++) =(tmp|(l<<lb))&BN_MASK2;
+			}
+		*(t++) =(l>>rb)&BN_MASK2;
+		}
+	*t=0;
+	bn_fix_top(r);
+	return(1);
+	}
diff --git a/AppleCSP/open_ssl/bn/bn_sqr.c b/AppleCSP/open_ssl/bn/bn_sqr.c
new file mode 100644
index 00000000..0c08ced2
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_sqr.c
@@ -0,0 +1,306 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_sqr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r must not be a */
+/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
+int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx)
+	{
+	int max,al;
+	int ret = 0;
+	BIGNUM *tmp,*rr;
+
+#ifdef BN_COUNT
+printf("BN_sqr %d * %d\n",a->top,a->top);
+#endif
+	bn_check_top(a);
+
+	al=a->top;
+	if (al <= 0)
+		{
+		r->top=0;
+		return(1);
+		}
+
+	BN_CTX_start(ctx);
+	rr=(a != r) ? r : BN_CTX_get(ctx);
+	tmp=BN_CTX_get(ctx);
+	if (tmp == NULL) goto err;
+
+	max=(al+al);
+	if (bn_wexpand(rr,max+1) == NULL) goto err;
+
+	r->neg=0;
+	if (al == 4)
+		{
+#ifndef BN_SQR_COMBA
+		BN_ULONG t[8];
+		bn_sqr_normal(rr->d,a->d,4,t);
+#else
+		bn_sqr_comba4(rr->d,a->d);
+#endif
+		}
+	else if (al == 8)
+		{
+#ifndef BN_SQR_COMBA
+		BN_ULONG t[16];
+		bn_sqr_normal(rr->d,a->d,8,t);
+#else
+		bn_sqr_comba8(rr->d,a->d);
+#endif
+		}
+	else 
+		{
+#if defined(BN_RECURSION)
+		if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
+			{
+			BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
+			bn_sqr_normal(rr->d,a->d,al,t);
+			}
+		else
+			{
+			int j,k;
+
+			j=BN_num_bits_word((BN_ULONG)al);
+			j=1<<(j-1);
+			k=j+j;
+			if (al == j)
+				{
+				if (bn_wexpand(a,k*2) == NULL) goto err;
+				if (bn_wexpand(tmp,k*2) == NULL) goto err;
+				bn_sqr_recursive(rr->d,a->d,al,tmp->d);
+				}
+			else
+				{
+				if (bn_wexpand(tmp,max) == NULL) goto err;
+				bn_sqr_normal(rr->d,a->d,al,tmp->d);
+				}
+			}
+#else
+		if (bn_wexpand(tmp,max) == NULL) goto err;
+		bn_sqr_normal(rr->d,a->d,al,tmp->d);
+#endif
+		}
+
+	rr->top=max;
+	if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
+	if (rr != r) BN_copy(r,rr);
+	ret = 1;
+ err:
+	BN_CTX_end(ctx);
+	return(ret);
+	}
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp)
+	{
+	int i,j,max;
+	BN_ULONG *ap,*rp;
+
+	max=n*2;
+	ap=a;
+	rp=r;
+	rp[0]=rp[max-1]=0;
+	rp++;
+	j=n;
+
+	if (--j > 0)
+		{
+		ap++;
+		rp[j]=bn_mul_words(rp,ap,j,ap[-1]);
+		rp+=2;
+		}
+
+	for (i=n-2; i>0; i--)
+		{
+		j--;
+		ap++;
+		rp[j]=bn_mul_add_words(rp,ap,j,ap[-1]);
+		rp+=2;
+		}
+
+	bn_add_words(r,r,r,max);
+
+	/* There will not be a carry */
+
+	bn_sqr_words(tmp,a,n);
+
+	bn_add_words(r,r,tmp,max);
+	}
+
+#ifdef BN_RECURSION
+/* r is 2*n words in size,
+ * a and b are both n words in size.
+ * n must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *t)
+	{
+	int n=n2/2;
+	int zero,c1;
+	BN_ULONG ln,lo,*p;
+
+#ifdef BN_COUNT
+printf(" bn_sqr_recursive %d * %d\n",n2,n2);
+#endif
+	if (n2 == 4)
+		{
+#ifndef BN_SQR_COMBA
+		bn_sqr_normal(r,a,4,t);
+#else
+		bn_sqr_comba4(r,a);
+#endif
+		return;
+		}
+	else if (n2 == 8)
+		{
+#ifndef BN_SQR_COMBA
+		bn_sqr_normal(r,a,8,t);
+#else
+		bn_sqr_comba8(r,a);
+#endif
+		return;
+		}
+	if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL)
+		{
+		bn_sqr_normal(r,a,n2,t);
+		return;
+		}
+	/* r=(a[0]-a[1])*(a[1]-a[0]) */
+	c1=bn_cmp_words(a,&(a[n]),n);
+	zero=0;
+	if (c1 > 0)
+		bn_sub_words(t,a,&(a[n]),n);
+	else if (c1 < 0)
+		bn_sub_words(t,&(a[n]),a,n);
+	else
+		zero=1;
+
+	/* The result will always be negative unless it is zero */
+	p= &(t[n2*2]);
+
+	if (!zero)
+		bn_sqr_recursive(&(t[n2]),t,n,p);
+	else
+		memset(&(t[n2]),0,n*sizeof(BN_ULONG));
+	bn_sqr_recursive(r,a,n,p);
+	bn_sqr_recursive(&(r[n2]),&(a[n]),n,p);
+
+	/* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+
+	/* t[32] is negative */
+	c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+
+	/* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
+	 * r[10] holds (a[0]*a[0])
+	 * r[32] holds (a[1]*a[1])
+	 * c1 holds the carry bits
+	 */
+	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+	if (c1)
+		{
+		p= &(r[n+n2]);
+		lo= *p;
+		ln=(lo+c1)&BN_MASK2;
+		*p=ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < (BN_ULONG)c1)
+			{
+			do	{
+				p++;
+				lo= *p;
+				ln=(lo+1)&BN_MASK2;
+				*p=ln;
+				} while (ln == 0);
+			}
+		}
+	}
+#endif
diff --git a/AppleCSP/open_ssl/bn/bn_word.c b/AppleCSP/open_ssl/bn/bn_word.c
new file mode 100644
index 00000000..d970d351
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bn_word.c
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn_word.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
+	{
+#ifndef BN_LLONG
+	BN_ULONG ret=0;
+#else
+	BN_ULLONG ret=0;
+#endif
+	int i;
+
+	w&=BN_MASK2;
+	for (i=a->top-1; i>=0; i--)
+		{
+#ifndef BN_LLONG
+		ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
+		ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%w;
+#else
+		ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])%
+			(BN_ULLONG)w);
+#endif
+		}
+	return((BN_ULONG)ret);
+	}
+
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
+	{
+	BN_ULONG ret;
+	int i;
+
+	if (a->top == 0) return(0);
+	ret=0;
+	w&=BN_MASK2;
+	for (i=a->top-1; i>=0; i--)
+		{
+		BN_ULONG l,d;
+		
+		l=a->d[i];
+		d=bn_div_words(ret,l,w);
+		ret=(l-((d*w)&BN_MASK2))&BN_MASK2;
+		a->d[i]=d;
+		}
+	if ((a->top > 0) && (a->d[a->top-1] == 0))
+		a->top--;
+	return(ret);
+	}
+
+int BN_add_word(BIGNUM *a, BN_ULONG w)
+	{
+	BN_ULONG l;
+	int i;
+
+	if (a->neg)
+		{
+		a->neg=0;
+		i=BN_sub_word(a,w);
+		if (!BN_is_zero(a))
+			a->neg=1;
+		return(i);
+		}
+	w&=BN_MASK2;
+	if (bn_wexpand(a,a->top+1) == NULL) return(0);
+	i=0;
+	for (;;)
+		{
+		l=(a->d[i]+(BN_ULONG)w)&BN_MASK2;
+		a->d[i]=l;
+		if (w > l)
+			w=1;
+		else
+			break;
+		i++;
+		}
+	if (i >= a->top)
+		a->top++;
+	return(1);
+	}
+
+int BN_sub_word(BIGNUM *a, BN_ULONG w)
+	{
+	int i;
+
+	if (a->neg)
+		{
+		a->neg=0;
+		i=BN_add_word(a,w);
+		a->neg=1;
+		return(i);
+		}
+
+	w&=BN_MASK2;
+	if ((a->top == 1) && (a->d[0] < w))
+		{
+		a->d[0]=w-a->d[0];
+		a->neg=1;
+		return(1);
+		}
+	i=0;
+	for (;;)
+		{
+		if (a->d[i] >= w)
+			{
+			a->d[i]-=w;
+			break;
+			}
+		else
+			{
+			a->d[i]=(a->d[i]-w)&BN_MASK2;
+			i++;
+			w=1;
+			}
+		}
+	if ((a->d[i] == 0) && (i == (a->top-1)))
+		a->top--;
+	return(1);
+	}
+
+int BN_mul_word(BIGNUM *a, BN_ULONG w)
+	{
+	BN_ULONG ll;
+
+	w&=BN_MASK2;
+	if (a->top)
+		{
+		ll=bn_mul_words(a->d,a->d,a->top,w);
+		if (ll)
+			{
+			if (bn_wexpand(a,a->top+1) == NULL) return(0);
+			a->d[a->top++]=ll;
+			}
+		}
+	return(1);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bnspeed.c b/AppleCSP/open_ssl/bn/bnspeed.c
new file mode 100644
index 00000000..41b47b06
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bnspeed.c
@@ -0,0 +1,251 @@
+/*
+ * 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.
+ */
+
+
+/* unused */
+
+/* crypto/bn/bnspeed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#define BASENUM	1000000
+#undef PROG
+#define PROG bnspeed_main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#if !defined(MSDOS) && (!defined(VMS) || defined(__DECC))
+#define TIMES
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(VMS) && defined(__DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+#  ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
+#   define HZ	100.0
+#  else /* _BSD_CLK_TCK_ */
+#   define HZ ((double)_BSD_CLK_TCK_)
+#  endif
+# else /* CLK_TCK */
+#  define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE	((long)1024*8)
+int run=0;
+
+static double Time_F(int s);
+#define START	0
+#define STOP	1
+
+static double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret < 1e-3)?1e-3:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
+		return((ret < 0.001)?0.001:ret);
+		}
+#endif
+	}
+
+#define NUM_SIZES	5
+static int sizes[NUM_SIZES]={128,256,512,1024,2048};
+/*static int sizes[NUM_SIZES]={59,179,299,419,539}; */
+
+void do_mul(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_CTX *ctx); 
+
+int main(int argc, char **argv)
+	{
+	BN_CTX *ctx;
+	BIGNUM a,b,c;
+
+	ctx=BN_CTX_new();
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+
+	do_mul(&a,&b,&c,ctx);
+	}
+
+void do_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+	{
+	int i,j,k;
+	double tm;
+	long num;
+
+	for (i=0; i<NUM_SIZES; i++)
+		{
+		num=BASENUM;
+		if (i) num/=(i*3);
+		BN_rand(a,sizes[i],1,0);
+		for (j=i; j<NUM_SIZES; j++)
+			{
+			BN_rand(b,sizes[j],1,0);
+			Time_F(START);
+			for (k=0; k<num; k++)
+				BN_mul(r,b,a,ctx);
+			tm=Time_F(STOP);
+			printf("mul %4d x %4d -> %8.3fms\n",sizes[i],sizes[j],tm*1000.0/num);
+			}
+		}
+
+	for (i=0; i<NUM_SIZES; i++)
+		{
+		num=BASENUM;
+		if (i) num/=(i*3);
+		BN_rand(a,sizes[i],1,0);
+		Time_F(START);
+		for (k=0; k<num; k++)
+			BN_sqr(r,a,ctx);
+		tm=Time_F(STOP);
+		printf("sqr %4d x %4d -> %8.3fms\n",sizes[i],sizes[i],tm*1000.0/num);
+		}
+
+	for (i=0; i<NUM_SIZES; i++)
+		{
+		num=BASENUM/10;
+		if (i) num/=(i*3);
+		BN_rand(a,sizes[i]-1,1,0);
+		for (j=i; j<NUM_SIZES; j++)
+			{
+			BN_rand(b,sizes[j],1,0);
+			Time_F(START);
+			for (k=0; k<100000; k++)
+				BN_div(r, NULL, b, a,ctx);
+			tm=Time_F(STOP);
+			printf("div %4d / %4d -> %8.3fms\n",sizes[j],sizes[i]-1,tm*1000.0/num);
+			}
+		}
+	}
+
diff --git a/AppleCSP/open_ssl/bn/bntest.c b/AppleCSP/open_ssl/bn/bntest.c
new file mode 100644
index 00000000..4549814f
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/bntest.c
@@ -0,0 +1,1096 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bntest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "openssl/e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+#ifdef WINDOWS
+#include "../bio/bss_file.c"
+#endif
+
+const int num0 = 100; /* number of tests */
+const int num1 = 50;  /* additional tests for some functions */
+const int num2 = 5;   /* number of tests for slow functions */
+
+int test_add(BIO *bp);
+int test_sub(BIO *bp);
+int test_lshift1(BIO *bp);
+int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
+int test_rshift1(BIO *bp);
+int test_rshift(BIO *bp,BN_CTX *ctx);
+int test_div(BIO *bp,BN_CTX *ctx);
+int test_div_recp(BIO *bp,BN_CTX *ctx);
+int test_mul(BIO *bp);
+int test_sqr(BIO *bp,BN_CTX *ctx);
+int test_mont(BIO *bp,BN_CTX *ctx);
+int test_mod(BIO *bp,BN_CTX *ctx);
+int test_mod_mul(BIO *bp,BN_CTX *ctx);
+int test_mod_exp(BIO *bp,BN_CTX *ctx);
+int test_exp(BIO *bp,BN_CTX *ctx);
+int rand_neg(void);
+static int results=0;
+
+#ifdef NO_STDIO
+#define APPS_WIN16
+#include "bss_file.c"
+#endif
+
+static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
+"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+static void message(BIO *out, char *m)
+	{
+	fprintf(stderr, "test %s\n", m);
+#if defined(linux) || defined(__FreeBSD__) /* can we use GNU bc features? */
+	BIO_puts(out, "print \"test ");
+	BIO_puts(out, m);
+	BIO_puts(out, "\\n\"\n");
+#endif
+	}
+
+int main(int argc, char *argv[])
+	{
+	BN_CTX *ctx;
+	BIO *out;
+	char *outfile=NULL;
+
+	results = 0;
+
+	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
+	                                       * even check its return value
+	                                       * (which we should) */
+
+	argc--;
+	argv++;
+	while (argc >= 1)
+		{
+		if (strcmp(*argv,"-results") == 0)
+			results=1;
+		else if (strcmp(*argv,"-out") == 0)
+			{
+			if (--argc < 1) break;
+			outfile= *(++argv);
+			}
+		argc--;
+		argv++;
+		}
+
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) exit(1);
+
+	out=BIO_new(BIO_s_file());
+	if (out == NULL) exit(1);
+	if (outfile == NULL)
+		{
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+		}
+	else
+		{
+		if (!BIO_write_filename(out,outfile))
+			{
+			perror(outfile);
+			exit(1);
+			}
+		}
+
+	if (!results)
+		BIO_puts(out,"obase=16\nibase=16\n");
+
+	message(out,"BN_add");
+	if (!test_add(out)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_sub");
+	if (!test_sub(out)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_lshift1");
+	if (!test_lshift1(out)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_lshift (fixed)");
+	if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
+	    goto err;
+	BIO_flush(out);
+
+	message(out,"BN_lshift");
+	if (!test_lshift(out,ctx,NULL)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_rshift1");
+	if (!test_rshift1(out)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_rshift");
+	if (!test_rshift(out,ctx)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_sqr");
+	if (!test_sqr(out,ctx)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_mul");
+	if (!test_mul(out)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_div");
+	if (!test_div(out,ctx)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_div_recp");
+	if (!test_div_recp(out,ctx)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_mod");
+	if (!test_mod(out,ctx)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_mod_mul");
+	if (!test_mod_mul(out,ctx)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_mont");
+	if (!test_mont(out,ctx)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_mod_exp");
+	if (!test_mod_exp(out,ctx)) goto err;
+	BIO_flush(out);
+
+	message(out,"BN_exp");
+	if (!test_exp(out,ctx)) goto err;
+	BIO_flush(out);
+
+	BN_CTX_free(ctx);
+	BIO_free(out);
+
+/**/
+	exit(0);
+err:
+	BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
+	                      * the failure, see test_bn in test/Makefile.ssl*/
+	BIO_flush(out);
+	ERR_load_crypto_strings();
+	ERR_print_errors_fp(stderr);
+	exit(1);
+	return(1);
+	}
+
+int test_add(BIO *bp)
+	{
+	BIGNUM a,b,c;
+	int i;
+	int j;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+
+	BN_rand(&a,512,0,0);
+	for (i=0; i<num0; i++)
+		{
+		BN_rand(&b,450+i,0,0);
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		if (bp == NULL)
+			for (j=0; j<10000; j++)
+				BN_add(&c,&a,&b);
+		BN_add(&c,&a,&b);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," + ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		a.neg=!a.neg;
+		b.neg=!b.neg;
+		BN_add(&c,&c,&b);
+		BN_add(&c,&c,&a);
+		if(!BN_is_zero(&c))
+		    {
+		    fprintf(stderr,"Add test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	return(1);
+	}
+
+int test_sub(BIO *bp)
+	{
+	BIGNUM a,b,c;
+	int i;
+	int j;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+
+	for (i=0; i<num0+num1; i++)
+		{
+		if (i < num1)
+			{
+			BN_rand(&a,512,0,0);
+			BN_copy(&b,&a);
+			if (BN_set_bit(&a,i)==0) return(0);
+			BN_add_word(&b,i);
+			}
+		else
+			{
+			BN_rand(&b,400+i-num1,0,0);
+			a.neg=rand_neg();
+			b.neg=rand_neg();
+			}
+		if (bp == NULL)
+			for (j=0; j<10000; j++)
+				BN_sub(&c,&a,&b);
+		BN_sub(&c,&a,&b);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," - ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_add(&c,&c,&b);
+		BN_sub(&c,&c,&a);
+		if(!BN_is_zero(&c))
+		    {
+		    fprintf(stderr,"Subtract test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	return(1);
+	}
+
+int test_div(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM a,b,c,d,e;
+	int i;
+	int j;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&e);
+
+	for (i=0; i<num0+num1; i++)
+		{
+		if (i < num1)
+			{
+			BN_rand(&a,400,0,0);
+			BN_copy(&b,&a);
+			BN_lshift(&a,&a,i);
+			BN_add_word(&a,i);
+			}
+		else
+			BN_rand(&b,50+3*(i-num1),0,0);
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		if (bp == NULL)
+			for (j=0; j<100; j++)
+				BN_div(&d,&c,&a,&b,ctx);
+		BN_div(&d,&c,&a,&b,ctx);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," / ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&d);
+			BIO_puts(bp,"\n");
+
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," % ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul(&e,&d,&b,ctx);
+		BN_add(&d,&e,&c);
+		BN_sub(&d,&d,&a);
+		if(!BN_is_zero(&d))
+		    {
+		    fprintf(stderr,"Division test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&e);
+	return(1);
+	}
+
+int test_div_recp(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM a,b,c,d,e;
+	BN_RECP_CTX recp;
+	int i;
+	int j;
+
+	BN_RECP_CTX_init(&recp);
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&e);
+
+	for (i=0; i<num0+num1; i++)
+		{
+		if (i < num1)
+			{
+			BN_rand(&a,400,0,0);
+			BN_copy(&b,&a);
+			BN_lshift(&a,&a,i);
+			BN_add_word(&a,i);
+			}
+		else
+			BN_rand(&b,50+3*(i-num1),0,0);
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		BN_RECP_CTX_set(&recp,&b,ctx);
+		if (bp == NULL)
+			for (j=0; j<100; j++)
+				BN_div_recp(&d,&c,&a,&recp,ctx);
+		BN_div_recp(&d,&c,&a,&recp,ctx);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," / ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&d);
+			BIO_puts(bp,"\n");
+
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," % ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul(&e,&d,&b,ctx);
+		BN_add(&d,&e,&c);
+		BN_sub(&d,&d,&a);
+		if(!BN_is_zero(&d))
+		    {
+		    fprintf(stderr,"Reciprocal division test failed!\n");
+		    fprintf(stderr,"a=");
+		    BN_print_fp(stderr,&a);
+		    fprintf(stderr,"\nb=");
+		    BN_print_fp(stderr,&b);
+		    fprintf(stderr,"\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&e);
+	BN_RECP_CTX_free(&recp);
+	return(1);
+	}
+
+int test_mul(BIO *bp)
+	{
+	BIGNUM a,b,c,d,e;
+	int i;
+	int j;
+	BN_CTX ctx;
+
+	BN_CTX_init(&ctx);
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&e);
+
+	for (i=0; i<num0+num1; i++)
+		{
+		if (i <= num1)
+			{
+			BN_rand(&a,100,0,0);
+			BN_rand(&b,100,0,0);
+			}
+		else
+			BN_rand(&b,i-num1,0,0);
+		a.neg=rand_neg();
+		b.neg=rand_neg();
+		if (bp == NULL)
+			for (j=0; j<100; j++)
+				BN_mul(&c,&a,&b,&ctx);
+		BN_mul(&c,&a,&b,&ctx);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," * ");
+				BN_print(bp,&b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_div(&d,&e,&c,&a,&ctx);
+		BN_sub(&d,&d,&b);
+		if(!BN_is_zero(&d) || !BN_is_zero(&e))
+		    {
+		    fprintf(stderr,"Multiplication test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&e);
+	BN_CTX_free(&ctx);
+	return(1);
+	}
+
+int test_sqr(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM a,c,d,e;
+	int i;
+	int j;
+
+	BN_init(&a);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&e);
+
+	for (i=0; i<num0; i++)
+		{
+		BN_rand(&a,40+i*10,0,0);
+		a.neg=rand_neg();
+		if (bp == NULL)
+			for (j=0; j<100; j++)
+				BN_sqr(&c,&a,ctx);
+		BN_sqr(&c,&a,ctx);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,&a);
+				BIO_puts(bp," * ");
+				BN_print(bp,&a);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&c);
+			BIO_puts(bp,"\n");
+			}
+		BN_div(&d,&e,&c,&a,ctx);
+		BN_sub(&d,&d,&a);
+		if(!BN_is_zero(&d) || !BN_is_zero(&e))
+		    {
+		    fprintf(stderr,"Square test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(&a);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&e);
+	return(1);
+	}
+
+int test_mont(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM a,b,c,d,A,B;
+	BIGNUM n;
+	int i;
+	int j;
+	BN_MONT_CTX *mont;
+
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&d);
+	BN_init(&A);
+	BN_init(&B);
+	BN_init(&n);
+
+	mont=BN_MONT_CTX_new();
+
+	BN_rand(&a,100,0,0); /**/
+	BN_rand(&b,100,0,0); /**/
+	for (i=0; i<num2; i++)
+		{
+		int bits = (200*(i+1))/num2;
+
+		if (bits == 0)
+			continue;
+		BN_rand(&n,bits,0,1);
+		BN_MONT_CTX_set(mont,&n,ctx);
+
+		BN_to_montgomery(&A,&a,mont,ctx);
+		BN_to_montgomery(&B,&b,mont,ctx);
+
+		if (bp == NULL)
+			for (j=0; j<100; j++)
+				BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
+		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
+		BN_from_montgomery(&A,&c,mont,ctx);/**/
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+#ifdef undef
+fprintf(stderr,"%d * %d %% %d\n",
+BN_num_bits(&a),
+BN_num_bits(&b),
+BN_num_bits(mont->N));
+#endif
+				BN_print(bp,&a);
+				BIO_puts(bp," * ");
+				BN_print(bp,&b);
+				BIO_puts(bp," % ");
+				BN_print(bp,&(mont->N));
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,&A);
+			BIO_puts(bp,"\n");
+			}
+		BN_mod_mul(&d,&a,&b,&n,ctx);
+		BN_sub(&d,&d,&A);
+		if(!BN_is_zero(&d))
+		    {
+		    fprintf(stderr,"Montgomery multiplication test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_MONT_CTX_free(mont);
+	BN_free(&a);
+	BN_free(&b);
+	BN_free(&c);
+	BN_free(&d);
+	BN_free(&A);
+	BN_free(&B);
+	BN_free(&n);
+	return(1);
+	}
+
+int test_mod(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i;
+	int j;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	BN_rand(a,1024,0,0); /**/
+	for (i=0; i<num0; i++)
+		{
+		BN_rand(b,450+i*10,0,0); /**/
+		a->neg=rand_neg();
+		b->neg=rand_neg();
+		if (bp == NULL)
+			for (j=0; j<100; j++)
+				BN_mod(c,a,b,ctx);/**/
+		BN_mod(c,a,b,ctx);/**/
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," % ");
+				BN_print(bp,b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,c);
+			BIO_puts(bp,"\n");
+			}
+		BN_div(d,e,a,b,ctx);
+		BN_sub(e,e,c);
+		if(!BN_is_zero(e))
+		    {
+		    fprintf(stderr,"Modulo test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_mod_mul(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	BN_rand(c,1024,0,0); /**/
+	for (i=0; i<num0; i++)
+		{
+		BN_rand(a,475+i*10,0,0); /**/
+		BN_rand(b,425+i*11,0,0); /**/
+		a->neg=rand_neg();
+		b->neg=rand_neg();
+	/*	if (bp == NULL)
+			for (j=0; j<100; j++)
+				BN_mod_mul(d,a,b,c,ctx);*/ /**/
+
+		if (!BN_mod_mul(e,a,b,c,ctx))
+			{
+			unsigned long l;
+
+			while ((l=ERR_get_error()))
+				fprintf(stderr,"ERROR:%s\n",
+					ERR_error_string(l,NULL));
+			exit(1);
+			}
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," * ");
+				BN_print(bp,b);
+				BIO_puts(bp," % ");
+				BN_print(bp,c);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,e);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul(d,a,b,ctx);
+		BN_sub(d,d,e);
+		BN_div(a,b,d,c,ctx);
+		if(!BN_is_zero(b))
+		    {
+		    fprintf(stderr,"Modulo multiply test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_mod_exp(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+
+	BN_rand(c,30,0,1); /* must be odd for montgomery */
+	for (i=0; i<num2; i++)
+		{
+		BN_rand(a,20+i*5,0,0); /**/
+		BN_rand(b,2+i,0,0); /**/
+
+		if (!BN_mod_exp(d,a,b,c,ctx))
+			return(00);
+
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," ^ ");
+				BN_print(bp,b);
+				BIO_puts(bp," % ");
+				BN_print(bp,c);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,d);
+			BIO_puts(bp,"\n");
+			}
+		BN_exp(e,a,b,ctx);
+		BN_sub(e,e,d);
+		BN_div(a,b,e,c,ctx);
+		if(!BN_is_zero(b))
+		    {
+		    fprintf(stderr,"Modulo exponentiation test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_exp(BIO *bp, BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*d,*e,*one;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	d=BN_new();
+	e=BN_new();
+	one=BN_new();
+	BN_one(one);
+
+	for (i=0; i<num2; i++)
+		{
+		BN_rand(a,20+i*5,0,0); /**/
+		BN_rand(b,2+i,0,0); /**/
+
+		if (!BN_exp(d,a,b,ctx))
+			return(00);
+
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," ^ ");
+				BN_print(bp,b);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,d);
+			BIO_puts(bp,"\n");
+			}
+		BN_one(e);
+		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
+		    BN_mul(e,e,a,ctx);
+		BN_sub(e,e,d);
+		if(!BN_is_zero(e))
+		    {
+		    fprintf(stderr,"Exponentiation test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(d);
+	BN_free(e);
+	BN_free(one);
+	return(1);
+	}
+
+int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
+	{
+	BIGNUM *a,*b,*c,*d;
+	int i;
+
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	BN_one(c);
+
+	if(a_)
+	    a=a_;
+	else
+	    {
+	    a=BN_new();
+	    BN_rand(a,200,0,0); /**/
+	    a->neg=rand_neg();
+	    }
+	for (i=0; i<num0; i++)
+		{
+		BN_lshift(b,a,i+1);
+		BN_add(c,c,c);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," * ");
+				BN_print(bp,c);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,b);
+			BIO_puts(bp,"\n");
+			}
+		BN_mul(d,a,c,ctx);
+		BN_sub(d,d,b);
+		if(!BN_is_zero(d))
+		    {
+		    fprintf(stderr,"Left shift test failed!\n");
+		    fprintf(stderr,"a=");
+		    BN_print_fp(stderr,a);
+		    fprintf(stderr,"\nb=");
+		    BN_print_fp(stderr,b);
+		    fprintf(stderr,"\nc=");
+		    BN_print_fp(stderr,c);
+		    fprintf(stderr,"\nd=");
+		    BN_print_fp(stderr,d);
+		    fprintf(stderr,"\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	return(1);
+	}
+
+int test_lshift1(BIO *bp)
+	{
+	BIGNUM *a,*b,*c;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+
+	BN_rand(a,200,0,0); /**/
+	a->neg=rand_neg();
+	for (i=0; i<num0; i++)
+		{
+		BN_lshift1(b,a);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," * 2");
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,b);
+			BIO_puts(bp,"\n");
+			}
+		BN_add(c,a,a);
+		BN_sub(a,b,c);
+		if(!BN_is_zero(a))
+		    {
+		    fprintf(stderr,"Left shift one test failed!\n");
+		    return 0;
+		    }
+		
+		BN_copy(a,b);
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	return(1);
+	}
+
+int test_rshift(BIO *bp,BN_CTX *ctx)
+	{
+	BIGNUM *a,*b,*c,*d,*e;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	d=BN_new();
+	e=BN_new();
+	BN_one(c);
+
+	BN_rand(a,200,0,0); /**/
+	a->neg=rand_neg();
+	for (i=0; i<num0; i++)
+		{
+		BN_rshift(b,a,i+1);
+		BN_add(c,c,c);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," / ");
+				BN_print(bp,c);
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,b);
+			BIO_puts(bp,"\n");
+			}
+		BN_div(d,e,a,c,ctx);
+		BN_sub(d,d,b);
+		if(!BN_is_zero(d))
+		    {
+		    fprintf(stderr,"Right shift test failed!\n");
+		    return 0;
+		    }
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	BN_free(d);
+	BN_free(e);
+	return(1);
+	}
+
+int test_rshift1(BIO *bp)
+	{
+	BIGNUM *a,*b,*c;
+	int i;
+
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+
+	BN_rand(a,200,0,0); /**/
+	a->neg=rand_neg();
+	for (i=0; i<num0; i++)
+		{
+		BN_rshift1(b,a);
+		if (bp != NULL)
+			{
+			if (!results)
+				{
+				BN_print(bp,a);
+				BIO_puts(bp," / 2");
+				BIO_puts(bp," - ");
+				}
+			BN_print(bp,b);
+			BIO_puts(bp,"\n");
+			}
+		BN_sub(c,a,b);
+		BN_sub(c,c,b);
+		if(!BN_is_zero(c) && !BN_is_one(c))
+		    {
+		    fprintf(stderr,"Right shift one test failed!\n");
+		    return 0;
+		    }
+		BN_copy(a,b);
+		}
+	BN_free(a);
+	BN_free(b);
+	BN_free(c);
+	return(1);
+	}
+
+int rand_neg(void)
+	{
+	static unsigned int neg=0;
+	static int sign[8]={0,0,0,1,1,0,1,1};
+
+	return(sign[(neg++)%8]);
+	}
diff --git a/AppleCSP/open_ssl/bn/divtest.c b/AppleCSP/open_ssl/bn/divtest.c
new file mode 100644
index 00000000..9a1417df
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/divtest.c
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+
+static int rand(n)
+{
+    unsigned char x[2];
+    RAND_pseudo_bytes(x,2);
+    return (x[0] + 2*x[1]);
+}
+
+static void bug(char *m, BIGNUM *a, BIGNUM *b)
+{
+    printf("%s!\na=",m);
+    BN_print_fp(stdout, a);
+    printf("\nb=");
+    BN_print_fp(stdout, b);
+    printf("\n");
+    fflush(stdout);
+}
+
+main()
+{
+    BIGNUM *a=BN_new(), *b=BN_new(), *c=BN_new(), *d=BN_new(),
+	*C=BN_new(), *D=BN_new();
+    BN_RECP_CTX *recp=BN_RECP_CTX_new();
+    BN_CTX *ctx=BN_CTX_new();
+
+    for(;;) {
+	BN_pseudo_rand(a,rand(),0,0);
+	BN_pseudo_rand(b,rand(),0,0);
+	if (BN_is_zero(b)) continue;
+
+	BN_RECP_CTX_set(recp,b,ctx);
+	if (BN_div(C,D,a,b,ctx) != 1)
+	    bug("BN_div failed",a,b);
+	if (BN_div_recp(c,d,a,recp,ctx) != 1)
+	    bug("BN_div_recp failed",a,b);
+	else if (BN_cmp(c,C) != 0 || BN_cmp(c,C) != 0)
+	    bug("mismatch",a,b);
+    }
+}
diff --git a/AppleCSP/open_ssl/bn/exp.c b/AppleCSP/open_ssl/bn/exp.c
new file mode 100644
index 00000000..7daec41d
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/exp.c
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+
+/* unused */
+
+#include <stdio.h>
+#include <openssl/tmdiff.h>
+#include "bn_lcl.h"
+
+#define SIZE	256
+#define NUM	(8*8*8)
+#define MOD	(8*8*8*8*8)
+
+main(argc,argv)
+int argc;
+char *argv[];
+	{
+	BN_CTX ctx;
+	BIGNUM a,b,c,r,rr,t,l;
+	int j,i,size=SIZE,num=NUM,mod=MOD;
+	char *start,*end;
+	BN_MONT_CTX mont;
+	double d,md;
+
+	BN_MONT_CTX_init(&mont);
+	BN_CTX_init(&ctx);
+	BN_init(&a);
+	BN_init(&b);
+	BN_init(&c);
+	BN_init(&r);
+
+	start=ms_time_new();
+	end=ms_time_new();
+	while (size <= 1024*8)
+		{
+		BN_rand(&a,size,0,0);
+		BN_rand(&b,size,1,0);
+		BN_rand(&c,size,0,1);
+
+		BN_mod(&a,&a,&c,&ctx);
+
+		ms_time_get(start);
+		for (i=0; i<10; i++)
+			BN_MONT_CTX_set(&mont,&c,&ctx);
+		ms_time_get(end);
+		md=ms_time_diff(start,end);
+
+		ms_time_get(start);
+		for (i=0; i<num; i++)
+			{
+			/* bn_mull(&r,&a,&b,&ctx); */
+			/* BN_sqr(&r,&a,&ctx); */
+			BN_mod_exp_mont(&r,&a,&b,&c,&ctx,&mont);
+			}
+		ms_time_get(end);
+		d=ms_time_diff(start,end)/* *50/33 */;
+		printf("%5d bit:%6.2f %6d %6.4f %4d m_set(%5.4f)\n",size,
+			d,num,d/num,(int)((d/num)*mod),md/10.0);
+		num/=8;
+		mod/=8;
+		if (num <= 0) num=1;
+		size*=2;
+		}
+
+	}
diff --git a/AppleCSP/open_ssl/bn/expspeed.c b/AppleCSP/open_ssl/bn/expspeed.c
new file mode 100644
index 00000000..b2cb29e1
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/expspeed.c
@@ -0,0 +1,233 @@
+/*
+ * 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.
+ */
+
+
+/* unused */
+
+/* crypto/bn/expspeed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#define BASENUM	5000
+#undef PROG
+#define PROG bnspeed_main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#if !defined(MSDOS) && (!defined(VMS) || defined(__DECC))
+#define TIMES
+#endif
+
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+
+/* Depending on the VMS version, the tms structure is perhaps defined.
+   The __TMS macro will show if it was.  If it wasn't defined, we should
+   undefine TIMES, since that tells the rest of the program how things
+   should be handled.				-- Richard Levitte */
+#if defined(VMS) && defined(__DECC) && !defined(__TMS)
+#undef TIMES
+#endif
+
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+#define _POSIX_SOURCE
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+
+/* The following if from times(3) man page.  It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+#  ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
+#   define HZ	100.0
+#  else /* _BSD_CLK_TCK_ */
+#   define HZ ((double)_BSD_CLK_TCK_)
+#  endif
+# else /* CLK_TCK */
+#  define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE	((long)1024*8)
+int run=0;
+
+static double Time_F(int s);
+#define START	0
+#define STOP	1
+
+static double Time_F(int s)
+	{
+	double ret;
+#ifdef TIMES
+	static struct tms tstart,tend;
+
+	if (s == START)
+		{
+		times(&tstart);
+		return(0);
+		}
+	else
+		{
+		times(&tend);
+		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+		return((ret < 1e-3)?1e-3:ret);
+		}
+#else /* !times() */
+	static struct timeb tstart,tend;
+	long i;
+
+	if (s == START)
+		{
+		ftime(&tstart);
+		return(0);
+		}
+	else
+		{
+		ftime(&tend);
+		i=(long)tend.millitm-(long)tstart.millitm;
+		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
+		return((ret < 0.001)?0.001:ret);
+		}
+#endif
+	}
+
+#define NUM_SIZES	6
+static int sizes[NUM_SIZES]={256,512,1024,2048,4096,8192};
+static int mul_c[NUM_SIZES]={8*8*8*8*8,8*8*8*8,8*8*8,8*8,8,1};
+/*static int sizes[NUM_SIZES]={59,179,299,419,539}; */
+
+void do_mul_exp(BIGNUM *r,BIGNUM *a,BIGNUM *b,BIGNUM *c,BN_CTX *ctx); 
+
+int main(int argc, char **argv)
+	{
+	BN_CTX *ctx;
+	BIGNUM *a,*b,*c,*r;
+
+	ctx=BN_CTX_new();
+	a=BN_new();
+	b=BN_new();
+	c=BN_new();
+	r=BN_new();
+
+	do_mul_exp(r,a,b,c,ctx);
+	}
+
+void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
+	{
+	int i,k;
+	double tm;
+	long num;
+	BN_MONT_CTX m;
+
+	memset(&m,0,sizeof(m));
+
+	num=BASENUM;
+	for (i=0; i<NUM_SIZES; i++)
+		{
+		BN_rand(a,sizes[i],1,0);
+		BN_rand(b,sizes[i],1,0);
+		BN_rand(c,sizes[i],1,1);
+		BN_mod(a,a,c,ctx);
+		BN_mod(b,b,c,ctx);
+
+		BN_MONT_CTX_set(&m,c,ctx);
+
+		Time_F(START);
+		for (k=0; k<num; k++)
+			BN_mod_exp_mont(r,a,b,c,ctx,&m);
+		tm=Time_F(STOP);
+		printf("mul %4d ^ %4d %% %d -> %8.3fms %5.1f\n",sizes[i],sizes[i],sizes[i],tm*1000.0/num,tm*mul_c[i]/num);
+		num/=7;
+		if (num <= 0) num=1;
+		}
+
+	}
+
diff --git a/AppleCSP/open_ssl/bn/exptest.c b/AppleCSP/open_ssl/bn/exptest.c
new file mode 100644
index 00000000..92ce6b00
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/exptest.c
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/exptest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#ifdef WINDOWS
+#include "../bio/bss_file.c"
+#endif
+
+#define NUM_BITS	(BN_BITS*2)
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+	{
+	BN_CTX *ctx;
+	BIO *out=NULL;
+	int i,ret;
+	unsigned char c;
+	BIGNUM *r_mont,*r_recp,*r_simple,*a,*b,*m;
+
+	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
+	                                       * even check its return value
+	                                       * (which we should) */
+
+	ERR_load_BN_strings();
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) exit(1);
+	r_mont=BN_new();
+	r_recp=BN_new();
+	r_simple=BN_new();
+	a=BN_new();
+	b=BN_new();
+	m=BN_new();
+	if (	(r_mont == NULL) || (r_recp == NULL) ||
+		(a == NULL) || (b == NULL))
+		goto err;
+
+	out=BIO_new(BIO_s_file());
+
+	if (out == NULL) exit(1);
+	BIO_set_fp(out,stdout,BIO_NOCLOSE);
+
+	for (i=0; i<200; i++)
+		{
+		RAND_bytes(&c,1);
+		c=(c%BN_BITS)-BN_BITS2;
+		BN_rand(a,NUM_BITS+c,0,0);
+
+		RAND_bytes(&c,1);
+		c=(c%BN_BITS)-BN_BITS2;
+		BN_rand(b,NUM_BITS+c,0,0);
+
+		RAND_bytes(&c,1);
+		c=(c%BN_BITS)-BN_BITS2;
+		BN_rand(m,NUM_BITS+c,0,1);
+
+		BN_mod(a,a,m,ctx);
+		BN_mod(b,b,m,ctx);
+
+		ret=BN_mod_exp_mont(r_mont,a,b,m,ctx,NULL);
+		if (ret <= 0)
+			{
+			printf("BN_mod_exp_mont() problems\n");
+			ERR_print_errors(out);
+			exit(1);
+			}
+
+		ret=BN_mod_exp_recp(r_recp,a,b,m,ctx);
+		if (ret <= 0)
+			{
+			printf("BN_mod_exp_recp() problems\n");
+			ERR_print_errors(out);
+			exit(1);
+			}
+
+		ret=BN_mod_exp_simple(r_simple,a,b,m,ctx);
+		if (ret <= 0)
+			{
+			printf("BN_mod_exp_simple() problems\n");
+			ERR_print_errors(out);
+			exit(1);
+			}
+
+		if (BN_cmp(r_simple, r_mont) == 0
+		    && BN_cmp(r_simple,r_recp) == 0)
+			{
+			printf(".");
+			fflush(stdout);
+			}
+		else
+		  	{
+			if (BN_cmp(r_simple,r_mont) != 0)
+				printf("\nsimple and mont results differ\n");
+			if (BN_cmp(r_simple,r_recp) != 0)
+				printf("\nsimple and recp results differ\n");
+
+			printf("a (%3d) = ",BN_num_bits(a));   BN_print(out,a);
+			printf("\nb (%3d) = ",BN_num_bits(b)); BN_print(out,b);
+			printf("\nm (%3d) = ",BN_num_bits(m)); BN_print(out,m);
+			printf("\nsimple   =");	BN_print(out,r_simple);
+			printf("\nrecp     =");	BN_print(out,r_recp);
+			printf("\nmont     ="); BN_print(out,r_mont);
+			printf("\n");
+			exit(1);
+			}
+		}
+	BN_free(r_mont);
+	BN_free(r_recp);
+	BN_free(r_simple);
+	BN_free(a);
+	BN_free(b);
+	BN_free(m);
+	BN_CTX_free(ctx);
+	ERR_remove_state(0);
+	CRYPTO_mem_leaks(out);
+	BIO_free(out);
+	printf(" done\n");
+	exit(0);
+err:
+	ERR_load_crypto_strings();
+	ERR_print_errors(out);
+	exit(1);
+	return(1);
+	}
+
diff --git a/AppleCSP/open_ssl/bn/vms-helper.c b/AppleCSP/open_ssl/bn/vms-helper.c
new file mode 100644
index 00000000..f0ec672a
--- /dev/null
+++ b/AppleCSP/open_ssl/bn/vms-helper.c
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+
+/* vms-helper.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+bn_div_words_abort(int i)
+{
+#if !defined(NO_STDIO) && !defined(WIN16)
+	fprintf(stderr,"Division would overflow (%d)\n",i);
+#endif
+	abort();
+}
diff --git a/AppleCSP/open_ssl/buffer/buf_err.c b/AppleCSP/open_ssl/buffer/buf_err.c
new file mode 100644
index 00000000..223547fd
--- /dev/null
+++ b/AppleCSP/open_ssl/buffer/buf_err.c
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/buffer/buf_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+
+/* BEGIN ERROR CODES */
+#ifndef NO_ERR
+static ERR_STRING_DATA BUF_str_functs[]=
+	{
+{ERR_PACK(0,BUF_F_BUF_MEM_GROW,0),	"BUF_MEM_grow"},
+{ERR_PACK(0,BUF_F_BUF_MEM_NEW,0),	"BUF_MEM_new"},
+{ERR_PACK(0,BUF_F_BUF_STRDUP,0),	"BUF_strdup"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA BUF_str_reasons[]=
+	{
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_BUF_strings(void)
+	{
+	static int init=1;
+
+	if (init)
+		{
+		init=0;
+#ifndef NO_ERR
+		ERR_load_strings(ERR_LIB_BUF,BUF_str_functs);
+		ERR_load_strings(ERR_LIB_BUF,BUF_str_reasons);
+#endif
+
+		}
+	}
diff --git a/AppleCSP/open_ssl/buffer/buffer.c b/AppleCSP/open_ssl/buffer/buffer.c
new file mode 100644
index 00000000..5fa4d11d
--- /dev/null
+++ b/AppleCSP/open_ssl/buffer/buffer.c
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/buffer/buffer.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+
+BUF_MEM *BUF_MEM_new(void)
+	{
+	BUF_MEM *ret;
+
+	ret=Malloc(sizeof(BUF_MEM));
+	if (ret == NULL)
+		{
+		BUFerr(BUF_F_BUF_MEM_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->length=0;
+	ret->max=0;
+	ret->data=NULL;
+	return(ret);
+	}
+
+void BUF_MEM_free(BUF_MEM *a)
+	{
+	if(a == NULL)
+	    return;
+
+	if (a->data != NULL)
+		{
+		memset(a->data,0,(unsigned int)a->max);
+		Free(a->data);
+		}
+	Free(a);
+	}
+
+int BUF_MEM_grow(BUF_MEM *str, int len)
+	{
+	char *ret;
+	unsigned int n;
+
+	if (str->length >= len)
+		{
+		str->length=len;
+		return(len);
+		}
+	if (str->max >= len)
+		{
+		memset(&str->data[str->length],0,len-str->length);
+		str->length=len;
+		return(len);
+		}
+	n=(len+3)/3*4;
+	if (str->data == NULL)
+		ret=Malloc(n);
+	else
+		ret=Realloc(str->data,n);
+	if (ret == NULL)
+		{
+		BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
+		len=0;
+		}
+	else
+		{
+		str->data=ret;
+		str->length=len;
+		str->max=n;
+		}
+	return(len);
+	}
+
+char *BUF_strdup(const char *str)
+	{
+	char *ret;
+	int n;
+
+	if (str == NULL) return(NULL);
+
+	n=strlen(str);
+	ret=Malloc(n+1);
+	if (ret == NULL) 
+		{
+		BUFerr(BUF_F_BUF_STRDUP,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	memcpy(ret,str,n+1);
+	return(ret);
+	}
+
diff --git a/AppleCSP/open_ssl/cryptlib.c b/AppleCSP/open_ssl/cryptlib.c
new file mode 100644
index 00000000..50255293
--- /dev/null
+++ b/AppleCSP/open_ssl/cryptlib.c
@@ -0,0 +1,350 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/cryptlib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+
+#if defined(WIN32) || defined(WIN16)
+static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
+#endif
+
+/* real #defines in crypto.h, keep these upto date */
+#if defined(LOCK_DEBUG)
+static const char* const lock_names[CRYPTO_NUM_LOCKS] =
+	{
+	"<<ERROR>>",
+	"err",
+	"err_hash",
+	"x509",
+	"x509_info",
+	"x509_pkey",
+	"x509_crl",
+	"x509_req",
+	"dsa",
+	"rsa",
+	"evp_pkey",
+	"x509_store",
+	"ssl_ctx",
+	"ssl_cert",
+	"ssl_session",
+	"ssl_sess_cert",
+	"ssl",
+	"rand",
+	"debug_malloc",
+	"BIO",
+	"gethostbyname",
+	"getservbyname",
+	"readdir",
+	"RSA_blinding",
+	"dh",
+	"debug_malloc2",
+#if CRYPTO_NUM_LOCKS != 26
+# error "Inconsistency between crypto.h and cryptlib.c"
+#endif
+	};
+#endif /*LOCK_DEBUG*/
+
+static STACK *app_locks=NULL;
+
+#if		CRYPTO_CALLBACK_ENABLE
+static void (MS_FAR *locking_callback)(int mode,int type,
+	const char *file,int line)=NULL;
+static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
+	int type,const char *file,int line)=NULL;
+static unsigned long (MS_FAR *id_callback)(void)=NULL;
+#endif	/* CRYPTO_CALLBACK_ENABLE */
+
+int CRYPTO_get_new_lockid(char *name)
+	{
+	char *str;
+	int i;
+
+	/* A hack to make Visual C++ 5.0 work correctly when linking as
+	 * a DLL using /MT. Without this, the application cannot use
+	 * and floating point printf's.
+	 * It also seems to be needed for Visual C 1.5 (win16) */
+#if defined(WIN32) || defined(WIN16)
+	SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
+#endif
+
+	if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	if ((str=BUF_strdup(name)) == NULL)
+		return(0);
+	i=sk_push(app_locks,str);
+	if (!i)
+		Free(str);
+	else
+		i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
+	return(i);
+	}
+
+int CRYPTO_num_locks(void)
+	{
+	return CRYPTO_NUM_LOCKS;
+	}
+
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+		int line)
+	{
+	#if	CRYPTO_CALLBACK_ENABLE
+	return(locking_callback);
+	#else
+	return NULL;
+	#endif
+	}
+
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+					  const char *file,int line)
+	{
+	#if	CRYPTO_CALLBACK_ENABLE
+	return(add_lock_callback);
+	#else
+	return NULL;
+	#endif
+	}
+
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
+					      const char *file,int line))
+	{
+	#if	CRYPTO_CALLBACK_ENABLE
+	locking_callback=func;
+	#endif
+	}
+
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+					      const char *file,int line))
+	{
+	#if	CRYPTO_CALLBACK_ENABLE
+	add_lock_callback=func;
+	#endif
+	}
+
+unsigned long (*CRYPTO_get_id_callback(void))(void)
+	{
+	#if	CRYPTO_CALLBACK_ENABLE
+	return(id_callback);
+	#else
+	return NULL;
+	#endif
+	}
+
+void CRYPTO_set_id_callback(unsigned long (*func)(void))
+	{
+	#if	CRYPTO_CALLBACK_ENABLE
+	id_callback=func;
+	#endif
+	}
+
+unsigned long CRYPTO_thread_id(void)
+	{
+	unsigned long ret=0;
+
+#if	CRYPTO_CALLBACK_ENABLE
+	if (id_callback == NULL)
+		{
+#ifdef WIN16
+		ret=(unsigned long)GetCurrentTask();
+#elif defined(WIN32)
+		ret=(unsigned long)GetCurrentThreadId();
+#elif defined(GETPID_IS_MEANINGLESS)
+		ret=1L;
+#else
+		ret=(unsigned long)getpid();
+#endif
+		}
+	else
+		ret=id_callback();
+#endif	/* CRYPTO_CALLBACK_ENABLE */
+	return(ret);
+	}
+
+void CRYPTO_lock(int mode, int type, const char *file, int line)
+	{
+#ifdef LOCK_DEBUG
+		{
+		char *rw_text,*operation_text;
+
+		if (mode & CRYPTO_LOCK)
+			operation_text="lock  ";
+		else if (mode & CRYPTO_UNLOCK)
+			operation_text="unlock";
+		else
+			operation_text="ERROR ";
+
+		if (mode & CRYPTO_READ)
+			rw_text="r";
+		else if (mode & CRYPTO_WRITE)
+			rw_text="w";
+		else
+			rw_text="ERROR";
+
+		fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
+			CRYPTO_thread_id(), rw_text, operation_text,
+			CRYPTO_get_lock_name(type), file, line);
+		}
+#endif
+#if	CRYPTO_CALLBACK_ENABLE
+	if (locking_callback != NULL)
+		locking_callback(mode,type,file,line);
+#endif
+	}
+
+int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
+	     int line)
+	{
+	int ret;
+#if	CRYPTO_CALLBACK_ENABLE
+	if (add_lock_callback != NULL)
+		{
+#ifdef LOCK_DEBUG
+		int before= *pointer;
+#endif
+
+		ret=add_lock_callback(pointer,amount,type,file,line);
+#ifdef LOCK_DEBUG
+		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+			CRYPTO_thread_id(),
+			before,amount,ret,
+			CRYPTO_get_lock_name(type),
+			file,line);
+#endif
+		*pointer=ret;
+		}
+	else
+#endif	/* CRYPTO_CALLBACK_ENABLE */
+		{
+		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
+
+		ret= *pointer+amount;
+#ifdef LOCK_DEBUG
+		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+			CRYPTO_thread_id(),
+			*pointer,amount,ret,
+			CRYPTO_get_lock_name(type),
+			file,line);
+#endif
+		*pointer=ret;
+		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
+		}
+	return(ret);
+	}
+
+#ifdef LOCK_DEBUG
+const char *CRYPTO_get_lock_name(int type)
+	{
+	if (type < 0)
+		return("ERROR");
+	else if (type < CRYPTO_NUM_LOCKS)
+		return(lock_names[type]);
+	else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks))
+		return("ERROR");
+	else
+		return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
+	}
+#endif /*LOCK_DEBUG*/
+
+#ifdef _DLL
+#ifdef WIN32
+
+/* All we really need to do is remove the 'error' state when a thread
+ * detaches */
+
+BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason,
+	     LPVOID lpvReserved)
+	{
+	switch(fdwReason)
+		{
+	case DLL_PROCESS_ATTACH:
+		break;
+	case DLL_THREAD_ATTACH:
+		break;
+	case DLL_THREAD_DETACH:
+		ERR_remove_state(0);
+		break;
+	case DLL_PROCESS_DETACH:
+		break;
+		}
+	return(TRUE);
+	}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/cryptlib.h b/AppleCSP/open_ssl/cryptlib.h
new file mode 100644
index 00000000..438031b3
--- /dev/null
+++ b/AppleCSP/open_ssl/cryptlib.h
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/cryptlib.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CRYPTLIB_H
+#define HEADER_CRYPTLIB_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include "openssl/e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/buffer.h> 
+#include <openssl/bio.h> 
+#include <openssl/err.h>
+#include <openssl/opensslconf.h>
+
+#ifndef VMS
+#define X509_CERT_AREA		OPENSSLDIR
+#define X509_CERT_DIR		OPENSSLDIR "/certs"
+#define X509_CERT_FILE		OPENSSLDIR "/cert.pem"
+#define X509_PRIVATE_DIR	OPENSSLDIR "/private"
+#else
+#define X509_CERT_AREA		"SSLROOT:[000000]"
+#define X509_CERT_DIR		"SSLCERTS:"
+#define X509_CERT_FILE		"SSLCERTS:cert.pem"
+#define X509_PRIVATE_DIR        "SSLPRIVATE:"
+#endif
+
+#define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
+#define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/dsa/dsa_asn1.c b/AppleCSP/open_ssl/dsa/dsa_asn1.c
new file mode 100644
index 00000000..ac46c6cb
--- /dev/null
+++ b/AppleCSP/open_ssl/dsa/dsa_asn1.c
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa_asn1.c */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dsa.h>
+#include <openssl/asn1.h>
+#ifndef	_OPENSSL_APPLE_CDSA_
+#include <openssl/asn1_mac.h>
+#endif
+
+DSA_SIG *DSA_SIG_new(void)
+{
+	DSA_SIG *ret;
+
+	ret = Malloc(sizeof(DSA_SIG));
+	if (ret == NULL)
+		{
+		DSAerr(DSA_F_DSA_SIG_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	ret->r = NULL;
+	ret->s = NULL;
+	return(ret);
+}
+
+void DSA_SIG_free(DSA_SIG *r)
+{
+	if (r == NULL) return;
+	if (r->r) BN_clear_free(r->r);
+	if (r->s) BN_clear_free(r->s);
+	Free(r);
+}
+
+#ifndef	_OPENSSL_APPLE_CDSA_
+
+int i2d_DSA_SIG(DSA_SIG *v, unsigned char **pp)
+{
+	int t=0,len;
+	ASN1_INTEGER rbs,sbs;
+	unsigned char *p;
+
+	rbs.data=Malloc(BN_num_bits(v->r)/8+1);
+	if (rbs.data == NULL)
+		{
+		DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	rbs.type=V_ASN1_INTEGER;
+	rbs.length=BN_bn2bin(v->r,rbs.data);
+	sbs.data=Malloc(BN_num_bits(v->s)/8+1);
+	if (sbs.data == NULL)
+		{
+		Free(rbs.data);
+		DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	sbs.type=V_ASN1_INTEGER;
+	sbs.length=BN_bn2bin(v->s,sbs.data);
+
+	len=i2d_ASN1_INTEGER(&rbs,NULL);
+	len+=i2d_ASN1_INTEGER(&sbs,NULL);
+
+	if (pp)
+		{
+		p=*pp;
+		ASN1_put_object(&p,1,len,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+		i2d_ASN1_INTEGER(&rbs,&p);
+		i2d_ASN1_INTEGER(&sbs,&p);
+		}
+	t=ASN1_object_size(1,len,V_ASN1_SEQUENCE);
+	Free(rbs.data);
+	Free(sbs.data);
+	return(t);
+}
+
+DSA_SIG *d2i_DSA_SIG(DSA_SIG **a, unsigned char **pp, long length)
+{
+	int i=ERR_R_NESTED_ASN1_ERROR;
+	ASN1_INTEGER *bs=NULL;
+	M_ASN1_D2I_vars(a,DSA_SIG *,DSA_SIG_new);
+
+	M_ASN1_D2I_Init();
+	M_ASN1_D2I_start_sequence();
+	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
+	if ((ret->r=BN_bin2bn(bs->data,bs->length,ret->r)) == NULL)
+		goto err_bn;
+	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
+	if ((ret->s=BN_bin2bn(bs->data,bs->length,ret->s)) == NULL)
+		goto err_bn;
+	M_ASN1_BIT_STRING_free(bs);
+	M_ASN1_D2I_Finish_2(a);
+
+err_bn:
+	i=ERR_R_BN_LIB;
+err:
+	DSAerr(DSA_F_D2I_DSA_SIG,i);
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) DSA_SIG_free(ret);
+	if (bs != NULL) M_ASN1_BIT_STRING_free(bs);
+	return(NULL);
+}
+
+#endif	/* _OPENSSL_APPLE_CDSA_ */
diff --git a/AppleCSP/open_ssl/dsa/dsa_err.c b/AppleCSP/open_ssl/dsa/dsa_err.c
new file mode 100644
index 00000000..9ddab261
--- /dev/null
+++ b/AppleCSP/open_ssl/dsa/dsa_err.c
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef NO_ERR
+static ERR_STRING_DATA DSA_str_functs[]=
+	{
+{ERR_PACK(0,DSA_F_D2I_DSA_SIG,0),	"d2i_DSA_SIG"},
+{ERR_PACK(0,DSA_F_DSAPARAMS_PRINT,0),	"DSAparams_print"},
+{ERR_PACK(0,DSA_F_DSAPARAMS_PRINT_FP,0),	"DSAparams_print_fp"},
+{ERR_PACK(0,DSA_F_DSA_DO_SIGN,0),	"DSA_do_sign"},
+{ERR_PACK(0,DSA_F_DSA_DO_VERIFY,0),	"DSA_do_verify"},
+{ERR_PACK(0,DSA_F_DSA_NEW,0),	"DSA_new"},
+{ERR_PACK(0,DSA_F_DSA_PRINT,0),	"DSA_print"},
+{ERR_PACK(0,DSA_F_DSA_PRINT_FP,0),	"DSA_print_fp"},
+{ERR_PACK(0,DSA_F_DSA_SIGN,0),	"DSA_sign"},
+{ERR_PACK(0,DSA_F_DSA_SIGN_SETUP,0),	"DSA_sign_setup"},
+{ERR_PACK(0,DSA_F_DSA_SIG_NEW,0),	"DSA_SIG_new"},
+{ERR_PACK(0,DSA_F_DSA_VERIFY,0),	"DSA_verify"},
+{ERR_PACK(0,DSA_F_I2D_DSA_SIG,0),	"i2d_DSA_SIG"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA DSA_str_reasons[]=
+	{
+{DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE       ,"data too large for key size"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_DSA_strings(void)
+	{
+	static int init=1;
+
+	if (init)
+		{
+		init=0;
+#ifndef NO_ERR
+		ERR_load_strings(ERR_LIB_DSA,DSA_str_functs);
+		ERR_load_strings(ERR_LIB_DSA,DSA_str_reasons);
+#endif
+
+		}
+	}
diff --git a/AppleCSP/open_ssl/dsa/dsa_gen.c b/AppleCSP/open_ssl/dsa/dsa_gen.c
new file mode 100644
index 00000000..951b4b80
--- /dev/null
+++ b/AppleCSP/open_ssl/dsa/dsa_gen.c
@@ -0,0 +1,312 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#undef GENUINE_DSA
+
+#ifdef GENUINE_DSA
+/* Parameter generation follows the original release of FIPS PUB 186,
+ * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
+#define HASH    SHA
+#else
+/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
+ * FIPS PUB 180-1) */
+#define HASH    SHA1 
+#endif 
+
+#ifndef NO_SHA
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/sha.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+
+DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
+		int *counter_ret, unsigned long *h_ret,
+		void (*callback)(int, int, void *),
+		void *cb_arg)
+	{
+	int ok=0;
+	unsigned char seed[SHA_DIGEST_LENGTH];
+	unsigned char md[SHA_DIGEST_LENGTH];
+	unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];
+	BIGNUM *r0,*W,*X,*c,*test;
+	BIGNUM *g=NULL,*q=NULL,*p=NULL;
+	BN_MONT_CTX *mont=NULL;
+	int k,n=0,i,b,m=0;
+	int counter=0;
+	int r=0;
+	BN_CTX *ctx=NULL,*ctx2=NULL,*ctx3=NULL;
+	unsigned int h=2;
+	DSA *ret=NULL;
+
+	if (bits < 512) bits=512;
+	bits=(bits+63)/64*64;
+
+	if (seed_len < 20)
+		seed_in = NULL; /* seed buffer too small -- ignore */
+	if (seed_len > 20) 
+		seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
+		                * but our internal buffers are restricted to 160 bits*/
+	if ((seed_in != NULL) && (seed_len == 20))
+		memcpy(seed,seed_in,seed_len);
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+	if ((ctx2=BN_CTX_new()) == NULL) goto err;
+	if ((ctx3=BN_CTX_new()) == NULL) goto err;
+	if ((ret=DSA_new()) == NULL) goto err;
+
+	if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+
+	BN_CTX_start(ctx2);
+	r0 = BN_CTX_get(ctx2);
+	g = BN_CTX_get(ctx2);
+	W = BN_CTX_get(ctx2);
+	q = BN_CTX_get(ctx2);
+	X = BN_CTX_get(ctx2);
+	c = BN_CTX_get(ctx2);
+	p = BN_CTX_get(ctx2);
+	test = BN_CTX_get(ctx2);
+
+	BN_lshift(test,BN_value_one(),bits-1);
+
+	for (;;)
+		{
+		for (;;) /* find q */
+			{
+			int seed_is_random;
+
+			/* step 1 */
+			if (callback != NULL) callback(0,m++,cb_arg);
+
+			if (!seed_len)
+				{
+				RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH);
+				seed_is_random = 1;
+				}
+			else
+				{
+				seed_is_random = 0;
+				seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
+				}
+			memcpy(buf,seed,SHA_DIGEST_LENGTH);
+			memcpy(buf2,seed,SHA_DIGEST_LENGTH);
+			/* precompute "SEED + 1" for step 7: */
+			for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+				{
+				buf[i]++;
+				if (buf[i] != 0) break;
+				}
+
+			/* step 2 */
+			HASH(seed,SHA_DIGEST_LENGTH,md);
+			HASH(buf,SHA_DIGEST_LENGTH,buf2);
+			for (i=0; i<SHA_DIGEST_LENGTH; i++)
+				md[i]^=buf2[i];
+
+			/* step 3 */
+			md[0]|=0x80;
+			md[SHA_DIGEST_LENGTH-1]|=0x01;
+			if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err;
+
+			/* step 4 */
+			r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random);
+			if (r > 0)
+				break;
+			if (r != 0)
+				goto err;
+
+			/* do a callback call */
+			/* step 5 */
+			}
+
+		if (callback != NULL) callback(2,0,cb_arg);
+		if (callback != NULL) callback(3,0,cb_arg);
+
+		/* step 6 */
+		counter=0;
+		/* "offset = 2" */
+
+		n=(bits-1)/160;
+		b=(bits-1)-n*160;
+
+		for (;;)
+			{
+			if (callback != NULL && counter != 0)
+				callback(0,counter,cb_arg);
+
+			/* step 7 */
+			BN_zero(W);
+			/* now 'buf' contains "SEED + offset - 1" */
+			for (k=0; k<=n; k++)
+				{
+				/* obtain "SEED + offset + k" by incrementing: */
+				for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+					{
+					buf[i]++;
+					if (buf[i] != 0) break;
+					}
+
+				HASH(buf,SHA_DIGEST_LENGTH,md);
+
+				/* step 8 */
+				if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0))
+					goto err;
+				BN_lshift(r0,r0,160*k);
+				BN_add(W,W,r0);
+				}
+
+			/* more of step 8 */
+			BN_mask_bits(W,bits-1);
+			BN_copy(X,W); /* this should be ok */
+			BN_add(X,X,test); /* this should be ok */
+
+			/* step 9 */
+			BN_lshift1(r0,q);
+			BN_mod(c,X,r0,ctx);
+			BN_sub(r0,c,BN_value_one());
+			BN_sub(p,X,r0);
+
+			/* step 10 */
+			if (BN_cmp(p,test) >= 0)
+				{
+				/* step 11 */
+				r = BN_is_prime_fasttest(p, DSS_prime_checks, callback, ctx3, cb_arg, 1);
+				if (r > 0)
+						goto end; /* found it */
+				if (r != 0)
+					goto err;
+				}
+
+			/* step 13 */
+			counter++;
+			/* "offset = offset + n + 1" */
+
+			/* step 14 */
+			if (counter >= 4096) break;
+			}
+		}
+end:
+	if (callback != NULL) callback(2,1,cb_arg);
+
+	/* We now need to generate g */
+	/* Set r0=(p-1)/q */
+	BN_sub(test,p,BN_value_one());
+	BN_div(r0,NULL,test,q,ctx);
+
+	BN_set_word(test,h);
+	BN_MONT_CTX_set(mont,p,ctx);
+
+	for (;;)
+		{
+		/* g=test^r0%p */
+		BN_mod_exp_mont(g,test,r0,p,ctx,mont);
+		if (!BN_is_one(g)) break;
+		BN_add(test,test,BN_value_one());
+		h++;
+		}
+
+	if (callback != NULL) callback(3,1,cb_arg);
+
+	ok=1;
+err:
+	if (!ok)
+		{
+		if (ret != NULL) DSA_free(ret);
+		}
+	else
+		{
+		ret->p=BN_dup(p);
+		ret->q=BN_dup(q);
+		ret->g=BN_dup(g);
+		if ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed,20);
+		if (counter_ret != NULL) *counter_ret=counter;
+		if (h_ret != NULL) *h_ret=h;
+		}
+	if (ctx != NULL) BN_CTX_free(ctx);
+	if (ctx2 != NULL)
+		{
+		BN_CTX_end(ctx2);
+		BN_CTX_free(ctx2);
+		}
+	if (ctx3 != NULL) BN_CTX_free(ctx3);
+	if (mont != NULL) BN_MONT_CTX_free(mont);
+	return(ok?ret:NULL);
+	}
+#endif
diff --git a/AppleCSP/open_ssl/dsa/dsa_key.c b/AppleCSP/open_ssl/dsa/dsa_key.c
new file mode 100644
index 00000000..0af87775
--- /dev/null
+++ b/AppleCSP/open_ssl/dsa/dsa_key.c
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+//#include <openssl/sha.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+
+int DSA_generate_key(DSA *dsa)
+	{
+	int ok=0;
+	unsigned int i;
+	BN_CTX *ctx=NULL;
+	BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+	if (dsa->priv_key == NULL)
+		{
+		if ((priv_key=BN_new()) == NULL) goto err;
+		}
+	else
+		priv_key=dsa->priv_key;
+
+	i=BN_num_bits(dsa->q);
+	for (;;)
+		{
+		if (!BN_rand(priv_key,i,1,0))
+			goto err;
+		if (BN_cmp(priv_key,dsa->q) >= 0)
+			BN_sub(priv_key,priv_key,dsa->q);
+		if (!BN_is_zero(priv_key)) break;
+		}
+
+	if (dsa->pub_key == NULL)
+		{
+		if ((pub_key=BN_new()) == NULL) goto err;
+		}
+	else
+		pub_key=dsa->pub_key;
+
+	if (!BN_mod_exp(pub_key,dsa->g,priv_key,dsa->p,ctx)) goto err;
+
+	dsa->priv_key=priv_key;
+	dsa->pub_key=pub_key;
+	ok=1;
+
+err:
+	if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key);
+	if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key);
+	if (ctx != NULL) BN_CTX_free(ctx);
+	return(ok);
+	}
diff --git a/AppleCSP/open_ssl/dsa/dsa_lib.c b/AppleCSP/open_ssl/dsa/dsa_lib.c
new file mode 100644
index 00000000..aad0f5e5
--- /dev/null
+++ b/AppleCSP/open_ssl/dsa/dsa_lib.c
@@ -0,0 +1,266 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/asn1.h>
+
+const char *DSA_version="DSA" OPENSSL_VERSION_PTEXT;
+
+static const DSA_METHOD *default_DSA_method;
+static int dsa_meth_num = 0;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *dsa_meth = NULL;
+
+void DSA_set_default_method(const DSA_METHOD *meth)
+{
+	default_DSA_method = meth;
+}
+
+const DSA_METHOD *DSA_get_default_method(void)
+{
+	if(!default_DSA_method) default_DSA_method = DSA_OpenSSL();
+	return default_DSA_method;
+}
+
+DSA *DSA_new(void)
+{
+	return DSA_new_method(NULL);
+}
+
+const DSA_METHOD *DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
+{
+        const DSA_METHOD *mtmp;
+        mtmp = dsa->meth;
+        if (mtmp->finish) mtmp->finish(dsa);
+        dsa->meth = meth;
+        if (meth->init) meth->init(dsa);
+        return mtmp;
+}
+
+
+DSA *DSA_new_method(const DSA_METHOD *meth)
+	{
+	DSA *ret;
+
+	ret=(DSA *)Malloc(sizeof(DSA));
+	if (ret == NULL)
+		{
+		DSAerr(DSA_F_DSA_NEW,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	if(!default_DSA_method) default_DSA_method = DSA_OpenSSL();
+	if(meth) ret->meth = meth;
+	else ret->meth = default_DSA_method;
+	ret->pad=0;
+	ret->version=0;
+	ret->write_params=1;
+	ret->p=NULL;
+	ret->q=NULL;
+	ret->g=NULL;
+
+	ret->pub_key=NULL;
+	ret->priv_key=NULL;
+
+	ret->kinv=NULL;
+	ret->r=NULL;
+	ret->method_mont_p=NULL;
+
+	ret->references=1;
+	ret->flags=ret->meth->flags;
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+		Free(ret);
+		ret=NULL;
+		}
+	else
+		CRYPTO_new_ex_data(dsa_meth,ret,&ret->ex_data);
+	
+	return(ret);
+	}
+
+void DSA_free(DSA *r)
+	{
+	int i;
+
+	if (r == NULL) return;
+
+	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_DSA);
+#ifdef REF_PRINT
+	REF_PRINT("DSA",r);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"DSA_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	CRYPTO_free_ex_data(dsa_meth, r, &r->ex_data);
+
+	if(r->meth->finish) r->meth->finish(r);
+
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->g != NULL) BN_clear_free(r->g);
+	if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+	if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+	if (r->kinv != NULL) BN_clear_free(r->kinv);
+	if (r->r != NULL) BN_clear_free(r->r);
+	Free(r);
+	}
+
+#ifndef	_OPENSSL_APPLE_CDSA_
+int DSA_size(DSA *r)
+	{
+	int ret,i;
+	ASN1_INTEGER bs;
+	unsigned char buf[4];
+
+	i=BN_num_bits(r->q);
+	bs.length=(i+7)/8;
+	bs.data=buf;
+	bs.type=V_ASN1_INTEGER;
+	/* If the top bit is set the asn1 encoding is 1 larger. */
+	buf[0]=0xff;	
+
+	i=i2d_ASN1_INTEGER(&bs,NULL);
+	i+=i; /* r and s */
+	ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
+	return(ret);
+	}
+#endif	/* _OPENSSL_APPLE_CDSA_ */
+
+int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	dsa_meth_num++;
+	return(CRYPTO_get_ex_new_index(dsa_meth_num-1,
+		&dsa_meth,argl,argp,new_func,dup_func,free_func));
+        }
+
+int DSA_set_ex_data(DSA *d, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&d->ex_data,idx,arg));
+	}
+
+void *DSA_get_ex_data(DSA *d, int idx)
+	{
+	return(CRYPTO_get_ex_data(&d->ex_data,idx));
+	}
+
+#ifndef NO_DH
+DH *DSA_dup_DH(DSA *r)
+	{
+	/* DSA has p, q, g, optional pub_key, optional priv_key.
+	 * DH has p, optional length, g, optional pub_key, optional priv_key.
+	 */ 
+
+	DH *ret = NULL;
+
+	if (r == NULL)
+		goto err;
+	ret = DH_new();
+	if (ret == NULL)
+		goto err;
+	if (r->p != NULL) 
+		if ((ret->p = BN_dup(r->p)) == NULL)
+			goto err;
+	if (r->q != NULL)
+		ret->length = BN_num_bits(r->q);
+	if (r->g != NULL)
+		if ((ret->g = BN_dup(r->g)) == NULL)
+			goto err;
+	if (r->pub_key != NULL)
+		if ((ret->pub_key = BN_dup(r->pub_key)) == NULL)
+			goto err;
+	if (r->priv_key != NULL)
+		if ((ret->priv_key = BN_dup(r->priv_key)) == NULL)
+			goto err;
+
+	return ret;
+
+ err:
+	if (ret != NULL)
+		DH_free(ret);
+	return NULL;
+	}
+#endif
diff --git a/AppleCSP/open_ssl/dsa/dsa_ossl.c b/AppleCSP/open_ssl/dsa/dsa_ossl.c
new file mode 100644
index 00000000..aae23451
--- /dev/null
+++ b/AppleCSP/open_ssl/dsa/dsa_ossl.c
@@ -0,0 +1,339 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa_ossl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/asn1.h>
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+		  DSA *dsa);
+static int dsa_init(DSA *dsa);
+static int dsa_finish(DSA *dsa);
+static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+		BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *in_mont);
+static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+				const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx);
+
+static const DSA_METHOD openssl_dsa_meth = {
+"OpenSSL DSA method",
+dsa_do_sign,
+dsa_sign_setup,
+dsa_do_verify,
+dsa_mod_exp,
+dsa_bn_mod_exp,
+dsa_init,
+dsa_finish,
+0,
+NULL
+};
+
+const DSA_METHOD *DSA_OpenSSL(void)
+{
+	return &openssl_dsa_meth;
+}
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+	{
+	BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
+	BIGNUM m;
+	BIGNUM xr;
+	BN_CTX *ctx=NULL;
+	int i,reason=ERR_R_BN_LIB;
+	DSA_SIG *ret=NULL;
+
+	BN_init(&m);
+	BN_init(&xr);
+	s=BN_new();
+	if (s == NULL) goto err;
+
+	i=BN_num_bytes(dsa->q); /* should be 20 */
+	if ((dlen > i) || (dlen > 50))
+		{
+		reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
+		goto err;
+		}
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+
+	if ((dsa->kinv == NULL) || (dsa->r == NULL))
+		{
+		if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
+		}
+	else
+		{
+		kinv=dsa->kinv;
+		dsa->kinv=NULL;
+		r=dsa->r;
+		dsa->r=NULL;
+		}
+
+	if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
+
+	/* Compute  s = inv(k) (m + xr) mod q */
+	if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
+	if (!BN_add(s, &xr, &m)) goto err;		/* s = m + xr */
+	if (BN_cmp(s,dsa->q) > 0)
+		BN_sub(s,s,dsa->q);
+	if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
+
+	ret=DSA_SIG_new();
+	if (ret == NULL) goto err;
+	ret->r = r;
+	ret->s = s;
+	
+err:
+	if (!ret)
+		{
+		DSAerr(DSA_F_DSA_DO_SIGN,reason);
+		BN_free(r);
+		BN_free(s);
+		}
+	if (ctx != NULL) BN_CTX_free(ctx);
+	BN_clear_free(&m);
+	BN_clear_free(&xr);
+	if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
+	    BN_clear_free(kinv);
+	return(ret);
+	}
+
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+	{
+	BN_CTX *ctx;
+	BIGNUM k,*kinv=NULL,*r=NULL;
+	int ret=0;
+
+	if (ctx_in == NULL)
+		{
+		if ((ctx=BN_CTX_new()) == NULL) goto err;
+		}
+	else
+		ctx=ctx_in;
+
+	BN_init(&k);
+	if ((r=BN_new()) == NULL) goto err;
+	kinv=NULL;
+
+	/* Get random k */
+	for (;;)
+		{
+		if (!BN_rand(&k, BN_num_bits(dsa->q), 1, 0)) goto err;
+		if (BN_cmp(&k,dsa->q) >= 0)
+			BN_sub(&k,&k,dsa->q);
+		if (!BN_is_zero(&k)) break;
+		}
+
+	if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+		{
+		if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
+			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
+				dsa->p,ctx)) goto err;
+		}
+
+	/* Compute r = (g^k mod p) mod q */
+	if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
+		(BN_MONT_CTX *)dsa->method_mont_p)) goto err;
+	if (!BN_mod(r,r,dsa->q,ctx)) goto err;
+
+	/* Compute  part of 's = inv(k) (m + xr) mod q' */
+	if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
+
+	if (*kinvp != NULL) BN_clear_free(*kinvp);
+	*kinvp=kinv;
+	kinv=NULL;
+	if (*rp != NULL) BN_clear_free(*rp);
+	*rp=r;
+	ret=1;
+err:
+	if (!ret)
+		{
+		DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
+		if (kinv != NULL) BN_clear_free(kinv);
+		if (r != NULL) BN_clear_free(r);
+		}
+	if (ctx_in == NULL) BN_CTX_free(ctx);
+	if (kinv != NULL) BN_clear_free(kinv);
+	BN_clear_free(&k);
+	return(ret);
+	}
+
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+		  DSA *dsa)
+	{
+	BN_CTX *ctx;
+	BIGNUM u1,u2,t1;
+	BN_MONT_CTX *mont=NULL;
+	int ret = -1;
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+	BN_init(&u1);
+	BN_init(&u2);
+	BN_init(&t1);
+
+	/* Calculate W = inv(S) mod Q
+	 * save W in u2 */
+	if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
+
+	/* save M in u1 */
+	if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
+
+	/* u1 = M * w mod q */
+	if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
+
+	/* u2 = r * w mod q */
+	if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
+
+	if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+		{
+		if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
+			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
+				dsa->p,ctx)) goto err;
+		}
+	mont=(BN_MONT_CTX *)dsa->method_mont_p;
+
+#if 0
+	{
+	BIGNUM t2;
+
+	BN_init(&t2);
+	/* v = ( g^u1 * y^u2 mod p ) mod q */
+	/* let t1 = g ^ u1 mod p */
+	if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err;
+	/* let t2 = y ^ u2 mod p */
+	if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err;
+	/* let u1 = t1 * t2 mod p */
+	if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn;
+	BN_free(&t2);
+	}
+	/* let u1 = u1 mod q */
+	if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err;
+#else
+	{
+	if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2,
+						dsa->p,ctx,mont)) goto err;
+	/* BN_copy(&u1,&t1); */
+	/* let u1 = u1 mod q */
+	if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
+	}
+#endif
+	/* V is now in u1.  If the signature is correct, it will be
+	 * equal to R. */
+	ret=(BN_ucmp(&u1, sig->r) == 0);
+
+	err:
+	if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
+	if (ctx != NULL) BN_CTX_free(ctx);
+	BN_free(&u1);
+	BN_free(&u2);
+	BN_free(&t1);
+	return(ret);
+	}
+
+static int dsa_init(DSA *dsa)
+{
+	dsa->flags|=DSA_FLAG_CACHE_MONT_P;
+	return(1);
+}
+
+static int dsa_finish(DSA *dsa)
+{
+	if(dsa->method_mont_p)
+		BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p);
+	return(1);
+}
+
+static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+		BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+		BN_MONT_CTX *in_mont)
+{
+	return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont);
+}
+	
+static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+				const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx)
+{
+	return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
+}
diff --git a/AppleCSP/open_ssl/dsa/dsa_sign.c b/AppleCSP/open_ssl/dsa/dsa_sign.c
new file mode 100644
index 00000000..e4d62a79
--- /dev/null
+++ b/AppleCSP/open_ssl/dsa/dsa_sign.c
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa_sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/asn1.h>
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+	{
+	return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
+	}
+
+#ifndef	_OPENSSL_APPLE_CDSA_
+int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+	     unsigned int *siglen, DSA *dsa)
+	{
+	DSA_SIG *s;
+	s=DSA_do_sign(dgst,dlen,dsa);
+	if (s == NULL)
+		{
+		*siglen=0;
+		return(0);
+		}
+	*siglen=i2d_DSA_SIG(s,&sig);
+	DSA_SIG_free(s);
+	return(1);
+	}
+#endif	/* _OPENSSL_APPLE_CDSA_ */
+
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+	{
+	return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
+	}
+
diff --git a/AppleCSP/open_ssl/dsa/dsa_vrf.c b/AppleCSP/open_ssl/dsa/dsa_vrf.c
new file mode 100644
index 00000000..1ed605b7
--- /dev/null
+++ b/AppleCSP/open_ssl/dsa/dsa_vrf.c
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa_vrf.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/asn1.h>
+//#include <openssl/asn1_mac.h>
+
+int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+		  DSA *dsa)
+	{
+	return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+	}
+
+/* data has already been hashed (probably with SHA or SHA-1). */
+/* returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+#ifndef	_OPENSSL_APPLE_CDSA_
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+	     unsigned char *sigbuf, int siglen, DSA *dsa)
+	{
+	DSA_SIG *s;
+	int ret=-1;
+
+	s = DSA_SIG_new();
+	if (s == NULL) return(ret);
+	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+	ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+err:
+	DSA_SIG_free(s);
+	return(ret);
+	}
+#endif	/* _OPENSSL_APPLE_CDSA_ */
diff --git a/AppleCSP/open_ssl/err/err.c b/AppleCSP/open_ssl/err/err.c
new file mode 100644
index 00000000..32325ca1
--- /dev/null
+++ b/AppleCSP/open_ssl/err/err.c
@@ -0,0 +1,781 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/err/err.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+
+static LHASH *error_hash=NULL;
+static LHASH *thread_hash=NULL;
+
+static unsigned long err_hash(ERR_STRING_DATA *a);
+static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b);
+static unsigned long pid_hash(ERR_STATE *pid);
+static int pid_cmp(ERR_STATE *a,ERR_STATE *pid);
+static unsigned long get_error_values(int inc,const char **file,int *line,
+				      const char **data,int *flags);
+static void ERR_STATE_free(ERR_STATE *s);
+#ifndef NO_ERR
+static ERR_STRING_DATA ERR_str_libraries[]=
+	{
+{ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
+{ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
+{ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
+{ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
+{ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
+{ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
+{ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
+{ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
+{ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
+{ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
+{ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
+{ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
+{ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
+{ERR_PACK(ERR_LIB_METH,0,0)		,"X509 lookup 'method' routines"},
+{ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
+{ERR_PACK(ERR_LIB_RSAREF,0,0)		,"RSAref routines"},
+{ERR_PACK(ERR_LIB_PROXY,0,0)		,"Proxy routines"},
+{ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
+{ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
+{ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
+{ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
+{ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
+{0,NULL},
+	};
+
+static ERR_STRING_DATA ERR_str_functs[]=
+	{
+	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
+	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
+	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
+	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"}, 
+	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
+	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
+	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
+	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
+#ifdef WINDOWS
+	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
+#endif
+	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
+	{0,NULL},
+	};
+
+static ERR_STRING_DATA ERR_str_reasons[]=
+	{
+{ERR_R_FATAL                             ,"fatal"},
+{ERR_R_SYS_LIB				,"system lib"},
+{ERR_R_BN_LIB				,"BN lib"},
+{ERR_R_RSA_LIB				,"RSA lib"},
+{ERR_R_DH_LIB				,"DH lib"},
+{ERR_R_EVP_LIB				,"EVP lib"},
+{ERR_R_BUF_LIB				,"BUF lib"},
+{ERR_R_BIO_LIB				,"BIO lib"},
+{ERR_R_OBJ_LIB				,"OBJ lib"},
+{ERR_R_PEM_LIB				,"PEM lib"},
+{ERR_R_X509_LIB				,"X509 lib"},
+{ERR_R_METH_LIB				,"METH lib"},
+{ERR_R_ASN1_LIB				,"ASN1 lib"},
+{ERR_R_CONF_LIB				,"CONF lib"},
+{ERR_R_SSL_LIB				,"SSL lib"},
+{ERR_R_PROXY_LIB			,"PROXY lib"},
+{ERR_R_BIO_LIB				,"BIO lib"},
+{ERR_R_PKCS7_LIB			,"PKCS7 lib"},
+{ERR_R_PKCS12_LIB			,"PKCS12 lib"},
+{ERR_R_MALLOC_FAILURE			,"Malloc failure"},
+{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
+{ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
+{ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
+{ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
+{ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
+{ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
+{ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
+{ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
+
+{0,NULL},
+	};
+
+
+#define NUM_SYS_STR_REASONS 127
+#define LEN_SYS_STR_REASON 32
+
+static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
+/* SYS_str_reasons is filled with copies of strerror() results at
+ * initialization.
+ * 'errno' values up to 127 should cover all usual errors,
+ * others will be displayed numerically by ERR_error_string.
+ * It is crucial that we have something for each reason code
+ * that occurs in ERR_str_reasons, or bogus reason strings
+ * will be returned for SYSerr(), which always gets an errno
+ * value and never one of those 'standard' reason codes. */
+
+static void build_SYS_str_reasons()
+	{
+	/* Malloc cannot be used here, use static storage instead */
+	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
+	int i;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
+
+	for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
+		{
+		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
+
+		str->error = (unsigned long)i;
+		if (str->string == NULL)
+			{
+			char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
+			char *src = strerror(i);
+			if (src != NULL)
+				{
+				strncpy(*dest, src, sizeof *dest);
+				(*dest)[sizeof *dest - 1] = '\0';
+				str->string = *dest;
+				}
+			}
+		if (str->string == NULL)
+			str->string = "unknown";
+		}
+
+	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
+	 * as required by ERR_load_strings. */
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
+	}
+#endif
+
+#define err_clear_data(p,i) \
+	if (((p)->err_data[i] != NULL) && \
+		(p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
+		{  \
+		Free((p)->err_data[i]); \
+		(p)->err_data[i]=NULL; \
+		} \
+	(p)->err_data_flags[i]=0;
+
+static void ERR_STATE_free(ERR_STATE *s)
+	{
+	int i;
+
+	if(s == NULL)
+	    return;
+
+	for (i=0; i<ERR_NUM_ERRORS; i++)
+		{
+		err_clear_data(s,i);
+		}
+	Free(s);
+	}
+
+void ERR_load_ERR_strings(void)
+	{
+	static int init=1;
+
+	if (init)
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+		if (init == 0)
+			{
+			CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+			return;
+			}
+		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+#ifndef NO_ERR
+		ERR_load_strings(0,ERR_str_libraries);
+		ERR_load_strings(0,ERR_str_reasons);
+		ERR_load_strings(ERR_LIB_SYS,ERR_str_functs);
+		build_SYS_str_reasons();
+		ERR_load_strings(ERR_LIB_SYS,SYS_str_reasons);
+#endif
+		init=0;
+		}
+	}
+
+void ERR_load_strings(int lib, ERR_STRING_DATA *str)
+	{
+	if (error_hash == NULL)
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
+		error_hash=lh_new(err_hash,err_cmp);
+		if (error_hash == NULL)
+			{
+			CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
+			return;
+			}
+		CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
+
+		ERR_load_ERR_strings();
+		}
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
+	while (str->error)
+		{
+		str->error|=ERR_PACK(lib,0,0);
+		lh_insert(error_hash,str);
+		str++;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
+	}
+
+void ERR_free_strings(void)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+
+	if (error_hash != NULL)
+		{
+		lh_free(error_hash);
+		error_hash=NULL;
+		}
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	}
+
+/********************************************************/
+
+void ERR_put_error(int lib, int func, int reason, const char *file,
+	     int line)
+	{
+	ERR_STATE *es;
+
+#ifdef _OSD_POSIX
+	/* In the BS2000-OSD POSIX subsystem, the compiler generates
+	 * path names in the form "*POSIX(/etc/passwd)".
+	 * This dirty hack strips them to something sensible.
+	 * @@@ We shouldn't modify a const string, though.
+	 */
+	if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
+		char *end;
+
+		/* Skip the "*POSIX(" prefix */
+		file += sizeof("*POSIX(")-1;
+		end = &file[strlen(file)-1];
+		if (*end == ')')
+			*end = '\0';
+		/* Optional: use the basename of the path only. */
+		if ((end = strrchr(file, '/')) != NULL)
+			file = &end[1];
+	}
+#endif
+	es=ERR_get_state();
+
+	es->top=(es->top+1)%ERR_NUM_ERRORS;
+	if (es->top == es->bottom)
+		es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
+	es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
+	es->err_file[es->top]=file;
+	es->err_line[es->top]=line;
+	err_clear_data(es,es->top);
+	}
+
+void ERR_clear_error(void)
+	{
+	ERR_STATE *es;
+
+	es=ERR_get_state();
+
+#if 0
+	/* hmm... is this needed */
+	for (i=0; i<ERR_NUM_ERRORS; i++)
+		{
+		es->err_buffer[i]=0;
+		es->err_file[i]=NULL;
+		es->err_line[i]= -1;
+		err_clear_data(es,i);
+		}
+#endif
+	es->top=es->bottom=0;
+	}
+
+
+unsigned long ERR_get_error(void)
+	{ return(get_error_values(1,NULL,NULL,NULL,NULL)); }
+
+unsigned long ERR_get_error_line(const char **file,
+	     int *line)
+	{ return(get_error_values(1,file,line,NULL,NULL)); }
+
+unsigned long ERR_get_error_line_data(const char **file, int *line,
+	     const char **data, int *flags)
+	{ return(get_error_values(1,file,line,
+	     data,flags)); }
+
+unsigned long ERR_peek_error(void)
+	{ return(get_error_values(0,NULL,NULL,NULL,NULL)); }
+
+unsigned long ERR_peek_error_line(const char **file,
+	     int *line)
+	{ return(get_error_values(0,file,line,NULL,NULL)); }
+
+unsigned long ERR_peek_error_line_data(const char **file, int *line,
+	     const char **data, int *flags)
+	{ return(get_error_values(0,file,line,
+	     data,flags)); }
+
+static unsigned long get_error_values(int inc, const char **file, int *line,
+	     const char **data, int *flags)
+	{	
+	int i=0;
+	ERR_STATE *es;
+	unsigned long ret;
+
+	es=ERR_get_state();
+
+	if (es->bottom == es->top) return(0);
+	i=(es->bottom+1)%ERR_NUM_ERRORS;
+
+	ret=es->err_buffer[i];
+	if (inc)
+		{
+		es->bottom=i;
+		es->err_buffer[i]=0;
+		}
+
+	if ((file != NULL) && (line != NULL))
+		{
+		if (es->err_file[i] == NULL)
+			{
+			*file="NA";
+			if (line != NULL) *line=0;
+			}
+		else
+			{
+			*file=es->err_file[i];
+			if (line != NULL) *line=es->err_line[i];
+			}
+		}
+
+	if (data != NULL)
+		{
+		if (es->err_data[i] == NULL)
+			{
+			*data="";
+			if (flags != NULL) *flags=0;
+			}
+		else
+			{
+			*data=es->err_data[i];
+			if (flags != NULL) *flags=es->err_data_flags[i];
+			}
+		}
+	return(ret);
+	}
+
+/* BAD for multi-threaded, uses a local buffer if ret == NULL */
+char *ERR_error_string(unsigned long e, char *ret)
+	{
+	#ifdef	NO_ERR
+	if(ret != NULL) {
+		strcpy(ret, "No Error String Info.");
+	}
+	return "No Error String info.";
+	#else
+	static char buf[256];
+	const char *ls,*fs,*rs;
+	unsigned long l,f,r;
+	int i;
+
+	l=ERR_GET_LIB(e);
+	f=ERR_GET_FUNC(e);
+	r=ERR_GET_REASON(e);
+
+	ls=ERR_lib_error_string(e);
+	fs=ERR_func_error_string(e);
+	rs=ERR_reason_error_string(e);
+
+	if (ret == NULL) ret=buf;
+
+	sprintf(&(ret[0]),"error:%08lX:",e);
+	i=strlen(ret);
+	if (ls == NULL)
+		sprintf(&(ret[i]),":lib(%lu) ",l);
+	else	sprintf(&(ret[i]),"%s",ls);
+	i=strlen(ret);
+	if (fs == NULL)
+		sprintf(&(ret[i]),":func(%lu) ",f);
+	else	sprintf(&(ret[i]),":%s",fs);
+	i=strlen(ret);
+	if (rs == NULL)
+		sprintf(&(ret[i]),":reason(%lu)",r);
+	else	sprintf(&(ret[i]),":%s",rs);
+
+	return(ret);
+	#endif
+	}
+
+LHASH *ERR_get_string_table(void)
+	{
+	return(error_hash);
+	}
+
+LHASH *ERR_get_err_state_table(void)
+	{
+	return(thread_hash);
+	}
+
+const char *ERR_lib_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p=NULL;
+	unsigned long l;
+
+	l=ERR_GET_LIB(e);
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH);
+
+	if (error_hash != NULL)
+		{
+		d.error=ERR_PACK(l,0,0);
+		p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d);
+		}
+
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH);
+
+	return((p == NULL)?NULL:p->string);
+	}
+
+const char *ERR_func_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p=NULL;
+	unsigned long l,f;
+
+	l=ERR_GET_LIB(e);
+	f=ERR_GET_FUNC(e);
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH);
+
+	if (error_hash != NULL)
+		{
+		d.error=ERR_PACK(l,f,0);
+		p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d);
+		}
+
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH);
+
+	return((p == NULL)?NULL:p->string);
+	}
+
+const char *ERR_reason_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p=NULL;
+	unsigned long l,r;
+
+	l=ERR_GET_LIB(e);
+	r=ERR_GET_REASON(e);
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH);
+
+	if (error_hash != NULL)
+		{
+		d.error=ERR_PACK(l,0,r);
+		p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d);
+		if (p == NULL)
+			{
+			d.error=ERR_PACK(0,0,r);
+			p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d);
+			}
+		}
+
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH);
+
+	return((p == NULL)?NULL:p->string);
+	}
+
+static unsigned long err_hash(ERR_STRING_DATA *a)
+	{
+	unsigned long ret,l;
+
+	l=a->error;
+	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
+	return(ret^ret%19*13);
+	}
+
+static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b)
+	{
+	return((int)(a->error-b->error));
+	}
+
+static unsigned long pid_hash(ERR_STATE *a)
+	{
+	return(a->pid*13);
+	}
+
+static int pid_cmp(ERR_STATE *a, ERR_STATE *b)
+	{
+	return((int)((long)a->pid - (long)b->pid));
+	}
+
+void ERR_remove_state(unsigned long pid)
+	{
+	ERR_STATE *p,tmp;
+
+	if (thread_hash == NULL)
+		return;
+	if (pid == 0)
+		pid=(unsigned long)CRYPTO_thread_id();
+	tmp.pid=pid;
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p=(ERR_STATE *)lh_delete(thread_hash,&tmp);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	if (p != NULL) ERR_STATE_free(p);
+	}
+
+static ERR_STATE *fallback = NULL;
+static ERR_STATE *getFallback()
+{
+	if(fallback == NULL) {
+		fallback = (ERR_STATE *)Malloc(sizeof(ERR_STATE));
+	}
+	return fallback;
+}
+
+ERR_STATE *ERR_get_state(void)
+	{
+	ERR_STATE *ret=NULL,tmp,*tmpp;
+	int i;
+	unsigned long pid;
+
+	pid=(unsigned long)CRYPTO_thread_id();
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	if (thread_hash == NULL)
+		{
+		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+		CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+		if (thread_hash == NULL)
+			{
+			MemCheck_off();
+			thread_hash=lh_new(pid_hash,pid_cmp);
+			MemCheck_on();
+			CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+			if (thread_hash == NULL) return(getFallback());
+			}
+		else
+			CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+		}
+	else
+		{
+		tmp.pid=pid;
+		ret=(ERR_STATE *)lh_retrieve(thread_hash,&tmp);
+		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+		}
+
+	/* ret == the error state, if NULL, make a new one */
+	if (ret == NULL)
+		{
+		ret=(ERR_STATE *)Malloc(sizeof(ERR_STATE));
+		if (ret == NULL) return(getFallback());
+		ret->pid=pid;
+		ret->top=0;
+		ret->bottom=0;
+		for (i=0; i<ERR_NUM_ERRORS; i++)
+			{
+			ret->err_data[i]=NULL;
+			ret->err_data_flags[i]=0;
+			}
+		CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+		tmpp=(ERR_STATE *)lh_insert(thread_hash,ret);
+		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+		if (tmpp != NULL) /* old entry - should not happen */
+			{
+			ERR_STATE_free(tmpp);
+			}
+		}
+	return(ret);
+	}
+
+int ERR_get_next_error_library(void)
+	{
+	static int value=ERR_LIB_USER;
+
+	return(value++);
+	}
+
+void ERR_set_error_data(char *data, int flags)
+	{
+	ERR_STATE *es;
+	int i;
+
+	es=ERR_get_state();
+
+	i=es->top;
+	if (i == 0)
+		i=ERR_NUM_ERRORS-1;
+
+	es->err_data[i]=data;
+	es->err_data_flags[es->top]=flags;
+	}
+
+void ERR_add_error_data(int num, ...)
+	{
+	va_list args;
+	int i,n,s;
+	char *str,*p,*a;
+
+	s=64;
+	str=Malloc(s+1);
+	if (str == NULL) return;
+	str[0]='\0';
+
+	va_start(args, num);
+	n=0;
+	for (i=0; i<num; i++)
+		{
+		a=va_arg(args, char*);
+		/* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
+		if (a != NULL)
+			{
+			n+=strlen(a);
+			if (n > s)
+				{
+				s=n+20;
+				p=Realloc(str,s+1);
+				if (p == NULL)
+					{
+					Free(str);
+					return;
+					}
+				else
+					str=p;
+				}
+			strcat(str,a);
+			}
+		}
+	ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
+
+	va_end(args);
+	}
+
diff --git a/AppleCSP/open_ssl/err/err_prn.c b/AppleCSP/open_ssl/err/err_prn.c
new file mode 100644
index 00000000..a878c75f
--- /dev/null
+++ b/AppleCSP/open_ssl/err/err_prn.c
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/err/err_prn.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+#ifndef NO_FP_API
+void ERR_print_errors_fp(FILE *fp)
+	{
+	unsigned long l;
+	char buf[200];
+	const char *file,*data;
+	int line,flags;
+	unsigned long es;
+
+	es=CRYPTO_thread_id();
+	while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
+		{
+		fprintf(fp,"%lu:%s:%s:%d:%s\n",es,ERR_error_string(l,buf),
+			file,line,(flags&ERR_TXT_STRING)?data:"");
+		}
+	}
+#endif
+
+void ERR_print_errors(BIO *bp)
+	{
+	unsigned long l;
+	char buf[256];
+	char buf2[256];
+	const char *file,*data;
+	int line,flags;
+	unsigned long es;
+
+	es=CRYPTO_thread_id();
+	while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
+		{
+		sprintf(buf2,"%lu:%s:%s:%d:",es,ERR_error_string(l,buf),
+			file,line);
+		BIO_write(bp,buf2,strlen(buf2));
+		if (flags & ERR_TXT_STRING)
+			BIO_write(bp,data,strlen(data));
+		BIO_write(bp,"\n",1);
+		}
+	}
+
diff --git a/AppleCSP/open_ssl/ex_data.c b/AppleCSP/open_ssl/ex_data.c
new file mode 100644
index 00000000..faadeea2
--- /dev/null
+++ b/AppleCSP/open_ssl/ex_data.c
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/ex_data.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+#include "cryptlib.h"
+
+int CRYPTO_get_ex_new_index(int idx, STACK_OF(CRYPTO_EX_DATA_FUNCS) **skp, long argl, void *argp,
+	     CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+	{
+	int ret= -1;
+	CRYPTO_EX_DATA_FUNCS *a;
+
+	MemCheck_off();
+	if (*skp == NULL)
+		*skp=sk_CRYPTO_EX_DATA_FUNCS_new_null();
+	if (*skp == NULL)
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	a=(CRYPTO_EX_DATA_FUNCS *)Malloc(sizeof(CRYPTO_EX_DATA_FUNCS));
+	if (a == NULL)
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	a->argl=argl;
+	a->argp=argp;
+	a->new_func=new_func;
+	a->dup_func=dup_func;
+	a->free_func=free_func;
+	while (sk_CRYPTO_EX_DATA_FUNCS_num(*skp) <= idx)
+		{
+		if (!sk_CRYPTO_EX_DATA_FUNCS_push(*skp,NULL))
+			{
+			CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX,ERR_R_MALLOC_FAILURE);
+			Free(a);
+			goto err;
+			}
+		}
+	sk_CRYPTO_EX_DATA_FUNCS_set(*skp,idx, a);
+	ret=idx;
+err:
+	MemCheck_on();
+	return(idx);
+	}
+
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
+	{
+	int i;
+
+	if (ad->sk == NULL)
+		{
+		if ((ad->sk=sk_new_null()) == NULL)
+			{
+			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		}
+	i=sk_num(ad->sk);
+
+	while (i <= idx)
+		{
+		if (!sk_push(ad->sk,NULL))
+			{
+			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		i++;
+		}
+	sk_set(ad->sk,idx,val);
+	return(1);
+	}
+
+void *CRYPTO_get_ex_data(CRYPTO_EX_DATA *ad, int idx)
+	{
+	if (ad->sk == NULL)
+		return(0);
+	else if (idx >= sk_num(ad->sk))
+		return(0);
+	else
+		return(sk_value(ad->sk,idx));
+	}
+
+/* The callback is called with the 'object', which is the original data object
+ * being duplicated, a pointer to the
+ * 'new' object to be inserted, the index, and the argi/argp
+ */
+int CRYPTO_dup_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, CRYPTO_EX_DATA *to,
+	     CRYPTO_EX_DATA *from)
+	{
+	int i,j,m,r;
+	CRYPTO_EX_DATA_FUNCS *mm;
+	char *from_d;
+
+	if (meth == NULL) return(1);
+	if (from->sk == NULL) return(1);
+	m=sk_CRYPTO_EX_DATA_FUNCS_num(meth);
+	j=sk_num(from->sk);
+	for (i=0; i<j; i++)
+		{
+		from_d=CRYPTO_get_ex_data(from,i);
+		if (i < m)
+			{
+			mm=sk_CRYPTO_EX_DATA_FUNCS_value(meth,i);
+			if (mm->dup_func != NULL)
+				r=mm->dup_func(to,from,(char **)&from_d,i,
+					mm->argl,mm->argp);
+			}
+		CRYPTO_set_ex_data(to,i,from_d);
+		}
+	return(1);
+	}
+
+/* Call each free callback */
+void CRYPTO_free_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, void *obj, CRYPTO_EX_DATA *ad)
+	{
+	CRYPTO_EX_DATA_FUNCS *m;
+	void *ptr;
+	int i,max;
+
+	if (meth != NULL)
+		{
+		max=sk_CRYPTO_EX_DATA_FUNCS_num(meth);
+		for (i=0; i<max; i++)
+			{
+			m=sk_CRYPTO_EX_DATA_FUNCS_value(meth,i);
+			if ((m != NULL) && (m->free_func != NULL))
+				{
+				ptr=CRYPTO_get_ex_data(ad,i);
+				m->free_func(obj,ptr,ad,i,m->argl,m->argp);
+				}
+			}
+		}
+	if (ad->sk != NULL)
+		{
+		sk_free(ad->sk);
+		ad->sk=NULL;
+		}
+	}
+
+void CRYPTO_new_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, void *obj, CRYPTO_EX_DATA *ad)
+	{
+	CRYPTO_EX_DATA_FUNCS *m;
+	void *ptr;
+	int i,max;
+
+	ad->sk=NULL;
+	if (meth != NULL)
+		{
+		max=sk_CRYPTO_EX_DATA_FUNCS_num(meth);
+		for (i=0; i<max; i++)
+			{
+			m=sk_CRYPTO_EX_DATA_FUNCS_value(meth,i);
+			if ((m != NULL) && (m->new_func != NULL))
+				{
+				ptr=CRYPTO_get_ex_data(ad,i);
+				m->new_func(obj,ptr,ad,i,m->argl,m->argp);
+				}
+			}
+		}
+	}
+
+IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
diff --git a/AppleCSP/open_ssl/lhash/lhash.c b/AppleCSP/open_ssl/lhash/lhash.c
new file mode 100644
index 00000000..9169be4b
--- /dev/null
+++ b/AppleCSP/open_ssl/lhash/lhash.c
@@ -0,0 +1,479 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/lhash/lhash.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Code for dynamic hash table routines
+ * Author - Eric Young v 2.0
+ *
+ * 2.2 eay - added #include "crypto.h" so the memory leak checking code is
+ *	     present. eay 18-Jun-98
+ *
+ * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98
+ *
+ * 2.0 eay - Fixed a bug that occurred when using lh_delete
+ *	     from inside lh_doall().  As entries were deleted,
+ *	     the 'table' was 'contract()ed', making some entries
+ *	     jump from the end of the table to the start, there by
+ *	     skipping the lh_doall() processing. eay - 4/12/95
+ *
+ * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
+ *	     were not being free()ed. 21/11/95
+ *
+ * 1.8 eay - Put the stats routines into a separate file, lh_stats.c
+ *	     19/09/95
+ *
+ * 1.7 eay - Removed the fputs() for realloc failures - the code
+ *           should silently tolerate them.  I have also fixed things
+ *           lint complained about 04/05/95
+ *
+ * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
+ *
+ * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
+ *
+ * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
+ *
+ * 1.3 eay - Fixed a few lint problems 19/3/1991
+ *
+ * 1.2 eay - Fixed lh_doall problem 13/3/1991
+ *
+ * 1.1 eay - Added lh_doall
+ *
+ * 1.0 eay - First version
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+
+const char *lh_version="lhash" OPENSSL_VERSION_PTEXT;
+
+#undef MIN_NODES 
+#define MIN_NODES	16
+#define UP_LOAD		(2*LH_LOAD_MULT) /* load times 256  (default 2) */
+#define DOWN_LOAD	(LH_LOAD_MULT)   /* load times 256  (default 1) */
+
+static void expand(LHASH *lh);
+static void contract(LHASH *lh);
+static LHASH_NODE **getrn(LHASH *lh, void *data, unsigned long *rhash);
+
+LHASH *lh_new(unsigned long (*h)(), int (*c)())
+	{
+	LHASH *ret;
+	int i;
+
+	if ((ret=(LHASH *)Malloc(sizeof(LHASH))) == NULL)
+		goto err0;
+	if ((ret->b=(LHASH_NODE **)Malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
+		goto err1;
+	for (i=0; i<MIN_NODES; i++)
+		ret->b[i]=NULL;
+	ret->comp=((c == NULL)?(int (*)())strcmp:c);
+	ret->hash=((h == NULL)?(unsigned long (*)())lh_strhash:h);
+	ret->num_nodes=MIN_NODES/2;
+	ret->num_alloc_nodes=MIN_NODES;
+	ret->p=0;
+	ret->pmax=MIN_NODES/2;
+	ret->up_load=UP_LOAD;
+	ret->down_load=DOWN_LOAD;
+	ret->num_items=0;
+
+	ret->num_expands=0;
+	ret->num_expand_reallocs=0;
+	ret->num_contracts=0;
+	ret->num_contract_reallocs=0;
+	ret->num_hash_calls=0;
+	ret->num_comp_calls=0;
+	ret->num_insert=0;
+	ret->num_replace=0;
+	ret->num_delete=0;
+	ret->num_no_delete=0;
+	ret->num_retrieve=0;
+	ret->num_retrieve_miss=0;
+	ret->num_hash_comps=0;
+
+	ret->error=0;
+	return(ret);
+err1:
+	Free(ret);
+err0:
+	return(NULL);
+	}
+
+void lh_free(LHASH *lh)
+	{
+	unsigned int i;
+	LHASH_NODE *n,*nn;
+
+	if (lh == NULL)
+	    return;
+
+	for (i=0; i<lh->num_nodes; i++)
+		{
+		n=lh->b[i];
+		while (n != NULL)
+			{
+			nn=n->next;
+			Free(n);
+			n=nn;
+			}
+		}
+	Free(lh->b);
+	Free(lh);
+	}
+
+void *lh_insert(LHASH *lh, void *data)
+	{
+	unsigned long hash;
+	LHASH_NODE *nn,**rn;
+	void *ret;
+
+	lh->error=0;
+	if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))
+		expand(lh);
+
+	rn=getrn(lh,data,&hash);
+
+	if (*rn == NULL)
+		{
+		if ((nn=(LHASH_NODE *)Malloc(sizeof(LHASH_NODE))) == NULL)
+			{
+			lh->error++;
+			return(NULL);
+			}
+		nn->data=data;
+		nn->next=NULL;
+#ifndef NO_HASH_COMP
+		nn->hash=hash;
+#endif
+		*rn=nn;
+		ret=NULL;
+		lh->num_insert++;
+		lh->num_items++;
+		}
+	else /* replace same key */
+		{
+		ret= (*rn)->data;
+		(*rn)->data=data;
+		lh->num_replace++;
+		}
+	return(ret);
+	}
+
+void *lh_delete(LHASH *lh, void *data)
+	{
+	unsigned long hash;
+	LHASH_NODE *nn,**rn;
+	void *ret;
+
+	lh->error=0;
+	rn=getrn(lh,data,&hash);
+
+	if (*rn == NULL)
+		{
+		lh->num_no_delete++;
+		return(NULL);
+		}
+	else
+		{
+		nn= *rn;
+		*rn=nn->next;
+		ret=nn->data;
+		Free(nn);
+		lh->num_delete++;
+		}
+
+	lh->num_items--;
+	if ((lh->num_nodes > MIN_NODES) &&
+		(lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)))
+		contract(lh);
+
+	return(ret);
+	}
+
+void *lh_retrieve(LHASH *lh, void *data)
+	{
+	unsigned long hash;
+	LHASH_NODE **rn;
+	void *ret;
+
+	lh->error=0;
+	rn=getrn(lh,data,&hash);
+
+	if (*rn == NULL)
+		{
+		lh->num_retrieve_miss++;
+		return(NULL);
+		}
+	else
+		{
+		ret= (*rn)->data;
+		lh->num_retrieve++;
+		}
+	return(ret);
+	}
+
+void lh_doall(LHASH *lh, void (*func)())
+	{
+	lh_doall_arg(lh,func,NULL);
+	}
+
+void lh_doall_arg(LHASH *lh, void (*func)(), void *arg)
+	{
+	int i;
+	LHASH_NODE *a,*n;
+
+	/* reverse the order so we search from 'top to bottom'
+	 * We were having memory leaks otherwise */
+	for (i=lh->num_nodes-1; i>=0; i--)
+		{
+		a=lh->b[i];
+		while (a != NULL)
+			{
+			/* 28/05/91 - eay - n added so items can be deleted
+			 * via lh_doall */
+			n=a->next;
+			func(a->data,arg);
+			a=n;
+			}
+		}
+	}
+
+static void expand(LHASH *lh)
+	{
+	LHASH_NODE **n,**n1,**n2,*np;
+	unsigned int p,i,j;
+	unsigned long hash,nni;
+
+	lh->num_nodes++;
+	lh->num_expands++;
+	p=(int)lh->p++;
+	n1= &(lh->b[p]);
+	n2= &(lh->b[p+(int)lh->pmax]);
+	*n2=NULL;        /* 27/07/92 - eay - undefined pointer bug */
+	nni=lh->num_alloc_nodes;
+	
+	for (np= *n1; np != NULL; )
+		{
+#ifndef NO_HASH_COMP
+		hash=np->hash;
+#else
+		hash=(*(lh->hash))(np->data);
+		lh->num_hash_calls++;
+#endif
+		if ((hash%nni) != p)
+			{ /* move it */
+			*n1= (*n1)->next;
+			np->next= *n2;
+			*n2=np;
+			}
+		else
+			n1= &((*n1)->next);
+		np= *n1;
+		}
+
+	if ((lh->p) >= lh->pmax)
+		{
+		j=(int)lh->num_alloc_nodes*2;
+		n=(LHASH_NODE **)Realloc(lh->b,
+			(unsigned int)sizeof(LHASH_NODE *)*j);
+		if (n == NULL)
+			{
+/*			fputs("realloc error in lhash",stderr); */
+			lh->error++;
+			lh->p=0;
+			return;
+			}
+		/* else */
+		for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
+			n[i]=NULL;			  /* 02/03/92 eay */
+		lh->pmax=lh->num_alloc_nodes;
+		lh->num_alloc_nodes=j;
+		lh->num_expand_reallocs++;
+		lh->p=0;
+		lh->b=n;
+		}
+	}
+
+static void contract(LHASH *lh)
+	{
+	LHASH_NODE **n,*n1,*np;
+
+	np=lh->b[lh->p+lh->pmax-1];
+	lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */
+	if (lh->p == 0)
+		{
+		n=(LHASH_NODE **)Realloc(lh->b,
+			(unsigned int)(sizeof(LHASH_NODE *)*lh->pmax));
+		if (n == NULL)
+			{
+/*			fputs("realloc error in lhash",stderr); */
+			lh->error++;
+			return;
+			}
+		lh->num_contract_reallocs++;
+		lh->num_alloc_nodes/=2;
+		lh->pmax/=2;
+		lh->p=lh->pmax-1;
+		lh->b=n;
+		}
+	else
+		lh->p--;
+
+	lh->num_nodes--;
+	lh->num_contracts++;
+
+	n1=lh->b[(int)lh->p];
+	if (n1 == NULL)
+		lh->b[(int)lh->p]=np;
+	else
+		{
+		while (n1->next != NULL)
+			n1=n1->next;
+		n1->next=np;
+		}
+	}
+
+static LHASH_NODE **getrn(LHASH *lh, void *data, unsigned long *rhash)
+	{
+	LHASH_NODE **ret,*n1;
+	unsigned long hash,nn;
+	int (*cf)();
+
+	hash=(*(lh->hash))(data);
+	lh->num_hash_calls++;
+	*rhash=hash;
+
+	nn=hash%lh->pmax;
+	if (nn < lh->p)
+		nn=hash%lh->num_alloc_nodes;
+
+	cf=lh->comp;
+	ret= &(lh->b[(int)nn]);
+	for (n1= *ret; n1 != NULL; n1=n1->next)
+		{
+#ifndef NO_HASH_COMP
+		lh->num_hash_comps++;
+		if (n1->hash != hash)
+			{
+			ret= &(n1->next);
+			continue;
+			}
+#endif
+		lh->num_comp_calls++;
+		if ((*cf)(n1->data,data) == 0)
+			break;
+		ret= &(n1->next);
+		}
+	return(ret);
+	}
+
+/* The following hash seems to work very well on normal text strings
+ * no collisions on /usr/dict/words and it distributes on %2^n quite
+ * well, not as good as MD5, but still good.
+ */
+unsigned long lh_strhash(const char *c)
+	{
+	unsigned long ret=0;
+	long n;
+	unsigned long v;
+	int r;
+
+	if ((c == NULL) || (*c == '\0'))
+		return(ret);
+/*
+	unsigned char b[16];
+	MD5(c,strlen(c),b);
+	return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24)); 
+*/
+
+	n=0x100;
+	while (*c)
+		{
+		v=n|(*c);
+		n+=0x100;
+		r= (int)((v>>2)^v)&0x0f;
+		ret=(ret<<r)|(ret>>(32-r));
+		ret&=0xFFFFFFFFL;
+		ret^=v*v;
+		c++;
+		}
+	return((ret>>16)^ret);
+	}
+
+unsigned long lh_num_items(LHASH *lh)
+	{
+	return lh ? lh->num_items : 0;
+	}
diff --git a/AppleCSP/open_ssl/mem.c b/AppleCSP/open_ssl/mem.c
new file mode 100644
index 00000000..fd995d0c
--- /dev/null
+++ b/AppleCSP/open_ssl/mem.c
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/mem.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+
+
+static int allow_customize = 1;      /* we provide flexible functions for */
+static int allow_customize_debug = 1;/* exchanging memory-related functions at
+                                      * run-time, but this must be done
+                                      * before any blocks are actually
+                                      * allocated; or we'll run into huge
+                                      * problems when malloc/free pairs
+                                      * don't match etc. */
+
+/* may be changed as long as `allow_customize' is set */
+static void *(*malloc_locked_func)(size_t)  = malloc;
+static void (*free_locked_func)(void *)     = free;
+static void *(*malloc_func)(size_t)         = malloc;
+static void *(*realloc_func)(void *, size_t)= realloc;
+static void (*free_func)(void *)            = free;
+
+/* may be changed as long as `allow_customize_debug' is set */
+/* XXX use correct function pointer types */
+#ifdef CRYPTO_MDEBUG
+  /* use default functions from mem_dbg.c */
+  static void (*malloc_debug_func)()= (void (*)())CRYPTO_dbg_malloc;
+  static void (*realloc_debug_func)()= (void (*)())CRYPTO_dbg_realloc;
+  static void (*free_debug_func)()= (void (*)())CRYPTO_dbg_free;
+  static void (*set_debug_options_func)()= (void (*)())CRYPTO_dbg_set_options;
+  static long (*get_debug_options_func)()= (long (*)())CRYPTO_dbg_get_options;
+#else
+  /* applications can use CRYPTO_malloc_debug_init() to select above case
+   * at run-time */
+  static void (*malloc_debug_func)()= NULL;
+  static void (*realloc_debug_func)()= NULL;
+  static void (*free_debug_func)()= NULL;
+  static void (*set_debug_options_func)()= NULL;
+  static long (*get_debug_options_func)()= NULL;
+#endif
+
+
+int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
+	void (*f)(void *))
+	{
+	if (!allow_customize)
+		return 0;
+	if ((m == NULL) || (r == NULL) || (f == NULL))
+		return 0;
+	malloc_func=m;
+	realloc_func=r;
+	free_func=f;
+	malloc_locked_func=m;
+	free_locked_func=f;
+	return 1;
+	}
+
+int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *))
+	{
+	if (!allow_customize)
+		return 0;
+	if ((m == NULL) || (f == NULL))
+		return 0;
+	malloc_locked_func=m;
+	free_locked_func=f;
+	return 1;
+	}
+
+int CRYPTO_set_mem_debug_functions(void (*m)(), void (*r)(), void (*f)(),void (*so)(),long (*go)())
+	{
+	if (!allow_customize_debug)
+		return 0;
+	malloc_debug_func=m;
+	realloc_debug_func=r;
+	free_debug_func=f;
+	set_debug_options_func=so;
+	get_debug_options_func=go;
+	return 1;
+	}
+
+void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t),
+	void (**f)(void *))
+	{
+	if (m != NULL) *m=malloc_func;
+	if (r != NULL) *r=realloc_func;
+	if (f != NULL) *f=free_func;
+	}
+
+void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *))
+	{
+	if (m != NULL) *m=malloc_locked_func;
+	if (f != NULL) *f=free_locked_func;
+	}
+
+void CRYPTO_get_mem_debug_functions(void (**m)(), void (**r)(), void (**f)(),void (**so)(),long (**go)())
+	{
+	if (m != NULL) *m=malloc_debug_func;
+	if (r != NULL) *r=realloc_debug_func;
+	if (f != NULL) *f=free_debug_func;
+	if (so != NULL) *so=set_debug_options_func;
+	if (go != NULL) *go=get_debug_options_func;
+	}
+
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line)
+	{
+	char *ret = NULL;
+
+	allow_customize = 0;
+	if (malloc_debug_func != NULL)
+		{
+		allow_customize_debug = 0;
+		malloc_debug_func(NULL, num, file, line, 0);
+		}
+	ret = malloc_locked_func(num);
+#ifdef LEVITTE_DEBUG
+	fprintf(stderr, "LEVITTE_DEBUG:         > 0x%p (%d)\n", ret, num);
+#endif
+	if (malloc_debug_func != NULL)
+		malloc_debug_func(ret, num, file, line, 1);
+
+	return ret;
+	}
+
+void CRYPTO_free_locked(void *str)
+	{
+	if (free_debug_func != NULL)
+		free_debug_func(str, 0);
+#ifdef LEVITTE_DEBUG
+	fprintf(stderr, "LEVITTE_DEBUG:         < 0x%p\n", str);
+#endif
+	free_locked_func(str);
+	if (free_debug_func != NULL)
+		free_debug_func(NULL, 1);
+	}
+
+void *CRYPTO_malloc(int num, const char *file, int line)
+	{
+	char *ret = NULL;
+
+	allow_customize = 0;
+	if (malloc_debug_func != NULL)
+		{
+		allow_customize_debug = 0;
+		malloc_debug_func(NULL, num, file, line, 0);
+		}
+	ret = malloc_func(num);
+#ifdef LEVITTE_DEBUG
+	fprintf(stderr, "LEVITTE_DEBUG:         > 0x%p (%d)\n", ret, num);
+#endif
+	if (malloc_debug_func != NULL)
+		malloc_debug_func(ret, num, file, line, 1);
+
+	return ret;
+	}
+
+void *CRYPTO_realloc(void *str, int num, const char *file, int line)
+	{
+	char *ret = NULL;
+
+	if (realloc_debug_func != NULL)
+		realloc_debug_func(str, NULL, num, file, line, 0);
+	ret = realloc_func(str,num);
+#ifdef LEVITTE_DEBUG
+	fprintf(stderr, "LEVITTE_DEBUG:         | 0x%p -> 0x%p (%d)\n", str, ret, num);
+#endif
+	if (realloc_debug_func != NULL)
+		realloc_debug_func(str, ret, num, file, line, 1);
+
+	return ret;
+	}
+
+void CRYPTO_free(void *str)
+	{
+	if (free_debug_func != NULL)
+		free_debug_func(str, 0);
+#ifdef LEVITTE_DEBUG
+	fprintf(stderr, "LEVITTE_DEBUG:         < 0x%p\n", str);
+#endif
+	free_func(str);
+	if (free_debug_func != NULL)
+		free_debug_func(NULL, 1);
+	}
+
+void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
+	{
+	if (a != NULL) Free(a);
+	a=(char *)Malloc(num);
+	return(a);
+	}
+
+
+void CRYPTO_set_mem_debug_options(long bits)
+	{
+	if (set_debug_options_func != NULL)
+		set_debug_options_func(bits);
+	}
+
+long CRYPTO_get_mem_debug_options(void)
+	{
+	if (get_debug_options_func != NULL)
+		return get_debug_options_func();
+	return 0;
+	}
diff --git a/AppleCSP/open_ssl/misc/md2_dgst.c b/AppleCSP/open_ssl/misc/md2_dgst.c
new file mode 100644
index 00000000..186be7c1
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/md2_dgst.c
@@ -0,0 +1,223 @@
+/* crypto/md2/md2_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/md2.h>
+#include <openssl/opensslv.h>
+
+const char *MD2_version="MD2" OPENSSL_VERSION_PTEXT;
+
+/* Implemented from RFC1319 The MD2 Message-Digest Algorithm
+ */
+
+#define UCHAR	unsigned char
+
+static void md2_block(MD2_CTX *c, const unsigned char *d);
+/* The magic S table - I have converted it to hex since it is
+ * basically just a random byte string. */
+static const MD2_INT S[256]={
+	0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
+	0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
+	0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
+	0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
+	0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
+	0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
+	0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
+	0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
+	0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
+	0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
+	0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
+	0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
+	0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
+	0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
+	0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
+	0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
+	0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
+	0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
+	0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
+	0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
+	0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
+	0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
+	0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
+	0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
+	0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
+	0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
+	0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
+	0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
+	0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
+	0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
+	0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
+	0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
+	};
+
+const char *MD2_options(void)
+	{
+	if (sizeof(MD2_INT) == 1)
+		return("md2(char)");
+	else
+		return("md2(int)");
+	}
+
+void MD2_Init(MD2_CTX *c)
+	{
+	c->num=0;
+	memset(c->state,0,MD2_BLOCK*sizeof(MD2_INT));
+	memset(c->cksm,0,MD2_BLOCK*sizeof(MD2_INT));
+	memset(c->data,0,MD2_BLOCK);
+	}
+
+void MD2_Update(MD2_CTX *c, const unsigned char *data, unsigned long len)
+	{
+	register UCHAR *p;
+
+	if (len == 0) return;
+
+	p=c->data;
+	if (c->num != 0)
+		{
+		if ((c->num+len) >= MD2_BLOCK)
+			{
+			memcpy(&(p[c->num]),data,MD2_BLOCK-c->num);
+			md2_block(c,c->data);
+			data+=(MD2_BLOCK - c->num);
+			len-=(MD2_BLOCK - c->num);
+			c->num=0;
+			/* drop through and do the rest */
+			}
+		else
+			{
+			memcpy(&(p[c->num]),data,(int)len);
+			/* data+=len; */
+			c->num+=(int)len;
+			return;
+			}
+		}
+	/* we now can process the input data in blocks of MD2_BLOCK
+	 * chars and save the leftovers to c->data. */
+	while (len >= MD2_BLOCK)
+		{
+		md2_block(c,data);
+		data+=MD2_BLOCK;
+		len-=MD2_BLOCK;
+		}
+	memcpy(p,data,(int)len);
+	c->num=(int)len;
+	}
+
+static void md2_block(MD2_CTX *c, const unsigned char *d)
+	{
+	register MD2_INT t,*sp1,*sp2;
+	register int i,j;
+	MD2_INT state[48];
+
+	sp1=c->state;
+	sp2=c->cksm;
+	j=sp2[MD2_BLOCK-1];
+	for (i=0; i<16; i++)
+		{
+		state[i]=sp1[i];
+		state[i+16]=t=d[i];
+		state[i+32]=(t^sp1[i]);
+		j=sp2[i]^=S[t^j];
+		}
+	t=0;
+	for (i=0; i<18; i++)
+		{
+		for (j=0; j<48; j+=8)
+			{
+			t= state[j+ 0]^=S[t];
+			t= state[j+ 1]^=S[t];
+			t= state[j+ 2]^=S[t];
+			t= state[j+ 3]^=S[t];
+			t= state[j+ 4]^=S[t];
+			t= state[j+ 5]^=S[t];
+			t= state[j+ 6]^=S[t];
+			t= state[j+ 7]^=S[t];
+			}
+		t=(t+i)&0xff;
+		}
+	memcpy(sp1,state,16*sizeof(MD2_INT));
+	memset(state,0,48*sizeof(MD2_INT));
+	}
+
+void MD2_Final(unsigned char *md, MD2_CTX *c)
+	{
+	int i,v;
+	register UCHAR *cp;
+	register MD2_INT *p1,*p2;
+
+	cp=c->data;
+	p1=c->state;
+	p2=c->cksm;
+	v=MD2_BLOCK-c->num;
+	for (i=c->num; i<MD2_BLOCK; i++)
+		cp[i]=(UCHAR)v;
+
+	md2_block(c,cp);
+
+	for (i=0; i<MD2_BLOCK; i++)
+		cp[i]=(UCHAR)p2[i];
+	md2_block(c,cp);
+
+	for (i=0; i<16; i++)
+		md[i]=(UCHAR)(p1[i]&0xff);
+	memset((char *)&c,0,sizeof(c));
+	}
+
diff --git a/AppleCSP/open_ssl/misc/rc2_cbc.c b/AppleCSP/open_ssl/misc/rc2_cbc.c
new file mode 100644
index 00000000..f53628c4
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/rc2_cbc.c
@@ -0,0 +1,256 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc2/rc2_cbc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc2.h>
+#include "rc2_locl.h"
+
+#ifndef	_OPENSSL_APPLE_CDSA_
+
+void RC2_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
+	     RC2_KEY *ks, unsigned char *iv, int encrypt)
+	{
+	register unsigned long tin0,tin1;
+	register unsigned long tout0,tout1,xor0,xor1;
+	register long l=length;
+	unsigned long tin[2];
+
+	if (encrypt)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC2_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC2_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC2_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC2_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+#endif	/* _OPENSSL_APPLE_CDSA_ */
+
+#ifdef	_OPENSSL_APPLE_CDSA_
+void RC2_encrypt(RC2_INT *d, RC2_KEY *key)
+#else
+void RC2_encrypt(unsigned long *d, RC2_KEY *key)
+#endif
+	{
+	int i,n;
+	register RC2_INT *p0,*p1;
+	register RC2_INT x0,x1,x2,x3,t;
+	unsigned long l;
+
+	l=d[0];
+	x0=(RC2_INT)l&0xffff;
+	x1=(RC2_INT)(l>>16L);
+	l=d[1];
+	x2=(RC2_INT)l&0xffff;
+	x3=(RC2_INT)(l>>16L);
+
+	n=3;
+	i=5;
+
+	p0=p1= &(key->data[0]);
+	for (;;)
+		{
+		t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff;
+		x0=(t<<1)|(t>>15);
+		t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff;
+		x1=(t<<2)|(t>>14);
+		t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff;
+		x2=(t<<3)|(t>>13);
+		t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff;
+		x3=(t<<5)|(t>>11);
+
+		if (--i == 0)
+			{
+			if (--n == 0) break;
+			i=(n == 2)?6:5;
+
+			x0+=p1[x3&0x3f];
+			x1+=p1[x0&0x3f];
+			x2+=p1[x1&0x3f];
+			x3+=p1[x2&0x3f];
+			}
+		}
+
+	d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
+	d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
+	}
+
+#ifdef	_OPENSSL_APPLE_CDSA_
+void RC2_decrypt(RC2_INT *d, RC2_KEY *key)
+#else
+void RC2_decrypt(unsigned long *d, RC2_KEY *key)
+#endif
+	{
+	int i,n;
+	register RC2_INT *p0,*p1;
+	register RC2_INT x0,x1,x2,x3,t;
+	unsigned long l;
+
+	l=d[0];
+	x0=(RC2_INT)l&0xffff;
+	x1=(RC2_INT)(l>>16L);
+	l=d[1];
+	x2=(RC2_INT)l&0xffff;
+	x3=(RC2_INT)(l>>16L);
+
+	n=3;
+	i=5;
+
+	p0= &(key->data[63]);
+	p1= &(key->data[0]);
+	for (;;)
+		{
+		t=((x3<<11)|(x3>>5))&0xffff;
+		x3=(t-(x0& ~x2)-(x1&x2)- *(p0--))&0xffff;
+		t=((x2<<13)|(x2>>3))&0xffff;
+		x2=(t-(x3& ~x1)-(x0&x1)- *(p0--))&0xffff;
+		t=((x1<<14)|(x1>>2))&0xffff;
+		x1=(t-(x2& ~x0)-(x3&x0)- *(p0--))&0xffff;
+		t=((x0<<15)|(x0>>1))&0xffff;
+		x0=(t-(x1& ~x3)-(x2&x3)- *(p0--))&0xffff;
+
+		if (--i == 0)
+			{
+			if (--n == 0) break;
+			i=(n == 2)?6:5;
+
+			x3=(x3-p1[x2&0x3f])&0xffff;
+			x2=(x2-p1[x1&0x3f])&0xffff;
+			x1=(x1-p1[x0&0x3f])&0xffff;
+			x0=(x0-p1[x3&0x3f])&0xffff;
+			}
+		}
+
+	d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
+	d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
+	}
+
diff --git a/AppleCSP/open_ssl/misc/rc2_locl.h b/AppleCSP/open_ssl/misc/rc2_locl.h
new file mode 100644
index 00000000..6b66202b
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/rc2_locl.h
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc2/rc2_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#define C_RC2(n) \
+	t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \
+	x0=(t<<1)|(t>>15); \
+	t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \
+	x1=(t<<2)|(t>>14); \
+	t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \
+	x2=(t<<3)|(t>>13); \
+	t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \
+	x3=(t<<5)|(t>>11);
+
diff --git a/AppleCSP/open_ssl/misc/rc2_skey.c b/AppleCSP/open_ssl/misc/rc2_skey.c
new file mode 100644
index 00000000..ea73fb6a
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/rc2_skey.c
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc2/rc2_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc2.h>
+#include "rc2_locl.h"
+
+static const unsigned char key_table[256]={
+	0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79,
+	0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e,
+	0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5,
+	0x87,0xb3,0x4f,0x13,0x61,0x45,0x6d,0x8d,0x09,0x81,0x7d,0x32,
+	0xbd,0x8f,0x40,0xeb,0x86,0xb7,0x7b,0x0b,0xf0,0x95,0x21,0x22,
+	0x5c,0x6b,0x4e,0x82,0x54,0xd6,0x65,0x93,0xce,0x60,0xb2,0x1c,
+	0x73,0x56,0xc0,0x14,0xa7,0x8c,0xf1,0xdc,0x12,0x75,0xca,0x1f,
+	0x3b,0xbe,0xe4,0xd1,0x42,0x3d,0xd4,0x30,0xa3,0x3c,0xb6,0x26,
+	0x6f,0xbf,0x0e,0xda,0x46,0x69,0x07,0x57,0x27,0xf2,0x1d,0x9b,
+	0xbc,0x94,0x43,0x03,0xf8,0x11,0xc7,0xf6,0x90,0xef,0x3e,0xe7,
+	0x06,0xc3,0xd5,0x2f,0xc8,0x66,0x1e,0xd7,0x08,0xe8,0xea,0xde,
+	0x80,0x52,0xee,0xf7,0x84,0xaa,0x72,0xac,0x35,0x4d,0x6a,0x2a,
+	0x96,0x1a,0xd2,0x71,0x5a,0x15,0x49,0x74,0x4b,0x9f,0xd0,0x5e,
+	0x04,0x18,0xa4,0xec,0xc2,0xe0,0x41,0x6e,0x0f,0x51,0xcb,0xcc,
+	0x24,0x91,0xaf,0x50,0xa1,0xf4,0x70,0x39,0x99,0x7c,0x3a,0x85,
+	0x23,0xb8,0xb4,0x7a,0xfc,0x02,0x36,0x5b,0x25,0x55,0x97,0x31,
+	0x2d,0x5d,0xfa,0x98,0xe3,0x8a,0x92,0xae,0x05,0xdf,0x29,0x10,
+	0x67,0x6c,0xba,0xc9,0xd3,0x00,0xe6,0xcf,0xe1,0x9e,0xa8,0x2c,
+	0x63,0x16,0x01,0x3f,0x58,0xe2,0x89,0xa9,0x0d,0x38,0x34,0x1b,
+	0xab,0x33,0xff,0xb0,0xbb,0x48,0x0c,0x5f,0xb9,0xb1,0xcd,0x2e,
+	0xc5,0xf3,0xdb,0x47,0xe5,0xa5,0x9c,0x77,0x0a,0xa6,0x20,0x68,
+	0xfe,0x7f,0xc1,0xad,
+	};
+
+/* It has come to my attention that there are 2 versions of the RC2
+ * key schedule.  One which is normal, and anther which has a hook to
+ * use a reduced key length.
+ * BSAFE uses the 'retarded' version.  What I previously shipped is
+ * the same as specifying 1024 for the 'bits' parameter.  Bsafe uses
+ * a version where the bits parameter is the same as len*8 */
+void RC2_set_key(RC2_KEY *key, int len, unsigned char *data, int bits)
+	{
+	int i,j;
+	unsigned char *k;
+	RC2_INT *ki;
+	unsigned int c,d;
+
+	k= (unsigned char *)&(key->data[0]);
+	*k=0; /* for if there is a zero length key */
+
+	if (len > 128) len=128;
+	if (bits <= 0) bits=1024;
+	if (bits > 1024) bits=1024;
+
+	for (i=0; i<len; i++)
+		k[i]=data[i];
+
+	/* expand table */
+	d=k[len-1];
+	j=0;
+	for (i=len; i < 128; i++,j++)
+		{
+		d=key_table[(k[j]+d)&0xff];
+		k[i]=d;
+		}
+
+	/* hmm.... key reduction to 'bits' bits */
+
+	j=(bits+7)>>3;
+	i=128-j;
+	c= (0xff>>(-bits & 0x07));
+
+	d=key_table[k[i]&c];
+	k[i]=d;
+	while (i--)
+		{
+		d=key_table[k[i+j]^d];
+		k[i]=d;
+		}
+
+	/* copy from bytes into RC2_INT's */
+	ki= &(key->data[63]);
+	for (i=127; i>=0; i-=2)
+		*(ki--)=((k[i]<<8)|k[i-1])&0xffff;
+	}
+
diff --git a/AppleCSP/open_ssl/misc/rc4_enc.c b/AppleCSP/open_ssl/misc/rc4_enc.c
new file mode 100644
index 00000000..55c710bf
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/rc4_enc.c
@@ -0,0 +1,332 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc4/rc4_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc4.h>
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
+	     unsigned char *outdata)
+	{
+        register RC4_INT *d;
+        register RC4_INT x,y,tx,ty;
+	int i;
+        
+        x=key->x;     
+        y=key->y;     
+        d=key->data; 
+
+#if defined(RC4_CHUNK)
+	/*
+	 * The original reason for implementing this(*) was the fact that
+	 * pre-21164a Alpha CPUs don't have byte load/store instructions
+	 * and e.g. a byte store has to be done with 64-bit load, shift,
+	 * and, or and finally 64-bit store. Peaking data and operating
+	 * at natural word size made it possible to reduce amount of
+	 * instructions as well as to perform early read-ahead without
+	 * suffering from RAW (read-after-write) hazard. This resulted
+	 * in ~40%(**) performance improvement on 21064 box with gcc.
+	 * But it's not only Alpha users who win here:-) Thanks to the
+	 * early-n-wide read-ahead this implementation also exhibits
+	 * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending
+	 * on sizeof(RC4_INT)).
+	 *
+	 * (*)	"this" means code which recognizes the case when input
+	 *	and output pointers appear to be aligned at natural CPU
+	 *	word boundary
+	 * (**)	i.e. according to 'apps/openssl speed rc4' benchmark,
+	 *	crypto/rc4/rc4speed.c exhibits almost 70% speed-up...
+	 *
+	 * Cavets.
+	 *
+	 * - RC4_CHUNK="unsigned long long" should be a #1 choice for
+	 *   UltraSPARC. Unfortunately gcc generates very slow code
+	 *   (2.5-3 times slower than one generated by Sun's WorkShop
+	 *   C) and therefore gcc (at least 2.95 and earlier) should
+	 *   always be told that RC4_CHUNK="unsigned long".
+	 *
+	 *					<appro@fy.chalmers.se>
+	 */
+
+# define RC4_STEP	( \
+			x=(x+1) &0xff,	\
+			tx=d[x],	\
+			y=(tx+y)&0xff,	\
+			ty=d[y],	\
+			d[y]=tx,	\
+			d[x]=ty,	\
+			(RC4_CHUNK)d[(tx+ty)&0xff]\
+			)
+
+	if ( ( ((unsigned long)indata  & (sizeof(RC4_CHUNK)-1)) | 
+	       ((unsigned long)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 )
+		{
+		RC4_CHUNK ichunk,otp;
+		const union { long one; char little; } is_endian = {1};
+
+		/*
+		 * I reckon we can afford to implement both endian
+		 * cases and to decide which way to take at run-time
+		 * because the machine code appears to be very compact
+		 * and redundant 1-2KB is perfectly tolerable (i.e.
+		 * in case the compiler fails to eliminate it:-). By
+		 * suggestion from Terrel Larson <terr@terralogic.net>
+		 * who also stands for the is_endian union:-)
+		 *
+		 * Special notes.
+		 *
+		 * - is_endian is declared automatic as doing otherwise
+		 *   (declaring static) prevents gcc from eliminating
+		 *   the redundant code;
+		 * - compilers (those I've tried) don't seem to have
+		 *   problems eliminating either the operators guarded
+		 *   by "if (sizeof(RC4_CHUNK)==8)" or the condition
+		 *   expressions themselves so I've got 'em to replace
+		 *   corresponding #ifdefs from the previous version;
+		 * - I chose to let the redundant switch cases when
+		 *   sizeof(RC4_CHUNK)!=8 be (were also #ifdefed
+		 *   before);
+		 * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in
+		 *   [LB]ESHFT guards against "shift is out of range"
+		 *   warnings when sizeof(RC4_CHUNK)!=8 
+		 *
+		 *			<appro@fy.chalmers.se>
+		 */
+		if (!is_endian.little)
+			{	/* BIG-ENDIAN CASE */
+# define BESHFT(c)	(((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
+			for (;len&-sizeof(RC4_CHUNK);len-=sizeof(RC4_CHUNK))
+				{
+				ichunk  = *(RC4_CHUNK *)indata;
+				otp  = RC4_STEP<<BESHFT(0);
+				otp |= RC4_STEP<<BESHFT(1);
+				otp |= RC4_STEP<<BESHFT(2);
+				otp |= RC4_STEP<<BESHFT(3);
+				if (sizeof(RC4_CHUNK)==8)
+					{
+					otp |= RC4_STEP<<BESHFT(4);
+					otp |= RC4_STEP<<BESHFT(5);
+					otp |= RC4_STEP<<BESHFT(6);
+					otp |= RC4_STEP<<BESHFT(7);
+					}
+				*(RC4_CHUNK *)outdata = otp^ichunk;
+				indata  += sizeof(RC4_CHUNK);
+				outdata += sizeof(RC4_CHUNK);
+				}
+			if (len)
+				{
+				RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
+
+				ichunk = *(RC4_CHUNK *)indata;
+				ochunk = *(RC4_CHUNK *)outdata;
+				otp = 0;
+				i = BESHFT(0);
+				mask <<= (sizeof(RC4_CHUNK)-len)<<3;
+				switch (len&(sizeof(RC4_CHUNK)-1))
+					{
+					case 7:	otp  = RC4_STEP<<i, i-=8;
+					case 6:	otp |= RC4_STEP<<i, i-=8;
+					case 5:	otp |= RC4_STEP<<i, i-=8;
+					case 4:	otp |= RC4_STEP<<i, i-=8;
+					case 3:	otp |= RC4_STEP<<i, i-=8;
+					case 2:	otp |= RC4_STEP<<i, i-=8;
+					case 1:	otp |= RC4_STEP<<i, i-=8;
+					case 0: ; /*
+						   * it's never the case,
+						   * but it has to be here
+						   * for ultrix?
+						   */
+					}
+				ochunk &= ~mask;
+				ochunk |= (otp^ichunk) & mask;
+				*(RC4_CHUNK *)outdata = ochunk;
+				}
+			key->x=x;     
+			key->y=y;
+			return;
+			}	/* big-endian */
+		else
+			{	/* LITTLE-ENDIAN CASE */
+# define LESHFT(c)	(((c)*8)&(sizeof(RC4_CHUNK)*8-1))
+			for (;len&-sizeof(RC4_CHUNK);len-=sizeof(RC4_CHUNK))
+				{
+				ichunk  = *(RC4_CHUNK *)indata;
+				otp  = RC4_STEP;
+				otp |= RC4_STEP<<8;
+				otp |= RC4_STEP<<16;
+				otp |= RC4_STEP<<24;
+				if (sizeof(RC4_CHUNK)==8)
+					{
+					otp |= RC4_STEP<<LESHFT(4);
+					otp |= RC4_STEP<<LESHFT(5);
+					otp |= RC4_STEP<<LESHFT(6);
+					otp |= RC4_STEP<<LESHFT(7);
+					}
+				*(RC4_CHUNK *)outdata = otp^ichunk;
+				indata  += sizeof(RC4_CHUNK);
+				outdata += sizeof(RC4_CHUNK);
+				}
+			if (len)
+				{
+				RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
+
+				ichunk = *(RC4_CHUNK *)indata;
+				ochunk = *(RC4_CHUNK *)outdata;
+				otp = 0;
+				i   = 0;
+				mask >>= (sizeof(RC4_CHUNK)-len)<<3;
+				switch (len&(sizeof(RC4_CHUNK)-1))
+					{
+					case 7:	otp  = RC4_STEP,    i+=8;
+					case 6:	otp |= RC4_STEP<<i, i+=8;
+					case 5:	otp |= RC4_STEP<<i, i+=8;
+					case 4:	otp |= RC4_STEP<<i, i+=8;
+					case 3:	otp |= RC4_STEP<<i, i+=8;
+					case 2:	otp |= RC4_STEP<<i, i+=8;
+					case 1:	otp |= RC4_STEP<<i, i+=8;
+					case 0: ; /*
+						   * it's never the case,
+						   * but it has to be here
+						   * for ultrix?
+						   */
+					}
+				ochunk &= ~mask;
+				ochunk |= (otp^ichunk) & mask;
+				*(RC4_CHUNK *)outdata = ochunk;
+				}
+			key->x=x;     
+			key->y=y;
+			return;
+			} /* little-endian */
+		}
+#endif
+#define LOOP(in,out) \
+		x=((x+1)&0xff); \
+		tx=d[x]; \
+		y=(tx+y)&0xff; \
+		d[x]=ty=d[y]; \
+		d[y]=tx; \
+		(out) = d[(tx+ty)&0xff]^ (in);
+
+#ifndef RC4_INDEX
+#define RC4_LOOP(a,b,i)	LOOP(*((a)++),*((b)++))
+#else
+#define RC4_LOOP(a,b,i)	LOOP(a[i],b[i])
+#endif
+
+	i=(int)(len>>3L);
+	if (i)
+		{
+		for (;;)
+			{
+			RC4_LOOP(indata,outdata,0);
+			RC4_LOOP(indata,outdata,1);
+			RC4_LOOP(indata,outdata,2);
+			RC4_LOOP(indata,outdata,3);
+			RC4_LOOP(indata,outdata,4);
+			RC4_LOOP(indata,outdata,5);
+			RC4_LOOP(indata,outdata,6);
+			RC4_LOOP(indata,outdata,7);
+#ifdef RC4_INDEX
+			indata+=8;
+			outdata+=8;
+#endif
+			if (--i == 0) break;
+			}
+		}
+	i=(int)len&0x07;
+	if (i)
+		{
+		for (;;)
+			{
+			RC4_LOOP(indata,outdata,0); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,1); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,2); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,3); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,4); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,5); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,6); if (--i == 0) break;
+			}
+		}               
+	key->x=x;     
+	key->y=y;
+	}
diff --git a/AppleCSP/open_ssl/misc/rc4_skey.c b/AppleCSP/open_ssl/misc/rc4_skey.c
new file mode 100644
index 00000000..c5eba017
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/rc4_skey.c
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc4/rc4_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc4.h>
+
+#ifndef	_OPENSSL_APPLE_CDSA_
+
+#include "rc4_locl.h"
+#include <openssl/opensslv.h>
+
+const char *RC4_version="RC4" OPENSSL_VERSION_PTEXT;
+
+const char *RC4_options(void)
+	{
+#ifdef RC4_INDEX
+	if (sizeof(RC4_INT) == 1)
+		return("rc4(idx,char)");
+	else
+		return("rc4(idx,int)");
+#else
+	if (sizeof(RC4_INT) == 1)
+		return("rc4(ptr,char)");
+	else
+		return("rc4(ptr,int)");
+#endif
+	}
+
+#endif	/* _OPENSSL_APPLE_CDSA_*/
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+	{
+        register RC4_INT tmp;
+        register int id1,id2;
+        register RC4_INT *d;
+        unsigned int i;
+        
+        d= &(key->data[0]);
+	for (i=0; i<256; i++)
+		d[i]=i;
+        key->x = 0;     
+        key->y = 0;     
+        id1=id2=0;     
+
+#define SK_LOOP(n) { \
+		tmp=d[(n)]; \
+		id2 = (data[id1] + tmp + id2) & 0xff; \
+		if (++id1 == len) id1=0; \
+		d[(n)]=d[id2]; \
+		d[id2]=tmp; }
+
+	for (i=0; i < 256; i+=4)
+		{
+		SK_LOOP(i+0);
+		SK_LOOP(i+1);
+		SK_LOOP(i+2);
+		SK_LOOP(i+3);
+		}
+	}
+    
diff --git a/AppleCSP/open_ssl/misc/rc5_enc.c b/AppleCSP/open_ssl/misc/rc5_enc.c
new file mode 100644
index 00000000..630e5eac
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/rc5_enc.c
@@ -0,0 +1,243 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc5/rc5_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/rc5.h>
+#include "rc5_locl.h"
+
+#ifndef	_OPENSSL_APPLE_CDSA_
+void RC5_32_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
+	     RC5_32_KEY *ks, unsigned char *iv, int encrypt)
+	{
+	register unsigned long tin0,tin1;
+	register unsigned long tout0,tout1,xor0,xor1;
+	register long l=length;
+	unsigned long tin[2];
+
+	if (encrypt)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC5_32_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC5_32_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC5_32_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC5_32_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+#endif
+
+#ifdef	_OPENSSL_APPLE_CDSA_
+void RC5_32_encrypt(RC5_32_INT *d, RC5_32_KEY *key)
+#else
+void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key)
+#endif	/* _OPENSSL_APPLE_CDSA_ */
+	{
+	RC5_32_INT a,b,*s;
+
+	s=key->data;
+
+	a=d[0]+s[0];
+	b=d[1]+s[1];
+	E_RC5_32(a,b,s, 2);
+	E_RC5_32(a,b,s, 4);
+	E_RC5_32(a,b,s, 6);
+	E_RC5_32(a,b,s, 8);
+	E_RC5_32(a,b,s,10);
+	E_RC5_32(a,b,s,12);
+	E_RC5_32(a,b,s,14);
+	E_RC5_32(a,b,s,16);
+	if (key->rounds == 12)
+		{
+		E_RC5_32(a,b,s,18);
+		E_RC5_32(a,b,s,20);
+		E_RC5_32(a,b,s,22);
+		E_RC5_32(a,b,s,24);
+		}
+	else if (key->rounds == 16)
+		{
+		/* Do a full expansion to avoid a jump */
+		E_RC5_32(a,b,s,18);
+		E_RC5_32(a,b,s,20);
+		E_RC5_32(a,b,s,22);
+		E_RC5_32(a,b,s,24);
+		E_RC5_32(a,b,s,26);
+		E_RC5_32(a,b,s,28);
+		E_RC5_32(a,b,s,30);
+		E_RC5_32(a,b,s,32);
+		}
+	d[0]=a;
+	d[1]=b;
+	}
+
+#ifdef	_OPENSSL_APPLE_CDSA_
+void RC5_32_decrypt(RC5_32_INT *d, RC5_32_KEY *key)
+#else
+void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key)
+#endif	/* _OPENSSL_APPLE_CDSA_*/
+	{
+	RC5_32_INT a,b,*s;
+
+	s=key->data;
+
+	a=d[0];
+	b=d[1];
+	if (key->rounds == 16) 
+		{
+		D_RC5_32(a,b,s,32);
+		D_RC5_32(a,b,s,30);
+		D_RC5_32(a,b,s,28);
+		D_RC5_32(a,b,s,26);
+		/* Do a full expansion to avoid a jump */
+		D_RC5_32(a,b,s,24);
+		D_RC5_32(a,b,s,22);
+		D_RC5_32(a,b,s,20);
+		D_RC5_32(a,b,s,18);
+		}
+	else if (key->rounds == 12)
+		{
+		D_RC5_32(a,b,s,24);
+		D_RC5_32(a,b,s,22);
+		D_RC5_32(a,b,s,20);
+		D_RC5_32(a,b,s,18);
+		}
+	D_RC5_32(a,b,s,16);
+	D_RC5_32(a,b,s,14);
+	D_RC5_32(a,b,s,12);
+	D_RC5_32(a,b,s,10);
+	D_RC5_32(a,b,s, 8);
+	D_RC5_32(a,b,s, 6);
+	D_RC5_32(a,b,s, 4);
+	D_RC5_32(a,b,s, 2);
+	d[0]=a-s[0];
+	d[1]=b-s[1];
+	}
+
diff --git a/AppleCSP/open_ssl/misc/rc5_locl.h b/AppleCSP/open_ssl/misc/rc5_locl.h
new file mode 100644
index 00000000..2c45d85d
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/rc5_locl.h
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc5/rc5_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#if defined(WIN32) && defined(_MSC_VER)
+#define ROTATE_l32(a,n)     _lrotl(a,n)
+#define ROTATE_r32(a,n)     _lrotr(a,n)
+#else
+#define ROTATE_l32(a,n)     (((a)<<(n&0x1f))|(((a)&0xffffffff)>>(32-(n&0x1f))))
+#define ROTATE_r32(a,n)     (((a)<<(32-(n&0x1f)))|(((a)&0xffffffff)>>(n&0x1f)))
+#endif
+
+#define RC5_32_MASK	0xffffffffL
+
+#define RC5_16_P	0xB7E1
+#define RC5_16_Q	0x9E37
+#define RC5_32_P	0xB7E15163L
+#define RC5_32_Q	0x9E3779B9L
+#define RC5_64_P	0xB7E151628AED2A6BLL
+#define RC5_64_Q	0x9E3779B97F4A7C15LL
+
+#define E_RC5_32(a,b,s,n) \
+	a^=b; \
+	a=ROTATE_l32(a,b); \
+	a+=s[n]; \
+	a&=RC5_32_MASK; \
+	b^=a; \
+	b=ROTATE_l32(b,a); \
+	b+=s[n+1]; \
+	b&=RC5_32_MASK;
+
+#define D_RC5_32(a,b,s,n) \
+	b-=s[n+1]; \
+	b&=RC5_32_MASK; \
+	b=ROTATE_r32(b,a); \
+	b^=a; \
+	a-=s[n]; \
+	a&=RC5_32_MASK; \
+	a=ROTATE_r32(a,b); \
+	a^=b;
+
+
+
diff --git a/AppleCSP/open_ssl/misc/rc5_skey.c b/AppleCSP/open_ssl/misc/rc5_skey.c
new file mode 100644
index 00000000..f1aad501
--- /dev/null
+++ b/AppleCSP/open_ssl/misc/rc5_skey.c
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc5/rc5_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc5.h>
+#include "rc5_locl.h"
+
+void RC5_32_set_key(RC5_32_KEY *key, int len, unsigned char *data,
+	     int rounds)
+	{
+	RC5_32_INT L[64],l,ll,A,B,*S,k;
+	int i,j,m,c,t,ii,jj;
+
+	if (	(rounds != RC5_16_ROUNDS) &&
+		(rounds != RC5_12_ROUNDS) &&
+		(rounds != RC5_8_ROUNDS))
+		rounds=RC5_16_ROUNDS;
+
+	key->rounds=rounds;
+	S= &(key->data[0]);
+	j=0;
+	for (i=0; i<=(len-8); i+=8)
+		{
+		c2l(data,l);
+		L[j++]=l;
+		c2l(data,l);
+		L[j++]=l;
+		}
+	ii=len-i;
+	if (ii)
+		{
+		k=len&0x07;
+		c2ln(data,l,ll,k);
+		L[j+0]=l;
+		L[j+1]=ll;
+		}
+
+	c=(len+3)/4;
+	t=(rounds+1)*2;
+	S[0]=RC5_32_P;
+	for (i=1; i<t; i++)
+		S[i]=(S[i-1]+RC5_32_Q)&RC5_32_MASK;
+
+	j=(t>c)?t:c;
+	j*=3;
+	ii=jj=0;
+	A=B=0;
+	for (i=0; i<j; i++)
+		{
+		k=(S[ii]+A+B)&RC5_32_MASK;
+		A=S[ii]=ROTATE_l32(k,3);
+		m=(int)(A+B);
+		k=(L[jj]+A+B)&RC5_32_MASK;
+		B=L[jj]=ROTATE_l32(k,m);
+		if (++ii >= t) ii=0;
+		if (++jj >= c) jj=0;
+		}
+	}
+
diff --git a/AppleCSP/open_ssl/openssl/asn1.h b/AppleCSP/open_ssl/openssl/asn1.h
new file mode 100644
index 00000000..021405ca
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/asn1.h
@@ -0,0 +1,1085 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/asn1/asn1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_H
+#define HEADER_ASN1_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+#include <openssl/bn.h>
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+
+#ifdef VMS
+#include <openssl/vms_idhacks.h>
+#endif
+
+#define V_ASN1_UNIVERSAL		0x00
+#define	V_ASN1_APPLICATION		0x40
+#define V_ASN1_CONTEXT_SPECIFIC		0x80
+#define V_ASN1_PRIVATE			0xc0
+
+#define V_ASN1_CONSTRUCTED		0x20
+#define V_ASN1_PRIMITIVE_TAG		0x1f
+#define V_ASN1_PRIMATIVE_TAG		0x1f
+
+#define V_ASN1_APP_CHOOSE		-2	/* let the recipient choose */
+
+#define V_ASN1_UNDEF			-1
+#define V_ASN1_EOC			0
+#define V_ASN1_BOOLEAN			1	/**/
+#define V_ASN1_INTEGER			2
+#define V_ASN1_NEG_INTEGER		(2+0x100)
+#define V_ASN1_BIT_STRING		3
+#define V_ASN1_OCTET_STRING		4
+#define V_ASN1_NULL			5
+#define V_ASN1_OBJECT			6
+#define V_ASN1_OBJECT_DESCRIPTOR	7
+#define V_ASN1_EXTERNAL			8
+#define V_ASN1_REAL			9
+#define V_ASN1_ENUMERATED		10
+#define V_ASN1_NEG_ENUMERATED		(10+0x100)
+#define V_ASN1_UTF8STRING		12
+#define V_ASN1_SEQUENCE			16
+#define V_ASN1_SET			17
+#define V_ASN1_NUMERICSTRING		18	/**/
+#define V_ASN1_PRINTABLESTRING		19
+#define V_ASN1_T61STRING		20
+#define V_ASN1_TELETEXSTRING		20	/* alias */
+#define V_ASN1_VIDEOTEXSTRING		21	/**/
+#define V_ASN1_IA5STRING		22
+#define V_ASN1_UTCTIME			23
+#define V_ASN1_GENERALIZEDTIME		24	/**/
+#define V_ASN1_GRAPHICSTRING		25	/**/
+#define V_ASN1_ISO64STRING		26	/**/
+#define V_ASN1_VISIBLESTRING		26	/* alias */
+#define V_ASN1_GENERALSTRING		27	/**/
+#define V_ASN1_UNIVERSALSTRING		28	/**/
+#define V_ASN1_BMPSTRING		30
+
+/* For use with d2i_ASN1_type_bytes() */
+#define B_ASN1_NUMERICSTRING	0x0001
+#define B_ASN1_PRINTABLESTRING	0x0002
+#define B_ASN1_T61STRING	0x0004
+#define B_ASN1_TELETEXSTRING	0x0008
+#define B_ASN1_VIDEOTEXSTRING	0x0008
+#define B_ASN1_IA5STRING	0x0010
+#define B_ASN1_GRAPHICSTRING	0x0020
+#define B_ASN1_ISO64STRING	0x0040
+#define B_ASN1_VISIBLESTRING	0x0040
+#define B_ASN1_GENERALSTRING	0x0080
+#define B_ASN1_UNIVERSALSTRING	0x0100
+#define B_ASN1_OCTET_STRING	0x0200
+#define B_ASN1_BIT_STRING	0x0400
+#define B_ASN1_BMPSTRING	0x0800
+#define B_ASN1_UNKNOWN		0x1000
+#define B_ASN1_UTF8STRING	0x2000
+
+/* For use with ASN1_mbstring_copy() */
+#define MBSTRING_FLAG		0x1000
+#define MBSTRING_ASC		(MBSTRING_FLAG|1)
+#define MBSTRING_BMP		(MBSTRING_FLAG|2)
+#define MBSTRING_UNIV		(MBSTRING_FLAG|3)
+#define MBSTRING_UTF8		(MBSTRING_FLAG|4)
+
+#define DECLARE_ASN1_SET_OF(type) \
+int i2d_ASN1_SET_OF_##type(STACK_OF(type) *a,unsigned char **pp, \
+			   int (*func)(type *,unsigned char **), int ex_tag, \
+			   int ex_class, int is_set); \
+STACK_OF(type) *d2i_ASN1_SET_OF_##type(STACK_OF(type) **a,unsigned char **pp, \
+				       long length, \
+				       type *(*func)(type **, \
+						     unsigned char **,long), \
+				       void (*free_func)(type *), \
+				       int ex_tag,int ex_class);
+
+#define IMPLEMENT_ASN1_SET_OF(type) \
+int i2d_ASN1_SET_OF_##type(STACK_OF(type) *a,unsigned char **pp, \
+			   int (*func)(type *,unsigned char **), int ex_tag, \
+			   int ex_class, int is_set) \
+    { return i2d_ASN1_SET((STACK *)a,pp,func,ex_tag,ex_class,is_set); } \
+STACK_OF(type) *d2i_ASN1_SET_OF_##type(STACK_OF(type) **a,unsigned char **pp, \
+				       long length, \
+				       type *(*func)(type **, \
+						     unsigned char **,long), \
+				       void (*free_func)(type *), \
+				       int ex_tag,int ex_class) \
+    { return (STACK_OF(type) *)d2i_ASN1_SET((STACK **)a,pp,length, \
+					    (char *(*)())func, \
+					    (void (*)())free_func, \
+					    ex_tag,ex_class); }
+
+typedef struct asn1_ctx_st
+	{
+	unsigned char *p;/* work char pointer */
+	int eos;	/* end of sequence read for indefinite encoding */
+	int error;	/* error code to use when returning an error */
+	int inf;	/* constructed if 0x20, indefinite is 0x21 */
+	int tag;	/* tag from last 'get object' */
+	int xclass;	/* class from last 'get object' */
+	long slen;	/* length of last 'get object' */
+	unsigned char *max; /* largest value of p allowed */
+	unsigned char *q;/* temporary variable */
+	unsigned char **pp;/* variable */
+	int line;	/* used in error processing */
+	} ASN1_CTX;
+
+/* These are used internally in the ASN1_OBJECT to keep track of
+ * whether the names and data need to be free()ed */
+#define ASN1_OBJECT_FLAG_DYNAMIC	 0x01	/* internal use */
+#define ASN1_OBJECT_FLAG_CRITICAL	 0x02	/* critical x509v3 object id */
+#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04	/* internal use */
+#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 	 0x08	/* internal use */
+typedef struct asn1_object_st
+	{
+	const char *sn,*ln;
+	int nid;
+	int length;
+	unsigned char *data;
+	int flags;	/* Should we free this one */
+	} ASN1_OBJECT;
+
+#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
+/* This is the base type that holds just about everything :-) */
+typedef struct asn1_string_st
+	{
+	int length;
+	int type;
+	unsigned char *data;
+	/* The value of the following field depends on the type being
+	 * held.  It is mostly being used for BIT_STRING so if the
+	 * input data has a non-zero 'unused bits' value, it will be
+	 * handled correctly */
+	long flags;
+	} ASN1_STRING;
+
+#define STABLE_FLAGS_MALLOC	0x01
+#define STABLE_NO_MASK		0x02
+#define DIRSTRING_TYPE	\
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+	int nid;
+	long minsize;
+	long maxsize;
+	unsigned long mask;
+	unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DECLARE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+#define ub_name				32768
+#define ub_common_name			64
+#define ub_locality_name		128
+#define ub_state_name			128
+#define ub_organization_name		64
+#define ub_organization_unit_name	64
+#define ub_title			64
+#define ub_email_address		128
+
+#ifdef NO_ASN1_TYPEDEFS
+#define ASN1_INTEGER		ASN1_STRING
+#define ASN1_ENUMERATED		ASN1_STRING
+#define ASN1_BIT_STRING		ASN1_STRING
+#define ASN1_OCTET_STRING	ASN1_STRING
+#define ASN1_PRINTABLESTRING	ASN1_STRING
+#define ASN1_T61STRING		ASN1_STRING
+#define ASN1_IA5STRING		ASN1_STRING
+#define ASN1_UTCTIME		ASN1_STRING
+#define ASN1_GENERALIZEDTIME	ASN1_STRING
+#define ASN1_TIME		ASN1_STRING
+#define ASN1_GENERALSTRING	ASN1_STRING
+#define ASN1_UNIVERSALSTRING	ASN1_STRING
+#define ASN1_BMPSTRING		ASN1_STRING
+#define ASN1_VISIBLESTRING	ASN1_STRING
+#define ASN1_UTF8STRING		ASN1_STRING
+#else
+typedef struct asn1_string_st ASN1_INTEGER;
+typedef struct asn1_string_st ASN1_ENUMERATED;
+typedef struct asn1_string_st ASN1_BIT_STRING;
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_PRINTABLESTRING;
+typedef struct asn1_string_st ASN1_T61STRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef struct asn1_string_st ASN1_GENERALSTRING;
+typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
+typedef struct asn1_string_st ASN1_BMPSTRING;
+typedef struct asn1_string_st ASN1_UTCTIME;
+typedef struct asn1_string_st ASN1_TIME;
+typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
+typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_string_st ASN1_UTF8STRING;
+#endif
+
+typedef int ASN1_NULL;
+
+typedef struct asn1_type_st
+	{
+	int type;
+	union	{
+		char *ptr;
+		ASN1_STRING *		asn1_string;
+		ASN1_OBJECT *		object;
+		ASN1_INTEGER *		integer;
+		ASN1_ENUMERATED *	enumerated;
+		ASN1_BIT_STRING *	bit_string;
+		ASN1_OCTET_STRING *	octet_string;
+		ASN1_PRINTABLESTRING *	printablestring;
+		ASN1_T61STRING *	t61string;
+		ASN1_IA5STRING *	ia5string;
+		ASN1_GENERALSTRING *	generalstring;
+		ASN1_BMPSTRING *	bmpstring;
+		ASN1_UNIVERSALSTRING *	universalstring;
+		ASN1_UTCTIME *		utctime;
+		ASN1_GENERALIZEDTIME *	generalizedtime;
+		ASN1_VISIBLESTRING *	visiblestring;
+		ASN1_UTF8STRING *	utf8string;
+		/* set and sequence are left complete and still
+		 * contain the set or sequence bytes */
+		ASN1_STRING *		set;
+		ASN1_STRING *		sequence;
+		} value;
+	} ASN1_TYPE;
+
+DECLARE_STACK_OF(ASN1_TYPE)
+DECLARE_ASN1_SET_OF(ASN1_TYPE)
+
+typedef struct asn1_method_st
+	{
+	int (*i2d)();
+	char *(*d2i)();
+	char *(*create)();
+	void (*destroy)();
+	} ASN1_METHOD;
+
+/* This is used when parsing some Netscape objects */
+typedef struct asn1_header_st
+	{
+	ASN1_OCTET_STRING *header;
+	char *data;
+	ASN1_METHOD *meth;
+	} ASN1_HEADER;
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+	int bitnum;
+	const char *lname;
+	const char *sname;
+} BIT_STRING_BITNAME;
+
+
+#define M_ASN1_STRING_length(x)	((x)->length)
+#define M_ASN1_STRING_length_set(x, n)	((x)->length = (n))
+#define M_ASN1_STRING_type(x)	((x)->type)
+#define M_ASN1_STRING_data(x)	((x)->data)
+
+/* Macros for string operations */
+#define M_ASN1_BIT_STRING_new()	(ASN1_BIT_STRING *)\
+		ASN1_STRING_type_new(V_ASN1_BIT_STRING)
+#define M_ASN1_BIT_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
+		ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+
+#define M_ASN1_INTEGER_new()	(ASN1_INTEGER *)\
+		ASN1_STRING_type_new(V_ASN1_INTEGER)
+#define M_ASN1_INTEGER_free(a)		ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_cmp(a,b)	ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+
+#define M_ASN1_ENUMERATED_new()	(ASN1_ENUMERATED *)\
+		ASN1_STRING_type_new(V_ASN1_ENUMERATED)
+#define M_ASN1_ENUMERATED_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_cmp(a,b)	ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+
+#define M_ASN1_OCTET_STRING_new()	(ASN1_OCTET_STRING *)\
+		ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
+#define M_ASN1_OCTET_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
+		ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+#define M_ASN1_OCTET_STRING_set(a,b,c)	ASN1_STRING_set((ASN1_STRING *)a,b,c)
+#define M_ASN1_OCTET_STRING_print(a,b)	ASN1_STRING_print(a,(ASN1_STRING *)b)
+#define M_i2d_ASN1_OCTET_STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
+		V_ASN1_UNIVERSAL)
+
+#define M_ASN1_PRINTABLE_new()	ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_PRINTABLE_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+		pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLE(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_PRINTABLESTRING| \
+			B_ASN1_T61STRING| \
+			B_ASN1_IA5STRING| \
+			B_ASN1_BIT_STRING| \
+			B_ASN1_UNIVERSALSTRING|\
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UTF8STRING|\
+			B_ASN1_UNKNOWN)
+
+#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_DIRECTORYSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+						pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DIRECTORYSTRING(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_PRINTABLESTRING| \
+			B_ASN1_TELETEXSTRING|\
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UNIVERSALSTRING|\
+			B_ASN1_UTF8STRING)
+
+#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+						pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DISPLAYTEXT(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_VISIBLESTRING| \
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UTF8STRING)
+
+#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
+		ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_ASN1_PRINTABLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
+		V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
+		(ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
+
+#define M_ASN1_T61STRING_new()	(ASN1_T61STRING *)\
+		ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_T61STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_T61STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
+		V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_T61STRING(a,pp,l) \
+		(ASN1_T61STRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
+
+#define M_ASN1_IA5STRING_new()	(ASN1_IA5STRING *)\
+		ASN1_STRING_type_new(V_ASN1_IA5STRING)
+#define M_ASN1_IA5STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_IA5STRING_dup(a)	\
+			(ASN1_IA5STRING *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_i2d_ASN1_IA5STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_IA5STRING(a,pp,l) \
+		(ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
+			B_ASN1_IA5STRING)
+
+#define M_ASN1_UTCTIME_new()	(ASN1_UTCTIME *)\
+		ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_UTCTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+
+#define M_ASN1_GENERALIZEDTIME_new()	(ASN1_GENERALIZEDTIME *)\
+		ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
+#define M_ASN1_GENERALIZEDTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
+	(ASN1_STRING *)a)
+
+#define M_ASN1_TIME_new()	(ASN1_TIME *)\
+		ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_TIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_TIME_dup(a) (ASN1_TIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+
+#define M_ASN1_GENERALSTRING_new()	(ASN1_GENERALSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
+#define M_ASN1_GENERALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_GENERALSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
+		(ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
+
+#define M_ASN1_UNIVERSALSTRING_new()	(ASN1_UNIVERSALSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
+#define M_ASN1_UNIVERSALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
+		(ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
+
+#define M_ASN1_BMPSTRING_new()	(ASN1_BMPSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_BMPSTRING)
+#define M_ASN1_BMPSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_BMPSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_BMPSTRING(a,pp,l) \
+		(ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
+
+#define M_ASN1_VISIBLESTRING_new()	(ASN1_VISIBLESTRING *)\
+		ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_ASN1_VISIBLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_VISIBLESTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
+		(ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
+
+#define M_ASN1_UTF8STRING_new()	(ASN1_UTF8STRING *)\
+		ASN1_STRING_type_new(V_ASN1_UTF8STRING)
+#define M_ASN1_UTF8STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UTF8STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UTF8STRING(a,pp,l) \
+		(ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
+
+  /* for the is_set parameter to i2d_ASN1_SET */
+#define IS_SEQUENCE	0
+#define IS_SET		1
+
+ASN1_TYPE *	ASN1_TYPE_new(void );
+void		ASN1_TYPE_free(ASN1_TYPE *a);
+int		i2d_ASN1_TYPE(ASN1_TYPE *a,unsigned char **pp);
+ASN1_TYPE *	d2i_ASN1_TYPE(ASN1_TYPE **a,unsigned char **pp,long length);
+int ASN1_TYPE_get(ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+
+ASN1_OBJECT *	ASN1_OBJECT_new(void );
+void		ASN1_OBJECT_free(ASN1_OBJECT *a);
+int		i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
+ASN1_OBJECT *	d2i_ASN1_OBJECT(ASN1_OBJECT **a,unsigned char **pp,
+			long length);
+
+DECLARE_STACK_OF(ASN1_OBJECT)
+DECLARE_ASN1_SET_OF(ASN1_OBJECT)
+
+ASN1_STRING *	ASN1_STRING_new(void);
+void		ASN1_STRING_free(ASN1_STRING *a);
+ASN1_STRING *	ASN1_STRING_dup(ASN1_STRING *a);
+ASN1_STRING *	ASN1_STRING_type_new(int type );
+int 		ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b);
+  /* Since this is used to store all sorts of things, via macros, for now, make
+     its data void * */
+int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+int ASN1_STRING_length(ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(ASN1_STRING *x);
+unsigned char * ASN1_STRING_data(ASN1_STRING *x);
+
+ASN1_BIT_STRING *	ASN1_BIT_STRING_new(void);
+void		ASN1_BIT_STRING_free(ASN1_BIT_STRING *a);
+int		i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
+ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,unsigned char **pp,
+			long length);
+int		ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
+			int length );
+int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+
+#ifdef HEADER_BIO_H
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+				BIT_STRING_BITNAME *tbl, int indent);
+#endif
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+				BIT_STRING_BITNAME *tbl);
+
+int		i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
+int 		d2i_ASN1_BOOLEAN(int *a,unsigned char **pp,long length);
+
+ASN1_INTEGER *	ASN1_INTEGER_new(void);
+void		ASN1_INTEGER_free(ASN1_INTEGER *a);
+int		i2d_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
+ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp,
+			long length);
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,unsigned char **pp,
+			long length);
+ASN1_INTEGER *	ASN1_INTEGER_dup(ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y);
+
+ASN1_ENUMERATED *	ASN1_ENUMERATED_new(void);
+void		ASN1_ENUMERATED_free(ASN1_ENUMERATED *a);
+int		i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a,unsigned char **pp);
+ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a,unsigned char **pp,
+			long length);
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, char *str); 
+
+int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, char *str); 
+
+ASN1_OCTET_STRING *	ASN1_OCTET_STRING_new(void);
+void		ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *a);
+int		i2d_ASN1_OCTET_STRING(ASN1_OCTET_STRING *a,unsigned char **pp);
+ASN1_OCTET_STRING *d2i_ASN1_OCTET_STRING(ASN1_OCTET_STRING **a,
+			unsigned char **pp,long length);
+ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *a);
+int 	ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b);
+int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, unsigned char *data, int len);
+
+ASN1_VISIBLESTRING *	ASN1_VISIBLESTRING_new(void);
+void		ASN1_VISIBLESTRING_free(ASN1_VISIBLESTRING *a);
+int	i2d_ASN1_VISIBLESTRING(ASN1_VISIBLESTRING *a,unsigned char **pp);
+ASN1_VISIBLESTRING *d2i_ASN1_VISIBLESTRING(ASN1_VISIBLESTRING **a,
+			unsigned char **pp,long length);
+
+ASN1_UTF8STRING *	ASN1_UTF8STRING_new(void);
+void		ASN1_UTF8STRING_free(ASN1_UTF8STRING *a);
+int		i2d_ASN1_UTF8STRING(ASN1_UTF8STRING *a,unsigned char **pp);
+ASN1_UTF8STRING *d2i_ASN1_UTF8STRING(ASN1_UTF8STRING **a,
+			unsigned char **pp,long length);
+
+ASN1_NULL *	ASN1_NULL_new(void);
+void		ASN1_NULL_free(ASN1_NULL *a);
+int		i2d_ASN1_NULL(ASN1_NULL *a,unsigned char **pp);
+ASN1_NULL *d2i_ASN1_NULL(ASN1_NULL **a, unsigned char **pp,long length);
+
+ASN1_BMPSTRING *	ASN1_BMPSTRING_new(void);
+void		ASN1_BMPSTRING_free(ASN1_BMPSTRING *a);
+int i2d_ASN1_BMPSTRING(ASN1_BMPSTRING *a, unsigned char **pp);
+ASN1_BMPSTRING *d2i_ASN1_BMPSTRING(ASN1_BMPSTRING **a, unsigned char **pp,
+	long length);
+
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+int i2d_ASN1_PRINTABLE(ASN1_STRING *a,unsigned char **pp);
+ASN1_STRING *d2i_ASN1_PRINTABLE(ASN1_STRING **a,
+	unsigned char **pp, long l);
+
+ASN1_PRINTABLESTRING *	ASN1_PRINTABLESTRING_new(void);
+void		ASN1_PRINTABLESTRING_free(ASN1_PRINTABLESTRING *a);
+ASN1_PRINTABLESTRING *d2i_ASN1_PRINTABLESTRING(ASN1_PRINTABLESTRING **a,
+	unsigned char **pp, long l);
+int i2d_ASN1_PRINTABLESTRING(ASN1_PRINTABLESTRING *a, unsigned char **pp);
+
+ASN1_STRING *	DIRECTORYSTRING_new(void);
+void		DIRECTORYSTRING_free(ASN1_STRING *a);
+int	i2d_DIRECTORYSTRING(ASN1_STRING *a,unsigned char **pp);
+ASN1_STRING *d2i_DIRECTORYSTRING(ASN1_STRING **a, unsigned char **pp,
+								 long length);
+
+ASN1_STRING *	DISPLAYTEXT_new(void);
+void		DISPLAYTEXT_free(ASN1_STRING *a);
+int	i2d_DISPLAYTEXT(ASN1_STRING *a,unsigned char **pp);
+ASN1_STRING *d2i_DISPLAYTEXT(ASN1_STRING **a, unsigned char **pp, long length);
+
+ASN1_T61STRING *	ASN1_T61STRING_new(void);
+void		ASN1_T61STRING_free(ASN1_IA5STRING *a);
+ASN1_T61STRING *d2i_ASN1_T61STRING(ASN1_T61STRING **a,
+	unsigned char **pp, long l);
+
+ASN1_IA5STRING *	ASN1_IA5STRING_new(void);
+void		ASN1_IA5STRING_free(ASN1_IA5STRING *a);
+int i2d_ASN1_IA5STRING(ASN1_IA5STRING *a,unsigned char **pp);
+ASN1_IA5STRING *d2i_ASN1_IA5STRING(ASN1_IA5STRING **a,
+	unsigned char **pp, long l);
+
+ASN1_UTCTIME *	ASN1_UTCTIME_new(void);
+void		ASN1_UTCTIME_free(ASN1_UTCTIME *a);
+int		i2d_ASN1_UTCTIME(ASN1_UTCTIME *a,unsigned char **pp);
+ASN1_UTCTIME *	d2i_ASN1_UTCTIME(ASN1_UTCTIME **a,unsigned char **pp,
+			long length);
+
+ASN1_GENERALIZEDTIME *	ASN1_GENERALIZEDTIME_new(void);
+void		ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *a);
+int		i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a,unsigned char **pp);
+ASN1_GENERALIZEDTIME *	d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,unsigned char **pp,
+			long length);
+
+ASN1_TIME *	ASN1_TIME_new(void);
+void		ASN1_TIME_free(ASN1_TIME *a);
+int		i2d_ASN1_TIME(ASN1_TIME *a,unsigned char **pp);
+ASN1_TIME *	d2i_ASN1_TIME(ASN1_TIME **a,unsigned char **pp, long length);
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
+
+int		i2d_ASN1_SET(STACK *a, unsigned char **pp,
+			int (*func)(), int ex_tag, int ex_class, int is_set);
+STACK *		d2i_ASN1_SET(STACK **a, unsigned char **pp, long length,
+			char *(*func)(), void (*free_func)(),
+			int ex_tag, int ex_class);
+
+#ifdef HEADER_BIO_H
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
+int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
+#endif
+int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
+	char *sn, char *ln);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(unsigned char *s, int max);
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, unsigned char **pp,
+	long length, int Ptag, int Pclass);
+/* type is one or more of the B_ASN1_ values. */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,unsigned char **pp,
+		long length,int type);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(unsigned char **pp, long *plength, int *ptag,
+	int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p,long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+	int tag, int xclass);
+int ASN1_object_size(int constructed, int length, int tag);
+
+/* Used to implement other functions */
+char *ASN1_dup(int (*i2d)(),char *(*d2i)(),char *x);
+
+#ifndef NO_FP_API
+char *ASN1_d2i_fp(char *(*xnew)(),char *(*d2i)(),FILE *fp,unsigned char **x);
+int ASN1_i2d_fp(int (*i2d)(),FILE *out,unsigned char *x);
+#endif
+
+#ifdef HEADER_BIO_H
+char *ASN1_d2i_bio(char *(*xnew)(),char *(*d2i)(),BIO *bp,unsigned char **x);
+int ASN1_i2d_bio(int (*i2d)(),BIO *out,unsigned char *x);
+int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp,ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp,ASN1_STRING *v);
+int ASN1_parse(BIO *bp,unsigned char *pp,long len,int indent);
+#endif
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write netscape format cert/key */
+int i2d_ASN1_HEADER(ASN1_HEADER *a,unsigned char **pp);
+ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,unsigned char **pp, long length);
+ASN1_HEADER *ASN1_HEADER_new(void );
+void ASN1_HEADER_free(ASN1_HEADER *a);
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+void ERR_load_ASN1_strings(void);
+
+/* Not used that much at this point, except for the first two */
+ASN1_METHOD *X509_asn1_meth(void);
+ASN1_METHOD *RSAPrivateKey_asn1_meth(void);
+ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void);
+ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
+	unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
+	unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+	unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
+	unsigned char *data, int max_len);
+
+STACK *ASN1_seq_unpack(unsigned char *buf, int len, char *(*d2i)(),
+						 void (*free_func)() ); 
+unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf,
+								 int *len );
+void *ASN1_unpack_string(ASN1_STRING *oct, char *(*d2i)());
+ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask, 
+					long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, 
+		const unsigned char *in, int inlen, int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the ASN1 functions. */
+
+/* Function codes. */
+#define ASN1_F_A2D_ASN1_OBJECT				 100
+#define ASN1_F_A2I_ASN1_ENUMERATED			 236
+#define ASN1_F_A2I_ASN1_INTEGER				 101
+#define ASN1_F_A2I_ASN1_STRING				 102
+#define ASN1_F_ACCESS_DESCRIPTION_NEW			 291
+#define ASN1_F_ASN1_COLLATE_PRIMITIVE			 103
+#define ASN1_F_ASN1_D2I_BIO				 104
+#define ASN1_F_ASN1_D2I_FP				 105
+#define ASN1_F_ASN1_DUP					 106
+#define ASN1_F_ASN1_ENUMERATED_SET			 232
+#define ASN1_F_ASN1_ENUMERATED_TO_BN			 233
+#define ASN1_F_ASN1_GENERALIZEDTIME_NEW			 222
+#define ASN1_F_ASN1_GET_OBJECT				 107
+#define ASN1_F_ASN1_HEADER_NEW				 108
+#define ASN1_F_ASN1_I2D_BIO				 109
+#define ASN1_F_ASN1_I2D_FP				 110
+#define ASN1_F_ASN1_INTEGER_SET				 111
+#define ASN1_F_ASN1_INTEGER_TO_BN			 112
+#define ASN1_F_ASN1_MBSTRING_COPY			 282
+#define ASN1_F_ASN1_OBJECT_NEW				 113
+#define ASN1_F_ASN1_PACK_STRING				 245
+#define ASN1_F_ASN1_PBE_SET				 253
+#define ASN1_F_ASN1_SEQ_PACK				 246
+#define ASN1_F_ASN1_SEQ_UNPACK				 247
+#define ASN1_F_ASN1_SIGN				 114
+#define ASN1_F_ASN1_STRING_NEW				 115
+#define ASN1_F_ASN1_STRING_TABLE_ADD			 283
+#define ASN1_F_ASN1_STRING_TYPE_NEW			 116
+#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING		 117
+#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING		 118
+#define ASN1_F_ASN1_TYPE_NEW				 119
+#define ASN1_F_ASN1_UNPACK_STRING			 248
+#define ASN1_F_ASN1_UTCTIME_NEW				 120
+#define ASN1_F_ASN1_VERIFY				 121
+#define ASN1_F_AUTHORITY_KEYID_NEW			 237
+#define ASN1_F_BASIC_CONSTRAINTS_NEW			 226
+#define ASN1_F_BN_TO_ASN1_ENUMERATED			 234
+#define ASN1_F_BN_TO_ASN1_INTEGER			 122
+#define ASN1_F_D2I_ACCESS_DESCRIPTION			 284
+#define ASN1_F_D2I_ASN1_BIT_STRING			 123
+#define ASN1_F_D2I_ASN1_BMPSTRING			 124
+#define ASN1_F_D2I_ASN1_BOOLEAN				 125
+#define ASN1_F_D2I_ASN1_BYTES				 126
+#define ASN1_F_D2I_ASN1_ENUMERATED			 235
+#define ASN1_F_D2I_ASN1_GENERALIZEDTIME			 223
+#define ASN1_F_D2I_ASN1_HEADER				 127
+#define ASN1_F_D2I_ASN1_INTEGER				 128
+#define ASN1_F_D2I_ASN1_NULL				 292
+#define ASN1_F_D2I_ASN1_OBJECT				 129
+#define ASN1_F_D2I_ASN1_OCTET_STRING			 130
+#define ASN1_F_D2I_ASN1_PRINT_TYPE			 131
+#define ASN1_F_D2I_ASN1_SET				 132
+#define ASN1_F_D2I_ASN1_TIME				 224
+#define ASN1_F_D2I_ASN1_TYPE				 133
+#define ASN1_F_D2I_ASN1_TYPE_BYTES			 134
+#define ASN1_F_D2I_ASN1_UINTEGER			 280
+#define ASN1_F_D2I_ASN1_UTCTIME				 135
+#define ASN1_F_D2I_ASN1_UTF8STRING			 266
+#define ASN1_F_D2I_ASN1_VISIBLESTRING			 267
+#define ASN1_F_D2I_AUTHORITY_KEYID			 238
+#define ASN1_F_D2I_BASIC_CONSTRAINTS			 227
+#define ASN1_F_D2I_DHPARAMS				 136
+#define ASN1_F_D2I_DIST_POINT				 276
+#define ASN1_F_D2I_DIST_POINT_NAME			 277
+#define ASN1_F_D2I_DSAPARAMS				 137
+#define ASN1_F_D2I_DSAPRIVATEKEY			 138
+#define ASN1_F_D2I_DSAPUBLICKEY				 139
+#define ASN1_F_D2I_GENERAL_NAME				 230
+#define ASN1_F_D2I_NETSCAPE_CERT_SEQUENCE		 228
+#define ASN1_F_D2I_NETSCAPE_PKEY			 140
+#define ASN1_F_D2I_NETSCAPE_RSA				 141
+#define ASN1_F_D2I_NETSCAPE_RSA_2			 142
+#define ASN1_F_D2I_NETSCAPE_SPKAC			 143
+#define ASN1_F_D2I_NETSCAPE_SPKI			 144
+#define ASN1_F_D2I_NOTICEREF				 268
+#define ASN1_F_D2I_OTHERNAME				 287
+#define ASN1_F_D2I_PBE2PARAM				 262
+#define ASN1_F_D2I_PBEPARAM				 249
+#define ASN1_F_D2I_PBKDF2PARAM				 263
+#define ASN1_F_D2I_PKCS12				 254
+#define ASN1_F_D2I_PKCS12_BAGS				 255
+#define ASN1_F_D2I_PKCS12_MAC_DATA			 256
+#define ASN1_F_D2I_PKCS12_SAFEBAG			 257
+#define ASN1_F_D2I_PKCS7				 145
+#define ASN1_F_D2I_PKCS7_DIGEST				 146
+#define ASN1_F_D2I_PKCS7_ENCRYPT			 147
+#define ASN1_F_D2I_PKCS7_ENC_CONTENT			 148
+#define ASN1_F_D2I_PKCS7_ENVELOPE			 149
+#define ASN1_F_D2I_PKCS7_ISSUER_AND_SERIAL		 150
+#define ASN1_F_D2I_PKCS7_RECIP_INFO			 151
+#define ASN1_F_D2I_PKCS7_SIGNED				 152
+#define ASN1_F_D2I_PKCS7_SIGNER_INFO			 153
+#define ASN1_F_D2I_PKCS7_SIGN_ENVELOPE			 154
+#define ASN1_F_D2I_PKCS8_PRIV_KEY_INFO			 250
+#define ASN1_F_D2I_PKEY_USAGE_PERIOD			 239
+#define ASN1_F_D2I_POLICYINFO				 269
+#define ASN1_F_D2I_POLICYQUALINFO			 270
+#define ASN1_F_D2I_PRIVATEKEY				 155
+#define ASN1_F_D2I_PUBLICKEY				 156
+#define ASN1_F_D2I_RSAPRIVATEKEY			 157
+#define ASN1_F_D2I_RSAPUBLICKEY				 158
+#define ASN1_F_D2I_SXNET				 241
+#define ASN1_F_D2I_SXNETID				 243
+#define ASN1_F_D2I_USERNOTICE				 271
+#define ASN1_F_D2I_X509					 159
+#define ASN1_F_D2I_X509_ALGOR				 160
+#define ASN1_F_D2I_X509_ATTRIBUTE			 161
+#define ASN1_F_D2I_X509_CERT_AUX			 285
+#define ASN1_F_D2I_X509_CINF				 162
+#define ASN1_F_D2I_X509_CRL				 163
+#define ASN1_F_D2I_X509_CRL_INFO			 164
+#define ASN1_F_D2I_X509_EXTENSION			 165
+#define ASN1_F_D2I_X509_KEY				 166
+#define ASN1_F_D2I_X509_NAME				 167
+#define ASN1_F_D2I_X509_NAME_ENTRY			 168
+#define ASN1_F_D2I_X509_PKEY				 169
+#define ASN1_F_D2I_X509_PUBKEY				 170
+#define ASN1_F_D2I_X509_REQ				 171
+#define ASN1_F_D2I_X509_REQ_INFO			 172
+#define ASN1_F_D2I_X509_REVOKED				 173
+#define ASN1_F_D2I_X509_SIG				 174
+#define ASN1_F_D2I_X509_VAL				 175
+#define ASN1_F_DIST_POINT_NAME_NEW			 278
+#define ASN1_F_DIST_POINT_NEW				 279
+#define ASN1_F_GENERAL_NAME_NEW				 231
+#define ASN1_F_I2D_ASN1_HEADER				 176
+#define ASN1_F_I2D_ASN1_TIME				 225
+#define ASN1_F_I2D_DHPARAMS				 177
+#define ASN1_F_I2D_DSAPARAMS				 178
+#define ASN1_F_I2D_DSAPRIVATEKEY			 179
+#define ASN1_F_I2D_DSAPUBLICKEY				 180
+#define ASN1_F_I2D_DSA_PUBKEY				 290
+#define ASN1_F_I2D_NETSCAPE_RSA				 181
+#define ASN1_F_I2D_PKCS7				 182
+#define ASN1_F_I2D_PRIVATEKEY				 183
+#define ASN1_F_I2D_PUBLICKEY				 184
+#define ASN1_F_I2D_RSAPRIVATEKEY			 185
+#define ASN1_F_I2D_RSAPUBLICKEY				 186
+#define ASN1_F_I2D_RSA_PUBKEY				 289
+#define ASN1_F_I2D_X509_ATTRIBUTE			 187
+#define ASN1_F_I2T_ASN1_OBJECT				 188
+#define ASN1_F_NETSCAPE_CERT_SEQUENCE_NEW		 229
+#define ASN1_F_NETSCAPE_PKEY_NEW			 189
+#define ASN1_F_NETSCAPE_SPKAC_NEW			 190
+#define ASN1_F_NETSCAPE_SPKI_NEW			 191
+#define ASN1_F_NOTICEREF_NEW				 272
+#define ASN1_F_OTHERNAME_NEW				 288
+#define ASN1_F_PBE2PARAM_NEW				 264
+#define ASN1_F_PBEPARAM_NEW				 251
+#define ASN1_F_PBKDF2PARAM_NEW				 265
+#define ASN1_F_PKCS12_BAGS_NEW				 258
+#define ASN1_F_PKCS12_MAC_DATA_NEW			 259
+#define ASN1_F_PKCS12_NEW				 260
+#define ASN1_F_PKCS12_SAFEBAG_NEW			 261
+#define ASN1_F_PKCS5_PBE2_SET				 281
+#define ASN1_F_PKCS7_DIGEST_NEW				 192
+#define ASN1_F_PKCS7_ENCRYPT_NEW			 193
+#define ASN1_F_PKCS7_ENC_CONTENT_NEW			 194
+#define ASN1_F_PKCS7_ENVELOPE_NEW			 195
+#define ASN1_F_PKCS7_ISSUER_AND_SERIAL_NEW		 196
+#define ASN1_F_PKCS7_NEW				 197
+#define ASN1_F_PKCS7_RECIP_INFO_NEW			 198
+#define ASN1_F_PKCS7_SIGNED_NEW				 199
+#define ASN1_F_PKCS7_SIGNER_INFO_NEW			 200
+#define ASN1_F_PKCS7_SIGN_ENVELOPE_NEW			 201
+#define ASN1_F_PKCS8_PRIV_KEY_INFO_NEW			 252
+#define ASN1_F_PKEY_USAGE_PERIOD_NEW			 240
+#define ASN1_F_POLICYINFO_NEW				 273
+#define ASN1_F_POLICYQUALINFO_NEW			 274
+#define ASN1_F_SXNETID_NEW				 244
+#define ASN1_F_SXNET_NEW				 242
+#define ASN1_F_USERNOTICE_NEW				 275
+#define ASN1_F_X509_ALGOR_NEW				 202
+#define ASN1_F_X509_ATTRIBUTE_NEW			 203
+#define ASN1_F_X509_CERT_AUX_NEW			 286
+#define ASN1_F_X509_CINF_NEW				 204
+#define ASN1_F_X509_CRL_INFO_NEW			 205
+#define ASN1_F_X509_CRL_NEW				 206
+#define ASN1_F_X509_DHPARAMS_NEW			 207
+#define ASN1_F_X509_EXTENSION_NEW			 208
+#define ASN1_F_X509_INFO_NEW				 209
+#define ASN1_F_X509_KEY_NEW				 210
+#define ASN1_F_X509_NAME_ENTRY_NEW			 211
+#define ASN1_F_X509_NAME_NEW				 212
+#define ASN1_F_X509_NEW					 213
+#define ASN1_F_X509_PKEY_NEW				 214
+#define ASN1_F_X509_PUBKEY_NEW				 215
+#define ASN1_F_X509_REQ_INFO_NEW			 216
+#define ASN1_F_X509_REQ_NEW				 217
+#define ASN1_F_X509_REVOKED_NEW				 218
+#define ASN1_F_X509_SIG_NEW				 219
+#define ASN1_F_X509_VAL_FREE				 220
+#define ASN1_F_X509_VAL_NEW				 221
+
+/* Reason codes. */
+#define ASN1_R_BAD_CLASS				 100
+#define ASN1_R_BAD_OBJECT_HEADER			 101
+#define ASN1_R_BAD_PASSWORD_READ			 102
+#define ASN1_R_BAD_PKCS7_CONTENT			 103
+#define ASN1_R_BAD_PKCS7_TYPE				 104
+#define ASN1_R_BAD_TAG					 105
+#define ASN1_R_BAD_TYPE					 106
+#define ASN1_R_BN_LIB					 107
+#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 108
+#define ASN1_R_BUFFER_TOO_SMALL				 109
+#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 166
+#define ASN1_R_DATA_IS_WRONG				 110
+#define ASN1_R_DECODE_ERROR				 155
+#define ASN1_R_DECODING_ERROR				 111
+#define ASN1_R_ENCODE_ERROR				 156
+#define ASN1_R_ERROR_PARSING_SET_ELEMENT		 112
+#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS		 157
+#define ASN1_R_EXPECTING_AN_ENUMERATED			 154
+#define ASN1_R_EXPECTING_AN_INTEGER			 113
+#define ASN1_R_EXPECTING_AN_OBJECT			 114
+#define ASN1_R_EXPECTING_AN_OCTET_STRING		 115
+#define ASN1_R_EXPECTING_A_BIT_STRING			 116
+#define ASN1_R_EXPECTING_A_BOOLEAN			 117
+#define ASN1_R_EXPECTING_A_GENERALIZEDTIME		 151
+#define ASN1_R_EXPECTING_A_NULL				 164
+#define ASN1_R_EXPECTING_A_TIME				 152
+#define ASN1_R_EXPECTING_A_UTCTIME			 118
+#define ASN1_R_FIRST_NUM_TOO_LARGE			 119
+#define ASN1_R_GENERALIZEDTIME_TOO_LONG			 153
+#define ASN1_R_HEADER_TOO_LONG				 120
+#define ASN1_R_ILLEGAL_CHARACTERS			 158
+#define ASN1_R_INVALID_BMPSTRING_LENGTH			 159
+#define ASN1_R_INVALID_DIGIT				 121
+#define ASN1_R_INVALID_SEPARATOR			 122
+#define ASN1_R_INVALID_TIME_FORMAT			 123
+#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH		 160
+#define ASN1_R_INVALID_UTF8STRING			 161
+#define ASN1_R_IV_TOO_LARGE				 124
+#define ASN1_R_LENGTH_ERROR				 125
+#define ASN1_R_MISSING_SECOND_NUMBER			 126
+#define ASN1_R_NON_HEX_CHARACTERS			 127
+#define ASN1_R_NOT_ENOUGH_DATA				 128
+#define ASN1_R_NULL_IS_WRONG_LENGTH			 165
+#define ASN1_R_ODD_NUMBER_OF_CHARS			 129
+#define ASN1_R_PARSING					 130
+#define ASN1_R_PRIVATE_KEY_HEADER_MISSING		 131
+#define ASN1_R_SECOND_NUMBER_TOO_LARGE			 132
+#define ASN1_R_SHORT_LINE				 133
+#define ASN1_R_STRING_TOO_LONG				 163
+#define ASN1_R_STRING_TOO_SHORT				 134
+#define ASN1_R_TAG_VALUE_TOO_HIGH			 135
+#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 136
+#define ASN1_R_TOO_LONG					 137
+#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 138
+#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 139
+#define ASN1_R_UNKNOWN_ATTRIBUTE_TYPE			 140
+#define ASN1_R_UNKNOWN_FORMAT				 162
+#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 141
+#define ASN1_R_UNKNOWN_OBJECT_TYPE			 142
+#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE			 143
+#define ASN1_R_UNSUPPORTED_CIPHER			 144
+#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM		 145
+#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE		 146
+#define ASN1_R_UTCTIME_TOO_LONG				 147
+#define ASN1_R_WRONG_PRINTABLE_TYPE			 148
+#define ASN1_R_WRONG_TAG				 149
+#define ASN1_R_WRONG_TYPE				 150
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/bio.h b/AppleCSP/open_ssl/openssl/bio.h
new file mode 100644
index 00000000..0c96f118
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/bio.h
@@ -0,0 +1,685 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bio/bio.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BIO_H
+#define HEADER_BIO_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+
+/* These are the 'types' of BIOs */
+#define BIO_TYPE_NONE		0
+#define BIO_TYPE_MEM		(1|0x0400)
+#define BIO_TYPE_FILE		(2|0x0400)
+
+#define BIO_TYPE_FD		(4|0x0400|0x0100)
+#define BIO_TYPE_SOCKET		(5|0x0400|0x0100)
+#define BIO_TYPE_NULL		(6|0x0400)
+#define BIO_TYPE_SSL		(7|0x0200)
+#define BIO_TYPE_MD		(8|0x0200)		/* passive filter */
+#define BIO_TYPE_BUFFER		(9|0x0200)		/* filter */
+#define BIO_TYPE_CIPHER		(10|0x0200)		/* filter */
+#define BIO_TYPE_BASE64		(11|0x0200)		/* filter */
+#define BIO_TYPE_CONNECT	(12|0x0400|0x0100)	/* socket - connect */
+#define BIO_TYPE_ACCEPT		(13|0x0400|0x0100)	/* socket for accept */
+#define BIO_TYPE_PROXY_CLIENT	(14|0x0200)		/* client proxy BIO */
+#define BIO_TYPE_PROXY_SERVER	(15|0x0200)		/* server proxy BIO */
+#define BIO_TYPE_NBIO_TEST	(16|0x0200)		/* server proxy BIO */
+#define BIO_TYPE_NULL_FILTER	(17|0x0200)
+#define BIO_TYPE_BER		(18|0x0200)		/* BER -> bin filter */
+#define BIO_TYPE_BIO		(19|0x0400)		/* (half a) BIO pair */
+
+#define BIO_TYPE_DESCRIPTOR	0x0100	/* socket, fd, connect or accept */
+#define BIO_TYPE_FILTER		0x0200
+#define BIO_TYPE_SOURCE_SINK	0x0400
+
+/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE); */
+#define BIO_NOCLOSE		0x00
+#define BIO_CLOSE		0x01
+
+/* These are used in the following macros and are passed to
+ * BIO_ctrl() */
+#define BIO_CTRL_RESET		1  /* opt - rewind/zero etc */
+#define BIO_CTRL_EOF		2  /* opt - are we at the eof */
+#define BIO_CTRL_INFO		3  /* opt - extra tit-bits */
+#define BIO_CTRL_SET		4  /* man - set the 'IO' type */
+#define BIO_CTRL_GET		5  /* man - get the 'IO' type */
+#define BIO_CTRL_PUSH		6  /* opt - internal, used to signify change */
+#define BIO_CTRL_POP		7  /* opt - internal, used to signify change */
+#define BIO_CTRL_GET_CLOSE	8  /* man - set the 'close' on free */
+#define BIO_CTRL_SET_CLOSE	9  /* man - set the 'close' on free */
+#define BIO_CTRL_PENDING	10  /* opt - is their more data buffered */
+#define BIO_CTRL_FLUSH		11  /* opt - 'flush' buffered output */
+#define BIO_CTRL_DUP		12  /* man - extra stuff for 'duped' BIO */
+#define BIO_CTRL_WPENDING	13  /* opt - number of bytes still to write */
+/* callback is int cb(BIO *bio,state,ret); */
+#define BIO_CTRL_SET_CALLBACK	14  /* opt - set callback function */
+#define BIO_CTRL_GET_CALLBACK	15  /* opt - set callback function */
+
+#define BIO_CTRL_SET_FILENAME	30	/* BIO_s_file special */
+
+/* modifiers */
+#define BIO_FP_READ		0x02
+#define BIO_FP_WRITE		0x04
+#define BIO_FP_APPEND		0x08
+#define BIO_FP_TEXT		0x10
+
+#define BIO_FLAGS_READ		0x01
+#define BIO_FLAGS_WRITE		0x02
+#define BIO_FLAGS_IO_SPECIAL	0x04
+#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+#define BIO_FLAGS_SHOULD_RETRY	0x08
+
+/* Used in BIO_gethostbyname() */
+#define BIO_GHBN_CTRL_HITS		1
+#define BIO_GHBN_CTRL_MISSES		2
+#define BIO_GHBN_CTRL_CACHE_SIZE	3
+#define BIO_GHBN_CTRL_GET_ENTRY		4
+#define BIO_GHBN_CTRL_FLUSH		5
+
+/* Mostly used in the SSL BIO */
+/* Not used anymore
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
+ * #define BIO_FLAGS_PROTOCOL_STARTUP	0x40
+ */
+
+#define BIO_FLAGS_BASE64_NO_NL	0x100
+
+/* This is used with memory BIOs: it means we shouldn't free up or change the
+ * data in any way.
+ */
+#define BIO_FLAGS_MEM_RDONLY	0x200
+
+#define BIO_set_flags(b,f) ((b)->flags|=(f))
+#define BIO_get_flags(b) ((b)->flags)
+#define BIO_set_retry_special(b) \
+		((b)->flags|=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_read(b) \
+		((b)->flags|=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_write(b) \
+		((b)->flags|=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+#define BIO_clear_flags(b,f) ((b)->flags&= ~(f))
+#define BIO_clear_retry_flags(b) \
+		((b)->flags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_get_retry_flags(b) \
+		((b)->flags&(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These should be used by the application to tell why we should retry */
+#define BIO_should_read(a)		((a)->flags & BIO_FLAGS_READ)
+#define BIO_should_write(a)		((a)->flags & BIO_FLAGS_WRITE)
+#define BIO_should_io_special(a)	((a)->flags & BIO_FLAGS_IO_SPECIAL)
+#define BIO_retry_type(a)		((a)->flags & BIO_FLAGS_RWS)
+#define BIO_should_retry(a)		((a)->flags & BIO_FLAGS_SHOULD_RETRY)
+
+/* The next two are used in conjunction with the
+ * BIO_should_io_special() condition.  After this returns true,
+ * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO 
+ * stack and return the 'reason' for the special and the offending BIO.
+ * Given a BIO, BIO_get_retry_reason(bio) will return the code. */
+/* Returned from the SSL bio when the certificate retrieval code had an error */
+#define BIO_RR_SSL_X509_LOOKUP		0x01
+/* Returned from the connect BIO when a connect would have blocked */
+#define BIO_RR_CONNECT			0x02
+
+/* These are passed by the BIO callback */
+#define BIO_CB_FREE	0x01
+#define BIO_CB_READ	0x02
+#define BIO_CB_WRITE	0x03
+#define BIO_CB_PUTS	0x04
+#define BIO_CB_GETS	0x05
+#define BIO_CB_CTRL	0x06
+
+/* The callback is called before and after the underling operation,
+ * The BIO_CB_RETURN flag indicates if it is after the call */
+#define BIO_CB_RETURN	0x80
+#define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
+#define BIO_cb_pre(a)	(!((a)&BIO_CB_RETURN))
+#define BIO_cb_post(a)	((a)&BIO_CB_RETURN)
+
+#define BIO_set_callback(b,cb)		((b)->callback=(cb))
+#define BIO_set_callback_arg(b,arg)	((b)->cb_arg=(char *)(arg))
+#define BIO_get_callback_arg(b)		((b)->cb_arg)
+#define BIO_get_callback(b)		((b)->callback)
+#define BIO_method_name(b)		((b)->method->name)
+#define BIO_method_type(b)		((b)->method->type)
+
+#ifndef WIN16
+typedef struct bio_method_st
+	{
+	int type;
+	const char *name;
+	int (*bwrite)();
+	int (*bread)();
+	int (*bputs)();
+	int (*bgets)();
+	long (*ctrl)();
+	int (*create)();
+	int (*destroy)();
+	long (*callback_ctrl)();
+	} BIO_METHOD;
+#else
+typedef struct bio_method_st
+	{
+	int type;
+	const char *name;
+	int (_far *bwrite)();
+	int (_far *bread)();
+	int (_far *bputs)();
+	int (_far *bgets)();
+	long (_far *ctrl)();
+	int (_far *create)();
+	int (_far *destroy)();
+	long (_fat *callback_ctrl)();
+	} BIO_METHOD;
+#endif
+
+typedef struct bio_st
+	{
+	const BIO_METHOD *method;
+	/* bio, mode, argp, argi, argl, ret */
+	long (*callback)(struct bio_st *,int,const char *,int, long,long);
+	char *cb_arg; /* first argument for the callback */
+
+	int init;
+	int shutdown;
+	int flags;	/* extra storage */
+	int retry_reason;
+	int num;
+	void *ptr;
+	struct bio_st *next_bio;	/* used by filter BIOs */
+	struct bio_st *prev_bio;	/* used by filter BIOs */
+	int references;
+	unsigned long num_read;
+	unsigned long num_write;
+
+	CRYPTO_EX_DATA ex_data;
+	} BIO;
+
+typedef struct bio_f_buffer_ctx_struct
+	{
+	/* BIO *bio; */ /* this is now in the BIO struct */
+	int ibuf_size;	/* how big is the input buffer */
+	int obuf_size;	/* how big is the output buffer */
+
+	char *ibuf;		/* the char array */
+	int ibuf_len;		/* how many bytes are in it */
+	int ibuf_off;		/* write/read offset */
+
+	char *obuf;		/* the char array */
+	int obuf_len;		/* how many bytes are in it */
+	int obuf_off;		/* write/read offset */
+	} BIO_F_BUFFER_CTX;
+
+/* connect BIO stuff */
+#define BIO_CONN_S_BEFORE		1
+#define BIO_CONN_S_GET_IP		2
+#define BIO_CONN_S_GET_PORT		3
+#define BIO_CONN_S_CREATE_SOCKET	4
+#define BIO_CONN_S_CONNECT		5
+#define BIO_CONN_S_OK			6
+#define BIO_CONN_S_BLOCKED_CONNECT	7
+#define BIO_CONN_S_NBIO			8
+/*#define BIO_CONN_get_param_hostname	BIO_ctrl */
+
+#define BIO_C_SET_CONNECT			100
+#define BIO_C_DO_STATE_MACHINE			101
+#define BIO_C_SET_NBIO				102
+#define BIO_C_SET_PROXY_PARAM			103
+#define BIO_C_SET_FD				104
+#define BIO_C_GET_FD				105
+#define BIO_C_SET_FILE_PTR			106
+#define BIO_C_GET_FILE_PTR			107
+#define BIO_C_SET_FILENAME			108
+#define BIO_C_SET_SSL				109
+#define BIO_C_GET_SSL				110
+#define BIO_C_SET_MD				111
+#define BIO_C_GET_MD				112
+#define BIO_C_GET_CIPHER_STATUS			113
+#define BIO_C_SET_BUF_MEM			114
+#define BIO_C_GET_BUF_MEM_PTR			115
+#define BIO_C_GET_BUFF_NUM_LINES		116
+#define BIO_C_SET_BUFF_SIZE			117
+#define BIO_C_SET_ACCEPT			118
+#define BIO_C_SSL_MODE				119
+#define BIO_C_GET_MD_CTX			120
+#define BIO_C_GET_PROXY_PARAM			121
+#define BIO_C_SET_BUFF_READ_DATA		122 /* data to read first */
+#define BIO_C_GET_CONNECT			123
+#define BIO_C_GET_ACCEPT			124
+#define BIO_C_SET_SSL_RENEGOTIATE_BYTES		125
+#define BIO_C_GET_SSL_NUM_RENEGOTIATES		126
+#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT	127
+#define BIO_C_FILE_SEEK				128
+#define BIO_C_GET_CIPHER_CTX			129
+#define BIO_C_SET_BUF_MEM_EOF_RETURN		130/*return end of input value*/
+#define BIO_C_SET_BIND_MODE			131
+#define BIO_C_GET_BIND_MODE			132
+#define BIO_C_FILE_TELL				133
+#define BIO_C_GET_SOCKS				134
+#define BIO_C_SET_SOCKS				135
+
+#define BIO_C_SET_WRITE_BUF_SIZE		136/* for BIO_s_bio */
+#define BIO_C_GET_WRITE_BUF_SIZE		137
+#define BIO_C_MAKE_BIO_PAIR			138
+#define BIO_C_DESTROY_BIO_PAIR			139
+#define BIO_C_GET_WRITE_GUARANTEE		140
+#define BIO_C_GET_READ_REQUEST			141
+#define BIO_C_SHUTDOWN_WR			142
+#define BIO_C_NREAD0				143
+#define BIO_C_NREAD				144
+#define BIO_C_NWRITE0				145
+#define BIO_C_NWRITE				146
+#define BIO_C_RESET_READ_REQUEST		147
+
+
+#define BIO_set_app_data(s,arg)		BIO_set_ex_data(s,0,arg)
+#define BIO_get_app_data(s)		BIO_get_ex_data(s,0)
+
+/* BIO_s_connect() and BIO_s_socks4a_connect() */
+#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
+#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
+#define BIO_set_conn_ip(b,ip)	  BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
+#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
+#define BIO_get_conn_hostname(b)  BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
+#define BIO_get_conn_port(b)      BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
+#define BIO_get_conn_ip(b,ip) BIO_ptr_ctrl(b,BIO_C_SET_CONNECT,2)
+#define BIO_get_conn_int_port(b,port) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,port)
+
+
+#define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+/* BIO_s_accept_socket() */
+#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
+#define BIO_get_accept_port(b)	BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
+/* #define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL)
+#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
+
+#define BIO_BIND_NORMAL			0
+#define BIO_BIND_REUSEADDR_IF_UNUSED	1
+#define BIO_BIND_REUSEADDR		2
+#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+#define BIO_do_connect(b)	BIO_do_handshake(b)
+#define BIO_do_accept(b)	BIO_do_handshake(b)
+#define BIO_do_handshake(b)	BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_proxy_client() */
+#define BIO_set_url(b,url)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
+#define BIO_set_proxies(b,p)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
+/* BIO_set_nbio(b,n) */
+#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
+/* BIO *BIO_get_filter_bio(BIO *bio); */
+#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
+#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
+#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
+
+#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
+#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
+#define BIO_get_url(b,url)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
+#define BIO_get_no_connect_return(b)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
+
+#define BIO_set_fd(b,fd,c)	BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+#define BIO_get_fd(b,c)		BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+#define BIO_set_fp(b,fp,c)	BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
+#define BIO_get_fp(b,fpp)	BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
+
+#define BIO_seek(b,ofs)	(int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+#define BIO_tell(b)	(int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/* name is cast to lose const, but might be better to route through a function
+   so we can do it safely */
+#ifdef CONST_STRICT
+/* If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b,const char *name);
+#else
+#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_READ,(char *)name)
+#endif
+#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_WRITE,name)
+#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_APPEND,name)
+#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/* WARNING WARNING, this ups the reference count on the read bio of the
+ * SSL structure.  This is because the ssl read BIO is now pointed to by
+ * the next_bio field in the bio.  So when you free the BIO, make sure
+ * you are doing a BIO_free_all() to catch the underlying BIO. */
+#define BIO_set_ssl(b,ssl,c)	BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+#define BIO_get_ssl(b,sslp)	BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+#define BIO_set_ssl_mode(b,client)	BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+#define BIO_set_ssl_renegotiate_bytes(b,num) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+#define BIO_get_num_renegotiates(b) \
+	BIO_ctrl(b,BIO_C_SET_SSL_NUM_RENEGOTIATES,0,NULL);
+#define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md)	BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
+
+#define BIO_get_mem_data(b,pp)	BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
+#define BIO_set_mem_buf(b,bm,c)	BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
+#define BIO_get_mem_ptr(b,pp)	BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
+#define BIO_set_mem_eof_return(b,v) \
+				BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+#define BIO_get_buffer_num_lines(b)	BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+#define BIO_set_buffer_size(b,size)	BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+#define BIO_dup_state(b,ret)	BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+#define BIO_reset(b)		(int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+#define BIO_eof(b)		(int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+#define BIO_set_close(b,c)	(int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+#define BIO_get_close(b)	(int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+#define BIO_pending(b)		(int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+#define BIO_wpending(b)		(int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+/* ...pending macros have inappropriate return type */
+size_t BIO_ctrl_pending(BIO *b);
+size_t BIO_ctrl_wpending(BIO *b);
+#define BIO_flush(b)		(int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0,(void (**)())(cbp))
+#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,(void (*)())(cb))
+
+/* For the BIO_f_buffer() type */
+#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+
+/* For BIO_s_bio() */
+#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+#define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+#define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+/* macros with inappropriate type -- but ...pending macros use int too: */
+#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+#define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+size_t BIO_ctrl_get_write_guarantee(BIO *b);
+size_t BIO_ctrl_get_read_request(BIO *b);
+int BIO_ctrl_reset_read_request(BIO *b);
+
+#ifdef NO_STDIO
+#define NO_FP_API
+#endif
+
+
+/* These two aren't currently implemented */
+/* int BIO_get_ex_num(BIO *bio); */
+/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
+int BIO_set_ex_data(BIO *bio,int idx,void *data);
+void *BIO_get_ex_data(BIO *bio,int idx);
+int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+unsigned long BIO_number_read(BIO *bio);
+unsigned long BIO_number_written(BIO *bio);
+
+#  if defined(WIN16) && defined(_WINDLL)
+BIO_METHOD *BIO_s_file_internal(void);
+BIO *BIO_new_file_internal(char *filename, char *mode);
+BIO *BIO_new_fp_internal(FILE *stream, int close_flag);
+#    define BIO_s_file	BIO_s_file_internal
+#    define BIO_new_file	BIO_new_file_internal
+#    define BIO_new_fp	BIO_new_fp_internal
+#  else /* FP_API */
+const BIO_METHOD *BIO_s_file(void );
+BIO *BIO_new_file(const char *filename, const char *mode);
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+#    define BIO_s_file_internal		BIO_s_file
+#    define BIO_new_file_internal	BIO_new_file
+#    define BIO_new_fp_internal		BIO_s_file
+#  endif /* FP_API */
+BIO *	BIO_new(const BIO_METHOD *type);
+int	BIO_set(BIO *a,const BIO_METHOD *type);
+int	BIO_free(BIO *a);
+int	BIO_read(BIO *b, void *data, int len);
+int	BIO_gets(BIO *bp,char *buf, int size);
+int	BIO_write(BIO *b, const void *data, int len);
+int	BIO_puts(BIO *bp,const char *buf);
+long	BIO_ctrl(BIO *bp,int cmd,long larg,void *parg);
+long	BIO_callback_ctrl(BIO *bp,int cmd,void (*fp)());
+char *	BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
+long	BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
+BIO *	BIO_push(BIO *b,BIO *append);
+BIO *	BIO_pop(BIO *b);
+void	BIO_free_all(BIO *a);
+BIO *	BIO_find_type(BIO *b,int bio_type);
+BIO *	BIO_get_retry_BIO(BIO *bio, int *reason);
+int	BIO_get_retry_reason(BIO *bio);
+BIO *	BIO_dup_chain(BIO *in);
+
+int BIO_nread0(BIO *bio, char **buf);
+int BIO_nread(BIO *bio, char **buf, int num);
+int BIO_nwrite0(BIO *bio, char **buf);
+int BIO_nwrite(BIO *bio, char **buf, int num);
+
+#ifndef WIN16
+long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+	long argl,long ret);
+#else
+long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+	long argl,long ret);
+#endif
+
+BIO_METHOD *BIO_s_mem(void);
+BIO *BIO_new_mem_buf(void *buf, int len);
+BIO_METHOD *BIO_s_socket(void);
+BIO_METHOD *BIO_s_connect(void);
+BIO_METHOD *BIO_s_accept(void);
+BIO_METHOD *BIO_s_fd(void);
+BIO_METHOD *BIO_s_log(void);
+BIO_METHOD *BIO_s_bio(void);
+BIO_METHOD *BIO_s_null(void);
+BIO_METHOD *BIO_f_null(void);
+BIO_METHOD *BIO_f_buffer(void);
+BIO_METHOD *BIO_f_nbio_test(void);
+/* BIO_METHOD *BIO_f_ber(void); */
+
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump(BIO *b,const char *bytes,int len);
+
+struct hostent *BIO_gethostbyname(const char *name);
+/* We might want a thread-safe interface too:
+ * struct hostent *BIO_gethostbyname_r(const char *name,
+ *     struct hostent *result, void *buffer, size_t buflen);
+ * or something similar (caller allocates a struct hostent,
+ * pointed to by "result", and additional buffer space for the various
+ * substructures; if the buffer does not suffice, NULL is returned
+ * and an appropriate error code is set).
+ */
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, unsigned long *arg);
+int BIO_socket_nbio(int fd,int mode);
+int BIO_get_port(const char *str, unsigned short *port_ptr);
+int BIO_get_host_ip(const char *str, unsigned char *ip);
+int BIO_get_accept_socket(char *host_port,int mode);
+int BIO_accept(int sock,char **ip_port);
+int BIO_sock_init(void );
+void BIO_sock_cleanup(void);
+int BIO_set_tcp_ndelay(int sock,int turn_on);
+
+void ERR_load_BIO_strings(void );
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_fd(int fd, int close_flag);
+BIO *BIO_new_connect(char *host_port);
+BIO *BIO_new_accept(char *host_port);
+
+int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
+	BIO **bio2, size_t writebuf2);
+/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
+ * Otherwise returns 0 and sets *bio1 and *bio2 to NULL.
+ * Size 0 uses default value.
+ */
+
+void BIO_copy_next_retry(BIO *b);
+
+long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);
+
+int BIO_printf(BIO *bio, ...);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the BIO functions. */
+
+/* Function codes. */
+#define BIO_F_ACPT_STATE				 100
+#define BIO_F_BIO_ACCEPT				 101
+#define BIO_F_BIO_BER_GET_HEADER			 102
+#define BIO_F_BIO_CTRL					 103
+#define BIO_F_BIO_GETHOSTBYNAME				 120
+#define BIO_F_BIO_GETS					 104
+#define BIO_F_BIO_GET_ACCEPT_SOCKET			 105
+#define BIO_F_BIO_GET_HOST_IP				 106
+#define BIO_F_BIO_GET_PORT				 107
+#define BIO_F_BIO_MAKE_PAIR				 121
+#define BIO_F_BIO_NEW					 108
+#define BIO_F_BIO_NEW_FILE				 109
+#define BIO_F_BIO_NEW_MEM_BUF				 126
+#define BIO_F_BIO_NREAD					 123
+#define BIO_F_BIO_NREAD0				 124
+#define BIO_F_BIO_NWRITE				 125
+#define BIO_F_BIO_NWRITE0				 122
+#define BIO_F_BIO_PUTS					 110
+#define BIO_F_BIO_READ					 111
+#define BIO_F_BIO_SOCK_INIT				 112
+#define BIO_F_BIO_WRITE					 113
+#define BIO_F_BUFFER_CTRL				 114
+#define BIO_F_CONN_CTRL					 127
+#define BIO_F_CONN_STATE				 115
+#define BIO_F_FILE_CTRL					 116
+#define BIO_F_MEM_WRITE					 117
+#define BIO_F_SSL_NEW					 118
+#define BIO_F_WSASTARTUP				 119
+
+/* Reason codes. */
+#define BIO_R_ACCEPT_ERROR				 100
+#define BIO_R_BAD_FOPEN_MODE				 101
+#define BIO_R_BAD_HOSTNAME_LOOKUP			 102
+#define BIO_R_BROKEN_PIPE				 124
+#define BIO_R_CONNECT_ERROR				 103
+#define BIO_R_ERROR_SETTING_NBIO			 104
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET	 105
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET	 106
+#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET		 107
+#define BIO_R_INVALID_ARGUMENT				 125
+#define BIO_R_INVALID_IP_ADDRESS			 108
+#define BIO_R_IN_USE					 123
+#define BIO_R_KEEPALIVE					 109
+#define BIO_R_NBIO_CONNECT_ERROR			 110
+#define BIO_R_NO_ACCEPT_PORT_SPECIFIED			 111
+#define BIO_R_NO_HOSTNAME_SPECIFIED			 112
+#define BIO_R_NO_PORT_DEFINED				 113
+#define BIO_R_NO_PORT_SPECIFIED				 114
+#define BIO_R_NULL_PARAMETER				 115
+#define BIO_R_TAG_MISMATCH				 116
+#define BIO_R_UNABLE_TO_BIND_SOCKET			 117
+#define BIO_R_UNABLE_TO_CREATE_SOCKET			 118
+#define BIO_R_UNABLE_TO_LISTEN_SOCKET			 119
+#define BIO_R_UNINITIALIZED				 120
+#define BIO_R_UNSUPPORTED_METHOD			 121
+#define BIO_R_WRITE_TO_READ_ONLY_BIO			 126
+#define BIO_R_WSASTARTUP				 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/bn.h b/AppleCSP/open_ssl/openssl/bn.h
new file mode 100644
index 00000000..faa5d072
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/bn.h
@@ -0,0 +1,530 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/bn/bn.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BN_H
+#define HEADER_BN_H
+
+#ifndef WIN16
+#include <stdio.h> /* FILE */
+#endif
+#include <openssl/opensslconf.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef VMS
+#undef BN_LLONG /* experimental, so far... */
+#endif
+
+#define BN_MUL_COMBA
+#define BN_SQR_COMBA
+#define BN_RECURSION
+#define RECP_MUL_MOD
+#define MONT_MUL_MOD
+
+/* This next option uses the C libraries (2 word)/(1 word) function.
+ * If it is not defined, I use my C version (which is slower).
+ * The reason for this flag is that when the particular C compiler
+ * library routine is used, and the library is linked with a different
+ * compiler, the library is missing.  This mostly happens when the
+ * library is built with gcc and then linked using normal cc.  This would
+ * be a common occurrence because gcc normally produces code that is
+ * 2 times faster than system compilers for the big number stuff.
+ * For machines with only one compiler (or shared libraries), this should
+ * be on.  Again this in only really a problem on machines
+ * using "long long's", are 32bit, and are not using my assembler code. */
+#if defined(MSDOS) || defined(WINDOWS) || defined(WIN32) || defined(linux)
+#define BN_DIV2W
+#endif
+
+/* assuming long is 64bit - this is the DEC Alpha
+ * unsigned long long is only 64 bits :-(, don't define
+ * BN_LLONG for the DEC Alpha */
+#ifdef SIXTY_FOUR_BIT_LONG
+#define BN_ULLONG	unsigned long long
+#define BN_ULONG	unsigned long
+#define BN_LONG		long
+#define BN_BITS		128
+#define BN_BYTES	8
+#define BN_BITS2	64
+#define BN_BITS4	32
+#define BN_MASK		(0xffffffffffffffffffffffffffffffffLL)
+#define BN_MASK2	(0xffffffffffffffffL)
+#define BN_MASK2l	(0xffffffffL)
+#define BN_MASK2h	(0xffffffff00000000L)
+#define BN_MASK2h1	(0xffffffff80000000L)
+#define BN_TBIT		(0x8000000000000000L)
+#define BN_DEC_CONV	(10000000000000000000UL)
+#define BN_DEC_FMT1	"%lu"
+#define BN_DEC_FMT2	"%019lu"
+#define BN_DEC_NUM	19
+#endif
+
+/* This is where the long long data type is 64 bits, but long is 32.
+ * For machines where there are 64bit registers, this is the mode to use.
+ * IRIX, on R4000 and above should use this mode, along with the relevant
+ * assembler code :-).  Do NOT define BN_LLONG.
+ */
+#ifdef SIXTY_FOUR_BIT
+#undef BN_LLONG
+#undef BN_ULLONG
+#define BN_ULONG	unsigned long long
+#define BN_LONG		long long
+#define BN_BITS		128
+#define BN_BYTES	8
+#define BN_BITS2	64
+#define BN_BITS4	32
+#define BN_MASK2	(0xffffffffffffffffLL)
+#define BN_MASK2l	(0xffffffffL)
+#define BN_MASK2h	(0xffffffff00000000LL)
+#define BN_MASK2h1	(0xffffffff80000000LL)
+#define BN_TBIT		(0x8000000000000000LL)
+#define BN_DEC_CONV	(10000000000000000000LL)
+#define BN_DEC_FMT1	"%llu"
+#define BN_DEC_FMT2	"%019llu"
+#define BN_DEC_NUM	19
+#endif
+
+#ifdef THIRTY_TWO_BIT
+#if defined(WIN32) && !defined(__GNUC__)
+#define BN_ULLONG	unsigned _int64
+#else
+#define BN_ULLONG	unsigned long long
+#endif
+#define BN_ULONG	unsigned long
+#define BN_LONG		long
+#define BN_BITS		64
+#define BN_BYTES	4
+#define BN_BITS2	32
+#define BN_BITS4	16
+#ifdef WIN32
+/* VC++ doesn't like the LL suffix */
+#define BN_MASK		(0xffffffffffffffffL)
+#else
+#define BN_MASK		(0xffffffffffffffffLL)
+#endif
+#define BN_MASK2	(0xffffffffL)
+#define BN_MASK2l	(0xffff)
+#define BN_MASK2h1	(0xffff8000L)
+#define BN_MASK2h	(0xffff0000L)
+#define BN_TBIT		(0x80000000L)
+#define BN_DEC_CONV	(1000000000L)
+#define BN_DEC_FMT1	"%lu"
+#define BN_DEC_FMT2	"%09lu"
+#define BN_DEC_NUM	9
+#endif
+
+#ifdef SIXTEEN_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG	unsigned long
+#define BN_ULONG	unsigned short
+#define BN_LONG		short
+#define BN_BITS		32
+#define BN_BYTES	2
+#define BN_BITS2	16
+#define BN_BITS4	8
+#define BN_MASK		(0xffffffff)
+#define BN_MASK2	(0xffff)
+#define BN_MASK2l	(0xff)
+#define BN_MASK2h1	(0xff80)
+#define BN_MASK2h	(0xff00)
+#define BN_TBIT		(0x8000)
+#define BN_DEC_CONV	(100000)
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%05u"
+#define BN_DEC_NUM	5
+#endif
+
+#ifdef EIGHT_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG	unsigned short
+#define BN_ULONG	unsigned char
+#define BN_LONG		char
+#define BN_BITS		16
+#define BN_BYTES	1
+#define BN_BITS2	8
+#define BN_BITS4	4
+#define BN_MASK		(0xffff)
+#define BN_MASK2	(0xff)
+#define BN_MASK2l	(0xf)
+#define BN_MASK2h1	(0xf8)
+#define BN_MASK2h	(0xf0)
+#define BN_TBIT		(0x80)
+#define BN_DEC_CONV	(100)
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%02u"
+#define BN_DEC_NUM	2
+#endif
+
+#define BN_DEFAULT_BITS	1280
+
+#ifdef BIGNUM
+#undef BIGNUM
+#endif
+
+#define BN_FLG_MALLOCED		0x01
+#define BN_FLG_STATIC_DATA	0x02
+#define BN_FLG_FREE		0x8000	/* used for debuging */
+#define BN_set_flags(b,n)	((b)->flags|=(n))
+#define BN_get_flags(b,n)	((b)->flags&(n))
+
+typedef struct bignum_st
+	{
+	BN_ULONG *d;	/* Pointer to an array of 'BN_BITS2' bit chunks. */
+	int top;	/* Index of last used d +1. */
+	/* The next are internal book keeping for bn_expand. */
+	int max;	/* Size of the d array. */
+	int neg;	/* one if the number is negative */
+	int flags;
+	} BIGNUM;
+
+/* Used for temp variables */
+#define BN_CTX_NUM	12
+#define BN_CTX_NUM_POS	12
+typedef struct bignum_ctx
+	{
+	int tos;
+	BIGNUM bn[BN_CTX_NUM];
+	int flags;
+	int depth;
+	int pos[BN_CTX_NUM_POS];
+	int too_many;
+	} BN_CTX;
+
+typedef struct bn_blinding_st
+	{
+	int init;
+	BIGNUM *A;
+	BIGNUM *Ai;
+	BIGNUM *mod; /* just a reference */
+	} BN_BLINDING;
+
+/* Used for montgomery multiplication */
+typedef struct bn_mont_ctx_st
+	{
+	int ri;        /* number of bits in R */
+	BIGNUM RR;     /* used to convert to montgomery form */
+	BIGNUM N;      /* The modulus */
+	BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
+	                * (Ni is only stored for bignum algorithm) */
+	BN_ULONG n0;   /* least significant word of Ni */
+	int flags;
+	} BN_MONT_CTX;
+
+/* Used for reciprocal division/mod functions
+ * It cannot be shared between threads
+ */
+typedef struct bn_recp_ctx_st
+	{
+	BIGNUM N;	/* the divisor */
+	BIGNUM Nr;	/* the reciprocal */
+	int num_bits;
+	int shift;
+	int flags;
+	} BN_RECP_CTX;
+
+#define BN_to_montgomery(r,a,mont,ctx)	BN_mod_mul_montgomery(\
+	r,a,&((mont)->RR),(mont),ctx)
+
+#define BN_prime_checks 0 /* default: select number of iterations
+			     based on the size of the number */
+
+/* number of Miller-Rabin iterations for an error rate  of less than 2^-80
+ * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
+ * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
+ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
+#define BN_prime_checks_for_size(b) ((b) >= 1300 ?  2 : \
+                                (b) >=  850 ?  3 : \
+                                (b) >=  650 ?  4 : \
+                                (b) >=  550 ?  5 : \
+                                (b) >=  450 ?  6 : \
+                                (b) >=  400 ?  7 : \
+                                (b) >=  350 ?  8 : \
+                                (b) >=  300 ?  9 : \
+                                (b) >=  250 ? 12 : \
+                                (b) >=  200 ? 15 : \
+                                (b) >=  150 ? 18 : \
+                                /* b >= 100 */ 27)
+
+#define BN_num_bytes(a)	((BN_num_bits(a)+7)/8)
+#define BN_is_word(a,w)	(((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w)))
+#define BN_is_zero(a)	(((a)->top == 0) || BN_is_word(a,0))
+#define BN_is_one(a)	(BN_is_word((a),1))
+#define BN_is_odd(a)	(((a)->top > 0) && ((a)->d[0] & 1))
+#define BN_one(a)	(BN_set_word((a),1))
+#define BN_zero(a)	(BN_set_word((a),0))
+
+/*#define BN_ascii2bn(a)	BN_hex2bn(a) */
+/*#define BN_bn2ascii(a)	BN_bn2hex(a) */
+
+BIGNUM *BN_value_one(void);
+char *	BN_options(void);
+BN_CTX *BN_CTX_new(void);
+void	BN_CTX_init(BN_CTX *c);
+void	BN_CTX_free(BN_CTX *c);
+void	BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void	BN_CTX_end(BN_CTX *ctx);
+int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int	BN_num_bits(const BIGNUM *a);
+int	BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void	BN_init(BIGNUM *);
+void	BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+int	BN_bn2bin(const BIGNUM *a, unsigned char *to);
+BIGNUM *BN_mpi2bn(unsigned char *s,int len,BIGNUM *ret);
+int	BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int	BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int	BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+	       BN_CTX *ctx);
+int	BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+int	BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int	BN_mul_word(BIGNUM *a, BN_ULONG w);
+int	BN_add_word(BIGNUM *a, BN_ULONG w);
+int	BN_sub_word(BIGNUM *a, BN_ULONG w);
+int	BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(BIGNUM *a);
+int	BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void	BN_free(BIGNUM *a);
+int	BN_is_bit_set(const BIGNUM *a, int n);
+int	BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int	BN_lshift1(BIGNUM *r, BIGNUM *a);
+int	BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx);
+int	BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+		   const BIGNUM *m,BN_CTX *ctx);
+int	BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int	BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2,
+		BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx);
+int	BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p,
+	BIGNUM *m,BN_CTX *ctx);
+int	BN_mask_bits(BIGNUM *a,int n);
+int	BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+#ifndef NO_FP_API
+int	BN_print_fp(FILE *fp, const BIGNUM *a);
+#endif
+#ifdef HEADER_BIO_H
+int	BN_print(BIO *fp, const BIGNUM *a);
+#else
+int	BN_print(void *fp, const BIGNUM *a);
+#endif
+int	BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx);
+int	BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+int	BN_rshift1(BIGNUM *r, BIGNUM *a);
+void	BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int	BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int	BN_set_bit(BIGNUM *a, int n);
+int	BN_clear_bit(BIGNUM *a, int n);
+char *	BN_bn2hex(const BIGNUM *a);
+char *	BN_bn2dec(const BIGNUM *a);
+int 	BN_hex2bn(BIGNUM **a, const char *str);
+int 	BN_dec2bn(BIGNUM **a, const char *str);
+int	BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
+BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add,
+		BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
+int	BN_is_prime(const BIGNUM *p,int nchecks,
+		void (*callback)(int,int,void *),
+		BN_CTX *ctx,void *cb_arg);
+int	BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
+		void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
+		int do_trial_division);
+void	ERR_load_BN_strings(void );
+
+BN_MONT_CTX *BN_MONT_CTX_new(void );
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont,
+			  BN_CTX *ctx);
+int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+
+BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod);
+void BN_BLINDING_free(BN_BLINDING *b);
+int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+
+#if		BN_PARAMS_ENABLE
+void BN_set_params(int mul,int high,int low,int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+#endif	/* BN_PARAMS_ENABLE */
+
+void	BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void	BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int	BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+int	BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y,
+		BN_RECP_CTX *recp,BN_CTX *ctx);
+int	BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			const BIGNUM *m, BN_CTX *ctx);
+int	BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
+		BN_RECP_CTX *recp, BN_CTX *ctx);
+
+/* library internal functions */
+
+#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->max)?\
+	(a):bn_expand2((a),(bits)/BN_BITS2+1))
+#define bn_wexpand(a,words) (((words) <= (a)->max)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+
+#define bn_fix_top(a) \
+        { \
+        BN_ULONG *ftl; \
+	if ((a)->top > 0) \
+		{ \
+		for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
+		if (*(ftl--)) break; \
+		} \
+	}
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+void     bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+
+#ifdef BN_DEBUG
+  void bn_dump1(FILE *o, const char *a, BN_ULONG *b,int n);
+# define bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
+   fprintf(stderr,"\n");}
+# define bn_dump(a,n) bn_dump1(stderr,#a,a,n);
+#else
+# define bn_print(a)
+# define bn_dump(a,b)
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+#define BN_F_BN_BLINDING_CONVERT			 100
+#define BN_F_BN_BLINDING_INVERT				 101
+#define BN_F_BN_BLINDING_NEW				 102
+#define BN_F_BN_BLINDING_UPDATE				 103
+#define BN_F_BN_BN2DEC					 104
+#define BN_F_BN_BN2HEX					 105
+#define BN_F_BN_CTX_GET					 116
+#define BN_F_BN_CTX_NEW					 106
+#define BN_F_BN_DIV					 107
+#define BN_F_BN_EXPAND2					 108
+#define BN_F_BN_MOD_EXP_MONT				 109
+#define BN_F_BN_MOD_INVERSE				 110
+#define BN_F_BN_MOD_MUL_RECIPROCAL			 111
+#define BN_F_BN_MPI2BN					 112
+#define BN_F_BN_NEW					 113
+#define BN_F_BN_RAND					 114
+#define BN_F_BN_USUB					 115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3				 100
+#define BN_R_BAD_RECIPROCAL				 101
+#define BN_R_CALLED_WITH_EVEN_MODULUS			 102
+#define BN_R_DIV_BY_ZERO				 103
+#define BN_R_ENCODING_ERROR				 104
+#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA		 105
+#define BN_R_INVALID_LENGTH				 106
+#define BN_R_NOT_INITIALIZED				 107
+#define BN_R_NO_INVERSE					 108
+#define BN_R_TOO_MANY_TEMPORARY_VARIABLES		 109
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/buffer.h b/AppleCSP/open_ssl/openssl/buffer.h
new file mode 100644
index 00000000..9f9103ab
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/buffer.h
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/buffer/buffer.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BUFFER_H
+#define HEADER_BUFFER_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct buf_mem_st
+	{
+	int length;	/* current number of bytes */
+	char *data;
+	int max;	/* size of buffer */
+	} BUF_MEM;
+
+BUF_MEM *BUF_MEM_new(void);
+void	BUF_MEM_free(BUF_MEM *a);
+int	BUF_MEM_grow(BUF_MEM *str, int len);
+char *	BUF_strdup(const char *str);
+
+void ERR_load_BUF_strings(void );
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the BUF functions. */
+
+/* Function codes. */
+#define BUF_F_BUF_MEM_GROW				 100
+#define BUF_F_BUF_MEM_NEW				 101
+#define BUF_F_BUF_STRDUP				 102
+
+/* Reason codes. */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/crypto.h b/AppleCSP/open_ssl/openssl/crypto.h
new file mode 100644
index 00000000..b2c7a6c9
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/crypto.h
@@ -0,0 +1,391 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/crypto.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CRYPTO_H
+#define HEADER_CRYPTO_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+
+#ifndef NO_FP_API
+#include <stdio.h>
+#endif
+
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+#include <openssl/opensslv.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+#if defined(VMS) || defined(__VMS)
+#include "vms_idhacks.h"
+#endif
+
+
+/* Backward compatibility to SSLeay */
+/* This is more to be used to check the correct DLL is being used
+ * in the MS world. */
+#define SSLEAY_VERSION_NUMBER	OPENSSL_VERSION_NUMBER
+#define SSLEAY_VERSION		0
+/* #define SSLEAY_OPTIONS	1 no longer supported */
+#define SSLEAY_CFLAGS		2
+#define SSLEAY_BUILT_ON		3
+#define SSLEAY_PLATFORM		4
+
+/* When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
+ * names in cryptlib.c
+ */
+
+#define	CRYPTO_LOCK_ERR			1
+#define	CRYPTO_LOCK_ERR_HASH		2
+#define	CRYPTO_LOCK_X509		3
+#define	CRYPTO_LOCK_X509_INFO		4
+#define	CRYPTO_LOCK_X509_PKEY		5
+#define CRYPTO_LOCK_X509_CRL		6
+#define CRYPTO_LOCK_X509_REQ		7
+#define CRYPTO_LOCK_DSA			8
+#define CRYPTO_LOCK_RSA			9
+#define CRYPTO_LOCK_EVP_PKEY		10
+#define	CRYPTO_LOCK_X509_STORE		11
+#define	CRYPTO_LOCK_SSL_CTX		12
+#define	CRYPTO_LOCK_SSL_CERT		13
+#define	CRYPTO_LOCK_SSL_SESSION		14
+#define	CRYPTO_LOCK_SSL_SESS_CERT	15
+#define	CRYPTO_LOCK_SSL			16
+#define	CRYPTO_LOCK_RAND		17
+#define	CRYPTO_LOCK_MALLOC		18
+#define	CRYPTO_LOCK_BIO			19
+#define	CRYPTO_LOCK_GETHOSTBYNAME	20
+#define	CRYPTO_LOCK_GETSERVBYNAME	21
+#define	CRYPTO_LOCK_READDIR		22
+#define	CRYPTO_LOCK_RSA_BLINDING	23
+#define	CRYPTO_LOCK_DH			24
+#define	CRYPTO_LOCK_MALLOC2		25
+#define	CRYPTO_NUM_LOCKS		26
+
+#define CRYPTO_LOCK		1
+#define CRYPTO_UNLOCK		2
+#define CRYPTO_READ		4
+#define CRYPTO_WRITE		8
+
+#ifndef NO_LOCKING
+#ifndef CRYPTO_w_lock
+#define CRYPTO_w_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_w_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_r_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_r_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_add(addr,amount,type)	\
+	CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
+#endif
+#else
+#define CRYPTO_w_lock(a)
+#define	CRYPTO_w_unlock(a)
+#define CRYPTO_r_lock(a)
+#define CRYPTO_r_unlock(a)
+#define CRYPTO_add(a,b,c)	((*(a))+=(b))
+#endif
+
+/* The following can be used to detect memory leaks in the SSLeay library.
+ * It used, it turns on malloc checking */
+
+#define CRYPTO_MEM_CHECK_OFF	0x0	/* an enume */
+#define CRYPTO_MEM_CHECK_ON	0x1	/* a bit */
+#define CRYPTO_MEM_CHECK_ENABLE	0x2	/* a bit */
+#define CRYPTO_MEM_CHECK_DISABLE 0x3	/* an enume */
+
+/* The following are bit values to turn on or off options connected to the
+ * malloc checking functionality */
+
+/* Adds time to the memory checking information */
+#define V_CRYPTO_MDEBUG_TIME	0x1 /* a bit */
+/* Adds thread number to the memory checking information */
+#define V_CRYPTO_MDEBUG_THREAD	0x2 /* a bit */
+
+#define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)
+
+
+/* predec of the BIO type */
+typedef struct bio_st BIO_dummy;
+
+typedef struct crypto_ex_data_st
+	{
+	STACK *sk;
+	int dummy; /* gcc is screwing up this data structure :-( */
+	} CRYPTO_EX_DATA;
+
+/* Called when a new object is created */
+typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+/* Called when an object is free()ed */
+typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+/* Called when we need to dup an object */
+typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+					int idx, long argl, void *argp);
+
+/* This stuff is basically class callback functions
+ * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */
+
+typedef struct crypto_ex_data_func_st
+	{
+	long argl;	/* Arbitary long */
+	void *argp;	/* Arbitary void * */
+	CRYPTO_EX_new *new_func;
+	CRYPTO_EX_free *free_func;
+	CRYPTO_EX_dup *dup_func;
+	} CRYPTO_EX_DATA_FUNCS;
+
+DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
+
+/* Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
+ * entry.
+ */
+
+#define CRYPTO_EX_INDEX_BIO		0
+#define CRYPTO_EX_INDEX_SSL		1
+#define CRYPTO_EX_INDEX_SSL_CTX		2
+#define CRYPTO_EX_INDEX_SSL_SESSION	3
+#define CRYPTO_EX_INDEX_X509_STORE	4
+#define CRYPTO_EX_INDEX_X509_STORE_CTX	5
+
+
+/* This is the default callbacks, but we can have others as well:
+ * this is needed in Win32 where the application malloc and the
+ * library malloc may not be the same.
+ */
+#define CRYPTO_malloc_init()	CRYPTO_set_mem_functions(\
+	malloc, realloc, free)
+
+#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
+# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */
+#  define CRYPTO_MDEBUG
+# endif
+#endif
+
+/* Set standard debugging functions (not done by default
+ * unless CRYPTO_MDEBUG is defined) */
+#define CRYPTO_malloc_debug_init()	do {\
+	CRYPTO_set_mem_debug_functions(\
+		(void (*)())CRYPTO_dbg_malloc,\
+		(void (*)())CRYPTO_dbg_realloc,\
+		(void (*)())CRYPTO_dbg_free,\
+		(void (*)())CRYPTO_dbg_set_options,\
+		(long (*)())CRYPTO_dbg_get_options);\
+	} while(0)
+
+int CRYPTO_mem_ctrl(int mode);
+int CRYPTO_is_mem_check_on(void);
+
+/* for applications */
+#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
+#define MemCheck_stop()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)
+
+/* for library-internal use */
+#define MemCheck_on()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
+#define MemCheck_off()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
+#define is_MemCheck_on() CRYPTO_is_mem_check_on()
+
+#define Malloc(num)	CRYPTO_malloc((int)num,__FILE__,__LINE__)
+#define Realloc(addr,num) \
+	CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
+#define Remalloc(addr,num) \
+	CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
+#define FreeFunc	CRYPTO_free
+#define Free(addr)	CRYPTO_free(addr)
+
+#define Malloc_locked(num) CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)
+#define Free_locked(addr) CRYPTO_free_locked(addr)
+
+
+/* Case insensiteve linking causes problems.... */
+#if defined(WIN16) || defined(VMS)
+#define ERR_load_CRYPTO_strings	ERR_load_CRYPTOlib_strings
+#endif
+
+
+const char *SSLeay_version(int type);
+unsigned long SSLeay(void);
+
+int CRYPTO_get_ex_new_index(int idx, STACK_OF(CRYPTO_EX_DATA_FUNCS) **skp, long argl, void *argp,
+	     CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *CRYPTO_get_ex_data(CRYPTO_EX_DATA *ad,int idx);
+int CRYPTO_dup_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, CRYPTO_EX_DATA *to,
+	     CRYPTO_EX_DATA *from);
+void CRYPTO_free_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, void *obj, CRYPTO_EX_DATA *ad);
+void CRYPTO_new_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, void *obj, CRYPTO_EX_DATA *ad);
+
+int CRYPTO_get_new_lockid(char *name);
+
+int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */
+void CRYPTO_lock(int mode, int type,const char *file,int line);
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
+					      const char *file,int line));
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+		int line);
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+					      const char *file, int line));
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+					  const char *file,int line);
+void CRYPTO_set_id_callback(unsigned long (*func)(void));
+unsigned long (*CRYPTO_get_id_callback(void))(void);
+unsigned long CRYPTO_thread_id(void);
+const char *CRYPTO_get_lock_name(int type);
+int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
+		    int line);
+
+/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions --
+ * call the latter last if you need different functions */
+int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
+int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*free_func)(void *));
+int CRYPTO_set_mem_debug_functions(void (*m)(),void (*r)(),void (*f)(),void (*so)(),long (*go)());
+void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *));
+void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *));
+void CRYPTO_get_mem_debug_functions(void (**m)(),void (**r)(),void (**f)(),void (**so)(),long (**go)());
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line);
+void CRYPTO_free_locked(void *);
+void *CRYPTO_malloc(int num, const char *file, int line);
+void CRYPTO_free(void *);
+void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
+void *CRYPTO_remalloc(void *addr,int num, const char *file, int line);
+
+void CRYPTO_set_mem_debug_options(long bits);
+long CRYPTO_get_mem_debug_options(void);
+
+#define CRYPTO_push_info(info) \
+        CRYPTO_push_info_(info, __FILE__, __LINE__);
+int CRYPTO_push_info_(const char *info, const char *file, int line);
+int CRYPTO_pop_info(void);
+int CRYPTO_remove_all_info(void);
+
+/* The last argument has the following significance:
+ *
+ * 0:	called before the actual memory allocation has taken place
+ * 1:	called after the actual memory allocation has taken place
+ */
+void CRYPTO_dbg_malloc(void *addr,int num,const char *file,int line,int before_p);
+void CRYPTO_dbg_realloc(void *addr1,void *addr2,int num,const char *file,int line,int before_p);
+void CRYPTO_dbg_free(void *addr,int before_p);
+
+/* Tell the debugging code about options.  By default, the following values
+ * apply:
+ *
+ * 0:	Clear all options.
+ * 1:	Set the "Show Time" option.
+ * 2:	Set the "Show Thread Number" option.
+ * 3:	1 + 2
+ */
+void CRYPTO_dbg_set_options(long bits);
+long CRYPTO_dbg_get_options(void);
+
+#ifndef NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *);
+#endif
+void CRYPTO_mem_leaks(struct bio_st *bio);
+/* unsigned long order, char *file, int line, int num_bytes, char *addr */
+void CRYPTO_mem_leaks_cb(void (*cb)());
+
+void ERR_load_CRYPTO_strings(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the CRYPTO functions. */
+
+/* Function codes. */
+#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX		 100
+#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID			 101
+#define CRYPTO_F_CRYPTO_SET_EX_DATA			 102
+
+/* Reason codes. */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/dsa.h b/AppleCSP/open_ssl/openssl/dsa.h
new file mode 100644
index 00000000..8cb59e0c
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/dsa.h
@@ -0,0 +1,259 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/dsa/dsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * The DSS routines are based on patches supplied by
+ * Steven Schoch <schoch@sheba.arc.nasa.gov>.  He basically did the
+ * work and I have just tweaked them a little to fit into my
+ * stylistic vision for SSLeay :-) */
+
+#ifndef HEADER_DSA_H
+#define HEADER_DSA_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_DSA
+#error DSA is disabled.
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#ifndef NO_DH
+# include <openssl/dh.h>
+#endif
+
+#define DSA_FLAG_CACHE_MONT_P	0x01
+
+typedef struct dsa_st DSA;
+
+typedef struct DSA_SIG_st
+	{
+	BIGNUM *r;
+	BIGNUM *s;
+	} DSA_SIG;
+
+typedef struct dsa_method {
+	const char *name;
+	DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa);
+	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+								BIGNUM **rp);
+	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
+							DSA_SIG *sig, DSA *dsa);
+	int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+			BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+			BN_MONT_CTX *in_mont);
+	int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+				const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx); /* Can be null */
+	int (*init)(DSA *dsa);
+	int (*finish)(DSA *dsa);
+	int flags;
+	char *app_data;
+} DSA_METHOD;
+
+struct dsa_st
+	{
+	/* This first variable is used to pick up errors where
+	 * a DSA is passed instead of of a EVP_PKEY */
+	int pad;
+	int version;
+	int write_params;
+	BIGNUM *p;
+	BIGNUM *q;	/* == 20 */
+	BIGNUM *g;
+
+	BIGNUM *pub_key;  /* y public key */
+	BIGNUM *priv_key; /* x private key */
+
+	BIGNUM *kinv;	/* Signing pre-calc */
+	BIGNUM *r;	/* Signing pre-calc */
+
+	int flags;
+	/* Normally used to cache montgomery values */
+	char *method_mont_p;
+	int references;
+	CRYPTO_EX_DATA ex_data;
+	const DSA_METHOD *meth;
+	};
+
+#define DSAparams_dup(x) (DSA *)ASN1_dup((int (*)())i2d_DSAparams, \
+		(char *(*)())d2i_DSAparams,(char *)(x))
+#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
+		(char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
+#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
+		(unsigned char *)(x))
+#define d2i_DSAparams_bio(bp,x) (DSA *)ASN1_d2i_bio((char *(*)())DSA_new, \
+		(char *(*)())d2i_DSAparams,(bp),(unsigned char **)(x))
+#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio(i2d_DSAparams,(bp), \
+		(unsigned char *)(x))
+
+
+DSA_SIG * DSA_SIG_new(void);
+void	DSA_SIG_free(DSA_SIG *a);
+int	i2d_DSA_SIG(DSA_SIG *a, unsigned char **pp);
+DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, unsigned char **pp, long length);
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa);
+int	DSA_do_verify(const unsigned char *dgst,int dgst_len,
+		      DSA_SIG *sig,DSA *dsa);
+
+const DSA_METHOD *DSA_OpenSSL(void);
+
+void        DSA_set_default_method(const DSA_METHOD *);
+const DSA_METHOD *DSA_get_default_method(void);
+const DSA_METHOD *DSA_set_method(DSA *dsa, const DSA_METHOD *);
+
+DSA *	DSA_new(void);
+DSA *	DSA_new_method(const DSA_METHOD *meth);
+int	DSA_size(DSA *);
+	/* next 4 return -1 on error */
+int	DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp);
+int	DSA_sign(int type,const unsigned char *dgst,int dlen,
+		unsigned char *sig, unsigned int *siglen, DSA *dsa);
+int	DSA_verify(int type,const unsigned char *dgst,int dgst_len,
+		unsigned char *sigbuf, int siglen, DSA *dsa);
+void	DSA_free (DSA *r);
+int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DSA_set_ex_data(DSA *d, int idx, void *arg);
+void *DSA_get_ex_data(DSA *d, int idx);
+
+void	ERR_load_DSA_strings(void );
+
+DSA *	d2i_DSAPublicKey(DSA **a, unsigned char **pp, long length);
+DSA *	d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
+DSA * 	d2i_DSAparams(DSA **a, unsigned char **pp, long length);
+DSA *	DSA_generate_parameters(int bits, unsigned char *seed,int seed_len,
+		int *counter_ret, unsigned long *h_ret,void
+		(*callback)(int, int, void *),void *cb_arg);
+int	DSA_generate_key(DSA *a);
+int	i2d_DSAPublicKey(DSA *a, unsigned char **pp);
+int 	i2d_DSAPrivateKey(DSA *a, unsigned char **pp);
+int	i2d_DSAparams(DSA *a,unsigned char **pp);
+
+#ifdef HEADER_BIO_H
+int	DSAparams_print(BIO *bp, DSA *x);
+int	DSA_print(BIO *bp, DSA *x, int off);
+#endif
+#ifndef NO_FP_API
+int	DSAparams_print_fp(FILE *fp, DSA *x);
+int	DSA_print_fp(FILE *bp, DSA *x, int off);
+#endif
+
+#define DSS_prime_checks 50
+/* Primality test according to FIPS PUB 186[-1], Appendix 2.1:
+ * 50 rounds of Rabin-Miller */
+#define DSA_is_prime(n, callback, cb_arg) \
+	BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)
+
+#ifndef NO_DH
+/* Convert DSA structure (key or just parameters) into DH structure
+ * (be careful to avoid small subgroup attacks when using this!) */
+DH *DSA_dup_DH(DSA *r);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the DSA functions. */
+
+/* Function codes. */
+#define DSA_F_D2I_DSA_SIG				 110
+#define DSA_F_DSAPARAMS_PRINT				 100
+#define DSA_F_DSAPARAMS_PRINT_FP			 101
+#define DSA_F_DSA_DO_SIGN				 112
+#define DSA_F_DSA_DO_VERIFY				 113
+#define DSA_F_DSA_NEW					 103
+#define DSA_F_DSA_PRINT					 104
+#define DSA_F_DSA_PRINT_FP				 105
+#define DSA_F_DSA_SIGN					 106
+#define DSA_F_DSA_SIGN_SETUP				 107
+#define DSA_F_DSA_SIG_NEW				 109
+#define DSA_F_DSA_VERIFY				 108
+#define DSA_F_I2D_DSA_SIG				 111
+
+/* Reason codes. */
+#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/e_os.h b/AppleCSP/open_ssl/openssl/e_os.h
new file mode 100644
index 00000000..c94d6dd9
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/e_os.h
@@ -0,0 +1,464 @@
+/*
+ * 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.
+ */
+
+
+/* e_os.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_E_OS_H
+#define HEADER_E_OS_H
+
+#include <openssl/opensslconf.h>
+
+#include <openssl/e_os2.h>
+/* <openssl/e_os2.h> contains what we can justify to make visible
+ * to the outside; this file e_os.h is not part of the exported
+ * interface. */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Used to checking reference counts, most while doing perl5 stuff :-) */
+#ifdef REF_PRINT
+#undef REF_PRINT
+#define REF_PRINT(a,b)	fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a)
+#endif
+
+#ifndef DEVRANDOM
+/* set this to your 'random' device if you have one.
+ * My default, we will try to read this file */
+#define DEVRANDOM "/dev/urandom"
+#endif
+
+#if defined(__MWERKS__) && defined(macintosh)
+# if macintosh==1
+#  ifndef MAC_OS_GUSI_SOURCE
+#    define MAC_OS_pre_X
+#    define NO_SYS_TYPES_H
+#  endif
+#  define NO_SYS_PARAM_H
+#  define NO_CHMOD
+#  define NO_SYSLOG
+#  undef  DEVRANDOM
+#  define GETPID_IS_MEANINGLESS
+# endif
+#endif
+
+/********************************************************************
+ The Microsoft section
+ ********************************************************************/
+/* The following is used becaue of the small stack in some
+ * Microsoft operating systems */
+#if defined(WIN16) || defined(MSDOS)
+#  define MS_STATIC	static
+#else
+#  define MS_STATIC
+#endif
+
+#if defined(_WIN32) && !defined(WIN32)
+#  define WIN32
+#endif
+
+#if defined(WIN32) || defined(WIN16)
+#  ifndef WINDOWS
+#    define WINDOWS
+#  endif
+#  ifndef MSDOS
+#    define MSDOS
+#  endif
+#endif
+
+#if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS)
+#  define GETPID_IS_MEANINGLESS
+#endif
+
+#ifdef WIN32
+#define get_last_sys_error()	GetLastError()
+#define clear_sys_error()	SetLastError(0)
+#if !defined(WINNT)
+#define WIN_CONSOLE_BUG
+#endif
+#else
+#define get_last_sys_error()	errno
+#define clear_sys_error()	errno=0
+#endif
+
+#ifdef WINDOWS
+#define get_last_socket_error()	WSAGetLastError()
+#define clear_socket_error()	WSASetLastError(0)
+#define readsocket(s,b,n)	recv((s),(b),(n),0)
+#define writesocket(s,b,n)	send((s),(b),(n),0)
+#define EADDRINUSE		WSAEADDRINUSE
+#elif defined(MAC_OS_pre_X)
+#define get_last_socket_error()	errno
+#define clear_socket_error()	errno=0
+#define closesocket(s)		MacSocket_close(s)
+#define readsocket(s,b,n)	MacSocket_recv((s),(b),(n),true)
+#define writesocket(s,b,n)	MacSocket_send((s),(b),(n))
+#else
+#define get_last_socket_error()	errno
+#define clear_socket_error()	errno=0
+#define ioctlsocket(a,b,c)	ioctl(a,b,c)
+#define closesocket(s)		close(s)
+#define readsocket(s,b,n)	read((s),(b),(n))
+#define writesocket(s,b,n)	write((s),(b),(n))
+#endif
+
+#ifdef WIN16
+#  define NO_FP_API
+#  define MS_CALLBACK	_far _loadds
+#  define MS_FAR	_far
+#else
+#  define MS_CALLBACK
+#  define MS_FAR
+#endif
+
+#ifdef NO_STDIO
+#  define NO_FP_API
+#endif
+
+#if defined(WINDOWS) || defined(MSDOS)
+
+#  ifndef S_IFDIR
+#    define S_IFDIR	_S_IFDIR
+#  endif
+
+#  ifndef S_IFMT
+#    define S_IFMT	_S_IFMT
+#  endif
+
+#  if !defined(WINNT)
+#    define NO_SYSLOG
+#  endif
+#  define NO_DIRENT
+
+#  ifdef WINDOWS
+#    include <windows.h>
+#    include <stddef.h>
+#    include <errno.h>
+#    include <string.h>
+#    include <malloc.h>
+#  endif
+#  include <io.h>
+#  include <fcntl.h>
+
+#  define ssize_t long
+
+#  if defined (__BORLANDC__)
+#    define _setmode setmode
+#    define _O_TEXT O_TEXT
+#    define _O_BINARY O_BINARY
+#    define _int64 __int64
+#    define _kbhit kbhit
+#  endif
+
+#  if defined(WIN16) && !defined(MONOLITH) && defined(SSLEAY) && defined(_WINEXITNOPERSIST)
+#    define EXIT(n) { if (n == 0) _wsetexit(_WINEXITNOPERSIST); return(n); }
+#  else
+#    define EXIT(n)		return(n);
+#  endif
+#  define LIST_SEPARATOR_CHAR ';'
+#  ifndef X_OK
+#    define X_OK	0
+#  endif
+#  ifndef W_OK
+#    define W_OK	2
+#  endif
+#  ifndef R_OK
+#    define R_OK	4
+#  endif
+#  define OPENSSL_CONF	"openssl.cnf"
+#  define SSLEAY_CONF	OPENSSL_CONF
+#  define NUL_DEV	"nul"
+#  define RFILE		".rnd"
+
+#else /* The non-microsoft world world */
+
+#  if defined(__VMS) && !defined(VMS)
+#  define VMS 1
+#  endif
+
+#  ifdef VMS
+  /* some programs don't include stdlib, so exit() and others give implicit 
+     function warnings */
+#    include <stdlib.h>
+#    if defined(__DECC)
+#      include <unistd.h>
+#    else
+#      include <unixlib.h>
+#    endif
+#    define OPENSSL_CONF	"openssl.cnf"
+#    define SSLEAY_CONF		OPENSSL_CONF
+#    define RFILE		".rnd"
+#    define LIST_SEPARATOR_CHAR ','
+#    define NUL_DEV		"NLA0:"
+  /* We need to do this since VMS has the following coding on status codes:
+
+     Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ...
+               The important thing to know is that odd numbers are considered
+	       good, while even ones are considered errors.
+     Bits 3-15: actual status number
+     Bits 16-27: facility number.  0 is considered "unknown"
+     Bits 28-31: control bits.  If bit 28 is set, the shell won't try to
+                 output the message (which, for random codes, just looks ugly)
+
+     So, what we do here is to change 0 to 1 to get the default success status,
+     and everything else is shifted up to fit into the status number field, and
+     the status is tagged as an error, which I believe is what is wanted here.
+     -- Richard Levitte
+  */
+#    if !defined(MONOLITH) || defined(OPENSSL_C)
+#      define EXIT(n)		do { int __VMS_EXIT = n; \
+                                     if (__VMS_EXIT == 0) \
+				       __VMS_EXIT = 1; \
+				     else \
+				       __VMS_EXIT = (n << 3) | 2; \
+                                     __VMS_EXIT |= 0x10000000; \
+				     exit(__VMS_EXIT); \
+				     return(__VMS_EXIT); } while(0)
+#    else
+#      define EXIT(n)		return(n)
+#    endif
+#    define NO_SYS_PARAM_H
+#  else
+     /* !defined VMS */
+#    ifdef OPENSSL_UNISTD
+#      include OPENSSL_UNISTD
+#    else
+#      include <unistd.h>
+#    endif
+#    ifndef NO_SYS_TYPES_H
+#      include <sys/types.h>
+#    endif
+#    ifdef NeXT
+#      define pid_t int /* pid_t is missing on NEXTSTEP/OPENSTEP
+                         * (unless when compiling with -D_POSIX_SOURCE,
+                         * which doesn't work for us) */
+#      define ssize_t int /* ditto */
+#    endif
+
+#    define OPENSSL_CONF	"openssl.cnf"
+#    define SSLEAY_CONF		OPENSSL_CONF
+#    define RFILE		".rnd"
+#    define LIST_SEPARATOR_CHAR ':'
+#    define NUL_DEV		"/dev/null"
+#    ifndef MONOLITH
+#      define EXIT(n)		exit(n); return(n)
+#    else
+#      define EXIT(n)		return(n)
+#    endif
+#  endif
+
+#  define SSLeay_getpid()	getpid()
+
+#endif
+
+
+/*************/
+
+#ifdef USE_SOCKETS
+#  if defined(WINDOWS) || defined(MSDOS)
+      /* windows world */
+
+#    ifdef NO_SOCK
+#      define SSLeay_Write(a,b,c)	(-1)
+#      define SSLeay_Read(a,b,c)	(-1)
+#      define SHUTDOWN(fd)		close(fd)
+#      define SHUTDOWN2(fd)		close(fd)
+#    else
+#      include <winsock.h>
+extern HINSTANCE _hInstance;
+#      define SSLeay_Write(a,b,c)	send((a),(b),(c),0)
+#      define SSLeay_Read(a,b,c)	recv((a),(b),(c),0)
+#      define SHUTDOWN(fd)		{ shutdown((fd),0); closesocket(fd); }
+#      define SHUTDOWN2(fd)		{ shutdown((fd),2); closesocket(fd); }
+#    endif
+
+#  elif defined(MAC_OS_pre_X)
+
+#    include "MacSocket.h"
+#    define SSLeay_Write(a,b,c)		MacSocket_send((a),(b),(c))
+#    define SSLeay_Read(a,b,c)		MacSocket_recv((a),(b),(c),true)
+#    define SHUTDOWN(fd)		MacSocket_close(fd)
+#    define SHUTDOWN2(fd)		MacSocket_close(fd)
+
+#  else
+
+#    ifndef NO_SYS_PARAM_H
+#      include <sys/param.h>
+#    endif
+#    include <sys/time.h> /* Needed under linux for FD_XXX */
+
+#    include <netdb.h>
+#    if defined(VMS) && !defined(__DECC)
+#      include <socket.h>
+#      include <in.h>
+#    else
+#      include <sys/socket.h>
+#      ifdef FILIO_H
+#        include <sys/filio.h> /* Added for FIONBIO under unixware */
+#      endif
+#      include <netinet/in.h>
+#    endif
+
+#    if defined(NeXT) || defined(_NEXT_SOURCE)
+#      include <sys/fcntl.h>
+#      include <sys/types.h>
+#    endif
+
+#    ifdef AIX
+#      include <sys/select.h>
+#    endif
+
+#    if defined(sun)
+#      include <sys/filio.h>
+#    else
+#      ifndef VMS
+#        include <sys/ioctl.h>
+#      else
+	 /* ioctl is only in VMS > 7.0 and when socketshr is not used */
+#        if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000)
+#          include <sys/ioctl.h>
+#        endif
+#      endif
+#    endif
+
+#    ifdef VMS
+#      include <unixio.h>
+#      if defined(TCPIP_TYPE_SOCKETSHR)
+#        include <socketshr.h>
+#      endif
+#    endif
+
+#    define SSLeay_Read(a,b,c)     read((a),(b),(c))
+#    define SSLeay_Write(a,b,c)    write((a),(b),(c))
+#    define SHUTDOWN(fd)    { shutdown((fd),0); closesocket((fd)); }
+#    define SHUTDOWN2(fd)   { shutdown((fd),2); closesocket((fd)); }
+#    define INVALID_SOCKET	(-1)
+#  endif
+#endif
+
+#if defined(__ultrix)
+#  ifndef ssize_t
+#    define ssize_t int 
+#  endif
+#endif
+
+#if defined(THREADS) || defined(sun)
+#ifndef _REENTRANT
+#define _REENTRANT
+#endif
+#endif
+
+/***********************************************/
+
+/* do we need to do this for getenv.
+ * Just define getenv for use under windows */
+
+#ifdef WIN16
+/* How to do this needs to be thought out a bit more.... */
+/*char *GETENV(char *);
+#define Getenv	GETENV*/
+#define Getenv	getenv
+#else
+#define Getenv getenv
+#endif
+
+#define DG_GCC_BUG	/* gcc < 2.6.3 on DGUX */
+
+#ifdef sgi
+#define IRIX_CC_BUG	/* all version of IRIX I've tested (4.* 5.*) */
+#endif
+#ifdef SNI
+#define IRIX_CC_BUG	/* CDS++ up to V2.0Bsomething suffered from the same bug.*/
+#endif
+
+#ifdef NO_MD2
+#define MD2_Init MD2Init
+#define MD2_Update MD2Update
+#define MD2_Final MD2Final
+#define MD2_DIGEST_LENGTH 16
+#endif
+#ifdef NO_MD5
+#define MD5_Init MD5Init 
+#define MD5_Update MD5Update
+#define MD5_Final MD5Final
+#define MD5_DIGEST_LENGTH 16
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/e_os2.h b/AppleCSP/open_ssl/openssl/e_os2.h
new file mode 100644
index 00000000..47ab43b3
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/e_os2.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+
+/* e_os2.h */
+
+#ifndef HEADER_E_OS2_H
+#define HEADER_E_OS2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/opensslconf.h> /* OPENSSL_UNISTD */
+
+#ifdef MSDOS
+# define OPENSSL_UNISTD_IO <io.h>
+# define OPENSSL_DECLARE_EXIT extern void exit(int);
+#else
+# define OPENSSL_UNISTD_IO OPENSSL_UNISTD
+# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */
+#endif
+
+/* Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN,
+   to define and declare certain global
+   symbols that, with some compilers under VMS, have to be defined and
+   declared explicitely with globaldef and globalref.  On other OS:es,
+   these macros are defined with something sensible. */
+
+#if defined(VMS) && !defined(__DECC)
+# define OPENSSL_EXTERN globalref
+# define OPENSSL_GLOBAL globaldef
+#else
+# define OPENSSL_EXTERN extern
+# define OPENSSL_GLOBAL
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/err.h b/AppleCSP/open_ssl/openssl/err.h
new file mode 100644
index 00000000..255c8cca
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/err.h
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/err/err.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ERR_H
+#define HEADER_ERR_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <openssl/opensslconf.h>
+
+#ifndef NO_FP_API
+#include <stdio.h>
+#endif
+
+/* The following is a bit of a trick to help the object files only contain
+ * the 'name of the file' string once.  Since 'err.h' is protected by the
+ * HEADER_ERR_H stuff, this should be included only once per file. */
+
+#define ERR_file_name	__FILE__
+
+#ifndef NO_ERR
+#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,d,e)
+#else
+#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,NULL,0)
+#endif
+
+#include <errno.h>
+
+#define ERR_TXT_MALLOCED	0x01
+#define ERR_TXT_STRING		0x02
+
+#define ERR_NUM_ERRORS	16
+typedef struct err_state_st
+	{
+	unsigned long pid;
+	unsigned long err_buffer[ERR_NUM_ERRORS];
+	char *err_data[ERR_NUM_ERRORS];
+	int err_data_flags[ERR_NUM_ERRORS];
+	const char *err_file[ERR_NUM_ERRORS];
+	int err_line[ERR_NUM_ERRORS];
+	int top,bottom;
+	} ERR_STATE;
+
+/* library */
+#define ERR_LIB_NONE		1
+#define ERR_LIB_SYS		2
+#define ERR_LIB_BN		3
+#define ERR_LIB_RSA		4
+#define ERR_LIB_DH		5
+#define ERR_LIB_EVP		6
+#define ERR_LIB_BUF		7
+#define ERR_LIB_OBJ		8
+#define ERR_LIB_PEM		9
+#define ERR_LIB_DSA		10
+#define ERR_LIB_X509		11
+#define ERR_LIB_METH		12
+#define ERR_LIB_ASN1		13
+#define ERR_LIB_CONF		14
+#define ERR_LIB_CRYPTO		15
+#define ERR_LIB_SSL		20
+#define ERR_LIB_SSL23		21
+#define ERR_LIB_SSL2		22
+#define ERR_LIB_SSL3		23
+#define ERR_LIB_RSAREF		30
+#define ERR_LIB_PROXY		31
+#define ERR_LIB_BIO		32
+#define ERR_LIB_PKCS7		33
+#define ERR_LIB_X509V3		34
+#define ERR_LIB_PKCS12		35
+#define ERR_LIB_RAND		36
+
+#define ERR_LIB_USER		128
+
+#define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,(f),(r),ERR_file_name,__LINE__)
+#define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,(f),(r),ERR_file_name,__LINE__)
+#define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,(f),(r),ERR_file_name,__LINE__)
+#define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,(f),(r),ERR_file_name,__LINE__)
+#define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,(f),(r),ERR_file_name,__LINE__)
+#define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,(f),(r),ERR_file_name,__LINE__)
+#define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,(f),(r),ERR_file_name,__LINE__)
+#define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,(f),(r),ERR_file_name,__LINE__)
+#define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,(f),(r),ERR_file_name,__LINE__)
+#define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,(f),(r),ERR_file_name,__LINE__)
+#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),ERR_file_name,__LINE__)
+#define METHerr(f,r) ERR_PUT_error(ERR_LIB_METH,(f),(r),ERR_file_name,__LINE__)
+#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),ERR_file_name,__LINE__)
+#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),ERR_file_name,__LINE__)
+#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),ERR_file_name,__LINE__)
+#define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,(f),(r),ERR_file_name,__LINE__)
+#define SSL23err(f,r) ERR_PUT_error(ERR_LIB_SSL23,(f),(r),ERR_file_name,__LINE__)
+#define SSL2err(f,r) ERR_PUT_error(ERR_LIB_SSL2,(f),(r),ERR_file_name,__LINE__)
+#define SSL3err(f,r) ERR_PUT_error(ERR_LIB_SSL3,(f),(r),ERR_file_name,__LINE__)
+#define RSAREFerr(f,r) ERR_PUT_error(ERR_LIB_RSAREF,(f),(r),ERR_file_name,__LINE__)
+#define PROXYerr(f,r) ERR_PUT_error(ERR_LIB_PROXY,(f),(r),ERR_file_name,__LINE__)
+#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),ERR_file_name,__LINE__)
+#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),ERR_file_name,__LINE__)
+#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),ERR_file_name,__LINE__)
+#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),ERR_file_name,__LINE__)
+
+/* Borland C seems too stupid to be able to shift and do longs in
+ * the pre-processor :-( */
+#define ERR_PACK(l,f,r)		(((((unsigned long)l)&0xffL)*0x1000000)| \
+				((((unsigned long)f)&0xfffL)*0x1000)| \
+				((((unsigned long)r)&0xfffL)))
+#define ERR_GET_LIB(l)		(int)((((unsigned long)l)>>24L)&0xffL)
+#define ERR_GET_FUNC(l)		(int)((((unsigned long)l)>>12L)&0xfffL)
+#define ERR_GET_REASON(l)	(int)((l)&0xfffL)
+#define ERR_FATAL_ERROR(l)	(int)((l)&ERR_R_FATAL)
+
+/* OS functions */
+#define SYS_F_FOPEN		1
+#define SYS_F_CONNECT		2
+#define SYS_F_GETSERVBYNAME	3
+#define SYS_F_SOCKET		4
+#define SYS_F_IOCTLSOCKET	5
+#define SYS_F_BIND		6
+#define SYS_F_LISTEN		7
+#define SYS_F_ACCEPT		8
+#define SYS_F_WSASTARTUP	9 /* Winsock stuff */
+#define SYS_F_OPENDIR		10
+
+#define ERR_R_FATAL		32	
+/* reasons */
+#define ERR_R_SYS_LIB	ERR_LIB_SYS
+#define ERR_R_BN_LIB	ERR_LIB_BN
+#define ERR_R_RSA_LIB	ERR_LIB_RSA
+#define ERR_R_DSA_LIB	ERR_LIB_DSA
+#define ERR_R_DH_LIB	ERR_LIB_DH
+#define ERR_R_EVP_LIB	ERR_LIB_EVP
+#define ERR_R_BUF_LIB	ERR_LIB_BUF
+#define ERR_R_BIO_LIB	ERR_LIB_BIO
+#define ERR_R_OBJ_LIB	ERR_LIB_OBJ
+#define ERR_R_PEM_LIB	ERR_LIB_PEM
+#define ERR_R_X509_LIB	ERR_LIB_X509
+#define ERR_R_METH_LIB	ERR_LIB_METH
+#define ERR_R_ASN1_LIB	ERR_LIB_ASN1
+#define ERR_R_CONF_LIB	ERR_LIB_CONF
+#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO
+#define ERR_R_SSL_LIB	ERR_LIB_SSL
+#define ERR_R_SSL23_LIB	ERR_LIB_SSL23
+#define ERR_R_SSL2_LIB	ERR_LIB_SSL2
+#define ERR_R_SSL3_LIB	ERR_LIB_SSL3
+#define ERR_R_PROXY_LIB	ERR_LIB_PROXY
+#define ERR_R_BIO_LIB	ERR_LIB_BIO
+#define ERR_R_PKCS7_LIB	ERR_LIB_PKCS7
+#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12
+
+/* fatal error */
+#define	ERR_R_MALLOC_FAILURE			(1|ERR_R_FATAL)
+#define	ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	(2|ERR_R_FATAL)
+#define	ERR_R_PASSED_NULL_PARAMETER		(3|ERR_R_FATAL)
+#define ERR_R_NESTED_ASN1_ERROR			(4)
+#define ERR_R_BAD_ASN1_OBJECT_HEADER		(5)
+#define ERR_R_BAD_GET_ASN1_OBJECT_CALL		(6)
+#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE	(7)
+#define ERR_R_ASN1_LENGTH_MISMATCH		(8)
+#define ERR_R_MISSING_ASN1_EOS			(9)
+
+typedef struct ERR_string_data_st
+	{
+	unsigned long error;
+	const char *string;
+	} ERR_STRING_DATA;
+
+void ERR_put_error(int lib, int func,int reason,const char *file,int line);
+void ERR_set_error_data(char *data,int flags);
+
+unsigned long ERR_get_error(void );
+unsigned long ERR_get_error_line(const char **file,int *line);
+unsigned long ERR_get_error_line_data(const char **file,int *line,
+				      const char **data, int *flags);
+unsigned long ERR_peek_error(void );
+unsigned long ERR_peek_error_line(const char **file,int *line);
+unsigned long ERR_peek_error_line_data(const char **file,int *line,
+				       const char **data,int *flags);
+void ERR_clear_error(void );
+char *ERR_error_string(unsigned long e,char *buf);
+const char *ERR_lib_error_string(unsigned long e);
+const char *ERR_func_error_string(unsigned long e);
+const char *ERR_reason_error_string(unsigned long e);
+#ifndef NO_FP_API
+void ERR_print_errors_fp(FILE *fp);
+#endif
+#ifdef HEADER_BIO_H
+void ERR_print_errors(BIO *bp);
+void ERR_add_error_data(int num, ...);
+#endif
+void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
+void ERR_load_ERR_strings(void);
+void ERR_load_crypto_strings(void);
+void ERR_free_strings(void);
+
+void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+ERR_STATE *ERR_get_state(void);
+
+#ifdef HEADER_LHASH_H
+LHASH *ERR_get_string_table(void );
+LHASH *ERR_get_err_state_table(void );
+#else
+char *ERR_get_string_table(void );
+char *ERR_get_err_state_table(void );
+#endif
+
+int ERR_get_next_error_library(void );
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/openssl/evp.h b/AppleCSP/open_ssl/openssl/evp.h
new file mode 100644
index 00000000..02d69fd3
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/evp.h
@@ -0,0 +1,761 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/evp/evp.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ENVELOPE_H
+#define HEADER_ENVELOPE_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifndef NO_MD2
+#include <openssl/md2.h>
+#endif
+#ifndef NO_MD5
+#include <openssl/md5.h>
+#endif
+#ifndef NO_SHA
+#include <openssl/sha.h>
+#endif
+#ifndef NO_RIPEMD
+#include <openssl/ripemd.h>
+#endif
+#ifndef NO_DES
+#include <openssl/des.h>
+#endif
+#ifndef NO_RC4
+#include <openssl/rc4.h>
+#endif
+#ifndef NO_RC2
+#include <openssl/rc2.h>
+#endif
+#ifndef NO_RC5
+#include <openssl/rc5.h>
+#endif
+#ifndef NO_BF
+#include <openssl/blowfish.h>
+#endif
+#ifndef NO_CAST
+#include <openssl/cast.h>
+#endif
+#ifndef NO_IDEA
+#include <openssl/idea.h>
+#endif
+#ifndef NO_MDC2
+#include <openssl/mdc2.h>
+#endif
+
+#define EVP_RC2_KEY_SIZE		16
+#define EVP_RC4_KEY_SIZE		16
+#define EVP_BLOWFISH_KEY_SIZE		16
+#define EVP_CAST5_KEY_SIZE		16
+#define EVP_RC5_32_12_16_KEY_SIZE	16
+#define EVP_MAX_MD_SIZE			(16+20) /* The SSLv3 md5+sha1 type */
+#define EVP_MAX_KEY_LENGTH		24
+#define EVP_MAX_IV_LENGTH		8
+
+#define PKCS5_SALT_LEN			8
+/* Default PKCS#5 iteration count */
+#define PKCS5_DEFAULT_ITER		2048
+
+#ifndef NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+#ifndef NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#ifndef NO_DH
+#include <openssl/dh.h>
+#endif
+
+#include <openssl/objects.h>
+
+#define EVP_PK_RSA	0x0001
+#define EVP_PK_DSA	0x0002
+#define EVP_PK_DH	0x0004
+#define EVP_PKT_SIGN	0x0010
+#define EVP_PKT_ENC	0x0020
+#define EVP_PKT_EXCH	0x0040
+#define EVP_PKS_RSA	0x0100
+#define EVP_PKS_DSA	0x0200
+#define EVP_PKT_EXP	0x1000 /* <= 512 bit key */
+
+#define EVP_PKEY_NONE	NID_undef
+#define EVP_PKEY_RSA	NID_rsaEncryption
+#define EVP_PKEY_RSA2	NID_rsa
+#define EVP_PKEY_DSA	NID_dsa
+#define EVP_PKEY_DSA1	NID_dsa_2
+#define EVP_PKEY_DSA2	NID_dsaWithSHA
+#define EVP_PKEY_DSA3	NID_dsaWithSHA1
+#define EVP_PKEY_DSA4	NID_dsaWithSHA1_2
+#define EVP_PKEY_DH	NID_dhKeyAgreement
+
+/* Type needs to be a bit field
+ * Sub-type needs to be for variations on the method, as in, can it do
+ * arbitrary encryption.... */
+typedef struct evp_pkey_st
+	{
+	int type;
+	int save_type;
+	int references;
+	union	{
+		char *ptr;
+#ifndef NO_RSA
+		struct rsa_st *rsa;	/* RSA */
+#endif
+#ifndef NO_DSA
+		struct dsa_st *dsa;	/* DSA */
+#endif
+#ifndef NO_DH
+		struct dh_st *dh;	/* DH */
+#endif
+		} pkey;
+	int save_parameters;
+	STACK /*X509_ATTRIBUTE*/ *attributes; /* [ 0 ] */
+	} EVP_PKEY;
+
+#define EVP_PKEY_MO_SIGN	0x0001
+#define EVP_PKEY_MO_VERIFY	0x0002
+#define EVP_PKEY_MO_ENCRYPT	0x0004
+#define EVP_PKEY_MO_DECRYPT	0x0008
+
+#if 0
+/* This structure is required to tie the message digest and signing together.
+ * The lookup can be done by md/pkey_method, oid, oid/pkey_method, or
+ * oid, md and pkey.
+ * This is required because for various smart-card perform the digest and
+ * signing/verification on-board.  To handle this case, the specific
+ * EVP_MD and EVP_PKEY_METHODs need to be closely associated.
+ * When a PKEY is created, it will have a EVP_PKEY_METHOD associated with it.
+ * This can either be software or a token to provide the required low level
+ * routines.
+ */
+typedef struct evp_pkey_md_st
+	{
+	int oid;
+	EVP_MD *md;
+	EVP_PKEY_METHOD *pkey;
+	} EVP_PKEY_MD;
+
+#define EVP_rsa_md2() \
+		EVP_PKEY_MD_add(NID_md2WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_md2())
+#define EVP_rsa_md5() \
+		EVP_PKEY_MD_add(NID_md5WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_md5())
+#define EVP_rsa_sha0() \
+		EVP_PKEY_MD_add(NID_shaWithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_sha())
+#define EVP_rsa_sha1() \
+		EVP_PKEY_MD_add(NID_sha1WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_sha1())
+#define EVP_rsa_ripemd160() \
+		EVP_PKEY_MD_add(NID_ripemd160WithRSA,\
+			EVP_rsa_pkcs1(),EVP_ripemd160())
+#define EVP_rsa_mdc2() \
+		EVP_PKEY_MD_add(NID_mdc2WithRSA,\
+			EVP_rsa_octet_string(),EVP_mdc2())
+#define EVP_dsa_sha() \
+		EVP_PKEY_MD_add(NID_dsaWithSHA,\
+			EVP_dsa(),EVP_mdc2())
+#define EVP_dsa_sha1() \
+		EVP_PKEY_MD_add(NID_dsaWithSHA1,\
+			EVP_dsa(),EVP_sha1())
+
+typedef struct evp_pkey_method_st
+	{
+	char *name;
+	int flags;
+	int type;		/* RSA, DSA, an SSLeay specific constant */
+	int oid;		/* For the pub-key type */
+	int encrypt_oid;	/* pub/priv key encryption */
+
+	int (*sign)();
+	int (*verify)();
+	struct	{
+		int
+		int (*set)();	/* get and/or set the underlying type */
+		int (*get)();
+		int (*encrypt)();
+		int (*decrypt)();
+		int (*i2d)();
+		int (*d2i)();
+		int (*dup)();
+		} pub,priv;
+	int (*set_asn1_parameters)();
+	int (*get_asn1_parameters)();
+	} EVP_PKEY_METHOD;
+#endif
+
+#ifndef EVP_MD
+typedef struct env_md_st
+	{
+	int type;
+	int pkey_type;
+	int md_size;
+	void (*init)();
+	void (*update)();
+	void (*final)();
+
+	int (*sign)();
+	int (*verify)();
+	int required_pkey_type[5]; /*EVP_PKEY_xxx */
+	int block_size;
+	int ctx_size; /* how big does the ctx need to be */
+	} EVP_MD;
+
+
+
+#define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
+
+#ifndef NO_DSA
+#define EVP_PKEY_DSA_method	DSA_sign,DSA_verify, \
+				{EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
+					EVP_PKEY_DSA4,0}
+#else
+#define EVP_PKEY_DSA_method	EVP_PKEY_NULL_method
+#endif
+
+#ifndef NO_RSA
+#define EVP_PKEY_RSA_method	RSA_sign,RSA_verify, \
+				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
+				RSA_sign_ASN1_OCTET_STRING, \
+				RSA_verify_ASN1_OCTET_STRING, \
+				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#else
+#define EVP_PKEY_RSA_method	EVP_PKEY_NULL_method
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
+#endif
+
+#endif /* !EVP_MD */
+
+typedef struct env_md_ctx_st
+	{
+	const EVP_MD *digest;
+	union	{
+		unsigned char base[4];
+#ifndef NO_MD2
+		MD2_CTX md2;
+#endif
+#ifndef NO_MD5
+		MD5_CTX md5;
+#endif
+#ifndef NO_RIPEMD
+		RIPEMD160_CTX ripemd160;
+#endif
+#ifndef NO_SHA
+		SHA_CTX sha;
+#endif
+#ifndef NO_MDC2
+		MDC2_CTX mdc2;
+#endif
+		} md;
+	} EVP_MD_CTX;
+
+typedef struct evp_cipher_st
+	{
+	int nid;
+	int block_size;
+	int key_len;
+	int iv_len;
+	void (*init)();		/* init for encryption */
+	void (*do_cipher)();	/* encrypt data */
+	void (*cleanup)();	/* used by cipher method */ 
+	int ctx_size;		/* how big the ctx needs to be */
+	/* int set_asn1_parameters(EVP_CIPHER_CTX,ASN1_TYPE *); */
+	int (*set_asn1_parameters)(); /* Populate a ASN1_TYPE with parameters */
+	/* int get_asn1_parameters(EVP_CIPHER_CTX,ASN1_TYPE *); */
+	int (*get_asn1_parameters)(); /* Get parameters from a ASN1_TYPE */
+	} EVP_CIPHER;
+
+typedef struct evp_cipher_info_st
+	{
+	const EVP_CIPHER *cipher;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+	} EVP_CIPHER_INFO;
+
+typedef struct evp_cipher_ctx_st
+	{
+	const EVP_CIPHER *cipher;
+	int encrypt;		/* encrypt or decrypt */
+	int buf_len;		/* number we have left */
+
+	unsigned char  oiv[EVP_MAX_IV_LENGTH];	/* original iv */
+	unsigned char  iv[EVP_MAX_IV_LENGTH];	/* working iv */
+	unsigned char buf[EVP_MAX_IV_LENGTH];	/* saved partial block */
+	int num;				/* used by cfb/ofb mode */
+
+	char *app_data;		/* application stuff */
+	union	{
+#ifndef NO_RC4
+		struct
+			{
+			unsigned char key[EVP_RC4_KEY_SIZE];
+			RC4_KEY ks;	/* working key */
+			} rc4;
+#endif
+#ifndef NO_DES
+		des_key_schedule des_ks;/* key schedule */
+		struct
+			{
+			des_key_schedule ks;/* key schedule */
+			des_cblock inw;
+			des_cblock outw;
+			} desx_cbc;
+		struct
+			{
+			des_key_schedule ks1;/* key schedule */
+			des_key_schedule ks2;/* key schedule (for ede) */
+			des_key_schedule ks3;/* key schedule (for ede3) */
+			} des_ede;
+#endif
+#ifndef NO_IDEA
+		IDEA_KEY_SCHEDULE idea_ks;/* key schedule */
+#endif
+#ifndef NO_RC2
+		RC2_KEY rc2_ks;/* key schedule */
+#endif
+#ifndef NO_RC5
+		RC5_32_KEY rc5_ks;/* key schedule */
+#endif
+#ifndef NO_BF
+		BF_KEY bf_ks;/* key schedule */
+#endif
+#ifndef NO_CAST
+		CAST_KEY cast_ks;/* key schedule */
+#endif
+		} c;
+	} EVP_CIPHER_CTX;
+
+typedef struct evp_Encode_Ctx_st
+	{
+	int num;	/* number saved in a partial encode/decode */
+	int length;	/* The length is either the output line length
+			 * (in input bytes) or the shortest input line
+			 * length that is ok.  Once decoding begins,
+			 * the length is adjusted up each time a longer
+			 * line is decoded */
+	unsigned char enc_data[80];	/* data to encode */
+	int line_num;	/* number read on current line */
+	int expect_nl;
+	} EVP_ENCODE_CTX;
+
+/* Password based encryption function */
+typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+		ASN1_TYPE *param, EVP_CIPHER *cipher,
+                EVP_MD *md, int en_de);
+
+#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+					(char *)(rsa))
+#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
+					(char *)(dsa))
+#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
+					(char *)(dh))
+
+/* Add some extra combinations */
+#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+#define EVP_MD_type(e)			((e)->type)
+#define EVP_MD_pkey_type(e)		((e)->pkey_type)
+#define EVP_MD_size(e)			((e)->md_size)
+#define EVP_MD_block_size(e)		((e)->block_size)
+
+#define EVP_MD_CTX_md(e)		((e)->digest)
+#define EVP_MD_CTX_size(e)		EVP_MD_size((e)->digest)
+#define EVP_MD_CTX_block_size(e)	EVP_MD_block_size((e)->digest)
+#define EVP_MD_CTX_type(e)		EVP_MD_type((e)->digest)
+
+#define EVP_CIPHER_nid(e)		((e)->nid)
+#define EVP_CIPHER_block_size(e)	((e)->block_size)
+#define EVP_CIPHER_key_length(e)	((e)->key_len)
+#define EVP_CIPHER_iv_length(e)		((e)->iv_len)
+
+#define EVP_CIPHER_CTX_cipher(e)	((e)->cipher)
+#define EVP_CIPHER_CTX_nid(e)		((e)->cipher->nid)
+#define EVP_CIPHER_CTX_block_size(e)	((e)->cipher->block_size)
+#define EVP_CIPHER_CTX_key_length(e)	((e)->cipher->key_len)
+#define EVP_CIPHER_CTX_iv_length(e)	((e)->cipher->iv_len)
+#define EVP_CIPHER_CTX_get_app_data(e)	((e)->app_data)
+#define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))
+#define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+
+#define EVP_ENCODE_LENGTH(l)	(((l+2)/3*4)+(l/48+1)*2+80)
+#define EVP_DECODE_LENGTH(l)	((l+3)/4*3+80)
+
+#define EVP_SignInit(a,b)		EVP_DigestInit(a,b)
+#define EVP_SignUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+#define	EVP_VerifyInit(a,b)		EVP_DigestInit(a,b)
+#define	EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+#define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
+#define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
+
+#ifdef CONST_STRICT
+void BIO_set_md(BIO *,const EVP_MD *md);
+#else
+# define BIO_set_md(b,md)		BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
+#endif
+#define BIO_get_md(b,mdp)		BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
+#define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+#define BIO_get_cipher_status(b)	BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
+#define BIO_get_cipher_ctx(b,c_pp)	BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
+
+#define	EVP_Cipher(c,o,i,l)	(c)->cipher->do_cipher((c),(o),(i),(l))
+
+#define EVP_add_cipher_alias(n,alias) \
+	OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_add_digest_alias(n,alias) \
+	OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_delete_cipher_alias(alias) \
+	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
+#define EVP_delete_digest_alias(alias) \
+	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
+
+
+int     EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);  
+void	EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+void	EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
+			 unsigned int cnt);
+void	EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
+
+int	EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
+void	EVP_set_pw_prompt(char *prompt);
+char *	EVP_get_pw_prompt(void);
+
+int	EVP_BytesToKey(const EVP_CIPHER *type,EVP_MD *md,unsigned char *salt,
+		unsigned char *data, int datal, int count,
+		unsigned char *key,unsigned char *iv);
+
+void	EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
+		unsigned char *key, unsigned char *iv);
+void	EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, unsigned char *in, int inl);
+void	EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+void	EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
+		unsigned char *key, unsigned char *iv);
+void	EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, unsigned char *in, int inl);
+int	EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+void	EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
+		       unsigned char *key,unsigned char *iv,int enc);
+void	EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, unsigned char *in, int inl);
+int	EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int	EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s,
+		EVP_PKEY *pkey);
+
+int	EVP_VerifyFinal(EVP_MD_CTX *ctx,unsigned char *sigbuf,
+		unsigned int siglen,EVP_PKEY *pkey);
+
+int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,EVP_CIPHER *type,unsigned char *ek,
+		int ekl,unsigned char *iv,EVP_PKEY *priv);
+int	EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int	EVP_SealInit(EVP_CIPHER_CTX *ctx, EVP_CIPHER *type, unsigned char **ek,
+		int *ekl, unsigned char *iv,EVP_PKEY **pubk, int npubk);
+void	EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl);
+
+void	EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+void	EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,
+		int *outl,unsigned char *in,int inl);
+void	EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl);
+int	EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void	EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+int	EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+		unsigned char *in, int inl);
+int	EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+		char *out, int *outl);
+int	EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void	ERR_load_EVP_strings(void );
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
+void EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
+
+#ifdef HEADER_BIO_H
+BIO_METHOD *BIO_f_md(void);
+BIO_METHOD *BIO_f_base64(void);
+BIO_METHOD *BIO_f_cipher(void);
+BIO_METHOD *BIO_f_reliable(void);
+void BIO_set_cipher(BIO *b,const EVP_CIPHER *c,unsigned char *k,
+	unsigned char *i, int enc);
+#endif
+
+EVP_MD *EVP_md_null(void);
+EVP_MD *EVP_md2(void);
+EVP_MD *EVP_md5(void);
+EVP_MD *EVP_sha(void);
+EVP_MD *EVP_sha1(void);
+EVP_MD *EVP_dss(void);
+EVP_MD *EVP_dss1(void);
+EVP_MD *EVP_mdc2(void);
+EVP_MD *EVP_ripemd160(void);
+
+EVP_CIPHER *EVP_enc_null(void);		/* does nothing :-) */
+EVP_CIPHER *EVP_des_ecb(void);
+EVP_CIPHER *EVP_des_ede(void);
+EVP_CIPHER *EVP_des_ede3(void);
+EVP_CIPHER *EVP_des_cfb(void);
+EVP_CIPHER *EVP_des_ede_cfb(void);
+EVP_CIPHER *EVP_des_ede3_cfb(void);
+EVP_CIPHER *EVP_des_ofb(void);
+EVP_CIPHER *EVP_des_ede_ofb(void);
+EVP_CIPHER *EVP_des_ede3_ofb(void);
+EVP_CIPHER *EVP_des_cbc(void);
+EVP_CIPHER *EVP_des_ede_cbc(void);
+EVP_CIPHER *EVP_des_ede3_cbc(void);
+EVP_CIPHER *EVP_desx_cbc(void);
+EVP_CIPHER *EVP_rc4(void);
+EVP_CIPHER *EVP_rc4_40(void);
+EVP_CIPHER *EVP_idea_ecb(void);
+EVP_CIPHER *EVP_idea_cfb(void);
+EVP_CIPHER *EVP_idea_ofb(void);
+EVP_CIPHER *EVP_idea_cbc(void);
+EVP_CIPHER *EVP_rc2_ecb(void);
+EVP_CIPHER *EVP_rc2_cbc(void);
+EVP_CIPHER *EVP_rc2_40_cbc(void);
+EVP_CIPHER *EVP_rc2_64_cbc(void);
+EVP_CIPHER *EVP_rc2_cfb(void);
+EVP_CIPHER *EVP_rc2_ofb(void);
+EVP_CIPHER *EVP_bf_ecb(void);
+EVP_CIPHER *EVP_bf_cbc(void);
+EVP_CIPHER *EVP_bf_cfb(void);
+EVP_CIPHER *EVP_bf_ofb(void);
+EVP_CIPHER *EVP_cast5_ecb(void);
+EVP_CIPHER *EVP_cast5_cbc(void);
+EVP_CIPHER *EVP_cast5_cfb(void);
+EVP_CIPHER *EVP_cast5_ofb(void);
+EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
+EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
+EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
+EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
+
+void OpenSSL_add_all_algorithms(void);
+void OpenSSL_add_all_ciphers(void);
+void OpenSSL_add_all_digests(void);
+#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
+#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
+#define SSLeay_add_all_digests() OpenSSL_add_all_digests()
+
+int EVP_add_cipher(EVP_CIPHER *cipher);
+int EVP_add_digest(EVP_MD *digest);
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+const EVP_MD *EVP_get_digestbyname(const char *name);
+void EVP_cleanup(void);
+
+int		EVP_PKEY_decrypt(unsigned char *dec_key,unsigned char *enc_key,
+			int enc_key_len,EVP_PKEY *private_key);
+int		EVP_PKEY_encrypt(unsigned char *enc_key,
+			unsigned char *key,int key_len,EVP_PKEY *pub_key);
+int		EVP_PKEY_type(int type);
+int		EVP_PKEY_bits(EVP_PKEY *pkey);
+int		EVP_PKEY_size(EVP_PKEY *pkey);
+int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key);
+#ifndef NO_RSA
+int 		EVP_PKEY_set1_RSA(EVP_PKEY *pkey,RSA *key);
+RSA *		EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+#endif
+#ifndef NO_DSA
+int 		EVP_PKEY_set1_DSA(EVP_PKEY *pkey,DSA *key);
+DSA *		EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+#endif
+#ifndef NO_DH
+int 		EVP_PKEY_set1_DH(EVP_PKEY *pkey,DH *key);
+DH *		EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+#endif
+EVP_PKEY *	EVP_PKEY_new(void);
+void		EVP_PKEY_free(EVP_PKEY *pkey);
+EVP_PKEY *	d2i_PublicKey(int type,EVP_PKEY **a, unsigned char **pp,
+			long length);
+int		i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+
+EVP_PKEY *	d2i_PrivateKey(int type,EVP_PKEY **a, unsigned char **pp,
+			long length);
+EVP_PKEY *	d2i_AutoPrivateKey(EVP_PKEY **a, unsigned char **pp,
+			long length);
+int		i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to,EVP_PKEY *from);
+int EVP_PKEY_missing_parameters(EVP_PKEY *pkey);
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
+int EVP_PKEY_cmp_parameters(EVP_PKEY *a,EVP_PKEY *b);
+
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
+
+/* calls methods */
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* These are used by EVP_CIPHER methods */
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
+
+/* PKCS5 password based encryption */
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, EVP_CIPHER *cipher, EVP_MD *md,
+			 int en_de);
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+			   unsigned char *salt, int saltlen, int iter,
+			   int keylen, unsigned char *out);
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, EVP_CIPHER *cipher, EVP_MD *md,
+			 int en_de);
+
+void PKCS5_PBE_add(void);
+
+int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+	     ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+int EVP_PBE_alg_add(int nid, EVP_CIPHER *cipher, EVP_MD *md,
+		    EVP_PBE_KEYGEN *keygen);
+void EVP_PBE_cleanup(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the EVP functions. */
+
+/* Function codes. */
+#define EVP_F_D2I_PKEY					 100
+#define EVP_F_EVP_DECRYPTFINAL				 101
+#define EVP_F_EVP_MD_CTX_COPY				 110
+#define EVP_F_EVP_OPENINIT				 102
+#define EVP_F_EVP_PBE_ALG_ADD				 115
+#define EVP_F_EVP_PBE_CIPHERINIT			 116
+#define EVP_F_EVP_PKCS82PKEY				 111
+#define EVP_F_EVP_PKCS8_SET_BROKEN			 112
+#define EVP_F_EVP_PKEY2PKCS8				 113
+#define EVP_F_EVP_PKEY_COPY_PARAMETERS			 103
+#define EVP_F_EVP_PKEY_DECRYPT				 104
+#define EVP_F_EVP_PKEY_ENCRYPT				 105
+#define EVP_F_EVP_PKEY_GET1_DH				 119
+#define EVP_F_EVP_PKEY_GET1_DSA				 120
+#define EVP_F_EVP_PKEY_GET1_RSA				 121
+#define EVP_F_EVP_PKEY_NEW				 106
+#define EVP_F_EVP_SIGNFINAL				 107
+#define EVP_F_EVP_VERIFYFINAL				 108
+#define EVP_F_PKCS5_PBE_KEYIVGEN			 117
+#define EVP_F_PKCS5_V2_PBE_KEYIVGEN			 118
+#define EVP_F_RC2_MAGIC_TO_METH				 109
+
+/* Reason codes. */
+#define EVP_R_BAD_DECRYPT				 100
+#define EVP_R_BN_DECODE_ERROR				 112
+#define EVP_R_BN_PUBKEY_ERROR				 113
+#define EVP_R_CIPHER_PARAMETER_ERROR			 122
+#define EVP_R_DECODE_ERROR				 114
+#define EVP_R_DIFFERENT_KEY_TYPES			 101
+#define EVP_R_ENCODE_ERROR				 115
+#define EVP_R_EVP_PBE_CIPHERINIT_ERROR			 119
+#define EVP_R_EXPECTING_AN_RSA_KEY			 127
+#define EVP_R_EXPECTING_A_DH_KEY			 128
+#define EVP_R_EXPECTING_A_DSA_KEY			 129
+#define EVP_R_INPUT_NOT_INITIALIZED			 111
+#define EVP_R_IV_TOO_LARGE				 102
+#define EVP_R_KEYGEN_FAILURE				 120
+#define EVP_R_MISSING_PARAMETERS			 103
+#define EVP_R_NO_DSA_PARAMETERS				 116
+#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
+#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
+#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE			 117
+#define EVP_R_PUBLIC_KEY_NOT_RSA			 106
+#define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
+#define EVP_R_UNSUPPORTED_CIPHER			 107
+#define EVP_R_UNSUPPORTED_KEYLENGTH			 123
+#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION	 124
+#define EVP_R_UNSUPPORTED_KEY_SIZE			 108
+#define EVP_R_UNSUPPORTED_PRF				 125
+#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM		 118
+#define EVP_R_UNSUPPORTED_SALT_TYPE			 126
+#define EVP_R_WRONG_FINAL_BLOCK_LENGTH			 109
+#define EVP_R_WRONG_PUBLIC_KEY_TYPE			 110
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/lhash.h b/AppleCSP/open_ssl/openssl/lhash.h
new file mode 100644
index 00000000..748d47b5
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/lhash.h
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/lhash/lhash.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Header for dynamic hash table routines
+ * Author - Eric Young
+ */
+
+#ifndef HEADER_LHASH_H
+#define HEADER_LHASH_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifndef NO_FP_API
+#include <stdio.h>
+#endif
+
+typedef struct lhash_node_st
+	{
+	void *data;
+	struct lhash_node_st *next;
+#ifndef NO_HASH_COMP
+	unsigned long hash;
+#endif
+	} LHASH_NODE;
+
+typedef struct lhash_st
+	{
+	LHASH_NODE **b;
+	int (*comp)();
+	unsigned long (*hash)();
+	unsigned int num_nodes;
+	unsigned int num_alloc_nodes;
+	unsigned int p;
+	unsigned int pmax;
+	unsigned long up_load; /* load times 256 */
+	unsigned long down_load; /* load times 256 */
+	unsigned long num_items;
+
+	unsigned long num_expands;
+	unsigned long num_expand_reallocs;
+	unsigned long num_contracts;
+	unsigned long num_contract_reallocs;
+	unsigned long num_hash_calls;
+	unsigned long num_comp_calls;
+	unsigned long num_insert;
+	unsigned long num_replace;
+	unsigned long num_delete;
+	unsigned long num_no_delete;
+	unsigned long num_retrieve;
+	unsigned long num_retrieve_miss;
+	unsigned long num_hash_comps;
+
+	int error;
+	} LHASH;
+
+#define LH_LOAD_MULT	256
+
+/* Indicates a malloc() error in the last call, this is only bad
+ * in lh_insert(). */
+#define lh_error(lh)	((lh)->error)
+
+LHASH *lh_new(unsigned long (*h)(/* void *a */), int (*c)(/* void *a,void *b */));
+void lh_free(LHASH *lh);
+void *lh_insert(LHASH *lh, void *data);
+void *lh_delete(LHASH *lh, void *data);
+void *lh_retrieve(LHASH *lh, void *data);
+    void lh_doall(LHASH *lh, void (*func)(/*void *b*/));
+void lh_doall_arg(LHASH *lh, void (*func)(/*void *a,void *b*/),void *arg);
+unsigned long lh_strhash(const char *c);
+unsigned long lh_num_items(LHASH *lh);
+
+#ifndef NO_FP_API
+void lh_stats(LHASH *lh, FILE *out);
+void lh_node_stats(LHASH *lh, FILE *out);
+void lh_node_usage_stats(LHASH *lh, FILE *out);
+#endif
+
+#ifdef HEADER_BIO_H
+void lh_stats_bio(LHASH *lh, BIO *out);
+void lh_node_stats_bio(LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(LHASH *lh, BIO *out);
+#endif
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/md2.h b/AppleCSP/open_ssl/openssl/md2.h
new file mode 100644
index 00000000..582bffb8
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/md2.h
@@ -0,0 +1,91 @@
+/* crypto/md/md2.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD2_H
+#define HEADER_MD2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_MD2
+#error MD2 is disabled.
+#endif
+
+#define MD2_DIGEST_LENGTH	16
+#define MD2_BLOCK       	16
+#include <openssl/opensslconf.h> /* MD2_INT */
+
+typedef struct MD2state_st
+	{
+	int num;
+	unsigned char data[MD2_BLOCK];
+	MD2_INT cksm[MD2_BLOCK];
+	MD2_INT state[MD2_BLOCK];
+	} MD2_CTX;
+
+const char *MD2_options(void);
+void MD2_Init(MD2_CTX *c);
+void MD2_Update(MD2_CTX *c, const unsigned char *data, unsigned long len);
+void MD2_Final(unsigned char *md, MD2_CTX *c);
+unsigned char *MD2(const unsigned char *d, unsigned long n,unsigned char *md);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/openssl/objects.h b/AppleCSP/open_ssl/openssl/objects.h
new file mode 100644
index 00000000..d65f8cf9
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/objects.h
@@ -0,0 +1,1050 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/objects/objects.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_OBJECTS_H
+#define HEADER_OBJECTS_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define SN_undef			"UNDEF"
+#define LN_undef			"undefined"
+#define NID_undef			0
+#define OBJ_undef			0L
+
+#define SN_Algorithm			"Algorithm"
+#define LN_algorithm			"algorithm"
+#define NID_algorithm			38
+#define OBJ_algorithm			1L,3L,14L,3L,2L
+
+#define LN_rsadsi			"rsadsi"
+#define NID_rsadsi			1
+#define OBJ_rsadsi			1L,2L,840L,113549L
+
+#define LN_pkcs				"pkcs"
+#define NID_pkcs			2
+#define OBJ_pkcs			OBJ_rsadsi,1L
+
+#define SN_md2				"MD2"
+#define LN_md2				"md2"
+#define NID_md2				3
+#define OBJ_md2				OBJ_rsadsi,2L,2L
+
+#define SN_md5				"MD5"
+#define LN_md5				"md5"
+#define NID_md5				4
+#define OBJ_md5				OBJ_rsadsi,2L,5L
+
+#define SN_rc4				"RC4"
+#define LN_rc4				"rc4"
+#define NID_rc4				5
+#define OBJ_rc4				OBJ_rsadsi,3L,4L
+
+#define LN_rsaEncryption		"rsaEncryption"
+#define NID_rsaEncryption		6
+#define OBJ_rsaEncryption		OBJ_pkcs,1L,1L
+
+#define SN_md2WithRSAEncryption		"RSA-MD2"
+#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption	7
+#define OBJ_md2WithRSAEncryption	OBJ_pkcs,1L,2L
+
+#define SN_md5WithRSAEncryption		"RSA-MD5"
+#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption	8
+#define OBJ_md5WithRSAEncryption	OBJ_pkcs,1L,4L
+
+#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC	9
+#define OBJ_pbeWithMD2AndDES_CBC	OBJ_pkcs,5L,1L
+
+#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC	10
+#define OBJ_pbeWithMD5AndDES_CBC	OBJ_pkcs,5L,3L
+
+#define LN_X500				"X500"
+#define NID_X500			11
+#define OBJ_X500			2L,5L
+
+#define LN_X509				"X509"
+#define NID_X509			12
+#define OBJ_X509			OBJ_X500,4L
+
+#define SN_commonName			"CN"
+#define LN_commonName			"commonName"
+#define NID_commonName			13
+#define OBJ_commonName			OBJ_X509,3L
+
+#define SN_countryName			"C"
+#define LN_countryName			"countryName"
+#define NID_countryName			14
+#define OBJ_countryName			OBJ_X509,6L
+
+#define SN_localityName			"L"
+#define LN_localityName			"localityName"
+#define NID_localityName		15
+#define OBJ_localityName		OBJ_X509,7L
+
+/* Postal Address? PA */
+
+/* should be "ST" (rfc1327) but MS uses 'S' */
+#define SN_stateOrProvinceName		"ST"
+#define LN_stateOrProvinceName		"stateOrProvinceName"
+#define NID_stateOrProvinceName		16
+#define OBJ_stateOrProvinceName		OBJ_X509,8L
+
+#define SN_organizationName		"O"
+#define LN_organizationName		"organizationName"
+#define NID_organizationName		17
+#define OBJ_organizationName		OBJ_X509,10L
+
+#define SN_organizationalUnitName	"OU"
+#define LN_organizationalUnitName	"organizationalUnitName"
+#define NID_organizationalUnitName	18
+#define OBJ_organizationalUnitName	OBJ_X509,11L
+
+#define SN_rsa				"RSA"
+#define LN_rsa				"rsa"
+#define NID_rsa				19
+#define OBJ_rsa				OBJ_X500,8L,1L,1L
+
+#define LN_pkcs7			"pkcs7"
+#define NID_pkcs7			20
+#define OBJ_pkcs7			OBJ_pkcs,7L
+
+#define LN_pkcs7_data			"pkcs7-data"
+#define NID_pkcs7_data			21
+#define OBJ_pkcs7_data			OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed			"pkcs7-signedData"
+#define NID_pkcs7_signed		22
+#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
+#define NID_pkcs7_enveloped		23
+#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped	"pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped	24
+#define OBJ_pkcs7_signedAndEnveloped	OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest			"pkcs7-digestData"
+#define NID_pkcs7_digest		25
+#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
+#define NID_pkcs7_encrypted		26
+#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
+
+#define LN_pkcs3			"pkcs3"
+#define NID_pkcs3			27
+#define OBJ_pkcs3			OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement		"dhKeyAgreement"
+#define NID_dhKeyAgreement		28
+#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
+
+#define SN_des_ecb			"DES-ECB"
+#define LN_des_ecb			"des-ecb"
+#define NID_des_ecb			29
+#define OBJ_des_ecb			OBJ_algorithm,6L
+
+#define SN_des_cfb64			"DES-CFB"
+#define LN_des_cfb64			"des-cfb"
+#define NID_des_cfb64			30
+/* IV + num */
+#define OBJ_des_cfb64			OBJ_algorithm,9L
+
+#define SN_des_cbc			"DES-CBC"
+#define LN_des_cbc			"des-cbc"
+#define NID_des_cbc			31
+/* IV */
+#define OBJ_des_cbc			OBJ_algorithm,7L
+
+#define SN_des_ede			"DES-EDE"
+#define LN_des_ede			"des-ede"
+#define NID_des_ede			32
+/* ?? */
+#define OBJ_des_ede			OBJ_algorithm,17L
+
+#define SN_des_ede3			"DES-EDE3"
+#define LN_des_ede3			"des-ede3"
+#define NID_des_ede3			33
+
+#define SN_idea_cbc			"IDEA-CBC"
+#define LN_idea_cbc			"idea-cbc"
+#define NID_idea_cbc			34
+#define OBJ_idea_cbc			1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_cfb64			"IDEA-CFB"
+#define LN_idea_cfb64			"idea-cfb"
+#define NID_idea_cfb64			35
+
+#define SN_idea_ecb			"IDEA-ECB"
+#define LN_idea_ecb			"idea-ecb"
+#define NID_idea_ecb			36
+
+#define SN_rc2_cbc			"RC2-CBC"
+#define LN_rc2_cbc			"rc2-cbc"
+#define NID_rc2_cbc			37
+#define OBJ_rc2_cbc			OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb			"RC2-ECB"
+#define LN_rc2_ecb			"rc2-ecb"
+#define NID_rc2_ecb			38
+
+#define SN_rc2_cfb64			"RC2-CFB"
+#define LN_rc2_cfb64			"rc2-cfb"
+#define NID_rc2_cfb64			39
+
+#define SN_rc2_ofb64			"RC2-OFB"
+#define LN_rc2_ofb64			"rc2-ofb"
+#define NID_rc2_ofb64			40
+
+#define SN_sha				"SHA"
+#define LN_sha				"sha"
+#define NID_sha				41
+#define OBJ_sha				OBJ_algorithm,18L
+
+#define SN_shaWithRSAEncryption		"RSA-SHA"
+#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption	42
+#define OBJ_shaWithRSAEncryption	OBJ_algorithm,15L
+
+#define SN_des_ede_cbc			"DES-EDE-CBC"
+#define LN_des_ede_cbc			"des-ede-cbc"
+#define NID_des_ede_cbc			43
+
+#define SN_des_ede3_cbc			"DES-EDE3-CBC"
+#define LN_des_ede3_cbc			"des-ede3-cbc"
+#define NID_des_ede3_cbc		44
+#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
+
+#define SN_des_ofb64			"DES-OFB"
+#define LN_des_ofb64			"des-ofb"
+#define NID_des_ofb64			45
+#define OBJ_des_ofb64			OBJ_algorithm,8L
+
+#define SN_idea_ofb64			"IDEA-OFB"
+#define LN_idea_ofb64			"idea-ofb"
+#define NID_idea_ofb64			46
+
+#define LN_pkcs9			"pkcs9"
+#define NID_pkcs9			47
+#define OBJ_pkcs9			OBJ_pkcs,9L
+
+#define SN_pkcs9_emailAddress		"Email"
+#define LN_pkcs9_emailAddress		"emailAddress"
+#define NID_pkcs9_emailAddress		48
+#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName	"unstructuredName"
+#define NID_pkcs9_unstructuredName	49
+#define OBJ_pkcs9_unstructuredName	OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType		"contentType"
+#define NID_pkcs9_contentType		50
+#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest		"messageDigest"
+#define NID_pkcs9_messageDigest		51
+#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime		"signingTime"
+#define NID_pkcs9_signingTime		52
+#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature	"countersignature"
+#define NID_pkcs9_countersignature	53
+#define OBJ_pkcs9_countersignature	OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword	"challengePassword"
+#define NID_pkcs9_challengePassword	54
+#define OBJ_pkcs9_challengePassword	OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress	"unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress	55
+#define OBJ_pkcs9_unstructuredAddress	OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes	"extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes	56
+#define OBJ_pkcs9_extCertAttributes	OBJ_pkcs9,9L
+
+#define SN_netscape			"Netscape"
+#define LN_netscape			"Netscape Communications Corp."
+#define NID_netscape			57
+#define OBJ_netscape			2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension	"nsCertExt"
+#define LN_netscape_cert_extension	"Netscape Certificate Extension"
+#define NID_netscape_cert_extension	58
+#define OBJ_netscape_cert_extension	OBJ_netscape,1L
+
+#define SN_netscape_data_type		"nsDataType"
+#define LN_netscape_data_type		"Netscape Data Type"
+#define NID_netscape_data_type		59
+#define OBJ_netscape_data_type		OBJ_netscape,2L
+
+#define SN_des_ede_cfb64		"DES-EDE-CFB"
+#define LN_des_ede_cfb64		"des-ede-cfb"
+#define NID_des_ede_cfb64		60
+
+#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
+#define LN_des_ede3_cfb64		"des-ede3-cfb"
+#define NID_des_ede3_cfb64		61
+
+#define SN_des_ede_ofb64		"DES-EDE-OFB"
+#define LN_des_ede_ofb64		"des-ede-ofb"
+#define NID_des_ede_ofb64		62
+
+#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
+#define LN_des_ede3_ofb64		"des-ede3-ofb"
+#define NID_des_ede3_ofb64		63
+
+/* I'm not sure about the object ID */
+#define SN_sha1				"SHA1"
+#define LN_sha1				"sha1"
+#define NID_sha1			64
+#define OBJ_sha1			OBJ_algorithm,26L
+/* 28 Jun 1996 - eay */
+/* #define OBJ_sha1			1L,3L,14L,2L,26L,05L <- wrong */
+
+#define SN_sha1WithRSAEncryption	"RSA-SHA1"
+#define LN_sha1WithRSAEncryption	"sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption	65
+#define OBJ_sha1WithRSAEncryption	OBJ_pkcs,1L,5L
+
+#define SN_dsaWithSHA			"DSA-SHA"
+#define LN_dsaWithSHA			"dsaWithSHA"
+#define NID_dsaWithSHA			66
+#define OBJ_dsaWithSHA			OBJ_algorithm,13L
+
+#define SN_dsa_2			"DSA-old"
+#define LN_dsa_2			"dsaEncryption-old"
+#define NID_dsa_2			67
+#define OBJ_dsa_2			OBJ_algorithm,12L
+
+/* proposed by microsoft to RSA */
+#define SN_pbeWithSHA1AndRC2_CBC	"PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC	"pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC	68
+#define OBJ_pbeWithSHA1AndRC2_CBC	OBJ_pkcs,5L,11L 
+
+/* proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now
+ * defined explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something
+ * completely different.
+ */
+#define LN_id_pbkdf2			"PBKDF2"
+#define NID_id_pbkdf2			69
+#define OBJ_id_pbkdf2			OBJ_pkcs,5L,12L 
+
+#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
+#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2		70
+/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
+#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
+
+#define SN_netscape_cert_type		"nsCertType"
+#define LN_netscape_cert_type		"Netscape Cert Type"
+#define NID_netscape_cert_type		71
+#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url		"nsBaseUrl"
+#define LN_netscape_base_url		"Netscape Base Url"
+#define NID_netscape_base_url		72
+#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url	"nsRevocationUrl"
+#define LN_netscape_revocation_url	"Netscape Revocation Url"
+#define NID_netscape_revocation_url	73
+#define OBJ_netscape_revocation_url	OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url	"nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url	"Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url	74
+#define OBJ_netscape_ca_revocation_url	OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url		"nsRenewalUrl"
+#define LN_netscape_renewal_url		"Netscape Renewal Url"
+#define NID_netscape_renewal_url	75
+#define OBJ_netscape_renewal_url	OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url	"nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url	"Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url	76
+#define OBJ_netscape_ca_policy_url	OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name	"nsSslServerName"
+#define LN_netscape_ssl_server_name	"Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name	77
+#define OBJ_netscape_ssl_server_name	OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment		"nsComment"
+#define LN_netscape_comment		"Netscape Comment"
+#define NID_netscape_comment		78
+#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence	"nsCertSequence"
+#define LN_netscape_cert_sequence	"Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence	79
+#define OBJ_netscape_cert_sequence	OBJ_netscape_data_type,5L
+
+#define SN_desx_cbc			"DESX-CBC"
+#define LN_desx_cbc			"desx-cbc"
+#define NID_desx_cbc			80
+
+#define SN_ld_ce			"ld-ce"
+#define NID_ld_ce			81
+#define OBJ_ld_ce			2L,5L,29L
+
+#define SN_subject_key_identifier	"subjectKeyIdentifier"
+#define LN_subject_key_identifier	"X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier	82
+#define OBJ_subject_key_identifier	OBJ_ld_ce,14L
+
+#define SN_key_usage			"keyUsage"
+#define LN_key_usage			"X509v3 Key Usage"
+#define NID_key_usage			83
+#define OBJ_key_usage			OBJ_ld_ce,15L
+
+#define SN_private_key_usage_period	"privateKeyUsagePeriod"
+#define LN_private_key_usage_period	"X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period	84
+#define OBJ_private_key_usage_period	OBJ_ld_ce,16L
+
+#define SN_subject_alt_name		"subjectAltName"
+#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
+#define NID_subject_alt_name		85
+#define OBJ_subject_alt_name		OBJ_ld_ce,17L
+
+#define SN_issuer_alt_name		"issuerAltName"
+#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name		86
+#define OBJ_issuer_alt_name		OBJ_ld_ce,18L
+
+#define SN_basic_constraints		"basicConstraints"
+#define LN_basic_constraints		"X509v3 Basic Constraints"
+#define NID_basic_constraints		87
+#define OBJ_basic_constraints		OBJ_ld_ce,19L
+
+#define SN_crl_number			"crlNumber"
+#define LN_crl_number			"X509v3 CRL Number"
+#define NID_crl_number			88
+#define OBJ_crl_number			OBJ_ld_ce,20L
+
+#define SN_certificate_policies		"certificatePolicies"
+#define LN_certificate_policies		"X509v3 Certificate Policies"
+#define NID_certificate_policies	89
+#define OBJ_certificate_policies	OBJ_ld_ce,32L
+
+#define SN_authority_key_identifier	"authorityKeyIdentifier"
+#define LN_authority_key_identifier	"X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier	90
+#define OBJ_authority_key_identifier	OBJ_ld_ce,35L
+
+#define SN_bf_cbc			"BF-CBC"
+#define LN_bf_cbc			"bf-cbc"
+#define NID_bf_cbc			91
+#define OBJ_bf_cbc			1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb			"BF-ECB"
+#define LN_bf_ecb			"bf-ecb"
+#define NID_bf_ecb			92
+
+#define SN_bf_cfb64			"BF-CFB"
+#define LN_bf_cfb64			"bf-cfb"
+#define NID_bf_cfb64			93
+
+#define SN_bf_ofb64			"BF-OFB"
+#define LN_bf_ofb64			"bf-ofb"
+#define NID_bf_ofb64			94
+
+#define SN_mdc2				"MDC2"
+#define LN_mdc2				"mdc2"
+#define NID_mdc2			95
+#define OBJ_mdc2			2L,5L,8L,3L,101L
+/* An alternative?			1L,3L,14L,3L,2L,19L */
+
+#define SN_mdc2WithRSA			"RSA-MDC2"
+#define LN_mdc2WithRSA			"mdc2withRSA"
+#define NID_mdc2WithRSA			96
+#define OBJ_mdc2WithRSA			2L,5L,8L,3L,100L
+
+#define SN_rc4_40			"RC4-40"
+#define LN_rc4_40			"rc4-40"
+#define NID_rc4_40			97
+
+#define SN_rc2_40_cbc			"RC2-40-CBC"
+#define LN_rc2_40_cbc			"rc2-40-cbc"
+#define NID_rc2_40_cbc			98
+
+#define SN_givenName			"G"
+#define LN_givenName			"givenName"
+#define NID_givenName			99
+#define OBJ_givenName			OBJ_X509,42L
+
+#define SN_surname			"S"
+#define LN_surname			"surname"
+#define NID_surname			100
+#define OBJ_surname			OBJ_X509,4L
+
+#define SN_initials			"I"
+#define LN_initials			"initials"
+#define NID_initials			101
+#define OBJ_initials			OBJ_X509,43L
+
+#define SN_uniqueIdentifier		"UID"
+#define LN_uniqueIdentifier		"uniqueIdentifier"
+#define NID_uniqueIdentifier		102
+#define OBJ_uniqueIdentifier		OBJ_X509,45L
+
+#define SN_crl_distribution_points	"crlDistributionPoints"
+#define LN_crl_distribution_points	"X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points	103
+#define OBJ_crl_distribution_points	OBJ_ld_ce,31L
+
+#define SN_md5WithRSA			"RSA-NP-MD5"
+#define LN_md5WithRSA			"md5WithRSA"
+#define NID_md5WithRSA			104
+#define OBJ_md5WithRSA			OBJ_algorithm,3L
+
+#define SN_serialNumber			"SN"
+#define LN_serialNumber			"serialNumber"
+#define NID_serialNumber		105
+#define OBJ_serialNumber		OBJ_X509,5L
+
+#define SN_title			"T"
+#define LN_title			"title"
+#define NID_title			106
+#define OBJ_title			OBJ_X509,12L
+
+#define SN_description			"D"
+#define LN_description			"description"
+#define NID_description			107
+#define OBJ_description			OBJ_X509,13L
+
+/* CAST5 is CAST-128, I'm just sticking with the documentation */
+#define SN_cast5_cbc			"CAST5-CBC"
+#define LN_cast5_cbc			"cast5-cbc"
+#define NID_cast5_cbc			108
+#define OBJ_cast5_cbc			1L,2L,840L,113533L,7L,66L,10L
+
+#define SN_cast5_ecb			"CAST5-ECB"
+#define LN_cast5_ecb			"cast5-ecb"
+#define NID_cast5_ecb			109
+
+#define SN_cast5_cfb64			"CAST5-CFB"
+#define LN_cast5_cfb64			"cast5-cfb"
+#define NID_cast5_cfb64			110
+
+#define SN_cast5_ofb64			"CAST5-OFB"
+#define LN_cast5_ofb64			"cast5-ofb"
+#define NID_cast5_ofb64			111
+
+#define LN_pbeWithMD5AndCast5_CBC	"pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC	112
+#define OBJ_pbeWithMD5AndCast5_CBC	1L,2L,840L,113533L,7L,66L,12L
+
+/* This is one sun will soon be using :-(
+ * id-dsa-with-sha1 ID  ::= {
+ *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
+ */
+#define SN_dsaWithSHA1			"DSA-SHA1"
+#define LN_dsaWithSHA1			"dsaWithSHA1"
+#define NID_dsaWithSHA1			113
+#define OBJ_dsaWithSHA1			1L,2L,840L,10040L,4L,3L
+
+#define NID_md5_sha1			114
+#define SN_md5_sha1			"MD5-SHA1"
+#define LN_md5_sha1			"md5-sha1"
+
+#define SN_sha1WithRSA			"RSA-SHA1-2"
+#define LN_sha1WithRSA			"sha1WithRSA"
+#define NID_sha1WithRSA			115
+#define OBJ_sha1WithRSA			OBJ_algorithm,29L
+
+#define SN_dsa				"DSA"
+#define LN_dsa				"dsaEncryption"
+#define NID_dsa				116
+#define OBJ_dsa				1L,2L,840L,10040L,4L,1L
+
+#define SN_ripemd160			"RIPEMD160"
+#define LN_ripemd160			"ripemd160"
+#define NID_ripemd160			117
+#define OBJ_ripemd160			1L,3L,36L,3L,2L,1L
+
+/* The name should actually be rsaSignatureWithripemd160, but I'm going
+ * to continue using the convention I'm using with the other ciphers */
+#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
+#define LN_ripemd160WithRSA		"ripemd160WithRSA"
+#define NID_ripemd160WithRSA		119
+#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
+
+/* Taken from rfc2040
+ *  RC5_CBC_Parameters ::= SEQUENCE {
+ *	version           INTEGER (v1_0(16)),
+ *	rounds            INTEGER (8..127),
+ *	blockSizeInBits   INTEGER (64, 128),
+ *	iv                OCTET STRING OPTIONAL
+ *	}
+ */
+#define SN_rc5_cbc			"RC5-CBC"
+#define LN_rc5_cbc			"rc5-cbc"
+#define NID_rc5_cbc			120
+#define OBJ_rc5_cbc			OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb			"RC5-ECB"
+#define LN_rc5_ecb			"rc5-ecb"
+#define NID_rc5_ecb			121
+
+#define SN_rc5_cfb64			"RC5-CFB"
+#define LN_rc5_cfb64			"rc5-cfb"
+#define NID_rc5_cfb64			122
+
+#define SN_rc5_ofb64			"RC5-OFB"
+#define LN_rc5_ofb64			"rc5-ofb"
+#define NID_rc5_ofb64			123
+
+#define SN_rle_compression		"RLE"
+#define LN_rle_compression		"run length compression"
+#define NID_rle_compression		124
+#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression		"ZLIB"
+#define LN_zlib_compression		"zlib compression"
+#define NID_zlib_compression		125
+#define OBJ_zlib_compression		1L,1L,1L,1L,666L,2L
+
+#define SN_ext_key_usage		"extendedKeyUsage"
+#define LN_ext_key_usage		"X509v3 Extended Key Usage"
+#define NID_ext_key_usage		126
+#define OBJ_ext_key_usage		OBJ_ld_ce,37
+
+#define SN_id_pkix			"PKIX"
+#define NID_id_pkix			127
+#define OBJ_id_pkix			1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_kp			"id-kp"
+#define NID_id_kp			128
+#define OBJ_id_kp			OBJ_id_pkix,3L
+
+/* PKIX extended key usage OIDs */
+
+#define SN_server_auth			"serverAuth"
+#define LN_server_auth			"TLS Web Server Authentication"
+#define NID_server_auth			129
+#define OBJ_server_auth			OBJ_id_kp,1L
+
+#define SN_client_auth			"clientAuth"
+#define LN_client_auth			"TLS Web Client Authentication"
+#define NID_client_auth			130
+#define OBJ_client_auth			OBJ_id_kp,2L
+
+#define SN_code_sign			"codeSigning"
+#define LN_code_sign			"Code Signing"
+#define NID_code_sign			131
+#define OBJ_code_sign			OBJ_id_kp,3L
+
+#define SN_email_protect		"emailProtection"
+#define LN_email_protect		"E-mail Protection"
+#define NID_email_protect		132
+#define OBJ_email_protect		OBJ_id_kp,4L
+
+#define SN_time_stamp			"timeStamping"
+#define LN_time_stamp			"Time Stamping"
+#define NID_time_stamp			133
+#define OBJ_time_stamp			OBJ_id_kp,8L
+
+/* Additional extended key usage OIDs: Microsoft */
+
+#define SN_ms_code_ind			"msCodeInd"
+#define LN_ms_code_ind			"Microsoft Individual Code Signing"
+#define NID_ms_code_ind			134
+#define OBJ_ms_code_ind			1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com			"msCodeCom"
+#define LN_ms_code_com			"Microsoft Commercial Code Signing"
+#define NID_ms_code_com			135
+#define OBJ_ms_code_com			1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign			"msCTLSign"
+#define LN_ms_ctl_sign			"Microsoft Trust List Signing"
+#define NID_ms_ctl_sign			136
+#define OBJ_ms_ctl_sign			1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc			"msSGC"
+#define LN_ms_sgc			"Microsoft Server Gated Crypto"
+#define NID_ms_sgc			137
+#define OBJ_ms_sgc			1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs			"msEFS"
+#define LN_ms_efs			"Microsoft Encrypted File System"
+#define NID_ms_efs			138
+#define OBJ_ms_efs			1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+/* Additional usage: Netscape */
+
+#define SN_ns_sgc			"nsSGC"
+#define LN_ns_sgc			"Netscape Server Gated Crypto"
+#define NID_ns_sgc			139
+#define OBJ_ns_sgc			OBJ_netscape,4L,1L
+
+#define SN_delta_crl			"deltaCRL"
+#define LN_delta_crl			"X509v3 Delta CRL Indicator"
+#define NID_delta_crl			140
+#define OBJ_delta_crl			OBJ_ld_ce,27L
+
+#define SN_crl_reason			"CRLReason"
+#define LN_crl_reason			"CRL Reason Code"
+#define NID_crl_reason			141
+#define OBJ_crl_reason			OBJ_ld_ce,21L
+
+#define SN_invalidity_date		"invalidityDate"
+#define LN_invalidity_date		"Invalidity Date"
+#define NID_invalidity_date		142
+#define OBJ_invalidity_date		OBJ_ld_ce,24L
+
+#define SN_sxnet			"SXNetID"
+#define LN_sxnet			"Strong Extranet ID"
+#define NID_sxnet			143
+#define OBJ_sxnet			1L,3L,101L,1L,4L,1L
+
+/* PKCS12 and related OBJECT IDENTIFIERS */
+
+#define OBJ_pkcs12			OBJ_pkcs,12L
+#define OBJ_pkcs12_pbeids		OBJ_pkcs12, 1
+
+#define SN_pbe_WithSHA1And128BitRC4	"PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4	"pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4	144
+#define OBJ_pbe_WithSHA1And128BitRC4	OBJ_pkcs12_pbeids, 1L
+
+#define SN_pbe_WithSHA1And40BitRC4	"PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4	"pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4	145
+#define OBJ_pbe_WithSHA1And40BitRC4	OBJ_pkcs12_pbeids, 2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC	"PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC	"pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC	146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC	"PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC	"pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC	147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC	148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC	OBJ_pkcs12_pbeids, 5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC	"PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC	"pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC	149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC	OBJ_pkcs12_pbeids, 6L
+
+#define OBJ_pkcs12_Version1	OBJ_pkcs12, 10L
+
+#define OBJ_pkcs12_BagIds	OBJ_pkcs12_Version1, 1L
+
+#define LN_keyBag		"keyBag"
+#define NID_keyBag		150
+#define OBJ_keyBag		OBJ_pkcs12_BagIds, 1L
+
+#define LN_pkcs8ShroudedKeyBag	"pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag	151
+#define OBJ_pkcs8ShroudedKeyBag	OBJ_pkcs12_BagIds, 2L
+
+#define LN_certBag		"certBag"
+#define NID_certBag		152
+#define OBJ_certBag		OBJ_pkcs12_BagIds, 3L
+
+#define LN_crlBag		"crlBag"
+#define NID_crlBag		153
+#define OBJ_crlBag		OBJ_pkcs12_BagIds, 4L
+
+#define LN_secretBag		"secretBag"
+#define NID_secretBag		154
+#define OBJ_secretBag		OBJ_pkcs12_BagIds, 5L
+
+#define LN_safeContentsBag	"safeContentsBag"
+#define NID_safeContentsBag	155
+#define OBJ_safeContentsBag	OBJ_pkcs12_BagIds, 6L
+
+#define LN_friendlyName		"friendlyName"
+#define	NID_friendlyName	156
+#define OBJ_friendlyName	OBJ_pkcs9, 20L
+
+#define LN_localKeyID		"localKeyID"
+#define	NID_localKeyID		157
+#define OBJ_localKeyID		OBJ_pkcs9, 21L
+
+#define OBJ_certTypes		OBJ_pkcs9, 22L
+
+#define LN_x509Certificate	"x509Certificate"
+#define	NID_x509Certificate	158
+#define OBJ_x509Certificate	OBJ_certTypes, 1L
+
+#define LN_sdsiCertificate	"sdsiCertificate"
+#define	NID_sdsiCertificate	159
+#define OBJ_sdsiCertificate	OBJ_certTypes, 2L
+
+#define OBJ_crlTypes		OBJ_pkcs9, 23L
+
+#define LN_x509Crl		"x509Crl"
+#define	NID_x509Crl		160
+#define OBJ_x509Crl		OBJ_crlTypes, 1L
+
+/* PKCS#5 v2 OIDs */
+
+#define LN_pbes2		"PBES2"
+#define NID_pbes2		161
+#define OBJ_pbes2		OBJ_pkcs,5L,13L
+
+#define LN_pbmac1		"PBMAC1"
+#define NID_pbmac1		162
+#define OBJ_pbmac1		OBJ_pkcs,5L,14L
+
+#define LN_hmacWithSHA1		"hmacWithSHA1"
+#define NID_hmacWithSHA1	163
+#define OBJ_hmacWithSHA1	OBJ_rsadsi,2L,7L
+
+/* Policy Qualifier Ids */
+
+#define LN_id_qt_cps		"Policy Qualifier CPS"
+#define SN_id_qt_cps		"id-qt-cps"
+#define NID_id_qt_cps		164
+#define OBJ_id_qt_cps		OBJ_id_pkix,2L,1L
+
+#define LN_id_qt_unotice	"Policy Qualifier User Notice"
+#define SN_id_qt_unotice	"id-qt-unotice"
+#define NID_id_qt_unotice	165
+#define OBJ_id_qt_unotice	OBJ_id_pkix,2L,2L
+
+#define SN_rc2_64_cbc			"RC2-64-CBC"
+#define LN_rc2_64_cbc			"rc2-64-cbc"
+#define NID_rc2_64_cbc			166
+
+#define SN_SMIMECapabilities		"SMIME-CAPS"
+#define LN_SMIMECapabilities		"S/MIME Capabilities"
+#define NID_SMIMECapabilities		167
+#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
+
+#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC	168
+#define OBJ_pbeWithMD2AndRC2_CBC	OBJ_pkcs,5L,4L
+
+#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC	169
+#define OBJ_pbeWithMD5AndRC2_CBC	OBJ_pkcs,5L,6L
+
+#define SN_pbeWithSHA1AndDES_CBC	"PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC	"pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC	170
+#define OBJ_pbeWithSHA1AndDES_CBC	OBJ_pkcs,5L,10L
+
+/* Extension request OIDs */
+
+#define LN_ms_ext_req			"Microsoft Extension Request"
+#define SN_ms_ext_req			"msExtReq"
+#define NID_ms_ext_req			171
+#define OBJ_ms_ext_req			1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define LN_ext_req			"Extension Request"
+#define SN_ext_req			"extReq"
+#define NID_ext_req			172
+#define OBJ_ext_req			OBJ_pkcs9,14L
+
+#define SN_name				"name"
+#define LN_name				"name"
+#define NID_name			173
+#define OBJ_name			OBJ_X509,41L
+
+#define SN_dnQualifier			"dnQualifier"
+#define LN_dnQualifier			"dnQualifier"
+#define NID_dnQualifier			174
+#define OBJ_dnQualifier			OBJ_X509,46L
+
+#define SN_id_pe			"id-pe"
+#define NID_id_pe			175
+#define OBJ_id_pe			OBJ_id_pkix,1L
+
+#define SN_id_ad			"id-ad"
+#define NID_id_ad			176
+#define OBJ_id_ad			OBJ_id_pkix,48L
+
+#define SN_info_access			"authorityInfoAccess"
+#define LN_info_access			"Authority Information Access"
+#define NID_info_access			177
+#define OBJ_info_access			OBJ_id_pe,1L
+
+#define SN_ad_OCSP			"OCSP"
+#define LN_ad_OCSP			"OCSP"
+#define NID_ad_OCSP			178
+#define OBJ_ad_OCSP			OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers		"caIssuers"
+#define LN_ad_ca_issuers		"CA Issuers"
+#define NID_ad_ca_issuers		179
+#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
+
+#define SN_OCSP_sign			"OCSPSigning"
+#define LN_OCSP_sign			"OCSP Signing"
+#define NID_OCSP_sign			180
+#define OBJ_OCSP_sign			OBJ_id_kp,9L
+
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+#define	OBJ_NAME_TYPE_UNDEF		0x00
+#define	OBJ_NAME_TYPE_MD_METH		0x01
+#define	OBJ_NAME_TYPE_CIPHER_METH	0x02
+#define	OBJ_NAME_TYPE_PKEY_METH		0x03
+#define	OBJ_NAME_TYPE_COMP_METH		0x04
+#define	OBJ_NAME_TYPE_NUM		0x05
+
+#define	OBJ_NAME_ALIAS		0x8000
+
+
+typedef struct obj_name_st
+	{
+	int type;
+	int alias;
+	const char *name;
+	const char *data;
+	} OBJ_NAME;
+
+#define		OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
+
+
+int OBJ_NAME_init(void);
+int OBJ_NAME_new_index(unsigned long (*hash_func)(),int (*cmp_func)(),
+	void (*free_func)());
+const char *OBJ_NAME_get(const char *name,int type);
+int OBJ_NAME_add(const char *name,int type,const char *data);
+int OBJ_NAME_remove(const char *name,int type);
+void OBJ_NAME_cleanup(int type); /* -1 for everything */
+
+ASN1_OBJECT *	OBJ_dup(ASN1_OBJECT *o);
+ASN1_OBJECT *	OBJ_nid2obj(int n);
+const char *	OBJ_nid2ln(int n);
+const char *	OBJ_nid2sn(int n);
+int		OBJ_obj2nid(ASN1_OBJECT *o);
+ASN1_OBJECT *	OBJ_txt2obj(const char *s, int no_name);
+int	OBJ_obj2txt(char *buf, int buf_len, ASN1_OBJECT *a, int no_name);
+int		OBJ_txt2nid(char *s);
+int		OBJ_ln2nid(const char *s);
+int		OBJ_sn2nid(const char *s);
+int		OBJ_cmp(ASN1_OBJECT *a,ASN1_OBJECT *b);
+char *		OBJ_bsearch(char *key,char *base,int num,int size,int (*cmp)());
+
+void		ERR_load_OBJ_strings(void );
+
+int		OBJ_new_nid(int num);
+int		OBJ_add_object(ASN1_OBJECT *obj);
+int		OBJ_create(char *oid,char *sn,char *ln);
+void		OBJ_cleanup(void );
+int		OBJ_create_objects(BIO *in);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the OBJ functions. */
+
+/* Function codes. */
+#define OBJ_F_OBJ_CREATE				 100
+#define OBJ_F_OBJ_DUP					 101
+#define OBJ_F_OBJ_NID2LN				 102
+#define OBJ_F_OBJ_NID2OBJ				 103
+#define OBJ_F_OBJ_NID2SN				 104
+
+/* Reason codes. */
+#define OBJ_R_MALLOC_FAILURE				 100
+#define OBJ_R_UNKNOWN_NID				 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/openssl_pkcs7.h b/AppleCSP/open_ssl/openssl/openssl_pkcs7.h
new file mode 100644
index 00000000..223438ba
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/openssl_pkcs7.h
@@ -0,0 +1,516 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/pkcs7/pkcs7.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PKCS7_H
+#define HEADER_PKCS7_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+
+#ifdef VMS
+#include <openssl/vms_idhacks.h>
+#endif
+
+#ifdef WIN32
+/* Under Win32 thes are defined in wincrypt.h */
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef PKCS7_SIGNER_INFO
+#endif
+
+/*
+Encryption_ID		DES-CBC
+Digest_ID		MD5
+Digest_Encryption_ID	rsaEncryption
+Key_Encryption_ID	rsaEncryption
+*/
+
+typedef struct pkcs7_issuer_and_serial_st
+	{
+	X509_NAME *issuer;
+	ASN1_INTEGER *serial;
+	} PKCS7_ISSUER_AND_SERIAL;
+
+typedef struct pkcs7_signer_info_st
+	{
+	ASN1_INTEGER 			*version;	/* version 1 */
+	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
+	X509_ALGOR			*digest_alg;
+	STACK_OF(X509_ATTRIBUTE)	*auth_attr;	/* [ 0 ] */
+	X509_ALGOR			*digest_enc_alg;
+	ASN1_OCTET_STRING		*enc_digest;
+	STACK_OF(X509_ATTRIBUTE)	*unauth_attr;	/* [ 1 ] */
+
+	/* The private key to sign with */
+	EVP_PKEY			*pkey;
+	} PKCS7_SIGNER_INFO;
+
+DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)
+
+typedef struct pkcs7_recip_info_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
+	X509_ALGOR			*key_enc_algor;
+	ASN1_OCTET_STRING		*enc_key;
+	X509				*cert; /* get the pub-key from this */
+	} PKCS7_RECIP_INFO;
+
+DECLARE_STACK_OF(PKCS7_RECIP_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)
+
+typedef struct pkcs7_signed_st
+	{
+	ASN1_INTEGER			*version;	/* version 1 */
+	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
+	STACK_OF(X509)			*cert;		/* [ 0 ] */
+	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
+	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
+
+	struct pkcs7_st			*contents;
+	} PKCS7_SIGNED;
+/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE.
+ * How about merging the two */
+
+typedef struct pkcs7_enc_content_st
+	{
+	ASN1_OBJECT			*content_type;
+	X509_ALGOR			*algorithm;
+	ASN1_OCTET_STRING		*enc_data;	/* [ 0 ] */
+	const EVP_CIPHER		*cipher;
+	} PKCS7_ENC_CONTENT;
+
+typedef struct pkcs7_enveloped_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
+	PKCS7_ENC_CONTENT		*enc_data;
+	} PKCS7_ENVELOPE;
+
+typedef struct pkcs7_signedandenveloped_st
+	{
+	ASN1_INTEGER			*version;	/* version 1 */
+	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
+	STACK_OF(X509)			*cert;		/* [ 0 ] */
+	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
+	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
+
+	PKCS7_ENC_CONTENT		*enc_data;
+	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
+	} PKCS7_SIGN_ENVELOPE;
+
+typedef struct pkcs7_digest_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	X509_ALGOR			*md;		/* md used */
+	struct pkcs7_st 		*contents;
+	ASN1_OCTET_STRING		*digest;
+	} PKCS7_DIGEST;
+
+typedef struct pkcs7_encrypted_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	PKCS7_ENC_CONTENT		*enc_data;
+	} PKCS7_ENCRYPT;
+
+typedef struct pkcs7_st
+	{
+	/* The following is non NULL if it contains ASN1 encoding of
+	 * this structure */
+	unsigned char *asn1;
+	long length;
+
+#define PKCS7_S_HEADER	0
+#define PKCS7_S_BODY	1
+#define PKCS7_S_TAIL	2
+	int state; /* used during processing */
+
+	int detached;
+
+	ASN1_OBJECT *type;
+	/* content as defined by the type */
+	/* all encryption/message digests are applied to the 'contents',
+	 * leaving out the 'type' field. */
+	union	{
+		char *ptr;
+
+		/* NID_pkcs7_data */
+		ASN1_OCTET_STRING *data;
+
+		/* NID_pkcs7_signed */
+		PKCS7_SIGNED *sign;
+
+		/* NID_pkcs7_enveloped */
+		PKCS7_ENVELOPE *enveloped;
+
+		/* NID_pkcs7_signedAndEnveloped */
+		PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
+
+		/* NID_pkcs7_digest */
+		PKCS7_DIGEST *digest;
+
+		/* NID_pkcs7_encrypted */
+		PKCS7_ENCRYPT *encrypted;
+		} d;
+	} PKCS7;
+
+#define PKCS7_OP_SET_DETACHED_SIGNATURE	1
+#define PKCS7_OP_GET_DETACHED_SIGNATURE	2
+
+#define PKCS7_get_signed_attributes(si)	((si)->auth_attr)
+#define PKCS7_get_attributes(si)	((si)->unauth_attr)
+
+#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
+#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
+#define PKCS7_type_is_signedAndEnveloped(a) \
+		(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
+#define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+
+#define PKCS7_set_detached(p,v) \
+		PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+#define PKCS7_get_detached(p) \
+		PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
+
+#ifdef SSLEAY_MACROS
+#ifndef PKCS7_ISSUER_AND_SERIAL_digest
+#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
+        ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
+	                (char *)data,md,len)
+#endif
+#endif
+
+/* S/MIME related flags */
+
+#define PKCS7_TEXT	0x1
+#define PKCS7_NOCERTS	0x2
+#define PKCS7_NOSIGS	0x4
+#define PKCS7_NOCHAIN	0x8
+#define PKCS7_NOINTERN	0x10
+#define PKCS7_NOVERIFY	0x20
+#define PKCS7_DETACHED	0x40
+#define PKCS7_BINARY	0x80
+#define PKCS7_NOATTR	0x100
+
+/* Flags: for compatibility with older code */
+
+#define SMIME_TEXT	PKCS7_TEXT
+#define SMIME_NOCERTS	PKCS7_NOCERTS
+#define SMIME_NOSIGS	PKCS7_NOSIGS
+#define SMIME_NOCHAIN	PKCS7_NOCHAIN
+#define SMIME_NOINTERN	PKCS7_NOINTERN
+#define SMIME_NOVERIFY	PKCS7_NOVERIFY
+#define SMIME_DETACHED	PKCS7_DETACHED
+#define SMIME_BINARY	PKCS7_BINARY
+#define SMIME_NOATTR	PKCS7_NOATTR
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new(void );
+void			PKCS7_ISSUER_AND_SERIAL_free(
+				PKCS7_ISSUER_AND_SERIAL *a);
+int 			i2d_PKCS7_ISSUER_AND_SERIAL(
+				PKCS7_ISSUER_AND_SERIAL *a,unsigned char **pp);
+PKCS7_ISSUER_AND_SERIAL *d2i_PKCS7_ISSUER_AND_SERIAL(
+				PKCS7_ISSUER_AND_SERIAL **a,
+				unsigned char **pp, long length);
+
+#ifndef SSLEAY_MACROS
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
+	unsigned char *md,unsigned int *len);
+#ifndef NO_FP_API
+PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7);
+int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
+#endif
+PKCS7 *PKCS7_dup(PKCS7 *p7);
+PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
+int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
+#endif
+
+PKCS7_SIGNER_INFO	*PKCS7_SIGNER_INFO_new(void);
+void			PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a);
+int 			i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a,
+				unsigned char **pp);
+PKCS7_SIGNER_INFO	*d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a,
+				unsigned char **pp,long length);
+
+PKCS7_RECIP_INFO	*PKCS7_RECIP_INFO_new(void);
+void			PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a);
+int 			i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a,
+				unsigned char **pp);
+PKCS7_RECIP_INFO	*d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a,
+				unsigned char **pp,long length);
+
+PKCS7_SIGNED		*PKCS7_SIGNED_new(void);
+void			PKCS7_SIGNED_free(PKCS7_SIGNED *a);
+int 			i2d_PKCS7_SIGNED(PKCS7_SIGNED *a,
+				unsigned char **pp);
+PKCS7_SIGNED		*d2i_PKCS7_SIGNED(PKCS7_SIGNED **a,
+				unsigned char **pp,long length);
+
+PKCS7_ENC_CONTENT	*PKCS7_ENC_CONTENT_new(void);
+void			PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a);
+int 			i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a,
+				unsigned char **pp);
+PKCS7_ENC_CONTENT	*d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a,
+				unsigned char **pp,long length);
+
+PKCS7_ENVELOPE		*PKCS7_ENVELOPE_new(void);
+void			PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a);
+int 			i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a,
+				unsigned char **pp);
+PKCS7_ENVELOPE		*d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a,
+				unsigned char **pp,long length);
+
+PKCS7_SIGN_ENVELOPE	*PKCS7_SIGN_ENVELOPE_new(void);
+void			PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a);
+int 			i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a,
+				unsigned char **pp);
+PKCS7_SIGN_ENVELOPE	*d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a,
+				unsigned char **pp,long length);
+
+PKCS7_DIGEST		*PKCS7_DIGEST_new(void);
+void			PKCS7_DIGEST_free(PKCS7_DIGEST *a);
+int 			i2d_PKCS7_DIGEST(PKCS7_DIGEST *a,
+				unsigned char **pp);
+PKCS7_DIGEST		*d2i_PKCS7_DIGEST(PKCS7_DIGEST **a,
+				unsigned char **pp,long length);
+
+PKCS7_ENCRYPT		*PKCS7_ENCRYPT_new(void);
+void			PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a);
+int 			i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a,
+				unsigned char **pp);
+PKCS7_ENCRYPT		*d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a,
+				unsigned char **pp,long length);
+
+PKCS7			*PKCS7_new(void);
+void			PKCS7_free(PKCS7 *a);
+void			PKCS7_content_free(PKCS7 *a);
+int 			i2d_PKCS7(PKCS7 *a,
+				unsigned char **pp);
+PKCS7			*d2i_PKCS7(PKCS7 **a,
+				unsigned char **pp,long length);
+
+void ERR_load_PKCS7_strings(void);
+
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
+
+int PKCS7_set_type(PKCS7 *p7, int type);
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+	EVP_MD *dgst);
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+int PKCS7_content_new(PKCS7 *p7, int nid);
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
+	BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); 
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+								X509 *x509);
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
+
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
+	EVP_PKEY *pkey, EVP_MD *dgst);
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si,int nid,int type,
+	void *data);
+int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+	void *value);
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+				STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
+
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+							BIO *data, int flags);
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+					BIO *indata, BIO *out, int flags);
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher,
+								int flags);
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK *cap);
+STACK *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
+int PKCS7_simple_smimecap(STACK *sk, int nid, int arg);
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+#define PKCS7_F_B64_READ_PKCS7				 120
+#define PKCS7_F_B64_WRITE_PKCS7				 121
+#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP		 118
+#define PKCS7_F_PKCS7_ADD_CERTIFICATE			 100
+#define PKCS7_F_PKCS7_ADD_CRL				 101
+#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO		 102
+#define PKCS7_F_PKCS7_ADD_SIGNER			 103
+#define PKCS7_F_PKCS7_CTRL				 104
+#define PKCS7_F_PKCS7_DATADECODE			 112
+#define PKCS7_F_PKCS7_DATAINIT				 105
+#define PKCS7_F_PKCS7_DATASIGN				 106
+#define PKCS7_F_PKCS7_DATAVERIFY			 107
+#define PKCS7_F_PKCS7_DECRYPT				 114
+#define PKCS7_F_PKCS7_ENCRYPT				 115
+#define PKCS7_F_PKCS7_GET0_SIGNERS			 124
+#define PKCS7_F_PKCS7_SET_CIPHER			 108
+#define PKCS7_F_PKCS7_SET_CONTENT			 109
+#define PKCS7_F_PKCS7_SET_TYPE				 110
+#define PKCS7_F_PKCS7_SIGN				 116
+#define PKCS7_F_PKCS7_SIGNATUREVERIFY			 113
+#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP			 119
+#define PKCS7_F_PKCS7_VERIFY				 117
+#define PKCS7_F_SMIME_READ_PKCS7			 122
+#define PKCS7_F_SMIME_TEXT				 123
+
+/* Reason codes. */
+#define PKCS7_R_CERTIFICATE_VERIFY_ERROR		 117
+#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 144
+#define PKCS7_R_CIPHER_NOT_INITIALIZED			 116
+#define PKCS7_R_CONTENT_AND_DATA_PRESENT		 118
+#define PKCS7_R_DECODE_ERROR				 130
+#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH		 100
+#define PKCS7_R_DECRYPT_ERROR				 119
+#define PKCS7_R_DIGEST_FAILURE				 101
+#define PKCS7_R_ERROR_ADDING_RECIPIENT			 120
+#define PKCS7_R_ERROR_SETTING_CIPHER			 121
+#define PKCS7_R_INTERNAL_ERROR				 102
+#define PKCS7_R_INVALID_MIME_TYPE			 131
+#define PKCS7_R_INVALID_NULL_POINTER			 143
+#define PKCS7_R_MIME_NO_CONTENT_TYPE			 132
+#define PKCS7_R_MIME_PARSE_ERROR			 133
+#define PKCS7_R_MIME_SIG_PARSE_ERROR			 134
+#define PKCS7_R_MISSING_CERIPEND_INFO			 103
+#define PKCS7_R_NO_CONTENT				 122
+#define PKCS7_R_NO_CONTENT_TYPE				 135
+#define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
+#define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
+#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115
+#define PKCS7_R_NO_SIGNATURES_ON_DATA			 123
+#define PKCS7_R_NO_SIGNERS				 142
+#define PKCS7_R_NO_SIG_CONTENT_TYPE			 138
+#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE	 104
+#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR		 124
+#define PKCS7_R_PKCS7_DATAFINAL_ERROR			 125
+#define PKCS7_R_PKCS7_DATASIGN				 126
+#define PKCS7_R_PKCS7_PARSE_ERROR			 139
+#define PKCS7_R_PKCS7_SIG_PARSE_ERROR			 140
+#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 127
+#define PKCS7_R_SIGNATURE_FAILURE			 105
+#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND		 128
+#define PKCS7_R_SIG_INVALID_MIME_TYPE			 141
+#define PKCS7_R_SMIME_TEXT_ERROR			 129
+#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE		 106
+#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO			 107
+#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST		 108
+#define PKCS7_R_UNKNOWN_DIGEST_TYPE			 109
+#define PKCS7_R_UNKNOWN_OPERATION			 110
+#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE			 111
+#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE		 112
+#define PKCS7_R_WRONG_CONTENT_TYPE			 113
+#define PKCS7_R_WRONG_PKCS7_TYPE			 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/opensslconf.h b/AppleCSP/open_ssl/openssl/opensslconf.h
new file mode 100644
index 00000000..69ec50f3
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/opensslconf.h
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * opensslconf.h - hand-rolled config #defines for openssl code used in AppleCSP
+ * Written by Doug Mitchell 4/3/2001
+ */
+#ifndef _OPENSSL_CONF_H_
+#define _OPENSSL_CONF_H_
+
+#include <Security/cssmtype.h>		/* for uint32, etc. */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Flags to disable a lot of code we don't need.
+ */
+#define _OPENSSL_APPLE_CDSA_	1
+
+#define NO_DH 		1
+#define NO_MD5 		1
+#define NO_RIPEMD 	1
+#define NO_DES 		1
+#define NO_BF 		1
+#define NO_CAST 	1
+#define NO_IDEA 	1
+#define NO_MDC2		1
+
+#ifdef	NDEBUG
+#define NO_ERR		1
+#endif
+
+/* disable the static callback ptrs in cryptlib.c */
+#define CRYPTO_CALLBACK_ENABLE		0
+
+/* disable the BN_{set,get}_params mechanism, unused */
+#define BN_PARAMS_ENABLE			0
+
+typedef uint32 RC2_INT;
+typedef uint32 RC4_INT;
+
+/* the following two need calibration and lots of testing; see rc4_enc.c... */
+#undef RC4_CHUNK
+#undef RC4_INDEX
+
+typedef uint32 RC5_32_INT;
+
+typedef uint32 MD2_INT;
+
+/*
+ * FIXME - this could certainly use some tweaking
+ */
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+/* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+
+/*
+ * Using 64 bit results in an 8% speedup for RSA sign, but a 3%
+ * slowdown for RSA verify on a G4 cubeÊcompared to 32 bit. 
+ *    --dpm, 5/10/01
+ */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT      
+#define THIRTY_TWO_BIT
+#undef SIXTEEN_BIT
+#undef EIGHT_BIT
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#endif	/* _OPENSSL_CONF_H_ */
diff --git a/AppleCSP/open_ssl/openssl/opensslv.h b/AppleCSP/open_ssl/openssl/opensslv.h
new file mode 100644
index 00000000..81326858
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/opensslv.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+
+#ifndef HEADER_OPENSSLV_H
+#define HEADER_OPENSSLV_H
+
+/* Numeric release version identifier:
+ * MMNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release.  The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev	  0x00903000
+ * 0.9.3-beta1	  0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
+ * 0.9.3	  0x0090300f
+ * 0.9.3a	  0x0090301f
+ * 0.9.4 	  0x0090400f
+ * 1.2.3z	  0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit.  This means
+ * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ *  major minor fix final patch/beta)
+ */
+#define OPENSSL_VERSION_NUMBER	0x0090581fL
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.5a 1 Apr 2000"
+#define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
+
+#endif /* HEADER_OPENSSLV_H */
diff --git a/AppleCSP/open_ssl/openssl/rand.h b/AppleCSP/open_ssl/openssl/rand.h
new file mode 100644
index 00000000..3175a468
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/rand.h
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rand/rand.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RAND_H
+#define HEADER_RAND_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rand_meth_st
+	{
+	void (*seed)(const void *buf, int num);
+	int (*bytes)(unsigned char *buf, int num);
+	void (*cleanup)(void);
+	void (*add)(const void *buf, int num, double entropy);
+	int (*pseudorand)(unsigned char *buf, int num);
+	int (*status)(void);
+	} RAND_METHOD;
+
+#ifdef BN_DEBUG
+extern int rand_predictable;
+#endif
+
+void RAND_set_rand_method(RAND_METHOD *meth);
+RAND_METHOD *RAND_get_rand_method(void );
+RAND_METHOD *RAND_SSLeay(void);
+void RAND_cleanup(void );
+int  RAND_bytes(unsigned char *buf,int num);
+int  RAND_pseudo_bytes(unsigned char *buf,int num);
+void RAND_seed(const void *buf,int num);
+void RAND_add(const void *buf,int num,double entropy);
+int  RAND_load_file(const char *file,long max_bytes);
+int  RAND_write_file(const char *file);
+const char *RAND_file_name(char *file,int num);
+int RAND_status(void);
+int RAND_egd(const char *path);
+#if defined(WINDOWS) || defined(WIN32)
+#include <windows.h>
+void RAND_screen(void);
+int RAND_event(UINT, WPARAM, LPARAM);
+#endif
+void	ERR_load_RAND_strings(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the RAND functions. */
+
+/* Function codes. */
+#define RAND_F_SSLEAY_RAND_BYTES			 100
+
+/* Reason codes. */
+#define RAND_R_PRNG_NOT_SEEDED				 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/rc2.h b/AppleCSP/open_ssl/openssl/rc2.h
new file mode 100644
index 00000000..563365e0
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/rc2.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc2/rc2.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC2_H
+#define HEADER_RC2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_RC2
+#error RC2 is disabled.
+#endif
+
+#define RC2_ENCRYPT	1
+#define RC2_DECRYPT	0
+
+#include <openssl/opensslconf.h> /* RC2_INT */
+#define RC2_BLOCK_SIZE_BYTES	8
+#define RC2_MIN_KEY_SIZE_BYTES	1
+#define RC2_MAX_KEY_SIZE_BYTES	128
+
+typedef struct rc2_key_st
+	{
+	RC2_INT data[64];
+	} RC2_KEY;
+
+ 
+void RC2_set_key(RC2_KEY *key, int len, unsigned char *data,int bits);
+#ifdef	_OPENSSL_APPLE_CDSA_
+void RC2_encrypt(RC2_INT *data,RC2_KEY *key);
+void RC2_decrypt(RC2_INT *data,RC2_KEY *key);
+#else
+void RC2_encrypt(unsigned long *data,RC2_KEY *key);
+void RC2_decrypt(unsigned long *data,RC2_KEY *key);
+void RC2_ecb_encrypt(unsigned char *in,unsigned char *out,RC2_KEY *key,
+	int enc);
+void RC2_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
+	RC2_KEY *ks, unsigned char *iv, int enc);
+void RC2_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	RC2_KEY *schedule, unsigned char *ivec, int *num, int enc);
+void RC2_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	RC2_KEY *schedule, unsigned char *ivec, int *num);
+#endif	/* _OPENSSL_APPLE_CDSA_ */
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/openssl/rc4.h b/AppleCSP/open_ssl/openssl/rc4.h
new file mode 100644
index 00000000..9ed5e05b
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/rc4.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc4/rc4.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC4_H
+#define HEADER_RC4_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_RC4
+#error RC4 is disabled.
+#endif
+
+#include <openssl/opensslconf.h> /* RC4_INT */
+
+#define RC4_MIN_KEY_SIZE_BYTES	1
+#define RC4_MAX_KEY_SIZE_BYTES	512
+
+typedef struct rc4_key_st
+	{
+	RC4_INT x,y;
+	RC4_INT data[256];
+	} RC4_KEY;
+
+ 
+const char *RC4_options(void);
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
+		unsigned char *outdata);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/openssl/rc5.h b/AppleCSP/open_ssl/openssl/rc5.h
new file mode 100644
index 00000000..123374b5
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/rc5.h
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rc5/rc5.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC5_H
+#define HEADER_RC5_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_RC5
+#error RC5 is disabled.
+#endif
+
+#define RC5_ENCRYPT	1
+#define RC5_DECRYPT	0
+
+#include <openssl/opensslconf.h> /* RC5_INT */
+
+#ifdef	_OPENSSL_APPLE_CDSA_
+
+#define RC5_BLOCK_SIZE_BYTES	8
+#define RC5_MIN_KEY_SIZE_BYTES	1
+#define RC5_MAX_KEY_SIZE_BYTES	255
+
+#else
+
+/* 32 bit.  For Alpha, things may get weird */
+#define RC5_32_INT unsigned long
+
+#define RC5_32_BLOCK		8
+#define RC5_32_KEY_LENGTH	16 /* This is a default, max is 255 */
+
+#endif	/* _OPENSSL_APPLE_CDSA_ */
+
+/* This are the only values supported.  Tweak the code if you want more
+ * The most supported modes will be
+ * RC5-32/12/16
+ * RC5-32/16/8
+ */
+#define RC5_8_ROUNDS	8
+#define RC5_12_ROUNDS	12
+#define RC5_16_ROUNDS	16
+
+typedef struct rc5_key_st
+	{
+	/* Number of rounds */
+	int rounds;
+	RC5_32_INT data[2*(RC5_16_ROUNDS+1)];
+	} RC5_32_KEY;
+
+ 
+void RC5_32_set_key(RC5_32_KEY *key, int len, unsigned char *data,
+	int rounds);
+	
+#ifdef	_OPENSSL_APPLE_CDSA_
+void RC5_32_encrypt(RC5_32_INT *data,RC5_32_KEY *key);
+void RC5_32_decrypt(RC5_32_INT *data,RC5_32_KEY *key);
+#else
+void RC5_32_ecb_encrypt(unsigned char *in,unsigned char *out,RC5_32_KEY *key,
+	int enc);
+void RC5_32_encrypt(unsigned long *data,RC5_32_KEY *key);
+void RC5_32_decrypt(unsigned long *data,RC5_32_KEY *key);
+void RC5_32_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
+	RC5_32_KEY *ks, unsigned char *iv, int enc);
+void RC5_32_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	RC5_32_KEY *schedule, unsigned char *ivec, int *num, int enc);
+void RC5_32_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	RC5_32_KEY *schedule, unsigned char *ivec, int *num);
+
+#endif	/* _OPENSSL_APPLE_CDSA_ */
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/openssl/rsa.h b/AppleCSP/open_ssl/openssl/rsa.h
new file mode 100644
index 00000000..f17cbd3c
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/rsa.h
@@ -0,0 +1,356 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RSA_H
+#define HEADER_RSA_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+
+#ifdef NO_RSA
+#error RSA is disabled.
+#endif
+
+typedef struct rsa_st RSA;
+
+typedef struct rsa_meth_st
+	{
+	const char *name;
+	int (*rsa_pub_enc)(int flen,unsigned char *from,unsigned char *to,
+			   RSA *rsa,int padding);
+	int (*rsa_pub_dec)(int flen,unsigned char *from,unsigned char *to,
+			   RSA *rsa,int padding);
+	int (*rsa_priv_enc)(int flen,unsigned char *from,unsigned char *to,
+			    RSA *rsa,int padding);
+	int (*rsa_priv_dec)(int flen,unsigned char *from,unsigned char *to,
+			    RSA *rsa,int padding);
+	int (*rsa_mod_exp)(BIGNUM *r0,BIGNUM *I,RSA *rsa); /* Can be null */
+	int (*bn_mod_exp)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx,
+			  BN_MONT_CTX *m_ctx); /* Can be null */
+	int (*init)(RSA *rsa);		/* called at new */
+	int (*finish)(RSA *rsa);	/* called at free */
+	int flags;			/* RSA_METHOD_FLAG_* things */
+	char *app_data;			/* may be needed! */
+/* New sign and verify functions: some libraries don't allow arbitrary data
+ * to be signed/verified: this allows them to be used. Note: for this to work
+ * the RSA_public_decrypt() and RSA_private_encrypt() should *NOT* be used
+ * RSA_sign(), RSA_verify() should be used instead. Note: for backwards
+ * compatibility this functionality is only enabled if the RSA_FLAG_SIGN_VER
+ * option is set in 'flags'.
+ */
+	int (*rsa_sign)(int type, unsigned char *m, unsigned int m_len,
+             unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+	int (*rsa_verify)(int dtype, unsigned char *m, unsigned int m_len,
+             unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+	} RSA_METHOD;
+
+struct rsa_st
+	{
+	/* The first parameter is used to pickup errors where
+	 * this is passed instead of aEVP_PKEY, it is set to 0 */
+	int pad;
+	int version;
+	const RSA_METHOD *meth;
+	BIGNUM *n;
+	BIGNUM *e;
+	BIGNUM *d;
+	BIGNUM *p;
+	BIGNUM *q;
+	BIGNUM *dmp1;
+	BIGNUM *dmq1;
+	BIGNUM *iqmp;
+	/* be careful using this if the RSA structure is shared */
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	int flags;
+
+	/* Used to cache montgomery values */
+	BN_MONT_CTX *_method_mod_n;
+	BN_MONT_CTX *_method_mod_p;
+	BN_MONT_CTX *_method_mod_q;
+
+	/* all BIGNUM values are actually in the following data, if it is not
+	 * NULL */
+	char *bignum_data;
+	BN_BLINDING *blinding;
+	};
+
+#define RSA_3	0x3L
+#define RSA_F4	0x10001L
+
+#define RSA_METHOD_FLAG_NO_CHECK	0x01 /* don't check pub/private match */
+
+#define RSA_FLAG_CACHE_PUBLIC		0x02
+#define RSA_FLAG_CACHE_PRIVATE		0x04
+#define RSA_FLAG_BLINDING		0x08
+#define RSA_FLAG_THREAD_SAFE		0x10
+/* This flag means the private key operations will be handled by rsa_mod_exp
+ * and that they do not depend on the private key components being present:
+ * for example a key stored in external hardware. Without this flag bn_mod_exp
+ * gets called when private key components are absent.
+ */
+#define RSA_FLAG_EXT_PKEY		0x20
+
+/* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions.
+ */
+#define RSA_FLAG_SIGN_VER		0x40
+
+#define RSA_PKCS1_PADDING	1
+#define RSA_SSLV23_PADDING	2
+#define RSA_NO_PADDING		3
+#define RSA_PKCS1_OAEP_PADDING	4
+
+#define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
+#define RSA_get_app_data(s)             RSA_get_ex_data(s,0)
+
+RSA *	RSA_new(void);
+RSA *	RSA_new_method(const RSA_METHOD *method);
+int	RSA_size(RSA *);
+RSA *	RSA_generate_key(int bits, unsigned long e,void
+		(*callback)(int,int,void *),void *cb_arg);
+int	RSA_check_key(RSA *);
+	/* next 4 return -1 on error */
+int	RSA_public_encrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_private_encrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_public_decrypt(int flen, unsigned char *from, 
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_private_decrypt(int flen, unsigned char *from, 
+		unsigned char *to, RSA *rsa,int padding);
+void	RSA_free (RSA *r);
+
+int	RSA_flags(RSA *r);
+
+void RSA_set_default_method(const RSA_METHOD *meth);
+const RSA_METHOD *RSA_get_default_method(void);
+const RSA_METHOD *RSA_get_method(RSA *rsa);
+const RSA_METHOD *RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
+
+/* This function needs the memory locking malloc callbacks to be installed */
+int RSA_memory_lock(RSA *r);
+
+/* If you have RSAref compiled in. */
+const RSA_METHOD *RSA_PKCS1_RSAref(void);
+
+/* these are the actual SSLeay RSA functions */
+const RSA_METHOD *RSA_PKCS1_SSLeay(void);
+
+const RSA_METHOD *RSA_null_method(void);
+
+void	ERR_load_RSA_strings(void );
+
+RSA *	d2i_RSAPublicKey(RSA **a, unsigned char **pp, long length);
+int	i2d_RSAPublicKey(RSA *a, unsigned char **pp);
+RSA *	d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length);
+int 	i2d_RSAPrivateKey(RSA *a, unsigned char **pp);
+#ifndef NO_FP_API
+int	RSA_print_fp(FILE *fp, RSA *r,int offset);
+#endif
+
+#ifdef HEADER_BIO_H
+int	RSA_print(BIO *bp, RSA *r,int offset);
+#endif
+
+int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)());
+RSA *d2i_Netscape_RSA(RSA **a, unsigned char **pp, long length, int (*cb)());
+/* Naughty internal function required elsewhere, to handle a MS structure
+ * that is the same as the netscape one :-) */
+RSA *d2i_Netscape_RSA_2(RSA **a, unsigned char **pp, long length, int (*cb)());
+
+/* The following 2 functions sign and verify a X509_SIG ASN1 object
+ * inside PKCS#1 padded RSA encryption */
+int RSA_sign(int type, unsigned char *m, unsigned int m_len,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify(int type, unsigned char *m, unsigned int m_len,
+	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+/* The following 2 function sign and verify a ASN1_OCTET_STRING
+ * object inside PKCS#1 padded RSA encryption */
+int RSA_sign_ASN1_OCTET_STRING(int type, unsigned char *m, unsigned int m_len,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify_ASN1_OCTET_STRING(int type, unsigned char *m, unsigned int m_len,
+	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+void RSA_blinding_off(RSA *rsa);
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen,
+	unsigned char *f,int fl);
+int RSA_padding_check_PKCS1_type_1(unsigned char *to,int tlen,
+	unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_PKCS1_type_2(unsigned char *to,int tlen,
+	unsigned char *f,int fl);
+int RSA_padding_check_PKCS1_type_2(unsigned char *to,int tlen,
+	unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to,int tlen,
+			       unsigned char *f,int fl,unsigned char *p,
+			       int pl);
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to,int tlen,
+				 unsigned char *f,int fl,int rsa_len,
+				 unsigned char *p,int pl);
+int RSA_padding_add_SSLv23(unsigned char *to,int tlen,
+	unsigned char *f,int fl);
+int RSA_padding_check_SSLv23(unsigned char *to,int tlen,
+	unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_none(unsigned char *to,int tlen,
+	unsigned char *f,int fl);
+int RSA_padding_check_none(unsigned char *to,int tlen,
+	unsigned char *f,int fl,int rsa_len);
+
+int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int RSA_set_ex_data(RSA *r,int idx,void *arg);
+void *RSA_get_ex_data(RSA *r, int idx);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the RSA functions. */
+
+/* Function codes. */
+#define RSA_F_MEMORY_LOCK				 100
+#define RSA_F_RSA_CHECK_KEY				 123
+#define RSA_F_RSA_EAY_PRIVATE_DECRYPT			 101
+#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT			 102
+#define RSA_F_RSA_EAY_PUBLIC_DECRYPT			 103
+#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT			 104
+#define RSA_F_RSA_GENERATE_KEY				 105
+#define RSA_F_RSA_NEW_METHOD				 106
+#define RSA_F_RSA_NULL					 124
+#define RSA_F_RSA_PADDING_ADD_NONE			 107
+#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP		 121
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1		 108
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2		 109
+#define RSA_F_RSA_PADDING_ADD_SSLV23			 110
+#define RSA_F_RSA_PADDING_CHECK_NONE			 111
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP		 122
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1		 112
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2		 113
+#define RSA_F_RSA_PADDING_CHECK_SSLV23			 114
+#define RSA_F_RSA_PRINT					 115
+#define RSA_F_RSA_PRINT_FP				 116
+#define RSA_F_RSA_SIGN					 117
+#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING		 118
+#define RSA_F_RSA_VERIFY				 119
+#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING		 120
+
+/* Reason codes. */
+#define RSA_R_ALGORITHM_MISMATCH			 100
+#define RSA_R_BAD_E_VALUE				 101
+#define RSA_R_BAD_FIXED_HEADER_DECRYPT			 102
+#define RSA_R_BAD_PAD_BYTE_COUNT			 103
+#define RSA_R_BAD_SIGNATURE				 104
+#define RSA_R_BLOCK_TYPE_IS_NOT_01			 106
+#define RSA_R_BLOCK_TYPE_IS_NOT_02			 107
+#define RSA_R_DATA_GREATER_THAN_MOD_LEN			 108
+#define RSA_R_DATA_TOO_LARGE				 109
+#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 110
+#define RSA_R_DATA_TOO_SMALL				 111
+#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE		 122
+#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY		 112
+#define RSA_R_DMP1_NOT_CONGRUENT_TO_D			 124
+#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D			 125
+#define RSA_R_D_E_NOT_CONGRUENT_TO_1			 123
+#define RSA_R_INVALID_MESSAGE_LENGTH			 131
+#define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
+#define RSA_R_KEY_SIZE_TOO_SMALL			 120
+#define RSA_R_NULL_BEFORE_BLOCK_MISSING			 113
+#define RSA_R_N_DOES_NOT_EQUAL_P_Q			 127
+#define RSA_R_OAEP_DECODING_ERROR			 121
+#define RSA_R_PADDING_CHECK_FAILED			 114
+#define RSA_R_P_NOT_PRIME				 128
+#define RSA_R_Q_NOT_PRIME				 129
+#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED		 130
+#define RSA_R_SSLV3_ROLLBACK_ATTACK			 115
+#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
+#define RSA_R_UNKNOWN_ALGORITHM_TYPE			 117
+#define RSA_R_UNKNOWN_PADDING_TYPE			 118
+#define RSA_R_WRONG_SIGNATURE_LENGTH			 119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/safestack.h b/AppleCSP/open_ssl/openssl/safestack.h
new file mode 100644
index 00000000..ce7d3cf5
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/safestack.h
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SAFESTACK_H
+#define HEADER_SAFESTACK_H
+
+#include <openssl/stack.h>
+
+#define STACK_OF(type)	STACK_##type
+
+#define DECLARE_STACK_OF(type) \
+typedef struct stack_st_##type	\
+    { \
+    STACK stack; \
+    } STACK_OF(type); \
+STACK_OF(type) *sk_##type##_new(int (*cmp)(type **,type **)); \
+STACK_OF(type) *sk_##type##_new_null(void); \
+void sk_##type##_free(STACK_OF(type) *sk); \
+int sk_##type##_num(const STACK_OF(type) *sk); \
+type *sk_##type##_value(const STACK_OF(type) *sk,int n); \
+type *sk_##type##_set(STACK_OF(type) *sk,int n,type *v); \
+void sk_##type##_zero(STACK_OF(type) *sk); \
+int sk_##type##_push(STACK_OF(type) *sk,type *v); \
+int sk_##type##_unshift(STACK_OF(type) *sk,type *v); \
+int sk_##type##_find(STACK_OF(type) *sk,type *v); \
+type *sk_##type##_delete(STACK_OF(type) *sk,int n); \
+void sk_##type##_delete_ptr(STACK_OF(type) *sk,type *v); \
+int sk_##type##_insert(STACK_OF(type) *sk,type *v,int n); \
+int (*sk_##type##_set_cmp_func(STACK_OF(type) *sk, \
+			       int (*cmp)(type **,type **)))(type **,type **); \
+STACK_OF(type) *sk_##type##_dup(STACK_OF(type) *sk); \
+void sk_##type##_pop_free(STACK_OF(type) *sk,void (*func)(type *)); \
+type *sk_##type##_shift(STACK_OF(type) *sk); \
+type *sk_##type##_pop(STACK_OF(type) *sk); \
+void sk_##type##_sort(STACK_OF(type) *sk);
+
+#define IMPLEMENT_STACK_OF(type) \
+STACK_OF(type) *sk_##type##_new(int (*cmp)(type **,type **)) \
+    { return (STACK_OF(type) *)sk_new(cmp); } \
+STACK_OF(type) *sk_##type##_new_null() \
+    { return (STACK_OF(type) *)sk_new_null(); } \
+void sk_##type##_free(STACK_OF(type) *sk) \
+    { sk_free((STACK *)sk); } \
+int sk_##type##_num(const STACK_OF(type) *sk) \
+    { return M_sk_num((const STACK *)sk); } \
+type *sk_##type##_value(const STACK_OF(type) *sk,int n) \
+    { return (type *)sk_value((STACK *)sk,n); } \
+type *sk_##type##_set(STACK_OF(type) *sk,int n,type *v) \
+    { return (type *)(sk_set((STACK *)sk,n,(char *)v)); } \
+void sk_##type##_zero(STACK_OF(type) *sk) \
+    { sk_zero((STACK *)sk); } \
+int sk_##type##_push(STACK_OF(type) *sk,type *v) \
+    { return sk_push((STACK *)sk,(char *)v); } \
+int sk_##type##_unshift(STACK_OF(type) *sk,type *v) \
+    { return sk_unshift((STACK *)sk,(char *)v); } \
+int sk_##type##_find(STACK_OF(type) *sk,type *v) \
+    { return sk_find((STACK *)sk,(char *)v); } \
+type *sk_##type##_delete(STACK_OF(type) *sk,int n) \
+    { return (type *)sk_delete((STACK *)sk,n); } \
+void sk_##type##_delete_ptr(STACK_OF(type) *sk,type *v) \
+    { sk_delete_ptr((STACK *)sk,(char *)v); } \
+int sk_##type##_insert(STACK_OF(type) *sk,type *v,int n) \
+    { return sk_insert((STACK *)sk,(char *)v,n); } \
+int (*sk_##type##_set_cmp_func(STACK_OF(type) *sk, \
+			       int (*cmp)(type **,type **)))(type **,type **) \
+    { return (int (*)(type **,type **))sk_set_cmp_func((STACK *)sk,cmp); } \
+STACK_OF(type) *sk_##type##_dup(STACK_OF(type) *sk) \
+    { return (STACK_OF(type) *)sk_dup((STACK *)sk); } \
+void sk_##type##_pop_free(STACK_OF(type) *sk,void (*func)(type *)) \
+    { sk_pop_free((STACK *)sk,func); } \
+type *sk_##type##_shift(STACK_OF(type) *sk) \
+    { return (type *)sk_shift((STACK *)sk); } \
+type *sk_##type##_pop(STACK_OF(type) *sk) \
+    { return (type *)sk_pop((STACK *)sk); } \
+void sk_##type##_sort(STACK_OF(type) *sk) \
+    { sk_sort((STACK *)sk); }
+
+#endif /* ndef HEADER_SAFESTACK_H */
diff --git a/AppleCSP/open_ssl/openssl/sha.h b/AppleCSP/open_ssl/openssl/sha.h
new file mode 100644
index 00000000..a611ba75
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/sha.h
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/sha/sha.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SHA_H
+#define HEADER_SHA_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(NO_SHA) || (defined(NO_SHA0) && defined(NO_SHA1))
+#error SHA is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! SHA_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(WIN16) || defined(__LP32__)
+#define SHA_LONG unsigned long
+#elif defined(_CRAY) || defined(__ILP64__)
+#define SHA_LONG unsigned long
+#define SHA_LONG_LOG2 3
+#else
+#define SHA_LONG unsigned int
+#endif
+
+#define SHA_LBLOCK	16
+#define SHA_CBLOCK	(SHA_LBLOCK*4)	/* SHA treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
+#define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st
+	{
+	SHA_LONG h0,h1,h2,h3,h4;
+	SHA_LONG Nl,Nh;
+	SHA_LONG data[SHA_LBLOCK];
+	int num;
+	} SHA_CTX;
+
+#ifndef NO_SHA0
+void SHA_Init(SHA_CTX *c);
+void SHA_Update(SHA_CTX *c, const void *data, unsigned long len);
+void SHA_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md);
+void SHA_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+#ifndef NO_SHA1
+void SHA1_Init(SHA_CTX *c);
+void SHA1_Update(SHA_CTX *c, const void *data, unsigned long len);
+void SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/openssl/stack.h b/AppleCSP/open_ssl/openssl/stack.h
new file mode 100644
index 00000000..d126b5b1
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/stack.h
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/stack/stack.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_STACK_H
+#define HEADER_STACK_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st
+	{
+	int num;
+	char **data;
+	int sorted;
+
+	int num_alloc;
+	int (*comp)();
+	} STACK;
+
+
+#define sk_new_null()	sk_new(NULL)
+
+#define M_sk_num(sk)		((sk) ? (sk)->num:-1)
+#define M_sk_value(sk,n)	((sk) ? (sk)->data[n] : NULL)
+
+int sk_num(STACK *);
+char *sk_value(STACK *, int);
+
+char *sk_set(STACK *, int, char *);
+
+STACK *sk_new(int (*cmp)());
+void sk_free(STACK *);
+void sk_pop_free(STACK *st, void (*func)());
+int sk_insert(STACK *sk,char *data,int where);
+char *sk_delete(STACK *st,int loc);
+char *sk_delete_ptr(STACK *st, char *p);
+int sk_find(STACK *st,char *data);
+int sk_push(STACK *st,char *data);
+int sk_unshift(STACK *st,char *data);
+char *sk_shift(STACK *st);
+char *sk_pop(STACK *st);
+void sk_zero(STACK *st);
+int (*sk_set_cmp_func(STACK *sk, int (*c)()))();
+STACK *sk_dup(STACK *st);
+void sk_sort(STACK *st);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleCSP/open_ssl/openssl/x509.h b/AppleCSP/open_ssl/openssl/x509.h
new file mode 100644
index 00000000..b9cc05dd
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/x509.h
@@ -0,0 +1,1222 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/x509/x509.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_X509_H
+#define HEADER_X509_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef VMS
+#undef X509_REVOKED_get_ext_by_critical
+#define X509_REVOKED_get_ext_by_critical X509_REVOKED_get_ext_by_critic
+#endif
+
+#include <openssl/stack.h>
+#include <openssl/asn1.h>
+#include <openssl/safestack.h>
+
+#ifndef NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+#ifndef NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#ifndef NO_DH
+#include <openssl/dh.h>
+#endif
+
+#include <openssl/evp.h>
+
+
+#ifdef WIN32
+/* Under Win32 this is defined in wincrypt.h */
+#undef X509_NAME
+#endif
+
+#define X509_FILETYPE_PEM	1
+#define X509_FILETYPE_ASN1	2
+#define X509_FILETYPE_DEFAULT	3
+
+#define X509v3_KU_DIGITAL_SIGNATURE	0x0080
+#define X509v3_KU_NON_REPUDIATION	0x0040
+#define X509v3_KU_KEY_ENCIPHERMENT	0x0020
+#define X509v3_KU_DATA_ENCIPHERMENT	0x0010
+#define X509v3_KU_KEY_AGREEMENT		0x0008
+#define X509v3_KU_KEY_CERT_SIGN		0x0004
+#define X509v3_KU_CRL_SIGN		0x0002
+#define X509v3_KU_ENCIPHER_ONLY		0x0001
+#define X509v3_KU_DECIPHER_ONLY		0x8000
+#define X509v3_KU_UNDEF			0xffff
+
+typedef struct X509_objects_st
+	{
+	int nid;
+	int (*a2i)();
+	int (*i2a)();
+	} X509_OBJECTS;
+
+typedef struct X509_algor_st
+	{
+	ASN1_OBJECT *algorithm;
+	ASN1_TYPE *parameter;
+	} X509_ALGOR;
+
+DECLARE_STACK_OF(X509_ALGOR)
+DECLARE_ASN1_SET_OF(X509_ALGOR)
+
+typedef struct X509_val_st
+	{
+	ASN1_UTCTIME *notBefore;
+	ASN1_UTCTIME *notAfter;
+	} X509_VAL;
+
+typedef struct X509_pubkey_st
+	{
+	X509_ALGOR *algor;
+	ASN1_BIT_STRING *public_key;
+	EVP_PKEY *pkey;
+	} X509_PUBKEY;
+
+typedef struct X509_sig_st
+	{
+	X509_ALGOR *algor;
+	ASN1_OCTET_STRING *digest;
+	} X509_SIG;
+
+typedef struct X509_name_entry_st
+	{
+	ASN1_OBJECT *object;
+	ASN1_STRING *value;
+	int set;
+	int size; 	/* temp variable */
+	} X509_NAME_ENTRY;
+
+DECLARE_STACK_OF(X509_NAME_ENTRY)
+DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
+
+/* we always keep X509_NAMEs in 2 forms. */
+typedef struct X509_name_st
+	{
+	STACK_OF(X509_NAME_ENTRY) *entries;
+	int modified;	/* true if 'bytes' needs to be built */
+#ifdef HEADER_BUFFER_H
+	BUF_MEM *bytes;
+#else
+	char *bytes;
+#endif
+	unsigned long hash; /* Keep the hash around for lookups */
+	} X509_NAME;
+
+DECLARE_STACK_OF(X509_NAME)
+
+#define X509_EX_V_NETSCAPE_HACK		0x8000
+#define X509_EX_V_INIT			0x0001
+typedef struct X509_extension_st
+	{
+	ASN1_OBJECT *object;
+	short critical;
+	short netscape_hack;
+	ASN1_OCTET_STRING *value;
+	struct v3_ext_method *method;	/* V3 method to use */
+	void *ext_val;			/* extension value */
+	} X509_EXTENSION;
+
+DECLARE_STACK_OF(X509_EXTENSION)
+DECLARE_ASN1_SET_OF(X509_EXTENSION)
+
+/* a sequence of these are used */
+typedef struct x509_attributes_st
+	{
+	ASN1_OBJECT *object;
+	int set; /* 1 for a set, 0 for a single item (which is wrong) */
+	union	{
+		char		*ptr;
+/* 1 */		STACK_OF(ASN1_TYPE) *set;
+/* 0 */		ASN1_TYPE	*single;
+		} value;
+	} X509_ATTRIBUTE;
+
+DECLARE_STACK_OF(X509_ATTRIBUTE)
+DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
+
+typedef struct X509_req_info_st
+	{
+	ASN1_INTEGER *version;
+	X509_NAME *subject;
+	X509_PUBKEY *pubkey;
+	/*  d=2 hl=2 l=  0 cons: cont: 00 */
+	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+	int req_kludge;
+	} X509_REQ_INFO;
+
+typedef struct X509_req_st
+	{
+	X509_REQ_INFO *req_info;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int references;
+	} X509_REQ;
+
+typedef struct x509_cinf_st
+	{
+	ASN1_INTEGER *version;		/* [ 0 ] default of v1 */
+	ASN1_INTEGER *serialNumber;
+	X509_ALGOR *signature;
+	X509_NAME *issuer;
+	X509_VAL *validity;
+	X509_NAME *subject;
+	X509_PUBKEY *key;
+	ASN1_BIT_STRING *issuerUID;		/* [ 1 ] optional in v2 */
+	ASN1_BIT_STRING *subjectUID;		/* [ 2 ] optional in v2 */
+	STACK_OF(X509_EXTENSION) *extensions;	/* [ 3 ] optional in v3 */
+	} X509_CINF;
+
+/* This stuff is certificate "auxiliary info"
+ * it contains details which are useful in certificate
+ * stores and databases. When used this is tagged onto
+ * the end of the certificate itself
+ */
+
+typedef struct x509_cert_aux_st
+	{
+	STACK_OF(ASN1_OBJECT) *trust;		/* trusted uses */
+	STACK_OF(ASN1_OBJECT) *reject;		/* rejected uses */
+	ASN1_UTF8STRING *alias;			/* "friendly name" */
+	ASN1_OCTET_STRING *keyid;		/* key id of private key */
+	STACK_OF(X509_ALGOR) *other;		/* other unspecified info */
+	} X509_CERT_AUX;
+
+typedef struct x509_st
+	{
+	X509_CINF *cert_info;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int valid;
+	int references;
+	char *name;
+	CRYPTO_EX_DATA ex_data;
+	/* These contain copies of various extension values */
+	long ex_pathlen;
+	unsigned long ex_flags;
+	unsigned long ex_kusage;
+	unsigned long ex_xkusage;
+	unsigned long ex_nscert;
+#ifndef NO_SHA
+	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+#endif
+	X509_CERT_AUX *aux;
+	} X509;
+
+DECLARE_STACK_OF(X509)
+DECLARE_ASN1_SET_OF(X509)
+
+/* This is used for a table of trust checking functions */
+
+typedef struct x509_trust_st {
+	int trust;
+	int flags;
+	int (*check_trust)(struct x509_trust_st *, X509 *, int);
+	char *name;
+	int arg1;
+	void *arg2;
+} X509_TRUST;
+
+DECLARE_STACK_OF(X509_TRUST)
+
+/* standard trust ids */
+
+#define X509_TRUST_DEFAULT	-1	/* Only valid in purpose settings */
+
+#define X509_TRUST_COMPAT	1
+#define X509_TRUST_SSL_CLIENT	2
+#define X509_TRUST_SSL_SERVER	3
+#define X509_TRUST_EMAIL	4
+#define X509_TRUST_OBJECT_SIGN	5
+
+/* Keep these up to date! */
+#define X509_TRUST_MIN		1
+#define X509_TRUST_MAX		5
+
+
+/* trust_flags values */
+#define	X509_TRUST_DYNAMIC 	1
+#define	X509_TRUST_DYNAMIC_NAME	2
+
+/* check_trust return codes */
+
+#define X509_TRUST_TRUSTED	1
+#define X509_TRUST_REJECTED	2
+#define X509_TRUST_UNTRUSTED	3
+
+typedef struct X509_revoked_st
+	{
+	ASN1_INTEGER *serialNumber;
+	ASN1_UTCTIME *revocationDate;
+	STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+	int sequence; /* load sequence */
+	} X509_REVOKED;
+
+DECLARE_STACK_OF(X509_REVOKED)
+DECLARE_ASN1_SET_OF(X509_REVOKED)
+
+typedef struct X509_crl_info_st
+	{
+	ASN1_INTEGER *version;
+	X509_ALGOR *sig_alg;
+	X509_NAME *issuer;
+	ASN1_UTCTIME *lastUpdate;
+	ASN1_UTCTIME *nextUpdate;
+	STACK_OF(X509_REVOKED) *revoked;
+	STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
+	} X509_CRL_INFO;
+
+typedef struct X509_crl_st
+	{
+	/* actual signature */
+	X509_CRL_INFO *crl;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int references;
+	} X509_CRL;
+
+DECLARE_STACK_OF(X509_CRL)
+DECLARE_ASN1_SET_OF(X509_CRL)
+
+typedef struct private_key_st
+	{
+	int version;
+	/* The PKCS#8 data types */
+	X509_ALGOR *enc_algor;
+	ASN1_OCTET_STRING *enc_pkey;	/* encrypted pub key */
+
+	/* When decrypted, the following will not be NULL */
+	EVP_PKEY *dec_pkey;
+
+	/* used to encrypt and decrypt */
+	int key_length;
+	char *key_data;
+	int key_free;	/* true if we should auto free key_data */
+
+	/* expanded version of 'enc_algor' */
+	EVP_CIPHER_INFO cipher;
+
+	int references;
+	} X509_PKEY;
+
+#ifdef HEADER_ENVELOPE_H
+typedef struct X509_info_st
+	{
+	X509 *x509;
+	X509_CRL *crl;
+	X509_PKEY *x_pkey;
+
+	EVP_CIPHER_INFO enc_cipher;
+	int enc_len;
+	char *enc_data;
+
+	int references;
+	} X509_INFO;
+
+DECLARE_STACK_OF(X509_INFO)
+#endif
+
+/* The next 2 structures and their 8 routines were sent to me by
+ * Pat Richard <patr@x509.com> and are used to manipulate
+ * Netscapes spki structures - useful if you are writing a CA web page
+ */
+typedef struct Netscape_spkac_st
+	{
+	X509_PUBKEY *pubkey;
+	ASN1_IA5STRING *challenge;	/* challenge sent in atlas >= PR2 */
+	} NETSCAPE_SPKAC;
+
+typedef struct Netscape_spki_st
+	{
+	NETSCAPE_SPKAC *spkac;	/* signed public key and challenge */
+	X509_ALGOR *sig_algor;
+	ASN1_BIT_STRING *signature;
+	} NETSCAPE_SPKI;
+
+/* Netscape certificate sequence structure */
+typedef struct Netscape_certificate_sequence
+	{
+	ASN1_OBJECT *type;
+	STACK_OF(X509) *certs;
+	} NETSCAPE_CERT_SEQUENCE;
+
+typedef struct CBCParameter_st
+	{
+	unsigned char iv[8];
+	} CBC_PARAM;
+
+/* Password based encryption structure */
+
+typedef struct PBEPARAM_st {
+ASN1_OCTET_STRING *salt;
+ASN1_INTEGER *iter;
+} PBEPARAM;
+
+/* Password based encryption V2 structures */
+
+typedef struct PBE2PARAM_st {
+X509_ALGOR *keyfunc;
+X509_ALGOR *encryption;
+} PBE2PARAM;
+
+typedef struct PBKDF2PARAM_st {
+ASN1_TYPE *salt;	/* Usually OCTET STRING but could be anything */
+ASN1_INTEGER *iter;
+ASN1_INTEGER *keylength;
+X509_ALGOR *prf;
+} PBKDF2PARAM;
+
+
+/* PKCS#8 private key info structure */
+
+typedef struct pkcs8_priv_key_info_st
+        {
+        int broken;     /* Flag for various broken formats */
+#define PKCS8_OK		0
+#define PKCS8_NO_OCTET		1
+#define PKCS8_EMBEDDED_PARAM	2
+#define PKCS8_NS_DB		3
+        ASN1_INTEGER *version;
+        X509_ALGOR *pkeyalg;
+        ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
+        STACK_OF(X509_ATTRIBUTE) *attributes;
+        } PKCS8_PRIV_KEY_INFO;
+
+#include <openssl/x509_vfy.h>
+#include <openssl/openssl_pkcs7.h>
+
+#ifdef SSLEAY_MACROS
+#define X509_verify(a,r) ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,\
+	a->signature,(char *)a->cert_info,r)
+#define X509_REQ_verify(a,r) ASN1_verify((int (*)())i2d_X509_REQ_INFO, \
+	a->sig_alg,a->signature,(char *)a->req_info,r)
+#define X509_CRL_verify(a,r) ASN1_verify((int (*)())i2d_X509_CRL_INFO, \
+	a->sig_alg, a->signature,(char *)a->crl,r)
+
+#define X509_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature, \
+		x->sig_alg, x->signature, (char *)x->cert_info,pkey,md)
+#define X509_REQ_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_REQ_INFO,x->sig_alg, NULL, \
+		x->signature, (char *)x->req_info,pkey,md)
+#define X509_CRL_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_CRL_INFO,x->crl->sig_alg,x->sig_alg, \
+		x->signature, (char *)x->crl,pkey,md)
+#define NETSCAPE_SPKI_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_NETSCAPE_SPKAC, x->sig_algor,NULL, \
+		x->signature, (char *)x->spkac,pkey,md)
+
+#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \
+		(char *(*)())d2i_X509,(char *)x509)
+#define X509_ATTRIBUTE_dup(xa) (X509_ATTRIBUTE *)ASN1_dup(\
+		(int (*)())i2d_X509_ATTRIBUTE, \
+		(char *(*)())d2i_X509_ATTRIBUTE,(char *)xa)
+#define X509_EXTENSION_dup(ex) (X509_EXTENSION *)ASN1_dup( \
+		(int (*)())i2d_X509_EXTENSION, \
+		(char *(*)())d2i_X509_EXTENSION,(char *)ex)
+#define d2i_X509_fp(fp,x509) (X509 *)ASN1_d2i_fp((char *(*)())X509_new, \
+		(char *(*)())d2i_X509, (fp),(unsigned char **)(x509))
+#define i2d_X509_fp(fp,x509) ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509)
+#define d2i_X509_bio(bp,x509) (X509 *)ASN1_d2i_bio((char *(*)())X509_new, \
+		(char *(*)())d2i_X509, (bp),(unsigned char **)(x509))
+#define i2d_X509_bio(bp,x509) ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509)
+
+#define X509_CRL_dup(crl) (X509_CRL *)ASN1_dup((int (*)())i2d_X509_CRL, \
+		(char *(*)())d2i_X509_CRL,(char *)crl)
+#define d2i_X509_CRL_fp(fp,crl) (X509_CRL *)ASN1_d2i_fp((char *(*)()) \
+		X509_CRL_new,(char *(*)())d2i_X509_CRL, (fp),\
+		(unsigned char **)(crl))
+#define i2d_X509_CRL_fp(fp,crl) ASN1_i2d_fp(i2d_X509_CRL,fp,\
+		(unsigned char *)crl)
+#define d2i_X509_CRL_bio(bp,crl) (X509_CRL *)ASN1_d2i_bio((char *(*)()) \
+		X509_CRL_new,(char *(*)())d2i_X509_CRL, (bp),\
+		(unsigned char **)(crl))
+#define i2d_X509_CRL_bio(bp,crl) ASN1_i2d_bio(i2d_X509_CRL,bp,\
+		(unsigned char *)crl)
+
+#define PKCS7_dup(p7) (PKCS7 *)ASN1_dup((int (*)())i2d_PKCS7, \
+		(char *(*)())d2i_PKCS7,(char *)p7)
+#define d2i_PKCS7_fp(fp,p7) (PKCS7 *)ASN1_d2i_fp((char *(*)()) \
+		PKCS7_new,(char *(*)())d2i_PKCS7, (fp),\
+		(unsigned char **)(p7))
+#define i2d_PKCS7_fp(fp,p7) ASN1_i2d_fp(i2d_PKCS7,fp,\
+		(unsigned char *)p7)
+#define d2i_PKCS7_bio(bp,p7) (PKCS7 *)ASN1_d2i_bio((char *(*)()) \
+		PKCS7_new,(char *(*)())d2i_PKCS7, (bp),\
+		(unsigned char **)(p7))
+#define i2d_PKCS7_bio(bp,p7) ASN1_i2d_bio(i2d_PKCS7,bp,\
+		(unsigned char *)p7)
+
+#define X509_REQ_dup(req) (X509_REQ *)ASN1_dup((int (*)())i2d_X509_REQ, \
+		(char *(*)())d2i_X509_REQ,(char *)req)
+#define d2i_X509_REQ_fp(fp,req) (X509_REQ *)ASN1_d2i_fp((char *(*)())\
+		X509_REQ_new, (char *(*)())d2i_X509_REQ, (fp),\
+		(unsigned char **)(req))
+#define i2d_X509_REQ_fp(fp,req) ASN1_i2d_fp(i2d_X509_REQ,fp,\
+		(unsigned char *)req)
+#define d2i_X509_REQ_bio(bp,req) (X509_REQ *)ASN1_d2i_bio((char *(*)())\
+		X509_REQ_new, (char *(*)())d2i_X509_REQ, (bp),\
+		(unsigned char **)(req))
+#define i2d_X509_REQ_bio(bp,req) ASN1_i2d_bio(i2d_X509_REQ,bp,\
+		(unsigned char *)req)
+
+#define RSAPublicKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey, \
+		(char *(*)())d2i_RSAPublicKey,(char *)rsa)
+#define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, \
+		(char *(*)())d2i_RSAPrivateKey,(char *)rsa)
+
+#define d2i_RSAPrivateKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPrivateKey, (fp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPrivateKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPrivateKey,fp, \
+		(unsigned char *)rsa)
+#define d2i_RSAPrivateKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPrivateKey, (bp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPrivateKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPrivateKey,bp, \
+		(unsigned char *)rsa)
+
+#define d2i_RSAPublicKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPublicKey, (fp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPublicKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPublicKey,fp, \
+		(unsigned char *)rsa)
+#define d2i_RSAPublicKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPublicKey, (bp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPublicKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPublicKey,bp, \
+		(unsigned char *)rsa)
+
+#define d2i_DSAPrivateKey_fp(fp,dsa) (DSA *)ASN1_d2i_fp((char *(*)())\
+		DSA_new,(char *(*)())d2i_DSAPrivateKey, (fp), \
+		(unsigned char **)(dsa))
+#define i2d_DSAPrivateKey_fp(fp,dsa) ASN1_i2d_fp(i2d_DSAPrivateKey,fp, \
+		(unsigned char *)dsa)
+#define d2i_DSAPrivateKey_bio(bp,dsa) (DSA *)ASN1_d2i_bio((char *(*)())\
+		DSA_new,(char *(*)())d2i_DSAPrivateKey, (bp), \
+		(unsigned char **)(dsa))
+#define i2d_DSAPrivateKey_bio(bp,dsa) ASN1_i2d_bio(i2d_DSAPrivateKey,bp, \
+		(unsigned char *)dsa)
+
+#define X509_ALGOR_dup(xn) (X509_ALGOR *)ASN1_dup((int (*)())i2d_X509_ALGOR,\
+		(char *(*)())d2i_X509_ALGOR,(char *)xn)
+
+#define X509_NAME_dup(xn) (X509_NAME *)ASN1_dup((int (*)())i2d_X509_NAME, \
+		(char *(*)())d2i_X509_NAME,(char *)xn)
+#define X509_NAME_ENTRY_dup(ne) (X509_NAME_ENTRY *)ASN1_dup( \
+		(int (*)())i2d_X509_NAME_ENTRY, \
+		(char *(*)())d2i_X509_NAME_ENTRY,\
+		(char *)ne)
+
+#define X509_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len)
+#define X509_NAME_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_X509_NAME,type,(char *)data,md,len)
+#ifndef PKCS7_ISSUER_AND_SERIAL_digest
+#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
+		(char *)data,md,len)
+#endif
+#endif
+
+#define X509_EXT_PACK_UNKNOWN	1
+#define X509_EXT_PACK_STRING	2
+
+#define		X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
+/* #define	X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
+#define		X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
+#define		X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
+#define		X509_extract_key(x)	X509_get_pubkey(x) /*****/
+#define		X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
+#define		X509_REQ_get_subject_name(x) ((x)->req_info->subject)
+#define		X509_REQ_extract_key(a)	X509_REQ_get_pubkey(a)
+#define		X509_name_cmp(a,b)	X509_NAME_cmp((a),(b))
+#define		X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
+
+#define		X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
+#define 	X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
+#define 	X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
+#define		X509_CRL_get_issuer(x) ((x)->crl->issuer)
+#define		X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
+
+/* This one is only used so that a binary form can output, as in
+ * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
+#define 	X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
+
+
+const char *X509_verify_cert_error_string(long n);
+
+#ifndef SSLEAY_MACROS
+#ifdef HEADER_ENVELOPE_H
+int X509_verify(X509 *a, EVP_PKEY *r);
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+
+NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len);
+char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+
+int X509_digest(X509 *data,const EVP_MD *type,unsigned char *md,unsigned int *len);
+int X509_NAME_digest(X509_NAME *data,const EVP_MD *type,
+	unsigned char *md,unsigned int *len);
+#endif
+
+#ifndef NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+int i2d_X509_fp(FILE *fp,X509 *x509);
+X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl);
+int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req);
+int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req);
+#ifndef NO_RSA
+RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa);
+RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
+int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa);
+#endif
+#ifndef NO_DSA
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+#endif
+X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
+int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+						PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+#endif
+
+#ifdef HEADER_BIO_H
+X509 *d2i_X509_bio(BIO *bp,X509 **x509);
+int i2d_X509_bio(BIO *bp,X509 *x509);
+X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl);
+int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req);
+int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req);
+#ifndef NO_RSA
+RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa);
+RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
+int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa);
+#endif
+#ifndef NO_DSA
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+#endif
+X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8);
+int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+						PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+#endif
+
+X509 *X509_dup(X509 *x509);
+X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+X509_CRL *X509_CRL_dup(X509_CRL *crl);
+X509_REQ *X509_REQ_dup(X509_REQ *req);
+X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+X509_NAME *X509_NAME_dup(X509_NAME *xn);
+X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+#ifndef NO_RSA
+RSA *RSAPublicKey_dup(RSA *rsa);
+RSA *RSAPrivateKey_dup(RSA *rsa);
+#endif
+
+#endif /* !SSLEAY_MACROS */
+
+int		X509_cmp_current_time(ASN1_UTCTIME *s);
+ASN1_UTCTIME *	X509_gmtime_adj(ASN1_UTCTIME *s, long adj);
+
+const char *	X509_get_default_cert_area(void );
+const char *	X509_get_default_cert_dir(void );
+const char *	X509_get_default_cert_file(void );
+const char *	X509_get_default_cert_dir_env(void );
+const char *	X509_get_default_cert_file_env(void );
+const char *	X509_get_default_private_dir(void );
+
+X509_REQ *	X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+X509 *		X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey);
+void ERR_load_X509_strings(void );
+
+X509_ALGOR *	X509_ALGOR_new(void );
+void		X509_ALGOR_free(X509_ALGOR *a);
+int		i2d_X509_ALGOR(X509_ALGOR *a,unsigned char **pp);
+X509_ALGOR *	d2i_X509_ALGOR(X509_ALGOR **a,unsigned char **pp,
+			long length);
+
+X509_VAL *	X509_VAL_new(void );
+void		X509_VAL_free(X509_VAL *a);
+int		i2d_X509_VAL(X509_VAL *a,unsigned char **pp);
+X509_VAL *	d2i_X509_VAL(X509_VAL **a,unsigned char **pp,
+			long length);
+
+X509_PUBKEY *	X509_PUBKEY_new(void );
+void		X509_PUBKEY_free(X509_PUBKEY *a);
+int		i2d_X509_PUBKEY(X509_PUBKEY *a,unsigned char **pp);
+X509_PUBKEY *	d2i_X509_PUBKEY(X509_PUBKEY **a,unsigned char **pp,
+			long length);
+int		X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_PUBKEY_get(X509_PUBKEY *key);
+int		X509_get_pubkey_parameters(EVP_PKEY *pkey,
+					   STACK_OF(X509) *chain);
+int		i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp);
+EVP_PKEY *	d2i_PUBKEY(EVP_PKEY **a,unsigned char **pp,
+			long length);
+#ifndef NO_RSA
+int		i2d_RSA_PUBKEY(RSA *a,unsigned char **pp);
+RSA *		d2i_RSA_PUBKEY(RSA **a,unsigned char **pp,
+			long length);
+#endif
+#ifndef NO_DSA
+int		i2d_DSA_PUBKEY(DSA *a,unsigned char **pp);
+DSA *		d2i_DSA_PUBKEY(DSA **a,unsigned char **pp,
+			long length);
+#endif
+
+X509_SIG *	X509_SIG_new(void );
+void		X509_SIG_free(X509_SIG *a);
+int		i2d_X509_SIG(X509_SIG *a,unsigned char **pp);
+X509_SIG *	d2i_X509_SIG(X509_SIG **a,unsigned char **pp,long length);
+
+X509_REQ_INFO *X509_REQ_INFO_new(void);
+void		X509_REQ_INFO_free(X509_REQ_INFO *a);
+int		i2d_X509_REQ_INFO(X509_REQ_INFO *a,unsigned char **pp);
+X509_REQ_INFO *d2i_X509_REQ_INFO(X509_REQ_INFO **a,unsigned char **pp,
+			long length);
+
+X509_REQ *	X509_REQ_new(void);
+void		X509_REQ_free(X509_REQ *a);
+int		i2d_X509_REQ(X509_REQ *a,unsigned char **pp);
+X509_REQ *	d2i_X509_REQ(X509_REQ **a,unsigned char **pp,long length);
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_new(void );
+void		X509_ATTRIBUTE_free(X509_ATTRIBUTE *a);
+int		i2d_X509_ATTRIBUTE(X509_ATTRIBUTE *a,unsigned char **pp);
+X509_ATTRIBUTE *d2i_X509_ATTRIBUTE(X509_ATTRIBUTE **a,unsigned char **pp,
+			long length);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+
+
+X509_EXTENSION *X509_EXTENSION_new(void );
+void		X509_EXTENSION_free(X509_EXTENSION *a);
+int		i2d_X509_EXTENSION(X509_EXTENSION *a,unsigned char **pp);
+X509_EXTENSION *d2i_X509_EXTENSION(X509_EXTENSION **a,unsigned char **pp,
+			long length);
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_new(void);
+void		X509_NAME_ENTRY_free(X509_NAME_ENTRY *a);
+int		i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a,unsigned char **pp);
+X509_NAME_ENTRY *d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a,unsigned char **pp,
+			long length);
+
+X509_NAME *	X509_NAME_new(void);
+void		X509_NAME_free(X509_NAME *a);
+int		i2d_X509_NAME(X509_NAME *a,unsigned char **pp);
+X509_NAME *	d2i_X509_NAME(X509_NAME **a,unsigned char **pp,long length);
+int		X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+
+
+X509_CINF *	X509_CINF_new(void);
+void		X509_CINF_free(X509_CINF *a);
+int		i2d_X509_CINF(X509_CINF *a,unsigned char **pp);
+X509_CINF *	d2i_X509_CINF(X509_CINF **a,unsigned char **pp,long length);
+
+X509 *		X509_new(void);
+void		X509_free(X509 *a);
+int		i2d_X509(X509 *a,unsigned char **pp);
+X509 *		d2i_X509(X509 **a,unsigned char **pp,long length);
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int X509_set_ex_data(X509 *r, int idx, void *arg);
+void *X509_get_ex_data(X509 *r, int idx);
+int		i2d_X509_AUX(X509 *a,unsigned char **pp);
+X509 *		d2i_X509_AUX(X509 **a,unsigned char **pp,long length);
+
+X509_CERT_AUX *	X509_CERT_AUX_new(void);
+void		X509_CERT_AUX_free(X509_CERT_AUX *a);
+int		i2d_X509_CERT_AUX(X509_CERT_AUX *a,unsigned char **pp);
+X509_CERT_AUX *	d2i_X509_CERT_AUX(X509_CERT_AUX **a,unsigned char **pp,
+								long length);
+int X509_alias_set1(X509 *x, unsigned char *name, int len);
+unsigned char * X509_alias_get0(X509 *x, int *len);
+int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
+void X509_trust_clear(X509 *x);
+void X509_reject_clear(X509 *x);
+
+X509_REVOKED *	X509_REVOKED_new(void);
+void		X509_REVOKED_free(X509_REVOKED *a);
+int		i2d_X509_REVOKED(X509_REVOKED *a,unsigned char **pp);
+X509_REVOKED *	d2i_X509_REVOKED(X509_REVOKED **a,unsigned char **pp,long length);
+
+X509_CRL_INFO *X509_CRL_INFO_new(void);
+void		X509_CRL_INFO_free(X509_CRL_INFO *a);
+int		i2d_X509_CRL_INFO(X509_CRL_INFO *a,unsigned char **pp);
+X509_CRL_INFO *d2i_X509_CRL_INFO(X509_CRL_INFO **a,unsigned char **pp,
+			long length);
+
+X509_CRL *	X509_CRL_new(void);
+void		X509_CRL_free(X509_CRL *a);
+int		i2d_X509_CRL(X509_CRL *a,unsigned char **pp);
+X509_CRL *	d2i_X509_CRL(X509_CRL **a,unsigned char **pp,long length);
+
+X509_PKEY *	X509_PKEY_new(void );
+void		X509_PKEY_free(X509_PKEY *a);
+int		i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp);
+X509_PKEY *	d2i_X509_PKEY(X509_PKEY **a,unsigned char **pp,long length);
+
+NETSCAPE_SPKI *	NETSCAPE_SPKI_new(void );
+void		NETSCAPE_SPKI_free(NETSCAPE_SPKI *a);
+int		i2d_NETSCAPE_SPKI(NETSCAPE_SPKI *a,unsigned char **pp);
+NETSCAPE_SPKI *	d2i_NETSCAPE_SPKI(NETSCAPE_SPKI **a,unsigned char **pp,
+			long length);
+
+NETSCAPE_SPKAC *NETSCAPE_SPKAC_new(void );
+void		NETSCAPE_SPKAC_free(NETSCAPE_SPKAC *a);
+int		i2d_NETSCAPE_SPKAC(NETSCAPE_SPKAC *a,unsigned char **pp);
+NETSCAPE_SPKAC *d2i_NETSCAPE_SPKAC(NETSCAPE_SPKAC **a,unsigned char **pp,
+		long length);
+
+
+int i2d_NETSCAPE_CERT_SEQUENCE(NETSCAPE_CERT_SEQUENCE *a, unsigned char **pp);
+NETSCAPE_CERT_SEQUENCE *NETSCAPE_CERT_SEQUENCE_new(void);
+NETSCAPE_CERT_SEQUENCE *d2i_NETSCAPE_CERT_SEQUENCE(NETSCAPE_CERT_SEQUENCE **a, unsigned char **pp, long length);
+void NETSCAPE_CERT_SEQUENCE_free(NETSCAPE_CERT_SEQUENCE *a);
+
+#ifdef HEADER_ENVELOPE_H
+X509_INFO *	X509_INFO_new(void);
+void		X509_INFO_free(X509_INFO *a);
+char *		X509_NAME_oneline(X509_NAME *a,char *buf,int size);
+
+int ASN1_verify(int (*i2d)(), X509_ALGOR *algor1,
+	ASN1_BIT_STRING *signature,char *data,EVP_PKEY *pkey);
+
+int ASN1_digest(int (*i2d)(),const EVP_MD *type,char *data,
+	unsigned char *md,unsigned int *len);
+
+int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
+	ASN1_BIT_STRING *signature,
+	char *data,EVP_PKEY *pkey, const EVP_MD *type);
+#endif
+
+int 		X509_set_version(X509 *x,long version);
+int 		X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+ASN1_INTEGER *	X509_get_serialNumber(X509 *x);
+int 		X509_set_issuer_name(X509 *x, X509_NAME *name);
+X509_NAME *	X509_get_issuer_name(X509 *a);
+int 		X509_set_subject_name(X509 *x, X509_NAME *name);
+X509_NAME *	X509_get_subject_name(X509 *a);
+int 		X509_set_notBefore(X509 *x, ASN1_UTCTIME *tm);
+int 		X509_set_notAfter(X509 *x, ASN1_UTCTIME *tm);
+int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_get_pubkey(X509 *x);
+int		X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
+
+int		X509_REQ_set_version(X509_REQ *x,long version);
+int		X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
+int		X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_REQ_get_pubkey(X509_REQ *req);
+int		X509_REQ_extension_nid(int nid);
+int *		X509_REQ_get_extension_nids(void);
+void		X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+				int nid);
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
+			  int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+			ASN1_OBJECT *obj, int type,
+			unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+			int nid, int type,
+			unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+			char *attrname, int type,
+			unsigned char *bytes, int len);
+
+int		X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
+
+int		X509_issuer_and_serial_cmp(X509 *a, X509 *b);
+unsigned long	X509_issuer_and_serial_hash(X509 *a);
+
+int		X509_issuer_name_cmp(X509 *a, X509 *b);
+unsigned long	X509_issuer_name_hash(X509 *a);
+
+int		X509_subject_name_cmp(X509 *a,X509 *b);
+unsigned long	X509_subject_name_hash(X509 *x);
+
+int		X509_cmp (X509 *a, X509 *b);
+int		X509_NAME_cmp (X509_NAME *a, X509_NAME *b);
+unsigned long	X509_NAME_hash(X509_NAME *x);
+
+int		X509_CRL_cmp(X509_CRL *a,X509_CRL *b);
+#ifndef NO_FP_API
+int		X509_print_fp(FILE *bp,X509 *x);
+int		X509_CRL_print_fp(FILE *bp,X509_CRL *x);
+int		X509_REQ_print_fp(FILE *bp,X509_REQ *req);
+#endif
+
+#ifdef HEADER_BIO_H
+int		X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+int		X509_print(BIO *bp,X509 *x);
+int		X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
+int		X509_CRL_print(BIO *bp,X509_CRL *x);
+int		X509_REQ_print(BIO *bp,X509_REQ *req);
+#endif
+
+int 		X509_NAME_entry_count(X509_NAME *name);
+int 		X509_NAME_get_text_by_NID(X509_NAME *name, int nid,
+			char *buf,int len);
+int		X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+			char *buf,int len);
+
+/* NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
+ * lastpos, search after that position on. */
+int 		X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
+int 		X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj,
+			int lastpos);
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+int 		X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,
+			int loc, int set);
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+			unsigned char *bytes, int len, int loc, int set);
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+			unsigned char *bytes, int len, int loc, int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+		char *field, int type, unsigned char *bytes, int len);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+			int type,unsigned char *bytes, int len);
+int X509_NAME_add_entry_by_txt(X509_NAME *name, char *field, int type,
+			unsigned char *bytes, int len, int loc, int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+			ASN1_OBJECT *obj, int type,unsigned char *bytes,
+			int len);
+int 		X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne,
+			ASN1_OBJECT *obj);
+int 		X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+			unsigned char *bytes, int len);
+ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+
+int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+				      int nid, int lastpos);
+int		X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+				      ASN1_OBJECT *obj,int lastpos);
+int		X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+					   int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+					 X509_EXTENSION *ex, int loc);
+
+int		X509_get_ext_count(X509 *x);
+int		X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
+int		X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
+X509_EXTENSION *X509_get_ext(X509 *x, int loc);
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+
+int		X509_CRL_get_ext_count(X509_CRL *x);
+int		X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
+int		X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+int		X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+
+int		X509_REVOKED_get_ext_count(X509_REVOKED *x);
+int		X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
+int		X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+int		X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+			int nid, int crit, ASN1_OCTET_STRING *data);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+			ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data);
+int		X509_EXTENSION_set_object(X509_EXTENSION *ex,ASN1_OBJECT *obj);
+int		X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+int		X509_EXTENSION_set_data(X509_EXTENSION *ex,
+			ASN1_OCTET_STRING *data);
+ASN1_OBJECT *	X509_EXTENSION_get_object(X509_EXTENSION *ex);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+int		X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+			  int lastpos);
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+					 X509_ATTRIBUTE *attr);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
+			ASN1_OBJECT *obj, int type,
+			unsigned char *bytes, int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
+			int nid, int type,
+			unsigned char *bytes, int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
+			char *attrname, int type,
+			unsigned char *bytes, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+	     int atrtype, void *data, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+	     ASN1_OBJECT *obj, int atrtype, void *data, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+		char *atrname, int type, unsigned char *bytes, int len);
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, ASN1_OBJECT *obj);
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, void *data, int len);
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
+					int atrtype, void *data);
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+
+int		X509_verify_cert(X509_STORE_CTX *ctx);
+
+/* lookup a cert from a X509 STACK */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name,
+				     ASN1_INTEGER *serial);
+X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name);
+
+int i2d_PBEPARAM(PBEPARAM *a, unsigned char **pp);
+PBEPARAM *PBEPARAM_new(void);
+PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, unsigned char **pp, long length);
+void PBEPARAM_free(PBEPARAM *a);
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+					 unsigned char *salt, int saltlen);
+
+int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **pp);
+PBKDF2PARAM *PBKDF2PARAM_new(void);
+PBKDF2PARAM *d2i_PBKDF2PARAM(PBKDF2PARAM **a, unsigned char **pp, long length);
+void PBKDF2PARAM_free(PBKDF2PARAM *a);
+
+int i2d_PBE2PARAM(PBE2PARAM *a, unsigned char **pp);
+PBE2PARAM *PBE2PARAM_new(void);
+PBE2PARAM *d2i_PBE2PARAM(PBE2PARAM **a, unsigned char **pp, long length);
+void PBE2PARAM_free(PBE2PARAM *a);
+
+/* PKCS#8 utilities */
+
+int i2d_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO *a, unsigned char **pp);
+PKCS8_PRIV_KEY_INFO *PKCS8_PRIV_KEY_INFO_new(void);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a,
+					 unsigned char **pp, long length);
+void PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *a);
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
+
+int X509_check_trust(X509 *x, int id, int flags);
+int X509_TRUST_get_count(void);
+X509_TRUST * X509_TRUST_get0(int idx);
+int X509_TRUST_get_by_id(int id);
+int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
+					char *name, int arg1, void *arg2);
+void X509_TRUST_cleanup(void);
+int X509_TRUST_get_flags(X509_TRUST *xp);
+char *X509_TRUST_get0_name(X509_TRUST *xp);
+int X509_TRUST_get_trust(X509_TRUST *xp);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the X509 functions. */
+
+/* Function codes. */
+#define X509_F_ADD_CERT_DIR				 100
+#define X509_F_BY_FILE_CTRL				 101
+#define X509_F_DIR_CTRL					 102
+#define X509_F_GET_CERT_BY_SUBJECT			 103
+#define X509_F_NETSCAPE_SPKI_B64_DECODE			 129
+#define X509_F_NETSCAPE_SPKI_B64_ENCODE			 130
+#define X509_F_X509V3_ADD_EXT				 104
+#define X509_F_X509_ADD_ATTR				 135
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID		 136
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ		 137
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT		 140
+#define X509_F_X509_ATTRIBUTE_GET0_DATA			 139
+#define X509_F_X509_ATTRIBUTE_SET1_DATA			 138
+#define X509_F_X509_CHECK_PRIVATE_KEY			 128
+#define X509_F_X509_EXTENSION_CREATE_BY_NID		 108
+#define X509_F_X509_EXTENSION_CREATE_BY_OBJ		 109
+#define X509_F_X509_GET_PUBKEY_PARAMETERS		 110
+#define X509_F_X509_LOAD_CERT_CRL_FILE			 132
+#define X509_F_X509_LOAD_CERT_FILE			 111
+#define X509_F_X509_LOAD_CRL_FILE			 112
+#define X509_F_X509_NAME_ADD_ENTRY			 113
+#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID		 114
+#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT		 131
+#define X509_F_X509_NAME_ENTRY_SET_OBJECT		 115
+#define X509_F_X509_NAME_ONELINE			 116
+#define X509_F_X509_NAME_PRINT				 117
+#define X509_F_X509_PRINT_FP				 118
+#define X509_F_X509_PUBKEY_GET				 119
+#define X509_F_X509_PUBKEY_SET				 120
+#define X509_F_X509_REQ_PRINT				 121
+#define X509_F_X509_REQ_PRINT_FP			 122
+#define X509_F_X509_REQ_TO_X509				 123
+#define X509_F_X509_STORE_ADD_CERT			 124
+#define X509_F_X509_STORE_ADD_CRL			 125
+#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT		 134
+#define X509_F_X509_TO_X509_REQ				 126
+#define X509_F_X509_TRUST_ADD				 133
+#define X509_F_X509_VERIFY_CERT				 127
+
+/* Reason codes. */
+#define X509_R_BAD_X509_FILETYPE			 100
+#define X509_R_BASE64_DECODE_ERROR			 118
+#define X509_R_CANT_CHECK_DH_KEY			 114
+#define X509_R_CERT_ALREADY_IN_HASH_TABLE		 101
+#define X509_R_ERR_ASN1_LIB				 102
+#define X509_R_INVALID_DIRECTORY			 113
+#define X509_R_INVALID_FIELD_NAME			 119
+#define X509_R_KEY_TYPE_MISMATCH			 115
+#define X509_R_KEY_VALUES_MISMATCH			 116
+#define X509_R_LOADING_CERT_DIR				 103
+#define X509_R_LOADING_DEFAULTS				 104
+#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY		 105
+#define X509_R_SHOULD_RETRY				 106
+#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN	 107
+#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY		 108
+#define X509_R_UNKNOWN_KEY_TYPE				 117
+#define X509_R_UNKNOWN_NID				 109
+#define X509_R_UNKNOWN_PURPOSE_ID			 121
+#define X509_R_UNKNOWN_TRUST_ID				 120
+#define X509_R_UNSUPPORTED_ALGORITHM			 111
+#define X509_R_WRONG_LOOKUP_TYPE			 112
+#define X509_R_WRONG_TYPE				 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/openssl/x509_vfy.h b/AppleCSP/open_ssl/openssl/x509_vfy.h
new file mode 100644
index 00000000..7ddfde7b
--- /dev/null
+++ b/AppleCSP/open_ssl/openssl/x509_vfy.h
@@ -0,0 +1,380 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/x509/x509_vfy.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_X509_H
+#include <openssl/x509.h>
+/* openssl/x509.h ends up #include-ing this file at about the only
+ * appropriate moment. */
+#endif
+
+#ifndef HEADER_X509_VFY_H
+#define HEADER_X509_VFY_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+
+/* Outer object */
+typedef struct x509_hash_dir_st
+	{
+	int num_dirs;
+	char **dirs;
+	int *dirs_type;
+	int num_dirs_alloced;
+	} X509_HASH_DIR_CTX;
+
+typedef struct x509_file_st
+	{
+	int num_paths;	/* number of paths to files or directories */
+	int num_alloced;
+	char **paths;	/* the list of paths or directories */
+	int *path_type;
+	} X509_CERT_FILE_CTX;
+
+/*******************************/
+/*
+SSL_CTX -> X509_STORE    
+		-> X509_LOOKUP
+			->X509_LOOKUP_METHOD
+		-> X509_LOOKUP
+			->X509_LOOKUP_METHOD
+ 
+SSL	-> X509_STORE_CTX
+		->X509_STORE    
+
+The X509_STORE holds the tables etc for verification stuff.
+A X509_STORE_CTX is used while validating a single certificate.
+The X509_STORE has X509_LOOKUPs for looking up certs.
+The X509_STORE then calls a function to actually verify the
+certificate chain.
+*/
+
+#define X509_LU_RETRY		-1
+#define X509_LU_FAIL		0
+#define X509_LU_X509		1
+#define X509_LU_CRL		2
+#define X509_LU_PKEY		3
+
+typedef struct x509_object_st
+	{
+	/* one of the above types */
+	int type;
+	union	{
+		char *ptr;
+		X509 *x509;
+		X509_CRL *crl;
+		EVP_PKEY *pkey;
+		} data;
+	} X509_OBJECT;
+
+typedef struct x509_lookup_st X509_LOOKUP;
+
+DECLARE_STACK_OF(X509_LOOKUP)
+
+/* This is a static that defines the function interface */
+typedef struct x509_lookup_method_st
+	{
+	const char *name;
+	int (*new_item)(X509_LOOKUP *ctx);
+	void (*free)(X509_LOOKUP *ctx);
+	int (*init)(X509_LOOKUP *ctx);
+	int (*shutdown)(X509_LOOKUP *ctx);
+	int (*ctrl)(X509_LOOKUP *ctx,int cmd,const char *argc,long argl,
+			char **ret);
+	int (*get_by_subject)(X509_LOOKUP *ctx,int type,X509_NAME *name,
+			      X509_OBJECT *ret);
+	int (*get_by_issuer_serial)(X509_LOOKUP *ctx,int type,X509_NAME *name,
+				    ASN1_INTEGER *serial,X509_OBJECT *ret);
+	int (*get_by_fingerprint)(X509_LOOKUP *ctx,int type,
+				  unsigned char *bytes,int len,
+				  X509_OBJECT *ret);
+	int (*get_by_alias)(X509_LOOKUP *ctx,int type,char *str,int len,
+			    X509_OBJECT *ret);
+	} X509_LOOKUP_METHOD;
+
+typedef struct x509_store_state_st X509_STORE_CTX;
+
+/* This is used to hold everything.  It is used for all certificate
+ * validation.  Once we have a certificate chain, the 'verify'
+ * function is then called to actually check the cert chain. */
+typedef struct x509_store_st
+	{
+	/* The following is a cache of trusted certs */
+	int cache; 	/* if true, stash any hits */
+#ifdef HEADER_LHASH_H
+	LHASH *certs;	/* cached certs; */ 
+#else
+	char *certs;
+#endif
+
+	/* These are external lookup methods */
+	STACK_OF(X509_LOOKUP) *get_cert_methods;
+	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
+	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);	/* error callback */
+
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	int depth;		/* how deep to look (still unused -- X509_STORE_CTX's depth is used) */
+	}  X509_STORE;
+
+#define X509_STORE_set_depth(ctx,d)       ((ctx)->depth=(d))
+
+#define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
+#define X509_STORE_set_verify_func(ctx,func)	((ctx)->verify=(func))
+
+/* This is the functions plus an instance of the local variables. */
+struct x509_lookup_st
+	{
+	int init;			/* have we been started */
+	int skip;			/* don't use us. */
+	X509_LOOKUP_METHOD *method;	/* the functions */
+	char *method_data;		/* method data */
+
+	X509_STORE *store_ctx;	/* who owns us */
+	};
+
+/* This is a temporary used when processing cert chains.  Since the
+ * gathering of the cert chain can take some time (and have to be
+ * 'retried', this needs to be kept and passed around. */
+struct x509_store_state_st      /* X509_STORE_CTX */
+	{
+	X509_STORE *ctx;
+	int current_method;	/* used when looking up certs */
+
+	/* The following are set by the caller */
+	X509 *cert;		/* The cert to check */
+	STACK_OF(X509) *untrusted;	/* chain of X509s - untrusted - passed in */
+	int purpose;		/* purpose to check untrusted certificates */
+	int trust;		/* trust setting to check */
+
+	/* The following is built up */
+	int depth;		/* how far to go looking up certs */
+	int valid;		/* if 0, rebuild chain */
+	int last_untrusted;	/* index of last untrusted cert */
+	STACK_OF(X509) *chain; 		/* chain of X509s - built up and trusted */
+
+	/* When something goes wrong, this is why */
+	int error_depth;
+	int error;
+	X509 *current_cert;
+
+	CRYPTO_EX_DATA ex_data;
+	};
+
+#define X509_STORE_CTX_set_depth(ctx,d)       ((ctx)->depth=(d))
+
+#define X509_STORE_CTX_set_app_data(ctx,data) \
+	X509_STORE_CTX_set_ex_data(ctx,0,data)
+#define X509_STORE_CTX_get_app_data(ctx) \
+	X509_STORE_CTX_get_ex_data(ctx,0)
+
+#define X509_L_FILE_LOAD	1
+#define X509_L_ADD_DIR		2
+
+#define X509_LOOKUP_load_file(x,name,type) \
+		X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
+
+#define X509_LOOKUP_add_dir(x,name,type) \
+		X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
+
+#define		X509_V_OK					0
+/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */
+
+#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT		2
+#define		X509_V_ERR_UNABLE_TO_GET_CRL			3
+#define		X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE	4
+#define		X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE	5
+#define		X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY	6
+#define		X509_V_ERR_CERT_SIGNATURE_FAILURE		7
+#define		X509_V_ERR_CRL_SIGNATURE_FAILURE		8
+#define		X509_V_ERR_CERT_NOT_YET_VALID			9	
+#define		X509_V_ERR_CERT_HAS_EXPIRED			10
+#define		X509_V_ERR_CRL_NOT_YET_VALID			11
+#define		X509_V_ERR_CRL_HAS_EXPIRED			12
+#define		X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD	13
+#define		X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD	14
+#define		X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD	15
+#define		X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD	16
+#define		X509_V_ERR_OUT_OF_MEM				17
+#define		X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT		18
+#define		X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN		19
+#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY	20
+#define		X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE	21
+#define		X509_V_ERR_CERT_CHAIN_TOO_LONG			22
+#define		X509_V_ERR_CERT_REVOKED				23
+#define		X509_V_ERR_INVALID_CA				24
+#define		X509_V_ERR_PATH_LENGTH_EXCEEDED			25
+#define		X509_V_ERR_INVALID_PURPOSE			26
+#define		X509_V_ERR_CERT_UNTRUSTED			27
+#define		X509_V_ERR_CERT_REJECTED			28
+
+/* The application is not happy */
+#define		X509_V_ERR_APPLICATION_VERIFICATION		50
+
+		  /* These functions are being redefined in another directory,
+		     and clash when the linker is case-insensitive, so let's
+		     hide them a little, by giving them an extra 'o' at the
+		     beginning of the name... */
+#ifdef VMS
+#undef X509v3_cleanup_extensions
+#define X509v3_cleanup_extensions oX509v3_cleanup_extensions
+#undef X509v3_add_extension
+#define X509v3_add_extension oX509v3_add_extension
+#undef X509v3_add_netscape_extensions
+#define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions
+#undef X509v3_add_standard_extensions
+#define X509v3_add_standard_extensions oX509v3_add_standard_extensions
+#endif
+
+#ifdef HEADER_LHASH_H
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(LHASH *h,int type,X509_NAME *name);
+#endif
+void X509_OBJECT_up_ref_count(X509_OBJECT *a);
+void X509_OBJECT_free_contents(X509_OBJECT *a);
+X509_STORE *X509_STORE_new(void );
+void X509_STORE_free(X509_STORE *v);
+
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+			 X509 *x509, STACK_OF(X509) *chain);
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name,
+	X509_OBJECT *ret);
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+	long argl, char **ret);
+
+#ifndef NO_STDIO
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+#endif
+
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+void X509_LOOKUP_free(X509_LOOKUP *ctx);
+int X509_LOOKUP_init(X509_LOOKUP *ctx);
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	X509_OBJECT *ret);
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	ASN1_INTEGER *serial, X509_OBJECT *ret);
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+	unsigned char *bytes, int len, X509_OBJECT *ret);
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str,
+	int len, X509_OBJECT *ret);
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+
+#ifndef NO_STDIO
+int	X509_STORE_load_locations (X509_STORE *ctx,
+		const char *file, const char *dir);
+int	X509_STORE_set_default_paths(X509_STORE *ctx);
+#endif
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int	X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
+void *	X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
+int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
+int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
+void	X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+				int purpose, int trust);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
diff --git a/AppleCSP/open_ssl/opensslUtils/openRsaSnacc.cpp b/AppleCSP/open_ssl/opensslUtils/openRsaSnacc.cpp
new file mode 100644
index 00000000..4317e195
--- /dev/null
+++ b/AppleCSP/open_ssl/opensslUtils/openRsaSnacc.cpp
@@ -0,0 +1,637 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * openRsaSnacc.cpp - glue between openrsa and SNACC
+ */
+#include "openRsaSnacc.h"
+#include "opensslUtils.h"
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+
+// bring in a ton of snacc-related stuff
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+
+// snacc-generated - snacc really should place these in pkcs[78].h
+#include <Security/sm_x501ud.h>
+#include <Security/sm_x411ub.h>
+#include <Security/sm_x411mtsas.h>
+#include <Security/sm_x501if.h>
+#include <Security/sm_x520sa.h>
+#include <Security/sm_x509cmn.h>
+#include <Security/sm_x509af.h>
+#include <Security/sm_x509ce.h>
+#include <Security/pkcs1oids.h>
+#include <Security/pkcs9oids.h>
+#include <Security/sm_cms.h>
+#include <Security/sm_ess.h>
+#include <Security/pkcs7.h>
+#include <Security/pkcs8.h>
+
+#include <Security/cdsaUtils.h>
+#include <Security/debugging.h>
+#include <Security/appleoids.h>
+
+
+#define sslSnaccDebug(args...)	debug("sslSnacc", ##args)
+
+/*
+ * Convert between SNACC-style BigIntegerStr and openssl-style BIGNUM.
+ */
+BIGNUM *bigIntStrToBn(
+	BigIntegerStr &snaccInt)
+{
+	BIGNUM *bn = BN_new();
+	BIGNUM *rtn;
+	char *rawOcts = snaccInt;
+	unsigned numBytes = snaccInt.Len();
+	
+	rtn = BN_bin2bn((unsigned char *)rawOcts, numBytes, bn);
+	if(rtn == NULL) {
+		BN_free(bn);
+		CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
+	}
+	return bn;
+}
+
+void bnToBigIntStr(
+	BIGNUM *bn,
+	BigIntegerStr &snaccInt)
+{
+	unsigned numBytes = BN_num_bytes(bn);
+	unsigned char *buf;
+	unsigned char *bp;
+	
+	/* 
+	 * BSAFE is peculiar here. When IT DER-encodes public keys, it often generates
+	 * a publicExponent whose leading bit (m.s. bit in the first byte) is 1. It
+	 * reads these fine, of course. But when it DER-encodes the same value in the
+	 * private key, it hews to DER rules and prepends a leading zero. If WE 
+	 * generate a private key with a field with a leading bit set, without the
+	 * (technically) required leading zero, BSAFE pukes....but only when parsing
+	 * private keys, not public keys. Same field (public exponent), different 
+	 * requirements for public and private keys. So we're cautious and prepend
+	 * a zero if the leading field is one. 
+	 *
+	 * This assumes of course that ALL numbers we're dealing with are positive....
+	 */ 
+	buf = (unsigned char *)Malloc(numBytes + 1);		// extra for possible prepend
+	if(buf == NULL) {
+		throw openSslException(CSSMERR_CSP_MEMORY_ERROR);
+	}
+	BN_bn2bin(bn, buf + 1);			
+	if(buf[1] & 0x80) {
+		/* pedantic DER rules for BSAFE - make sure first byte is zero */
+		buf[0] = 0;
+		bp = buf;
+		numBytes++;
+	}
+	else {
+		/* use what BN_bn2bin gave us */
+		bp = buf+1;
+	}
+	snaccInt.ReSet((char *)bp, numBytes);
+	Free(buf);
+}
+
+/* estimate size of encoded BigIntegerStr */
+unsigned sizeofBigInt(
+	BigIntegerStr &bigInt)
+{
+	return bigInt.Len() + 4;
+}
+
+/* set up a encoded NULL for AlgorithmIdentifier.parameters, required for RSA */
+static void nullAlgParams(
+	AlgorithmIdentifier	&snaccAlgId)
+{
+	snaccAlgId.parameters = new AsnAny;
+	char encodedNull[2] = {NULLTYPE_TAG_CODE, 0};
+	CSM_Buffer *cbuf = new CSM_Buffer(encodedNull, 2);
+	snaccAlgId.parameters->value = cbuf;
+}
+
+
+/*
+ * Replacements for d2i_RSAPublicKey, etc. 
+ */
+CSSM_RETURN RSAPublicKeyDecode(
+	RSA 			*openKey, 
+	void 			*p, 
+	size_t			length)
+{
+	RSAPublicKey snaccPubKey;
+	
+	CssmData cData(p, length);
+	try {
+		SC_decodeAsnObj(cData, snaccPubKey);
+	}
+	catch(...) {
+		return CSSMERR_CSP_INVALID_KEY;
+	}
+	try {
+		openKey->n = bigIntStrToBn(snaccPubKey.modulus);
+		openKey->e = bigIntStrToBn(snaccPubKey.publicExponent);
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	return 0;
+}
+
+CSSM_RETURN	RSAPublicKeyEncode(
+	RSA 			*openKey, 
+	CssmOwnedData	&encodedKey)
+{
+	/* First convert into a snacc-style public key */
+	RSAPublicKey snaccPubKey;
+	
+	try {
+		bnToBigIntStr(openKey->n, snaccPubKey.modulus);
+		bnToBigIntStr(openKey->e, snaccPubKey.publicExponent);
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	
+	/* conservative guess for max size of encoded key */
+	unsigned maxSize = sizeofBigInt(snaccPubKey.modulus) +
+					   sizeofBigInt(snaccPubKey.publicExponent) +
+					   20;
+					   
+	/* DER encode */
+	try {
+		SC_encodeAsnObj(snaccPubKey, encodedKey, maxSize);
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	return 0;
+}
+
+CSSM_RETURN RSAPrivateKeyDecode(
+	RSA 			*openKey, 
+	void 			*p, 
+	size_t			length)
+{
+	PrivateKeyInfo snaccPrivKeyInfo;
+	CssmData cData(p, length);
+	try {
+		SC_decodeAsnObj(cData, snaccPrivKeyInfo);
+	}
+	catch(...) {
+		return CSSMERR_CSP_INVALID_KEY;
+	}
+	
+	/* verify alg identifier */
+	if(snaccPrivKeyInfo.privateKeyAlgorithm == NULL) {
+		sslSnaccDebug("RSAPrivateKeyDecode: no privateKeyAlgorithm");
+		return CSSMERR_CSP_INVALID_KEY;
+	}
+	if(snaccPrivKeyInfo.privateKeyAlgorithm->algorithm != rsaEncryption) {
+		sslSnaccDebug("RSAPrivateKeyDecode: bad privateKeyAlgorithm");
+		return CSSMERR_CSP_ALGID_MISMATCH;
+	}
+	
+	/* 
+	 * snaccPrivKeyInfo.privateKey is an octet string which needs 
+	 * subsequent decoding 
+	 */
+	char *rawOcts = snaccPrivKeyInfo.privateKey;
+	unsigned numBytes = snaccPrivKeyInfo.privateKey.Len();
+	RSAPrivateKey snaccPrivKey;
+	CssmData cData2(rawOcts, numBytes);
+	try {
+		SC_decodeAsnObj(cData2, snaccPrivKey);
+	}
+	catch(...) {
+		sslSnaccDebug("RSAPrivateKeyDecode: bad snaccPrivKeyInfo.privateKey");
+		return CSSMERR_CSP_INVALID_KEY;
+	}
+	
+	/* convert snaccPrivKey fields to RSA key fields */
+	try {
+		openKey->version = snaccPrivKey.version;
+		openKey->n	  = bigIntStrToBn(snaccPrivKey.modulus);
+		openKey->e	  = bigIntStrToBn(snaccPrivKey.publicExponent);
+		openKey->d 	  = bigIntStrToBn(snaccPrivKey.privateExponent);
+		openKey->p 	  = bigIntStrToBn(snaccPrivKey.prime1);
+		openKey->q 	  = bigIntStrToBn(snaccPrivKey.prime2);
+		openKey->dmp1 = bigIntStrToBn(snaccPrivKey.exponent1);
+		openKey->dmq1 = bigIntStrToBn(snaccPrivKey.exponent2);
+		openKey->iqmp = bigIntStrToBn(snaccPrivKey.coefficient);
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	return 0;
+}
+
+CSSM_RETURN	RSAPrivateKeyEncode(
+	RSA 			*openKey, 
+	CssmOwnedData	&encodedKey)
+{
+	/* First convert into a snacc-style private key */
+	RSAPrivateKey snaccPrivKey;
+	
+	try {
+		snaccPrivKey.version = openKey->version;
+		bnToBigIntStr(openKey->n, 	 snaccPrivKey.modulus);
+		bnToBigIntStr(openKey->e, 	 snaccPrivKey.publicExponent);
+		bnToBigIntStr(openKey->d, 	 snaccPrivKey.privateExponent);
+		bnToBigIntStr(openKey->p, 	 snaccPrivKey.prime1);
+		bnToBigIntStr(openKey->q, 	 snaccPrivKey.prime2);
+		bnToBigIntStr(openKey->dmp1, snaccPrivKey.exponent1);
+		bnToBigIntStr(openKey->dmq1, snaccPrivKey.exponent2);
+		bnToBigIntStr(openKey->iqmp, snaccPrivKey.coefficient);
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	
+	/* conservative guess for max size of encoded key */
+	unsigned maxSize = sizeofBigInt(snaccPrivKey.modulus) +
+					   sizeofBigInt(snaccPrivKey.publicExponent) +
+					   sizeofBigInt(snaccPrivKey.privateExponent) +
+					   sizeofBigInt(snaccPrivKey.prime1) +
+					   sizeofBigInt(snaccPrivKey.prime2) +
+					   sizeofBigInt(snaccPrivKey.exponent1) +
+					   sizeofBigInt(snaccPrivKey.exponent2) +
+					   sizeofBigInt(snaccPrivKey.coefficient) +
+					   64;		// includes the to-be-generated algId
+					   
+	/* DER encode */
+	try {
+		SC_encodeAsnObj(snaccPrivKey, encodedKey, maxSize);
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	
+	/* that encoding is the privateKey field of a PrivateKeyInfo */
+	PrivateKeyInfo snaccPrivKeyInfo;
+	snaccPrivKeyInfo.version = 0;		/* I think.... */
+	snaccPrivKeyInfo.privateKeyAlgorithm = new AlgorithmIdentifier;
+	snaccPrivKeyInfo.privateKeyAlgorithm->algorithm = rsaEncryption;
+	nullAlgParams(*snaccPrivKeyInfo.privateKeyAlgorithm);
+	snaccPrivKeyInfo.privateKey.Set((char *)encodedKey.data(), encodedKey.length());
+	
+	/* now encode the privateKeyInfo */
+	encodedKey.reset();
+	try {
+		SC_encodeAsnObj(snaccPrivKeyInfo, encodedKey, maxSize);
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	return 0;
+}
+
+/*
+ * Given a message digest and associated algorithm, cook up a PKCS1-style
+ * DigestInfo and return its DER encoding. This is a necessary step for 
+ * RSA signature (both generating and verifying) - the output of this 
+ * routine is what gets encrypted during signing, and what is expected when
+ * verifying (i.e., decrypting the signature).
+ *
+ * A good guess for the length of the output digestInfo is the size of the
+ * key being used to sign/verify. The digest can never be larger than that. 
+ */
+CSSM_RETURN generateDigestInfo(
+	const void		*msgDigest,
+	size_t			digestLen,
+	CSSM_ALGORITHMS	digestAlg,		// CSSM_ALGID_SHA1, etc.
+	CssmOwnedData	&encodedInfo,
+	size_t			maxEncodedSize)
+{
+	if(digestAlg == CSSM_ALGID_NONE) {
+		/* special case, no encode, just copy */
+		encodedInfo.copy(msgDigest, digestLen);
+		return 0;
+	}
+	
+	DigestInfo	info;
+	info.digest.Set((char *)msgDigest, digestLen);
+	info.digestAlgorithm = new DigestAlgorithmIdentifier;
+	
+	switch(digestAlg) {
+		case CSSM_ALGID_MD5:
+			info.digestAlgorithm->algorithm = md5;
+			break;
+		case CSSM_ALGID_MD2:
+			info.digestAlgorithm->algorithm = md2;
+			break;
+		case CSSM_ALGID_SHA1:
+			info.digestAlgorithm->algorithm = sha_1;
+			break;
+		default:
+			return CSSMERR_CSP_INVALID_ALGORITHM;
+	}
+	nullAlgParams(*info.digestAlgorithm);
+	try {
+		SC_encodeAsnObj(info, encodedInfo, maxEncodedSize);
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	return 0;
+}
+
+unsigned sizeofAsnBits(
+	AsnBits &bits)
+{
+	return (bits.BitLen() * 8) + 4;
+}
+
+unsigned sizeofAsnOcts(
+	AsnOcts &octs)
+{
+	return octs.Len() + 4;
+}
+
+
+/***
+ *** DSA
+ ***/
+
+/* SNACC DSAAlgorithmId <--> DSA->{p,g,q} */
+static DSAAlgorithmId *dsaToSnaccAlgId(
+	const DSA *openKey)
+{
+	try {
+		DSAAlgorithmId *algId = new DSAAlgorithmId;
+		
+		algId->algorithm = dsa_bsafe;
+		algId->params = new DSABsafeParams;
+		algId->params->keySizeInBits = BN_num_bits(openKey->p);
+		bnToBigIntStr(openKey->p, algId->params->p);
+		bnToBigIntStr(openKey->q, algId->params->q);
+		bnToBigIntStr(openKey->g, algId->params->g);
+		return algId;
+	}
+	catch(...) {
+		return NULL;
+	}
+}
+
+static CSSM_RETURN snaccAlgIdToDsa(
+	DSAAlgorithmId &algId,
+	DSA *openKey)
+{
+	if(algId.algorithm != dsa_bsafe) {
+		sslSnaccDebug("snaccAlgIdToDsa: bad algorithm");
+		return CSSMERR_CSP_ALGID_MISMATCH;
+	}
+	if(algId.params == NULL) {
+		sslSnaccDebug("snaccAlgIdToDsa: bad params");
+		return CSSMERR_CSP_INVALID_KEY;
+	}
+	openKey->p = bigIntStrToBn(algId.params->p);
+	openKey->q = bigIntStrToBn(algId.params->q);
+	openKey->g = bigIntStrToBn(algId.params->g);
+	return 0;
+}
+
+static unsigned sizeOfDsaAlg(
+	const DSAAlgorithmId &algId)
+{
+	return sizeofBigInt(algId.params->p) + 
+		   sizeofBigInt(algId.params->g) +
+		   sizeofBigInt(algId.params->q) +
+		   30;
+}
+
+CSSM_RETURN DSAPublicKeyDecode(
+	DSA 			*openKey, 
+	unsigned char 	*p, 
+	unsigned		length)
+{
+	DSAPublicKey snaccPubKey;
+	CSSM_RETURN rtn;
+	
+	CssmData cData(p, length);
+	try {
+		SC_decodeAsnObj(cData, snaccPubKey);
+		rtn = snaccAlgIdToDsa(*snaccPubKey.dsaAlg, openKey);
+		if(rtn) {
+			return rtn;
+		}
+		
+		/* inside of snaccPubKey.publicKey is the DER-encoding of a BigIntegerStr */
+		char *keyOcts = (char *)snaccPubKey.publicKey.BitOcts();
+		CssmData kData(keyOcts, (snaccPubKey.publicKey.BitLen() + 7) / 8);
+		BigIntegerStr pubKeyOcts;
+		SC_decodeAsnObj(kData, pubKeyOcts);
+		openKey->pub_key = bigIntStrToBn(pubKeyOcts);
+
+		if(openKey->pub_key == NULL) {
+			return CSSMERR_CSP_INVALID_KEY;
+		}
+		return 0;
+	}
+	catch(...) {
+		return CSSMERR_CSP_INVALID_KEY;
+	}
+}
+
+CSSM_RETURN	DSAPublicKeyEncode(
+	DSA 			*openKey, 
+	CssmOwnedData	&encodedKey)
+{
+	try {
+		/* First convert into a snacc-style public key */
+		DSAPublicKey snaccPubKey;
+
+		snaccPubKey.dsaAlg = dsaToSnaccAlgId(openKey);
+		if(snaccPubKey.dsaAlg == NULL) {
+			return CSSMERR_CSP_MEMORY_ERROR;
+		}
+		
+		/* 
+		 * publicKey is the DER-encoding of a BigIntegerStr wrapped in 
+		 * an AsnBits
+		 */
+		BigIntegerStr pubKeyInt;
+		bnToBigIntStr(openKey->pub_key, pubKeyInt);
+		unsigned maxSize = sizeofBigInt(pubKeyInt);
+		SC_encodeAsnObj(pubKeyInt, encodedKey, maxSize);
+
+		/* that encoding goes into DSAPublicKey.publicKey */
+		snaccPubKey.publicKey.Set((char *)encodedKey.data(), encodedKey.length() * 8);
+		
+		/* conservative guess for max size of encoded key */
+		maxSize = sizeOfDsaAlg(*snaccPubKey.dsaAlg) +
+				  sizeofAsnBits(snaccPubKey.publicKey) +
+				  20;
+					   
+		/* DER encode */
+		encodedKey.reset();
+		SC_encodeAsnObj(snaccPubKey, encodedKey, maxSize);
+		return 0;
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+}
+
+CSSM_RETURN DSAPrivateKeyDecode(
+	DSA 			*openKey, 
+	unsigned char 	*p, 
+	unsigned		length)
+{
+	DSAPrivateKey snaccPrivKey;
+	int rtn;
+	
+	CssmData cData(p, length);
+	try {
+		SC_decodeAsnObj(cData, snaccPrivKey);
+		openKey->version = snaccPrivKey.version;
+		
+		rtn = snaccAlgIdToDsa(*snaccPrivKey.dsaAlg, openKey);
+		if(rtn) {
+			return rtn;
+		}
+		
+		/* snaccPrivKey.privateKey is the DER-encoding of a DSAPrivateKeyOcts... */
+		char *keyOcts = snaccPrivKey.privateKey;
+		CssmData kData(keyOcts, snaccPrivKey.privateKey.Len());
+		DSAPrivateKeyOcts privKeyOcts;
+		SC_decodeAsnObj(kData, privKeyOcts);
+		
+		openKey->priv_key = bigIntStrToBn(privKeyOcts.privateKey);
+		if(openKey->priv_key == NULL) {
+			return CSSMERR_CSP_INVALID_KEY;
+		}
+		return 0;
+	}
+	catch(...) {
+		return CSSMERR_CSP_INVALID_KEY;
+	}
+}
+
+CSSM_RETURN	DSAPrivateKeyEncode(
+	DSA 			*openKey, 
+	CssmOwnedData	&encodedKey)
+{
+	try {
+		/* First convert into a snacc-style private key */
+		DSAPrivateKey snaccPrivKey;
+
+		snaccPrivKey.version = openKey->version;
+		snaccPrivKey.dsaAlg = dsaToSnaccAlgId(openKey);
+		if(snaccPrivKey.dsaAlg == NULL) {
+			return CSSMERR_CSP_MEMORY_ERROR;
+		}
+		
+		/* DSAPrivateKey.privateKey is the DER-encoding of one of these... */
+		DSAPrivateKeyOcts privKeyOcts;
+		bnToBigIntStr(openKey->priv_key, privKeyOcts.privateKey);
+
+		/* conservative guess for max size of encoded privKey bits */
+		unsigned maxSize = sizeofBigInt(privKeyOcts.privateKey) +
+					   10;		// includes the to-be-generated algId
+					   
+		/* DER encode */
+		SC_encodeAsnObj(privKeyOcts, encodedKey, maxSize);
+
+		/* that encoding goes into DSAPrivateKey.privateKey */
+		snaccPrivKey.privateKey.Set((char *)encodedKey.data(), encodedKey.length());
+		
+		/* conservative guess for max size of the whole thing */
+		maxSize = maxSize + 				// what we just did
+				sizeOfDsaAlg(*snaccPrivKey.dsaAlg) +
+				40;
+					   
+		/* DER encode */
+		encodedKey.reset();
+		SC_encodeAsnObj(snaccPrivKey, encodedKey, maxSize);
+		return 0;
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+}
+
+CSSM_RETURN DSASigEncode(
+	DSA_SIG			*openSig,
+	CssmOwnedData	&encodedSig)
+{
+	/* First convert into a snacc-style sig */
+	DSASignature	snaccSig;
+	
+	try {
+		bnToBigIntStr(openSig->r, snaccSig.r);
+		bnToBigIntStr(openSig->s, snaccSig.s);
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	
+	/* conservative guess for max size of encoded key */
+	unsigned maxSize = sizeofBigInt(snaccSig.r) +
+					   sizeofBigInt(snaccSig.s) +
+					   10;
+					   
+	/* DER encode */
+	try {
+		SC_encodeAsnObj(snaccSig, encodedSig, maxSize);
+	}
+	catch(...) {
+		/* ? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	return 0;
+}
+
+CSSM_RETURN DSASigDecode(
+	DSA_SIG 		*openSig, 
+	const void 		*p, 
+	unsigned		length)
+{
+	DSASignature snaccSig;
+	
+	CssmData cData((char *)p, length);
+	try {
+		SC_decodeAsnObj(cData, snaccSig);
+	}
+	catch(...) {
+		return CSSMERR_CSP_INVALID_SIGNATURE;
+	}
+	try {
+		openSig->r = bigIntStrToBn(snaccSig.r);
+		openSig->s = bigIntStrToBn(snaccSig.s);
+	}
+	catch(...) {
+		/* FIXME - bad sig? memory? */
+		return CSSMERR_CSP_MEMORY_ERROR;
+	}
+	return 0;
+}
diff --git a/AppleCSP/open_ssl/opensslUtils/openRsaSnacc.h b/AppleCSP/open_ssl/opensslUtils/openRsaSnacc.h
new file mode 100644
index 00000000..7a89e74c
--- /dev/null
+++ b/AppleCSP/open_ssl/opensslUtils/openRsaSnacc.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * openRsaSnacc.h - glue between openrsa and SNACC
+ */
+ 
+#ifndef	_OPEN_RSA_SNACC_H_
+#define _OPEN_RSA_SNACC_H_
+
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <Security/cssmtype.h>
+#include <Security/cssmdata.h>
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Convert between SNACC-style BigIntegerStr and openssl-style BIGNUM.
+ */
+BIGNUM *bigIntStrToBn(
+	BigIntegerStr 	&snaccInt);
+void bnToBigIntStr(
+	BIGNUM 			*bn,
+	BigIntegerStr 	&snaccInt);
+	
+
+/* estimate size of encoded BigIntegerStr */
+unsigned sizeofBigInt(
+	BigIntegerStr 	&bigInt);
+
+/*
+ * Replacements for d2i_RSAPublicKey, etc. 
+ */
+CSSM_RETURN RSAPublicKeyDecode(
+	RSA 			*openKey, 
+	void 			*p, 
+	size_t			length);
+CSSM_RETURN	RSAPublicKeyEncode(
+	RSA 			*openKey, 
+	CssmOwnedData	&encodedKey);
+CSSM_RETURN RSAPrivateKeyDecode(
+	RSA 			*openKey, 
+	void 			*p, 
+	size_t	 		length);
+CSSM_RETURN	RSAPrivateKeyEncode(
+	RSA 			*openKey, 
+	CssmOwnedData	&encodedKey);
+
+CSSM_RETURN generateDigestInfo(
+	const void		*messageDigest,
+	size_t			digestLen,
+	CSSM_ALGORITHMS	digestAlg,		// CSSM_ALGID_SHA1, etc.
+	CssmOwnedData	&encodedInfo,
+	size_t			maxEncodedSize);
+
+CSSM_RETURN DSAPublicKeyDecode(
+	DSA 			*openKey, 
+	unsigned char 	*p, 
+	unsigned		length);
+CSSM_RETURN	DSAPublicKeyEncode(
+	DSA 			*openKey, 
+	CssmOwnedData	&encodedKey);
+CSSM_RETURN DSAPrivateKeyDecode(
+	DSA 			*openKey, 
+	unsigned char 	*p, 
+	unsigned 		length);
+CSSM_RETURN	DSAPrivateKeyEncode(
+	DSA 			*openKey, 
+	CssmOwnedData	&encodedKey);
+
+CSSM_RETURN DSASigEncode(
+	DSA_SIG			*openSig,
+	CssmOwnedData	&encodedSig);
+CSSM_RETURN DSASigDecode(
+	DSA_SIG 		*openSig, 
+	const void 		*p, 
+	unsigned		length);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _OPEN_RSA_SNACC_H_ */
diff --git a/AppleCSP/open_ssl/opensslUtils/opensslUtils.cpp b/AppleCSP/open_ssl/opensslUtils/opensslUtils.cpp
new file mode 100644
index 00000000..3a55eebe
--- /dev/null
+++ b/AppleCSP/open_ssl/opensslUtils/opensslUtils.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * opensslUtils.h - Support for ssleay-derived crypto modules
+ */
+ 
+#include <openssl/rand.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <Security/debugging.h>
+#include <Security/cssmerr.h>
+#include "opensslUtils.h"
+#include <AppleCSP/YarrowConnection.h>
+#include <AppleCSP/AppleCSPUtils.h>
+#include <Security/logging.h>
+
+#define sslUtilsDebug(args...)	debug("sslUtils", ## args)
+
+openSslException::openSslException(
+	int irtn, 
+	const char *op)
+		: mIrtn(irtn)
+{ 
+	if(op) {
+		char buf[300];
+		ERR_error_string(irtn, buf);
+		sslUtilsDebug("%s: %s\n", op, buf);
+	}
+}
+
+/* these are replacements for the ones in ssleay */
+#define DUMP_RAND_BYTES	0
+
+static int randDex = 1;
+
+int  RAND_bytes(unsigned char *buf,int num)
+{
+	try {
+		cspGetRandomBytes(buf, (unsigned)num);
+	}
+	catch(...) {
+		/* that can only mean Yarrow failure, which we really need to 
+		 * cut some slack for */
+		Security::Syslog::error("Apple CSP: yarrow failure");
+		for(int i=0; i<num; i++) {
+			buf[i] = (i*3) + randDex++;
+		}
+	}
+	return 1;
+}
+
+int  RAND_pseudo_bytes(unsigned char *buf,int num)
+{
+	return RAND_bytes(buf, num);
+}
+
+void RAND_add(const void *buf,int num,double entropy)
+{
+	try {
+		cspAddEntropy(buf, (unsigned)num);
+	}
+	catch(...) {
+	}
+}
+
+/* replacement for mem_dbg.c */
+int CRYPTO_mem_ctrl(int mode)
+{
+	return 0;
+}
+
+/*
+ * Log error info. Returns the error code we pop off the error queue.
+ */
+unsigned long logSslErrInfo(const char *op)
+{
+	unsigned long e = ERR_get_error();
+	char outbuf[1024];
+	ERR_error_string(e, outbuf);
+	if(op) {
+		Security::Syslog::error("Apple CSP %s: %s", op, outbuf);
+	}
+	else {
+		Security::Syslog::error("Apple CSP %s", outbuf);
+	}
+	return e;
+}
+
+/*
+ * Replacement for same function in openssl's sha.c, which we don't link against. 
+ * The only place this is used is in DSA_generate_parameters().
+ */
+unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md)
+{
+	if(md == NULL) {
+		sslUtilsDebug("SHA1 with NULL md");
+		CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
+	}
+	cspGenSha1Hash(d, n, md);
+	return md;
+}
+
diff --git a/AppleCSP/open_ssl/opensslUtils/opensslUtils.h b/AppleCSP/open_ssl/opensslUtils/opensslUtils.h
new file mode 100644
index 00000000..88c2c31e
--- /dev/null
+++ b/AppleCSP/open_ssl/opensslUtils/opensslUtils.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * appleUtils.h - Support for ssleay-derived crypto modules
+ */
+ 
+#ifndef	_OPENSSL_UTILS_H_
+#define _OPENSSL_UTILS_H_
+
+#include <openssl/err.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Trivial exception class associated with an openssl error.
+ */
+class openSslException
+{
+public:
+	openSslException(
+		int irtn,
+		const char *op = NULL); 	
+	~openSslException() 				{ }
+	int irtn()	{ return mIrtn; }
+private:
+	int mIrtn;
+};
+
+unsigned long logSslErrInfo(const char *op);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _OPENSSL_UTILS_H_ */
diff --git a/AppleCSP/open_ssl/rsa/rsa_chk.c b/AppleCSP/open_ssl/rsa/rsa_chk.c
new file mode 100644
index 00000000..a68408ba
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_chk.c
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_chk.c  -*- Mode: C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+
+
+int RSA_check_key(RSA *key)
+	{
+	BIGNUM *i, *j, *k, *l, *m;
+	BN_CTX *ctx;
+	int r;
+	int ret=1;
+	
+	i = BN_new();
+	j = BN_new();
+	k = BN_new();
+	l = BN_new();
+	m = BN_new();
+	ctx = BN_CTX_new();
+	if (i == NULL || j == NULL || k == NULL || l == NULL ||
+		m == NULL || ctx == NULL)
+		{
+		ret = -1;
+		RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	
+	/* p prime? */
+	r = BN_is_prime(key->p, BN_prime_checks, NULL, NULL, NULL);
+	if (r != 1)
+		{
+		ret = r;
+		if (r != 0)
+			goto err;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
+		}
+	
+	/* q prime? */
+	r = BN_is_prime(key->q, BN_prime_checks, NULL, NULL, NULL);
+	if (r != 1)
+		{
+		ret = r;
+		if (r != 0)
+			goto err;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
+		}
+	
+	/* n = p*q? */
+	r = BN_mul(i, key->p, key->q, ctx);
+	if (!r) { ret = -1; goto err; }
+	
+	if (BN_cmp(i, key->n) != 0)
+		{
+		ret = 0;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
+		}
+	
+	/* d*e = 1  mod lcm(p-1,q-1)? */
+
+	r = BN_sub(i, key->p, BN_value_one());
+	if (!r) { ret = -1; goto err; }
+	r = BN_sub(j, key->q, BN_value_one());
+	if (!r) { ret = -1; goto err; }
+
+	/* now compute k = lcm(i,j) */
+	r = BN_mul(l, i, j, ctx);
+	if (!r) { ret = -1; goto err; }
+	r = BN_gcd(m, i, j, ctx);
+	if (!r) { ret = -1; goto err; }
+	r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
+	if (!r) { ret = -1; goto err; }
+
+	r = BN_mod_mul(i, key->d, key->e, k, ctx);
+	if (!r) { ret = -1; goto err; }
+
+	if (!BN_is_one(i))
+		{
+		ret = 0;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
+		}
+	
+	if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL)
+		{
+		/* dmp1 = d mod (p-1)? */
+		r = BN_sub(i, key->p, BN_value_one());
+		if (!r) { ret = -1; goto err; }
+
+		r = BN_mod(j, key->d, i, ctx);
+		if (!r) { ret = -1; goto err; }
+
+		if (BN_cmp(j, key->dmp1) != 0)
+			{
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+				RSA_R_DMP1_NOT_CONGRUENT_TO_D);
+			}
+	
+		/* dmq1 = d mod (q-1)? */    
+		r = BN_sub(i, key->q, BN_value_one());
+		if (!r) { ret = -1; goto err; }
+	
+		r = BN_mod(j, key->d, i, ctx);
+		if (!r) { ret = -1; goto err; }
+
+		if (BN_cmp(j, key->dmq1) != 0)
+			{
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+				RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
+			}
+	
+		/* iqmp = q^-1 mod p? */
+		if(!BN_mod_inverse(i, key->q, key->p, ctx))
+			{
+			ret = -1;
+			goto err;
+			}
+
+		if (BN_cmp(i, key->iqmp) != 0)
+			{
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+				RSA_R_IQMP_NOT_INVERSE_OF_Q);
+			}
+		}
+
+ err:
+	if (i != NULL) BN_free(i);
+	if (j != NULL) BN_free(j);
+	if (k != NULL) BN_free(k);
+	if (l != NULL) BN_free(l);
+	if (m != NULL) BN_free(m);
+	if (ctx != NULL) BN_CTX_free(ctx);
+	return (ret);
+	}
diff --git a/AppleCSP/open_ssl/rsa/rsa_eay.c b/AppleCSP/open_ssl/rsa/rsa_eay.c
new file mode 100644
index 00000000..b3a47d1c
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_eay.c
@@ -0,0 +1,513 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_eay.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+#ifndef RSA_NULL
+
+static int RSA_eay_public_encrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_private_encrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_public_decrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_private_decrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_mod_exp(BIGNUM *r0, BIGNUM *i, RSA *rsa);
+static int RSA_eay_init(RSA *rsa);
+static int RSA_eay_finish(RSA *rsa);
+static const RSA_METHOD rsa_pkcs1_eay_meth={
+	"Eric Young's PKCS#1 RSA",
+	RSA_eay_public_encrypt,
+	RSA_eay_public_decrypt,
+	RSA_eay_private_encrypt,
+	RSA_eay_private_decrypt,
+	RSA_eay_mod_exp,
+	BN_mod_exp_mont,
+	RSA_eay_init,
+	RSA_eay_finish,
+	0,
+	NULL,
+	};
+
+const RSA_METHOD *RSA_PKCS1_SSLeay(void)
+	{
+	return(&rsa_pkcs1_eay_meth);
+	}
+
+static int RSA_eay_public_encrypt(int flen, unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM f,ret;
+	int i,j,k,num=0,r= -1;
+	unsigned char *buf=NULL;
+	BN_CTX *ctx=NULL;
+
+	BN_init(&f);
+	BN_init(&ret);
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+	num=BN_num_bytes(rsa->n);
+	if ((buf=(unsigned char *)Malloc(num)) == NULL)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
+		break;
+#ifndef	_OPENSSL_APPLE_CDSA_
+#ifndef NO_SHA
+	case RSA_PKCS1_OAEP_PADDING:
+	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
+		break;
+#endif
+#endif
+	case RSA_SSLV23_PADDING:
+		i=RSA_padding_add_SSLv23(buf,num,from,flen);
+		break;
+	case RSA_NO_PADDING:
+		i=RSA_padding_add_none(buf,num,from,flen);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (i <= 0) goto err;
+
+	if (BN_bin2bn(buf,num,&f) == NULL) goto err;
+	
+	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+		{
+		if ((rsa->_method_mod_n=BN_MONT_CTX_new()) != NULL)
+			if (!BN_MONT_CTX_set(rsa->_method_mod_n,rsa->n,ctx))
+			    goto err;
+		}
+
+	if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
+		rsa->_method_mod_n)) goto err;
+
+	/* put in leading 0 bytes if the number is less than the
+	 * length of the modulus */
+	j=BN_num_bytes(&ret);
+	i=BN_bn2bin(&ret,&(to[num-j]));
+	for (k=0; k<(num-i); k++)
+		to[k]=0;
+
+	r=num;
+err:
+	if (ctx != NULL) BN_CTX_free(ctx);
+	BN_clear_free(&f);
+	BN_clear_free(&ret);
+	if (buf != NULL) 
+		{
+		memset(buf,0,num);
+		Free(buf);
+		}
+	return(r);
+	}
+
+static int RSA_eay_private_encrypt(int flen, unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM f,ret;
+	int i,j,k,num=0,r= -1;
+	unsigned char *buf=NULL;
+	BN_CTX *ctx=NULL;
+
+	BN_init(&f);
+	BN_init(&ret);
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+	num=BN_num_bytes(rsa->n);
+	if ((buf=(unsigned char *)Malloc(num)) == NULL)
+		{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
+		break;
+	case RSA_NO_PADDING:
+		i=RSA_padding_add_none(buf,num,from,flen);
+		break;
+	case RSA_SSLV23_PADDING:
+	default:
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (i <= 0) goto err;
+
+	if (BN_bin2bn(buf,num,&f) == NULL) goto err;
+
+	if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL))
+		RSA_blinding_on(rsa,ctx);
+	if (rsa->flags & RSA_FLAG_BLINDING)
+		if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err;
+
+	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
+		((rsa->p != NULL) &&
+		(rsa->q != NULL) &&
+		(rsa->dmp1 != NULL) &&
+		(rsa->dmq1 != NULL) &&
+		(rsa->iqmp != NULL)) )
+		{ if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
+	else
+		{
+		if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
+		}
+
+	if (rsa->flags & RSA_FLAG_BLINDING)
+		if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err;
+
+	/* put in leading 0 bytes if the number is less than the
+	 * length of the modulus */
+	j=BN_num_bytes(&ret);
+	i=BN_bn2bin(&ret,&(to[num-j]));
+	for (k=0; k<(num-i); k++)
+		to[k]=0;
+
+	r=num;
+err:
+	if (ctx != NULL) BN_CTX_free(ctx);
+	BN_clear_free(&ret);
+	BN_clear_free(&f);
+	if (buf != NULL)
+		{
+		memset(buf,0,num);
+		Free(buf);
+		}
+	return(r);
+	}
+
+static int RSA_eay_private_decrypt(int flen, unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM f,ret;
+	int j,num=0,r= -1;
+	unsigned char *p;
+	unsigned char *buf=NULL;
+	BN_CTX *ctx=NULL;
+
+	BN_init(&f);
+	BN_init(&ret);
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+
+	num=BN_num_bytes(rsa->n);
+
+	if ((buf=(unsigned char *)Malloc(num)) == NULL)
+		{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* This check was for equality but PGP does evil things
+	 * and chops off the top '0' bytes */
+	if (flen > num)
+		{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
+		goto err;
+		}
+
+	/* make data into a big number */
+	if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err;
+
+	if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL))
+		RSA_blinding_on(rsa,ctx);
+	if (rsa->flags & RSA_FLAG_BLINDING)
+		if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err;
+
+	/* do the decrypt */
+	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
+		((rsa->p != NULL) &&
+		(rsa->q != NULL) &&
+		(rsa->dmp1 != NULL) &&
+		(rsa->dmq1 != NULL) &&
+		(rsa->iqmp != NULL)) )
+		{ if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
+	else
+		{
+		if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL))
+			goto err;
+		}
+
+	if (rsa->flags & RSA_FLAG_BLINDING)
+		if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err;
+
+	p=buf;
+	j=BN_bn2bin(&ret,p); /* j is only used with no-padding mode */
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
+		break;
+#ifndef	_OPENSSL_APPLE_CDSA_
+#ifndef NO_SHA
+        case RSA_PKCS1_OAEP_PADDING:
+	        r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
+                break;
+#endif
+#endif
+ 	case RSA_SSLV23_PADDING:
+		r=RSA_padding_check_SSLv23(to,num,buf,j,num);
+		break;
+	case RSA_NO_PADDING:
+		r=RSA_padding_check_none(to,num,buf,j,num);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (r < 0)
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
+
+err:
+	if (ctx != NULL) BN_CTX_free(ctx);
+	BN_clear_free(&f);
+	BN_clear_free(&ret);
+	if (buf != NULL)
+		{
+		memset(buf,0,num);
+		Free(buf);
+		}
+	return(r);
+	}
+
+static int RSA_eay_public_decrypt(int flen, unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM f,ret;
+	int i,num=0,r= -1;
+	unsigned char *p;
+	unsigned char *buf=NULL;
+	BN_CTX *ctx=NULL;
+
+	BN_init(&f);
+	BN_init(&ret);
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+
+	num=BN_num_bytes(rsa->n);
+	buf=(unsigned char *)Malloc(num);
+	if (buf == NULL)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* This check was for equality but PGP does evil things
+	 * and chops off the top '0' bytes */
+	if (flen > num)
+		{
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
+		goto err;
+		}
+
+	if (BN_bin2bn(from,flen,&f) == NULL) goto err;
+	/* do the decrypt */
+	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+		{
+		if ((rsa->_method_mod_n=BN_MONT_CTX_new()) != NULL)
+			if (!BN_MONT_CTX_set(rsa->_method_mod_n,rsa->n,ctx))
+			    goto err;
+		}
+
+	if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
+		rsa->_method_mod_n)) goto err;
+
+	p=buf;
+	i=BN_bn2bin(&ret,p);
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
+		break;
+	case RSA_NO_PADDING:
+		r=RSA_padding_check_none(to,num,buf,i,num);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (r < 0)
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
+
+err:
+	if (ctx != NULL) BN_CTX_free(ctx);
+	BN_clear_free(&f);
+	BN_clear_free(&ret);
+	if (buf != NULL)
+		{
+		memset(buf,0,num);
+		Free(buf);
+		}
+	return(r);
+	}
+
+static int RSA_eay_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
+	{
+	BIGNUM r1,m1;
+	int ret=0;
+	BN_CTX *ctx;
+
+	if ((ctx=BN_CTX_new()) == NULL) goto err;
+	BN_init(&m1);
+	BN_init(&r1);
+
+	if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
+		{
+		if (rsa->_method_mod_p == NULL)
+			{
+			if ((rsa->_method_mod_p=BN_MONT_CTX_new()) != NULL)
+				if (!BN_MONT_CTX_set(rsa->_method_mod_p,rsa->p,
+						     ctx))
+					goto err;
+			}
+		if (rsa->_method_mod_q == NULL)
+			{
+			if ((rsa->_method_mod_q=BN_MONT_CTX_new()) != NULL)
+				if (!BN_MONT_CTX_set(rsa->_method_mod_q,rsa->q,
+						     ctx))
+					goto err;
+			}
+		}
+
+	if (!BN_mod(&r1,I,rsa->q,ctx)) goto err;
+	if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx,
+		rsa->_method_mod_q)) goto err;
+
+	if (!BN_mod(&r1,I,rsa->p,ctx)) goto err;
+	if (!rsa->meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx,
+		rsa->_method_mod_p)) goto err;
+
+	if (!BN_sub(r0,r0,&m1)) goto err;
+	/* This will help stop the size of r0 increasing, which does
+	 * affect the multiply if it optimised for a power of 2 size */
+	if (r0->neg)
+		if (!BN_add(r0,r0,rsa->p)) goto err;
+
+	if (!BN_mul(&r1,r0,rsa->iqmp,ctx)) goto err;
+	if (!BN_mod(r0,&r1,rsa->p,ctx)) goto err;
+	/* If p < q it is occasionally possible for the correction of
+         * adding 'p' if r0 is negative above to leave the result still
+	 * negative. This can break the private key operations: the following
+	 * second correction should *always* correct this rare occurrence.
+	 * This will *never* happen with OpenSSL generated keys because
+         * they ensure p > q [steve]
+         */
+	if (r0->neg)
+		if (!BN_add(r0,r0,rsa->p)) goto err;
+	if (!BN_mul(&r1,r0,rsa->q,ctx)) goto err;
+	if (!BN_add(r0,&r1,&m1)) goto err;
+
+	ret=1;
+err:
+	BN_clear_free(&m1);
+	BN_clear_free(&r1);
+	BN_CTX_free(ctx);
+	return(ret);
+	}
+
+static int RSA_eay_init(RSA *rsa)
+	{
+	rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
+	return(1);
+	}
+
+static int RSA_eay_finish(RSA *rsa)
+	{
+	if (rsa->_method_mod_n != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_n);
+	if (rsa->_method_mod_p != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_p);
+	if (rsa->_method_mod_q != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_q);
+	return(1);
+	}
+
+#endif
diff --git a/AppleCSP/open_ssl/rsa/rsa_err.c b/AppleCSP/open_ssl/rsa/rsa_err.c
new file mode 100644
index 00000000..17db7db3
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_err.c
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef NO_ERR
+static ERR_STRING_DATA RSA_str_functs[]=
+	{
+{ERR_PACK(0,RSA_F_MEMORY_LOCK,0),	"MEMORY_LOCK"},
+{ERR_PACK(0,RSA_F_RSA_CHECK_KEY,0),	"RSA_check_key"},
+{ERR_PACK(0,RSA_F_RSA_EAY_PRIVATE_DECRYPT,0),	"RSA_EAY_PRIVATE_DECRYPT"},
+{ERR_PACK(0,RSA_F_RSA_EAY_PRIVATE_ENCRYPT,0),	"RSA_EAY_PRIVATE_ENCRYPT"},
+{ERR_PACK(0,RSA_F_RSA_EAY_PUBLIC_DECRYPT,0),	"RSA_EAY_PUBLIC_DECRYPT"},
+{ERR_PACK(0,RSA_F_RSA_EAY_PUBLIC_ENCRYPT,0),	"RSA_EAY_PUBLIC_ENCRYPT"},
+{ERR_PACK(0,RSA_F_RSA_GENERATE_KEY,0),	"RSA_generate_key"},
+{ERR_PACK(0,RSA_F_RSA_NEW_METHOD,0),	"RSA_new_method"},
+{ERR_PACK(0,RSA_F_RSA_NULL,0),	"RSA_NULL"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_NONE,0),	"RSA_padding_add_none"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,0),	"RSA_padding_add_PKCS1_OAEP"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,0),	"RSA_padding_add_PKCS1_type_1"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,0),	"RSA_padding_add_PKCS1_type_2"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_SSLV23,0),	"RSA_padding_add_SSLv23"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_NONE,0),	"RSA_padding_check_none"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP,0),	"RSA_padding_check_PKCS1_OAEP"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,0),	"RSA_padding_check_PKCS1_type_1"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,0),	"RSA_padding_check_PKCS1_type_2"},
+{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_SSLV23,0),	"RSA_padding_check_SSLv23"},
+{ERR_PACK(0,RSA_F_RSA_PRINT,0),	"RSA_print"},
+{ERR_PACK(0,RSA_F_RSA_PRINT_FP,0),	"RSA_print_fp"},
+{ERR_PACK(0,RSA_F_RSA_SIGN,0),	"RSA_sign"},
+{ERR_PACK(0,RSA_F_RSA_SIGN_ASN1_OCTET_STRING,0),	"RSA_sign_ASN1_OCTET_STRING"},
+{ERR_PACK(0,RSA_F_RSA_VERIFY,0),	"RSA_verify"},
+{ERR_PACK(0,RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,0),	"RSA_verify_ASN1_OCTET_STRING"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA RSA_str_reasons[]=
+	{
+{RSA_R_ALGORITHM_MISMATCH                ,"algorithm mismatch"},
+{RSA_R_BAD_E_VALUE                       ,"bad e value"},
+{RSA_R_BAD_FIXED_HEADER_DECRYPT          ,"bad fixed header decrypt"},
+{RSA_R_BAD_PAD_BYTE_COUNT                ,"bad pad byte count"},
+{RSA_R_BAD_SIGNATURE                     ,"bad signature"},
+{RSA_R_BLOCK_TYPE_IS_NOT_01              ,"block type is not 01"},
+{RSA_R_BLOCK_TYPE_IS_NOT_02              ,"block type is not 02"},
+{RSA_R_DATA_GREATER_THAN_MOD_LEN         ,"data greater than mod len"},
+{RSA_R_DATA_TOO_LARGE                    ,"data too large"},
+{RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE       ,"data too large for key size"},
+{RSA_R_DATA_TOO_SMALL                    ,"data too small"},
+{RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE       ,"data too small for key size"},
+{RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY        ,"digest too big for rsa key"},
+{RSA_R_DMP1_NOT_CONGRUENT_TO_D           ,"dmp1 not congruent to d"},
+{RSA_R_DMQ1_NOT_CONGRUENT_TO_D           ,"dmq1 not congruent to d"},
+{RSA_R_D_E_NOT_CONGRUENT_TO_1            ,"d e not congruent to 1"},
+{RSA_R_INVALID_MESSAGE_LENGTH            ,"invalid message length"},
+{RSA_R_IQMP_NOT_INVERSE_OF_Q             ,"iqmp not inverse of q"},
+{RSA_R_KEY_SIZE_TOO_SMALL                ,"key size too small"},
+{RSA_R_NULL_BEFORE_BLOCK_MISSING         ,"null before block missing"},
+{RSA_R_N_DOES_NOT_EQUAL_P_Q              ,"n does not equal p q"},
+{RSA_R_OAEP_DECODING_ERROR               ,"oaep decoding error"},
+{RSA_R_PADDING_CHECK_FAILED              ,"padding check failed"},
+{RSA_R_P_NOT_PRIME                       ,"p not prime"},
+{RSA_R_Q_NOT_PRIME                       ,"q not prime"},
+{RSA_R_RSA_OPERATIONS_NOT_SUPPORTED      ,"rsa operations not supported"},
+{RSA_R_SSLV3_ROLLBACK_ATTACK             ,"sslv3 rollback attack"},
+{RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD,"the asn1 object identifier is not known for this md"},
+{RSA_R_UNKNOWN_ALGORITHM_TYPE            ,"unknown algorithm type"},
+{RSA_R_UNKNOWN_PADDING_TYPE              ,"unknown padding type"},
+{RSA_R_WRONG_SIGNATURE_LENGTH            ,"wrong signature length"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_RSA_strings(void)
+	{
+	static int init=1;
+
+	if (init)
+		{
+		init=0;
+#ifndef NO_ERR
+		ERR_load_strings(ERR_LIB_RSA,RSA_str_functs);
+		ERR_load_strings(ERR_LIB_RSA,RSA_str_reasons);
+#endif
+
+		}
+	}
diff --git a/AppleCSP/open_ssl/rsa/rsa_gen.c b/AppleCSP/open_ssl/rsa/rsa_gen.c
new file mode 100644
index 00000000..0a0125d4
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_gen.c
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+RSA *RSA_generate_key(int bits, unsigned long e_value,
+	     void (*callback)(int,int,void *), void *cb_arg)
+	{
+	RSA *rsa=NULL;
+	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
+	int bitsp,bitsq,ok= -1,n=0,i;
+	BN_CTX *ctx=NULL,*ctx2=NULL;
+
+	ctx=BN_CTX_new();
+	if (ctx == NULL) goto err;
+	ctx2=BN_CTX_new();
+	if (ctx2 == NULL) goto err;
+	BN_CTX_start(ctx);
+	r0 = BN_CTX_get(ctx);
+	r1 = BN_CTX_get(ctx);
+	r2 = BN_CTX_get(ctx);
+	r3 = BN_CTX_get(ctx);
+	if (r3 == NULL) goto err;
+
+	bitsp=(bits+1)/2;
+	bitsq=bits-bitsp;
+	rsa=RSA_new();
+	if (rsa == NULL) goto err;
+
+	/* set e */ 
+	rsa->e=BN_new();
+	if (rsa->e == NULL) goto err;
+
+#if 1
+	/* The problem is when building with 8, 16, or 32 BN_ULONG,
+	 * unsigned long can be larger */
+	for (i=0; i<sizeof(unsigned long)*8; i++)
+		{
+		if (e_value & (1<<i))
+			BN_set_bit(rsa->e,i);
+		}
+#else
+	if (!BN_set_word(rsa->e,e_value)) goto err;
+#endif
+
+	/* generate p and q */
+	for (;;)
+		{
+		rsa->p=BN_generate_prime(NULL,bitsp,0,NULL,NULL,callback,cb_arg);
+		if (rsa->p == NULL) goto err;
+		if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
+		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
+		if (BN_is_one(r1)) break;
+		if (callback != NULL) callback(2,n++,cb_arg);
+		BN_free(rsa->p);
+		}
+	if (callback != NULL) callback(3,0,cb_arg);
+	for (;;)
+		{
+		rsa->q=BN_generate_prime(NULL,bitsq,0,NULL,NULL,callback,cb_arg);
+		if (rsa->q == NULL) goto err;
+		if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
+		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
+		if (BN_is_one(r1) && (BN_cmp(rsa->p,rsa->q) != 0))
+			break;
+		if (callback != NULL) callback(2,n++,cb_arg);
+		BN_free(rsa->q);
+		}
+	if (callback != NULL) callback(3,1,cb_arg);
+	if (BN_cmp(rsa->p,rsa->q) < 0)
+		{
+		tmp=rsa->p;
+		rsa->p=rsa->q;
+		rsa->q=tmp;
+		}
+
+	/* calculate n */
+	rsa->n=BN_new();
+	if (rsa->n == NULL) goto err;
+	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
+
+	/* calculate d */
+	if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;	/* p-1 */
+	if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;	/* q-1 */
+	if (!BN_mul(r0,r1,r2,ctx)) goto err;	/* (p-1)(q-1) */
+
+/* should not be needed, since gcd(p-1,e) == 1 and gcd(q-1,e) == 1 */
+/*	for (;;)
+		{
+		if (!BN_gcd(r3,r0,rsa->e,ctx)) goto err;
+		if (BN_is_one(r3)) break;
+
+		if (1)
+			{
+			if (!BN_add_word(rsa->e,2L)) goto err;
+			continue;
+			}
+		RSAerr(RSA_F_RSA_GENERATE_KEY,RSA_R_BAD_E_VALUE);
+		goto err;
+		}
+*/
+	rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2);	/* d */
+	if (rsa->d == NULL) goto err;
+
+	/* calculate d mod (p-1) */
+	rsa->dmp1=BN_new();
+	if (rsa->dmp1 == NULL) goto err;
+	if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;
+
+	/* calculate d mod (q-1) */
+	rsa->dmq1=BN_new();
+	if (rsa->dmq1 == NULL) goto err;
+	if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;
+
+	/* calculate inverse of q mod p */
+	rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
+	if (rsa->iqmp == NULL) goto err;
+
+	ok=1;
+err:
+	if (ok == -1)
+		{
+		RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN);
+		ok=0;
+		}
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	BN_CTX_free(ctx2);
+	
+	if (!ok)
+		{
+		if (rsa != NULL) RSA_free(rsa);
+		return(NULL);
+		}
+	else
+		return(rsa);
+	}
+
diff --git a/AppleCSP/open_ssl/rsa/rsa_lib.c b/AppleCSP/open_ssl/rsa/rsa_lib.c
new file mode 100644
index 00000000..45ef7f33
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_lib.c
@@ -0,0 +1,351 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT;
+
+static const RSA_METHOD *default_RSA_meth=NULL;
+static int rsa_meth_num=0;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *rsa_meth=NULL;
+
+RSA *RSA_new(void)
+	{
+	return(RSA_new_method(NULL));
+	}
+
+void RSA_set_default_method(const RSA_METHOD *meth)
+	{
+	default_RSA_meth=meth;
+	}
+
+const RSA_METHOD *RSA_get_default_method(void)
+{
+	return default_RSA_meth;
+}
+
+const RSA_METHOD *RSA_get_method(RSA *rsa)
+{
+	return rsa->meth;
+}
+
+const RSA_METHOD *RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
+{
+	const RSA_METHOD *mtmp;
+	mtmp = rsa->meth;
+	if (mtmp->finish) mtmp->finish(rsa);
+	rsa->meth = meth;
+	if (meth->init) meth->init(rsa);
+	return mtmp;
+}
+
+RSA *RSA_new_method(const RSA_METHOD *meth)
+	{
+	RSA *ret;
+
+	if (default_RSA_meth == NULL)
+		{
+#ifdef RSA_NULL
+		default_RSA_meth=RSA_null_method();
+#else
+#ifdef RSAref
+		default_RSA_meth=RSA_PKCS1_RSAref();
+#else
+		default_RSA_meth=RSA_PKCS1_SSLeay();
+#endif
+#endif
+		}
+	ret=(RSA *)Malloc(sizeof(RSA));
+	if (ret == NULL)
+		{
+		RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+
+	if (meth == NULL)
+		ret->meth=default_RSA_meth;
+	else
+		ret->meth=meth;
+
+	ret->pad=0;
+	ret->version=0;
+	ret->n=NULL;
+	ret->e=NULL;
+	ret->d=NULL;
+	ret->p=NULL;
+	ret->q=NULL;
+	ret->dmp1=NULL;
+	ret->dmq1=NULL;
+	ret->iqmp=NULL;
+	ret->references=1;
+	ret->_method_mod_n=NULL;
+	ret->_method_mod_p=NULL;
+	ret->_method_mod_q=NULL;
+	ret->blinding=NULL;
+	ret->bignum_data=NULL;
+	ret->flags=ret->meth->flags;
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+		Free(ret);
+		ret=NULL;
+		}
+	else
+		CRYPTO_new_ex_data(rsa_meth,ret,&ret->ex_data);
+	return(ret);
+	}
+
+void RSA_free(RSA *r)
+	{
+	int i;
+
+	if (r == NULL) return;
+
+	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA);
+#ifdef REF_PRINT
+	REF_PRINT("RSA",r);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"RSA_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	CRYPTO_free_ex_data(rsa_meth,r,&r->ex_data);
+
+	if (r->meth->finish != NULL)
+		r->meth->finish(r);
+
+	if (r->n != NULL) BN_clear_free(r->n);
+	if (r->e != NULL) BN_clear_free(r->e);
+	if (r->d != NULL) BN_clear_free(r->d);
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
+	if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
+	if (r->iqmp != NULL) BN_clear_free(r->iqmp);
+	if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
+	if (r->bignum_data != NULL) Free_locked(r->bignum_data);
+	Free(r);
+	}
+
+int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	rsa_meth_num++;
+	return(CRYPTO_get_ex_new_index(rsa_meth_num-1,
+		&rsa_meth,argl,argp,new_func,dup_func,free_func));
+        }
+
+int RSA_set_ex_data(RSA *r, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
+	}
+
+void *RSA_get_ex_data(RSA *r, int idx)
+	{
+	return(CRYPTO_get_ex_data(&r->ex_data,idx));
+	}
+
+int RSA_size(RSA *r)
+	{
+	return(BN_num_bytes(r->n));
+	}
+
+int RSA_public_encrypt(int flen, unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
+	}
+
+int RSA_private_encrypt(int flen, unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
+	}
+
+int RSA_private_decrypt(int flen, unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
+	}
+
+int RSA_public_decrypt(int flen, unsigned char *from, unsigned char *to,
+	     RSA *rsa, int padding)
+	{
+	return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
+	}
+
+int RSA_flags(RSA *r)
+	{
+	return((r == NULL)?0:r->meth->flags);
+	}
+
+void RSA_blinding_off(RSA *rsa)
+	{
+	if (rsa->blinding != NULL)
+		{
+		BN_BLINDING_free(rsa->blinding);
+		rsa->blinding=NULL;
+		}
+	rsa->flags&= ~RSA_FLAG_BLINDING;
+	}
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
+	{
+	BIGNUM *A,*Ai;
+	BN_CTX *ctx;
+	int ret=0;
+
+	if (p_ctx == NULL)
+		{
+		if ((ctx=BN_CTX_new()) == NULL) goto err;
+		}
+	else
+		ctx=p_ctx;
+
+	if (rsa->blinding != NULL)
+		BN_BLINDING_free(rsa->blinding);
+
+	BN_CTX_start(ctx);
+	A = BN_CTX_get(ctx);
+	if (!BN_rand(A,BN_num_bits(rsa->n)-1,1,0)) goto err;
+	if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
+
+	if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
+	    goto err;
+	rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n);
+	rsa->flags|=RSA_FLAG_BLINDING;
+	BN_free(Ai);
+	ret=1;
+err:
+	BN_CTX_end(ctx);
+	if (ctx != p_ctx) BN_CTX_free(ctx);
+	return(ret);
+	}
+
+int RSA_memory_lock(RSA *r)
+	{
+	int i,j,k,off;
+	char *p;
+	BIGNUM *bn,**t[6],*b;
+	BN_ULONG *ul;
+
+	if (r->d == NULL) return(1);
+	t[0]= &r->d;
+	t[1]= &r->p;
+	t[2]= &r->q;
+	t[3]= &r->dmp1;
+	t[4]= &r->dmq1;
+	t[5]= &r->iqmp;
+	k=sizeof(BIGNUM)*6;
+	off=k/sizeof(BN_ULONG)+1;
+	j=1;
+	for (i=0; i<6; i++)
+		j+= (*t[i])->top;
+	if ((p=Malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
+		{
+		RSAerr(RSA_F_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	bn=(BIGNUM *)p;
+	ul=(BN_ULONG *)&(p[off]);
+	for (i=0; i<6; i++)
+		{
+		b= *(t[i]);
+		*(t[i])= &(bn[i]);
+		memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
+		bn[i].flags=BN_FLG_STATIC_DATA;
+		bn[i].d=ul;
+		memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
+		ul+=b->top;
+		BN_clear_free(b);
+		}
+	
+	/* I should fix this so it can still be done */
+	r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
+
+	r->bignum_data=p;
+	return(1);
+	}
+
diff --git a/AppleCSP/open_ssl/rsa/rsa_none.c b/AppleCSP/open_ssl/rsa/rsa_none.c
new file mode 100644
index 00000000..d340c8f3
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_none.c
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_none.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_none(unsigned char *to, int tlen, unsigned char *from,
+	     int flen)
+	{
+	if (flen > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_NONE,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return(0);
+		}
+
+	if (flen < tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_NONE,RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
+		return(0);
+		}
+	
+	memcpy(to,from,(unsigned int)flen);
+	return(1);
+	}
+
+int RSA_padding_check_none(unsigned char *to, int tlen, unsigned char *from,
+	     int flen, int num)
+	{
+
+	if (flen > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_NONE,RSA_R_DATA_TOO_LARGE);
+		return(-1);
+		}
+
+	memset(to,0,tlen-flen);
+	memcpy(to+tlen-flen,from,flen);
+	return(tlen);
+	}
+
diff --git a/AppleCSP/open_ssl/rsa/rsa_null.c b/AppleCSP/open_ssl/rsa/rsa_null.c
new file mode 100644
index 00000000..f3268fa8
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_null.c
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+
+/* rsa_null.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+/* This is a dummy RSA implementation that just returns errors when called.
+ * It is designed to allow some RSA functions to work while stopping those
+ * covered by the RSA patent. That is RSA, encryption, decryption, signing
+ * and verify is not allowed but RSA key generation, key checking and other
+ * operations (like storing RSA keys) are permitted.
+ */
+
+static int RSA_null_public_encrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_null_private_encrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_null_public_decrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+static int RSA_null_private_decrypt(int flen, unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+#if 0 /* not currently used */
+static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *i, RSA *rsa);
+#endif
+static int RSA_null_init(RSA *rsa);
+static int RSA_null_finish(RSA *rsa);
+static const RSA_METHOD rsa_null_meth={
+	"Null RSA",
+	RSA_null_public_encrypt,
+	RSA_null_public_decrypt,
+	RSA_null_private_encrypt,
+	RSA_null_private_decrypt,
+	NULL, NULL,
+	RSA_null_init,
+	RSA_null_finish,
+	0,
+	NULL,
+	};
+
+const RSA_METHOD *RSA_null_method(void)
+	{
+	return(&rsa_null_meth);
+	}
+
+static int RSA_null_public_encrypt(int flen, unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+
+static int RSA_null_private_encrypt(int flen, unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+
+static int RSA_null_private_decrypt(int flen, unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+
+static int RSA_null_public_decrypt(int flen, unsigned char *from,
+	     unsigned char *to, RSA *rsa, int padding)
+	{
+	RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+
+#if 0 /* not currently used */
+static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
+	{
+	RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+	return -1;
+	}
+#endif
+
+static int RSA_null_init(RSA *rsa)
+	{
+	return(1);
+	}
+
+static int RSA_null_finish(RSA *rsa)
+	{
+	return(1);
+	}
+
+
diff --git a/AppleCSP/open_ssl/rsa/rsa_pk1.c b/AppleCSP/open_ssl/rsa/rsa_pk1.c
new file mode 100644
index 00000000..98fc3c88
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_pk1.c
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_pk1.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
+	     unsigned char *from, int flen)
+	{
+	int j;
+	unsigned char *p;
+
+	if (flen > (tlen-11))
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return(0);
+		}
+	
+	p=(unsigned char *)to;
+
+	*(p++)=0;
+	*(p++)=1; /* Private Key BT (Block Type) */
+
+	/* pad out with 0xff data */
+	j=tlen-3-flen;
+	memset(p,0xff,j);
+	p+=j;
+	*(p++)='\0';
+	memcpy(p,from,(unsigned int)flen);
+	return(1);
+	}
+
+int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+	     unsigned char *from, int flen, int num)
+	{
+	int i,j;
+	unsigned char *p;
+
+	p=from;
+	if ((num != (flen+1)) || (*(p++) != 01))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BLOCK_TYPE_IS_NOT_01);
+		return(-1);
+		}
+
+	/* scan over padding data */
+	j=flen-1; /* one for type. */
+	for (i=0; i<j; i++)
+		{
+		if (*p != 0xff) /* should decrypt to 0xff */
+			{
+			if (*p == 0)
+				{ p++; break; }
+			else	{
+				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_FIXED_HEADER_DECRYPT);
+				return(-1);
+				}
+			}
+		p++;
+		}
+
+	if (i == j)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return(-1);
+		}
+
+	if (i < 8)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_PAD_BYTE_COUNT);
+		return(-1);
+		}
+	i++; /* Skip over the '\0' */
+	j-=i;
+	if (j > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE);
+		return(-1);
+		}
+	memcpy(to,p,(unsigned int)j);
+
+	return(j);
+	}
+
+int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+	     unsigned char *from, int flen)
+	{
+	int i,j;
+	unsigned char *p;
+	
+	if (flen > (tlen-11))
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return(0);
+		}
+	
+	p=(unsigned char *)to;
+
+	*(p++)=0;
+	*(p++)=2; /* Public Key BT (Block Type) */
+
+	/* pad out with non-zero random data */
+	j=tlen-3-flen;
+
+	if (RAND_bytes(p,j) <= 0)
+		return(0);
+	for (i=0; i<j; i++)
+		{
+		if (*p == '\0')
+			do	{
+				if (RAND_bytes(p,1) <= 0)
+					return(0);
+				} while (*p == '\0');
+		p++;
+		}
+
+	*(p++)='\0';
+
+	memcpy(p,from,(unsigned int)flen);
+	return(1);
+	}
+
+int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
+	     unsigned char *from, int flen, int num)
+	{
+	int i,j;
+	unsigned char *p;
+
+	p=from;
+	if ((num != (flen+1)) || (*(p++) != 02))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BLOCK_TYPE_IS_NOT_02);
+		return(-1);
+		}
+#ifdef PKCS1_CHECK
+	return(num-11);
+#endif
+
+	/* scan over padding data */
+	j=flen-1; /* one for type. */
+	for (i=0; i<j; i++)
+		if (*(p++) == 0) break;
+
+	if (i == j)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return(-1);
+		}
+
+	if (i < 8)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BAD_PAD_BYTE_COUNT);
+		return(-1);
+		}
+	i++; /* Skip over the '\0' */
+	j-=i;
+	if (j > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE);
+		return(-1);
+		}
+	memcpy(to,p,(unsigned int)j);
+
+	return(j);
+	}
+
diff --git a/AppleCSP/open_ssl/rsa/rsa_saos.c b/AppleCSP/open_ssl/rsa/rsa_saos.c
new file mode 100644
index 00000000..82d4c617
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_saos.c
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_saos.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int RSA_sign_ASN1_OCTET_STRING(int type, unsigned char *m, unsigned int m_len,
+	     unsigned char *sigret, unsigned int *siglen, RSA *rsa)
+	{
+	ASN1_OCTET_STRING sig;
+	int i,j,ret=1;
+	unsigned char *p,*s;
+
+	sig.type=V_ASN1_OCTET_STRING;
+	sig.length=m_len;
+	sig.data=m;
+
+	i=i2d_ASN1_OCTET_STRING(&sig,NULL);
+	j=RSA_size(rsa);
+	if ((i-RSA_PKCS1_PADDING) > j)
+		{
+		RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+		return(0);
+		}
+	s=(unsigned char *)Malloc((unsigned int)j+1);
+	if (s == NULL)
+		{
+		RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	p=s;
+	i2d_ASN1_OCTET_STRING(&sig,&p);
+	i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
+	if (i <= 0)
+		ret=0;
+	else
+		*siglen=i;
+
+	memset(s,0,(unsigned int)j+1);
+	Free(s);
+	return(ret);
+	}
+
+int RSA_verify_ASN1_OCTET_STRING(int dtype, unsigned char *m,
+	     unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
+	     RSA *rsa)
+	{
+	int i,ret=0;
+	unsigned char *p,*s;
+	ASN1_OCTET_STRING *sig=NULL;
+
+	if (siglen != (unsigned int)RSA_size(rsa))
+		{
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,RSA_R_WRONG_SIGNATURE_LENGTH);
+		return(0);
+		}
+
+	s=(unsigned char *)Malloc((unsigned int)siglen);
+	if (s == NULL)
+		{
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
+
+	if (i <= 0) goto err;
+
+	p=s;
+	sig=d2i_ASN1_OCTET_STRING(NULL,&p,(long)i);
+	if (sig == NULL) goto err;
+
+	if (	((unsigned int)sig->length != m_len) ||
+		(memcmp(m,sig->data,m_len) != 0))
+		{
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,RSA_R_BAD_SIGNATURE);
+		}
+	else
+		ret=1;
+err:
+	if (sig != NULL) M_ASN1_OCTET_STRING_free(sig);
+	memset(s,0,(unsigned int)siglen);
+	Free(s);
+	return(ret);
+	}
+
diff --git a/AppleCSP/open_ssl/rsa/rsa_sign.c b/AppleCSP/open_ssl/rsa/rsa_sign.c
new file mode 100644
index 00000000..ebfd14f5
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_sign.c
@@ -0,0 +1,239 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+/* Size of an SSL signature: MD5+SHA1 */
+#define SSL_SIG_LENGTH	36
+
+int RSA_sign(int type, unsigned char *m, unsigned int m_len,
+	     unsigned char *sigret, unsigned int *siglen, RSA *rsa)
+	{
+	X509_SIG sig;
+	ASN1_TYPE parameter;
+	int i,j,ret=1;
+	unsigned char *p,*s = NULL;
+	X509_ALGOR algor;
+	ASN1_OCTET_STRING digest;
+	if(rsa->flags & RSA_FLAG_SIGN_VER)
+	      return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
+	/* Special case: SSL signature, just check the length */
+	if(type == NID_md5_sha1) {
+		if(m_len != SSL_SIG_LENGTH) {
+			RSAerr(RSA_F_RSA_SIGN,RSA_R_INVALID_MESSAGE_LENGTH);
+			return(0);
+		}
+		i = SSL_SIG_LENGTH;
+		s = m;
+	} else {
+		sig.algor= &algor;
+		sig.algor->algorithm=OBJ_nid2obj(type);
+		if (sig.algor->algorithm == NULL)
+			{
+			RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
+			return(0);
+			}
+		if (sig.algor->algorithm->length == 0)
+			{
+			RSAerr(RSA_F_RSA_SIGN,RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+			return(0);
+			}
+		parameter.type=V_ASN1_NULL;
+		parameter.value.ptr=NULL;
+		sig.algor->parameter= &parameter;
+
+		sig.digest= &digest;
+		sig.digest->data=m;
+		sig.digest->length=m_len;
+
+		i=i2d_X509_SIG(&sig,NULL);
+	}
+	j=RSA_size(rsa);
+	if ((i-RSA_PKCS1_PADDING) > j)
+		{
+		RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+		return(0);
+		}
+	if(type != NID_md5_sha1) {
+		s=(unsigned char *)Malloc((unsigned int)j+1);
+		if (s == NULL)
+			{
+			RSAerr(RSA_F_RSA_SIGN,ERR_R_MALLOC_FAILURE);
+			return(0);
+			}
+		p=s;
+		i2d_X509_SIG(&sig,&p);
+	}
+	i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
+	if (i <= 0)
+		ret=0;
+	else
+		*siglen=i;
+
+	if(type != NID_md5_sha1) {
+		memset(s,0,(unsigned int)j+1);
+		Free(s);
+	}
+	return(ret);
+	}
+
+int RSA_verify(int dtype, unsigned char *m, unsigned int m_len,
+	     unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
+	{
+	int i,ret=0,sigtype;
+	unsigned char *p,*s;
+	X509_SIG *sig=NULL;
+
+	if (siglen != (unsigned int)RSA_size(rsa))
+		{
+		RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
+		return(0);
+		}
+
+	if(rsa->flags & RSA_FLAG_SIGN_VER)
+	    return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa);
+
+	s=(unsigned char *)Malloc((unsigned int)siglen);
+	if (s == NULL)
+		{
+		RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
+			RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
+			return(0);
+	}
+	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
+
+	if (i <= 0) goto err;
+
+	/* Special case: SSL signature */
+	if(dtype == NID_md5_sha1) {
+		if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
+				RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+		else ret = 1;
+	} else {
+		p=s;
+		sig=d2i_X509_SIG(NULL,&p,(long)i);
+
+		if (sig == NULL) goto err;
+		sigtype=OBJ_obj2nid(sig->algor->algorithm);
+
+
+	#ifdef RSA_DEBUG
+		/* put a backward compatibility flag in EAY */
+		fprintf(stderr,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype),
+			OBJ_nid2ln(dtype));
+	#endif
+		if (sigtype != dtype)
+			{
+			if (((dtype == NID_md5) &&
+				(sigtype == NID_md5WithRSAEncryption)) ||
+				((dtype == NID_md2) &&
+				(sigtype == NID_md2WithRSAEncryption)))
+				{
+				/* ok, we will let it through */
+	#if !defined(NO_STDIO) && !defined(WIN16)
+				fprintf(stderr,"signature has problems, re-make with post SSLeay045\n");
+	#endif
+				}
+			else
+				{
+				RSAerr(RSA_F_RSA_VERIFY,
+						RSA_R_ALGORITHM_MISMATCH);
+				goto err;
+				}
+			}
+		if (	((unsigned int)sig->digest->length != m_len) ||
+			(memcmp(m,sig->digest->data,m_len) != 0))
+			{
+			RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+			}
+		else
+			ret=1;
+	}
+err:
+	if (sig != NULL) X509_SIG_free(sig);
+	memset(s,0,(unsigned int)siglen);
+	Free(s);
+	return(ret);
+	}
+
diff --git a/AppleCSP/open_ssl/rsa/rsa_ssl.c b/AppleCSP/open_ssl/rsa/rsa_ssl.c
new file mode 100644
index 00000000..f9a6a852
--- /dev/null
+++ b/AppleCSP/open_ssl/rsa/rsa_ssl.c
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/rsa/rsa_ssl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_SSLv23(unsigned char *to, int tlen, unsigned char *from,
+	     int flen)
+	{
+	int i,j;
+	unsigned char *p;
+	
+	if (flen > (tlen-11))
+		{
+		RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return(0);
+		}
+	
+	p=(unsigned char *)to;
+
+	*(p++)=0;
+	*(p++)=2; /* Public Key BT (Block Type) */
+
+	/* pad out with non-zero random data */
+	j=tlen-3-8-flen;
+
+	if (RAND_bytes(p,j) <= 0)
+		return(0);
+	for (i=0; i<j; i++)
+		{
+		if (*p == '\0')
+			do	{
+				if (RAND_bytes(p,1) <= 0)
+					return(0);
+				} while (*p == '\0');
+		p++;
+		}
+
+	memset(p,3,8);
+	p+=8;
+	*(p++)='\0';
+
+	memcpy(p,from,(unsigned int)flen);
+	return(1);
+	}
+
+int RSA_padding_check_SSLv23(unsigned char *to, int tlen, unsigned char *from,
+	     int flen, int num)
+	{
+	int i,j,k;
+	unsigned char *p;
+
+	p=from;
+	if (flen < 10)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_DATA_TOO_SMALL);
+		return(-1);
+		}
+	if ((num != (flen+1)) || (*(p++) != 02))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_BLOCK_TYPE_IS_NOT_02);
+		return(-1);
+		}
+
+	/* scan over padding data */
+	j=flen-1; /* one for type */
+	for (i=0; i<j; i++)
+		if (*(p++) == 0) break;
+
+	if ((i == j) || (i < 8))
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return(-1);
+		}
+	for (k= -8; k<0; k++)
+		{
+		if (p[k] !=  0x03) break;
+		}
+	if (k == 0)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_SSLV3_ROLLBACK_ATTACK);
+		return(-1);
+		}
+
+	i++; /* Skip over the '\0' */
+	j-=i;
+	if (j > tlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_DATA_TOO_LARGE);
+		return(-1);
+		}
+	memcpy(to,p,(unsigned int)j);
+
+	return(j);
+	}
+
diff --git a/AppleCSP/open_ssl/stack/stack.c b/AppleCSP/open_ssl/stack/stack.c
new file mode 100644
index 00000000..d62120c7
--- /dev/null
+++ b/AppleCSP/open_ssl/stack/stack.c
@@ -0,0 +1,329 @@
+/*
+ * 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.
+ */
+
+
+/* crypto/stack/stack.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Code for stacks
+ * Author - Eric Young v 1.0
+ * 1.2 eay 12-Mar-97 -	Modified sk_find so that it _DOES_ return the
+ *			lowest index for the searched item.
+ *
+ * 1.1 eay - Take from netdb and added to SSLeay
+ *
+ * 1.0 eay - First version 29/07/92
+ */
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/stack.h>
+
+#undef MIN_NODES
+#define MIN_NODES	4
+
+const char *STACK_version="Stack" OPENSSL_VERSION_PTEXT;
+
+#define	FP_ICC	(int (*)(const void *,const void *))
+#include <errno.h>
+
+int (*sk_set_cmp_func(STACK *sk, int (*c)()))(void)
+	{
+	int (*old)()=sk->comp;
+
+	if (sk->comp != c)
+		sk->sorted=0;
+	sk->comp=c;
+
+	return old;
+	}
+
+STACK *sk_dup(STACK *sk)
+	{
+	STACK *ret;
+	char **s;
+
+	if ((ret=sk_new(sk->comp)) == NULL) goto err;
+	s=(char **)Realloc((char *)ret->data,
+		(unsigned int)sizeof(char *)*sk->num_alloc);
+	if (s == NULL) goto err;
+	ret->data=s;
+
+	ret->num=sk->num;
+	memcpy(ret->data,sk->data,sizeof(char *)*sk->num);
+	ret->sorted=sk->sorted;
+	ret->num_alloc=sk->num_alloc;
+	ret->comp=sk->comp;
+	return(ret);
+err:
+	return(NULL);
+	}
+
+STACK *sk_new(int (*c)())
+	{
+	STACK *ret;
+	int i;
+
+	if ((ret=(STACK *)Malloc(sizeof(STACK))) == NULL)
+		goto err0;
+	if ((ret->data=(char **)Malloc(sizeof(char *)*MIN_NODES)) == NULL)
+		goto err1;
+	for (i=0; i<MIN_NODES; i++)
+		ret->data[i]=NULL;
+	ret->comp=c;
+	ret->num_alloc=MIN_NODES;
+	ret->num=0;
+	ret->sorted=0;
+	return(ret);
+err1:
+	Free(ret);
+err0:
+	return(NULL);
+	}
+
+int sk_insert(STACK *st, char *data, int loc)
+	{
+	char **s;
+
+	if(st == NULL) return 0;
+	if (st->num_alloc <= st->num+1)
+		{
+		s=(char **)Realloc((char *)st->data,
+			(unsigned int)sizeof(char *)*st->num_alloc*2);
+		if (s == NULL)
+			return(0);
+		st->data=s;
+		st->num_alloc*=2;
+		}
+	if ((loc >= (int)st->num) || (loc < 0))
+		st->data[st->num]=data;
+	else
+		{
+		int i;
+		char **f,**t;
+
+		f=(char **)st->data;
+		t=(char **)&(st->data[1]);
+		for (i=st->num; i>=loc; i--)
+			t[i]=f[i];
+			
+#ifdef undef /* no memmove on sunos :-( */
+		memmove( (char *)&(st->data[loc+1]),
+			(char *)&(st->data[loc]),
+			sizeof(char *)*(st->num-loc));
+#endif
+		st->data[loc]=data;
+		}
+	st->num++;
+	st->sorted=0;
+	return(st->num);
+	}
+
+char *sk_delete_ptr(STACK *st, char *p)
+	{
+	int i;
+
+	for (i=0; i<st->num; i++)
+		if (st->data[i] == p)
+			return(sk_delete(st,i));
+	return(NULL);
+	}
+
+char *sk_delete(STACK *st, int loc)
+	{
+	char *ret;
+	int i,j;
+
+	if ((st == NULL) || (st->num == 0) || (loc < 0)
+					 || (loc >= st->num)) return(NULL);
+
+	ret=st->data[loc];
+	if (loc != st->num-1)
+		{
+		j=st->num-1;
+		for (i=loc; i<j; i++)
+			st->data[i]=st->data[i+1];
+		/* In theory memcpy is not safe for this
+		 * memcpy( &(st->data[loc]),
+		 *	&(st->data[loc+1]),
+		 *	sizeof(char *)*(st->num-loc-1));
+		 */
+		}
+	st->num--;
+	return(ret);
+	}
+
+int sk_find(STACK *st, char *data)
+	{
+	char **r;
+	int i;
+	int (*comp_func)();
+	if(st == NULL) return -1;
+
+	if (st->comp == NULL)
+		{
+		for (i=0; i<st->num; i++)
+			if (st->data[i] == data)
+				return(i);
+		return(-1);
+		}
+	sk_sort(st);
+	if (data == NULL) return(-1);
+	comp_func=(int (*)())st->comp;
+	r=(char **)bsearch(&data,(char *)st->data,
+		st->num,sizeof(char *),FP_ICC comp_func);
+	if (r == NULL) return(-1);
+	i=(int)(r-st->data);
+	for ( ; i>0; i--)
+		if ((*st->comp)(&(st->data[i-1]),&data) < 0)
+			break;
+	return(i);
+	}
+
+int sk_push(STACK *st, char *data)
+	{
+	return(sk_insert(st,data,st->num));
+	}
+
+int sk_unshift(STACK *st, char *data)
+	{
+	return(sk_insert(st,data,0));
+	}
+
+char *sk_shift(STACK *st)
+	{
+	if (st == NULL) return(NULL);
+	if (st->num <= 0) return(NULL);
+	return(sk_delete(st,0));
+	}
+
+char *sk_pop(STACK *st)
+	{
+	if (st == NULL) return(NULL);
+	if (st->num <= 0) return(NULL);
+	return(sk_delete(st,st->num-1));
+	}
+
+void sk_zero(STACK *st)
+	{
+	if (st == NULL) return;
+	if (st->num <= 0) return;
+	memset((char *)st->data,0,sizeof(st->data)*st->num);
+	st->num=0;
+	}
+
+void sk_pop_free(STACK *st, void (*func)())
+	{
+	int i;
+
+	if (st == NULL) return;
+	for (i=0; i<st->num; i++)
+		if (st->data[i] != NULL)
+			func(st->data[i]);
+	sk_free(st);
+	}
+
+void sk_free(STACK *st)
+	{
+	if (st == NULL) return;
+	if (st->data != NULL) Free(st->data);
+	Free(st);
+	}
+
+int sk_num(STACK *st)
+{
+	if(st == NULL) return -1;
+	return st->num;
+}
+
+char *sk_value(STACK *st, int i)
+{
+	if(st == NULL) return NULL;
+	return st->data[i];
+}
+
+char *sk_set(STACK *st, int i, char *value)
+{
+	if(st == NULL) return NULL;
+	return (st->data[i] = value);
+}
+
+void sk_sort(STACK *st)
+    {
+    if (!st->sorted)
+	{
+	int (*comp_func)();
+
+	comp_func=(int (*)())st->comp;
+	qsort(st->data,st->num,sizeof(char *),FP_ICC comp_func);
+	st->sorted=1;
+	}
+    }
diff --git a/AppleCSPDL/AppleCSPDL.pbproj/.cvsignore b/AppleCSPDL/AppleCSPDL.pbproj/.cvsignore
new file mode 100644
index 00000000..0857ac37
--- /dev/null
+++ b/AppleCSPDL/AppleCSPDL.pbproj/.cvsignore
@@ -0,0 +1 @@
+*.pbxuser
diff --git a/AppleCSPDL/AppleCSPDL.pbproj/project.pbxproj b/AppleCSPDL/AppleCSPDL.pbproj/project.pbxproj
new file mode 100644
index 00000000..46ce5436
--- /dev/null
+++ b/AppleCSPDL/AppleCSPDL.pbproj/project.pbxproj
@@ -0,0 +1,481 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 32;
+	objects = {
+		01278A2FFEDB186711CD283A = {
+			isa = PBXFileReference;
+			path = SSContext.cpp;
+			refType = 4;
+		};
+		01278A30FEDB186711CD283A = {
+			isa = PBXFileReference;
+			path = SSKey.cpp;
+			refType = 4;
+		};
+		01278A31FEDB186711CD283A = {
+			fileRef = 01278A2FFEDB186711CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01278A32FEDB186711CD283A = {
+			fileRef = 01278A30FEDB186711CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01278A33FEDB4D5611CD283A = {
+			isa = PBXFileReference;
+			path = SSFactory.cpp;
+			refType = 4;
+		};
+		01278A34FEDB4D5611CD283A = {
+			isa = PBXFileReference;
+			path = SSFactory.h;
+			refType = 4;
+		};
+		01278A35FEDB4D5611CD283A = {
+			fileRef = 01278A34FEDB4D5611CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01278A36FEDB4D5611CD283A = {
+			fileRef = 01278A33FEDB4D5611CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01278A37FEDB676A11CD283A = {
+			isa = PBXFileReference;
+			path = SSCSPSession.cpp;
+			refType = 4;
+		};
+		01278A38FEDB676A11CD283A = {
+			isa = PBXFileReference;
+			path = SSCSPSession.h;
+			refType = 4;
+		};
+		01278A39FEDB676A11CD283A = {
+			fileRef = 01278A38FEDB676A11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01278A3AFEDB676A11CD283A = {
+			fileRef = 01278A37FEDB676A11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		023E3602001F8E8611CD283A = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OTHER_LDFLAGS = "\U0001-dylib_file \"$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Security:$(SYMROOT)/Security.framework/Versions/A/Security\"";
+			};
+			isa = PBXBuildStyle;
+			name = "Build Folder";
+		};
+		049EAD58FEF6E7E511CD283A = {
+			isa = PBXFileReference;
+			path = SSDLSession.cpp;
+			refType = 4;
+		};
+		049EAD59FEF6E7E511CD283A = {
+			isa = PBXFileReference;
+			path = SSDLSession.h;
+			refType = 4;
+		};
+		049EAD5AFEF6E7E511CD283A = {
+			fileRef = 049EAD59FEF6E7E511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		049EAD5BFEF6E7E511CD283A = {
+			fileRef = 049EAD58FEF6E7E511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		050E4183FEFED76611CD283A = {
+			isa = PBXFileReference;
+			path = SSDatabase.cpp;
+			refType = 4;
+		};
+		050E4184FEFED76611CD283A = {
+			isa = PBXFileReference;
+			path = SSDatabase.h;
+			refType = 4;
+		};
+		050E4185FEFED76611CD283A = {
+			fileRef = 050E4184FEFED76611CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		050E4186FEFED76611CD283A = {
+			fileRef = 050E4183FEFED76611CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		089C1669FE841209C02AAC07 = {
+			buildStyles = (
+				1B60AA6AFFD84BD911CD296C,
+				1B60AA6BFFD84BD911CD296C,
+				023E3602001F8E8611CD283A,
+			);
+			isa = PBXProject;
+			mainGroup = 089C166AFE841209C02AAC07;
+			projectDirPath = .;
+			targets = (
+				089C1673FE841209C02AAC07,
+			);
+		};
+		089C166AFE841209C02AAC07 = {
+			children = (
+				08FB77AFFE84173DC02AAC07,
+				089C1671FE841209C02AAC07,
+				19C28FB6FE9D52B211CA2CBB,
+			);
+			isa = PBXGroup;
+			name = CFPlugInBundle;
+			refType = 4;
+		};
+		089C1671FE841209C02AAC07 = {
+			children = (
+				2AD52209FFF3DF1811CD283A,
+			);
+			isa = PBXGroup;
+			name = "External Frameworks and Libraries";
+			path = "";
+			refType = 3;
+		};
+		089C1673FE841209C02AAC07 = {
+			buildPhases = (
+				089C1674FE841209C02AAC07,
+				089C1675FE841209C02AAC07,
+				089C1676FE841209C02AAC07,
+				089C1677FE841209C02AAC07,
+				089C1679FE841209C02AAC07,
+			);
+			buildSettings = {
+				DEPLOYMENT_OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				EXPORTED_SYMBOLS_FILE = cssmplugin.exp;
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-bundle -undefined error -lstdc++";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleCSPDL;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = bundle;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXBundleTarget;
+			name = AppleCSPDL;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Security";
+			productName = AppleCSPDL;
+			productReference = 1B60AA69FFD84BD911CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleExecutable</key>
+	<string>AppleCSPDL</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.applecspdl</string>
+	<key>CFBundleName</key>
+	<string>AppleCSPDL</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>AppleCSPDL 1.0</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		089C1674FE841209C02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				11996865FF0456D211CD283A,
+				17C156A2FEA7954611CD283A,
+				634531E5FF09563011CD283A,
+				71F5C646FED611A911CD283A,
+				09C51A18FEF19D5311CD283A,
+				01278A39FEDB676A11CD283A,
+				050E4185FEFED76611CD283A,
+				049EAD5AFEF6E7E511CD283A,
+				01278A35FEDB4D5611CD283A,
+				71F5C648FED61A6411CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		089C1675FE841209C02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		089C1676FE841209C02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				11996866FF0456D211CD283A,
+				17C156A5FEA7954611CD283A,
+				634531E6FF09563011CD283A,
+				01278A31FEDB186711CD283A,
+				09C51A19FEF19D5311CD283A,
+				01278A3AFEDB676A11CD283A,
+				050E4186FEFED76611CD283A,
+				049EAD5BFEF6E7E511CD283A,
+				01278A36FEDB4D5611CD283A,
+				01278A32FEDB186711CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		089C1677FE841209C02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				2AD5220AFFF3DF1811CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		089C1679FE841209C02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		08FB77AFFE84173DC02AAC07 = {
+			children = (
+				17C1569CFEA7954611CD283A,
+				17C1569DFEA7954611CD283A,
+				17C1569EFEA7954611CD283A,
+				17C1569FFEA7954611CD283A,
+				634531E3FF09563011CD283A,
+				634531E4FF09563011CD283A,
+				01278A2FFEDB186711CD283A,
+				71F5C645FED611A911CD283A,
+				61D315C0FEF05D5211CD283A,
+				61D315C1FEF05D5211CD283A,
+				01278A37FEDB676A11CD283A,
+				01278A38FEDB676A11CD283A,
+				050E4183FEFED76611CD283A,
+				050E4184FEFED76611CD283A,
+				049EAD58FEF6E7E511CD283A,
+				049EAD59FEF6E7E511CD283A,
+				01278A33FEDB4D5611CD283A,
+				01278A34FEDB4D5611CD283A,
+				01278A30FEDB186711CD283A,
+				71F5C647FED61A6411CD283A,
+				1DF71D5EFF310FB211CD283A,
+			);
+			isa = PBXGroup;
+			name = Source;
+			refType = 4;
+		};
+		09C51A18FEF19D5311CD283A = {
+			fileRef = 61D315C1FEF05D5211CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		09C51A19FEF19D5311CD283A = {
+			fileRef = 61D315C0FEF05D5211CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		11996865FF0456D211CD283A = {
+			fileRef = 17C1569DFEA7954611CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		11996866FF0456D211CD283A = {
+			fileRef = 17C1569CFEA7954611CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		17C1569CFEA7954611CD283A = {
+			isa = PBXFileReference;
+			path = CSPDLDatabase.cpp;
+			refType = 4;
+		};
+		17C1569DFEA7954611CD283A = {
+			isa = PBXFileReference;
+			path = CSPDLDatabase.h;
+			refType = 4;
+		};
+		17C1569EFEA7954611CD283A = {
+			isa = PBXFileReference;
+			path = CSPDLPlugin.cpp;
+			refType = 4;
+		};
+		17C1569FFEA7954611CD283A = {
+			isa = PBXFileReference;
+			path = CSPDLPlugin.h;
+			refType = 4;
+		};
+		17C156A2FEA7954611CD283A = {
+			fileRef = 17C1569FFEA7954611CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		17C156A5FEA7954611CD283A = {
+			fileRef = 17C1569EFEA7954611CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		19C28FB6FE9D52B211CA2CBB = {
+			children = (
+				1B60AA69FFD84BD911CD296C,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		1B60AA69FFD84BD911CD296C = {
+			isa = PBXBundleReference;
+			path = AppleCSPDL.bundle;
+			refType = 3;
+		};
+		1B60AA6AFFD84BD911CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		1B60AA6BFFD84BD911CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		1DF71D5EFF310FB211CD283A = {
+			isa = PBXFileReference;
+			path = cssmplugin.exp;
+			refType = 4;
+		};
+		2AD52209FFF3DF1811CD283A = {
+			isa = PBXFrameworkReference;
+			path = Security.framework;
+			refType = 3;
+		};
+		2AD5220AFFF3DF1811CD283A = {
+			fileRef = 2AD52209FFF3DF1811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		61D315C0FEF05D5211CD283A = {
+			isa = PBXFileReference;
+			path = SSCSPDLSession.cpp;
+			refType = 4;
+		};
+		61D315C1FEF05D5211CD283A = {
+			isa = PBXFileReference;
+			path = SSCSPDLSession.h;
+			refType = 4;
+		};
+		634531E3FF09563011CD283A = {
+			isa = PBXFileReference;
+			path = Schema.cpp;
+			refType = 4;
+		};
+		634531E4FF09563011CD283A = {
+			isa = PBXFileReference;
+			path = Schema.h;
+			refType = 4;
+		};
+		634531E5FF09563011CD283A = {
+			fileRef = 634531E4FF09563011CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		634531E6FF09563011CD283A = {
+			fileRef = 634531E3FF09563011CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		71F5C645FED611A911CD283A = {
+			isa = PBXFileReference;
+			path = SSContext.h;
+			refType = 4;
+		};
+		71F5C646FED611A911CD283A = {
+			fileRef = 71F5C645FED611A911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		71F5C647FED61A6411CD283A = {
+			isa = PBXFileReference;
+			path = SSKey.h;
+			refType = 4;
+		};
+		71F5C648FED61A6411CD283A = {
+			fileRef = 71F5C647FED61A6411CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+	};
+	rootObject = 089C1669FE841209C02AAC07;
+}
diff --git a/AppleCSPDL/AppleCSPDLPlugin.cpp b/AppleCSPDL/AppleCSPDLPlugin.cpp
new file mode 100644
index 00000000..0b68310f
--- /dev/null
+++ b/AppleCSPDL/AppleCSPDLPlugin.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 obtai
+n  
+ * 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.
+ */
+
+  
+// 
+// Produce the "genuine plugin version" of the Apple "file DL"
+//
+#include <CSPDLPlugin.h>
+
+
+//
+// Create the plugin object and generate the C layer hookup
+//
+ModuleNexus<CSPDLPlugin> plugin;
+
+#include <Security/pluginspi.h>
diff --git a/AppleCSPDL/CSPDLDatabase.cpp b/AppleCSPDL/CSPDLDatabase.cpp
new file mode 100644
index 00000000..d3ede0f2
--- /dev/null
+++ b/AppleCSPDL/CSPDLDatabase.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+
+//
+//  CSPDLDatabase.cpp - Description t.b.d.
+//
+#include "CSPDLDatabase.h"
+#include <Security/DatabaseSession.h>
+#include <Security/DbContext.h>
+#include <Security/cssmdb.h>
+#include <fcntl.h>
+#include <memory>
+
+//
+// CSPDLDatabaseManager implementation
+//
+Database *
+CSPDLDatabaseManager::make(const DbName &inDbName)
+{
+    CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+}
diff --git a/AppleCSPDL/CSPDLDatabase.h b/AppleCSPDL/CSPDLDatabase.h
new file mode 100644
index 00000000..000b2af5
--- /dev/null
+++ b/AppleCSPDL/CSPDLDatabase.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+
+//
+//  CSPDLDatabase.h - Description t.b.d.
+//
+#ifndef _H_CSPDLDATABASE
+#define _H_CSPDLDATABASE
+
+#include <Security/Database.h>
+#include <Security/DbContext.h>
+#include <Security/handleobject.h>
+#include <Security/refcount.h>
+#include <vector>
+
+//
+// CSPDLDatabaseManager
+//
+class CSPDLDatabaseManager : public DatabaseManager
+{
+public:
+    Database *make(const DbName &inDbName);
+};
+
+#endif //_H_CSPDLDATABASE
diff --git a/AppleCSPDL/CSPDLPlugin.cpp b/AppleCSPDL/CSPDLPlugin.cpp
new file mode 100644
index 00000000..c9e40e90
--- /dev/null
+++ b/AppleCSPDL/CSPDLPlugin.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+//
+// CSPDLPlugin.cpp - File Based CSP/DL plug-in module.
+//
+#include "CSPDLPlugin.h"
+
+#include "SSCSPSession.h"
+#include "SSDLSession.h"
+
+
+//
+// Make and break the plugin object
+//
+CSPDLPlugin::CSPDLPlugin()
+{
+}
+
+CSPDLPlugin::~CSPDLPlugin()
+{
+}
+
+
+//
+// Create a new plugin session, our way
+//
+PluginSession *
+CSPDLPlugin::makeSession(CSSM_MODULE_HANDLE handle,
+						 const CSSM_VERSION &version,
+						 uint32 subserviceId,
+						 CSSM_SERVICE_TYPE subserviceType,
+						 CSSM_ATTACH_FLAGS attachFlags,
+						 const CSSM_UPCALLS &upcalls)
+{
+    switch (subserviceType)
+	{
+        case CSSM_SERVICE_CSP:
+            return new SSCSPSession(handle,
+									*this,
+									version,
+									subserviceId,
+									subserviceType,
+									attachFlags,
+									upcalls,
+									mSSCSPDLSession);
+        case CSSM_SERVICE_DL:
+            return new SSDLSession(handle,
+								   *this,
+								   version,
+								   subserviceId,
+								   subserviceType,
+								   attachFlags,
+								   upcalls,
+								   mDatabaseManager,
+								   mSSCSPDLSession);
+        default:
+            CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
+            return 0;	// placebo
+    }
+}
diff --git a/AppleCSPDL/CSPDLPlugin.h b/AppleCSPDL/CSPDLPlugin.h
new file mode 100644
index 00000000..63280859
--- /dev/null
+++ b/AppleCSPDL/CSPDLPlugin.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+//
+// CSPDLCSPDL.h - File Based CSP/DL plug-in module.
+//
+#ifndef _H_CSPDLPLUGIN
+#define _H_CSPDLPLUGIN
+
+#include "SSCSPDLSession.h"
+#include "CSPDLDatabase.h"
+#include "SSFactory.h"
+
+#include <Security/cssmplugin.h>
+
+class SSCSPSession;
+
+class CSPDLPlugin : public CssmPlugin
+{
+	NOCOPY(CSPDLPlugin)
+public:
+    CSPDLPlugin();
+    ~CSPDLPlugin();
+
+    PluginSession *makeSession(CSSM_MODULE_HANDLE handle,
+                               const CSSM_VERSION &version,
+                               uint32 subserviceId,
+                               CSSM_SERVICE_TYPE subserviceType,
+                               CSSM_ATTACH_FLAGS attachFlags,
+                               const CSSM_UPCALLS &upcalls);
+private:
+	friend class SSCSPSession;
+	friend class SSCSPDLSession;
+	SSCSPDLSession mSSCSPDLSession;
+    CSPDLDatabaseManager mDatabaseManager;
+    SSFactory mSSFactory;
+};
+
+
+#endif //_H_CSPDLPLUGIN
diff --git a/AppleCSPDL/CVSVersionInfo.txt b/AppleCSPDL/CVSVersionInfo.txt
new file mode 100644
index 00000000..126aac7e
--- /dev/null
+++ b/AppleCSPDL/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:51 mb Exp $
+# $Name: Security-28 $
+ProjectName: AppleCSPDL
+ProjectVersion: 15
diff --git a/AppleCSPDL/KeySchema.h b/AppleCSPDL/KeySchema.h
new file mode 100644
index 00000000..a76ea150
--- /dev/null
+++ b/AppleCSPDL/KeySchema.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+
+//
+// KeySchema.h
+//
+#ifndef _H_KEYSCHEMA
+#define _H_KEYSCHEMA
+
+#include <Security/dlclient.h>
+
+namespace KeySchema
+{
+	extern const CSSM_DB_ATTRIBUTE_INFO KeyClass;
+	extern const CSSM_DB_ATTRIBUTE_INFO PrintName;
+	extern const CSSM_DB_ATTRIBUTE_INFO Alias;
+	extern const CSSM_DB_ATTRIBUTE_INFO Permanent;
+	extern const CSSM_DB_ATTRIBUTE_INFO Private;
+	extern const CSSM_DB_ATTRIBUTE_INFO Modifiable;
+	extern const CSSM_DB_ATTRIBUTE_INFO Label;
+	extern const CSSM_DB_ATTRIBUTE_INFO ApplicationTag;
+	extern const CSSM_DB_ATTRIBUTE_INFO KeyCreator;
+	extern const CSSM_DB_ATTRIBUTE_INFO KeyType;
+	extern const CSSM_DB_ATTRIBUTE_INFO KeySizeInBits;
+	extern const CSSM_DB_ATTRIBUTE_INFO EffectiveKeySize;
+	extern const CSSM_DB_ATTRIBUTE_INFO StartDate;
+	extern const CSSM_DB_ATTRIBUTE_INFO EndDate;
+	extern const CSSM_DB_ATTRIBUTE_INFO Sensitive;
+	extern const CSSM_DB_ATTRIBUTE_INFO AlwaysSensitive;
+	extern const CSSM_DB_ATTRIBUTE_INFO Extractable;
+	extern const CSSM_DB_ATTRIBUTE_INFO NeverExtractable;
+	extern const CSSM_DB_ATTRIBUTE_INFO Encrypt;
+	extern const CSSM_DB_ATTRIBUTE_INFO Decrypt;
+	extern const CSSM_DB_ATTRIBUTE_INFO Derive;
+	extern const CSSM_DB_ATTRIBUTE_INFO Sign;
+	extern const CSSM_DB_ATTRIBUTE_INFO Verify;
+	extern const CSSM_DB_ATTRIBUTE_INFO SignRecover;
+	extern const CSSM_DB_ATTRIBUTE_INFO VerifyRecover;
+	extern const CSSM_DB_ATTRIBUTE_INFO Wrap;
+	extern const CSSM_DB_ATTRIBUTE_INFO Unwrap;
+
+	extern const CSSM_DB_SCHEMA_ATTRIBUTE_INFO KeySchemaAttributeList[];
+	extern const CSSM_DB_SCHEMA_INDEX_INFO KeySchemaIndexList[];
+	extern const uint32 KeySchemaAttributeCount;
+	extern const uint32 KeySchemaIndexCount;
+};
+
+
+#endif // _H_KEYSCHEMA
diff --git a/AppleCSPDL/KeySchema.m4 b/AppleCSPDL/KeySchema.m4
new file mode 100644
index 00000000..84098e84
--- /dev/null
+++ b/AppleCSPDL/KeySchema.m4
@@ -0,0 +1,137 @@
+divert(-1)
+changecom(/*, */)
+/*
+ * 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.
+ */
+
+define(`startClass',
+`define(`indexIndex', 0)dnl
+define(`class', $1)dnl
+divert(1)dnl
+// $1 `attribute numbers
+enum
+{'
+divert(2)dnl
+// $1 attributes
+static const CSSM_DB_SCHEMA_ATTRIBUTE_INFO $1SchemaAttributeList[] =
+{
+divert(3)dnl
+// $1 indices
+static const CSSM_DB_SCHEMA_INDEX_INFO $1SchemaIndexList[] =
+{')
+
+define(`endClass',
+`divert(1)dnl
+};
+
+divert(2)dnl
+};
+
+const uint32 class()SchemaAttributeCount = sizeof(class()SchemaAttributeList) / sizeof(CSSM_DB_SCHEMA_ATTRIBUTE_INFO);
+
+divert(3)dnl
+`    // Unique (primary) index'
+undivert(5)
+`    // Secondary indices'
+undivert(6)dnl
+};
+
+const uint32 class()SchemaIndexCount = sizeof(class()SchemaIndexList) / sizeof(CSSM_DB_SCHEMA_INDEX_INFO);
+
+undivert(4)dnl
+divert(0)dnl
+undivert(1)dnl
+undivert(2)dnl
+undivert(3)dnl')
+
+define(`attributeBody',
+`{
+ifelse(index(`$1',`s'),-1,
+`    CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER,
+    {(char *)$3},',
+`    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {$4},')
+    CSSM_DB_ATTRIBUTE_FORMAT_$7
+}')
+
+define(`simpleAttribute',
+`const CSSM_DB_ATTRIBUTE_INFO $2 =
+attributeBody($*);
+')
+
+define(`attribute',
+`divert(1)dnl
+    $3,
+divert(2)dnl
+    { $3, $4, { $5, $6 }, CSSM_DB_ATTRIBUTE_FORMAT_$7 },
+divert(-1)
+ifelse(index(`$1',`S'),-1,`',
+`divert(4)dnl
+simpleAttribute($*)
+divert(-1)')dnl
+
+ifelse(index(`$1',`U'),-1,`',
+`divert(5)dnl
+    { $3, 0, CSSM_DB_INDEX_UNIQUE, CSSM_DB_INDEX_ON_ATTRIBUTE },
+divert(-1)')dnl
+ifelse(index(`$1',`I'),-1,`',
+`define(`indexIndex', incr(indexIndex))dnl
+divert(6)dnl
+    { $3, indexIndex(), CSSM_DB_INDEX_NONUNIQUE, CSSM_DB_INDEX_ON_ATTRIBUTE },
+divert(-1)')')
+
+/* Start of actual output */
+divert(0)dnl
+/*
+ * Generated by m4 from KeySchema.m4 please do not edit this file.
+ */
+
+`#include "KeySchema.h"'
+
+namespace KeySchema {
+
+divert(-1)
+startClass(Key)
+attribute(`  Ss', KeyClass, kKeyClass, "KeyClass", 0, NULL, UINT32)
+attribute(`  Ss', PrintName, kPrintName, "PrintName", 0, NULL, BLOB)
+attribute(`  Ss', Alias, kAlias, "Alias", 0, NULL, BLOB)
+attribute(`  Ss', Permanent, kPermanent, "Permanent", 0, NULL, UINT32)
+attribute(`  Ss', Private, kPrivate, "Private", 0, NULL, UINT32)
+attribute(`  Ss', Modifiable, kModifiable, "Modifiable", 0, NULL, UINT32)
+attribute(`UISs', Label, kLabel, "Label", 0, NULL, BLOB)
+attribute(`U Ss', ApplicationTag, kApplicationTag, "ApplicationTag", 0, NULL, BLOB)
+attribute(`U Ss', KeyCreator, kKeyCreator, "KeyCreator", 0, NULL, BLOB)
+attribute(`U Ss', KeyType, kKeyType, "KeyType", 0, NULL, UINT32)
+attribute(`U Ss', KeySizeInBits, kKeySizeInBits, "KeySizeInBits", 0, NULL, UINT32)
+attribute(`U Ss', EffectiveKeySize, kEffectiveKeySize, "EffectiveKeySize", 0, NULL, UINT32)
+attribute(`U Ss', StartDate, kStartDate, "StartDate", 0, NULL, BLOB)
+attribute(`U Ss', EndDate, kEndDate, "EndDate", 0, NULL, BLOB)
+attribute(`  Ss', Sensitive, kSensitive, "Sensitive", 0, NULL, UINT32)
+attribute(`  Ss', AlwaysSensitive, kAlwaysSensitive, "AlwaysSensitive", 0, NULL, UINT32)
+attribute(`  Ss', Extractable, kExtractable, "Extractable", 0, NULL, UINT32)
+attribute(`  Ss', NeverExtractable, kNeverExtractable, "NeverExtractable", 0, NULL, UINT32)
+attribute(` ISs', Encrypt, kEncrypt, "Encrypt", 0, NULL, UINT32)
+attribute(` ISs', Decrypt, kDecrypt, "Decrypt", 0, NULL, UINT32)
+attribute(` ISs', Derive, kDerive, "Derive", 0, NULL, UINT32)
+attribute(` ISs', Sign, kSign, "Sign", 0, NULL, UINT32)
+attribute(` ISs', Verify, kVerify, "Verify", 0, NULL, UINT32)
+attribute(` ISs', SignRecover, kSignRecover, "SignRecover", 0, NULL, UINT32)
+attribute(` ISs', VerifyRecover, kVerifyRecover, "VerifyRecover", 0, NULL, UINT32)
+attribute(` ISs', Wrap, kWrap, "Wrap", 0, NULL, UINT32)
+attribute(` ISs', Unwrap, kUnwrap, "Unwrap", 0, NULL, UINT32)
+endClass()
+
+} // end namespace KeySchema
diff --git a/AppleCSPDL/SSCSPDLSession.cpp b/AppleCSPDL/SSCSPDLSession.cpp
new file mode 100644
index 00000000..7a2bae58
--- /dev/null
+++ b/AppleCSPDL/SSCSPDLSession.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSCSPDLSession.cpp - Security Server CSP/DL session.
+//
+#include "SSCSPDLSession.h"
+
+#include "CSPDLPlugin.h"
+#include "SSKey.h"
+
+using namespace SecurityServer;
+
+//
+// SSCSPDLSession -- Security Server CSP session
+//
+SSCSPDLSession::SSCSPDLSession()
+// @@@ FIXME allocators needs to change.
+: mClientSession(CssmAllocator::standard(), CssmAllocator::standard())
+{
+}
+
+
+//
+// Reference Key management
+//
+void
+SSCSPDLSession::makeReferenceKey(SSCSPSession &session, KeyHandle inKeyHandle,
+								 CssmKey &outKey, SSDatabase &inSSDatabase,
+								 uint32 inKeyAttr, const CssmData *inKeyLabel)
+{
+	new SSKey(session, inKeyHandle, outKey, inSSDatabase, inKeyAttr,
+			  inKeyLabel);
+}
+
+SSKey &
+SSCSPDLSession::lookupKey(const CssmKey &inKey)
+{
+	if (inKey.blobType() == CSSM_KEYBLOB_REFERENCE)
+		return find<SSKey>(inKey);
+	else if (inKey.blobType() == CSSM_KEYBLOB_RAW)
+	{
+		// @@@ How can we deal with this?
+	}
+
+	CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+}
diff --git a/AppleCSPDL/SSCSPDLSession.h b/AppleCSPDL/SSCSPDLSession.h
new file mode 100644
index 00000000..eb4c05b5
--- /dev/null
+++ b/AppleCSPDL/SSCSPDLSession.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSCSPDLSession.h - File Based CSP/DL plug-in module.
+//
+#ifndef _H_SSCSPDLSESSION
+#define _H_SSCSPDLSESSION
+
+#include <Security/CSPsession.h>
+#include <Security/SecurityServerClient.h>
+
+
+class CSPDLPlugin;
+class SSFactory;
+class SSCSPSession;
+class SSDatabase;
+class SSKey;
+
+class SSCSPDLSession: public KeyPool
+{
+public:
+	SSCSPDLSession();
+
+	SecurityServer::ClientSession &clientSession() { return mClientSession; }
+
+	void makeReferenceKey(SSCSPSession &session,
+						  SecurityServer::KeyHandle inKeyHandle,
+						  CssmKey &outKey, SSDatabase &inSSDatabase,
+						  uint32 inKeyAttr, const CssmData *inKeyLabel);
+	SSKey &lookupKey(const CssmKey &inKey);
+
+private:
+	SecurityServer::ClientSession mClientSession;
+};
+
+
+#endif // _H_SSCSPDLSESSION
diff --git a/AppleCSPDL/SSCSPSession.cpp b/AppleCSPDL/SSCSPSession.cpp
new file mode 100644
index 00000000..5f5b7f3a
--- /dev/null
+++ b/AppleCSPDL/SSCSPSession.cpp
@@ -0,0 +1,490 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSCSPSession.cpp - Security Server CSP session.
+//
+#include "SSCSPSession.h"
+
+#include "CSPDLPlugin.h"
+#include "SSDatabase.h"
+#include "SSDLSession.h"
+#include "SSKey.h"
+
+#include <memory>
+
+using namespace std;
+using namespace SecurityServer;
+
+//
+// SSCSPSession -- Security Server CSP session
+//
+SSCSPSession::SSCSPSession(CSSM_MODULE_HANDLE handle,
+						   CSPDLPlugin &plug,
+						   const CSSM_VERSION &version,
+						   uint32 subserviceId,
+						   CSSM_SERVICE_TYPE subserviceType,
+						   CSSM_ATTACH_FLAGS attachFlags,
+						   const CSSM_UPCALLS &upcalls,
+						   SSCSPDLSession &ssCSPDLSession)
+: CSPFullPluginSession(handle, plug, version, subserviceId, subserviceType,
+					   attachFlags, upcalls),
+  mSSCSPDLSession(ssCSPDLSession),
+  mSSFactory(plug.mSSFactory)
+{
+}
+
+//
+// Called at (CSSM) context create time. This is ignored; we do a full 
+// context setup later, at setupContext time. 
+//
+CSPFullPluginSession::CSPContext *
+SSCSPSession::contextCreate(CSSM_CC_HANDLE handle, const Context &context)
+{
+	return NULL;
+}
+
+
+//
+// Called by CSPFullPluginSession when an op is actually commencing.
+// Context can safely assumed to be fully formed and stable for the
+// duration of the  op; thus we wait until now to set up our 
+// CSPContext as appropriate to the op.
+//
+void
+SSCSPSession::setupContext(CSPContext * &cspCtx,
+						   const Context &context,
+						   bool encoding)
+{
+	// note we skip this if this CSPContext is being reused
+    if (cspCtx == NULL)
+	{
+
+		if (mSSFactory.setup(*this, cspCtx, context, encoding))
+			return;
+
+#if 0
+		if (mBSafe4Factory.setup(*this, cspCtx, context))
+			return;
+
+		if (mCryptKitFactory.setup(*this, cspCtx, context))
+			return;
+#endif
+
+        CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+	}
+}
+
+
+//
+// DL interaction
+//
+SSDatabase
+SSCSPSession::getDatabase(const Context &context)
+{
+	CSSM_DL_DB_HANDLE *aDLDbHandle = context.get<CSSM_DL_DB_HANDLE>(CSSM_ATTRIBUTE_DL_DB_HANDLE);
+	if (!aDLDbHandle)
+		return SSDatabase();
+
+	return findSession<SSDLSession>(aDLDbHandle->DLHandle).findDbHandle(aDLDbHandle->DBHandle);
+}
+
+
+//
+// Reference Key management
+//
+void
+SSCSPSession::makeReferenceKey(KeyHandle inKeyHandle, CssmKey &ioKey, SSDatabase &inSSDatabase,
+							   uint32 inKeyAttr, const CssmData *inKeyLabel)
+{
+	return mSSCSPDLSession.makeReferenceKey(*this, inKeyHandle, ioKey, inSSDatabase, inKeyAttr, inKeyLabel);
+}
+
+SSKey &
+SSCSPSession::lookupKey(const CssmKey &inKey)
+{
+	return mSSCSPDLSession.lookupKey(inKey);
+}
+
+
+//
+// Key creating and handeling members
+//
+void
+SSCSPSession::WrapKey(CSSM_CC_HANDLE CCHandle,
+					  const Context &context,
+					  const AccessCredentials &AccessCred,
+					  const CssmKey &Key,
+					  const CssmData *DescriptiveData,
+					  CssmKey &WrappedKey,
+					  CSSM_PRIVILEGE Privilege)
+{
+	// @@@ Deal with permanent keys
+ 	const CssmKey *keyInContext =
+		context.get<const CssmKey>(CSSM_ATTRIBUTE_KEY);
+
+	KeyHandle contextKeyHandle = (keyInContext
+								  ? lookupKey(*keyInContext).keyHandle()
+								  : noKey);
+	clientSession().wrapKey(context, contextKeyHandle,
+							lookupKey(Key).keyHandle(), &AccessCred,
+							DescriptiveData, WrappedKey, *this);
+}
+
+void
+SSCSPSession::UnwrapKey(CSSM_CC_HANDLE CCHandle,
+						const Context &context,
+						const CssmKey *PublicKey,
+						const CssmWrappedKey &WrappedKey,
+						uint32 KeyUsage,
+						uint32 KeyAttr,
+						const CssmData *KeyLabel,
+						const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+						CssmKey &UnwrappedKey,
+						CssmData &DescriptiveData,
+						CSSM_PRIVILEGE Privilege)
+{
+	SSDatabase database = getDatabase(context);
+	const AccessCredentials *cred = NULL;
+	const AclEntryInput *owner = NULL;
+	if (CredAndAclEntry)
+	{
+		cred = AccessCredentials::overlay(CredAndAclEntry->AccessCred);
+		owner = &AclEntryInput::overlay(CredAndAclEntry->InitialAclEntry);
+	}
+
+	KeyHandle publicKey = noKey;
+	if (PublicKey)
+	{
+		if (PublicKey->blobType() == CSSM_KEYBLOB_RAW)
+		{
+			// @@@ We need to unwrap the publicKey into the SecurityServer
+			// before continuing
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+		}
+		else
+			publicKey = lookupKey(*PublicKey).keyHandle();
+	}
+
+	// @@@ Deal with permanent keys
+ 	const CssmKey *keyInContext =
+		context.get<const CssmKey>(CSSM_ATTRIBUTE_KEY);
+
+	KeyHandle contextKeyHandle =
+		keyInContext ? lookupKey(*keyInContext).keyHandle() : noKey;
+
+	KeyHandle unwrappedKeyHandle;
+	clientSession().unwrapKey(database.dbHandle(), context, contextKeyHandle,
+							  publicKey, WrappedKey, KeyUsage, KeyAttr,
+							  cred, owner, DescriptiveData, unwrappedKeyHandle,
+							  UnwrappedKey.header(), *this);	
+	makeReferenceKey(unwrappedKeyHandle, UnwrappedKey, database, KeyAttr,
+					 KeyLabel);
+}
+
+void
+SSCSPSession::DeriveKey(CSSM_CC_HANDLE ccHandle,
+						const Context &context,
+						CssmData &param,
+						uint32 keyUsage,
+						uint32 keyAttr,
+						const CssmData *keyLabel,
+						const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry,
+						CssmKey &derivedKey)
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::GenerateKey(CSSM_CC_HANDLE ccHandle,
+						  const Context &context,
+						  uint32 keyUsage,
+						  uint32 keyAttr,
+						  const CssmData *keyLabel,
+						  const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry,
+						  CssmKey &key,
+						  CSSM_PRIVILEGE privilege)
+{
+	SSDatabase database = getDatabase(context);
+	const AccessCredentials *cred = NULL;
+	const AclEntryInput *owner = NULL;
+	if (credAndAclEntry)
+	{
+		cred = AccessCredentials::overlay(credAndAclEntry->AccessCred);
+		owner = &AclEntryInput::overlay(credAndAclEntry->InitialAclEntry);
+	}
+
+	KeyHandle keyHandle;
+	clientSession().generateKey(database.dbHandle(), context, keyUsage,
+								keyAttr, cred, owner, keyHandle, key.header());
+	makeReferenceKey(keyHandle, key, database, keyAttr, keyLabel);
+}
+
+void
+SSCSPSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle,
+							  const Context &context,
+							  uint32 publicKeyUsage,
+							  uint32 publicKeyAttr,
+							  const CssmData *publicKeyLabel,
+							  CssmKey &publicKey,
+							  uint32 privateKeyUsage,
+							  uint32 privateKeyAttr,
+							  const CssmData *privateKeyLabel,
+							  const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry,
+							  CssmKey &privateKey,
+							  CSSM_PRIVILEGE privilege)
+{
+	SSDatabase database = getDatabase(context);
+	const AccessCredentials *cred = NULL;
+	const AclEntryInput *owner = NULL;
+	if (credAndAclEntry)
+	{
+		cred = AccessCredentials::overlay(credAndAclEntry->AccessCred);
+		owner = &AclEntryInput::overlay(credAndAclEntry->InitialAclEntry);
+	}
+
+	KeyHandle pubKeyHandle, privKeyHandle;
+	clientSession().generateKey(database.dbHandle(), context,
+							   publicKeyUsage, publicKeyAttr,
+							   privateKeyUsage, privateKeyAttr,
+							   cred, owner,
+							   pubKeyHandle, publicKey.header(),
+							   privKeyHandle, privateKey.header());
+	makeReferenceKey(privKeyHandle, privateKey, database, privateKeyAttr,
+					 privateKeyLabel);
+	// @@@ What if this throws, we need to free privateKey.
+	makeReferenceKey(pubKeyHandle, publicKey, database, publicKeyAttr,
+					 publicKeyLabel);
+}
+
+void
+SSCSPSession::ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
+											CssmKey &PrivateKey)
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle,
+								 const Context &Context,
+								 const CssmKey &Key,
+								 CSSM_KEY_SIZE &KeySize)
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::FreeKey(const AccessCredentials *accessCred,
+					  CssmKey &ioKey, CSSM_BOOL deleteKey)
+{
+	if (ioKey.blobType() == CSSM_KEYBLOB_REFERENCE)
+	{
+		// @@@ Note that this means that detaching a session should free
+		// all keys ascociated with it or else...
+		// -- or else what?
+		// exactly!
+
+		// @@@ There are thread safety issues when deleting a key that is
+		// in use by another thread, but the answer to that is: Don't do
+		// that!
+
+		// Find the key in the map.  Tell tell the key to free itself
+		// (when the auto_ptr deletes the key it removes itself from the map). 
+		auto_ptr<SSKey> ssKey(&mSSCSPDLSession.find<SSKey>(ioKey));
+		ssKey->free(accessCred, ioKey, deleteKey);
+	}
+	else
+	{
+		CSPFullPluginSession::FreeKey(accessCred, ioKey, deleteKey);
+	}
+}
+
+
+//
+// Generation stuff.
+//
+void
+SSCSPSession::GenerateRandom(CSSM_CC_HANDLE ccHandle,
+							 const Context &context,
+							 CssmData &randomNumber)
+{
+    checkOperation(context.type(), CSSM_ALGCLASS_RANDOMGEN);
+	// if (context.algorithm() != @@@) CssmError::throwMe(ALGORITHM_NOT_SUPPORTED);
+	uint32 needed = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE);
+
+	// @@@ What about the seed?
+    if (randomNumber.length())
+	{
+        if (randomNumber.length() < needed)
+            CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+		randomNumber.Length = needed;
+		clientSession().generateRandom(randomNumber);
+    }
+	else
+	{
+        randomNumber.Data = alloc<uint8>(needed);
+		try
+		{
+			randomNumber.Length = needed;
+			clientSession().generateRandom(randomNumber);
+		}
+		catch(...)
+		{
+			free(randomNumber.Data);
+			randomNumber.Data = NULL;
+			throw;
+		}
+	}
+}
+
+//
+// Login/Logout and token operational maintainance.  These mean little
+// without support by the actual implementation, but we can help...
+// @@@ Should this be in CSP[non-Full]PluginSession?
+//
+void
+SSCSPSession::Login(const AccessCredentials &AccessCred,
+					const CssmData *LoginName,
+					const void *Reserved)
+{
+	// @@@ Do a login to the securityServer making keys persistant until it
+	// goes away
+	unimplemented();
+}
+
+void
+SSCSPSession::Logout()
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::VerifyDevice(const CssmData &DeviceCert)
+{
+	CssmError::throwMe(CSSMERR_CSP_DEVICE_VERIFY_FAILED);
+}
+
+void
+SSCSPSession::GetOperationalStatistics(CSPOperationalStatistics &statistics)
+{
+	unimplemented();
+}
+
+
+//
+// Utterly miscellaneous, rarely used, strange functions
+//
+void
+SSCSPSession::RetrieveCounter(CssmData &Counter)
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::RetrieveUniqueId(CssmData &UniqueID)
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm, CssmData &TimeData)
+{
+	unimplemented();
+}
+
+
+//
+// ACL retrieval and change operations
+//
+void
+SSCSPSession::GetKeyOwner(const CssmKey &Key,
+						  CSSM_ACL_OWNER_PROTOTYPE &Owner)
+{
+	lookupKey(Key).getOwner(Owner, *this);
+}
+
+void
+SSCSPSession::ChangeKeyOwner(const AccessCredentials &AccessCred,
+							 const CssmKey &Key,
+							 const CSSM_ACL_OWNER_PROTOTYPE &NewOwner)
+{
+	lookupKey(Key).changeOwner(AccessCred,
+							   AclOwnerPrototype::overlay(NewOwner));
+}
+
+void
+SSCSPSession::GetKeyAcl(const CssmKey &Key,
+						const CSSM_STRING *SelectionTag,
+						uint32 &NumberOfAclInfos,
+						CSSM_ACL_ENTRY_INFO_PTR &AclInfos)
+{
+	lookupKey(Key).getAcl(reinterpret_cast<const char *>(SelectionTag),
+						  NumberOfAclInfos,
+						  reinterpret_cast<AclEntryInfo *&>(AclInfos), *this);
+}
+
+void
+SSCSPSession::ChangeKeyAcl(const AccessCredentials &AccessCred,
+						   const CSSM_ACL_EDIT &AclEdit,
+						   const CssmKey &Key)
+{
+	lookupKey(Key).changeAcl(AccessCred, AclEdit::overlay(AclEdit));
+}
+
+void
+SSCSPSession::GetLoginOwner(CSSM_ACL_OWNER_PROTOTYPE &Owner)
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::ChangeLoginOwner(const AccessCredentials &AccessCred,
+							   const CSSM_ACL_OWNER_PROTOTYPE &NewOwner)
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::GetLoginAcl(const CSSM_STRING *SelectionTag,
+						  uint32 &NumberOfAclInfos,
+						  CSSM_ACL_ENTRY_INFO_PTR &AclInfos)
+{
+	unimplemented();
+}
+
+void
+SSCSPSession::ChangeLoginAcl(const AccessCredentials &AccessCred,
+							 const CSSM_ACL_EDIT &AclEdit)
+{
+	unimplemented();
+}
+
+
+
+//
+// Passthroughs (by default, unimplemented)
+//
+void
+SSCSPSession::PassThrough(CSSM_CC_HANDLE CCHandle,
+						  const Context &Context,
+						  uint32 PassThroughId,
+						  const void *InData,
+						  void **OutData)
+{
+	unimplemented();
+}
diff --git a/AppleCSPDL/SSCSPSession.h b/AppleCSPDL/SSCSPSession.h
new file mode 100644
index 00000000..97daab1f
--- /dev/null
+++ b/AppleCSPDL/SSCSPSession.h
@@ -0,0 +1,165 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSDLSession.h - CSP session for security server CSP/DL.
+//
+#ifndef _H_SSCSPSESSION
+#define _H_SSCSPSESSION
+
+#include "SSCSPDLSession.h"
+
+#include <Security/SecurityServerClient.h>
+
+
+class CSPDLPlugin;
+class SSFactory;
+class SSDatabase;
+class SSKey;
+
+class SSCSPSession : public CSPFullPluginSession
+{
+public:
+	SSCSPDLSession &mSSCSPDLSession;
+	SSFactory &mSSFactory;
+
+	SSCSPSession(CSSM_MODULE_HANDLE handle,
+				 CSPDLPlugin &plug,
+				 const CSSM_VERSION &version,
+				 uint32 subserviceId,
+				 CSSM_SERVICE_TYPE subserviceType,
+				 CSSM_ATTACH_FLAGS attachFlags,
+				 const CSSM_UPCALLS &upcalls,
+				 SSCSPDLSession &ssCSPDLSession);
+
+	SecurityServer::ClientSession &clientSession()
+	{ return mSSCSPDLSession.clientSession(); }
+
+	CSPContext *contextCreate(CSSM_CC_HANDLE handle, const Context &context);
+#if 0
+	void contextUpdate(CSSM_CC_HANDLE handle, const Context &context,
+					   PluginContext *ctx);
+	void contextDelete(CSSM_CC_HANDLE handle, const Context &context,
+					   PluginContext *ctx);
+#endif
+
+	void setupContext(CSPContext * &ctx, const Context &context,
+					  bool encoding);
+
+	SSDatabase getDatabase(const Context &context);
+
+	void makeReferenceKey(SecurityServer::KeyHandle inKeyHandle,
+						  CssmKey &outKey, SSDatabase &inSSDatabase,
+						  uint32 inKeyAttr, const CssmData *inKeyLabel);
+	SSKey &lookupKey(const CssmKey &inKey);
+
+	void WrapKey(CSSM_CC_HANDLE CCHandle,
+				const Context &Context,
+				const AccessCredentials &AccessCred,
+				const CssmKey &Key,
+				const CssmData *DescriptiveData,
+				CssmKey &WrappedKey,
+				CSSM_PRIVILEGE Privilege);
+	void UnwrapKey(CSSM_CC_HANDLE CCHandle,
+				const Context &Context,
+				const CssmKey *PublicKey,
+				const CssmKey &WrappedKey,
+				uint32 KeyUsage,
+				uint32 KeyAttr,
+				const CssmData *KeyLabel,
+				const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+				CssmKey &UnwrappedKey,
+				CssmData &DescriptiveData,
+				CSSM_PRIVILEGE Privilege);
+	void DeriveKey(CSSM_CC_HANDLE CCHandle,
+				const Context &Context,
+				CssmData &Param,
+				uint32 KeyUsage,
+				uint32 KeyAttr,
+				const CssmData *KeyLabel,
+				const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+				CssmKey &DerivedKey);
+	void GenerateKey(CSSM_CC_HANDLE ccHandle,
+					const Context &context,
+					uint32 keyUsage,
+					uint32 keyAttr,
+					const CssmData *keyLabel,
+					const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry,
+					CssmKey &key,
+					CSSM_PRIVILEGE privilege);
+	void GenerateKeyPair(CSSM_CC_HANDLE ccHandle,
+						const Context &context,
+						uint32 publicKeyUsage,
+						uint32 publicKeyAttr,
+						const CssmData *publicKeyLabel,
+						CssmKey &publicKey,
+						uint32 privateKeyUsage,
+						uint32 privateKeyAttr,
+						const CssmData *privateKeyLabel,
+						const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry,
+						CssmKey &privateKey,
+						CSSM_PRIVILEGE privilege);
+	void ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
+									CssmKey &PrivateKey);
+	void QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle,
+							const Context &Context,
+							const CssmKey &Key,
+							CSSM_KEY_SIZE &KeySize);
+	void FreeKey(const AccessCredentials *AccessCred,
+				CssmKey &key, CSSM_BOOL Delete);
+	void GenerateRandom(CSSM_CC_HANDLE ccHandle,
+						const Context &context,
+						CssmData &randomNumber);
+	void Login(const AccessCredentials &AccessCred,
+			const CssmData *LoginName,
+			const void *Reserved);
+	void Logout();
+	void VerifyDevice(const CssmData &DeviceCert);
+	void GetOperationalStatistics(CSPOperationalStatistics &statistics);
+	void RetrieveCounter(CssmData &Counter);
+	void RetrieveUniqueId(CssmData &UniqueID);
+	void GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm, CssmData &TimeData);
+	void GetKeyOwner(const CssmKey &Key,
+					CSSM_ACL_OWNER_PROTOTYPE &Owner);
+	void ChangeKeyOwner(const AccessCredentials &AccessCred,
+						const CssmKey &Key,
+						const CSSM_ACL_OWNER_PROTOTYPE &NewOwner);
+	void GetKeyAcl(const CssmKey &Key,
+					const CSSM_STRING *SelectionTag,
+					uint32 &NumberOfAclInfos,
+					CSSM_ACL_ENTRY_INFO_PTR &AclInfos);
+	void ChangeKeyAcl(const AccessCredentials &AccessCred,
+					const CSSM_ACL_EDIT &AclEdit,
+					const CssmKey &Key);
+	void GetLoginOwner(CSSM_ACL_OWNER_PROTOTYPE &Owner);
+	void ChangeLoginOwner(const AccessCredentials &AccessCred,
+						const CSSM_ACL_OWNER_PROTOTYPE &NewOwner);
+	void GetLoginAcl(const CSSM_STRING *SelectionTag,
+					uint32 &NumberOfAclInfos,
+					CSSM_ACL_ENTRY_INFO_PTR &AclInfos);
+	void ChangeLoginAcl(const AccessCredentials &AccessCred,
+						const CSSM_ACL_EDIT &AclEdit);
+	void PassThrough(CSSM_CC_HANDLE CCHandle,
+					const Context &Context,
+					uint32 PassThroughId,
+					const void *InData,
+					void **OutData);
+};
+
+
+#endif // _H_SSCSPSESSION
diff --git a/AppleCSPDL/SSContext.cpp b/AppleCSPDL/SSContext.cpp
new file mode 100644
index 00000000..d03f0f75
--- /dev/null
+++ b/AppleCSPDL/SSContext.cpp
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSContext - cryptographic contexts for the security server
+//
+#include "SSContext.h"
+
+#include "SSCSPSession.h"
+#include "SSKey.h"
+
+using namespace SecurityServer;
+
+//
+// SSContext
+//
+SSContext::SSContext(SSCSPSession &session)
+: mSession(session), mContext(NULL)
+{
+}
+
+void
+SSContext::init(const Context &context,
+				bool /* encoding */) // @@@ should be removed from API since it's already in mDirection
+{
+	mContext = &context;
+}
+
+SecurityServer::ClientSession &
+SSContext::clientSession()
+{
+	return mSession.clientSession();
+}
+
+
+//
+// SSRandomContext -- Context for GenerateRandom operations
+//
+SSRandomContext::SSRandomContext(SSCSPSession &session) : SSContext(session) {}
+
+void
+SSRandomContext::init(const Context &context, bool encoding)
+{
+	SSContext::init(context, encoding);
+
+	// set/freeze output size
+	mOutSize = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE);
+
+#if 0
+	// seed the PRNG (if specified)
+	if (const CssmCryptoData *seed = context.get<CssmCryptoData>(CSSM_ATTRIBUTE_SEED)) {
+		const CssmData &seedValue = (*seed)();
+		clientSession().seedRandom(seedValue);
+	}
+#endif
+}
+
+size_t 
+SSRandomContext::outputSize(bool final, size_t inSize)
+{
+	return mOutSize;
+}
+
+void
+SSRandomContext::final(CssmData &out)
+{
+	clientSession().generateRandom(out);
+}
+
+
+//
+// SSSignContext -- Context for signing and GenerateMac operations
+//
+SSSignContext::SSSignContext(SSCSPSession &session) : SSContext(session) {}
+
+void
+SSSignContext::update(const CssmData &data)
+{
+}
+
+size_t
+SSSignContext::outputSize(bool final, size_t inSize)
+{
+	return 0;
+}
+
+void
+SSSignContext::final(CssmData &out)
+{
+}
+
+
+//
+// SSVerifyContext -- Context for Verify and VerifyMac operations
+//
+SSVerifyContext::SSVerifyContext(SSCSPSession &session) : SSContext(session) {}
+
+void
+SSVerifyContext::update(const CssmData &data)
+{
+}
+
+void
+SSVerifyContext::final(const CssmData &in)
+{
+}
+
+
+//
+// SSCryptContext -- Context for Encrypt and Decrypt operations
+//
+SSCryptContext::SSCryptContext(SSCSPSession &session)
+: SSContext(session), mKeyHandle(noKey), mCurrent(0), mCapacity(0),
+mBuffer(NULL)
+{
+}
+
+
+SSCryptContext::~SSCryptContext()
+{
+	freeBuffer();
+}
+
+void
+SSCryptContext::freeBuffer()
+{
+	// @@@ We should probably use CssmAllocator::standard(sensitive) instead of malloc/realloc/free here
+	if (mBuffer)
+	{
+		// Zero out buffer (only on decrypt?)
+		if (mCapacity /* && !encoding() */)
+		{
+			memset(mBuffer, 0, mCapacity);
+		}
+
+		free(mBuffer);
+		mBuffer = NULL;
+		mCapacity = 0;
+	}
+}
+
+void
+SSCryptContext::init(const Context &context, bool encoding)
+{
+	SSContext::init(context, encoding);
+	freeBuffer();
+
+	mCurrent = 0;
+	mCapacity = 0;
+
+ 	const CssmKey &keyInContext =
+		context.get<const CssmKey>(CSSM_ATTRIBUTE_KEY,
+								   CSSMERR_CSP_MISSING_ATTR_KEY);
+
+	// @@@ Should return SSKey.
+	mKeyHandle = mSession.lookupKey(keyInContext).keyHandle();
+}
+
+size_t
+SSCryptContext::inputSize(size_t outSize)
+{
+	return UINT_MAX;
+}
+
+size_t
+SSCryptContext::outputSize(bool final, size_t inSize)
+{
+	if (!final)
+	{
+		mCapacity = mCurrent + inSize;
+		mBuffer = realloc(mBuffer, mCapacity);
+		return 0;
+	}
+
+	// There should not be any remaining input data left when final is true;
+	assert(!inSize);
+
+	// Do the actual operation.
+	const CssmData in(mBuffer, mCurrent);
+	CssmData out;
+	if (encoding())
+		clientSession().encrypt(*mContext, mKeyHandle, in, out);
+	else
+		clientSession().decrypt(*mContext, mKeyHandle, in, out);
+
+	freeBuffer();
+	mBuffer = out.Data;
+	mCapacity = out.Length;
+	mCurrent = 0;
+	return mCapacity;
+}
+
+void
+SSCryptContext::minimumProgress(size_t &in, size_t &out)
+{
+	// This should never be called.
+	assert(false);
+}
+
+void
+SSCryptContext::update(void *inp, size_t &inSize, void *outp, size_t &outSize)
+{
+	outSize = 0;
+	assert(inSize);
+	assert(mCurrent + inSize <= mCapacity);
+	memcpy(&reinterpret_cast<uint8 *>(mBuffer)[mCurrent], inp, inSize);
+	mCurrent += inSize;
+}
+
+void
+SSCryptContext::final(CssmData &out)
+{
+	if(!out.Length) return;
+	assert(out.Data && out.Length);
+	uint32 todo = min(out.Length, mCapacity - mCurrent);
+	memcpy(out.Data, &reinterpret_cast<uint8 *>(mBuffer)[mCurrent], todo);
+	mCurrent += todo;
+	out.Length = todo;
+
+	freeBuffer();
+}
+
+
+#if 0
+//
+// SSKeyPairGenContext -- Context for key pair generation
+//
+SSKeyPairGenContext::SSKeyPairGenContext(SSCSPSession &session)
+: SSContext(session) {}
+
+void
+SSKeyPairGenContext::generate(const Context &context, 
+							  CssmKey &pubKey,
+							  SSKey *pubBinKey,
+							  CssmKey &privKey,
+							  SSKey *privBinKey)
+{
+}
+
+void
+SSKeyPairGenContext::generate(const Context &context,
+							  SSKey &pubBinKey,
+							  SSKey &privBinKey,
+							  uint32 &keySize)
+{
+}
+
+
+//
+// SSSymmKeyGenContext -- Context for symmetric key generation
+//
+SSSymmKeyGenContext::SSSymmKeyGenContext(SSCSPSession &session,
+										 uint32 minSize,
+										 uint32 maxSize,
+										 bool byteSized)
+: SSContext(session),
+  minSizeInBits(minSize),
+  maxSizeInBits(maxSize),
+  mustBeByteSized(byteSized)
+{
+}
+			
+void
+SSSymmKeyGenContext::generateSymKey(const Context &context, CssmKey &cssmKey)
+{
+}
+#endif
diff --git a/AppleCSPDL/SSContext.h b/AppleCSPDL/SSContext.h
new file mode 100644
index 00000000..1f3f6d4e
--- /dev/null
+++ b/AppleCSPDL/SSContext.h
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSContext.h - Security Server contexts 
+//
+#ifndef _H_SS_CONTEXT
+#define _H_SS_CONTEXT
+
+#include <Security/CSPsession.h>
+#include <Security/SecurityServerClient.h>
+
+//
+// Parent class for all CSPContexts implemented in this CSP.  Currently the
+// only thing we add is a reference to our creator's session.
+//
+class SSCSPSession;
+class SSKey;
+
+class SSContext : public CSPFullPluginSession::CSPContext
+{
+public:
+	SSContext(SSCSPSession &session);
+	virtual void init(const Context &context, bool encoding);
+
+protected:
+	SecurityServer::ClientSession &clientSession();
+	SSCSPSession &mSession;
+
+	// We remeber a pointer to the passed in context and assume it will
+	// remain a valid from init(), update() all the way though the call to
+	// final().
+	const Context *mContext;
+};
+
+// SSSignContext -- Context for Sign, and GenerateMac operations
+class SSSignContext : public SSContext
+{
+public:
+	SSSignContext(SSCSPSession &session);
+	virtual void update(const CssmData &data);
+	virtual size_t outputSize(bool final, size_t inSize);
+	virtual void final(CssmData &out);
+};
+
+// SSVerifyContext -- Context for Verify, and VerifyMac operations
+class SSVerifyContext : public SSContext
+{
+public:
+	SSVerifyContext(SSCSPSession &session);
+	virtual void update(const CssmData &data);
+	virtual void final(const CssmData &in);
+};
+
+// Context for GenerateRandom operations
+class SSRandomContext : public SSContext
+{
+public:
+	SSRandomContext(SSCSPSession &session);
+	virtual void init(const Context &context, bool);
+	virtual size_t outputSize(bool final, size_t inSize);
+	virtual void final(CssmData &out);
+
+private:
+	uint32 mOutSize;
+};
+
+// Context for Encrypt and Decrypt operations
+class SSCryptContext : public SSContext
+{
+public:
+	SSCryptContext(SSCSPSession &session);
+	~SSCryptContext();
+	virtual void init(const Context &context, bool encoding);
+	virtual size_t inputSize(size_t outSize);
+	virtual size_t outputSize(bool final, size_t inSize);
+	virtual void minimumProgress(size_t &in, size_t &out);
+	virtual void update(void *inp, size_t &inSize, void *outp,
+						size_t &outSize);
+	virtual void final(CssmData &out);
+
+private:
+	void freeBuffer();
+
+	SecurityServer::KeyHandle mKeyHandle;
+	uint32 mCurrent;
+	uint32 mCapacity;
+	void *mBuffer;
+};
+
+#if 0
+// Context for key (pair) generation
+class SSKeyGenContext : public SSContext
+{
+public:
+	SSKeyGenContext(SSCSPSession &session);
+
+	// Subclass implements generate(const Context &, CssmKey &,
+	// CssmKey &). That method allocates two subclass-specific 
+	// SSKeys and calls this method. This will call down to 
+	// generate(const Context &, SSKey &, SSKey &)
+	// and optionally to SSKey::generateKeyBlob.
+	void generate(const Context &context, 
+				  CssmKey &pubKey,
+				  SSKey *pubBinKey,
+				  CssmKey &privKey,
+				  SSKey *privBinKey);
+
+protected:
+	// @@@ Subclasses must implement this. It cooks up a key pair.
+	virtual void generate(const Context &context,
+						  SSKey &pubBinKey,		// valid on successful return
+						  SSKey &privBinKey, 	// ditto
+						  uint32 &keySize);	// ditto
+
+public:
+	void generateSymKey(const Context &context, CssmKey &outCssmKey); 
+};
+#endif // 0
+
+
+#endif // _H_SS_CONTEXT
diff --git a/AppleCSPDL/SSDLSession.cpp b/AppleCSPDL/SSDLSession.cpp
new file mode 100644
index 00000000..fee09af4
--- /dev/null
+++ b/AppleCSPDL/SSDLSession.cpp
@@ -0,0 +1,620 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSDLSession.h - DL session for security server CSP/DL.
+//
+#include "SSDLSession.h"
+
+#include "CSPDLPlugin.h"
+#include "SSKey.h"
+
+using namespace CssmClient;
+using namespace SecurityServer;
+using namespace std;
+
+//
+// SSDLSession -- Security Server DL session
+//
+SSDLSession::SSDLSession(CSSM_MODULE_HANDLE handle,
+						 CSPDLPlugin &plug,
+						 const CSSM_VERSION &version,
+						 uint32 subserviceId,
+						 CSSM_SERVICE_TYPE subserviceType,
+						 CSSM_ATTACH_FLAGS attachFlags,
+						 const CSSM_UPCALLS &upcalls,
+						 DatabaseManager &databaseManager,
+						 SSCSPDLSession &ssCSPDLSession)
+: DLPluginSession(handle, plug, version, subserviceId, subserviceType,
+				  attachFlags, upcalls, databaseManager),
+  mSSCSPDLSession(ssCSPDLSession),
+  mDL(Module(gGuidAppleFileDL, Cssm::standard()))
+{
+	// @@@ mDL.allocator(*static_cast<DatabaseSession *>(this));
+	mDL->allocator(allocator());
+	mDL->version(version);
+	mDL->subserviceId(subserviceId);
+	mDL->flags(attachFlags);
+}
+
+SSDLSession::~SSDLSession()
+{
+	// @@@ What about a catch?
+	StLock<Mutex> _1(mSSUniqueRecordLock);
+	mSSUniqueRecordMap.clear();
+
+	StLock<Mutex> _2(mDbHandleLock);
+	DbHandleMap::iterator end = mDbHandleMap.end();
+	for (DbHandleMap::iterator it = mDbHandleMap.begin(); it != end; ++it)
+		it->second->close();
+
+	mDbHandleMap.clear();
+	mDL->detach();
+}
+
+// Utility functions
+void
+SSDLSession::GetDbNames(CSSM_NAME_LIST_PTR &outNameList)
+{
+	// @@@ Fix client lib
+	CSSM_DL_GetDbNames(mDL->handle(), &outNameList);
+}
+
+
+void
+SSDLSession::FreeNameList(CSSM_NAME_LIST &inNameList)
+{
+	// @@@ Fix client lib
+	CSSM_DL_FreeNameList(mDL->handle(), &inNameList);
+}
+
+
+void
+SSDLSession::DbDelete(const char *inDbName,
+					  const CSSM_NET_ADDRESS *inDbLocation,
+					  const AccessCredentials *inAccessCred)
+{
+	SSDatabase db(mSSCSPDLSession.clientSession(), mDL, inDbName, inDbLocation);
+	db->accessCredentials(inAccessCred);
+	db->deleteDb();
+}
+
+// DbContext creation and destruction.
+void
+SSDLSession::DbCreate(const char *inDbName,
+					  const CSSM_NET_ADDRESS *inDbLocation,
+					  const CSSM_DBINFO &inDBInfo,
+					  CSSM_DB_ACCESS_TYPE inAccessRequest,
+					  const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
+					  const void *inOpenParameters,
+					  CSSM_DB_HANDLE &outDbHandle)
+{
+	SSDatabase db(mSSCSPDLSession.clientSession(), mDL, inDbName, inDbLocation);
+	db->dbInfo(&inDBInfo);
+	db->accessRequest(inAccessRequest);
+	db->resourceControlContext(inCredAndAclEntry);
+	db->openParameters(inOpenParameters);
+	db->create(DLDbIdentifier(CssmSubserviceUid(plugin.myGuid(), &version(), subserviceId(),
+												CSSM_SERVICE_DL | CSSM_SERVICE_CSP),
+							  inDbName, inDbLocation));
+	db->dbInfo(NULL);
+	outDbHandle = makeDbHandle(db);
+}
+
+void
+SSDLSession::DbOpen(const char *inDbName,
+					const CSSM_NET_ADDRESS *inDbLocation,
+					CSSM_DB_ACCESS_TYPE inAccessRequest,
+					const AccessCredentials *inAccessCred,
+					const void *inOpenParameters,
+					CSSM_DB_HANDLE &outDbHandle)
+{
+	SSDatabase db(mSSCSPDLSession.clientSession(), mDL, inDbName, inDbLocation);
+	db->accessRequest(inAccessRequest);
+	db->accessCredentials(inAccessCred);
+	db->openParameters(inOpenParameters);
+	db->open(DLDbIdentifier(CssmSubserviceUid(plugin.myGuid(), &version(), subserviceId(),
+											  CSSM_SERVICE_DL | CSSM_SERVICE_CSP),
+							inDbName, inDbLocation));
+	outDbHandle = makeDbHandle(db);
+}
+
+// Operations using DbContext instances.
+void
+SSDLSession::DbClose(CSSM_DB_HANDLE inDbHandle)
+{
+	killDbHandle(inDbHandle)->close();
+}
+
+void
+SSDLSession::CreateRelation(CSSM_DB_HANDLE inDbHandle,
+							CSSM_DB_RECORDTYPE inRelationID,
+							const char *inRelationName,
+							uint32 inNumberOfAttributes,
+							const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
+							uint32 inNumberOfIndexes,
+							const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+	// @@@ Fix inAttributeInfo and inIndexInfo arguments (might be NULL if NumberOf = 0)
+	db->createRelation(inRelationID, inRelationName,
+					  inNumberOfAttributes, &inAttributeInfo,
+					  inNumberOfIndexes, &inIndexInfo);
+}
+
+void
+SSDLSession::DestroyRelation(CSSM_DB_HANDLE inDbHandle,
+							 CSSM_DB_RECORDTYPE inRelationID)
+{
+	// @@@ Check credentials.
+	SSDatabase db = findDbHandle(inDbHandle);
+	db->destroyRelation(inRelationID);
+}
+
+void
+SSDLSession::Authenticate(CSSM_DB_HANDLE inDbHandle,
+						  CSSM_DB_ACCESS_TYPE inAccessRequest,
+						  const AccessCredentials &inAccessCred)
+{
+	// @@@ Use securityserver.
+	SSDatabase db = findDbHandle(inDbHandle);
+	db->authenticate(inAccessRequest, &inAccessCred);
+}
+
+
+void
+SSDLSession::GetDbAcl(CSSM_DB_HANDLE inDbHandle,
+					  const CSSM_STRING *inSelectionTag,
+					  uint32 &outNumberOfAclInfos,
+					  CSSM_ACL_ENTRY_INFO_PTR &outAclInfos)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+SSDLSession::ChangeDbAcl(CSSM_DB_HANDLE inDbHandle,
+						 const AccessCredentials &inAccessCred,
+						 const CSSM_ACL_EDIT &inAclEdit)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+SSDLSession::GetDbOwner(CSSM_DB_HANDLE inDbHandle,
+						CSSM_ACL_OWNER_PROTOTYPE &outOwner)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+SSDLSession::ChangeDbOwner(CSSM_DB_HANDLE inDbHandle,
+						   const AccessCredentials &inAccessCred,
+						   const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+SSDLSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle,
+                                 char **outDbName)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+	// @@@ Fix this functions signature.
+	db->name(*outDbName);
+}
+
+void
+SSDLSession::DataInsert(CSSM_DB_HANDLE inDbHandle,
+						CSSM_DB_RECORDTYPE inRecordType,
+						const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+						const CssmData *inData,
+						CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+	// @@@ Fix client lib.
+    SSUniqueRecord uniqueId = db->insert(inRecordType, inAttributes, inData, true); // @@@ Fix me
+	outUniqueId = makeSSUniqueRecord(uniqueId);
+	// @@@ If this is a key do the right thing.
+}
+
+void
+SSDLSession::DataDelete(CSSM_DB_HANDLE inDbHandle,
+						const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+	SSUniqueRecord uniqueId = findSSUniqueRecord(inUniqueRecordIdentifier);
+	uniqueId->deleteRecord();
+	// @@@ If this is a key do the right thing.
+}
+
+
+void
+SSDLSession::DataModify(CSSM_DB_HANDLE inDbHandle,
+						CSSM_DB_RECORDTYPE inRecordType,
+						CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier,
+						const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
+						const CssmData *inDataToBeModified,
+						CSSM_DB_MODIFY_MODE inModifyMode)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+	SSUniqueRecord uniqueId = findSSUniqueRecord(inoutUniqueRecordIdentifier);
+	uniqueId->modify(inRecordType, inAttributesToBeModified, inDataToBeModified, inModifyMode);
+	// @@@ If this is a key do the right thing.
+}
+
+CSSM_HANDLE
+SSDLSession::DataGetFirst(CSSM_DB_HANDLE inDbHandle,
+						  const DLQuery *inQuery,
+						  CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+						  CssmData *inoutData,
+						  CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+	CSSM_HANDLE resultsHandle = CSSM_INVALID_HANDLE;
+    SSUniqueRecord uniqueId(db);
+
+	// Setup so we always retrive the attributes even if the client
+	// doesn't want them so we can figure out if we just retrived a key.
+	CSSM_DB_RECORD_ATTRIBUTE_DATA attributes;
+	CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes;
+	if (inoutAttributes)
+		pAttributes = inoutAttributes;
+	else
+	{
+		pAttributes = &attributes;
+		memset(pAttributes, 0, sizeof(attributes));
+	}
+
+	// Retrive the record.
+	CSSM_RETURN result = CSSM_DL_DataGetFirst(db->handle(), inQuery, &resultsHandle,
+											  pAttributes, inoutData, uniqueId);
+	if (result)
+	{
+		if (result == CSSMERR_DL_ENDOFDATA)
+			return CSSM_INVALID_HANDLE;
+
+		CssmError::throwMe(result);
+	}
+
+	uniqueId->activate();
+
+	// If we the client didn't ask for data then it doesn't matter
+	// if this record is a key or not, just return it.
+	if (inoutData)
+	{
+		if (pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PUBLIC_KEY
+			|| pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PRIVATE_KEY
+			|| pAttributes->DataRecordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
+		{
+			// This record is a key, do the right thing (tm).
+			// Allocate storage for the key.
+			CssmKey *outKey = allocator().alloc<CssmKey>();
+			new SSKey(*this, *outKey, db, uniqueId, pAttributes->DataRecordType, *inoutData);
+
+			// Free the data we retrived (keyblob)
+			allocator().free(inoutData->Data);
+
+			// Set the length and data on the data we return to the client
+			inoutData->Length = sizeof(*outKey);
+			inoutData->Data = reinterpret_cast<uint8 *>(outKey);			
+		}
+	}
+
+	outUniqueRecord = makeSSUniqueRecord(uniqueId);
+	return resultsHandle;
+}
+
+bool
+SSDLSession::DataGetNext(CSSM_DB_HANDLE inDbHandle,
+						 CSSM_HANDLE inResultsHandle,
+						 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+						 CssmData *inoutData,
+						 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
+{
+	// @@@ If this is a key do the right thing.
+	SSDatabase db = findDbHandle(inDbHandle);
+    SSUniqueRecord uniqueId(db);
+
+	// Setup so we always retrive the attributes even if the client
+	// doesn't want them so we can figure out if we just retrived a key.
+	CSSM_DB_RECORD_ATTRIBUTE_DATA attributes;
+	CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes;
+	if (inoutAttributes)
+		pAttributes = inoutAttributes;
+	else
+	{
+		pAttributes = &attributes;
+		memset(pAttributes, 0, sizeof(attributes));
+	}
+
+	CSSM_RETURN result = CSSM_DL_DataGetNext(db->handle(), inResultsHandle,
+											 inoutAttributes, inoutData, uniqueId);
+	if (result)
+	{
+		if (result == CSSMERR_DL_ENDOFDATA)
+			return false;
+
+		CssmError::throwMe(result);
+	}
+
+	uniqueId->activate();
+
+	// If we the client didn't ask for data then it doesn't matter
+	// if this record is a key or not, just return it.
+	if (inoutData)
+	{
+		if (pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PUBLIC_KEY
+			|| pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PRIVATE_KEY
+			|| pAttributes->DataRecordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
+		{
+			// This record is a key, do the right thing (tm).
+			// Allocate storage for the key.
+			CssmKey *outKey = allocator().alloc<CssmKey>();
+			new SSKey(*this, *outKey, db, uniqueId, pAttributes->DataRecordType, *inoutData);
+
+			// Free the data we retrived (keyblob)
+			allocator().free(inoutData->Data);
+
+			// Set the length and data on the data we return to the client
+			inoutData->Length = sizeof(*outKey);
+			inoutData->Data = reinterpret_cast<uint8 *>(outKey);			
+		}
+	}
+
+	outUniqueRecord = makeSSUniqueRecord(uniqueId);
+
+	return true;
+}
+
+void
+SSDLSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle,
+							CSSM_HANDLE inResultsHandle)
+{
+	// @@@ If this is a key do the right thing.
+	SSDatabase db = findDbHandle(inDbHandle);
+	CSSM_RETURN result = CSSM_DL_DataAbortQuery(db->handle(), inResultsHandle);
+	if (result)
+		CssmError::throwMe(result);
+}
+
+void
+SSDLSession::DataGetFromUniqueRecordId(CSSM_DB_HANDLE inDbHandle,
+									   const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
+									   CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+									   CssmData *inoutData)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+	const SSUniqueRecord uniqueId = findSSUniqueRecord(inUniqueRecord);
+	CSSM_RETURN result = CSSM_DL_DataGetFromUniqueRecordId(db->handle(), uniqueId, inoutAttributes, inoutData);
+	if (result)
+		CssmError::throwMe(result);
+	// @@@ If this is a key do the right thing.
+}
+
+void
+SSDLSession::FreeUniqueRecord(CSSM_DB_HANDLE inDbHandle,
+							  CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
+{
+	killSSUniqueRecord(inUniqueRecordIdentifier);
+}
+
+void
+SSDLSession::PassThrough(CSSM_DB_HANDLE inDbHandle,
+						 uint32 inPassThroughId,
+						 const void *inInputParams,
+						 void **outOutputParams)
+{
+	SSDatabase db = findDbHandle(inDbHandle);
+	switch (inPassThroughId)
+	{
+		case CSSM_APPLECSPDL_DB_LOCK:
+			db->lock();
+			break;
+		case CSSM_APPLECSPDL_DB_UNLOCK:
+			if (inInputParams)
+				db->unlock(*reinterpret_cast<const CSSM_DATA *>(inInputParams));
+			else
+				db->unlock();
+			break;
+		case CSSM_APPLECSPDL_DB_GET_SETTINGS:
+		{
+			if (!outOutputParams)
+				CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER);
+
+			CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR params =
+				allocator().alloc<CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS>();
+			try
+			{
+				uint32 idleTimeout;
+				bool lockOnSleep;
+				db->getSettings(idleTimeout, lockOnSleep);
+				params->idleTimeout = idleTimeout;
+				params->lockOnSleep = lockOnSleep;
+			}
+			catch(...)
+			{
+				allocator().free(params);
+				throw;
+			}
+			*reinterpret_cast<CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR *>(outOutputParams) = params;
+			break;
+		}
+		case CSSM_APPLECSPDL_DB_SET_SETTINGS:
+		{
+			if (!inInputParams)
+				CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER);
+
+			const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS *params =
+				reinterpret_cast<const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS *>(inInputParams);
+			db->setSettings(params->idleTimeout, params->lockOnSleep);
+			break;
+		}
+		case CSSM_APPLECSPDL_DB_IS_LOCKED:
+		{
+			if (!outOutputParams)
+				CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER);
+
+			CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR params =
+				allocator().alloc<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS>();
+			try
+			{
+				params->isLocked = db->isLocked();
+			}
+			catch(...)
+			{
+				allocator().free(params);
+				throw;
+			}
+			*reinterpret_cast<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR *>(outOutputParams) = params;
+			break;
+		}
+		case CSSM_APPLECSPDL_DB_CHANGE_PASSWORD:
+		{
+			if (!inInputParams)
+				CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER);
+
+			const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS *params =
+				reinterpret_cast<const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS *>(inInputParams);
+			db->changePassphrase(params->accessCredentials);
+			break;
+		}
+		default:
+		{
+			CSSM_RETURN result = CSSM_DL_PassThrough(db->handle(), inPassThroughId, inInputParams, outOutputParams);
+			if (result)
+				CssmError::throwMe(result);
+			break;
+		}
+	}
+}
+
+CSSM_DB_HANDLE
+SSDLSession::makeDbHandle(SSDatabase &inDb)
+{
+	StLock<Mutex> _(mDbHandleLock);
+	CSSM_DB_HANDLE aDbHandle = inDb->handle().DBHandle;
+	bool inserted = mDbHandleMap.insert(DbHandleMap::value_type(aDbHandle, inDb)).second;
+	assert(inserted);
+	return aDbHandle;
+}
+
+SSDatabase
+SSDLSession::killDbHandle(CSSM_DB_HANDLE inDbHandle)
+{
+	StLock<Mutex> _(mDbHandleLock);
+	DbHandleMap::iterator it = mDbHandleMap.find(inDbHandle);
+	if (it == mDbHandleMap.end())
+		CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE);
+
+	SSDatabase db = it->second;
+	mDbHandleMap.erase(it);
+	return db;
+}
+
+SSDatabase
+SSDLSession::findDbHandle(CSSM_DB_HANDLE inDbHandle)
+{
+	StLock<Mutex> _(mDbHandleLock);
+	DbHandleMap::iterator it = mDbHandleMap.find(inDbHandle);
+	if (it == mDbHandleMap.end())
+		CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE);
+
+	return it->second;
+}
+
+CSSM_DB_UNIQUE_RECORD_PTR
+SSDLSession::makeSSUniqueRecord(SSUniqueRecord &uniqueId)
+{
+	StLock<Mutex> _(mSSUniqueRecordLock);
+	CSSM_HANDLE ref = CSSM_HANDLE(static_cast<CSSM_DB_UNIQUE_RECORD *>(uniqueId));
+	bool inserted = mSSUniqueRecordMap.insert(SSUniqueRecordMap::value_type(ref, uniqueId)).second;
+	assert(inserted);
+	return createUniqueRecord(ref);
+}
+
+SSUniqueRecord
+SSDLSession::killSSUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
+{
+	CSSM_HANDLE ref = parseUniqueRecord(inUniqueRecord);
+	StLock<Mutex> _(mSSUniqueRecordLock);
+	SSUniqueRecordMap::iterator it = mSSUniqueRecordMap.find(ref);
+	if (it == mSSUniqueRecordMap.end())
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
+
+	SSUniqueRecord uniqueRecord = it->second;
+	mSSUniqueRecordMap.erase(it);
+	freeUniqueRecord(inUniqueRecord);
+	return uniqueRecord;
+}
+
+SSUniqueRecord
+SSDLSession::findSSUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
+{
+	CSSM_HANDLE ref = parseUniqueRecord(inUniqueRecord);
+	StLock<Mutex> _(mSSUniqueRecordLock);
+	SSUniqueRecordMap::iterator it = mSSUniqueRecordMap.find(ref);
+	if (it == mSSUniqueRecordMap.end())
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
+
+	return it->second;
+}
+
+CSSM_DB_UNIQUE_RECORD_PTR
+SSDLSession::createUniqueRecord(CSSM_HANDLE ref)
+{
+	CSSM_DB_UNIQUE_RECORD *aUniqueRecord = allocator().alloc<CSSM_DB_UNIQUE_RECORD>();
+	memset(aUniqueRecord, 0, sizeof(CSSM_DB_UNIQUE_RECORD));
+	aUniqueRecord->RecordIdentifier.Length = sizeof(CSSM_HANDLE);
+	try
+	{
+		aUniqueRecord->RecordIdentifier.Data = allocator().alloc<uint8>(sizeof(CSSM_HANDLE));
+		*reinterpret_cast<CSSM_HANDLE *>(aUniqueRecord->RecordIdentifier.Data) = ref;
+	}
+	catch(...)
+	{
+		free(aUniqueRecord);
+		throw;
+	}
+
+	return aUniqueRecord;
+}
+
+CSSM_HANDLE
+SSDLSession::parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
+{
+	if (inUniqueRecord.RecordIdentifier.Length != sizeof(CSSM_HANDLE))
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
+
+	return *reinterpret_cast<CSSM_HANDLE *>(inUniqueRecord.RecordIdentifier.Data);
+}
+
+void
+SSDLSession::freeUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
+{
+	if (inUniqueRecord.RecordIdentifier.Length != 0
+		&& inUniqueRecord.RecordIdentifier.Data != NULL)
+	{
+		inUniqueRecord.RecordIdentifier.Length = 0;
+		allocator().free(inUniqueRecord.RecordIdentifier.Data);
+	}
+	allocator().free(&inUniqueRecord);
+}
diff --git a/AppleCSPDL/SSDLSession.h b/AppleCSPDL/SSDLSession.h
new file mode 100644
index 00000000..c7143bc2
--- /dev/null
+++ b/AppleCSPDL/SSDLSession.h
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSDLSession.h - DL session for security server CSP/DL.
+//
+#ifndef _H_SSDLSESSION
+#define _H_SSDLSESSION
+
+#include <Security/DLsession.h>
+
+#include "SSDatabase.h"
+
+class CSPDLPlugin;
+class SSCSPDLSession;
+
+class SSDLSession : public DLPluginSession
+{
+public:
+	SSCSPDLSession &mSSCSPDLSession;
+
+	SSDLSession(CSSM_MODULE_HANDLE handle,
+				CSPDLPlugin &plug,
+				const CSSM_VERSION &version,
+				uint32 subserviceId,
+				CSSM_SERVICE_TYPE subserviceType,
+				CSSM_ATTACH_FLAGS attachFlags,
+				const CSSM_UPCALLS &upcalls,
+				DatabaseManager &databaseManager,
+				SSCSPDLSession &ssCSPDLSession);
+	~SSDLSession();
+
+    void GetDbNames(CSSM_NAME_LIST_PTR &NameList);
+    void FreeNameList(CSSM_NAME_LIST &NameList);
+    void DbDelete(const char *DbName,
+                  const CSSM_NET_ADDRESS *DbLocation,
+                  const AccessCredentials *AccessCred);
+    void DbCreate(const char *DbName,
+                  const CSSM_NET_ADDRESS *DbLocation,
+                  const CSSM_DBINFO &DBInfo,
+                  CSSM_DB_ACCESS_TYPE AccessRequest,
+                  const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                  const void *OpenParameters,
+                  CSSM_DB_HANDLE &DbHandle);
+    void DbOpen(const char *DbName,
+                const CSSM_NET_ADDRESS *DbLocation,
+                CSSM_DB_ACCESS_TYPE AccessRequest,
+                const AccessCredentials *AccessCred,
+                const void *OpenParameters,
+                CSSM_DB_HANDLE &DbHandle);
+    void DbClose(CSSM_DB_HANDLE DBHandle);
+    void CreateRelation(CSSM_DB_HANDLE DBHandle,
+                        CSSM_DB_RECORDTYPE RelationID,
+                        const char *RelationName,
+                        uint32 NumberOfAttributes,
+                        const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &pAttributeInfo,
+                        uint32 NumberOfIndexes,
+                        const CSSM_DB_SCHEMA_INDEX_INFO &pIndexInfo);
+    void DestroyRelation(CSSM_DB_HANDLE DBHandle,
+                         CSSM_DB_RECORDTYPE RelationID);
+
+    void Authenticate(CSSM_DB_HANDLE DBHandle,
+                      CSSM_DB_ACCESS_TYPE AccessRequest,
+                      const AccessCredentials &AccessCred);
+    void GetDbAcl(CSSM_DB_HANDLE DBHandle,
+                  const CSSM_STRING *SelectionTag,
+                  uint32 &NumberOfAclInfos,
+                  CSSM_ACL_ENTRY_INFO_PTR &AclInfos);
+    void ChangeDbAcl(CSSM_DB_HANDLE DBHandle,
+                     const AccessCredentials &AccessCred,
+                     const CSSM_ACL_EDIT &AclEdit);
+    void GetDbOwner(CSSM_DB_HANDLE DBHandle,
+                    CSSM_ACL_OWNER_PROTOTYPE &Owner);
+    void ChangeDbOwner(CSSM_DB_HANDLE DBHandle,
+                       const AccessCredentials &AccessCred,
+                       const CSSM_ACL_OWNER_PROTOTYPE &NewOwner);
+    void GetDbNameFromHandle(CSSM_DB_HANDLE DBHandle,
+                             char **DbName);
+    void DataInsert(CSSM_DB_HANDLE DBHandle,
+                    CSSM_DB_RECORDTYPE RecordType,
+                    const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes,
+                    const CssmData *Data,
+                    CSSM_DB_UNIQUE_RECORD_PTR &UniqueId);
+    void DataDelete(CSSM_DB_HANDLE DBHandle,
+                    const CSSM_DB_UNIQUE_RECORD &UniqueRecordIdentifier);
+    void DataModify(CSSM_DB_HANDLE DBHandle,
+                    CSSM_DB_RECORDTYPE RecordType,
+                    CSSM_DB_UNIQUE_RECORD &UniqueRecordIdentifier,
+                    const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified,
+                    const CssmData *DataToBeModified,
+                    CSSM_DB_MODIFY_MODE ModifyMode);
+    CSSM_HANDLE DataGetFirst(CSSM_DB_HANDLE DBHandle,
+                             const DLQuery *Query,
+                             CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                             CssmData *Data,
+                             CSSM_DB_UNIQUE_RECORD_PTR &UniqueId);
+    bool DataGetNext(CSSM_DB_HANDLE DBHandle,
+                     CSSM_HANDLE ResultsHandle,
+                     CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                     CssmData *Data,
+                     CSSM_DB_UNIQUE_RECORD_PTR &UniqueId);
+    void DataAbortQuery(CSSM_DB_HANDLE DBHandle,
+                        CSSM_HANDLE ResultsHandle);
+    void DataGetFromUniqueRecordId(CSSM_DB_HANDLE DBHandle,
+                                   const CSSM_DB_UNIQUE_RECORD &UniqueRecord,
+                                   CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                                   CssmData *Data);
+    void FreeUniqueRecord(CSSM_DB_HANDLE DBHandle,
+                          CSSM_DB_UNIQUE_RECORD &UniqueRecord);
+    void PassThrough(CSSM_DB_HANDLE DBHandle,
+                     uint32 PassThroughId,
+                     const void *InputParams,
+                     void **OutputParams);
+
+	CssmAllocator &allocator() { return *static_cast<DatabaseSession *>(this); }
+
+	SSDatabase findDbHandle(CSSM_DB_HANDLE inDbHandle);
+protected:
+	CSSM_DB_HANDLE makeDbHandle(SSDatabase &inDb);
+	SSDatabase killDbHandle(CSSM_DB_HANDLE inDbHandle);
+
+	Mutex mDbHandleLock;
+	typedef map<CSSM_DB_HANDLE, SSDatabase> DbHandleMap;
+	DbHandleMap mDbHandleMap;
+
+	CSSM_DB_UNIQUE_RECORD_PTR makeSSUniqueRecord(SSUniqueRecord &uniqueId);
+	SSUniqueRecord killSSUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord);
+	SSUniqueRecord findSSUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord);
+
+	CSSM_DB_UNIQUE_RECORD_PTR createUniqueRecord(CSSM_HANDLE ref);
+	CSSM_HANDLE parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord);
+	void freeUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord);
+
+	Mutex mSSUniqueRecordLock;
+	typedef map<CSSM_HANDLE, SSUniqueRecord> SSUniqueRecordMap;
+	SSUniqueRecordMap mSSUniqueRecordMap;
+
+	CssmClient::DL mDL;
+};
+
+
+#endif // _H_SSDLSESSION
diff --git a/AppleCSPDL/SSDatabase.cpp b/AppleCSPDL/SSDatabase.cpp
new file mode 100644
index 00000000..7dc77507
--- /dev/null
+++ b/AppleCSPDL/SSDatabase.cpp
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSDatabase.cpp - Security Server database object
+//
+#include "SSDatabase.h"
+
+#include "KeySchema.h"
+
+using namespace CssmClient;
+using namespace SecurityServer;
+
+const char *const SSDatabaseImpl::DBBlobRelationName = "DBBlob";
+
+
+SSDatabaseImpl::SSDatabaseImpl(ClientSession &inClientSession,
+							   const CssmClient::DL &dl,
+							   const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
+: Db::Impl(dl, inDbName, inDbLocation), mClientSession(inClientSession), mSSDbHandle(noDb)
+{
+}
+
+SSDatabaseImpl::~SSDatabaseImpl()
+{
+	if (mSSDbHandle != noDb)
+		mClientSession.releaseDb(mSSDbHandle);
+}
+
+SSUniqueRecord
+SSDatabaseImpl::insert(CSSM_DB_RECORDTYPE recordType,
+					   const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+					   const CSSM_DATA *data, bool)
+{
+	SSUniqueRecord uniqueId(SSDatabase(this));
+	check(CSSM_DL_DataInsert(handle(), recordType,
+							 attributes,
+							 data, uniqueId));
+	// Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope.
+	uniqueId->activate();
+	return uniqueId;
+}
+
+void
+SSDatabaseImpl::lock()
+{
+	mClientSession.lock(dbHandle());
+
+}
+
+void
+SSDatabaseImpl::unlock()
+{
+	mClientSession.unlock(dbHandle());
+}
+
+void
+SSDatabaseImpl::unlock(const CSSM_DATA &password)
+{
+	mClientSession.unlock(dbHandle(), CssmData::overlay(password));
+}
+
+void
+SSDatabaseImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
+{
+	DBParameters parameters;
+	mClientSession.getDbParameters(dbHandle(), parameters);
+	outIdleTimeout = parameters.idleTimeout;
+	outLockOnSleep = parameters.lockOnSleep;
+}
+
+void
+SSDatabaseImpl::setSettings(uint32 inIdleTimeout, bool inLockOnSleep)
+{
+	DBParameters parameters;
+	parameters.idleTimeout = inIdleTimeout;
+	parameters.lockOnSleep = inLockOnSleep;
+	mClientSession.setDbParameters(dbHandle(), parameters);
+
+	// Reencode the db blob.
+	CssmDataContainer dbb(allocator());
+	mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
+	mDbBlobId->modify(DBBlobRelationID, NULL, &dbb, CSSM_DB_MODIFY_ATTRIBUTE_NONE);
+}
+
+bool
+SSDatabaseImpl::isLocked()
+{
+	return mClientSession.isLocked(dbHandle());
+}
+
+void
+SSDatabaseImpl::changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	mClientSession.changePassphrase(dbHandle(), AccessCredentials::overlay(cred));
+
+	// Reencode the db blob.
+	CssmDataContainer dbb(allocator());
+	mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
+	mDbBlobId->modify(DBBlobRelationID, NULL, &dbb, CSSM_DB_MODIFY_ATTRIBUTE_NONE);
+}
+
+DbHandle
+SSDatabaseImpl::dbHandle()
+{
+	activate();
+	return mSSDbHandle;
+}
+
+void
+SSDatabaseImpl::create(const DLDbIdentifier &dlDbIdentifier)
+{
+	DbImpl::create();
+
+	try
+	{
+		// @@@ The CSSM_DB_SCHEMA_ATTRIBUTE_INFO and CSSM_DB_SCHEMA_INDEX_INFO
+		// arguments should be optional.
+		createRelation(DBBlobRelationID, DBBlobRelationName,
+					0, (CSSM_DB_SCHEMA_ATTRIBUTE_INFO *)42,
+					0, (CSSM_DB_SCHEMA_INDEX_INFO *)42);
+
+		// @@@ Only iff not already in mDbInfo
+		createRelation(CSSM_DL_DB_RECORD_PUBLIC_KEY, "CSSM_DL_DB_RECORD_PUBLIC_KEY",
+					KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
+					KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
+
+		// @@@ Only iff not already in mDbInfo
+		createRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY, "CSSM_DL_DB_RECORD_PRIVATE_KEY",
+					KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
+					KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
+
+		// @@@ Only iff not already in mDbInfo
+		createRelation(CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "CSSM_DL_DB_RECORD_SYMMETRIC_KEY",
+					KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
+					KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
+
+		DBParameters dbParameters;
+		memset(&dbParameters, 0, sizeof(DBParameters));
+		dbParameters.idleTimeout = kDefaultIdleTimeout;
+		dbParameters.lockOnSleep = kDefaultLockOnSleep;
+
+		const AccessCredentials *cred = NULL;
+		const AclEntryInput *owner = NULL;
+		if (resourceControlContext())
+		{
+			cred = AccessCredentials::overlay(resourceControlContext()->AccessCred);
+			owner = &AclEntryInput::overlay(resourceControlContext()->InitialAclEntry);
+		}
+		mSSDbHandle = mClientSession.createDb(dlDbIdentifier, cred, owner, dbParameters);
+		CssmDataContainer dbb(allocator());
+		mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
+		mDbBlobId = Db::Impl::insert(DBBlobRelationID, NULL, &dbb);
+	}
+	catch(...)
+	{
+		DbImpl::deleteDb();
+		throw;
+	}
+}
+
+void
+SSDatabaseImpl::open(const DLDbIdentifier &dlDbIdentifier)
+{
+	Db::Impl::open();
+
+	DbCursor cursor(SSDatabase(this));
+	cursor->recordType(DBBlobRelationID);
+	CssmDataContainer dbb(allocator());
+	if (!cursor->next(NULL, &dbb, mDbBlobId))
+		CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+	mSSDbHandle = mClientSession.decodeDb(dlDbIdentifier, AccessCredentials::overlay(accessCredentials()), dbb);
+}
+
+DbUniqueRecordImpl *
+SSDatabaseImpl::newDbUniqueRecord()
+{
+	return new SSUniqueRecordImpl(SSDatabase(this));
+}
+
+
+SSUniqueRecordImpl::SSUniqueRecordImpl(const SSDatabase &db)
+: DbUniqueRecord::Impl(db)
+{
+}
+
+SSUniqueRecordImpl::~SSUniqueRecordImpl()
+{
+}
+
+SSDatabase
+SSUniqueRecordImpl::database() const
+{
+	return parent<SSDatabase>();
+}
+
diff --git a/AppleCSPDL/SSDatabase.h b/AppleCSPDL/SSDatabase.h
new file mode 100644
index 00000000..28cbc17c
--- /dev/null
+++ b/AppleCSPDL/SSDatabase.h
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSDatabase.h - Security Server database object
+//
+#ifndef	_H_SSDATABASE_
+#define _H_SSDATABASE_
+
+#include <Security/dlclient.h>
+#include <Security/SecurityServerClient.h>
+
+class SSCSPDLSession;
+class SSUniqueRecord;
+
+//
+// Protected please ignore this class unless subclassing SSDatabase.
+//
+class SSDatabaseImpl : public CssmClient::DbImpl
+{
+	static const char *const DBBlobRelationName;
+	enum {
+		DBBlobRelationID = CSSM_DB_RECORDTYPE_APP_DEFINED_START + 0x8000
+	};
+
+public:
+	SSDatabaseImpl(SecurityServer::ClientSession &inClientSession,
+				   const CssmClient::DL &dl,
+				   const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
+	virtual ~SSDatabaseImpl();
+
+	void create(const DLDbIdentifier &dlDbIdentifier);
+	void open(const DLDbIdentifier &dlDbIdentifier);
+	SSUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
+						  const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+						  const CSSM_DATA *data, bool);
+
+	// Passthrough functions (only implemented by AppleCSPDL).
+	void lock();
+	void unlock();
+	void unlock(const CSSM_DATA &password);
+	void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
+	void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
+	bool isLocked();
+	void changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred);
+
+	// DbUniqueRecordMaker
+	CssmClient::DbUniqueRecordImpl *newDbUniqueRecord();
+
+	// New methods not inherited from DbImpl
+	SecurityServer::DbHandle dbHandle();
+
+private:
+	enum
+	{
+		kDefaultIdleTimeout		= 5 * 60, // 5 minute default autolock time
+		kDefaultLockOnSleep		= true
+	};
+
+	SecurityServer::ClientSession &mClientSession;
+	SecurityServer::DbHandle mSSDbHandle;
+	CssmClient::DbUniqueRecord mDbBlobId;
+};
+
+
+//
+// SSDatabase --  A Security Server aware Db object.
+//
+class SSDatabase : public CssmClient::Db
+{
+public:
+	typedef SSDatabaseImpl Impl;
+
+	explicit SSDatabase(SSDatabaseImpl *impl) : CssmClient::Db(impl) {}
+	SSDatabase() : CssmClient::Db(NULL) {}
+	SSDatabase(SecurityServer::ClientSession &inClientSession,
+			   const CssmClient::DL &dl,
+			   const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
+	: CssmClient::Db(new SSDatabaseImpl(inClientSession, dl, inDbName, inDbLocation)) {}
+
+	SSDatabaseImpl *operator ->() const { return &impl<SSDatabaseImpl>(); }
+	SSDatabaseImpl &operator *() const { return impl<SSDatabaseImpl>(); }
+
+	// For convinience only
+	SecurityServer::DbHandle dbHandle() { return (*this) ? (*this)->dbHandle() : SecurityServer::noDb; }
+};
+
+
+class SSUniqueRecordImpl : public CssmClient::DbUniqueRecordImpl
+{
+public:
+	SSUniqueRecordImpl(const SSDatabase &db);
+	virtual ~SSUniqueRecordImpl();
+
+	SSDatabase database() const;
+};
+
+
+class SSUniqueRecord : public CssmClient::DbUniqueRecord
+{
+public:
+	typedef SSUniqueRecordImpl Impl;
+
+	explicit SSUniqueRecord(SSUniqueRecordImpl *impl) : CssmClient::DbUniqueRecord(impl) {}
+	SSUniqueRecord() : CssmClient::DbUniqueRecord(NULL) {}
+	SSUniqueRecord(const SSDatabase &db) : CssmClient::DbUniqueRecord(new SSUniqueRecordImpl(db)) {}
+
+	SSUniqueRecordImpl *operator ->() const { return &impl<SSUniqueRecordImpl>(); }
+	SSUniqueRecordImpl &operator *() const { return impl<SSUniqueRecordImpl>(); }
+};
+
+
+#endif	// _H_SSDATABASE_
diff --git a/AppleCSPDL/SSFactory.cpp b/AppleCSPDL/SSFactory.cpp
new file mode 100644
index 00000000..1e01a505
--- /dev/null
+++ b/AppleCSPDL/SSFactory.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSFactory -- The factory for Security Server context objects
+//
+#include "SSFactory.h"
+
+#include "SSContext.h"
+
+
+//
+// SSFactory -- The factory for Security Server context objects
+//
+bool SSFactory::setup(SSCSPSession &session, CSPFullPluginSession::CSPContext * &cspCtx,
+					  const Context &context, bool encoding)
+{
+	if (cspCtx)
+		return false;	// not ours or already set
+
+	switch (context.type())
+	{
+	case CSSM_ALGCLASS_SIGNATURE:
+	case CSSM_ALGCLASS_MAC:
+		cspCtx = encoding ? new SSSignContext(session) : new SSVerifyContext(session);
+		return true;
+	case CSSM_ALGCLASS_SYMMETRIC:
+	case CSSM_ALGCLASS_ASYMMETRIC:
+		cspCtx = new SSCryptContext(session); // @@@ Could also be wrap/unwrap
+		return true;
+	case CSSM_ALGCLASS_RANDOMGEN:
+		cspCtx = new SSRandomContext(session); // @@@ Should go.
+		return true;
+	}
+
+	return false;
+
+#if 0
+	/* FIXME - qualify by ALGCLASS as well to avoid MAC */
+	switch (context.algorithm()) {
+	case CSSM_ALGID_MD5:
+		cspCtx = new MD5Context(session);
+		return true;
+	case CSSM_ALGID_SHA1:
+		cspCtx = new SHA1Context(session);
+		return true;
+	}
+	return false;
+
+    if (ctx)
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	// won't support re-definition
+    switch (context.algorithm()) {
+        case CSSM_ALGID_ROTTY_ROT_16:
+            ctx = new SSContext(16);
+            return true;
+        case CSSM_ALGID_ROTTY_ROT_37:
+            ctx = new SSContext(37);
+            return true;
+    }
+#endif
+    return false;
+}
diff --git a/AppleCSPDL/SSFactory.h b/AppleCSPDL/SSFactory.h
new file mode 100644
index 00000000..66d0ea3b
--- /dev/null
+++ b/AppleCSPDL/SSFactory.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+
+//
+//  SSAlgorithms.h - Description t.b.d.
+//
+#ifndef _H_SS_ALGORITHMS
+#define _H_SS_ALGORITHMS
+
+#include <Security/CSPsession.h>
+
+/* Can't include CSPDLPlugin.h due to circular dependency */
+class SSCSPSession;
+
+// no longer a subclass of AlgorithmFactory due to 
+// differing setup() methods
+class SSFactory
+{
+public:
+    bool setup(SSCSPSession &session, CSPFullPluginSession::CSPContext * &ctx,
+			   const Context &context, bool encoding);
+};
+
+#endif // _H_SS_ALGORITHMS
diff --git a/AppleCSPDL/SSKey.cpp b/AppleCSPDL/SSKey.cpp
new file mode 100644
index 00000000..76aa7d9f
--- /dev/null
+++ b/AppleCSPDL/SSKey.cpp
@@ -0,0 +1,337 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSKey - reference keys for the security server
+//
+#include "SSKey.h"
+
+#include "SSCSPSession.h"
+#include "SSCSPDLSession.h"
+#include "SSDatabase.h"
+#include "SSDLSession.h"
+#include "KeySchema.h"
+#include <Security/cssmplugin.h>
+
+using namespace CssmClient;
+using namespace SecurityServer;
+
+// Constructor for a Security Server generated key.
+SSKey::SSKey(SSCSPSession &session, KeyHandle keyHandle, CssmKey &ioKey,
+			 SSDatabase &inSSDatabase, uint32 inKeyAttr,
+			 const CssmData *inKeyLabel)
+: ReferencedKey(session.mSSCSPDLSession),
+mAllocator(session), mKeyHandle(keyHandle)
+{
+	CssmKey::Header &header = ioKey.header();
+	if (inKeyAttr & CSSM_KEYATTR_PERMANENT)
+	{
+		if (!inSSDatabase)
+			CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE);
+
+		// EncodeKey and store it in the db.
+		CssmDataContainer blob(clientSession().returnAllocator);
+		clientSession().encodeKey(keyHandle, blob);
+
+		assert(header.HeaderVersion == CSSM_KEYHEADER_VERSION);
+		switch (header.KeyClass)
+		{
+		case CSSM_KEYCLASS_PUBLIC_KEY:
+			mRecordType = CSSM_DL_DB_RECORD_PUBLIC_KEY;
+			break;
+		case CSSM_KEYCLASS_PRIVATE_KEY:
+			mRecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
+			break;
+		case CSSM_KEYCLASS_SESSION_KEY:
+			mRecordType = CSSM_DL_DB_RECORD_SYMMETRIC_KEY;
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+		}
+
+		CssmData label;
+		if (inKeyLabel)
+			label = *inKeyLabel;
+
+		CssmData none;
+		// We store the keys real CSP guid on disk
+		CssmGuidData creatorGuid(header.CspId);
+		CssmDateData startDate(header.StartDate);
+		CssmDateData endDate(header.EndDate);
+
+		DbAttributes attributes(inSSDatabase);
+		attributes.recordType(mRecordType);
+		attributes.add(KeySchema::KeyClass, mRecordType);
+		attributes.add(KeySchema::PrintName, label);
+		attributes.add(KeySchema::Alias, none);
+		attributes.add(KeySchema::Permanent,
+					   header.attribute(CSSM_KEYATTR_PERMANENT));
+		attributes.add(KeySchema::Private,
+					   header.attribute(CSSM_KEYATTR_PRIVATE));
+		attributes.add(KeySchema::Modifiable,
+					   header.attribute(CSSM_KEYATTR_MODIFIABLE));
+		attributes.add(KeySchema::Label, label);
+		attributes.add(KeySchema::ApplicationTag, none);
+		attributes.add(KeySchema::KeyCreator, creatorGuid);
+		attributes.add(KeySchema::KeyType, header.AlgorithmId);
+		attributes.add(KeySchema::KeySizeInBits, header.LogicalKeySizeInBits);
+		// @@@ Get the real effective key size.
+		attributes.add(KeySchema::EffectiveKeySize, header.LogicalKeySizeInBits);
+		attributes.add(KeySchema::StartDate, startDate);
+		attributes.add(KeySchema::EndDate, endDate);
+		attributes.add(KeySchema::Sensitive,
+					   header.attribute(CSSM_KEYATTR_SENSITIVE));
+		attributes.add(KeySchema::AlwaysSensitive,
+					   header.attribute(CSSM_KEYATTR_ALWAYS_SENSITIVE));
+		attributes.add(KeySchema::Extractable,
+					   header.attribute(CSSM_KEYATTR_EXTRACTABLE));
+		attributes.add(KeySchema::NeverExtractable,
+					   header.attribute(CSSM_KEYATTR_NEVER_EXTRACTABLE));
+		attributes.add(KeySchema::Encrypt,
+					   header.useFor(CSSM_KEYUSE_ANY | CSSM_KEYUSE_ENCRYPT));
+		attributes.add(KeySchema::Decrypt,
+					   header.useFor(CSSM_KEYUSE_ANY | CSSM_KEYUSE_DECRYPT));
+		attributes.add(KeySchema::Derive,
+					   header.useFor(CSSM_KEYUSE_ANY | CSSM_KEYUSE_DERIVE));
+		attributes.add(KeySchema::Sign,
+					   header.useFor(CSSM_KEYUSE_ANY | CSSM_KEYUSE_SIGN));
+		attributes.add(KeySchema::Verify,
+					   header.useFor(CSSM_KEYUSE_ANY | CSSM_KEYUSE_VERIFY));
+		attributes.add(KeySchema::SignRecover,
+					   header.useFor(CSSM_KEYUSE_ANY
+									 | CSSM_KEYUSE_SIGN_RECOVER));
+		attributes.add(KeySchema::VerifyRecover,
+					   header.useFor(CSSM_KEYUSE_ANY
+									 | CSSM_KEYUSE_VERIFY_RECOVER));
+		attributes.add(KeySchema::Wrap,
+					   header.useFor(CSSM_KEYUSE_ANY | CSSM_KEYUSE_WRAP));
+		attributes.add(KeySchema::Unwrap,
+					   header.useFor(CSSM_KEYUSE_ANY | CSSM_KEYUSE_UNWRAP));
+
+		// @@@ Fixme
+		mUniqueId = inSSDatabase->insert(mRecordType, &attributes, &blob,
+										 true);
+	}
+
+	header.cspGuid(session.plugin.myGuid()); // Set the csp guid to me.
+	makeReferenceKey(mAllocator, keyReference(), ioKey);
+}
+
+// Constructor for a key retrived from a Db.
+SSKey::SSKey(SSDLSession &session, CssmKey &ioKey, SSDatabase &inSSDatabase,
+			 const SSUniqueRecord &uniqueId, CSSM_DB_RECORDTYPE recordType,
+			 CssmData &keyBlob)
+: ReferencedKey(session.mSSCSPDLSession),
+mAllocator(session.allocator()), mKeyHandle(noKey), mUniqueId(uniqueId),
+mRecordType(recordType)
+{
+	CssmKey::Header &header = ioKey.header();
+	memset(&header, 0, sizeof(header)); // Clear key header
+
+	if (!mUniqueId || !mUniqueId->database())
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+	header.HeaderVersion = CSSM_KEYHEADER_VERSION;
+	switch (mRecordType)
+	{
+	case CSSM_DL_DB_RECORD_PUBLIC_KEY:
+		header.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+		break;
+	case CSSM_DL_DB_RECORD_PRIVATE_KEY:
+		header.KeyClass = CSSM_KEYCLASS_PRIVATE_KEY;
+		break;
+	case CSSM_DL_DB_RECORD_SYMMETRIC_KEY:
+		header.KeyClass = CSSM_KEYCLASS_SESSION_KEY;
+		break;
+	default:
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	}
+
+	DbAttributes attributes(mUniqueId->database());
+	attributes.recordType(mRecordType);
+	attributes.add(KeySchema::KeyClass);			// 0
+	attributes.add(KeySchema::Permanent);			// 1
+	attributes.add(KeySchema::Private);			// 2
+	attributes.add(KeySchema::Modifiable);			// 3
+	attributes.add(KeySchema::KeyCreator);			// 4
+	attributes.add(KeySchema::KeyType);			// 5
+	attributes.add(KeySchema::KeySizeInBits);		// 6
+	attributes.add(KeySchema::StartDate);			// 7
+	attributes.add(KeySchema::EndDate);			// 8
+	attributes.add(KeySchema::Sensitive);			// 9
+	attributes.add(KeySchema::AlwaysSensitive);	// 10
+	attributes.add(KeySchema::Extractable);		// 11
+	attributes.add(KeySchema::NeverExtractable);	// 12
+	attributes.add(KeySchema::Encrypt);			// 13
+	attributes.add(KeySchema::Decrypt);			// 14
+	attributes.add(KeySchema::Derive);				// 15
+	attributes.add(KeySchema::Sign);				// 16
+	attributes.add(KeySchema::Verify);				// 17
+	attributes.add(KeySchema::SignRecover);		// 18
+	attributes.add(KeySchema::VerifyRecover);		// 19
+	attributes.add(KeySchema::Wrap);				// 20
+	attributes.add(KeySchema::Unwrap);				// 21
+
+	mUniqueId->get(&attributes, NULL);
+
+	// Assert that the mRecordType matches the KeyClass attribute.
+	if (mRecordType != uint32(attributes[0]))
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+
+	header.AlgorithmId = attributes[5]; // KeyType
+    header.LogicalKeySizeInBits = attributes[6]; // KeySizeInBits
+
+	if (attributes[1]) header.setAttribute(CSSM_KEYATTR_PERMANENT);
+	if (attributes[2]) header.setAttribute(CSSM_KEYATTR_PRIVATE);
+	if (attributes[3]) header.setAttribute(CSSM_KEYATTR_MODIFIABLE);
+	if (attributes[9]) header.setAttribute(CSSM_KEYATTR_SENSITIVE);
+	if (attributes[11]) header.setAttribute(CSSM_KEYATTR_EXTRACTABLE);
+	if (attributes[10]) header.setAttribute(CSSM_KEYATTR_ALWAYS_SENSITIVE);
+	if (attributes[12]) header.setAttribute(CSSM_KEYATTR_NEVER_EXTRACTABLE);
+
+	if (attributes[13]) header.usage(CSSM_KEYUSE_ENCRYPT);
+	if (attributes[14]) header.usage(CSSM_KEYUSE_DECRYPT);
+	if (attributes[15]) header.usage(CSSM_KEYUSE_DERIVE);
+	if (attributes[16]) header.usage(CSSM_KEYUSE_SIGN);
+	if (attributes[17]) header.usage(CSSM_KEYUSE_VERIFY);
+	if (attributes[18]) header.usage(CSSM_KEYUSE_SIGN_RECOVER);
+	if (attributes[19]) header.usage(CSSM_KEYUSE_VERIFY_RECOVER);
+	if (attributes[20]) header.usage(CSSM_KEYUSE_WRAP);
+	if (attributes[21]) header.usage(CSSM_KEYUSE_UNWRAP);
+
+	// If all usages are allowed set usage to CSSM_KEYUSE_ANY
+	if (header.usage() == (CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT
+						   | CSSM_KEYUSE_DERIVE | CSSM_KEYUSE_SIGN
+						   | CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_SIGN_RECOVER
+						   | CSSM_KEYUSE_VERIFY_RECOVER | CSSM_KEYUSE_WRAP
+						   | CSSM_KEYUSE_UNWRAP))
+		header.usage(CSSM_KEYUSE_ANY); 
+
+	if (!attributes[7].size() || !attributes[8].size())
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+
+    header.StartDate = attributes[7].at<CSSM_DATE>(0);
+    header.EndDate = attributes[8].at<CSSM_DATE>(0);
+
+	makeReferenceKey(mAllocator, keyReference(), ioKey);
+	header.cspGuid(session.plugin.myGuid()); // Set the csp guid to me.
+}
+
+SSKey::~SSKey()
+{
+	if (mKeyHandle != noKey)
+		clientSession().releaseKey(mKeyHandle);
+}
+
+void
+SSKey::free(const AccessCredentials *accessCred, CssmKey &ioKey,
+			CSSM_BOOL deleteKey)
+{
+	freeReferenceKey(mAllocator, ioKey);
+	if (deleteKey)
+	{
+		if (!mUniqueId || !mUniqueId->database())
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+	
+		// @@@ Evaluate accessCred against Db acl.
+		// What should we do with accessCred?  Reauthenticate
+		// mUniqueId->database()?
+		mUniqueId->deleteRecord();
+	}
+
+	if (mKeyHandle != noKey)
+	{
+		clientSession().releaseKey(mKeyHandle);
+		mKeyHandle = noKey;
+	}
+}
+
+SecurityServer::ClientSession &
+SSKey::clientSession()
+{
+	return keyPool<SSCSPDLSession>().clientSession();
+}
+
+KeyHandle
+SSKey::keyHandle()
+{
+	if (mKeyHandle == noKey)
+	{
+		// Deal with uninstantiated keys.
+		if (!mUniqueId || !mUniqueId->database())
+			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+
+		CssmDataContainer blob;
+		mUniqueId->get(NULL, &blob);
+		CssmKey::Header dummyHeader; // @@@ Unused
+		mKeyHandle =
+			clientSession().decodeKey(mUniqueId->database().dbHandle(), blob,
+									  dummyHeader);
+
+		// @@@ Check decoded header against returned header
+	}
+
+	return  mKeyHandle;
+}
+
+//
+// ACL retrieval and change operations
+//
+void
+SSKey::getOwner(CSSM_ACL_OWNER_PROTOTYPE &owner, CssmAllocator &allocator)
+{
+	clientSession().getKeyOwner(keyHandle(), AclOwnerPrototype::overlay(owner),
+								allocator);
+}
+
+void
+SSKey::changeOwner(const AccessCredentials &accessCred,
+				   const AclOwnerPrototype &newOwner)
+{
+	clientSession().changeKeyOwner(keyHandle(), accessCred, newOwner);
+	if (mUniqueId == true)
+	{
+		// The key is persistant, make the change on disk.
+		CssmDataContainer keyBlob(clientSession().returnAllocator);
+		clientSession().encodeKey(keyHandle(), keyBlob);
+		mUniqueId->modify(mRecordType, NULL, &keyBlob,
+						  CSSM_DB_MODIFY_ATTRIBUTE_NONE);
+	}
+}
+
+void
+SSKey::getAcl(const char *selectionTag, uint32 &numberOfAclInfos,
+			  AclEntryInfo *&aclInfos, CssmAllocator &allocator)
+{
+	clientSession().getKeyAcl(keyHandle(), selectionTag, numberOfAclInfos,
+							  aclInfos, allocator);
+}
+
+void
+SSKey::changeAcl(const AccessCredentials &accessCred, const AclEdit &aclEdit)
+{
+	clientSession().changeKeyAcl(keyHandle(), accessCred, aclEdit);
+	if (mUniqueId == true)
+	{
+		// The key is persistant, make the change on disk.
+		CssmDataContainer keyBlob(clientSession().returnAllocator);
+		clientSession().encodeKey(keyHandle(), keyBlob);
+		mUniqueId->modify(mRecordType, NULL, &keyBlob,
+						  CSSM_DB_MODIFY_ATTRIBUTE_NONE);
+	}
+}
diff --git a/AppleCSPDL/SSKey.h b/AppleCSPDL/SSKey.h
new file mode 100644
index 00000000..262e9fab
--- /dev/null
+++ b/AppleCSPDL/SSKey.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+
+//
+// SSKey.h - CSP-wide SSKey base class
+//
+#ifndef	_H_SSKEY_
+#define _H_SSKEY_
+
+#include <Security/CSPsession.h>
+
+#include "SSDatabase.h"
+
+#include <Security/dlclient.h>
+#include <Security/SecurityServerClient.h>
+
+namespace Security
+{
+
+class CssmKey;
+
+} // end namespace Security
+
+class SSCSPSession;
+class SSCSPDLSession;
+class SSDLSession;
+
+class SSKey : public ReferencedKey
+{
+public:
+	SSKey(SSCSPSession &session, SecurityServer::KeyHandle keyHandle,
+		  CssmKey &ioKey, SSDatabase &inSSDatabase, uint32 inKeyAttr,
+		  const CssmData *inKeyLabel);
+	SSKey(SSDLSession &session, CssmKey &ioKey, SSDatabase &inSSDatabase,
+		  const SSUniqueRecord &uniqueId, CSSM_DB_RECORDTYPE recordType,
+		  CssmData &keyBlob);
+
+	virtual ~SSKey();
+	void free(const AccessCredentials *accessCred, CssmKey &ioKey,
+			  CSSM_BOOL deleteKey);
+
+	SecurityServer::ClientSession &clientSession();
+	SecurityServer::KeyHandle keyHandle();
+
+    // ACL retrieval and change operations
+	void getOwner(CSSM_ACL_OWNER_PROTOTYPE &owner, CssmAllocator &allocator);
+	void changeOwner(const AccessCredentials &accessCred,
+					 const AclOwnerPrototype &newOwner);
+	void getAcl(const char *selectionTag, uint32 &numberOfAclInfos,
+				AclEntryInfo *&aclInfos, CssmAllocator &allocator);
+	void changeAcl(const AccessCredentials &accessCred,
+				   const AclEdit &aclEdit);
+
+private:
+	CssmAllocator &mAllocator;
+	SecurityServer::KeyHandle mKeyHandle;
+	SSDatabase mSSDatabase;
+	SSUniqueRecord mUniqueId;
+	CSSM_DB_RECORDTYPE mRecordType;
+};
+
+
+#endif	// _H_SSKEY_
diff --git a/AppleCSPDL/cssmplugin.exp b/AppleCSPDL/cssmplugin.exp
new file mode 100644
index 00000000..f5046fbf
--- /dev/null
+++ b/AppleCSPDL/cssmplugin.exp
@@ -0,0 +1,4 @@
+_CSSM_SPI_ModuleLoad
+_CSSM_SPI_ModuleAttach
+_CSSM_SPI_ModuleDetach
+_CSSM_SPI_ModuleUnload
diff --git a/AppleDL/.cvsignore b/AppleDL/.cvsignore
new file mode 100644
index 00000000..7b6b8240
--- /dev/null
+++ b/AppleDL/.cvsignore
@@ -0,0 +1 @@
+AppleCSPDL?Data
diff --git a/AppleDL/AppleCSPDL.mcp b/AppleDL/AppleCSPDL.mcp
new file mode 100644
index 0000000000000000000000000000000000000000..a4eb36faef46da5048dca34bfc82b62b497ed480
GIT binary patch
literal 28375
zcmeHQYm8gRb)I|q(qkn{isM&onX(=$OY4;r#g5Fx&aSw-(t1fPC9a}PUtBJEwM&by
zkX&0zkY?K?ZPPZefx0kI#7>RYNtysf(z*!H2kf*cYQ!y?)&YXLO_Krvn$~UFA4!3r
zaMkadIV3N+<Rw>9Q$@=IeKTjyoI8&*XNEI(@4d>DN_nM}Pbur5Qn{2;kNu)j{sd&B
zmTe(26fI?)bLmPYSE_^)mC|EQrdH3|5OE<}9f?F&s<l!fJmXw?qEyLNl@^X?GETJ`
zPNZwgBAH89mYiBR>C|eu;*toba(O2lPnXM0(eagBJ{z9ASgWK(X~J1tSz2-`VN-;u
zpdmc7Qmo|)j*&iiY$nV>IpGwWf{9!;U9CEW#k^B#N>AiVi|KrLwv4NDA9Ux$a>Wbo
zbbVw^Z;wO|A4VO8GMX;MMYRl$P;7Q1Iu%D_Om*>eW;Pj)J1_t&Qgrf0oJdzQXhCaP
zB5W-zk%+c-i-NV?qO^0jnB(pi(}~F`X$KSHy}FOc9j_MLO+Dj$u-Q)04eP;+<*GFn
z)5#4Y?OqV+-~^F1J`iblfk<Ppn;y`Vxf~$UHvT%@ZYM45WG0=_w31G`>=H4<>>e%=
zxd$uK9Qa7bagTHu_PVU4AdZpCmm^HC=?jG&`@#%YUzn5u*9E!zg}j#Gj<k$6$2M77
zsbrk+T*Yy!ibd%G!NjFs&tb7#EM4qRseQ5NR#=PYbW>{grfzzz9@b5(#p}8$H9WEI
zbv+fuWxMIQJ=RO7W#qjS*LZ`MvUrG>O5Ibs>9oxXZ?%SlcU3dXX1DCMGpd^=<@MR)
zrPG&PSwP=*rE(9uQiZe8t6{zDj%%B<wp&3hGx`5yOA<n<n}E&07GNvD4U!)i0=5C$
z0a6eM0N7Wln}8j_PGA@C7T{*!t-vk7t-x)-?SKv31MCI%0sDaiz@5O|z%YP)nz|Qw
z8?Xlm1G|Akz+qqnxDOZwjsW)qZwKB190lG9JOJDUJOaEI7z4(E<G?ZC-9QwW049NV
z0q+4G1|q-|Z~{09OaqSsGe8W81E+uofro%QfNMpxH*G|_((be|ZQW^X++)(u7@!zW
z;+Tio0AK{z4-5l`fdjxHfb!kIK432phWae9fF}N~aUY#ltIw)^ANj2}E*^Vc9h<p)
znZ5&cZA1FV`*bhqSL`8ui@l+Lu@&?wT7iCL^3O?nr=)My-blYP`7w#(x)zQPYh&AJ
zIi(WXvz0n6dS|4(J0;fI^H8h+tLV(HOJ|S{K9fpiO65x`R7s`M)l}*<v~}kZ4*}bN
z?Z8dI4qzv+3!tHlk<c0NdN@CFnar9H6HjX}Q(1;(1TfTM6KsM+|I^}t1!`yoaH26+
zGzvjliZL0M^w?FRur{jUJoKV^LpZn12$?xce<g7a(Qirg3o|-OrNPsWNsj|&RFwKv
z@LY39&jMU~NWTvlPf+Twz;i7keG@RAqSW`m)2~1l+p=A=%Ho>C`2e!+LBO>MWO1%?
zjRIMmzw|?pl|jHY3uN)o$F&P&{W1df6J-510+tK1UPQn(4P<=<0oOK=^|uJP#(}Kw
zAdq#z`Y-TY%Rn~!DmJzmbBzMo_aWdK2eQWza4iJcNd#eX;Ijz!Xja)55wmX~`;!Rv
zYF62_;XdJi5AlBCUq#Gy7G%GUU|6%t{#V2Yg?|$<*Ikg0HanzQ<zw5q?t*+=XGb)v
ze3OXTZjkT&2u3xld^yBNg#TH@T%SR{XAtmuknb}H-l19LV>`KSgM5FAfa^EN_ZkAO
z;~*dH`JiT%?+1vvUW5F!G1qgD|2P7UG04A!Afj32e-bg*dyxMR5YR_Ke%j$-&8h(X
zm%kOD0Q<_{3{ZeRJVp*YZO*X)1zteF`apqK5JWYr0{@11!tg=*6m0|wvMp1ZRYBV7
zgzz6ld{X$&BIa)mDEKu5k7`y0IW9AX4}}rOgdam37oNUBp9Y0Kfq?D4p@^qhHI=JW
zdEa5F;1p{rk{&Is)Ko0D7@jVaOO;xf$MksOoI80uozIs_#qdcdUsmyRVYA28isx`F
z*2i|Hu)R{)$GI;xJ5=uKWe?bX;%PbAw4Y#FPbw`ZlE%qH4iv1SzQHBmvXP}=&4$(0
zD6;hpX4?kdBpVxbInK5pTH9|^v}`md(zWzry6TKBtBJ*EsaSI^)<!esvMa@$Q|W>u
zV$D)EyU3epB9#Q?r&pZHB@r8*(qv}YDWpX#iDll6NSAY38lOnI>vtuW6%vhxvT^RT
z&W)F{D|ypG<VgzE)_cc`P?w76pdnsXk=9<jk~*)^Z)8Zv!MS?gOlkdQ-;q)8JXlxn
zn<-r3>VL%5V>Z{FhNipA^=x-Pn%%DFHmne7=rPMRop2OsP8msvw=f0Z*rMj6vr~<E
zqvg$Mq%YF97Qoe~5!t%ClW%c%3f8!L+r{<sR^9E9-8?@<;!dqndcvt(sD_iZbTON*
zWKr{CC0)4`i6>)W-1Lha&lT(ZD6SqwK1|r_!scbJi*)ajD`hS~5mQgjsYc|cLOl+n
z7G0yr>y@_Lj%ln5J?==T$k}4<ai>yE=Up`>Yb%S*`s27=YkHN8rF7LPy`J#`-Zs*W
zNlwq6op1C-jMJKKNwqb;wGNmSC3L6-25*$2Rk}4N+Ei<Hq)$U)+MIDRxNALksm#@?
zHLZO<qVGo5%<aYqoF}`Isa4IC&tRcRt<-Y)Tn(ewkAbJL7FN!uGmf@$@AghqO6BRI
z^u{<`(#h0Ey3IFWv58nrMRc>u`IV(yF;5pAFPHO9G?|!)={3=vMwjckN!+i`m5MHv
ziI|tH!=-gm%hF&fXo!~oA2t}4)EPi*3(tKP_irTb2mP8eds*s{xJL|X&g{uT!k<CB
zN%#fCn}z3oYK!ny#9M{`7~=Z*<7x2QME*QtIe(}xfxk)QFCmumhx$wKa{f^N0DhO~
zd>1kMK>8t2KYy^i`uXE_@b&Y@e(?442lvXi0U(QeQ0jp!?j30hko6M?<osbh242n|
z))V0G0zlT!Baril^%QtHe^{Ra9|k}c_osU_tE?{~zDM{!LA+P^R}k+L{_BX@R*?0N
z2o7jgS#Ka77M^FLgNE0CjJsEO+U$_<Y$NyNAbn065uST`Ie*yPH_Q3MJ`4Vc=qw_>
zU-<Kg<@{k^059hcn|3%VI=_IJHU-(ghTs9sD*Mxj<@{m)4tP0#*k1-O=MVeOz&`|l
z?5`o<o*!iYJpws@*#81v&L8#<z&{LteDrHMfB5Jla{lmf9L4~UkNp_etnxAcxbWQf
zbL>IBpF}XBS#u7X6rN|7Dd9hk_=NE6<4NIv12OFg@_hjTeF)_HLj*ILRlZjd%lX6i
z4e)aQ@X?3a4v_Cn1akiHZvvm76w`7Cg43E+e)=Hi9>{+$f~01ZpW`(r{4<C-mLNat
zdY@*M|2v4!2~Qi&8$Q6f_<rFzCiHtyAcKH*0R^fEeoC_{@N<ZNTKK0C|BUeT`IPW~
zfp|gq?;%bbJ{U&Kwt|8j7uEp^a!j(CRY8{L2wy}@{{sb|L$IV-6?_fxvhd$RoD-h?
z;#>uV0to1@pwL?p<Ta~8dl46eXMb4-D8%t8X;y{UhO+P<Kumx_A45>l?2k{tdBHXF
zEx^qHZ9%)+0BuDZ(KhTm`^>)5KC}z%%5jMTZwEN{j{=<Q4*;Co?*eE?&S8!%$C`7P
zbC+Yc0MIu%-kignyN>{zi(>%iCdZ$Codh_pv_E}`e#tSXKhR%?0FLWTz%9V7z-_=*
zU=-l|xC__~+zo_*J-|Hx$9*5LA2<MTUhDw20~X)|CV(vf=P-Tz2tXPJ4g#EWhk(Pt
z2yh?Z2RLUqS2#z4z$6d?rhwalJAlo=G%y2j9@5|9z$suBNB}2*(*WoH+kmscHsB<1
zMTCyg7LEmGjOAMFW`o#oO<=-cmPF6*p+`F|_fZ~g{a6=0WEn!e9FGgs1L0n(VRXtB
zK*}-8_o2tJD)gbpaV+<t$FcrEAA0nMN*{Xt+Har-g9<gA0?hSpmpy26Kl6j@(|P*K
z7}t<4^HTahh_2iMK3vM*4IRJu@`t~UpP84gytu)YH?Re`&deiVYzQ+GO!mc>pLiDA
z2kxH+v=J?UKN!2bVk25W_j#LaaC#d++lzCjIhWilwtC#|G3<v}NZ`!uEDsV5@|`$y
zmb+$>6*TvR!TP4AW0SaGzr@25A9ktRp_5KJi+jN?{R5(RNa7KfzJGJ$Rwb_Ri^gt=
z_es20;&2#u>Wj5>u2_wLO(u1Fwo2}HiFZi6t7|>=p497Ulpp&1bHB;63ur9#`A^*+
zE2Xn|@;1DPTlh>PfAtIIxEH>B`M>`dKY$hvPCTjv$9NQhGxLl#pn(Nwfy*F7e3ZqC
zwBGQ?AA@SSOvC#JUbB%rM*PC(@{8<b@$p=xROGV+4@LObvuZ@Gm24y{ZM?pUUvP6=
zUoYDIVz6p#Jh!O-js#qOvE~oQ8_+Bpy35?UbG;bTx1aTTA$#w^USdN#M$<2XuJxkz
zcO*Jp%;Z<Hcrs|Cn`%S#U)GBdPbBgZVf|UL4P}QxXPXvq{f_vJUnFA@<@LnkV9jV+
z@5bd^ei7gw@6Ge)cviFi;Ovdt^+C@D7Fc5edVYtu)7R+Tu!812iNV?Ph8^VoI>z4y
zJ}?HC5U#)L23i}$0(dAdVBUwj;tszTG@eM{aXxEx{^ct!rg0(5Yb4HEPg$Go4>i)7
zu~u8tSDnJ-*la$|GmAF^uZS8};2((n6R{KXnG3lrUo|?H#7j>h^LJw_mC6<Iu1GqM
z4-Q>XJ*jFfUAe+GqQX=Pub&ih#dPh;s_)X~wH@xFcn!oZt8O>Tnz8Mcvx(`^a>Y5H
zyV$uFy#(r|&{qCarJ}b5tav<e)sH%lp(ShH2W@ZN-DdW*i`SQ4fI45~S>IJ_wOLL)
z9y`7^r&WSKh`L{TZOxQaJQ3pqz@F4sIp?Aio`v+0xd5Hn<Bx`WskXfb+)+IdD=l`+
zSch-{x@VGSqU*S%qbkdpo1C8;UF37)-Kph;<}PZwoJ^NY5x2Yx-9^=ubC?efccuQz
z@orH6<&?X&g&FH8$Frcm%W*DxmgCu2$<%iC9`>I7;!`xboF1(~zg(}qcW#|22OsV8
zp#ICrc=oK9ombHY)1J(-mnZgLPI<+nTeP#MeH!iQ@teXA3iKk~ud1`uORracwv_Sg
zQ?KipzW`LK74Jz(#U8YP{OWSP=epYVv4xJMR`F0q#|)RSpK_=^3M08LTQ{4KD@OTx
zkq7njyTi*z@y2-1&Uw_cAbF!#IcO}$>}>SLSxRk-Lf6~Q=DPgFy#_17RSu>ewgrU!
z%)quW?wIU(4|@0Y<{9hU^Wr9B$ByGWGV9v&b}#1|?Rl?DkMFUfHhz=4T1S4{GhV;!
zu037Pa=aVVe|x+)QR^tjv!K4q`BCpNyV!XLrpo&Em|Y5Ll+*7XvsXEN?lHR*v)X7+
zpL@)n<@CG9>|9WzJ=fqD#q2TBK@UPJ_$41t;%9z56_B~+Q$QUq_%YwBb{;VFbDewD
zuI12VKdQZIKjWp_a~<tf@x;V{1{N4tU|<1lfzZ*yx4AFj-$p}6AOBDH`Vczmtm>>A
zIpDi+EoA;Y(jpop)@gy%RsMNyoz-<xxA2h@-`WfxKT)}{32$Z43SNKV<%jdG)jg1P
z8QXIG)!W9WaQMK6JhZW{a&9o?n}?&b6O+T?;fe9NaYTvf=p4UqvvJ5e$k#>+)mqz`
zZre#bX0Qr*+h2S)L*JsDpRaP!&R3e{=+CZ6-tCYFSw6~f%kPHVrX1zC<$E9xs6tKu
zrP=k9vE_3pa20Z{GA{YHgGh%9wJO``l5eGa2lR7oa(+tdV4;@h{c@N75I;3_5bc4!
zyFCZc9($xvuC~b!ejoBX3$>-Ter;W7mIJOqTYm}crUE|u+z@GI>r;rHE~MN4vOe-8
z<S!>;_`i?rCqE9JpQ{4Rynx^sA45>~Gg<H>l;SH^yBHYxx4#6Q{Q(W_L$J9}V!zxp
z#4<N&ee0!V@chgeXy}s&?l9%-eJ6O@3v}OK<11(1HS(R`fPkMP1C4zd<9oA_-@?yp
z$wT2Y-^3TuzHj7_Imq8lZG71an<6V@<nMV70)Da#l=>Tt`wlI)&hztN4{NcSdX;uI
z@_Fh$V&p@gMQrM|KJ!uV@=VXrAA#Ru^gqE*kBtGKp+9F}<S%?0{5Yi$p<cCJ%k4+E
zf<I0vz6kcuXlKyqe}(pmYOxx*74aiRel`VOo*WqZ7I;&R^*rasBmm0(6Uuqr=)b{!
z$=!<Se+R#4<Zu25c-js$M7h{=+w0&@Qi`FaubO_@qhAF-O(}+-pD>etefTc$tb@@k
zg0GtL|L%w2XDG!NkzgO|HZ8YLu<V!?tEJZvf6nNy{tEcGk&mPi>&IU3wM_Qwl#wrg
Q2;(C4e(`@GV}0s>0o04ocmMzZ

literal 0
HcmV?d00001

diff --git a/AppleDL/AppleDL.pbxproj/.cvsignore b/AppleDL/AppleDL.pbxproj/.cvsignore
new file mode 100644
index 00000000..0857ac37
--- /dev/null
+++ b/AppleDL/AppleDL.pbxproj/.cvsignore
@@ -0,0 +1 @@
+*.pbxuser
diff --git a/AppleDL/AppleDL.pbxproj/project.pbxproj b/AppleDL/AppleDL.pbxproj/project.pbxproj
new file mode 100644
index 00000000..140f280b
--- /dev/null
+++ b/AppleDL/AppleDL.pbxproj/project.pbxproj
@@ -0,0 +1,247 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 32;
+	objects = {
+		023E3605001F8F6B11CD283A = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OTHER_LDFLAGS = "\U0001-dylib_file \"$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Security:$(SYMROOT)/Security.framework/Versions/A/Security\"";
+			};
+			isa = PBXBuildStyle;
+			name = "Build Folder";
+		};
+		0FD07C9DFE8A174411CD283A = {
+			buildStyles = (
+				1B60AA6DFFD84BFD11CD296C,
+				1B60AA6EFFD84BFD11CD296C,
+				023E3605001F8F6B11CD283A,
+			);
+			isa = PBXProject;
+			mainGroup = 0FD07C9EFE8A174411CD283A;
+			projectDirPath = .;
+			targets = (
+				0FD07CA2FE8A183A11CD283A,
+			);
+		};
+		0FD07C9EFE8A174411CD283A = {
+			children = (
+				0FD07CAAFE8A18AF11CD283A,
+				2B8B5BBCFFF3E33011CD283A,
+				0FD07CBFFE8A1A0011CD283A,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		0FD07CA2FE8A183A11CD283A = {
+			buildPhases = (
+				0FD07CA3FE8A183A11CD283A,
+				0FD07CA4FE8A183A11CD283A,
+				0FD07CA5FE8A183A11CD283A,
+				0FD07CA6FE8A183A11CD283A,
+				0FD07CA7FE8A183A11CD283A,
+			);
+			buildSettings = {
+				DEPLOYMENT_OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				EXPORTED_SYMBOLS_FILE = cssmplugin.exp;
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-bundle -undefined error -lstdc++";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleFileDL;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = bundle;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXBundleTarget;
+			name = AppleFileDL;
+			productInstallPath = "\"$(SYSTEM_LIBRARY_DIR)/Security\"";
+			productName = AppleFileDL;
+			productReference = 1B60AA6CFFD84BFD11CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleExecutable</key>
+	<string>AppleFileDL</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.applefiledl</string>
+	<key>CFBundleName</key>
+	<string>AppleFileDL</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>AppleFileDL 1.0</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		0FD07CA3FE8A183A11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				2295BBC2FEEF08A311CD28CA,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0FD07CA4FE8A183A11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		0FD07CA5FE8A183A11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				2295BBC3FEEF08A311CD28CA,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0FD07CA6FE8A183A11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				2B8B5BBEFFF3E33011CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0FD07CA7FE8A183A11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0FD07CAAFE8A18AF11CD283A = {
+			children = (
+				2295BBC0FEEF08A311CD28CA,
+				2295BBC1FEEF08A311CD28CA,
+				1DF71D5DFF30EDAB11CD283A,
+				0FD07CB3FE8A18AF11CD283A,
+				0FD07CB4FE8A18AF11CD283A,
+				0FD07CB5FE8A18AF11CD283A,
+			);
+			isa = PBXGroup;
+			name = AppleDL;
+			path = "";
+			refType = 4;
+		};
+		0FD07CB3FE8A18AF11CD283A = {
+			isa = PBXFileReference;
+			path = FORMAT;
+			refType = 4;
+		};
+		0FD07CB4FE8A18AF11CD283A = {
+			isa = PBXFileReference;
+			path = ISSUES;
+			refType = 4;
+		};
+		0FD07CB5FE8A18AF11CD283A = {
+			isa = PBXFileReference;
+			path = TODO;
+			refType = 4;
+		};
+		0FD07CBFFE8A1A0011CD283A = {
+			children = (
+				1B60AA6CFFD84BFD11CD296C,
+			);
+			isa = PBXGroup;
+			name = Products;
+			path = "";
+			refType = 3;
+		};
+		1B60AA6CFFD84BFD11CD296C = {
+			isa = PBXBundleReference;
+			path = AppleFileDL.bundle;
+			refType = 3;
+		};
+		1B60AA6DFFD84BFD11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		1B60AA6EFFD84BFD11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		1DF71D5DFF30EDAB11CD283A = {
+			isa = PBXFileReference;
+			path = cssmplugin.exp;
+			refType = 4;
+		};
+		2295BBC0FEEF08A311CD28CA = {
+			isa = PBXFileReference;
+			path = AppleFileDL.cpp;
+			refType = 4;
+		};
+		2295BBC1FEEF08A311CD28CA = {
+			isa = PBXFileReference;
+			path = AppleFileDL.h;
+			refType = 4;
+		};
+		2295BBC2FEEF08A311CD28CA = {
+			fileRef = 2295BBC1FEEF08A311CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2295BBC3FEEF08A311CD28CA = {
+			fileRef = 2295BBC0FEEF08A311CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		2B8B5BBCFFF3E33011CD283A = {
+			children = (
+				2B8B5BBDFFF3E33011CD283A,
+			);
+			isa = PBXGroup;
+			name = "External Frameworks";
+			refType = 4;
+		};
+		2B8B5BBDFFF3E33011CD283A = {
+			isa = PBXFrameworkReference;
+			path = Security.framework;
+			refType = 3;
+		};
+		2B8B5BBEFFF3E33011CD283A = {
+			fileRef = 2B8B5BBDFFF3E33011CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+	};
+	rootObject = 0FD07C9DFE8A174411CD283A;
+}
diff --git a/AppleDL/AppleDLPlugin.cpp b/AppleDL/AppleDLPlugin.cpp
new file mode 100644
index 00000000..fe86ad96
--- /dev/null
+++ b/AppleDL/AppleDLPlugin.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 obtai
+n  
+ * 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.
+ */
+
+  
+// 
+// Produce the "genuine plugin version" of the Apple "file DL"
+//
+#include <AppleFileDL.h>
+
+
+//
+// Create the plugin object and generate the C layer hookup
+//
+ModuleNexus<AppleFileDL> plugin;
+
+#include <Security/pluginspi.h>
diff --git a/AppleDL/AppleFileDL.cpp b/AppleDL/AppleFileDL.cpp
new file mode 100644
index 00000000..11ac1847
--- /dev/null
+++ b/AppleDL/AppleFileDL.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleFileDL.cpp - File Based DL plug-in module.
+//
+#include "AppleFileDL.h"
+
+#include <Security/DLsession.h>
+
+
+// Names and IDs of tables used in a DL database
+
+static const AppleDatabaseTableName kTableNames[] = {
+	{ CSSM_DL_DB_SCHEMA_INFO, "CSSM_DL_DB_SCHEMA_INFO" },
+	{ CSSM_DL_DB_SCHEMA_ATTRIBUTES, "CSSM_DL_DB_SCHEMA_ATTRIBUTES" },
+	{ CSSM_DL_DB_SCHEMA_INDEXES, "CSSM_DL_DB_SCHEMA_INDEXES" },
+	{ CSSM_DL_DB_SCHEMA_PARSING_MODULE, "CSSM_DL_DB_SCHEMA_PARSING_MODULE" },
+	{ CSSM_DL_DB_RECORD_CERT, "CSSM_DL_DB_RECORD_CERT" },
+	{ CSSM_DL_DB_RECORD_CRL, "CSSM_DL_DB_RECORD_CRL" },
+	{ CSSM_DL_DB_RECORD_POLICY, "CSSM_DL_DB_RECORD_POLICY" },
+	{ CSSM_DL_DB_RECORD_GENERIC, "CSSM_DL_DB_RECORD_GENERIC" },
+	{ CSSM_DL_DB_RECORD_PUBLIC_KEY, "CSSM_DL_DB_RECORD_PUBLIC_KEY" },
+	{ CSSM_DL_DB_RECORD_PRIVATE_KEY, "CSSM_DL_DB_RECORD_PRIVATE_KEY" },
+	{ CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "CSSM_DL_DB_RECORD_SYMMETRIC_KEY" },
+	{ ~0UL, NULL }
+};
+
+//
+// Make and break the plugin object
+//
+AppleFileDL::AppleFileDL()
+	:	mDatabaseManager(kTableNames)
+{
+}
+
+AppleFileDL::~AppleFileDL()
+{
+}
+
+
+//
+// Create a new plugin session, our way
+//
+PluginSession *AppleFileDL::makeSession(CSSM_MODULE_HANDLE handle,
+                                       const CSSM_VERSION &version,
+                                       uint32 subserviceId,
+                                       CSSM_SERVICE_TYPE subserviceType,
+                                       CSSM_ATTACH_FLAGS attachFlags,
+                                       const CSSM_UPCALLS &upcalls)
+{
+    switch (subserviceType) {
+        case CSSM_SERVICE_DL:
+            return new DLPluginSession(handle,
+                                       *this,
+                                       version,
+                                       subserviceId,
+                                       subserviceType,
+                                       attachFlags,
+                                       upcalls,
+                                       mDatabaseManager);
+        default:
+            CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
+            return 0;	// placebo
+    }
+}
diff --git a/AppleDL/AppleFileDL.h b/AppleDL/AppleFileDL.h
new file mode 100644
index 00000000..498ae8b2
--- /dev/null
+++ b/AppleDL/AppleFileDL.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleFileDL.h - File Based DL plug-in module.
+//
+#ifndef _H_APPLEFILEDL
+#define _H_APPLEFILEDL
+
+#include <Security/cssmplugin.h>
+#include <Security/AppleDatabase.h>
+
+class AppleFileDL : public CssmPlugin
+{
+	NOCOPY(AppleFileDL)
+public:
+    AppleFileDL();
+    ~AppleFileDL();
+
+    PluginSession *makeSession(CSSM_MODULE_HANDLE handle,
+                               const CSSM_VERSION &version,
+                               uint32 subserviceId,
+                               CSSM_SERVICE_TYPE subserviceType,
+                               CSSM_ATTACH_FLAGS attachFlags,
+                               const CSSM_UPCALLS &upcalls);
+private:
+    AppleDatabaseManager mDatabaseManager;
+};
+
+
+#endif //_H_APPLEFILEDL
diff --git a/AppleDL/CVSVersionInfo.txt b/AppleDL/CVSVersionInfo.txt
new file mode 100644
index 00000000..7f386aa1
--- /dev/null
+++ b/AppleDL/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:52 mb Exp $
+# $Name: Security-28 $
+ProjectName: AppleDL
+ProjectVersion: 13
diff --git a/AppleDL/FORMAT b/AppleDL/FORMAT
new file mode 100644
index 00000000..bae9292f
--- /dev/null
+++ b/AppleDL/FORMAT
@@ -0,0 +1,153 @@
+Some notes of the format of DL files:
+
+
+
+DL file format:
+
+All offsets are relative to the start of the section they are in.
+All fileds are uint32 (4 bytes) unless otherwise specified.  All other fields are aligned on 4 bytes boundries.
+
+Header Section
+	Magic
+	File Format Version Number
+	Auth Section Offset
+	Schema Section Offset
+
+Auth Section
+	Auth Info Size
+	Auth Info Data
+
+Schema Section					# This section is always read entirely into memory
+	Schema Section Size (uint32)
+	Tables
+		Table Count (uint32)
+		Table Offset 0			# Relative to start of Schema Section
+		Table Offset 1
+		...
+		Table Offset N
+
+# Information about parsing modules is read directly from the meta tables
+Table Section
+	Table Section Size
+	Table ID (uint32)
+	Records Count				# Number of Records in record section.
+	Record 0 Offset				# Relative to start of Table Section.
+	Index SubSection Offset		# Relative to start of Table Section
+	Head of Free List			# Table Section relative first free
+								# recordNumber slot (with bit 0 set)
+								# Or 0 if there are no free records
+	Record Number Count			# Start of range of unused record numbers
+	Record 0 offset				# Relative to start of Table Section.
+	Record 1 offset
+	Record 2 freelist			# If Bit zero is set this is Table Section
+								# relative offset to next free recordNumber
+								# 0 indicates the last free record slot.
+	...
+	Record n offset
+	Record
+		Record Size			# Rounded up to nearest mulitple of 4
+		Record Number
+		Creation File Version
+		Record Version
+		Data Size
+		SemanticInformation
+		Attribute 0 Offset
+		Attribute 1 Offset
+		Attribute 2 Offset
+		...
+		Attribute m Offset
+		Data
+			Data	
+		Attribute 0
+			Size
+			Data
+		Attribute 1
+			Value
+		...
+		Attribute m
+			Value Count
+				Value 0
+				Value 1
+				...
+				Value p
+	Record
+	...
+	Record
+	Index SubSection
+		Index SubSection Size
+		Index TOC			# This is part of the Schema
+			Record Type
+			Attribute Type
+			Index Offset
+		Index 1
+			Index Size
+			Index Offsets
+				Index Offset Count
+				Index Data 1 Offset
+				Index Data 2 Offset
+				...
+				Index Data m OFFSET
+			Index Data
+				Index Data 1
+					Record Offset
+					Attribute Size
+					Attribute Data
+				Index Data 2
+				...
+				Index Data N			
+		Index 2
+		...
+		Index n
+
+Version Section		# Maintained by AtomicFile code
+	4 byte version number
+
+old Schema Section				# This section is always read entirely into memory
+	Schema Section Size (uint32)
+	Releations
+		Relation Count (uint32)
+        Relation
+            Relation ID (uint32)
+            Record Section Offset
+            Relation Name Size
+            Relation Name Data
+			Attributes
+                Attribute Count (uint32)
+                Attribute
+                    Releation ID (uint32)
+                    Attribute ID (uint32)
+                    Attribute Format (uint32)
+                    Attribute Name Format (uint32)
+                    Attribute Name Size
+                    Attribute Name Data
+                    Attribute Name ID Size
+                    Attribute Name ID Data
+                    ParsingModule
+                        Parsion Module Present (bool)
+                        Module ID (GUID)
+                        SSID (uint32)
+                        SubService Type (uint32)
+                        Addin Version Major (uint32)
+                        Addin Version Minor (uint32)
+                Attribute
+                ...
+                Attribute
+            Indexes
+                Index Count (uint32)
+                Index
+                    Relation ID (uint32)
+                    Index ID (uint32)
+                    Index Type (uint32)
+                    Indexed Data Location (uint32)
+                    Index Attribute Count (uint32)
+                        Attribute ID (uint32)
+                        Attribute ID (uint32)
+                        ...
+                        Attribute ID (uint32)
+                Index
+                ...
+                Index
+        Relation
+        ...
+        Relation
+
diff --git a/AppleDL/ISSUES b/AppleDL/ISSUES
new file mode 100644
index 00000000..4dd01a31
--- /dev/null
+++ b/AppleDL/ISSUES
@@ -0,0 +1,61 @@
+ISSUES with cdsa verson 2 Datastore Library
+
+DL_DataGetFromUniqueRecordId
+
+* Which value of CSSM_QUERYFLAGS should this call assume?  In other words if fetching the Data of a Key item should this call return a reference key or a raw key.
+
+* What if the record has been modified by another caller since it was last retrieved.  This call should be able to update the CSSM_UNIQUE_RECORD_PTR passed in.  Or otherwise indicate that the record that a particular attribute is being requested for has changed.
+
+DL_DbCreate v/s DL_CreateRelation
+
+* Why not change CSSM_DBINFO to use the same data structures as DL_CreateRelation does.  Currently CSSM_DBINFO uses CSSM_DB_RECORD_ATTRIBUTE_INFO, CSSM_DB_RECORD_INDEX_INFO and CSSM_DB_PARSING_MODULE_INFO the first 2 contains less information than the CSSM_DB_SCHEMA_ATTRIBUTE_INFO and CSSM_DB_SCHEMA_INDEX_INFO fields used by DL_CreateRelation.  There is no equivalent for the information provided at Database creation time containd in the CSSM_DB_PARSING_MODULE_INFO inside the CSSM_DBINFO.
+
+I purpose we change everything to using the same data structures (CSSM_DB_SCHEMA_ATTRIBUTE_INFO and CSSM_DB_SCHEMA_INDEX_INFO since they are richer).  This would make the CSSM_DB_RECORD_ATTRIBUTE_INFO structure obsolete.
+
+Also note that CSSM_DB_SCHEMA_ATTRIBUTE_INFO does not contain an CSSM_DB_ATTRIBUTE_NAME_FORMAT field and neither should the CSSM_DB_SCHEMA_ATTRIBUTE_INFO relation since each attribute will have the 3 types of names given at creation time.  The CSSM_DB_ATTRIBUTE_NAME_FORMAT need only be used to retrieve an attribute using a particular name format.
+
+DL_DataGetFirst
+
+* CSSM_SELECTION_PREDICATE (which is part of CSSM_QUERY) contains a CSSM_DB_ATTRIBUTE_DATA.  What are the intended semantics for a CSSM_SELECTION_PREDICATE containing a CSSM_DB_ATTRIBUTE_DATA with NumberOfValues not equal to 1?
+
+DL_DataGetFirst, DL_DataGetNext and DL_DataGetFromUniqueRecordId
+
+* The AttributeFormat specified when retrieving an attribute must match that in the schema.
+	-or-
+* When retrieving an attribute the AttributeFormat for that attribute is returned.
+
+From the description of these calls it is not clear which of the two options above is the intended one.  I vote for the second option.
+
+DL_DataInsert and DL_DataModify
+
+* The AttributeFormat specified when specifying an attribute must match that in the schema otherwise CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT is returned.
+
+This should be a added to the description of these calls.
+
+DL_DataDelete
+
+* From the description of this function it would seem that is does an implicit CSSM_DL_FreeUniqueRecord().  Is this correct?
+
+
+General
+
+* What is the difference between a single valued and multi-valued attribute?  How do you indicate that an attribute is to be multi-valued?
+
+These terms are used in the description of DL_DataModify and in other places.  However there is nothing in the schema to indicate whether an attribute is single valued or multi valued.  If an attribute has one value and DL_DataModify is called with the CSSM_DB_MODIFY_ATTRIBUTE_ADD ModifyMode it is unclear whether the current value should be replaced with a new one or the passed in value should be added to the values of the attribute (bring the NumberOfValues for that attribute up to 2).
+
+How is this supposed to (or intended to) work?
+
+Error codes
+
+* When for example passing a value for a CSSM_DB_ATTRIBUTE_FORMAT or CSSM_DB_ATTRIBUTE_FORMAT_UINT32 with a length other than 1 2 or 4 we need an error code to indicate this.  I suggest something like:
+
+    #define CSSMERR_DL_INVALID_VALUE (CSSM_DL_BASE_DL_ERROR + 47)
+
+	A value specified for an attribute was not of the correct form.
+
+
+New Issues:
+
+Page 471:
+CSSM_DB_CONJUNCTIVE
+What is the intented semantic of CSSM_DB_NONE?  It only makes sense when a single SelectionPredicate is specified in which case using either CSSM_DB_AND or CSSM_DB_OR would do just fine instead.
diff --git a/AppleDL/TODO b/AppleDL/TODO
new file mode 100644
index 00000000..cdbf0a15
--- /dev/null
+++ b/AppleDL/TODO
@@ -0,0 +1,49 @@
+* Make the pAttributeInfo and pIndexInfo arguments to CSSM_DL_CreateRelation optional.
+
+* Enhance POD wrappers and use them everywhere (DONE for insert still needs work for get).
+
+* Implement Indexes
+
+* Implement unique index checks for dataInsert and dataModify
+
+* Add unique index info to UNIQUE_RECORD structures.
+
+* Implement KEY items (AppleCSPDL).
+
+* Clean up usage of ReadSection::at(uint32) vs. ReadSection::operator[](uint32)
+
+* Fix AtomicFile for NFS and ASIP (Use alternative locking mechanism).
+
+* Implement ACL evaluation for Db access.
+
+* Implement ACL APIs.
+
+* Make DbModifier thread safe again.
+
+* Cleanup Query objects when DbContext is destroyed (register them with the context).
+
+* What if we open a DB that is being created?  Currently we get back DL_DATABASE_CORRUPT
+  should this become DL_DATABASE_DOES_NOT_EXIST?
+
+* When using CssmOid attribute names make sure to deep copy the CssmOids data (DONE).
+
+* Implement SelectionPredicates completely
+  To make DataGetFirst and DataGetNext actually work (DONE).
+
+* Implement CreateRelation (DONE)
+
+* Implement DataModify (DONE, now with correct semantics -- CB)
+
+* In DataModify, check that RecordType matches that in the UniqueRecordId.
+
+* Store index data when creating tables and databases.
+
+* Add write buffering in AtomicFile to increase performance; flush buffer before seek.
+
+* Make sure that automatically-assigned attribute ids don't shadow ones passed in explicitly.
+
+* Performance: Avoid reconstructing DbVersion after a write (w/o a schema change) when we
+  could derive it from the DbModifier. Only if version is as expected (i.e. no other writes
+  in the meantime)
+
+* Add fsync() to make sure AtomicFile is written before rename.
diff --git a/AppleDL/cssmplugin.exp b/AppleDL/cssmplugin.exp
new file mode 100644
index 00000000..f5046fbf
--- /dev/null
+++ b/AppleDL/cssmplugin.exp
@@ -0,0 +1,4 @@
+_CSSM_SPI_ModuleLoad
+_CSSM_SPI_ModuleAttach
+_CSSM_SPI_ModuleDetach
+_CSSM_SPI_ModuleUnload
diff --git a/AppleX509CL/.cvsignore b/AppleX509CL/.cvsignore
new file mode 100644
index 00000000..8be42d6a
--- /dev/null
+++ b/AppleX509CL/.cvsignore
@@ -0,0 +1,2 @@
+PBUserInfo
+AppleX509CL?Data
diff --git a/AppleX509CL/AppleX509CL.cpp b/AppleX509CL/AppleX509CL.cpp
new file mode 100644
index 00000000..15a693b9
--- /dev/null
+++ b/AppleX509CL/AppleX509CL.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleX509CL.cpp - File Based X.509 Certificate Library plug-in module.
+//
+#include "AppleX509CL.h"
+
+#include "AppleX509CLSession.h"
+
+
+//
+// Make and break the plugin object
+//
+AppleX509CL::AppleX509CL()
+{
+}
+
+AppleX509CL::~AppleX509CL()
+{
+}
+
+
+//
+// Create a new plugin session, our way
+//
+PluginSession *AppleX509CL::makeSession(
+	CSSM_MODULE_HANDLE handle,
+	const CSSM_VERSION &version,
+	uint32 subserviceId,
+	CSSM_SERVICE_TYPE subserviceType,
+	CSSM_ATTACH_FLAGS attachFlags,
+	const CSSM_UPCALLS &upcalls)
+{
+    switch (subserviceType) {
+        case CSSM_SERVICE_CL:
+            return new AppleX509CLSession(handle,
+                                       *this,
+                                       version,
+                                       subserviceId,
+                                       subserviceType,
+                                       attachFlags,
+                                       upcalls);
+        default:
+            CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
+            return 0;	// placebo
+    }
+}
diff --git a/AppleX509CL/AppleX509CL.h b/AppleX509CL/AppleX509CL.h
new file mode 100644
index 00000000..09ed0ae5
--- /dev/null
+++ b/AppleX509CL/AppleX509CL.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleX509CL.h - File Based CSP/DL plug-in module.
+//
+#ifndef _H_APPLEX509CL
+#define _H_APPLEX509CL
+
+#include <Security/cssmplugin.h>
+#include <Security/pluginsession.h>
+
+class AppleX509CL : public CssmPlugin
+{
+public:
+    AppleX509CL();
+    ~AppleX509CL();
+
+    PluginSession *makeSession(
+			CSSM_MODULE_HANDLE handle,
+			const CSSM_VERSION &version,
+			uint32 subserviceId,
+			CSSM_SERVICE_TYPE subserviceType,
+			CSSM_ATTACH_FLAGS attachFlags,
+			const CSSM_UPCALLS &upcalls);
+private:
+    // Don't copy AppleX509CL
+    AppleX509CL(const AppleX509CL&);
+    void operator=(const AppleX509CL&);
+};
+
+
+#endif //_H_APPLEX509CL
diff --git a/AppleX509CL/AppleX509CL.mcp b/AppleX509CL/AppleX509CL.mcp
new file mode 100644
index 0000000000000000000000000000000000000000..687e67756a3914308041ea7b6158945697e6e842
GIT binary patch
literal 103293
zcmeI531Ah~)yHRELN*rJ1VoVsE{H$^3J7r{BrL&1A_2jz<dHlekgZ8js#a55t#;Mc
zwsyC6QM=mKYHO>dR$FT~m$tTc5w~u%ZeJI>Siax6_s)AW@6Gbi)S{USXYT)<d*;l&
z=bm%t&dn^X-Q69QWffVLeUxQi+GyFA?XawoW$@l=Cu}mEYP;Lg>r=hG?cKe}rrz#t
z>DGRyXo%#A5tfxmTGsOAmbH>L%Wtd2(k9w$@{}=#otSphZt!?0VR+NYixSg5b|3jn
zs2Dt#d=WIvvW^ymu7FA)No%3f#I);1lZ)OmtK@fICGUpHAxV8ug+i8f3Hfm3o5-(*
zMpz|}-$VWhXe1=*7HE`0mL+8eAU{C<5H#8<d3rbb6VRB8_m=dKKL?H7LtV-L0ga;x
z@4#2&nB#R@?1R7uLL^(-H9<kkUPwN%=&5^7fRD|rNgV4wa5Gr;!HD)*<ddcK;4U@?
z3j$xr<`4xf`)%Y?tdc29;J+7qD0Be$3*=KRd(0T{o#5nj68K^8H1YxHFW~9cp*Fpg
z5W5}*krM1<9S$7@M%FsQvd?P=&jlYzdy!3?44wgz5*yec`zgv3+rZM!Bv|Ts^rE?o
zXlvqf@GR?=zX)IKKYQ=qzthIVwct5Wg8yG5uY_oE;(qd~;;%e+Hu#U=xrqh$?h+RP
z&%@-;fX9Q6fk;K7<5&f)qGjas4So&z0)x*b7rT>+u3&Q<^;rV`5O@*wnFRhkcrkPY
zco%s!gx!iBBtIUaZAHH&KLI)#{5<)I5XUbbPJR-E9g3wN#75MqSn9O|;@HLF!!;18
zcq5yo3R=bIk=GjhPVzc~uP2xGkc!1V;wz-$yV-~?Qt^-3U`t8Gzh+afpjG@Q@>K@^
zll&Bohe<sf43>H}8Z7lZ)nLh28{9_TWU%<#X$F6se2u|3lQ$cD7x`L)r61QB{3!Y9
z20u-{-r#?eiw}`XMzA?UL90ak{Y-<gwI%UDDv`d$FC>+SEzeQVDv^3gf0Ig5Y{b5#
zl1?@)g1{HCkup+=_`oIwt&*$ATMhm&xwM&7@@Y0{1+9`>$u}GP1M)2f|AKt0!G9!g
zH~6pQ+YEkze7nY_733WTPbQc84V7fm&^1K6O=1XA&1PF9pcG0b*gzvyW;^2?zjBk_
zSM9@qB!kjOw4&42YQ?GpD4i!K2a>OqIZ_EU9IAlIpmJygG!l&^&~T^%Duc?Q5zt5(
zqb}YnYV)>b`uNg7kgg@_6p)P&Dh^ncIyY6@k?QM9_f?+X-Xpr)>CF13<f@v}Yv2{L
zOOfoRm8dNmwb7&;qCV=}DE5%D;mF(8t($j&l>leF!Aa6S(=d)P%xR_^j{}!;5PCPF
z-^$mlUTsDQU8&*~Yu1?|#wspt?%vVcn(h--%j+AKp?0LnN4VsQ%Gad(GLn|7#2!_1
zYIA+Ep?y<ts<+*vsKh85?h;RoY)rL!q>GGHg~`iIF0C7B`g8<4txTud(!G6^Ci-<-
z%+{Dm`b{X4{Cq!}m)YGH=mRXFY$+uDFXPT^NY1AXkc|Ce;6_Nsb~z^!8S0!V=Q}ws
zPKRX7uZLDaGa)%w%z_Ssj)ulVGS18SM#eK4$Cg3jf8t>>w#|X6plOh#k&v7(W$c%6
zUdDGhZ^-y5=YTp$&JofIImgPFUky!!WXzYrVHC6+S^>#8KNpg7znlveLB~OdK$9Rj
z?@ob^gd{djf|8J&PfmoULNe~kx$huo26PleRLa~*jYFf!+aWp6oC8VEkAtMA<s4H3
z$@!%gN<%GB3fcsXfm)$5s0}(0ngDHv#On`-j)2BOgO{lNK8z{*CM}~%oQAXo8k_5v
zjj8YIPxp4E`;*Id_H=ajrhE6zB=u>%TV;Bu#7vxqoCRcvk4o9;PO<mQ8MUKtd4ki2
zoRnUAlDb2~QkC61`a{$$kuo{&$j0RB>?`f^#0A1MDcj0IY!VN^j@^cA9uL4nw(AG6
z;jii;^;LYjh))267zD3ORq+YnmDz9mRjrq%`r2EQYx%?GrtY1|#vL8~?bh=4-oE~1
zb9zf>x~t!+*7I8y&yw|>J>9+i$%Ttfu^OA!yMHcCb#!!hcO_S*J9@0f^~u_*+F7%-
z;QC}!s;@QGp?<ANpKmoSTkhS}U4w;-wp-PvI$$-mrjD)cnL0K#)mq+K3&&MG`I)JL
z`C+Oczo44FPHRK$>gAbwD1NqD^3$mVSXH9Ay`$rG(#*cfR?GFHx39O=QrE$oQ>|&L
zVKt`ux2n9kA-QHpSATnFT9i1f+Dgx_S+lagQ?09;D?73(Fm!Tx>ZtkcRg2nYW)v8m
z6lPepl^M~EZc#eHr^IW$<uz-q>c({MmUMD8*D+4JVXJoM^o9B9SjDu}|LD#2tJiIi
z<7eurIZpeXL%I8$GItfMYHwxhmMvYk0#DkW;{sW}?+&8XPm%Chwq4zv@h)nMH9Raw
zH%=eG_uV01w^pQD=+)$N(EPpgIlAXObrRN!RA*Z5KuFehcb%K=WrfCC-jUwPoe1fk
z-fq^>`?`CrrR{x$tB2KyziLN1>X`PdyE#6TWorMHKF{#vM_qc;jx9+~%Ou!*`69o(
zy^B#HU*3;TyK*FJdU`tATT}h*-CYv=W?>&~u7&%YRsU*N*tS~kUn+>Jm$r9RYa>u?
z<+E9qD@;vq*LHVyc6U{KLf>2D3<T9CVx2sRdUc?j(IIm*Z<uHci6tA_ySCGtwLALy
zyE~Joq+fSlcW+ytRnsb+$}ro%wa;3cB9dkF?(c8!+S12h-jT+1Jw58z(jDy`ZLHSy
z_on(R)nQxGy-B@~r3Y==)x$m<MvdXz$I_)0t!?5EUFi<1eob<955rpf`AC_OHM5ub
zo!L$5E#9~y-KD*uy-)te)wxLy;cApX&J2p>+%p4@q1qgkQwNGn-9&mtNB1TiC|ec%
zXQJfV-ZX#W$u!Ow*=kDnb{JKh9psl)El!l)uwd@u+6K#oD_eVd+`svgTpxa>*!$Jl
zdr&GPe@>A<)u{aDFE8d#F6X`@S95&5k!z75`CI;!xRgzHjZ!ZlY`^)-$8Fua_xgVf
zNvp(-77NtzH^h9uxNhEqd-pyde=?2JP_)1>Tq5fgL(u}N&D<|A(KFReW-luWG|I`O
znx-c1-mnKY>?&}l5HZo0DbD|c6h-zxrhIS!j!>Sx)O=AoGggq>Zi?#~R%~e9-rgoN
z#`Voy%}L^KY@RzGwx#m^E-iOcHLgEX-(qB2!?<}{Zeo(X&Fwtg^&t}?VdzXjDO7@T
zB21_|YqF)m$f#BVE_FWj-&eiC$JF=zgq6FhL#2vxu8`GQP<8ILhW9F3%XqFo`~-5Z
zN&IATu2b@trK&yGE`BQHqSCq42r930Uw#A$nd_{eV(0S2uRP}(Dp(|Qf#fT)yphKE
zc8KTV%Wq$~k5E=}dRWW}EDvjfQgC{s@6LJ%(;=)c2K^3^drcT36KV#z$_wjIDUa+>
z5en&0DVFO_-#SW}d440HJbQiWC*Zke^%Gd%-nB;BXfA90M0PG(7-|G54{4tiJ8dvI
zD=(}GG_?2SItc4(5dkj}A>l5?;lVBvVWBSNA%QN%!C~%{hWLad;%hOd(6N`dJESx;
zyt4uUUabWDLR$(#0$YlM!#YzMTy6i5mK~!4T4ch**(DLu?BGyV`-cazBNEtY{z2^Q
z7Hk*x3kqP_IV60gI5c=gAUJfL(!dtE!xlI6{{6!*NOL4|gEXhuCrEQ7@`5y{JU2*l
zigSY0r!+T6eMGX>@hNomYEEf>kopR^y){=L6Qnr>xj~v!oD-yerNPy91!>NXzCoHJ
z;}fL*5+Tjb3DVsCeS*|SB(T$5LF%(xuw8P4G-v1BAk8Vx57HcgoFMfn4Qx?Pkh=bm
zN}c_JG)E#gNOOvPf;2}WFGzFBbAvReI44MbN^^tMM<i<<pF&r!=9K0Ksjq<BTXO|6
zL7G#L8>BhKIYH`I8eDBxkml^@8>BfhK0)d)5z_3OAkE$1CrEun0z1tWq&~X^+a)(h
zb9T-R(wyS_Ak7iT2~wZZz!n7uDSuRq2vU&<2~sHz4^oi`3sNZ$2~sHz4pOHyBuE_*
zU+Xx9{=F)tp+TAz2=G=V;1{G)5E7(P92}&X(%@?Q2dV5B6{I2)9;7abkY)!5soFn0
zNF9;DPV)~^XSZOxgaoPV91^5b92%q|5FDgVX<&<jgVb3jjk+?;%7p}MRwz7dvvOg<
zo0SR);jB<_AbVv(!r3e6YfZ0+zb|BELIXTkEWqDgVt&D%Ee;9!tWZ>hW+lVpG*2$F
z_Q5gh(iI-LUcrd|@sDD!im3hziRi4Nkhs=DXo)xxX5}KIOOzE7T_P79T_P13T_O|}
zU5-p-bUA_{z2}I8^^V9C5M5cZQ2$h7!O<nfk<leWg+-T077|@9xyafh8?cO-^(~Pp
zsDDH-qJKmre_hvmtf>A&N6_+6R*@&Vw0)i1Y4ORtxXPFCL{xrpZY<?Xc%vx4+!H_f
z#qP-QFZJ|^zliA#|3b&k`K37#5+soEE*}9M75N38c*rl-9QR)`@?~;kAW$Nte&UDD
z-!Odk&-HkJkwEJ@UhcnJu-!eLoxgL4Pix1I_Ux=&h<|5=!o55z7v}3(sSuCP3I+SU
zS0=>!y@I~I<Q4Jnk*rK;JmiW6c%4hkFE+BpArX=l(#{baCt1nxXvvd{tbK6gxO9cb
zk5@3FfBa*~t0JoZLgFf`C^EXx5^>(p%0w<Qx<sgu=n}c;=n|>O=n|o*=yGHtqstKt
z={-jztan7FfauDKh5Dxw3yv-+j*Ko5DlEE0vXJO<$wk&4*?{v>*0)5ap#BlTi2e}~
znU8r-Hr``J^&dL2^RXaBA<@PD5pg9FArU3T;jttVVNoRIA@L){!I9&XhV+Re;@cZe
zp}(D_G&Dl80s-Eo1pJ~x3PR#RilZVyWWr;>B@t3Tqyqe2?H}&(j!2+&MSH%NJG%wj
z9f=^%mYqX<T9(#wZ_@IHhDe0?v=oQ?v`B>cw3LVVv=j&Xv{M@5(~gL*)ty3r+e&Gu
zPiF-Jd`1cQ`Lq;-__P#9`LxJ{`?O0Uq<-Rc{?{04|8SpnL;|fV+Vg$d*)7=aAwDfT
zhxl}Ms$?EhQ;!{ay*ewSA8rd3asM?TNR5*5Z%y`C&R-USl;o_D2Z^~?%EM%Q`y^W%
z_o}&{8W}pGEGRM&78H>v3ua`(ESM4E?!ut@7GOb96J<e1Cd7h{h<}Y4u|jMorGZwH
z!eD!4N`sH<?`5)MsC7gj*e*_~uSJ|f|2m1Kg8fKJ18pIN!M4bh1|Qeo7P4cgEkq#L
z7EY<JEu2E9PT0op8P>eBZjhYk+#4j6dj<}Y^PY!;q&#QiAR*y9XN@o!&zU()&{#7}
zB+{npnbXYuutBQyDLr#W3>4Gn?Vw`M**i$c?YyBfQB89kIY@~f5ZwzcL6W&sh6uSx
zGvV-&jvz7xIf4jAID&}Cgd(usQf_X$4w1=Dn1h5oQ;Z;?oM9wL%srTd$wahW)HrQZ
zHqC!%K5t+NlJg8KK|;9$OOTv*U<s1)3@kxHVjgE;36t^oQ<$K!X_!c)O}zt4kgA-4
zB~VNcEJ4Mdfh9=DJ+OqzL^aJBSb~(~4=h2FxdTgtTxMVilp~O%96{~tekdnQS%f3V
zt}?KMsfe;B`(_80AVr>mB}gb|U<nd)4=iCa5p8!5EE0e|Z_&sbSc2p{151!l?!Xcx
z=N(vrq&x#lkdW{le+rZF3@l-SuEE;RUb3s>FF|T@Ru{s>G7%FfmYuQqRmd~21nF=O
zETJ+{O>+j8ASL+&OORylz!D)BX(ox2C`VAS<Q`Z84~nt~M-W}kjK!~CRJm)$5+IWu
zSc2-}8CZgZat4+lG55d{CKJ(i_rN0U^lMx00%VY!XJ82u${kpO<h%n*kd$X&2@(?X
zIQ|qS;~7}O1YLu*pS|RGPV@z-$r)I}#WE2SD3+bE_*KX=umtIF4=kZFQB89OmLMhh
z151!(?!Xcu7ilKhKgtnArXWWU!3akX5ogBY*DtEv3@m~JWU>QGkdS9!2@=W~Sc1gd
z1521pMBCj13k$;D_j~2dRq`b~gGqjI?l6)s;T=Ho%RNI!ezAMd@GtdviNA=kk$<5R
zNBN~WgF}!&#@~Ge^nj3G;28??i`|1jKxuHboxsoEF+b$<WpaZ(P$Hz+;;&AC`|M9?
zM5l>@z)q7w31@%J!FFN4YzXJ?><Qld;+(L}7jOrxe`#Qg+(9a>^LfdiUf*p<b#2*^
z+LBfmUw*@s>U)orpRUYn+jRH_Udk=cyp1lbR(0L2p7X5V5v7I8cDAN@qg{8GyhTr5
zaVJXs8sS$xKRIvp{3OI2xz+QN3#^`BTVzPedo5m&frRfX>{pFI&3?jxn*Hjm{DKwV
z&Qw>MM3(lTKuJANWL|F=)HpF)!Hx5;f?vy&q)!$6WCN?<*EY|)3xgV^c9a)3X5MKS
z5RtBT9f~f$+T|V4PssOxeuAz8M!s<-7TCWnU|YTEEmZMvNM1)IX&F?+8<6YB<uh2t
zi3MLxlD`!iR=OfB-#_^*RMOwry@UJ*P-%Z%dy4#7sH{z4TRx*z4(#AHO7h9B3Sc)_
zJ|Q;zJS}rBc!c3!1s=Jxe`Gx}UjmOhS6)eN*$;pZNOz=L!T$#yjT-8lkk56EF?a!Z
ztUgvkJ~1|~zCX=J{}QhUkMHm9sR4f&d|<k!gU=5o?gUTh?y8|~iATW`+cf_L@Fd<=
z%5jUPfDhW)Ux7V}<TGNE+san3Z;^cZ>)>>M9rY}_1boQa^iGk#4m_oQcq45r`WE=m
zEu-p0Ui43ukJ^Ey{>dG@wH33<r@^MtrUCGL@bs>>bQ@Scm3ElCumvpkIXto8xtqZ6
z0UrU8ioeX}NCmCppOMcnSoF*1%t*uJQ)DxtB={Keqc^tlB3Nr!Gk8{F!Q=GFFxt<j
z;!2*}1(yDuqy1snjbQnF9BJ4+Y^t<B40{aB=UBxb<ok%$Jnau9a?E42Ka|Ml<Brw-
zP_h*~U;9Ie=wG1wsN@FlLf!8r(ig{Re<;}vUS#-t!Hcy&l*;GYs<l6q%8Sg7*Zxp?
z4)_G^1EuGKPc--%@JaeurMH1k*8WiX3-A){52gPC*J%5f$>-sgYJVt`&(GCre<+hr
z*41f$D3dSv@HSoXhceN>T>C@WEnuQT{Gse2@Jj6uWzU1_wLg?gU#!ypP%g1>iuQ+c
z`5a$^_J?x(RehrGO2X#NU@61K<)0y64cXuyk~cwo)u{Yw^3xz*T~;BV*;@mR0*ij>
zV~$zTNWK;t50*Gz2k~jWic87G&l2EIkgtdMgkHtB$v0G}7_WE&Oe__TCR~xT&Xjk@
zgQtSel6S|0Ph@kpygME&adD0%uRgbiUj%*)^9Yf-md!?al{|PCxJBL_4}Juk()J%N
zakok4{0s+4aI3sK9xVFX<Sq2zv%u-Zv@iS~d?9!<_!;nr!CMTLzSwH;Pr>bcZklX_
z#Kku7&lzIIg13Y30nY|^7|ijkPJ?^FT?Stb?l$;K;2wiT|7#6?4&1Bps1e{kgO3LH
zgE{Uf{KMK|@K*4-VC*pJ3h;S}g%|aJuLtk6O47dq-vxdhFViPRM?D5Uf9dYp-3*1r
z;0spnt`~e5_`*|nuNI77TCZQbd!67k_@Xm+pC$NB;EP*!rvzUI9@xBli{QJ#Z_xHX
zK=fat$Dh$a>y3K+89fdBCYhcy>@Edg+S;G21500ACKEHT#NC_aCDh<+z?Y|+Q=7rJ
zf~9Rq@cra((c{nPzk=VY$Dc9yqV+aC{)|}+e!Cuj#)v<@10szP{qNM{&zSdtuhiqu
zm@k5_(&NvVAA{ee$Dc7zf#0pipRp1bSL^X-Y$f<TdQ2GG0Di9?XU2*nzfX@pV<qmc
zG5jxp->=7?u|ENSK#xCT{|)}29)HG72Y*P9IpbD<KWy-J@JIBq#)<!YRF6O7#3tA3
z@n_sG!5@Q2;}dMIQ_vbell<cb;~(lX<z(YK*?iLQ#SWh`_?zV7H>B~uV{?Oo)`7#x
zZ!~y5`KJvQ+sc?iI`BL;pH<L0@Pp)^Gk6#I=M8?6Tx>y_Aoi4iB274kjr0L&!kKI&
zHb@f&*nC+KSn7MTg4TrZk$=VD=g1{iNfQrbBX%K86d(Aig4V<q@~;^z{c@YZ((bPt
z{C)Co7%YBuyT+5Ikl$hOGIFsIX_EByE<xaTvH6yQ)+DLdod*Au{M!cqgZwUy50Z1x
z-3Hf^f5+f7`F9PLSi8qysi(A=bdbp2tDtqzljKrw(&QpGKTyz`d?fh~4Ho@BGB`yp
z{!N;E37h*Av?hO?T;hr}S#0otg4Sg5s|O9<Oa2p$51vLYZ6h5l`hTXNb+G7v$Y7~I
zW0j<XKgQ-43R(w?y&pDMcybKV!Oye#m4enG6Ul#V@X6%AF}RKV5rf}GzT4n0kw0p%
z9RD$c|3&_|##0U_f5PAu<YGJ0l<jPOtDrSS`tf%Li@*HdU}?u641R(9j~X93gM5#{
ztI7Xl@Ok8aHu!_&GLDcAy^GD$3R;KCah}n5YAN}%2G1gY&fq3;Ip2_`?qKs51+A$c
zCjYC!;%k31SnBn6jgzCv#ipd>0yg4*q~sZF{;8mq6dw>9k&>TeBjXV%DZVD{BqgPe
z|54DICjBCQK$^BtO(Qfu3v4TBO}iAFFqkpGE;1N@v5O6+F7_~ur%wl$7`zNDwjfPU
zgUbxQ0$gq|V~Jg1FurLIHyC@^BQ!p2JXppT(qU51Q3jt5KEU7|V6hSDuy=#U7<>zO
ztihsxoWb;ujb2HIQ*Iw<@Uh?t1~-7kMx?{>D|?c`?*t!Y@E5_84Ho?e8!Y+{(fA0d
z{}hAgfn~fP9dQbHs=@8xq`{Yirx|=b7@JBuf_}6QGZ<gCB?d@GVn6!`gO3KwctJX{
z9z4U~E#RXJehYY}!J?miBprD-So~EmF=Wryct$CBj=@QArNP9qU1e}9c&@>hf@!Cu
z8KVCfgGE2~l{7=@KVRdchJhCtj6H1nSkh4^f{!!!Z15t3F90t#_@m%zgYN_%Z?M$=
z1dV6nQ#QIJ&7^(yNd~V0(*{X1&jl}0(3<&vaE-yYgO?i2m}J*#d^Emq*BOjm?PUfx
zf|ncI30`6F)!>x|e-%vMNILqL;8h0i1>+NvX5lY3{--eQv(c;Y2Joo{p9fxT@KxX@
zgTDkm&EWgMv{TZoKZBb!o-H<6YcRfGuQQms+ov1c23~LQ8^Ih~((Dg|&oKB7@R<hx
z3VfEq{{YixlI9RY_BjS)Z~HX{i~fxUzYW}Cu+%?g@I&BD2LB6;pGm4b9L)X-V`DpQ
z@OJQKgWm<-V({0%TMhm>xZU6vz}qygBIa!NmsBNo=r9<4Hhn3n>Pm2z!P1Z22JZ&<
zXgs$V{91$OfO`$5f9yVkk+u5`7T;j}k~CN9i7zVr8!&w=X`aN$PJ^YtUS}{qVxMoY
z=)Az-Yrq#8d^`B{20sbDNaJI~2QD^vE_lFT{K9^N!R%*WV(_(K{6Nw%cY)tz@E-7`
z8Xr3re3`+F0rr~>#;5Gd4W_>K6$XD4%y=Z}*l&X0YVaSx_=KeSW591Wcro}L2A>0F
zES5B%W7=05d?WZOgTDvH4<yYO|9`i}3#6XdUDAT%!0#~_-?ZOrFzvSAXYeP%*i_O2
z(fNLZp9OzF<AoEzA2j$R@P`b>PwfvId<FO;27eAr`z0;>8TeWSt%d&pe@x@!rhu<A
zxDNbrgYi@Q69!{HoBByQ?hD{g8T=sldV`+_-=OiLNnmUwY0*;frwt|!?9UjC&Fs$_
zd<&SmN?P;?`12YsPJlU{q{Y+0HyOMf{6&MMo?kMU{;|Jo@U7sR4gMwgD+d1u%<&{u
zi%#SeUIqTD!Ni>XHG}CN`!<7b2Y=n*$H3pv`1leqWs;7s0^ecq8ZbU5>G*TOyA-sJ
zr?2d98GIM`PJ<r@e_P`d%D|LKI$<{WZi7z)f5+h0g1>7peqrBZFgk2}NYV*=!1ro=
z;sN0A8@veo1B1^3|IpwIz&|n=-?4veu+;NDgZ}`&U*nTTgC8(>J{X^nbkch8PYf2F
zKQ&m|jxS0&3H#X(8T=dY&kdG7`h~_PPXRw{@bTbZ8vGjYuM8Ibzc!e-vC$>zWctm<
zpA=?4d$+-V0Y9qol5t@AQqq!nVERDeCh!vmi{CzJFk^%LTZ3-`|IT1+VE^9WXTaD<
zQjO^Uqrr2*^oOJx@wY!2ycNvYA*trg;HM1!6!>X_>1P|gl4_`n{jA37Gda&0oP_^>
z1}_KGPDx8Uz<)LPYVh9-CJyYs8!YyJUgO%~V8#eZwa0@0Y4AGmzYKmo_}>P98vKI6
z^rub#NvbOb?==|PCN#9_=sP}zpi<rCU{g?cGq}j`>7NAqOIk*K62lBW4qRez8@SZq
zE5Kz2e+gV}Fn*V)Fqn2E&?Ra4Vc-!O54Ek#ePqrfa~+xE$lS?pfzr@sXbW^Uv=I{D
zY=^c%+ad9#PN)m&hI*jaLcLHQ)DP`|=wq2@$oxX)6*8ZYbCjH$<eX$*3rVbg2>KXw
z9rSVN8t8-2C!kM45(C#mH$XQ+;%lFQJ_~WqkaLBcBjns5=L9)d%K1Rf12X=raepa2
zTnp7f%b=5>8i*LNRzNGE6QLzgJ+uls1!{mAp;MvNP!n_-v<7O1)<VRDTF*Y2d_A-Q
zIs-ZrIvhFzIue=zB_aGy{heec`O(l+XgV|tnhni?DxoT9E=1f|$3VoPH6L04Erf^z
zYY{XJS`1Y~$3rJT*wn(-7PhvqwS`SBY-(K#VQaPC_darLrPlkfwOZf9)@nTuTdVau
zY^~Pou(evBqrcSp8g^CdX^bCgeGYr8b+oUNe+{Bf)cV|Q<X?xr0o@MW0eutN1$_&;
z6Z$rE7exPA7eN<81JE0w^P$&6mq2fX-UPi4x)8b)x(s?VbUAbd^cLu?(A%K5L+^mz
z30(<Y1-%Qp0D3ocHS`|nz0feI1S*BfAR8)%%ApEqI3%eE8Uc-jMnMNaqoFa-SZEwH
z9y$=308NA@K?gwzXfkv#bO<yBYJpPFCa4uU8`=o9L1}0+bQbg)XbZFzYKOK#+o2Aq
z6Y7Gxp&sb9P%qR6^+V@CJD_u+^PrtH?-$U+&@Z81K|h6l4*eSX4fF`~6X+pmH}oj<
z81y*w1oR~ITj+Pt@1Z|He}wixe}euD{S0~vdK!8LdX{6~3w<B@0rW%YJMdSLe-HW*
z^ke8g=x*p9%1$A_pS%HTgihu61JHvI^;2t#97nAoQh&8(NW0V;;dhZ=4K+chL2KaC
z4z<=tJJi~qw09ABH$<D%x*ly(>xyE7#b9Y)HFP|50>5diTF;}cYW<G3s`WbBsn+MD
zozFpH#}lEGpp&5`@ScbM0sRyD7xWkSHROMX{tdkV{RjF#=x>xQCErV43)Ml(AXu_?
zCTnK0Rwip?vNk4bVzL${YhY^a>#yX?p%u_ds2(~JngJaJ&4i{yM?gnIv!L0~H0W?>
z4pa$ML35#b&@s@l(0phCv=BNDIt)4h8V!ws#zMoPW@r>N4jK;~2vtBMp|#KiXdQGq
zv>uuWO@fFQS@V*$E?MJ}wJllGlC>;535|d@KxaT_LT5o2Ljw?Ylxs`5rj%<{xfYdc
zO1YMlYe>14l{tgVjpUkD=0$Qni8(Esev^5LTvN)mq+CPFTuH7U<+@R>7iEqi*NSqD
zD03dUK9uW1xgM13K)L>t`H5T`%k`gJ_sJYf<~VZQC)ay&4I$SKGEb802Dx64>kzrl
zkn06|7xXRY7WNZ+;Wu(UB6BjiR**T8%=2V^B-aaaogmi-GEb9h1Gy%UYXO<-$aR3s
z|79K~bAOrh%UoaP_%gSbd6HcB$lPA$^fJGbxt7f7)m$FC4{{oT6WeMmO)Qb|lwZ|@
ze27@xE7Jl5pS72?M5>>_FU(DFJ9^}k@UfSOS%zYA`9+ELi{^%E>%4UD_P%6uKeu$I
zdgZQ8`9AmS^vAVhUl|I1;_?eQr`Xli)hpAfwsdb_H8=89w|DimZ`s<P<qZX!#BF5e
zf)UJlWVl?x>C=eZq--8Rh>a9mU<g?t;8y>kV}bY@W9amCAuZ*~*_-5y5vP}CfsGsc
z`cv`%!~ZVXR;j+T%-*=My{o;S8*1CnPw!)WR6AHfeMybkxUoOo+u7cg>fhJH%NjH*
zJh^Fjs;8$Ty<x%J#jPE=WkclmFqRc-94pi|bni5ux99ZcSfI77FV(lTW0UjyWy@{X
zhwc;nrAS?msEO#yR)ziXK;viBuC7})BRQk4W^D~wQ+@5)8T(^J|66rpEm&WVsJ}A(
zw~i9)eFa)T&QzVL_O4f8)d#Q2@`sl=#TJMy5L*BXFdWDk^I&s-7_%s!sj!ygFR|97
z0_6A$r*%*Pa;y_tlM9gJud3F}0J+R%B<<j@)I8y-IkY2F1Us9M<FDa7{W(Z-);jx2
zyF77$98Ok1^^xp>>=7N5J~{E!JCnAZx=+io!>#EStK?2cfZr+pDy)-NpTo`19l5CM
zKu0cLgO~H-<#hY3TU+NEjY(;rjlzswq<xt-awprZn@20}V}}=iTyOoIU$1<9j=!|c
zHTGMg?BxzmWzTfWXSi#M_9m5_7+kC={{7S=yT#snbZnsKZx>3blH)!PcN(y)WYJUi
z&!*3=-ELdOww-8Fas&*6gls+jseZG`=u-?iUfS{DB=zk<Kx&ee%an7M(yd#Uc&^we
z^XgMdT^rHAS@{=gZ!+!8G*=y4j;RuNiJ;%nw?mdmGG$qn41NWTe+U&c{vlV;_=j9U
z;~#Pbjep1$H2xu1(D+xVTs;0cz7&stVhJbS9IFK7(Q@(lmv6hlAOEDwAQ|7CGmEU%
zb4QvQ7fVgqaD;5e&t3dhx9Y0VMt%%>YFwYx??L2ETYkz%!(6*;!`jO3-ZsDTec>rR
zJ*`{A_KB*`06RN+X3YxLRJfk-<!1EAd$|G+l&Mc|YoLr2phvx8Fic3bt2f;jCL>DH
zeaZSxxn(Rsu)U#vX+Tki&Fw@+Niv}4xfy%)(p8xq0>J7`+amSIu9c|(1%_QneUzTI
z?r=kgA4Waop!9Ue`*ea+!S(45)*&SY+oyZewlGZv>52dD7iPj2S+-yN-A`t(aT?MV
zXl$-uHm1Idzq@v&`+3`HPe*rent%IZl=`&ZtunncZOQKYvU4o^s<6P0RrPCM6%C0S
z5nJHJTEMxF=Ed&MerjIuznmP%3R#@;Ex^_EM14#2+V1X-O@8;$$lWY8O-&74W)Enx
zmhf=%u6$*K%!%)#@ipj>zmKNavoh~%qey0gHKoD1PLMS!)~6~?U43dz<Fd+S8<zPW
ze2K8tMJF34_ZJP}60aAlzvSg@WsTidt7VBL@w1d6CLDT2;-c~wDf~j#Q{!hT#SU>&
z!>I9#3hfv1vy`!0$Y~@qUfA(7bFoJZbqfT1(q`zGg?o15r|5@HcSp8#7-tAMNeuB+
zrtf9rhA+8iL?=NITUm0_0`iMnuf}*6TJ)Dmoc#*O-3u{;vHaqCOo^A*>6=Bp)sO|B
zK}{o#+l;^z=JgDf{<k<}4C*@mFlA|NU2_fXDmALzoEYz`1^$<7w5G1y;>r8;<imHh
z9jU&)bYJDRRNmj-&a7`rHm*OjN$sPeth_PJC#{mJ)$Nq~+HB-A(IpXFT-UH-L+keT
zHu;3+`eq&~947Z6aUc`l`ncu?kD6-d^K;sLs>=V~{46lJAFQnGZ0*TDQmNaLvDE)|
zK{$K!Z?uV}^THDns`t!@t%c==E+-XN?VVdZciA)gcd=D`<}-71%A1PkE*~woC|gG#
zv`fmJeI=Lu-M?czI2PF2-``VRRke-rqOxyCS7mE=XH`#cciWEE{=TYhZQHBnRnDv8
zMyS53R8M==;2d**(sJ$0nx}1Rdh^^9th?~f0adq|58b5v&rY#ee8lJHPF=TJ`Cr-8
z6D-a9fbgm+R_?UQm(Ea9muEQksw#WL>AUKz`dw9)lpT3XrYu3(NKaW-QxRpOJY^SU
z_A93B08iPbOxZBXMtjPZXUa+_8|NuII#X6o*;r56sJT;DuCJ=H$4jkeU#Qwwwz8Yg
zHS&7~M^v2gCs)~%PrdCwr?1?#cC~Kd5kFziZmW1@w|$7n&YGYkC#YH6{?y(3MO_#v
zOP!l?UFW?0?+-Js%H<f&8Smxwy-G^X<pm@yC1(lGIVEA0oZ8K&gu_x%V`Ed^L?&zp
zzp^DT)xEC~cXsl{-nGrmt-b9%L3h47_XY>wuPetd<epyjk>aq|X$?=3DpNZ|VPINS
zv&P&V>wl}&682PjwzO{!R6;=^de$_rsSVRnNLdR)gW3~Y`#Zz?BD_{I8Bz6-Q(=fG
zJt`d*B4PA&hMGBaf2UB@rzgBsg?LzRU&Jlr&H+R67E@N)Dwh?(f`!;e_O3j?y(d_U
zikwh8OMmGV0r}Q>K=@42cV2`YC%UW!5qVikv}Cx1=xJ<hSQ;+H%ks1L%LguUG&VIX
z9~3?7YwM!)M3uK7!0r3VD7nU__0IkKf$eH)=-w2iC#t*!fk7RiHu<lyIQ3Y{_g%Z?
zgShFAK#wkDq$6_l^D%+eaYoFrr%_bo6sRZsBv^QT0-LQ&v=4eh6&0+9JCB{dd9k_b
zukdb{b9<<rM{{sJf*1H4Qb4~Cxb%eed{lk1dcub?^c46U5)}(cYxn?kR8scoQ{S(T
z5)Ccq3N?Is6uP%AY#|%0Gi4!f&T3k=JaRnj>)#PM9u}fUT39()&of0lhg8Touj<3Q
z$Riskf&r<;@GD<pr->dtlTd4*Mr%%1zQ4^RUWsS8m-DJhjVuw@i-n9(FVVS_8?~@4
zWJJjEIp3e!Q{`{!uhKcM>m7t%1MK6RH(1Xg&3Okk0#m&azUsAw-!J9yFZWzE(8~Kb
zSB=zD;9NCQPx#a@Glz=S6RN0SJumlMHK1MlJXa0SGk{|{bKZjHs*!s3x4Eic<Yjp@
zr>3tn``Zs~s9ha-?JhEz*<pZ<Ug2}zfL6)tg7<088>mNY|8mWF3+XRapZ#dg%ljRU
zJw{&15HypR=()wk&z0d7^0ojqB7_g%*{kWmcSP*t86{Frc!e?}c%+`t6Tv>Tt0z=Z
z!S!iNzvP8y)nA3KegxPjb4J-3b{=r8Rz>Q0Y4*v~Cw{w(ZzK=ERsA0Ervm&ie!GmX
z1vS&PdLQ7?T5izJOs~eb%M8x5g(1BZ7wzvBh~Gi7zxU89qki!_NM0HJ6xZ^<Xo2`U
zDjDMr`S(8*y=-q=P_Jpo7=B0tb>CxbkBkrK`#`O+Ft(UmL7UBYeb$;c(5^FY7&+aP
zuQ%me&F>B74fAKH_g-7pnWlWB$y@Y|sn%wbr?}}>(k63La;uSRGy2jhcR#>jDyjCe
zU7hE~s!;7oT&Wk6$X+}K^1ph^uCCB4e(SdVE50#t17ZvO*DP>gCRB>l1D<BMV`Y`M
zc>dRp8Y_N9SYW6>-lfm+DnjI(9H-a<Sqo$a&MYfNu?1oa<XIq|W8|46W;hlY@^g%^
z^T<nE;m~uI|LqD#SnC`Yi1XM2u?1oayqYbL$TqHg)za=AU2QxRoaMPu=Dta}>8wn@
z4OG4$yT1O^x~?4^;kPuq6~#EVz^mB;@!aCo+`EOhE$FXqg=>f<V++I<h%NByu|WP^
z2JW``y+ADZZ0a6g`TL-G5v+O}XFRQSn>EI<1zx%Zf&=lT>y9<V7KpHbazD2Z4$3<k
zOXR3ZYy6k=hz=NP#WrrynQHGEYV97%?UkiXCl$}T%qpIDgZU{h_kOO&r#z`%?mhJ@
zJ(M>&`${hR$7%2_Fx3At>v_5Nyz8%27M|MIqWsVOa&Pg!_~qX6I`e&bxpzDx82pfZ
zm1vA-1oC|i^<2orgr17C?BaTc#MRHpNhBSdm6JzF@)L6WEzz1(fE=GovJNUhPM))$
zT!7qg<YorQWiB+R-w5P7vT~Us*x7{KNPcxj$yw&3O5#iMolUL59>{8PQ2OM=Q}0aL
zcIrMY#}2oqTda~h9RYr)?sI;4^*P-9+>uN52EPMd_HyL%HF!BMUQV~qy0vw#(U_F>
z$?{#sF4DeC8|@zJ*3F~M^HDED{k-jTe!ckiIvTwB;OTSxrERXU-x6gnci1U=rdvM4
z!;%~~spQmpDZj+6pL%4s*n5xmdG!44!c6@R@z#65vXVtl-9MW?yH;kvww-8F`UnI@
z2-$l4Q~hR>(We-4ytL!PN$T5!fC{jTT&CQ9#=3Ru5`D35v{9Cka}MCiMgL~yU#Pvw
zv{zL^9Yl1?F;%j!6#b4q^~tDASym~7nzSu){6nsw@eiSb#y{i=8vl?hX#7L2pz#m6
zg2q4O;_)x*CV9y5t876${)sK}?UJ>S8%4{-<Dc7J8V~;XCwk*Eu{p!$8(eW>Ps}&W
zf58*=93%fwF(<Y_Y=NO?fp|O^dVL<ZIJQ8L1>)~727F9I87%((Vj*9`jK9C=8(jl%
z2kRR$a)9{zi(-WrlUmp*{{CW5cW-|(;7fCs6@Pzm)~sOb?Bf>*0<G-mX$^Jb%p3nB
z^_XS(0B!rACsa|vdS32t+635VH1=@5MH65e#g1y%fJ;x<w+sr`6aD}wdgAXdhILp(
zSqtTbd~L0e?<Vf!w`c-9QCE1--uNGXe=))Xf{I%x7_2Wj59-(7UZ$_M#ou2H@{Gdy
z@%I<QY~}j;N#J+68sqOT4&JxI1Fh`LF~epouCFge>M3xp8mT9AikbadR<xc_MVYx+
zl%AJ+t{PCEeV(fZ=ouh5ojGq<&qvuOt7m_ktA>p}T))QOUko*nYt9?sLGkw&!wlGB
z3J2qx<MH<w!z`T{p+df*rbfEf&=W!Sj1sLUR8hh8iNC+N(63)JXSn$Li+<*@2H?iu
zUsS8pA(6`8KT^Kt%P?J6AmMuWd~#-|7Xg~gK9#S=?=QXxd&IlM78nv1i0_>m65Sj(
zGPXb=7La+Zlj8RvIF{JI^7uUnHBZ~t^yaxISa%iAi{FE=a(z{mJwC+~#j`K0lD8g|
zt?af&%kLSR=1x_deR&Upe$LTaDo$U=70M%)wbJVB>+khO!MX4c8i1d(q<ZB>9&8kT
z&iixhquBo_`0ZXjhdd|`LTdd*zt5K0T#}RsAN_8A#b>30TEClLdRtb%n}0a^6SF&e
z`Z%tee<b!Pp5NKOB}aexTJ-E{YUt~?icXU@Ox1N7!Evq1p5F9ktLTI80ngF=kvzp&
zT(9{Ho)H<%FT0YwSo05<0<O~hF{hCquK6Y7z}1GogS<lX&z=ZA-taFbf0yRJM`TXW
z{IO%mS1Eqt-ahb&nqPV$d9t&=k9L`-aaF<1FUW@+JNtWb_+?j9JOE#GxMqW;A~zbo
z^p~6e7{3qc?C+4j+q?K99_F{P&vj3NO+Qb1OV&QWdn5d95UJt@HpV`0k#}%y7p`TE
zO|vofdE#L3xx$5i78_%qho1$XCtM!L{X83EpNY~ZJB7=O1(vYU_9=R==zJYSD%-%u
z)bm%Df!{1#^k0#!=XX8|<8sBe%ETW`J#R<G5+YT+iH)vj@q{D6Vn<S$=rr}b_ora-
z71D$U*qD0$>HFaK3YYq~vC;J`ZhsW~KH>7v?|e2+Kk|^RlfLHeM;HGN_?dom@k_6T
z@ARXa{~!2HKf3v1pEB)Nr+$fN{uc9_RNBI3gyP#j#kXzaw-sU^Bfqo({!)IED$ZtO
z<e$a2>{`XPDz=gv`CFI6KgIBSGV+P(E%4DLsY3kO$lo{~z8sHK`5+sk|F7?dzfQ5O
zvdQF=RXrPi`8oI(X#O>ih#Jj*`W*P8m-MmKj5FgEzwz=vz<<4B+vm)*tV2g@{^(=j
zU!?ffEWxFke>A>lOMH^bq`$PDhHo^(9}q5fyNQkVhsJk*68;+$+bX9m)+nv#<E-7-
zmuUWM>}r>2{^Enc5;LR<kv~cC8=j-DZSg-+`E)i$&xz8mOBLI?UUWXJ^%VUXe3|Ay
z*-x(R)>vH+-}wKWPr*M%>wjF@W&Ho{1+<|_>p6_oD%<#f>4%WlanU#;0iQURG-nB$
zO<K>Fe+d7r!nLeD;^&Jr|5rbP|2D<8_K2R5TK`*i!+*Qx&-ppIvFE36gZ~cAuar#N
zv*B~%KkwB18&4#^OY48^5co3wl0I#NCu#ogegnQr^FM=ats6A|E_}y+m*!W>Q}lX#
zXn5!h`0qCI-(t8kc3WHm|7s(Tt*q&~{`M2_O}x+f6MW-W>#%`s;{E;u;p=gr@d$L=
zCf@JA9{x66pYOE5zlPtW2V|Vr{@nPXQ{msL*wzEH@Y@agxErvU{Z-BXIsW4KbFuj0
z*EE06jah%*xE?+>mGm2qZ~VF8@ka31HUE*1kem7+i_hBMFnq=Y$DiMU@7cE-zLXn3
zyaOBCcNqS?VB^nkDFS~}^LO7zuKl@jF?F+dY5t?5$hDq^d(VcC-6cILeQNyqn>)aF
zDz<&xBy!y^4flxszpePzV}B#p{@gel8`^hi`Eu;x`13iU=WZ=u)<kan`3p7hzoYq&
zA4P8b`FUyAcNO10v5egK^PWG$zsK;GkQ;w4eHQ-r6yJJW;=|Z;Ep@Q5i=@ZJ&Srer
zAZ`4<Vq1^jKz^_8-!Fa;{tq<&50`+oKR3>#?)DEg|A}65?az&8Q)l}}n*XGXhuWVT
zPiAbef2{cSnDVSY&sYmz`h)c3N;bxyzfN22`xV>z;|Iu1JpQ2?{sV?D{%`#G6MuyN
zpyJ!(#LtaCf1lX0e`5HIm$n{Pt$}**|7res;@IKuk$(S+;#;4ieML!S2kRr!-oI-3
ziTG*Je9dqCCw%E|vdK@w*Y&gx9tPv@if`>%LayV;dY2sQdBwMvZFKZsy!YWJ;r~PP
zlT#i27w`Scui<kHl6@F4<><fQr!fAd`A2RcH~Raji~VoK$JfZqI#W5{NwE+7DEzBC
zQ))h@Mb)-)5t;Vq+N<WE=LKC@S(oKsb3Xk4D84=6lq|n_5B$A`PmDWy<|H#yHG9S~
z=7IWr`u;Wezw_Rr*^TheR`z`V>W{-`Oefj%Ze*+L^Zr8_vlGOy;(sNp=d+dYi#7ka
z!?SwIAB9gJi2OnsCybsqY=X}iDydBTP1k4PgXh98Rcz~~KNF7HPZn+=#uH_l|KtGt
zgsSJl+ZekN__3rtXR<MRp2T+&6^d=2aZpyz19RaI*Zi7uGJ1|X5ShdX&A&|gaa3ow
I_d4bO0em0GrvLx|

literal 0
HcmV?d00001

diff --git a/AppleX509CL/AppleX509CL.pbproj/project.pbxproj b/AppleX509CL/AppleX509CL.pbproj/project.pbxproj
new file mode 100644
index 00000000..533513ed
--- /dev/null
+++ b/AppleX509CL/AppleX509CL.pbproj/project.pbxproj
@@ -0,0 +1,531 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 32;
+	objects = {
+		00EDCDFCFF682165D0A17CE7 = {
+			isa = PBXFileReference;
+			path = CertExtensions.cpp;
+			refType = 4;
+		};
+		00EDCDFDFF682166D0A17CE7 = {
+			fileRef = 00EDCDFCFF682165D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00EDCDFEFF685DECD0A17CE7 = {
+			isa = PBXFileReference;
+			path = CertExtensions.h;
+			refType = 4;
+		};
+		00EDCDFFFF685DECD0A17CE7 = {
+			fileRef = 00EDCDFEFF685DECD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0145E217FFEECAE67F000001 = {
+			isa = PBXFileReference;
+			path = CSPAttacher.h;
+			refType = 4;
+		};
+		0145E218FFEECAE67F000001 = {
+			fileRef = 0145E217FFEECAE67F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0145E219FFEECB7D7F000001 = {
+			isa = PBXFileReference;
+			path = CSPAttacher.cpp;
+			refType = 4;
+		};
+		0145E21AFFEECB7D7F000001 = {
+			fileRef = 0145E219FFEECB7D7F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01B9A482FF51F881D0A17CE7 = {
+			isa = PBXFileReference;
+			path = CertBuilder.cpp;
+			refType = 4;
+		};
+		01B9A483FF51F881D0A17CE7 = {
+			isa = PBXFileReference;
+			path = CertBuilder.h;
+			refType = 4;
+		};
+		01B9A484FF51F882D0A17CE7 = {
+			fileRef = 01B9A483FF51F881D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01B9A485FF51F882D0A17CE7 = {
+			fileRef = 01B9A482FF51F881D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		023E3604001F8F3611CD283A = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OTHER_LDFLAGS = "\U0001-dylib_file \"$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Security:$(SYMROOT)/Security.framework/Versions/A/Security\"";
+			};
+			isa = PBXBuildStyle;
+			name = "Build Folder";
+		};
+		026EACE1FF4315CCD0A17CE7 = {
+			buildStyles = (
+				1C9129D5FFD8583A11CD296C,
+				1C9129D6FFD8583A11CD296C,
+				023E3604001F8F3611CD283A,
+			);
+			isa = PBXProject;
+			mainGroup = 026EACE2FF4315CCD0A17CE7;
+			productRefGroup = 026EACE3FF431640D0A17CE7;
+			projectDirPath = .;
+			targets = (
+				026EACE7FF431640D0A17CE7,
+			);
+		};
+		026EACE2FF4315CCD0A17CE7 = {
+			children = (
+				026EACEDFF431781D0A17CE7,
+				026EACEEFF431781D0A17CE7,
+				01B9A482FF51F881D0A17CE7,
+				01B9A483FF51F881D0A17CE7,
+				00EDCDFCFF682165D0A17CE7,
+				00EDCDFEFF685DECD0A17CE7,
+				04CBC2A4FF487123D0A17CE7,
+				0A8DEDB2FF48916BD0A17CE7,
+				0A8DEDB0FF488BFED0A17CE7,
+				0145E219FFEECB7D7F000001,
+				0145E217FFEECAE67F000001,
+				08D5DEBCFF52F2F3D0A17CE7,
+				08D5DEBEFF52F335D0A17CE7,
+				0A8DEDBAFF49C621D0A17CE7,
+				0A8DEDBBFF49C621D0A17CE7,
+				0A8DEDB6FF499ACAD0A17CE7,
+				23C0B750FF4C5F61D0A17CE7,
+				23C0B751FF4C5F61D0A17CE7,
+				026EACFFFF43462AD0A17CE7,
+				026EAD00FF43462AD0A17CE7,
+				23715C3DFF4C5A26D0A17CE7,
+				23C0B758FF4C6EA0D0A17CE7,
+				23C0B759FF4C6EA0D0A17CE7,
+				026EACFDFF431F36D0A17CE7,
+				35D41EC6FFF3E85F11CD283A,
+				026EACE3FF431640D0A17CE7,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		026EACE3FF431640D0A17CE7 = {
+			children = (
+				1C9129D4FFD8583A11CD296C,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		026EACE7FF431640D0A17CE7 = {
+			buildPhases = (
+				026EACE8FF431640D0A17CE7,
+				026EACE9FF431640D0A17CE7,
+				026EACEAFF431640D0A17CE7,
+				026EACEBFF431640D0A17CE7,
+				026EACECFF431640D0A17CE7,
+			);
+			buildSettings = {
+				DEPLOYMENT_OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				EXPORTED_SYMBOLS_FILE = cssmplugin.exp;
+				FRAMEWORK_SEARCH_PATHS = "";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security";
+				OPTIMIZATION_CFLAGS = "-O1";
+				OTHER_CFLAGS = "-DVDADER_RULES";
+				OTHER_LDFLAGS = "-bundle -undefined error -lstdc++";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleX509CL;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-format -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = bundle;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXBundleTarget;
+			name = AppleX509CL;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Security";
+			productName = AppleX509CL;
+			productReference = 1C9129D4FFD8583A11CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AppleX509CL</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.applex509cl</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>AppleX509CL</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>AppleX509CL 1.0</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		026EACE8FF431640D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				026EACF5FF431781D0A17CE7,
+				0A8DEDB1FF488BFED0A17CE7,
+				0A8DEDB7FF499ACAD0A17CE7,
+				0A8DEDBCFF49C621D0A17CE7,
+				23C0B752FF4C5F61D0A17CE7,
+				23C0B75AFF4C6EA0D0A17CE7,
+				01B9A484FF51F882D0A17CE7,
+				08D5DEBFFF52F335D0A17CE7,
+				00EDCDFFFF685DECD0A17CE7,
+				0145E218FFEECAE67F000001,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		026EACE9FF431640D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		026EACEAFF431640D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				026EACF7FF431781D0A17CE7,
+				026EACFEFF431F36D0A17CE7,
+				026EAD01FF43462AD0A17CE7,
+				026EAD02FF43462AD0A17CE7,
+				04CBC2A5FF487123D0A17CE7,
+				0A8DEDB3FF48916BD0A17CE7,
+				0A8DEDBDFF49C621D0A17CE7,
+				23715C3EFF4C5A26D0A17CE7,
+				23C0B753FF4C5F61D0A17CE7,
+				23C0B75BFF4C6EA0D0A17CE7,
+				01B9A485FF51F882D0A17CE7,
+				08D5DEBDFF52F2F3D0A17CE7,
+				00EDCDFDFF682166D0A17CE7,
+				0145E21AFFEECB7D7F000001,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		026EACEBFF431640D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				35D41EC8FFF3E85F11CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		026EACECFF431640D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		026EACEDFF431781D0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleX509CL.cpp;
+			refType = 4;
+		};
+		026EACEEFF431781D0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleX509CL.h;
+			refType = 4;
+		};
+		026EACF5FF431781D0A17CE7 = {
+			fileRef = 026EACEEFF431781D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		026EACF7FF431781D0A17CE7 = {
+			fileRef = 026EACEDFF431781D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		026EACFDFF431F36D0A17CE7 = {
+			isa = PBXFileReference;
+			path = cssmplugin.exp;
+			refType = 4;
+		};
+		026EACFEFF431F36D0A17CE7 = {
+			fileRef = 026EACFDFF431F36D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		026EACFFFF43462AD0A17CE7 = {
+			isa = PBXFileReference;
+			path = Session_Cert.cpp;
+			refType = 4;
+		};
+		026EAD00FF43462AD0A17CE7 = {
+			isa = PBXFileReference;
+			path = Session_CRL.cpp;
+			refType = 4;
+		};
+		026EAD01FF43462AD0A17CE7 = {
+			fileRef = 026EACFFFF43462AD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		026EAD02FF43462AD0A17CE7 = {
+			fileRef = 026EAD00FF43462AD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		04CBC2A4FF487123D0A17CE7 = {
+			isa = PBXFileReference;
+			path = CertFields.cpp;
+			refType = 4;
+		};
+		04CBC2A5FF487123D0A17CE7 = {
+			fileRef = 04CBC2A4FF487123D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		08D5DEBCFF52F2F3D0A17CE7 = {
+			isa = PBXFileReference;
+			path = DecodedCert.cpp;
+			refType = 4;
+		};
+		08D5DEBDFF52F2F3D0A17CE7 = {
+			fileRef = 08D5DEBCFF52F2F3D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		08D5DEBEFF52F335D0A17CE7 = {
+			isa = PBXFileReference;
+			path = DecodedCert.h;
+			refType = 4;
+		};
+		08D5DEBFFF52F335D0A17CE7 = {
+			fileRef = 08D5DEBEFF52F335D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0A8DEDB0FF488BFED0A17CE7 = {
+			isa = PBXFileReference;
+			path = CLCachedEntry.h;
+			refType = 4;
+		};
+		0A8DEDB1FF488BFED0A17CE7 = {
+			fileRef = 0A8DEDB0FF488BFED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0A8DEDB2FF48916BD0A17CE7 = {
+			isa = PBXFileReference;
+			path = CLCachedEntry.cpp;
+			refType = 4;
+		};
+		0A8DEDB3FF48916BD0A17CE7 = {
+			fileRef = 0A8DEDB2FF48916BD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0A8DEDB6FF499ACAD0A17CE7 = {
+			isa = PBXFileReference;
+			path = LockedMap.h;
+			refType = 4;
+		};
+		0A8DEDB7FF499ACAD0A17CE7 = {
+			fileRef = 0A8DEDB6FF499ACAD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0A8DEDBAFF49C621D0A17CE7 = {
+			isa = PBXFileReference;
+			path = debugging.c;
+			refType = 4;
+		};
+		0A8DEDBBFF49C621D0A17CE7 = {
+			isa = PBXFileReference;
+			path = debugging.h;
+			refType = 4;
+		};
+		0A8DEDBCFF49C621D0A17CE7 = {
+			fileRef = 0A8DEDBBFF49C621D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0A8DEDBDFF49C621D0A17CE7 = {
+			fileRef = 0A8DEDBAFF49C621D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		1C9129D4FFD8583A11CD296C = {
+			isa = PBXBundleReference;
+			path = AppleX509CL.bundle;
+			refType = 3;
+		};
+		1C9129D5FFD8583A11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		1C9129D6FFD8583A11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		23715C3DFF4C5A26D0A17CE7 = {
+			isa = PBXFileReference;
+			path = Session_Crypto.cpp;
+			refType = 4;
+		};
+		23715C3EFF4C5A26D0A17CE7 = {
+			fileRef = 23715C3DFF4C5A26D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		23C0B750FF4C5F61D0A17CE7 = {
+			isa = PBXFileReference;
+			path = Session.h;
+			refType = 4;
+		};
+		23C0B751FF4C5F61D0A17CE7 = {
+			isa = PBXFileReference;
+			path = Session.cpp;
+			refType = 4;
+		};
+		23C0B752FF4C5F61D0A17CE7 = {
+			fileRef = 23C0B750FF4C5F61D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		23C0B753FF4C5F61D0A17CE7 = {
+			fileRef = 23C0B751FF4C5F61D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		23C0B758FF4C6EA0D0A17CE7 = {
+			isa = PBXFileReference;
+			path = SnaccUtils.cpp;
+			refType = 4;
+		};
+		23C0B759FF4C6EA0D0A17CE7 = {
+			isa = PBXFileReference;
+			path = SnaccUtils.h;
+			refType = 4;
+		};
+		23C0B75AFF4C6EA0D0A17CE7 = {
+			fileRef = 23C0B759FF4C6EA0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		23C0B75BFF4C6EA0D0A17CE7 = {
+			fileRef = 23C0B758FF4C6EA0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		35D41EC6FFF3E85F11CD283A = {
+			children = (
+				35D41EC7FFF3E85F11CD283A,
+			);
+			isa = PBXGroup;
+			name = "External Frameworks";
+			path = ../Projects/SecurityX/AppleX509CL;
+			refType = 3;
+		};
+		35D41EC7FFF3E85F11CD283A = {
+			isa = PBXFrameworkReference;
+			path = Security.framework;
+			refType = 3;
+		};
+		35D41EC8FFF3E85F11CD283A = {
+			fileRef = 35D41EC7FFF3E85F11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+	};
+	rootObject = 026EACE1FF4315CCD0A17CE7;
+}
diff --git a/AppleX509CL/AppleX509CLPlugin.cpp b/AppleX509CL/AppleX509CLPlugin.cpp
new file mode 100644
index 00000000..ad2990cc
--- /dev/null
+++ b/AppleX509CL/AppleX509CLPlugin.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 obtai
+n  
+ * 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.
+ */
+
+  
+// 
+// Produce the "genuine plugin version" of the Apple X509 CL
+//
+#include <AppleX509CL.h>
+
+
+//
+// Create the plugin object and generate the C layer hookup
+//
+ModuleNexus<AppleX509CL> plugin;
+
+#include <Security/pluginspi.h>
diff --git a/AppleX509CL/AppleX509CLSession.cpp b/AppleX509CL/AppleX509CLSession.cpp
new file mode 100644
index 00000000..81c8a0e9
--- /dev/null
+++ b/AppleX509CL/AppleX509CLSession.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * AppleX509CLSession.cpp - general CL session support
+ */
+
+#include "AppleX509CLSession.h"
+#include <Security/debugging.h>
+
+AppleX509CLSession::AppleX509CLSession(
+	CSSM_MODULE_HANDLE theHandle,
+	CssmPlugin &plug,
+	const CSSM_VERSION &version,
+	uint32 subserviceId,
+	CSSM_SERVICE_TYPE subserviceType,
+	CSSM_ATTACH_FLAGS attachFlags,
+	const CSSM_UPCALLS &upcalls)
+		: CLPluginSession(theHandle, plug, version, subserviceId, 
+							subserviceType,attachFlags, upcalls)
+{
+}
+
+AppleX509CLSession::~AppleX509CLSession()
+{
+	/* free leftover contents of cache and query maps */
+	CLCachedEntry *cachedCert = cacheMap.removeFirstEntry();
+	while(cachedCert != NULL) {
+		debug("clDetach", "CL detach: deleting a cached Cert\n");
+		delete cachedCert;
+		cachedCert = cacheMap.removeFirstEntry();
+	}
+	CLQuery *query = queryMap.removeFirstEntry();
+	while(query != NULL) {
+		debug("clDetach", "CL detach: deleting a cached query\n");
+		delete query;
+		query = queryMap.removeFirstEntry();
+	}
+}
+
+CLCachedCert *
+AppleX509CLSession::lookupCachedCert(CSSM_HANDLE handle)
+{
+	CLCachedEntry *entry = cacheMap.lookupEntry(handle);
+	if(entry != NULL) {
+		/* 
+		 * we rely on this dynamic cast to detect a bogus lookup 
+		 * of a cert via a CRL's handle
+		 */
+		return dynamic_cast<CLCachedCert *>(entry);
+	}
+	else {
+		return NULL;
+	}
+}
+		
+CLCachedCRL	*
+AppleX509CLSession::lookupCachedCRL(CSSM_HANDLE handle)
+{
+	CLCachedEntry *entry = cacheMap.lookupEntry(handle);
+	if(entry != NULL) {
+		/* 
+		 * we rely on this dynamic cast to detect a bogus lookup 
+		 * of a CRL via a cert's handle
+		 */
+		return dynamic_cast<CLCachedCRL *>(entry);
+	}
+	else {
+		return NULL;
+	}
+}	
+
diff --git a/AppleX509CL/AppleX509CLSession.h b/AppleX509CL/AppleX509CLSession.h
new file mode 100644
index 00000000..c15e3795
--- /dev/null
+++ b/AppleX509CL/AppleX509CLSession.h
@@ -0,0 +1,312 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleX509CLSession.h - general CL session functions.
+//
+#ifndef _H_APPLEX509CLSESSION
+#define _H_APPLEX509CLSESSION
+
+#include <Security/CLsession.h>
+#include "CLCachedEntry.h"
+#include "DecodedCert.h"
+#include "LockedMap.h"
+#include <Security/threading.h>
+
+class AppleX509CLSession : public CLPluginSession {
+
+public:
+
+	AppleX509CLSession(
+		CSSM_MODULE_HANDLE theHandle,
+		CssmPlugin &plug,
+		const CSSM_VERSION &version,
+		uint32 subserviceId,
+		CSSM_SERVICE_TYPE subserviceType,
+		CSSM_ATTACH_FLAGS attachFlags,
+		const CSSM_UPCALLS &upcalls);
+
+	~AppleX509CLSession();
+
+// ====================================================================
+// Cert Interpretation
+// ====================================================================				
+	
+	void CertDescribeFormat(
+		uint32 &NumberOfFields,
+		CSSM_OID_PTR &OidList);
+
+// Non-cached
+	
+	void CertGetAllFields(
+		const CssmData &Cert,
+		uint32 &NumberOfFields,
+		CSSM_FIELD_PTR &CertFields);
+
+	CSSM_HANDLE CertGetFirstFieldValue(
+		const CssmData &Cert,
+		const CssmData &CertField,
+		uint32 &NumberOfMatchedFields,
+		CSSM_DATA_PTR &Value);
+
+	bool CertGetNextFieldValue(
+		CSSM_HANDLE ResultsHandle,
+		CSSM_DATA_PTR &Value);
+
+
+// Cached
+	
+	void CertCache(
+		const CssmData &Cert,
+		CSSM_HANDLE &CertHandle);
+
+	CSSM_HANDLE CertGetFirstCachedFieldValue(
+		CSSM_HANDLE CertHandle,
+		const CssmData &CertField,
+		uint32 &NumberOfMatchedFields,
+		CSSM_DATA_PTR &Value);
+
+	bool CertGetNextCachedFieldValue(
+		CSSM_HANDLE ResultsHandle,
+		CSSM_DATA_PTR &Value);
+
+	void CertAbortCache(
+		CSSM_HANDLE CertHandle);
+
+	void CertAbortQuery(
+		CSSM_HANDLE ResultsHandle);
+
+
+
+// Templates
+							
+	void CertCreateTemplate(
+		uint32 NumberOfFields,
+		const CSSM_FIELD CertFields[],
+		CssmData &CertTemplate);
+
+	void CertGetAllTemplateFields(
+		const CssmData &CertTemplate,
+		uint32 &NumberOfFields,
+		CSSM_FIELD_PTR &CertFields);
+						
+
+// Memory						
+
+	void FreeFields(
+		uint32 NumberOfFields,
+		CSSM_FIELD_PTR &FieldArray);
+	void FreeFieldValue(
+		const CssmData &CertOrCrlOid,
+		CssmData *Value);
+
+// Key
+	
+	void CertGetKeyInfo(
+		const CssmData &Cert,
+		CSSM_KEY_PTR &Key);
+						
+// ====================================================================
+// CRL Interpretation
+// ====================================================================
+
+// Non-cached
+	
+	void CrlDescribeFormat(
+		uint32 &NumberOfFields,
+		CSSM_OID_PTR &OidList);
+
+	void CrlGetAllFields(
+		const CssmData &Crl,
+		uint32 &NumberOfCrlFields,
+		CSSM_FIELD_PTR &CrlFields);
+
+	CSSM_HANDLE CrlGetFirstFieldValue(
+		const CssmData &Crl,
+		const CssmData &CrlField,
+		uint32 &NumberOfMatchedFields,
+		CSSM_DATA_PTR &Value);
+	
+	bool CrlGetNextFieldValue(
+		CSSM_HANDLE ResultsHandle,
+		CSSM_DATA_PTR &Value);
+
+	void IsCertInCrl(
+		const CssmData &Cert,
+		const CssmData &Crl,
+		CSSM_BOOL &CertFound);
+	
+	
+// Cached
+
+	void CrlCache(
+		const CssmData &Crl,
+		CSSM_HANDLE &CrlHandle);
+
+	void CrlGetAllCachedRecordFields(CSSM_HANDLE CrlHandle,
+		const CssmData &CrlRecordIndex,
+		uint32 &NumberOfFields,
+		CSSM_FIELD_PTR &CrlFields);
+						
+	CSSM_HANDLE CrlGetFirstCachedFieldValue(
+		CSSM_HANDLE CrlHandle,
+		const CssmData *CrlRecordIndex,
+		const CssmData &CrlField,
+		uint32 &NumberOfMatchedFields,
+		CSSM_DATA_PTR &Value);
+
+	bool CrlGetNextCachedFieldValue(
+		CSSM_HANDLE ResultsHandle,
+		CSSM_DATA_PTR &Value);
+
+	void IsCertInCachedCrl(
+		const CssmData &Cert,
+		CSSM_HANDLE CrlHandle,
+		CSSM_BOOL &CertFound,
+		CssmData &CrlRecordIndex);
+
+	void CrlAbortCache(
+		CSSM_HANDLE CrlHandle);
+
+	void CrlAbortQuery(
+		CSSM_HANDLE ResultsHandle);
+
+
+// Template
+
+	void CrlCreateTemplate(
+		uint32 NumberOfFields,
+		const CSSM_FIELD *CrlTemplate,
+		CssmData &NewCrl);
+
+	void CrlSetFields(
+		uint32 NumberOfFields,
+		const CSSM_FIELD *CrlTemplate,
+		const CssmData &OldCrl,
+		CssmData &ModifiedCrl);
+
+	void CrlAddCert(
+		CSSM_CC_HANDLE CCHandle,
+		const CssmData &Cert,
+		uint32 NumberOfFields,
+		const CSSM_FIELD CrlEntryFields[],
+		const CssmData &OldCrl,
+		CssmData &NewCrl);
+
+	void CrlRemoveCert(
+		const CssmData &Cert,
+		const CssmData &OldCrl,
+		CssmData &NewCrl);
+
+// ====================================================================
+// Verify/Sign
+// ====================================================================
+	
+// Certs
+	
+	void CertVerifyWithKey(
+		CSSM_CC_HANDLE CCHandle,
+		const CssmData &CertToBeVerified);
+	
+	void CertVerify(
+		CSSM_CC_HANDLE CCHandle,
+		const CssmData &CertToBeVerified,
+		const CssmData *SignerCert,
+		const CSSM_FIELD *VerifyScope,
+		uint32 ScopeSize);
+						
+	void CertSign(
+		CSSM_CC_HANDLE CCHandle,
+		const CssmData &CertTemplate,
+		const CSSM_FIELD *SignScope,
+		uint32 ScopeSize,
+		CssmData &SignedCert);
+
+// Cert Groups
+
+	void CertGroupFromVerifiedBundle(
+		CSSM_CC_HANDLE CCHandle,
+		const CSSM_CERT_BUNDLE &CertBundle,
+		const CssmData *SignerCert,
+		CSSM_CERTGROUP_PTR &CertGroup);
+						
+	void CertGroupToSignedBundle(
+		CSSM_CC_HANDLE CCHandle,
+		const CSSM_CERTGROUP &CertGroupToBundle,
+		const CSSM_CERT_BUNDLE_HEADER *BundleInfo,
+		CssmData &SignedBundle);
+						
+// CRLs
+
+	void CrlVerifyWithKey(
+		CSSM_CC_HANDLE CCHandle,
+		const CssmData &CrlToBeVerified);
+
+	void CrlVerify(
+		CSSM_CC_HANDLE CCHandle,
+		const CssmData &CrlToBeVerified,
+		const CssmData &SignerCert,
+		const CSSM_FIELD *VerifyScope,
+		uint32 ScopeSize);
+						
+	void CrlSign(
+		CSSM_CC_HANDLE CCHandle,
+		const CssmData &UnsignedCrl,
+		const CSSM_FIELD *SignScope,
+		uint32 ScopeSize,
+		CssmData &SignedCrl);
+
+// ====================================================================
+// Module Specific Pass-Through
+// ====================================================================
+	
+	void PassThrough(
+		CSSM_CC_HANDLE CCHandle,
+		uint32 PassThroughId,
+		const void *InputParams,
+		void **OutputParams);
+
+private:
+	/* routines in Session_Cert.cpp */
+	void getAllParsedCertFields(
+		const DecodedCert	&cert,
+		uint32 				&NumberOfFields,		// RETURNED
+		CSSM_FIELD_PTR 		&CertFields);			// RETURNED
+
+	/* routines in Session_Crypto.cpp */
+	void signData(
+		CSSM_CC_HANDLE		ccHand,
+		const CssmData		&tbs,
+		CssmOwnedData		&sig);			// mallocd and returned
+	void verifyData(
+		CSSM_CC_HANDLE		ccHand,
+		const CssmData		&tbs,
+		const CssmData		&sig);
+	
+	/*
+	 * Maps of cached certs, CRLs, and active queries
+	 * This one holds cached certs and CRLs.
+	 */
+	LockedMap<CSSM_HANDLE, CLCachedEntry>	cacheMap;
+	LockedMap<CSSM_HANDLE, CLQuery>			queryMap;
+
+	CLCachedCert *lookupCachedCert(CSSM_HANDLE handle);
+	CLCachedCRL	 *lookupCachedCRL(CSSM_HANDLE handle);
+};
+
+#endif //_H_APPLEX509CLSESSION
diff --git a/AppleX509CL/CLCachedEntry.cpp b/AppleX509CL/CLCachedEntry.cpp
new file mode 100644
index 00000000..d06b8bd1
--- /dev/null
+++ b/AppleX509CL/CLCachedEntry.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CLCachedEntry.cpp - classes representing cached certs and CRLs. 
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+
+#include "CLCachedEntry.h"
+
+/*
+ * CLCachedEntry base class constructor. Only job here is to cook up 
+ * a handle.
+ */
+CLCachedEntry::CLCachedEntry()
+{
+	mHandle = reinterpret_cast<CSSM_HANDLE>(this);
+}
+
+CLCachedCert::~CLCachedCert()
+{
+	delete &mCert;
+}
+
+CLCachedCRL::~CLCachedCRL()
+{
+	delete &mCrl;
+}
+
+CLQuery::CLQuery(
+	CLQueryType		type,
+	const CssmOid	&oid,
+	unsigned		numFields,
+	bool			isFromCache,
+	CSSM_HANDLE		cachedObj) :
+		mQueryType(type),
+		mFieldId(CssmAllocator::standard()),
+		mNextIndex(1),
+		mNumFields(numFields),
+		mFromCache(isFromCache),
+		mCachedObject(cachedObj)
+{
+	mFieldId.copy(oid);
+	mHandle = reinterpret_cast<CSSM_HANDLE>(this);
+}	
+
+CLQuery::~CLQuery()
+{
+	/* mFieldId auto frees */
+}
diff --git a/AppleX509CL/CLCachedEntry.h b/AppleX509CL/CLCachedEntry.h
new file mode 100644
index 00000000..09f7ab27
--- /dev/null
+++ b/AppleX509CL/CLCachedEntry.h
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CLCachedEntry.h - classes representing cached certs and CRLs. 
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+
+#ifndef	_APPLE_X509_CL_CACHED_ENTRY_H_
+#define _APPLE_X509_CL_CACHED_ENTRY_H_
+
+#include <Security/cssmtype.h>
+#include <Security/utilities.h>
+#include <Security/cssmdata.h>
+#include "DecodedCert.h"
+
+/* 
+ * There is one of these per active cached object (cert or CRL). 
+ * AppleX509CLSession keeps a map of these in cacheMap. 
+ */
+class CLCachedEntry 
+{
+public:
+	CLCachedEntry();
+	virtual ~CLCachedEntry() { }
+	CSSM_HANDLE		handle() { return mHandle; }
+private:
+	CSSM_HANDLE		mHandle;	
+};
+
+class CLCachedCert : public CLCachedEntry
+{
+public:
+	CLCachedCert(
+		DecodedCert &c) : mCert(c) { }
+	~CLCachedCert();
+	DecodedCert	&cert()	{ return mCert; }
+private:
+	/* unpacked snacc format */
+	DecodedCert &mCert;
+};
+
+class CLCachedCRL : public CLCachedEntry
+{
+public:
+	CLCachedCRL(
+		CertificateList &c) : mCrl(c) { }
+	~CLCachedCRL();
+	CertificateList	&crl()	{ return mCrl; }
+private:
+	/* unpacked snacc format */
+	CertificateList &mCrl;
+};
+
+/*
+ * An active query, always associated with a CLCachedEntry.
+ * AppleX509CLSession keeps a map of these in queryMap. 
+ *
+ * In the case of a CLCachedEntry created by an explicit {Cert,CRL}Cache op,
+ * there can be multiple queries active for a given cached cert. In
+ * the *GetFirst*FieldValue case, there is a one-to-one relationship between
+ * the CLQUery and its associated cached object.
+ *
+ * Out of paranoia in the {Cert,CRL}Cache case, we store the handle of 
+ * the associated cached object, not a ref to the object, in case the
+ * cached object has been deleted via *AbortCache. We could ref count,
+ * but that would require a lock in CLCachedEntry...looking up an object
+ * in the session's cache map should not be too expensive. 
+ */
+ 
+typedef enum {
+	CLQ_Cert,
+	CLQ_CRL
+} CLQueryType;
+
+class CLQuery 
+{
+public:
+	CLQuery(
+		CLQueryType		type,
+		const CssmOid	&oid,
+		unsigned		numFields,
+		bool			isFromCache,
+		CSSM_HANDLE		cachedObj);			
+		
+	~CLQuery();
+	
+	/*  
+	 * Accessors - all member variables are invariant after creation, except 
+	 * for nextIndex which can only increment
+	 */
+	CLQueryType		queryType() 	{ return mQueryType; }
+	const CssmOid	&fieldId()		{ return mFieldId; }
+	unsigned 		nextIndex()		{ return mNextIndex; }
+	void			incrementIndex(){ mNextIndex++; }
+	unsigned 		numFields() 	{ return mNumFields; }
+	bool			fromCache()		{ return mFromCache; }
+	CSSM_HANDLE		cachedObject()	{ return mCachedObject; }
+	CSSM_HANDLE		handle()		{ return mHandle;}
+
+private:
+	CLQueryType		mQueryType;
+	CssmAutoData 	mFieldId;		// thing we're searching for - may be empty
+	unsigned 		mNextIndex;		// index of next find op 
+	unsigned 		mNumFields;		// total available 
+	bool			mFromCache;		// true : via CertGetFirstCachedFieldValue
+									// false : via CertGetFirstFieldValue
+	CSSM_HANDLE		mCachedObject;	// of our associated cached cert/CRL
+	CSSM_HANDLE		mHandle;		// ours
+};
+
+#endif	/* _APPLE_X509_CL_CACHED_ENTRY_H_ */
diff --git a/AppleX509CL/CLCertExtensions.cpp b/AppleX509CL/CLCertExtensions.cpp
new file mode 100644
index 00000000..dcad8447
--- /dev/null
+++ b/AppleX509CL/CLCertExtensions.cpp
@@ -0,0 +1,1249 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CLCertExtensions.cpp - extensions support. A major component of DecodedCert.
+ *
+ * Created 9/8/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ *
+ */
+ 
+#include "DecodedCert.h"
+#include "cldebugging.h"
+#include "CertBuilder.h"
+#include "CLCertExtensions.h"
+#include "SnaccUtils.h"
+#include <Security/utilities.h>
+#include <Security/oidscert.h>
+#include <Security/cssmerr.h>
+#include <Security/x509defs.h>
+#include <Security/certextensions.h>
+#include <Security/cdsaUtils.h>
+#include <Security/sm_x509ce.h>
+#include <Security/globalizer.h>
+
+static AsnType *oidToSnaccObj(
+	const AsnOid &extnId);
+
+#define MIN_EXTENSIONS		4		// initial size of *mExtensions
+
+/*
+ * AsnOid "constants" which we construct and cache on demand to avoid the 
+ * somewhat expensive op of constructing them every time we test for equality 
+ * in oidToSnaccObj().
+ */
+class ExtOidCache
+{
+public:
+	ExtOidCache() :
+		mId_ce_keyUsage(id_ce_keyUsage_arc),
+		mId_ce_basicConstraints(id_ce_basicConstraints_arc),
+		mId_ce_extKeyUsage(id_ce_extKeyUsage_arc),
+		mId_ce_subjectKeyIdentifier(id_ce_subjectKeyIdentifier_arc),
+		mId_ce_authorityKeyIdentifier(id_ce_authorityKeyIdentifier_arc),
+		mId_ce_subjectAltName(id_ce_subjectAltName_arc),
+		mId_ce_certificatePolicies(id_ce_certificatePolicies_arc),
+		mId_netscape_cert_type(id_netscape_cert_type_arc)
+			{ }
+		
+	AsnOid 	mId_ce_keyUsage;
+	AsnOid	mId_ce_basicConstraints;
+	AsnOid	mId_ce_extKeyUsage;
+	AsnOid	mId_ce_subjectKeyIdentifier;
+	AsnOid	mId_ce_authorityKeyIdentifier;
+	AsnOid	mId_ce_subjectAltName;
+	AsnOid	mId_ce_certificatePolicies;
+	AsnOid	mId_netscape_cert_type;
+};
+
+static ModuleNexus<ExtOidCache> extOidCache;
+
+/*
+ * Decode tbs->Extensions into mExtensions. This involves figuring out
+ * what kind of object is represented in the octet string in the 
+ * extension, decoding it, and placing the resulting AsnType in a 
+ * new DecodedExten struct.
+ *
+ * Called when decoding either a cert (for caching it or getting its fields)
+ * or a template (only via CertGetAllTemplateFields()).
+ */
+void DecodedCert::decodeExtensions()
+{
+	CASSERT(certificateToSign != NULL);
+	Extensions *extensions = certificateToSign->extensions;
+	if(extensions == NULL) {
+		/* OK, no extensions present */
+		return;
+	}
+	
+	Extension *snaccExten = extensions->First();
+	extensions->SetCurrToFirst();
+	
+	/* traverse extension list */
+	while(snaccExten != 0) {
+		/*
+		 * For this extension->extnId, cook up an approppriate 
+		 * AsnType (KeyUsage, etc.);
+		 */
+		AsnOid &extnId = snaccExten->extnId;
+		bool berEncoded = false;
+		AsnType *snaccObj = oidToSnaccObj(extnId);
+		if(snaccObj == NULL) {
+			/* 
+			 * We don't know how to deal with this, just take the 
+			 * raw bytes, copied from snaccExte.
+			 */
+			snaccObj = new AsnOcts(snaccExten->extnValue);
+			berEncoded = true;
+		}
+		else {
+			/* 
+			 * We have a snacc-style object specific to this extension.
+			 * Decode the extensions's extnValue into that object. We don't
+			 * have to know what kind of object it is anymore. 
+			 */
+			CssmData cData(snaccExten->extnValue, snaccExten->extnValue.Len());
+			try {
+				SC_decodeAsnObj(cData, *snaccObj);
+			}
+			catch (...) {
+				/* 
+				 * FIXME - what do we do here? Is it safe to just ignore this
+				 * extension, or is the whole cert invalid?
+				 */
+				errorLog0("decodeExtensions: extension decode error\n");
+				delete snaccObj;
+				snaccObj = NULL;
+			}
+		}	
+		if(snaccObj != NULL) {
+			/* add to mExtensions if the decode was successful */
+			bool critical = false;		// default
+			if(snaccExten->critical != NULL) {
+				critical = *snaccExten->critical;
+			}
+			addExtension(snaccObj, 
+				snaccExten->extnId, 
+				critical,
+				berEncoded);
+		}
+		extensions->GoNext();
+		snaccExten = extensions->Curr();
+	}
+}
+
+/*
+ * Encode mExtensions into tbs->Extensions.
+ *
+ * Each extension object, currently stored as some AsnType subclass,
+ * is BER-encoded and the reesult is stored as an octet string
+ * (AsnOcts) in a new Extension object in the TBS.
+ *
+ * Only called from CertCreateTemplate via encodeTbs(). 
+ */
+#define MAX_EXTEN_SIZE	(4 * 1024)		/* SWAG for max encoded size */
+
+void DecodedCert::encodeExtensions()
+{
+	CertificateToSign *tbs = certificateToSign;
+	CASSERT(mState == CS_Building);
+	CASSERT((tbs != NULL) && (tbs->extensions == NULL));
+
+	if(mNumExtensions == 0) {
+		/* no extensions, no error */
+		return;
+	}
+	tbs->extensions = new Extensions;
+	Extensions *extns = tbs->extensions;
+	
+	/* for each of our DecodedExtens, append an Extension object to
+	 * tbs->extensions */
+	unsigned extenDex;
+	for(extenDex=0; extenDex<mNumExtensions; extenDex++) {
+		Extension *snaccExt = extns->Append();
+		DecodedExten *decodedExt = &mExtensions[extenDex];
+		
+		/* BER-encode the extension object if appropriate */
+		if(decodedExt->berEncoded) {
+			/* unknown extension type, it's already encoded */
+			/* A failure of this dynamic cast is a fata internal error */
+			AsnOcts *rawOcts = dynamic_cast<AsnOcts *>(decodedExt->snaccObj);
+			if(rawOcts == NULL) {
+				errorLog0("encodeExtensions: dynamic_cast failure!\n");
+				CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+			}
+			snaccExt->extnValue.Set(*rawOcts);
+		}
+		else {
+			CssmAutoData aData(alloc);
+			try {
+				SC_encodeAsnObj(*decodedExt->snaccObj, aData, MAX_EXTEN_SIZE);
+			}
+			catch (...) {
+				errorLog0("encodeExtensions: extension encode error\n");
+				throw;
+			}
+			CssmData &cData = aData.get();
+			snaccExt->extnValue.Set((char *)cData.data(), cData.length());
+		}
+		snaccExt->critical = new AsnBool(decodedExt->critical);
+		snaccExt->extnId.Set(*decodedExt->extnId);
+	}
+}
+
+
+/* 
+ * Add a new DecodedExten to mExtensions.
+ * Called from decodeExtensions and setField*.
+ * At this point, the actual extenmsion data is represented by some subclass
+ * of AsnType - either a specific extension type (e.g. KeyUsage), or as an
+ * octet string (AsnOcts) for extension types we don't understand (and which 
+ * are encoded by the app). 
+ */
+void DecodedCert::addExtension(
+	AsnType 			*snaccObj,	// e.g. KeyUsage
+	const AsnOid		&extnId,	
+	bool				critical,
+	bool				berEncoded)	// i.e., we don't know how to parse
+{
+	/* cook up a new DecodedExten, reallocing mExtensions is necessary */
+	if(mNumExtensions == mSizeofExtensions) {
+		/* expand by doubling, or initial malloc */
+		mSizeofExtensions = mNumExtensions ? 
+			(2 * mNumExtensions) : MIN_EXTENSIONS;
+		mExtensions = (DecodedExten *)alloc.realloc(
+			mExtensions, mSizeofExtensions * sizeof(DecodedExten));
+	}
+	DecodedExten *decodedExt = &mExtensions[mNumExtensions++];
+	decodedExt->extnId     = new AsnOid(extnId);
+	decodedExt->critical   = critical;
+	decodedExt->snaccObj   = snaccObj;
+	decodedExt->berEncoded = berEncoded;
+}
+
+/* 
+ * Search for DecodedExten by AsnOid or "any unknown extension".
+ * Called from getField*() and inferKeyUsage. 
+ * Returns NULL if specified extension not found.
+ */
+DecodedExten *DecodedCert::findDecodedExt(
+	const AsnOid		&extnId,		// for known extensions
+	bool				unknown,		// otherwise		
+	uint32				index, 
+	uint32				&numFields) const
+{
+	unsigned dex;
+	DecodedExten *decodedExt;
+	DecodedExten *rtnExt = NULL;
+	unsigned found = 0;
+	
+	for(dex=0; dex<mNumExtensions; dex++) {
+		CASSERT(mExtensions != NULL);
+		decodedExt = &mExtensions[dex];
+		/*
+		 * known extensions: OID match
+		 * unknown extensions: just know that we didn't decode it
+		 */
+		if( (!unknown && (*decodedExt->extnId == extnId)) || 
+		    (unknown && decodedExt->berEncoded)) {
+			
+			if(found++ == index) {
+				/* the one we want */
+				rtnExt = decodedExt;
+			}
+			if((rtnExt != NULL) && (index != 0)) {
+				/* only determine numFields on search for first one */
+				break;
+			}
+		}
+	}
+	if(rtnExt != NULL) {
+		/* sucessful return  */
+		if(index == 0) {
+			numFields = found;
+		}
+		return rtnExt;
+	}
+	else {
+		return NULL;
+	}
+}
+
+/*
+ * Common code to pass info from a DecodedExten back to app.
+ * Called from getField*().
+ */
+static void getFieldExtenCommon(
+	void 				*cdsaObj,			// e.g. CE_KeyUsage
+											// CSSM_DATA_PTR for berEncoded
+	const DecodedExten	&decodedExt, 
+	CssmOwnedData		&fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt;
+	CssmAllocator &alloc = fieldValue.allocator;
+	CssmData &fdata = fieldValue.get();
+	
+	cssmExt = (CSSM_X509_EXTENSION_PTR)alloc.malloc(sizeof(CSSM_X509_EXTENSION));
+	fdata.Data = (uint8 *)cssmExt;
+	fdata.Length = sizeof(CSSM_X509_EXTENSION);
+	CL_snaccOidToCssm(*decodedExt.extnId,
+		CssmOid::overlay(cssmExt->extnId),
+		alloc);
+	if(decodedExt.critical != NULL) {
+		cssmExt->critical = decodedExt.critical ? CSSM_TRUE : CSSM_FALSE;
+	}
+	else {
+		/* default */
+		cssmExt->critical = false;
+	}
+	if(decodedExt.berEncoded) {
+		/* an extension we never parsed or understood */
+		cssmExt->format = CSSM_X509_DATAFORMAT_ENCODED;
+		cssmExt->value.parsedValue = NULL;
+		cssmExt->BERvalue = *(reinterpret_cast<CSSM_DATA_PTR>(cdsaObj));
+	}
+	else {
+		cssmExt->format = CSSM_X509_DATAFORMAT_PARSED;
+		cssmExt->value.parsedValue = cdsaObj;
+		cssmExt->BERvalue.Data = NULL;
+		cssmExt->BERvalue.Length = 0;
+	}
+}
+
+/* 
+ * Common code for top of setField* and freeField*().
+ */
+static CSSM_X509_EXTENSION_PTR verifySetFreeExtension(
+	const CssmData &fieldValue,
+	bool berEncoded)		// false: value in value.parsedValue
+							// true : value in BERValue
+{
+	if(fieldValue.length() != sizeof(CSSM_X509_EXTENSION)) {
+		errorLog2("Set/FreeExtension: bad length : exp %d got %d\n", 
+			(int)sizeof(CSSM_X509_EXTENSION), (int)fieldValue.length());
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);			
+	}
+	CSSM_X509_EXTENSION_PTR cssmExt = 
+		reinterpret_cast<CSSM_X509_EXTENSION_PTR>(fieldValue.data());
+	if(berEncoded) {
+		if((cssmExt->value.parsedValue != NULL) || (cssmExt->BERvalue.Data == NULL)) {
+			CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);		
+		}
+	}
+	else {
+		if((cssmExt->value.parsedValue == NULL) || (cssmExt->BERvalue.Data != NULL)) {
+			CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);		
+		}
+	}
+	return cssmExt;
+}
+
+/*
+ * Common free code for all extensions. Extension-specific code must
+ * free anything beyond cdsaExt->Value.parsedValue, then we free everything 
+ * else (except the extension struct itself, which is freed by 
+ * DecodedCert::freeCertFieldData()). 
+ */
+static void freeFieldExtenCommon(
+	CSSM_X509_EXTENSION_PTR	exten,
+	CssmAllocator			&alloc)
+{
+	alloc.free(exten->extnId.Data);
+	alloc.free(exten->BERvalue.Data);		// may be NULL
+	alloc.free(exten->value.parsedValue);		// may be NULL
+}
+
+
+/* 
+ * Cook up an AsnType associated with specified extnId 
+ * When adding oid/type pairs here, also add to:
+ *   -- fieldFuncs[] in CertFields.cpp
+ *   -- and the get/set/free functions in this file.
+ */
+static AsnType *oidToSnaccObj(
+	const AsnOid &extnId)
+{
+	ExtOidCache &oc = extOidCache();
+	
+	if(extnId == oc.mId_ce_keyUsage) {
+		return new KeyUsage;
+	}
+	else if(extnId == oc.mId_ce_basicConstraints) {
+		return new BasicConstraintsSyntax;
+	}
+	else if(extnId == oc.mId_ce_extKeyUsage) {
+		return new ExtKeyUsageSyntax;
+	}	
+	else if(extnId == oc.mId_ce_subjectKeyIdentifier) {
+		return new AsnOcts;
+	}
+	else if(extnId == oc.mId_ce_authorityKeyIdentifier) {
+		return new AuthorityKeyIdentifier;
+	}
+	else if(extnId == oc.mId_ce_subjectAltName) {
+		return new GeneralNames;
+	}
+	else if(extnId == oc.mId_ce_certificatePolicies) {
+		return new CertificatePoliciesSyntax;
+	}
+	else if(extnId == oc.mId_netscape_cert_type) {
+		return new AsnBits;
+	}
+	else {
+		return NULL;
+	}
+}
+
+/* common code for top of getField* */
+template<class SnaccType, class CdsaType>
+bool GetFieldTop(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmAllocator		&alloc,
+	const AsnOid		&fieldId,
+	SnaccType			*&snaccObj,
+	CdsaType			*&cdsaObj,
+	DecodedExten		*&decodedExt)
+{
+	/* See if we have one of these in our list of DecodedExtens */
+	decodedExt = cert.findDecodedExt(fieldId, false, index, numFields);
+	if(decodedExt == NULL) {
+		return false;
+	}
+	
+	/* failure of this dynamic_cast is fatal */
+	snaccObj = dynamic_cast<SnaccType *>(decodedExt->snaccObj);  
+	if(snaccObj == NULL) {
+		errorLog0("GetFieldTop: dynamic_cast failure\n");
+		CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+	}
+	cdsaObj = (CdsaType *)alloc.malloc(sizeof(CdsaType));
+	memset(cdsaObj, 0, sizeof(CdsaType));
+	return true;
+}
+
+/***
+ *** get/set/free functions called out from CertFields.cpp
+ ***/
+
+/*
+ * One common free for extensions whose parsed value doesn't go any deeper 
+ * than cssmExt->value.parsedValue. 
+ */
+void freeFieldSimpleExtension (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	freeFieldExtenCommon(cssmExt, fieldValue.allocator);
+}
+
+/***
+ *** KeyUsage 
+ *** CDSA format 	CE_KeyUsage
+ *** SNACC format 	KeyUsage
+ *** OID 			CSSMOID_KeyUsage
+ ***/
+ 
+void setFieldKeyUsage(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CE_KeyUsage *cdsaObj = (CE_KeyUsage *)cssmExt->value.parsedValue;
+	
+	/* brute-force cdsaObj --> snaccObj */
+	char bits[sizeof(CE_KeyUsage)];
+	bits[0] = static_cast<char>((*cdsaObj) >> 8);
+	bits[1] = static_cast<char>(*cdsaObj);
+	memmove(bits, cdsaObj, sizeof(CE_KeyUsage));
+	KeyUsage *snaccObj = new KeyUsage(bits, sizeof(CE_KeyUsage) * 8);
+	
+	/* add to mExtensions */
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+
+bool getFieldKeyUsage(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	KeyUsage *snaccObj;
+	CE_KeyUsage *cdsaObj;
+	bool brtn;
+	
+	brtn = GetFieldTop<KeyUsage, CE_KeyUsage>(
+		cert,
+		index,
+		numFields,
+		fieldValue.allocator,
+		id_ce_keyUsage,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+	
+	unsigned toCopy = (snaccObj->BitLen() + 7) / 8;
+	if(toCopy > 2) {
+		/* I hope I never see this... */
+		errorLog0("getFieldKeyUsage: KeyUsage larger than 2 bytes!\n");
+		toCopy = 2;
+	}
+	unsigned char bits[2] = {0, 0};
+	memmove(bits, snaccObj->BitOcts(), toCopy);
+	*cdsaObj = (((unsigned)bits[0]) << 8) | bits[1];
+	
+	/* pass back to caller */
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+/***
+ *** Basic Constraints 
+ *** CDSA format: 	CE_BasicConstraints
+ *** SNACC format 	BasicConstraintsSyntax
+ *** OID 			CSSMOID_BasicConstraints
+ ***/
+ 
+void setFieldBasicConstraints(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	BasicConstraintsSyntax *snaccObj = new BasicConstraintsSyntax;
+	CE_BasicConstraints *cdsaObj = (CE_BasicConstraints *)cssmExt->value.parsedValue;
+	
+	/* brute-force cdsaObj --> snaccObj */
+	snaccObj->cA = new AsnBool(cdsaObj->cA ? true : false);
+	if(cdsaObj->pathLenConstraintPresent) {
+		AsnIntType val = cdsaObj->pathLenConstraint;
+		snaccObj->pathLenConstraint = new AsnInt(val);
+	}
+
+	/* add to mExtensions */
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+
+bool getFieldBasicConstraints(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	BasicConstraintsSyntax *snaccObj;
+	CE_BasicConstraints *cdsaObj;
+	bool brtn;
+	
+	brtn = GetFieldTop<BasicConstraintsSyntax, CE_BasicConstraints>(
+		cert,
+		index,
+		numFields,
+		fieldValue.allocator,
+		id_ce_basicConstraints,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+
+	if(snaccObj->cA == NULL) {
+		/* default */
+		cdsaObj->cA = CSSM_FALSE;
+	}
+	else {
+		bool val = *snaccObj->cA;
+		cdsaObj->cA = val ? CSSM_TRUE : CSSM_FALSE;
+	}
+	if(snaccObj->pathLenConstraint == NULL) {
+		cdsaObj->pathLenConstraintPresent = CSSM_FALSE;
+		cdsaObj->pathLenConstraint = 0;
+	}
+	else {
+		cdsaObj->pathLenConstraintPresent = CSSM_TRUE;
+		AsnIntType val = *snaccObj->pathLenConstraint;
+		cdsaObj->pathLenConstraint = val;
+	}
+	
+	/* pass back to caller */
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+/***
+ *** Extended Key Usage
+ *** CDSA format: 	CE_ExtendedKeyUsage
+ *** SNACC format 	ExtKeyUsageSyntax
+ *** OID 			CSSMOID_ExtendedKeyUsage
+ ***/
+void setFieldExtKeyUsage(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	ExtKeyUsageSyntax *snaccObj = new ExtKeyUsageSyntax;
+	CE_ExtendedKeyUsage *cdsaObj = (CE_ExtendedKeyUsage *)cssmExt->value.parsedValue;
+	
+	/* brute-force cdsaObj --> snaccObj, one 'purpose' (OID) at a time */
+	unsigned oidDex;
+	for(oidDex=0; oidDex<cdsaObj->numPurposes; oidDex++) {
+		KeyPurposeId *snaccPurp = snaccObj->Append();
+		CSSM_OID_PTR cdsaPurp = &cdsaObj->purposes[oidDex];
+		snaccPurp->Set(reinterpret_cast<char *>(cdsaPurp->Data), cdsaPurp->Length); 
+	}
+
+	/* add to mExtensions */
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+bool getFieldExtKeyUsage(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	ExtKeyUsageSyntax *snaccObj;
+	CE_ExtendedKeyUsage *cdsaObj;
+	bool brtn;
+	
+	brtn = GetFieldTop<ExtKeyUsageSyntax, CE_ExtendedKeyUsage>(
+		cert,
+		index,
+		numFields,
+		fieldValue.allocator,
+		id_ce_extKeyUsage,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+	
+	/* brute force snaccObj --> cdsaObj, one purpose at a time */ 
+	CssmAllocator &alloc = fieldValue.allocator;
+	cdsaObj->numPurposes = snaccObj->Count();
+	cdsaObj->purposes = (CSSM_OID_PTR)alloc.malloc(cdsaObj->numPurposes * 
+			sizeof(CSSM_OID));
+	snaccObj->SetCurrToFirst();
+	unsigned oidDex;
+	for(oidDex=0; oidDex<cdsaObj->numPurposes; oidDex++) {
+		CL_snaccOidToCssm(*snaccObj->Curr(),
+			CssmOid::overlay(cdsaObj->purposes[oidDex]),
+			alloc);
+		snaccObj->GoNext();
+	}
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+void freeFieldExtKeyUsage(
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CssmAllocator &alloc = fieldValue.allocator;
+	CE_ExtendedKeyUsage *cdsaObj = 
+		(CE_ExtendedKeyUsage *)cssmExt->value.parsedValue;
+	unsigned oidDex;
+	for(oidDex=0; oidDex<cdsaObj->numPurposes; oidDex++) {
+		alloc.free(cdsaObj->purposes[oidDex].Data);
+	}
+	alloc.free(cdsaObj->purposes);
+	freeFieldExtenCommon(cssmExt, alloc);		// frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Subject Key Identifier
+ *** CDSA format: 	CE_SubjectKeyID, which is just a CSSM_DATA
+ *** SNACC format 	AsnOcts
+ *** OID 			CSSMOID_SubjectKeyIdentifier
+ ***/
+ 
+void setFieldSubjectKeyId(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CE_SubjectKeyID *cdsaObj = (CE_SubjectKeyID *)cssmExt->value.parsedValue;
+	AsnOcts *snaccObj = new AsnOcts((char *)cdsaObj->Data, cdsaObj->Length);
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+bool getFieldSubjectKeyId(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	AsnOcts *snaccObj;
+	CE_SubjectKeyID *cdsaObj;
+	bool brtn;
+	
+	brtn = GetFieldTop<AsnOcts, CE_SubjectKeyID>(
+		cert,
+		index,
+		numFields,
+		fieldValue.allocator,
+		id_ce_subjectKeyIdentifier,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+	CL_AsnOctsToCssmData(*snaccObj, *cdsaObj, fieldValue.allocator);
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+void freeFieldSubjectKeyId (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CssmAllocator &alloc = fieldValue.allocator;
+	CE_SubjectKeyID *cdsaObj = (CE_SubjectKeyID *)cssmExt->value.parsedValue;
+	alloc.free(cdsaObj->Data);
+	freeFieldExtenCommon(cssmExt, alloc);		// frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Authority Key Identifier
+ *** CDSA format: 	CE_AuthorityKeyID
+ *** SNACC format 	AuthorityKeyIdentifier
+ *** OID 			CSSMOID_AuthorityKeyIdentifier
+ ***/
+ 
+void setFieldAuthorityKeyId(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CE_AuthorityKeyID *cdsaObj = (CE_AuthorityKeyID *)cssmExt->value.parsedValue;
+	AuthorityKeyIdentifier *snaccObj = new AuthorityKeyIdentifier;
+
+	/* 
+	 * brute-force a CDSA-style CE_AuthorityKeyID into snacc-style 
+	 * AuthorityKeyIdentifier
+	 */
+	if(cdsaObj->keyIdentifierPresent) {
+		/* Just an AsnOcts */
+		snaccObj->keyIdentifier = new AsnOcts((char *)cdsaObj->keyIdentifier.Data,
+			cdsaObj->keyIdentifier.Length);
+	}
+	if(cdsaObj->generalNamesPresent ) {
+		/* GeneralNames, the hard one */
+		snaccObj->authorityCertIssuer = CL_cdsaGeneralNamesToSnacc(
+			*cdsaObj->generalNames);
+	}
+	if(cdsaObj->serialNumberPresent) {
+		/* boils down to BigIntegerStr, or AsnOcts */
+		snaccObj->authorityCertSerialNumber = 
+			new CertificateSerialNumber((char *)cdsaObj->serialNumber.Data,
+				cdsaObj->serialNumber.Length);
+	}
+	
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+bool getFieldAuthorityKeyId(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	AuthorityKeyIdentifier *snaccObj;
+	CE_AuthorityKeyID *cdsaObj;
+	bool brtn;
+	CssmAllocator &alloc = fieldValue.allocator;
+	
+	brtn = GetFieldTop<AuthorityKeyIdentifier, CE_AuthorityKeyID>(
+		cert,
+		index,
+		numFields,
+		alloc,
+		id_ce_authorityKeyIdentifier,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+	
+	/* brute-force a snacc-style AuthorityKeyIdentifier into CDSA format */
+	if(snaccObj->keyIdentifier != NULL) {
+		/* Just an AsnOcts */
+		cdsaObj->keyIdentifierPresent = CSSM_TRUE;
+		CL_AsnOctsToCssmData(*snaccObj->keyIdentifier, 
+			cdsaObj->keyIdentifier, 
+			alloc);
+	}
+	if(snaccObj->authorityCertIssuer != NULL) {
+		/* GeneralNames, the hard one */
+		cdsaObj->generalNamesPresent = CSSM_TRUE;
+		cdsaObj->generalNames = (CE_GeneralNames *)alloc.malloc(sizeof(CE_GeneralName));
+			CL_snaccGeneralNamesToCdsa(*snaccObj->authorityCertIssuer, 
+				*cdsaObj->generalNames,
+				alloc);
+	}
+	if(snaccObj->authorityCertSerialNumber != NULL) {
+		/* boils down to BigIntegerStr, or AsnOcts */
+		cdsaObj->serialNumberPresent = CSSM_TRUE;
+		CL_AsnOctsToCssmData(*snaccObj->authorityCertSerialNumber, 
+			cdsaObj->serialNumber, 
+			alloc);
+	}
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+static void freeFieldGeneralNames(
+	CE_GeneralNames *cdsaObj,
+	CssmAllocator &alloc)
+{
+	if(cdsaObj == NULL) {
+		return;
+	}
+	for(unsigned i=0; i<cdsaObj->numNames; i++) {
+		alloc.free(cdsaObj->generalName[i].name.Data);
+	}
+	if(cdsaObj->numNames) {
+		memset(cdsaObj->generalName, 0, cdsaObj->numNames * sizeof(CE_GeneralName));
+	}
+	memset(cdsaObj, 0, sizeof(CE_GeneralNames));
+}
+
+void freeFieldAuthorityKeyId (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CssmAllocator &alloc = fieldValue.allocator;
+	CE_AuthorityKeyID *cdsaObj = (CE_AuthorityKeyID *)cssmExt->value.parsedValue;
+	alloc.free(cdsaObj->keyIdentifier.Data);
+	freeFieldGeneralNames(cdsaObj->generalNames, alloc);
+	alloc.free(cdsaObj->serialNumber.Data);
+	memset(cdsaObj, 0, sizeof(CE_AuthorityKeyID));
+	freeFieldExtenCommon(cssmExt, alloc);		// frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Subject alternate name
+ *** CDSA Format:	CE_GeneralNames
+ *** SNACC format:	GeneralNames
+ *** OID: 			CSSMOID_SubjectAltName
+ ***/
+void setFieldSubjAltName(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CE_GeneralNames *cdsaObj = (CE_GeneralNames *)cssmExt->value.parsedValue;
+	GeneralNames *snaccObj = CL_cdsaGeneralNamesToSnacc(*cdsaObj);
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+bool getFieldSubjAltName(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	GeneralNames *snaccObj;
+	CE_GeneralNames *cdsaObj;
+	bool brtn;
+	
+	brtn = GetFieldTop<GeneralNames, CE_GeneralNames>(
+		cert,
+		index,
+		numFields,
+		fieldValue.allocator,
+		id_ce_subjectAltName,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+	CL_snaccGeneralNamesToCdsa(*snaccObj, *cdsaObj,	fieldValue.allocator);
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+void freeFieldSubjAltName (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CssmAllocator &alloc = fieldValue.allocator;
+	CE_GeneralNames *cdsaObj = (CE_GeneralNames *)cssmExt->value.parsedValue;
+	freeFieldGeneralNames(cdsaObj, alloc);
+	freeFieldExtenCommon(cssmExt, alloc);		// frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Certificate Policies
+ *** CDSA Format:	CE_CertPolicies
+ *** SNACC format:	CertificatePoliciesSyntax
+ *** OID: 			CSSMOID_CertificatePolicies
+ ***/
+ 
+#define MAX_IA5_NAME_SIZE	1024
+
+void setFieldCertPolicies(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CssmAllocator &alloc = CssmAllocator::standard();
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CertificatePoliciesSyntax *snaccObj = new CertificatePoliciesSyntax;
+	CE_CertPolicies *cdsaObj = (CE_CertPolicies *)cssmExt->value.parsedValue;
+	
+	/* brute-force cdsaObj --> snaccObj */
+	for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) {
+		CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex];
+		PolicyInformation *sPolInfo = snaccObj->Append();
+		sPolInfo->policyIdentifier.Set((char *)cPolInfo->certPolicyId.Data,
+			cPolInfo->certPolicyId.Length);
+		if(cPolInfo->numPolicyQualifiers != 0) {
+			sPolInfo->policyQualifiers = new PolicyInformationSeqOf;
+		}
+		for(unsigned qualDex=0; qualDex<cPolInfo->numPolicyQualifiers; qualDex++) {
+			CE_PolicyQualifierInfo *cQualInfo = &cPolInfo->policyQualifiers[qualDex];
+			PolicyQualifierInfo *sQualInfo = sPolInfo->policyQualifiers->Append();
+			
+			/* OK we're at the lowest level. 
+			 * policyQualifierId == id_qt_cps: qualifier is an IA5 string,
+			 * incoming data is its contents. Else incoming data is an encoded
+			 * blob we pass on directly.
+			 */
+			sQualInfo->policyQualifierId.Set(
+				(char *)cQualInfo->policyQualifierId.Data,
+					cQualInfo->policyQualifierId.Length);
+
+			/* we'll convert this incoming ptr/len.... */
+			uint8 *rawData = cQualInfo->qualifier.Data;
+			unsigned rawDataLen = cQualInfo->qualifier.Length;
+			/* to this, somehow; it'll be used to build the required AsnAny.  */
+			CssmAutoData aData(alloc);
+			
+			if(sQualInfo->policyQualifierId == id_qt_cps) {
+				/* build & encode an IA5String */
+				IA5String *ia5 = new IA5String((char *)rawData, rawDataLen);
+				SC_encodeAsnObj(*ia5, aData, MAX_IA5_NAME_SIZE);
+				delete ia5;
+			}
+			else {
+				/* copy over directly */
+				aData.copy(rawData, rawDataLen);
+			}
+			
+			/* install the result into CSM_Buffer, which mallocs & copies */
+			sQualInfo->qualifier = new AsnAny;
+			char *cp = aData;
+			sQualInfo->qualifier->value = new CSM_Buffer(cp, aData.length());
+			aData.reset();
+		}	/* for each qualifier */
+	}	/* for each policy */
+	
+	/* add to mExtensions */
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+bool getFieldCertPolicies(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	CertificatePoliciesSyntax *snaccObj;
+	CE_CertPolicies *cdsaObj;
+	bool brtn;
+	CssmAllocator &alloc = fieldValue.allocator;
+	brtn = GetFieldTop<CertificatePoliciesSyntax, CE_CertPolicies>(
+		cert,
+		index,
+		numFields,
+		fieldValue.allocator,
+		id_ce_certificatePolicies,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+
+	/* brute force CertificatePoliciesSyntax --> CE_CertPolicies */
+	cdsaObj->numPolicies = snaccObj->Count();
+	unsigned sz = cdsaObj->numPolicies * sizeof(CE_PolicyInformation);
+	cdsaObj->policies = (CE_PolicyInformation *)alloc.malloc(sz);
+	memset(cdsaObj->policies, 0, sz);
+	snaccObj->SetCurrToFirst();
+	for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) {
+		CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex];
+		PolicyInformation *sPolInfo = snaccObj->Curr();
+		CssmOid &cOid = CssmOid::overlay(cPolInfo->certPolicyId);
+		CL_snaccOidToCssm(sPolInfo->policyIdentifier, cOid, alloc);
+		if(sPolInfo->policyQualifiers == NULL) {
+			continue;
+		}
+		cPolInfo->numPolicyQualifiers = sPolInfo->policyQualifiers->Count();
+		cPolInfo->policyQualifiers = (CE_PolicyQualifierInfo *)
+			alloc.malloc(cPolInfo->numPolicyQualifiers *
+				sizeof(CE_PolicyQualifierInfo));
+		sPolInfo->policyQualifiers->SetCurrToFirst();
+		for(unsigned qualDex=0; qualDex<cPolInfo->numPolicyQualifiers; qualDex++) {
+			PolicyQualifierInfo *sQualInfo = sPolInfo->policyQualifiers->Curr();
+			CE_PolicyQualifierInfo *cQualInfo = &cPolInfo->policyQualifiers[qualDex];
+			
+			/* 
+			 * leaf. 
+			 * policyQualifierId == id_qt_cps : IA5String - decode and return
+			 * contents. Else return whole thing. 
+			 */
+			CssmOid &cOid2 = CssmOid::overlay(cQualInfo->policyQualifierId);
+			CL_snaccOidToCssm(sQualInfo->policyQualifierId, cOid2, alloc);
+			/* convert this: */
+			CSM_Buffer *cbuf = sQualInfo->qualifier->value;
+			/* to this */
+			CssmRemoteData outData(alloc, cQualInfo->qualifier);
+			if(sQualInfo->policyQualifierId == id_qt_cps) {
+				IA5String ia5;
+				CssmAutoData berData(alloc, cbuf->Access(), cbuf->Length());
+				/* error is fatal, punt the whole kit'n'kaboodle and leak */
+				SC_decodeAsnObj(berData, ia5);
+				char *src = ia5;
+				outData.copy(src, ia5.Len());
+			}
+			else {
+				outData.copy(cbuf->Access(), cbuf->Length());
+			}
+			outData.release();
+			sPolInfo->policyQualifiers->GoNext();
+		}
+		snaccObj->GoNext();
+	}
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+void freeFieldCertPolicies (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CssmAllocator &alloc = fieldValue.allocator;
+	CE_CertPolicies *cdsaObj = (CE_CertPolicies *)cssmExt->value.parsedValue;
+	for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) {
+		CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex];
+		alloc.free(cPolInfo->certPolicyId.Data);
+		for(unsigned qualDex=0; qualDex<cPolInfo->numPolicyQualifiers; qualDex++) {
+			CE_PolicyQualifierInfo *cQualInfo = &cPolInfo->policyQualifiers[qualDex];
+			alloc.free(cQualInfo->policyQualifierId.Data);
+			alloc.free(cQualInfo->qualifier.Data);
+		}
+		alloc.free(cPolInfo->policyQualifiers);
+	}
+	alloc.free(cdsaObj->policies);
+	freeFieldExtenCommon(cssmExt, alloc);		// frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Netscape cert type
+ *** CDSA Format:	CE_NetscapeCertType (a uint16)
+ *** SNACC format:	AsnBits
+ *** OID: 			CSSMOID_NetscapeCertType
+ ***/
+void setFieldNetscapeCertType(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CE_NetscapeCertType *cdsaObj = (CE_NetscapeCertType *)cssmExt->value.parsedValue;
+	
+	char bits[sizeof(CE_NetscapeCertType)];
+	bits[0] = static_cast<char>((*cdsaObj) >> 8);
+	bits[1] = static_cast<char>(*cdsaObj);
+	memmove(bits, cdsaObj, sizeof(CE_NetscapeCertType));
+	AsnBits *snaccObj = new AsnBits(bits, sizeof(CE_NetscapeCertType) * 8);
+	
+	/* add to mExtensions */
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+bool getFieldNetscapeCertType(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	AsnBits *snaccObj;
+	CE_NetscapeCertType *cdsaObj;
+	bool brtn;
+	
+	brtn = GetFieldTop<AsnBits, CE_NetscapeCertType>(
+		cert,
+		index,
+		numFields,
+		fieldValue.allocator,
+		id_netscape_cert_type,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+
+	unsigned toCopy = (snaccObj->BitLen() + 7) / 8;
+	if(toCopy > 2) {
+		/* I hope I never see this... */
+		errorLog0("getFieldNetscapeCertType: bitstring larger than 2 bytes!\n");
+		toCopy = 2;
+	}
+	unsigned char bits[2] = {0, 0};
+	memmove(bits, snaccObj->BitOcts(), toCopy);
+	*cdsaObj = (((unsigned)bits[0]) << 8) | bits[1];
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+/***
+ *** unknown extensions 
+ *** CDSA format: raw bytes in a CSSM_DATA. This data is the BER-encoding of
+ ***              some extension struct we don't know about.
+ *** SNACC format AsnOcts
+ *** OID 		  CSSMOID_X509V3CertificateExtensionCStruct
+ ***/
+
+void setFieldUnknownExt(
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, true);
+	AsnOcts *snaccObj = new AsnOcts(
+		reinterpret_cast<char *>(cssmExt->BERvalue.Data),
+		cssmExt->BERvalue.Length);
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, true); 
+}
+
+bool getFieldUnknownExt(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	AsnOid noOidLikeThis (1, 2);	// a dummy argument
+	DecodedExten *decodedExt = cert.findDecodedExt(noOidLikeThis, 
+		true, index, numFields);
+	if(decodedExt == NULL) {
+		return false;
+	}
+	/* failure of this dynamic_cast is fatal */
+	AsnOcts *snaccObj = dynamic_cast<AsnOcts *>(decodedExt->snaccObj);  
+	if(snaccObj == NULL) {
+		errorLog0("getFieldUnknownExt: dynamic_cast failure\n");
+		CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+	}
+	char *octData = *snaccObj;
+	CssmAutoData encodedBytes(fieldValue.allocator, octData, snaccObj->Len());
+	/* easier way to do this...? */
+	CssmData cData = encodedBytes.release();
+	getFieldExtenCommon(&cData, *decodedExt, fieldValue);
+	return true;
+}
+
+void freeFieldUnknownExt (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, true);
+	CssmAllocator &alloc = fieldValue.allocator;
+	freeFieldExtenCommon(cssmExt, alloc);		// frees extnId, parsedValue, BERvalue
+}
+
+
+
+#if template_pcode
+
+/***
+ *** Subject alternate name
+ *** CDSA Format:	CE_GeneralNames
+ *** SNACC format:	GeneralNames
+ *** OID: 			CSSMOID_SubjectAltName
+ ***/
+void setFieldSomeExt(		
+	DecodedCert	&cert, 
+	const CssmData &fieldValue) 
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	new an approppriate AsnType snaccObj (KeyUsage, etc.);
+	extension-specific e.g. CE_KeyUsage *cdsaObj = cssmExt->value.parsedValue;
+	/* brute-force cdsaObj --> snaccObj */
+	...
+	/* add to mExtensions */
+	cert.addExtension(snaccObj, cssmExt->extnId, cssmExt->critical, false); 
+}
+
+bool getFieldSomeExt(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) 
+{
+	DecodedExten *decodedExt;
+	e.g. ExtKeyUsageSyntax *snaccObj;
+	e.g. CE_ExtendedKeyUsage *cdsaObj;
+	bool brtn;
+	
+	brtn = GetFieldTop<ExtKeyUsageSyntax, CE_ExtendedKeyUsage>(
+		cert,
+		index,
+		numFields,
+		fieldValue.allocator,
+		e.g. id_ce_extKeyUsage,
+		snaccObj,
+		cdsaObj,
+		decodedExt);
+	if(!brtn) {
+		return false;
+	}
+
+	brute force snaccObj --> cdsaObj;
+	getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+	return true;
+}
+
+/* only used if complex structs below cssmExt->value.parsedValue */
+void freeFieldSomeExt (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+	CssmAllocator &alloc = fieldValue.allocator;
+	free the stuff in cssmExt->value.parsedValue;
+	freeFieldExtenCommon(cssmExt, alloc);		// frees extnId, parsedValue, BERvalue
+}
+
+#endif
diff --git a/AppleX509CL/CLCertExtensions.h b/AppleX509CL/CLCertExtensions.h
new file mode 100644
index 00000000..acfc01f9
--- /dev/null
+++ b/AppleX509CL/CLCertExtensions.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CLCertExtensions.h - extern declarations of get/set/free functions implemented in
+ *                    CertExtensions,cpp and used only in CertFields.cpp.
+ *
+ * Created 9/8/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+
+#ifndef	_CL_CERT_EXTENSIONS_H_
+#define _CL_CERT_EXTENSIONS_H_
+
+#include "DecodedCert.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Functions to map OID --> {get,set,free}field
+ */
+typedef bool (getFieldFcn) (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue);	// RETURNED
+typedef void (setFieldFcn) (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue);
+typedef void (freeFieldFcn) (
+	CssmOwnedData		&fieldValue);
+
+getFieldFcn getFieldKeyUsage, getFieldBasicConstraints, getFieldExtKeyUsage,
+	getFieldSubjectKeyId, getFieldAuthorityKeyId, getFieldSubjAltName,
+	getFieldCertPolicies, getFieldNetscapeCertType, getFieldUnknownExt;
+setFieldFcn setFieldKeyUsage, setFieldBasicConstraints, setFieldExtKeyUsage,
+	setFieldSubjectKeyId, setFieldAuthorityKeyId, setFieldSubjAltName,
+	setFieldCertPolicies, setFieldNetscapeCertType, setFieldUnknownExt;
+freeFieldFcn freeFieldSimpleExtension, freeFieldExtKeyUsage, freeFieldSubjectKeyId,
+	freeFieldAuthorityKeyId, freeFieldSubjAltName, freeFieldCertPolicies, 
+	freeFieldUnknownExt;
+	
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _CERT_EXTENSIONS_H_*/
diff --git a/AppleX509CL/CSPAttacher.cpp b/AppleX509CL/CSPAttacher.cpp
new file mode 100644
index 00000000..4569450f
--- /dev/null
+++ b/AppleX509CL/CSPAttacher.cpp
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CSPAttacher.cpp - process-wide class which loads and attaches to CSP at most
+ *				     once, and detaches and unloads the CSP when this code is
+ *	 			     unloaded.
+ */
+
+#include "CSPAttacher.h"
+#include "cldebugging.h"
+#include <Security/globalizer.h>
+#include <Security/threading.h>
+#include <Security/cssmalloc.h>
+#include <Security/cssmapple.h>
+#include <Security/cssmtype.h>
+#include <Security/cssmapi.h>
+
+class CSPAttacher
+{
+public:
+	CSPAttacher() :
+		mCspHand(CSSM_INVALID_HANDLE),
+		mCspDlHand(CSSM_INVALID_HANDLE)
+			{ }
+	~CSPAttacher();
+	CSSM_CSP_HANDLE			getCspHand(bool bareCsp);
+	
+private:
+	/* connection to CSP and CSPDL, evaluated lazily */
+	CSSM_HANDLE				mCspHand;
+	CSSM_HANDLE				mCspDlHand;
+	Mutex					mLock;
+};
+
+/* the single global thing */
+static ModuleNexus<CSPAttacher> cspAttacher;
+
+static void *CL_malloc(
+	 uint32 size,
+     void *allocref)
+{
+	return CssmAllocator::standard().malloc(size);
+}
+
+static void CL_free(
+     void *memblock,
+     void *allocref)
+{
+	CssmAllocator::standard().free(memblock);
+}
+
+static void *CL_realloc(
+     void *memblock,
+     uint32 size,
+     void *allocref)
+{
+	return CssmAllocator::standard().realloc(memblock, size);
+}
+
+static void *CL_calloc(
+     uint32 num,
+     uint32 size,
+     void *allocref)
+{
+	return CssmAllocator::standard().calloc(num, size);
+}
+
+static const CSSM_API_MEMORY_FUNCS CL_memFuncs = {
+	CL_malloc,
+	CL_free,
+	CL_realloc,
+ 	CL_calloc,
+ 	NULL
+ };
+
+
+/*
+ * This only gets called when cspAttacher get deleted, i.e., when this code
+ * is actually unloaded from the process's address space.
+ */
+CSPAttacher::~CSPAttacher()
+{
+	StLock<Mutex> 	_(mLock);
+
+	if(mCspHand != CSSM_INVALID_HANDLE) {
+		CSSM_ModuleDetach(mCspHand);
+		CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL);
+	}
+	if(mCspDlHand != CSSM_INVALID_HANDLE) {
+		CSSM_ModuleDetach(mCspDlHand);
+		CSSM_ModuleUnload(&gGuidAppleCSPDL, NULL, NULL);
+	}
+}
+
+CSSM_CSP_HANDLE CSPAttacher::getCspHand(bool bareCsp)
+{
+	const char 		*modName;
+	CSSM_RETURN		crtn;
+	const CSSM_GUID *guid;
+	CSSM_VERSION 	vers = {2, 0};
+	StLock<Mutex> 	_(mLock);
+	CSSM_CSP_HANDLE	cspHand;
+	
+	if(bareCsp) {
+		if(mCspHand != CSSM_INVALID_HANDLE) {
+			/* already connected */
+			return mCspHand;
+		}	
+		guid = &gGuidAppleCSP;
+		modName = "AppleCSP";
+	}
+	else {
+		if(mCspDlHand != CSSM_INVALID_HANDLE) {
+			/* already connected */
+			return mCspDlHand;
+		}	
+		guid = &gGuidAppleCSPDL;
+		modName = "AppleCSPDL";
+	}
+	crtn = CSSM_ModuleLoad(guid,
+		CSSM_KEY_HIERARCHY_NONE,
+		NULL,			// eventHandler
+		NULL);			// AppNotifyCallbackCtx
+	if(crtn) {
+		errorLog2("AppleX509CLSession::cspAttach: error (%d) loading %s\n",
+			(int)crtn, modName);
+		CssmError::throwMe(crtn);
+	}
+	crtn = CSSM_ModuleAttach (guid,
+		&vers,
+		&CL_memFuncs,			// memFuncs
+		0,						// SubserviceID
+		CSSM_SERVICE_CSP,		// SubserviceFlags 
+		0,						// AttachFlags
+		CSSM_KEY_HIERARCHY_NONE,
+		NULL,					// FunctionTable
+		0,						// NumFuncTable
+		NULL,					// reserved
+		&cspHand);
+	if(crtn) {
+		errorLog2("AppleX509CLSession::cspAttach: error (%d) attaching to %s\n",
+			(int)crtn, modName);
+		CssmError::throwMe(crtn);
+	}
+	if(bareCsp) {
+		mCspHand = cspHand;
+	}
+	else {
+		mCspDlHand = cspHand;
+	}
+	return cspHand;
+}
+
+/* 
+ * Just one public function - "give me a CSP handle".
+ *   bareCsp true: AppleCSP
+ *   bareCsp false: AppleCSPDL
+ */
+CSSM_CSP_HANDLE	getGlobalCspHand(bool bareCsp)
+{
+	return cspAttacher().getCspHand(bareCsp);
+}
+
diff --git a/AppleX509CL/CSPAttacher.h b/AppleX509CL/CSPAttacher.h
new file mode 100644
index 00000000..6b08ca48
--- /dev/null
+++ b/AppleX509CL/CSPAttacher.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CSPAttacher.h - process-wide class which loads and attaches to CSP at most
+ *				   once, and detaches and unloads the CSP when this code is
+ *	 			   unloaded.
+ */
+ 
+#ifndef	_CSP_ATTACHER_H_
+#define _CSP_ATTACHER_H_
+
+#include <Security/cssmtype.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* 
+ * Just one public function - "give me a CSP handle".
+ *   bareCsp true : AppleCSP
+ *   bareCsp false: AppleCSPDL
+ *
+ * Throws a CssmError on failure. 
+ */
+extern CSSM_CSP_HANDLE	getGlobalCspHand(bool bareCsp);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _CSP_ATTACHER_H_ */
\ No newline at end of file
diff --git a/AppleX509CL/CVSVersionInfo.txt b/AppleX509CL/CVSVersionInfo.txt
new file mode 100644
index 00000000..a1de6b38
--- /dev/null
+++ b/AppleX509CL/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:52 mb Exp $
+# $Name: Security-28 $
+ProjectName: AppleX509CL
+ProjectVersion: 3
diff --git a/AppleX509CL/CertBuilder.cpp b/AppleX509CL/CertBuilder.cpp
new file mode 100644
index 00000000..4a3a093a
--- /dev/null
+++ b/AppleX509CL/CertBuilder.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CertBuilder.cpp - sublasses of various snacc-generated cert-related
+ * classes. 
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+
+#include "CertBuilder.h"
+#include <Security/cssmerr.h>
+#include <Security/utilities.h>
+
+#define BUF_ENC_EXTRA	64
+
+/*
+ * Name is a complex structure which boils down to an arbitrarily
+ * large array of (usually) printable names. We facilitate the
+ * construction of the array, one AttributeTypeAndDistinguishedValue
+ * per RelativeDistinguishedName. This is the format commonly used
+ * in the real world, though it's legal to have multiple ATDVs
+ * per RDN - we just don't do it here. 
+ *
+ * Typically the object manipulated here is inserted into a 
+ * CertificateToSign object, as issuer or subject. 
+ */
+void NameBuilder::addATDV(  
+		const AsnOid &type,		// id_at_commonName, etc. from sm_x501if
+		const char *value,		// the bytes
+		size_t valueLen,
+		DirectoryString::ChoiceIdEnum stringType,	
+								// printableStringCid, etc.
+								//   from sm_x520sa
+		bool primaryDistinguished)
+{
+	/* cook up the RDN sequence first time thru */
+	if(rDNSequence == NULL) {
+		rDNSequence = new RDNSequence;
+		choiceId = rDNSequenceCid;		// no others available
+	}
+	
+	/* one RelativeDistinguishedName and one ATDV */
+	RelativeDistinguishedName *rdn = rDNSequence->Append();
+	AttributeTypeAndDistinguishedValue *atdv = rdn->Append();
+	
+	/* 
+	 * fill in the ATDV
+	 * FIXME - AttributeTypeAndDistinguishedValueSetOf??? What's that?
+	 */
+	atdv->type = type;
+	if(!primaryDistinguished) {
+		/* default is true, only encode if not default */
+		atdv->primaryDistinguished = new AsnBool(primaryDistinguished);
+	}
+	
+	/* DirectoryString from sm_x520sa */
+	DirectoryString dirStr;
+	dirStr.choiceId = stringType;
+	switch(stringType) {
+		case DirectoryString::teletexStringCid:
+			dirStr.teletexString = new TeletexString(value, valueLen);
+			break;
+		case DirectoryString::printableStringCid:
+			dirStr.printableString = new PrintableString(value, valueLen);
+			break;
+		case DirectoryString::universalStringCid:
+			dirStr.universalString = new UniversalString(value, valueLen);
+			break;
+		case DirectoryString::bmpStringCid:
+			dirStr.bmpString = new BMPString(value, valueLen);
+			break;
+		case DirectoryString::utf8StringCid:
+			dirStr.utf8String = new UTF8String(value, valueLen);
+			break;
+	}
+
+	/* 
+	 * As far as I can tell, atdv->value.value is a CSM_Buffer containing 
+	 * the encoded dirStr. First malloc a dest buffer...
+	 */
+	size_t bufLen = valueLen + BUF_ENC_EXTRA;
+	char *buf = (char *)calloc(1, bufLen);
+	if(buf == NULL) {
+		CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
+	}
+	
+	/* encode dirStr --> abuf */
+	AsnBuf abuf;
+	abuf.Init(buf, bufLen);
+	abuf.ResetInWriteRvsMode();
+	AsnLen bytesEnc;
+	dirStr.BEncPdu(abuf, bytesEnc);
+	if(bytesEnc > bufLen) {
+		#ifndef NDEBUG
+		printf("Whoops! Buffer overflow\n");
+		#endif
+		/* throw */
+	}
+	
+	/* install the result into CSM_Buffer, which mallocs & copies */
+	atdv->value.value = new CSM_Buffer(abuf.DataPtr(), abuf.DataLen());
+	free(buf);
+}
+
+/*
+ * Custom AsnOid, used for converting CssmOid to AsnOid. The Snacc class
+ * declaration doesn't provide a means to construct from, or set by,
+ * pre-encoded OID bytes (which are available in a CssmOid).
+ */
+OidBuilder::OidBuilder(const CSSM_OID &coid)
+{
+    oid =  Asn1Alloc (coid.Length);
+	memcpy(oid, coid.Data, coid.Length);
+	octetLen = coid.Length;
+}
+
diff --git a/AppleX509CL/CertBuilder.h b/AppleX509CL/CertBuilder.h
new file mode 100644
index 00000000..4f67c434
--- /dev/null
+++ b/AppleX509CL/CertBuilder.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CertBuilder.h - sublasses of various snacc-generated cert-related
+ * classes. 
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+
+#ifndef	_CERT_BUILDER_H_
+#define _CERT_BUILDER_H_
+
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+#include <Security/sm_x501if.h>
+#include <Security/sm_x520sa.h>
+#include <Security/sm_x411mtsas.h>
+#include <Security/sm_x509cmn.h>
+#include <Security/sm_x509af.h>
+#include <Security/pkcs9oids.h>
+#include <Security/sm_x509ce.h>
+#include <Security/sm_cms.h>
+#include <Security/sm_ess.h>
+
+#include <Security/cssmtype.h>
+
+/*
+ * Name is a complex structure which boils down to an arbitrarily
+ * large array of (usually) printable names. We facilitate the
+ * construction of the array, one AttributeTypeAndDistinguishedValue
+ * per RelativeDistinguishedName. This is the format commonly used
+ * in the real world, though it's legal to have multiple ATDVs
+ * per RDN - we just don't do it here. 
+ *
+ * Typically the object manipulated here is inserted into a 
+ * CertificateToSign object, as issuer or subject. 
+ */
+class NameBuilder : public Name		// Name from sm_x501if
+{
+public:
+	void addATDV(  
+		const AsnOid					&type,		// id_at_commonName, etc. 
+													//   from sm_x520sa
+		const char 						*value,		// the bytes
+		size_t							valueLen,
+		DirectoryString::ChoiceIdEnum	stringType,	// printableStringCid, etc.
+													//   from sm_x520sa
+		bool							primaryDistinguished = true);   
+};
+
+
+/*
+ * Custom AsnOid, used for converting CssmOid to AsnOid. The Snacc class
+ * declaration doesn't provide a means to construct from, or set by,
+ * pre-encoded OID bytes (which are available in a CssmOid).
+ */
+class OidBuilder : public AsnOid
+{
+public:
+	OidBuilder(const CSSM_OID &coid);
+	~OidBuilder() { }
+};
+
+#endif	/* _CERT_BUILDER_H_ */
+
diff --git a/AppleX509CL/CertFields.cpp b/AppleX509CL/CertFields.cpp
new file mode 100644
index 00000000..63fb159b
--- /dev/null
+++ b/AppleX509CL/CertFields.cpp
@@ -0,0 +1,1291 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CertFields.cpp - convert between snacc-based Certificate components and CDSA-style
+ *                  fields. A major component of DecodedCert.
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ *
+ * The code in this file is dreadfully gross. There is no practical way to do this
+ * work (converting between C++ snacc types and C CSDA types) without the kind
+ * of brute force code you see here. 
+ */
+
+#include "DecodedCert.h"
+#include "cldebugging.h"
+#include "CertBuilder.h"
+#include "CLCertExtensions.h"
+#include "SnaccUtils.h"
+#include <Security/utilities.h>
+#include <Security/oidscert.h>
+#include <Security/cssmerr.h>
+#include <Security/x509defs.h>
+#include <Security/cdsaUtils.h>
+
+/*
+ * Routines for common validity checking for certificateToSign fields.
+ *
+ * Call from setField*: verify field isn't already set, optionally validate
+ * input length
+ */
+static void tbsSetCheck(
+	void				*fieldToSet,
+	const CssmData		&fieldValue,
+	uint32				expLength,
+	const char			*op)
+{
+	if(fieldToSet != NULL) {						
+		/* can't add another */
+		errorLog1("setField(%s): field already set\n", op);
+		CssmError::throwMe(CSSMERR_CL_INVALID_NUMBER_OF_FIELDS);		
+	}										
+	if((expLength != 0) && (fieldValue.length() != expLength)) {		
+		errorLog3("setField(%s): bad length : exp %d got %d\n", 
+			op, (int)expLength, (int)fieldValue.length());
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);			
+	}
+}
+
+/*
+ * Call from getField* for unique fields - detect missing field or index out of bounds.
+ */
+static bool tbsGetCheck(
+	void		*requiredField,
+	uint32		reqIndex)
+{
+	if((requiredField == NULL) ||  (reqIndex != 0)) {
+		return false;
+	}
+	else {
+		return true;
+	}
+}
+
+/***
+ *** Version
+ *** Format = DER-encoded int (max of four bytes in this case)
+ ***/
+static bool getField_Version (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(!tbsGetCheck(cert.certificateToSign->version, index)) {
+		return false;
+	}
+
+	/* cook up big-endian char array representation */
+	int ivers = *cert.certificateToSign->version;
+	uint32 uvers = static_cast<uint32>(ivers);
+	uint8 chars[sizeof(uint32)];
+	for(uint32 i=0; i<sizeof(uint32); i++) {
+		chars[sizeof(uint32) - 1 -i] = (uint8)uvers;
+		uvers >>= 8; 
+	}
+	fieldValue.copy(chars, sizeof(uint32));
+	numFields = 1;
+	return true;
+}
+
+static void setField_Version (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	tbsSetCheck(cert.certificateToSign->version, fieldValue, 0, "version");
+	
+	/* get big-endian int from *fieldValue.Data */
+	if(fieldValue.length() > sizeof(unsigned)) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);			
+	}
+	uint32 vers = 0;
+	uint8 *cp = fieldValue;
+	for(unsigned i=0; i<fieldValue.length(); i++) {
+		vers <<= 8;
+		vers |= cp[i];
+	}
+	cert.certificateToSign->version = new Version((int)vers);
+	cert.certificateToSign->version->Set((int)vers);
+}
+
+
+#if	this_is_a_template
+/***
+ *** Version
+ *** Format = DER-encoded int (always four bytes in this case)
+ ***/
+static bool getField_Version (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	tbsGetCheck(cert.certificateToSign->version, index);
+}
+static void setField_Version (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	tbsSetCheck(cert.certificateToSign->version, fieldValue, sizeof(uint32),
+		"version");
+
+}
+static void freeField_Version (
+	CssmOwnedData		&fieldValue)
+{
+}
+#endif
+
+/***
+ *** Serial Number
+ *** Format = DER-encoded int, variable length
+ ***/
+static bool getField_SerialNumber (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(index > 0) {
+		return false;
+	}
+	
+	char *cp = cert.certificateToSign->serialNumber;	
+	uint32 len = cert.certificateToSign->serialNumber.Len();
+	fieldValue.copy(cp, len);
+	numFields = 1;
+	return true;
+}
+
+static void setField_SerialNumber (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	cert.certificateToSign->serialNumber.Set(fieldValue, fieldValue.Length);
+}
+
+/***
+ *** Issuer Name, Subject Name (C struct version)
+ *** Format = CSSM_X509_NAME
+ *** class Name from sm_x501if
+ ***/
+
+/* first, the common code */
+static bool getField_RDN (
+	const Name 			&name,
+	uint32				&numFields,		// RETURNED (if successful, 0 or 1)
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	RDNSequence *rdns = name.rDNSequence;
+	int numRdns = rdns->Count();
+	if((rdns == NULL) || (numRdns == 0)) {
+		/* not technically an error */
+		return false;
+	}
+	
+	/* alloc top-level CSSM_X509_NAME and its RelativeDistinguishedName array */
+	CssmAllocator &alloc = fieldValue.allocator;
+	fieldValue.malloc(sizeof(CSSM_X509_NAME));
+	CSSM_X509_NAME_PTR x509Name = (CSSM_X509_NAME_PTR)fieldValue.data();
+	memset(x509Name, 0, sizeof(CSSM_X509_NAME));
+	x509Name->numberOfRDNs = numRdns;
+	x509Name->RelativeDistinguishedName = 
+		(CSSM_X509_RDN_PTR)alloc.malloc(sizeof(CSSM_X509_RDN) * numRdns);
+	CSSM_X509_RDN_PTR currRdn = x509Name->RelativeDistinguishedName;
+	memset(currRdn, 0, sizeof(CSSM_X509_RDN) * numRdns);
+	
+	rdns->SetCurrElmt(0);
+	for(int rdnDex=0; rdnDex<numRdns; rdnDex++) {
+		/* from sm_x501if */
+		RelativeDistinguishedName *rdn = rdns->Curr();
+		if(rdn == NULL) {
+			/* not sure how this can happen... */
+			dprintf1("getField_RDN: NULL rdn at index %d\n", rdnDex);
+			
+			/* next snacc RDN but keep CDSA position unchanged */
+			rdns->GoNext();				// snacc format
+			x509Name->numberOfRDNs--;	// since we're skipping one
+			continue;
+		}
+		int numAttrs = rdn->Count();
+		if(numAttrs == 0) {
+			dprintf1("getField_RDN: zero numAttrs at index %d\n", rdnDex);
+			rdns->GoNext();		
+			x509Name->numberOfRDNs--;	// since we're skipping one
+			continue;
+		}
+		
+		/* alloc CSSM_X509_TYPE_VALUE_PAIR array for this rdn */
+		currRdn->numberOfPairs = numAttrs;
+		currRdn->AttributeTypeAndValue = (CSSM_X509_TYPE_VALUE_PAIR_PTR)
+			alloc.malloc(sizeof(CSSM_X509_TYPE_VALUE_PAIR) * numAttrs);
+		CSSM_X509_TYPE_VALUE_PAIR_PTR currAttr = currRdn->AttributeTypeAndValue;
+		memset(currAttr, 0, sizeof(CSSM_X509_TYPE_VALUE_PAIR) * numAttrs);
+		
+		/* descend into array of attribute/values */
+		rdn->SetCurrElmt(0);
+		for(int attrDex=0; attrDex<numAttrs; attrDex++) {
+			/* from sm_x501if */
+			AttributeTypeAndDistinguishedValue *att = rdn->Curr();
+			if(att == NULL) {
+				/* not sure how this can happen... */
+				dprintf1("getField_RDN: NULL att at index %d\n", attrDex);
+				rdn->GoNext();
+				currRdn->numberOfPairs--;
+				continue;
+			}
+
+			/*
+			 * Convert snacc-style AttributeTypeAndDistinguishedValue to
+			 * CSSM-style CSSM_X509_TYPE_VALUE_PAIR
+			 *
+			 * Hopefully 'value' is one of the types defined in DirectoryString,
+			 * defined in sm_x520sa. Some certs use IA5String, which is not
+			 * technically legal and is not handled by DirectoryString, so
+			 * we have to handle that ourself. See e.g. the Thawte serverbasic 
+			 * cert, which has an email address in IA5String format. 
+			 */
+			CSM_Buffer				*cbuf = att->value.value;
+			AsnBuf					buf;
+			AsnLen					len = cbuf->Length();
+			AsnTag 					tag;
+			AsnLen 					elmtLen;
+			ENV_TYPE 				env;
+			int						val;
+			char					*valData;
+			int						valLength;
+			DirectoryString			*dirStr = NULL;
+			
+			buf.InstallData(cbuf->Access(), len);
+			if ((val = setjmp (env)) == 0) {
+				tag = BDecTag (buf, len, env);
+				elmtLen = BDecLen (buf, len, env);
+			}
+			else {
+				errorLog0("getField_RDN: malformed DirectoryString (1)\n");
+				/* FIXME - throw? Discard the whole cert? What? */
+				rdn->GoNext();
+				currRdn->numberOfPairs--;
+				continue;
+			}
+
+			/* current buf ptr is at the string value's contents. */
+			if((tag == MAKE_TAG_ID (UNIV, PRIM, IA5STRING_TAG_CODE)) ||
+			   (tag == MAKE_TAG_ID (UNIV, CONS, IA5STRING_TAG_CODE))) {
+					/* any other printable types not handled by DirectoryString here */
+					valData = buf.DataPtr();
+					valLength = buf.DataLen();
+					// workaround
+					delete dirStr;
+					dirStr = NULL;
+			}
+			else {
+				/* from sm_x520sa.h */
+				AsnLen dec;
+				dirStr = new DirectoryString;
+				if((val = setjmp (env)) == 0) {
+					dirStr->BDecContent(buf, tag, elmtLen, dec, env);
+				}
+				else {
+					errorLog0("getField_RDN: malformed DirectoryString (1)\n");
+					/* FIXME - throw? Discard the whole cert? What? */
+					rdn->GoNext();
+					currRdn->numberOfPairs--;
+					continue;
+				}
+				AsnOcts *octs = NULL;
+				switch(dirStr->choiceId) {
+					case DirectoryString::printableStringCid:
+						octs = dirStr->printableString;
+						break;
+					case DirectoryString::teletexStringCid:
+						octs = dirStr->teletexString;
+						break;
+					case DirectoryString::universalStringCid:
+						octs = dirStr->universalString;
+						break;
+					case DirectoryString::bmpStringCid:
+						octs = dirStr->bmpString;
+						break;
+					case DirectoryString::utf8StringCid:
+						octs = dirStr->utf8String;
+						break;
+					default:
+						/* should never happen unless DirectoryString changes */
+						errorLog1("getField_RDN: Bad DirectoryString::choiceId (%d)\n",
+							(int)dirStr->choiceId);
+						CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+				}
+				valData = *octs;
+				valLength = octs->Len();
+			}	/* normal DirectoryString */
+			
+			/* OK, set up outgoing CSSM_X509_TYPE_VALUE_PAIR */
+			CssmOid &oid = CssmOid::overlay(currAttr->type);
+			CL_snaccOidToCssm(att->type, oid, alloc);
+			currAttr->valueType = tag >> 24;
+			currAttr->value.Data = (uint8 *)alloc.malloc(valLength);
+			currAttr->value.Length = valLength;
+			memcpy(currAttr->value.Data, valData, valLength);
+			
+			rdn->GoNext();	// snacc format
+			currAttr++;		// CDSA format
+			delete dirStr;
+		}	/* for eact attr in rdn */
+
+		rdns->GoNext();		// snacc format
+		currRdn++;			// CDSA format
+	}	/* for each rdn in rdns */
+	numFields = 1;
+	return true;
+}
+
+static void setField_RDN  (
+	NameBuilder			&name,
+	const CssmData		&fieldValue)
+{
+	/*
+	 * The main job here is extracting attr/value pairs in CSSM format 
+	 * from fieldData, and converting them into arguments for NameBuilder.addATDV.
+	 * Note that we're taking the default for primaryDistinguished,
+	 * because the CDSA CSSM_X509_TYPE_VALUE_PAIR struct doesn't allow for
+	 * it. 
+	 */
+	CSSM_X509_NAME_PTR x509Name = (CSSM_X509_NAME_PTR)fieldValue.data();
+	for(unsigned rdnDex=0; rdnDex<x509Name->numberOfRDNs; rdnDex++) {
+		CSSM_X509_RDN_PTR rdn = &x509Name->RelativeDistinguishedName[rdnDex];
+		if(rdn->numberOfPairs != 1) {
+			errorLog0("setField_RDN: only one a/v pair per RDN supported\n");
+			CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+		}
+
+		CSSM_X509_TYPE_VALUE_PAIR_PTR atv = rdn->AttributeTypeAndValue;
+		AsnOid oid;
+		oid.Set(reinterpret_cast<char *>(atv->type.Data), atv->type.Length);
+		
+		DirectoryString::ChoiceIdEnum stringType;
+		switch(atv->valueType) {
+			case BER_TAG_T61_STRING:
+				stringType = DirectoryString::teletexStringCid;
+				break;
+			case BER_TAG_PRINTABLE_STRING:
+				stringType = DirectoryString::printableStringCid;
+				break;
+			case BER_TAG_PKIX_UNIVERSAL_STRING:
+				stringType = DirectoryString::universalStringCid;
+				break;
+			case BER_TAG_PKIX_BMP_STRING:
+				stringType = DirectoryString::bmpStringCid;
+				break;
+			case BER_TAG_PKIX_UTF8_STRING:
+				stringType = DirectoryString::utf8StringCid;
+				break;
+			default:
+				errorLog1("setField_RDN: illegal tag(%d)\n", atv->valueType);
+				CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+		}
+		name.addATDV(oid,
+			reinterpret_cast<char *>(atv->value.Data),
+			atv->value.Length,
+			stringType);
+
+	}
+}
+
+/* common for issuer and subject */
+static void freeField_RDN  (
+	CssmOwnedData		&fieldValue)
+{
+	if(fieldValue.data() == NULL) {
+		return;
+	}
+	if(fieldValue.length() != sizeof(CSSM_X509_NAME)) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+	CssmAllocator &alloc = fieldValue.allocator;
+	CSSM_X509_NAME_PTR x509Name = (CSSM_X509_NAME_PTR)fieldValue.data();
+	for(unsigned rdnDex=0; rdnDex<x509Name->numberOfRDNs; rdnDex++) {
+		CSSM_X509_RDN_PTR rdn = &x509Name->RelativeDistinguishedName[rdnDex];
+		for(unsigned atvDex=0; atvDex<rdn->numberOfPairs; atvDex++) {
+			CSSM_X509_TYPE_VALUE_PAIR_PTR atv = &rdn->AttributeTypeAndValue[atvDex];
+			alloc.free(atv->type.Data);
+			alloc.free(atv->value.Data);
+			memset(atv, 0, sizeof(CSSM_X509_TYPE_VALUE_PAIR));
+		}
+		alloc.free(rdn->AttributeTypeAndValue);
+		memset(rdn, 0, sizeof(CSSM_X509_RDN));
+	}
+	alloc.free(x509Name->RelativeDistinguishedName);
+	memset(x509Name, 0, sizeof(CSSM_X509_NAME));
+	
+	/* top-level x509Name pointer freed by freeCertFieldData() */
+}
+
+/*** issuer ***/
+static bool getField_Issuer (
+	const DecodedCert	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	bool brtn;
+	
+	if(!tbsGetCheck(cert.certificateToSign->issuer, index)) {
+		return false;
+	}
+	try {
+		brtn = getField_RDN(*cert.certificateToSign->issuer, numFields, fieldValue);
+	}
+	catch (...) {
+		freeField_RDN(fieldValue);
+		throw;
+	}
+	return brtn;
+}
+
+static void setField_Issuer  (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	tbsSetCheck(cert.certificateToSign->issuer, fieldValue, sizeof(CSSM_X509_NAME),
+		"IssuerName");
+	NameBuilder *issuer = new NameBuilder;
+	cert.certificateToSign->issuer = issuer;
+	setField_RDN(*issuer, fieldValue);
+}
+
+/*** subject ***/
+static bool getField_Subject (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(!tbsGetCheck(cert.certificateToSign->subject, index)) {
+		return false;
+	}
+	bool brtn;
+	try {
+		brtn = getField_RDN(*cert.certificateToSign->subject, numFields, fieldValue);
+	}
+	catch (...) {
+		freeField_RDN(fieldValue);
+		throw;
+	}
+	return brtn;
+}
+
+static void setField_Subject  (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	tbsSetCheck(cert.certificateToSign->subject, fieldValue, sizeof(CSSM_X509_NAME),
+		"SubjectName");
+	NameBuilder *subject = new NameBuilder;
+	cert.certificateToSign->subject = subject;
+	setField_RDN(*subject, fieldValue);
+}
+
+/***
+ *** Issuer Name, Subject Name (normalized and encoded version)
+ *** Format = CSSM_DATA containing the DER encoding of the normalized name
+ *** class Name from sm_x501if
+ ***/
+
+/* first, the common code */
+static bool getField_normRDN (
+	const Name 			&name,
+	uint32				&numFields,		// RETURNED (if successful, 0 or 1)
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	/*
+	 * First step is to make a copy of the existing name. The easiest way to do 
+	 * this is to encode and decode.	
+	 */
+	CssmAllocator &alloc = fieldValue.allocator;
+	CssmAutoData encodedName1(alloc);
+	/* FIXME - should SC_encodeAsnObj() take a const AsnType & ? */
+	SC_encodeAsnObj(const_cast<Name &>(name), encodedName1, MAX_RDN_SIZE);
+	Name decodedName;
+	SC_decodeAsnObj(encodedName1, decodedName);
+	
+	/* normalize */
+	CL_normalizeX509Name(decodedName, alloc);
+	
+	/* encode result */
+	SC_encodeAsnObj(decodedName, fieldValue, MAX_RDN_SIZE);
+	numFields = 1;
+	return true;
+}
+
+static bool getFieldSubjectNorm(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(!tbsGetCheck(cert.certificateToSign->subject, index)) {
+		return false;
+	}
+	return getField_normRDN(*cert.certificateToSign->subject, numFields, fieldValue);
+}
+
+static bool getFieldIssuerNorm(
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(!tbsGetCheck(cert.certificateToSign->issuer, index)) {
+		return false;
+	}
+	return getField_normRDN(*cert.certificateToSign->issuer, numFields, fieldValue);
+}
+
+
+/***
+ *** TBS AlgId, Signature AlgId
+ *** Format = CSSM_X509_ALGORITHM_IDENTIFIER
+ ***
+ *** common code:
+ ***/
+static void getField_AlgId (
+	const AlgorithmIdentifier 	*snaccAlgId,
+	CssmOwnedData				&fieldValue)	// RETURNED
+{
+	CssmAllocator &alloc = fieldValue.allocator;
+	fieldValue.malloc(sizeof(CSSM_X509_ALGORITHM_IDENTIFIER));
+	CSSM_X509_ALGORITHM_IDENTIFIER *cssmAlgId = 
+		(CSSM_X509_ALGORITHM_IDENTIFIER *)fieldValue.data();
+	CL_snaccAlgIdToCssm (*snaccAlgId, *cssmAlgId, alloc);
+}
+
+static void setField_AlgId (
+	AlgorithmIdentifier *snaccAlgId,
+	const CssmData		&fieldValue)
+{
+	CSSM_X509_ALGORITHM_IDENTIFIER *cssmAlgId = 
+		(CSSM_X509_ALGORITHM_IDENTIFIER *)fieldValue.data();
+	if(cssmAlgId->algorithm.Data == NULL) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+	CL_cssmAlgIdToSnacc(*cssmAlgId, *snaccAlgId);
+}
+
+static void freeField_AlgId (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_ALGORITHM_IDENTIFIER *cssmAlgId = 
+		(CSSM_X509_ALGORITHM_IDENTIFIER *)fieldValue.data();
+	if(cssmAlgId == NULL) {
+		return;
+	}
+	if(fieldValue.length() != sizeof(CSSM_X509_ALGORITHM_IDENTIFIER)) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+	CssmAllocator &alloc = fieldValue.allocator;
+	alloc.free(cssmAlgId->algorithm.Data);
+	alloc.free(cssmAlgId->parameters.Data);
+	memset(cssmAlgId, 0, sizeof(CSSM_X509_ALGORITHM_IDENTIFIER));
+}
+
+
+/* TBS AlgId */
+static bool getField_TbsAlgId (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	AlgorithmIdentifier *snaccAlgId = cert.certificateToSign->signature;
+	if(!tbsGetCheck(snaccAlgId, index)) {
+		return false;
+	}
+	getField_AlgId(snaccAlgId, fieldValue);
+	numFields = 1;
+	return true;
+}
+
+static void setField_TbsAlgId (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	tbsSetCheck(cert.certificateToSign->signature, fieldValue, 
+		sizeof(CSSM_X509_ALGORITHM_IDENTIFIER), "TBS_AlgId");
+	AlgorithmIdentifier *snaccAlgId = new AlgorithmIdentifier;
+	cert.certificateToSign->signature = snaccAlgId;
+	setField_AlgId(snaccAlgId, fieldValue);
+}
+
+/* Cert AlgId - read only */
+static bool getField_CertAlgId (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	AlgorithmIdentifier *snaccAlgId = cert.algorithmIdentifier;
+	if(!tbsGetCheck(snaccAlgId, index)) {
+		return false;
+	}
+	getField_AlgId(snaccAlgId, fieldValue);
+	numFields = 1;
+	return true;
+}
+
+/***
+ *** Validity not before, not after
+ *** Format: CSSM_X509_TIME
+ ***/
+
+/*** common code ***/
+static void getField_Time (
+	const Time 		*snaccTime,
+	CssmOwnedData	&fieldValue)	// RETURNED
+{
+	CssmAllocator &alloc = fieldValue.allocator;
+	fieldValue.malloc(sizeof(CSSM_X509_TIME));
+	CSSM_X509_TIME *cssmTime = 
+		(CSSM_X509_TIME *)fieldValue.data();
+	memset(cssmTime, 0, sizeof(CSSM_X509_TIME));
+
+	char *timeStr = NULL;
+	int timeStrLen = 0;
+	switch(snaccTime->choiceId) {
+		case Time::utcTimeCid:
+			cssmTime->timeType = BER_TAG_UTC_TIME;
+			timeStr = *snaccTime->utcTime;		// an AsnOct
+			timeStrLen = snaccTime->utcTime->Len();
+			break;
+		case Time::generalizedTimeCid:
+			timeStr = *snaccTime->generalizedTime;		// an AsnOct
+			timeStrLen = snaccTime->generalizedTime->Len();
+			cssmTime->timeType = BER_TAG_GENERALIZED_TIME;
+			break;
+		default:
+			/* snacc error, should never happen */
+			cssmTime->timeType = BER_TAG_OCTET_STRING;
+			timeStr = *snaccTime->generalizedTime;		// an AsnOct
+			timeStrLen = snaccTime->generalizedTime->Len();
+			break;
+	}
+
+	cssmTime->time.Data = reinterpret_cast<uint8 *>(alloc.malloc(timeStrLen));
+	cssmTime->time.Length = timeStrLen;
+	memcpy(cssmTime->time.Data, timeStr, timeStrLen);
+}
+
+static void setField_Time (
+	Time 			*snaccTime,
+	const CssmData	&fieldValue)
+{
+	CSSM_X509_TIME *cssmTime = 
+		(CSSM_X509_TIME *)fieldValue.data();
+	const char *tStr = reinterpret_cast<const char *>(cssmTime->time.Data);
+	size_t tLen = cssmTime->time.Length;
+	
+	switch(cssmTime->timeType) {
+		case BER_TAG_GENERALIZED_TIME:
+			snaccTime->choiceId = Time::generalizedTimeCid;
+			snaccTime->generalizedTime = new GeneralizedTime(tStr, tLen);
+			break;
+		case BER_TAG_UTC_TIME:
+			snaccTime->choiceId = Time::utcTimeCid;
+			snaccTime->utcTime = new UTCTime(tStr, tLen);
+			break;
+		default:
+			errorLog1("setField_Time: bad time tag (%d)\n", cssmTime->timeType);
+			CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+}
+
+static void freeField_Time (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_TIME *cssmTime = (CSSM_X509_TIME *)fieldValue.data();
+	if(cssmTime == NULL) {
+		return;
+	}
+	if(fieldValue.length() != sizeof(CSSM_X509_TIME)) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+	fieldValue.allocator.free(cssmTime->time.Data);
+	memset(cssmTime, 0, sizeof(CSSM_X509_TIME));
+}
+
+/*** not before ***/
+static bool getField_NotBefore (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(!tbsGetCheck(cert.certificateToSign->validity, index)) {
+		return false;
+	}
+	if(cert.certificateToSign->validity->notBefore == NULL) {
+		return false;
+	}
+	getField_Time(cert.certificateToSign->validity->notBefore, fieldValue);
+	numFields = 1;
+	return true;
+}
+
+static void setField_NotBefore (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	/* anything could need mallocing except TBS */
+	if(cert.certificateToSign->validity == NULL) {
+		cert.certificateToSign->validity = new Validity;
+	}
+	tbsSetCheck(cert.certificateToSign->validity->notBefore, fieldValue, 
+		sizeof(CSSM_X509_TIME), "NotBefore");
+	cert.certificateToSign->validity->notBefore = new Time;
+	setField_Time(cert.certificateToSign->validity->notBefore, fieldValue);
+}
+
+/*** not after ***/
+static bool getField_NotAfter (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(!tbsGetCheck(cert.certificateToSign->validity, index)) {
+		return false;
+	}
+	if(cert.certificateToSign->validity->notAfter == NULL) {
+		return false;
+	}
+	getField_Time(cert.certificateToSign->validity->notAfter, fieldValue);
+	numFields = 1;
+	return true;
+}
+
+static void setField_NotAfter (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	/* anything could need mallocing except TBS */
+	if(cert.certificateToSign->validity == NULL) {
+		cert.certificateToSign->validity = new Validity;
+	}
+	tbsSetCheck(cert.certificateToSign->validity->notAfter, fieldValue, 
+		sizeof(CSSM_X509_TIME), "NotAfter");
+	cert.certificateToSign->validity->notAfter = new Time;
+	setField_Time(cert.certificateToSign->validity->notAfter, fieldValue);
+}
+
+/***
+ *** Subject/issuer unique ID
+ *** Format: Raw bytes. It's stored in the cert as an ASN bit string; the decoded
+ *** bytes are present at this level (i.e., not tag and length in the bytes). 
+ *** NOTE: this is not quite accurate in that we only provide byte-aligned size,
+ *** not bit-aligned. This field is rarely if ever used so I think it's O, but
+ *** beware.
+ ***/
+static bool getField_SubjectUniqueId (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	UniqueIdentifier *id = cert.certificateToSign->subjectUniqueIdentifier;
+	if(!tbsGetCheck(id, index)) {
+		return false;
+	}
+	SC_asnBitsToCssmData(*id, fieldValue);
+	numFields = 1;
+	return true;
+}
+
+static void setField_SubjectUniqueId (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	tbsSetCheck(cert.certificateToSign->subjectUniqueIdentifier, fieldValue, 0,
+		"SubjectUniqueID");
+	cert.certificateToSign->subjectUniqueIdentifier = new UniqueIdentifier(
+		reinterpret_cast<char * const>(fieldValue.Data), fieldValue.Length * 8);
+}
+
+static bool getField_IssuerUniqueId (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	UniqueIdentifier *id = cert.certificateToSign->issuerUniqueIdentifier;
+	if(!tbsGetCheck(id, index)) {
+		return false;
+	}
+	SC_asnBitsToCssmData(*id, fieldValue);
+	numFields = 1;
+	return true;
+}
+
+static void setField_IssuerUniqueId (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	tbsSetCheck(cert.certificateToSign->issuerUniqueIdentifier, fieldValue, 0,
+		"IssuerniqueID");
+	cert.certificateToSign->issuerUniqueIdentifier = new UniqueIdentifier(
+		reinterpret_cast<char * const>(fieldValue.Data), fieldValue.Length * 8);
+}
+
+/***
+ *** Public key info
+ *** Format = CSSM_X509_SUBJECT_PUBLIC_KEY_INFO
+ ***/
+static bool getField_PublicKeyInfo (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(!tbsGetCheck(cert.certificateToSign->subjectPublicKeyInfo, index)) {
+		return false;
+	}
+	SubjectPublicKeyInfo *snaccKeyInfo = cert.certificateToSign->subjectPublicKeyInfo;
+	AlgorithmIdentifier *snaccAlgId = snaccKeyInfo->algorithm;
+	if(snaccAlgId == NULL) {
+		errorLog0("getField_PublicKeyInfo: cert has pubKeyInfo but no algorithm!\n");
+		return false;
+	}
+	CssmAllocator &alloc = fieldValue.allocator;
+	fieldValue.malloc(sizeof(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO));
+	CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *cssmKeyInfo = 
+		(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.data();
+	memset(cssmKeyInfo, 0, sizeof(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO));
+	CL_snaccAlgIdToCssm(*snaccAlgId, cssmKeyInfo->algorithm, alloc);
+	
+	/* 
+	 * key info - the actual public key blob - is stored in the cert as a bit string;
+	 * snacc will give us the actual bits which are invariably yet another DER
+	 * encoding (e.g., PKCS1 for RSA public keys). 
+	 */
+	size_t keyLen = (snaccKeyInfo->subjectPublicKey.BitLen() + 7) / 8;
+	cssmKeyInfo->subjectPublicKey.Data = (uint8 *)alloc.malloc(keyLen);
+	cssmKeyInfo->subjectPublicKey.Length = keyLen;
+	memcpy(cssmKeyInfo->subjectPublicKey.Data, 
+		   snaccKeyInfo->subjectPublicKey.BitOcts(),
+		   keyLen);
+	numFields = 1;
+	return true;
+}
+
+static void setField_PublicKeyInfo (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	/* This fails if setField_PublicKeyStruct has already been called */
+	tbsSetCheck(cert.certificateToSign->subjectPublicKeyInfo, fieldValue, 
+		sizeof(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO), "PubKeyInfo");
+	CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *cssmKeyInfo = 
+		(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.Data;
+	if((cssmKeyInfo->subjectPublicKey.Data == NULL) ||
+	   (cssmKeyInfo->subjectPublicKey.Length == 0)) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+
+	SubjectPublicKeyInfo *snaccKeyInfo = new SubjectPublicKeyInfo;
+	cert.certificateToSign->subjectPublicKeyInfo = snaccKeyInfo;
+	snaccKeyInfo->algorithm = new AlgorithmIdentifier;
+
+	/* common code to convert algorithm info (algID and parameters) */
+	const CSSM_X509_ALGORITHM_IDENTIFIER *cssmAlgId = &cssmKeyInfo->algorithm;
+	CL_cssmAlgIdToSnacc(*cssmAlgId, *snaccKeyInfo->algorithm);
+
+	/* actual public key blob - AsnBits */
+	snaccKeyInfo->subjectPublicKey.Set(reinterpret_cast<char *>
+		(cssmKeyInfo->subjectPublicKey.Data), 
+		cssmKeyInfo->subjectPublicKey.Length);
+
+}
+static void freeField_PublicKeyInfo (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *cssmKeyInfo = 
+		(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)fieldValue.data();
+	if(cssmKeyInfo == NULL) {
+		return;
+	}
+	CssmAllocator &alloc = fieldValue.allocator;
+	CSSM_X509_ALGORITHM_IDENTIFIER *algId = &cssmKeyInfo->algorithm;
+	alloc.free(algId->algorithm.Data);
+	alloc.free(algId->parameters.Data);
+	alloc.free(cssmKeyInfo->subjectPublicKey.Data);
+	memset(cssmKeyInfo, 0, sizeof(CSSM_X509_SUBJECT_PUBLIC_KEY_INFO));}
+
+/***
+ *** key info from CSSM_KEY
+ *** Format = CSSM_KEY
+ ***/
+static bool getField_PublicKeyStruct (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if(!tbsGetCheck(cert.certificateToSign->subjectPublicKeyInfo, index)) {
+		return false;
+	}
+	CSSM_KEY_PTR cssmKey = cert.extractCSSMKey(fieldValue.allocator);
+	fieldValue.set(reinterpret_cast<uint8 *>(cssmKey), sizeof(CSSM_KEY));
+	numFields = 1;
+	return true;
+}
+
+static void setField_PublicKeyStruct (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	/* This fails if setField_PublicKeyInfo has already been called */
+	tbsSetCheck(cert.certificateToSign->subjectPublicKeyInfo, fieldValue, 
+		sizeof(CSSM_KEY), "PubKey");
+	CSSM_KEY_PTR cssmKey = (CSSM_KEY_PTR)fieldValue.data();
+	if((cssmKey->KeyData.Data == NULL) ||
+	   (cssmKey->KeyData.Data == 0)) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+
+	SubjectPublicKeyInfo *snaccKeyInfo = new SubjectPublicKeyInfo;
+	cert.certificateToSign->subjectPublicKeyInfo = snaccKeyInfo;
+	snaccKeyInfo->algorithm = new AlgorithmIdentifier;
+	CL_cssmAlgToSnaccOid(cssmKey->KeyHeader.AlgorithmId, 
+		snaccKeyInfo->algorithm->algorithm);
+
+	/* NULL algorithm paramneters, always in this case */
+	CL_nullAlgParams(*snaccKeyInfo->algorithm);
+	
+	/* actual public key blob - AsnBits */
+	/***
+	 *** TBD FIXME if this key is a ref key, null wrap it to a raw key
+	 ***/
+	if(cssmKey->KeyHeader.BlobType != CSSM_KEYBLOB_RAW) {
+			errorLog0("CL SetField: must specify RAW key blob\n");
+			CssmError::throwMe(CSSM_ERRCODE_INVALID_FIELD_POINTER);
+	}
+	snaccKeyInfo->subjectPublicKey.Set(reinterpret_cast<char *>
+		(cssmKey->KeyData.Data), cssmKey->KeyData.Length * 8);
+}
+
+static void freeField_PublicKeyStruct (
+	CssmOwnedData		&fieldValue)
+{
+	CSSM_KEY_PTR cssmKey = (CSSM_KEY_PTR)fieldValue.data();
+	DecodedCert::freeCSSMKey(cssmKey, fieldValue.allocator, false);
+}
+
+/***
+ *** Signature
+ *** Format = raw bytes
+ *** read-only
+ ***/
+static bool getField_Signature (
+	const DecodedCert 	&cert,
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue)	// RETURNED
+{
+	if((index > 0) || 							// max of one sig
+	   (cert.signatureValue.BitLen() == 0)) {	// no sig - must be TBS only
+		return false;
+	}
+	SC_asnBitsToCssmData(cert.signatureValue, fieldValue);
+	numFields = 1;
+	return true;
+}
+
+/***
+ *** end of field-specific triplets
+ ***/
+ 
+/* setField for read-only OIDs (i.e., the ones in cert, not TBS) */
+static void setField_ReadOnly (
+	DecodedCert			&cert,
+	const CssmData		&fieldValue)
+{
+	errorLog0("Attempt to set a read-only field\n");
+	CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG);
+}
+
+/*
+ * Table to map OID to {get,set,free}field
+ */
+typedef struct {
+	const CSSM_OID		*fieldId;
+	getFieldFcn			*getFcn;
+	setFieldFcn			*setFcn;
+	freeFieldFcn		*freeFcn;		// OPTIONAL - NULL means just free the 
+										// top-level data
+} oidToFieldFuncs;
+
+static const oidToFieldFuncs fieldFuncTable[] = {
+	{ 	&CSSMOID_X509V1Version, 
+		&getField_Version, &setField_Version, NULL },
+	{ 	&CSSMOID_X509V1SerialNumber, 
+		&getField_SerialNumber, &setField_SerialNumber, NULL 	},
+	{ 	&CSSMOID_X509V1IssuerNameCStruct, 
+		&getField_Issuer, &setField_Issuer, &freeField_RDN },
+	{ 	&CSSMOID_X509V1SubjectNameCStruct, 
+		&getField_Subject, &setField_Subject, &freeField_RDN },
+	{	&CSSMOID_X509V1SignatureAlgorithmTBS,
+		&getField_TbsAlgId, &setField_TbsAlgId, &freeField_AlgId },
+	{	&CSSMOID_X509V1SignatureAlgorithm, 
+		&getField_CertAlgId, &setField_ReadOnly, &freeField_AlgId	},
+	{	&CSSMOID_X509V1ValidityNotBefore,
+		&getField_NotBefore,	&setField_NotBefore,	&freeField_Time },
+	{	&CSSMOID_X509V1ValidityNotAfter,
+		&getField_NotAfter, &setField_NotAfter, &freeField_Time },
+	{	&CSSMOID_X509V1CertificateIssuerUniqueId,
+		&getField_IssuerUniqueId, &setField_IssuerUniqueId, NULL },
+	{	&CSSMOID_X509V1CertificateSubjectUniqueId,
+		&getField_SubjectUniqueId, &setField_SubjectUniqueId, NULL },
+	{	&CSSMOID_X509V1SubjectPublicKeyCStruct,
+		&getField_PublicKeyInfo, &setField_PublicKeyInfo, &freeField_PublicKeyInfo },
+	{	&CSSMOID_CSSMKeyStruct,
+		&getField_PublicKeyStruct, &setField_PublicKeyStruct, 
+		&freeField_PublicKeyStruct },
+	{	&CSSMOID_X509V1Signature,
+		&getField_Signature, &setField_ReadOnly, NULL },
+	{   &CSSMOID_X509V1IssuerName, 
+		getFieldIssuerNorm, &setField_ReadOnly, NULL },
+	{   &CSSMOID_X509V1SubjectName, 
+		getFieldSubjectNorm, &setField_ReadOnly, NULL },
+		
+	/* 
+	 * Extensions, implemented in CertExtensions.cpp 
+	 * When adding new ones, also add to:
+	 *   -- oidToSnaccObj() in CertExtensions.cpp
+	 *   -- get/set/free functions in CertExtensions.{cpp,h}
+	 */
+	{	&CSSMOID_KeyUsage, &getFieldKeyUsage, &setFieldKeyUsage, 
+	    &freeFieldSimpleExtension },
+	{   &CSSMOID_BasicConstraints, &getFieldBasicConstraints, 
+	    &setFieldBasicConstraints, &freeFieldSimpleExtension },
+	{	&CSSMOID_ExtendedKeyUsage, &getFieldExtKeyUsage,
+		&setFieldExtKeyUsage, &freeFieldExtKeyUsage } ,
+	{	&CSSMOID_SubjectKeyIdentifier, &getFieldSubjectKeyId,
+		&setFieldSubjectKeyId, &freeFieldSubjectKeyId } ,
+	{	&CSSMOID_AuthorityKeyIdentifier, &getFieldAuthorityKeyId,
+		&setFieldAuthorityKeyId, &freeFieldAuthorityKeyId } ,
+	{	&CSSMOID_SubjectAltName, &getFieldSubjAltName,
+		&setFieldSubjAltName, &freeFieldSubjAltName } ,
+	{	&CSSMOID_CertificatePolicies, &getFieldCertPolicies,
+		&setFieldCertPolicies, &freeFieldCertPolicies } ,
+	{	&CSSMOID_NetscapeCertType, &getFieldNetscapeCertType,
+		&setFieldNetscapeCertType, &freeFieldSimpleExtension } ,
+	{   &CSSMOID_X509V3CertificateExtensionCStruct, &getFieldUnknownExt,
+		&setFieldUnknownExt, &freeFieldUnknownExt }
+};
+
+#define NUM_KNOWN_FIELDS		(sizeof(fieldFuncTable) / sizeof(oidToFieldFuncs))
+#define NUM_STD_CERT_FIELDS		13		/* not including extensions */
+
+
+/* map an OID to an oidToFieldFuncs */
+static const oidToFieldFuncs *oidToFields(
+	const CssmOid	&fieldId)
+{
+	const oidToFieldFuncs *funcPtr = fieldFuncTable;
+	
+	for(unsigned i=0; i<NUM_KNOWN_FIELDS; i++) {
+		if(fieldId == CssmData::overlay(*funcPtr->fieldId)) {
+			return funcPtr;
+		}
+		funcPtr++;
+	}
+	CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG);
+}
+
+
+/***
+ *** Public functions
+ ***/
+
+/* 
+ * Obtain the index'th occurrence of field specified by fieldId in specified cert.
+ * Format of the returned field depends on fieldId.
+ * Returns total number of fieldId fields in the cert if index is 0.
+ * FieldValue assumed to be empty on entry. 
+ * Returns true if specified field was found, else returns false. 
+ */
+bool DecodedCert::getCertFieldData(
+	const CssmOid		&fieldId,		// which field
+	unsigned			index,			// which occurrence (0 = first)
+	uint32				&numFields,		// RETURNED
+	CssmOwnedData		&fieldValue) const	// RETURNED
+{ 
+	CASSERT(certificateToSign != NULL);
+	switch(mState) {
+		case CS_Empty:		
+		case CS_Building:	
+			errorLog0("DecodedCert::getCertField: can't parse undecoded cert!\n");
+			CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+		case CS_DecodedCert:
+		case CS_DecodedTBS:
+			break;
+	}
+	const oidToFieldFuncs *fieldFuncs = oidToFields(fieldId);
+	return fieldFuncs->getFcn(*this, index, numFields, fieldValue);
+}
+ 
+/*
+ * Set the field specified by fieldId in the specified Cert. 
+ * Note no index - individual field routines either append (for extensions)
+ * or if field already set ::throwMe(for all others) 
+ */
+void DecodedCert::setCertField(
+	const CssmOid		&fieldId,		// which field
+	const CssmData		&fieldValue) 
+{
+	CASSERT(certificateToSign != NULL);
+	switch(mState) {
+		case CS_Empty:			// first time thru
+			mState = CS_Building;
+			break;
+		case CS_Building:		// subsequent passes
+			break;
+		case CS_DecodedCert:
+		case CS_DecodedTBS:
+			errorLog0("DecodedCert::setCertField: can't build on a decoded cert!\n");
+			CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+	}
+	if((fieldValue.data() == NULL) || (fieldValue.length() == 0)) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+	const oidToFieldFuncs *fieldFuncs = oidToFields(fieldId);
+	const CssmData &value = CssmData::overlay(fieldValue);
+	fieldFuncs->setFcn(*this, value);
+}
+
+/*
+ * Free the fieldId-specific data referred to by fieldValue->Data. 
+ */
+void DecodedCert::freeCertFieldData(
+	const CssmOid		&fieldId,
+	CssmOwnedData		&fieldValue)
+{
+	if((fieldValue.data() == NULL) || (fieldValue.length() == 0)) {
+		CssmError::throwMe(CSSM_ERRCODE_INVALID_FIELD_POINTER);
+	}
+	const oidToFieldFuncs *fieldFuncs = oidToFields(fieldId);
+	if(fieldFuncs->freeFcn != NULL) {
+		/* optional - simple cases handled below */
+		fieldFuncs->freeFcn(fieldValue);
+	}
+	fieldValue.reset();
+	fieldValue.release();
+
+}
+
+
+/*
+ * Common means to get all fields from a decoded cert. Used in 
+ * CertGetAllTemplateFields and CertGetAllFields.
+ */
+void DecodedCert::getAllParsedCertFields(
+	uint32 				&NumberOfFields,		// RETURNED
+	CSSM_FIELD_PTR 		&CertFields)			// RETURNED
+{
+	/* this is the max - some might be missing */
+	uint32 maxFields = NUM_STD_CERT_FIELDS + mNumExtensions;
+	CSSM_FIELD_PTR outFields = (CSSM_FIELD_PTR)malloc(maxFields * sizeof(CSSM_FIELD));
+	
+	/*
+	 * We'll be copying oids and values for fields we find into
+	 * outFields; current number of valid fields found in numOutFields.
+	 */
+	memset(outFields, 0, maxFields * sizeof(CSSM_FIELD));
+	uint32 			numOutFields = 0;
+	CSSM_FIELD_PTR 	currOutField;
+	uint32 			currOidDex;
+	const CSSM_OID 	*currOid;
+	CssmAutoData 	aData(alloc);		// for malloc/copy of outgoing data
+	
+	/* query for each OID we know about */
+	for(currOidDex=0; currOidDex<NUM_KNOWN_FIELDS; currOidDex++) {
+		const oidToFieldFuncs *fieldFuncs = &fieldFuncTable[currOidDex];
+		currOid = fieldFuncs->fieldId;
+		uint32 numFields;				// for THIS oid
+
+		/* 
+		 * Return false if field not there, which is not an error here. 
+		 * Actual exceptions are fatal.
+		 */
+		if(!fieldFuncs->getFcn(*this, 
+				0, 				// index - looking for first one
+				numFields, 
+				aData)) {
+			continue;
+		}
+		
+		/* got some data for this oid - copy it and oid to outgoing CertFields */
+		CASSERT(numOutFields < maxFields);
+		currOutField = &outFields[numOutFields];
+		currOutField->FieldValue = aData.release();
+		aData.copy(*currOid);
+		currOutField->FieldOid = aData.release();
+		numOutFields++;
+		
+		/* if more fields are available for this OID, snag them too */
+		for(uint32 fieldDex=1; fieldDex<numFields; fieldDex++) {
+			/* note this should always succeed */
+			bool brtn = fieldFuncs->getFcn(*this,
+				fieldDex, 			
+				numFields, 			// shouldn't change
+				aData);
+			if(!brtn) {
+				errorLog0("getAllParsedCertFields: index screwup\n");
+				CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+			}
+			CASSERT(numOutFields < maxFields);
+			currOutField = &outFields[numOutFields];
+			currOutField->FieldValue = aData.release();
+			aData.copy(*currOid);
+			currOutField->FieldOid = aData.release();
+			numOutFields++;
+		}	/* multiple fields for currOid */
+	}		/* for each known OID */
+	
+	NumberOfFields = numOutFields;
+	CertFields = outFields;
+}
+
+void
+DecodedCert::describeFormat(
+	CssmAllocator &alloc,
+	uint32 &NumberOfFields,
+	CSSM_OID_PTR &OidList)
+{
+	/* malloc in app's space, do deep copy (including ->Data) */
+	CSSM_OID_PTR oidList = (CSSM_OID_PTR)alloc.malloc(
+		NUM_KNOWN_FIELDS * sizeof(CSSM_OID));
+	memset(oidList, 0, NUM_KNOWN_FIELDS * sizeof(CSSM_OID));
+	for(unsigned i=0; i<NUM_KNOWN_FIELDS; i++) {
+		CssmAutoData oidCopy(alloc, *fieldFuncTable[i].fieldId);
+		oidList[i] = oidCopy.release();
+	}
+	NumberOfFields = NUM_KNOWN_FIELDS;
+	OidList = oidList;
+}
diff --git a/AppleX509CL/DecodedCert.cpp b/AppleX509CL/DecodedCert.cpp
new file mode 100644
index 00000000..1ec61db7
--- /dev/null
+++ b/AppleX509CL/DecodedCert.cpp
@@ -0,0 +1,283 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * DecodedCert.cpp - object representing a snacc-decoded cert, with extensions
+ * parsed and decoded (still in snacc format).
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+
+#include "DecodedCert.h"
+#include "SnaccUtils.h"
+#include "cldebugging.h"
+#include "AppleX509CLSession.h"
+#include "CSPAttacher.h"
+#include <Security/cdsaUtils.h>
+#include <Security/cssmapple.h>
+
+DecodedCert::DecodedCert(
+	AppleX509CLSession	&session)
+	: alloc(CssmAllocator::standard()),
+	  mSession(session)
+{
+	certificateToSign = new CertificateToSign;
+	reset();
+}
+
+/* one-shot constructor, decoding from DER-encoded data */
+DecodedCert::DecodedCert(
+	AppleX509CLSession	&session,
+	const CssmData 	&encodedCert)
+	: alloc(CssmAllocator::standard()),
+	  mSession(session)
+{
+	reset();
+	SC_decodeAsnObj(encodedCert, *this);
+	decodeExtensions();
+	mState = CS_DecodedCert;
+}
+		
+DecodedCert::~DecodedCert()
+{
+	/* free all extensions */
+	unsigned dex;
+	
+	for(dex=0; dex<mNumExtensions; dex++) {
+		DecodedExten *exten = &mExtensions[dex];
+		delete exten->extnId;
+		delete exten->snaccObj;
+	}
+	alloc.free(mExtensions);
+	reset();
+}
+	
+/* decode TBSCert and its extensions */
+void DecodedCert::decodeTbs(
+	const CssmData	&encodedTbs)
+{
+	CASSERT(mState == CS_Empty);
+	CASSERT(certificateToSign != NULL);
+	try {
+		SC_decodeAsnObj(encodedTbs, *certificateToSign);
+	}
+	catch (...) {
+		errorLog0("decodeTbs: tbs.BDec failure\n");
+		/* FIXME - leave in bad state? delete and clear? let's be cautious...*/
+		delete certificateToSign;
+		certificateToSign = new CertificateToSign;
+	}
+	decodeExtensions();
+	mState = CS_DecodedTBS;
+}
+
+/*
+ * FIXME : how to determine max encoding size at run time!?
+ */
+#define MAX_TEMPLATE_SIZE	(8 * 1024)
+
+/* encode TBS component; only called from CertCreateTemplate */
+void DecodedCert::encodeTbs(
+	CssmOwnedData	&encodedTbs)
+{
+	encodeExtensions();
+	CASSERT(mState == CS_Building);
+	if(certificateToSign == NULL) {
+		errorLog0("DecodedCert::encodeTbs: no TBS\n");
+		CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+	}
+	
+	/* enforce required fields - could go deeper, maybe we should */
+	if((certificateToSign->signature == NULL) ||
+	   (certificateToSign->issuer == NULL) ||
+	   (certificateToSign->validity == NULL) ||
+	   (certificateToSign->subject == NULL) ||
+	   (certificateToSign->subjectPublicKeyInfo == NULL)) {
+		errorLog0("DecodedCert::encodeTbs: incomplete TBS\n");
+		/* an odd, undocumented error return */
+		CssmError::throwMe(CSSMERR_CL_NO_FIELD_VALUES);
+	}
+	SC_encodeAsnObj(*certificateToSign, encodedTbs, MAX_TEMPLATE_SIZE);
+}
+
+/*
+ * Cook up CSSM_KEYUSE, gleaning as much as possible from
+ * (optional) extensions. If no applicable extensions available,
+ * we'll just return CSSM_KEYUSE_ANY.
+ *
+ * Note that the standard KeyUsage flags involving 'signing' translate
+ * to verify since we're only dealing with public keys. 
+ */
+CSSM_KEYUSE DecodedCert::inferKeyUsage() const
+{
+	CSSM_KEYUSE keyUse = 0;
+	DecodedExten *decodedExten;
+	uint32 numFields;
+	
+	decodedExten = findDecodedExt(id_ce_keyUsage, false, 0, numFields);
+	if(decodedExten) {
+		KeyUsage *ku = dynamic_cast<KeyUsage *>(decodedExten->snaccObj);
+		if(ku == NULL) {
+			errorLog0("inferKeyUsage: dynamic_cast failure(1)\n");
+			CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+		}
+		if(ku->GetBit(KeyUsage::digitalSignature)) {
+			keyUse |= CSSM_KEYUSE_VERIFY;
+		}
+		if(ku->GetBit(KeyUsage::nonRepudiation)) {
+			keyUse |= CSSM_KEYUSE_VERIFY;
+		}
+		if(ku->GetBit(KeyUsage::keyEncipherment)) {
+			keyUse |= CSSM_KEYUSE_WRAP;
+		}
+		if(ku->GetBit(KeyUsage::keyAgreement)) {
+			keyUse |= CSSM_KEYUSE_DERIVE;
+		}
+		if(ku->GetBit(KeyUsage::keyCertSign)) {
+			keyUse |= CSSM_KEYUSE_VERIFY;
+		}
+		if(ku->GetBit(KeyUsage::cRLSign)) {
+			keyUse |= CSSM_KEYUSE_VERIFY;
+		}
+		if(ku->GetBit(KeyUsage::dataEncipherment)) {
+			keyUse |= CSSM_KEYUSE_ENCRYPT;
+		}
+	}
+	decodedExten = findDecodedExt(id_ce_extKeyUsage, false, 0, numFields);
+	if(decodedExten) {
+		ExtKeyUsageSyntax *eku = 
+			dynamic_cast<ExtKeyUsageSyntax *>(decodedExten->snaccObj);
+		if(eku == NULL) {
+			errorLog0("inferKeyUsage: dynamic_cast failure(2)\n");
+			CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+		}
+		unsigned numOids = eku->Count();
+		eku->SetCurrToFirst();
+		unsigned oidDex;
+		for(oidDex=0; oidDex<numOids; oidDex++) {
+			KeyPurposeId *purp = eku->Curr();
+			if(*purp == id_kp_codeSigning) {
+				keyUse |= CSSM_KEYUSE_VERIFY;
+			}
+			/* I don't think the other purposes are useful... */
+			eku->GoNext();
+		}
+	}
+	if(keyUse == 0) {
+		/* Nothing found; take the default. */
+		keyUse = CSSM_KEYUSE_ANY;
+	}
+	return keyUse;
+}
+
+/*
+ * Obtain a CSSM_KEY from a decoded cert, inferring as much as we can
+ * from required fields (subjectPublicKeyInfo) and extensions (for 
+ * KeyUse).
+ */
+CSSM_KEY_PTR DecodedCert::extractCSSMKey(
+	CssmAllocator		&alloc)	const
+{
+	CASSERT(certificateToSign != NULL);
+	SubjectPublicKeyInfo *snaccKeyInfo = certificateToSign->subjectPublicKeyInfo;
+	if((snaccKeyInfo == NULL) ||
+	   (snaccKeyInfo->algorithm == NULL)) {
+		CssmError::throwMe(CSSMERR_CL_NO_FIELD_VALUES);
+	}
+	CSSM_KEY_PTR cssmKey = (CSSM_KEY_PTR) alloc.malloc(sizeof(CSSM_KEY));
+	memset(cssmKey, 0, sizeof(CSSM_KEY));
+	CSSM_KEYHEADER &hdr = cssmKey->KeyHeader;
+	CssmRemoteData keyData(alloc, cssmKey->KeyData);
+	try {
+		hdr.HeaderVersion = CSSM_KEYHEADER_VERSION;
+		/* CspId blank */
+		hdr.BlobType = CSSM_KEYBLOB_RAW;
+		hdr.AlgorithmId = CL_snaccOidToCssmAlg(snaccKeyInfo->algorithm->algorithm);
+			
+		/* 
+		 * Format inferred from AlgorithmId. I have never seen these defined
+		 * anywhere, e.g., whart's the format of an RSA public key in a cert?
+		 * X509 certainly doesn't say. However. the following two cases are known
+		 * to be correct. 
+		 */
+		switch(hdr.AlgorithmId) {
+			case CSSM_ALGID_RSA:
+				hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
+				break;
+			case CSSM_ALGID_DSA:
+				hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
+				break;
+			case CSSM_ALGID_FEE:
+				/* CSSM_KEYBLOB_RAW_FORMAT_NONE --> DER encoded */
+				hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_NONE;
+				break;
+			default:
+				/* punt */
+				hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_NONE;
+		}
+		hdr.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+		
+		/* KeyUsage inferred from extensions */
+		hdr.KeyUsage = inferKeyUsage();
+		
+		/* start/end date unknown, leave zero */
+		hdr.WrapAlgorithmId = CSSM_ALGID_NONE;
+		hdr.WrapMode = CSSM_ALGMODE_NONE;
+		
+		/*
+		 * subjectPublicKeyInfo.subjectPublicKey (AsnBits) ==> KeyData
+		 */
+		SC_asnBitsToCssmData(snaccKeyInfo->subjectPublicKey, keyData);
+		keyData.release();
+
+		/*
+		 * LogicalKeySizeInBits - ask the CSP
+		 */
+		CSSM_CSP_HANDLE cspHand = getGlobalCspHand(true);
+		CSSM_KEY_SIZE keySize;
+		CSSM_RETURN crtn;
+		crtn = CSSM_QueryKeySizeInBits(cspHand, NULL, cssmKey, &keySize);
+		if(crtn) {
+			CssmError::throwMe(crtn);
+		}
+		cssmKey->KeyHeader.LogicalKeySizeInBits = 
+			keySize.LogicalKeySizeInBits;
+	}
+	catch (...) {
+		alloc.free(cssmKey);
+		throw;
+	}
+	return cssmKey;
+}
+
+void DecodedCert::freeCSSMKey(
+	CSSM_KEY_PTR		cssmKey,
+	CssmAllocator		&alloc,
+	bool				freeTop)
+{
+	if(cssmKey == NULL) {
+		return;
+	}
+	alloc.free(cssmKey->KeyData.Data);
+	memset(cssmKey, 0, sizeof(CSSM_KEY));
+	if(freeTop) {
+		alloc.free(cssmKey);
+	}
+}
+
diff --git a/AppleX509CL/DecodedCert.h b/AppleX509CL/DecodedCert.h
new file mode 100644
index 00000000..7296829b
--- /dev/null
+++ b/AppleX509CL/DecodedCert.h
@@ -0,0 +1,233 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * DecodedCert.h - object representing a snacc-decoded cert, with extensions
+ * parsed and decoded (still in snacc format).
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ *
+ * This object is how we store certs, both when caching them (explicitly or
+ * during a search), and as an intermediate stage during template (TBS, or
+ * to-be-signed cert) construction. This is a subclass of the SNACC-generated class
+ * Certificate; the main functionality we add is the parsing and decoding of 
+ * Extensions. Extensions are not decoded in class Certificate beyond the level
+ * of the X.509 Extension object, which just contains the ID (an OID), the
+ * critical flag, and an octet string containing an ID-specific thing. 
+ *
+ * When we decode a cert or a TBS, we also parse the Extension objects, decoding
+ * then into specific SNACC classes like KeyUsage or BasicConstriantsSyntax. We
+ * keep these decoded extensions in a list of DecodedExten structs. GetCertField
+ * ops which access extensions access these DecodedExten structs.
+ *
+ * When creating a cert template (TBS), each incoming field associated with an 
+ * extension is translated into an object like a (SNACC) KeyUsage and stored in
+ * our DecodedExten list. 
+ *
+ * When encoding a TBS, we BER-encode each of the SNACC objects (KeyUsage, etc.) 
+ * in our list of DecodedExtens, wrapthe result in an Octet string (actually an
+ * AsnOcts) and store it in the SNACC-generated CertificateToSign's extensions
+ * list. 
+ *
+ * Support for extensions which we don't understand is handled as follows. When
+ * setting cert fields for such extensions during template construction, the app 
+ * has to BER-encode the underlying extension. We just wrap this in an octet string
+ * (AsnOcts) and store the result in a DecodedExten without further ado. When 
+ * encoding the TBS, this octet string is just copied into the CertificateToSign's 
+ * Extension list without further ado. When decoding a cert, if we find an 
+ * extension we don't understand, the SNACC object stored in the DecodedExten 
+ * is just a copy of the AsnOcts (which is the BER encoding of the underlying 
+ * mystery extension wrapped in an Octet string). We pass back the Octet string's 
+ * contents (*not* the BER-encoded octet string) during a GetCertField op. 
+ */
+
+#ifndef	_DECODED_CERT_H_
+#define _DECODED_CERT_H_
+
+#include <Security/cssmtype.h>
+#include <Security/cssmdata.h>
+
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+#include <Security/sm_x501if.h>
+#include <Security/sm_x520sa.h>
+#include <Security/sm_x411mtsas.h>
+#include <Security/sm_x509cmn.h>
+#include <Security/sm_x509af.h>
+#include <Security/pkcs9oids.h>
+#include <Security/sm_x509ce.h>
+#include <Security/sm_cms.h>
+#include <Security/sm_ess.h>
+
+/* state of a DecodedCert */
+typedef enum {
+	CS_Empty,
+	CS_DecodedCert,		// can't set fields in this state
+	CS_DecodedTBS,		// ditto
+	CS_Building			// in the process of setting fields
+} CertState;
+
+/* means for holding decoded extensions */
+typedef struct {
+	AsnOid		*extnId;
+	bool		critical;
+	AsnType		*snaccObj;		// KeyUsage, BasicConstraintsSyntax, etc.
+	bool		berEncoded;		// indicates unknown extension which we
+								// do not BER-decode when parsing a cert
+} DecodedExten;
+
+class AppleX509CLSession;
+
+class DecodedCert : public Certificate
+{
+public:
+	/* construct empty cert, no decoded extensions */
+	DecodedCert(
+		AppleX509CLSession	&session);
+	
+	/* one-shot constructor, decoding from DER-encoded data */
+	DecodedCert(
+		AppleX509CLSession	&session,
+		const CssmData 		&encodedCert);
+		
+	~DecodedCert();
+	
+	/* decode TBSCert and its extensions */
+	void decodeTbs(
+		const CssmData	&encodedTbs);
+		
+	/* encode TBSCert and its extensions */
+	void encodeTbs(
+		CssmOwnedData	&encodedTbs);
+		
+	/***
+	 *** field accessors (in CertFields.cpp)
+	 ***/
+	
+	/* 
+	 * Obtain the index'th occurrence of field specified by fieldId.
+	 * Format of the returned field depends on fieldId.
+	 * Returns total number of fieldId fields in the cert if index is 0.
+	 * Returns true if specified field was found, else returns false. 
+	 */
+	bool getCertFieldData(
+		const CssmOid		&fieldId,			// which field
+		unsigned			index,				// which occurrence (0 = first)
+		uint32				&numFields,			// RETURNED
+		CssmOwnedData		&fieldValue) const;	// RETURNED
+
+	/*
+	 * Set the field specified by fieldId in TBS. 
+	 * Note no index - individual field routines either append (for extensions)
+	 * or throw if field already set (for all others) 
+	 */
+	void setCertField(
+		const CssmOid		&fieldId,		// which field
+		const CssmData		&fieldValue);	
+
+	/*
+	 * Free the fieldId-specific data referred to by fieldValue.get().data().
+	 */
+	static void freeCertFieldData(
+		const CssmOid		&fieldId,
+		CssmOwnedData		&fieldValue);
+
+	void getAllParsedCertFields(
+		uint32 				&NumberOfFields,		// RETURNED
+		CSSM_FIELD_PTR 		&CertFields);			// RETURNED
+
+	static void describeFormat(
+		CssmAllocator 		&alloc,
+		uint32 				&NumberOfFields,
+		CSSM_OID_PTR 		&OidList);
+
+	/*
+  	 * Obtain a CSSM_KEY from a decoded cert, inferring as much as we can
+	 * from required fields (subjectPublicKeyInfo) and extensions (for 
+	 * KeyUse).
+	 */
+	CSSM_KEY_PTR extractCSSMKey(
+		CssmAllocator		&alloc) const;
+
+	static void freeCSSMKey(
+		CSSM_KEY_PTR		cssmKey,
+		CssmAllocator		&alloc,
+		bool				freeTop = true);	// delete the actual key
+												// as well as contents
+
+private:
+
+	/***
+	 *** Extensions support (CertExtensions.cpp)
+	 ***/
+	 
+	/* decode extensions ==> mExtensions */
+	void decodeExtensions();
+
+	/* encode mExtensions ==> tbs->Extensions */
+	void encodeExtensions();
+	
+	CSSM_KEYUSE inferKeyUsage() const;
+
+	/* called from decodeExtensions and setField* */
+	void addExtension(
+		AsnType 			*snaccThing,	// e.g. KeyUsage
+		const AsnOid		&extnId,		
+		bool				critical,
+		bool				berEncoded);
+
+public:
+
+	/* as above, CSSM-centric OID */
+	void addExtension(
+		AsnType 			*snaccThing,	// e.g. KeyUsage
+		const CSSM_OID		&extnId,		
+		bool				critical,
+		bool				berEncoded)
+		{
+			AsnOid snaccOid(reinterpret_cast<char *>(extnId.Data), extnId.Length);
+			addExtension(snaccThing, snaccOid, critical, berEncoded);
+		}
+
+	/* called from getField* and inferKeyUsage */
+	/* returns NULL if not found */
+	DecodedExten *findDecodedExt(
+		const AsnOid		&extnId,		// for known extensions
+		bool				unknown,		// otherwise	
+		uint32				index,	
+		uint32				&numFields) const;
+
+private:
+	CertState			mState;
+	DecodedExten		*mExtensions;
+	unsigned			mNumExtensions;		// # valid DecodedExtens
+	unsigned			mSizeofExtensions;	// mallocd size in DecodedExten
+	CssmAllocator		&alloc;
+	AppleX509CLSession	&mSession;
+	
+	void reset() 
+		{
+			mState = CS_Empty;
+			mExtensions = NULL;
+			mNumExtensions = 0;
+			mSizeofExtensions = 0;
+		}
+};
+
+#endif	/* _DECODED_CERT_H_ */
diff --git a/AppleX509CL/LockedMap.h b/AppleX509CL/LockedMap.h
new file mode 100644
index 00000000..2a7a1c06
--- /dev/null
+++ b/AppleX509CL/LockedMap.h
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * LockedMap.h - STL-style map with attached Mutex
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+ 
+#ifndef	_LOCKED_MAP_H_
+#define _LOCKED_MAP_H_
+
+#include <map>
+#include <Security/threading.h>
+
+template <class KeyType, class ValueType>
+class LockedMap
+{
+private:
+	typedef std::map<KeyType, ValueType *> MapType;
+	MapType					mMap;
+	Mutex					mMapLock;
+	
+	/* low-level lookup, cacheMapLock held on entry and exit */
+	ValueType 				
+	*lookupEntryLocked(KeyType key) 
+		{
+			// don't create new entry if desired entry isn't there
+			MapType::iterator it = mMap.find(key);
+			if(it == mMap.end()) {
+				return NULL;
+			}
+			return it->second;
+		}
+
+public:
+	/* high level maintenance */
+	void 
+	addEntry(ValueType &value, KeyType key)
+		{
+			StLock<Mutex> _(mMapLock);
+			mMap[key] = &value;
+		}
+		
+	ValueType				
+	*lookupEntry(KeyType key)
+		{
+			StLock<Mutex> _(mMapLock);
+			return lookupEntryLocked(key);
+		}
+		
+	void	
+	removeEntry(KeyType key)
+		{
+			StLock<Mutex> _(mMapLock);
+
+			ValueType *value = lookupEntryLocked(key);
+			if(value != NULL) {
+				mMap.erase(key);
+			}
+		}
+		
+	ValueType	
+	*removeFirstEntry()
+		{
+			StLock<Mutex> _(mMapLock);
+			MapType::iterator it = mMap.begin();
+			if(it == mMap.end()) {
+				return NULL;
+			}
+			ValueType *rtn = it->second;
+			mMap.erase(it->first);
+			return rtn;
+		}
+};
+
+#endif	/* _LOCKED_MAP_H_ */
diff --git a/AppleX509CL/Session_CRL.cpp b/AppleX509CL/Session_CRL.cpp
new file mode 100644
index 00000000..89902a33
--- /dev/null
+++ b/AppleX509CL/Session_CRL.cpp
@@ -0,0 +1,232 @@
+/*
+ * 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.
+ */
+
+
+//
+// Apple X.509 CRL-related session functions.
+//
+
+#include "AppleX509CLSession.h"
+
+void
+AppleX509CLSession::CrlDescribeFormat(
+	uint32 &NumberOfFields,
+	CSSM_OID_PTR &OidList)
+{
+	unimplemented();
+}
+
+
+void
+AppleX509CLSession::CrlGetAllFields(
+	const CssmData &Crl,
+	uint32 &NumberOfCrlFields,
+	CSSM_FIELD_PTR &CrlFields)
+{
+	unimplemented();
+}
+
+
+CSSM_HANDLE
+AppleX509CLSession::CrlGetFirstFieldValue(
+	const CssmData &Crl,
+	const CssmData &CrlField,
+	uint32 &NumberOfMatchedFields,
+	CSSM_DATA_PTR &Value)
+{
+	unimplemented();
+	return CSSM_INVALID_HANDLE;
+}
+
+	
+bool
+AppleX509CLSession::CrlGetNextFieldValue(
+	CSSM_HANDLE ResultsHandle,
+	CSSM_DATA_PTR &Value)
+{
+	unimplemented();
+	return false;
+}
+
+
+void
+AppleX509CLSession::IsCertInCrl(
+	const CssmData &Cert,
+	const CssmData &Crl,
+	CSSM_BOOL &CertFound)
+{
+	unimplemented();
+}
+
+	
+	
+#if __MWERKS__
+#pragma mark Cached
+#endif
+	
+void
+AppleX509CLSession::CrlCache(
+	const CssmData &Crl,
+	CSSM_HANDLE &CrlHandle)
+{
+	unimplemented();
+}
+
+
+CSSM_HANDLE
+AppleX509CLSession::CrlGetFirstCachedFieldValue(
+	CSSM_HANDLE CrlHandle,
+	const CssmData *CrlRecordIndex,
+	const CssmData &CrlField,
+	uint32 &NumberOfMatchedFields,
+	CSSM_DATA_PTR &Value)
+{
+	unimplemented();
+	return CSSM_INVALID_HANDLE;
+}
+
+
+bool
+AppleX509CLSession::CrlGetNextCachedFieldValue(
+	CSSM_HANDLE ResultsHandle,
+	CSSM_DATA_PTR &Value)
+{
+	unimplemented();
+	return false;
+}
+
+
+void
+AppleX509CLSession::IsCertInCachedCrl(
+	const CssmData &Cert,
+	CSSM_HANDLE CrlHandle,
+	CSSM_BOOL &CertFound,
+	CssmData &CrlRecordIndex)
+{
+	unimplemented();
+}
+
+
+void
+AppleX509CLSession::CrlAbortCache(
+	CSSM_HANDLE CrlHandle)
+{
+	unimplemented();
+}
+
+
+void
+AppleX509CLSession::CrlAbortQuery(
+	CSSM_HANDLE ResultsHandle)
+{
+	unimplemented();
+}
+
+
+
+#if __MWERKS__
+#pragma mark Template
+#endif
+
+void
+AppleX509CLSession::CrlCreateTemplate(
+	uint32 NumberOfFields,
+	const CSSM_FIELD *CrlTemplate,
+	CssmData &NewCrl)
+{
+	unimplemented();
+}
+
+
+void
+AppleX509CLSession::CrlSetFields(
+	uint32 NumberOfFields,
+	const CSSM_FIELD *CrlTemplate,
+	const CssmData &OldCrl,
+	CssmData &ModifiedCrl)
+{
+	unimplemented();
+}
+
+
+void
+AppleX509CLSession::CrlAddCert(
+	CSSM_CC_HANDLE CCHandle,
+	const CssmData &Cert,
+	uint32 NumberOfFields,
+	const CSSM_FIELD CrlEntryFields[],
+	const CssmData &OldCrl,
+	CssmData &NewCrl)
+{
+	unimplemented();
+}
+
+
+void
+AppleX509CLSession::CrlRemoveCert(
+	const CssmData &Cert,
+	const CssmData &OldCrl,
+	CssmData &NewCrl)
+{
+	unimplemented();
+}
+
+
+void
+AppleX509CLSession::CrlGetAllCachedRecordFields(
+	CSSM_HANDLE CrlHandle,
+	const CssmData &CrlRecordIndex,
+	uint32 &NumberOfFields,
+	CSSM_FIELD_PTR &CrlFields)
+{
+	unimplemented();
+}
+
+void
+AppleX509CLSession::CrlVerifyWithKey(
+	CSSM_CC_HANDLE CCHandle,
+	const CssmData &CrlToBeVerified)
+{
+	unimplemented();
+}
+
+
+void
+AppleX509CLSession::CrlVerify(
+	CSSM_CC_HANDLE CCHandle,
+	const CssmData &CrlToBeVerified,
+	const CssmData &SignerCert,
+	const CSSM_FIELD *VerifyScope,
+	uint32 ScopeSize)
+{
+	unimplemented();
+}
+
+void
+AppleX509CLSession::CrlSign(
+	CSSM_CC_HANDLE CCHandle,
+	const CssmData &UnsignedCrl,
+	const CSSM_FIELD *SignScope,
+	uint32 ScopeSize,
+	CssmData &SignedCrl)
+{
+	unimplemented();
+}
+
+
+
+
diff --git a/AppleX509CL/Session_Cert.cpp b/AppleX509CL/Session_Cert.cpp
new file mode 100644
index 00000000..39bbb6ef
--- /dev/null
+++ b/AppleX509CL/Session_Cert.cpp
@@ -0,0 +1,348 @@
+/*
+ * 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.
+ */
+
+
+//
+// Session_Cert.cpp - cert-related session functions.
+//
+
+#include "AppleX509CLSession.h"
+#include "DecodedCert.h"
+#include "CLCachedEntry.h"
+#include "cldebugging.h"
+#include <Security/oidscert.h>
+
+void
+AppleX509CLSession::CertDescribeFormat(
+	uint32 &NumberOfFields,
+	CSSM_OID_PTR &OidList)
+{
+	DecodedCert::describeFormat(*this, NumberOfFields, OidList);
+}
+
+void
+AppleX509CLSession::CertGetAllFields(
+	const CssmData &Cert,
+	uint32 &NumberOfFields,
+	CSSM_FIELD_PTR &CertFields)
+{
+	class DecodedCert decodedCert(*this, Cert);
+	decodedCert.getAllParsedCertFields(NumberOfFields, CertFields);
+}
+
+
+CSSM_HANDLE
+AppleX509CLSession::CertGetFirstFieldValue(
+	const CssmData &EncodedCert,
+	const CssmData &CertField,
+	uint32 &NumberOfMatchedFields,
+	CSSM_DATA_PTR &Value)
+{
+	NumberOfMatchedFields = 0;
+	Value = NULL;
+	CssmAutoData aData(*this);
+	
+	DecodedCert *decodedCert = new DecodedCert(*this, EncodedCert);
+	uint32 numMatches;
+	
+	/* this returns false if field not there, throws on bad OID */
+	bool brtn;
+	try {
+		brtn = decodedCert->getCertFieldData(CertField, 
+			0, 				// index
+			numMatches, 
+			aData);
+	}
+	catch (...) {
+		delete decodedCert;
+		throw;
+	}
+	if(!brtn) {
+		delete decodedCert;
+		return CSSM_INVALID_HANDLE;
+	}
+
+	/* cook up a CLCachedCert, stash it in cache */
+	CLCachedCert *cachedCert = new CLCachedCert(*decodedCert);
+	cacheMap.addEntry(*cachedCert, cachedCert->handle());
+	
+	/* cook up a CLQuery, stash it */
+	CLQuery *query = new CLQuery(
+		CLQ_Cert, 
+		CertField, 
+		numMatches,
+		false,				// isFromCache
+		cachedCert->handle());
+	queryMap.addEntry(*query, query->handle());
+	
+	/* success - copy field data to outgoing Value */
+	Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
+	*Value = aData.release();
+	NumberOfMatchedFields = numMatches;
+	return query->handle();
+}
+
+
+bool
+AppleX509CLSession::CertGetNextFieldValue(
+	CSSM_HANDLE ResultsHandle,
+	CSSM_DATA_PTR &Value)
+{
+	/* fetch & validate the query */
+	CLQuery *query = queryMap.lookupEntry(ResultsHandle);
+	if(query == NULL) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
+	}
+	if(query->nextIndex() >= query->numFields()) {
+		return false;
+	}
+
+	/* fetch the associated cached cert */
+	CLCachedCert *cachedCert = lookupCachedCert(query->cachedObject());
+	uint32 dummy;
+	CssmAutoData aData(*this);
+	if(!cachedCert->cert().getCertFieldData(query->fieldId(), 
+		query->nextIndex(), 
+		dummy,
+		aData))  {
+		return false;
+	}
+		
+	/* success - copy field data to outgoing Value */
+	Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
+	*Value = aData.release();
+	query->incrementIndex();
+	return true;
+}
+
+void
+AppleX509CLSession::CertCache(
+	const CssmData &EncodedCert,
+	CSSM_HANDLE &CertHandle)
+{
+	DecodedCert *decodedCert = new DecodedCert(*this, EncodedCert);
+	
+	/* cook up a CLCachedCert, stash it in cache */
+	CLCachedCert *cachedCert = new CLCachedCert(*decodedCert);
+	cacheMap.addEntry(*cachedCert, cachedCert->handle());
+	CertHandle = cachedCert->handle();
+}
+
+CSSM_HANDLE
+AppleX509CLSession::CertGetFirstCachedFieldValue(
+	CSSM_HANDLE CertHandle,
+	const CssmData &CertField,
+	uint32 &NumberOfMatchedFields,
+	CSSM_DATA_PTR &Value)
+{
+	/* fetch the associated cached cert */
+	CLCachedCert *cachedCert = lookupCachedCert(CertHandle);
+	if(cachedCert == NULL) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
+	}
+	
+	CssmAutoData aData(*this);
+	uint32 numMatches;
+
+	/* this returns false if field not there, throws on bad OID */
+	if(!cachedCert->cert().getCertFieldData(CertField, 
+			0, 				// index
+			numMatches, 
+			aData)) {
+		return CSSM_INVALID_HANDLE;
+	}
+
+	/* cook up a CLQuery, stash it */
+	CLQuery *query = new CLQuery(
+		CLQ_Cert, 
+		CertField, 
+		numMatches,
+		true,				// isFromCache
+		cachedCert->handle());
+	queryMap.addEntry(*query, query->handle());
+	
+	/* success - copy field data to outgoing Value */
+	Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
+	*Value = aData.release();
+	NumberOfMatchedFields = numMatches;
+	return query->handle();
+}
+
+
+bool
+AppleX509CLSession::CertGetNextCachedFieldValue(
+	CSSM_HANDLE ResultsHandle,
+	CSSM_DATA_PTR &Value)
+{
+	/* Identical to, so just call... */
+	return CertGetNextFieldValue(ResultsHandle, Value);
+}
+
+void
+AppleX509CLSession::CertAbortCache(
+	CSSM_HANDLE CertHandle)
+{
+	/* fetch the associated cached cert, remove from map, delete it */
+	CLCachedCert *cachedCert = lookupCachedCert(CertHandle);
+	if(cachedCert == NULL) {
+		errorLog0("CertAbortCache: cachedCert not found\n");
+		CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
+	}
+	cacheMap.removeEntry(cachedCert->handle());
+	delete cachedCert;
+}
+
+/*
+ * Abort either type of cert field query (cache based or non-cache based)
+ */
+void
+AppleX509CLSession::CertAbortQuery(
+	CSSM_HANDLE ResultsHandle)
+{
+	/* fetch & validate the query */
+	CLQuery *query = queryMap.lookupEntry(ResultsHandle);
+	if(query == NULL) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
+	}
+
+	if(!query->fromCache()) {
+		/* the associated cached cert was created just for this query; dispose */
+		CLCachedCert *cachedCert = lookupCachedCert(query->cachedObject());
+		if(cachedCert == NULL) {
+			/* should never happen */
+			errorLog0("CertAbortQuery: cachedCert not found\n");
+			CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+		}
+		cacheMap.removeEntry(cachedCert->handle());
+		delete cachedCert;
+	}
+	queryMap.removeEntry(query->handle());
+	delete query;
+}
+
+void
+AppleX509CLSession::CertCreateTemplate(
+	uint32 NumberOfFields,
+	const CSSM_FIELD CertFields[],
+	CssmData &CertTemplate)
+{
+	/* cook up an empty Cert */
+	DecodedCert cert(*this);
+
+	/* grind thru specified fields; exceptions are fatal */
+	for(uint32 dex=0; dex<NumberOfFields; dex++) {
+		cert.setCertField(
+			CssmOid::overlay(CertFields[dex].FieldOid), 
+			CssmData::overlay(CertFields[dex].FieldValue));
+	}
+	
+	/* TBD - ensure all required fields are set? We do this 
+	 * when we sign the cert; maybe we should do it here. */
+	
+	/* 
+	 * We have the CertificateToSign in snacc format. Encode.
+	 */
+	CssmRemoteData rData(*this, CertTemplate);
+	cert.encodeTbs(rData);
+	rData.release();
+}
+
+
+void
+AppleX509CLSession::CertGetAllTemplateFields(
+	const CssmData &CertTemplate,
+	uint32 &NumberOfFields,
+	CSSM_FIELD_PTR &CertFields)
+{
+	DecodedCert	cert(*this);		// empty
+	cert.decodeTbs(CertTemplate);
+	cert.getAllParsedCertFields(NumberOfFields, CertFields);
+}
+
+void
+AppleX509CLSession::FreeFields(
+	uint32 NumberOfFields,
+	CSSM_FIELD_PTR &FieldArray)
+{
+	unsigned 		i;
+	CSSM_FIELD_PTR 	thisField;
+	CSSM_OID_PTR	thisOid;
+	
+	for(i=0; i<NumberOfFields; i++) {
+		thisField = &FieldArray[i];
+		thisOid = &thisField->FieldOid;
+		
+		/* oid-specific handling of value */
+		/* TBD - if this fails, call tbd DecodedCRL::freeCertFieldData */
+		/* BUG - the CssmRemoteData constructor clears the referent,
+		 * iff the referent is a CSSSM_DATA (as opposed to a CssmData).
+		 */
+		CssmData &cData = CssmData::overlay(thisField->FieldValue);
+		CssmRemoteData rData(*this, cData);
+		DecodedCert::freeCertFieldData(CssmOid::overlay(*thisOid), rData);
+		
+		/* and the oid itself */
+		free(thisOid->Data);
+		thisOid->Data = NULL;
+		thisOid->Length = 0;
+	}
+	free(FieldArray);
+}
+
+void
+AppleX509CLSession::FreeFieldValue(
+	const CssmData &CertOrCrlOid,
+	CssmData *Value)
+{
+	if(Value == NULL) {
+		CssmError::throwMe(CSSM_ERRCODE_INVALID_FIELD_POINTER);
+	}
+	CssmRemoteData cd(*this, *Value);
+	/* TBD - if this fails, call tbd DecodedCRL::freeCertFieldData */
+	DecodedCert::freeCertFieldData(CertOrCrlOid, cd);
+	free(Value);
+}
+
+void
+AppleX509CLSession::CertGroupFromVerifiedBundle(
+	CSSM_CC_HANDLE CCHandle,
+	const CSSM_CERT_BUNDLE &CertBundle,
+	const CssmData *SignerCert,
+	CSSM_CERTGROUP_PTR &CertGroup)
+{
+	unimplemented();
+}
+
+void
+AppleX509CLSession::CertGroupToSignedBundle(
+	CSSM_CC_HANDLE CCHandle,
+	const CSSM_CERTGROUP &CertGroupToBundle,
+	const CSSM_CERT_BUNDLE_HEADER *BundleInfo,
+	CssmData &SignedBundle)
+{
+	unimplemented();
+}
+
+void
+AppleX509CLSession::PassThrough(
+	CSSM_CC_HANDLE CCHandle,
+	uint32 PassThroughId,
+	const void *InputParams,
+	void **OutputParams)
+{
+	unimplemented();
+}
diff --git a/AppleX509CL/Session_Crypto.cpp b/AppleX509CL/Session_Crypto.cpp
new file mode 100644
index 00000000..223e55d9
--- /dev/null
+++ b/AppleX509CL/Session_Crypto.cpp
@@ -0,0 +1,312 @@
+/*
+ * 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.
+ */
+
+
+/* 
+ * Session_Crypto.cpp: CL session functions: sign, verify, CSSM_KEY extraction.
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+
+#include "AppleX509CLSession.h"
+#include "DecodedCert.h"
+#include "SnaccUtils.h"
+#include "cldebugging.h"
+#include "CSPAttacher.h"
+#include <Security/oidscert.h>
+#include <Security/cssmapple.h>
+#include <Security/cssmerrno.h>
+#include <Security/cdsaUtils.h>
+
+/*
+ * Given a DER-encoded cert, obtain a fully usable CSSM_KEY representing
+ * the cert's public key. 
+ */
+void
+AppleX509CLSession::CertGetKeyInfo(
+	const CssmData &Cert,
+	CSSM_KEY_PTR &Key)
+{
+	DecodedCert decodedCert(*this, Cert);
+	Key = decodedCert.extractCSSMKey(*this);
+}
+
+/*
+ * Given a DER-encoded cert and a fully specified crypto context, verify 
+ * cert's TBS and signature. 
+ */
+void
+AppleX509CLSession::CertVerifyWithKey(
+	CSSM_CC_HANDLE CCHandle,
+	const CssmData &CertToBeVerified)
+{
+	CssmAutoData tbs(*this);
+	CssmAutoData algId(*this);
+	CssmAutoData sig(*this);
+	CL_certDecodeComponents(CertToBeVerified, tbs, algId, sig);
+	verifyData(CCHandle, tbs, sig);
+}
+
+/*
+ * Verify a DER-encoded cert, obtaining crypto context from either
+ * caller-specified context or by inference from SignerCert.
+ */
+void
+AppleX509CLSession::CertVerify(
+	CSSM_CC_HANDLE CCHandle,
+	const CssmData &CertToBeVerified,
+	const CssmData *SignerCert,
+	const CSSM_FIELD *VerifyScope,
+	uint32 ScopeSize)
+{
+	if((VerifyScope != NULL) || (ScopeSize != 0)) {
+		CssmError::throwMe(CSSMERR_CL_SCOPE_NOT_SUPPORTED);
+	}
+	if((CCHandle == CSSM_INVALID_HANDLE) && (SignerCert == NULL)) {
+		/* need one or the other */
+		CssmError::throwMe(CSSMERR_CL_INVALID_CONTEXT_HANDLE);
+	}
+	
+	/* get top-level components  */
+	CssmAutoData tbs(*this);		// in DER format
+	CssmAutoData algId(*this);		// in DER format
+	CssmAutoData sig(*this);		// in DER format
+	CL_certDecodeComponents(CertToBeVerified, tbs, algId, sig);
+
+	/* these must be explicitly freed upon exit */
+	CSSM_KEY_PTR signerPubKey = NULL;
+	CSSM_CONTEXT_PTR context = NULL;
+	CSSM_CSP_HANDLE cspHand = CSSM_INVALID_HANDLE;
+	CSSM_CC_HANDLE ourCcHand = CSSM_INVALID_HANDLE;
+	
+	/* SignerCert optional; if present, obtain its subject key */
+	if(SignerCert != NULL) {
+		CertGetKeyInfo(*SignerCert, signerPubKey);
+	}
+	
+	/* signerPubKey must be explicitly freed in any case */
+	try {
+		if(CCHandle != CSSM_INVALID_HANDLE) {
+			/*
+			 * We'll use this CCHandle for the sig verify, but 
+			 * make sure it matches possible incoming SignerCert parameters
+			 */
+			if(SignerCert != NULL) {
+				CSSM_RETURN crtn;
+				
+				/* extract signer's public key as a CSSM_KEY from context */
+				crtn = CSSM_GetContext(CCHandle, &context);
+				if(crtn) {
+					CssmError::throwMe(CSSMERR_CL_INVALID_CONTEXT_HANDLE);
+				}
+				CSSM_CONTEXT_ATTRIBUTE_PTR attr;
+				crtn = CSSM_GetContextAttribute(context,
+					CSSM_ATTRIBUTE_KEY,
+					&attr);
+				if(crtn) {
+					errorLog0("CertVerify: valid CCHandle but no key!\n");
+					CssmError::throwMe(CSSMERR_CL_INVALID_CONTEXT_HANDLE);
+				}
+				/* require match */
+				CASSERT(signerPubKey != NULL);
+				CSSM_KEY_PTR contextPubKey = attr->Attribute.Key;
+				if(contextPubKey->KeyHeader.AlgorithmId != 
+				   signerPubKey->KeyHeader.AlgorithmId) {
+					errorLog0("CertVerify: AlgorithmId mismatch!\n");
+					CssmError::throwMe(CSSMERR_CL_INVALID_CONTEXT_HANDLE);
+				}
+				
+				/* TBD - check key size, when we have a CSP which can report it */
+				/* TBD - anything else? */
+			}	/* verifying multiple contexts */
+			/* OK to use CCHandle as is for verify context */
+		}	/* valid CCHandle */
+		else {
+			/* 
+			 * All we have is signer cert. We already have its public key;
+			 * get signature alg from CertToBeVerified's Cert.algID (which 
+			 * we currently have in DER form).
+			 */
+			CASSERT(SignerCert != NULL);
+			CASSERT(signerPubKey != NULL);
+			
+			AlgorithmIdentifier snaccAlgId;
+			//CL_decodeAlgId(algId, snaccAlgId);
+			SC_decodeAsnObj(algId, snaccAlgId);
+			CSSM_ALGORITHMS vfyAlg = CL_snaccOidToCssmAlg(snaccAlgId.algorithm);
+			
+			/* attach to CSP, cook up a context */
+			cspHand = getGlobalCspHand(true);
+			CSSM_RETURN crtn;
+			crtn = CSSM_CSP_CreateSignatureContext(cspHand,
+				vfyAlg,
+				NULL,			// Access Creds
+				signerPubKey,
+				&ourCcHand);
+			CCHandle = ourCcHand;
+		}	/* inferring sig verify context from SignerCert */
+		verifyData(CCHandle, tbs, sig);
+	}
+	catch(...) {
+		/* FIXME - isn't there a better way to do this? Save the 
+		 * exception as a CSSM_RETURN and throw it if nonzero later?
+		 */
+		if(context != NULL) {
+			CSSM_FreeContext(context);
+		}
+		DecodedCert::freeCSSMKey(signerPubKey, *this);
+		if(ourCcHand != CSSM_INVALID_HANDLE) {
+			CSSM_DeleteContext(ourCcHand);
+		}
+		throw;
+	}
+	if(context != NULL) {
+		CSSM_FreeContext(context);
+	}
+	DecodedCert::freeCSSMKey(signerPubKey, *this);
+	if(ourCcHand != CSSM_INVALID_HANDLE) {
+		CSSM_DeleteContext(ourCcHand);
+	}
+}
+
+/*
+ * Given a DER-encoded TBSCert and a fully specified crypto context,
+ * sign the TBSCert and return the resulting DER-encoded Cert.
+ */
+void
+AppleX509CLSession::CertSign(
+	CSSM_CC_HANDLE CCHandle,
+	const CssmData &CertTemplate,
+	const CSSM_FIELD *SignScope,
+	uint32 ScopeSize,
+	CssmData &SignedCert)
+{
+	if((SignScope != NULL) || (ScopeSize != 0)) {
+		CssmError::throwMe(CSSMERR_CL_SCOPE_NOT_SUPPORTED);
+	}
+	if(CCHandle == CSSM_INVALID_HANDLE) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_CONTEXT_HANDLE);
+	}
+	
+	/* cook up algId from context->(signing key, sig algorithm) */
+	CSSM_CONTEXT_PTR context = NULL;		// must be freed
+	CSSM_RETURN crtn;
+	crtn = CSSM_GetContext(CCHandle, &context);
+	if(crtn) {
+		CssmError::throwMe(CSSMERR_CL_INVALID_CONTEXT_HANDLE);
+	}
+	CSSM_CONTEXT_ATTRIBUTE_PTR attr;		// not freed
+	crtn = CSSM_GetContextAttribute(context,
+		CSSM_ATTRIBUTE_KEY,
+		&attr);
+	if(crtn) {
+		errorLog0("CertSign: valid CCHandle but no signing key!\n");
+		CssmError::throwMe(CSSMERR_CL_INVALID_CONTEXT_HANDLE);
+	}
+	CSSM_KEY_PTR signingKey = attr->Attribute.Key;
+	if(signingKey == NULL) {
+		errorLog0("CertSign: valid CCHandle, NULL signing key!\n");
+		CssmError::throwMe(CSSMERR_CL_INVALID_CONTEXT_HANDLE);
+	}
+
+	AlgorithmIdentifier snaccAlgId;
+	CssmAutoData encAlgId(*this);
+	CssmAutoData rawSig(*this);
+	CssmAutoData fullCert(*this);
+	try {
+		/* CSSM alg --> snacc-style AlgorithmIdentifier object */
+		CL_cssmAlgToSnaccOid(context->AlgorithmType,
+				snaccAlgId.algorithm);
+		/* NULL params - FIXME - is this OK? */
+		CL_nullAlgParams(snaccAlgId);
+		/* DER-encode the algID */
+		SC_encodeAsnObj(snaccAlgId, encAlgId, 128);
+		/* sign TBS --> sig */
+		signData(CCHandle, CertTemplate, rawSig);
+		/* put it all together */
+		CL_certEncodeComponents(CertTemplate, encAlgId, rawSig, fullCert);
+	}
+	catch (...) {
+		CSSM_FreeContext(context);
+		throw;
+	}
+	CSSM_FreeContext(context);
+	SignedCert = fullCert.release();
+}
+
+/*** Private functions ***/
+
+/*
+ * Sign a CssmData with the specified signing context. Used for
+ * signing both certs and CRLs; this routine doesn't know anything 
+ * about either one. 
+ */
+void 
+AppleX509CLSession::signData(
+	CSSM_CC_HANDLE	ccHand,
+	const CssmData	&tbs,
+	CssmOwnedData	&sig)			// mallocd and returned
+{
+	CSSM_RETURN crtn;
+	CssmData cSig;
+	
+	crtn = CSSM_SignData(
+		ccHand,
+		&tbs,
+		1,					// DataBufCount
+		CSSM_ALGID_NONE,	// DigestAlgorithm,
+		&cSig);
+	if(crtn) {
+		errorLog1("AppleX509CLSession::CSSM_SignData: %s\n", 
+			cssmErrorString(crtn).c_str());
+		CssmError::throwMe(crtn);
+	}
+	sig.set(cSig);
+}
+
+/*
+ * Verify a block of data given a crypto context and a signature. 
+ * Used for verifying certs and CRLs. Returns a CSSM_RETURN (callers
+ * always need to clean up after calling us).
+ */ 
+void AppleX509CLSession::verifyData(
+	CSSM_CC_HANDLE	ccHand,
+	const CssmData	&tbs,
+	const CssmData	&sig)
+{
+	CSSM_RETURN crtn;
+	
+	crtn = CSSM_VerifyData(ccHand,
+		&tbs,
+		1,
+		CSSM_ALGID_NONE,		// Digest alg
+		&sig);
+	if(crtn) {
+		// errorLog1("AppleX509CLSession::verifyData: %s\n", 
+		//	cssmErrorString(crtn).c_str());
+		if(crtn == CSSMERR_CSP_VERIFY_FAILED) {
+			/* CSP and CL report this differently */
+			CssmError::throwMe(CSSMERR_CL_VERIFICATION_FAILURE);
+		}
+		else {
+			CssmError::throwMe(crtn);
+		}
+	}
+}
+
+
diff --git a/AppleX509CL/SnaccUtils.cpp b/AppleX509CL/SnaccUtils.cpp
new file mode 100644
index 00000000..99a7ea74
--- /dev/null
+++ b/AppleX509CL/SnaccUtils.cpp
@@ -0,0 +1,834 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * CertSNACC.cpp - snacc-related cert functions
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+ 
+#include "SnaccUtils.h"
+#include "cldebugging.h"
+#include <Security/pkcs1oids.h>
+#include <Security/cdsaUtils.h>
+#include <Security/cssmapple.h>
+#include <Security/appleoids.h>
+#include <Security/globalizer.h>
+
+#define DEBUG_DECODE	0
+#if		DEBUG_DECODE
+#define ddprintf(x)		printf  x
+#else
+#define ddprintf(x)
+#endif
+
+/*
+ * AsnOid "constants" which we construct and cache on demand to avoid the 
+ * somewhat expensive op of constructing them every time we test for equality 
+ * in CL_snaccOidToCssmAlg.
+ */
+class AlgOidCache
+{
+public:
+	AlgOidCache() :
+		mRsaEncryption(rsaEncryption_arc),
+		mMd2WithRSAEncryption(md2WithRSAEncryption_arc),
+		mMd5WithRSAEncryption(md5WithRSAEncryption_arc),
+		mSha1withRSAEncryption(sha1withRSAEncryption_arc),
+		mId_dsa(id_dsa_arc),
+		mId_dsa_with_sha1(id_dsa_with_sha1_arc),
+		mAppleFee(appleFee_arc),
+		mAppleAsc(appleAsc_arc),
+		mAppleFeeMD5(appleFeeMD5_arc),
+		mAppleFeeSHA1(appleFeeSHA1_arc),
+		mAppleFeed(appleFeed_arc),
+		mAppleFeedExp(appleFeedExp_arc),
+		mAppleECDSA(appleECDSA_arc)
+			{ }
+		
+	AsnOid 	mRsaEncryption;
+	AsnOid	mMd2WithRSAEncryption;
+	AsnOid	mMd5WithRSAEncryption;
+	AsnOid	mSha1withRSAEncryption;
+	AsnOid	mId_dsa;
+	AsnOid	mId_dsa_with_sha1;
+	AsnOid	mAppleFee;
+	AsnOid	mAppleAsc;
+	AsnOid	mAppleFeeMD5;
+	AsnOid	mAppleFeeSHA1;
+	AsnOid	mAppleFeed;
+	AsnOid	mAppleFeedExp;
+	AsnOid	mAppleECDSA;
+};
+
+static ModuleNexus<AlgOidCache> algOidCache;
+
+/*
+ * To ensure a secure means of signing and verifying TBSCert blobs, we
+ * provide these functions to encode and decode just the top-level
+ * elements of a certificate. Snacc doesn't allow you to specify, for
+ * example, a fully encoded TBSCert prior to encoding the whole cert after
+ * signing it - you have to decode the TBSCert, put it and the other
+ * components into a Cert, and then encode the whole thing. Unfortunately
+ * there is no guarantee that when you decode and re-encode a TBSCert blob,
+ * you get the same thing you started with (although with DER rules, as
+ * opposed to BER rules, you should). Thus when signing, we sign the TBSCert
+ * and encode the signed cert here without ever decoding the TBSCert (or,
+ * at least, without using the decoded version to get the encoded TBS blob).
+ */
+
+void 
+CL_certDecodeComponents(
+	const CssmData 	&signedCert,		// DER-encoded
+	CssmOwnedData	&TBSCert,			// still DER-encoded
+	CssmOwnedData	&algId,				// ditto
+	CssmOwnedData	&rawSig)			// raw bits (not an encoded AsnBits)
+{
+	CssmAutoData encodedSig(rawSig.allocator);
+
+	/* drop signedCert into an AsnBuf for processing */
+	AsnBuf buf;
+	buf.InstallData(reinterpret_cast<char *>(signedCert.data()), signedCert.length());
+	
+	/* based on snacc-generated Certificate::BDec() and BDecContent() */
+	AsnTag tag;
+	AsnLen bytesDecoded = 0;
+	AsnLen decLen;			// from BDecLen
+	AsnLen totalLen;		// including tag and ASN length 
+	char *elemStart;		// ptr to start of element, including tag
+	
+	int  rtn;
+    ENV_TYPE env;
+    if ((rtn = setjmp (env)) == 0) {
+		tag = BDecTag (buf, bytesDecoded, env);
+		if (tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)) {
+			errorLog1("CL_CertDecodeComponents: bad first-level tag (0x%x)\n", tag);
+			CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+		}
+		decLen = BDecLen (buf, bytesDecoded, env);		// of total
+		/* FIXME - we should be able to ensure right here that we have enough */
+		
+		/* First element, TBSCert */
+		/* Note we need to include the tag and content in the outgoing blobs */
+		elemStart = buf.DataPtr() + bytesDecoded;
+		tag = BDecTag (buf, bytesDecoded, env);
+		if(tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)) {
+			errorLog1("CL_CertDecodeComponents: bad TBSCert tag (0x%x)\n", tag);
+			CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+		}
+
+		decLen = BDecLen (buf, bytesDecoded, env);					// DER 'length'
+		/* buf now at first content byte; simulate grabbing content */
+		totalLen = decLen + (bytesDecoded - (elemStart - buf.DataPtr())); 
+		buf.Skip(decLen);
+		bytesDecoded += decLen;
+		TBSCert.copy(elemStart, totalLen);
+		ddprintf(("CL_certDecodeComponents: TBS len %d; data %02x %02x %02x %02x...\n",
+			totalLen, ((uint8 *)elemStart)[0], ((uint8 *)elemStart)[1],
+			((uint8 *)elemStart)[2], ((uint8 *)elemStart)[3]));
+		
+		/* next element, algId */
+		elemStart = buf.DataPtr() + bytesDecoded;
+		tag = BDecTag (buf, bytesDecoded, env);
+		if(tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)) {
+			errorLog1("CL_CertDecodeComponents: bad AlgId tag (0x%x)\n", tag);
+			CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+		}
+		decLen = BDecLen (buf, bytesDecoded, env);
+		totalLen = decLen + (bytesDecoded - (elemStart - buf.DataPtr())); 
+		buf.Skip(decLen);
+		bytesDecoded += decLen;
+		algId.copy(elemStart, totalLen);
+		ddprintf(("CL_certDecodeComponents: algId len %d; data %02x %02x %02x...\n",
+			totalLen, ((uint8 *)elemStart)[0], ((uint8 *)elemStart)[1],
+			((uint8 *)elemStart)[2]));
+		
+		/* next element, signature */
+		elemStart = buf.DataPtr() + bytesDecoded;
+		tag = BDecTag (buf, bytesDecoded, env);
+		if((tag != MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)) &&
+		   (tag != MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))) {
+			errorLog1("CL_CertDecodeComponents: bad sig tag 0x%x\n", tag);
+			CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+		}
+		decLen = BDecLen (buf, bytesDecoded, env);		
+		totalLen = decLen + (bytesDecoded - (elemStart - buf.DataPtr())); 
+		encodedSig.copy(elemStart, totalLen);
+		ddprintf(("CL_certDecodeComponents: encodedSig len %d; data %02x %02x "
+			"%02x %02x...\n",
+			totalLen, ((uint8 *)elemStart)[0], ((uint8 *)elemStart)[1],
+			((uint8 *)elemStart)[2], ((uint8 *)elemStart)[3]));
+		
+		/*
+		 * encodedSig is a DER-encoded AsnBits. Decode for caller.
+		 */
+		SC_decodeAsnBitsToCssmData(encodedSig.get(), rawSig);
+		ddprintf(("CL_certDecodeComponents: rawSig len %d\n", rawSig.length()));
+		/* 
+		 * OK, if we get here, we can skip the remaining stuff from 
+		 * Certificate::BDecContent(), which involves getting to the end 
+		 * of indefinte-length data.
+		 */
+	}
+	else {
+		errorLog0("CL_CertDecodeComponents: longjmp during decode\n");
+		TBSCert.reset();
+		algId.reset();
+		rawSig.reset();
+		CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+	}
+}
+
+/*
+ * Given pre-DER-encoded blobs, do the final encode step for a signed cert.
+ */
+void 
+CL_certEncodeComponents(
+	const CssmData		&TBSCert,		// DER-encoded
+	const CssmData		&algId,			// ditto
+	const CssmData		&rawSig,		// raw bits, not encoded
+	CssmOwnedData 		&signedCert)	// DER-encoded
+{
+	/* first BER-encode the signature */
+	AsnBits snaccSig(reinterpret_cast<char *>(rawSig.data()), 
+			rawSig.length() * 8);
+	CssmAutoData encodedSig(signedCert.allocator);
+	SC_encodeAsnObj(snaccSig, encodedSig, rawSig.length() + 10);
+	
+	/* 
+	 * OK, we have all three cert components already DER-encoded. The encoded
+	 * cert is just (tag | contentLength | TBSCert | algId | encodedSig). 
+	 * To avoid an unneccessary copy at the end of the encode, figure out
+	 * the length of tag and contentLength. The tag is known to be one byte. 
+	 */
+	size_t contentLen = TBSCert.length() + algId.length() + encodedSig.length();
+	size_t lenLen = SC_lengthOfLength(contentLen);
+	size_t totalLen = 1 /* tag */ + lenLen /* length bytes */ + contentLen;
+	signedCert.malloc(totalLen);
+	
+	/* tag */
+	char *cp = (char *)signedCert.data();
+	*cp++ = UNIV | CONS | SEQ_TAG_CODE;
+	
+	/* length */
+	SC_encodeLength(contentLen, cp, lenLen);
+	cp += lenLen;
+	
+	/* concatenate the existing components */
+	memcpy(cp, TBSCert.data(), TBSCert.length());
+	cp += TBSCert.length();
+	memcpy(cp, algId.data(), algId.length());
+	cp += algId.length();
+	memcpy(cp, encodedSig.data(), encodedSig.length());
+	CASSERT((cp + encodedSig.length()) == 
+		((char *)signedCert.data() + signedCert.length()));
+}
+
+/* malloc/copy a CsmmOid from a snacc-style AsnOid. */
+void CL_snaccOidToCssm(
+	const AsnOid 	&inOid,
+	CssmOid			&outOid,
+	CssmAllocator	&alloc)
+{
+	outOid.Data = (uint8 *)alloc.malloc(inOid.Len());
+	outOid.Length = inOid.Len();
+	const char *cp = inOid;
+	memcpy(outOid.Data, cp, outOid.Length);
+}
+
+/* convert algorithm identifier from CSSM format to snacc format */
+void CL_cssmAlgIdToSnacc (
+	const CSSM_X509_ALGORITHM_IDENTIFIER &cssmAlgId,
+	AlgorithmIdentifier &snaccAlgId)
+{
+	snaccAlgId.algorithm.Set(reinterpret_cast<char *>(
+		cssmAlgId.algorithm.Data), cssmAlgId.algorithm.Length);
+	if(cssmAlgId.parameters.Data != NULL) {
+		/* optional parameters, raw bytes */
+		/* FIXME - is that right? SHould we encode as a bit string?
+		 * I've never seen this "ANY" type field used... */
+		snaccAlgId.parameters = new AsnAny;
+		CSM_Buffer *cbuf = new CSM_Buffer(
+			reinterpret_cast<char *>(cssmAlgId.parameters.Data),
+				cssmAlgId.parameters.Length);
+		snaccAlgId.parameters->value = cbuf;
+	}
+	else {
+		CL_nullAlgParams(snaccAlgId);
+	}
+}
+
+/* convert algorithm indentifier from snacc format to CSSM format */
+void CL_snaccAlgIdToCssm (
+	const AlgorithmIdentifier 		&snaccAlgId,
+	CSSM_X509_ALGORITHM_IDENTIFIER	&cssmAlgId,
+	CssmAllocator					&alloc)
+{
+	memset(&cssmAlgId, 0, sizeof(CSSM_X509_ALGORITHM_IDENTIFIER));
+	
+	/* algorithm - required */
+	CssmOid &outOid = CssmOid::overlay(cssmAlgId.algorithm);
+	CL_snaccOidToCssm(snaccAlgId.algorithm, outOid, alloc);
+		
+	/* parameters as AsnAny - optional - for now just pass back the raw bytes */
+	if(snaccAlgId.parameters != NULL) {
+		CSM_Buffer *cbuf = snaccAlgId.parameters->value;
+		cssmAlgId.parameters.Data = (uint8 *)alloc.malloc(cbuf->Length());
+		cssmAlgId.parameters.Length = cbuf->Length();
+		memmove(cssmAlgId.parameters.Data, cbuf->Access(), 
+			cssmAlgId.parameters.Length);
+	}
+}
+
+/* convert between uint32-style CSSM algorithm and snacc-style AsnOid */
+CSSM_ALGORITHMS CL_snaccOidToCssmAlg(
+	const AsnOid &oid)
+{
+	AlgOidCache &oc = algOidCache();
+	
+	CSSM_ALGORITHMS cssmAlg = 0;
+	if(oid == oc.mRsaEncryption) {
+		cssmAlg = CSSM_ALGID_RSA;
+	}
+	else if(oid == oc.mMd2WithRSAEncryption) {
+		cssmAlg = CSSM_ALGID_MD2WithRSA;
+	}
+	else if(oid == oc.mMd5WithRSAEncryption) {
+		cssmAlg = CSSM_ALGID_MD5WithRSA;
+	}
+	else if(oid == oc.mSha1withRSAEncryption) {
+		cssmAlg = CSSM_ALGID_SHA1WithRSA;
+	}
+	else if(oid == oc.mId_dsa) {
+		cssmAlg = CSSM_ALGID_DSA;
+	}
+	else if(oid == oc.mId_dsa_with_sha1) {
+		cssmAlg = CSSM_ALGID_SHA1WithDSA;
+	}
+	else if(oid == oc.mAppleFee) {
+		cssmAlg = CSSM_ALGID_FEE;
+	}
+	else if(oid == oc.mAppleAsc) {
+		cssmAlg = CSSM_ALGID_ASC;
+	}
+	else if(oid == oc.mAppleFeeMD5) {
+		cssmAlg = CSSM_ALGID_FEE_MD5;
+	}
+	else if(oid == oc.mAppleFeeSHA1) {
+		cssmAlg = CSSM_ALGID_FEE_SHA1;
+	}
+	else if(oid == oc.mAppleFeed) {
+		cssmAlg = CSSM_ALGID_FEED;
+	}
+	else if(oid == oc.mAppleFeedExp) {
+		cssmAlg = CSSM_ALGID_FEEDEXP;
+	}
+	else if(oid == oc.mAppleECDSA) {
+		cssmAlg = CSSM_ALGID_SHA1WithECDSA;
+	}
+	/* etc. */
+	else {
+		errorLog0("snaccOidToCssmAlg: unknown alg\n");
+		#ifndef	NDEBUG
+		printf("Bogus OID: "); oid.Print(cout);
+		printf("\n");
+		#endif
+		CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+	}
+	return cssmAlg;
+}
+
+void CL_cssmAlgToSnaccOid(
+	CSSM_ALGORITHMS cssmAlg,
+	AsnOid &oid)
+{
+	switch(cssmAlg) {
+		case CSSM_ALGID_RSA:
+			oid.ReSet(rsaEncryption_arc);
+			break;
+		case CSSM_ALGID_MD2WithRSA:
+			oid.ReSet(md2WithRSAEncryption_arc);
+			break;
+		case CSSM_ALGID_MD5WithRSA:
+			oid.ReSet(md2WithRSAEncryption_arc);
+			break;
+		case CSSM_ALGID_SHA1WithRSA:
+			oid.ReSet(sha1withRSAEncryption_arc);
+			break;
+		case CSSM_ALGID_DSA:
+			oid.ReSet(id_dsa_arc);
+			break;
+		case CSSM_ALGID_SHA1WithDSA:
+			oid.ReSet(id_dsa_with_sha1_arc);
+			break;
+		case CSSM_ALGID_FEE:
+			oid.ReSet(appleFee_arc);
+			break;
+		case CSSM_ALGID_ASC:
+			oid.ReSet(appleAsc_arc);
+			break;
+		case CSSM_ALGID_FEE_MD5:
+			oid.ReSet(appleFeeMD5_arc);
+			break;
+		case CSSM_ALGID_FEE_SHA1:
+			oid.ReSet(appleFeeSHA1_arc);
+			break;
+		case CSSM_ALGID_FEED:
+			oid.ReSet(appleFeed_arc);
+			break;
+		case CSSM_ALGID_FEEDEXP:
+			oid.ReSet(appleFeedExp_arc);
+			break;
+		case CSSM_ALGID_SHA1WithECDSA:
+			oid.ReSet(appleECDSA_arc);
+			break;
+		/* etc. */
+		default:
+			errorLog1("cssmAlgToSnaccOid: unknown alg (%d)\n", (int)cssmAlg);
+			CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+	}
+}
+
+/* set up a encoded NULL for AlgorithmIdentifier.parameters */
+void CL_nullAlgParams(
+	AlgorithmIdentifier	&snaccAlgId)
+{
+	snaccAlgId.parameters = new AsnAny;
+	char encodedNull[2] = {NULLTYPE_TAG_CODE, 0};
+	CSM_Buffer *cbuf = new CSM_Buffer(encodedNull, 2);
+	snaccAlgId.parameters->value = cbuf;
+}
+
+/* AsnOcts --> CSSM_DATA */
+void CL_AsnOctsToCssmData(
+	const AsnOcts 	&octs,
+	CSSM_DATA		&cdata,
+	CssmAllocator	&alloc)
+{
+	const char *cp = octs;
+	CssmAutoData aData(alloc, (uint8 *)cp, octs.Len());
+	cdata = aData.release();
+}
+
+#define MAX_NAME_SIZE	(4 * 1024)
+
+/* snacc-style GeneralNames --> CE_GeneralNames */
+/* GeneralNames from sm_x509cmn.h */
+void CL_snaccGeneralNamesToCdsa(
+	GeneralNames &snaccObj,
+	CE_GeneralNames &cdsaObj,
+	CssmAllocator &alloc)
+{
+	cdsaObj.numNames = snaccObj.Count();
+	if(cdsaObj.numNames == 0) {
+		cdsaObj.generalName = NULL;
+		return;
+	}
+	cdsaObj.generalName = (CE_GeneralName *)alloc.malloc(
+		cdsaObj.numNames * sizeof(CE_GeneralName));
+	snaccObj.SetCurrToFirst();
+	CssmAutoData aData(alloc);
+	for(unsigned i=0; i<cdsaObj.numNames; i++) {
+		CE_GeneralName *currCdsaName = &cdsaObj.generalName[i];
+		GeneralName *currSnaccName = snaccObj.Curr();
+		
+		/* just take the simple ones for now */
+		char *src = NULL;
+		unsigned len = 0;
+		AsnType *toBeEncoded = NULL;
+		switch(currSnaccName->choiceId) {
+			case GeneralName::otherNameCid:
+				/* OTHER_NAME, AsnOid */
+				currCdsaName->nameType = GNT_OtherName;
+				src = *currSnaccName->otherName;
+				len = currSnaccName->otherName->Len();
+				break;
+			case GeneralName::rfc822NameCid:
+				/* IA5String, AsnOcts */
+				currCdsaName->nameType = GNT_RFC822Name;
+				src = *currSnaccName->rfc822Name;
+				len = currSnaccName->rfc822Name->Len();
+				break;
+			case GeneralName::dNSNameCid:
+				/* IA5String, AsnOcts */
+				currCdsaName->nameType = GNT_DNSName;
+				src = *currSnaccName->dNSName;
+				len = currSnaccName->dNSName->Len();
+				break;
+			case GeneralName::x400AddressCid:
+				/* ORAddress from sm_x411mtsas */
+				currCdsaName->nameType = GNT_X400Address;
+				toBeEncoded = currSnaccName->x400Address;
+				break;
+			case GeneralName::directoryNameCid:
+				/* Name from sm_x501if */
+				/* We actually have to to deal with this in CertFields.cpp;
+				 * it'll be easy to support this (with a mod to 
+				 * CE_GeneralName).
+				 */
+				currCdsaName->nameType = GNT_DirectoryName;
+				toBeEncoded = currSnaccName->directoryName;
+				break;
+			case GeneralName::ediPartyNameCid:
+				/* EDIPartyName from sm_x509cmn */
+				currCdsaName->nameType = GNT_EdiPartyName;
+				toBeEncoded = currSnaccName->ediPartyName;
+				break;
+			case GeneralName::uniformResourceIdentifierCid:
+				/* IA5String, AsnOcts */
+				currCdsaName->nameType = GNT_URI;
+				src = *currSnaccName->uniformResourceIdentifier;
+				len = currSnaccName->uniformResourceIdentifier->Len();
+				break;
+			case GeneralName::iPAddressCid:
+				/* AsnOcts */
+				currCdsaName->nameType = GNT_IPAddress;
+				src = *currSnaccName->iPAddress;
+				len = currSnaccName->iPAddress->Len();
+				break;
+			case GeneralName::registeredIDCid:
+				/* AsnOid */
+				currCdsaName->nameType = GNT_RegisteredID;
+				src = *currSnaccName->registeredID;
+				len = currSnaccName->registeredID->Len();
+				break;
+		}
+		if(src == NULL) {
+			/* punt - encode the complex object and give caller the encoded
+			 * bytes */
+			CASSERT(toBeEncoded != NULL);
+			SC_encodeAsnObj(*toBeEncoded, aData, MAX_NAME_SIZE);
+			src = aData;
+			len = aData.length();
+			aData.release();
+			currCdsaName->berEncoded = CSSM_TRUE;
+		}
+		else {
+			CASSERT(toBeEncoded == NULL);
+			currCdsaName->berEncoded = CSSM_FALSE;
+		}
+		
+		/* src --> currCdsaName->name */
+		currCdsaName->name.Data = (uint8 *)alloc.malloc(len);
+		currCdsaName->name.Length = len;
+		memmove(currCdsaName->name.Data, src, len);
+		
+		snaccObj.GoNext();
+	}
+}
+
+/* CE_GeneralNames --> snacc-style GeneralNames */
+/* GeneralNames from sm_x509cmn.h */
+GeneralNames *CL_cdsaGeneralNamesToSnacc(
+	CE_GeneralNames &cdsaObj)
+{
+	GeneralNames *snaccObj = new GeneralNames;
+	bool abortFlag = false;		// true --> invalid incoming field 
+	CssmAllocator &alloc = CssmAllocator::standard();
+	
+	for(unsigned i=0; i<cdsaObj.numNames; i++) {
+		CE_GeneralName *currCdsaName = &cdsaObj.generalName[i];
+		char *rawData = reinterpret_cast<char *>(currCdsaName->name.Data);
+		unsigned rawDataLen = currCdsaName->name.Length;
+		GeneralName *currSnaccName = snaccObj->Append();
+		CssmData &berCdata = CssmData::overlay(currCdsaName->name);
+		CssmRemoteData berData(alloc, berCdata);
+		switch(currCdsaName->nameType) {
+			case GNT_OtherName:
+				/* OTHER_NAME, AsnOid */
+				if(currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::otherNameCid;
+				currSnaccName->otherName = new AsnOid(rawData, rawDataLen);
+				break;
+
+			case GNT_RFC822Name:
+				/* IA5String */
+				if(currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::rfc822NameCid;
+				currSnaccName->rfc822Name = new IA5String(rawData, rawDataLen);
+				break;
+			case GNT_DNSName:
+				/* IA5String */
+				if(currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::dNSNameCid;
+				currSnaccName->rfc822Name = new IA5String(rawData, rawDataLen);	
+				break;
+			
+			case GNT_X400Address:
+				/* ORAddress from sm_x411mtsas */
+				if(!currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::x400AddressCid;
+				currSnaccName->x400Address = new ORAddress;
+				try {
+					SC_decodeAsnObj(berData, *currSnaccName->x400Address);
+				}
+				catch(...) {
+					abortFlag = true;
+				}
+				break;
+			case GNT_DirectoryName:
+				/* Name from sm_x501if */
+				/* We actually have to to deal with this in CertFields.cpp;
+				 * it'll be easy to support this (with a mod to 
+				 * CE_GeneralName).
+				 */
+				if(!currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::directoryNameCid;
+				currSnaccName->directoryName = new Name;
+				try {
+					SC_decodeAsnObj(berData, *currSnaccName->directoryName);
+				}
+				catch(...) {
+					abortFlag = true;
+				}
+				break;
+				
+			case GNT_EdiPartyName:
+				/* EDIPartyName from sm_x509cmn */
+				if(!currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::ediPartyNameCid;
+				currSnaccName->ediPartyName = new EDIPartyName;
+				try {
+					SC_decodeAsnObj(berData, *currSnaccName->ediPartyName);
+				}
+				catch(...) {
+					abortFlag = true;
+				}
+				break;
+
+			case GNT_URI:
+				/* IA5String */
+				if(currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::uniformResourceIdentifierCid;
+				currSnaccName->uniformResourceIdentifier = 
+					new IA5String(rawData, rawDataLen);
+				break;
+
+			case GNT_IPAddress:
+				/* AsnOcts */
+				if(currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::iPAddressCid;
+				currSnaccName->iPAddress = new AsnOcts(rawData, rawDataLen);
+				break;
+			case GNT_RegisteredID:
+				/* AsnOid */
+				if(currCdsaName->berEncoded) {
+					abortFlag = true;
+					break;
+				}
+				currSnaccName->choiceId = GeneralName::registeredIDCid;
+				currSnaccName->registeredID = new AsnOid(rawData, rawDataLen);
+				break;
+		}
+		berData.release();
+		if(abortFlag) {
+			break;
+		}
+	}
+	if(abortFlag) {
+		delete snaccObj;
+		CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
+	}
+	return snaccObj;
+}
+
+void CL_normalizeString(
+	char *strPtr,
+	int &strLen)
+{
+	char *pCh = strPtr;				// working ptr
+	char *pD = pCh;					// start of good string chars
+	char *pEos = pCh + strLen - 1;
+	
+	if(strLen == 0) {
+		return;
+	}
+
+	/* adjust if Length included NULL terminator */
+	while(*pEos == 0) {
+		pEos--;
+	}
+	
+	/* Remove trailing spaces */
+	while(isspace(*pEos)) {
+		pEos--;
+	}
+	
+	/* Point to one past last non-space character */
+	pEos++;
+
+	/* upper case */
+	while(pCh < pEos) {
+		*pCh++ = toupper(*pCh);
+	}
+	
+	/* clean out whitespace */
+	/* 
+	 * 1. skip all leading whitespace 
+	 */
+	pCh = pD;
+	while(isspace(*pCh) && (pCh < pEos)) {
+		pCh++;
+	}
+	
+	/*
+	 * 2. eliminate multiple whitespace.
+	 *    pCh points to first non-white char.
+	 *	  pD still points to start of string
+	 */
+	char ch;
+	while(pCh < pEos) {
+		ch = *pCh++;
+		*pD++ = ch;		// normal case
+		if( isspace(ch) ){
+			/* skip 'til next nonwhite */
+			while(isspace(*pCh) && (pCh < pEos)) {
+				pCh++;
+			}
+		}
+	};
+
+	strLen = pD - strPtr;
+}
+
+/* 
+ * Normalize an RDN. Per RFC2459 (4.1.2.4), printable strings are case 
+ * insensitive and we're supposed to ignore leading and trailing 
+ * whitespace, and collapse multiple whitespace characters into one. 
+ */
+void CL_normalizeX509Name(
+	Name &name,
+	CssmAllocator &alloc)
+{
+	RDNSequence *rdns = name.rDNSequence;
+	int numRdns = rdns->Count();
+	if((rdns == NULL) || (numRdns == 0)) {
+		/* not technically an error */
+		return;
+	}
+	
+	rdns->SetCurrElmt(0);
+	for(int rdnDex=0; rdnDex<numRdns; rdnDex++) {
+		/* from sm_x501if */
+		RelativeDistinguishedName *rdn = rdns->Curr();
+		if(rdn == NULL) {
+			/* not sure how this can happen... */
+			dprintf1("clNormalizeX509Name: NULL rdn at index %d\n", rdnDex);
+			rdns->GoNext();	
+			continue;
+		}
+		int numAttrs = rdn->Count();
+		if(numAttrs == 0) {
+			dprintf1("clNormalizeX509Name: zero numAttrs at index %d\n", rdnDex);
+			rdns->GoNext();		
+			continue;
+		}
+		
+		/* descend into array of attribute/values */
+		rdn->SetCurrElmt(0);
+		for(int attrDex=0; attrDex<numAttrs; attrDex++) {
+			/* from sm_x501if */
+			AttributeTypeAndDistinguishedValue *att = rdn->Curr();
+			if(att == NULL) {
+				/* not sure how this can happen... */
+				dprintf1("clNormalizeX509Name: NULL att at index %d\n", attrDex);
+				rdn->GoNext();
+				continue;
+			}
+			
+			/* 
+			 * att->value is an AsnAny (CSM_Buffer) containing an encoded
+			 * string - supposedly a DirectoryString, but some certs put an
+			 * IA5String here which is not handled by DirectoryString.
+			 *
+			 * (See e.g. the Thawte serverbasic cert, which has an email 
+			 * address in IA5String format.) In the IA5String case we skip the
+			 * normalization.
+			 *
+			 * Anyway, figure out what's there, snag the raw string, normalize the 
+			 * string, cook up an appropriate DirectoryString for it, encode the
+			 * result, and put the encoding back in att->value.
+			 */
+			CSM_Buffer				*cbuf = att->value.value;
+			DirectoryString			dirStr;
+			char 					*cbufData = const_cast<char *>(cbuf->Access());
+			CssmData				encodedStr(cbufData, cbuf->Length());
+			
+			/* avoid exception if this is an IA5String... */
+			char tagByte = cbufData[0];
+			if((tagByte == (UNIV | PRIM | IA5STRING_TAG_CODE)) ||
+			   (tagByte == (UNIV | CONS | IA5STRING_TAG_CODE))) {
+				/* can't normalize */
+				return;
+			}
+			try {
+				SC_decodeAsnObj(encodedStr, dirStr);
+			}
+			catch (...) {
+				/* can't normalize */
+				errorLog0("clNormalizeX509Name: malformed DirectoryString (1)\n");
+				return;
+			} 
+
+			/* normalize, we don't need to know what kind of string it is */
+			char *strPtr = *dirStr.teletexString;
+			int newLen = dirStr.teletexString->Len();
+			CL_normalizeString(strPtr, newLen);
+			
+			/* set new AsnOcts data from normalized version, freeing old */
+			dirStr.teletexString->ReSet(strPtr, newLen);
+			
+			/* encode result */
+			CssmAutoData normEncoded(alloc);
+			SC_encodeAsnObj(dirStr, normEncoded, newLen + 8);
+			
+			/* set new AsnAny data */
+			cbuf->Set((char *)normEncoded.data(), normEncoded.length());
+			
+			rdn->GoNext();
+		}	/* for each attribute/value */
+	rdns->GoNext();
+	}		/* for each RDN */
+}
+
+
diff --git a/AppleX509CL/SnaccUtils.h b/AppleX509CL/SnaccUtils.h
new file mode 100644
index 00000000..5893cea8
--- /dev/null
+++ b/AppleX509CL/SnaccUtils.h
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * SnaccUtils.h - snacc-related cert functions
+ *
+ * Created 9/1/2000 by Doug Mitchell. 
+ * Copyright (c) 2000 by Apple Computer. 
+ */
+ 
+#ifndef	_SNACC_UTILS_H_
+#define _SNACC_UTILS_H_
+
+#include <Security/cssmtype.h>
+#include <Security/x509defs.h>
+#include <Security/certextensions.h>
+#include <Security/cssmdata.h>
+
+/* ghastly requirements of snacc-generated cert code */
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+#include <Security/sm_x501if.h>
+#include <Security/sm_x520sa.h>
+#include <Security/sm_x411mtsas.h>
+#include <Security/sm_x509cmn.h>
+#include <Security/sm_x509af.h>
+#include <Security/pkcs9oids.h>
+#include <Security/sm_x509ce.h>
+#include <Security/sm_cms.h>
+#include <Security/sm_ess.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void 
+CL_certDecodeComponents(
+	const CssmData 	&signedCert,		// DER-encoded
+	CssmOwnedData	&TBSCert,			// still DER-encoded
+	CssmOwnedData	&algId,				// ditto
+	CssmOwnedData	&sig);				// ditto
+
+void 
+CL_certEncodeComponents(
+	const CssmData		&TBSCert,		// DER-encoded
+	const CssmData		&algId,			// ditto
+	const CssmData		&rawSig,		// the raw bits, not encoded
+	CssmOwnedData 		&signedCert);	// DER-encoded
+
+void CL_snaccOidToCssm(
+	const AsnOid 		&inOid,
+	CssmOid				&outOid,
+	CssmAllocator		&alloc);
+
+/* convert algorithm identifier between CSSM and snacc formats */
+void CL_cssmAlgIdToSnacc (
+	const CSSM_X509_ALGORITHM_IDENTIFIER &cssmAlgId,
+	AlgorithmIdentifier 			&snaccAlgId);
+
+void CL_snaccAlgIdToCssm (
+	const AlgorithmIdentifier 		&snaccAlgId,
+	CSSM_X509_ALGORITHM_IDENTIFIER	&cssmAlgId,
+	CssmAllocator					&alloc);
+
+/* convert between uint32-style CSSM algorithm and snacc-style AsnOid */
+CSSM_ALGORITHMS CL_snaccOidToCssmAlg(
+	const AsnOid 					&oid);
+
+void CL_cssmAlgToSnaccOid(
+	CSSM_ALGORITHMS 				cssmAlg,
+	AsnOid 							&oid);
+
+/* set up a encoded NULL for AlgorithmIdentifier.parameters */
+void CL_nullAlgParams(
+	AlgorithmIdentifier				&snaccAlgId);
+
+/* AsnOcts --> CSSM_DATA */
+void CL_AsnOctsToCssmData(
+	const AsnOcts 					&octs,
+	CSSM_DATA						&cdata,
+	CssmAllocator					&alloc);
+
+/* snacc-style GeneralNames --> CE_GeneralNames */
+/* GeneralNames from sm_x509cmn.h */
+void CL_snaccGeneralNamesToCdsa(
+	GeneralNames &snaccObj,
+	CE_GeneralNames &cdsaObj,
+	CssmAllocator &alloc);
+
+/* CE_GeneralNames --> snacc-style GeneralNames */
+GeneralNames *CL_cdsaGeneralNamesToSnacc(
+	CE_GeneralNames 				&cdsaObj);
+
+#define MAX_RDN_SIZE	(4 * 1024)
+
+void CL_normalizeString(
+	char 			*strPtr,
+	int 			&strLen);
+void CL_normalizeX509Name(
+	Name 			&name,
+	CssmAllocator 	&alloc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SNACC_UTILS_H_ */
+
diff --git a/AppleX509CL/TODO b/AppleX509CL/TODO
new file mode 100644
index 00000000..de81bb21
--- /dev/null
+++ b/AppleX509CL/TODO
@@ -0,0 +1 @@
+Things TODO in AppleX509CL
diff --git a/AppleX509CL/cldebugging.c b/AppleX509CL/cldebugging.c
new file mode 100644
index 00000000..2cf9653f
--- /dev/null
+++ b/AppleX509CL/cldebugging.c
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cldebugging.c
+
+	Contains:	Debugging support.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		03/10/98	dpm		Created.
+
+*/
+
+#include "cldebugging.h"
+
+#if		!LOG_VIA_PRINTF
+
+#include <string.h>
+#include <CarbonCore/MacTypes.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* this one needs a writable string */
+static void logCom(unsigned char *str) {
+	c2pstr((char *)str);
+	DebugStr(str);
+}
+
+/* remaining ones can take constant strings */
+void dblog0(char *str)	{
+	Str255	outStr;
+	strcpy((char *)outStr, str);
+	logCom(outStr);
+}
+
+void dblog1(char *str, void *arg1)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1);
+	logCom(outStr);
+}
+
+void dblog2(char *str, void * arg1, void * arg2)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2);
+	logCom(outStr);
+}
+
+void dblog3(char *str, void * arg1, void * arg2, void * arg3)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2, arg3);
+	logCom(outStr);
+}
+
+void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2, arg3, arg4);
+	logCom(outStr);
+}
+
+#endif	/* !LOG_VIA_PRINTF */
+
+#if	DEBUG_ENABLE
+volatile void _panic(const char *str)
+{
+	printf(str);
+	exit(1);
+}
+#endif
+
+//int foobarSymbol;
diff --git a/AppleX509CL/cldebugging.h b/AppleX509CL/cldebugging.h
new file mode 100644
index 00000000..f7342aff
--- /dev/null
+++ b/AppleX509CL/cldebugging.h
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cldebugging.h
+
+	Contains:	Debugging macros.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		06/02/98	dpm		Added DEBUG_THREAD_YIELD.
+		03/10/98	dpm		Created.
+
+*/
+
+#ifndef	_CLDEBUGGING_H_
+#define _CLDEBUGGING_H_
+
+#ifdef	NDEBUG
+#define DEBUG_ENABLE		0
+#define ERROR_LOG_ENABLE	0
+#else
+#define DEBUG_ENABLE		1
+#define ERROR_LOG_ENABLE	1
+#endif
+
+/* any other way? */
+#define LOG_VIA_PRINTF		1
+
+#if		DEBUG_ENABLE || ERROR_LOG_ENABLE
+
+#include <stdio.h>
+
+#if		!LOG_VIA_PRINTF
+
+#error Hey, figure out a debug mechanism
+
+#include <string.h>
+#include <CarbonCore/MacTypes.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* remaining ones can take constant strings */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern void dblog0(char *str);
+extern void dblog1(char *str, void * arg1);
+extern void dblog2(char *str, void * arg1, void * arg2);
+extern void dblog3(char *str, void * arg1, void * arg2, void * arg3);
+extern void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4);
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#else	/* LOG_VIA_PRINTF */
+
+#define dblog0(str)								printf(str)
+#define dblog1(str, arg1)						printf(str, arg1)
+#define dblog2(str, arg1, arg2)					printf(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)			printf(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)		printf(str, arg1, arg2, arg3, arg4)
+
+#endif	/* LOG_VIA_PRINTF */
+
+#else	/* log macros disabled */
+
+#define dblog0(str)
+#define dblog1(str, arg1)
+#define dblog2(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* DEBUG_ENABLE || ERROR_LOG_ENABLE */
+
+#if	DEBUG_ENABLE
+
+#define dprintf0(str)								dblog0(str)
+#define dprintf1(str, arg1)							dblog1(str, arg1)
+#define dprintf2(str, arg1, arg2)					dblog2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)				dblog3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)		dblog4(str, arg1, arg2, arg3,  arg4)
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern volatile void _panic(const char *str);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#define CASSERT(expression) 							\
+  ((expression) ? (void)0 : 							\
+   (dprintf1 ("Assertion failed: " #expression 			\
+      ", file " __FILE__ ", line %d.\n", __LINE__), 	\
+    _panic("Assertion Failure")))
+
+#else	/* DEBUG_ENABLE */
+
+#define dprintf0(str)
+#define dprintf1(str, arg1)
+#define dprintf2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)
+
+#define CASSERT(expression)
+
+#endif	/* DEBUG_ENABLE */
+
+/*
+ * Error logging. This may well be platform dependent.
+ */
+#if		ERROR_LOG_ENABLE
+#define errorLog0(str)								dblog0(str)
+#define errorLog1(str, arg1)						dblog1(str, arg1)
+#define errorLog2(str, arg1, arg2)					dblog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)			dblog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)		dblog4(str, arg1, arg2, arg3, arg4)
+
+#else	/* ERROR_LOG_ENABLE */
+
+#define errorLog0(str)
+#define errorLog1(str, arg1)
+#define errorLog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* ERROR_LOG_ENABLE */
+
+#endif	/* _CLDEBUGGING_H_ */
diff --git a/AppleX509CL/cssmplugin.exp b/AppleX509CL/cssmplugin.exp
new file mode 100644
index 00000000..f5046fbf
--- /dev/null
+++ b/AppleX509CL/cssmplugin.exp
@@ -0,0 +1,4 @@
+_CSSM_SPI_ModuleLoad
+_CSSM_SPI_ModuleAttach
+_CSSM_SPI_ModuleDetach
+_CSSM_SPI_ModuleUnload
diff --git a/AppleX509TP/AppleTP.cpp b/AppleX509TP/AppleTP.cpp
new file mode 100644
index 00000000..6bd8977b
--- /dev/null
+++ b/AppleX509TP/AppleTP.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleTP.cpp 
+//
+#include "AppleTP.h"
+#include "AppleTPSession.h"
+
+
+//
+// Make and break the plugin object
+//
+AppleTP::AppleTP()
+{
+}
+
+AppleTP::~AppleTP()
+{
+}
+
+
+//
+// Create a new plugin session, our way
+//
+PluginSession *AppleTP::makeSession(
+	CSSM_MODULE_HANDLE handle,
+	const CSSM_VERSION &version,
+	uint32 subserviceId,
+	CSSM_SERVICE_TYPE subserviceType,
+	CSSM_ATTACH_FLAGS attachFlags,
+	const CSSM_UPCALLS &upcalls)
+{
+    switch (subserviceType) {
+        case CSSM_SERVICE_TP:
+            return new AppleTPSession(handle,
+                                       *this,
+                                       version,
+                                       subserviceId,
+                                       subserviceType,
+                                       attachFlags,
+                                       upcalls);
+        default:
+            CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
+            return 0;	// placebo
+    }
+}
diff --git a/AppleX509TP/AppleTP.h b/AppleX509TP/AppleTP.h
new file mode 100644
index 00000000..80c7a224
--- /dev/null
+++ b/AppleX509TP/AppleTP.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+
+//
+// AppleTP.h - TP module for X509, SSL, iSign
+//
+#ifndef _H_APPLETP
+#define _H_APPLETP
+
+#include <Security/cssmplugin.h>
+#include <Security/pluginsession.h>
+
+class AppleTP : public CssmPlugin
+{
+public:
+    AppleTP();
+    ~AppleTP();
+
+    PluginSession *makeSession(
+			CSSM_MODULE_HANDLE handle,
+			const CSSM_VERSION &version,
+			uint32 subserviceId,
+			CSSM_SERVICE_TYPE subserviceType,
+			CSSM_ATTACH_FLAGS attachFlags,
+			const CSSM_UPCALLS &upcalls);
+private:
+    // Don't copy AppleTP
+    AppleTP(const AppleTP&);
+    void operator=(const AppleTP&);
+};
+
+
+#endif //_H_APPLETP
diff --git a/AppleX509TP/AppleTP.pbproj/project.pbxproj b/AppleX509TP/AppleTP.pbproj/project.pbxproj
new file mode 100644
index 00000000..d354edcf
--- /dev/null
+++ b/AppleX509TP/AppleTP.pbproj/project.pbxproj
@@ -0,0 +1,445 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 32;
+	objects = {
+		00E007DFFF9267D6D0A17CE7 = {
+			isa = PBXFileReference;
+			path = certGroupUtils.cpp;
+			refType = 4;
+		};
+		00E007E0FF9267D6D0A17CE7 = {
+			isa = PBXFileReference;
+			path = certGroupUtils.h;
+			refType = 4;
+		};
+		00E007E1FF9267D6D0A17CE7 = {
+			isa = PBXFileReference;
+			path = iSignRootCerts.c;
+			refType = 4;
+		};
+		00E007E2FF9267D6D0A17CE7 = {
+			isa = PBXFileReference;
+			path = rootCerts.h;
+			refType = 4;
+		};
+		00E007E3FF9267D6D0A17CE7 = {
+			isa = PBXFileReference;
+			path = tpPolicies.cpp;
+			refType = 4;
+		};
+		00E007E4FF9267D6D0A17CE7 = {
+			isa = PBXFileReference;
+			path = tpPolicies.h;
+			refType = 4;
+		};
+		00E007E5FF9267D6D0A17CE7 = {
+			fileRef = 00E007E0FF9267D6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		00E007E6FF9267D6D0A17CE7 = {
+			fileRef = 00E007E2FF9267D6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		00E007E7FF9267D6D0A17CE7 = {
+			fileRef = 00E007E4FF9267D6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		00E007E8FF9267D6D0A17CE7 = {
+			fileRef = 00E007DFFF9267D6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00E007E9FF9267D6D0A17CE7 = {
+			fileRef = 00E007E1FF9267D6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00E007EAFF9267D6D0A17CE7 = {
+			fileRef = 00E007E3FF9267D6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00E007EBFF926B7BD0A17CE7 = {
+			isa = PBXFileReference;
+			path = debugging.c;
+			refType = 4;
+		};
+		00E007ECFF926B7BD0A17CE7 = {
+			isa = PBXFileReference;
+			path = debugging.h;
+			refType = 4;
+		};
+		00E007EDFF926B7BD0A17CE7 = {
+			fileRef = 00E007ECFF926B7BD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		00E007EEFF926B7BD0A17CE7 = {
+			fileRef = 00E007EBFF926B7BD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		00E007EFFF937BBCD0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslRootCerts.c;
+			refType = 4;
+		};
+		00E007F0FF937BBCD0A17CE7 = {
+			fileRef = 00E007EFFF937BBCD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		023E3601001F8E2511CD283A = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OTHER_LDFLAGS = "\U0001-dylib_file \"$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Security:$(SYMROOT)/Security.framework/Versions/A/Security\"";
+			};
+			isa = PBXBuildStyle;
+			name = "Build Folder";
+		};
+		02B529DEFF8D3AA7D0A17CE7 = {
+			buildStyles = (
+				1C9129D8FFD8585E11CD296C,
+				1C9129D9FFD8585E11CD296C,
+				023E3601001F8E2511CD283A,
+			);
+			isa = PBXProject;
+			mainGroup = 02B529DFFF8D3AA7D0A17CE7;
+			productRefGroup = 02B529E0FF8D3AFDD0A17CE7;
+			projectDirPath = .;
+			targets = (
+				02B529E3FF8D3AFDD0A17CE7,
+			);
+		};
+		02B529DFFF8D3AA7D0A17CE7 = {
+			children = (
+				02B529EDFF8D3DB1D0A17CE7,
+				02B529EBFF8D3D43D0A17CE7,
+				02B529EFFF8D3E0AD0A17CE7,
+				02B529E9FF8D3C09D0A17CE7,
+				00E007DFFF9267D6D0A17CE7,
+				00E007E0FF9267D6D0A17CE7,
+				00E007EBFF926B7BD0A17CE7,
+				00E007ECFF926B7BD0A17CE7,
+				00E007E1FF9267D6D0A17CE7,
+				00E007E2FF9267D6D0A17CE7,
+				00E007EFFF937BBCD0A17CE7,
+				02B529F8FF8D458FD0A17CE7,
+				5F314875FFA4B878D0A17CE7,
+				5F314873FFA4B3D9D0A17CE7,
+				00E007E3FF9267D6D0A17CE7,
+				00E007E4FF9267D6D0A17CE7,
+				0B9ABCAFFF9395CDD0A17CE7,
+				0B9ABCB1FF9396DDD0A17CE7,
+				35D41EC9FFF3E99811CD283A,
+				02B529E0FF8D3AFDD0A17CE7,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		02B529E0FF8D3AFDD0A17CE7 = {
+			children = (
+				1C9129D7FFD8585E11CD296C,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		02B529E3FF8D3AFDD0A17CE7 = {
+			buildPhases = (
+				02B529E4FF8D3AFDD0A17CE7,
+				02B529E5FF8D3AFDD0A17CE7,
+				02B529E6FF8D3AFDD0A17CE7,
+				02B529E7FF8D3AFDD0A17CE7,
+				02B529E8FF8D3AFDD0A17CE7,
+			);
+			buildSettings = {
+				DEPLOYMENT_OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				EXPORTED_SYMBOLS_FILE = cssmplugin.exp;
+				FRAMEWORK_SEARCH_PATHS = "";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security";
+				OPTIMIZATION_CFLAGS = "-O2 -fno-inline";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-bundle -undefined suppress -lstdc++";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleX509TP;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas  -Wno-format";
+				WRAPPER_EXTENSION = bundle;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXBundleTarget;
+			name = AppleTP;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Security";
+			productName = AppleX509TP;
+			productReference = 1C9129D7FFD8585E11CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AppleX509TP</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.applex509tp</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>AppleX509TP</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>AppleX509TP 1.0</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		02B529E4FF8D3AFDD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				02B529EAFF8D3C09D0A17CE7,
+				02B529ECFF8D3D43D0A17CE7,
+				00E007E5FF9267D6D0A17CE7,
+				00E007E6FF9267D6D0A17CE7,
+				00E007E7FF9267D6D0A17CE7,
+				00E007EDFF926B7BD0A17CE7,
+				0B9ABCB2FF9396DDD0A17CE7,
+				5F314874FFA4B3D9D0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		02B529E5FF8D3AFDD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		02B529E6FF8D3AFDD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				02B529EEFF8D3DB1D0A17CE7,
+				02B529F0FF8D3E0AD0A17CE7,
+				02B529F9FF8D458FD0A17CE7,
+				00E007E8FF9267D6D0A17CE7,
+				00E007E9FF9267D6D0A17CE7,
+				00E007EAFF9267D6D0A17CE7,
+				00E007EEFF926B7BD0A17CE7,
+				00E007F0FF937BBCD0A17CE7,
+				0B9ABCB0FF9395CDD0A17CE7,
+				5F314876FFA4B878D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		02B529E7FF8D3AFDD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				35D41ECBFFF3E99811CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		02B529E8FF8D3AFDD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		02B529E9FF8D3C09D0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleTPSession.h;
+			refType = 4;
+		};
+		02B529EAFF8D3C09D0A17CE7 = {
+			fileRef = 02B529E9FF8D3C09D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		02B529EBFF8D3D43D0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleTP.h;
+			refType = 4;
+		};
+		02B529ECFF8D3D43D0A17CE7 = {
+			fileRef = 02B529EBFF8D3D43D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		02B529EDFF8D3DB1D0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleTP.cpp;
+			refType = 4;
+		};
+		02B529EEFF8D3DB1D0A17CE7 = {
+			fileRef = 02B529EDFF8D3DB1D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		02B529EFFF8D3E0AD0A17CE7 = {
+			isa = PBXFileReference;
+			path = AppleTPSession.cpp;
+			refType = 4;
+		};
+		02B529F0FF8D3E0AD0A17CE7 = {
+			fileRef = 02B529EFFF8D3E0AD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		02B529F8FF8D458FD0A17CE7 = {
+			isa = PBXFileReference;
+			path = tpCertGroup.cpp;
+			refType = 4;
+		};
+		02B529F9FF8D458FD0A17CE7 = {
+			fileRef = 02B529F8FF8D458FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0B9ABCAFFF9395CDD0A17CE7 = {
+			isa = PBXFileReference;
+			path = tpTime.c;
+			refType = 4;
+		};
+		0B9ABCB0FF9395CDD0A17CE7 = {
+			fileRef = 0B9ABCAFFF9395CDD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0B9ABCB1FF9396DDD0A17CE7 = {
+			isa = PBXFileReference;
+			path = tpTime.h;
+			refType = 4;
+		};
+		0B9ABCB2FF9396DDD0A17CE7 = {
+			fileRef = 0B9ABCB1FF9396DDD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1C9129D7FFD8585E11CD296C = {
+			isa = PBXBundleReference;
+			path = AppleX509TP.bundle;
+			refType = 3;
+		};
+		1C9129D8FFD8585E11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		1C9129D9FFD8585E11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		35D41EC9FFF3E99811CD283A = {
+			children = (
+				35D41ECAFFF3E99811CD283A,
+			);
+			isa = PBXGroup;
+			name = "External Frameworks";
+			path = ../Projects/SecurityX/AppleX509TP;
+			refType = 3;
+		};
+		35D41ECAFFF3E99811CD283A = {
+			isa = PBXFrameworkReference;
+			path = Security.framework;
+			refType = 3;
+		};
+		35D41ECBFFF3E99811CD283A = {
+			fileRef = 35D41ECAFFF3E99811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		5F314873FFA4B3D9D0A17CE7 = {
+			isa = PBXFileReference;
+			path = TPCertInfo.h;
+			refType = 4;
+		};
+		5F314874FFA4B3D9D0A17CE7 = {
+			fileRef = 5F314873FFA4B3D9D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		5F314875FFA4B878D0A17CE7 = {
+			isa = PBXFileReference;
+			path = TPCertInfo.cpp;
+			refType = 4;
+		};
+		5F314876FFA4B878D0A17CE7 = {
+			fileRef = 5F314875FFA4B878D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+	};
+	rootObject = 02B529DEFF8D3AA7D0A17CE7;
+}
diff --git a/AppleX509TP/AppleTPSession.cpp b/AppleX509TP/AppleTPSession.cpp
new file mode 100644
index 00000000..5b7cab29
--- /dev/null
+++ b/AppleX509TP/AppleTPSession.cpp
@@ -0,0 +1,243 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * AppleTPSession.cpp - general session support and (mostly) unimplemented functions
+ */
+
+#include "AppleTPSession.h"
+
+AppleTPSession::AppleTPSession(
+	CSSM_MODULE_HANDLE theHandle,
+	CssmPlugin &plug,
+	const CSSM_VERSION &version,
+	uint32 subserviceId,
+	CSSM_SERVICE_TYPE subserviceType,
+	CSSM_ATTACH_FLAGS attachFlags,
+	const CSSM_UPCALLS &upcalls)
+		: TPPluginSession(theHandle, plug, version, subserviceId, 
+							subserviceType,attachFlags, upcalls)
+{
+	/* TBD session stuff here...
+	mCspHand = CSSM_INVALID_HANDLE;
+	mCspDlHand = CSSM_INVALID_HANDLE;
+	...*/
+}
+
+AppleTPSession::~AppleTPSession()
+{
+	/* TBD 
+	if(mCspHand != CSSM_INVALID_HANDLE) {
+		CSSM_ModuleDetach(mCspHand); 
+	}
+	if(mCspDlHand != CSSM_INVALID_HANDLE) {
+		CSSM_ModuleDetach(mCspDlHand); 
+	}
+	*/
+}
+
+void AppleTPSession::CertCreateTemplate(CSSM_CL_HANDLE CLHandle,
+		uint32 NumberOfFields,
+		const CSSM_FIELD CertFields[],
+		CssmData &CertTemplate)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CrlVerify(CSSM_CL_HANDLE CLHandle,
+		CSSM_CSP_HANDLE CSPHandle,
+		const CSSM_ENCODED_CRL &CrlToBeVerified,
+		const CSSM_CERTGROUP &SignerCertGroup,
+		const CSSM_TP_VERIFY_CONTEXT &VerifyContext,
+		CSSM_TP_VERIFY_CONTEXT_RESULT &RevokerVerifyResult)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CertReclaimKey(const CSSM_CERTGROUP &CertGroup,
+		uint32 CertIndex,
+		CSSM_LONG_HANDLE KeyCacheHandle,
+		CSSM_CSP_HANDLE CSPHandle,
+		const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+/*** CertGroupVerify, CertGroupConstruct in TPCertGroup.cpp ***/
+
+void AppleTPSession::CertSign(CSSM_CL_HANDLE CLHandle,
+		CSSM_CC_HANDLE CCHandle,
+		const CssmData &CertTemplateToBeSigned,
+		const CSSM_CERTGROUP &SignerCertGroup,
+		const CSSM_TP_VERIFY_CONTEXT &SignerVerifyContext,
+		CSSM_TP_VERIFY_CONTEXT_RESULT &SignerVerifyResult,
+		CssmData &SignedCert)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::TupleGroupToCertGroup(CSSM_CL_HANDLE CLHandle,
+		const CSSM_TUPLEGROUP &TupleGroup,
+		CSSM_CERTGROUP_PTR &CertTemplates)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::ReceiveConfirmation(const CssmData &ReferenceIdentifier,
+		CSSM_TP_CONFIRM_RESPONSE_PTR &Responses,
+		sint32 &ElapsedTime)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::PassThrough(CSSM_CL_HANDLE CLHandle,
+		CSSM_CC_HANDLE CCHandle,
+		const CSSM_DL_DB_LIST *DBList,
+		uint32 PassThroughId,
+		const void *InputParams,
+		void **OutputParams)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CertRemoveFromCrlTemplate(CSSM_CL_HANDLE CLHandle,
+		CSSM_CSP_HANDLE CSPHandle,
+		const CssmData *OldCrlTemplate,
+		const CSSM_CERTGROUP &CertGroupToBeRemoved,
+		const CSSM_CERTGROUP &RevokerCertGroup,
+		const CSSM_TP_VERIFY_CONTEXT &RevokerVerifyContext,
+		CSSM_TP_VERIFY_CONTEXT_RESULT &RevokerVerifyResult,
+		CssmData &NewCrlTemplate)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CertRevoke(CSSM_CL_HANDLE CLHandle,
+		CSSM_CSP_HANDLE CSPHandle,
+		const CssmData *OldCrlTemplate,
+		const CSSM_CERTGROUP &CertGroupToBeRevoked,
+		const CSSM_CERTGROUP &RevokerCertGroup,
+		const CSSM_TP_VERIFY_CONTEXT &RevokerVerifyContext,
+		CSSM_TP_VERIFY_CONTEXT_RESULT &RevokerVerifyResult,
+		CSSM_TP_CERTCHANGE_REASON Reason,
+		CssmData &NewCrlTemplate)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CertReclaimAbort(CSSM_LONG_HANDLE KeyCacheHandle)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CrlCreateTemplate(CSSM_CL_HANDLE CLHandle,
+		uint32 NumberOfFields,
+		const CSSM_FIELD CrlFields[],
+		CssmData &NewCrlTemplate)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CertGroupToTupleGroup(CSSM_CL_HANDLE CLHandle,
+		const CSSM_CERTGROUP &CertGroup,
+		CSSM_TUPLEGROUP_PTR &TupleGroup)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::SubmitCredRequest(const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
+		CSSM_TP_AUTHORITY_REQUEST_TYPE RequestType,
+		const CSSM_TP_REQUEST_SET &RequestInput,
+		const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthContext,
+		sint32 &EstimatedTime,
+		CssmData &ReferenceIdentifier)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::FormRequest(const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
+		CSSM_TP_FORM_TYPE FormType,
+		CssmData &BlankForm)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CrlSign(CSSM_CL_HANDLE CLHandle,
+		CSSM_CC_HANDLE CCHandle,
+		const CSSM_ENCODED_CRL &CrlToBeSigned,
+		const CSSM_CERTGROUP &SignerCertGroup,
+		const CSSM_TP_VERIFY_CONTEXT &SignerVerifyContext,
+		CSSM_TP_VERIFY_CONTEXT_RESULT &SignerVerifyResult,
+		CssmData &SignedCrl)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CertGroupPrune(CSSM_CL_HANDLE CLHandle,
+		const CSSM_DL_DB_LIST &DBList,
+		const CSSM_CERTGROUP &OrderedCertGroup,
+		CSSM_CERTGROUP_PTR &PrunedCertGroup)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::ApplyCrlToDb(CSSM_CL_HANDLE CLHandle,
+		CSSM_CSP_HANDLE CSPHandle,
+		const CSSM_ENCODED_CRL &CrlToBeApplied,
+		const CSSM_CERTGROUP &SignerCertGroup,
+		const CSSM_TP_VERIFY_CONTEXT *ApplyCrlVerifyContext,
+		CSSM_TP_VERIFY_CONTEXT_RESULT &ApplyCrlVerifyResult)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::CertGetAllTemplateFields(CSSM_CL_HANDLE CLHandle,
+		const CssmData &CertTemplate,
+		uint32 &NumberOfFields,
+		CSSM_FIELD_PTR &CertFields)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::ConfirmCredResult(const CssmData &ReferenceIdentifier,
+		const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
+		const CSSM_TP_CONFIRM_RESPONSE &Responses,
+		const CSSM_TP_AUTHORITY_ID *PreferredAuthority)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::FormSubmit(CSSM_TP_FORM_TYPE FormType,
+		const CssmData &Form,
+		const CSSM_TP_AUTHORITY_ID *ClearanceAuthority,
+		const CSSM_TP_AUTHORITY_ID *RepresentedAuthority,
+		AccessCredentials *Credentials)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void AppleTPSession::RetrieveCredResult(const CssmData &ReferenceIdentifier,
+		const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
+		sint32 &EstimatedTime,
+		CSSM_BOOL &ConfirmationRequired,
+		CSSM_TP_RESULT_SET_PTR &RetrieveOutput)
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+
diff --git a/AppleX509TP/AppleTPSession.h b/AppleX509TP/AppleTPSession.h
new file mode 100644
index 00000000..ca2460a3
--- /dev/null
+++ b/AppleX509TP/AppleTPSession.h
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+
+
+/* 
+ * AppleTPSession.h - TP session functions.
+ * 
+ * Created 10/5/2000 by Doug Mitchell.
+ */
+ 
+#ifndef _H_APPLE_TP_SESSION
+#define _H_APPLE_TP_SESSION
+
+#include <Security/TPsession.h>
+#include "TPCertInfo.h"
+
+#define REALLOC_WORKAROUND	0
+#if 	REALLOC_WORKAROUND
+#include <string.h>
+#endif
+
+class AppleTPSession : public TPPluginSession {
+
+public:
+
+	AppleTPSession(
+		CSSM_MODULE_HANDLE theHandle,
+		CssmPlugin &plug,
+		const CSSM_VERSION &version,
+		uint32 subserviceId,
+		CSSM_SERVICE_TYPE subserviceType,
+		CSSM_ATTACH_FLAGS attachFlags,
+		const CSSM_UPCALLS &upcalls);
+
+	~AppleTPSession();
+	
+	#if		REALLOC_WORKAROUND
+	void *realloc(void *oldp, size_t size) {
+		void *newp = malloc(size);
+		memmove(newp, oldp, size);
+		free(oldp);
+		return newp;
+	}
+	#endif	/* REALLOC_WORKAROUND */
+
+	/* methods declared in TPabstractSession.h */
+	void CertCreateTemplate(CSSM_CL_HANDLE CLHandle,
+         uint32 NumberOfFields,
+         const CSSM_FIELD CertFields[],
+         CssmData &CertTemplate);
+	void CrlVerify(CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ENCODED_CRL &CrlToBeVerified,
+         const CSSM_CERTGROUP &SignerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT &VerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT &RevokerVerifyResult);
+	void CertReclaimKey(const CSSM_CERTGROUP &CertGroup,
+         uint32 CertIndex,
+         CSSM_LONG_HANDLE KeyCacheHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry);
+	void CertGroupVerify(CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_CERTGROUP &CertGroupToBeVerified,
+         const CSSM_TP_VERIFY_CONTEXT *VerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR VerifyContextResult);
+	void CertGroupConstruct(CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_DL_DB_LIST &DBList,
+         const void *ConstructParams,
+         const CSSM_CERTGROUP &CertGroupFrag,
+         CSSM_CERTGROUP_PTR &CertGroup);
+	void CertSign(CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CssmData &CertTemplateToBeSigned,
+         const CSSM_CERTGROUP &SignerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT &SignerVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT &SignerVerifyResult,
+         CssmData &SignedCert);
+	void TupleGroupToCertGroup(CSSM_CL_HANDLE CLHandle,
+         const CSSM_TUPLEGROUP &TupleGroup,
+         CSSM_CERTGROUP_PTR &CertTemplates);
+	void ReceiveConfirmation(const CssmData &ReferenceIdentifier,
+         CSSM_TP_CONFIRM_RESPONSE_PTR &Responses,
+         sint32 &ElapsedTime);
+	void PassThrough(CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DL_DB_LIST *DBList,
+         uint32 PassThroughId,
+         const void *InputParams,
+         void **OutputParams);
+	void CertRemoveFromCrlTemplate(CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CssmData *OldCrlTemplate,
+         const CSSM_CERTGROUP &CertGroupToBeRemoved,
+         const CSSM_CERTGROUP &RevokerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT &RevokerVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT &RevokerVerifyResult,
+         CssmData &NewCrlTemplate);
+	void CertRevoke(CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CssmData *OldCrlTemplate,
+         const CSSM_CERTGROUP &CertGroupToBeRevoked,
+         const CSSM_CERTGROUP &RevokerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT &RevokerVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT &RevokerVerifyResult,
+         CSSM_TP_CERTCHANGE_REASON Reason,
+         CssmData &NewCrlTemplate);
+	void CertReclaimAbort(CSSM_LONG_HANDLE KeyCacheHandle);
+	void CrlCreateTemplate(CSSM_CL_HANDLE CLHandle,
+         uint32 NumberOfFields,
+         const CSSM_FIELD CrlFields[],
+         CssmData &NewCrlTemplate);
+	void CertGroupToTupleGroup(CSSM_CL_HANDLE CLHandle,
+         const CSSM_CERTGROUP &CertGroup,
+         CSSM_TUPLEGROUP_PTR &TupleGroup);
+	void SubmitCredRequest(const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
+         CSSM_TP_AUTHORITY_REQUEST_TYPE RequestType,
+         const CSSM_TP_REQUEST_SET &RequestInput,
+         const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthContext,
+         sint32 &EstimatedTime,
+         CssmData &ReferenceIdentifier);
+	void FormRequest(const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
+         CSSM_TP_FORM_TYPE FormType,
+         CssmData &BlankForm);
+	void CrlSign(CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_ENCODED_CRL &CrlToBeSigned,
+         const CSSM_CERTGROUP &SignerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT &SignerVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT &SignerVerifyResult,
+         CssmData &SignedCrl);
+	void CertGroupPrune(CSSM_CL_HANDLE CLHandle,
+         const CSSM_DL_DB_LIST &DBList,
+         const CSSM_CERTGROUP &OrderedCertGroup,
+         CSSM_CERTGROUP_PTR &PrunedCertGroup);
+	void ApplyCrlToDb(CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ENCODED_CRL &CrlToBeApplied,
+         const CSSM_CERTGROUP &SignerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT *ApplyCrlVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT &ApplyCrlVerifyResult);
+	void CertGetAllTemplateFields(CSSM_CL_HANDLE CLHandle,
+         const CssmData &CertTemplate,
+         uint32 &NumberOfFields,
+         CSSM_FIELD_PTR &CertFields);
+	void ConfirmCredResult(const CssmData &ReferenceIdentifier,
+         const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
+         const CSSM_TP_CONFIRM_RESPONSE &Responses,
+         const CSSM_TP_AUTHORITY_ID *PreferredAuthority);
+	void FormSubmit(CSSM_TP_FORM_TYPE FormType,
+         const CssmData &Form,
+         const CSSM_TP_AUTHORITY_ID *ClearanceAuthority,
+         const CSSM_TP_AUTHORITY_ID *RepresentedAuthority,
+         AccessCredentials *Credentials);
+	void RetrieveCredResult(const CssmData &ReferenceIdentifier,
+         const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
+         sint32 &EstimatedTime,
+         CSSM_BOOL &ConfirmationRequired,
+         CSSM_TP_RESULT_SET_PTR &RetrieveOutput);
+
+private:
+	void AppleTPSession::CertGroupConstructPriv(CSSM_CL_HANDLE clHand,
+			CSSM_CSP_HANDLE cspHand,
+			const CSSM_DL_DB_LIST &DBList,
+			const void *ConstructParams,
+			const CSSM_CERTGROUP &CertGroupFrag,
+			CSSM_BOOL ignoreExpired,
+			TPCertGroup *&CertGroup);
+
+};
+
+#endif	/* _H_APPLE_TP_SESSION */
diff --git a/AppleX509TP/AppleX509TPPlugin.cpp b/AppleX509TP/AppleX509TPPlugin.cpp
new file mode 100644
index 00000000..4debd333
--- /dev/null
+++ b/AppleX509TP/AppleX509TPPlugin.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 obtai
+n  
+ * 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.
+ */
+
+  
+// 
+// Produce the "genuine plugin version" of the Apple X509 TP
+//
+#include <AppleTP.h>
+
+
+//
+// Create the plugin object and generate the C layer hookup
+//
+ModuleNexus<AppleTP> plugin;
+
+#include <Security/pluginspi.h>
diff --git a/AppleX509TP/CVSVersionInfo.txt b/AppleX509TP/CVSVersionInfo.txt
new file mode 100644
index 00000000..12b4a6b9
--- /dev/null
+++ b/AppleX509TP/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:53 mb Exp $
+# $Name: Security-28 $
+ProjectName: AppleX509TP
+ProjectVersion: 3
diff --git a/AppleX509TP/TPCertInfo.cpp b/AppleX509TP/TPCertInfo.cpp
new file mode 100644
index 00000000..726cd7dd
--- /dev/null
+++ b/AppleX509TP/TPCertInfo.cpp
@@ -0,0 +1,407 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * TPCertInfo.h - TP's private certificate info classes
+ *
+ * Written 10/23/2000 by Doug Mitchell.
+ */
+
+#include "TPCertInfo.h"
+#include "tpdebugging.h"
+#include "tpTime.h"
+#include "certGroupUtils.h"
+#include <Security/cssmapi.h>
+#include <Security/x509defs.h>
+#include <Security/oidscert.h>
+#include <Security/oidsalg.h>
+#include <string.h>						/* for memcmp */
+#include <Security/threading.h>	/* for Mutex */
+#include <Security/globalizer.h>
+#include <Security/debugging.h>
+
+#define tpTimeDbg(args...)	debug("tpTime", ## args) 
+
+/* 
+ * No default constructor - this is the only way.
+ * This caches the cert and fetches subjectName and issuerName
+ * to ensure the incoming certData is well-constructed.
+ */
+TPCertInfo::TPCertInfo(
+	const CSSM_DATA		*certData,
+	CSSM_CL_HANDLE		clHand,
+	bool				copyCertData) :		// true: we copy, we free
+											// false - caller owns
+		mClHand(clHand),
+		mCacheHand(CSSM_INVALID_HANDLE),
+		mSubjectName(NULL),
+		mIssuerName(NULL)
+{
+	CSSM_RETURN	crtn;
+
+	if(copyCertData) {
+		mCertData = tpMallocCopyCssmData(CssmAllocator::standard(), certData);
+	}
+	else {
+		mCertData = const_cast<CSSM_DATA *>(certData);
+	}
+	mWeOwnTheData = copyCertData;
+	
+	/* cache the cert */
+	mClHand = clHand;
+	crtn = CSSM_CL_CertCache(clHand, mCertData, &mCacheHand);
+	if(crtn) {
+		/* bad cert */
+		CssmError::throwMe(crtn);
+	}
+	
+	/* fetch subject name */
+	crtn = fetchField(&CSSMOID_X509V1SubjectName, &mSubjectName);
+	if(crtn) {
+		/* bad cert */
+		releaseResources();
+		CssmError::throwMe(crtn);
+	}
+	
+	/* fetch issuer name */
+	crtn = fetchField(&CSSMOID_X509V1IssuerName, &mIssuerName);
+	if(crtn) {
+		/* bad cert */
+		releaseResources();
+		CssmError::throwMe(crtn);
+	}
+}
+	
+/* frees mSubjectName, mIssuerName, mCacheHand via mClHand */
+TPCertInfo::~TPCertInfo()
+{
+	releaseResources();
+}
+
+void TPCertInfo::releaseResources()
+{
+	if(mWeOwnTheData && (mCertData != NULL)) {
+		tpFreeCssmData(CssmAllocator::standard(), mCertData, CSSM_TRUE);
+	}
+	if(mSubjectName) {
+		freeField(&CSSMOID_X509V1SubjectName, mSubjectName);
+	}
+	if(mIssuerName) {
+		freeField(&CSSMOID_X509V1IssuerName, mIssuerName);
+	}
+	if(mCacheHand != CSSM_INVALID_HANDLE) {
+		CSSM_CL_CertAbortCache(mClHand, mCacheHand);
+	}
+}
+
+/* fetch arbitrary field from cached cert */
+CSSM_RETURN TPCertInfo::fetchField(
+	const CSSM_OID	*fieldOid,
+	CSSM_DATA_PTR	*fieldData)		// mallocd by CL and RETURNED
+{
+	CSSM_RETURN crtn;
+	
+	uint32 NumberOfFields = 0;
+	CSSM_HANDLE resultHand = 0;
+	*fieldData = NULL;
+
+	crtn = CSSM_CL_CertGetFirstCachedFieldValue(
+		mClHand,
+		mCacheHand,
+	    fieldOid,
+	    &resultHand,
+	    &NumberOfFields,
+		fieldData);
+	if(crtn) {
+		return crtn;
+	}
+	if(NumberOfFields != 1) {
+		errorLog1("TPCertInfo::fetchField: numFields %d, expected 1\n", 
+			(int)NumberOfFields);
+	}
+  	CSSM_CL_CertAbortQuery(mClHand, resultHand);
+	return CSSM_OK;
+}
+
+/* free arbitrary field obtained from fetchField() */
+CSSM_RETURN TPCertInfo::freeField( 
+	const CSSM_OID	*fieldOid,
+	CSSM_DATA_PTR	fieldData)	
+{
+	return CSSM_CL_FreeFieldValue(mClHand, fieldOid, fieldData);
+
+}
+
+/* accessors */
+CSSM_CL_HANDLE TPCertInfo::clHand()
+{
+	return mClHand;
+}
+
+CSSM_HANDLE TPCertInfo::cacheHand()
+{
+	return mCacheHand;
+}
+
+const CSSM_DATA *TPCertInfo::certData()
+{
+	CASSERT(mCertData != NULL);
+	return mCertData;
+}
+
+const CSSM_DATA *TPCertInfo::subjectName()
+{
+	CASSERT(mSubjectName != NULL);
+	return mSubjectName;
+}
+
+const CSSM_DATA *TPCertInfo::issuerName()						
+{
+	CASSERT(mIssuerName != NULL);
+	return mIssuerName;
+}
+
+bool TPCertInfo::isSelfSigned()		// i.e., subject == issuer
+{
+	return tpCompareCssmData(mSubjectName, mIssuerName) ? true : false;
+}
+
+/* 
+ * Verify validity (not before/after). Returns 
+ * 		CSSMERR_TP_CERT_NOT_VALID_YET
+ *		CSSMERR_TP_CERT_EXPIRED
+ *		CSSM_OK
+ *		CSSMERR_TP_INVALID_CERT_POINTER, other "bogus cert" errors
+ *
+ * We use some stdlib time calls over in tpTime.c; the stdlib function
+ * gmtime() is not thread-safe, so we do the protection here. Note that
+ * this makes *our* calls to gmtime() thread-safe, but if the app has
+ * other threads which are also calling gmtime, we're out of luck.
+ */
+static ModuleNexus<Mutex> tpTimeLock;
+
+CSSM_RETURN TPCertInfo::isCurrent(
+	CSSM_BOOL		allowExpired)
+{
+	CSSM_DATA_PTR	notBeforeField = NULL;
+	CSSM_DATA_PTR	notAfterField = NULL;
+	CSSM_RETURN		crtn = CSSM_OK;
+	
+	CASSERT(mCacheHand != CSSM_INVALID_HANDLE);
+	crtn = fetchField(&CSSMOID_X509V1ValidityNotBefore, &notBeforeField);
+	if(crtn) {
+		errorLog0("TPCertInfo::isCurrent: GetField error");
+		return crtn;
+	}
+	
+	struct tm now;
+	{
+		StLock<Mutex> _(tpTimeLock());
+		nowTime(&now);
+	}
+	struct tm notBefore;
+	CSSM_X509_TIME *xNotBefore = (CSSM_X509_TIME *)notBeforeField->Data;
+
+	if(timeStringToTm((char *)xNotBefore->time.Data, xNotBefore->time.Length, 
+			&notBefore)) {
+		errorLog0("TPCertInfo::isCurrent: malformed notBefore time\n");
+		crtn = CSSMERR_TP_INVALID_CERT_POINTER;
+		goto errOut;
+	}
+	if(compareTimes(&now, &notBefore) < 0) {
+		crtn = CSSMERR_TP_CERT_NOT_VALID_YET;
+		tpTimeDbg("\nTP_CERT_NOT_VALID_YET:\n   now y:%d m:%d d:%d h:%d m:%d",
+			now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, 
+			now.tm_min);
+		tpTimeDbg(" notBefore y:%d m:%d d:%d h:%d m:%d",
+			notBefore.tm_year, notBefore.tm_mon, notBefore.tm_mday, 
+			notBefore.tm_hour, notBefore.tm_min);
+		struct tm now2;
+		{
+			StLock<Mutex> _(tpTimeLock());
+			nowTime(&now2);
+		}
+		tpTimeDbg(" now2      y:%d m:%d d:%d h:%d m:%d",
+			now2.tm_year, now2.tm_mon, now2.tm_mday, now2.tm_hour, 
+			now2.tm_min);
+		goto errOut;
+	}
+
+	if(!allowExpired) {
+		struct tm notAfter;
+		crtn = fetchField(&CSSMOID_X509V1ValidityNotAfter, &notAfterField);
+		if(crtn) {
+			errorLog0("TPCertInfo::isCurrent: GetField error");
+			goto errOut;
+		}
+	
+		CSSM_X509_TIME *xNotAfter = (CSSM_X509_TIME *)notAfterField->Data;
+		if(timeStringToTm((char *)xNotAfter->time.Data, xNotAfter->time.Length, 
+				&notAfter)) {
+			errorLog0("TPCertInfo::isCurrent: malformed notAfter time\n");
+			crtn = CSSMERR_TP_INVALID_CERT_POINTER;
+		}
+		else if(compareTimes(&now, &notAfter) > 0) {
+			crtn = CSSMERR_TP_CERT_EXPIRED;
+			tpTimeDbg("\nTP_CERT_EXPIRED: \n   now y:%d m:%d d:%d "
+					"h:%d m:%d",
+				now.tm_year, now.tm_mon, now.tm_mday, 
+				now.tm_hour, now.tm_min);
+			tpTimeDbg(" notAfter y:%d m:%d d:%d h:%d m:%d",
+				notAfter.tm_year, notAfter.tm_mon, notAfter.tm_mday, 
+				notAfter.tm_hour, notAfter.tm_min);
+			struct tm now2;
+			{
+				StLock<Mutex> _(tpTimeLock());
+				nowTime(&now2);
+			}
+			tpTimeDbg(" now2      y:%d m:%d d:%d h:%d m:%d",
+				now2.tm_year, now2.tm_mon, now2.tm_mday, now2.tm_hour, 
+				now2.tm_min);
+		}
+		else {
+			crtn = CSSM_OK;
+		}
+	}
+	else {
+		crtn = CSSM_OK;
+	}
+errOut:
+	if(notAfterField) {
+		freeField(&CSSMOID_X509V1ValidityNotAfter, notAfterField);
+	}
+	if(notBeforeField) {
+		freeField(&CSSMOID_X509V1ValidityNotBefore, notBeforeField);
+	}
+	return crtn;
+}
+
+/***
+ *** TPCertGroup class
+ ***/
+TPCertGroup::TPCertGroup(
+	CssmAllocator		&alloc,
+	unsigned			numCerts) :
+		mAlloc(alloc),
+		mNumCerts(0)
+{
+	mCertInfo = (TPCertInfo **)alloc.malloc(numCerts * sizeof(TPCertInfo *));
+	mSizeofCertInfo = numCerts;
+}
+	
+/*
+ * Deletes all TPCertInfo's.
+ */
+TPCertGroup::~TPCertGroup()
+{
+	unsigned i;
+	for(i=0; i<mNumCerts; i++) {
+		delete mCertInfo[i];
+	}
+	mAlloc.free(mCertInfo);
+}
+
+/* add/remove/access TPTCertInfo's. */
+void TPCertGroup::appendCert(
+	TPCertInfo			*certInfo)			// appends to end of mCertInfo
+{
+	if(mNumCerts == mSizeofCertInfo) {
+		/* FIXME - do we need the realloc workaround we used to have in TPSession? */
+		mSizeofCertInfo *= 2;
+		mCertInfo = (TPCertInfo **)mAlloc.realloc(mCertInfo, 
+			mSizeofCertInfo * sizeof(TPCertInfo *));
+	}
+	mCertInfo[mNumCerts++] = certInfo;
+}
+
+TPCertInfo *TPCertGroup::certAtIndex(
+	unsigned			index)
+{
+	if(index > (mNumCerts - 1)) {
+		CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
+	}
+	return mCertInfo[index];
+}
+
+TPCertInfo *TPCertGroup::removeCertAtIndex(
+	unsigned			index)				// doesn't delete the cert, just 
+											// removes it from out list
+{
+	if(index > (mNumCerts - 1)) {
+		CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
+	}
+	TPCertInfo *rtn = mCertInfo[index];
+	
+	/* removed requested element and compact remaining array */
+	unsigned i;
+	for(i=index; i<(mNumCerts - 1); i++) {
+		mCertInfo[i] = mCertInfo[i+1];
+	}
+	mNumCerts--;
+	return rtn;
+}
+
+unsigned TPCertGroup::numCerts()
+{
+	return mNumCerts;
+}
+
+TPCertInfo *TPCertGroup::firstCert()
+{
+	if(mNumCerts == 0) {
+		/* the caller really should not do this... */
+		CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
+	}
+	else {
+		return mCertInfo[0];
+	}
+}
+
+TPCertInfo *TPCertGroup::lastCert()
+{
+	if(mNumCerts == 0) {
+		/* the caller really should not do this... */
+		CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
+	}
+	else {
+		return mCertInfo[mNumCerts - 1];
+	}
+}
+
+/* build a CSSM_CERTGROUP corresponding with our mCertInfo */
+CSSM_CERTGROUP_PTR TPCertGroup::buildCssmCertGroup()
+{
+	CSSM_CERTGROUP_PTR cgrp = 
+		(CSSM_CERTGROUP_PTR)mAlloc.malloc(sizeof(CSSM_CERTGROUP));
+	cgrp->NumCerts = mNumCerts;
+	cgrp->CertGroupType = CSSM_CERTGROUP_ENCODED_CERT;
+	cgrp->CertType = CSSM_CERT_X_509v3;
+	cgrp->CertEncoding = CSSM_CERT_ENCODING_DER; 
+	if(mNumCerts == 0) {
+		/* legal */
+		cgrp->GroupList.CertList = NULL;
+		return cgrp;
+	}
+	cgrp->GroupList.CertList = (CSSM_DATA_PTR)mAlloc.calloc(mNumCerts, 
+		sizeof(CSSM_DATA));
+	for(unsigned i=0; i<mNumCerts; i++) {
+		tpCopyCssmData(mAlloc, mCertInfo[i]->certData(), 
+			&cgrp->GroupList.CertList[i]);
+	}
+	return cgrp;
+}
diff --git a/AppleX509TP/TPCertInfo.h b/AppleX509TP/TPCertInfo.h
new file mode 100644
index 00000000..313c9443
--- /dev/null
+++ b/AppleX509TP/TPCertInfo.h
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * TPCertInfo.h - TP's private certificate info and cert group classes
+ *
+ * Written 10/23/2000 by Doug Mitchell.
+ */
+ 
+#ifndef	_TP_CERT_INFO_H_
+#define _TP_CERT_INFO_H_
+
+#include <Security/cssmtype.h>
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+
+/*
+ * Class representing one certificate. The raw cert data usually comes from
+ * a client (via incoming cert groups in CertGroupConstruct() and CertGroupVerify());
+ * In this case, we don't own the raw data and don't copy or free it. Caller can 
+ * optionally specify that we copy (and own and eventnually free) the raw cert data. 
+ * The constructor throws on any error (bad cert data); subsequent to successful 
+ * construction, no CSSM errors are thrown and it's guaranteed that the cert is
+ * basically good and successfully cached in the CL, and that we have a locally
+ * cached subject and issuer name (in normalized encoded format). 
+ */ 
+class TPCertInfo
+{
+public:
+	/* 
+	 * No default constructor - this is the only way.
+	 * This caches the cert and fetches subjectName and issuerName
+	 * to ensure the incoming certData is well-constructed.
+	 */
+	TPCertInfo(
+		const CSSM_DATA		*certData,
+		CSSM_CL_HANDLE		clHand,
+		bool				copyCertData = false);	// true: we copy, we free
+													// false - caller owns
+		
+	/* frees mSubjectName, mIssuerName, mCacheHand via mClHand */
+	~TPCertInfo();
+	
+	/* 
+	 * Fetch arbitrary field from cached cert.
+	 * Only should be used when caller is sure there is either zero or one
+	 * of the requested fields present in the cert.
+	 */
+	CSSM_RETURN fetchField(
+		const CSSM_OID	*fieldOid,
+		CSSM_DATA_PTR	*fieldData);			// mallocd by CL and RETURNED
+
+	/* free arbitrary field obtained from fetchField() */
+	CSSM_RETURN freeField( 
+		const CSSM_OID	*fieldOid,
+		CSSM_DATA_PTR	fieldData);
+		
+	/* accessors */
+	CSSM_CL_HANDLE	clHand();
+	CSSM_HANDLE		cacheHand();
+	const CSSM_DATA *certData();
+	const CSSM_DATA *subjectName();
+	const CSSM_DATA *issuerName();				
+
+	bool isSelfSigned();						// i.e., subject == issuer
+	
+	/* 
+	 * Verify validity (not before/after). Returns 
+	 * 		CSSMERR_TP_CERT_NOT_VALID_YET
+	 *		CSSMERR_TP_CERT_EXPIRED
+	 *		CSSM_OK
+	 *		CSSMERR_TP_INVALID_CERT_POINTER, other "bogus cert" errors
+	 */
+	CSSM_RETURN isCurrent(
+		CSSM_BOOL		allowExpired = CSSM_FALSE);
+		
+private:
+	CSSM_DATA				*mCertData;			// always valid
+	bool					mWeOwnTheData;		// if true, we have to free mCertData
+	CSSM_CL_HANDLE			mClHand;			// always valid
+	CSSM_HANDLE				mCacheHand;			// always valid
+	CSSM_DATA_PTR			mSubjectName;		// always valid
+	CSSM_DATA_PTR			mIssuerName;		// always valid
+	
+	void releaseResources();
+	
+	/* other field accessors here */
+};
+
+/*
+ * TP's private Cert Group class. Provides a list of TPCertInfo pointers, to which 
+ * caller can append additional elements, access an element at an arbitrary position, 
+ * and remover an element at an arbitrrary position. 
+ */
+class TPCertGroup
+{
+public:
+	/*
+	 * No default constructor - use this to cook up an instance with 
+	 * space for numCerts TPCertInfos. 
+	 */
+	TPCertGroup(
+		CssmAllocator		&alloc,
+		unsigned			numCerts);
+	
+	/*
+	 * Deletes all TPCertInfo's.
+	 */
+	~TPCertGroup();
+	
+	/* add/remove/access TPTCertInfo's. */
+	void appendCert(
+		TPCertInfo			*certInfo);			// appends to end of mCertInfo
+	TPCertInfo *certAtIndex(
+		unsigned			index);
+	TPCertInfo *removeCertAtIndex(
+		unsigned			index);				// doesn't delete the cert, just 
+												// removes it from our list
+	unsigned numCerts();						// how many do we have? 
+	
+	/* 
+	 * Convenience accessors for first and last cert, only valid when we have
+	 * at least one cert.
+	 */
+	TPCertInfo 
+		*firstCert();
+	TPCertInfo
+		*lastCert();
+		
+	/* build a CSSM_CERTGROUP corresponding with our mCertInfo */
+	CSSM_CERTGROUP_PTR		
+		buildCssmCertGroup();
+	
+private:
+	CssmAllocator			&mAlloc;
+	TPCertInfo				**mCertInfo;		// just an array of pointers
+	unsigned				mNumCerts;			// valid certs in certInfo
+	unsigned				mSizeofCertInfo;	// mallocd space in certInfo
+};
+#endif	/* _TP_CERT_INFO_H_ */
diff --git a/AppleX509TP/certGroupUtils.cpp b/AppleX509TP/certGroupUtils.cpp
new file mode 100644
index 00000000..513d8eb9
--- /dev/null
+++ b/AppleX509TP/certGroupUtils.cpp
@@ -0,0 +1,441 @@
+/*
+ * 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.
+ */
+
+
+/*
+	certGroupUtils.cpp
+
+	Created 10/9/2000 by Doug Mitchell. 
+*/
+
+#include <Security/cssmtype.h>
+#include <Security/cssmapi.h>
+#include <Security/x509defs.h>
+#include <Security/oidscert.h>
+#include <Security/oidsalg.h>
+#include <Security/cssmapple.h>
+
+#include "certGroupUtils.h" 
+#include "cldebugging.h"
+#include "tpTime.h"
+
+#include <string.h>				/* for memcmp */
+
+#if 0
+void *tpCalloc(CssmAllocator &alloc, uint32 num, uint32 size)
+{
+	void *p = alloc.malloc(num * size);
+	memset(p, 0, num* size);
+	return p;
+}  
+#endif
+
+/*
+ * Copy one CSSM_DATA to another, mallocing destination. 
+ */
+void tpCopyCssmData(
+	CssmAllocator	&alloc,
+	const CSSM_DATA	*src,
+	CSSM_DATA_PTR	dst)
+{
+	dst->Data = (uint8 *)alloc.malloc(src->Length);
+	dst->Length = src->Length;
+	memmove(dst->Data, src->Data, src->Length);
+}
+
+/*
+ * Malloc a CSSM_DATA, copy another one to it.
+ */
+CSSM_DATA_PTR tpMallocCopyCssmData(
+	CssmAllocator	&alloc,
+	const CSSM_DATA	*src)
+{
+	CSSM_DATA_PTR dst = (CSSM_DATA_PTR)alloc.malloc(sizeof(CSSM_DATA));
+	tpCopyCssmData(alloc, src, dst);
+	return dst;
+}
+
+/*
+ * Free the data referenced by a CSSM data, and optionally, the struct itself.
+ */
+void tpFreeCssmData(
+	CssmAllocator	&alloc,
+	CSSM_DATA_PTR 	data,
+	CSSM_BOOL 		freeStruct)
+{
+	if(data == NULL) {
+		return;
+	}
+	if(data->Length != 0) {
+		tpFree(alloc, data->Data);
+	}
+	if(freeStruct) {
+		tpFree(alloc, data);
+	}
+	else {
+		data->Length = 0;
+		data->Data = NULL;
+	}
+}
+
+/*
+ * Compare two CSSM_DATAs, return CSSM_TRUE if identical.
+ */
+CSSM_BOOL tpCompareCssmData(
+	const CSSM_DATA *data1,
+	const CSSM_DATA *data2)
+{	
+	if((data1 == NULL) || (data1->Data == NULL) || 
+	   (data2 == NULL) || (data2->Data == NULL) ||
+	   (data1->Length != data2->Length)) {
+		return CSSM_FALSE;
+	}
+	if(data1->Length != data2->Length) {
+		return CSSM_FALSE;
+	}
+	if(memcmp(data1->Data, data2->Data, data1->Length) == 0) {
+		return CSSM_TRUE;
+	}
+	else {
+		return CSSM_FALSE;
+	}
+}
+
+/*
+ * Compare two OIDs, return CSSM_TRUE if identical.
+ */
+CSSM_BOOL tpCompareOids(
+	const CSSM_OID *oid1,
+	const CSSM_OID *oid2)
+{	
+	/*
+	 * This should break if/when CSSM_OID is not the same as
+	 * CSSM_DATA, which is exactly what we want.
+	 */
+	return tpCompareCssmData(oid1, oid2);
+}
+
+/*
+ * Obtain the public key blob from a cert.
+ */
+CSSM_DATA_PTR tp_CertGetPublicKey( 
+    TPCertInfo *cert,
+	CSSM_DATA_PTR *valueToFree)			// used in tp_CertFreePublicKey
+{
+	CSSM_RETURN crtn;
+	CSSM_DATA_PTR val;
+	CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *keyInfo;
+	
+	*valueToFree = NULL;
+	crtn = cert->fetchField(&CSSMOID_X509V1SubjectPublicKeyCStruct, &val);
+	if(crtn) {
+		errorLog0("Error on CSSM_CL_CertGetFirstFieldValue(PublicKeyCStruct)\n");
+		return NULL;
+	}
+	*valueToFree = val;
+	keyInfo = (CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)val->Data;
+	return &keyInfo->subjectPublicKey;
+}
+
+void tp_CertFreePublicKey(
+	CSSM_CL_HANDLE	clHand,
+	CSSM_DATA_PTR	value)
+{
+  	CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SubjectPublicKeyCStruct, value);
+}
+
+/*
+ * Obtain signature algorithm info from a cert.
+ */
+CSSM_X509_ALGORITHM_IDENTIFIER_PTR tp_CertGetAlgId( 
+    TPCertInfo	 	*cert,
+	CSSM_DATA_PTR 	*valueToFree)			// used in tp_CertFreeAlgId
+{
+	CSSM_RETURN crtn;
+	CSSM_DATA_PTR val;
+	
+	*valueToFree = NULL;
+	crtn = cert->fetchField(&CSSMOID_X509V1SignatureAlgorithm, &val);
+	if(crtn) {
+		errorLog0("Error on fetchField(CSSMOID_X509V1SignatureAlgorithm)\n");
+		return NULL;
+	}
+	*valueToFree = val;
+	return (CSSM_X509_ALGORITHM_IDENTIFIER_PTR)val->Data;
+}
+
+void tp_CertFreeAlgId(
+	CSSM_CL_HANDLE	clHand,
+	CSSM_DATA_PTR	value)
+{
+  	CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SignatureAlgorithm, value);
+}
+
+/* 
+ * Compare two DER-encoded normalized names.
+ */
+CSSM_BOOL tpIsSameName( 
+	const CSSM_DATA *name1,
+	const CSSM_DATA *name2)
+{
+	return tpCompareCssmData(name1, name2);
+}
+
+
+/*
+ * Given a TP handle, a CSP handle, a CL handle, and two certs, verify
+ * subjectCert with issuerCert. If checkIssuerExpired is CSSM_TRUE, 
+ * we'll do a not before/after check of the issuer only if the 
+ * signature verify  passes. The rationale is that we're not interested 
+ * in this condition for potential issuers which fail the sig verify. 
+ *
+ * Returns:
+ *		CSSM_OK
+ *		CSSMERR_TP_VERIFICATION_FAILURE		-- sig verify failure
+ *		CSSMERR_TP_CERT_EXPIRED
+ *		CSSMERR_TP_CERT_NOT_VALID_YET
+ */
+CSSM_RETURN tp_VerifyCert(
+	CSSM_CL_HANDLE			clHand,
+	CSSM_CSP_HANDLE			cspHand,
+	TPCertInfo				*subjectCert,
+	TPCertInfo				*issuerCert,
+	CSSM_BOOL				checkIssuerCurrent,
+	CSSM_BOOL				allowExpired)
+{
+	CSSM_RETURN			crtn;
+
+	crtn = CSSM_CL_CertVerify(clHand, 
+    	CSSM_INVALID_HANDLE, 
+    	subjectCert->certData(),
+    	issuerCert->certData(),
+    	NULL,				// VerifyScope
+    	0);					// ScopeSize
+	if(crtn == CSSM_OK) {
+		if(checkIssuerCurrent) {
+			/* also verify validity of issuer */
+			crtn = issuerCert->isCurrent(allowExpired);
+		}
+	}
+	else {
+		/* general cert verify failure */
+		crtn = CSSMERR_TP_VERIFICATION_FAILURE;
+	}
+	return crtn;
+}
+
+/*
+ * Determine if two certs - passed in encoded form - are equivalent. 
+ */
+CSSM_BOOL tp_CompareCerts(
+	const CSSM_DATA			*cert1,
+	const CSSM_DATA			*cert2)
+{
+	return tpCompareCssmData(cert1, cert2);
+}
+
+#if		TP_DL_ENABLE
+/*
+ * Given a DL/DB, look up cert by subject name. Subsequent
+ * certs can be found using the returned result handle. 
+ */
+static CSSM_DB_UNIQUE_RECORD_PTR tpCertLookup(
+	CSSM_TP_HANDLE		tpHand,
+	CSSM_DL_DB_HANDLE	dlDb,
+	const CSSM_DATA_PTR	subjectName,	// DER-encoded
+	CSSM_HANDLE_PTR		resultHand,
+	CSSM_DATA_PTR		cert)			// RETURNED
+{
+	CSSM_QUERY						query;
+	CSSM_SELECTION_PREDICATE		predicate;	
+	CSSM_BOOL  						EndOfDataStore;
+	CSSM_DB_UNIQUE_RECORD_PTR		record;
+	
+	cert->Data = NULL;
+	cert->Length = 0;
+	
+	predicate.DbOperator = CSSM_DB_EQUAL;
+	predicate.Attribute.Info.AttributeNameFormat = 
+		CSSM_DB_ATTRIBUTE_NAME_AS_NUMBER;		// may not be needed
+	predicate.Attribute.Info.Attr.AttributeNumber = kSubjectKCItemAttr;
+	predicate.Attribute.Value = *subjectName;
+	
+	query.RecordType = CSSM_DL_DB_RECORD_CERT;
+	query.NumSelectionPredicates = 1;
+	query.Conjunctive = CSSM_DB_NONE;
+	
+	query.SelectionPredicate = &predicate;
+	
+	record = CSSM_DL_DataGetFirst(dlDb,
+		&query,
+		resultHand,
+		&EndOfDataStore,
+		NULL,				// don't fetch attributes
+		cert);
+	return record;
+}
+
+/*
+ * Search a list of DBs for a cert which verifies specified subject cert. 
+ * Just a boolean return - we found it, or not. If we did, we return
+ * a pointer to the raw cert. 
+ *
+ * Special case of subject cert expired indicated by *subjectExpired 
+ * returned as something other than CSSM_OK.
+ */
+CSSM_DATA_PTR tpFindIssuer(
+	CSSM_TP_HANDLE			tpHand,
+	CSSM_CL_HANDLE			clHand,
+	CSSM_CSP_HANDLE			cspHand,
+	const CSSM_DATA_PTR		subjectCert,
+	const CSSM_DATA_PTR		issuerName,			// passed for convenience
+	const CSSM_DB_LIST_PTR	dbList,
+	CSSM_RETURN				*issuerExpired)		// RETURNED
+{
+	uint32						dbDex;
+	CSSM_HANDLE					resultHand;
+	CSSM_DATA_PTR				cert;					// we malloc
+	CSSM_DL_DB_HANDLE			dlDb;
+	CSSM_DB_UNIQUE_RECORD_PTR	record;
+	
+	*subjectExpired = CSSM_OK;
+	if(dbList == NULL) {
+		return NULL;
+	}
+	cert = (CSSM_DATA_PTR)tpMalloc(tpHand, sizeof(CSSM_DATA));
+	cert->Data = NULL;
+	cert->Length = 0;
+	
+	for(dbDex=0; dbDex<dbList->NumHandles; dbDex++) {
+		dlDb = dbList->DLDBHandle[dbDex];
+		record = tpCertLookup(tpHand,
+			dlDb,
+			issuerName,
+			&resultHand,
+			cert);
+		/* remember we have to abort this query regardless...*/
+		if(record != NULL) {
+			/* Found one. Does it verify the subject cert? */
+			if(!tp_VerifyCert(tpHand,
+					clHand,
+					cspHand,
+					subjectCert,
+					cert,
+					issuerExpired)) {
+					
+				/* special case - abort immediately if issuerExpired has expired */
+				if((*issuerExpired) != CSSM_OK) {
+					CSSM_DL_AbortQuery(dlDb, resultHand);
+					goto abort;
+				}
+				
+				/*
+				 * Verify fail. Continue searching this DB. Break on 
+				 * finding the holy grail or no more records found. 
+				 */
+				for(;;) {
+					CSSM_BOOL eod;
+					
+					tpFreeCssmData(tpHand, cert, CSSM_FALSE);
+					record = CSSM_DL_DataGetNext(dlDb, 
+						resultHand,
+						&eod,
+						NULL,		// no attrs 
+						cert);
+					if(record == NULL) {
+						/* no more, done with this DB */
+						break;
+					}
+					
+					/* found one - does it verify subject? */
+					if(tp_VerifyCert(tpHand,
+							clHand,
+							cspHand,
+							subjectCert,
+							cert,
+							issuerExpired)) {
+						/* yes! */
+						break;
+					}
+					else if((*issuerExpired) != CSSM_OK) {
+						/* abort immediately */
+						CSSM_DL_AbortQuery(dlDb, resultHand);
+						goto abort;
+					}
+				} /* searching subsequent records */
+			}	/* verify fail */
+			/* else success! */
+
+			if(record != NULL) {
+				/* successful return */
+				CSSM_DL_AbortQuery(dlDb, resultHand);
+				return cert;
+			}
+		}	/* tpCertLookup, i.e., CSSM_DL_DataGetFirst, succeeded */
+		
+		/* in any case, abort the query for this db */
+		CSSM_DL_AbortQuery(dlDb, resultHand);
+		
+	}	/* main loop searching dbList */
+
+abort:
+	/* issuer not found */
+	tpFreeCssmData(tpHand, cert, CSSM_TRUE);
+	return NULL;
+}
+
+#endif	/* TP_DL_ENABLE */
+
+/*
+ * Given a aignature OID, return the corresponding CSSM_ALGID for the 
+ * signature the required key.
+ */
+CSSM_ALGORITHMS tpOidToAldId(
+	const CSSM_OID *oid,
+	CSSM_ALGORITHMS *keyAlg)			// RETURNED
+{
+	*keyAlg = CSSM_ALGID_RSA;			// default
+	if(tpCompareOids(oid, &CSSMOID_MD2WithRSA)) {
+		return CSSM_ALGID_MD2WithRSA;
+	}
+	else if(tpCompareOids(oid, &CSSMOID_MD5WithRSA)) {
+		return CSSM_ALGID_MD5WithRSA;
+	}
+	else if(tpCompareOids(oid, &CSSMOID_SHA1WithRSA)) {
+		return CSSM_ALGID_SHA1WithRSA;
+	}
+	else if(tpCompareOids(oid, &CSSMOID_SHA1WithDSA)) {
+		*keyAlg = CSSM_ALGID_DSA;
+		return CSSM_ALGID_SHA1WithDSA;
+	}
+	else if(tpCompareOids(oid, &CSSMOID_APPLE_FEE_MD5)) {
+		*keyAlg = CSSM_ALGID_FEE;
+		return CSSM_ALGID_FEE_MD5;
+	}
+	else if(tpCompareOids(oid, &CSSMOID_APPLE_FEE_SHA1)) {
+		*keyAlg = CSSM_ALGID_FEE;
+		return CSSM_ALGID_FEE_SHA1;
+	}
+	else if(tpCompareOids(oid, &CSSMOID_APPLE_ECDSA)) {
+		*keyAlg = CSSM_ALGID_FEE;
+		return CSSM_ALGID_SHA1WithECDSA;
+	}
+	else {
+		*keyAlg = CSSM_ALGID_NONE;
+		return CSSM_ALGID_NONE;
+	}
+}
diff --git a/AppleX509TP/certGroupUtils.h b/AppleX509TP/certGroupUtils.h
new file mode 100644
index 00000000..ec28cc3d
--- /dev/null
+++ b/AppleX509TP/certGroupUtils.h
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+
+/*
+	certGroupUtils.h
+
+	Created 10/9/2000 by Doug Mitchell. 
+*/
+
+#ifndef _CERT_GROUP_UTILS_H
+#define _CERT_GROUP_UTILS_H
+
+#include <Security/x509defs.h>
+#include <Security/cssmalloc.h>
+#include "TPCertInfo.h"
+/*
+ * Cheetah version of TP doesn't work with DLs. 
+ */
+#define TP_DL_ENABLE		0
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* quick & dirty port from OS9 to OS X... */
+#define tpFree(alloc, ptr)			(alloc).free(ptr)
+#define tpMalloc(alloc, size)		(alloc).malloc(size)
+#define tpCalloc(alloc, num, size)	(alloc).calloc(num, size)
+
+void tpCopyCssmData(
+	CssmAllocator	&alloc,
+	const CSSM_DATA	*src,
+	CSSM_DATA_PTR	dst);
+CSSM_DATA_PTR tpMallocCopyCssmData(
+	CssmAllocator	&alloc,
+	const CSSM_DATA	*src);
+void tpFreeCssmData(
+	CssmAllocator &alloc,
+	CSSM_DATA_PTR 	data,
+	CSSM_BOOL 		freeStruct);
+CSSM_BOOL tpCompareCssmData(
+	const CSSM_DATA *data1,
+	const CSSM_DATA *data2);
+CSSM_BOOL tpCompareOids(
+	const CSSM_OID *oid1,
+	const CSSM_OID *oid2);
+
+CSSM_DATA_PTR tp_CertGetPublicKey( 
+	TPCertInfo 		*cert,
+	CSSM_DATA_PTR 	*valueToFree);			// used in tp_CertFreePublicKey
+void tp_CertFreePublicKey(
+	CSSM_CL_HANDLE	clHand,
+	CSSM_DATA_PTR	value);
+
+CSSM_X509_ALGORITHM_IDENTIFIER_PTR tp_CertGetAlgId( 
+    TPCertInfo	 	*cert,
+	CSSM_DATA_PTR 	*valueToFree);	// used in tp_CertFreeAlgId
+void tp_CertFreeAlgId(
+	CSSM_CL_HANDLE	clHand,
+	CSSM_DATA_PTR	value);
+
+#if	 TP_DL_ENABLE
+CSSM_DATA_PTR
+tp_GetCertFromDBList( CSSM_TP_HANDLE hTP,
+                      CSSM_CL_HANDLE hCL,
+                      CSSM_SELECTION_PREDICATE_PTR pPredicate,
+                      uint32 NumberOfPredicates,
+                      const CSSM_DB_LIST_PTR pDBList );
+
+CSSM_DATA_PTR
+tp_GetCertFromDBListBySName( CSSM_TP_HANDLE hTP,
+                             CSSM_CL_HANDLE hCL,
+                             const CSSM_DATA_PTR pSubjectName,
+                             const CSSM_DB_LIST_PTR pDBList );
+
+#endif	/* TP_DL_ENABLE*/
+
+CSSM_BOOL tpIsSameName( 
+	const CSSM_DATA *pName1,
+	const CSSM_DATA *pName2);
+
+CSSM_RETURN tp_VerifyCert(
+	CSSM_CL_HANDLE			clHand,
+	CSSM_CSP_HANDLE			cspHand,
+	TPCertInfo				*subjectCert,
+	TPCertInfo				*issuerCert,
+	CSSM_BOOL				checkIssuerCurrent,
+	CSSM_BOOL				allowExpired);
+
+CSSM_BOOL tp_CompareCerts(
+	const CSSM_DATA			*cert1,
+	const CSSM_DATA			*cert2);
+
+#if		TP_DL_ENABLE
+/*
+ * Search a list of DBs for a cert which verifies specified subject cert. 
+ * Just a boolean return - we found it, or not.
+ */
+CSSM_DATA_PTR tpFindIssuer(
+	CSSM_TP_HANDLE			tpHand,
+	CSSM_CL_HANDLE			clHand,
+	CSSM_CSP_HANDLE			cspHand,
+	const CSSM_DATA_PTR		subjectCert,
+	const CSSM_DATA_PTR		issuerName,			// passed for convenience
+	const CSSM_DB_LIST_PTR	dbList,
+	CSSM_BOOL				*subjectExpired);	// RETURNED
+#endif
+
+/*
+ * Given an OID, return the corresponding CSSM_ALGID.
+ */
+CSSM_ALGORITHMS tpOidToAldId(
+	const CSSM_OID *oid,
+	CSSM_ALGORITHMS *keyAlg);			// RETURNED
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _CERT_GROUP_UTILS_H */
diff --git a/AppleX509TP/cssmplugin.exp b/AppleX509TP/cssmplugin.exp
new file mode 100644
index 00000000..f5046fbf
--- /dev/null
+++ b/AppleX509TP/cssmplugin.exp
@@ -0,0 +1,4 @@
+_CSSM_SPI_ModuleLoad
+_CSSM_SPI_ModuleAttach
+_CSSM_SPI_ModuleDetach
+_CSSM_SPI_ModuleUnload
diff --git a/AppleX509TP/iSignRootCerts.c b/AppleX509TP/iSignRootCerts.c
new file mode 100644
index 00000000..5374af84
--- /dev/null
+++ b/AppleX509TP/iSignRootCerts.c
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		iSignRootCerts.c
+
+	Contains:	embedded iSign root certs - subject name and public keys 
+
+	Written by:	Doug Mitchell. 
+
+	Copyright:	Copyright 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include <Security/cssmtype.h>
+#include "rootCerts.h"
+
+/* 
+ * this static data is generated by extractCertFields, copy&pasted from
+ * its output into this source file 
+ */
+
+/***********************
+Cert File Name: serverbasic.crt
+Subject Name       :
+    Country        : ZA
+    State          : Western Cape
+    Locality       : Cape Town
+    Org            : Thawte Consulting cc
+    OrgUnit        : Certification Services Division
+    Common Name    : Thawte Server CA
+    Email addrs    : server-certs@thawte.com
+ ***********************/
+static const uint8 serverbasic_subject_bytes[] = {
+   0x30,  0x81,  0xc4,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x5a,  0x41,  
+   0x31,  0x15,  0x30,  0x13,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x0c,  0x57,  0x45,  0x53,  0x54,  0x45,  
+   0x52,  0x4e,  0x20,  0x43,  0x41,  0x50,  0x45,  0x31,  
+   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x07,  
+   0x13,  0x09,  0x43,  0x41,  0x50,  0x45,  0x20,  0x54,  
+   0x4f,  0x57,  0x4e,  0x31,  0x1d,  0x30,  0x1b,  0x06,  
+   0x03,  0x55,  0x04,  0x0a,  0x13,  0x14,  0x54,  0x48,  
+   0x41,  0x57,  0x54,  0x45,  0x20,  0x43,  0x4f,  0x4e,  
+   0x53,  0x55,  0x4c,  0x54,  0x49,  0x4e,  0x47,  0x20,  
+   0x43,  0x43,  0x31,  0x28,  0x30,  0x26,  0x06,  0x03,  
+   0x55,  0x04,  0x0b,  0x13,  0x1f,  0x43,  0x45,  0x52,  
+   0x54,  0x49,  0x46,  0x49,  0x43,  0x41,  0x54,  0x49,  
+   0x4f,  0x4e,  0x20,  0x53,  0x45,  0x52,  0x56,  0x49,  
+   0x43,  0x45,  0x53,  0x20,  0x44,  0x49,  0x56,  0x49,  
+   0x53,  0x49,  0x4f,  0x4e,  0x31,  0x19,  0x30,  0x17,  
+   0x06,  0x03,  0x55,  0x04,  0x03,  0x13,  0x10,  0x54,  
+   0x48,  0x41,  0x57,  0x54,  0x45,  0x20,  0x53,  0x45,  
+   0x52,  0x56,  0x45,  0x52,  0x20,  0x43,  0x41,  0x31,  
+   0x26,  0x30,  0x24,  0x06,  0x09,  0x2a,  0x86,  0x48,  
+   0x86,  0xf7,  0x0d,  0x01,  0x09,  0x01,  0x16,  0x17,  
+   0x73,  0x65,  0x72,  0x76,  0x65,  0x72,  0x2d,  0x63,  
+   0x65,  0x72,  0x74,  0x73,  0x40,  0x74,  0x68,  0x61,  
+   0x77,  0x74,  0x65,  0x2e,  0x63,  0x6f,  0x6d
+};
+const CSSM_DATA serverbasic_subject = { 199, (uint8 *)serverbasic_subject_bytes };
+static const uint8 serverbasic_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xd3,  
+   0xa4,  0x50,  0x6e,  0xc8,  0xff,  0x56,  0x6b,  0xe6,  
+   0xcf,  0x5d,  0xb6,  0xea,  0x0c,  0x68,  0x75,  0x47,  
+   0xa2,  0xaa,  0xc2,  0xda,  0x84,  0x25,  0xfc,  0xa8,  
+   0xf4,  0x47,  0x51,  0xda,  0x85,  0xb5,  0x20,  0x74,  
+   0x94,  0x86,  0x1e,  0x0f,  0x75,  0xc9,  0xe9,  0x08,  
+   0x61,  0xf5,  0x06,  0x6d,  0x30,  0x6e,  0x15,  0x19,  
+   0x02,  0xe9,  0x52,  0xc0,  0x62,  0xdb,  0x4d,  0x99,  
+   0x9e,  0xe2,  0x6a,  0x0c,  0x44,  0x38,  0xcd,  0xfe,  
+   0xbe,  0xe3,  0x64,  0x09,  0x70,  0xc5,  0xfe,  0xb1,  
+   0x6b,  0x29,  0xb6,  0x2f,  0x49,  0xc8,  0x3b,  0xd4,  
+   0x27,  0x04,  0x25,  0x10,  0x97,  0x2f,  0xe7,  0x90,  
+   0x6d,  0xc0,  0x28,  0x42,  0x99,  0xd7,  0x4c,  0x43,  
+   0xde,  0xc3,  0xf5,  0x21,  0x6d,  0x54,  0x9f,  0x5d,  
+   0xc3,  0x58,  0xe1,  0xc0,  0xe4,  0xd9,  0x5b,  0xb0,  
+   0xb8,  0xdc,  0xb4,  0x7b,  0xdf,  0x36,  0x3a,  0xc2,  
+   0xb5,  0x66,  0x22,  0x12,  0xd6,  0x87,  0x0d,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+const CSSM_DATA serverbasic_pubKey = { 140, (uint8 *)serverbasic_pubKey_bytes };
+
+
+/***********************
+Cert File Name: serverpremium.crt
+Subject Name       :
+    Country        : ZA
+    State          : Western Cape
+    Locality       : Cape Town
+    Org            : Thawte Consulting cc
+    OrgUnit        : Certification Services Division
+    Common Name    : Thawte Premium Server CA
+    Email addrs    : premium-server@thawte.com
+ ***********************/
+static const uint8 serverpremium_subject_bytes[] = {
+   0x30,  0x81,  0xce,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x5a,  0x41,  
+   0x31,  0x15,  0x30,  0x13,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x0c,  0x57,  0x45,  0x53,  0x54,  0x45,  
+   0x52,  0x4e,  0x20,  0x43,  0x41,  0x50,  0x45,  0x31,  
+   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x07,  
+   0x13,  0x09,  0x43,  0x41,  0x50,  0x45,  0x20,  0x54,  
+   0x4f,  0x57,  0x4e,  0x31,  0x1d,  0x30,  0x1b,  0x06,  
+   0x03,  0x55,  0x04,  0x0a,  0x13,  0x14,  0x54,  0x48,  
+   0x41,  0x57,  0x54,  0x45,  0x20,  0x43,  0x4f,  0x4e,  
+   0x53,  0x55,  0x4c,  0x54,  0x49,  0x4e,  0x47,  0x20,  
+   0x43,  0x43,  0x31,  0x28,  0x30,  0x26,  0x06,  0x03,  
+   0x55,  0x04,  0x0b,  0x13,  0x1f,  0x43,  0x45,  0x52,  
+   0x54,  0x49,  0x46,  0x49,  0x43,  0x41,  0x54,  0x49,  
+   0x4f,  0x4e,  0x20,  0x53,  0x45,  0x52,  0x56,  0x49,  
+   0x43,  0x45,  0x53,  0x20,  0x44,  0x49,  0x56,  0x49,  
+   0x53,  0x49,  0x4f,  0x4e,  0x31,  0x21,  0x30,  0x1f,  
+   0x06,  0x03,  0x55,  0x04,  0x03,  0x13,  0x18,  0x54,  
+   0x48,  0x41,  0x57,  0x54,  0x45,  0x20,  0x50,  0x52,  
+   0x45,  0x4d,  0x49,  0x55,  0x4d,  0x20,  0x53,  0x45,  
+   0x52,  0x56,  0x45,  0x52,  0x20,  0x43,  0x41,  0x31,  
+   0x28,  0x30,  0x26,  0x06,  0x09,  0x2a,  0x86,  0x48,  
+   0x86,  0xf7,  0x0d,  0x01,  0x09,  0x01,  0x16,  0x19,  
+   0x70,  0x72,  0x65,  0x6d,  0x69,  0x75,  0x6d,  0x2d,  
+   0x73,  0x65,  0x72,  0x76,  0x65,  0x72,  0x40,  0x74,  
+   0x68,  0x61,  0x77,  0x74,  0x65,  0x2e,  0x63,  0x6f,  
+   0x6d
+};
+const CSSM_DATA serverpremium_subject = { 209, (uint8 *)serverpremium_subject_bytes };
+static const uint8 serverpremium_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xd2,  
+   0x36,  0x36,  0x6a,  0x8b,  0xd7,  0xc2,  0x5b,  0x9e,  
+   0xda,  0x81,  0x41,  0x62,  0x8f,  0x38,  0xee,  0x49,  
+   0x04,  0x55,  0xd6,  0xd0,  0xef,  0x1c,  0x1b,  0x95,  
+   0x16,  0x47,  0xef,  0x18,  0x48,  0x35,  0x3a,  0x52,  
+   0xf4,  0x2b,  0x6a,  0x06,  0x8f,  0x3b,  0x2f,  0xea,  
+   0x56,  0xe3,  0xaf,  0x86,  0x8d,  0x9e,  0x17,  0xf7,  
+   0x9e,  0xb4,  0x65,  0x75,  0x02,  0x4d,  0xef,  0xcb,  
+   0x09,  0xa2,  0x21,  0x51,  0xd8,  0x9b,  0xd0,  0x67,  
+   0xd0,  0xba,  0x0d,  0x92,  0x06,  0x14,  0x73,  0xd4,  
+   0x93,  0xcb,  0x97,  0x2a,  0x00,  0x9c,  0x5c,  0x4e,  
+   0x0c,  0xbc,  0xfa,  0x15,  0x52,  0xfc,  0xf2,  0x44,  
+   0x6e,  0xda,  0x11,  0x4a,  0x6e,  0x08,  0x9f,  0x2f,  
+   0x2d,  0xe3,  0xf9,  0xaa,  0x3a,  0x86,  0x73,  0xb6,  
+   0x46,  0x53,  0x58,  0xc8,  0x89,  0x05,  0xbd,  0x83,  
+   0x11,  0xb8,  0x73,  0x3f,  0xaa,  0x07,  0x8d,  0xf4,  
+   0x42,  0x4d,  0xe7,  0x40,  0x9d,  0x1c,  0x37,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+const CSSM_DATA serverpremium_pubKey = { 140, (uint8 *)serverpremium_pubKey_bytes };
+
+
+/***********************
+Cert File Name: PCA3ss_v4.cer
+Subject Name       :
+    Country        : US
+    Org            : VeriSign, Inc.
+    OrgUnit        : Class 3 Public Primary Certification Authority
+ ***********************/
+static const uint8 PCA3ss_v4_subject_bytes[] = {
+   0x30,  0x5f,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x17,  0x30,  0x15,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0e,  0x56,  0x45,  0x52,  0x49,  0x53,  0x49,  
+   0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  0x2e,  
+   0x31,  0x37,  0x30,  0x35,  0x06,  0x03,  0x55,  0x04,  
+   0x0b,  0x13,  0x2e,  0x43,  0x4c,  0x41,  0x53,  0x53,  
+   0x20,  0x33,  0x20,  0x50,  0x55,  0x42,  0x4c,  0x49,  
+   0x43,  0x20,  0x50,  0x52,  0x49,  0x4d,  0x41,  0x52,  
+   0x59,  0x20,  0x43,  0x45,  0x52,  0x54,  0x49,  0x46,  
+   0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  0x20,  
+   0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  0x54,  
+   0x59
+};
+const CSSM_DATA PCA3ss_v4_subject = { 97, (uint8 *)PCA3ss_v4_subject_bytes };
+static const uint8 PCA3ss_v4_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xc9,  
+   0x5c,  0x59,  0x9e,  0xf2,  0x1b,  0x8a,  0x01,  0x14,  
+   0xb4,  0x10,  0xdf,  0x04,  0x40,  0xdb,  0xe3,  0x57,  
+   0xaf,  0x6a,  0x45,  0x40,  0x8f,  0x84,  0x0c,  0x0b,  
+   0xd1,  0x33,  0xd9,  0xd9,  0x11,  0xcf,  0xee,  0x02,  
+   0x58,  0x1f,  0x25,  0xf7,  0x2a,  0xa8,  0x44,  0x05,  
+   0xaa,  0xec,  0x03,  0x1f,  0x78,  0x7f,  0x9e,  0x93,  
+   0xb9,  0x9a,  0x00,  0xaa,  0x23,  0x7d,  0xd6,  0xac,  
+   0x85,  0xa2,  0x63,  0x45,  0xc7,  0x72,  0x27,  0xcc,  
+   0xf4,  0x4c,  0xc6,  0x75,  0x71,  0xd2,  0x39,  0xef,  
+   0x4f,  0x42,  0xf0,  0x75,  0xdf,  0x0a,  0x90,  0xc6,  
+   0x8e,  0x20,  0x6f,  0x98,  0x0f,  0xf8,  0xac,  0x23,  
+   0x5f,  0x70,  0x29,  0x36,  0xa4,  0xc9,  0x86,  0xe7,  
+   0xb1,  0x9a,  0x20,  0xcb,  0x53,  0xa5,  0x85,  0xe7,  
+   0x3d,  0xbe,  0x7d,  0x9a,  0xfe,  0x24,  0x45,  0x33,  
+   0xdc,  0x76,  0x15,  0xed,  0x0f,  0xa2,  0x71,  0x64,  
+   0x4c,  0x65,  0x2e,  0x81,  0x68,  0x45,  0xa7,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+const CSSM_DATA PCA3ss_v4_pubKey = { 140, (uint8 *)PCA3ss_v4_pubKey_bytes };
+
+
+/* end of static data generated by extractCertFields */
+
+const tpRootCert iSignRootCerts[] = {
+    { &serverbasic_subject, &serverbasic_pubKey, 1024 },
+    { &serverpremium_subject, &serverpremium_pubKey, 1024 },
+    { &PCA3ss_v4_subject, &PCA3ss_v4_pubKey, 1024 }
+};
+
+unsigned const numiSignRootCerts = sizeof(iSignRootCerts) / sizeof(tpRootCert);
diff --git a/AppleX509TP/rootCerts.h b/AppleX509TP/rootCerts.h
new file mode 100644
index 00000000..47a349eb
--- /dev/null
+++ b/AppleX509TP/rootCerts.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		rootCerts.h
+
+	Contains:	embedded iSign and SSL root certs - subject name 
+				and public keys
+
+	Written by:	Doug Mitchell. 
+
+	Copyright:	Copyright 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_TP_ROOT_CERTS_H_
+#define _TP_ROOT_CERTS_H_
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern	"C" {
+#endif /* __cplusplus */
+
+/*
+ * Each one of these represents one known root cert.
+ */
+typedef struct {
+	const CSSM_DATA * const	subjectName;	// normalized and DER-encoded
+	const CSSM_DATA * const	publicKey;		// DER-encoded
+	uint32 					keySize;
+} tpRootCert;
+
+extern const tpRootCert iSignRootCerts[];
+extern const unsigned numiSignRootCerts;
+
+extern const tpRootCert sslRootCerts[];
+extern const unsigned numSslRootCerts;
+
+/* These certs are shared by SSL and iSign */
+extern const CSSM_DATA serverpremium_pubKey;
+extern const CSSM_DATA serverpremium_subject;
+extern const CSSM_DATA serverbasic_pubKey;
+extern const CSSM_DATA serverbasic_subject;
+extern const CSSM_DATA PCA3ss_v4_pubKey;
+extern const CSSM_DATA PCA3ss_v4_subject;
+
+#define ENABLE_APPLE_DEBUG_ROOT		0
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif	/* _TP_ROOT_CERTS_H_ */
\ No newline at end of file
diff --git a/AppleX509TP/sslRootCerts.c b/AppleX509TP/sslRootCerts.c
new file mode 100644
index 00000000..51d58253
--- /dev/null
+++ b/AppleX509TP/sslRootCerts.c
@@ -0,0 +1,1426 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslRootCerts.c
+
+	Contains:	embedded SSL root certs - subject name and public keys 
+
+	Written by:	Doug Mitchell. 
+
+	Copyright:	Copyright 2000 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include <Security/cssmtype.h>
+#include "rootCerts.h"
+
+
+/***********************
+Cert File Name: Class1_PCA_G2_v2.cer
+Subject Name       :
+    Country        : US
+    Org            : VeriSign, Inc.
+    OrgUnit        : Class 1 Public Primary Certification Authority - G2
+    OrgUnit        : (c) 1998 VeriSign, Inc. - For authorized use only
+    OrgUnit        : VeriSign Trust Network
+ ***********************/
+static const uint8 Class1_PCA_G2_v2_subject_bytes[] = {
+   0x30,  0x81,  0xc1,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  
+   0x31,  0x17,  0x30,  0x15,  0x06,  0x03,  0x55,  0x04,  
+   0x0a,  0x13,  0x0e,  0x56,  0x45,  0x52,  0x49,  0x53,  
+   0x49,  0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x31,  0x3c,  0x30,  0x3a,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x33,  0x43,  0x4c,  0x41,  0x53,  
+   0x53,  0x20,  0x31,  0x20,  0x50,  0x55,  0x42,  0x4c,  
+   0x49,  0x43,  0x20,  0x50,  0x52,  0x49,  0x4d,  0x41,  
+   0x52,  0x59,  0x20,  0x43,  0x45,  0x52,  0x54,  0x49,  
+   0x46,  0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  
+   0x20,  0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x2d,  0x20,  0x47,  0x32,  0x31,  
+   0x3a,  0x30,  0x38,  0x06,  0x03,  0x55,  0x04,  0x0b,  
+   0x13,  0x31,  0x28,  0x43,  0x29,  0x20,  0x31,  0x39,  
+   0x39,  0x38,  0x20,  0x56,  0x45,  0x52,  0x49,  0x53,  
+   0x49,  0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x20,  0x2d,  0x20,  0x46,  0x4f,  0x52,  0x20,  
+   0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  0x5a,  
+   0x45,  0x44,  0x20,  0x55,  0x53,  0x45,  0x20,  0x4f,  
+   0x4e,  0x4c,  0x59,  0x31,  0x1f,  0x30,  0x1d,  0x06,  
+   0x03,  0x55,  0x04,  0x0b,  0x13,  0x16,  0x56,  0x45,  
+   0x52,  0x49,  0x53,  0x49,  0x47,  0x4e,  0x20,  0x54,  
+   0x52,  0x55,  0x53,  0x54,  0x20,  0x4e,  0x45,  0x54,  
+   0x57,  0x4f,  0x52,  0x4b
+};
+static const CSSM_DATA Class1_PCA_G2_v2_subject = { 196, (uint8 *)Class1_PCA_G2_v2_subject_bytes };
+static const uint8 Class1_PCA_G2_v2_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xaa,  
+   0xd0,  0xba,  0xbe,  0x16,  0x2d,  0xb8,  0x83,  0xd4,  
+   0xca,  0xd2,  0x0f,  0xbc,  0x76,  0x31,  0xca,  0x94,  
+   0xd8,  0x1d,  0x93,  0x8c,  0x56,  0x02,  0xbc,  0xd9,  
+   0x6f,  0x1a,  0x6f,  0x52,  0x36,  0x6e,  0x75,  0x56,  
+   0x0a,  0x55,  0xd3,  0xdf,  0x43,  0x87,  0x21,  0x11,  
+   0x65,  0x8a,  0x7e,  0x8f,  0xbd,  0x21,  0xde,  0x6b,  
+   0x32,  0x3f,  0x1b,  0x84,  0x34,  0x95,  0x05,  0x9d,  
+   0x41,  0x35,  0xeb,  0x92,  0xeb,  0x96,  0xdd,  0xaa,  
+   0x59,  0x3f,  0x01,  0x53,  0x6d,  0x99,  0x4f,  0xed,  
+   0xe5,  0xe2,  0x2a,  0x5a,  0x90,  0xc1,  0xb9,  0xc4,  
+   0xa6,  0x15,  0xcf,  0xc8,  0x45,  0xeb,  0xa6,  0x5d,  
+   0x8e,  0x9c,  0x3e,  0xf0,  0x64,  0x24,  0x76,  0xa5,  
+   0xcd,  0xab,  0x1a,  0x6f,  0xb6,  0xd8,  0x7b,  0x51,  
+   0x61,  0x6e,  0xa6,  0x7f,  0x87,  0xc8,  0xe2,  0xb7,  
+   0xe5,  0x34,  0xdc,  0x41,  0x88,  0xea,  0x09,  0x40,  
+   0xbe,  0x73,  0x92,  0x3d,  0x6b,  0xe7,  0x75,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA Class1_PCA_G2_v2_pubKey = { 140, (uint8 *)Class1_PCA_G2_v2_pubKey_bytes };
+
+
+/***********************
+Cert File Name: Class2_PCA_G2_v2.cer
+Subject Name       :
+    Country        : US
+    Org            : VeriSign, Inc.
+    OrgUnit        : Class 2 Public Primary Certification Authority - G2
+    OrgUnit        : (c) 1998 VeriSign, Inc. - For authorized use only
+    OrgUnit        : VeriSign Trust Network
+ ***********************/
+static const uint8 Class2_PCA_G2_v2_subject_bytes[] = {
+   0x30,  0x81,  0xc1,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  
+   0x31,  0x17,  0x30,  0x15,  0x06,  0x03,  0x55,  0x04,  
+   0x0a,  0x13,  0x0e,  0x56,  0x45,  0x52,  0x49,  0x53,  
+   0x49,  0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x31,  0x3c,  0x30,  0x3a,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x33,  0x43,  0x4c,  0x41,  0x53,  
+   0x53,  0x20,  0x32,  0x20,  0x50,  0x55,  0x42,  0x4c,  
+   0x49,  0x43,  0x20,  0x50,  0x52,  0x49,  0x4d,  0x41,  
+   0x52,  0x59,  0x20,  0x43,  0x45,  0x52,  0x54,  0x49,  
+   0x46,  0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  
+   0x20,  0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x2d,  0x20,  0x47,  0x32,  0x31,  
+   0x3a,  0x30,  0x38,  0x06,  0x03,  0x55,  0x04,  0x0b,  
+   0x13,  0x31,  0x28,  0x43,  0x29,  0x20,  0x31,  0x39,  
+   0x39,  0x38,  0x20,  0x56,  0x45,  0x52,  0x49,  0x53,  
+   0x49,  0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x20,  0x2d,  0x20,  0x46,  0x4f,  0x52,  0x20,  
+   0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  0x5a,  
+   0x45,  0x44,  0x20,  0x55,  0x53,  0x45,  0x20,  0x4f,  
+   0x4e,  0x4c,  0x59,  0x31,  0x1f,  0x30,  0x1d,  0x06,  
+   0x03,  0x55,  0x04,  0x0b,  0x13,  0x16,  0x56,  0x45,  
+   0x52,  0x49,  0x53,  0x49,  0x47,  0x4e,  0x20,  0x54,  
+   0x52,  0x55,  0x53,  0x54,  0x20,  0x4e,  0x45,  0x54,  
+   0x57,  0x4f,  0x52,  0x4b
+};
+static const CSSM_DATA Class2_PCA_G2_v2_subject = { 196, (uint8 *)Class2_PCA_G2_v2_subject_bytes };
+static const uint8 Class2_PCA_G2_v2_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xa7,  
+   0x88,  0x01,  0x21,  0x74,  0x2c,  0xe7,  0x1a,  0x03,  
+   0xf0,  0x98,  0xe1,  0x97,  0x3c,  0x0f,  0x21,  0x08,  
+   0xf1,  0x9c,  0xdb,  0x97,  0xe9,  0x9a,  0xfc,  0xc2,  
+   0x04,  0x06,  0x13,  0xbe,  0x5f,  0x52,  0xc8,  0xcc,  
+   0x1e,  0x2c,  0x12,  0x56,  0x2c,  0xb8,  0x01,  0x69,  
+   0x2c,  0xcc,  0x99,  0x1f,  0xad,  0xb0,  0x96,  0xae,  
+   0x79,  0x04,  0xf2,  0x13,  0x39,  0xc1,  0x7b,  0x98,  
+   0xba,  0x08,  0x2c,  0xe8,  0xc2,  0x84,  0x13,  0x2c,  
+   0xaa,  0x69,  0xe9,  0x09,  0xf4,  0xc7,  0xa9,  0x02,  
+   0xa4,  0x42,  0xc2,  0x23,  0x4f,  0x4a,  0xd8,  0xf0,  
+   0x0e,  0xa2,  0xfb,  0x31,  0x6c,  0xc9,  0xe6,  0x6f,  
+   0x99,  0x27,  0x07,  0xf5,  0xe6,  0xf4,  0x4c,  0x78,  
+   0x9e,  0x6d,  0xeb,  0x46,  0x86,  0xfa,  0xb9,  0x86,  
+   0xc9,  0x54,  0xf2,  0xb2,  0xc4,  0xaf,  0xd4,  0x46,  
+   0x1c,  0x5a,  0xc9,  0x15,  0x30,  0xff,  0x0d,  0x6c,  
+   0xf5,  0x2d,  0x0e,  0x6d,  0xce,  0x7f,  0x77,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA Class2_PCA_G2_v2_pubKey = { 140, (uint8 *)Class2_PCA_G2_v2_pubKey_bytes };
+
+
+/***********************
+Cert File Name: Class3_PCA_G2_v2.cer
+Subject Name       :
+    Country        : US
+    Org            : VeriSign, Inc.
+    OrgUnit        : Class 3 Public Primary Certification Authority - G2
+    OrgUnit        : (c) 1998 VeriSign, Inc. - For authorized use only
+    OrgUnit        : VeriSign Trust Network
+ ***********************/
+static const uint8 Class3_PCA_G2_v2_subject_bytes[] = {
+   0x30,  0x81,  0xc1,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  
+   0x31,  0x17,  0x30,  0x15,  0x06,  0x03,  0x55,  0x04,  
+   0x0a,  0x13,  0x0e,  0x56,  0x45,  0x52,  0x49,  0x53,  
+   0x49,  0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x31,  0x3c,  0x30,  0x3a,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x33,  0x43,  0x4c,  0x41,  0x53,  
+   0x53,  0x20,  0x33,  0x20,  0x50,  0x55,  0x42,  0x4c,  
+   0x49,  0x43,  0x20,  0x50,  0x52,  0x49,  0x4d,  0x41,  
+   0x52,  0x59,  0x20,  0x43,  0x45,  0x52,  0x54,  0x49,  
+   0x46,  0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  
+   0x20,  0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x2d,  0x20,  0x47,  0x32,  0x31,  
+   0x3a,  0x30,  0x38,  0x06,  0x03,  0x55,  0x04,  0x0b,  
+   0x13,  0x31,  0x28,  0x43,  0x29,  0x20,  0x31,  0x39,  
+   0x39,  0x38,  0x20,  0x56,  0x45,  0x52,  0x49,  0x53,  
+   0x49,  0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x20,  0x2d,  0x20,  0x46,  0x4f,  0x52,  0x20,  
+   0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  0x5a,  
+   0x45,  0x44,  0x20,  0x55,  0x53,  0x45,  0x20,  0x4f,  
+   0x4e,  0x4c,  0x59,  0x31,  0x1f,  0x30,  0x1d,  0x06,  
+   0x03,  0x55,  0x04,  0x0b,  0x13,  0x16,  0x56,  0x45,  
+   0x52,  0x49,  0x53,  0x49,  0x47,  0x4e,  0x20,  0x54,  
+   0x52,  0x55,  0x53,  0x54,  0x20,  0x4e,  0x45,  0x54,  
+   0x57,  0x4f,  0x52,  0x4b
+};
+static const CSSM_DATA Class3_PCA_G2_v2_subject = { 196, (uint8 *)Class3_PCA_G2_v2_subject_bytes };
+static const uint8 Class3_PCA_G2_v2_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xcc,  
+   0x5e,  0xd1,  0x11,  0x5d,  0x5c,  0x69,  0xd0,  0xab,  
+   0xd3,  0xb9,  0x6a,  0x4c,  0x99,  0x1f,  0x59,  0x98,  
+   0x30,  0x8e,  0x16,  0x85,  0x20,  0x46,  0x6d,  0x47,  
+   0x3f,  0xd4,  0x85,  0x20,  0x84,  0xe1,  0x6d,  0xb3,  
+   0xf8,  0xa4,  0xed,  0x0c,  0xf1,  0x17,  0x0f,  0x3b,  
+   0xf9,  0xa7,  0xf9,  0x25,  0xd7,  0xc1,  0xcf,  0x84,  
+   0x63,  0xf2,  0x7c,  0x63,  0xcf,  0xa2,  0x47,  0xf2,  
+   0xc6,  0x5b,  0x33,  0x8e,  0x64,  0x40,  0x04,  0x68,  
+   0xc1,  0x80,  0xb9,  0x64,  0x1c,  0x45,  0x77,  0xc7,  
+   0xd8,  0x6e,  0xf5,  0x95,  0x29,  0x3c,  0x50,  0xe8,  
+   0x34,  0xd7,  0x78,  0x1f,  0xa8,  0xba,  0x6d,  0x43,  
+   0x91,  0x95,  0x8f,  0x45,  0x57,  0x5e,  0x7e,  0xc5,  
+   0xfb,  0xca,  0xa4,  0x04,  0xeb,  0xea,  0x97,  0x37,  
+   0x54,  0x30,  0x6f,  0xbb,  0x01,  0x47,  0x32,  0x33,  
+   0xcd,  0xdc,  0x57,  0x9b,  0x64,  0x69,  0x61,  0xf8,  
+   0x9b,  0x1d,  0x1c,  0x89,  0x4f,  0x5c,  0x67,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA Class3_PCA_G2_v2_pubKey = { 140, (uint8 *)Class3_PCA_G2_v2_pubKey_bytes };
+
+
+/***********************
+Cert File Name: Class4_PCA_G2_v2.cer
+Subject Name       :
+    Country        : US
+    Org            : VeriSign, Inc.
+    OrgUnit        : Class 4 Public Primary Certification Authority - G2
+    OrgUnit        : (c) 1998 VeriSign, Inc. - For authorized use only
+    OrgUnit        : VeriSign Trust Network
+ ***********************/
+static const uint8 Class4_PCA_G2_v2_subject_bytes[] = {
+   0x30,  0x81,  0xc1,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  
+   0x31,  0x17,  0x30,  0x15,  0x06,  0x03,  0x55,  0x04,  
+   0x0a,  0x13,  0x0e,  0x56,  0x45,  0x52,  0x49,  0x53,  
+   0x49,  0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x31,  0x3c,  0x30,  0x3a,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x33,  0x43,  0x4c,  0x41,  0x53,  
+   0x53,  0x20,  0x34,  0x20,  0x50,  0x55,  0x42,  0x4c,  
+   0x49,  0x43,  0x20,  0x50,  0x52,  0x49,  0x4d,  0x41,  
+   0x52,  0x59,  0x20,  0x43,  0x45,  0x52,  0x54,  0x49,  
+   0x46,  0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  
+   0x20,  0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x2d,  0x20,  0x47,  0x32,  0x31,  
+   0x3a,  0x30,  0x38,  0x06,  0x03,  0x55,  0x04,  0x0b,  
+   0x13,  0x31,  0x28,  0x43,  0x29,  0x20,  0x31,  0x39,  
+   0x39,  0x38,  0x20,  0x56,  0x45,  0x52,  0x49,  0x53,  
+   0x49,  0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x20,  0x2d,  0x20,  0x46,  0x4f,  0x52,  0x20,  
+   0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  0x5a,  
+   0x45,  0x44,  0x20,  0x55,  0x53,  0x45,  0x20,  0x4f,  
+   0x4e,  0x4c,  0x59,  0x31,  0x1f,  0x30,  0x1d,  0x06,  
+   0x03,  0x55,  0x04,  0x0b,  0x13,  0x16,  0x56,  0x45,  
+   0x52,  0x49,  0x53,  0x49,  0x47,  0x4e,  0x20,  0x54,  
+   0x52,  0x55,  0x53,  0x54,  0x20,  0x4e,  0x45,  0x54,  
+   0x57,  0x4f,  0x52,  0x4b
+};
+static const CSSM_DATA Class4_PCA_G2_v2_subject = { 196, (uint8 *)Class4_PCA_G2_v2_subject_bytes };
+static const uint8 Class4_PCA_G2_v2_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xba,  
+   0xf0,  0xe4,  0xcf,  0xf9,  0xc4,  0xae,  0x85,  0x54,  
+   0xb9,  0x07,  0x57,  0xf9,  0x8f,  0xc5,  0x7f,  0x68,  
+   0x11,  0xf8,  0xc4,  0x17,  0xb0,  0x44,  0xdc,  0xe3,  
+   0x30,  0x73,  0xd5,  0x2a,  0x62,  0x2a,  0xb8,  0xd0,  
+   0xcc,  0x1c,  0xed,  0x28,  0x5b,  0x7e,  0xbd,  0x6a,  
+   0xdc,  0xb3,  0x91,  0x24,  0xca,  0x41,  0x62,  0x3c,  
+   0xfc,  0x02,  0x01,  0xbf,  0x1c,  0x16,  0x31,  0x94,  
+   0x05,  0x97,  0x76,  0x6e,  0xa2,  0xad,  0xbd,  0x61,  
+   0x17,  0x6c,  0x4e,  0x30,  0x86,  0xf0,  0x51,  0x37,  
+   0x2a,  0x50,  0xc7,  0xa8,  0x62,  0x81,  0xdc,  0x5b,  
+   0x4a,  0xaa,  0xc1,  0xa0,  0xb4,  0x6e,  0xeb,  0x2f,  
+   0xe5,  0x57,  0xc5,  0xb1,  0x2b,  0x40,  0x70,  0xdb,  
+   0x5a,  0x4d,  0xa1,  0x8e,  0x1f,  0xbd,  0x03,  0x1f,  
+   0xd8,  0x03,  0xd4,  0x8f,  0x4c,  0x99,  0x71,  0xbc,  
+   0xe2,  0x82,  0xcc,  0x58,  0xe8,  0x98,  0x3a,  0x86,  
+   0xd3,  0x86,  0x38,  0xf3,  0x00,  0x29,  0x1f,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA Class4_PCA_G2_v2_pubKey = { 140, (uint8 *)Class4_PCA_G2_v2_pubKey_bytes };
+
+
+/***********************
+Cert File Name: PCA1ss_v4.cer
+Subject Name       :
+    Country        : US
+    Org            : VeriSign, Inc.
+    OrgUnit        : Class 1 Public Primary Certification Authority
+ ***********************/
+static const uint8 PCA1ss_v4_subject_bytes[] = {
+   0x30,  0x5f,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x17,  0x30,  0x15,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0e,  0x56,  0x45,  0x52,  0x49,  0x53,  0x49,  
+   0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  0x2e,  
+   0x31,  0x37,  0x30,  0x35,  0x06,  0x03,  0x55,  0x04,  
+   0x0b,  0x13,  0x2e,  0x43,  0x4c,  0x41,  0x53,  0x53,  
+   0x20,  0x31,  0x20,  0x50,  0x55,  0x42,  0x4c,  0x49,  
+   0x43,  0x20,  0x50,  0x52,  0x49,  0x4d,  0x41,  0x52,  
+   0x59,  0x20,  0x43,  0x45,  0x52,  0x54,  0x49,  0x46,  
+   0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  0x20,  
+   0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  0x54,  
+   0x59
+};
+static const CSSM_DATA PCA1ss_v4_subject = { 97, (uint8 *)PCA1ss_v4_subject_bytes };
+static const uint8 PCA1ss_v4_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xe5,  
+   0x19,  0xbf,  0x6d,  0xa3,  0x56,  0x61,  0x2d,  0x99,  
+   0x48,  0x71,  0xf6,  0x67,  0xde,  0xb9,  0x8d,  0xeb,  
+   0xb7,  0x9e,  0x86,  0x80,  0x0a,  0x91,  0x0e,  0xfa,  
+   0x38,  0x25,  0xaf,  0x46,  0x88,  0x82,  0xe5,  0x73,  
+   0xa8,  0xa0,  0x9b,  0x24,  0x5d,  0x0d,  0x1f,  0xcc,  
+   0x65,  0x6e,  0x0c,  0xb0,  0xd0,  0x56,  0x84,  0x18,  
+   0x87,  0x9a,  0x06,  0x9b,  0x10,  0xa1,  0x73,  0xdf,  
+   0xb4,  0x58,  0x39,  0x6b,  0x6e,  0xc1,  0xf6,  0x15,  
+   0xd5,  0xa8,  0xa8,  0x3f,  0xaa,  0x12,  0x06,  0x8d,  
+   0x31,  0xac,  0x7f,  0xb0,  0x34,  0xd7,  0x8f,  0x34,  
+   0x67,  0x88,  0x09,  0xcd,  0x14,  0x11,  0xe2,  0x4e,  
+   0x45,  0x56,  0x69,  0x1f,  0x78,  0x02,  0x80,  0xda,  
+   0xdc,  0x47,  0x91,  0x29,  0xbb,  0x36,  0xc9,  0x63,  
+   0x5c,  0xc5,  0xe0,  0xd7,  0x2d,  0x87,  0x7b,  0xa1,  
+   0xb7,  0x32,  0xb0,  0x7b,  0x30,  0xba,  0x2a,  0x2f,  
+   0x31,  0xaa,  0xee,  0xa3,  0x67,  0xda,  0xdb,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA PCA1ss_v4_pubKey = { 140, (uint8 *)PCA1ss_v4_pubKey_bytes };
+
+
+/***********************
+Cert File Name: PCA2ss_v4.cer
+Subject Name       :
+    Country        : US
+    Org            : VeriSign, Inc.
+    OrgUnit        : Class 2 Public Primary Certification Authority
+ ***********************/
+static const uint8 PCA2ss_v4_subject_bytes[] = {
+   0x30,  0x5f,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x17,  0x30,  0x15,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0e,  0x56,  0x45,  0x52,  0x49,  0x53,  0x49,  
+   0x47,  0x4e,  0x2c,  0x20,  0x49,  0x4e,  0x43,  0x2e,  
+   0x31,  0x37,  0x30,  0x35,  0x06,  0x03,  0x55,  0x04,  
+   0x0b,  0x13,  0x2e,  0x43,  0x4c,  0x41,  0x53,  0x53,  
+   0x20,  0x32,  0x20,  0x50,  0x55,  0x42,  0x4c,  0x49,  
+   0x43,  0x20,  0x50,  0x52,  0x49,  0x4d,  0x41,  0x52,  
+   0x59,  0x20,  0x43,  0x45,  0x52,  0x54,  0x49,  0x46,  
+   0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  0x20,  
+   0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  0x54,  
+   0x59
+};
+static const CSSM_DATA PCA2ss_v4_subject = { 97, (uint8 *)PCA2ss_v4_subject_bytes };
+static const uint8 PCA2ss_v4_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xb6,  
+   0x5a,  0x8b,  0xa3,  0x0d,  0x6a,  0x23,  0x83,  0x80,  
+   0x6b,  0xcf,  0x39,  0x87,  0xf4,  0x21,  0x13,  0x33,  
+   0x06,  0x4c,  0x25,  0xa2,  0xed,  0x55,  0x12,  0x97,  
+   0xc5,  0xa7,  0x80,  0xb9,  0xfa,  0x83,  0xc1,  0x20,  
+   0xa0,  0xfa,  0x2f,  0x15,  0x0d,  0x7c,  0xa1,  0x60,  
+   0x6b,  0x7e,  0x79,  0x2c,  0xfa,  0x06,  0x0f,  0x3a,  
+   0xae,  0xf6,  0x1b,  0x6f,  0xb1,  0xd2,  0xff,  0x2f,  
+   0x28,  0x52,  0x5f,  0x83,  0x7d,  0x4b,  0xc4,  0x7a,  
+   0xb7,  0xf8,  0x66,  0x1f,  0x80,  0x54,  0xfc,  0xb7,  
+   0xc2,  0x8e,  0x59,  0x4a,  0x14,  0x57,  0x46,  0xd1,  
+   0x9a,  0x93,  0xbe,  0x41,  0x91,  0x03,  0xbb,  0x15,  
+   0x80,  0x93,  0x5c,  0xeb,  0xe7,  0xcc,  0x08,  0x6c,  
+   0x3f,  0x3e,  0xb3,  0x4a,  0xfc,  0xff,  0x4b,  0x6c,  
+   0x23,  0xd5,  0x50,  0x82,  0x26,  0x44,  0x19,  0x8e,  
+   0x23,  0xc3,  0x71,  0xea,  0x19,  0x24,  0x47,  0x04,  
+   0x9e,  0x75,  0xbf,  0xc8,  0xa6,  0x00,  0x1f,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA PCA2ss_v4_pubKey = { 140, (uint8 *)PCA2ss_v4_pubKey_bytes };
+
+/***********************
+Cert File Name: RSASecureServer.cer
+Subject Name       :
+    Country        : US
+    Org            : RSA Data Security, Inc.
+    OrgUnit        : Secure Server Certification Authority
+ ***********************/
+static const uint8 RSASecureServer_subject_bytes[] = {
+   0x30,  0x5f,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x20,  0x30,  0x1e,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x17,  0x52,  0x53,  0x41,  0x20,  0x44,  0x41,  
+   0x54,  0x41,  0x20,  0x53,  0x45,  0x43,  0x55,  0x52,  
+   0x49,  0x54,  0x59,  0x2c,  0x20,  0x49,  0x4e,  0x43,  
+   0x2e,  0x31,  0x2e,  0x30,  0x2c,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x25,  0x53,  0x45,  0x43,  0x55,  
+   0x52,  0x45,  0x20,  0x53,  0x45,  0x52,  0x56,  0x45,  
+   0x52,  0x20,  0x43,  0x45,  0x52,  0x54,  0x49,  0x46,  
+   0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  0x20,  
+   0x41,  0x55,  0x54,  0x48,  0x4f,  0x52,  0x49,  0x54,  
+   0x59
+};
+static const CSSM_DATA RSASecureServer_subject = { 97, (uint8 *)RSASecureServer_subject_bytes };
+static const uint8 RSASecureServer_pubKey_bytes[] = {
+   0x30,  0x81,  0x85,  0x02,  0x7e,  0x00,  0x92,  0xce,  
+   0x7a,  0xc1,  0xae,  0x83,  0x3e,  0x5a,  0xaa,  0x89,  
+   0x83,  0x57,  0xac,  0x25,  0x01,  0x76,  0x0c,  0xad,  
+   0xae,  0x8e,  0x2c,  0x37,  0xce,  0xeb,  0x35,  0x78,  
+   0x64,  0x54,  0x03,  0xe5,  0x84,  0x40,  0x51,  0xc9,  
+   0xbf,  0x8f,  0x08,  0xe2,  0x8a,  0x82,  0x08,  0xd2,  
+   0x16,  0x86,  0x37,  0x55,  0xe9,  0xb1,  0x21,  0x02,  
+   0xad,  0x76,  0x68,  0x81,  0x9a,  0x05,  0xa2,  0x4b,  
+   0xc9,  0x4b,  0x25,  0x66,  0x22,  0x56,  0x6c,  0x88,  
+   0x07,  0x8f,  0xf7,  0x81,  0x59,  0x6d,  0x84,  0x07,  
+   0x65,  0x70,  0x13,  0x71,  0x76,  0x3e,  0x9b,  0x77,  
+   0x4c,  0xe3,  0x50,  0x89,  0x56,  0x98,  0x48,  0xb9,  
+   0x1d,  0xa7,  0x29,  0x1a,  0x13,  0x2e,  0x4a,  0x11,  
+   0x59,  0x9c,  0x1e,  0x15,  0xd5,  0x49,  0x54,  0x2c,  
+   0x73,  0x3a,  0x69,  0x82,  0xb1,  0x97,  0x39,  0x9c,  
+   0x6d,  0x70,  0x67,  0x48,  0xe5,  0xdd,  0x2d,  0xd6,  
+   0xc8,  0x1e,  0x7b,  0x02,  0x03,  0x01,  0x00,  0x01
+   
+};
+static const CSSM_DATA RSASecureServer_pubKey = { 136, (uint8 *)RSASecureServer_pubKey_bytes };
+
+
+/***********************
+Cert File Name: persbasi.crt
+Subject Name       :
+    Country        : ZA
+    State          : Western Cape
+    Locality       : Cape Town
+    Org            : Thawte Consulting
+    OrgUnit        : Certification Services Division
+    Common Name    : Thawte Personal Basic CA
+    Email addrs    : personal-basic@thawte.com
+ ***********************/
+static const uint8 persbasi_subject_bytes[] = {
+   0x30,  0x81,  0xcb,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x5a,  0x41,  
+   0x31,  0x15,  0x30,  0x13,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x0c,  0x57,  0x45,  0x53,  0x54,  0x45,  
+   0x52,  0x4e,  0x20,  0x43,  0x41,  0x50,  0x45,  0x31,  
+   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x07,  
+   0x13,  0x09,  0x43,  0x41,  0x50,  0x45,  0x20,  0x54,  
+   0x4f,  0x57,  0x4e,  0x31,  0x1a,  0x30,  0x18,  0x06,  
+   0x03,  0x55,  0x04,  0x0a,  0x13,  0x11,  0x54,  0x48,  
+   0x41,  0x57,  0x54,  0x45,  0x20,  0x43,  0x4f,  0x4e,  
+   0x53,  0x55,  0x4c,  0x54,  0x49,  0x4e,  0x47,  0x31,  
+   0x28,  0x30,  0x26,  0x06,  0x03,  0x55,  0x04,  0x0b,  
+   0x13,  0x1f,  0x43,  0x45,  0x52,  0x54,  0x49,  0x46,  
+   0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  0x20,  
+   0x53,  0x45,  0x52,  0x56,  0x49,  0x43,  0x45,  0x53,  
+   0x20,  0x44,  0x49,  0x56,  0x49,  0x53,  0x49,  0x4f,  
+   0x4e,  0x31,  0x21,  0x30,  0x1f,  0x06,  0x03,  0x55,  
+   0x04,  0x03,  0x13,  0x18,  0x54,  0x48,  0x41,  0x57,  
+   0x54,  0x45,  0x20,  0x50,  0x45,  0x52,  0x53,  0x4f,  
+   0x4e,  0x41,  0x4c,  0x20,  0x42,  0x41,  0x53,  0x49,  
+   0x43,  0x20,  0x43,  0x41,  0x31,  0x28,  0x30,  0x26,  
+   0x06,  0x09,  0x2a,  0x86,  0x48,  0x86,  0xf7,  0x0d,  
+   0x01,  0x09,  0x01,  0x16,  0x19,  0x70,  0x65,  0x72,  
+   0x73,  0x6f,  0x6e,  0x61,  0x6c,  0x2d,  0x62,  0x61,  
+   0x73,  0x69,  0x63,  0x40,  0x74,  0x68,  0x61,  0x77,  
+   0x74,  0x65,  0x2e,  0x63,  0x6f,  0x6d
+};
+static const CSSM_DATA persbasi_subject = { 206, (uint8 *)persbasi_subject_bytes };
+static const uint8 persbasi_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xbc,  
+   0xbc,  0x93,  0x53,  0x6d,  0xc0,  0x50,  0x4f,  0x82,  
+   0x15,  0xe6,  0x48,  0x94,  0x35,  0xa6,  0x5a,  0xbe,  
+   0x6f,  0x42,  0xfa,  0x0f,  0x47,  0xee,  0x77,  0x75,  
+   0x72,  0xdd,  0x8d,  0x49,  0x9b,  0x96,  0x57,  0xa0,  
+   0x78,  0xd4,  0xca,  0x3f,  0x51,  0xb3,  0x69,  0x0b,  
+   0x91,  0x76,  0x17,  0x22,  0x07,  0x97,  0x6a,  0xc4,  
+   0x51,  0x93,  0x4b,  0xe0,  0x8d,  0xef,  0x37,  0x95,  
+   0xa1,  0x0c,  0x4d,  0xda,  0x34,  0x90,  0x1d,  0x17,  
+   0x89,  0x97,  0xe0,  0x35,  0x38,  0x57,  0x4a,  0xc0,  
+   0xf4,  0x08,  0x70,  0xe9,  0x3c,  0x44,  0x7b,  0x50,  
+   0x7e,  0x61,  0x9a,  0x90,  0xe3,  0x23,  0xd3,  0x88,  
+   0x11,  0x46,  0x27,  0xf5,  0x0b,  0x07,  0x0e,  0xbb,  
+   0xdd,  0xd1,  0x7f,  0x20,  0x0a,  0x88,  0xb9,  0x56,  
+   0x0b,  0x2e,  0x1c,  0x80,  0xda,  0xf1,  0xe3,  0x9e,  
+   0x29,  0xef,  0x14,  0xbd,  0x0a,  0x44,  0xfb,  0x1b,  
+   0x5b,  0x18,  0xd1,  0xbf,  0x23,  0x93,  0x21,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA persbasi_pubKey = { 140, (uint8 *)persbasi_pubKey_bytes };
+
+
+/***********************
+Cert File Name: persfree.crt
+Subject Name       :
+    Country        : ZA
+    State          : Western Cape
+    Locality       : Cape Town
+    Org            : Thawte Consulting
+    OrgUnit        : Certification Services Division
+    Common Name    : Thawte Personal Freemail CA
+    Email addrs    : personal-freemail@thawte.com
+ ***********************/
+static const uint8 persfree_subject_bytes[] = {
+   0x30,  0x81,  0xd1,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x5a,  0x41,  
+   0x31,  0x15,  0x30,  0x13,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x0c,  0x57,  0x45,  0x53,  0x54,  0x45,  
+   0x52,  0x4e,  0x20,  0x43,  0x41,  0x50,  0x45,  0x31,  
+   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x07,  
+   0x13,  0x09,  0x43,  0x41,  0x50,  0x45,  0x20,  0x54,  
+   0x4f,  0x57,  0x4e,  0x31,  0x1a,  0x30,  0x18,  0x06,  
+   0x03,  0x55,  0x04,  0x0a,  0x13,  0x11,  0x54,  0x48,  
+   0x41,  0x57,  0x54,  0x45,  0x20,  0x43,  0x4f,  0x4e,  
+   0x53,  0x55,  0x4c,  0x54,  0x49,  0x4e,  0x47,  0x31,  
+   0x28,  0x30,  0x26,  0x06,  0x03,  0x55,  0x04,  0x0b,  
+   0x13,  0x1f,  0x43,  0x45,  0x52,  0x54,  0x49,  0x46,  
+   0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  0x20,  
+   0x53,  0x45,  0x52,  0x56,  0x49,  0x43,  0x45,  0x53,  
+   0x20,  0x44,  0x49,  0x56,  0x49,  0x53,  0x49,  0x4f,  
+   0x4e,  0x31,  0x24,  0x30,  0x22,  0x06,  0x03,  0x55,  
+   0x04,  0x03,  0x13,  0x1b,  0x54,  0x48,  0x41,  0x57,  
+   0x54,  0x45,  0x20,  0x50,  0x45,  0x52,  0x53,  0x4f,  
+   0x4e,  0x41,  0x4c,  0x20,  0x46,  0x52,  0x45,  0x45,  
+   0x4d,  0x41,  0x49,  0x4c,  0x20,  0x43,  0x41,  0x31,  
+   0x2b,  0x30,  0x29,  0x06,  0x09,  0x2a,  0x86,  0x48,  
+   0x86,  0xf7,  0x0d,  0x01,  0x09,  0x01,  0x16,  0x1c,  
+   0x70,  0x65,  0x72,  0x73,  0x6f,  0x6e,  0x61,  0x6c,  
+   0x2d,  0x66,  0x72,  0x65,  0x65,  0x6d,  0x61,  0x69,  
+   0x6c,  0x40,  0x74,  0x68,  0x61,  0x77,  0x74,  0x65,  
+   0x2e,  0x63,  0x6f,  0x6d
+};
+static const CSSM_DATA persfree_subject = { 212, (uint8 *)persfree_subject_bytes };
+static const uint8 persfree_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xd4,  
+   0x69,  0xd7,  0xd4,  0xb0,  0x94,  0x64,  0x5b,  0x71,  
+   0xe9,  0x47,  0xd8,  0x0c,  0x51,  0xb6,  0xea,  0x72,  
+   0x91,  0xb0,  0x84,  0x5e,  0x7d,  0x2d,  0x0d,  0x8f,  
+   0x7b,  0x12,  0xdf,  0x85,  0x25,  0x75,  0x28,  0x74,  
+   0x3a,  0x42,  0x2c,  0x63,  0x27,  0x9f,  0x95,  0x7b,  
+   0x4b,  0xef,  0x7e,  0x19,  0x87,  0x1d,  0x86,  0xea,  
+   0xa3,  0xdd,  0xb9,  0xce,  0x96,  0x64,  0x1a,  0xc2,  
+   0x14,  0x6e,  0x44,  0xac,  0x7c,  0xe6,  0x8f,  0xe8,  
+   0x4d,  0x0f,  0x71,  0x1f,  0x40,  0x38,  0xa6,  0x00,  
+   0xa3,  0x87,  0x78,  0xf6,  0xf9,  0x94,  0x86,  0x5e,  
+   0xad,  0xea,  0xc0,  0x5e,  0x76,  0xeb,  0xd9,  0x14,  
+   0xa3,  0x5d,  0x6e,  0x7a,  0x7c,  0x0c,  0xa5,  0x4b,  
+   0x55,  0x7f,  0x06,  0x19,  0x29,  0x7f,  0x9e,  0x9a,  
+   0x26,  0xd5,  0x6a,  0xbb,  0x38,  0x24,  0x08,  0x6a,  
+   0x98,  0xc7,  0xb1,  0xda,  0xa3,  0x98,  0x91,  0xfd,  
+   0x79,  0xdb,  0xe5,  0x5a,  0xc4,  0x1c,  0xb9,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA persfree_pubKey = { 140, (uint8 *)persfree_pubKey_bytes };
+
+
+/***********************
+Cert File Name: persprem.crt
+Subject Name       :
+    Country        : ZA
+    State          : Western Cape
+    Locality       : Cape Town
+    Org            : Thawte Consulting
+    OrgUnit        : Certification Services Division
+    Common Name    : Thawte Personal Premium CA
+    Email addrs    : personal-premium@thawte.com
+ ***********************/
+static const uint8 persprem_subject_bytes[] = {
+   0x30,  0x81,  0xcf,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x5a,  0x41,  
+   0x31,  0x15,  0x30,  0x13,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x0c,  0x57,  0x45,  0x53,  0x54,  0x45,  
+   0x52,  0x4e,  0x20,  0x43,  0x41,  0x50,  0x45,  0x31,  
+   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x07,  
+   0x13,  0x09,  0x43,  0x41,  0x50,  0x45,  0x20,  0x54,  
+   0x4f,  0x57,  0x4e,  0x31,  0x1a,  0x30,  0x18,  0x06,  
+   0x03,  0x55,  0x04,  0x0a,  0x13,  0x11,  0x54,  0x48,  
+   0x41,  0x57,  0x54,  0x45,  0x20,  0x43,  0x4f,  0x4e,  
+   0x53,  0x55,  0x4c,  0x54,  0x49,  0x4e,  0x47,  0x31,  
+   0x28,  0x30,  0x26,  0x06,  0x03,  0x55,  0x04,  0x0b,  
+   0x13,  0x1f,  0x43,  0x45,  0x52,  0x54,  0x49,  0x46,  
+   0x49,  0x43,  0x41,  0x54,  0x49,  0x4f,  0x4e,  0x20,  
+   0x53,  0x45,  0x52,  0x56,  0x49,  0x43,  0x45,  0x53,  
+   0x20,  0x44,  0x49,  0x56,  0x49,  0x53,  0x49,  0x4f,  
+   0x4e,  0x31,  0x23,  0x30,  0x21,  0x06,  0x03,  0x55,  
+   0x04,  0x03,  0x13,  0x1a,  0x54,  0x48,  0x41,  0x57,  
+   0x54,  0x45,  0x20,  0x50,  0x45,  0x52,  0x53,  0x4f,  
+   0x4e,  0x41,  0x4c,  0x20,  0x50,  0x52,  0x45,  0x4d,  
+   0x49,  0x55,  0x4d,  0x20,  0x43,  0x41,  0x31,  0x2a,  
+   0x30,  0x28,  0x06,  0x09,  0x2a,  0x86,  0x48,  0x86,  
+   0xf7,  0x0d,  0x01,  0x09,  0x01,  0x16,  0x1b,  0x70,  
+   0x65,  0x72,  0x73,  0x6f,  0x6e,  0x61,  0x6c,  0x2d,  
+   0x70,  0x72,  0x65,  0x6d,  0x69,  0x75,  0x6d,  0x40,  
+   0x74,  0x68,  0x61,  0x77,  0x74,  0x65,  0x2e,  0x63,  
+   0x6f,  0x6d
+};
+static const CSSM_DATA persprem_subject = { 210, (uint8 *)persprem_subject_bytes };
+static const uint8 persprem_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xc9,  
+   0x66,  0xd9,  0xf8,  0x07,  0x44,  0xcf,  0xb9,  0x8c,  
+   0x2e,  0xf0,  0xa1,  0xef,  0x13,  0x45,  0x6c,  0x05,  
+   0xdf,  0xde,  0x27,  0x16,  0x51,  0x36,  0x41,  0x11,  
+   0x6c,  0x6c,  0x3b,  0xed,  0xfe,  0x10,  0x7d,  0x12,  
+   0x9e,  0xe5,  0x9b,  0x42,  0x9a,  0xfe,  0x60,  0x31,  
+   0xc3,  0x66,  0xb7,  0x73,  0x3a,  0x48,  0xae,  0x4e,  
+   0xd0,  0x32,  0x37,  0x94,  0x88,  0xb5,  0x0d,  0xb6,  
+   0xd9,  0xf3,  0xf2,  0x44,  0xd9,  0xd5,  0x88,  0x12,  
+   0xdd,  0x76,  0x4d,  0xf2,  0x1a,  0xfc,  0x6f,  0x23,  
+   0x1e,  0x7a,  0xf1,  0xd8,  0x98,  0x45,  0x4e,  0x07,  
+   0x10,  0xef,  0x16,  0x42,  0xd0,  0x43,  0x75,  0x6d,  
+   0x4a,  0xde,  0xe2,  0xaa,  0xc9,  0x31,  0xff,  0x1f,  
+   0x00,  0x70,  0x7c,  0x66,  0xcf,  0x10,  0x25,  0x08,  
+   0xba,  0xfa,  0xee,  0x00,  0xe9,  0x46,  0x03,  0x66,  
+   0x27,  0x11,  0x15,  0x3b,  0xaa,  0x5b,  0xf2,  0x98,  
+   0xdd,  0x36,  0x42,  0xb2,  0xda,  0x88,  0x75,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA persprem_pubKey = { 140, (uint8 *)persprem_pubKey_bytes };
+
+/***********************
+Cert File Name: GTECyberTrustGlobalRoot.crt
+Subject Name       :
+    Country        : US
+    Org            : GTE Corporation
+    OrgUnit        : GTE CyberTrust Solutions, Inc.
+    Common Name    : GTE CyberTrust Global Root
+ ***********************/
+static const uint8 GTECyberTrustGlobalRoot_subject_bytes[] = {
+   0x30,  0x75,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x18,  0x30,  0x16,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0f,  0x47,  0x54,  0x45,  0x20,  0x43,  0x4f,  
+   0x52,  0x50,  0x4f,  0x52,  0x41,  0x54,  0x49,  0x4f,  
+   0x4e,  0x31,  0x27,  0x30,  0x25,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x1e,  0x47,  0x54,  0x45,  0x20,  
+   0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  
+   0x53,  0x54,  0x20,  0x53,  0x4f,  0x4c,  0x55,  0x54,  
+   0x49,  0x4f,  0x4e,  0x53,  0x2c,  0x20,  0x49,  0x4e,  
+   0x43,  0x2e,  0x31,  0x23,  0x30,  0x21,  0x06,  0x03,  
+   0x55,  0x04,  0x03,  0x13,  0x1a,  0x47,  0x54,  0x45,  
+   0x20,  0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x20,  0x47,  0x4c,  0x4f,  0x42,  
+   0x41,  0x4c,  0x20,  0x52,  0x4f,  0x4f,  0x54
+};
+static const CSSM_DATA GTECyberTrustGlobalRoot_subject = { 119, (uint8 *)GTECyberTrustGlobalRoot_subject_bytes };
+static const uint8 GTECyberTrustGlobalRoot_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0x95,  
+   0x0f,  0xa0,  0xb6,  0xf0,  0x50,  0x9c,  0xe8,  0x7a,  
+   0xc7,  0x88,  0xcd,  0xdd,  0x17,  0x0e,  0x2e,  0xb0,  
+   0x94,  0xd0,  0x1b,  0x3d,  0x0e,  0xf6,  0x94,  0xc0,  
+   0x8a,  0x94,  0xc7,  0x06,  0xc8,  0x90,  0x97,  0xc8,  
+   0xb8,  0x64,  0x1a,  0x7a,  0x7e,  0x6c,  0x3c,  0x53,  
+   0xe1,  0x37,  0x28,  0x73,  0x60,  0x7f,  0xb2,  0x97,  
+   0x53,  0x07,  0x9f,  0x53,  0xf9,  0x6d,  0x58,  0x94,  
+   0xd2,  0xaf,  0x8d,  0x6d,  0x88,  0x67,  0x80,  0xe6,  
+   0xed,  0xb2,  0x95,  0xcf,  0x72,  0x31,  0xca,  0xa5,  
+   0x1c,  0x72,  0xba,  0x5c,  0x02,  0xe7,  0x64,  0x42,  
+   0xe7,  0xf9,  0xa9,  0x2c,  0xd6,  0x3a,  0x0d,  0xac,  
+   0x8d,  0x42,  0xaa,  0x24,  0x01,  0x39,  0xe6,  0x9c,  
+   0x3f,  0x01,  0x85,  0x57,  0x0d,  0x58,  0x87,  0x45,  
+   0xf8,  0xd3,  0x85,  0xaa,  0x93,  0x69,  0x26,  0x85,  
+   0x70,  0x48,  0x80,  0x3f,  0x12,  0x15,  0xc7,  0x79,  
+   0xb4,  0x1f,  0x05,  0x2f,  0x3b,  0x62,  0x99,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA GTECyberTrustGlobalRoot_pubKey = { 140, (uint8 *)GTECyberTrustGlobalRoot_pubKey_bytes };
+
+
+/***********************
+Cert File Name: GTECyberTrustRoot.crt
+Subject Name       :
+    Country        : US
+    Org            : GTE Corporation
+    Common Name    : GTE CyberTrust Root
+ ***********************/
+static const uint8 GTECyberTrustRoot_subject_bytes[] = {
+   0x30,  0x45,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x18,  0x30,  0x16,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0f,  0x47,  0x54,  0x45,  0x20,  0x43,  0x4f,  
+   0x52,  0x50,  0x4f,  0x52,  0x41,  0x54,  0x49,  0x4f,  
+   0x4e,  0x31,  0x1c,  0x30,  0x1a,  0x06,  0x03,  0x55,  
+   0x04,  0x03,  0x13,  0x13,  0x47,  0x54,  0x45,  0x20,  
+   0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  
+   0x53,  0x54,  0x20,  0x52,  0x4f,  0x4f,  0x54
+};
+static const CSSM_DATA GTECyberTrustRoot_subject = { 71, (uint8 *)GTECyberTrustRoot_subject_bytes };
+static const uint8 GTECyberTrustRoot_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xb8,  
+   0xe6,  0x4f,  0xba,  0xdb,  0x98,  0x7c,  0x71,  0x7c,  
+   0xaf,  0x44,  0xb7,  0xd3,  0x0f,  0x46,  0xd9,  0x64,  
+   0xe5,  0x93,  0xc1,  0x42,  0x8e,  0xc7,  0xba,  0x49,  
+   0x8d,  0x35,  0x2d,  0x7a,  0xe7,  0x8b,  0xbd,  0xe5,  
+   0x05,  0x31,  0x59,  0xc6,  0xb1,  0x2f,  0x0a,  0x0c,  
+   0xfb,  0x9f,  0xa7,  0x3f,  0xa2,  0x09,  0x66,  0x84,  
+   0x56,  0x1e,  0x37,  0x29,  0x1b,  0x87,  0xe9,  0x7e,  
+   0x0c,  0xca,  0x9a,  0x9f,  0xa5,  0x7f,  0xf5,  0x15,  
+   0x94,  0xa3,  0xd5,  0xa2,  0x46,  0x82,  0xd8,  0x68,  
+   0x4c,  0xd1,  0x37,  0x15,  0x06,  0x68,  0xaf,  0xbd,  
+   0xf8,  0xb0,  0xb3,  0xf0,  0x29,  0xf5,  0x95,  0x5a,  
+   0x09,  0x16,  0x61,  0x77,  0x0a,  0x22,  0x25,  0xd4,  
+   0x4f,  0x45,  0xaa,  0xc7,  0xbd,  0xe5,  0x96,  0xdf,  
+   0xf9,  0xd4,  0xa8,  0x8e,  0x42,  0xcc,  0x24,  0xc0,  
+   0x1e,  0x91,  0x27,  0x4a,  0xb5,  0x6d,  0x06,  0x80,  
+   0x63,  0x39,  0xc4,  0xa2,  0x5e,  0x38,  0x03,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA GTECyberTrustRoot_pubKey = { 140, (uint8 *)GTECyberTrustRoot_pubKey_bytes };
+
+
+/***********************
+Cert File Name: GTECyberTrustRoot2.crt
+Subject Name       :
+    Country        : US
+    Org            : GTE Corporation
+    OrgUnit        : GTE CyberTrust Solutions, Inc.
+    Common Name    : GTE CyberTrust Root 2
+ ***********************/
+static const uint8 GTECyberTrustRoot2_subject_bytes[] = {
+   0x30,  0x70,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x18,  0x30,  0x16,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0f,  0x47,  0x54,  0x45,  0x20,  0x43,  0x4f,  
+   0x52,  0x50,  0x4f,  0x52,  0x41,  0x54,  0x49,  0x4f,  
+   0x4e,  0x31,  0x27,  0x30,  0x25,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x1e,  0x47,  0x54,  0x45,  0x20,  
+   0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  
+   0x53,  0x54,  0x20,  0x53,  0x4f,  0x4c,  0x55,  0x54,  
+   0x49,  0x4f,  0x4e,  0x53,  0x2c,  0x20,  0x49,  0x4e,  
+   0x43,  0x2e,  0x31,  0x1e,  0x30,  0x1c,  0x06,  0x03,  
+   0x55,  0x04,  0x03,  0x13,  0x15,  0x47,  0x54,  0x45,  
+   0x20,  0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x20,  0x52,  0x4f,  0x4f,  0x54,  
+   0x20,  0x32
+};
+static const CSSM_DATA GTECyberTrustRoot2_subject = { 114, (uint8 *)GTECyberTrustRoot2_subject_bytes };
+static const uint8 GTECyberTrustRoot2_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xd9,  
+   0x2c,  0x4c,  0x4e,  0x2f,  0x69,  0x1a,  0x23,  0xe3,  
+   0x56,  0xba,  0xf3,  0xce,  0x84,  0xc0,  0x09,  0xc0,  
+   0x79,  0xf1,  0x44,  0x5f,  0x33,  0x1f,  0x15,  0x91,  
+   0x7f,  0x8a,  0x88,  0x28,  0xb8,  0x24,  0x45,  0xcc,  
+   0x8f,  0x18,  0xcd,  0x1f,  0x74,  0xd1,  0xb5,  0x8f,  
+   0x71,  0x4c,  0xd6,  0x31,  0xf6,  0x73,  0x96,  0x84,  
+   0x94,  0x40,  0xc5,  0xa9,  0x83,  0x60,  0x24,  0x7d,  
+   0xaf,  0x6f,  0x34,  0xb7,  0x4b,  0x4c,  0xc2,  0x09,  
+   0x80,  0x3b,  0x45,  0x04,  0x9e,  0xc4,  0x3c,  0xc4,  
+   0x27,  0x75,  0x7b,  0x00,  0x0c,  0xa1,  0x64,  0x47,  
+   0xb5,  0x14,  0x5d,  0x82,  0x4b,  0x51,  0x3a,  0x58,  
+   0xbb,  0x44,  0x4c,  0x3d,  0xd3,  0xe5,  0x06,  0x38,  
+   0xe8,  0x61,  0x5c,  0x98,  0x78,  0xbb,  0x80,  0xb3,  
+   0x9c,  0xda,  0x72,  0x82,  0x62,  0xa0,  0xdf,  0x9c,  
+   0x5f,  0xeb,  0xf9,  0x4f,  0x77,  0xc2,  0xcc,  0x60,  
+   0x18,  0x00,  0x6b,  0x34,  0x82,  0x25,  0xb3,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA GTECyberTrustRoot2_pubKey = { 140, (uint8 *)GTECyberTrustRoot2_pubKey_bytes };
+
+
+/***********************
+Cert File Name: GTECyberTrustRoot3.crt
+Subject Name       :
+    Country        : US
+    Org            : GTE Corporation
+    OrgUnit        : GTE CyberTrust Solutions, Inc.
+    Common Name    : GTE CyberTrust Root 3
+ ***********************/
+static const uint8 GTECyberTrustRoot3_subject_bytes[] = {
+   0x30,  0x70,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x18,  0x30,  0x16,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0f,  0x47,  0x54,  0x45,  0x20,  0x43,  0x4f,  
+   0x52,  0x50,  0x4f,  0x52,  0x41,  0x54,  0x49,  0x4f,  
+   0x4e,  0x31,  0x27,  0x30,  0x25,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x1e,  0x47,  0x54,  0x45,  0x20,  
+   0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  
+   0x53,  0x54,  0x20,  0x53,  0x4f,  0x4c,  0x55,  0x54,  
+   0x49,  0x4f,  0x4e,  0x53,  0x2c,  0x20,  0x49,  0x4e,  
+   0x43,  0x2e,  0x31,  0x1e,  0x30,  0x1c,  0x06,  0x03,  
+   0x55,  0x04,  0x03,  0x13,  0x15,  0x47,  0x54,  0x45,  
+   0x20,  0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x20,  0x52,  0x4f,  0x4f,  0x54,  
+   0x20,  0x33
+};
+static const CSSM_DATA GTECyberTrustRoot3_subject = { 114, (uint8 *)GTECyberTrustRoot3_subject_bytes };
+static const uint8 GTECyberTrustRoot3_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xe1,  
+   0xf3,  0xb1,  0x2b,  0x0b,  0xce,  0xdc,  0x14,  0xd9,  
+   0x34,  0x97,  0x62,  0x50,  0x12,  0x56,  0x63,  0x84,  
+   0x4c,  0x53,  0xfa,  0xc0,  0x85,  0xcf,  0xfa,  0xc1,  
+   0xdd,  0x0f,  0xde,  0x79,  0x13,  0x7f,  0x53,  0xfb,  
+   0xaa,  0x0e,  0x60,  0xdd,  0xe2,  0x62,  0xbf,  0xc6,  
+   0xee,  0x4e,  0x99,  0x34,  0xaa,  0x68,  0x43,  0x35,  
+   0x99,  0xf8,  0xa3,  0xfd,  0xf3,  0x63,  0xbd,  0x01,  
+   0x54,  0x6a,  0x9e,  0xb2,  0x3a,  0x96,  0x2c,  0x7b,  
+   0x78,  0x28,  0xc6,  0x5a,  0xb5,  0x8d,  0x1a,  0x15,  
+   0x18,  0xfd,  0xe3,  0x8c,  0x2e,  0xa2,  0x50,  0x09,  
+   0x5b,  0x71,  0xd6,  0x0d,  0xb5,  0x18,  0x1f,  0x19,  
+   0x8e,  0x04,  0x29,  0x93,  0x93,  0x78,  0xab,  0x5f,  
+   0x14,  0xe7,  0x73,  0x42,  0xf2,  0x03,  0x0c,  0x57,  
+   0xa2,  0x1b,  0x50,  0x3b,  0x0b,  0xbb,  0x59,  0xe0,  
+   0xa0,  0x3a,  0x03,  0xee,  0x27,  0x1b,  0x5a,  0x4c,  
+   0xb9,  0xb0,  0x08,  0xca,  0xb9,  0x1a,  0x89,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA GTECyberTrustRoot3_pubKey = { 140, (uint8 *)GTECyberTrustRoot3_pubKey_bytes };
+
+
+/***********************
+Cert File Name: GTECyberTrustRoot4.crt
+Subject Name       :
+    Country        : US
+    Org            : GTE Corporation
+    OrgUnit        : GTE CyberTrust Solutions, Inc.
+    Common Name    : GTE CyberTrust Root 4
+ ***********************/
+static const uint8 GTECyberTrustRoot4_subject_bytes[] = {
+   0x30,  0x70,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x18,  0x30,  0x16,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0f,  0x47,  0x54,  0x45,  0x20,  0x43,  0x4f,  
+   0x52,  0x50,  0x4f,  0x52,  0x41,  0x54,  0x49,  0x4f,  
+   0x4e,  0x31,  0x27,  0x30,  0x25,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x1e,  0x47,  0x54,  0x45,  0x20,  
+   0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  
+   0x53,  0x54,  0x20,  0x53,  0x4f,  0x4c,  0x55,  0x54,  
+   0x49,  0x4f,  0x4e,  0x53,  0x2c,  0x20,  0x49,  0x4e,  
+   0x43,  0x2e,  0x31,  0x1e,  0x30,  0x1c,  0x06,  0x03,  
+   0x55,  0x04,  0x03,  0x13,  0x15,  0x47,  0x54,  0x45,  
+   0x20,  0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x20,  0x52,  0x4f,  0x4f,  0x54,  
+   0x20,  0x34
+};
+static const CSSM_DATA GTECyberTrustRoot4_subject = { 114, (uint8 *)GTECyberTrustRoot4_subject_bytes };
+static const uint8 GTECyberTrustRoot4_pubKey_bytes[] = {
+   0x30,  0x82,  0x01,  0x0a,  0x02,  0x82,  0x01,  0x01,  
+   0x00,  0xba,  0x9d,  0x22,  0x6e,  0x7f,  0xda,  0x66,  
+   0x3c,  0x39,  0x42,  0xb1,  0xa3,  0x2a,  0x6f,  0xd3,  
+   0xf7,  0xbc,  0xae,  0xac,  0x31,  0x5a,  0xd7,  0x11,  
+   0x90,  0x47,  0xb9,  0x9d,  0x19,  0x2e,  0xf9,  0xf3,  
+   0x1b,  0x22,  0xa0,  0xc3,  0xe1,  0xa7,  0xba,  0xc4,  
+   0xfc,  0x5e,  0x0a,  0x94,  0x4b,  0x98,  0x5a,  0x4b,  
+   0x26,  0xe4,  0x1f,  0xf4,  0xdc,  0xf3,  0xfe,  0x8e,  
+   0x88,  0xdc,  0x6c,  0x2d,  0x7c,  0x77,  0x87,  0x26,  
+   0x50,  0xc0,  0x5e,  0x4e,  0xa8,  0x28,  0xa1,  0xea,  
+   0x17,  0x69,  0x4f,  0x4d,  0xc6,  0x01,  0x0e,  0xda,  
+   0x9a,  0x0d,  0x06,  0x56,  0x26,  0x15,  0xb6,  0xa4,  
+   0x5d,  0x7a,  0x35,  0xaf,  0x8d,  0xed,  0x78,  0x52,  
+   0x86,  0xf9,  0x38,  0xab,  0xb3,  0x01,  0xd3,  0xda,  
+   0x05,  0x96,  0xb1,  0xb6,  0x50,  0xab,  0xc0,  0xa1,  
+   0xae,  0x17,  0x53,  0xfa,  0x43,  0x39,  0x20,  0x71,  
+   0x65,  0x23,  0xdb,  0x6d,  0xc4,  0xb6,  0xed,  0x98,  
+   0x45,  0x83,  0xd7,  0xd2,  0xf6,  0xe2,  0xa9,  0x6b,  
+   0xfb,  0xf9,  0x75,  0xcc,  0xef,  0xc5,  0xab,  0x71,  
+   0x96,  0x35,  0xe8,  0xdf,  0x8e,  0x91,  0x9b,  0xa8,  
+   0x10,  0x75,  0x1f,  0xb7,  0xce,  0x13,  0x8e,  0x6b,  
+   0xb3,  0x96,  0x77,  0x97,  0x1a,  0x91,  0x2f,  0xc7,  
+   0x2c,  0x69,  0x99,  0xf0,  0x0f,  0x2a,  0x68,  0x00,  
+   0x98,  0x76,  0x44,  0x1b,  0x8c,  0x28,  0xd2,  0xeb,  
+   0x8e,  0xf4,  0x83,  0xb4,  0x7f,  0xa4,  0x25,  0x5e,  
+   0x6c,  0x3b,  0xd9,  0xc6,  0x68,  0xd5,  0x61,  0xb8,  
+   0xd4,  0x5e,  0x31,  0x07,  0xb5,  0x5b,  0x90,  0x35,  
+   0x52,  0x57,  0x7b,  0x17,  0x20,  0xed,  0x2d,  0xb8,  
+   0x1e,  0x8e,  0x88,  0x39,  0x3e,  0x52,  0xcb,  0xdf,  
+   0xf0,  0x5c,  0xb1,  0x65,  0xbb,  0xa5,  0x12,  0xb4,  
+   0x90,  0x63,  0xbf,  0x71,  0x9d,  0x32,  0xc1,  0xda,  
+   0xbf,  0x50,  0x4a,  0x95,  0xbe,  0x06,  0x3a,  0xc4,  
+   0x2b,  0xeb,  0xcd,  0x98,  0x76,  0x44,  0x4d,  0x0b,  
+   0xe5,  0x02,  0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA GTECyberTrustRoot4_pubKey = { 270, (uint8 *)GTECyberTrustRoot4_pubKey_bytes };
+
+
+/***********************
+Cert File Name: GTECyberTrustRoot5.crt
+Subject Name       :
+    Country        : US
+    Org            : GTE Corporation
+    OrgUnit        : GTE CyberTrust Solutions, Inc.
+    Common Name    : GTE CyberTrust Root 5
+ ***********************/
+static const uint8 GTECyberTrustRoot5_subject_bytes[] = {
+   0x30,  0x70,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x55,  0x53,  0x31,  
+   0x18,  0x30,  0x16,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x0f,  0x47,  0x54,  0x45,  0x20,  0x43,  0x4f,  
+   0x52,  0x50,  0x4f,  0x52,  0x41,  0x54,  0x49,  0x4f,  
+   0x4e,  0x31,  0x27,  0x30,  0x25,  0x06,  0x03,  0x55,  
+   0x04,  0x0b,  0x13,  0x1e,  0x47,  0x54,  0x45,  0x20,  
+   0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  
+   0x53,  0x54,  0x20,  0x53,  0x4f,  0x4c,  0x55,  0x54,  
+   0x49,  0x4f,  0x4e,  0x53,  0x2c,  0x20,  0x49,  0x4e,  
+   0x43,  0x2e,  0x31,  0x1e,  0x30,  0x1c,  0x06,  0x03,  
+   0x55,  0x04,  0x03,  0x13,  0x15,  0x47,  0x54,  0x45,  
+   0x20,  0x43,  0x59,  0x42,  0x45,  0x52,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x20,  0x52,  0x4f,  0x4f,  0x54,  
+   0x20,  0x35
+};
+static const CSSM_DATA GTECyberTrustRoot5_subject = { 114, (uint8 *)GTECyberTrustRoot5_subject_bytes };
+static const uint8 GTECyberTrustRoot5_pubKey_bytes[] = {
+   0x30,  0x82,  0x01,  0x0a,  0x02,  0x82,  0x01,  0x01,  
+   0x00,  0xbc,  0x12,  0x6e,  0x3f,  0x8a,  0x7c,  0x7a,  
+   0x97,  0x01,  0xec,  0x1e,  0xbb,  0x39,  0x5a,  0x02,  
+   0xf4,  0x78,  0x44,  0xa2,  0x48,  0x1b,  0x8e,  0x7b,  
+   0x49,  0x52,  0x7a,  0xb8,  0x7b,  0x47,  0xb3,  0xaf,  
+   0x94,  0x9b,  0x6f,  0xbb,  0x96,  0xfa,  0x2b,  0x6a,  
+   0x65,  0x5c,  0xb8,  0x1c,  0x94,  0x73,  0xbe,  0xbf,  
+   0x89,  0x0a,  0x22,  0x80,  0xee,  0x57,  0xfc,  0x8c,  
+   0x05,  0xbb,  0x70,  0x9f,  0x97,  0x39,  0x04,  0xda,  
+   0xa3,  0x87,  0x5c,  0xa8,  0xe5,  0xca,  0xaf,  0xc0,  
+   0x33,  0x9a,  0xd5,  0x37,  0x5c,  0x4b,  0xac,  0xe4,  
+   0x80,  0xd0,  0xa6,  0x23,  0x60,  0xfb,  0xfd,  0x72,  
+   0x2e,  0x94,  0x9d,  0xc7,  0xce,  0xc2,  0x04,  0x32,  
+   0xef,  0x78,  0x60,  0x5d,  0xed,  0xad,  0x87,  0x0f,  
+   0x45,  0x65,  0x1e,  0x3c,  0x9a,  0x0a,  0x9a,  0xbe,  
+   0x5d,  0x1d,  0x99,  0xec,  0xe7,  0xf2,  0xd1,  0xc6,  
+   0x7a,  0x17,  0xd9,  0xad,  0x9b,  0x54,  0x96,  0x7f,  
+   0xc4,  0x7c,  0x60,  0xbf,  0x85,  0xaa,  0x15,  0x35,  
+   0x1d,  0x40,  0xda,  0x11,  0xbc,  0xec,  0x54,  0x21,  
+   0x28,  0x2d,  0x23,  0xa1,  0xa8,  0xf0,  0xcf,  0x2d,  
+   0xcd,  0xdd,  0xfc,  0x7e,  0x0f,  0x5e,  0xe1,  0x65,  
+   0x07,  0x56,  0xcb,  0x07,  0xb4,  0xd2,  0x56,  0xe8,  
+   0x5e,  0x31,  0xcc,  0x18,  0x63,  0xc4,  0x86,  0xd2,  
+   0x2d,  0x85,  0xcf,  0x93,  0x92,  0xab,  0x6d,  0xfe,  
+   0x68,  0x39,  0xfb,  0xde,  0x73,  0xbd,  0x86,  0xf8,  
+   0xe4,  0x46,  0x7a,  0xea,  0x9f,  0x0c,  0xcb,  0xf4,  
+   0x19,  0xfe,  0x63,  0xbc,  0xd1,  0x2c,  0x7b,  0x88,  
+   0x33,  0x36,  0xf6,  0xe4,  0xe1,  0x9c,  0x0c,  0x53,  
+   0x81,  0x60,  0x1c,  0xda,  0x2e,  0xab,  0x96,  0xa9,  
+   0x16,  0x88,  0x13,  0x50,  0x99,  0xb2,  0xbd,  0x55,  
+   0xdf,  0x15,  0x30,  0x7e,  0xe8,  0xe5,  0x98,  0xfb,  
+   0x70,  0x7e,  0x6c,  0xb5,  0x07,  0xfc,  0xfc,  0x46,  
+   0xb7,  0xd0,  0xed,  0x37,  0x96,  0x7e,  0x32,  0xfe,  
+   0x21,  0x02,  0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA GTECyberTrustRoot5_pubKey = { 270, (uint8 *)GTECyberTrustRoot5_pubKey_bytes };
+
+
+/***********************
+Cert File Name: BTCTRoot.uu.raw
+Subject Name       :
+    Country        : IE
+    Org            : Baltimore
+    OrgUnit        : CyberTrust
+    Common Name    : Baltimore CyberTrust Root
+ ***********************/
+static const uint8 BTCTRoot_subject_bytes[] = {
+   0x30,  0x5a,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x49,  0x45,  0x31,  
+   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x09,  0x42,  0x41,  0x4c,  0x54,  0x49,  0x4d,  
+   0x4f,  0x52,  0x45,  0x31,  0x13,  0x30,  0x11,  0x06,  
+   0x03,  0x55,  0x04,  0x0b,  0x13,  0x0a,  0x43,  0x59,  
+   0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  0x53,  0x54,  
+   0x31,  0x22,  0x30,  0x20,  0x06,  0x03,  0x55,  0x04,  
+   0x03,  0x13,  0x19,  0x42,  0x41,  0x4c,  0x54,  0x49,  
+   0x4d,  0x4f,  0x52,  0x45,  0x20,  0x43,  0x59,  0x42,  
+   0x45,  0x52,  0x54,  0x52,  0x55,  0x53,  0x54,  0x20,  
+   0x52,  0x4f,  0x4f,  0x54
+};
+static const CSSM_DATA BTCTRoot_subject = { 92, (uint8 *)BTCTRoot_subject_bytes };
+static const uint8 BTCTRoot_pubKey_bytes[] = {
+   0x30,  0x82,  0x01,  0x0a,  0x02,  0x82,  0x01,  0x01,  
+   0x00,  0xa3,  0x04,  0xbb,  0x22,  0xab,  0x98,  0x3d,  
+   0x57,  0xe8,  0x26,  0x72,  0x9a,  0xb5,  0x79,  0xd4,  
+   0x29,  0xe2,  0xe1,  0xe8,  0x95,  0x80,  0xb1,  0xb0,  
+   0xe3,  0x5b,  0x8e,  0x2b,  0x29,  0x9a,  0x64,  0xdf,  
+   0xa1,  0x5d,  0xed,  0xb0,  0x09,  0x05,  0x6d,  0xdb,  
+   0x28,  0x2e,  0xce,  0x62,  0xa2,  0x62,  0xfe,  0xb4,  
+   0x88,  0xda,  0x12,  0xeb,  0x38,  0xeb,  0x21,  0x9d,  
+   0xc0,  0x41,  0x2b,  0x01,  0x52,  0x7b,  0x88,  0x77,  
+   0xd3,  0x1c,  0x8f,  0xc7,  0xba,  0xb9,  0x88,  0xb5,  
+   0x6a,  0x09,  0xe7,  0x73,  0xe8,  0x11,  0x40,  0xa7,  
+   0xd1,  0xcc,  0xca,  0x62,  0x8d,  0x2d,  0xe5,  0x8f,  
+   0x0b,  0xa6,  0x50,  0xd2,  0xa8,  0x50,  0xc3,  0x28,  
+   0xea,  0xf5,  0xab,  0x25,  0x87,  0x8a,  0x9a,  0x96,  
+   0x1c,  0xa9,  0x67,  0xb8,  0x3f,  0x0c,  0xd5,  0xf7,  
+   0xf9,  0x52,  0x13,  0x2f,  0xc2,  0x1b,  0xd5,  0x70,  
+   0x70,  0xf0,  0x8f,  0xc0,  0x12,  0xca,  0x06,  0xcb,  
+   0x9a,  0xe1,  0xd9,  0xca,  0x33,  0x7a,  0x77,  0xd6,  
+   0xf8,  0xec,  0xb9,  0xf1,  0x68,  0x44,  0x42,  0x48,  
+   0x13,  0xd2,  0xc0,  0xc2,  0xa4,  0xae,  0x5e,  0x60,  
+   0xfe,  0xb6,  0xa6,  0x05,  0xfc,  0xb4,  0xdd,  0x07,  
+   0x59,  0x02,  0xd4,  0x59,  0x18,  0x98,  0x63,  0xf5,  
+   0xa5,  0x63,  0xe0,  0x90,  0x0c,  0x7d,  0x5d,  0xb2,  
+   0x06,  0x7a,  0xf3,  0x85,  0xea,  0xeb,  0xd4,  0x03,  
+   0xae,  0x5e,  0x84,  0x3e,  0x5f,  0xff,  0x15,  0xed,  
+   0x69,  0xbc,  0xf9,  0x39,  0x36,  0x72,  0x75,  0xcf,  
+   0x77,  0x52,  0x4d,  0xf3,  0xc9,  0x90,  0x2c,  0xb9,  
+   0x3d,  0xe5,  0xc9,  0x23,  0x53,  0x3f,  0x1f,  0x24,  
+   0x98,  0x21,  0x5c,  0x07,  0x99,  0x29,  0xbd,  0xc6,  
+   0x3a,  0xec,  0xe7,  0x6e,  0x86,  0x3a,  0x6b,  0x97,  
+   0x74,  0x63,  0x33,  0xbd,  0x68,  0x18,  0x31,  0xf0,  
+   0x78,  0x8d,  0x76,  0xbf,  0xfc,  0x9e,  0x8e,  0x5d,  
+   0x2a,  0x86,  0xa7,  0x4d,  0x90,  0xdc,  0x27,  0x1a,  
+   0x39,  0x02,  0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA BTCTRoot_pubKey = { 270, (uint8 *)BTCTRoot_pubKey_bytes };
+
+/***********************
+Cert File Name: BTCTcodert.uu.raw
+Subject Name       :
+    Country        : IE
+    Org            : Baltimore
+    OrgUnit        : CyberTrust
+    Common Name    : Baltimore CyberTrust Code Signing Root
+ ***********************/
+static const uint8 BTCTcodert_subject_bytes[] = {
+   0x30,  0x67,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x49,  0x45,  0x31,  
+   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x09,  0x42,  0x41,  0x4c,  0x54,  0x49,  0x4d,  
+   0x4f,  0x52,  0x45,  0x31,  0x13,  0x30,  0x11,  0x06,  
+   0x03,  0x55,  0x04,  0x0b,  0x13,  0x0a,  0x43,  0x59,  
+   0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  0x53,  0x54,  
+   0x31,  0x2f,  0x30,  0x2d,  0x06,  0x03,  0x55,  0x04,  
+   0x03,  0x13,  0x26,  0x42,  0x41,  0x4c,  0x54,  0x49,  
+   0x4d,  0x4f,  0x52,  0x45,  0x20,  0x43,  0x59,  0x42,  
+   0x45,  0x52,  0x54,  0x52,  0x55,  0x53,  0x54,  0x20,  
+   0x43,  0x4f,  0x44,  0x45,  0x20,  0x53,  0x49,  0x47,  
+   0x4e,  0x49,  0x4e,  0x47,  0x20,  0x52,  0x4f,  0x4f,  
+   0x54
+};
+static const CSSM_DATA BTCTcodert_subject = { 105, (uint8 *)BTCTcodert_subject_bytes };
+static const uint8 BTCTcodert_pubKey_bytes[] = {
+   0x30,  0x82,  0x01,  0x0a,  0x02,  0x82,  0x01,  0x01,  
+   0x00,  0xc8,  0x71,  0x9a,  0x18,  0x12,  0x8e,  0x7a,  
+   0xdb,  0xf9,  0x9a,  0xfc,  0x41,  0xaf,  0xd8,  0xf2,  
+   0xf4,  0x09,  0x8e,  0xad,  0x3f,  0xfe,  0x67,  0x37,  
+   0x3c,  0xda,  0xc9,  0x26,  0x50,  0xb1,  0xb1,  0x3e,  
+   0xcb,  0xe8,  0x4e,  0x73,  0x00,  0xf2,  0xb2,  0xdc,  
+   0xf3,  0xc5,  0x46,  0xfb,  0x09,  0xef,  0x18,  0x96,  
+   0xce,  0xa7,  0xe0,  0x9c,  0x84,  0x5d,  0x20,  0x0e,  
+   0x7a,  0xa0,  0xaa,  0x36,  0x8b,  0xfa,  0x28,  0xb6,  
+   0x78,  0x2e,  0xb3,  0xec,  0xe8,  0x47,  0xf3,  0x04,  
+   0xf0,  0x90,  0x23,  0xb4,  0xea,  0xaf,  0xe5,  0x53,  
+   0xb8,  0x05,  0xf7,  0x47,  0x5d,  0x2b,  0x86,  0xf1,  
+   0xa7,  0xa4,  0xc6,  0x3b,  0x35,  0xb6,  0xd2,  0x0d,  
+   0x52,  0x41,  0xd7,  0xf4,  0x92,  0x75,  0xe1,  0xa2,  
+   0x0a,  0x50,  0x56,  0x87,  0xbe,  0x97,  0x0b,  0x7b,  
+   0x33,  0x85,  0x10,  0xb9,  0x28,  0x18,  0xee,  0x33,  
+   0xea,  0x48,  0x11,  0xd7,  0x5b,  0x91,  0x47,  0x76,  
+   0x22,  0xd4,  0xee,  0xcf,  0x5d,  0xe7,  0xa8,  0x4e,  
+   0x1c,  0x9d,  0x96,  0x91,  0xdd,  0x9c,  0xbd,  0x74,  
+   0x09,  0xa8,  0x72,  0x61,  0xaa,  0xb0,  0x21,  0x3a,  
+   0xf1,  0x3d,  0x2c,  0x03,  0x56,  0x09,  0xd2,  0xc1,  
+   0xdc,  0xc3,  0xb5,  0xc7,  0x54,  0x37,  0xab,  0xe6,  
+   0x26,  0xa2,  0xb2,  0x46,  0x71,  0x73,  0xca,  0x11,  
+   0x88,  0xee,  0xbc,  0xe7,  0x64,  0xf7,  0xd0,  0x11,  
+   0x1a,  0x73,  0x40,  0x5a,  0xc8,  0x49,  0x2c,  0x0f,  
+   0xb7,  0xef,  0x90,  0x7f,  0x68,  0x80,  0x04,  0x38,  
+   0x0b,  0x1b,  0x0f,  0x3b,  0xd4,  0xf5,  0xa0,  0xb3,  
+   0xc2,  0x8e,  0xe1,  0x34,  0xb4,  0x80,  0x99,  0x6d,  
+   0x9e,  0x76,  0xd4,  0x92,  0x29,  0x40,  0xb1,  0x95,  
+   0xd2,  0x37,  0xa4,  0x67,  0x12,  0x7f,  0xe0,  0x62,  
+   0xbb,  0xae,  0x35,  0xc5,  0x99,  0x36,  0x82,  0x44,  
+   0xb8,  0xe6,  0x78,  0x18,  0x33,  0x61,  0x71,  0x93,  
+   0x5b,  0x2d,  0x8d,  0x9f,  0x78,  0x95,  0x82,  0xeb,  
+   0x6d,  0x02,  0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA BTCTcodert_pubKey = { 270, (uint8 *)BTCTcodert_pubKey_bytes };
+
+
+/***********************
+Cert File Name: BTCTmort.uu.raw
+Subject Name       :
+    Country        : IE
+    Org            : Baltimore
+    OrgUnit        : CyberTrust
+    Common Name    : Baltimore CyberTrust Mobile Root
+ ***********************/
+static const uint8 BTCTmort_subject_bytes[] = {
+   0x30,  0x61,  0x31,  0x0b,  0x30,  0x09,  0x06,  0x03,  
+   0x55,  0x04,  0x06,  0x13,  0x02,  0x49,  0x45,  0x31,  
+   0x12,  0x30,  0x10,  0x06,  0x03,  0x55,  0x04,  0x0a,  
+   0x13,  0x09,  0x42,  0x41,  0x4c,  0x54,  0x49,  0x4d,  
+   0x4f,  0x52,  0x45,  0x31,  0x13,  0x30,  0x11,  0x06,  
+   0x03,  0x55,  0x04,  0x0b,  0x13,  0x0a,  0x43,  0x59,  
+   0x42,  0x45,  0x52,  0x54,  0x52,  0x55,  0x53,  0x54,  
+   0x31,  0x29,  0x30,  0x27,  0x06,  0x03,  0x55,  0x04,  
+   0x03,  0x13,  0x20,  0x42,  0x41,  0x4c,  0x54,  0x49,  
+   0x4d,  0x4f,  0x52,  0x45,  0x20,  0x43,  0x59,  0x42,  
+   0x45,  0x52,  0x54,  0x52,  0x55,  0x53,  0x54,  0x20,  
+   0x4d,  0x4f,  0x42,  0x49,  0x4c,  0x45,  0x20,  0x52,  
+   0x4f,  0x4f,  0x54
+};
+static const CSSM_DATA BTCTmort_subject = { 99, (uint8 *)BTCTmort_subject_bytes };
+static const uint8 BTCTmort_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xa3,  
+   0x6d,  0xb1,  0x38,  0x56,  0xac,  0xfc,  0xb5,  0x56,  
+   0x21,  0xde,  0xc0,  0x90,  0x5d,  0x26,  0x47,  0x82,  
+   0xc6,  0x7d,  0x8f,  0x1f,  0xa0,  0x85,  0x8f,  0x2f,  
+   0xbb,  0xd4,  0xe1,  0x1c,  0x1d,  0xf2,  0x24,  0x1f,  
+   0x28,  0xb0,  0x2f,  0xb9,  0xa4,  0xa5,  0x6f,  0xa2,  
+   0x22,  0x20,  0x64,  0xfe,  0x84,  0x47,  0x3c,  0x7e,  
+   0x2b,  0x6c,  0x69,  0x6a,  0xb8,  0xd4,  0xc0,  0x96,  
+   0x8e,  0x8c,  0x52,  0x0d,  0xcd,  0x6f,  0x41,  0xd4,  
+   0xbf,  0x04,  0xae,  0xa7,  0x81,  0x2f,  0x2d,  0x98,  
+   0x48,  0xd2,  0xc1,  0x94,  0xa3,  0xb5,  0x19,  0x5d,  
+   0x5d,  0x51,  0x64,  0xf4,  0x8e,  0x41,  0xb0,  0x9b,  
+   0xc0,  0x2d,  0x22,  0xa0,  0x5e,  0xc6,  0xd8,  0x5a,  
+   0x12,  0x63,  0xbc,  0x11,  0x4a,  0x5e,  0x26,  0x12,  
+   0x1d,  0xe2,  0x26,  0x05,  0xe6,  0x0f,  0x5f,  0x22,  
+   0x1f,  0x7a,  0x5f,  0x76,  0x94,  0xae,  0xcf,  0x5a,  
+   0x28,  0x0e,  0xab,  0x45,  0xda,  0x22,  0x31,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA BTCTmort_pubKey = { 140, (uint8 *)BTCTmort_pubKey_bytes };
+
+
+/***********************
+Cert File Name: TC_Class_0.cer
+Subject Name       :
+    Country        : DE
+    State          : Hamburg
+    Locality       : Hamburg
+    Org            : TC TrustCenter for Security in Data Networks GmbH
+    OrgUnit        : TC TrustCenter Class 0 CA
+    Email addrs    : certificate@trustcenter.de
+ ***********************/
+static const uint8 TC_Class_0_subject_bytes[] = {
+   0x30,  0x81,  0xbc,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x44,  0x45,  
+   0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x07,  0x48,  0x41,  0x4d,  0x42,  0x55,  
+   0x52,  0x47,  0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  
+   0x55,  0x04,  0x07,  0x13,  0x07,  0x48,  0x41,  0x4d,  
+   0x42,  0x55,  0x52,  0x47,  0x31,  0x3a,  0x30,  0x38,  
+   0x06,  0x03,  0x55,  0x04,  0x0a,  0x13,  0x31,  0x54,  
+   0x43,  0x20,  0x54,  0x52,  0x55,  0x53,  0x54,  0x43,  
+   0x45,  0x4e,  0x54,  0x45,  0x52,  0x20,  0x46,  0x4f,  
+   0x52,  0x20,  0x53,  0x45,  0x43,  0x55,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x49,  0x4e,  0x20,  0x44,  0x41,  
+   0x54,  0x41,  0x20,  0x4e,  0x45,  0x54,  0x57,  0x4f,  
+   0x52,  0x4b,  0x53,  0x20,  0x47,  0x4d,  0x42,  0x48,  
+   0x31,  0x22,  0x30,  0x20,  0x06,  0x03,  0x55,  0x04,  
+   0x0b,  0x13,  0x19,  0x54,  0x43,  0x20,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x43,  0x45,  0x4e,  0x54,  0x45,  
+   0x52,  0x20,  0x43,  0x4c,  0x41,  0x53,  0x53,  0x20,  
+   0x30,  0x20,  0x43,  0x41,  0x31,  0x29,  0x30,  0x27,  
+   0x06,  0x09,  0x2a,  0x86,  0x48,  0x86,  0xf7,  0x0d,  
+   0x01,  0x09,  0x01,  0x16,  0x1a,  0x63,  0x65,  0x72,  
+   0x74,  0x69,  0x66,  0x69,  0x63,  0x61,  0x74,  0x65,  
+   0x40,  0x74,  0x72,  0x75,  0x73,  0x74,  0x63,  0x65,  
+   0x6e,  0x74,  0x65,  0x72,  0x2e,  0x64,  0x65
+};
+static const CSSM_DATA TC_Class_0_subject = { 191, (uint8 *)TC_Class_0_subject_bytes };
+static const uint8 TC_Class_0_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xdf,  
+   0x7d,  0xe6,  0xbe,  0xbf,  0xd5,  0xf0,  0x2f,  0x6d,  
+   0x4e,  0x0e,  0xd1,  0xe0,  0x8d,  0x0b,  0x7f,  0x3b,  
+   0x54,  0xe8,  0x8a,  0xe2,  0xb0,  0x9f,  0x28,  0xc5,  
+   0x8a,  0xc6,  0xb9,  0xb3,  0x33,  0x27,  0xf5,  0x27,  
+   0xca,  0x1a,  0x4c,  0x54,  0x12,  0x6b,  0xb4,  0xb2,  
+   0x46,  0xb3,  0x1d,  0x4b,  0xb3,  0xf4,  0x21,  0x0b,  
+   0x4b,  0x02,  0x2e,  0xa1,  0xc2,  0x34,  0x9c,  0x85,  
+   0xa0,  0xc4,  0x78,  0x11,  0xdb,  0xdb,  0x6b,  0x27,  
+   0x2b,  0x09,  0x2a,  0x18,  0x4e,  0x40,  0xcc,  0x9f,  
+   0x71,  0x19,  0x67,  0x99,  0x74,  0xa2,  0x7c,  0x3f,  
+   0xc1,  0xd8,  0x8b,  0x23,  0xc8,  0x63,  0x3b,  0x8a,  
+   0x21,  0xab,  0x5c,  0xde,  0x1e,  0xf4,  0x8d,  0xdc,  
+   0xb4,  0x18,  0xc3,  0x05,  0x73,  0xf4,  0x6a,  0xb4,  
+   0xa1,  0xfa,  0x01,  0x08,  0x2b,  0x01,  0x0f,  0x6d,  
+   0x37,  0x5b,  0xaa,  0x38,  0x86,  0x67,  0x39,  0xd7,  
+   0xe5,  0x5f,  0xfa,  0xe4,  0x7e,  0xcc,  0xa3,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA TC_Class_0_pubKey = { 140, (uint8 *)TC_Class_0_pubKey_bytes };
+
+
+/***********************
+Cert File Name: TC_Class_1.cer
+Subject Name       :
+    Country        : DE
+    State          : Hamburg
+    Locality       : Hamburg
+    Org            : TC TrustCenter for Security in Data Networks GmbH
+    OrgUnit        : TC TrustCenter Class 1 CA
+    Email addrs    : certificate@trustcenter.de
+ ***********************/
+static const uint8 TC_Class_1_subject_bytes[] = {
+   0x30,  0x81,  0xbc,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x44,  0x45,  
+   0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x07,  0x48,  0x41,  0x4d,  0x42,  0x55,  
+   0x52,  0x47,  0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  
+   0x55,  0x04,  0x07,  0x13,  0x07,  0x48,  0x41,  0x4d,  
+   0x42,  0x55,  0x52,  0x47,  0x31,  0x3a,  0x30,  0x38,  
+   0x06,  0x03,  0x55,  0x04,  0x0a,  0x13,  0x31,  0x54,  
+   0x43,  0x20,  0x54,  0x52,  0x55,  0x53,  0x54,  0x43,  
+   0x45,  0x4e,  0x54,  0x45,  0x52,  0x20,  0x46,  0x4f,  
+   0x52,  0x20,  0x53,  0x45,  0x43,  0x55,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x49,  0x4e,  0x20,  0x44,  0x41,  
+   0x54,  0x41,  0x20,  0x4e,  0x45,  0x54,  0x57,  0x4f,  
+   0x52,  0x4b,  0x53,  0x20,  0x47,  0x4d,  0x42,  0x48,  
+   0x31,  0x22,  0x30,  0x20,  0x06,  0x03,  0x55,  0x04,  
+   0x0b,  0x13,  0x19,  0x54,  0x43,  0x20,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x43,  0x45,  0x4e,  0x54,  0x45,  
+   0x52,  0x20,  0x43,  0x4c,  0x41,  0x53,  0x53,  0x20,  
+   0x31,  0x20,  0x43,  0x41,  0x31,  0x29,  0x30,  0x27,  
+   0x06,  0x09,  0x2a,  0x86,  0x48,  0x86,  0xf7,  0x0d,  
+   0x01,  0x09,  0x01,  0x16,  0x1a,  0x63,  0x65,  0x72,  
+   0x74,  0x69,  0x66,  0x69,  0x63,  0x61,  0x74,  0x65,  
+   0x40,  0x74,  0x72,  0x75,  0x73,  0x74,  0x63,  0x65,  
+   0x6e,  0x74,  0x65,  0x72,  0x2e,  0x64,  0x65
+};
+static const CSSM_DATA TC_Class_1_subject = { 191, (uint8 *)TC_Class_1_subject_bytes };
+static const uint8 TC_Class_1_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xb0,  
+   0x29,  0xeb,  0xb4,  0x76,  0xb3,  0xae,  0xd7,  0xb6,  
+   0x5b,  0xb4,  0x5e,  0xe7,  0xbd,  0xe3,  0xb1,  0x9c,  
+   0x49,  0x04,  0x57,  0x5b,  0xa1,  0xab,  0xd9,  0x7f,  
+   0x13,  0x1b,  0xfd,  0xba,  0x61,  0xab,  0xd8,  0xe7,  
+   0x71,  0xdf,  0x2d,  0x00,  0x94,  0x5d,  0x51,  0x48,  
+   0x7d,  0x23,  0xef,  0x75,  0x62,  0x84,  0x90,  0x3c,  
+   0x0a,  0x1f,  0x59,  0x11,  0x74,  0x2f,  0x8e,  0x80,  
+   0xa5,  0xfd,  0x30,  0x02,  0x3d,  0x29,  0x52,  0xcd,  
+   0x72,  0x1a,  0x49,  0x21,  0x9c,  0xbc,  0xcb,  0x52,  
+   0x8e,  0x48,  0xa1,  0x63,  0x96,  0xc8,  0x10,  0x85,  
+   0x30,  0x69,  0x57,  0x74,  0x45,  0xc0,  0x5a,  0x86,  
+   0xc6,  0xd5,  0x3d,  0xe0,  0x68,  0x57,  0x7d,  0x31,  
+   0x6a,  0x24,  0x8d,  0x45,  0x97,  0x3e,  0x31,  0x7e,  
+   0x68,  0x66,  0x32,  0x6e,  0x24,  0x6d,  0xec,  0x32,  
+   0x36,  0xc9,  0x41,  0xca,  0xf0,  0x31,  0x44,  0xc8,  
+   0xa3,  0x61,  0xca,  0x1b,  0xa0,  0x36,  0x1f,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA TC_Class_1_pubKey = { 140, (uint8 *)TC_Class_1_pubKey_bytes };
+
+
+/***********************
+Cert File Name: TC_Class_2.cer
+Subject Name       :
+    Country        : DE
+    State          : Hamburg
+    Locality       : Hamburg
+    Org            : TC TrustCenter for Security in Data Networks GmbH
+    OrgUnit        : TC TrustCenter Class 2 CA
+    Email addrs    : certificate@trustcenter.de
+ ***********************/
+static const uint8 TC_Class_2_subject_bytes[] = {
+   0x30,  0x81,  0xbc,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x44,  0x45,  
+   0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x07,  0x48,  0x41,  0x4d,  0x42,  0x55,  
+   0x52,  0x47,  0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  
+   0x55,  0x04,  0x07,  0x13,  0x07,  0x48,  0x41,  0x4d,  
+   0x42,  0x55,  0x52,  0x47,  0x31,  0x3a,  0x30,  0x38,  
+   0x06,  0x03,  0x55,  0x04,  0x0a,  0x13,  0x31,  0x54,  
+   0x43,  0x20,  0x54,  0x52,  0x55,  0x53,  0x54,  0x43,  
+   0x45,  0x4e,  0x54,  0x45,  0x52,  0x20,  0x46,  0x4f,  
+   0x52,  0x20,  0x53,  0x45,  0x43,  0x55,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x49,  0x4e,  0x20,  0x44,  0x41,  
+   0x54,  0x41,  0x20,  0x4e,  0x45,  0x54,  0x57,  0x4f,  
+   0x52,  0x4b,  0x53,  0x20,  0x47,  0x4d,  0x42,  0x48,  
+   0x31,  0x22,  0x30,  0x20,  0x06,  0x03,  0x55,  0x04,  
+   0x0b,  0x13,  0x19,  0x54,  0x43,  0x20,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x43,  0x45,  0x4e,  0x54,  0x45,  
+   0x52,  0x20,  0x43,  0x4c,  0x41,  0x53,  0x53,  0x20,  
+   0x32,  0x20,  0x43,  0x41,  0x31,  0x29,  0x30,  0x27,  
+   0x06,  0x09,  0x2a,  0x86,  0x48,  0x86,  0xf7,  0x0d,  
+   0x01,  0x09,  0x01,  0x16,  0x1a,  0x63,  0x65,  0x72,  
+   0x74,  0x69,  0x66,  0x69,  0x63,  0x61,  0x74,  0x65,  
+   0x40,  0x74,  0x72,  0x75,  0x73,  0x74,  0x63,  0x65,  
+   0x6e,  0x74,  0x65,  0x72,  0x2e,  0x64,  0x65
+};
+static const CSSM_DATA TC_Class_2_subject = { 191, (uint8 *)TC_Class_2_subject_bytes };
+static const uint8 TC_Class_2_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xda,  
+   0x38,  0xe8,  0xed,  0x32,  0x00,  0x29,  0x71,  0x83,  
+   0x01,  0x0d,  0xbf,  0x8c,  0x01,  0xdc,  0xda,  0xc6,  
+   0xad,  0x39,  0xa4,  0xa9,  0x8a,  0x2f,  0xd5,  0x8b,  
+   0x5c,  0x68,  0x5f,  0x50,  0xc6,  0x62,  0xf5,  0x66,  
+   0xbd,  0xca,  0x91,  0x22,  0xec,  0xaa,  0x1d,  0x51,  
+   0xd7,  0x3d,  0xb3,  0x51,  0xb2,  0x83,  0x4e,  0x5d,  
+   0xcb,  0x49,  0xb0,  0xf0,  0x4c,  0x55,  0xe5,  0x6b,  
+   0x2d,  0xc7,  0x85,  0x0b,  0x30,  0x1c,  0x92,  0x4e,  
+   0x82,  0xd4,  0xca,  0x02,  0xed,  0xf7,  0x6f,  0xbe,  
+   0xdc,  0xe0,  0xe3,  0x14,  0xb8,  0x05,  0x53,  0xf2,  
+   0x9a,  0xf4,  0x56,  0x8b,  0x5a,  0x9e,  0x85,  0x93,  
+   0xd1,  0xb4,  0x82,  0x56,  0xae,  0x4d,  0xbb,  0xa8,  
+   0x4b,  0x57,  0x16,  0xbc,  0xfe,  0xf8,  0x58,  0x9e,  
+   0xf8,  0x29,  0x8d,  0xb0,  0x7b,  0xcd,  0x78,  0xc9,  
+   0x4f,  0xac,  0x8b,  0x67,  0x0c,  0xf1,  0x9c,  0xfb,  
+   0xfc,  0x57,  0x9b,  0x57,  0x5c,  0x4f,  0x0d,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA TC_Class_2_pubKey = { 140, (uint8 *)TC_Class_2_pubKey_bytes };
+
+
+/***********************
+Cert File Name: TC_Class_3.cer
+Subject Name       :
+    Country        : DE
+    State          : Hamburg
+    Locality       : Hamburg
+    Org            : TC TrustCenter for Security in Data Networks GmbH
+    OrgUnit        : TC TrustCenter Class 3 CA
+    Email addrs    : certificate@trustcenter.de
+ ***********************/
+static const uint8 TC_Class_3_subject_bytes[] = {
+   0x30,  0x81,  0xbc,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x44,  0x45,  
+   0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x07,  0x48,  0x41,  0x4d,  0x42,  0x55,  
+   0x52,  0x47,  0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  
+   0x55,  0x04,  0x07,  0x13,  0x07,  0x48,  0x41,  0x4d,  
+   0x42,  0x55,  0x52,  0x47,  0x31,  0x3a,  0x30,  0x38,  
+   0x06,  0x03,  0x55,  0x04,  0x0a,  0x13,  0x31,  0x54,  
+   0x43,  0x20,  0x54,  0x52,  0x55,  0x53,  0x54,  0x43,  
+   0x45,  0x4e,  0x54,  0x45,  0x52,  0x20,  0x46,  0x4f,  
+   0x52,  0x20,  0x53,  0x45,  0x43,  0x55,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x49,  0x4e,  0x20,  0x44,  0x41,  
+   0x54,  0x41,  0x20,  0x4e,  0x45,  0x54,  0x57,  0x4f,  
+   0x52,  0x4b,  0x53,  0x20,  0x47,  0x4d,  0x42,  0x48,  
+   0x31,  0x22,  0x30,  0x20,  0x06,  0x03,  0x55,  0x04,  
+   0x0b,  0x13,  0x19,  0x54,  0x43,  0x20,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x43,  0x45,  0x4e,  0x54,  0x45,  
+   0x52,  0x20,  0x43,  0x4c,  0x41,  0x53,  0x53,  0x20,  
+   0x33,  0x20,  0x43,  0x41,  0x31,  0x29,  0x30,  0x27,  
+   0x06,  0x09,  0x2a,  0x86,  0x48,  0x86,  0xf7,  0x0d,  
+   0x01,  0x09,  0x01,  0x16,  0x1a,  0x63,  0x65,  0x72,  
+   0x74,  0x69,  0x66,  0x69,  0x63,  0x61,  0x74,  0x65,  
+   0x40,  0x74,  0x72,  0x75,  0x73,  0x74,  0x63,  0x65,  
+   0x6e,  0x74,  0x65,  0x72,  0x2e,  0x64,  0x65
+};
+static const CSSM_DATA TC_Class_3_subject = { 191, (uint8 *)TC_Class_3_subject_bytes };
+static const uint8 TC_Class_3_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xb6,  
+   0xb4,  0xc1,  0x35,  0x05,  0x2e,  0x0d,  0x8d,  0xec,  
+   0xa0,  0x40,  0x6a,  0x1c,  0x0e,  0x27,  0xa6,  0x50,  
+   0x92,  0x6b,  0x50,  0x1b,  0x07,  0xde,  0x2e,  0xe7,  
+   0x76,  0xcc,  0xe0,  0xda,  0xfc,  0x84,  0xa8,  0x5e,  
+   0x8c,  0x63,  0x6a,  0x2b,  0x4d,  0xd9,  0x4e,  0x02,  
+   0x76,  0x11,  0xc1,  0x0b,  0xf2,  0x8d,  0x79,  0xca,  
+   0x00,  0xb6,  0xf1,  0xb0,  0x0e,  0xd7,  0xfb,  0xa4,  
+   0x17,  0x3d,  0xaf,  0xab,  0x69,  0x7a,  0x96,  0x27,  
+   0xbf,  0xaf,  0x33,  0xa1,  0x9a,  0x2a,  0x59,  0xaa,  
+   0xc4,  0xb5,  0x37,  0x08,  0xf2,  0x12,  0xa5,  0x31,  
+   0xb6,  0x43,  0xf5,  0x32,  0x96,  0x71,  0x28,  0x28,  
+   0xab,  0x8d,  0x28,  0x86,  0xdf,  0xbb,  0xee,  0xe3,  
+   0x0c,  0x7d,  0x30,  0xd6,  0xc3,  0x52,  0xab,  0x8f,  
+   0x5d,  0x27,  0x9c,  0x6b,  0xc0,  0xa3,  0xe7,  0x05,  
+   0x6b,  0x57,  0x49,  0x44,  0xb3,  0x6e,  0xea,  0x64,  
+   0xcf,  0xd2,  0x8e,  0x7a,  0x50,  0x77,  0x77,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA TC_Class_3_pubKey = { 140, (uint8 *)TC_Class_3_pubKey_bytes };
+
+
+/***********************
+Cert File Name: TC_Class_4.cer
+Subject Name       :
+    Country        : DE
+    State          : Hamburg
+    Locality       : Hamburg
+    Org            : TC TrustCenter for Security in Data Networks GmbH
+    OrgUnit        : TC TrustCenter Class 4 CA
+    Email addrs    : certificate@trustcenter.de
+ ***********************/
+static const uint8 TC_Class_4_subject_bytes[] = {
+   0x30,  0x81,  0xbc,  0x31,  0x0b,  0x30,  0x09,  0x06,  
+   0x03,  0x55,  0x04,  0x06,  0x13,  0x02,  0x44,  0x45,  
+   0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  0x55,  0x04,  
+   0x08,  0x13,  0x07,  0x48,  0x41,  0x4d,  0x42,  0x55,  
+   0x52,  0x47,  0x31,  0x10,  0x30,  0x0e,  0x06,  0x03,  
+   0x55,  0x04,  0x07,  0x13,  0x07,  0x48,  0x41,  0x4d,  
+   0x42,  0x55,  0x52,  0x47,  0x31,  0x3a,  0x30,  0x38,  
+   0x06,  0x03,  0x55,  0x04,  0x0a,  0x13,  0x31,  0x54,  
+   0x43,  0x20,  0x54,  0x52,  0x55,  0x53,  0x54,  0x43,  
+   0x45,  0x4e,  0x54,  0x45,  0x52,  0x20,  0x46,  0x4f,  
+   0x52,  0x20,  0x53,  0x45,  0x43,  0x55,  0x52,  0x49,  
+   0x54,  0x59,  0x20,  0x49,  0x4e,  0x20,  0x44,  0x41,  
+   0x54,  0x41,  0x20,  0x4e,  0x45,  0x54,  0x57,  0x4f,  
+   0x52,  0x4b,  0x53,  0x20,  0x47,  0x4d,  0x42,  0x48,  
+   0x31,  0x22,  0x30,  0x20,  0x06,  0x03,  0x55,  0x04,  
+   0x0b,  0x13,  0x19,  0x54,  0x43,  0x20,  0x54,  0x52,  
+   0x55,  0x53,  0x54,  0x43,  0x45,  0x4e,  0x54,  0x45,  
+   0x52,  0x20,  0x43,  0x4c,  0x41,  0x53,  0x53,  0x20,  
+   0x34,  0x20,  0x43,  0x41,  0x31,  0x29,  0x30,  0x27,  
+   0x06,  0x09,  0x2a,  0x86,  0x48,  0x86,  0xf7,  0x0d,  
+   0x01,  0x09,  0x01,  0x16,  0x1a,  0x63,  0x65,  0x72,  
+   0x74,  0x69,  0x66,  0x69,  0x63,  0x61,  0x74,  0x65,  
+   0x40,  0x74,  0x72,  0x75,  0x73,  0x74,  0x63,  0x65,  
+   0x6e,  0x74,  0x65,  0x72,  0x2e,  0x64,  0x65
+};
+static const CSSM_DATA TC_Class_4_subject = { 191, (uint8 *)TC_Class_4_subject_bytes };
+static const uint8 TC_Class_4_pubKey_bytes[] = {
+   0x30,  0x81,  0x89,  0x02,  0x81,  0x81,  0x00,  0xbf,  
+   0x2f,  0x63,  0xd6,  0x36,  0x7b,  0xb2,  0x0d,  0xd3,  
+   0x55,  0xf5,  0x64,  0x6c,  0xe6,  0x25,  0x5d,  0xc6,  
+   0xb4,  0xc8,  0x14,  0xba,  0x25,  0x38,  0x83,  0xeb,  
+   0x56,  0x62,  0xa5,  0x55,  0xa9,  0x65,  0xa3,  0xf4,  
+   0x23,  0x99,  0xc2,  0x4b,  0xb9,  0xd0,  0xcd,  0x54,  
+   0x67,  0xa6,  0xa3,  0xa0,  0xa3,  0xa9,  0x33,  0x2b,  
+   0x76,  0xe4,  0xbd,  0xad,  0x77,  0xb2,  0xed,  0x5c,  
+   0x12,  0x74,  0xc3,  0xc5,  0xb6,  0x0f,  0x52,  0x9a,  
+   0x72,  0x93,  0x43,  0x90,  0x62,  0x66,  0x15,  0x0f,  
+   0x45,  0xa5,  0xdd,  0xe0,  0xdd,  0xb8,  0x6f,  0x40,  
+   0x6e,  0x57,  0xc1,  0x79,  0x72,  0xa3,  0x60,  0xaa,  
+   0xba,  0x76,  0x1d,  0x12,  0x89,  0x53,  0x5a,  0xfc,  
+   0x02,  0xbe,  0xe1,  0x09,  0x13,  0xc5,  0x4a,  0x2f,  
+   0xdc,  0x3d,  0x8b,  0x19,  0xad,  0xd7,  0x8b,  0x24,  
+   0x45,  0xfb,  0x4c,  0xf4,  0xcd,  0x5c,  0x35,  0x1d,  
+   0x29,  0x4c,  0x51,  0xf3,  0xf2,  0x6c,  0x55,  0x02,  
+   0x03,  0x01,  0x00,  0x01
+};
+static const CSSM_DATA TC_Class_4_pubKey = { 140, (uint8 *)TC_Class_4_pubKey_bytes };
+
+
+/* end of static data generated by extractCertFields */
+
+const tpRootCert sslRootCerts[] = 
+{
+    { &Class1_PCA_G2_v2_subject, &Class1_PCA_G2_v2_pubKey, 1024 },
+    { &Class2_PCA_G2_v2_subject, &Class2_PCA_G2_v2_pubKey, 1024 },
+    { &Class3_PCA_G2_v2_subject, &Class3_PCA_G2_v2_pubKey, 1024 },
+    { &Class4_PCA_G2_v2_subject, &Class4_PCA_G2_v2_pubKey, 1024 },
+    { &PCA1ss_v4_subject, &PCA1ss_v4_pubKey, 1024 },
+    { &PCA2ss_v4_subject, &PCA2ss_v4_pubKey, 1024 },
+    { &PCA3ss_v4_subject, &PCA3ss_v4_pubKey, 1024 },
+    { &RSASecureServer_subject, &RSASecureServer_pubKey, 1000 },
+    { &persbasi_subject, &persbasi_pubKey, 1024 },
+    { &persfree_subject, &persfree_pubKey, 1024 },
+    { &persprem_subject, &persprem_pubKey, 1024 },
+    { &serverpremium_subject, &serverpremium_pubKey, 1024 },
+    { &serverbasic_subject, &serverbasic_pubKey, 1024 },
+    { &GTECyberTrustGlobalRoot_subject, &GTECyberTrustGlobalRoot_pubKey, 1024 },
+    { &GTECyberTrustRoot_subject, &GTECyberTrustRoot_pubKey, 1024 },
+    { &GTECyberTrustRoot2_subject, &GTECyberTrustRoot2_pubKey, 1024 },
+    { &GTECyberTrustRoot3_subject, &GTECyberTrustRoot3_pubKey, 1024 },
+    { &GTECyberTrustRoot4_subject, &GTECyberTrustRoot4_pubKey, 2048 },
+    { &GTECyberTrustRoot5_subject, &GTECyberTrustRoot5_pubKey, 2048 },
+    { &BTCTRoot_subject, &BTCTRoot_pubKey, 2048 },
+    { &BTCTcodert_subject, &BTCTcodert_pubKey, 2048 },
+    { &BTCTmort_subject, &BTCTmort_pubKey, 1024 },
+    { &TC_Class_0_subject, &TC_Class_0_pubKey, 1024 },
+    { &TC_Class_1_subject, &TC_Class_1_pubKey, 1024 },
+    { &TC_Class_2_subject, &TC_Class_2_pubKey, 1024 },
+    { &TC_Class_3_subject, &TC_Class_3_pubKey, 1024 },
+    { &TC_Class_4_subject, &TC_Class_4_pubKey, 1024 },
+
+};
+
+const unsigned numSslRootCerts = sizeof(sslRootCerts) / sizeof(tpRootCert);
diff --git a/AppleX509TP/tpCertGroup.cpp b/AppleX509TP/tpCertGroup.cpp
new file mode 100644
index 00000000..4f172db3
--- /dev/null
+++ b/AppleX509TP/tpCertGroup.cpp
@@ -0,0 +1,645 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tpCertGroup.cpp - Cert group functions (construct, verify) 
+ *
+ * Created 10/5/2000 by Doug Mitchell.
+ */
+ 
+#include "AppleTPSession.h"
+#include "certGroupUtils.h"
+#include "TPCertInfo.h"
+#include "tpPolicies.h"
+#include "tpdebugging.h"
+#include <Security/oidsalg.h>
+
+
+/*-----------------------------------------------------------------------------
+ * CertGroupConstruct
+ *
+ * Description:
+ *   This function returns a pointer to a mallocd CSSM_CERTGROUP which
+ *   refers to a mallocd list of raw ordered X.509 certs which verify back as
+ *   far as the TP is able to go. The first cert of the returned list is the
+ *   subject cert. The TP will attempt to search thru the DBs passed in
+ *   DBList in order to complete the chain. The chain is completed when a
+ *   self-signed (root) cert is found in the chain. The root cert may be
+ *   present in the input CertGroupFrag, or it may have been obtained from
+ *   one of the DBs passed in DBList. It is not an error if no root cert is
+ *   found. 
+ *   
+ *   The error conditions are: 
+ *   -- The first cert of CertGroupFrag is an invalid cert. NULL is returned,
+ *		err = CSSM_TP_INVALID_CERTIFICATE.
+ *   -- The root cert (if found) fails to verify. Valid certgroup is returned,
+ *      err = CSSMERR_TP_VERIFICATION_FAILURE.
+ *   -- Any cert in the (possibly partially) constructed chain has expired or
+ *      isn't valid yet, err = CSSMERR_TP_CERT_EXPIRED or 
+ *      CSSMERR_TP_CERT_NOT_VALID_YET. A CertGroup is returned. 
+ *   -- CSSMERR_TP_CERT_EXPIRED and CSSMERR_TP_CERT_NOT_VALID_YET. If one of these
+ *		conditions obtains for the first (leaf) cert, the function throws this
+ *		error immediately and the outgoing cert group is empty. For subsequent certs,
+ *		the temporal validity of a cert is only tested AFTER a cert successfully
+ *		meets the cert chaining criteria (subject/issuer match and signature
+ *		verify). A cert in a chain with this error is not added to the outgoing
+ *		cert group. 
+ *   -- the usual errors like bad handle or memory failure. 
+ *
+ * Parameters:
+ *   Two handles - to an open CL and CSP. The CSP must be capable of
+ *   dealing with the signature algorithms used by the certs. The CL must be
+ *   an X.509-savvy CL.  
+ *   
+ *   CertGroupFrag, an unordered array of raw X.509 certs in the form of a
+ *   CSSM_CERTGROUP_PTR. The first cert of this list is the subject cert
+ *   which is eventually to be verified. The other certs can be in any order 
+ *   and may not even have any relevance to the cert chain being constructed. 
+ *   They may also be invalid certs. 
+ *   
+ *   DBList, a list of DB/DL handles which may contain certs necessary to
+ *   complete the desired cert chain. (Not currently implemented.)
+ *
+ *---------------------------------------------------------------------------*/
+ 
+/* public version */
+void AppleTPSession::CertGroupConstruct(CSSM_CL_HANDLE clHand,
+		CSSM_CSP_HANDLE cspHand,
+		const CSSM_DL_DB_LIST &DBList,
+		const void *ConstructParams,
+		const CSSM_CERTGROUP &CertGroupFrag,
+		CSSM_CERTGROUP_PTR &CertGroup)
+{
+	TPCertGroup *tpCertGroup;
+	CertGroupConstructPriv(clHand,
+		cspHand,
+		DBList,
+		ConstructParams,
+		CertGroupFrag,
+		CSSM_FALSE,			// allowExpired
+		tpCertGroup);
+	CertGroup = tpCertGroup->buildCssmCertGroup();
+	delete tpCertGroup;	
+}
+
+
+/* 
+ * Private version of CertGroupConstruct, used by CertGroupConstruct and
+ * CertGroupVerify. Returns a TP-style TPCertGroup for further processing.
+ * This only throws CSSM-style exceptions in the following cases: 
+ * 
+ *  -- input parameter errors
+ *  -- the first (leaf) cert is bad (doesn't parse, expired, not valid yet).
+ *
+ *  All other cert-related errors simply result in the bad cert being ignored.
+ *  Other exceptions are gross system errors like malloc failure.
+ */
+void AppleTPSession::CertGroupConstructPriv(CSSM_CL_HANDLE clHand,
+		CSSM_CSP_HANDLE cspHand,
+		const CSSM_DL_DB_LIST &DBList,
+		const void *ConstructParams,
+		const CSSM_CERTGROUP &CertGroupFrag,
+		CSSM_BOOL allowExpired,
+		TPCertGroup *&CertGroup)
+{
+	TPCertGroup			*inCertGroup;				// unordered input certs
+	TPCertGroup			*outCertGroup;				// ordered, verified output certs
+
+	/*
+	 * subjectCert refers to the cert we're currently trying to verify. It's either
+	 * an element in inCertGroup (if we're verifying a cert from the incoming
+	 * CertGroupFrag) or dbSubject (if we're verifying a cert which came from a DB).
+	 *
+	 * Similarly, issuerCert, when non-NULL, points to a cert which has just
+	 * been located as a verifiable issuer of subjectCert. It points to either
+	 * an element in inCertGroup or to dbIssuer.
+	 */
+	TPCertInfo			*subjectCert;				// the one we're working on
+	TPCertInfo			*issuerCert = NULL;			// verified as next one in chain
+	TPCertInfo			*certInfo;					// working cert
+	unsigned			certDex;					// index into certInfo
+	CSSM_RETURN			crtn;
+	CSSM_RETURN			outErr = CSSM_OK;
+	
+	/* verify input args */
+	if(cspHand == CSSM_INVALID_HANDLE) {
+		CssmError::throwMe(CSSMERR_TP_INVALID_CSP_HANDLE);
+	}
+	if(clHand == CSSM_INVALID_HANDLE)	{
+		CssmError::throwMe(CSSMERR_TP_INVALID_CL_HANDLE);
+	}
+	if( (CertGroupFrag.NumCerts == 0) ||				// list is empty
+	    (CertGroupFrag.CertGroupType != CSSM_CERTGROUP_ENCODED_CERT) ||
+	    (CertGroupFrag.GroupList.CertList[0].Data == NULL) ||	// first cert empty
+	    (CertGroupFrag.GroupList.CertList[0].Length == 0)) {		// first cert empty
+		CssmError::throwMe(CSSMERR_CL_INVALID_CERTGROUP_POINTER);
+	}
+	switch(CertGroupFrag.CertType) {
+		case CSSM_CERT_X_509v1:
+		case CSSM_CERT_X_509v2:
+		case CSSM_CERT_X_509v3:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_TP_UNKNOWN_FORMAT);
+	}
+	switch(CertGroupFrag.CertEncoding) {
+		case CSSM_CERT_ENCODING_BER:
+		case CSSM_CERT_ENCODING_DER:
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_TP_UNKNOWN_FORMAT);
+	}
+	
+	/* 
+	 * Set up incoming and outgoing TPCertGrorups. 
+	 */
+	inCertGroup  = new TPCertGroup(*this, CertGroupFrag.NumCerts - 1);
+	outCertGroup = new TPCertGroup(*this, CertGroupFrag.NumCerts);
+	
+	/*
+	 * Parse first (leaf) cert. Note that this cert is special: if it's bad we abort
+	 * immediately; otherwise it goes directly into outCertGroup.
+	 */
+	try {
+		certInfo = new TPCertInfo(
+			&CertGroupFrag.GroupList.CertList[0],
+			clHand);
+	}
+	catch(CssmError cerr) {
+		outErr = CSSMERR_TP_INVALID_CERTIFICATE;
+		goto abort;
+	}
+	catch(...) {
+		/* everything else is way fatal */
+		throw;
+	}
+	
+	/* verify this first one is current */
+	outErr = certInfo->isCurrent(allowExpired);
+	if(outErr) {
+		goto abort;
+	}
+	
+	/* Add to outCertGroup */
+	outCertGroup->appendCert(certInfo);
+	
+	/* this'll be the first subject cert in the main loop */
+	subjectCert = certInfo;
+	
+	/* 
+	 * Add remaining input certs to inCertGroup. Note that this lets us 
+	 * skip bad incoming certs right away.
+	 */
+	for(certDex=1; certDex<CertGroupFrag.NumCerts; certDex++) {
+		try {
+			certInfo = new TPCertInfo(&CertGroupFrag.GroupList.CertList[certDex],
+				clHand);
+		}
+		catch (...) {
+			/* just ignore this cert */
+			continue;
+		}
+		inCertGroup->appendCert(certInfo);
+	}
+	
+	/*** main loop ***
+	 *
+	 * On entry, we have two TPCertGroups. InCertGroup contains n-1 certs, where n 
+	 * is the size of the CertGroupFrag passed to us by the caller. The certs in
+	 * inCertGroup are unordered but are known to be parseable, CL-cacheable certs.
+	 * OutGroupCert contains one cert, the incoming leaf cert.
+	 *
+	 * The job in this loop is to build an ordered, verified cert chain in  
+	 * outCertGroup out of certs from inCertGroup and/or DBList. As good certs
+	 * are found in inCertGroup, they're removed from that TPCertGroup. On exit
+	 * we delete inCertGroup, which deletes all the remaining TPCertInfo's in it. 
+	 * The constructed outCertGroup is returned to the caller. 
+	 *
+	 * Exit loop on: 
+	 *   -- find a root cert in the chain
+	 *   -- memory error
+	 *   -- or no more certs to add to chain. 
+	 */
+	for(;;) {
+		/* top of loop: subjectCert is the cert we're trying to verify. */
+		
+		/* is this a root cert?  */
+		if(subjectCert->isSelfSigned()) {
+			/*
+			 * Verify this alleged root cert. We're at the end of the chain no 
+			 * matter what happens here. 
+			 * Note we already validated before/after when this was tested
+			 * as issuer (or, if it's the leaf cert, before we entered this loop). 
+			 */ 
+			outErr = tp_VerifyCert(clHand,
+				cspHand,
+				subjectCert,
+				subjectCert,
+				CSSM_FALSE,		// checkIssuerCurrent
+				CSSM_TRUE);		// allowExpired, don't care
+			break;
+		}
+		
+		/* Search unused incoming certs to find an issuer */
+		for(certDex=0; certDex<inCertGroup->numCerts(); certDex++) {
+			certInfo = inCertGroup->certAtIndex(certDex);
+			
+			/* potential issuer - names match? */
+			if(tpIsSameName(subjectCert->issuerName(), certInfo->subjectName())) {
+				/* yep, do a sig verify with "not before/after" check */
+				crtn = tp_VerifyCert(clHand,
+					cspHand,
+					subjectCert,
+					certInfo,
+					CSSM_TRUE,
+					allowExpired);			
+				switch(crtn) {
+					case CSSM_OK:
+						/* YES! We'll add it to outCertGroup below...*/
+						issuerCert = certInfo;
+						inCertGroup->removeCertAtIndex(certDex);
+						goto issuerLoopEnd;
+					case CSSMERR_TP_CERT_NOT_VALID_YET:
+					case CSSMERR_TP_CERT_EXPIRED:
+						/* special case - abort immediateley (note the cert
+						 * sig verify succeeded.) */
+						outErr = crtn;
+						goto abort;
+					default:
+						/* just skip this one and keep looking */
+						break;
+				}
+			} 	/* names match */
+		} 		/* searching inCertGroup for issuer */
+		
+issuerLoopEnd:
+
+		#if	TP_DL_ENABLE
+		if(issuerCert == NULL) {
+			/* Issuer not in incoming cert group. Search DBList. */
+			CSSM_DATA_PTR foundCert;
+			
+			foundCert = tpFindIssuer(tpHand,
+				clHand,
+				cspHand,
+				subjectCert->certData(),
+				subjectCert->issuerName(),
+				DBList,
+				&subjectExpired);
+			if(subjectExpired) {
+				/* special case - abort immediately */
+				outErr = subjectExpired;
+				goto abort;
+			}
+			if(foundCert != NULL) {
+				/* set issuerCert for this found cert */
+				issuerCert = new TPCertInfo(foundCert,
+					clHand,
+					true);				// *do* copy
+				/* 
+				 * free cert data obtained from DB 
+				 * FIXME: this assumes that OUR session allocators are the 
+				 * same ones used by the DL to malloc this cert!
+				 * FIXME: handle exception here 
+				 */
+				tpFreeCssmData(*this, foundCert, CSSM_TRUE);
+			}
+		}	/*  Issuer not in incoming cert group */
+		#endif	/* TP_DL_ENABLE */
+		
+		if(issuerCert == NULL) {
+			/* end of search, broken chain */
+			break;
+		}
+		
+		/*
+		 * One way or the other, we've found a cert which verifies subjectCert.
+		 * Add the issuer to outCertGroup and make it the new subjectCert for
+		 * the next pass.
+		 */
+		outCertGroup->appendCert(issuerCert);
+		subjectCert = issuerCert;
+		issuerCert = NULL;
+	}	/* main loop */
+	
+abort:
+	delete inCertGroup;
+	CertGroup = outCertGroup;
+	if(outErr) {
+		CssmError::throwMe(outErr);
+	}
+}
+/*-----------------------------------------------------------------------------
+ * CertGroupVerify
+ *
+ * Description:
+ *   -- Construct a cert chain using TP_CertGroupConstruct. 
+ *   -- Attempt to verify that cert chain against one of the known 
+ *      good certs passed in AnchorCerts. 
+ *   -- Optionally enforces additional policies (TBD) when verifying the cert chain.
+ *   -- Optionally returns the entire cert chain constructed in 
+ *      TP_CertGroupConstruct and here, all the way to an anchor cert or as 
+ *      far as we were able to go, in *Evidence. 
+ *
+ * Parameters:
+ *   Two handles - to an open CL and CSP. The CSP must be capable of
+ *   dealing with the signature algorithms used by the certs. The CL must be
+ *   an X.509-savvy CL.  
+ *   
+ *   RawCerts, an unordered array of raw certs in the form of a
+ *   CSSM_CERTGROUP_PTR. The first cert of this list is the subject cert
+ *   which is eventually to be verified. The other certs can be in any order
+ *   and may not even have any relevance to the cert chain being constructed.
+ *   They may also be invalid certs. 
+ *   
+ *   DBList, a list of DB/DL handles which may contain certs necessary to
+ *   complete the desired cert chain. (Currently not implemented.)
+ *   
+ *   AnchorCerts, a list of known trusted certs. 
+ *   NumberOfAnchorCerts, size of AnchorCerts array. 
+ *   
+ *   PolicyIdentifiers, Optional policy OID. NULL indicates default
+ *		X.509 trust policy.
+ *
+ *	 Supported Policies:
+ *			CSSMOID_APPLE_ISIGN
+ *			CSSMOID_APPLE_X509_BASIC
+ *		
+ *			For both of these, the associated FieldValue must be {0, NULL},
+ *
+ *   NumberOfPolicyIdentifiers, size of PolicyIdentifiers array, must be 
+ *      zero or one. 
+ * 
+ *   All other arguments must be zero/NULL.
+ *
+ *   Returns:
+ *      CSSM_OK : cert chain verified all the way back to an AnchorCert.
+ *      CSSMERR_TP_INVALID_ANCHOR_CERT : In this case, the cert chain
+ *   		was validated back to a self-signed (root) cert found in either
+ *   		CertToBeVerified or in one of the DBs in DBList, but that root cert
+ *   		was *NOT* found in the AnchorCert list. 
+ *		CSSMERR_TP_NOT_TRUSTED: no root cert was found and no AnchorCert
+ *   		verified the end of the constructed cert chain.
+ *		CSSMERR_TP_VERIFICATION_FAILURE: a root cert was found which does
+ *   		not self-verify. 
+ *   	CSSMERR_TP_VERIFY_ACTION_FAILED: indicates a failure of the requested 
+ *			policy action. 
+ *   	CSSMERR_TP_INVALID_CERTIFICATE: indicates a bad leaf cert. 
+ *		CSSMERR_TP_INVALID_REQUEST_INPUTS : no incoming VerifyContext.
+ *		CSSMERR_TP_CERT_EXPIRED and CSSMERR_TP_CERT_NOT_VALID_YET: see comments
+ *			for CertGroupConstruct. 
+ *---------------------------------------------------------------------------*/
+
+void AppleTPSession::CertGroupVerify(CSSM_CL_HANDLE clHand,
+		CSSM_CSP_HANDLE cspHand,
+		const CSSM_CERTGROUP &CertGroupToBeVerified,
+		const CSSM_TP_VERIFY_CONTEXT *VerifyContext,
+		CSSM_TP_VERIFY_CONTEXT_RESULT_PTR VerifyContextResult)
+{
+	unsigned				i;
+	TPCertInfo				*lastCert;
+	CSSM_BOOL				verifiedToRoot = CSSM_FALSE;
+	TPPolicy				policy;
+	CSSM_RETURN				outErr = CSSM_OK;
+	CSSM_RETURN				crtn;
+	const CSSM_TP_CALLERAUTH_CONTEXT *cred;
+	CSSM_OID_PTR 			oid = NULL;
+	CSSM_BOOL				allowExpired = CSSM_FALSE;
+	TPCertGroup 			*tpCertGroup = NULL;	// created by
+													//   CertGroupConstructPriv
+	TPCertInfo 				*certInfo = NULL;
+	
+	/* verify input args, skipping the ones checked by CertGroupConstruct */
+	if((VerifyContext == NULL) || (VerifyContext->Cred == NULL)) {
+		/* the spec says that this is optional but we require it */
+			CssmError::throwMe(CSSMERR_TP_INVALID_REQUEST_INPUTS);
+	}
+	cred = VerifyContext->Cred;
+	
+	/* allow cert expiration errors? */
+	if(cred->Policy.PolicyControl == CSSM_TP_ALLOW_EXPIRE) {
+		allowExpired = CSSM_TRUE;
+	}
+	
+	/* Check out requested policies */
+	switch(cred->Policy.NumberOfPolicyIds) {
+		case 0:
+			/* default */
+			policy = kTPDefault;
+			break;			
+	    case 1:
+	    	if(cred->Policy.PolicyIds == NULL) {
+				CssmError::throwMe(CSSMERR_TP_INVALID_POLICY_IDENTIFIERS);
+	    	}
+			
+			/*
+			 * none of the supported policies allow any additional params 
+			 */
+			if((cred->Policy.PolicyIds->FieldValue.Data != NULL) ||
+				(cred->Policy.PolicyIds->FieldValue.Length != 0)) {
+				CssmError::throwMe(CSSMERR_TP_INVALID_POLICY_IDENTIFIERS);
+			}
+			oid = &cred->Policy.PolicyIds->FieldOid;
+	    	if(tpCompareOids(oid, &CSSMOID_APPLE_ISIGN)) {
+				policy = kTPiSign;
+	    	}
+	    	else if(tpCompareOids(oid, &CSSMOID_APPLE_X509_BASIC)) {
+				policy = kTPx509Basic;
+	    	}
+	    	else if(tpCompareOids(oid, &CSSMOID_APPLE_TP_SSL)) {
+				policy = kTP_SSL;
+	    	}
+	    	else {
+	    		/* unknown TP OID */
+				CssmError::throwMe(CSSMERR_TP_INVALID_POLICY_IDENTIFIERS);
+	    	}
+	    	break;
+		default:
+			/* only zero or one allowed */
+			CssmError::throwMe(CSSMERR_TP_INVALID_POLICY_IDENTIFIERS);
+	} 
+	
+	/* now the args we can't deal with */
+	if(cred->CallerCredentials != NULL) {
+			CssmError::throwMe(CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER);
+	}
+	/* FIXME - ANY OTHERS? */
+	
+	/* get verified (possibly partial) outCertGroup - error is fatal */
+	/* BUT: we still return partial evidence if asked to...from now on. */
+	try {
+		CertGroupConstructPriv(
+			clHand,
+			cspHand,
+			*cred->DBList, 		// not optional to Construct!
+			NULL,
+			CertGroupToBeVerified,
+			allowExpired,
+			tpCertGroup);
+	}
+	catch(CssmError cerr) {
+		outErr = cerr.cssmError();
+		goto out;
+	}
+	/* others are way fatal */
+	CASSERT(tpCertGroup != NULL);
+	CASSERT(tpCertGroup->numCerts() >= 1);
+	
+	/* subsequent errors and returns to out: */
+
+	/*
+	 * Case 1: last cert in outCertGroup is a root cert. See if 
+	 * the root cert is in AnchorCerts.
+	 * Note that TP_CertGroupConstruct did the actual root 
+	 * self-verify test.
+	 */
+	lastCert = tpCertGroup->lastCert();
+	if(lastCert->isSelfSigned()) {
+		verifiedToRoot = CSSM_TRUE;
+		
+		/* see if that root cert is identical to one of the anchor certs */
+		for(i=0; i<cred->NumberOfAnchorCerts; i++) {
+			if(tp_CompareCerts(lastCert->certData(), &cred->AnchorCerts[i])) {
+				/* one fully successful return */
+				outErr = CSSM_OK;
+				goto out;
+			}
+		}
+		
+		/* verified to a root cert which is not an anchor */
+		outErr = CSSMERR_TP_INVALID_ANCHOR_CERT;
+		goto out;
+	}
+
+	/* try to validate lastCert with anchor certs */
+	/* note we're skipping the subject/issuer check...OK? */
+	for(i=0; i<cred->NumberOfAnchorCerts; i++) {
+		try {
+			certInfo = new TPCertInfo(&cred->AnchorCerts[i],
+				clHand);
+		}
+		catch(...) {
+			/* bad anchor cert - ignore it */
+			continue;
+		}
+		crtn = tp_VerifyCert(clHand, 
+			cspHand, 
+			lastCert, 
+			certInfo, 
+			CSSM_TRUE,				// check not/before of anchor
+			allowExpired);
+		switch(crtn) {
+			case CSSM_OK:
+				/*  The other normal fully successful return. */
+				outErr = CSSM_OK;
+				if(certInfo->isSelfSigned()) {
+					verifiedToRoot = CSSM_TRUE;	
+				}
+				
+				/*
+				 * One more thing: add this anchor cert to the Evidence chain
+				 */
+				try {
+					tpCertGroup->appendCert(certInfo);
+				}
+				catch(...) {
+					/* shoot - must be memory error */
+					verifiedToRoot = CSSM_FALSE;
+					delete certInfo;
+					outErr = CSSMERR_TP_MEMORY_ERROR;
+				}
+				goto out;
+				
+			case CSSMERR_TP_CERT_NOT_VALID_YET:
+			case CSSMERR_TP_CERT_EXPIRED:
+				/* special case - abort immediateley */
+				delete certInfo;
+				outErr = crtn;
+				goto out;
+			default:
+				/* continue to next anchor */
+				delete certInfo;
+				break;
+		}
+	}	/* for each anchor */
+	
+	/* partial chain, no root, not verifiable by anchor */
+	outErr = CSSMERR_TP_NOT_TRUSTED;
+
+	/* common exit - error or success */
+out:
+	/* 
+	 * Do further policy verification if appropriate.
+	 *
+	 * SSL: CSSMERR_TP_NOT_TRUSTED and CSSMERR_TP_INVALID_ANCHOR_CERT
+	 * are both special cases which can result in full success. 
+	 */
+	if((policy == kTP_SSL) && (outErr == CSSMERR_TP_NOT_TRUSTED)) {
+		/* see if last cert can be verified by an embedded SSL root */
+		certInfo = tpCertGroup->lastCert();
+		CSSM_BOOL brtn = tp_verifyWithSslRoots(clHand, 
+			cspHand, 
+			certInfo);
+		if(brtn) {
+			/* SSL success with no incoming root */
+			/* note unknown incoming root (INVALID_ANCHOR_CERT) is handled
+			 * below, after tp_policyVerify */
+			outErr = CSSM_OK;
+		}
+	}
+	if((outErr == CSSM_OK) ||							// full success so far 
+	   (outErr == CSSMERR_TP_INVALID_ANCHOR_CERT)) {	// OK, but root not an anchor
+		
+		CSSM_RETURN crtn = tp_policyVerify(policy,
+			*this,
+			clHand,
+			cspHand,
+			tpCertGroup,
+			verifiedToRoot);
+		if(crtn) {
+			/* don't override existing INVALID_ANCHOR_CERT on policy success */
+			outErr = crtn;
+		}
+		else if((outErr == CSSMERR_TP_INVALID_ANCHOR_CERT) && (policy == kTP_SSL)) {
+			/* SSL - found a good anchor, move to full success */
+			outErr = CSSM_OK;
+		}
+	}
+
+	/* return evidence - i.e., current chain - if asked to */
+	if(VerifyContextResult != NULL) {
+		/* The spec is utterly bogus. We're going to punt and use
+		 * CSSM_EVIDENCE_FORM_UNSPECIFIC to mean just a pointer to
+		 * a CSSM_CERTGROUP. How's that!?
+		 */
+		VerifyContextResult->NumberOfEvidences = 1;
+		VerifyContextResult->Evidence = 
+			(CSSM_EVIDENCE_PTR)malloc(sizeof(CSSM_EVIDENCE));
+		VerifyContextResult->Evidence->EvidenceForm = CSSM_EVIDENCE_FORM_UNSPECIFIC;
+		VerifyContextResult->Evidence->Evidence = 
+			tpCertGroup->buildCssmCertGroup();
+	}
+	
+	/* delete (internaluse only) TPCertGroup */
+	delete tpCertGroup;
+	if(outErr) {
+		CssmError::throwMe(outErr);
+	}
+}
+
+
diff --git a/AppleX509TP/tpPolicies.cpp b/AppleX509TP/tpPolicies.cpp
new file mode 100644
index 00000000..177b72fe
--- /dev/null
+++ b/AppleX509TP/tpPolicies.cpp
@@ -0,0 +1,813 @@
+/*
+ * 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.
+ */
+
+
+/*
+	policies.cpp - TP module policy implementation
+
+	Created 10/9/2000 by Doug Mitchell. 
+*/
+
+#include <Security/cssmtype.h>
+#include <Security/cssmapi.h>
+#include "tpPolicies.h"
+#include <Security/oidsattr.h>
+#include <Security/cssmerr.h>
+#include "tpdebugging.h"
+#include "rootCerts.h"
+#include "certGroupUtils.h"
+#include <Security/x509defs.h>
+#include <Security/oidscert.h>
+#include <Security/certextensions.h>
+#include <Security/cssmapple.h>
+#include <string.h>
+
+/* 
+ * Our private per-extension info. One of these per (understood) extension per
+ * cert. 
+ */
+typedef struct {
+	CSSM_BOOL		present;
+	CSSM_BOOL		critical;
+	CE_Data       	*extnData;		// mallocd by CL
+	CSSM_DATA		*valToFree;		// the data we pass to freeField()
+} iSignExtenInfo;
+
+/*
+ * Struct to keep track of info pertinent to one cert.
+ */
+typedef struct {
+
+	/* extensions pertinent to iSign */
+	iSignExtenInfo		authorityId;
+	iSignExtenInfo		subjectId;
+	iSignExtenInfo		keyUsage;
+	iSignExtenInfo		extendKeyUsage;
+	iSignExtenInfo		basicConstraints;
+	iSignExtenInfo		netscapeCertType;
+				
+	/* flag indicating presence of a critical extension we don't understand */
+	CSSM_BOOL			foundUnknownCritical;
+	
+} iSignCertInfo;
+ 
+
+/*
+ * Setup a single iSignExtenInfo. Called once per known extension
+ * per cert. 
+ */
+static CSSM_RETURN tpSetupExtension(
+	CssmAllocator		&alloc, 
+	CSSM_DATA 			*extnData,
+	iSignExtenInfo		*extnInfo)		// which component of certInfo
+{
+	if(extnData->Length != sizeof(CSSM_X509_EXTENSION)) {
+		errorLog0("tpSetupExtension: malformed CSSM_FIELD\n");
+		return CSSMERR_TP_UNKNOWN_FORMAT;
+	}
+	CSSM_X509_EXTENSION *cssmExt = (CSSM_X509_EXTENSION *)extnData->Data;
+	extnInfo->present   = CSSM_TRUE;
+	extnInfo->critical  = cssmExt->critical;
+	extnInfo->extnData  = (CE_Data *)cssmExt->value.parsedValue;
+	extnInfo->valToFree = extnData;
+	return CSSM_OK;
+}
+
+/*
+ * Fetch a known extension, set up associated iSignExtenInfo if present.
+ */
+static CSSM_RETURN iSignFetchExtension(
+	CssmAllocator		&alloc, 
+	TPCertInfo			*tpCert,
+	const CSSM_OID		*fieldOid,		// which extension to fetch
+	iSignExtenInfo		*extnInfo)		// where the info goes
+{
+	CSSM_DATA_PTR	fieldValue;			// mallocd by CL
+	CSSM_RETURN		crtn;
+	
+	crtn = tpCert->fetchField(fieldOid, &fieldValue);
+	switch(crtn) {
+		case CSSM_OK:
+			break;
+		case CSSMERR_CL_NO_FIELD_VALUES:
+			/* field not present, OK */
+			return CSSM_OK;
+		default:
+			return crtn;
+	}
+	return tpSetupExtension(alloc,
+			fieldValue,
+			extnInfo);
+}
+
+/*
+ * Search for al unknown extensions. If we find one which is flagged critical, 
+ * flag certInfo->foundUnknownCritical. Only returns error on gross errors.  
+ */
+static CSSM_RETURN iSignSearchUnknownExtensions(
+	TPCertInfo			*tpCert,
+	iSignCertInfo		*certInfo)
+{
+	CSSM_RETURN 	crtn;
+	CSSM_DATA_PTR 	fieldValue = NULL;
+	CSSM_HANDLE		searchHand = CSSM_INVALID_HANDLE;
+	uint32 			numFields = 0;
+	
+	crtn = CSSM_CL_CertGetFirstCachedFieldValue(tpCert->clHand(),
+		tpCert->cacheHand(),
+		&CSSMOID_X509V3CertificateExtensionCStruct,
+		&searchHand,
+		&numFields, 
+		&fieldValue);
+	switch(crtn) {
+		case CSSM_OK:
+			/* found one, proceed */
+			break;
+		case CSSMERR_CL_NO_FIELD_VALUES:
+			/* no unknown extensions present, OK */
+			return CSSM_OK;
+		default:
+			return crtn;
+	}
+	
+	if(fieldValue->Length != sizeof(CSSM_X509_EXTENSION)) {
+		errorLog0("iSignSearchUnknownExtensions: malformed CSSM_FIELD\n");
+		return CSSMERR_TP_UNKNOWN_FORMAT;
+	}
+	CSSM_X509_EXTENSION *cssmExt = (CSSM_X509_EXTENSION *)fieldValue->Data;
+	if(cssmExt->critical) {
+		/* BRRZAPP! Found an unknown extension marked critical */
+		certInfo->foundUnknownCritical = CSSM_TRUE;
+		goto fini;
+	}
+	CSSM_CL_FreeFieldValue(tpCert->clHand(), 
+		&CSSMOID_X509V3CertificateExtensionCStruct, 
+		fieldValue);
+	fieldValue = NULL;
+	
+	/* process remaining unknown extensions */
+	for(unsigned i=1; i<numFields; i++) {
+		crtn = CSSM_CL_CertGetNextCachedFieldValue(tpCert->clHand(),
+			searchHand,
+			&fieldValue);
+		if(crtn) {
+			/* should never happen */
+			errorLog0("searchUnknownExtensions: GetNextCachedFieldValue error\n");
+			break;
+		}
+		if(fieldValue->Length != sizeof(CSSM_X509_EXTENSION)) {
+			errorLog0("iSignSearchUnknownExtensions: malformed CSSM_FIELD\n");
+			crtn = CSSMERR_TP_UNKNOWN_FORMAT;
+			break;
+		}
+		CSSM_X509_EXTENSION *cssmExt = (CSSM_X509_EXTENSION *)fieldValue->Data;
+		if(cssmExt->critical) {
+			/* BRRZAPP! Found an unknown extension marked critical */
+			certInfo->foundUnknownCritical = CSSM_TRUE;
+			break;
+		}
+		CSSM_CL_FreeFieldValue(tpCert->clHand(), 
+			&CSSMOID_X509V3CertificateExtensionCStruct, 
+			fieldValue);
+		fieldValue = NULL;
+	} /* for additional fields */
+				
+fini:
+	if(fieldValue) {
+		CSSM_CL_FreeFieldValue(tpCert->clHand(), 
+			&CSSMOID_X509V3CertificateExtensionCStruct, 
+			fieldValue);
+	}
+	if(searchHand != CSSM_INVALID_HANDLE) {
+		CSSM_CL_CertAbortQuery(tpCert->clHand(), searchHand);
+	}
+	return crtn;
+}
+/*
+ * Given a TPCertInfo, fetch the associated iSignCertInfo fields. 
+ * Returns CSSM_FAIL on error. 
+ */
+static CSSM_RETURN iSignGetCertInfo(
+	CssmAllocator		&alloc, 
+	TPCertInfo			*tpCert,
+	iSignCertInfo		*certInfo)
+{
+	CSSM_RETURN			crtn;
+	
+	/* first grind thru the extensions we're interested in */
+	crtn = iSignFetchExtension(alloc,
+		tpCert,
+		&CSSMOID_AuthorityKeyIdentifier,
+		&certInfo->authorityId);
+	if(crtn) {
+		return crtn;
+	}
+	crtn = iSignFetchExtension(alloc,
+		tpCert,
+		&CSSMOID_SubjectKeyIdentifier,
+		&certInfo->subjectId);
+	if(crtn) {
+		return crtn;
+	}
+	crtn = iSignFetchExtension(alloc,
+		tpCert,
+		&CSSMOID_KeyUsage,
+		&certInfo->keyUsage);
+	if(crtn) {
+		return crtn;
+	}
+	crtn = iSignFetchExtension(alloc,
+		tpCert,
+		&CSSMOID_ExtendedKeyUsage,
+		&certInfo->extendKeyUsage);
+	if(crtn) {
+		return crtn;
+	}
+	crtn = iSignFetchExtension(alloc,
+		tpCert,
+		&CSSMOID_BasicConstraints,
+		&certInfo->basicConstraints);
+	if(crtn) {
+		return crtn;
+	}
+	crtn = iSignFetchExtension(alloc,
+		tpCert,
+		&CSSMOID_NetscapeCertType,
+		&certInfo->netscapeCertType);
+	if(crtn) {
+		return crtn;
+	}
+
+	/* now look for extensions we don't understand - the only thing we're interested
+	 * in is the critical flag. */
+	return iSignSearchUnknownExtensions(tpCert, certInfo);
+}
+
+/*
+ * Free (via CL) the fields allocated in iSignGetCertInfo().
+ */
+static void iSignFreeCertInfo(
+	CSSM_CL_HANDLE	clHand,
+	iSignCertInfo	*certInfo)
+{
+	if(certInfo->authorityId.present) {
+		CSSM_CL_FreeFieldValue(clHand, &CSSMOID_AuthorityKeyIdentifier, 
+			certInfo->authorityId.valToFree);
+	}
+	if(certInfo->subjectId.present) {
+		CSSM_CL_FreeFieldValue(clHand, &CSSMOID_SubjectKeyIdentifier, 
+			certInfo->subjectId.valToFree);
+	}
+	if(certInfo->keyUsage.present) {
+		CSSM_CL_FreeFieldValue(clHand, &CSSMOID_KeyUsage, 
+			certInfo->keyUsage.valToFree);
+	}
+	if(certInfo->extendKeyUsage.present) {
+		CSSM_CL_FreeFieldValue(clHand, &CSSMOID_ExtendedKeyUsage, 
+			certInfo->extendKeyUsage.valToFree);
+	}
+	if(certInfo->basicConstraints.present) {
+		CSSM_CL_FreeFieldValue(clHand, &CSSMOID_BasicConstraints, 
+			certInfo->basicConstraints.valToFree);
+	}
+	if(certInfo->netscapeCertType.present) {
+		CSSM_CL_FreeFieldValue(clHand, &CSSMOID_NetscapeCertType, 
+			certInfo->netscapeCertType.valToFree);
+	}
+}
+
+/*
+ * Common code for comparing a root to a list of known embedded roots.
+ */
+static CSSM_BOOL tp_isKnownRootCert(
+	TPCertInfo				*rootCert,		// raw cert to compare
+	const tpRootCert		*knownRoots,
+	unsigned				numKnownRoots)
+{
+	const CSSM_DATA		*subjectName = NULL;
+	CSSM_DATA_PTR		publicKey = NULL;
+	unsigned			dex;
+	CSSM_BOOL			brtn = CSSM_FALSE;
+	CSSM_DATA_PTR		valToFree = NULL;
+	
+	subjectName = rootCert->subjectName();
+	publicKey = tp_CertGetPublicKey(rootCert, &valToFree);	
+	if(publicKey == NULL) {
+		errorLog0("tp_isKnownRootCert: error retrieving public key info!\n");
+		goto errOut;
+	}
+	
+	/*
+	 * Grind thru the list of known certs, demanding perfect match of 
+	 * both fields 
+	 */
+	for(dex=0; dex<numKnownRoots; dex++) {
+		if(!tpCompareCssmData(subjectName, 
+	                          knownRoots[dex].subjectName)) {
+	    	continue;
+	    }
+		if(!tpCompareCssmData(publicKey,
+	                          knownRoots[dex].publicKey)) {
+	    	continue;
+	    }
+#if 	ENABLE_APPLE_DEBUG_ROOT
+	    if( dex == (knownRoots - 1) ){
+	    	brtn = CSSM_FALSE;
+	    	//tpSetError(CSSM_TP_DEBUG_CERT);
+	    	break;
+	    }
+#endif
+	    brtn = CSSM_TRUE;
+	    break;
+	}
+errOut:
+	tp_CertFreePublicKey(rootCert->clHand(), valToFree);
+	return brtn;
+}
+
+/*
+ * See if specified root cert is a known (embedded) iSign root cert.
+ * Returns CSSM_TRUE if the cert is a known root cert. 
+ */
+static CSSM_BOOL tp_isIsignRootCert(
+	CSSM_CL_HANDLE			clHand,
+	TPCertInfo				*rootCert)		// raw cert from cert group
+{
+	return tp_isKnownRootCert(rootCert, iSignRootCerts, numiSignRootCerts);
+}
+
+/*
+ * See if specified root cert is a known (embedded) SSL root cert.
+ * Returns CSSM_TRUE if the cert is a known root cert. 
+ */
+static CSSM_BOOL tp_isSslRootCert(
+	CSSM_CL_HANDLE			clHand,
+	TPCertInfo				*rootCert)		// raw cert from cert group
+{
+	return tp_isKnownRootCert(rootCert, sslRootCerts, numSslRootCerts);
+}
+
+/*
+ * Attempt to verify specified cert (from the end of a chain) with one of
+ * our known SSL roots. 
+ */
+CSSM_BOOL tp_verifyWithSslRoots(
+	CSSM_CL_HANDLE	clHand, 
+	CSSM_CSP_HANDLE	cspHand, 
+	TPCertInfo		*certToVfy)			// last in chain, not root
+{
+	CSSM_KEY 		rootKey;			// pub key manufactured from tpRootCert info
+	CSSM_CC_HANDLE	ccHand;				// signature context
+	CSSM_RETURN		crtn;
+	unsigned 		dex;
+	const tpRootCert *rootInfo;
+	CSSM_BOOL		brtn = CSSM_FALSE;
+	CSSM_KEYHEADER	*hdr = &rootKey.KeyHeader;
+	CSSM_X509_ALGORITHM_IDENTIFIER_PTR algId;
+	CSSM_DATA_PTR	valToFree = NULL;
+	CSSM_ALGORITHMS	sigAlg;
+	
+	memset(&rootKey, 0, sizeof(CSSM_KEY));
+	
+	/*
+	 * Get signature algorithm from subject key
+	 */
+	algId = tp_CertGetAlgId(certToVfy, &valToFree);
+	if(algId == NULL) {
+		/* bad cert */
+		return CSSM_FALSE;
+	}
+	/* subsequest errors to errOut: */
+	
+	/* map to key and signature algorithm */
+	sigAlg = tpOidToAldId(&algId->algorithm, &hdr->AlgorithmId);
+	if(sigAlg == CSSM_ALGID_NONE) {
+		errorLog0("tp_verifyWithSslRoots: unknown sig alg\n");
+		goto errOut;
+	}
+	
+	/* Set up other constant key fields */
+	hdr->BlobType = CSSM_KEYBLOB_RAW;
+	switch(hdr->AlgorithmId) {
+		case CSSM_ALGID_RSA:
+			hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
+			break;
+		case CSSM_ALGID_DSA:
+			hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
+			break;
+		case CSSM_ALGID_FEE:
+			hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
+			break;
+		default:
+			/* punt */
+			hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_NONE;
+	}
+	hdr->KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+	hdr->KeyAttr = CSSM_KEYATTR_MODIFIABLE | CSSM_KEYATTR_EXTRACTABLE;
+	hdr->KeyUsage = CSSM_KEYUSE_VERIFY;
+
+	for(dex=0; dex<numSslRootCerts; dex++) {
+		/* only variation in key in the loop - raw key bits and size */
+		rootInfo = &sslRootCerts[dex];
+		if(!tpIsSameName(rootInfo->subjectName, certToVfy->issuerName())) {
+			/* not this root */
+			continue;
+		}
+		rootKey.KeyData = *rootInfo->publicKey;
+		hdr->LogicalKeySizeInBits = rootInfo->keySize;
+		crtn = CSSM_CSP_CreateSignatureContext(cspHand,
+			sigAlg,
+			NULL,		// AcccedCred
+			&rootKey,
+			&ccHand);
+		if(crtn) {
+			errorLog0("tp_verifyWithSslRoots: CSSM_CSP_CreateSignatureContext err\n");
+			CssmError::throwMe(CSSMERR_TP_INTERNAL_ERROR);
+		}
+		crtn = CSSM_CL_CertVerify(clHand,
+			ccHand,
+			certToVfy->certData(),
+			NULL,			// no signer cert
+			NULL,			// VerifyScope
+			0);				// ScopeSize
+		CSSM_DeleteContext(ccHand);
+		if(crtn == CSSM_OK) {
+			/* success! */
+			brtn = CSSM_TRUE;
+			break;
+		}
+	}
+errOut:
+	if(valToFree != NULL) {
+		tp_CertFreeAlgId(clHand, valToFree);
+	}
+	return brtn;
+}
+
+/*
+ * RFC2459 says basicConstraints must be flagged critical for
+ * CA certs, but Verisign doesn't work that way.
+ */
+#define BASIC_CONSTRAINTS_MUST_BE_CRITICAL		0
+
+/*
+ * TP iSign spec says Extended Key Usage required for leaf certs,
+ * but Verisign doesn't work that way. 
+ */
+#define EXTENDED_KEY_USAGE_REQUIRED_FOR_LEAF	0
+
+/*
+ * TP iSign spec says Subject Alternate Name required for leaf certs,
+ * but Verisign doesn't work that way. 
+ */
+#define SUBJECT_ALT_NAME_REQUIRED_FOR_LEAF		0
+
+/*
+ * TP iSign spec originally required KeyUsage for all certs, but
+ * Verisign doesn't have that in their roots.
+ */
+#define KEY_USAGE_REQUIRED_FOR_ROOT				0
+
+/*
+ * Public routine to perform TP verification on a constructed 
+ * cert group.
+ * Returns CSSM_TRUE on success.
+ * Asumes the chain has passed basic subject/issuer verification. First cert of
+ * incoming certGroup is end-entity (leaf). 
+ *
+ * Per-policy details:
+ *   iSign: Assumes that last cert in incoming certGroup is a root cert.
+ *			Also assumes a cert group of more than one cert.
+ *   kTPx509Basic: CertGroup of length one allowed. 
+ */
+CSSM_RETURN tp_policyVerify(
+	TPPolicy					policy,
+	CssmAllocator				&alloc,
+	CSSM_CL_HANDLE				clHand,
+	CSSM_CSP_HANDLE				cspHand,
+	TPCertGroup 				*certGroup,
+	CSSM_BOOL					verifiedToRoot)		// last cert is good root
+{
+	iSignCertInfo 			*certInfo = NULL;
+	uint32					numCerts;
+	iSignCertInfo			*thisCertInfo;
+	uint16					expUsage;
+	uint16					actUsage;
+	unsigned				certDex;
+	CSSM_BOOL				cA = CSSM_FALSE;// init for compiler warning
+	CSSM_BOOL				isLeaf;			// end entity
+	CSSM_BOOL				isRoot;			// root cert
+	CE_ExtendedKeyUsage		*extendUsage;
+	CE_AuthorityKeyID		*authorityId;
+	CSSM_RETURN				outErr = CSSM_OK;
+	TPCertInfo 				*lastCert;
+	
+	/* First, kTPDefault is a nop here */
+	if(policy == kTPDefault) {
+		return CSSM_OK;
+	}
+	
+	if(certGroup == NULL) {
+		return CSSMERR_TP_INVALID_CERTGROUP;
+	}
+	numCerts = certGroup->numCerts();
+	if(numCerts == 0) {
+		return CSSMERR_TP_INVALID_CERTGROUP;
+	}
+	if(policy == kTPiSign) {
+		if(!verifiedToRoot) {
+			/* no way, this requires a root cert */
+			return CSSMERR_TP_INVALID_CERTGROUP;
+		}
+		if(numCerts <= 1) {
+			/* nope, not for iSign */
+			return CSSMERR_TP_INVALID_CERTGROUP;
+		}
+	}
+	
+	/* cook up an iSignCertInfo array */
+	certInfo = (iSignCertInfo *)tpCalloc(alloc, numCerts, sizeof(iSignCertInfo));
+	/* subsequent errors to errOut: */
+	
+	/* fill it with interesting info from parsed certs */
+	for(certDex=0; certDex<numCerts; certDex++) {
+		if(iSignGetCertInfo(alloc, 
+				certGroup->certAtIndex(certDex),		
+				&certInfo[certDex])) {
+			outErr = CSSMERR_TP_INVALID_CERTIFICATE;
+			goto errOut;
+		}	
+	}
+		
+	/*
+	 * OK, the heart of TP enforcement.
+	 * First check for presence of required extensions and 
+	 * critical extensions we don't understand.
+	 */
+	for(certDex=0; certDex<numCerts; certDex++) {
+		thisCertInfo = &certInfo[certDex];
+		
+		if(thisCertInfo->foundUnknownCritical) {
+			/* illegal for all policies */
+			errorLog0("tp_policyVerify: critical flag in unknown extension\n");
+			outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+			goto errOut; 
+		}
+		
+		/* 
+		 * Note it's possible for both of these to be true, for a 
+		 * of length one (kTPx509Basic only!)
+		 */
+		isLeaf = (certDex == 0)              ? CSSM_TRUE : CSSM_FALSE;
+		isRoot = (certDex == (numCerts - 1)) ? CSSM_TRUE : CSSM_FALSE;
+			
+		/*
+		 * BasicConstraints.cA
+		 * iSign:   	 required in all but leaf and root,
+		 *          	 for which it is optional (with default values of false
+		 *         	 	 for leaf and true for root).
+		 * kTPx509Basic,
+		 * kTP_SSL:      always optional, default of false for leaf and
+		 *				 true for others
+		 * All:     	 cA must be false for leaf, true for others
+		 */
+		if(!thisCertInfo->basicConstraints.present) {
+			if(isLeaf) {
+				/* cool, use default; note that kTPx509Basic with
+				 * certGroup length of one may take this case */
+				cA = CSSM_FALSE;
+			}
+			else if(isRoot) {
+				/* cool, use default */
+				cA = CSSM_TRUE;
+			}
+			else {
+				switch(policy) {
+					case kTPx509Basic:
+					case kTP_SSL:
+						/* 
+						 * not present, not leaf, not root, kTPx509Basic 
+						 * ....OK; infer as true 
+						 */
+						cA = CSSM_TRUE;
+						break;
+					case kTPiSign:
+						/* required for iSign in this position */
+						errorLog0("tp_policyVerify: no basicConstraints\n");
+						outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+						goto errOut; 
+					default:
+						/* not reached */
+						break;
+				}
+			}
+		}
+		else {
+			/* basicConstraints present */
+			#if		BASIC_CONSTRAINTS_MUST_BE_CRITICAL
+			/* disabled for verisign compatibility */
+			if(!thisCertInfo->basicConstraints.critical) {
+				/* per RFC 2459 */
+				errorLog0("tp_policyVerify: basicConstraints marked not critical\n");
+				outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+				goto errOut; 
+			}
+			#endif	/* BASIC_CONSTRAINTS_MUST_BE_CRITICAL */
+			cA = thisCertInfo->basicConstraints.extnData->basicConstraints.cA;
+		}
+		
+		if(isLeaf) {
+			/* special case to allow a chain of length 1, leaf and root 
+			 * both true (kTPx509Basic, kTP_SSL only) */
+			if(cA && !isRoot) {
+				errorLog0("tp_policyVerify: cA true for leaf\n");
+				outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+				goto errOut; 
+			}
+		} else if(!cA) {
+			errorLog0("tp_policyVerify: cA false for non-leaf\n");
+			outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+			goto errOut; 
+		}
+		
+		/*
+		 * Authority Key Identifier optional
+		 * iSign   		: only allowed in !root. 
+		 *           	  If present, must not be critical.
+		 * kTPx509Basic : 
+		 * kTP_SSL      : ignored (though used later for chain verification)
+		 */ 
+		if((policy == kTPiSign) && thisCertInfo->authorityId.present) {
+			if(isRoot) {
+				errorLog0("tp_policyVerify: authorityId in root\n");
+				outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+				goto errOut; 
+			}
+			if(thisCertInfo->authorityId.critical) {
+				/* illegal per RFC 2459 */
+				errorLog0("tp_policyVerify: authorityId marked critical\n");
+				outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+				goto errOut; 
+			}
+		}
+
+		/*
+		 * Subject Key Identifier optional 
+		 * iSign   		 : can't be critical. 
+		 * kTPx509Basic,
+		 * kTP_SSL       : ignored (though used later for chain verification)
+		 */ 
+		if(thisCertInfo->subjectId.present) {
+			if((policy == kTPiSign) && thisCertInfo->subjectId.critical) {
+				errorLog0("tp_policyVerify: subjectId marked critical\n");
+				outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+				goto errOut; 
+			}
+		}
+		
+		/*
+		 * Key Usage optional except as noted required
+		 * iSign    	: required for non-root/non-leaf
+		 *            	  Leaf cert : if present, usage = digitalSignature
+		 *				  Exception : if leaf, and keyUsage not present, 
+		 *					          netscape-cert-type must be present, with
+		 *							  Object Signing bit set
+		 * kTPx509Basic : non-leaf  : usage = keyCertSign
+		 *			  	  Leaf: don't care
+		 */ 
+		if(thisCertInfo->keyUsage.present) {
+			/*
+			 * Leaf cert: usage = digitalSignature
+			 * Others:    usage = keyCertSign
+			 * We only require that one bit to be set, we ignore others. 
+			 */
+			if(isLeaf) {
+				if(policy == kTPiSign) {
+					expUsage = CE_KU_DigitalSignature;
+				}
+				else {
+					/* hack to accept whatever's there */
+					expUsage = thisCertInfo->keyUsage.extnData->keyUsage;
+				}
+			}
+			else {
+				/* this is true for all policies */
+				expUsage = CE_KU_KeyCertSign;
+			}
+			actUsage = thisCertInfo->keyUsage.extnData->keyUsage;
+			if(!(actUsage & expUsage)) {
+				errorLog2("tp_policyVerify: bad keyUsage (leaf %s; usage 0x%x)\n",
+					(certDex == 0) ? "TRUE" : "FALSE", actUsage);
+				outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+				goto errOut; 
+			}
+		}
+		else if(policy == kTPiSign) {
+			/* 
+			 * iSign requires keyUsage present for non root OR
+			 * netscape-cert-type/ObjectSigning for leaf
+			 */
+			if(isLeaf && thisCertInfo->netscapeCertType.present) {
+				CE_NetscapeCertType ct = 
+					thisCertInfo->netscapeCertType.extnData->netscapeCertType;
+					
+				if(!(ct & CE_NCT_ObjSign)) {
+					errorLog0("tp_policyVerify: netscape-cert-type, !ObjectSign\n");
+					outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+					goto errOut;
+				}
+			}
+			else if(!isRoot) {
+				errorLog0("tp_policyVerify: !isRoot, no keyUsage, !(leaf and netscapeCertType)\n");
+				outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+				goto errOut; 
+			}
+		}				
+	}	/* for certDex, checking presence of extensions */
+
+	/*
+	 * Special case checking for leaf (end entity) cert	
+	 *
+	 * iSign only: Extended key usage, optional for leaf, 
+	 * value CSSMOID_ExtendedUseCodeSigning
+	 */
+	if((policy == kTPiSign) && certInfo[0].extendKeyUsage.present) {
+		extendUsage = &certInfo[0].extendKeyUsage.extnData->extendedKeyUsage;
+		if(extendUsage->numPurposes != 1) {
+			errorLog1("tp_policyVerify: bad extendUsage->numPurposes (%d)\n",
+				(int)extendUsage->numPurposes);
+			outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+			goto errOut; 
+		}
+		if(!tpCompareOids(extendUsage->purposes,
+				&CSSMOID_ExtendedUseCodeSigning)) {
+			errorLog0("tp_policyVerify: bad extendKeyUsage\n");
+			outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+			goto errOut; 
+		}
+	}
+	
+	/*
+	 * Verify authorityId-->subjectId linkage.
+	 * All optional - skip if needed fields not present.
+	 * Also, always skip last (root) cert.  
+	 */
+	for(certDex=0; certDex<(numCerts-1); certDex++) {
+		if(!certInfo[certDex].authorityId.present ||
+		   !certInfo[certDex+1].subjectId.present) {
+		 	continue;  
+		}
+		authorityId = &certInfo[certDex].authorityId.extnData->authorityKeyID;
+		if(!authorityId->keyIdentifierPresent) {
+			/* we only know how to compare keyIdentifier */
+			continue;
+		}
+		if(!tpCompareCssmData(&authorityId->keyIdentifier,
+				&certInfo[certDex+1].subjectId.extnData->subjectKeyID)) {
+			errorLog0("tp_policyVerify: bad key ID linkage\n");
+			outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+			goto errOut; 
+		}
+	}
+	
+	/* iSign, SSL: compare root against known root certs */
+	lastCert = certGroup->lastCert();
+	if(policy == kTPiSign) {
+		bool brtn = tp_isIsignRootCert(clHand, lastCert);
+		if(!brtn) {
+			outErr = CSSMERR_TP_VERIFY_ACTION_FAILED;
+		}
+	}
+	else if(verifiedToRoot && (policy == kTP_SSL)) {
+		/* note SSL doesn't require root here */
+		bool brtn = tp_isSslRootCert(clHand, lastCert);
+		if(!brtn) {
+			outErr = CSSMERR_TP_INVALID_ANCHOR_CERT;
+		}
+	}
+	else {
+		outErr = CSSM_OK;
+	}
+errOut:
+	/* free resources */
+	for(certDex=0; certDex<numCerts; certDex++) {
+		thisCertInfo = &certInfo[certDex];
+		iSignFreeCertInfo(clHand, thisCertInfo);
+	}
+	tpFree(alloc, certInfo);
+	return outErr;
+}
diff --git a/AppleX509TP/tpPolicies.h b/AppleX509TP/tpPolicies.h
new file mode 100644
index 00000000..ee66c51c
--- /dev/null
+++ b/AppleX509TP/tpPolicies.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+
+/*
+	tpPolicies.h - TP module policy implementation
+
+	Created 10/9/2000 by Doug Mitchell. 
+*/
+
+#ifndef	_TP_POLICIES_H_
+#define _TP_POLICIES_H_
+
+#include <Security/cssmtype.h>
+#include <Security/cssmalloc.h>
+#include "TPCertInfo.h"
+
+#ifdef __cplusplus
+extern	"C" {
+#endif /* __cplusplus */
+
+CSSM_BOOL tp_verifyWithSslRoots(
+	CSSM_CL_HANDLE	clHand, 
+	CSSM_CSP_HANDLE	cspHand, 
+	TPCertInfo 		*certToVfy);		// last in chain, not root
+
+/*
+ * Enumerated policies enforced by this module.
+ */
+typedef enum {
+	kTPDefault,			/* no extension parsing, just sig and expiration */
+	kTPx509Basic,		/* basic X.509/RFC2459 */
+	kTPiSign,			/* Apple code signing */
+	kTP_SSL				/* SecureTransport/SSL */
+} TPPolicy;
+
+/*
+ * Perform TP verification on a constructed (ordered) cert group.
+ * Returns CSSM_TRUE on success.
+ */
+CSSM_RETURN tp_policyVerify(
+	TPPolicy					policy,
+	CssmAllocator				&alloc,
+	CSSM_CL_HANDLE				clHand,
+	CSSM_CSP_HANDLE				cspHand,
+	TPCertGroup 				*certGroup,
+	CSSM_BOOL					verifiedToRoot);	// last cert is good root
+
+#ifdef __cplusplus
+}
+#endif
+#endif	/* _TP_POLICIES_H_ */
diff --git a/AppleX509TP/tpTime.c b/AppleX509TP/tpTime.c
new file mode 100644
index 00000000..9e9ee2c0
--- /dev/null
+++ b/AppleX509TP/tpTime.c
@@ -0,0 +1,234 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tpTime.c - cert related time functions
+ *
+ * Written 10/10/2000 by Doug Mitchell.
+ */
+ 
+#include "tpTime.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define UTC_TIME_STRLEN				13
+#define GENERALIZED_TIME_STRLEN		15
+
+/*
+ * Given a string containing either a UTC-style or "generalized time"
+ * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on
+ * error. 
+ */
+int timeStringToTm(
+	const char			*str,
+	unsigned			len,
+	struct tm			*tmp)
+{
+	char 		szTemp[5];
+	unsigned 	isUtc;
+	unsigned 	x;
+	unsigned 	i;
+	char 		*cp;
+
+	if((str == NULL) || (len == 0) || (tmp == NULL)) {
+    	return 1;
+  	}
+  	
+  	/* tolerate NULL terminated or not */
+  	if(str[len - 1] == '\0') {
+  		len--;
+  	}
+  	switch(len) {
+  		case UTC_TIME_STRLEN:			// 2-digit year, not Y2K compliant
+  			isUtc = 1;
+  			break;
+  		case GENERALIZED_TIME_STRLEN:	// 4-digit year
+  			isUtc = 0;
+  			break;
+  		default:						// unknown format 
+  			return 1;
+  	}
+  	
+  	cp = (char *)str;
+  	
+	/* check that all characters except last are digits */
+	for(i=0; i<(len - 1); i++) {
+		if ( !(isdigit(cp[i])) ) {
+		  	return 1;
+		}
+	}
+
+  	/* check last character is a 'Z' */
+  	if(cp[len - 1] != 'Z' )	{
+		return 1;
+  	}
+
+  	/* YEAR */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	if(!isUtc) {
+		/* two more digits */
+		szTemp[2] = *cp++;
+		szTemp[3] = *cp++;
+		szTemp[4] = '\0';
+	}
+	else { 
+		szTemp[2] = '\0';
+	}
+	x = atoi( szTemp );
+	if(isUtc) {
+		/* 
+		 * 2-digit year. 
+		 *   0  <= year <  50 : assume century 21
+		 *   50 <= year <  70 : illegal per PKIX
+		 *   70 <  year <= 99 : assume century 20
+		 */
+		if(x < 50) {
+			x += 2000;
+		}
+		else if(x < 70) {
+			return 1;
+		}
+		else {
+			/* century 20 */
+			x += 1900;			
+		}
+	}
+  	/* by definition - tm_year is year - 1900 */
+  	tmp->tm_year = x - 1900;
+
+  	/* MONTH */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+	x = atoi( szTemp );
+	/* in the string, months are from 1 to 12 */
+	if((x > 12) || (x <= 0)) {
+    	return 1;
+	}
+	/* in a tm, 0 to 11 */
+  	tmp->tm_mon = x - 1;
+
+ 	/* DAY */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+	x = atoi( szTemp );
+	/* 1..31 in both formats */
+	if((x > 31) || (x <= 0)) {
+		return 1;
+	}
+  	tmp->tm_mday = x;
+
+	/* HOUR */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+	x = atoi( szTemp );
+	if((x > 23) || (x < 0)) {
+		return 1;
+	}
+	tmp->tm_hour = x;
+
+  	/* MINUTE */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+	x = atoi( szTemp );
+	if((x > 59) || (x < 0)) {
+		return 1;
+	}
+  	tmp->tm_min = x;
+
+  	/* SECOND */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+  	x = atoi( szTemp );
+	if((x > 59) || (x < 0)) {
+		return 1;
+	}
+  	tmp->tm_sec = x;
+	return 0;
+}
+
+/* return current GMT time as a struct tm */
+void nowTime(
+	struct tm *now)
+{
+	time_t nowTime = time(NULL);
+	*now = *gmtime(&nowTime);
+}
+
+/*
+ * Compare two times. Assumes they're both in GMT. Returns:
+ * -1 if t1 <  t2
+ *  0 if t1 == t2
+ *  1 if t1 >  t2
+ */
+int compareTimes(
+	const struct tm 	*t1,
+	const struct tm 	*t2)
+{
+	if(t1->tm_year > t2->tm_year) {
+		return 1;
+	}
+	else if(t1->tm_year < t2->tm_year) {
+		return -1;
+	}
+	/* year equal */
+	else if(t1->tm_mon > t2->tm_mon) {
+		return 1;
+	}
+	else if(t1->tm_mon < t2->tm_mon) {
+		return -1;
+	}
+	/* month equal */
+	else if(t1->tm_mday > t2->tm_mday) {
+		return 1;
+	}
+	else if(t1->tm_mday < t2->tm_mday) {
+		return -1;
+	}
+	/* day of month equal */
+	else if(t1->tm_hour > t2->tm_hour) {
+		return 1;
+	}
+	else if(t1->tm_hour < t2->tm_hour) {
+		return -1;
+	}
+	/* hour equal */
+	else if(t1->tm_min > t2->tm_min) {
+		return 1;
+	}
+	else if(t1->tm_min < t2->tm_min) {
+		return -1;
+	}
+	/* minute equal */
+	else if(t1->tm_sec > t2->tm_sec) {
+		return 1;
+	}
+	else if(t1->tm_sec < t2->tm_sec) {
+		return -1;
+	}
+	/* equal */
+	return 0;
+}
+
diff --git a/AppleX509TP/tpTime.h b/AppleX509TP/tpTime.h
new file mode 100644
index 00000000..7ad2699b
--- /dev/null
+++ b/AppleX509TP/tpTime.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tpTime.h - cert related time functions
+ *
+ * Written 10/10/2000 by Doug Mitchell.
+ */
+ 
+#ifndef	_TP_TIME_H_
+#define _TP_TIME_H_
+
+#include <time.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Given a string containing either a UTC-style or "generalized time"
+ * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on
+ * error. 
+ */
+extern int timeStringToTm(
+	const char			*str,
+	unsigned			len,
+	struct tm			*tmp);
+
+/* return current GMT time as a struct tm */
+extern void nowTime(
+	struct tm		 	*now);
+
+/*
+ * Compare two times. Assumes they're both in GMT. Returns:
+ * -1 if t1 <  t2
+ *  0 if t1 == t2
+ *  1 if t1 >  t2
+ */
+extern int compareTimes(
+	const struct tm 	*t1,
+	const struct tm 	*t2);
+	
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _TP_TIME_H_*/
diff --git a/AppleX509TP/tpdebugging.c b/AppleX509TP/tpdebugging.c
new file mode 100644
index 00000000..0c6a504b
--- /dev/null
+++ b/AppleX509TP/tpdebugging.c
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		tpdebugging.c
+
+	Contains:	Debugging support.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first): 
+
+		03/10/98	dpm		Created.
+
+*/
+
+#include "tpdebugging.h"
+
+#if		!LOG_VIA_PRINTF
+
+#include <string.h>
+#include <CarbonCore/MacTypes.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* this one needs a writable string */
+static void logCom(unsigned char *str) {
+	c2pstr((char *)str);
+	DebugStr(str);
+}
+
+/* remaining ones can take constant strings */
+void dblog0(char *str)	{
+	Str255	outStr;
+	strcpy((char *)outStr, str);
+	logCom(outStr);
+}
+
+void dblog1(char *str, void *arg1)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1);
+	logCom(outStr);
+}
+
+void dblog2(char *str, void * arg1, void * arg2)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2);
+	logCom(outStr);
+}
+
+void dblog3(char *str, void * arg1, void * arg2, void * arg3)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2, arg3);
+	logCom(outStr);
+}
+
+void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2, arg3, arg4);
+	logCom(outStr);
+}
+
+#endif	/* !LOG_VIA_PRINTF */
+
+//int foobarSymbol;
diff --git a/AppleX509TP/tpdebugging.h b/AppleX509TP/tpdebugging.h
new file mode 100644
index 00000000..a0cd615d
--- /dev/null
+++ b/AppleX509TP/tpdebugging.h
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		tpdebugging.h
+
+	Contains:	Debugging macros.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		06/02/98	dpm		Added DEBUG_THREAD_YIELD.
+		03/10/98	dpm		Created.
+
+*/
+
+#ifndef	_TPDEBUGGING_H_
+#define _TPDEBUGGING_H_
+
+#ifdef	NDEBUG
+#define DEBUG_ENABLE		0
+#define ERROR_LOG_ENABLE	0
+#else
+#define DEBUG_ENABLE		1
+#define ERROR_LOG_ENABLE	1
+#endif
+
+/* any other way? */
+#define LOG_VIA_PRINTF		1
+
+#if		DEBUG_ENABLE || ERROR_LOG_ENABLE
+
+#include <stdio.h>
+
+#if		!LOG_VIA_PRINTF
+
+#error Hey, figure out a debug mechanism
+
+#include <string.h>
+#include <CarbonCore/MacTypes.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* remaining ones can take constant strings */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern void dblog0(char *str);
+extern void dblog1(char *str, void * arg1);
+extern void dblog2(char *str, void * arg1, void * arg2);
+extern void dblog3(char *str, void * arg1, void * arg2, void * arg3);
+extern void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4);
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#else	/* LOG_VIA_PRINTF */
+
+#define dblog0(str)								printf(str)
+#define dblog1(str, arg1)						printf(str, arg1)
+#define dblog2(str, arg1, arg2)					printf(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)			printf(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)		printf(str, arg1, arg2, arg3, arg4)
+
+#endif	/* LOG_VIA_PRINTF */
+
+#else	/* log macros disabled */
+
+#define dblog0(str)
+#define dblog1(str, arg1)
+#define dblog2(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* DEBUG_ENABLE || ERROR_LOG_ENABLE */
+
+#if	DEBUG_ENABLE
+
+#define dprintf0(str)								dblog0(str)
+#define dprintf1(str, arg1)							dblog1(str, arg1)
+#define dprintf2(str, arg1, arg2)					dblog2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)				dblog3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)		dblog4(str, arg1, arg2, arg3,  arg4)
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+static inline volatile void _panic(const char *str)
+{
+	printf(str);
+	exit(1);
+}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#define CASSERT(expression) 							\
+  ((expression) ? (void)0 : 							\
+   (dprintf1 ("Assertion failed: " #expression 			\
+      ", file " __FILE__ ", line %d.\n", __LINE__), 	\
+    _panic("Assertion Failure")))
+
+#else	/* DEBUG_ENABLE */
+
+#define dprintf0(str)
+#define dprintf1(str, arg1)
+#define dprintf2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)
+
+#define CASSERT(expression)
+
+#endif	/* DEBUG_ENABLE */
+
+/*
+ * Error logging. This may well be platform dependent.
+ */
+#if		ERROR_LOG_ENABLE
+#define errorLog0(str)								dblog0(str)
+#define errorLog1(str, arg1)						dblog1(str, arg1)
+#define errorLog2(str, arg1, arg2)					dblog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)			dblog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)		dblog4(str, arg1, arg2, arg3, arg4)
+
+#else	/* ERROR_LOG_ENABLE */
+
+#define errorLog0(str)
+#define errorLog1(str, arg1)
+#define errorLog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* ERROR_LOG_ENABLE */
+
+#endif	/* _TPDEBUGGING_H_ */
diff --git a/CVSVersionInfo.txt b/CVSVersionInfo.txt
new file mode 100644
index 00000000..231f8aee
--- /dev/null
+++ b/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.22 2001/09/11 00:42:18 mb Exp $
+# $Name: Security-28 $
+ProjectName: Security
+ProjectVersion: 28
diff --git a/Keychain/CCallbackMgr.cp b/Keychain/CCallbackMgr.cp
new file mode 100644
index 00000000..4ff7ab72
--- /dev/null
+++ b/Keychain/CCallbackMgr.cp
@@ -0,0 +1,313 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		CCallbackMgr.cp
+
+	Contains:	Code that communicates with processes that install a callback
+                with the Keychain Manager to receive keychain events.
+
+	Written by:	Sari Harrison, Craig Mortensen
+
+	Copyright:	© 1998-2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+	To Do:
+*/
+
+#include "CCallbackMgr.h"
+
+#include <algorithm>
+#include <list>
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include "Globals.h"
+#include <Security/DLDBListCFPref.h>
+
+//using namespace std;
+using namespace KeychainCore;
+using namespace CssmClient;
+
+static const UInt32 kTicksBetweenIdleEvents = 5L;
+
+#pragma mark ÑÑÑÑ CallbackInfo ÑÑÑÑ
+
+CallbackInfo::CallbackInfo() : mCallback(NULL),mEventMask(0),mContext(NULL)
+{
+}
+
+CallbackInfo::CallbackInfo(SecKeychainCallbackProcPtr inCallbackFunction,SecKeychainEventMask inEventMask,void *inContext)
+	 : mCallback(inCallbackFunction),mEventMask(inEventMask),mContext(inContext)
+{
+}
+
+CallbackInfo::~CallbackInfo()
+{
+}
+
+bool CallbackInfo::operator==(const CallbackInfo& other) const
+{
+    return mCallback==other.mCallback;
+}
+
+bool CallbackInfo::operator!=(const CallbackInfo& other) const
+{
+	return !(*this==other);
+}
+
+
+#pragma mark ÑÑÑÑ CCallbackMgr ÑÑÑÑ
+
+CCallbackMgr *CCallbackMgr::mCCallbackMgr;
+
+CCallbackMgr::CCallbackMgr() :
+    // register for receiving Keychain events via CF
+    Observer( kSecEventNotificationName, NULL, CFNotificationSuspensionBehaviorDeliverImmediately )
+{
+}
+
+CCallbackMgr::~CCallbackMgr()
+{
+}
+
+CCallbackMgr& CCallbackMgr::Instance()
+{
+	if (!mCCallbackMgr)
+		mCCallbackMgr = new CCallbackMgr();	
+
+	return *mCCallbackMgr;
+}
+
+void CCallbackMgr::AddCallback( SecKeychainCallbackProcPtr inCallbackFunction, 
+                             SecKeychainEventMask 	inEventMask,
+                             void* 			inContext)
+
+{
+	CallbackInfo info( inCallbackFunction, inEventMask, inContext );
+	CallbackInfo existingInfo;
+
+
+    CallbackInfoListIterator ix = find( CCallbackMgr::Instance().mEventCallbacks.begin(),
+                                        CCallbackMgr::Instance().mEventCallbacks.end(), info );
+	
+	// make sure it is not already there
+	if ( ix!=CCallbackMgr::Instance().mEventCallbacks.end() )
+    {
+        // It's already there. This could mean that the old process died unexpectedly,
+        // so we need to validate the process ID of the existing callback.
+        // On Mac OS X this list is per process so this is always a duplicate
+		MacOSError::throwMe(errSecDuplicateCallback);
+	}
+	
+	CCallbackMgr::Instance().mEventCallbacks.push_back(info);
+}
+
+#if 0
+void CCallbackMgr::AddCallbackUPP(KCCallbackUPP 	inCallbackFunction,
+                               KCEventMask 		inEventMask,
+                               void*			inContext)
+{
+	CallbackInfo info( reinterpret_cast<SecKeychainCallbackProcPtr>(inCallbackFunction), inEventMask, inContext );
+	CallbackInfo existingInfo;
+
+#if TARGET_API_MAC_OS8
+    OSErr err = noErr;
+	err = ::GetCurrentProcess( &info.mProcessID );
+	KCThrowIf_( err );
+#endif
+
+    CallbackInfoListIterator ix = find( CCallbackMgr::Instance().mEventCallbacks.begin(),
+                                        CCallbackMgr::Instance().mEventCallbacks.end(), info );
+	
+	// make sure it is not already there
+	if ( ix!=CCallbackMgr::Instance().mEventCallbacks.end() )
+    {
+        // It's already there. This could mean that the old process died unexpectedly,
+        // so we need to validate the process ID of the existing callback.
+#if TARGET_API_MAC_OS8
+		if (ValidProcess(ix->mProcessID))	// existing callback is OK, so don't add this one.
+			MacOSError::throwMe(errKCDuplicateCallback);
+
+		// Process is gone, so remove the old entry
+		CCallbackMgr::Instance().mEventCallbacks.erase(ix);
+#else
+        // On Mac OS X this list is per process so this is always a duplicate
+		MacOSError::throwMe(errKCDuplicateCallback);
+#endif
+	}
+	
+	CCallbackMgr::Instance().mEventCallbacks.push_back(info);
+}
+#endif
+
+
+class Predicate
+{
+	SecKeychainCallbackProcPtr mCallbackFunction;
+public:
+	Predicate(SecKeychainCallbackProcPtr inCallbackFunction) : mCallbackFunction(inCallbackFunction) {}
+	bool operator()(const CallbackInfo &cbInfo) { return cbInfo.mCallback == mCallbackFunction; }
+};
+
+void CCallbackMgr::RemoveCallback(SecKeychainCallbackProcPtr inCallbackFunction)
+{
+	size_t oldSize = CCallbackMgr::Instance().mEventCallbacks.size();
+	Predicate predicate(inCallbackFunction);
+	CCallbackMgr::Instance().mEventCallbacks.remove_if(predicate);
+
+	if (oldSize == CCallbackMgr::Instance().mEventCallbacks.size())
+		MacOSError::throwMe(errSecInvalidCallback);
+}
+
+#if 0
+void CCallbackMgr::RemoveCallbackUPP(KCCallbackUPP inCallbackFunction)
+{
+	size_t oldSize = CCallbackMgr::Instance().mEventCallbacks.size();
+	Predicate predicate(reinterpret_cast<SecKeychainCallbackProcPtr>(inCallbackFunction));
+	CCallbackMgr::Instance().mEventCallbacks.remove_if(predicate);
+
+	if (oldSize == CCallbackMgr::Instance().mEventCallbacks.size())
+		MacOSError::throwMe(errKCInvalidCallback);
+}
+#endif
+
+bool CCallbackMgr::ThisProcessUsesSystemEvtCallback()
+{
+	const SecKeychainEventMask theMask = 1 << kSecSystemEvent;
+
+
+	for ( CallbackInfoListIterator ix = CCallbackMgr::Instance().mEventCallbacks.begin();
+		  ix!=CCallbackMgr::Instance().mEventCallbacks.end(); ++ix )
+	{
+        if ( ix->mEventMask & theMask)
+            return true;
+	}
+	return false;
+}
+
+//%%% jch move this function to SecurityHI
+bool CCallbackMgr::ThisProcessCanDisplayUI()
+{
+    return true;
+}
+
+#if 0
+void CCallbackMgr::Idle()
+{
+	static unsigned long lastTickCount = 0;
+	unsigned long tickCount = ::TickCount( );
+	
+	if (tickCount > lastTickCount+kTicksBetweenIdleEvents)
+	{
+    	lastTickCount = tickCount;
+	}
+}
+#endif
+
+void CCallbackMgr::AlertClients(SecKeychainEvent inEvent, bool inOKToAllocateMemory)
+{
+    AlertClients(inEvent, Keychain(), Item(), inOKToAllocateMemory);
+}
+
+void CCallbackMgr::AlertClients(SecKeychainEvent inEvent,
+                                const Keychain &inKeychain,
+                                const Item &inItem,
+                                bool inOKToAllocateMemory)
+{
+    // Deal with events that we care about ourselves first.
+    if (inEvent == kSecDefaultChangedEvent)
+        globals().defaultKeychain.reload(true);
+    else if (inEvent == kSecKeychainListChangedEvent)
+        globals().storageManager.reload(true);
+
+	// Iterate through callbacks, looking for those registered for inEvent
+	const SecKeychainEventMask theMask = 1U << inEvent;
+
+	for ( CallbackInfoListIterator ix = CCallbackMgr::Instance().mEventCallbacks.begin();
+		ix != CCallbackMgr::Instance().mEventCallbacks.end(); ++ix )
+	{
+		if (!(ix->mEventMask & theMask))
+			continue;
+
+		SecKeychainCallbackInfo	cbInfo;
+		cbInfo.version = 0; // @@@ kKeychainAPIVersion;
+		cbInfo.item = inItem ? ItemRef::handle(inItem) : 0;
+		cbInfo.keychain = inKeychain ? KeychainRef::handle(inKeychain) : 0;
+
+#if 0
+        //%%%cpm- need to change keychaincore.i so we don't to the reinterpret_cast
+        // we need a carbon-version of the callbackmgr to register for events
+        // and call the "C" real callback mgr (use the ix->mCallback when this is ready)
+        
+        // until then, we rely on CarbonCore for the UPP stuff
+        InvokeKCCallbackUPP(inEvent,reinterpret_cast<KCCallbackInfo*>(&cbInfo),ix->mContext,
+                            reinterpret_cast<KCCallbackUPP>(ix->mCallback));
+#else
+		ix->mCallback(inEvent,&cbInfo,ix->mContext);
+#endif
+	}
+}
+
+/***********************************************************************************
+*	Event() - Overriden function of the KCEventObserver object.
+*			  Each instance of KeychainCore will receive events from CF
+*			  that was initiated by another KeychainCore instance that
+*			  triggered the event.
+*
+* 	We <could> care about which KeychainCore posted the event: 
+* 		Example (KCDeleteItem event):
+*			If it was 'us', we don't do anything; we already processed the event. 
+* 			If it wasn't 'us', we should remove our cached reference to the item that was deleted.
+*
+***********************************************************************************/
+void CCallbackMgr::Event(CFNotificationCenterRef center, 
+                         CFStringRef name, 
+                         const void *object, 
+                         CFDictionaryRef userInfo)
+{
+    // Decode from userInfo the event type, 'keychain' CFDict, and 'item' CFDict
+    CCFValue event(CFDictionaryGetValue( userInfo, kSecEventTypeKey ));
+	SecKeychainEvent	thisEvent = 0;
+    if (!event.hasValue())
+		return;
+
+	thisEvent = sint32( event );
+
+    CFDictionaryRef kc = reinterpret_cast<CFDictionaryRef>
+                            (CFDictionaryGetValue(userInfo, kSecEventKeychainKey));
+    Keychain thisKeychain;
+    if (kc)
+    {
+        thisKeychain = globals().storageManager.keychain	
+                            (DLDbListCFPref::cfDictionaryRefToDLDbIdentifier(kc));
+    }
+
+    CFDataRef item = reinterpret_cast<CFDataRef>
+                            (CFDictionaryGetValue(userInfo, kSecEventItemKey));
+    Item thisItem;
+    if (item && thisKeychain)
+    {
+        const CssmData pkData(const_cast<UInt8*>(CFDataGetBytePtr(item)), CFDataGetLength(item));
+        PrimaryKey pk(pkData);
+		thisItem = thisKeychain->item(pk);
+    }
+
+    // Notify our process of this event.
+	CCallbackMgr::AlertClients(thisEvent, thisKeychain, thisItem);
+}
diff --git a/Keychain/CCallbackMgr.h b/Keychain/CCallbackMgr.h
new file mode 100644
index 00000000..9f04f947
--- /dev/null
+++ b/Keychain/CCallbackMgr.h
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		CCallbackMgr.h
+
+	Contains:	Code that communicates with processes that install a callback
+                with the Keychain Manager to receive keychain events.
+
+	Written by:	Sari Harrison, Craig Mortensen
+
+	Copyright:	© 1998-2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+	To Do:
+*/
+
+#ifndef __CCALLBACKMGR__
+#define __CCALLBACKMGR__
+
+#include <Security/SecKeychainAPI.h>
+#include <Security/KCEventObserver.h>
+#include <Security/KCEventNotifier.h>
+#include <Security/Keychains.h>
+#include <list>
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+class CallbackInfo;
+class CCallbackMgr;
+
+class CallbackInfo
+{
+public:
+	~CallbackInfo();
+	CallbackInfo();
+	CallbackInfo(SecKeychainCallbackProcPtr inCallbackFunction,SecKeychainEventMask inEventMask,void *inContext);
+	
+	bool operator ==(const CallbackInfo& other) const;
+	bool operator !=(const CallbackInfo& other) const;
+
+	SecKeychainCallbackProcPtr			mCallback;
+	SecKeychainEventMask				mEventMask;
+	void						*mContext;
+};
+
+// typedefs
+typedef CallbackInfo *CallbackInfoPtr;
+typedef CallbackInfo const *ConstCallbackInfoPtr;
+
+typedef list<CallbackInfo>::iterator CallbackInfoListIterator;
+typedef list<CallbackInfo>::const_iterator ConstCallbackInfoListIterator;
+
+#ifdef _CPP_CCALLBACKMGR
+# pragma export on
+#endif
+
+
+class CCallbackMgr : Observer
+{
+public:
+	
+	CCallbackMgr();
+	~CCallbackMgr();
+	
+	static CCallbackMgr& Instance();
+
+	static void AddCallback( SecKeychainCallbackProcPtr inCallbackFunction, SecKeychainEventMask inEventMask, void* inContext);
+	//static void AddCallbackUPP(KCCallbackUPP inCallbackFunction, KCEventMask inEventMask, void* inContext);
+
+	static void RemoveCallback( SecKeychainCallbackProcPtr inCallbackFunction );
+    //static void RemoveCallbackUPP(KCCallbackUPP inCallbackFunction);
+	static bool HasCallbacks() { return CCallbackMgr::Instance().mEventCallbacks.size() > 0; };
+	static bool ThisProcessUsesSystemEvtCallback();
+	static bool ThisProcessCanDisplayUI();
+	
+	static void AlertClients( SecKeychainEvent inEvent, bool inOKToAllocateMemory);
+#if 0
+	static void Idle();
+#endif
+
+private:
+
+    virtual void 	Event ( CFNotificationCenterRef center, 
+                            CFStringRef 			name, 
+                            const void*				object, 
+                            CFDictionaryRef 		userInfo );
+
+	static void AlertClients( SecKeychainEvent inEvent, const Keychain& inKeychain,
+                                const Item &inItem, bool inOKToAllocateMemory = true);
+
+	list<CallbackInfo> 		mEventCallbacks;
+	static CCallbackMgr* 	mCCallbackMgr;
+};
+
+} // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif // __CCALLBACKMGR__
diff --git a/Keychain/DLDBListCFPref.cpp b/Keychain/DLDBListCFPref.cpp
new file mode 100644
index 00000000..f7ee77d1
--- /dev/null
+++ b/Keychain/DLDBListCFPref.cpp
@@ -0,0 +1,274 @@
+/*
+ * 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.
+ */
+
+
+/*
+    DLDBListCFPref.cpp
+*/
+
+#include "DLDBListCFPref.h"
+#include <Security/cssmapple.h>
+#include <memory>
+#include <pwd.h>
+
+using namespace CssmClient;
+
+static const double kDLDbListCFPrefRevertInterval = 30.0;
+
+#define kKeyGUID CFSTR("GUID")
+#define kKeySubserviceId CFSTR("SubserviceId")
+#define kKeySubserviceType CFSTR("SubserviceType")
+#define kKeyDbName CFSTR("DbName")
+#define kKeyDbLocation CFSTR("DbLocation")
+#define kKeyActive CFSTR("Active")
+#define kKeyMajorVersion CFSTR("MajorVersion")
+#define kKeyMinorVersion CFSTR("MinorVersion")
+#define kDefaultDLDbListKey CFSTR("DLDBSearchList")
+#define kDefaultDomain CFSTR("com.apple.security")
+
+
+//-------------------------------------------------------------------------------------
+//
+//			Lists of DL/DBs, with CFPreferences backing store
+//
+//-------------------------------------------------------------------------------------
+
+DLDbListCFPref::DLDbListCFPref(CFStringRef theDLDbListKey,CFStringRef prefsDomain) :
+    mPrefsDomain(prefsDomain?prefsDomain:kDefaultDomain),mDLDbListKey(theDLDbListKey?theDLDbListKey:kDefaultDLDbListKey)
+{
+    loadOrCreate();
+}
+
+DLDbListCFPref::~DLDbListCFPref()
+{
+    save();
+}
+
+void DLDbListCFPref::loadOrCreate()
+{
+ 
+    CFRef<CFArrayRef> theArray(static_cast<CFArrayRef>(::CFPreferencesCopyValue(mDLDbListKey, mPrefsDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost)));
+	if (!theArray)
+        return;
+
+    if (::CFGetTypeID(theArray)!=::CFArrayGetTypeID())
+    {
+        ::CFPreferencesSetValue(mDLDbListKey, NULL, mPrefsDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+		return;
+    }
+    
+    CFIndex top=::CFArrayGetCount(theArray);
+    // Each entry is a CFDictionary; peel it off & add it to the array
+    for (CFIndex idx=0;idx<top;idx++)
+    {
+        CFDictionaryRef theDict=reinterpret_cast<CFDictionaryRef>(::CFArrayGetValueAtIndex(theArray,idx));
+        DLDbIdentifier theDLDbIdentifier=cfDictionaryRefToDLDbIdentifier(theDict);
+        push_back(theDLDbIdentifier);
+    }
+	
+	
+	mPrefsTimeStamp=CFAbsoluteTimeGetCurrent();
+
+
+}
+
+void DLDbListCFPref::save()
+{
+    if (!hasChanged())
+        return;
+    // Make a temporary CFArray with the contents of the vector
+ 	CFRef<CFMutableArrayRef> theArray(::CFArrayCreateMutable(kCFAllocatorDefault,size(),&kCFTypeArrayCallBacks));
+    for (DLDbList::const_iterator ix=begin();ix!=end();ix++)
+	{
+		CFRef<CFDictionaryRef> aDict(dlDbIdentifierToCFDictionaryRef(*ix));
+        ::CFArrayAppendValue(theArray,aDict);
+	}
+
+	::CFPreferencesSetValue(mDLDbListKey, theArray, mPrefsDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+    ::CFPreferencesSynchronize(mPrefsDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+
+    changed(false);
+}
+
+void DLDbListCFPref::clearDefaultKeychain()
+{
+	::CFPreferencesSetValue(mDLDbListKey, NULL, mPrefsDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+    ::CFPreferencesSynchronize(mPrefsDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+	
+    changed(false);
+}
+
+
+
+//----------------------------------------------------------------------
+//			Conversions
+//----------------------------------------------------------------------
+
+DLDbIdentifier DLDbListCFPref::cfDictionaryRefToDLDbIdentifier(CFDictionaryRef theDict)
+{
+    // We must get individual values from the dictionary and store in basic types
+
+    // GUID
+    CCFValue vGuid(::CFDictionaryGetValue(theDict,kKeyGUID));
+    string guidStr=vGuid;
+    const Guid guid(guidStr.c_str());
+
+    //CSSM_VERSION
+	CSSM_VERSION theVersion={0,};
+    CCFValue vMajor(::CFDictionaryGetValue(theDict,kKeyMajorVersion));
+	theVersion.Major = vMajor;
+    CCFValue vMinor(::CFDictionaryGetValue(theDict,kKeyMinorVersion));
+	theVersion.Minor = vMinor;
+
+    //subserviceId
+    CCFValue vSsid(::CFDictionaryGetValue(theDict,kKeySubserviceId));
+    uint32 subserviceId=sint32(vSsid);
+
+    //CSSM_SERVICE_TYPE
+    CSSM_SERVICE_TYPE subserviceType=CSSM_SERVICE_DL;
+    CCFValue vSsType(::CFDictionaryGetValue(theDict,kKeySubserviceType));
+    subserviceType=vSsType;
+    
+    // Get DbName from dictionary
+    CCFValue vDbName(::CFDictionaryGetValue(theDict,kKeyDbName));
+    string dbName=vDbName;
+    
+    // jch Get DbLocation from dictionary
+	CssmNetAddress *dbLocation=NULL;
+    
+    // Create a local CssmSubserviceUid
+    CssmSubserviceUid ssuid(guid,&theVersion,subserviceId,subserviceType);
+        
+    return DLDbIdentifier(ssuid,ExpandTildesInPath(dbName).c_str(),dbLocation);
+}
+
+string DLDbListCFPref::HomeDir()
+{
+    const char *home = getenv("HOME");
+    if (!home)
+    {
+        // If $HOME is unset get the current users home directory from the passwd file.
+        struct passwd *pw = getpwuid(getuid());
+        if (pw)
+            home = pw->pw_dir;
+    }
+    return home ? home : "";
+}
+
+string DLDbListCFPref::ExpandTildesInPath(const string &inPath)
+{
+    if ((short)inPath.find("~/",0,2) == 0)
+        return HomeDir() + inPath.substr(1);
+    else
+        return inPath;
+}
+
+string DLDbListCFPref::StripPathStuff(const string &inPath)
+{
+    if (inPath.find("/private/automount/Network/",0,27) == 0)
+        return inPath.substr(18);
+    if (inPath.find("/automount/Network/",0,19) == 0)
+        return inPath.substr(10);
+    if (inPath.find("/private/Network/",0,17) == 0)
+        return inPath.substr(8);
+    return inPath;
+}
+
+string DLDbListCFPref::AbbreviatedPath(const string &inPath)
+{
+    string path = StripPathStuff(inPath);
+    string home = StripPathStuff(HomeDir() + "/");
+    size_t homeLen = home.length();
+
+    if (homeLen > 1 && path.find(home.c_str(), 0, homeLen) == 0)
+        return "~" + path.substr(homeLen - 1);
+    else
+        return path;
+}
+
+CFDictionaryRef DLDbListCFPref::dlDbIdentifierToCFDictionaryRef(const DLDbIdentifier& dldbIdentifier)
+{
+	CFRef<CFMutableDictionaryRef> aDict(CFDictionaryCreateMutable(kCFAllocatorDefault,0,
+		&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks));
+    if (!aDict)
+        throw ::std::bad_alloc();
+
+    // Put SUBSERVICE_UID in dictionary
+    char buffer[Guid::stringRepLength+1];
+    const CssmSubserviceUid& ssuid=dldbIdentifier.ssuid();
+    const Guid &theGuid = Guid::overlay(ssuid.Guid);
+    CFRef<CFStringRef> stringGuid(::CFStringCreateWithCString(kCFAllocatorDefault,
+            theGuid.toString(buffer),kCFStringEncodingMacRoman));
+    if (stringGuid)
+        ::CFDictionarySetValue(aDict,kKeyGUID,stringGuid);
+        
+    if (ssuid.SubserviceId!=0)
+    {
+        CFRef<CFNumberRef> subserviceId(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.SubserviceId));
+        if (subserviceId)
+            ::CFDictionarySetValue(aDict,kKeySubserviceId,subserviceId);
+    }
+    if (ssuid.SubserviceType!=0)
+    {
+        CFRef<CFNumberRef> subserviceType(CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.SubserviceType));
+        if (subserviceType)
+            ::CFDictionarySetValue(aDict,kKeySubserviceType,subserviceType);
+    }
+    if (ssuid.Version.Major!=0 && ssuid.Version.Minor!=0)
+    {
+        CFRef<CFNumberRef> majorVersion(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.Version.Major));
+        if (majorVersion)
+            ::CFDictionarySetValue(aDict,kKeyMajorVersion,majorVersion);
+        CFRef<CFNumberRef> minorVersion(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.Version.Minor));
+        if (minorVersion)
+            ::CFDictionarySetValue(aDict,kKeyMinorVersion,minorVersion);
+    }
+    
+    // Put DbName in dictionary
+	const char *dbName=dldbIdentifier.dbName();
+    if (dbName)
+    {
+        CFRef<CFStringRef> theDbName(::CFStringCreateWithCString(kCFAllocatorDefault,AbbreviatedPath(dbName).c_str(),kCFStringEncodingMacRoman));
+        ::CFDictionarySetValue(aDict,kKeyDbName,theDbName);
+    }
+    // Put DbLocation in dictionary
+	const CSSM_NET_ADDRESS *dbLocation=dldbIdentifier.dbLocation();
+    if (dbLocation!=NULL && dbLocation->AddressType!=CSSM_ADDR_NONE)
+    {
+        CFRef<CFDataRef> theData(::CFDataCreate(kCFAllocatorDefault,dbLocation->Address.Data,dbLocation->Address.Length));
+        if (theData)
+            ::CFDictionarySetValue(aDict,kKeyDbLocation,theData);
+    }
+
+    ::CFRetain(aDict);
+	return aDict;
+}
+bool DLDbListCFPref::revert(bool force)
+{ 
+
+	// if the prefs have not been refreshed in the last 5 seconds force a reload
+	if (force || CFAbsoluteTimeGetCurrent() - mPrefsTimeStamp > kDLDbListCFPrefRevertInterval)
+	{
+		clear();
+		::CFPreferencesSynchronize(mPrefsDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+	    loadOrCreate();
+		return true;  // @@@ Be smarter about when something *really* changed
+	}
+
+	return false;
+}
+
diff --git a/Keychain/DLDBListCFPref.h b/Keychain/DLDBListCFPref.h
new file mode 100644
index 00000000..a4c6be96
--- /dev/null
+++ b/Keychain/DLDBListCFPref.h
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+
+/*
+    DLDBListCFPref.h
+*/
+
+#ifndef __DLDBLISTCFPREF_H_
+#define __DLDBLISTCFPREF_H_
+
+#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFPreferences.h>
+#include <Security/DLDBList.h>
+#include <Security/cssmdb.h>
+#include <stdexcept>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFDate.h>
+
+
+namespace Security
+{
+
+class DLDbListCFPref : public CssmClient::DLDbList
+{
+public:
+    DLDbListCFPref(CFStringRef theDLDbListKey=NULL,CFStringRef prefsDomain=NULL);
+    ~DLDbListCFPref();
+    
+    void save();
+    CssmClient::DLDbList& list() { return *this; }	// eventually, it should check mod dates of CFPrefs file, etc.
+    
+    static DLDbIdentifier cfDictionaryRefToDLDbIdentifier(CFDictionaryRef theDict);
+    static CFDictionaryRef dlDbIdentifierToCFDictionaryRef(const DLDbIdentifier& dldbIdentifier);
+	bool revert(bool force);
+	void clearDefaultKeychain();
+    
+    static string ExpandTildesInPath(const string &inPath);
+	static string StripPathStuff(const string &inPath);
+    static string AbbreviatedPath(const string &inPath);
+    static string HomeDir();
+
+private:
+    // Private member variables
+    CFStringRef mPrefsDomain;
+    CFStringRef mDLDbListKey;
+
+    // Private member functions
+    void loadOrCreate();
+
+	CFAbsoluteTime mPrefsTimeStamp;
+};
+
+class CCFValue
+{
+public:
+    template <class T>
+    T cfref() const { return reinterpret_cast<T>(CFTypeRef(mRef)); }
+
+	CCFValue() {}
+	CCFValue(CFTypeRef ref) : mRef(ref) {}
+	CCFValue &operator =(CFTypeRef ref) { mRef = ref; return *this; }
+
+    CCFValue &operator = (bool value)
+    {
+        mRef = value?kCFBooleanTrue:kCFBooleanFalse;
+        return *this;
+    }
+
+/*
+    CCFValue &operator = (const string &value) { string(value); return *this; }
+
+    void string(const string &value, CFStringEncoding encoding=kCFStringEncodingMacRoman)
+    {
+        mRef = CFStringCreate();
+CFStringRef CFStringCreateWithBytes(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean isExternalRepresentation);
+        if (!mRef) throw std::bad_alloc;
+        CFRelease(mRef);
+    }
+*/
+
+    bool hasValue() const { return mRef; }
+
+    operator bool() const
+    {
+        if (!mRef) return false;
+        if (::CFGetTypeID(mRef) != ::CFBooleanGetTypeID())
+            throw std::logic_error("wrong type in property list");
+
+        return ::CFBooleanGetValue(cfref<CFBooleanRef>());
+    }
+
+    operator sint32() const
+    {
+        if (!mRef) return 0;
+        if (::CFGetTypeID(mRef) != ::CFNumberGetTypeID())
+            throw std::logic_error("wrong type in property list");
+        
+        sint32 val;
+        ::CFNumberGetValue(cfref<CFNumberRef>(),kCFNumberSInt32Type,&val);
+        return val;
+    }
+
+    operator uint32() const { return uint32(sint32(*this)); }
+
+    operator const string() const { return getString(); }
+
+    const string getString(CFStringEncoding encoding=kCFStringEncodingMacRoman) const
+    {
+        if (!mRef)
+            throw std::logic_error("missing string in property list");
+        if (::CFGetTypeID(mRef) != ::CFStringGetTypeID())
+            throw std::logic_error("wrong type in property list");
+
+        const char *tmpStr=::CFStringGetCStringPtr(cfref<CFStringRef>(),encoding);
+        if (tmpStr == NULL)
+        {
+            CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfref<CFStringRef>()), encoding);
+            auto_array<char> buffer(maxLen + 1);
+
+            if (!::CFStringGetCString(cfref<CFStringRef>(),buffer.get(),maxLen + 1,encoding))
+                throw std::logic_error("could not convert string from property list");
+
+            tmpStr=buffer.get();
+            return string(tmpStr?tmpStr:"");
+        }
+        return string(tmpStr?tmpStr:"");
+    }
+private:
+	CFCopyRef<CFTypeRef>mRef;
+};
+
+} // end namespace Security
+
+#endif /* __DLDBLISTCFPREF_H_ */
diff --git a/Keychain/DefaultKeychain.cpp b/Keychain/DefaultKeychain.cpp
new file mode 100644
index 00000000..8f05bad4
--- /dev/null
+++ b/Keychain/DefaultKeychain.cpp
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+
+/*
+    File:		DefaultKeychain.cpp
+
+    Contains:	User preference for default keychain
+
+    Copyright:	2000 by Apple Computer, Inc., all rights reserved.
+
+    To Do:
+*/
+
+#include "DefaultKeychain.h"
+
+#include "CCallbackMgr.h"
+#include "KCEventNotifier.h"
+#include "Keychains.h"
+#include "Globals.h"
+#include "KCExceptions.h"
+
+using namespace KeychainCore;
+using namespace CssmClient;
+
+DefaultKeychain::DefaultKeychain() : mPref(CFSTR("DefaultKeychain"))
+{
+}
+
+// Set/Get via DLDbIdentifier
+void DefaultKeychain::dLDbIdentifier(const DLDbIdentifier& keychainID)
+{
+    DLDbList& theList=mPref.list();
+    if (theList.size()>0 && keychainID==theList[0])		// already the default keychain
+        return;
+    theList.clear();
+    mPref.add(keychainID);			// destructor will save
+    mPref.save();
+    KCEventNotifier::PostKeychainEvent(kSecDefaultChangedEvent, keychainID);
+    defaultID = keychainID;
+}
+
+// unset default
+void DefaultKeychain::unset()
+{
+    DLDbList& theList=mPref.list();
+ 	theList.clear();
+	mPref.clearDefaultKeychain();
+	KCEventNotifier::PostKeychainEvent(kSecDefaultChangedEvent);
+}
+
+void DefaultKeychain::reload(bool force)
+{
+	if (!defaultID || mPref.revert(force))
+    {
+        DLDbList& theList=mPref.list();
+        if (theList.size()==0)
+            MacOSError::throwMe(errSecNoDefaultKeychain);
+        defaultID = theList[0];
+    }
+}
+
+DLDbIdentifier DefaultKeychain::dLDbIdentifier()
+{
+    reload();
+    return defaultID;
+}
+
+// Set/Get via Keychain
+void DefaultKeychain::keychain(const Keychain& keychain)
+{
+    DefaultKeychain::dLDbIdentifier(keychain->dLDbIdentifier());	// call the main "set" routine
+}
+
+Keychain DefaultKeychain::keychain()	// was: GetTimedDefaultKC
+{
+    return globals().storageManager.keychain(dLDbIdentifier());
+}
+
+bool DefaultKeychain::isSet()
+{
+    return mPref.list().size() != 0;
+}
diff --git a/Keychain/DefaultKeychain.h b/Keychain/DefaultKeychain.h
new file mode 100644
index 00000000..463f56c1
--- /dev/null
+++ b/Keychain/DefaultKeychain.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+
+/*
+    File:		DefaultKeychain.h
+
+    Contains:	User preference for default keychain
+
+    Written by:	John Hurley
+
+    Copyright:	2000 by Apple Computer, Inc., all rights reserved.
+
+    To Do:
+*/
+
+#ifndef _H_KEYCHAINCORE_DEFAULTKEYCHAIN__
+#define _H_KEYCHAINCORE_DEFAULTKEYCHAIN__
+
+#include <Security/DLDBListCFPref.h>
+#include <Security/Keychains.h>
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+//---------------------------------------------------------------------------------
+//	Default keychain
+//
+//	Note that this is strictly a user preference setting, indicating which keychain
+//	should be used to add items to. No validity checking should be done on it in
+//	this class, since it may not be available right now (e.g. on a network volume)
+//----------------------------------------------------------------------------------
+
+class Keychain;
+
+class DefaultKeychain
+{
+public:
+	DefaultKeychain();
+	
+	// Set/Get via DLDbIdentifier
+	void dLDbIdentifier(const DLDbIdentifier& keychainID);
+	DefaultKeychain &operator =(const DLDbIdentifier& keychainID)
+	{ dLDbIdentifier(keychainID); return *this; }
+
+    void reload(bool force = false);
+	DLDbIdentifier dLDbIdentifier();
+	operator DLDbIdentifier () { return dLDbIdentifier(); }
+
+	// Remove if passed in DLDbIdentifier is currently the default
+	void remove(const DLDbIdentifier& keychainID);
+
+	// Set/Get via Keychain
+	void keychain(const Keychain& keychain);
+	DefaultKeychain &operator =(const Keychain& inKeychain) { keychain(inKeychain); return *this; }
+
+	Keychain keychain();
+	operator Keychain () { return keychain(); }
+
+	void unset(); // Who needs a default keychain anyway.
+    bool isSet();
+private:
+	DLDbListCFPref mPref;
+    DLDbIdentifier defaultID;
+};
+
+}; // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif /* _H_KEYCHAINCORE_DEFAULTKEYCHAIN__ */
diff --git a/Keychain/Globals.cpp b/Keychain/Globals.cpp
new file mode 100644
index 00000000..40bd1f12
--- /dev/null
+++ b/Keychain/Globals.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+
+/*
+    File:		Globals.cpp
+
+    Contains:	Private "globals" and interfaces for KeychainCore
+
+    Copyright:	2000 by Apple Computer, Inc., all rights reserved.
+
+    To Do:
+	
+	Notes:		Many functions moved from CKeychainMgr.h
+*/
+
+#include "Globals.h"
+#include "KCExceptions.h"
+
+
+using namespace KeychainCore;
+using namespace CssmClient;
+
+ModuleNexus<Globals> KeychainCore::globals;
+
+#pragma mark ÑÑÑÑ Constructor/Destructor ÑÑÑÑ
+
+Globals::Globals() :
+mUI(true), mACLFactory(CssmAllocator::standard())
+{
+}
+
+const AccessCredentials * Globals::credentials() 
+{
+	return (mUI ? mACLFactory.keychainPromptCredentials() : mACLFactory.nullCredentials()); 
+}
diff --git a/Keychain/Globals.h b/Keychain/Globals.h
new file mode 100644
index 00000000..f17ed83b
--- /dev/null
+++ b/Keychain/Globals.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+
+/*
+    File:		Globals.h
+
+    Contains:	Private "globals" and interfaces for KeychainCore
+
+    Copyright:	2000 by Apple Computer, Inc., all rights reserved.
+
+    To Do:
+	
+	Notes:		Many functions moved from CKeychainMgr.h
+*/
+
+#ifndef _H_GLOBALS_KEYCHAINCORE
+#define _H_GLOBALS_KEYCHAINCORE
+
+#ifdef check
+#undef check
+#endif
+#include <Security/StorageManager.h>
+#include <Security/DefaultKeychain.h>
+#include <Security/keychainacl.h>
+
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+class Globals
+{
+public:
+    Globals();
+	const AccessCredentials *credentials();
+	void setUserInteractionAllowed(bool bUI) { mUI=bUI; }
+	bool getUserInteractionAllowed() const { return mUI; }
+
+	// Public globals
+	StorageManager storageManager;
+	DefaultKeychain defaultKeychain;
+	Mutex apiLock;
+private:
+    
+	// Other "globals"
+	bool mUI;
+	CssmClient::KeychainAclFactory mACLFactory;  
+};
+
+extern ModuleNexus<Globals> globals;
+
+} // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif /* _H_GLOBALS_KEYCHAINCORE */
diff --git a/Keychain/Item.cpp b/Keychain/Item.cpp
new file mode 100644
index 00000000..8eb93849
--- /dev/null
+++ b/Keychain/Item.cpp
@@ -0,0 +1,959 @@
+/*
+ * 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.
+ */
+
+
+//
+// Item.cpp
+//
+
+#include "Item.h"
+
+#include "Globals.h"
+#include "Schema.h"
+#include "KCEventNotifier.h"
+#include "cssmdatetime.h"
+#include <Security/keychainacl.h>
+#include <Security/SecKeychainAPIPriv.h>
+#include <Security/aclsupport.h>
+#include <Security/osxsigning.h>
+
+using namespace KeychainCore;
+using namespace CSSMDateTimeUtils;
+
+//
+// ItemImpl
+//
+
+// NewItemImpl constructor
+ItemImpl::ItemImpl(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data)
+: mDbAttributes(new DbAttributes())
+{
+	if (length && data)
+		mData.reset(new CssmDataContainer(data, length));
+
+	mDbAttributes->recordType(Schema::recordTypeFor(itemClass));
+	mDbAttributes->add(Schema::attributeInfo(kSecCreatorItemAttr), itemCreator);
+
+    SInt64 date;
+	GetCurrentMacLongDateTime(date);
+    setAttribute(Schema::attributeInfo(kSecCreationDateItemAttr), date);
+    setAttribute(Schema::attributeInfo(kSecModDateItemAttr), date);
+}
+
+ItemImpl::ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data)
+: mDbAttributes(new DbAttributes())
+{
+	if (length && data)
+		mData.reset(new CssmDataContainer(data, length));
+
+
+	mDbAttributes->recordType(Schema::recordTypeFor(itemClass));
+
+	if(attrList) 
+	{
+		for(UInt32 i=0; i < attrList->count; i++)
+		{
+			mDbAttributes->add(Schema::attributeInfo(attrList->attr[i].tag), CssmData(attrList->attr[i].data,  attrList->attr[i].length));
+		}
+	}
+
+    SInt64 date;
+	GetCurrentMacLongDateTime(date);
+    setAttribute(Schema::attributeInfo(kSecCreationDateItemAttr), date);
+    setAttribute(Schema::attributeInfo(kSecModDateItemAttr), date);
+}
+
+// DbItemImpl constructor
+ItemImpl::ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey, const DbUniqueRecord &uniqueId)
+: mUniqueId(uniqueId), mKeychain(keychain), mPrimaryKey(primaryKey)
+{
+	mKeychain->addItem(mPrimaryKey, this);
+}
+
+// PrimaryKey ItemImpl constructor
+ItemImpl::ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey)
+: mKeychain(keychain), mPrimaryKey(primaryKey)
+{
+	mKeychain->addItem(mPrimaryKey, this);
+}
+
+// Constructor used when copying an item to a keychain.
+
+ItemImpl::ItemImpl(ItemImpl &item) :
+    mData(item.modifiedData() ? NULL : new CssmDataContainer()),
+    mDbAttributes(new DbAttributes())
+{
+	mDbAttributes->recordType(item.recordType());
+	CSSM_DB_RECORD_ATTRIBUTE_INFO *schemaAttributes = NULL;
+
+	if (item.mKeychain) {
+		// get the entire source item from its keychain. This requires figuring
+		// out the schema for the item based on its record type.
+		
+		for (uint32 i = 0; i < Schema::DBInfo.NumberOfRecordTypes; i++)
+			if (item.recordType() == Schema::DBInfo.RecordAttributeNames[i].DataRecordType) {
+				schemaAttributes = &Schema::DBInfo.RecordAttributeNames[i];
+				break;
+			}
+				
+		if (schemaAttributes == NULL)
+			// the source item is invalid
+			MacOSError::throwMe(errSecInvalidItemRef);
+
+		for (uint32 i = 0; i < schemaAttributes->NumberOfAttributes; i++)
+			mDbAttributes->add(schemaAttributes->AttributeInfo[i]);
+
+        item.getContent(mDbAttributes.get(), mData.get());
+	}
+
+    // @@@ We don't deal with modified attributes.
+	
+	if (item.modifiedData())
+		// the copied data comes from the source item
+		mData.reset(new CssmDataContainer(item.modifiedData()->Data,
+			item.modifiedData()->Length));
+}
+
+ItemImpl::~ItemImpl()
+{
+	if (mKeychain && *mPrimaryKey)
+		mKeychain->removeItem(*mPrimaryKey, this);
+}
+
+void
+ItemImpl::didModify()
+{
+	mData.reset(NULL);
+	mDbAttributes.reset(NULL);
+}
+
+const CSSM_DATA &
+ItemImpl::defaultAttributeValue(const CSSM_DB_ATTRIBUTE_INFO &info)
+{
+	static const uint32 zeroInt = 0;
+	static const double zeroDouble = 0.0;
+	static const char timeBytes[] = "20010101000000Z";
+
+	static const CSSM_DATA defaultFourBytes = { 4, (uint8 *) &zeroInt };
+	static const CSSM_DATA defaultEightBytes = { 8, (uint8 *) &zeroDouble };
+	static const CSSM_DATA defaultTime = { 16, (uint8 *) timeBytes };
+	static const CSSM_DATA defaultZeroBytes = { 0, NULL };
+
+	switch (info.AttributeFormat)
+	{
+		case CSSM_DB_ATTRIBUTE_FORMAT_SINT32:
+		case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
+			return defaultFourBytes;
+			
+		case CSSM_DB_ATTRIBUTE_FORMAT_REAL:
+			return defaultEightBytes;
+			
+		case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE:
+			return defaultTime;
+			
+		default:
+			return defaultZeroBytes;
+	}
+}
+
+PrimaryKey
+ItemImpl::add(const Keychain &keychain)
+{
+	// If we already have a Keychain we can't be added.
+	if (mKeychain)
+		MacOSError::throwMe(errSecDuplicateItem);
+
+    // If we don't have any attributes we can't be added.
+    // (this might occur if attempting to add the item twice, since our attributes
+    // and data are set to NULL at the end of this function.)
+    if (!mDbAttributes.get())
+		MacOSError::throwMe(errSecDuplicateItem);
+
+    // If the label (PrintName) attribute isn't specified, set a default label.
+    if (!mDbAttributes->find(Schema::attributeInfo(kSecLabelItemAttr)))
+    {
+        CssmDbAttributeData *label = NULL;
+        switch (mDbAttributes->recordType())
+        {
+            case CSSM_DL_DB_RECORD_GENERIC_PASSWORD:
+                label = mDbAttributes->find(Schema::attributeInfo(kSecServiceItemAttr));
+                break;
+
+            case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD:
+            case CSSM_DL_DB_RECORD_INTERNET_PASSWORD:
+                label = mDbAttributes->find(Schema::attributeInfo(kSecServerItemAttr));
+                // if AppleShare server name wasn't specified, try the server address
+                if (!label) label = mDbAttributes->find(Schema::attributeInfo(kSecAddressItemAttr));
+                break;
+    
+            default:
+                break;
+        }
+        // if all else fails, use the account name.
+        if (!label) label = mDbAttributes->find(Schema::attributeInfo(kSecAccountItemAttr));
+
+        if (label && label->size())
+            mDbAttributes->add(Schema::attributeInfo(kSecLabelItemAttr), label->at<CssmData>(0));
+    }
+
+	// get the attributes that are part of the primary key
+	const CssmAutoDbRecordAttributeInfo &primaryKeyInfos =
+		keychain->primaryKeyInfosFor(recordType());
+
+	// make sure each primary key element has a value in the item, otherwise
+	// the database will complain. we make a set of the provided attribute infos
+	// to avoid O(N^2) behavior.
+
+	DbAttributes *attributes = mDbAttributes.get();
+	typedef set<CssmDbAttributeInfo> InfoSet;
+	InfoSet infoSet;
+
+	for (uint32 i = 0; i < attributes->size(); i++)
+		infoSet.insert(attributes->at(i).Info);
+
+	for (uint32 i = 0; i < primaryKeyInfos.size(); i++) {
+		InfoSet::const_iterator it = infoSet.find(primaryKeyInfos.at(i));
+
+		if (it == infoSet.end()) {
+			// we need to add a default value to the item attributes
+			attributes->add(primaryKeyInfos.at(i),
+				defaultAttributeValue(primaryKeyInfos.at(i)));
+		}
+	}
+
+	Db db(keychain->database());
+	if (db->dl()->subserviceMask() & CSSM_SERVICE_CSP)
+	{
+		// Add the item to the secure storage db
+		SSDb ssDb(safe_cast<SSDbImpl *>(&(*db)));
+
+		TrackingAllocator allocator(CssmAllocator::standard());
+		// @@@ Share this instance
+		KeychainAclFactory aclFactory(allocator);
+
+		AclEntryPrototype anyEncrypt(TypedList(allocator, CSSM_ACL_SUBJECT_TYPE_ANY));
+		AuthorizationGroup &anyEncryptAuthGroup = anyEncrypt.authorization();
+		CSSM_ACL_AUTHORIZATION_TAG encryptTag = CSSM_ACL_AUTHORIZATION_ENCRYPT;
+		anyEncryptAuthGroup.NumberOfAuthTags = 1;
+		anyEncryptAuthGroup.AuthTags = &encryptTag;
+
+		const AccessCredentials *nullCred = aclFactory.nullCredentials();
+
+		const ResourceControlContext credAndAclEntry
+			(anyEncrypt, const_cast<AccessCredentials *>(nullCred));
+
+		// Create a new SSGroup with owner = ANY, encrypt = ANY
+		SSGroup ssGroup(ssDb, &credAndAclEntry);
+
+		// Now we edit the acl to look like we want it to.
+
+		// Find the PrintName (which we want SecurityAgent to display when evaluating the ACL
+		CssmDbAttributeData *data = mDbAttributes->find(Schema::attributeInfo(kSecLabelItemAttr));
+		CssmData noName;
+		CssmData &printName = data ? CssmData::overlay(data->Value[0]) : noName;
+
+		// @@@ This code should use KeychainACL instead, but that class will need some changes.
+		// Defering integration with KeychainACL to Puma.
+
+		// Figure out if we should special case this to have an anyAllow in this ACL or not.
+		// Currently only generic password items with sevicename "iTools" passwords are always anyAllow.
+		bool anyAllow = false;
+		if (mDbAttributes->recordType() == CSSM_DL_DB_RECORD_GENERIC_PASSWORD)
+		{
+			CssmDbAttributeData *data = mDbAttributes->find(Schema::attributeInfo(kSecServiceItemAttr));
+			if (data && data->Value[0].Length == 6 && !memcmp("iTools", data->Value[0].Data, 6))
+				anyAllow = true;
+		}
+
+		CssmList &list = *new(allocator) CssmList();
+	
+		// List is a threshold acl with 2 elements or 3 if anyAllow is true.
+		list.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_THRESHOLD));   
+		list.append(new(allocator) ListElement(1));
+		list.append(new(allocator) ListElement(2 + anyAllow));
+
+		// If anyAllow is true start the threshold list with a any allow sublist.
+		if(anyAllow)
+		{
+			CssmList &anySublist = *new(allocator) CssmList();
+			anySublist.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_ANY));
+			list.append(new(allocator) ListElement(anySublist));
+		}
+
+		// Now add a sublist to trust the current application.
+		auto_ptr<CodeSigning::OSXCode> code(CodeSigning::OSXCode::main());
+		const char *path = code->canonicalPath().c_str();
+		CssmData comment(const_cast<char *>(path), strlen(path) + 1);
+		TrustedApplication app(path, comment);
+		CssmList &appSublist = *new(allocator) CssmList();
+		appSublist.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE));
+		appSublist.append(new(allocator) ListElement(CSSM_ACL_CODE_SIGNATURE_OSX));
+		appSublist.append(new(allocator) ListElement(app->signature()));
+		appSublist.append(new(allocator) ListElement(app->comment()));
+		list.append(new(allocator) ListElement(appSublist));
+
+		// Finally add the keychain prompt sublist to the list so we default to asking
+		// the user for permission if all else fails.
+		CssmList &promptSublist = *new(allocator) CssmList();
+		promptSublist.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT));
+		promptSublist.append(new(allocator) ListElement(printName));
+		list.append(new(allocator) ListElement(promptSublist));	
+
+		// The acl prototype we want to add contains the list we just made.
+		AclEntryPrototype promptDecrypt(list);
+
+		// Now make sure it only authorizes decrypt.
+		AuthorizationGroup &promptDecryptAuthGroup = promptDecrypt.authorization();
+		CSSM_ACL_AUTHORIZATION_TAG decryptTag = CSSM_ACL_AUTHORIZATION_DECRYPT;
+		promptDecryptAuthGroup.NumberOfAuthTags = 1;
+		promptDecryptAuthGroup.AuthTags = &decryptTag;
+
+		// Add an acl entry for decrypt we just made
+		AclEdit edit(promptDecrypt);
+		ssGroup->changeAcl(nullCred, edit);
+
+		try
+		{
+			// Insert the record using the newly created group.
+			mUniqueId = ssDb->insert(recordType(), mDbAttributes.get(),
+									 mData.get(), ssGroup, nullCred);
+		}
+		catch(...)
+		{
+			ssGroup->deleteKey(nullCred);
+			throw;
+		}
+
+		// Change the owner so change acl = KeychainPrompt
+		AclEntryPrototype promptOwner(TypedList(allocator, CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT,
+			new(allocator) ListElement(allocator, printName)));
+		AclOwnerPrototype owner(promptOwner);
+		ssGroup->changeOwner(nullCred, owner);
+	}
+	else
+	{
+		// add the item to the (regular) db
+		mUniqueId = db->insert(recordType(), mDbAttributes.get(), mData.get());
+	}
+
+	mPrimaryKey = keychain->makePrimaryKey(recordType(), mUniqueId);
+    mKeychain = keychain;
+
+	// Forget our data and attributes.
+	mData.reset(NULL);
+	mDbAttributes.reset(NULL);
+
+	return mPrimaryKey;
+}
+
+Item
+ItemImpl::copyTo(const Keychain &keychain)
+{
+	Item item(*this);
+	keychain->add(item);
+	return item;
+}
+
+void
+ItemImpl::update()
+{
+	if (!mKeychain)
+		MacOSError::throwMe(errSecNoSuchKeychain); 
+		
+	// Don't update if nothing changed.
+	if (!isModified())
+		return;
+
+	// Set the modification date on the item.
+    SInt64 date;
+	GetCurrentMacLongDateTime(date);
+    setAttribute(Schema::attributeInfo(kSecModDateItemAttr), date);
+
+	// Make sure that we have mUniqueId
+	dbUniqueRecord();
+	Db db(mUniqueId->database());
+	if (db->dl()->subserviceMask() & CSSM_SERVICE_CSP)
+	{
+		// Add the item to the secure storage db
+		SSDbUniqueRecord ssUniqueId(safe_cast<SSDbUniqueRecordImpl *>
+									(&(*mUniqueId)));
+
+		// @@@ Share this instance
+		const AccessCredentials *autoPrompt = globals().credentials();
+
+
+		// Only call this is user interaction is enabled.
+		ssUniqueId->modify(recordType(),
+						   mDbAttributes.get(),
+						   mData.get(),
+						   CSSM_DB_MODIFY_ATTRIBUTE_REPLACE,
+						   autoPrompt);
+	}
+	else
+	{
+		mUniqueId->modify(recordType(),
+						  mDbAttributes.get(),
+						  mData.get(),
+						  CSSM_DB_MODIFY_ATTRIBUTE_REPLACE);
+	}
+
+	PrimaryKey oldPK = mPrimaryKey;
+	mPrimaryKey = mKeychain->makePrimaryKey(recordType(), mUniqueId);
+
+	// Forget our data and attributes.
+	mData.reset(NULL);
+	mDbAttributes.reset(NULL);
+
+	// Let the Keychain update what it needs to.
+	mKeychain->didUpdate(this, oldPK, mPrimaryKey);
+}
+
+void
+ItemImpl::getClass(SecKeychainAttribute &attr, UInt32 *actualLength)
+{
+	if (actualLength)
+		*actualLength = sizeof(SecItemClass);
+
+	if (attr.length < sizeof(SecItemClass))
+		MacOSError::throwMe(errSecBufferTooSmall);
+
+	SecItemClass aClass = Schema::itemClassFor(recordType());
+	memcpy(attr.data, &aClass, sizeof(SecItemClass));
+}
+
+void
+ItemImpl::setAttribute(SecKeychainAttribute& attr)
+{
+    setAttribute(Schema::attributeInfo(attr.tag), CssmData(attr.data, attr.length));
+}
+
+CSSM_DB_RECORDTYPE
+ItemImpl::recordType() const
+{
+	if (mDbAttributes.get())
+		return mDbAttributes->recordType();
+
+	return mPrimaryKey->recordType();
+}
+
+const DbAttributes *
+ItemImpl::modifiedAttributes() const
+{
+	return mDbAttributes.get();
+}
+
+const CssmData *
+ItemImpl::modifiedData() const
+{
+	return mData.get();
+}
+
+void
+ItemImpl::setData(UInt32 length,const void *data)
+{
+	mData.reset(new CssmDataContainer(data, length));
+}
+
+CssmClient::DbUniqueRecord
+ItemImpl::dbUniqueRecord()
+{
+	if (!mUniqueId)
+	{
+		assert(mKeychain && mPrimaryKey);
+		DbCursor cursor(mPrimaryKey->createCursor(mKeychain));
+		if (!cursor->next(NULL, NULL, mUniqueId))
+		{
+			killRef();
+			MacOSError::throwMe(errSecInvalidItemRef);
+		}
+	}
+
+	return mUniqueId;
+}
+
+PrimaryKey
+ItemImpl::primaryKey() const
+{
+	return mPrimaryKey;
+}
+
+bool
+ItemImpl::isPersistant() const
+{
+	return mKeychain;
+}
+
+bool
+ItemImpl::isModified() const
+{
+	return mData.get() || mDbAttributes.get();
+}
+
+Keychain
+ItemImpl::keychain() const
+{
+	return mKeychain;
+}
+
+bool
+ItemImpl::operator <(const ItemImpl &other) const
+{
+
+	if (*mData)
+	{
+		// Pointer compare
+		return this < &other;
+	}
+
+	// XXX Deal with not having a mPrimaryKey
+	return *mPrimaryKey < *(other.mPrimaryKey);
+
+}
+
+void
+ItemImpl::setAttribute(const CssmDbAttributeInfo &info, const CssmPolyData &data)
+{
+	if (!mDbAttributes.get())
+	{
+		mDbAttributes.reset(new DbAttributes());
+		mDbAttributes->recordType(mPrimaryKey->recordType());
+	}
+
+	uint32 length = data.Length;
+	const void *buf = reinterpret_cast<const void *>(data.Data);
+    uint8 timeString[16];
+
+    // XXX This code is duplicated in KCCursorImpl::KCCursorImpl()
+    // Convert a 4 or 8 byte TIME_DATE to a CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
+    // style attribute value.
+    if (info.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
+    {
+        if (length == sizeof(UInt32))
+        {
+            MacSecondsToTimeString(*reinterpret_cast<const UInt32 *>(buf), 16, &timeString);
+            buf = &timeString;
+            length = 16;
+        }
+        else if (length == sizeof(SInt64))
+        {
+            MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64 *>(buf),
+                                        16, &timeString);
+            buf = &timeString;
+            length = 16;
+        }
+    }
+
+	mDbAttributes->add(info, CssmData(const_cast<void*>(buf), length));
+}
+
+void
+ItemImpl::modifyContent(const SecKeychainAttributeList *attrList, UInt32 dataLength, const void *inData)
+{
+	if (!mDbAttributes.get())
+	{
+		mDbAttributes.reset(new DbAttributes());
+		mDbAttributes->recordType(mPrimaryKey->recordType());
+	}
+
+	if(attrList) // optional
+	{
+		for(UInt32 ix=0; ix < attrList->count; ix++)
+		{
+			mDbAttributes->add(Schema::attributeInfo(attrList->attr[ix].tag), CssmData(attrList->attr[ix].data,  attrList->attr[ix].length));
+		}
+	}
+	
+	if(inData)
+	{
+		mData.reset(new CssmDataContainer(inData, dataLength));
+	}
+	
+	update();
+}
+
+void
+ItemImpl::getContent(SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData)
+{
+
+	// If the data hasn't been set we can't return it.
+	if (!mKeychain && outData)
+	{
+		CssmData *data = mData.get();
+		if (!data)
+			MacOSError::throwMe(errSecDataNotAvailable);
+	}
+	// TODO: need to check and make sure attrs are valid and handle error condition
+
+
+	if(itemClass)
+		*itemClass = Schema::itemClassFor(recordType());
+		
+	dbUniqueRecord();
+
+    UInt32 attrCount = attrList ? attrList->count : 0;
+	DbAttributes dbAttributes(mUniqueId->database(), attrCount);
+    for (UInt32 ix = 0; ix < attrCount; ++ix)
+        dbAttributes.add(Schema::attributeInfo(attrList->attr[ix].tag));
+
+	CssmDataContainer itemData;
+    getContent(&dbAttributes, outData ? &itemData : NULL);
+
+	if (outData) KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this);
+
+    for (UInt32 ix = 0; ix < attrCount; ++ix)
+    {
+        if (dbAttributes.at(ix).NumberOfValues > 0)
+        {
+            attrList->attr[ix].data = dbAttributes.at(ix).Value[0].Data;	
+            attrList->attr[ix].length = dbAttributes.at(ix).Value[0].Length;
+
+            // We don't want the data released, it is up the client
+            dbAttributes.at(ix).Value[0].Data = NULL;
+            dbAttributes.at(ix).Value[0].Length = 0;
+        }
+        else
+        {
+            attrList->attr[ix].data = NULL;	
+            attrList->attr[ix].length = 0;
+        }
+    }
+
+	if (outData)
+	{
+		*outData=itemData.data();
+		itemData.Data=NULL;
+		
+		*length=itemData.length();
+		itemData.Length=0;
+	}
+	
+}
+
+void
+ItemImpl::freeContent(SecKeychainAttributeList *attrList, void *data)
+{
+	CssmAllocator &allocator = CssmAllocator::standard(); // @@@ This might not match the one used originally
+	if (data)
+		allocator.free(data);
+
+    UInt32 attrCount = attrList ? attrList->count : 0;
+    for (UInt32 ix = 0; ix < attrCount; ++ix)
+    {
+        allocator.free(attrList->attr[ix].data);
+        attrList->attr[ix].data = NULL;
+    }
+}
+
+void
+ItemImpl::modifyAttributesAndData(const SecKeychainAttributeList *attrList, UInt32 dataLength, const void *inData)
+{
+	if (!mKeychain)
+		MacOSError::throwMe(errSecNoSuchKeychain);
+
+	if (!mDbAttributes.get())
+	{
+		mDbAttributes.reset(new DbAttributes());
+		mDbAttributes->recordType(mPrimaryKey->recordType());
+	}
+
+    UInt32 attrCount = attrList ? attrList->count : 0;
+	for (UInt32 ix = 0; ix < attrCount; ix++)
+	{
+		CssmDbAttributeInfo info=mKeychain->attributeInfoForTag(attrList->attr[ix].tag);
+						
+		if (attrList->attr[ix].length || info.AttributeFormat==CSSM_DB_ATTRIBUTE_FORMAT_STRING  || info.AttributeFormat==CSSM_DB_ATTRIBUTE_FORMAT_BLOB
+		 || info.AttributeFormat==CSSM_DB_ATTRIBUTE_FORMAT_STRING  || info.AttributeFormat==CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM
+		 || info.AttributeFormat==CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32)
+			mDbAttributes->add(info, CssmData(attrList->attr[ix].data, attrList->attr[ix].length));
+		else
+			mDbAttributes->add(info);
+	}
+	
+	if(inData)
+	{
+		mData.reset(new CssmDataContainer(inData, dataLength));
+	}
+	
+	update();
+}
+
+void
+ItemImpl::getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData)
+{
+	// If the data hasn't been set we can't return it.
+	if (!mKeychain && outData)
+	{
+		CssmData *data = mData.get();
+		if (!data)
+			MacOSError::throwMe(errSecDataNotAvailable);
+	}
+	// TODO: need to check and make sure attrs are valid and handle error condition
+
+
+	if(itemClass)
+		*itemClass = Schema::itemClassFor(recordType());
+		
+	dbUniqueRecord();
+
+    UInt32 attrCount = info ? info->count : 0;
+	DbAttributes dbAttributes(mUniqueId->database(), attrCount);
+    for (UInt32 ix = 0; ix < attrCount; ix++)
+	{
+		CssmDbAttributeData &record = dbAttributes.add();
+		record.Info.AttributeNameFormat=CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
+		record.Info.Label.AttributeID=info->tag[ix];
+	}
+
+	CssmDataContainer itemData;
+    getContent(&dbAttributes, outData ? &itemData : NULL);
+
+	if(info && attrList)
+	{
+		SecKeychainAttributeList *theList=reinterpret_cast<SecKeychainAttributeList *>(malloc(sizeof(SecKeychainAttributeList)));
+		SecKeychainAttribute *attr=reinterpret_cast<SecKeychainAttribute *>(malloc(sizeof(SecKeychainAttribute)*attrCount));
+		theList->count=attrCount;
+		theList->attr=attr;
+	
+		for (UInt32 ix = 0; ix < attrCount; ++ix)
+		{
+			attr[ix].tag=info->tag[ix];
+			
+			if (dbAttributes.at(ix).NumberOfValues > 0)
+			{
+				attr[ix].data = dbAttributes.at(ix).Value[0].Data;	
+				attr[ix].length = dbAttributes.at(ix).Value[0].Length;
+	
+				// We don't want the data released, it is up the client
+				dbAttributes.at(ix).Value[0].Data = NULL;
+				dbAttributes.at(ix).Value[0].Length = 0;
+			}
+			else
+			{
+				attr[ix].data = NULL;	
+				attr[ix].length = 0;
+			}
+		}
+		*attrList=theList;
+	}
+
+	if (outData)
+	{
+		*outData=itemData.data();
+		itemData.Data=NULL;
+		
+		*length=itemData.length();
+		itemData.Length=0;
+				
+		KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this);
+	}
+	
+}
+
+void
+ItemImpl::freeAttributesAndData(SecKeychainAttributeList *attrList, void *data)
+{
+	CssmAllocator &allocator = CssmAllocator::standard(); // @@@ This might not match the one used originally
+
+	if (data)
+		allocator.free(data);
+
+	if(attrList)
+	{
+		for (UInt32 ix = 0; ix < attrList->count; ++ix)
+		{
+			allocator.free(attrList->attr[ix].data);
+		}
+		free(attrList->attr);
+		free(attrList);
+	}
+}
+
+void
+ItemImpl::getAttribute(SecKeychainAttribute& attr, UInt32 *actualLength)
+{
+	if (attr.tag == kSecClassItemAttr)
+		return getClass(attr, actualLength);
+
+	if (mDbAttributes.get())
+	{
+		CssmDbAttributeData *data = mDbAttributes->find(Schema::attributeInfo(attr.tag));
+		if (data)
+		{
+			getAttributeFrom(data, attr, actualLength);
+			return;
+		}
+	}
+
+	if (!mKeychain)
+		MacOSError::throwMe(errSecNoSuchAttr);
+		
+	dbUniqueRecord();
+	DbAttributes dbAttributes(mUniqueId->database(), 1);
+	dbAttributes.add(Schema::attributeInfo(attr.tag));
+	mUniqueId->get(&dbAttributes, NULL);
+	getAttributeFrom(&dbAttributes.at(0), attr, actualLength);
+}
+
+void
+ItemImpl::getAttributeFrom(CssmDbAttributeData *data, SecKeychainAttribute &attr, UInt32 *actualLength)
+{
+    static const uint32 zero = 0;
+    uint32 length;
+    const void *buf;
+
+    // Temporary storage for buf.
+    SInt64 macLDT;
+    UInt32 macSeconds;
+    sint16 svalue16;
+    uint16 uvalue16;
+    sint8 svalue8;
+    uint8 uvalue8;
+
+	if (!data)
+        length = 0;
+    else if (data->size() < 1) // Attribute has no values.
+    {
+        if (data->format() == CSSM_DB_ATTRIBUTE_FORMAT_SINT32
+            || data->format() == CSSM_DB_ATTRIBUTE_FORMAT_UINT32)
+        {
+            length = sizeof(zero);
+            buf = &zero;
+        }
+        else if (CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
+            length = 0; // Should we throw here?
+        else // All other formats
+            length = 0;
+	}
+    else // Get the first value
+    {
+        length = data->Value[0].Length;
+        buf = data->Value[0].Data;
+
+        if (data->format() == CSSM_DB_ATTRIBUTE_FORMAT_SINT32)
+        {
+            if (attr.length == sizeof(sint8))
+            {
+                length = attr.length;
+                svalue8 = sint8(*reinterpret_cast<const sint32 *>(buf));
+                buf = &svalue8;
+            }
+            else if (attr.length == sizeof(sint16))
+            {
+                length = attr.length;
+                svalue16 = sint16(*reinterpret_cast<const sint32 *>(buf));
+                buf = &svalue16;
+            }
+        }
+        else if (data->format() == CSSM_DB_ATTRIBUTE_FORMAT_UINT32)
+        {
+            if (attr.length == sizeof(uint8))
+            {
+                length = attr.length;
+                uvalue8 = uint8(*reinterpret_cast<const uint32 *>(buf));
+                buf = &uvalue8;
+            }
+            else if (attr.length == sizeof(uint16))
+            {
+                length = attr.length;
+                uvalue16 = uint16(*reinterpret_cast<const uint32 *>(buf));
+                buf = &uvalue16;
+            }
+        }
+        else if (data->format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
+        {
+            if (attr.length == sizeof(UInt32))
+            {
+                TimeStringToMacSeconds(data->Value[0], macSeconds);
+                buf = &macSeconds;
+                length = attr.length;
+            }
+            else if (attr.length == sizeof(SInt64))
+            {
+                TimeStringToMacLongDateTime(data->Value[0], macLDT);
+                buf = &macLDT;
+                length = attr.length;
+            }
+        }
+    }
+
+	if (actualLength)
+		*actualLength = length;
+
+    if (length)
+    {
+        if (attr.length < length)
+            MacOSError::throwMe(errSecBufferTooSmall);
+
+        memcpy(attr.data, buf, length);
+    }
+}
+
+void
+ItemImpl::getData(CssmDataContainer& outData)
+{
+	if (!mKeychain)
+	{
+		CssmData *data = mData.get();
+		// If the data hasn't been set we can't return it.
+		if (!data)
+			MacOSError::throwMe(errSecDataNotAvailable);
+
+		outData = *data;
+		return;
+	}
+
+    getContent(NULL, &outData);
+
+	//%%%<might> be done elsewhere, but here is good for now
+	KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this);
+}
+
+SSGroup
+ItemImpl::group()
+{
+	SSGroup group;
+	if (&*mUniqueId)
+	{
+		Db db(mKeychain->database());
+		if (db->dl()->subserviceMask() & CSSM_SERVICE_CSP)
+		{
+			group = safer_cast<SSDbUniqueRecordImpl &>(*mUniqueId).group();
+		}
+	}
+
+	return group;
+}
+
+void
+ItemImpl::getContent(DbAttributes *dbAttributes, CssmDataContainer *itemData)
+{
+    // Make sure mUniqueId is set.
+	dbUniqueRecord();
+	if (itemData)
+	{
+		Db db(mUniqueId->database());
+		if (db->dl()->subserviceMask() & CSSM_SERVICE_CSP)
+		{
+			SSDbUniqueRecord ssUniqueId(safe_cast<SSDbUniqueRecordImpl *>(&(*mUniqueId)));
+			const AccessCredentials *autoPrompt = globals().credentials();
+			ssUniqueId->get(dbAttributes, itemData, autoPrompt);
+            return;
+		}
+    }
+
+    mUniqueId->get(dbAttributes, itemData); 
+}
diff --git a/Keychain/Item.h b/Keychain/Item.h
new file mode 100644
index 00000000..6f6edcde
--- /dev/null
+++ b/Keychain/Item.h
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+
+//
+// Item.h
+//
+#ifndef _H_DBITEM
+#define _H_DBITEM
+
+#include <Security/Keychains.h>
+#include <Security/PrimaryKey.h>
+#include <Security/securestorage.h>
+
+namespace Security
+{
+
+using namespace CssmClient;
+
+namespace KeychainCore
+{
+class Item;
+class Keychain;
+
+class ItemImpl : public ReferencedObject
+{
+    friend class Item;
+
+protected:
+	// new item constructors
+    ItemImpl(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data);
+	
+	ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data);
+
+	// db item contstructor
+    ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
+
+	// PrimaryKey item contstructor
+    ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey);
+	
+	ItemImpl(ItemImpl &item);
+
+	void getAttributeFrom(CssmDbAttributeData *data, SecKeychainAttribute &attr,  UInt32 *actualLength);
+	void getClass(SecKeychainAttribute &attr,  UInt32 *actualLength);
+
+protected:
+	// Methods called by KeychainImpl;
+	friend class KeychainImpl;
+
+	// Add the receiver to keychain
+	PrimaryKey add(const Keychain &keychain);
+		
+	// Get the default value for an attribute
+	static const CSSM_DATA &defaultAttributeValue(const CSSM_DB_ATTRIBUTE_INFO &info);
+
+public:
+    ~ItemImpl();
+    bool isPersistant() const;
+    bool isModified() const;
+
+	void update();
+
+	// put a copy of the item into a given keychain
+	Item copyTo(const Keychain &keychain);
+
+    CSSM_DB_RECORDTYPE recordType() const;
+
+	// Used for writing the record to the database.
+    CssmClient::DbUniqueRecord dbUniqueRecord();
+	const CssmClient::DbAttributes *modifiedAttributes() const;
+	const CssmData *modifiedData() const;
+	void didModify(); // Forget any attributes and data we just wrote to the db
+
+	Keychain keychain() const;
+	PrimaryKey primaryKey() const;
+	bool operator <(const ItemImpl &other) const;
+
+	void getAttribute(SecKeychainAttribute& attr,  UInt32 *actualLength);
+	void getData(CssmDataContainer& outData);
+	
+	void modifyContent(const SecKeychainAttributeList *attrList, UInt32 dataLength, const void *inData);
+	void getContent(SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData);
+	static void freeContent(SecKeychainAttributeList *attrList, void *data);
+	static void freeAttributesAndData(SecKeychainAttributeList *attrList, void *data);
+
+	void getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData);
+	void modifyAttributesAndData(const SecKeychainAttributeList *attrList, UInt32 dataLength, const void *inData);
+
+	void setAttribute(SecKeychainAttribute& attr);
+	void setAttribute(const CssmDbAttributeInfo &info, const CssmPolyData &data);
+	void setData(UInt32 length,const void *data);
+	
+	
+	
+	SSGroup group();
+
+
+protected:
+    void getContent(DbAttributes *dbAttributes, CssmDataContainer *itemData);
+
+	// new item members
+    auto_ptr<CssmDataContainer> mData;
+    auto_ptr<CssmClient::DbAttributes> mDbAttributes;
+
+	// db item members
+    CssmClient::DbUniqueRecord mUniqueId;
+	Keychain mKeychain;
+    PrimaryKey mPrimaryKey;
+	
+};
+
+class Item : public RefPointer<ItemImpl>
+{
+public:
+    Item() {}
+    Item(ItemImpl *impl) : RefPointer<ItemImpl>(impl) {}
+
+    Item(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data)
+	: RefPointer<ItemImpl>(new ItemImpl(itemClass, itemCreator, length, data)) {}
+	
+    Item(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data)
+	: RefPointer<ItemImpl>(new ItemImpl(itemClass, attrList, length, data)) {}
+
+    Item(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId)
+    : RefPointer<ItemImpl>(new ItemImpl(keychain, primaryKey, uniqueId)) {}
+
+    Item(const Keychain &keychain, const PrimaryKey &primaryKey)
+    : RefPointer<ItemImpl>(new ItemImpl(keychain, primaryKey)) {}
+	
+	Item(ItemImpl &item)
+	: RefPointer<ItemImpl>(new ItemImpl(item)) {}
+
+    bool operator <(const Item &other) const { return **this < *other; }
+    bool operator !=(const Item &other) const { return **this < *other || *other < **this; }
+    bool operator ==(const Item &other) const { return !(*this != other); }
+
+	typedef ItemImpl Impl;
+};
+
+
+typedef Ref<Item, ItemImpl, SecKeychainItemRef, errSecInvalidItemRef> ItemRef;
+
+
+}; // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif // _H_DBITEM
\ No newline at end of file
diff --git a/Keychain/KCCursor.cpp b/Keychain/KCCursor.cpp
new file mode 100644
index 00000000..f457dd8d
--- /dev/null
+++ b/Keychain/KCCursor.cpp
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+
+//
+// KCCursor.cpp
+//
+
+#include "KCCursor.h"
+
+#include "Item.h"
+#include "Schema.h"
+#include "cssmdatetime.h"
+#include "Globals.h"
+#include "StorageManager.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+using namespace KeychainCore;
+using namespace CssmClient;
+using namespace CSSMDateTimeUtils;
+
+//
+// KCCursorImpl
+//
+KCCursorImpl::KCCursorImpl(const DbCursor &dbCursor, SecItemClass itemClass, const SecKeychainAttributeList *attrList)
+: mDbCursor(dbCursor)
+{
+	if (!attrList) // No additional selectionPredicates: we are done
+		return;
+
+		
+    mDbCursor->recordType(Schema::recordTypeFor(itemClass));
+
+	mDbCursor->conjunctive(CSSM_DB_AND);
+	const SecKeychainAttribute *end=&attrList->attr[attrList->count];
+	// Add all the attrs in attrs list to the cursor.
+	for (const SecKeychainAttribute *attr=attrList->attr; attr != end; ++attr)
+	{
+        const CssmDbAttributeInfo &info = Schema::attributeInfo(attr->tag);
+        void *buf = attr->data;
+        UInt32 length = attr->length;
+        uint8 timeString[16];
+    
+        // XXX This code is duplicated in NewItemImpl::setAttribute()
+        // Convert a 4 or 8 byte TIME_DATE to a CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
+        // style attribute value.
+        if (info.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
+        {
+            if (length == sizeof(UInt32))
+            {
+                MacSecondsToTimeString(*reinterpret_cast<const UInt32 *>(buf),
+                                        16, &timeString);
+                buf = &timeString;
+                length = 16;
+            }
+            else if (length == sizeof(SInt64))
+            {
+                MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64 *>(buf),
+                                            16, &timeString);
+                buf = &timeString;
+                length = 16;
+            }
+        }
+        mDbCursor->add(CSSM_DB_EQUAL,info, CssmData(buf,length));
+	}
+}
+
+KCCursorImpl::KCCursorImpl(const DbCursor &dbCursor, const SecKeychainAttributeList *attrList)
+: mDbCursor(dbCursor)
+{
+	if (!attrList) // No additional selectionPredicates: we are done
+		return;
+
+	mDbCursor->conjunctive(CSSM_DB_AND);
+	bool foundClassAttribute=false;
+	const SecKeychainAttribute *end=&attrList->attr[attrList->count];
+	// Add all the attrs in attrs list to the cursor.
+	for (const SecKeychainAttribute *attr=attrList->attr; attr != end; ++attr)
+	{
+		if (attr->tag!=kSecClassItemAttr)	// a regular attribute
+		{
+            const CssmDbAttributeInfo &info = Schema::attributeInfo(attr->tag);
+            void *buf = attr->data;
+            UInt32 length = attr->length;
+            uint8 timeString[16];
+        
+            // XXX This code is duplicated in NewItemImpl::setAttribute()
+            // Convert a 4 or 8 byte TIME_DATE to a CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
+            // style attribute value.
+            if (info.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
+            {
+                if (length == sizeof(UInt32))
+                {
+                    MacSecondsToTimeString(*reinterpret_cast<const UInt32 *>(buf),
+                                           16, &timeString);
+                    buf = &timeString;
+                    length = 16;
+                }
+                else if (length == sizeof(SInt64))
+                {
+                    MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64 *>(buf),
+                                                16, &timeString);
+                    buf = &timeString;
+                    length = 16;
+                }
+            }
+			mDbCursor->add(CSSM_DB_EQUAL,info, CssmData(buf,length));
+
+			continue;
+		}
+		
+		// the class attribute
+		if (foundClassAttribute || attr->length != sizeof(SecItemClass))
+			MacOSError::throwMe(paramErr); // We have 2 different 'clas' attributes
+
+		mDbCursor->recordType(Schema
+            ::recordTypeFor(*reinterpret_cast<SecItemClass *>(attr->data)));
+		foundClassAttribute=true;
+	}
+}
+
+KCCursorImpl::~KCCursorImpl()
+{
+}
+
+bool
+KCCursorImpl::next(Item &item)
+{
+	DbAttributes dbAttributes;
+	DbUniqueRecord uniqueId;
+	if (!mDbCursor)
+		MacOSError::throwMe(errSecInvalidSearchRef);
+
+	for (;;)
+	{
+		if (!mDbCursor->next(&dbAttributes, NULL, uniqueId))
+		{
+			// Forget my resources.
+			mDbCursor = DbCursor();
+			return false;
+		}
+
+		// Skip records that we don't have a matching itemClass for,
+		// since we can't do anything with them.
+		if (Schema::itemClassFor(dbAttributes.recordType()))
+			break;
+	}
+
+	Keychain keychain = globals().storageManager.keychain(uniqueId->database()->dlDbIdentifier());
+	// Go though Keychain since item might already exist.
+	item = keychain->item(dbAttributes.recordType(), uniqueId);
+	return true;
+}
diff --git a/Keychain/KCCursor.h b/Keychain/KCCursor.h
new file mode 100644
index 00000000..291e1ff6
--- /dev/null
+++ b/Keychain/KCCursor.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		KCCursor.h
+
+	Contains:	The keychain class
+
+	Copyright:	2000 by Apple Computer, Inc., all rights reserved.
+
+	To Do:
+*/
+
+#ifndef _H_KCCURSOR_
+#define _H_KCCURSOR_
+
+#include <Security/StorageManager.h>
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+class KCCursor;
+
+class KCCursorImpl : public ReferencedObject
+{
+    NOCOPY(KCCursorImpl)
+    friend class KCCursor;
+protected:
+	KCCursorImpl(const CssmClient::DbCursor &dbCursor, SecItemClass itemClass, const SecKeychainAttributeList *attrList);
+	KCCursorImpl(const CssmClient::DbCursor &dbCursor, const SecKeychainAttributeList *attrList);
+
+public:
+	virtual ~KCCursorImpl();
+	bool next(Item &item);
+
+private:
+	CssmClient::DbCursor mDbCursor;
+};
+
+
+class KCCursor : public RefPointer<KCCursorImpl>
+{
+public:
+    KCCursor() {}
+    
+    KCCursor(KCCursorImpl *impl) : RefPointer<KCCursorImpl>(impl) {}
+
+    KCCursor(const CssmClient::DbCursor &dbCursor, const SecKeychainAttributeList *attrList)
+	: RefPointer<KCCursorImpl>(new KCCursorImpl(dbCursor, attrList)) {}
+
+    KCCursor(const CssmClient::DbCursor &dbCursor, SecItemClass itemClass, const SecKeychainAttributeList *attrList)
+	: RefPointer<KCCursorImpl>(new KCCursorImpl(dbCursor, itemClass, attrList)) {}
+
+	typedef KCCursorImpl Impl;
+};
+
+
+typedef Ref<KCCursor, KCCursorImpl, SecKeychainSearchRef, errSecInvalidSearchRef> KCCursorRef;
+
+} // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif /* _H_KCCURSOR_ */
+
diff --git a/Keychain/KCEventNotifier.cpp b/Keychain/KCEventNotifier.cpp
new file mode 100644
index 00000000..2cf9f658
--- /dev/null
+++ b/Keychain/KCEventNotifier.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		KCEventNotifier.cpp
+
+	Contains:	OS X CF Notifier for Keychain Events
+
+	Written by:	Craig Mortensen
+
+	Copyright:	2000 by Apple Computer, Inc., All rights reserved.
+
+	Change History (most recent first):
+
+	To Do:
+*/
+
+#include "KCEventNotifier.h"
+#include "KCExceptions.h"
+#include "Keychains.h"
+
+using namespace KeychainCore;
+
+void KCEventNotifier::PostKeychainEvent(SecKeychainEvent whichEvent, const Keychain &keychain, const Item &kcItem)
+{
+	DLDbIdentifier dlDbIdentifier;
+	PrimaryKey primaryKey;
+
+	if (keychain)
+		dlDbIdentifier = keychain->dLDbIdentifier();
+
+    if (kcItem)
+		primaryKey = kcItem->primaryKey();
+
+	PostKeychainEvent(whichEvent, dlDbIdentifier, primaryKey);
+}
+
+
+void KCEventNotifier::PostKeychainEvent(SecKeychainEvent whichEvent,
+										const DLDbIdentifier &dlDbIdentifier, 
+										const PrimaryKey &primaryKey)
+{
+	CFRef<CFMutableDictionaryRef> mutableDict(::CFDictionaryCreateMutable(kCFAllocatorDefault,0,
+			&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+    KCThrowIfMemFail_(CFMutableDictionaryRef(mutableDict));
+
+	SInt32 theEvent = SInt32(whichEvent);
+    CFRef<CFNumberRef> theEventData(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &theEvent));
+    KCThrowIfMemFail_(CFNumberRef(theEventData));
+    CFDictionarySetValue(mutableDict, kSecEventTypeKey, theEventData);
+
+	if (dlDbIdentifier)
+	{
+		CFRef<CFDictionaryRef> dict(DLDbListCFPref::dlDbIdentifierToCFDictionaryRef(dlDbIdentifier));
+		KCThrowIfMemFail_(CFDictionaryRef(dict));
+		CFDictionarySetValue(mutableDict, kSecEventKeychainKey, dict);
+	}
+
+    if (primaryKey)
+    {
+		CFRef<CFDataRef> data(CFDataCreate(kCFAllocatorDefault, primaryKey->Data, primaryKey->Length));
+		KCThrowIfMemFail_(CFDataRef(data));
+		CFDictionarySetValue(mutableDict, kSecEventItemKey, data);
+    }
+
+    // 'name' has to be globally unique (could be KCLockEvent, etc.)
+    // 'object' is just information or a context that can be used.
+    // 'userInfo' has info on event (i.e. which DL/DB(kc - see John's Dict), the event, 
+    //								 item(cssmdbuniqueRec))
+    CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(), 
+										 kSecEventNotificationName, NULL, mutableDict, false);
+}
diff --git a/Keychain/KCEventNotifier.h b/Keychain/KCEventNotifier.h
new file mode 100644
index 00000000..768d53e7
--- /dev/null
+++ b/Keychain/KCEventNotifier.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		KCEventNotifier.h
+
+	Contains:	OS X CF Notifier for Keychain Events
+
+	Written by:	Craig Mortensen
+
+	Copyright:	2000 by Apple Computer, Inc., All rights reserved.
+
+	Change History (most recent first):
+
+	To Do:
+*/
+
+#ifndef _KCEVENTNOTIFIER_H_
+#define _KCEVENTNOTIFIER_H_
+
+#include <CoreFoundation/CFNotificationCenter.h>
+#include <CoreFoundation/CFString.h>
+#include <Security/Item.h>
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+#define kSecEventNotificationName CFSTR("com.apple.securitycore.kcevent")
+#define kSecEventTypeKey CFSTR("type")
+#define kSecEventKeychainKey CFSTR("keychain")
+#define kSecEventItemKey CFSTR("item")
+
+class Keychain;
+
+class KCEventNotifier
+{
+public:
+	static void PostKeychainEvent(SecKeychainEvent kcEvent, 
+								  const Keychain& keychain, 
+								  const Item &item = Item());
+	static void PostKeychainEvent(SecKeychainEvent kcEvent, 
+								  const DLDbIdentifier &dlDbIdentifier = DLDbIdentifier(), 
+								  const PrimaryKey &primaryKey = PrimaryKey());
+};
+
+} // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif /* _KCEVENTNOTIFIER_H_ */
diff --git a/Keychain/KCEventObserver.cpp b/Keychain/KCEventObserver.cpp
new file mode 100644
index 00000000..09943893
--- /dev/null
+++ b/Keychain/KCEventObserver.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		KCEventObserver.cpp
+
+	Contains:	OS X CF Observer for Keychain Events
+
+	Written by:	Craig Mortensen
+
+	Copyright:	2000 by Apple Computer, Inc., All rights reserved.
+
+	Change History (most recent first):
+
+	To Do:
+*/
+
+#include "KCEventObserver.h"
+
+using namespace Security;
+
+Observer::Observer()
+{
+}
+//
+// Upon creation of this object, add this observer for this instance of KeychainCore
+//
+Observer::Observer( CFStringRef name, const void *object, 
+                    CFNotificationSuspensionBehavior suspensionBehavior )
+{
+    add( name, object, suspensionBehavior );
+}
+
+//
+// Upon destruction of this object, remove 'this' observer for this instance of KeychainCore
+//
+Observer::~Observer()
+{
+    ::CFNotificationCenterRemoveEveryObserver( CFNotificationCenterGetDistributedCenter(), this );
+}
+
+//
+// 'callback' is passed in to CFNotificationCenterAddObserver() when this object
+// is constructed when KeychainCore is created.  'callback' is called by CF whenever an event happens.
+//
+void Observer::callback(CFNotificationCenterRef 	center, 
+                        void*					 	observer, 
+                        CFStringRef 				name, 
+                        const void* 				object, 
+                        CFDictionaryRef 			userInfo)
+{
+    // 'Event' is where this KeychainCore notifies it's clients of the kc event that just happened.
+    //
+	try
+	{
+		reinterpret_cast<Observer *>(observer)->Event( center, name, object, userInfo );
+	}
+	catch(...)
+	{
+		// @@@ do a log to console();
+	}
+}
+
+//
+// Add 'this' observer to CF for this instance of KeychainCore
+//
+void Observer::add( CFStringRef 					 name, 
+                    const void* 					 object, 
+                    CFNotificationSuspensionBehavior suspensionBehavior )
+{
+    ::CFNotificationCenterAddObserver( CFNotificationCenterGetDistributedCenter(), 
+                                       this, callback, name, object, suspensionBehavior );
+}
diff --git a/Keychain/KCEventObserver.h b/Keychain/KCEventObserver.h
new file mode 100644
index 00000000..39fadb4e
--- /dev/null
+++ b/Keychain/KCEventObserver.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		KCEventObserver.h
+
+	Contains:	OS X CF Observer for Keychain Events
+
+	Written by:	Craig Mortensen
+
+	Copyright:	2000 by Apple Computer, Inc., All rights reserved.
+
+	Change History (most recent first):
+
+	To Do:
+*/
+
+#include <CoreFoundation/CFNotificationCenter.h>
+#include <CoreFoundation/CFString.h>
+#include <Security/SecKeychainAPI.h>
+
+namespace Security
+{
+
+class Observer
+{
+public:
+    Observer				();
+    
+    Observer				( CFStringRef 						name, 
+                              const void*						object, 
+                              CFNotificationSuspensionBehavior 	suspensionBehavior = 
+                                                                CFNotificationSuspensionBehaviorHold );
+    
+    virtual	~Observer		();
+
+    static void callback	( CFNotificationCenterRef 	center, 
+                              void*					 	observer, 
+                              CFStringRef 				name, 
+                              const void* 				object, 
+                              CFDictionaryRef 			userInfo );
+
+            void	add		( CFStringRef 						name, 
+                              const void*						object, 
+                              CFNotificationSuspensionBehavior  suspensionBehavior );
+
+    virtual void 	Event	( CFNotificationCenterRef 	center, 
+                              CFStringRef 				name, 
+                              const void* 				object, 
+                              CFDictionaryRef 			userInfo ) = 0;
+};
+
+} // end namespace Security
diff --git a/Keychain/KCExceptions.h b/Keychain/KCExceptions.h
new file mode 100644
index 00000000..e3d6c313
--- /dev/null
+++ b/Keychain/KCExceptions.h
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+
+/*
+    KCExceptions.h
+*/
+
+#ifndef _H_KCEXCEPTIONS
+#define _H_KCEXCEPTIONS
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+#ifdef lock
+#undef lock
+#endif
+#include <Security/utilities.h>
+
+#ifdef check
+#undef check
+#endif
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+//
+// Helpers for memory pointer validation
+//
+
+/*	remove RequiredParam when cdsa does namespaces
+template <class T>
+inline T &Required(T *ptr,OSStatus err = paramErr)
+{
+    return Required(ptr,err);
+}
+*/
+
+template <class T>
+inline void KCThrowIfMemFail_(const T *ptr)
+{
+    if (ptr==NULL)
+		MacOSError::throwMe(memFullErr);
+}
+
+inline void KCThrowIf_(OSStatus theErr)
+{
+	// will also work for OSErr
+    if (theErr!=noErr)
+        MacOSError::throwMe(theErr);
+}
+
+inline void KCThrowIf_(bool test,OSStatus theErr)
+{
+	// will also work for OSErr
+    if (test)
+        MacOSError::throwMe(theErr);
+}
+
+inline void KCThrowParamErrIf_(bool test)
+{
+    if (test)
+        MacOSError::throwMe(paramErr);
+}
+
+inline void KCUnimplemented_()
+{
+	MacOSError::throwMe(unimpErr);
+}
+
+} // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif /* _H_KCEXCEPTIONS */
\ No newline at end of file
diff --git a/Keychain/KCUtilities.cpp b/Keychain/KCUtilities.cpp
new file mode 100644
index 00000000..88185136
--- /dev/null
+++ b/Keychain/KCUtilities.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+
+#ifdef __MWERKS__
+#define _KC_UTILITIES
+#endif
+
+#include <Security/KCUtilities.h>
+#include <Security/cssmerrno.h>
+
+namespace Security
+{
+
+OSStatus GetKeychainErrFromCSSMErr( OSStatus cssmError )
+{
+	if (CSSM_ERR_IS_CONVERTIBLE(cssmError))
+	{
+		switch (CSSM_ERRCODE(cssmError))
+		{
+			// CONVERTIBLE ERROR CODES.
+			case CSSM_ERRCODE_SERVICE_NOT_AVAILABLE:
+				return errSecNotAvailable;
+			case CSSM_ERRCODE_USER_CANCELED:
+				return userCanceledErr;
+			case CSSM_ERRCODE_OPERATION_AUTH_DENIED:
+				return errSecAuthFailed;
+			default:
+				return cssmError;
+		}
+	}
+	else
+	{
+		switch (cssmError)
+		{
+			// DL SPECIFIC ERROR CODES
+			case CSSMERR_DL_RECORD_NOT_FOUND:
+				return errSecItemNotFound;
+			case CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA:
+				return errSecDuplicateItem;
+			case CSSMERR_DL_DATABASE_CORRUPT:
+				return errSecInvalidKeychain;
+			case CSSMERR_DL_DATASTORE_DOESNOT_EXIST:
+				return errSecNoSuchKeychain;
+			case CSSMERR_DL_DATASTORE_ALREADY_EXISTS:
+				return errSecDuplicateKeychain;
+			case CSSMERR_DL_INVALID_FIELD_NAME:
+				return errSecNoSuchAttr;
+			default:
+				return cssmError;
+		}
+	}
+}
+
+StKCAttribute::StKCAttribute( SecKeychainAttribute* inPtr ) :
+    fAttr( inPtr )
+{
+}
+
+StKCAttribute::~StKCAttribute( )
+{
+    delete fAttr;
+}
+
+StKCItem::StKCItem( SecKeychainItemRef* inItem, OSStatus* result ) :
+    fItem( inItem ),
+    fResult( result )
+{
+}
+
+StKCItem::~StKCItem( )
+{
+    // if an error occured and the item is valid, release the item
+    //
+    if ( *fResult != noErr && *fItem != NULL )
+        ::SecKeychainItemRelease(*fItem ); // %%% rjp was KCItemRelease(fitem);
+}
+
+} // end namespace Security
diff --git a/Keychain/KCUtilities.h b/Keychain/KCUtilities.h
new file mode 100644
index 00000000..945cc2f1
--- /dev/null
+++ b/Keychain/KCUtilities.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+
+#ifdef _KC_UTILS
+# pragma export on
+#endif
+
+#include <Security/SecKeychainAPI.h>
+#include <Security/utilities.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <memory>
+
+namespace Security
+{
+
+OSStatus GetKeychainErrFromCSSMErr(OSStatus cssmError);
+
+//
+// Helpers for memory pointer validation
+//
+template <class T>
+inline T &RequiredParam(T *ptr,OSStatus err = paramErr)
+{
+    if (ptr == NULL)
+        MacOSError::throwMe(err);
+    return *ptr;
+}
+
+class StKCAttribute
+{
+public:
+                    StKCAttribute( SecKeychainAttribute* attr );
+        virtual		~StKCAttribute( void );
+private:
+        SecKeychainAttribute* 	fAttr;
+};
+
+// Class for cleaning up a KCItemRef when finished with it
+// if an error occurs at any time when dealing with the item.
+//
+class StKCItem
+{
+public:
+                    StKCItem( SecKeychainItemRef* item, OSStatus* result );
+        virtual		~StKCItem( void );
+private:
+        SecKeychainItemRef* 	fItem;
+        OSStatus*	fResult;
+};
+
+} // end namespace Security
+
+#ifdef _KC_UTILS
+#pragma export off
+#endif
diff --git a/Keychain/Keychains.cpp b/Keychain/Keychains.cpp
new file mode 100644
index 00000000..085b62f9
--- /dev/null
+++ b/Keychain/Keychains.cpp
@@ -0,0 +1,632 @@
+/*
+ * 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.
+ */
+
+
+//
+// Keychains.cpp
+//
+
+#include "Keychains.h"
+#include "KCEventNotifier.h"
+
+#include "Item.h"
+#include "KCCursor.h"
+#include "Globals.h"
+#include "Schema.h"
+#include <Security/keychainacl.h>
+#include <Security/cssmacl.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <Security/cssmdb.h>
+
+
+using namespace KeychainCore;
+using namespace CssmClient;
+
+
+//
+// KeychainSchemaImpl
+//
+KeychainSchemaImpl::KeychainSchemaImpl(const Db &db)
+{
+	DbCursor relations(db);
+	relations->recordType(CSSM_DL_DB_SCHEMA_INFO);
+	DbAttributes relationRecord(db, 1);
+	relationRecord.add(Schema::RelationID);
+	DbUniqueRecord outerUniqueId(db);
+
+	while (relations->next(&relationRecord, NULL, outerUniqueId))
+	{
+		DbUniqueRecord uniqueId(db);
+
+		uint32 relationID = relationRecord.at(0);
+		if (CSSM_DB_RECORDTYPE_SCHEMA_START <= relationID && relationID < CSSM_DB_RECORDTYPE_SCHEMA_END)
+			continue;
+
+		// Create a cursor on the SCHEMA_ATTRIBUTES table for records with RelationID == relationID
+		DbCursor attributes(db);
+		attributes->recordType(CSSM_DL_DB_SCHEMA_ATTRIBUTES);
+		attributes->add(CSSM_DB_EQUAL, Schema::RelationID, relationID);
+	
+		// Set up a record for retriving the SCHEMA_ATTRIBUTES
+		DbAttributes attributeRecord(db, 2);
+		attributeRecord.add(Schema::AttributeFormat);
+		attributeRecord.add(Schema::AttributeID);
+		attributeRecord.add(Schema::AttributeNameFormat);
+	
+	
+		RelationInfoMap &rim = mDatabaseInfoMap[relationID];
+		while (attributes->next(&attributeRecord, NULL, uniqueId))
+		{
+			if(CSSM_DB_ATTRIBUTE_FORMAT(attributeRecord.at(2))==CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER)
+				rim[attributeRecord.at(1)] = attributeRecord.at(0);
+		}
+		
+		// Create a cursor on the CSSM_DL_DB_SCHEMA_INDEXES table for records with RelationID == relationID
+		DbCursor indexes(db);
+		indexes->recordType(CSSM_DL_DB_SCHEMA_INDEXES);
+		indexes->conjunctive(CSSM_DB_AND);
+		indexes->add(CSSM_DB_EQUAL, Schema::RelationID, relationID);
+		indexes->add(CSSM_DB_EQUAL, Schema::IndexType, uint32(CSSM_DB_INDEX_UNIQUE));
+
+		// Set up a record for retriving the SCHEMA_INDEXES
+		DbAttributes indexRecord(db, 1);
+		indexRecord.add(Schema::AttributeID);
+
+		CssmAutoDbRecordAttributeInfo &infos = *new CssmAutoDbRecordAttributeInfo();
+		mPrimaryKeyInfoMap.insert(PrimaryKeyInfoMap::value_type(relationID, &infos));
+		infos.DataRecordType = relationID;
+		while (indexes->next(&indexRecord, NULL, uniqueId))
+		{
+			CssmDbAttributeInfo &info = infos.add();
+			info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
+			info.Label.AttributeID = indexRecord.at(0);
+			info.AttributeFormat = rim[info.Label.AttributeID]; // @@@ Might insert bogus value if DB is corrupt
+		}
+	}
+}
+
+KeychainSchemaImpl::~KeychainSchemaImpl()
+{
+	for_each_map_delete(mPrimaryKeyInfoMap.begin(), mPrimaryKeyInfoMap.end());
+}
+
+CSSM_DB_ATTRIBUTE_FORMAT 
+KeychainSchemaImpl::attributeFormatFor(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const
+{
+
+	DatabaseInfoMap::const_iterator dit = mDatabaseInfoMap.find(recordType);
+	if (dit == mDatabaseInfoMap.end())
+		MacOSError::throwMe(errSecNoSuchClass);
+	RelationInfoMap::const_iterator rit = dit->second.find(attributeId);
+	if (dit == dit->second.end())
+		MacOSError::throwMe(errSecNoSuchAttr);
+
+	return rit->second;
+}
+
+CssmDbAttributeInfo
+KeychainSchemaImpl::attributeInfoForTag(UInt32 tag)
+{
+	CSSM_DB_ATTRIBUTE_INFO info;
+
+	for(DatabaseInfoMap::const_iterator dit = mDatabaseInfoMap.begin(); dit != mDatabaseInfoMap.end(); ++dit)
+	{
+		for(RelationInfoMap::const_iterator rit = dit->second.begin(); rit != dit->second.end(); ++rit)
+		{
+			if(rit->first==tag)
+			{
+				info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
+				info.Label.AttributeID = rit->first;
+				info.AttributeFormat = rit->second;
+				return info;
+			}
+		}
+	}
+	return info;
+}
+
+void
+KeychainSchemaImpl::getAttributeInfoForRecordType(CSSM_DB_RECORDTYPE recordType, SecKeychainAttributeInfo **Info)
+{
+	DatabaseInfoMap::const_iterator dit = mDatabaseInfoMap.find(recordType);
+	if (dit == mDatabaseInfoMap.end())
+		MacOSError::throwMe(errSecNoSuchClass);
+
+	SecKeychainAttributeInfo *theList=reinterpret_cast<SecKeychainAttributeInfo *>(malloc(sizeof(SecKeychainAttributeInfo)));
+	
+	UInt32 capacity=32;
+	UInt32 *tagBuf=reinterpret_cast<UInt32 *>(malloc(capacity*sizeof(UInt32)));
+	UInt32 *formatBuf=reinterpret_cast<UInt32 *>(malloc(capacity*sizeof(UInt32)));
+	UInt32 i=0;
+	
+	for(RelationInfoMap::const_iterator rit = dit->second.begin(); rit != dit->second.end(); ++rit)
+	{
+		if(i>=capacity)
+		{
+			capacity*=2;
+			tagBuf=reinterpret_cast<UInt32 *>(realloc(tagBuf, (capacity*sizeof(UInt32))));
+			formatBuf=reinterpret_cast<UInt32 *>(realloc(tagBuf, (capacity*sizeof(UInt32))));
+		}
+		tagBuf[i]=rit->first;
+		formatBuf[i++]=rit->second;
+	}
+	
+	theList->count=i;
+	theList->tag=tagBuf;
+	theList->format=formatBuf;
+	*Info=theList;		
+}
+
+
+const CssmAutoDbRecordAttributeInfo &
+KeychainSchemaImpl::primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType)
+{
+	PrimaryKeyInfoMap::iterator it;
+	it = mPrimaryKeyInfoMap.find(recordType);
+	
+	// if the primary key attributes have already been determined,
+	// return the cached results
+	
+	if (it == mPrimaryKeyInfoMap.end())
+		MacOSError::throwMe(errSecNoSuchClass); // @@@ Not really but whatever.
+
+	return *it->second;
+}
+
+bool
+KeychainSchemaImpl::operator <(const KeychainSchemaImpl &other) const
+{
+	return mDatabaseInfoMap < other.mDatabaseInfoMap;
+}
+
+bool
+KeychainSchemaImpl::operator ==(const KeychainSchemaImpl &other) const
+{
+	return mDatabaseInfoMap == other.mDatabaseInfoMap;
+}
+
+
+//
+// KeychainImpl
+//
+KeychainImpl::KeychainImpl(const Db &db)
+: mDb(db)
+{
+}
+
+KeychainImpl::~KeychainImpl()
+{
+}
+
+KCCursor
+KeychainImpl::createCursor(SecItemClass itemClass, const SecKeychainAttributeList *attrList)
+{
+	return KCCursor(DbCursor(mDb), itemClass, attrList);
+}
+
+KCCursor
+KeychainImpl::createCursor(const SecKeychainAttributeList *attrList)
+{
+	return KCCursor(DbCursor(mDb), attrList);
+}
+
+void
+KeychainImpl::create(UInt32 passwordLength, const void *inPassword)
+{
+	if (!inPassword)
+	{
+		create();
+		return;
+	}
+
+	CssmAllocator &alloc = CssmAllocator::standard();
+	// @@@ Share this instance
+	KeychainAclFactory aclFactory(alloc);
+
+	// @@@ This leaks the returned credentials
+	const CssmData password(const_cast<void *>(inPassword), passwordLength);
+	const AccessCredentials *cred = aclFactory.passwordChangeCredentials(password);
+
+	// @@@ Create a nice wrapper for building the default AclEntryPrototype. 
+	TypedList subject(alloc, CSSM_ACL_SUBJECT_TYPE_ANY);
+	AclEntryPrototype protoType(subject);
+	AuthorizationGroup &authGroup = protoType.authorization();
+	CSSM_ACL_AUTHORIZATION_TAG tag = CSSM_ACL_AUTHORIZATION_ANY;
+	authGroup.NumberOfAuthTags = 1;
+	authGroup.AuthTags = &tag;
+
+	const ResourceControlContext rcc(protoType, const_cast<AccessCredentials *>(cred));
+	create(&rcc);
+}
+
+void KeychainImpl::create(ConstStringPtr inPassword)
+{
+    if ( inPassword )
+        create(static_cast<UInt32>(inPassword[0]), &inPassword[1]);
+    else
+        create();
+}
+
+void
+KeychainImpl::create()
+{
+	CssmAllocator &alloc = CssmAllocator::standard();
+	// @@@ Share this instance
+	KeychainAclFactory aclFactory(alloc);
+
+	const AccessCredentials *cred = aclFactory.keychainPromptUnlockCredentials();
+
+	// @@@ Create a nice wrapper for building the default AclEntryPrototype.
+	TypedList subject(alloc, CSSM_ACL_SUBJECT_TYPE_ANY);
+	AclEntryPrototype protoType(subject);
+	AuthorizationGroup &authGroup = protoType.authorization();
+	CSSM_ACL_AUTHORIZATION_TAG tag = CSSM_ACL_AUTHORIZATION_ANY;
+	authGroup.NumberOfAuthTags = 1;
+	authGroup.AuthTags = &tag;
+
+	const ResourceControlContext rcc(protoType, const_cast<AccessCredentials *>(cred));
+	create(&rcc);
+}
+
+void
+KeychainImpl::create(const ResourceControlContext *rcc)
+{
+	mDb->dbInfo(&Schema::DBInfo); // Set the schema (to force a create)
+	mDb->resourceControlContext(rcc);
+    try
+    {
+        mDb->create();
+    }
+    catch (...)
+    {
+		mDb->resourceControlContext(NULL);
+        mDb->dbInfo(NULL); // Clear the schema (to not break an open call later)
+        throw;
+    }
+	mDb->resourceControlContext(NULL);
+	mDb->dbInfo(NULL); // Clear the schema (to not break an open call later)
+	globals().storageManager.created(Keychain(this));
+}
+
+void
+KeychainImpl::open()
+{
+	mDb->open();
+}
+
+void
+KeychainImpl::lock()
+{
+	mDb->lock();
+}
+
+void
+KeychainImpl::unlock()
+{
+	mDb->unlock();
+}
+
+void
+KeychainImpl::unlock(const CssmData &password)
+{
+	mDb->unlock(password);
+}
+
+void
+KeychainImpl::unlock(ConstStringPtr password)
+{
+	if (password)
+	{
+		const CssmData data(const_cast<unsigned char *>(&password[1]), password[0]);
+		unlock(data);
+	}
+	else
+		unlock();
+}
+
+void
+KeychainImpl::getSettings(uint32 &outIdleTimeOut, bool &outLockOnSleep)
+{
+	mDb->getSettings(outIdleTimeOut, outLockOnSleep);
+}
+
+void
+KeychainImpl::setSettings(uint32 inIdleTimeOut, bool inLockOnSleep)
+{
+	mDb->setSettings(inIdleTimeOut, inLockOnSleep);
+}
+void 
+KeychainImpl::changePassphrase(UInt32 oldPasswordLength, const void *oldPassword,
+	UInt32 newPasswordLength, const void *newPassword)
+{
+	// @@@ When AutoCredentials is actually finished we should no logner use a tracking allocator.
+	TrackingAllocator allocator(CssmAllocator::standard());
+	AutoCredentials cred = AutoCredentials(allocator);
+	if (oldPassword)
+	{
+		const CssmData &oldPass = *new(allocator) CssmData(const_cast<void *>(oldPassword), oldPasswordLength);
+		TypedList &oldList = *new(allocator) TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK);
+		oldList.append(new(allocator) ListElement(CSSM_SAMPLE_TYPE_PASSWORD));
+		oldList.append(new(allocator) ListElement(oldPass));
+		cred += oldList;
+	}
+
+	if (newPassword)
+	{
+		const CssmData &newPass = *new(allocator) CssmData(const_cast<void *>(newPassword), newPasswordLength);
+		TypedList &newList = *new(allocator) TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK);
+		newList.append(new(allocator) ListElement(CSSM_SAMPLE_TYPE_PASSWORD));
+		newList.append(new(allocator) ListElement(newPass));
+		cred += newList;
+	}
+
+	mDb->changePassphrase(&cred);
+}
+
+void
+KeychainImpl::changePassphrase(ConstStringPtr oldPassword, ConstStringPtr newPassword)
+{
+	const void *oldPtr, *newPtr;
+	UInt32 oldLen, newLen;
+	if (oldPassword)
+	{
+		oldLen = oldPassword[0];
+		oldPtr = oldPassword + 1;
+	}
+	else
+	{
+		oldLen = 0;
+		oldPtr = NULL;
+	}
+
+	if (newPassword)
+	{
+		newLen = newPassword[0];
+		newPtr = newPassword + 1;
+	}
+	else
+	{
+		newLen = 0;
+		newPtr = NULL;
+	}
+
+	changePassphrase(oldLen, oldPtr, newLen, newPtr);
+}
+
+void
+KeychainImpl::authenticate(const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	// @@@ This should do an authenticate which is not the same as unlock.
+	if (!exists())
+		MacOSError::throwMe(errSecNoSuchKeychain);
+
+	MacOSError::throwMe(unimpErr);
+}
+
+UInt32
+KeychainImpl::status() const
+{
+	// @@@ We should figure out the read/write status though a DL passthrough or some other way.
+	// @@@ Also should locked be unlocked read only or just read-only?
+	return (mDb->isLocked() ? 0 : kSecUnlockStateStatus | kSecWrPermStatus) | kSecRdPermStatus;
+}
+
+bool
+KeychainImpl::exists()
+{
+	bool exists = true;
+	try
+	{
+		open();
+		// Ok to leave the mDb open since it will get closed when it goes away.
+	}
+	catch (const CssmError &e)
+	{
+		if (e.cssmError() != CSSMERR_DL_DATASTORE_DOESNOT_EXIST)
+			throw;
+		exists = false;
+	}
+
+	return exists;
+}
+
+bool
+KeychainImpl::isActive() const
+{
+	return mDb->isActive();
+}
+
+void
+KeychainImpl::add(Item &inItem)
+{
+	PrimaryKey primaryKey = inItem->add(this);
+	{
+		StLock<Mutex> _(mDbItemMapLock);
+		// Use &* to get the item's Impl.
+		mDbItemMap[primaryKey] = &*inItem;
+	}
+
+    KCEventNotifier::PostKeychainEvent(kSecAddEvent, this, inItem);
+}
+
+void
+KeychainImpl::didUpdate(ItemImpl *inItemImpl, PrimaryKey &oldPK,
+						PrimaryKey &newPK)
+{
+	// Make sure we only hold mDbItemMapLock as long as we need to.
+	{
+		StLock<Mutex> _(mDbItemMapLock);
+		DbItemMap::iterator it = mDbItemMap.find(oldPK);
+		if (it != mDbItemMap.end() && it->second == inItemImpl)
+			mDbItemMap.erase(it);
+		mDbItemMap[newPK] = inItemImpl;
+	}
+
+    KCEventNotifier::PostKeychainEvent( kSecUpdateEvent, this, inItemImpl );
+}
+
+void
+KeychainImpl::deleteItem(Item &inoutItem)
+{
+	// item must be persistant.
+	if (!inoutItem->isPersistant())
+		MacOSError::throwMe(errSecInvalidItemRef);
+
+	DbUniqueRecord uniqueId = inoutItem->dbUniqueRecord();
+	PrimaryKey primaryKey = inoutItem->primaryKey();
+	uniqueId->deleteRecord();
+
+	// Don't kill the ref or clear the Item() since this potentially
+	// messes up things for the receiver of the kSecDeleteEvent notification.
+	//inoutItem->killRef();
+	//inoutItem = Item();
+
+    // Post the notification for the item deletion with
+	// the primaryKey obtained when the item still existed
+	KCEventNotifier::PostKeychainEvent(kSecDeleteEvent, dLDbIdentifier(), primaryKey);
+}
+
+PrimaryKey
+KeychainImpl::makePrimaryKey(CSSM_DB_RECORDTYPE recordType, DbUniqueRecord &uniqueId)
+{
+	DbAttributes primaryKeyAttrs(uniqueId->database());
+	primaryKeyAttrs.recordType(recordType);
+	gatherPrimaryKeyAttributes(primaryKeyAttrs);
+	uniqueId->get(&primaryKeyAttrs, NULL);
+	return PrimaryKey(primaryKeyAttrs);
+}
+
+const CssmAutoDbRecordAttributeInfo &
+KeychainImpl::primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType)
+{
+	return keychainSchema()->primaryKeyInfosFor(recordType);
+}
+
+void KeychainImpl::gatherPrimaryKeyAttributes(DbAttributes& primaryKeyAttrs)
+{
+	const CssmAutoDbRecordAttributeInfo &infos =
+		primaryKeyInfosFor(primaryKeyAttrs.recordType());
+
+	// @@@ fix this to not copy info.		
+	for (uint32 i = 0; i < infos.size(); i++)
+		primaryKeyAttrs.add(infos.at(i));
+}
+
+Item
+KeychainImpl::item(const PrimaryKey& primaryKey)
+{
+	{
+		StLock<Mutex> _(mDbItemMapLock);
+		DbItemMap::iterator it = mDbItemMap.find(primaryKey);
+		if (it != mDbItemMap.end())
+		{
+			return Item(it->second);
+		}
+	}
+
+	// Create an item with just a primary key
+    return Item(this, primaryKey);
+}
+
+Item
+KeychainImpl::item(CSSM_DB_RECORDTYPE recordType, DbUniqueRecord &uniqueId)
+{
+	PrimaryKey primaryKey = makePrimaryKey(recordType, uniqueId);
+	{
+		StLock<Mutex> _(mDbItemMapLock);
+		DbItemMap::iterator it = mDbItemMap.find(primaryKey);
+		if (it != mDbItemMap.end())
+		{
+			return Item(it->second);
+		}
+	}
+
+	// Create a new item
+    return Item(this, primaryKey, uniqueId);
+}
+
+KeychainSchema
+KeychainImpl::keychainSchema()
+{
+	if (!mKeychainSchema)
+	{
+		// @@@ Use cache in storageManager
+		mKeychainSchema = KeychainSchema(mDb);
+	}
+
+	return mKeychainSchema;
+}
+
+// Called from DbItemImpl's constructor (so it is only paritally constructed), add it to the map. 
+void
+KeychainImpl::addItem(const PrimaryKey &primaryKey, ItemImpl *dbItemImpl)
+{
+	StLock<Mutex> _(mDbItemMapLock);
+	DbItemMap::iterator it = mDbItemMap.find(primaryKey);
+	if (it != mDbItemMap.end())
+	{
+		// @@@ There is a race condition here when being called in multiple threads
+		// We might have added an item using add and received a notification at the same time
+		//assert(true);
+		throw errSecDuplicateItem;
+		//mDbItemMap.erase(it);
+		// @@@ What to do here?
+	}
+
+	mDbItemMap.insert(DbItemMap::value_type(primaryKey, dbItemImpl));
+}
+
+void
+KeychainImpl::removeItem(const PrimaryKey &primaryKey, const ItemImpl *inItemImpl)
+{
+	// Sent from DbItemImpl's destructor, remove it from the map. 
+	StLock<Mutex> _(mDbItemMapLock);
+	DbItemMap::iterator it = mDbItemMap.find(primaryKey);
+	if (it != mDbItemMap.end() && it->second == inItemImpl)
+		mDbItemMap.erase(it);
+}
+
+void
+KeychainImpl::getAttributeInfoForItemID(CSSM_DB_RECORDTYPE itemID, SecKeychainAttributeInfo **Info)
+{
+	keychainSchema()->getAttributeInfoForRecordType(itemID, Info);
+}
+
+void 
+KeychainImpl::freeAttributeInfo(SecKeychainAttributeInfo *Info)
+{
+	free(Info->tag);
+	free(Info->format);
+	free(Info);
+}
+
+CssmDbAttributeInfo
+KeychainImpl::attributeInfoForTag(UInt32 tag)
+{
+	return keychainSchema()->attributeInfoForTag(tag);
+
+}
+
+Keychain
+Keychain::optional(SecKeychainRef handle)
+{
+	if (handle)
+		return KeychainRef::required(handle);
+	else
+		return globals().defaultKeychain;
+}
+
diff --git a/Keychain/Keychains.h b/Keychain/Keychains.h
new file mode 100644
index 00000000..54242aa7
--- /dev/null
+++ b/Keychain/Keychains.h
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		Keychains.h
+
+	Contains:	The keychain class
+
+	Copyright:	2000 by Apple Computer, Inc., all rights reserved.
+
+	To Do:
+*/
+
+#ifndef _H_KEYCHAINS_
+#define _H_KEYCHAINS_
+
+#include <Security/dlclient.h>
+#include <Security/refcount.h>
+#include <Security/utilities.h>
+#include <Security/DLDBListCFPref.h>
+#include <Security/Refs.h>
+#include <Security/SecKeychainAPI.h>
+#include <Security/SecKeychainAPIPriv.h>
+#include <memory>
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+class KCCursor;
+class Item;
+class ItemImpl;
+class Keychain;
+class PrimaryKey;
+class StorageManager;
+
+
+class KeychainSchemaImpl : public ReferencedObject
+{
+public:
+    KeychainSchemaImpl(const CssmClient::Db &db);
+    ~KeychainSchemaImpl();
+
+	CSSM_DB_ATTRIBUTE_FORMAT attributeFormatFor(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const;
+	const CssmAutoDbRecordAttributeInfo &primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType);
+	
+	bool operator <(const KeychainSchemaImpl &other) const;
+	bool operator ==(const KeychainSchemaImpl &other) const;
+
+	void getAttributeInfoForRecordType(CSSM_DB_RECORDTYPE recordType, SecKeychainAttributeInfo **Info);
+	CssmDbAttributeInfo attributeInfoForTag(UInt32 tag);
+
+private:
+	typedef map<CSSM_DB_RECORDTYPE, CssmAutoDbRecordAttributeInfo *> PrimaryKeyInfoMap;
+	PrimaryKeyInfoMap mPrimaryKeyInfoMap;
+
+	typedef map<uint32, CSSM_DB_ATTRIBUTE_FORMAT> RelationInfoMap;
+	typedef map<CSSM_DB_RECORDTYPE, RelationInfoMap> DatabaseInfoMap;
+	DatabaseInfoMap mDatabaseInfoMap;
+
+	
+};
+
+
+class KeychainSchema : public RefPointer<KeychainSchemaImpl>
+{
+public:
+    KeychainSchema() {}
+    KeychainSchema(KeychainSchemaImpl *impl) : RefPointer<KeychainSchemaImpl>(impl) {}
+    KeychainSchema(const CssmClient::Db &db) : RefPointer<KeychainSchemaImpl>(new KeychainSchemaImpl(db)) {}
+
+	bool operator <(const KeychainSchema &other) const
+	{ return ptr && other.ptr ? *ptr < *other.ptr : ptr < other.ptr; }
+	bool operator ==(const KeychainSchema &other) const
+	{ return ptr && other.ptr ? *ptr == *other.ptr : ptr == other.ptr; }
+
+private:
+	typedef KeychainSchemaImpl Impl;
+};
+
+
+class KeychainImpl : public ReferencedObject
+{
+    NOCOPY(KeychainImpl)
+	friend class Keychain;
+protected:
+    KeychainImpl(const CssmClient::Db &db);
+
+protected:
+	// Methods called by ItemImpl;
+	friend class ItemImpl;
+
+	void didUpdate(ItemImpl *inItemImpl, PrimaryKey &oldPK,
+						PrimaryKey &newPK);
+
+public:
+    virtual ~KeychainImpl();
+
+    // Item calls
+    void add(Item &item); // item must not be persistant.  Item will change.
+    void deleteItem(Item &item); // item must be persistant.
+
+    // Keychain calls
+	void create(UInt32 passwordLength, const void *inPassword);
+    void create(ConstStringPtr inPassword);
+    void create();
+    void create(const ResourceControlContext *rcc);
+    void open(); // There is no close since the client lib deals with that itself. might throw
+
+	// Locking and unlocking a keychain.
+    void lock();
+    void unlock();
+	void unlock(const CssmData &password);
+    void unlock(ConstStringPtr password); // @@@ This has a length limit, we should remove it.
+
+	void getSettings(uint32 &outIdleTimeOut, bool &outLockOnSleep);
+	void setSettings(uint32 inIdleTimeOut, bool inLockOnSleep);
+
+	// Passing in NULL for either oldPassword or newPassword will cause them to be prompted for.
+	// To specify a zero length password in either case the oldPasswordLength or newPasswordLength
+	// value must be 0 and the oldPassword or newPassword must not be NULL.
+	void changePassphrase(UInt32 oldPasswordLength, const void *oldPassword,
+		UInt32 newPasswordLength, const void *newPassword);
+	void changePassphrase(ConstStringPtr oldPassword, ConstStringPtr newPassword);
+
+    void authenticate(const CSSM_ACCESS_CREDENTIALS *cred);     // Does not do an unlock.
+
+	const char *name() const { return mDb->name(); }
+	UInt32 status() const;
+	bool exists();
+	bool isActive() const;
+
+	KCCursor createCursor(const SecKeychainAttributeList *attrList);
+	KCCursor createCursor(SecItemClass itemClass, const SecKeychainAttributeList *attrList);
+	CssmClient::Db database() { return mDb; }
+	DLDbIdentifier dLDbIdentifier() const { return mDb->dlDbIdentifier(); }
+
+	PrimaryKey makePrimaryKey(CSSM_DB_RECORDTYPE recordType, CssmClient::DbUniqueRecord &uniqueId);
+	void gatherPrimaryKeyAttributes(CssmClient::DbAttributes& primaryKeyAttrs);
+	
+	const CssmAutoDbRecordAttributeInfo &primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType);
+
+    Item item(const PrimaryKey& primaryKey);
+    Item item(CSSM_DB_RECORDTYPE recordType, CssmClient::DbUniqueRecord &uniqueId);
+	
+	CssmDbAttributeInfo attributeInfoForTag(UInt32 tag);
+	void getAttributeInfoForItemID(CSSM_DB_RECORDTYPE itemID, SecKeychainAttributeInfo **Info);
+static	void freeAttributeInfo(SecKeychainAttributeInfo *Info);
+
+private:
+	KeychainSchema keychainSchema();
+	void addItem(const PrimaryKey &primaryKey, ItemImpl *dbItemImpl);
+	void removeItem(const PrimaryKey &primaryKey, const ItemImpl *inItemImpl); 
+
+    CssmClient::Db mDb;
+	Mutex mDbItemMapLock;
+    typedef map<PrimaryKey, ItemImpl *> DbItemMap;
+    DbItemMap mDbItemMap;
+
+	KeychainSchema mKeychainSchema;
+};
+
+
+class Keychain : public RefPointer<KeychainImpl>
+{
+public:
+    Keychain() {}
+    Keychain(KeychainImpl *impl) : RefPointer<KeychainImpl>(impl) {}
+
+	static Keychain optional(SecKeychainRef handle); 
+
+private:
+	friend class StorageManager;
+    Keychain(const CssmClient::Db &db)
+	: RefPointer<KeychainImpl>(new KeychainImpl(db)) {}
+
+	typedef KeychainImpl Impl;
+};
+
+
+typedef Ref<Keychain, KeychainImpl, SecKeychainRef, errSecInvalidKeychain> KeychainRef;
+
+} // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif /* _H_KEYCHAINS_ */
+
diff --git a/Keychain/PrimaryKey.cpp b/Keychain/PrimaryKey.cpp
new file mode 100644
index 00000000..b2a04a5d
--- /dev/null
+++ b/Keychain/PrimaryKey.cpp
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+
+//
+// PrimaryKey.cpp
+//
+
+#include "PrimaryKey.h"
+
+using namespace KeychainCore;
+using namespace CssmClient;
+
+
+PrimaryKeyImpl::PrimaryKeyImpl(const CSSM_DATA &data)
+: CssmDataContainer(data.Data, data.Length)
+{
+
+//@@@ do bounds checking here, throw if invalid
+
+}
+
+PrimaryKeyImpl::PrimaryKeyImpl(const DbAttributes &primaryKeyAttrs)
+{
+	Length = sizeof(uint32);
+	for (uint32 ix = 0; ix < primaryKeyAttrs.size(); ++ix)
+	{
+		if (primaryKeyAttrs.at(ix).size() == 0)
+			MacOSError::throwMe(errSecInvalidKeychain);
+
+		Length += sizeof(uint32) + primaryKeyAttrs.at(ix).Value[0].Length;
+	}
+
+	// Careful with exceptions
+	Data = mAllocator.alloc<uint8>(Length);
+	uint8 *p = Data;
+
+	putUInt32(p, primaryKeyAttrs.recordType());
+	for (uint32 ix = 0; ix < primaryKeyAttrs.size(); ++ix)
+	{
+		uint32 len = primaryKeyAttrs.at(ix).Value[0].Length;
+		putUInt32(p, len);
+		memcpy(p, primaryKeyAttrs.at(ix).Value[0].Data, len);
+		p += len;
+	}
+}
+
+CssmClient::DbCursor
+PrimaryKeyImpl::createCursor(const Keychain &keychain) 
+{
+	DbCursor cursor(keychain->database());
+
+	// @@@ Set up cursor to find item with this.
+	uint8 *p = Data;
+	uint32 left = Length;
+	if (left < sizeof(*p))
+		MacOSError::throwMe(errSecNoSuchAttr); // XXX Not really but whatever.
+
+	CSSM_DB_RECORDTYPE rt = getUInt32(p, left);
+	const CssmAutoDbRecordAttributeInfo &infos = keychain->primaryKeyInfosFor(rt);
+
+	cursor->recordType(rt);
+	cursor->conjunctive(CSSM_DB_AND);
+	for (uint32 ix = 0; ix < infos.size(); ++ix)
+	{
+		uint32 len = getUInt32(p, left);
+
+		if (left < len)
+			MacOSError::throwMe(errSecNoSuchAttr); // XXX Not really but whatever.
+
+		CssmData value(p, len);
+		left -= len;
+		p += len;
+
+		cursor->add(CSSM_DB_EQUAL, infos.at(ix), value);
+	}
+
+	return cursor;
+}
+
+
+void
+PrimaryKeyImpl::putUInt32(uint8 *&p, uint32 value)
+{
+	*p++ = (value >> 24);
+	*p++ = (value >> 16) & 0xff;
+	*p++ = (value >> 8) & 0xff;
+	*p++ = value & 0xff;
+}
+
+uint32
+PrimaryKeyImpl::getUInt32(uint8 *&p, uint32 &left) const
+{
+	if (left < sizeof(uint32))
+		MacOSError::throwMe(errSecNoSuchAttr); // XXX Not really but whatever.
+
+
+	// @@@ Assumes data written in big endian.
+	uint32 value = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
+	p += sizeof(uint32);
+	left -= sizeof(uint32);
+	return value;
+}
+
+
+
+CSSM_DB_RECORDTYPE
+PrimaryKeyImpl::recordType() const
+{
+	uint8 *data = Data;
+	uint32 length = Length;
+	return getUInt32(data, length);
+}
diff --git a/Keychain/PrimaryKey.h b/Keychain/PrimaryKey.h
new file mode 100644
index 00000000..d7250beb
--- /dev/null
+++ b/Keychain/PrimaryKey.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+
+//
+// PrimaryKey.h
+//
+#ifndef _H_PRIMARYKEY
+#define _H_PRIMARYKEY
+
+#include <Security/dlclient.h>
+#include <Security/Keychains.h>
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+class PrimaryKeyImpl : public CssmDataContainer
+{
+public:
+    PrimaryKeyImpl(const CSSM_DATA &data);
+    PrimaryKeyImpl(const CssmClient::DbAttributes &primaryKeyAttrs);
+    ~PrimaryKeyImpl() {}
+
+	void putUInt32(uint8 *&p, uint32 value);
+	uint32 getUInt32(uint8 *&p, uint32 &left) const;
+
+	CssmClient::DbCursor createCursor(const Keychain &keychain);
+
+	CSSM_DB_RECORDTYPE recordType() const;
+private:
+};
+
+
+class PrimaryKey : public RefPointer<PrimaryKeyImpl>
+{
+public:
+    PrimaryKey() {}
+    PrimaryKey(PrimaryKeyImpl *impl) : RefPointer<PrimaryKeyImpl>(impl) {}
+    PrimaryKey(const CSSM_DATA &data)
+	: RefPointer<PrimaryKeyImpl>(new PrimaryKeyImpl(data)) {}
+    PrimaryKey(const CssmClient::DbAttributes &primaryKeyAttrs)
+	: RefPointer<PrimaryKeyImpl>(new PrimaryKeyImpl(primaryKeyAttrs)) {}
+
+	bool operator <(const PrimaryKey &other) const { return **this < *other; }
+};
+
+}; // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif // _H_PRIMARYKEY
diff --git a/Keychain/Refs.h b/Keychain/Refs.h
new file mode 100644
index 00000000..5e26f6aa
--- /dev/null
+++ b/Keychain/Refs.h
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+
+//
+// Refs.h
+//
+#ifndef _H_REFS
+#define _H_REFS
+
+#include <Security/handleobject.h>
+#include <set>
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+class ReferencedObject : public RefCount
+{
+public:
+	ReferencedObject() : mHandle(0) {}
+	virtual ~ReferencedObject() {}
+
+    void addedRef(CSSM_HANDLE handle) { mHandle = handle; }
+    void removedRef(CSSM_HANDLE handle) { mHandle = 0; }
+    CSSM_HANDLE handle() const { return mHandle; }
+
+    void killRef();
+
+private:
+    CSSM_HANDLE mHandle;
+};
+
+
+class RefObject : public HandleObject, public RefCount
+{
+public:
+    RefObject(ReferencedObject &object) : mObject(&object)
+	{
+		if (mObject)
+			mObject->addedRef(reinterpret_cast<CSSM_HANDLE>(HandleObject::handle()));
+	}
+
+	void ref() const { RefCount::ref(); }
+	unsigned int unref() const { return RefCount::unref(); }
+
+    RefPointer<ReferencedObject> mObject;
+};
+
+
+inline void ReferencedObject::killRef()
+{
+	delete &killHandle<RefObject>(mHandle);
+	mHandle = 0;
+}
+
+
+template <class _Object, class _ObjectImpl, class _Handle, OSStatus _ErrorCode>
+class Ref
+{
+public:
+    static _Handle handle(const _Object &object)
+	{
+		if (!object)
+			return 0;
+
+		_Handle handle = reinterpret_cast<_Handle>(object->handle()); // Return the existing handle if it exists
+		if (handle)
+		{
+			retain(handle);
+			return handle;
+		}
+	
+		RefObject *ref = new RefObject(*object);
+		ref->ref();
+		return reinterpret_cast<_Handle>(ref->HandleObject::handle());
+	}
+
+    static void retain(_Handle handle)
+    { findHandle<RefObject>(CSSM_HANDLE(handle), _ErrorCode).ref(); }
+
+    static void release(_Handle handle)
+    {
+		RefObject &ref = findHandle<RefObject>(CSSM_HANDLE(handle), _ErrorCode);
+        if (ref.unref() == 0)
+        {
+			if (ref.mObject)
+				ref.mObject->removedRef(CSSM_HANDLE(handle));
+
+			delete &killHandle<RefObject>(CSSM_HANDLE(handle), _ErrorCode);
+        }
+    }
+
+	static _Object required(_Handle handle)
+    {
+		RefObject &ref = findHandle<RefObject>(CSSM_HANDLE(handle), _ErrorCode);
+		if (!ref.mObject)
+			MacOSError::throwMe(_ErrorCode);
+                _ObjectImpl *impl = dynamic_cast<_ObjectImpl *>(&(*ref.mObject));
+                if (!impl)
+                        MacOSError::throwMe(_ErrorCode);
+		return _Object(impl);
+	}
+};
+
+}; // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif // _H_REFS
\ No newline at end of file
diff --git a/Keychain/Schema.h b/Keychain/Schema.h
new file mode 100644
index 00000000..cc5b055c
--- /dev/null
+++ b/Keychain/Schema.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+
+//
+// Schema.h
+//
+#ifndef _H_SCHEMA
+#define _H_SCHEMA
+
+//#include <Security/dlclient.h>
+#include <Security/SecKeychainAPI.h>
+
+namespace Security {
+
+namespace KeychainCore {
+
+namespace Schema {
+
+CSSM_DB_RECORDTYPE recordTypeFor(SecItemClass itemClass);
+SecItemClass itemClassFor(CSSM_DB_RECORDTYPE recordType);
+const CSSM_DB_ATTRIBUTE_INFO &attributeInfo(SecKeychainAttrType attrType);
+
+extern const CSSM_DB_ATTRIBUTE_INFO RelationID;
+extern const CSSM_DB_ATTRIBUTE_INFO RelationName;
+extern const CSSM_DB_ATTRIBUTE_INFO AttributeID;
+extern const CSSM_DB_ATTRIBUTE_INFO AttributeNameFormat;
+extern const CSSM_DB_ATTRIBUTE_INFO AttributeName;
+extern const CSSM_DB_ATTRIBUTE_INFO AttributeNameID;
+extern const CSSM_DB_ATTRIBUTE_INFO AttributeFormat;
+extern const CSSM_DB_ATTRIBUTE_INFO IndexType;
+
+extern const CSSM_DBINFO DBInfo;
+
+} // end namespace Schema
+
+} // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif // _H_SCHEMA
+
diff --git a/Keychain/Schema.m4 b/Keychain/Schema.m4
new file mode 100644
index 00000000..8dad5d48
--- /dev/null
+++ b/Keychain/Schema.m4
@@ -0,0 +1,307 @@
+divert(-1)
+changecom(/*, */)
+/*
+ * 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.
+ */
+
+define(`startClass',
+`define(`arrayIndex', 0)dnl
+define(`class', $1)dnl
+divert(0)dnl
+// $1 password attributes
+static const CSSM_DB_ATTRIBUTE_INFO $1Attributes[] =
+{
+divert(1)dnl
+// $1 password indices
+static const CSSM_DB_INDEX_INFO $1Indices[] =
+{')
+
+define(`endClass',
+`divert(0)dnl
+};
+
+divert(1)dnl
+`  // Unique (primary) index'
+undivert(3)
+`  // Secondary indices'
+undivert(4)dnl
+};
+
+divert(-1)')
+
+define(`attributeBody',
+`    {
+ifelse(index(`$1',`s'),-1,
+`        CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER,
+        {(char *)$3},',
+`        CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+        {$4},')
+        CSSM_DB_ATTRIBUTE_FORMAT_$7
+    }')
+
+define(`simpleAttribute',
+`const CSSM_DB_ATTRIBUTE_INFO $2 =
+attributeBody($*);
+')
+
+define(`attribute',
+`ifelse(index(`$1',`U'),-1,`',
+`divert(3)dnl
+  {
+    CSSM_DB_INDEX_UNIQUE,
+    CSSM_DB_INDEX_ON_ATTRIBUTE,
+attributeBody($*)
+  },
+')dnl
+ifelse(index(`$1',`I'),-1,`',
+`divert(4)dnl
+  {
+    CSSM_DB_INDEX_NONUNIQUE,
+    CSSM_DB_INDEX_ON_ATTRIBUTE,
+attributeBody($*)
+  },
+')dnl
+divert(2)dnl
+dnl const CSSM_DB_ATTRIBUTE_INFO &`k'class()$2 = class()Attributes[arrayIndex()];
+`#define k'class()$2 class()Attributes[arrayIndex()];
+divert(0)dnl
+attributeBody($*),dnl
+define(`arrayIndex', incr(arrayIndex))dnl
+')
+
+define(`attrInfo',
+`{
+        $1,
+        sizeof($2Attributes) / sizeof(CSSM_DB_ATTRIBUTE_INFO),
+        const_cast<CSSM_DB_ATTRIBUTE_INFO_PTR>($2Attributes)
+    }')
+
+define(`indexInfo',
+`{
+        $1,
+        sizeof($2Indices) / sizeof(CSSM_DB_INDEX_INFO),
+        const_cast<CSSM_DB_INDEX_INFO_PTR>($2Indices)
+    }')
+
+define(`parseInfo',
+`{
+        CSSM_DB_RECORDTYPE_APP_DEFINED_START,
+        {
+            {0,0,0,{0}},
+            {0,0},
+            0,
+            0
+        }
+    }')
+
+/* Start of actual output */
+divert(0)dnl
+/*
+ * Generated by m4 from Schema.m4 please do not edit this file.
+ */
+
+`#include <Security/Schema.h>'
+
+`#include <Security/SecKeychainAPIPriv.h>'
+`#include <Security/cssmapple.h>'
+`#include <Security/utilities.h>'
+
+namespace Security {
+
+namespace KeychainCore {
+
+namespace Schema {
+
+// Meta attributes
+simpleAttribute(`  s', RelationID, 0, "RelationID", 0, NULL, UINT32)
+simpleAttribute(`  s', RelationName, 1, "RelationName", 0, NULL, STRING)
+simpleAttribute(`  s', AttributeID, 1, "AttributeID", 0, NULL, UINT32)
+simpleAttribute(`  s', AttributeNameFormat, 2, "AttributeNameFormat", 0, NULL, UINT32)
+simpleAttribute(`  s', AttributeName, 3, "AttributeName", 0, NULL, STRING)
+simpleAttribute(`  s', AttributeNameID, 4, "AttributeNameID", 0, NULL, BLOB)
+simpleAttribute(`  s', AttributeFormat, 5, "AttributeFormat", 0, NULL, UINT32)
+simpleAttribute(`  s', IndexType, 3, "IndexType", 0, NULL, UINT32)
+
+divert(-1)
+startClass(Generic)
+attribute(`  i', CreationDate, kSecCreationDateItemAttr, "CreationDate", 0, NULL, TIME_DATE)
+attribute(`  i', ModDate, kSecModDateItemAttr, "ModDate", 0, NULL, TIME_DATE)
+attribute(`  i', Description, kSecDescriptionItemAttr, "Description", 0, NULL, BLOB)
+attribute(`  i', Comment, kSecCommentItemAttr, "Comment", 0, NULL, BLOB)
+attribute(`  i', Creator, kSecCreatorItemAttr, "Creator", 0, NULL, UINT32)
+attribute(`  i', Type, kSecTypeItemAttr, "Type", 0, NULL, UINT32)
+attribute(`  i', ScriptCode, kSecScriptCodeItemAttr, "ScriptCode", 0, NULL, SINT32)
+attribute(`  s', PrintName, kSecLabelItemAttr, "PrintName", 0, NULL, BLOB)
+attribute(`  s', Alias, kSecAliasItemAttr, "Alias", 0, NULL, BLOB)
+attribute(`  i', Invisible, kSecInvisibleItemAttr, "Invisible", 0, NULL, SINT32)
+attribute(`  i', Negative, kSecNegativeItemAttr, "Negative", 0, NULL, SINT32)
+attribute(`  i', CustomIcon, kSecCustomIconItemAttr, "CustomIcon", 0, NULL, SINT32)
+attribute(`  i', Protected, kSecProtectedDataItemAttr, "Protected", 0, NULL, BLOB)
+attribute(`UIi', Account, kSecAccountItemAttr, "Account", 0, NULL, BLOB)
+attribute(`UIi', Service, kSecServiceItemAttr, "Service", 0, NULL, BLOB)
+attribute(`  i', Generic, kSecGenericItemAttr, "Generic", 0, NULL, BLOB)
+endClass()
+
+startClass(Appleshare)
+attribute(`  i', CreationDate, kSecCreationDateItemAttr, "CreationDate", 0, NULL, TIME_DATE)
+attribute(`  i', ModDate, kSecModDateItemAttr, "ModDate", 0, NULL, TIME_DATE)
+attribute(`  i', Description, kSecDescriptionItemAttr, "Description", 0, NULL, BLOB)
+attribute(`  i', Comment, kSecCommentItemAttr, "Comment", 0, NULL, BLOB)
+attribute(`  i', Creator, kSecCreatorItemAttr, "Creator", 0, NULL, UINT32)
+attribute(`  i', Type, kSecTypeItemAttr, "Type", 0, NULL, UINT32)
+attribute(`  i', ScriptCode, kSecScriptCodeItemAttr, "ScriptCode", 0, NULL, SINT32)
+attribute(`  s', PrintName, kSecLabelItemAttr, "PrintName", 0, NULL, BLOB)
+attribute(`  s', Alias, kSecAliasItemAttr, "Alias", 0, NULL, BLOB)
+attribute(`  i', Invisible, kSecInvisibleItemAttr, "Invisible", 0, NULL, SINT32)
+attribute(`  i', Negative, kSecNegativeItemAttr, "Negative", 0, NULL, SINT32)
+attribute(`  i', CustomIcon, kSecCustomIconItemAttr, "CustomIcon", 0, NULL, SINT32)
+attribute(`  i', Protected, kSecProtectedDataItemAttr, "Protected", 0, NULL, BLOB)
+attribute(`UIi', Account, kSecAccountItemAttr, "Account", 0, NULL, BLOB)
+attribute(`UIi', Volume, kSecVolumeItemAttr, "Volume", 0, NULL, BLOB)
+attribute(`  i', Server, kSecServerItemAttr, "Server", 0, NULL, BLOB)
+attribute(`  i', Protocol, kSecProtocolItemAttr, "Protocol", 0, NULL, UINT32)
+attribute(`UIi', Address, kSecAddressItemAttr, "Address", 0, NULL, BLOB)
+attribute(`UIi', Signature, kSecSignatureItemAttr, "Signature", 0, NULL, BLOB)
+endClass()
+
+startClass(Internet)
+attribute(`  i', CreationDate, kSecCreationDateItemAttr, "CreationDate", 0, NULL, TIME_DATE)
+attribute(`  i', ModDate, kSecModDateItemAttr, "ModDate", 0, NULL, TIME_DATE)
+attribute(`  i', Description, kSecDescriptionItemAttr, "Description", 0, NULL, BLOB)
+attribute(`  i', Comment, kSecCommentItemAttr, "Comment", 0, NULL, BLOB)
+attribute(`  i', Creator, kSecCreatorItemAttr, "Creator", 0, NULL, UINT32)
+attribute(`  i', Type, kSecTypeItemAttr, "Type", 0, NULL, UINT32)
+attribute(`  i', ScriptCode, kSecScriptCodeItemAttr, "ScriptCode", 0, NULL, SINT32)
+attribute(`  s', PrintName, kSecLabelItemAttr, "PrintName", 0, NULL, BLOB)
+attribute(`  s', Alias, kSecAliasItemAttr, "Alias", 0, NULL, BLOB)
+attribute(`  i', Invisible, kSecInvisibleItemAttr, "Invisible", 0, NULL, SINT32)
+attribute(`  i', Negative, kSecNegativeItemAttr, "Negative", 0, NULL, SINT32)
+attribute(`  i', CustomIcon, kSecCustomIconItemAttr, "CustomIcon", 0, NULL, SINT32)
+attribute(`  i', Protected, kSecProtectedDataItemAttr, "Protected", 0, NULL, BLOB)
+attribute(`UIi', Account, kSecAccountItemAttr, "Account", 0, NULL, BLOB)
+attribute(`UIi', SecurityDomain, kSecSecurityDomainItemAttr, "SecurityDomain", 0, NULL, BLOB)
+attribute(`UIi', Server, kSecServerItemAttr, "Server", 0, NULL, BLOB)
+attribute(`UIi', Protocol, kSecProtocolItemAttr, "Protocol", 0, NULL, UINT32)
+attribute(`UIi', AuthType, kSecAuthTypeItemAttr, "AuthType", 0, NULL, BLOB)
+attribute(`UIi', Port, kSecPortItemAttr, "Port", 0, NULL, UINT32)
+attribute(`UIi', Path, kSecPathItemAttr, "Path", 0, NULL, BLOB)
+endClass()
+
+divert(3)
+static const CSSM_DB_RECORD_ATTRIBUTE_INFO Attributes[] =
+{
+    attrInfo(CSSM_DL_DB_RECORD_GENERIC_PASSWORD, Generic),
+    attrInfo(CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD, Appleshare),
+    attrInfo(CSSM_DL_DB_RECORD_INTERNET_PASSWORD, Internet)
+};
+
+static const CSSM_DB_RECORD_INDEX_INFO Indices[] =
+{
+    indexInfo(CSSM_DL_DB_RECORD_GENERIC_PASSWORD, Generic),
+    indexInfo(CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD, Appleshare),
+    indexInfo(CSSM_DL_DB_RECORD_INTERNET_PASSWORD, Internet)
+};
+
+static const CSSM_DB_PARSING_MODULE_INFO ParseInfos[] =
+{
+    parseInfo(),
+    parseInfo(),
+    parseInfo()
+};
+
+//
+// Public stuff
+//
+const CSSM_DBINFO DBInfo =
+{
+    sizeof(Attributes) / sizeof(CSSM_DB_RECORD_ATTRIBUTE_INFO),
+    const_cast<CSSM_DB_PARSING_MODULE_INFO_PTR>(ParseInfos),
+    const_cast<CSSM_DB_RECORD_ATTRIBUTE_INFO_PTR>(Attributes),
+    const_cast<CSSM_DB_RECORD_INDEX_INFO_PTR>(Indices),
+    CSSM_TRUE,
+    NULL,
+    NULL
+};
+
+//
+// Schema methods
+//
+CSSM_DB_RECORDTYPE
+recordTypeFor(SecItemClass itemClass)
+{
+    switch (itemClass)
+    {
+    case kSecGenericPasswordItemClass: return CSSM_DL_DB_RECORD_GENERIC_PASSWORD;
+    case kSecInternetPasswordItemClass: return CSSM_DL_DB_RECORD_INTERNET_PASSWORD;
+    case kSecAppleSharePasswordItemClass: return CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD;
+    default: MacOSError::throwMe(errSecNoSuchClass);
+    }
+}
+
+SecItemClass
+itemClassFor(CSSM_DB_RECORDTYPE recordType)
+{
+    switch (recordType)
+    {
+    case CSSM_DL_DB_RECORD_GENERIC_PASSWORD: return kSecGenericPasswordItemClass;
+    case CSSM_DL_DB_RECORD_INTERNET_PASSWORD: return kSecInternetPasswordItemClass;
+    case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD: return kSecAppleSharePasswordItemClass;
+    default: return 0; // MacOSError::throwMe(errSecNoSuchClass);
+    }
+}
+
+const CSSM_DB_ATTRIBUTE_INFO &
+attributeInfo(SecKeychainAttrType attrType)
+{
+    switch (attrType) 
+    {
+    case kSecCreationDateItemAttr: return kGenericCreationDate;
+    case kSecModDateItemAttr: return kGenericModDate;
+    case kSecDescriptionItemAttr: return kGenericDescription;
+    case kSecCommentItemAttr: return kGenericComment;
+    case kSecCreatorItemAttr: return kGenericCreator;
+    case kSecTypeItemAttr: return kGenericType;
+    case kSecScriptCodeItemAttr: return kGenericScriptCode;
+    case kSecLabelItemAttr: return kGenericPrintName;
+    case kSecAliasItemAttr: return kGenericAlias;
+    case kSecInvisibleItemAttr: return kGenericInvisible;
+    case kSecNegativeItemAttr: return kGenericNegative;
+    case kSecCustomIconItemAttr: return kGenericCustomIcon;
+    /* Unique Generic password attributes */
+    case kSecAccountItemAttr: return kGenericAccount;
+    case kSecServiceItemAttr: return kGenericService;
+    case kSecGenericItemAttr: return kGenericGeneric;
+    /* Unique Appleshare password attributes */
+    case kSecVolumeItemAttr: return kAppleshareVolume;
+    case kSecAddressItemAttr: return kAppleshareAddress;
+    case kSecSignatureItemAttr: return kAppleshareSignature;
+    /* Unique AppleShare and Internet attributes */
+    case kSecServerItemAttr: return kAppleshareServer;
+    case kSecProtocolItemAttr: return kAppleshareProtocol;
+    /* Unique Internet password attributes */
+    case kSecSecurityDomainItemAttr: return kInternetSecurityDomain;
+    case kSecAuthTypeItemAttr: return kInternetAuthType;
+    case kSecPortItemAttr: return kInternetPort;
+    case kSecPathItemAttr: return kInternetPath;
+    default: MacOSError::throwMe(errSecNoSuchAttr); // @@@ Not really but whatever.
+    }
+}
+
+} // end namespace Schema
+
+} // end namespace KeychainCore
+
+} // end namespace Security
diff --git a/Keychain/SecKeychainAPI.cpp b/Keychain/SecKeychainAPI.cpp
new file mode 100644
index 00000000..1c9c123c
--- /dev/null
+++ b/Keychain/SecKeychainAPI.cpp
@@ -0,0 +1,736 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  SecKeychainAPI.cpp
+ *  SecurityCore
+ *
+ *    Copyright:  (c) 2000 by Apple Computer, Inc., all rights reserved
+ *
+ */
+
+
+#include <Security/SecKeychainAPI.h>
+#include "SecKeychainAPIPriv.h"
+#include "Keychains.h"
+#include "Globals.h"
+#include "KCUtilities.h"
+#include "KCEventNotifier.h"
+#include "KCCursor.h"
+#include "CCallbackMgr.h"
+#include "KCExceptions.h"
+#include "Schema.h"
+#include <Security/globalizer.h>
+
+using namespace Security;
+
+using namespace KeychainCore;
+
+//
+// API boilerplate macros. These provide a frame for C++ code that is impermeable to exceptions.
+// Usage:
+//	BEGIN_API
+//		... your C++ code here ...
+//  END_API		// returns CSSM_RETURN on exception
+//	END_API0	// returns nothing (void) on exception
+//	END_API1(bad) // return (bad) on exception
+//
+#define BEGIN_SECAPI \
+	try { \
+		StLock<Mutex> _(globals().apiLock);
+#define END_SECAPI \
+	} \
+	catch (const MacOSError &err) { return err.osStatus(); } \
+	catch (const CssmCommonError &err) { return GetKeychainErrFromCSSMErr(err.cssmError())/*err.cssmError(CSSM_CSSM_BASE_ERROR)*/; } \
+	catch (::std::bad_alloc) { return memFullErr; } \
+	catch (...) { return internalComponentErr; } \
+    return noErr;
+#define END_SECAPI0		} catch (...) { return; }
+#define END_SECAPI1(bad)	} catch (...) { return bad; }
+
+
+OSStatus SecKeychainGetVersion(UInt32 *returnVers)
+{
+    if (!returnVers) return noErr;
+
+	*returnVers=0x02028000;
+	return noErr;
+}
+
+
+OSStatus SecKeychainOpen(const char *pathName, SecKeychainRef *keychainRef)
+{
+    BEGIN_SECAPI
+		RequiredParam(keychainRef)=KeychainRef::handle(globals().storageManager.make(pathName));
+	END_SECAPI
+}
+
+OSStatus SecKeychainCreateNew(const char *pathName, SecKeychainRef *keychainRef, UInt32 passwordLength, const void *password, Boolean promptUser)
+{
+    BEGIN_SECAPI
+
+		KCThrowParamErrIf_(!pathName);
+
+		Keychain keychain = globals().storageManager.make(pathName);
+		
+		if(promptUser)
+		{
+			keychain->create();
+		}
+		else
+		{
+            KCThrowParamErrIf_(!password);
+            
+			keychain->create(passwordLength, password);
+		}
+        RequiredParam(keychainRef)=KeychainRef::handle(keychain);
+
+	END_SECAPI
+}
+
+OSStatus SecKeychainDelete(SecKeychainRef keychainRef)
+{
+    BEGIN_SECAPI
+	
+		Keychain keychain = Keychain::optional(keychainRef);
+		keychain->database()->deleteDb();
+		
+        list<SecKeychainRef> SecKeychainRefToRemove;
+		SecKeychainRefToRemove.push_back(keychainRef);
+		KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager;
+		smgr.remove(SecKeychainRefToRemove);
+		return noErr;
+
+	END_SECAPI
+
+
+}
+OSStatus SecKeychainSetSettings(SecKeychainRef keychainRef, const SecKeychainSettings *newSettings)
+{
+    BEGIN_SECAPI
+        Keychain keychain = Keychain::optional(keychainRef);
+		if(newSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1)
+		{
+			UInt32 lockInterval=newSettings->lockInterval;
+			bool lockOnSleep=newSettings->lockOnSleep;
+
+			keychain->setSettings(lockInterval, lockOnSleep);
+        }
+	END_SECAPI
+}
+
+
+OSStatus SecKeychainCopySettings(SecKeychainRef keychainRef, SecKeychainSettings *outSettings)
+{
+    BEGIN_SECAPI
+        Keychain keychain = Keychain::optional(keychainRef);
+		if(outSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1)
+		{
+			UInt32 lockInterval;
+			bool lockOnSleep;
+			
+			keychain->getSettings(lockInterval, lockOnSleep);
+			outSettings->lockInterval=lockInterval;
+			outSettings->lockOnSleep=lockOnSleep;
+        }
+	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainUnlock(SecKeychainRef keychainRef, UInt32 passwordLength, void *password, Boolean usePassword)
+{
+    BEGIN_SECAPI
+        Keychain keychain = Keychain::optional(keychainRef);
+
+		if(usePassword)
+			keychain->unlock(CssmData(password,passwordLength));
+		else
+			keychain->unlock();
+	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainLock(SecKeychainRef	keychainRef)
+{
+    BEGIN_SECAPI
+        Keychain keychain = Keychain::optional(keychainRef);
+		keychain->lock();
+	END_SECAPI
+}
+
+
+OSStatus SecKeychainLockAll()
+{
+    BEGIN_SECAPI
+		globals().storageManager.lockAll();
+	END_SECAPI
+}
+
+
+OSStatus SecKeychainRelease(SecKeychainRef keychainRef)
+{
+    BEGIN_SECAPI
+		KeychainRef::release(keychainRef);
+	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainCopyDefault(SecKeychainRef *keychainRef)
+{
+    BEGIN_SECAPI
+        RequiredParam(keychainRef)=KeychainRef::handle(globals().defaultKeychain.keychain());
+	END_SECAPI
+}
+
+
+OSStatus SecKeychainSetDefault(SecKeychainRef keychainRef)
+{
+    BEGIN_SECAPI
+		globals().defaultKeychain.keychain(Keychain::optional(keychainRef));
+ 	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainGetStatus(SecKeychainRef keychainRef, SecKeychainStatus *keychainStatus)
+{
+    BEGIN_SECAPI
+		RequiredParam(keychainStatus) = (SecKeychainStatus)Keychain::optional(keychainRef)->status();
+	END_SECAPI
+}
+  
+
+OSStatus SecKeychainGetPath(SecKeychainRef keychainRef, UInt32 * ioPathLength, char *pathName)
+{
+    BEGIN_SECAPI
+		RequiredParam(pathName);
+		const char *name = Keychain::optional(keychainRef)->name();
+		UInt32 nameLen = strlen(name);
+		memcpy(pathName, name, *ioPathLength);
+		if(nameLen < *ioPathLength)  // if the size is smaller then the buffer
+			*ioPathLength=nameLen;   // set the length.  otherwise the size is clipped because
+									 // the buffer is too small.
+		
+	END_SECAPI
+}
+
+
+UInt16 SecKeychainListGetCount(void)
+{
+    BEGIN_SECAPI
+		return globals().storageManager.size();
+	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainListCopyKeychainAtIndex(UInt16 index, SecKeychainRef *keychainRef)
+{
+    BEGIN_SECAPI
+		KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager;
+		RequiredParam(keychainRef)=KeychainRef::handle(smgr[index]);
+	END_SECAPI
+}
+ 
+OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void *data, SecKeychainRef keychainRef, SecKeychainItemRef *itemRef)
+{
+    BEGIN_SECAPI
+		KCThrowParamErrIf_(length!=0 && data==NULL);
+        Item item(itemClass, attrList, length, data);
+        Keychain::optional(keychainRef)->add(item);
+        if (itemRef)
+        	*itemRef = ItemRef::handle(item);
+	END_SECAPI
+}
+ 
+OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
+{
+    BEGIN_SECAPI
+		Item item = ItemRef::required(itemRef);
+		item->modifyContent(attrList, length, data);
+	END_SECAPI
+}
+ 
+ 
+OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData)
+{
+	BEGIN_SECAPI
+		Item item = ItemRef::required(itemRef);
+		item->getContent(itemClass, attrList, length, outData);
+	END_SECAPI
+}
+
+OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data)
+{
+	BEGIN_SECAPI
+		ItemImpl::freeContent(attrList, data);
+	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef, UInt32 itemID, SecKeychainAttributeInfo **info)
+{
+	BEGIN_SECAPI
+		Keychain keychain = Keychain::optional(keychainRef);
+		keychain->getAttributeInfoForItemID(itemID, info);
+	END_SECAPI
+}
+
+OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info)
+{
+	BEGIN_SECAPI
+		KeychainImpl::freeAttributeInfo(info);
+	END_SECAPI
+}
+
+OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
+{
+    BEGIN_SECAPI
+		Item item = ItemRef::required(itemRef);
+		item->modifyAttributesAndData(attrList, length, data);
+	END_SECAPI
+}
+
+OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData)
+{
+	BEGIN_SECAPI
+		Item item = ItemRef::required(itemRef);
+		item->getAttributesAndData(info, itemClass, attrList, length, outData);
+	END_SECAPI
+}
+
+OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attrList, void *data)
+{
+	BEGIN_SECAPI
+		ItemImpl::freeAttributesAndData(attrList, data);
+	END_SECAPI
+}
+
+OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef)
+{
+    BEGIN_SECAPI
+		Item item = ItemRef::required( itemRef );
+		Keychain keychain = item->keychain();
+		KCThrowIf_( !keychain, errSecInvalidItemRef );
+		
+        keychain->deleteItem( item ); // item must be persistant.
+	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef* keychainRef)
+{
+    BEGIN_SECAPI
+		Required(keychainRef) = KeychainRef::handle(ItemRef::required(itemRef)->keychain());
+	END_SECAPI
+}
+
+
+OSStatus SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainItemRef *itemCopy, SecKeychainRef destKeychainRef)
+{
+    BEGIN_SECAPI
+		Item copy = ItemRef::required(itemRef)->copyTo(Keychain::optional(destKeychainRef));
+		if (itemCopy)
+			*itemCopy = ItemRef::handle(copy);
+	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainItemRelease(SecKeychainItemRef itemRef)
+{
+    BEGIN_SECAPI
+ 		ItemRef::release(itemRef);
+	END_SECAPI
+}
+
+OSStatus SecKeychainSearchCreateFromAttributes(SecKeychainRef keychainRef, SecItemClass itemClass, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef)
+{
+    BEGIN_SECAPI
+
+		Required(searchRef); // Make sure that searchRef is an invalid SearchRef
+
+		KCCursor cursor;
+		if (keychainRef)
+			cursor = Keychain::optional(keychainRef)->createCursor(itemClass, attrList);
+		else
+			cursor = globals().storageManager.createCursor(itemClass, attrList);
+
+        *searchRef = KCCursorRef::handle(cursor);
+
+	END_SECAPI
+}
+ 
+
+OSStatus SecKeychainCopySearchNextItem(SecKeychainSearchRef searchRef, SecKeychainItemRef *itemRef)
+{
+    BEGIN_SECAPI
+        RequiredParam(itemRef);
+        Item item;
+        if (!KCCursorRef::required(searchRef)->next(item))
+            return errSecItemNotFound;
+
+        *itemRef=ItemRef::handle(item);
+	END_SECAPI
+}
+ 
+OSStatus SecKeychainSearchRelease(SecKeychainSearchRef searchRef)
+{
+    BEGIN_SECAPI
+		KCCursorRef::release(searchRef);
+	END_SECAPI
+}
+
+
+OSStatus SecKeychainListRemoveKeychain(SecKeychainRef *keychainRef)
+{
+    BEGIN_SECAPI
+        list<SecKeychainRef> SecKeychainRefToRemove;
+		SecKeychainRefToRemove.push_back(RequiredParam(keychainRef));
+		StorageManager &smgr = globals().storageManager;
+		smgr.remove(SecKeychainRefToRemove);
+		return noErr;
+	END_SECAPI
+}
+ 
+
+pascal OSStatus SecKeychainAddCallback(SecKeychainCallbackProcPtr callbackFunction, SecKeychainEventMask eventMask, void* userContext)
+{
+    BEGIN_SECAPI
+		RequiredParam(callbackFunction);
+		CCallbackMgr::AddCallback(callbackFunction,eventMask,userContext);
+	END_SECAPI
+}	
+
+OSStatus SecKeychainRemoveCallback(SecKeychainCallbackProcPtr callbackFunction)
+{
+    BEGIN_SECAPI
+		RequiredParam(callbackFunction);
+        CCallbackMgr::RemoveCallback(callbackFunction);
+	END_SECAPI
+}	
+
+
+// --- Private API
+
+OSStatus SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword,  UInt32 newPasswordLength, const void *newPassword)
+{
+    BEGIN_SECAPI
+	globals().storageManager.changeLoginPassword(oldPasswordLength, oldPassword,  newPasswordLength, newPassword);
+    END_SECAPI
+}
+
+OSStatus SecKeychainCopyLogin(SecKeychainRef *keychainRef)
+{
+    BEGIN_SECAPI
+	// NOTE: operates on default Keychain!  It shouldn't... we want to 
+	//		 have code that operates of a login keychain.
+        RequiredParam(keychainRef)=KeychainRef::handle(globals().defaultKeychain.keychain());
+    END_SECAPI
+}
+
+
+OSStatus SecKeychainAddInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, char *serverName, 
+										UInt32 securityDomainLength, char *securityDomain, UInt32 accountNameLength, char *accountName, 
+										UInt32 pathLength, char *path, UInt16 port, OSType protocol, OSType authType,
+										UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef)
+{
+    BEGIN_SECAPI
+		KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL);
+		// @@@ Get real itemClass
+        Item item(kSecInternetPasswordItemClass, 'aapl', passwordLength, passwordData);
+		
+		if (serverName && serverNameLength)
+			item->setAttribute(Schema::attributeInfo(kSecServerItemAttr),
+				CssmData(serverName, serverNameLength));
+			
+		if (accountName && accountNameLength)
+		{
+			CssmData account(accountName, accountNameLength);
+			item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
+			 // @@@ We should probably leave setting of label up to lower level code.
+			item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), account);
+		}
+
+		if (securityDomain && securityDomainLength)
+			item->setAttribute(Schema::attributeInfo(kSecSecurityDomainItemAttr),
+				CssmData(securityDomain, securityDomainLength));
+			
+		item->setAttribute(Schema::attributeInfo(kSecPortItemAttr), UInt32(port));
+		item->setAttribute(Schema::attributeInfo(kSecProtocolItemAttr), protocol);
+		item->setAttribute(Schema::attributeInfo(kSecAuthTypeItemAttr), authType);
+			
+		if (path && pathLength)
+			item->setAttribute(Schema::attributeInfo(kSecPathItemAttr),
+				CssmData(path, pathLength));
+
+		Keychain::optional(keychainRef)->add(item);
+        if (itemRef)
+        	*itemRef = ItemRef::handle(item);
+
+    END_SECAPI
+}
+
+OSStatus SecKeychainFindInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, char *serverName, 
+										UInt32 securityDomainLength, char *securityDomain, UInt32 accountNameLength, char *accountName,
+										UInt32 pathLength, char *path, UInt16 port, OSType protocol, OSType authType,
+										UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef)
+												
+{
+     BEGIN_SECAPI
+
+
+		UInt32 attrCount = 0;
+					
+		// The number of attributes to search on depends on what was passed in
+		if ( serverName && serverNameLength)
+			attrCount++;
+			
+		if ( securityDomain && securityDomainLength )
+			attrCount++;
+			
+		if ( accountName && accountNameLength)
+			attrCount++;
+			
+		if ( port )
+			attrCount++;
+			
+		if ( protocol )
+			attrCount++;
+			
+		if ( authType )
+			attrCount++;
+			
+		if ( path && pathLength )
+			attrCount++;
+			
+		auto_array<SecKeychainAttribute> attrs(attrCount);
+		attrCount = 0;
+
+		if ( serverName && serverNameLength )
+		{
+			attrs[attrCount].tag = kSecServerItemAttr;
+			attrs[attrCount].length = serverNameLength;
+			attrs[attrCount].data = serverName;
+			attrCount++;
+		}
+		if ( securityDomain && securityDomainLength )
+		{
+			attrs[attrCount].tag = kSecSecurityDomainItemAttr;
+			attrs[attrCount].length = securityDomainLength;
+			attrs[attrCount].data = securityDomain;
+			attrCount++;
+		}
+		if ( accountName && accountNameLength )
+		{
+			attrs[attrCount].tag = kSecAccountItemAttr;
+			attrs[attrCount].length = accountNameLength;
+			attrs[attrCount].data = accountName;
+			attrCount++;
+		}
+		
+		if ( port )
+		{
+			attrs[attrCount].tag = kSecPortItemAttr;
+			attrs[attrCount].length = sizeof( port );
+			attrs[attrCount].data = &port;
+			attrCount++;
+		}
+		if ( protocol )
+		{
+			attrs[attrCount].tag = kSecProtocolItemAttr;
+			attrs[attrCount].length = sizeof( protocol );
+			attrs[attrCount].data = &protocol;
+			attrCount++;
+		}
+		if ( authType )
+		{
+			attrs[attrCount].tag = kSecAuthTypeItemAttr;
+			attrs[attrCount].length = sizeof( authType );
+			attrs[attrCount].data = &authType;
+			attrCount++;
+		}
+			
+		if ( path  && pathLength )
+		{
+			attrs[attrCount].tag = kSecPathItemAttr;
+			attrs[attrCount].length = pathLength;
+			attrs[attrCount].data = path;
+			attrCount++;
+		}
+
+        SecKeychainAttributeList attrList;
+		attrList.count = attrCount;
+		attrList.attr = attrs.get();
+		
+		Item item;
+	
+		KCCursor cursor;
+		if (keychainRef)
+			cursor = Keychain::optional(keychainRef)->createCursor(kSecInternetPasswordItemClass, &attrList);
+		else
+			cursor = globals().storageManager.createCursor(kSecInternetPasswordItemClass, &attrList);
+
+		if (!cursor->next(item))
+			return errSecItemNotFound;
+
+			
+		// Get its data (only if necessary)
+		if ( passwordData || passwordLength )
+		{
+			CssmDataContainer outData;
+			item->getData(outData);
+			*passwordLength=outData.length();
+			outData.Length=NULL;
+			*passwordData=outData.data();
+			outData.Data=NULL;
+		}
+		
+		if (itemRef)
+			*itemRef=ItemRef::handle(item);
+ 
+            
+    END_SECAPI
+
+	
+
+}
+
+OSStatus SecKeychainAddGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, char *serviceName,
+									   UInt32 accountNameLength, char *accountName, 
+									   UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef)
+										
+{
+   BEGIN_SECAPI
+ 
+		KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL);
+		// @@@ Get real itemClass
+        Item item(kSecGenericPasswordItemClass, 'aapl', passwordLength, passwordData);
+		
+		if (serviceName && serviceNameLength)
+			item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), CssmData(serviceName, serviceNameLength));
+			
+		if (accountName && accountNameLength)
+		{
+			CssmData account(accountName, accountNameLength);
+			item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
+			 // @@@ We should probably leave setting of label up to lower level code.
+			item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), account);
+		}
+
+        Keychain::optional(keychainRef)->add(item);
+        if (itemRef)
+        	*itemRef = ItemRef::handle(item);
+
+    END_SECAPI
+}
+
+OSStatus SecKeychainFindGenericPassword(SecKeychainRef keychainRef,  UInt32 serviceNameLength, char *serviceName,
+										UInt32 accountNameLength, char *accountName,
+										UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef)
+																			   
+{
+    BEGIN_SECAPI
+		UInt32 attrCount = 0;
+					
+		// The number of attributes to search on depends on what was passed in
+		if (serviceName && serviceNameLength)
+			attrCount++;
+			
+		if (accountName && accountNameLength)
+			attrCount++;
+
+		auto_array<SecKeychainAttribute> attrs(attrCount);
+		attrCount = 0;
+
+		if (serviceName && serviceNameLength)
+		{
+			attrs[attrCount].tag = kSecServiceItemAttr;
+			attrs[attrCount].length = serviceNameLength;
+			attrs[attrCount].data = serviceName;
+			attrCount++;
+		}
+		if (accountName && accountNameLength)
+		{
+			attrs[attrCount].tag = kSecAccountItemAttr;
+			attrs[attrCount].length = accountNameLength;
+			attrs[attrCount].data = accountName;
+			attrCount++;
+		}
+		
+        SecKeychainAttributeList attrList;
+		attrList.count = attrCount;
+		attrList.attr = attrs.get();
+
+ 		Item item;
+	
+		KCCursor cursor;
+		if (keychainRef)
+			cursor = Keychain::optional(keychainRef)->createCursor(kSecGenericPasswordItemClass, &attrList);
+		else
+			cursor = globals().storageManager.createCursor(kSecGenericPasswordItemClass, &attrList);
+
+  		if (!cursor->next(item))
+			return errSecItemNotFound;
+
+			
+		// Get its data (only if necessary)
+		if ( passwordData || passwordLength )
+		{
+			CssmDataContainer outData;
+			item->getData(outData);
+			*passwordLength=outData.length();
+			outData.Length=NULL;
+			*passwordData=outData.data();
+			outData.Data=NULL;
+		}
+		
+		if (itemRef)
+			*itemRef=ItemRef::handle(item);
+ 
+		           
+    END_SECAPI
+}
+
+OSStatus SecKeychainLogin(UInt32 nameLength, void* name, UInt32 passwordLength, void* password)
+{
+    BEGIN_SECAPI
+	globals().storageManager.login(nameLength, name,  passwordLength, password);
+    END_SECAPI
+}
+
+OSStatus SecKeychainLogout()
+{
+    BEGIN_SECAPI
+	globals().storageManager.logout();
+    END_SECAPI
+}
+
+OSStatus SecKeychainSetUserInteractionAllowed(Boolean state) 
+{
+	BEGIN_SECAPI
+	globals().setUserInteractionAllowed(state);
+    END_SECAPI
+	
+}
+
+OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state) 
+{
+	BEGIN_SECAPI
+	Required(state)=globals().getUserInteractionAllowed();
+    END_SECAPI
+	
+}
+
diff --git a/Keychain/SecKeychainAPI.h b/Keychain/SecKeychainAPI.h
new file mode 100644
index 00000000..a71d0738
--- /dev/null
+++ b/Keychain/SecKeychainAPI.h
@@ -0,0 +1,883 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  SecKeychainAPI.h
+ *  SecurityCore
+ *
+ *    Copyright:  (c) 2000 by Apple Computer, Inc., all rights reserved
+ *
+ */
+
+/*!
+	@header SecKeychainAPI The Security Core API contains all the APIs need to create a Keychain management application, minus the HI.
+	 
+	NOTE: Any function with Create or Copy in the name returns an object that must be released.
+*/
+
+#if !defined(__SECKEYCHAINAPI__)
+#define __SECKEYCHAINAPI__ 1
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <Security/cssmapple.h>
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifndef __SEC_TYPES__
+#define __SEC_TYPES__
+
+/*!
+@typedef SecKeychainRef
+Opaque Structure to a Keychain reference.
+*/
+typedef struct OpaqueSecKeychainRef				*SecKeychainRef;
+/*!
+@typedef SecKeychainItemRef
+Opaque Structure to a Keychain item reference.
+*/
+typedef struct OpaqueSecKeychainItemRef			*SecKeychainItemRef;
+/*!
+@typedef SecKeychainSearchRef
+Opaque Structure to a Keychain search reference.
+*/
+typedef struct OpaqueSecKeychainSearchRef		*SecKeychainSearchRef;
+
+typedef OSType	SecKeychainAttrType;
+/*!
+@struct SecKeychainAttribute
+Security Item attributes. 
+*/
+struct SecKeychainAttribute {
+    SecKeychainAttrType          tag;                            /* 4-byte attribute tag */
+    UInt32                       length;                         /* Length of attribute data */
+    void *                       data;                           /* Pointer to attribute data */
+};
+typedef struct SecKeychainAttribute      SecKeychainAttribute;
+typedef SecKeychainAttribute *           SecKeychainAttributePtr;
+
+/*!
+@struct SecKeychainAttributeList
+Security attribute list. 
+*/
+struct SecKeychainAttributeList {
+    UInt32                       		 count;                          /* How many attributes in the array */
+    SecKeychainAttribute *               attr;                           /* Pointer to first attribute in array */
+};
+typedef struct SecKeychainAttributeList  SecKeychainAttributeList;
+
+typedef UInt32 SecKeychainStatus;
+
+#endif
+
+/*!
+@enum TableIDs
+*/
+enum {
+    kSecGenericPasswordItemTableID = CSSM_DL_DB_RECORD_GENERIC_PASSWORD,                  /* Generic password */
+    kSecInternetPasswordItemTableID = CSSM_DL_DB_RECORD_INTERNET_PASSWORD,                /* Internet password */
+    kSecAppleSharePasswordItemTableID = CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD             /* AppleShare password */
+};
+
+/*!
+@struct SecKeychainAttributeInfo
+Security attribute tag list. 
+*/
+struct SecKeychainAttributeInfo {
+    UInt32                       		 count;                   		 /* How many items in the array */
+    UInt32 *            				 tag;                            /* Pointer to first attribute tag in array */
+	UInt32 *            				 format;                         /* Pointer to first attribute format in array */
+};
+typedef struct SecKeychainAttributeInfo  SecKeychainAttributeInfo;
+
+
+
+/*!
+@typedef SecTypeRef
+Opaque pointer to one a pointer to a security referece.
+Such as SecKeychainSearchRef, SecKeychainItemRef and SecKeychainItemRef.
+*/
+typedef void									*SecTypeRef;
+
+/*!
+@enum KeychainErrors 
+*/
+enum {
+    errSecNotAvailable           = -25291,
+    errSecReadOnly               = -25292,
+    errSecAuthFailed             = -25293,
+    errSecNoSuchKeychain         = -25294,
+    errSecInvalidKeychain        = -25295,
+    errSecDuplicateKeychain      = -25296,
+    errSecDuplicateCallback      = -25297,
+    errSecInvalidCallback        = -25298,
+    errSecDuplicateItem          = -25299,
+    errSecItemNotFound           = -25300,
+    errSecBufferTooSmall         = -25301,
+    errSecDataTooLarge           = -25302,
+    errSecNoSuchAttr             = -25303,
+    errSecInvalidItemRef         = -25304,
+    errSecInvalidSearchRef       = -25305,
+    errSecNoSuchClass            = -25306,
+    errSecNoDefaultKeychain      = -25307,
+    errSecInteractionNotAllowed  = -25308,
+    errSecReadOnlyAttr           = -25309,
+    errSecWrongSecVersion        = -25310,
+    errSecKeySizeNotAllowed      = -25311,
+    errSecNoStorageModule        = -25312,
+    errSecNoCertificateModule    = -25313,
+    errSecNoPolicyModule         = -25314,
+    errSecInteractionRequired    = -25315,
+    errSecDataNotAvailable       = -25316,
+    errSecDataNotModifiable      = -25317,
+    errSecCreateChainFailed      = -25318
+};
+
+/*!
+@enum KeychainEvents
+Events relating to the state of the default Keychain.
+*/
+typedef UInt16 SecKeychainEvent;
+enum {
+    kSecLockEvent                = 1,                            /* a keychain was locked */
+    kSecUnlockEvent              = 2,                            /* a keychain was unlocked */
+    kSecAddEvent                 = 3,                            /* an item was added to a keychain */
+    kSecDeleteEvent              = 4,                            /* an item was deleted from a keychain */
+    kSecUpdateEvent              = 5,                            /* an item was updated */
+    kSecPasswordChangedEvent     = 6,                            /* the keychain password was changed */
+    kSecSystemEvent              = 8,                            /* the keychain client can process events */
+    kSecDefaultChangedEvent      = 9,                            /* the default keychain was changed */
+    kSecDataAccessEvent          = 10,                           /* a process has accessed a keychain item's data */
+    kSecKeychainListChangedEvent = 11                            /* the list of keychains has changed */
+};
+
+
+typedef UInt16 SecKeychainEventMask;
+enum {
+    kSecLockEventMask            = 1 << kSecLockEvent,
+    kSecUnlockEventMask          = 1 << kSecUnlockEvent,
+    kSecAddEventMask             = 1 << kSecAddEvent,
+    kSecDeleteEventMask          = 1 << kSecDeleteEvent,
+    kSecUpdateEventMask          = 1 << kSecUpdateEvent,
+    kSecPasswordChangedEventMask = 1 << kSecPasswordChangedEvent,
+    kSecSystemEventEventMask     = 1 << kSecSystemEvent,
+    kSecDefaultChangedEventMask  = 1 << kSecDefaultChangedEvent,
+    kSecDataAccessEventMask      = 1 << kSecDataAccessEvent,
+    kSecEveryEventMask           = 0xFFFF                        /* all of the above*/
+};
+
+typedef UInt8                    SecAFPServerSignature[16];
+typedef UInt8                    SecPublicKeyHash[20];
+
+/*!
+@enum KeychainStatus
+The current status of the Keychain.
+*/
+enum {
+    kSecUnlockStateStatus        = 1,
+    kSecRdPermStatus             = 2,
+    kSecWrPermStatus             = 4
+};
+
+typedef FourCharCode             SecItemClass;
+/*!
+@enum KeychainItemClasses
+Keychain item classes
+*/
+
+enum {
+    kSecInternetPasswordItemClass = 'inet',                   /* Internet password */
+    kSecGenericPasswordItemClass = 'genp',                    /* Generic password */
+    kSecAppleSharePasswordItemClass = 'ashp'                  /* AppleShare password */
+};
+
+
+/*!
+@enum FourCharacterCodes
+*/
+enum {
+                                                                 /* Common attributes */
+    kSecCreationDateItemAttr     = 'cdat',                       /* Date the item was created (UInt32) */
+    kSecModDateItemAttr          = 'mdat',                       /* Last time the item was updated (UInt32) */
+    kSecDescriptionItemAttr      = 'desc',                       /* User-visible description string (string) */
+    kSecCommentItemAttr          = 'icmt',                       /* User's comment about the item (string) */
+    kSecCreatorItemAttr          = 'crtr',                       /* Item's creator (OSType) */
+    kSecTypeItemAttr             = 'type',                       /* Item's type (OSType) */
+    kSecScriptCodeItemAttr       = 'scrp',                       /* Script code for all strings (ScriptCode) */
+    kSecLabelItemAttr            = 'labl',                       /* Item label (string) */
+    kSecInvisibleItemAttr        = 'invi',                       /* Invisible (boolean) */
+    kSecNegativeItemAttr         = 'nega',                       /* Negative (boolean) */
+    kSecCustomIconItemAttr       = 'cusi',                       /* Custom icon (boolean) */
+                                                                 /* Unique Generic password attributes */
+    kSecAccountItemAttr          = 'acct',                       /* User account (string) - also applies to Appleshare and Generic */
+    kSecServiceItemAttr          = 'svce',                       /* Service (string) */
+    kSecGenericItemAttr          = 'gena',                       /* User-defined attribute (untyped bytes) */
+                                                                 /* Unique Internet password attributes */
+    kSecSecurityDomainItemAttr   = 'sdmn',                       /* urity domain (string) */
+    kSecServerItemAttr           = 'srvr',                       /* Server's domain name or IP address (string) */
+    kSecAuthTypeItemAttr         = 'atyp',                       /* Authentication Type (AuthType) */
+    kSecPortItemAttr             = 'port',                       /* Port (UInt32) */
+    kSecPathItemAttr             = 'path',                       /* Path (string) */
+                                                                 /* Unique Appleshare password attributes */
+    kSecVolumeItemAttr           = 'vlme',                       /* Volume (string) */
+    kSecAddressItemAttr          = 'addr',                       /* Server address (IP or domain name) or zone name (string) */
+    kSecSignatureItemAttr        = 'ssig',                       /* Server signature block (AFPServerSignature) */
+                                                                 /* Unique AppleShare and Internet attributes */
+    kSecProtocolItemAttr         = 'ptcl',                       /* Protocol (ProtocolType) */
+
+};
+
+typedef FourCharCode SecItemAttr;
+
+
+/*!
+@enum SecurityAuthTypeCodes
+*/
+enum {
+    kSecAuthTypeNTLM             = 'ntlm',
+    kSecAuthTypeMSN              = 'msna',
+    kSecAuthTypeDPA              = 'dpaa',
+    kSecAuthTypeRPA              = 'rpaa',
+    kSecAuthTypeHTTPDigest       = 'httd',
+    kSecAuthTypeDefault          = 'dflt'
+};
+typedef FourCharCode             SecAuthType;
+
+/*!
+@enum SecurityProtocolTypeCodes
+*/
+enum {
+    kSecProtocolTypeFTP          = 'ftp ',
+    kSecProtocolTypeFTPAccount   = 'ftpa',
+    kSecProtocolTypeHTTP         = 'http',
+    kSecProtocolTypeIRC          = 'irc ',
+    kSecProtocolTypeNNTP         = 'nntp',
+    kSecProtocolTypePOP3         = 'pop3',
+    kSecProtocolTypeSMTP         = 'smtp',
+    kSecProtocolTypeSOCKS        = 'sox ',
+    kSecProtocolTypeIMAP         = 'imap',
+    kSecProtocolTypeLDAP         = 'ldap',
+    kSecProtocolTypeAppleTalk    = 'atlk',
+    kSecProtocolTypeAFP          = 'afp ',
+    kSecProtocolTypeTelnet       = 'teln'
+};
+typedef FourCharCode             SecProtocolType;
+
+/*!
+@typedef KCChangeSettingsInfo
+Keychain Settings
+*/
+struct SecKeychainSettings
+{ 
+	UInt32			      		version; 
+	Boolean	              		lockOnSleep; 
+	Boolean                  	useLockInterval; 
+	UInt32                		lockInterval; 
+};
+typedef struct SecKeychainSettings		SecKeychainSettings;
+
+#define SEC_KEYCHAIN_SETTINGS_VERS1 1
+
+struct SecKeychainCallbackInfo 
+{
+    UInt32								version;
+    SecKeychainItemRef					item;
+    long								processID[2];
+    long								event[4]; 
+    SecKeychainRef						keychain;
+};
+typedef struct SecKeychainCallbackInfo SecKeychainCallbackInfo;
+									
+
+/*!
+    @function SecKeychainGetVersion
+    Returns the version of the Keychain Manager (an unsigned 32-bit integer) in version.
+    
+    @param returnVers Pointer to a UNInt32 to receive the version number.
+    @result noErr 0 No error.
+            errSecNotAvailable -25291 Keychain Manager was not loaded.
+*/
+OSStatus SecKeychainGetVersion(UInt32 *returnVers);
+
+/*!
+    @function SecKeychainOpen
+    Returns a referenece to the keychain specified by keychainFile.
+    The memory that keychain occupies must be released by calling SecKeychainRelease when finished
+    with it.
+    
+    @param pathName A posix path to the keychain file.
+    @param keychainRef Returned keychain reference.
+    @result noErr 0 No error.
+            paramErr -50 The keychain parameter is invalid (NULL).
+*/
+OSStatus SecKeychainOpen(const char *pathName, SecKeychainRef *keychainRef);
+
+/*!
+	@function SecKeychainCreateNew
+    Returns a referenece to the keychain specified by keychainFile.
+    The memory that keychain occupies must be released by calling SecKeychainRelease when finished
+    with it.
+    
+    @param pathName A posix path to the keychain file.
+    @param promptUser Display a password dialog to the user.
+    @param keychainRef Returned keychain reference.
+    @param passwordLength Max length of the password buffer.
+    @param password A pointer to buffer with the password.  Must be in canonical UTF8 encoding.
+    @result noErr 0 No error.
+            paramErr -50 The keychain parameter is invalid (NULL).
+*/
+OSStatus SecKeychainCreateNew(const char *pathName, SecKeychainRef *keychainRef, UInt32 passwordLength, const void *password, Boolean promptUser);
+
+/*!
+	@function SecKeychainDelete
+    Deletes a the keychain specified by keychainRef.
+     
+    @param keychainRef keychain to delete reference.
+    @result noErr 0 No error.
+            paramErr -50 The keychain parameter is invalid (NULL).
+*/
+OSStatus SecKeychainDelete(SecKeychainRef keychainRef);
+
+/*!
+	@function SecKeychainSetSettings
+	Changes the settings of keychain including the lockOnSleep, useLockInterval and lockInterval.
+	
+    @param keychainRef keychain reference of the keychain to set.
+ 	@param newSettings A SecKeychainSettings structure pointer.
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainSetSettings(SecKeychainRef keychainRef, const SecKeychainSettings *newSettings);
+
+/*!
+	@function SecKeychainCopySettings
+	Copy the settings of keychain including the lockOnSleep, useLockInterval and lockInterval.  Because this structure is versioned
+	the caller is required to preallocate it and fill in the version of the structure.
+
+    @param keychainRef keychain reference of the keychain settings to copy.
+    @param outSettings  A SecKeychainSettings structure pointer.
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainCopySettings(SecKeychainRef keychainRef, SecKeychainSettings *outSettings);
+
+/*!
+	@function SecKeychainUnlock
+	Unlocks the specified keychain.
+	
+    @param keychainRef A reference to the keychain to be unlocked.
+	@param passwordLength The length of the password buffer.
+	@param password A buffer with the password for the keychain.
+	@param usePassword By setting this flag the password parameter is either used or ignored.
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainUnlock(SecKeychainRef keychainRef, UInt32 passwordLength, void *password, Boolean usePassword);
+
+/*!
+	@function SecKeychainLock
+	Locks the specified keychain.
+
+    @param keychainRef A reference to the keychain to be Locked.
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainLock(SecKeychainRef	keychainRef);
+
+/*!
+	@function SecKeychainLockAll
+	Locks all keychains.
+
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainLockAll();
+
+/*!
+	@function SecKeychainCopyDefault
+	This routine returns a SecKeychainRef which specifies the default keychain. Your application
+	might call this routine to obtain the name and location of the default keychain.
+	
+	@param SecKeychainRef A pointer to a reference of the default keychain.
+	@result noErr 0 No error.
+			errSecNoDefaultKeychain -25307 There is no currently default keychain.
+*/
+OSStatus SecKeychainCopyDefault(SecKeychainRef *keychainRef);
+
+/*!
+	@function SecKeychainSetDefault
+	This routine sets the default keychain to the keychain specified by keychain. 
+	
+	@param SecKeychainRef A pointer to a reference of the default keychain.
+    @result noErr 0 No error.
+	paramErr -50 The input specification parameter was NULL.
+	errSecNoSuchKeychain -25294 The specified keychain could not be found.
+	errSecInvalidKeychain -25295 The specified keychain is invalid
+*/
+OSStatus SecKeychainSetDefault(SecKeychainRef keychainRef);
+
+/*!
+	@function SecKeychainGetStatus
+	
+	Returns status information for the specified keychain in the supplied parameter. If keychain is NULL,
+	the status of the default keychain is returned.
+	
+	The value returned in keychainStatus is a 32-bit field, the meaning of which must be determined
+	by comparison with a list of predefined constants. 
+	
+	Currently defined bitmask values are:
+		kSecUnlockStateStatus 	1 The specified keychain is unlocked if bit 0 is set.
+		kSecRdPermStatus 		2 The specified keychain is unlocked with read permission if bit 1 is set.
+		kSecWrPermStatus 		4 The specified keychain is unlocked with write permission if bit 2 is set.
+
+	@param keychainRef Pointer to a keychain reference (NULL specifies the default keychain).
+	@param keychainRefStatus Returned status of the specified keychain.
+
+    @result noErr 0 No error.
+			errSecNoSuchKeychain -25294 The specified keychain could not be found.
+			errSecInvalidKeychain -25295 The specified keychain is invalid.	
+*/
+OSStatus SecKeychainGetStatus(SecKeychainRef keychainRef, SecKeychainStatus* keychainStatus);
+
+/*!
+	@function SecKeychainRelease
+	Releases  keychain item references
+	 
+	@param keychainRef A keychain  reference to release.
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainRelease(SecKeychainRef itemRef);
+
+/*!
+	@function SecKeychainGetPath
+	Get the path location of the specified keychain.
+    @param keychainRef A reference to a keychain.
+    @param ioPathLength On input specifies the size or the buffer pointed to by path and on output the length of the buffer 
+                        (without the zero termination which is added)
+	@param pathName A posix path to the receive keychain filename.
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainGetPath(SecKeychainRef keychainRef, UInt32 *ioPathLength, char *pathName);
+
+/*!
+	@function SecKeychainListGetCount
+	This function returns the number of available keychains. This number includes all keychains within
+	the "Keychains" folder, as well as any other keychains known to the Keychain Manager.
+    @result the number of keychains.
+*/
+UInt16 SecKeychainListGetCount(void);
+
+/*!
+	@function SecKeychainListCopyKeychainAtIndex
+	This routine to copies a keychain item from the default keychain to another. 
+	@param index The index of the item to copy.
+	@param keychainRef A keychain reference of the destination keychain.
+	@result noErr 0 No error.
+			errSecInvalidKeychain -25295 The specified destination keychain was invalid.
+			errSecReadOnly -25292 The destination keychain is read only.
+			errSecNoSuchClass -25306 item has an invalid keychain item class.
+*/
+OSStatus SecKeychainListCopyKeychainAtIndex(UInt16 index, SecKeychainRef *keychainRef);
+
+/*!
+	@function SecKeychainItemCreateFromContent
+	Creates a new keychain item from the supplied parameters. A reference to the newly-created
+	item is returned in item. A copy of the data buffer pointed to by data is stored in the item.
+	When the item reference is no longer required, call SecKeychainRelease to deallocate memory occupied
+	by the item.
+	
+	@param itemRefClass A constant identifying the class of item to be created.
+	@param attrList The list of attributes of the item to be created.
+	@param length Length of the data to be stored in this item.
+	@param data Pointer to a buffer containing the data to be stored in this item.
+    @param keychain to add the item to.
+	@param itemRef A reference to the newly created keychain item (optional).
+    @result noErr 0 No error.
+			paramErr -50 Not enough valid parameters were supplied.
+			memFullErr -108 Not enough memory in current heap zone to create the object.
+*/
+OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void *data, SecKeychainRef keychainRef, SecKeychainItemRef *itemRef);
+
+/*!
+	@function SecKeychainItemModifyContent
+	This routine to update an existing keychain item after changing its attributes or data. The item is
+	written to the keychain's permanent data store. If item has not previously been added to a keychain,
+	SecKeychainItemModifyContent does nothing and returns noErr.
+
+	@param itemRef A reference of the keychain item to be modified.
+	@param attrList The list of attributes to be set in this item.
+	@param length Length of the data to be stored in this item.
+	@param data Pointer to a buffer containing the data to be stored in this item.
+    @result noErr 0 No error.
+			errSecNoDefaultKeychain -25307 No default keychain could be found.
+			errSecInvalidItemRef -25304 The specified keychain item reference was invalid.
+*/
+OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data);
+
+/*!
+	@function SecKeychainItemCopyContent
+	Use this function to retrieve the data and/or attributes stored in the given keychain item.
+		
+	You must call SecKeychainItemFreeContent when you no longer need the attributes and data.
+
+	@param itemRef A reference of the keychain item to be modified.
+	@param itemClass The items class.  Pass NULL if not required.
+	@param attrList The list of attributes to get in this item on input, on output the attributes are filled in.
+	@param length on output the actual length of the data.
+	@param outData Pointer to a buffer containing the data in this item.  Pass NULL if not required.
+
+    @result noErr 0 No error.
+			paramErr -50 Not enough valid parameters were supplied.
+			errSecInvalidItemRef -25304 The specified keychain item reference was invalid.
+			errSecBufferTooSmall -25301 The data was too large for the supplied buffer.
+			errSecDataNotAvailable -25316 The data is not available for this item.	
+*/
+OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData);
+
+/*!
+	@function SecKeychainItemFreeContent
+*/
+OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data);
+
+/*!
+	@function SecKeychainAttributeInfoForItemID
+	This will allow clients to obtain the tags for all possible attrs for that item class. User should call SecKeychainFreeAttributeInfo to
+	release the structure when done with it.  
+	
+	Warning, this call returns more attributes than are support by the old style Keychain API and passing them inro older calls will
+	yield an invalid attribute error.  The recommended call to retrieve the attribtute values is SecKeychainItemCopyAttributesAndData.
+
+    @param keychainRef A reference to the keychain.
+	@param itemID the relation ID of the item tags
+	@param info a pointer to a SecKeychainAttributeInfo structure
+	
+    @result noErr 0 No error.
+			paramErr -50 Not enough valid parameters were supplied.
+*/
+OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef,  UInt32 itemID, SecKeychainAttributeInfo **info);
+
+/*!
+	@function SecKeychainFreeAttributeInfo
+	This function free the memory aquired during the SecKeychainAttributeInfoForItemID call.
+		
+	@param Info a pointer to a SecKeychainAttributeInfo structure
+	
+    @result noErr 0 No error.
+			paramErr -50 Not enough valid parameters were supplied.
+*/
+OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info);
+
+/*!
+	@function SecKeychainItemModifyContent
+	This routine to update an existing keychain item after changing its attributes or data. The item is
+	written to the keychain's permanent data store. If item has not previously been added to a keychain,
+	SecKeychainItemModifyContent does nothing and returns noErr.
+
+	@param itemRef A reference of the keychain item to be modified.
+	@param attrList The list of attributes to be set in this item.
+	@param length Length of the data to be stored in this item.
+	@param data Pointer to a buffer containing the data to be stored in this item.
+    @result noErr 0 No error.
+			errSecNoDefaultKeychain -25307 No default keychain could be found.
+			errSecInvalidItemRef -25304 The specified keychain item reference was invalid.
+*/
+OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data);
+
+
+/*!
+	@function SecKeychainItemCopyAttributesAndData
+	Use this function to retrieve the data and/or attributes stored in the given keychain item.
+		
+	You must call SecKeychainItemFreeAttributesAndData when you no longer need the attributes and data.
+
+	@param itemRef A reference of the keychain item to be modified.
+	@param info List of tags of attributes to retrieve.
+	@param itemClass The items class.  Pass NULL if not required.
+	@param attrList The list of attributes to get in this item on input, on output the attributes are filled in.
+	@param length on output the actual length of the data.
+	@param outData Pointer to a buffer containing the data in this item.  Pass NULL if not required.
+
+    @result noErr 0 No error.
+			paramErr -50 Not enough valid parameters were supplied.
+			errSecInvalidItemRef -25304 The specified keychain item reference was invalid.
+			errSecBufferTooSmall -25301 The data was too large for the supplied buffer.
+			errSecDataNotAvailable -25316 The data is not available for this item.	
+*/
+OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData);
+
+/*!
+	@function SecKeychainItemFreeAttributesAndData
+	Use this function to release the data and/or attributes returned by the SecKeychainItemCopyAttributesAndData function.
+
+	@param info List of tags of attributes to retrieve.
+
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attrList, void *data);
+
+/*!
+	@function SecKeychainItemDelete
+	Use this routine to delete a keychain item from the default keychain's permanent data store. If itemRef
+	has not previously been added to the keychain, SecKeychainItemDelete does nothing and returns noErr.
+	IMPORTANT: SecKeychainItemDelete does not dispose the memory occupied by the item reference itself;
+	use SecKeychainItemRelease when you are completely finished with an item.	
+
+	@param itemRef A keychain item reference of the item to be deleted.
+    @result noErr 0 No error.
+			errSecNoDefaultKeychain -25307 No default keychain could be found.
+			errSecInvalidItemRef -25304 The specified keychain item reference was invalid.	
+*/
+OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef);
+
+/*!
+	@function SecKeychainItemCopyKeychain
+	Use this routine to copy an existing keychain reference from a keychain item.	
+	
+	@param itemRef A keychain item reference of the item to be updated.
+	@param keychainRef A pointer to a keychain reference returned.  Release this by calling
+           SecKeychainRelease().
+    @result noErr 0 No error.
+			errSecInvalidItemRef -25304 The specified keychain item reference was invalid.	
+*/
+OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef* keychainRef);
+
+
+/*!
+	@function SecKeychainItemCreateCopy
+	Use this routine to copy a keychain item. The copy will be returned in itemCopy.
+	
+	@param itemRef A keychain item reference to copy.
+	@param itemCopy The new copied item.	
+    @result noErr 0 No error.
+			errSecInvalidKeychain -25295 The specified destKeychain was invalid.
+			errSecReadOnly -25292 The destKeychain is read only.
+			errSecNoSuchClass -25306 item has an invalid keychain item class.	
+*/
+OSStatus SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainItemRef *itemCopy, SecKeychainRef destKeychainRef);
+
+/*!
+	@function SecKeychainItemRelease
+	Releases  keychain item references
+	 
+	@param itemRef A keychain item reference to release.
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainItemRelease(SecKeychainItemRef itemRef);
+
+/*!
+	@function SecKeychainSearchCreateFromAttributes
+	Creates a search reference matching a list of zero or more specified attributes in the specified keychain
+	and returns a reference to the item. Pass NULL for keychain if you wish to search all unlocked
+	keychains. The caller is responsible for calling SecKeychainSearchRelease to release this reference
+	when finished with it. A reference to the current search criteria is also returned, for subsequent calls to
+	SecKeychainCopySearchNextItem. This reference must be released by the caller when completely finished with a
+	search by calling SecKeychainSearchRelease.
+	
+	@param keychainRef The keychain to search (NULL means search all unlocked keychains)
+	@param attrList A list of zero or more SecKeychainAttribute records to be matched
+					(NULL matches any keychain item).
+	@param searchRef A reference to the current search is returned here.
+	
+    @result noErr 0 No error.
+			errSecNoDefaultKeychain -25307 No default keychain could be found.
+			errSecItemNotFound -25300 No matching keychain item was found.
+			errSecNoSuchAttr -25303 Specified an attribute which is undefined for this item class.	
+*/
+OSStatus SecKeychainSearchCreateFromAttributes(SecKeychainRef keychainRef, SecItemClass itemClass, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef);
+
+/*!
+	@function SecKeychainCopySearchNextItem
+	Finds the next keychain item matching the given search criteria, as previously specified by a call to
+	SecKeychainSearchCreateFromAttributes, and returns a reference to the item. The caller is responsible for releasing
+	this reference when finished with it.
+	
+	@param searchRef A reference to the current search criteria.
+	@param itemRef A reference to the next matching keychain item, if any, is returned here.	
+    @result noErr 0 No error.
+			errSecNoDefaultKeychain -25307 No default keychain could be found.
+			errSecInvalidSearchRef -25305 The specified search reference was invalid.
+			errSecItemNotFound -25300 No more matching keychain items were found.	
+*/
+OSStatus SecKeychainCopySearchNextItem(SecKeychainSearchRef searchRef, SecKeychainItemRef *itemRef);
+
+/*!
+	@function SecKeychainSearchRelease
+	Releases a keychain search reference.
+		
+	@param searchRef A reference to the search reference.
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainSearchRelease(SecKeychainSearchRef searchRef);
+
+ 
+/*!
+	@function SecKeychainListRemoveKeychain
+	Removed the specified keychain from the list of availible keychains.
+	
+	@param keychainRef A reference to the keychain to be removed.
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainListRemoveKeychain(SecKeychainRef *keychainRef);
+ 
+// Keychain Callback mgr stuff
+typedef OSStatus (*SecKeychainCallbackProcPtr)(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo* info, void *context);
+
+
+/*!
+	@function SecKeychainAddCallback
+	Add a callback.
+	
+	@param callbackFunction The callback function pointer to add
+	@param eventMask
+	@param userContext
+    @result noErr 0 No error.
+*/
+OSStatus SecKeychainAddCallback(SecKeychainCallbackProcPtr callbackFunction, SecKeychainEventMask eventMask, void* userContext);
+
+
+/*!
+	@function SecKeychainRemoveCallback
+	Remove a callback.
+	
+	@param callbackFunction The callback function pointer to remove 
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainRemoveCallback(SecKeychainCallbackProcPtr callbackFunction);
+
+
+/*!
+	@function SecKeychainAddInternetPassword
+	Add an internet password to the specified keychain.
+	
+	@param keychainRef
+	@param serverNameLength
+	@param serverName
+	@param securityDomainLength
+	@param securityDomain
+	@param accountNameLength
+	@param accountName
+	@param pathLength
+	@param path
+	@param port
+	@param protocol
+	@param authType
+	@param passwordLength
+	@param passwordData
+	@param itemRef
+	
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainAddInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, char *serverName, 
+										UInt32 securityDomainLength, char *securityDomain, UInt32 accountNameLength, char *accountName, 
+										UInt32 pathLength, char *path, UInt16 port, OSType protocol, OSType authType,
+										UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef);
+
+
+/*!
+	@function SecKeychainFindInternetPassword
+	Find an internet password
+		
+	@param keychainRef
+	@param serverNameLength
+	@param serverName
+	@param securityDomainLength
+	@param securityDomain
+	@param accountNameLength
+	@param accountName
+	@param pathLength
+	@param path
+	@param port
+	@param protocol
+	@param authType
+	@param passwordLength
+	@param passwordData
+	@param itemRef
+
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainFindInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, char *serverName, 
+										UInt32 securityDomainLength, char *securityDomain, UInt32 accountNameLength, char *accountName,
+										UInt32 pathLength, char *path, UInt16 port, OSType protocol, OSType authType,
+										UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef);
+
+
+/*!
+	@function SecKeychainAddGenericPassword
+	Add an generic password to the specified keychain.
+	
+	@param  keychainRef
+	@param serviceNameLength
+	@param serviceName
+	@param accountNameLength
+	@param accountName
+	@param passwordData
+	@param passwordLength
+	@param itemRef
+
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainAddGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, char *serviceName,
+									   UInt32 accountNameLength, char *accountName, 
+									   UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef);
+
+
+/*!
+	@function SecKeychainFindGenericPassword
+	Find a generic password
+
+	@param keychainRef
+	@param serverNameLength
+	@param serverName
+	@param accountNameLength
+	@param accountName
+	@param passwordLength
+	@param passwordData
+	@param itemRef
+
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainFindGenericPassword(SecKeychainRef keychainRef,  UInt32 serviceNameLength, char *serviceName,
+										UInt32 accountNameLength, char *accountName,
+										UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef);
+
+
+
+/*!
+	@function SecKeychainSetUserInteractionAllowed
+	Turn on/off any optional user interface
+	
+	@param state true = allow user interface, false = disallow user interface
+
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainSetUserInteractionAllowed(Boolean state);
+
+/*!
+	@function SecKeychainGetUserInteractionAllowed
+	Get the current setting for SecKeychainSetUserInteractionAllowed
+		
+	@param *state true = allow user interface, false = disallow user interface
+
+	@result noErr 0 No error.
+*/
+OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* ! __SECKEYCHAINAPI__ */
+
+
diff --git a/Keychain/SecKeychainAPIPriv.h b/Keychain/SecKeychainAPIPriv.h
new file mode 100644
index 00000000..22c5c42d
--- /dev/null
+++ b/Keychain/SecKeychainAPIPriv.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  SecKeychainAPIPriv.h
+ *  SecurityCore
+ *
+ *    Copyright:  (c) 2000 by Apple Computer, Inc., all rights reserved
+ *
+ */
+#ifndef __KEYCHAINAPIPRIV__
+#define __KEYCHAINAPIPRIV__
+
+#include <Security/SecKeychainAPI.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Private keychain item attributes */
+enum 
+{
+	kSecClassItemAttr            = 'clas',                       /* Item class (KCItemClass) */
+	kSecAliasItemAttr            = 'alis',                       /* Alias attribute (required by CDSA). */
+	kSecProtectedDataItemAttr    = 'prot',                       /* Item's data is protected (encrypted) (Boolean) */
+
+                                                                 /* Certificate attributes */
+    kSecSubjectItemAttr          = 'subj',                       /* Subject distinguished name (DER-encoded data) */
+    kSecCommonNameItemAttr       = 'cn  ',                       /* Common Name (UTF8-encoded string) */
+    kSecIssuerItemAttr           = 'issu',                       /* Issuer distinguished name (DER-encoded data) */
+    kSecSerialNumberItemAttr     = 'snbr',                       /* Certificate serial number (DER-encoded data) */
+    kSecEMailItemAttr            = 'mail',                       /* E-mail address (ASCII-encoded string) */
+    kSecPublicKeyHashItemAttr    = 'hpky',                       /* Hash of public key (PublicKeyHash), 20 bytes max. */
+    kSecIssuerURLItemAttr        = 'iurl',                       /* URL of the certificate issuer (ASCII-encoded string) */
+                                                                 /* Shared by keys and certificates */
+    kSecEncryptItemAttr          = 'encr',                       /* Encrypt (Boolean) */
+    kSecDecryptItemAttr          = 'decr',                       /* Decrypt (Boolean) */
+    kSecSignItemAttr             = 'sign',                       /* Sign (Boolean) */
+    kSecVerifyItemAttr           = 'veri',                       /* Verify (Boolean) */
+    kSecWrapItemAttr             = 'wrap',                       /* Wrap (Boolean) */
+    kSecUnwrapItemAttr           = 'unwr',                       /* Unwrap (Boolean) */
+    kSecStartDateItemAttr        = 'sdat',                       /* Start Date (UInt32) */
+    kSecEndDateItemAttr          = 'edat'                        /* End Date (UInt32) */
+};
+
+OSStatus SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword,  UInt32 newPasswordLength, const void *newPassword);
+
+OSStatus SecKeychainCopyLogin(SecKeychainRef *keychainRef);
+
+OSStatus SecKeychainLogin(UInt32 nameLength, void* name, UInt32 passwordLength, void* password);
+
+OSStatus SecKeychainLogout();
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // __KEYCHAINAPIPRIV__
diff --git a/Keychain/StorageManager.cpp b/Keychain/StorageManager.cpp
new file mode 100644
index 00000000..78194a43
--- /dev/null
+++ b/Keychain/StorageManager.cpp
@@ -0,0 +1,370 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		StorageManager.cpp
+
+	Contains:	Working with multiple keychains
+
+	Copyright:	2000 by Apple Computer, Inc., all rights reserved.
+
+	To Do:
+*/
+
+#include "StorageManager.h"
+#include "KCEventNotifier.h"
+
+#include <Security/cssmapple.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <algorithm>
+#include <string>
+#include <Security/Authorization.h>
+#include <Security/AuthorizationTags.h>
+#include <Security/AuthSession.h>
+#include <Security/debugging.h>
+
+#include "KCCursor.h"
+#include "Globals.h"
+#include "DefaultKeychain.h"
+
+using namespace CssmClient;
+using namespace KeychainCore;
+
+StorageManager::StorageManager() :
+    mSavedList(),
+    mKeychains(),
+    mMultiDLDb(mSavedList.list(), true) // Passinng true enables use of Secure Storage
+{
+}
+
+// Create KC if it doesn't exist	
+Keychain
+StorageManager::keychain(const DLDbIdentifier &dLDbIdentifier)
+{
+	//StLock<Mutex> _(mKeychainsLock);
+    KeychainMap::iterator it = mKeychains.find(dLDbIdentifier);
+    if (it != mKeychains.end())
+		return it->second;
+
+	// The keychain is not in our cache.  Create it.
+	Keychain keychain(mMultiDLDb->database(dLDbIdentifier));
+
+	// Add the keychain to the cache.
+	mKeychains.insert(KeychainMap::value_type(dLDbIdentifier, keychain));
+	return keychain;
+}
+
+// Create KC if it doesn't exist	
+Keychain
+StorageManager::makeKeychain(const DLDbIdentifier &dLDbIdentifier)
+{
+	Keychain keychain(keychain(dLDbIdentifier));
+
+	const vector<DLDbIdentifier> &list = mMultiDLDb->list();
+	if (find(list.begin(), list.end(), dLDbIdentifier) != list.end())
+	{
+		// The dLDbIdentifier for this keychain is already on our search list.
+		return keychain;
+	}
+
+	// If the keychain doesn't exist don't bother adding it to the search list yet.
+	if (!keychain->exists())
+		return keychain;
+
+	// The keychain exists and is not in our search list add it to the search
+	// list and the cache.  Then inform mMultiDLDb.
+	mSavedList.revert(true);
+	mSavedList.add(dLDbIdentifier);
+	mSavedList.save();
+
+	// @@@ Will happen again when kSecKeychainListChangedEvent notification is received.
+	mMultiDLDb->list(mSavedList.list());
+
+	KCEventNotifier::PostKeychainEvent(kSecKeychainListChangedEvent);
+
+	return keychain;
+}
+
+void
+StorageManager::created(const Keychain &keychain) // Be notified a Keychain just got created.
+{
+    DLDbIdentifier dLDbIdentifier = keychain->dLDbIdentifier();
+	
+    // If we don't have a default Keychain yet.  Make the newly created keychain the default.
+    DefaultKeychain &defaultKeychain = globals().defaultKeychain;
+    if (!defaultKeychain.isSet())
+        defaultKeychain.dLDbIdentifier(dLDbIdentifier);
+
+	// Add the keychain to the search list and the cache.  Then inform mMultiDLDb.
+	mSavedList.revert(true);
+	mSavedList.add(dLDbIdentifier);
+	mSavedList.save();
+
+	// @@@ Will happen again when kSecKeychainListChangedEvent notification is received.
+	mMultiDLDb->list(mSavedList.list());
+
+	KCEventNotifier::PostKeychainEvent(kSecKeychainListChangedEvent);
+}
+
+
+KCCursor
+StorageManager::createCursor(SecItemClass itemClass, const SecKeychainAttributeList *attrList)
+{
+	return KCCursor(DbCursor(mMultiDLDb), itemClass, attrList);
+}
+
+KCCursor
+StorageManager::createCursor(const SecKeychainAttributeList *attrList)
+{
+	return KCCursor(DbCursor(mMultiDLDb), attrList);
+}
+
+void
+StorageManager::lockAll()
+{
+    for (KeychainMap::iterator ix = mKeychains.begin(); ix != mKeychains.end(); ix++)
+	{
+		Keychain keychain(ix->second);
+		if (keychain->isActive())
+			keychain->lock();
+	}
+}
+
+void
+StorageManager::reload(bool force)
+{
+    // Reinitialize list from CFPrefs if changed.  When force is true force a prefs revert now.
+    if (mSavedList.revert(force))
+        mMultiDLDb->list(mSavedList.list());
+}
+
+size_t
+StorageManager::size()
+{
+    reload();
+    return mMultiDLDb->list().size();
+}
+
+Keychain
+StorageManager::at(unsigned int ix)
+{
+    reload();
+    if (ix >= mMultiDLDb->list().size())
+        MacOSError::throwMe(errSecInvalidKeychain);
+
+    return keychain(mMultiDLDb->list().at(ix));
+}
+
+Keychain
+StorageManager::operator[](unsigned int ix)
+{
+    return at(ix);
+}	
+
+void StorageManager::remove(const list<SecKeychainRef>& kcsToRemove)
+{
+	//StLock<Mutex> _(mKeychainsLock);
+	mSavedList.revert(true);
+	DLDbIdentifier defaultId = globals().defaultKeychain.dLDbIdentifier();
+	bool unsetDefault=false;
+    for (list<SecKeychainRef>::const_iterator ix = kcsToRemove.begin();ix!=kcsToRemove.end();ix++)
+	{
+		// Find the keychain object for the given ref
+		Keychain keychainToRemove;
+		try
+		{
+			keychainToRemove = KeychainRef::required(*ix);
+		}
+		catch (const MacOSError& err)
+		{
+			if (err.osStatus() == errSecInvalidKeychain)
+				continue;
+			throw;
+		}
+		
+		// Remove it from the saved list
+		mSavedList.remove(keychainToRemove->dLDbIdentifier());
+		if (keychainToRemove->dLDbIdentifier() == defaultId)
+			unsetDefault=true;
+		// Now remove it from the map
+		KeychainMap::iterator it = mKeychains.find(keychainToRemove->dLDbIdentifier());
+		if (it==mKeychains.end())
+			continue;
+		mKeychains.erase(it);
+	}
+	mSavedList.save();
+	mMultiDLDb->list(mSavedList.list());
+	KCEventNotifier::PostKeychainEvent(kSecKeychainListChangedEvent);
+	if (unsetDefault)
+		globals().defaultKeychain.unset();
+}
+
+void StorageManager::replace(const list<SecKeychainRef>& newKCList)
+{
+	// replace keychains list with new list
+	CssmClient::DLDbList dldbList;
+	convert(newKCList,dldbList);
+}
+
+void StorageManager::convert(const list<SecKeychainRef>& SecKeychainRefList,CssmClient::DLDbList& dldbList)
+{
+    // Convert a list of SecKeychainRefs to a DLDbList
+	dldbList.clear();		// If we don't clear list, we should use "add" instead of push_back
+	for (list<SecKeychainRef>::const_iterator ix = SecKeychainRefList.begin();ix!=SecKeychainRefList.end();ix++)
+	{
+		// Find the keychain object for the given ref
+		Keychain keychain;
+		try
+		{
+			keychain = KeychainRef::required(*ix);
+		}
+		catch (const MacOSError& err)
+		{
+			if (err.osStatus() == errSecInvalidKeychain)
+				continue;
+			throw;
+		}
+		
+		// Add it to the list
+		dldbList.push_back(keychain->dLDbIdentifier());
+	}
+}
+
+
+#pragma mark ÑÑÑÑ Login Functions ÑÑÑÑ
+
+void StorageManager::login(ConstStringPtr name, ConstStringPtr password)
+{
+    if ( name == NULL || password == NULL )
+        MacOSError::throwMe(paramErr);
+
+	login(name[0], name + 1, password[0], password + 1);
+}
+
+void StorageManager::login(UInt32 nameLength, const void *name, UInt32 passwordLength, const void *password)
+{
+    // @@@ set up the login session on behalf of loginwindow
+    // @@@ (this code should migrate into loginwindow)
+    debug("KClogin", "setting up login session");
+    if (OSStatus ssnErr = SessionCreate(sessionKeepCurrentBootstrap,
+            sessionHasGraphicAccess | sessionHasTTY))
+        debug("KClogin", "session setup failed status=%ld", ssnErr);
+
+    if (name == NULL || (passwordLength != 0 && password == NULL))
+        MacOSError::throwMe(paramErr);
+
+	// Make sure name is zero terminated
+	string theName(reinterpret_cast<const char *>(name), nameLength);
+	Keychain keychain = make(theName.c_str());
+	try
+	{
+		keychain->unlock(CssmData(const_cast<void *>(password), passwordLength));
+        debug("KClogin", "keychain unlock successful");
+	}
+	catch(const CssmError &e)
+	{
+		if (e.osStatus() != CSSMERR_DL_DATASTORE_DOESNOT_EXIST)
+			throw;
+        debug("KClogin", "creating login keychain");
+		keychain->create(passwordLength, password);
+		// Login Keychain does not lock on sleep nor lock after timeout by default.
+		keychain->setSettings(INT_MAX, false);
+	}
+
+	// @@@ Create a authorization credential for the current user.
+    debug("KClogin", "creating login authorization");
+	const AuthorizationItem envList[] =
+	{
+		{ kAuthorizationEnvironmentUsername, nameLength, const_cast<void *>(name), 0 },
+		{ kAuthorizationEnvironmentPassword, passwordLength, const_cast<void *>(password), 0 },
+		{ kAuthorizationEnvironmentShared, 0, NULL, 0 }
+	};
+	const AuthorizationEnvironment environment =
+	{
+		sizeof(envList) / sizeof(*envList),
+		const_cast<AuthorizationItem *>(envList)
+	};
+	if (OSStatus authErr = AuthorizationCreate(NULL, &environment,
+            kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize, NULL))
+        debug("KClogin", "failed to create login auth, status=%ld", authErr);
+}
+
+void StorageManager::logout()
+{
+    // nothing left to do here
+}
+
+void StorageManager::changeLoginPassword(ConstStringPtr oldPassword, ConstStringPtr newPassword)
+{
+	globals().defaultKeychain.keychain()->changePassphrase(oldPassword, newPassword);
+}
+
+
+void StorageManager::changeLoginPassword(UInt32 oldPasswordLength, const void *oldPassword,  UInt32 newPasswordLength, const void *newPassword)
+{
+	globals().defaultKeychain.keychain()->changePassphrase(oldPasswordLength, oldPassword,  newPasswordLength, newPassword);
+}
+
+#pragma mark ÑÑÑÑ File Related ÑÑÑÑ
+
+Keychain StorageManager::make(const char *pathName)
+{
+	string fullPathName;
+    if ( pathName[0] == '/' )
+		fullPathName = pathName;
+	else
+    {
+		// Get Home directory from environment.
+		const char *homeDir = getenv("HOME");
+		if (homeDir == NULL)
+		{
+			// If $HOME is unset get the current users home directory from the passwd file.
+			struct passwd *pw = getpwuid(getuid());
+			if (!pw)
+				MacOSError::throwMe(paramErr);
+
+			homeDir = pw->pw_dir;
+		}
+
+		fullPathName = homeDir;
+		fullPathName += "/Library/Keychains/";
+		fullPathName += pathName;
+	}
+
+    const CSSM_NET_ADDRESS *DbLocation = NULL;	// NULL for keychains
+    const CSSM_VERSION *version = NULL;
+    uint32 subserviceId = 0;
+    CSSM_SERVICE_TYPE subserviceType = CSSM_SERVICE_DL | CSSM_SERVICE_CSP;
+    const CssmSubserviceUid ssuid( gGuidAppleCSPDL, version, 
+                                   subserviceId, subserviceType );
+	DLDbIdentifier dLDbIdentifier( ssuid, fullPathName.c_str(), DbLocation );
+	return makeKeychain( dLDbIdentifier );
+}
+
+KeychainSchema
+StorageManager::keychainSchemaFor(const CssmClient::Db &db)
+{
+	KeychainSchema schema(db);
+	pair<KeychainSchemaSet::iterator, bool> result = mKeychainSchemaSet.insert(db);
+	if (result.second)
+		return schema;
+	return *result.first;
+}
+
diff --git a/Keychain/StorageManager.h b/Keychain/StorageManager.h
new file mode 100644
index 00000000..91631ee7
--- /dev/null
+++ b/Keychain/StorageManager.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		StorageManager.h
+
+	Contains:	Working with multiple keychains
+
+	Copyright:	2000 by Apple Computer, Inc., all rights reserved.
+
+	To Do:
+*/
+
+#ifndef _H_STORAGEMANAGER_
+#define _H_STORAGEMANAGER_
+
+#include <list>
+#include <Security/multidldb.h>
+#include <Security/DLDBListCFPref.h>
+#include <Security/Keychains.h>
+
+namespace Security
+{
+
+namespace KeychainCore
+{
+
+class StorageManager
+{
+    NOCOPY(StorageManager)
+public:
+	StorageManager();
+    ~StorageManager() {}
+
+    //bool onlist(const Keychain & keychain);
+
+    // These will call addAndNotify() if the specified keychain already exists
+    Keychain make(const char *fullPathName);
+    void created(const Keychain &keychain); // Be notified a Keychain just got created.
+
+	// Misc
+    void lockAll();
+    void reload(bool force = false);
+
+    void add(const Keychain& keychainToAdd); // Only add if not there yet.  Doesn't write out CFPref
+
+    // Vector-like methods.
+	size_t size();
+	Keychain at(unsigned int ix);
+	Keychain operator[](unsigned int ix);
+
+    void erase(const Keychain& keychainToRemove);
+
+	KCCursor createCursor(const SecKeychainAttributeList *attrList);
+	KCCursor createCursor(SecItemClass itemClass, const SecKeychainAttributeList *attrList);
+
+     // Create KC if it doesn't exist, add to cache, but don't modify search list.	
+    Keychain keychain(const DLDbIdentifier &dlDbIdentifier);
+
+     // Create KC if it doesn't exist, add it to the search list if it is not already on it.
+    Keychain makeKeychain(const DLDbIdentifier &dlDbIdentifier);
+
+
+	// Keychain list maintenance
+	void remove(const list<SecKeychainRef>& kcsToRemove);	    // remove keychains from list
+	void replace(const list<SecKeychainRef>& newKCList);		// replace keychains list with new list
+	void convert(const list<SecKeychainRef>& SecKeychainRefList,CssmClient::DLDbList& dldbList);	// maybe should be private
+
+	// Login keychain support
+	void login(ConstStringPtr name, ConstStringPtr password);
+	void login(UInt32 nameLength, const void *name, UInt32 passwordLength, const void *password);
+	void logout();
+	void changeLoginPassword(ConstStringPtr oldPassword, ConstStringPtr newPassword);
+	void changeLoginPassword(UInt32 oldPasswordLength, const void *oldPassword,  UInt32 newPasswordLength, const void *newPassword);
+
+private:
+    typedef map<DLDbIdentifier, Keychain> KeychainMap;
+	typedef set<KeychainSchema> KeychainSchemaSet;
+
+    // Only add if not there yet.  Writes out CFPref and broadcasts KCPrefListChanged notification
+	void addAndNotify(const Keychain& keychainToAdd);
+	KeychainSchema keychainSchemaFor(const CssmClient::Db &db);
+
+	//Mutex mKeychainsLock;
+    DLDbListCFPref mSavedList;
+    KeychainMap mKeychains;		// the array of Keychains
+    CssmClient::MultiDLDb mMultiDLDb;
+	KeychainSchemaSet mKeychainSchemaSet;
+};
+
+} // end namespace KeychainCore
+
+} // end namespace Security
+
+#endif /* _H_STORAGEMANAGER_ */
+
diff --git a/Keychain/cssmdatetime.cpp b/Keychain/cssmdatetime.cpp
new file mode 100644
index 00000000..980f0234
--- /dev/null
+++ b/Keychain/cssmdatetime.cpp
@@ -0,0 +1,262 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cssmdatetime.cpp
+
+	Contains:	CSSM date and time utilities for the Mac
+
+	Written by:	The Hindsight team
+
+	Copyright:	© 1997-2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+	To Do:
+*/
+
+#ifdef __MWERKS__
+#define _CPP_CSSM_DATE_TIME_UTILS
+#endif
+
+#include "cssmdatetime.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <Security/utilities.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFTimeZone.h>
+
+namespace Security
+{
+
+namespace CSSMDateTimeUtils
+{
+
+#define MAX_TIME_STR_LEN  	30
+#define UTC_TIME_STRLEN  13
+#define GENERALIZED_TIME_STRLEN  15
+
+
+void
+GetCurrentMacLongDateTime(SInt64 &outMacDate)
+{
+	CFTimeZoneRef timeZone = CFTimeZoneCopyDefault();
+	CFAbsoluteTime absTime = CFAbsoluteTimeGetCurrent();
+	absTime += CFTimeZoneGetSecondsFromGMT(timeZone, absTime);
+	CFRelease(timeZone);
+	outMacDate = SInt64(double(absTime + kCFAbsoluteTimeIntervalSince1904));
+}
+
+void
+TimeStringToMacSeconds (const CSSM_DATA &inUTCTime, UInt32 &ioMacDate)
+{
+    SInt64 ldt;
+    TimeStringToMacLongDateTime(inUTCTime, ldt);
+    ioMacDate = UInt32(ldt);
+}
+
+/*
+ * Given a CSSM_DATA containing either a UTC-style or "generalized time"
+ * time string, convert to 32-bit Mac time in seconds.
+ * Returns nonzero on error. 
+ */
+void
+TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, SInt64 &outMacDate)
+{
+	char 		szTemp[5];
+	unsigned 	len;
+	int 		isUtc;
+	sint32 		x;
+	sint32 		i;
+	char 		*cp;
+
+	CFGregorianDate date;
+	::memset( &date, 0, sizeof(date) );
+
+	if ((inUTCTime.Data == NULL) || (inUTCTime.Length == 0))
+    {
+    	MacOSError::throwMe(paramErr);
+  	}
+
+  	/* tolerate NULL terminated or not */
+  	len = inUTCTime.Length;
+  	if (inUTCTime.Data[len - 1] == '\0')
+  		len--;
+
+  	switch(len)
+    {
+  		case UTC_TIME_STRLEN:			// 2-digit year, not Y2K compliant
+  			isUtc = 1;
+  			break;
+  		case GENERALIZED_TIME_STRLEN:	// 4-digit year
+  			isUtc = 0;
+  			break;
+  		default:						// unknown format 
+            MacOSError::throwMe(paramErr);
+  	}
+
+  	cp = (char *)inUTCTime.Data;
+  	
+	/* check that all characters except last are digits */
+    for(i=0; i<(sint32)(len - 1); i++) {
+		if ( !(isdigit(cp[i])) ) {
+            MacOSError::throwMe(paramErr);
+		}
+	}
+
+  	/* check last character is a 'Z' */
+  	if(cp[len - 1] != 'Z' )	{
+        MacOSError::throwMe(paramErr);
+  	}
+
+  	/* YEAR */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	if(!isUtc) {
+		/* two more digits */
+		szTemp[2] = *cp++;
+		szTemp[3] = *cp++;
+		szTemp[4] = '\0';
+	}
+	else { 
+		szTemp[2] = '\0';
+	}
+	x = atoi( szTemp );
+	if(isUtc) {
+		/* 
+		 * 2-digit year. 
+		 *   0  <= year <= 50 : assume century 21
+		 *   50 <  year <  70 : illegal per PKIX
+		 *   70 <  year <= 99 : assume century 20
+		 */
+		if(x <= 50) {
+			x += 100;
+		}
+		else if(x < 70) {
+            MacOSError::throwMe(paramErr);
+		}
+		/* else century 20, OK */
+
+		/* bug fix... we need to end up with a 4-digit year! */
+		x += 1900;
+	}
+  	/* by definition - tm_year is year - 1900 */
+  	//tmp->tm_year = x - 1900;
+  	date.year = x;
+
+  	/* MONTH */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+	x = atoi( szTemp );
+	/* in the string, months are from 1 to 12 */
+	if((x > 12) || (x <= 0)) {
+        MacOSError::throwMe(paramErr);
+	}
+	/* in a tm, 0 to 11 */
+  	//tmp->tm_mon = x - 1;
+  	date.month = x;
+
+ 	/* DAY */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+	x = atoi( szTemp );
+	/* 1..31 in both formats */
+	if((x > 31) || (x <= 0)) {
+        MacOSError::throwMe(paramErr);
+	}
+  	//tmp->tm_mday = x;
+  	date.day = x;
+
+	/* HOUR */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+	x = atoi( szTemp );
+	if((x > 23) || (x < 0)) {
+        MacOSError::throwMe(paramErr);
+	}
+	//tmp->tm_hour = x;
+	date.hour = x;
+
+  	/* MINUTE */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+	x = atoi( szTemp );
+	if((x > 59) || (x < 0)) {
+        MacOSError::throwMe(paramErr);
+	}
+  	//tmp->tm_min = x;
+  	date.minute = x;
+
+  	/* SECOND */
+	szTemp[0] = *cp++;
+	szTemp[1] = *cp++;
+	szTemp[2] = '\0';
+  	x = atoi( szTemp );
+	if((x > 59) || (x < 0)) {
+        MacOSError::throwMe(paramErr);
+	}
+  	//tmp->tm_sec = x;
+  	date.second = x;
+
+	CFTimeZoneRef timeZone = CFTimeZoneCopyDefault();
+	CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime(date, timeZone);
+	CFRelease(timeZone);
+	outMacDate = SInt64(double(absTime + kCFAbsoluteTimeIntervalSince1904));
+}
+
+void MacSecondsToTimeString(UInt32 inMacDate, UInt32 inLength, void *outData)
+{
+    SInt64 ldt = SInt64(UInt64(inMacDate));
+    MacLongDateTimeToTimeString(ldt, inLength, outData);
+}
+
+void MacLongDateTimeToTimeString(const SInt64 &inMacDate,
+                                        UInt32 inLength, void *outData)
+{
+	CFAbsoluteTime absTime = inMacDate - kCFAbsoluteTimeIntervalSince1904;
+	CFTimeZoneRef timeZone = CFTimeZoneCopyDefault();
+	CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(absTime, timeZone);
+	CFRelease(timeZone);
+
+    if (inLength == 16)
+    {
+        sprintf((char *)(outData), "%04d%02d%02d%02d%02d%02dZ",
+                int(date.year % 10000), date.month, date.day,
+                date.hour, date.minute, int(date.second));
+    }
+    else if (inLength == 14)
+    {
+ 		/* UTC - 2 year digits - code which parses this assumes that
+		 * (2-digit) years between 0 and 49 are in century 21 */
+        sprintf((char *)(outData), "%02d%02d%02d%02d%02d%02dZ",
+                int(date.year % 100), date.month, date.day,
+                date.hour, date.minute, int(date.second));
+    }
+    else
+        MacOSError::throwMe(paramErr);
+}
+
+}; // end namespace CSSMDateTimeUtils
+
+} // end namespace Security
diff --git a/Keychain/cssmdatetime.h b/Keychain/cssmdatetime.h
new file mode 100644
index 00000000..2f7a4762
--- /dev/null
+++ b/Keychain/cssmdatetime.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cssmdatetime.h
+
+	Contains:	defines for the CSSM date and time utilities for the Mac
+
+	Written by:	The Hindsight team
+
+	Copyright:	© 1997-2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+	To Do:
+*/
+
+#ifndef _CSSM_DATE_TIME_UTILS
+#define _CSSM_DATE_TIME_UTILS
+
+#include <Security/cssm.h>
+
+#ifdef _CPP_CSSM_DATE_TIME_UTILS
+# pragma export on
+#endif
+
+namespace Security
+{
+
+namespace CSSMDateTimeUtils
+{
+
+// Get the current time.
+extern void GetCurrentMacLongDateTime(SInt64 &outMacDate);
+
+extern void TimeStringToMacSeconds(const CSSM_DATA &inUTCTime, UInt32 &ioMacDate);
+extern void TimeStringToMacLongDateTime(const CSSM_DATA &inUTCTime, SInt64 &outMacDate);
+
+// Length of inLength is an input parameter and must be 14 or 16.
+// The outData parameter must point to a buffer of at least inLength bytes.
+extern void MacSecondsToTimeString(UInt32 inMacDate, UInt32 inLength, void *outData);
+extern void MacLongDateTimeToTimeString(const SInt64 &inMacDate,
+                                        UInt32 inLength, void *outData);
+}; // end namespace CSSMDateTimeUtils
+
+} // end namespace Security
+
+#ifdef _CPP_CSSM_DATE_TIME_UTILS
+# pragma export off
+#endif
+
+#endif //_CSSM_DATE_TIME_UTILS
diff --git a/Network/connectionpool.cpp b/Network/connectionpool.cpp
new file mode 100644
index 00000000..c43f2603
--- /dev/null
+++ b/Network/connectionpool.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+
+//
+// connectionpool - manage pool of active, unused Connection objects
+//
+#include "connectionpool.h"
+#include "netconnection.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Try to locate a Connection with a suitable HostTarget from the pool.
+// If found, remove it from the pool and return it. Otherwise, return NULL (no error).
+//
+Connection *ConnectionPool::get(const HostTarget &host)
+{
+    //@@@ locking, of course :-)
+    ConnectionMap::iterator it = mConnections.find(host);
+    if (it != mConnections.end()) {
+        // take it and use it
+        Connection *connection = it->second;
+        mConnections.erase(it);
+        debug("connpool", "Connection %p retrieved from pool", connection);
+        return connection;
+    }
+    // none available
+    return NULL;
+}
+
+
+//
+// Retain a Connection in the pool
+//
+void ConnectionPool::retain(Connection *connection)
+{
+    //@@@ threading, of course :-)
+    debug("connpool", "Connection %p retained in connection pool", connection);
+    mConnections.insert(ConnectionMap::value_type(connection->hostTarget, connection));
+    //mConnections[connection->hostTarget] = connection;
+}
+
+
+//
+// Remove a retained Connection from the pool.
+// Returns true if found (and removed); false otherwise.
+//
+bool ConnectionPool::remove(Connection *connection)
+{
+    // this search is two-stage to deal with potentially large multimaps
+    typedef ConnectionMap::iterator Iter;
+    pair<Iter, Iter> range = mConnections.equal_range(connection->hostTarget);
+    for (Iter it = range.first; it != range.second; it++)
+        if (it->second == connection) {
+            mConnections.erase(it);
+            debug("connpool", "Connection %p removed from connection pool", connection);
+            return true;
+        }
+    return false;
+}
+
+
+//
+// Clear the connection pool
+//
+void ConnectionPool::purge()
+{
+    IFDEBUG(debug("connpool", "Connection pool purging %ld connections", mConnections.size()));
+    for (ConnectionMap::iterator it = mConnections.begin(); it != mConnections.end(); it++)
+        delete it->second;
+    mConnections.erase(mConnections.begin(), mConnections.end());
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/connectionpool.h b/Network/connectionpool.h
new file mode 100644
index 00000000..6dd7e1d1
--- /dev/null
+++ b/Network/connectionpool.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+
+//
+// connectionpool - manage pool of active, unused Connection objects
+//
+#ifndef _H_CONNECTIONPOOL
+#define _H_CONNECTIONPOOL
+
+#include "target.h"
+#include <map>
+
+namespace Security {
+namespace Network {
+
+
+class Connection;
+
+
+//
+// There is exactly one InternetAccessManager object per process.
+//
+class ConnectionPool {
+public:
+    ConnectionPool() { }
+    ~ConnectionPool() { purge(); }
+    
+    Connection *get(const HostTarget &host);
+    void retain(Connection *connection);
+    bool remove(Connection *connection);
+    
+    void purge();
+    
+private:
+    typedef multimap<HostTarget, Connection *> ConnectionMap;
+    ConnectionMap mConnections;				// set of active connections
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_CONNECTIONPOOL
diff --git a/Network/file-protocol.cpp b/Network/file-protocol.cpp
new file mode 100644
index 00000000..cd758a33
--- /dev/null
+++ b/Network/file-protocol.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+
+//
+// file-protocol - File protocol objects
+//
+#include "file-protocol.h"
+#include "netmanager.h"
+#include "neterror.h"
+#include "netparameters.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Construct the protocol object
+//
+FileProtocol::FileProtocol(Manager &mgr) : Protocol(mgr, "file")
+{
+}
+
+
+//
+// Create a Transfer object for our protocol
+//
+FileProtocol::FileTransfer *FileProtocol::makeTransfer(const Target &target, Operation operation)
+{
+    switch (operation) {
+    case download:
+        return new Reader(*this, target);
+        break;
+    case upload:
+        return new Writer(*this, target);
+    default:
+        Error::throwMe();
+    }
+}
+
+
+FileProtocol::FileTransfer::FileTransfer(FileProtocol &proto, const Target &tgt, Operation op)
+    : Transfer(proto, tgt, op)
+{
+}
+
+int FileProtocol::FileTransfer::fileDesc() const
+{ return *this; }
+
+
+void FileProtocol::FileTransfer::transitError(const CssmCommonError &error)
+{
+    fail();
+}
+
+
+//
+// Read transfers
+//
+FileProtocol::Reader::Reader(FileProtocol &proto, const Target &tgt) 
+    : FileTransfer(proto, tgt, download)
+{
+}
+
+void FileProtocol::Reader::start()
+{
+    open(target.path.c_str());
+
+     // notify any observer that we are under way.
+     observe(Observer::resourceFound);
+    observe(Observer::downloading);
+    
+	setFlag(O_NONBLOCK);
+    int restartOffset = getv<int>(kNetworkRestartPosition, 0);
+    if (restartOffset)
+        seek(restartOffset);
+    size_t size = fileSize() - restartOffset;
+    mode(sink(), size);
+    sink().setSize(size);
+    protocol.manager.addIO(this);
+}
+
+void FileProtocol::Reader::transit(Event event, char *, size_t)
+{
+    assert(event == autoReadDone);
+    protocol.manager.removeIO(this);
+    finish();
+}
+
+
+//
+// Write transfers
+//
+FileProtocol::Writer::Writer(FileProtocol &proto, const Target &tgt)
+    : FileTransfer(proto, tgt, upload)
+{
+}
+
+void FileProtocol::Writer::start()
+{
+    open(target.path.c_str(), O_WRONLY | O_CREAT);
+    
+    // notify any observer that we are under way.
+    observe(Observer::resourceFound);
+    observe(Observer::uploading);
+    
+    int restartOffset = getv<int>(kNetworkRestartPosition, 0);
+    if (restartOffset)
+        seek(restartOffset);
+    protocol.manager.addIO(this);
+    disable(input);
+    mode(source(), fileSize() - restartOffset);
+}
+
+void FileProtocol::Writer::transit(Event event, char *, size_t)
+{
+    assert(event == autoWriteDone);
+    protocol.manager.removeIO(this);
+    finish();
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/file-protocol.h b/Network/file-protocol.h
new file mode 100644
index 00000000..3280b15e
--- /dev/null
+++ b/Network/file-protocol.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+//
+// file-protocol - FILE protocol objects
+//
+#ifndef _H_FILE_PROTOCOL
+#define _H_FILE_PROTOCOL
+
+#include "transfer.h"
+#include "xfercore.h"
+#include "protocol.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// The Protocol object for the file (local file access) protocol
+//
+class FileProtocol : public Protocol {
+    class FileTransfer;
+public:
+    FileProtocol(Manager &mgr);
+    
+    FileTransfer *makeTransfer(const Target &target, Operation operation);
+    
+private:
+    class FileTransfer : public Transfer, protected TransferEngine::Client, protected FileDesc {
+    public:
+        FileTransfer(FileProtocol &proto, const Target &tgt, Operation op);
+        void transitError(const CssmCommonError &error);
+        int fileDesc() const;
+    };
+    
+    class Reader : public FileTransfer {
+    public:
+        Reader(FileProtocol &proto, const Target &tgt);
+        void transit(Event event, char *input, size_t inputLength);
+        
+    protected:
+        void start();
+    };
+    
+    class Writer : public FileTransfer {
+    public:
+        Writer(FileProtocol &proto, const Target &tgt);
+        void transit(Event event, char *input, size_t inputLength);
+        
+    protected:
+        void start();
+    };
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_FILE_PROTOCOL
diff --git a/Network/ftp-protocol.cpp b/Network/ftp-protocol.cpp
new file mode 100644
index 00000000..9e2a87fc
--- /dev/null
+++ b/Network/ftp-protocol.cpp
@@ -0,0 +1,566 @@
+/*
+ * 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.
+ */
+
+
+//
+// ftp-protocol - FTP protocol objects
+//
+// Basic design notes:
+// FTPConnection and FTPDataConnection are mildly incestuous. An FTPConnection
+// *contains* an FTPDataConnection to manage its data channel during transfers.
+// It could *be* an FTPDataConnection, but they are both TransferEngine::TCPClients,
+// which would make coding awkward and mistake prone.
+// During wrap-up of a transfer, the control and data channels must synchronize to
+// make sure they're both done. (Note that 226/250 replies do NOT guarantee that all
+// data has been received on the data path; network latency can hold back that data
+// for an arbitrarily long time (modulo TCP timeouts). Synchronization is achieved in
+// classic ping-pong fashion: FTPConnection calls FTPDataConnection::connectionDone()
+// to signal that it's side is done. The data connection calls FTPConnection::finish once
+// it knows they're both done (because FTPConnection told it about its side already).
+//
+// This version has support for simple FTP proxy operation, where the PASS argument
+// is of the form user@remote-host. FTPProxyProtocol uses this support to implement
+// FTP/FTP proxies.
+//
+// Limits on functionality:
+// Only stream mode is supported.
+// No EBCDIC support.
+//
+#include "ftp-protocol.h"
+#include "netparameters.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Construct the protocol object
+//
+FTPProtocol::FTPProtocol(Manager &mgr) : Protocol(mgr, "ftp")
+{
+}
+
+
+//
+// Create a Transfer object for our protocol
+//
+FTPProtocol::FTPTransfer *FTPProtocol::makeTransfer(const Target &target, Operation operation)
+{
+    return new FTPTransfer(*this, target, operation);
+}
+
+
+//
+// Construct an FTPConnection object
+//
+FTPProtocol::FTPConnection::FTPConnection(Protocol &proto, const HostTarget &hostTarget)
+    : TCPConnection(proto, hostTarget), state(errorState), mImageMode(false),
+      mDataPath(*this)
+{
+    const HostTarget &host = proxyHostTarget();
+    connect(host.host(), host.port());
+    state = loginInitial;
+}
+
+
+//
+// Issue a request on the connection.
+//
+void FTPProtocol::FTPConnection::request(const char *path)
+{
+    assert(isDocked());
+    mOperationPath = path;
+    
+    if (state == idle)		// already (idly) at command prompt, so...
+        startCommand();					// ... start operation right now
+}
+
+void FTPProtocol::FTPConnection::startCommand()
+{
+    // notify any observer of the change in status
+    observe(Observer::resourceFound);
+    
+    switch (operation()) {
+    case makeDirectory:
+        printfe("MKD %s", mOperationPath.c_str());
+        state = directCommandSent;
+        return;
+    case removeDirectory:
+        printfe("RMD %s", mOperationPath.c_str());
+        state = directCommandSent;
+        return;
+    case genericCommand:
+        printfe("%s", mOperationPath.c_str());
+        state = directCommandSent;
+        return;
+    }
+    
+    // all other commands initiate data transfers. First, set appropriate mode
+    bool wantImageMode;
+    switch (operation()) {
+    case downloadDirectory:
+    case downloadListing:
+        wantImageMode = false;
+        break;
+    case download:
+    case upload:
+        wantImageMode = getv<string>(kNetworkFtpTransferMode, "I") == "I";
+        break;
+    default:
+        assert(false);
+    }
+    
+    // adjust transfer mode if needed
+    if (mImageMode != wantImageMode) {
+        printfe("TYPE %s", wantImageMode ? "I" : "A");
+        mImageMode = wantImageMode;		// a bit premature, but this shouldn't fail
+        state = typeCommandSent;
+        return;		// we'll be back here
+    } 
+    if (mPassive = getv<bool>(kNetworkFtpPassiveTransfers)) {
+        // initiate passive mode download
+        printfe("PASV");
+        state = passiveSent;
+    } else {
+        // initiate "active mode" (default mode) download.
+        // The cooking recipe for the host/port address is deliciously subtle. We obviously take
+        // the receiver's bound port. But in most cases, its address at this stage (passive bound)
+        // is ANY, and thus useless to the server. We pick the command connection's local
+        // address for completion. However, in SOME cases mReceiver.localAddress() has
+        // a meaningful value (SOCKS, for one), so we allow this to prevail if available.
+        mReceiver.open();		// open receiver and bind
+        FTPAddress addr(mReceiver.localAddress().defaults(localAddress()));
+        printfe("PORT %u,%u,%u,%u,%u,%u",
+            addr.h1, addr.h2, addr.h3, addr.h4, addr.p1, addr.p2);
+        state = portSent;
+    }
+}
+
+
+//
+// Initiate a data transfer (any direction or form) as indicated by mOperation.
+// mDataPath has already been set up.
+//
+void FTPProtocol::FTPConnection::startTransfer(bool restarted)
+{
+    if (!restarted)
+        if (int restartOffset = getv<int>(kNetworkRestartPosition, 0)) {
+            // restart requested - insert a REST command here
+            printfe("REST %d", restartOffset);
+            state = restartSent;
+            return;
+        }
+    
+    switch (operation()) {
+    case download:
+        printfe("RETR %s", mOperationPath.c_str());
+        break;
+    case downloadDirectory:
+        printfe("NLST %s", mOperationPath.c_str());
+        break;
+    case downloadListing:
+        printfe("LIST %s", mOperationPath.c_str());
+        break;
+    case upload:
+        printfe("%s %s",
+            getv<bool>(kNetworkFtpUniqueStores, false) ? "STOU" : "STOR",
+            mOperationPath.c_str());
+        break;
+    default:
+        assert(false);
+    }
+    state = transferSent;
+}
+
+
+//
+// This is the master state transit machine for FTP.
+//
+void FTPProtocol::FTPConnection::transit(Event event, char *input, size_t length)
+{
+    if (!isDocked()) {	// not docked; event while in Connection cache
+        abort();		// clean up
+        return;
+    }
+
+    switch (event) {
+    case connectionDone: // TCP connection complete or failed
+        {
+            int error = length;	// transmitted in the 'length' argument
+            observe(Observer::connectEvent, &error);
+            if (error)		// retry
+                connect();
+            else			// connection good
+                mode(lineInput);
+        }
+        return;
+    case inputAvailable:
+        {
+            restarting(false);	// valid input observed, commit to this Connection
+
+            // interpret input as FTP protocol reply, handling continued responses
+            observe(Observer::protocolReceive, input);
+            if (replyContinuation(input))
+                return;				// still continuing, keep reading
+            InetReply reply(input); // parse this reply
+            if (!reply.valid())		// don't know why, but we're dead
+                fail(input);
+            if (replyContinuation(reply))
+                return;				// is continuation now
+    
+            // dispatch state machine
+            switch (state) {
+            case loginInitial:
+                switch (reply) {
+                case 220:
+                    {
+                        string username = getv<string>(kNetworkGenericUsername,
+                            hostTarget.haveUserPass() ? hostTarget.username() : "anonymous");
+                        if (transfer().protocol.isProxy()) {
+                            char portPart[10];
+                            sprintf(portPart, ":%d", transfer().target.host.port());
+                            username += "@" + transfer().target.host.host().name() + portPart;
+                        }
+                        printfe("USER %s", username.c_str());
+                        state = loginUserSent;
+                        break;
+                    }
+                default:
+                    fail(input);
+                }
+                break;
+            case loginUserSent:
+                switch (reply) {
+                case 331:
+                    {
+                        string password = getv<string>(kNetworkGenericPassword,
+                            hostTarget.haveUserPass() ? hostTarget.password() : "anonymous@nowhere.net");
+                        printfe("PASS %s", password.c_str());
+                        state = loginPassSent;
+                        break;
+                    }
+                case 230:
+                    startCommand();
+                    break;
+                default:
+                    fail(input);
+                }
+                break;
+            case loginPassSent:
+                switch (reply) {
+                case 230:
+                    startCommand();
+                    break;
+                default:
+                    fail(input);
+                }
+                break;
+            case typeCommandSent:
+                switch (reply) {
+                case 200:
+                    startCommand();
+                    break;
+                default:
+                    fail(input);
+                }
+                break;
+            case passiveSent:
+                switch (reply) {
+                case 227:
+                    {
+                        // reply text =~ Entering passive mode (h1,h2,h3,h4,p1,p2)
+                        FTPAddress addr;
+                        if (const char *p = strchr(reply.message(), '(')) {
+                            if (sscanf(p, "(%u,%u,%u,%u,%u,%u)", 
+                                &addr.h1, &addr.h2, &addr.h3, &addr.h4, &addr.p1, &addr.p2) != 6)
+                                fail(input);
+                        } else if (const char *p = strstr(reply.message(), "mode")) {
+                            // RFC1123 says to be really nice to BROKEN FTP servers here
+                            if (sscanf(p+4, "%u,%u,%u,%u,%u,%u",
+                                &addr.h1, &addr.h2, &addr.h3, &addr.h4, &addr.p1, &addr.p2) != 6)
+                                fail(input);
+                        } else {
+                            fail(input);
+                            return;
+                        }
+                        mDataPath.open(addr);	//@@@ synchronous - move to state machine
+                        startTransfer();
+                    }
+                    break;
+                default:
+                    fail(input);
+                }
+                break;
+            case portSent:
+                switch (reply) {
+                case 200:	// PORT command successful
+                    startTransfer();
+                    break;
+                default:
+                    fail(input);
+                }
+                break;
+            case restartSent:
+                switch (reply) {
+                case 350:	// Restarting at ...
+                    startTransfer(true);	// now do the transfer command for real
+                    break;
+                default:
+                    fail(input);
+                }
+                break;
+            case transferSent:
+                switch (reply) {
+                case 150:
+                    if (!mPassive)
+                        mReceiver.receive(mDataPath);	// accept incoming connection and stop listening
+                    
+                    // engage the data path
+                    switch (operation()) {
+                    case download:
+                    case downloadDirectory:
+                    case downloadListing:
+                        mDataPath.start(sink());
+                        break;
+                    case upload:
+                        mDataPath.start(source());
+                        break;
+                    default:
+                        assert(false);
+                    }
+                    state = transferInProgress;
+                    break;
+                default:	// download command failed
+                    if (!mPassive)
+                        mReceiver.close();
+                    state = idle;
+                    fail();
+                    break;
+                }
+                break;
+            case transferInProgress:
+                switch (reply) {
+                case 226:	// transfer complete
+                    state = idle;	// idle command mode
+                    retain(true);
+                    mDataPath.connectionDone();
+                    break;
+                case 452:
+                    fail(input, ENOSPC);
+                    break;
+                default:	// transfer failed
+                    // (ignore any error in mDataPath - prefer diagnostics from remote)
+                    mDataPath.close();
+                    state = idle;
+                    fail(input);
+                    break;
+                }
+                break;
+                
+            case directCommandSent:
+                {
+                    switch (reply.type()) {
+                    case 2:
+                        retain(true);
+                        finish();
+                        break;
+                    default:
+                        fail();
+                        break;
+                    }
+                    state = idle;
+                }
+                break;
+                
+            default:
+                assert(false);
+            }
+        }
+        break;
+
+    case endOfInput:
+        return restart();			// try to restart, fail if we can't (or shouldn't)
+    default:
+        assert(false);
+    }
+}
+
+void FTPProtocol::FTPConnection::transitError(const CssmCommonError &error)
+{
+    //@@@ need to do much better diagnostics here
+    fail();		// fail transfer and discard connection
+}
+
+
+bool FTPProtocol::FTPConnection::validate()
+{
+    assert(state == idle);
+    tickle();
+    return state == idle;
+}
+
+
+//
+// The data connection object
+//
+void FTPProtocol::FTPDataConnection::start(Sink &sink)
+{
+    debug("ftp", "data connection starts download");
+    setup();
+    mode(sink);
+}
+
+void FTPProtocol::FTPDataConnection::start(Source &source)
+{
+    debug("ftp", "data connection starts upload");
+    setup();
+    mode(source);
+}
+
+void FTPProtocol::FTPDataConnection::setup()
+{
+    connection.protocol.manager.addIO(this);
+    mFailureStatus = noErr;			// okay so far
+    mConnectionDone = false;		// connection side not ready yet
+    mTransferDone = false;			// our side not ready net
+}
+
+int FTPProtocol::FTPDataConnection::fileDesc() const
+{
+    return *this;
+}
+
+void FTPProtocol::FTPDataConnection::transit(Event event, char *input, size_t length)
+{
+    assert(event == autoReadDone || event == autoWriteDone || event == endOfInput);
+    debug("ftp", "data transfer complete");
+    close();		// close data path
+    finish();		// proceed with state protocol
+}
+
+void FTPProtocol::FTPDataConnection::transitError(const CssmCommonError &error)
+{
+    mFailureStatus = error.osStatus();
+    close();		// close data path
+    finish();		// proceed with state protocol
+}
+
+void FTPProtocol::FTPDataConnection::close()
+{
+    if (isOpen()) {
+        connection.protocol.manager.removeIO(this);
+        TCPClientSocket::close();
+        mTransferDone = true;
+    }
+}
+
+void FTPProtocol::FTPDataConnection::connectionDone()
+{
+    mConnectionDone = true;
+    finish();
+}
+
+void FTPProtocol::FTPDataConnection::finish()
+{
+    if (mFailureStatus) {
+        connection.fail("data transfer failed", mFailureStatus);
+        connection.finish();
+    } else if (mTransferDone && mConnectionDone) {
+        connection.finish();
+    } else if (mConnectionDone) {
+        debug("ftp", "holding for data transfer completion");
+    } else {
+        debug("ftp", "holding for control message");
+    }
+}
+
+
+//
+// Transfer objects
+//
+FTPProtocol::FTPTransfer::FTPTransfer(Protocol &proto, const Target &tgt, Operation operation)
+    : Transfer(proto, tgt, operation, defaultFtpPort)
+{ }
+
+void FTPProtocol::FTPTransfer::start()
+{
+    FTPConnection *connection = protocol.manager.findConnection<FTPConnection>(target);
+    if (connection == NULL)
+        connection = new FTPConnection(protocol, target);
+                
+    connection->dock(this);
+    connection->request(target.path.c_str());
+}
+
+void FTPProtocol::FTPTransfer::abort()
+{
+    setError("aborted");
+    connectionAs<FTPConnection>().abort();
+}
+
+void FTPProtocol::FTPConnection::abort()
+{
+    close();
+    mDataPath.close();
+    fail();
+}
+
+
+Transfer::ResultClass FTPProtocol::FTPTransfer::resultClass() const
+{
+    switch (state()) {
+    case failed:
+        {
+            InetReply reply(errorDescription().c_str());
+            if (reply / 10 == 53)	// 53x - authentication failure
+                return authorizationFailure;
+      		// when in doubt, blame the remote
+            return remoteFailure;
+        }
+    case finished:
+        return success;
+    default:
+        assert(false);
+    }
+}
+
+
+//
+// Translate the ideosyncratic text form of FTP's socket addresses to and from the real thing
+//
+FTPProtocol::FTPAddress::FTPAddress(const IPSockAddress &sockaddr)
+{
+    uint32 addr = sockaddr.address();
+    h1 = addr >> 24;
+    h2 = (addr >> 16) & 0xFF;
+    h3 = (addr >> 8) & 0xFF;
+    h4 = addr & 0xFF;
+    p1 = sockaddr.port() >> 8;
+    p2 = sockaddr.port() & 0xFF;
+}
+
+FTPProtocol::FTPAddress::operator IPSockAddress() const
+{
+    assert(!(h1 & ~0xff) & !(h2 & ~0xff) & !(h3 & ~0xff) & !(h4 & ~0xff)
+        & !(p1 & ~0xff) & !(p2 & ~0xff));
+    return IPSockAddress(IPAddress(h1 << 24 | h2 << 16 | h3 << 8 | h4), p1 << 8 | p2);
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/ftp-protocol.h b/Network/ftp-protocol.h
new file mode 100644
index 00000000..287da2e4
--- /dev/null
+++ b/Network/ftp-protocol.h
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+
+
+//
+// ftp-protocol - FTP protocol objects
+//
+#ifndef _H_FTP_PROTOCOL
+#define _H_FTP_PROTOCOL
+
+#include "xfercore.h"
+#include "protocol.h"
+#include "transfer.h"
+#include "netconnection.h"
+#include "neterror.h"
+#include <Security/ip++.h>
+#include <Security/inetreply.h>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// The Protocol object for the FTP protocol
+//
+class FTPProtocol : public Protocol {
+    class FTPTransfer;
+    class FTPConnection;
+public:
+    static const IPPort defaultFtpPort = 21;
+
+    FTPProtocol(Manager &mgr);
+    
+public:
+    FTPTransfer *makeTransfer(const Target &target, Operation operation);
+    
+public:
+    // FTP-specific operation codes
+    enum {
+        downloadDirectory = protocolSpecific,	// get filename list (NLST)
+        downloadListing,						// get host-specific listing (LIST)
+        makeDirectory,							// make a directory (MKD)
+        removeDirectory,						// remove a directory (RMD)
+        genericCommand							// issue generic FTP command
+    };
+    
+private:
+    //
+    // The data connection object manages a data pipe (for one upload/download)
+    //
+    class FTPDataConnection : public TransferEngine::Client, public TCPClientSocket {
+    public:
+        FTPDataConnection(FTPConnection &conn) : connection(conn) { }
+
+        FTPConnection &connection;		// the main Connection we belong to
+
+        void start(Sink &sink);			// start download
+        void start(Source &source);		// start upload
+        void close();					// unconditional close
+        void connectionDone();			// Connection is done
+        
+        OSStatus status() const			{ return mFailureStatus; }
+        
+        int fileDesc() const;
+        
+    protected:
+        void transit(Event event, char *input, size_t inputLength);
+        void transitError(const CssmCommonError &error);
+        void setup();
+        void finish();
+    
+    private:
+        OSStatus mFailureStatus;		// noErr unless something went wrong
+        bool mTransferDone;				// our transfer is all done
+        bool mConnectionDone;			// our Connection is ready to finish()
+    }; 
+
+    //
+    // This is the persistent connection object.
+    //
+    class FTPConnection : public TCPConnection {
+        friend class FTPDataConnection;
+    public:
+        FTPConnection(Protocol &proto, const HostTarget &tgt);
+    
+        // state machine master state
+        enum State {
+            errorState,				// invalid state marker (reset or fail)
+
+            // login sub-engine
+            loginInitial,			// just connected [want hello or need-login]
+            loginUserSent,			// USER command sent [want hello or need-pass]
+            loginPassSent,			// PASS command sent [want dispatch command]
+
+            // idle state
+            idle,		// at command prompt, idle [nothing pending]
+            
+            // data transfer states
+            typeCommandSent,		// sent TYPE command [want ok]
+            passiveSent,			// sent PASV [want contact address]
+            portSent,				// sent PORT [want port ok]
+            restartSent,			// sent REST [want 350 Restarting...]
+            transferSent,			// sent RETR et al [want transfer starting]
+            transferInProgress,		// download in progress [want transfer complete]
+            
+            // misc. states
+            directCommandSent,		// sent non-transfer command, want success
+            
+            START = loginInitial
+        };
+        
+        FTPTransfer &transfer() { return transferAs<FTPTransfer>(); }
+        
+        void request(const char *path);
+        void abort();
+        
+    protected:
+        void transit(Event event, char *input, size_t inputLength);
+        void transitError(const CssmCommonError &error);
+        bool validate();
+
+        void startCommand();		// initiate mOperation, if any
+        void startTransfer(bool restarted = false);
+        
+        bool imageMode() const		{ return mImageMode; }
+        void imageMode(bool mode);
+        
+        void fail(const char *reply, OSStatus error = Transfer::defaultOSStatusError)
+        { setError(reply, error); Error::throwMe(error); }
+        void fail()		{ retain(false); Connection::fail(); }
+
+    protected:
+        State state;				// state engine state
+        InetReply::Continuation replyContinuation; // cotinued-reply marker
+
+        // state describing the ongoing connection
+        bool mImageMode;			// in image (vs. ascii) mode
+        bool mPassive;				// current transfer is in passive mode
+        
+        string mOperationPath;		// remote path for operation
+        
+        FTPDataConnection mDataPath; // subsidiary (data transfer) connection
+        TCPServerSocket mReceiver;	// incoming listen socket for active mode transfers
+    };
+    
+    //
+    //  The official Transfer object (for all kinds of transfers)
+    //
+    class FTPTransfer : public Transfer {
+    public:
+        FTPTransfer(Protocol &proto, const Target &target, Operation operation);
+        
+        ResultClass resultClass() const;
+        
+    protected:
+        void start();					// start me up
+        void abort();					// abort this Transfer
+        
+        string mFailedReply;			// reply string that triggered failure
+    };
+    
+private:
+    struct FTPAddress {
+        unsigned int h1, h2, h3, h4, p1, p2;
+        
+        FTPAddress() { }
+        FTPAddress(const IPSockAddress &addr);
+        operator IPSockAddress () const;
+    };
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_FTP_PROTOCOL
diff --git a/Network/ftp-proxy-protocol.cpp b/Network/ftp-proxy-protocol.cpp
new file mode 100644
index 00000000..9ce4ef34
--- /dev/null
+++ b/Network/ftp-proxy-protocol.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+//
+// ftp-proxy protocol: FTP variant for proxying
+//
+#include "ftp-proxy-protocol.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Construct the protocol object
+//
+FTPProxyProtocol::FTPProxyProtocol(Manager &mgr, const HostTarget &proxy)
+    : FTPProtocol(mgr), host(proxy.defaultPort(defaultFtpPort))
+{
+    debug("uaproxy", "%p ftp proxy for %s", this, host.urlForm().c_str());
+}
+
+
+//
+// Create a Transfer object for our protocol
+//
+FTPProxyProtocol::FTPTransfer *FTPProxyProtocol::makeTransfer(const Target &target,
+    Operation operation)
+{
+    return new FTPTransfer(*this, target, operation);
+}
+
+
+bool FTPProxyProtocol::isProxy() const
+{ return true; }
+
+const HostTarget &FTPProxyProtocol::proxyHost() const
+{ return host; }
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/ftp-proxy-protocol.h b/Network/ftp-proxy-protocol.h
new file mode 100644
index 00000000..9e8e9641
--- /dev/null
+++ b/Network/ftp-proxy-protocol.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+
+//
+// ftp-proxy protocol: FTP variant for application-level FTP proxying
+//
+// This version of an FTP proxy uses the "user@host" form of login name to express
+// proxying.
+//
+#ifndef _H_FTP_PROXY_PROTOCOL
+#define _H_FTP_PROXY_PROTOCOL
+
+#include "ftp-protocol.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// The protocol object for proxy FTP.
+// Since FTPProtocol contains code to support the proxy variant,
+// this Protocol object is quite trivial.
+//
+class FTPProxyProtocol : public FTPProtocol {
+public:
+    FTPProxyProtocol(Manager &mgr, const HostTarget &proxy);
+    
+    FTPTransfer *makeTransfer(const Target &target, Operation operation);
+    
+public:
+    bool isProxy() const;
+    const HostTarget &proxyHost() const;
+    
+private:
+    const HostTarget host;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_FTP_PROXY_PROTOCOL
diff --git a/Network/http-protocol.cpp b/Network/http-protocol.cpp
new file mode 100644
index 00000000..814d911e
--- /dev/null
+++ b/Network/http-protocol.cpp
@@ -0,0 +1,511 @@
+/*
+ * 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.
+ */
+
+
+//
+// http-protocol - HTTP protocol objects
+//
+// HTTP Transfers succeed (state() == finished) if the HTTP protocol was successfully
+// observed. This means that even 300/400/500 type results are "successful" as far
+// as state() is concerned. ResultClass() will attempt to classify both successful and
+// unsuccessful outcomes, and errorDescription() is the primary HTTP response line
+// (HTTP/1.n ccc some-string). HTTP Transfers fail (state() == failed) only if they can't
+// talk to the server, or a protocol violation (or unimplemented feature) is detected.
+// Deal with it.
+//
+// Note that the protected flag deferSendRequest allows the state sequencer to be
+// interrupted at the idle stage (before an HTTP request is sent over the virtual wire).
+// This is used by the https protocol driver to "wedge in" the SSL negotiation. Not very
+// elegant, but it works.
+//
+// This implementation of the http protocol includes http proxy operation. As a result,
+// it is very important to distinguish the various HostTargets and Targets involved:
+//	Connection::hostTarget is the host we're talking to - it could be a proxy.
+//	Transfer::target.host is the host we're trying to reach.
+// From the HTTPConnection's point of view:
+//	hostTarget may be a proxy or the destination
+//	target().host is always the host we're trying to reach
+// If we're not in proxy mode, these two are usually the same (caveat tester).
+//
+#include "http-protocol.h"
+#include "netparameters.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Construct the protocol object
+//
+HTTPProtocol::HTTPProtocol(Manager &mgr, const char *scheme) : Protocol(mgr, scheme)
+{
+}
+
+
+//
+// Create a Transfer object for our protocol
+//
+HTTPProtocol::HTTPTransfer *HTTPProtocol::makeTransfer(const Target &target, Operation operation)
+{
+    return new HTTPTransfer(*this, target, operation, defaultHttpPort);
+}
+
+
+//
+// Construct an HTTPConnection object
+//
+HTTPProtocol::HTTPConnection::HTTPConnection(Protocol &proto,
+    const HostTarget &hostTarget)
+    : TCPConnection(proto, hostTarget),
+    state(errorState), deferSendRequest(false)
+{
+    const HostTarget &host = proxyHostTarget();
+    connect(host.host(), host.port());
+    state = connecting;
+}
+
+
+//
+// Start a request/response transaction on this Connection. This puts out all the
+// HTTP request headers in one fell swoop (but not any request body).
+// The Connection must be in idle state.
+//
+void HTTPProtocol::HTTPConnection::request(const char *operation)
+{
+    mOperation = operation;
+    if (state == idle)	// already waiting for request
+        sendRequest();
+}
+
+void HTTPProtocol::HTTPConnection::sendRequest()
+{
+    assert(state == idle);
+
+    flushOutput(false);	// hold output until we're done
+    const Target &target = this->target();
+    if (transfer().useProxyHeaders()) {
+        printfe("%s %s HTTP/1.1",
+            mOperation.c_str(), target.urlForm().c_str());
+        authorizationHeader("Proxy-Authorization", hostTarget,
+            kNetworkGenericProxyUsername, kNetworkGenericProxyPassword);
+    } else {
+        printfe("%s %s HTTP/1.1", mOperation.c_str(), target.path.c_str());
+    }
+    hostHeader();
+    authorizationHeader("Authorization", target,
+        kNetworkGenericUsername, kNetworkGenericPassword);
+    printfe("User-Agent: %s",
+        getv<string>(kNetworkHttpUserAgent, "MacNetwork/1.0 (Macintosh)").c_str());
+        
+    // if restarting, add a Range header
+    if (int restartOffset = getv<int>(kNetworkRestartPosition, 0)) {
+        printfe("Range: bytes=%d-", restartOffset);
+    }
+    
+    // add other headers set by caller, if any
+    {
+        string otherHeaders;
+        if (get(kNetworkHttpMoreHeaders, otherHeaders)) {
+            // launder and rinse - don't let the caller screw up the HTTP header structure
+            static const char lineEndings[] = "\r\n";
+            const char *p = otherHeaders.c_str();
+            while (const char *q = strpbrk(p, lineEndings)) {
+                if (q > p)
+                    printfe("%.*s", q - p, p);
+                p = q + strspn(q, lineEndings);
+            }
+            // now send any last (unterminated) line
+            if (*p)
+                printfe("%s", p);
+        }
+    }
+
+    // add fields used for upstream transfer, if any, and initiate
+    if (transfer().hasSource()) {
+        Source &source = transfer().source();
+        size_t size = source.getSize();
+        if (size == Source::unknownSize) {
+            //@@@ try to use Transfer-encoding: chunked -- for now, just use EOF delimiting
+        } else {
+            printfe("Content-length: %ld", size);
+        }
+        printfe("");					// end of headers
+        mode(source);					// initiate autoWrite mode
+    } else {
+        printfe("");					// end of headers, no data
+    }
+
+    flushOutput();						// release pent-up output
+    mode(lineInput);					// line input mode
+    state = primaryResponse;			// prime the state machine
+}
+
+void HTTPProtocol::HTTPConnection::hostHeader()
+{
+    const HostTarget &host = target().host;
+    if (host.port())
+        printfe("Host: %s:%d", host.host().name().c_str(), host.port());
+    else
+        printfe("Host: %s", host.host().name().c_str());
+}
+
+void HTTPProtocol::HTTPConnection::authorizationHeader(const char *headerName,
+    const HostTarget &host,
+    ParameterSource::Key userKey, ParameterSource::Key passKey)
+{
+    string username = host.haveUserPass() ? host.username() : getv<string>(userKey);
+    string password = host.haveUserPass() ? host.password() : getv<string>(passKey);
+    //@@@ only "Basic" authentication supported for now
+    if (!username.empty()) {
+        //@@@ ad-hoc Base64 encoding. Replace with suitable stream encoder when available
+        static const char alphabet[] = 
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+        string token = username + ":" + password;
+        char *buffer = new char[4 * token.length() / 3 + 2];	// just enough
+        const char *src = token.c_str(), *end = src + token.length();
+        char *outp = buffer;
+        while (src < end) {
+            uint32 binary = src[0] << 16;
+            if (src+1 < end)
+                binary |= src[1] << 8 | src[2];
+            *outp++ = alphabet[(binary >> 18) & 0x3F];
+            *outp++ = alphabet[(binary >> 12) & 0x3F];
+            *outp++ = (src+1 < end) ? alphabet[(binary >> 6) & 0x3F] : '=';
+            *outp++ = (src+2 < end) ? alphabet[binary & 0x3F] : '=';
+            src += 3;
+        }
+        *outp = '\0';
+        printfe("%s: Basic %s", headerName, buffer);
+        delete[] buffer;
+    }
+}
+
+
+//
+// This is the master state transit machine for HTTP.
+//
+void HTTPProtocol::HTTPConnection::transit(Event event, char *input, size_t length)
+{
+    switch (event) {
+    case autoWriteDone:	// ingore: it's asynchronous to our state machine
+        return;
+    case endOfInput:	// most of the time, this is a protocol error, so filter it out now
+        switch (state) {
+        case idle:
+        case readWholeBody:	// expected
+            break;
+        case primaryResponse: // Connection failed; restart it
+            return restart();
+        default:		// unexpected; fail
+            UnixError::throwMe(ECONNRESET);	// @@@ diagnostic?
+        }
+        break;
+    case connectionDone: // TCP connection complete or failed
+        {
+            assert(state == connecting);
+            int error = length;
+            observe(Observer::connectEvent, &error);
+            if (error) {	// retry
+                connect();
+            } else {		// connection good
+                state = idle;
+                if (!deferSendRequest) {	// (subclass wants to wedge in)
+                    mode(lineInput);
+                    sendRequest();
+                }
+            }
+        }
+        return;
+    default:
+        break;
+    }
+
+    switch (state) {
+    case primaryResponse:
+        {
+            assert(mode() == lineInput);
+            observe(Observer::protocolReceive, input);
+            transfer().httpResponse() = input;	// remember response for caller
+            // --> HTTP/major.minor status reason-phrase
+            int reasonPos;
+            if (sscanf(input, "HTTP/%d.%d %u %n",
+                    &httpVersionMajor, &httpVersionMinor,
+                    &transfer().httpResponseCode(), &reasonPos) != 3) {
+                // malformed response header
+                fail(Transfer::remoteFailure);
+            }
+            
+            if (httpVersionMajor != 1)	// wrong major protocol Version
+                fail(Transfer::remoteFailure);
+            if (httpVersionMinor < 0 || httpVersionMinor > 1)
+                fail(Transfer::remoteFailure);
+ 
+            // notify the URLAccess emulation that we have the result code
+            observe (Observer::resultCodeReady);
+            
+           // okay, we grok the version. We'll proceed for now reading headers etc.
+            state = readHeaders;
+            
+            // we got input from the server, so this Connection is now confirmed good
+            restarting(false);
+            break;
+        }
+    case readHeaders:
+        {
+            assert(mode() == lineInput);
+            if (length) {		// another header
+                headers().add(input);
+                observe(Observer::protocolReceive, input);
+            } else {			// end of headers
+                // we are now handling the transition from response headers to response body
+                observe(Observer::protocolReceive, "** END OF HEADER **");
+                
+                // Transfer-Encoding overrides Content-Length as per RFC2616 p.34
+                if (const char *encoding = headers().find("Transfer-Encoding")) {
+                    if (!strcasecmp(encoding, "chunked")) {
+                        // eat input in chunks
+                        state = chunkHeader;
+                        // mode remains lineInput
+                        break;
+                    } else if (!strcasecmp(encoding, "identity")) {
+                        // allowed and ignored
+                    } else {
+                        // unrecognized transfer-encoding
+                        fail(Transfer::remoteFailure);
+                    }
+                }
+                // no transfer-encoding (or transfer-encoding: identity): big gulp mode
+                if (const char *lengthArg = headers().find("Content-Length")) {
+                    size_t length = strtol(lengthArg, NULL, 10);
+                    sink().setSize(length);
+                    mode(sink(), length);
+                } else {
+                    mode(sink());
+                }
+                state = readWholeBody;
+            }
+            break;
+        }
+    case chunkHeader:
+        {
+            assert(mode() == lineInput);
+            // line should be (just) a hex number, sans "0x" prefix or spaces. Be strict
+            char *endOfMatch;
+            size_t chunkLength = strtol(input, &endOfMatch, 0x10);
+            if (length == 0 || endOfMatch == input) // no valid number
+                fail(Transfer::remoteFailure);
+            if (chunkLength) {
+                debug("http", "reading chunk of %ld bytes", chunkLength);
+                mode(sink(), chunkLength);
+                state = chunkDownload;
+            } else {
+                debug("http", "final chunk marker");
+                state = chunkTrailer;
+                observe(Observer::protocolReceive, "** END OF DATA **");
+            }
+            break;
+        }
+    case chunkGap:
+        {
+            assert(mode() == lineInput);
+            state = chunkHeader;
+            break;
+        }
+    case chunkTrailer:
+        {
+            assert(mode() == lineInput);
+            if (input[0] == '\0') {	// end of trailer
+                finish();
+            } else {
+                headers().add(input);
+                observe(Observer::protocolReceive, input);
+            }
+            break;
+        }
+    case chunkDownload:
+        {
+            assert(event == autoReadDone);
+            state = chunkGap;
+            mode(lineInput);
+            break;
+        }
+    case readWholeBody:
+        {
+            assert(event == autoReadDone || event == endOfInput);
+            finish();
+            break;
+        }
+    case idle:
+        {
+            // the only asynchronous event in idle mode is a connection drop
+            debug("http",
+                "event %d while idle; destroying connection", event);
+            abort();
+            state = dead;
+        }
+        break;
+    default:
+        assert(false);
+    }
+}
+
+void HTTPProtocol::HTTPConnection::transitError(const CssmCommonError &error)
+{
+    // note that fail(const char * [, OSStatus]) has already called setError
+    fail(true);		// fail transfer and throw out connection
+}
+
+
+void HTTPProtocol::HTTPConnection::finish()
+{
+    chooseRetain();			// shall we keep the Connection?
+    Connection::finish();	// finish this transfer
+    mode(lineInput);		// ensure valid input mode
+    state = idle;			// idle state
+}
+
+
+void HTTPProtocol::HTTPConnection::fail(bool forceDrop)
+{
+    if (forceDrop)
+        retain(false);		// drop the Connection
+    else
+        chooseRetain();		// perhaps keep it
+    Connection::fail();		// fail this transfer
+}
+
+
+bool HTTPProtocol::HTTPConnection::validate()
+{
+    assert(state == idle);
+    tickle();	// may change state
+    return state == idle;
+}
+
+
+void HTTPProtocol::HTTPConnection::chooseRetain()
+{
+    // figure out whether to stay alive
+    retain(strcasecmp(headers().find("Connection", "Keep"), "Close"));
+    //@@@ need to handle the HTTP/1.0 case    
+}
+
+
+//
+// Transfer objects
+//
+HTTPProtocol::HTTPTransfer::HTTPTransfer(Protocol &proto,
+    const Target &tgt, Operation operation, IPPort defaultPort)
+    : Transfer(proto, tgt, operation, defaultPort),
+      mResultClass(unclassifiedFailure)
+{
+}
+
+void HTTPProtocol::HTTPTransfer::start()
+{
+    // HTTP servers can serve both proxy requests and direct requests,
+    // and can be pooled based on that fact. Use proxy==target here.
+    const HostTarget &host = proxyHostTarget();
+    HTTPConnection *connection = protocol.manager.findConnection<HTTPConnection>(host);
+    if (connection == NULL)
+        connection = new HTTPConnection(protocol, host);
+    connection->dock(this);
+    startRequest();
+}
+
+void HTTPProtocol::HTTPTransfer::abort()
+{
+    setError("aborted");
+    connectionAs<HTTPConnection>().abort();
+}
+
+void HTTPProtocol::HTTPConnection::abort()
+{
+    close();
+    fail(true);
+}
+
+
+//
+// This lower-level request startup function can be called directly by children.
+//
+void HTTPProtocol::HTTPTransfer::startRequest()
+{
+    const char *defaultForm;
+    switch (operation()) {
+    case Protocol::upload:		defaultForm = "PUT"; break;
+    case Protocol::transaction:	defaultForm = "POST"; break;
+    default:					defaultForm = "GET"; break;
+    }
+    connectionAs<HTTPConnection>().request(getv<string>(kNetworkHttpCommand, defaultForm).c_str());
+}
+
+
+//
+// Determine whether we should use the proxy form of HTTP headers.
+// By default, this is true iff we are used by a proxy Protocol.
+// However, children may override this determination.
+//
+bool HTTPProtocol::HTTPTransfer::useProxyHeaders() const
+{
+    return protocol.isProxy();
+}
+
+Transfer::ResultClass HTTPProtocol::HTTPTransfer::resultClass() const
+{
+    switch (state()) {
+    case failed:
+        return mResultClass;
+    case finished:
+        {
+            if (mResultClass != unclassifiedFailure)
+                return mResultClass;	// preclassified
+            unsigned int code = httpResponseCode();
+            if (code == 401 || code == 407)	// auth or proxy auth required
+                return authorizationFailure;
+            else if (code / 100 == 2)			// success codes
+                return success;
+            else	// when in doubt, blame the remote end :-)
+                return remoteFailure;
+        }
+    default:
+        assert(false);
+        return localFailure;
+    }
+}
+
+
+void HTTPProtocol::HTTPTransfer::fail(ResultClass why, OSStatus how)
+{
+    mResultClass = why;
+    Error::throwMe(how);
+}
+
+
+//
+// Manage the HTTP version of a HeaderMap
+//
+void HTTPProtocol::HTTPHeaderMap::merge(string key, string &old, string newValue)
+{
+    // duplicates must be CSV type; concatenate (RFC 2616; section 4.2)
+    old = old + ", " + newValue;
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/http-protocol.h b/Network/http-protocol.h
new file mode 100644
index 00000000..09ffd3bd
--- /dev/null
+++ b/Network/http-protocol.h
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+
+//
+// http-protocol - HTTP protocol objects
+//
+#ifndef _H_HTTP_PROTOCOL
+#define _H_HTTP_PROTOCOL
+
+#include "neterror.h"
+#include "xfercore.h"
+#include "protocol.h"
+#include "transfer.h"
+#include "netconnection.h"
+#include <Security/ip++.h>
+#include <Security/headermap.h>
+#include <Security/inetreply.h>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// The Protocol object for the HTTP protocol
+//
+class HTTPProtocol : public Protocol {
+    class HTTPTransfer;
+public:
+    static const IPPort defaultHttpPort = 80;
+
+    HTTPProtocol(Manager &mgr, const char *scheme = "http");
+    
+public:
+    HTTPTransfer *makeTransfer(const Target &target, Operation operation);
+    
+private:
+    class HTTPHeaderMap : public HeaderMap {
+    public:
+        void merge(string key, string &old, string newValue);
+    };
+
+private:
+    //
+    // Our persistent connection object
+    //
+    class HTTPConnection : public TCPConnection {
+    public:
+        HTTPConnection(Protocol &proto, const HostTarget &tgt);
+    
+        // state machine master state
+        enum State {
+            errorState,				// invalid state marker
+            connecting,				// awaiting transport level connection
+            primaryResponse,		// read primary response line
+            readHeaders,			// read initial headers
+            readWholeBody,			// read basic body (Transfer-Encoding: identity)
+            
+            idle,					// between requests on persistent connection
+            dead,					// RIP
+            
+            // state submachine for Transfer-Encoding: chunked
+            chunkHeader,			// chunk header line (hex-length CRNL)
+            chunkDownload,			// data of chunk (read in autoReadInput mode)
+            chunkGap,				// empty line after chunk (now why did they do *that*?)
+            chunkTrailer,			// reading trailer header fields (why not :-)
+            
+            START = primaryResponse
+        };
+        
+        HTTPTransfer &transfer() { return transferAs<HTTPTransfer>(); }
+        HeaderMap &headers();
+        
+        void request(const char *operation);
+        void abort();
+        
+    protected:
+        void transit(Event event, char *input, size_t inputLength);
+        void transitError(const CssmCommonError &error);
+        void finish();
+        void fail(bool forceDrop = false);	// direct fail
+        void fail(Transfer::ResultClass why, OSStatus how = Transfer::defaultOSStatusError)
+        { transfer().fail(why, how); }	// use in transit(): setup, throws, gets caught, then fails
+        bool validate();
+        
+        void sendRequest();
+        void hostHeader();
+        void authorizationHeader(const char *headerName,
+            const HostTarget &host,
+            ParameterSource::Key userKey, ParameterSource::Key passKey);
+        void chooseRetain();
+
+    protected:
+        State state;						// master state machine switch
+        bool deferSendRequest;				// allows a subclass to interrupt state machine
+        string mOperation;					// requested HTTP operation
+        unsigned int httpVersionMajor;		// major version of peer
+        unsigned int httpVersionMinor;		// minor version of peer
+    };
+
+
+    //
+    // A generic Transfer object. All HTTP transfers are transactional (headers in, optional data in,
+    // headers out, optional data out), so there's no reason to distinguish subclasses.
+    //
+    class HTTPTransfer : public Transfer {
+    public:
+        HTTPTransfer(Protocol &proto, const Target &tgt, Operation operation, IPPort defaultPort);
+        
+        // access to HTTP-specific protocol details
+        string &httpResponse()		{ return mPrimaryResponseString; }
+        unsigned int &httpResponseCode() { return mPrimaryResponseCode; }
+        unsigned int httpResponseCode() const { return mPrimaryResponseCode; }
+        HeaderMap &httpHeaders()	{ return mHeaders; }
+        
+        void fail(ResultClass how, OSStatus err = defaultOSStatusError);
+        
+        // diagnostics
+        ResultClass resultClass() const;
+        
+        void startRequest();				// start request on our Connection
+        virtual bool useProxyHeaders() const; // should we use proxy form of request headers?
+ 
+    protected:
+        void start();						// start HTTP
+        void abort();						// abort the Transfer
+
+    private:
+        string mPrimaryResponseString;		// HTTP protocol first response line
+        unsigned int mPrimaryResponseCode;	// numeric response code
+        ResultClass mResultClass;			// explicit classification (unclassified if not set)
+        HTTPHeaderMap mHeaders;				// map of response headers
+    };
+};
+
+
+//
+// Deferred inlines
+//
+inline HeaderMap &HTTPProtocol::HTTPConnection::headers()
+{ return transfer().httpHeaders(); }
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_HTTP_PROTOCOL
diff --git a/Network/http-proxy-protocol.cpp b/Network/http-proxy-protocol.cpp
new file mode 100644
index 00000000..b35cb159
--- /dev/null
+++ b/Network/http-proxy-protocol.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+//
+// http-proxy protocol: HTTP variant for proxying
+//
+#include "http-proxy-protocol.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Construct the protocol object
+//
+HTTPProxyProtocol::HTTPProxyProtocol(Manager &mgr, const HostTarget &proxy)
+    : HTTPProtocol(mgr), host(proxy.defaultPort(defaultHttpPort))
+{
+    debug("uaproxy", "%p http proxy for %s", this, host.urlForm().c_str());
+}
+
+
+//
+// Create a Transfer object for our protocol
+//
+HTTPProxyProtocol::HTTPTransfer *HTTPProxyProtocol::makeTransfer(const Target &target,
+    Operation operation)
+{
+    return new HTTPTransfer(*this, target, operation, defaultHttpPort);
+}
+
+
+bool HTTPProxyProtocol::isProxy() const
+{ return true; }
+
+const HostTarget &HTTPProxyProtocol::proxyHost() const
+{ return host; }
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/http-proxy-protocol.h b/Network/http-proxy-protocol.h
new file mode 100644
index 00000000..c167ccc0
--- /dev/null
+++ b/Network/http-proxy-protocol.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+
+//
+// http-proxy protocol: HTTP variant for proxying
+//
+#ifndef _H_HTTP_PROXY_PROTOCOL
+#define _H_HTTP_PROXY_PROTOCOL
+
+#include "http-protocol.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// The protocol object for proxy HTTP.
+// Since HTTPProtocol contains code to support the proxy variant,
+// this Protocol object is quite trivial.
+//
+class HTTPProxyProtocol : public HTTPProtocol {
+public:
+    HTTPProxyProtocol(Manager &mgr, const HostTarget &proxy);
+    
+    HTTPTransfer *makeTransfer(const Target &target, Operation operation);
+    
+public:
+    bool isProxy() const;
+    const HostTarget &proxyHost() const;
+    
+private:
+    const HostTarget host;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_HTTP_PROXY_PROTOCOL
diff --git a/Network/https-protocol.cpp b/Network/https-protocol.cpp
new file mode 100644
index 00000000..13952c79
--- /dev/null
+++ b/Network/https-protocol.cpp
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+
+
+//
+// https-protocol - SSL based HTTP.
+//
+#include "https-protocol.h"
+#include "netparameters.h"
+
+
+
+namespace Security {
+namespace Network {
+
+//
+// Construct the protocol object
+//
+SecureHTTPProtocol::SecureHTTPProtocol(Manager &mgr) : HTTPProtocol(mgr, "https")
+{
+}
+
+
+//
+// Names and identifiers
+//
+const char *SecureHTTPProtocol::name() const
+{
+    return "http/ssl";
+}
+
+
+//
+// Create a Transfer object for our protocol
+//
+SecureHTTPProtocol::SecureHTTPTransfer *SecureHTTPProtocol::makeTransfer(const Target &target,
+    Operation operation)
+{
+    return new SecureHTTPTransfer(*this, target, operation, defaultHttpsPort);
+}
+
+
+//
+// Construct an HTTPConnection object
+//
+SecureHTTPProtocol::SecureHTTPConnection::SecureHTTPConnection(Protocol &proto,
+    const HostTarget &hostTarget)
+    : HTTPConnection(proto, hostTarget),
+    SecureTransport<Socket>(static_cast<TCPClientSocket &>(*this)),	// (CC pitfall)
+    deferStartSSL(false), sslActive(false)
+
+{
+    // HTTPConnection already set up everything for talking to the server
+    deferSendRequest = true;	// interrupt HTTP state machine after connecting state
+    sslState = sslConnecting;
+}
+
+SecureHTTPProtocol::SecureHTTPConnection::~SecureHTTPConnection()
+{
+}
+
+void SecureHTTPProtocol::SecureHTTPConnection::sslRequest()
+{
+    switch (sslState) {
+    case sslConnecting:		// new connection - wait for TL ready
+        break;
+    case sslConnected:		// already set; go ahead HTTP
+        transfer().startRequest();
+        break;
+    default:
+        assert(false);		// huh?
+    }
+}
+
+void SecureHTTPProtocol::SecureHTTPConnection::startSSL()
+{
+    assert(sslState == sslStartup);
+
+    // from now on, perform I/O through the SSL layer
+    sslActive = true;
+
+    // switch initially to raw input mode. Note that no input bytes will actually
+    // be delivered by our modified read() until SSL handshake is complete.
+    mode(rawInput);
+    
+    // configure the SSL session
+    allowExpiredCerts(getv<bool>(kNetworkHttpAcceptExpiredCerts, false));
+    allowUnknownRoots(getv<bool>(kNetworkHttpAcceptUnknownRoots, false));
+
+    // start SSL handshake
+    SSL::open();
+    assert(SSL::state() == kSSLHandshake);	// there is no chance that we could already be done
+    sslState = sslHandshaking;
+}
+
+
+//
+// Validate a connection retrieved from the cache
+//
+bool SecureHTTPProtocol::SecureHTTPConnection::validate()
+{
+    return HTTPConnection::validate() && SSL::state() == kSSLConnected;
+}
+
+
+//
+// Our state transit method controls only the initial SSL handshake.
+// Think of it as a "prefix" to the HTTP protocol state engine. Once the handshake
+// is complete, we hand off further state management to the HTTP machine.
+//
+void SecureHTTPProtocol::SecureHTTPConnection::transit(Event event, 
+    char *input, size_t inputLength)
+{
+    try {
+        switch (sslState) {
+        case sslConnecting:
+            HTTPConnection::transit(event, input, inputLength);
+            if (HTTPConnection::state == idle) { // transport level ready
+                sslState = sslStartup;
+                if (!deferStartSSL)
+                    startSSL();
+            }
+            return;
+        case sslHandshaking:
+            assert(event == inputAvailable);
+            SecureTransport<Socket>::open();	// advance handshake protocol
+            switch (SSL::state()) {
+            case kSSLHandshake:					// not yet done
+                return;
+            case kSSLConnected:					// ready for HTTP
+                sslState = sslConnected;
+                transfer().startRequest();
+                return;
+            default:
+                assert(false);	// can't happen - would have thrown
+            }
+        case sslConnected:
+            return HTTPConnection::transit(event, input, inputLength);
+        default:
+            assert(false);						// huh?
+        }
+
+        // if SSL fails, we have to abandon the Connection
+    } catch (CssmCommonError &err) {
+        setError("SSL failed", err.osStatus());
+        throw;
+    } catch (...) {
+        setError("SSL failed");
+        throw;
+    }
+}
+
+
+//
+// The I/O layer for SecureHTTPConnection objects.
+//
+size_t SecureHTTPProtocol::SecureHTTPConnection::read(void *data, size_t length)
+{
+    return sslActive ? SSL::read(data, length) : Socket::read(data, length);
+}
+
+size_t SecureHTTPProtocol::SecureHTTPConnection::write(const void *data, size_t length)
+{
+    return sslActive ? SSL::write(data, length) : Socket::write(data, length);
+}
+
+bool SecureHTTPProtocol::SecureHTTPConnection::atEnd() const
+{
+    return sslActive ? SSL::atEnd() : Socket::atEnd();
+}
+
+
+//
+// HTTPS Transfer objects.
+//
+SecureHTTPProtocol::SecureHTTPTransfer::SecureHTTPTransfer(Protocol &proto,
+    const Target &tgt, Operation operation, IPPort defPort) 
+    : HTTPTransfer(proto, tgt, operation, defPort)
+{
+}
+
+void SecureHTTPProtocol::SecureHTTPTransfer::start()
+{
+    SecureHTTPConnection *connection =
+        protocol.manager.findConnection<SecureHTTPConnection>(target);
+    if (connection == NULL)
+        connection = new SecureHTTPConnection(protocol, target);
+    connection->dock(this);
+    connection->sslRequest();
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/https-protocol.h b/Network/https-protocol.h
new file mode 100644
index 00000000..6b0a2477
--- /dev/null
+++ b/Network/https-protocol.h
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+
+//
+// https-protocol - SSL based HTTP
+//
+#ifndef _H_HTTPS_PROTOCOL
+#define _H_HTTPS_PROTOCOL
+
+#include "http-protocol.h"
+#include <Security/securetransport++.h>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// The protocol object for https.
+// This is heavily based on the HTTP protocol, which provides hooks to filter
+// the I/O channels to implement the crypto. Refer to HTTP for all the protocol
+// stuff.
+//
+class SecureHTTPProtocol : public HTTPProtocol {
+    class SecureHTTPTransfer;
+public:
+    static const IPPort defaultHttpsPort = 443;
+
+    SecureHTTPProtocol(Manager &mgr);
+    
+public:
+    const char *name() const;
+    SecureHTTPTransfer *makeTransfer(const Target &target, Operation operation);
+    
+private:
+    //
+    // Our persistent connection object
+    //
+    typedef SecureTransport<Socket> SSL;
+    
+    class SecureHTTPConnection : public HTTPConnection, protected SSL {
+    public:
+        SecureHTTPConnection(Protocol &proto, const HostTarget &tgt);
+        ~SecureHTTPConnection();
+        
+        void sslRequest();
+        
+    protected:
+        enum {
+            sslConnecting,			// awaiting transport level connection
+            sslStartup,				// just connected
+            sslHandshaking,			// SSL handshake proceeding
+            sslConnected			// SSL established, I/O possible
+        } sslState;
+        
+        void transit(Event event, char *input, size_t inputLength);
+        void startSSL();
+        
+        bool validate();
+        
+    protected:
+        bool deferStartSSL;			// protocol break for sub-protocols
+        
+    private:
+        bool sslActive;				// using SSL for I/O
+        
+        // override I/O methods for TransferEngine::Client
+        size_t read(void *data, size_t length);
+        size_t write(const void *data, size_t length);
+        bool atEnd() const;
+    };
+
+
+    //
+    // A generic Transfer object. All HTTP transfers are transactional (headers in, optional data in,
+    // headers out, optional data out), so there's no reason to distinguish subclasses.
+    //
+    class SecureHTTPTransfer : public HTTPTransfer {
+    public:
+        SecureHTTPTransfer(Protocol &proto, 
+            const Target &tgt, Operation operation, IPPort defaultPort);
+            
+    protected:
+        void start();
+    };
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_HTTPS_PROTOCOL
diff --git a/Network/https-proxy-protocol.cpp b/Network/https-proxy-protocol.cpp
new file mode 100644
index 00000000..19020694
--- /dev/null
+++ b/Network/https-proxy-protocol.cpp
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+
+
+//
+// https-proxy - CONNECT style transparent proxy connection to SSL host.
+//
+// This is the CONNECT method of an ordinary (proxying) HTTP server.
+// Once it switches a connection to transparent proxying, there's no way to get out
+// again. Hence, our Connection objects belong to the remote host, not the proxy.
+//
+#include "https-proxy-protocol.h"
+#include "netparameters.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Construct the protocol object
+//
+ConnectHTTPProtocol::ConnectHTTPProtocol(Manager &mgr, const HostTarget &proxy)
+    : SecureHTTPProtocol(mgr), host(proxy.defaultPort(defaultHttpPort))
+{
+}
+
+
+//
+// Create a Transfer object for our protocol
+//
+ConnectHTTPProtocol::ConnectHTTPTransfer *ConnectHTTPProtocol::makeTransfer(const Target &target,
+    Operation operation)
+{
+    return new ConnectHTTPTransfer(*this, target, operation, defaultHttpsPort);
+}
+
+
+//
+// Construct an HTTPConnection object
+//
+ConnectHTTPProtocol::ConnectHTTPConnection::ConnectHTTPConnection(Protocol &proto,
+    const HostTarget &hostTarget)
+    : SecureHTTPConnection(proto, hostTarget)
+
+{
+    // SecureHTTPConnection already set up everything for talking to the server
+    connectState = connectConnecting;
+    deferStartSSL = true;	// tell parent protocol to break on connect-complete
+}
+
+ConnectHTTPProtocol::ConnectHTTPConnection::~ConnectHTTPConnection()
+{
+}
+
+
+//
+// Start a connection request
+//
+void ConnectHTTPProtocol::ConnectHTTPConnection::connectRequest()
+{
+    switch (connectState) {
+    case connectConnecting:
+        return;		// still waiting for TCP
+    case connectStartup:
+        {
+            const HostTarget &host = target().host;
+            flushOutput(false); // hold output
+            printfe("CONNECT %s:%d HTTP/1.1",
+                host.host().name().c_str(), target().host.port());
+            hostHeader();
+            authorizationHeader("Proxy-Authorization", hostTarget,
+                kNetworkGenericProxyUsername, kNetworkGenericProxyPassword);
+            printfe("");		// end of headers
+            flushOutput();		// flush accumulated output
+            mode(lineInput);
+            connectState = connectPrimaryResponse;
+        }
+        break;
+    case connectReady:			// already set; go ahead next layer (https)
+        sslRequest();
+        break;
+    default:
+        assert(false);			// huh?
+    }
+}
+
+
+//
+// Our state transit method controls only the initial SSL handshake.
+// Think of it as a "prefix" to the HTTP protocol state engine. Once the handshake
+// is complete, we hand off further state management to the HTTP machine.
+//
+void ConnectHTTPProtocol::ConnectHTTPConnection::transit(Event event, 
+    char *input, size_t inputLength)
+{
+    if (event == endOfInput && connectState != connectReady)
+        UnixError::throwMe(ECONNRESET);	// @@@ diagnostic?
+    
+    switch (connectState) {
+    case connectConnecting:
+        SecureHTTPConnection::transit(event, input, inputLength);
+        if (SecureHTTPConnection::sslState == sslStartup) { // transport level ready
+            connectState = connectStartup;
+            connectRequest();
+        }
+        return;
+    case connectPrimaryResponse:
+        {
+            // sketchily read proxy's primary response
+            int major, minor, code;
+            if (sscanf(input, "HTTP/%d.%d %u", &major, &minor, &code) != 3) {
+                fail(input);	// malformed response header
+            }
+            if (major != 1 || minor < 0 || minor > 1)
+                fail(input);
+            switch (code) {
+            case 200:		// okay, proceed
+                connectState = connectReadHeaders;
+                break;
+            default:		// this didn't work
+                transfer().httpResponse() = input;	// won't have a better one
+                fail(input);
+            }
+        }
+        break;
+    case connectReadHeaders:
+        {
+            if (inputLength) {
+                headers().add(input);
+            } else {
+                // end of proxy headers: start SSL now
+                connectState = connectReady;
+                try {
+                    startSSL();
+                } catch (CssmCommonError &err) {
+                    setError("SSL failed", err.osStatus());
+                    throw;
+                } catch (...) {
+                    setError("SSL failed");
+                    throw;
+                }
+            }
+        }
+        break;
+    case connectReady:
+        return SecureHTTPConnection::transit(event, input, inputLength);
+    default:
+        assert(false);						// huh?
+    }
+}
+
+
+//
+// HTTPS Transfer objects.
+//
+ConnectHTTPProtocol::ConnectHTTPTransfer::ConnectHTTPTransfer(Protocol &proto,
+    const Target &tgt, Operation operation, IPPort defPort) 
+    : SecureHTTPTransfer(proto, tgt, operation, defPort)
+{
+}
+
+void ConnectHTTPProtocol::ConnectHTTPTransfer::start()
+{
+    ConnectHTTPConnection *connection =
+        protocol.manager.findConnection<ConnectHTTPConnection>(target);
+    if (connection == NULL)
+        connection = new ConnectHTTPConnection(protocol, target);
+    connection->dock(this);
+    connection->connectRequest();
+}
+
+
+//
+// Even though this is formally a proxy protocol, we should not use
+// proxy headers, since the proxy is transparent and the remote system
+// expects a direct request.
+// 
+bool ConnectHTTPProtocol::ConnectHTTPTransfer::useProxyHeaders() const
+{
+    return false;
+}
+
+
+//
+// We are a proxy protocol
+//
+bool ConnectHTTPProtocol::isProxy() const
+{ return true; }
+
+const HostTarget &ConnectHTTPProtocol::proxyHost() const
+{ return host; }
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/https-proxy-protocol.h b/Network/https-proxy-protocol.h
new file mode 100644
index 00000000..56617969
--- /dev/null
+++ b/Network/https-proxy-protocol.h
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+
+//
+// https-proxy - CONNECT style transparent proxy connection to SSL host
+//
+#ifndef _H_HTTPS_PROXY_PROTOCOL
+#define _H_HTTPS_PROXY_PROTOCOL
+
+#include "https-protocol.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// The CONNECT protocol is a subclass of the secure (SSL) HTTP protocol.
+//
+class ConnectHTTPProtocol : public SecureHTTPProtocol {
+    class ConnectHTTPTransfer;
+public:
+    ConnectHTTPProtocol(Manager &mgr, const HostTarget &proxy);
+    
+public:
+    ConnectHTTPTransfer *makeTransfer(const Target &target, Operation operation);
+    
+private:
+    //
+    // Our persistent connection object
+    //
+    class ConnectHTTPConnection : public SecureHTTPConnection {
+    public:
+        ConnectHTTPConnection(Protocol &proto, const HostTarget &tgt);
+        ~ConnectHTTPConnection();
+        
+        enum {
+            connectConnecting,			// TCP layer connecting pending
+            connectStartup,				// starting conversation
+            connectPrimaryResponse,		// sent CONNECT, waiting for primary response
+            connectReadHeaders,			// reading proxy headers
+            connectReady				// in transparent mode
+        } connectState;
+        
+        void connectRequest();
+        
+    protected:
+        void transit(Event event, char *input, size_t inputLength);
+    };
+
+
+    //
+    // A generic Transfer object. All HTTP transfers are transactional (headers in, optional data in,
+    // headers out, optional data out), so there's no reason to distinguish subclasses.
+    //
+    class ConnectHTTPTransfer : public SecureHTTPTransfer {
+    public:
+        ConnectHTTPTransfer(Protocol &proto, 
+            const Target &tgt, Operation operation, IPPort defaultPort);
+            
+    protected:
+        void start();
+        
+        bool useProxyHeaders() const;
+    };
+    
+public:
+    bool isProxy() const;
+    const HostTarget &proxyHost() const;
+    
+private:
+    const HostTarget host;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_HTTPS_PROXY_PROTOCOL
diff --git a/Network/multiobserver.cpp b/Network/multiobserver.cpp
new file mode 100644
index 00000000..032204c8
--- /dev/null
+++ b/Network/multiobserver.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+
+//
+// multiobserver - Observer multiplexer
+//
+#include "multiobserver.h"
+
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Manage the observer set
+//
+void MultiplexObserver::add(Observer &obs)
+{
+    mObservers.insert(&obs);
+    Observer::setEvents(getEvents() | obs.getEvents());
+}
+
+void MultiplexObserver::remove(Observer &obs)
+{
+    mObservers.erase(&obs);
+    setEvents();
+}
+
+
+//
+// (Re)calculate the event mask
+//
+void MultiplexObserver::setEvents()
+{
+    Events eventSet = noEvents;
+    for (set<Observer *>::const_iterator it = mObservers.begin(); it != mObservers.end(); it++)
+        eventSet |= (*it)->getEvents();
+    Observer::setEvents(eventSet);
+}
+
+
+//
+// Fan out an observation
+//
+void MultiplexObserver::observe(Events events, Transfer *xfer, const void *info)
+{
+    for (set<Observer *>::const_iterator it = mObservers.begin(); it != mObservers.end(); it++)
+        if ((*it)->wants(events))
+            (*it)->observe(events, xfer, info);
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/multiobserver.h b/Network/multiobserver.h
new file mode 100644
index 00000000..a0ad9423
--- /dev/null
+++ b/Network/multiobserver.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+
+//
+// multiobserver - Observer multiplexer
+//
+#ifndef _H_MULTIPLEXOBSERVER
+#define _H_MULTIPLEXOBSERVER
+
+#include <Security/observer.h>
+#include <set>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// A MultipexObserver can be used to "fan out" events to any number of Observers.
+// Note that we do not keep an ordering of Observers.
+//
+class MultiplexObserver : public Observer {
+public:
+    MultiplexObserver();
+    
+    void add(Observer &obs);
+    void remove(Observer &obs);
+    bool contains(Observer &obs);
+    
+    // call setEvents() if one of the member Observers changes its event set
+    // Note: this disallows setEvents(Events) on purpose
+    void setEvents();
+    
+    void add(Observer *obs)		{ assert(obs); add(*obs); }
+    void remove(Observer *obs)	{ assert(obs); remove(*obs); }
+    
+    void observe(Events events, Transfer *xfer, const void *info);
+
+private:
+    set<Observer *> mObservers;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_MULTIPLEXOBSERVER
diff --git a/Network/netconnection.cpp b/Network/netconnection.cpp
new file mode 100644
index 00000000..f3edb070
--- /dev/null
+++ b/Network/netconnection.cpp
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+
+//
+// connection - a (potentially) persistent access path to a (possibly :-) remote entity
+//
+#include "netconnection.h"
+#include "protocol.h"
+#include "netmanager.h"
+#include "transfer.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Create a Connection object for a particular Protocol and HostTarget.
+// Note that these two arguments are potentially unrelated; in general,
+// you can't assume that &proto == &host.protocol().
+//
+Connection::Connection(Protocol &proto, const HostTarget &host)
+    : protocol(proto), hostTarget(host), mTransfer(NULL), mRetainMe(false), mRestarting(false)
+{
+    debug("netconn", 
+        "connection %p created for %s", this, hostTarget.urlForm().c_str());
+}
+
+
+//
+// Destroy a Connection, assuming it's idle.
+//
+Connection::~Connection()
+{
+    assert(!isDocked());
+    debug("netconn", "connection %p destroyed", this);
+}
+
+
+//
+// Dock the Connection to a Transfer.
+//
+void Connection::dock(Transfer *xfer)
+{
+    assert(!isDocked());
+    assert(!xfer->isDocked());
+    mTransfer = xfer;
+    xfer->mConnection = this;
+    debug("netconn", "connection %p docked xfer %p", this, xfer);
+}
+
+
+//
+// Undock the Connection from its currently docked Transfer.
+// The mRetainMe flag determines what happens next: we either
+// submit ourselves to our Manager for retention, or for cleanup.
+//
+void Connection::undock()
+{
+    // paranoia first
+    assert(isDocked());
+    assert(mTransfer->mConnection == this);
+    
+    // will we be kept?
+    bool retain = mRetainMe && mTransfer->shareConnections();
+    
+    // physically sever our relationship with the Transfer
+    debug("netconn", "connection %p undocking xfer %p", this, mTransfer);
+    mTransfer->mConnection = NULL;
+    mTransfer = NULL;
+
+    // submit ourselves to the manager for retention
+    if (retain)
+        protocol.manager.retainConnection(this);
+    else
+        protocol.manager.closeConnection(this);
+}
+
+
+//
+// Forwarders for finish/fail
+//
+void Connection::finish()
+{
+    assert(isDocked());
+    mTransfer->finish();
+}
+
+void Connection::fail()
+{
+    if (isDocked()) {
+        // fail the transfer we're docked to, which will undock us and dispose of us
+        mTransfer->fail();
+    } else {
+        // we failed while in limbo. Self-dispose
+        retain(false);
+        protocol.manager.closeConnection(this);
+    }
+}
+
+
+//
+// Drop the current Connection and re-execute start()
+//
+void Connection::restart()
+{
+    if (mRestarting) {
+        Transfer *transfer = mTransfer;
+        debug("netconn", "%p restarting xfer %p", this, transfer);
+        
+        // throw outselves out
+        retain(false);
+        undock();
+        
+        // restart the transfer
+        transfer->start();
+    } else {
+        // restart request on Connection that's not marked restarting.
+        // Presumably a real error, and we assume error indications have already
+        // been set (in the Transfer) by the caller as desired.
+        fail();
+    }
+}
+
+
+//
+// The default implementation of validate() does nothing and succeeds.
+//
+bool Connection::validate()
+{
+    return true;
+}
+
+
+//
+// The file descriptor of a TCPConnection is itself (as a TCPClientSocket)
+//
+int TCPConnection::fileDesc() const
+{
+    return *this;
+}
+
+
+//
+// The TCPConnection destructor will remove any remaining I/O hook
+//
+TCPConnection::~TCPConnection()
+{
+    close();
+}
+
+void TCPConnection::close()
+{
+    if (isOpen()) {
+        protocol.manager.removeIO(this);
+        TCPClientSocket::close();
+    }
+}
+
+
+//
+// Asynchronous connect processing for TCPClient subclasses.
+// The full call sets up data and initiates the first connect attempt; the second
+// form needs to be called on failure notification to (re)try other addresses.
+//
+void TCPConnection::connect(const Host &host, IPPort port)
+{
+    mAddressCandidates = host.addresses();
+    mPort = port;
+    nextCandidate();
+    protocol.manager.addIO(this);
+    mode(connecting);
+}
+
+void TCPConnection::connect()
+{
+    if (mAddressCandidates.empty()) {
+        // out of candidates. This connection attempt is failing
+        UnixError::throwMe(EHOSTUNREACH);
+    }
+
+    close();
+    nextCandidate();
+    protocol.manager.addIO(this);
+    mode(connecting);
+}
+
+void TCPConnection::nextCandidate()
+{
+    // pull the next address from the candidate set
+    std::set<IPAddress>::iterator it = mAddressCandidates.begin();
+    IPAddress addr = *it;
+    mAddressCandidates.erase(it);
+    
+    open(addr, mPort, O_NONBLOCK);
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/netconnection.h b/Network/netconnection.h
new file mode 100644
index 00000000..247d7abc
--- /dev/null
+++ b/Network/netconnection.h
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+
+//
+// connection - a (potentially) persistent access path to a (possibly :-) remote entity.
+//
+// Connection objects are the bearers of actual network (or other) I/O. They are distinct
+// from Transfers, which embody an individual activity for a particular client (and Target).
+// To do its stuff, a Transfer "docks" with a Connection, uses its resources, then "undocks"
+// and leaves the Connection free to dock again with another Transfer (or, eventually, expire).
+//
+// Access protocols that do not have persistent state connections (e.g. FILE) will not use
+// Connections at all; there is no requirement for a Transfer to use a Connection for its work.
+//
+// Actual Connection objects are specialized per protocol; for example, you'd expect
+// an HTTPTransfer to dock to an HTTPConnection. If you subclass an existing protocol,
+// you *may* be able to get away with using its Connection objects - but more often you'd
+// subclass them in turn.
+//
+#ifndef _H_NETCONNECTION
+#define _H_NETCONNECTION
+
+#include <Security/ip++.h>
+#include <Security/hosts.h>
+#include <Security/streams.h>
+#include "protocol.h"
+#include "target.h"
+#include "parameters.h"
+#include "transfer.h"
+#include <set>
+
+
+using namespace IPPlusPlus;
+
+
+namespace Security {
+namespace Network {
+
+
+class Manager;
+class Protocol;
+class Target;
+
+
+//
+// A generic Connection represents a semi-persistent channel of access to something
+// identified by a Target.
+//
+class Connection : public ParameterSource {
+    friend class Transfer;
+    friend class Manager;
+    typedef Protocol::Operation Operation;
+public:
+    Connection(Protocol &proto, const HostTarget &spec);
+    virtual ~Connection();
+    
+    Protocol &protocol;
+    const HostTarget hostTarget;
+    
+    // dock status
+    virtual void dock(Transfer *xfer);
+    virtual void undock();
+    bool isDocked() const		{ return mTransfer; }
+    
+    template <class XFer>
+    XFer &transferAs() const	{ assert(mTransfer); return *safe_cast<XFer *>(mTransfer); }
+    
+    // manage persistence
+    bool retain() const			{ return mRetainMe; }
+    void retain(bool r)			{ mRetainMe = r; }
+    
+    // see if we're still alive (after perhaps a delay)
+    virtual bool validate();
+    
+    // return our hostTarget or that of the proxy server, if any
+    const HostTarget &proxyHostTarget() const
+    { return protocol.isProxy() ? protocol.proxyHost() : hostTarget; }
+    
+protected:
+    Sink &sink() const				{ assert(isDocked()); return mTransfer->sink(); }
+    Source &source() const			{ assert(isDocked()); return mTransfer->source(); }
+    const Target &target() const	{ assert(isDocked()); return mTransfer->target; }
+    Operation operation() const		{ assert(isDocked()); return mTransfer->operation(); }
+    
+    ParameterSource *parameters()	{ assert(mTransfer); return mTransfer->parameters(); }
+    bool getParams(Key key, Value &value) const
+    { assert(mTransfer); return mTransfer->getParams(key, value); }
+    void observe(Observer::Event event, const void *info = NULL) const
+    { if (mTransfer) mTransfer->observe(event, info); }
+    
+    void setError(const char *s, OSStatus err = Transfer::defaultOSStatusError)
+    { if (mTransfer) mTransfer->setError(s, err); }
+    
+    void finish();
+    void fail();    
+    
+    virtual void restart();
+    void restarting(bool rs)		{ mRestarting = rs; }
+    bool restarting() const			{ return mRestarting; }
+    
+private:
+    Transfer *mTransfer;				// currently docked transfer (NULL if idle)
+    bool mRetainMe;						// want to be retained in connection pool
+    bool mRestarting;					// restart allowed
+};
+
+
+//
+// A Connection that is also a TransferAgent::Client.
+// This is a common case (but it isn't always true).
+//
+class TCPConnection : public Connection,
+        public TransferEngine::Client, public TCPClientSocket {
+public:
+    TCPConnection(Protocol &proto, const HostTarget &spec)
+    : Connection(proto, spec) { }
+    ~TCPConnection();
+    
+    // remove from I/O hooks and close
+    void close();
+
+    // manage asynchronous connection establishment
+    void connect(const Host &host, IPPort port);
+    void connect();
+
+    int fileDesc() const;
+    
+private:
+    std::set<IPAddress> mAddressCandidates;
+    IPPort mPort;
+    
+    void nextCandidate();
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_NETCONNECTION
diff --git a/Network/neterror.cpp b/Network/neterror.cpp
new file mode 100644
index 00000000..eae2d900
--- /dev/null
+++ b/Network/neterror.cpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+
+//
+// neterror - exception objects for Security::Network
+//
+#include "neterror.h"
+
+
+namespace Security {
+namespace Network {
+
+
+Error::Error(OSStatus err) : MacOSError(err)
+{
+}
+
+Error::~Error()
+{
+}
+
+void Error::throwMe(OSStatus err) { throw Error(err); }
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/neterror.h b/Network/neterror.h
new file mode 100644
index 00000000..165a5e74
--- /dev/null
+++ b/Network/neterror.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+
+//
+// neterror - exception objects for Security::Network
+//
+#ifndef _H_NETERROR
+#define _H_NETERROR
+
+#include <Security/utilities.h>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// We subordinate our error space to the CSSM exception model.
+// Our primary error space is that of MacOS OSStatus codes.
+//
+class Error : public Security::MacOSError {
+protected:
+	Error(OSStatus err);
+public:
+	virtual ~Error();
+    //@@@ -1 == internal error?!
+    static void throwMe(OSStatus err = -1) __attribute__((noreturn));
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_NETERROR
diff --git a/Network/netmanager.cpp b/Network/netmanager.cpp
new file mode 100644
index 00000000..433d9e95
--- /dev/null
+++ b/Network/netmanager.cpp
@@ -0,0 +1,294 @@
+/*
+ * 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.
+ */
+
+
+//
+// manager - network protocol core manager class
+//
+#include "netmanager.h"
+#include "protocol.h"
+#include "transfer.h"
+#include "netconnection.h"
+#include "neterror.h"
+
+
+namespace Security {
+namespace Network {
+
+
+Manager::Manager() : mActiveTransfers(0), mRetainConnections(true), mObserver(NULL)
+{
+}
+
+Manager::~Manager()
+{
+    //@@@ cleanup, s'il vous plait:
+    //@@@ abort transfers and destroy them
+    //@@@ notify any observers
+    //@@@ destroy protocol objects
+}
+
+
+//
+// Add a new Transfer to this Manager.
+// This does not start it; it'll just sit around until started.
+//
+void Manager::add(Transfer *xfer)
+{
+    assert(xfer->state() == Transfer::cold);
+    mTransfers.insert(xfer);
+    xfer->mState = Transfer::warm;
+}
+
+
+//
+// Remove a Transfer from this Manager.
+// You can remove a pre-active Transfer, or one that has finished or failed.
+// You can't remove an active Transfer - abort it first.
+//
+void Manager::remove(Transfer *xfer)
+{
+    assert(mTransfers.find(xfer) != mTransfers.end());	// is ours
+    assert(xfer->state() != Transfer::active);
+    mTransfers.erase(xfer);
+}
+
+
+//
+// Start a Transfer. It must already have been added, and must be in a pre-active state.
+//
+void Manager::start(Transfer *xfer)
+{
+    assert(mTransfers.find(xfer) != mTransfers.end());	// is ours
+    assert(xfer->state() == Transfer::warm);
+    try {
+        xfer->start();
+        xfer->mState = Transfer::active;
+        xfer->observe(Observer::transferStarting);
+        mActiveTransfers++;
+        debug("netmanager", "%ld active transfers", mActiveTransfers);
+    } catch (...) {
+        xfer->mState = Transfer::failed;
+        debug("netmanager", "Transfer %p failed to start", xfer);
+        throw;
+    }
+}
+
+
+//
+// Abort a Transfer.
+// If it is active, try to make it stop as soon as it's safe. This may return while
+// the Transfer's state is still active; it will eventually switch to failed unless it
+// happened to succeed before we got to it (in which case it'll be finished).
+// You can't abort a Transfer that isn't active.
+//@@@ Phasing problem? Perhaps aborting non-active Transfers should be
+//@@@ allowed (and ignored or flagged).
+//
+void Manager::abort(Transfer *xfer)
+{
+    assert(mTransfers.find(xfer) != mTransfers.end());	// is ours
+    switch (xfer->state()) {
+    case Transfer::active:
+        try {
+            debug("netmanager", "xfer %p request abort", xfer);
+            xfer->abort();
+        } catch (...) {
+            debug("netmanager", "xfer %p failed to abort; forcing the issue", xfer);
+            xfer->Transfer::abort();
+        }
+        break;
+    case Transfer::finished:
+    case Transfer::failed:
+        // no longer running; ignore cancel request
+        debug("netmanager", "xfer %p abort ignored (already done)", xfer);
+        break;
+    default:
+        assert(false);		// mustn't call in this state
+    }
+}
+
+
+//
+// Do bookkeeping for a Transfer that wants to be done.
+// This method can only be called from a Transfer that belongs
+// to this Manager and was started.
+//
+void Manager::done(Transfer *xfer)
+{
+    assert(mTransfers.find(xfer) != mTransfers.end());	// is ours
+    assert(xfer->state() == Transfer::finished || xfer->state() == Transfer::failed);
+    assert(mActiveTransfers > 0);
+    mActiveTransfers--;
+    debug("netmanager", "%ld active transfers", mActiveTransfers);
+}
+
+
+//
+// Manage engine clients on behalf of active Transfers.
+//@@@ Currently the API doesn't specify which Transfer these belong to.
+//@@@ Perhaps it should.
+//
+void Manager::addIO(TransferEngine::Client *client)
+{
+    mEngine.add(client);
+}
+
+void Manager::removeIO(TransferEngine::Client *client)
+{
+    mEngine.remove(client);
+}
+
+
+//
+// Manage Connections on behalf of Transfers (and perhaps Protocols)
+//
+void Manager::retainConnection(Connection *connection)
+{
+    if (mRetainConnections)
+        mConnections.retain(connection);
+    else
+        closeConnection(connection);
+}
+
+void Manager::closeConnection(Connection *connection)
+{
+    mConnections.remove(connection);
+    mMorgue.insert(connection);
+}
+
+
+//
+// Try to find a live retained Connection for a HostTarget and return it.
+//
+Connection *Manager::pickConnection(const HostTarget &host)
+{
+    while (Connection *connection = mConnections.get(host)) {
+        if (connection->validate()) {
+            connection->restarting(true);	// mark restarting
+            return connection;				// good to go
+        }
+        // if validate returned false, the connection has self-destructed (so ignore it)
+        debug("netmanager", "%p connection %p failed to validate",
+            this, connection);
+    }
+    return NULL;	// no joy, caller must make a new one
+}
+
+
+//
+// Handle the global Connection cache
+//
+void Manager::reuseConnections(bool retain)
+{
+    mRetainConnections = retain;
+}
+
+
+void Manager::flushConnections()
+{
+    mConnections.purge();
+}
+
+
+//
+// Timer management
+//
+void Manager::setTimer(Timer *timer, Time::Absolute when)
+{
+	mTimers.schedule(timer, when); 
+}
+	
+void Manager::clearTimer(Timer *timer)
+{
+	if (timer->scheduled())
+		mTimers.unschedule(timer); 
+}
+
+
+void Manager::runTimers()
+{
+    while (Timer *top = static_cast<Timer *>(mTimers.pop(Time::now()))) {
+        debug("netmanager", "%p timer %p executing at %.3f",
+            this, top, Time::now().internalForm());
+        try {
+            top->action();
+            debug("machsrvtime", "%p timer %p done", this, top);
+        } catch (...) {
+            debug("machsrvtime",
+                "%p server timer %p failed with exception", this, top);
+        }
+    }
+}
+
+
+//
+// Perform a (small) incremental operations step.
+//
+void Manager::step()
+{
+    prepare();
+    if (!mEngine.isEmpty()) {
+        debug("mgrstep", "operations step");
+        mEngine();
+    }
+}
+
+
+//
+// Run in this thread until a particular time (or until no more Transfers are active).
+//
+void Manager::run(Time::Absolute stopTime)
+{
+    debug("netmanager",
+		"starting run with %ld active transfers", mActiveTransfers);
+    while (mActiveTransfers > 0) {
+        prepare();
+        Time::Absolute limit = mTimers.empty() ? stopTime : min(stopTime, mTimers.next());
+        mEngine(limit - Time::now());
+        if (Time::now() > stopTime)
+            break;
+    }
+    debug("netmanager", "ending run");
+}
+
+void Manager::run()
+{
+    run(Time::heatDeath());
+}
+
+
+//
+// Internal stepper
+//
+void Manager::prepare()
+{
+    // clear the morgue
+    if (!mMorgue.empty()) {
+        debug("netmanager",
+            "clearing morgue of %ld connections", mMorgue.size());
+        for (set<Connection *>::iterator it = mMorgue.begin(); it != mMorgue.end(); it++)
+            delete *it;
+        mMorgue.erase(mMorgue.begin(), mMorgue.end());
+    }
+    
+    // run pending timers
+    runTimers();
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/netmanager.h b/Network/netmanager.h
new file mode 100644
index 00000000..e51426a3
--- /dev/null
+++ b/Network/netmanager.h
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+
+//
+// manager - network protocol core manager class
+//
+#ifndef _H_NETMANAGER
+#define _H_NETMANAGER
+
+#include <Security/ip++.h>
+#include <Security/timeflow.h>
+#include <Security/tqueue.h>
+#include "xfercore.h"
+#include "connectionpool.h"
+#include "target.h"
+#include "parameters.h"
+#include "observer.h"
+#include <set>
+#include <map>
+
+
+using namespace IPPlusPlus;
+
+
+namespace Security {
+namespace Network {
+
+
+class Protocol;
+class Transfer;
+class Connection;
+
+
+//
+// A Manager object represents the top-level operations controller.
+// You would usually only have one per process, though you *can*
+// have more than one - they would not interact at all, and each
+// Protocol, Transfer, etc. object could only belong to one of them.
+//
+class Manager : public ParameterPointer {
+public:
+    Manager();
+    virtual ~Manager();
+    
+public:
+    void add(Transfer *xfer);
+    void remove(Transfer *xfer);
+    void start(Transfer *xfer);
+    void abort(Transfer *xfer);
+    
+    Observer *observer() const			{ return mObserver; }
+    void observer(Observer *ob)			{ mObserver = ob; }
+    
+public:	// meant for just Transfer and Connection
+    void done(Transfer *xfer);
+    
+    void addIO(TransferEngine::Client *client);
+    void removeIO(TransferEngine::Client *client);
+    
+public:	// meant just for Connection
+    template <class ProtoConnection>
+    ProtoConnection *findConnection(const HostTarget &host)
+    { return safe_cast<ProtoConnection *>(pickConnection(host)); }
+
+    void retainConnection(Connection *connection);
+    void closeConnection(Connection *connection);
+    
+public:
+    void step();							// one small step for URLkind...
+    void run();								// run until no more work
+    void run(Time::Absolute upTo);			// run until some future time
+    
+public:
+    bool reuseConnections() const	{ return mRetainConnections; }
+    void reuseConnections(bool retain);		// global connection reuse override
+    void flushConnections();				// clear connection cache (expensive)
+
+public:
+	class Timer : private ScheduleQueue<Time::Absolute>::Event {
+        friend class Manager;
+	protected:
+		virtual ~Timer() { }
+        
+		Time::Absolute when() const	{ return Event::when(); }
+		bool scheduled() const		{ return Event::scheduled(); }
+	
+	public:
+		virtual void action() = 0;
+	};
+	
+	virtual void setTimer(Timer *timer, Time::Absolute when);
+	void setTimer(Timer *timer, Time::Interval offset)
+	{ setTimer(timer, Time::now() + offset); }
+
+	virtual void clearTimer(Timer *timer);
+    
+protected:
+    virtual void runTimers();				// run ready timers
+    virtual void prepare();					// setup for engine
+
+private:
+    void doStep();							// internal operative step
+    Connection *pickConnection(const HostTarget &host);
+
+private:
+    typedef map<string, Protocol *> ProtoMap;
+    ProtoMap mProtocols;					// map of registered protocols
+    
+private:
+    typedef set<Transfer *> TransferSet;
+    TransferSet mTransfers;					// set of active transfers (prelim)
+    uint32 mActiveTransfers;				// number of active transfers
+    
+private:
+    TransferEngine mEngine;					// transfer core engine
+    ConnectionPool mConnections;			// pool of retained (live) Connections
+    set<Connection *> mMorgue;				// Connections we should destroy
+    bool mRetainConnections;				// global connection-reuse enable
+    Observer *mObserver;					// default observer (NULL if none)
+    
+	ScheduleQueue<Time::Absolute> mTimers;	// timer queue
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_NETMANAGER
diff --git a/Network/netparameters.h b/Network/netparameters.h
new file mode 100644
index 00000000..135e01c0
--- /dev/null
+++ b/Network/netparameters.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+
+//
+// netparameters - ParameterSource keys for network protocol parameters
+//
+#ifndef _H_NETPARAMETERS
+#define _H_NETPARAMETERS
+
+#include "parameters.h"
+
+
+namespace Security {
+namespace Network {
+
+
+enum {
+    // generic (potentially applies to all protocols)
+    kNetworkGenericUsername			= PARAMKEY(0x00001,string), // username for simple auth
+    kNetworkGenericPassword			= PARAMKEY(0x00002,string),	// password for simple auths
+    kNetworkRestartPosition			= PARAMKEY(0x00003,integer), // byte position to restart from
+    
+    // generic but for proxy use only (all proxy protocols)
+    kNetworkGenericProxyUsername	= PARAMKEY(0x00100,string),	// username for proxy
+    kNetworkGenericProxyPassword	= PARAMKEY(0x00101,string),	// password for proxy
+
+    // FTP protocol specific
+    kNetworkFtpPassiveTransfers		= PARAMKEY(0x01001,bool),	// use passive mode transfers
+    kNetworkFtpTransferMode			= PARAMKEY(0x01002,string),	// transfer mode ("A" or "I")
+    kNetworkFtpUniqueStores			= PARAMKEY(0x01003,bool),	// request unique stores (STOU)
+
+    // HTTP/HTTPS protocol specific
+    kNetworkHttpCommand				= PARAMKEY(0x02001,string),	// access command (GET et al.)
+    kNetworkHttpUserAgent			= PARAMKEY(0x02002,string),	// User-Agent: value
+    kNetworkHttpMoreHeaders			= PARAMKEY(0x02003,string),	// arbitrary more headers
+    kNetworkHttpAcceptExpiredCerts	= PARAMKEY(0x02004,bool),	// accept expired certs
+    kNetworkHttpAcceptUnknownRoots	= PARAMKEY(0x02005,bool),	// accept untrusted root certificates
+    
+    // Legacy interface use ONLY. Not valid for modern use
+    kNetworkLegacyIsSecure			= PARAMKEY(0x100001,bool),	// secure connection (SSL)
+    kNetworkLegacyRespHeader		= PARAMKEY(0x100002,string), // collected response headers
+    kNetworkLegacyReqBody			= PARAMKEY(0x100003,data), // request body (in memory, as string)
+    
+    kNetworkLegacyResourceSize		= PARAMKEY(0x100004,integer),
+    kNetworkLegacyFileType			= PARAMKEY(0x100005,integer),
+    kNetworkLegacyFileCreator		= PARAMKEY(0x100006,integer),
+    kNetworkLegacyLastModifiedTime	= PARAMKEY(0x100007,integer),
+    kNetworkLegacyMIMEType			= PARAMKEY(0x100008,string),
+    kNetworkLegacyResourceName			= PARAMKEY(0x100009,string),
+    
+    // @@@ mistakenly added -- to be removed
+    kNetworkGenericURL				= PARAMKEY(0x00004,string),
+    kNetworkGenericHost				= PARAMKEY(0x00005,string)
+};
+
+
+}	// end namespace Security
+}	// end namespace Network
+
+#endif //_H_UAPARAMETERS
diff --git a/Network/networkchooser.cpp b/Network/networkchooser.cpp
new file mode 100644
index 00000000..9f11abb6
--- /dev/null
+++ b/Network/networkchooser.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+
+//
+// chooser - Protocol repository and Transfer maker for network protocols
+//
+#include "networkchooser.h"
+
+
+namespace Security {
+namespace Network {
+
+
+Chooser::Chooser(Manager &mgr) : manager(mgr)
+{
+}
+
+Chooser::~Chooser()
+{
+}
+
+
+//
+// Add, remove, and locate primary Protocols by name.
+//
+void Chooser::add(Protocol *protocol)
+{
+    //@@@ locking
+    Protocol * &proto = mCoreProtocols[protocol->urlPrefix()];
+    assert(proto == NULL);
+    proto = protocol;
+}
+
+void Chooser::remove(Protocol *protocol)
+{
+    ProtoMap::iterator it = mCoreProtocols.find(protocol->urlPrefix());
+    assert(it != mCoreProtocols.end());
+    mCoreProtocols.erase(it);
+}
+
+Protocol &Chooser::protocolFor(const char *protoName) const
+{
+    ProtoMap::const_iterator it = mCoreProtocols.find(protoName);
+    if (it == mCoreProtocols.end())
+        UnixError::throwMe(ENOENT);
+    return *it->second;
+}
+
+
+//
+// The default implementation of protocolFor just finds a direct-connection Protocol
+// for the target's scheme.
+//
+Protocol &Chooser::protocolFor(const HostTarget &target) const
+{
+    return protocolFor(target.scheme());
+}
+
+
+//
+// Here is a short-cut makeTransfer method.
+// It simply determines the proper Protocol, creates a Transfer from it, and adds it
+// to the Manager.
+// 
+Transfer *Chooser::makeTransfer(const Target &target, Operation operation)
+{
+    Protocol &protocol = protocolFor(target);
+    //@@@ use auto_ptr here?
+    Transfer *transfer = protocol.makeTransfer(target, operation);
+    manager.add(transfer);
+    return transfer;
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/networkchooser.h b/Network/networkchooser.h
new file mode 100644
index 00000000..66560b30
--- /dev/null
+++ b/Network/networkchooser.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+
+//
+// chooser - Protocol repository and Transfer maker for network protocols
+//
+#ifndef _H_CHOOSER
+#define _H_CHOOSER
+
+#include <Security/netmanager.h>
+#include <Security/protocol.h>
+#include <set>
+#include <map>
+
+
+using namespace IPPlusPlus;
+
+namespace Security {
+namespace Network {
+
+
+class Protocol;
+class Transfer;
+class Connection;
+
+
+//
+//
+class Chooser {
+    typedef Protocol::Operation Operation;
+public:
+    Chooser(Manager &mgr);
+    virtual ~Chooser();
+    
+    Manager &manager;
+    
+public:
+    // add and remove direct protocols
+    void add(Protocol *protocol);
+    void remove(Protocol *protocol);
+    Protocol &protocolFor(const char *protoName) const; // find protocol by URL scheme
+    
+public:
+    // override this method to implement protocol choosing
+    virtual Protocol &protocolFor(const HostTarget &target) const;
+    
+public:
+    Transfer *makeTransfer(const Target &target, Operation operation);
+    
+private:
+    typedef map<string, Protocol *> ProtoMap;
+    ProtoMap mCoreProtocols;					// map of registered protocols
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_CHOOSER
diff --git a/Network/observer.cpp b/Network/observer.cpp
new file mode 100644
index 00000000..5eabbd14
--- /dev/null
+++ b/Network/observer.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+
+//
+// observer - notification client for Network events
+//
+#include "observer.h"
+
+
+
+namespace Security {
+namespace Network {
+
+//
+// Blank virtual destructor
+//
+Observer::~Observer()
+{ }
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/observer.h b/Network/observer.h
new file mode 100644
index 00000000..d036f0b5
--- /dev/null
+++ b/Network/observer.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+
+//
+// observer - notification client for network events
+//
+#ifndef _H_OBSERVER
+#define _H_OBSERVER
+
+#include <Security/utilities.h>
+
+
+namespace Security {
+namespace Network {
+
+
+class Transfer;
+
+
+//
+// An Observer object has a set (bitmask) of events it is interested in.
+// Observers are registered with Transfer and Manager objects to take effect.
+//
+class Observer {
+public:
+    virtual ~Observer();
+    
+public:
+    enum {
+        noEvents						= 0x000000,		// mask for no events
+        transferStarting				= 0x000001,		// starting transfer operation
+        transferComplete				= 0x000002,		// successfully finished
+        transferFailed					= 0x000004,		// failed somehow
+        connectEvent					= 0x000800,		// transport level connection done or failed
+        protocolSend					= 0x001000,		// low-level protocol message sent
+        protocolReceive					= 0x002000,		// low-level protocol message received
+
+        //@@@ questionable
+        resourceFound					= 0x000008,		// resource found, OK to continue
+        downloading						= 0x000010,		// downloading in progress
+        aborting						= 0x000020,		// abort in progress
+        dataAvailable					= 0x000040,		// data ready to go
+        systemEvent						= 0x000080,		// ???
+        percentEvent					= 0x000100,		// a >= 1% data move has occurred
+        periodicEvent					= 0x000200,		// call every so often (.25 sec)
+        propertyChangedEvent			= 0x000400,
+        resultCodeReady					= 0x004000,		// result code has been received by HTTP
+        uploading						= 0x008000,		// uploading
+        
+        allEvents						= 0xFFFFFFFF	// mask for all events
+    };
+    typedef uint32 Event, Events;
+    
+    void setEvents(Events mask)		{ mEventMask = mask; }
+    Events getEvents() const		{ return mEventMask; }
+    bool wants(Events events) const	{ return mEventMask & events; }
+    
+    virtual void observe(Events events, Transfer *xfer, const void *info = NULL) = 0;
+    
+private:
+    Events mEventMask;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_OBSERVER
diff --git a/Network/parameters.cpp b/Network/parameters.cpp
new file mode 100644
index 00000000..d1b99eba
--- /dev/null
+++ b/Network/parameters.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+
+//
+// parameters - dynamic parameter retrieval interface
+//
+#include "parameters.h"
+#include <Security/debugging.h>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// ParameterStacks
+//
+bool ParameterStack::getParams(Key key, Value &value) const
+{
+    for (const_iterator it = begin(); it != end(); it++) {
+        if ((*it)->get(key, value))
+            return true;
+    }
+    return false;
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/parameters.h b/Network/parameters.h
new file mode 100644
index 00000000..a5671860
--- /dev/null
+++ b/Network/parameters.h
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+
+//
+// parameters - dynamic parameter retrieval interface
+//
+#ifndef _H_PARAMETERS
+#define _H_PARAMETERS
+
+#include <Security/typedvalue.h>
+#include <Security/debugging.h>
+#include <vector>
+#include <cstdarg>
+
+
+namespace Security {
+namespace Network {
+
+
+class ParameterSource {
+public:
+    // Keys are unsigned integers with integrated typing
+    typedef uint32 Key;
+    typedef GenericValue Value;
+    
+    enum {
+        integerKey = 1,		// int
+        stringKey = 2,		// string
+        boolKey = 3,		// bool
+        dataKey = 4			// ConstData
+    };
+#	define PARAMKEY(id,type)	((id) << 8 | (Security::Network::ParameterSource::type##Key))
+    inline int keyType(Key key) const		{ return key & 0xFF; }
+
+public:
+    virtual ~ParameterSource() { }
+    
+public:
+    // core form: this can be virtually overridden
+    virtual bool getParams(Key key, Value &value) const = 0;
+    
+    // convenience form: unwrap to Value base type
+    template <class T> bool get(Key key, T &result) const
+    {
+        TypedValue<T> value;
+        if (getParams(key, value)) {
+            result = value;
+            debug("paramsource", "%p key=0x%lx retrieved", this, key);
+            return true;
+        } else {
+            debug("paramsource", "%p key=0x%lx not found", this, key);
+            return false;
+        }
+    }
+
+    // convenience form: return value, use default if not found (no failure indication)
+    template <class T> T getv(Key key, T value = T()) const
+    {
+        get(key, value);		// overwrite value if successful
+        return value;			// then return it or remaining default
+    }
+};
+
+
+//
+// A ParameterPointer is a ParameterSource that has an indirection to another
+// ParameterSource. The underlying ("base") reference can be changed at will.
+// If it is NULL, all lookups fail.
+//
+class ParameterPointer : public ParameterSource {
+public:
+    ParameterPointer() : mBase(NULL) { }
+    ParameterPointer(ParameterSource *src) : mBase(src) { }
+
+    operator bool () const				{ return mBase; }
+    ParameterSource *parameters() const { return mBase; }
+    ParameterSource *parameters(ParameterSource *newBase)
+    { ParameterSource *old = mBase; mBase = newBase; return old; }
+    
+    ParameterSource *parameters(ParameterSource &newBase)
+    { return parameters(&newBase); }
+
+    bool getParams(Key key, Value &value) const
+    { return mBase && mBase->getParams(key, value); }
+
+private:
+    ParameterSource *mBase;				// where to get it from...
+};
+
+
+//
+// Here's an entire (ordered) "stack" of ParameterSources. Just build a vector
+// of pointers to ParameterSources, and have them searched in order.
+//
+class ParameterStack : public ParameterSource, public vector<ParameterSource *> {
+public:
+    bool getParams(Key key, Value &value) const;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_PARAMETERS
diff --git a/Network/protocol.cpp b/Network/protocol.cpp
new file mode 100644
index 00000000..cc263ac7
--- /dev/null
+++ b/Network/protocol.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+
+//
+// protocol - generic interface to an access protocol
+//
+#include "protocol.h"
+#include "netmanager.h"
+#include "neterror.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Construct and manage a Protocol object
+//
+Protocol::Protocol(Manager &mgr, const char *prefix) : manager(mgr), mPrefix(prefix)
+{
+}
+
+Protocol::~Protocol()
+{
+}
+
+
+//
+// By default, name() just returns the same as urlPrefix()
+//
+const char *Protocol::name() const
+{
+    return urlPrefix();
+}
+
+
+//
+// Default Transfer factory (fails)
+//
+Transfer *Protocol::makeTransfer(const Target &, Operation)
+{ Error::throwMe(); }
+
+
+//
+// Default to *not* a proxy protocol
+//
+bool Protocol::isProxy() const
+{ return false; }
+
+const HostTarget &Protocol::proxyHost() const
+{
+    assert(false);
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/protocol.h b/Network/protocol.h
new file mode 100644
index 00000000..e3dd0d02
--- /dev/null
+++ b/Network/protocol.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+//
+// protocol - generic interface to an access protocol
+//
+#ifndef _H_PROTOCOL
+#define _H_PROTOCOL
+
+#include <Security/ip++.h>
+#include "netmanager.h"
+
+using namespace IPPlusPlus;
+
+
+namespace Security {
+namespace Network {
+
+
+class Transfer;
+class Target;
+
+
+//
+// A Protocol object represents a particular transfer/access protocol.
+//
+class Protocol {
+public:
+    Protocol(Manager &mgr, const char *prefix = NULL);
+    virtual ~Protocol();
+
+    virtual const char *name() const;
+    const char *urlPrefix() const	{ return mPrefix ? mPrefix : "?"; }
+    
+    typedef unsigned int Operation;
+    enum {
+        download = 1,			// transfer data to sink
+        upload = 2,				// transfer data from source
+        transaction = 3,		// source-to-sink transaction mode
+        
+        protocolSpecific = 101	// starting here is protocol specific
+    };
+    
+    virtual Transfer *makeTransfer(const Target &target, Operation operation);
+    
+    Manager &manager;
+    
+public:
+    virtual bool isProxy() const;	// true if this is a proxy protocol
+    virtual const HostTarget &proxyHost() const; // proxy host if isProxy()
+
+private:
+    const char *mPrefix;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_PROTOCOL
diff --git a/Network/simplemanager.cpp b/Network/simplemanager.cpp
new file mode 100644
index 00000000..6b804460
--- /dev/null
+++ b/Network/simplemanager.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+//
+// simplemanager - "direct mode" network core manager
+//
+#include "simplemanager.h"
+#include "netparameters.h"
+#include <Security/url.h>
+
+#include "file-protocol.h"
+#include "ftp-protocol.h"
+#include "http-protocol.h"
+#include "https-protocol.h"
+
+
+namespace Security {
+namespace Network {
+
+
+SimpleManager::SimpleManager() : Chooser(static_cast<Manager &>(*this))
+{
+    add(new HTTPProtocol(*this));
+    add(new SecureHTTPProtocol(*this));
+    add(new FTPProtocol(*this));
+    add(new FileProtocol(*this));
+}
+
+
+//
+// Run all active transfers synchronously until complete.
+//
+void SimpleManager::allTransfersSynchronous()
+{
+    run();
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/simplemanager.h b/Network/simplemanager.h
new file mode 100644
index 00000000..ac61ede6
--- /dev/null
+++ b/Network/simplemanager.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+
+//
+// simplemanager - "direct mode" network core manager
+//
+#ifndef _H_SIMPLEMANAGER
+#define _H_SIMPLEMANAGER
+
+#include "netmanager.h"
+#include "networkchooser.h"
+#include <Security/streams.h>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// The Test manager class
+//
+class SimpleManager : public Manager, public Chooser {
+public:
+    SimpleManager();
+    
+#if BUG_GCC
+    void add(Transfer *xfer)		{ Manager::add(xfer); }
+    void add(Protocol *proto)		{ Chooser::add(proto); }
+#else
+    using Manager::add;
+    using Chooser::add;
+#endif
+    
+public:
+    void allTransfersSynchronous();
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_SIMPLEMANAGER
diff --git a/Network/target.cpp b/Network/target.cpp
new file mode 100644
index 00000000..31a764bd
--- /dev/null
+++ b/Network/target.cpp
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+//
+// target - target objects and their sub-components
+//
+#include "target.h"
+#include "protocol.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Produce a HostTarget with a default port inserted, if necessary.
+//
+HostTarget HostTarget::defaultPort(IPPort defPort) const
+{
+    return HostTarget(scheme(), host(), port(defPort), username(), password());
+}
+
+
+//
+// Given a Target, construct a canonical proper URL string
+//
+string HostTarget::urlForm() const
+{
+    // form the :port optional part
+    char portPart[10];
+    if (mPort)
+        sprintf(portPart, ":%d", mPort);
+    else
+        portPart[0] = '\0';
+        
+    // build the whole form
+    char buffer[1024];
+    if (haveUserPass()) {
+        snprintf(buffer, sizeof(buffer), "%s://%s:%s@%s%s",
+            scheme(), mUser.c_str(), mPassword.c_str(),
+            mHost.name().c_str(), portPart);
+    } else {
+        snprintf(buffer, sizeof(buffer), "%s://%s%s",
+            scheme(), mHost.name().c_str(), portPart);
+    }
+    return buffer;
+}
+
+string Target::urlForm() const
+{
+    return host.urlForm() + path;
+}
+
+
+bool HostTarget::operator == (const HostTarget &other) const
+{
+    return mScheme == other.mScheme
+        && mHost == other.mHost
+        && mPort == other.mPort
+        && mUser == other.mUser
+        && mPassword == other.mPassword;
+}
+
+bool HostTarget::operator < (const HostTarget &other) const
+{
+    // arbitrary lexicographic ordering
+    if (mScheme != other.mScheme)
+        return mScheme < other.mScheme;
+    if (mHost != other.mHost)
+        return mHost < other.mHost;
+    if (mPort != other.mPort)
+        return mPort < other.mPort;
+    if (mUser != other.mUser)
+        return mUser < other.mUser;
+    return mPassword < other.mPassword;
+}
+
+bool HostTarget::operator <= (const HostTarget &other) const
+{
+    //@@@ be lenient on subsume-matching empty users/passwords? Distinguish spec/unspec?
+    return mHost <= other.mHost
+        && mScheme == other.mScheme
+        && mPort == other.mPort
+        && mUser == other.mUser
+        && mPassword == other.mPassword;
+}
+
+bool Target::operator == (const Target &other) const
+{
+    return host == other.host && path == other.path;
+}
+
+bool Target::operator <= (const Target &other) const
+{
+    //@@@ be lenient on path matches? Usage?
+    return host <= other.host && path == other.path;
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/target.h b/Network/target.h
new file mode 100644
index 00000000..d1e94b33
--- /dev/null
+++ b/Network/target.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+
+//
+// target - target objects and their sub-components
+//
+#ifndef _H_TARGET
+#define _H_TARGET
+
+#include <Security/ip++.h>
+#include <Security/hosts.h>
+#include <set>
+
+
+namespace Security {
+namespace Network {
+
+using namespace IPPlusPlus;
+
+
+class Protocol;
+
+
+//
+// A HostTarget is the "host part" of a full access target.
+// HostTargets are suitable for use as keys in STL containers.
+//
+class HostTarget {
+public:
+    HostTarget(const char *scheme, Host h, IPPort p, string user = "", string password = "")
+        : mScheme(scheme), mHost(h), mPort(p), mUser(user), mPassword(password) { }
+        
+    const char *scheme() const	{ return mScheme.c_str(); }
+    const Host &host() const	{ return mHost; }
+    IPPort port(IPPort defaultPort = 0) const { return mPort ? mPort : defaultPort; }
+
+    //@@@ this should probably be replaced with pluggable authentication schemes
+    bool haveUserPass() const	{ return mUser != ""; }
+    string username() const		{ return mUser; }
+    string password() const		{ return mPassword; }
+    
+    bool operator == (const HostTarget &other) const;	// equality
+    bool operator < (const HostTarget &other) const;	// less-than for sorting
+    bool operator <= (const HostTarget &other) const;	// proper nonstrict subsumption
+    
+    HostTarget defaultPort(IPPort def) const;
+    
+    string urlForm() const;		// canonical URL prefix form (without /path postfix)
+
+private:
+    string mScheme;				// URL scheme
+    Host mHost;					// host name or number; no default
+    IPPort mPort;				// port number; zero to use protocol default
+    string mUser;				// username; default empty
+    string mPassword;			// password; default empty
+};
+
+
+//
+// Targets
+// Targets are suitable for use as keys in STL functions.
+//
+class Target {
+public:
+    Target(const HostTarget &theHost, const char *thePath) : host(theHost), path(thePath) { }
+    Target(const HostTarget &theHost, string thePath) : host(theHost), path(thePath) { }
+    Target(const char *scheme, Host h, IPPort p, const char *thePath) 
+        : host(scheme, h, p), path(thePath) { }
+    
+    bool operator == (const Target &other) const;
+    bool operator <= (const Target &other) const;
+    
+    operator const HostTarget &() const		{ return host; }
+    
+    string urlForm() const;		// construct canonical URL form
+    
+    const HostTarget host;
+    const string path;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_TARGET
diff --git a/Network/transfer.cpp b/Network/transfer.cpp
new file mode 100644
index 00000000..eeb6f7ca
--- /dev/null
+++ b/Network/transfer.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+
+//
+// transfer - the embodiment of a single transfer transaction
+//
+#include "transfer.h"
+#include "netmanager.h"
+#include "netconnection.h"
+#include "protocol.h"
+#include "neterror.h"
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Construct and destroy Transfer objects
+//
+Transfer::Transfer(Protocol &proto, const Target &tgt, Operation op, IPPort defPort)
+    : protocol(proto),
+      target(tgt.host.defaultPort(defPort), tgt.path),
+      mState(cold), mOperation(op), mConnection(NULL),
+      mSource(NULL), mSink(NULL),
+      mShareConnections(proto.manager.reuseConnections()),
+      mErrorStatus(defaultOSStatusError)
+{
+    debug("netxfer", "%p created for protocol %p(%s) target %s operation %d",
+        this, &proto, proto.name(), target.urlForm().c_str(), mOperation);
+
+    parameters(protocol.manager);	// inherit environment from manager object
+    mObserver = protocol.manager.observer();
+}
+
+Transfer::~Transfer()
+{
+    debug("netxfer", "transfer %p destroyed", this);
+}
+
+
+//
+// Generic error management.
+// These defaults do (almost) nothing useful; they should be overridden by
+// each Protocol's Transfer object.
+//
+Transfer::ResultClass Transfer::resultClass() const
+{
+    switch (state()) {
+    case failed:
+        return unclassifiedFailure;
+    case finished:
+        return success;
+    default:
+        Error::throwMe();
+    }
+}
+
+OSStatus Transfer::errorStatus() const
+{
+    assert(state() == failed);
+    return mErrorStatus;
+}
+
+string Transfer::errorDescription() const
+{
+    assert(state() == failed);
+    return mErrorDescription;
+}
+
+
+//
+// Restart trampoline
+//
+void Transfer::restart()
+{
+    assert(mConnection);
+    return mConnection->restart();
+}
+
+
+//
+// Notify any observer
+//
+void Transfer::observe(Observer::Events events, const void *info)
+{
+    if (mObserver && mObserver->wants(events))
+        mObserver->observe(events, this, info);
+}
+
+
+//
+// Set yourself to be successfully done
+//
+void Transfer::finish()
+{
+    debug("xferengine", "transfer %p is finishing up", this);
+    mState = finished;
+    if (isDocked())
+        mConnection->undock();
+    protocol.manager.done(this);
+    observe(Observer::transferComplete);
+}
+
+
+//
+// Set yourself to have failed
+//
+void Transfer::fail()
+{
+    debug("xferengine", "transfer %p is failing", this);
+    mState = failed;
+    if (isDocked())
+        mConnection->undock();
+    protocol.manager.done(this);
+    observe(Observer::transferFailed);
+}
+
+
+//
+// This default implementation of abort() simply fails.
+// This is not likely to be enough for most protocols.
+//
+void Transfer::abort()
+{
+    if (isDocked())
+        mConnection->retain(false);	// indeterminate state; don't keep it
+    fail();
+}
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/transfer.h b/Network/transfer.h
new file mode 100644
index 00000000..ab929de8
--- /dev/null
+++ b/Network/transfer.h
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+
+//
+// transfer - the embodiment of a single transfer transaction
+//
+#ifndef _H_TRANSFER
+#define _H_TRANSFER
+
+#include <Security/streams.h>
+#include <Security/ip++.h>
+#include "protocol.h"
+#include "target.h"
+#include "parameters.h"
+#include "observer.h"
+
+
+using namespace IPPlusPlus;
+
+
+namespace Security {
+namespace Network {
+
+
+class Protocol;
+
+
+//
+// A Transfer is a single transaction with a target. It usually performs
+// a data transfer (upload or download), though it could also be some
+// administrative action such as creating or deleting (remote) directories.
+//
+class Transfer : public ParameterPointer {
+    friend class Manager;
+    friend class Connection;
+public:
+    typedef Protocol::Operation Operation;
+    
+    Transfer(Protocol &proto, const Target &tgt, Operation op, IPPort defaultPort = 0);
+    virtual ~Transfer();
+    
+    Protocol &protocol;
+    const Target target;
+    
+    enum State {
+        cold,							// queued
+        warm,							// (not yet used)
+        active,							// in progress
+        frozen,							// (not yet used)
+        finished,						// successfully finished
+        failed							// failed
+    };
+    
+    enum ResultClass {
+        success,						// seems to have worked
+        localFailure,					// local error
+        networkFailure,					// failure talking to remote partner
+        remoteFailure,					// failure reported by remote partner
+        authorizationFailure,			// remote reject our authorization
+        abortedFailure,					// transfer was aborted intentionally
+        unclassifiedFailure				// something else went wrong
+    };
+    
+    State state() const				{ return mState; }
+    Operation operation() const		{ return mOperation; }
+    
+    // valid only if state() is finished or failed
+    virtual ResultClass resultClass() const;	// classify outcome
+    
+    // call these ONLY if state() == failed
+    virtual OSStatus errorStatus() const;		// OSStatus short form of error condition
+    virtual string errorDescription() const;	// string form of error condition
+    
+    template <class Conn>
+    Conn &connectionAs() const
+    { assert(mConnection); return *safe_cast<Conn *>(mConnection); }
+    
+    bool isDocked() const				{ return mConnection; }
+
+    Sink &sink() const					{ assert(mSink); return *mSink; }
+    Source &source() const				{ assert(mSource); return *mSource; }
+    void sink(Sink &snk)				{ assert(!mSink); mSink = &snk; }
+    void source(Source &src)			{ assert(!mSource); mSource = &src; }
+    bool hasSink() const				{ return mSink; }
+    bool hasSource() const				{ return mSource; }
+    
+    // get/set the Observer. Observer is initially inherited from Manager
+    Observer *observer() const			{ return mObserver; }
+    void observer(Observer *ob)			{ mObserver = ob; }
+    
+    // get/set connection reuse feature
+    bool shareConnections() const		{ return mShareConnections; }
+    void shareConnections(bool share)	{ mShareConnections = share; }
+    
+    // return our hostTarget or that of the proxy server, if any
+    const HostTarget &proxyHostTarget() const
+    { return protocol.isProxy() ? protocol.proxyHost() : target; }
+
+    // last resort OSStatus to return for failure, if nothing better is known
+    static const OSStatus defaultOSStatusError = -30785;	//@@@ not a good choice, but what?
+        
+protected:
+    virtual void start() = 0;			// engage!
+    virtual void abort();				// abort while running
+
+    void restart();    
+    void observe(Observer::Events events, const void *info = NULL);
+    
+    void setError(const char *s, OSStatus err = defaultOSStatusError)
+    { if (s) mErrorStatus = err; mErrorDescription = s; }
+    
+    void finish();
+    void fail();
+
+private:
+    State mState;						// current state
+    Operation mOperation;				// operation type
+    Connection *mConnection;			// docked connection (NULL if none)
+    Observer *mObserver;				// observer (NULL if none)
+    Source *mSource;					// origin data source (NULL if N/A)
+    Sink *mSink;						// destination data sink (NULL if N/A)
+    bool mShareConnections;				// participate in Connection pool (reuse)
+    
+    OSStatus mErrorStatus;				// OSStatus to return by default
+    string mErrorDescription;			// error string to return by default
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_TRANSFER
diff --git a/Network/xfercore.cpp b/Network/xfercore.cpp
new file mode 100644
index 00000000..6e9fcbda
--- /dev/null
+++ b/Network/xfercore.cpp
@@ -0,0 +1,405 @@
+/*
+ * 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.
+ */
+
+
+//
+// xfercore - core data transfer engine
+//
+#include "xfercore.h"
+#include <Security/debugging.h>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Create an engine-level client object.
+// @@@ Defer buffer allocation to mating?
+// @@@ Defer state initialization to mating?
+//
+TransferEngine::Client::Client()
+    : mMode(invalidInput), mAutoCopyOut(false),
+    mSink(NULL), mSource(NULL),
+    mAutoFlush(true),
+    mReadBuffer(16384), mWriteBuffer(16384)
+{
+}
+
+TransferEngine::Client::~Client()
+{
+}
+
+
+//
+// Add and remove clients to/from the engine
+//
+void TransferEngine::add(Client *client)
+{
+    client->io = client->fileDesc(); // punch master I/O down to Selector client level
+    Selector::add(client->io, *client, input | critical);	// initial registration
+}
+
+void TransferEngine::remove(Client *client)
+{
+#ifndef NDEBUG
+    if (!client->mReadBuffer.isEmpty())
+        debug("xferengine", "xfer %p(%d) HAD %ld BYTES READ LEFT",
+            client, client->fileDesc(), client->mReadBuffer.length());
+    if (!client->mWriteBuffer.isEmpty())
+        debug("xferengine", "xfer %p(%d) HAD %ld BYTES WRITE LEFT",
+            client, client->fileDesc(), client->mWriteBuffer.length());
+#endif //NDEBUG
+    Selector::remove(client->io);
+    client->io = FileDesc();	// invalidate
+}
+
+
+//
+// Mode switching.
+// In addition to the generic switcher (mode), there are variants that set associated
+// information, such as sources/sinks.
+//
+void TransferEngine::Client::mode(InputMode newMode)
+{
+    debug("xferengine", "xfer %p(%d) switching to mode %d", this, fileDesc(), newMode);
+    switch (newMode) {
+    case rawInput:
+    case lineInput:
+        mMode = newMode;
+        break;
+    case connecting:
+        enable(output);
+        mMode = connecting;
+        break;
+    default:
+        assert(false);	// can't switch to these modes like that
+    }
+}
+
+void TransferEngine::Client::mode(Sink &sink, size_t byteCount)
+{
+    mMode = autoReadInput;
+    mSink = &sink;
+    mResidualReadCount = byteCount;
+    debug("xferengine", "xfer %p(%d) switching to autoReadInput (%ld bytes)", 
+        this, fileDesc(), byteCount);
+}
+
+void TransferEngine::Client::mode(Source &source, size_t byteCount)
+{
+    assert (!mAutoCopyOut);		// no replacements, please
+    mAutoCopyOut = true;
+    mSource = &source;
+    mResidualWriteCount = byteCount;
+    debug("xferengine", "xfer %p(%d) enabling autoCopyOut mode (%ld bytes)",
+        this, fileDesc(), byteCount);
+    enable(output);
+}
+
+
+//
+// Output methods. This queues output to be sent to the client's connection
+// as soon as practical.
+//
+void TransferEngine::Client::printf(const char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    vprintf(format, args);
+    va_end(args);
+}
+
+void TransferEngine::Client::vprintf(const char *format, va_list args)
+{
+    mWriteBuffer.vprintf(format, args);
+#if !defined(NDEBUG)
+    char buffer[1024];
+    vsnprintf(buffer, sizeof(buffer), format, args);
+    debug("engineio", "%p(%d) <-- %s", this, fileDesc(), buffer);
+#endif //NDEBUG
+    startOutput();
+}
+
+void TransferEngine::Client::printfe(const char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    vprintfe(format, args);
+    va_end(args);
+}
+
+void TransferEngine::Client::vprintfe(const char *format, va_list args)
+{
+    mWriteBuffer.vprintf(format, args);
+    mWriteBuffer.printf("\r\n");
+#if !defined(NDEBUG)
+    char buffer[1024];
+    vsnprintf(buffer, sizeof(buffer), format, args);
+    debug("engineio", "%p(%d) <-- %s[CRNL]", this, fileDesc(), buffer);
+#endif //NDEBUG
+    startOutput();
+}
+
+
+//
+// Set output auto-flush mode. Think of this as a weak output-hold mode.
+// If autoflush is off, we don't try hard to send data out immediately. If it's
+// on, we send data as soon as it's generated.
+// Calling flushOutput(true) always generates I/O as needed to send output
+// data NOW (even if the mode was already on).
+// 
+void TransferEngine::Client::flushOutput(bool autoFlush)
+{
+    mAutoFlush = autoFlush;
+    debug("engineio", "%p(%d) output flush %s", this, fileDesc(), autoFlush? "on" : "off");
+    if (mAutoFlush)
+        startOutput();
+}
+
+
+//
+// StartOutput is called by output generators to get output flowing.
+// It may generate output I/O, or hold things in buffers according to
+// current settings.
+//
+void TransferEngine::Client::startOutput()
+{
+    if (mAutoFlush) {
+        if (mAutoCopyOut && !mWriteBuffer.isFull())
+            autoCopy();						// try to tack on some autoCopy output
+        if (!mWriteBuffer.isEmpty()) {
+            mWriteBuffer.write(*this);
+            if (mAutoFlush || !mWriteBuffer.isEmpty()) { // possibly more output
+                enable(output);				// ask for output-drain notification
+            } else {
+                disable(output);			// no need for output-possible events
+            }
+        }
+    }
+}
+
+
+//
+// Given that autoCopyOut mode is active, try to transfer some bytes
+// into the write buffer. This is a lazy, fast push, suitable for tacking on
+// when you are about to send data for some other reason.
+// Returns the number of bytes retrieved from the auto-Source (possibly zero).
+//
+size_t TransferEngine::Client::autoCopy()
+{
+    size_t len = mWriteBuffer.available();	//@@@ (true) ?
+    if (mResidualWriteCount && mResidualWriteCount < len)
+        len = mResidualWriteCount;
+    void *addr; mWriteBuffer.locatePut(addr, len);
+    mSource->produce(addr, len);
+    debug("xferengine", "xfer %p(%d) autoCopyOut source delivered %ld bytes",
+        this, fileDesc(), len);
+    mWriteBuffer.usePut(len);
+    return len;
+}
+
+
+//
+// This is the notify function called by the IP Selector layer when I/O is possible.
+// It runs the state machines for all current clients, calling their transit methods
+// in turn.
+//
+void TransferEngine::Client::notify(int fd, Type type)
+{
+    try {
+        //@@@ Note: We do not currently do anything special about critical events.
+
+        if (type & Selector::output) {
+            // if we're in connecting mode
+            if (mMode == connecting) {
+                Socket s; s = fd;	// Socket(fd) means something different...
+                int error = s.error();
+                debug("xferengine", "xfer %p(%d) connect (errno %d)",
+                    this, fd, error);
+                transit(connectionDone, NULL, error);
+                return;
+            }
+            
+            //@@@ use high/low water marks here
+            if (mAutoCopyOut && !mWriteBuffer.isFull()) {
+                if (autoCopy() == 0) {
+                    switch (mSource->state()) {
+                    case Source::stalled:
+                        // ah well, maybe later
+                        debug("xferengine", "xfer %p(%d) autoCopyOut source is stalled", this, fd);
+                        break;
+                    case Source::endOfData:
+                        mAutoCopyOut = false;	// done
+                        debug("xferengine", "xfer %p(%d) autoCopyOut end of data", this, fd);
+                        if (mResidualWriteCount > 0)
+                            debug("xferengine", "xfer %p(%d) has %ld autoCopy bytes left",
+                                this, fd, mResidualWriteCount);
+                        transit(autoWriteDone);
+                        if (!isActive())
+                            return;		// transit removed us; stop now
+                        break;
+                    default:
+                        assert(false);
+                    }
+                }
+            }
+            if (mWriteBuffer.isEmpty()) {	// output possible, no output pending
+                debug("xferengine", "xfer %p(%d) disabling output (empty)", this, fd);
+                disable(output);
+            } else {					// stuff some more
+                size_t length = mWriteBuffer.write(*this);
+                debug("xferengine", "xfer %p(%d) writing %ld bytes", this, fd, length);
+            }
+        }
+    
+        if (type & Selector::input) {
+            IFDEBUG(debug("xferengine", "xfer %p(%d) input ready %d bytes",
+                this, fd, io.iocget<int>(FIONREAD)));
+    
+            do {
+                //@@@ break out after partial buffer to give Equal Time to other transfers? good idea?!
+                if (mReadBuffer.read(*this) == 0) {
+                    mReadBuffer.read(*this, true);
+                }
+                
+                if (mReadBuffer.isEmpty() && atEnd()) {
+                    transit(endOfInput);
+                    break;
+                }
+                switch (mMode) {
+                case rawInput:
+                    rawInputTransit();
+                    break;
+                case lineInput:
+                    lineInputTransit();
+                    break;
+                case autoReadInput:
+                    autoReadInputTransit();
+                    if (mMode != autoIODone)
+                        break;
+                    // autoRead completed; fall through to autoIODone handling
+                case autoIODone:
+                    mMode = invalidInput;		// pre-mark error
+                    transit(autoReadDone);		// notify; this must reset mode or exit
+                    if (!isActive())			// if we're terminated...
+                        return;					// ... then go
+                    assert(mMode != invalidInput); // else enforce mode reset
+                    break;
+                case connecting:
+                    {
+                        // we should never be here. Selector gave us "read but not write" while connecting. FUBAR
+                        Socket s; s = fd;
+                        debug("xferengine",
+                            "fd %d input while connecting (errno=%d, type=%d)",
+                            fd, s.error(), type);
+                        UnixError::throwMe(ECONNREFUSED);	// likely interpretation
+                    }
+                default:
+                    debug("xferengine", "mode error in input sequencer (mode=%d)", mMode);
+                    assert(false);
+                }
+                if (!io)		// client has unhooked; clear buffer and exit loop
+                    mReadBuffer.clear();
+            } while (!mReadBuffer.isEmpty());
+            //@@@ feed back for more output here? But also see comments above...
+            //@@@ probably better to take the trip through the Selector
+        }
+    } catch (CssmCommonError &err) {
+        transitError(err);
+    } catch (...) {
+        transitError(UnixError::make(EIO));		// best guess (could be anything)
+    }
+}
+
+void TransferEngine::Client::rawInputTransit()
+{
+    // just shove it at the user
+    char *addr; size_t length = mReadBuffer.length();
+    mReadBuffer.locateGet(addr, length);
+    IFDEBUG(debug("engineio", "%p(%d) --> %d bytes RAW",
+        this, fileDesc(), io.iocget<int>(FIONREAD)));
+    transit(inputAvailable, addr, length);
+    mReadBuffer.usePut(length);
+}
+
+void TransferEngine::Client::lineInputTransit()
+{
+    char *line; size_t length = mReadBuffer.length();
+    mReadBuffer.locateGet(line, length);
+
+    char *nl;
+    for (nl = line; nl < line + length && *nl != '\n'; nl++) ;
+    if (nl == line + length)				// no end-of-line, wait for more
+        return;
+        
+    if (nl > line && nl[-1] == '\r') {		// proper \r\n termination
+        nl[-1] = '\0';						// terminate for transit convenience
+        debug("engineio", "%p(%d) --> %s", this, fileDesc(), line);
+        transit(inputAvailable, line, nl - line - 1);
+    } else {								// improper, tolerate
+        nl[0] = '\0';						// terminate for transit convenience
+        debug("engineio", "%p(%d) [IMPROPER] --> %s", this, fileDesc(), line);
+        transit(inputAvailable, line, nl - line);
+    }
+    mReadBuffer.useGet(nl - line + 1);
+}
+
+void TransferEngine::Client::autoReadInputTransit()
+{
+    debug("xferengine", "xfer %p(%d) %ld pending %d available",
+        this, fileDesc(), mReadBuffer.length(), io.iocget<int>(FIONREAD));
+    void *data; size_t length = mReadBuffer.length();
+    if (mResidualReadCount && mResidualReadCount < length)
+        length = mResidualReadCount;
+    mReadBuffer.locateGet(data, length);
+    debug("engineio", "%p(%d) --> %ld bytes autoReadInput", this, fileDesc(), length);
+    mSink->consume(data, length);
+    mReadBuffer.useGet(length);
+    if (mResidualReadCount && (mResidualReadCount -= length) == 0)
+        mMode = autoIODone;
+}
+
+
+//
+// The (protected) tickle() method causes a one-time scan
+// of the requesting client. This will simulate an input-ready event
+// and possibly call the transit method.
+// This is designed to be used from validate() or in other unusual
+// external situations. Don't call this from within transit().
+//
+void TransferEngine::Client::tickle()
+{
+    notify(io, input | critical);
+}
+
+
+//
+// The default read/write methods perform direct I/O on the underlying file descriptor.
+//
+size_t TransferEngine::Client::read(void *data, size_t size)
+{ return io.read(data, size); }
+
+size_t TransferEngine::Client::write(const void *data, size_t size)
+{ return io.write(data, size); }
+
+bool TransferEngine::Client::atEnd() const
+{ return io.atEnd(); }
+
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/Network/xfercore.h b/Network/xfercore.h
new file mode 100644
index 00000000..f1d2e8e4
--- /dev/null
+++ b/Network/xfercore.h
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+
+//
+// xfercore - core data transfer engine
+//
+#ifndef _H_XFERCORE
+#define _H_XFERCORE
+
+#include <Security/ip++.h>
+#include <Security/selector.h>
+#include <Security/buffers.h>
+#include <Security/streams.h>
+#include <cstdarg>
+
+#if defined(SOCKS_SUPPORT)
+# include <Security/socks++.h>
+# define TCPClientSocket SocksClientSocket
+# define TCPServerSocket SocksServerSocket
+#endif
+
+using Security::Buffer;
+using namespace IPPlusPlus;
+
+
+namespace Security {
+namespace Network {
+
+
+class TransferEngine : public Selector {
+public:
+    TransferEngine() { }
+    virtual ~TransferEngine() { }
+    
+public:
+    class Client : public Selector::Client {
+        friend class TransferEngine;
+    public:
+        Client();
+        virtual ~Client();
+    
+    public:
+        enum InputMode {
+            invalidInput,				// error mode (invalid)
+            connecting,					// working on TCP connection
+            rawInput,					// raw chunk input (whatever's on the wire)
+            lineInput,					// Internet lines input (\r\n)
+            autoReadInput,				// bulk read to docked sink
+            
+            autoIODone					// transiition marker
+        };
+        InputMode mode() const		{ return mMode; }
+        void mode(InputMode m);			// set (switch) mode
+        void mode(Sink &sink, size_t byteCount = 0);
+        
+        void mode(Source &source, size_t byteCount = 0);
+        bool autoWriteActive() const	{ return mSource; }
+        
+        enum Event {					// event type: (input, length) arguments
+            inputAvailable,				// input available in current mode: (data, length)
+            connectionDone,				// TCP connection event: (NULL, errno)
+            autoReadDone,				// autoReadInput has completed: (NULL, 0)
+            autoWriteDone,				// autoWriteOutput has completed: (NULL, 0)
+            endOfInput,					// end of data stream from remote end: (NULL, 0)
+            ioError						// I/O failed: (CssmCommonError *, 0)
+        };
+        
+        virtual void transit(Event event, char *data = NULL, size_t length = 0) = 0;
+        virtual void transitError(const CssmCommonError &error) = 0;
+        virtual int fileDesc() const = 0;
+        
+    public:
+        // override this to implement I/O filters - default is pass-through
+        virtual size_t read(void *data, size_t size);
+        virtual size_t write(const void *data, size_t size);
+        virtual bool atEnd() const;
+        
+    protected:
+        void printf(const char *format, ...);
+        void printfe(const char *format, ...);
+        void vprintf(const char *format, va_list args);
+        void vprintfe(const char *format, va_list args);
+        
+        void flushOutput(bool autoFlush = true);
+        
+        void tickle();
+    
+    private:
+        void notify(int fd, Type type);
+        
+    private:
+        void rawInputTransit();
+        void lineInputTransit();
+        void autoReadInputTransit();
+        
+        void startOutput();
+        size_t autoCopy();
+        
+    private:
+        InputMode mMode;				// current mode
+        bool mAutoCopyOut;				// auto-copyout overlay mode
+        Sink *mSink;					// sink for autoReadInput mode
+        Source *mSource;				// source for copyout overlay mode
+        size_t mResidualReadCount;		// bytes left to autoReadInput (zero => unlimited)
+        size_t mResidualWriteCount;		// bytes left to autoCopyOut (zero => unlimited)
+        bool mAutoFlush;				// output auto-flush mode
+        
+        FileDesc io;
+        
+        Buffer mReadBuffer;
+        Buffer mWriteBuffer;
+    };
+        
+public:
+    void add(Client *client);
+    void remove(Client *client);
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif //_H_XFERCORE
diff --git a/SecureTransport/CVSVersionInfo.txt b/SecureTransport/CVSVersionInfo.txt
new file mode 100644
index 00000000..d0b1f63e
--- /dev/null
+++ b/SecureTransport/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:58 mb Exp $
+# $Name: Security-28 $
+ProjectName: SecureTransport
+ProjectVersion: 3
diff --git a/SecureTransport/LICENSE.txt b/SecureTransport/LICENSE.txt
new file mode 100644
index 00000000..7a94e7fc
--- /dev/null
+++ b/SecureTransport/LICENSE.txt
@@ -0,0 +1 @@
+LICENSE.txt
-----------
SSLRef 3.0 Final -- 11/19/96
Copyright (c)1996 by Netscape Communications Corp.

By retrieving this software you are bound by the licensing terms
disclosed in the file "LICENSE.txt". Please read it, and if you
don't accept the terms, delete this software.

SSLRef 3.0 was codeveloped by Netscape Communications Corp. of
Mountain View, California <http://home.netscape.com/> and Consensus
Development Corporation of Berkeley, California
<http://www.consensus.com/>.


SSL Reference Implemenation License Agreement for Non-Commercial Use
--------------------------------------------------------------------
Netscape Communications Corporation ("Netscape") hereby grants you a
non-exclusive, non-transferable license to use the Secure Sockets
Layer Reference Implementation 3.0 (the "Software") subject to the
following terms:

1. You may modify the Software and/or incorporate it, in whole or
in part, into other software programs (a "Derivative Work").

2. You may not use the Software or Derivative Works for
revenue-generating purposes. You may not:

(a) license or distribute the Software or any Derivative Work in
any manner that generates license fees, royalties, maintenance fees,
upgrade fees or any other form of income.

(b) use the Software or a Derivative Work to provide services to
others for which you are compensated in any manner.

(c) distribute the Software or a Derivative Work without written
agreement from the end user to abide by the terms of this Section 2.

3. You may reproduce and use the Software and Derivative Works
free of charge for internal use. Such internal use may be at the
premises of an establishment which is engaged in revenue-generating
activities, provided that the Software and Derivative Works are not
used as specified in Section 2.

4. Any modification of the Software must prominently state in the
modified product or associated documentation that it has been
modified and the date the modifications were made. Any copy of the
Software or Derivative Work shall include a copy of this Agreement,
Netscape's copyright notices and the disclaimer of warranty and
limitation of liability.

5. Title, ownership rights, and intellectual property rights in and
to the Software shall remain in Netscape and/or its suppliers.
You may use the Software only as provided in this Agreement.
Netscape shall have no obligation to provide maintenance, support,
upgrades or new releases to you or any person to whom you distribute
the Software or a Derivative Work.

6. Netscape may use Licensee's name in publicity materials as a
licensee of the Software.

7. Disclaimer of Warranty. THE SOFTWARE IS LICENSED "AS IS"
WITHOUT WARRANTY OF ANY KIND, INCLUDING WITHOUT LIMITATION,
PERFORMANCE, MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE RESULTS AND PERFORMANCE OF THE
SOFTWARE IS ASSUMED BY YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE,
YOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR
CORRECTION.

8. Limitation of Liability. UNDER NO CIRCUMSTANCES AND UNDER NO
LEGAL THEORY SHALL NETSCAPE OR ITS SUPPLIERS BE LIABLE TO YOU OR ANY
OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES OF ANY CHARACTER INCLUDING WITHOUT LIMITATION ANY COMMERCIAL
DAMAGES OR LOSSES , EVEN IF NETSCAPE HAS BEEN INFORMED OF THE
POSSIBILITY OF SUCH DAMAGES.

9. You may not download or otherwise export or reexport the
Software or any underlying information or technology except in full
compliance with all United States and other applicable laws and
regulations. EXCEPT FOR EXPORT TO CANADA FOR USE IN CANADA BY
CANADIAN CITIZENS, THE SOFTWARE AND ANY UNDERLYING TECHNOLOGY MAY
NOT BE EXPORTED OUTSIDE THE UNITED STATES OR TO ANY FOREIGN ENTITY
OR "FOREIGN PERSON" AS DEFINED BY U.S. GOVERNMENT REGULATIONS,
INCLUDING WITHOUT LIMITATION, ANYONE WHO IS NOT A CITIZEN, NATIONAL
OR LAWFUL PERMANENT RESIDENT OF THE UNITED STATES. BY DOWNLOADING
OR USING THE SOFTWARE, YOU ARE AGREEING TO THE FOREGOING AND YOU ARE
WARRANTING THAT YOU ARE NOT A "FOREIGN PERSON" OR UNDER THE CONTROL
OF A FOREIGN PERSON.

10. Either party may terminate this Agreement immediately in the
event of default by the other party. You may also terminate this
Agreement at any time by destroying the Software and all copies
thereof. Termination of your license will not terminate any
sublicenses previously granted by you so long as the sublicensee
complies with this Agreement.

11. Use, duplication or disclosure by the United States Government
is subject to restrictions set forth in subparagraphs (a) through
(d) of the Commercial Computer-Restricted Rights clause at FAR
52.227-19 when applicable, or in subparagraph (c)(1)(ii) of the
Rights in Technical Data and Computer Program clause at DFARS
252.227-7013, and in similar clauses in the NASA FAR Supplement.
Contractor/manufacturer is Netscape Communications Corporation, 501
East Middlefield Road, Mountain View, CA 94043.

12. This Agreement shall be governed by and construed under
California law as such law applies to agreements between California
residents entered into and to be performed entirely within
California, except as governed by Federal law.
\ No newline at end of file
diff --git a/SecureTransport/ModuleAttacher.cpp b/SecureTransport/ModuleAttacher.cpp
new file mode 100644
index 00000000..42378a73
--- /dev/null
+++ b/SecureTransport/ModuleAttacher.cpp
@@ -0,0 +1,253 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * ModuleAttacher.cpp
+ *
+ * Process-wide class which loads and attaches to {CSP, TP, CL} at most
+ * once, and detaches and unloads the modules when this code is unloaded.
+ */
+
+#include "ModuleAttacher.h"
+#include "sslDebug.h"
+#include "appleCdsa.h"
+#include <Security/globalizer.h>
+#include <Security/threading.h>
+#include <Security/cssmalloc.h>
+#include <Security/cssmapple.h>
+#include <Security/cssmtype.h>
+#include <Security/cssmapi.h>
+
+class ModuleAttacher
+{
+public:
+	ModuleAttacher() :
+		mCspHand(CSSM_INVALID_HANDLE),
+		mClHand(CSSM_INVALID_HANDLE),
+		mTpHand(CSSM_INVALID_HANDLE),
+		mCssmInitd(false)
+			{ }
+	~ModuleAttacher();
+	CSSM_CSP_HANDLE			getCspHand();
+	CSSM_CL_HANDLE			getClHand();
+	CSSM_TP_HANDLE			getTpHand();
+	CSSM_RETURN				loadAllModules(
+								CSSM_CSP_HANDLE &cspHand,
+								CSSM_CL_HANDLE	&clHand,
+								CSSM_TP_HANDLE	&tpHand);
+
+private:
+	/* on all private member functions, mLock held on entry and exit */
+	bool					initCssm();
+	CSSM_HANDLE				loadModule(
+								CSSM_SERVICE_TYPE svcType,	// CSSM_SERVICE_CSP, etc.
+								const CSSM_GUID *guid,
+								const char *modName);
+	void					unloadModule(
+								CSSM_HANDLE	hand,
+								const CSSM_GUID *guid);
+
+	/* connection to modules, evaluated lazily */
+	CSSM_CSP_HANDLE			mCspHand;
+	CSSM_TP_HANDLE			mClHand;
+	CSSM_TP_HANDLE			mTpHand;
+	bool					mCssmInitd;
+	Mutex					mLock;
+};
+
+/* the single global thing */
+static ModuleNexus<ModuleAttacher> moduleAttacher;
+
+static const CSSM_API_MEMORY_FUNCS CA_memFuncs = {
+	stAppMalloc,
+	stAppFree,
+	stAppRealloc,
+ 	stAppCalloc,
+ 	NULL
+};
+
+
+/*
+ * This only gets called when cspAttacher get deleted, i.e., when this code
+ * is actually unloaded from the process's address space.
+ */
+ModuleAttacher::~ModuleAttacher()
+{
+	StLock<Mutex> 	_(mLock);
+
+	if(mCspHand != CSSM_INVALID_HANDLE) {
+		unloadModule(mCspHand, &gGuidAppleCSP);
+	}
+	if(mTpHand != CSSM_INVALID_HANDLE) {
+		unloadModule(mTpHand, &gGuidAppleX509TP);
+	}
+	if(mClHand != CSSM_INVALID_HANDLE) {
+		unloadModule(mClHand, &gGuidAppleX509CL);
+	}
+}
+
+static const CSSM_VERSION cssmVers = {2, 0};
+static const CSSM_GUID testGuid = { 0xFADE, 0, 0, { 1,2,3,4,5,6,7,0 }};
+
+bool ModuleAttacher::initCssm()
+{
+	CSSM_RETURN  crtn;
+    CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE;
+	
+	if(mCssmInitd) {
+		return true;
+	}  
+	crtn = CSSM_Init (&cssmVers, 
+		CSSM_PRIVILEGE_SCOPE_NONE,
+		&testGuid,
+		CSSM_KEY_HIERARCHY_NONE,
+		&pvcPolicy,
+		NULL /* reserved */);
+	if(crtn != CSSM_OK) {
+		errorLog1("CSSM_Init returned %s", stCssmErrToStr(crtn));
+		return false;
+	}
+	else {
+		mCssmInitd = true;
+		return true;
+	}
+}
+
+CSSM_HANDLE ModuleAttacher::loadModule(
+	CSSM_SERVICE_TYPE svcType,	// CSSM_SERVICE_CSP, etc.
+	const CSSM_GUID *guid,
+	const char *modName)
+{
+	CSSM_RETURN crtn;
+	CSSM_HANDLE hand;
+	
+	if(!initCssm()) {
+		return CSSM_INVALID_HANDLE;
+	}
+	crtn = CSSM_ModuleLoad(guid,
+		CSSM_KEY_HIERARCHY_NONE,
+		NULL,			// eventHandler
+		NULL);			// AppNotifyCallbackCtx
+	if(crtn) {
+		errorLog2("AppleX509CLSession::cspAttach: error (%s) loading %s\n",
+			stCssmErrToStr(crtn), modName);
+		return CSSM_INVALID_HANDLE;
+	}
+	crtn = CSSM_ModuleAttach (guid,
+		&cssmVers,
+		&CA_memFuncs,			// memFuncs
+		0,						// SubserviceID
+		svcType,				// SubserviceFlags 
+		0,						// AttachFlags
+		CSSM_KEY_HIERARCHY_NONE,
+		NULL,					// FunctionTable
+		0,						// NumFuncTable
+		NULL,					// reserved
+		&hand);
+	if(crtn) {
+		errorLog2("AppleX509CLSession::cspAttach: error (%s) attaching to %s\n",
+			stCssmErrToStr(crtn), modName);
+		return CSSM_INVALID_HANDLE;
+	}
+	return hand;
+}
+
+void ModuleAttacher::unloadModule(
+	CSSM_HANDLE	hand,
+	const CSSM_GUID *guid)
+{
+	CSSM_ModuleDetach(hand);
+	CSSM_ModuleUnload(guid, NULL, NULL);
+}
+
+CSSM_CSP_HANDLE ModuleAttacher::getCspHand()
+{
+	StLock<Mutex> 	_(mLock);
+	
+	if(mCspHand != CSSM_INVALID_HANDLE) {
+		/* already connected */
+		return mCspHand;
+	}	
+	mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
+	return mCspHand;
+}
+
+CSSM_CL_HANDLE ModuleAttacher::getClHand()
+{
+	StLock<Mutex> 	_(mLock);
+	
+	if(mClHand != CSSM_INVALID_HANDLE) {
+		/* already connected */
+		return mClHand;
+	}	
+	mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
+	return mClHand;
+}
+
+CSSM_TP_HANDLE ModuleAttacher::getTpHand()
+{
+	StLock<Mutex> 	_(mLock);
+	
+	if(mTpHand != CSSM_INVALID_HANDLE) {
+		/* already connected */
+		return mTpHand;
+	}	
+	mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP"); 
+	return mTpHand;
+}
+
+CSSM_RETURN ModuleAttacher::loadAllModules(
+	CSSM_CSP_HANDLE &cspHand,
+	CSSM_CL_HANDLE	&clHand,
+	CSSM_TP_HANDLE	&tpHand)
+{
+	StLock<Mutex> 	_(mLock);
+	
+	if(mCspHand == CSSM_INVALID_HANDLE) {
+		mCspHand = loadModule(CSSM_SERVICE_CSP, &gGuidAppleCSP, "AppleCSP");
+		if(mCspHand == CSSM_INVALID_HANDLE) {
+			return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
+		}
+	}
+	if(mClHand == CSSM_INVALID_HANDLE) {
+		mClHand = loadModule(CSSM_SERVICE_CL, &gGuidAppleX509CL, "AppleCL");
+		if(mClHand == CSSM_INVALID_HANDLE) {
+			return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
+		}
+	}
+	if(mTpHand == CSSM_INVALID_HANDLE) {
+		mTpHand = loadModule(CSSM_SERVICE_TP, &gGuidAppleX509TP, "AppleTP");
+		if(mTpHand == CSSM_INVALID_HANDLE) {
+			return CSSMERR_CSSM_ADDIN_LOAD_FAILED;
+		}
+	}
+	cspHand = mCspHand;
+	clHand  = mClHand;
+	tpHand  = mTpHand;
+	return CSSM_OK;
+}
+
+/* public C function to load and attach to all three modules */
+CSSM_RETURN attachToModules(
+	CSSM_CSP_HANDLE		*cspHand,
+	CSSM_CL_HANDLE		*clHand,
+	CSSM_TP_HANDLE		*tpHand)
+{
+	return moduleAttacher().loadAllModules(*cspHand, *clHand, *tpHand);
+}
+
diff --git a/SecureTransport/ModuleAttacher.h b/SecureTransport/ModuleAttacher.h
new file mode 100644
index 00000000..ef353084
--- /dev/null
+++ b/SecureTransport/ModuleAttacher.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * ModuleAttacher.h 
+ *
+ * Process-wide class which loads and attaches to {CSP, TP, CL} at most
+ * once, and detaches and unloads the modules when this code is unloaded.
+ */
+ 
+#ifndef	_MODULE_ATTACHER_H_
+#define _MODULE_ATTACHER_H_
+
+#include <Security/cssmtype.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* 
+ * Load and attach to all three modules.
+ * Returns CSSMERR_CSSM_ADDIN_LOAD_FAILED or CSSM_OK.
+ */
+extern CSSM_RETURN attachToModules(
+	CSSM_CSP_HANDLE		*cspHand,
+	CSSM_CL_HANDLE		*clHand,
+	CSSM_TP_HANDLE		*tpHand);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _CSP_ATTACHER_H_ */
\ No newline at end of file
diff --git a/SecureTransport/README b/SecureTransport/README
new file mode 100644
index 00000000..4de427f4
--- /dev/null
+++ b/SecureTransport/README
@@ -0,0 +1 @@
+                     SecureTransport notes
                       8 Nov 1999 dmitch
                       
Current status of this project:

Note "Version" refers to SSL2 vs. SSL3. "Mode" refers to client vs. server.

-- All modes require domestic CSP. 

-- Both modes require post-Sonata CSP mods which allow 
   specification of raw symmetric key bits. These CSP changes 
   have been checked in prior to 8 Nov 1999.

-- Server mode requires post-Sonata CSP mods which allow 
   asymmetric keys to have multiple KeyUsage flags set - 
   specifically, private keys must be able to sign and 
   decrypt; public keys must be able to verify and encrypt.
   These CSP changes have NOT been checked in as of 8 Nov 1999;
   final implementation pending input from A. Perez. 

-- Client mode works in both versions, both domestic and export. 

-- Server mode works with Netscape client 4.6.1 on Mac. 
   Operation with IE on Mac is flaky - sometimes it works,
   sometimes not. Server untested with Windows clients. 

-- Client authentication is not tested. 

-- No support for session resumption. This needs a thread-safe
   database, to be implemented in appleSession.c.

\ No newline at end of file
diff --git a/SecureTransport/SecureTransport.pbproj/project.pbxproj b/SecureTransport/SecureTransport.pbproj/project.pbxproj
new file mode 100644
index 00000000..622eca48
--- /dev/null
+++ b/SecureTransport/SecureTransport.pbproj/project.pbxproj
@@ -0,0 +1,1647 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 31;
+	objects = {
+		00E4CE33FF9B8B71D0A17CE7 = {
+			buildStyles = (
+				48499A08FFCB05657F000001,
+				48499A09FFCB05657F000001,
+			);
+			isa = PBXProject;
+			mainGroup = 00E4CE34FF9B8B71D0A17CE7;
+			productRefGroup = 00E4CE35FF9B8CA8D0A17CE7;
+			projectDirPath = .;
+			targets = (
+				00E4CE37FF9B8CA8D0A17CE7,
+				00E4CE38FF9B8CA8D0A17CE7,
+			);
+		};
+		00E4CE34FF9B8B71D0A17CE7 = {
+			children = (
+				00E4CE3EFF9B8E08D0A17CE7,
+				00E4CE41FF9B8EABD0A17CE7,
+				00E4CE42FF9B8EABD0A17CE7,
+				00E4CE5FFF9B8EABD0A17CE7,
+				00E4CE60FF9B8EABD0A17CE7,
+				00E4CE61FF9B8EABD0A17CE7,
+				1F12355AFF9CE43ED0A17CE7,
+				00E4CE35FF9B8CA8D0A17CE7,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		00E4CE35FF9B8CA8D0A17CE7 = {
+			children = (
+				00E4CE36FF9B8CA8D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		00E4CE36FF9B8CA8D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			path = SecureTransport.framework;
+			refType = 3;
+		};
+		00E4CE37FF9B8CA8D0A17CE7 = {
+			buildPhases = (
+			);
+			buildSettings = {
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = World;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				00E4CEBEFF9B99B0D0A17CE7,
+			);
+			isa = PBXAggregateTarget;
+			name = World;
+			productName = World;
+			shouldUseHeadermap = 0;
+		};
+		00E4CE38FF9B8CA8D0A17CE7 = {
+			buildPhases = (
+				00E4CE39FF9B8CA8D0A17CE7,
+				00E4CE3AFF9B8CA8D0A17CE7,
+				00E4CE3BFF9B8CA8D0A17CE7,
+				00E4CE3CFF9B8CA8D0A17CE7,
+				00E4CE3DFF9B8CA8D0A17CE7,
+			);
+			buildSettings = {
+				DEPLOYMENT_OPTIMIZATION_CFLAGS = "-O3";
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				EXPORTED_SYMBOLS_FILE = secureTransport.exp;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYMROOT)\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)/privateInc\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				OPTIMIZATION_CFLAGS = "-O3";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-lstdc++";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = SecureTransport;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-format";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXFrameworkTarget;
+			name = SecureTransport;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = SecureTransport;
+			productReference = 00E4CE36FF9B8CA8D0A17CE7;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string></string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		00E4CE39FF9B8CA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				00E4CE62FF9B8EABD0A17CE7,
+				00E4CE63FF9B8EABD0A17CE7,
+				00E4CE64FF9B8EABD0A17CE7,
+				00E4CE65FF9B8EABD0A17CE7,
+				00E4CE66FF9B8EABD0A17CE7,
+				00E4CE67FF9B8EABD0A17CE7,
+				00E4CE68FF9B8EABD0A17CE7,
+				00E4CE6BFF9B8EABD0A17CE7,
+				00E4CE6CFF9B8EABD0A17CE7,
+				00E4CE6DFF9B8EABD0A17CE7,
+				00E4CE6EFF9B8EABD0A17CE7,
+				00E4CE6FFF9B8EABD0A17CE7,
+				00E4CE70FF9B8EABD0A17CE7,
+				00E4CE71FF9B8EABD0A17CE7,
+				00E4CE72FF9B8EABD0A17CE7,
+				00E4CE73FF9B8EABD0A17CE7,
+				00E4CE75FF9B8EABD0A17CE7,
+				00E4CE76FF9B8EABD0A17CE7,
+				00E4CE77FF9B8EABD0A17CE7,
+				00E4CE78FF9B8EABD0A17CE7,
+				00E4CE79FF9B8EABD0A17CE7,
+				00E4CE7AFF9B8EABD0A17CE7,
+				00E4CE7BFF9B8EABD0A17CE7,
+				00E4CE7CFF9B8EABD0A17CE7,
+				00E4CE7DFF9B8EABD0A17CE7,
+				00E4CEB7FF9B909FD0A17CE7,
+				00E4CEB8FF9B909FD0A17CE7,
+				0145E21DFFEED50A7F000001,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		00E4CE3AFF9B8CA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		00E4CE3BFF9B8CA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				00E4CE82FF9B8F1DD0A17CE7,
+				00E4CE83FF9B8F1DD0A17CE7,
+				00E4CE84FF9B8F1DD0A17CE7,
+				00E4CE85FF9B8F1DD0A17CE7,
+				00E4CE9BFF9B8FE5D0A17CE7,
+				00E4CE9CFF9B8FE5D0A17CE7,
+				00E4CE9EFF9B8FE5D0A17CE7,
+				00E4CE9FFF9B8FE5D0A17CE7,
+				00E4CEA0FF9B8FE5D0A17CE7,
+				00E4CEA1FF9B8FE5D0A17CE7,
+				00E4CEA2FF9B8FE5D0A17CE7,
+				00E4CEA3FF9B8FE5D0A17CE7,
+				00E4CEA4FF9B8FE5D0A17CE7,
+				00E4CEA5FF9B8FE5D0A17CE7,
+				00E4CEA6FF9B8FE5D0A17CE7,
+				00E4CEA7FF9B8FE5D0A17CE7,
+				00E4CEA8FF9B8FE5D0A17CE7,
+				00E4CEA9FF9B8FE5D0A17CE7,
+				00E4CEAAFF9B8FE5D0A17CE7,
+				00E4CEABFF9B8FE5D0A17CE7,
+				00E4CEACFF9B8FE5D0A17CE7,
+				00E4CEADFF9B8FE5D0A17CE7,
+				00E4CEAEFF9B8FE5D0A17CE7,
+				00E4CEAFFF9B8FE5D0A17CE7,
+				00E4CEB9FF9B909FD0A17CE7,
+				00E4CEBAFF9B909FD0A17CE7,
+				00E4CEBBFF9B909FD0A17CE7,
+				00E4CEBCFF9B909FD0A17CE7,
+				00E4CEBDFF9B909FD0A17CE7,
+				00E4CEC0FF9B9A4ED0A17CE7,
+				00E4CEC2FF9BA51FD0A17CE7,
+				0145E21EFFEED50A7F000001,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		00E4CE3CFF9B8CA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				1F123555FF9CE352D0A17CE7,
+				1F123558FF9CE3A5D0A17CE7,
+				1F123559FF9CE3A5D0A17CE7,
+				1F12355DFF9CE43ED0A17CE7,
+				1F12355EFF9CE43ED0A17CE7,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		00E4CE3DFF9B8CA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		00E4CE3EFF9B8E08D0A17CE7 = {
+			children = (
+				00E4CEB0FF9B909FD0A17CE7,
+				00E4CEB1FF9B909FD0A17CE7,
+				00E4CEB2FF9B909FD0A17CE7,
+				00E4CEB3FF9B909FD0A17CE7,
+				00E4CEB4FF9B909FD0A17CE7,
+				00E4CE3FFF9B8E08D0A17CE7,
+				00E4CE40FF9B8E08D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "SSL Core";
+			refType = 4;
+		};
+		00E4CE3FFF9B8E08D0A17CE7 = {
+			children = (
+				00E4CE86FF9B8FE5D0A17CE7,
+				00E4CE87FF9B8FE5D0A17CE7,
+				00E4CE88FF9B8FE5D0A17CE7,
+				00E4CE89FF9B8FE5D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = SSL2;
+			refType = 4;
+		};
+		00E4CE40FF9B8E08D0A17CE7 = {
+			children = (
+				00E4CE8AFF9B8FE5D0A17CE7,
+				00E4CE8BFF9B8FE5D0A17CE7,
+				00E4CE8CFF9B8FE5D0A17CE7,
+				00E4CE8DFF9B8FE5D0A17CE7,
+				00E4CE8EFF9B8FE5D0A17CE7,
+				00E4CE8FFF9B8FE5D0A17CE7,
+				00E4CE90FF9B8FE5D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = Handshake;
+			refType = 4;
+		};
+		00E4CE41FF9B8EABD0A17CE7 = {
+			children = (
+				00E4CEB5FF9B909FD0A17CE7,
+				00E4CEB6FF9B909FD0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "Public Headers";
+			path = "";
+			refType = 4;
+		};
+		00E4CE42FF9B8EABD0A17CE7 = {
+			children = (
+				00E4CE43FF9B8EABD0A17CE7,
+				00E4CE44FF9B8EABD0A17CE7,
+				00E4CE45FF9B8EABD0A17CE7,
+				00E4CE46FF9B8EABD0A17CE7,
+				00E4CE47FF9B8EABD0A17CE7,
+				00E4CE48FF9B8EABD0A17CE7,
+				00E4CE49FF9B8EABD0A17CE7,
+				0145E21CFFEED50A7F000001,
+				00E4CE4CFF9B8EABD0A17CE7,
+				00E4CE4DFF9B8EABD0A17CE7,
+				00E4CE4EFF9B8EABD0A17CE7,
+				00E4CE4FFF9B8EABD0A17CE7,
+				00E4CE50FF9B8EABD0A17CE7,
+				00E4CE51FF9B8EABD0A17CE7,
+				00E4CE52FF9B8EABD0A17CE7,
+				00E4CE53FF9B8EABD0A17CE7,
+				00E4CE54FF9B8EABD0A17CE7,
+				00E4CE56FF9B8EABD0A17CE7,
+				00E4CE57FF9B8EABD0A17CE7,
+				00E4CE58FF9B8EABD0A17CE7,
+				00E4CE59FF9B8EABD0A17CE7,
+				00E4CE5AFF9B8EABD0A17CE7,
+				00E4CE5BFF9B8EABD0A17CE7,
+				00E4CE5CFF9B8EABD0A17CE7,
+				00E4CE5DFF9B8EABD0A17CE7,
+				00E4CE5EFF9B8EABD0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "Private Headers";
+			path = "";
+			refType = 4;
+		};
+		00E4CE43FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = appleCdsa.h;
+			path = privateInc/appleCdsa.h;
+			refType = 4;
+		};
+		00E4CE44FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = appleGlue.h;
+			path = privateInc/appleGlue.h;
+			refType = 4;
+		};
+		00E4CE45FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = appleSession.h;
+			path = privateInc/appleSession.h;
+			refType = 4;
+		};
+		00E4CE46FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = cipherSpecs.h;
+			path = privateInc/cipherSpecs.h;
+			refType = 4;
+		};
+		00E4CE47FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = cryptType.h;
+			path = privateInc/cryptType.h;
+			refType = 4;
+		};
+		00E4CE48FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = digests.h;
+			path = privateInc/digests.h;
+			refType = 4;
+		};
+		00E4CE49FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = md5.h;
+			path = privateInc/md5.h;
+			refType = 4;
+		};
+		00E4CE4CFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sha.h;
+			path = privateInc/sha.h;
+			refType = 4;
+		};
+		00E4CE4DFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = ssl.h;
+			path = privateInc/ssl.h;
+			refType = 4;
+		};
+		00E4CE4EFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = ssl2.h;
+			path = privateInc/ssl2.h;
+			refType = 4;
+		};
+		00E4CE4FFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslalert.h;
+			path = privateInc/sslalert.h;
+			refType = 4;
+		};
+		00E4CE50FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslalloc.h;
+			path = privateInc/sslalloc.h;
+			refType = 4;
+		};
+		00E4CE51FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslBER.h;
+			path = privateInc/sslBER.h;
+			refType = 4;
+		};
+		00E4CE52FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslBuildFlags.h;
+			path = privateInc/sslBuildFlags.h;
+			refType = 4;
+		};
+		00E4CE53FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslctx.h;
+			path = privateInc/sslctx.h;
+			refType = 4;
+		};
+		00E4CE54FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslDebug.h;
+			path = privateInc/sslDebug.h;
+			refType = 4;
+		};
+		00E4CE56FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslerrs.h;
+			path = privateInc/sslerrs.h;
+			refType = 4;
+		};
+		00E4CE57FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslhdshk.h;
+			path = privateInc/sslhdshk.h;
+			refType = 4;
+		};
+		00E4CE58FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslKeychain.h;
+			path = privateInc/sslKeychain.h;
+			refType = 4;
+		};
+		00E4CE59FF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslPriv.h;
+			path = privateInc/sslPriv.h;
+			refType = 4;
+		};
+		00E4CE5AFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslrec.h;
+			path = privateInc/sslrec.h;
+			refType = 4;
+		};
+		00E4CE5BFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslsess.h;
+			path = privateInc/sslsess.h;
+			refType = 4;
+		};
+		00E4CE5CFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = ssltrspt.h;
+			path = privateInc/ssltrspt.h;
+			refType = 4;
+		};
+		00E4CE5DFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sslutil.h;
+			path = privateInc/sslutil.h;
+			refType = 4;
+		};
+		00E4CE5EFF9B8EABD0A17CE7 = {
+			isa = PBXFileReference;
+			name = symCipher.h;
+			path = privateInc/symCipher.h;
+			refType = 4;
+		};
+		00E4CE5FFF9B8EABD0A17CE7 = {
+			children = (
+				00E4CE7EFF9B8F1DD0A17CE7,
+				00E4CE7FFF9B8F1DD0A17CE7,
+				00E4CE80FF9B8F1DD0A17CE7,
+				00E4CE81FF9B8F1DD0A17CE7,
+				00E4CE91FF9B8FE5D0A17CE7,
+				00E4CE92FF9B8FE5D0A17CE7,
+				00E4CE94FF9B8FE5D0A17CE7,
+				00E4CEC1FF9BA51FD0A17CE7,
+				0145E21BFFEED50A7F000001,
+			);
+			isa = PBXGroup;
+			name = Apple;
+			path = "";
+			refType = 4;
+		};
+		00E4CE60FF9B8EABD0A17CE7 = {
+			children = (
+				00E4CE95FF9B8FE5D0A17CE7,
+				00E4CE96FF9B8FE5D0A17CE7,
+				00E4CE97FF9B8FE5D0A17CE7,
+				00E4CE98FF9B8FE5D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "Embedded Crypto";
+			path = "";
+			refType = 4;
+		};
+		00E4CE61FF9B8EABD0A17CE7 = {
+			children = (
+				00E4CEBFFF9B9A4ED0A17CE7,
+				00E4CE99FF9B8FE5D0A17CE7,
+				00E4CE9AFF9B8FE5D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = Misc.;
+			path = "";
+			refType = 4;
+		};
+		00E4CE62FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE43FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE63FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE44FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE64FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE45FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE65FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE46FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE66FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE47FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE67FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE48FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE68FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE49FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE6BFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE4CFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE6CFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE4DFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE6DFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE4EFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE6EFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE4FFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE6FFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE50FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE70FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE51FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE71FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE52FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE72FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE53FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE73FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE54FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE75FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE56FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE76FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE57FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE77FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE58FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE78FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE59FF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE79FF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE5AFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE7AFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE5BFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE7BFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE5CFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE7CFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE5DFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE7DFF9B8EABD0A17CE7 = {
+			fileRef = 00E4CE5EFF9B8EABD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE7EFF9B8F1DD0A17CE7 = {
+			isa = PBXFileReference;
+			path = appleCdsa.c;
+			refType = 4;
+		};
+		00E4CE7FFF9B8F1DD0A17CE7 = {
+			isa = PBXFileReference;
+			path = appleGlue.c;
+			refType = 4;
+		};
+		00E4CE80FF9B8F1DD0A17CE7 = {
+			isa = PBXFileReference;
+			path = appleSession.c;
+			refType = 4;
+		};
+		00E4CE81FF9B8F1DD0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslKeychain.c;
+			refType = 4;
+		};
+		00E4CE82FF9B8F1DD0A17CE7 = {
+			fileRef = 00E4CE7EFF9B8F1DD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE83FF9B8F1DD0A17CE7 = {
+			fileRef = 00E4CE7FFF9B8F1DD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE84FF9B8F1DD0A17CE7 = {
+			fileRef = 00E4CE80FF9B8F1DD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE85FF9B8F1DD0A17CE7 = {
+			fileRef = 00E4CE81FF9B8F1DD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE86FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = ssl2map.c;
+			refType = 4;
+		};
+		00E4CE87FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = ssl2mesg.c;
+			refType = 4;
+		};
+		00E4CE88FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = ssl2prot.c;
+			refType = 4;
+		};
+		00E4CE89FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = ssl2rec.c;
+			refType = 4;
+		};
+		00E4CE8AFF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = hdskcert.c;
+			refType = 4;
+		};
+		00E4CE8BFF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = hdskchgc.c;
+			refType = 4;
+		};
+		00E4CE8CFF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = hdskfini.c;
+			refType = 4;
+		};
+		00E4CE8DFF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = hdskhelo.c;
+			refType = 4;
+		};
+		00E4CE8EFF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = hdskkeys.c;
+			refType = 4;
+		};
+		00E4CE8FFF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = hdskkyex.c;
+			refType = 4;
+		};
+		00E4CE90FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslhdshk.c;
+			refType = 4;
+		};
+		00E4CE91FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = cipherSpecs.c;
+			refType = 4;
+		};
+		00E4CE92FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslBER.cpp;
+			refType = 4;
+		};
+		00E4CE94FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = symCipher.c;
+			refType = 4;
+		};
+		00E4CE95FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = digests.c;
+			refType = 4;
+		};
+		00E4CE96FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = md5.c;
+			refType = 4;
+		};
+		00E4CE97FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = nullciph.c;
+			refType = 4;
+		};
+		00E4CE98FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = sha.c;
+			refType = 4;
+		};
+		00E4CE99FF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslalloc.c;
+			refType = 4;
+		};
+		00E4CE9AFF9B8FE5D0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslutil.c;
+			refType = 4;
+		};
+		00E4CE9BFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE91FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE9CFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE92FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE9EFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE94FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CE9FFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE99FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA0FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE9AFF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA1FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE95FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA2FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE96FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA3FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE97FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA4FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE98FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA5FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE86FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA6FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE87FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA7FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE88FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA8FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE89FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEA9FF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE8AFF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEAAFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE8BFF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEABFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE8CFF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEACFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE8DFF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEADFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE8EFF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEAEFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE8FFF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEAFFF9B8FE5D0A17CE7 = {
+			fileRef = 00E4CE90FF9B8FE5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEB0FF9B909FD0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslalert.c;
+			refType = 4;
+		};
+		00E4CEB1FF9B909FD0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslctx.c;
+			refType = 4;
+		};
+		00E4CEB2FF9B909FD0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslrec.c;
+			refType = 4;
+		};
+		00E4CEB3FF9B909FD0A17CE7 = {
+			isa = PBXFileReference;
+			path = sslsess.c;
+			refType = 4;
+		};
+		00E4CEB4FF9B909FD0A17CE7 = {
+			isa = PBXFileReference;
+			path = ssltrspt.c;
+			refType = 4;
+		};
+		00E4CEB5FF9B909FD0A17CE7 = {
+			isa = PBXFileReference;
+			name = CipherSuite.h;
+			path = SecureTransport/CipherSuite.h;
+			refType = 4;
+		};
+		00E4CEB6FF9B909FD0A17CE7 = {
+			isa = PBXFileReference;
+			name = SecureTransport.h;
+			path = SecureTransport/SecureTransport.h;
+			refType = 4;
+		};
+		00E4CEB7FF9B909FD0A17CE7 = {
+			fileRef = 00E4CEB5FF9B909FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEB8FF9B909FD0A17CE7 = {
+			fileRef = 00E4CEB6FF9B909FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEB9FF9B909FD0A17CE7 = {
+			fileRef = 00E4CEB0FF9B909FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEBAFF9B909FD0A17CE7 = {
+			fileRef = 00E4CEB1FF9B909FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEBBFF9B909FD0A17CE7 = {
+			fileRef = 00E4CEB2FF9B909FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEBCFF9B909FD0A17CE7 = {
+			fileRef = 00E4CEB3FF9B909FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEBDFF9B909FD0A17CE7 = {
+			fileRef = 00E4CEB4FF9B909FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEBEFF9B99B0D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 00E4CE38FF9B8CA8D0A17CE7;
+		};
+		00E4CEBFFF9B9A4ED0A17CE7 = {
+			isa = PBXFileReference;
+			path = secureTransport.exp;
+			refType = 4;
+		};
+		00E4CEC0FF9B9A4ED0A17CE7 = {
+			fileRef = 00E4CEBFFF9B9A4ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00E4CEC1FF9BA51FD0A17CE7 = {
+			isa = PBXFileReference;
+			path = cppUtils.cpp;
+			refType = 4;
+		};
+		00E4CEC2FF9BA51FD0A17CE7 = {
+			fileRef = 00E4CEC1FF9BA51FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0145E21BFFEED50A7F000001 = {
+			isa = PBXFileReference;
+			path = ModuleAttacher.cpp;
+			refType = 4;
+		};
+		0145E21CFFEED50A7F000001 = {
+			isa = PBXFileReference;
+			path = ModuleAttacher.h;
+			refType = 4;
+		};
+		0145E21DFFEED50A7F000001 = {
+			fileRef = 0145E21CFFEED50A7F000001;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0145E21EFFEED50A7F000001 = {
+			fileRef = 0145E21BFFEED50A7F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1F123554FF9CE352D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			name = cdsa.framework;
+			path = /System/Library/PrivateFrameworks/cdsa.framework;
+			refType = 0;
+		};
+		1F123555FF9CE352D0A17CE7 = {
+			fileRef = 1F123554FF9CE352D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1F123556FF9CE3A5D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			name = cdsa_utilities.framework;
+			path = /System/Library/PrivateFrameworks/cdsa_utilities.framework;
+			refType = 0;
+		};
+		1F123557FF9CE3A5D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			name = CoreFoundation.framework;
+			path = /System/Library/Frameworks/CoreFoundation.framework;
+			refType = 0;
+		};
+		1F123558FF9CE3A5D0A17CE7 = {
+			fileRef = 1F123556FF9CE3A5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1F123559FF9CE3A5D0A17CE7 = {
+			fileRef = 1F123557FF9CE3A5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1F12355AFF9CE43ED0A17CE7 = {
+			children = (
+				1F123554FF9CE352D0A17CE7,
+				1F123556FF9CE3A5D0A17CE7,
+				1F123557FF9CE3A5D0A17CE7,
+				1F12355BFF9CE43ED0A17CE7,
+				1F12355CFF9CE43ED0A17CE7,
+			);
+			isa = PBXGroup;
+			name = Frameworks;
+			refType = 4;
+		};
+		1F12355BFF9CE43ED0A17CE7 = {
+			isa = PBXFrameworkReference;
+			name = SecuritySNACCRuntime.framework;
+			path = /System/Library/PrivateFrameworks/SecuritySNACCRuntime.framework;
+			refType = 0;
+		};
+		1F12355CFF9CE43ED0A17CE7 = {
+			isa = PBXFrameworkReference;
+			name = SecurityASN1.framework;
+			path = /System/Library/PrivateFrameworks/SecurityASN1.framework;
+			refType = 0;
+		};
+		1F12355DFF9CE43ED0A17CE7 = {
+			fileRef = 1F12355BFF9CE43ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1F12355EFF9CE43ED0A17CE7 = {
+			fileRef = 1F12355CFF9CE43ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		48499A08FFCB05657F000001 = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		48499A09FFCB05657F000001 = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+	};
+	rootObject = 00E4CE33FF9B8B71D0A17CE7;
+}
diff --git a/SecureTransport/SecureTransport/CipherSuite.h b/SecureTransport/SecureTransport/CipherSuite.h
new file mode 100644
index 00000000..b7195b1d
--- /dev/null
+++ b/SecureTransport/SecureTransport/CipherSuite.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		CipherSuite.h
+
+	Contains:	SSL Cipher Suite definitions. 
+
+	Written by:	Doug Mitchell, based in Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+#ifndef _CIPHER_SUITE_H_
+#define _CIPHER_SUITE_H_
+
+/* fetch Uint32 */
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+/*
+ * Defined as enum for debugging, but in the protocol
+ * it is actually exactly two bytes
+ */
+typedef UInt32 SSLCipherSuite;
+
+enum
+{   SSL_NULL_WITH_NULL_NULL =                   0x0000,
+    SSL_RSA_WITH_NULL_MD5 =                     0x0001,
+    SSL_RSA_WITH_NULL_SHA =                     0x0002,
+    SSL_RSA_EXPORT_WITH_RC4_40_MD5 =            0x0003,
+    SSL_RSA_WITH_RC4_128_MD5 =                  0x0004,
+    SSL_RSA_WITH_RC4_128_SHA =                  0x0005,
+    SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 =        0x0006,
+    SSL_RSA_WITH_IDEA_CBC_SHA =                 0x0007,
+    SSL_RSA_EXPORT_WITH_DES40_CBC_SHA =         0x0008,
+    SSL_RSA_WITH_DES_CBC_SHA =                  0x0009,
+    SSL_RSA_WITH_3DES_EDE_CBC_SHA =             0x000A,
+    SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA =      0x000B,
+    SSL_DH_DSS_WITH_DES_CBC_SHA =               0x000C,
+    SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA =          0x000D,
+    SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA =      0x000E,
+    SSL_DH_RSA_WITH_DES_CBC_SHA =               0x000F,
+    SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA =          0x0010,
+    SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA =     0x0011,
+    SSL_DHE_DSS_WITH_DES_CBC_SHA =              0x0012,
+    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA =         0x0013,
+    SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA =     0x0014,
+    SSL_DHE_RSA_WITH_DES_CBC_SHA =              0x0015,
+    SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA =         0x0016,
+    SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 =        0x0017,
+    SSL_DH_anon_WITH_RC4_128_MD5 =              0x0018,
+    SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA =     0x0019,
+    SSL_DH_anon_WITH_DES_CBC_SHA =              0x001A,
+    SSL_DH_anon_WITH_3DES_EDE_CBC_SHA =         0x001B,
+    SSL_FORTEZZA_DMS_WITH_NULL_SHA =            0x001C,
+    SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA =    0x001D,
+    SSL_RSA_WITH_RC2_CBC_MD5 =                  0xFF80,     /* These are included to provide tags for */
+    SSL_RSA_WITH_IDEA_CBC_MD5 =                 0xFF81,     /*  SSL 2 cipher kinds which are not specified */
+    SSL_RSA_WITH_DES_CBC_MD5 =                  0xFF82,     /*  for SSL 3 */
+    SSL_RSA_WITH_3DES_EDE_CBC_MD5 =             0xFF83,
+    SSL_NO_SUCH_CIPHERSUITE =                   0xFFFF
+};
+
+#endif	/* _CIPHER_SUITE_H_ */
diff --git a/SecureTransport/SecureTransport/SecureTransport.h b/SecureTransport/SecureTransport/SecureTransport.h
new file mode 100644
index 00000000..73740e98
--- /dev/null
+++ b/SecureTransport/SecureTransport/SecureTransport.h
@@ -0,0 +1,573 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		SecureTransport.h
+
+	Contains:	Public API for Apple SSL 3.0 Implementation
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef _SECURE_TRANSPORT_H_
+#define _SECURE_TRANSPORT_H_
+
+/*
+ * Initial X port: no keychain storage of certs; no server mode, no
+ * client-side authentication. 
+ */
+#define ST_KEYCHAIN_ENABLE			0
+#define ST_SERVER_MODE_ENABLE		0
+#define ST_CLIENT_AUTHENTICATION	0
+
+/*
+ * This file describes the public API for an implementation of the 
+ * Secure Socket Layer, V. 3.0. This implementation is based on Netscape's
+ * SSLRef 3.0, modified for Apple use. (Appropriate copyrights and
+ * acknowledgements are found elsewhere, and in all files containing 
+ * Netscape code.)
+ *
+ * As in SSLRef 3.0, there no transport layer dependencies in this library;
+ * it can be used with sockets, Open Transport, etc. Applications using
+ * this library provide callback functions which do the actual I/O
+ * on underlying network connections. Applications are also responsible
+ * for setting up raw network connections; the application passes in
+ * an opaque reference to the underlying (connected) entity at the 
+ * start of an SSL session.
+ *
+ * Some terminology:
+ *
+ * A "client" is the initiator of an SSL Session. The canonical example
+ * of a client is a web browser, when it's talking to an https URL. 
+ *
+ * A "server" is an entity which accepts requests for SSL sessions made
+ * by clients. E.g., a secure web server. 
+ 
+ * An "SSL Session", or "session", is bounded by calls to SSLHandshake()
+ * and SSLClose(). An "Active session" is in some state between these
+ * two calls, inclusive.
+ * 
+ * An SSL Session Context, or SSLContextRef, is an opaque reference in this
+ * library to the state associated with one session.  
+ */ 
+ 
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+//#include <CoreServices/CoreServices.h>
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFArray.h>
+#include <Security/CipherSuite.h>
+
+#if		ST_KEYCHAIN_ENABLE
+#include <Keychain.h>
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************
+ *** Common typedefs ***
+ ***********************/
+ 
+/* Opaque reference to an SSL session context */
+struct                      SSLContext;
+typedef struct SSLContext   *SSLContextRef;
+
+/* Opaque reference to an I/O conection (socket, Endpoint, etc.) */
+typedef const void *		SSLConnectionRef;
+
+/* SSL Protocol version */
+typedef enum {
+	kSSLProtocolUnknown,		/* no protocol negotiated/specified */
+	kSSLProtocol2,				/* SSL 2.0 only */
+	kSSLProtocol3,				/* SSL 3.0 preferred, 2.0 OK if peer requires */
+	kSSLProtocol3Only			/* use SSL 3.0 only, fail if peer tries to
+								 * negotiate 2.0 */
+} SSLProtocol;
+
+/* State of an SSLSession */
+typedef enum {
+	kSSLIdle,					/* no I/O performed yet */
+	kSSLHandshake,				/* SSL handshake in progress */
+	kSSLConnected,				/* Handshake complete, ready for normal I/O */
+	kSSLClosed,					/* connection closed normally */
+	kSSLAborted					/* connection aborted */
+} SSLSessionState;
+
+/* 
+ * R/W functions. The application using this library provides
+ * these functions via SSLSetIOFuncs().
+ *
+ * Data's memory is allocated by caller; on entry to these two functions
+ * the *length argument indicates both the size of the available data and the
+ * requested byte count. Number of bytes actually transferred is returned in 
+ * *length.
+ *
+ * The application may configure the underlying connection to operate
+ * in a non-blocking manner; in such a case, a read operation may
+ * well return SSLWouldBlockErr, indicating "I transferred less data than
+ * you requested (maybe even zero bytes), nothing is wrong, except 
+ * requested I/O hasn't completed". This will be returned back up to 
+ * the application as a return from SSLRead(), SSLWrite(), SSLHandshake(),
+ * etc. 
+ */
+typedef OSStatus 
+(*SSLReadFunc) 				(SSLConnectionRef 	connection,
+							 void 				*data, 			/* owned by 
+							 									 * caller, data
+							 									 * RETURNED */
+							 UInt32 			*dataLength);	/* IN/OUT */ 
+typedef OSStatus 
+(*SSLWriteFunc) 			(SSLConnectionRef 	connection,
+							 const void 		*data, 
+							 UInt32 			*dataLength);	/* IN/OUT */ 
+
+
+/*************************************************
+ *** OSStatus values unique to SecureTransport ***
+ *************************************************/
+ 
+enum {
+	errSSLProtocol				= -9800,	/* SSL protocol error */
+	errSSLNegotiation			= -9801,	/* Cipher Suite negotiation failure */
+	errSSLFatalAlert			= -9802,	/* Fatal alert */
+	errSSLWouldBlock			= -9803,	/* I/O would block (not fatal) */
+    errSSLSessionNotFound 		= -9804,	/* attempt to restore an unknown
+    										 *    session */
+    errSSLClosedGraceful 		= -9805,	/* connection closed gracefully */
+    errSSLClosedAbort 			= -9806,	/* connection closed via error */
+    errSSLXCertChainInvalid 	= -9807,	/* Invalid certificate chain */
+    errSSLBadCert				= -9808,	/* bad certificate format */
+	errSSLCrypto				= -9809,	/* underlying cryptographic error */
+	errSSLInternal				= -9810,	/* Internal error */
+	errSSLModuleAttach			= -9811,	/* module attach failure */
+    errSSLUnknownRootCert		= -9812,	/* valid cert chain, untrusted root */
+    errSSLNoRootCert			= -9813,	/* cert chain not verified by root */
+	errSSLCertExpired			= -9814,	/* chain had an expired cert */
+	errSSLCertNotYetValid		= -9815,	/* chain had a cert not yet valid */
+	errSSLClosedNoNotify		= -9816,	/* server closed session with no 
+											 *     notification */
+	errSSLBufferOverflow		= -9817,	/* insufficient buffer provided */
+	errSSLBadCipherSuite		= -9818,	/* bad SSLCipherSuite */
+	errSSLLast					= -9849		/* end of range, to be deleted */
+};
+
+
+/******************
+ *** Public API ***
+ ******************/
+
+/* 
+ * Create a new session context.
+ */
+OSStatus
+SSLNewContext				(Boolean 			isServer,
+							 SSLContextRef 		*contextPtr);	/* RETURNED */
+
+/*
+ * Dispose of an SSLContextRef.
+ */
+OSStatus
+SSLDisposeContext			(SSLContextRef		context);
+
+/*
+ * Determine the state of an SSL session.
+ */
+OSStatus 
+SSLGetSessionState			(SSLContextRef		context,
+							 SSLSessionState	*state);	/* RETURNED */
+							 
+							 
+/********************************************************************
+ *** Session context configuration, common to client and servers. ***
+ ********************************************************************/
+ 
+/* 
+ * Specify functions which do the network I/O. Must be called prior
+ * to SSLHandshake(); subsequently can not be called while a session is
+ * active. 
+ */
+OSStatus 
+SSLSetIOFuncs				(SSLContextRef		context, 
+							 SSLReadFunc 		read,
+							 SSLWriteFunc		write);
+							 
+/* 
+ * Get/set SSL protocol version; optional. Default for client is is 
+ * kSSLProtocolUnknown (which works with whatever the server prefers);
+ * default for server side is kSSLProtocol3 (which prefers SSL3 but
+ * works with SSL2-only clients). 
+ *
+ * SSLSetProtocolVersion can not be called when a session is active. 
+ */
+OSStatus 
+SSLSetProtocolVersion		(SSLContextRef 		context,
+							 SSLProtocol		version);
+
+OSStatus 
+SSLGetProtocolVersion		(SSLContextRef		context,
+							 SSLProtocol		*protocol);		/* RETURNED */
+
+#if		(ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION)
+
+/*
+ * Specify this connection's certificate(s). This is mandatory for
+ * server connections, optional for clients. Specifying a certificate
+ * for a client enables SSL client-side authentication. The end-entity
+ * cert is in certRef[0]. Specifying a root cert is optional; if it's
+ * not specified, the root cert which verifies the cert chain specified
+ * here must have been specified in SSLSetTrustedRootCertKC().
+ *
+ * The certRefs argument is a CFArray containing KCItemRefs. 
+ *
+ * Can only be called when no session is active. 
+ *
+ * SecureTransport assumes the following:
+ *   
+ *	-- The certRef references remains valid for the lifetime of the 
+ *     session.
+ *  -- The specified certRef[0] is capable of signing. 
+ *  -- In order for a server connection to work with SSL3 protocol,
+ *     the private key associated with certRef[0] must ALSO be
+ *	   capable of decryption. This is a workaround for a known 
+ * 	   Netscape bug.  
+ */
+OSStatus
+SSLSetCertificate			(SSLContextRef		context,
+							 CFArrayRef			certRefs);
+
+#endif	/* (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION) */
+
+#if		ST_KEYCHAIN_ENABLE
+
+/*
+ * Specify a Keychain containing trusted root certificates.
+ * Optional; the Keychain's root certs either are appended to or 
+ * replace the existing SSLContextRef's root certs, which are initialized
+ * to a system-wide set of trusted roots at SSLContextAlloc().
+ *
+ * Can not be called while a session is active.
+ */
+OSStatus
+SSLSetTrustedRootCertKC		(SSLContextRef		context,
+							 KCRef				keyChainRef,
+							 Boolean			deleteExisting);
+							 
+/*
+ * Specify a Keychain (and access credentials for the keychain)
+ * to which newly encountered root certs are attempted to be
+ * added. This may or may not result in user interaction, depending
+ * on the configuration of the keychain and of the specified
+ * accesssCreds.
+ *
+ * Can not be called while a session is active and can only be
+ * called a maximum of one time per SSLContextRef.
+ */
+OSStatus 
+SSLSetNewRootKC				(SSLContextRef		context,
+							 KCRef				keyChainRef,
+							 void				*accessCreds);
+	
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+/*
+ * Specify I/O connection - a socket, endpoint, etc., which is
+ * managed by caller. On the client side, it's assumed that communication
+ * has been established with the desired server on this connection.
+ * On the server side, it's assumed that an incoming client request
+ * has been established. 
+ *
+ * Must be called prior to SSLHandshake(); subsequently can only be
+ * called when no session is active.
+ */
+OSStatus
+SSLSetConnection			(SSLContextRef		context,
+							 SSLConnectionRef	connection);
+
+/*
+ * Obtain the actual negotiated protocol version of the active
+ * session, which may be different that the value specified in 
+ * SSLSetProtocolVersion(). Returns kSSLProtocolUnknown if no 
+ * SSL session is in progress.
+ */
+OSStatus 
+SSLGetNegotiatedProtocolVersion		(SSLContextRef		context,
+									 SSLProtocol		*protocol); /* RETURNED */
+
+/*
+ * Determine number and values of all of the SSLCipherSuites we support.
+ * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
+ * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
+ * will be returned. 
+ */
+OSStatus
+SSLGetNumberSupportedCiphers (SSLContextRef			context,
+							  UInt32				*numCiphers);
+			
+OSStatus
+SSLGetSupportedCiphers		 (SSLContextRef			context,
+							  SSLCipherSuite		*ciphers,		/* RETURNED */
+							  UInt32				*numCiphers);	/* IN/OUT */
+
+/*
+ * Specify a (typlically) restricted set of SSLCipherSuites to be enabled by
+ * the current SSLContext. Can only be called when no session is active. Default
+ * set of enabled SSLCipherSuites is the same as the complete set of supported 
+ * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
+ */
+OSStatus 
+SSLSetEnabledCiphers		(SSLContextRef			context,
+							 const SSLCipherSuite	*ciphers,	
+							 UInt32					numCiphers);
+							 
+/*
+ * Determine number and values of all of the SSLCipherSuites currently enabled.
+ * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
+ * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
+ * will be returned. 
+ */
+OSStatus
+SSLGetNumberEnabledCiphers 	(SSLContextRef			context,
+							 UInt32					*numCiphers);
+			
+OSStatus
+SSLGetEnabledCiphers		(SSLContextRef			context,
+							 SSLCipherSuite			*ciphers,		/* RETURNED */
+							 UInt32					*numCiphers);	/* IN/OUT */
+
+
+/*
+ * Specify the option of ignoring certificates' "expired" times. 
+ * This is a common failure in the real SSL world. Default for 
+ * this flag is false, meaning expired certs result in a
+ * errSSLCertExpired error.
+ */ 
+OSStatus 
+SSLSetAllowExpiredCerts		(SSLContextRef		context,
+							 Boolean			allowExpired);
+							 
+/* 
+ * Obtain the current value of an SSLContext's "allowExpiredCerts" flag. 
+ */
+OSStatus
+SSLGetAllowExpiredCerts		(SSLContextRef		context,
+							 Boolean			*allowExpired); /* RETURNED */
+
+/*
+ * Specify option of allowing for an unknown root cert, i.e., one which
+ * this software can not verify as one of a list of known good root certs. 
+ * Default for this flag is false, in which case one of the following two
+ * errors may occur:
+ *    -- The peer returns a cert chain with a root cert, and the chain 
+ *       verifies to that root, but the root is not one of our trusted
+ *       roots. This results in errSSLUnknownRootCert on handshake. 
+ *    -- The peer returns a cert chain which does not contain a root cert,
+ *       and we can't verify the chain to one of our trusted roots. This 
+ *       results in errSSLNoRootCert on handshake.
+ *
+ * Both of these error conditions are ignored when the AllowAnyRoot flag is true,
+ * allowing connection to a totally untrusted peer. 
+ */
+OSStatus 
+SSLSetAllowAnyRoot			(SSLContextRef		context,
+							 Boolean			anyRoot);
+
+/* 
+ * Obtain the current value of an SSLContext's "allow any root" flag. 
+ */
+OSStatus
+SSLGetAllowAnyRoot			(SSLContextRef		context,
+							 Boolean			*anyRoot); /* RETURNED */
+
+/*
+ * Request peer certificates. Valid anytime, subsequent to
+ * a handshake attempt.
+ *
+ * The certs argument is a CFArray containing CFDataRefs, each
+ * of which is one DER-encoded cert. The entire array is mallocd
+ * by the SecureTransport library. The cert at the end of the 
+ * returned array is the subject (end entity) cert; the root cert
+ * (or the closest cert to it) is in index 0 of the returned array. 
+ */	
+OSStatus 
+SSLGetPeerCertificates		(SSLContextRef 		context, 
+							 CFArrayRef			*certs);	/* RETURNED */
+							 								 
+/*
+ * Specify some data, opaque to this library, which is sufficient
+ * to uniquely identify the peer of the current session. An example
+ * would be IP address and port, stored in some caller-private manner.
+ * To be optionally called prior to SSLHandshake for the current 
+ * session. This is mandatory if this session is to be resumable. 
+ */
+OSStatus 
+SSLSetPeerID				(SSLContextRef 		context, 
+							 CFDataRef 			peerID);
+
+/*
+ * Obtain the SSLCipherSuite (e.g., SSL_RSA_WITH_DES_CBC_SHA) negotiated
+ * for this session. Only valid when a session is active.
+ */
+OSStatus 
+SSLGetNegotiatedCipher		(SSLContextRef 		context,
+							 SSLCipherSuite 	*cipherSuite);
+
+
+/********************************************************
+ *** Session context configuration, server side only. ***
+ ********************************************************/
+				 
+#if		ST_SERVER_MODE_ENABLE
+/*
+ * Specify this connection's encryption certificate(s). This is
+ * used in one of the following cases:
+ *
+ *	-- The end-entity certificate specified in SSLSetCertificate() is 
+ *	   not capable of encryption. (THIS REQUIREMENT IS OBSOLETE due
+ *	   due a workaround for a Netscape bug.)
+ *
+ *  -- The end-entity certificate specified in SSLSetCertificate() 
+ * 	   contains a key which is too large (i.e., too strong) for legal 
+ *	   encryption in this session. In this case a weaker cert is 
+ *     specified here and is used for server-initiated key exchange. 
+ *
+ *  -- Servers which establsh an SSL level 2 connection require
+ *     encryption certs. (SSL2 does not perform signing and verification,
+ *     only asymmetric encryption and decryption.)
+ *
+ *  The encryptionCertRef argument is a CFArray containing 
+ *  KCItemRefs. 
+ *
+ * The following assumptions are made:
+ *
+ *	-- The encryptionCertRef references remains valid for the lifetime of the 
+ *     connection.
+ *  -- The specified encryptionCertRef[0] is capable of encryption. 
+ *
+ * Can only be called when no session is active. 
+ *
+ * Notes:
+ * ------
+ *
+ * -- SSL servers which enforce the SSL3 spec to the letter will
+ *    not accept encryption certs with key sizes larger than 512
+ *    bits for exportable ciphers. Apps which wish to use encryption 
+ *    certs with key sizes larger than 512 bits should disable the 
+ *    use of exportable ciphers via the SSLSetExportEnable() call. 
+ */
+OSStatus
+SSLSetEncryptionCertificate	(SSLContextRef		context,
+							 CFArrayRef			certRefs);
+
+/*
+ * Specify requirements for client-side authentication.
+ * Optional; Default is kNeverAuthenticate, unless SSLSetTrustedRootCertKC
+ * has been called, in which case the default is kTryAuthenticate.
+ *
+ * Can only be called when no session is active.  
+ */
+typedef enum {
+	kNeverAuthenticate,			/* skip client authentication */
+	kAlwaysAuthenticate,		/* require it */
+	kTryAuthenticate			/* try to authenticate, but not an error
+								 * if client doesn't have a cert */
+} SSLAuthenticate;
+
+OSStatus
+SSLSetClientSideAuthenticate 	(SSLContextRef		context,
+								 SSLAuthenticate	auth);
+		
+#endif	/* ST_SERVER_MODE_ENABLE */
+
+/*******************************
+ ******** I/O Functions ********
+ *******************************/
+ 
+/*
+ * Note: depending on the configuration of the underlying I/O 
+ * connection, all SSL I/O functions can return SSLWouldBlockErr,
+ * indicating "not complete, nothing is wrong, except required
+ * I/O hasn't completed". Caller may need to repeat I/Os as necessary
+ * if the underlying connection has been configured to behave in 
+ * a non-blocking manner.
+ */
+  
+/*
+ * Perform the SSL handshake. On successful return, session is 
+ * ready for normal secure application I/O via SSLWrite and SSLRead.
+ *
+ * Interesting error returns:
+ *
+ *	errSSLUnknownRootCert: Peer had a valid cert chain, but the root of 
+ *		the chain is unknown. 
+ *
+ * 	errSSLNoRootCert: Peer had a cert chain which was not verifiable
+ *		to a root cert. Handshake was aborted; peer's cert chain
+ *		available via SSLGetPeerCertificates().
+ *
+ * 	errSSLCertExpired: Peer's cert chain had one or more expired certs.
+ *
+ *  errSSLXCertChainInvalid: Peer had an invalid cert chain (i.e.,
+ *		signature verification within the chain failed, or no certs
+ *		were found). 
+ *
+ *  In all of the above errors, the handshake was aborted; peer's 
+ *  cert chain available via SSLGetPeerCertificates().
+ *
+ * A return value of errSSLWouldBlock indicates that SSLHandshake has to be called
+ * again (and again and again until something else is returned).
+ */ 	 
+OSStatus 
+SSLHandshake				(SSLContextRef		context);
+
+/*
+ * Normal application-level read/write. On both of these, a errSSLWouldBlock
+ * return and a partially completed transfer - or even zero bytes transferred -
+ * are NOT mutually exclusive. 
+ */
+OSStatus 
+SSLWrite					(SSLContextRef		context,
+							 const void *		data,
+							 UInt32				dataLength,
+							 UInt32 			*processed);	/* RETURNED */ 
+
+/*
+ * data is mallocd by caller; available size specified in
+ * dataLength; actual number of bytes read returned in
+ * *processed.
+ */
+OSStatus 
+SSLRead						(SSLContextRef		context,
+							 void *				data,			/* RETURNED */
+							 UInt32				dataLength,
+							 UInt32 			*processed);	/* RETURNED */ 
+							 
+/*
+ * Terminate current SSL session. 
+ */
+OSStatus 
+SSLClose					(SSLContextRef		context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SECURE_TRANSPORT_H_ */
diff --git a/SecureTransport/appleCdsa.c b/SecureTransport/appleCdsa.c
new file mode 100644
index 00000000..9349bfac
--- /dev/null
+++ b/SecureTransport/appleCdsa.c
@@ -0,0 +1,1508 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		appleCdsa.c
+
+	Contains:	interface between SSL and CDSA
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+#include "sslctx.h"
+#include "sslalloc.h"
+#include "appleCdsa.h"
+#include "sslerrs.h"
+#include "sslutil.h"
+#include "sslDebug.h"
+#include "sslBER.h"
+#include "ModuleAttacher.h"
+
+#ifndef	_SSL_KEYCHAIN_H_
+#include "sslKeychain.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <Security/cssm.h>
+#include <Security/cssmapple.h>
+
+/* X.509 includes, from cssmapi */
+#include <Security/x509defs.h>         /* x.509 function and type defs */
+#include <Security/oidsalg.h>
+#include <Security/oidscert.h>
+
+#pragma mark *** Utilities ***
+
+/*
+ * Free a CSSM_KEY - its CSP resources, KCItemRef, and the key itself.
+ */
+SSLErr sslFreeKey(
+	CSSM_CSP_HANDLE		cspHand,
+	CSSM_KEY_PTR		*key,		/* so we can null it out */
+	#if		ST_KEYCHAIN_ENABLE
+	KCItemRef			*kcItem)	/* optional; ditto */
+	#else
+	void				*kcItem)
+	#endif
+{
+	CASSERT(key != NULL);
+	
+	if(*key != NULL) {
+		if(cspHand != 0) {
+			CSSM_FreeKey(cspHand, NULL, *key, CSSM_FALSE);
+		}
+		sslFree(*key);
+		*key = NULL;
+	}
+	#if		ST_KEYCHAIN_ENABLE
+	if((kcItem != NULL) && (*kcItem != NULL)) {
+		KCReleaseItem(kcItem);		/* does this NULL the referent? */
+		*kcItem = NULL;
+	}
+	#endif
+	return SSLNoErr;
+}
+
+/*
+ * Standard app-level memory functions required by CDSA.
+ */
+void * stAppMalloc (uint32 size, void *allocRef) {
+	return( malloc(size) );
+}
+void stAppFree (void *mem_ptr, void *allocRef) {
+	free(mem_ptr);
+ 	return;
+}
+void * stAppRealloc (void *ptr, uint32 size, void *allocRef) {
+	return( realloc( ptr, size ) );
+}
+void * stAppCalloc (uint32 num, uint32 size, void *allocRef) {
+	return( calloc( num, size ) );
+}
+
+/*
+ * Ensure there's a connection to ctx->cspHand. If there 
+ * already is one, fine.
+ * Note that as of 12/18/00, we assume we're connected to 
+ * all modules all the time (since we do an attachToAll() in 
+ * SSLNewContext()).
+ */
+SSLErr attachToCsp(SSLContext *ctx)
+{
+	CASSERT(ctx != NULL);
+	if(ctx->cspHand != 0) {
+		return SSLNoErr;
+	}	
+	else {
+		return SSLAttachFailure;
+	}
+}
+
+/* 
+ * Connect to TP, CL; reusable.
+ */
+SSLErr attachToCl(SSLContext *ctx)
+{
+	CASSERT(ctx != NULL);
+	if(ctx->clHand != 0) {
+		return SSLNoErr;
+	}
+	else {
+		return SSLAttachFailure;
+	}
+}
+
+SSLErr attachToTp(SSLContext *ctx)
+{
+	CASSERT(ctx != NULL);
+	if(ctx->tpHand != 0) {
+		return SSLNoErr;
+	}
+	else {
+		return SSLAttachFailure;
+	}
+}
+
+/*
+ * Convenience function - attach to CSP, CL, TP. Reusable. 
+ */
+SSLErr attachToAll(SSLContext *ctx)
+{
+	CSSM_RETURN crtn;
+	
+	CASSERT(ctx != NULL);
+	crtn = attachToModules(&ctx->cspHand, &ctx->clHand, 
+		&ctx->tpHand);
+	if(crtn) {
+	   return SSLAttachFailure;
+	}
+	else {
+		return SSLNoErr;
+	}
+}
+
+SSLErr detachFromAll(SSLContext *ctx)
+{
+	#if	0
+	/* No more, attachments are kept on a global basis */
+	CASSERT(ctx != NULL);
+	if(ctx->cspHand != 0) {
+		CSSM_ModuleDetach(ctx->cspHand);
+		ctx->cspHand = 0;
+	}
+	if(ctx->tpHand != 0) {
+		CSSM_ModuleDetach(ctx->tpHand);
+		ctx->tpHand = 0;
+	}
+	if(ctx->clHand != 0) {
+		CSSM_ModuleDetach(ctx->clHand);
+		ctx->clHand = 0;
+	}
+	#endif	/* 0 */
+	return SSLNoErr;
+}
+
+#pragma mark -
+#pragma mark *** CSSM_DATA routines ***
+
+CSSM_DATA_PTR stMallocCssmData(
+	uint32 size)
+{
+	CSSM_DATA_PTR rtn = (CSSM_DATA_PTR)stAppMalloc(sizeof(CSSM_DATA), NULL);
+
+	if(rtn == NULL) {
+		return NULL;
+	}
+	rtn->Length = size;
+	if(size == 0) {
+		rtn->Data = NULL;
+	}
+	else {
+		rtn->Data = (uint8 *)stAppMalloc(size, NULL);
+	}
+	return rtn;
+}
+
+void stFreeCssmData(
+	CSSM_DATA_PTR data,
+	CSSM_BOOL freeStruct)
+{
+	if(data == NULL) {
+		return;
+	}
+	if(data->Data != NULL) {
+		stAppFree(data->Data, NULL);
+		data->Data   = NULL;
+	}
+	data->Length = 0;
+	if(freeStruct) {
+		stAppFree(data, NULL);
+	}
+}
+
+/*
+ * Ensure that indicated CSSM_DATA_PTR can handle 'length' bytes of data.
+ * Malloc the Data ptr if necessary.
+ */
+SSLErr stSetUpCssmData(
+	CSSM_DATA_PTR 	data,
+	uint32 			length)
+{
+	CASSERT(data != NULL);
+	if(data->Length == 0) {
+		data->Data = (uint8 *)stAppMalloc(length, NULL);
+		if(data->Data == NULL) {
+			return SSLMemoryErr;
+		}
+	}
+	else if(data->Length < length) {
+		errorLog0("stSetUpCssmData: length too small\n");
+		return SSLMemoryErr;
+	}
+	data->Length = length;
+	return SSLNoErr;
+}
+
+#pragma mark -
+#pragma mark *** Public CSP Functions ***
+
+/*
+ * Common RNG function; replaces SSLRef's SSLRandomFunc.
+ */
+SSLErr sslRand(SSLContext *ctx, SSLBuffer *buf)
+{
+	CSSM_RETURN 	crtn;
+	CSSM_CC_HANDLE 	rngHand;
+	CSSM_DATA		randData;
+	SSLErr			serr;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(buf != NULL);
+	CASSERT(buf->data != NULL);
+	
+	serr = attachToCsp(ctx);
+	if(serr) {
+		return serr;
+	}
+	if(buf->length == 0) {
+		dprintf0("sslRand: zero buf->length\n");
+		return SSLNoErr;
+	}
+	
+	/*
+	 * We happen to know that the CSP has a really good RNG
+	 * seed if we don't specify anything; let's use it
+	 */
+	crtn = CSSM_CSP_CreateRandomGenContext(ctx->cspHand,
+			CSSM_ALGID_APPLE_YARROW,
+			NULL,				/* seed */
+			buf->length,
+			&rngHand);
+	if(crtn) {
+		stPrintCdsaError("CSSM_CSP_CreateRandomGenContext", crtn);
+		return SSLCryptoError;
+	}
+	SSLBUF_TO_CSSM(buf, &randData);	
+	crtn = CSSM_GenerateRandom(rngHand, &randData);
+	if(crtn) {
+		stPrintCdsaError("CSSM_GenerateRandom", crtn);
+		serr = SSLCryptoError;
+	}
+	CSSM_DeleteContext(rngHand);
+	return serr;
+}
+
+/*
+ * Raw RSA sign/verify.
+ *
+ * Initial X port: CSP doesns't support this, so we'll do sign/verify via
+ * raw RSA encrypt/decrypt here. 
+ */
+#define SIGN_VFY_VIA_ENCR_DECR	0
+
+#if		SIGN_VFY_VIA_ENCR_DECR
+
+SSLErr sslRsaRawSign(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	privKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*plainText,
+	UInt32				plainTextLen,
+	UInt8				*sig,			// mallocd by caller; RETURNED
+	UInt32				sigLen,			// available
+	UInt32				*actualBytes)	// RETURNED
+{
+	/* Raw RSA sign with no digest is the same as raw RSA encrypt. */
+	/* Force CSSM_KEYUSE_ANY in case CL provided keyuse bits more specific 
+	 * than we really want */
+	SSLErr serr;
+	CSSM_KEYUSE savedKeyUse = privKey->KeyHeader.KeyUsage;
+	privKey->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
+	serr = sslRsaEncrypt(ctx,
+		privKey,
+		cspHand,
+		plainText,
+		plainTextLen,
+		sig,	
+		sigLen,
+		actualBytes);
+	privKey->KeyHeader.KeyUsage = savedKeyUse;
+	return serr;
+}
+
+SSLErr sslRsaRawVerify(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	pubKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*plainText,
+	UInt32				plainTextLen,
+	const UInt8			*sig,
+	UInt32				sigLen)	
+{	
+	/* 
+	 * Raw RSA verify with no digest is just a comparison of the incoming
+	 * plaintext with (signature, decrypted via raw RSA decrypt). 
+	 */
+	 
+	UInt32 actualBytes;
+	SSLErr serr;
+	UInt8  *digest;
+	
+	/* Force CSSM_KEYUSE_ANY in case CL provided keyuse bits more specific 
+	 * than we really want */
+	CSSM_KEYUSE savedKeyUse = pubKey->KeyHeader.KeyUsage;
+	pubKey->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
+	
+	/* malloc space for decrypting the signature */
+	digest = sslMalloc(plainTextLen);
+	if(digest == NULL) {
+		return SSLMemoryErr;
+	}
+	
+	/* decrypt signature */
+	serr = sslRsaDecrypt(ctx,
+		pubKey,
+		cspHand,
+		sig,
+		sigLen,		
+		digest,			
+		plainTextLen,	
+		&actualBytes);
+	pubKey->KeyHeader.KeyUsage = savedKeyUse;
+	if(serr) {
+		goto errOut;
+	}
+	if((actualBytes != plainTextLen) ||
+	   (memcmp(plainText, digest, plainTextLen))) {
+		errorLog0("sslRsaRawVerify: sig miscompare\n");
+		serr = SSLCryptoError;
+	}
+	else {
+		serr = SSLNoErr;
+	}
+errOut:
+	sslFree(digest);
+	return serr;
+}
+
+#else	/* OS9 and future post-cheetah version */
+
+SSLErr sslRsaRawSign(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	privKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*plainText,
+	UInt32				plainTextLen,
+	UInt8				*sig,			// mallocd by caller; RETURNED
+	UInt32				sigLen,			// available
+	UInt32				*actualBytes)	// RETURNED
+{
+	CSSM_CC_HANDLE			sigHand = 0;
+	CSSM_RETURN				crtn;
+	SSLErr					serr;
+	CSSM_DATA				sigData;
+	CSSM_DATA				ptextData;
+	
+	CASSERT(ctx != NULL);
+	if((privKey == NULL) 	|| 
+	   (cspHand == 0) 		|| 
+	   (plainText == NULL)	|| 
+	   (sig == NULL)		||
+	   (actualBytes == NULL)) {
+		errorLog0("sslRsaRawSign: bad arguments\n");
+		return SSLInternalError;
+	}
+	*actualBytes = 0;
+	
+	crtn = CSSM_CSP_CreateSignatureContext(cspHand,
+		CSSM_ALGID_RSA,
+		NULL,				// passPhrase
+		privKey,
+		&sigHand);
+	if(crtn) {
+		stPrintCdsaError("CSSM_CSP_CreateSignatureContext (1)", crtn);
+		return SSLCryptoError;
+	}
+	
+	ptextData.Data = (uint8 *)plainText;
+	ptextData.Length = plainTextLen;
+	
+	/* caller better get this right, or the SignData will fail */
+	sigData.Data = sig;
+	sigData.Length = sigLen;
+	
+	crtn = CSSM_SignData(sigHand,
+		&ptextData,
+		1,
+		CSSM_ALGID_NONE,	// digestAlg 
+		&sigData);
+	if(crtn) {
+		stPrintCdsaError("CSSM_SignData", crtn);
+		serr = SSLCryptoError;
+	}
+	else {
+		*actualBytes = sigData.Length;
+		serr = SSLNoErr;
+	}
+	if(sigHand != 0) {
+		CSSM_DeleteContext(sigHand);
+	}
+	return serr;
+}
+
+SSLErr sslRsaRawVerify(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	pubKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*plainText,
+	UInt32				plainTextLen,
+	const UInt8			*sig,
+	UInt32				sigLen)	
+{
+	CSSM_CC_HANDLE			sigHand = 0;
+	CSSM_RETURN				crtn;
+	SSLErr					serr;
+	CSSM_DATA				sigData;
+	CSSM_DATA				ptextData;
+	
+	CASSERT(ctx != NULL);
+	if((pubKey == NULL) 	|| 
+	   (cspHand == 0) 		|| 
+	   (plainText == NULL)	|| 
+	   (sig == NULL)) {
+		errorLog0("sslRsaRawVerify: bad arguments\n");
+		return SSLInternalError;
+	}
+	
+	crtn = CSSM_CSP_CreateSignatureContext(cspHand,
+		CSSM_ALGID_RSA,
+		NULL,				// passPhrase
+		pubKey,
+		&sigHand);
+	if(sigHand == 0) {
+		stPrintCdsaError("CSSM_CSP_CreateSignatureContext (2)", crtn);
+		return SSLCryptoError;
+	}
+	
+	ptextData.Data = (uint8 *)plainText;
+	ptextData.Length = plainTextLen;
+	sigData.Data = (uint8 *)sig;
+	sigData.Length = sigLen;
+	
+	crtn = CSSM_VerifyData(sigHand,
+		&ptextData,
+		1,
+		CSSM_ALGID_NONE,		// digestAlg
+		&sigData);
+	if(crtn) {
+		stPrintCdsaError("CSSM_VerifyData", crtn);
+		serr = SSLCryptoError;
+	}
+	else {
+		serr = SSLNoErr;
+	}
+	if(sigHand != 0) {
+		CSSM_DeleteContext(sigHand);
+	}
+	return serr;
+}
+#endif	/* SIGN_VFY_VIA_ENCR_DECR */
+
+/*
+ * Encrypt/Decrypt
+ */
+#if		APPLE_DOMESTIC_CSP_REQUIRED
+
+/*
+ * Mucho work needed to get this functionality out of export CSP....
+ */
+
+SSLErr sslRsaEncrypt(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	pubKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*plainText,
+	UInt32				plainTextLen,
+	UInt8				*cipherText,		// mallocd by caller; RETURNED 
+	UInt32				cipherTextLen,		// available
+	UInt32				*actualBytes)		// RETURNED
+{
+	CSSM_DATA 		ctextData = {0, NULL};
+	CSSM_DATA 		ptextData;
+	CSSM_DATA		remData = {0, NULL};
+	CSSM_CC_HANDLE 	cryptHand = 0;
+	SSLErr			serr = SSLInternalError;
+	CSSM_RETURN		crtn;
+	uint32			bytesMoved = 0;
+	CSSM_ACCESS_CREDENTIALS	creds;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(actualBytes != NULL);
+	*actualBytes = 0;
+	
+	if((pubKey == NULL) || (cspHand == 0)) {
+		errorLog0("sslRsaEncrypt: bad pubKey/cspHand\n");
+		return SSLInternalError;
+	}
+	
+	#if		RSA_PUB_KEY_USAGE_HACK
+	pubKey->KeyHeader.KeyUsage |= CSSM_KEYUSE_ENCRYPT;
+	#endif
+	memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+	
+	crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
+		CSSM_ALGID_RSA,
+		&creds,
+		pubKey,
+		CSSM_PADDING_NONE,
+		&cryptHand);
+	if(crtn) {
+		stPrintCdsaError("CSSM_CSP_CreateAsymmetricContext", crtn);
+		return SSLCryptoError;
+	}
+	ptextData.Data = (uint8 *)plainText;
+	ptextData.Length = plainTextLen;
+	
+	if(pubKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY) {
+		/* 
+		 * Special case, encrypting with private key (i.e., raw sign). Add
+		 * the required context attr.
+		 */
+		CSSM_CONTEXT_ATTRIBUTE	modeAttr;
+		
+		modeAttr.AttributeType     = CSSM_ATTRIBUTE_MODE;
+		modeAttr.AttributeLength   = sizeof(uint32);
+		modeAttr.Attribute.Uint32  = CSSM_ALGMODE_PRIVATE_KEY;
+		crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &modeAttr);
+		if(crtn) {
+			stPrintCdsaError("CSSM_UpdateContextAttributes", crtn);
+			CSSM_DeleteContext(cryptHand);
+			return SSLCryptoError;
+		}
+	}
+	
+	/* 
+	 * Have CSP malloc ciphertext 
+	 */
+	crtn = CSSM_EncryptData(cryptHand,
+		&ptextData,
+		1,
+		&ctextData,
+		1,
+		&bytesMoved,
+		&remData);
+	if(crtn == CSSM_OK) {
+		/* 
+		 * ciphertext in both ctextData and remData; ensure it'll fit
+		 * in caller's buf & copy 
+		 */
+		if(bytesMoved > cipherTextLen) {
+			errorLog2("sslRsaEncrypt overflow; cipherTextLen %ld bytesMoved %ld\n",
+				cipherTextLen, bytesMoved);
+			serr = SSLDataOverflow;
+		}
+		else {
+			UInt32 toMoveCtext;
+			UInt32 toMoveRem;
+			
+			*actualBytes = bytesMoved;
+			/* 
+			 * Snag valid data from ctextData - its length or bytesMoved, 
+			 * whichever is less
+			 */
+			if(ctextData.Length > bytesMoved) {
+				/* everything's in ctext */
+				toMoveCtext = bytesMoved;
+				toMoveRem = 0;
+			}
+			else {
+				/* must be some in remData too */
+				toMoveCtext = ctextData.Length;
+				toMoveRem = bytesMoved - toMoveCtext;		// remainder 
+			}
+			if(toMoveCtext) {
+				memmove(cipherText, ctextData.Data, toMoveCtext);
+			}
+			if(toMoveRem) {
+				memmove(cipherText + toMoveCtext, remData.Data,
+					toMoveRem);
+			}
+			serr = SSLNoErr;
+		}
+	}
+	else {
+		stPrintCdsaError("CSSM_EncryptData", crtn);
+		serr = SSLCryptoError;
+	}
+	if(cryptHand != 0) {
+		CSSM_DeleteContext(cryptHand);
+	}
+
+	/* free data mallocd by CSP */
+	stFreeCssmData(&ctextData, CSSM_FALSE);
+	stFreeCssmData(&remData, CSSM_FALSE);
+	return serr;
+}
+
+SSLErr sslRsaDecrypt(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	privKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*cipherText,
+	UInt32				cipherTextLen,		
+	UInt8				*plainText,			// mallocd by caller; RETURNED
+	UInt32				plainTextLen,		// available
+	UInt32				*actualBytes)		// RETURNED
+{
+	CSSM_DATA 		ptextData = {0, NULL};
+	CSSM_DATA 		ctextData;
+	CSSM_DATA		remData = {0, NULL};
+	CSSM_CC_HANDLE 	cryptHand = 0;
+	SSLErr			serr = SSLInternalError;
+	CSSM_RETURN		crtn;
+	uint32			bytesMoved = 0;
+	CSSM_ACCESS_CREDENTIALS	creds;
+		
+	CASSERT(ctx != NULL);
+	CASSERT(actualBytes != NULL);
+	*actualBytes = 0;
+	
+	if((privKey == NULL) || (cspHand == 0)) {
+		errorLog0("sslRsaDecrypt: bad privKey/cspHand\n");
+		return SSLInternalError;
+	}
+	memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+	crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
+		CSSM_ALGID_RSA,
+		&creds,
+		privKey,
+		CSSM_PADDING_NONE,
+		&cryptHand);
+	if(crtn) {
+		stPrintCdsaError("CSSM_CSP_CreateAsymmetricContext", crtn);
+		return SSLCryptoError;
+	}
+	ctextData.Data = (uint8 *)cipherText;
+	ctextData.Length = cipherTextLen;
+	
+	if(privKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PUBLIC_KEY) {
+		/* 
+		 * Special case, decrypting with public key (i.e., raw verify). Add
+		 * the required context attr.
+		 */
+		CSSM_CONTEXT_ATTRIBUTE	modeAttr;
+		
+		modeAttr.AttributeType     = CSSM_ATTRIBUTE_MODE;
+		modeAttr.AttributeLength   = sizeof(uint32);
+		modeAttr.Attribute.Uint32  = CSSM_ALGMODE_PUBLIC_KEY;
+		crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &modeAttr);
+		if(crtn) {
+			stPrintCdsaError("CSSM_UpdateContextAttributes", crtn);
+			CSSM_DeleteContext(cryptHand);
+			return SSLCryptoError;
+		}
+	}
+
+	/* 
+	 * Have CSP malloc plaintext 
+	 */
+	crtn = CSSM_DecryptData(cryptHand,
+		&ctextData,
+		1,
+		&ptextData,
+		1,
+		&bytesMoved,
+		&remData);
+	if(crtn == CSSM_OK) {
+		/* 
+		 * plaintext in both ptextData and remData; ensure it'll fit
+		 * in caller's buf & copy 
+		 */
+		if(bytesMoved > plainTextLen) {
+			errorLog2("sslRsaDecrypt overflow; plainTextLen %ld bytesMoved %ld\n",
+				plainTextLen, bytesMoved);
+			serr = SSLDataOverflow;
+		}
+		else {
+			UInt32 toMovePtext;
+			UInt32 toMoveRem;
+			
+			*actualBytes = bytesMoved;
+			/* 
+			 * Snag valid data from ptextData - its length or bytesMoved, 
+			 * whichever is less
+			 */
+			if(ptextData.Length > bytesMoved) {
+				/* everything's in ptext */
+				toMovePtext = bytesMoved;
+				toMoveRem = 0;
+			}
+			else {
+				/* must be some in remData too */
+				toMovePtext = ptextData.Length;
+				toMoveRem = bytesMoved - toMovePtext;		// remainder 
+			}
+			if(toMovePtext) {
+				memmove(plainText, ptextData.Data, toMovePtext);
+			}
+			if(toMoveRem) {
+				memmove(plainText + toMovePtext, remData.Data,
+					toMoveRem);
+			}
+			serr = SSLNoErr;
+		}
+	}
+	else {
+		stPrintCdsaError("CSSM_DecryptData", crtn);
+		serr = SSLCryptoError;
+	}
+	if(cryptHand != 0) {
+		CSSM_DeleteContext(cryptHand);
+	}
+	
+	/* free data mallocd by CSP */
+	stFreeCssmData(&ptextData, CSSM_FALSE);
+	stFreeCssmData(&remData, CSSM_FALSE);
+	return serr;
+}
+
+#endif	/* APPLE_DOMESTIC_CSP_REQUIRED */
+
+/*
+ * Obtain size of key in bytes.
+ */
+UInt32 sslKeyLengthInBytes(const CSSM_KEY_PTR key)
+{
+	CASSERT(key != NULL);
+	return (((key->KeyHeader.LogicalKeySizeInBits) + 7) / 8);
+}
+
+/*
+ * Get raw key bits from an RSA public key.
+ */
+SSLErr sslGetPubKeyBits(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	pubKey,
+	CSSM_CSP_HANDLE		cspHand,
+	SSLBuffer			*modulus,		// data mallocd and RETURNED
+	SSLBuffer			*exponent)		// data mallocd and RETURNED
+{
+	CSSM_KEY			wrappedKey;
+	CSSM_BOOL			didWrap = CSSM_FALSE;
+	CSSM_KEYHEADER_PTR	hdr;
+	CSSM_CC_HANDLE 		ccHand;
+	CSSM_RETURN			crtn;
+	SSLBuffer			pubKeyBlob;
+	SSLErr				srtn;
+	CSSM_ACCESS_CREDENTIALS	creds;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(modulus != NULL);
+	CASSERT(exponent != NULL);
+	CASSERT(pubKey != NULL);
+	
+	hdr = &pubKey->KeyHeader;
+	if(hdr->KeyClass != CSSM_KEYCLASS_PUBLIC_KEY) {
+		errorLog1("sslGetPubKeyBits: bad keyClass (%ld)\n", hdr->KeyClass);
+		return SSLInternalError;
+	}
+	if(hdr->AlgorithmId != CSSM_ALGID_RSA) {
+		errorLog1("sslGetPubKeyBits: bad AlgorithmId (%ld)\n", hdr->AlgorithmId);
+		return SSLInternalError;
+	}
+	
+	/* 
+	 * Handle possible reference format - I think it should be in
+	 * blob form since it came from the DL, but conversion is 
+	 * simple.
+	 */
+	switch(hdr->BlobType) {
+		case CSSM_KEYBLOB_RAW:
+			/* easy case */
+			CSSM_TO_SSLBUF(&pubKey->KeyData, &pubKeyBlob);
+			break;
+
+		case CSSM_KEYBLOB_REFERENCE:
+			/* 
+			 * Convert to a blob via "NULL wrap"; no wrapping key, 
+			 * ALGID_NONE 
+			 */ 
+			srtn = attachToCsp(ctx);
+			if(srtn) {
+				return srtn;
+			}
+			memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+			crtn = CSSM_CSP_CreateSymmetricContext(ctx->cspHand,
+					CSSM_ALGID_NONE,
+					CSSM_ALGMODE_NONE,
+					&creds,			// creds
+					pubKey,
+					NULL,			// InitVector
+					CSSM_PADDING_NONE,
+					0,			// reserved
+					&ccHand);
+			if(crtn) {
+				stPrintCdsaError("sslGetPubKeyBits: CreateSymmetricContext failure", crtn); 
+				return SSLMemoryErr;
+			}
+			memset(&wrappedKey, 0, sizeof(CSSM_KEY));
+			crtn = CSSM_WrapKey(ccHand,
+				&creds,
+				pubKey,
+				NULL,			// descriptiveData
+				&wrappedKey);
+			CSSM_DeleteContext(ccHand);
+			if(crtn) {
+				stPrintCdsaError("CSSM_WrapKey", crtn);
+				return SSLCryptoError;
+			}
+			hdr = &wrappedKey.KeyHeader;
+			if(hdr->BlobType != CSSM_KEYBLOB_RAW) {
+				errorLog1("sslGetPubKeyBits: bad BlobType (%ld) after WrapKey\n", 
+					hdr->BlobType);
+				return SSLCryptoError;
+			}
+			didWrap = CSSM_TRUE;
+			CSSM_TO_SSLBUF(&wrappedKey.KeyData, &pubKeyBlob);
+			break;
+
+		default:
+			errorLog1("sslGetPubKeyBits: bad BlobType (%ld)\n", 
+				hdr->BlobType);
+			return SSLInternalError;
+	
+	}	/* switch BlobType */
+
+	CASSERT(hdr->BlobType == CSSM_KEYBLOB_RAW); 
+	srtn = sslDecodeRsaBlob(&pubKeyBlob, modulus, exponent);
+	if(didWrap) {
+		CSSM_FreeKey(ctx->cspHand, NULL, &wrappedKey, CSSM_FALSE);
+	}
+	return srtn;
+}
+
+/*
+ * Given raw RSA key bits, cook up a CSSM_KEY_PTR. Used in 
+ * Server-initiated key exchange. 
+ */
+SSLErr sslGetPubKeyFromBits(
+	SSLContext			*ctx,
+	const SSLBuffer		*modulus,	
+	const SSLBuffer		*exponent,	
+	CSSM_KEY_PTR		*pubKey,		// mallocd and RETURNED
+	CSSM_CSP_HANDLE		*cspHand)		// RETURNED
+{
+	CSSM_KEY_PTR		key = NULL;
+	SSLErr				serr;
+	SSLBuffer			blob;
+	CSSM_KEYHEADER_PTR	hdr;
+	CSSM_KEY_SIZE		keySize;
+	CSSM_RETURN			crtn;
+	
+	CASSERT((ctx != NULL) && (modulus != NULL) && (exponent != NULL));
+	CASSERT((pubKey != NULL) && (cspHand != NULL));
+	
+	*pubKey = NULL;
+	*cspHand = 0;
+	
+	serr = attachToCsp(ctx);
+	if(serr) {
+		return serr;
+	}
+	serr = sslEncodeRsaBlob(modulus, exponent, &blob);
+	if(serr) {
+		return serr;
+	}
+	
+	/* the rest is boilerplate, cook up a good-looking public key */
+	key = sslMalloc(sizeof(CSSM_KEY));
+	if(key == NULL) {
+		return SSLMemoryErr;
+	}
+	memset(key, 0, sizeof(CSSM_KEY));
+	hdr = &key->KeyHeader;
+	
+    hdr->HeaderVersion = CSSM_KEYHEADER_VERSION;
+    /* key_ptr->KeyHeader.CspId is unknown (remains 0) */
+    hdr->BlobType = CSSM_KEYBLOB_RAW;
+    hdr->AlgorithmId = CSSM_ALGID_RSA;
+    hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
+    hdr->KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
+    /* comply with ASA requirements */
+    hdr->KeyUsage = CSSM_KEYUSE_VERIFY;
+    hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
+    /* key_ptr->KeyHeader.StartDate is unknown  (remains 0) */
+    /* key_ptr->KeyHeader.EndDate is unknown  (remains 0) */
+    hdr->WrapAlgorithmId = CSSM_ALGID_NONE;
+    hdr->WrapMode = CSSM_ALGMODE_NONE;
+
+	/* blob->data was mallocd by sslEncodeRsaBlob, pass it over to 
+	 * actual key */
+	SSLBUF_TO_CSSM(&blob, &key->KeyData);
+	
+	/*
+	 * Get keySizeInBits. This also serves to validate the key blob
+	 * we just cooked up.
+	 */
+    crtn = CSSM_QueryKeySizeInBits(ctx->cspHand, CSSM_INVALID_HANDLE, key, &keySize);
+	if(crtn) {	
+    	stPrintCdsaError("sslGetPubKeyFromBits: QueryKeySizeInBits\n", crtn);
+		serr = SSLCryptoError;
+    	goto abort;
+	}
+	
+	/* success */
+    hdr->LogicalKeySizeInBits = keySize.EffectiveKeySizeInBits;
+    *pubKey = key;
+    *cspHand = ctx->cspHand;
+	return SSLNoErr;
+	
+abort:
+	/* note this frees the blob */
+	sslFreeKey(ctx->cspHand, &key, NULL);
+	return serr;
+}
+
+#pragma mark -
+#pragma mark *** Public Certificate Functions ***
+
+/*
+ * Given a DER-encoded cert, obtain its public key as a CSSM_KEY_PTR.
+ * Caller must CSSM_FreeKey and free the CSSM_KEY_PTR itself. 
+ *
+ * For now, the returned cspHand is a copy of ctx->cspHand, so it
+ * doesn't have to be detached later - this may change....
+ */
+SSLErr sslPubKeyFromCert(
+	SSLContext 			*ctx,
+	const SSLBuffer		*derCert,
+	CSSM_KEY_PTR		*pubKey,		// RETURNED
+	CSSM_CSP_HANDLE		*cspHand)		// RETURNED
+{
+	SSLErr 			serr;
+	CSSM_DATA		certData;
+	CSSM_RETURN		crtn;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(derCert != NULL);
+	CASSERT(pubKey != NULL);
+	CASSERT(cspHand != NULL);
+	
+	*pubKey = NULL;
+	*cspHand = 0;
+	
+	serr = attachToCl(ctx);
+	if(serr) {
+		return serr;
+	}
+	serr = attachToCsp(ctx);
+	if(serr) {
+		return serr;
+	}
+	SSLBUF_TO_CSSM(derCert, &certData);
+	crtn = CSSM_CL_CertGetKeyInfo(ctx->clHand, &certData, pubKey);
+	if(crtn) {
+		return SSLBadCert;
+	}
+	else {
+		*cspHand = ctx->cspHand; 
+		return SSLNoErr;
+	}
+}
+
+#if		0
+
+#include <Files.h>
+#include <Errors.h>
+
+/* for writing root cert to a file */
+
+static OSErr writeBlob(const CSSM_DATA_PTR blob, 
+	const char *fileName)
+{
+	OSErr	err = noErr;
+	FSSpec	fsp;
+	short	fileRef;
+	long	count = blob->Length;
+	int		len = strlen(fileName);
+	
+	fsp.vRefNum = 0;
+	fsp.parID = 0;
+	fsp.name[0] = len;
+	memmove(&fsp.name[1], fileName, len);
+
+	err = FSpCreate(&fsp, 0, 0, 0);
+	if(err && (err != dupFNErr)) {
+		dprintf1("***FSpCreate() returned %d\n", err);
+		return err;
+	}
+	err = FSpOpenDF(&fsp, fsRdWrPerm, &fileRef);
+	if(err) {
+		dprintf1("***FSpOpenDF() returned %d\n", err);
+		return err;
+	}
+	err = FSWrite(fileRef, &count, blob->Data);
+	if(err) {
+		dprintf1("***FSWrite() returned %d\n", err);
+		return err;
+	}
+	err = FSClose(fileRef);
+	if(err) {
+		dprintf1("***FSClose() returned %d\n", err);
+		return err;
+	}
+	return 0;
+}
+
+void writeBufBlob(const SSLBuffer *blob, 
+	const char *fileName)
+{
+	CSSM_DATA	d;
+	
+	SSLBUF_TO_CSSM(blob, &d)
+	writeBlob(&d, fileName);
+}
+
+#endif	/* 0 */
+
+#if		ST_KEYCHAIN_ENABLE
+
+/*
+ * Given a CSSM_CERTGROUP which fails due to CSSM_TP_INVALID_ANCHOR
+ * (chain verifies to an unknown root):
+ *
+ * -- find the root cert
+ * -- add it to newRootCertKc if present (else error)
+ * -- add it to trustedCerts
+ * -- re-verify certgroup, demand full success
+ */
+static SSLErr sslHandleNewRoot(
+	SSLContext				*ctx,
+	CSSM_CERTGROUP_PTR		certGroup)
+{
+	int 			i;
+	CSSM_DATA_PTR	rootCert;
+	CSSM_BOOL		expired;
+	SSLErr			serr;
+	CSSM_BOOL		brtn;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(certGroup != NULL);
+	
+	if(ctx->newRootCertKc == NULL) {
+		/* no place to add this; done */
+		return SSLUnknownRootCert;
+	}
+	
+	/*
+	 * The root cert "should" be at the end of the chain, but 
+	 * let's not assume that. (We are assuming that there is 
+	 * only one root in the cert group...)
+	 */
+	for(i=0; i<certGroup->NumCerts; i++) {
+		rootCert = &certGroup->CertList[i];
+		if(sslVerifyCert(ctx, rootCert, rootCert, ctx->cspHand, &expired)) {
+			break;
+		}
+	}
+	if(i == certGroup->NumCerts) {
+		/* Huh! no root cert!? We should not have been called! */
+		errorLog0("sslHandleNewRoot: no root cert!\n");
+		return SSLInternalError;
+	}
+	
+	/*
+	 * Add to newRootCertKc. This may well fail due to user interaction.	
+	 */
+	serr = sslAddNewRoot(ctx, rootCert);
+	if(serr) {
+		return serr;
+	}
+	
+	/*
+	 * Just to be sure...reverify the whole cert chain. 
+	 */
+	brtn = CSSM_TP_CertGroupVerify(
+		ctx->tpHand,
+		ctx->clHand,
+		ctx->cspHand,
+		NULL,					// DBList
+		NULL, 					// PolicyIdentifiers
+		0,						// NumberofPolicyIdentifiers
+		CSSM_TP_STOP_ON_POLICY, 
+		certGroup,
+		ctx->trustedCerts,		// AnchorCerts
+		ctx->numTrustedCerts, 
+		NULL,					// VerifyScope
+		0,						// ScopeSize
+		0,						// Action
+		0,						// Data
+		NULL,					// evidence
+		NULL);					// evidenceSize
+	if(brtn == CSSM_FALSE) {
+		errorLog0("sslHandleNewRoot: adding new root did not help!\n");
+		return SSLUnknownRootCert;
+	}
+	return SSLNoErr;
+}
+
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+/* free a CSSM_CERT_GROUP */ 
+static void sslFreeCertGroup(
+	CSSM_CERTGROUP_PTR	certGroup,
+	CSSM_BOOL			freeCerts,	// free individual cert fields
+	CSSM_BOOL			freeStruct)	// free the overall CSSM_CERTGROUP
+{
+	unsigned dex;
+	
+	if(certGroup == NULL) {
+		return;	
+	}
+	
+	/* free the individual cert Data fields */
+	if(certGroup->GroupList.CertList) {
+		if(freeCerts) {
+			for(dex=0; dex<certGroup->NumCerts; dex++) {
+				stFreeCssmData(&certGroup->GroupList.CertList[dex], CSSM_FALSE);
+			}
+		}
+		/* and the array of CSSM_DATAs */
+		stAppFree(certGroup->GroupList.CertList, NULL);
+	}
+	if(freeStruct) {
+		stAppFree(certGroup, NULL);
+	}
+}
+
+/*
+ * Verify a chain of DER-encoded certs.
+ * First cert in a chain is root; this must also be present
+ * in ctx->trustedCerts. 
+ */
+SSLErr sslVerifyCertChain(
+	SSLContext				*ctx,
+	const SSLCertificate	*certChain)
+{
+	UInt32 						numCerts;
+	CSSM_CERTGROUP				certGroup;
+	int 						i;
+	SSLErr						serr;
+	SSLCertificate				*c = (SSLCertificate *)certChain;
+	CSSM_RETURN					crtn;
+	CSSM_TP_VERIFY_CONTEXT		vfyCtx;
+	CSSM_TP_CALLERAUTH_CONTEXT	authCtx;
+	CSSM_FIELD					policyId;
+	CSSM_DL_DB_LIST				dbList;
+	
+	numCerts = SSLGetCertificateChainLength(certChain);
+	if(numCerts == 0) {
+		/* nope */
+		return SSLBadCert;
+	}
+	#if 0
+	serr = attachToAll(ctx);
+	if(serr) {
+		return serr;
+	}
+	#endif
+	
+	/* 
+	 * SSLCertificate chain --> CSSM TP cert group.
+	 * TP Cert group has root at the end, opposite of 
+	 * SSLCertificate chain. 
+	 */
+	certGroup.GroupList.CertList = 
+		(CSSM_DATA_PTR)sslMalloc(numCerts * sizeof(CSSM_DATA));
+	if(certGroup.GroupList.CertList == NULL) {
+		return SSLMemoryErr;
+	}
+	certGroup.CertGroupType = CSSM_CERTGROUP_ENCODED_CERT;
+	certGroup.CertType = CSSM_CERT_X_509v3;
+	certGroup.CertEncoding = CSSM_CERT_ENCODING_DER; 
+	certGroup.NumCerts = numCerts;
+	
+	memset(certGroup.GroupList.CertList, 0, numCerts * sizeof(CSSM_DATA));
+	
+	for(i=numCerts-1; i>=0; i--) {
+		SSLBUF_TO_CSSM(&c->derCert, &certGroup.GroupList.CertList[i]);
+		c = c->next;
+	}
+	
+	#if		0
+	if(ctx->rootCertName != NULL) {
+		/* save root cert */
+		writeBlob(&certGroup.CertList[numCerts-1], ctx->rootCertName);
+	}
+	#endif	/* SSL_DEBUG */
+	
+	memset(&vfyCtx, 0, sizeof(CSSM_TP_VERIFY_CONTEXT));
+	vfyCtx.Action = CSSM_TP_ACTION_DEFAULT;
+	vfyCtx.Cred = &authCtx;
+	
+	/* CSSM_TP_CALLERAUTH_CONTEXT components */
+	/* 
+		typedef struct cssm_tp_callerauth_context {
+			CSSM_TP_POLICYINFO Policy;
+			CSSM_TIMESTRING VerifyTime;
+			CSSM_TP_STOP_ON VerificationAbortOn;
+			CSSM_TP_VERIFICATION_RESULTS_CALLBACK CallbackWithVerifiedCert;
+			uint32 NumberOfAnchorCerts;
+			CSSM_DATA_PTR AnchorCerts;
+			CSSM_DL_DB_LIST_PTR DBList;
+			CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials;
+		} CSSM_TP_CALLERAUTH_CONTEXT, *CSSM_TP_CALLERAUTH_CONTEXT_PTR;
+	*/
+	/* zero or one policy here */
+	policyId.FieldValue.Data = NULL;
+	policyId.FieldValue.Length = 0;
+	policyId.FieldOid = CSSMOID_APPLE_TP_SSL;
+	authCtx.Policy.NumberOfPolicyIds = 1;
+	authCtx.Policy.PolicyIds = &policyId;
+	authCtx.Policy.PolicyControl = ctx->allowExpiredCerts ?
+		CSSM_TP_ALLOW_EXPIRE : NULL;
+	authCtx.VerifyTime = NULL;
+	authCtx.VerificationAbortOn = CSSM_TP_STOP_ON_POLICY;
+	authCtx.CallbackWithVerifiedCert = NULL;
+	authCtx.NumberOfAnchorCerts = ctx->numTrustedCerts;
+	authCtx.AnchorCerts = ctx->trustedCerts;	
+	memset(&dbList, 0, sizeof(CSSM_DL_DB_LIST));
+	authCtx.DBList = &dbList;
+	authCtx.CallerCredentials = NULL;
+
+	/*
+	 * Here we go; hand it over to TP. Note trustedCerts are our
+	 * known good Anchor certs; they're already formatted properly. 
+	 * Unlike most other Apple code, we demand full success here, 
+	 * implying that the last cert in the chain is indeed an Anchor
+	 * cert. We already know that all of our anchor certs are
+	 * roots, so on successful return, we'll know the incoming 
+	 * chain has a root, it verifies to that root, and that that
+	 * root is in trustedCerts.  
+	 */
+	crtn = CSSM_TP_CertGroupVerify(ctx->tpHand,
+		ctx->clHand,
+		ctx->cspHand,
+		&certGroup,
+		&vfyCtx,
+		NULL);			// no evidence needed
+
+	serr = SSLNoErr;
+	if(crtn) {	
+		/* get some detailed error info */
+		switch(crtn) {
+			case CSSMERR_TP_INVALID_ANCHOR_CERT:
+				/* root found but we don't trust it */
+				if(ctx->allowAnyRoot) {
+					dprintf0("***Warning: accepting unknown root cert\n");
+					break;
+				}
+				#if		ST_KEYCHAIN_ENABLE
+				if(ctx->newRootCertKc != NULL) {
+					/* see if user wants to handle new root */
+					serr = sslHandleNewRoot(ctx, &certGroup);
+				}
+				else {
+					serr = SSLUnknownRootCert;
+				}
+				#else
+				serr = SSLUnknownRootCert;
+				#endif	/* ST_KEYCHAIN_ENABLE */
+				break;
+			case CSSMERR_TP_NOT_TRUSTED:
+				/* no root, not even in implicit SSL roots */
+				if(ctx->allowAnyRoot) {
+					dprintf0("***Warning: accepting unverified cert chain\n");
+					break;
+				}
+				serr = SSLNoRootCert;
+				break;
+			case CSSMERR_TP_CERT_EXPIRED:
+				/* FIXME  - tolerate this case via some TBD flag */
+				serr = SSLCertExpired;
+				break;
+			case CSSMERR_TP_CERT_NOT_VALID_YET:
+				serr = SSLCertNotYetValid;
+				break;
+			default:
+				stPrintCdsaError(
+					"sslVerifyCertChain: CSSM_TP_CertGroupVerify returned", 					crtn);
+				serr = X509CertChainInvalidErr;
+				break;
+		}
+	} 	/* brtn FALSE */
+
+	/* 
+	 * don't free individual certs - caller still owns them
+	 * don't free struct - on stack 
+	 */
+	sslFreeCertGroup(&certGroup, CSSM_FALSE, CSSM_FALSE);
+	return serr;
+}
+
+
+#if 0
+/* not needed in X */
+
+/*
+ * Given two certs, verify subjectCert with issuerCert. Returns 
+ * CSSM_TRUE on successful verify.
+ * Only special case on error is "subject cert expired", indicated by
+ * *subjectExpired returned as CSSM_TRUE.
+ */
+CSSM_BOOL sslVerifyCert(
+	SSLContext				*ctx,
+	const CSSM_DATA_PTR		subjectCert,
+	const CSSM_DATA_PTR		issuerCert,
+	CSSM_CSP_HANDLE			cspHand,			// can verify with issuerCert
+	CSSM_BOOL				*subjectExpired)	// RETURNED
+{
+	CSSM_KEY_PTR		issuerPubKey = NULL;
+	CSSM_DATA_PTR		sigOid = NULL;
+	CSSM_HANDLE 		ResultsHandle;
+	uint32 				NumberOfFields;
+	CSSM_ERROR_PTR 		pErr = NULL;
+	CSSM_BOOL			brtn;
+	uint32				*algId = NULL;		// mallocd by CL_Passthrough
+	CSSM_CC_HANDLE		ccHand = 0;
+	
+	*subjectExpired = CSSM_FALSE;
+
+	/* ensure connection to CL, TP */
+	if(attachToCl(ctx)) {
+		return CSSM_FALSE;
+	}
+	if(attachToTp(ctx)) {
+		return CSSM_FALSE;
+	}
+	
+	/* public key from issuer cert */	
+	issuerPubKey = CSSM_CL_CertGetKeyInfo(ctx->clHand, issuerCert);
+	if(issuerPubKey == NULL) {
+		return CSSM_FALSE;
+	}
+	/* subsequent errors to abort: */
+	
+	/* signature alg from subject cert */
+    sigOid = CSSM_CL_CertGetFirstFieldValue(ctx->clHand, 
+    	subjectCert,
+    	&CSSMOID_X509V1SignatureAlgorithm,
+		&ResultsHandle, 
+		&NumberOfFields);
+	if(sigOid == NULL) {
+		stPrintCdsaError("CSSM_CL_CertGetFirstFieldValue");
+		brtn = CSSM_FALSE;
+    	CSSM_CL_CertAbortQuery(ctx->clHand, ResultsHandle);
+		goto abort;
+	}
+    /* cleanup query state */
+    CSSM_CL_CertAbortQuery(ctx->clHand, ResultsHandle);
+
+	/* convert: alg OID to CSSM_ALGID_xxx */
+	algId = (uint32 *)CSSM_CL_PassThrough(ctx->clHand,
+			0,			// no handle needed
+			INTEL_X509V3_PASSTHROUGH_ALGOID_TO_ALGID,
+			sigOid);
+	if(*algId == CSSM_ALGID_NONE) {
+		brtn = CSSM_FALSE;
+		goto abort;
+	}
+
+	/* set up a sign context with obtained pub key and algorithm */		
+	ccHand = CSSM_CSP_CreateSignatureContext(cspHand,
+		*algId,
+		NULL,		// no passphrase
+		issuerPubKey);
+	if(ccHand == 0) {
+		brtn = CSSM_FALSE;
+		goto abort;
+	}
+
+	/* go for it - CL takes over from here */
+    brtn = CSSM_CL_CertVerify(ctx->clHand, 
+    	ccHand, 
+    	subjectCert,
+    	issuerCert,
+    	NULL,				// VerifyScope
+    	0);					// ScopeSize
+	if(!brtn && (CSSM_GetError()->error == CSSM_CL_CERT_EXPIRED)) {
+		*subjectExpired = CSSM_TRUE;
+	}
+	
+abort:
+	if(issuerPubKey != NULL) {
+		CSSM_Free(issuerPubKey->KeyData.Data);
+		CSSM_Free(issuerPubKey);
+	}
+	if(sigOid != NULL) {
+		CSSM_Free(sigOid->Data);
+		CSSM_Free(sigOid);
+	}
+	if(ccHand != 0) {
+		CSSM_DeleteContext(ccHand);
+	} 
+	if(algId != NULL) {
+		CSSM_Free(algId);
+	}
+	return brtn;
+}
+#endif	/* 0 - not needed */
+
+#if		ST_KEYCHAIN_ENABLE 
+/* no cert parsing in this version */
+
+/*
+ * Given a DER-encoded cert, obtain its DER-encoded subject name.
+ */
+CSSM_DATA_PTR sslGetCertSubjectName( 
+	SSLContext			*ctx,
+    const CSSM_DATA_PTR cert)
+{
+	uint32 			NumberOfFields = 0;
+	CSSM_HANDLE 	ResultsHandle = 0;
+	CSSM_DATA_PTR 	pEncodedName = NULL;
+	CSSM_RETURN		crtn;
+	
+	/* ensure connection to CL */
+	if(attachToCl(ctx)) {
+		return NULL;
+	}
+	crtn = CSSM_CL_CertGetFirstFieldValue(
+		ctx->clHand,
+		cert,
+	    &CSSMOID_X509V1SubjectName,
+	    &ResultsHandle,
+	    &NumberOfFields, 
+		&pEncodedName);
+	if(crtn) {
+		stPrintCdsaError("CertGetFirstFieldValue", crtn);
+	}
+  	CSSM_CL_CertAbortQuery(ctx->clHand, ResultsHandle);
+	return pEncodedName;
+}
+#endif	ST_KEYCHAIN_ENABLE 
+
+#if		(SSL_DEBUG && ST_KEYCHAIN_ENABLE)
+void verifyTrustedRoots(SSLContext *ctx,
+	CSSM_DATA_PTR	certs,
+	unsigned		numCerts)
+{	
+	int i;
+	CSSM_DATA_PTR cert;
+	CSSM_BOOL	expired;
+	
+	for(i=0; i<numCerts; i++) {
+		cert = &certs[i];
+		if(!sslVerifyCert(ctx,
+				cert,
+				cert,
+				ctx->cspHand,
+				&expired)) {
+			sslPanic("Bad trusted cert!\n");
+		}
+	}
+}
+#endif
+
+
diff --git a/SecureTransport/appleGlue.c b/SecureTransport/appleGlue.c
new file mode 100644
index 00000000..69c2dade
--- /dev/null
+++ b/SecureTransport/appleGlue.c
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		appleGlue.c
+
+	Contains:	Glue layer between Apple SecureTransport and 
+				original SSLRef code. 
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_SSL_H_
+#include "ssl.h"
+#endif
+
+#ifndef	_SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef	_SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef	_APPLE_GLUE_H_
+#include "appleGlue.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <time.h>
+#include <string.h>
+
+/*
+ * Cruft used to map between private SSLErr's and the SSL-specific 
+ * OSStatus values in SecureTransport.h. Eventually we should do 
+ * away with SSLErr....
+ */
+typedef struct {
+	SSLErr		serr;
+	OSStatus	oerr;
+} _sslErrMap;
+
+static const _sslErrMap sslErrMap[] = {
+	{ SSLNoErr, 					noErr						},
+	{ SSLMemoryErr, 				memFullErr					},
+	{ SSLUnsupportedErr, 			unimpErr					},
+	{ SSLProtocolErr, 				errSSLProtocol				},
+	{ SSLNegotiationErr, 			errSSLNegotiation			},
+	{ SSLFatalAlert, 				errSSLFatalAlert			},
+	{ SSLWouldBlockErr, 			errSSLWouldBlock			},
+	{ SSLIOErr, 					ioErr						},
+	{ SSLSessionNotFoundErr, 		errSSLSessionNotFound		},
+	{ SSLConnectionClosedGraceful, 	errSSLClosedGraceful		},
+	{ SSLConnectionClosedError, 	errSSLClosedAbort			},
+   	{ X509CertChainInvalidErr, 		errSSLXCertChainInvalid		},
+    { SSLBadCert,					errSSLBadCert				},
+    { SSLCryptoError,				errSSLCrypto				},
+    { SSLInternalError,				errSSLInternal				},
+    { SSLDataOverflow,				errSSLCrypto				},
+    { SSLAttachFailure,				errSSLModuleAttach			},
+    { SSLUnknownRootCert,			errSSLUnknownRootCert		},
+    { SSLNoRootCert,				errSSLNoRootCert			},
+    { SSLCertExpired,				errSSLCertExpired			},
+	{ SSLCertNotYetValid,			errSSLCertNotYetValid		},
+    { SSLBadStateErr,				badReqErr					},
+    { SSLConnectionClosedNoNotify,	errSSLClosedNoNotify		},
+};
+
+#define SIZEOF_ERR_MAP	(sizeof(sslErrMap) / sizeof(_sslErrMap))
+
+/*
+ * Functions to allow old code to use SSLBuffer-based I/O calls.
+ * We redirect the calls here to an SSL{Write,Read}Func.
+ * This is of course way inefficient due to an extra copy for
+ * each I/O, but let's do it this way until the port settles down.
+ */ 
+SSLErr sslIoRead(
+ 	SSLBuffer 		buf, 
+ 	UInt32 			*actualLength, 
+ 	SSLContext 		*ctx)
+ {
+ 	UInt32 		dataLength = buf.length;
+ 	OSStatus	ortn;
+ 		
+	*actualLength = 0;
+	ortn = (ctx->ioCtx.read)(ctx->ioCtx.ioRef,
+		buf.data,
+		&dataLength);
+	*actualLength = dataLength;
+	return sslErrFromOsStatus(ortn);
+ }
+ 
+ SSLErr sslIoWrite(
+ 	SSLBuffer 		buf, 
+ 	UInt32 			*actualLength, 
+ 	SSLContext 		*ctx)
+ {
+ 	UInt32 			dataLength = buf.length;
+ 	OSStatus		ortn;
+ 		
+	*actualLength = 0;
+	ortn = (ctx->ioCtx.write)(ctx->ioCtx.ioRef,
+		buf.data,
+		&dataLength);
+	*actualLength = dataLength;
+	return sslErrFromOsStatus(ortn);
+ }
+
+ /*
+  * Convert between SSLErr and OSStatus.
+  * These will go away eventually.
+  */
+SSLErr sslErrFromOsStatus(OSStatus o)
+{
+	int i;
+	const _sslErrMap *emap = sslErrMap;
+	
+	for(i=0; i<SIZEOF_ERR_MAP; i++) {
+		if(emap->oerr == o) {
+			return emap->serr;
+		}
+		emap++;
+	}
+	return SSLIOErr;			/* normal: bad error */
+}
+ 
+OSStatus sslErrToOsStatus(SSLErr s)
+{
+	int i;
+	const _sslErrMap *emap = sslErrMap;
+	
+	for(i=0; i<SIZEOF_ERR_MAP; i++) {
+		if(emap->serr == s) {
+			return emap->oerr;
+		}
+		emap++;
+	}
+	CASSERT(0);					/* Debug: panic */
+	return paramErr;			/* normal: bad error */
+}
+
+/*
+ * Time functions - replaces SSLRef's SSLTimeFunc, SSLConvertTimeFunc
+ * Weird - this is just used to generate a random number in
+ * SSLEncodeRandom
+ */
+SSLErr sslTime(UInt32 *tim)
+{
+	time((time_t *)&tim);
+	return SSLNoErr;
+}
+
+#ifdef	notdef
+/* not used.... */
+SSLErr sslConvertTime(UInt32 *time)
+{
+	return SSLUnsupportedErr;
+}
+#endif
diff --git a/SecureTransport/appleSession.c b/SecureTransport/appleSession.c
new file mode 100644
index 00000000..7b003cca
--- /dev/null
+++ b/SecureTransport/appleSession.c
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		appleSession.c
+
+	Contains:	Session storage module, _APPLE_CDSA_ version. 
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+/* 
+ * This file replaces the caller-specified SSLAddSessionFunc,
+ * SSLGetSessionFunc, and SSLDeleteSessionFunc callbacks in the 
+ * original SSLRef 3.0.
+ */
+#ifndef	_SSL_H_
+#include "ssl.h"
+#endif
+
+#ifndef	_SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef	_SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef	_APPLE_GLUE_H_
+#include "appleGlue.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef	_APPLE_SESSION_H_
+#include "appleSession.h"
+#endif
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+/*
+ * Store opaque sessionData, associated with opaque sessionKey.
+ */
+SSLErr sslAddSession (
+	const SSLBuffer sessionKey, 
+	const SSLBuffer sessionData, 
+	void *sessionRef)
+{
+	/* TBD */
+	return SSLUnsupportedErr;
+}
+
+/*
+ * Given an opaque sessionKey, alloc & retrieve associated sessionData.
+ */
+SSLErr sslGetSession (
+	const SSLBuffer sessionKey, 
+	SSLBuffer *sessionData, 
+	void *sessionRef)
+{
+	/* TBD */
+	return SSLSessionNotFoundErr;
+}
+
+SSLErr sslDeleteSession (
+	const SSLBuffer sessionKey, 
+	void *sessionRef)
+{
+	/* TBD */
+	return SSLSessionNotFoundErr;
+}
+
diff --git a/SecureTransport/cipherSpecs.c b/SecureTransport/cipherSpecs.c
new file mode 100644
index 00000000..d00d219f
--- /dev/null
+++ b/SecureTransport/cipherSpecs.c
@@ -0,0 +1,532 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cipherSpecs.c
+
+	Contains:	SSLCipherSpec declarations
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslctx.h"
+#include "cryptType.h"
+#include "symCipher.h"
+#include "cipherSpecs.h"
+#include "sslDebug.h"
+#include "sslalloc.h"
+#include "sslDebug.h"
+#include "sslutil.h"
+#include <string.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+/* FIXME - domestic suites do not work in server side in level 3 */
+
+#define ENABLE_3DES		1		/* normally enabled, our first preference */
+#define ENABLE_RC4		1		/* normally enabled, the most common one */
+#define ENABLE_DES		1		/* normally enabled */
+#define ENABLE_RC2		1		/* normally enabled */
+
+#define ENABLE_RSA_DES_SHA_NONEXPORT		ENABLE_DES	
+#define ENABLE_RSA_DES_MD5_NONEXPORT		ENABLE_DES
+#define ENABLE_RSA_DES_SHA_EXPORT			ENABLE_DES
+#define ENABLE_RSA_RC4_MD5_EXPORT			ENABLE_RC4	/* the most common one */
+#define ENABLE_RSA_RC4_MD5_NONEXPORT		ENABLE_RC4 
+#define ENABLE_RSA_RC4_SHA_NONEXPORT		ENABLE_RC4
+#define ENABLE_RSA_RC2_MD5_EXPORT			ENABLE_RC2
+#define ENABLE_RSA_RC2_MD5_NONEXPORT		ENABLE_RC2
+#define ENABLE_RSA_3DES_SHA					ENABLE_3DES 
+#define ENABLE_RSA_3DES_MD5					ENABLE_3DES	
+
+extern SSLSymmetricCipher SSLCipherNull;		/* in nullciph.c */
+
+/*
+ * The symmetric ciphers currently supported (in addition to the
+ * NULL cipher in nullciph.c).
+ */
+#if	ENABLE_DES
+static const SSLSymmetricCipher SSLCipherDES_CBC = {
+    8,      /* Key size in bytes */
+    8,      /* Secret key size = 64 bits */
+    8,      /* IV size */
+    8,      /* Block size */
+    CSSM_ALGID_DES,
+    CSSM_ALGID_DES,
+    /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
+     * for us */
+    CSSM_ALGMODE_CBC_IV8,
+	CSSM_PADDING_NONE,
+    CDSASymmInit,
+    CDSASymmEncrypt,
+    CDSASymmDecrypt,
+    CDSASymmFinish
+};
+
+static const SSLSymmetricCipher SSLCipherDES40_CBC = {
+    8,      /* Key size in bytes */
+    5,      /* Secret key size = 40 bits */
+    8,      /* IV size */
+    8,      /* Block size */
+    CSSM_ALGID_DES,
+    CSSM_ALGID_DES,
+    CSSM_ALGMODE_CBC_IV8,
+	CSSM_PADDING_NONE,
+    CDSASymmInit,
+    CDSASymmEncrypt,
+    CDSASymmDecrypt,
+    CDSASymmFinish
+};
+#endif	/* ENABLE_DES */
+
+#if	ENABLE_3DES
+static const SSLSymmetricCipher SSLCipher3DES_CBC = {
+    24,     /* Key size in bytes */
+    24,     /* Secret key size = 192 bits */
+    8,      /* IV size */
+    8,      /* Block size */
+    CSSM_ALGID_3DES_3KEY,			// key gen 
+    CSSM_ALGID_3DES_3KEY_EDE,		// encryption
+    /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
+     * for us */
+    CSSM_ALGMODE_CBC_IV8,
+	CSSM_PADDING_NONE,
+    CDSASymmInit,
+    CDSASymmEncrypt,
+    CDSASymmDecrypt,
+    CDSASymmFinish
+};
+#endif	/* ENABLE_3DES */
+
+#if		ENABLE_RC4
+static const SSLSymmetricCipher SSLCipherRC4_40 = {
+    16,         /* Key size in bytes */
+    5,          /* Secret key size = 40 bits */
+    0,          /* IV size */
+    0,          /* Block size */
+    CSSM_ALGID_RC4,
+    CSSM_ALGID_RC4,
+    CSSM_ALGMODE_NONE,
+	CSSM_PADDING_NONE,
+    CDSASymmInit,
+    CDSASymmEncrypt,
+    CDSASymmDecrypt,
+    CDSASymmFinish
+};
+
+static const SSLSymmetricCipher SSLCipherRC4_128 = {
+    16,         /* Key size in bytes */
+    16,         /* Secret key size = 128 bits */
+    0,          /* IV size */
+    0,          /* Block size */
+    CSSM_ALGID_RC4,
+    CSSM_ALGID_RC4,
+    CSSM_ALGMODE_NONE,
+	CSSM_PADDING_NONE,
+    CDSASymmInit,
+    CDSASymmEncrypt,
+    CDSASymmDecrypt,
+    CDSASymmFinish
+};
+#endif	/* ENABLE_RC4 */
+
+#if		ENABLE_RC2
+static const SSLSymmetricCipher SSLCipherRC2_40 = {
+    16,         /* Key size in bytes */
+    5,          /* Secret key size = 40 bits */
+    8,          /* IV size */
+    8,          /* Block size */
+    CSSM_ALGID_RC2,
+    CSSM_ALGID_RC2,
+    CSSM_ALGMODE_CBC_IV8,
+	CSSM_PADDING_NONE,
+    CDSASymmInit,
+    CDSASymmEncrypt,
+    CDSASymmDecrypt,
+    CDSASymmFinish
+};
+
+static const SSLSymmetricCipher SSLCipherRC2_128 = {
+    16,         /* Key size in bytes */
+    16,          /* Secret key size = 40 bits */
+    8,          /* IV size */
+    8,          /* Block size */
+    CSSM_ALGID_RC2,
+    CSSM_ALGID_RC2,
+    CSSM_ALGMODE_CBC_IV8,
+	CSSM_PADDING_NONE,
+    CDSASymmInit,
+    CDSASymmEncrypt,
+    CDSASymmDecrypt,
+    CDSASymmFinish
+};
+
+#endif	/* ENABLE_RC2*/
+
+
+/* Even if we don't support NULL_WITH_NULL_NULL for transport, 
+ * we need a reference for startup */
+const SSLCipherSpec SSL_NULL_WITH_NULL_NULL_CipherSpec =
+{   SSL_NULL_WITH_NULL_NULL,
+    Exportable,
+    SSL_NULL_auth,
+    &SSLHashNull,
+    &SSLCipherNull
+};
+
+/*
+ * List of all CipherSpecs we implement. Depending on a context's 
+ * exportable flag, not all of these might be available for use. 
+ *
+ * FIXME - I'm not sure the distinction between e.g. SSL_RSA and SSL_RSA_EXPORT
+ * makes any sense here. See comments for the definition of 
+ * KeyExchangeMethod in cryptType.h.
+ */
+/* Order by preference, domestic first */
+static const SSLCipherSpec KnownCipherSpecs[] =
+{
+	/*** domestic only ***/
+	#if	ENABLE_RSA_3DES_SHA
+	    {   
+	    	SSL_RSA_WITH_3DES_EDE_CBC_SHA, 
+	    	NotExportable, 
+	    	SSL_RSA, 
+	    	&SSLHashSHA1, 
+	    	&SSLCipher3DES_CBC 
+	    },
+	#endif
+	#if	ENABLE_RSA_3DES_MD5
+	    {   
+	    	SSL_RSA_WITH_3DES_EDE_CBC_MD5, 
+	    	NotExportable, 
+	    	SSL_RSA, 
+	    	&SSLHashMD5, 
+	    	&SSLCipher3DES_CBC 
+	    },
+	#endif
+    #if	ENABLE_RSA_RC4_SHA_NONEXPORT
+	    {   
+	    	SSL_RSA_WITH_RC4_128_SHA, 
+	    	NotExportable, 
+	    	SSL_RSA, 
+	    	&SSLHashSHA1, 
+	    	&SSLCipherRC4_128 
+	    },
+    #endif
+    #if	ENABLE_RSA_RC4_MD5_NONEXPORT
+	    {   
+	    	SSL_RSA_WITH_RC4_128_MD5, 
+	    	NotExportable, 
+	    	SSL_RSA, 
+	    	&SSLHashMD5, 
+	    	&SSLCipherRC4_128 
+	    },
+    #endif
+	#if	ENABLE_RSA_DES_SHA_NONEXPORT
+	    {   
+	    	SSL_RSA_WITH_DES_CBC_SHA, 
+	    	NotExportable, 
+	    	SSL_RSA, 
+	    	&SSLHashSHA1, 
+	    	&SSLCipherDES_CBC 
+	    },
+    #endif
+	#if	ENABLE_RSA_DES_MD5_NONEXPORT
+	    {   
+	    	SSL_RSA_WITH_DES_CBC_MD5, 
+	    	NotExportable, 
+	    	SSL_RSA, 
+	    	&SSLHashMD5, 
+	    	&SSLCipherDES_CBC 
+	    },
+    #endif
+	/*** exportable ***/
+	#if	ENABLE_RSA_RC4_MD5_EXPORT
+		{   
+			SSL_RSA_EXPORT_WITH_RC4_40_MD5, 
+			Exportable, 
+			SSL_RSA_EXPORT, 
+			&SSLHashMD5, 
+			&SSLCipherRC4_40 
+		},
+	#endif
+    #if APPLE_DH
+	    /* Apple CSP doesn't support D-H yet */
+	    {   
+	    	SSL_DH_anon_WITH_RC4_128_MD5, 
+	    	NotExportable, 
+	    	SSL_DH_anon, 
+	    	&SSLHashMD5, 
+	    	&SSLCipherRC4_128 
+	    },
+    #endif
+	#if ENABLE_RSA_DES_SHA_EXPORT
+	    {   
+	    	SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 
+	    	Exportable, 
+	    	SSL_RSA_EXPORT, 
+	    	&SSLHashSHA1, 
+	    	&SSLCipherDES40_CBC 
+	    },
+	#endif 
+	
+    #if	ENABLE_RSA_RC2_MD5_EXPORT
+	    {   
+	    	SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 
+	    	Exportable, 
+	    	SSL_RSA_EXPORT, 
+	    	&SSLHashMD5, 
+	    	&SSLCipherRC2_40 
+	    },
+    #endif
+    #if	ENABLE_RSA_RC2_MD5_NONEXPORT
+	    {   
+	    	SSL_RSA_WITH_RC2_CBC_MD5, 
+	    	NotExportable, 
+	    	SSL_RSA, 
+	    	&SSLHashMD5, 
+	    	&SSLCipherRC2_128 
+	    },
+    #endif
+	    {   
+	    	SSL_RSA_WITH_NULL_MD5, 
+	    	Exportable, 
+	    	SSL_RSA, 
+	    	&SSLHashMD5, 
+	    	&SSLCipherNull 
+	    }
+};
+
+static const int CipherSpecCount = sizeof(KnownCipherSpecs) / sizeof(SSLCipherSpec);
+
+/*
+ * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
+ * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
+ * not been called).
+ */
+SSLErr sslBuildCipherSpecArray(SSLContext *ctx)
+{
+	unsigned 		size;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(ctx->validCipherSpecs == NULL);
+	
+	ctx->numValidCipherSpecs = CipherSpecCount;
+	size = CipherSpecCount * sizeof(SSLCipherSpec);
+	ctx->validCipherSpecs = sslMalloc(size);
+	if(ctx->validCipherSpecs == NULL) {
+		ctx->numValidCipherSpecs = 0;
+		return SSLMemoryErr;
+	}
+	memmove(ctx->validCipherSpecs, KnownCipherSpecs, size);
+	return SSLNoErr;
+}
+
+/*
+ * Convert an array of SSLCipherSpecs (which is either KnownCipherSpecs or
+ * ctx->validCipherSpecs) to an array of SSLCipherSuites.
+ */
+static OSStatus
+cipherSpecsToCipherSuites(
+	UInt32				numCipherSpecs,	/* size of cipherSpecs */
+	const SSLCipherSpec	*cipherSpecs,
+	SSLCipherSuite		*ciphers,		/* RETURNED */
+	UInt32				*numCiphers)	/* IN/OUT */
+{
+	unsigned dex;
+	
+	if(*numCiphers < numCipherSpecs) {
+		return errSSLBufferOverflow;
+	}
+	for(dex=0; dex<numCipherSpecs; dex++) {
+		ciphers[dex] = cipherSpecs[dex].cipherSpec;
+	}
+	*numCiphers = numCipherSpecs;
+	return noErr;
+}
+
+/***
+ *** Publically exported functions declared in SecureTransport.h
+ ***/
+ 
+/*
+ * Determine number and values of all of the SSLCipherSuites we support.
+ * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
+ * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
+ * will be returned. 
+ */
+OSStatus
+SSLGetNumberSupportedCiphers (SSLContextRef	ctx,
+							  UInt32		*numCiphers)
+{
+	if((ctx == NULL) || (numCiphers == NULL)) {
+		return paramErr;
+	}
+	*numCiphers = CipherSpecCount;
+	return noErr;
+}
+			
+OSStatus
+SSLGetSupportedCiphers		 (SSLContextRef		ctx,
+							  SSLCipherSuite	*ciphers,		/* RETURNED */
+							  UInt32			*numCiphers)	/* IN/OUT */
+{
+	if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
+		return paramErr;
+	}
+	return cipherSpecsToCipherSuites(CipherSpecCount,
+		KnownCipherSpecs,
+		ciphers,
+		numCiphers);
+}
+
+/*
+ * Specify a (typlically) restricted set of SSLCipherSuites to be enabled by
+ * the current SSLContext. Can only be called when no session is active. Default
+ * set of enabled SSLCipherSuites is the same as the complete set of supported 
+ * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
+ */
+OSStatus 
+SSLSetEnabledCiphers		(SSLContextRef			ctx,
+							 const SSLCipherSuite	*ciphers,	
+							 UInt32					numCiphers)
+{
+	unsigned 		size;
+	unsigned 		callerDex;
+	unsigned		tableDex;
+	
+	if((ctx == NULL) || (ciphers == NULL) || (numCiphers == 0)) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	size = numCiphers * sizeof(SSLCipherSpec);
+	ctx->validCipherSpecs = sslMalloc(size);
+	if(ctx->validCipherSpecs == NULL) {
+		ctx->numValidCipherSpecs = 0;
+		return SSLMemoryErr;
+	}
+
+	/* 
+	 * Run thru caller's specs, finding a matching SSLCipherSpec for each one.
+	 * If caller specifies one we don't know about, abort. 
+	 */
+	for(callerDex=0; callerDex<numCiphers; callerDex++) {
+		/* find matching CipherSpec in our known table */
+		int foundOne = 0;
+		for(tableDex=0; tableDex<CipherSpecCount; tableDex++) {
+			if(ciphers[callerDex] == KnownCipherSpecs[tableDex].cipherSpec) {
+				ctx->validCipherSpecs[callerDex] = KnownCipherSpecs[tableDex];
+				foundOne = 1;
+				break;
+			}
+		}
+		if(!foundOne) {
+			/* caller specified one we don't implement */
+			sslFree(ctx->validCipherSpecs);
+			ctx->validCipherSpecs = NULL;
+			return errSSLBadCipherSuite;
+		}
+	}
+	
+	/* success */
+	ctx->numValidCipherSpecs = numCiphers;
+	return noErr;
+}
+							 
+/*
+ * Determine number and values of all of the SSLCipherSuites currently enabled.
+ * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
+ * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
+ * will be returned. 
+ */
+OSStatus
+SSLGetNumberEnabledCiphers 	(SSLContextRef			ctx,
+							 UInt32					*numCiphers)
+{
+	if((ctx == NULL) || (numCiphers == NULL)) {
+		return paramErr;
+	}
+	if(ctx->validCipherSpecs == NULL) {
+		/* hasn't been set; use default */
+		*numCiphers = CipherSpecCount;
+	}
+	else {
+		/* caller set via SSLSetEnabledCiphers */
+		*numCiphers = ctx->numValidCipherSpecs;
+	}
+	return noErr;
+}
+			
+OSStatus
+SSLGetEnabledCiphers		(SSLContextRef			ctx,
+							 SSLCipherSuite			*ciphers,		/* RETURNED */
+							 UInt32					*numCiphers)	/* IN/OUT */
+{
+	if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
+		return paramErr;
+	}
+	if(ctx->validCipherSpecs == NULL) {
+		/* hasn't been set; use default */
+		return cipherSpecsToCipherSuites(CipherSpecCount,
+			KnownCipherSpecs,
+			ciphers,
+			numCiphers);
+	}
+	else {
+		/* use the ones specified in SSLSetEnabledCiphers() */
+		return cipherSpecsToCipherSuites(ctx->numValidCipherSpecs,
+			ctx->validCipherSpecs,
+			ciphers,
+			numCiphers);
+	}
+}
+
+/***
+ *** End of publically exported functions declared in SecureTransport.h
+ ***/
+
+/*
+ * Given a valid ctx->selectedCipher and ctx->validCipherSpecs, set
+ * ctx->selectedCipherSpec as appropriate. 
+ */
+SSLErr
+FindCipherSpec(SSLContext *ctx)
+{   
+
+	unsigned i;
+    
+    CASSERT(ctx != NULL);
+    CASSERT(ctx->validCipherSpecs != NULL);
+    
+    ctx->selectedCipherSpec = NULL;
+    for (i=0; i<ctx->numValidCipherSpecs; i++)
+    {   if (ctx->validCipherSpecs[i].cipherSpec == ctx->selectedCipher) {
+        	ctx->selectedCipherSpec = &ctx->validCipherSpecs[i];
+            break;
+        }
+    }    
+    if (ctx->selectedCipherSpec == NULL)         /* Not found */
+        return SSLNegotiationErr;
+    return SSLNoErr;
+}
+
diff --git a/SecureTransport/cppUtils.cpp b/SecureTransport/cppUtils.cpp
new file mode 100644
index 00000000..d6a5fe48
--- /dev/null
+++ b/SecureTransport/cppUtils.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+
+#include "sslBuildFlags.h"
+#include <Security/cssmtype.h>
+#include "appleCdsa.h"
+#include <Security/cssmerrno.h>
+
+#if		SSL_DEBUG
+void stPrintCdsaError(const char *op, CSSM_RETURN crtn)
+{
+	cssmPerror(op, crtn);
+}
+
+char *stCssmErrToStr(CSSM_RETURN err)
+{
+	string errStr = cssmErrorString(err);
+	return const_cast<char *>(errStr.c_str());
+}
+#endif
+
diff --git a/SecureTransport/digests.c b/SecureTransport/digests.c
new file mode 100644
index 00000000..3654d31d
--- /dev/null
+++ b/SecureTransport/digests.c
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		digests.c
+
+	Contains:	interface between SSL and SHA, MD5 digest libraries
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: digests.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: digests.c    Hashing support functions and data structures
+
+    Contains interface functions which generalize hashing support for MD5
+    and SHA1 and a dummy null hash implementation (used before MACing is
+    turned on). Also, utility functions for using the hashes.
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _CRYPTTYPE_H_
+#include "cryptType.h"
+#endif
+
+#ifndef SHA_H
+#include <stdio.h>      /* sha.h has a prototype with a FILE* */
+#include "st_sha.h"
+#endif
+
+#ifndef	_SSL_MD5_H_
+#include "sslmd5.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef	_DIGESTS_H_
+#include "digests.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#include <string.h>
+
+typedef struct
+{   SHA_INFO    sha;
+    int         bufferPos;
+    uint8       dataBuffer[SHA_BLOCKSIZE];
+} SSL_SHA_INFO;
+
+uint8   SSLMACPad1[MAX_MAC_PADDING], SSLMACPad2[MAX_MAC_PADDING];
+
+/*
+ * Public general hash functions 
+ */
+void
+SSLInitMACPads(void)
+{   int     i;
+    
+    for (i = 0; i < MAX_MAC_PADDING; i++)
+    {   SSLMACPad1[i] = 0x36;
+        SSLMACPad2[i] = 0x5C;
+    }
+}
+
+/* FIXME - what's this for, if each alg has its own clone functions? */
+SSLErr
+CloneHashState(const HashReference *ref, SSLBuffer state, SSLBuffer *newState, SSLContext *ctx)
+{   SSLErr      err;
+    if ((err = SSLAllocBuffer(newState, state.length, &ctx->sysCtx)) != 0)
+        return err;
+    memcpy(newState->data, state.data, state.length);
+    return SSLNoErr;
+}
+
+SSLErr
+ReadyHash(const HashReference *ref, SSLBuffer *state, SSLContext *ctx)
+{   SSLErr      err;
+    if ((err = SSLAllocBuffer(state, ref->contextSize, &ctx->sysCtx)) != 0)
+        return err;
+    if ((err = ref->init(*state)) != 0)
+        return err;
+    return SSLNoErr;
+}
+
+static SSLErr HashNullInit(SSLBuffer);
+static SSLErr HashNullUpdate(SSLBuffer,SSLBuffer);
+static SSLErr HashNullFinal(SSLBuffer,SSLBuffer);
+static SSLErr HashNullClone(SSLBuffer,SSLBuffer);
+
+static SSLErr HashMD5Init(SSLBuffer digestCtx);
+static SSLErr HashMD5Update(SSLBuffer digestCtx, SSLBuffer data);
+static SSLErr HashMD5Final(SSLBuffer digestCtx, SSLBuffer digest);
+static SSLErr HashMD5Clone(SSLBuffer src, SSLBuffer dest);
+
+static SSLErr HashSHA1Init(SSLBuffer digestCtx);
+static SSLErr HashSHA1Update(SSLBuffer digestCtx, SSLBuffer data);
+static SSLErr HashSHA1Final(SSLBuffer digestCtx, SSLBuffer digest);
+static SSLErr HashSHA1Clone(SSLBuffer src, SSLBuffer dest);
+
+/*
+ * These are the handles by which the bulk of digesting work
+ * is done.
+ */
+const HashReference SSLHashNull = 
+	{ 	
+		0, 
+	  	0, 
+	  	0, 
+	  	HashNullInit, 
+	  	HashNullUpdate, 
+	  	HashNullFinal, 
+	  	HashNullClone 
+	};
+	
+const HashReference SSLHashMD5 = 
+	{ 
+		sizeof(MD5_CTX), 
+		16, 
+		48, 
+		HashMD5Init, 
+		HashMD5Update, 
+		HashMD5Final, 
+		HashMD5Clone 
+	};
+
+const HashReference SSLHashSHA1 = 
+	{ 
+		sizeof(SSL_SHA_INFO), 
+		20, 
+		40, 
+		HashSHA1Init, 
+		HashSHA1Update, 
+		HashSHA1Final, 
+		HashSHA1Clone 
+	};
+
+/*** NULL ***/
+static SSLErr HashNullInit(SSLBuffer digestCtx) { 
+	return SSLNoErr; 
+}
+
+static SSLErr HashNullUpdate(SSLBuffer digestCtx, SSLBuffer data) { 
+	return SSLNoErr; 
+}
+
+static SSLErr HashNullFinal(SSLBuffer digestCtx, SSLBuffer digest) { 
+	return SSLNoErr; 
+}
+
+static SSLErr HashNullClone(SSLBuffer src, SSLBuffer dest) { 
+	return SSLNoErr; 
+}
+
+/*** MD5 ***/
+
+static SSLErr HashMD5Init(SSLBuffer digestCtx)
+{   CASSERT(digestCtx.length >= sizeof(MD5_CTX));
+    SSLMD5Init((MD5_CTX*)digestCtx.data);
+    return SSLNoErr;
+}
+
+static SSLErr HashMD5Update(SSLBuffer digestCtx, SSLBuffer data)
+{   CASSERT(digestCtx.length >= sizeof(MD5_CTX));
+    SSLMD5Update((MD5_CTX*)digestCtx.data, data.data, data.length);
+    return SSLNoErr;
+}
+
+static SSLErr HashMD5Final(SSLBuffer digestCtx, SSLBuffer digest)
+{   CASSERT(digestCtx.length >= sizeof(MD5_CTX));
+    CASSERT(digest.length >= 16);
+    SSLMD5Final(digest.data, (MD5_CTX*)digestCtx.data);
+    digest.length = 16;
+    return SSLNoErr;
+}
+
+static SSLErr HashMD5Clone(SSLBuffer src, SSLBuffer dest)
+{   
+	if (src.length != dest.length) {
+		errorLog0("HashMD5Clone: length mismatch\n");
+        return SSLProtocolErr;
+    }
+    memcpy(dest.data, src.data, src.length);
+    return SSLNoErr;
+}   
+
+/*** SHA ***/
+static SSLErr HashSHA1Init(SSLBuffer digestCtx)
+{   SSL_SHA_INFO    *ctx = (SSL_SHA_INFO*)digestCtx.data;
+    CASSERT(digestCtx.length >= sizeof(SSL_SHA_INFO));
+    sha_init(&ctx->sha);
+    ctx->bufferPos = 0;
+    return SSLNoErr;
+}
+
+static SSLErr HashSHA1Update(SSLBuffer digestCtx, SSLBuffer data)
+{   SSL_SHA_INFO    *ctx = (SSL_SHA_INFO*)digestCtx.data;
+    uint32          dataRemaining, processed;
+    uint8           *dataPos;
+    
+    CASSERT(digestCtx.length >= sizeof(SSL_SHA_INFO));
+    dataRemaining = data.length;
+    dataPos = data.data;
+    while (dataRemaining > 0)
+    {   processed = SHA_BLOCKSIZE - ctx->bufferPos;
+        if (dataRemaining < processed)
+            processed = dataRemaining;
+        memcpy(ctx->dataBuffer+ctx->bufferPos, dataPos, processed);
+        ctx->bufferPos += processed;
+        if (ctx->bufferPos == SHA_BLOCKSIZE)
+        {   sha_update(&ctx->sha, ctx->dataBuffer, ctx->bufferPos);
+            ctx->bufferPos = 0;
+        }
+        dataRemaining -= processed;
+        dataPos += processed;
+    }
+    //DUMP_BUFFER_PTR("SHA1 data", digestCtx.data, data);
+    return SSLNoErr;
+}
+
+static SSLErr HashSHA1Final(SSLBuffer digestCtx, SSLBuffer digest)
+{   SSL_SHA_INFO    *ctx = (SSL_SHA_INFO*)digestCtx.data;
+    CASSERT(digestCtx.length >= sizeof(SSL_SHA_INFO));
+    CASSERT(digest.length >= SHA_DIGESTSIZE);
+    if (ctx->bufferPos > 0)
+        sha_update(&ctx->sha, ctx->dataBuffer, ctx->bufferPos);
+    sha_final((SHA_INFO*)digestCtx.data);
+    memcpy(digest.data, ((SHA_INFO*)digestCtx.data)->digest, 20);
+    //DUMP_BUFFER_PTR("SHA1 final", digestCtx.data, digest);
+    return SSLNoErr;
+}
+
+static SSLErr HashSHA1Clone(SSLBuffer src, SSLBuffer dest)
+{   if (src.length != dest.length) {
+		errorLog0("HashSHA1Clone: length mismatch\n");
+        return SSLProtocolErr;
+    }
+    memcpy(dest.data, src.data, src.length);
+    return SSLNoErr;
+}   
diff --git a/SecureTransport/hdskcert.c b/SecureTransport/hdskcert.c
new file mode 100644
index 00000000..63f6e539
--- /dev/null
+++ b/SecureTransport/hdskcert.c
@@ -0,0 +1,594 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		hdskcert.c
+
+	Contains:	certificate request/verify messages
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: hdskcert.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: hdskcert.c   Contains support for certificate-related messages
+
+    Support for encoding and decoding the certificate, certificate
+    request, and certificate verify messages.
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef	_DIGESTS_H_
+#include "digests.h"
+#endif
+
+#ifndef	_APPLE_CDSA_H_
+#include "appleCdsa.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#include <string.h>
+
+SSLErr
+SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx)
+{   SSLErr          err;
+    UInt32          totalLength;
+    int             i, j, certCount;
+    UInt8           *progress;
+    SSLCertificate  *cert;
+    
+    /* Match DER-encoded root certs here */
+
+    cert = ctx->localCert;
+    CASSERT(cert != 0);
+    totalLength = 0;
+    certCount = 0;
+    while (cert)
+    {   totalLength += 3 + cert->derCert.length;    /* 3 for encoded length field */
+        ++certCount;
+        cert = cert->next;
+    }
+    
+    certificate->contentType = SSL_handshake;
+    certificate->protocolVersion = SSL_Version_3_0;
+    if ((err = SSLAllocBuffer(&certificate->contents, totalLength + 7, &ctx->sysCtx)) != 0)
+        return err;
+    
+    progress = certificate->contents.data;
+    *progress++ = SSL_certificate;
+    progress = SSLEncodeInt(progress, totalLength+3, 3);    /* Handshake message length */
+    progress = SSLEncodeInt(progress, totalLength, 3);      /* Vector length */
+    
+    /* Root cert is first in the linked list, but has to go last, so walk list backwards */
+    for (i = 0; i < certCount; ++i)
+    {   cert = ctx->localCert;
+        for (j = i+1; j < certCount; ++j)
+            cert = cert->next;
+        progress = SSLEncodeInt(progress, cert->derCert.length, 3);
+        memcpy(progress, cert->derCert.data, cert->derCert.length);
+        progress += cert->derCert.length;
+    }
+    
+    CASSERT(progress == certificate->contents.data + certificate->contents.length);
+    
+    if (ctx->protocolSide == SSL_ClientSide)
+        ctx->certSent = 1;
+
+    return SSLNoErr;
+}
+
+SSLErr
+SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
+{   SSLErr          err;
+    UInt32          listLen, certLen;
+	#ifndef	__APPLE__
+    SSLBuffer       buf;
+	#endif
+    UInt8           *p;
+    SSLCertificate  *cert;
+    
+    p = message.data;
+    listLen = SSLDecodeInt(p,3);
+    p += 3;
+    if (listLen + 3 != message.length) {
+    	errorLog0("SSLProcessCertificate: length decode error 1\n");
+        return SSLProtocolErr;
+    }
+    
+    while (listLen > 0)
+    {   certLen = SSLDecodeInt(p,3);
+        p += 3;
+        if (listLen < certLen + 3) {
+    		errorLog0("SSLProcessCertificate: length decode error 2\n");
+            return SSLProtocolErr;
+        }
+		#ifdef	__APPLE__
+		cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
+		if(cert == NULL) {
+			return SSLMemoryErr;
+		}
+        if ((err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
+        {   sslFree(cert);
+            return err;
+        }
+		#else
+        if ((err = SSLAllocBuffer(&buf, sizeof(SSLCertificate), &ctx->sysCtx)) != 0)
+            return err;
+        cert = (SSLCertificate*)buf.data;
+        if ((err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
+        {   SSLFreeBuffer(&buf, &ctx->sysCtx);
+            return err;
+        }
+		#endif
+        memcpy(cert->derCert.data, p, certLen);
+        p += certLen;
+        cert->next = ctx->peerCert;     /* Insert backwards; root cert will be first in linked list */
+        ctx->peerCert = cert;
+        #ifndef	_APPLE_CDSA_
+        /* we don't parse this, the CL does */
+        if ((err = ASNParseX509Certificate(cert->derCert, &cert->cert, ctx)) != 0)
+            return err;        
+        #endif
+        listLen -= 3+certLen;
+    }
+    CASSERT(p == message.data + message.length && listLen == 0);
+    
+    if (ctx->peerCert == 0)
+        return X509CertChainInvalidErr;
+    
+    #ifdef	_APPLE_CDSA_
+    if((err = sslVerifyCertChain(ctx, ctx->peerCert)) != 0) 
+    #else
+    if ((err = X509VerifyCertChain(ctx->peerCert, ctx)) != 0)
+	#endif
+        return err;
+
+/* Server's certificate is the last one in the chain */
+    cert = ctx->peerCert;
+    while (cert->next != 0)
+        cert = cert->next;
+/* Convert its public key to RSAREF format */
+    #ifdef	_APPLE_CDSA_
+    if ((err = sslPubKeyFromCert(ctx, 
+    	&cert->derCert, 
+    	&ctx->peerPubKey,
+    	&ctx->peerPubKeyCsp)) != 0)
+    #else
+    if ((err = X509ExtractPublicKey(&cert->cert.pubKey, &ctx->peerKey)) != 0)
+    #endif
+        return err;
+    
+    #ifndef	_APPLE_CDSA_
+    /*
+     * This appears to be redundant with the cert check above; 
+     * it's here for additional cert checking by clients of SSLRef. 
+     */
+    if (ctx->certCtx.checkCertFunc != 0)
+    {   SSLBuffer       certList, *certs;
+        int             i,certCount;
+        SSLCertificate  *c;
+        
+        if ((err = SSLGetPeerCertificateChainLength(ctx, &certCount)) != 0)
+            return err;
+        if ((err = SSLAllocBuffer(&certList, certCount * sizeof(SSLBuffer), &ctx->sysCtx)) != 0)
+            return err;
+        certs = (SSLBuffer *)certList.data;
+        c = ctx->peerCert;
+        for (i = 0; i < certCount; i++, c = c->next)
+            certs[i] = c->derCert;
+        
+        if ((err = ctx->certCtx.checkCertFunc(certCount, certs, ctx->certCtx.checkCertRef)) != 0)
+        {   SSLFreeBuffer(&certList, &ctx->sysCtx);
+            return err;
+        }
+        SSLFreeBuffer(&certList, &ctx->sysCtx);
+    }
+    #endif	/* _APPLE_CDSA_ */
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx)
+{   
+	#if		!ST_SERVER_MODE_ENABLE
+	
+	/* cert request only happens in server mode */
+	errorLog0("SSLEncodeCertificateRequest called\n");
+	return SSLUnsupportedErr;
+	
+	#else
+ 
+	SSLErr      err;
+    UInt32      dnListLen, msgLen;
+    UInt8       *progress;
+    DNListElem  *dn;
+    
+	dnListLen = 0;
+    dn = ctx->acceptableDNList;
+    CASSERT(dn != NULL);
+    while (dn)
+    {   dnListLen += 2 + dn->derDN.length;
+        dn = dn->next;
+    }
+    msgLen = 1 + 1 + 2 + dnListLen;
+    
+    request->contentType = SSL_handshake;
+    request->protocolVersion = SSL_Version_3_0;
+    if ((err = SSLAllocBuffer(&request->contents, msgLen + 4, &ctx->sysCtx)) != 0)
+        return err;
+    
+    progress = request->contents.data;
+    *progress++ = SSL_certificate_request;
+    progress = SSLEncodeInt(progress, msgLen, 3);
+    
+    *progress++ = 1;        /* one cert type */
+    *progress++ = 1;        /* RSA-sign type */
+    progress = SSLEncodeInt(progress, dnListLen, 2);
+    dn = ctx->acceptableDNList;
+    while (dn)
+    {   progress = SSLEncodeInt(progress, dn->derDN.length, 2);
+        memcpy(progress, dn->derDN.data, dn->derDN.length);
+        progress += dn->derDN.length;
+        dn = dn->next;
+    }
+    
+    CASSERT(progress == request->contents.data + request->contents.length);
+    
+    return SSLNoErr;
+	#endif	/* ST_SERVER_MODE_ENABLE */
+}
+
+SSLErr
+SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx)
+{   SSLErr          err;
+    int             i, dnListLen, dnLen;
+    unsigned int    typeCount;
+    UInt8           *progress;
+    SSLBuffer       dnBuf;
+    DNListElem      *dn;
+    
+	/* cert request only happens in during client authentication, which
+	 * we don't do */
+	errorLog0("SSLProcessCertificateRequest called\n");
+    if (message.length < 3) {
+    	errorLog0("SSLProcessCertificateRequest: length decode error 1\n");
+        return ERR(SSLProtocolErr);
+    }
+    progress = message.data;
+    typeCount = *progress++;
+    if (typeCount < 1 || message.length < 3 + typeCount) {
+    	errorLog0("SSLProcessCertificateRequest: length decode error 2\n");
+        return ERR(SSLProtocolErr);
+    }
+    for (i = 0; i < typeCount; i++)
+    {   if (*progress++ == 1)
+            ctx->x509Requested = 1;
+    }
+    
+    dnListLen = SSLDecodeInt(progress, 2);
+    progress += 2;
+    if (message.length != 3 + typeCount + dnListLen) {
+    	errorLog0("SSLProcessCertificateRequest: length decode error 3\n");
+        return ERR(SSLProtocolErr);
+	}    
+    while (dnListLen > 0)
+    {   if (dnListLen < 2) {
+    		errorLog0("SSLProcessCertificateRequest: dnListLen error 1\n");
+            return ERR(SSLProtocolErr);
+        }
+        dnLen = SSLDecodeInt(progress, 2);
+        progress += 2;
+        if (dnListLen < 2 + dnLen) {
+     		errorLog0("SSLProcessCertificateRequest: dnListLen error 2\n");
+           	return ERR(SSLProtocolErr);
+    	}
+        if (ERR(err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem), &ctx->sysCtx)) != 0)
+            return err;
+        dn = (DNListElem*)dnBuf.data;
+        if (ERR(err = SSLAllocBuffer(&dn->derDN, dnLen, &ctx->sysCtx)) != 0)
+        {   SSLFreeBuffer(&dnBuf, &ctx->sysCtx);
+            return err;
+        }
+        memcpy(dn->derDN.data, progress, dnLen);
+        progress += dnLen;
+        dn->next = ctx->acceptableDNList;
+        ctx->acceptableDNList = dn;
+        dnListLen -= 2 + dnLen;
+    }
+    
+    CASSERT(progress == message.data + message.length);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx)
+{   SSLErr          err;
+    UInt8           signedHashData[36];
+    SSLBuffer       hashData, shaMsgState, md5MsgState;
+    UInt32          len;
+    UInt32		    outputLen;
+    
+    certVerify->contents.data = 0;
+    hashData.data = signedHashData;
+    hashData.length = 36;
+    
+    if (ERR(err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
+        goto fail;
+    if (ERR(err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
+        goto fail;
+    if (ERR(err = SSLCalculateFinishedMessage(hashData, shaMsgState, md5MsgState, 0, ctx)) != 0)
+        goto fail;
+    
+#if RSAREF
+    len = (ctx->localKey.bits + 7)/8;
+#elif BSAFE
+    {   A_RSA_KEY   *keyInfo;
+        int         rsaResult;
+        
+        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->localKey, KI_RSAPublic)) != 0)
+            return ERR(SSLUnknownErr);
+        len = keyInfo->modulus.len;
+    }
+#elif	_APPLE_CDSA_
+	CASSERT(ctx->signingPrivKey != NULL);
+	len = sslKeyLengthInBytes(ctx->signingPrivKey);
+#else
+#error No asymmetric crypto specified
+#endif /* RSAREF / BSAFE */
+    
+    certVerify->contentType = SSL_handshake;
+    certVerify->protocolVersion = SSL_Version_3_0;
+    if (ERR(err = SSLAllocBuffer(&certVerify->contents, len + 6, &ctx->sysCtx)) != 0)
+        goto fail;
+    
+    certVerify->contents.data[0] = SSL_certificate_verify;
+    SSLEncodeInt(certVerify->contents.data+1, len+2, 3);
+    SSLEncodeInt(certVerify->contents.data+4, len, 2);
+#if RSAREF
+    if (RSAPrivateEncrypt(certVerify->contents.data+6, &outputLen,
+                    signedHashData, 36, &ctx->localKey) != 0)   /* Sign the structure */
+    {   err = ERR(SSLUnknownErr);
+        goto fail;
+    }
+#elif BSAFE
+    {   B_ALGORITHM_OBJ     rsa;
+        B_ALGORITHM_METHOD  *chooser[] = { &AM_RSA_CRT_ENCRYPT, 0 };
+        int                 rsaResult;
+        
+        if (ERR(rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
+            return SSLUnknownErr;
+        if (ERR(rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPrivate, 0)) != 0)
+            return SSLUnknownErr;
+        if (ERR(rsaResult = B_EncryptInit(rsa, ctx->localKey, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        if (ERR(rsaResult = B_EncryptUpdate(rsa, certVerify->contents.data+6,
+                    &outputLen, len, signedHashData, 36, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        if (ERR(rsaResult = B_EncryptFinal(rsa, certVerify->contents.data+6+outputLen,
+                    &outputLen, len-outputLen, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        B_DestroyAlgorithmObject(&rsa);
+    }
+#elif	_APPLE_CDSA_
+
+		err = sslRsaRawSign(ctx,
+			ctx->signingPrivKey,
+			ctx->signingKeyCsp,
+			signedHashData,
+			36,				// MD5 size + SHA1 size
+			certVerify->contents.data+6,
+			len,			// we mallocd len+6
+			&outputLen);
+		if(err) {
+			goto fail;
+		}
+#else
+#error No asymmetric crypto specified
+#endif /* RSAREF / BSAFE */
+    
+    CASSERT(outputLen == len);
+    
+    err = SSLNoErr;
+    
+fail:
+    ERR(SSLFreeBuffer(&shaMsgState, &ctx->sysCtx));
+    ERR(SSLFreeBuffer(&md5MsgState, &ctx->sysCtx));
+
+    return err;
+}
+
+SSLErr
+SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx)
+{   SSLErr          err;
+    UInt8           signedHashData[36];
+    UInt16          signatureLen;
+    SSLBuffer       hashData, shaMsgState, md5MsgState, outputData;
+    #if	defined(BSAFE) || defined(RSAREF)
+    unsigned int    outputLen;
+    #endif
+    unsigned int    publicModulusLen;
+    
+    shaMsgState.data = 0;
+    md5MsgState.data = 0;
+    outputData.data = 0;
+    
+    if (message.length < 2) {
+    	errorLog0("SSLProcessCertificateVerify: msg len error\n");
+        return ERR(SSLProtocolErr);     
+    }
+    
+    signatureLen = (UInt16)SSLDecodeInt(message.data, 2);
+    if (message.length != 2 + signatureLen) {
+    	errorLog0("SSLProcessCertificateVerify: sig len error 1\n");
+        return ERR(SSLProtocolErr);
+    }
+    
+#if RSAREF
+    publicModulusLen = (ctx->peerKey.bits + 7)/8;
+#elif BSAFE
+    {   A_RSA_KEY   *keyInfo;
+        int         rsaResult;
+        
+        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->peerKey, KI_RSAPublic)) != 0)
+            return SSLUnknownErr;
+        publicModulusLen = keyInfo->modulus.len;
+    }
+#elif	_APPLE_CDSA_
+	CASSERT(ctx->peerPubKey != NULL);
+	publicModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
+#else
+#error No asymmetric crypto specified
+#endif /* RSAREF / BSAFE */
+    
+    if (signatureLen != publicModulusLen) {
+    	errorLog0("SSLProcessCertificateVerify: sig len error 2\n");
+        return ERR(SSLProtocolErr);
+    }
+    outputData.data = 0;
+    hashData.data = signedHashData;
+    hashData.length = 36;
+    
+    if (ERR(err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
+        goto fail;
+    if (ERR(err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
+        goto fail;
+    if (ERR(err = SSLCalculateFinishedMessage(hashData, shaMsgState, md5MsgState, 0, ctx)) != 0)
+        goto fail;
+    
+    if (ERR(err = SSLAllocBuffer(&outputData, publicModulusLen, &ctx->sysCtx)) != 0)
+        goto fail;
+    
+#if RSAREF
+    if (RSAPublicDecrypt(outputData.data, &outputLen,
+        message.data + 2, signatureLen, &ctx->peerKey) != 0)
+    {   ERR(err = SSLUnknownErr);
+        goto fail;
+    }
+#elif BSAFE
+    {   B_ALGORITHM_OBJ     rsa;
+        B_ALGORITHM_METHOD  *chooser[] = { &AM_MD2, &AM_MD5, &AM_RSA_DECRYPT, 0 };
+        int                 rsaResult;
+        unsigned int        decryptLen;
+        
+        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_DecryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_DecryptUpdate(rsa, outputData.data, &decryptLen, 36,
+                    message.data + 2, signatureLen, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen = decryptLen;
+        if ((rsaResult = B_DecryptFinal(rsa, outputData.data+outputLen,
+                    &decryptLen, 36-outputLen, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen += decryptLen;
+        B_DestroyAlgorithmObject(&rsa);
+    }
+#elif	_APPLE_CDSA_
+	/* 
+	 * The CSP does the decrypt & compare for us in one shot
+	 */
+	err = sslRsaRawVerify(ctx,
+		ctx->peerPubKey,
+		ctx->peerPubKeyCsp,		// FIXME - maybe we just use cspHand?
+		message.data + 2, 
+		signatureLen,
+		outputData.data,
+		36);
+	if(err) {
+		goto fail;
+	}
+		
+#endif /* RSAREF / BSAFE */
+    
+#if	!_APPLE_CDSA_
+	/* we don't have to do the compare */
+    if (outputLen != 36)
+    {   
+    	ERR(err = SSLProtocolErr);
+        goto fail;
+    }
+    outputData.length = outputLen;
+    
+    DUMP_BUFFER_NAME("Finished got   ", outputData);
+    DUMP_BUFFER_NAME("Finished wanted", hashData);
+    
+    if (memcmp(outputData.data, signedHashData, 36) != 0)
+    {   
+    	ERR(err = SSLProtocolErr);
+        goto fail;
+    }
+#endif	/* BSAFE, RSAREF only */
+
+    err = SSLNoErr;
+    
+fail:
+    ERR(SSLFreeBuffer(&shaMsgState, &ctx->sysCtx));
+    ERR(SSLFreeBuffer(&md5MsgState, &ctx->sysCtx));
+    ERR(SSLFreeBuffer(&outputData, &ctx->sysCtx));
+
+    return err;
+}
diff --git a/SecureTransport/hdskchgc.c b/SecureTransport/hdskchgc.c
new file mode 100644
index 00000000..bf667f79
--- /dev/null
+++ b/SecureTransport/hdskchgc.c
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		hdskchgc.c
+
+	Contains:	support for change cipher spec messages
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: hdskchgc.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: hdskchgc.c   Contains support for change cipher spec messages
+
+    Simple support for encoding and decoding change cipher spec messages;
+    the decode message also installs the pending read cipher (if it is
+    ready).
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#include <string.h>
+
+SSLErr
+SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx)
+{   SSLErr          err;
+    
+    CASSERT(ctx->writePending.ready);
+    
+    #if	LOG_NEGOTIATE
+    dprintf0("===Sending changeCipherSpec msg\n");
+    #endif
+    rec->contentType = SSL_change_cipher_spec;
+    rec->protocolVersion = SSL_Version_3_0;
+    rec->contents.length = 1;
+    if ((err = SSLAllocBuffer(&rec->contents, 1, &ctx->sysCtx)) != 0)
+        return err;
+    rec->contents.data[0] = 1;
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx)
+{   SSLErr          err;
+    
+    if (rec.contents.length != 1 || rec.contents.data[0] != 1)
+    {   SSLFatalSessionAlert(alert_unexpected_message, ctx);
+    	errorLog2("***bad changeCipherSpec msg: length %d data 0x%x\n",
+    		(unsigned)rec.contents.length, (unsigned)rec.contents.data[0]);
+        return SSLProtocolErr;
+    }
+    
+    if (!ctx->readPending.ready || ctx->state != HandshakeChangeCipherSpec)
+    {   SSLFatalSessionAlert(alert_unexpected_message, ctx);
+    	errorLog2("***bad changeCipherSpec msg: readPending.ready %d state %d\n",
+    		(unsigned)ctx->readPending.ready, (unsigned)ctx->state);
+        return SSLProtocolErr;
+    }
+    
+    #if	LOG_NEGOTIATE
+    dprintf0("===Processing changeCipherSpec msg\n");
+    #endif
+    
+    /* Install new cipher spec on read side */
+    if ((err = SSLDisposeCipherSuite(&ctx->readCipher, ctx)) != 0)
+    {   SSLFatalSessionAlert(alert_close_notify, ctx);
+        return err;
+    }
+    ctx->readCipher = ctx->readPending;
+    ctx->readCipher.ready = 0;      /* Can't send data until Finished is sent */
+    SSLChangeHdskState(ctx, HandshakeFinished);
+    memset(&ctx->readPending, 0, sizeof(CipherContext));        /* Zero out old data */
+    return SSLNoErr;    
+}
+
+SSLErr
+SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (cipher->symKey)
+    {   if ((err = cipher->symCipher->finish(cipher, ctx)) != 0)
+            return err;
+        cipher->symKey = 0;
+    }
+    
+    return SSLNoErr;
+}
diff --git a/SecureTransport/hdskfini.c b/SecureTransport/hdskfini.c
new file mode 100644
index 00000000..ca0392e4
--- /dev/null
+++ b/SecureTransport/hdskfini.c
@@ -0,0 +1,250 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		hdskfini.c
+
+	Contains:	Finished and server hello done messages. 
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: hdskfini.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: hdskfini.c   Finished and server hello done messages
+
+    Support for encoding and decoding finished and server hello done
+    messgages. Also includes the necessary calculations for the Finished
+    message; note that the same function is used to calculate certificate
+    verify message hashes (without the 'SRVR' or 'CLNT' protocol side
+    identifier).
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef	_DIGESTS_H_
+#include "digests.h"
+#endif
+
+#include <string.h>
+
+SSLErr
+SSLEncodeFinishedMessage(SSLRecord *finished, SSLContext *ctx)
+{   SSLErr          err;
+    SSLBuffer       finishedMsg, shaMsgState, md5MsgState;
+    UInt32          sideSenderValue;
+    
+    shaMsgState.data = 0;
+    md5MsgState.data = 0;
+    
+    finished->contentType = SSL_handshake;
+    finished->protocolVersion = SSL_Version_3_0;
+    if ((err = SSLAllocBuffer(&finished->contents, 40, &ctx->sysCtx)) != 0)
+        return err;
+    
+    finished->contents.data[0] = SSL_finished;
+    SSLEncodeInt(finished->contents.data + 1, 36, 3);
+    
+    finishedMsg.data = finished->contents.data+4;
+    finishedMsg.length = 36;
+    
+    if ((err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
+        goto fail;
+    if ((err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
+        goto fail;
+    sideSenderValue = (ctx->protocolSide == SSL_ServerSide) ? SSL_Finished_Sender_Server : SSL_Finished_Sender_Client;
+    if ((err = SSLCalculateFinishedMessage(finishedMsg, shaMsgState, md5MsgState, sideSenderValue, ctx)) != 0)
+        goto fail;  
+    
+fail:
+    SSLFreeBuffer(&shaMsgState, &ctx->sysCtx);
+    SSLFreeBuffer(&md5MsgState, &ctx->sysCtx);
+    return err;
+}
+
+SSLErr
+SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
+{   SSLErr          err;
+    SSLBuffer       expectedFinished, shaMsgState, md5MsgState;
+    UInt32          peerSenderValue;
+    
+    if (message.length != 36) {
+		errorLog0("SSLProcessFinished: msg len error 1\n");
+        return SSLProtocolErr;
+    }
+    peerSenderValue = (ctx->protocolSide == SSL_ClientSide) ? SSL_Finished_Sender_Server : SSL_Finished_Sender_Client;
+    expectedFinished.data = 0;
+    if ((err = SSLAllocBuffer(&expectedFinished, 36, &ctx->sysCtx)) != 0)
+        return err;
+    shaMsgState.data = 0;
+    if ((err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
+        goto fail;
+    md5MsgState.data = 0;
+    if ((err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
+        goto fail;
+    if ((err = SSLCalculateFinishedMessage(expectedFinished, shaMsgState, md5MsgState, peerSenderValue, ctx)) != 0)
+        goto fail;
+    DUMP_BUFFER_NAME("finished got", message);
+    DUMP_BUFFER_NAME("finished wanted", expectedFinished);
+    if (memcmp(expectedFinished.data, message.data, 36) != 0)
+    {  
+   		errorLog0("SSLProcessFinished: memcmp failure\n");
+   	 	err = SSLProtocolErr;
+        goto fail;
+    }
+    
+fail:
+    SSLFreeBuffer(&expectedFinished, &ctx->sysCtx);
+    SSLFreeBuffer(&shaMsgState, &ctx->sysCtx);
+    SSLFreeBuffer(&md5MsgState, &ctx->sysCtx);
+    return err;
+}
+
+SSLErr
+SSLCalculateFinishedMessage(SSLBuffer finished, SSLBuffer shaMsgState,
+            SSLBuffer md5MsgState, UInt32 senderID, SSLContext *ctx)
+{   SSLErr          err;
+    SSLBuffer       hash, input;
+    UInt8           sender[4], md5Inner[16], shaInner[20];
+    
+    CASSERT(finished.length == 36);
+    
+    if (senderID != 0)
+    {   SSLEncodeInt(sender, senderID, 4);
+        input.data = sender;
+        input.length = 4;
+        if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+            return err;
+        if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+            return err;
+    }
+    input.data = ctx->masterSecret;
+    input.length = 48;
+    if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+        return err;
+    if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+        return err;
+    input.data = SSLMACPad1;
+    input.length = SSLHashMD5.macPadSize;
+    if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+        return err;
+    input.length = SSLHashSHA1.macPadSize;
+    if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+        return err;
+    hash.data = md5Inner;
+    hash.length = 16;
+    if ((err = SSLHashMD5.final(md5MsgState, hash)) != 0)
+        return err;
+    hash.data = shaInner;
+    hash.length = 20;
+    if ((err = SSLHashSHA1.final(shaMsgState, hash)) != 0)
+        return err;
+    if ((err = SSLHashMD5.init(md5MsgState)) != 0)
+        return err;
+    if ((err = SSLHashSHA1.init(shaMsgState)) != 0)
+        return err;
+    input.data = ctx->masterSecret;
+    input.length = 48;
+    if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+        return err;
+    if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+        return err;
+    input.data = SSLMACPad2;
+    input.length = SSLHashMD5.macPadSize;
+    if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+        return err;
+    input.length = SSLHashSHA1.macPadSize;
+    if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+        return err;
+    input.data = md5Inner;
+    input.length = 16;
+    if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
+        return err;
+    hash.data = finished.data;
+    hash.length = 16;
+    if ((err = SSLHashMD5.final(md5MsgState, hash)) != 0)
+        return err;
+    input.data = shaInner;
+    input.length = 20;
+    if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
+        return err;
+    hash.data = finished.data + 16;
+    hash.length = 20;
+    if ((err = SSLHashSHA1.final(shaMsgState, hash)) != 0)
+        return err;
+    return SSLNoErr;
+}
+
+SSLErr
+SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx)
+{   SSLErr          err;
+    
+    helloDone->contentType = SSL_handshake;
+    helloDone->protocolVersion = SSL_Version_3_0;
+    if ((err = SSLAllocBuffer(&helloDone->contents, 4, &ctx->sysCtx)) != 0)
+        return err;
+    helloDone->contents.data[0] = SSL_server_hello_done;
+    SSLEncodeInt(helloDone->contents.data+1, 0, 3);     /* Message has 0 length */
+    return SSLNoErr;
+}
+
+SSLErr
+SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
+{   CASSERT(ctx->protocolSide == SSL_ClientSide);
+    if (message.length != 0) {
+    	errorLog0("SSLProcessServerHelloDone: nonzero msg len\n");
+        return SSLProtocolErr;
+    }
+    return SSLNoErr;
+}
diff --git a/SecureTransport/hdskhelo.c b/SecureTransport/hdskhelo.c
new file mode 100644
index 00000000..70ee621a
--- /dev/null
+++ b/SecureTransport/hdskhelo.c
@@ -0,0 +1,375 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		hdskhelo.c
+
+	Contains:	Support for client hello and server hello messages. 
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: hdskhelo.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: hdskhelo.c   Support for client hello and server hello messages
+
+    Also, encoding of Random structures and initializing the message
+    hashes used for calculating finished and certificate verify messages.
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLSESS_H_
+#include "sslsess.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef	_APPLE_GLUE_H_
+#include "appleGlue.h"
+#endif
+
+#ifndef	_APPLE_CDSA_H_
+#include "appleCdsa.h"
+#endif
+
+#ifndef	_DIGESTS_H_
+#include "digests.h"
+#endif
+
+#ifndef	_CIPHER_SPECS_H_
+#include "cipherSpecs.h"
+#endif
+
+#include <string.h>
+
+static SSLErr SSLEncodeRandom(unsigned char *p, SSLContext *ctx);
+
+SSLErr
+SSLEncodeServerHello(SSLRecord *serverHello, SSLContext *ctx)
+{   SSLErr          err;
+    UInt8           *progress;
+    int             sessionIDLen;
+    
+    sessionIDLen = 0;
+    if (ctx->sessionID.data != 0)
+        sessionIDLen = (UInt8)ctx->sessionID.length;
+ 	#if LOG_NEGOTIATE
+	dprintf0("===SSL3 server: sending SSL_Version_3_0\n");
+	#endif
+    serverHello->protocolVersion = SSL_Version_3_0;
+    serverHello->contentType = SSL_handshake;
+    if ((err = SSLAllocBuffer(&serverHello->contents, 42 + sessionIDLen, &ctx->sysCtx)) != 0)
+        return err;
+    
+    progress = serverHello->contents.data;
+    *progress++ = SSL_server_hello;
+    progress = SSLEncodeInt(progress, 38 + sessionIDLen, 3);
+    progress = SSLEncodeInt(progress, SSL_Version_3_0, 2);
+    if ((err = SSLEncodeRandom(progress, ctx)) != 0)
+        return err;
+    memcpy(ctx->serverRandom, progress, 32);
+    progress += 32;
+    *(progress++) = (UInt8)sessionIDLen;
+    if (sessionIDLen > 0)
+        memcpy(progress, ctx->sessionID.data, sessionIDLen);
+    progress += sessionIDLen;
+    progress = SSLEncodeInt(progress, ctx->selectedCipher, 2);
+    *(progress++) = 0;      /* Null compression */
+
+    dprintf1("ssl3: server specifying cipherSuite 0x%lx\n", (UInt32)ctx->selectedCipher);
+    
+    CASSERT(progress == serverHello->contents.data + serverHello->contents.length);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
+{   SSLErr              err;
+    SSLProtocolVersion  protocolVersion;
+    unsigned int        sessionIDLen;
+    UInt8               *p;
+    
+    CASSERT(ctx->protocolSide == SSL_ClientSide);
+    
+    if (message.length < 38 || message.length > 70) {
+    	errorLog0("SSLProcessServerHello: msg len error\n");
+        return SSLProtocolErr;
+    }
+    p = message.data;
+    
+    protocolVersion = (SSLProtocolVersion)SSLDecodeInt(p, 2);
+    p += 2;
+    if (protocolVersion != SSL_Version_3_0)
+        return SSLUnsupportedErr;
+    ctx->negProtocolVersion = protocolVersion;
+    #if LOG_NEGOTIATE
+    dprintf0("===SSL3 client: negVersion is 3_0\n");
+    #endif
+    
+    memcpy(ctx->serverRandom, p, 32);
+    p += 32;
+    
+    sessionIDLen = *p++;
+    if (message.length != 38 + sessionIDLen) {
+    	errorLog0("SSLProcessServerHello: msg len error 2\n");
+        return SSLProtocolErr;
+    }
+    if (sessionIDLen > 0 && ctx->peerID.data != 0)
+    {   /* Don't die on error; just treat it as an uncached session */
+        err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx);
+        if (err == 0)
+            memcpy(ctx->sessionID.data, p, sessionIDLen);
+    }
+    p += sessionIDLen;
+    
+    ctx->selectedCipher = (UInt16)SSLDecodeInt(p,2);
+    #if	LOG_NEGOTIATE
+    dprintf1("===ssl3: server requests cipherKind 0x%x\n", 
+    	(UInt32)ctx->selectedCipher);
+    #endif
+    p += 2;
+    if ((err = FindCipherSpec(ctx)) != 0) {
+        return err;
+    }
+    
+    if (*p++ != 0)      /* Compression */
+        return SSLUnsupportedErr;
+    
+    CASSERT(p == message.data + message.length);
+    return SSLNoErr;
+}
+
+SSLErr
+SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
+{   int             length, i;
+    SSLErr          err;
+    unsigned char   *p;
+    SSLBuffer       sessionIdentifier;
+    UInt16          sessionIDLen;
+    
+    CASSERT(ctx->protocolSide == SSL_ClientSide);
+    
+    sessionIDLen = 0;
+    if (ctx->resumableSession.data != 0)
+    {   if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
+        {   return err;
+        }
+        sessionIDLen = sessionIdentifier.length;
+    }
+    
+    length = 39 + 2*(ctx->numValidCipherSpecs) + sessionIDLen;
+    
+    clientHello->protocolVersion = SSL_Version_3_0;
+    clientHello->contentType = SSL_handshake;
+    if ((err = SSLAllocBuffer(&clientHello->contents, length + 4, &ctx->sysCtx)) != 0)
+        return err;
+    
+    p = clientHello->contents.data;
+    *p++ = SSL_client_hello;
+    p = SSLEncodeInt(p, length, 3);
+    p = SSLEncodeInt(p, SSL_Version_3_0, 2);
+  	#if LOG_NEGOTIATE
+	dprintf0("===SSL3 client: proclaiming Version_3_0 capable ONLY\n");
+	#endif
+   if ((err = SSLEncodeRandom(p, ctx)) != 0)
+    {   SSLFreeBuffer(&clientHello->contents, &ctx->sysCtx);
+        return err;
+    }
+    memcpy(ctx->clientRandom, p, 32);
+    p += 32;
+    *p++ = sessionIDLen;    /* 1 byte vector length */
+    if (sessionIDLen > 0)
+    {   memcpy(p, sessionIdentifier.data, sessionIDLen);
+        if ((err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
+            return err;
+    }
+    p += sessionIDLen;
+    p = SSLEncodeInt(p, 2*(ctx->numValidCipherSpecs), 2);  /* 2 byte long vector length */
+    for (i = 0; i<ctx->numValidCipherSpecs; ++i)
+        p = SSLEncodeInt(p, ctx->validCipherSpecs[i].cipherSpec, 2);
+    *p++ = 1;                               /* 1 byte long vector */
+    *p++ = 0;                               /* null compression */
+    
+    CASSERT(p == clientHello->contents.data + clientHello->contents.length);
+    
+    if ((err = SSLInitMessageHashes(ctx)) != 0)
+        return err;
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSLProcessClientHello(SSLBuffer message, SSLContext *ctx)
+{   SSLErr              err;
+    SSLProtocolVersion  clientVersion;
+    UInt16              cipherListLen, cipherCount, desiredSpec, cipherSpec;
+    UInt8               sessionIDLen, compressionCount;
+    UInt8               *progress;
+    int                 i;
+    
+    if (message.length < 41) {
+    	errorLog0("SSLProcessClientHello: msg len error 1\n");
+        return SSLProtocolErr;
+    }
+    progress = message.data;
+    clientVersion = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
+    progress += 2;
+    if (clientVersion < SSL_Version_3_0) {
+        #if LOG_NEGOTIATE
+        dprintf1("===SSL3 server: clientVersion %s rejected\n", clientVersion);
+        #endif
+        return SSLUnsupportedErr;
+    }
+    ctx->negProtocolVersion = SSL_Version_3_0;
+    #if LOG_NEGOTIATE
+    dprintf0("===SSL3 server: negVersion is 3_0\n");
+    #endif
+    
+    memcpy(ctx->clientRandom, progress, 32);
+    progress += 32;
+    sessionIDLen = *(progress++);
+    if (message.length < 41 + sessionIDLen) {
+    	errorLog0("SSLProcessClientHello: msg len error 2\n");
+        return SSLProtocolErr;
+    }
+    if (sessionIDLen > 0 && ctx->peerID.data != 0)
+    {   /* Don't die on error; just treat it as an uncacheable session */
+        err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx);
+        if (err == 0)
+            memcpy(ctx->sessionID.data, progress, sessionIDLen);
+    }
+    progress += sessionIDLen;
+    
+    cipherListLen = (UInt16)SSLDecodeInt(progress, 2);  /* Count of cipherSpecs, must be even & >= 2 */
+    progress += 2;
+    if ((cipherListLen & 1) || cipherListLen < 2 || message.length < 39 + sessionIDLen + cipherListLen) {
+    	errorLog0("SSLProcessClientHello: msg len error 3\n");
+        return SSLProtocolErr;
+    }
+    cipherCount = cipherListLen/2;
+    cipherSpec = 0xFFFF;        /* No match marker */
+    while (cipherSpec == 0xFFFF && cipherCount--)
+    {   desiredSpec = (UInt16)SSLDecodeInt(progress, 2);
+        progress += 2;
+        for (i = 0; i <ctx->numValidCipherSpecs; i++)
+        {   if (ctx->validCipherSpecs[i].cipherSpec == desiredSpec)
+            {   cipherSpec = desiredSpec;
+                break;
+            }
+        }
+    }
+    
+    if (cipherSpec == 0xFFFF)
+        return SSLNegotiationErr;
+    progress += 2 * cipherCount;    /* Advance past unchecked cipherCounts */
+    ctx->selectedCipher = cipherSpec;
+    if ((err = FindCipherSpec(ctx)) != 0) {
+        return err;
+    }
+    #if	LOG_NEGOTIATE
+    dprintf1("ssl3 server: selecting cipherKind 0x%x\n", (UInt32)ctx->selectedCipher);
+    #endif
+    
+    compressionCount = *(progress++);
+/* message.length restriction relaxed to allow too-long messages for future expansion
+    following recommendation of TLS meeting 5/29/96 */
+    if (compressionCount < 1 || message.length < 38 + sessionIDLen + cipherListLen + compressionCount) {
+    	errorLog0("SSLProcessClientHello: msg len error 4\n");
+        return SSLProtocolErr;
+    }
+    /* Ignore list; we're doing null */
+    
+    if ((err = SSLInitMessageHashes(ctx)) != 0)
+        return err;
+    
+    return SSLNoErr;
+}
+
+static SSLErr
+SSLEncodeRandom(unsigned char *p, SSLContext *ctx)
+{   SSLBuffer   randomData;
+    SSLErr      err;
+    UInt32      time;
+    
+    #ifdef	_APPLE_CDSA_
+    if ((err = sslTime(&time)) != 0)
+    #else
+    if ((err = ctx->sysCtx.time(&time, ctx->sysCtx.timeRef)) != 0)
+    #endif
+        return err;
+    SSLEncodeInt(p, time, 4);
+    randomData.data = p+4;
+    randomData.length = 28;
+    #ifdef	_APPLE_CDSA_
+   	if((err = sslRand(ctx, &randomData)) != 0)
+    #else
+    if ((err = ctx->sysCtx.random(randomData, ctx->sysCtx.randomRef)) != 0)
+    #endif
+        return err;
+    return SSLNoErr;
+}
+
+SSLErr
+SSLInitMessageHashes(SSLContext *ctx)
+{   SSLErr          err;
+    if ((err = SSLFreeBuffer(&ctx->shaState, &ctx->sysCtx)) != 0)
+        return err;
+    if ((err = SSLFreeBuffer(&ctx->md5State, &ctx->sysCtx)) != 0)
+        return err;
+    if ((err = ReadyHash(&SSLHashSHA1, &ctx->shaState, ctx)) != 0)
+        return err;
+    if ((err = ReadyHash(&SSLHashMD5, &ctx->md5State, ctx)) != 0)
+        return err;
+    return SSLNoErr;
+}
diff --git a/SecureTransport/hdskkeys.c b/SecureTransport/hdskkeys.c
new file mode 100644
index 00000000..aa941b69
--- /dev/null
+++ b/SecureTransport/hdskkeys.c
@@ -0,0 +1,545 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		hdskkeys.c
+
+	Contains:	Key calculation and encoding
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: hdskkeys.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: hdskkeys.c   Key calculation and encoding
+
+    Contains code for encoding premaster secrets, generating master
+    secrets from premaster secrets & key data generation from master
+    secrets and following initialization of ciphers.
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef	_APPLE_CDSA_H_
+#include "appleCdsa.h"
+#endif
+
+#ifndef	_DIGESTS_H_
+#include "digests.h"
+#endif
+
+#include <string.h>
+
+static SSLErr SSLGenerateKeyMaterial(SSLBuffer key, SSLContext *ctx);
+
+SSLErr
+SSLEncodeRSAPremasterSecret(SSLContext *ctx)
+{   SSLBuffer           randData;
+    SSLErr              err;
+    
+    if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, 48, &ctx->sysCtx)) != 0)
+        return err;
+    
+    SSLEncodeInt(ctx->preMasterSecret.data, SSL_Version_3_0, 2);
+    randData.data = ctx->preMasterSecret.data+2;
+    randData.length = 46;
+    #ifdef	_APPLE_CDSA_
+    if ((err = sslRand(ctx, &randData)) != 0)
+    #else
+    if ((err = ctx->sysCtx.random(randData, ctx->sysCtx.randomRef)) != 0)
+    #endif
+        return err;
+    
+    DUMP_BUFFER_NAME("premaster secret", ctx->preMasterSecret);
+    
+    return SSLNoErr;
+}
+
+#if	APPLE_DH
+
+SSLErr
+SSLEncodeDHPremasterSecret(SSLContext *ctx)
+{   
+	#if		!APPLE_DH
+	return SSLUnsupportedErr;
+	#else
+	
+	SSLErr              err;
+    int                 rsaResult;
+    SSLRandomCtx        rsaRandom;
+#if RSAREF
+    SSLBuffer           privateValue;
+#endif
+
+/* Given the server's Diffie-Hellman parameters, prepare a public & private value,
+ *  then use the public value provided by the server and our private value to
+ *  generate a shared key (the premaster secret). Save our public value in
+ *  ctx->dhExchangePublic to send to the server so it can calculate the matching
+ *  key on its end
+ */
+    if (ERR(err = ReadyRandom(&rsaRandom, ctx)) != 0)
+        return err;
+    
+#if RSAREF
+    {   privateValue.data = 0;
+        
+        if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, ctx->peerDHParams.primeLen, &ctx->sysCtx)) != 0)
+            goto fail;
+        if (ERR(err = SSLAllocBuffer(&privateValue, ctx->dhExchangePublic.length - 16, &ctx->sysCtx)) != 0)
+            goto fail;
+        
+        if ((rsaResult = R_SetupDHAgreement(ctx->dhExchangePublic.data, privateValue.data,
+                            privateValue.length, &ctx->peerDHParams, &rsaRandom)) != 0)
+        {   err = SSLUnknownErr;
+            goto fail;
+        }
+        
+        if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, ctx->peerDHParams.primeLen, &ctx->sysCtx)) != 0)
+            goto fail;
+        
+        if ((rsaResult = R_ComputeDHAgreedKey (ctx->preMasterSecret.data, ctx->dhPeerPublic.data,
+                            privateValue.data, privateValue.length,  &ctx->peerDHParams)) != 0)
+        {   err = SSLUnknownErr;
+            goto fail;
+        }
+    }
+#elif BSAFE
+    {   unsigned int    outputLen;
+        
+        if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, 128, &ctx->sysCtx)) != 0)
+            goto fail;
+        if ((rsaResult = B_KeyAgreePhase1(ctx->peerDHParams, ctx->dhExchangePublic.data,
+                            &outputLen, 128, rsaRandom, NO_SURR)) != 0)
+        {   err = SSLUnknownErr;
+            goto fail;
+        }
+        ctx->dhExchangePublic.length = outputLen;
+        if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, 128, &ctx->sysCtx)) != 0)
+            goto fail;
+        if ((rsaResult = B_KeyAgreePhase2(ctx->peerDHParams, ctx->preMasterSecret.data,
+                            &outputLen, 128, ctx->dhPeerPublic.data, ctx->dhPeerPublic.length,
+                            NO_SURR)) != 0)
+        {   err = SSLUnknownErr;
+            goto fail;
+        }
+        ctx->preMasterSecret.length = outputLen;
+    }
+ #endif
+    
+    DUMP_BUFFER_NAME("premaster secret", ctx->preMasterSecret);
+    
+    err = SSLNoErr;
+fail:
+#if RSAREF
+    ERR(SSLFreeBuffer(&privateValue, &ctx->sysCtx));
+    R_RandomFinal(&rsaRandom);
+#elif BSAFE
+    B_DestroyAlgorithmObject(&rsaRandom);
+#endif  
+    return err;
+    #endif
+}
+
+#endif	/* APPLE_DH */
+
+SSLErr
+SSLCalculateMasterSecret(SSLContext *ctx)
+{   SSLErr      err;
+    SSLBuffer   shaState, md5State, clientRandom,
+                serverRandom, shaHash, md5Hash, leader;
+    UInt8       *masterProgress, shaHashData[20], leaderData[3];
+    int         i;
+    
+    md5State.data = shaState.data = 0;
+    if ((err = SSLAllocBuffer(&md5State, SSLHashMD5.contextSize, &ctx->sysCtx)) != 0)
+        goto fail;
+    if ((err = SSLAllocBuffer(&shaState, SSLHashSHA1.contextSize, &ctx->sysCtx)) != 0)
+        goto fail;
+    
+    clientRandom.data = ctx->clientRandom;
+    clientRandom.length = 32;
+    serverRandom.data = ctx->serverRandom;
+    serverRandom.length = 32;
+    shaHash.data = shaHashData;
+    shaHash.length = 20;
+    
+    masterProgress = ctx->masterSecret;
+    
+    for (i = 1; i <= 3; i++)
+    {   if ((err = SSLHashMD5.init(md5State)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.init(shaState)) != 0)
+            goto fail;
+        
+        leaderData[0] = leaderData[1] = leaderData[2] = 0x40 + i;   /* 'A', 'B', etc. */
+        leader.data = leaderData;
+        leader.length = i;
+        
+        if ((err = SSLHashSHA1.update(shaState, leader)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.update(shaState, ctx->preMasterSecret)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.update(shaState, clientRandom)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.update(shaState, serverRandom)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.final(shaState, shaHash)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(md5State, ctx->preMasterSecret)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(md5State, shaHash)) != 0)
+            goto fail;
+        md5Hash.data = masterProgress;
+        md5Hash.length = 16;
+        if ((err = SSLHashMD5.final(md5State, md5Hash)) != 0)
+            goto fail;
+        masterProgress += 16;
+    }
+    
+    DUMP_DATA_NAME("master secret",ctx->masterSecret, 48);
+    
+    err = SSLNoErr;
+fail:
+    SSLFreeBuffer(&shaState, &ctx->sysCtx);
+    SSLFreeBuffer(&md5State, &ctx->sysCtx);
+    return err;
+}
+
+SSLErr
+SSLInitPendingCiphers(SSLContext *ctx)
+{   SSLErr          err;
+    SSLBuffer       key, hashCtx;
+    UInt8           *keyDataProgress, *keyPtr, *ivPtr;
+    int             keyDataLen;
+    CipherContext   *serverPending, *clientPending;
+        
+    key.data = hashCtx.data = 0;
+    
+    ctx->readPending.hash = ctx->selectedCipherSpec->macAlgorithm;
+    ctx->writePending.hash = ctx->selectedCipherSpec->macAlgorithm;
+    ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher;
+    ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher;
+    ctx->readPending.sequenceNum.high = ctx->readPending.sequenceNum.low = 0;
+    ctx->writePending.sequenceNum.high = ctx->writePending.sequenceNum.low = 0;
+    
+    keyDataLen = ctx->selectedCipherSpec->macAlgorithm->digestSize +
+                     ctx->selectedCipherSpec->cipher->secretKeySize;
+    if (ctx->selectedCipherSpec->isExportable == NotExportable)
+        keyDataLen += ctx->selectedCipherSpec->cipher->ivSize;
+    keyDataLen *= 2;        /* two of everything */
+    
+    if ((err = SSLAllocBuffer(&key, keyDataLen, &ctx->sysCtx)) != 0)
+        return err;
+    if ((err = SSLGenerateKeyMaterial(key, ctx)) != 0)
+        goto fail;
+    DUMP_BUFFER_NAME("key data",key);
+    
+    if (ctx->protocolSide == SSL_ServerSide)
+    {   serverPending = &ctx->writePending;
+        clientPending = &ctx->readPending;
+    }
+    else
+    {   serverPending = &ctx->readPending;
+        clientPending = &ctx->writePending;
+    }
+    
+    keyDataProgress = key.data;
+    memcpy(clientPending->macSecret, keyDataProgress, ctx->selectedCipherSpec->macAlgorithm->digestSize);
+    DUMP_DATA_NAME("client write mac secret", keyDataProgress, ctx->selectedCipherSpec->macAlgorithm->digestSize);
+    keyDataProgress += ctx->selectedCipherSpec->macAlgorithm->digestSize;
+    memcpy(serverPending->macSecret, keyDataProgress, ctx->selectedCipherSpec->macAlgorithm->digestSize);
+    DUMP_DATA_NAME("server write mac secret", keyDataProgress, ctx->selectedCipherSpec->macAlgorithm->digestSize);
+    keyDataProgress += ctx->selectedCipherSpec->macAlgorithm->digestSize;
+    
+    if (ctx->selectedCipherSpec->isExportable == NotExportable)
+    {   keyPtr = keyDataProgress;
+        keyDataProgress += ctx->selectedCipherSpec->cipher->secretKeySize;
+        /* Skip server write key to get to IV */
+        ivPtr = keyDataProgress + ctx->selectedCipherSpec->cipher->secretKeySize;
+        /* APPLE_CDSA changes to all symmetric cipher routines.....*/
+        if ((err = ctx->selectedCipherSpec->cipher->initialize(keyPtr, ivPtr,
+                                    clientPending, ctx)) != 0)
+            goto fail;
+        DUMP_DATA_NAME("client write key", keyPtr, ctx->selectedCipherSpec->cipher->secretKeySize);
+        DUMP_DATA_NAME("client write iv", ivPtr, ctx->selectedCipherSpec->cipher->ivSize);
+        keyPtr = keyDataProgress;
+        keyDataProgress += ctx->selectedCipherSpec->cipher->secretKeySize;
+        /* Skip client write IV to get to server write IV */
+        ivPtr = keyDataProgress + ctx->selectedCipherSpec->cipher->ivSize;
+        if ((err = ctx->selectedCipherSpec->cipher->initialize(keyPtr, ivPtr,
+                                    serverPending, ctx)) != 0)
+            goto fail;
+        DUMP_DATA_NAME("server write key", keyPtr, ctx->selectedCipherSpec->cipher->secretKeySize);
+        DUMP_DATA_NAME("server write iv", ivPtr, ctx->selectedCipherSpec->cipher->ivSize);
+    }
+    else
+    {   UInt8           exportKey[16], exportIV[16];
+        SSLBuffer       hashOutput, clientWrite, serverWrite, clientRandom,
+                        serverRandom;
+        
+        CASSERT(ctx->selectedCipherSpec->cipher->keySize <= 16);
+        CASSERT(ctx->selectedCipherSpec->cipher->ivSize <= 16);
+        
+        clientWrite.data = keyDataProgress;
+        clientWrite.length = ctx->selectedCipherSpec->cipher->secretKeySize;
+        serverWrite.data = keyDataProgress + clientWrite.length;
+        serverWrite.length = ctx->selectedCipherSpec->cipher->secretKeySize;
+        clientRandom.data = ctx->clientRandom;
+        clientRandom.length = 32;
+        serverRandom.data = ctx->serverRandom;
+        serverRandom.length = 32;
+        
+        if ((err = SSLAllocBuffer(&hashCtx, SSLHashMD5.contextSize, &ctx->sysCtx)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.init(hashCtx)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(hashCtx, clientWrite)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+            goto fail;
+        hashOutput.data = exportKey;
+        hashOutput.length = 16;
+        if ((err = SSLHashMD5.final(hashCtx, hashOutput)) != 0)
+            goto fail;
+        
+        if (ctx->selectedCipherSpec->cipher->ivSize > 0)
+        {   if ((err = SSLHashMD5.init(hashCtx)) != 0)
+                goto fail;
+            if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+                goto fail;
+            if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+                goto fail;
+            hashOutput.data = exportIV;
+            hashOutput.length = 16;
+            if ((err = SSLHashMD5.final(hashCtx, hashOutput)) != 0)
+                goto fail;
+        }
+        if ((err = ctx->selectedCipherSpec->cipher->initialize(exportKey, exportIV,
+                                    clientPending, ctx)) != 0)
+            goto fail;
+        
+        if ((err = SSLHashMD5.init(hashCtx)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(hashCtx, serverWrite)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+            goto fail;
+        hashOutput.data = exportKey;
+        hashOutput.length = 16;
+        if ((err = SSLHashMD5.final(hashCtx, hashOutput)) != 0)
+            goto fail;
+        
+        if (ctx->selectedCipherSpec->cipher->ivSize > 0)
+        {   if ((err = SSLHashMD5.init(hashCtx)) != 0)
+                goto fail;
+            if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+                goto fail;
+            if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+                goto fail;
+            hashOutput.data = exportIV;
+            hashOutput.length = 16;
+            if ((err = SSLHashMD5.final(hashCtx, hashOutput)) != 0)
+                goto fail;
+        }
+        if ((err = ctx->selectedCipherSpec->cipher->initialize(exportKey, exportIV,
+                                    serverPending, ctx)) != 0)
+            goto fail;
+    }
+    
+/* Ciphers are ready for use */
+    ctx->writePending.ready = 1;
+    ctx->readPending.ready = 1;
+    
+/* Ciphers get swapped by sending or receiving a change cipher spec message */
+    
+    err = SSLNoErr;
+fail:
+    SSLFreeBuffer(&key, &ctx->sysCtx);
+    SSLFreeBuffer(&hashCtx, &ctx->sysCtx);
+    return err;
+}
+
+static SSLErr
+SSLGenerateKeyMaterial(SSLBuffer key, SSLContext *ctx)
+{   SSLErr      err;
+    UInt8       leaderData[10];     /* Max of 10 hashes (* 16 bytes/hash = 160 bytes of key) */
+    UInt8       shaHashData[20], md5HashData[16];
+    SSLBuffer   shaContext, md5Context;
+    UInt8       *keyProgress;
+    int         i,j,remaining, satisfied;
+    SSLBuffer   leader, masterSecret, serverRandom, clientRandom, shaHash, md5Hash;
+    
+    CASSERT(key.length <= 16 * sizeof(leaderData));
+    
+    leader.data = leaderData;
+    masterSecret.data = ctx->masterSecret;
+    masterSecret.length = 48;
+    serverRandom.data = ctx->serverRandom;
+    serverRandom.length = 32;
+    clientRandom.data = ctx->clientRandom;
+    clientRandom.length = 32;
+    shaHash.data = shaHashData;
+    shaHash.length = 20;
+    md5Hash.data = md5HashData;
+    md5Hash.length = 20;
+    
+    md5Context.data = 0;
+    shaContext.data = 0;
+    if ((err = ReadyHash(&SSLHashMD5, &md5Context, ctx)) != 0)
+        goto fail;
+    if ((err = ReadyHash(&SSLHashSHA1, &shaContext, ctx)) != 0)
+        goto fail;  
+    
+    keyProgress = key.data;
+    remaining = key.length;
+    
+    for (i = 0; remaining > 0; ++i)
+    {   for (j = 0; j <= i; j++)
+            leaderData[j] = 0x41 + i;   /* 'A', 'BB', 'CCC', etc. */
+        leader.length = i+1;
+        
+        if ((err = SSLHashSHA1.update(shaContext, leader)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.update(shaContext, masterSecret)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.update(shaContext, serverRandom)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.update(shaContext, clientRandom)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.final(shaContext, shaHash)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(md5Context, masterSecret)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.update(md5Context, shaHash)) != 0)
+            goto fail;
+        if ((err = SSLHashMD5.final(md5Context, md5Hash)) != 0)
+            goto fail;
+        
+        satisfied = 16;
+        if (remaining < 16)
+            satisfied = remaining;
+        memcpy(keyProgress, md5HashData, satisfied);
+        remaining -= satisfied;
+        keyProgress += satisfied;
+        
+        if ((err = SSLHashMD5.init(md5Context)) != 0)
+            goto fail;
+        if ((err = SSLHashSHA1.init(shaContext)) != 0)
+            goto fail;
+    }
+    
+    CASSERT(remaining == 0 && keyProgress == (key.data + key.length));
+    err = SSLNoErr;
+fail:
+    SSLFreeBuffer(&md5Context, &ctx->sysCtx);
+    SSLFreeBuffer(&shaContext, &ctx->sysCtx);
+    
+    return err;
+}
+
+#ifndef	_APPLE_CDSA_
+/* I'm not sure what this is for */
+SSLErr
+ReadyRandom(SSLRandomCtx *rsaRandom, SSLContext *ctx)
+{   SSLErr              err;
+    SSLBuffer           randomSeedBuf;
+    UInt8               randomSeed[32];
+    int                 rsaResult;
+#if RSAREF
+    unsigned int        bytesNeeded;
+    
+    if (R_RandomInit(rsaRandom) != 0)
+        return ERR(SSLUnknownErr);
+    if (R_GetRandomBytesNeeded(&bytesNeeded, rsaRandom) != 0)
+        return ERR(SSLUnknownErr);
+    
+    randomSeedBuf.data = randomSeed;
+    randomSeedBuf.length = 32;
+    
+    while (bytesNeeded > 0)
+    {   if (ERR(err = ctx->sysCtx.random(randomSeedBuf, ctx->sysCtx.randomRef)) != 0)
+            return err;
+        if ((rsaResult = R_RandomUpdate(rsaRandom, randomSeed, 32)) != 0)
+            return ERR(SSLUnknownErr);
+        
+        if (bytesNeeded >= 32)
+            bytesNeeded -= 32;
+        else
+            bytesNeeded = 0;
+    }
+#elif BSAFE
+    static B_ALGORITHM_OBJ  random;
+    B_ALGORITHM_METHOD      *chooser[] = { &AM_MD5_RANDOM, 0 };
+    
+    if ((rsaResult = B_CreateAlgorithmObject(rsaRandom)) != 0)
+        return ERR(SSLUnknownErr);
+    if ((rsaResult = B_SetAlgorithmInfo(*rsaRandom, AI_MD5Random, 0)) != 0)
+        return ERR(SSLUnknownErr);
+    if ((rsaResult = B_RandomInit(*rsaRandom, chooser, NO_SURR)) != 0)
+        return ERR(SSLUnknownErr);
+    randomSeedBuf.data = randomSeed;
+    randomSeedBuf.length = 32;
+    if (ERR(err = ctx->sysCtx.random(randomSeedBuf, ctx->sysCtx.randomRef)) != 0)
+        return err;
+    if ((rsaResult = B_RandomUpdate(*rsaRandom, randomSeedBuf.data, randomSeedBuf.length, NO_SURR)) != 0)
+        return ERR(SSLUnknownErr);
+#endif /* RSAREF / BSAFE */
+        
+    return SSLNoErr;
+}
+#endif	/* APPLE_CDSA */
diff --git a/SecureTransport/hdskkyex.c b/SecureTransport/hdskkyex.c
new file mode 100644
index 00000000..495c3913
--- /dev/null
+++ b/SecureTransport/hdskkyex.c
@@ -0,0 +1,1165 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		hdskkyex.c
+
+	Contains:	Support for key exchange and server key exchange
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: hdskkyex.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: hdskkyex.c   Support for key exchange and server key exchange
+
+    Encoding and decoding of key exchange and server key exchange
+    messages in both the Diffie-Hellman and RSA variants; also, includes
+    the necessary crypto library calls to support this negotiation.
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef	_APPLE_CDSA_H_
+#include "appleCdsa.h"
+#endif
+
+#ifndef	_DIGESTS_H_
+#include "digests.h"
+#endif
+
+#include <string.h>
+
+#if	_APPLE_CDSA_
+/*
+ * For this config, just for this file, we'll do this typedef....
+ */
+typedef	CSSM_KEY_PTR	SSLRSAPrivateKey;
+#endif
+
+static SSLErr SSLEncodeRSAServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
+static SSLErr SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx);
+static SSLErr SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx);
+static SSLErr SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
+static SSLErr SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
+#if	APPLE_DH
+static SSLErr SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
+static SSLErr SSLEncodeDHanonKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
+static SSLErr SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
+static SSLErr SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx);
+#endif
+
+SSLErr
+SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
+{   SSLErr      err;
+    
+    switch (ctx->selectedCipherSpec->keyExchangeMethod)
+    {   case SSL_RSA:
+        case SSL_RSA_EXPORT:
+            if (ERR(err = SSLEncodeRSAServerKeyExchange(keyExch, ctx)) != 0)
+                return err;
+            break;
+        #if		APPLE_DH
+        case SSL_DH_anon:
+            if (ERR(err = SSLEncodeDHanonServerKeyExchange(keyExch, ctx)) != 0)
+                return err;
+            break;
+        #endif
+        default:
+            return ERR(SSLUnsupportedErr);
+    }
+    
+    return SSLNoErr;
+}
+
+static SSLErr
+SSLEncodeRSAServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
+{   SSLErr          err;
+    UInt8           *progress;
+    int             length;
+    UInt32	    	outputLen, localKeyModulusLen;
+    UInt8           hashes[36];
+    SSLBuffer       exportKey,clientRandom,serverRandom,hashCtx, hash;
+    
+    exportKey.data = 0;
+    hashCtx.data = 0;
+    
+    #if	_APPLE_CDSA_
+    /* we have a public key here... */
+    CASSERT(ctx->encryptPubKey != NULL);
+    CASSERT(ctx->protocolSide == SSL_ServerSide);
+    
+    if ((err = SSLEncodeRSAKeyParams(&exportKey, &ctx->encryptPubKey, ctx)) != 0)
+    #else
+    if (ERR(err = SSLEncodeRSAKeyParams(&exportKey, &ctx->exportKey, ctx)) != 0)
+    #endif
+        goto fail;
+    
+#if RSAREF
+    localKeyModulusLen = (ctx->localKey.bits + 7)/8;
+#elif BSAFE
+    {   A_RSA_KEY   *keyInfo;
+        int         rsaResult;
+        
+        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->localKey, KI_RSAPublic)) != 0)
+            return SSLUnknownErr;
+        localKeyModulusLen = keyInfo->modulus.len;
+    }
+#elif	_APPLE_CDSA_
+	CASSERT(ctx->signingPubKey != NULL);
+	localKeyModulusLen = sslKeyLengthInBytes(ctx->signingPubKey);
+#else
+#error No Asymmetric crypto specified 
+#endif /* RSAREF / BSAFE */
+    
+    length = exportKey.length + 2 + localKeyModulusLen;     /* RSA ouputs a block as long as the modulus */
+    
+    keyExch->protocolVersion = SSL_Version_3_0;
+    keyExch->contentType = SSL_handshake;
+    if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
+        goto fail;
+    
+    progress = keyExch->contents.data;
+    *progress++ = SSL_server_key_exchange;
+    progress = SSLEncodeInt(progress, length, 3);
+    
+    memcpy(progress, exportKey.data, exportKey.length);
+    progress += exportKey.length;
+    
+    clientRandom.data = ctx->clientRandom;
+    clientRandom.length = 32;
+    serverRandom.data = ctx->serverRandom;
+    serverRandom.length = 32;
+    
+    hash.data = &hashes[0];
+    hash.length = 16;
+    if (ERR(err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashMD5.update(hashCtx, exportKey)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashMD5.final(hashCtx, hash)) != 0)
+        goto fail;
+    if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
+        goto fail;
+    
+    hash.data = &hashes[16];
+    hash.length = 20;
+    if (ERR(err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashSHA1.update(hashCtx, exportKey)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashSHA1.final(hashCtx, hash)) != 0)
+        goto fail;
+    if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
+        goto fail;
+    
+    progress = SSLEncodeInt(progress, localKeyModulusLen, 2);
+#if RSAREF
+    if (RSAPrivateEncrypt(progress, &outputLen, hashes, 36, &ctx->localKey) != 0)   /* Sign the structure */
+        return ERR(SSLUnknownErr);
+#elif BSAFE
+    {   B_ALGORITHM_OBJ     rsa;
+        B_ALGORITHM_METHOD  *chooser[] = { &AM_RSA_ENCRYPT, &AM_RSA_CRT_ENCRYPT, 0 };
+        int                 rsaResult;
+        UInt32        		encryptedOut;
+        
+        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPrivate, 0)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_EncryptInit(rsa, ctx->localKey, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_EncryptUpdate(rsa, progress,
+                    &encryptedOut, localKeyModulusLen, hashes, 36, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen = encryptedOut;
+        if ((rsaResult = B_EncryptFinal(rsa, progress+outputLen,
+                    &encryptedOut, localKeyModulusLen-outputLen, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen += encryptedOut;
+        B_DestroyAlgorithmObject(&rsa);
+    }
+#elif	_APPLE_CDSA_
+	err = sslRsaRawSign(ctx,
+		ctx->signingPrivKey,
+		ctx->signingKeyCsp,
+		hashes,
+		36,
+		progress,
+		length,
+		&outputLen);
+	if(err) {
+		goto fail;
+	}
+#endif /* RSAREF / BSAFE */
+    CASSERT(outputLen == localKeyModulusLen);
+    
+    err = SSLNoErr;
+    
+fail:
+    ERR(SSLFreeBuffer(&hashCtx, &ctx->sysCtx));
+    ERR(SSLFreeBuffer(&exportKey, &ctx->sysCtx));
+    
+    return err;
+}
+
+static SSLErr
+SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx)
+{   SSLErr      err;
+    SSLBuffer   modulus, exponent;
+    UInt8       *progress;
+    
+#if RSAREF
+    keyParams->data = 0;
+    modulus.length = (key->bits + 7) / 8;
+    modulus.data = key->modulus + MAX_RSA_MODULUS_LEN - modulus.length;
+    
+    exponent.length = MAX_RSA_MODULUS_LEN;
+    exponent.data = key->publicExponent;            /* Point at first byte */
+    
+    while (*exponent.data == 0)
+    {   ++exponent.data;
+        --exponent.length;
+    }
+#elif BSAFE
+    {   A_RSA_KEY   *keyInfo;
+        int         rsaResult;
+        
+        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, *key, KI_RSAPublic)) != 0)
+            return SSLUnknownErr;
+        modulus.data = keyInfo->modulus.data;
+        modulus.length = keyInfo->modulus.len;
+        exponent.data = keyInfo->exponent.data;
+        exponent.length = keyInfo->exponent.len;
+    }   
+#elif	_APPLE_CDSA_
+	err = sslGetPubKeyBits(ctx,
+		*key,
+		ctx->encryptKeyCsp,
+		&modulus,
+		&exponent);
+	if(err) {
+		SSLFreeBuffer(&modulus, &ctx->sysCtx);
+		SSLFreeBuffer(&exponent, &ctx->sysCtx);
+		return err;
+	}
+#else
+#error No assymetric crypto specified
+#endif /* RSAREF / BSAFE */
+    
+    if (ERR(err = SSLAllocBuffer(keyParams, modulus.length + exponent.length + 4, &ctx->sysCtx)) != 0)
+        return err;
+    progress = keyParams->data;
+    progress = SSLEncodeInt(progress, modulus.length, 2);
+    memcpy(progress, modulus.data, modulus.length);
+    progress += modulus.length;
+    progress = SSLEncodeInt(progress, exponent.length, 2);
+    memcpy(progress, exponent.data, exponent.length);
+
+#if	_APPLE_CDSA_
+	/* these were mallocd by sslGetPubKeyBits() */
+	SSLFreeBuffer(&modulus, &ctx->sysCtx);
+	SSLFreeBuffer(&exponent, &ctx->sysCtx);
+#endif
+    return SSLNoErr;
+}
+
+#if		APPLE_DH
+static SSLErr
+SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
+{   SSLErr              err;
+    UInt32        		length;
+    UInt8               *progress;
+    SSLRandomCtx        random;
+    int                 rsaErr;
+    
+#if RSAREF
+    length = 6 + ctx->dhAnonParams.primeLen + ctx->dhAnonParams.generatorLen +
+                    ctx->dhExchangePublic.length;
+    
+    keyExch->protocolVersion = SSL_Version_3_0;
+    keyExch->contentType = SSL_handshake;
+    if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
+        return err;
+    
+    progress = keyExch->contents.data;
+    *progress++ = SSL_server_key_exchange;
+    progress = SSLEncodeInt(progress, length, 3);
+    
+    progress = SSLEncodeInt(progress, ctx->dhAnonParams.primeLen, 2);
+    memcpy(progress, ctx->dhAnonParams.prime, ctx->dhAnonParams.primeLen);
+    progress += ctx->dhAnonParams.primeLen;
+    
+    progress = SSLEncodeInt(progress, ctx->dhAnonParams.generatorLen, 2);
+    memcpy(progress, ctx->dhAnonParams.generator, ctx->dhAnonParams.generatorLen);
+    progress += ctx->dhAnonParams.generatorLen;
+    
+    if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, ctx->peerDHParams.primeLen, &ctx->sysCtx)) != 0)
+        return err;
+    if (ERR(err = SSLAllocBuffer(&ctx->dhPrivate, ctx->dhExchangePublic.length - 16, &ctx->sysCtx)) != 0)
+        return err;
+
+    if (ERR(err = ReadyRandom(&random, ctx)) != 0)
+        return err;
+    
+    if ((rsaErr = R_SetupDHAgreement(ctx->dhExchangePublic.data, ctx->dhPrivate.data,
+                    ctx->dhPrivate.length, &ctx->dhAnonParams, &random)) != 0)
+    {   err = SSLUnknownErr;
+        return err;
+    }
+    
+    progress = SSLEncodeInt(progress, ctx->dhExchangePublic.length, 2);
+    memcpy(progress, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
+    progress += ctx->dhExchangePublic.length;
+    
+#elif BSAFE
+    {   A_DH_KEY_AGREE_PARAMS   *params;
+        unsigned int            outputLen;
+        
+        if ((rsaErr = B_GetAlgorithmInfo((POINTER*)&params, ctx->dhAnonParams, AI_DHKeyAgree)) != 0)
+            return SSLUnknownErr;
+        if (ERR(err = ReadyRandom(&random, ctx)) != 0)
+            return err;
+        if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, 128, &ctx->sysCtx)) != 0)
+            return err;
+        if ((rsaErr = B_KeyAgreePhase1(ctx->dhAnonParams, ctx->dhExchangePublic.data,
+                            &outputLen, 128, random, NO_SURR)) != 0)
+        {   err = SSLUnknownErr;
+            return err;
+        }
+        ctx->dhExchangePublic.length = outputLen;
+        
+        length = 6 + params->prime.len + params->base.len + ctx->dhExchangePublic.length;
+        
+        keyExch->protocolVersion = SSL_Version_3_0;
+        keyExch->contentType = SSL_handshake;
+        if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
+            return err;
+        
+        progress = keyExch->contents.data;
+        *progress++ = SSL_server_key_exchange;
+        progress = SSLEncodeInt(progress, length, 3);
+        
+        progress = SSLEncodeInt(progress, params->prime.len, 2);
+        memcpy(progress, params->prime.data, params->prime.len);
+        progress += params->prime.len;
+        
+        progress = SSLEncodeInt(progress, params->base.len, 2);
+        memcpy(progress, params->base.data, params->base.len);
+        progress += params->base.len;
+        
+        progress = SSLEncodeInt(progress, ctx->dhExchangePublic.length, 2);
+        memcpy(progress, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
+        progress += ctx->dhExchangePublic.length;
+    }
+#endif /* RSAREF / BSAFE */
+        
+    ASSERT(progress == keyExch->contents.data + keyExch->contents.length);
+    
+    return SSLNoErr;
+}
+
+#endif	/* APPLE_DH */
+
+SSLErr
+SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
+{   SSLErr      err;
+    
+    switch (ctx->selectedCipherSpec->keyExchangeMethod)
+    {   case SSL_RSA:
+        case SSL_RSA_EXPORT:
+            if (ERR(err = SSLProcessRSAServerKeyExchange(message, ctx)) != 0)
+                return err;
+            break;
+        #if		APPLE_DH
+        case SSL_DH_anon:
+            if (ERR(err = SSLProcessDHanonServerKeyExchange(message, ctx)) != 0)
+                return err;
+            break;
+        #endif
+        default:
+            return ERR(SSLUnsupportedErr);
+    }
+    
+    return SSLNoErr;
+}
+
+static SSLErr
+SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx)
+{   
+	SSLErr          err;
+    SSLBuffer       tempPubKey, hashOut, hashCtx, clientRandom, serverRandom;
+    UInt16          modulusLen, exponentLen, signatureLen;
+    UInt8           *progress, *modulus, *exponent, *signature;
+	#if	_APPLE_CDSA_
+    UInt8           hash[36];
+    #else
+    UInt8           hash[20];
+    UInt32    		outputLen;
+    #endif	/* _APPLE_CDSA_ */
+    SSLBuffer       signedHashes;
+    
+    signedHashes.data = 0;
+    hashCtx.data = 0;
+    
+    if (message.length < 2) {
+    	errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
+        return ERR(SSLProtocolErr);
+    }
+    progress = message.data;
+    modulusLen = SSLDecodeInt(progress, 2);
+    modulus = progress + 2;
+    progress += 2+modulusLen;
+    if (message.length < 4 + modulusLen) {
+    	errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
+        return ERR(SSLProtocolErr);
+    }
+    exponentLen = SSLDecodeInt(progress, 2);
+    exponent = progress + 2;
+    progress += 2+exponentLen;
+    if (message.length < 6 + modulusLen + exponentLen) {
+    	errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
+        return ERR(SSLProtocolErr);
+    }
+    signatureLen = SSLDecodeInt(progress, 2);
+    signature = progress + 2;
+    if (message.length != 6 + modulusLen + exponentLen + signatureLen) {
+    	errorLog0("SSLProcessRSAServerKeyExchange: msg len error 3\n");
+        return ERR(SSLProtocolErr);
+    }
+    
+#if RSAREF
+    {   /* Allocate room for the signed hashes; RSA can encrypt data
+            as long as the modulus */
+        if (ERR(err = SSLAllocBuffer(&signedHashes, (ctx->peerKey.bits + 7)/8, &ctx->sysCtx)) != 0)
+            return err;
+
+        if ((RSAPublicDecrypt(signedHashes.data, &outputLen, signature, signatureLen,
+                            &ctx->peerKey)) != 0)
+        {   ERR(err = SSLUnknownErr);
+            goto fail;
+        }
+    }
+#elif BSAFE
+    {   B_ALGORITHM_OBJ     rsa;
+        B_ALGORITHM_METHOD  *chooser[] = { &AM_MD2, &AM_MD5, &AM_RSA_DECRYPT, 0 };
+        int                 rsaResult;
+        unsigned int        decryptLen;
+        
+        /* Allocate room for the signed hashes; BSAFE makes sure we don't decode too much data */
+        if (ERR(err = SSLAllocBuffer(&signedHashes, 36, &ctx->sysCtx)) != 0)
+            return err; 
+    
+        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_DecryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_DecryptUpdate(rsa, signedHashes.data, &decryptLen, 36,
+                    signature, signatureLen, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen = decryptLen;
+        if ((rsaResult = B_DecryptFinal(rsa, signedHashes.data+outputLen,
+                    &decryptLen, 36-outputLen, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen += decryptLen;
+        B_DestroyAlgorithmObject(&rsa);
+    }
+#elif	_APPLE_CDSA_
+	
+	/* not yet - calculate the hashes and then do a sig verify */
+		
+#else
+#error No Asymmetric crypto module
+#endif
+
+	#ifndef	_APPLE_CDSA_
+    if (outputLen != 36)
+    {   ERR(err = SSLProtocolErr);
+        goto fail;
+    }
+    #endif
+    
+    clientRandom.data = ctx->clientRandom;
+    clientRandom.length = 32;
+    serverRandom.data = ctx->serverRandom;
+    serverRandom.length = 32;
+    tempPubKey.data = message.data;
+    tempPubKey.length = modulusLen + exponentLen + 4;
+    hashOut.data = hash;
+    
+    hashOut.length = 16;
+    if (ERR(err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashMD5.update(hashCtx, tempPubKey)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashMD5.final(hashCtx, hashOut)) != 0)
+        goto fail;
+        
+    #if		_APPLE_CDSA_
+    /* 
+     * SHA hash goes right after the MD5 hash 
+     */
+    hashOut.data = hash + 16; 
+    #else
+    if ((memcmp(hash, signedHashes.data, 16)) != 0)
+    {   ERR(err = SSLProtocolErr);
+        goto fail;
+    }
+    #endif	/* _APPLE_CDSA_ */
+
+    hashOut.length = 20;
+    if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
+        goto fail;
+    
+    if (ERR(err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashSHA1.update(hashCtx, tempPubKey)) != 0)
+        goto fail;
+    if (ERR(err = SSLHashSHA1.final(hashCtx, hashOut)) != 0)
+        goto fail;
+
+	#if	_APPLE_CDSA_
+
+	err = sslRsaRawVerify(ctx,
+		ctx->peerPubKey,
+		ctx->peerPubKeyCsp,
+		hash,					/* plaintext */
+		36,						/* plaintext length */
+		signature,
+		signatureLen);
+	if(err) {
+		errorLog1("SSLProcessRSAServerKeyExchange: sslRsaRawVerify returned %d\n",
+			err);
+		goto fail;
+	}
+	
+	#else	/* old BSAFE/RSAREF */
+	
+    if ((memcmp(hash, signedHashes.data + 16, 20)) != 0)
+    {   ERR(err = SSLProtocolErr);
+        goto fail;
+    }
+
+	#endif
+    
+/* Signature matches; now replace server key with new key */
+#if RSAREF
+    memset(&ctx->peerKey, 0, sizeof(R_RSA_PUBLIC_KEY));
+    memcpy(ctx->peerKey.modulus + (MAX_RSA_MODULUS_LEN - modulusLen),
+            modulus, modulusLen);
+    memcpy(ctx->peerKey.exponent + (MAX_RSA_MODULUS_LEN - exponentLen),
+            exponent, exponentLen);
+    
+/* Adjust bit length for leading zeros in value; assume no more than 8 leading zero bits */
+    {   unsigned int    bitAdjust;
+        UInt8           c;
+        
+        c = modulus[0];
+        
+        bitAdjust = 8;
+        while (c != 0)
+        {   --bitAdjust;
+            c >>= 1;
+        }
+        ctx->peerKey.bits = modulusLen * 8 - bitAdjust;
+    }
+    err = SSLNoErr;
+#elif BSAFE
+    {   A_RSA_KEY   pubKeyInfo;
+        int         rsaErr;
+        
+        pubKeyInfo.modulus.data = modulus;
+        pubKeyInfo.modulus.len = modulusLen;
+        pubKeyInfo.exponent.data = exponent;
+        pubKeyInfo.exponent.len = exponentLen;
+        
+        if ((rsaErr = B_CreateKeyObject(&ctx->peerKey)) != 0)
+            return SSLUnknownErr;
+        if ((rsaErr = B_SetKeyInfo(ctx->peerKey, KI_RSAPublic, (POINTER)&pubKeyInfo)) != 0)
+            return SSLUnknownErr;
+    }
+    err = SSLNoErr;
+#elif _APPLE_CDSA_
+	{
+		SSLBuffer modBuf;
+		SSLBuffer expBuf;
+		
+		/* first free existing peerKey */
+		sslFreeKey(ctx->peerPubKeyCsp, 
+			&ctx->peerPubKey,
+			NULL);					/* no KCItem */
+			
+		/* and cook up a new one from raw bits */
+		modBuf.data = modulus;
+		modBuf.length = modulusLen;
+		expBuf.data = exponent;
+		expBuf.length = exponentLen;
+		err = sslGetPubKeyFromBits(ctx,
+			&modBuf,
+			&expBuf,
+			&ctx->peerPubKey,
+			&ctx->peerPubKeyCsp);
+	}
+#else
+#error No Assymmetric crypto module
+#endif /* RSAREF / BSAFE */
+fail:
+    ERR(SSLFreeBuffer(&signedHashes, &ctx->sysCtx));
+    ERR(SSLFreeBuffer(&hashCtx, &ctx->sysCtx));
+    return err;
+}
+
+#if		APPLE_DH
+static SSLErr
+SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
+{   SSLErr          err;
+    UInt8           *progress;
+    unsigned int    totalLength;
+    
+    if (message.length < 6) {
+    	errorLog1("SSLProcessDHanonServerKeyExchange error: msg len %d\n",
+    		message.length);
+        return ERR(SSLProtocolErr);
+    }
+    progress = message.data;
+    totalLength = 0;
+    
+#if RSAREF
+    {   SSLBuffer       alloc;
+        UInt8           *prime, *generator, *publicVal;
+        
+        ctx->peerDHParams.primeLen = SSLDecodeInt(progress, 2);
+        progress += 2;
+        prime = progress;
+        progress += ctx->peerDHParams.primeLen;
+        totalLength += ctx->peerDHParams.primeLen;
+        if (message.length < 6 + totalLength)
+            return ERR(SSLProtocolErr);
+        
+        ctx->peerDHParams.generatorLen = SSLDecodeInt(progress, 2);
+        progress += 2;
+        generator = progress;
+        progress += ctx->peerDHParams.generatorLen;
+        totalLength += ctx->peerDHParams.generatorLen;
+        if (message.length < 6 + totalLength)
+            return ERR(SSLProtocolErr);
+            
+        ctx->dhPeerPublic.length = SSLDecodeInt(progress, 2);
+        progress += 2;
+        publicVal = progress;
+        progress += ctx->dhPeerPublic.length;
+        totalLength += ctx->dhPeerPublic.length;
+        if (message.length != 6 + totalLength)
+            return ERR(SSLProtocolErr);
+        
+        ASSERT(progress == message.data + message.length);
+        
+        if (ERR(err = SSLAllocBuffer(&alloc, ctx->peerDHParams.primeLen +
+                                    ctx->peerDHParams.generatorLen, &ctx->sysCtx)) != 0)
+            return err;
+        
+        ctx->peerDHParams.prime = alloc.data;
+        memcpy(ctx->peerDHParams.prime, prime, ctx->peerDHParams.primeLen);
+        ctx->peerDHParams.generator = alloc.data + ctx->peerDHParams.primeLen;
+        memcpy(ctx->peerDHParams.generator, generator, ctx->peerDHParams.generatorLen);
+        
+        if (ERR(err = SSLAllocBuffer(&ctx->dhPeerPublic,
+                                ctx->dhPeerPublic.length, &ctx->sysCtx)) != 0)
+            return err;
+        
+        memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
+    }
+#elif BSAFE
+    {   int                     rsaErr;
+        unsigned char           *publicVal;
+        A_DH_KEY_AGREE_PARAMS   params;
+        B_ALGORITHM_METHOD      *chooser[] = { &AM_DH_KEY_AGREE, 0 };
+
+        params.prime.len = SSLDecodeInt(progress, 2);
+        progress += 2;
+        params.prime.data = progress;
+        progress += params.prime.len;
+        totalLength += params.prime.len;
+        if (message.length < 6 + totalLength)
+            return ERR(SSLProtocolErr);
+        
+        params.base.len = SSLDecodeInt(progress, 2);
+        progress += 2;
+        params.base.data = progress;
+        progress += params.base.len;
+        totalLength += params.base.len;
+        if (message.length < 6 + totalLength)
+            return ERR(SSLProtocolErr);
+        
+        ctx->dhPeerPublic.length = SSLDecodeInt(progress, 2);
+        if (ERR(err = SSLAllocBuffer(&ctx->dhPeerPublic, ctx->dhPeerPublic.length, &ctx->sysCtx)) != 0)
+            return err;
+        
+        progress += 2;
+        publicVal = progress;
+        progress += ctx->dhPeerPublic.length;
+        totalLength += ctx->dhPeerPublic.length;
+        memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
+        if (message.length != 6 + totalLength)
+            return ERR(SSLProtocolErr);
+        
+        params.exponentBits = 8 * ctx->dhPeerPublic.length - 1;
+        
+        if ((rsaErr = B_CreateAlgorithmObject(&ctx->peerDHParams)) != 0)
+            return SSLUnknownErr;
+        if ((rsaErr = B_SetAlgorithmInfo(ctx->peerDHParams, AI_DHKeyAgree, (POINTER)&params)) != 0)
+            return SSLUnknownErr;
+        if ((rsaErr = B_KeyAgreeInit(ctx->peerDHParams, (B_KEY_OBJ) 0, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+    }
+#endif
+        
+    return SSLNoErr;
+}
+
+#endif
+
+SSLErr
+SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
+{   SSLErr      err;
+    
+    switch (ctx->selectedCipherSpec->keyExchangeMethod)
+    {   case SSL_RSA:
+        case SSL_RSA_EXPORT:
+            if (ERR(err = SSLDecodeRSAKeyExchange(keyExchange, ctx)) != 0)
+                return err;
+            break;
+		#if		APPLE_DH
+        case SSL_DH_anon:
+            if (ERR(err = SSLDecodeDHanonKeyExchange(keyExchange, ctx)) != 0)
+                return err;
+            break;
+        #endif
+        default:
+            return ERR(SSLUnsupportedErr);
+    }
+    
+    return SSLNoErr;
+}
+
+static SSLErr
+SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
+{   SSLErr              err;
+    SSLBuffer           result;
+    UInt32        		outputLen, localKeyModulusLen;
+    SSLRSAPrivateKey    *key;
+    SSLProtocolVersion  version;
+    Boolean				useEncryptKey = false;
+    
+    #if	_APPLE_CDSA_
+    
+	    /* different key names, also need CSP handle */
+	    CSSM_CSP_HANDLE		cspHand;
+	    
+	    CASSERT(ctx->protocolSide == SSL_ServerSide);
+	    
+	    /* 
+	     * FIXME - The original SSLRef looked at 
+	     * ctx->selectedCipherSpec->keyExchangeMethod to decide which 
+	     * key to use (exportKey or localKey). I really don't think we 
+	     * want to use that - it's constant. We need to look at 
+	     * whether the app specified encrypting certs, right?
+	     */
+	    #if		SSL_SERVER_KEYEXCH_HACK
+	    	/* 
+	    	 * the way we work with Netscape.
+	    	 * FIXME - maybe we should *require* an encryptPrivKey in this
+	    	 * situation?
+	    	 */
+	    	if((ctx->selectedCipherSpec->keyExchangeMethod == SSL_RSA_EXPORT) &&
+	    	   (ctx->encryptPrivKey != NULL)) {
+	    	   	useEncryptKey = true;
+	    	}
+	    	
+	    #else	/* !SSL_SERVER_KEYEXCH_HACK */
+	    	/* The "correct" way, I think, which doesn't work with Netscape */
+	    	if (ctx->encryptPrivKey) {
+	    		useEncryptKey = true;
+	    	}
+	    #endif	/* SSL_SERVER_KEYEXCH_HACK */
+	    if (useEncryptKey) {
+	        key = &ctx->encryptPrivKey;
+	        cspHand = ctx->encryptKeyCsp;
+	    } 
+	    else {
+	        key = &ctx->signingPrivKey;
+	        cspHand = ctx->signingKeyCsp;
+	    }
+    #else	/* original SSLRef3 */
+	    if (ctx->selectedCipherSpec->keyExchangeMethod == SSL_RSA_EXPORT)
+	        key = &ctx->exportKey;
+	    else
+	        key = &ctx->localKey;
+    #endif	/* _APPLE_CDSA_ */
+    result.data = 0;
+    
+#if RSAREF
+    localKeyModulusLen = (key->bits + 7)/8;
+#elif BSAFE
+    {   A_RSA_KEY   *keyInfo;
+        int         rsaResult;
+        
+        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, *key, KI_RSAPublic)) != 0)
+            return SSLUnknownErr;
+        localKeyModulusLen = keyInfo->modulus.len;
+    }
+#elif	_APPLE_CDSA_
+	localKeyModulusLen = sslKeyLengthInBytes(*key);
+#else
+#error No assymetric crypto module
+#endif /* RSAREF / BSAFE */
+    
+    if (keyExchange.length != localKeyModulusLen) {
+    	errorLog0("SSLDecodeRSAKeyExchange: length error\n");
+        return ERR(SSLProtocolErr);
+	}
+	
+#if RSAREF
+    if (ERR(err = SSLAllocBuffer(&result, localKeyModulusLen, &ctx->sysCtx)) != 0)
+        return err;
+    if ((RSAPrivateDecrypt(result.data, &outputLen, keyExchange.data, keyExchange.length, key)) != 0)
+    {   ERR(err = SSLUnknownErr);
+        goto fail;
+    }
+#elif BSAFE
+    {   B_ALGORITHM_OBJ     rsa;
+        B_ALGORITHM_METHOD  *chooser[] = { &AM_RSA_DECRYPT, &AM_RSA_CRT_DECRYPT, 0 };
+        int                 rsaResult;
+        unsigned int        decryptLen;
+        
+        /* Allocate room for the premaster secret; BSAFE makes sure we don't decode too much data */
+        if (ERR(err = SSLAllocBuffer(&result, 48, &ctx->sysCtx)) != 0)
+            return err; 
+    
+        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPrivate, 0)) != 0)
+            return SSLUnknownErr;
+        #ifdef	macintosh
+        /* 
+         * I think this is an SSLRef bug - we need to use the right key here,
+         * as the RSAREF case above does!
+         */
+         if ((rsaResult = B_DecryptInit(rsa, *key, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+       #else	/* the SSLRef way */
+        if ((rsaResult = B_DecryptInit(rsa, ctx->localKey, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        #endif	/* mac/SSLREF */
+        if ((rsaResult = B_DecryptUpdate(rsa, result.data, &decryptLen, 48,
+                    keyExchange.data, keyExchange.length, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen = decryptLen;
+        if ((rsaResult = B_DecryptFinal(rsa, result.data+outputLen,
+                    &decryptLen, 48-outputLen, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen += decryptLen;
+        B_DestroyAlgorithmObject(&rsa);
+    }
+#elif	_APPLE_CDSA_
+	err = sslRsaDecrypt(ctx,
+		*key,
+		cspHand,
+		keyExchange.data, 
+		keyExchange.length,
+		result.data,
+		48,
+		&outputLen);
+	if(err) {
+		goto fail;
+	}
+#endif
+    
+    if (outputLen != 48)
+    {   
+		errorLog0("SSLDecodeRSAKeyExchange: outputLen error\n");
+    	ERR(err = SSLProtocolErr);
+        goto fail;
+    }
+    result.length = outputLen;
+    
+    version = (SSLProtocolVersion)SSLDecodeInt(result.data, 2);
+/* Modify this check to check against our maximum version with protocol revisions */
+    if (version > ctx->negProtocolVersion && version < SSL_Version_3_0) {
+		errorLog0("SSLDecodeRSAKeyExchange: version error\n");
+    	ERR(err = SSLProtocolErr);
+        goto fail;
+    }
+    if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, 48, &ctx->sysCtx)) != 0)
+        goto fail;
+    memcpy(ctx->preMasterSecret.data, result.data, 48);
+    
+    err = SSLNoErr;
+fail:
+    ERR(SSLFreeBuffer(&result, &ctx->sysCtx));
+    return err;
+}
+
+#if		APPLE_DH
+static SSLErr
+SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
+{   SSLErr          err;
+    unsigned int    publicLen;
+    int             rsaResult;
+
+    publicLen = SSLDecodeInt(keyExchange.data, 2);
+    
+#if RSAREF
+    if (keyExchange.length != publicLen + 2 ||
+        publicLen != ctx->dhAnonParams.primeLen)
+        return ERR(SSLProtocolErr);
+    
+    if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, ctx->dhAnonParams.primeLen, &ctx->sysCtx)) != 0)
+        return err;
+    
+    if ((rsaResult = R_ComputeDHAgreedKey (ctx->preMasterSecret.data, ctx->dhPeerPublic.data,
+                        ctx->dhPrivate.data, ctx->dhPrivate.length,  &ctx->dhAnonParams)) != 0)
+    {   err = SSLUnknownErr;
+        return err;
+    }
+    
+#elif BSAFE
+    {   unsigned int    amount;
+        if (keyExchange.length != publicLen + 2)
+            return ERR(SSLProtocolErr);
+    
+        if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, 128, &ctx->sysCtx)) != 0)
+            return err;
+        
+        if ((rsaResult = B_KeyAgreePhase2(ctx->dhAnonParams, ctx->preMasterSecret.data,
+            &amount, 128, keyExchange.data+2, publicLen, NO_SURR)) != 0)
+            return err;
+        
+        ctx->preMasterSecret.length = amount;
+    }   
+#endif
+        
+    return SSLNoErr;
+}
+#endif	/* APPLE_DH */
+
+SSLErr
+SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
+{   SSLErr      err;
+    
+    CASSERT(ctx->protocolSide == SSL_ClientSide);
+    
+    switch (ctx->selectedCipherSpec->keyExchangeMethod)
+    {   case SSL_RSA:
+        case SSL_RSA_EXPORT:
+            if (ERR(err = SSLEncodeRSAKeyExchange(keyExchange, ctx)) != 0)
+                return err;
+            break;
+        #if		APPLE_DH
+        case SSL_DH_anon:
+            if (ERR(err = SSLEncodeDHanonKeyExchange(keyExchange, ctx)) != 0)
+                return err;
+            break;
+        #endif
+        default:
+            return ERR(SSLUnsupportedErr);
+    }
+    
+    return SSLNoErr;
+}
+
+static SSLErr
+SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
+{   SSLErr              err;
+    UInt32        		outputLen, peerKeyModulusLen;
+    #if	!_APPLE_CDSA_
+    SSLRandomCtx        rsaRandom;
+    int                 rsaResult;
+    #endif
+    
+    if (ERR(err = SSLEncodeRSAPremasterSecret(ctx)) != 0)
+        return err;
+    
+    #if	!_APPLE_CDSA_
+    if (ERR(err = ReadyRandom(&rsaRandom, ctx)) != 0)
+        return err;
+    #endif
+    
+    keyExchange->contentType = SSL_handshake;
+    keyExchange->protocolVersion = SSL_Version_3_0;
+        
+#if RSAREF
+    peerKeyModulusLen = (ctx->peerKey.bits + 7)/8;
+#elif BSAFE
+    {   A_RSA_KEY   *keyInfo;
+        
+        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->peerKey, KI_RSAPublic)) != 0)
+            return SSLUnknownErr;
+        peerKeyModulusLen = keyInfo->modulus.len;
+    }
+#elif	_APPLE_CDSA_
+	peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
+#else
+#error No Assymetric Crypto
+#endif /* RSAREF / BSAFE */
+    if (ERR(err = SSLAllocBuffer(&keyExchange->contents,peerKeyModulusLen + 4,&ctx->sysCtx)) != 0)
+    {   
+#if RSAREF
+        R_RandomFinal(&rsaRandom);
+#elif BSAFE
+        B_DestroyAlgorithmObject(&rsaRandom);
+#endif
+        return err;
+    }
+    keyExchange->contents.data[0] = SSL_client_key_exchange;
+    SSLEncodeInt(keyExchange->contents.data + 1, peerKeyModulusLen, 3);
+#if RSAREF
+    if ((rsaResult = RSAPublicEncrypt(keyExchange->contents.data+4, &outputLen,
+                                ctx->preMasterSecret.data, 48,
+                                &ctx->peerKey,&rsaRandom)) != 0)
+    {   R_RandomFinal(&rsaRandom);
+        return ERR(SSLUnknownErr);
+    }
+    
+    R_RandomFinal(&rsaRandom);
+
+#elif BSAFE
+    {   B_ALGORITHM_OBJ     rsa;
+        B_ALGORITHM_METHOD  *chooser[] = { &AM_RSA_ENCRYPT, 0 };
+        int                 rsaResult;
+        unsigned int        encryptedOut;
+        
+        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_EncryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_EncryptUpdate(rsa, keyExchange->contents.data+4,
+                    &encryptedOut, peerKeyModulusLen, ctx->preMasterSecret.data, 48, rsaRandom, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen = encryptedOut;
+        if ((rsaResult = B_EncryptFinal(rsa, keyExchange->contents.data+4+outputLen,
+                    &encryptedOut, peerKeyModulusLen-outputLen, rsaRandom, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen += encryptedOut;
+        B_DestroyAlgorithmObject(&rsa);
+    }
+    
+    B_DestroyAlgorithmObject(&rsaRandom);
+#elif _APPLE_CDSA_
+	err = sslRsaEncrypt(ctx,
+		ctx->peerPubKey,
+		/* FIXME - maybe this should be ctx->cspHand */
+		ctx->peerPubKeyCsp,
+		ctx->preMasterSecret.data, 
+		48,
+		keyExchange->contents.data+4,
+		peerKeyModulusLen,
+		&outputLen);
+	if(err) {
+		return err;
+	}
+#endif  
+    
+    CASSERT(outputLen + 4 == keyExchange->contents.length);
+    
+    return SSLNoErr;
+}
+
+#if		APPLE_DH
+static SSLErr
+SSLEncodeDHanonKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
+{   SSLErr              err;
+    unsigned int        outputLen;
+    
+    if (ERR(err = SSLEncodeDHPremasterSecret(ctx)) != 0)
+        return err;
+    
+    outputLen = ctx->dhExchangePublic.length + 2;
+    
+    keyExchange->contentType = SSL_handshake;
+    keyExchange->protocolVersion = SSL_Version_3_0;
+    
+    if (ERR(err = SSLAllocBuffer(&keyExchange->contents,outputLen + 4,&ctx->sysCtx)) != 0)
+        return err;
+    
+    keyExchange->contents.data[0] = SSL_client_key_exchange;
+    SSLEncodeInt(keyExchange->contents.data+1, ctx->dhExchangePublic.length+2, 3);
+    
+    SSLEncodeInt(keyExchange->contents.data+4, ctx->dhExchangePublic.length, 2);
+    memcpy(keyExchange->contents.data+6, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
+    
+    return SSLNoErr;
+}
+#endif
+
diff --git a/SecureTransport/nullciph.c b/SecureTransport/nullciph.c
new file mode 100644
index 00000000..175cb057
--- /dev/null
+++ b/SecureTransport/nullciph.c
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: nullciph.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: nullciph.c   A dummy implementation of the null cipher
+
+    The null cipher is used for SSL_NULL_WITH_NULL_NULL,
+    SSL_RSA_WITH_NULL_MD5, and SSL_RSA_WITH_NULL_SHA ciphers.
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#include <string.h>
+
+static SSLErr NullInit(
+	uint8 *key, 
+	uint8* iv, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx);
+static SSLErr NullCrypt(
+	SSLBuffer src, 
+	SSLBuffer dest, 
+	CipherContext *cipherCtx,
+	SSLContext *ctx);
+static SSLErr NullFinish(
+	CipherContext *cipherCtx,
+	SSLContext *ctx);
+
+const SSLSymmetricCipher SSLCipherNull = {
+    0,          /* Key size in bytes (ignoring parity) */
+    0,          /* Secret key size */
+    0,          /* IV size */
+    0,          /* Block size */
+    #ifdef	_APPLE_CDSA_
+    CSSM_ALGID_NONE,	
+    CSSM_ALGID_NONE,	
+    CSSM_ALGMODE_NONE,
+	CSSM_PADDING_NONE,
+    #endif	/* _APPLE_CDSA */
+    NullInit,
+    NullCrypt,
+    NullCrypt,
+    NullFinish
+};
+
+static SSLErr NullInit(
+	uint8 *key, 
+	uint8* iv, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx)
+{  
+ 	return SSLNoErr;
+}
+
+static SSLErr NullCrypt(
+	SSLBuffer src, 
+	SSLBuffer dest, 
+	CipherContext *cipherCtx,
+	SSLContext *ctx)
+{   
+	if (src.data != dest.data)
+        memcpy(dest.data, src.data, src.length);
+    return SSLNoErr;
+}
+
+static SSLErr NullFinish(
+	CipherContext *cipherCtx,
+	SSLContext *ctx)
+{   
+	return SSLNoErr;
+}
diff --git a/SecureTransport/privateInc/appleCdsa.h b/SecureTransport/privateInc/appleCdsa.h
new file mode 100644
index 00000000..d51ff3aa
--- /dev/null
+++ b/SecureTransport/privateInc/appleCdsa.h
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		appleCdsa.h
+
+	Contains:	interface between SSL and CDSA
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_APPLE_CDSA_H_
+#define _APPLE_CDSA_H_	1
+
+#include "ssl.h"
+#include "sslPriv.h"
+#include "sslctx.h"
+#include "sslerrs.h"
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if		SSL_DEBUG
+extern void stPrintCdsaError(const char *op, CSSM_RETURN crtn);
+extern char *stCssmErrToStr(CSSM_RETURN err);
+#else
+#define stPrintCdsaError(o, cr)
+#endif
+
+extern SSLErr sslFreeKey(CSSM_CSP_HANDLE cspHand, 
+	CSSM_KEY_PTR 	*key,
+	#if		ST_KEYCHAIN_ENABLE
+	KCItemRef		*kcItem);
+	#else	/* !ST_KEYCHAIN_ENABLE */
+	/* fixme - will we need kcItem as a CL field ptr? */
+	void			*kcItem);
+	#endif	/* ST_KEYCHAIN_ENABLE*/
+
+extern SSLErr attachToCsp(SSLContext *ctx);
+extern SSLErr attachToCl(SSLContext *ctx);
+extern SSLErr attachToTp(SSLContext *ctx);
+extern SSLErr attachToAll(SSLContext *ctx);
+extern SSLErr detachFromAll(SSLContext *ctx);
+
+extern CSSM_DATA_PTR stMallocCssmData(uint32 size);
+extern void stFreeCssmData(CSSM_DATA_PTR data, CSSM_BOOL freeStruct);
+extern SSLErr stSetUpCssmData(CSSM_DATA_PTR data, uint32 length);
+
+
+/*
+ * Common RNG function; replaces SSLRef's SSLRandomFunc
+ */
+extern SSLErr sslRand(
+	SSLContext *ctx, 
+	SSLBuffer *buf);
+
+/*
+ * Given a DER-encoded cert, obtain its public key as a CSSM_KEY_PTR.
+ */
+extern SSLErr sslPubKeyFromCert(
+	SSLContext 				*ctx,
+	const SSLBuffer			*derCert,
+	CSSM_KEY_PTR			*pubKey,		// RETURNED
+	CSSM_CSP_HANDLE			*cspHand);		// RETURNED
+
+/*
+ * Verify a cert chain.
+ */
+extern SSLErr sslVerifyCertChain(
+	SSLContext				*ctx,
+	const SSLCertificate	*certChain); 
+
+/*
+ * Raw RSA sign/verify.
+ */
+SSLErr sslRsaRawSign(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	privKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*plainText,
+	UInt32				plainTextLen,
+	UInt8				*sig,			// mallocd by caller; RETURNED
+	UInt32				sigLen,			// available
+	UInt32				*actualBytes);	// RETURNED
+	
+SSLErr sslRsaRawVerify(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	pubKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*plainText,
+	UInt32				plainTextLen,
+	const UInt8			*sig,
+	UInt32				sigLen);		// available
+	
+/*
+ * Encrypt/Decrypt
+ */
+SSLErr sslRsaEncrypt(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	pubKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*plainText,
+	UInt32				plainTextLen,
+	UInt8				*cipherText,		// mallocd by caller; RETURNED 
+	UInt32				cipherTextLen,		// available
+	UInt32				*actualBytes);		// RETURNED
+SSLErr sslRsaDecrypt(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	privKey,
+	CSSM_CSP_HANDLE		cspHand,
+	const UInt8			*cipherText,
+	UInt32				cipherTextLen,		
+	UInt8				*plainText,			// mallocd by caller; RETURNED
+	UInt32				plainTextLen,		// available
+	UInt32				*actualBytes);		// RETURNED
+
+/*
+ * Obtain size of key in bytes.
+ */
+extern UInt32 sslKeyLengthInBytes(
+	const CSSM_KEY_PTR key);
+
+/*
+ * Get raw key bits from an RSA public key.
+ */
+SSLErr sslGetPubKeyBits(
+	SSLContext			*ctx,
+	const CSSM_KEY_PTR	pubKey,
+	CSSM_CSP_HANDLE		cspHand,
+	SSLBuffer			*modulus,		// data mallocd and RETURNED
+	SSLBuffer			*exponent);		// data mallocd and RETURNED
+
+/*
+ * Given raw RSA key bits, cook up a CSSM_KEY_PTR. Used in 
+ * Server-initiated key exchange. 
+ */
+SSLErr sslGetPubKeyFromBits(
+	SSLContext			*ctx,
+	const SSLBuffer		*modulus,	
+	const SSLBuffer		*exponent,	
+	CSSM_KEY_PTR		*pubKey,		// mallocd and RETURNED
+	CSSM_CSP_HANDLE		*cspHand);		// RETURNED
+
+/*
+ * Given two certs, verify subjectCert with issuerCert. Returns 
+ * CSSM_TRUE on successful verify.
+ * Only special case on error is "subject cert expired", indicated by
+ * *subjectExpired returned as CSSM_TRUE.
+ */
+#if 0
+/* no longer needed */
+CSSM_BOOL sslVerifyCert(
+	SSLContext				*ctx,
+	const CSSM_DATA_PTR		subjectCert,
+	const CSSM_DATA_PTR		issuerCert,
+	CSSM_CSP_HANDLE			cspHand,			// can verify with issuerCert
+	CSSM_BOOL				*subjectExpired);	// RETURNED
+#endif
+
+/*
+ * Given a DER-encoded cert, obtain its DER-encoded subject name.
+ */
+#if		ST_KEYCHAIN_ENABLE 
+CSSM_DATA_PTR sslGetCertSubjectName( 
+	SSLContext			*ctx,
+    const CSSM_DATA_PTR cert);
+#endif		ST_KEYCHAIN_ENABLE 
+
+#if		(SSL_DEBUG && ST_KEYCHAIN_ENABLE)
+void verifyTrustedRoots(SSLContext *ctx,
+	CSSM_DATA_PTR	certs,
+	unsigned		numCerts);
+#endif
+
+void * stAppMalloc (uint32 size, void *allocRef);
+void stAppFree (void *mem_ptr, void *allocRef);
+void * stAppRealloc (void *ptr, uint32 size, void *allocRef);
+void * stAppCalloc (uint32 num, uint32 size, void *allocRef);
+
+/* 
+ * Convert between SSLBuffer and CSSM_DATA, which are after all identical.
+ * No mallocs, just copy the pointer and length. 
+ */
+#define SSLBUF_TO_CSSM(sb, cd)  {		\
+	(cd)->Length = (sb)->length; 		\
+	(cd)->Data   = (sb)->data;			\
+}
+
+#define CSSM_TO_SSLBUF(cd, sb)  {		\
+	(sb)->length = (cd)->Length; 		\
+	(sb)->data   = (cd)->Data;			\
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif	/* _APPLE_CDSA_H_ */
diff --git a/SecureTransport/privateInc/appleGlue.h b/SecureTransport/privateInc/appleGlue.h
new file mode 100644
index 00000000..428be0e0
--- /dev/null
+++ b/SecureTransport/privateInc/appleGlue.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		appleGlue.h
+
+	Contains:	Glue layer between Apple SecureTransport and 
+				original SSLRef code. 
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_SSL_H_
+#include "ssl.h"
+#endif
+
+#ifndef	_APPLE_GLUE_H_
+#define _APPLE_GLUE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Functions to allow old code to use SSLBuffer-based I/O calls.
+ * We redirect the calls here to an SSLIOFunc.
+ * This is of course way inefficient due to an extra copy for
+ * each I/O, but let's do it this way until the port settles down.
+ */
+ 
+SSLErr sslIoRead(
+ 	SSLBuffer 		buf, 
+ 	UInt32 			*actualLength, 
+ 	SSLContext 		*ctx);
+ 
+SSLErr sslIoWrite(
+ 	SSLBuffer 		buf, 
+ 	UInt32 			*actualLength, 
+ 	SSLContext 		*ctx);
+ 
+ /*
+  * Convert between SSLErr and OSStatus.
+  */
+extern SSLErr sslErrFromOsStatus(OSStatus o);
+extern OSStatus sslErrToOsStatus(SSLErr s);
+ 
+/*
+ * Time functions - replaces SSLRef's SSLTimeFunc, SSLConvertTimeFunc
+ */
+extern SSLErr sslTime(UInt32 *time);
+SSLErr sslConvertTime(UInt32 *time);
+
+#ifdef __cplusplus
+}
+#endif
+
+ #endif	/* _APPLE_GLUE_H_ */
+
+ 
\ No newline at end of file
diff --git a/SecureTransport/privateInc/appleSession.h b/SecureTransport/privateInc/appleSession.h
new file mode 100644
index 00000000..90e70594
--- /dev/null
+++ b/SecureTransport/privateInc/appleSession.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		appleSession.h
+
+	Contains:	Session storage module, _APPLE_CDSA_ version. 
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+/* 
+ * This file replaces the caller-specified SSLAddSessionFunc,
+ * SSLGetSessionFunc, and SSLDeleteSessionFunc callbacks in the 
+ * original SSLRef 3.0.
+ */
+ 
+#ifndef	_APPLE_SESSION_H_
+#define _APPLE_SESSION_H_
+
+#ifndef	_SSL_H_
+#include "ssl.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern SSLErr sslAddSession (
+	const SSLBuffer sessionKey, 
+	const SSLBuffer sessionData, 
+	void *sessionRef);
+
+extern SSLErr sslGetSession (
+	const SSLBuffer sessionKey, 
+	SSLBuffer *sessionData, 
+	void *sessionRef);
+
+extern SSLErr sslDeleteSession (
+	const SSLBuffer sessionKey, 
+	void *sessionRef);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _APPLE_SESSION_H_ */
diff --git a/SecureTransport/privateInc/cipherSpecs.h b/SecureTransport/privateInc/cipherSpecs.h
new file mode 100644
index 00000000..95984b99
--- /dev/null
+++ b/SecureTransport/privateInc/cipherSpecs.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cipherSpecs.h
+
+	Contains:	SSLCipherSpec declarations
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_CIPHER_SPECS_H_
+#define _CIPHER_SPECS_H_
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _CRYPTTYPE_H_
+#include "cryptType.h"
+#endif
+
+/* 
+ * Build ctx->validCipherSpecs as a copy of all known CipherSpecs. 
+ */
+extern SSLErr sslBuildCipherSpecArray(SSLContext *ctx);
+
+/*
+ * Given a valid ctx->selectedCipher and ctx->validCipherSpecs, set
+ * ctx->selectedCipherSpec as appropriate. 
+ */
+SSLErr  FindCipherSpec(SSLContext *ctx);
+
+extern const SSLCipherSpec SSL_NULL_WITH_NULL_NULL_CipherSpec;
+
+
+#endif	/* _CIPHER_SPECS_H_ */
diff --git a/SecureTransport/privateInc/cryptType.h b/SecureTransport/privateInc/cryptType.h
new file mode 100644
index 00000000..d5da53f8
--- /dev/null
+++ b/SecureTransport/privateInc/cryptType.h
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		cryptType.h
+
+	Contains:	Crypto structures and routines
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: cryptype.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: cryptype.h   Crypto structures and routines
+
+    Types associated with cryptographic functionality, including hashes,
+    symmetric ciphers, and cipher specs.
+
+    ****************************************************************** */
+
+#ifndef _CRYPTTYPE_H_
+#define _CRYPTTYPE_H_ 1
+
+#include "sslerrs.h"
+#include <Security/CipherSuite.h>
+#include "sslPriv.h"
+#include "sslctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{   SSL2_RC4_128_WITH_MD5 =                 0x010080,
+    SSL2_RC4_128_EXPORT_40_WITH_MD5 =       0x020080,
+    SSL2_RC2_128_CBC_WITH_MD5 =             0x030080,
+    SSL2_RC2_128_CBC_EXPORT40_WITH_MD5 =    0x040080,
+    SSL2_IDEA_128_CBC_WITH_MD5 =            0x050080,
+    SSL2_DES_64_CBC_WITH_MD5 =              0x060040,
+    SSL2_DES_192_EDE3_CBC_WITH_MD5 =        0x0700C0
+} SSL2CipherKind;
+
+typedef struct
+{   SSL2CipherKind  	cipherKind;
+    SSLCipherSuite     	cipherSuite;
+} SSLCipherMapping;
+
+/*
+ * Note: we're not changing the digest mechanisms for now; BSAFE 
+ * doesn't provide the necessary "digest clone" op. 
+ */
+typedef SSLErr (*HashInit)(SSLBuffer digestCtx);
+typedef SSLErr (*HashUpdate)(SSLBuffer digestCtx, SSLBuffer data);
+typedef SSLErr (*HashFinal)(SSLBuffer digestCtx, SSLBuffer digest);
+typedef SSLErr (*HashClone)(SSLBuffer src, SSLBuffer dest);
+
+typedef struct
+{   UInt32      contextSize;
+    UInt32      digestSize;
+    UInt32      macPadSize;
+    HashInit    init;
+    HashUpdate  update;
+    HashFinal   final;
+    HashClone   clone;
+} HashReference;
+
+extern const HashReference SSLHashNull;
+extern const HashReference SSLHashMD5;
+extern const HashReference SSLHashSHA1;
+
+#ifdef	_APPLE_CDSA_
+/*
+ * All symmetric ciphers go thru CDSA, but we'll keep these callouts for
+ * now. The major change here is the inclusion of the CipherContext
+ * arg, for alg/mode and key storage. 
+ */
+struct CipherContext;
+typedef struct CipherContext CipherContext;
+
+typedef SSLErr (*SSLKeyFunc)(
+	UInt8 *key, 
+	UInt8 *iv, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx);
+typedef SSLErr (*SSLCryptFunc)(
+	SSLBuffer src, 
+	SSLBuffer dest, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx);
+typedef SSLErr (*SSLFinishFunc)(
+	CipherContext *cipherCtx, 
+	SSLContext *ctx);
+
+#else
+typedef SSLErr (*SSLKeyFunc)(UInt8 *key, UInt8 *iv, void **cipherRef, SSLContext *ctx);
+typedef SSLErr (*SSLCryptFunc)(SSLBuffer src, SSLBuffer dest, void *cipherRef, SSLContext *ctx);
+typedef SSLErr (*SSLFinishFunc)(void *cipherRef, SSLContext *ctx);
+#endif	/* _APPLE_CDSA */
+
+typedef enum
+{   NotExportable = 0,
+    Exportable = 1
+} Exportability;
+
+/*
+ * Statically defined description of a symmetric sipher. 
+ */
+typedef struct {
+    UInt8           	keySize;            /* Sizes are in bytes */
+    UInt8           	secretKeySize;
+    UInt8           	ivSize;
+    UInt8          	 	blockSize;
+    #ifdef	_APPLE_CDSA_
+    CSSM_ALGORITHMS		keyAlg;				/* CSSM_ALGID_DES, etc. */
+    CSSM_ALGORITHMS		encrAlg;			/* ditto */
+    CSSM_ENCRYPT_MODE	encrMode;			/* CSSM_ALGMODE_CBCPadIV8, etc. */
+	CSSM_PADDING		encrPad;
+    #endif	/* _APPLE_CDSA */
+    SSLKeyFunc      	initialize;
+    SSLCryptFunc    	encrypt;
+    SSLCryptFunc    	decrypt;
+    SSLFinishFunc   	finish;
+} SSLSymmetricCipher;
+
+#define MAX_DIGEST_SIZE 20          /* SHA digest size = 160 bits */
+#define MAX_MAC_PADDING 48          /* MD5 MAC padding size = 48 bytes */
+#define MASTER_SECRET_LEN 48        /* master secret = 3 x MD5 hashes concatenated */
+#ifdef	__APPLE__
+/* SSL V2 - mac secret is the size of symmetric key, not digest */
+#define MAX_SYMKEY_SIZE		24
+#endif	/* __APPLE__ */
+
+typedef enum
+{   SSL_NULL_auth,
+	/*
+	 * FIXME: I have no idea what the difference is between
+	 * e.g. SSL_RSA and SS_RSA_EXPORT. These don't go over the 
+	 * wire. 
+	 * The few times the SSLRef code behaves differently between
+	 * these two look wrong. See SSLDecodeRSAKeyExchange(),
+	 * SSLAdvanceHandshake(). 
+	 *
+	 * UPDATE: see comments for SSL_SERVER_KEYEXCH_HACK hack. 
+	 */
+    SSL_RSA,
+    SSL_RSA_EXPORT,
+    SSL_DH_DSS,
+    SSL_DH_DSS_EXPORT,
+    SSL_DH_RSA,
+    SSL_DH_RSA_EXPORT,
+    SSL_DHE_DSS,
+    SSL_DHE_DSS_EXPORT,
+    SSL_DHE_RSA,
+    SSL_DHE_RSA_EXPORT,
+    SSL_DH_anon,
+    SSL_DH_anon_EXPORT,
+    SSL_Fortezza
+} KeyExchangeMethod;
+
+typedef struct {
+    SSLCipherSuite      		cipherSpec;
+    Exportability       		isExportable;
+    KeyExchangeMethod   		keyExchangeMethod;
+    const HashReference      	*macAlgorithm;
+    const SSLSymmetricCipher  	*cipher;
+} SSLCipherSpec;
+
+extern const SSLCipherMapping SSL2CipherMap[];
+extern const int SSL2CipherMapCount;
+extern UInt8 SSLMACPad1[], SSLMACPad2[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CRYPTTYPE_H_ */
diff --git a/SecureTransport/privateInc/digests.h b/SecureTransport/privateInc/digests.h
new file mode 100644
index 00000000..c24a0bf3
--- /dev/null
+++ b/SecureTransport/privateInc/digests.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		digests.h
+
+	Contains:	HashReference declarations
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_DIGESTS_H_
+#define _DIGESTS_H_	1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern HashReference SSLHashNull;
+extern HashReference SSLHashMD5;
+extern HashReference SSLHashSHA1;
+
+extern void SSLInitMACPads(void);
+extern SSLErr CloneHashState(
+	const HashReference *ref, 
+	SSLBuffer state, 
+	SSLBuffer *newState, 
+	SSLContext *ctx);
+extern SSLErr ReadyHash(
+	const HashReference *ref, 
+	SSLBuffer *state, 
+	SSLContext *ctx);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _DIGESTS_H_ */
diff --git a/SecureTransport/privateInc/ssl.h b/SecureTransport/privateInc/ssl.h
new file mode 100644
index 00000000..77c69fb7
--- /dev/null
+++ b/SecureTransport/privateInc/ssl.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		ssl.h
+
+	Contains:	convenience header, including public and private parts
+				of original ssl.h
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_SSL_H_
+#define _SSL_H_
+
+#include <Security/SecureTransport.h>
+#include "sslPriv.h"
+
+#endif	/* _SSL_H */
\ No newline at end of file
diff --git a/SecureTransport/privateInc/ssl2.h b/SecureTransport/privateInc/ssl2.h
new file mode 100644
index 00000000..19304e5a
--- /dev/null
+++ b/SecureTransport/privateInc/ssl2.h
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		ssl2.h
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: ssl2.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: ssl2.h       SSL 2 functionality header
+
+    This file contains function prototypes and equate values for SSL2.
+    The relevant functions are contained in files whose names match
+    ssl2*.c
+
+    ****************************************************************** */
+
+#ifndef _SSL2_H_
+#define _SSL2_H_
+
+#ifndef _SECURE_TRANSPORT_H_
+#include "SecureTransport.h"
+#endif
+
+#ifndef	_SSL_PRIV_H_
+#include "sslPriv.h"
+#endif
+
+#ifndef _SSLREC_H_
+#include "sslrec.h"
+#endif
+
+typedef enum
+{   ssl2_mt_error = 0,
+    ssl2_mt_client_hello = 1,
+    ssl2_mt_client_master_key = 2,
+    ssl2_mt_client_finished = 3,
+    ssl2_mt_server_hello = 4,
+    ssl2_mt_server_verify = 5,
+    ssl2_mt_server_finished = 6,
+    ssl2_mt_request_certificate = 7,
+    ssl2_mt_client_certificate = 8,
+    ssl2_mt_kickstart_handshake = 99
+} SSL2MessageType;
+
+typedef enum
+{   ssl2_pe_no_cipher = 1,
+    ssl2_pe_no_certificate = 2,
+    ssl2_pe_bad_certificate = 4,
+    ssl2_pe_unsupported_certificate_type = 6
+} SSL2ErrorCode;
+
+typedef enum
+{   ssl2_ct_x509_certificate = 1
+} SSL2CertTypeCode;
+
+#define SSL2_CONNECTION_ID_LENGTH   16
+
+typedef SSLErr (*EncodeSSL2MessageFunc)(SSLBuffer *msg, SSLContext *ctx);
+SSLErr SSL2ReadRecord(SSLRecord *rec, SSLContext *ctx);
+SSLErr SSL2WriteRecord(SSLRecord rec, SSLContext *ctx);
+SSLErr SSL2ProcessMessage(SSLRecord rec, SSLContext *ctx);
+SSLErr SSL2SendError(SSL2ErrorCode error, SSLContext *ctx);
+SSLErr SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx);
+SSLErr SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx);
+SSLErr SSL2CompareSessionIDs(SSLContext *ctx);
+SSLErr SSL2InstallSessionKey(SSLContext *ctx);
+SSLErr SSL2GenerateSessionID(SSLContext *ctx);
+SSLErr SSL2InitCiphers(SSLContext *ctx);
+
+SSLErr SSL2ProcessClientHello(SSLBuffer msgContents, SSLContext *ctx);
+SSLErr SSL2EncodeClientHello(SSLBuffer *msg, SSLContext *ctx);
+SSLErr SSL2ProcessClientMasterKey(SSLBuffer msgContents, SSLContext *ctx);
+SSLErr SSL2EncodeClientMasterKey(SSLBuffer *msg, SSLContext *ctx);
+SSLErr SSL2ProcessClientFinished(SSLBuffer msgContents, SSLContext *ctx);
+SSLErr SSL2EncodeClientFinished(SSLBuffer *msg, SSLContext *ctx);
+SSLErr SSL2ProcessServerHello(SSLBuffer msgContents, SSLContext *ctx);
+SSLErr SSL2EncodeServerHello(SSLBuffer *msg, SSLContext *ctx);
+SSLErr SSL2ProcessServerVerify(SSLBuffer msgContents, SSLContext *ctx);
+SSLErr SSL2EncodeServerVerify(SSLBuffer *msg, SSLContext *ctx);
+SSLErr SSL2ProcessServerFinished(SSLBuffer msgContents, SSLContext *ctx);
+SSLErr SSL2EncodeServerFinished(SSLBuffer *msg, SSLContext *ctx);
+
+#endif
diff --git a/SecureTransport/privateInc/sslBER.h b/SecureTransport/privateInc/sslBER.h
new file mode 100644
index 00000000..b859e7da
--- /dev/null
+++ b/SecureTransport/privateInc/sslBER.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslBER.h
+
+	Contains:	BER routines
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_SSL_BER_H_
+#define _SSL_BER_H_
+
+#ifndef	_SSL_PRIV_H_
+#include "sslPriv.h"
+#endif
+
+#ifdef __cplusplus
+extern	"C" {
+#endif
+
+/*
+ * Given a PKCS-1 encoded RSA public key, extract the 
+ * modulus and public exponent.
+ *
+ * RSAPublicKey ::= SEQUENCE {
+ *		modulus INTEGER, -- n
+ *		publicExponent INTEGER -- e }
+ */
+ 
+SSLErr sslDecodeRsaBlob(
+	const SSLBuffer	*blob,			/* PKCS-1 encoded */
+	SSLBuffer		*modulus,		/* data mallocd and RETURNED */
+	SSLBuffer		*exponent);		/* data mallocd and RETURNED */
+
+/*
+ * Given a raw modulus and exponent, cook up a
+ * BER-encoded RSA public key blob.
+ */
+ 
+SSLErr sslEncodeRsaBlob(
+	const SSLBuffer	*modulus,		
+	const SSLBuffer	*exponent,		
+	SSLBuffer		*blob);			/* data mallocd and RETURNED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SSL_BER_H_ */
\ No newline at end of file
diff --git a/SecureTransport/privateInc/sslBuildFlags.h b/SecureTransport/privateInc/sslBuildFlags.h
new file mode 100644
index 00000000..ca064632
--- /dev/null
+++ b/SecureTransport/privateInc/sslBuildFlags.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslBuildFlags.h
+
+	Contains:	Common build flags 
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_SSL_BUILD_FLAGS_H_
+#define _SSL_BUILD_FLAGS_H_				1
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * This flags functional changes, within SSLRef3 source, made to
+ * accomodate the Apple SecureTransport library.
+ */
+#define _APPLE_CDSA_					1
+
+/*
+ * Work around the Netscape Server Key Exchange bug. When this is 
+ * true, only do server key exchange if both of the following are
+ * true:
+ *
+ *   -- an export-grade ciphersuite has been negotiated, and
+ *   -- an encryptPrivKey is present in the context
+ */
+#define SSL_SERVER_KEYEXCH_HACK			1
+
+/*
+ * RSA functions which use a public key to do encryption force 
+ * the proper usage bit because the CL always gives us
+ * a pub key (from a cert) with only the verify bit set. 
+ * This needs a mod to the CL to do the right thing, and that
+ * might not be enough - what if server certs don't have the 
+ * appropriate usage bits?
+ */
+#define RSA_PUB_KEY_USAGE_HACK			1
+
+/*
+ * For now, we're assuming that the domestic CSP is available - major
+ * rework needed if it's not. 
+ */
+#define APPLE_DOMESTIC_CSP_REQUIRED		1
+
+/* debugging flags */
+#ifdef	NDEBUG
+#define SSL_DEBUG			0
+#define ERROR_LOG_ENABLE	0
+#else
+#define SSL_DEBUG			1
+#define ERROR_LOG_ENABLE	1
+#endif	/* NDEBUG */
+	
+#if defined(__cplusplus)
+}
+#endif
+
+#endif	/* _SSL_BUILD_FLAGS_H_ */
diff --git a/SecureTransport/privateInc/sslDebug.h b/SecureTransport/privateInc/sslDebug.h
new file mode 100644
index 00000000..db23cde5
--- /dev/null
+++ b/SecureTransport/privateInc/sslDebug.h
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslDebug.h
+
+	Contains:	Debugging macros.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1998, 1999 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		03/10/98	dpm		Created.
+
+*/
+
+#ifndef	_SSL_DEBUG_H_
+#define _SSL_DEBUG_H_
+
+#include "sslBuildFlags.h"
+
+#if		SSL_DEBUG || ERROR_LOG_ENABLE
+
+/* any other way? */
+#define LOG_VIA_PRINTF		1
+
+#include <stdio.h>
+
+#if		!LOG_VIA_PRINTF
+
+#error Hey, figure out a debug mechanism
+
+#include <string.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* remaining ones can take constant strings */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern void dblog0(char *str);
+extern void dblog1(char *str, void * arg1);
+extern void dblog2(char *str, void * arg1, void * arg2);
+extern void dblog3(char *str, void * arg1, void * arg2, void * arg3);
+extern void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4);
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#else	/* LOG_VIA_PRINTF */
+
+#define dblog0(str)								printf(str)
+#define dblog1(str, arg1)						printf(str, arg1)
+#define dblog2(str, arg1, arg2)					printf(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)			printf(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)		printf(str, arg1, arg2, arg3, arg4)
+
+#endif	/* LOG_VIA_PRINTF */
+
+#else	/* log macros disabled */
+
+#define dblog0(str)
+#define dblog1(str, arg1)
+#define dblog2(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* SSL_DEBUG || ERROR_LOG_ENABLE */
+
+#if	SSL_DEBUG
+
+#define dprintf0(str)								dblog0(str)
+#define dprintf1(str, arg1)							dblog1(str, arg1)
+#define dprintf2(str, arg1, arg2)					dblog2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)				dblog3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)		dblog4(str, arg1, arg2, arg3,  arg4)
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+static inline volatile void sslPanic(const char *str)
+{
+	printf(str);
+	exit(1);
+}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#define CASSERT(expression) 							\
+  ((expression) ? (void)0 : 							\
+   (dprintf1 ("Assertion failed: " #expression 			\
+      ", file " __FILE__ ", line %d.\n", __LINE__), 	\
+    sslPanic("Assertion Failure")))
+
+#else	/* SSL_DEBUG */
+
+#define dprintf0(str)
+#define dprintf1(str, arg1)
+#define dprintf2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)
+
+#define CASSERT(expression)
+#define sslPanic(s)
+#endif	/* SSL_DEBUG */
+
+/*
+ * Error logging. This may well be platform dependent.
+ */
+#if		ERROR_LOG_ENABLE
+#define errorLog0(str)								dblog0(str);
+#define errorLog1(str, arg1)						dblog1(str, arg1)
+#define errorLog2(str, arg1, arg2)					dblog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)			dblog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)		dblog4(str, arg1, arg2, arg3, arg4)
+
+#else	/* ERROR_LOG_ENABLE */
+
+#define errorLog0(str)
+#define errorLog1(str, arg1)
+#define errorLog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* ERROR_LOG_ENABLE */
+
+/*
+ * Override SSLRef macros
+ */
+#define ERR(x)							(x)
+#define DUMP_BUFFER_NAME(name, buf)
+#define DUMP_DATA_NAME(name, p, len)
+#define ASSERTMSG(m)					sslPanic(m)
+#define DEBUGVAL1(str, arg)				errorLog1(str, arg)
+
+/*** SSL-Specific debugging ***/
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+/* Logging Enable Flags */
+
+#if		SSL_DEBUG
+
+/* log changes in handshake state */
+#define LOG_HDSK_STATE		0
+
+/* log handshake messages */
+#define LOG_HDSK_MSG		0
+
+/* log negotiated handshake paramters */
+#define LOG_NEGOTIATE		0
+
+/* log received protocol messsages */
+#define LOG_RX_PROTOCOL		0
+
+#else	/* !SSL_DEBUG - normal build - all flags disabled */
+#define LOG_HDSK_STATE		0
+#define LOG_HDSK_MSG		0
+#define LOG_NEGOTIATE		0
+#endif	/* SSL_DEBUG */
+
+#if		LOG_HDSK_STATE
+extern void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState);
+#else	/* LOG_HDSK_STATE */
+#define SSLChangeHdskState(ctx, newState) { ctx->state=newState; }
+#endif	/* LOG_HDSK_STATE */
+
+#if		LOG_HDSK_MSG
+extern void SSLLogHdskMsg(SSLHandshakeType msg, char sent);
+extern char *hdskStateToStr(SSLHandshakeState state);
+#else	/* LOG_HDSK_STATE */
+#define SSLLogHdskMsg(msg, sent)
+#endif	/* LOG_HDSK_STATE */
+
+/* 
+ * A crufty little routine to write cert blobs to disk.
+ * Implemented in appleCdsa.c.
+ */
+#if	SSL_DEBUG
+extern void writeBufBlob(const SSLBuffer *blob, 
+	const char *fileName);
+#endif
+
+#endif	/* _SSL_DEBUG_H_ */
diff --git a/SecureTransport/privateInc/sslKeychain.h b/SecureTransport/privateInc/sslKeychain.h
new file mode 100644
index 00000000..2edc3f2a
--- /dev/null
+++ b/SecureTransport/privateInc/sslKeychain.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslKeychain.h
+
+	Contains:	Apple Keychain routines
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_SSL_KEYCHAIN_H_
+#define _SSL_KEYCHAIN_H_
+
+
+#ifndef	_SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFArray.h>
+
+#if		ST_KEYCHAIN_ENABLE
+#include <MacTypes.h>
+#include <Keychain.h>
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if	(ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION)
+/*
+ * Given an array of certs (as KCItemRefs) and a destination
+ * SSLCertificate:
+ *
+ * -- free destCerts if we have any
+ * -- Get raw cert data, convert to array of SSLCertificates in *destCert 
+ * -- get pub, priv keys from certRef[0], store in *pubKey, *privKey
+ * -- validate cert chain
+ *
+ */
+OSStatus 
+parseIncomingCerts(
+	SSLContext		*ctx,
+	CFArrayRef		certs,
+	SSLCertificate	**destCert,		/* &ctx->{localCert,encryptCert} */
+	CSSM_KEY_PTR	*pubKey,		/* &ctx->signingPubKey, etc. */
+	CSSM_KEY_PTR	*privKey,		/* &ctx->signingPrivKey, etc. */
+	CSSM_CSP_HANDLE	*cspHand,		/* &ctx->signingKeyCsp, etc. */
+	KCItemRef		*privKeyRef);	/* &ctx->signingKeyRef, etc. */
+#endif	/* (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION) */
+
+/*
+ * Add Apple built-in root certs to ctx->trustedCerts.
+ */
+OSStatus 
+addBuiltInCerts	(
+	SSLContextRef	ctx);
+
+#if		ST_KEYCHAIN_ENABLE
+/*
+ * Given an open Keychain:
+ * -- Get raw cert data, add to array of CSSM_DATAs in 
+ *    ctx->trustedCerts 
+ * -- verify that each of these is a valid (self-verifying)
+ *    root cert
+ * -- add each subject name to acceptableDNList
+ */
+OSStatus
+parseTrustedKeychain(
+	SSLContextRef		ctx,
+	KCRef				keyChainRef);
+
+/*
+ * Given a newly encountered root cert (obtained from a peer's cert chain),
+ * add it to newRootCertKc if the user so allows, and if so, add it to 
+ * trustedCerts.
+ */
+SSLErr
+sslAddNewRoot(
+	SSLContext			*ctx, 
+	const CSSM_DATA_PTR	rootCert);
+
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SSL_KEYCHAIN_H_ */
\ No newline at end of file
diff --git a/SecureTransport/privateInc/sslPriv.h b/SecureTransport/privateInc/sslPriv.h
new file mode 100644
index 00000000..349bedfd
--- /dev/null
+++ b/SecureTransport/privateInc/sslPriv.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslPriv.h
+
+	Contains:	Misc. private SSL typedefs
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_SSL_PRIV_H_
+#define _SSL_PRIV_H_	1
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include "sslBuildFlags.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Apple CSP doesn't support D-H yet */
+#define APPLE_DH		0
+
+/* 
+ * For ease of porting, we'll keep this around for internal use.
+ * It's used extensively; eventually we'll convert over to
+ * CFData, as in the public API.
+ */
+typedef struct
+{   UInt32  length;
+    UInt8   *data;
+} SSLBuffer;
+
+/*
+ * We can make this more Mac-like as well...
+ */
+typedef struct
+{   UInt32  high;
+    UInt32  low;
+}   sslUint64;
+
+/*
+ * Not exposed in public API
+ */
+typedef enum
+{   SSL_ServerSide = 1,
+    SSL_ClientSide = 2
+} SSLProtocolSide;
+
+typedef enum
+{   SSL_Version_Undetermined = 0,
+    SSL_Version_3_0_With_2_0_Hello = 100,
+    SSL_Version_3_0_Only = 101,
+    SSL_Version_2_0 = 0x0002,
+    SSL_Version_3_0 = 0x0300
+} SSLProtocolVersion;
+
+/*
+ * Clients see an opaque SSLContextRef; internal code uses the 
+ * following typedef.
+ */
+typedef struct SSLContext SSLContext;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SSL_PRIV_H */
diff --git a/SecureTransport/privateInc/sslalert.h b/SecureTransport/privateInc/sslalert.h
new file mode 100644
index 00000000..41ed716d
--- /dev/null
+++ b/SecureTransport/privateInc/sslalert.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: sslalert.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslalert.h   Alert layer functions and values
+
+    Prototypes for functions in sslalert.c and alert layer equates.
+
+    ****************************************************************** */
+
+#ifndef _SSLALERT_H_
+#define _SSLALERT_H_ 1
+
+#ifndef _SECURE_TRANSPORT_H_
+#include "SecureTransport.h"
+#endif
+
+#ifndef	_SSL_PRIV_H_
+#include "sslPriv.h"
+#endif
+
+#ifndef _SSLREC_H_
+#include "sslrec.h"
+#endif
+
+typedef enum
+{   alert_warning = 1,
+    alert_fatal = 2
+} AlertLevel;
+
+typedef enum
+{   alert_close_notify = 0,
+    alert_unexpected_message = 10,
+    alert_bad_record_mac = 20,
+    alert_decompression_failure = 30,
+    alert_handshake_failure = 40,
+    alert_no_certificate = 41,
+    alert_bad_certificate = 42,
+    alert_unsupported_certificate = 43,
+    alert_certificate_revoked = 44,
+    alert_certificate_expired = 45,
+    alert_certificate_unknown = 46,
+    alert_illegal_parameter = 47
+} AlertDescription;
+
+SSLErr SSLProcessAlert(SSLRecord rec, SSLContext *ctx);
+SSLErr SSLSendAlert(AlertLevel level, AlertDescription desc, SSLContext *ctx);
+SSLErr SSLEncodeAlert(SSLRecord *rec, AlertLevel level, AlertDescription desc, SSLContext *ctx);
+SSLErr SSLFatalSessionAlert(AlertDescription desc, SSLContext *ctx);
+
+#endif /* _SSLALERT_H_ */
diff --git a/SecureTransport/privateInc/sslalloc.h b/SecureTransport/privateInc/sslalloc.h
new file mode 100644
index 00000000..9f6da39b
--- /dev/null
+++ b/SecureTransport/privateInc/sslalloc.h
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslalloc.h
+
+	Contains:	memory allocator declarations
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: sslalloc.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslalloc.h   Allocation shell routines
+
+    These routines wrap the user-supplied callbacks to provide allocation
+    functionality.
+
+    ****************************************************************** */
+
+#ifndef _SSLALLOC_H_
+#define _SSLALLOC_H_ 1
+
+#include "sslctx.h"
+#include "sslerrs.h"
+#include "sslPriv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 
+ * General purpose allocators
+ */
+void *sslMalloc(UInt32 length);
+void sslFree(void *p);
+void *sslRealloc(void *oldPtr, UInt32 oldLen, UInt32 newLen);
+
+/*
+ * SSLBuffer-oriented allocators
+ */
+SSLErr SSLAllocBuffer(SSLBuffer *buf, UInt32 length, const SystemContext *ctx);
+SSLErr SSLFreeBuffer(SSLBuffer *buf, const SystemContext *ctx);
+SSLErr SSLReallocBuffer(SSLBuffer *buf, UInt32 newSize, const SystemContext *ctx);
+
+/*
+ * Set up/tear down CF allocators.
+ */
+OSStatus cfSetUpAllocators(SSLContext *ctx);
+void cfTearDownAllocators(SSLContext *ctx);
+
+/*
+ * Convenience routines.
+ */
+UInt8 *sslAllocCopy(const UInt8 *src, UInt32 len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/SecureTransport/privateInc/sslctx.h b/SecureTransport/privateInc/sslctx.h
new file mode 100644
index 00000000..cd082838
--- /dev/null
+++ b/SecureTransport/privateInc/sslctx.h
@@ -0,0 +1,385 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslctx.h
+
+	Contains:	Private SSL typedefs: SSLContext and its components
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+/*  *********************************************************************
+    File: sslctx.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslctx.h     Internal state of an SSL connection
+
+    Contains the SSLContext structure which encapsulates the state of the
+    connection at any time. Whenever SSLREF might have to return (mostly
+    when I/O is done), this structure must completely represent the
+    connection state
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#define _SSLCTX_H_ 1
+
+#include <Security/SecureTransport.h>
+#include "sslBuildFlags.h"
+
+#ifdef	_APPLE_CDSA_
+
+#include <Security/cssmtype.h>
+
+#if		ST_KEYCHAIN_ENABLE
+#include <Keychain.h>
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+#endif	/* _APPLE_CDSA_ */
+
+#ifndef	_APPLE_CDSA_
+#include "sslalloc.h"
+#endif
+
+#include "sslerrs.h"
+#include "sslPriv.h"
+
+
+/*
+ * These were originally in ssl.h; they're not exposed as client-specified
+ * functions here.
+ */
+#ifndef	_APPLE_CDSA_
+typedef SSLErr (*SSLRandomFunc) (
+	SSLBuffer data, 
+	void *randomRef);
+typedef SSLErr (*SSLTimeFunc) (
+	UInt32 *time, 
+	void *timeRef);
+typedef SSLErr (*SSLConvertTimeFunc) (
+	UInt32 *time, 
+	void *timeRef);
+typedef SSLErr (*SSLAddSessionFunc) (
+	SSLBuffer sessionKey, 
+	SSLBuffer sessionData, 
+	void *sessionRef);
+typedef SSLErr (*SSLGetSessionFunc) (
+	SSLBuffer sessionKey, 
+	SSLBuffer *sessionData, 
+	void *sessionRef);
+typedef SSLErr (*SSLDeleteSessionFunc) (
+	SSLBuffer sessionKey, 
+	void *sessionRef);
+typedef SSLErr (*SSLCheckCertificateFunc) (
+	int certCount, 
+	SSLBuffer *derCerts, 
+	void *checkCertificateRef);
+#endif	/* _APPLE_CDSA_ */
+
+typedef struct
+{   SSLReadFunc         read;
+    SSLWriteFunc        write;
+    SSLConnectionRef   	ioRef;
+} IOContext;
+
+struct SystemContext
+{   
+	/* FIXME - this probably goes away; we keep it as a struct due
+	 * to its pervasive use in calls to SSLAllocBuffer. We have to
+	 * have *an* element in it for compiler reasons.
+	 */
+	#ifdef	_APPLE_CDSA_
+	int 				foo;
+	#else
+	SSLAllocFunc        alloc;
+    SSLFreeFunc         free;
+    SSLReallocFunc      realloc;
+    void                *allocRef;
+    SSLTimeFunc         time;
+    SSLConvertTimeFunc  convertTime;
+    void                *timeRef;
+    SSLRandomFunc       random;
+    void                *randomRef;
+    #endif	/* _APPLE_CDSA_ */
+};
+
+typedef struct SystemContext SystemContext;
+
+typedef struct
+{   
+	#ifndef	_APPLE_CDSA_
+	/* these functions are hard-coded */
+	SSLAddSessionFunc       addSession;
+    SSLGetSessionFunc       getSession;
+    SSLDeleteSessionFunc    deleteSession;
+    #endif
+    void                    *sessionRef;
+} SessionContext;
+
+#ifndef	_APPLE_CDSA_
+/* not used, cert functions via CDSA */
+typedef struct
+{   SSLCheckCertificateFunc checkCertFunc;
+    void                    *checkCertRef;
+} CertificateContext;
+#endif
+
+/*
+ * A carryover from original SSLRef 3.0 - we'll store the DER-encoded
+ * certs in an SSLCertificate this way for now; there's a lot of code
+ * which munges these lists.
+ */
+typedef struct SSLCertificate
+{   
+	struct SSLCertificate   *next;
+    SSLBuffer               derCert;
+    #ifndef	_APPLE_CDSA_
+    /* but not decoded...we never do that! */
+    X509Cert                cert;
+    #endif	/* _APPLE_CDSA_ */
+} SSLCertificate;
+
+#include "cryptType.h"
+
+struct CipherContext
+{   const HashReference       *hash;
+    const SSLSymmetricCipher  *symCipher;
+    
+    #ifdef	_APPLE_CDSA_
+    
+    /* 
+     * symKey is obtained from the CSP at cspHand. Normally this 
+     * cspHand is the same as ctx->cspHand; some day they might differ.
+     * Code which deals with this struct doesn't ever have to 
+     * attach or detach from cspHand - that's taken care of at the
+     * SSLContext level.
+     */
+    CSSM_KEY_PTR		symKey;	
+    CSSM_CSP_HANDLE		cspHand;
+    CSSM_CC_HANDLE		ccHand;
+
+	/* needed in CDSASymmInit */
+	uint8				encrypting;
+	
+    #else
+    void                *symCipherState;
+    #endif	/* _APPLE_CDSA_*/
+    sslUint64           sequenceNum;
+    uint8               ready;
+	#ifdef	__APPLE__
+	/* in SSL2 mode, the macSecret is the same size as the
+	 * cipher key - which is 24 bytes in the 3DDES case. */
+	uint8				macSecret[MAX_SYMKEY_SIZE];
+	#else
+    uint8               macSecret[MAX_DIGEST_SIZE];
+	#endif	/* __APPLE__ */
+};
+/* typedef in cryptType.h */
+
+#include "sslhdshk.h"
+
+typedef struct WaitingRecord
+{   struct WaitingRecord    *next;
+    SSLBuffer				data;
+    uint32                  sent;
+} WaitingRecord;
+
+typedef struct DNListElem
+{   struct DNListElem   *next;
+    SSLBuffer		    derDN;
+} DNListElem;
+
+struct SSLContext
+{   
+	/*
+	 * For _APPLE_CDSA_, SystemContext is empty; we'll leave it in for now
+	 * 'cause it gets passed around so often for SSLAllocBuffer().
+	 */
+	SystemContext       sysCtx;
+    IOContext           ioCtx;
+    SessionContext      sessionCtx;
+    #ifndef	_APPLE_CDSA_
+    CertificateContext  certCtx;
+    #endif
+    
+    SSLProtocolVersion  reqProtocolVersion;	/* requested by app */
+    SSLProtocolVersion  negProtocolVersion;	/* negotiated */
+    SSLProtocolSide     protocolSide;
+    
+    #ifdef	_APPLE_CDSA_
+    
+    /* crypto state in CDSA-centric terms */
+    
+    CSSM_KEY_PTR		signingPrivKey;	/* our private signing key */
+    CSSM_KEY_PTR		signingPubKey;	/* our public signing key */
+    CSSM_CSP_HANDLE		signingKeyCsp;	/* associated DL/CSP */
+	#if		ST_KEYCHAIN_ENABLE
+    KCItemRef			signingKeyRef;	/* for signingPrivKey */
+    #endif
+	
+	/* this stuff should probably be #if ST_SERVER_MODE_ENABLE....  */
+    CSSM_KEY_PTR		encryptPrivKey;	/* our private encrypt key, for 
+    									 * server-initiated key exchange */
+    CSSM_KEY_PTR		encryptPubKey;	/* public version of above */
+    CSSM_CSP_HANDLE		encryptKeyCsp;
+	#if		ST_KEYCHAIN_ENABLE
+	/* but we'll just do this so we can compile it */
+    KCItemRef			encryptKeyRef;	/* for encryptPrivKey */
+    #endif 	/* ST_KEYCHAIN_ENABLE */
+	
+    CSSM_KEY_PTR		peerPubKey;
+    CSSM_CSP_HANDLE		peerPubKeyCsp;	/* may not be needed, we figure this
+    									 * one out by trial&error, right? */
+    									 
+  	/* 
+  	 * Various cert chains stored in an SSLRef-centric way for now
+  	 * (see comments above re: SSLCertificate).
+  	 * For all three, the root is the first in the chain. 
+  	 */
+    SSLCertificate      *localCert;
+    SSLCertificate		*encryptCert;
+    SSLCertificate      *peerCert;
+    
+    /* 
+     * trusted root certs; specific to this implementation, we'll store
+     * them conveniently...these will be used as AnchorCerts in a TP
+     * call. 
+     */
+    UInt32				numTrustedCerts;
+    CSSM_DATA_PTR		trustedCerts;
+    
+    /*
+     * Keychain to which newly encountered root certs are attempted
+     * to be added. AccessCreds untyped for now.
+     */
+	#if		ST_KEYCHAIN_ENABLE
+    KCRef				newRootCertKc;
+    void				*accessCreds;
+    #endif	/* ST_KEYCHAIN_ENABLE */
+	
+    /* for symmetric cipher and RNG */
+    CSSM_CSP_HANDLE		cspHand;
+    
+    /* session-wide handles for Apple TP, CL */
+    CSSM_TP_HANDLE		tpHand;
+    CSSM_CL_HANDLE		clHand;
+    
+    /* FIXME - how will we represent this? */
+    void         		*dhAnonParams;
+    void         		*peerDHParams;
+        
+    /* context and allocator for CF */
+	CFAllocatorRef 		cfAllocatorRef;
+	CFAllocatorContext 	lCFAllocatorContext;
+
+	Boolean				allowExpiredCerts;
+	
+    #else
+    /* from SSLRef 3.0 */
+    SSLRSAPrivateKey    localKey;
+    SSLRSAPrivateKey    exportKey;
+    SSLCertificate      *localCert;
+    SSLCertificate      *peerCert;
+    SSLRSAPublicKey     peerKey;
+    SSLDHParams         dhAnonParams;
+    SSLDHParams         peerDHParams;
+    #endif	_APPLE_CDSA_
+    
+    SSLBuffer		    sessionID;
+    
+    SSLBuffer			dhPeerPublic;
+    SSLBuffer 			dhExchangePublic;
+    SSLBuffer 			dhPrivate;
+    
+    SSLBuffer			peerID;
+    SSLBuffer			resumableSession;
+    
+    CipherContext       readCipher;
+    CipherContext       writeCipher;
+    CipherContext       readPending;
+    CipherContext       writePending;
+    
+    uint16              selectedCipher;			/* currently selected */
+    const SSLCipherSpec *selectedCipherSpec;	/* ditto */
+    SSLCipherSpec		*validCipherSpecs;		/* context's valid specs */
+    unsigned			numValidCipherSpecs;	/* size of validCipherSpecs */
+    SSLHandshakeState   state;
+    
+    #ifdef	_APPLE_CDSA_
+	#if		ST_SERVER_MODE_ENABLE
+    SSLAuthenticate		clientAuth;			/* kNeverAuthenticate, etc. */
+    Boolean				tryClientAuth;
+	#endif	/* ST_SERVER_MODE_ENABLE */
+    #else
+    int                 requestClientCert;
+    #endif
+    int                 certRequested;
+    int                 certSent;
+    int                 certReceived;
+    int                 x509Requested;
+    DNListElem          *acceptableDNList;
+    
+    uint8               clientRandom[32];
+    uint8               serverRandom[32];
+    SSLBuffer   		preMasterSecret;
+    uint8               masterSecret[48];
+    
+    SSLBuffer   		shaState, md5State;
+    
+    SSLBuffer		    fragmentedMessageCache;
+    
+    int                 ssl2ChallengeLength;
+    int                 ssl2ConnectionIDLength;
+    int                 ssl2SessionMatch;
+    
+/* Record layer fields */
+    SSLBuffer    		partialReadBuffer;
+    uint32              amountRead;
+    
+/* Transport layer fields */
+    WaitingRecord       *recordWriteQueue;
+    SSLBuffer			receivedDataBuffer;
+    uint32              receivedDataPos;
+    
+    #ifdef	_APPLE_CDSA_
+    Boolean				allowAnyRoot;		// don't require known roots
+    #if		SSL_DEBUG
+    char				*rootCertName;		// if non-null, write root cert here    
+    #endif	/* SSL_DEBUG */
+    #endif	/* _APPLE_CDSA_ */
+    
+};
+
+#endif /* _SSLCTX_H_ */
diff --git a/SecureTransport/privateInc/sslerrs.h b/SecureTransport/privateInc/sslerrs.h
new file mode 100644
index 00000000..245e8232
--- /dev/null
+++ b/SecureTransport/privateInc/sslerrs.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: sslerrs.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslerrs.h    Errors SSLRef can return
+
+
+    ****************************************************************** */
+
+#ifndef _SSLERRS_H_
+#define _SSLERRS_H_ 1
+
+/*
+ * FIXME - we should eventually do away with these and just use the ones
+ * on SecureTransport.h. For now, public functions (mostly in sslctx.h)
+ * call sslErrToOsStatus() to map these to the apropriate OSStatus.
+ *
+ * If you add to this, add to errSSLxxx list in SecureTransport.h and also
+ * to the sslErrMap map in appleGlue.c.
+ */
+typedef enum
+{   SSLNoErr = 0,
+    SSLMemoryErr,
+    SSLUnsupportedErr,
+    SSLProtocolErr,
+    SSLNegotiationErr,
+    SSLFatalAlert,
+    SSLWouldBlockErr,
+    SSLIOErr,
+    SSLSessionNotFoundErr,
+    SSLConnectionClosedGraceful,
+    SSLConnectionClosedError,
+    X509CertChainInvalidErr,
+    SSLBadCert,
+    
+    /* new errors for APPLE_CDSA */
+    SSLCryptoError,
+    SSLInternalError,
+    SSLAttachFailure,				/* CSSM_ModuleAttach failure */
+    SSLDataOverflow,				/* data buffer overflow */
+    SSLUnknownRootCert,				/* valid cert chain, untrusted root */
+    SSLNoRootCert,					/* cert chain not verified by root */
+    SSLCertExpired,					/* chain had an expired cert */
+    SSLBadStateErr,					/* connection in wrong state */
+	SSLCertNotYetValid,
+	SSLConnectionClosedNoNotify,	/* server closed session with no 
+									 *     notification */
+    /* etc. */
+    
+    SSL_NoSuchError					/* no comma, get it? */
+} SSLErr;
+
+#endif
diff --git a/SecureTransport/privateInc/sslhdshk.h b/SecureTransport/privateInc/sslhdshk.h
new file mode 100644
index 00000000..786eed6b
--- /dev/null
+++ b/SecureTransport/privateInc/sslhdshk.h
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: sslhdshk.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslhdshk.h   SSL Handshake Layer
+
+    Prototypes, values, and types for the SSL handshake state machine and
+    handshake decoding routines.
+
+    ****************************************************************** */
+
+#ifndef _SSLHDSHK_H_
+#define _SSLHDSHK_H_ 72
+
+#ifndef _SSL_H_
+//#include "ssl.h"
+#endif
+
+#ifndef _CRYPTYPE_H_
+#include "cryptType.h"
+#endif
+
+#ifndef _SSLREC_H_
+#include "sslrec.h"
+#endif
+
+typedef enum
+{   SSL_hello_request = 0,
+    SSL_client_hello = 1,
+    SSL_server_hello = 2,
+    SSL_certificate = 11,
+    SSL_server_key_exchange = 12,
+    SSL_certificate_request = 13,
+    SSL_server_hello_done = 14,
+    SSL_certificate_verify = 15,
+    SSL_client_key_exchange = 16,
+    SSL_finished = 20,
+    SSL_MAGIC_no_certificate_alert = 100
+} SSLHandshakeType;
+
+typedef enum
+{   SSL_read,
+    SSL_write
+} CipherSide;
+
+typedef enum
+{   
+	SSLUninitialized = 0,				/* only valid within SSLContextAlloc */
+	HandshakeServerUninit,				/* no handshake yet */
+	HandshakeClientUninit,				/* no handshake yet */
+	SSLGracefulClose,
+    SSLErrorClose,
+	SSLNoNotifyClose,					/* server disconnected with no
+										 *   notify msg */
+    /* remainder must be consecutive */
+    HandshakeServerHello,               /* must get server hello; client hello sent */
+    HandshakeServerHelloUnknownVersion, /* Could get SSL 2 or SSL 3 server hello back */
+    HandshakeKeyExchange,               /* must get key exchange; cipher spec requires it */
+    HandshakeCertificate,               /* may get certificate or certificate request (if no cert request received yet) */
+    HandshakeHelloDone,                 /* must get server hello done; after key exchange or fixed DH parameters */
+    HandshakeClientCertificate,         /* must get certificate or no cert alert from client */
+    HandshakeClientKeyExchange,         /* must get client key exchange */
+    HandshakeClientCertVerify,          /* must get certificate verify from client */
+    HandshakeChangeCipherSpec,          /* time to change the cipher spec */
+    HandshakeFinished,                  /* must get a finished message in the new cipher spec */
+    HandshakeSSL2ClientMasterKey,
+    HandshakeSSL2ClientFinished,
+    HandshakeSSL2ServerHello,
+    HandshakeSSL2ServerVerify,
+    HandshakeSSL2ServerFinished,
+    HandshakeServerReady,               /* ready for I/O; server side */
+    HandshakeClientReady                /* ready for I/O; client side */
+} SSLHandshakeState;
+    
+typedef struct
+{   SSLHandshakeType    type;
+    SSLBuffer           contents;
+} SSLHandshakeMsg;
+
+#define SSL_Finished_Sender_Server  0x53525652
+#define SSL_Finished_Sender_Client  0x434C4E54
+
+/** sslhdshk.c **/
+typedef SSLErr (*EncodeMessageFunc)(SSLRecord *rec, SSLContext *ctx);
+SSLErr SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx);
+SSLErr SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx);
+SSLErr SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx);
+SSLErr SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx);
+
+/** hdskchgc.c **/
+SSLErr SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx);
+SSLErr SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx);
+SSLErr SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx);
+
+/** hdskcert.c **/
+SSLErr SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx);
+SSLErr SSLProcessCertificate(SSLBuffer message, SSLContext *ctx);
+SSLErr SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx);
+SSLErr SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx);
+SSLErr SSLEncodeCertificateVerify(SSLRecord *verify, SSLContext *ctx);
+SSLErr SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx);
+
+/** hdskhelo.c **/
+SSLErr SSLEncodeServerHello(SSLRecord *serverHello, SSLContext *ctx);
+SSLErr SSLProcessServerHello(SSLBuffer message, SSLContext *ctx);
+SSLErr SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx);
+SSLErr SSLProcessClientHello(SSLBuffer message, SSLContext *ctx);
+SSLErr SSLInitMessageHashes(SSLContext *ctx);
+
+/** hdskkyex.c **/
+SSLErr SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
+SSLErr SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx);
+SSLErr SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
+SSLErr SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
+
+/** hdskfini.c **/
+SSLErr SSLEncodeFinishedMessage(SSLRecord *finished, SSLContext *ctx);
+SSLErr SSLProcessFinished(SSLBuffer message, SSLContext *ctx);
+SSLErr SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx);
+SSLErr SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx);
+SSLErr SSLCalculateFinishedMessage(SSLBuffer finished, SSLBuffer shaMsgState, SSLBuffer md5MsgState, UInt32 senderID, SSLContext *ctx);
+
+/** hdskkeys.c **/
+SSLErr SSLEncodeRSAPremasterSecret(SSLContext *ctx);
+SSLErr SSLEncodeDHPremasterSecret(SSLContext *ctx);
+SSLErr SSLCalculateMasterSecret(SSLContext *ctx);
+SSLErr SSLInitPendingCiphers(SSLContext *ctx);
+#ifdef	_APPLE_CDSA_
+/* FIXME - TBD */
+SSLErr ReadyRandom(void *randCtx, SSLContext *ctx);
+#else
+SSLErr ReadyRandom(SSLRandomCtx *rsaRandom, SSLContext *ctx);
+#endif
+
+#endif /* _SSLHDSHK_H_ */
diff --git a/SecureTransport/privateInc/sslmd5.h b/SecureTransport/privateInc/sslmd5.h
new file mode 100644
index 00000000..d8d078f7
--- /dev/null
+++ b/SecureTransport/privateInc/sslmd5.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslmd5.h
+
+	Contains:	public API to low-level MD5 module
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0, based on RSA code
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#ifndef	_SSL_MD5_H_
+#define _SSL_MD5_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* these are from aglobal.h, which we really don't want to compile against */
+typedef unsigned long int UINT4;
+#define PROTO_LIST(x) x
+typedef unsigned char *POINTER;
+
+/* MD5 context. */
+typedef struct {
+  UINT4 state[4];                                   /* state (ABCD) */
+  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];                         /* input buffer */
+} MD5_CTX;
+
+void SSLMD5Init PROTO_LIST ((MD5_CTX *));
+void SSLMD5Update PROTO_LIST
+  ((MD5_CTX *, const unsigned char *, unsigned int));
+void SSLMD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSL_MD5_H_ */
diff --git a/SecureTransport/privateInc/sslrec.h b/SecureTransport/privateInc/sslrec.h
new file mode 100644
index 00000000..c477adad
--- /dev/null
+++ b/SecureTransport/privateInc/sslrec.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: sslrec.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslrec.h     SSL Record Layer
+
+    Prototypes, values, and types for the SSL record layer.
+
+    ****************************************************************** */
+
+#ifndef _SSLREC_H_
+#define _SSLREC_H_ 1
+
+#ifndef _SSL_PRIV_H_
+#include "sslPriv.h"
+#endif /* _SSL_PRIV_H_ */
+
+#ifndef	_SSLERRS_H_
+#include "sslerrs.h"
+#endif
+
+enum
+{   SSL_version_2_0_record,
+    SSL_smallest_3_0_type = 20,
+    SSL_change_cipher_spec = 20,
+    SSL_alert = 21,
+    SSL_handshake = 22,
+    SSL_application_data = 23,
+    SSL_largest_3_0_type = 23
+};
+
+typedef struct
+{   UInt8                   contentType;
+    SSLProtocolVersion      protocolVersion;
+    SSLBuffer               contents;
+} SSLRecord;
+
+#define MAX_RECORD_LENGTH   16300   /* Slightly smaller that 16384 to make room for a MAC in an SSL 2.0 3-byte header record */
+
+#define DEFAULT_BUFFER_SIZE 4096
+
+SSLErr  SSLReadRecord(SSLRecord *rec, SSLContext *ctx);
+SSLErr  SSLWriteRecord(SSLRecord rec, SSLContext *ctx);
+
+#endif /* _SSLREC_H_ */
diff --git a/SecureTransport/privateInc/sslsess.h b/SecureTransport/privateInc/sslsess.h
new file mode 100644
index 00000000..deb13304
--- /dev/null
+++ b/SecureTransport/privateInc/sslsess.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: sslsess.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslsess.h    SSL Session Interface
+
+    Prototypes for the SSL session interface functions in sslsess.c.
+
+    ****************************************************************** */
+
+#ifndef _SSLSESS_H_
+#define _SSLSESS_H_ 1
+
+#define SSL_SESSION_ID_LEN  16      /* 16 <= SSL_SESSION_ID_LEN <= 32 */
+
+SSLErr SSLAddSessionID(const SSLContext *ctx);
+SSLErr SSLGetSessionID(SSLBuffer *sessionData, const SSLContext *ctx);
+SSLErr SSLDeleteSessionID(const SSLContext *ctx);
+SSLErr SSLRetrieveSessionIDIdentifier(
+	const SSLBuffer sessionData, 
+	SSLBuffer *identifier, 
+	const SSLContext *ctx);
+SSLErr SSLRetrieveSessionIDProtocolVersion(
+	const SSLBuffer sessionID, 
+	SSLProtocolVersion *version, 
+	const SSLContext *ctx);
+SSLErr SSLInstallSessionID(const SSLBuffer sessionData, SSLContext *ctx);
+
+#endif /* _SSLSESS_H_ */
diff --git a/SecureTransport/privateInc/ssltrspt.h b/SecureTransport/privateInc/ssltrspt.h
new file mode 100644
index 00000000..80b0a2c2
--- /dev/null
+++ b/SecureTransport/privateInc/ssltrspt.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: ssltrspt.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: ssltrspt.h   SSL Transport Layer
+
+    A single fabulous prototype for the single function in ssltrspt.h
+    which isn't in ssl.h. You have found the SSLRef easter egg (such as
+    it is). SSLRef by Tim Dierks, with help from Eric Gundrum, Chris
+    Allen, Jonathan Zamick, and Michael Rutman. Thanks also to Jim
+    CastroLang, Clare Burmeister, and Tony Hughes. Also, thanks to our
+    friends at Netscape: Tom Weinstein, Jeff Weinstein, Phil Karlton, and
+    Eric Greenberg.
+
+    ****************************************************************** */
+
+#ifndef _SSLTRSPT_H_
+#define _SSLTRSPT_H_ 1
+
+#ifndef _SSL_H_
+#include "ssl.h"
+#endif
+
+#ifndef _SSLREC_H_
+#include "sslrec.h"
+#endif
+
+SSLErr QueueMessage(SSLRecord rec, SSLContext *ctx);
+
+#endif
diff --git a/SecureTransport/privateInc/sslutil.h b/SecureTransport/privateInc/sslutil.h
new file mode 100644
index 00000000..f07587b1
--- /dev/null
+++ b/SecureTransport/privateInc/sslutil.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: sslutil.h
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslutil.h    Utility functions
+
+    These functions get used in message decoding all over the place.
+
+    ****************************************************************** */
+
+#ifndef _SSLUTIL_H_
+#define _SSLUTIL_H_ 1
+
+#ifndef _SECURE_TRANSPORT_H_
+#include "SecureTransport.h"
+#endif
+
+#ifndef	_SSL_PRIV_H_
+#include "sslPriv.h"
+#endif
+
+UInt32  SSLDecodeInt(const unsigned char *p, int length);
+unsigned char *SSLEncodeInt(unsigned char *p, UInt32 value, int length);
+void    IncrementUInt64(sslUint64 *v);
+
+UInt32 SSLGetCertificateChainLength(const SSLCertificate *c);
+Boolean sslIsSessionActive(const SSLContext *ctx);
+OSStatus sslDeleteCertificateChain(SSLCertificate *certs, SSLContext *ctx);
+
+#if	SSL_DEBUG
+extern const char *protocolVersStr(SSLProtocolVersion prot);
+#endif
+
+#define SET_SSL_BUFFER(buf, d, l)   do { (buf).data = (d); (buf).length = (l); } while (0)
+
+#endif
diff --git a/SecureTransport/privateInc/st_sha.h b/SecureTransport/privateInc/st_sha.h
new file mode 100644
index 00000000..4728daa7
--- /dev/null
+++ b/SecureTransport/privateInc/st_sha.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+#ifndef SHA_H
+#define SHA_H
+
+/* NIST Secure Hash Algorithm */
+/* heavily modified from Peter C. Gutmann's implementation */
+
+/* Useful defines & typedefs */
+
+/* Possibly an unreasonable assumption, but it works */
+#ifdef WIN32
+#define LITTLE_ENDIAN  1
+#endif
+
+typedef unsigned char BYTE;
+typedef unsigned long LONG;
+
+#define SHA_BLOCKSIZE       64
+#define SHA_DIGESTSIZE      20
+
+typedef struct {
+    LONG digest[5];     /* message digest */
+    LONG count_lo, count_hi;    /* 64-bit bit count */
+    LONG data[16];      /* SHA data buffer */
+} SHA_INFO;
+
+void sha_init(SHA_INFO *);
+void sha_update(SHA_INFO *, BYTE *, int);
+void sha_final(SHA_INFO *);
+
+void sha_stream(SHA_INFO *, FILE *);
+void sha_print(SHA_INFO *);
+
+#define USE_MODIFIED_SHA 1
+
+#endif /* SHA_H */
diff --git a/SecureTransport/privateInc/symCipher.h b/SecureTransport/privateInc/symCipher.h
new file mode 100644
index 00000000..d3d2d7c3
--- /dev/null
+++ b/SecureTransport/privateInc/symCipher.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		symCipher.h
+
+	Contains:	CDSA-based symmetric cipher module
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef	_SYM_CIPHER_H_
+#define _SYM_CIPHER_H_
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _CRYPTTYPE_H_
+#include "cryptType.h"
+#endif
+
+
+/*
+ * All symmetric cipher logic goes thru these same four routines, on the 
+ * way down to CDSA
+ */
+SSLErr CDSASymmInit(
+	uint8 *key, 
+	uint8* iv, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx);
+SSLErr CDSASymmEncrypt(
+	SSLBuffer src, 
+	SSLBuffer dest, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx);
+SSLErr CDSASymmDecrypt(
+	SSLBuffer src, 
+	SSLBuffer dest, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx);
+SSLErr CDSASymmFinish(
+	CipherContext *cipherCtx, 
+	SSLContext *ctx);
+
+#endif	/* _SYM_CIPHER_H_ */
\ No newline at end of file
diff --git a/SecureTransport/secureTransport.exp b/SecureTransport/secureTransport.exp
new file mode 100644
index 00000000..69077021
--- /dev/null
+++ b/SecureTransport/secureTransport.exp
@@ -0,0 +1,21 @@
+_SSLNewContext
+_SSLDisposeContext
+_SSLGetSessionState
+_SSLSetIOFuncs
+_SSLSetProtocolVersion
+_SSLGetProtocolVersion
+_SSLSetConnection
+_SSLGetNegotiatedProtocolVersion
+_SSLSetExportable
+_SSLGetExportable
+_SSLSetAllowExpiredCerts
+_SSLGetAllowExpiredCerts
+_SSLSetAllowAnyRoot
+_SSLGetAllowAnyRoot
+_SSLGetPeerCertificates
+_SSLSetPeerID
+_SSLGetNegotiatedCipher
+_SSLHandshake
+_SSLWrite
+_SSLRead
+_SSLClose
diff --git a/SecureTransport/securetransport++.cpp b/SecureTransport/securetransport++.cpp
new file mode 100644
index 00000000..d052cde3
--- /dev/null
+++ b/SecureTransport/securetransport++.cpp
@@ -0,0 +1,302 @@
+/*
+ * 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.
+ */
+
+
+//
+// securetransport++ - C++ interface to Apple's Secure Transport layer
+//
+#include "securetransport++.h"
+#include <Security/debugging.h>
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+//
+// Construct a core object.
+// This creates the Context object and sets the I/O functions.
+//
+SecureTransportCore::SecureTransportCore() : mAtEnd(false)
+{
+    MacOSError::check(SSLNewContext(false, &mContext));
+    try {
+    	MacOSError::check(SSLSetIOFuncs(mContext, sslReadFunc, sslWriteFunc));
+        MacOSError::check(SSLSetConnection(mContext, this));
+        debug("ssl", "%p constructed", this);
+    } catch (...) {
+        SSLDisposeContext(mContext);
+        throw;
+    }
+}
+
+
+//
+// On destruction, we force a close and destroy the Context.
+//
+SecureTransportCore::~SecureTransportCore()
+{
+    SSLDisposeContext(mContext);	// ignore error (can't do anything if error)
+    debug("ssl", "%p destroyed", this);
+}
+
+
+//
+// Open initiates or continues the SSL handshake.
+// In nonblocking mode, open may return while handshake is still in
+// progress. Keep calling open until state() != errSSLWouldBlock, or
+// go directly to I/O.
+//
+void SecureTransportCore::open()
+{
+    switch (OSStatus err = SSLHandshake(mContext)) {
+    case noErr:
+    case errSSLWouldBlock:
+        debug("ssl", "%p open, state=%d", this, state());
+        return;
+    default:
+        MacOSError::throwMe(err);
+    }
+}
+
+
+//
+// Close the SSL layer if needed.
+// Note that this does nothing to the underlying I/O layer.
+//
+void SecureTransportCore::close()
+{
+    switch (state()) {
+    case kSSLHandshake:
+    case kSSLConnected:
+        debug("ssl", "%p closed", this);
+        SSLClose(mContext);
+        break;
+    default:
+        break;
+    }
+}
+
+
+//
+// Read bytes from the SSL layer. This is the standard FileDescoid
+// read function.
+// Note that if the connection is still handshaking, handshake will proceed
+// and no bytes will be read (yet).
+//
+size_t SecureTransportCore::read(void *data, size_t length)
+{
+    if (continueHandshake())
+        return 0;
+    UInt32 bytesRead;
+    switch (OSStatus err = SSLRead(mContext, data, length, &bytesRead)) {
+    case noErr:					// full read
+    case errSSLWouldBlock:		// partial read
+        return bytesRead;		// (may be zero in non-blocking scenarios)
+    case errSSLClosedGraceful:	// means end-of-data, but we may still return some
+    case errSSLClosedNoNotify:	// peer closed abruptly (not sending SSL layer shutdown)
+        if (bytesRead == 0)
+            mAtEnd = true;		// no more data - set final end-of-data flag
+        return bytesRead;
+    default:
+        MacOSError::throwMe(err);
+    }
+}
+
+
+//
+// Write bytes to the SSL layer. This is the standard FileDescoid write function.
+// Note that if the connection is still handshaking, handshake will proceed
+// and no bytes will be written (yet).
+//
+size_t SecureTransportCore::write(const void *data, size_t length)
+{
+    if (continueHandshake())
+        return 0;
+    UInt32 bytesWritten;
+    switch (OSStatus err = SSLWrite(mContext, data, length, &bytesWritten)) {
+    case noErr:
+        return bytesWritten;
+    case errSSLWouldBlock:
+        return 0;	// no data, no error, no fuss
+    default:
+        MacOSError::throwMe(err);
+    }
+}
+
+
+//
+// Continue handshake processing if necessary.
+// Returns true if handshake is in progress and not yet complete.
+//
+bool SecureTransportCore::continueHandshake()
+{
+    if (state() == kSSLHandshake) {
+        // still in handshake mode; prod it along
+        debug("ssl", "%p continuing handshake", this);
+        switch (OSStatus err = SSLHandshake(mContext)) {
+        case noErr:
+        case errSSLWouldBlock:
+            break;
+        default:
+            MacOSError::throwMe(err);
+        }
+        IFDEBUG(if (state() != kSSLHandshake) debug("ssl", "%p handshake complete", this));
+        return state() == kSSLHandshake;
+    } else
+        return false;
+}
+
+
+//
+// State access methods
+//
+SSLSessionState SecureTransportCore::state() const
+{
+    SSLSessionState state;
+    MacOSError::check(SSLGetSessionState(mContext, &state));
+    return state;
+}
+
+SSLProtocol SecureTransportCore::version() const
+{
+    SSLProtocol version;
+    MacOSError::check(SSLGetProtocolVersion(mContext, &version));
+    return version;
+}
+
+void SecureTransportCore::version(SSLProtocol version)
+{
+    MacOSError::check(SSLSetProtocolVersion(mContext, version));
+}
+    
+UInt32 SecureTransportCore::numSupportedCiphers() const
+{
+	UInt32 numCiphers;
+    MacOSError::check(SSLGetNumberSupportedCiphers(mContext, &numCiphers));
+    return numCiphers;
+}
+
+void SecureTransportCore::supportedCiphers(
+	SSLCipherSuite *ciphers, 
+	UInt32 &numCiphers) const
+{
+    MacOSError::check(SSLGetSupportedCiphers(mContext, ciphers, &numCiphers));
+}
+
+UInt32 SecureTransportCore::numEnabledCiphers() const
+{
+	UInt32 numCiphers;
+    MacOSError::check(SSLGetNumberEnabledCiphers(mContext, &numCiphers));
+    return numCiphers;
+}
+
+void SecureTransportCore::enabledCiphers(
+	SSLCipherSuite *ciphers, 
+	UInt32 &numCiphers) const
+{
+    MacOSError::check(SSLGetEnabledCiphers(mContext, ciphers, &numCiphers));
+}
+
+void SecureTransportCore::enabledCiphers(
+	SSLCipherSuite *ciphers, 
+	UInt32 numCiphers)
+{
+    MacOSError::check(SSLSetEnabledCiphers(mContext, ciphers, numCiphers));
+}
+
+bool SecureTransportCore::allowExpiredCerts() const
+{
+    Boolean allow;
+    MacOSError::check(SSLGetAllowExpiredCerts(mContext, &allow));
+    return allow;
+}
+
+void SecureTransportCore::allowExpiredCerts(bool allow)
+{
+    MacOSError::check(SSLSetAllowExpiredCerts(mContext, allow));
+}
+
+bool SecureTransportCore::allowUnknownRoots() const
+{
+    Boolean allow;
+    MacOSError::check(SSLGetAllowAnyRoot(mContext, &allow));
+    return allow;
+}
+
+void SecureTransportCore::allowUnknownRoots(bool allow)
+{
+    MacOSError::check(SSLSetAllowAnyRoot(mContext, allow));
+}
+
+
+//
+// Implement SecureTransport's read/write transport functions.
+// Note that this API is very un-UNIX in that error codes (errSSLClosedGraceful, errSSLWouldBlock)
+// are returned even though data has been produced.
+//
+OSStatus SecureTransportCore::sslReadFunc(SSLConnectionRef connection,
+    void *data, UInt32 *length)
+{
+    const SecureTransportCore *stc = reinterpret_cast<const SecureTransportCore *>(connection);
+    try {
+        size_t lengthRequested = *length;
+        *length = stc->ioRead(data, lengthRequested);
+        debug("sslconio", "%p read %ld of %ld bytes", stc, *length, lengthRequested);
+        if (*length == lengthRequested)	// full deck
+            return noErr;
+        else if (stc->ioAtEnd()) {
+            debug("sslconio", "%p end of source input, returning %ld bytes",
+                stc, *length);
+            return errSSLClosedGraceful;
+        } else
+            return errSSLWouldBlock;
+    } catch (UnixError &err) {
+        *length = 0;
+        if (err.error == ECONNRESET)
+            return errSSLClosedGraceful;
+        throw;
+    } catch (CssmCommonError &err) {
+        *length = 0;
+        return err.osStatus();
+    } catch (...) {
+        *length = 0;
+        return -1;	//@@@ generic internal error?
+    }
+}
+
+OSStatus SecureTransportCore::sslWriteFunc(SSLConnectionRef connection,
+    const void *data, UInt32 *length)
+{
+    const SecureTransportCore *stc = reinterpret_cast<const SecureTransportCore *>(connection);
+    try {
+        size_t lengthRequested = *length;
+        *length = stc->ioWrite(data, lengthRequested);
+        debug("sslconio", "%p wrote %ld of %ld bytes", stc, *length, lengthRequested);
+        return *length == lengthRequested ? noErr : errSSLWouldBlock;
+    } catch (CssmCommonError &err) {
+        *length = 0;
+        return err.osStatus();
+    } catch (...) {
+        *length = 0;
+        return -1;	//@@@ generic internal error?
+    }
+}
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/SecureTransport/securetransport++.h b/SecureTransport/securetransport++.h
new file mode 100644
index 00000000..22e15917
--- /dev/null
+++ b/SecureTransport/securetransport++.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+
+//
+// securetransport++ - C++ interface to Apple's Secure Transport layer
+//
+#ifndef _H_SECURETRANSPORTPLUSPLUS
+#define _H_SECURETRANSPORTPLUSPLUS
+
+#include <Security/ip++.h>
+#include <Security/SecureTransport.h>
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+//
+// The common-code core of a SecureTransport context and session.
+// Abstract - do not use directly.
+//
+class SecureTransportCore {
+public:
+    SecureTransportCore();
+    virtual ~SecureTransportCore();
+    
+    void open();		// open SSL (but not underlying I/O)
+    void close();		// close SSL (but not underlying I/O)
+    
+    SSLSessionState state() const;
+    
+    SSLProtocol version() const;
+    void version(SSLProtocol v);
+    
+	UInt32 numSupportedCiphers() const;
+	void supportedCiphers(SSLCipherSuite *ciphers, UInt32 &numCiphers) const;
+	
+	UInt32 numEnabledCiphers() const;
+	void enabledCiphers(SSLCipherSuite *ciphers, UInt32 &numCiphers) const;	// get
+	void enabledCiphers(SSLCipherSuite *ciphers, UInt32 numCiphers);		// set
+	
+    bool allowExpiredCerts() const;
+    void allowExpiredCerts(bool allow);
+    
+    bool allowUnknownRoots() const;
+    void allowUnknownRoots(bool allow);
+    
+    size_t read(void *data, size_t length);
+    size_t write(const void *data, size_t length);
+    bool atEnd() const		{ return mAtEnd; }
+
+protected:
+    virtual size_t ioRead(void *data, size_t length) const = 0;
+    virtual size_t ioWrite(const void *data, size_t length) const = 0;
+    virtual bool ioAtEnd() const = 0;
+    
+private:
+	static OSStatus sslReadFunc(SSLConnectionRef, void *, UInt32 *);
+	static OSStatus sslWriteFunc(SSLConnectionRef, const void *, UInt32 *);
+    
+    bool continueHandshake();
+    
+private:
+    SSLContextRef mContext;		// SecureTransport session/context object
+    bool mAtEnd;				// end-of-data flag derived from last SSLRead
+};
+
+
+//
+// This is what you use. The constructor argument is a FileDescoid object
+// of some kind, such as a FileDesc, Socket, etc.
+// Note that SecureTransport is in turn a FileDescoid object, so you can read/write
+// it in the usual fashion, and it will in turn read/write cipher data from its I/O source.
+//
+template <class IO>
+class SecureTransport : public SecureTransportCore {
+public:
+    SecureTransport(IO &ioRef) : io(ioRef) { }
+    ~SecureTransport() { close(); }
+
+    IO &io;
+
+private:
+    size_t ioRead(void *data, size_t length) const			{ return io.read(data, length); }
+    size_t ioWrite(const void *data, size_t length) const	{ return io.write(data, length); }
+    bool ioAtEnd() const									{ return io.atEnd(); }
+};
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
+
+
+#endif //_H_SECURETRANSPORTPLUSPLUS
diff --git a/SecureTransport/sha.c b/SecureTransport/sha.c
new file mode 100644
index 00000000..01d87b35
--- /dev/null
+++ b/SecureTransport/sha.c
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+
+/* NIST Secure Hash Algorithm */
+/* heavily modified by Uwe Hollerbach uh@alumni.caltech edu */
+/* from Peter C. Gutmann's implementation as found in */
+/* Applied Cryptography by Bruce Schneier */
+
+/* NIST's proposed modification to SHA of 7/11/94 may be */
+/* activated by defining USE_MODIFIED_SHA */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "st_sha.h"
+
+/* SHA f()-functions */
+
+#define f1(x,y,z)   ((x & y) | (~x & z))
+#define f2(x,y,z)   (x ^ y ^ z)
+#define f3(x,y,z)   ((x & y) | (x & z) | (y & z))
+#define f4(x,y,z)   (x ^ y ^ z)
+
+/* SHA constants */
+
+#define CONST1      0x5a827999L
+#define CONST2      0x6ed9eba1L
+#define CONST3      0x8f1bbcdcL
+#define CONST4      0xca62c1d6L
+
+/* 32-bit rotate */
+
+#define ROT32(x,n)  ((x << n) | (x >> (32 - n)))
+
+#define FUNC(n,i)                       \
+    temp = ROT32(A,5) + f##n(B,C,D) + E + W[i] + CONST##n;  \
+    E = D; D = C; C = ROT32(B,30); B = A; A = temp
+
+/* do SHA transformation */
+
+static void sha_transform(SHA_INFO *sha_info)
+{
+    int i;
+    LONG temp, A, B, C, D, E, W[80];
+
+    for (i = 0; i < 16; ++i) {
+    W[i] = sha_info->data[i];
+    }
+    for (i = 16; i < 80; ++i) {
+    W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
+#ifdef USE_MODIFIED_SHA
+    W[i] = ROT32(W[i], 1);
+#endif /* USE_MODIFIED_SHA */
+    }
+    A = sha_info->digest[0];
+    B = sha_info->digest[1];
+    C = sha_info->digest[2];
+    D = sha_info->digest[3];
+    E = sha_info->digest[4];
+#ifdef UNROLL_LOOPS
+    FUNC(1, 0);  FUNC(1, 1);  FUNC(1, 2);  FUNC(1, 3);  FUNC(1, 4);
+    FUNC(1, 5);  FUNC(1, 6);  FUNC(1, 7);  FUNC(1, 8);  FUNC(1, 9);
+    FUNC(1,10);  FUNC(1,11);  FUNC(1,12);  FUNC(1,13);  FUNC(1,14);
+    FUNC(1,15);  FUNC(1,16);  FUNC(1,17);  FUNC(1,18);  FUNC(1,19);
+
+    FUNC(2,20);  FUNC(2,21);  FUNC(2,22);  FUNC(2,23);  FUNC(2,24);
+    FUNC(2,25);  FUNC(2,26);  FUNC(2,27);  FUNC(2,28);  FUNC(2,29);
+    FUNC(2,30);  FUNC(2,31);  FUNC(2,32);  FUNC(2,33);  FUNC(2,34);
+    FUNC(2,35);  FUNC(2,36);  FUNC(2,37);  FUNC(2,38);  FUNC(2,39);
+
+    FUNC(3,40);  FUNC(3,41);  FUNC(3,42);  FUNC(3,43);  FUNC(3,44);
+    FUNC(3,45);  FUNC(3,46);  FUNC(3,47);  FUNC(3,48);  FUNC(3,49);
+    FUNC(3,50);  FUNC(3,51);  FUNC(3,52);  FUNC(3,53);  FUNC(3,54);
+    FUNC(3,55);  FUNC(3,56);  FUNC(3,57);  FUNC(3,58);  FUNC(3,59);
+
+    FUNC(4,60);  FUNC(4,61);  FUNC(4,62);  FUNC(4,63);  FUNC(4,64);
+    FUNC(4,65);  FUNC(4,66);  FUNC(4,67);  FUNC(4,68);  FUNC(4,69);
+    FUNC(4,70);  FUNC(4,71);  FUNC(4,72);  FUNC(4,73);  FUNC(4,74);
+    FUNC(4,75);  FUNC(4,76);  FUNC(4,77);  FUNC(4,78);  FUNC(4,79);
+#else /* !UNROLL_LOOPS */
+    for (i = 0; i < 20; ++i) {
+    FUNC(1,i);
+    }
+    for (i = 20; i < 40; ++i) {
+    FUNC(2,i);
+    }
+    for (i = 40; i < 60; ++i) {
+    FUNC(3,i);
+    }
+    for (i = 60; i < 80; ++i) {
+    FUNC(4,i);
+    }
+#endif /* !UNROLL_LOOPS */
+    sha_info->digest[0] += A;
+    sha_info->digest[1] += B;
+    sha_info->digest[2] += C;
+    sha_info->digest[3] += D;
+    sha_info->digest[4] += E;
+}
+
+/* HACK: OS X #defines LITTLE_ENDIAN (to 1234) in many places.... */
+#ifdef	__APPLE__
+#undef	LITTLE_ENDIAN
+#endif
+/* end hack */
+
+#ifdef LITTLE_ENDIAN
+
+/* change endianness of data */
+
+static void byte_reverse(LONG *buffer, int count)
+{
+    int i;
+    BYTE ct[4], *cp;
+
+    count /= sizeof(LONG);
+    cp = (BYTE *) buffer;
+    for (i = 0; i < count; ++i) {
+    ct[0] = cp[0];
+    ct[1] = cp[1];
+    ct[2] = cp[2];
+    ct[3] = cp[3];
+    cp[0] = ct[3];
+    cp[1] = ct[2];
+    cp[2] = ct[1];
+    cp[3] = ct[0];
+    cp += sizeof(LONG);
+    }
+}
+
+#endif /* LITTLE_ENDIAN */
+
+/* initialize the SHA digest */
+
+void sha_init(SHA_INFO *sha_info)
+{
+    sha_info->digest[0] = 0x67452301L;
+    sha_info->digest[1] = 0xefcdab89L;
+    sha_info->digest[2] = 0x98badcfeL;
+    sha_info->digest[3] = 0x10325476L;
+    sha_info->digest[4] = 0xc3d2e1f0L;
+    sha_info->count_lo = 0L;
+    sha_info->count_hi = 0L;
+}
+
+/* update the SHA digest */
+
+void sha_update(SHA_INFO *sha_info, BYTE *buffer, int count)
+{
+    if ((sha_info->count_lo + ((LONG) count << 3)) < sha_info->count_lo) {
+    ++sha_info->count_hi;
+    }
+    sha_info->count_lo += (LONG) count << 3;
+    sha_info->count_hi += (LONG) count >> 29;
+    while (count >= SHA_BLOCKSIZE) {
+    memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
+#ifdef LITTLE_ENDIAN
+    byte_reverse(sha_info->data, SHA_BLOCKSIZE);
+#endif /* LITTLE_ENDIAN */
+    sha_transform(sha_info);
+    buffer += SHA_BLOCKSIZE;
+    count -= SHA_BLOCKSIZE;
+    }
+    memcpy(sha_info->data, buffer, count);
+}
+
+/* finish computing the SHA digest */
+
+void sha_final(SHA_INFO *sha_info)
+{
+    int count;
+    LONG lo_bit_count, hi_bit_count;
+
+    lo_bit_count = sha_info->count_lo;
+    hi_bit_count = sha_info->count_hi;
+    count = (int) ((lo_bit_count >> 3) & 0x3f);
+    ((BYTE *) sha_info->data)[count++] = 0x80;
+    if (count > 56) {
+    memset((BYTE *) &sha_info->data + count, 0, 64 - count);
+#ifdef LITTLE_ENDIAN
+    byte_reverse(sha_info->data, SHA_BLOCKSIZE);
+#endif /* LITTLE_ENDIAN */
+    sha_transform(sha_info);
+    memset(&sha_info->data, 0, 56);
+    } else {
+    memset((BYTE *) &sha_info->data + count, 0, 56 - count);
+    }
+#ifdef LITTLE_ENDIAN
+    byte_reverse(sha_info->data, SHA_BLOCKSIZE);
+#endif /* LITTLE_ENDIAN */
+    sha_info->data[14] = hi_bit_count;
+    sha_info->data[15] = lo_bit_count;
+    sha_transform(sha_info);
+#ifdef LITTLE_ENDIAN
+    byte_reverse(sha_info->digest, SHA_DIGESTSIZE);
+#endif /* LITTLE_ENDIAN */
+}
+
+/* compute the SHA digest of a FILE stream */
+
+#define BLOCK_SIZE  8192
+
+void sha_stream(SHA_INFO *sha_info, FILE *fin)
+{
+    int i;
+    BYTE data[BLOCK_SIZE];
+
+    sha_init(sha_info);
+    while ((i = fread(data, 1, BLOCK_SIZE, fin)) > 0) {
+    sha_update(sha_info, data, i);
+    }
+    sha_final(sha_info);
+}
+
+/* print a SHA digest */
+
+void sha_print(SHA_INFO *sha_info)
+{
+    printf("%08lx %08lx %08lx %08lx %08lx\n",
+    sha_info->digest[0], sha_info->digest[1], sha_info->digest[2],
+    sha_info->digest[3], sha_info->digest[4]);
+}
diff --git a/SecureTransport/ssl2map.c b/SecureTransport/ssl2map.c
new file mode 100644
index 00000000..3737d7cc
--- /dev/null
+++ b/SecureTransport/ssl2map.c
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: ssl2map.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: ssl2map.c    Maps SSL 2 cipher kinds to SSL 3 cipher suites
+
+    We use the SSL 3 CipherSuites to look up ciphers, hashes, etc; thus,
+    this table maps two-byte SSL 3 CipherSuite values to three-byte SSL 2
+    CipherKind values.
+
+    ****************************************************************** */
+
+#ifndef	_SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _CRYPTTYPE_H_
+#include "cryptType.h"
+#endif
+
+const SSLCipherMapping SSL2CipherMap[] =
+{   {   SSL2_RC4_128_WITH_MD5, SSL_RSA_WITH_RC4_128_MD5 },
+    {   SSL2_RC4_128_EXPORT_40_WITH_MD5, SSL_RSA_EXPORT_WITH_RC4_40_MD5 },
+    {   SSL2_RC2_128_CBC_WITH_MD5, SSL_RSA_WITH_RC2_CBC_MD5 },
+    {   SSL2_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 },
+    {   SSL2_IDEA_128_CBC_WITH_MD5, SSL_RSA_WITH_IDEA_CBC_MD5 },
+    {   SSL2_DES_64_CBC_WITH_MD5, SSL_RSA_WITH_DES_CBC_MD5 },
+    {   SSL2_DES_192_EDE3_CBC_WITH_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5}
+};
+
+const int SSL2CipherMapCount = sizeof(SSL2CipherMap) / sizeof(SSLCipherMapping);
diff --git a/SecureTransport/ssl2mesg.c b/SecureTransport/ssl2mesg.c
new file mode 100644
index 00000000..f879e5ab
--- /dev/null
+++ b/SecureTransport/ssl2mesg.c
@@ -0,0 +1,897 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: ssl2mesg.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: ssl2mesg.c   Message encoding and decoding functions for SSL 2
+
+    The necessary message encoding and decoding for all SSL 2 handshake
+    messages.
+
+    ****************************************************************** */
+
+#ifndef _SSL_H_
+#include "ssl.h"
+#endif
+
+#ifndef _SSL2_H_
+#include "ssl2.h"
+#endif
+
+#ifndef _SSLREC_H_
+#include "sslrec.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLSESS_H_
+#include "sslsess.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef	_CIPHER_SPECS_H_
+#include "cipherSpecs.h"
+#endif
+
+#ifndef	_APPLE_CDSA_H_
+#include "appleCdsa.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#include <string.h>
+
+SSLErr
+SSL2ProcessClientHello(SSLBuffer msg, SSLContext *ctx)
+{   SSLErr              err;
+    UInt8               *progress, *cipherList;
+    int                 i, j, cipherKindCount, sessionIDLen, challengeLen;
+    SSL2CipherKind      cipherKind;
+    SSLCipherSuite      matchingCipher, selectedCipher;
+    SSLProtocolVersion  version;
+    
+    if (msg.length < 27) {
+		errorLog0("SSL2ProcessClientHello: msg len error 1\n");
+        return ERR(SSLProtocolErr);
+    }
+    
+    progress = msg.data;
+    
+    version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
+    /* FIXME - ensure client isn't slipping under a SSL_Version_3_0_Only spec... */
+    if (ctx->negProtocolVersion == SSL_Version_Undetermined)
+    {   if (version > SSL_Version_3_0)
+            version = SSL_Version_3_0;
+        #if LOG_NEGOTIATE
+        dprintf1("===SSL2 server: negVersion was undetermined; is %s\n",
+        	protocolVersStr(version));
+        #endif
+        ctx->negProtocolVersion = version;
+    }
+    else if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello)
+    {   if (version < SSL_Version_3_0) {
+			errorLog0("SSL2ProcessClientHello: version error\n");
+            return ERR(SSLProtocolErr);
+        }
+        #if LOG_NEGOTIATE
+        dprintf0("===SSL2 server: negVersion was 3_0_With_2_0_Hello; is 3_0\n");
+        #endif
+        ctx->negProtocolVersion = SSL_Version_3_0;
+    }
+    
+    progress += 2;
+    cipherKindCount = SSLDecodeInt(progress, 2);
+    progress += 2;
+    if (cipherKindCount % 3 != 0) {
+		errorLog0("SSL2ProcessClientHello: cipherKindCount error\n");
+        return ERR(SSLProtocolErr);
+    }
+    cipherKindCount /= 3;
+    sessionIDLen = SSLDecodeInt(progress, 2);
+    progress += 2;
+    challengeLen = SSLDecodeInt(progress, 2);
+    progress += 2;
+    
+    if (msg.length != 8 + 3*cipherKindCount + sessionIDLen + challengeLen ||
+        (sessionIDLen != 0 && sessionIDLen != 16) ||
+        challengeLen < 16 || challengeLen > 32 ) {
+		errorLog0("SSL2ProcessClientHello: msg len error 2\n");
+        return ERR(SSLProtocolErr);
+    }
+    cipherList = progress;
+    selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
+
+    if (ctx->negProtocolVersion == SSL_Version_3_0)        /* If we're negotiating an SSL 3.0 session, use SSL 3.0 suites first */
+    {   for (i = 0; i < cipherKindCount; i++)
+        {   cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
+            progress += 3;
+            if (selectedCipher != SSL_NO_SUCH_CIPHERSUITE)
+                continue;
+            if ((((UInt32)cipherKind) & 0xFF0000) != 0)
+                continue;       /* Skip SSL 2 suites */
+            matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
+            for (j = 0; j<ctx->numValidCipherSpecs; j++)
+                if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
+                {   selectedCipher = matchingCipher;
+                    break;
+                }
+        }
+    }
+    
+    progress = cipherList;
+    for (i = 0; i < cipherKindCount; i++)
+    {   cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
+        progress += 3;
+        if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)  /* After we find one, just keep advancing progress past the unused ones */
+        {   if ((((UInt32)cipherKind) & 0xFF0000) != 0) /* If it's a real SSL2 spec, look for it in the list */
+            {   matchingCipher = SSL_NO_SUCH_CIPHERSUITE;
+                for (j = 0; j < SSL2CipherMapCount; j++)
+                    if (cipherKind == SSL2CipherMap[j].cipherKind)
+                    {   matchingCipher = SSL2CipherMap[j].cipherSuite;
+                        break;
+                    }
+            }
+            else    /* if the first byte is zero, it's an encoded SSL 3 CipherSuite */
+                matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
+            if (matchingCipher != SSL_NO_SUCH_CIPHERSUITE)
+                for (j = 0; j < ctx->numValidCipherSpecs; j++)   
+                    if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
+                    {   selectedCipher = matchingCipher;
+                        break;
+                    }
+        }
+    }
+    if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
+        return ERR(SSLNegotiationErr);
+    
+    ctx->selectedCipher = selectedCipher;
+    err = FindCipherSpec(ctx);
+    if(err != 0) {
+        return err;
+    }
+    if (sessionIDLen > 0 && ctx->peerID.data != 0)
+    {   /* Don't die on error; just treat it as an uncacheable session */
+        ERR(err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx));
+        if (err == 0)
+            memcpy(ctx->sessionID.data, progress, sessionIDLen);
+    }
+    progress += sessionIDLen;
+    
+    ctx->ssl2ChallengeLength = challengeLen;
+    memset(ctx->clientRandom, 0, 32);
+    memcpy(ctx->clientRandom+32 - challengeLen, progress, challengeLen);
+    progress += challengeLen;
+    CASSERT(progress == msg.data + msg.length);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2EncodeClientHello(SSLBuffer *msg, SSLContext *ctx)
+{   SSLErr          err;
+    UInt8           *progress;
+    int             i, j, useSSL3Ciphers, totalCipherCount;
+    int             sessionIDLen;
+    UInt16          version;
+    SSLBuffer       sessionIdentifier, randomData;
+    
+    switch (ctx->negProtocolVersion)
+    {   case SSL_Version_Undetermined:
+        case SSL_Version_3_0_With_2_0_Hello:
+        	/* go for it, see if server can handle upgrading */
+           	useSSL3Ciphers = 1;
+            version = SSL_Version_3_0;
+            break;
+        case SSL_Version_2_0:
+            useSSL3Ciphers = 0;
+            version = SSL_Version_2_0;
+            break;
+        case SSL_Version_3_0_Only:
+        case SSL_Version_3_0:
+        default:
+            ASSERTMSG("Bad protocol version for sending SSL 2 Client Hello");
+            break;
+    }
+ 	#if LOG_NEGOTIATE
+	dprintf1("===SSL client: proclaiming %s capable\n", 
+		protocolVersStr((SSLProtocolVersion)version));
+	#endif
+    
+    if (useSSL3Ciphers != 0)
+        totalCipherCount = ctx->numValidCipherSpecs;
+    else
+        totalCipherCount = 0;
+        
+    for (i = 0; i < SSL2CipherMapCount; i++)
+        for (j = 0; j < ctx->numValidCipherSpecs; j++)
+            if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
+            {   totalCipherCount++;
+                break;
+            }
+    
+    sessionIDLen = 0;
+    sessionIdentifier.data = 0;
+    if (ctx->resumableSession.data != 0)
+    {   if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
+            return err;
+        sessionIDLen = sessionIdentifier.length;
+    }
+    
+/* msg length = 9 + 3 * totalCipherCount + sessionIDLen + 16 bytes of challenge
+ *  Use exactly 16 bytes of challenge because Netscape products have a bug
+ *  that requires this length
+ */ 
+    if (ERR(err = SSLAllocBuffer(msg, 9 + (3*totalCipherCount) + sessionIDLen + 16, &ctx->sysCtx)) != 0)
+    {   ERR(SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx));
+        return err;
+    }
+    
+    progress = msg->data;
+    *progress++ = ssl2_mt_client_hello;
+    progress = SSLEncodeInt(progress, version, 2);
+    progress = SSLEncodeInt(progress, 3*totalCipherCount, 2);
+    progress = SSLEncodeInt(progress, sessionIDLen, 2);
+    progress = SSLEncodeInt(progress, 16, 2);
+    
+/* If we can send SSL3 ciphers, encode the two-byte cipher specs into three-byte
+ *  CipherKinds which have a leading 0.
+ */
+    if (useSSL3Ciphers != 0)
+        for (i = 0; i < ctx->numValidCipherSpecs; i++)
+            progress = SSLEncodeInt(progress, ctx->validCipherSpecs[i].cipherSpec, 3);
+    
+/* Now send those SSL2 specs for which we have implementations */
+    for (i = 0; i < SSL2CipherMapCount; i++)
+        for (j = 0; j < ctx->numValidCipherSpecs; j++)
+            if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
+            {   progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
+                break;
+            }
+    
+    if (sessionIDLen > 0)
+    {   memcpy(progress, sessionIdentifier.data, sessionIDLen);
+        progress += sessionIDLen;
+        ERR(SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx));
+    }
+    
+    randomData.data = progress;
+    randomData.length = 16;
+    #ifdef	_APPLE_CDSA_
+    if ((err = sslRand(ctx, &randomData)) != 0)
+    #else
+    if (ERR(err = ctx->sysCtx.random(randomData, ctx->sysCtx.randomRef)) != 0)
+    #endif
+    {   ERR(SSLFreeBuffer(msg, &ctx->sysCtx));
+        return err;
+    }
+    progress += 16;
+    
+/* Zero out the first 16 bytes of clientRandom, and store the challenge in the
+    second 16 bytes */
+    memset(ctx->clientRandom, 0, 16);
+    memcpy(ctx->clientRandom+16, randomData.data, 16);
+    ctx->ssl2ChallengeLength = 16;
+    
+    CASSERT(progress == msg->data + msg->length);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2ProcessClientMasterKey(SSLBuffer msg, SSLContext *ctx)
+{   SSLErr          err;
+    SSL2CipherKind  cipherKind;
+    SSLBuffer       secretData;
+    int             clearLength, encryptedLength, keyArgLength;
+    UInt32    		secretLength, localKeyModulusLen;
+    UInt8           *progress;
+    
+    if (msg.length < 9) {
+		errorLog0("SSL2ProcessClientMasterKey: msg.length error 1\n");
+        return ERR(SSLProtocolErr);
+    }
+    CASSERT(ctx->protocolSide == SSL_ServerSide);
+    
+    progress = msg.data;
+    cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
+    progress += 3;
+    clearLength = SSLDecodeInt(progress, 2);
+    progress += 2;
+    encryptedLength = SSLDecodeInt(progress, 2);
+    progress += 2;
+    keyArgLength = SSLDecodeInt(progress, 2);
+    progress += 2;
+    
+    if (msg.length != 9 + clearLength + encryptedLength + keyArgLength) {
+		errorLog0("SSL2ProcessClientMasterKey: msg.length error 2\n");
+        return ERR(SSLProtocolErr);
+    }
+    
+/* Master key == CLEAR_DATA || SECRET_DATA */
+    memcpy(ctx->masterSecret, progress, clearLength);
+    progress += clearLength;
+
+#if RSAREF
+    localKeyModulusLen = (ctx->localKey.bits + 7)/8;
+#elif BSAFE
+    {   A_RSA_KEY   *keyInfo;
+        int         rsaResult;
+        
+        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->localKey, KI_RSAPublic)) != 0)
+            return SSLUnknownErr;
+        localKeyModulusLen = keyInfo->modulus.len;
+    }
+#elif	_APPLE_CDSA_
+	CASSERT(ctx->encryptPrivKey != NULL);
+	localKeyModulusLen = sslKeyLengthInBytes(ctx->encryptPrivKey);
+#else
+#error No Asymmetric crypto
+#endif /* RSAREF / BSAFE */
+
+    if (encryptedLength != localKeyModulusLen) {
+		errorLog0("SSL2ProcessClientMasterKey: encryptedLength error 1\n");
+        return ERR(SSLProtocolErr);
+	}
+	
+/* Allocate enough room to hold any decrypted value */
+    if (ERR(err = SSLAllocBuffer(&secretData, encryptedLength, &ctx->sysCtx)) != 0)
+        return err;
+    
+#if RSAREF
+/* Replace this with code to do decryption at lower level & check PKCS1 padding
+    for rollback attack */
+    if ((RSAPrivateDecrypt(secretData.data, &secretLength, progress, encryptedLength, &ctx->localKey)) != 0)
+    {   ERR(err = SSLFreeBuffer(&secretData, &ctx->sysCtx));
+        return ERR(SSLUnknownErr);
+    }
+#elif BSAFE
+    {   B_ALGORITHM_OBJ     rsa;
+        B_ALGORITHM_METHOD  *chooser[] = { &AM_RSA_CRT_DECRYPT, 0 };
+        int                 rsaResult;
+        unsigned int        decryptLen;
+        
+        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPrivate, 0)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_DecryptInit(rsa, ctx->localKey, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_DecryptUpdate(rsa, secretData.data, &decryptLen, encryptedLength,
+                    progress, encryptedLength, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        secretLength = decryptLen;
+        if ((rsaResult = B_DecryptFinal(rsa, secretData.data+secretLength,
+                    &decryptLen, encryptedLength-secretLength, 0, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        secretLength += decryptLen;
+        B_DestroyAlgorithmObject(&rsa);
+    }
+#elif	_APPLE_CDSA_
+	/* 
+	 * note we use encryptPrivKey, not signingPrivKey - this really is 
+	 * a decrypt op. Servers have to be configured with valid encryption cert
+	 * chain to work with SSL2.
+	 */
+	err = sslRsaDecrypt(ctx,
+		ctx->encryptPrivKey,
+		ctx->encryptKeyCsp,
+		progress, 
+		encryptedLength,
+		secretData.data,
+		encryptedLength,	// same length for both...? 
+		&secretLength);
+	if(err) {
+		SSLFreeBuffer(&secretData, &ctx->sysCtx);
+		return err;
+	}
+#endif /* RSAREF / BSAFE */
+    
+    progress += encryptedLength;
+    
+    if (clearLength + secretLength != ctx->selectedCipherSpec->cipher->keySize) {
+    	errorLog0("SSL2ProcessClientMasterKey: length error 3\n");
+        return ERR(SSLProtocolErr);
+    }
+    memcpy(ctx->masterSecret + clearLength, secretData.data, secretLength);
+    if (ERR(err = SSLFreeBuffer(&secretData, &ctx->sysCtx)) != 0)
+        return err;
+    
+    if (keyArgLength != ctx->selectedCipherSpec->cipher->ivSize) {
+    	errorLog0("SSL2ProcessClientMasterKey: length error 4\n");
+        return ERR(SSLProtocolErr);
+    }
+    
+/* Stash the IV after the master key in master secret storage */
+    memcpy(ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize, progress, keyArgLength);
+    progress += keyArgLength;
+    CASSERT(progress = msg.data + msg.length);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2EncodeClientMasterKey(SSLBuffer *msg, SSLContext *ctx)
+{   SSLErr              err;
+    int                 length, i, clearLen;
+    UInt32        		outputLen, peerKeyModulusLen;
+    SSLBuffer           keyData;
+    UInt8               *progress;
+    #ifndef	_APPLE_CDSA_
+    SSLRandomCtx        rsaRandom;
+    int                 rsaResult;
+	#endif
+	
+#if RSAREF
+    peerKeyModulusLen = (ctx->peerKey.bits + 7)/8;
+#elif BSAFE
+    {   A_RSA_KEY   *keyInfo;
+        int         rsaResult;
+        
+        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->peerKey, KI_RSAPublic)) != 0)
+            return SSLUnknownErr;
+        peerKeyModulusLen = keyInfo->modulus.len;
+    }
+#elif	_APPLE_CDSA_
+	peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
+#endif /* RSAREF / BSAFE */
+
+/* Length is 10 + clear key size + encrypted output size + iv size */
+    length = 10;
+    clearLen = ctx->selectedCipherSpec->cipher->keySize - ctx->selectedCipherSpec->cipher->secretKeySize;
+    length += clearLen;
+    length += peerKeyModulusLen;
+    length += ctx->selectedCipherSpec->cipher->ivSize;
+    
+    if (ERR(err = SSLAllocBuffer(msg, length, &ctx->sysCtx)) != 0)
+        return err;
+    progress = msg->data;
+    *progress++ = ssl2_mt_client_master_key;
+    for (i = 0; i < SSL2CipherMapCount; i++)
+        if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
+            break;
+    CASSERT(i < SSL2CipherMapCount);
+	#if LOG_NEGOTIATE
+	dprintf1("===SSL2EncodeClientMasterKey: sending cipherKind 0x%x\n", 
+		SSL2CipherMap[i].cipherKind);
+	#endif
+    progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
+    progress = SSLEncodeInt(progress, clearLen, 2);
+    progress = SSLEncodeInt(progress, peerKeyModulusLen, 2);
+    progress = SSLEncodeInt(progress, ctx->selectedCipherSpec->cipher->ivSize, 2);
+    
+    /* Generate the keying material; we need enough data for the key and IV */
+    keyData.data = ctx->masterSecret;
+    keyData.length = ctx->selectedCipherSpec->cipher->keySize + ctx->selectedCipherSpec->cipher->ivSize;
+    CASSERT(keyData.length <= 48);   /* Must be able to store it in the masterSecret array */
+    #ifdef	_APPLE_CDSA_
+    if ((err = sslRand(ctx, &keyData)) != 0)
+    #else
+    if (ERR(err = ctx->sysCtx.random(keyData, ctx->sysCtx.randomRef)) != 0)
+    #endif
+        return err;
+    
+    memcpy(progress, ctx->masterSecret, clearLen);
+    progress += clearLen;
+    
+    #ifndef	_APPLE_CDSA_
+    if (ERR(err = ReadyRandom(&rsaRandom, ctx)) != 0)
+        return err;
+    #endif
+    
+/* Replace this with code to do encryption at lower level & set PKCS1 padding
+    for rollback attack */
+#if RSAREF
+    if ((rsaResult = RSAPublicEncrypt(progress, &outputLen,
+                                ctx->masterSecret + clearLen,
+                                ctx->selectedCipherSpec->cipher->keySize - clearLen,
+                                &ctx->peerKey,&rsaRandom)) != 0)
+    {   R_RandomFinal(&rsaRandom);
+        return ERR(SSLUnknownErr);
+    }
+#elif BSAFE
+    {   B_ALGORITHM_OBJ     rsa;
+        B_ALGORITHM_METHOD  *chooser[] = { &AM_RSA_ENCRYPT, 0 };
+        unsigned int        encryptedOut;
+        
+        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_EncryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        if ((rsaResult = B_EncryptUpdate(rsa, progress,
+                    &encryptedOut, peerKeyModulusLen, ctx->masterSecret + clearLen,
+                    ctx->selectedCipherSpec->cipher->keySize - clearLen,
+                    rsaRandom, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen = encryptedOut;
+        if ((rsaResult = B_EncryptFinal(rsa, progress+outputLen,
+                    &encryptedOut, peerKeyModulusLen-outputLen, rsaRandom, NO_SURR)) != 0)
+            return SSLUnknownErr;
+        outputLen += encryptedOut;
+        B_DestroyAlgorithmObject(&rsa);
+    }
+#elif	_APPLE_CDSA_
+	/* 
+	 * encrypt only the secret key portion of masterSecret, starting at
+	 * clearLen bytes
+	 */
+	err = sslRsaEncrypt(ctx,
+		ctx->peerPubKey,
+		ctx->peerPubKeyCsp,		// XX - maybe cspHand
+		ctx->masterSecret + clearLen,
+		ctx->selectedCipherSpec->cipher->keySize - clearLen,
+		progress, 
+		peerKeyModulusLen,
+		&outputLen);
+	if(err) {
+		return err;
+	}
+#endif
+
+    progress += outputLen;
+    
+#if RSAREF
+    R_RandomFinal(&rsaRandom);
+#elif BSAFE
+    B_DestroyAlgorithmObject(&rsaRandom);
+#endif
+        
+    /* copy clear IV to msg buf */
+    memcpy(progress, ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize,
+            ctx->selectedCipherSpec->cipher->ivSize);
+    progress += ctx->selectedCipherSpec->cipher->ivSize;
+    
+    CASSERT(progress == msg->data + msg->length);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2ProcessClientFinished(SSLBuffer msg, SSLContext *ctx)
+{   if (msg.length != ctx->sessionID.length) {
+    	errorLog0("SSL2ProcessClientFinished: length error\n");
+        return ERR(SSLProtocolErr);
+    }
+    if (memcmp(msg.data, ctx->serverRandom, ctx->ssl2ConnectionIDLength) != 0) {
+    	errorLog0("SSL2ProcessClientFinished: data compare error\n");
+        return ERR(SSLProtocolErr);
+	}    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2EncodeClientFinished(SSLBuffer *msg, SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (ERR(err = SSLAllocBuffer(msg, ctx->ssl2ConnectionIDLength+1, &ctx->sysCtx)) != 0)
+        return err;
+    msg->data[0] = ssl2_mt_client_finished;
+    memcpy(msg->data+1, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2ProcessServerHello(SSLBuffer msg, SSLContext *ctx)
+{   SSLErr              err;
+    SSL2CertTypeCode    certType;
+    int                 sessionIDMatch, certLen, cipherSpecsLen, connectionIDLen;
+    int                 i, j;
+    SSL2CipherKind      cipherKind;
+	#ifndef	__APPLE__
+    SSLBuffer           certBuf;
+	#endif
+    SSLCertificate      *cert;
+    SSLCipherSuite      matchingCipher = 0;		// avoid compiler warning
+    SSLCipherSuite      selectedCipher;
+    UInt8               *progress;
+    SSLProtocolVersion  version;
+    
+    if (msg.length < 10) {
+    	errorLog0("SSL2ProcessServerHello: length error\n");
+        return ERR(SSLProtocolErr);
+    }
+    progress = msg.data;
+    
+    sessionIDMatch = *progress++;
+    certType = (SSL2CertTypeCode)*progress++;
+    version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
+    progress += 2;
+    if (version != SSL_Version_2_0) {
+    	errorLog0("SSL2ProcessServerHello: version error\n");
+        return ERR(SSLProtocolErr);
+    }
+    ctx->negProtocolVersion = version;
+    #if LOG_NEGOTIATE
+    dprintf0("===SSL2 client: negVersion is 2_0\n");
+    #endif
+    certLen = SSLDecodeInt(progress, 2);
+    progress += 2;
+    cipherSpecsLen = SSLDecodeInt(progress, 2);
+    progress += 2;
+    connectionIDLen = SSLDecodeInt(progress, 2);
+    progress += 2;
+    
+    if (connectionIDLen < 16 || connectionIDLen > 32 || cipherSpecsLen % 3 != 0 ||
+        (msg.length != 10 + certLen + cipherSpecsLen + connectionIDLen) )
+        return ERR(SSLProtocolErr);
+    if (sessionIDMatch != 0)
+    {   if (certLen != 0 || cipherSpecsLen != 0 /* || certType != 0 */ )
+            return ERR(SSLProtocolErr);
+        ctx->ssl2SessionMatch = 1;
+        
+        ctx->ssl2ConnectionIDLength = connectionIDLen;
+        memcpy(ctx->serverRandom, progress, connectionIDLen);
+        progress += connectionIDLen;
+    }
+    else
+    {   if (certType != ssl2_ct_x509_certificate)
+            return ERR(SSLNegotiationErr);
+        cipherSpecsLen /= 3;
+        
+		#ifdef	__APPLE__
+ 		cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
+		if(cert == NULL) {
+			return SSLMemoryErr;
+		}
+		#else
+        if (ERR(err = SSLAllocBuffer(&certBuf, sizeof(SSLCertificate), &ctx->sysCtx)) != 0)
+            return err;
+        cert = (SSLCertificate*)certBuf.data;
+		#endif
+        cert->next = 0;
+        if (ERR(err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
+        {   
+			#ifdef	__APPLE__
+			sslFree(cert);
+			#else
+			ERR(SSLFreeBuffer(&certBuf, &ctx->sysCtx));
+			#endif
+            return err;
+        }
+        memcpy(cert->derCert.data, progress, certLen);
+        progress += certLen;
+        #ifndef	_APPLE_CDSA_
+        /* not necessary */
+        if (ERR(err = ASNParseX509Certificate(cert->derCert, &cert->cert, ctx)) != 0)
+        {   ERR(SSLFreeBuffer(&cert->derCert, &ctx->sysCtx));
+            ERR(SSLFreeBuffer(&certBuf, &ctx->sysCtx));
+            return err;
+        }
+        #endif
+        ctx->peerCert = cert;
+        #ifdef	_APPLE_CDSA_
+        /* This cert never gets verified in original SSLRef3 code... */
+    	if((err = sslVerifyCertChain(ctx, ctx->peerCert)) != 0) {
+    		return err;
+    	}
+        if((err = sslPubKeyFromCert(ctx, 
+        	&cert->derCert, 
+        	&ctx->peerPubKey,
+        	&ctx->peerPubKeyCsp)) != 0)
+        #else
+        if (ERR(err = X509ExtractPublicKey(&cert->cert.pubKey, &ctx->peerKey)) != 0)
+        #endif
+            return err;
+        
+        selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
+        for (i = 0; i < cipherSpecsLen; i++)
+        {   cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
+            progress += 3;
+            //dprintf1("ssl2: server supports cipherKind 0x%x\n", (UInt32)cipherKind);
+            if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)  /* After we find one, just keep advancing progress past the unused ones */
+            {   for (j = 0; j < SSL2CipherMapCount; j++)
+                    if (cipherKind == SSL2CipherMap[j].cipherKind)
+                    {   matchingCipher = SSL2CipherMap[j].cipherSuite;
+                        break;
+                    }
+                for (j = 0; j < ctx->numValidCipherSpecs; j++)   
+                    if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
+                    {   selectedCipher = matchingCipher;
+                        break;
+                    }
+            }
+        }
+        if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
+            return ERR(SSLNegotiationErr);
+		#if LOG_NEGOTIATE
+		dprintf1("===SSL2 client: selectedCipher 0x%x\n", 
+			selectedCipher);
+		#endif
+        
+        ctx->selectedCipher = selectedCipher;
+        if (ERR(err = FindCipherSpec(ctx)) != 0) {
+            return err;
+        }
+        ctx->ssl2ConnectionIDLength = connectionIDLen;
+        memcpy(ctx->serverRandom, progress, connectionIDLen);
+        progress += connectionIDLen;
+    }
+    
+    CASSERT(progress == msg.data + msg.length);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2EncodeServerHello(SSLBuffer *msg, SSLContext *ctx)
+{   SSLErr              err;
+    SSLCertificate      *cert;
+    SSLBuffer           randomData;
+    UInt8               *progress;
+    int                 i;
+    
+    /* Create the connection ID */
+    ctx->ssl2ConnectionIDLength = SSL2_CONNECTION_ID_LENGTH;
+    randomData.data = ctx->serverRandom;
+    randomData.length = ctx->ssl2ConnectionIDLength;
+    #ifdef	_APPLE_CDSA_
+    if ((err = sslRand(ctx, &randomData)) != 0)
+    #else
+    if (ERR(err = ctx->sysCtx.random(randomData, ctx->sysCtx.randomRef)) != 0)
+    #endif
+        return err;
+        
+    if (ctx->ssl2SessionMatch != 0)
+    {   if (ERR(err = SSLAllocBuffer(msg, 11 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
+            return err;
+        progress = msg->data;
+        *progress++ = ssl2_mt_server_hello;
+        *progress++ = ctx->ssl2SessionMatch;
+        *progress++ = 0;    /* cert type */
+        progress = SSLEncodeInt(progress, ctx->negProtocolVersion, 2);
+        progress = SSLEncodeInt(progress, 0, 2);    /* cert len */
+        progress = SSLEncodeInt(progress, 0, 2);    /* cipherspecs len */
+        progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
+        memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
+        progress += ctx->ssl2ConnectionIDLength;
+    }
+    else
+    {   /* First, find the last cert in the chain; it's the one we'll send */
+    
+    	#if	_APPLE_CDSA_
+    	/*
+    	 * For Apple, we require an encryptCert here - we'll be encrypting
+    	 * with it, after all.
+    	 */
+    	if(ctx->encryptCert == NULL) {
+    		errorLog0("SSL2EncodeServerHello: No encryptCert!\n");
+    		return SSLBadStateErr;
+    	}
+    	cert = ctx->encryptCert;
+    	#else
+        CASSERT(ctx->localCert != 0);
+        cert = ctx->localCert;
+        #endif	_APPLE_CDSA_
+        
+        while (cert->next != 0)
+            cert = cert->next;
+        
+        if (ERR(err = SSLAllocBuffer(msg, 11 + cert->derCert.length + 3 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
+            return err;
+        progress = msg->data;
+        *progress++ = ssl2_mt_server_hello;
+        *progress++ = ctx->ssl2SessionMatch;
+        *progress++ = ssl2_ct_x509_certificate; /* cert type */
+	 	#if LOG_NEGOTIATE
+		dprintf1("===SSL2 server: sending vers info %s\n", 
+			protocolVersStr((SSLProtocolVersion)ctx->negProtocolVersion));
+		#endif
+        progress = SSLEncodeInt(progress, ctx->negProtocolVersion, 2);
+        progress = SSLEncodeInt(progress, cert->derCert.length, 2);
+        progress = SSLEncodeInt(progress, 3, 2);    /* cipherspecs len */
+        progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
+        memcpy(progress, cert->derCert.data, cert->derCert.length);
+        progress += cert->derCert.length;
+        for (i = 0; i < SSL2CipherMapCount; i++)
+            if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
+                break;
+        CASSERT(i < SSL2CipherMapCount);
+        progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
+     	dprintf1("ssl2: server specifying cipherKind 0x%lx\n", 
+     		(UInt32)SSL2CipherMap[i].cipherKind);
+        memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
+        progress += ctx->ssl2ConnectionIDLength;
+    }
+    
+    CASSERT(progress == msg->data + msg->length);
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2ProcessServerVerify(SSLBuffer msg, SSLContext *ctx)
+{   if (msg.length != ctx->ssl2ChallengeLength)
+        return ERR(SSLProtocolErr);
+    
+    if (memcmp(msg.data, ctx->clientRandom + 32 - ctx->ssl2ChallengeLength,
+                    ctx->ssl2ChallengeLength) != 0)
+        return ERR(SSLProtocolErr);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2EncodeServerVerify(SSLBuffer *msg, SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->ssl2ChallengeLength, &ctx->sysCtx)) != 0)
+        return err;
+    
+    msg->data[0] = ssl2_mt_server_verify;
+    memcpy(msg->data+1, ctx->clientRandom + 32 - ctx->ssl2ChallengeLength,
+                    ctx->ssl2ChallengeLength);
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2ProcessServerFinished(SSLBuffer msg, SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (ERR(err = SSLAllocBuffer(&ctx->sessionID, msg.length, &ctx->sysCtx)) != 0)
+        return err;
+    memcpy(ctx->sessionID.data, msg.data, msg.length);
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2EncodeServerFinished(SSLBuffer *msg, SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
+        return err;
+    
+    msg->data[0] = ssl2_mt_server_finished;
+    memcpy(msg->data+1, ctx->sessionID.data, ctx->sessionID.length);
+    
+    return SSLNoErr;
+}
diff --git a/SecureTransport/ssl2prot.c b/SecureTransport/ssl2prot.c
new file mode 100644
index 00000000..b96cb60f
--- /dev/null
+++ b/SecureTransport/ssl2prot.c
@@ -0,0 +1,527 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		ssl2prot.c
+
+	Contains:	Protocol engine for SSL 2
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: ssl2prot.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: ssl2prot.c   Protocol engine for SSL 2
+
+    This is the heart of the SSL 2 implementation, including the state
+    engine for proceeding through the handshake and the necessary code
+    for installing negotiated keys and algorithms.
+
+    ****************************************************************** */
+
+#ifndef _SSL_H_
+#include "ssl.h"
+#endif
+
+#ifndef _SSL2_H_
+#include "ssl2.h"
+#endif
+
+#ifndef _SSLREC_H_
+#include "sslrec.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLSESS_H_
+#include "sslsess.h"
+#endif
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef	_APPLE_CDSA_H_
+#include "appleCdsa.h"
+#endif
+
+#include <string.h>
+
+#if	LOG_HDSK_MSG
+
+static char *sslHdskMsgToStr(SSL2MessageType msg)
+{
+	static char badStr[100];
+	
+	switch(msg) {
+		case ssl2_mt_error:
+			return "ssl2_mt_error";	
+		case ssl2_mt_client_hello:
+			return "ssl2_mt_client_hello";	
+		case ssl2_mt_client_master_key:
+			return "ssl2_mt_client_master_key";	
+		case ssl2_mt_client_finished:
+			return "ssl2_mt_client_finished";	
+		case ssl2_mt_server_hello:
+			return "ssl2_mt_server_hello";	
+		case ssl2_mt_server_verify:
+			return "ssl2_mt_server_verify";	
+		case ssl2_mt_server_finished:
+			return "ssl2_mt_server_finished";	
+		case ssl2_mt_request_certificate:
+			return "ssl2_mt_request_certificate";	
+		case ssl2_mt_client_certificate:
+			return "ssl2_mt_client_certificate";	
+		case ssl2_mt_kickstart_handshake:
+			return "ssl2_mt_kickstart_handshake";	
+		default:
+			sprintf(badStr, "Unknown msg (%d(d)", msg);
+			return badStr;
+	}
+}
+
+static void logSsl2Msg(SSL2MessageType msg, char sent)
+{
+	char *ms = sslHdskMsgToStr(msg);
+	printf("...msg %s: %s\n", (sent ? "sent" : "recd"), ms);
+}
+
+#else	/* SSL_DEBUG */
+
+#define logSsl2Msg(m, s)
+
+#endif
+
+SSLErr
+SSL2ProcessMessage(SSLRecord rec, SSLContext *ctx)
+{   SSLErr              err = 0;
+    SSL2MessageType     msg;
+    SSLBuffer           contents;
+    
+    if (rec.contents.length < 2)
+        return ERR(SSLProtocolErr);
+    
+    msg = (SSL2MessageType)rec.contents.data[0];
+    contents.data = rec.contents.data + 1;
+    contents.length = rec.contents.length - 1;
+    
+    logSsl2Msg(msg, 0);
+    
+    switch (msg)
+    {   case ssl2_mt_error:
+    		#if	_APPLE_CDSA_
+    		/* ref code returned an unitialized local err here */
+    		err = SSLConnectionClosedError;
+    		#endif
+            break;
+        case ssl2_mt_client_hello:
+            if (ctx->state != HandshakeServerUninit)
+                return ERR(SSLProtocolErr);
+            ERR(err = SSL2ProcessClientHello(contents, ctx));
+            if (err == SSLNegotiationErr)
+                ERR(SSL2SendError(ssl2_pe_no_cipher, ctx));
+            break;
+        case ssl2_mt_client_master_key:
+            if (ctx->state != HandshakeSSL2ClientMasterKey)
+                return ERR(SSLProtocolErr);
+            ERR(err = SSL2ProcessClientMasterKey(contents, ctx));
+            break;
+        case ssl2_mt_client_finished:
+            if (ctx->state != HandshakeSSL2ClientFinished)
+                return ERR(SSLProtocolErr);
+            ERR(err = SSL2ProcessClientFinished(contents, ctx));
+            break;
+        case ssl2_mt_server_hello:
+            if (ctx->state != HandshakeSSL2ServerHello &&
+                ctx->state != HandshakeServerHelloUnknownVersion)
+                return ERR(SSLProtocolErr);
+            ERR(err = SSL2ProcessServerHello(contents, ctx));
+            if (err == SSLNegotiationErr)
+                ERR(SSL2SendError(ssl2_pe_no_cipher, ctx));
+            break;
+        case ssl2_mt_server_verify:
+            if (ctx->state != HandshakeSSL2ServerVerify)
+                return ERR(SSLProtocolErr);
+            ERR(err = SSL2ProcessServerVerify(contents, ctx));
+            break;
+        case ssl2_mt_server_finished:
+            if (ctx->state != HandshakeSSL2ServerFinished) {
+            	#if	LOG_HDSK_STATE
+            	errorLog1("ssl2_mt_server_finished; state %s\n",
+            		hdskStateToStr(ctx->state));
+            	#endif
+                return ERR(SSLProtocolErr);
+            }
+            ERR(err = SSL2ProcessServerFinished(contents, ctx));
+            break;
+        case ssl2_mt_request_certificate:
+            /* Don't process the request; we don't support client certification */
+            break;
+        case ssl2_mt_client_certificate:
+            return ERR(SSLProtocolErr);
+            break;
+        default:
+            DEBUGVAL1("Unknown message %d", msg);
+            return ERR(SSLProtocolErr);
+            break;
+    }
+    
+    if (err == 0)
+    {   	/* FIXME - use requested or negotiated protocol version here? */
+    	if (msg == ssl2_mt_client_hello && ctx->negProtocolVersion == SSL_Version_3_0)
+        {   /* Promote this message to SSL 3 protocol */
+            if (ERR(err = SSL3ReceiveSSL2ClientHello(rec, ctx)) != 0)
+                return err;
+        }
+        else
+            ERR(err = SSL2AdvanceHandshake(msg, ctx));
+    }
+    return err;
+}
+
+SSLErr
+SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx)
+{   SSLErr          err;
+    
+    err = SSLNoErr;
+    
+    switch (msg)
+    {   case ssl2_mt_kickstart_handshake:
+            if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
+                ctx->negProtocolVersion == SSL_Version_Undetermined)
+                if (ERR(err = SSLInitMessageHashes(ctx)) != 0)
+                    return err;
+            if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientHello, ctx)) != 0)
+                return err;
+            switch (ctx->negProtocolVersion)
+            {   case SSL_Version_Undetermined:
+                    SSLChangeHdskState(ctx, HandshakeServerHelloUnknownVersion);
+                    break;
+                case SSL_Version_3_0_With_2_0_Hello:
+                    ctx->negProtocolVersion = SSL_Version_3_0;
+				    #if LOG_NEGOTIATE
+				    dprintf0("===SSL client kickstart: negVersion is 3_0\n");
+				    #endif
+                  SSLChangeHdskState(ctx, HandshakeServerHello);
+                    break;
+                case SSL_Version_2_0:
+                    SSLChangeHdskState(ctx, HandshakeSSL2ServerHello);
+                    break;
+                case SSL_Version_3_0_Only:
+                case SSL_Version_3_0:
+                default:
+                    ASSERTMSG("Bad protocol version for sending SSL 2 Client Hello");
+                    break;
+            }
+            break;
+        case ssl2_mt_client_hello:
+            if (ERR(err = SSL2CompareSessionIDs(ctx)) != 0)
+                return err;
+            if (ctx->ssl2SessionMatch == 0)
+                if (ERR(err = SSL2GenerateSessionID(ctx)) != 0)
+                    return err;
+            if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerHello, ctx)) != 0)
+                return err;
+            if (ctx->ssl2SessionMatch == 0)
+            {   SSLChangeHdskState(ctx, HandshakeSSL2ClientMasterKey);
+                break;
+            }
+            if (ERR(err = SSL2InstallSessionKey(ctx)) != 0)
+                return err;
+            /* Fall through for matching session; lame, but true */
+        case ssl2_mt_client_master_key:
+            if (ERR(err = SSL2InitCiphers(ctx)) != 0)
+                return err;
+            if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerVerify, ctx)) != 0)
+                return err;
+            if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerFinished, ctx)) != 0)
+                return err;
+            SSLChangeHdskState(ctx, HandshakeSSL2ClientFinished);
+            break;
+        case ssl2_mt_server_hello:
+            if (ctx->ssl2SessionMatch == 0)
+            {   if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientMasterKey, ctx)) != 0)
+                    return err;
+            }
+            else
+            {   if (ERR(err = SSL2InstallSessionKey(ctx)) != 0)
+                    return err;
+            }
+            if (ERR(err = SSL2InitCiphers(ctx)) != 0)
+                return err;
+            if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientFinished, ctx)) != 0)
+                return err;
+            SSLChangeHdskState(ctx, HandshakeSSL2ServerVerify);
+            break;
+        case ssl2_mt_client_finished:
+            /* Handshake is complete; turn ciphers on */
+            ctx->writeCipher.ready = 1;
+            ctx->readCipher.ready = 1;
+            #if	_APPLE_CDSA_
+            /* original code never got out of ssl2_mt_client_finished state */
+            CASSERT(ctx->protocolSide == SSL_ServerSide);
+            SSLChangeHdskState(ctx, HandshakeServerReady);
+            #endif	/* _APPLE_CDSA_ */
+            if (ctx->peerID.data != 0)
+                ERR(SSLAddSessionID(ctx));
+            break;
+        case ssl2_mt_server_verify:
+            SSLChangeHdskState(ctx, HandshakeSSL2ServerFinished);
+            break;
+        case ssl2_mt_request_certificate:
+            if (ERR(err = SSL2SendError(ssl2_pe_no_certificate, ctx)) != 0)
+                return err;
+            break;
+        case ssl2_mt_server_finished:
+            /* Handshake is complete; turn ciphers on */
+            ctx->writeCipher.ready = 1;
+            ctx->readCipher.ready = 1;
+            #if	_APPLE_CDSA_
+            /* original code never got out of ssl2_mt_server_finished state */
+            CASSERT(ctx->protocolSide == SSL_ClientSide);
+            SSLChangeHdskState(ctx, HandshakeClientReady);
+            #endif	/* _APPLE_CDSA_ */
+            if (ctx->peerID.data != 0)
+                ERR(SSLAddSessionID(ctx));
+            break;
+        case ssl2_mt_error:
+        case ssl2_mt_client_certificate:
+            return ERR(SSLProtocolErr);
+            break;
+    }
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx)
+{   SSLErr          err;
+    SSLRecord       rec;
+    
+    rec.contentType = SSL_version_2_0_record;
+    rec.protocolVersion = SSL_Version_2_0;
+    if (ERR(err = encodeFunc(&rec.contents, ctx)) != 0)
+        return err;
+
+    logSsl2Msg((SSL2MessageType)rec.contents.data[0], 1);
+    
+    if (ERR(err = SSLWriteRecord(rec, ctx)) != 0)
+    {   ERR(SSLFreeBuffer(&rec.contents, &ctx->sysCtx));
+        return err;
+    }
+    
+    if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
+        ctx->negProtocolVersion == SSL_Version_Undetermined)
+        if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
+            ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
+            return err;
+    
+    ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx));
+    return err;
+}
+
+SSLErr
+SSL2CompareSessionIDs(SSLContext *ctx)
+{   SSLErr          err;
+    SSLBuffer       sessionIdentifier;
+
+    ctx->ssl2SessionMatch = 0;
+    
+    if (ctx->resumableSession.data == 0)
+        return SSLNoErr;
+    
+    if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession,
+                                    &sessionIdentifier, ctx)) != 0)
+        return err;
+    
+    if (sessionIdentifier.length == ctx->sessionID.length &&
+        memcmp(sessionIdentifier.data, ctx->sessionID.data, sessionIdentifier.length) == 0)
+        ctx->ssl2SessionMatch = 1;
+    
+    if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
+        return err;
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2InstallSessionKey(SSLContext *ctx)
+{   SSLErr          err;
+    
+    CASSERT(ctx->ssl2SessionMatch != 0);
+    CASSERT(ctx->resumableSession.data != 0);
+    if (ERR(err = SSLInstallSessionID(ctx->resumableSession, ctx)) != 0)
+        return err;
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2GenerateSessionID(SSLContext *ctx)
+{   SSLErr          err;
+    
+    if (ERR(err = SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx)) != 0)
+        return err;
+    if (ERR(err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, &ctx->sysCtx)) != 0)
+        return err;
+    #ifdef	_APPLE_CDSA_
+    if ((err = sslRand(ctx, &ctx->sessionID)) != 0)
+    #else
+    if (ERR(err = ctx->sysCtx.random(ctx->sessionID, ctx->sysCtx.randomRef)) != 0)
+   	#endif
+        return err;
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2InitCiphers(SSLContext *ctx)
+{   SSLErr          err;
+    int             keyMaterialLen;
+    SSLBuffer       keyData;
+    uint8           variantChar, *progress, *readKey, *writeKey, *iv;
+    SSLBuffer       hashDigest, hashContext, masterKey, challenge, connectionID, variantData;
+    
+    keyMaterialLen = 2 * ctx->selectedCipherSpec->cipher->keySize;
+    if (ERR(err = SSLAllocBuffer(&keyData, keyMaterialLen, &ctx->sysCtx)) != 0)
+        return err;
+    
+	/* Can't have % in assertion string... */
+	#if	SSL_DEBUG
+	{
+		UInt32 keyModDigestSize = keyMaterialLen % SSLHashMD5.digestSize;
+		CASSERT(keyModDigestSize == 0);
+    }
+	#endif
+	
+    masterKey.data = ctx->masterSecret;
+    masterKey.length = ctx->selectedCipherSpec->cipher->keySize;
+    challenge.data = ctx->clientRandom + 32 - ctx->ssl2ChallengeLength;
+    challenge.length = ctx->ssl2ChallengeLength;
+    connectionID.data = ctx->serverRandom;
+    connectionID.length = ctx->ssl2ConnectionIDLength;
+    variantData.data = &variantChar;
+    variantData.length = 1;
+    if (ERR(err = SSLAllocBuffer(&hashContext, SSLHashMD5.contextSize, &ctx->sysCtx)) != 0)
+    {   ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
+        return err;
+    }
+
+    variantChar = 0x30;     /* '0' */
+    progress = keyData.data;
+    while (keyMaterialLen)
+    {   hashDigest.data = progress;
+        hashDigest.length = SSLHashMD5.digestSize;
+        if (ERR(err = SSLHashMD5.init(hashContext)) != 0 ||
+            ERR(err = SSLHashMD5.update(hashContext, masterKey)) != 0 ||
+            ERR(err = SSLHashMD5.update(hashContext, variantData)) != 0 ||
+            ERR(err = SSLHashMD5.update(hashContext, challenge)) != 0 ||
+            ERR(err = SSLHashMD5.update(hashContext, connectionID)) != 0 ||
+            ERR(err = SSLHashMD5.final(hashContext, hashDigest)) != 0)
+        {   SSLFreeBuffer(&keyData, &ctx->sysCtx);
+            SSLFreeBuffer(&hashContext, &ctx->sysCtx);
+            return err;
+        }
+        progress += hashDigest.length;
+        ++variantChar;
+        keyMaterialLen -= hashDigest.length;
+    }
+    
+    CASSERT(progress == keyData.data + keyData.length);
+    
+    if (ERR(err = SSLFreeBuffer(&hashContext, &ctx->sysCtx)) != 0)
+    {   ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
+        return err;
+    }
+    
+    ctx->readPending.hash = ctx->selectedCipherSpec->macAlgorithm;
+    ctx->writePending.hash = ctx->selectedCipherSpec->macAlgorithm;
+    ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher;
+    ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher;
+    ctx->readPending.sequenceNum = ctx->readCipher.sequenceNum;
+    ctx->writePending.sequenceNum = ctx->writeCipher.sequenceNum;
+    
+    if (ctx->protocolSide == SSL_ServerSide)
+    {   writeKey = keyData.data;
+        readKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
+    }
+    else
+    {   readKey = keyData.data;
+        writeKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
+    }
+    
+    iv = ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize;
+    
+    /* APPLE_CDSA symmetric cipher changes....*/
+    if (ERR(err = ctx->readPending.symCipher->initialize(readKey, iv,
+                            &ctx->readPending, ctx)) != 0 ||
+        ERR(err = ctx->writePending.symCipher->initialize(writeKey, iv,
+                            &ctx->writePending, ctx)) != 0)
+    {   ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
+        return err;
+    }
+    
+	/* 
+	 * HEY! macSecret is only 20 bytes. This blows up when key size
+	 * is greater than 20, e.g., 3DES. 
+	 * I'll increase the size of macSecret to 24, 'cause it appears
+	 * from the SSL v23 spec that the macSecret really the same size as
+	 * CLIENT-WRITE-KEY and  SERVER-READ-KEY (see 1.2 of the spec).
+	 */
+    memcpy(ctx->readPending.macSecret, readKey, ctx->selectedCipherSpec->cipher->keySize);
+    memcpy(ctx->writePending.macSecret, writeKey, ctx->selectedCipherSpec->cipher->keySize);
+    
+    if (ERR(err = SSLFreeBuffer(&keyData, &ctx->sysCtx)) != 0)
+        return err;
+    
+    ctx->readCipher = ctx->readPending;
+    ctx->writeCipher = ctx->writePending;
+    memset(&ctx->readPending, 0, sizeof(CipherContext));        /* Zero out old data */
+    memset(&ctx->writePending, 0, sizeof(CipherContext));       /* Zero out old data */
+    
+    return SSLNoErr;
+}
diff --git a/SecureTransport/ssl2rec.c b/SecureTransport/ssl2rec.c
new file mode 100644
index 00000000..be1b8c52
--- /dev/null
+++ b/SecureTransport/ssl2rec.c
@@ -0,0 +1,457 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		ssl2rec.c
+
+	Contains:	Record encrypting/decrypting/MACing for SSL 2
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: ssl2rec.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: ssl2rec.c    Record encrypting/decrypting/MACing for SSL 2
+
+
+    ****************************************************************** */
+
+#ifndef _SSL2_H_
+#include "ssl2.h"
+#endif
+
+#ifndef _SSLREC_H_
+#include "sslrec.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef	_DIGESTS_H_
+#include "digests.h"
+#endif
+
+#ifdef	_APPLE_CDSA_
+#ifndef	_APPLE_GLUE_H_
+#include "appleGlue.h"
+#endif
+#endif
+
+#include <string.h>
+
+static SSLErr SSL2DecryptRecord(SSLBuffer *payload, SSLContext *ctx);
+static SSLErr SSL2VerifyMAC(SSLBuffer content, UInt8 *compareMAC, SSLContext *ctx);
+static SSLErr SSL2CalculateMAC(SSLBuffer secret, SSLBuffer content, UInt32 seqNo, const HashReference *hash, SSLBuffer mac, SSLContext *ctx);
+
+
+SSLErr
+SSL2ReadRecord(SSLRecord *rec, SSLContext *ctx)
+{   SSLErr          err;
+    UInt32          len, contentLen;
+    int             padding, headerSize;
+    UInt8           *progress;
+    SSLBuffer       readData, cipherFragment;
+    
+    switch (ctx->negProtocolVersion)
+    {   case SSL_Version_Undetermined:
+        case SSL_Version_3_0_With_2_0_Hello:
+        case SSL_Version_2_0:
+            break;
+        case SSL_Version_3_0:           /* We've negotiated a 3.0 session; we can send an alert */
+            SSLFatalSessionAlert(alert_unexpected_message, ctx);
+            return SSLProtocolErr;
+        case SSL_Version_3_0_Only:      /* We haven't yet negotiated, but we don't want to support 2.0; just die without an alert */
+            return SSLProtocolErr;
+        default:
+            sslPanic("bad protocolVersion in ctx->protocolVersion");
+    }
+    
+    if (!ctx->partialReadBuffer.data || ctx->partialReadBuffer.length < 3)
+    {   if (ctx->partialReadBuffer.data)
+            if (ERR(err = SSLFreeBuffer(&ctx->partialReadBuffer, &ctx->sysCtx)) != 0)
+            {   SSLFatalSessionAlert(alert_close_notify, ctx);
+                return err;
+            }
+        if (ERR(err = SSLAllocBuffer(&ctx->partialReadBuffer, DEFAULT_BUFFER_SIZE, &ctx->sysCtx)) != 0)
+        {   SSLFatalSessionAlert(alert_close_notify, ctx);
+            return err;
+        }
+    }
+    
+    if (ctx->amountRead < 3)
+    {   readData.length = 3 - ctx->amountRead;
+        readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+        len = readData.length;
+        #ifdef	_APPLE_CDSA_
+        err = sslIoRead(readData, &len, ctx);
+        if(err != 0)
+		#else
+        if (ERR(err = ctx->ioCtx.read(readData, &len, ctx->ioCtx.ioRef)) != 0)
+		#endif
+        {   if (err == SSLWouldBlockErr)
+                ctx->amountRead += len;
+            if (err == SSLIOErr && ctx->amountRead == 0)    /* If the session closes on a record boundary, it's graceful */
+                err = SSLConnectionClosedGraceful;
+            return err;
+        }
+        ctx->amountRead += len;
+    }
+    
+    rec->contentType = SSL_version_2_0_record;
+    rec->protocolVersion = SSL_Version_2_0;
+    progress = ctx->partialReadBuffer.data;
+    
+    if (((*progress) & 0x80) != 0)          /* High bit on -> specifies 2-byte header */
+    {   headerSize = 2;
+        contentLen = ((progress[0] & 0x7F) << 8) | progress[1];
+        padding = 0;
+    }
+    else if (((*progress) & 0x40) != 0)     /* Bit 6 on -> specifies security escape */
+    {   return ERR(SSLProtocolErr);                 /* No security escapes are defined */
+    }
+    else                                    /* 3-byte header */
+    {   headerSize = 3;
+        contentLen = ((progress[0] & 0x3F) << 8) | progress[1];
+        padding = progress[2];
+    }
+    
+    #ifdef	__APPLE__
+    /* 
+     * FIXME - what's the max record size?
+     * and why doesn't SSLReadRecord parse the 2 or 3 byte header?
+	 * Note: I see contentLen of 0 coming back from www.cduniverse.com when
+	 * it's only been given SSL_RSA_EXPORT_WITH_DES40_CBC_SHA.
+     */
+    if((contentLen == 0) || (contentLen > 0xffff)) {
+    	return SSLProtocolErr;
+    }
+    #endif
+    
+    progress += headerSize;
+    
+    if (ctx->partialReadBuffer.length < headerSize + contentLen)
+    {   if (ERR(err = SSLReallocBuffer(&ctx->partialReadBuffer, 5 + contentLen, &ctx->sysCtx)) != 0)
+            return err;
+    }
+    
+    if (ctx->amountRead < headerSize + contentLen)
+    {   readData.length = headerSize + contentLen - ctx->amountRead;
+        readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+        len = readData.length;
+        #ifdef	_APPLE_CDSA_
+        err = sslIoRead(readData, &len, ctx);
+        if(err != 0)
+		#else
+        if (ERR(err = ctx->ioCtx.read(readData, &len, ctx->ioCtx.ioRef)) != 0)
+		#endif
+        {   if (err == SSLWouldBlockErr)
+                ctx->amountRead += len;
+            return err;
+        }
+        ctx->amountRead += len;
+    }
+    
+    cipherFragment.data = ctx->partialReadBuffer.data + headerSize;
+    cipherFragment.length = contentLen;
+    if (ERR(err = SSL2DecryptRecord(&cipherFragment, ctx)) != 0)
+        return err;
+    
+    cipherFragment.length -= padding;       /* Remove padding; MAC was removed by SSL2DecryptRecord */
+    
+    IncrementUInt64(&ctx->readCipher.sequenceNum);
+    
+/* Allocate a buffer to return the plaintext in and return it */
+    if (ERR(err = SSLAllocBuffer(&rec->contents, cipherFragment.length, &ctx->sysCtx)) != 0)
+        return err;
+    memcpy(rec->contents.data, cipherFragment.data, cipherFragment.length);
+    
+    ctx->amountRead = 0;        /* We've used all the data in the cache */
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSL2WriteRecord(SSLRecord rec, SSLContext *ctx)
+{   SSLErr          err;
+    int             padding = 0, i, headerSize;
+    WaitingRecord   *out, *queue;
+    SSLBuffer       buf, content, payload, secret, mac;
+    UInt8           *progress;
+    UInt16          payloadSize, blockSize;
+    
+    CASSERT(rec.contents.length < 16384);
+    
+    out = 0;
+    /* Allocate a WaitingRecord to store our ready-to-send record in */
+    if (ERR(err = SSLAllocBuffer(&buf, sizeof(WaitingRecord), &ctx->sysCtx)) != 0)
+        return err;
+    out = (WaitingRecord*)buf.data;
+    out->next = 0;
+    out->sent = 0;
+        
+    payloadSize = (UInt16) (rec.contents.length + ctx->writeCipher.hash->digestSize);
+    blockSize = ctx->writeCipher.symCipher->blockSize;
+    if (blockSize > 0)
+    {   
+		#ifdef	_APPLE_CDSA_
+		/* HEY! this netscape code could never work with a block cipher... */
+		padding = blockSize - (payloadSize % blockSize);
+		#else
+		/* bogon */
+		padding = blockSize - (payloadSize % blockSize) - 1;
+		#endif
+        if (padding == blockSize)
+            padding = 0;
+        payloadSize += padding;
+        headerSize = 3;
+    }
+    else
+    {   padding = 0;
+        headerSize = 2;
+    }
+    out->data.data = 0;
+    if (ERR(err = SSLAllocBuffer(&out->data, headerSize + payloadSize, &ctx->sysCtx)) != 0)
+        goto fail;
+    progress = out->data.data;
+    
+    if (headerSize == 2)
+        progress = SSLEncodeInt(progress, payloadSize | 0x8000, 2);
+    else
+    {   progress = SSLEncodeInt(progress, payloadSize, 2);
+        *progress++ = padding;
+    }
+    
+    payload.data = progress;
+    payload.length = payloadSize;
+    
+    mac.data = progress;
+    mac.length = ctx->writeCipher.hash->digestSize;
+    progress += mac.length;
+    
+    content.data = progress;
+    content.length = rec.contents.length + padding;
+    memcpy(progress, rec.contents.data, rec.contents.length);
+    progress += rec.contents.length;
+    i = padding;
+    while (i--)
+        *progress++ = padding;
+
+    CASSERT(progress == out->data.data + out->data.length);
+    
+    secret.data = ctx->writeCipher.macSecret;
+    secret.length = ctx->writeCipher.symCipher->keySize;
+    if (mac.length > 0)
+        if (ERR(err = SSL2CalculateMAC(secret, content, ctx->writeCipher.sequenceNum.low,
+                                    ctx->writeCipher.hash, mac, ctx)) != 0)
+            goto fail;
+    
+    /* APPLE_CDSA change...*/
+    if (ERR(err = ctx->writeCipher.symCipher->encrypt(payload, 
+    		payload, 
+    		&ctx->writeCipher, 
+    		ctx)) != 0)
+        goto fail;
+    
+    /* Enqueue the record to be written from the idle loop */
+    if (ctx->recordWriteQueue == 0)
+        ctx->recordWriteQueue = out;
+    else
+    {   queue = ctx->recordWriteQueue;
+        while (queue->next != 0)
+            queue = queue->next;
+        queue->next = out;
+    }
+    
+    /* Increment the sequence number */
+    IncrementUInt64(&ctx->writeCipher.sequenceNum);
+    
+    return SSLNoErr;
+    
+fail:   /* Only for if we fail between when the WaitingRecord is allocated and when it is queued */
+    SSLFreeBuffer(&out->data, 0);
+    buf.data = (UInt8*)out;
+    buf.length = sizeof(WaitingRecord);
+    SSLFreeBuffer(&buf, &ctx->sysCtx);
+    return err;
+}
+
+static SSLErr
+SSL2DecryptRecord(SSLBuffer *payload, SSLContext *ctx)
+{   SSLErr          err;
+    SSLBuffer       content;
+    
+    if (ctx->readCipher.symCipher->blockSize > 0)
+        if (payload->length % ctx->readCipher.symCipher->blockSize != 0)
+            return ERR(SSLProtocolErr);
+    
+/* Decrypt in place */
+	/* APPLE_CDSA change...*/
+    if (ERR(err = ctx->readCipher.symCipher->decrypt(*payload, 
+    		*payload, 
+    		&ctx->readCipher, 
+    		ctx)) != 0)
+        return err;
+    
+    if (ctx->readCipher.hash->digestSize > 0)       /* Optimize away MAC for null case */
+    {   content.data = payload->data + ctx->readCipher.hash->digestSize;        /* Data is after MAC */
+        content.length = payload->length - ctx->readCipher.hash->digestSize;
+        if (ERR(err = SSL2VerifyMAC(content, payload->data, ctx)) != 0)
+            return err;
+    /* Adjust payload to remove MAC; caller is still responsible for removing padding [if any] */
+        *payload = content;
+    }
+    
+    return SSLNoErr;
+}
+
+#define IGNORE_MAC_FAILURE	0
+
+static SSLErr
+SSL2VerifyMAC(SSLBuffer content, UInt8 *compareMAC, SSLContext *ctx)
+{   SSLErr      err;
+    UInt8       calculatedMAC[MAX_DIGEST_SIZE];
+    SSLBuffer   secret, mac;
+    
+    secret.data = ctx->readCipher.macSecret;
+    secret.length = ctx->readCipher.symCipher->keySize;
+    mac.data = calculatedMAC;
+    mac.length = ctx->readCipher.hash->digestSize;
+    if (ERR(err = SSL2CalculateMAC(secret, content, ctx->readCipher.sequenceNum.low,
+                                ctx->readCipher.hash, mac, ctx)) != 0)
+        return err;
+    if (memcmp(mac.data, compareMAC, mac.length) != 0) {
+		#if	IGNORE_MAC_FAILURE
+		dprintf0("SSL2VerifyMAC: Mac verify failure\n");
+		return SSLNoErr;
+		#else
+		errorLog0("SSL2VerifyMAC: Mac verify failure\n");
+        return ERR(SSLProtocolErr);
+        #endif
+    }
+    return SSLNoErr;
+}
+
+#define LOG_MAC_DATA		0
+#if		LOG_MAC_DATA
+static void logMacData(
+	char *field,
+	SSLBuffer *data)
+{
+	int i;
+	
+	printf("%s: ", field);
+	for(i=0; i<data->length; i++) {
+		printf("%02X", data->data[i]);
+		if((i % 4) == 3) {
+			printf(" ");
+		}
+	}
+	printf("\n");
+}
+#else	/* LOG_MAC_DATA */
+#define logMacData(f, d)
+#endif	/* LOG_MAC_DATA */
+
+/* For SSL 2, the MAC is hash ( secret || content || sequence# )
+ *  where secret is the decryption key for the message, content is
+ *  the record data plus any padding used to round out the record
+ *  size to an even multiple of the block size and sequence# is
+ *  a monotonically increasing 32-bit unsigned integer.
+ */
+static SSLErr
+SSL2CalculateMAC(SSLBuffer secret, SSLBuffer content, UInt32 seqNo, const HashReference *hash, SSLBuffer mac, SSLContext *ctx)
+{   SSLErr      err;
+    UInt8       sequenceNum[4];
+    SSLBuffer   seqData, hashContext;
+    
+    SSLEncodeInt(sequenceNum, seqNo, 4);
+    seqData.data = sequenceNum;
+    seqData.length = 4;
+	
+    hashContext.data = 0;
+    if (ERR(err = ReadyHash(hash, &hashContext, ctx)) != 0)
+        return err;
+    if (ERR(err = hash->update(hashContext, secret)) != 0)
+        goto fail;
+    if (ERR(err = hash->update(hashContext, content)) != 0)
+        goto fail;
+    if (ERR(err = hash->update(hashContext, seqData)) != 0)
+        goto fail;
+    if (ERR(err = hash->final(hashContext, mac)) != 0)
+        goto fail;
+
+	logMacData("secret ", &secret);
+	logMacData("seqData", &seqData);
+	logMacData("mac    ", &mac);
+    
+    err = SSLNoErr;
+fail:
+    ERR(SSLFreeBuffer(&hashContext, &ctx->sysCtx));
+    return err;
+}
+
+SSLErr
+SSL2SendError(SSL2ErrorCode error, SSLContext *ctx)
+{   SSLErr          err;
+    SSLRecord       rec;
+    UInt8           errorData[3];
+    
+    rec.contentType = SSL_version_2_0_record;
+    rec.protocolVersion = SSL_Version_2_0;
+    rec.contents.data = errorData;
+    rec.contents.length = 3;
+    errorData[0] = ssl2_mt_error;
+    SSLEncodeInt(errorData + 1, error, 2);
+    
+    ERR(err = SSL2WriteRecord(rec, ctx));
+    return err;
+}
diff --git a/SecureTransport/sslBER.cpp b/SecureTransport/sslBER.cpp
new file mode 100644
index 00000000..8a51116d
--- /dev/null
+++ b/SecureTransport/sslBER.cpp
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslBER.cpp
+
+	Contains:	BER routines
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+#include "sslalloc.h"
+#include "sslDebug.h"
+#include "sslBER.h"
+
+#include <Security/asn-incl.h>
+#include <Security/sm_vdatypes.h>
+#include <Security/asn-type.h>
+#include <Security/pkcs1oids.h>		/* for RSAPublicKey */
+#include <Security/cdsaUtils.h>
+#include <string.h>
+#include <Security/cssmdata.h>
+
+/* convert between SSLBuffer and snacc-style BigIntegerStr */
+
+static void snaccIntToData(
+	const BigIntegerStr			&snaccInt,
+	SSLBuffer					*outData)		// already mallocd
+{
+	const char *scp = snaccInt;
+	uint8 *cp = (uint8 *)scp;
+	uint32 len = snaccInt.Len();
+
+	if (*cp == 0x00) {
+		/* skip over this place-holding m.s. byte */
+		cp++;
+		len--;
+	}
+
+	memmove(outData->data, cp, len);
+	outData->length = len;
+}
+
+static void dataToSnaccInt(
+	const SSLBuffer		*inData,
+	BigIntegerStr 		&snaccInt)
+{
+	uint8 *cp;
+	int msbIsSet = 0;
+	
+	if (inData->data[0] & 0x80) {
+		/* m.s. bit of BER data must be zero! */ 
+		cp = (uint8 *)malloc(inData->length + 1);
+		*cp = 0;
+		memmove(cp+1, inData->data, inData->length);
+		msbIsSet = 1;
+	}
+	else {
+		cp = inData->data;
+	}
+	snaccInt.Set(reinterpret_cast<const char *>(cp), 
+		inData->length + msbIsSet);
+	if(msbIsSet) {
+		free(cp);
+	}
+}
+
+/*
+ * Given a PKCS-1 encoded RSA public key, extract the 
+ * modulus and public exponent.
+ *
+ * RSAPublicKey ::= SEQUENCE {
+ *		modulus INTEGER, -- n
+ *		publicExponent INTEGER -- e }
+ */
+ 
+SSLErr sslDecodeRsaBlob(
+	const SSLBuffer	*blob,			/* PKCS-1 encoded */
+	SSLBuffer		*modulus,		/* data mallocd and RETURNED */
+	SSLBuffer		*exponent)		/* data mallocd and RETURNED */
+{
+	SSLErr				srtn;
+
+	CASSERT(blob != NULL);
+	CASSERT(modulus != NULL);
+	CASSERT(exponent != NULL);
+	
+	/* DER-decode the blob */
+	RSAPublicKey snaccPubKey;
+	CssmData cssmBlob(blob->data, blob->length);
+	try {
+		SC_decodeAsnObj(cssmBlob, snaccPubKey);
+	}
+	catch(...) {
+		return SSLBadCert;
+	}
+	
+	/* malloc & convert components */
+	srtn = SSLAllocBuffer(modulus, snaccPubKey.modulus.Len(), NULL);
+	if(srtn) {
+		return srtn;
+	}
+	snaccIntToData(snaccPubKey.modulus, modulus);
+	srtn = SSLAllocBuffer(exponent, snaccPubKey.publicExponent.Len(), 
+		NULL);
+	if(srtn) {
+		return srtn;
+	}
+	snaccIntToData(snaccPubKey.publicExponent, exponent);
+	return SSLNoErr;
+}
+
+/*
+ * Given a raw modulus and exponent, cook up a
+ * BER-encoded RSA public key blob.
+ */
+SSLErr sslEncodeRsaBlob(
+	const SSLBuffer	*modulus,		
+	const SSLBuffer	*exponent,		
+	SSLBuffer		*blob)			/* data mallocd and RETURNED */
+{
+	CASSERT((modulus != NULL) && (exponent != NULL));
+	blob->data = NULL;
+	blob->length = 0;
+
+	/* Cook up a snacc-style RSAPublic key */
+	RSAPublicKey snaccPubKey;
+	dataToSnaccInt(modulus, snaccPubKey.modulus);
+	dataToSnaccInt(exponent, snaccPubKey.publicExponent);
+		
+	/* estimate max size, BER-encode */
+	size_t maxSize = 2 * (modulus->length + exponent->length);
+	CssmAllocator &alloc  = CssmAllocator::standard();
+	CssmAutoData cblob(alloc);
+	try {
+		SC_encodeAsnObj(snaccPubKey, cblob, maxSize);
+	}
+	catch(...) {
+		/* right...? */
+		return SSLMemoryErr;
+	}
+	
+	/* copy to caller's SSLBuffer */
+	SSLErr srtn = SSLAllocBuffer(blob, cblob.length(), NULL);
+	if(srtn) {
+		return srtn;
+	}
+	memmove(blob->data, cblob.data(), cblob.length());
+	return SSLNoErr;
+}
+
diff --git a/SecureTransport/sslDebug.c b/SecureTransport/sslDebug.c
new file mode 100644
index 00000000..9f59aec0
--- /dev/null
+++ b/SecureTransport/sslDebug.c
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslDebug.c
+
+	Contains:	Debugging support.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1998 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		03/10/98	dpm		Created.
+
+*/
+
+
+#include "sslDebug.h"
+
+#if		SSL_DEBUG && macintosh
+
+#include <string.h>
+#include <Types.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* this one needs a writable string */
+static void logCom(unsigned char *str) {
+	c2pstr((char *)str);
+	DebugStr(str);
+}
+
+/* remaining ones can take constant strings */
+void dblog0(char *str)	{
+	Str255	outStr;
+	strcpy((char *)outStr, str);
+	logCom(outStr);
+}
+
+void dblog1(char *str, void *arg1)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1);
+	logCom(outStr);
+}
+
+void dblog2(char *str, void * arg1, void * arg2)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2);
+	logCom(outStr);
+}
+
+void dblog3(char *str, void * arg1, void * arg2, void * arg3)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2, arg3);
+	logCom(outStr);
+}
+
+void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4)	{
+	Str255	outStr;
+	sprintf((char *)outStr, str, arg1, arg2, arg3, arg4);
+	logCom(outStr);
+}
+
+#endif	/* SSL_DEBUG */
+
+/*
+ * Panic/exit.
+ */
+#include <stdlib.h>
+volatile void sslPanic(const char *reason)
+{
+	errorLog0((char *)reason);
+	/* FIXME */
+	exit(1);
+}
+
diff --git a/SecureTransport/sslKeychain.c b/SecureTransport/sslKeychain.c
new file mode 100644
index 00000000..2e35639e
--- /dev/null
+++ b/SecureTransport/sslKeychain.c
@@ -0,0 +1,563 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslKeychain.c
+
+	Contains:	Apple Keychain routines
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "ssl.h"
+#include "sslctx.h"
+#include "sslalloc.h"
+#include "appleCdsa.h"
+#include "appleGlue.h"
+#include "sslerrs.h"
+#include "sslDebug.h"
+#include "sslKeychain.h"
+#include "sslutil.h"
+
+#if		ST_KEYCHAIN_ENABLE
+#include <Keychain.h>
+#include <KeychainPriv.h>
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+#include <string.h>
+
+#if		ST_KEYCHAIN_ENABLE
+static OSStatus
+addCertData(
+	SSLContext		*ctx,
+	KCItemRef		kcItem,
+	CSSM_DATA_PTR	certData,
+	Boolean			*goodCert);		/* RETURNED */
+
+/*
+ * Given a KCItemRef: is this item a cert?
+ */
+static Boolean
+isItemACert(KCItemRef kcItem)
+{	
+	KCAttribute		attr;
+	FourCharCode	itemClass;
+	OSStatus		ortn;
+	UInt32			len;
+	
+	attr.tag = kClassKCItemAttr;
+	attr.length = sizeof(FourCharCode);
+	attr.data = &itemClass;
+	
+	ortn = KCGetAttribute (kcItem, &attr, &len);
+	if (ortn == noErr) {
+		return((itemClass == kCertificateKCItemClass) ? true : false);
+	}
+	else {
+		errorLog1("isItemACert: KCGetAttribute returned %d\n", ortn);
+		return false;
+	}
+}
+
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+#if		(ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION)
+/*
+ * Given an array of certs (as KCItemRefs, specified by caller
+ * in SSLSetCertificate or SSLSetEncryptionCertificate) and a 
+ * destination SSLCertificate:
+ *
+ * -- free destCerts if we have any
+ * -- Get raw cert data, convert to array of SSLCertificates in *destCert 
+ * -- validate cert chain
+ * -- get pub, priv keys from certRef[0], store in *pubKey, *privKey
+ */
+OSStatus 
+parseIncomingCerts(
+	SSLContext		*ctx,
+	CFArrayRef		certs,
+	SSLCertificate	**destCert,		/* &ctx->{localCert,encryptCert} */
+	CSSM_KEY_PTR	*pubKey,		/* &ctx->signingPubKey, etc. */
+	CSSM_KEY_PTR	*privKey,		/* &ctx->signingPrivKey, etc. */
+	CSSM_CSP_HANDLE	*cspHand,		/* &ctx->signingKeyCsp, etc. */
+	KCItemRef		*privKeyRef)	/* &ctx->signingKeyRef, etc. */
+{
+	CFIndex			numCerts;
+	CFIndex			cert;
+	SSLCertificate	*certChain = NULL;
+	SSLCertificate	*thisSslCert;
+	KCItemRef		kcItem;
+	SSLBuffer		*derSubjCert = NULL;
+	UInt32			certLen;
+	OSStatus		ortn;
+	SSLErr			srtn;
+	FromItemGetPrivateKeyParams	keyParams = {NULL, NULL};
+	FromItemGetKeyInfoParams	keyInfo = {NULL, NULL, 0};
+	CSSM_CSP_HANDLE				dummyCsp;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(destCert != NULL);		/* though its referent may be NULL */
+	CASSERT(pubKey != NULL);
+	CASSERT(privKey != NULL);
+	CASSERT(cspHand != NULL);
+	CASSERT(privKeyRef != NULL);
+	
+	sslDeleteCertificateChain(*destCert, ctx);
+	*destCert = NULL;
+	*pubKey   = NULL;
+	*privKey  = NULL;
+	*cspHand  = 0;
+	
+	if(certs == NULL) {
+		dprintf0("parseIncomingCerts: NULL incoming cert array\n");
+		return errSSLBadCert;
+	}
+	numCerts = CFArrayGetCount(certs);
+	if(numCerts == 0) {
+		dprintf0("parseIncomingCerts: empty incoming cert array\n");
+		return errSSLBadCert;
+	}
+	
+	/* 
+	 * Convert: CFArray of KCItemRefs --> chain of SSLCertificates. 
+	 * Incoming certs have root last; SSLCertificate chain has root
+	 * first.
+	 */
+	for(cert=0; cert<numCerts; cert++) {
+		kcItem = (KCItemRef)CFArrayGetValueAtIndex(certs, cert);
+		if(kcItem == NULL) {
+			errorLog0("parseIncomingCerts: bad cert array\n");
+			return paramErr;
+		}	
+		if(!isItemACert(kcItem)) {
+			/* client app error, not ours */
+			return paramErr;
+		}
+		
+		/* 
+		 * OK, cook up an SSLCertificate and its associated SSLBuffer.
+		 * First the size of the actual cert data...
+		 */
+		ortn = KCGetData(kcItem, 0,  NULL, &certLen);
+		if(ortn != noErr) {
+			errorLog1("parseIncomingCerts: KCGetData(1) returned %d\n", ortn);
+			return ortn;
+		}
+		thisSslCert = sslMalloc(sizeof(SSLCertificate));
+		if(thisSslCert == NULL) {
+			return memFullErr;
+		}
+		if(SSLAllocBuffer(&thisSslCert->derCert, certLen, &ctx->sysCtx)) {
+			return memFullErr;
+		}
+		
+		/* now the data itself */
+		ortn = KCGetData (kcItem, 
+			certLen, 
+			thisSslCert->derCert.data, 
+			&certLen);
+		if(ortn) {
+			errorLog1("parseIncomingCerts: KCGetData(2) returned %d\n", ortn);
+			SSLFreeBuffer(&thisSslCert->derCert, &ctx->sysCtx);
+			return ortn;
+		}
+		
+		/* enqueue onto head of cert chain */
+		thisSslCert->next = certChain;
+		certChain = thisSslCert;
+		
+		if(derSubjCert == NULL) {
+			/* Save this ptr for obtaining public key */
+			derSubjCert = &thisSslCert->derCert;
+		}
+	}
+	
+	/* validate the whole mess */
+	srtn = sslVerifyCertChain(ctx, certChain);
+	if(srtn) {
+		ortn = sslErrToOsStatus(srtn);
+		goto errOut;
+	}
+	
+	/* 
+	 * Get privKey, pubKey, KCItem of certs[0].
+	 * First, the private key, from the Keychain, using crufy private API.
+	 */
+	keyParams.item = (KCItemRef)CFArrayGetValueAtIndex(certs, 0);
+	ortn = KCDispatch(kKCFromItemGetPrivateKey, &keyParams);
+	if(ortn) {
+		errorLog1("KCDispatch(kKCFromItemGetPrivateKey) returned %d\n", ortn);
+		goto errOut;
+	}
+	keyInfo.item = keyParams.privateKeyItem;
+	ortn = KCDispatch(kKCFromItemGetKeyInfo, &keyInfo);
+	if(ortn) {
+		errorLog1("KCDispatch(kKCFromItemGetKeyInfo) returned %d\n", ortn);
+		goto errOut;
+	}
+	*privKey = (CSSM_KEY_PTR)keyInfo.keyPtr;
+	*cspHand = keyInfo.cspHandle;
+	*privKeyRef = keyParams.privateKeyItem;
+	
+	/* now the public key, from CL */
+	/* FIXME - what if this CSP differs from the one we got from KC??? */
+	srtn = sslPubKeyFromCert(ctx, 
+		derSubjCert, 
+		pubKey,
+		&dummyCsp);
+	if(srtn) {
+		errorLog1("sslPubKeyFromCert returned %d\n", srtn);
+		ortn = sslErrToOsStatus(srtn);
+		goto errOut;
+	}
+	
+	/* SUCCESS */ 
+	*destCert = certChain;
+	return noErr;
+	
+errOut:
+	/* free certChain, everything in it, other vars, return ortn */
+	sslDeleteCertificateChain(certChain, ctx);
+	if(keyInfo.keyPtr != NULL) {
+		sslFreeKey(keyInfo.cspHandle, &keyInfo.keyPtr, NULL);
+	}
+	if(keyParams.privateKeyItem != NULL) {
+		KCReleaseItem(&keyParams.privateKeyItem);
+	}
+	return ortn;
+}
+#endif	/* (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION) */
+
+/*
+ * Add Apple built-in root certs to ctx->trustedCerts.
+ */
+OSStatus addBuiltInCerts	(SSLContextRef		ctx)
+{
+	#if		ST_KEYCHAIN_ENABLE
+	OSStatus 			ortn;
+	KCRef				kc = nil;
+	
+	ortn = KCDispatch(kKCGetRootCertificateKeychain, &kc);
+	if(ortn) {
+		errorLog1("KCDispatch(kKCGetRootCertificateKeychain) returned %d\n", 
+			ortn);
+		return ortn;
+	}
+	return parseTrustedKeychain(ctx, kc);
+	#else
+	/* nothing for now */
+	return noErr;
+	#endif	/* ST_KEYCHAIN_ENABLE */
+}
+
+#if		ST_KEYCHAIN_ENABLE 
+
+/*
+ * Given an open Keychain:
+ * -- Get raw cert data, add to array of CSSM_DATAs in 
+ *    ctx->trustedCerts 
+ * -- verify that each of these is a valid (self-verifying)
+ *    root cert
+ * -- add each subject name to acceptableDNList
+ */
+OSStatus
+parseTrustedKeychain		(SSLContextRef		ctx,
+							 KCRef				keyChainRef)
+{
+	CFMutableArrayRef	kcCerts = NULL;		/* all certs in one keychain */
+	uint32				numGoodCerts = 0;	/* # of good root certs */
+	CSSM_DATA_PTR		certData = NULL;	/* array of CSSM_DATAs */
+	CFIndex				certDex;			/* index into kcCerts */
+	CFIndex				certsPerKc;			/* # of certs in this KC */
+	OSStatus			ortn;
+	KCItemRef			kcItem;				/* one cert */
+	Boolean				goodCert;
+	
+	CASSERT(ctx != NULL);
+	if(keyChainRef == NULL) {
+		return paramErr;
+	}
+	
+	ortn = KCFindX509Certificates(keyChainRef,
+		NULL,				// name, XXX
+		NULL,				// emailAddress, XXX
+		kCertSearchAny,		// options
+		&kcCerts);			// results
+	switch(ortn) {
+		case noErr:
+			break;					// proceed
+		case errKCItemNotFound:
+			return noErr;			// no certs; done
+		default:
+			errorLog1("parseTrustedKeychains: KCFindX509Certificates returned %d\n",
+				ortn);
+			return ortn;
+	}
+	if(kcCerts == NULL) {
+		dprintf0("parseTrustedKeychains: no certs in KC\n");
+		return noErr;
+	}
+	
+	/* Note kcCerts must be released on any exit, successful or
+	 * otherwise. */
+	
+	certsPerKc = CFArrayGetCount(kcCerts);	
+
+	/* 
+	 * This array gets allocd locally; we'll add it to 
+	 * ctx->trustedCerts when we're done.
+	 */
+	certData = sslMalloc(certsPerKc * sizeof(CSSM_DATA));
+	if(certData == NULL) {
+		ortn = memFullErr;
+		goto errOut;
+	}
+	memset(certData, 0, certsPerKc * sizeof(CSSM_DATA));
+	
+	/* 
+	 * Build up local certData one root cert at a time. 
+	 * Some certs might not pass muster, hence the numGoodCerts
+	 * which may or may not increment each time thru.
+	 */
+	for(certDex=0; certDex<certsPerKc; certDex++) {
+		kcItem = (KCItemRef)CFArrayGetValueAtIndex(kcCerts, certDex);
+		if(kcItem == NULL) {
+			errorLog0("parseTrustedKeychains: CF error 1\n");
+			ortn = errSSLInternal;
+			goto errOut;
+		}
+		if(!KCIsRootCertificate(kcItem)) {
+			/* not root, OK, skip to next cert */
+			dprintf1("parseTrustedKeychains: cert %d NOT ROOT\n",	certDex);
+			continue;
+		}
+		ortn = addCertData(ctx,
+			kcItem, 
+			&certData[numGoodCerts], 
+			&goodCert);
+		if(ortn) {
+			goto errOut;
+		}
+		if(goodCert) {
+			/* added valid root to certData */
+			numGoodCerts++;
+		}
+	}	/* for each cert in kcCerts */
+
+	#if	SSL_DEBUG
+	verifyTrustedRoots(ctx, certData, numGoodCerts);
+	#endif
+
+	/* Realloc ctx->trustedCerts, add new root certs */
+	ctx->trustedCerts = sslRealloc(ctx->trustedCerts, 
+		ctx->numTrustedCerts * sizeof(CSSM_DATA),
+		(ctx->numTrustedCerts + numGoodCerts) * sizeof(CSSM_DATA));
+	if(ctx->trustedCerts == NULL) {
+		ortn = memFullErr;
+		goto errOut;
+	}
+	for(certDex=0; certDex<numGoodCerts; certDex++) {
+		ctx->trustedCerts[ctx->numTrustedCerts + certDex] = certData[certDex];
+	}
+	ctx->numTrustedCerts += numGoodCerts;
+	ortn = noErr;
+	
+	#if	SSL_DEBUG
+	verifyTrustedRoots(ctx, ctx->trustedCerts, ctx->numTrustedCerts);
+	#endif
+	
+errOut:
+	sslFree(certData);
+	if(kcCerts != NULL) {
+		CFRelease(kcCerts);
+	}
+	return ortn;
+}
+
+/*
+ * Given a cert as a KCItemRef:
+ * -- verify that the cert self-verifies
+ * -- add its DER-encoded data *certData.
+ * -- Add its subjectName to acceptableDNList.
+ * -- If all is well, return True in *goodCert.
+ *
+ * The actual CSSM_DATA.Data is mallocd via CSSM_Malloc. 
+ */
+static OSStatus
+addCertData(
+	SSLContext		*ctx,
+	KCItemRef		kcItem,
+	CSSM_DATA_PTR	certData,
+	Boolean			*goodCert)		/* RETURNED */
+{	
+	UInt32			certSize;
+	OSStatus		ortn;
+	SSLErr			srtn;
+	CSSM_BOOL		subjectExpired;
+	CSSM_DATA_PTR	dnData;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(certData != NULL);	
+	CASSERT(kcItem != NULL);
+	CASSERT(goodCert != NULL);
+	
+	*goodCert = false; 
+	
+	/* how big is the cert? */
+	ortn = KCGetData (kcItem, 0,  NULL, &certSize);
+	if(ortn != noErr) {
+		errorLog1("addCertData: KCGetData(1) returned %d\n", ortn);
+		return ortn;
+	}
+
+	/* Allocate the buffer. */
+	srtn = stSetUpCssmData(certData, certSize);
+	if(srtn) {
+		return sslErrToOsStatus(srtn);
+	}
+	
+	/* Get the data. */
+	ortn = KCGetData (kcItem, certSize, certData->Data, &certSize);
+	if(ortn) {
+		errorLog1("addCertData: KCGetData(2) returned %d\n", ortn);
+		stFreeCssmData(certData, CSSM_FALSE);
+		return ortn;
+	}
+
+	/* 
+	 * Do actual cert verify, which 
+     * KCIsRootCertificate does not do. A failure isn't
+     * fatal; we just don't add the cert to the array in
+     * that case.
+     *
+     * FIXME - we assume here that our common cspHand can
+     * do this cert verify; if not, we have some API work to 
+     * do (to let the caller specify which CSP to use with 
+     * trusted certs).
+     */
+	if(!sslVerifyCert(ctx,	
+			certData,
+			certData,
+			ctx->cspHand,
+			&subjectExpired)) {			
+		dprintf0("addCertData: cert does not self-verify!\n");
+		stFreeCssmData(certData, CSSM_FALSE);
+		return noErr;
+	}
+	
+	/* Add this cert's subject name to (poss. existing) acceptableDNList */
+	dnData = sslGetCertSubjectName(ctx, certData);
+	if(dnData) {
+		DNListElem *dn = sslMalloc(sizeof(DNListElem));
+		if(dn == NULL) {
+			return memFullErr;
+		}
+		dn->next = ctx->acceptableDNList;
+		ctx->acceptableDNList = dn;
+		
+		/* move actual data to dn; free the CSSM_DATA struct (must be
+		 * via CSSM_Free()!) */
+		CSSM_TO_SSLBUF(dnData, &dn->derDN);
+		sslFree(dnData);
+	}
+
+	*goodCert = true;
+	return noErr;
+}
+
+/*
+ * Given a newly encountered root cert (obtained from a peer's cert chain),
+ * add it to newRootCertKc if the user so allows, and if so, add it to 
+ * trustedCerts.
+ */
+SSLErr
+sslAddNewRoot(
+	SSLContext			*ctx, 
+	const CSSM_DATA_PTR	rootCert)
+{
+	KCRef			defaultKc;
+	Boolean			bDefaultKcExists;
+	KCItemRef		certRef = NULL;
+	OSStatus		ortn;
+	CSSM_DATA_PTR	newTrustee;
+	SSLErr			serr;
+	
+	CASSERT(ctx != NULL);
+	CASSERT(rootCert != NULL);
+	CASSERT(ctx->newRootCertKc != NULL);	/* caller verifies this */
+	
+	/*
+	 * Get default KC, temporarily set new default.
+	 */
+	ortn = KCGetDefaultKeychain(&defaultKc);
+	if(ortn) {
+		bDefaultKcExists = false;
+	}
+	else {
+		bDefaultKcExists = true;
+	}
+	ortn = KCSetDefaultKeychain(ctx->newRootCertKc);
+	if(ortn) {
+		errorLog1("sslAddNewRoot: KCSetDefaultKeychain returned %d\n", ortn);
+		return SSLUnknownRootCert;
+	}
+
+	/*	
+	 * Add cert to newRootCertKc. This may well fail due to user
+	 * interaction ("Do you want to add this root cert...?").
+	 */
+	ortn = KCAddX509Certificate(rootCert->Data, rootCert->Length, &certRef);
+	
+	/* restore default KC in any case */
+	if(bDefaultKcExists) {
+		KCSetDefaultKeychain(defaultKc);
+	}
+	if(ortn) {
+		dprintf1("sslAddNewRoot: KCAddX509Certificate returned %d\n", ortn);
+		return SSLUnknownRootCert;
+	}
+
+	/* 
+	 * OK, user accepted new root. Now add to our private stash of 
+	 * trusted roots. Realloc the whole pile... 
+	 */
+	ctx->trustedCerts = (CSSM_DATA_PTR)sslRealloc(ctx->trustedCerts,
+		(ctx->numTrustedCerts * sizeof(CSSM_DATA)),
+		((ctx->numTrustedCerts + 1) * sizeof(CSSM_DATA)));
+	if(ctx->trustedCerts == NULL) {
+		return SSLMemoryErr;
+	}
+	
+	/* Now add a copy of the new root. */
+	newTrustee = &ctx->trustedCerts[ctx->numTrustedCerts];
+	newTrustee->Data = NULL;
+	newTrustee->Length = 0;
+	serr = stSetUpCssmData(newTrustee, rootCert->Length);
+	if(serr) {
+		return serr;
+	}
+	BlockMove(rootCert->Data, newTrustee->Data, rootCert->Length);
+	(ctx->numTrustedCerts)++;
+	return SSLNoErr;
+}
+
+#endif	/* ST_KEYCHAIN_ENABLE */
+
diff --git a/SecureTransport/sslalert.c b/SecureTransport/sslalert.c
new file mode 100644
index 00000000..27d4e6c6
--- /dev/null
+++ b/SecureTransport/sslalert.c
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: sslalert.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslalert.c   Support for alert protocol in SSL 3
+
+    Encoding, decoding and processing for the SSL alert protocol. Also,
+    support for sending fatal alerts, which also closes down our
+    connection, including invalidating our cached session.
+
+    ****************************************************************** */
+
+#include "ssl.h"
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLSESS_H_
+#include "sslsess.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+SSLErr
+SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
+{   SSLErr              err = SSLNoErr;
+    AlertLevel          level;
+    AlertDescription    desc;
+    uint8               *progress;
+    uint32              remaining;
+    
+    if (rec.contents.length % 2 != 0)
+    {   ERR(err = SSLFatalSessionAlert(alert_illegal_parameter, ctx));
+        if (!err)
+            ERR(err = SSLProtocolErr);
+        return err;
+    }
+    
+    progress = rec.contents.data;
+    remaining = rec.contents.length;
+    while (remaining > 0)
+    {   level = (AlertLevel)*progress++;
+        desc = (AlertDescription)*progress++;
+        remaining -= 2;
+        
+        /* 
+         * APPLE_CDSA changes: ignore sessionID-related failures here;
+         * the important thing is the alert. 
+         */
+        if (level == alert_fatal)
+        {   
+        	SSLDeleteSessionID(ctx);
+            dprintf1("***Fatal alert %d received", desc);
+            return SSLFatalAlert;
+        }
+        
+        switch (desc)
+        {   case alert_unexpected_message:
+            case alert_bad_record_mac:
+            case alert_decompression_failure:
+            case alert_handshake_failure:
+            case alert_illegal_parameter:
+                /* These must always be fatal; if we got here, the level is warning;
+                 *  die anyway
+                 */
+                SSLDeleteSessionID(ctx);
+                err = SSLFatalAlert;
+                break;
+            case alert_close_notify:
+                ERR(SSLClose(ctx));
+                err = SSLNoErr;
+                break;
+            case alert_no_certificate:
+                if (ctx->state == HandshakeClientCertificate)
+                    if (ERR(err = SSLAdvanceHandshake(SSL_certificate, ctx)) != 0)
+                        return err;
+                break;
+            case alert_bad_certificate:
+            case alert_unsupported_certificate:
+            case alert_certificate_revoked:
+            case alert_certificate_expired:
+            case alert_certificate_unknown:
+                err = SSLNoErr;
+                break;
+            default:
+                /* Unknown alert, but not fatal; ignore it */
+                break;
+        }
+    }
+    
+    return err;
+}
+
+SSLErr
+SSLSendAlert(AlertLevel level, AlertDescription desc, SSLContext *ctx)
+{   SSLRecord       rec;
+    SSLErr          err;
+    
+    CASSERT((ctx->negProtocolVersion == SSL_Version_3_0) ||
+            (ctx->negProtocolVersion == SSL_Version_Undetermined) ||
+            (ctx->negProtocolVersion == SSL_Version_3_0_Only));
+    
+    if ((err = SSLEncodeAlert(&rec, level, desc, ctx)) != 0)
+        return err;
+    if ((err = SSLWriteRecord(rec, ctx)) != 0)
+        return err;
+    if ((err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
+        return err;
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSLEncodeAlert(SSLRecord *rec, AlertLevel level, AlertDescription desc, SSLContext *ctx)
+{   SSLErr          err;
+    
+    rec->contentType = SSL_alert;
+    rec->protocolVersion = SSL_Version_3_0;
+    rec->contents.length = 2;
+    if ((err = SSLAllocBuffer(&rec->contents, 2, &ctx->sysCtx)) != 0)
+        return err;
+    rec->contents.data[0] = level;
+    rec->contents.data[1] = desc;
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSLFatalSessionAlert(AlertDescription desc, SSLContext *ctx)
+{   SSLErr          err1, err2;
+    
+    if(desc != alert_close_notify) {
+    	errorLog1("SSLFatalSessionAlert: desc %d\n", desc);
+    }
+	//dprintf0("SSLFatalSessionAlert: going to state ErrorClose\n");
+    SSLChangeHdskState(ctx, SSLErrorClose);
+    
+    /* Make session unresumable; I'm not stopping if I get an error,
+        because I'd like to attempt to send the alert anyway */
+    err1 = SSLDeleteSessionID(ctx);
+    
+    /* Second, send the alert */
+    err2 = SSLSendAlert(alert_fatal, desc, ctx);
+    
+    /* If they both returned errors, arbitrarily return the first */
+    return err1 != 0 ? err1 : err2;
+}
diff --git a/SecureTransport/sslalloc.c b/SecureTransport/sslalloc.c
new file mode 100644
index 00000000..46870116
--- /dev/null
+++ b/SecureTransport/sslalloc.c
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslalloc.c
+
+	Contains:	memory allocator implementation
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: sslalloc.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslalloc.c   Utility functions for doing allocation
+
+    These functions call the user-supplied callbacks to
+    allocate/free/reallocate memory
+
+    ****************************************************************** */
+
+#include "sslalloc.h"
+#include "sslctx.h"
+#include "sslDebug.h"
+
+#ifdef	_APPLE_CDSA_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+#pragma mark *** CF Allocators ***
+
+/* copied from CSSMCFUtilities in the AppleCSP:CSPLib project.... */
+
+static void* cfAllocate(CFIndex size, CFOptionFlags hint, void *info)
+{
+	return sslMalloc((Size)size);
+}
+
+static void* cfReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info)
+{
+	return sslRealloc(ptr, (Size)newsize, (Size)newsize);
+}
+
+static void cfDeallocate(void *ptr, void *info)
+{
+	sslFree(ptr);
+}
+
+/*
+ * Set up/tear down CF allocators.
+ */
+OSStatus cfSetUpAllocators(SSLContext *ctx)
+{
+	/* Initialize gCFAllocatorContext with the system default
+	   allocator context.  */
+	CFAllocatorGetContext(kCFAllocatorSystemDefault, &ctx->lCFAllocatorContext);
+
+	ctx->lCFAllocatorContext.allocate   = cfAllocate;
+	ctx->lCFAllocatorContext.reallocate = cfReallocate;
+	ctx->lCFAllocatorContext.deallocate = cfDeallocate;
+
+	ctx->cfAllocatorRef = CFAllocatorCreate(kCFAllocatorUseContext, 
+		&ctx->lCFAllocatorContext);
+	if (!ctx->cfAllocatorRef)
+		return memFullErr; 
+
+	return noErr;
+}
+
+void cfTearDownAllocators(SSLContext *ctx)
+{
+	if (ctx->cfAllocatorRef != NULL)
+		CFRelease(ctx->cfAllocatorRef);
+}
+
+#pragma mark *** Basic low-level malloc/free ***
+
+/*
+ * For now, all allocs/frees go thru here. 
+ */
+#include <string.h>			/* memset */
+#include <stdlib.h>
+
+void *
+sslMalloc(UInt32 length)
+{   
+	return malloc(length);
+}
+
+void
+sslFree(void *p)
+{   
+	if(p != nil) {
+		free(p);
+	}
+}
+
+void *
+sslRealloc(void *oldPtr, UInt32 oldLen, UInt32 newLen)
+{   
+	return realloc(oldPtr, newLen);
+}
+
+#endif
+
+#pragma mark *** SSLBuffer-level alloc/free ***
+
+SSLErr
+SSLAllocBuffer(SSLBuffer *buf, UInt32 length, const SystemContext *ctx)
+{   
+	buf->data = sslMalloc(length);
+	if(buf->data == NULL) {
+		buf->length = 0;
+		return SSLMemoryErr;
+	}
+    buf->length = length;
+    return SSLNoErr;
+}
+
+SSLErr
+SSLFreeBuffer(SSLBuffer *buf, const SystemContext *ctx)
+{   
+	if(buf == NULL) {
+		errorLog0("SSLFreeBuffer: NULL buf!\n");
+		return SSLInternalError;
+	}
+    sslFree(buf->data);
+    buf->data = NULL;
+    buf->length = 0;
+    return SSLNoErr;
+}
+
+SSLErr
+SSLReallocBuffer(SSLBuffer *buf, UInt32 newSize, const SystemContext *ctx)
+{   
+	buf->data = sslRealloc(buf->data, buf->length, newSize);
+	if(buf->data == NULL) {
+		buf->length = 0;
+		return SSLMemoryErr;
+	}
+	buf->length = newSize;
+	return SSLNoErr;
+}
+
+#pragma mark *** Convenience routines ***
+
+UInt8 *sslAllocCopy(
+	const UInt8 *src,
+	UInt32 len)
+{
+	UInt8 *dst;
+	
+	dst = sslMalloc(len);
+	if(dst == NULL) {
+		return NULL;
+	} 
+	memmove(dst, src, len);
+	return dst;
+} 
diff --git a/SecureTransport/sslctx.c b/SecureTransport/sslctx.c
new file mode 100644
index 00000000..1707af31
--- /dev/null
+++ b/SecureTransport/sslctx.c
@@ -0,0 +1,732 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslctx.c
+
+	Contains:	SSLContext accessors
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: sslctx.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslctx.c     SSLContext accessors
+
+    Functions called by the end user which configure an SSLContext
+    structure or access data stored there.
+
+    ****************************************************************** */
+
+
+#include "ssl.h"
+#include "sslctx.h"
+#include "sslalloc.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include "digests.h"
+#include "sslDebug.h"
+#include "appleCdsa.h"
+#include "appleGlue.h"
+#include "sslKeychain.h"
+#include "sslutil.h"
+#include "cipherSpecs.h"
+
+#include <string.h>
+
+static void sslFreeDnList(
+	SSLContext *ctx)
+{
+    DNListElem      *dn, *nextDN;
+    SSLBuffer       buf;
+    
+    dn = ctx->acceptableDNList;
+
+    while (dn)
+    {   
+    	SSLFreeBuffer(&dn->derDN, &ctx->sysCtx);
+        nextDN = dn->next;
+        buf.data = (uint8*)dn;
+        buf.length = sizeof(DNListElem);
+        SSLFreeBuffer(&buf, &ctx->sysCtx);
+        dn = nextDN;
+    }
+    ctx->acceptableDNList = NULL;
+}
+
+static SSLErr sslFreeTrustedRoots(
+	SSLContext *ctx)
+{
+	int i;
+	
+	CASSERT(ctx != NULL);
+	if((ctx->numTrustedCerts == 0) || (ctx->trustedCerts == NULL)) {
+		/* they really should both be zero, right? */
+		CASSERT((ctx->numTrustedCerts == 0) && (ctx->trustedCerts == NULL));
+	}
+	else {
+		for(i=0; i<ctx->numTrustedCerts; i++) {
+			stFreeCssmData(&ctx->trustedCerts[i], CSSM_FALSE);
+		}
+		sslFree(ctx->trustedCerts);
+	}
+	ctx->numTrustedCerts = 0;
+	ctx->trustedCerts = NULL;
+	sslFreeDnList(ctx);
+	return SSLNoErr;
+}
+
+OSStatus
+SSLNewContext				(Boolean 			isServer,
+							 SSLContextRef 		*contextPtr)	/* RETURNED */
+{
+	SSLContext 	*ctx;
+	OSStatus 	oerr;
+	SSLErr		serr;
+		
+	if(contextPtr == NULL) {
+		return paramErr;
+	}
+	*contextPtr = NULL;
+	ctx = (SSLContext *)sslMalloc(sizeof(SSLContext));
+	if(ctx == NULL) {
+		return memFullErr;
+	}
+	/* subsequent errors to errOut: */
+	
+    memset(ctx, 0, sizeof(SSLContext));
+    ctx->state = SSLUninitialized;
+    
+    /* different defaults for client and server ... */
+    if(isServer) {
+    	ctx->protocolSide = SSL_ServerSide;
+    	ctx->reqProtocolVersion = SSL_Version_3_0;
+    }
+    else {
+    	ctx->protocolSide = SSL_ClientSide;
+    	ctx->reqProtocolVersion = SSL_Version_Undetermined;
+    }
+    ctx->negProtocolVersion = SSL_Version_Undetermined;
+	
+    /* Initialize the cipher state to NULL_WITH_NULL_NULL */
+    ctx->selectedCipherSpec = &SSL_NULL_WITH_NULL_NULL_CipherSpec;
+    ctx->selectedCipher = ctx->selectedCipherSpec->cipherSpec;
+    ctx->writeCipher.hash = ctx->selectedCipherSpec->macAlgorithm;
+    ctx->readCipher.hash = ctx->selectedCipherSpec->macAlgorithm;
+    ctx->readCipher.symCipher = ctx->selectedCipherSpec->cipher;
+    ctx->writeCipher.symCipher = ctx->selectedCipherSpec->cipher;
+	
+	#if		_APPLE_CDSA_
+	/* these two are invariant */
+    ctx->writeCipher.encrypting = 1;
+    ctx->writePending.encrypting = 1;
+	#endif	/* _APPLE_CDSA_ */
+	
+    /* this gets init'd on first call to SSLHandshake() */
+    ctx->validCipherSpecs = NULL;
+    ctx->numValidCipherSpecs = 0;
+    
+    SSLInitMACPads();
+	if(cfSetUpAllocators(ctx)) {
+		oerr = memFullErr;
+		goto errOut;
+	}
+	
+	/* attach to CSP, CL, TP */
+	serr = attachToAll(ctx);
+	if(serr) {
+		oerr = sslErrToOsStatus(serr);
+		goto errOut;
+	}
+	
+	/* snag root certs from Keychain, tolerate error */
+	addBuiltInCerts(ctx);
+	
+    *contextPtr = ctx;
+    return noErr;
+    
+errOut:
+	sslFree(ctx);
+	return oerr;
+}
+
+
+/*
+ * Dispose of an SSLContext.
+ */
+OSStatus
+SSLDisposeContext				(SSLContext			*ctx)
+{   
+	WaitingRecord   *wait, *next;
+    SSLBuffer       buf;
+    
+    if(ctx == NULL) {
+    	return paramErr;
+    }
+    sslDeleteCertificateChain(ctx->localCert, ctx);
+    sslDeleteCertificateChain(ctx->encryptCert, ctx);
+    sslDeleteCertificateChain(ctx->peerCert, ctx);
+    ctx->localCert = ctx->encryptCert = ctx->peerCert = NULL;
+    SSLFreeBuffer(&ctx->partialReadBuffer, &ctx->sysCtx);
+    
+    wait = ctx->recordWriteQueue;
+    while (wait)
+    {   SSLFreeBuffer(&wait->data, &ctx->sysCtx);
+        next = wait->next;
+        buf.data = (uint8*)wait;
+        buf.length = sizeof(WaitingRecord);
+        SSLFreeBuffer(&buf, &ctx->sysCtx);
+        wait = next;
+    }
+    
+    SSLFreeBuffer(&ctx->dhPeerPublic, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->dhExchangePublic, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->dhPrivate, &ctx->sysCtx);
+    
+    SSLFreeBuffer(&ctx->shaState, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->md5State, &ctx->sysCtx);
+    
+    SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->peerID, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->resumableSession, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->partialReadBuffer, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->fragmentedMessageCache, &ctx->sysCtx);
+    SSLFreeBuffer(&ctx->receivedDataBuffer, &ctx->sysCtx);
+
+    SSLDisposeCipherSuite(&ctx->readCipher, ctx);
+    SSLDisposeCipherSuite(&ctx->writeCipher, ctx);
+    SSLDisposeCipherSuite(&ctx->readPending, ctx);
+    SSLDisposeCipherSuite(&ctx->writePending, ctx);
+
+	sslFree(ctx->validCipherSpecs);
+	ctx->validCipherSpecs = NULL;
+	ctx->numValidCipherSpecs = 0;
+	
+	/* free APPLE_CDSA stuff */
+	#if		ST_KEYCHAIN_ENABLE
+	sslFreeKey(ctx->signingKeyCsp, &ctx->signingPrivKey, &ctx->signingKeyRef);
+	sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPrivKey, &ctx->encryptKeyRef);
+	#else	
+	sslFreeKey(ctx->signingKeyCsp, &ctx->signingPrivKey, NULL);
+	sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPrivKey, NULL);
+	#endif	/* ST_KEYCHAIN_ENABLE */
+	sslFreeKey(ctx->signingKeyCsp, &ctx->signingPubKey, NULL);
+	sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPubKey, NULL);
+	sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
+	
+	#if		SSL_DEBUG
+	if(ctx->rootCertName != NULL) {
+		sslFree(ctx->rootCertName);
+	}
+	#endif	/* SSL_DEBUG */
+	
+	sslFreeTrustedRoots(ctx);
+	
+	detachFromAll(ctx);
+	    
+    cfTearDownAllocators(ctx);
+    memset(ctx, 0, sizeof(SSLContext));
+    sslFree(ctx);
+    return noErr;
+}
+
+/*
+ * Determine the state of an SSL session.
+ */
+OSStatus 
+SSLGetSessionState			(SSLContextRef		context,
+							 SSLSessionState	*state)		/* RETURNED */
+{
+	SSLSessionState rtnState = kSSLIdle;
+	
+	if(context == NULL) {
+		return paramErr;
+	}
+	*state = rtnState;
+	switch(context->state) {
+		case SSLUninitialized:
+		case HandshakeServerUninit:
+		case HandshakeClientUninit:
+			rtnState = kSSLIdle;
+			break;
+		case SSLGracefulClose:
+			rtnState = kSSLClosed;
+			break;
+		case SSLErrorClose:
+		case SSLNoNotifyClose:
+			rtnState = kSSLAborted;
+			break;
+		case HandshakeServerReady:
+		case HandshakeClientReady:
+			rtnState = kSSLConnected;
+			break;
+		default:
+			CASSERT((context->state >= HandshakeServerHello) &&
+			        (context->state <= HandshakeSSL2ServerFinished));
+			rtnState = kSSLHandshake;
+			break;
+			
+	}
+	*state = rtnState;
+	return noErr;
+}
+
+OSStatus 
+SSLSetIOFuncs				(SSLContextRef		ctx, 
+							 SSLReadFunc 		read,
+							 SSLWriteFunc		write)
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	ctx->ioCtx.read = read;
+	ctx->ioCtx.write = write;
+	return noErr;
+}
+
+OSStatus
+SSLSetConnection			(SSLContextRef		ctx,
+							 SSLConnectionRef	connection)
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	ctx->ioCtx.ioRef = connection;
+    return noErr;
+}
+
+OSStatus 
+SSLSetProtocolVersion		(SSLContextRef 		ctx,
+							 SSLProtocol		version)
+{   
+	SSLProtocolVersion	versInt;
+	
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+
+	/* convert external representation to private */
+	switch(version) {
+		case kSSLProtocolUnknown:
+			versInt = SSL_Version_Undetermined;
+			break;
+		case kSSLProtocol2:
+			versInt = SSL_Version_2_0;
+			break;
+		case kSSLProtocol3:
+			/* this tells us to do our best but allows 2.0 */
+			versInt = SSL_Version_Undetermined;
+			break;
+		case kSSLProtocol3Only:
+			versInt = SSL_Version_3_0_Only;
+			break;
+		default:
+			return paramErr;
+	}
+	ctx->reqProtocolVersion = ctx->negProtocolVersion = versInt;
+    return noErr;
+}
+
+static SSLProtocol convertProtToExtern(SSLProtocolVersion prot)
+{
+	switch(prot) {
+		case SSL_Version_Undetermined:
+			return kSSLProtocolUnknown;
+		case SSL_Version_3_0_Only:
+			return kSSLProtocol3Only;
+		case SSL_Version_2_0:
+			return kSSLProtocol2;
+		case SSL_Version_3_0:
+			return kSSLProtocol3;
+		case SSL_Version_3_0_With_2_0_Hello:
+			sslPanic("How did we get SSL_Version_3_0_With_2_0_Hello?");
+		default:
+			sslPanic("convertProtToExtern: bad prot");
+	}
+	/* not reached but make compiler happy */
+	return kSSLProtocolUnknown;
+}
+
+OSStatus 
+SSLGetProtocolVersion		(SSLContextRef		ctx,
+							 SSLProtocol		*protocol)		/* RETURNED */
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	*protocol = convertProtToExtern(ctx->reqProtocolVersion);
+	return noErr;
+}
+
+OSStatus 
+SSLGetNegotiatedProtocolVersion		(SSLContextRef		ctx,
+									 SSLProtocol		*protocol) /* RETURNED */
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	*protocol = convertProtToExtern(ctx->negProtocolVersion);
+	return noErr;
+}
+
+OSStatus 
+SSLSetAllowExpiredCerts	(SSLContextRef		ctx,
+						 Boolean			allowExpired)
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	ctx->allowExpiredCerts = allowExpired;
+	return noErr;
+}
+
+OSStatus
+SSLGetAllowExpiredCerts		(SSLContextRef		ctx,
+							 Boolean			*allowExpired)
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	*allowExpired = ctx->allowExpiredCerts;
+	return noErr;
+}
+
+OSStatus SSLSetAllowAnyRoot(
+	SSLContextRef	ctx,
+	Boolean			anyRoot)
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	ctx->allowAnyRoot = anyRoot;
+	return noErr;
+}
+
+OSStatus
+SSLGetAllowAnyRoot(
+	SSLContextRef	ctx,
+	Boolean			*anyRoot)
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	*anyRoot = ctx->allowAnyRoot;
+	return noErr;
+}
+
+#if	ST_SERVER_MODE_ENABLE
+OSStatus
+SSLSetClientSideAuthenticate 	(SSLContext			*ctx,
+								 SSLAuthenticate	auth)
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	ctx->clientAuth = auth;
+	switch(auth) {
+		case kNeverAuthenticate:
+			ctx->tryClientAuth = false;
+			break;
+		case kAlwaysAuthenticate:
+		case kTryAuthenticate:
+			/* FIXME - needs work to distinguish these cases at
+			 * handshake time */
+			ctx->tryClientAuth = true;
+			break;
+	}
+	return noErr;
+}
+#endif	/* ST_SERVER_MODE_ENABLE */
+
+#if	(ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION)
+
+OSStatus
+SSLSetCertificate			(SSLContextRef		ctx,
+							 CFArrayRef			certRefs)
+{
+	/*
+	 * -- free localCerts if we have any
+	 * -- Get raw cert data, convert to ctx->localCert
+	 * -- get pub, priv keys from certRef[0]
+	 * -- validate cert chain
+	 */
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	return parseIncomingCerts(ctx,
+		certRefs,
+		&ctx->localCert,
+		&ctx->signingPubKey,
+		&ctx->signingPrivKey,
+		&ctx->signingKeyCsp,
+		&ctx->signingKeyRef);
+}
+#endif	/* (ST_SERVER_MODE_ENABLE || ST_CLIENT_AUTHENTICATION) */
+
+#if	ST_SERVER_MODE_ENABLE
+OSStatus
+SSLSetEncryptionCertificate	(SSLContextRef		ctx,
+							 CFArrayRef			certRefs)
+{
+	/*
+	 * -- free encryptCert if we have any
+	 * -- Get raw cert data, convert to ctx->encryptCert
+	 * -- get pub, priv keys from certRef[0]
+	 * -- validate cert chain
+	 */
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	return parseIncomingCerts(ctx,
+		certRefs,
+		&ctx->encryptCert,
+		&ctx->encryptPubKey,
+		&ctx->encryptPrivKey,
+		&ctx->encryptKeyCsp,
+		&ctx->encryptKeyRef);
+}
+#endif	/* ST_SERVER_MODE_ENABLE*/
+
+#if		ST_KEYCHAIN_ENABLE
+
+/*
+ * Add (optional, additional) trusted root certs.
+ */
+OSStatus
+SSLSetTrustedRootCertKC		(SSLContextRef		ctx,
+							 KCRef				keyChainRef,
+							 Boolean			deleteExisting)
+{
+	/*
+	 * -- free trustedCerts if deleteExisting
+	 * -- Get raw cert data, add to ctx->trustedCerts
+	 * -- verify that each of these is a valid (self-verifying)
+	 *    root cert
+	 * -- add each subject name to acceptableDNList
+	 */
+	if((ctx == NULL) || (keyChainRef == nil)) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	if(deleteExisting) {
+		sslFreeTrustedRoots(ctx);
+	}
+	return parseTrustedKeychain(ctx, keyChainRef);
+}
+
+OSStatus 
+SSLSetNewRootKC				(SSLContextRef		ctx,
+							 KCRef				keyChainRef,
+							 void				*accessCreds)
+{
+	if((ctx == NULL) || (keyChainRef == nil)) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	if(ctx->newRootCertKc != NULL) {
+		/* can't do this multiple times */
+		return badReqErr;
+	}
+	ctx->newRootCertKc = keyChainRef;
+	ctx->accessCreds = accessCreds;
+	return noErr;
+}
+#endif	/* ST_KEYCHAIN_ENABLE */
+
+OSStatus 
+SSLSetPeerID				(SSLContext 		*ctx, 
+							 CFDataRef 			peerID)
+{
+	SSLErr serr;
+	uint32 len;
+	
+	/* copy peerId to context->peerId */
+	if((ctx == NULL) || 
+	   (peerID == NULL) ||
+	   ((len = CFDataGetLength(peerID)) == 0)) {
+		return paramErr;
+	}
+	if(sslIsSessionActive(ctx)) {
+		/* can't do this with an active session */
+		return badReqErr;
+	}
+	SSLFreeBuffer(&ctx->peerID, &ctx->sysCtx);
+	serr = SSLAllocBuffer(&ctx->peerID, len, &ctx->sysCtx);
+	if(serr) {
+		return sslErrToOsStatus(serr);
+	}
+	memmove(ctx->peerID.data, CFDataGetBytePtr(peerID), len);
+	ctx->peerID.length = len;
+	return noErr;
+}
+
+OSStatus 
+SSLGetNegotiatedCipher		(SSLContextRef 		ctx,
+							 SSLCipherSuite 	*cipherSuite)
+{
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	if(!sslIsSessionActive(ctx)) {
+		return badReqErr;
+	}
+	*cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
+	return noErr;
+}
+
+/*
+ * Add an acceptable distinguished name.
+ * FIXME - this looks like a big hole in the SSLRef code; 
+ * acceptableDNList is set here and in SSLProcessCertificateRequest();
+ * it's used and sent to a client in SSLEncodeCertificateRequest();
+ * but the list is never used to decide what certs to send!
+ *
+ * Also FIXME - this allocation of dnBufs is total horseshit. The
+ * SSLBufs can never get freed. Why not just allocate the 
+ * raw DNListElems? Sheesh. 
+ */
+#if 0
+/* not used */
+static SSLErr
+SSLAddDistinguishedName(SSLContext *ctx, SSLBuffer derDN)
+{   SSLBuffer       dnBuf;
+    DNListElem      *dn;
+    SSLErr          err;
+    
+    if ((err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem), &ctx->sysCtx)) != 0)
+        return err;
+    dn = (DNListElem*)dnBuf.data;
+    if ((err = SSLAllocBuffer(&dn->derDN, derDN.length, &ctx->sysCtx)) != 0)
+    {   SSLFreeBuffer(&dnBuf, &ctx->sysCtx);
+        return err;
+    }
+    memcpy(dn->derDN.data, derDN.data, derDN.length);
+    dn->next = ctx->acceptableDNList;
+    ctx->acceptableDNList = dn;
+    return SSLNoErr;
+}
+#endif	/* not used */
+
+/*
+ * Request peer certificates. Valid anytime, subsequent to
+ * a handshake attempt.
+ */	
+OSStatus 
+SSLGetPeerCertificates		(SSLContextRef 		ctx, 
+							 CFArrayRef			*certs)
+{
+	uint32 				numCerts;
+	CFMutableArrayRef	ca;
+	CFIndex				i;
+	CFDataRef			cfd;
+	SSLCertificate		*scert;
+	
+	if(ctx == NULL) {
+		return paramErr;
+	}
+	*certs = NULL;
+	
+	/* 
+	 * Copy peerCert, a chain of SSLCertificates, to a CFArray of 
+	 * CFDataRefs, each of which is one DER-encoded cert.
+	 */
+	numCerts = SSLGetCertificateChainLength(ctx->peerCert);
+	if(numCerts == 0) {
+		return noErr;
+	}
+	ca = CFArrayCreateMutable(ctx->cfAllocatorRef,
+		(CFIndex)numCerts, &kCFTypeArrayCallBacks);
+	if(ca == NULL) {
+		return memFullErr;	
+	}
+	
+	/*
+	 * We'll give the certs in the same order we store them -
+	 * caller gets root first. OK?
+	 */
+	scert = ctx->peerCert;
+	for(i=0; i<numCerts; i++) {
+		CASSERT(scert != NULL);		/* else SSLGetCertificateChainLength 
+									 * broken */
+		cfd = CFDataCreate(ctx->cfAllocatorRef,
+				scert->derCert.data,
+				scert->derCert.length);
+		if(cfd == NULL) {
+			CFRelease(ca);
+			return memFullErr;
+		}
+		CFArrayAppendValue(ca, cfd);
+		scert = scert->next;
+	}
+	*certs = ca;
+	return noErr;
+}							 								 
+   
+
+
diff --git a/SecureTransport/sslhdshk.c b/SecureTransport/sslhdshk.c
new file mode 100644
index 00000000..a43a2e09
--- /dev/null
+++ b/SecureTransport/sslhdshk.c
@@ -0,0 +1,788 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslhdshk.c
+
+	Contains:	SSL 3.0 handshake state machine. 
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: sslhdshk.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslhdshk.c   SSL 3.0 handshake state machine
+
+    Support for SSL Handshake messages, including extracting handshake
+    messages from record layer records, processing those messages
+    (including verifying their appropriateness) and then advancing the
+    handshake by generating response messages and/or changing the state
+    such that different messages are expected. In addition, controls when
+    keys are generated.
+
+    ****************************************************************** */
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLHDSHK_H_
+#include "sslhdshk.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef _SSLSESS_H_
+#include "sslsess.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef	_APPLE_CDSA_H_
+#include "appleCdsa.h"
+#endif
+
+#include <string.h>
+
+#define REQUEST_CERT_CORRECT        0
+
+static SSLErr SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
+
+SSLErr
+SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
+{   SSLErr          err;
+    sint32          remaining;
+    UInt8           *p;
+    SSLHandshakeMsg message;
+    SSLBuffer       messageData;
+    
+    if (ctx->fragmentedMessageCache.data != 0)
+    {   if ((err = SSLReallocBuffer(&ctx->fragmentedMessageCache,
+                    ctx->fragmentedMessageCache.length + rec.contents.length,
+                    &ctx->sysCtx)) != 0)
+        {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+            return ERR(err);
+        }
+        memcpy(ctx->fragmentedMessageCache.data + ctx->fragmentedMessageCache.length,
+            rec.contents.data, rec.contents.length);
+        remaining = ctx->fragmentedMessageCache.length;
+        p = ctx->fragmentedMessageCache.data;
+    }
+    else
+    {   remaining = rec.contents.length;
+        p = rec.contents.data;
+    }
+
+    while (remaining > 0)
+    {   if (remaining < 4)
+            break;  /* we must have at least a header */
+        
+        messageData.data = p;
+        message.type = (SSLHandshakeType)*p++;
+        message.contents.length = SSLDecodeInt(p, 3);
+        if ((message.contents.length + 4) > remaining)
+            break;
+        
+        p += 3;
+        message.contents.data = p;
+        p += message.contents.length;
+        messageData.length = 4 + message.contents.length;
+        CASSERT(p == messageData.data + messageData.length);
+        
+        /* message fragmentation */
+        remaining -= messageData.length;
+        if (ERR(err = SSLProcessHandshakeMessage(message, ctx)) != 0)
+            return err;
+        
+        if (message.type != SSL_hello_request)
+        {   if (ERR(err = SSLHashSHA1.update(ctx->shaState, messageData)) != 0 ||
+                ERR(err = SSLHashMD5.update(ctx->md5State, messageData)) != 0)
+            {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                return err;
+            }
+        }
+        
+        if (ERR(err = SSLAdvanceHandshake(message.type, ctx)) != 0)
+            return err;
+    }
+    
+    if (remaining > 0)      /* Fragmented handshake message */
+    {   /* If there isn't a cache, allocate one */
+        if (ctx->fragmentedMessageCache.data == 0)
+        {   if (ERR(err = SSLAllocBuffer(&ctx->fragmentedMessageCache, remaining, &ctx->sysCtx)) != 0)
+            {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                return err;
+            }
+        }
+        if (p != ctx->fragmentedMessageCache.data)
+        {   memcpy(ctx->fragmentedMessageCache.data, p, remaining);
+            ctx->fragmentedMessageCache.length = remaining;
+        }
+    }
+    else if (ctx->fragmentedMessageCache.data != 0)
+    {   if (ERR(err = SSLFreeBuffer(&ctx->fragmentedMessageCache, &ctx->sysCtx)) != 0)
+        {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+            return err;
+        }
+    }
+    
+    return SSLNoErr;
+}
+
+static SSLErr
+SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
+{   SSLErr      err;
+    
+    err = SSLNoErr;
+    SSLLogHdskMsg(message.type, 0);
+    switch (message.type)
+    {   case SSL_hello_request:
+            if (ctx->protocolSide != SSL_ClientSide)
+                goto wrongMessage;
+            if (message.contents.length > 0)
+                err = ERR(SSLProtocolErr);
+            break;
+        case SSL_client_hello:
+            if (ctx->state != HandshakeServerUninit)
+                goto wrongMessage;
+            ERR(err = SSLProcessClientHello(message.contents, ctx));
+            break;
+        case SSL_server_hello:
+            if (ctx->state != HandshakeServerHello &&
+                ctx->state != HandshakeServerHelloUnknownVersion)
+                goto wrongMessage;
+            ERR(err = SSLProcessServerHello(message.contents, ctx));
+            break;
+        case SSL_certificate:
+            if (ctx->state != HandshakeCertificate &&
+                ctx->state != HandshakeClientCertificate)
+                goto wrongMessage;
+            ERR(err = SSLProcessCertificate(message.contents, ctx));
+            break;
+        case SSL_certificate_request:
+            if ((ctx->state != HandshakeHelloDone && ctx->state != HandshakeKeyExchange)
+                 || ctx->certRequested)
+                goto wrongMessage;
+            ERR(err = SSLProcessCertificateRequest(message.contents, ctx));
+            break;
+        case SSL_server_key_exchange:
+             #if _APPLE_CDSA_
+       		/* 
+        	 * Since this message is optional, and completely at the
+        	 * server's discretion, we need to be able to handle this
+        	 * in one of two states...
+        	 */
+        	switch(ctx->state) {
+        		case HandshakeKeyExchange:	/* explicitly waiting for this */
+        		case HandshakeHelloDone:
+        			break;
+        		default:
+                	goto wrongMessage;
+        	}
+        	#else
+            if (ctx->state != HandshakeKeyExchange)
+                goto wrongMessage;
+            #endif	/* _APPLE_CDSA_ */
+            ERR(err = SSLProcessServerKeyExchange(message.contents, ctx));
+            break;
+        case SSL_server_hello_done:
+            if (ctx->state != HandshakeHelloDone)
+                goto wrongMessage;
+            ERR(err = SSLProcessServerHelloDone(message.contents, ctx));
+            break;
+        case SSL_certificate_verify:
+            if (ctx->state != HandshakeClientCertVerify)
+                goto wrongMessage;
+            ERR(err = SSLProcessCertificateVerify(message.contents, ctx));
+            break;
+        case SSL_client_key_exchange:
+            if (ctx->state != HandshakeClientKeyExchange)
+                goto wrongMessage;
+            ERR(err = SSLProcessKeyExchange(message.contents, ctx));
+            break;
+        case SSL_finished:
+            if (ctx->state != HandshakeFinished)
+                goto wrongMessage;
+            ERR(err = SSLProcessFinished(message.contents, ctx));
+            break;
+        default:
+            goto wrongMessage;
+            break;
+    }
+    
+    if (err)
+    {   if (err == SSLProtocolErr)
+            ERR(SSLFatalSessionAlert(alert_illegal_parameter, ctx));
+        else if (err == SSLNegotiationErr)
+            ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
+        else
+            ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+    }
+    return ERR(err);
+    
+wrongMessage:
+    ERR(SSLFatalSessionAlert(alert_unexpected_message, ctx));
+    return ERR(SSLProtocolErr);
+}
+
+SSLErr
+SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
+{   SSLErr          err;
+    SSLBuffer       sessionIdentifier;
+    
+    switch (processed)
+    {   case SSL_hello_request:
+            if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
+                return err;
+            SSLChangeHdskState(ctx, HandshakeServerHello);
+            break;
+        case SSL_client_hello:
+            CASSERT(ctx->protocolSide == SSL_ServerSide);
+            if (ctx->sessionID.data != 0)   /* If session ID != 0, client is trying to resume */
+            {   if (ctx->resumableSession.data != 0)
+                {   if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
+                        return err;
+                    if (sessionIdentifier.length == ctx->sessionID.length &&
+                        memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
+                    {   /* Everything matches; resume the session */
+                        //DEBUGMSG("Using resumed SSL3 Session");
+                        if (ERR(err = SSLInstallSessionID(ctx->resumableSession, ctx)) != 0)
+                        {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                            return err;
+                        }
+                        if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
+                            return err;
+                        if (ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
+                            ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
+                        {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                            return err;
+                        }
+                        if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
+                            return err;
+                        /* Install new cipher spec on write side */
+                        if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
+                        {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                            return err;
+                        }
+                        ctx->writeCipher = ctx->writePending;
+                        ctx->writeCipher.ready = 0;     /* Can't send data until Finished is sent */
+                        memset(&ctx->writePending, 0, sizeof(CipherContext));       /* Zero out old data */
+                        if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
+                            return err;
+                        /* Finished has been sent; enable data dransfer on write channel */
+                        ctx->writeCipher.ready = 1;
+                        SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
+                        break;
+                    }
+                    if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0 ||
+                        ERR(err = SSLDeleteSessionID(ctx)) != 0)
+                    {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                        return err;
+                    }
+                }
+                if (ERR(err = SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx)) != 0)
+                {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                    return err;
+                }
+            }
+            
+            /* If we get here, we're not resuming; generate a new session ID if we know our peer */
+            if (ctx->peerID.data != 0)
+            {   /* Ignore errors; just treat as uncached session */
+                CASSERT(ctx->sessionID.data == 0);
+                ERR(err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, &ctx->sysCtx));
+                if (err == 0)
+                {   
+                	#ifdef	_APPLE_CDSA_
+                	if((err = sslRand(ctx, &ctx->sessionID)) != 0)
+                	#else
+                	if (ERR(err = ctx->sysCtx.random(ctx->sessionID, ctx->sysCtx.randomRef)) != 0)
+                	#endif
+                    {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                        return err;
+                    }
+                }
+            }
+            
+            if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
+                return err;
+            switch (ctx->selectedCipherSpec->keyExchangeMethod)
+            {   case SSL_NULL_auth:
+            	#if		APPLE_DH
+                case SSL_DH_anon:
+                #endif
+                case SSL_DH_anon_EXPORT:
+					#if		ST_SERVER_MODE_ENABLE
+                	if(ctx->clientAuth == kAlwaysAuthenticate) {
+                		/* APPLE_CDSA change: app requires this; abort */
+                		SSLFatalSessionAlert(alert_handshake_failure, ctx);
+                		return SSLNegotiationErr;
+                	}
+                	ctx->tryClientAuth = false;
+					#else	/* ST_SERVER_MODE_ENABLE */
+					/* server side needs work */
+					#endif	/* ST_SERVER_MODE_ENABLE*/
+                    break;
+                default:        /* everything else */
+                    if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
+                        return err;
+                    break;
+            }
+            #ifdef	_APPLE_CDSA_
+		        /*
+	             * At this point we decide whether to send a server key exchange
+	             * method. For Apple servers, I think we'll ALWAYS do this, because
+	             * of key usage restrictions (can't decrypt and sign with the same
+	             * private key), but conceptually in this code, we do it if 
+	             * enabled by the presence of encryptPrivKey. 
+	             */
+	            #if		SSL_SERVER_KEYEXCH_HACK	
+	            	/*
+	            	 * This is currently how we work with Netscape. It requires
+	            	 * a CSP which can handle private keys which can both
+	            	 * sign and decrypt. 
+	            	 */
+	            	if((ctx->selectedCipherSpec->keyExchangeMethod != SSL_RSA) &&
+	            	   (ctx->encryptPrivKey != NULL)) {
+			        	err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
+			        	if(err) {
+							return err;
+						}
+	            	}
+	            #else	/* !SSL_SERVER_KEYEXCH_HACK */
+	            	/*
+	            	 * This is, I believe the "right" way, but Netscape doesn't
+	            	 * work this way.
+	            	 */
+		            if (ctx->encryptPrivKey != NULL) {
+			        	err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
+			        	if(err) {
+							return err;
+						}
+					}
+				#endif	/* SSL_SERVER_KEYEXCH_HACK */
+            #else	/* !_APPLE_CDSA_ */
+	            /* original SSLRef3.... */
+	            if (ctx->selectedCipherSpec->keyExchangeMethod != SSL_RSA)
+	                if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx)) != 0)
+	                    return err;
+            #endif	/* _APPLE_CDSA_ */
+			#if	ST_SERVER_MODE_ENABLE
+            if (ctx->tryClientAuth)
+            {   if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest, ctx)) != 0)
+                    return err;
+                ctx->certRequested = 1;
+            }
+			#else	/* !ST_SERVER_MODE_ENABLE */
+			/* disabled for now */
+			#endif	/* ST_SERVER_MODE_ENABLE */
+            if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone, ctx)) != 0)
+                return err;
+            if (ctx->certRequested) {
+                SSLChangeHdskState(ctx, HandshakeClientCertificate);
+            }
+            else {
+                SSLChangeHdskState(ctx, HandshakeClientKeyExchange);
+            }
+            break;
+        case SSL_server_hello:
+            if (ctx->resumableSession.data != 0 && ctx->sessionID.data != 0)
+            {   if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
+                {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                    return err;
+                }
+                if (sessionIdentifier.length == ctx->sessionID.length &&
+                    memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
+                {   /* Everything matches; resume the session */
+                    if (ERR(err = SSLInstallSessionID(ctx->resumableSession, ctx)) != 0 ||
+                        ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
+                        ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
+                    {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                        return err;
+                    }
+                    SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
+                    break;
+                }
+                if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
+                {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                    return err;
+                }
+            }
+            switch (ctx->selectedCipherSpec->keyExchangeMethod)
+            {   
+            	/* these require a key exchange message */
+            	case SSL_NULL_auth:
+                case SSL_DH_anon:
+                case SSL_DH_anon_EXPORT:
+                    SSLChangeHdskState(ctx, HandshakeKeyExchange);
+                    break;
+                case SSL_RSA:
+                case SSL_DH_DSS:
+                case SSL_DH_DSS_EXPORT:
+                case SSL_DH_RSA:
+                case SSL_DH_RSA_EXPORT:
+                case SSL_RSA_EXPORT:
+                case SSL_DHE_DSS:
+                case SSL_DHE_DSS_EXPORT:
+                case SSL_DHE_RSA:
+                case SSL_DHE_RSA_EXPORT:
+                case SSL_Fortezza:
+                    SSLChangeHdskState(ctx, HandshakeCertificate);
+                    break;
+                default:
+                    ASSERTMSG("Unknown key exchange method");
+                    break;
+            }
+            break;
+        case SSL_certificate:
+            if (ctx->state == HandshakeCertificate)
+                switch (ctx->selectedCipherSpec->keyExchangeMethod)
+                {   case SSL_RSA:
+                	#ifdef	_APPLE_CDSA_
+                 	/*
+                	 * I really think the two RSA cases should be
+                	 * handled the same here - the server key exchange is
+                	 * optional, and is up to the server.
+                	 * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
+                	 * we're a client here.
+                	 */                   
+                	case SSL_RSA_EXPORT:
+                    #endif
+                    case SSL_DH_DSS:
+                    case SSL_DH_DSS_EXPORT:
+                    case SSL_DH_RSA:
+                    case SSL_DH_RSA_EXPORT:
+                        SSLChangeHdskState(ctx, HandshakeHelloDone);
+                        break;
+                	#ifndef	_APPLE_CDSA_
+                    case SSL_RSA_EXPORT:
+                    #endif
+                    case SSL_DHE_DSS:
+                    case SSL_DHE_DSS_EXPORT:
+                    case SSL_DHE_RSA:
+                    case SSL_DHE_RSA_EXPORT:
+                    case SSL_Fortezza:
+                        SSLChangeHdskState(ctx, HandshakeKeyExchange);
+                        break;
+                    default:
+                        ASSERTMSG("Unknown or unexpected key exchange method");
+                        break;
+                }
+            else if (ctx->state == HandshakeClientCertificate)
+            {   SSLChangeHdskState(ctx, HandshakeClientKeyExchange);
+                if (ctx->peerCert != 0)
+                    ctx->certReceived = 1;
+            }
+            break;
+        case SSL_certificate_request:   /* state stays in HandshakeHelloDone; distinction is in ctx->certRequested */
+            if (ctx->peerCert == 0)
+            {   ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
+                return ERR(SSLProtocolErr);
+            }
+            ctx->certRequested = 1;
+            break;
+        case SSL_server_key_exchange:
+            SSLChangeHdskState(ctx, HandshakeHelloDone);
+            break;
+        case SSL_server_hello_done:
+            if (ctx->certRequested)
+            {   if (ctx->localCert != 0 && ctx->x509Requested)
+                {   if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
+                        return err;
+                }
+                else
+                {   if (ERR(err = SSLSendAlert(alert_warning, alert_no_certificate, ctx)) != 0)
+                        return err;
+                }
+            }
+            if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeKeyExchange, ctx)) != 0)
+                return err;
+            if (ERR(err = SSLCalculateMasterSecret(ctx)) != 0 ||
+                ERR(err = SSLInitPendingCiphers(ctx)) != 0)
+            {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                return err;
+            }
+            if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
+                return err;
+            if (ctx->certSent)
+                if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify, ctx)) != 0)
+                    return err;
+            if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
+                return err;
+            /* Install new cipher spec on write side */
+            if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
+            {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                return err;
+            }
+            ctx->writeCipher = ctx->writePending;
+            ctx->writeCipher.ready = 0;     /* Can't send data until Finished is sent */
+            memset(&ctx->writePending, 0, sizeof(CipherContext));       /* Zero out old data */
+            if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
+                return err;
+            /* Finished has been sent; enable data dransfer on write channel */
+            ctx->writeCipher.ready = 1;
+            SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
+            break;
+        case SSL_certificate_verify:
+            SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
+            break;
+        case SSL_client_key_exchange:
+            if (ERR(err = SSLCalculateMasterSecret(ctx)) != 0 ||
+                ERR(err = SSLInitPendingCiphers(ctx)) != 0)
+            {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+                return err;
+            }
+            if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
+                return err;
+            if (ctx->certReceived) {
+                SSLChangeHdskState(ctx, HandshakeClientCertVerify);
+            }
+            else {
+                SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
+            }
+            break;
+        case SSL_finished:
+            /* Handshake is over; enable data transfer on read channel */
+            ctx->readCipher.ready = 1;
+            /* If writePending is set, we haven't yet sent a finished message; send it */
+            if (ctx->writePending.ready != 0)
+            {   if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
+                    return err;
+                
+                /* Install new cipher spec on write side */
+                if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
+                {   SSLFatalSessionAlert(alert_close_notify, ctx);
+                    return err;
+                }
+                ctx->writeCipher = ctx->writePending;
+                ctx->writeCipher.ready = 0;     /* Can't send data until Finished is sent */
+                memset(&ctx->writePending, 0, sizeof(CipherContext));       /* Zero out old data */
+                if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
+                    return err;
+                ctx->writeCipher.ready = 1;
+            }
+            if (ctx->protocolSide == SSL_ServerSide) {
+                SSLChangeHdskState(ctx, HandshakeServerReady);
+            }
+            else {
+                SSLChangeHdskState(ctx, HandshakeClientReady);
+            }
+            if (ctx->peerID.data != 0)
+                ERR(SSLAddSessionID(ctx));
+            break;
+        default:
+            ASSERTMSG("Unknown State");
+            break;
+    }
+    
+    return SSLNoErr;
+}
+
+SSLErr
+SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx)
+{   SSLErr          err;
+    SSLRecord       rec;
+    
+    if (ERR(err = msgFunc(&rec, ctx)) != 0)
+    {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+        goto fail;
+    }
+    
+    if (rec.contentType == SSL_handshake)
+    {   if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
+            ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
+        {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+            goto fail;
+        }
+        SSLLogHdskMsg((SSLHandshakeType)rec.contents.data[0], 1);
+    }
+    
+    if (ERR(err = SSLWriteRecord(rec, ctx)) != 0)
+        goto fail;
+    
+    err = SSLNoErr;
+fail:
+    SSLFreeBuffer(&rec.contents, &ctx->sysCtx);
+    
+    return err;
+}
+
+SSLErr
+SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (ERR(err = SSLInitMessageHashes(ctx)) != 0)
+        return err;
+    
+    if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
+        ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
+    {   ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
+        return err;
+    }
+    
+    if (ERR(err = SSLAdvanceHandshake(SSL_client_hello, ctx)) != 0)
+        return err;
+    
+    return SSLNoErr;
+}
+
+/* log changes in handshake state */
+#if		LOG_HDSK_STATE
+
+#include <stdio.h>
+
+char *hdskStateToStr(SSLHandshakeState state)
+{
+	static char badStr[100];
+	
+	switch(state) {
+		case SSLUninitialized:
+			return "SSLUninitialized";	
+		case HandshakeServerUninit:
+			return "HandshakeServerUninit";	
+		case HandshakeClientUninit:
+			return "HandshakeClientUninit";	
+		case SSLGracefulClose:
+			return "SSLGracefulClose";	
+		case SSLErrorClose:
+			return "SSLErrorClose";		
+		case SSLNoNotifyClose:
+			return "SSLNoNotifyClose";
+		case HandshakeServerHello:
+			return "HandshakeServerHello";	
+		case HandshakeServerHelloUnknownVersion:
+			return "HandshakeServerHelloUnknownVersion";	
+		case HandshakeKeyExchange:
+			return "HandshakeKeyExchange";	
+		case HandshakeCertificate:
+			return "HandshakeCertificate";	
+		case HandshakeHelloDone:
+			return "HandshakeHelloDone";	
+		case HandshakeClientCertificate:
+			return "HandshakeClientCertificate";	
+		case HandshakeClientKeyExchange:
+			return "HandshakeClientKeyExchange";	
+		case HandshakeClientCertVerify:
+			return "HandshakeClientCertVerify";	
+		case HandshakeChangeCipherSpec:
+			return "HandshakeChangeCipherSpec";	
+		case HandshakeFinished:
+			return "HandshakeFinished";	
+		case HandshakeSSL2ClientMasterKey:
+			return "HandshakeSSL2ClientMasterKey";
+		case HandshakeSSL2ClientFinished:
+			return "HandshakeSSL2ClientFinished";	
+		case HandshakeSSL2ServerHello:
+			return "HandshakeSSL2ServerHello";	
+		case HandshakeSSL2ServerVerify:
+			return "HandshakeSSL2ServerVerify";	
+		case HandshakeSSL2ServerFinished:
+			return "HandshakeSSL2ServerFinished";	
+		case HandshakeServerReady:
+			return "HandshakeServerReady";	
+		case HandshakeClientReady:
+			return "HandshakeClientReady";
+		default:
+			sprintf(badStr, "Unknown state (%d(d)", state);
+			return badStr;
+	}
+}
+
+void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
+{
+	printf("...hdskState = %s\n", hdskStateToStr(newState));
+	ctx->state = newState;
+}
+
+#endif	/* LOG_HDSK_STATE */
+
+/* log handshake messages */
+
+#if		LOG_HDSK_MSG
+
+#include <stdio.h>
+
+static char *hdskMsgToStr(SSLHandshakeType msg)
+{
+	static char badStr[100];
+	
+	switch(msg) {
+		case SSL_hello_request:
+			return "SSL_hello_request";	
+		case SSL_client_hello:
+			return "SSL_client_hello";	
+		case SSL_server_hello:
+			return "SSL_server_hello";	
+		case SSL_certificate:
+			return "SSL_certificate";	
+		case SSL_server_key_exchange:
+			return "SSL_server_key_exchange";	
+		case SSL_certificate_request:
+			return "SSL_certificate_request";	
+		case SSL_server_hello_done:
+			return "SSL_server_hello_done";	
+		case SSL_certificate_verify:
+			return "SSL_certificate_verify";	
+		case SSL_client_key_exchange:
+			return "SSL_client_key_exchange";	
+		case SSL_finished:
+			return "SSL_finished";	
+		case SSL_MAGIC_no_certificate_alert:
+			return "SSL_MAGIC_no_certificate_alert";	
+		default:
+			sprintf(badStr, "Unknown state (%d(d)", msg);
+			return badStr;
+	}
+}
+
+void SSLLogHdskMsg(SSLHandshakeType msg, char sent)
+{
+	printf("---%s handshake msg %s\n", 
+		hdskMsgToStr(msg), (sent ? "sent" : "recv"));
+}
+
+#endif	/* LOG_HDSK_MSG */
\ No newline at end of file
diff --git a/SecureTransport/sslmd5.c b/SecureTransport/sslmd5.c
new file mode 100644
index 00000000..2c077ed6
--- /dev/null
+++ b/SecureTransport/sslmd5.c
@@ -0,0 +1,354 @@
+/*
+ * 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.
+ */
+
+
+/* sslmd5.c - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#if 0
+#ifdef	BSAFE
+#include "aglobal.h"
+#else
+#include "global.h"
+#endif
+#endif
+#include "sslmd5.h"
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
+static void Encode PROTO_LIST
+  ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+  ((UINT4 *, const unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static const unsigned char PADDING[64] = {
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void SSLMD5Init (context)
+MD5_CTX *context;                                        /* context */
+{
+  context->count[0] = context->count[1] = 0;
+  /* Load magic initialization constants.
+*/
+  context->state[0] = 0x67452301;
+  context->state[1] = 0xefcdab89;
+  context->state[2] = 0x98badcfe;
+  context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+  operation, processing another message block, and updating the
+  context.
+ */
+void SSLMD5Update (context, input, inputLen)
+MD5_CTX *context;                                        /* context */
+unsigned const char *input;                          /* input block */
+unsigned int inputLen;                     /* length of input block */
+{
+  unsigned int i, index, partLen;
+
+  /* Compute number of bytes mod 64 */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+  /* Update number of bits */
+  if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
+    context->count[1]++;
+  context->count[1] += ((UINT4)inputLen >> 29);
+
+  partLen = 64 - index;
+
+  /* Transform as many times as possible. */
+  if (inputLen >= partLen) {
+    MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+    MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+   MD5Transform (context->state, &input[i]);
+
+ index = 0;
+  }
+  else
+ i = 0;
+
+  /* Buffer remaining input */
+  MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+  inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+  the message digest and zeroizing the context.
+ */
+void SSLMD5Final (digest, context)
+unsigned char digest[16];                         /* message digest */
+MD5_CTX *context;                                       /* context */
+{
+  unsigned char bits[8];
+  unsigned int index, padLen;
+
+  /* Save number of bits */
+  Encode (bits, context->count, 8);
+
+  /* Pad out to 56 mod 64.
+*/
+  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+  padLen = (index < 56) ? (56 - index) : (120 - index);
+  SSLMD5Update (context, PADDING, padLen);
+
+  /* Append length (before padding) */
+  SSLMD5Update (context, bits, 8);
+
+  /* Store state in digest */
+  Encode (digest, context->state, 16);
+
+  /* Zeroize sensitive information.
+*/
+  MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+const unsigned char block[64];
+{
+  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+  Decode (x, block, 64);
+
+  /* Round 1 */
+  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+  /* Round 3 */
+  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+  /* Round 4 */
+  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+
+  /* Zeroize sensitive information. */
+  MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+  a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+  }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+  a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+const unsigned char *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+    output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
diff --git a/SecureTransport/sslrec.c b/SecureTransport/sslrec.c
new file mode 100644
index 00000000..2e792d94
--- /dev/null
+++ b/SecureTransport/sslrec.c
@@ -0,0 +1,539 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslrec.c
+
+	Contains:	Encryption, decryption and MACing of data
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: sslrec.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslrec.c     Encryption, decryption and MACing of data
+
+    All the transformations which occur between plaintext and the
+    secured, authenticated data that goes out over the wire. Also,
+    detects incoming SSL 2 hello messages and hands them off to the SSL 2
+    record layer (and hands all SSL 2 reading & writing off to the SSL 2
+    layer).
+
+    ****************************************************************** */
+
+
+#include "ssl.h"
+
+#ifndef _SSLREC_H_
+#include "sslrec.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _CRYPTTYPE_H_
+#include "cryptType.h"
+#endif
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef _SSL2_H_
+#include "ssl2.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifdef	_APPLE_CDSA_
+#ifndef	_APPLE_GLUE_H_
+#include "appleGlue.h"
+#endif
+#endif
+
+#include <string.h>
+
+/*
+ * Lots of servers fail to provide closure alerts when they disconnect. 
+ * For now we'll just accept it as long as it occurs on a clean record boundary
+ * (and the handshake is complete). 
+ */
+#define SSL_ALLOW_UNNOTICED_DISCONNECT	1
+
+static SSLErr DecryptSSLRecord(UInt8 type, SSLBuffer *payload, SSLContext *ctx);
+static SSLErr VerifyMAC(UInt8 type, SSLBuffer data, UInt8 *compareMAC, SSLContext *ctx);
+static SSLErr ComputeMAC(UInt8 type, SSLBuffer data, SSLBuffer mac, sslUint64 seqNo, SSLBuffer secret, const HashReference *macHash, SSLContext *ctx);
+static UInt8* SSLEncodeUInt64(UInt8 *p, sslUint64 value);
+
+/* ReadSSLRecord
+ *  Attempt to read & decrypt an SSL record.
+ */
+SSLErr
+SSLReadRecord(SSLRecord *rec, SSLContext *ctx)
+{   SSLErr          err;
+    UInt32          len, contentLen;
+    UInt8           *progress;
+    SSLBuffer       readData, cipherFragment;
+    
+    if (!ctx->partialReadBuffer.data || ctx->partialReadBuffer.length < 5)
+    {   if (ctx->partialReadBuffer.data)
+            if ((err = SSLFreeBuffer(&ctx->partialReadBuffer, &ctx->sysCtx)) != 0)
+            {   SSLFatalSessionAlert(alert_close_notify, ctx);
+                return ERR(err);
+            }
+        if ((err = SSLAllocBuffer(&ctx->partialReadBuffer, DEFAULT_BUFFER_SIZE, &ctx->sysCtx)) != 0)
+        {   SSLFatalSessionAlert(alert_close_notify, ctx);
+            return ERR(err);
+        }
+    }
+    
+    if (ctx->negProtocolVersion == SSL_Version_Undetermined ||
+        ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello)
+        if (ctx->amountRead < 1)
+        {   readData.length = 1 - ctx->amountRead;
+            readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+            len = readData.length;
+            #ifdef	_APPLE_CDSA_
+            err = sslIoRead(readData, &len, ctx);
+            if(err != 0)
+			#else
+            if (ERR(err = ctx->ioCtx.read(readData, &len, ctx->ioCtx.ioRef)) != 0)
+            #endif
+            {   if (err == SSLWouldBlockErr)
+                    ctx->amountRead += len;
+                else
+                    SSLFatalSessionAlert(alert_close_notify, ctx);
+                return err;
+            }
+            ctx->amountRead += len;
+        }
+    
+/* In undetermined cases, if the first byte isn't in the range of SSL 3.0
+ *  record types, this is an SSL 2.0 record
+ */
+    switch (ctx->negProtocolVersion)
+    {   case SSL_Version_Undetermined:
+        case SSL_Version_3_0_With_2_0_Hello:
+            if (ctx->partialReadBuffer.data[0] < SSL_smallest_3_0_type ||
+                ctx->partialReadBuffer.data[0] > SSL_largest_3_0_type)
+                return SSL2ReadRecord(rec, ctx);
+            else
+                break;
+        case SSL_Version_2_0:
+            return SSL2ReadRecord(rec, ctx);
+        default:
+            break;
+    }
+    
+    if (ctx->amountRead < 5)
+    {   readData.length = 5 - ctx->amountRead;
+        readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+        len = readData.length;
+        #ifdef	_APPLE_CDSA_
+        err = sslIoRead(readData, &len, ctx);
+        if(err != 0)
+		#else
+        if (ERR(err = ctx->ioCtx.read(readData, &len, ctx->ioCtx.ioRef)) != 0)
+        #endif
+        {   
+			switch(err) {
+				case SSLWouldBlockErr:
+					ctx->amountRead += len;
+					break;
+				#if	SSL_ALLOW_UNNOTICED_DISCONNECT
+				case SSLConnectionClosedGraceful:
+					/* legal if we're on record boundary and we've gotten past 
+					 * the handshake */
+					if((ctx->amountRead == 0) && 				/* nothing pending */
+					   (len == 0) &&							/* nothing new */
+					   (ctx->state == HandshakeClientReady)) {	/* handshake done */
+					    /*
+						 * This means that the server has discionected without 
+						 * sending a closure alert notice. This is technically
+						 * illegal per the SSL3 spec, but about half of the 
+						 * servers out there do it, so we report it as a separate
+						 * error which most clients - including (currently)
+						 * URLAccess - ignore by treating it the same as
+						 * a SSLConnectionClosedGraceful error. Paranoid
+						 * clients can detect it and handle it however they
+						 * want to.
+						 */
+						SSLChangeHdskState(ctx, SSLNoNotifyClose);
+						err = SSLConnectionClosedNoNotify;
+						break;
+					}
+					else {
+						/* illegal disconnect */
+						err = SSLConnectionClosedError;
+						/* and drop thru to default: fatal alert */
+					}
+				#endif	/* SSL_ALLOW_UNNOTICED_DISCONNECT */
+				default:
+					SSLFatalSessionAlert(alert_close_notify, ctx);
+					break;
+				}
+            return err;
+        }
+        ctx->amountRead += len;
+    }
+    
+    CASSERT(ctx->amountRead >= 5);
+    
+    progress = ctx->partialReadBuffer.data;
+    rec->contentType = *progress++;
+    if (rec->contentType < SSL_smallest_3_0_type || 
+        rec->contentType > SSL_largest_3_0_type)
+        return ERR(SSLProtocolErr);
+    
+    rec->protocolVersion = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
+    progress += 2;
+    contentLen = SSLDecodeInt(progress, 2);
+    progress += 2;
+    if (contentLen > (16384 + 2048))    /* Maximum legal length of an SSLCipherText payload */
+    {   SSLFatalSessionAlert(alert_unexpected_message, ctx);
+        return ERR(SSLProtocolErr);
+    }
+    
+    if (ctx->partialReadBuffer.length < 5 + contentLen)
+    {   if ((err = SSLReallocBuffer(&ctx->partialReadBuffer, 5 + contentLen, &ctx->sysCtx)) != 0)
+        {   SSLFatalSessionAlert(alert_close_notify, ctx);
+            return ERR(err);
+        }
+    }
+    
+    if (ctx->amountRead < 5 + contentLen)
+    {   readData.length = 5 + contentLen - ctx->amountRead;
+        readData.data = ctx->partialReadBuffer.data + ctx->amountRead;
+        len = readData.length;
+        #ifdef	_APPLE_CDSA_
+        err = sslIoRead(readData, &len, ctx);
+        if(err != 0)
+		#else
+        if (ERR(err = ctx->ioCtx.read(readData, &len, ctx->ioCtx.ioRef)) != 0)
+        #endif
+        {   if (err == SSLWouldBlockErr)
+                ctx->amountRead += len;
+            else
+                SSLFatalSessionAlert(alert_close_notify, ctx);
+            return err;
+        }
+        ctx->amountRead += len;
+    }
+    
+    CASSERT(ctx->amountRead >= 5 + contentLen);
+    
+    cipherFragment.data = ctx->partialReadBuffer.data + 5;
+    cipherFragment.length = contentLen;
+    
+/* Decrypt the payload & check the MAC, modifying the length of the buffer to indicate the
+ *  amount of plaintext data after adjusting for the block size and removing the MAC
+ *  (this function generates its own alerts)
+ */
+    if ((err = DecryptSSLRecord(rec->contentType, &cipherFragment, ctx)) != 0)
+        return err;
+    
+/* We appear to have sucessfully received a record; increment the sequence number */
+    IncrementUInt64(&ctx->readCipher.sequenceNum);
+    
+/* Allocate a buffer to return the plaintext in and return it */
+    if ((err = SSLAllocBuffer(&rec->contents, cipherFragment.length, &ctx->sysCtx)) != 0)
+    {   SSLFatalSessionAlert(alert_close_notify, ctx);
+        return ERR(err);
+    }
+    memcpy(rec->contents.data, cipherFragment.data, cipherFragment.length);
+    
+    ctx->amountRead = 0;        /* We've used all the data in the cache */
+    
+    return SSLNoErr;
+}
+
+/* SSLWriteRecord does not send alerts on failure, out of the assumption/fear
+ *  that this might result in a loop (since sending an alert causes SSLWriteRecord
+ *  to be called).
+ */
+SSLErr
+SSLWriteRecord(SSLRecord rec, SSLContext *ctx)
+{   SSLErr          err;
+    int             padding = 0, i;
+    WaitingRecord   *out, *queue;
+    SSLBuffer       buf, payload, secret, mac;
+    UInt8           *progress;
+    UInt16          payloadSize,blockSize;
+    
+    if (rec.protocolVersion == SSL_Version_2_0)
+        return SSL2WriteRecord(rec, ctx);
+    
+    CASSERT(rec.protocolVersion == SSL_Version_3_0);
+    CASSERT(rec.contents.length <= 16384);
+    
+    out = 0;
+    /* Allocate a WaitingRecord to store our ready-to-send record in */
+    if ((err = SSLAllocBuffer(&buf, sizeof(WaitingRecord), &ctx->sysCtx)) != 0)
+        return ERR(err);
+    out = (WaitingRecord*)buf.data;
+    out->next = 0;
+    out->sent = 0;
+    /* Allocate enough room for the transmitted record, which will be:
+     *  5 bytes of header +
+     *  encrypted contents +
+     *  macLength +
+     *  padding [block ciphers only] +
+     *  padding length field (1 byte) [block ciphers only]
+     */
+    payloadSize = (UInt16) (rec.contents.length + ctx->writeCipher.hash->digestSize);
+    blockSize = ctx->writeCipher.symCipher->blockSize;
+    if (blockSize > 0)
+    {   padding = blockSize - (payloadSize % blockSize) - 1;
+        payloadSize += padding + 1;
+    }
+    out->data.data = 0;
+    if ((err = SSLAllocBuffer(&out->data, 5 + payloadSize, &ctx->sysCtx)) != 0)
+        goto fail;
+    
+    progress = out->data.data;
+    *(progress++) = rec.contentType;
+    progress = SSLEncodeInt(progress, rec.protocolVersion, 2);
+    progress = SSLEncodeInt(progress, payloadSize, 2);
+    
+    /* Copy the contents into the output buffer */
+    memcpy(progress, rec.contents.data, rec.contents.length);
+    payload.data = progress;
+    payload.length = rec.contents.length;
+    
+    progress += rec.contents.length;
+    /* MAC immediately follows data */
+    mac.data = progress;
+    mac.length = ctx->writeCipher.hash->digestSize;
+    progress += mac.length;
+    
+    /* MAC the data */
+    if (mac.length > 0)     /* Optimize away null case */
+    {   secret.data = ctx->writeCipher.macSecret;
+        secret.length = ctx->writeCipher.hash->digestSize;
+        if ((err = ComputeMAC(rec.contentType, payload, mac, ctx->writeCipher.sequenceNum, secret, ctx->writeCipher.hash, ctx)) != 0)
+            goto fail;
+    }
+    
+    /* Update payload to reflect encrypted data: contents, mac & padding */
+    payload.length = payloadSize;
+    
+    /* Fill in the padding bytes & padding length field with the padding value; the
+     *  protocol only requires the last byte,
+     *  but filling them all in avoids leaking data
+     */
+    if (ctx->writeCipher.symCipher->blockSize > 0)
+        for (i = 1; i <= padding + 1; ++i)
+            payload.data[payload.length - i] = padding;
+    
+    /* Encrypt the data */
+    DUMP_BUFFER_NAME("cleartext data", payload);
+    /* _APPLE_CDSA_ change */
+    if ((err = ctx->writeCipher.symCipher->encrypt(payload, 
+    		payload, 
+    		&ctx->writeCipher, 
+    		ctx)) != 0)
+        goto fail;
+    DUMP_BUFFER_NAME("encrypted data", payload);
+    
+    /* Enqueue the record to be written from the idle loop */
+    if (ctx->recordWriteQueue == 0)
+        ctx->recordWriteQueue = out;
+    else
+    {   queue = ctx->recordWriteQueue;
+        while (queue->next != 0)
+            queue = queue->next;
+        queue->next = out;
+    }
+    
+    /* Increment the sequence number */
+    IncrementUInt64(&ctx->writeCipher.sequenceNum);
+    
+    return SSLNoErr;
+    
+fail:   /* Only for if we fail between when the WaitingRecord is allocated and when it is queued */
+    SSLFreeBuffer(&out->data, &ctx->sysCtx);
+    buf.data = (UInt8*)out;
+    buf.length = sizeof(WaitingRecord);
+    SSLFreeBuffer(&buf, &ctx->sysCtx);
+    return ERR(err);
+}
+
+static SSLErr
+DecryptSSLRecord(UInt8 type, SSLBuffer *payload, SSLContext *ctx)
+{   SSLErr      err;
+    SSLBuffer   content;
+    
+    if ((ctx->readCipher.symCipher->blockSize > 0) &&
+        ((payload->length % ctx->readCipher.symCipher->blockSize) != 0))
+    {   SSLFatalSessionAlert(alert_unexpected_message, ctx);
+        return ERR(SSLProtocolErr);
+    }
+
+    /* Decrypt in place */
+    DUMP_BUFFER_NAME("encrypted data", (*payload));
+    /* _APPLE_CDSA_ change */
+    if ((err = ctx->readCipher.symCipher->decrypt(*payload, 
+    		*payload, 
+    		&ctx->readCipher, 
+    		ctx)) != 0)
+    {   SSLFatalSessionAlert(alert_close_notify, ctx);
+        return ERR(err);
+    }
+    DUMP_BUFFER_NAME("decrypted data", (*payload));
+    
+/* Locate content within decrypted payload */
+    content.data = payload->data;
+    content.length = payload->length - ctx->readCipher.hash->digestSize;
+    if (ctx->readCipher.symCipher->blockSize > 0)
+    {   /* padding can't be equal to or more than a block */
+        if (payload->data[payload->length - 1] >= ctx->readCipher.symCipher->blockSize)
+        {   SSLFatalSessionAlert(alert_unexpected_message, ctx);
+        	errorLog1("DecryptSSLRecord: bad padding length (%d)\n", 
+        		(unsigned)payload->data[payload->length - 1]);
+            return ERR(SSLProtocolErr);
+        }
+        content.length -= 1 + payload->data[payload->length - 1];   /* Remove block size padding */
+    }
+
+/* Verify MAC on payload */
+    if (ctx->readCipher.hash->digestSize > 0)       /* Optimize away MAC for null case */
+        if ((err = VerifyMAC(type, content, payload->data + content.length, ctx)) != 0)
+        {   SSLFatalSessionAlert(alert_bad_record_mac, ctx);
+            return ERR(err);
+        }
+    
+    *payload = content;     /* Modify payload buffer to indicate content length */
+    
+    return SSLNoErr;
+}
+
+static UInt8*
+SSLEncodeUInt64(UInt8 *p, sslUint64 value)
+{   p = SSLEncodeInt(p, value.high, 4);
+    return SSLEncodeInt(p, value.low, 4);
+}
+
+static SSLErr
+VerifyMAC(UInt8 type, SSLBuffer data, UInt8 *compareMAC, SSLContext *ctx)
+{   SSLErr          err;
+    UInt8           macData[MAX_DIGEST_SIZE];
+    SSLBuffer       secret, mac;
+    
+    secret.data = ctx->readCipher.macSecret;
+    secret.length = ctx->readCipher.hash->digestSize;
+    mac.data = macData;
+    mac.length = ctx->readCipher.hash->digestSize;
+    
+    if ((err = ComputeMAC(type, data, mac, ctx->readCipher.sequenceNum, secret, ctx->readCipher.hash, ctx)) != 0)
+        return ERR(err);
+    
+    if ((memcmp(mac.data, compareMAC, mac.length)) != 0) {
+		errorLog0("VerifyMAC: Mac verify failure\n");
+        return ERR(SSLProtocolErr);
+    }
+    return SSLNoErr;
+}
+
+static SSLErr
+ComputeMAC(UInt8 type, SSLBuffer data, SSLBuffer mac, sslUint64 seqNo, SSLBuffer secret,
+            const HashReference *macHash, SSLContext *ctx)
+{   SSLErr          err;
+    UInt8           innerDigestData[MAX_DIGEST_SIZE];
+    UInt8           scratchData[11], *progress;
+    SSLBuffer       digest,digestCtx,scratch;
+    
+    CASSERT(macHash->macPadSize <= MAX_MAC_PADDING);
+    CASSERT(macHash->digestSize <= MAX_DIGEST_SIZE);
+    CASSERT(SSLMACPad1[0] == 0x36 && SSLMACPad2[0] == 0x5C);
+    
+    digestCtx.data = 0;
+    if ((err = SSLAllocBuffer(&digestCtx, macHash->contextSize, &ctx->sysCtx)) != 0)
+        goto exit;
+    
+/* MAC = hash( MAC_write_secret + pad_2 + hash( MAC_write_secret + pad_1 + seq_num + type + length + content ) ) */
+    if ((err = macHash->init(digestCtx)) != 0)
+        goto exit;
+    if ((err = macHash->update(digestCtx, secret)) != 0)    /* MAC secret */
+        goto exit;
+    scratch.data = SSLMACPad1;
+    scratch.length = macHash->macPadSize;
+    if ((err = macHash->update(digestCtx, scratch)) != 0)   /* pad1 */
+        goto exit;
+    progress = scratchData;
+    progress = SSLEncodeUInt64(progress, seqNo);
+    *progress++ = type;
+    progress = SSLEncodeInt(progress, data.length, 2);
+    scratch.data = scratchData;
+    scratch.length = 11;
+    CASSERT(progress = scratchData+11);
+    if ((err = macHash->update(digestCtx, scratch)) != 0)   /* sequenceNo, type & length */
+        goto exit;
+    if ((err = macHash->update(digestCtx, data)) != 0)      /* content */
+        goto exit;
+    digest.data = innerDigestData;
+    digest.length = macHash->digestSize;
+    if ((err = macHash->final(digestCtx, digest)) != 0) /* figure inner digest */
+        goto exit;
+    
+    if ((err = macHash->init(digestCtx)) != 0)
+        goto exit;
+    if ((err = macHash->update(digestCtx, secret)) != 0)    /* MAC secret */
+        goto exit;
+    scratch.data = SSLMACPad2;
+    scratch.length = macHash->macPadSize;
+    if ((err = macHash->update(digestCtx, scratch)) != 0)   /* pad2 */
+        goto exit;
+    if ((err = macHash->update(digestCtx, digest)) != 0)    /* inner digest */
+        goto exit;  
+    if ((err = macHash->final(digestCtx, mac)) != 0)    /* figure the mac */
+        goto exit;
+    
+    err = SSLNoErr; /* redundant, I know */
+    
+exit:
+    SSLFreeBuffer(&digestCtx, &ctx->sysCtx);
+    return ERR(err);
+}
diff --git a/SecureTransport/sslsess.c b/SecureTransport/sslsess.c
new file mode 100644
index 00000000..be5973bb
--- /dev/null
+++ b/SecureTransport/sslsess.c
@@ -0,0 +1,301 @@
+/*
+ * 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.
+ */
+
+
+/*  *********************************************************************
+    File: sslsess.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslsess.c    SSL Session DB interface
+
+    This file contains functions which interact with the session database
+    to store and restore sessions and retrieve information from packed
+    session records.
+
+    ****************************************************************** */
+
+#ifndef _SSL_H_
+#include "ssl.h"
+#endif
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLSESS_H_
+#include "sslsess.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef	_CIPHER_SPECS_H_
+#include "cipherSpecs.h"
+#endif
+
+#ifdef	_APPLE_CDSA_
+#ifndef	_APPLE_SESSION_H_
+#include "appleSession.h"
+#endif
+#endif
+
+#include <string.h>
+#include <stddef.h>
+
+typedef struct
+{   int                 sessionIDLen;
+    UInt8               sessionID[32];
+    SSLProtocolVersion  protocolVersion;
+    UInt16              cipherSuite;
+    UInt8               masterSecret[48];
+    int                 certCount;
+    UInt8               certs[1];   /* Actually, variable length */
+} ResumableSession;
+
+/*
+ * Cook up a (private) resumable session blob, based on the
+ * specified ctx, store it with ctx->peerID as the key. 
+ * NOTE: This is contrary to the SSLRef3 spec, which claims that
+ * servers store resumable sessions using ctx->sessionID as the key.
+ * I don' think this is an issue...is it?
+ */
+SSLErr
+SSLAddSessionID(const SSLContext *ctx)
+{   SSLErr              err;
+    uint32              sessionIDLen;
+    SSLBuffer           sessionID;
+    ResumableSession    *session;
+    int                 certCount;
+    SSLCertificate      *cert;
+    uint8               *certDest;
+    
+    /* If we don't know who the peer is, we can't store a session */
+    if (ctx->peerID.data == 0)
+        return SSLSessionNotFoundErr;
+    
+    sessionIDLen = offsetof(ResumableSession, certs);
+    cert = ctx->peerCert;
+    certCount = 0;
+    while (cert)
+    {   ++certCount;
+        sessionIDLen += 4 + cert->derCert.length;
+        cert = cert->next;
+    }
+    
+    if ((err = SSLAllocBuffer(&sessionID, sessionIDLen, &ctx->sysCtx)) != 0)
+        return err;
+    
+    session = (ResumableSession*)sessionID.data;
+    
+    session->sessionIDLen = ctx->sessionID.length;
+    memcpy(session->sessionID, ctx->sessionID.data, session->sessionIDLen);
+    session->protocolVersion = ctx->negProtocolVersion;
+    session->cipherSuite = ctx->selectedCipher;
+    memcpy(session->masterSecret, ctx->masterSecret, 48);
+    session->certCount = certCount;
+    
+    certDest = session->certs;
+    cert = ctx->peerCert;
+    while (cert)
+    {   certDest = SSLEncodeInt(certDest, cert->derCert.length, 4);
+        memcpy(certDest, cert->derCert.data, cert->derCert.length);
+        certDest += cert->derCert.length;
+        cert = cert->next;
+    }
+    
+    #ifdef	_APPLE_CDSA_
+    err = sslAddSession(ctx->peerID, sessionID, ctx->sessionCtx.sessionRef);
+    #else
+    err = ctx->sessionCtx.addSession(ctx->peerID, sessionID, ctx->sessionCtx.sessionRef);
+    #endif
+    SSLFreeBuffer(&sessionID, &ctx->sysCtx);
+    
+    return err;
+}
+
+/*
+ * Retrieve resumable session data, from key ctx->peerID.
+ */
+SSLErr
+SSLGetSessionID(SSLBuffer *sessionData, const SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (ctx->peerID.data == 0)
+        return ERR(SSLSessionNotFoundErr);
+    
+    sessionData->data = 0;
+    
+    #ifdef	_APPLE_CDSA_
+    err = sslGetSession(ctx->peerID, sessionData, ctx->sessionCtx.sessionRef);
+    #else
+    ERR(err = ctx->sessionCtx.getSession(ctx->peerID, sessionData, ctx->sessionCtx.sessionRef));
+    #endif
+    
+    if (sessionData->data == 0)
+        return ERR(SSLSessionNotFoundErr);
+    
+    return err;
+}
+
+SSLErr
+SSLDeleteSessionID(const SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (ctx->peerID.data == 0)
+        return SSLSessionNotFoundErr;
+    
+    #ifdef	_APPLE_CDSA_
+    err = sslDeleteSession(ctx->peerID, ctx->sessionCtx.sessionRef);
+    #else
+    err = ctx->sessionCtx.deleteSession(ctx->peerID, ctx->sessionCtx.sessionRef);
+    #endif
+    return err;
+}
+
+/*
+ * Given a sessionData blob, obtain the associated sessionID (NOT the key...).
+ */
+SSLErr
+SSLRetrieveSessionIDIdentifier(
+		const SSLBuffer sessionData, 
+		SSLBuffer *identifier, 
+		const SSLContext *ctx)
+{   SSLErr              err;
+    ResumableSession    *session;
+    
+    session = (ResumableSession*) sessionData.data;
+    if ((err = SSLAllocBuffer(identifier, session->sessionIDLen, &ctx->sysCtx)) != 0)
+        return err;
+    memcpy(identifier->data, session->sessionID, session->sessionIDLen);
+    return SSLNoErr;
+}
+
+/*
+ * Obtain the protocol version associated with a specified resumable session blob.
+ */
+SSLErr
+SSLRetrieveSessionIDProtocolVersion(
+		const SSLBuffer sessionID, 
+		SSLProtocolVersion *version, 
+		const SSLContext *ctx)
+{   ResumableSession    *session;
+    
+    session = (ResumableSession*) sessionID.data;
+    *version = session->protocolVersion;
+    return SSLNoErr;
+}
+
+/*
+ * Retrieve session state. Presumably, ctx->sessionID and
+ * ctx->negProtocolVersion are already init'd (from the above two functions). 
+ */
+SSLErr
+SSLInstallSessionID(const SSLBuffer sessionData, SSLContext *ctx)
+{   SSLErr              err;
+    ResumableSession    *session;
+    uint8               *storedCertProgress;
+    SSLCertificate      *cert, *lastCert;
+	#ifndef	__APPLE__
+    SSLBuffer           certAlloc;
+	#endif
+    int                 certCount;
+    uint32              certLen;
+    
+    session = (ResumableSession*)sessionData.data;
+    
+    CASSERT(ctx->negProtocolVersion == session->protocolVersion);
+    
+    ctx->selectedCipher = session->cipherSuite;
+    if ((err = FindCipherSpec(ctx)) != 0) {
+        return err;
+    }
+    memcpy(ctx->masterSecret, session->masterSecret, 48);
+    
+    lastCert = 0;
+    storedCertProgress = session->certs;
+    certCount = session->certCount;
+
+    while (certCount--)
+    {   
+		#ifdef	__APPLE__
+		cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
+		if(cert == NULL) {
+			return SSLMemoryErr;
+		}
+		#else
+		if ((err = SSLAllocBuffer(&certAlloc, sizeof(SSLCertificate), &ctx->sysCtx)) != 0)
+            return err;
+        cert = (SSLCertificate*)certAlloc.data;
+		#endif
+        cert->next = 0;
+        certLen = SSLDecodeInt(storedCertProgress, 4);
+        storedCertProgress += 4;
+        if ((err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
+        {   
+			#ifdef	__APPLE__
+			sslFree(cert);
+			#else
+			SSLFreeBuffer(&certAlloc,&ctx->sysCtx);
+			#endif
+            return err;
+        }
+        memcpy(cert->derCert.data, storedCertProgress, certLen);
+        storedCertProgress += certLen;
+        #ifndef	_APPLE_CDSA_
+        /* we don't decode */
+        if ((err = ASNParseX509Certificate(cert->derCert, &cert->cert, ctx)) != 0)
+        {   
+			SSLFreeBuffer(&cert->derCert,&ctx->sysCtx);
+			#ifdef	__APPLE__
+			sslFree(cert);
+			#else
+            SSLFreeBuffer(&certAlloc,&ctx->sysCtx);
+			#endif
+            return err;
+        }
+        #endif
+        if (lastCert == 0)
+            ctx->peerCert = cert;
+        else
+            lastCert->next = cert;
+        lastCert = cert;
+    }
+    
+    return SSLNoErr;
+}
diff --git a/SecureTransport/ssltrspt.c b/SecureTransport/ssltrspt.c
new file mode 100644
index 00000000..c069b794
--- /dev/null
+++ b/SecureTransport/ssltrspt.c
@@ -0,0 +1,552 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		ssltrspt.c
+
+	Contains:	SSLContext transport layer
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: ssltrspt.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: ssltrspt.c   Data transportation functionality
+
+    Transports data between the application and the record layer; also
+    hands off handshake, alert, and change cipher spec messages to their
+    handlers. Also, ensures that negotiation happens before application
+    data goes out on the wire.
+
+    ****************************************************************** */
+
+#ifndef _SSLTRSPT_H_
+#include "ssltrspt.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef _SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLCTX_H_
+#include "sslrec.h"
+#endif
+
+#ifndef _SSLALERT_H_
+#include "sslalert.h"
+#endif
+
+#ifndef _SSLSESS_H_
+#include "sslsess.h"
+#endif
+
+#ifndef _SSL2_H_
+#include "ssl2.h"
+#endif
+
+#ifdef	_APPLE_CDSA_
+#ifndef	_APPLE_GLUE_H_
+#include "appleGlue.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#ifndef	_CIPHER_SPECS_H_
+#include "cipherSpecs.h"
+#endif
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#endif
+
+#include <string.h>
+
+#define SSL_IO_TRACE	0
+#if		SSL_IO_TRACE
+static void sslIoTrace(
+	const char *op,
+	UInt32 req, 
+	UInt32 moved,
+	OSStatus stat)
+{
+	printf("===%s: req %4d moved %4d status %d\n", 
+		op, req, moved, stat);
+}
+
+#else
+#define sslIoTrace(op, req, moved, stat)
+#endif	/* SSL_IO_TRACE */
+
+static SSLErr SSLProcessProtocolMessage(SSLRecord rec, SSLContext *ctx);
+static SSLErr SSLHandshakeProceed(SSLContext *ctx);
+static SSLErr SSLInitConnection(SSLContext *ctx);
+static SSLErr SSLServiceWriteQueue(SSLContext *ctx);
+
+OSStatus 
+SSLWrite(
+	SSLContext			*ctx,
+	const void *		data,
+	UInt32				dataLength,
+	UInt32 				*bytesWritten)	/* RETURNED */ 
+{   
+	SSLErr          err;
+    SSLRecord       rec;
+    UInt32          dataLen, processed;
+    
+    if((ctx == NULL) || (bytesWritten == NULL)) {
+    	return paramErr;
+    }
+    dataLen = dataLength;
+    processed = 0;        /* Initialize in case we return with SSLWouldBlockErr */
+    *bytesWritten = 0;
+    
+    switch(ctx->state) {
+    	case SSLGracefulClose:
+        	err = SSLConnectionClosedGraceful;
+			goto abort;
+        case SSLErrorClose:
+        	err = SSLConnectionClosedError;
+			goto abort;
+        default:
+	    	/* FIXME - original code didn't check for handshake in progress - 
+	    	 * should we? 
+	    	 */
+			sslIoTrace("SSLWrite", dataLength, 0, badReqErr);
+	    	return badReqErr;
+	    case HandshakeServerReady:
+	    case HandshakeClientReady:
+			break;
+	}
+	
+    /* First, we have to wait until the session is ready to send data,
+        so the encryption keys and such have been established. */
+    err = SSLNoErr;
+    while (ctx->writeCipher.ready == 0)
+    {   if ((err = SSLHandshakeProceed(ctx)) != 0)
+            goto exit;
+    }
+    
+    /* Attempt to empty the write queue before queueing more data */
+    if ((err = SSLServiceWriteQueue(ctx)) != 0)
+        goto abort;
+    
+    processed = 0;
+    /* Fragment, package and encrypt the data and queue the resulting data for sending */
+    while (dataLen > 0)
+    {   rec.contentType = SSL_application_data;
+        rec.protocolVersion = ctx->negProtocolVersion;
+        rec.contents.data = ((UInt8*)data) + processed;
+        
+        if (dataLen < MAX_RECORD_LENGTH)
+            rec.contents.length = dataLen;
+        else
+            rec.contents.length = MAX_RECORD_LENGTH;
+        
+        if (ERR(err = SSLWriteRecord(rec, ctx)) != 0)
+            goto exit;
+        
+        processed += rec.contents.length;
+        dataLen -= rec.contents.length;
+    }
+    
+    /* All the data has been advanced to the write queue */
+    *bytesWritten = processed;
+    if (ERR(err = SSLServiceWriteQueue(ctx)) != 0)
+        goto exit;
+    
+    err = SSLNoErr;
+exit:
+    if (err != 0 && err != SSLWouldBlockErr && err != SSLConnectionClosedGraceful) {
+		dprintf1("SSLWrite: going to state errorCLose due to err %d\n",
+			err);
+        SSLChangeHdskState(ctx, SSLErrorClose);
+    }
+abort:
+	sslIoTrace("SSLWrite", dataLength, *bytesWritten, sslErrToOsStatus(err));
+    return sslErrToOsStatus(err);
+}
+
+OSStatus 
+SSLRead	(
+	SSLContext			*ctx,
+	void *				data,
+	UInt32				dataLength,
+	UInt32 				*processed)		/* RETURNED */ 
+{   
+	SSLErr          err;
+    UInt8           *progress;
+    UInt32          bufSize, remaining, count;
+    SSLRecord       rec;
+    
+    if((ctx == NULL) || (processed == NULL)) {
+    	return paramErr;
+    }
+    bufSize = dataLength;
+    *processed = 0;        /* Initialize in case we return with SSLWouldBlockErr */
+
+	/* first handle cases in which we know we're finished */
+	switch(ctx->state) {
+		case SSLGracefulClose:
+			err = SSLConnectionClosedGraceful;
+			goto abort;
+		case SSLErrorClose:
+			err = SSLConnectionClosedError;
+			goto abort;
+		case SSLNoNotifyClose:
+			err = SSLConnectionClosedNoNotify;
+			goto abort;
+		default:
+			break;
+	}
+    
+    /* First, we have to wait until the session is ready to receive data,
+        so the encryption keys and such have been established. */
+    err = SSLNoErr;
+    while (ctx->readCipher.ready == 0)
+    {   if (ERR(err = SSLHandshakeProceed(ctx)) != 0)
+            goto exit;
+    }
+    
+    /* Attempt to service the write queue */
+    if (ERR(err = SSLServiceWriteQueue(ctx)) != 0)
+    {   if (err != SSLWouldBlockErr)
+            goto exit;
+        err = SSLNoErr; /* Write blocking shouldn't stop attempts to read */
+    }
+    
+    remaining = bufSize;
+    progress = (UInt8*)data;
+    if (ctx->receivedDataBuffer.data)
+    {   count = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
+        if (count > bufSize)
+            count = bufSize;
+        memcpy(data, ctx->receivedDataBuffer.data + ctx->receivedDataPos, count);
+        remaining -= count;
+        progress += count;
+        *processed += count;
+        ctx->receivedDataPos += count;
+    }
+    
+    CASSERT(ctx->receivedDataPos <= ctx->receivedDataBuffer.length);
+    CASSERT(*processed + remaining == bufSize);
+    CASSERT(progress == ((UInt8*)data) + *processed);
+    
+    if (ctx->receivedDataBuffer.data != 0 &&
+        ctx->receivedDataPos >= ctx->receivedDataBuffer.length)
+    {   SSLFreeBuffer(&ctx->receivedDataBuffer, &ctx->sysCtx);
+        ctx->receivedDataBuffer.data = 0;
+        ctx->receivedDataPos = 0;
+    }
+    
+    while (remaining > 0 && ctx->state != SSLGracefulClose)
+    {   CASSERT(ctx->receivedDataBuffer.data == 0);
+        if (ERR(err = SSLReadRecord(&rec, ctx)) != 0)
+            goto exit;
+        
+        if (rec.contentType == SSL_application_data ||
+            rec.contentType == SSL_version_2_0_record)
+        {   if (rec.contents.length <= remaining)
+            {   memcpy(progress, rec.contents.data, rec.contents.length);
+                remaining -= rec.contents.length;
+                progress += rec.contents.length;
+                *processed += rec.contents.length;
+                /* COMPILER BUG!
+                 * This:
+                 * if (ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
+                 * passes the address of rec to SSLFreeBuffer, not the address
+                 * of the contents field (which should be offset 8 from the start
+                 * of rec).
+                 */
+                {
+                	SSLBuffer *b = &rec.contents;
+                	if (ERR(err = SSLFreeBuffer(b, &ctx->sysCtx)) != 0) {
+                    	goto exit;
+                    }
+                }
+            }
+            else
+            {   memcpy(progress, rec.contents.data, remaining);
+                progress += remaining;
+                *processed += remaining;
+                ctx->receivedDataBuffer = rec.contents;
+                ctx->receivedDataPos = remaining;
+                remaining = 0;
+            }
+        }
+        else
+        {   if (ERR(err = SSLProcessProtocolMessage(rec, ctx)) != 0)
+                goto exit;
+            if (ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
+                goto exit;
+        }
+    }
+    
+    err = SSLNoErr;
+    
+exit:
+	/* shut down on serious errors */
+	switch(err) {
+		case SSLNoErr:
+		case SSLWouldBlockErr:
+		case SSLConnectionClosedGraceful:
+		case SSLConnectionClosedNoNotify:
+			break;
+		default:
+			dprintf1("SSLRead: going to state errorClose due to err %d\n",
+				err);
+			SSLChangeHdskState(ctx, SSLErrorClose);
+			break;
+    }
+abort:
+	sslIoTrace("SSLRead ", dataLength, *processed, sslErrToOsStatus(err));
+    return sslErrToOsStatus(err);
+}
+
+#if	SSL_DEBUG
+#include "appleCdsa.h"
+#endif
+
+OSStatus
+SSLHandshake(SSLContext *ctx)
+{   
+	SSLErr  err;
+
+	if(ctx == NULL) {
+		return paramErr;
+	}
+    if (ctx->state == SSLGracefulClose)
+        return sslErrToOsStatus(SSLConnectionClosedGraceful);
+    if (ctx->state == SSLErrorClose)
+        return sslErrToOsStatus(SSLConnectionClosedError);
+    
+    if(ctx->protocolSide == SSL_ServerSide) {
+    	/* some things the caller really has to have done by now... */
+    	if((ctx->localCert == NULL) ||
+    	   (ctx->signingPrivKey == NULL) ||
+    	   (ctx->signingPubKey == NULL) ||
+    	   (ctx->signingKeyCsp == 0)) {
+    	 	errorLog0("SSLHandshake: insufficient init\n");
+    	 	return badReqErr;
+    	}
+    }
+    if(ctx->validCipherSpecs == NULL) {
+    	/* build list of legal cipherSpecs */
+    	err = sslBuildCipherSpecArray(ctx);
+    	if(err) {
+    		return err;
+    	}
+    }
+    err = SSLNoErr;
+    while (ctx->readCipher.ready == 0 || ctx->writeCipher.ready == 0)
+    {   if (ERR(err = SSLHandshakeProceed(ctx)) != 0)
+            return sslErrToOsStatus(err);
+    }
+    
+    return noErr;
+}
+
+
+static SSLErr
+SSLHandshakeProceed(SSLContext *ctx)
+{   SSLErr      err;
+    SSLRecord   rec;
+    
+    if (ctx->state == SSLUninitialized)
+        if (ERR(err = SSLInitConnection(ctx)) != 0)
+            return err;
+    if (ERR(err = SSLServiceWriteQueue(ctx)) != 0)
+        return err;
+    CASSERT(ctx->readCipher.ready == 0);
+    if (ERR(err = SSLReadRecord(&rec, ctx)) != 0)
+        return err;
+    if (ERR(err = SSLProcessProtocolMessage(rec, ctx)) != 0)
+    {   SSLFreeBuffer(&rec.contents, &ctx->sysCtx);
+        return err;
+    }
+    if (ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
+        return err;
+        
+    return SSLNoErr;
+}
+
+static SSLErr
+SSLInitConnection(SSLContext *ctx)
+{   SSLErr      err;
+    
+    if (ctx->protocolSide == SSL_ClientSide) {
+        SSLChangeHdskState(ctx, HandshakeClientUninit);
+    }
+    else
+    {   CASSERT(ctx->protocolSide == SSL_ServerSide);
+        SSLChangeHdskState(ctx, HandshakeServerUninit);
+    }
+    
+    if (ctx->peerID.data != 0)
+    {   ERR(SSLGetSessionID(&ctx->resumableSession, ctx));
+        /* Ignore errors; just treat as uncached session */
+    }
+    
+/* If we're a client, and we have a cached resumable session, we want
+ *  to try to negotiate the same session type we negotiated before,
+ *  because an SSL 3.0 session can only be resumed with an SSL 3.0
+ *  hello message.
+ */
+    if (ctx->protocolSide == SSL_ClientSide && ctx->resumableSession.data != 0)
+    {   if (ERR(err = SSLRetrieveSessionIDProtocolVersion(ctx->resumableSession,
+                                        &ctx->negProtocolVersion, ctx)) != 0)
+            return err;
+    }
+    
+/* If we're the client & handshake hasn't yet begun, start it by
+ *  pretending we just received a hello request
+ */
+    if (ctx->state == HandshakeClientUninit && ctx->writeCipher.ready == 0)
+    {   switch (ctx->negProtocolVersion)
+        {   case SSL_Version_Undetermined:
+            case SSL_Version_3_0_With_2_0_Hello:
+            case SSL_Version_2_0:
+                if (ERR(err = SSL2AdvanceHandshake(ssl2_mt_kickstart_handshake, ctx)) != 0)
+                    return err;
+                break;
+            case SSL_Version_3_0_Only:
+            case SSL_Version_3_0:
+                if (ERR(err = SSLAdvanceHandshake(SSL_hello_request, ctx)) != 0)
+                    return err;
+                break;
+            default:
+                sslPanic("Bad protocol version");
+                break;
+        }
+    }
+    
+    return SSLNoErr;
+}
+
+static SSLErr
+SSLServiceWriteQueue(SSLContext *ctx)
+{   SSLErr          err;
+    UInt32          written;
+    SSLBuffer       buf, recBuf;
+    WaitingRecord   *rec;
+    
+    while ((rec = ctx->recordWriteQueue) != 0)
+    {   buf.data = rec->data.data + rec->sent;
+        buf.length = rec->data.length - rec->sent;
+        #ifdef	_APPLE_CDSA_
+        err = sslIoWrite(buf, &written, ctx);
+        #else
+        err = ctx->ioCtx.write(buf, &written, ctx->ioCtx.ioRef);
+        #endif
+        // FIXME - detect & abort ERR(err);
+        rec->sent += written;
+        if (rec->sent >= rec->data.length)
+        {   CASSERT(rec->sent == rec->data.length);
+            CASSERT(err == 0);
+            err = SSLFreeBuffer(&rec->data, &ctx->sysCtx);
+            CASSERT(err == 0);
+            recBuf.data = (UInt8*)rec;
+            recBuf.length = sizeof(WaitingRecord);
+            ctx->recordWriteQueue = rec->next;
+            err = SSLFreeBuffer(&recBuf, &ctx->sysCtx);
+            CASSERT(err == 0);
+        }
+        if (ERR(err))
+            return err;
+        CASSERT(ctx->recordWriteQueue == 0 || ctx->recordWriteQueue->sent == 0);
+    }
+    
+    return SSLNoErr;
+}
+
+#if		LOG_RX_PROTOCOL
+static void sslLogRxProto(const char *msgType)
+{
+	printf("---received protoMsg %s\n", msgType);
+}
+#else
+#define sslLogRxProto(msgType)
+#endif	/* LOG_RX_PROTOCOL */
+
+static SSLErr
+SSLProcessProtocolMessage(SSLRecord rec, SSLContext *ctx)
+{   SSLErr      err;
+    
+    switch (rec.contentType)
+    {   case SSL_handshake:
+			sslLogRxProto("SSL_handshake");
+            ERR(err = SSLProcessHandshakeRecord(rec, ctx));
+            break;
+        case SSL_alert:
+ 			sslLogRxProto("SSL_alert");
+            ERR(err = SSLProcessAlert(rec, ctx));
+            break;
+        case SSL_change_cipher_spec:
+			sslLogRxProto("SSL_change_cipher_spec");
+            ERR(err = SSLProcessChangeCipherSpec(rec, ctx));
+            break;
+        case SSL_version_2_0_record:
+			sslLogRxProto("SSL_version_2_0_record");
+            ERR(err = SSL2ProcessMessage(rec, ctx));
+            break;
+        default:
+			sslLogRxProto("Bad msg");
+            return ERR(SSLProtocolErr);
+    }
+    
+    return err;
+}
+
+OSStatus
+SSLClose(SSLContext *ctx)
+{   
+	SSLErr      err = SSLNoErr;		/* _APPLE_CDSA_ bug fix - was uninit'd */
+    
+	if(ctx == NULL) {
+		return paramErr;
+	}
+    if (ctx->negProtocolVersion == SSL_Version_3_0)
+        ERR(err = SSLSendAlert(alert_warning, alert_close_notify, ctx));
+    if (err == 0)
+        ERR(err = SSLServiceWriteQueue(ctx));
+    SSLChangeHdskState(ctx, SSLGracefulClose);
+    if (err == SSLIOErr)
+        err = SSLNoErr;     /* Ignore errors related to closed streams */
+    return sslErrToOsStatus(err);
+}
diff --git a/SecureTransport/sslutil.c b/SecureTransport/sslutil.c
new file mode 100644
index 00000000..f03bb5c1
--- /dev/null
+++ b/SecureTransport/sslutil.c
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		sslutil.c
+
+	Contains:	Misc. SSL utility functions
+
+	Written by:	Doug Mitchell, based on Netscape SSLRef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: sslutil.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: sslutil.c    Utility functions for encoding structures
+
+    Handles encoding endian-independant wire representation of 2, 3, or 4
+    byte integers.
+
+    ****************************************************************** */
+
+#ifndef	_SSLCTX_H_
+#include "sslctx.h"
+#endif
+
+#ifndef _SSLUTIL_H_
+#include "sslutil.h"
+#endif
+
+#ifndef _SSLALLOC_H_
+#include "sslalloc.h"
+#endif
+
+#ifndef	_SSL_DEBUG_H_
+#include "sslDebug.h"
+#endif
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+UInt32
+SSLDecodeInt(const unsigned char *p, int length)
+{   UInt32  val = 0;
+    while (length--)
+        val = (val << 8) | *p++;
+    return val;
+}
+
+unsigned char *
+SSLEncodeInt(unsigned char *p, UInt32 value, int length)
+{   unsigned char   *retVal = p + length;       /* Return pointer to char after int */
+    CASSERT(length > 0 && length <= 4);
+    while (length--)                /* Assemble backwards */
+    {   p[length] = (UInt8)value;   /* Implicit masking to low byte */
+        value >>= 8;
+    }
+    return retVal;
+}
+
+void
+IncrementUInt64(sslUint64 *v)
+{   if (++v->low == 0)          /* Must have just rolled over */
+        ++v->high;
+}
+
+UInt32
+SSLGetCertificateChainLength(const SSLCertificate *c)
+{   
+	UInt32 rtn = 0;
+	
+    while (c)
+    {   
+    	rtn++;
+        c = c->next;
+    }
+    return rtn;
+}
+
+Boolean sslIsSessionActive(const SSLContext *ctx)
+{
+	CASSERT(ctx != NULL);
+	switch(ctx->state) {
+		case SSLUninitialized:
+		case HandshakeServerUninit:
+		case HandshakeClientUninit:
+		case SSLGracefulClose:
+		case SSLErrorClose:
+			return false;
+		default:
+			return true;
+	}
+}
+
+OSStatus sslDeleteCertificateChain(
+    SSLCertificate		*certs,
+	SSLContext 			*ctx)
+{	
+	SSLCertificate		*cert;
+	SSLCertificate		*nextCert;
+	
+	CASSERT(ctx != NULL);
+	cert=certs;
+	while(cert != NULL) {
+		nextCert = cert->next;
+		SSLFreeBuffer(&cert->derCert, &ctx->sysCtx);
+		sslFree(cert);
+		cert = nextCert;
+	}
+	return noErr;
+}
+
+#if	SSL_DEBUG
+
+const char *protocolVersStr(SSLProtocolVersion prot)
+{
+	switch(prot) {
+ 	case SSL_Version_Undetermined: return "SSL_Version_Undetermined";
+ 	case SSL_Version_3_0_With_2_0_Hello: return "SSL_Version_3_0_With_2_0_Hello";
+ 	case SSL_Version_3_0_Only: return "SSL_Version_3_0_Only";
+ 	case SSL_Version_2_0: return "SSL_Version_2_0";
+ 	case SSL_Version_3_0: return "SSL_Version_3_0";
+ 	default: sslPanic("protocolVersStr: bad prot");
+ 	}
+ 	return NULL;	/* NOT REACHED */
+}
+
+#endif	/* SSL_DEBUG */
diff --git a/SecureTransport/symCipher.c b/SecureTransport/symCipher.c
new file mode 100644
index 00000000..f7942005
--- /dev/null
+++ b/SecureTransport/symCipher.c
@@ -0,0 +1,397 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		symCipher.c
+
+	Contains:	CDSA-based symmetric cipher module
+
+	Written by:	Doug Mitchell, based on Netscape RSARef 3.0
+
+	Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+/*  *********************************************************************
+    File: ciphers.c
+
+    SSLRef 3.0 Final -- 11/19/96
+
+    Copyright (c)1996 by Netscape Communications Corp.
+
+    By retrieving this software you are bound by the licensing terms
+    disclosed in the file "LICENSE.txt". Please read it, and if you don't
+    accept the terms, delete this software.
+
+    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
+    View, California <http://home.netscape.com/> and Consensus Development
+    Corporation of Berkeley, California <http://www.consensus.com/>.
+
+    *********************************************************************
+
+    File: ciphers.c    Data structures for handling supported ciphers
+
+    Contains a table mapping cipherSuite values to the ciphers, MAC
+    algorithms, key exchange procedures and so on that are used for that
+    algorithm, in order of preference.
+
+    ****************************************************************** */
+
+#include "sslctx.h"
+#include "cryptType.h"
+#include "sslDebug.h"
+#include "sslalloc.h"
+#include "appleCdsa.h"
+#include "symCipher.h"
+
+#include <Security/cssm.h>
+
+#include <string.h>
+
+/* dispose of dynamically allocated resources in a CipherContext */
+static void disposeCipherCtx(
+	CipherContext *cipherCtx)
+{
+	CASSERT(cipherCtx != NULL);
+	if(cipherCtx->symKey != NULL) {
+		CASSERT(cipherCtx->cspHand != 0);
+		CSSM_FreeKey(cipherCtx->cspHand, NULL, cipherCtx->symKey, CSSM_FALSE);
+		sslFree(cipherCtx->symKey);
+		cipherCtx->symKey = NULL;
+	}
+	cipherCtx->cspHand = 0;
+	if(cipherCtx->ccHand != 0) {
+		CSSM_DeleteContext(cipherCtx->ccHand);
+		cipherCtx->ccHand = 0;
+	}
+}
+
+SSLErr CDSASymmInit(
+	uint8 *key, 
+	uint8* iv, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx)
+{
+	/*
+	 * Cook up a symmetric key and a CCSM_CC_HANDLE. Assumes:
+	 * 		cipherCtx->symCipher.keyAlg
+	 * 		ctx->cspHand
+	 * 		key (raw key bytes)
+	 * On successful exit:
+	 * 		Resulting CSSM_KEY_PTR --> cipherCtx->symKey
+	 * 	 	Resulting CSSM_CC_HANDLE --> cipherCtx->ccHand
+	 *      (Currently) a copy of ctx->cspHand --> cipherCtx->cspHand
+	 *
+	 * FIXME - for now we assume that ctx->cspHand is capable of 
+	 * using the specified algorithm, keysize, and mode. This
+	 * may need revisiting.
+	 */
+	
+	SSLErr				serr = SSLInternalError;
+	CSSM_RETURN			crtn;
+	const SSLSymmetricCipher  *symCipher;
+	CSSM_DATA			ivData;
+	CSSM_DATA_PTR		ivDataPtr = NULL;
+	CSSM_KEY_PTR		symKey = NULL;
+	CSSM_CC_HANDLE		ccHand = 0;
+	CSSM_KEYHEADER_PTR	hdr;
+	char				*op;
+	
+	CASSERT(cipherCtx != NULL);
+	CASSERT(cipherCtx->symCipher != NULL);
+	CASSERT(ctx != NULL);
+	if(ctx->cspHand == 0) {
+		errorLog0("CDSASymmInit: NULL cspHand!\n");
+		return SSLInternalError;
+	}
+	
+	/* clean up cipherCtx  */
+	disposeCipherCtx(cipherCtx);
+
+	/* cook up a raw key */
+	symKey = sslMalloc(sizeof(CSSM_KEY));
+	if(symKey == NULL) {
+		return SSLMemoryErr;
+	}
+	memset(symKey, 0, sizeof(CSSM_KEY));
+	serr = stSetUpCssmData(&symKey->KeyData, cipherCtx->symCipher->keySize);
+	if(serr) {
+		sslFree(symKey);
+		return serr;
+	}
+	memmove(symKey->KeyData.Data, key, cipherCtx->symCipher->keySize);
+	
+	/* set up the header */
+	hdr = &symKey->KeyHeader;
+	hdr->BlobType = CSSM_KEYBLOB_RAW;
+	hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
+	hdr->AlgorithmId = cipherCtx->symCipher->keyAlg;
+	hdr->KeyClass = CSSM_KEYCLASS_SESSION_KEY;
+	hdr->LogicalKeySizeInBits = cipherCtx->symCipher->keySize * 8;
+	hdr->KeyAttr = CSSM_KEYATTR_MODIFIABLE | CSSM_KEYATTR_EXTRACTABLE;
+	hdr->KeyUsage = CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT;
+	hdr->WrapAlgorithmId = CSSM_ALGID_NONE;
+	
+	cipherCtx->symKey = symKey;
+	
+	/* now the crypt handle */
+	symCipher = cipherCtx->symCipher;
+	if(symCipher->ivSize != 0) {
+		ivData.Data = iv;
+		ivData.Length = symCipher->ivSize;
+		ivDataPtr = &ivData;
+	}
+	crtn = CSSM_CSP_CreateSymmetricContext(ctx->cspHand,
+		symCipher->encrAlg,
+		symCipher->encrMode,
+		NULL, 
+		symKey,
+		ivDataPtr,
+		symCipher->encrPad,
+		0,						// Params
+		&ccHand);
+	if(crtn) {
+		stPrintCdsaError("CSSM_CSP_CreateSymmetricContext", crtn);
+		serr = SSLCryptoError;
+		goto errOut;
+	}
+	cipherCtx->ccHand = ccHand;
+	
+	/* after this, each en/decrypt is merely an update */
+	if(cipherCtx->encrypting) {
+		crtn = CSSM_EncryptDataInit(ccHand);
+		op = "CSSM_EncryptDataInit";
+	}
+	else {
+		crtn = CSSM_DecryptDataInit(ccHand);
+		op = "CSSM_DecryptDataInit";
+	}
+	if(crtn) {
+		stPrintCdsaError("CSSM_CSP_EncryptDataInit", crtn);
+		serr = SSLCryptoError;
+		goto errOut;
+	}
+	
+	/* success */
+	cipherCtx->cspHand = ctx->cspHand;
+	serr = SSLNoErr;
+	
+errOut:
+	if(serr) {
+		/* dispose of the stuff we created */
+		disposeCipherCtx(cipherCtx);
+	}
+	return serr;
+}
+
+#define REDECRYPT_DATA		0
+
+#define LOG_SYMM_DATA		0
+#if		LOG_SYMM_DATA
+static void logSymmData(
+	char *field,
+	SSLBuffer *data, 
+	int maxLen)
+{
+	int i;
+	
+	printf("%s: ", field);
+	for(i=0; i<data->length; i++) {
+		if(i == maxLen) {
+			break;
+		}
+		printf("%02X", data->data[i]);
+		if((i % 4) == 3) {
+			printf(" ");
+		}
+	}
+	printf("\n");
+}
+#else	/* LOG_SYMM_DATA */
+#define logSymmData(f, d, l)
+#endif	/* LOG_SYMM_DATA */
+
+#define IS_ALIGNED(count, blockSize)	((count % blockSize) == 0)
+
+SSLErr CDSASymmEncrypt(
+	SSLBuffer src, 
+	SSLBuffer dest, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx)
+{
+	CSSM_RETURN			crtn;
+	CSSM_DATA			ptextData;
+	CSSM_DATA			ctextData = {0, NULL};
+	uint32				bytesEncrypted;
+	SSLErr				serr = SSLInternalError;
+	
+	/*
+	 * Valid on entry:
+	 * cipherCtx->ccHand
+	 * cipherCtx->cspHand
+	 */
+	CASSERT(ctx != NULL);
+	CASSERT(cipherCtx != NULL);
+	logSymmData("Symm encrypt ptext", &src, 48);
+	
+	#if	SSL_DEBUG
+	{
+		unsigned blockSize = cipherCtx->symCipher->blockSize;
+		if(blockSize) {
+			if(!IS_ALIGNED(src.length, blockSize)) {
+				errorLog2("CDSASymmEncrypt: unaligned ptext (len %ld bs %d)\n",
+					src.length, blockSize);
+				return SSLInternalError;
+			}
+			if(!IS_ALIGNED(dest.length, blockSize)) {
+				errorLog2("CDSASymmEncrypt: unaligned ctext (len %ld bs %d)\n",
+					dest.length, blockSize);
+				return SSLInternalError;
+			}
+		}
+	}
+	#endif
+	
+	if((cipherCtx->ccHand == 0) || (cipherCtx->cspHand == 0)) {
+		errorLog0("CDSASymmEncrypt: null args\n");
+		return SSLInternalError;
+	}
+	SSLBUF_TO_CSSM(&src, &ptextData);
+	crtn = CSSM_EncryptDataUpdate(cipherCtx->ccHand,
+		&ptextData,
+		1,
+		&ctextData,
+		1,
+		&bytesEncrypted);
+	if(crtn) {
+		stPrintCdsaError("CSSM_EncryptDataUpdate", crtn);
+		serr = SSLCryptoError;
+		goto errOut;
+	}
+	
+	if(bytesEncrypted > dest.length) {
+		/* FIXME - can this happen? Should we remalloc? */
+		errorLog2("Symmetric encrypt overflow: bytesEncrypted %ld destLen %ld\n",
+			bytesEncrypted, dest.length);
+		serr = SSLDataOverflow;
+		goto errOut;
+	}
+	if(bytesEncrypted) {
+		memmove(dest.data, ctextData.Data, bytesEncrypted);
+	}
+	dest.length = bytesEncrypted;
+	
+	/* CSP mallocd ctext  */
+	/* FIXME - once we're really sure that the caller always mallocs
+	 * dest.data, we should avoid this malloc/copy */
+	stFreeCssmData(&ctextData, CSSM_FALSE);
+	
+	/* FIXME - sure we don't need to do Final()? */
+	
+	logSymmData("Symm encrypt ctext", &dest, 48);
+	serr = SSLNoErr;
+	
+errOut:
+	return serr;
+}
+
+SSLErr CDSASymmDecrypt(
+	SSLBuffer src, 
+	SSLBuffer dest, 
+	CipherContext *cipherCtx, 
+	SSLContext *ctx)
+{
+	CSSM_RETURN			crtn;
+	CSSM_DATA			ptextData = {0, NULL};
+	CSSM_DATA			ctextData;
+	uint32				bytesDecrypted;
+	SSLErr				serr = SSLInternalError;
+		
+	/*
+	 * Valid on entry:
+	 * cipherCtx->cspHand
+	 * cipherCtx->ccHand
+	 */
+	CASSERT(ctx != NULL);
+	CASSERT(cipherCtx != NULL);
+	if((cipherCtx->ccHand == 0) || (cipherCtx->cspHand == 0)) {
+		errorLog0("CDSASymmDecrypt: null args\n");
+		return SSLInternalError;
+	}
+	
+	#if	SSL_DEBUG
+	{
+		unsigned blockSize = cipherCtx->symCipher->blockSize;
+		if(blockSize) {
+			if(!IS_ALIGNED(src.length, blockSize)) {
+				errorLog2("CDSASymmDecrypt: unaligned ctext (len %ld bs %d)\n",
+					src.length, blockSize);
+				return SSLInternalError;
+			}
+			if(!IS_ALIGNED(dest.length, blockSize)) {
+				errorLog2("CDSASymmDecrypt: unaligned ptext (len %ld bs %d)\n",
+					dest.length, blockSize);
+				return SSLInternalError;
+			}
+		}
+	}
+	#endif
+
+	SSLBUF_TO_CSSM(&src, &ctextData);
+	crtn = CSSM_DecryptDataUpdate(cipherCtx->ccHand,
+		&ctextData,
+		1,
+		&ptextData,
+		1,
+		&bytesDecrypted);
+	if(crtn) {
+		stPrintCdsaError("CSSM_DecryptDataUpdate", crtn);
+		serr = SSLCryptoError;
+		goto errOut;
+	}
+	
+	if(bytesDecrypted > dest.length) {
+		/* FIXME - can this happen? Should we remalloc? */
+		errorLog2("Symmetric decrypt overflow: bytesDecrypted %ld destLen %ld\n",
+			bytesDecrypted, dest.length);
+		serr = SSLDataOverflow;
+		goto errOut;
+	}
+	
+	if(bytesDecrypted) {
+		memmove(dest.data, ptextData.Data, bytesDecrypted);
+	}
+
+	/* CSP mallocd ptext, remData */
+	stFreeCssmData(&ptextData, CSSM_FALSE);
+
+	dest.length = bytesDecrypted;
+	serr = SSLNoErr;
+	logSymmData("Symm decrypt ptext(1)", &dest, 48);
+errOut:
+	return serr;
+}
+
+SSLErr CDSASymmFinish(
+	CipherContext *cipherCtx, 
+	SSLContext *ctx)
+{
+	/* dispose of cipherCtx->{symKey,cspHand,ccHand} */
+	disposeCipherCtx(cipherCtx);
+	return SSLNoErr;
+}
+
diff --git a/Security.exp b/Security.exp
new file mode 100644
index 00000000..d2d2f086
--- /dev/null
+++ b/Security.exp
@@ -0,0 +1,32 @@
+_gGuidAppleCSP
+_gGuidAppleCSPDL
+_gGuidAppleFileDL
+_gGuidAppleX509CL
+_gGuidAppleX509TP
+_cssmPerror
+_SSLNewContext
+_SSLDisposeContext
+_SSLGetSessionState
+_SSLSetIOFuncs
+_SSLSetProtocolVersion
+_SSLGetProtocolVersion
+_SSLSetConnection
+_SSLGetNegotiatedProtocolVersion
+_SSLGetNumberSupportedCiphers
+_SSLGetSupportedCiphers
+_SSLSetEnabledCiphers
+_SSLGetNumberEnabledCiphers
+_SSLGetEnabledCiphers
+_SSLSetAllowExpiredCerts
+_SSLGetAllowExpiredCerts
+_SSLGetPeerCertificates
+_SSLSetPeerID
+_SSLGetNegotiatedCipher
+_SSLHandshake
+_SSLWrite
+_SSLRead
+_SSLClose
+_SSLSetAllowAnyRoot
+_SessionGetInfo
+_SessionCreate
+_checkpw
diff --git a/Security.pbproj/.cvsignore b/Security.pbproj/.cvsignore
new file mode 100644
index 00000000..ae0520be
--- /dev/null
+++ b/Security.pbproj/.cvsignore
@@ -0,0 +1,2 @@
+michael.pbxuser
+perry.pbxuser
diff --git a/Security.pbproj/project.pbxproj b/Security.pbproj/project.pbxproj
new file mode 100644
index 00000000..f2af4207
--- /dev/null
+++ b/Security.pbproj/project.pbxproj
@@ -0,0 +1,14900 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 34;
+	objects = {
+		01379EAE001E00F311CD296C = {
+			children = (
+				01FA81B1FFF2B54C11CD283A,
+				01FA8239FFF2B54C11CD283A,
+				0AD5441E0003C2C511CD296C,
+			);
+			isa = PBXGroup;
+			name = "Support Files";
+			refType = 4;
+		};
+		014259A8001645E911CD296C = {
+			children = (
+				01FA8049FFF2B54C11CD283A,
+				01FA804AFFF2B54C11CD283A,
+				01FA804BFFF2B54C11CD283A,
+				01FA804CFFF2B54C11CD283A,
+				01FA8061FFF2B54C11CD283A,
+				01FA8062FFF2B54C11CD283A,
+				01FA806BFFF2B54C11CD283A,
+				01FA806CFFF2B54C11CD283A,
+				01FA806DFFF2B54C11CD283A,
+				01FA806EFFF2B54C11CD283A,
+				01FA806FFFF2B54C11CD283A,
+				01FA8070FFF2B54C11CD283A,
+				01FA8071FFF2B54C11CD283A,
+				01FA8072FFF2B54C11CD283A,
+				01FA8073FFF2B54C11CD283A,
+				01FA8074FFF2B54C11CD283A,
+				01FA8075FFF2B54C11CD283A,
+				01FA8076FFF2B54C11CD283A,
+				01FA8077FFF2B54C11CD283A,
+				01FA8078FFF2B54C11CD283A,
+				01FA808EFFF2B54C11CD283A,
+				01FA808FFFF2B54C11CD283A,
+				01FA8090FFF2B54C11CD283A,
+				01FA8091FFF2B54C11CD283A,
+				01FA809AFFF2B54C11CD283A,
+				01FA809EFFF2B54C11CD283A,
+				01FA809FFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			name = Database;
+			refType = 4;
+		};
+		014259A9001645E911CD296C = {
+			children = (
+				01FA803BFFF2B54C11CD283A,
+				01FA803CFFF2B54C11CD283A,
+				01FA803DFFF2B54C11CD283A,
+				01FA803EFFF2B54C11CD283A,
+				01FA8040FFF2B54C11CD283A,
+				01FA803FFFF2B54C11CD283A,
+				01FA8043FFF2B54C11CD283A,
+				01FA8044FFF2B54C11CD283A,
+				01FA8045FFF2B54C11CD283A,
+				01FA8046FFF2B54C11CD283A,
+				01FA8047FFF2B54C11CD283A,
+				01FA8048FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			name = "ACL Subjects";
+			refType = 4;
+		};
+		014259AA001645E911CD296C = {
+			children = (
+				01FA8085FFF2B54C11CD283A,
+				01FA8086FFF2B54C11CD283A,
+				01FA8087FFF2B54C11CD283A,
+				01FA8088FFF2B54C11CD283A,
+				01FA808BFFF2B54C11CD283A,
+				01FA808CFFF2B54C11CD283A,
+				01FA8089FFF2B54C11CD283A,
+				01FA808AFFF2B54C11CD283A,
+				327DDDF600D7DB7505CD296C,
+				327DDDF700D7DB7505CD296C,
+			);
+			isa = PBXGroup;
+			name = Mach;
+			refType = 4;
+		};
+		014880C7005EAE4D11CD283A = {
+			isa = PBXLibraryReference;
+			path = libAppleCSP.a;
+			refType = 3;
+		};
+		014880C8005EAE4D11CD283A = {
+			isa = PBXLibraryReference;
+			path = libAppleFileDL.a;
+			refType = 3;
+		};
+		014880C9005EAE4D11CD283A = {
+			isa = PBXLibraryReference;
+			path = libAppleCSPDL.a;
+			refType = 3;
+		};
+		014880CA005EAE4D11CD283A = {
+			isa = PBXLibraryReference;
+			path = libAppleX509CL.a;
+			refType = 3;
+		};
+		014880CB005EAE4D11CD283A = {
+			isa = PBXLibraryReference;
+			path = libAppleX509TP.a;
+			refType = 3;
+		};
+		014880CD005EAE4D11CD283A = {
+			buildPhases = (
+				014880CF005EAE4D11CD283A,
+				014880D0005EAE4D11CD283A,
+				014880D1005EAE4D11CD283A,
+				014880D2005EAE4D11CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SYMROOT)/BSafe.framework/Headers\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/BSafe.framework/Headers\" \"$(SRCROOT)/AppleCSP\" \"$(SRCROOT)/AppleCSP/open_ssl\" \"\"";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "-DCRYPTKIT_CSP_ENABLE -DASC_CSP_ENABLE -DVDADER_RULES -DALLOW_ZERO_PASSWORD -DCRYPTKIT_DER_ENABLE";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libAppleCSP.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				01488164005EB1E311CD283A,
+			);
+			isa = PBXLibraryTarget;
+			name = AppleCSP;
+			productInstallPath = /usr/local/lib;
+			productName = AppleCSP;
+			productReference = 014880C7005EAE4D11CD283A;
+			shouldUseHeadermap = 1;
+		};
+		014880CF005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				014880EC005EB04411CD283A,
+				014880ED005EB04411CD283A,
+				014880EE005EB04411CD283A,
+				014880EF005EB04411CD283A,
+				014880F0005EB04411CD283A,
+				014880F1005EB04411CD283A,
+				014880F2005EB04411CD283A,
+				014880F3005EB04411CD283A,
+				014880F4005EB04411CD283A,
+				014880F5005EB04411CD283A,
+				014880F6005EB04411CD283A,
+				014880F7005EB04411CD283A,
+				014880F8005EB04411CD283A,
+				014880F9005EB04411CD283A,
+				014880FA005EB04411CD283A,
+				014880FB005EB04411CD283A,
+				014880FC005EB04411CD283A,
+				014880FD005EB04411CD283A,
+				014880FE005EB04411CD283A,
+				014880FF005EB04411CD283A,
+				01488100005EB04411CD283A,
+				01488101005EB04411CD283A,
+				01488102005EB04411CD283A,
+				01488104005EB04411CD283A,
+				01488105005EB04411CD283A,
+				01488106005EB04411CD283A,
+				039FF1DF00724E1A7F000001,
+				039FF1E300724FFC7F000001,
+				2C5247F2007A39B47F000001,
+				2C5247F3007A39B47F000001,
+				2C5247F4007A39B47F000001,
+				2C5247F5007A39B47F000001,
+				4A4C766F007A4E317F000001,
+				4A4C7670007A4E317F000001,
+				4A4C7676007A52DC7F000001,
+				52BFC30A007A6A1B7F000001,
+				57FCEE95007B8B3D7F000001,
+				57FCEE9D007B8D4F7F000001,
+				1691956A00947FD37F000001,
+				1691956C009480BC7F000001,
+				1691956E009485A47F000001,
+				169195B60094A63C7F000001,
+				169195B70094A63C7F000001,
+				169195DB0094A7427F000001,
+				169195DC0094A7427F000001,
+				169195F40094A8577F000001,
+				169195F50094A8577F000001,
+				169195F60094A8577F000001,
+				169195F70094A8577F000001,
+				169195F80094A8577F000001,
+				169195F90094A8577F000001,
+				169195FA0094A8577F000001,
+				169195FB0094A8577F000001,
+				169195FC0094A8577F000001,
+				169195FD0094A8577F000001,
+				169195FE0094A8577F000001,
+				169195FF0094A8577F000001,
+				169196000094A8577F000001,
+				169196010094A8577F000001,
+				169196030094A8577F000001,
+				169196040094A8577F000001,
+				169196050094A8577F000001,
+				169196060094A8577F000001,
+				169196070094A8577F000001,
+				169196080094A8577F000001,
+				256C38B00094AE787F000001,
+				256C38B10094AE787F000001,
+				256C38B50094B2537F000001,
+				28B044E00094C5577F000001,
+				28B044E50094DC627F000001,
+				48855E840095DC957F000001,
+				01D5634900974F7C7F000001,
+				127F63C60098D55A7F000001,
+				07E4D6E500A0CD8D7F000001,
+				209FCB4F00A738117F000001,
+				59375E6C00A848827F000001,
+				59375E6F00A849237F000001,
+				0149035C00A9DC487F000001,
+				0149035D00A9DC487F000001,
+				0149035E00A9DC487F000001,
+				0149035F00A9DC487F000001,
+				0149036500A9DF347F000001,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		014880D0005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01488107005EB04411CD283A,
+				01488108005EB04411CD283A,
+				01488109005EB04411CD283A,
+				0148810A005EB04411CD283A,
+				0148810B005EB04411CD283A,
+				0148810C005EB04411CD283A,
+				0148810D005EB04411CD283A,
+				0148810E005EB04411CD283A,
+				0148810F005EB04411CD283A,
+				01488110005EB04411CD283A,
+				01488111005EB04411CD283A,
+				01488112005EB04411CD283A,
+				01488113005EB04411CD283A,
+				01488114005EB04411CD283A,
+				01488115005EB04411CD283A,
+				01488116005EB04411CD283A,
+				01488117005EB04411CD283A,
+				01488118005EB04411CD283A,
+				01488119005EB04411CD283A,
+				0148811A005EB04411CD283A,
+				0148811B005EB04411CD283A,
+				0148811C005EB04411CD283A,
+				0148811D005EB04411CD283A,
+				0148811E005EB04411CD283A,
+				0148811F005EB04411CD283A,
+				01488120005EB04411CD283A,
+				01488122005EB04411CD283A,
+				01488123005EB04411CD283A,
+				01488124005EB04411CD283A,
+				63B97E6700603F0B7F000001,
+				039FF1DD00724C3A7F000001,
+				039FF1E100724E6E7F000001,
+				2C5247F6007A39B47F000001,
+				2C5247F7007A39B47F000001,
+				2C5247F8007A39B47F000001,
+				4A4C7671007A4E317F000001,
+				4A4C7673007A4E657F000001,
+				4A4C7677007A52DC7F000001,
+				52BFC30C007A6A1B7F000001,
+				52BFC30D007A6A1B7F000001,
+				57FCEE8C007A7B2F7F000001,
+				57FCEE99007B8B3D7F000001,
+				4AC94A7D0084BE397F000001,
+				4AC94A7F0084C0977F000001,
+				16919570009486767F000001,
+				1691958B0094A5A87F000001,
+				1691958C0094A5A87F000001,
+				1691958D0094A5A87F000001,
+				1691958E0094A5A87F000001,
+				1691958F0094A5A87F000001,
+				169195900094A5A87F000001,
+				169195910094A5A87F000001,
+				169195920094A5A87F000001,
+				169195940094A5A87F000001,
+				169195950094A5A87F000001,
+				169195960094A5A87F000001,
+				169195970094A5A87F000001,
+				169195980094A5A87F000001,
+				1691959A0094A5A87F000001,
+				1691959B0094A5A87F000001,
+				169195B80094A63C7F000001,
+				169195B90094A63C7F000001,
+				169195BA0094A63C7F000001,
+				169195BB0094A63C7F000001,
+				169195BC0094A63C7F000001,
+				169195BD0094A63C7F000001,
+				169195BE0094A63C7F000001,
+				169195BF0094A63C7F000001,
+				169195C00094A63C7F000001,
+				169195C10094A63C7F000001,
+				169195C20094A63C7F000001,
+				169195C30094A63C7F000001,
+				169195C40094A63C7F000001,
+				169195C50094A63C7F000001,
+				169195C60094A63C7F000001,
+				169195C70094A63C7F000001,
+				169195C80094A63C7F000001,
+				169195C90094A63C7F000001,
+				169195CA0094A63C7F000001,
+				169195CB0094A63C7F000001,
+				169195CC0094A63C7F000001,
+				169195CD0094A63C7F000001,
+				169195CE0094A63C7F000001,
+				169195CF0094A63C7F000001,
+				169195D40094A6FD7F000001,
+				169195D50094A6FD7F000001,
+				169195D60094A6FD7F000001,
+				169195DD0094A7427F000001,
+				169195DE0094A7427F000001,
+				256C38B20094AE787F000001,
+				256C38B30094AE787F000001,
+				256C38B70094B96F7F000001,
+				28B044E20094C6C57F000001,
+				28B044E60094DC627F000001,
+				48855E860095DD697F000001,
+				07E4D6DC00A0CA617F000001,
+				07E4D6DD00A0CA617F000001,
+				07E4D6DE00A0CA617F000001,
+				07E4D6DF00A0CA617F000001,
+				07E4D6E000A0CA617F000001,
+				07E4D6E100A0CA617F000001,
+				07E4D6E200A0CA617F000001,
+				07E4D6E300A0CA617F000001,
+				209FCB5100A739657F000001,
+				59375E7000A849237F000001,
+				59375E7200A849BB7F000001,
+				0149036000A9DC487F000001,
+				0149036100A9DC487F000001,
+				0149036200A9DC487F000001,
+				0149036300A9DC487F000001,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		014880D1005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		014880D2005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		014880D4005EAE4D11CD283A = {
+			buildPhases = (
+				014880D5005EAE4D11CD283A,
+				014880D6005EAE4D11CD283A,
+				014880D7005EAE4D11CD283A,
+				014880D8005EAE4D11CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "-DVDADER_RULES";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libAppleCSPDL.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				01488165005EB22011CD283A,
+			);
+			isa = PBXLibraryTarget;
+			name = AppleCSPDL;
+			productInstallPath = /usr/local/lib;
+			productName = AppleCSPDL;
+			productReference = 014880C9005EAE4D11CD283A;
+			shouldUseHeadermap = 1;
+		};
+		014880D5005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01488125005EB04411CD283A,
+				01488126005EB04411CD283A,
+				01488127005EB04411CD283A,
+				01488128005EB04411CD283A,
+				01488129005EB04411CD283A,
+				0148812A005EB04411CD283A,
+				0148812B005EB04411CD283A,
+				0148812C005EB04411CD283A,
+				0148812D005EB04411CD283A,
+				0148812E005EB04411CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		014880D6005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0148812F005EB04411CD283A,
+				01488131005EB04411CD283A,
+				01488132005EB04411CD283A,
+				01488133005EB04411CD283A,
+				01488134005EB04411CD283A,
+				01488135005EB04411CD283A,
+				01488136005EB04411CD283A,
+				01488137005EB04411CD283A,
+				01488138005EB04411CD283A,
+				327DDDF500D707D805CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		014880D7005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		014880D8005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		014880DA005EAE4D11CD283A = {
+			buildPhases = (
+				014880DB005EAE4D11CD283A,
+				014880DC005EAE4D11CD283A,
+				014880DD005EAE4D11CD283A,
+				014880DE005EAE4D11CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libAppleFileDL.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				01488166005EB22011CD283A,
+			);
+			isa = PBXLibraryTarget;
+			name = AppleFileDL;
+			productInstallPath = /usr/local/lib;
+			productName = AppleFileDL;
+			productReference = 014880C8005EAE4D11CD283A;
+			shouldUseHeadermap = 1;
+		};
+		014880DB005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01488139005EB04411CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		014880DC005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0148813A005EB04411CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		014880DD005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		014880DE005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		014880E0005EAE4D11CD283A = {
+			buildPhases = (
+				014880E1005EAE4D11CD283A,
+				014880E2005EAE4D11CD283A,
+				014880E3005EAE4D11CD283A,
+				014880E4005EAE4D11CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "-DVDADER_RULES";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libAppleX509CL.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				01488167005EB22011CD283A,
+			);
+			isa = PBXLibraryTarget;
+			name = AppleX509CL;
+			productInstallPath = /usr/local/lib;
+			productName = AppleX509CL;
+			productReference = 014880CA005EAE4D11CD283A;
+			shouldUseHeadermap = 1;
+		};
+		014880E1005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0148813B005EB04411CD283A,
+				0148813C005EB04411CD283A,
+				0148813D005EB04411CD283A,
+				0148813E005EB04411CD283A,
+				0148813F005EB04411CD283A,
+				01488140005EB04411CD283A,
+				01488141005EB04411CD283A,
+				01488142005EB04411CD283A,
+				01488143005EB04411CD283A,
+				01488144005EB04411CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		014880E2005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01488145005EB04411CD283A,
+				01488146005EB04411CD283A,
+				01488147005EB04411CD283A,
+				01488148005EB04411CD283A,
+				01488149005EB04411CD283A,
+				0148814A005EB04411CD283A,
+				0148814B005EB04411CD283A,
+				0148814C005EB04411CD283A,
+				0148814D005EB04411CD283A,
+				0148814E005EB04411CD283A,
+				0148814F005EB04411CD283A,
+				01488150005EB04411CD283A,
+				01488151005EB04411CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		014880E3005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		014880E4005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		014880E6005EAE4D11CD283A = {
+			buildPhases = (
+				014880E7005EAE4D11CD283A,
+				014880E8005EAE4D11CD283A,
+				014880E9005EAE4D11CD283A,
+				014880EA005EAE4D11CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "-DVDADER_RULES";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libAppleX509TP.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				01488168005EB22011CD283A,
+			);
+			isa = PBXLibraryTarget;
+			name = AppleX509TP;
+			productInstallPath = /usr/local/lib;
+			productName = AppleX509TP;
+			productReference = 014880CB005EAE4D11CD283A;
+			shouldUseHeadermap = 1;
+		};
+		014880E7005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01488152005EB04411CD283A,
+				01488153005EB04411CD283A,
+				01488154005EB04411CD283A,
+				01488155005EB04411CD283A,
+				01488156005EB04411CD283A,
+				01488157005EB04411CD283A,
+				01488158005EB04411CD283A,
+				01488159005EB04411CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		014880E8005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0148815A005EB04411CD283A,
+				0148815B005EB04411CD283A,
+				0148815C005EB04411CD283A,
+				0148815D005EB04411CD283A,
+				0148815E005EB04411CD283A,
+				0148815F005EB04411CD283A,
+				01488160005EB04411CD283A,
+				01488161005EB04411CD283A,
+				01488162005EB04411CD283A,
+				01488163005EB04411CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		014880E9005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		014880EA005EAE4D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		014880EC005EB04411CD283A = {
+			fileRef = 07A0F5EE005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880ED005EB04411CD283A = {
+			fileRef = 07A0F5EF005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880EE005EB04411CD283A = {
+			fileRef = 07A0F5F1005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880EF005EB04411CD283A = {
+			fileRef = 07A0F5F3005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F0005EB04411CD283A = {
+			fileRef = 07A0F5F6005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F1005EB04411CD283A = {
+			fileRef = 07A0F5F8005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F2005EB04411CD283A = {
+			fileRef = 07A0F5F9005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F3005EB04411CD283A = {
+			fileRef = 07A0F5FB005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F4005EB04411CD283A = {
+			fileRef = 07A0F5FC005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F5005EB04411CD283A = {
+			fileRef = 07A0F5FE005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F6005EB04411CD283A = {
+			fileRef = 07A0F600005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F7005EB04411CD283A = {
+			fileRef = 07A0F603005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F8005EB04411CD283A = {
+			fileRef = 07A0F60A005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880F9005EB04411CD283A = {
+			fileRef = 07A0F60B005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880FA005EB04411CD283A = {
+			fileRef = 07A0F60E005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880FB005EB04411CD283A = {
+			fileRef = 07A0F610005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880FC005EB04411CD283A = {
+			fileRef = 07A0F670005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880FD005EB04411CD283A = {
+			fileRef = 07A0F671005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880FE005EB04411CD283A = {
+			fileRef = 07A0F673005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		014880FF005EB04411CD283A = {
+			fileRef = 07A0F675005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488100005EB04411CD283A = {
+			fileRef = 07A0F677005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488101005EB04411CD283A = {
+			fileRef = 07A0F679005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488102005EB04411CD283A = {
+			fileRef = 07A0F67B005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488104005EB04411CD283A = {
+			fileRef = 07A0F67F005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488105005EB04411CD283A = {
+			fileRef = 07A0F682005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488106005EB04411CD283A = {
+			fileRef = 07A0F684005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488107005EB04411CD283A = {
+			fileRef = 07A0F5EC005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488108005EB04411CD283A = {
+			fileRef = 07A0F5F0005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488109005EB04411CD283A = {
+			fileRef = 07A0F5F2005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148810A005EB04411CD283A = {
+			fileRef = 07A0F5F5005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148810B005EB04411CD283A = {
+			fileRef = 07A0F5F7005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148810C005EB04411CD283A = {
+			fileRef = 07A0F5FA005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148810D005EB04411CD283A = {
+			fileRef = 07A0F5FD005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148810E005EB04411CD283A = {
+			fileRef = 07A0F5FF005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148810F005EB04411CD283A = {
+			fileRef = 07A0F601005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488110005EB04411CD283A = {
+			fileRef = 07A0F602005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488111005EB04411CD283A = {
+			fileRef = 07A0F604005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488112005EB04411CD283A = {
+			fileRef = 07A0F605005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488113005EB04411CD283A = {
+			fileRef = 07A0F607005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488114005EB04411CD283A = {
+			fileRef = 07A0F608005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488115005EB04411CD283A = {
+			fileRef = 07A0F609005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488116005EB04411CD283A = {
+			fileRef = 07A0F60C005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488117005EB04411CD283A = {
+			fileRef = 07A0F60D005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488118005EB04411CD283A = {
+			fileRef = 07A0F60F005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488119005EB04411CD283A = {
+			fileRef = 07A0F611005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148811A005EB04411CD283A = {
+			fileRef = 07A0F612005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148811B005EB04411CD283A = {
+			fileRef = 07A0F66F005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148811C005EB04411CD283A = {
+			fileRef = 07A0F672005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148811D005EB04411CD283A = {
+			fileRef = 07A0F674005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148811E005EB04411CD283A = {
+			fileRef = 07A0F676005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148811F005EB04411CD283A = {
+			fileRef = 07A0F678005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488120005EB04411CD283A = {
+			fileRef = 07A0F67A005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488122005EB04411CD283A = {
+			fileRef = 07A0F67E005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488123005EB04411CD283A = {
+			fileRef = 07A0F681005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488124005EB04411CD283A = {
+			fileRef = 07A0F683005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488125005EB04411CD283A = {
+			fileRef = 07A0F68B005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488126005EB04411CD283A = {
+			fileRef = 07A0F68D005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488127005EB04411CD283A = {
+			fileRef = 07A0F691005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488128005EB04411CD283A = {
+			fileRef = 07A0F693005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488129005EB04411CD283A = {
+			fileRef = 07A0F695005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148812A005EB04411CD283A = {
+			fileRef = 07A0F697005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148812B005EB04411CD283A = {
+			fileRef = 07A0F699005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148812C005EB04411CD283A = {
+			fileRef = 07A0F69B005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148812D005EB04411CD283A = {
+			fileRef = 07A0F69D005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148812E005EB04411CD283A = {
+			fileRef = 07A0F69F005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148812F005EB04411CD283A = {
+			fileRef = 07A0F68A005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488131005EB04411CD283A = {
+			fileRef = 07A0F690005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488132005EB04411CD283A = {
+			fileRef = 07A0F692005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488133005EB04411CD283A = {
+			fileRef = 07A0F694005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488134005EB04411CD283A = {
+			fileRef = 07A0F696005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488135005EB04411CD283A = {
+			fileRef = 07A0F698005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488136005EB04411CD283A = {
+			fileRef = 07A0F69A005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488137005EB04411CD283A = {
+			fileRef = 07A0F69C005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488138005EB04411CD283A = {
+			fileRef = 07A0F69E005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488139005EB04411CD283A = {
+			fileRef = 07A0F6A5005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148813A005EB04411CD283A = {
+			fileRef = 07A0F6A4005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148813B005EB04411CD283A = {
+			fileRef = 07A0F6AE005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148813C005EB04411CD283A = {
+			fileRef = 07A0F6B3005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148813D005EB04411CD283A = {
+			fileRef = 07A0F6B5005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148813E005EB04411CD283A = {
+			fileRef = 07A0F6B8005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148813F005EB04411CD283A = {
+			fileRef = 07A0F6BA005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488140005EB04411CD283A = {
+			fileRef = 07A0F6BE005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488141005EB04411CD283A = {
+			fileRef = 07A0F6C0005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488142005EB04411CD283A = {
+			fileRef = 07A0F6C1005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488143005EB04411CD283A = {
+			fileRef = 07A0F6C3005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488144005EB04411CD283A = {
+			fileRef = 07A0F6C8005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488145005EB04411CD283A = {
+			fileRef = 07A0F6AD005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488146005EB04411CD283A = {
+			fileRef = 07A0F6B2005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488147005EB04411CD283A = {
+			fileRef = 07A0F6B4005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488148005EB04411CD283A = {
+			fileRef = 07A0F6B6005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488149005EB04411CD283A = {
+			fileRef = 07A0F6B7005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148814A005EB04411CD283A = {
+			fileRef = 07A0F6B9005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148814B005EB04411CD283A = {
+			fileRef = 07A0F6BD005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148814C005EB04411CD283A = {
+			fileRef = 07A0F6BF005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148814D005EB04411CD283A = {
+			fileRef = 07A0F6C2005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148814E005EB04411CD283A = {
+			fileRef = 07A0F6C4005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148814F005EB04411CD283A = {
+			fileRef = 07A0F6C5005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488150005EB04411CD283A = {
+			fileRef = 07A0F6C6005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488151005EB04411CD283A = {
+			fileRef = 07A0F6C7005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488152005EB04411CD283A = {
+			fileRef = 07A0F6CC005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488153005EB04411CD283A = {
+			fileRef = 07A0F6D0005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488154005EB04411CD283A = {
+			fileRef = 07A0F6D2005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488155005EB04411CD283A = {
+			fileRef = 07A0F6D6005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488156005EB04411CD283A = {
+			fileRef = 07A0F6D8005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488157005EB04411CD283A = {
+			fileRef = 07A0F6DC005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488158005EB04411CD283A = {
+			fileRef = 07A0F6DE005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488159005EB04411CD283A = {
+			fileRef = 07A0F6E0005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148815A005EB04411CD283A = {
+			fileRef = 07A0F6CB005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148815B005EB04411CD283A = {
+			fileRef = 07A0F6CF005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148815C005EB04411CD283A = {
+			fileRef = 07A0F6D1005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148815D005EB04411CD283A = {
+			fileRef = 07A0F6D5005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148815E005EB04411CD283A = {
+			fileRef = 07A0F6D7005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0148815F005EB04411CD283A = {
+			fileRef = 07A0F6D9005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488160005EB04411CD283A = {
+			fileRef = 07A0F6DA005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488161005EB04411CD283A = {
+			fileRef = 07A0F6DB005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488162005EB04411CD283A = {
+			fileRef = 07A0F6DD005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488163005EB04411CD283A = {
+			fileRef = 07A0F6DF005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01488164005EB1E311CD283A = {
+			isa = PBXTargetDependency;
+			target = 01CE6B1DFFF2B33A11CD283A;
+		};
+		01488165005EB22011CD283A = {
+			isa = PBXTargetDependency;
+			target = 01CE6B1DFFF2B33A11CD283A;
+		};
+		01488166005EB22011CD283A = {
+			isa = PBXTargetDependency;
+			target = 01CE6B1DFFF2B33A11CD283A;
+		};
+		01488167005EB22011CD283A = {
+			isa = PBXTargetDependency;
+			target = 01CE6B1DFFF2B33A11CD283A;
+		};
+		01488168005EB22011CD283A = {
+			isa = PBXTargetDependency;
+			target = 01CE6B1DFFF2B33A11CD283A;
+		};
+		0149035400A9DC487F000001 = {
+			isa = PBXFileReference;
+			name = DES.c;
+			path = MiscCSPAlgs/DES.c;
+			refType = 4;
+		};
+		0149035500A9DC487F000001 = {
+			isa = PBXFileReference;
+			name = DES.h;
+			path = MiscCSPAlgs/DES.h;
+			refType = 4;
+		};
+		0149035600A9DC487F000001 = {
+			isa = PBXFileReference;
+			name = MD5.c;
+			path = MiscCSPAlgs/MD5.c;
+			refType = 4;
+		};
+		0149035700A9DC487F000001 = {
+			isa = PBXFileReference;
+			name = MD5.h;
+			path = MiscCSPAlgs/MD5.h;
+			refType = 4;
+		};
+		0149035800A9DC487F000001 = {
+			isa = PBXFileReference;
+			name = SHA1_priv.c;
+			path = MiscCSPAlgs/SHA1_priv.c;
+			refType = 4;
+		};
+		0149035900A9DC487F000001 = {
+			isa = PBXFileReference;
+			name = SHA1_priv.h;
+			path = MiscCSPAlgs/SHA1_priv.h;
+			refType = 4;
+		};
+		0149035A00A9DC487F000001 = {
+			isa = PBXFileReference;
+			name = SHA1.c;
+			path = MiscCSPAlgs/SHA1.c;
+			refType = 4;
+		};
+		0149035B00A9DC487F000001 = {
+			isa = PBXFileReference;
+			name = SHA1.h;
+			path = MiscCSPAlgs/SHA1.h;
+			refType = 4;
+		};
+		0149035C00A9DC487F000001 = {
+			fileRef = 0149035500A9DC487F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149035D00A9DC487F000001 = {
+			fileRef = 0149035700A9DC487F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149035E00A9DC487F000001 = {
+			fileRef = 0149035900A9DC487F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149035F00A9DC487F000001 = {
+			fileRef = 0149035B00A9DC487F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149036000A9DC487F000001 = {
+			fileRef = 0149035400A9DC487F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149036100A9DC487F000001 = {
+			fileRef = 0149035600A9DC487F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149036200A9DC487F000001 = {
+			fileRef = 0149035800A9DC487F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149036300A9DC487F000001 = {
+			fileRef = 0149035A00A9DC487F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149036400A9DF347F000001 = {
+			isa = PBXFileReference;
+			name = platform.h;
+			path = MiscCSPAlgs/platform.h;
+			refType = 4;
+		};
+		0149036500A9DF347F000001 = {
+			fileRef = 0149036400A9DF347F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0149036600A9E34D7F000001 = {
+			isa = PBXFileReference;
+			path = libComCryption.a;
+			refType = 3;
+		};
+		0149036700A9E34D7F000001 = {
+			isa = PBXFileReference;
+			path = libCryptKit.a;
+			refType = 3;
+		};
+		014989C0006AA1D111CD283A = {
+			fileRef = 07A0F5F1005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		014989C1006AA1D111CD283A = {
+			fileRef = 07A0F5F3005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0165238D000BEC3311CD296C = {
+			children = (
+				01FA8215FFF2B54C11CD283A,
+				01FA823BFFF2B54C11CD283A,
+				01FA823CFFF2B54C11CD283A,
+				01FA821AFFF2B54C11CD283A,
+				01FA821BFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			name = MIG;
+			refType = 4;
+		};
+		0165238E000BEC3311CD296C = {
+			children = (
+				01FA821FFFF2B54C11CD283A,
+				01FA8227FFF2B54C11CD283A,
+				01FA8226FFF2B54C11CD283A,
+				01FA8229FFF2B54C11CD283A,
+				01FA8228FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			name = "Client Library";
+			refType = 4;
+		};
+		0165238F000BEC3311CD296C = {
+			children = (
+				01FA821DFFF2B54C11CD283A,
+				01FA821CFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			name = "Agent Client Library";
+			path = "";
+			refType = 4;
+		};
+		0177F263FFFAA2D311CD283A = {
+			children = (
+				0177F269FFFAA2D311CD283A,
+				0177F26AFFFAA2D311CD283A,
+				0177F27EFFFAA2D311CD283A,
+				0177F27FFFFAA2D311CD283A,
+				0177F286FFFAA2D311CD283A,
+				0177F287FFFAA2D311CD283A,
+				0177F28AFFFAA2D311CD283A,
+				0177F28BFFFAA2D311CD283A,
+				0177F290FFFAA2D311CD283A,
+				0177F291FFFAA2D311CD283A,
+				0177F292FFFAA2D311CD283A,
+				0177F293FFFAA2D311CD283A,
+				0177F29CFFFAA2D311CD283A,
+				0177F29DFFFAA2D311CD283A,
+				0177F29EFFFAA2D311CD283A,
+				0177F29FFFFAA2D311CD283A,
+				0177F2A0FFFAA2D311CD283A,
+				0177F2A1FFFAA2D311CD283A,
+				0177F2A2FFFAA2D311CD283A,
+				0177F352FFFAC61911CD283A,
+				0177F353FFFAC61911CD283A,
+				0177F2B7FFFAA2D311CD283A,
+				0177F2B8FFFAA2D311CD283A,
+				0177F2C6FFFAA2D311CD283A,
+				0177F2C7FFFAA2D311CD283A,
+				0177F2C9FFFAA2D311CD283A,
+				F579CFD900E99FC401CD283A,
+				0177F2CDFFFAA2D311CD283A,
+				0177F2D1FFFAA2D311CD283A,
+				0177F2D2FFFAA2D311CD283A,
+				0177F2D3FFFAA2D311CD283A,
+				0177F2D6FFFAA2D311CD283A,
+				0177F2D7FFFAA2D311CD283A,
+			);
+			isa = PBXGroup;
+			path = Keychain;
+			refType = 4;
+		};
+		0177F269FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = CCallbackMgr.cp;
+			refType = 4;
+		};
+		0177F26AFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = CCallbackMgr.h;
+			refType = 4;
+		};
+		0177F27EFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = cssmdatetime.cpp;
+			refType = 4;
+		};
+		0177F27FFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = cssmdatetime.h;
+			refType = 4;
+		};
+		0177F286FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = DefaultKeychain.cpp;
+			refType = 4;
+		};
+		0177F287FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = DefaultKeychain.h;
+			refType = 4;
+		};
+		0177F28AFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = DLDBListCFPref.cpp;
+			refType = 4;
+		};
+		0177F28BFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = DLDBListCFPref.h;
+			refType = 4;
+		};
+		0177F290FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Globals.cpp;
+			refType = 4;
+		};
+		0177F291FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Globals.h;
+			refType = 4;
+		};
+		0177F292FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Item.cpp;
+			refType = 4;
+		};
+		0177F293FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Item.h;
+			refType = 4;
+		};
+		0177F29CFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = KCCursor.cpp;
+			refType = 4;
+		};
+		0177F29DFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = KCCursor.h;
+			refType = 4;
+		};
+		0177F29EFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = KCEventNotifier.cpp;
+			refType = 4;
+		};
+		0177F29FFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = KCEventNotifier.h;
+			refType = 4;
+		};
+		0177F2A0FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = KCEventObserver.cpp;
+			refType = 4;
+		};
+		0177F2A1FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = KCEventObserver.h;
+			refType = 4;
+		};
+		0177F2A2FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = KCExceptions.h;
+			refType = 4;
+		};
+		0177F2B7FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Keychains.cpp;
+			refType = 4;
+		};
+		0177F2B8FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Keychains.h;
+			refType = 4;
+		};
+		0177F2C6FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = PrimaryKey.cpp;
+			refType = 4;
+		};
+		0177F2C7FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = PrimaryKey.h;
+			refType = 4;
+		};
+		0177F2C9FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Refs.h;
+			refType = 4;
+		};
+		0177F2CCFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Schema.cpp;
+			refType = 4;
+		};
+		0177F2CDFFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = Schema.h;
+			refType = 4;
+		};
+		0177F2D1FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = SecKeychainAPI.cpp;
+			refType = 4;
+		};
+		0177F2D2FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = SecKeychainAPI.h;
+			refType = 4;
+		};
+		0177F2D3FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = SecKeychainAPIPriv.h;
+			refType = 4;
+		};
+		0177F2D6FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = StorageManager.cpp;
+			refType = 4;
+		};
+		0177F2D7FFFAA2D311CD283A = {
+			isa = PBXFileReference;
+			path = StorageManager.h;
+			refType = 4;
+		};
+		0177F2DEFFFAA2D311CD283A = {
+			fileRef = 0177F26AFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2EAFFFAA2D311CD283A = {
+			fileRef = 0177F27FFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2EEFFFAA2D311CD283A = {
+			fileRef = 0177F287FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2F0FFFAA2D311CD283A = {
+			fileRef = 0177F28BFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2F4FFFAA2D311CD283A = {
+			fileRef = 0177F291FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2F5FFFAA2D311CD283A = {
+			fileRef = 0177F293FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2FAFFFAA2D311CD283A = {
+			fileRef = 0177F29DFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2FBFFFAA2D311CD283A = {
+			fileRef = 0177F29FFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2FCFFFAA2D311CD283A = {
+			fileRef = 0177F2A1FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F2FDFFFAA2D311CD283A = {
+			fileRef = 0177F2A2FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F30BFFFAA2D311CD283A = {
+			fileRef = 0177F2B8FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F315FFFAA2D311CD283A = {
+			fileRef = 0177F2C7FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F317FFFAA2D311CD283A = {
+			fileRef = 0177F2C9FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F319FFFAA2D311CD283A = {
+			fileRef = 0177F2CDFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F31AFFFAA2D311CD283A = {
+			fileRef = 0177F2D2FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F31BFFFAA2D311CD283A = {
+			fileRef = 0177F2D3FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F31DFFFAA2D311CD283A = {
+			fileRef = 0177F2D7FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F323FFFAA2D311CD283A = {
+			fileRef = 0177F269FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F32CFFFAA2D311CD283A = {
+			fileRef = 0177F27EFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F330FFFAA2D311CD283A = {
+			fileRef = 0177F286FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F332FFFAA2D311CD283A = {
+			fileRef = 0177F28AFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F334FFFAA2D311CD283A = {
+			fileRef = 0177F290FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F335FFFAA2D311CD283A = {
+			fileRef = 0177F292FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F33AFFFAA2D311CD283A = {
+			fileRef = 0177F29CFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F33BFFFAA2D311CD283A = {
+			fileRef = 0177F29EFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F33CFFFAA2D311CD283A = {
+			fileRef = 0177F2A0FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F344FFFAA2D311CD283A = {
+			fileRef = 0177F2B7FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F349FFFAA2D311CD283A = {
+			fileRef = 0177F2C6FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F34BFFFAA2D311CD283A = {
+			fileRef = 0177F2CCFFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F34EFFFAA2D311CD283A = {
+			fileRef = 0177F2D1FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F350FFFAA2D311CD283A = {
+			fileRef = 0177F2D6FFFAA2D311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0177F352FFFAC61911CD283A = {
+			isa = PBXFileReference;
+			path = KCUtilities.cpp;
+			refType = 4;
+		};
+		0177F353FFFAC61911CD283A = {
+			isa = PBXFileReference;
+			path = KCUtilities.h;
+			refType = 4;
+		};
+		0177F354FFFAC61911CD283A = {
+			fileRef = 0177F353FFFAC61911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0177F355FFFAC61911CD283A = {
+			fileRef = 0177F352FFFAC61911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		017A54F20094AAE57F000001 = {
+			isa = PBXFileReference;
+			path = "https-proxy-protocol.h";
+			refType = 4;
+		};
+		017A54F30094AAE57F000001 = {
+			isa = PBXFileReference;
+			path = "https-proxy-protocol.cpp";
+			refType = 4;
+		};
+		017A54F40094AAE57F000001 = {
+			fileRef = 017A54F20094AAE57F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		017A54F50094AAE57F000001 = {
+			fileRef = 017A54F30094AAE57F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		017B6CA6009748107F000001 = {
+			isa = PBXFileReference;
+			path = buffers.cpp;
+			refType = 4;
+		};
+		017B6CA7009748107F000001 = {
+			isa = PBXFileReference;
+			path = buffers.h;
+			refType = 4;
+		};
+		017B6CA8009748107F000001 = {
+			fileRef = 017B6CA7009748107F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		017B6CA9009748107F000001 = {
+			fileRef = 017B6CA6009748107F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01827D09008CB8707F000001 = {
+			isa = PBXFileReference;
+			path = "ftp-proxy-protocol.h";
+			refType = 4;
+		};
+		01827D0A008CB8707F000001 = {
+			isa = PBXFileReference;
+			path = "ftp-proxy-protocol.cpp";
+			refType = 4;
+		};
+		01827D0B008CB8707F000001 = {
+			fileRef = 01827D09008CB8707F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01827D0C008CB8707F000001 = {
+			fileRef = 01827D0A008CB8707F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01CE6B19FFF2B1BA11CD283A = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OPTIMIZATION_CFLAGS = "-O0 -fno-inline";
+				OTHER_CFLAGS = "\U0001 -DDEBUGDUMP";
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		01CE6B1AFFF2B1BA11CD283A = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				OPTIMIZATION_CFLAGS = "-O2";
+				OTHER_CFLAGS = "\U0001-DNDEBUG";
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		01CE6B1BFFF2B31311CD283A = {
+			buildPhases = (
+			);
+			buildSettings = {
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = world;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				01CE6B1CFFF2B31311CD283A,
+				125E8604FFF3D96711CD283A,
+				01FA8902FFF2BCA811CD283A,
+				01FA8903FFF2BCA811CD283A,
+				01FA88F8FFF2BBEB11CD283A,
+			);
+			isa = PBXAggregateTarget;
+			name = world;
+			productName = world;
+			shouldUseHeadermap = 0;
+		};
+		01CE6B1CFFF2B31311CD283A = {
+			isa = PBXTargetDependency;
+			target = 0867D69CFE84028FC02AAC07;
+		};
+		01CE6B1DFFF2B33A11CD283A = {
+			buildArgumentsString = "-f cdsa/generator.mk $ACTION \"SRCROOT=$SRCROOT\" \"SYMROOT=$SYMROOT\"";
+			buildPhases = (
+			);
+			buildSettings = {
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = generate;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = generate;
+			productName = generate;
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 1;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		01D5634800974F7C7F000001 = {
+			isa = PBXFileReference;
+			name = openssl_pkcs7.h;
+			path = openssl/openssl_pkcs7.h;
+			refType = 4;
+		};
+		01D5634900974F7C7F000001 = {
+			fileRef = 01D5634800974F7C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA7FE6FFF2B54C11CD283A = {
+			children = (
+				01FA7FE7FFF2B54C11CD283A,
+				01FA8039FFF2B54C11CD283A,
+				01FA8003FFF2B54C11CD283A,
+				01FA8025FFF2B54C11CD283A,
+				01FA80AAFFF2B54C11CD283A,
+				01FA80C6FFF2B54C11CD283A,
+				01FA80D6FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = cdsa;
+			refType = 4;
+		};
+		01FA7FE7FFF2B54C11CD283A = {
+			children = (
+				01FA7FE8FFF2B54C11CD283A,
+				01FA7FE9FFF2B54C11CD283A,
+				01FA7FEAFFF2B54C11CD283A,
+				01FA7FEBFFF2B54C11CD283A,
+				01FA7FECFFF2B54C11CD283A,
+				01FA7FEDFFF2B54C11CD283A,
+				01FA7FEEFFF2B54C11CD283A,
+				01FA7FEFFFF2B54C11CD283A,
+				01FA7FF0FFF2B54C11CD283A,
+				01FA7FF1FFF2B54C11CD283A,
+				01FA7FF2FFF2B54C11CD283A,
+				01FA7FF3FFF2B54C11CD283A,
+				01FA7FF4FFF2B54C11CD283A,
+				01FA7FF5FFF2B54C11CD283A,
+				01FA7FF6FFF2B54C11CD283A,
+				01FA7FF7FFF2B54C11CD283A,
+				01FA7FF8FFF2B54C11CD283A,
+				01FA7FF9FFF2B54C11CD283A,
+				01FA7FFAFFF2B54C11CD283A,
+				01FA7FFBFFF2B54C11CD283A,
+				01FA7FFCFFF2B54C11CD283A,
+				01FA7FFDFFF2B54C11CD283A,
+				01FA7FFEFFF2B54C11CD283A,
+				01FA7FFFFFF2B54C11CD283A,
+				01FA8000FFF2B54C11CD283A,
+				01FA8001FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = cdsa;
+			refType = 4;
+		};
+		01FA7FE8FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = certextensions.h;
+			refType = 4;
+		};
+		01FA7FE9FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssm.h;
+			refType = 4;
+		};
+		01FA7FEAFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmaci.h;
+			refType = 4;
+		};
+		01FA7FEBFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmapi.h;
+			refType = 4;
+		};
+		01FA7FECFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmapple.h;
+			refType = 4;
+		};
+		01FA7FEDFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcli.h;
+			refType = 4;
+		};
+		01FA7FEEFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmconfig.h;
+			refType = 4;
+		};
+		01FA7FEFFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcspi.h;
+			refType = 4;
+		};
+		01FA7FF0FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdli.h;
+			refType = 4;
+		};
+		01FA7FF1FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmerr.h;
+			refType = 4;
+		};
+		01FA7FF2FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmkrapi.h;
+			refType = 4;
+		};
+		01FA7FF3FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmkrspi.h;
+			refType = 4;
+		};
+		01FA7FF4FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmspi.h;
+			refType = 4;
+		};
+		01FA7FF5FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmtpi.h;
+			refType = 4;
+		};
+		01FA7FF6FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmtype.h;
+			refType = 4;
+		};
+		01FA7FF7FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = eisl.h;
+			refType = 4;
+		};
+		01FA7FF8FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = emmspi.h;
+			refType = 4;
+		};
+		01FA7FF9FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = emmtype.h;
+			refType = 4;
+		};
+		01FA7FFAFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = mds.h;
+			refType = 4;
+		};
+		01FA7FFBFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = mds_schema.h;
+			refType = 4;
+		};
+		01FA7FFCFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidsalg.h;
+			refType = 4;
+		};
+		01FA7FFDFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidsattr.h;
+			refType = 4;
+		};
+		01FA7FFEFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidsbase.h;
+			refType = 4;
+		};
+		01FA7FFFFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidscert.h;
+			refType = 4;
+		};
+		01FA8000FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidscrl.h;
+			refType = 4;
+		};
+		01FA8001FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = x509defs.h;
+			refType = 4;
+		};
+		01FA8003FFF2B54C11CD283A = {
+			children = (
+				01FA8004FFF2B54C11CD283A,
+				01FA8005FFF2B54C11CD283A,
+				01FA8006FFF2B54C11CD283A,
+				01FA8008FFF2B54C11CD283A,
+				01FA8009FFF2B54C11CD283A,
+				01FA800AFFF2B54C11CD283A,
+				01FA800BFFF2B54C11CD283A,
+				01FA800CFFF2B54C11CD283A,
+				01FA800DFFF2B54C11CD283A,
+				01FA800EFFF2B54C11CD283A,
+				01FA800FFFF2B54C11CD283A,
+				01FA8010FFF2B54C11CD283A,
+				01FA8011FFF2B54C11CD283A,
+				01FA8012FFF2B54C11CD283A,
+				01FA8013FFF2B54C11CD283A,
+				01FA8014FFF2B54C11CD283A,
+				01FA8015FFF2B54C11CD283A,
+				01FA8016FFF2B54C11CD283A,
+				01FA8017FFF2B54C11CD283A,
+				01FA8018FFF2B54C11CD283A,
+				01FA8019FFF2B54C11CD283A,
+				01FA801AFFF2B54C11CD283A,
+				01FA801BFFF2B54C11CD283A,
+				01FA801CFFF2B54C11CD283A,
+				01FA801DFFF2B54C11CD283A,
+				01FA801EFFF2B54C11CD283A,
+				01FA801FFFF2B54C11CD283A,
+				01FA8020FFF2B54C11CD283A,
+				01FA8021FFF2B54C11CD283A,
+				01FA8022FFF2B54C11CD283A,
+				01FA8023FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = cdsa_client;
+			refType = 4;
+		};
+		01FA8004FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = aclclient.h;
+			refType = 4;
+		};
+		01FA8005FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = aclsupport.cpp;
+			refType = 4;
+		};
+		01FA8006FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = aclsupport.h;
+			refType = 4;
+		};
+		01FA8008FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cryptoclient.cpp;
+			refType = 4;
+		};
+		01FA8009FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cryptoclient.h;
+			refType = 4;
+		};
+		01FA800AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cspclient.cpp;
+			refType = 4;
+		};
+		01FA800BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cspclient.h;
+			refType = 4;
+		};
+		01FA800CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmclient.cpp;
+			refType = 4;
+		};
+		01FA800DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmclient.h;
+			refType = 4;
+		};
+		01FA800EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = dlclient.cpp;
+			refType = 4;
+		};
+		01FA800FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = dlclient.h;
+			refType = 4;
+		};
+		01FA8010FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DLDBList.cpp;
+			refType = 4;
+		};
+		01FA8011FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DLDBList.h;
+			refType = 4;
+		};
+		01FA8012FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = genkey.cpp;
+			refType = 4;
+		};
+		01FA8013FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = genkey.h;
+			refType = 4;
+		};
+		01FA8014FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = keychainacl.cpp;
+			refType = 4;
+		};
+		01FA8015FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = keychainacl.h;
+			refType = 4;
+		};
+		01FA8016FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = keyclient.cpp;
+			refType = 4;
+		};
+		01FA8017FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = keyclient.h;
+			refType = 4;
+		};
+		01FA8018FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = macclient.cpp;
+			refType = 4;
+		};
+		01FA8019FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = macclient.h;
+			refType = 4;
+		};
+		01FA801AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = multidldb.cpp;
+			refType = 4;
+		};
+		01FA801BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = multidldb.h;
+			refType = 4;
+		};
+		01FA801CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = osxsigner.cpp;
+			refType = 4;
+		};
+		01FA801DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = osxsigner.h;
+			refType = 4;
+		};
+		01FA801EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = securestorage.cpp;
+			refType = 4;
+		};
+		01FA801FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = securestorage.h;
+			refType = 4;
+		};
+		01FA8020FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = signclient.cpp;
+			refType = 4;
+		};
+		01FA8021FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = signclient.h;
+			refType = 4;
+		};
+		01FA8022FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = wrapkey.cpp;
+			refType = 4;
+		};
+		01FA8023FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = wrapkey.h;
+			refType = 4;
+		};
+		01FA8025FFF2B54C11CD283A = {
+			children = (
+				01FA8027FFF2B54C11CD283A,
+				01FA8028FFF2B54C11CD283A,
+				01FA8029FFF2B54C11CD283A,
+				01FA802AFFF2B54C11CD283A,
+				01FA802BFFF2B54C11CD283A,
+				01FA802CFFF2B54C11CD283A,
+				01FA802DFFF2B54C11CD283A,
+				01FA802EFFF2B54C11CD283A,
+				01FA802FFFF2B54C11CD283A,
+				01FA8030FFF2B54C11CD283A,
+				01FA8031FFF2B54C11CD283A,
+				01FA8032FFF2B54C11CD283A,
+				01FA8033FFF2B54C11CD283A,
+				01FA8034FFF2B54C11CD283A,
+				01FA8035FFF2B54C11CD283A,
+				01FA8036FFF2B54C11CD283A,
+				01FA8037FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = cdsa_pluginlib;
+			refType = 4;
+		};
+		01FA8027FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ACsession.h;
+			refType = 4;
+		};
+		01FA8028FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "c++plugin.h";
+			refType = 4;
+		};
+		01FA8029FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = CLsession.h;
+			refType = 4;
+		};
+		01FA802AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = CSPsession.cpp;
+			refType = 4;
+		};
+		01FA802BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = CSPsession.h;
+			refType = 4;
+		};
+		01FA802CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = csputilities.cpp;
+			refType = 4;
+		};
+		01FA802DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmplugin.cpp;
+			refType = 4;
+		};
+		01FA802EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmplugin.h;
+			refType = 4;
+		};
+		01FA802FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DLsession.cpp;
+			refType = 4;
+		};
+		01FA8030FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DLsession.h;
+			refType = 4;
+		};
+		01FA8031FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.cfg;
+			refType = 4;
+		};
+		01FA8032FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.mk;
+			refType = 4;
+		};
+		01FA8033FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.pl;
+			refType = 4;
+		};
+		01FA8034FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pluginsession.cpp;
+			refType = 4;
+		};
+		01FA8035FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pluginsession.h;
+			refType = 4;
+		};
+		01FA8036FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pluginspi.h;
+			refType = 4;
+		};
+		01FA8037FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = TPsession.h;
+			refType = 4;
+		};
+		01FA8039FFF2B54C11CD283A = {
+			children = (
+				014259A8001645E911CD296C,
+				01FA804DFFF2B54C11CD283A,
+				01FA804EFFF2B54C11CD283A,
+				01FA804FFFF2B54C11CD283A,
+				01FA8050FFF2B54C11CD283A,
+				01FA8051FFF2B54C11CD283A,
+				01FA8052FFF2B54C11CD283A,
+				01FA8055FFF2B54C11CD283A,
+				01FA8056FFF2B54C11CD283A,
+				01FA8057FFF2B54C11CD283A,
+				01FA8058FFF2B54C11CD283A,
+				01FA8059FFF2B54C11CD283A,
+				01FA805AFFF2B54C11CD283A,
+				01FA805BFFF2B54C11CD283A,
+				01FA805CFFF2B54C11CD283A,
+				01FA805DFFF2B54C11CD283A,
+				01FA805EFFF2B54C11CD283A,
+				01FA805FFFF2B54C11CD283A,
+				01FA8060FFF2B54C11CD283A,
+				01FA8063FFF2B54C11CD283A,
+				01FA8064FFF2B54C11CD283A,
+				01FA8065FFF2B54C11CD283A,
+				01FA8066FFF2B54C11CD283A,
+				01FA8067FFF2B54C11CD283A,
+				01FA8068FFF2B54C11CD283A,
+				01FA8069FFF2B54C11CD283A,
+				01FA806AFFF2B54C11CD283A,
+				01FA8079FFF2B54C11CD283A,
+				01FA807AFFF2B54C11CD283A,
+				01FA807BFFF2B54C11CD283A,
+				01FA807CFFF2B54C11CD283A,
+				01FA807DFFF2B54C11CD283A,
+				01FA807EFFF2B54C11CD283A,
+				01FA807FFFF2B54C11CD283A,
+				01FA8080FFF2B54C11CD283A,
+				01FA8081FFF2B54C11CD283A,
+				01FA8082FFF2B54C11CD283A,
+				01FA8083FFF2B54C11CD283A,
+				01FA8084FFF2B54C11CD283A,
+				01FA808DFFF2B54C11CD283A,
+				01FA8096FFF2B54C11CD283A,
+				01FA8097FFF2B54C11CD283A,
+				01FA8098FFF2B54C11CD283A,
+				01FA8099FFF2B54C11CD283A,
+				01FA809BFFF2B54C11CD283A,
+				01FA80A0FFF2B54C11CD283A,
+				01FA80A1FFF2B54C11CD283A,
+				025C84BB0027360A11CD296C,
+				01FA80A2FFF2B54C11CD283A,
+				01FA80A3FFF2B54C11CD283A,
+				01FA80A4FFF2B54C11CD283A,
+				01FA80A5FFF2B54C11CD283A,
+				01FA80A6FFF2B54C11CD283A,
+				01FA80A7FFF2B54C11CD283A,
+				01FA80A8FFF2B54C11CD283A,
+				3272260D00E3C7FB05CD296C,
+				014259A9001645E911CD296C,
+				014259AA001645E911CD296C,
+				33BD041F00838F447F000001,
+			);
+			isa = PBXGroup;
+			path = cdsa_utilities;
+			refType = 4;
+		};
+		01FA803BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_any.cpp;
+			refType = 4;
+		};
+		01FA803CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_any.h;
+			refType = 4;
+		};
+		01FA803DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_codesigning.cpp;
+			refType = 4;
+		};
+		01FA803EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_codesigning.h;
+			refType = 4;
+		};
+		01FA803FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_comment.cpp;
+			refType = 4;
+		};
+		01FA8040FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_comment.h;
+			refType = 4;
+		};
+		01FA8043FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_password.cpp;
+			refType = 4;
+		};
+		01FA8044FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_password.h;
+			refType = 4;
+		};
+		01FA8045FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_process.cpp;
+			refType = 4;
+		};
+		01FA8046FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_process.h;
+			refType = 4;
+		};
+		01FA8047FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_threshold.cpp;
+			refType = 4;
+		};
+		01FA8048FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_threshold.h;
+			refType = 4;
+		};
+		01FA8049FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AppleDatabase.cpp;
+			refType = 4;
+		};
+		01FA804AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AppleDatabase.h;
+			refType = 4;
+		};
+		01FA804BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AtomicFile.cpp;
+			refType = 4;
+		};
+		01FA804CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AtomicFile.h;
+			refType = 4;
+		};
+		01FA804DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = callback.cpp;
+			refType = 4;
+		};
+		01FA804EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = callback.h;
+			refType = 4;
+		};
+		01FA804FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = codesigning.cpp;
+			refType = 4;
+		};
+		01FA8050FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = codesigning.h;
+			refType = 4;
+		};
+		01FA8051FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = context.cpp;
+			refType = 4;
+		};
+		01FA8052FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = context.h;
+			refType = 4;
+		};
+		01FA8055FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmacl.cpp;
+			refType = 4;
+		};
+		01FA8056FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmacl.h;
+			refType = 4;
+		};
+		01FA8057FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmaclpod.cpp;
+			refType = 4;
+		};
+		01FA8058FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmaclpod.h;
+			refType = 4;
+		};
+		01FA8059FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmalloc.cpp;
+			refType = 4;
+		};
+		01FA805AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmalloc.h;
+			refType = 4;
+		};
+		01FA805BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcred.cpp;
+			refType = 4;
+		};
+		01FA805CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcred.h;
+			refType = 4;
+		};
+		01FA805DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdata.cpp;
+			refType = 4;
+		};
+		01FA805EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdata.h;
+			refType = 4;
+		};
+		01FA805FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdates.cpp;
+			refType = 4;
+		};
+		01FA8060FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdates.h;
+			refType = 4;
+		};
+		01FA8061FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdb.cpp;
+			refType = 4;
+		};
+		01FA8062FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdb.h;
+			refType = 4;
+		};
+		01FA8063FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmerrno.cpp;
+			refType = 4;
+		};
+		01FA8064FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmerrno.h;
+			refType = 4;
+		};
+		01FA8065FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmlist.cpp;
+			refType = 4;
+		};
+		01FA8066FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmlist.h;
+			refType = 4;
+		};
+		01FA8067FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmwalkers.cpp;
+			refType = 4;
+		};
+		01FA8068FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmwalkers.h;
+			refType = 4;
+		};
+		01FA8069FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = daemon.cpp;
+			refType = 4;
+		};
+		01FA806AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = daemon.h;
+			refType = 4;
+		};
+		01FA806BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = Database.cpp;
+			refType = 4;
+		};
+		01FA806CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = Database.h;
+			refType = 4;
+		};
+		01FA806DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DatabaseSession.cpp;
+			refType = 4;
+		};
+		01FA806EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DatabaseSession.h;
+			refType = 4;
+		};
+		01FA806FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbContext.cpp;
+			refType = 4;
+		};
+		01FA8070FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbContext.h;
+			refType = 4;
+		};
+		01FA8071FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbIndex.cpp;
+			refType = 4;
+		};
+		01FA8072FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbIndex.h;
+			refType = 4;
+		};
+		01FA8073FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbName.cpp;
+			refType = 4;
+		};
+		01FA8074FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbName.h;
+			refType = 4;
+		};
+		01FA8075FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbQuery.cpp;
+			refType = 4;
+		};
+		01FA8076FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbQuery.h;
+			refType = 4;
+		};
+		01FA8077FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbValue.cpp;
+			refType = 4;
+		};
+		01FA8078FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = DbValue.h;
+			refType = 4;
+		};
+		01FA8079FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = debugging.cpp;
+			refType = 4;
+		};
+		01FA807AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = debugging.h;
+			refType = 4;
+		};
+		01FA807BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = debugsupport.h;
+			refType = 4;
+		};
+		01FA807CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.mk;
+			refType = 4;
+		};
+		01FA807DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.pl;
+			refType = 4;
+		};
+		01FA807EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = globalizer.cpp;
+			refType = 4;
+		};
+		01FA807FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = globalizer.h;
+			refType = 4;
+		};
+		01FA8080FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = guids.cpp;
+			refType = 4;
+		};
+		01FA8081FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = handleobject.cpp;
+			refType = 4;
+		};
+		01FA8082FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = handleobject.h;
+			refType = 4;
+		};
+		01FA8083FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = logging.cpp;
+			refType = 4;
+		};
+		01FA8084FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = logging.h;
+			refType = 4;
+		};
+		01FA8085FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "mach++.cpp";
+			refType = 4;
+		};
+		01FA8086FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "mach++.h";
+			refType = 4;
+		};
+		01FA8087FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = mach_notify.c;
+			refType = 4;
+		};
+		01FA8088FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = mach_notify.h;
+			refType = 4;
+		};
+		01FA8089FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = machrunloopserver.cpp;
+			refType = 4;
+		};
+		01FA808AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = machrunloopserver.h;
+			refType = 4;
+		};
+		01FA808BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = machserver.cpp;
+			refType = 4;
+		};
+		01FA808CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = machserver.h;
+			refType = 4;
+		};
+		01FA808DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = memutils.h;
+			refType = 4;
+		};
+		01FA808EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = MetaAttribute.cpp;
+			refType = 4;
+		};
+		01FA808FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = MetaAttribute.h;
+			refType = 4;
+		};
+		01FA8090FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = MetaRecord.cpp;
+			refType = 4;
+		};
+		01FA8091FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = MetaRecord.h;
+			refType = 4;
+		};
+		01FA8096FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = os9utils.cpp;
+			refType = 4;
+		};
+		01FA8097FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = os9utils.h;
+			refType = 4;
+		};
+		01FA8098FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = osxsigning.cpp;
+			refType = 4;
+		};
+		01FA8099FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = osxsigning.h;
+			refType = 4;
+		};
+		01FA809AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ReadWriteSection.h;
+			refType = 4;
+		};
+		01FA809BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = refcount.h;
+			refType = 4;
+		};
+		01FA809EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = SelectionPredicate.cpp;
+			refType = 4;
+		};
+		01FA809FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = SelectionPredicate.h;
+			refType = 4;
+		};
+		01FA80A0FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = threading.cpp;
+			refType = 4;
+		};
+		01FA80A1FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = threading.h;
+			refType = 4;
+		};
+		01FA80A2FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = tqueue.cpp;
+			refType = 4;
+		};
+		01FA80A3FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = tqueue.h;
+			refType = 4;
+		};
+		01FA80A4FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = utilities.cpp;
+			refType = 4;
+		};
+		01FA80A5FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = utilities.h;
+			refType = 4;
+		};
+		01FA80A6FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = utility_config.h;
+			refType = 4;
+		};
+		01FA80A7FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = walkers.cpp;
+			refType = 4;
+		};
+		01FA80A8FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = walkers.h;
+			refType = 4;
+		};
+		01FA80AAFFF2B54C11CD283A = {
+			children = (
+				01FA80ACFFF2B54C11CD283A,
+				01FA80ADFFF2B54C11CD283A,
+				01FA80AEFFF2B54C11CD283A,
+				01FA80AFFFF2B54C11CD283A,
+				01FA80B0FFF2B54C11CD283A,
+				01FA80B1FFF2B54C11CD283A,
+				01FA80B2FFF2B54C11CD283A,
+				01FA80B3FFF2B54C11CD283A,
+				01FA80B4FFF2B54C11CD283A,
+				01FA80B5FFF2B54C11CD283A,
+				01FA80B6FFF2B54C11CD283A,
+				01FA80B7FFF2B54C11CD283A,
+				01FA80BBFFF2B54C11CD283A,
+				01FA80BCFFF2B54C11CD283A,
+				01FA80BEFFF2B54C11CD283A,
+				01FA80BFFFF2B54C11CD283A,
+				01FA80C0FFF2B54C11CD283A,
+				01FA80C1FFF2B54C11CD283A,
+				01FA80C2FFF2B54C11CD283A,
+				01FA80C3FFF2B54C11CD283A,
+				01FA80C4FFF2B54C11CD283A,
+				327DDDBD00D6D8E605CD296C,
+				01FA80BAFFF2B54C11CD283A,
+				01FA80B8FFF2B54C11CD283A,
+				01FA80B9FFF2B54C11CD283A,
+				01FA80BDFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = cssm;
+			refType = 4;
+		};
+		01FA80ACFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = attachfactory.cpp;
+			refType = 4;
+		};
+		01FA80ADFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = attachfactory.h;
+			refType = 4;
+		};
+		01FA80AEFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = attachment.cpp;
+			refType = 4;
+		};
+		01FA80AFFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = attachment.h;
+			refType = 4;
+		};
+		01FA80B0FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cspattachment.cpp;
+			refType = 4;
+		};
+		01FA80B1FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cspattachment.h;
+			refType = 4;
+		};
+		01FA80B2FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssm.cpp;
+			refType = 4;
+		};
+		01FA80B3FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcontext.cpp;
+			refType = 4;
+		};
+		01FA80B4FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcontext.h;
+			refType = 4;
+		};
+		01FA80B5FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmint.h;
+			refType = 4;
+		};
+		01FA80B6FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmmds.cpp;
+			refType = 4;
+		};
+		01FA80B7FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cssmmds.h;
+			refType = 4;
+		};
+		01FA80B8FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.cfg;
+			refType = 4;
+		};
+		01FA80B9FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.mk;
+			refType = 4;
+		};
+		01FA80BAFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.pl;
+			refType = 4;
+		};
+		01FA80BBFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = manager.cpp;
+			refType = 4;
+		};
+		01FA80BCFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = manager.h;
+			refType = 4;
+		};
+		01FA80BDFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = MDS;
+			refType = 4;
+		};
+		01FA80BEFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = module.cpp;
+			refType = 4;
+		};
+		01FA80BFFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = module.h;
+			refType = 4;
+		};
+		01FA80C0FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidsalg.c;
+			refType = 4;
+		};
+		01FA80C1FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidsattr.c;
+			refType = 4;
+		};
+		01FA80C2FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidscert.cpp;
+			refType = 4;
+		};
+		01FA80C3FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = oidscrl.cpp;
+			refType = 4;
+		};
+		01FA80C4FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = transition.cpp;
+			refType = 4;
+		};
+		01FA80C6FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = generator.mk;
+			refType = 4;
+		};
+		01FA80D6FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = TODO;
+			refType = 4;
+		};
+		01FA8126FFF2B54C11CD283A = {
+			children = (
+				01FA8127FFF2B54C11CD283A,
+				01FA8128FFF2B54C11CD283A,
+				01FA8129FFF2B54C11CD283A,
+				01FA812AFFF2B54C11CD283A,
+				01FA812BFFF2B54C11CD283A,
+				01FA812CFFF2B54C11CD283A,
+				01FA812DFFF2B54C11CD283A,
+				01FA812EFFF2B54C11CD283A,
+				01FA812FFFF2B54C11CD283A,
+				01FA8130FFF2B54C11CD283A,
+				01FA8131FFF2B54C11CD283A,
+				01FA8132FFF2B54C11CD283A,
+				01FA8133FFF2B54C11CD283A,
+				01FA8134FFF2B54C11CD283A,
+				01FA8135FFF2B54C11CD283A,
+				01FA8136FFF2B54C11CD283A,
+				01FA8137FFF2B54C11CD283A,
+				01FA8138FFF2B54C11CD283A,
+				01FA8152FFF2B54C11CD283A,
+				01FA8153FFF2B54C11CD283A,
+				01FA8156FFF2B54C11CD283A,
+				01FA8157FFF2B54C11CD283A,
+				01FA8158FFF2B54C11CD283A,
+				01FA8159FFF2B54C11CD283A,
+				01FA815AFFF2B54C11CD283A,
+				01FA815BFFF2B54C11CD283A,
+				01FA815CFFF2B54C11CD283A,
+				01FA815DFFF2B54C11CD283A,
+				01FA815EFFF2B54C11CD283A,
+				01FA815FFFF2B54C11CD283A,
+				01FA8161FFF2B54C11CD283A,
+				01FA8162FFF2B54C11CD283A,
+				01FA8163FFF2B54C11CD283A,
+				01FA8164FFF2B54C11CD283A,
+				01FA8165FFF2B54C11CD283A,
+				01FA8166FFF2B54C11CD283A,
+				01FA8167FFF2B54C11CD283A,
+				33BD042000838F447F000001,
+			);
+			isa = PBXGroup;
+			path = SecureTransport;
+			refType = 4;
+		};
+		01FA8127FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = appleCdsa.c;
+			refType = 4;
+		};
+		01FA8128FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = appleGlue.c;
+			refType = 4;
+		};
+		01FA8129FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = appleSession.c;
+			refType = 4;
+		};
+		01FA812AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cipherSpecs.c;
+			refType = 4;
+		};
+		01FA812BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cppUtils.cpp;
+			refType = 4;
+		};
+		01FA812CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = digests.c;
+			refType = 4;
+		};
+		01FA812DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = hdskcert.c;
+			refType = 4;
+		};
+		01FA812EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = hdskchgc.c;
+			refType = 4;
+		};
+		01FA812FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = hdskfini.c;
+			refType = 4;
+		};
+		01FA8130FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = hdskhelo.c;
+			refType = 4;
+		};
+		01FA8131FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = hdskkeys.c;
+			refType = 4;
+		};
+		01FA8132FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = hdskkyex.c;
+			refType = 4;
+		};
+		01FA8133FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = LICENSE.txt;
+			refType = 4;
+		};
+		01FA8134FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslmd5.c;
+			refType = 4;
+		};
+		01FA8135FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ModuleAttacher.cpp;
+			refType = 4;
+		};
+		01FA8136FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ModuleAttacher.h;
+			refType = 4;
+		};
+		01FA8137FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = nullciph.c;
+			refType = 4;
+		};
+		01FA8138FFF2B54C11CD283A = {
+			children = (
+				01FA8139FFF2B54C11CD283A,
+				01FA813AFFF2B54C11CD283A,
+				01FA813BFFF2B54C11CD283A,
+				01FA813CFFF2B54C11CD283A,
+				01FA813DFFF2B54C11CD283A,
+				01FA813EFFF2B54C11CD283A,
+				01FA813FFFF2B54C11CD283A,
+				01FA8140FFF2B54C11CD283A,
+				01FA8141FFF2B54C11CD283A,
+				01FA8142FFF2B54C11CD283A,
+				01FA8143FFF2B54C11CD283A,
+				01FA8144FFF2B54C11CD283A,
+				01FA8145FFF2B54C11CD283A,
+				01FA8146FFF2B54C11CD283A,
+				01FA8147FFF2B54C11CD283A,
+				01FA8148FFF2B54C11CD283A,
+				01FA8149FFF2B54C11CD283A,
+				01FA814AFFF2B54C11CD283A,
+				01FA814BFFF2B54C11CD283A,
+				01FA814CFFF2B54C11CD283A,
+				01FA814DFFF2B54C11CD283A,
+				01FA814EFFF2B54C11CD283A,
+				01FA814FFFF2B54C11CD283A,
+				01FA8150FFF2B54C11CD283A,
+				01FA8151FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = privateInc;
+			refType = 4;
+		};
+		01FA8139FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = appleCdsa.h;
+			refType = 4;
+		};
+		01FA813AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = appleGlue.h;
+			refType = 4;
+		};
+		01FA813BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = appleSession.h;
+			refType = 4;
+		};
+		01FA813CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cipherSpecs.h;
+			refType = 4;
+		};
+		01FA813DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cryptType.h;
+			refType = 4;
+		};
+		01FA813EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = digests.h;
+			refType = 4;
+		};
+		01FA813FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslmd5.h;
+			refType = 4;
+		};
+		01FA8140FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = st_sha.h;
+			refType = 4;
+		};
+		01FA8141FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssl.h;
+			refType = 4;
+		};
+		01FA8142FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssl2.h;
+			refType = 4;
+		};
+		01FA8143FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslalert.h;
+			refType = 4;
+		};
+		01FA8144FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslalloc.h;
+			refType = 4;
+		};
+		01FA8145FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslBER.h;
+			refType = 4;
+		};
+		01FA8146FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslBuildFlags.h;
+			refType = 4;
+		};
+		01FA8147FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslctx.h;
+			refType = 4;
+		};
+		01FA8148FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslDebug.h;
+			refType = 4;
+		};
+		01FA8149FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslerrs.h;
+			refType = 4;
+		};
+		01FA814AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslhdshk.h;
+			refType = 4;
+		};
+		01FA814BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslKeychain.h;
+			refType = 4;
+		};
+		01FA814CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslPriv.h;
+			refType = 4;
+		};
+		01FA814DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslrec.h;
+			refType = 4;
+		};
+		01FA814EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslsess.h;
+			refType = 4;
+		};
+		01FA814FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssltrspt.h;
+			refType = 4;
+		};
+		01FA8150FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslutil.h;
+			refType = 4;
+		};
+		01FA8151FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = symCipher.h;
+			refType = 4;
+		};
+		01FA8152FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = README;
+			refType = 4;
+		};
+		01FA8153FFF2B54C11CD283A = {
+			children = (
+				01FA8154FFF2B54C11CD283A,
+				01FA8155FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = SecureTransport;
+			refType = 4;
+		};
+		01FA8154FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = CipherSuite.h;
+			refType = 4;
+		};
+		01FA8155FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = SecureTransport.h;
+			refType = 4;
+		};
+		01FA8156FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = secureTransport.exp;
+			refType = 4;
+		};
+		01FA8157FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sha.c;
+			refType = 4;
+		};
+		01FA8158FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssl2map.c;
+			refType = 4;
+		};
+		01FA8159FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssl2mesg.c;
+			refType = 4;
+		};
+		01FA815AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssl2prot.c;
+			refType = 4;
+		};
+		01FA815BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssl2rec.c;
+			refType = 4;
+		};
+		01FA815CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslalert.c;
+			refType = 4;
+		};
+		01FA815DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslalloc.c;
+			refType = 4;
+		};
+		01FA815EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslBER.cpp;
+			refType = 4;
+		};
+		01FA815FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslctx.c;
+			refType = 4;
+		};
+		01FA8161FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslhdshk.c;
+			refType = 4;
+		};
+		01FA8162FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslKeychain.c;
+			refType = 4;
+		};
+		01FA8163FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslrec.c;
+			refType = 4;
+		};
+		01FA8164FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslsess.c;
+			refType = 4;
+		};
+		01FA8165FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssltrspt.c;
+			refType = 4;
+		};
+		01FA8166FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sslutil.c;
+			refType = 4;
+		};
+		01FA8167FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = symCipher.c;
+			refType = 4;
+		};
+		01FA8168FFF2B54C11CD283A = {
+			children = (
+				01FA8169FFF2B54C11CD283A,
+				01FA817CFFF2B54C11CD283A,
+				01FA818CFFF2B54C11CD283A,
+				01FA819CFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = SecurityASN1;
+			refType = 4;
+		};
+		01FA8169FFF2B54C11CD283A = {
+			children = (
+				4EB202DD0058585F7F000001,
+				01FA816AFFF2B54C11CD283A,
+				01FA816BFFF2B54C11CD283A,
+				01FA816CFFF2B54C11CD283A,
+				01FA816DFFF2B54C11CD283A,
+				01FA816EFFF2B54C11CD283A,
+				01FA816FFFF2B54C11CD283A,
+				01FA8170FFF2B54C11CD283A,
+				01FA8171FFF2B54C11CD283A,
+				01FA8172FFF2B54C11CD283A,
+				01FA8173FFF2B54C11CD283A,
+				01FA8174FFF2B54C11CD283A,
+				01FA8175FFF2B54C11CD283A,
+				01FA8176FFF2B54C11CD283A,
+				01FA8177FFF2B54C11CD283A,
+				01FA8178FFF2B54C11CD283A,
+				01FA8179FFF2B54C11CD283A,
+				01FA817AFFF2B54C11CD283A,
+				01FA817BFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = asn;
+			refType = 4;
+		};
+		01FA816AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-useful.asn1";
+			refType = 4;
+		};
+		01FA816BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs1.asn1;
+			refType = 4;
+		};
+		01FA816CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs1oids.asn;
+			refType = 4;
+		};
+		01FA816DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs5.asn1;
+			refType = 4;
+		};
+		01FA816EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs7.asn;
+			refType = 4;
+		};
+		01FA816FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs8.asn;
+			refType = 4;
+		};
+		01FA8170FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs9oids.asn;
+			refType = 4;
+		};
+		01FA8171FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_cms.asn;
+			refType = 4;
+		};
+		01FA8172FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_ess.asn;
+			refType = 4;
+		};
+		01FA8173FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_vdatypes.asn;
+			refType = 4;
+		};
+		01FA8174FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x411mtsas.asn;
+			refType = 4;
+		};
+		01FA8175FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x411ub.asn;
+			refType = 4;
+		};
+		01FA8176FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x501if.asn;
+			refType = 4;
+		};
+		01FA8177FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x501ud.asn;
+			refType = 4;
+		};
+		01FA8178FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509af.asn;
+			refType = 4;
+		};
+		01FA8179FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509ce.asn;
+			refType = 4;
+		};
+		01FA817AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509cmn.asn;
+			refType = 4;
+		};
+		01FA817BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x520sa.asn;
+			refType = 4;
+		};
+		01FA817CFFF2B54C11CD283A = {
+			children = (
+				4EB202DE0058585F7F000001,
+				01FA817DFFF2B54C11CD283A,
+				01FA817EFFF2B54C11CD283A,
+				01FA817FFFF2B54C11CD283A,
+				01FA8180FFF2B54C11CD283A,
+				01FA8181FFF2B54C11CD283A,
+				01FA8182FFF2B54C11CD283A,
+				01FA8183FFF2B54C11CD283A,
+				01FA8184FFF2B54C11CD283A,
+				01FA8185FFF2B54C11CD283A,
+				01FA8186FFF2B54C11CD283A,
+				01FA8187FFF2B54C11CD283A,
+				01FA8188FFF2B54C11CD283A,
+				01FA8189FFF2B54C11CD283A,
+				01FA818AFFF2B54C11CD283A,
+				01FA818BFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = "c++";
+			refType = 4;
+		};
+		01FA817DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs1oids.cpp;
+			refType = 4;
+		};
+		01FA817EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs7.cpp;
+			refType = 4;
+		};
+		01FA817FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs8.cpp;
+			refType = 4;
+		};
+		01FA8180FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs9oids.cpp;
+			refType = 4;
+		};
+		01FA8181FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_cms.cpp;
+			refType = 4;
+		};
+		01FA8182FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_ess.cpp;
+			refType = 4;
+		};
+		01FA8183FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_vdatypes.cpp;
+			refType = 4;
+		};
+		01FA8184FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x411mtsas.cpp;
+			refType = 4;
+		};
+		01FA8185FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x411ub.cpp;
+			refType = 4;
+		};
+		01FA8186FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x501if.cpp;
+			refType = 4;
+		};
+		01FA8187FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x501ud.cpp;
+			refType = 4;
+		};
+		01FA8188FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509af.cpp;
+			refType = 4;
+		};
+		01FA8189FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509ce.cpp;
+			refType = 4;
+		};
+		01FA818AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509cmn.cpp;
+			refType = 4;
+		};
+		01FA818BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x520sa.cpp;
+			refType = 4;
+		};
+		01FA818CFFF2B54C11CD283A = {
+			children = (
+				4EB202E00058588E7F000001,
+				01FA818DFFF2B54C11CD283A,
+				01FA818EFFF2B54C11CD283A,
+				01FA818FFFF2B54C11CD283A,
+				01FA8190FFF2B54C11CD283A,
+				01FA8191FFF2B54C11CD283A,
+				01FA8192FFF2B54C11CD283A,
+				01FA8193FFF2B54C11CD283A,
+				01FA8194FFF2B54C11CD283A,
+				01FA8195FFF2B54C11CD283A,
+				01FA8196FFF2B54C11CD283A,
+				01FA8197FFF2B54C11CD283A,
+				01FA8198FFF2B54C11CD283A,
+				01FA8199FFF2B54C11CD283A,
+				01FA819AFFF2B54C11CD283A,
+				01FA819BFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = inc;
+			refType = 4;
+		};
+		01FA818DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs1oids.h;
+			refType = 4;
+		};
+		01FA818EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs7.h;
+			refType = 4;
+		};
+		01FA818FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs8.h;
+			refType = 4;
+		};
+		01FA8190FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = pkcs9oids.h;
+			refType = 4;
+		};
+		01FA8191FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_cms.h;
+			refType = 4;
+		};
+		01FA8192FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_ess.h;
+			refType = 4;
+		};
+		01FA8193FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_vdatypes.h;
+			refType = 4;
+		};
+		01FA8194FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x411mtsas.h;
+			refType = 4;
+		};
+		01FA8195FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x411ub.h;
+			refType = 4;
+		};
+		01FA8196FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x501if.h;
+			refType = 4;
+		};
+		01FA8197FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x501ud.h;
+			refType = 4;
+		};
+		01FA8198FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509af.h;
+			refType = 4;
+		};
+		01FA8199FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509ce.h;
+			refType = 4;
+		};
+		01FA819AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x509cmn.h;
+			refType = 4;
+		};
+		01FA819BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_x520sa.h;
+			refType = 4;
+		};
+		01FA819CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = Makefile;
+			refType = 4;
+		};
+		01FA819DFFF2B54C11CD283A = {
+			children = (
+				01FA8214FFF2B54C11CD283A,
+				01FA821EFFF2B54C11CD283A,
+				01FA81B5FFF2B54C11CD283A,
+				01FA81B4FFF2B54C11CD283A,
+				01FA8219FFF2B54C11CD283A,
+				01FA8218FFF2B54C11CD283A,
+				01FA8223FFF2B54C11CD283A,
+				01FA8222FFF2B54C11CD283A,
+				125E85A9FFF3CDEF11CD283A,
+				125E85A8FFF3CDEF11CD283A,
+				01FA81A5FFF2B54C11CD283A,
+				01FA81A4FFF2B54C11CD283A,
+				01FA8221FFF2B54C11CD283A,
+				01FA8220FFF2B54C11CD283A,
+				01FA81BDFFF2B54C11CD283A,
+				01FA81BCFFF2B54C11CD283A,
+				01FA8225FFF2B54C11CD283A,
+				01FA8224FFF2B54C11CD283A,
+				01FA81A0FFF2B54C11CD283A,
+				01FA81A1FFF2B54C11CD283A,
+				01FA819EFFF2B54C11CD283A,
+				01FA819FFFF2B54C11CD283A,
+				01FA81A2FFF2B54C11CD283A,
+				01FA81A3FFF2B54C11CD283A,
+				01FA81B9FFF2B54C11CD283A,
+				01FA81B8FFF2B54C11CD283A,
+				01FA81B2FFF2B54C11CD283A,
+				01FA81B3FFF2B54C11CD283A,
+				01FA823AFFF2B54C11CD283A,
+				01379EAE001E00F311CD296C,
+				0165238D000BEC3311CD296C,
+				0165238E000BEC3311CD296C,
+				0165238F000BEC3311CD296C,
+				01FA81BEFFF2B54C11CD283A,
+				01FA81A6FFF2B54C11CD283A,
+				01FA822AFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = SecurityServer;
+			refType = 4;
+		};
+		01FA819EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_keychain.cpp;
+			refType = 4;
+		};
+		01FA819FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acl_keychain.h;
+			refType = 4;
+		};
+		01FA81A0FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acls.cpp;
+			refType = 4;
+		};
+		01FA81A1FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = acls.h;
+			refType = 4;
+		};
+		01FA81A2FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = agentquery.cpp;
+			refType = 4;
+		};
+		01FA81A3FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = agentquery.h;
+			refType = 4;
+		};
+		01FA81A4FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = authority.cpp;
+			refType = 4;
+		};
+		01FA81A5FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = authority.h;
+			refType = 4;
+		};
+		01FA81A6FFF2B54C11CD283A = {
+			children = (
+				01FA81A8FFF2B54C11CD283A,
+				3267644800EBF3A905CD296C,
+				01FA81A7FFF2B54C11CD283A,
+				01FA81A9FFF2B54C11CD283A,
+				01FA81AAFFF2B54C11CD283A,
+				01FA81ABFFF2B54C11CD283A,
+				01FA81ACFFF2B54C11CD283A,
+				01FA81ADFFF2B54C11CD283A,
+				01FA81AEFFF2B54C11CD283A,
+				01FA81AFFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = Authorization;
+			refType = 4;
+		};
+		01FA81A7FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = Authorization.cpp;
+			refType = 4;
+		};
+		01FA81A8FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = Authorization.h;
+			refType = 4;
+		};
+		01FA81A9FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationEngine.cpp;
+			refType = 4;
+		};
+		01FA81AAFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationEngine.h;
+			refType = 4;
+		};
+		01FA81ABFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationTags.h;
+			refType = 4;
+		};
+		01FA81ACFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationTrampoline.cpp;
+			refType = 4;
+		};
+		01FA81ADFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationWalkers.h;
+			refType = 4;
+		};
+		01FA81AEFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = trampolineClient.cpp;
+			refType = 4;
+		};
+		01FA81AFFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = trampolineServer.cpp;
+			refType = 4;
+		};
+		01FA81B1FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = BLOBFORMAT;
+			refType = 4;
+		};
+		01FA81B2FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cfnotifier.cpp;
+			refType = 4;
+		};
+		01FA81B3FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cfnotifier.h;
+			refType = 4;
+		};
+		01FA81B4FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = connection.cpp;
+			refType = 4;
+		};
+		01FA81B5FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = connection.h;
+			refType = 4;
+		};
+		01FA81B8FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = dbcrypto.cpp;
+			refType = 4;
+		};
+		01FA81B9FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = dbcrypto.h;
+			refType = 4;
+		};
+		01FA81BCFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = key.cpp;
+			refType = 4;
+		};
+		01FA81BDFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = key.h;
+			refType = 4;
+		};
+		01FA81BEFFF2B54C11CD283A = {
+			children = (
+				32615BB000E3B46905CD296C,
+				32615BB200E3B4A105CD296C,
+				01FA81C1FFF2B54C11CD283A,
+				01FA81E3FFF2B54C11CD283A,
+				01FA81F7FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = MacYarrow;
+			refType = 4;
+		};
+		01FA81C1FFF2B54C11CD283A = {
+			children = (
+				01FA81C2FFF2B54C11CD283A,
+				01FA81C3FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = testHarness;
+			refType = 4;
+		};
+		01FA81C2FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = clientTest.cpp;
+			refType = 4;
+		};
+		01FA81C3FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = serverDaemon.cpp;
+			refType = 4;
+		};
+		01FA81E3FFF2B54C11CD283A = {
+			children = (
+				01FA81E4FFF2B54C11CD283A,
+				01FA81E5FFF2B54C11CD283A,
+				01FA81E6FFF2B54C11CD283A,
+				01FA81E7FFF2B54C11CD283A,
+				01FA81E8FFF2B54C11CD283A,
+				01FA81E9FFF2B54C11CD283A,
+				01FA81ECFFF2B54C11CD283A,
+				01FA81EDFFF2B54C11CD283A,
+				01FA81EEFFF2B54C11CD283A,
+				01FA81EFFFF2B54C11CD283A,
+				560B41E100E23FA50DCD28E8,
+				560B41E200E23FA50DCD28E8,
+			);
+			isa = PBXGroup;
+			path = YarrowServer;
+			refType = 4;
+		};
+		01FA81E4FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = debug.c;
+			refType = 4;
+		};
+		01FA81E5FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = debug.h;
+			refType = 4;
+		};
+		01FA81E6FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = entropyFile.h;
+			refType = 4;
+		};
+		01FA81E7FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = entropyFileOS9.c;
+			refType = 4;
+		};
+		01FA81E8FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = entropyFileUnix.c;
+			refType = 4;
+		};
+		01FA81E9FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = kdebug_private.h;
+			refType = 4;
+		};
+		01FA81ECFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = prefixDebug.h;
+			refType = 4;
+		};
+		01FA81EDFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = prefixRelease.h;
+			refType = 4;
+		};
+		01FA81EEFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = systemEntropy.c;
+			refType = 4;
+		};
+		01FA81EFFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = systemEntropy.h;
+			refType = 4;
+		};
+		01FA81F7FFF2B54C11CD283A = {
+			children = (
+				01FA81F8FFF2B54C11CD283A,
+				01FA81F9FFF2B54C11CD283A,
+				01FA81FAFFF2B54C11CD283A,
+				01FA81FBFFF2B54C11CD283A,
+				01FA81FCFFF2B54C11CD283A,
+				01FA81FDFFF2B54C11CD283A,
+				01FA81FEFFF2B54C11CD283A,
+				01FA81FFFFF2B54C11CD283A,
+				01FA8200FFF2B54C11CD283A,
+				01FA8201FFF2B54C11CD283A,
+				01FA8202FFF2B54C11CD283A,
+				01FA8203FFF2B54C11CD283A,
+				01FA8204FFF2B54C11CD283A,
+				01FA8205FFF2B54C11CD283A,
+				01FA8206FFF2B54C11CD283A,
+				01FA8207FFF2B54C11CD283A,
+				01FA8208FFF2B54C11CD283A,
+				01FA8209FFF2B54C11CD283A,
+				01FA820AFFF2B54C11CD283A,
+				01FA820BFFF2B54C11CD283A,
+				01FA820CFFF2B54C11CD283A,
+				01FA820DFFF2B54C11CD283A,
+				01FA820EFFF2B54C11CD283A,
+				01FA820FFFF2B54C11CD283A,
+				01FA8210FFF2B54C11CD283A,
+				01FA8212FFF2B54C11CD283A,
+				01FA8213FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = zlib;
+			refType = 4;
+		};
+		01FA81F8FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = adler32.c;
+			refType = 4;
+		};
+		01FA81F9FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = algorithm.txt;
+			refType = 4;
+		};
+		01FA81FAFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ChangeLog;
+			refType = 4;
+		};
+		01FA81FBFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = compress.c;
+			refType = 4;
+		};
+		01FA81FCFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = crc32.c;
+			refType = 4;
+		};
+		01FA81FDFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = deflate.c;
+			refType = 4;
+		};
+		01FA81FEFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = deflate.h;
+			refType = 4;
+		};
+		01FA81FFFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = infblock.c;
+			refType = 4;
+		};
+		01FA8200FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = infblock.h;
+			refType = 4;
+		};
+		01FA8201FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = infcodes.c;
+			refType = 4;
+		};
+		01FA8202FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = infcodes.h;
+			refType = 4;
+		};
+		01FA8203FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = inffast.c;
+			refType = 4;
+		};
+		01FA8204FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = inffast.h;
+			refType = 4;
+		};
+		01FA8205FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = inffixed.h;
+			refType = 4;
+		};
+		01FA8206FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = inflate.c;
+			refType = 4;
+		};
+		01FA8207FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = inftrees.c;
+			refType = 4;
+		};
+		01FA8208FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = inftrees.h;
+			refType = 4;
+		};
+		01FA8209FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = infutil.c;
+			refType = 4;
+		};
+		01FA820AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = infutil.h;
+			refType = 4;
+		};
+		01FA820BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = README;
+			refType = 4;
+		};
+		01FA820CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = trees.c;
+			refType = 4;
+		};
+		01FA820DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = trees.h;
+			refType = 4;
+		};
+		01FA820EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = uncompr.c;
+			refType = 4;
+		};
+		01FA820FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = zconf.h;
+			refType = 4;
+		};
+		01FA8210FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = zlib.h;
+			refType = 4;
+		};
+		01FA8212FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = zutil.c;
+			refType = 4;
+		};
+		01FA8213FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = zutil.h;
+			refType = 4;
+		};
+		01FA8214FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = main.cpp;
+			refType = 4;
+		};
+		01FA8215FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = Makefile;
+			refType = 4;
+		};
+		01FA8216FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			name = Makefile.startup;
+			path = SecurityServer/Makefile.startup;
+			refType = 2;
+		};
+		01FA8218FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = process.cpp;
+			refType = 4;
+		};
+		01FA8219FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = process.h;
+			refType = 4;
+		};
+		01FA821AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = secagent.defs;
+			refType = 4;
+		};
+		01FA821BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = secagent_types.h;
+			refType = 4;
+		};
+		01FA821CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = SecurityAgentClient.cpp;
+			refType = 4;
+		};
+		01FA821DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = SecurityAgentClient.h;
+			refType = 4;
+		};
+		01FA821EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = securityserver.h;
+			refType = 4;
+		};
+		01FA821FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = SecurityServerClient.h;
+			refType = 4;
+		};
+		01FA8220FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = server.cpp;
+			refType = 4;
+		};
+		01FA8221FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = server.h;
+			refType = 4;
+		};
+		01FA8222FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = session.cpp;
+			refType = 4;
+		};
+		01FA8223FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = session.h;
+			refType = 4;
+		};
+		01FA8224FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssblob.cpp;
+			refType = 4;
+		};
+		01FA8225FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssblob.h;
+			refType = 4;
+		};
+		01FA8226FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssclient.cpp;
+			refType = 4;
+		};
+		01FA8227FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ssclient.h;
+			refType = 4;
+		};
+		01FA8228FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sstransit.cpp;
+			refType = 4;
+		};
+		01FA8229FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sstransit.h;
+			refType = 4;
+		};
+		01FA822AFFF2B54C11CD283A = {
+			children = (
+				01FA8216FFF2B54C11CD283A,
+				01FA822BFFF2B54C11CD283A,
+				01FA822CFFF2B54C11CD283A,
+				21306AAD0030B27011CD283A,
+			);
+			isa = PBXGroup;
+			path = StartupItems;
+			refType = 4;
+		};
+		01FA822BFFF2B54C11CD283A = {
+			isa = PBXExecutableFileReference;
+			path = SecurityServer;
+			refType = 4;
+		};
+		01FA822CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = StartupParameters.plist;
+			refType = 4;
+		};
+		01FA8239FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = TODO;
+			refType = 4;
+		};
+		01FA823AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = transition.cpp;
+			refType = 4;
+		};
+		01FA823BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ucsp.defs;
+			refType = 4;
+		};
+		01FA823CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = ucsp_types.h;
+			refType = 4;
+		};
+		01FA823FFFF2B54C11CD283A = {
+			children = (
+				01FA8241FFF2B54C11CD283A,
+				01FA8263FFF2B54C11CD283A,
+				01FA8467FFF2B54C11CD283A,
+				01FA848CFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = SecuritySNACCRuntime;
+			refType = 4;
+		};
+		01FA8241FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = Apple_README;
+			refType = 4;
+		};
+		01FA8263FFF2B54C11CD283A = {
+			children = (
+				01FA8264FFF2B54C11CD283A,
+				01FA827AFFF2B54C11CD283A,
+				01FA829BFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = "c++-lib";
+			refType = 4;
+		};
+		01FA8264FFF2B54C11CD283A = {
+			children = (
+				01FA8265FFF2B54C11CD283A,
+				01FA8266FFF2B54C11CD283A,
+				01FA8267FFF2B54C11CD283A,
+				01FA8268FFF2B54C11CD283A,
+				01FA8269FFF2B54C11CD283A,
+				01FA826AFFF2B54C11CD283A,
+				01FA826BFFF2B54C11CD283A,
+				01FA826CFFF2B54C11CD283A,
+				01FA826DFFF2B54C11CD283A,
+				01FA826EFFF2B54C11CD283A,
+				01FA826FFFF2B54C11CD283A,
+				01FA8270FFF2B54C11CD283A,
+				01FA8271FFF2B54C11CD283A,
+				01FA8272FFF2B54C11CD283A,
+				01FA8273FFF2B54C11CD283A,
+				01FA8274FFF2B54C11CD283A,
+				01FA8275FFF2B54C11CD283A,
+				01FA8276FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = "c++";
+			refType = 4;
+		};
+		01FA8265FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-any.cpp";
+			refType = 4;
+		};
+		01FA8266FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-bits.cpp";
+			refType = 4;
+		};
+		01FA8267FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-bool.cpp";
+			refType = 4;
+		};
+		01FA8268FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-enum.cpp";
+			refType = 4;
+		};
+		01FA8269FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-int.cpp";
+			refType = 4;
+		};
+		01FA826AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-len.cpp";
+			refType = 4;
+		};
+		01FA826BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-list.cpp";
+			refType = 4;
+		};
+		01FA826CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-null.cpp";
+			refType = 4;
+		};
+		01FA826DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-octs.cpp";
+			refType = 4;
+		};
+		01FA826EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-oid.cpp";
+			refType = 4;
+		};
+		01FA826FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-real.cpp";
+			refType = 4;
+		};
+		01FA8270FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-tag.cpp";
+			refType = 4;
+		};
+		01FA8271FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-type.cpp";
+			refType = 4;
+		};
+		01FA8272FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-useful.cpp";
+			refType = 4;
+		};
+		01FA8273FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = hash.cpp;
+			refType = 4;
+		};
+		01FA8274FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = meta.cpp;
+			refType = 4;
+		};
+		01FA8275FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = print.cpp;
+			refType = 4;
+		};
+		01FA8276FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "str-stk.cpp";
+			refType = 4;
+		};
+		01FA827AFFF2B54C11CD283A = {
+			children = (
+				01FA827BFFF2B54C11CD283A,
+				01FA827CFFF2B54C11CD283A,
+				01FA827DFFF2B54C11CD283A,
+				01FA827EFFF2B54C11CD283A,
+				01FA827FFFF2B54C11CD283A,
+				01FA8280FFF2B54C11CD283A,
+				01FA8281FFF2B54C11CD283A,
+				01FA8282FFF2B54C11CD283A,
+				01FA8283FFF2B54C11CD283A,
+				01FA8284FFF2B54C11CD283A,
+				01FA8285FFF2B54C11CD283A,
+				01FA8286FFF2B54C11CD283A,
+				01FA8287FFF2B54C11CD283A,
+				01FA8288FFF2B54C11CD283A,
+				01FA8289FFF2B54C11CD283A,
+				01FA828AFFF2B54C11CD283A,
+				01FA828BFFF2B54C11CD283A,
+				01FA828CFFF2B54C11CD283A,
+				01FA828DFFF2B54C11CD283A,
+				01FA828EFFF2B54C11CD283A,
+				01FA828FFFF2B54C11CD283A,
+				01FA8290FFF2B54C11CD283A,
+				01FA8291FFF2B54C11CD283A,
+				01FA8292FFF2B54C11CD283A,
+				01FA8293FFF2B54C11CD283A,
+				01FA8295FFF2B54C11CD283A,
+				01FA8296FFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = inc;
+			refType = 4;
+		};
+		01FA827BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-any.h";
+			refType = 4;
+		};
+		01FA827CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-bits.h";
+			refType = 4;
+		};
+		01FA827DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-bool.h";
+			refType = 4;
+		};
+		01FA827EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-buf.h";
+			refType = 4;
+		};
+		01FA827FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-config.h";
+			refType = 4;
+		};
+		01FA8280FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-enum.h";
+			refType = 4;
+		};
+		01FA8281FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-incl.h";
+			refType = 4;
+		};
+		01FA8282FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-int.h";
+			refType = 4;
+		};
+		01FA8283FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-len.h";
+			refType = 4;
+		};
+		01FA8284FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-list.h";
+			refType = 4;
+		};
+		01FA8285FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-null.h";
+			refType = 4;
+		};
+		01FA8286FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-octs.h";
+			refType = 4;
+		};
+		01FA8287FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-oid.h";
+			refType = 4;
+		};
+		01FA8288FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-real.h";
+			refType = 4;
+		};
+		01FA8289FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-tag.h";
+			refType = 4;
+		};
+		01FA828AFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-type.h";
+			refType = 4;
+		};
+		01FA828BFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "asn-useful.h";
+			refType = 4;
+		};
+		01FA828CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cdsaUtils.h;
+			refType = 4;
+		};
+		01FA828DFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = config.h;
+			refType = 4;
+		};
+		01FA828EFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = hash.h;
+			refType = 4;
+		};
+		01FA828FFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = init.h;
+			refType = 4;
+		};
+		01FA8290FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = meta.h;
+			refType = 4;
+		};
+		01FA8291FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = policy.h;
+			refType = 4;
+		};
+		01FA8292FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = print.h;
+			refType = 4;
+		};
+		01FA8293FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_vdasnacc.h;
+			refType = 4;
+		};
+		01FA8295FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = snacc.h;
+			refType = 4;
+		};
+		01FA8296FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = "str-stk.h";
+			refType = 4;
+		};
+		01FA829BFFF2B54C11CD283A = {
+			children = (
+				01FA82B6FFF2B54C11CD283A,
+				01FA82BDFFF2B54C11CD283A,
+				01FA82BEFFF2B54C11CD283A,
+			);
+			isa = PBXGroup;
+			path = src;
+			refType = 4;
+		};
+		01FA82B6FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = cdsaUtils.cpp;
+			refType = 4;
+		};
+		01FA82BDFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_buffer.cpp;
+			refType = 4;
+		};
+		01FA82BEFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = sm_vdasnacc.cpp;
+			refType = 4;
+		};
+		01FA8467FFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = README;
+			refType = 4;
+		};
+		01FA848CFFF2B54C11CD283A = {
+			isa = PBXFileReference;
+			path = VDADER_RULES.TXT;
+			refType = 4;
+		};
+		01FA848EFFF2B54C11CD283A = {
+			fileRef = 01FA7FE8FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA848FFFF2B54C11CD283A = {
+			fileRef = 01FA7FE9FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8490FFF2B54C11CD283A = {
+			fileRef = 01FA7FEAFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8491FFF2B54C11CD283A = {
+			fileRef = 01FA7FEBFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8492FFF2B54C11CD283A = {
+			fileRef = 01FA7FECFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8493FFF2B54C11CD283A = {
+			fileRef = 01FA7FEDFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8494FFF2B54C11CD283A = {
+			fileRef = 01FA7FEEFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8495FFF2B54C11CD283A = {
+			fileRef = 01FA7FEFFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8496FFF2B54C11CD283A = {
+			fileRef = 01FA7FF0FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8497FFF2B54C11CD283A = {
+			fileRef = 01FA7FF1FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8498FFF2B54C11CD283A = {
+			fileRef = 01FA7FF2FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8499FFF2B54C11CD283A = {
+			fileRef = 01FA7FF3FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA849AFFF2B54C11CD283A = {
+			fileRef = 01FA7FF4FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA849BFFF2B54C11CD283A = {
+			fileRef = 01FA7FF5FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA849CFFF2B54C11CD283A = {
+			fileRef = 01FA7FF6FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA849DFFF2B54C11CD283A = {
+			fileRef = 01FA7FF7FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA849EFFF2B54C11CD283A = {
+			fileRef = 01FA7FF8FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA849FFFF2B54C11CD283A = {
+			fileRef = 01FA7FF9FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A0FFF2B54C11CD283A = {
+			fileRef = 01FA7FFAFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A1FFF2B54C11CD283A = {
+			fileRef = 01FA7FFBFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A2FFF2B54C11CD283A = {
+			fileRef = 01FA7FFCFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A3FFF2B54C11CD283A = {
+			fileRef = 01FA7FFDFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A4FFF2B54C11CD283A = {
+			fileRef = 01FA7FFEFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A5FFF2B54C11CD283A = {
+			fileRef = 01FA7FFFFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A6FFF2B54C11CD283A = {
+			fileRef = 01FA8000FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A7FFF2B54C11CD283A = {
+			fileRef = 01FA8001FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA84A8FFF2B54C11CD283A = {
+			fileRef = 01FA8004FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84A9FFF2B54C11CD283A = {
+			fileRef = 01FA8006FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84AAFFF2B54C11CD283A = {
+			fileRef = 01FA8009FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84ABFFF2B54C11CD283A = {
+			fileRef = 01FA800BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84ACFFF2B54C11CD283A = {
+			fileRef = 01FA800DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84ADFFF2B54C11CD283A = {
+			fileRef = 01FA800FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84AEFFF2B54C11CD283A = {
+			fileRef = 01FA8011FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84AFFFF2B54C11CD283A = {
+			fileRef = 01FA8013FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B0FFF2B54C11CD283A = {
+			fileRef = 01FA8015FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B1FFF2B54C11CD283A = {
+			fileRef = 01FA8017FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B2FFF2B54C11CD283A = {
+			fileRef = 01FA8019FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B3FFF2B54C11CD283A = {
+			fileRef = 01FA801BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B4FFF2B54C11CD283A = {
+			fileRef = 01FA801DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B5FFF2B54C11CD283A = {
+			fileRef = 01FA801FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B6FFF2B54C11CD283A = {
+			fileRef = 01FA8021FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B7FFF2B54C11CD283A = {
+			fileRef = 01FA8023FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B8FFF2B54C11CD283A = {
+			fileRef = 01FA8027FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84B9FFF2B54C11CD283A = {
+			fileRef = 01FA8028FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84BAFFF2B54C11CD283A = {
+			fileRef = 01FA8029FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84BBFFF2B54C11CD283A = {
+			fileRef = 01FA802BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84BCFFF2B54C11CD283A = {
+			fileRef = 01FA802EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84BDFFF2B54C11CD283A = {
+			fileRef = 01FA8030FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84BEFFF2B54C11CD283A = {
+			fileRef = 01FA8035FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84BFFFF2B54C11CD283A = {
+			fileRef = 01FA8036FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C0FFF2B54C11CD283A = {
+			fileRef = 01FA8037FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C1FFF2B54C11CD283A = {
+			fileRef = 01FA803CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C2FFF2B54C11CD283A = {
+			fileRef = 01FA803EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C3FFF2B54C11CD283A = {
+			fileRef = 01FA8040FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C5FFF2B54C11CD283A = {
+			fileRef = 01FA8044FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C6FFF2B54C11CD283A = {
+			fileRef = 01FA8046FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C7FFF2B54C11CD283A = {
+			fileRef = 01FA8048FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C8FFF2B54C11CD283A = {
+			fileRef = 01FA804AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84C9FFF2B54C11CD283A = {
+			fileRef = 01FA804CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84CAFFF2B54C11CD283A = {
+			fileRef = 01FA804EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84CBFFF2B54C11CD283A = {
+			fileRef = 01FA8050FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84CCFFF2B54C11CD283A = {
+			fileRef = 01FA8052FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84CEFFF2B54C11CD283A = {
+			fileRef = 01FA8056FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84CFFFF2B54C11CD283A = {
+			fileRef = 01FA8058FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D0FFF2B54C11CD283A = {
+			fileRef = 01FA805AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D1FFF2B54C11CD283A = {
+			fileRef = 01FA805CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D2FFF2B54C11CD283A = {
+			fileRef = 01FA805EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D3FFF2B54C11CD283A = {
+			fileRef = 01FA8060FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D4FFF2B54C11CD283A = {
+			fileRef = 01FA8062FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D5FFF2B54C11CD283A = {
+			fileRef = 01FA8064FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D6FFF2B54C11CD283A = {
+			fileRef = 01FA8066FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D7FFF2B54C11CD283A = {
+			fileRef = 01FA8068FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D8FFF2B54C11CD283A = {
+			fileRef = 01FA806AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84D9FFF2B54C11CD283A = {
+			fileRef = 01FA806CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84DAFFF2B54C11CD283A = {
+			fileRef = 01FA806EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84DBFFF2B54C11CD283A = {
+			fileRef = 01FA8070FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84DCFFF2B54C11CD283A = {
+			fileRef = 01FA8072FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84DDFFF2B54C11CD283A = {
+			fileRef = 01FA8074FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84DEFFF2B54C11CD283A = {
+			fileRef = 01FA8076FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84DFFFF2B54C11CD283A = {
+			fileRef = 01FA8078FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E0FFF2B54C11CD283A = {
+			fileRef = 01FA807AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E1FFF2B54C11CD283A = {
+			fileRef = 01FA807BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E2FFF2B54C11CD283A = {
+			fileRef = 01FA807FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E3FFF2B54C11CD283A = {
+			fileRef = 01FA8082FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E4FFF2B54C11CD283A = {
+			fileRef = 01FA8084FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E5FFF2B54C11CD283A = {
+			fileRef = 01FA8086FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E6FFF2B54C11CD283A = {
+			fileRef = 01FA8088FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E7FFF2B54C11CD283A = {
+			fileRef = 01FA808AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E8FFF2B54C11CD283A = {
+			fileRef = 01FA808CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84E9FFF2B54C11CD283A = {
+			fileRef = 01FA808DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84EAFFF2B54C11CD283A = {
+			fileRef = 01FA808FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84EBFFF2B54C11CD283A = {
+			fileRef = 01FA8091FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84EDFFF2B54C11CD283A = {
+			fileRef = 01FA8097FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84EEFFF2B54C11CD283A = {
+			fileRef = 01FA8099FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84EFFFF2B54C11CD283A = {
+			fileRef = 01FA809AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F0FFF2B54C11CD283A = {
+			fileRef = 01FA809BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F2FFF2B54C11CD283A = {
+			fileRef = 01FA809FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F3FFF2B54C11CD283A = {
+			fileRef = 01FA80A1FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F4FFF2B54C11CD283A = {
+			fileRef = 01FA80A3FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F5FFF2B54C11CD283A = {
+			fileRef = 01FA80A5FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F6FFF2B54C11CD283A = {
+			fileRef = 01FA80A6FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F7FFF2B54C11CD283A = {
+			fileRef = 01FA80A8FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F8FFF2B54C11CD283A = {
+			fileRef = 01FA80ADFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84F9FFF2B54C11CD283A = {
+			fileRef = 01FA80AFFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84FAFFF2B54C11CD283A = {
+			fileRef = 01FA80B1FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84FBFFF2B54C11CD283A = {
+			fileRef = 01FA80B4FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84FCFFF2B54C11CD283A = {
+			fileRef = 01FA80B5FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84FDFFF2B54C11CD283A = {
+			fileRef = 01FA80B7FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84FEFFF2B54C11CD283A = {
+			fileRef = 01FA80BCFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA84FFFFF2B54C11CD283A = {
+			fileRef = 01FA80BFFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8517FFF2B54C11CD283A = {
+			fileRef = 01FA8136FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8518FFF2B54C11CD283A = {
+			fileRef = 01FA8139FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8519FFF2B54C11CD283A = {
+			fileRef = 01FA813AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA851AFFF2B54C11CD283A = {
+			fileRef = 01FA813BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA851BFFF2B54C11CD283A = {
+			fileRef = 01FA813CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA851CFFF2B54C11CD283A = {
+			fileRef = 01FA813DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA851DFFF2B54C11CD283A = {
+			fileRef = 01FA813EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA851EFFF2B54C11CD283A = {
+			fileRef = 01FA813FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA851FFFF2B54C11CD283A = {
+			fileRef = 01FA8140FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8520FFF2B54C11CD283A = {
+			fileRef = 01FA8141FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8521FFF2B54C11CD283A = {
+			fileRef = 01FA8142FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8522FFF2B54C11CD283A = {
+			fileRef = 01FA8143FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8523FFF2B54C11CD283A = {
+			fileRef = 01FA8144FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8524FFF2B54C11CD283A = {
+			fileRef = 01FA8145FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8525FFF2B54C11CD283A = {
+			fileRef = 01FA8146FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8526FFF2B54C11CD283A = {
+			fileRef = 01FA8147FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8527FFF2B54C11CD283A = {
+			fileRef = 01FA8148FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8528FFF2B54C11CD283A = {
+			fileRef = 01FA8149FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8529FFF2B54C11CD283A = {
+			fileRef = 01FA814AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA852AFFF2B54C11CD283A = {
+			fileRef = 01FA814BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA852BFFF2B54C11CD283A = {
+			fileRef = 01FA814CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA852CFFF2B54C11CD283A = {
+			fileRef = 01FA814DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA852DFFF2B54C11CD283A = {
+			fileRef = 01FA814EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA852EFFF2B54C11CD283A = {
+			fileRef = 01FA814FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA852FFFF2B54C11CD283A = {
+			fileRef = 01FA8150FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8530FFF2B54C11CD283A = {
+			fileRef = 01FA8151FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA8531FFF2B54C11CD283A = {
+			fileRef = 01FA8154FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8532FFF2B54C11CD283A = {
+			fileRef = 01FA8155FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8533FFF2B54C11CD283A = {
+			fileRef = 01FA818DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8534FFF2B54C11CD283A = {
+			fileRef = 01FA818EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8535FFF2B54C11CD283A = {
+			fileRef = 01FA818FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8536FFF2B54C11CD283A = {
+			fileRef = 01FA8190FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8537FFF2B54C11CD283A = {
+			fileRef = 01FA8191FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8538FFF2B54C11CD283A = {
+			fileRef = 01FA8192FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8539FFF2B54C11CD283A = {
+			fileRef = 01FA8193FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA853AFFF2B54C11CD283A = {
+			fileRef = 01FA8194FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA853BFFF2B54C11CD283A = {
+			fileRef = 01FA8195FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA853CFFF2B54C11CD283A = {
+			fileRef = 01FA8196FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA853DFFF2B54C11CD283A = {
+			fileRef = 01FA8197FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA853EFFF2B54C11CD283A = {
+			fileRef = 01FA8198FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA853FFFF2B54C11CD283A = {
+			fileRef = 01FA8199FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8540FFF2B54C11CD283A = {
+			fileRef = 01FA819AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8541FFF2B54C11CD283A = {
+			fileRef = 01FA819BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8546FFF2B54C11CD283A = {
+			fileRef = 01FA81A8FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8548FFF2B54C11CD283A = {
+			fileRef = 01FA81ABFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01FA8549FFF2B54C11CD283A = {
+			fileRef = 01FA81ADFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8583FFF2B54C11CD283A = {
+			fileRef = 01FA827BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8584FFF2B54C11CD283A = {
+			fileRef = 01FA827CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8585FFF2B54C11CD283A = {
+			fileRef = 01FA827DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8586FFF2B54C11CD283A = {
+			fileRef = 01FA827EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8587FFF2B54C11CD283A = {
+			fileRef = 01FA827FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8588FFF2B54C11CD283A = {
+			fileRef = 01FA8280FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8589FFF2B54C11CD283A = {
+			fileRef = 01FA8281FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA858AFFF2B54C11CD283A = {
+			fileRef = 01FA8282FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA858BFFF2B54C11CD283A = {
+			fileRef = 01FA8283FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA858CFFF2B54C11CD283A = {
+			fileRef = 01FA8284FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA858DFFF2B54C11CD283A = {
+			fileRef = 01FA8285FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA858EFFF2B54C11CD283A = {
+			fileRef = 01FA8286FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA858FFFF2B54C11CD283A = {
+			fileRef = 01FA8287FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8590FFF2B54C11CD283A = {
+			fileRef = 01FA8288FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8591FFF2B54C11CD283A = {
+			fileRef = 01FA8289FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8592FFF2B54C11CD283A = {
+			fileRef = 01FA828AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8593FFF2B54C11CD283A = {
+			fileRef = 01FA828BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8594FFF2B54C11CD283A = {
+			fileRef = 01FA828CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8595FFF2B54C11CD283A = {
+			fileRef = 01FA828DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8596FFF2B54C11CD283A = {
+			fileRef = 01FA828EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8597FFF2B54C11CD283A = {
+			fileRef = 01FA828FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8598FFF2B54C11CD283A = {
+			fileRef = 01FA8290FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8599FFF2B54C11CD283A = {
+			fileRef = 01FA8291FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA859AFFF2B54C11CD283A = {
+			fileRef = 01FA8292FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA859BFFF2B54C11CD283A = {
+			fileRef = 01FA8293FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA859DFFF2B54C11CD283A = {
+			fileRef = 01FA8295FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA859EFFF2B54C11CD283A = {
+			fileRef = 01FA8296FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8609FFF2B54C11CD283A = {
+			fileRef = 01FA80BDFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01FA86D9FFF2B54C11CD283A = {
+			fileRef = 01FA8005FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86DAFFF2B54C11CD283A = {
+			fileRef = 01FA8008FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86DBFFF2B54C11CD283A = {
+			fileRef = 01FA800AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86DCFFF2B54C11CD283A = {
+			fileRef = 01FA800CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86DDFFF2B54C11CD283A = {
+			fileRef = 01FA800EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86DEFFF2B54C11CD283A = {
+			fileRef = 01FA8010FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86DFFFF2B54C11CD283A = {
+			fileRef = 01FA8012FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E0FFF2B54C11CD283A = {
+			fileRef = 01FA8014FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E1FFF2B54C11CD283A = {
+			fileRef = 01FA8016FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E2FFF2B54C11CD283A = {
+			fileRef = 01FA8018FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E3FFF2B54C11CD283A = {
+			fileRef = 01FA801AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E4FFF2B54C11CD283A = {
+			fileRef = 01FA801CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E5FFF2B54C11CD283A = {
+			fileRef = 01FA801EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E6FFF2B54C11CD283A = {
+			fileRef = 01FA8020FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E7FFF2B54C11CD283A = {
+			fileRef = 01FA8022FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86E9FFF2B54C11CD283A = {
+			fileRef = 01FA802AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86EAFFF2B54C11CD283A = {
+			fileRef = 01FA802CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86EBFFF2B54C11CD283A = {
+			fileRef = 01FA802DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86ECFFF2B54C11CD283A = {
+			fileRef = 01FA802FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86EDFFF2B54C11CD283A = {
+			fileRef = 01FA8034FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86EFFFF2B54C11CD283A = {
+			fileRef = 01FA803BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F0FFF2B54C11CD283A = {
+			fileRef = 01FA803DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F1FFF2B54C11CD283A = {
+			fileRef = 01FA803FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F3FFF2B54C11CD283A = {
+			fileRef = 01FA8043FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F4FFF2B54C11CD283A = {
+			fileRef = 01FA8045FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F5FFF2B54C11CD283A = {
+			fileRef = 01FA8047FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F6FFF2B54C11CD283A = {
+			fileRef = 01FA8049FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F7FFF2B54C11CD283A = {
+			fileRef = 01FA804BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F8FFF2B54C11CD283A = {
+			fileRef = 01FA804DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86F9FFF2B54C11CD283A = {
+			fileRef = 01FA804FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86FAFFF2B54C11CD283A = {
+			fileRef = 01FA8051FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86FCFFF2B54C11CD283A = {
+			fileRef = 01FA8055FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86FDFFF2B54C11CD283A = {
+			fileRef = 01FA8057FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86FEFFF2B54C11CD283A = {
+			fileRef = 01FA8059FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA86FFFFF2B54C11CD283A = {
+			fileRef = 01FA805BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8700FFF2B54C11CD283A = {
+			fileRef = 01FA805DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8701FFF2B54C11CD283A = {
+			fileRef = 01FA805FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8702FFF2B54C11CD283A = {
+			fileRef = 01FA8061FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8703FFF2B54C11CD283A = {
+			fileRef = 01FA8063FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8704FFF2B54C11CD283A = {
+			fileRef = 01FA8065FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8705FFF2B54C11CD283A = {
+			fileRef = 01FA8067FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8706FFF2B54C11CD283A = {
+			fileRef = 01FA8069FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8707FFF2B54C11CD283A = {
+			fileRef = 01FA806BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8708FFF2B54C11CD283A = {
+			fileRef = 01FA806DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8709FFF2B54C11CD283A = {
+			fileRef = 01FA806FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA870AFFF2B54C11CD283A = {
+			fileRef = 01FA8071FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA870BFFF2B54C11CD283A = {
+			fileRef = 01FA8073FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA870CFFF2B54C11CD283A = {
+			fileRef = 01FA8075FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA870DFFF2B54C11CD283A = {
+			fileRef = 01FA8077FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA870EFFF2B54C11CD283A = {
+			fileRef = 01FA8079FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA870FFFF2B54C11CD283A = {
+			fileRef = 01FA807EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8710FFF2B54C11CD283A = {
+			fileRef = 01FA8080FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8711FFF2B54C11CD283A = {
+			fileRef = 01FA8081FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8712FFF2B54C11CD283A = {
+			fileRef = 01FA8083FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8713FFF2B54C11CD283A = {
+			fileRef = 01FA8085FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8714FFF2B54C11CD283A = {
+			fileRef = 01FA8087FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8715FFF2B54C11CD283A = {
+			fileRef = 01FA8089FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8716FFF2B54C11CD283A = {
+			fileRef = 01FA808BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8717FFF2B54C11CD283A = {
+			fileRef = 01FA808EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8718FFF2B54C11CD283A = {
+			fileRef = 01FA8090FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA871BFFF2B54C11CD283A = {
+			fileRef = 01FA8096FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA871CFFF2B54C11CD283A = {
+			fileRef = 01FA8098FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA871EFFF2B54C11CD283A = {
+			fileRef = 01FA809EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA871FFFF2B54C11CD283A = {
+			fileRef = 01FA80A0FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8720FFF2B54C11CD283A = {
+			fileRef = 01FA80A2FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8721FFF2B54C11CD283A = {
+			fileRef = 01FA80A4FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8722FFF2B54C11CD283A = {
+			fileRef = 01FA80A7FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8724FFF2B54C11CD283A = {
+			fileRef = 01FA80ACFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8725FFF2B54C11CD283A = {
+			fileRef = 01FA80AEFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8726FFF2B54C11CD283A = {
+			fileRef = 01FA80B0FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8727FFF2B54C11CD283A = {
+			fileRef = 01FA80B2FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8728FFF2B54C11CD283A = {
+			fileRef = 01FA80B3FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8729FFF2B54C11CD283A = {
+			fileRef = 01FA80B6FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA872AFFF2B54C11CD283A = {
+			fileRef = 01FA80BBFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA872BFFF2B54C11CD283A = {
+			fileRef = 01FA80BEFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA872CFFF2B54C11CD283A = {
+			fileRef = 01FA80C0FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA872DFFF2B54C11CD283A = {
+			fileRef = 01FA80C1FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA872EFFF2B54C11CD283A = {
+			fileRef = 01FA80C2FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA872FFFF2B54C11CD283A = {
+			fileRef = 01FA80C3FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8730FFF2B54C11CD283A = {
+			fileRef = 01FA80C4FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA874FFFF2B54C11CD283A = {
+			fileRef = 01FA8127FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8750FFF2B54C11CD283A = {
+			fileRef = 01FA8128FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8751FFF2B54C11CD283A = {
+			fileRef = 01FA8129FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8752FFF2B54C11CD283A = {
+			fileRef = 01FA812AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8753FFF2B54C11CD283A = {
+			fileRef = 01FA812BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8754FFF2B54C11CD283A = {
+			fileRef = 01FA812CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8755FFF2B54C11CD283A = {
+			fileRef = 01FA812DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8756FFF2B54C11CD283A = {
+			fileRef = 01FA812EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8757FFF2B54C11CD283A = {
+			fileRef = 01FA812FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8758FFF2B54C11CD283A = {
+			fileRef = 01FA8130FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8759FFF2B54C11CD283A = {
+			fileRef = 01FA8131FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA875AFFF2B54C11CD283A = {
+			fileRef = 01FA8132FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA875BFFF2B54C11CD283A = {
+			fileRef = 01FA8134FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA875CFFF2B54C11CD283A = {
+			fileRef = 01FA8135FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA875DFFF2B54C11CD283A = {
+			fileRef = 01FA8137FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA875FFFF2B54C11CD283A = {
+			fileRef = 01FA8157FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8760FFF2B54C11CD283A = {
+			fileRef = 01FA8158FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8761FFF2B54C11CD283A = {
+			fileRef = 01FA8159FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8762FFF2B54C11CD283A = {
+			fileRef = 01FA815AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8763FFF2B54C11CD283A = {
+			fileRef = 01FA815BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8764FFF2B54C11CD283A = {
+			fileRef = 01FA815CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8765FFF2B54C11CD283A = {
+			fileRef = 01FA815DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8766FFF2B54C11CD283A = {
+			fileRef = 01FA815EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8767FFF2B54C11CD283A = {
+			fileRef = 01FA815FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8769FFF2B54C11CD283A = {
+			fileRef = 01FA8161FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA876AFFF2B54C11CD283A = {
+			fileRef = 01FA8162FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA876BFFF2B54C11CD283A = {
+			fileRef = 01FA8163FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA876CFFF2B54C11CD283A = {
+			fileRef = 01FA8164FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA876DFFF2B54C11CD283A = {
+			fileRef = 01FA8165FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA876EFFF2B54C11CD283A = {
+			fileRef = 01FA8166FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA876FFFF2B54C11CD283A = {
+			fileRef = 01FA8167FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8770FFF2B54C11CD283A = {
+			fileRef = 01FA817DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8771FFF2B54C11CD283A = {
+			fileRef = 01FA817EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8772FFF2B54C11CD283A = {
+			fileRef = 01FA817FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8773FFF2B54C11CD283A = {
+			fileRef = 01FA8180FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8774FFF2B54C11CD283A = {
+			fileRef = 01FA8181FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8775FFF2B54C11CD283A = {
+			fileRef = 01FA8182FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8776FFF2B54C11CD283A = {
+			fileRef = 01FA8183FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8777FFF2B54C11CD283A = {
+			fileRef = 01FA8184FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8778FFF2B54C11CD283A = {
+			fileRef = 01FA8185FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8779FFF2B54C11CD283A = {
+			fileRef = 01FA8186FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA877AFFF2B54C11CD283A = {
+			fileRef = 01FA8187FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA877BFFF2B54C11CD283A = {
+			fileRef = 01FA8188FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA877CFFF2B54C11CD283A = {
+			fileRef = 01FA8189FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA877DFFF2B54C11CD283A = {
+			fileRef = 01FA818AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA877EFFF2B54C11CD283A = {
+			fileRef = 01FA818BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8783FFF2B54C11CD283A = {
+			fileRef = 01FA81A7FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8786FFF2B54C11CD283A = {
+			fileRef = 01FA81AEFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8787FFF2B54C11CD283A = {
+			fileRef = 01FA81AFFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87C9FFF2B54C11CD283A = {
+			fileRef = 01FA8265FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87CAFFF2B54C11CD283A = {
+			fileRef = 01FA8266FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87CBFFF2B54C11CD283A = {
+			fileRef = 01FA8267FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87CCFFF2B54C11CD283A = {
+			fileRef = 01FA8268FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87CDFFF2B54C11CD283A = {
+			fileRef = 01FA8269FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87CEFFF2B54C11CD283A = {
+			fileRef = 01FA826AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87CFFFF2B54C11CD283A = {
+			fileRef = 01FA826BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D0FFF2B54C11CD283A = {
+			fileRef = 01FA826CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D1FFF2B54C11CD283A = {
+			fileRef = 01FA826DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D2FFF2B54C11CD283A = {
+			fileRef = 01FA826EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D3FFF2B54C11CD283A = {
+			fileRef = 01FA826FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D4FFF2B54C11CD283A = {
+			fileRef = 01FA8270FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D5FFF2B54C11CD283A = {
+			fileRef = 01FA8271FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D6FFF2B54C11CD283A = {
+			fileRef = 01FA8272FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D7FFF2B54C11CD283A = {
+			fileRef = 01FA8273FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D8FFF2B54C11CD283A = {
+			fileRef = 01FA8274FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87D9FFF2B54C11CD283A = {
+			fileRef = 01FA8275FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87DAFFF2B54C11CD283A = {
+			fileRef = 01FA8276FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87F7FFF2B54C11CD283A = {
+			fileRef = 01FA82B6FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87FEFFF2B54C11CD283A = {
+			fileRef = 01FA82BDFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA87FFFFF2B54C11CD283A = {
+			fileRef = 01FA82BEFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA88F0FFF2B96911CD283A = {
+			buildArgumentsString = "-f SecurityServer/Makefile $ACTION \"SYMROOT=$(SYMROOT)\" \"SRCROOT=$(SRCROOT)\"";
+			buildPhases = (
+			);
+			buildSettings = {
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = "SecurityServer MIG RPC";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = "SecurityServer MIG RPC";
+			productName = "SecurityServer MIG RPC";
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 1;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		01FA88F8FFF2BBEB11CD283A = {
+			isa = PBXTargetDependency;
+			target = 01FA88F9FFF2BBEB11CD283A;
+		};
+		01FA88F9FFF2BBEB11CD283A = {
+			buildArgumentsString = "-f SecurityServer/Makefile.startup $ALL_SETTINGS $ACTION";
+			buildPhases = (
+			);
+			buildSettings = {
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = "Install Startup Arrangements";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = "Install Startup Arrangements";
+			productName = "Install Startup Arrangements";
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 1;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		01FA88FBFFF2BC5611CD283A = {
+			isa = PBXExecutableFileReference;
+			path = SecurityServer;
+			refType = 3;
+		};
+		01FA88FCFFF2BC5611CD283A = {
+			buildPhases = (
+				01FA88FDFFF2BC5611CD283A,
+				01FA88FEFFF2BC5611CD283A,
+				01FA88FFFFF2BC5611CD283A,
+				01FA8900FFF2BC5611CD283A,
+			);
+			buildSettings = {
+				INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
+				LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/2.95.2;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "-DDatabase=XDatabase";
+				OTHER_LDFLAGS = "-twolevel_namespace -lSecurityAgentClient";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = SecurityServer;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(SRCROOT)/SecurityServer/SecurityServer.order\" -e start";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				1B40D2E3FFF9716411CD283A,
+			);
+			isa = PBXToolTarget;
+			name = SecurityServer;
+			productInstallPath = "$(SYSTEM_CORE_SERVICES_DIR)";
+			productName = SecurityServer;
+			productReference = 01FA88FBFFF2BC5611CD283A;
+			shouldUseHeadermap = 1;
+		};
+		01FA88FDFFF2BC5611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				125E85AFFFF3D51B11CD283A,
+				125E85B0FFF3D51B11CD283A,
+				125E85B1FFF3D51B11CD283A,
+				125E85B2FFF3D51B11CD283A,
+				125E85B3FFF3D51B11CD283A,
+				125E85B9FFF3D54811CD283A,
+				125E85BAFFF3D54811CD283A,
+				125E85BBFFF3D54811CD283A,
+				125E85BFFFF3D5ED11CD283A,
+				125E85C0FFF3D5ED11CD283A,
+				125E85C1FFF3D5ED11CD283A,
+				125E85C2FFF3D5ED11CD283A,
+				125E85C3FFF3D5ED11CD283A,
+				125E85C4FFF3D5ED11CD283A,
+				125E85C5FFF3D5ED11CD283A,
+				125E85C6FFF3D5ED11CD283A,
+				125E85C7FFF3D5ED11CD283A,
+				125E85EAFFF3D8B711CD283A,
+				125E85EBFFF3D8B711CD283A,
+				125E85ECFFF3D8B711CD283A,
+				125E85EEFFF3D8B711CD283A,
+				125E85F0FFF3D8B711CD283A,
+				125E85F1FFF3D8B711CD283A,
+				125E85F2FFF3D8B711CD283A,
+				125E85F3FFF3D8B711CD283A,
+				125E8605FFF3DAEF11CD283A,
+				4EB202E10058588E7F000001,
+				568640ED00E23FD90DCD28E8,
+				32615BB100E3B46A05CD296C,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		01FA88FEFFF2BC5611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				125E85B4FFF3D51B11CD283A,
+				125E85B5FFF3D51B11CD283A,
+				125E85B6FFF3D51B11CD283A,
+				125E85B7FFF3D51B11CD283A,
+				125E85B8FFF3D51B11CD283A,
+				125E85BCFFF3D54811CD283A,
+				125E85BDFFF3D54811CD283A,
+				125E85BEFFF3D54811CD283A,
+				125E85C8FFF3D5ED11CD283A,
+				125E85C9FFF3D5ED11CD283A,
+				125E85CAFFF3D5ED11CD283A,
+				125E85CCFFF3D5ED11CD283A,
+				125E85CDFFF3D5ED11CD283A,
+				125E85CEFFF3D5ED11CD283A,
+				125E85CFFFF3D5ED11CD283A,
+				125E85D0FFF3D5ED11CD283A,
+				125E85D1FFF3D5ED11CD283A,
+				125E85FAFFF3D8B711CD283A,
+				125E85FBFFF3D8B711CD283A,
+				125E85FDFFF3D8B711CD283A,
+				125E85FFFFF3D8B711CD283A,
+				125E8600FFF3D8B711CD283A,
+				125E8601FFF3D8B711CD283A,
+				125E8602FFF3D8B711CD283A,
+				125E8603FFF3D8B711CD283A,
+				568640EE00E23FD90DCD28E8,
+				32615BB300E3B4A205CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		01FA88FFFFF2BC5611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				1A23E787009758847F000001,
+				1BA451B20097605B7F000001,
+				3949557400CC6A4511CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		01FA8900FFF2BC5611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		01FA8901FFF2BCA811CD283A = {
+			isa = PBXExecutableFileReference;
+			path = AuthorizationTrampoline;
+			refType = 3;
+		};
+		01FA8902FFF2BCA811CD283A = {
+			isa = PBXTargetDependency;
+			target = 01FA88FCFFF2BC5611CD283A;
+		};
+		01FA8903FFF2BCA811CD283A = {
+			isa = PBXTargetDependency;
+			target = 01FA8904FFF2BCA811CD283A;
+		};
+		01FA8904FFF2BCA811CD283A = {
+			buildPhases = (
+				01FA8905FFF2BCA811CD283A,
+				01FA8906FFF2BCA811CD283A,
+				01FA8908FFF2BCA811CD283A,
+				01FA890AFFF2BCA811CD283A,
+			);
+			buildSettings = {
+				INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
+				LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/2.95.2;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "$(AUX_CFLAGS)";
+				OTHER_LDFLAGS = "-twolevel_namespace -lstdc++";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AuthorizationTrampoline;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+			);
+			isa = PBXToolTarget;
+			name = AuthorizationTrampoline;
+			productInstallPath = "$(SYSTEM_CORE_SERVICES_DIR)";
+			productName = AuthorizationTrampoline;
+			productReference = 01FA8901FFF2BCA811CD283A;
+			shouldUseHeadermap = 1;
+		};
+		01FA8905FFF2BCA811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		01FA8906FFF2BCA811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01FA8907FFF2BCA811CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		01FA8907FFF2BCA811CD283A = {
+			fileRef = 01FA81ACFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8908FFF2BCA811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				1A23E788009758847F000001,
+				1BA451B30097605B7F000001,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		01FA890AFFF2BCA811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		01FA890DFFF2BD9911CD283A = {
+			children = (
+				01FA890FFFF2BE3511CD283A,
+				01FA8910FFF2BE3511CD283A,
+				01FA8911FFF2BE3511CD283A,
+				01FA8912FFF2BE3511CD283A,
+				01FA8913FFF2BE3511CD283A,
+				01FA8914FFF2BE3511CD283A,
+				01FA8915FFF2BE3511CD283A,
+				01FA8916FFF2BE3511CD283A,
+				01FA8917FFF2BE3511CD283A,
+				01FA8918FFF2BE3511CD283A,
+				01FA8919FFF2BE3511CD283A,
+				01FA891AFFF2BE3511CD283A,
+				01FA891BFFF2BE3511CD283A,
+				01FA891CFFF2BE3511CD283A,
+				0177F2CCFFFAA2D311CD283A,
+				07A0F690005DAEE111CD283A,
+			);
+			isa = PBXGroup;
+			path = derived_src;
+			refType = 3;
+		};
+		01FA890EFFF2BD9911CD283A = {
+			children = (
+				01FA891FFFF2BE3511CD283A,
+				01FA8920FFF2BE3511CD283A,
+				01FA8926FFF2BE3511CD283A,
+			);
+			isa = PBXGroup;
+			name = "derived headers";
+			path = include;
+			refType = 3;
+		};
+		01FA890FFFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = ACabstractsession.cpp;
+			refType = 4;
+		};
+		01FA8910FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = CLabstractsession.cpp;
+			refType = 4;
+		};
+		01FA8911FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = CSPabstractsession.cpp;
+			refType = 4;
+		};
+		01FA8912FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = cssmexports.gen;
+			refType = 4;
+		};
+		01FA8913FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = DLabstractsession.cpp;
+			refType = 4;
+		};
+		01FA8914FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = errorcodes.gen;
+			refType = 4;
+		};
+		01FA8915FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = funcnames.gen;
+			refType = 4;
+		};
+		01FA8916FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = generator.rpt;
+			refType = 4;
+		};
+		01FA8917FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = secagentServer.cpp;
+			refType = 4;
+		};
+		01FA8918FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = secagentUser.cpp;
+			refType = 4;
+		};
+		01FA8919FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = TPabstractsession.cpp;
+			refType = 4;
+		};
+		01FA891AFFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = transition.gen;
+			refType = 4;
+		};
+		01FA891BFFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = ucspServer.cpp;
+			refType = 4;
+		};
+		01FA891CFFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = ucspUser.cpp;
+			refType = 4;
+		};
+		01FA891FFFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = secagent.h;
+			refType = 4;
+		};
+		01FA8920FFF2BE3511CD283A = {
+			children = (
+				01FA8921FFF2BE3511CD283A,
+				01FA8922FFF2BE3511CD283A,
+				01FA8923FFF2BE3511CD283A,
+				01FA8924FFF2BE3511CD283A,
+				01FA8925FFF2BE3511CD283A,
+			);
+			isa = PBXGroup;
+			path = Security;
+			refType = 4;
+		};
+		01FA8921FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = ACabstractsession.h;
+			refType = 4;
+		};
+		01FA8922FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = CLabstractsession.h;
+			refType = 4;
+		};
+		01FA8923FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = CSPabstractsession.h;
+			refType = 4;
+		};
+		01FA8924FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = DLabstractsession.h;
+			refType = 4;
+		};
+		01FA8925FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = TPabstractsession.h;
+			refType = 4;
+		};
+		01FA8926FFF2BE3511CD283A = {
+			isa = PBXFileReference;
+			path = ucsp.h;
+			refType = 4;
+		};
+		01FA8929FFF2BE3511CD283A = {
+			fileRef = 01FA8921FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA892AFFF2BE3511CD283A = {
+			fileRef = 01FA8922FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA892BFFF2BE3511CD283A = {
+			fileRef = 01FA8923FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA892CFFF2BE3511CD283A = {
+			fileRef = 01FA8924FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA892DFFF2BE3511CD283A = {
+			fileRef = 01FA8925FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		01FA8930FFF2BE3511CD283A = {
+			fileRef = 01FA890FFFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8931FFF2BE3511CD283A = {
+			fileRef = 01FA8910FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8932FFF2BE3511CD283A = {
+			fileRef = 01FA8911FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8933FFF2BE3511CD283A = {
+			fileRef = 01FA8913FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		01FA8936FFF2BE3511CD283A = {
+			fileRef = 01FA8919FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+//010
+//011
+//012
+//013
+//014
+//020
+//021
+//022
+//023
+//024
+		025C84BB0027360A11CD296C = {
+			isa = PBXFileReference;
+			path = threading_internal.h;
+			refType = 4;
+		};
+		025C84BC0027360A11CD296C = {
+			fileRef = 025C84BB0027360A11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+//020
+//021
+//022
+//023
+//024
+//030
+//031
+//032
+//033
+//034
+		030701E1FFF95F6F11CD283A = {
+			isa = PBXFileReference;
+			path = Security.exp;
+			refType = 4;
+		};
+		030701E3FFF96F8511CD283A = {
+			isa = PBXLibraryReference;
+			path = libSecurityAgentClient.a;
+			refType = 3;
+		};
+		030701E4FFF96F8511CD283A = {
+			buildPhases = (
+				030701E5FFF96F8511CD283A,
+				030701E6FFF96F8511CD283A,
+				030701E7FFF96F8511CD283A,
+				030701E8FFF96F8511CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				INSTALL_PATH = /usr/local/lib;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "-DNOSA -DAGENTPATH=\\\\\\\"/System/Library/CoreServices/SecurityAgent.app\\\\\\\" -DAGENTNAME=\\\\\\\"SecurityAgent\\\\\\\"";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libSecurityAgentClient.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				1B40D2E4FFF9716411CD283A,
+			);
+			isa = PBXLibraryTarget;
+			name = "SecurityAgent Client";
+			productInstallPath = /usr/local/lib;
+			productName = "SecurityAgent Client";
+			productReference = 030701E3FFF96F8511CD283A;
+			shouldUseHeadermap = 1;
+		};
+		030701E5FFF96F8511CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		030701E6FFF96F8511CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				030701E9FFF96F9911CD283A,
+				030701EAFFF96F9911CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		030701E7FFF96F8511CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		030701E8FFF96F8511CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		030701E9FFF96F9911CD283A = {
+			fileRef = 01FA821CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		030701EAFFF96F9911CD283A = {
+			fileRef = 01FA8918FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		034768DDFF38A45A11DB9C8B = {
+			children = (
+				1BA451B10097605B7F000001,
+				01FA88FBFFF2BC5611CD283A,
+				01FA8901FFF2BCA811CD283A,
+				125E85D4FFF3D67D11CD283A,
+				030701E3FFF96F8511CD283A,
+				325EAA3100D6B2BE05CD296C,
+				325EAA3200D6B2BE05CD296C,
+			);
+			isa = PBXGroup;
+			name = Products;
+			path = "";
+			refType = 4;
+		};
+		034768DEFF38A45A11DB9C8B = {
+			isa = PBXFrameworkReference;
+			name = Security.framework;
+			path = /System/Library/Frameworks/Security.framework;
+			refType = 0;
+		};
+		039FF1DB00724BE07F000001 = {
+			children = (
+				039FF1DC00724C3A7F000001,
+				039FF1E200724FFC7F000001,
+				0149035400A9DC487F000001,
+				0149035500A9DC487F000001,
+				07A0F672005DAEE111CD283A,
+				07A0F673005DAEE111CD283A,
+				209FCB5000A739657F000001,
+				209FCB4E00A738117F000001,
+				59375E6B00A848827F000001,
+				0149035600A9DC487F000001,
+				0149035700A9DC487F000001,
+				039FF1E000724E6E7F000001,
+				039FF1DE00724E1A7F000001,
+				0149036400A9DF347F000001,
+				2C5247F0007A39B47F000001,
+				2C5247F1007A39B47F000001,
+				52BFC307007A6A1B7F000001,
+				52BFC308007A6A1B7F000001,
+				4A4C7674007A52DC7F000001,
+				4A4C7675007A52DC7F000001,
+				59375E7100A849BB7F000001,
+				0149035800A9DC487F000001,
+				0149035900A9DC487F000001,
+				0149035A00A9DC487F000001,
+				0149035B00A9DC487F000001,
+				07A0F675005DAEE111CD283A,
+				07A0F674005DAEE111CD283A,
+			);
+			isa = PBXGroup;
+			name = MiscCSPAlgs;
+			refType = 4;
+		};
+		039FF1DC00724C3A7F000001 = {
+			isa = PBXFileReference;
+			name = desContext.cpp;
+			path = MiscCSPAlgs/desContext.cpp;
+			refType = 4;
+		};
+		039FF1DD00724C3A7F000001 = {
+			fileRef = 039FF1DC00724C3A7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		039FF1DE00724E1A7F000001 = {
+			isa = PBXFileReference;
+			name = miscAlgFactory.h;
+			path = MiscCSPAlgs/miscAlgFactory.h;
+			refType = 4;
+		};
+		039FF1DF00724E1A7F000001 = {
+			fileRef = 039FF1DE00724E1A7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		039FF1E000724E6E7F000001 = {
+			isa = PBXFileReference;
+			name = miscAlgFactory.cpp;
+			path = MiscCSPAlgs/miscAlgFactory.cpp;
+			refType = 4;
+		};
+		039FF1E100724E6E7F000001 = {
+			fileRef = 039FF1E000724E6E7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		039FF1E200724FFC7F000001 = {
+			isa = PBXFileReference;
+			name = desContext.h;
+			path = AppleCSP/MiscCSPAlgs/desContext.h;
+			refType = 2;
+		};
+		039FF1E300724FFC7F000001 = {
+			fileRef = 039FF1E200724FFC7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		03B76D49FFF2D31811CD283A = {
+			fileRef = 01FA823CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		03B76D4AFFF2D35D11CD283A = {
+			fileRef = 01FA8227FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		03B76D4BFFF2D35D11CD283A = {
+			fileRef = 01FA8229FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		03B76D4CFFF2D35D11CD283A = {
+			fileRef = 01FA821FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		03B76D4DFFF2D35D11CD283A = {
+			fileRef = 01FA8926FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		03B76D4EFFF2D35D11CD283A = {
+			fileRef = 01FA8226FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		03B76D4FFFF2D35D11CD283A = {
+			fileRef = 01FA8228FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		03B76D51FFF2D43011CD283A = {
+			fileRef = 01FA891CFFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+//030
+//031
+//032
+//033
+//034
+//050
+//051
+//052
+//053
+//054
+		05855484FFF2DA1E11CD283A = {
+			isa = PBXTargetDependency;
+			target = 01FA88F0FFF2B96911CD283A;
+		};
+//050
+//051
+//052
+//053
+//054
+//070
+//071
+//072
+//073
+//074
+		07A0F5EA005DAEE111CD283A = {
+			children = (
+				256C38AB0094AE067F000001,
+				57FCEE8D007B8B3D7F000001,
+				2C5247EA007A39B47F000001,
+				039FF1DB00724BE07F000001,
+				07A0F5EB005DAEE111CD283A,
+				07A0F5F4005DAEE111CD283A,
+				07A0F606005DAEE111CD283A,
+				07A0F66E005DAEE111CD283A,
+				07A0F680005DAEE111CD283A,
+				07A0F685005DAEE111CD283A,
+				325EAA3700D6B47405CD296C,
+			);
+			isa = PBXGroup;
+			path = AppleCSP;
+			refType = 4;
+		};
+		07A0F5EB005DAEE111CD283A = {
+			children = (
+				07A0F5EC005DAEE111CD283A,
+				07A0F5EE005DAEE111CD283A,
+				4AC94A7E0084C0977F000001,
+				07A0F5EF005DAEE111CD283A,
+				07A0F5F0005DAEE111CD283A,
+				07A0F5F1005DAEE111CD283A,
+				07A0F5F2005DAEE111CD283A,
+				07A0F5F3005DAEE111CD283A,
+				4AC94A7C0084BE397F000001,
+			);
+			isa = PBXGroup;
+			path = AES;
+			refType = 4;
+		};
+		07A0F5EC005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = aescsp.cpp;
+			refType = 4;
+		};
+		07A0F5EE005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = aescspi.h;
+			refType = 4;
+		};
+		07A0F5EF005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = "boxes-ref.h";
+			refType = 4;
+		};
+		07A0F5F0005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = "rijndael-alg-ref.c";
+			refType = 4;
+		};
+		07A0F5F1005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = "rijndael-alg-ref.h";
+			refType = 4;
+		};
+		07A0F5F2005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = rijndaelApi.c;
+			refType = 4;
+		};
+		07A0F5F3005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = rijndaelApi.h;
+			refType = 4;
+		};
+		07A0F5F4005DAEE111CD283A = {
+			children = (
+				07A0F5F5005DAEE111CD283A,
+				07A0F5F6005DAEE111CD283A,
+				07A0F5F7005DAEE111CD283A,
+				07A0F5F8005DAEE111CD283A,
+				07A0F5F9005DAEE111CD283A,
+				07A0F5FA005DAEE111CD283A,
+				07A0F5FB005DAEE111CD283A,
+				07A0F5FC005DAEE111CD283A,
+				07A0F5FD005DAEE111CD283A,
+				07A0F5FE005DAEE111CD283A,
+				07A0F5FF005DAEE111CD283A,
+				07A0F600005DAEE111CD283A,
+				07A0F601005DAEE111CD283A,
+				1691956900947FD37F000001,
+				127F63C50098D55A7F000001,
+				07A0F602005DAEE111CD283A,
+				07A0F603005DAEE111CD283A,
+				1691956B009480BC7F000001,
+				07A0F604005DAEE111CD283A,
+				07A0F605005DAEE111CD283A,
+				1691956D009485A47F000001,
+				1691956F009486767F000001,
+				48855E830095DC957F000001,
+				48855E850095DD697F000001,
+			);
+			isa = PBXGroup;
+			path = AppleCSP;
+			refType = 4;
+		};
+		07A0F5F5005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleCSP.cpp;
+			refType = 4;
+		};
+		07A0F5F6005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleCSP.h;
+			refType = 4;
+		};
+		07A0F5F7005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleCSPContext.cpp;
+			refType = 4;
+		};
+		07A0F5F8005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleCSPContext.h;
+			refType = 4;
+		};
+		07A0F5F9005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleCSPSession.h;
+			refType = 4;
+		};
+		07A0F5FA005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleCSPUtils.cpp;
+			refType = 4;
+		};
+		07A0F5FB005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleCSPUtils.h;
+			refType = 4;
+		};
+		07A0F5FC005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = BinaryKey.h;
+			refType = 4;
+		};
+		07A0F5FD005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = BlockCryptor.cpp;
+			refType = 4;
+		};
+		07A0F5FE005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = BlockCryptor.h;
+			refType = 4;
+		};
+		07A0F5FF005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = cspdebugging.c;
+			refType = 4;
+		};
+		07A0F600005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = cspdebugging.h;
+			refType = 4;
+		};
+		07A0F601005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = deriveKey.cpp;
+			refType = 4;
+		};
+		07A0F602005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = pkcs_7_8.cpp;
+			refType = 4;
+		};
+		07A0F603005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = pkcs_7_8.h;
+			refType = 4;
+		};
+		07A0F604005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = wrapKey.cpp;
+			refType = 4;
+		};
+		07A0F605005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = wrapKeyCms.cpp;
+			refType = 4;
+		};
+		07A0F606005DAEE111CD283A = {
+			children = (
+				07A0F607005DAEE111CD283A,
+				07A0F608005DAEE111CD283A,
+				07A0F609005DAEE111CD283A,
+				07A0F60A005DAEE111CD283A,
+				07A0F60B005DAEE111CD283A,
+				07A0F60C005DAEE111CD283A,
+				07A0F60D005DAEE111CD283A,
+				07A0F60E005DAEE111CD283A,
+				07A0F60F005DAEE111CD283A,
+				07A0F610005DAEE111CD283A,
+				07A0F611005DAEE111CD283A,
+				07A0F612005DAEE111CD283A,
+			);
+			isa = PBXGroup;
+			path = BSafeCSP;
+			refType = 4;
+		};
+		07A0F607005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = algmaker.cpp;
+			refType = 4;
+		};
+		07A0F608005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsafeAsymmetric.cpp;
+			refType = 4;
+		};
+		07A0F609005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsafeContext.cpp;
+			refType = 4;
+		};
+		07A0F60A005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsafecsp.h;
+			refType = 4;
+		};
+		07A0F60B005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsafecspi.h;
+			refType = 4;
+		};
+		07A0F60C005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsafeKeyGen.cpp;
+			refType = 4;
+		};
+		07A0F60D005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsafePKCS1.cpp;
+			refType = 4;
+		};
+		07A0F60E005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsafePKCS1.h;
+			refType = 4;
+		};
+		07A0F60F005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsafeSymmetric.cpp;
+			refType = 4;
+		};
+		07A0F610005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = bsobjects.h;
+			refType = 4;
+		};
+		07A0F611005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = memory.cpp;
+			refType = 4;
+		};
+		07A0F612005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = miscalgorithms.cpp;
+			refType = 4;
+		};
+		07A0F66E005DAEE111CD283A = {
+			children = (
+				07A0F66F005DAEE111CD283A,
+				07A0F670005DAEE111CD283A,
+				07A0F671005DAEE111CD283A,
+				07A0F676005DAEE111CD283A,
+				07A0F677005DAEE111CD283A,
+				07A0F678005DAEE111CD283A,
+				07A0F679005DAEE111CD283A,
+				07A0F67A005DAEE111CD283A,
+				07A0F67B005DAEE111CD283A,
+				07A0F67E005DAEE111CD283A,
+				07A0F67F005DAEE111CD283A,
+				63B97E6600603F0A7F000001,
+			);
+			isa = PBXGroup;
+			path = CryptKitCSP;
+			refType = 4;
+		};
+		07A0F66F005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = cryptkitcsp.cpp;
+			refType = 4;
+		};
+		07A0F670005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = cryptkitcsp.h;
+			refType = 4;
+		};
+		07A0F671005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CryptKitSpace.h;
+			refType = 4;
+		};
+		07A0F672005DAEE111CD283A = {
+			isa = PBXFileReference;
+			name = DigestContext.cpp;
+			path = AppleCSP/MiscCSPAlgs/DigestContext.cpp;
+			refType = 2;
+		};
+		07A0F673005DAEE111CD283A = {
+			isa = PBXFileReference;
+			name = DigestContext.h;
+			path = AppleCSP/MiscCSPAlgs/DigestContext.h;
+			refType = 2;
+		};
+		07A0F674005DAEE111CD283A = {
+			isa = PBXFileReference;
+			name = SHA1_MD5_Object.cpp;
+			path = MiscCSPAlgs/SHA1_MD5_Object.cpp;
+			refType = 4;
+		};
+		07A0F675005DAEE111CD283A = {
+			isa = PBXFileReference;
+			name = SHA1_MD5_Object.h;
+			path = MiscCSPAlgs/SHA1_MD5_Object.h;
+			refType = 4;
+		};
+		07A0F676005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FEEAsymmetricContext.cpp;
+			refType = 4;
+		};
+		07A0F677005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FEEAsymmetricContext.h;
+			refType = 4;
+		};
+		07A0F678005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FEECSPUtils.cpp;
+			refType = 4;
+		};
+		07A0F679005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FEECSPUtils.h;
+			refType = 4;
+		};
+		07A0F67A005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FEEKeys.cpp;
+			refType = 4;
+		};
+		07A0F67B005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FEEKeys.h;
+			refType = 4;
+		};
+		07A0F67E005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FEESignatureObject.cpp;
+			refType = 4;
+		};
+		07A0F67F005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FEESignatureObject.h;
+			refType = 4;
+		};
+		07A0F680005DAEE111CD283A = {
+			children = (
+				07A0F681005DAEE111CD283A,
+				07A0F682005DAEE111CD283A,
+				07A0F683005DAEE111CD283A,
+				07A0F684005DAEE111CD283A,
+			);
+			isa = PBXGroup;
+			path = PBKDF2;
+			refType = 4;
+		};
+		07A0F681005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = HMACSHA1.c;
+			refType = 4;
+		};
+		07A0F682005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = HMACSHA1.h;
+			refType = 4;
+		};
+		07A0F683005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = pbkdf2.c;
+			refType = 4;
+		};
+		07A0F684005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = pbkdf2.h;
+			refType = 4;
+		};
+		07A0F685005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = TODO;
+			refType = 4;
+		};
+		07A0F686005DAEE111CD283A = {
+			children = (
+				07A0F68A005DAEE111CD283A,
+				07A0F68B005DAEE111CD283A,
+				07A0F68C005DAEE111CD283A,
+				07A0F68D005DAEE111CD283A,
+				F5E32A1500EAB9A301CD283A,
+				07A0F691005DAEE111CD283A,
+				07A0F692005DAEE111CD283A,
+				07A0F693005DAEE111CD283A,
+				07A0F694005DAEE111CD283A,
+				07A0F695005DAEE111CD283A,
+				07A0F696005DAEE111CD283A,
+				07A0F697005DAEE111CD283A,
+				07A0F698005DAEE111CD283A,
+				07A0F699005DAEE111CD283A,
+				07A0F69A005DAEE111CD283A,
+				07A0F69B005DAEE111CD283A,
+				07A0F69C005DAEE111CD283A,
+				07A0F69D005DAEE111CD283A,
+				07A0F69E005DAEE111CD283A,
+				07A0F69F005DAEE111CD283A,
+				327DDDE700D6FC1A05CD296C,
+			);
+			isa = PBXGroup;
+			path = AppleCSPDL;
+			refType = 4;
+		};
+		07A0F68A005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CSPDLDatabase.cpp;
+			refType = 4;
+		};
+		07A0F68B005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CSPDLDatabase.h;
+			refType = 4;
+		};
+		07A0F68C005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CSPDLPlugin.cpp;
+			refType = 4;
+		};
+		07A0F68D005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CSPDLPlugin.h;
+			refType = 4;
+		};
+		07A0F690005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = KeySchema.cpp;
+			refType = 4;
+		};
+		07A0F691005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = KeySchema.h;
+			refType = 4;
+		};
+		07A0F692005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSContext.cpp;
+			refType = 4;
+		};
+		07A0F693005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSContext.h;
+			refType = 4;
+		};
+		07A0F694005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSCSPDLSession.cpp;
+			refType = 4;
+		};
+		07A0F695005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSCSPDLSession.h;
+			refType = 4;
+		};
+		07A0F696005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSCSPSession.cpp;
+			refType = 4;
+		};
+		07A0F697005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSCSPSession.h;
+			refType = 4;
+		};
+		07A0F698005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSDatabase.cpp;
+			refType = 4;
+		};
+		07A0F699005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSDatabase.h;
+			refType = 4;
+		};
+		07A0F69A005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSDLSession.cpp;
+			refType = 4;
+		};
+		07A0F69B005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSDLSession.h;
+			refType = 4;
+		};
+		07A0F69C005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSFactory.cpp;
+			refType = 4;
+		};
+		07A0F69D005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSFactory.h;
+			refType = 4;
+		};
+		07A0F69E005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSKey.cpp;
+			refType = 4;
+		};
+		07A0F69F005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SSKey.h;
+			refType = 4;
+		};
+		07A0F6A0005DAEE111CD283A = {
+			children = (
+				07A0F6A4005DAEE111CD283A,
+				07A0F6A5005DAEE111CD283A,
+				07A0F6A8005DAEE111CD283A,
+				07A0F6A9005DAEE111CD283A,
+				07A0F6AA005DAEE111CD283A,
+				3290383500D6BB3705CD296C,
+			);
+			isa = PBXGroup;
+			path = AppleDL;
+			refType = 4;
+		};
+		07A0F6A4005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleFileDL.cpp;
+			refType = 4;
+		};
+		07A0F6A5005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleFileDL.h;
+			refType = 4;
+		};
+		07A0F6A8005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = FORMAT;
+			refType = 4;
+		};
+		07A0F6A9005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = ISSUES;
+			refType = 4;
+		};
+		07A0F6AA005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = TODO;
+			refType = 4;
+		};
+		07A0F6AB005DAEE111CD283A = {
+			children = (
+				07A0F6AD005DAEE111CD283A,
+				07A0F6AE005DAEE111CD283A,
+				07A0F6B2005DAEE111CD283A,
+				07A0F6B3005DAEE111CD283A,
+				07A0F6B4005DAEE111CD283A,
+				07A0F6B5005DAEE111CD283A,
+				07A0F6B6005DAEE111CD283A,
+				07A0F6B7005DAEE111CD283A,
+				07A0F6B8005DAEE111CD283A,
+				07A0F6B9005DAEE111CD283A,
+				07A0F6BA005DAEE111CD283A,
+				07A0F6BD005DAEE111CD283A,
+				07A0F6BE005DAEE111CD283A,
+				07A0F6BF005DAEE111CD283A,
+				07A0F6C0005DAEE111CD283A,
+				07A0F6C1005DAEE111CD283A,
+				07A0F6C2005DAEE111CD283A,
+				07A0F6C3005DAEE111CD283A,
+				07A0F6C4005DAEE111CD283A,
+				07A0F6C5005DAEE111CD283A,
+				07A0F6C6005DAEE111CD283A,
+				07A0F6C7005DAEE111CD283A,
+				07A0F6C8005DAEE111CD283A,
+				07A0F6C9005DAEE111CD283A,
+				3290383600D6BB3705CD296C,
+			);
+			isa = PBXGroup;
+			path = AppleX509CL;
+			refType = 4;
+		};
+		07A0F6AD005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleX509CL.cpp;
+			refType = 4;
+		};
+		07A0F6AE005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleX509CL.h;
+			refType = 4;
+		};
+		07A0F6B2005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CertBuilder.cpp;
+			refType = 4;
+		};
+		07A0F6B3005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CertBuilder.h;
+			refType = 4;
+		};
+		07A0F6B4005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CLCertExtensions.cpp;
+			refType = 4;
+		};
+		07A0F6B5005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CLCertExtensions.h;
+			refType = 4;
+		};
+		07A0F6B6005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CertFields.cpp;
+			refType = 4;
+		};
+		07A0F6B7005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CLCachedEntry.cpp;
+			refType = 4;
+		};
+		07A0F6B8005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CLCachedEntry.h;
+			refType = 4;
+		};
+		07A0F6B9005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CSPAttacher.cpp;
+			refType = 4;
+		};
+		07A0F6BA005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = CSPAttacher.h;
+			refType = 4;
+		};
+		07A0F6BD005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = cldebugging.c;
+			refType = 4;
+		};
+		07A0F6BE005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = cldebugging.h;
+			refType = 4;
+		};
+		07A0F6BF005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = DecodedCert.cpp;
+			refType = 4;
+		};
+		07A0F6C0005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = DecodedCert.h;
+			refType = 4;
+		};
+		07A0F6C1005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = LockedMap.h;
+			refType = 4;
+		};
+		07A0F6C2005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleX509CLSession.cpp;
+			refType = 4;
+		};
+		07A0F6C3005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleX509CLSession.h;
+			refType = 4;
+		};
+		07A0F6C4005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = Session_Cert.cpp;
+			refType = 4;
+		};
+		07A0F6C5005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = Session_CRL.cpp;
+			refType = 4;
+		};
+		07A0F6C6005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = Session_Crypto.cpp;
+			refType = 4;
+		};
+		07A0F6C7005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SnaccUtils.cpp;
+			refType = 4;
+		};
+		07A0F6C8005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = SnaccUtils.h;
+			refType = 4;
+		};
+		07A0F6C9005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = TODO;
+			refType = 4;
+		};
+		07A0F6CA005DAEE111CD283A = {
+			children = (
+				07A0F6CB005DAEE111CD283A,
+				07A0F6CC005DAEE111CD283A,
+				07A0F6CF005DAEE111CD283A,
+				07A0F6D0005DAEE111CD283A,
+				07A0F6D1005DAEE111CD283A,
+				07A0F6D2005DAEE111CD283A,
+				07A0F6D5005DAEE111CD283A,
+				07A0F6D6005DAEE111CD283A,
+				07A0F6D7005DAEE111CD283A,
+				07A0F6D8005DAEE111CD283A,
+				07A0F6D9005DAEE111CD283A,
+				07A0F6DA005DAEE111CD283A,
+				07A0F6DB005DAEE111CD283A,
+				07A0F6DC005DAEE111CD283A,
+				07A0F6DD005DAEE111CD283A,
+				07A0F6DE005DAEE111CD283A,
+				07A0F6DF005DAEE111CD283A,
+				07A0F6E0005DAEE111CD283A,
+				3290383700D6BB3705CD296C,
+			);
+			isa = PBXGroup;
+			path = AppleX509TP;
+			refType = 4;
+		};
+		07A0F6CB005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleTP.cpp;
+			refType = 4;
+		};
+		07A0F6CC005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleTP.h;
+			refType = 4;
+		};
+		07A0F6CF005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleTPSession.cpp;
+			refType = 4;
+		};
+		07A0F6D0005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = AppleTPSession.h;
+			refType = 4;
+		};
+		07A0F6D1005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = certGroupUtils.cpp;
+			refType = 4;
+		};
+		07A0F6D2005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = certGroupUtils.h;
+			refType = 4;
+		};
+		07A0F6D5005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = tpdebugging.c;
+			refType = 4;
+		};
+		07A0F6D6005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = tpdebugging.h;
+			refType = 4;
+		};
+		07A0F6D7005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = iSignRootCerts.c;
+			refType = 4;
+		};
+		07A0F6D8005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = rootCerts.h;
+			refType = 4;
+		};
+		07A0F6D9005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = sslRootCerts.c;
+			refType = 4;
+		};
+		07A0F6DA005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = tpCertGroup.cpp;
+			refType = 4;
+		};
+		07A0F6DB005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = TPCertInfo.cpp;
+			refType = 4;
+		};
+		07A0F6DC005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = TPCertInfo.h;
+			refType = 4;
+		};
+		07A0F6DD005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = tpPolicies.cpp;
+			refType = 4;
+		};
+		07A0F6DE005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = tpPolicies.h;
+			refType = 4;
+		};
+		07A0F6DF005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = tpTime.c;
+			refType = 4;
+		};
+		07A0F6E0005DAEE111CD283A = {
+			isa = PBXFileReference;
+			path = tpTime.h;
+			refType = 4;
+		};
+		07E4D6D300A0CA617F000001 = {
+			children = (
+				07E4D6D400A0CA617F000001,
+				07E4D6D500A0CA617F000001,
+				07E4D6D600A0CA617F000001,
+				07E4D6D700A0CA617F000001,
+				07E4D6D800A0CA617F000001,
+				07E4D6D900A0CA617F000001,
+				07E4D6DA00A0CA617F000001,
+				07E4D6DB00A0CA617F000001,
+			);
+			isa = PBXGroup;
+			name = dsa;
+			refType = 4;
+		};
+		07E4D6D400A0CA617F000001 = {
+			isa = PBXFileReference;
+			name = dsa_asn1.c;
+			path = dsa/dsa_asn1.c;
+			refType = 4;
+		};
+		07E4D6D500A0CA617F000001 = {
+			isa = PBXFileReference;
+			name = dsa_err.c;
+			path = dsa/dsa_err.c;
+			refType = 4;
+		};
+		07E4D6D600A0CA617F000001 = {
+			isa = PBXFileReference;
+			name = dsa_gen.c;
+			path = dsa/dsa_gen.c;
+			refType = 4;
+		};
+		07E4D6D700A0CA617F000001 = {
+			isa = PBXFileReference;
+			name = dsa_key.c;
+			path = dsa/dsa_key.c;
+			refType = 4;
+		};
+		07E4D6D800A0CA617F000001 = {
+			isa = PBXFileReference;
+			name = dsa_lib.c;
+			path = dsa/dsa_lib.c;
+			refType = 4;
+		};
+		07E4D6D900A0CA617F000001 = {
+			isa = PBXFileReference;
+			name = dsa_ossl.c;
+			path = dsa/dsa_ossl.c;
+			refType = 4;
+		};
+		07E4D6DA00A0CA617F000001 = {
+			isa = PBXFileReference;
+			name = dsa_sign.c;
+			path = dsa/dsa_sign.c;
+			refType = 4;
+		};
+		07E4D6DB00A0CA617F000001 = {
+			isa = PBXFileReference;
+			name = dsa_vrf.c;
+			path = dsa/dsa_vrf.c;
+			refType = 4;
+		};
+		07E4D6DC00A0CA617F000001 = {
+			fileRef = 07E4D6D400A0CA617F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		07E4D6DD00A0CA617F000001 = {
+			fileRef = 07E4D6D500A0CA617F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		07E4D6DE00A0CA617F000001 = {
+			fileRef = 07E4D6D600A0CA617F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		07E4D6DF00A0CA617F000001 = {
+			fileRef = 07E4D6D700A0CA617F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		07E4D6E000A0CA617F000001 = {
+			fileRef = 07E4D6D800A0CA617F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		07E4D6E100A0CA617F000001 = {
+			fileRef = 07E4D6D900A0CA617F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		07E4D6E200A0CA617F000001 = {
+			fileRef = 07E4D6DA00A0CA617F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		07E4D6E300A0CA617F000001 = {
+			fileRef = 07E4D6DB00A0CA617F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		07E4D6E400A0CD8D7F000001 = {
+			isa = PBXFileReference;
+			name = sha.h;
+			path = openssl/sha.h;
+			refType = 4;
+		};
+		07E4D6E500A0CD8D7F000001 = {
+			fileRef = 07E4D6E400A0CD8D7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//070
+//071
+//072
+//073
+//074
+//080
+//081
+//082
+//083
+//084
+		0867D690FE84028FC02AAC07 = {
+			buildStyles = (
+				01CE6B1AFFF2B1BA11CD283A,
+				01CE6B19FFF2B1BA11CD283A,
+				320C8FE900EA6AD705CD296C,
+			);
+			isa = PBXProject;
+			mainGroup = 0867D691FE84028FC02AAC07;
+			productRefGroup = 034768DDFF38A45A11DB9C8B;
+			projectDirPath = "";
+			targets = (
+				01CE6B1BFFF2B31311CD283A,
+				01CE6B1DFFF2B33A11CD283A,
+				01FA88F0FFF2B96911CD283A,
+				0867D69CFE84028FC02AAC07,
+				030701E4FFF96F8511CD283A,
+				125E85D5FFF3D67D11CD283A,
+				01FA88FCFFF2BC5611CD283A,
+				01FA8904FFF2BCA811CD283A,
+				01FA88F9FFF2BBEB11CD283A,
+				3290385000D6BB7805CD296C,
+				014880CD005EAE4D11CD283A,
+				014880D4005EAE4D11CD283A,
+				014880DA005EAE4D11CD283A,
+				014880E0005EAE4D11CD283A,
+				014880E6005EAE4D11CD283A,
+				3290383800D6BB3705CD296C,
+				325EAA2200D6B08805CD296C,
+				3290382200D6BA5905CD296C,
+				3290381900D6BA5905CD296C,
+				3290382800D6BA5905CD296C,
+				3290382E00D6BA5905CD296C,
+			);
+		};
+		0867D691FE84028FC02AAC07 = {
+			children = (
+				01FA7FE6FFF2B54C11CD283A,
+				0177F263FFFAA2D311CD283A,
+				0F404EB6008616EE7F000001,
+				01FA819DFFF2B54C11CD283A,
+				01FA8126FFF2B54C11CD283A,
+				01FA8168FFF2B54C11CD283A,
+				01FA823FFFF2B54C11CD283A,
+				07A0F5EA005DAEE111CD283A,
+				07A0F686005DAEE111CD283A,
+				07A0F6A0005DAEE111CD283A,
+				07A0F6AB005DAEE111CD283A,
+				07A0F6CA005DAEE111CD283A,
+				F5A5E50E00FB884E01CD29D4,
+				01FA890DFFF2BD9911CD283A,
+				01FA890EFFF2BD9911CD283A,
+				030701E1FFF95F6F11CD283A,
+				0867D69AFE84028FC02AAC07,
+				034768DDFF38A45A11DB9C8B,
+			);
+			isa = PBXGroup;
+			name = Security;
+			refType = 4;
+		};
+		0867D69AFE84028FC02AAC07 = {
+			children = (
+				325EAA2900D6B23F05CD296C,
+				125E85ADFFF3D44A11CD283A,
+				1A23E785009758847F000001,
+				327DDDFA00D7E81F05CD296C,
+			);
+			isa = PBXGroup;
+			name = "External Frameworks and Libraries";
+			refType = 4;
+		};
+		0867D69CFE84028FC02AAC07 = {
+			buildPhases = (
+				0867D69DFE84028FC02AAC07,
+				0867D69EFE84028FC02AAC07,
+				0867D69FFE84028FC02AAC07,
+				0867D6A0FE84028FC02AAC07,
+				0867D6A2FE84028FC02AAC07,
+				F5DDE3AE00B3358F01CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/derived_src\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+				LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/2.95.2;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "-DLIMITED_SIGNING -DBUILTIN_PLUGINS -DVDADER_RULES";
+				OTHER_LDFLAGS = "-lComCryption -lCryptKit -twolevel_namespace \"-L$(SYMROOT)\" -seg_addr_table \"$(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table\"";
+				PREBINDING = YES;
+				PRODUCT_NAME = Security;
+				SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/Security.order\"";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			dependencies = (
+				3290384F00D6BB7805CD296C,
+				05855484FFF2DA1E11CD283A,
+			);
+			isa = PBXFrameworkTarget;
+			name = Security;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+			productName = Security;
+			productReference = 034768DEFF38A45A11DB9C8B;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>Security</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.security</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Security</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>Security 1.0</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		0867D69DFE84028FC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				01FA848EFFF2B54C11CD283A,
+				01FA848FFFF2B54C11CD283A,
+				01FA8490FFF2B54C11CD283A,
+				01FA8491FFF2B54C11CD283A,
+				01FA8492FFF2B54C11CD283A,
+				01FA8493FFF2B54C11CD283A,
+				01FA8494FFF2B54C11CD283A,
+				01FA8495FFF2B54C11CD283A,
+				01FA8496FFF2B54C11CD283A,
+				01FA8497FFF2B54C11CD283A,
+				01FA8498FFF2B54C11CD283A,
+				01FA8499FFF2B54C11CD283A,
+				01FA849AFFF2B54C11CD283A,
+				01FA849BFFF2B54C11CD283A,
+				01FA849CFFF2B54C11CD283A,
+				01FA849DFFF2B54C11CD283A,
+				01FA849EFFF2B54C11CD283A,
+				01FA849FFFF2B54C11CD283A,
+				01FA84A0FFF2B54C11CD283A,
+				01FA84A1FFF2B54C11CD283A,
+				01FA84A2FFF2B54C11CD283A,
+				01FA84A3FFF2B54C11CD283A,
+				01FA84A4FFF2B54C11CD283A,
+				01FA84A5FFF2B54C11CD283A,
+				01FA84A6FFF2B54C11CD283A,
+				01FA84A7FFF2B54C11CD283A,
+				01FA84A8FFF2B54C11CD283A,
+				01FA84A9FFF2B54C11CD283A,
+				01FA84AAFFF2B54C11CD283A,
+				01FA84ABFFF2B54C11CD283A,
+				01FA84ACFFF2B54C11CD283A,
+				01FA84ADFFF2B54C11CD283A,
+				01FA84AEFFF2B54C11CD283A,
+				01FA84AFFFF2B54C11CD283A,
+				01FA84B0FFF2B54C11CD283A,
+				01FA84B1FFF2B54C11CD283A,
+				01FA84B2FFF2B54C11CD283A,
+				01FA84B3FFF2B54C11CD283A,
+				01FA84B4FFF2B54C11CD283A,
+				01FA84B5FFF2B54C11CD283A,
+				01FA84B6FFF2B54C11CD283A,
+				01FA84B7FFF2B54C11CD283A,
+				01FA84B8FFF2B54C11CD283A,
+				01FA84B9FFF2B54C11CD283A,
+				01FA84BAFFF2B54C11CD283A,
+				01FA84BBFFF2B54C11CD283A,
+				01FA84BCFFF2B54C11CD283A,
+				01FA84BDFFF2B54C11CD283A,
+				01FA84BEFFF2B54C11CD283A,
+				01FA84BFFFF2B54C11CD283A,
+				01FA84C0FFF2B54C11CD283A,
+				01FA84C1FFF2B54C11CD283A,
+				01FA84C2FFF2B54C11CD283A,
+				01FA84C3FFF2B54C11CD283A,
+				01FA84C5FFF2B54C11CD283A,
+				01FA84C6FFF2B54C11CD283A,
+				01FA84C7FFF2B54C11CD283A,
+				01FA84C8FFF2B54C11CD283A,
+				01FA84C9FFF2B54C11CD283A,
+				01FA84CAFFF2B54C11CD283A,
+				01FA84CBFFF2B54C11CD283A,
+				01FA84CCFFF2B54C11CD283A,
+				01FA84CEFFF2B54C11CD283A,
+				01FA84CFFFF2B54C11CD283A,
+				01FA84D0FFF2B54C11CD283A,
+				01FA84D1FFF2B54C11CD283A,
+				01FA84D2FFF2B54C11CD283A,
+				01FA84D3FFF2B54C11CD283A,
+				01FA84D4FFF2B54C11CD283A,
+				01FA84D5FFF2B54C11CD283A,
+				01FA84D6FFF2B54C11CD283A,
+				01FA84D7FFF2B54C11CD283A,
+				01FA84D8FFF2B54C11CD283A,
+				01FA84D9FFF2B54C11CD283A,
+				01FA84DAFFF2B54C11CD283A,
+				01FA84DBFFF2B54C11CD283A,
+				01FA84DCFFF2B54C11CD283A,
+				01FA84DDFFF2B54C11CD283A,
+				01FA84DEFFF2B54C11CD283A,
+				01FA84DFFFF2B54C11CD283A,
+				01FA84E0FFF2B54C11CD283A,
+				01FA84E1FFF2B54C11CD283A,
+				01FA84E2FFF2B54C11CD283A,
+				01FA84E3FFF2B54C11CD283A,
+				01FA84E4FFF2B54C11CD283A,
+				01FA84E5FFF2B54C11CD283A,
+				01FA84E6FFF2B54C11CD283A,
+				01FA84E7FFF2B54C11CD283A,
+				01FA84E8FFF2B54C11CD283A,
+				01FA84E9FFF2B54C11CD283A,
+				01FA84EAFFF2B54C11CD283A,
+				01FA84EBFFF2B54C11CD283A,
+				01FA84EDFFF2B54C11CD283A,
+				01FA84EEFFF2B54C11CD283A,
+				01FA84EFFFF2B54C11CD283A,
+				01FA84F0FFF2B54C11CD283A,
+				01FA84F2FFF2B54C11CD283A,
+				01FA84F3FFF2B54C11CD283A,
+				025C84BC0027360A11CD296C,
+				01FA84F4FFF2B54C11CD283A,
+				01FA84F5FFF2B54C11CD283A,
+				01FA84F6FFF2B54C11CD283A,
+				01FA84F7FFF2B54C11CD283A,
+				01FA84F8FFF2B54C11CD283A,
+				01FA84F9FFF2B54C11CD283A,
+				01FA84FAFFF2B54C11CD283A,
+				01FA84FBFFF2B54C11CD283A,
+				01FA84FCFFF2B54C11CD283A,
+				01FA84FDFFF2B54C11CD283A,
+				01FA84FEFFF2B54C11CD283A,
+				01FA84FFFFF2B54C11CD283A,
+				01FA8517FFF2B54C11CD283A,
+				01FA8518FFF2B54C11CD283A,
+				01FA8519FFF2B54C11CD283A,
+				01FA851AFFF2B54C11CD283A,
+				01FA851BFFF2B54C11CD283A,
+				01FA851CFFF2B54C11CD283A,
+				01FA851DFFF2B54C11CD283A,
+				01FA851EFFF2B54C11CD283A,
+				01FA851FFFF2B54C11CD283A,
+				01FA8520FFF2B54C11CD283A,
+				01FA8521FFF2B54C11CD283A,
+				01FA8522FFF2B54C11CD283A,
+				01FA8523FFF2B54C11CD283A,
+				01FA8524FFF2B54C11CD283A,
+				01FA8525FFF2B54C11CD283A,
+				01FA8526FFF2B54C11CD283A,
+				01FA8527FFF2B54C11CD283A,
+				01FA8528FFF2B54C11CD283A,
+				01FA8529FFF2B54C11CD283A,
+				01FA852AFFF2B54C11CD283A,
+				01FA852BFFF2B54C11CD283A,
+				01FA852CFFF2B54C11CD283A,
+				01FA852DFFF2B54C11CD283A,
+				01FA852EFFF2B54C11CD283A,
+				01FA852FFFF2B54C11CD283A,
+				01FA8530FFF2B54C11CD283A,
+				01FA8531FFF2B54C11CD283A,
+				01FA8532FFF2B54C11CD283A,
+				01FA8533FFF2B54C11CD283A,
+				01FA8534FFF2B54C11CD283A,
+				01FA8535FFF2B54C11CD283A,
+				01FA8536FFF2B54C11CD283A,
+				01FA8537FFF2B54C11CD283A,
+				01FA8538FFF2B54C11CD283A,
+				01FA8539FFF2B54C11CD283A,
+				01FA853AFFF2B54C11CD283A,
+				01FA853BFFF2B54C11CD283A,
+				01FA853CFFF2B54C11CD283A,
+				01FA853DFFF2B54C11CD283A,
+				01FA853EFFF2B54C11CD283A,
+				01FA853FFFF2B54C11CD283A,
+				01FA8540FFF2B54C11CD283A,
+				01FA8541FFF2B54C11CD283A,
+				4EB202E2005859A47F000001,
+				01FA8546FFF2B54C11CD283A,
+				01FA8548FFF2B54C11CD283A,
+				01FA8549FFF2B54C11CD283A,
+				01FA8583FFF2B54C11CD283A,
+				01FA8584FFF2B54C11CD283A,
+				01FA8585FFF2B54C11CD283A,
+				01FA8586FFF2B54C11CD283A,
+				01FA8587FFF2B54C11CD283A,
+				01FA8588FFF2B54C11CD283A,
+				01FA8589FFF2B54C11CD283A,
+				01FA858AFFF2B54C11CD283A,
+				01FA858BFFF2B54C11CD283A,
+				01FA858CFFF2B54C11CD283A,
+				01FA858DFFF2B54C11CD283A,
+				01FA858EFFF2B54C11CD283A,
+				01FA858FFFF2B54C11CD283A,
+				01FA8590FFF2B54C11CD283A,
+				01FA8591FFF2B54C11CD283A,
+				01FA8592FFF2B54C11CD283A,
+				01FA8593FFF2B54C11CD283A,
+				01FA8594FFF2B54C11CD283A,
+				01FA8595FFF2B54C11CD283A,
+				01FA8596FFF2B54C11CD283A,
+				01FA8597FFF2B54C11CD283A,
+				01FA8598FFF2B54C11CD283A,
+				01FA8599FFF2B54C11CD283A,
+				01FA859AFFF2B54C11CD283A,
+				01FA859BFFF2B54C11CD283A,
+				01FA859DFFF2B54C11CD283A,
+				01FA859EFFF2B54C11CD283A,
+				01FA8929FFF2BE3511CD283A,
+				01FA892AFFF2BE3511CD283A,
+				01FA892BFFF2BE3511CD283A,
+				01FA892CFFF2BE3511CD283A,
+				01FA892DFFF2BE3511CD283A,
+				03B76D49FFF2D31811CD283A,
+				03B76D4AFFF2D35D11CD283A,
+				03B76D4BFFF2D35D11CD283A,
+				03B76D4CFFF2D35D11CD283A,
+				03B76D4DFFF2D35D11CD283A,
+				2DFDC7A8FFF3E4ED11CD283A,
+				31200C5CFFF3E57C11CD283A,
+				338005E1FFF3E69711CD283A,
+				0177F2DEFFFAA2D311CD283A,
+				0177F2EAFFFAA2D311CD283A,
+				0177F2EEFFFAA2D311CD283A,
+				0177F2F0FFFAA2D311CD283A,
+				0177F2F4FFFAA2D311CD283A,
+				0177F2F5FFFAA2D311CD283A,
+				0177F2FAFFFAA2D311CD283A,
+				0177F2FBFFFAA2D311CD283A,
+				0177F2FCFFFAA2D311CD283A,
+				0177F2FDFFFAA2D311CD283A,
+				0177F354FFFAC61911CD283A,
+				0177F30BFFFAA2D311CD283A,
+				0177F315FFFAA2D311CD283A,
+				0177F317FFFAA2D311CD283A,
+				0177F319FFFAA2D311CD283A,
+				0177F31AFFFAA2D311CD283A,
+				0177F31BFFFAA2D311CD283A,
+				0177F31DFFFAA2D311CD283A,
+				014989C0006AA1D111CD283A,
+				014989C1006AA1D111CD283A,
+				33BD042300838F447F000001,
+				33BD042C00838FB17F000001,
+				33BD042D00838FB17F000001,
+				33BD042E00838FB17F000001,
+				33BD0449008390257F000001,
+				33BD044A008390257F000001,
+				33BD044B008390257F000001,
+				33BD044C008390257F000001,
+				33BD044D008390257F000001,
+				33BD044E008390257F000001,
+				33BD044F008390257F000001,
+				33BD0450008390257F000001,
+				33BD0451008390257F000001,
+				33BD0452008390257F000001,
+				33BD0460008390B17F000001,
+				33BD0464008391C07F000001,
+				0F404EDA008618137F000001,
+				0F404EDB008618137F000001,
+				0F404EDC008618137F000001,
+				0F404EDD008618137F000001,
+				0F404EDE008618137F000001,
+				0F404EE0008618137F000001,
+				0F404EE1008618137F000001,
+				0F404EE2008618137F000001,
+				0F404EE3008618137F000001,
+				0F404EE4008618137F000001,
+				0F404EE5008618137F000001,
+				0F404EE8008618137F000001,
+				2178153B008B941B7F000001,
+				01827D0B008CB8707F000001,
+				017A54F40094AAE57F000001,
+				017B6CA8009748107F000001,
+				2F4DD9A700A0A0767F000001,
+				4D37AD4200AA03857F000001,
+				4D37AD4300AA03857F000001,
+				4D37AD4400AA03857F000001,
+				4D37AD4500AA03857F000001,
+				4D37AD4600AA03857F000001,
+				3264486600D54DD305CD296C,
+				3290387000D6C5FE05CD296C,
+				327DDDE300D6F8A605CD296C,
+				327DDDE400D6F8A605CD296C,
+				327DDDF800D7DB7505CD296C,
+				32604C2800E3C14505CD296C,
+				3272260B00E3C75605CD296C,
+				3267644900EBF3AA05CD296C,
+				F58785CA00FB966001CD29D4,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0867D69EFE84028FC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				01FA8609FFF2B54C11CD283A,
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		0867D69FFE84028FC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				01FA86D9FFF2B54C11CD283A,
+				01FA86DAFFF2B54C11CD283A,
+				01FA86DBFFF2B54C11CD283A,
+				01FA86DCFFF2B54C11CD283A,
+				01FA86DDFFF2B54C11CD283A,
+				01FA86DEFFF2B54C11CD283A,
+				01FA86DFFFF2B54C11CD283A,
+				01FA86E0FFF2B54C11CD283A,
+				01FA86E1FFF2B54C11CD283A,
+				01FA86E2FFF2B54C11CD283A,
+				01FA86E3FFF2B54C11CD283A,
+				01FA86E4FFF2B54C11CD283A,
+				01FA86E5FFF2B54C11CD283A,
+				01FA86E6FFF2B54C11CD283A,
+				01FA86E7FFF2B54C11CD283A,
+				01FA86E9FFF2B54C11CD283A,
+				01FA86EAFFF2B54C11CD283A,
+				01FA86EBFFF2B54C11CD283A,
+				01FA86ECFFF2B54C11CD283A,
+				01FA86EDFFF2B54C11CD283A,
+				01FA86EFFFF2B54C11CD283A,
+				01FA86F0FFF2B54C11CD283A,
+				01FA86F1FFF2B54C11CD283A,
+				01FA86F3FFF2B54C11CD283A,
+				01FA86F4FFF2B54C11CD283A,
+				01FA86F5FFF2B54C11CD283A,
+				01FA86F6FFF2B54C11CD283A,
+				01FA86F7FFF2B54C11CD283A,
+				01FA86F8FFF2B54C11CD283A,
+				01FA86F9FFF2B54C11CD283A,
+				01FA86FAFFF2B54C11CD283A,
+				01FA86FCFFF2B54C11CD283A,
+				01FA86FDFFF2B54C11CD283A,
+				01FA86FEFFF2B54C11CD283A,
+				01FA86FFFFF2B54C11CD283A,
+				01FA8700FFF2B54C11CD283A,
+				01FA8701FFF2B54C11CD283A,
+				01FA8702FFF2B54C11CD283A,
+				01FA8703FFF2B54C11CD283A,
+				01FA8704FFF2B54C11CD283A,
+				01FA8705FFF2B54C11CD283A,
+				01FA8706FFF2B54C11CD283A,
+				01FA8707FFF2B54C11CD283A,
+				01FA8708FFF2B54C11CD283A,
+				01FA8709FFF2B54C11CD283A,
+				01FA870AFFF2B54C11CD283A,
+				01FA870BFFF2B54C11CD283A,
+				01FA870CFFF2B54C11CD283A,
+				01FA870DFFF2B54C11CD283A,
+				01FA870EFFF2B54C11CD283A,
+				01FA870FFFF2B54C11CD283A,
+				01FA8710FFF2B54C11CD283A,
+				01FA8711FFF2B54C11CD283A,
+				01FA8712FFF2B54C11CD283A,
+				01FA8713FFF2B54C11CD283A,
+				01FA8714FFF2B54C11CD283A,
+				01FA8715FFF2B54C11CD283A,
+				01FA8716FFF2B54C11CD283A,
+				01FA8717FFF2B54C11CD283A,
+				01FA8718FFF2B54C11CD283A,
+				01FA871BFFF2B54C11CD283A,
+				01FA871CFFF2B54C11CD283A,
+				01FA871EFFF2B54C11CD283A,
+				01FA871FFFF2B54C11CD283A,
+				01FA8720FFF2B54C11CD283A,
+				01FA8721FFF2B54C11CD283A,
+				01FA8722FFF2B54C11CD283A,
+				01FA8724FFF2B54C11CD283A,
+				01FA8725FFF2B54C11CD283A,
+				01FA8726FFF2B54C11CD283A,
+				01FA8727FFF2B54C11CD283A,
+				01FA8728FFF2B54C11CD283A,
+				01FA8729FFF2B54C11CD283A,
+				01FA872AFFF2B54C11CD283A,
+				01FA872BFFF2B54C11CD283A,
+				01FA872CFFF2B54C11CD283A,
+				01FA872DFFF2B54C11CD283A,
+				01FA872EFFF2B54C11CD283A,
+				01FA872FFFF2B54C11CD283A,
+				01FA8730FFF2B54C11CD283A,
+				01FA874FFFF2B54C11CD283A,
+				01FA8750FFF2B54C11CD283A,
+				01FA8751FFF2B54C11CD283A,
+				01FA8752FFF2B54C11CD283A,
+				01FA8753FFF2B54C11CD283A,
+				01FA8754FFF2B54C11CD283A,
+				01FA8755FFF2B54C11CD283A,
+				01FA8756FFF2B54C11CD283A,
+				01FA8757FFF2B54C11CD283A,
+				01FA8758FFF2B54C11CD283A,
+				01FA8759FFF2B54C11CD283A,
+				01FA875AFFF2B54C11CD283A,
+				01FA875BFFF2B54C11CD283A,
+				01FA875CFFF2B54C11CD283A,
+				01FA875DFFF2B54C11CD283A,
+				01FA875FFFF2B54C11CD283A,
+				01FA8760FFF2B54C11CD283A,
+				01FA8761FFF2B54C11CD283A,
+				01FA8762FFF2B54C11CD283A,
+				01FA8763FFF2B54C11CD283A,
+				01FA8764FFF2B54C11CD283A,
+				01FA8765FFF2B54C11CD283A,
+				01FA8766FFF2B54C11CD283A,
+				01FA8767FFF2B54C11CD283A,
+				01FA8769FFF2B54C11CD283A,
+				01FA876AFFF2B54C11CD283A,
+				01FA876BFFF2B54C11CD283A,
+				01FA876CFFF2B54C11CD283A,
+				01FA876DFFF2B54C11CD283A,
+				01FA876EFFF2B54C11CD283A,
+				01FA876FFFF2B54C11CD283A,
+				01FA8770FFF2B54C11CD283A,
+				01FA8771FFF2B54C11CD283A,
+				01FA8772FFF2B54C11CD283A,
+				01FA8773FFF2B54C11CD283A,
+				01FA8774FFF2B54C11CD283A,
+				01FA8775FFF2B54C11CD283A,
+				01FA8776FFF2B54C11CD283A,
+				01FA8777FFF2B54C11CD283A,
+				01FA8778FFF2B54C11CD283A,
+				01FA8779FFF2B54C11CD283A,
+				01FA877AFFF2B54C11CD283A,
+				01FA877BFFF2B54C11CD283A,
+				01FA877CFFF2B54C11CD283A,
+				01FA877DFFF2B54C11CD283A,
+				01FA877EFFF2B54C11CD283A,
+				4EB202E3005859A47F000001,
+				01FA8783FFF2B54C11CD283A,
+				01FA8786FFF2B54C11CD283A,
+				01FA8787FFF2B54C11CD283A,
+				01FA87C9FFF2B54C11CD283A,
+				01FA87CAFFF2B54C11CD283A,
+				01FA87CBFFF2B54C11CD283A,
+				01FA87CCFFF2B54C11CD283A,
+				01FA87CDFFF2B54C11CD283A,
+				01FA87CEFFF2B54C11CD283A,
+				01FA87CFFFF2B54C11CD283A,
+				01FA87D0FFF2B54C11CD283A,
+				01FA87D1FFF2B54C11CD283A,
+				01FA87D2FFF2B54C11CD283A,
+				01FA87D3FFF2B54C11CD283A,
+				01FA87D4FFF2B54C11CD283A,
+				01FA87D5FFF2B54C11CD283A,
+				01FA87D6FFF2B54C11CD283A,
+				01FA87D7FFF2B54C11CD283A,
+				01FA87D8FFF2B54C11CD283A,
+				01FA87D9FFF2B54C11CD283A,
+				01FA87DAFFF2B54C11CD283A,
+				01FA87F7FFF2B54C11CD283A,
+				01FA87FEFFF2B54C11CD283A,
+				01FA87FFFFF2B54C11CD283A,
+				01FA8930FFF2BE3511CD283A,
+				01FA8931FFF2BE3511CD283A,
+				01FA8932FFF2BE3511CD283A,
+				01FA8933FFF2BE3511CD283A,
+				01FA8936FFF2BE3511CD283A,
+				03B76D4EFFF2D35D11CD283A,
+				03B76D4FFFF2D35D11CD283A,
+				03B76D51FFF2D43011CD283A,
+				0177F323FFFAA2D311CD283A,
+				0177F32CFFFAA2D311CD283A,
+				0177F330FFFAA2D311CD283A,
+				0177F332FFFAA2D311CD283A,
+				0177F334FFFAA2D311CD283A,
+				0177F335FFFAA2D311CD283A,
+				0177F33AFFFAA2D311CD283A,
+				0177F33BFFFAA2D311CD283A,
+				0177F33CFFFAA2D311CD283A,
+				0177F355FFFAC61911CD283A,
+				0177F344FFFAA2D311CD283A,
+				0177F349FFFAA2D311CD283A,
+				0177F34BFFFAA2D311CD283A,
+				0177F34EFFFAA2D311CD283A,
+				0177F350FFFAA2D311CD283A,
+				33BD042400838F447F000001,
+				33BD042F00838FB17F000001,
+				33BD043000838FB17F000001,
+				33BD043100838FB17F000001,
+				33BD0454008390257F000001,
+				33BD0455008390257F000001,
+				33BD0456008390257F000001,
+				33BD0457008390257F000001,
+				33BD0458008390257F000001,
+				33BD0459008390257F000001,
+				33BD045A008390257F000001,
+				33BD045B008390257F000001,
+				33BD045C008390257F000001,
+				33BD045D008390257F000001,
+				33BD0461008390B17F000001,
+				33BD0465008391C07F000001,
+				0F404EEA008618137F000001,
+				0F404EEB008618137F000001,
+				0F404EEC008618137F000001,
+				0F404EED008618137F000001,
+				0F404EEE008618137F000001,
+				0F404EF0008618137F000001,
+				0F404EF1008618137F000001,
+				0F404EF2008618137F000001,
+				0F404EF3008618137F000001,
+				0F404EF4008618137F000001,
+				0F404EF5008618137F000001,
+				0F404EF7008618137F000001,
+				2178153C008B941B7F000001,
+				01827D0C008CB8707F000001,
+				017A54F50094AAE57F000001,
+				017B6CA9009748107F000001,
+				2F4DD9A800A0A0767F000001,
+				4D37AD4700AA03857F000001,
+				4D37AD4800AA03857F000001,
+				4D37AD4900AA03857F000001,
+				4D37AD4A00AA03857F000001,
+				3264486700D54DD305CD296C,
+				3290387100D6C5FE05CD296C,
+				327DDDE500D6F8A605CD296C,
+				327DDDE600D6F8A605CD296C,
+				327DDDF900D7DB7605CD296C,
+				32604C2900E3C14505CD296C,
+				3272260C00E3C75705CD296C,
+				F58785CB00FB966001CD29D4,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0867D6A0FE84028FC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				125E85AEFFF3D44A11CD283A,
+				1A23E786009758847F000001,
+				325EAA2A00D6B24005CD296C,
+				325EAA2B00D6B24005CD296C,
+				325EAA2C00D6B24005CD296C,
+				325EAA2D00D6B24005CD296C,
+				325EAA2E00D6B24005CD296C,
+				327DDDFB00D7E81F05CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0867D6A2FE84028FC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+//080
+//081
+//082
+//083
+//084
+//0A0
+//0A1
+//0A2
+//0A3
+//0A4
+		0AD5441E0003C2C511CD296C = {
+			isa = PBXFileReference;
+			path = SecurityServer.order;
+			refType = 4;
+		};
+//0A0
+//0A1
+//0A2
+//0A3
+//0A4
+//0F0
+//0F1
+//0F2
+//0F3
+//0F4
+		0F404EB6008616EE7F000001 = {
+			children = (
+				0F404EB9008618137F000001,
+				0F404EBA008618137F000001,
+				0F404EBB008618137F000001,
+				0F404EBC008618137F000001,
+				0F404EBF008618137F000001,
+				0F404EC0008618137F000001,
+				0F404EC1008618137F000001,
+				0F404EC2008618137F000001,
+				0F404EC3008618137F000001,
+				0F404EC4008618137F000001,
+				3264486400D54DD305CD296C,
+				3264486500D54DD305CD296C,
+				0F404EC5008618137F000001,
+				0F404EC7008618137F000001,
+				0F404ECA008618137F000001,
+				0F404ECB008618137F000001,
+				4D37AD3A00AA03857F000001,
+				4D37AD3900AA03857F000001,
+				4D37AD3C00AA03857F000001,
+				4D37AD3B00AA03857F000001,
+				4D37AD3E00AA03857F000001,
+				4D37AD3D00AA03857F000001,
+				4D37AD3F00AA03857F000001,
+				4D37AD4100AA03857F000001,
+				4D37AD4000AA03857F000001,
+				0F404ECC008618137F000001,
+				0F404ED5008618137F000001,
+			);
+			isa = PBXGroup;
+			path = Network;
+			refType = 4;
+		};
+		0F404EB9008618137F000001 = {
+			isa = PBXFileReference;
+			path = protocol.h;
+			refType = 4;
+		};
+		0F404EBA008618137F000001 = {
+			isa = PBXFileReference;
+			path = protocol.cpp;
+			refType = 4;
+		};
+		0F404EBB008618137F000001 = {
+			isa = PBXFileReference;
+			path = transfer.h;
+			refType = 4;
+		};
+		0F404EBC008618137F000001 = {
+			isa = PBXFileReference;
+			path = transfer.cpp;
+			refType = 4;
+		};
+		0F404EBF008618137F000001 = {
+			isa = PBXFileReference;
+			path = connectionpool.h;
+			refType = 4;
+		};
+		0F404EC0008618137F000001 = {
+			isa = PBXFileReference;
+			path = connectionpool.cpp;
+			refType = 4;
+		};
+		0F404EC1008618137F000001 = {
+			isa = PBXFileReference;
+			path = target.h;
+			refType = 4;
+		};
+		0F404EC2008618137F000001 = {
+			isa = PBXFileReference;
+			path = target.cpp;
+			refType = 4;
+		};
+		0F404EC3008618137F000001 = {
+			isa = PBXFileReference;
+			path = observer.h;
+			refType = 4;
+		};
+		0F404EC4008618137F000001 = {
+			isa = PBXFileReference;
+			path = observer.cpp;
+			refType = 4;
+		};
+		0F404EC5008618137F000001 = {
+			isa = PBXFileReference;
+			path = parameters.h;
+			refType = 4;
+		};
+		0F404EC7008618137F000001 = {
+			isa = PBXFileReference;
+			path = parameters.cpp;
+			refType = 4;
+		};
+		0F404ECA008618137F000001 = {
+			isa = PBXFileReference;
+			path = xfercore.h;
+			refType = 4;
+		};
+		0F404ECB008618137F000001 = {
+			isa = PBXFileReference;
+			path = xfercore.cpp;
+			refType = 4;
+		};
+		0F404ECC008618137F000001 = {
+			children = (
+				0F404ECD008618137F000001,
+				0F404ECE008618137F000001,
+				0F404ECF008618137F000001,
+				0F404ED0008618137F000001,
+				0F404ED1008618137F000001,
+				0F404ED2008618137F000001,
+				0F404ED3008618137F000001,
+				0F404ED4008618137F000001,
+				21781539008B941B7F000001,
+				2178153A008B941B7F000001,
+				01827D09008CB8707F000001,
+				01827D0A008CB8707F000001,
+				017A54F20094AAE57F000001,
+				017A54F30094AAE57F000001,
+			);
+			isa = PBXGroup;
+			name = Protocols;
+			refType = 4;
+		};
+		0F404ECD008618137F000001 = {
+			isa = PBXFileReference;
+			path = "file-protocol.h";
+			refType = 4;
+		};
+		0F404ECE008618137F000001 = {
+			isa = PBXFileReference;
+			path = "file-protocol.cpp";
+			refType = 4;
+		};
+		0F404ECF008618137F000001 = {
+			isa = PBXFileReference;
+			path = "ftp-protocol.h";
+			refType = 4;
+		};
+		0F404ED0008618137F000001 = {
+			isa = PBXFileReference;
+			path = "ftp-protocol.cpp";
+			refType = 4;
+		};
+		0F404ED1008618137F000001 = {
+			isa = PBXFileReference;
+			path = "http-protocol.h";
+			refType = 4;
+		};
+		0F404ED2008618137F000001 = {
+			isa = PBXFileReference;
+			path = "http-protocol.cpp";
+			refType = 4;
+		};
+		0F404ED3008618137F000001 = {
+			isa = PBXFileReference;
+			path = "https-protocol.h";
+			refType = 4;
+		};
+		0F404ED4008618137F000001 = {
+			isa = PBXFileReference;
+			path = "https-protocol.cpp";
+			refType = 4;
+		};
+		0F404ED5008618137F000001 = {
+			children = (
+				0F404ED6008618137F000001,
+				0F404ED7008618137F000001,
+			);
+			isa = PBXGroup;
+			name = Managers;
+			refType = 4;
+		};
+		0F404ED6008618137F000001 = {
+			isa = PBXFileReference;
+			path = simplemanager.h;
+			refType = 4;
+		};
+		0F404ED7008618137F000001 = {
+			isa = PBXFileReference;
+			path = simplemanager.cpp;
+			refType = 4;
+		};
+		0F404EDA008618137F000001 = {
+			fileRef = 0F404EBF008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EDB008618137F000001 = {
+			fileRef = 0F404ECD008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EDC008618137F000001 = {
+			fileRef = 0F404ECF008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EDD008618137F000001 = {
+			fileRef = 0F404ED1008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EDE008618137F000001 = {
+			fileRef = 0F404ED3008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EE0008618137F000001 = {
+			fileRef = 0F404EC3008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EE1008618137F000001 = {
+			fileRef = 0F404EC5008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EE2008618137F000001 = {
+			fileRef = 0F404EB9008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EE3008618137F000001 = {
+			fileRef = 0F404ED6008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EE4008618137F000001 = {
+			fileRef = 0F404EC1008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EE5008618137F000001 = {
+			fileRef = 0F404EBB008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EE8008618137F000001 = {
+			fileRef = 0F404ECA008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		0F404EEA008618137F000001 = {
+			fileRef = 0F404EC0008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EEB008618137F000001 = {
+			fileRef = 0F404ECE008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EEC008618137F000001 = {
+			fileRef = 0F404ED0008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EED008618137F000001 = {
+			fileRef = 0F404ED2008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EEE008618137F000001 = {
+			fileRef = 0F404ED4008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EF0008618137F000001 = {
+			fileRef = 0F404EC4008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EF1008618137F000001 = {
+			fileRef = 0F404EC7008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EF2008618137F000001 = {
+			fileRef = 0F404EBA008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EF3008618137F000001 = {
+			fileRef = 0F404ED7008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EF4008618137F000001 = {
+			fileRef = 0F404EC2008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EF5008618137F000001 = {
+			fileRef = 0F404EBC008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0F404EF7008618137F000001 = {
+			fileRef = 0F404ECB008618137F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//0F0
+//0F1
+//0F2
+//0F3
+//0F4
+//120
+//121
+//122
+//123
+//124
+		125E85A8FFF3CDEF11CD283A = {
+			isa = PBXFileReference;
+			path = xdatabase.cpp;
+			refType = 4;
+		};
+		125E85A9FFF3CDEF11CD283A = {
+			isa = PBXFileReference;
+			path = xdatabase.h;
+			refType = 4;
+		};
+		125E85ADFFF3D44A11CD283A = {
+			isa = PBXFrameworkReference;
+			name = CoreFoundation.framework;
+			path = /System/Library/Frameworks/CoreFoundation.framework;
+			refType = 0;
+		};
+		125E85AEFFF3D44A11CD283A = {
+			fileRef = 125E85ADFFF3D44A11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85AFFFF3D51B11CD283A = {
+			fileRef = 01FA819FFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85B0FFF3D51B11CD283A = {
+			fileRef = 01FA81A1FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85B1FFF3D51B11CD283A = {
+			fileRef = 01FA81A3FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85B2FFF3D51B11CD283A = {
+			fileRef = 01FA81A5FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85B3FFF3D51B11CD283A = {
+			fileRef = 01FA81AAFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85B4FFF3D51B11CD283A = {
+			fileRef = 01FA819EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85B5FFF3D51B11CD283A = {
+			fileRef = 01FA81A0FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85B6FFF3D51B11CD283A = {
+			fileRef = 01FA81A2FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85B7FFF3D51B11CD283A = {
+			fileRef = 01FA81A4FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85B8FFF3D51B11CD283A = {
+			fileRef = 01FA81A9FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85B9FFF3D54811CD283A = {
+			fileRef = 01FA81B3FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85BAFFF3D54811CD283A = {
+			fileRef = 01FA81B5FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85BBFFF3D54811CD283A = {
+			fileRef = 01FA81B9FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85BCFFF3D54811CD283A = {
+			fileRef = 01FA81B2FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85BDFFF3D54811CD283A = {
+			fileRef = 01FA81B4FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85BEFFF3D54811CD283A = {
+			fileRef = 01FA81B8FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85BFFFF3D5ED11CD283A = {
+			fileRef = 01FA81BDFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C0FFF3D5ED11CD283A = {
+			fileRef = 01FA8219FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C1FFF3D5ED11CD283A = {
+			fileRef = 01FA821BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C2FFF3D5ED11CD283A = {
+			fileRef = 01FA821DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C3FFF3D5ED11CD283A = {
+			fileRef = 01FA821EFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C4FFF3D5ED11CD283A = {
+			fileRef = 01FA8221FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C5FFF3D5ED11CD283A = {
+			fileRef = 01FA8223FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C6FFF3D5ED11CD283A = {
+			fileRef = 01FA8225FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C7FFF3D5ED11CD283A = {
+			fileRef = 125E85A9FFF3CDEF11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85C8FFF3D5ED11CD283A = {
+			fileRef = 01FA81BCFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85C9FFF3D5ED11CD283A = {
+			fileRef = 01FA8214FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85CAFFF3D5ED11CD283A = {
+			fileRef = 01FA8218FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85CCFFF3D5ED11CD283A = {
+			fileRef = 01FA8220FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85CDFFF3D5ED11CD283A = {
+			fileRef = 01FA8222FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85CEFFF3D5ED11CD283A = {
+			fileRef = 01FA8224FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85CFFFF3D5ED11CD283A = {
+			fileRef = 01FA823AFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85D0FFF3D5ED11CD283A = {
+			fileRef = 125E85A8FFF3CDEF11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85D1FFF3D5ED11CD283A = {
+			fileRef = 01FA891BFFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85D4FFF3D67D11CD283A = {
+			isa = PBXLibraryReference;
+			path = libSecurityAgentServer.a;
+			refType = 3;
+		};
+		125E85D5FFF3D67D11CD283A = {
+			buildPhases = (
+				125E85D6FFF3D67D11CD283A,
+				125E85D7FFF3D67D11CD283A,
+				125E85D9FFF3D67D11CD283A,
+				125E85DAFFF3D67D11CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				HEADER_SEARCH_PATHS = "\"$(SYMROOT)/include\"";
+				INSTALL_PATH = /usr/local/lib;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libSecurityAgentServer.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				125E85DCFFF3D76D11CD283A,
+			);
+			isa = PBXLibraryTarget;
+			name = "SecurityAgent Server";
+			productInstallPath = /usr/local/lib;
+			productName = "SecurityAgent Server";
+			productReference = 125E85D4FFF3D67D11CD283A;
+			shouldUseHeadermap = 1;
+		};
+		125E85D6FFF3D67D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				125E8606FFF3DB3E11CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		125E85D7FFF3D67D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				125E85D8FFF3D67D11CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		125E85D8FFF3D67D11CD283A = {
+			fileRef = 01FA8917FFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85D9FFF3D67D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		125E85DAFFF3D67D11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		125E85DCFFF3D76D11CD283A = {
+			isa = PBXTargetDependency;
+			target = 01FA88F0FFF2B96911CD283A;
+		};
+		125E85EAFFF3D8B711CD283A = {
+			fileRef = 01FA81E5FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85EBFFF3D8B711CD283A = {
+			fileRef = 01FA81E6FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85ECFFF3D8B711CD283A = {
+			fileRef = 01FA81E9FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85EEFFF3D8B711CD283A = {
+			fileRef = 01FA81EFFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85F0FFF3D8B711CD283A = {
+			fileRef = 01FA81FEFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85F1FFF3D8B711CD283A = {
+			fileRef = 01FA820DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85F2FFF3D8B711CD283A = {
+			fileRef = 01FA8210FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85F3FFF3D8B711CD283A = {
+			fileRef = 01FA8213FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E85FAFFF3D8B711CD283A = {
+			fileRef = 01FA81E4FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85FBFFF3D8B711CD283A = {
+			fileRef = 01FA81E8FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85FDFFF3D8B711CD283A = {
+			fileRef = 01FA81EEFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E85FFFFF3D8B711CD283A = {
+			fileRef = 01FA81F8FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E8600FFF3D8B711CD283A = {
+			fileRef = 01FA81FBFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E8601FFF3D8B711CD283A = {
+			fileRef = 01FA81FDFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E8602FFF3D8B711CD283A = {
+			fileRef = 01FA820CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E8603FFF3D8B711CD283A = {
+			fileRef = 01FA8212FFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		125E8604FFF3D96711CD283A = {
+			isa = PBXTargetDependency;
+			target = 125E85D5FFF3D67D11CD283A;
+		};
+		125E8605FFF3DAEF11CD283A = {
+			fileRef = 01FA823CFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		125E8606FFF3DB3E11CD283A = {
+			fileRef = 01FA821BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		127F63C50098D55A7F000001 = {
+			isa = PBXFileReference;
+			path = NullDigest.h;
+			refType = 4;
+		};
+		127F63C60098D55A7F000001 = {
+			fileRef = 127F63C50098D55A7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//120
+//121
+//122
+//123
+//124
+//160
+//161
+//162
+//163
+//164
+		1691956900947FD37F000001 = {
+			isa = PBXFileReference;
+			name = DigestObject.h;
+			path = AppleCSP/AppleCSP/DigestObject.h;
+			refType = 2;
+		};
+		1691956A00947FD37F000001 = {
+			fileRef = 1691956900947FD37F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691956B009480BC7F000001 = {
+			isa = PBXFileReference;
+			name = RawSigner.h;
+			path = AppleCSP/AppleCSP/RawSigner.h;
+			refType = 2;
+		};
+		1691956C009480BC7F000001 = {
+			fileRef = 1691956B009480BC7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691956D009485A47F000001 = {
+			isa = PBXFileReference;
+			path = SignatureContext.h;
+			refType = 4;
+		};
+		1691956E009485A47F000001 = {
+			fileRef = 1691956D009485A47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691956F009486767F000001 = {
+			isa = PBXFileReference;
+			path = SignatureContext.cpp;
+			refType = 4;
+		};
+		16919570009486767F000001 = {
+			fileRef = 1691956F009486767F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195710094A2ED7F000001 = {
+			children = (
+				59375E6D00A849237F000001,
+				2C5247ED007A39B47F000001,
+				2C5247EC007A39B47F000001,
+				2C5247EE007A39B47F000001,
+				57FCEE8B007A7B2F7F000001,
+				52BFC306007A6A1B7F000001,
+				4A4C766D007A4E317F000001,
+				4A4C766C007A4E317F000001,
+				4A4C7672007A4E657F000001,
+			);
+			isa = PBXGroup;
+			name = misc;
+			path = "";
+			refType = 4;
+		};
+		169195720094A2ED7F000001 = {
+			children = (
+				169195DF0094A8577F000001,
+				169195E00094A8577F000001,
+				169195E10094A8577F000001,
+				169195E20094A8577F000001,
+				169195E40094A8577F000001,
+				169195E50094A8577F000001,
+				169195E60094A8577F000001,
+				169195E70094A8577F000001,
+				169195E80094A8577F000001,
+				169195E90094A8577F000001,
+				169195EA0094A8577F000001,
+				59375E6E00A849237F000001,
+				169195EB0094A8577F000001,
+				2C5247EB007A39B47F000001,
+				169195EC0094A8577F000001,
+				01D5634800974F7C7F000001,
+				169195EE0094A8577F000001,
+				2C5247EF007A39B47F000001,
+				52BFC304007A6A1B7F000001,
+				4A4C766E007A4E317F000001,
+				169195EF0094A8577F000001,
+				169195F00094A8577F000001,
+				169195F10094A8577F000001,
+				07E4D6E400A0CD8D7F000001,
+				169195F30094A8577F000001,
+				169195F20094A8577F000001,
+			);
+			isa = PBXGroup;
+			name = openssl;
+			refType = 4;
+		};
+		169195730094A5A87F000001 = {
+			children = (
+				169195740094A5A87F000001,
+			);
+			isa = PBXGroup;
+			name = stack;
+			refType = 4;
+		};
+		169195740094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = stack.c;
+			path = stack/stack.c;
+			refType = 4;
+		};
+		169195750094A5A87F000001 = {
+			children = (
+				169195760094A5A87F000001,
+				169195770094A5A87F000001,
+				169195780094A5A87F000001,
+				169195790094A5A87F000001,
+				1691957A0094A5A87F000001,
+				1691957B0094A5A87F000001,
+				1691957C0094A5A87F000001,
+				1691957E0094A5A87F000001,
+				1691957F0094A5A87F000001,
+				169195800094A5A87F000001,
+				169195810094A5A87F000001,
+			);
+			isa = PBXGroup;
+			name = rsa;
+			refType = 4;
+		};
+		169195760094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_chk.c;
+			path = rsa/rsa_chk.c;
+			refType = 4;
+		};
+		169195770094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_eay.c;
+			path = rsa/rsa_eay.c;
+			refType = 4;
+		};
+		169195780094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_err.c;
+			path = rsa/rsa_err.c;
+			refType = 4;
+		};
+		169195790094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_gen.c;
+			path = rsa/rsa_gen.c;
+			refType = 4;
+		};
+		1691957A0094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_lib.c;
+			path = rsa/rsa_lib.c;
+			refType = 4;
+		};
+		1691957B0094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_none.c;
+			path = rsa/rsa_none.c;
+			refType = 4;
+		};
+		1691957C0094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_null.c;
+			path = rsa/rsa_null.c;
+			refType = 4;
+		};
+		1691957E0094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_pk1.c;
+			path = rsa/rsa_pk1.c;
+			refType = 4;
+		};
+		1691957F0094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_saos.c;
+			path = rsa/rsa_saos.c;
+			refType = 4;
+		};
+		169195800094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_sign.c;
+			path = rsa/rsa_sign.c;
+			refType = 4;
+		};
+		169195810094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = rsa_ssl.c;
+			path = rsa/rsa_ssl.c;
+			refType = 4;
+		};
+		169195820094A5A87F000001 = {
+			children = (
+				169195830094A5A87F000001,
+			);
+			isa = PBXGroup;
+			name = lhash;
+			refType = 4;
+		};
+		169195830094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = lhash.c;
+			path = lhash/lhash.c;
+			refType = 4;
+		};
+		169195840094A5A87F000001 = {
+			children = (
+				169195860094A5A87F000001,
+				169195870094A5A87F000001,
+			);
+			isa = PBXGroup;
+			name = err;
+			refType = 4;
+		};
+		169195860094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = err_prn.c;
+			path = err/err_prn.c;
+			refType = 4;
+		};
+		169195870094A5A87F000001 = {
+			isa = PBXFileReference;
+			name = err.c;
+			path = err/err.c;
+			refType = 4;
+		};
+		169195880094A5A87F000001 = {
+			children = (
+				1691959C0094A63C7F000001,
+				1691959D0094A63C7F000001,
+				1691959E0094A63C7F000001,
+				1691959F0094A63C7F000001,
+				169195A00094A63C7F000001,
+				169195A10094A63C7F000001,
+				169195A20094A63C7F000001,
+				169195A30094A63C7F000001,
+				169195A40094A63C7F000001,
+				169195A50094A63C7F000001,
+				169195A60094A63C7F000001,
+				169195A70094A63C7F000001,
+				169195A80094A63C7F000001,
+				169195A90094A63C7F000001,
+				169195AA0094A63C7F000001,
+				169195AB0094A63C7F000001,
+				169195AC0094A63C7F000001,
+				169195AD0094A63C7F000001,
+				169195AE0094A63C7F000001,
+				169195AF0094A63C7F000001,
+				169195B00094A63C7F000001,
+				169195B10094A63C7F000001,
+			);
+			isa = PBXGroup;
+			name = bn;
+			refType = 4;
+		};
+		169195890094A5A87F000001 = {
+			children = (
+				169195B20094A63C7F000001,
+				169195B30094A63C7F000001,
+			);
+			isa = PBXGroup;
+			name = bio;
+			refType = 4;
+		};
+		1691958A0094A5A87F000001 = {
+			children = (
+				169195B40094A63C7F000001,
+				169195B50094A63C7F000001,
+			);
+			isa = PBXGroup;
+			name = buffer;
+			path = "";
+			refType = 4;
+		};
+		1691958B0094A5A87F000001 = {
+			fileRef = 169195740094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691958C0094A5A87F000001 = {
+			fileRef = 169195760094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691958D0094A5A87F000001 = {
+			fileRef = 169195770094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691958E0094A5A87F000001 = {
+			fileRef = 169195780094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691958F0094A5A87F000001 = {
+			fileRef = 169195790094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195900094A5A87F000001 = {
+			fileRef = 1691957A0094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195910094A5A87F000001 = {
+			fileRef = 1691957B0094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195920094A5A87F000001 = {
+			fileRef = 1691957C0094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195940094A5A87F000001 = {
+			fileRef = 1691957E0094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195950094A5A87F000001 = {
+			fileRef = 1691957F0094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195960094A5A87F000001 = {
+			fileRef = 169195800094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195970094A5A87F000001 = {
+			fileRef = 169195810094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195980094A5A87F000001 = {
+			fileRef = 169195830094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691959A0094A5A87F000001 = {
+			fileRef = 169195860094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691959B0094A5A87F000001 = {
+			fileRef = 169195870094A5A87F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1691959C0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_add.c;
+			path = bn/bn_add.c;
+			refType = 4;
+		};
+		1691959D0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_asm.c;
+			path = bn/bn_asm.c;
+			refType = 4;
+		};
+		1691959E0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_blind.c;
+			path = bn/bn_blind.c;
+			refType = 4;
+		};
+		1691959F0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_ctx.c;
+			path = bn/bn_ctx.c;
+			refType = 4;
+		};
+		169195A00094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_div.c;
+			path = bn/bn_div.c;
+			refType = 4;
+		};
+		169195A10094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_err.c;
+			path = bn/bn_err.c;
+			refType = 4;
+		};
+		169195A20094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_exp.c;
+			path = bn/bn_exp.c;
+			refType = 4;
+		};
+		169195A30094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_exp2.c;
+			path = bn/bn_exp2.c;
+			refType = 4;
+		};
+		169195A40094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_gcd.c;
+			path = bn/bn_gcd.c;
+			refType = 4;
+		};
+		169195A50094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_lcl.h;
+			path = bn/bn_lcl.h;
+			refType = 4;
+		};
+		169195A60094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_lib.c;
+			path = bn/bn_lib.c;
+			refType = 4;
+		};
+		169195A70094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_mont.c;
+			path = bn/bn_mont.c;
+			refType = 4;
+		};
+		169195A80094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_mpi.c;
+			path = bn/bn_mpi.c;
+			refType = 4;
+		};
+		169195A90094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_mul.c;
+			path = bn/bn_mul.c;
+			refType = 4;
+		};
+		169195AA0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_prime.c;
+			path = bn/bn_prime.c;
+			refType = 4;
+		};
+		169195AB0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_prime.h;
+			path = bn/bn_prime.h;
+			refType = 4;
+		};
+		169195AC0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_print.c;
+			path = bn/bn_print.c;
+			refType = 4;
+		};
+		169195AD0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_rand.c;
+			path = bn/bn_rand.c;
+			refType = 4;
+		};
+		169195AE0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_recp.c;
+			path = bn/bn_recp.c;
+			refType = 4;
+		};
+		169195AF0094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_shift.c;
+			path = bn/bn_shift.c;
+			refType = 4;
+		};
+		169195B00094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_sqr.c;
+			path = bn/bn_sqr.c;
+			refType = 4;
+		};
+		169195B10094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bn_word.c;
+			path = bn/bn_word.c;
+			refType = 4;
+		};
+		169195B20094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bio_lib.c;
+			path = bio/bio_lib.c;
+			refType = 4;
+		};
+		169195B30094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = bss_file.c;
+			path = bio/bss_file.c;
+			refType = 4;
+		};
+		169195B40094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = buf_err.c;
+			path = buffer/buf_err.c;
+			refType = 4;
+		};
+		169195B50094A63C7F000001 = {
+			isa = PBXFileReference;
+			name = buffer.c;
+			path = buffer/buffer.c;
+			refType = 4;
+		};
+		169195B60094A63C7F000001 = {
+			fileRef = 169195A50094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195B70094A63C7F000001 = {
+			fileRef = 169195AB0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195B80094A63C7F000001 = {
+			fileRef = 1691959C0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195B90094A63C7F000001 = {
+			fileRef = 1691959D0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195BA0094A63C7F000001 = {
+			fileRef = 1691959E0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195BB0094A63C7F000001 = {
+			fileRef = 1691959F0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195BC0094A63C7F000001 = {
+			fileRef = 169195A00094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195BD0094A63C7F000001 = {
+			fileRef = 169195A10094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195BE0094A63C7F000001 = {
+			fileRef = 169195A20094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195BF0094A63C7F000001 = {
+			fileRef = 169195A30094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C00094A63C7F000001 = {
+			fileRef = 169195A40094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C10094A63C7F000001 = {
+			fileRef = 169195A60094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C20094A63C7F000001 = {
+			fileRef = 169195A70094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C30094A63C7F000001 = {
+			fileRef = 169195A80094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C40094A63C7F000001 = {
+			fileRef = 169195A90094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C50094A63C7F000001 = {
+			fileRef = 169195AA0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C60094A63C7F000001 = {
+			fileRef = 169195AC0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C70094A63C7F000001 = {
+			fileRef = 169195AD0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C80094A63C7F000001 = {
+			fileRef = 169195AE0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195C90094A63C7F000001 = {
+			fileRef = 169195AF0094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195CA0094A63C7F000001 = {
+			fileRef = 169195B00094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195CB0094A63C7F000001 = {
+			fileRef = 169195B10094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195CC0094A63C7F000001 = {
+			fileRef = 169195B20094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195CD0094A63C7F000001 = {
+			fileRef = 169195B30094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195CE0094A63C7F000001 = {
+			fileRef = 169195B40094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195CF0094A63C7F000001 = {
+			fileRef = 169195B50094A63C7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195D00094A6FD7F000001 = {
+			children = (
+				169195D70094A7427F000001,
+				169195D80094A7427F000001,
+				169195D90094A7427F000001,
+				169195DA0094A7427F000001,
+			);
+			isa = PBXGroup;
+			name = opensslUtils;
+			refType = 4;
+		};
+		169195D10094A6FD7F000001 = {
+			isa = PBXFileReference;
+			path = cryptlib.c;
+			refType = 4;
+		};
+		169195D20094A6FD7F000001 = {
+			isa = PBXFileReference;
+			path = ex_data.c;
+			refType = 4;
+		};
+		169195D30094A6FD7F000001 = {
+			isa = PBXFileReference;
+			path = mem.c;
+			refType = 4;
+		};
+		169195D40094A6FD7F000001 = {
+			fileRef = 169195D10094A6FD7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195D50094A6FD7F000001 = {
+			fileRef = 169195D20094A6FD7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195D60094A6FD7F000001 = {
+			fileRef = 169195D30094A6FD7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195D70094A7427F000001 = {
+			isa = PBXFileReference;
+			name = opensslUtils.cpp;
+			path = opensslUtils/opensslUtils.cpp;
+			refType = 4;
+		};
+		169195D80094A7427F000001 = {
+			isa = PBXFileReference;
+			name = opensslUtils.h;
+			path = opensslUtils/opensslUtils.h;
+			refType = 4;
+		};
+		169195D90094A7427F000001 = {
+			isa = PBXFileReference;
+			name = openRsaSnacc.cpp;
+			path = opensslUtils/openRsaSnacc.cpp;
+			refType = 4;
+		};
+		169195DA0094A7427F000001 = {
+			isa = PBXFileReference;
+			name = openRsaSnacc.h;
+			path = opensslUtils/openRsaSnacc.h;
+			refType = 4;
+		};
+		169195DB0094A7427F000001 = {
+			fileRef = 169195D80094A7427F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195DC0094A7427F000001 = {
+			fileRef = 169195DA0094A7427F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195DD0094A7427F000001 = {
+			fileRef = 169195D70094A7427F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195DE0094A7427F000001 = {
+			fileRef = 169195D90094A7427F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195DF0094A8577F000001 = {
+			isa = PBXFileReference;
+			name = asn1.h;
+			path = openssl/asn1.h;
+			refType = 4;
+		};
+		169195E00094A8577F000001 = {
+			isa = PBXFileReference;
+			name = bio.h;
+			path = openssl/bio.h;
+			refType = 4;
+		};
+		169195E10094A8577F000001 = {
+			isa = PBXFileReference;
+			name = bn.h;
+			path = openssl/bn.h;
+			refType = 4;
+		};
+		169195E20094A8577F000001 = {
+			isa = PBXFileReference;
+			name = buffer.h;
+			path = openssl/buffer.h;
+			refType = 4;
+		};
+		169195E30094A8577F000001 = {
+			isa = PBXFileReference;
+			path = cryptlib.h;
+			refType = 4;
+		};
+		169195E40094A8577F000001 = {
+			isa = PBXFileReference;
+			name = crypto.h;
+			path = openssl/crypto.h;
+			refType = 4;
+		};
+		169195E50094A8577F000001 = {
+			isa = PBXFileReference;
+			name = dsa.h;
+			path = openssl/dsa.h;
+			refType = 4;
+		};
+		169195E60094A8577F000001 = {
+			isa = PBXFileReference;
+			name = e_os.h;
+			path = openssl/e_os.h;
+			refType = 4;
+		};
+		169195E70094A8577F000001 = {
+			isa = PBXFileReference;
+			name = e_os2.h;
+			path = openssl/e_os2.h;
+			refType = 4;
+		};
+		169195E80094A8577F000001 = {
+			isa = PBXFileReference;
+			name = err.h;
+			path = openssl/err.h;
+			refType = 4;
+		};
+		169195E90094A8577F000001 = {
+			isa = PBXFileReference;
+			name = evp.h;
+			path = openssl/evp.h;
+			refType = 4;
+		};
+		169195EA0094A8577F000001 = {
+			isa = PBXFileReference;
+			name = lhash.h;
+			path = openssl/lhash.h;
+			refType = 4;
+		};
+		169195EB0094A8577F000001 = {
+			isa = PBXFileReference;
+			name = objects.h;
+			path = openssl/objects.h;
+			refType = 4;
+		};
+		169195EC0094A8577F000001 = {
+			isa = PBXFileReference;
+			name = opensslv.h;
+			path = openssl/opensslv.h;
+			refType = 4;
+		};
+		169195EE0094A8577F000001 = {
+			isa = PBXFileReference;
+			name = rand.h;
+			path = openssl/rand.h;
+			refType = 4;
+		};
+		169195EF0094A8577F000001 = {
+			isa = PBXFileReference;
+			name = rsa.h;
+			path = openssl/rsa.h;
+			refType = 4;
+		};
+		169195F00094A8577F000001 = {
+			isa = PBXFileReference;
+			name = safestack.h;
+			path = openssl/safestack.h;
+			refType = 4;
+		};
+		169195F10094A8577F000001 = {
+			isa = PBXFileReference;
+			name = stack.h;
+			path = openssl/stack.h;
+			refType = 4;
+		};
+		169195F20094A8577F000001 = {
+			isa = PBXFileReference;
+			name = x509_vfy.h;
+			path = openssl/x509_vfy.h;
+			refType = 4;
+		};
+		169195F30094A8577F000001 = {
+			isa = PBXFileReference;
+			name = x509.h;
+			path = openssl/x509.h;
+			refType = 4;
+		};
+		169195F40094A8577F000001 = {
+			fileRef = 169195DF0094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195F50094A8577F000001 = {
+			fileRef = 169195E00094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195F60094A8577F000001 = {
+			fileRef = 169195E10094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195F70094A8577F000001 = {
+			fileRef = 169195E20094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195F80094A8577F000001 = {
+			fileRef = 169195E30094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195F90094A8577F000001 = {
+			fileRef = 169195E40094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195FA0094A8577F000001 = {
+			fileRef = 169195E50094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195FB0094A8577F000001 = {
+			fileRef = 169195E60094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195FC0094A8577F000001 = {
+			fileRef = 169195E70094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195FD0094A8577F000001 = {
+			fileRef = 169195E80094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195FE0094A8577F000001 = {
+			fileRef = 169195E90094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169195FF0094A8577F000001 = {
+			fileRef = 169195EA0094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169196000094A8577F000001 = {
+			fileRef = 169195EB0094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169196010094A8577F000001 = {
+			fileRef = 169195EC0094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169196030094A8577F000001 = {
+			fileRef = 169195EE0094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169196040094A8577F000001 = {
+			fileRef = 169195EF0094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169196050094A8577F000001 = {
+			fileRef = 169195F00094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169196060094A8577F000001 = {
+			fileRef = 169195F10094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169196070094A8577F000001 = {
+			fileRef = 169195F20094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		169196080094A8577F000001 = {
+			fileRef = 169195F30094A8577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//160
+//161
+//162
+//163
+//164
+//1A0
+//1A1
+//1A2
+//1A3
+//1A4
+		1A23E785009758847F000001 = {
+			isa = PBXFileReference;
+			name = "libstdc++.a";
+			path = "/usr/lib/gcc/darwin/2.95.2/libstdc++.a";
+			refType = 0;
+		};
+		1A23E786009758847F000001 = {
+			fileRef = 1A23E785009758847F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1A23E787009758847F000001 = {
+			fileRef = 1A23E785009758847F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1A23E788009758847F000001 = {
+			fileRef = 1A23E785009758847F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//1A0
+//1A1
+//1A2
+//1A3
+//1A4
+//1B0
+//1B1
+//1B2
+//1B3
+//1B4
+		1B40D2E3FFF9716411CD283A = {
+			isa = PBXTargetDependency;
+			target = 030701E4FFF96F8511CD283A;
+		};
+		1B40D2E4FFF9716411CD283A = {
+			isa = PBXTargetDependency;
+			target = 01FA88F0FFF2B96911CD283A;
+		};
+		1BA451B10097605B7F000001 = {
+			isa = PBXFrameworkReference;
+			path = Security.framework;
+			refType = 3;
+		};
+		1BA451B20097605B7F000001 = {
+			fileRef = 1BA451B10097605B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		1BA451B30097605B7F000001 = {
+			fileRef = 1BA451B10097605B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//1B0
+//1B1
+//1B2
+//1B3
+//1B4
+//200
+//201
+//202
+//203
+//204
+		209FCB4E00A738117F000001 = {
+			isa = PBXFileReference;
+			name = MacContext.h;
+			path = MiscCSPAlgs/MacContext.h;
+			refType = 4;
+		};
+		209FCB4F00A738117F000001 = {
+			fileRef = 209FCB4E00A738117F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		209FCB5000A739657F000001 = {
+			isa = PBXFileReference;
+			name = MacContext.cpp;
+			path = AppleCSP/MiscCSPAlgs/MacContext.cpp;
+			refType = 2;
+		};
+		209FCB5100A739657F000001 = {
+			fileRef = 209FCB5000A739657F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//200
+//201
+//202
+//203
+//204
+//210
+//211
+//212
+//213
+//214
+		21306AAD0030B27011CD283A = {
+			isa = PBXFileReference;
+			path = Localizable.strings;
+			refType = 4;
+		};
+		21781539008B941B7F000001 = {
+			isa = PBXFileReference;
+			path = "http-proxy-protocol.h";
+			refType = 4;
+		};
+		2178153A008B941B7F000001 = {
+			isa = PBXFileReference;
+			path = "http-proxy-protocol.cpp";
+			refType = 4;
+		};
+		2178153B008B941B7F000001 = {
+			fileRef = 21781539008B941B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		2178153C008B941B7F000001 = {
+			fileRef = 2178153A008B941B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//210
+//211
+//212
+//213
+//214
+//250
+//251
+//252
+//253
+//254
+		256C38AB0094AE067F000001 = {
+			children = (
+				256C38AC0094AE787F000001,
+				256C38AD0094AE787F000001,
+				256C38AE0094AE787F000001,
+				256C38AF0094AE787F000001,
+				28B044DF0094C5577F000001,
+				28B044E10094C6C57F000001,
+				256C38B60094B96F7F000001,
+				256C38B40094B2537F000001,
+				28B044E30094DC627F000001,
+				28B044E40094DC627F000001,
+			);
+			isa = PBXGroup;
+			name = RSA_DSA;
+			refType = 4;
+		};
+		256C38AC0094AE787F000001 = {
+			isa = PBXFileReference;
+			name = RSA_DSA_csp.h;
+			path = RSA_DSA/RSA_DSA_csp.h;
+			refType = 4;
+		};
+		256C38AD0094AE787F000001 = {
+			isa = PBXFileReference;
+			name = RSA_DSA_csp.cpp;
+			path = RSA_DSA/RSA_DSA_csp.cpp;
+			refType = 4;
+		};
+		256C38AE0094AE787F000001 = {
+			isa = PBXFileReference;
+			name = RSA_DSA_keys.cpp;
+			path = RSA_DSA/RSA_DSA_keys.cpp;
+			refType = 4;
+		};
+		256C38AF0094AE787F000001 = {
+			isa = PBXFileReference;
+			name = RSA_DSA_keys.h;
+			path = RSA_DSA/RSA_DSA_keys.h;
+			refType = 4;
+		};
+		256C38B00094AE787F000001 = {
+			fileRef = 256C38AC0094AE787F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		256C38B10094AE787F000001 = {
+			fileRef = 256C38AF0094AE787F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		256C38B20094AE787F000001 = {
+			fileRef = 256C38AD0094AE787F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		256C38B30094AE787F000001 = {
+			fileRef = 256C38AE0094AE787F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		256C38B40094B2537F000001 = {
+			isa = PBXFileReference;
+			name = RSA_DSA_utils.h;
+			path = AppleCSP/RSA_DSA/RSA_DSA_utils.h;
+			refType = 2;
+		};
+		256C38B50094B2537F000001 = {
+			fileRef = 256C38B40094B2537F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		256C38B60094B96F7F000001 = {
+			isa = PBXFileReference;
+			name = RSA_DSA_utils.cpp;
+			path = AppleCSP/RSA_DSA/RSA_DSA_utils.cpp;
+			refType = 2;
+		};
+		256C38B70094B96F7F000001 = {
+			fileRef = 256C38B60094B96F7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//250
+//251
+//252
+//253
+//254
+//280
+//281
+//282
+//283
+//284
+		28B044DF0094C5577F000001 = {
+			isa = PBXFileReference;
+			name = RSA_DSA_signature.h;
+			path = AppleCSP/RSA_DSA/RSA_DSA_signature.h;
+			refType = 2;
+		};
+		28B044E00094C5577F000001 = {
+			fileRef = 28B044DF0094C5577F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		28B044E10094C6C57F000001 = {
+			isa = PBXFileReference;
+			name = RSA_DSA_signature.cpp;
+			path = AppleCSP/RSA_DSA/RSA_DSA_signature.cpp;
+			refType = 2;
+		};
+		28B044E20094C6C57F000001 = {
+			fileRef = 28B044E10094C6C57F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		28B044E30094DC627F000001 = {
+			isa = PBXFileReference;
+			name = RSA_asymmetric.cpp;
+			path = RSA_DSA/RSA_asymmetric.cpp;
+			refType = 4;
+		};
+		28B044E40094DC627F000001 = {
+			isa = PBXFileReference;
+			name = RSA_asymmetric.h;
+			path = RSA_DSA/RSA_asymmetric.h;
+			refType = 4;
+		};
+		28B044E50094DC627F000001 = {
+			fileRef = 28B044E40094DC627F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		28B044E60094DC627F000001 = {
+			fileRef = 28B044E30094DC627F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//280
+//281
+//282
+//283
+//284
+//2C0
+//2C1
+//2C2
+//2C3
+//2C4
+		2C5247EA007A39B47F000001 = {
+			children = (
+				07E4D6D300A0CA617F000001,
+				169195D00094A6FD7F000001,
+				169195890094A5A87F000001,
+				169195880094A5A87F000001,
+				1691958A0094A5A87F000001,
+				169195840094A5A87F000001,
+				169195820094A5A87F000001,
+				169195710094A2ED7F000001,
+				169195750094A5A87F000001,
+				169195730094A5A87F000001,
+				169195720094A2ED7F000001,
+				169195D10094A6FD7F000001,
+				169195E30094A8577F000001,
+				169195D20094A6FD7F000001,
+				169195D30094A6FD7F000001,
+			);
+			isa = PBXGroup;
+			path = open_ssl;
+			refType = 4;
+		};
+		2C5247EB007A39B47F000001 = {
+			isa = PBXFileReference;
+			name = opensslconf.h;
+			path = openssl/opensslconf.h;
+			refType = 4;
+		};
+		2C5247EC007A39B47F000001 = {
+			isa = PBXFileReference;
+			name = rc2_cbc.c;
+			path = misc/rc2_cbc.c;
+			refType = 4;
+		};
+		2C5247ED007A39B47F000001 = {
+			isa = PBXFileReference;
+			name = rc2_locl.h;
+			path = misc/rc2_locl.h;
+			refType = 4;
+		};
+		2C5247EE007A39B47F000001 = {
+			isa = PBXFileReference;
+			name = rc2_skey.c;
+			path = misc/rc2_skey.c;
+			refType = 4;
+		};
+		2C5247EF007A39B47F000001 = {
+			isa = PBXFileReference;
+			name = rc2.h;
+			path = openssl/rc2.h;
+			refType = 4;
+		};
+		2C5247F0007A39B47F000001 = {
+			isa = PBXFileReference;
+			name = rc2Context.cpp;
+			path = MiscCSPAlgs/rc2Context.cpp;
+			refType = 4;
+		};
+		2C5247F1007A39B47F000001 = {
+			isa = PBXFileReference;
+			name = rc2Context.h;
+			path = MiscCSPAlgs/rc2Context.h;
+			refType = 4;
+		};
+		2C5247F2007A39B47F000001 = {
+			fileRef = 2C5247EB007A39B47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2C5247F3007A39B47F000001 = {
+			fileRef = 2C5247ED007A39B47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2C5247F4007A39B47F000001 = {
+			fileRef = 2C5247EF007A39B47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2C5247F5007A39B47F000001 = {
+			fileRef = 2C5247F1007A39B47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2C5247F6007A39B47F000001 = {
+			fileRef = 2C5247EC007A39B47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2C5247F7007A39B47F000001 = {
+			fileRef = 2C5247EE007A39B47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2C5247F8007A39B47F000001 = {
+			fileRef = 2C5247F0007A39B47F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//2C0
+//2C1
+//2C2
+//2C3
+//2C4
+//2D0
+//2D1
+//2D2
+//2D3
+//2D4
+		2DFDC7A8FFF3E4ED11CD283A = {
+			fileRef = 01FA821DFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+//2D0
+//2D1
+//2D2
+//2D3
+//2D4
+//2F0
+//2F1
+//2F2
+//2F3
+//2F4
+		2F4DD9A500A0A0767F000001 = {
+			isa = PBXFileReference;
+			path = fdsel.h;
+			refType = 4;
+		};
+		2F4DD9A600A0A0767F000001 = {
+			isa = PBXFileReference;
+			path = fdsel.cpp;
+			refType = 4;
+		};
+		2F4DD9A700A0A0767F000001 = {
+			fileRef = 2F4DD9A500A0A0767F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		2F4DD9A800A0A0767F000001 = {
+			fileRef = 2F4DD9A600A0A0767F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//2F0
+//2F1
+//2F2
+//2F3
+//2F4
+//310
+//311
+//312
+//313
+//314
+		31200C5CFFF3E57C11CD283A = {
+			fileRef = 01FA891FFFF2BE3511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+//310
+//311
+//312
+//313
+//314
+//320
+//321
+//322
+//323
+//324
+		320C8FE900EA6AD705CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OPTIMIZATION_CFLAGS = "-O2";
+				OTHER_CFLAGS = "\U0001-DNDEBUG -Wall -W -Winline -Wundef -Wno-unused -Wcast-qual -Wcast-align -Wmissing-noreturn";
+			};
+			isa = PBXBuildStyle;
+			name = "Lint Screen";
+		};
+		325EAA2100D6B08805CD296C = {
+			isa = PBXBundleReference;
+			path = AppleCSP.bundle;
+			refType = 3;
+		};
+		325EAA2200D6B08805CD296C = {
+			buildPhases = (
+				325EAA2400D6B08805CD296C,
+				325EAA2500D6B08805CD296C,
+				325EAA2600D6B08805CD296C,
+				325EAA2700D6B08805CD296C,
+				325EAA2800D6B08805CD296C,
+			);
+			buildSettings = {
+				LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/2.95.2;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-bundle -undefined error";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleCSP;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = bundle;
+			};
+			dependencies = (
+				325EAA2300D6B08805CD296C,
+			);
+			isa = PBXBundleTarget;
+			name = "AppleCSP Plugin";
+			productName = "AppleCSP Plugin";
+			productReference = 325EAA2100D6B08805CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AppleCSP</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		325EAA2300D6B08805CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880CD005EAE4D11CD283A;
+		};
+		325EAA2400D6B08805CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		325EAA2500D6B08805CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		325EAA2600D6B08805CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				325EAA3800D6B47505CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		325EAA2700D6B08805CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				325EAA3300D6B2BF05CD296C,
+				325EAA3400D6B2BF05CD296C,
+				325EAA3500D6B2BF05CD296C,
+				325EAA3600D6B2BF05CD296C,
+				3290381400D6B78A05CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		325EAA2800D6B08805CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		325EAA2900D6B23F05CD296C = {
+			children = (
+				0149036600A9E34D7F000001,
+				0149036700A9E34D7F000001,
+			);
+			isa = PBXGroup;
+			name = "From BSafe";
+			refType = 4;
+		};
+		325EAA2A00D6B24005CD296C = {
+			fileRef = 014880C7005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA2B00D6B24005CD296C = {
+			fileRef = 014880C8005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA2C00D6B24005CD296C = {
+			fileRef = 014880C9005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA2D00D6B24005CD296C = {
+			fileRef = 014880CA005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA2E00D6B24005CD296C = {
+			fileRef = 014880CB005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA3100D6B2BE05CD296C = {
+			children = (
+				014880C7005EAE4D11CD283A,
+				014880C8005EAE4D11CD283A,
+				014880C9005EAE4D11CD283A,
+				014880CA005EAE4D11CD283A,
+				014880CB005EAE4D11CD283A,
+			);
+			isa = PBXGroup;
+			name = "Plugins as Libraries";
+			path = "";
+			refType = 4;
+		};
+		325EAA3200D6B2BE05CD296C = {
+			children = (
+				325EAA2100D6B08805CD296C,
+				3290381500D6BA5905CD296C,
+				3290381600D6BA5905CD296C,
+				3290381700D6BA5905CD296C,
+				3290381800D6BA5905CD296C,
+			);
+			isa = PBXGroup;
+			name = "Plugins Proper";
+			refType = 4;
+		};
+		325EAA3300D6B2BF05CD296C = {
+			fileRef = 014880C7005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA3400D6B2BF05CD296C = {
+			fileRef = 0149036600A9E34D7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA3500D6B2BF05CD296C = {
+			fileRef = 0149036700A9E34D7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA3600D6B2BF05CD296C = {
+			fileRef = 1A23E785009758847F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		325EAA3700D6B47405CD296C = {
+			isa = PBXFileReference;
+			path = AppleCSPPlugin.cpp;
+			refType = 4;
+		};
+		325EAA3800D6B47505CD296C = {
+			fileRef = 325EAA3700D6B47405CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		32604C2600E3C14405CD296C = {
+			isa = PBXFileReference;
+			path = devrandom.cpp;
+			refType = 4;
+		};
+		32604C2700E3C14405CD296C = {
+			isa = PBXFileReference;
+			path = devrandom.h;
+			refType = 4;
+		};
+		32604C2800E3C14505CD296C = {
+			fileRef = 32604C2700E3C14405CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		32604C2900E3C14505CD296C = {
+			fileRef = 32604C2600E3C14405CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		32615BB000E3B46905CD296C = {
+			isa = PBXFileReference;
+			path = yarrowseed.h;
+			refType = 4;
+		};
+		32615BB100E3B46A05CD296C = {
+			fileRef = 32615BB000E3B46905CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		32615BB200E3B4A105CD296C = {
+			isa = PBXFileReference;
+			path = yarrowseed.cpp;
+			refType = 4;
+		};
+		32615BB300E3B4A205CD296C = {
+			fileRef = 32615BB200E3B4A105CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3264486400D54DD305CD296C = {
+			isa = PBXFileReference;
+			path = multiobserver.h;
+			refType = 4;
+		};
+		3264486500D54DD305CD296C = {
+			isa = PBXFileReference;
+			path = multiobserver.cpp;
+			refType = 4;
+		};
+		3264486600D54DD305CD296C = {
+			fileRef = 3264486400D54DD305CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		3264486700D54DD305CD296C = {
+			fileRef = 3264486500D54DD305CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3267644800EBF3A905CD296C = {
+			isa = PBXFileReference;
+			path = AuthSession.h;
+			refType = 4;
+		};
+		3267644900EBF3AA05CD296C = {
+			fileRef = 3267644800EBF3A905CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		3272260900E3C75605CD296C = {
+			isa = PBXFileReference;
+			path = uniformrandom.cpp;
+			refType = 4;
+		};
+		3272260A00E3C75605CD296C = {
+			isa = PBXFileReference;
+			path = uniformrandom.h;
+			refType = 4;
+		};
+		3272260B00E3C75605CD296C = {
+			fileRef = 3272260A00E3C75605CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		3272260C00E3C75705CD296C = {
+			fileRef = 3272260900E3C75605CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3272260D00E3C7FB05CD296C = {
+			children = (
+				32604C2600E3C14405CD296C,
+				32604C2700E3C14405CD296C,
+				3272260900E3C75605CD296C,
+				3272260A00E3C75605CD296C,
+			);
+			isa = PBXGroup;
+			name = "Random Numbers";
+			path = "";
+			refType = 4;
+		};
+		327DDDBD00D6D8E605CD296C = {
+			children = (
+				3290386E00D6C5FD05CD296C,
+				3290386F00D6C5FD05CD296C,
+				327DDDDF00D6F8A505CD296C,
+				327DDDE000D6F8A505CD296C,
+				327DDDE100D6F8A505CD296C,
+				327DDDE200D6F8A505CD296C,
+			);
+			isa = PBXGroup;
+			name = "Module Loading";
+			refType = 4;
+		};
+		327DDDDF00D6F8A505CD296C = {
+			isa = PBXFileReference;
+			path = modload_plugin.cpp;
+			refType = 4;
+		};
+		327DDDE000D6F8A505CD296C = {
+			isa = PBXFileReference;
+			path = modload_plugin.h;
+			refType = 4;
+		};
+		327DDDE100D6F8A505CD296C = {
+			isa = PBXFileReference;
+			path = modload_static.cpp;
+			refType = 4;
+		};
+		327DDDE200D6F8A505CD296C = {
+			isa = PBXFileReference;
+			path = modload_static.h;
+			refType = 4;
+		};
+		327DDDE300D6F8A605CD296C = {
+			fileRef = 327DDDE000D6F8A505CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		327DDDE400D6F8A605CD296C = {
+			fileRef = 327DDDE200D6F8A505CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		327DDDE500D6F8A605CD296C = {
+			fileRef = 327DDDDF00D6F8A505CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		327DDDE600D6F8A605CD296C = {
+			fileRef = 327DDDE100D6F8A505CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		327DDDE700D6FC1A05CD296C = {
+			isa = PBXFileReference;
+			path = AppleCSPDLPlugin.cpp;
+			refType = 4;
+		};
+		327DDDE800D6FC1B05CD296C = {
+			fileRef = 327DDDE700D6FC1A05CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		327DDDF500D707D805CD296C = {
+			fileRef = 07A0F68C005DAEE111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		327DDDF600D7DB7505CD296C = {
+			isa = PBXFileReference;
+			path = powerwatch.cpp;
+			refType = 4;
+		};
+		327DDDF700D7DB7505CD296C = {
+			isa = PBXFileReference;
+			path = powerwatch.h;
+			refType = 4;
+		};
+		327DDDF800D7DB7505CD296C = {
+			fileRef = 327DDDF700D7DB7505CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		327DDDF900D7DB7605CD296C = {
+			fileRef = 327DDDF600D7DB7505CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		327DDDFA00D7E81F05CD296C = {
+			isa = PBXFrameworkReference;
+			name = IOKit.framework;
+			path = /System/Library/Frameworks/IOKit.framework;
+			refType = 0;
+		};
+		327DDDFB00D7E81F05CD296C = {
+			fileRef = 327DDDFA00D7E81F05CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290381400D6B78A05CD296C = {
+			fileRef = 1BA451B10097605B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290381500D6BA5905CD296C = {
+			isa = PBXBundleReference;
+			path = AppleDL.bundle;
+			refType = 3;
+		};
+		3290381600D6BA5905CD296C = {
+			isa = PBXBundleReference;
+			path = AppleCSPDL.bundle;
+			refType = 3;
+		};
+		3290381700D6BA5905CD296C = {
+			isa = PBXBundleReference;
+			path = AppleX509CL.bundle;
+			refType = 3;
+		};
+		3290381800D6BA5905CD296C = {
+			isa = PBXBundleReference;
+			path = AppleX509TP.bundle;
+			refType = 3;
+		};
+		3290381900D6BA5905CD296C = {
+			buildPhases = (
+				3290381A00D6BA5905CD296C,
+				3290381B00D6BA5905CD296C,
+				3290381C00D6BA5905CD296C,
+				3290381D00D6BA5905CD296C,
+				3290382100D6BA5905CD296C,
+			);
+			buildSettings = {
+				LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/2.95.2;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-bundle -undefined suppress";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleDL;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = bundle;
+			};
+			dependencies = (
+				3290383B00D6BB3705CD296C,
+			);
+			isa = PBXBundleTarget;
+			name = "AppleDL Plugin";
+			productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
+			productName = "AppleDL Plugin";
+			productReference = 3290381500D6BA5905CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AppleDL</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		3290381A00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		3290381B00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		3290381C00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				3290383C00D6BB3705CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		3290381D00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				3290381E00D6BA5905CD296C,
+				3290381F00D6BA5905CD296C,
+				3290382000D6BA5905CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		3290381E00D6BA5905CD296C = {
+			fileRef = 1BA451B10097605B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290381F00D6BA5905CD296C = {
+			fileRef = 1A23E785009758847F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290382000D6BA5905CD296C = {
+			fileRef = 014880C8005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290382100D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		3290382200D6BA5905CD296C = {
+			buildPhases = (
+				3290382300D6BA5905CD296C,
+				3290382400D6BA5905CD296C,
+				3290382500D6BA5905CD296C,
+				3290382600D6BA5905CD296C,
+				3290382700D6BA5905CD296C,
+			);
+			buildSettings = {
+				LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/2.95.2;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-bundle -undefined suppress";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleCSPDL;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = bundle;
+			};
+			dependencies = (
+				3290383E00D6BB3705CD296C,
+			);
+			isa = PBXBundleTarget;
+			name = "AppleCSPDL Plugin";
+			productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
+			productName = "AppleCSPDL Plugin";
+			productReference = 3290381600D6BA5905CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AppleCSPDL</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		3290382300D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		3290382400D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		3290382500D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				327DDDE800D6FC1B05CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		3290382600D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				3290384000D6BB3705CD296C,
+				3290384100D6BB3705CD296C,
+				3290384200D6BB3705CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		3290382700D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		3290382800D6BA5905CD296C = {
+			buildPhases = (
+				3290382900D6BA5905CD296C,
+				3290382A00D6BA5905CD296C,
+				3290382B00D6BA5905CD296C,
+				3290382C00D6BA5905CD296C,
+				3290382D00D6BA5905CD296C,
+			);
+			buildSettings = {
+				LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/2.95.2;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-bundle -undefined suppress";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleX509CL;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = bundle;
+			};
+			dependencies = (
+				3290384400D6BB3705CD296C,
+			);
+			isa = PBXBundleTarget;
+			name = "AppleX509CL Plugin";
+			productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
+			productName = "AppleX509CL Plugin";
+			productReference = 3290381700D6BA5905CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AppleX509CL</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		3290382900D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		3290382A00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		3290382B00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				3290384500D6BB3705CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		3290382C00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				3290384600D6BB3705CD296C,
+				3290384700D6BB3705CD296C,
+				3290384800D6BB3705CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		3290382D00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		3290382E00D6BA5905CD296C = {
+			buildPhases = (
+				3290382F00D6BA5905CD296C,
+				3290383000D6BA5905CD296C,
+				3290383100D6BA5905CD296C,
+				3290383200D6BA5905CD296C,
+				3290383300D6BA5905CD296C,
+			);
+			buildSettings = {
+				INSTALL_PATH = "";
+				LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/2.95.2;
+				OPTIMIZATION_CFLAGS = "-O2 -DNDEBUG";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-bundle -undefined suppress";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AppleX509TP;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = bundle;
+			};
+			dependencies = (
+				3290384A00D6BB3705CD296C,
+			);
+			isa = PBXBundleTarget;
+			name = "AppleX509TP Plugin";
+			productInstallPath = "";
+			productName = "AppleX509TP Plugin";
+			productReference = 3290381800D6BA5905CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AppleX509TP</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		3290382F00D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		3290383000D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		3290383100D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				3290384B00D6BB3705CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		3290383200D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				3290384C00D6BB3705CD296C,
+				3290384D00D6BB3705CD296C,
+				3290384E00D6BB3705CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		3290383300D6BA5905CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		3290383500D6BB3705CD296C = {
+			isa = PBXFileReference;
+			path = AppleDLPlugin.cpp;
+			refType = 4;
+		};
+		3290383600D6BB3705CD296C = {
+			isa = PBXFileReference;
+			path = AppleX509CLPlugin.cpp;
+			refType = 4;
+		};
+		3290383700D6BB3705CD296C = {
+			isa = PBXFileReference;
+			path = AppleX509TPPlugin.cpp;
+			refType = 4;
+		};
+		3290383800D6BB3705CD296C = {
+			buildPhases = (
+			);
+			buildSettings = {
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = "Plugin Bundles";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				3290383900D6BB3705CD296C,
+				3290383A00D6BB3705CD296C,
+				3290383D00D6BB3705CD296C,
+				3290384300D6BB3705CD296C,
+				3290384900D6BB3705CD296C,
+			);
+			isa = PBXAggregateTarget;
+			name = "Plugin Bundles";
+			productName = "Plugin Bundles";
+			shouldUseHeadermap = 0;
+		};
+		3290383900D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 325EAA2200D6B08805CD296C;
+		};
+		3290383A00D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 3290381900D6BA5905CD296C;
+		};
+		3290383B00D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880DA005EAE4D11CD283A;
+		};
+		3290383C00D6BB3705CD296C = {
+			fileRef = 3290383500D6BB3705CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290383D00D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 3290382200D6BA5905CD296C;
+		};
+		3290383E00D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880D4005EAE4D11CD283A;
+		};
+		3290384000D6BB3705CD296C = {
+			fileRef = 014880C9005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384100D6BB3705CD296C = {
+			fileRef = 1BA451B10097605B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384200D6BB3705CD296C = {
+			fileRef = 1A23E785009758847F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384300D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 3290382800D6BA5905CD296C;
+		};
+		3290384400D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880E0005EAE4D11CD283A;
+		};
+		3290384500D6BB3705CD296C = {
+			fileRef = 3290383600D6BB3705CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384600D6BB3705CD296C = {
+			fileRef = 014880CA005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384700D6BB3705CD296C = {
+			fileRef = 1BA451B10097605B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384800D6BB3705CD296C = {
+			fileRef = 1A23E785009758847F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384900D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 3290382E00D6BA5905CD296C;
+		};
+		3290384A00D6BB3705CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880E6005EAE4D11CD283A;
+		};
+		3290384B00D6BB3705CD296C = {
+			fileRef = 3290383700D6BB3705CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384C00D6BB3705CD296C = {
+			fileRef = 014880CB005EAE4D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384D00D6BB3705CD296C = {
+			fileRef = 1BA451B10097605B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384E00D6BB3705CD296C = {
+			fileRef = 1A23E785009758847F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		3290384F00D6BB7805CD296C = {
+			isa = PBXTargetDependency;
+			target = 3290385000D6BB7805CD296C;
+		};
+		3290385000D6BB7805CD296C = {
+			buildPhases = (
+			);
+			buildSettings = {
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = "Built-in Plugin Code";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				3290385100D6BB7805CD296C,
+				3290385200D6BB7805CD296C,
+				3290385300D6BB7805CD296C,
+				3290385400D6BB7805CD296C,
+				3290385500D6BB7805CD296C,
+			);
+			isa = PBXAggregateTarget;
+			name = "Built-in Plugin Code";
+			productName = "Built-in Plugin Code";
+			shouldUseHeadermap = 0;
+		};
+		3290385100D6BB7805CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880CD005EAE4D11CD283A;
+		};
+		3290385200D6BB7805CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880D4005EAE4D11CD283A;
+		};
+		3290385300D6BB7805CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880DA005EAE4D11CD283A;
+		};
+		3290385400D6BB7805CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880E0005EAE4D11CD283A;
+		};
+		3290385500D6BB7805CD296C = {
+			isa = PBXTargetDependency;
+			target = 014880E6005EAE4D11CD283A;
+		};
+		3290386E00D6C5FD05CD296C = {
+			isa = PBXFileReference;
+			path = modloader.cpp;
+			refType = 4;
+		};
+		3290386F00D6C5FD05CD296C = {
+			isa = PBXFileReference;
+			path = modloader.h;
+			refType = 4;
+		};
+		3290387000D6C5FE05CD296C = {
+			fileRef = 3290386F00D6C5FD05CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		3290387100D6C5FE05CD296C = {
+			fileRef = 3290386E00D6C5FD05CD296C;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//320
+//321
+//322
+//323
+//324
+//330
+//331
+//332
+//333
+//334
+		338005E1FFF3E69711CD283A = {
+			fileRef = 01FA821BFFF2B54C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD041F00838F447F000001 = {
+			children = (
+				017B6CA6009748107F000001,
+				017B6CA7009748107F000001,
+				33BD0434008390257F000001,
+				33BD0435008390257F000001,
+				33BD0436008390257F000001,
+				33BD0437008390257F000001,
+				33BD0462008391C07F000001,
+				33BD0463008391C07F000001,
+				33BD045E008390B17F000001,
+				33BD045F008390B17F000001,
+				33BD0438008390257F000001,
+				33BD0439008390257F000001,
+				33BD043A008390257F000001,
+				33BD043B008390257F000001,
+				33BD043C008390257F000001,
+				33BD043D008390257F000001,
+				2F4DD9A600A0A0767F000001,
+				2F4DD9A500A0A0767F000001,
+				33BD043E008390257F000001,
+				33BD043F008390257F000001,
+				33BD0440008390257F000001,
+				33BD0441008390257F000001,
+				33BD0442008390257F000001,
+				33BD0443008390257F000001,
+				33BD0444008390257F000001,
+				33BD0445008390257F000001,
+				33BD0446008390257F000001,
+				33BD0447008390257F000001,
+				33BD042500838F5A7F000001,
+			);
+			isa = PBXGroup;
+			name = UNIX;
+			refType = 4;
+		};
+		33BD042000838F447F000001 = {
+			children = (
+				33BD042100838F447F000001,
+				33BD042200838F447F000001,
+			);
+			isa = PBXGroup;
+			name = "C++ Interface";
+			refType = 4;
+		};
+		33BD042100838F447F000001 = {
+			isa = PBXFileReference;
+			path = "securetransport++.cpp";
+			refType = 4;
+		};
+		33BD042200838F447F000001 = {
+			isa = PBXFileReference;
+			path = "securetransport++.h";
+			refType = 4;
+		};
+		33BD042300838F447F000001 = {
+			fileRef = 33BD042200838F447F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD042400838F447F000001 = {
+			fileRef = 33BD042100838F447F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD042500838F5A7F000001 = {
+			children = (
+				33BD042600838FB17F000001,
+				33BD042700838FB17F000001,
+				33BD042800838FB17F000001,
+				33BD042900838FB17F000001,
+				33BD042A00838FB17F000001,
+				33BD042B00838FB17F000001,
+			);
+			isa = PBXGroup;
+			name = Socks;
+			refType = 4;
+		};
+		33BD042600838FB17F000001 = {
+			isa = PBXFileReference;
+			path = "socks++.cpp";
+			refType = 4;
+		};
+		33BD042700838FB17F000001 = {
+			isa = PBXFileReference;
+			path = "socks++.h";
+			refType = 4;
+		};
+		33BD042800838FB17F000001 = {
+			isa = PBXFileReference;
+			path = "socks++4.cpp";
+			refType = 4;
+		};
+		33BD042900838FB17F000001 = {
+			isa = PBXFileReference;
+			path = "socks++4.h";
+			refType = 4;
+		};
+		33BD042A00838FB17F000001 = {
+			isa = PBXFileReference;
+			path = "socks++5.cpp";
+			refType = 4;
+		};
+		33BD042B00838FB17F000001 = {
+			isa = PBXFileReference;
+			path = "socks++5.h";
+			refType = 4;
+		};
+		33BD042C00838FB17F000001 = {
+			fileRef = 33BD042700838FB17F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD042D00838FB17F000001 = {
+			fileRef = 33BD042900838FB17F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD042E00838FB17F000001 = {
+			fileRef = 33BD042B00838FB17F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD042F00838FB17F000001 = {
+			fileRef = 33BD042600838FB17F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD043000838FB17F000001 = {
+			fileRef = 33BD042800838FB17F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD043100838FB17F000001 = {
+			fileRef = 33BD042A00838FB17F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD0434008390257F000001 = {
+			isa = PBXFileReference;
+			path = bufferfifo.cpp;
+			refType = 4;
+		};
+		33BD0435008390257F000001 = {
+			isa = PBXFileReference;
+			path = bufferfifo.h;
+			refType = 4;
+		};
+		33BD0436008390257F000001 = {
+			isa = PBXFileReference;
+			path = constdata.cpp;
+			refType = 4;
+		};
+		33BD0437008390257F000001 = {
+			isa = PBXFileReference;
+			path = constdata.h;
+			refType = 4;
+		};
+		33BD0438008390257F000001 = {
+			isa = PBXFileReference;
+			path = inetreply.cpp;
+			refType = 4;
+		};
+		33BD0439008390257F000001 = {
+			isa = PBXFileReference;
+			path = inetreply.h;
+			refType = 4;
+		};
+		33BD043A008390257F000001 = {
+			isa = PBXFileReference;
+			path = "ip++.cpp";
+			refType = 4;
+		};
+		33BD043B008390257F000001 = {
+			isa = PBXFileReference;
+			path = "ip++.h";
+			refType = 4;
+		};
+		33BD043C008390257F000001 = {
+			isa = PBXFileReference;
+			path = selector.cpp;
+			refType = 4;
+		};
+		33BD043D008390257F000001 = {
+			isa = PBXFileReference;
+			path = selector.h;
+			refType = 4;
+		};
+		33BD043E008390257F000001 = {
+			isa = PBXFileReference;
+			path = streams.cpp;
+			refType = 4;
+		};
+		33BD043F008390257F000001 = {
+			isa = PBXFileReference;
+			path = streams.h;
+			refType = 4;
+		};
+		33BD0440008390257F000001 = {
+			isa = PBXFileReference;
+			path = timeflow.cpp;
+			refType = 4;
+		};
+		33BD0441008390257F000001 = {
+			isa = PBXFileReference;
+			path = timeflow.h;
+			refType = 4;
+		};
+		33BD0442008390257F000001 = {
+			isa = PBXFileReference;
+			path = typedvalue.cpp;
+			refType = 4;
+		};
+		33BD0443008390257F000001 = {
+			isa = PBXFileReference;
+			path = typedvalue.h;
+			refType = 4;
+		};
+		33BD0444008390257F000001 = {
+			isa = PBXFileReference;
+			path = "unix++.cpp";
+			refType = 4;
+		};
+		33BD0445008390257F000001 = {
+			isa = PBXFileReference;
+			path = "unix++.h";
+			refType = 4;
+		};
+		33BD0446008390257F000001 = {
+			isa = PBXFileReference;
+			path = url.cpp;
+			refType = 4;
+		};
+		33BD0447008390257F000001 = {
+			isa = PBXFileReference;
+			path = url.h;
+			refType = 4;
+		};
+		33BD0449008390257F000001 = {
+			fileRef = 33BD0435008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD044A008390257F000001 = {
+			fileRef = 33BD0437008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD044B008390257F000001 = {
+			fileRef = 33BD0439008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD044C008390257F000001 = {
+			fileRef = 33BD043B008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD044D008390257F000001 = {
+			fileRef = 33BD043D008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD044E008390257F000001 = {
+			fileRef = 33BD043F008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD044F008390257F000001 = {
+			fileRef = 33BD0441008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD0450008390257F000001 = {
+			fileRef = 33BD0443008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD0451008390257F000001 = {
+			fileRef = 33BD0445008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD0452008390257F000001 = {
+			fileRef = 33BD0447008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD0454008390257F000001 = {
+			fileRef = 33BD0434008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD0455008390257F000001 = {
+			fileRef = 33BD0436008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD0456008390257F000001 = {
+			fileRef = 33BD0438008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD0457008390257F000001 = {
+			fileRef = 33BD043A008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD0458008390257F000001 = {
+			fileRef = 33BD043C008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD0459008390257F000001 = {
+			fileRef = 33BD043E008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD045A008390257F000001 = {
+			fileRef = 33BD0440008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD045B008390257F000001 = {
+			fileRef = 33BD0442008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD045C008390257F000001 = {
+			fileRef = 33BD0444008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD045D008390257F000001 = {
+			fileRef = 33BD0446008390257F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD045E008390B17F000001 = {
+			isa = PBXFileReference;
+			path = hosts.cpp;
+			refType = 4;
+		};
+		33BD045F008390B17F000001 = {
+			isa = PBXFileReference;
+			path = hosts.h;
+			refType = 4;
+		};
+		33BD0460008390B17F000001 = {
+			fileRef = 33BD045F008390B17F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD0461008390B17F000001 = {
+			fileRef = 33BD045E008390B17F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		33BD0462008391C07F000001 = {
+			isa = PBXFileReference;
+			path = headermap.cpp;
+			refType = 4;
+		};
+		33BD0463008391C07F000001 = {
+			isa = PBXFileReference;
+			path = headermap.h;
+			refType = 4;
+		};
+		33BD0464008391C07F000001 = {
+			fileRef = 33BD0463008391C07F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		33BD0465008391C07F000001 = {
+			fileRef = 33BD0462008391C07F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//330
+//331
+//332
+//333
+//334
+//390
+//391
+//392
+//393
+//394
+		3949557400CC6A4511CD283A = {
+			fileRef = 125E85ADFFF3D44A11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//390
+//391
+//392
+//393
+//394
+//480
+//481
+//482
+//483
+//484
+		48855E830095DC957F000001 = {
+			isa = PBXFileReference;
+			path = YarrowConnection.h;
+			refType = 4;
+		};
+		48855E840095DC957F000001 = {
+			fileRef = 48855E830095DC957F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		48855E850095DD697F000001 = {
+			isa = PBXFileReference;
+			path = YarrowConnection.cpp;
+			refType = 4;
+		};
+		48855E860095DD697F000001 = {
+			fileRef = 48855E850095DD697F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//480
+//481
+//482
+//483
+//484
+//4A0
+//4A1
+//4A2
+//4A3
+//4A4
+		4A4C766C007A4E317F000001 = {
+			isa = PBXFileReference;
+			name = rc5_enc.c;
+			path = misc/rc5_enc.c;
+			refType = 4;
+		};
+		4A4C766D007A4E317F000001 = {
+			isa = PBXFileReference;
+			name = rc5_locl.h;
+			path = misc/rc5_locl.h;
+			refType = 4;
+		};
+		4A4C766E007A4E317F000001 = {
+			isa = PBXFileReference;
+			name = rc5.h;
+			path = openssl/rc5.h;
+			refType = 4;
+		};
+		4A4C766F007A4E317F000001 = {
+			fileRef = 4A4C766D007A4E317F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4A4C7670007A4E317F000001 = {
+			fileRef = 4A4C766E007A4E317F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4A4C7671007A4E317F000001 = {
+			fileRef = 4A4C766C007A4E317F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4A4C7672007A4E657F000001 = {
+			isa = PBXFileReference;
+			name = rc5_skey.c;
+			path = misc/rc5_skey.c;
+			refType = 4;
+		};
+		4A4C7673007A4E657F000001 = {
+			fileRef = 4A4C7672007A4E657F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4A4C7674007A52DC7F000001 = {
+			isa = PBXFileReference;
+			name = rc5Context.cpp;
+			path = MiscCSPAlgs/rc5Context.cpp;
+			refType = 4;
+		};
+		4A4C7675007A52DC7F000001 = {
+			isa = PBXFileReference;
+			name = rc5Context.h;
+			path = MiscCSPAlgs/rc5Context.h;
+			refType = 4;
+		};
+		4A4C7676007A52DC7F000001 = {
+			fileRef = 4A4C7675007A52DC7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4A4C7677007A52DC7F000001 = {
+			fileRef = 4A4C7674007A52DC7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4AC94A7C0084BE397F000001 = {
+			isa = PBXFileReference;
+			path = "vRijndael-alg-ref.c";
+			refType = 4;
+		};
+		4AC94A7D0084BE397F000001 = {
+			fileRef = 4AC94A7C0084BE397F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4AC94A7E0084C0977F000001 = {
+			isa = PBXFileReference;
+			path = "boxes-ref.c";
+			refType = 4;
+		};
+		4AC94A7F0084C0977F000001 = {
+			fileRef = 4AC94A7E0084C0977F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//4A0
+//4A1
+//4A2
+//4A3
+//4A4
+//4D0
+//4D1
+//4D2
+//4D3
+//4D4
+		4D37AD3900AA03857F000001 = {
+			isa = PBXFileReference;
+			path = netconnection.cpp;
+			refType = 4;
+		};
+		4D37AD3A00AA03857F000001 = {
+			isa = PBXFileReference;
+			path = netconnection.h;
+			refType = 4;
+		};
+		4D37AD3B00AA03857F000001 = {
+			isa = PBXFileReference;
+			path = neterror.cpp;
+			refType = 4;
+		};
+		4D37AD3C00AA03857F000001 = {
+			isa = PBXFileReference;
+			path = neterror.h;
+			refType = 4;
+		};
+		4D37AD3D00AA03857F000001 = {
+			isa = PBXFileReference;
+			path = netmanager.cpp;
+			refType = 4;
+		};
+		4D37AD3E00AA03857F000001 = {
+			isa = PBXFileReference;
+			path = netmanager.h;
+			refType = 4;
+		};
+		4D37AD3F00AA03857F000001 = {
+			isa = PBXFileReference;
+			path = netparameters.h;
+			refType = 4;
+		};
+		4D37AD4000AA03857F000001 = {
+			isa = PBXFileReference;
+			path = networkchooser.cpp;
+			refType = 4;
+		};
+		4D37AD4100AA03857F000001 = {
+			isa = PBXFileReference;
+			path = networkchooser.h;
+			refType = 4;
+		};
+		4D37AD4200AA03857F000001 = {
+			fileRef = 4D37AD3A00AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		4D37AD4300AA03857F000001 = {
+			fileRef = 4D37AD3C00AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		4D37AD4400AA03857F000001 = {
+			fileRef = 4D37AD3E00AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		4D37AD4500AA03857F000001 = {
+			fileRef = 4D37AD3F00AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		4D37AD4600AA03857F000001 = {
+			fileRef = 4D37AD4100AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		4D37AD4700AA03857F000001 = {
+			fileRef = 4D37AD3900AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4D37AD4800AA03857F000001 = {
+			fileRef = 4D37AD3B00AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4D37AD4900AA03857F000001 = {
+			fileRef = 4D37AD3D00AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4D37AD4A00AA03857F000001 = {
+			fileRef = 4D37AD4000AA03857F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//4D0
+//4D1
+//4D2
+//4D3
+//4D4
+//4E0
+//4E1
+//4E2
+//4E3
+//4E4
+		4EB202DD0058585F7F000001 = {
+			isa = PBXFileReference;
+			path = appleoids.asn;
+			refType = 4;
+		};
+		4EB202DE0058585F7F000001 = {
+			isa = PBXFileReference;
+			path = appleoids.cpp;
+			refType = 4;
+		};
+		4EB202E00058588E7F000001 = {
+			isa = PBXFileReference;
+			path = appleoids.h;
+			refType = 4;
+		};
+		4EB202E10058588E7F000001 = {
+			fileRef = 4EB202E00058588E7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4EB202E2005859A47F000001 = {
+			fileRef = 4EB202E00058588E7F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		4EB202E3005859A47F000001 = {
+			fileRef = 4EB202DE0058585F7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//4E0
+//4E1
+//4E2
+//4E3
+//4E4
+//520
+//521
+//522
+//523
+//524
+		52BFC304007A6A1B7F000001 = {
+			isa = PBXFileReference;
+			name = rc4.h;
+			path = openssl/rc4.h;
+			refType = 4;
+		};
+		52BFC306007A6A1B7F000001 = {
+			isa = PBXFileReference;
+			name = rc4_skey.c;
+			path = misc/rc4_skey.c;
+			refType = 4;
+		};
+		52BFC307007A6A1B7F000001 = {
+			isa = PBXFileReference;
+			name = rc4Context.cpp;
+			path = MiscCSPAlgs/rc4Context.cpp;
+			refType = 4;
+		};
+		52BFC308007A6A1B7F000001 = {
+			isa = PBXFileReference;
+			name = rc4Context.h;
+			path = MiscCSPAlgs/rc4Context.h;
+			refType = 4;
+		};
+		52BFC30A007A6A1B7F000001 = {
+			fileRef = 52BFC308007A6A1B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		52BFC30C007A6A1B7F000001 = {
+			fileRef = 52BFC306007A6A1B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		52BFC30D007A6A1B7F000001 = {
+			fileRef = 52BFC307007A6A1B7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//520
+//521
+//522
+//523
+//524
+//560
+//561
+//562
+//563
+//564
+		560B41E100E23FA50DCD28E8 = {
+			isa = PBXFileReference;
+			path = MacYarrow_OSX.cpp;
+			refType = 4;
+		};
+		560B41E200E23FA50DCD28E8 = {
+			isa = PBXFileReference;
+			path = MacYarrow_OSX.h;
+			refType = 4;
+		};
+		568640ED00E23FD90DCD28E8 = {
+			fileRef = 560B41E200E23FA50DCD28E8;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		568640EE00E23FD90DCD28E8 = {
+			fileRef = 560B41E100E23FA50DCD28E8;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//560
+//561
+//562
+//563
+//564
+//570
+//571
+//572
+//573
+//574
+		57FCEE8B007A7B2F7F000001 = {
+			isa = PBXFileReference;
+			name = rc4_enc.c;
+			path = misc/rc4_enc.c;
+			refType = 4;
+		};
+		57FCEE8C007A7B2F7F000001 = {
+			fileRef = 57FCEE8B007A7B2F7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		57FCEE8D007B8B3D7F000001 = {
+			children = (
+				57FCEE8E007B8B3D7F000001,
+				57FCEE8F007B8B3D7F000001,
+				57FCEE9C007B8D4F7F000001,
+			);
+			isa = PBXGroup;
+			name = ComCryption;
+			refType = 4;
+		};
+		57FCEE8E007B8B3D7F000001 = {
+			isa = PBXFileReference;
+			name = ascContext.cpp;
+			path = ComCryption/ascContext.cpp;
+			refType = 4;
+		};
+		57FCEE8F007B8B3D7F000001 = {
+			isa = PBXFileReference;
+			name = ascContext.h;
+			path = ComCryption/ascContext.h;
+			refType = 4;
+		};
+		57FCEE95007B8B3D7F000001 = {
+			fileRef = 57FCEE8F007B8B3D7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		57FCEE99007B8B3D7F000001 = {
+			fileRef = 57FCEE8E007B8B3D7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		57FCEE9C007B8D4F7F000001 = {
+			isa = PBXFileReference;
+			name = ascFactory.h;
+			path = ComCryption/ascFactory.h;
+			refType = 4;
+		};
+		57FCEE9D007B8D4F7F000001 = {
+			fileRef = 57FCEE9C007B8D4F7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//570
+//571
+//572
+//573
+//574
+//590
+//591
+//592
+//593
+//594
+		59375E6B00A848827F000001 = {
+			isa = PBXFileReference;
+			name = MD2Object.h;
+			path = MiscCSPAlgs/MD2Object.h;
+			refType = 4;
+		};
+		59375E6C00A848827F000001 = {
+			fileRef = 59375E6B00A848827F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		59375E6D00A849237F000001 = {
+			isa = PBXFileReference;
+			name = md2_dgst.c;
+			path = misc/md2_dgst.c;
+			refType = 4;
+		};
+		59375E6E00A849237F000001 = {
+			isa = PBXFileReference;
+			name = md2.h;
+			path = openssl/md2.h;
+			refType = 4;
+		};
+		59375E6F00A849237F000001 = {
+			fileRef = 59375E6E00A849237F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		59375E7000A849237F000001 = {
+			fileRef = 59375E6D00A849237F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		59375E7100A849BB7F000001 = {
+			isa = PBXFileReference;
+			name = MD2Object.cpp;
+			path = MiscCSPAlgs/MD2Object.cpp;
+			refType = 4;
+		};
+		59375E7200A849BB7F000001 = {
+			fileRef = 59375E7100A849BB7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//590
+//591
+//592
+//593
+//594
+//630
+//631
+//632
+//633
+//634
+		63B97E6600603F0A7F000001 = {
+			isa = PBXFileReference;
+			path = CryptKitDER.cpp;
+			refType = 4;
+		};
+		63B97E6700603F0B7F000001 = {
+			fileRef = 63B97E6600603F0A7F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//630
+//631
+//632
+//633
+//634
+//F50
+//F51
+//F52
+//F53
+//F54
+		F579CFD900E99FC401CD283A = {
+			isa = PBXFileReference;
+			path = Schema.m4;
+			refType = 4;
+		};
+		F58785C800FB965F01CD29D4 = {
+			isa = PBXFileReference;
+			name = checkpw.c;
+			path = checkpw/checkpw.c;
+			refType = 2;
+		};
+		F58785C900FB965F01CD29D4 = {
+			isa = PBXFileReference;
+			name = checkpw.h;
+			path = checkpw/checkpw.h;
+			refType = 2;
+		};
+		F58785CA00FB966001CD29D4 = {
+			fileRef = F58785C900FB965F01CD29D4;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
+		F58785CB00FB966001CD29D4 = {
+			fileRef = F58785C800FB965F01CD29D4;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A5E50E00FB884E01CD29D4 = {
+			children = (
+				F58785C800FB965F01CD29D4,
+				F58785C900FB965F01CD29D4,
+			);
+			isa = PBXGroup;
+			name = checkpw;
+			refType = 4;
+		};
+		F5DDE3AE00B3358F01CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			generatedFileNames = (
+			);
+			isa = PBXShellScriptBuildPhase;
+			name = "Shell Script";
+			neededFileNames = (
+			);
+			shellPath = /bin/sh;
+			shellScript = "${SRCROOT}/symbol_strip.sh ${SRCROOT}/Security.exp";
+		};
+		F5E32A1500EAB9A301CD283A = {
+			isa = PBXFileReference;
+			path = KeySchema.m4;
+			refType = 4;
+		};
+	};
+	rootObject = 0867D690FE84028FC02AAC07;
+}
diff --git a/SecurityASN1/CVSVersionInfo.txt b/SecurityASN1/CVSVersionInfo.txt
new file mode 100644
index 00000000..bd0f26cb
--- /dev/null
+++ b/SecurityASN1/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:59 mb Exp $
+# $Name: Security-28 $
+ProjectName: SecurityASN1
+ProjectVersion: 6
diff --git a/SecurityASN1/Makefile b/SecurityASN1/Makefile
new file mode 100644
index 00000000..3acdaead
--- /dev/null
+++ b/SecurityASN1/Makefile
@@ -0,0 +1,63 @@
+#
+# Makefile to build snacc-generated code for pkcs* and cms
+#
+ASN1_SRC= sm_vdatypes.asn sm_x501ud.asn  sm_x411ub.asn sm_x411mtsas.asn \
+			sm_x501if.asn  sm_x520sa.asn sm_x509cmn.asn sm_x509af.asn \
+			sm_x509ce.asn  pkcs1oids.asn pkcs9oids.asn sm_cms.asn sm_ess.asn \
+			pkcs7.asn pkcs8.asn appleoids.asn
+
+SNACC_SRC= $(SRCROOT)/..
+
+GEN_SRC= $(ASN1_SRC:%.asn=%.cpp)
+GEN_HDR= $(ASN1_SRC:%.asn=%.h)
+
+ASN_SRC_DIR= $(SRCROOT)/asn
+GEN_SRC_DIR= $(SRCROOT)/c++
+GEN_HDR_DIR= $(SRCROOT)/inc
+
+VPATH= $(ASN_SRC_DIR)
+
+#
+# get snacc headers from snacc project source, not from /usr/local/include
+#
+HDR_INCPATH= -I$(SNACC_SRC)/c++-lib/inc
+
+#
+# standard useful ASN1
+#
+ASN_USEFUL= asn-useful.asn1
+
+#
+# local build directory, 
+#
+#LOCAL_BUILD= /Data_and_Apps/dmitchBuild
+LOCAL_BUILD= $(SYMROOT)
+
+CFLAGS= -g  $(HDR_INCPATH) -DVDADER_RULES
+LDFLAGS= -lstdc++ -lsnacc++ -L$(LOCAL_BUILD)
+
+CC= /usr/bin/cc
+SNACC= /usr/local/bin/snacc
+SNACC_FLAGS= -C -D -u $(ASN_USEFUL)
+
+first:	$(GEN_SRC) move_genfiles
+
+$(GEN_SRC):	$(ASN1_SRC)
+	(cd $(ASN_SRC_DIR); $(SNACC) $(SNACC_FLAGS) $(ASN1_SRC))
+
+move_genfiles:	clean_genfiles
+	(cd $(ASN_SRC_DIR); \
+	 mv *.cpp $(GEN_SRC_DIR); \
+	 mv *.h $(GEN_HDR_DIR))
+
+clean_genfiles:
+	(cd $(GEN_SRC_DIR); rm -f *.cpp)
+	(cd $(GEN_HDR_DIR); rm -f *.h)
+
+clean:	clean_genfiles
+
+install:
+
+# anything else?
+
+
diff --git a/SecurityASN1/PkcsCms.pbproj/project.pbxproj b/SecurityASN1/PkcsCms.pbproj/project.pbxproj
new file mode 100644
index 00000000..0265a122
--- /dev/null
+++ b/SecurityASN1/PkcsCms.pbproj/project.pbxproj
@@ -0,0 +1,805 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 33;
+	objects = {
+		01C17CFFFF16DC3011CD283A = {
+			children = (
+				01C17D00FF16DC3011CD283A,
+			);
+			isa = PBXGroup;
+			name = Frameworks;
+			refType = 4;
+		};
+		01C17D00FF16DC3011CD283A = {
+			isa = PBXFrameworkReference;
+			path = SecuritySNACCRuntime.framework;
+			refType = 3;
+		};
+		01C17D01FF16DC3011CD283A = {
+			fileRef = 01C17D00FF16DC3011CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//010
+//011
+//012
+//013
+//014
+//020
+//021
+//022
+//023
+//024
+		022D30ACFEF82B87D0A17CE7 = {
+			buildStyles = (
+				2B4BC6B0FFE026FE7F000001,
+				2B4BC6B1FFE026FE7F000001,
+			);
+			isa = PBXProject;
+			mainGroup = 022D30ADFEF82B87D0A17CE7;
+			productRefGroup = 022D30AFFEF8301ED0A17CE7;
+			projectDirPath = "";
+			targets = (
+				022D30F5FEF83C56D0A17CE7,
+				022D30B1FEF8301ED0A17CE7,
+				022D30AEFEF82D08D0A17CE7,
+			);
+		};
+		022D30ADFEF82B87D0A17CE7 = {
+			children = (
+				022D30B7FEF8308ED0A17CE7,
+				022D30C7FEF8308ED0A17CE7,
+				01C17CFFFF16DC3011CD283A,
+				022D30AFFEF8301ED0A17CE7,
+				141E8021FFE9D5767F000001,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		022D30AEFEF82D08D0A17CE7 = {
+			buildArgumentsString = "-f $(SRCROOT)/Makefile $ACTION SRCROOT=$(SRCROOT) SYMROOT=$(SYMROOT)";
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = CompileAsn;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = CompileAsn;
+			productName = CompileAsn;
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 287;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		022D30AFFEF8301ED0A17CE7 = {
+			children = (
+				0509B1B7FF15465811CD283A,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		022D30B1FEF8301ED0A17CE7 = {
+			buildPhases = (
+				022D30B2FEF8301ED0A17CE7,
+				022D30B3FEF8301ED0A17CE7,
+				022D30B4FEF8301ED0A17CE7,
+				022D30B5FEF8301ED0A17CE7,
+				022D30B6FEF8301ED0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)/inc\" \"$(SYMROOT)/SecuritySNACCRuntime.framework/Headers\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/SecuritySNACCRuntime.framework/Headers\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-DVDADER_RULES";
+				OTHER_LDFLAGS = "\"-lstdc++\"";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = SecurityASN1;
+				SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/SecurityASN1.order\"";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			dependencies = (
+			);
+			isa = PBXFrameworkTarget;
+			name = PkcsCms;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = SecurityASN1;
+			productReference = 0509B1B7FF15465811CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>SecurityASN1</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		022D30B2FEF8301ED0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				022D30D7FEF8308ED0A17CE7,
+				022D30D8FEF8308ED0A17CE7,
+				022D30D9FEF8308ED0A17CE7,
+				022D30DAFEF8308ED0A17CE7,
+				022D30DBFEF8308ED0A17CE7,
+				022D30DCFEF8308ED0A17CE7,
+				022D30DDFEF8308ED0A17CE7,
+				022D30DEFEF8308ED0A17CE7,
+				022D30DFFEF8308ED0A17CE7,
+				022D30E0FEF8308ED0A17CE7,
+				022D30E1FEF8308ED0A17CE7,
+				022D30E2FEF8308ED0A17CE7,
+				022D30E3FEF8308ED0A17CE7,
+				022D30E4FEF8308ED0A17CE7,
+				022D30E5FEF8308ED0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		022D30B3FEF8301ED0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		022D30B4FEF8301ED0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				022D30E6FEF8308ED0A17CE7,
+				022D30E7FEF8308ED0A17CE7,
+				022D30E8FEF8308ED0A17CE7,
+				022D30E9FEF8308ED0A17CE7,
+				022D30EAFEF8308ED0A17CE7,
+				022D30EBFEF8308ED0A17CE7,
+				022D30ECFEF8308ED0A17CE7,
+				022D30EDFEF8308ED0A17CE7,
+				022D30EEFEF8308ED0A17CE7,
+				022D30EFFEF8308ED0A17CE7,
+				022D30F0FEF8308ED0A17CE7,
+				022D30F1FEF8308ED0A17CE7,
+				022D30F2FEF8308ED0A17CE7,
+				022D30F3FEF8308ED0A17CE7,
+				022D30F4FEF8308ED0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		022D30B5FEF8301ED0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01C17D01FF16DC3011CD283A,
+				141E8022FFE9D5767F000001,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		022D30B6FEF8301ED0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		022D30B7FEF8308ED0A17CE7 = {
+			children = (
+				022D30B8FEF8308ED0A17CE7,
+				022D30B9FEF8308ED0A17CE7,
+				022D30BAFEF8308ED0A17CE7,
+				022D30BBFEF8308ED0A17CE7,
+				022D30BCFEF8308ED0A17CE7,
+				022D30BDFEF8308ED0A17CE7,
+				022D30BEFEF8308ED0A17CE7,
+				022D30BFFEF8308ED0A17CE7,
+				022D30C0FEF8308ED0A17CE7,
+				022D30C1FEF8308ED0A17CE7,
+				022D30C2FEF8308ED0A17CE7,
+				022D30C3FEF8308ED0A17CE7,
+				022D30C4FEF8308ED0A17CE7,
+				022D30C5FEF8308ED0A17CE7,
+				022D30C6FEF8308ED0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "gen src";
+			refType = 4;
+		};
+		022D30B8FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = pkcs1oids.cpp;
+			path = "c++/pkcs1oids.cpp";
+			refType = 4;
+		};
+		022D30B9FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = pkcs7.cpp;
+			path = "c++/pkcs7.cpp";
+			refType = 4;
+		};
+		022D30BAFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = pkcs8.cpp;
+			path = "c++/pkcs8.cpp";
+			refType = 4;
+		};
+		022D30BBFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = pkcs9oids.cpp;
+			path = "c++/pkcs9oids.cpp";
+			refType = 4;
+		};
+		022D30BCFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_cms.cpp;
+			path = "c++/sm_cms.cpp";
+			refType = 4;
+		};
+		022D30BDFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_ess.cpp;
+			path = "c++/sm_ess.cpp";
+			refType = 4;
+		};
+		022D30BEFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_vdatypes.cpp;
+			path = "c++/sm_vdatypes.cpp";
+			refType = 4;
+		};
+		022D30BFFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x411mtsas.cpp;
+			path = "c++/sm_x411mtsas.cpp";
+			refType = 4;
+		};
+		022D30C0FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x411ub.cpp;
+			path = "c++/sm_x411ub.cpp";
+			refType = 4;
+		};
+		022D30C1FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x501if.cpp;
+			path = "c++/sm_x501if.cpp";
+			refType = 4;
+		};
+		022D30C2FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x501ud.cpp;
+			path = "c++/sm_x501ud.cpp";
+			refType = 4;
+		};
+		022D30C3FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x509af.cpp;
+			path = "c++/sm_x509af.cpp";
+			refType = 4;
+		};
+		022D30C4FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x509ce.cpp;
+			path = "c++/sm_x509ce.cpp";
+			refType = 4;
+		};
+		022D30C5FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x509cmn.cpp;
+			path = "c++/sm_x509cmn.cpp";
+			refType = 4;
+		};
+		022D30C6FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x520sa.cpp;
+			path = "c++/sm_x520sa.cpp";
+			refType = 4;
+		};
+		022D30C7FEF8308ED0A17CE7 = {
+			children = (
+				022D30C8FEF8308ED0A17CE7,
+				022D30C9FEF8308ED0A17CE7,
+				022D30CAFEF8308ED0A17CE7,
+				022D30CBFEF8308ED0A17CE7,
+				022D30CCFEF8308ED0A17CE7,
+				022D30CDFEF8308ED0A17CE7,
+				022D30CEFEF8308ED0A17CE7,
+				022D30CFFEF8308ED0A17CE7,
+				022D30D0FEF8308ED0A17CE7,
+				022D30D1FEF8308ED0A17CE7,
+				022D30D2FEF8308ED0A17CE7,
+				022D30D3FEF8308ED0A17CE7,
+				022D30D4FEF8308ED0A17CE7,
+				022D30D5FEF8308ED0A17CE7,
+				022D30D6FEF8308ED0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "gen inc";
+			path = "";
+			refType = 4;
+		};
+		022D30C8FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = pkcs1oids.h;
+			path = inc/pkcs1oids.h;
+			refType = 4;
+		};
+		022D30C9FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = pkcs7.h;
+			path = inc/pkcs7.h;
+			refType = 4;
+		};
+		022D30CAFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = pkcs8.h;
+			path = inc/pkcs8.h;
+			refType = 4;
+		};
+		022D30CBFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = pkcs9oids.h;
+			path = inc/pkcs9oids.h;
+			refType = 4;
+		};
+		022D30CCFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_cms.h;
+			path = inc/sm_cms.h;
+			refType = 4;
+		};
+		022D30CDFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_ess.h;
+			path = inc/sm_ess.h;
+			refType = 4;
+		};
+		022D30CEFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_vdatypes.h;
+			path = inc/sm_vdatypes.h;
+			refType = 4;
+		};
+		022D30CFFEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x411mtsas.h;
+			path = inc/sm_x411mtsas.h;
+			refType = 4;
+		};
+		022D30D0FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x411ub.h;
+			path = inc/sm_x411ub.h;
+			refType = 4;
+		};
+		022D30D1FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x501if.h;
+			path = inc/sm_x501if.h;
+			refType = 4;
+		};
+		022D30D2FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x501ud.h;
+			path = inc/sm_x501ud.h;
+			refType = 4;
+		};
+		022D30D3FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x509af.h;
+			path = inc/sm_x509af.h;
+			refType = 4;
+		};
+		022D30D4FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x509ce.h;
+			path = inc/sm_x509ce.h;
+			refType = 4;
+		};
+		022D30D5FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x509cmn.h;
+			path = inc/sm_x509cmn.h;
+			refType = 4;
+		};
+		022D30D6FEF8308ED0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_x520sa.h;
+			path = inc/sm_x520sa.h;
+			refType = 4;
+		};
+		022D30D7FEF8308ED0A17CE7 = {
+			fileRef = 022D30C8FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30D8FEF8308ED0A17CE7 = {
+			fileRef = 022D30C9FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30D9FEF8308ED0A17CE7 = {
+			fileRef = 022D30CAFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30DAFEF8308ED0A17CE7 = {
+			fileRef = 022D30CBFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30DBFEF8308ED0A17CE7 = {
+			fileRef = 022D30CCFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30DCFEF8308ED0A17CE7 = {
+			fileRef = 022D30CDFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30DDFEF8308ED0A17CE7 = {
+			fileRef = 022D30CEFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30DEFEF8308ED0A17CE7 = {
+			fileRef = 022D30CFFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30DFFEF8308ED0A17CE7 = {
+			fileRef = 022D30D0FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30E0FEF8308ED0A17CE7 = {
+			fileRef = 022D30D1FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30E1FEF8308ED0A17CE7 = {
+			fileRef = 022D30D2FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30E2FEF8308ED0A17CE7 = {
+			fileRef = 022D30D3FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30E3FEF8308ED0A17CE7 = {
+			fileRef = 022D30D4FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30E4FEF8308ED0A17CE7 = {
+			fileRef = 022D30D5FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30E5FEF8308ED0A17CE7 = {
+			fileRef = 022D30D6FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		022D30E6FEF8308ED0A17CE7 = {
+			fileRef = 022D30B8FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30E7FEF8308ED0A17CE7 = {
+			fileRef = 022D30B9FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30E8FEF8308ED0A17CE7 = {
+			fileRef = 022D30BAFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30E9FEF8308ED0A17CE7 = {
+			fileRef = 022D30BBFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30EAFEF8308ED0A17CE7 = {
+			fileRef = 022D30BCFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30EBFEF8308ED0A17CE7 = {
+			fileRef = 022D30BDFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30ECFEF8308ED0A17CE7 = {
+			fileRef = 022D30BEFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30EDFEF8308ED0A17CE7 = {
+			fileRef = 022D30BFFEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30EEFEF8308ED0A17CE7 = {
+			fileRef = 022D30C0FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30EFFEF8308ED0A17CE7 = {
+			fileRef = 022D30C1FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30F0FEF8308ED0A17CE7 = {
+			fileRef = 022D30C2FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30F1FEF8308ED0A17CE7 = {
+			fileRef = 022D30C3FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30F2FEF8308ED0A17CE7 = {
+			fileRef = 022D30C4FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30F3FEF8308ED0A17CE7 = {
+			fileRef = 022D30C5FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30F4FEF8308ED0A17CE7 = {
+			fileRef = 022D30C6FEF8308ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		022D30F5FEF83C56D0A17CE7 = {
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = World;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+				022D30F7FEF83C56D0A17CE7,
+			);
+			isa = PBXAggregateTarget;
+			name = World;
+			productName = World;
+			shouldUseHeadermap = 0;
+		};
+		022D30F7FEF83C56D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 022D30B1FEF8301ED0A17CE7;
+		};
+//020
+//021
+//022
+//023
+//024
+//050
+//051
+//052
+//053
+//054
+		0509B1B7FF15465811CD283A = {
+			isa = PBXFrameworkReference;
+			path = SecurityASN1.framework;
+			refType = 3;
+		};
+//050
+//051
+//052
+//053
+//054
+//140
+//141
+//142
+//143
+//144
+		141E8021FFE9D5767F000001 = {
+			isa = PBXFrameworkReference;
+			name = cdsa_utilities.framework;
+			path = /System/Library/PrivateFrameworks/cdsa_utilities.framework;
+			refType = 0;
+		};
+		141E8022FFE9D5767F000001 = {
+			fileRef = 141E8021FFE9D5767F000001;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//140
+//141
+//142
+//143
+//144
+//2B0
+//2B1
+//2B2
+//2B3
+//2B4
+		2B4BC6B0FFE026FE7F000001 = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OPTIMIZATION_CFLAGS = "";
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		2B4BC6B1FFE026FE7F000001 = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+	};
+	rootObject = 022D30ACFEF82B87D0A17CE7;
+}
diff --git a/SecurityASN1/asn/appleoids.asn b/SecurityASN1/asn/appleoids.asn
new file mode 100644
index 00000000..b8d961fe
--- /dev/null
+++ b/SecurityASN1/asn/appleoids.asn
@@ -0,0 +1,167 @@
+APPLE-OIDS
+DEFINITIONS IMPLICIT TAGS  ::=
+BEGIN
+-- EXPORTS All --
+
+IMPORTS
+  BigIntegerStr
+    FROM VdaEnhancedTypes
+;
+
+-- base OIDs for Apple, Apple Data Security
+appleBaseOid OBJECT IDENTIFIER ::= { 1 2 840 113635 }
+appleDataSecurity OBJECT IDENTIFIER ::= { appleBaseOid 100 }
+
+-- base OIDs for Apple Trust Policies and Algorithms
+appleTrustPolicy OBJECT IDENTIFIER ::= { appleDataSecurity 1 }
+appleSecurityAlgorithm OBJECT IDENTIFIER ::=Ê{ appleDataSecurity 2 }
+
+-- Apple trust policy OIDs
+
+appleISignTP OBJECT IDENTIFIER 		::= { appleTrustPolicy 1 }
+appleX509Basic OBJECT IDENTIFIER 	::= { appleTrustPolicy 2 }
+appleSSLPolicy OBJECT IDENTIFIER    ::= { appleTrustPolicy 3 } 
+
+-- Apple algorithms
+appleFee OBJECT IDENTIFIER ::= { appleSecurityAlgorithm 1 }
+appleAsc OBJECT IDENTIFIER ::= { appleSecurityAlgorithm 2 }
+appleFeeMD5 OBJECT IDENTIFIER ::= { appleSecurityAlgorithm 3 }
+appleFeeSHA1 OBJECT IDENTIFIER ::= { appleSecurityAlgorithm 4 }
+appleFeed OBJECT IDENTIFIER ::= { appleSecurityAlgorithm 5 }
+appleFeedExp OBJECT IDENTIFIER ::= { appleSecurityAlgorithm 6 }
+appleECDSA OBJECT IDENTIFIER ::= { appleSecurityAlgorithm 7 }
+
+-- FEE ElGamal-style signature
+FEEElGamalSignature ::= SEQUENCE {
+  u     BigIntegerStr,
+  pmX 	BigIntegerStr
+}
+
+-- FEE ECDSA-style signature
+FEEECDSASignature ::= SEQUENCE {
+  c     BigIntegerStr, 
+  d     BigIntegerStr
+}
+
+-- FEE Curve parameters
+FEEPrimeType ::=    INTEGER { pt-mersenne(0), pt-fee(1), pt-general(2) }
+FEECurveType ::=    INTEGER { ct-montgomery(0), ct-weierstrass(1), ct-general(2) }
+
+FEECurveParameters ::= SEQUENCE
+{
+	primeType		FEEPrimeType,
+	curveType		FEECurveType,
+	q				INTEGER,			-- unsigned
+	k				INTEGER,			-- signed 
+	m				INTEGER,
+	a				BigIntegerStr,
+	bb				BigIntegerStr,		-- can't use variable/field b
+	c				BigIntegerStr,
+	x1Plus			BigIntegerStr,
+	x1Minus			BigIntegerStr,
+	cOrderPlus		BigIntegerStr,
+	cOrderMinus		BigIntegerStr,
+	x1OrderPlus		BigIntegerStr,
+	x1OrderMinus	BigIntegerStr,
+	basePrime		BigIntegerStr	OPTIONAL	-- iff FEEPrimeType == pt-general
+}
+
+-- FEE keys
+
+FEEPublicKey ::= SEQUENCE
+{
+	version			INTEGER,
+	curveParams		FEECurveParameters,
+	plusX			BigIntegerStr,
+	minusX			BigIntegerStr,
+	plusY			BigIntegerStr	OPTIONAL	-- iff FEECurveType == ct-weierstrass
+}
+
+FEEPrivateKey ::= SEQUENCE 
+{
+	version			INTEGER,
+	curveParams		FEECurveParameters,
+	privData		BigIntegerStr
+}
+
+-- DSA keys
+--
+-- DSA private keys are represented as a PrivateKeyInfo (pkcs8); DSA public keys
+-- are represented as SubjectPublicKeyInfo (sm_s509af). However, the public p, g, 
+-- and q parameters are expressed in the AlgorithmIdentifier.parameters
+-- field which is an ANY type. To simplify encoding and decoding (AsnAny is a royal
+-- hassle to deal with), we define new structs for the entire keys here.
+-- NOTE: these definition are derived from reverse engineering the key blobs
+-- created by BSAFE 4.0 using info type KI_DSA{Public,Private}BER. The BSAFE 
+-- documentation claims that this encoding is X9.20 compatible; however BSAFE
+-- adds a field to the dss-params (here called DSABSafeParams) struct which 
+-- indicates the prime size in bits. The encoding and decoding implemented here
+-- is verified to be compatible with BSAFE 4.0 but no othyer implementations of
+-- DSA keys.
+-- 
+DSAPrivateKey ::= SEQUENCE
+{
+	version			INTEGER,
+	dsaAlg			DSAAlgorithmId,
+	privateKey		OCTET STRING
+}	
+
+--
+-- The publicKey is actually the DER encoding of an ASN integer, wrapped in a
+-- BIT STRING. 
+--
+DSAPublicKey ::= SEQUENCE
+{
+	dsaAlg			DSAAlgorithmId,
+	publicKey		BIT STRING
+}
+
+--
+-- A convenient replacement for a DSA AlgorithmIdentifier
+--
+DSAAlgorithmId ::= SEQUENCE
+{
+	algorithm       OBJECT IDENTIFIER,	-- id_dsa from sm_cms
+	params			DSABsafeParams
+}
+
+--
+-- This is the "ANY" parameter from AlgorithmIdentifier.
+--
+DSABsafeParams ::= SEQUENCE
+{
+	keySizeInBits	INTEGER,	
+	p				BigIntegerStr,
+	q				BigIntegerStr,
+	g				BigIntegerStr
+}
+
+--
+-- DSAPrivateKey.privateKey is actually the DER encoding, as an AsnOcts, of this.
+--
+DSAPrivateKeyOcts ::= SEQUENCE
+{
+	privateKey		BigIntegerStr
+}
+	
+--
+-- DSA signature
+--
+DSASignature ::= SEQUENCE
+{
+	r				BigIntegerStr,
+	s				BigIntegerStr
+}
+
+--
+-- Encoding of the basic DSA parameters for use in a CDSA key generation context.
+-- 
+DSAAlgParams ::= SEQUENCE
+{
+	p				BigIntegerStr,
+	q				BigIntegerStr,
+	g				BigIntegerStr
+}
+
+END -- APPLE-OIDS
+
diff --git a/SecurityASN1/asn/asn-useful.asn1 b/SecurityASN1/asn/asn-useful.asn1
new file mode 100644
index 00000000..9834ac23
--- /dev/null
+++ b/SecurityASN1/asn/asn-useful.asn1
@@ -0,0 +1,105 @@
+ASN-USEFUL DEFINITIONS ::=
+BEGIN
+
+-- file: .../asn1specs/asn-useful.asn1
+--
+-- NOTE: every one of these types is marked as a PDU so the compiler
+--       will produce the encode and decode routines that
+--       enc/dec the top tag/len pairs, not just the content decoders.
+--       (only nec for re-generating the library files "asn_useful.[ch]").
+--       The isPdu field does not affect how this module is linked
+--       with other modules during compilation.
+--
+--  (type DEF comment directives immediately follow the "::=")
+--
+-- MS 92
+--
+-- $Header: /cvs/Darwin/Security/SecurityASN1/asn/asn-useful.asn1,v 1.1.1.1 2001/05/18 23:13:59 mb Exp $
+-- $Log: asn-useful.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:13:59  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1  2000/06/14 22:23:07  dmitch
+-- New PKCS/CMS snacc-generated framework.
+--
+-- Revision 1.1.1.1  2000/03/09 00:59:54  rmurphy
+-- Base Fortissimo Tree
+--
+-- Revision 1.2  1999/03/10 18:23:38  aram
+-- Corrected definition of UTF8String.
+--
+-- Revision 1.1  1999/03/10 18:16:44  aram
+-- Added UTF8String definition.
+--
+-- Revision 1.3  1995/07/24 15:12:35  rj
+-- useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme.
+--
+-- Revision 1.2  1994/08/28  09:54:19  rj
+-- comment leader fixed.
+--
+-- Revision 1.1  1994/08/28  09:51:15  rj
+-- first check-in.
+
+
+ObjectDescriptor ::= -- isPdu:"TRUE" --
+                     [UNIVERSAL 7] IMPLICIT OCTET STRING
+
+UTF8String       ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 12] IMPLICIT OCTET STRING
+
+NumericString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 18] IMPLICIT OCTET STRING
+
+PrintableString  ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 19] IMPLICIT OCTET STRING
+
+TeletexString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 20] IMPLICIT OCTET STRING
+
+T61String        ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 20] IMPLICIT OCTET STRING
+
+VideotexString   ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 21] IMPLICIT OCTET STRING
+
+IA5String        ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 22] IMPLICIT OCTET STRING
+
+GraphicString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 25] IMPLICIT OCTET STRING
+
+VisibleString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 26] IMPLICIT OCTET STRING
+
+ISO646String     ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 26] IMPLICIT OCTET STRING
+
+GeneralString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 27] IMPLICIT OCTET STRING
+
+UTCTime          ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 23] IMPLICIT OCTET STRING
+
+GeneralizedTime  ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 24] IMPLICIT OCTET STRING
+
+UniversalString  ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 28] IMPLICIT OCTET STRING
+
+BMPString        ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 30] IMPLICIT OCTET STRING
+
+EXTERNAL         ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 8] IMPLICIT SEQUENCE
+{
+        direct-reference      OBJECT IDENTIFIER OPTIONAL,
+        indirect-reference    INTEGER OPTIONAL,
+        data-value-descriptor ObjectDescriptor OPTIONAL,
+        encoding CHOICE
+        {
+                single-ASN1-type [0] OCTET STRING,  -- should be ANY
+                octet-aligned    [1] IMPLICIT OCTET STRING,
+                arbitrary        [2] IMPLICIT BIT STRING
+        }
+}
+
+END  -- of ASN-USEFUL  type definitions
diff --git a/SecurityASN1/asn/pkcs1.asn1 b/SecurityASN1/asn/pkcs1.asn1
new file mode 100644
index 00000000..b89fa06c
--- /dev/null
+++ b/SecurityASN1/asn/pkcs1.asn1
@@ -0,0 +1,205 @@
+PKCS-1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
+        modules(0) pkcs-1(1)}
+
+-- $Revision: 1.1.1.1 $
+
+-- This module has been checked for conformance with the ASN.1
+-- standard by the OSS ASN.1 Tools
+
+DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS ALL --
+-- All types and values defined in this module is exported for use in other
+-- ASN.1 modules.
+
+-- IMPORTS None --
+
+-- Basic object identifiers 
+
+-- The DER for this in hexadecimal is:
+-- 06 08 
+--    2A 86 48 86 F7 0D 01 01
+--
+pkcs-1 OBJECT IDENTIFIER ::= {
+   iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+
+--
+-- When the following OIDs are used in an AlgorithmIdentifier
+-- the parameters MUST be present and MUST be NULL.
+--
+rsaEncryption          OBJECT IDENTIFIER ::= { pkcs-1 1 }
+md2WithRSAEncryption   OBJECT IDENTIFIER ::= { pkcs-1 2 }
+md4WithRSAEncryption   OBJECT IDENTIFIER ::= { pkcs-1 3 }
+md5WithRSAEncryption   OBJECT IDENTIFIER ::= { pkcs-1 4 }
+sha1WithRSAEncryption  OBJECT IDENTIFIER ::= { pkcs-1 5 }
+rsaOAEPEncryptionSET   OBJECT IDENTIFIER ::= { pkcs-1 6 }
+
+--
+-- When id-RSAES-OAEP is used in an AlgorithmIdentifier
+-- the parameters MUST be present and MUST be RSAES-OAEP-params.
+--
+id-RSAES-OAEP          OBJECT IDENTIFIER ::= { pkcs-1 7 }
+
+--
+-- When id-mgf1 is used in an AlgorithmIdentifier
+-- the parameters MUST be present and MUST be
+-- a DigestAlgorithmIdentifier, specifically SHA1Identifier.
+--
+id-mgf1                OBJECT IDENTIFIER ::= { pkcs-1 8 }
+
+--
+-- When id-pSpecified is used in an AlgorithmIdentifier
+-- the parameters MUST be an OCTET STRING.
+--
+id-pSpecified OBJECT IDENTIFIER ::= { pkcs-1 9 }
+
+--
+-- This OID really belongs in a module with the secsig OIDs.
+--
+id-sha1                OBJECT IDENTIFIER ::= { 
+   iso(1) identified-organization(3) oiw(14) secsig(3)
+   algorithms(2) 26 }
+
+
+-- Useful types
+
+ALGORITHM-IDENTIFIER ::= TYPE-IDENTIFIER
+
+-- Note: the parameter InfoObjectSet in the following definitions
+-- allows a distinct information object set to be specified for
+-- sets of algorithms such as:  
+-- DigestAlgorithms ALGORITHM-IDENTIFIER ::= {
+--    { NULL IDENTIFIED BY id-sha1 },
+--    { NULL IDENTIFIED BY id-md5 },
+--    { NULL IDENTIFIED BY id-md2 }
+-- }
+--
+AlgorithmIdentifier { ALGORITHM-IDENTIFIER:InfoObjectSet } ::= 
+SEQUENCE {
+   algorithm   ALGORITHM-IDENTIFIER.&id({InfoObjectSet}),
+   parameters  ALGORITHM-IDENTIFIER.&Type({InfoObjectSet}
+                                           {@algorithm}) OPTIONAL
+}
+
+-- Algorithms
+
+--
+-- Allowed OAEP digest algorithms.
+--
+OAEPDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
+   { SHA1Parameters IDENTIFIED BY id-sha1 },
+     ... --Allows for future expansion
+}
+
+sha1Identifier AlgorithmIdentifier {{ OAEPDigestAlgorithms }} ::= 
+   {algorithm id-sha1, parameters SHA1Parameters : NULL}
+
+SHA1Parameters ::= NULL
+
+--
+-- Allowed Mask Generation Function algorithms.
+-- If the identifier is id-mgf1, the parameters
+-- are a single digest algorithm identifier.
+--
+PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
+   { MGF1Parameters IDENTIFIED BY id-mgf1 },
+     ...--Allows for future expansion
+}
+
+MGF1Parameters ::= 
+   AlgorithmIdentifier { {OAEPDigestAlgorithms} }
+
+--
+-- Allowed algorithms for pSourceFunc.
+--
+PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
+   { PEmptyString IDENTIFIED BY id-pSpecified },
+   ...--Allows for future expansion
+}
+
+PEmptyString ::= OCTET STRING (SIZE(0))
+
+-- 
+-- This identifier means that P is an empty string, so the digest
+-- of the empty string appears in the RSA block before masking.
+--
+pSpecifiedEmptyIdentifier AlgorithmIdentifier {{ PKCS1PSourceAlgorithms }} ::=
+   { algorithm id-pSpecified, parameters PEmptyString : ''H }
+
+--
+-- Default AlgorithmIdentifier for id-RSAES-OAEP.maskGenFunc.
+--
+mgf1SHA1Identifier AlgorithmIdentifier {{ PKCS1MGFAlgorithms }} ::=
+    { algorithm id-mgf1, 
+      parameters AlgorithmIdentifier{{OAEPDigestAlgorithms}} : sha1Identifier}
+
+--
+-- Type identifier definitions for the PKCS #1 OIDs.
+--
+PKCS1Algorithms ALGORITHM-IDENTIFIER ::= {
+   { NULL IDENTIFIED BY rsaEncryption }               |
+   { NULL IDENTIFIED BY md2WithRSAEncryption }        |
+   { NULL IDENTIFIED BY md4WithRSAEncryption }        |
+   { NULL IDENTIFIED BY md5WithRSAEncryption }        |
+   { NULL IDENTIFIED BY sha1WithRSAEncryption }       |
+   { NULL IDENTIFIED BY rsaOAEPEncryptionSET }        |
+   { RSAES-OAEP-params IDENTIFIED BY id-RSAES-OAEP }  | 
+     PKCS1PSourceAlgorithms,
+     ... -- Allows for future expansion
+}
+
+-- Main structures
+
+RSAPublicKey ::= SEQUENCE {
+   modulus          INTEGER, -- (Usually large) n = p*q
+   publicExponent   INTEGER  -- (Usually small) e 
+}
+
+-- 
+-- Representation of RSA private key with p and q
+-- information for the CRT algorithm.
+--
+RSAPrivateKey ::= SEQUENCE {
+   version          INTEGER { rsaPrivateKeyVer0(0) }(rsaPrivateKeyVer0),
+   modulus          INTEGER, -- (Usually large) n
+   publicExponent   INTEGER, -- (Usually small) e
+   privateExponent  INTEGER, -- (Usually large) d
+   prime1           INTEGER, -- (Usually large) p
+   prime2           INTEGER, -- (Usually large) q
+   exponent1        INTEGER, -- (Usually large) d mod (p-1)
+   exponent2        INTEGER, -- (Usually large) d mod (q-1)
+   coefficient      INTEGER  -- (Usually large) (inverse of q) mod p 
+}
+
+-- 
+-- AlgorithmIdentifier.parameters for id-RSAES-OAEP.
+-- Note that the tags in this Sequence are explicit.
+--
+
+RSAES-OAEP-params ::=  SEQUENCE { 
+   hashFunc         [0] AlgorithmIdentifier { {OAEPDigestAlgorithms} }
+                        DEFAULT sha1Identifier,
+   maskGenFunc      [1] AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
+                        DEFAULT mgf1SHA1Identifier,               
+   pSourceFunc      [2] AlgorithmIdentifier { {PKCS1PSourceAlgorithms} } 
+                        DEFAULT pSpecifiedEmptyIdentifier
+}
+
+-- 
+-- Identifier for default RSAES-OAEP algorithm identifier
+-- The DER Encoding of this is in hexadecimal:
+-- 30 0D
+--    06 09 
+--       2A 86 48 86 F7 0D 01 01 07
+--    30 00   
+--       Notice that the DER encoding of default values is "empty". 
+--
+rSAES-OAEP-Default-Identifier AlgorithmIdentifier{ {PKCS1Algorithms} } ::= 
+     {algorithm id-RSAES-OAEP,
+      parameters RSAES-OAEP-params : {hashFunc    sha1Identifier, 
+                                      maskGenFunc mgf1SHA1Identifier,
+                                      pSourceFunc pSpecifiedEmptyIdentifier}}
+
+END -- PKCS1Definitions
diff --git a/SecurityASN1/asn/pkcs1oids.asn b/SecurityASN1/asn/pkcs1oids.asn
new file mode 100644
index 00000000..bc1025df
--- /dev/null
+++ b/SecurityASN1/asn/pkcs1oids.asn
@@ -0,0 +1,46 @@
+PKCS1-OIDS
+DEFINITIONS IMPLICIT TAGS  ::=
+BEGIN
+-- EXPORTS All --
+
+IMPORTS
+  BigIntegerStr
+    FROM VdaEnhancedTypes
+;
+
+rsadsi OBJECT IDENTIFIER ::= { 1 2 840 113549 }
+pkcs OBJECT IDENTIFIER ::= { rsadsi 1 }
+
+pkcs-1 OBJECT IDENTIFIER ::= { pkcs 1 }
+rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
+md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
+md4WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 3 }
+md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
+sha1withRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }  -- dmitch
+
+rsaDigestAlgorithm OBJECT IDENTIFIER ::= { rsadsi 2 }
+md2 OBJECT IDENTIFIER ::= { rsaDigestAlgorithm 2 }
+md4 OBJECT IDENTIFIER ::= { rsaDigestAlgorithm 4 }
+md5 OBJECT IDENTIFIER ::= { rsaDigestAlgorithm 5 }
+
+RSAPublicKey ::= SEQUENCE {
+  modulus BigIntegerStr, -- n
+  publicExponent BigIntegerStr -- e
+}
+
+RSAPrivateKey ::= SEQUENCE {
+  version INTEGER, -- Version,
+  modulus BigIntegerStr, -- n
+  publicExponent BigIntegerStr, -- e
+  privateExponent BigIntegerStr, -- d
+  prime1 BigIntegerStr, -- p
+  prime2 BigIntegerStr, -- q
+  exponent1 BigIntegerStr, -- d mod (p-1)
+  exponent2 BigIntegerStr, -- d mod (q-1)
+  coefficient BigIntegerStr -- (inverse of q) mod p
+}
+
+-- Version ::= INTEGER
+
+END -- PKCS1-OIDS
+
diff --git a/SecurityASN1/asn/pkcs5.asn1 b/SecurityASN1/asn/pkcs5.asn1
new file mode 100644
index 00000000..d090fbb7
--- /dev/null
+++ b/SecurityASN1/asn/pkcs5.asn1
@@ -0,0 +1,141 @@
+-- PKCS #5 v2.0 ASN.1 Module
+-- Revised March 25, 1999
+
+-- This module has been checked for conformance with the
+-- ASN.1 standard by the OSS ASN.1 Tools
+
+PKCS5v2-0 {iso(1) member-body(2) us(840) rsadsi(113549)
+  pkcs(1) pkcs-5(5) modules(16) pkcs5v2-0(1)}
+
+DEFINITIONS ::= BEGIN
+
+-- Basic object identifiers
+
+rsadsi OBJECT IDENTIFIER ::= 
+  {iso(1) member-body(2) us(840) 113549}
+pkcs OBJECT IDENTIFIER ::= {rsadsi 1}
+pkcs-5 OBJECT IDENTIFIER ::= {pkcs 5}
+
+-- Basic types and classes
+
+AlgorithmIdentifier { ALGORITHM-IDENTIFIER:InfoObjectSet } ::= 
+SEQUENCE {
+  algorithm ALGORITHM-IDENTIFIER.&id({InfoObjectSet}),
+  parameters ALGORITHM-IDENTIFIER.&Type({InfoObjectSet}
+    {@algorithm}) OPTIONAL }
+
+ALGORITHM-IDENTIFIER ::= TYPE-IDENTIFIER
+
+-- PBKDF2
+
+PBKDF2Algorithms ALGORITHM-IDENTIFIER ::= 
+  { {PBKDF2-params IDENTIFIED BY id-PBKDF2}, ...}
+
+id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12}
+
+algid-hmacWithSHA1 AlgorithmIdentifier {{PBKDF2-PRFs}} ::=
+  {algorithm id-hmacWithSHA1, parameters NULL : NULL}
+
+PBKDF2-params ::= SEQUENCE {
+  salt CHOICE {
+    specified OCTET STRING,
+    otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}}
+  },
+  iterationCount INTEGER (1..MAX),
+  keyLength INTEGER (1..MAX) OPTIONAL,
+  prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT
+    algid-hmacWithSHA1 }
+
+PBKDF2-SaltSources ALGORITHM-IDENTIFIER ::= { ... }
+
+PBKDF2-PRFs ALGORITHM-IDENTIFIER ::=
+  { {NULL IDENTIFIED BY id-hmacWithSHA1}, ... }
+
+ -- PBES1
+
+PBES1Algorithms ALGORITHM-IDENTIFIER ::= 
+  { {PBEParameter IDENTIFIED BY pbeWithMD2AndDES-CBC} |
+    {PBEParameter IDENTIFIED BY pbeWithMD2AndRC2-CBC} |
+    {PBEParameter IDENTIFIED BY pbeWithMD5AndDES-CBC} |
+    {PBEParameter IDENTIFIED BY pbeWithMD5AndRC2-CBC} |
+    {PBEParameter IDENTIFIED BY pbeWithSHA1AndDES-CBC} |
+    {PBEParameter IDENTIFIED BY pbeWithSHA1AndRC2-CBC}, ...}
+
+pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1}
+pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4}
+pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3}
+pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6}
+pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10}
+pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11}
+
+PBEParameter ::= SEQUENCE {
+  salt OCTET STRING (SIZE(8)),
+  iterationCount INTEGER }
+
+-- PBES2
+
+PBES2Algorithms ALGORITHM-IDENTIFIER ::= 
+  { {PBES2-params IDENTIFIED BY id-PBES2}, ...}
+
+id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13}
+
+PBES2-params ::= SEQUENCE {
+  keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+  encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
+
+PBES2-KDFs ALGORITHM-IDENTIFIER ::=
+  { {PBKDF2-params IDENTIFIED BY id-PBKDF2}, ... }
+
+PBES2-Encs ALGORITHM-IDENTIFIER ::= { ... }
+
+-- PBMAC1
+
+PBMAC1Algorithms ALGORITHM-IDENTIFIER ::= 
+  { {PBMAC1-params IDENTIFIED BY id-PBMAC1}, ...}
+
+id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14}
+
+PBMAC1-params ::=  SEQUENCE {
+  keyDerivationFunc AlgorithmIdentifier {{PBMAC1-KDFs}},
+  messageAuthScheme AlgorithmIdentifier {{PBMAC1-MACs}} }
+
+PBMAC1-KDFs ALGORITHM-IDENTIFIER ::=
+  { {PBKDF2-params IDENTIFIED BY id-PBKDF2}, ... }
+
+PBMAC1-MACs ALGORITHM-IDENTIFIER ::= { ... }
+
+-- Supporting techniques
+
+digestAlgorithm OBJECT IDENTIFIER     ::= {rsadsi 2}
+encryptionAlgorithm OBJECT IDENTIFIER ::= {rsadsi 3}
+
+SupportingAlgorithms ALGORITHM-IDENTIFIER ::=
+  { {NULL IDENTIFIED BY id-hmacWithSHA1} |
+    {OCTET STRING (SIZE(8)) IDENTIFIED BY desCBC} |
+    {OCTET STRING (SIZE(8)) IDENTIFIED BY des-EDE3-CBC} |
+    {RC2-CBC-Parameter IDENTIFIED BY rc2CBC} |
+    {RC5-CBC-Parameters IDENTIFIED BY rc5-CBC-PAD}, ... }
+
+id-hmacWithSHA1 OBJECT IDENTIFIER ::= {digestAlgorithm 7}
+
+desCBC OBJECT IDENTIFIER ::=
+  {iso(1) identified-organization(3) oiw(14) secsig(3)
+    algorithms(2) 7} -- from OIW
+
+des-EDE3-CBC OBJECT IDENTIFIER ::= {encryptionAlgorithm 7}
+
+rc2CBC OBJECT IDENTIFIER ::= {encryptionAlgorithm 2}
+
+RC2-CBC-Parameter ::= SEQUENCE {
+  rc2ParameterVersion INTEGER OPTIONAL,
+  iv OCTET STRING (SIZE(8)) }
+
+rc5-CBC-PAD OBJECT IDENTIFIER ::= {encryptionAlgorithm 9} 
+
+RC5-CBC-Parameters ::= SEQUENCE {
+  version INTEGER {v1-0(16)} (v1-0),
+  rounds INTEGER (8..127),
+  blockSizeInBits INTEGER (64 | 128),
+  iv OCTET STRING OPTIONAL }
+
+END
diff --git a/SecurityASN1/asn/pkcs7.asn b/SecurityASN1/asn/pkcs7.asn
new file mode 100644
index 00000000..69b2d0b2
--- /dev/null
+++ b/SecurityASN1/asn/pkcs7.asn
@@ -0,0 +1,63 @@
+PKCS7 
+
+-- ??? {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7)
+--      modules(0) pkcs-7(1)}
+
+DEFINITIONS EXPLICIT TAGS ::=
+BEGIN
+
+--
+-- 3. Definitions
+--
+
+-- EXPORTS All;
+
+IMPORTS
+
+	informationFramework, authenticationFramework
+		FROM UsefulDefinitions { usefulDefinitions }
+
+	AlgorithmIdentifier
+		FROM AuthenticationFramework { authenticationFramework }
+
+;
+
+-- *** A large amount of stuff we don't need right now deleted ***
+
+--
+-- 13. Encrypted-data content type
+--
+
+EncryptedData ::= SEQUENCE {
+  version               INTEGER {edVer0(0)} (edVer0),
+  encryptedContentInfo  EncryptedContentInfo
+}
+
+EncryptedContentInfo ::= SEQUENCE {
+  contentType     ContentType,
+  contentEncryptionAlgorithm
+                  ContentEncryptionAlgorithmIdentifier,
+  encryptedContent
+                  [0] IMPLICIT EncryptedContent OPTIONAL
+}
+
+ContentType ::= OBJECT IDENTIFIER
+
+EncryptedContent ::= OCTET STRING
+
+ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+--
+-- 14. Object Identifiers
+--
+
+pkcs-7                  OBJECT IDENTIFIER ::=
+  { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
+dataPkcs7               OBJECT IDENTIFIER ::= { pkcs-7 1 }
+signedData              OBJECT IDENTIFIER ::= { pkcs-7 2 }
+envelopedData           OBJECT IDENTIFIER ::= { pkcs-7 3 }
+signedAndEnvelopedData  OBJECT IDENTIFIER ::= { pkcs-7 4 }
+digestedData            OBJECT IDENTIFIER ::= { pkcs-7 5 }
+encryptedData           OBJECT IDENTIFIER ::= { pkcs-7 6 }
+
+END
diff --git a/SecurityASN1/asn/pkcs8.asn b/SecurityASN1/asn/pkcs8.asn
new file mode 100644
index 00000000..163db63d
--- /dev/null
+++ b/SecurityASN1/asn/pkcs8.asn
@@ -0,0 +1,40 @@
+PrivateKeyInformationSyntax
+-- PKCS#8 ASN.1
+DEFINITIONS IMPLICIT TAGS  ::=
+BEGIN
+-- EXPORTS All --
+IMPORTS
+        AlgorithmIdentifier
+           FROM AuthenticationFramework { authenticationFramework }
+        Attributes
+           FROM InformationFramework { informationFramework }
+        EncryptedKey
+           FROM CryptographicMessageSyntax
+;
+
+PrivateKeyInfo ::= SEQUENCE {
+	version INTEGER, -- Version,
+	privateKeyAlgorithm AlgorithmIdentifier,
+	privateKey PrivateKey,
+	attributes [0] IMPLICIT Attributes OPTIONAL }
+
+
+-- Version ::= INTEGER
+
+-- PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+
+
+PrivateKey ::= OCTET STRING
+
+
+EncryptedPrivateKeyInfo ::= SEQUENCE {
+	encryptionAlgorithm AlgorithmIdentifier,
+	encryptedKey EncryptedKey }
+
+
+-- EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+-- EncryptedKey ::= OCTET STRING
+
+END -- PrivateKeyInformationSyntax
+
diff --git a/SecurityASN1/asn/pkcs9oids.asn b/SecurityASN1/asn/pkcs9oids.asn
new file mode 100644
index 00000000..c8113e39
--- /dev/null
+++ b/SecurityASN1/asn/pkcs9oids.asn
@@ -0,0 +1,19 @@
+PKCS9-OIDS
+DEFINITIONS IMPLICIT TAGS  ::=
+BEGIN
+-- EXPORTS All --
+
+pkcs-9 OBJECT IDENTIFIER ::= { 1 2 840 113549 1 9 }
+
+emailAddress OBJECT IDENTIFIER ::= { pkcs-9 1 }
+unstructuredName OBJECT IDENTIFIER ::= { pkcs-9 2 }
+contentTypePkcs9 OBJECT IDENTIFIER ::= { pkcs-9 3 }
+messageDigest OBJECT IDENTIFIER ::= { pkcs-9 4 }
+signingTime OBJECT IDENTIFIER ::= { pkcs-9 5 }
+countersignature OBJECT IDENTIFIER ::= { pkcs-9 6 }
+challengePassword OBJECT IDENTIFIER ::= { pkcs-9 7 }
+unstructuredAddress OBJECT IDENTIFIER ::= { pkcs-9 8 }
+extendedCertificateAttributes OBJECT IDENTIFIER ::= { pkcs-9 9 }
+
+END -- PKCS9-OIDS
+
diff --git a/SecurityASN1/asn/sm_cms.asn b/SecurityASN1/asn/sm_cms.asn
new file mode 100644
index 00000000..c861a477
--- /dev/null
+++ b/SecurityASN1/asn/sm_cms.asn
@@ -0,0 +1,431 @@
+
+-- @(#) sm_cms.asn 1.13 12/17/98 14:17:10 
+-- FROM cms.txt:   <http://ietf.org/internet-drafts/draft-ietf-smime-cms-13.txt>
+
+   CryptographicMessageSyntax
+       { 1 2 840 113549 1 9 16 0 1 }
+       --RWC;{ iso(1) member-body(2) us(840) rsadsi(113549)
+       --RWC;  pkcs(1) pkcs-9(9) smime(16) modules(0) cms(1) }
+
+   DEFINITIONS IMPLICIT TAGS ::=
+   BEGIN
+
+   -- EXPORTS All
+   -- The types and values defined in this module are exported for use in
+   -- the other ASN.1 modules.  Other applications may use them for their
+   -- own purposes.
+
+   IMPORTS
+
+  -- MB;KeyIdentifier (replaces SubjectKeyIdentifier)
+     KeyIdentifier
+	   FROM CertificateExtensions
+
+  -- MB;PKCS1-OIDS
+     rsadsi, pkcs --MB;rsaEncryption, md5
+	   FROM PKCS1-OIDS
+
+  -- Useful Definitions from X.501
+     informationFramework, authenticationFramework
+       FROM UsefulDefinitions  { usefulDefinitions }
+
+  -- Directory Information Framework (X.501)
+       Name, Attribute, Attributes, AttributeValue
+         FROM InformationFramework --RWC; { joint-iso-itu-t ds(5) rWCmodules(1)
+         --RWC; "modules(1)" re-defined from above "CrytpgraphicMessageSyntax".
+         --RWC;    informationFramework(1) 3 }
+
+   -- Directory Authentication Framework (X.509)
+      AlgorithmIdentifier, AttributeCertificate, Certificate,
+      CertificateList, CertificateSerialNumber, Time
+        FROM AuthenticationFramework; --RWC;{ joint-iso-itu-t rWCds(5)
+        --RWC; "ds(1)" re-defined.
+        --RWC;module(1) rWCauthenticationFramework(7) 3 } ;
+
+
+
+
+
+   -- Cryptographic Message Syntax
+
+   ContentInfo ::= SEQUENCE {
+     contentType ContentType,
+     content [0] EXPLICIT ANY } --RWC;DEFINED BY contentType }
+
+   ContentType ::= OBJECT IDENTIFIER
+
+   SignedData ::= SEQUENCE {
+     version CMSVersion,
+     digestAlgorithms DigestAlgorithmIdentifiers,
+     encapContentInfo EncapsulatedContentInfo,
+     certificates [0] IMPLICIT CertificateSet OPTIONAL,
+     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+     signerInfos SignerInfos }
+
+   DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
+
+   SignerInfos ::= SET OF SignerInfo
+
+
+
+   EncapsulatedContentInfo ::= SEQUENCE {
+     eContentType ContentType,
+     eContent [0] EXPLICIT OCTET STRING OPTIONAL }
+
+   SignerInfo ::= SEQUENCE {
+     version CMSVersion,
+     sid SignerIdentifier,
+     digestAlgorithm DigestAlgorithmIdentifier,
+     signedAttrs [0] IMPLICIT Attributes OPTIONAL, --MB;SignedAttributes OPTIONAL,
+     signatureAlgorithm SignatureAlgorithmIdentifier,
+     signature SignatureValue,
+     unsignedAttrs [1] IMPLICIT Attributes OPTIONAL } --MB;UnsignedAttributes OPTIONAL }
+
+   SignerIdentifier ::= CHOICE {
+     issuerAndSerialNumber IssuerAndSerialNumber,
+     subjectKeyIdentifier [0] KeyIdentifier } --MB;SubjectKeyIdentifier }
+
+   --MB;SignedAttributes ::= SET SIZE (1..MAX) OF Attribute
+
+   --MB;UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute
+
+   --MB;Attribute ::= SEQUENCE {
+   --MB;  attrType OBJECT IDENTIFIER,
+   --MB;  attrValues SET OF AttributeValue }
+
+   --MB;AttributeValue ::= ANY
+
+   SignatureValue ::= OCTET STRING
+
+   EnvelopedData ::= SEQUENCE {
+     version CMSVersion,
+     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+     recipientInfos RecipientInfos,
+     encryptedContentInfo EncryptedContentInfo,
+     unprotectedAttrs [1] IMPLICIT Attributes OPTIONAL } --MB;UnprotectedAttributes OPTIONAL }
+
+   OriginatorInfo ::= SEQUENCE {
+     certs [0] IMPLICIT CertificateSet OPTIONAL,
+     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL }
+
+   RecipientInfos ::= SET OF RecipientInfo
+
+   EncryptedContentInfo ::= SEQUENCE {
+     contentType ContentType,
+     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+     encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
+
+   EncryptedContent ::= OCTET STRING
+
+
+
+   --MB;UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute
+
+   RecipientInfo ::= CHOICE {
+     ktri KeyTransRecipientInfo,
+     kari [1] KeyAgreeRecipientInfo,
+     kekri [2] KEKRecipientInfo }
+
+   EncryptedKey ::= OCTET STRING
+
+   KeyTransRecipientInfo ::= SEQUENCE {
+     version CMSVersion,  -- always set to 0 or 2
+     rid RecipientIdentifier,
+     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+     encryptedKey EncryptedKey }
+
+   RecipientIdentifier ::= CHOICE {
+     issuerAndSerialNumber IssuerAndSerialNumber,
+     subjectKeyIdentifier [0] KeyIdentifier } --MB;SubjectKeyIdentifier }
+
+   KeyAgreeRecipientInfo ::= SEQUENCE {
+     version CMSVersion,  -- always set to 3
+     originator [0] EXPLICIT OriginatorIdentifierOrKey,
+     ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
+     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+     recipientEncryptedKeys RecipientEncryptedKeys }
+
+   OriginatorIdentifierOrKey ::= CHOICE {
+     issuerAndSerialNumber IssuerAndSerialNumber,
+     subjectKeyIdentifier [0] KeyIdentifier, --MB;SubjectKeyIdentifier,
+     originatorKey [1] OriginatorPublicKey }
+
+   OriginatorPublicKey ::= SEQUENCE {
+     algorithm AlgorithmIdentifier,
+     publicKey BIT STRING }
+
+   RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey
+
+   RecipientEncryptedKey ::= SEQUENCE {
+     rid KeyAgreeRecipientIdentifier,
+     encryptedKey EncryptedKey }
+
+   KeyAgreeRecipientIdentifier ::= CHOICE {
+     issuerAndSerialNumber IssuerAndSerialNumber,
+     rKeyId [0] IMPLICIT RecipientKeyIdentifier }
+
+
+
+
+   RecipientKeyIdentifier ::= SEQUENCE {
+     subjectKeyIdentifier KeyIdentifier, --MB;SubjectKeyIdentifier,
+     date GeneralizedTime OPTIONAL,
+     other OtherKeyAttribute OPTIONAL }
+
+   --MB;SubjectKeyIdentifier ::= OCTET STRING
+
+   KEKRecipientInfo ::= SEQUENCE {
+     version CMSVersion,  -- always set to 4
+     kekid KEKIdentifier,
+     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+     encryptedKey EncryptedKey }
+
+   KEKIdentifier ::= SEQUENCE {
+     keyIdentifier OCTET STRING,
+     date GeneralizedTime OPTIONAL,
+     other OtherKeyAttribute OPTIONAL }
+
+   DigestedData ::= SEQUENCE {
+     version CMSVersion,
+     digestAlgorithm DigestAlgorithmIdentifier,
+     encapContentInfo EncapsulatedContentInfo,
+     digest Digest }
+
+   Digest ::= OCTET STRING
+
+   EncryptedData ::= SEQUENCE {
+     version CMSVersion,
+     encryptedContentInfo EncryptedContentInfo }
+
+   AuthenticatedData ::= SEQUENCE {
+     version CMSVersion,
+     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+     recipientInfos RecipientInfos,
+     macAlgorithm MessageAuthenticationCodeAlgorithm,
+     digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
+     encapContentInfo EncapsulatedContentInfo,
+     authenctiatedAttributes [2] IMPLICIT Attributes OPTIONAL, --MB;AuthAttributes OPTIONAL,
+     mac MessageAuthenticationCode,
+     unauthenticatedAttributes [3] IMPLICIT Attributes OPTIONAL } --MB;UnauthAttributes OPTIONAL }
+
+   --MB;AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
+
+   --MB;UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
+
+   MessageAuthenticationCode ::= OCTET STRING
+
+   DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+
+
+
+   SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
+
+   KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+   ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+   MessageAuthenticationCodeAlgorithm ::= AlgorithmIdentifier
+
+   CertificateRevocationLists ::= SET OF CertificateList
+
+   CertificateChoices ::= CHOICE {
+     certificate Certificate,  -- See X.509
+     extendedCertificate [0] IMPLICIT ExtendedCertificate,  -- Obsolete
+     attrCert [1] IMPLICIT AttributeCertificate }  -- See X.509 & X9.57
+
+   CertificateSet ::= SET OF CertificateChoices
+
+   IssuerAndSerialNumber ::= SEQUENCE {
+     issuer Name,
+     serialNumber CertificateSerialNumber }
+
+   CMSVersion ::= INTEGER  { v0(0), v1(1), v2(2), v3(3), v4(4) }
+
+   UserKeyingMaterial ::= OCTET STRING
+
+   UserKeyingMaterials ::= SET SIZE (1..MAX) OF UserKeyingMaterial
+
+   OtherKeyAttribute ::= SEQUENCE {
+     keyAttrId OBJECT IDENTIFIER,
+     keyAttr ANY  OPTIONAL } --RWC;DEFINED BY keyAttrId OPTIONAL }
+
+
+   -- CMS Attributes
+
+   MessageDigest ::= OCTET STRING
+
+   SigningTime  ::= Time
+
+   --MB;Time ::= CHOICE {
+   --MB;  utcTime UTCTime,
+   --MB;  generalTime GeneralizedTime }
+
+   Countersignature ::= SignerInfo
+
+
+
+   -- Algorithm Identifiers
+
+   sha-1 OBJECT IDENTIFIER ::= { 1 3 14 3 2 26 } --MB;{ iso(1) identified-organization(3)
+       --MB;oiw(14) secsig(3) algorithm(2) 26 }
+
+   --MB;md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+   --MB;    rsadsi(113549) digestAlgorithm(2) 5 }
+
+   id-dsa-with-sha1 OBJECT IDENTIFIER ::= { 1 2 840 10040 4 3 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) x9-57 (10040) x9cm(4) 3 }
+
+   --MB;rsaEncryption OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+   --MB;    us(840) rsadsi(113549) pkcs(1) pkcs-1(1) 1 }
+
+   dh-public-number OBJECT IDENTIFIER ::= { 1 2 840 10046 2 1 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) ansi-x942(10046) number-type(2) 1 }
+
+   id-alg-ESDH OBJECT IDENTIFIER ::= { pkcs 9 16 3 5 } --MB;{ iso(1) member-body(2) us(840)
+       --MB;rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 5 }
+
+   id-alg-CMS3DESwrap OBJECT IDENTIFIER ::= { pkcs 9 16 3 6 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 6 }
+
+   id-alg-CMSRC2wrap OBJECT IDENTIFIER ::= { pkcs 9 16 3 7 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 7 }
+
+   des-ede3-cbc OBJECT IDENTIFIER ::= { rsadsi 3 7 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) encryptionAlgorithm(3) 7 }
+
+   rc2-cbc OBJECT IDENTIFIER ::= { rsadsi 3 2 } --MB;{ iso(1) member-body(2) us(840)
+       --MB;rsadsi(113549) encryptionAlgorithm(3) 2 }
+
+   hMAC-SHA1 OBJECT IDENTIFIER ::= { 1 3 6 1 5 5 8 1 2 } --MB;{ iso(1) identified-organization(3)
+       --MB;dod(6) internet(1) security(5) mechanisms(5) 8 1 2 }
+
+   -- some more algorithms added by dmitch 
+   
+   rc2-ecb OBJECT IDENTIFIER ::= { rsadsi 3 3 }
+
+   rc4 OBJECT IDENTIFIER ::= { rsadsi 3 4 }
+
+   rc4WithMAC OBJECT IDENTIFIER ::= { rsadsi 3 5 }
+
+   desx-CBC OBJECT IDENTIFIER ::= { rsadsi 3 6 }
+
+   rc5CBC OBJECT IDENTIFIER ::= { rsadsi 3 8 }
+   
+   rc5-CBCPad OBJECT IDENTIFIER ::= { rsadsi 3 9 }
+   
+   desCDMF OBJECT IDENTIFIER ::= { rsadsi 3 10 }
+   
+   -- this is the OID used by BSAFE when generating DSA keys. It is not
+   -- the same as id_dsa from sm_x501ud...
+   
+   dsa-bsafe OBJECT IDENTIFIER ::= {1 3 14 3 2 12}
+   
+   -- end of dmitch addenda
+   
+   
+   -- Algorithm Parameters
+
+   KeyWrapAlgorithm ::= AlgorithmIdentifier
+
+   RC2wrapParameter ::= RC2ParameterVersion
+
+   RC2ParameterVersion ::= INTEGER
+
+   CBCParameter ::= IV
+
+   IV ::= OCTET STRING  -- exactly 8 octets
+
+   RC2CBCParameter ::= SEQUENCE {
+     rc2ParameterVersion INTEGER,
+     iv OCTET STRING  }  -- exactly 8 octets
+
+
+   -- Content Type Object Identifiers
+
+   id-data OBJECT IDENTIFIER ::= { pkcs 7 1 } --MB; { iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 }
+
+   id-signedData OBJECT IDENTIFIER ::= { pkcs 7 2 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs7(7) 2 }
+
+   id-envelopedData OBJECT IDENTIFIER ::= { pkcs 7 3 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs7(7) 3 }
+
+   id-digestedData OBJECT IDENTIFIER ::= { pkcs 7 5 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs7(7) 5 }
+
+   id-encryptedData OBJECT IDENTIFIER ::= { pkcs 7 6 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs7(7) 6 }
+
+   id-ct-authData OBJECT IDENTIFIER ::= { pkcs 9 16 1 2 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16)
+       --MB;ct(1) 2 }
+
+
+   -- Attribute Object Identifiers
+
+   id-contentType OBJECT IDENTIFIER ::= { pkcs 9 3 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs9(9) 3 }
+
+   id-messageDigest OBJECT IDENTIFIER ::= { pkcs 9 4 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs9(9) 4 }
+
+   id-signingTime OBJECT IDENTIFIER ::= { pkcs 9 5 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs9(9) 5 }
+
+   id-countersignature OBJECT IDENTIFIER ::= { pkcs 9 6 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs9(9) 6 }
+
+
+   -- Obsolete Extended Certificate syntax from PKCS#6
+
+   ExtendedCertificateOrCertificate ::= CHOICE {
+     certificate Certificate,
+     extendedCertificate [0] IMPLICIT ExtendedCertificate }
+
+   ExtendedCertificate ::= SEQUENCE {
+     extendedCertificateInfo ExtendedCertificateInfo,
+     signatureAlgorithm SignatureAlgorithmIdentifier,
+     signature Signature }
+
+   ExtendedCertificateInfo ::= SEQUENCE {
+     version CMSVersion,
+     certificate Certificate,
+     attributes Attributes } --MB;UnauthAttributes }
+
+   Signature ::= BIT STRING
+
+
+
+   -- Everything below this line is not part of draft-ietf-smime-cms-13.txt
+
+
+   -- Attribute Object Identifiers
+
+   id-macValue OBJECT IDENTIFIER ::= { pkcs 9 16 2 8 } --MB;{ iso(1) member-body(2)
+       --MB;us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16) aa(2) 8 }
+
+
+   -- Algorithm Identifiers
+
+   id-dsa OBJECT IDENTIFIER ::= { 1 2 840 10040 4 1 } --MB;{iso(1) member-body(2)
+       --MB;us(840) x9-57(10040) x9cm(4) 1 }
+
+
+   -- Content Encryption Algorithms
+   --        For the effective-key-bits (key size) greater than 32 and less
+   --        than 256, the RC2-CBC algorithm parameters are encoded as:
+   --        RC2-CBC parameter ::=  SEQUENCE {
+   --                rc2ParameterVersion INTEGER,
+   --                iv OCTET STRING (8) }
+   --        For the effective-key-bits of 40, 64, and 128, the
+   --        rc2ParameterVersion values are 160, 120, 58 respectively.
+
+
+   -- Normally in PKCS#7
+   DigestInfo ::= SEQUENCE { -- Defined in PKCS#7 but not IETF-CMS
+     digestAlgorithm DigestAlgorithmIdentifier,
+     digest Digest }
+
+
+   END -- of CryptographicMessageSyntax
diff --git a/SecurityASN1/asn/sm_ess.asn b/SecurityASN1/asn/sm_ess.asn
new file mode 100644
index 00000000..f90e24e7
--- /dev/null
+++ b/SecurityASN1/asn/sm_ess.asn
@@ -0,0 +1,238 @@
+-- @(#) sm_ess.asn 1.13 12/17/98 14:17:02 
+-- FROM ess.txt:  draft-ietf-smime-ess-09.txt
+ExtendedSecurityServices
+     { 1 2 840 113549 1 9 16 0 2 } --MB;{ iso(1) member-body(2) us(840) rsadsi(113549)
+      --MB; pkcs(1) pkcs-9(9) smime(16) modules(0) ess(2) }
+
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+IMPORTS
+
+     KeyIdentifier, PolicyQualifierInfo, PolicyInformation, CertPolicyId
+	   FROM CertificateExtensions
+
+    pkcs-9
+    FROM PKCS9-OIDS
+ 
+-- Cryptographic Message Syntax (CMS)
+    ContentType, IssuerAndSerialNumber, CMSVersion
+    FROM CryptographicMessageSyntax { 1 2 840 113549 1 9 16 0 1 }
+   --RWC;iso(1) member-body(2) us(840)
+    --RWC;rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) modules(0) cms(1)}
+
+-- PKIX Certificate and CRL Profile, Sec A.2 Implicitly Tagged Module,
+--  1988 Syntax
+    --RWC;PolicyInformation FROM PKIX1Implicit88 {iso(1)   RWC; Added ")"
+    --RWC;identified-organization(3)dod(6) internet(1) security(5)
+    --RWC;mechanisms(5) pkix(7)id-mod(0) id-pkix1-implicit-88(2)}
+
+-- X.509
+    --RWC;GeneralNames, CertificateSerialNumber FROM CertificateExtensions  RWC; Removed ","
+    --RWC;{joint-iso-ccitt ds(5) module(1) certificateExtensions(26) 0}
+
+   ub-security-categories, ub-privacy-mark-length, ub-integer-options FROM UpperBounds
+                  -- RWC; Added to avoid SNACC ASN.1 Compiler link errors.
+
+   CertificateSerialNumber, IssuerSerial
+      FROM AuthenticationFramework  --RWC; Added
+
+   GeneralNames FROM CommonX509Definitions ;   --RWC; Added
+
+
+-- Extended Security Services
+
+-- The construct "SEQUENCE SIZE (1..MAX) OF" appears in several ASN.1
+-- constructs in this module. A valid ASN.1 SEQUENCE can have zero or
+-- more entries. The SIZE (1..MAX) construct constrains the SEQUENCE to 
+-- have at least one entry. MAX indicates the upper bound is unspecified.
+-- Implementations are free to choose an upper bound that suits their
+-- environment.
+
+-- Section 2.7
+
+ReceiptRequest ::= SEQUENCE {
+  signedContentIdentifier ContentIdentifier,
+  receiptsFrom ReceiptsFrom,
+  receiptsTo SEQUENCE SIZE (1..ub-receiptsTo) OF GeneralNames }
+
+ub-receiptsTo INTEGER ::= 16
+
+smime OBJECT IDENTIFIER ::= { pkcs-9 smime(16) }
+
+id-aa OBJECT IDENTIFIER ::= { pkcs-9 smime(16) 2 }
+
+id-aa-receiptRequest OBJECT IDENTIFIER ::= { id-aa 1 }
+
+ContentIdentifier ::= OCTET STRING
+
+id-aa-contentIdentifier OBJECT IDENTIFIER ::= { id-aa 7 }
+
+ReceiptsFrom ::= CHOICE {
+  allOrFirstTier [0] AllOrFirstTier,
+  -- formerly "allOrNone [0]AllOrNone"
+  receiptList [1] SEQUENCE OF GeneralNames }
+
+AllOrFirstTier ::= INTEGER { -- Formerly AllOrNone
+  allReceipts (0),
+  firstTierRecipients (1) }
+
+
+-- Section 2.8
+
+Receipt ::= SEQUENCE {
+  version CMSVersion,  -- Version is imported from [CMS]
+  contentType ContentType,
+  signedContentIdentifier ContentIdentifier,
+  originatorSignatureValue OCTET STRING }
+
+id-ct-receipt OBJECT IDENTIFIER ::= { smime id-ct(1) 1 }
+
+-- Section 2.9
+
+ContentHints ::= SEQUENCE {
+  contentDescription UTF8String OPTIONAL, --RWC;SIZE (1..MAX) OPTIONAL,
+  contentType ContentType }
+
+id-aa-contentHint OBJECT IDENTIFIER ::= { id-aa 4 }
+
+-- Section 2.10
+
+MsgSigDigest ::= OCTET STRING
+
+id-aa-msgSigDigest OBJECT IDENTIFIER ::= { id-aa 5 }
+
+-- Section 2.11
+
+ContentReference ::= SEQUENCE {
+  contentType ContentType,
+  signedContentIdentifier ContentIdentifier,
+  originatorSignatureValue OCTET STRING }
+
+id-aa-contentReference   OBJECT IDENTIFIER ::= { id-aa 10 }
+
+
+-- Section 3.2
+
+ESSSecurityLabel ::= SET {
+  security-policy-identifier SecurityPolicyIdentifier,
+  security-classification SecurityClassification OPTIONAL,
+  privacy-mark ESSPrivacyMark OPTIONAL,
+  security-categories SecurityCategories OPTIONAL }
+
+id-aa-securityLabel OBJECT IDENTIFIER ::= { id-aa 2}
+
+SecurityPolicyIdentifier ::= OBJECT IDENTIFIER
+
+SecurityClassification ::= INTEGER {
+  unmarked (0),
+  unclassified (1),
+  restricted (2),
+  confidential (3),
+  secret (4),
+  top-secret (5) } (0..ub-integer-options)
+
+--RWC; IMPORTED;ub-integer-options INTEGER ::= 256
+
+ESSPrivacyMark ::= CHOICE {
+  pStringááááá PrintableString, --RWC;SIZE (1..ub-privacy-mark-length),
+  utf8Stringáá UTF8String --RWC;SIZE (1..MAX)
+}
+
+--RWC; IMPORTED;ub-privacy-mark-length INTEGER ::= 128
+
+SecurityCategories ::= SET SIZE (1..ub-security-categories) OF
+        SecurityCategory
+
+--RWC; IMPORTED;ub-security-categories INTEGER ::= 64
+
+SecurityCategory ::= SEQUENCE {
+  type  [0] OBJECT IDENTIFIER,
+  value [1] ANY  --RWC;DEFINED BY type 
+}
+
+--Note: The aforementioned SecurityCategory syntax produces identical
+--hex encodings as the following SecurityCategory syntax that is
+--documented in the X.411 specification:
+--
+--SecurityCategory ::= SEQUENCE {
+--     type  [0]  SECURITY-CATEGORY,
+--     value [1]  ANY DEFINED BY type }
+--
+--SECURITY-CATEGORY MACRO ::=
+--BEGIN
+--TYPE NOTATION ::= type | empty
+--VALUE NOTATION ::= value (VALUE OBJECT IDENTIFIER)
+--END
+
+-- Section 3.4
+
+EquivalentLabels ::= SEQUENCE OF ESSSecurityLabel
+
+id-aa-equivalentLabels OBJECT IDENTIFIER ::= { id-aa 9}
+
+
+-- Section 4.4
+
+MLExpansionHistory ::= SEQUENCE
+        SIZE (1..ub-ml-expansion-history) OF MLData
+
+id-aa-mlExpandHistory OBJECT IDENTIFIER ::= { id-aa 3}
+
+ub-ml-expansion-history INTEGER ::= 64
+
+MLData ::= SEQUENCE {
+  mailListIdentifier EntityIdentifier,
+        -- EntityIdentifier is imported from [CMS]
+  expansionTime GeneralizedTime,
+  mlReceiptPolicy MLReceiptPolicy OPTIONAL }
+
+EntityIdentifier ::= CHOICE {
+  issuerAndSerialNumber IssuerAndSerialNumber,
+  subjectKeyIdentifier KeyIdentifier }   
+
+MLReceiptPolicy ::= CHOICE {
+  none [0] NULL,
+  insteadOf [1] SEQUENCE SIZE (1..MAX) OF GeneralNames,
+  inAdditionTo [2] SEQUENCE SIZE (1..MAX) OF GeneralNames }
+
+
+-- Section 5.4
+
+SigningCertificate ::=  SEQUENCE {
+    certs        SEQUENCE OF ESSCertID,
+    policies     SEQUENCE OF PolicyInformation OPTIONAL
+}
+
+id-aa-signingCertificate OBJECT IDENTIFIER ::= { id-aa 4444 } --RWC;Removed <TBD> }
+
+ESSCertID ::=  SEQUENCE {
+     certHash                 CertHash,
+     issuerSerial             IssuerSerial OPTIONAL
+}
+
+CertHash ::= OCTET STRING -- SHA1 hash of entire certificate
+--RWC; Modified "Hash" to "CertHash" to avoid crypto++ library contention.
+
+--RWC;
+--RWC; Added for completeness
+--RWC;
+
+
+   -- policyQualifierIds for Internet policy qualifiers
+
+   id-pkix  OBJECT IDENTIFIER  ::=
+               { iso(1) identified-organization(3) dod(6) internet(1)
+                       security(5) mechanisms(5) pkix(7) }
+
+   id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
+   id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
+   id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
+
+   PolicyQualifierId ::=
+        OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+
+
+
+
+END
diff --git a/SecurityASN1/asn/sm_vdatypes.asn b/SecurityASN1/asn/sm_vdatypes.asn
new file mode 100644
index 00000000..3fb591dc
--- /dev/null
+++ b/SecurityASN1/asn/sm_vdatypes.asn
@@ -0,0 +1,13 @@
+-- @(#) sm_vdatypes.asn 1.4 4/27/98 14:51:24 
+VdaEnhancedTypes DEFINITIONS ::=
+BEGIN
+
+-- NOTE: 
+--       This module contains the ASN.1 defintions for types that are not
+--       supported by Snacc 1.3b1 (i.e. UniversalString) and some echanced
+--       types for handling large integers.
+--
+
+BigIntegerStr    ::= [UNIVERSAL  2] IMPLICIT OCTET STRING
+
+END
diff --git a/SecurityASN1/asn/sm_x411mtsas.asn b/SecurityASN1/asn/sm_x411mtsas.asn
new file mode 100644
index 00000000..8e819a0f
--- /dev/null
+++ b/SecurityASN1/asn/sm_x411mtsas.asn
@@ -0,0 +1,158 @@
+-- @(#) sm_x411mtsas.asn 1.3 2/25/98 16:39:35 
+MTSAbstractService 
+-- { joint-iso-ccitt mhs-motis(6) mts(3) modules(0)
+-- mts-abstract-service(1) }
+
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- Prologue
+
+-- Exports everything
+
+-- Import UpperBounds Information
+
+IMPORTS
+   ub-bit-options, ub-built-in-content-type, 
+   ub-built-in-encoded-information-types, ub-common-name-length, 
+   ub-content-id-length, ub-content-length, ub-content-types, 
+   ub-country-name-alpha-length, ub-country-name-numeric-length,
+   ub-dl-expansions, ub-domain-defined-attribute-value-length,
+   ub-domain-defined-attributes, ub-domain-defined-attribute-type-length,
+   ub-domain-name-length, 
+   ub-encoded-information-types, ub-extension-attributes, ub-extension-types,
+   ub-generation-qualifier-length, ub-given-name-length,  ub-initials-length,
+   ub-integer-options, ub-labels-and-redirections, ub-local-id-length,
+   ub-mta-name-length, ub-mts-user-types, ub-numeric-user-id-length,
+   ub-organization-name-length, ub-organizational-unit-name-length,
+   ub-organizational-units, ub-password-length, ub-pds-name-length,
+   ub-pds-parameter-length,   
+   ub-postal-code-length, ub-privacy-mark-length, ub-queue-size, 
+   ub-reason-codes, ub-recipients, ub-recipient-number-for-advice-length, 
+   ub-redirections, ub-security-categories, ub-security-labels, 
+   ub-security-problems, ub-supplementary-info-length, ub-surname-length, 
+   ub-terminal-id-length, ub-tsap-id-length,
+   ub-x121-address-length
+   FROM UpperBounds  { upperBounds } ;
+
+-- O/R names
+
+-- not used
+--
+-- ORName ::= [APPLICATION 0] SEQUENCE {
+--     address            COMPONENTS OF ORAddress,
+--     directory-name [0] Name OPTIONAL }
+
+ORAddress ::= SEQUENCE {
+   standard-attributes       StandardAttributes,
+   domain-defined-attributes DomainDefinedAttributes OPTIONAL,
+
+   -- also see teletex-domain-defined-attributes
+
+  extension-attributes ExtensionAttributes OPTIONAL }
+
+-- Note - The OR-address is semantically absent from the OR-name 
+-- if the standard-attribute sequence is empty and the 
+-- domain-defined-attributes and extension-attributes  are both omitted.
+
+-- Standard attributes
+
+StandardAttributes ::= SEQUENCE {
+   country-name               CountryName OPTIONAL,
+   administration-domain-name AdministrationDomainName OPTIONAL,
+                              -- also see  extended-network-address
+   network-address            [0] NetworkAddress OPTIONAL, 
+   terminal-identifier        [1] TerminalIdentifier OPTIONAL,
+   private-domain-name        [2] PrivateDomainName OPTIONAL,
+                                  --also see teletex-organization-name
+   organization-name          [3] OrganizationName OPTIONAL,
+   numeric-user-identifier    [4] NumericUserIdentifier OPTIONAL,
+                                  --also  see  teletex-personal-name
+   personal-name              [5] PersonalName OPTIONAL,  
+                                  --also see teletex-organizational-unit-names 
+   organizational-unit-names  [6] OrganizationUnitNames OPTIONAL }
+
+
+CountryName ::= [APPLICATION 1] CHOICE {
+   x121-dcc-code         NumericString (SIZE  (ub-country-name-numeric-length)),
+
+   iso-3166-alpha2-code  PrintableString (SIZE (ub-country-name-alpha-length)) }
+
+AdministrationDomainName ::= [APPLICATION 2] CHOICE {
+   numeric NumericString (SIZE (0..ub-domain-name-length)),
+   printable PrintableString (SIZE (0..ub-domain-name-length)) }
+
+NetworkAddress ::= X121Address
+
+X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
+
+TerminalIdentifier  ::= PrintableString (SIZE (1..ub-terminal-id-length))
+
+PrivateDomainName ::= CHOICE {
+   numeric NumericString (SIZE (1. .ub-domain-name-length)),
+   printable PrintableString (SIZE (1..ub-domain-name-length)) }
+
+OrganizationName  ::= PrintableString (SIZE (1..ub-organization-name-length))
+
+NumericUserIdentifier ::= NumericString (SIZE (1..ub-numeric-user-id-length))
+
+PersonalName ::= SET {
+   surname     [0] PrintableString (SIZE (1..ub-surname-length)),
+   given-name  [1]  PrintableString (SIZE (1..ub-given-name-length)) OPTIONAL,
+   initials    [2]  PrintableString  (SIZE  (1..ub-initials-length)) OPTIONAL,
+   generation-qualifier [3] PrintableString 
+                 (SIZE (1..ub-generation-qualifier-length)) OPTIONAL }
+
+OrganizationUnitNames  ::=  SEQUENCE SIZE  (1..ub-organizational-units) OF
+                            OrganizationUnitName
+
+OrganizationUnitName   ::=  PrintableString 
+                           (SIZE (1..ub-organizational-unit-name-length))
+
+-- Domain-defined attributes
+
+DomainDefinedAttributes  ::= SEQUENCE SIZE (1..ub-domain-defined-attributes) 
+                             OF DomainDefinedAttribute
+
+DomainDefinedAttribute ::= SEQUENCE {
+   type  PrintableString  (SIZE  (1..ub-domain-defined-attribute-type-length)),
+   value PrintableString (SIZE (1..ub-domain-defined-attribute-value-length)) }
+
+-- Extension attributes
+
+ExtensionAttributes  ::= SET SIZE (1. .ub-extension-attributes)  OF
+                         ExtensionAttribute
+
+ExtensionAttribute ::= SEQUENCE {
+   extension-attribute-type  [0] INTEGER,
+   extension-attribute-value [1] ANY }
+
+CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
+
+TeletexCommonName  ::= TeletexString (SIZE (1..ub-common-name-length))
+
+TeletexOrganizationalName  ::=  TeletexString  
+                                 (SIZE  (1..ub-organization-name-length))
+
+TeletexPersonalName ::= SET {
+   surname     [0] TeletexString (SIZE (1..ub-surname-length)),
+   given-name  [1] TeletexString (SIZE (1..ub-given-name-length)) OPTIONAL,
+   initials    [2] TeletexString (SIZE (1..ub-initials-length)) OPTIONAL,
+   generation-qualifier [3] TeletexString 
+                   (SIZE (1..ub-generation-qualifier-length)) OPTIONAL }
+
+TeletexOrganizationUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) OF
+     TeletexOrganizationalUnitName
+
+TeletexOrganizationalUnitName ::= TeletexString 
+     (SIZE  (1..ub-organizational-unit-name-length))
+
+TeletexDomainDefinedAttributes ::= SEQUENCE 
+     SIZE (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute
+
+TeletexDomainDefinedAttribute ::= SEQUENCE {
+     type  TeletexString (SIZE (1..ub-domain-defined-attribute-type-length)),
+     value TeletexString  (SIZE (1..ub-domain-defined-attribute-value-length)) }
+
+END
diff --git a/SecurityASN1/asn/sm_x411ub.asn b/SecurityASN1/asn/sm_x411ub.asn
new file mode 100644
index 00000000..2a9ed239
--- /dev/null
+++ b/SecurityASN1/asn/sm_x411ub.asn
@@ -0,0 +1,131 @@
+-- @(#) sm_x411ub.asn 1.3 3/4/98 15:25:57 
+UpperBounds  
+-- {  joint-iso-ccitt mhs-motis(6)  mts(3)  modules(0) upper-bounds(3) }
+
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- Prologue
+
+-- Exports everything
+
+-- IMPORTS nothing
+
+-- Upper bounds
+
+ub-integer-options INTEGER ::= 256
+
+ub-queue-size INTEGER ::= 2147483647    -- the largest  integer  in 32 bits
+
+ub-content-length INTEGER ::= 2147483647     -- the largest integer in 32 bits
+
+ub-password-length INTEGER ::= 62
+
+ub-bit-options INTEGER ::= 16
+
+ub-content-types INTEGER ::= 1024
+
+ub-tsap-id-length INTEGER ::= 16
+
+ub-recipients INTEGER ::= 32767
+
+ub-content-id-length INTEGER ::= 16
+
+ub-x121-address-length INTEGER ::= 15
+
+ub-mts-user-types INTEGER ::= 256
+
+ub-reason-codes INTEGER ::= 32767
+
+ub-diagnostic-codes INTEGER ::= 32767
+
+ub-supplementary-info-length INTEGER ::= 256
+
+ub-extension-types INTEGER ::= 256
+                                 
+ub-recipient-number-for-advice-length INTEGER ::= 32
+
+ub-content-correlator-length INTEGER ::= 512
+
+ub-redirections INTEGER ::= 512
+
+ub-dl-expansions INTEGER ::= 512
+
+ub-built-in-content-type INTEGER ::= 32767
+
+ub-local-id-length INTEGER ::= 32
+
+ub-mta-name-length INTEGER ::= 32
+
+ub-country-name-numeric-length INTEGER ::= 3
+
+ub-country-name-alpha-length INTEGER ::= 2
+
+ub-domain-name-length INTEGER ::= 16
+
+ub-terminal-id-length INTEGER ::= 24
+
+ub-organization-name-length INTEGER ::= 64
+
+ub-numeric-user-id-length INTEGER ::= 32
+
+ub-surname-length INTEGER ::= 40
+
+ub-given-name-length INTEGER ::= 16
+
+ub-initials-length INTEGER ::= 5
+
+ub-generation-qualifier-length INTEGER ::= 3
+
+ub-organizational-units INTEGER ::= 4
+
+ub-organizational-unit-name-length INTEGER ::= 32
+
+ub-domain-defined-attributes INTEGER ::= 4
+
+ub-domain-defined-attribute-type-length INTEGER ::= 8
+
+ub-domain-defined-attribute-value-length INTEGER ::= 128
+                                 
+ub-extension-attributes INTEGER ::= 256
+
+ub-common-name-length INTEGER ::= 64
+
+ub-pds-name-length INTEGER ::= 16
+
+ub-postal-code-length INTEGER ::= 16
+
+ub-pds-parameter-length INTEGER ::= 30
+
+ub-physical-address-lines INTEGER ::= 6
+
+ub-unformatted-address-length INTEGER ::= 180
+
+ub-e163-4-number-length INTEGER ::= 15
+
+ub-e163-4-sub-address-length INTEGER ::= 40
+
+ub-built-in-encoded-information-types INTEGER ::= 32
+
+ub-teletex-private-use-length INTEGER ::= 128
+
+ub-encoded-information-types INTEGER ::= 1024
+
+ub-security-labels INTEGER ::= 256
+
+ub-labels-and-redirections INTEGER ::= 256
+
+ub-security-problems INTEGER ::= 256
+
+ub-privacy-mark-length INTEGER ::= 128
+
+ub-security-categories INTEGER ::= 64
+
+ub-transfers INTEGER ::= 512
+
+ub-bilateral-info INTEGER ::= 1024
+
+ub-additional-info INTEGER ::= 1024
+
+END -- of UpperBounds
diff --git a/SecurityASN1/asn/sm_x501if.asn b/SecurityASN1/asn/sm_x501if.asn
new file mode 100644
index 00000000..2673eea4
--- /dev/null
+++ b/SecurityASN1/asn/sm_x501if.asn
@@ -0,0 +1,48 @@
+-- @(#) sm_x501if.asn 1.2 2/24/98 13:39:21 
+InformationFramework 
+--
+-- oid defined in sm_x501ud.asn
+--
+-- { joint-iso-itu-t(1) ds(5) modules(1) informationFramework(1) 3 }
+DEFINITIONS EXPLICIT TAGS ::=
+BEGIN
+
+
+-- Added this because the CMS module needs it and thinks it comes from
+-- this module.
+--
+--   Pierce 2/23/98
+
+Attributes ::= SET OF Attribute
+
+AttributeType ::= OBJECT IDENTIFIER
+
+AttributeValue ::= ANY
+
+Attribute ::= SEQUENCE {
+   type   AttributeType,
+   values SET OF AttributeValue
+}
+
+Name ::= CHOICE {
+   rDNSequence RDNSequence 
+}
+
+DistinguishedName ::= RDNSequence
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+RelativeDistinguishedName ::= SET SIZE (1..MAX) OF
+   AttributeTypeAndDistinguishedValue
+
+
+AttributeTypeAndDistinguishedValue ::= SEQUENCE {
+   type                      OBJECT IDENTIFIER,
+   value                     ANY,
+   primaryDistinguished      BOOLEAN DEFAULT TRUE,
+   valuesWithContext         SET SIZE (1 .. MAX) OF SEQUENCE {
+   distingAttrValue          OBJECT IDENTIFIER OPTIONAL,
+   contextList               SET SIZE (1 .. MAX) OF ANY } OPTIONAL
+}
+
+END
diff --git a/SecurityASN1/asn/sm_x501ud.asn b/SecurityASN1/asn/sm_x501ud.asn
new file mode 100644
index 00000000..b5313955
--- /dev/null
+++ b/SecurityASN1/asn/sm_x501ud.asn
@@ -0,0 +1,136 @@
+-- @(#) sm_x501ud.asn 1.3 3/2/98 12:55:28 
+UsefulDefinitions 
+-- { joint-iso-ccitt ds(5) module(1) usefulDefinitions(0) 2 }
+DEFINITIONS ::=
+
+BEGIN
+
+-- EXPORTS All --
+
+-- The types and values defined in this module are exported for use in the 
+-- other ASN.1 modules contained within the Directory Specifications, and 
+-- for the use of other applications which will use them to access 
+-- Directory services. Other applications may use them for their own purposes, 
+-- but this will not constrain extensions and modifications needed to maintain
+--  or improve the Directory service.
+
+ds OBJECT IDENTIFIER   ::=    { joint-iso-ccitt ds(5) }
+
+-- categories of information object 
+
+module OBJECT IDENTIFIER   ::=    {ds 1}
+
+serviceElement OBJECT IDENTIFIER   ::=    {ds 2}
+applicationContext OBJECT IDENTIFIER   ::=    {ds 3}
+attributeType OBJECT IDENTIFIER   ::=    {ds 4}
+attributeSyntax OBJECT IDENTIFIER   ::=    {ds 5}
+objectClass OBJECT IDENTIFIER   ::=    {ds 6}
+-- attributeSet OBJECT IDENTIFIER   ::=   {ds 7}
+dsAlgorithm OBJECT IDENTIFIER   ::=   {ds 8}
+abstractSyntax OBJECT IDENTIFIER   ::=   {ds 9}
+-- object OBJECT IDENTIFIER   ::=    {ds 10}
+-- port    OBJECT IDENTIFIER   ::=    {ds 11}
+dsaOperationalAttribute OBJECT IDENTIFIER   ::=    {ds 12}
+matchingRule OBJECT IDENTIFIER   ::=    {ds 13}
+knowledgeMatchingRule OBJECT IDENTIFIER   ::=    {ds 14}
+nameForm OBJECT IDENTIFIER   ::=    {ds 15}
+group    OBJECT IDENTIFIER   ::=    {ds 16}
+subentry OBJECT IDENTIFIER   ::=    {ds 17}
+operationalAttributeType OBJECT IDENTIFIER   ::=    {ds 18}
+operationalBinding OBJECT IDENTIFIER   ::=   {ds 19}
+schemaObjectClass OBJECT IDENTIFIER   ::=   {ds 20}
+schemaOperationalAttribute OBJECT IDENTIFIER   ::=   {ds 21}
+administrativeRoles OBJECT IDENTIFIER   ::=   {ds 23}
+accessControlAttribute OBJECT IDENTIFIER   ::=   {ds 24}
+rosObject OBJECT IDENTIFIER   ::=   {ds 25}
+contract OBJECT IDENTIFIER   ::=   {ds 26}
+package OBJECT IDENTIFIER   ::=   {ds 27}
+accessControlSchemes OBJECT IDENTIFIER   ::=   {ds 28}
+certificateExtension OBJECT IDENTIFIER   ::=   {ds 29}
+managementObject OBJECT IDENTIFIER   ::=   {ds 30}
+-- modules --
+
+-- already defined
+--
+-- usefulDefinitions OBJECT IDENTIFIER   ::=   {module usefulDefinitions(0) 3}
+informationFramework OBJECT IDENTIFIER   ::=   {module informationFramework(1) 3}
+directoryAbstractService OBJECT IDENTIFIER   ::=   {module directoryAbstractService(2) 3}
+distributedOperations OBJECT IDENTIFIER   ::=   {module distributedOperations(3) 3}
+protocolObjectIdentifiers OBJECT IDENTIFIER   ::=   {module protocolObjectIdentifiers (4) 3}
+selectedAttributeTypes OBJECT IDENTIFIER   ::=   {module selectedAttributeTypes(5) 3}
+selectedObjectClasses OBJECT IDENTIFIER   ::=   {module selectedObjectClasses(6) 3}
+authenticationFramework OBJECT IDENTIFIER   ::=   {module authenticationFramework(7) 3}
+algorithmObjectIdentifiers OBJECT IDENTIFIER   ::=   {module algorithmObjectIdentifiers(8) 3}
+directoryObjectIdentifiers OBJECT IDENTIFIER   ::=   {module directoryObjectIdentifiers(9) 3}
+upperBounds OBJECT IDENTIFIER   ::=   {module upperBounds(10) 3}
+dap OBJECT IDENTIFIER   ::=   {module dap(11) 3}
+
+dsp OBJECT IDENTIFIER   ::=   {module dsp(12) 3}
+distributedDirectoryOIDs OBJECT IDENTIFIER   ::=   {module distributedDirectoryOIDs(13) 3}
+directoryShadowOIDs OBJECT IDENTIFIER   ::=   {module directoryShadowOIDs(14) 3}
+directoryShadowAbstractService OBJECT IDENTIFIER   ::=   {module directoryShadowAbstractService(15) 3}
+disp OBJECT IDENTIFIER   ::=   {module disp(16) 3}
+dop OBJECT IDENTIFIER   ::=   {module dop(17) 3}
+opBindingManagement OBJECT IDENTIFIER   ::=   {module opBindingManagement(18) 3}
+opBindingOIDs OBJECT IDENTIFIER   ::=   {module opBindingOIDs(19) 3}
+hierarchicalOperationalBindings OBJECT IDENTIFIER   ::=   {module hierarchicalOperationalBindings(20) 3}
+dsaOperationalAttributeTypes OBJECT IDENTIFIER   ::=   {module dsaOperationalAttributeTypes(22) 3}
+schemaAdministration OBJECT IDENTIFIER   ::=   {module schemaAdministration(23) 3}
+basicAccessControl OBJECT IDENTIFIER   ::=   {module basicAccessControl(24) 3}
+directoryOperationalBindingTypes OBJECT IDENTIFIER   ::=   {module directoryOperationalBindingTypes(25) 3}
+certificateExtensions OBJECT IDENTIFIER   ::=   {module certificateExtensions (26) 0}
+directoryManagement OBJECT IDENTIFIER   ::=   {module directoryManagement (27) 1}
+enhancedSecurity OBJECT IDENTIFIER   ::=   {module enhancedSecurity (28) }
+
+
+-- synonyms --
+id-oc OBJECT IDENTIFIER   ::=   objectClass
+id-at OBJECT IDENTIFIER   ::=   attributeType
+id-as OBJECT IDENTIFIER   ::=   abstractSyntax
+id-mr OBJECT IDENTIFIER   ::=   matchingRule
+id-nf OBJECT IDENTIFIER   ::=   nameForm
+id-sc OBJECT IDENTIFIER   ::=   subentry
+id-oa OBJECT IDENTIFIER   ::=   operationalAttributeType
+id-ob OBJECT IDENTIFIER   ::=   operationalBinding
+id-doa OBJECT IDENTIFIER   ::=   dsaOperationalAttribute
+id-kmr OBJECT IDENTIFIER   ::=   knowledgeMatchingRule
+id-soc OBJECT IDENTIFIER   ::=   schemaObjectClass
+id-soa OBJECT IDENTIFIER   ::=   schemaOperationalAttribute
+id-ar OBJECT IDENTIFIER   ::=   administrativeRoles
+id-aca OBJECT IDENTIFIER   ::=   accessControlAttribute
+id-ac OBJECT IDENTIFIER   ::=   applicationContext
+id-rosObject OBJECT IDENTIFIER   ::=   rosObject
+id-contract OBJECT IDENTIFIER   ::=   contract
+id-package OBJECT IDENTIFIER   ::=   package
+id-acScheme OBJECT IDENTIFIER   ::=   accessControlSchemes
+id-ce OBJECT IDENTIFIER   ::=   certificateExtension
+id-mgt OBJECT IDENTIFIER   ::=   managementObject
+-- obsolete module identifiers --
+--   usefulDefinitions OBJECT IDENTIFIER   ::=   {module 0}
+--   informationFramework OBJECT IDENTIFIER   ::=   {module 1}
+--    directoryAbstractService OBJECT IDENTIFIER   ::=   {module 2}
+--    distributedOperations OBJECT IDENTIFIER   ::=   {module 3}
+--   protocolObjectIdentifiers OBJECT IDENTIFIER   ::=   {module 4}
+--    selectedAttributeTypes OBJECT IDENTIFIER   ::=   {module 5}
+--    selectedObjectClasses OBJECT IDENTIFIER   ::=   {module 6}
+--   authenticationFramework OBJECT IDENTIFIER   ::=   {module 7}
+--   algorithmObjectIdentifiers OBJECT IDENTIFIER   ::=   {module 8}
+--   directoryObjectIdentifiers OBJECT IDENTIFIER   ::=   {module 9}
+--   upperBounds OBJECT IDENTIFIER   ::=   {module 10}
+--   dap OBJECT IDENTIFIER   ::=   {module 11}
+--   dsp OBJECT IDENTIFIER   ::=   {module 12}
+--   distributedDirectoryObjectIdentifiers
+-- OBJECT IDENTIFIER   ::=   {module 13}
+-- unused module identifiers --
+--   directoryShadowOIDs OBJECT IDENTIFIER   ::=   {module 14}
+--   directoryShadowAbstractService OBJECT IDENTIFIER   ::=   {module 15}
+--   disp OBJECT IDENTIFIER   ::=   {module 16}
+--   dop OBJECT IDENTIFIER   ::=   {module 17}
+--   opBindingManagement OBJECT IDENTIFIER   ::=   {module 18}
+--   opBindingOIDs OBJECT IDENTIFIER   ::=   {module 19}
+--   hierarchicalOperationalBindings OBJECT IDENTIFIER   ::=   {module 20}
+--   dsaOperationalAttributeTypes OBJECT IDENTIFIER   ::=   {module 22}
+--   schemaAdministration OBJECT IDENTIFIER   ::=   {module 23}
+--   basicAccessControl    OBJECT IDENTIFIER   ::=   {module 24}
+--   operationalBindingOIDs OBJECT IDENTIFIER   ::=   {module 25}
+END
diff --git a/SecurityASN1/asn/sm_x509af.asn b/SecurityASN1/asn/sm_x509af.asn
new file mode 100644
index 00000000..8fd9ef6e
--- /dev/null
+++ b/SecurityASN1/asn/sm_x509af.asn
@@ -0,0 +1,215 @@
+-- @(#) sm_x509af.asn 1.2 2/24/98 13:40:34 
+AuthenticationFramework 
+-- 
+-- oid defined in sm_x501ud.asn
+--
+-- {joint-iso-ccitt ds(5) module(1) authenticationFramework(7) 3}
+
+DEFINITIONS ::=
+
+BEGIN
+
+-- EXPORTS All --
+-- The types and values defined in this module are exported for use in the 
+-- other ASN.1 modules contained 
+-- within the Directory Specifications, and for the use of other applications
+-- which will use them to access Directory services. Other applications may 
+-- use them for their own purposes, but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory 
+-- service.
+
+IMPORTS
+
+   BigIntegerStr
+   FROM VdaEnhancedTypes
+
+   id-at, informationFramework, upperBounds, selectedAttributeTypes, 
+   basicAccessControl, certificateExtensions
+      FROM UsefulDefinitions { usefulDefinitions }
+
+   Name, Attribute, AttributeType
+      FROM InformationFramework  { informationFramework }
+
+   ub-password-length
+      FROM UpperBounds  { upperBounds }
+
+-- not used
+--   AuthenticationLevel
+--     FROM BasicAccessControl { basicAccessControl }
+
+--   GeneralNames
+--      FROM CertificateExtensions { certificateExtensions }
+
+   GeneralNames
+        FROM CommonX509Definitions
+
+   UniqueIdentifier
+      FROM SelectedAttributeTypes  { selectedAttributeTypes } ;
+
+-- basic certificate definition
+
+Certificate ::= SEQUENCE {
+    certificateToSign    CertificateToSign,
+    algorithmIdentifier  AlgorithmIdentifier,
+    signatureValue       BIT STRING }
+
+CertificateToSign ::=  SEQUENCE {
+   version           [0]  Version DEFAULT v1,
+   serialNumber           CertificateSerialNumber,
+   signature              AlgorithmIdentifier,
+   issuer                 Name,
+   validity               Validity,
+   subject                Name,
+   subjectPublicKeyInfo   SubjectPublicKeyInfo,
+                        -- if present, version must be v2 or v3
+   issuerUniqueIdentifier   [1]   IMPLICIT UniqueIdentifier OPTIONAL,
+                        -- if present, version must be v2 or v3
+   subjectUniqueIdentifier  [2]   IMPLICIT UniqueIdentifier OPTIONAL,
+                        -- If present, version must be v3 
+   extensions         [3]   Extensions OPTIONAL }
+
+Version            ::=   INTEGER { v1(0), v2(1), v3(2) }
+
+-- CertificateSerialNumber   ::=   INTEGER
+
+CertificateSerialNumber ::= BigIntegerStr
+
+
+AlgorithmIdentifier      ::=   SEQUENCE {
+   algorithm       OBJECT IDENTIFIER,
+   parameters      ANY OPTIONAL }
+
+Validity            ::=   SEQUENCE {
+   notBefore   Time,
+   notAfter    Time }
+
+SubjectPublicKeyInfo   ::=   SEQUENCE {
+   algorithm          AlgorithmIdentifier,
+   subjectPublicKey   BIT STRING }
+
+Time  ::=  CHOICE { 
+   utcTime       UTCTime, 
+   generalizedTime   GeneralizedTime }
+
+Extensions ::= SEQUENCE OF Extension
+
+-- For those extensions where ordering of individual extensions within the 
+-- SEQUENCE is significant, the specification of those individual extensions
+--  shall include the rules for the significance of the order therein
+
+Extension ::= SEQUENCE {
+   extnId      OBJECT IDENTIFIER,
+   critical    BOOLEAN DEFAULT FALSE,
+               -- extnValue contains a DER encoding
+   extnValue   OCTET STRING }
+
+-- other certifiate constructs
+
+Certificates            ::=   SEQUENCE {
+   userCertificate      Certificate,
+   certificationPath    ForwardCertificationPath OPTIONAL }
+
+ForwardCertificationPath ::=   SEQUENCE OF CrossCertificates
+
+CrossCertificates ::=   SET OF Certificate
+
+CertificationPath ::=   SEQUENCE {
+   userCertificate      Certificate,
+   theCACertificates    SEQUENCE OF CertificatePair OPTIONAL }
+
+CertificatePair ::=   SEQUENCE {
+   -- at least one of the pair shall be present
+   forward      [0]   Certificate OPTIONAL, 
+   reverse      [1]   Certificate OPTIONAL }
+
+-- certificate revocation list (CRL)
+
+CertificateList ::= SEQUENCE {
+   crlToSign           CRLToSign,
+   algorithmIdentifier AlgorithmIdentifier,
+   signatureValue      BIT STRING }
+   
+CRLToSign ::= SEQUENCE {
+   version           Version OPTIONAL, -- if present, version must be v2
+   signature         AlgorithmIdentifier,
+   issuer            Name,
+   thisUpdate        Time,
+   nextUpdate        Time OPTIONAL,
+   revokedCertificates   SEQUENCE OF SEQUENCE {
+         userCertificate      CertificateSerialNumber,
+         revocationDate       Time,
+         crlEntryExtensions   Extensions OPTIONAL } OPTIONAL,
+   crlExtensions   [0]  Extensions OPTIONAL }
+
+-- attribute certificate
+AttributeCertificationPath  ::=  SEQUENCE {
+   attributeCertificate   AttributeCertificate, 
+   acPath      SEQUENCE OF ACPathData OPTIONAL }
+
+ACPathData  ::=  SEQUENCE {
+   certificate            [0]  Certificate  OPTIONAL,
+   attributeCertificate   [1]  AttributeCertificate  OPTIONAL }
+
+AttributeCertificate ::= SEQUENCE {
+   attributeCertificateInfo AttributeCertificateInfo,
+   algorithmIdentifier      AlgorithmIdentifier,
+   signatureValue           BIT STRING }
+
+AttributeCertificateInfo ::= SEQUENCE {
+   version         Version DEFAULT v1,
+   subject   CHOICE {
+      baseCertificateID [0] IssuerSerial,    -- associated  with a Public Key 
+                                             -- Certificate 
+      subjectName       [1] GeneralNames },  -- associated  with a name 
+   issuer                 GeneralNames, -- CA issuing the attribute certificate
+   signature              AlgorithmIdentifier,
+   serialNumber           CertificateSerialNumber,
+   attCertValidityPeriod  AttCertValidityPeriod,
+   attributes      SEQUENCE OF Attribute,
+   issuerUniqueID   UniqueIdentifier OPTIONAL,
+   extensions      Extensions OPTIONAL }
+
+IssuerSerial  ::= SEQUENCE {
+   issuer       GeneralNames,
+   serial       CertificateSerialNumber,
+   issuerUID    UniqueIdentifier OPTIONAL}
+
+AttCertValidityPeriod ::= SEQUENCE {
+   notBeforeTime   GeneralizedTime,
+   notAfterTime   GeneralizedTime }
+
+AttributeCertificateAssertion  ::=  SEQUENCE  {
+   -- At least one component of the sequence must be present
+   subject      [0]   CHOICE {
+      baseCertificateID   [0]  IssuerSerial,
+      subjectName         [1]  Name } OPTIONAL,
+   issuer          [1]   Name OPTIONAL,
+   attCertValidity [2]   GeneralizedTime OPTIONAL,
+   attType         [3]   SET OF AttributeType OPTIONAL }
+
+-- attribute types --
+
+UserPassword ::= OCTET STRING (SIZE (0..ub-password-length))
+
+UserCertificate ::= Certificate
+
+CACertificate ::= Certificate
+
+CrossCertificatePair ::= CertificatePair
+
+AuthorityRevocationList ::= CertificateList
+
+CertificateRevocationList ::= CertificateList
+
+AttributeCertificateRevocationList ::= CertificateList
+
+-- object identifier assignments --
+id-at-userPassword      OBJECT IDENTIFIER   ::=   {id-at 35} 
+id-at-userCertificate      OBJECT IDENTIFIER   ::=   {id-at 36}
+id-at-cAcertificate         OBJECT IDENTIFIER   ::=   {id-at 37}
+id-at-authorityRevocationList   OBJECT IDENTIFIER   ::=   {id-at 38}
+id-at-certificateRevocationList   OBJECT IDENTIFIER   ::=   {id-at 39}
+id-at-crossCertificatePair      OBJECT IDENTIFIER   ::=   {id-at 40}
+id-at-attributeCertificate      OBJECT IDENTIFIER   ::=   {id-at 58}
+
+END
diff --git a/SecurityASN1/asn/sm_x509ce.asn b/SecurityASN1/asn/sm_x509ce.asn
new file mode 100644
index 00000000..b096a241
--- /dev/null
+++ b/SecurityASN1/asn/sm_x509ce.asn
@@ -0,0 +1,265 @@
+-- @(#) sm_x509ce.asn 1.3 3/4/98 15:25:14 
+CertificateExtensions 
+--
+-- oid defined sm_x501ud.asn
+-- {joint-iso-ccitt ds(5) module(1) certificateExtensions(26) 0}
+
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS ALL
+
+IMPORTS
+   id-at, id-ce, id-mr, informationFramework, authenticationFramework,
+      selectedAttributeTypes, upperBounds
+      FROM UsefulDefinitions { usefulDefinitions }
+
+   Name, RelativeDistinguishedName, Attribute
+      FROM InformationFramework  { informationFramework }
+
+   GeneralNames, GeneralName
+      FROM CommonX509Definitions 
+
+   CertificateSerialNumber, CertificateList, AlgorithmIdentifier
+      FROM AuthenticationFramework { authenticationFramework }
+
+   DirectoryString
+      FROM SelectedAttributeTypes  { selectedAttributeTypes }
+
+   ORAddress
+      FROM MTSAbstractService { mTSAbstractService } 
+	   
+   id-pkix
+	  FROM ExtendedSecurityServices { extendedSecurityServices };
+
+-- Unless explicitly noted otherwise, there is no significance to the ordering
+-- of components of a SEQUENCE OF construct in this specification.
+
+-- Key and policy information extensions --
+
+AuthorityKeyIdentifier ::= SEQUENCE {
+   keyIdentifier             [0] KeyIdentifier           OPTIONAL,
+   authorityCertIssuer       [1] GeneralNames            OPTIONAL,
+   authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+
+KeyIdentifier ::= OCTET STRING
+
+SubjectKeyIdentifier ::= KeyIdentifier
+
+KeyUsage ::= BIT STRING {
+   digitalSignature (0),
+   nonRepudiation   (1),
+   keyEncipherment  (2),
+   dataEncipherment (3),
+   keyAgreement     (4),
+   keyCertSign      (5),
+   cRLSign          (6),
+   encipherOnly     (7),
+   decipherOnly     (8) }
+
+KeyPurposeId ::= OBJECT IDENTIFIER
+
+-- Added 9/14/00 by dmitch
+ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+
+PrivateKeyUsagePeriod ::= SEQUENCE {
+   notBefore   [0]   GeneralizedTime OPTIONAL,
+   notAfter   [1]   GeneralizedTime OPTIONAL }
+   ( WITH COMPONENTS    {..., notBefore PRESENT} |
+   WITH COMPONENTS    {..., notAfter PRESENT} )
+
+
+CertificatePoliciesSyntax ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+
+PolicyInformation ::= SEQUENCE {
+   policyIdentifier   CertPolicyId,
+   policyQualifiers   SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL }
+
+CertPolicyId ::= OBJECT IDENTIFIER
+
+PolicyQualifierInfo ::= SEQUENCE {
+   policyQualifierId   OBJECT IDENTIFIER,
+   qualifier           ANY OPTIONAL }
+
+PolicyMappingsSyntax ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
+   issuerDomainPolicy      CertPolicyId,
+   subjectDomainPolicy   CertPolicyId }
+
+SupportedAlgorithm ::= SEQUENCE {
+   algorithmIdentifier             AlgorithmIdentifier,
+   intendedUsage               [0] KeyUsage OPTIONAL,
+   intendedCertificatePolicies [1] CertificatePoliciesSyntax OPTIONAL }
+
+-- Certificate subject and certificate issuer attributes extensions --
+
+SubjectName ::= GeneralNames
+
+-- moved to sm_x509cmn.asn since both sm_x509af.asn and sm_x509ce.asn need
+-- it
+--
+-- GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+-- GeneralName ::= CHOICE {
+--    otherName        [0]   OTHER-NAME,
+   -- rfc822Name       [1]   IA5String,
+   -- dNSName          [2]   IA5String,
+   -- x400Address      [3]   ORAddress,
+   -- directoryName    [4]   Name,
+   -- ediPartyName     [5]   EDIPartyName,
+   -- uniformResourceIdentifier  [6]   IA5String,
+   -- iPAddress                  [7]   OCTET STRING,
+   -- registeredID               [8]   OBJECT IDENTIFIER }
+-- 
+-- OTHER-NAME ::= OBJECT IDENTIFIER
+
+-- EDIPartyName ::= SEQUENCE {
+   -- nameAssigner      [0]   DirectoryString  OPTIONAL,
+   -- partyName         [1]   DirectoryString  }
+-- 
+
+IssuerAltName ::= GeneralNames
+
+SubjectDirectoryAttributes ::= AttributesSyntax
+
+AttributesSyntax ::= SEQUENCE SIZE (1..MAX) OF Attribute
+
+
+-- Certification path constraints extensions --
+
+BasicConstraintsSyntax ::= SEQUENCE {
+   cA         BOOLEAN DEFAULT FALSE,
+   pathLenConstraint    INTEGER (0..MAX) OPTIONAL }
+
+NameConstraintsSyntax ::= SEQUENCE {
+   permittedSubtrees   [0]   GeneralSubtrees OPTIONAL,
+   excludedSubtrees   [1]   GeneralSubtrees OPTIONAL }
+
+GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+GeneralSubtree ::= SEQUENCE {
+   base         GeneralName,
+   minimum      [0]   BaseDistance DEFAULT 0,
+   maximum      [1]   BaseDistance OPTIONAL }
+
+BaseDistance ::= INTEGER (0..MAX)
+
+PolicyConstraintsSyntax ::= SEQUENCE {
+   requireExplicitPolicy   [0] SkipCerts OPTIONAL,
+   inhibitPolicyMapping   [1] SkipCerts OPTIONAL }
+
+SkipCerts ::= INTEGER (0..MAX) 
+
+CertPolicySet ::= SEQUENCE OF CertPolicyId
+
+-- Basic CRL extensions --
+
+CRLNumber ::= INTEGER (0..MAX)
+
+CRLReason ::= ENUMERATED {
+   unspecified          (0),
+   keyCompromise        (1), 
+   cACompromise         (2), 
+   affiliationChanged   (3), 
+   superseded           (4),
+   cessationOfOperation (5),
+   certificateHold      (6),  -- note 7 is not used by this spec.
+   removeFromCRL        (8) }
+
+HoldInstruction ::= OBJECT IDENTIFIER
+
+
+InvalidityDate ::= GeneralizedTime
+
+-- CRL distribution points and delta-CRL extensions --
+
+CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint 
+
+DistributionPoint ::= SEQUENCE {
+   distributionPoint   [0]   DistributionPointName OPTIONAL,
+   reasons             [1]   ReasonFlags OPTIONAL,
+   cRLIssuer           [2]   GeneralNames OPTIONAL }
+
+DistributionPointName ::= CHOICE {
+   fullName                [0]   GeneralNames,
+   nameRelativeToCRLIssuer [1]   RelativeDistinguishedName }
+
+ReasonFlags ::= BIT STRING {
+   unused               (0),
+   keyCompromise        (1), 
+   caCompromise         (2), 
+   affiliationChanged   (3), 
+   superseded           (4),
+   cessationOfOperation (5),
+   certificateHold      (6) }
+
+IssuingDistPointSyntax ::= SEQUENCE {
+   distributionPoint      [0] DistributionPointName OPTIONAL,
+   onlyContainsUserCerts  [1] BOOLEAN DEFAULT FALSE,
+   onlyContainsCACerts    [2] BOOLEAN DEFAULT FALSE,
+   onlySomeReasons        [3] ReasonFlags OPTIONAL,
+   indirectCRL            [4] BOOLEAN DEFAULT FALSE }
+
+CertificateIssuer ::= GeneralNames
+
+BaseCRLNumber ::= CRLNumber
+
+DeltaRevocationList ::= CertificateList
+
+-- Matching rules 
+
+-- removed.  Our ASN.1 compiler does not support matching ruling.  We will
+-- do this manually -Pierce
+--
+
+-- end of Matching rules
+
+-- Object identifier assignments --
+
+id-at-supportedAlgorithms      OBJECT IDENTIFIER   ::=   {id-at 52}
+id-at-deltaRevocationList         OBJECT IDENTIFIER   ::=   {id-at 53}
+id-ce-subjectDirectoryAttributes      OBJECT IDENTIFIER   ::=   {id-ce 9}
+id-ce-subjectKeyIdentifier      OBJECT IDENTIFIER   ::=   {id-ce 14}
+id-ce-keyUsage            OBJECT IDENTIFIER   ::=   {id-ce 15}
+id-ce-privateKeyUsagePeriod      OBJECT IDENTIFIER   ::=   {id-ce 16}
+id-ce-subjectAltName         OBJECT IDENTIFIER   ::=   {id-ce 17}
+id-ce-issuerAltName         OBJECT IDENTIFIER   ::=   {id-ce 18}
+id-ce-basicConstraints         OBJECT IDENTIFIER   ::=   {id-ce 19}
+id-ce-cRLNumber            OBJECT IDENTIFIER   ::=   {id-ce 20}
+id-ce-reasonCode            OBJECT IDENTIFIER   ::=   {id-ce 21}
+id-ce-instructionCode         OBJECT IDENTIFIER   ::=   {id-ce 23}
+id-ce-invalidityDate         OBJECT IDENTIFIER   ::=   {id-ce 24}
+id-ce-deltaCRLIndicator         OBJECT IDENTIFIER   ::=   {id-ce 27}
+id-ce-issuingDistributionPoint      OBJECT IDENTIFIER   ::=   {id-ce 28}
+id-ce-certificateIssuer         OBJECT IDENTIFIER   ::=   {id-ce 29}
+id-ce-nameConstraints         OBJECT IDENTIFIER   ::=   {id-ce 30}
+id-ce-cRLDistributionPoints      OBJECT IDENTIFIER   ::=   {id-ce 31}
+id-ce-certificatePolicies         OBJECT IDENTIFIER   ::=   {id-ce 32}
+id-ce-policyMappings         OBJECT IDENTIFIER   ::=   {id-ce 33}
+-- deprecated               OBJECT IDENTIFIER   ::=   {id-ce 34}
+id-ce-authorityKeyIdentifier      OBJECT IDENTIFIER   ::=   {id-ce 35}
+id-ce-policyConstraints         OBJECT IDENTIFIER   ::=   {id-ce 36}
+id-ce-extKeyUsage         OBJECT IDENTIFIER   ::=   {id-ce 37}
+id-mr-certificateExactMatch      OBJECT IDENTIFIER   ::=   {id-mr 34}
+id-mr-certificateMatch         OBJECT IDENTIFIER   ::=   {id-mr 35}
+id-mr-certificatePairExactMatch      OBJECT IDENTIFIER   ::=   {id-mr 36}
+id-mr-certificatePairMatch      OBJECT IDENTIFIER   ::=   {id-mr 37}
+id-mr-certificateListExactMatch      OBJECT IDENTIFIER   ::=   {id-mr 38}
+id-mr-certificateListMatch      OBJECT IDENTIFIER   ::=   {id-mr 39}
+id-mr-algorithmIdentifierMatch      OBJECT IDENTIFIER   ::=   {id-mr 40}
+
+id-kp 						OBJECT IDENTIFIER ::= {id-pkix 3}
+id-kp-serverAuth 			OBJECT IDENTIFIER ::= {id-kp 1}
+id-kp-clientAuth 			OBJECT IDENTIFIER ::= {id-kp 2}
+id-kp-codeSigning 			OBJECT IDENTIFIER ::= {id-kp 3}
+id-kp-emailProtection 		OBJECT IDENTIFIER ::= {id-kp 4}
+id-kp-timeStamping 			OBJECT IDENTIFIER ::= {id-kp 8}
+ 
+id-netscape-cert-type		OBJECT IDENTIFIER ::= {2 16 840 1 113730 1 1}
+
+-- The following OBJECT IDENTIFIERS are not used by this specification:
+-- {id-ce 2}, {id-ce 3}, {id-ce 4}, {id-ce 5}, {id-ce 6}, {id-ce 7},
+-- {id-ce 8}, {id-ce 10}, {id-ce 11}, {id-ce 12}, {id-ce 13}, 
+-- {id-ce 22}, {id-ce 25}, {id-ce 26}
+
+END
diff --git a/SecurityASN1/asn/sm_x509cmn.asn b/SecurityASN1/asn/sm_x509cmn.asn
new file mode 100644
index 00000000..94f6e86b
--- /dev/null
+++ b/SecurityASN1/asn/sm_x509cmn.asn
@@ -0,0 +1,41 @@
+-- @(#) sm_x509cmn.asn 1.3 3/2/98 12:56:14 
+CommonX509Definitions
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- EXPORTS ALL
+
+IMPORTS
+   informationFramework, selectedAttributeTypes
+      FROM UsefulDefinitions { usefulDefinitions }
+
+   Name
+      FROM InformationFramework  { informationFramework }
+
+   DirectoryString
+      FROM SelectedAttributeTypes  { selectedAttributeTypes }
+
+   ORAddress
+      FROM MTSAbstractService { mTSAbstractService } ;
+
+GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+GeneralName ::= CHOICE {
+   otherName        [0]   OTHER-NAME,
+   rfc822Name       [1]   IA5String,
+   dNSName          [2]   IA5String,
+   x400Address      [3]   ORAddress,
+   directoryName    [4]   Name,
+   ediPartyName     [5]   EDIPartyName,
+   uniformResourceIdentifier  [6]   IA5String,
+   iPAddress                  [7]   OCTET STRING,
+   registeredID               [8]   OBJECT IDENTIFIER }
+
+OTHER-NAME ::= OBJECT IDENTIFIER
+
+EDIPartyName ::= SEQUENCE {
+   nameAssigner      [0]   DirectoryString  OPTIONAL,
+   partyName         [1]   DirectoryString  }
+
+END
diff --git a/SecurityASN1/asn/sm_x520sa.asn b/SecurityASN1/asn/sm_x520sa.asn
new file mode 100644
index 00000000..6483a153
--- /dev/null
+++ b/SecurityASN1/asn/sm_x520sa.asn
@@ -0,0 +1,196 @@
+-- @(#) sm_x520sa.asn 1.3 4/27/98 14:42:39 
+SelectedAttributeTypes 
+-- 
+-- oid defined in sm_x501ud.asn
+--
+-- {joint-iso-ccitt ds(5) module(1) selectedAttributeTypes(5) 2}
+DEFINITIONS ::=
+
+BEGIN
+
+-- EXPORTS All --
+
+-- The types and values defined in this module are exported for use in the 
+-- other ASN.1 modules contained 
+-- within the Directory Specifications, and for the use of other applications
+--  which will use them to access 
+-- Directory services. Other applications may use them for their own purposes,
+--  but this will not constrain
+-- extensions and modifications needed to maintain or improve the Directory 
+-- service.
+IMPORTS
+
+   informationFramework, upperBounds, id-at, id-mr
+   FROM  UsefulDefinitions { usefulDefinitions }
+
+   AttributeType, DistinguishedName
+   FROM InformationFramework  { informationFramework } ;
+
+-- Directory string type --
+
+UniqueIdentifier ::= BIT STRING
+
+DirectoryString ::= CHOICE {
+   teletexString     TeletexString (SIZE (1..MAX)),
+   printableString   PrintableString (SIZE (1..MAX)),
+   universalString   UniversalString (SIZE (1..MAX)),
+   bmpString         BMPString (SIZE (1..MAX)),
+   utf8String        UTF8String (SIZE (1..MAX)) }
+
+
+-- Object identifier assignments 
+-- object identifiers assigned in other modules are shown in comments
+-- Attributes 
+-- id-at-objectClass   OBJECT IDENTIFIER   ::=   {id-at 0}
+-- id-at-aliasedEntryName   OBJECT IDENTIFIER   ::=   {id-at 1}
+id-at-encryptedAliasedEntryName   OBJECT IDENTIFIER   ::=   {id-at 1 2}
+id-at-knowledgeInformation   OBJECT IDENTIFIER   ::=   {id-at 2}
+id-at-commonName    OBJECT IDENTIFIER   ::=   {id-at 3}
+id-at-encryptedCommonName    OBJECT IDENTIFIER   ::=   {id-at 3 2}
+id-at-surname    OBJECT IDENTIFIER   ::=   {id-at 4}
+id-at-encryptedSurname    OBJECT IDENTIFIER   ::=   {id-at 4 2}
+id-at-serialNumber    OBJECT IDENTIFIER   ::=   {id-at 5}
+id-at-encryptedSerialNumber    OBJECT IDENTIFIER   ::=   {id-at 5 2}
+id-at-countryName    OBJECT IDENTIFIER   ::=   {id-at 6}
+id-at-encryptedCountryName    OBJECT IDENTIFIER   ::=   {id-at 6 2}
+id-at-localityName    OBJECT IDENTIFIER   ::=   {id-at 7}
+id-at-encryptedLocalityName    OBJECT IDENTIFIER   ::=   {id-at 7 2}
+id-at-collectiveLocalityName    OBJECT IDENTIFIER   ::=   {id-at 7 1}
+id-at-encryptedCollectiveLocalityName OBJECT IDENTIFIER   ::=   {id-at 7 1 2}
+id-at-stateOrProvinceName    OBJECT IDENTIFIER   ::=   {id-at 8}
+id-at-encryptedStateOrProvinceName OBJECT IDENTIFIER   ::=   {id-at 8 2}
+id-at-collectiveStateOrProvinceName    OBJECT IDENTIFIER   ::=   {id-at 8 1}
+id-at-encryptedCollectiveStateOrProvinceName OBJECT IDENTIFIER   ::=   {id-at 8 1 2}
+id-at-streetAddress    OBJECT IDENTIFIER   ::=   {id-at 9}
+id-at-encryptedStreetAddress    OBJECT IDENTIFIER   ::=   {id-at 9 2}
+id-at-collectiveStreetAddress    OBJECT IDENTIFIER   ::=   {id-at 9 1}
+id-at-encryptedCollectiveStreetAddress OBJECT IDENTIFIER   ::=   {id-at 9 1 2}
+id-at-organizationName    OBJECT IDENTIFIER   ::=   {id-at 10}
+id-at-encryptedOrganizationName    OBJECT IDENTIFIER   ::=   {id-at 10 2}
+id-at-collectiveOrganizationName OBJECT IDENTIFIER   ::=   {id-at 10 1}
+id-at-encryptedCollectiveOrganizationName OBJECT IDENTIFIER   ::=   {id-at 10 1 2}
+id-at-organizationalUnitName   OBJECT IDENTIFIER   ::=   {id-at 11}
+id-at-encryptedOrganizationalUnitName OBJECT IDENTIFIER   ::=   {id-at 11 2}
+id-at-collectiveOrganizationalUnitName OBJECT IDENTIFIER   ::=   {id-at 11 1}
+id-at-encryptedCollectiveOrganizationalUnitName OBJECT IDENTIFIER   ::=   {id-at 11 1 2}
+id-at-title    OBJECT IDENTIFIER   ::=   {id-at 12}
+id-at-encryptedTitle    OBJECT IDENTIFIER   ::=   {id-at 12 2}
+id-at-description    OBJECT IDENTIFIER   ::=   {id-at 13}
+id-at-encryptedDescription    OBJECT IDENTIFIER   ::=   {id-at 13 2}
+id-at-searchGuide    OBJECT IDENTIFIER   ::=   {id-at 14}
+id-at-encryptedSearchGuide    OBJECT IDENTIFIER   ::=   {id-at 14 2}
+id-at-businessCategory    OBJECT IDENTIFIER   ::=   {id-at 15}
+id-at-encryptedBusinessCategory    OBJECT IDENTIFIER   ::=   {id-at 15 2}
+id-at-postalAddress    OBJECT IDENTIFIER   ::=   {id-at 16}
+id-at-encryptedPostalAddress    OBJECT IDENTIFIER   ::=   {id-at 16 2}
+id-at-collectivePostalAddress    OBJECT IDENTIFIER   ::=   {id-at 16 1}
+id-at-encryptedCollectivePostalAddress OBJECT IDENTIFIER   ::=   {id-at 16 1 2}
+id-at-postalCode    OBJECT IDENTIFIER   ::=   {id-at 17}
+id-at-encryptedPostalCode    OBJECT IDENTIFIER   ::=   {id-at 17 2}
+id-at-collectivePostalCode    OBJECT IDENTIFIER   ::=   {id-at 17 1}
+id-at-encryptedCollectivePostalCode    OBJECT IDENTIFIER   ::=   {id-at 17 1 2}
+id-at-postOfficeBox    OBJECT IDENTIFIER   ::=   {id-at 18}
+id-at-encryptedPostOfficeBox    OBJECT IDENTIFIER   ::=   {id-at 18 2}
+id-at-collectivePostOfficeBox    OBJECT IDENTIFIER   ::=   {id-at 18 1}
+id-at-encryptedCollectivePostOfficeBox OBJECT IDENTIFIER   ::=   {id-at 18 1 2}
+id-at-physicalDeliveryOfficeName OBJECT IDENTIFIER   ::=   {id-at 19}
+id-at-encryptedPhysicalDeliveryOfficeName OBJECT IDENTIFIER   ::=   {id-at 19 2}
+id-at-collectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER   ::=   {id-at 19 1}
+id-at-encryptedCollectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER   ::=   {id-at 19 1 2}
+id-at-telephoneNumber   OBJECT IDENTIFIER   ::=   {id-at 20}
+id-at-encryptedTelephoneNumber   OBJECT IDENTIFIER   ::=   {id-at 20 2}
+id-at-collectiveTelephoneNumber   OBJECT IDENTIFIER   ::=   {id-at 20 1}
+id-at-encryptedCollectiveTelephoneNumber OBJECT IDENTIFIER   ::=   {id-at 20 1 2}
+id-at-telexNumber    OBJECT IDENTIFIER   ::=   {id-at 21}
+id-at-encryptedTelexNumber    OBJECT IDENTIFIER   ::=   {id-at 21 2}
+id-at-collectiveTelexNumber      OBJECT IDENTIFIER   ::=   {id-at 21 1}
+id-at-encryptedCollectiveTelexNumber OBJECT IDENTIFIER   ::=   {id-at 21 1 2}
+id-at-teletexTerminalIdentifier    OBJECT IDENTIFIER   ::=   {id-at 22}
+id-at-encryptedTeletexTerminalIdentifier OBJECT IDENTIFIER   ::=   {id-at 22 2}
+id-at-collectiveTeletexTerminalIdentifier   OBJECT IDENTIFIER   ::=   {id-at 22 1}
+id-at-encryptedCollectiveTeletexTerminalIdentifier   OBJECT IDENTIFIER   ::=   {id-at 22 1 2}
+id-at-facsimileTelephoneNumber    OBJECT IDENTIFIER   ::=   {id-at 23}
+id-at-encryptedFacsimileTelephoneNumber OBJECT IDENTIFIER   ::=   {id-at 23 2}
+id-at-collectiveFacsimileTelephoneNumber OBJECT IDENTIFIER   ::=   {id-at 23 1}
+id-at-encryptedCollectiveFacsimileTelephoneNumber OBJECT IDENTIFIER   ::=   {id-at 23 1 2}
+id-at-x121Address    OBJECT IDENTIFIER   ::=   {id-at 24}
+id-at-encryptedX121Address    OBJECT IDENTIFIER   ::=   {id-at 24 2}
+id-at-internationalISDNNumber    OBJECT IDENTIFIER   ::=   {id-at 25}
+id-at-encryptedInternationalISDNNumber OBJECT IDENTIFIER   ::=   {id-at 25 2}
+id-at-collectiveInternationalISDNNumber    OBJECT IDENTIFIER   ::=   {id-at 25 1}
+id-at-encryptedCollectiveInternationalISDNNumber    OBJECT IDENTIFIER   ::=   {id-at 25 1 2}
+id-at-registeredAddress    OBJECT IDENTIFIER   ::=   {id-at 26}
+id-at-encryptedRegisteredAddress    OBJECT IDENTIFIER   ::=   {id-at 26 2}
+id-at-destinationIndicator    OBJECT IDENTIFIER   ::=   {id-at 27}
+id-at-encryptedDestinationIndicator OBJECT IDENTIFIER   ::=   {id-at 27 2}
+id-at-preferredDeliveryMethod    OBJECT IDENTIFIER   ::=   {id-at 28}
+id-at-encryptedPreferredDeliveryMethod OBJECT IDENTIFIER   ::=   {id-at 28 2}
+id-at-presentationAddress   OBJECT IDENTIFIER   ::=   {id-at 29}
+id-at-encryptedPresentationAddress   OBJECT IDENTIFIER   ::=   {id-at 29 2}
+id-at-supportedApplicationContext OBJECT IDENTIFIER   ::=   {id-at 30}
+id-at-encryptedSupportedApplicationContext OBJECT IDENTIFIER   ::=   {id-at 30 2}
+id-at-member    OBJECT IDENTIFIER   ::=   {id-at 31}
+id-at-encryptedMember    OBJECT IDENTIFIER   ::=   {id-at 31 2}
+id-at-owner    OBJECT IDENTIFIER   ::=   {id-at 32}
+id-at-encryptedOwner    OBJECT IDENTIFIER   ::=   {id-at 32 2}
+id-at-roleOccupant    OBJECT IDENTIFIER   ::=   {id-at 33}
+id-at-encryptedRoleOccupant    OBJECT IDENTIFIER   ::=   {id-at 33 2}
+id-at-seeAlso    OBJECT IDENTIFIER   ::=   {id-at 34}
+id-at-encryptedSeeAlso    OBJECT IDENTIFIER   ::=   {id-at 34 2}
+-- id-at-userPassword    OBJECT IDENTIFIER   ::=   {id-at 35}
+id-at-encryptedUserPassword    OBJECT IDENTIFIER   ::=   {id-at 35 2}
+-- id-at-userCertificate    OBJECT IDENTIFIER   ::=   {id-at 36}
+id-at-encryptedUserCertificate    OBJECT IDENTIFIER   ::=   {id-at 36 2}
+-- id-at-cACertificate    OBJECT IDENTIFIER   ::=   {id-at 37}
+id-at-encryptedCACertificate    OBJECT IDENTIFIER   ::=   {id-at 37 2}
+-- id-at-authorityRevocationList    OBJECT IDENTIFIER   ::=   {id-at 38}
+id-at-encryptedAuthorityRevocationList
+    OBJECT IDENTIFIER   ::=   {id-at 38 2}
+-- id-at-certificateRevocationList   OBJECT IDENTIFIER   ::=   {id-at 39}
+id-at-encryptedCertificateRevocationList
+   OBJECT IDENTIFIER   ::=   {id-at 39 2}
+-- id-at-crossCertificatePair   OBJECT IDENTIFIER   ::=   {id-at 40}
+id-at-encryptedCrossCertificatePair      OBJECT IDENTIFIER   ::=   {id-at 40 2}
+id-at-name   OBJECT IDENTIFIER   ::=   {id-at 41}
+id-at-givenName    OBJECT IDENTIFIER   ::=   {id-at 42}
+id-at-encryptedGivenName    OBJECT IDENTIFIER   ::=   {id-at 42 2}
+id-at-initials    OBJECT IDENTIFIER   ::=   {id-at 43}
+id-at-encryptedInitials    OBJECT IDENTIFIER   ::=   {id-at 43 2}
+id-at-generationQualifier   OBJECT IDENTIFIER   ::=   {id-at 44}
+id-at-encryptedGenerationQualifier   OBJECT IDENTIFIER   ::=   {id-at 44 2}
+id-at-uniqueIdentifier    OBJECT IDENTIFIER   ::=   {id-at 45}
+id-at-encryptedUniqueIdentifier    OBJECT IDENTIFIER   ::=   {id-at 45 2}
+id-at-dnQualifier    OBJECT IDENTIFIER   ::=   {id-at 46}
+id-at-encryptedDnQualifier    OBJECT IDENTIFIER   ::=   {id-at 46 2}
+id-at-enhancedSearchGuide    OBJECT IDENTIFIER   ::=   {id-at 47}
+id-at-encryptedEnhancedSearchGuide
+    OBJECT IDENTIFIER   ::=   {id-at 47 2}
+id-at-protocolInformation    OBJECT IDENTIFIER   ::=   {id-at 48}
+id-at-encryptedProtocolInformation
+    OBJECT IDENTIFIER   ::=   {id-at 48 2}
+id-at-distinguishedName    OBJECT IDENTIFIER   ::=   {id-at 49}
+id-at-encryptedDistinguishedName    OBJECT IDENTIFIER   ::=   {id-at 49 2}
+id-at-uniqueMember    OBJECT IDENTIFIER   ::=   {id-at 50}
+id-at-encryptedUniqueMember    OBJECT IDENTIFIER   ::=   {id-at 50 2}
+id-at-houseIdentifier    OBJECT IDENTIFIER   ::=   {id-at 51}
+id-at-encryptedHouseIdentifier    OBJECT IDENTIFIER   ::=   {id-at 51 2}
+--id-at-supportedAlgorithms   OBJECT IDENTIFIER   ::=   {id-at 52}
+id-at-encryptedSupportedAlgorithms    OBJECT IDENTIFIER   ::=   {id-at 52 2}
+--id-at-deltaRevocationList   OBJECT IDENTIFIER   ::=   {id-at 53}
+id-at-encryptedDeltaRevocationList   OBJECT IDENTIFIER   ::=   {id-at 53 2}
+id-at-dmdName   OBJECT IDENTIFIER   ::=   {id-at 54}
+id-at-encryptedDmdName   OBJECT IDENTIFIER   ::=   {id-at 54 2}
+-- id-at-clearance   OBJECT IDENTIFIER   ::=   {id-at 55}
+id-at-encryptedClearance    OBJECT IDENTIFIER   ::=   {id-at 55 2}
+-- id-at-defaultDirQop   OBJECT IDENTIFIER   ::=   {id-at 56}
+id-at-encryptedDefaultDirQop    OBJECT IDENTIFIER   ::=   {id-at 56 2}
+-- id-at-attributeIntegrityInfo   OBJECT IDENTIFIER   ::=   {id-at 57}
+id-at-encryptedAttributeIntegrityInfo   OBJECT IDENTIFIER   ::=   {id-at 57 2}
+--id-at-attributeCertificate   OBJECT IDENTIFIER   ::=   {id-at 58} 
+id-at-encryptedAttributeCertificate   OBJECT IDENTIFIER   ::=   {id-at 58 2}
+-- id-at-attributeCertificateRevocationList   OBJECT IDENTIFIER   ::=   {id-at 59}
+id-at-encryptedAttributeCertificateRevocationList OBJECT IDENTIFIER   ::=   {id-at 59 2}
+-- id-at-confKeyInfo   OBJECT IDENTIFIER   ::=   {id-at 60}
+id-at-encryptedConfKeyInfo   OBJECT IDENTIFIER   ::=   {id-at 60 2}
+
+END
diff --git a/SecurityASN1/c++/.cvsignore b/SecurityASN1/c++/.cvsignore
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/SecurityASN1/c++/.cvsignore
@@ -0,0 +1 @@
+
diff --git a/SecurityASN1/c++/appleoids.cpp b/SecurityASN1/c++/appleoids.cpp
new file mode 100644
index 00000000..9349cb1f
--- /dev/null
+++ b/SecurityASN1/c++/appleoids.cpp
@@ -0,0 +1,2984 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// appleoids.cpp - class member functions for ASN.1 module APPLE-OIDS
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+DSABsafeParams::DSABsafeParams()
+{
+}
+
+DSABsafeParams::DSABsafeParams (const DSABsafeParams &)
+{
+  Asn1Error << "use of incompletely defined DSABsafeParams::DSABsafeParams (const DSABsafeParams &)" << endl;
+  abort();
+}
+
+DSABsafeParams::~DSABsafeParams()
+{
+}
+
+AsnType *DSABsafeParams::Clone() const
+{
+  return new DSABsafeParams;
+}
+
+AsnType *DSABsafeParams::Copy() const
+{
+  return new DSABsafeParams (*this);
+}
+
+#if SNACC_DEEP_COPY
+DSABsafeParams &DSABsafeParams::operator = (const DSABsafeParams &that)
+#else // SNACC_DEEP_COPY
+DSABsafeParams &DSABsafeParams::operator = (const DSABsafeParams &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    keySizeInBits = that.keySizeInBits;
+    p = that.p;
+    q = that.q;
+    g = that.g;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DSABsafeParams &DSABsafeParams::operator = (const DSABsafeParams &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DSABsafeParams::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = g.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = q.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = p.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = keySizeInBits.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DSABsafeParams::BEncContent
+
+
+void DSABsafeParams::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    keySizeInBits.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -100);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    p.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -101);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    q.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -102);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    g.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -103);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -104);
+  }
+  else
+    return;
+} // DSABsafeParams::BDecContent
+
+AsnLen DSABsafeParams::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DSABsafeParams::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DSABsafeParams::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -105);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DSABsafeParams::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DSABsafeParams::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DSABsafeParams::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "keySizeInBits ";
+    os << keySizeInBits;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "p ";
+    os << p;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "q ";
+    os << q;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "g ";
+    os << g;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DSABsafeParams::Print
+
+
+FEECurveParameters::FEECurveParameters()
+{
+  basePrime = NULL;
+}
+
+FEECurveParameters::FEECurveParameters (const FEECurveParameters &)
+{
+  Asn1Error << "use of incompletely defined FEECurveParameters::FEECurveParameters (const FEECurveParameters &)" << endl;
+  abort();
+}
+
+FEECurveParameters::~FEECurveParameters()
+{
+  delete basePrime;
+}
+
+AsnType *FEECurveParameters::Clone() const
+{
+  return new FEECurveParameters;
+}
+
+AsnType *FEECurveParameters::Copy() const
+{
+  return new FEECurveParameters (*this);
+}
+
+#if SNACC_DEEP_COPY
+FEECurveParameters &FEECurveParameters::operator = (const FEECurveParameters &that)
+#else // SNACC_DEEP_COPY
+FEECurveParameters &FEECurveParameters::operator = (const FEECurveParameters &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    primeType = that.primeType;
+    curveType = that.curveType;
+    q = that.q;
+    k = that.k;
+    m = that.m;
+    a = that.a;
+    bb = that.bb;
+    c = that.c;
+    x1Plus = that.x1Plus;
+    x1Minus = that.x1Minus;
+    cOrderPlus = that.cOrderPlus;
+    cOrderMinus = that.cOrderMinus;
+    x1OrderPlus = that.x1OrderPlus;
+    x1OrderMinus = that.x1OrderMinus;
+    if (that.basePrime)
+    {
+      if (!basePrime)
+        basePrime = new BigIntegerStr;
+      *basePrime = *that.basePrime;
+    }
+    else
+    {
+      delete basePrime;
+      basePrime = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined FEECurveParameters &FEECurveParameters::operator = (const FEECurveParameters &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+FEECurveParameters::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (basePrime))
+  {
+    l = basePrime->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = x1OrderMinus.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = x1OrderPlus.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = cOrderMinus.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = cOrderPlus.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = x1Minus.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = x1Plus.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = c.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = bb.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = a.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = m.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = k.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = q.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = curveType.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = primeType.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // FEECurveParameters::BEncContent
+
+
+void FEECurveParameters::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    primeType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -106);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    curveType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -107);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    q.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -108);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    k.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -109);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    m.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -110);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    a.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -111);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    bb.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -112);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    c.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -113);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    x1Plus.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -114);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    x1Minus.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -115);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    cOrderPlus.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -116);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    cOrderMinus.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -117);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    x1OrderPlus.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -118);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    x1OrderMinus.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -119);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    basePrime = new BigIntegerStr;
+    basePrime->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -120);
+  }
+  else
+    return;
+} // FEECurveParameters::BDecContent
+
+AsnLen FEECurveParameters::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void FEECurveParameters::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "FEECurveParameters::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -121);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int FEECurveParameters::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int FEECurveParameters::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void FEECurveParameters::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "primeType ";
+    os << primeType;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "curveType ";
+    os << curveType;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "q ";
+    os << q;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "k ";
+    os << k;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "m ";
+    os << m;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "a ";
+    os << a;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "bb ";
+    os << bb;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "c ";
+    os << c;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "x1Plus ";
+    os << x1Plus;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "x1Minus ";
+    os << x1Minus;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "cOrderPlus ";
+    os << cOrderPlus;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "cOrderMinus ";
+    os << cOrderMinus;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "x1OrderPlus ";
+    os << x1OrderPlus;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "x1OrderMinus ";
+    os << x1OrderMinus;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (basePrime))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "basePrime ";
+    os << *basePrime;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "basePrime ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // FEECurveParameters::Print
+
+
+DSAAlgorithmId::DSAAlgorithmId()
+{
+#if TCL
+  params = new DSABsafeParams;
+#else
+  params = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+DSAAlgorithmId::DSAAlgorithmId (const DSAAlgorithmId &)
+{
+  Asn1Error << "use of incompletely defined DSAAlgorithmId::DSAAlgorithmId (const DSAAlgorithmId &)" << endl;
+  abort();
+}
+
+DSAAlgorithmId::~DSAAlgorithmId()
+{
+  delete params;
+}
+
+AsnType *DSAAlgorithmId::Clone() const
+{
+  return new DSAAlgorithmId;
+}
+
+AsnType *DSAAlgorithmId::Copy() const
+{
+  return new DSAAlgorithmId (*this);
+}
+
+#if SNACC_DEEP_COPY
+DSAAlgorithmId &DSAAlgorithmId::operator = (const DSAAlgorithmId &that)
+#else // SNACC_DEEP_COPY
+DSAAlgorithmId &DSAAlgorithmId::operator = (const DSAAlgorithmId &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    algorithm = that.algorithm;
+    if (that.params)
+    {
+      if (!params)
+        params = new DSABsafeParams;
+      *params = *that.params;
+    }
+    else
+    {
+      delete params;
+      params = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DSAAlgorithmId &DSAAlgorithmId::operator = (const DSAAlgorithmId &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DSAAlgorithmId::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = params->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = algorithm.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DSAAlgorithmId::BEncContent
+
+
+void DSAAlgorithmId::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    algorithm.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -122);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    params = new DSABsafeParams;
+    params->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -123);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -124);
+  }
+  else
+    return;
+} // DSAAlgorithmId::BDecContent
+
+AsnLen DSAAlgorithmId::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DSAAlgorithmId::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DSAAlgorithmId::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -125);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DSAAlgorithmId::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DSAAlgorithmId::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DSAAlgorithmId::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "algorithm ";
+    os << algorithm;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (params))
+  {
+    Indent (os, indentG);
+    os << "params ";
+    os << *params;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "params ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DSAAlgorithmId::Print
+
+
+FEEElGamalSignature::FEEElGamalSignature()
+{
+}
+
+FEEElGamalSignature::FEEElGamalSignature (const FEEElGamalSignature &)
+{
+  Asn1Error << "use of incompletely defined FEEElGamalSignature::FEEElGamalSignature (const FEEElGamalSignature &)" << endl;
+  abort();
+}
+
+FEEElGamalSignature::~FEEElGamalSignature()
+{
+}
+
+AsnType *FEEElGamalSignature::Clone() const
+{
+  return new FEEElGamalSignature;
+}
+
+AsnType *FEEElGamalSignature::Copy() const
+{
+  return new FEEElGamalSignature (*this);
+}
+
+#if SNACC_DEEP_COPY
+FEEElGamalSignature &FEEElGamalSignature::operator = (const FEEElGamalSignature &that)
+#else // SNACC_DEEP_COPY
+FEEElGamalSignature &FEEElGamalSignature::operator = (const FEEElGamalSignature &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    u = that.u;
+    pmX = that.pmX;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined FEEElGamalSignature &FEEElGamalSignature::operator = (const FEEElGamalSignature &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+FEEElGamalSignature::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = pmX.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = u.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // FEEElGamalSignature::BEncContent
+
+
+void FEEElGamalSignature::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    u.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -126);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    pmX.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -127);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -128);
+  }
+  else
+    return;
+} // FEEElGamalSignature::BDecContent
+
+AsnLen FEEElGamalSignature::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void FEEElGamalSignature::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "FEEElGamalSignature::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -129);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int FEEElGamalSignature::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int FEEElGamalSignature::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void FEEElGamalSignature::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "u ";
+    os << u;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "pmX ";
+    os << pmX;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // FEEElGamalSignature::Print
+
+
+FEEECDSASignature::FEEECDSASignature()
+{
+}
+
+FEEECDSASignature::FEEECDSASignature (const FEEECDSASignature &)
+{
+  Asn1Error << "use of incompletely defined FEEECDSASignature::FEEECDSASignature (const FEEECDSASignature &)" << endl;
+  abort();
+}
+
+FEEECDSASignature::~FEEECDSASignature()
+{
+}
+
+AsnType *FEEECDSASignature::Clone() const
+{
+  return new FEEECDSASignature;
+}
+
+AsnType *FEEECDSASignature::Copy() const
+{
+  return new FEEECDSASignature (*this);
+}
+
+#if SNACC_DEEP_COPY
+FEEECDSASignature &FEEECDSASignature::operator = (const FEEECDSASignature &that)
+#else // SNACC_DEEP_COPY
+FEEECDSASignature &FEEECDSASignature::operator = (const FEEECDSASignature &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    c = that.c;
+    d = that.d;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined FEEECDSASignature &FEEECDSASignature::operator = (const FEEECDSASignature &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+FEEECDSASignature::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = d.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = c.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // FEEECDSASignature::BEncContent
+
+
+void FEEECDSASignature::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    c.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -130);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    d.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -131);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -132);
+  }
+  else
+    return;
+} // FEEECDSASignature::BDecContent
+
+AsnLen FEEECDSASignature::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void FEEECDSASignature::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "FEEECDSASignature::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -133);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int FEEECDSASignature::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int FEEECDSASignature::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void FEEECDSASignature::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "c ";
+    os << c;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "d ";
+    os << d;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // FEEECDSASignature::Print
+
+
+FEEPublicKey::FEEPublicKey()
+{
+#if TCL
+  curveParams = new FEECurveParameters;
+#else
+  curveParams = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  plusY = NULL;
+}
+
+FEEPublicKey::FEEPublicKey (const FEEPublicKey &)
+{
+  Asn1Error << "use of incompletely defined FEEPublicKey::FEEPublicKey (const FEEPublicKey &)" << endl;
+  abort();
+}
+
+FEEPublicKey::~FEEPublicKey()
+{
+  delete curveParams;
+  delete plusY;
+}
+
+AsnType *FEEPublicKey::Clone() const
+{
+  return new FEEPublicKey;
+}
+
+AsnType *FEEPublicKey::Copy() const
+{
+  return new FEEPublicKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+FEEPublicKey &FEEPublicKey::operator = (const FEEPublicKey &that)
+#else // SNACC_DEEP_COPY
+FEEPublicKey &FEEPublicKey::operator = (const FEEPublicKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.curveParams)
+    {
+      if (!curveParams)
+        curveParams = new FEECurveParameters;
+      *curveParams = *that.curveParams;
+    }
+    else
+    {
+      delete curveParams;
+      curveParams = NULL;
+    }
+    plusX = that.plusX;
+    minusX = that.minusX;
+    if (that.plusY)
+    {
+      if (!plusY)
+        plusY = new BigIntegerStr;
+      *plusY = *that.plusY;
+    }
+    else
+    {
+      delete plusY;
+      plusY = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined FEEPublicKey &FEEPublicKey::operator = (const FEEPublicKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+FEEPublicKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (plusY))
+  {
+    l = plusY->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = minusX.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = plusX.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = curveParams->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // FEEPublicKey::BEncContent
+
+
+void FEEPublicKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -134);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    curveParams = new FEECurveParameters;
+    curveParams->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -135);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    plusX.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -136);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    minusX.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -137);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    plusY = new BigIntegerStr;
+    plusY->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -138);
+  }
+  else
+    return;
+} // FEEPublicKey::BDecContent
+
+AsnLen FEEPublicKey::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void FEEPublicKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "FEEPublicKey::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -139);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int FEEPublicKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int FEEPublicKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void FEEPublicKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (curveParams))
+  {
+    Indent (os, indentG);
+    os << "curveParams ";
+    os << *curveParams;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "curveParams ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "plusX ";
+    os << plusX;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "minusX ";
+    os << minusX;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (plusY))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "plusY ";
+    os << *plusY;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "plusY ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // FEEPublicKey::Print
+
+
+FEEPrivateKey::FEEPrivateKey()
+{
+#if TCL
+  curveParams = new FEECurveParameters;
+#else
+  curveParams = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+FEEPrivateKey::FEEPrivateKey (const FEEPrivateKey &)
+{
+  Asn1Error << "use of incompletely defined FEEPrivateKey::FEEPrivateKey (const FEEPrivateKey &)" << endl;
+  abort();
+}
+
+FEEPrivateKey::~FEEPrivateKey()
+{
+  delete curveParams;
+}
+
+AsnType *FEEPrivateKey::Clone() const
+{
+  return new FEEPrivateKey;
+}
+
+AsnType *FEEPrivateKey::Copy() const
+{
+  return new FEEPrivateKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+FEEPrivateKey &FEEPrivateKey::operator = (const FEEPrivateKey &that)
+#else // SNACC_DEEP_COPY
+FEEPrivateKey &FEEPrivateKey::operator = (const FEEPrivateKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.curveParams)
+    {
+      if (!curveParams)
+        curveParams = new FEECurveParameters;
+      *curveParams = *that.curveParams;
+    }
+    else
+    {
+      delete curveParams;
+      curveParams = NULL;
+    }
+    privData = that.privData;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined FEEPrivateKey &FEEPrivateKey::operator = (const FEEPrivateKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+FEEPrivateKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = privData.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = curveParams->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // FEEPrivateKey::BEncContent
+
+
+void FEEPrivateKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -140);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    curveParams = new FEECurveParameters;
+    curveParams->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -141);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    privData.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -142);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -143);
+  }
+  else
+    return;
+} // FEEPrivateKey::BDecContent
+
+AsnLen FEEPrivateKey::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void FEEPrivateKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "FEEPrivateKey::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -144);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int FEEPrivateKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int FEEPrivateKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void FEEPrivateKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (curveParams))
+  {
+    Indent (os, indentG);
+    os << "curveParams ";
+    os << *curveParams;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "curveParams ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "privData ";
+    os << privData;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // FEEPrivateKey::Print
+
+
+DSAPrivateKey::DSAPrivateKey()
+{
+#if TCL
+  dsaAlg = new DSAAlgorithmId;
+#else
+  dsaAlg = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+DSAPrivateKey::DSAPrivateKey (const DSAPrivateKey &)
+{
+  Asn1Error << "use of incompletely defined DSAPrivateKey::DSAPrivateKey (const DSAPrivateKey &)" << endl;
+  abort();
+}
+
+DSAPrivateKey::~DSAPrivateKey()
+{
+  delete dsaAlg;
+}
+
+AsnType *DSAPrivateKey::Clone() const
+{
+  return new DSAPrivateKey;
+}
+
+AsnType *DSAPrivateKey::Copy() const
+{
+  return new DSAPrivateKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+DSAPrivateKey &DSAPrivateKey::operator = (const DSAPrivateKey &that)
+#else // SNACC_DEEP_COPY
+DSAPrivateKey &DSAPrivateKey::operator = (const DSAPrivateKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.dsaAlg)
+    {
+      if (!dsaAlg)
+        dsaAlg = new DSAAlgorithmId;
+      *dsaAlg = *that.dsaAlg;
+    }
+    else
+    {
+      delete dsaAlg;
+      dsaAlg = NULL;
+    }
+    privateKey = that.privateKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DSAPrivateKey &DSAPrivateKey::operator = (const DSAPrivateKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DSAPrivateKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = privateKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = dsaAlg->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DSAPrivateKey::BEncContent
+
+
+void DSAPrivateKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -145);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    dsaAlg = new DSAAlgorithmId;
+    dsaAlg->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -146);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    privateKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -147);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -148);
+  }
+  else
+    return;
+} // DSAPrivateKey::BDecContent
+
+AsnLen DSAPrivateKey::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DSAPrivateKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DSAPrivateKey::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -149);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DSAPrivateKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DSAPrivateKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DSAPrivateKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (dsaAlg))
+  {
+    Indent (os, indentG);
+    os << "dsaAlg ";
+    os << *dsaAlg;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "dsaAlg ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "privateKey ";
+    os << privateKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DSAPrivateKey::Print
+
+
+DSAPublicKey::DSAPublicKey()
+{
+#if TCL
+  dsaAlg = new DSAAlgorithmId;
+#else
+  dsaAlg = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+DSAPublicKey::DSAPublicKey (const DSAPublicKey &)
+{
+  Asn1Error << "use of incompletely defined DSAPublicKey::DSAPublicKey (const DSAPublicKey &)" << endl;
+  abort();
+}
+
+DSAPublicKey::~DSAPublicKey()
+{
+  delete dsaAlg;
+}
+
+AsnType *DSAPublicKey::Clone() const
+{
+  return new DSAPublicKey;
+}
+
+AsnType *DSAPublicKey::Copy() const
+{
+  return new DSAPublicKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+DSAPublicKey &DSAPublicKey::operator = (const DSAPublicKey &that)
+#else // SNACC_DEEP_COPY
+DSAPublicKey &DSAPublicKey::operator = (const DSAPublicKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.dsaAlg)
+    {
+      if (!dsaAlg)
+        dsaAlg = new DSAAlgorithmId;
+      *dsaAlg = *that.dsaAlg;
+    }
+    else
+    {
+      delete dsaAlg;
+      dsaAlg = NULL;
+    }
+    publicKey = that.publicKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DSAPublicKey &DSAPublicKey::operator = (const DSAPublicKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DSAPublicKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = publicKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = dsaAlg->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DSAPublicKey::BEncContent
+
+
+void DSAPublicKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    dsaAlg = new DSAAlgorithmId;
+    dsaAlg->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -150);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    publicKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -151);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -152);
+  }
+  else
+    return;
+} // DSAPublicKey::BDecContent
+
+AsnLen DSAPublicKey::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DSAPublicKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DSAPublicKey::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -153);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DSAPublicKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DSAPublicKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DSAPublicKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (dsaAlg))
+  {
+    Indent (os, indentG);
+    os << "dsaAlg ";
+    os << *dsaAlg;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "dsaAlg ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "publicKey ";
+    os << publicKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DSAPublicKey::Print
+
+
+DSAPrivateKeyOcts::DSAPrivateKeyOcts()
+{
+}
+
+DSAPrivateKeyOcts::DSAPrivateKeyOcts (const DSAPrivateKeyOcts &)
+{
+  Asn1Error << "use of incompletely defined DSAPrivateKeyOcts::DSAPrivateKeyOcts (const DSAPrivateKeyOcts &)" << endl;
+  abort();
+}
+
+DSAPrivateKeyOcts::~DSAPrivateKeyOcts()
+{
+}
+
+AsnType *DSAPrivateKeyOcts::Clone() const
+{
+  return new DSAPrivateKeyOcts;
+}
+
+AsnType *DSAPrivateKeyOcts::Copy() const
+{
+  return new DSAPrivateKeyOcts (*this);
+}
+
+#if SNACC_DEEP_COPY
+DSAPrivateKeyOcts &DSAPrivateKeyOcts::operator = (const DSAPrivateKeyOcts &that)
+#else // SNACC_DEEP_COPY
+DSAPrivateKeyOcts &DSAPrivateKeyOcts::operator = (const DSAPrivateKeyOcts &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    privateKey = that.privateKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DSAPrivateKeyOcts &DSAPrivateKeyOcts::operator = (const DSAPrivateKeyOcts &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DSAPrivateKeyOcts::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = privateKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DSAPrivateKeyOcts::BEncContent
+
+
+void DSAPrivateKeyOcts::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    privateKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -154);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -155);
+  }
+  else
+    return;
+} // DSAPrivateKeyOcts::BDecContent
+
+AsnLen DSAPrivateKeyOcts::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DSAPrivateKeyOcts::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DSAPrivateKeyOcts::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -156);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DSAPrivateKeyOcts::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DSAPrivateKeyOcts::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DSAPrivateKeyOcts::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "privateKey ";
+    os << privateKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DSAPrivateKeyOcts::Print
+
+
+DSASignature::DSASignature()
+{
+}
+
+DSASignature::DSASignature (const DSASignature &)
+{
+  Asn1Error << "use of incompletely defined DSASignature::DSASignature (const DSASignature &)" << endl;
+  abort();
+}
+
+DSASignature::~DSASignature()
+{
+}
+
+AsnType *DSASignature::Clone() const
+{
+  return new DSASignature;
+}
+
+AsnType *DSASignature::Copy() const
+{
+  return new DSASignature (*this);
+}
+
+#if SNACC_DEEP_COPY
+DSASignature &DSASignature::operator = (const DSASignature &that)
+#else // SNACC_DEEP_COPY
+DSASignature &DSASignature::operator = (const DSASignature &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    r = that.r;
+    s = that.s;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DSASignature &DSASignature::operator = (const DSASignature &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DSASignature::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = s.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = r.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DSASignature::BEncContent
+
+
+void DSASignature::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    r.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -157);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    s.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -158);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -159);
+  }
+  else
+    return;
+} // DSASignature::BDecContent
+
+AsnLen DSASignature::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DSASignature::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DSASignature::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -160);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DSASignature::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DSASignature::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DSASignature::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "r ";
+    os << r;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "s ";
+    os << s;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DSASignature::Print
+
+
+DSAAlgParams::DSAAlgParams()
+{
+}
+
+DSAAlgParams::DSAAlgParams (const DSAAlgParams &)
+{
+  Asn1Error << "use of incompletely defined DSAAlgParams::DSAAlgParams (const DSAAlgParams &)" << endl;
+  abort();
+}
+
+DSAAlgParams::~DSAAlgParams()
+{
+}
+
+AsnType *DSAAlgParams::Clone() const
+{
+  return new DSAAlgParams;
+}
+
+AsnType *DSAAlgParams::Copy() const
+{
+  return new DSAAlgParams (*this);
+}
+
+#if SNACC_DEEP_COPY
+DSAAlgParams &DSAAlgParams::operator = (const DSAAlgParams &that)
+#else // SNACC_DEEP_COPY
+DSAAlgParams &DSAAlgParams::operator = (const DSAAlgParams &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    p = that.p;
+    q = that.q;
+    g = that.g;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DSAAlgParams &DSAAlgParams::operator = (const DSAAlgParams &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DSAAlgParams::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = g.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = q.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = p.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DSAAlgParams::BEncContent
+
+
+void DSAAlgParams::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    p.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -161);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    q.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -162);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    g.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -163);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -164);
+  }
+  else
+    return;
+} // DSAAlgParams::BDecContent
+
+AsnLen DSAAlgParams::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DSAAlgParams::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DSAAlgParams::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -165);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DSAAlgParams::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DSAAlgParams::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DSAAlgParams::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "p ";
+    os << p;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "q ";
+    os << q;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "g ";
+    os << g;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DSAAlgParams::Print
+
+
diff --git a/SecurityASN1/c++/pkcs1oids.cpp b/SecurityASN1/c++/pkcs1oids.cpp
new file mode 100644
index 00000000..12eb1615
--- /dev/null
+++ b/SecurityASN1/c++/pkcs1oids.cpp
@@ -0,0 +1,593 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// pkcs1oids.cpp - class member functions for ASN.1 module PKCS1-OIDS
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+RSAPublicKey::RSAPublicKey()
+{
+}
+
+RSAPublicKey::RSAPublicKey (const RSAPublicKey &)
+{
+  Asn1Error << "use of incompletely defined RSAPublicKey::RSAPublicKey (const RSAPublicKey &)" << endl;
+  abort();
+}
+
+RSAPublicKey::~RSAPublicKey()
+{
+}
+
+AsnType *RSAPublicKey::Clone() const
+{
+  return new RSAPublicKey;
+}
+
+AsnType *RSAPublicKey::Copy() const
+{
+  return new RSAPublicKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+RSAPublicKey &RSAPublicKey::operator = (const RSAPublicKey &that)
+#else // SNACC_DEEP_COPY
+RSAPublicKey &RSAPublicKey::operator = (const RSAPublicKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    modulus = that.modulus;
+    publicExponent = that.publicExponent;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RSAPublicKey &RSAPublicKey::operator = (const RSAPublicKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+RSAPublicKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = publicExponent.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = modulus.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // RSAPublicKey::BEncContent
+
+
+void RSAPublicKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    modulus.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -100);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    publicExponent.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -101);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -102);
+  }
+  else
+    return;
+} // RSAPublicKey::BDecContent
+
+AsnLen RSAPublicKey::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void RSAPublicKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "RSAPublicKey::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -103);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int RSAPublicKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int RSAPublicKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void RSAPublicKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "modulus ";
+    os << modulus;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "publicExponent ";
+    os << publicExponent;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // RSAPublicKey::Print
+
+
+RSAPrivateKey::RSAPrivateKey()
+{
+}
+
+RSAPrivateKey::RSAPrivateKey (const RSAPrivateKey &)
+{
+  Asn1Error << "use of incompletely defined RSAPrivateKey::RSAPrivateKey (const RSAPrivateKey &)" << endl;
+  abort();
+}
+
+RSAPrivateKey::~RSAPrivateKey()
+{
+}
+
+AsnType *RSAPrivateKey::Clone() const
+{
+  return new RSAPrivateKey;
+}
+
+AsnType *RSAPrivateKey::Copy() const
+{
+  return new RSAPrivateKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+RSAPrivateKey &RSAPrivateKey::operator = (const RSAPrivateKey &that)
+#else // SNACC_DEEP_COPY
+RSAPrivateKey &RSAPrivateKey::operator = (const RSAPrivateKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    modulus = that.modulus;
+    publicExponent = that.publicExponent;
+    privateExponent = that.privateExponent;
+    prime1 = that.prime1;
+    prime2 = that.prime2;
+    exponent1 = that.exponent1;
+    exponent2 = that.exponent2;
+    coefficient = that.coefficient;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RSAPrivateKey &RSAPrivateKey::operator = (const RSAPrivateKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+RSAPrivateKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = coefficient.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = exponent2.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = exponent1.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = prime2.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = prime1.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = privateExponent.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = publicExponent.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = modulus.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // RSAPrivateKey::BEncContent
+
+
+void RSAPrivateKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -104);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    modulus.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -105);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    publicExponent.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -106);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    privateExponent.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -107);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    prime1.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -108);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    prime2.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -109);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    exponent1.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -110);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    exponent2.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -111);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    coefficient.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -112);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -113);
+  }
+  else
+    return;
+} // RSAPrivateKey::BDecContent
+
+AsnLen RSAPrivateKey::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void RSAPrivateKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "RSAPrivateKey::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -114);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int RSAPrivateKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int RSAPrivateKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void RSAPrivateKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "modulus ";
+    os << modulus;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "publicExponent ";
+    os << publicExponent;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "privateExponent ";
+    os << privateExponent;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "prime1 ";
+    os << prime1;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "prime2 ";
+    os << prime2;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "exponent1 ";
+    os << exponent1;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "exponent2 ";
+    os << exponent2;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "coefficient ";
+    os << coefficient;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // RSAPrivateKey::Print
+
+
diff --git a/SecurityASN1/c++/pkcs7.cpp b/SecurityASN1/c++/pkcs7.cpp
new file mode 100644
index 00000000..350c4f79
--- /dev/null
+++ b/SecurityASN1/c++/pkcs7.cpp
@@ -0,0 +1,514 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// pkcs7.cpp - class member functions for ASN.1 module PKCS7
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+EncryptedContentInfo1::EncryptedContentInfo1()
+{
+#if TCL
+  contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier1;
+#else
+  contentEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  encryptedContent = NULL;
+}
+
+EncryptedContentInfo1::EncryptedContentInfo1 (const EncryptedContentInfo1 &)
+{
+  Asn1Error << "use of incompletely defined EncryptedContentInfo1::EncryptedContentInfo1 (const EncryptedContentInfo1 &)" << endl;
+  abort();
+}
+
+EncryptedContentInfo1::~EncryptedContentInfo1()
+{
+  delete contentEncryptionAlgorithm;
+  delete encryptedContent;
+}
+
+AsnType *EncryptedContentInfo1::Clone() const
+{
+  return new EncryptedContentInfo1;
+}
+
+AsnType *EncryptedContentInfo1::Copy() const
+{
+  return new EncryptedContentInfo1 (*this);
+}
+
+#if SNACC_DEEP_COPY
+EncryptedContentInfo1 &EncryptedContentInfo1::operator = (const EncryptedContentInfo1 &that)
+#else // SNACC_DEEP_COPY
+EncryptedContentInfo1 &EncryptedContentInfo1::operator = (const EncryptedContentInfo1 &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    contentType = that.contentType;
+    if (that.contentEncryptionAlgorithm)
+    {
+      if (!contentEncryptionAlgorithm)
+        contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier1;
+      *contentEncryptionAlgorithm = *that.contentEncryptionAlgorithm;
+    }
+    else
+    {
+      delete contentEncryptionAlgorithm;
+      contentEncryptionAlgorithm = NULL;
+    }
+    if (that.encryptedContent)
+    {
+      if (!encryptedContent)
+        encryptedContent = new EncryptedContent1;
+      *encryptedContent = *that.encryptedContent;
+    }
+    else
+    {
+      delete encryptedContent;
+      encryptedContent = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EncryptedContentInfo1 &EncryptedContentInfo1::operator = (const EncryptedContentInfo1 &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EncryptedContentInfo1::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (encryptedContent))
+  {
+    l = encryptedContent->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = contentEncryptionAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = contentType.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // EncryptedContentInfo1::BEncContent
+
+
+void EncryptedContentInfo1::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -100);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier1;
+    contentEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -101);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedContent = new EncryptedContent1;
+    encryptedContent->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -102);
+  }
+  else
+    return;
+} // EncryptedContentInfo1::BDecContent
+
+AsnLen EncryptedContentInfo1::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EncryptedContentInfo1::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EncryptedContentInfo1::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -103);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EncryptedContentInfo1::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EncryptedContentInfo1::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EncryptedContentInfo1::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "contentType ";
+    os << contentType;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (contentEncryptionAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "contentEncryptionAlgorithm ";
+    os << *contentEncryptionAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "contentEncryptionAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encryptedContent))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "encryptedContent ";
+    os << *encryptedContent;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encryptedContent ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // EncryptedContentInfo1::Print
+
+
+EncryptedData1::EncryptedData1()
+{
+#if TCL
+  encryptedContentInfo = new EncryptedContentInfo1;
+#else
+  encryptedContentInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EncryptedData1::EncryptedData1 (const EncryptedData1 &)
+{
+  Asn1Error << "use of incompletely defined EncryptedData1::EncryptedData1 (const EncryptedData1 &)" << endl;
+  abort();
+}
+
+EncryptedData1::~EncryptedData1()
+{
+  delete encryptedContentInfo;
+}
+
+AsnType *EncryptedData1::Clone() const
+{
+  return new EncryptedData1;
+}
+
+AsnType *EncryptedData1::Copy() const
+{
+  return new EncryptedData1 (*this);
+}
+
+#if SNACC_DEEP_COPY
+EncryptedData1 &EncryptedData1::operator = (const EncryptedData1 &that)
+#else // SNACC_DEEP_COPY
+EncryptedData1 &EncryptedData1::operator = (const EncryptedData1 &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.encryptedContentInfo)
+    {
+      if (!encryptedContentInfo)
+        encryptedContentInfo = new EncryptedContentInfo1;
+      *encryptedContentInfo = *that.encryptedContentInfo;
+    }
+    else
+    {
+      delete encryptedContentInfo;
+      encryptedContentInfo = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EncryptedData1 &EncryptedData1::operator = (const EncryptedData1 &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EncryptedData1::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = encryptedContentInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // EncryptedData1::BEncContent
+
+
+void EncryptedData1::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -104);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedContentInfo = new EncryptedContentInfo1;
+    encryptedContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -105);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -106);
+  }
+  else
+    return;
+} // EncryptedData1::BDecContent
+
+AsnLen EncryptedData1::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EncryptedData1::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EncryptedData1::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -107);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EncryptedData1::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EncryptedData1::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EncryptedData1::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encryptedContentInfo))
+  {
+    Indent (os, indentG);
+    os << "encryptedContentInfo ";
+    os << *encryptedContentInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encryptedContentInfo ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // EncryptedData1::Print
+
+
diff --git a/SecurityASN1/c++/pkcs8.cpp b/SecurityASN1/c++/pkcs8.cpp
new file mode 100644
index 00000000..627ec406
--- /dev/null
+++ b/SecurityASN1/c++/pkcs8.cpp
@@ -0,0 +1,541 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// pkcs8.cpp - class member functions for ASN.1 module PrivateKeyInformationSyntax
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+PrivateKeyInfo::PrivateKeyInfo()
+{
+#if TCL
+  privateKeyAlgorithm = new AlgorithmIdentifier;
+#else
+  privateKeyAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  attributes = NULL;
+}
+
+PrivateKeyInfo::PrivateKeyInfo (const PrivateKeyInfo &)
+{
+  Asn1Error << "use of incompletely defined PrivateKeyInfo::PrivateKeyInfo (const PrivateKeyInfo &)" << endl;
+  abort();
+}
+
+PrivateKeyInfo::~PrivateKeyInfo()
+{
+  delete privateKeyAlgorithm;
+  delete attributes;
+}
+
+AsnType *PrivateKeyInfo::Clone() const
+{
+  return new PrivateKeyInfo;
+}
+
+AsnType *PrivateKeyInfo::Copy() const
+{
+  return new PrivateKeyInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+PrivateKeyInfo &PrivateKeyInfo::operator = (const PrivateKeyInfo &that)
+#else // SNACC_DEEP_COPY
+PrivateKeyInfo &PrivateKeyInfo::operator = (const PrivateKeyInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.privateKeyAlgorithm)
+    {
+      if (!privateKeyAlgorithm)
+        privateKeyAlgorithm = new AlgorithmIdentifier;
+      *privateKeyAlgorithm = *that.privateKeyAlgorithm;
+    }
+    else
+    {
+      delete privateKeyAlgorithm;
+      privateKeyAlgorithm = NULL;
+    }
+    privateKey = that.privateKey;
+    if (that.attributes)
+    {
+      if (!attributes)
+        attributes = new Attributes;
+      *attributes = *that.attributes;
+    }
+    else
+    {
+      delete attributes;
+      attributes = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PrivateKeyInfo &PrivateKeyInfo::operator = (const PrivateKeyInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+PrivateKeyInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (attributes))
+  {
+      BEncEocIfNec (b);
+    l = attributes->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+    l = privateKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = privateKeyAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // PrivateKeyInfo::BEncContent
+
+
+void PrivateKeyInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -100);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    privateKeyAlgorithm = new AlgorithmIdentifier;
+    privateKeyAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -101);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    privateKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -102);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    attributes = new Attributes;
+    attributes->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -103);
+  }
+  else
+    return;
+} // PrivateKeyInfo::BDecContent
+
+AsnLen PrivateKeyInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void PrivateKeyInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "PrivateKeyInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -104);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PrivateKeyInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PrivateKeyInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void PrivateKeyInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (privateKeyAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "privateKeyAlgorithm ";
+    os << *privateKeyAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "privateKeyAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "privateKey ";
+    os << privateKey;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (attributes))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "attributes ";
+    os << *attributes;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "attributes ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // PrivateKeyInfo::Print
+
+
+EncryptedPrivateKeyInfo::EncryptedPrivateKeyInfo()
+{
+#if TCL
+  encryptionAlgorithm = new AlgorithmIdentifier;
+#else
+  encryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EncryptedPrivateKeyInfo::EncryptedPrivateKeyInfo (const EncryptedPrivateKeyInfo &)
+{
+  Asn1Error << "use of incompletely defined EncryptedPrivateKeyInfo::EncryptedPrivateKeyInfo (const EncryptedPrivateKeyInfo &)" << endl;
+  abort();
+}
+
+EncryptedPrivateKeyInfo::~EncryptedPrivateKeyInfo()
+{
+  delete encryptionAlgorithm;
+}
+
+AsnType *EncryptedPrivateKeyInfo::Clone() const
+{
+  return new EncryptedPrivateKeyInfo;
+}
+
+AsnType *EncryptedPrivateKeyInfo::Copy() const
+{
+  return new EncryptedPrivateKeyInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+EncryptedPrivateKeyInfo &EncryptedPrivateKeyInfo::operator = (const EncryptedPrivateKeyInfo &that)
+#else // SNACC_DEEP_COPY
+EncryptedPrivateKeyInfo &EncryptedPrivateKeyInfo::operator = (const EncryptedPrivateKeyInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.encryptionAlgorithm)
+    {
+      if (!encryptionAlgorithm)
+        encryptionAlgorithm = new AlgorithmIdentifier;
+      *encryptionAlgorithm = *that.encryptionAlgorithm;
+    }
+    else
+    {
+      delete encryptionAlgorithm;
+      encryptionAlgorithm = NULL;
+    }
+    encryptedKey = that.encryptedKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EncryptedPrivateKeyInfo &EncryptedPrivateKeyInfo::operator = (const EncryptedPrivateKeyInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EncryptedPrivateKeyInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = encryptedKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = encryptionAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // EncryptedPrivateKeyInfo::BEncContent
+
+
+void EncryptedPrivateKeyInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptionAlgorithm = new AlgorithmIdentifier;
+    encryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -105);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -106);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -107);
+  }
+  else
+    return;
+} // EncryptedPrivateKeyInfo::BDecContent
+
+AsnLen EncryptedPrivateKeyInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EncryptedPrivateKeyInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EncryptedPrivateKeyInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -108);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EncryptedPrivateKeyInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EncryptedPrivateKeyInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EncryptedPrivateKeyInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (encryptionAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "encryptionAlgorithm ";
+    os << *encryptionAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encryptionAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "encryptedKey ";
+    os << encryptedKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // EncryptedPrivateKeyInfo::Print
+
+
diff --git a/SecurityASN1/c++/pkcs9oids.cpp b/SecurityASN1/c++/pkcs9oids.cpp
new file mode 100644
index 00000000..ae085b29
--- /dev/null
+++ b/SecurityASN1/c++/pkcs9oids.cpp
@@ -0,0 +1,34 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// pkcs9oids.cpp - class member functions for ASN.1 module PKCS9-OIDS
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
diff --git a/SecurityASN1/c++/sm_cms.cpp b/SecurityASN1/c++/sm_cms.cpp
new file mode 100644
index 00000000..60b6c6f2
--- /dev/null
+++ b/SecurityASN1/c++/sm_cms.cpp
@@ -0,0 +1,10963 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_cms.cpp - class member functions for ASN.1 module CryptographicMessageSyntax
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+OriginatorPublicKey::OriginatorPublicKey()
+{
+#if TCL
+  algorithm = new AlgorithmIdentifier;
+#else
+  algorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+OriginatorPublicKey::OriginatorPublicKey (const OriginatorPublicKey &)
+{
+  Asn1Error << "use of incompletely defined OriginatorPublicKey::OriginatorPublicKey (const OriginatorPublicKey &)" << endl;
+  abort();
+}
+
+OriginatorPublicKey::~OriginatorPublicKey()
+{
+  delete algorithm;
+}
+
+AsnType *OriginatorPublicKey::Clone() const
+{
+  return new OriginatorPublicKey;
+}
+
+AsnType *OriginatorPublicKey::Copy() const
+{
+  return new OriginatorPublicKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+OriginatorPublicKey &OriginatorPublicKey::operator = (const OriginatorPublicKey &that)
+#else // SNACC_DEEP_COPY
+OriginatorPublicKey &OriginatorPublicKey::operator = (const OriginatorPublicKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.algorithm)
+    {
+      if (!algorithm)
+        algorithm = new AlgorithmIdentifier;
+      *algorithm = *that.algorithm;
+    }
+    else
+    {
+      delete algorithm;
+      algorithm = NULL;
+    }
+    publicKey = that.publicKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined OriginatorPublicKey &OriginatorPublicKey::operator = (const OriginatorPublicKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+OriginatorPublicKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = publicKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = algorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // OriginatorPublicKey::BEncContent
+
+
+void OriginatorPublicKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    algorithm = new AlgorithmIdentifier;
+    algorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -100);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    publicKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -101);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -102);
+  }
+  else
+    return;
+} // OriginatorPublicKey::BDecContent
+
+AsnLen OriginatorPublicKey::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void OriginatorPublicKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "OriginatorPublicKey::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -103);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int OriginatorPublicKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int OriginatorPublicKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void OriginatorPublicKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (algorithm))
+  {
+    Indent (os, indentG);
+    os << "algorithm ";
+    os << *algorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "algorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "publicKey ";
+    os << publicKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // OriginatorPublicKey::Print
+
+
+AsnType *CertificateRevocationLists::Clone() const
+{
+  return new CertificateRevocationLists;
+}
+
+AsnType *CertificateRevocationLists::Copy() const
+{
+  return new CertificateRevocationLists (*this);
+}
+
+AsnLen CertificateRevocationLists::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void CertificateRevocationLists::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "CertificateRevocationLists::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -104);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+CertificateRevocationLists::CertificateRevocationLists (const CertificateRevocationLists &)
+{
+  Asn1Error << "use of incompletely defined CertificateRevocationLists::CertificateRevocationLists (const CertificateRevocationLists &)" << endl;
+  abort();
+}
+
+CertificateRevocationLists::~CertificateRevocationLists()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+CertificateRevocationLists &CertificateRevocationLists::operator = (const CertificateRevocationLists &that)
+#else // SNACC_DEEP_COPY
+CertificateRevocationLists &CertificateRevocationLists::operator = (const CertificateRevocationLists &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificateRevocationLists &CertificateRevocationLists::operator = (const CertificateRevocationLists &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void CertificateRevocationLists::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  CertificateRevocationLists::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // CertificateRevocationLists::SetCurrElmt
+
+
+unsigned long int  CertificateRevocationLists::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // CertificateRevocationLists::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+CertificateList *CertificateRevocationLists::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new CertificateList;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificateRevocationLists::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+CertificateList  *CertificateRevocationLists::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateList;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificateRevocationLists::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertificateList  *CertificateRevocationLists::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateList;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificateRevocationLists::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertificateList *CertificateRevocationLists::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateList;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificateRevocationLists::InsertAfter
+
+
+CertificateRevocationLists  &CertificateRevocationLists::AppendCopy (CertificateList &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateList;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+CertificateRevocationLists  &CertificateRevocationLists::PrependCopy (CertificateList &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateList;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificateRevocationLists::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertificateRevocationLists &CertificateRevocationLists::InsertBeforeAndCopy (CertificateList &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateList;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificateRevocationLists::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertificateRevocationLists  &CertificateRevocationLists::InsertAfterAndCopy (CertificateList &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateList;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificateRevocationLists::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void CertificateRevocationLists::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen CertificateRevocationLists::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // CertificateRevocationLists::BEncContent
+
+
+void  CertificateRevocationLists::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    CertificateList *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -105);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // CertificateRevocationLists::BDecContent
+
+
+IssuerAndSerialNumber::IssuerAndSerialNumber()
+{
+#if TCL
+  issuer = new Name;
+#else
+  issuer = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+IssuerAndSerialNumber::IssuerAndSerialNumber (const IssuerAndSerialNumber &)
+{
+  Asn1Error << "use of incompletely defined IssuerAndSerialNumber::IssuerAndSerialNumber (const IssuerAndSerialNumber &)" << endl;
+  abort();
+}
+
+IssuerAndSerialNumber::~IssuerAndSerialNumber()
+{
+  delete issuer;
+}
+
+AsnType *IssuerAndSerialNumber::Clone() const
+{
+  return new IssuerAndSerialNumber;
+}
+
+AsnType *IssuerAndSerialNumber::Copy() const
+{
+  return new IssuerAndSerialNumber (*this);
+}
+
+#if SNACC_DEEP_COPY
+IssuerAndSerialNumber &IssuerAndSerialNumber::operator = (const IssuerAndSerialNumber &that)
+#else // SNACC_DEEP_COPY
+IssuerAndSerialNumber &IssuerAndSerialNumber::operator = (const IssuerAndSerialNumber &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.issuer)
+    {
+      if (!issuer)
+        issuer = new Name;
+      *issuer = *that.issuer;
+    }
+    else
+    {
+      delete issuer;
+      issuer = NULL;
+    }
+    serialNumber = that.serialNumber;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined IssuerAndSerialNumber &IssuerAndSerialNumber::operator = (const IssuerAndSerialNumber &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+IssuerAndSerialNumber::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = serialNumber.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+    l = issuer->BEncContent (b);
+    totalLen += l;
+
+  return totalLen;
+} // IssuerAndSerialNumber::BEncContent
+
+
+void IssuerAndSerialNumber::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuer = new Name;
+    issuer->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -106);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    serialNumber.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -107);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -108);
+  }
+  else
+    return;
+} // IssuerAndSerialNumber::BDecContent
+
+AsnLen IssuerAndSerialNumber::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void IssuerAndSerialNumber::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "IssuerAndSerialNumber::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -109);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int IssuerAndSerialNumber::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int IssuerAndSerialNumber::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void IssuerAndSerialNumber::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (issuer))
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << *issuer;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "serialNumber ";
+    os << serialNumber;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // IssuerAndSerialNumber::Print
+
+
+OtherKeyAttribute::OtherKeyAttribute()
+{
+  keyAttr = NULL;
+}
+
+OtherKeyAttribute::OtherKeyAttribute (const OtherKeyAttribute &)
+{
+  Asn1Error << "use of incompletely defined OtherKeyAttribute::OtherKeyAttribute (const OtherKeyAttribute &)" << endl;
+  abort();
+}
+
+OtherKeyAttribute::~OtherKeyAttribute()
+{
+  delete keyAttr;
+}
+
+AsnType *OtherKeyAttribute::Clone() const
+{
+  return new OtherKeyAttribute;
+}
+
+AsnType *OtherKeyAttribute::Copy() const
+{
+  return new OtherKeyAttribute (*this);
+}
+
+#if SNACC_DEEP_COPY
+OtherKeyAttribute &OtherKeyAttribute::operator = (const OtherKeyAttribute &that)
+#else // SNACC_DEEP_COPY
+OtherKeyAttribute &OtherKeyAttribute::operator = (const OtherKeyAttribute &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    keyAttrId = that.keyAttrId;
+    if (that.keyAttr)
+    {
+      if (!keyAttr)
+        keyAttr = new AsnAny;
+      *keyAttr = *that.keyAttr;
+    }
+    else
+    {
+      delete keyAttr;
+      keyAttr = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined OtherKeyAttribute &OtherKeyAttribute::operator = (const OtherKeyAttribute &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+OtherKeyAttribute::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (keyAttr))
+  {
+        ENC_LOAD_ANYBUF(keyAttr, b, l);
+    totalLen += l;
+  }
+
+    l = keyAttrId.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // OtherKeyAttribute::BEncContent
+
+
+void OtherKeyAttribute::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    keyAttrId.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = b.PeekByte();
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDecEoc (b, seqBytesDecoded, env);
+
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -110);
+  }
+
+  // ANY type
+    keyAttr = new AsnAny;
+        DEC_LOAD_ANYBUF(keyAttr, b, seqBytesDecoded, env);
+
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -111);
+  }
+  else
+    return;
+} // OtherKeyAttribute::BDecContent
+
+AsnLen OtherKeyAttribute::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void OtherKeyAttribute::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "OtherKeyAttribute::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -112);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int OtherKeyAttribute::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int OtherKeyAttribute::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void OtherKeyAttribute::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "keyAttrId ";
+    os << keyAttrId;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (keyAttr))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "keyAttr ";
+    os << *keyAttr;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "keyAttr ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // OtherKeyAttribute::Print
+
+
+AsnType *DigestAlgorithmIdentifiers::Clone() const
+{
+  return new DigestAlgorithmIdentifiers;
+}
+
+AsnType *DigestAlgorithmIdentifiers::Copy() const
+{
+  return new DigestAlgorithmIdentifiers (*this);
+}
+
+AsnLen DigestAlgorithmIdentifiers::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void DigestAlgorithmIdentifiers::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "DigestAlgorithmIdentifiers::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -113);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+DigestAlgorithmIdentifiers::DigestAlgorithmIdentifiers (const DigestAlgorithmIdentifiers &)
+{
+  Asn1Error << "use of incompletely defined DigestAlgorithmIdentifiers::DigestAlgorithmIdentifiers (const DigestAlgorithmIdentifiers &)" << endl;
+  abort();
+}
+
+DigestAlgorithmIdentifiers::~DigestAlgorithmIdentifiers()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+DigestAlgorithmIdentifiers &DigestAlgorithmIdentifiers::operator = (const DigestAlgorithmIdentifiers &that)
+#else // SNACC_DEEP_COPY
+DigestAlgorithmIdentifiers &DigestAlgorithmIdentifiers::operator = (const DigestAlgorithmIdentifiers &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DigestAlgorithmIdentifiers &DigestAlgorithmIdentifiers::operator = (const DigestAlgorithmIdentifiers &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void DigestAlgorithmIdentifiers::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  DigestAlgorithmIdentifiers::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // DigestAlgorithmIdentifiers::SetCurrElmt
+
+
+unsigned long int  DigestAlgorithmIdentifiers::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // DigestAlgorithmIdentifiers::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+DigestAlgorithmIdentifier *DigestAlgorithmIdentifiers::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new DigestAlgorithmIdentifier;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // DigestAlgorithmIdentifiers::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+DigestAlgorithmIdentifier  *DigestAlgorithmIdentifiers::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DigestAlgorithmIdentifier;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // DigestAlgorithmIdentifiers::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+DigestAlgorithmIdentifier  *DigestAlgorithmIdentifiers::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DigestAlgorithmIdentifier;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // DigestAlgorithmIdentifiers::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+DigestAlgorithmIdentifier *DigestAlgorithmIdentifiers::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DigestAlgorithmIdentifier;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // DigestAlgorithmIdentifiers::InsertAfter
+
+
+DigestAlgorithmIdentifiers  &DigestAlgorithmIdentifiers::AppendCopy (DigestAlgorithmIdentifier &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DigestAlgorithmIdentifier;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+DigestAlgorithmIdentifiers  &DigestAlgorithmIdentifiers::PrependCopy (DigestAlgorithmIdentifier &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DigestAlgorithmIdentifier;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // DigestAlgorithmIdentifiers::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+DigestAlgorithmIdentifiers &DigestAlgorithmIdentifiers::InsertBeforeAndCopy (DigestAlgorithmIdentifier &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DigestAlgorithmIdentifier;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // DigestAlgorithmIdentifiers::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+DigestAlgorithmIdentifiers  &DigestAlgorithmIdentifiers::InsertAfterAndCopy (DigestAlgorithmIdentifier &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DigestAlgorithmIdentifier;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // DigestAlgorithmIdentifiers::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void DigestAlgorithmIdentifiers::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen DigestAlgorithmIdentifiers::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // DigestAlgorithmIdentifiers::BEncContent
+
+
+void  DigestAlgorithmIdentifiers::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    DigestAlgorithmIdentifier *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -114);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // DigestAlgorithmIdentifiers::BDecContent
+
+
+EncapsulatedContentInfo::EncapsulatedContentInfo()
+{
+  eContent = NULL;
+}
+
+EncapsulatedContentInfo::EncapsulatedContentInfo (const EncapsulatedContentInfo &)
+{
+  Asn1Error << "use of incompletely defined EncapsulatedContentInfo::EncapsulatedContentInfo (const EncapsulatedContentInfo &)" << endl;
+  abort();
+}
+
+EncapsulatedContentInfo::~EncapsulatedContentInfo()
+{
+  delete eContent;
+}
+
+AsnType *EncapsulatedContentInfo::Clone() const
+{
+  return new EncapsulatedContentInfo;
+}
+
+AsnType *EncapsulatedContentInfo::Copy() const
+{
+  return new EncapsulatedContentInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+EncapsulatedContentInfo &EncapsulatedContentInfo::operator = (const EncapsulatedContentInfo &that)
+#else // SNACC_DEEP_COPY
+EncapsulatedContentInfo &EncapsulatedContentInfo::operator = (const EncapsulatedContentInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    eContentType = that.eContentType;
+    if (that.eContent)
+    {
+      if (!eContent)
+        eContent = new AsnOcts;
+      *eContent = *that.eContent;
+    }
+    else
+    {
+      delete eContent;
+      eContent = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EncapsulatedContentInfo &EncapsulatedContentInfo::operator = (const EncapsulatedContentInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EncapsulatedContentInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (eContent))
+  {
+      BEncEocIfNec (b);
+    l = eContent->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+    l = eContentType.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // EncapsulatedContentInfo::BEncContent
+
+
+void EncapsulatedContentInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    eContentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -115);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+       && (tag1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -116);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    eContent = new AsnOcts;
+    eContent->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -117);
+  }
+  else
+    return;
+} // EncapsulatedContentInfo::BDecContent
+
+AsnLen EncapsulatedContentInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EncapsulatedContentInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EncapsulatedContentInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -118);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EncapsulatedContentInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EncapsulatedContentInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EncapsulatedContentInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "eContentType ";
+    os << eContentType;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (eContent))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "eContent ";
+    os << *eContent;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "eContent ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // EncapsulatedContentInfo::Print
+
+
+SignerIdentifier::SignerIdentifier()
+{
+  choiceId = issuerAndSerialNumberCid;
+#if TCL
+  issuerAndSerialNumber = new IssuerAndSerialNumber;
+#else
+  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+SignerIdentifier::SignerIdentifier (const SignerIdentifier &)
+{
+  Asn1Error << "use of incompletely defined SignerIdentifier::SignerIdentifier (const SignerIdentifier &)" << endl;
+  abort();
+}
+
+SignerIdentifier::~SignerIdentifier()
+{
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      delete issuerAndSerialNumber;
+      break;
+    case subjectKeyIdentifierCid:
+      delete subjectKeyIdentifier;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *SignerIdentifier::Clone() const
+{
+  return new SignerIdentifier;
+}
+
+AsnType *SignerIdentifier::Copy() const
+{
+  return new SignerIdentifier (*this);
+}
+
+#if SNACC_DEEP_COPY
+SignerIdentifier &SignerIdentifier::operator = (const SignerIdentifier &that)
+#else // SNACC_DEEP_COPY
+SignerIdentifier &SignerIdentifier::operator = (const SignerIdentifier &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        delete issuerAndSerialNumber;
+        break;
+      case subjectKeyIdentifierCid:
+        delete subjectKeyIdentifier;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        issuerAndSerialNumber = new IssuerAndSerialNumber;
+        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
+        break;
+      case subjectKeyIdentifierCid:
+        subjectKeyIdentifier = new KeyIdentifier;
+        *subjectKeyIdentifier = *that.subjectKeyIdentifier;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SignerIdentifier &SignerIdentifier::operator = (const SignerIdentifier &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+SignerIdentifier::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      BEncEocIfNec (b);
+      l = issuerAndSerialNumber->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+    case subjectKeyIdentifierCid:
+      l = subjectKeyIdentifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+      break;
+
+  } // end switch
+  return l;
+} // SignerIdentifier::BEncContent
+
+
+void SignerIdentifier::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = issuerAndSerialNumberCid;
+      issuerAndSerialNumber = new IssuerAndSerialNumber;
+        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 0):
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      choiceId = subjectKeyIdentifierCid;
+      subjectKeyIdentifier = new KeyIdentifier;
+        subjectKeyIdentifier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -119);
+      break;
+  } // end switch
+} // SignerIdentifier::BDecContent
+
+
+AsnLen SignerIdentifier::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void SignerIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int SignerIdentifier::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int SignerIdentifier::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void SignerIdentifier::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      os << "issuerAndSerialNumber ";
+      if (issuerAndSerialNumber)
+        os << *issuerAndSerialNumber;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case subjectKeyIdentifierCid:
+      os << "subjectKeyIdentifier ";
+      if (subjectKeyIdentifier)
+        os << *subjectKeyIdentifier;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // SignerIdentifier::Print
+
+EncryptedContentInfo::EncryptedContentInfo()
+{
+#if TCL
+  contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier;
+#else
+  contentEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  encryptedContent = NULL;
+}
+
+EncryptedContentInfo::EncryptedContentInfo (const EncryptedContentInfo &)
+{
+  Asn1Error << "use of incompletely defined EncryptedContentInfo::EncryptedContentInfo (const EncryptedContentInfo &)" << endl;
+  abort();
+}
+
+EncryptedContentInfo::~EncryptedContentInfo()
+{
+  delete contentEncryptionAlgorithm;
+  delete encryptedContent;
+}
+
+AsnType *EncryptedContentInfo::Clone() const
+{
+  return new EncryptedContentInfo;
+}
+
+AsnType *EncryptedContentInfo::Copy() const
+{
+  return new EncryptedContentInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+EncryptedContentInfo &EncryptedContentInfo::operator = (const EncryptedContentInfo &that)
+#else // SNACC_DEEP_COPY
+EncryptedContentInfo &EncryptedContentInfo::operator = (const EncryptedContentInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    contentType = that.contentType;
+    if (that.contentEncryptionAlgorithm)
+    {
+      if (!contentEncryptionAlgorithm)
+        contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier;
+      *contentEncryptionAlgorithm = *that.contentEncryptionAlgorithm;
+    }
+    else
+    {
+      delete contentEncryptionAlgorithm;
+      contentEncryptionAlgorithm = NULL;
+    }
+    if (that.encryptedContent)
+    {
+      if (!encryptedContent)
+        encryptedContent = new EncryptedContent;
+      *encryptedContent = *that.encryptedContent;
+    }
+    else
+    {
+      delete encryptedContent;
+      encryptedContent = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EncryptedContentInfo &EncryptedContentInfo::operator = (const EncryptedContentInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EncryptedContentInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (encryptedContent))
+  {
+    l = encryptedContent->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = contentEncryptionAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = contentType.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // EncryptedContentInfo::BEncContent
+
+
+void EncryptedContentInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -120);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier;
+    contentEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -121);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedContent = new EncryptedContent;
+    encryptedContent->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -122);
+  }
+  else
+    return;
+} // EncryptedContentInfo::BDecContent
+
+AsnLen EncryptedContentInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EncryptedContentInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EncryptedContentInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -123);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EncryptedContentInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EncryptedContentInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EncryptedContentInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "contentType ";
+    os << contentType;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (contentEncryptionAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "contentEncryptionAlgorithm ";
+    os << *contentEncryptionAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "contentEncryptionAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encryptedContent))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "encryptedContent ";
+    os << *encryptedContent;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encryptedContent ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // EncryptedContentInfo::Print
+
+
+RecipientIdentifier::RecipientIdentifier()
+{
+  choiceId = issuerAndSerialNumberCid;
+#if TCL
+  issuerAndSerialNumber = new IssuerAndSerialNumber;
+#else
+  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+RecipientIdentifier::RecipientIdentifier (const RecipientIdentifier &)
+{
+  Asn1Error << "use of incompletely defined RecipientIdentifier::RecipientIdentifier (const RecipientIdentifier &)" << endl;
+  abort();
+}
+
+RecipientIdentifier::~RecipientIdentifier()
+{
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      delete issuerAndSerialNumber;
+      break;
+    case subjectKeyIdentifierCid:
+      delete subjectKeyIdentifier;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *RecipientIdentifier::Clone() const
+{
+  return new RecipientIdentifier;
+}
+
+AsnType *RecipientIdentifier::Copy() const
+{
+  return new RecipientIdentifier (*this);
+}
+
+#if SNACC_DEEP_COPY
+RecipientIdentifier &RecipientIdentifier::operator = (const RecipientIdentifier &that)
+#else // SNACC_DEEP_COPY
+RecipientIdentifier &RecipientIdentifier::operator = (const RecipientIdentifier &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        delete issuerAndSerialNumber;
+        break;
+      case subjectKeyIdentifierCid:
+        delete subjectKeyIdentifier;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        issuerAndSerialNumber = new IssuerAndSerialNumber;
+        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
+        break;
+      case subjectKeyIdentifierCid:
+        subjectKeyIdentifier = new KeyIdentifier;
+        *subjectKeyIdentifier = *that.subjectKeyIdentifier;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RecipientIdentifier &RecipientIdentifier::operator = (const RecipientIdentifier &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+RecipientIdentifier::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      BEncEocIfNec (b);
+      l = issuerAndSerialNumber->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+    case subjectKeyIdentifierCid:
+      l = subjectKeyIdentifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+      break;
+
+  } // end switch
+  return l;
+} // RecipientIdentifier::BEncContent
+
+
+void RecipientIdentifier::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = issuerAndSerialNumberCid;
+      issuerAndSerialNumber = new IssuerAndSerialNumber;
+        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 0):
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      choiceId = subjectKeyIdentifierCid;
+      subjectKeyIdentifier = new KeyIdentifier;
+        subjectKeyIdentifier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -124);
+      break;
+  } // end switch
+} // RecipientIdentifier::BDecContent
+
+
+AsnLen RecipientIdentifier::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void RecipientIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int RecipientIdentifier::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int RecipientIdentifier::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void RecipientIdentifier::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      os << "issuerAndSerialNumber ";
+      if (issuerAndSerialNumber)
+        os << *issuerAndSerialNumber;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case subjectKeyIdentifierCid:
+      os << "subjectKeyIdentifier ";
+      if (subjectKeyIdentifier)
+        os << *subjectKeyIdentifier;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // RecipientIdentifier::Print
+
+OriginatorIdentifierOrKey::OriginatorIdentifierOrKey()
+{
+  choiceId = issuerAndSerialNumberCid;
+#if TCL
+  issuerAndSerialNumber = new IssuerAndSerialNumber;
+#else
+  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+OriginatorIdentifierOrKey::OriginatorIdentifierOrKey (const OriginatorIdentifierOrKey &)
+{
+  Asn1Error << "use of incompletely defined OriginatorIdentifierOrKey::OriginatorIdentifierOrKey (const OriginatorIdentifierOrKey &)" << endl;
+  abort();
+}
+
+OriginatorIdentifierOrKey::~OriginatorIdentifierOrKey()
+{
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      delete issuerAndSerialNumber;
+      break;
+    case subjectKeyIdentifierCid:
+      delete subjectKeyIdentifier;
+      break;
+    case originatorKeyCid:
+      delete originatorKey;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *OriginatorIdentifierOrKey::Clone() const
+{
+  return new OriginatorIdentifierOrKey;
+}
+
+AsnType *OriginatorIdentifierOrKey::Copy() const
+{
+  return new OriginatorIdentifierOrKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+OriginatorIdentifierOrKey &OriginatorIdentifierOrKey::operator = (const OriginatorIdentifierOrKey &that)
+#else // SNACC_DEEP_COPY
+OriginatorIdentifierOrKey &OriginatorIdentifierOrKey::operator = (const OriginatorIdentifierOrKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        delete issuerAndSerialNumber;
+        break;
+      case subjectKeyIdentifierCid:
+        delete subjectKeyIdentifier;
+        break;
+      case originatorKeyCid:
+        delete originatorKey;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        issuerAndSerialNumber = new IssuerAndSerialNumber;
+        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
+        break;
+      case subjectKeyIdentifierCid:
+        subjectKeyIdentifier = new KeyIdentifier;
+        *subjectKeyIdentifier = *that.subjectKeyIdentifier;
+        break;
+      case originatorKeyCid:
+        originatorKey = new OriginatorPublicKey;
+        *originatorKey = *that.originatorKey;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined OriginatorIdentifierOrKey &OriginatorIdentifierOrKey::operator = (const OriginatorIdentifierOrKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+OriginatorIdentifierOrKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      BEncEocIfNec (b);
+      l = issuerAndSerialNumber->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+    case subjectKeyIdentifierCid:
+      l = subjectKeyIdentifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+      break;
+
+    case originatorKeyCid:
+      BEncEocIfNec (b);
+      l = originatorKey->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+      break;
+
+  } // end switch
+  return l;
+} // OriginatorIdentifierOrKey::BEncContent
+
+
+void OriginatorIdentifierOrKey::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = issuerAndSerialNumberCid;
+      issuerAndSerialNumber = new IssuerAndSerialNumber;
+        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 0):
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      choiceId = subjectKeyIdentifierCid;
+      subjectKeyIdentifier = new KeyIdentifier;
+        subjectKeyIdentifier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = originatorKeyCid;
+      originatorKey = new OriginatorPublicKey;
+        originatorKey->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -125);
+      break;
+  } // end switch
+} // OriginatorIdentifierOrKey::BDecContent
+
+
+AsnLen OriginatorIdentifierOrKey::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void OriginatorIdentifierOrKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int OriginatorIdentifierOrKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int OriginatorIdentifierOrKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void OriginatorIdentifierOrKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      os << "issuerAndSerialNumber ";
+      if (issuerAndSerialNumber)
+        os << *issuerAndSerialNumber;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case subjectKeyIdentifierCid:
+      os << "subjectKeyIdentifier ";
+      if (subjectKeyIdentifier)
+        os << *subjectKeyIdentifier;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case originatorKeyCid:
+      os << "originatorKey ";
+      if (originatorKey)
+        os << *originatorKey;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // OriginatorIdentifierOrKey::Print
+
+RecipientKeyIdentifier::RecipientKeyIdentifier()
+{
+  date = NULL;
+  other = NULL;
+}
+
+RecipientKeyIdentifier::RecipientKeyIdentifier (const RecipientKeyIdentifier &)
+{
+  Asn1Error << "use of incompletely defined RecipientKeyIdentifier::RecipientKeyIdentifier (const RecipientKeyIdentifier &)" << endl;
+  abort();
+}
+
+RecipientKeyIdentifier::~RecipientKeyIdentifier()
+{
+  delete date;
+  delete other;
+}
+
+AsnType *RecipientKeyIdentifier::Clone() const
+{
+  return new RecipientKeyIdentifier;
+}
+
+AsnType *RecipientKeyIdentifier::Copy() const
+{
+  return new RecipientKeyIdentifier (*this);
+}
+
+#if SNACC_DEEP_COPY
+RecipientKeyIdentifier &RecipientKeyIdentifier::operator = (const RecipientKeyIdentifier &that)
+#else // SNACC_DEEP_COPY
+RecipientKeyIdentifier &RecipientKeyIdentifier::operator = (const RecipientKeyIdentifier &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    subjectKeyIdentifier = that.subjectKeyIdentifier;
+    if (that.date)
+    {
+      if (!date)
+        date = new GeneralizedTime;
+      *date = *that.date;
+    }
+    else
+    {
+      delete date;
+      date = NULL;
+    }
+    if (that.other)
+    {
+      if (!other)
+        other = new OtherKeyAttribute;
+      *other = *that.other;
+    }
+    else
+    {
+      delete other;
+      other = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RecipientKeyIdentifier &RecipientKeyIdentifier::operator = (const RecipientKeyIdentifier &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+RecipientKeyIdentifier::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (other))
+  {
+      BEncEocIfNec (b);
+    l = other->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (date))
+  {
+    l = date->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = subjectKeyIdentifier.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // RecipientKeyIdentifier::BEncContent
+
+
+void RecipientKeyIdentifier::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    subjectKeyIdentifier.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -126);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    date = new GeneralizedTime;
+    date->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    other = new OtherKeyAttribute;
+    other->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -127);
+  }
+  else
+    return;
+} // RecipientKeyIdentifier::BDecContent
+
+AsnLen RecipientKeyIdentifier::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void RecipientKeyIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "RecipientKeyIdentifier::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -128);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int RecipientKeyIdentifier::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int RecipientKeyIdentifier::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void RecipientKeyIdentifier::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "subjectKeyIdentifier ";
+    os << subjectKeyIdentifier;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (date))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "date ";
+    os << *date;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "date ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (other))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "other ";
+    os << *other;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "other ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // RecipientKeyIdentifier::Print
+
+
+KEKIdentifier::KEKIdentifier()
+{
+  date = NULL;
+  other = NULL;
+}
+
+KEKIdentifier::KEKIdentifier (const KEKIdentifier &)
+{
+  Asn1Error << "use of incompletely defined KEKIdentifier::KEKIdentifier (const KEKIdentifier &)" << endl;
+  abort();
+}
+
+KEKIdentifier::~KEKIdentifier()
+{
+  delete date;
+  delete other;
+}
+
+AsnType *KEKIdentifier::Clone() const
+{
+  return new KEKIdentifier;
+}
+
+AsnType *KEKIdentifier::Copy() const
+{
+  return new KEKIdentifier (*this);
+}
+
+#if SNACC_DEEP_COPY
+KEKIdentifier &KEKIdentifier::operator = (const KEKIdentifier &that)
+#else // SNACC_DEEP_COPY
+KEKIdentifier &KEKIdentifier::operator = (const KEKIdentifier &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    keyIdentifier = that.keyIdentifier;
+    if (that.date)
+    {
+      if (!date)
+        date = new GeneralizedTime;
+      *date = *that.date;
+    }
+    else
+    {
+      delete date;
+      date = NULL;
+    }
+    if (that.other)
+    {
+      if (!other)
+        other = new OtherKeyAttribute;
+      *other = *that.other;
+    }
+    else
+    {
+      delete other;
+      other = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined KEKIdentifier &KEKIdentifier::operator = (const KEKIdentifier &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+KEKIdentifier::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (other))
+  {
+      BEncEocIfNec (b);
+    l = other->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (date))
+  {
+    l = date->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = keyIdentifier.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // KEKIdentifier::BEncContent
+
+
+void KEKIdentifier::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    keyIdentifier.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -129);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    date = new GeneralizedTime;
+    date->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    other = new OtherKeyAttribute;
+    other->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -130);
+  }
+  else
+    return;
+} // KEKIdentifier::BDecContent
+
+AsnLen KEKIdentifier::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void KEKIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "KEKIdentifier::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -131);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int KEKIdentifier::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int KEKIdentifier::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void KEKIdentifier::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "keyIdentifier ";
+    os << keyIdentifier;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (date))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "date ";
+    os << *date;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "date ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (other))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "other ";
+    os << *other;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "other ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // KEKIdentifier::Print
+
+
+ExtendedCertificateInfo::ExtendedCertificateInfo()
+{
+#if TCL
+  certificate = new Certificate;
+#else
+  certificate = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+ExtendedCertificateInfo::ExtendedCertificateInfo (const ExtendedCertificateInfo &)
+{
+  Asn1Error << "use of incompletely defined ExtendedCertificateInfo::ExtendedCertificateInfo (const ExtendedCertificateInfo &)" << endl;
+  abort();
+}
+
+ExtendedCertificateInfo::~ExtendedCertificateInfo()
+{
+  delete certificate;
+}
+
+AsnType *ExtendedCertificateInfo::Clone() const
+{
+  return new ExtendedCertificateInfo;
+}
+
+AsnType *ExtendedCertificateInfo::Copy() const
+{
+  return new ExtendedCertificateInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+ExtendedCertificateInfo &ExtendedCertificateInfo::operator = (const ExtendedCertificateInfo &that)
+#else // SNACC_DEEP_COPY
+ExtendedCertificateInfo &ExtendedCertificateInfo::operator = (const ExtendedCertificateInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.certificate)
+    {
+      if (!certificate)
+        certificate = new Certificate;
+      *certificate = *that.certificate;
+    }
+    else
+    {
+      delete certificate;
+      certificate = NULL;
+    }
+    attributes = that.attributes;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ExtendedCertificateInfo &ExtendedCertificateInfo::operator = (const ExtendedCertificateInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ExtendedCertificateInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = attributes.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = certificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // ExtendedCertificateInfo::BEncContent
+
+
+void ExtendedCertificateInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -132);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    certificate = new Certificate;
+    certificate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -133);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    attributes.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -134);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -135);
+  }
+  else
+    return;
+} // ExtendedCertificateInfo::BDecContent
+
+AsnLen ExtendedCertificateInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ExtendedCertificateInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ExtendedCertificateInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -136);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ExtendedCertificateInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ExtendedCertificateInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ExtendedCertificateInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (certificate))
+  {
+    Indent (os, indentG);
+    os << "certificate ";
+    os << *certificate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "certificate ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "attributes ";
+    os << attributes;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ExtendedCertificateInfo::Print
+
+
+SignerInfo::SignerInfo()
+{
+#if TCL
+  sid = new SignerIdentifier;
+#else
+  sid = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  digestAlgorithm = new DigestAlgorithmIdentifier;
+#else
+  digestAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  signedAttrs = NULL;
+#if TCL
+  signatureAlgorithm = new SignatureAlgorithmIdentifier;
+#else
+  signatureAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  unsignedAttrs = NULL;
+}
+
+SignerInfo::SignerInfo (const SignerInfo &)
+{
+  Asn1Error << "use of incompletely defined SignerInfo::SignerInfo (const SignerInfo &)" << endl;
+  abort();
+}
+
+SignerInfo::~SignerInfo()
+{
+  delete sid;
+  delete digestAlgorithm;
+  delete signedAttrs;
+  delete signatureAlgorithm;
+  delete unsignedAttrs;
+}
+
+AsnType *SignerInfo::Clone() const
+{
+  return new SignerInfo;
+}
+
+AsnType *SignerInfo::Copy() const
+{
+  return new SignerInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+SignerInfo &SignerInfo::operator = (const SignerInfo &that)
+#else // SNACC_DEEP_COPY
+SignerInfo &SignerInfo::operator = (const SignerInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.sid)
+    {
+      if (!sid)
+        sid = new SignerIdentifier;
+      *sid = *that.sid;
+    }
+    else
+    {
+      delete sid;
+      sid = NULL;
+    }
+    if (that.digestAlgorithm)
+    {
+      if (!digestAlgorithm)
+        digestAlgorithm = new DigestAlgorithmIdentifier;
+      *digestAlgorithm = *that.digestAlgorithm;
+    }
+    else
+    {
+      delete digestAlgorithm;
+      digestAlgorithm = NULL;
+    }
+    if (that.signedAttrs)
+    {
+      if (!signedAttrs)
+        signedAttrs = new Attributes;
+      *signedAttrs = *that.signedAttrs;
+    }
+    else
+    {
+      delete signedAttrs;
+      signedAttrs = NULL;
+    }
+    if (that.signatureAlgorithm)
+    {
+      if (!signatureAlgorithm)
+        signatureAlgorithm = new SignatureAlgorithmIdentifier;
+      *signatureAlgorithm = *that.signatureAlgorithm;
+    }
+    else
+    {
+      delete signatureAlgorithm;
+      signatureAlgorithm = NULL;
+    }
+    signature = that.signature;
+    if (that.unsignedAttrs)
+    {
+      if (!unsignedAttrs)
+        unsignedAttrs = new Attributes;
+      *unsignedAttrs = *that.unsignedAttrs;
+    }
+    else
+    {
+      delete unsignedAttrs;
+      unsignedAttrs = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SignerInfo &SignerInfo::operator = (const SignerInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+SignerInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (unsignedAttrs))
+  {
+      BEncEocIfNec (b);
+    l = unsignedAttrs->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+    l = signature.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = signatureAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (signedAttrs))
+  {
+      BEncEocIfNec (b);
+    l = signedAttrs->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = digestAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = sid->BEncContent (b);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // SignerInfo::BEncContent
+
+
+void SignerInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -137);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    sid = new SignerIdentifier;
+    sid->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -138);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    digestAlgorithm = new DigestAlgorithmIdentifier;
+    digestAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -139);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signedAttrs = new Attributes;
+    signedAttrs->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signatureAlgorithm = new SignatureAlgorithmIdentifier;
+    signatureAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -140);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signature.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -141);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    unsignedAttrs = new Attributes;
+    unsignedAttrs->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -142);
+  }
+  else
+    return;
+} // SignerInfo::BDecContent
+
+AsnLen SignerInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void SignerInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "SignerInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -143);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int SignerInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int SignerInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void SignerInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (sid))
+  {
+    Indent (os, indentG);
+    os << "sid ";
+    os << *sid;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "sid ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (digestAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithm ";
+    os << *digestAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (signedAttrs))
+  {
+    Indent (os, indentG);
+    os << "signedAttrs ";
+    os << *signedAttrs;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "signedAttrs ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (signatureAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "signatureAlgorithm ";
+    os << *signatureAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "signatureAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "signature ";
+    os << signature;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (unsignedAttrs))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "unsignedAttrs ";
+    os << *unsignedAttrs;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "unsignedAttrs ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // SignerInfo::Print
+
+
+KeyTransRecipientInfo::KeyTransRecipientInfo()
+{
+#if TCL
+  rid = new RecipientIdentifier;
+#else
+  rid = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+#else
+  keyEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+KeyTransRecipientInfo::KeyTransRecipientInfo (const KeyTransRecipientInfo &)
+{
+  Asn1Error << "use of incompletely defined KeyTransRecipientInfo::KeyTransRecipientInfo (const KeyTransRecipientInfo &)" << endl;
+  abort();
+}
+
+KeyTransRecipientInfo::~KeyTransRecipientInfo()
+{
+  delete rid;
+  delete keyEncryptionAlgorithm;
+}
+
+AsnType *KeyTransRecipientInfo::Clone() const
+{
+  return new KeyTransRecipientInfo;
+}
+
+AsnType *KeyTransRecipientInfo::Copy() const
+{
+  return new KeyTransRecipientInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+KeyTransRecipientInfo &KeyTransRecipientInfo::operator = (const KeyTransRecipientInfo &that)
+#else // SNACC_DEEP_COPY
+KeyTransRecipientInfo &KeyTransRecipientInfo::operator = (const KeyTransRecipientInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.rid)
+    {
+      if (!rid)
+        rid = new RecipientIdentifier;
+      *rid = *that.rid;
+    }
+    else
+    {
+      delete rid;
+      rid = NULL;
+    }
+    if (that.keyEncryptionAlgorithm)
+    {
+      if (!keyEncryptionAlgorithm)
+        keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+      *keyEncryptionAlgorithm = *that.keyEncryptionAlgorithm;
+    }
+    else
+    {
+      delete keyEncryptionAlgorithm;
+      keyEncryptionAlgorithm = NULL;
+    }
+    encryptedKey = that.encryptedKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined KeyTransRecipientInfo &KeyTransRecipientInfo::operator = (const KeyTransRecipientInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+KeyTransRecipientInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = encryptedKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = keyEncryptionAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = rid->BEncContent (b);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // KeyTransRecipientInfo::BEncContent
+
+
+void KeyTransRecipientInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -144);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    rid = new RecipientIdentifier;
+    rid->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -145);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+    keyEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -146);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -147);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -148);
+  }
+  else
+    return;
+} // KeyTransRecipientInfo::BDecContent
+
+AsnLen KeyTransRecipientInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void KeyTransRecipientInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "KeyTransRecipientInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -149);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int KeyTransRecipientInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int KeyTransRecipientInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void KeyTransRecipientInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (rid))
+  {
+    Indent (os, indentG);
+    os << "rid ";
+    os << *rid;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "rid ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (keyEncryptionAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "keyEncryptionAlgorithm ";
+    os << *keyEncryptionAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "keyEncryptionAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "encryptedKey ";
+    os << encryptedKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // KeyTransRecipientInfo::Print
+
+
+KeyAgreeRecipientIdentifier::KeyAgreeRecipientIdentifier()
+{
+  choiceId = issuerAndSerialNumberCid;
+#if TCL
+  issuerAndSerialNumber = new IssuerAndSerialNumber;
+#else
+  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+KeyAgreeRecipientIdentifier::KeyAgreeRecipientIdentifier (const KeyAgreeRecipientIdentifier &)
+{
+  Asn1Error << "use of incompletely defined KeyAgreeRecipientIdentifier::KeyAgreeRecipientIdentifier (const KeyAgreeRecipientIdentifier &)" << endl;
+  abort();
+}
+
+KeyAgreeRecipientIdentifier::~KeyAgreeRecipientIdentifier()
+{
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      delete issuerAndSerialNumber;
+      break;
+    case rKeyIdCid:
+      delete rKeyId;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *KeyAgreeRecipientIdentifier::Clone() const
+{
+  return new KeyAgreeRecipientIdentifier;
+}
+
+AsnType *KeyAgreeRecipientIdentifier::Copy() const
+{
+  return new KeyAgreeRecipientIdentifier (*this);
+}
+
+#if SNACC_DEEP_COPY
+KeyAgreeRecipientIdentifier &KeyAgreeRecipientIdentifier::operator = (const KeyAgreeRecipientIdentifier &that)
+#else // SNACC_DEEP_COPY
+KeyAgreeRecipientIdentifier &KeyAgreeRecipientIdentifier::operator = (const KeyAgreeRecipientIdentifier &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        delete issuerAndSerialNumber;
+        break;
+      case rKeyIdCid:
+        delete rKeyId;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        issuerAndSerialNumber = new IssuerAndSerialNumber;
+        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
+        break;
+      case rKeyIdCid:
+        rKeyId = new RecipientKeyIdentifier;
+        *rKeyId = *that.rKeyId;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined KeyAgreeRecipientIdentifier &KeyAgreeRecipientIdentifier::operator = (const KeyAgreeRecipientIdentifier &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+KeyAgreeRecipientIdentifier::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      BEncEocIfNec (b);
+      l = issuerAndSerialNumber->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+    case rKeyIdCid:
+      BEncEocIfNec (b);
+      l = rKeyId->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+      break;
+
+  } // end switch
+  return l;
+} // KeyAgreeRecipientIdentifier::BEncContent
+
+
+void KeyAgreeRecipientIdentifier::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = issuerAndSerialNumberCid;
+      issuerAndSerialNumber = new IssuerAndSerialNumber;
+        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      choiceId = rKeyIdCid;
+      rKeyId = new RecipientKeyIdentifier;
+        rKeyId->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -150);
+      break;
+  } // end switch
+} // KeyAgreeRecipientIdentifier::BDecContent
+
+
+AsnLen KeyAgreeRecipientIdentifier::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void KeyAgreeRecipientIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int KeyAgreeRecipientIdentifier::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int KeyAgreeRecipientIdentifier::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void KeyAgreeRecipientIdentifier::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      os << "issuerAndSerialNumber ";
+      if (issuerAndSerialNumber)
+        os << *issuerAndSerialNumber;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case rKeyIdCid:
+      os << "rKeyId ";
+      if (rKeyId)
+        os << *rKeyId;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // KeyAgreeRecipientIdentifier::Print
+
+KEKRecipientInfo::KEKRecipientInfo()
+{
+#if TCL
+  kekid = new KEKIdentifier;
+#else
+  kekid = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+#else
+  keyEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+KEKRecipientInfo::KEKRecipientInfo (const KEKRecipientInfo &)
+{
+  Asn1Error << "use of incompletely defined KEKRecipientInfo::KEKRecipientInfo (const KEKRecipientInfo &)" << endl;
+  abort();
+}
+
+KEKRecipientInfo::~KEKRecipientInfo()
+{
+  delete kekid;
+  delete keyEncryptionAlgorithm;
+}
+
+AsnType *KEKRecipientInfo::Clone() const
+{
+  return new KEKRecipientInfo;
+}
+
+AsnType *KEKRecipientInfo::Copy() const
+{
+  return new KEKRecipientInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+KEKRecipientInfo &KEKRecipientInfo::operator = (const KEKRecipientInfo &that)
+#else // SNACC_DEEP_COPY
+KEKRecipientInfo &KEKRecipientInfo::operator = (const KEKRecipientInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.kekid)
+    {
+      if (!kekid)
+        kekid = new KEKIdentifier;
+      *kekid = *that.kekid;
+    }
+    else
+    {
+      delete kekid;
+      kekid = NULL;
+    }
+    if (that.keyEncryptionAlgorithm)
+    {
+      if (!keyEncryptionAlgorithm)
+        keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+      *keyEncryptionAlgorithm = *that.keyEncryptionAlgorithm;
+    }
+    else
+    {
+      delete keyEncryptionAlgorithm;
+      keyEncryptionAlgorithm = NULL;
+    }
+    encryptedKey = that.encryptedKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined KEKRecipientInfo &KEKRecipientInfo::operator = (const KEKRecipientInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+KEKRecipientInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = encryptedKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = keyEncryptionAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = kekid->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // KEKRecipientInfo::BEncContent
+
+
+void KEKRecipientInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -151);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    kekid = new KEKIdentifier;
+    kekid->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -152);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+    keyEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -153);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -154);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -155);
+  }
+  else
+    return;
+} // KEKRecipientInfo::BDecContent
+
+AsnLen KEKRecipientInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void KEKRecipientInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "KEKRecipientInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -156);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int KEKRecipientInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int KEKRecipientInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void KEKRecipientInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (kekid))
+  {
+    Indent (os, indentG);
+    os << "kekid ";
+    os << *kekid;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "kekid ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (keyEncryptionAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "keyEncryptionAlgorithm ";
+    os << *keyEncryptionAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "keyEncryptionAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "encryptedKey ";
+    os << encryptedKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // KEKRecipientInfo::Print
+
+
+ExtendedCertificate::ExtendedCertificate()
+{
+#if TCL
+  extendedCertificateInfo = new ExtendedCertificateInfo;
+#else
+  extendedCertificateInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  signatureAlgorithm = new SignatureAlgorithmIdentifier;
+#else
+  signatureAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+ExtendedCertificate::ExtendedCertificate (const ExtendedCertificate &)
+{
+  Asn1Error << "use of incompletely defined ExtendedCertificate::ExtendedCertificate (const ExtendedCertificate &)" << endl;
+  abort();
+}
+
+ExtendedCertificate::~ExtendedCertificate()
+{
+  delete extendedCertificateInfo;
+  delete signatureAlgorithm;
+}
+
+AsnType *ExtendedCertificate::Clone() const
+{
+  return new ExtendedCertificate;
+}
+
+AsnType *ExtendedCertificate::Copy() const
+{
+  return new ExtendedCertificate (*this);
+}
+
+#if SNACC_DEEP_COPY
+ExtendedCertificate &ExtendedCertificate::operator = (const ExtendedCertificate &that)
+#else // SNACC_DEEP_COPY
+ExtendedCertificate &ExtendedCertificate::operator = (const ExtendedCertificate &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.extendedCertificateInfo)
+    {
+      if (!extendedCertificateInfo)
+        extendedCertificateInfo = new ExtendedCertificateInfo;
+      *extendedCertificateInfo = *that.extendedCertificateInfo;
+    }
+    else
+    {
+      delete extendedCertificateInfo;
+      extendedCertificateInfo = NULL;
+    }
+    if (that.signatureAlgorithm)
+    {
+      if (!signatureAlgorithm)
+        signatureAlgorithm = new SignatureAlgorithmIdentifier;
+      *signatureAlgorithm = *that.signatureAlgorithm;
+    }
+    else
+    {
+      delete signatureAlgorithm;
+      signatureAlgorithm = NULL;
+    }
+    signature = that.signature;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ExtendedCertificate &ExtendedCertificate::operator = (const ExtendedCertificate &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ExtendedCertificate::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = signature.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = signatureAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = extendedCertificateInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // ExtendedCertificate::BEncContent
+
+
+void ExtendedCertificate::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    extendedCertificateInfo = new ExtendedCertificateInfo;
+    extendedCertificateInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -157);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signatureAlgorithm = new SignatureAlgorithmIdentifier;
+    signatureAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -158);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signature.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -159);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -160);
+  }
+  else
+    return;
+} // ExtendedCertificate::BDecContent
+
+AsnLen ExtendedCertificate::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ExtendedCertificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ExtendedCertificate::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -161);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ExtendedCertificate::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ExtendedCertificate::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ExtendedCertificate::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (extendedCertificateInfo))
+  {
+    Indent (os, indentG);
+    os << "extendedCertificateInfo ";
+    os << *extendedCertificateInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "extendedCertificateInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (signatureAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "signatureAlgorithm ";
+    os << *signatureAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "signatureAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "signature ";
+    os << signature;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ExtendedCertificate::Print
+
+
+AsnType *SignerInfos::Clone() const
+{
+  return new SignerInfos;
+}
+
+AsnType *SignerInfos::Copy() const
+{
+  return new SignerInfos (*this);
+}
+
+AsnLen SignerInfos::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void SignerInfos::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "SignerInfos::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -162);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+SignerInfos::SignerInfos (const SignerInfos &)
+{
+  Asn1Error << "use of incompletely defined SignerInfos::SignerInfos (const SignerInfos &)" << endl;
+  abort();
+}
+
+SignerInfos::~SignerInfos()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+SignerInfos &SignerInfos::operator = (const SignerInfos &that)
+#else // SNACC_DEEP_COPY
+SignerInfos &SignerInfos::operator = (const SignerInfos &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SignerInfos &SignerInfos::operator = (const SignerInfos &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void SignerInfos::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  SignerInfos::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // SignerInfos::SetCurrElmt
+
+
+unsigned long int  SignerInfos::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // SignerInfos::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+SignerInfo *SignerInfos::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new SignerInfo;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SignerInfos::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+SignerInfo  *SignerInfos::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SignerInfo;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SignerInfos::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+SignerInfo  *SignerInfos::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SignerInfo;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SignerInfos::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+SignerInfo *SignerInfos::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SignerInfo;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SignerInfos::InsertAfter
+
+
+SignerInfos  &SignerInfos::AppendCopy (SignerInfo &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SignerInfo;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+SignerInfos  &SignerInfos::PrependCopy (SignerInfo &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SignerInfo;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // SignerInfos::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+SignerInfos &SignerInfos::InsertBeforeAndCopy (SignerInfo &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SignerInfo;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // SignerInfos::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+SignerInfos  &SignerInfos::InsertAfterAndCopy (SignerInfo &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SignerInfo;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // SignerInfos::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void SignerInfos::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen SignerInfos::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // SignerInfos::BEncContent
+
+
+void  SignerInfos::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    SignerInfo *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -163);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // SignerInfos::BDecContent
+
+
+RecipientEncryptedKey::RecipientEncryptedKey()
+{
+#if TCL
+  rid = new KeyAgreeRecipientIdentifier;
+#else
+  rid = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+RecipientEncryptedKey::RecipientEncryptedKey (const RecipientEncryptedKey &)
+{
+  Asn1Error << "use of incompletely defined RecipientEncryptedKey::RecipientEncryptedKey (const RecipientEncryptedKey &)" << endl;
+  abort();
+}
+
+RecipientEncryptedKey::~RecipientEncryptedKey()
+{
+  delete rid;
+}
+
+AsnType *RecipientEncryptedKey::Clone() const
+{
+  return new RecipientEncryptedKey;
+}
+
+AsnType *RecipientEncryptedKey::Copy() const
+{
+  return new RecipientEncryptedKey (*this);
+}
+
+#if SNACC_DEEP_COPY
+RecipientEncryptedKey &RecipientEncryptedKey::operator = (const RecipientEncryptedKey &that)
+#else // SNACC_DEEP_COPY
+RecipientEncryptedKey &RecipientEncryptedKey::operator = (const RecipientEncryptedKey &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.rid)
+    {
+      if (!rid)
+        rid = new KeyAgreeRecipientIdentifier;
+      *rid = *that.rid;
+    }
+    else
+    {
+      delete rid;
+      rid = NULL;
+    }
+    encryptedKey = that.encryptedKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RecipientEncryptedKey &RecipientEncryptedKey::operator = (const RecipientEncryptedKey &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+RecipientEncryptedKey::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = encryptedKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+    l = rid->BEncContent (b);
+    totalLen += l;
+
+  return totalLen;
+} // RecipientEncryptedKey::BEncContent
+
+
+void RecipientEncryptedKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    rid = new KeyAgreeRecipientIdentifier;
+    rid->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -164);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -165);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -166);
+  }
+  else
+    return;
+} // RecipientEncryptedKey::BDecContent
+
+AsnLen RecipientEncryptedKey::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void RecipientEncryptedKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "RecipientEncryptedKey::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -167);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int RecipientEncryptedKey::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int RecipientEncryptedKey::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void RecipientEncryptedKey::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (rid))
+  {
+    Indent (os, indentG);
+    os << "rid ";
+    os << *rid;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "rid ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "encryptedKey ";
+    os << encryptedKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // RecipientEncryptedKey::Print
+
+
+CertificateChoices::CertificateChoices()
+{
+  choiceId = certificateCid;
+#if TCL
+  certificate = new Certificate;
+#else
+  certificate = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+CertificateChoices::CertificateChoices (const CertificateChoices &)
+{
+  Asn1Error << "use of incompletely defined CertificateChoices::CertificateChoices (const CertificateChoices &)" << endl;
+  abort();
+}
+
+CertificateChoices::~CertificateChoices()
+{
+  switch (choiceId)
+  {
+    case certificateCid:
+      delete certificate;
+      break;
+    case extendedCertificateCid:
+      delete extendedCertificate;
+      break;
+    case attrCertCid:
+      delete attrCert;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *CertificateChoices::Clone() const
+{
+  return new CertificateChoices;
+}
+
+AsnType *CertificateChoices::Copy() const
+{
+  return new CertificateChoices (*this);
+}
+
+#if SNACC_DEEP_COPY
+CertificateChoices &CertificateChoices::operator = (const CertificateChoices &that)
+#else // SNACC_DEEP_COPY
+CertificateChoices &CertificateChoices::operator = (const CertificateChoices &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case certificateCid:
+        delete certificate;
+        break;
+      case extendedCertificateCid:
+        delete extendedCertificate;
+        break;
+      case attrCertCid:
+        delete attrCert;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case certificateCid:
+        certificate = new Certificate;
+        *certificate = *that.certificate;
+        break;
+      case extendedCertificateCid:
+        extendedCertificate = new ExtendedCertificate;
+        *extendedCertificate = *that.extendedCertificate;
+        break;
+      case attrCertCid:
+        attrCert = new AttributeCertificate;
+        *attrCert = *that.attrCert;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificateChoices &CertificateChoices::operator = (const CertificateChoices &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+CertificateChoices::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case certificateCid:
+      BEncEocIfNec (b);
+      l = certificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+    case extendedCertificateCid:
+      BEncEocIfNec (b);
+      l = extendedCertificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+      break;
+
+    case attrCertCid:
+      BEncEocIfNec (b);
+      l = attrCert->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+      break;
+
+  } // end switch
+  return l;
+} // CertificateChoices::BEncContent
+
+
+void CertificateChoices::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = certificateCid;
+      certificate = new Certificate;
+        certificate->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      choiceId = extendedCertificateCid;
+      extendedCertificate = new ExtendedCertificate;
+        extendedCertificate->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = attrCertCid;
+      attrCert = new AttributeCertificate;
+        attrCert->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -168);
+      break;
+  } // end switch
+} // CertificateChoices::BDecContent
+
+
+AsnLen CertificateChoices::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void CertificateChoices::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int CertificateChoices::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int CertificateChoices::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void CertificateChoices::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case certificateCid:
+      os << "certificate ";
+      if (certificate)
+        os << *certificate;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case extendedCertificateCid:
+      os << "extendedCertificate ";
+      if (extendedCertificate)
+        os << *extendedCertificate;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case attrCertCid:
+      os << "attrCert ";
+      if (attrCert)
+        os << *attrCert;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // CertificateChoices::Print
+
+AsnType *CertificateSet::Clone() const
+{
+  return new CertificateSet;
+}
+
+AsnType *CertificateSet::Copy() const
+{
+  return new CertificateSet (*this);
+}
+
+AsnLen CertificateSet::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void CertificateSet::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "CertificateSet::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -169);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+CertificateSet::CertificateSet (const CertificateSet &)
+{
+  Asn1Error << "use of incompletely defined CertificateSet::CertificateSet (const CertificateSet &)" << endl;
+  abort();
+}
+
+CertificateSet::~CertificateSet()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+CertificateSet &CertificateSet::operator = (const CertificateSet &that)
+#else // SNACC_DEEP_COPY
+CertificateSet &CertificateSet::operator = (const CertificateSet &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificateSet &CertificateSet::operator = (const CertificateSet &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void CertificateSet::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  CertificateSet::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // CertificateSet::SetCurrElmt
+
+
+unsigned long int  CertificateSet::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // CertificateSet::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+CertificateChoices *CertificateSet::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new CertificateChoices;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificateSet::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+CertificateChoices  *CertificateSet::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateChoices;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificateSet::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertificateChoices  *CertificateSet::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateChoices;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificateSet::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertificateChoices *CertificateSet::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateChoices;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificateSet::InsertAfter
+
+
+CertificateSet  &CertificateSet::AppendCopy (CertificateChoices &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateChoices;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+CertificateSet  &CertificateSet::PrependCopy (CertificateChoices &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateChoices;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificateSet::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertificateSet &CertificateSet::InsertBeforeAndCopy (CertificateChoices &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateChoices;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificateSet::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertificateSet  &CertificateSet::InsertAfterAndCopy (CertificateChoices &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificateChoices;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificateSet::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void CertificateSet::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen CertificateSet::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // CertificateSet::BEncContent
+
+
+void  CertificateSet::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    CertificateChoices *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if (!((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0))
+         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -170);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // CertificateSet::BDecContent
+
+
+OriginatorInfo::OriginatorInfo()
+{
+  certs = NULL;
+  crls = NULL;
+}
+
+OriginatorInfo::OriginatorInfo (const OriginatorInfo &)
+{
+  Asn1Error << "use of incompletely defined OriginatorInfo::OriginatorInfo (const OriginatorInfo &)" << endl;
+  abort();
+}
+
+OriginatorInfo::~OriginatorInfo()
+{
+  delete certs;
+  delete crls;
+}
+
+AsnType *OriginatorInfo::Clone() const
+{
+  return new OriginatorInfo;
+}
+
+AsnType *OriginatorInfo::Copy() const
+{
+  return new OriginatorInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+OriginatorInfo &OriginatorInfo::operator = (const OriginatorInfo &that)
+#else // SNACC_DEEP_COPY
+OriginatorInfo &OriginatorInfo::operator = (const OriginatorInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.certs)
+    {
+      if (!certs)
+        certs = new CertificateSet;
+      *certs = *that.certs;
+    }
+    else
+    {
+      delete certs;
+      certs = NULL;
+    }
+    if (that.crls)
+    {
+      if (!crls)
+        crls = new CertificateRevocationLists;
+      *crls = *that.crls;
+    }
+    else
+    {
+      delete crls;
+      crls = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined OriginatorInfo &OriginatorInfo::operator = (const OriginatorInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+OriginatorInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (crls))
+  {
+      BEncEocIfNec (b);
+    l = crls->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (certs))
+  {
+      BEncEocIfNec (b);
+    l = certs->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // OriginatorInfo::BEncContent
+
+
+void OriginatorInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    certs = new CertificateSet;
+    certs->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    crls = new CertificateRevocationLists;
+    crls->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -171);
+  }
+  else
+    return;
+} // OriginatorInfo::BDecContent
+
+AsnLen OriginatorInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void OriginatorInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "OriginatorInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -172);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int OriginatorInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int OriginatorInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void OriginatorInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (certs))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "certs ";
+    os << *certs;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "certs ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (crls))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "crls ";
+    os << *crls;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "crls ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // OriginatorInfo::Print
+
+
+AsnType *RecipientEncryptedKeys::Clone() const
+{
+  return new RecipientEncryptedKeys;
+}
+
+AsnType *RecipientEncryptedKeys::Copy() const
+{
+  return new RecipientEncryptedKeys (*this);
+}
+
+AsnLen RecipientEncryptedKeys::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void RecipientEncryptedKeys::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "RecipientEncryptedKeys::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -173);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+RecipientEncryptedKeys::RecipientEncryptedKeys (const RecipientEncryptedKeys &)
+{
+  Asn1Error << "use of incompletely defined RecipientEncryptedKeys::RecipientEncryptedKeys (const RecipientEncryptedKeys &)" << endl;
+  abort();
+}
+
+RecipientEncryptedKeys::~RecipientEncryptedKeys()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+RecipientEncryptedKeys &RecipientEncryptedKeys::operator = (const RecipientEncryptedKeys &that)
+#else // SNACC_DEEP_COPY
+RecipientEncryptedKeys &RecipientEncryptedKeys::operator = (const RecipientEncryptedKeys &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RecipientEncryptedKeys &RecipientEncryptedKeys::operator = (const RecipientEncryptedKeys &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void RecipientEncryptedKeys::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  RecipientEncryptedKeys::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // RecipientEncryptedKeys::SetCurrElmt
+
+
+unsigned long int  RecipientEncryptedKeys::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // RecipientEncryptedKeys::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+RecipientEncryptedKey *RecipientEncryptedKeys::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new RecipientEncryptedKey;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RecipientEncryptedKeys::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+RecipientEncryptedKey  *RecipientEncryptedKeys::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientEncryptedKey;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RecipientEncryptedKeys::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+RecipientEncryptedKey  *RecipientEncryptedKeys::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientEncryptedKey;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RecipientEncryptedKeys::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+RecipientEncryptedKey *RecipientEncryptedKeys::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientEncryptedKey;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RecipientEncryptedKeys::InsertAfter
+
+
+RecipientEncryptedKeys  &RecipientEncryptedKeys::AppendCopy (RecipientEncryptedKey &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientEncryptedKey;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+RecipientEncryptedKeys  &RecipientEncryptedKeys::PrependCopy (RecipientEncryptedKey &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientEncryptedKey;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // RecipientEncryptedKeys::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+RecipientEncryptedKeys &RecipientEncryptedKeys::InsertBeforeAndCopy (RecipientEncryptedKey &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientEncryptedKey;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // RecipientEncryptedKeys::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+RecipientEncryptedKeys  &RecipientEncryptedKeys::InsertAfterAndCopy (RecipientEncryptedKey &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientEncryptedKey;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // RecipientEncryptedKeys::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void RecipientEncryptedKeys::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen RecipientEncryptedKeys::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // RecipientEncryptedKeys::BEncContent
+
+
+void  RecipientEncryptedKeys::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    RecipientEncryptedKey *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -174);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // RecipientEncryptedKeys::BDecContent
+
+
+KeyAgreeRecipientInfo::KeyAgreeRecipientInfo()
+{
+#if TCL
+  originator = new OriginatorIdentifierOrKey;
+#else
+  originator = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  ukm = NULL;
+#if TCL
+  keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+#else
+  keyEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+KeyAgreeRecipientInfo::KeyAgreeRecipientInfo (const KeyAgreeRecipientInfo &)
+{
+  Asn1Error << "use of incompletely defined KeyAgreeRecipientInfo::KeyAgreeRecipientInfo (const KeyAgreeRecipientInfo &)" << endl;
+  abort();
+}
+
+KeyAgreeRecipientInfo::~KeyAgreeRecipientInfo()
+{
+  delete originator;
+  delete ukm;
+  delete keyEncryptionAlgorithm;
+}
+
+AsnType *KeyAgreeRecipientInfo::Clone() const
+{
+  return new KeyAgreeRecipientInfo;
+}
+
+AsnType *KeyAgreeRecipientInfo::Copy() const
+{
+  return new KeyAgreeRecipientInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+KeyAgreeRecipientInfo &KeyAgreeRecipientInfo::operator = (const KeyAgreeRecipientInfo &that)
+#else // SNACC_DEEP_COPY
+KeyAgreeRecipientInfo &KeyAgreeRecipientInfo::operator = (const KeyAgreeRecipientInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.originator)
+    {
+      if (!originator)
+        originator = new OriginatorIdentifierOrKey;
+      *originator = *that.originator;
+    }
+    else
+    {
+      delete originator;
+      originator = NULL;
+    }
+    if (that.ukm)
+    {
+      if (!ukm)
+        ukm = new UserKeyingMaterial;
+      *ukm = *that.ukm;
+    }
+    else
+    {
+      delete ukm;
+      ukm = NULL;
+    }
+    if (that.keyEncryptionAlgorithm)
+    {
+      if (!keyEncryptionAlgorithm)
+        keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+      *keyEncryptionAlgorithm = *that.keyEncryptionAlgorithm;
+    }
+    else
+    {
+      delete keyEncryptionAlgorithm;
+      keyEncryptionAlgorithm = NULL;
+    }
+    recipientEncryptedKeys = that.recipientEncryptedKeys;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined KeyAgreeRecipientInfo &KeyAgreeRecipientInfo::operator = (const KeyAgreeRecipientInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+KeyAgreeRecipientInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = recipientEncryptedKeys.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = keyEncryptionAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (ukm))
+  {
+      BEncEocIfNec (b);
+    l = ukm->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = originator->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // KeyAgreeRecipientInfo::BEncContent
+
+
+void KeyAgreeRecipientInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -175);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    originator = new OriginatorIdentifierOrKey;
+    originator->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -176);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+       && (tag1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -177);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    ukm = new UserKeyingMaterial;
+    ukm->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
+    keyEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -178);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    recipientEncryptedKeys.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -179);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -180);
+  }
+  else
+    return;
+} // KeyAgreeRecipientInfo::BDecContent
+
+AsnLen KeyAgreeRecipientInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void KeyAgreeRecipientInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "KeyAgreeRecipientInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -181);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int KeyAgreeRecipientInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int KeyAgreeRecipientInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void KeyAgreeRecipientInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (originator))
+  {
+    Indent (os, indentG);
+    os << "originator ";
+    os << *originator;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "originator ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (ukm))
+  {
+    Indent (os, indentG);
+    os << "ukm ";
+    os << *ukm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "ukm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (keyEncryptionAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "keyEncryptionAlgorithm ";
+    os << *keyEncryptionAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "keyEncryptionAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "recipientEncryptedKeys ";
+    os << recipientEncryptedKeys;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // KeyAgreeRecipientInfo::Print
+
+
+RecipientInfo::RecipientInfo()
+{
+  choiceId = ktriCid;
+#if TCL
+  ktri = new KeyTransRecipientInfo;
+#else
+  ktri = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+RecipientInfo::RecipientInfo (const RecipientInfo &)
+{
+  Asn1Error << "use of incompletely defined RecipientInfo::RecipientInfo (const RecipientInfo &)" << endl;
+  abort();
+}
+
+RecipientInfo::~RecipientInfo()
+{
+  switch (choiceId)
+  {
+    case ktriCid:
+      delete ktri;
+      break;
+    case kariCid:
+      delete kari;
+      break;
+    case kekriCid:
+      delete kekri;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *RecipientInfo::Clone() const
+{
+  return new RecipientInfo;
+}
+
+AsnType *RecipientInfo::Copy() const
+{
+  return new RecipientInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+RecipientInfo &RecipientInfo::operator = (const RecipientInfo &that)
+#else // SNACC_DEEP_COPY
+RecipientInfo &RecipientInfo::operator = (const RecipientInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case ktriCid:
+        delete ktri;
+        break;
+      case kariCid:
+        delete kari;
+        break;
+      case kekriCid:
+        delete kekri;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case ktriCid:
+        ktri = new KeyTransRecipientInfo;
+        *ktri = *that.ktri;
+        break;
+      case kariCid:
+        kari = new KeyAgreeRecipientInfo;
+        *kari = *that.kari;
+        break;
+      case kekriCid:
+        kekri = new KEKRecipientInfo;
+        *kekri = *that.kekri;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RecipientInfo &RecipientInfo::operator = (const RecipientInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+RecipientInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case ktriCid:
+      BEncEocIfNec (b);
+      l = ktri->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+    case kariCid:
+      BEncEocIfNec (b);
+      l = kari->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+      break;
+
+    case kekriCid:
+      BEncEocIfNec (b);
+      l = kekri->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 2);
+      break;
+
+  } // end switch
+  return l;
+} // RecipientInfo::BEncContent
+
+
+void RecipientInfo::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = ktriCid;
+      ktri = new KeyTransRecipientInfo;
+        ktri->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = kariCid;
+      kari = new KeyAgreeRecipientInfo;
+        kari->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 2):
+      choiceId = kekriCid;
+      kekri = new KEKRecipientInfo;
+        kekri->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -182);
+      break;
+  } // end switch
+} // RecipientInfo::BDecContent
+
+
+AsnLen RecipientInfo::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void RecipientInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int RecipientInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int RecipientInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void RecipientInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case ktriCid:
+      os << "ktri ";
+      if (ktri)
+        os << *ktri;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case kariCid:
+      os << "kari ";
+      if (kari)
+        os << *kari;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case kekriCid:
+      os << "kekri ";
+      if (kekri)
+        os << *kekri;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // RecipientInfo::Print
+
+AsnType *RecipientInfos::Clone() const
+{
+  return new RecipientInfos;
+}
+
+AsnType *RecipientInfos::Copy() const
+{
+  return new RecipientInfos (*this);
+}
+
+AsnLen RecipientInfos::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void RecipientInfos::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "RecipientInfos::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -183);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+RecipientInfos::RecipientInfos (const RecipientInfos &)
+{
+  Asn1Error << "use of incompletely defined RecipientInfos::RecipientInfos (const RecipientInfos &)" << endl;
+  abort();
+}
+
+RecipientInfos::~RecipientInfos()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+RecipientInfos &RecipientInfos::operator = (const RecipientInfos &that)
+#else // SNACC_DEEP_COPY
+RecipientInfos &RecipientInfos::operator = (const RecipientInfos &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RecipientInfos &RecipientInfos::operator = (const RecipientInfos &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void RecipientInfos::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  RecipientInfos::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // RecipientInfos::SetCurrElmt
+
+
+unsigned long int  RecipientInfos::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // RecipientInfos::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+RecipientInfo *RecipientInfos::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new RecipientInfo;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RecipientInfos::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+RecipientInfo  *RecipientInfos::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientInfo;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RecipientInfos::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+RecipientInfo  *RecipientInfos::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientInfo;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RecipientInfos::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+RecipientInfo *RecipientInfos::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientInfo;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RecipientInfos::InsertAfter
+
+
+RecipientInfos  &RecipientInfos::AppendCopy (RecipientInfo &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientInfo;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+RecipientInfos  &RecipientInfos::PrependCopy (RecipientInfo &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientInfo;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // RecipientInfos::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+RecipientInfos &RecipientInfos::InsertBeforeAndCopy (RecipientInfo &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientInfo;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // RecipientInfos::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+RecipientInfos  &RecipientInfos::InsertAfterAndCopy (RecipientInfo &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RecipientInfo;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // RecipientInfos::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void RecipientInfos::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen RecipientInfos::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // RecipientInfos::BEncContent
+
+
+void  RecipientInfos::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    RecipientInfo *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if (!((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))
+         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2))))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -184);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // RecipientInfos::BDecContent
+
+
+ContentInfo::ContentInfo()
+{
+}
+
+ContentInfo::ContentInfo (const ContentInfo &)
+{
+  Asn1Error << "use of incompletely defined ContentInfo::ContentInfo (const ContentInfo &)" << endl;
+  abort();
+}
+
+ContentInfo::~ContentInfo()
+{
+}
+
+AsnType *ContentInfo::Clone() const
+{
+  return new ContentInfo;
+}
+
+AsnType *ContentInfo::Copy() const
+{
+  return new ContentInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+ContentInfo &ContentInfo::operator = (const ContentInfo &that)
+#else // SNACC_DEEP_COPY
+ContentInfo &ContentInfo::operator = (const ContentInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    contentType = that.contentType;
+    content = that.content;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ContentInfo &ContentInfo::operator = (const ContentInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ContentInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+        ENC_LOAD_ANYBUF(&content, b, l);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+
+    l = contentType.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // ContentInfo::BEncContent
+
+
+void ContentInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -185);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+        DEC_LOAD_ANYBUF(&content, b, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -186);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -187);
+  }
+  else
+    return;
+} // ContentInfo::BDecContent
+
+AsnLen ContentInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ContentInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ContentInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -188);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ContentInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ContentInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ContentInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "contentType ";
+    os << contentType;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "content ";
+    os << content;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ContentInfo::Print
+
+
+SignedData::SignedData()
+{
+#if TCL
+  encapContentInfo = new EncapsulatedContentInfo;
+#else
+  encapContentInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  certificates = NULL;
+  crls = NULL;
+}
+
+SignedData::SignedData (const SignedData &)
+{
+  Asn1Error << "use of incompletely defined SignedData::SignedData (const SignedData &)" << endl;
+  abort();
+}
+
+SignedData::~SignedData()
+{
+  delete encapContentInfo;
+  delete certificates;
+  delete crls;
+}
+
+AsnType *SignedData::Clone() const
+{
+  return new SignedData;
+}
+
+AsnType *SignedData::Copy() const
+{
+  return new SignedData (*this);
+}
+
+#if SNACC_DEEP_COPY
+SignedData &SignedData::operator = (const SignedData &that)
+#else // SNACC_DEEP_COPY
+SignedData &SignedData::operator = (const SignedData &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    digestAlgorithms = that.digestAlgorithms;
+    if (that.encapContentInfo)
+    {
+      if (!encapContentInfo)
+        encapContentInfo = new EncapsulatedContentInfo;
+      *encapContentInfo = *that.encapContentInfo;
+    }
+    else
+    {
+      delete encapContentInfo;
+      encapContentInfo = NULL;
+    }
+    if (that.certificates)
+    {
+      if (!certificates)
+        certificates = new CertificateSet;
+      *certificates = *that.certificates;
+    }
+    else
+    {
+      delete certificates;
+      certificates = NULL;
+    }
+    if (that.crls)
+    {
+      if (!crls)
+        crls = new CertificateRevocationLists;
+      *crls = *that.crls;
+    }
+    else
+    {
+      delete crls;
+      crls = NULL;
+    }
+    signerInfos = that.signerInfos;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SignedData &SignedData::operator = (const SignedData &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+SignedData::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = signerInfos.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (crls))
+  {
+      BEncEocIfNec (b);
+    l = crls->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (certificates))
+  {
+      BEncEocIfNec (b);
+    l = certificates->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = encapContentInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = digestAlgorithms.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // SignedData::BEncContent
+
+
+void SignedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -189);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    digestAlgorithms.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -190);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encapContentInfo = new EncapsulatedContentInfo;
+    encapContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -191);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    certificates = new CertificateSet;
+    certificates->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    crls = new CertificateRevocationLists;
+    crls->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signerInfos.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -192);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -193);
+  }
+  else
+    return;
+} // SignedData::BDecContent
+
+AsnLen SignedData::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void SignedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "SignedData::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -194);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int SignedData::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int SignedData::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void SignedData::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithms ";
+    os << digestAlgorithms;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encapContentInfo))
+  {
+    Indent (os, indentG);
+    os << "encapContentInfo ";
+    os << *encapContentInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encapContentInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (certificates))
+  {
+    Indent (os, indentG);
+    os << "certificates ";
+    os << *certificates;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "certificates ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (crls))
+  {
+    Indent (os, indentG);
+    os << "crls ";
+    os << *crls;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "crls ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "signerInfos ";
+    os << signerInfos;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // SignedData::Print
+
+
+EnvelopedData::EnvelopedData()
+{
+  originatorInfo = NULL;
+#if TCL
+  encryptedContentInfo = new EncryptedContentInfo;
+#else
+  encryptedContentInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  unprotectedAttrs = NULL;
+}
+
+EnvelopedData::EnvelopedData (const EnvelopedData &)
+{
+  Asn1Error << "use of incompletely defined EnvelopedData::EnvelopedData (const EnvelopedData &)" << endl;
+  abort();
+}
+
+EnvelopedData::~EnvelopedData()
+{
+  delete originatorInfo;
+  delete encryptedContentInfo;
+  delete unprotectedAttrs;
+}
+
+AsnType *EnvelopedData::Clone() const
+{
+  return new EnvelopedData;
+}
+
+AsnType *EnvelopedData::Copy() const
+{
+  return new EnvelopedData (*this);
+}
+
+#if SNACC_DEEP_COPY
+EnvelopedData &EnvelopedData::operator = (const EnvelopedData &that)
+#else // SNACC_DEEP_COPY
+EnvelopedData &EnvelopedData::operator = (const EnvelopedData &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.originatorInfo)
+    {
+      if (!originatorInfo)
+        originatorInfo = new OriginatorInfo;
+      *originatorInfo = *that.originatorInfo;
+    }
+    else
+    {
+      delete originatorInfo;
+      originatorInfo = NULL;
+    }
+    recipientInfos = that.recipientInfos;
+    if (that.encryptedContentInfo)
+    {
+      if (!encryptedContentInfo)
+        encryptedContentInfo = new EncryptedContentInfo;
+      *encryptedContentInfo = *that.encryptedContentInfo;
+    }
+    else
+    {
+      delete encryptedContentInfo;
+      encryptedContentInfo = NULL;
+    }
+    if (that.unprotectedAttrs)
+    {
+      if (!unprotectedAttrs)
+        unprotectedAttrs = new Attributes;
+      *unprotectedAttrs = *that.unprotectedAttrs;
+    }
+    else
+    {
+      delete unprotectedAttrs;
+      unprotectedAttrs = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EnvelopedData &EnvelopedData::operator = (const EnvelopedData &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EnvelopedData::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (unprotectedAttrs))
+  {
+      BEncEocIfNec (b);
+    l = unprotectedAttrs->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = encryptedContentInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = recipientInfos.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (originatorInfo))
+  {
+      BEncEocIfNec (b);
+    l = originatorInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // EnvelopedData::BEncContent
+
+
+void EnvelopedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -195);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    originatorInfo = new OriginatorInfo;
+    originatorInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    recipientInfos.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -196);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedContentInfo = new EncryptedContentInfo;
+    encryptedContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -197);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    unprotectedAttrs = new Attributes;
+    unprotectedAttrs->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -198);
+  }
+  else
+    return;
+} // EnvelopedData::BDecContent
+
+AsnLen EnvelopedData::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EnvelopedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EnvelopedData::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -199);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EnvelopedData::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EnvelopedData::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EnvelopedData::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (originatorInfo))
+  {
+    Indent (os, indentG);
+    os << "originatorInfo ";
+    os << *originatorInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "originatorInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "recipientInfos ";
+    os << recipientInfos;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encryptedContentInfo))
+  {
+    Indent (os, indentG);
+    os << "encryptedContentInfo ";
+    os << *encryptedContentInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encryptedContentInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (unprotectedAttrs))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "unprotectedAttrs ";
+    os << *unprotectedAttrs;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "unprotectedAttrs ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // EnvelopedData::Print
+
+
+DigestedData::DigestedData()
+{
+#if TCL
+  digestAlgorithm = new DigestAlgorithmIdentifier;
+#else
+  digestAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  encapContentInfo = new EncapsulatedContentInfo;
+#else
+  encapContentInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+DigestedData::DigestedData (const DigestedData &)
+{
+  Asn1Error << "use of incompletely defined DigestedData::DigestedData (const DigestedData &)" << endl;
+  abort();
+}
+
+DigestedData::~DigestedData()
+{
+  delete digestAlgorithm;
+  delete encapContentInfo;
+}
+
+AsnType *DigestedData::Clone() const
+{
+  return new DigestedData;
+}
+
+AsnType *DigestedData::Copy() const
+{
+  return new DigestedData (*this);
+}
+
+#if SNACC_DEEP_COPY
+DigestedData &DigestedData::operator = (const DigestedData &that)
+#else // SNACC_DEEP_COPY
+DigestedData &DigestedData::operator = (const DigestedData &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.digestAlgorithm)
+    {
+      if (!digestAlgorithm)
+        digestAlgorithm = new DigestAlgorithmIdentifier;
+      *digestAlgorithm = *that.digestAlgorithm;
+    }
+    else
+    {
+      delete digestAlgorithm;
+      digestAlgorithm = NULL;
+    }
+    if (that.encapContentInfo)
+    {
+      if (!encapContentInfo)
+        encapContentInfo = new EncapsulatedContentInfo;
+      *encapContentInfo = *that.encapContentInfo;
+    }
+    else
+    {
+      delete encapContentInfo;
+      encapContentInfo = NULL;
+    }
+    digest = that.digest;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DigestedData &DigestedData::operator = (const DigestedData &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DigestedData::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = digest.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = encapContentInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = digestAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DigestedData::BEncContent
+
+
+void DigestedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -200);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    digestAlgorithm = new DigestAlgorithmIdentifier;
+    digestAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -201);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encapContentInfo = new EncapsulatedContentInfo;
+    encapContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -202);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    digest.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -203);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -204);
+  }
+  else
+    return;
+} // DigestedData::BDecContent
+
+AsnLen DigestedData::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DigestedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DigestedData::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -205);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DigestedData::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DigestedData::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DigestedData::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (digestAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithm ";
+    os << *digestAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encapContentInfo))
+  {
+    Indent (os, indentG);
+    os << "encapContentInfo ";
+    os << *encapContentInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encapContentInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "digest ";
+    os << digest;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DigestedData::Print
+
+
+EncryptedData::EncryptedData()
+{
+#if TCL
+  encryptedContentInfo = new EncryptedContentInfo;
+#else
+  encryptedContentInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EncryptedData::EncryptedData (const EncryptedData &)
+{
+  Asn1Error << "use of incompletely defined EncryptedData::EncryptedData (const EncryptedData &)" << endl;
+  abort();
+}
+
+EncryptedData::~EncryptedData()
+{
+  delete encryptedContentInfo;
+}
+
+AsnType *EncryptedData::Clone() const
+{
+  return new EncryptedData;
+}
+
+AsnType *EncryptedData::Copy() const
+{
+  return new EncryptedData (*this);
+}
+
+#if SNACC_DEEP_COPY
+EncryptedData &EncryptedData::operator = (const EncryptedData &that)
+#else // SNACC_DEEP_COPY
+EncryptedData &EncryptedData::operator = (const EncryptedData &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.encryptedContentInfo)
+    {
+      if (!encryptedContentInfo)
+        encryptedContentInfo = new EncryptedContentInfo;
+      *encryptedContentInfo = *that.encryptedContentInfo;
+    }
+    else
+    {
+      delete encryptedContentInfo;
+      encryptedContentInfo = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EncryptedData &EncryptedData::operator = (const EncryptedData &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EncryptedData::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = encryptedContentInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // EncryptedData::BEncContent
+
+
+void EncryptedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -206);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encryptedContentInfo = new EncryptedContentInfo;
+    encryptedContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -207);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -208);
+  }
+  else
+    return;
+} // EncryptedData::BDecContent
+
+AsnLen EncryptedData::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EncryptedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EncryptedData::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -209);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EncryptedData::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EncryptedData::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EncryptedData::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encryptedContentInfo))
+  {
+    Indent (os, indentG);
+    os << "encryptedContentInfo ";
+    os << *encryptedContentInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encryptedContentInfo ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // EncryptedData::Print
+
+
+AuthenticatedData::AuthenticatedData()
+{
+  originatorInfo = NULL;
+#if TCL
+  macAlgorithm = new MessageAuthenticationCodeAlgorithm;
+#else
+  macAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  digestAlgorithm = NULL;
+#if TCL
+  encapContentInfo = new EncapsulatedContentInfo;
+#else
+  encapContentInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  authenctiatedAttributes = NULL;
+  unauthenticatedAttributes = NULL;
+}
+
+AuthenticatedData::AuthenticatedData (const AuthenticatedData &)
+{
+  Asn1Error << "use of incompletely defined AuthenticatedData::AuthenticatedData (const AuthenticatedData &)" << endl;
+  abort();
+}
+
+AuthenticatedData::~AuthenticatedData()
+{
+  delete originatorInfo;
+  delete macAlgorithm;
+  delete digestAlgorithm;
+  delete encapContentInfo;
+  delete authenctiatedAttributes;
+  delete unauthenticatedAttributes;
+}
+
+AsnType *AuthenticatedData::Clone() const
+{
+  return new AuthenticatedData;
+}
+
+AsnType *AuthenticatedData::Copy() const
+{
+  return new AuthenticatedData (*this);
+}
+
+#if SNACC_DEEP_COPY
+AuthenticatedData &AuthenticatedData::operator = (const AuthenticatedData &that)
+#else // SNACC_DEEP_COPY
+AuthenticatedData &AuthenticatedData::operator = (const AuthenticatedData &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    if (that.originatorInfo)
+    {
+      if (!originatorInfo)
+        originatorInfo = new OriginatorInfo;
+      *originatorInfo = *that.originatorInfo;
+    }
+    else
+    {
+      delete originatorInfo;
+      originatorInfo = NULL;
+    }
+    recipientInfos = that.recipientInfos;
+    if (that.macAlgorithm)
+    {
+      if (!macAlgorithm)
+        macAlgorithm = new MessageAuthenticationCodeAlgorithm;
+      *macAlgorithm = *that.macAlgorithm;
+    }
+    else
+    {
+      delete macAlgorithm;
+      macAlgorithm = NULL;
+    }
+    if (that.digestAlgorithm)
+    {
+      if (!digestAlgorithm)
+        digestAlgorithm = new DigestAlgorithmIdentifier;
+      *digestAlgorithm = *that.digestAlgorithm;
+    }
+    else
+    {
+      delete digestAlgorithm;
+      digestAlgorithm = NULL;
+    }
+    if (that.encapContentInfo)
+    {
+      if (!encapContentInfo)
+        encapContentInfo = new EncapsulatedContentInfo;
+      *encapContentInfo = *that.encapContentInfo;
+    }
+    else
+    {
+      delete encapContentInfo;
+      encapContentInfo = NULL;
+    }
+    if (that.authenctiatedAttributes)
+    {
+      if (!authenctiatedAttributes)
+        authenctiatedAttributes = new Attributes;
+      *authenctiatedAttributes = *that.authenctiatedAttributes;
+    }
+    else
+    {
+      delete authenctiatedAttributes;
+      authenctiatedAttributes = NULL;
+    }
+    mac = that.mac;
+    if (that.unauthenticatedAttributes)
+    {
+      if (!unauthenticatedAttributes)
+        unauthenticatedAttributes = new Attributes;
+      *unauthenticatedAttributes = *that.unauthenticatedAttributes;
+    }
+    else
+    {
+      delete unauthenticatedAttributes;
+      unauthenticatedAttributes = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AuthenticatedData &AuthenticatedData::operator = (const AuthenticatedData &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AuthenticatedData::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (unauthenticatedAttributes))
+  {
+      BEncEocIfNec (b);
+    l = unauthenticatedAttributes->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 3);
+    totalLen += l;
+  }
+
+    l = mac.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (authenctiatedAttributes))
+  {
+      BEncEocIfNec (b);
+    l = authenctiatedAttributes->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 2);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = encapContentInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (digestAlgorithm))
+  {
+      BEncEocIfNec (b);
+    l = digestAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = macAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = recipientInfos.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (originatorInfo))
+  {
+      BEncEocIfNec (b);
+    l = originatorInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // AuthenticatedData::BEncContent
+
+
+void AuthenticatedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -210);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    originatorInfo = new OriginatorInfo;
+    originatorInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    recipientInfos.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -211);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    macAlgorithm = new MessageAuthenticationCodeAlgorithm;
+    macAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -212);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    digestAlgorithm = new DigestAlgorithmIdentifier;
+    digestAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encapContentInfo = new EncapsulatedContentInfo;
+    encapContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -213);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    authenctiatedAttributes = new Attributes;
+    authenctiatedAttributes->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    mac.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -214);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 3)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    unauthenticatedAttributes = new Attributes;
+    unauthenticatedAttributes->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -215);
+  }
+  else
+    return;
+} // AuthenticatedData::BDecContent
+
+AsnLen AuthenticatedData::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AuthenticatedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AuthenticatedData::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -216);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AuthenticatedData::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AuthenticatedData::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AuthenticatedData::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (originatorInfo))
+  {
+    Indent (os, indentG);
+    os << "originatorInfo ";
+    os << *originatorInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "originatorInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "recipientInfos ";
+    os << recipientInfos;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (macAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "macAlgorithm ";
+    os << *macAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "macAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (digestAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithm ";
+    os << *digestAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encapContentInfo))
+  {
+    Indent (os, indentG);
+    os << "encapContentInfo ";
+    os << *encapContentInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encapContentInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (authenctiatedAttributes))
+  {
+    Indent (os, indentG);
+    os << "authenctiatedAttributes ";
+    os << *authenctiatedAttributes;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "authenctiatedAttributes ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "mac ";
+    os << mac;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (unauthenticatedAttributes))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "unauthenticatedAttributes ";
+    os << *unauthenticatedAttributes;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "unauthenticatedAttributes ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AuthenticatedData::Print
+
+
+AsnType *UserKeyingMaterials::Clone() const
+{
+  return new UserKeyingMaterials;
+}
+
+AsnType *UserKeyingMaterials::Copy() const
+{
+  return new UserKeyingMaterials (*this);
+}
+
+AsnLen UserKeyingMaterials::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void UserKeyingMaterials::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "UserKeyingMaterials::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -217);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+UserKeyingMaterials::UserKeyingMaterials (const UserKeyingMaterials &)
+{
+  Asn1Error << "use of incompletely defined UserKeyingMaterials::UserKeyingMaterials (const UserKeyingMaterials &)" << endl;
+  abort();
+}
+
+UserKeyingMaterials::~UserKeyingMaterials()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+UserKeyingMaterials &UserKeyingMaterials::operator = (const UserKeyingMaterials &that)
+#else // SNACC_DEEP_COPY
+UserKeyingMaterials &UserKeyingMaterials::operator = (const UserKeyingMaterials &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined UserKeyingMaterials &UserKeyingMaterials::operator = (const UserKeyingMaterials &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void UserKeyingMaterials::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  UserKeyingMaterials::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // UserKeyingMaterials::SetCurrElmt
+
+
+unsigned long int  UserKeyingMaterials::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // UserKeyingMaterials::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+UserKeyingMaterial *UserKeyingMaterials::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new UserKeyingMaterial;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // UserKeyingMaterials::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+UserKeyingMaterial  *UserKeyingMaterials::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new UserKeyingMaterial;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // UserKeyingMaterials::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+UserKeyingMaterial  *UserKeyingMaterials::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new UserKeyingMaterial;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // UserKeyingMaterials::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+UserKeyingMaterial *UserKeyingMaterials::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new UserKeyingMaterial;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // UserKeyingMaterials::InsertAfter
+
+
+UserKeyingMaterials  &UserKeyingMaterials::AppendCopy (UserKeyingMaterial &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new UserKeyingMaterial;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+UserKeyingMaterials  &UserKeyingMaterials::PrependCopy (UserKeyingMaterial &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new UserKeyingMaterial;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // UserKeyingMaterials::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+UserKeyingMaterials &UserKeyingMaterials::InsertBeforeAndCopy (UserKeyingMaterial &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new UserKeyingMaterial;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // UserKeyingMaterials::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+UserKeyingMaterials  &UserKeyingMaterials::InsertAfterAndCopy (UserKeyingMaterial &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new UserKeyingMaterial;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // UserKeyingMaterials::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void UserKeyingMaterials::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen UserKeyingMaterials::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncDefLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // UserKeyingMaterials::BEncContent
+
+
+void  UserKeyingMaterials::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    UserKeyingMaterial *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+         && (tag1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -218);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // UserKeyingMaterials::BDecContent
+
+
+RC2CBCParameter::RC2CBCParameter()
+{
+}
+
+RC2CBCParameter::RC2CBCParameter (const RC2CBCParameter &)
+{
+  Asn1Error << "use of incompletely defined RC2CBCParameter::RC2CBCParameter (const RC2CBCParameter &)" << endl;
+  abort();
+}
+
+RC2CBCParameter::~RC2CBCParameter()
+{
+}
+
+AsnType *RC2CBCParameter::Clone() const
+{
+  return new RC2CBCParameter;
+}
+
+AsnType *RC2CBCParameter::Copy() const
+{
+  return new RC2CBCParameter (*this);
+}
+
+#if SNACC_DEEP_COPY
+RC2CBCParameter &RC2CBCParameter::operator = (const RC2CBCParameter &that)
+#else // SNACC_DEEP_COPY
+RC2CBCParameter &RC2CBCParameter::operator = (const RC2CBCParameter &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    rc2ParameterVersion = that.rc2ParameterVersion;
+    iv = that.iv;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RC2CBCParameter &RC2CBCParameter::operator = (const RC2CBCParameter &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+RC2CBCParameter::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = iv.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+    l = rc2ParameterVersion.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // RC2CBCParameter::BEncContent
+
+
+void RC2CBCParameter::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    rc2ParameterVersion.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -219);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    iv.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -220);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -221);
+  }
+  else
+    return;
+} // RC2CBCParameter::BDecContent
+
+AsnLen RC2CBCParameter::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void RC2CBCParameter::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "RC2CBCParameter::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -222);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int RC2CBCParameter::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int RC2CBCParameter::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void RC2CBCParameter::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "rc2ParameterVersion ";
+    os << rc2ParameterVersion;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "iv ";
+    os << iv;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // RC2CBCParameter::Print
+
+
+ExtendedCertificateOrCertificate::ExtendedCertificateOrCertificate()
+{
+  choiceId = certificateCid;
+#if TCL
+  certificate = new Certificate;
+#else
+  certificate = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+ExtendedCertificateOrCertificate::ExtendedCertificateOrCertificate (const ExtendedCertificateOrCertificate &)
+{
+  Asn1Error << "use of incompletely defined ExtendedCertificateOrCertificate::ExtendedCertificateOrCertificate (const ExtendedCertificateOrCertificate &)" << endl;
+  abort();
+}
+
+ExtendedCertificateOrCertificate::~ExtendedCertificateOrCertificate()
+{
+  switch (choiceId)
+  {
+    case certificateCid:
+      delete certificate;
+      break;
+    case extendedCertificateCid:
+      delete extendedCertificate;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *ExtendedCertificateOrCertificate::Clone() const
+{
+  return new ExtendedCertificateOrCertificate;
+}
+
+AsnType *ExtendedCertificateOrCertificate::Copy() const
+{
+  return new ExtendedCertificateOrCertificate (*this);
+}
+
+#if SNACC_DEEP_COPY
+ExtendedCertificateOrCertificate &ExtendedCertificateOrCertificate::operator = (const ExtendedCertificateOrCertificate &that)
+#else // SNACC_DEEP_COPY
+ExtendedCertificateOrCertificate &ExtendedCertificateOrCertificate::operator = (const ExtendedCertificateOrCertificate &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case certificateCid:
+        delete certificate;
+        break;
+      case extendedCertificateCid:
+        delete extendedCertificate;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case certificateCid:
+        certificate = new Certificate;
+        *certificate = *that.certificate;
+        break;
+      case extendedCertificateCid:
+        extendedCertificate = new ExtendedCertificate;
+        *extendedCertificate = *that.extendedCertificate;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ExtendedCertificateOrCertificate &ExtendedCertificateOrCertificate::operator = (const ExtendedCertificateOrCertificate &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ExtendedCertificateOrCertificate::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case certificateCid:
+      BEncEocIfNec (b);
+      l = certificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+    case extendedCertificateCid:
+      BEncEocIfNec (b);
+      l = extendedCertificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+      break;
+
+  } // end switch
+  return l;
+} // ExtendedCertificateOrCertificate::BEncContent
+
+
+void ExtendedCertificateOrCertificate::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = certificateCid;
+      certificate = new Certificate;
+        certificate->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      choiceId = extendedCertificateCid;
+      extendedCertificate = new ExtendedCertificate;
+        extendedCertificate->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -223);
+      break;
+  } // end switch
+} // ExtendedCertificateOrCertificate::BDecContent
+
+
+AsnLen ExtendedCertificateOrCertificate::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void ExtendedCertificateOrCertificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int ExtendedCertificateOrCertificate::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ExtendedCertificateOrCertificate::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ExtendedCertificateOrCertificate::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case certificateCid:
+      os << "certificate ";
+      if (certificate)
+        os << *certificate;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case extendedCertificateCid:
+      os << "extendedCertificate ";
+      if (extendedCertificate)
+        os << *extendedCertificate;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // ExtendedCertificateOrCertificate::Print
+
+DigestInfo::DigestInfo()
+{
+#if TCL
+  digestAlgorithm = new DigestAlgorithmIdentifier;
+#else
+  digestAlgorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+DigestInfo::DigestInfo (const DigestInfo &)
+{
+  Asn1Error << "use of incompletely defined DigestInfo::DigestInfo (const DigestInfo &)" << endl;
+  abort();
+}
+
+DigestInfo::~DigestInfo()
+{
+  delete digestAlgorithm;
+}
+
+AsnType *DigestInfo::Clone() const
+{
+  return new DigestInfo;
+}
+
+AsnType *DigestInfo::Copy() const
+{
+  return new DigestInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+DigestInfo &DigestInfo::operator = (const DigestInfo &that)
+#else // SNACC_DEEP_COPY
+DigestInfo &DigestInfo::operator = (const DigestInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.digestAlgorithm)
+    {
+      if (!digestAlgorithm)
+        digestAlgorithm = new DigestAlgorithmIdentifier;
+      *digestAlgorithm = *that.digestAlgorithm;
+    }
+    else
+    {
+      delete digestAlgorithm;
+      digestAlgorithm = NULL;
+    }
+    digest = that.digest;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DigestInfo &DigestInfo::operator = (const DigestInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DigestInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = digest.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = digestAlgorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DigestInfo::BEncContent
+
+
+void DigestInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    digestAlgorithm = new DigestAlgorithmIdentifier;
+    digestAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -224);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    digest.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -225);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -226);
+  }
+  else
+    return;
+} // DigestInfo::BDecContent
+
+AsnLen DigestInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DigestInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DigestInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -227);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DigestInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DigestInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DigestInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (digestAlgorithm))
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithm ";
+    os << *digestAlgorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "digestAlgorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "digest ";
+    os << digest;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DigestInfo::Print
+
+
diff --git a/SecurityASN1/c++/sm_ess.cpp b/SecurityASN1/c++/sm_ess.cpp
new file mode 100644
index 00000000..91ee7266
--- /dev/null
+++ b/SecurityASN1/c++/sm_ess.cpp
@@ -0,0 +1,6921 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_ess.cpp - class member functions for ASN.1 module ExtendedSecurityServices
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+AsnType *SigningCertificateSeqOf1::Clone() const
+{
+  return new SigningCertificateSeqOf1;
+}
+
+AsnType *SigningCertificateSeqOf1::Copy() const
+{
+  return new SigningCertificateSeqOf1 (*this);
+}
+
+AsnLen SigningCertificateSeqOf1::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void SigningCertificateSeqOf1::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "SigningCertificateSeqOf1::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -100);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+SigningCertificateSeqOf1::SigningCertificateSeqOf1 (const SigningCertificateSeqOf1 &)
+{
+  Asn1Error << "use of incompletely defined SigningCertificateSeqOf1::SigningCertificateSeqOf1 (const SigningCertificateSeqOf1 &)" << endl;
+  abort();
+}
+
+SigningCertificateSeqOf1::~SigningCertificateSeqOf1()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+SigningCertificateSeqOf1 &SigningCertificateSeqOf1::operator = (const SigningCertificateSeqOf1 &that)
+#else // SNACC_DEEP_COPY
+SigningCertificateSeqOf1 &SigningCertificateSeqOf1::operator = (const SigningCertificateSeqOf1 &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SigningCertificateSeqOf1 &SigningCertificateSeqOf1::operator = (const SigningCertificateSeqOf1 &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void SigningCertificateSeqOf1::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  SigningCertificateSeqOf1::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // SigningCertificateSeqOf1::SetCurrElmt
+
+
+unsigned long int  SigningCertificateSeqOf1::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // SigningCertificateSeqOf1::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+PolicyInformation *SigningCertificateSeqOf1::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new PolicyInformation;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SigningCertificateSeqOf1::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+PolicyInformation  *SigningCertificateSeqOf1::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SigningCertificateSeqOf1::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+PolicyInformation  *SigningCertificateSeqOf1::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SigningCertificateSeqOf1::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+PolicyInformation *SigningCertificateSeqOf1::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SigningCertificateSeqOf1::InsertAfter
+
+
+SigningCertificateSeqOf1  &SigningCertificateSeqOf1::AppendCopy (PolicyInformation &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+SigningCertificateSeqOf1  &SigningCertificateSeqOf1::PrependCopy (PolicyInformation &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // SigningCertificateSeqOf1::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+SigningCertificateSeqOf1 &SigningCertificateSeqOf1::InsertBeforeAndCopy (PolicyInformation &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // SigningCertificateSeqOf1::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+SigningCertificateSeqOf1  &SigningCertificateSeqOf1::InsertAfterAndCopy (PolicyInformation &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // SigningCertificateSeqOf1::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void SigningCertificateSeqOf1::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen SigningCertificateSeqOf1::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // SigningCertificateSeqOf1::BEncContent
+
+
+void  SigningCertificateSeqOf1::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    PolicyInformation *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -101);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // SigningCertificateSeqOf1::BDecContent
+
+
+AsnType *MLReceiptPolicySeqOf1::Clone() const
+{
+  return new MLReceiptPolicySeqOf1;
+}
+
+AsnType *MLReceiptPolicySeqOf1::Copy() const
+{
+  return new MLReceiptPolicySeqOf1 (*this);
+}
+
+AsnLen MLReceiptPolicySeqOf1::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void MLReceiptPolicySeqOf1::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "MLReceiptPolicySeqOf1::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -102);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+MLReceiptPolicySeqOf1::MLReceiptPolicySeqOf1 (const MLReceiptPolicySeqOf1 &)
+{
+  Asn1Error << "use of incompletely defined MLReceiptPolicySeqOf1::MLReceiptPolicySeqOf1 (const MLReceiptPolicySeqOf1 &)" << endl;
+  abort();
+}
+
+MLReceiptPolicySeqOf1::~MLReceiptPolicySeqOf1()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+MLReceiptPolicySeqOf1 &MLReceiptPolicySeqOf1::operator = (const MLReceiptPolicySeqOf1 &that)
+#else // SNACC_DEEP_COPY
+MLReceiptPolicySeqOf1 &MLReceiptPolicySeqOf1::operator = (const MLReceiptPolicySeqOf1 &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined MLReceiptPolicySeqOf1 &MLReceiptPolicySeqOf1::operator = (const MLReceiptPolicySeqOf1 &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void MLReceiptPolicySeqOf1::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  MLReceiptPolicySeqOf1::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // MLReceiptPolicySeqOf1::SetCurrElmt
+
+
+unsigned long int  MLReceiptPolicySeqOf1::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // MLReceiptPolicySeqOf1::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+GeneralNames *MLReceiptPolicySeqOf1::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new GeneralNames;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLReceiptPolicySeqOf1::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+GeneralNames  *MLReceiptPolicySeqOf1::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLReceiptPolicySeqOf1::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+GeneralNames  *MLReceiptPolicySeqOf1::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLReceiptPolicySeqOf1::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+GeneralNames *MLReceiptPolicySeqOf1::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLReceiptPolicySeqOf1::InsertAfter
+
+
+MLReceiptPolicySeqOf1  &MLReceiptPolicySeqOf1::AppendCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+MLReceiptPolicySeqOf1  &MLReceiptPolicySeqOf1::PrependCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // MLReceiptPolicySeqOf1::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+MLReceiptPolicySeqOf1 &MLReceiptPolicySeqOf1::InsertBeforeAndCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // MLReceiptPolicySeqOf1::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+MLReceiptPolicySeqOf1  &MLReceiptPolicySeqOf1::InsertAfterAndCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // MLReceiptPolicySeqOf1::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void MLReceiptPolicySeqOf1::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen MLReceiptPolicySeqOf1::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // MLReceiptPolicySeqOf1::BEncContent
+
+
+void  MLReceiptPolicySeqOf1::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    GeneralNames *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -103);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // MLReceiptPolicySeqOf1::BDecContent
+
+
+AsnType *MLReceiptPolicySeqOf::Clone() const
+{
+  return new MLReceiptPolicySeqOf;
+}
+
+AsnType *MLReceiptPolicySeqOf::Copy() const
+{
+  return new MLReceiptPolicySeqOf (*this);
+}
+
+AsnLen MLReceiptPolicySeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void MLReceiptPolicySeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "MLReceiptPolicySeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -104);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+MLReceiptPolicySeqOf::MLReceiptPolicySeqOf (const MLReceiptPolicySeqOf &)
+{
+  Asn1Error << "use of incompletely defined MLReceiptPolicySeqOf::MLReceiptPolicySeqOf (const MLReceiptPolicySeqOf &)" << endl;
+  abort();
+}
+
+MLReceiptPolicySeqOf::~MLReceiptPolicySeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+MLReceiptPolicySeqOf &MLReceiptPolicySeqOf::operator = (const MLReceiptPolicySeqOf &that)
+#else // SNACC_DEEP_COPY
+MLReceiptPolicySeqOf &MLReceiptPolicySeqOf::operator = (const MLReceiptPolicySeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined MLReceiptPolicySeqOf &MLReceiptPolicySeqOf::operator = (const MLReceiptPolicySeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void MLReceiptPolicySeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  MLReceiptPolicySeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // MLReceiptPolicySeqOf::SetCurrElmt
+
+
+unsigned long int  MLReceiptPolicySeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // MLReceiptPolicySeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+GeneralNames *MLReceiptPolicySeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new GeneralNames;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLReceiptPolicySeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+GeneralNames  *MLReceiptPolicySeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLReceiptPolicySeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+GeneralNames  *MLReceiptPolicySeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLReceiptPolicySeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+GeneralNames *MLReceiptPolicySeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLReceiptPolicySeqOf::InsertAfter
+
+
+MLReceiptPolicySeqOf  &MLReceiptPolicySeqOf::AppendCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+MLReceiptPolicySeqOf  &MLReceiptPolicySeqOf::PrependCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // MLReceiptPolicySeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+MLReceiptPolicySeqOf &MLReceiptPolicySeqOf::InsertBeforeAndCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // MLReceiptPolicySeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+MLReceiptPolicySeqOf  &MLReceiptPolicySeqOf::InsertAfterAndCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // MLReceiptPolicySeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void MLReceiptPolicySeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen MLReceiptPolicySeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // MLReceiptPolicySeqOf::BEncContent
+
+
+void  MLReceiptPolicySeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    GeneralNames *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -105);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // MLReceiptPolicySeqOf::BDecContent
+
+
+AsnType *ReceiptsFromSeqOf::Clone() const
+{
+  return new ReceiptsFromSeqOf;
+}
+
+AsnType *ReceiptsFromSeqOf::Copy() const
+{
+  return new ReceiptsFromSeqOf (*this);
+}
+
+AsnLen ReceiptsFromSeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ReceiptsFromSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ReceiptsFromSeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -106);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+ReceiptsFromSeqOf::ReceiptsFromSeqOf (const ReceiptsFromSeqOf &)
+{
+  Asn1Error << "use of incompletely defined ReceiptsFromSeqOf::ReceiptsFromSeqOf (const ReceiptsFromSeqOf &)" << endl;
+  abort();
+}
+
+ReceiptsFromSeqOf::~ReceiptsFromSeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+ReceiptsFromSeqOf &ReceiptsFromSeqOf::operator = (const ReceiptsFromSeqOf &that)
+#else // SNACC_DEEP_COPY
+ReceiptsFromSeqOf &ReceiptsFromSeqOf::operator = (const ReceiptsFromSeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ReceiptsFromSeqOf &ReceiptsFromSeqOf::operator = (const ReceiptsFromSeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void ReceiptsFromSeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  ReceiptsFromSeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // ReceiptsFromSeqOf::SetCurrElmt
+
+
+unsigned long int  ReceiptsFromSeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // ReceiptsFromSeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+GeneralNames *ReceiptsFromSeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new GeneralNames;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ReceiptsFromSeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+GeneralNames  *ReceiptsFromSeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ReceiptsFromSeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+GeneralNames  *ReceiptsFromSeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ReceiptsFromSeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+GeneralNames *ReceiptsFromSeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ReceiptsFromSeqOf::InsertAfter
+
+
+ReceiptsFromSeqOf  &ReceiptsFromSeqOf::AppendCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+ReceiptsFromSeqOf  &ReceiptsFromSeqOf::PrependCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // ReceiptsFromSeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ReceiptsFromSeqOf &ReceiptsFromSeqOf::InsertBeforeAndCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // ReceiptsFromSeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ReceiptsFromSeqOf  &ReceiptsFromSeqOf::InsertAfterAndCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // ReceiptsFromSeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void ReceiptsFromSeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen ReceiptsFromSeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // ReceiptsFromSeqOf::BEncContent
+
+
+void  ReceiptsFromSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    GeneralNames *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -107);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // ReceiptsFromSeqOf::BDecContent
+
+
+AsnType *ReceiptRequestSeqOf::Clone() const
+{
+  return new ReceiptRequestSeqOf;
+}
+
+AsnType *ReceiptRequestSeqOf::Copy() const
+{
+  return new ReceiptRequestSeqOf (*this);
+}
+
+AsnLen ReceiptRequestSeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ReceiptRequestSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ReceiptRequestSeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -108);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+ReceiptRequestSeqOf::ReceiptRequestSeqOf (const ReceiptRequestSeqOf &)
+{
+  Asn1Error << "use of incompletely defined ReceiptRequestSeqOf::ReceiptRequestSeqOf (const ReceiptRequestSeqOf &)" << endl;
+  abort();
+}
+
+ReceiptRequestSeqOf::~ReceiptRequestSeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+ReceiptRequestSeqOf &ReceiptRequestSeqOf::operator = (const ReceiptRequestSeqOf &that)
+#else // SNACC_DEEP_COPY
+ReceiptRequestSeqOf &ReceiptRequestSeqOf::operator = (const ReceiptRequestSeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ReceiptRequestSeqOf &ReceiptRequestSeqOf::operator = (const ReceiptRequestSeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void ReceiptRequestSeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  ReceiptRequestSeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // ReceiptRequestSeqOf::SetCurrElmt
+
+
+unsigned long int  ReceiptRequestSeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // ReceiptRequestSeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+GeneralNames *ReceiptRequestSeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new GeneralNames;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ReceiptRequestSeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+GeneralNames  *ReceiptRequestSeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ReceiptRequestSeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+GeneralNames  *ReceiptRequestSeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ReceiptRequestSeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+GeneralNames *ReceiptRequestSeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ReceiptRequestSeqOf::InsertAfter
+
+
+ReceiptRequestSeqOf  &ReceiptRequestSeqOf::AppendCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+ReceiptRequestSeqOf  &ReceiptRequestSeqOf::PrependCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // ReceiptRequestSeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ReceiptRequestSeqOf &ReceiptRequestSeqOf::InsertBeforeAndCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // ReceiptRequestSeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ReceiptRequestSeqOf  &ReceiptRequestSeqOf::InsertAfterAndCopy (GeneralNames &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralNames;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // ReceiptRequestSeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void ReceiptRequestSeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen ReceiptRequestSeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // ReceiptRequestSeqOf::BEncContent
+
+
+void  ReceiptRequestSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    GeneralNames *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -109);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // ReceiptRequestSeqOf::BDecContent
+
+
+ESSPrivacyMark::ESSPrivacyMark()
+{
+  choiceId = pStringCid;
+#if TCL
+  pString = new PrintableString;
+#else
+  pString = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+ESSPrivacyMark::ESSPrivacyMark (const ESSPrivacyMark &)
+{
+  Asn1Error << "use of incompletely defined ESSPrivacyMark::ESSPrivacyMark (const ESSPrivacyMark &)" << endl;
+  abort();
+}
+
+ESSPrivacyMark::~ESSPrivacyMark()
+{
+  switch (choiceId)
+  {
+    case pStringCid:
+      delete pString;
+      break;
+    case utf8StringCid:
+      delete utf8String;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *ESSPrivacyMark::Clone() const
+{
+  return new ESSPrivacyMark;
+}
+
+AsnType *ESSPrivacyMark::Copy() const
+{
+  return new ESSPrivacyMark (*this);
+}
+
+#if SNACC_DEEP_COPY
+ESSPrivacyMark &ESSPrivacyMark::operator = (const ESSPrivacyMark &that)
+#else // SNACC_DEEP_COPY
+ESSPrivacyMark &ESSPrivacyMark::operator = (const ESSPrivacyMark &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case pStringCid:
+        delete pString;
+        break;
+      case utf8StringCid:
+        delete utf8String;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case pStringCid:
+        pString = new PrintableString;
+        *pString = *that.pString;
+        break;
+      case utf8StringCid:
+        utf8String = new UTF8String;
+        *utf8String = *that.utf8String;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ESSPrivacyMark &ESSPrivacyMark::operator = (const ESSPrivacyMark &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ESSPrivacyMark::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case pStringCid:
+      l = pString->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+      break;
+
+    case utf8StringCid:
+      l = utf8String->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, 12);
+      break;
+
+  } // end switch
+  return l;
+} // ESSPrivacyMark::BEncContent
+
+
+void ESSPrivacyMark::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE):
+      choiceId = pStringCid;
+      pString = new PrintableString;
+        pString->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, 12):
+    case MAKE_TAG_ID (UNIV, CONS, 12):
+      choiceId = utf8StringCid;
+      utf8String = new UTF8String;
+        utf8String->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -110);
+      break;
+  } // end switch
+} // ESSPrivacyMark::BDecContent
+
+
+AsnLen ESSPrivacyMark::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void ESSPrivacyMark::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int ESSPrivacyMark::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ESSPrivacyMark::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ESSPrivacyMark::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case pStringCid:
+      os << "pString ";
+      if (pString)
+        os << *pString;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case utf8StringCid:
+      os << "utf8String ";
+      if (utf8String)
+        os << *utf8String;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // ESSPrivacyMark::Print
+
+SecurityCategory::SecurityCategory()
+{
+}
+
+SecurityCategory::SecurityCategory (const SecurityCategory &)
+{
+  Asn1Error << "use of incompletely defined SecurityCategory::SecurityCategory (const SecurityCategory &)" << endl;
+  abort();
+}
+
+SecurityCategory::~SecurityCategory()
+{
+}
+
+AsnType *SecurityCategory::Clone() const
+{
+  return new SecurityCategory;
+}
+
+AsnType *SecurityCategory::Copy() const
+{
+  return new SecurityCategory (*this);
+}
+
+#if SNACC_DEEP_COPY
+SecurityCategory &SecurityCategory::operator = (const SecurityCategory &that)
+#else // SNACC_DEEP_COPY
+SecurityCategory &SecurityCategory::operator = (const SecurityCategory &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    type = that.type;
+    value = that.value;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SecurityCategory &SecurityCategory::operator = (const SecurityCategory &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+SecurityCategory::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+        ENC_LOAD_ANYBUF(&value, b, l);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+
+    l = type.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+
+  return totalLen;
+} // SecurityCategory::BEncContent
+
+
+void SecurityCategory::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    type.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -111);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+        DEC_LOAD_ANYBUF(&value, b, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -112);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -113);
+  }
+  else
+    return;
+} // SecurityCategory::BDecContent
+
+AsnLen SecurityCategory::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void SecurityCategory::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "SecurityCategory::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -114);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int SecurityCategory::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int SecurityCategory::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void SecurityCategory::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "type ";
+    os << type;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "value ";
+    os << value;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // SecurityCategory::Print
+
+
+EntityIdentifier::EntityIdentifier()
+{
+  choiceId = issuerAndSerialNumberCid;
+#if TCL
+  issuerAndSerialNumber = new IssuerAndSerialNumber;
+#else
+  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EntityIdentifier::EntityIdentifier (const EntityIdentifier &)
+{
+  Asn1Error << "use of incompletely defined EntityIdentifier::EntityIdentifier (const EntityIdentifier &)" << endl;
+  abort();
+}
+
+EntityIdentifier::~EntityIdentifier()
+{
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      delete issuerAndSerialNumber;
+      break;
+    case subjectKeyIdentifierCid:
+      delete subjectKeyIdentifier;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *EntityIdentifier::Clone() const
+{
+  return new EntityIdentifier;
+}
+
+AsnType *EntityIdentifier::Copy() const
+{
+  return new EntityIdentifier (*this);
+}
+
+#if SNACC_DEEP_COPY
+EntityIdentifier &EntityIdentifier::operator = (const EntityIdentifier &that)
+#else // SNACC_DEEP_COPY
+EntityIdentifier &EntityIdentifier::operator = (const EntityIdentifier &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        delete issuerAndSerialNumber;
+        break;
+      case subjectKeyIdentifierCid:
+        delete subjectKeyIdentifier;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case issuerAndSerialNumberCid:
+        issuerAndSerialNumber = new IssuerAndSerialNumber;
+        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
+        break;
+      case subjectKeyIdentifierCid:
+        subjectKeyIdentifier = new KeyIdentifier;
+        *subjectKeyIdentifier = *that.subjectKeyIdentifier;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EntityIdentifier &EntityIdentifier::operator = (const EntityIdentifier &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EntityIdentifier::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      BEncEocIfNec (b);
+      l = issuerAndSerialNumber->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+    case subjectKeyIdentifierCid:
+      l = subjectKeyIdentifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+      break;
+
+  } // end switch
+  return l;
+} // EntityIdentifier::BEncContent
+
+
+void EntityIdentifier::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = issuerAndSerialNumberCid;
+      issuerAndSerialNumber = new IssuerAndSerialNumber;
+        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE):
+      choiceId = subjectKeyIdentifierCid;
+      subjectKeyIdentifier = new KeyIdentifier;
+        subjectKeyIdentifier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -115);
+      break;
+  } // end switch
+} // EntityIdentifier::BDecContent
+
+
+AsnLen EntityIdentifier::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void EntityIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int EntityIdentifier::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EntityIdentifier::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EntityIdentifier::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case issuerAndSerialNumberCid:
+      os << "issuerAndSerialNumber ";
+      if (issuerAndSerialNumber)
+        os << *issuerAndSerialNumber;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case subjectKeyIdentifierCid:
+      os << "subjectKeyIdentifier ";
+      if (subjectKeyIdentifier)
+        os << *subjectKeyIdentifier;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // EntityIdentifier::Print
+
+ReceiptsFrom::ReceiptsFrom()
+{
+  choiceId = allOrFirstTierCid;
+#if TCL
+  allOrFirstTier = new AllOrFirstTier;
+#else
+  allOrFirstTier = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+ReceiptsFrom::ReceiptsFrom (const ReceiptsFrom &)
+{
+  Asn1Error << "use of incompletely defined ReceiptsFrom::ReceiptsFrom (const ReceiptsFrom &)" << endl;
+  abort();
+}
+
+ReceiptsFrom::~ReceiptsFrom()
+{
+  switch (choiceId)
+  {
+    case allOrFirstTierCid:
+      delete allOrFirstTier;
+      break;
+    case receiptListCid:
+      delete receiptList;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *ReceiptsFrom::Clone() const
+{
+  return new ReceiptsFrom;
+}
+
+AsnType *ReceiptsFrom::Copy() const
+{
+  return new ReceiptsFrom (*this);
+}
+
+#if SNACC_DEEP_COPY
+ReceiptsFrom &ReceiptsFrom::operator = (const ReceiptsFrom &that)
+#else // SNACC_DEEP_COPY
+ReceiptsFrom &ReceiptsFrom::operator = (const ReceiptsFrom &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case allOrFirstTierCid:
+        delete allOrFirstTier;
+        break;
+      case receiptListCid:
+        delete receiptList;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case allOrFirstTierCid:
+        allOrFirstTier = new AllOrFirstTier;
+        *allOrFirstTier = *that.allOrFirstTier;
+        break;
+      case receiptListCid:
+        receiptList = new ReceiptsFromSeqOf;
+        *receiptList = *that.receiptList;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ReceiptsFrom &ReceiptsFrom::operator = (const ReceiptsFrom &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ReceiptsFrom::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case allOrFirstTierCid:
+      l = allOrFirstTier->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+      break;
+
+    case receiptListCid:
+      BEncEocIfNec (b);
+      l = receiptList->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+      break;
+
+  } // end switch
+  return l;
+} // ReceiptsFrom::BEncContent
+
+
+void ReceiptsFrom::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (CNTX, PRIM, 0):
+      choiceId = allOrFirstTierCid;
+      allOrFirstTier = new AllOrFirstTier;
+        allOrFirstTier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = receiptListCid;
+      receiptList = new ReceiptsFromSeqOf;
+        receiptList->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -116);
+      break;
+  } // end switch
+} // ReceiptsFrom::BDecContent
+
+
+AsnLen ReceiptsFrom::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void ReceiptsFrom::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int ReceiptsFrom::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ReceiptsFrom::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ReceiptsFrom::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case allOrFirstTierCid:
+      os << "allOrFirstTier ";
+      if (allOrFirstTier)
+        os << *allOrFirstTier;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case receiptListCid:
+      os << "receiptList ";
+      if (receiptList)
+        os << *receiptList;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // ReceiptsFrom::Print
+
+AsnType *SecurityCategories::Clone() const
+{
+  return new SecurityCategories;
+}
+
+AsnType *SecurityCategories::Copy() const
+{
+  return new SecurityCategories (*this);
+}
+
+AsnLen SecurityCategories::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void SecurityCategories::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "SecurityCategories::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -117);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+SecurityCategories::SecurityCategories (const SecurityCategories &)
+{
+  Asn1Error << "use of incompletely defined SecurityCategories::SecurityCategories (const SecurityCategories &)" << endl;
+  abort();
+}
+
+SecurityCategories::~SecurityCategories()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+SecurityCategories &SecurityCategories::operator = (const SecurityCategories &that)
+#else // SNACC_DEEP_COPY
+SecurityCategories &SecurityCategories::operator = (const SecurityCategories &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SecurityCategories &SecurityCategories::operator = (const SecurityCategories &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void SecurityCategories::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  SecurityCategories::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // SecurityCategories::SetCurrElmt
+
+
+unsigned long int  SecurityCategories::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // SecurityCategories::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+SecurityCategory *SecurityCategories::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new SecurityCategory;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SecurityCategories::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+SecurityCategory  *SecurityCategories::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SecurityCategory;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SecurityCategories::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+SecurityCategory  *SecurityCategories::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SecurityCategory;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SecurityCategories::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+SecurityCategory *SecurityCategories::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SecurityCategory;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SecurityCategories::InsertAfter
+
+
+SecurityCategories  &SecurityCategories::AppendCopy (SecurityCategory &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SecurityCategory;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+SecurityCategories  &SecurityCategories::PrependCopy (SecurityCategory &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SecurityCategory;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // SecurityCategories::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+SecurityCategories &SecurityCategories::InsertBeforeAndCopy (SecurityCategory &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SecurityCategory;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // SecurityCategories::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+SecurityCategories  &SecurityCategories::InsertAfterAndCopy (SecurityCategory &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new SecurityCategory;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // SecurityCategories::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void SecurityCategories::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen SecurityCategories::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // SecurityCategories::BEncContent
+
+
+void  SecurityCategories::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    SecurityCategory *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -118);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // SecurityCategories::BDecContent
+
+
+MLReceiptPolicy::MLReceiptPolicy()
+{
+  choiceId = noneCid;
+#if TCL
+  none = new AsnNull;
+#else
+  none = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+MLReceiptPolicy::MLReceiptPolicy (const MLReceiptPolicy &)
+{
+  Asn1Error << "use of incompletely defined MLReceiptPolicy::MLReceiptPolicy (const MLReceiptPolicy &)" << endl;
+  abort();
+}
+
+MLReceiptPolicy::~MLReceiptPolicy()
+{
+  switch (choiceId)
+  {
+    case noneCid:
+      delete none;
+      break;
+    case insteadOfCid:
+      delete insteadOf;
+      break;
+    case inAdditionToCid:
+      delete inAdditionTo;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *MLReceiptPolicy::Clone() const
+{
+  return new MLReceiptPolicy;
+}
+
+AsnType *MLReceiptPolicy::Copy() const
+{
+  return new MLReceiptPolicy (*this);
+}
+
+#if SNACC_DEEP_COPY
+MLReceiptPolicy &MLReceiptPolicy::operator = (const MLReceiptPolicy &that)
+#else // SNACC_DEEP_COPY
+MLReceiptPolicy &MLReceiptPolicy::operator = (const MLReceiptPolicy &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case noneCid:
+        delete none;
+        break;
+      case insteadOfCid:
+        delete insteadOf;
+        break;
+      case inAdditionToCid:
+        delete inAdditionTo;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case noneCid:
+        none = new AsnNull;
+        *none = *that.none;
+        break;
+      case insteadOfCid:
+        insteadOf = new MLReceiptPolicySeqOf;
+        *insteadOf = *that.insteadOf;
+        break;
+      case inAdditionToCid:
+        inAdditionTo = new MLReceiptPolicySeqOf1;
+        *inAdditionTo = *that.inAdditionTo;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined MLReceiptPolicy &MLReceiptPolicy::operator = (const MLReceiptPolicy &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+MLReceiptPolicy::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case noneCid:
+      l = none->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+      break;
+
+    case insteadOfCid:
+      BEncEocIfNec (b);
+      l = insteadOf->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+      break;
+
+    case inAdditionToCid:
+      BEncEocIfNec (b);
+      l = inAdditionTo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 2);
+      break;
+
+  } // end switch
+  return l;
+} // MLReceiptPolicy::BEncContent
+
+
+void MLReceiptPolicy::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (CNTX, PRIM, 0):
+      choiceId = noneCid;
+      none = new AsnNull;
+        none->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = insteadOfCid;
+      insteadOf = new MLReceiptPolicySeqOf;
+        insteadOf->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 2):
+      choiceId = inAdditionToCid;
+      inAdditionTo = new MLReceiptPolicySeqOf1;
+        inAdditionTo->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -119);
+      break;
+  } // end switch
+} // MLReceiptPolicy::BDecContent
+
+
+AsnLen MLReceiptPolicy::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void MLReceiptPolicy::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int MLReceiptPolicy::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int MLReceiptPolicy::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void MLReceiptPolicy::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case noneCid:
+      os << "none ";
+      if (none)
+        os << *none;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case insteadOfCid:
+      os << "insteadOf ";
+      if (insteadOf)
+        os << *insteadOf;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case inAdditionToCid:
+      os << "inAdditionTo ";
+      if (inAdditionTo)
+        os << *inAdditionTo;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // MLReceiptPolicy::Print
+
+ESSCertID::ESSCertID()
+{
+  issuerSerial = NULL;
+}
+
+ESSCertID::ESSCertID (const ESSCertID &)
+{
+  Asn1Error << "use of incompletely defined ESSCertID::ESSCertID (const ESSCertID &)" << endl;
+  abort();
+}
+
+ESSCertID::~ESSCertID()
+{
+  delete issuerSerial;
+}
+
+AsnType *ESSCertID::Clone() const
+{
+  return new ESSCertID;
+}
+
+AsnType *ESSCertID::Copy() const
+{
+  return new ESSCertID (*this);
+}
+
+#if SNACC_DEEP_COPY
+ESSCertID &ESSCertID::operator = (const ESSCertID &that)
+#else // SNACC_DEEP_COPY
+ESSCertID &ESSCertID::operator = (const ESSCertID &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    certHash = that.certHash;
+    if (that.issuerSerial)
+    {
+      if (!issuerSerial)
+        issuerSerial = new IssuerSerial;
+      *issuerSerial = *that.issuerSerial;
+    }
+    else
+    {
+      delete issuerSerial;
+      issuerSerial = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ESSCertID &ESSCertID::operator = (const ESSCertID &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ESSCertID::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (issuerSerial))
+  {
+      BEncEocIfNec (b);
+    l = issuerSerial->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = certHash.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // ESSCertID::BEncContent
+
+
+void ESSCertID::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    certHash.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -120);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuerSerial = new IssuerSerial;
+    issuerSerial->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -121);
+  }
+  else
+    return;
+} // ESSCertID::BDecContent
+
+AsnLen ESSCertID::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ESSCertID::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ESSCertID::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -122);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ESSCertID::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ESSCertID::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ESSCertID::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "certHash ";
+    os << certHash;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (issuerSerial))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "issuerSerial ";
+    os << *issuerSerial;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "issuerSerial ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ESSCertID::Print
+
+
+AsnType *SigningCertificateSeqOf::Clone() const
+{
+  return new SigningCertificateSeqOf;
+}
+
+AsnType *SigningCertificateSeqOf::Copy() const
+{
+  return new SigningCertificateSeqOf (*this);
+}
+
+AsnLen SigningCertificateSeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void SigningCertificateSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "SigningCertificateSeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -123);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+SigningCertificateSeqOf::SigningCertificateSeqOf (const SigningCertificateSeqOf &)
+{
+  Asn1Error << "use of incompletely defined SigningCertificateSeqOf::SigningCertificateSeqOf (const SigningCertificateSeqOf &)" << endl;
+  abort();
+}
+
+SigningCertificateSeqOf::~SigningCertificateSeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+SigningCertificateSeqOf &SigningCertificateSeqOf::operator = (const SigningCertificateSeqOf &that)
+#else // SNACC_DEEP_COPY
+SigningCertificateSeqOf &SigningCertificateSeqOf::operator = (const SigningCertificateSeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SigningCertificateSeqOf &SigningCertificateSeqOf::operator = (const SigningCertificateSeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void SigningCertificateSeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  SigningCertificateSeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // SigningCertificateSeqOf::SetCurrElmt
+
+
+unsigned long int  SigningCertificateSeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // SigningCertificateSeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+ESSCertID *SigningCertificateSeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new ESSCertID;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SigningCertificateSeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+ESSCertID  *SigningCertificateSeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSCertID;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SigningCertificateSeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ESSCertID  *SigningCertificateSeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSCertID;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SigningCertificateSeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ESSCertID *SigningCertificateSeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSCertID;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // SigningCertificateSeqOf::InsertAfter
+
+
+SigningCertificateSeqOf  &SigningCertificateSeqOf::AppendCopy (ESSCertID &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSCertID;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+SigningCertificateSeqOf  &SigningCertificateSeqOf::PrependCopy (ESSCertID &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSCertID;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // SigningCertificateSeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+SigningCertificateSeqOf &SigningCertificateSeqOf::InsertBeforeAndCopy (ESSCertID &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSCertID;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // SigningCertificateSeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+SigningCertificateSeqOf  &SigningCertificateSeqOf::InsertAfterAndCopy (ESSCertID &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSCertID;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // SigningCertificateSeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void SigningCertificateSeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen SigningCertificateSeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // SigningCertificateSeqOf::BEncContent
+
+
+void  SigningCertificateSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    ESSCertID *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -124);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // SigningCertificateSeqOf::BDecContent
+
+
+ESSSecurityLabel::ESSSecurityLabel()
+{
+  security_classification = NULL;
+  privacy_mark = NULL;
+  security_categories = NULL;
+}
+
+ESSSecurityLabel::ESSSecurityLabel (const ESSSecurityLabel &)
+{
+  Asn1Error << "use of incompletely defined ESSSecurityLabel::ESSSecurityLabel (const ESSSecurityLabel &)" << endl;
+  abort();
+}
+
+ESSSecurityLabel::~ESSSecurityLabel()
+{
+  delete security_classification;
+  delete privacy_mark;
+  delete security_categories;
+}
+
+AsnType *ESSSecurityLabel::Clone() const
+{
+  return new ESSSecurityLabel;
+}
+
+AsnType *ESSSecurityLabel::Copy() const
+{
+  return new ESSSecurityLabel (*this);
+}
+
+#if SNACC_DEEP_COPY
+ESSSecurityLabel &ESSSecurityLabel::operator = (const ESSSecurityLabel &that)
+#else // SNACC_DEEP_COPY
+ESSSecurityLabel &ESSSecurityLabel::operator = (const ESSSecurityLabel &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    security_policy_identifier = that.security_policy_identifier;
+    if (that.security_classification)
+    {
+      if (!security_classification)
+        security_classification = new SecurityClassification;
+      *security_classification = *that.security_classification;
+    }
+    else
+    {
+      delete security_classification;
+      security_classification = NULL;
+    }
+    if (that.privacy_mark)
+    {
+      if (!privacy_mark)
+        privacy_mark = new ESSPrivacyMark;
+      *privacy_mark = *that.privacy_mark;
+    }
+    else
+    {
+      delete privacy_mark;
+      privacy_mark = NULL;
+    }
+    if (that.security_categories)
+    {
+      if (!security_categories)
+        security_categories = new SecurityCategories;
+      *security_categories = *that.security_categories;
+    }
+    else
+    {
+      delete security_categories;
+      security_categories = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ESSSecurityLabel &ESSSecurityLabel::operator = (const ESSSecurityLabel &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen ESSSecurityLabel::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      AsnBuf outputBuf;
+       int iii=0, tmpCount=0;
+      char *lpszBuf = (char *)calloc(1, 1024);
+      outputBuf.Init(lpszBuf, 1024);
+      outputBuf.ResetInWriteRvsMode();
+      CSM_Buffer *tmpEnc[4];
+  if (NOT_NULL (security_categories))
+  {
+      BEncEocIfNec (b);
+    l = security_categories->BEncContent (outputBuf);
+    l += BEncConsLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+  if (NOT_NULL (privacy_mark))
+  {
+    l = privacy_mark->BEncContent (outputBuf);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+  if (NOT_NULL (security_classification))
+  {
+    l = security_classification->BEncContent (outputBuf);
+    BEncDefLenTo127 (outputBuf, l);
+    l++;
+
+    l += BEncTag1 (outputBuf, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+    l = security_policy_identifier.BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+
+      vdasnacc_sortSet(tmpEnc, iii);
+      tmpCount = iii;  /** REMEMBER how many we have**/
+      for (iii=0; iii < tmpCount; iii++)
+         SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < tmpCount; iii++) delete tmpEnc[iii];
+      free(lpszBuf);
+  return totalLen;
+} // ESSSecurityLabel::BEncContent
+
+
+void ESSSecurityLabel::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen setBytesDecoded = 0;
+  unsigned int mandatoryElmtsDecoded = 0;
+  AsnLen elmtLen1;
+
+  for (; (setBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )
+  {
+    tag1 = BDecTag (b, setBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, setBytesDecoded, env)
+      break; /* exit for loop */
+    }
+    elmtLen1 = BDecLen (b, setBytesDecoded, env);
+    switch (tag1)
+    {
+      case MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE):
+        security_policy_identifier.BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          mandatoryElmtsDecoded++;
+          break;
+
+      case MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE):
+        security_classification = new SecurityClassification;
+        security_classification->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+      case MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE):
+      case MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE):
+      case MAKE_TAG_ID (UNIV, PRIM, 12):
+      case MAKE_TAG_ID (UNIV, CONS, 12):
+        privacy_mark = new ESSPrivacyMark;
+        privacy_mark->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+      case MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE):
+        security_categories = new SecurityCategories;
+        security_categories->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+       default:
+         Asn1Error << "Unexpected Tag on SET elmt." << endl;
+         longjmp (env, -125);
+    } // end switch
+  } // end for loop
+  bytesDecoded += setBytesDecoded;
+  if (mandatoryElmtsDecoded != 1)
+  {
+     Asn1Error << "ERROR - non-optional SET element missing." << endl;
+     longjmp (env, -126);
+  }
+} // ESSSecurityLabel::BDecContent
+
+AsnLen
+ESSSecurityLabel::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void ESSSecurityLabel::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "ESSSecurityLabel::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -127);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ESSSecurityLabel::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ESSSecurityLabel::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ESSSecurityLabel::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SET --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "security-policy-identifier ";
+    os << security_policy_identifier;
+  }
+
+  if (NOT_NULL (security_classification))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "security-classification ";
+    os << *security_classification;
+  }
+  else
+    os << "-- void2 --\n";
+
+  if (NOT_NULL (privacy_mark))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "privacy-mark ";
+    os << *privacy_mark;
+  }
+  else
+    os << "-- void2 --\n";
+
+  if (NOT_NULL (security_categories))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "security-categories ";
+    os << *security_categories;
+  }
+  else
+    os << "-- void2 --\n";
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ESSSecurityLabel - operator <<
+
+
+MLData::MLData()
+{
+#if TCL
+  mailListIdentifier = new EntityIdentifier;
+#else
+  mailListIdentifier = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  mlReceiptPolicy = NULL;
+}
+
+MLData::MLData (const MLData &)
+{
+  Asn1Error << "use of incompletely defined MLData::MLData (const MLData &)" << endl;
+  abort();
+}
+
+MLData::~MLData()
+{
+  delete mailListIdentifier;
+  delete mlReceiptPolicy;
+}
+
+AsnType *MLData::Clone() const
+{
+  return new MLData;
+}
+
+AsnType *MLData::Copy() const
+{
+  return new MLData (*this);
+}
+
+#if SNACC_DEEP_COPY
+MLData &MLData::operator = (const MLData &that)
+#else // SNACC_DEEP_COPY
+MLData &MLData::operator = (const MLData &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.mailListIdentifier)
+    {
+      if (!mailListIdentifier)
+        mailListIdentifier = new EntityIdentifier;
+      *mailListIdentifier = *that.mailListIdentifier;
+    }
+    else
+    {
+      delete mailListIdentifier;
+      mailListIdentifier = NULL;
+    }
+    expansionTime = that.expansionTime;
+    if (that.mlReceiptPolicy)
+    {
+      if (!mlReceiptPolicy)
+        mlReceiptPolicy = new MLReceiptPolicy;
+      *mlReceiptPolicy = *that.mlReceiptPolicy;
+    }
+    else
+    {
+      delete mlReceiptPolicy;
+      mlReceiptPolicy = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined MLData &MLData::operator = (const MLData &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+MLData::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (mlReceiptPolicy))
+  {
+    l = mlReceiptPolicy->BEncContent (b);
+    totalLen += l;
+  }
+
+    l = expansionTime.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    totalLen += l;
+
+    l = mailListIdentifier->BEncContent (b);
+    totalLen += l;
+
+  return totalLen;
+} // MLData::BEncContent
+
+
+void MLData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    mailListIdentifier = new EntityIdentifier;
+    mailListIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -128);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    expansionTime.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -129);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    mlReceiptPolicy = new MLReceiptPolicy;
+    mlReceiptPolicy->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -130);
+  }
+  else
+    return;
+} // MLData::BDecContent
+
+AsnLen MLData::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void MLData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "MLData::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -131);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int MLData::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int MLData::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void MLData::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (mailListIdentifier))
+  {
+    Indent (os, indentG);
+    os << "mailListIdentifier ";
+    os << *mailListIdentifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "mailListIdentifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "expansionTime ";
+    os << expansionTime;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (mlReceiptPolicy))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "mlReceiptPolicy ";
+    os << *mlReceiptPolicy;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "mlReceiptPolicy ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // MLData::Print
+
+
+ReceiptRequest::ReceiptRequest()
+{
+#if TCL
+  receiptsFrom = new ReceiptsFrom;
+#else
+  receiptsFrom = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+ReceiptRequest::ReceiptRequest (const ReceiptRequest &)
+{
+  Asn1Error << "use of incompletely defined ReceiptRequest::ReceiptRequest (const ReceiptRequest &)" << endl;
+  abort();
+}
+
+ReceiptRequest::~ReceiptRequest()
+{
+  delete receiptsFrom;
+}
+
+AsnType *ReceiptRequest::Clone() const
+{
+  return new ReceiptRequest;
+}
+
+AsnType *ReceiptRequest::Copy() const
+{
+  return new ReceiptRequest (*this);
+}
+
+#if SNACC_DEEP_COPY
+ReceiptRequest &ReceiptRequest::operator = (const ReceiptRequest &that)
+#else // SNACC_DEEP_COPY
+ReceiptRequest &ReceiptRequest::operator = (const ReceiptRequest &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    signedContentIdentifier = that.signedContentIdentifier;
+    if (that.receiptsFrom)
+    {
+      if (!receiptsFrom)
+        receiptsFrom = new ReceiptsFrom;
+      *receiptsFrom = *that.receiptsFrom;
+    }
+    else
+    {
+      delete receiptsFrom;
+      receiptsFrom = NULL;
+    }
+    receiptsTo = that.receiptsTo;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ReceiptRequest &ReceiptRequest::operator = (const ReceiptRequest &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ReceiptRequest::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = receiptsTo.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = receiptsFrom->BEncContent (b);
+    totalLen += l;
+
+    l = signedContentIdentifier.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // ReceiptRequest::BEncContent
+
+
+void ReceiptRequest::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signedContentIdentifier.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -132);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    receiptsFrom = new ReceiptsFrom;
+    receiptsFrom->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -133);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    receiptsTo.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -134);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -135);
+  }
+  else
+    return;
+} // ReceiptRequest::BDecContent
+
+AsnLen ReceiptRequest::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ReceiptRequest::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ReceiptRequest::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -136);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ReceiptRequest::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ReceiptRequest::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ReceiptRequest::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "signedContentIdentifier ";
+    os << signedContentIdentifier;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (receiptsFrom))
+  {
+    Indent (os, indentG);
+    os << "receiptsFrom ";
+    os << *receiptsFrom;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "receiptsFrom ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "receiptsTo ";
+    os << receiptsTo;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ReceiptRequest::Print
+
+
+Receipt::Receipt()
+{
+}
+
+Receipt::Receipt (const Receipt &)
+{
+  Asn1Error << "use of incompletely defined Receipt::Receipt (const Receipt &)" << endl;
+  abort();
+}
+
+Receipt::~Receipt()
+{
+}
+
+AsnType *Receipt::Clone() const
+{
+  return new Receipt;
+}
+
+AsnType *Receipt::Copy() const
+{
+  return new Receipt (*this);
+}
+
+#if SNACC_DEEP_COPY
+Receipt &Receipt::operator = (const Receipt &that)
+#else // SNACC_DEEP_COPY
+Receipt &Receipt::operator = (const Receipt &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    version = that.version;
+    contentType = that.contentType;
+    signedContentIdentifier = that.signedContentIdentifier;
+    originatorSignatureValue = that.originatorSignatureValue;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Receipt &Receipt::operator = (const Receipt &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+Receipt::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = originatorSignatureValue.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+    l = signedContentIdentifier.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+    l = contentType.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+    l = version.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // Receipt::BEncContent
+
+
+void Receipt::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -137);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -138);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signedContentIdentifier.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -139);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    originatorSignatureValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -140);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -141);
+  }
+  else
+    return;
+} // Receipt::BDecContent
+
+AsnLen Receipt::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void Receipt::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "Receipt::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -142);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int Receipt::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int Receipt::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void Receipt::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << version;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "contentType ";
+    os << contentType;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "signedContentIdentifier ";
+    os << signedContentIdentifier;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "originatorSignatureValue ";
+    os << originatorSignatureValue;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // Receipt::Print
+
+
+ContentHints::ContentHints()
+{
+  contentDescription = NULL;
+}
+
+ContentHints::ContentHints (const ContentHints &)
+{
+  Asn1Error << "use of incompletely defined ContentHints::ContentHints (const ContentHints &)" << endl;
+  abort();
+}
+
+ContentHints::~ContentHints()
+{
+  delete contentDescription;
+}
+
+AsnType *ContentHints::Clone() const
+{
+  return new ContentHints;
+}
+
+AsnType *ContentHints::Copy() const
+{
+  return new ContentHints (*this);
+}
+
+#if SNACC_DEEP_COPY
+ContentHints &ContentHints::operator = (const ContentHints &that)
+#else // SNACC_DEEP_COPY
+ContentHints &ContentHints::operator = (const ContentHints &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.contentDescription)
+    {
+      if (!contentDescription)
+        contentDescription = new UTF8String;
+      *contentDescription = *that.contentDescription;
+    }
+    else
+    {
+      delete contentDescription;
+      contentDescription = NULL;
+    }
+    contentType = that.contentType;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ContentHints &ContentHints::operator = (const ContentHints &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ContentHints::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = contentType.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (contentDescription))
+  {
+    l = contentDescription->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, 12);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // ContentHints::BEncContent
+
+
+void ContentHints::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, 12))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, 12)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentDescription = new UTF8String;
+    contentDescription->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -143);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -144);
+  }
+  else
+    return;
+} // ContentHints::BDecContent
+
+AsnLen ContentHints::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ContentHints::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ContentHints::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -145);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ContentHints::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ContentHints::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ContentHints::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (contentDescription))
+  {
+    Indent (os, indentG);
+    os << "contentDescription ";
+    os << *contentDescription;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "contentDescription ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "contentType ";
+    os << contentType;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ContentHints::Print
+
+
+ContentReference::ContentReference()
+{
+}
+
+ContentReference::ContentReference (const ContentReference &)
+{
+  Asn1Error << "use of incompletely defined ContentReference::ContentReference (const ContentReference &)" << endl;
+  abort();
+}
+
+ContentReference::~ContentReference()
+{
+}
+
+AsnType *ContentReference::Clone() const
+{
+  return new ContentReference;
+}
+
+AsnType *ContentReference::Copy() const
+{
+  return new ContentReference (*this);
+}
+
+#if SNACC_DEEP_COPY
+ContentReference &ContentReference::operator = (const ContentReference &that)
+#else // SNACC_DEEP_COPY
+ContentReference &ContentReference::operator = (const ContentReference &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    contentType = that.contentType;
+    signedContentIdentifier = that.signedContentIdentifier;
+    originatorSignatureValue = that.originatorSignatureValue;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ContentReference &ContentReference::operator = (const ContentReference &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ContentReference::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = originatorSignatureValue.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+    l = signedContentIdentifier.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+    l = contentType.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // ContentReference::BEncContent
+
+
+void ContentReference::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -146);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signedContentIdentifier.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -147);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    originatorSignatureValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -148);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -149);
+  }
+  else
+    return;
+} // ContentReference::BDecContent
+
+AsnLen ContentReference::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ContentReference::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ContentReference::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -150);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ContentReference::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ContentReference::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ContentReference::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "contentType ";
+    os << contentType;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "signedContentIdentifier ";
+    os << signedContentIdentifier;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "originatorSignatureValue ";
+    os << originatorSignatureValue;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ContentReference::Print
+
+
+AsnType *EquivalentLabels::Clone() const
+{
+  return new EquivalentLabels;
+}
+
+AsnType *EquivalentLabels::Copy() const
+{
+  return new EquivalentLabels (*this);
+}
+
+AsnLen EquivalentLabels::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EquivalentLabels::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EquivalentLabels::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -151);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+EquivalentLabels::EquivalentLabels (const EquivalentLabels &)
+{
+  Asn1Error << "use of incompletely defined EquivalentLabels::EquivalentLabels (const EquivalentLabels &)" << endl;
+  abort();
+}
+
+EquivalentLabels::~EquivalentLabels()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+EquivalentLabels &EquivalentLabels::operator = (const EquivalentLabels &that)
+#else // SNACC_DEEP_COPY
+EquivalentLabels &EquivalentLabels::operator = (const EquivalentLabels &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EquivalentLabels &EquivalentLabels::operator = (const EquivalentLabels &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void EquivalentLabels::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  EquivalentLabels::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // EquivalentLabels::SetCurrElmt
+
+
+unsigned long int  EquivalentLabels::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // EquivalentLabels::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+ESSSecurityLabel *EquivalentLabels::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new ESSSecurityLabel;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // EquivalentLabels::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+ESSSecurityLabel  *EquivalentLabels::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSSecurityLabel;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // EquivalentLabels::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ESSSecurityLabel  *EquivalentLabels::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSSecurityLabel;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // EquivalentLabels::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ESSSecurityLabel *EquivalentLabels::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSSecurityLabel;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // EquivalentLabels::InsertAfter
+
+
+EquivalentLabels  &EquivalentLabels::AppendCopy (ESSSecurityLabel &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSSecurityLabel;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+EquivalentLabels  &EquivalentLabels::PrependCopy (ESSSecurityLabel &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSSecurityLabel;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // EquivalentLabels::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+EquivalentLabels &EquivalentLabels::InsertBeforeAndCopy (ESSSecurityLabel &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSSecurityLabel;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // EquivalentLabels::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+EquivalentLabels  &EquivalentLabels::InsertAfterAndCopy (ESSSecurityLabel &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ESSSecurityLabel;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // EquivalentLabels::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void EquivalentLabels::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen EquivalentLabels::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // EquivalentLabels::BEncContent
+
+
+void  EquivalentLabels::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    ESSSecurityLabel *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -152);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // EquivalentLabels::BDecContent
+
+
+AsnType *MLExpansionHistory::Clone() const
+{
+  return new MLExpansionHistory;
+}
+
+AsnType *MLExpansionHistory::Copy() const
+{
+  return new MLExpansionHistory (*this);
+}
+
+AsnLen MLExpansionHistory::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void MLExpansionHistory::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "MLExpansionHistory::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -153);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+MLExpansionHistory::MLExpansionHistory (const MLExpansionHistory &)
+{
+  Asn1Error << "use of incompletely defined MLExpansionHistory::MLExpansionHistory (const MLExpansionHistory &)" << endl;
+  abort();
+}
+
+MLExpansionHistory::~MLExpansionHistory()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+MLExpansionHistory &MLExpansionHistory::operator = (const MLExpansionHistory &that)
+#else // SNACC_DEEP_COPY
+MLExpansionHistory &MLExpansionHistory::operator = (const MLExpansionHistory &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined MLExpansionHistory &MLExpansionHistory::operator = (const MLExpansionHistory &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void MLExpansionHistory::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  MLExpansionHistory::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // MLExpansionHistory::SetCurrElmt
+
+
+unsigned long int  MLExpansionHistory::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // MLExpansionHistory::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+MLData *MLExpansionHistory::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new MLData;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLExpansionHistory::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+MLData  *MLExpansionHistory::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new MLData;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLExpansionHistory::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+MLData  *MLExpansionHistory::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new MLData;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLExpansionHistory::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+MLData *MLExpansionHistory::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new MLData;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // MLExpansionHistory::InsertAfter
+
+
+MLExpansionHistory  &MLExpansionHistory::AppendCopy (MLData &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new MLData;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+MLExpansionHistory  &MLExpansionHistory::PrependCopy (MLData &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new MLData;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // MLExpansionHistory::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+MLExpansionHistory &MLExpansionHistory::InsertBeforeAndCopy (MLData &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new MLData;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // MLExpansionHistory::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+MLExpansionHistory  &MLExpansionHistory::InsertAfterAndCopy (MLData &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new MLData;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // MLExpansionHistory::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void MLExpansionHistory::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen MLExpansionHistory::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // MLExpansionHistory::BEncContent
+
+
+void  MLExpansionHistory::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    MLData *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -154);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // MLExpansionHistory::BDecContent
+
+
+SigningCertificate::SigningCertificate()
+{
+  policies = NULL;
+}
+
+SigningCertificate::SigningCertificate (const SigningCertificate &)
+{
+  Asn1Error << "use of incompletely defined SigningCertificate::SigningCertificate (const SigningCertificate &)" << endl;
+  abort();
+}
+
+SigningCertificate::~SigningCertificate()
+{
+  delete policies;
+}
+
+AsnType *SigningCertificate::Clone() const
+{
+  return new SigningCertificate;
+}
+
+AsnType *SigningCertificate::Copy() const
+{
+  return new SigningCertificate (*this);
+}
+
+#if SNACC_DEEP_COPY
+SigningCertificate &SigningCertificate::operator = (const SigningCertificate &that)
+#else // SNACC_DEEP_COPY
+SigningCertificate &SigningCertificate::operator = (const SigningCertificate &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    certs = that.certs;
+    if (that.policies)
+    {
+      if (!policies)
+        policies = new SigningCertificateSeqOf1;
+      *policies = *that.policies;
+    }
+    else
+    {
+      delete policies;
+      policies = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SigningCertificate &SigningCertificate::operator = (const SigningCertificate &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+SigningCertificate::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (policies))
+  {
+      BEncEocIfNec (b);
+    l = policies->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = certs.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // SigningCertificate::BEncContent
+
+
+void SigningCertificate::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    certs.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -155);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    policies = new SigningCertificateSeqOf1;
+    policies->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -156);
+  }
+  else
+    return;
+} // SigningCertificate::BDecContent
+
+AsnLen SigningCertificate::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void SigningCertificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "SigningCertificate::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -157);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int SigningCertificate::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int SigningCertificate::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void SigningCertificate::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "certs ";
+    os << certs;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (policies))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "policies ";
+    os << *policies;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "policies ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // SigningCertificate::Print
+
+
diff --git a/SecurityASN1/c++/sm_vdatypes.cpp b/SecurityASN1/c++/sm_vdatypes.cpp
new file mode 100644
index 00000000..9d0fde91
--- /dev/null
+++ b/SecurityASN1/c++/sm_vdatypes.cpp
@@ -0,0 +1,90 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_vdatypes.cpp - class member functions for ASN.1 module VdaEnhancedTypes
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+AsnType *BigIntegerStr::Clone() const
+{
+  return new BigIntegerStr;
+}
+
+AsnType *BigIntegerStr::Copy() const
+{
+  return new BigIntegerStr (*this);
+}
+
+AsnLen BigIntegerStr::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    return l;
+}
+
+void BigIntegerStr::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+    {
+        Asn1Error << "BigIntegerStr::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, -100);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int BigIntegerStr::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int BigIntegerStr::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
diff --git a/SecurityASN1/c++/sm_x411mtsas.cpp b/SecurityASN1/c++/sm_x411mtsas.cpp
new file mode 100644
index 00000000..bbf0af10
--- /dev/null
+++ b/SecurityASN1/c++/sm_x411mtsas.cpp
@@ -0,0 +1,5045 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x411mtsas.cpp - class member functions for ASN.1 module MTSAbstractService
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+CountryName::CountryName()
+{
+  choiceId = x121_dcc_codeCid;
+#if TCL
+  x121_dcc_code = new NumericString;
+#else
+  x121_dcc_code = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+CountryName::CountryName (const CountryName &)
+{
+  Asn1Error << "use of incompletely defined CountryName::CountryName (const CountryName &)" << endl;
+  abort();
+}
+
+CountryName::~CountryName()
+{
+  switch (choiceId)
+  {
+    case x121_dcc_codeCid:
+      delete x121_dcc_code;
+      break;
+    case iso_3166_alpha2_codeCid:
+      delete iso_3166_alpha2_code;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *CountryName::Clone() const
+{
+  return new CountryName;
+}
+
+AsnType *CountryName::Copy() const
+{
+  return new CountryName (*this);
+}
+
+#if SNACC_DEEP_COPY
+CountryName &CountryName::operator = (const CountryName &that)
+#else // SNACC_DEEP_COPY
+CountryName &CountryName::operator = (const CountryName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case x121_dcc_codeCid:
+        delete x121_dcc_code;
+        break;
+      case iso_3166_alpha2_codeCid:
+        delete iso_3166_alpha2_code;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case x121_dcc_codeCid:
+        x121_dcc_code = new NumericString;
+        *x121_dcc_code = *that.x121_dcc_code;
+        break;
+      case iso_3166_alpha2_codeCid:
+        iso_3166_alpha2_code = new PrintableString;
+        *iso_3166_alpha2_code = *that.iso_3166_alpha2_code;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CountryName &CountryName::operator = (const CountryName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+CountryName::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case x121_dcc_codeCid:
+      l = x121_dcc_code->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE);
+      break;
+
+    case iso_3166_alpha2_codeCid:
+      l = iso_3166_alpha2_code->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+      break;
+
+  } // end switch
+  return l;
+} // CountryName::BEncContent
+
+
+void CountryName::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE):
+      choiceId = x121_dcc_codeCid;
+      x121_dcc_code = new NumericString;
+        x121_dcc_code->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE):
+      choiceId = iso_3166_alpha2_codeCid;
+      iso_3166_alpha2_code = new PrintableString;
+        iso_3166_alpha2_code->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -100);
+      break;
+  } // end switch
+} // CountryName::BDecContent
+
+
+AsnLen CountryName::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, APPL, CONS, 1);
+    return l;
+}
+
+void CountryName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+    AsnLen extraLen1;
+
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (APPL, CONS, 1))    {
+        Asn1Error << "CountryName::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, -101);
+    }
+    extraLen1 = BDecLen (b, bytesDecoded, env);
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+    if (extraLen1 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+}
+
+int CountryName::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int CountryName::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void CountryName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case x121_dcc_codeCid:
+      os << "x121-dcc-code ";
+      if (x121_dcc_code)
+        os << *x121_dcc_code;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case iso_3166_alpha2_codeCid:
+      os << "iso-3166-alpha2-code ";
+      if (iso_3166_alpha2_code)
+        os << *iso_3166_alpha2_code;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // CountryName::Print
+
+AdministrationDomainName::AdministrationDomainName()
+{
+  choiceId = numericCid;
+#if TCL
+  numeric = new NumericString;
+#else
+  numeric = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+AdministrationDomainName::AdministrationDomainName (const AdministrationDomainName &)
+{
+  Asn1Error << "use of incompletely defined AdministrationDomainName::AdministrationDomainName (const AdministrationDomainName &)" << endl;
+  abort();
+}
+
+AdministrationDomainName::~AdministrationDomainName()
+{
+  switch (choiceId)
+  {
+    case numericCid:
+      delete numeric;
+      break;
+    case printableCid:
+      delete printable;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *AdministrationDomainName::Clone() const
+{
+  return new AdministrationDomainName;
+}
+
+AsnType *AdministrationDomainName::Copy() const
+{
+  return new AdministrationDomainName (*this);
+}
+
+#if SNACC_DEEP_COPY
+AdministrationDomainName &AdministrationDomainName::operator = (const AdministrationDomainName &that)
+#else // SNACC_DEEP_COPY
+AdministrationDomainName &AdministrationDomainName::operator = (const AdministrationDomainName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case numericCid:
+        delete numeric;
+        break;
+      case printableCid:
+        delete printable;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case numericCid:
+        numeric = new NumericString;
+        *numeric = *that.numeric;
+        break;
+      case printableCid:
+        printable = new PrintableString;
+        *printable = *that.printable;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AdministrationDomainName &AdministrationDomainName::operator = (const AdministrationDomainName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AdministrationDomainName::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case numericCid:
+      l = numeric->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE);
+      break;
+
+    case printableCid:
+      l = printable->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+      break;
+
+  } // end switch
+  return l;
+} // AdministrationDomainName::BEncContent
+
+
+void AdministrationDomainName::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE):
+      choiceId = numericCid;
+      numeric = new NumericString;
+        numeric->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE):
+      choiceId = printableCid;
+      printable = new PrintableString;
+        printable->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -102);
+      break;
+  } // end switch
+} // AdministrationDomainName::BDecContent
+
+
+AsnLen AdministrationDomainName::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, APPL, CONS, 2);
+    return l;
+}
+
+void AdministrationDomainName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+    AsnLen extraLen1;
+
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (APPL, CONS, 2))    {
+        Asn1Error << "AdministrationDomainName::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, -103);
+    }
+    extraLen1 = BDecLen (b, bytesDecoded, env);
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+    if (extraLen1 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+}
+
+int AdministrationDomainName::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AdministrationDomainName::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AdministrationDomainName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case numericCid:
+      os << "numeric ";
+      if (numeric)
+        os << *numeric;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case printableCid:
+      os << "printable ";
+      if (printable)
+        os << *printable;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // AdministrationDomainName::Print
+
+PrivateDomainName::PrivateDomainName()
+{
+  choiceId = numericCid;
+#if TCL
+  numeric = new NumericString;
+#else
+  numeric = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+PrivateDomainName::PrivateDomainName (const PrivateDomainName &)
+{
+  Asn1Error << "use of incompletely defined PrivateDomainName::PrivateDomainName (const PrivateDomainName &)" << endl;
+  abort();
+}
+
+PrivateDomainName::~PrivateDomainName()
+{
+  switch (choiceId)
+  {
+    case numericCid:
+      delete numeric;
+      break;
+    case printableCid:
+      delete printable;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *PrivateDomainName::Clone() const
+{
+  return new PrivateDomainName;
+}
+
+AsnType *PrivateDomainName::Copy() const
+{
+  return new PrivateDomainName (*this);
+}
+
+#if SNACC_DEEP_COPY
+PrivateDomainName &PrivateDomainName::operator = (const PrivateDomainName &that)
+#else // SNACC_DEEP_COPY
+PrivateDomainName &PrivateDomainName::operator = (const PrivateDomainName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case numericCid:
+        delete numeric;
+        break;
+      case printableCid:
+        delete printable;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case numericCid:
+        numeric = new NumericString;
+        *numeric = *that.numeric;
+        break;
+      case printableCid:
+        printable = new PrintableString;
+        *printable = *that.printable;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PrivateDomainName &PrivateDomainName::operator = (const PrivateDomainName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+PrivateDomainName::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case numericCid:
+      l = numeric->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE);
+      break;
+
+    case printableCid:
+      l = printable->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+      break;
+
+  } // end switch
+  return l;
+} // PrivateDomainName::BEncContent
+
+
+void PrivateDomainName::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE):
+      choiceId = numericCid;
+      numeric = new NumericString;
+        numeric->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE):
+      choiceId = printableCid;
+      printable = new PrintableString;
+        printable->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -104);
+      break;
+  } // end switch
+} // PrivateDomainName::BDecContent
+
+
+AsnLen PrivateDomainName::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void PrivateDomainName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int PrivateDomainName::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PrivateDomainName::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void PrivateDomainName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case numericCid:
+      os << "numeric ";
+      if (numeric)
+        os << *numeric;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case printableCid:
+      os << "printable ";
+      if (printable)
+        os << *printable;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // PrivateDomainName::Print
+
+PersonalName::PersonalName()
+{
+  given_name = NULL;
+  initials = NULL;
+  generation_qualifier = NULL;
+}
+
+PersonalName::PersonalName (const PersonalName &)
+{
+  Asn1Error << "use of incompletely defined PersonalName::PersonalName (const PersonalName &)" << endl;
+  abort();
+}
+
+PersonalName::~PersonalName()
+{
+  delete given_name;
+  delete initials;
+  delete generation_qualifier;
+}
+
+AsnType *PersonalName::Clone() const
+{
+  return new PersonalName;
+}
+
+AsnType *PersonalName::Copy() const
+{
+  return new PersonalName (*this);
+}
+
+#if SNACC_DEEP_COPY
+PersonalName &PersonalName::operator = (const PersonalName &that)
+#else // SNACC_DEEP_COPY
+PersonalName &PersonalName::operator = (const PersonalName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    surname = that.surname;
+    if (that.given_name)
+    {
+      if (!given_name)
+        given_name = new PrintableString;
+      *given_name = *that.given_name;
+    }
+    else
+    {
+      delete given_name;
+      given_name = NULL;
+    }
+    if (that.initials)
+    {
+      if (!initials)
+        initials = new PrintableString;
+      *initials = *that.initials;
+    }
+    else
+    {
+      delete initials;
+      initials = NULL;
+    }
+    if (that.generation_qualifier)
+    {
+      if (!generation_qualifier)
+        generation_qualifier = new PrintableString;
+      *generation_qualifier = *that.generation_qualifier;
+    }
+    else
+    {
+      delete generation_qualifier;
+      generation_qualifier = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PersonalName &PersonalName::operator = (const PersonalName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen PersonalName::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      AsnBuf outputBuf;
+       int iii=0, tmpCount=0;
+      char *lpszBuf = (char *)calloc(1, 1024);
+      outputBuf.Init(lpszBuf, 1024);
+      outputBuf.ResetInWriteRvsMode();
+      CSM_Buffer *tmpEnc[4];
+  if (NOT_NULL (generation_qualifier))
+  {
+    l = generation_qualifier->BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, CNTX, PRIM, 3);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+  if (NOT_NULL (initials))
+  {
+    l = initials->BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, CNTX, PRIM, 2);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+  if (NOT_NULL (given_name))
+  {
+    l = given_name->BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, CNTX, PRIM, 1);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+    l = surname.BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, CNTX, PRIM, 0);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+
+      vdasnacc_sortSet(tmpEnc, iii);
+      tmpCount = iii;  /** REMEMBER how many we have**/
+      for (iii=0; iii < tmpCount; iii++)
+         SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < tmpCount; iii++) delete tmpEnc[iii];
+      free(lpszBuf);
+  return totalLen;
+} // PersonalName::BEncContent
+
+
+void PersonalName::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen setBytesDecoded = 0;
+  unsigned int mandatoryElmtsDecoded = 0;
+  AsnLen elmtLen1;
+
+  for (; (setBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )
+  {
+    tag1 = BDecTag (b, setBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, setBytesDecoded, env)
+      break; /* exit for loop */
+    }
+    elmtLen1 = BDecLen (b, setBytesDecoded, env);
+    switch (tag1)
+    {
+      case MAKE_TAG_ID (CNTX, PRIM, 0):
+      case MAKE_TAG_ID (CNTX, CONS, 0):
+        surname.BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          mandatoryElmtsDecoded++;
+          break;
+
+      case MAKE_TAG_ID (CNTX, PRIM, 1):
+      case MAKE_TAG_ID (CNTX, CONS, 1):
+        given_name = new PrintableString;
+        given_name->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+      case MAKE_TAG_ID (CNTX, PRIM, 2):
+      case MAKE_TAG_ID (CNTX, CONS, 2):
+        initials = new PrintableString;
+        initials->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+      case MAKE_TAG_ID (CNTX, PRIM, 3):
+      case MAKE_TAG_ID (CNTX, CONS, 3):
+        generation_qualifier = new PrintableString;
+        generation_qualifier->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+       default:
+         Asn1Error << "Unexpected Tag on SET elmt." << endl;
+         longjmp (env, -105);
+    } // end switch
+  } // end for loop
+  bytesDecoded += setBytesDecoded;
+  if (mandatoryElmtsDecoded != 1)
+  {
+     Asn1Error << "ERROR - non-optional SET element missing." << endl;
+     longjmp (env, -106);
+  }
+} // PersonalName::BDecContent
+
+AsnLen
+PersonalName::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void PersonalName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "PersonalName::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -107);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PersonalName::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PersonalName::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void PersonalName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SET --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "surname ";
+    os << surname;
+  }
+
+  if (NOT_NULL (given_name))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "given-name ";
+    os << *given_name;
+  }
+  else
+    os << "-- void2 --\n";
+
+  if (NOT_NULL (initials))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "initials ";
+    os << *initials;
+  }
+  else
+    os << "-- void2 --\n";
+
+  if (NOT_NULL (generation_qualifier))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "generation-qualifier ";
+    os << *generation_qualifier;
+  }
+  else
+    os << "-- void2 --\n";
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // PersonalName - operator <<
+
+
+DomainDefinedAttribute::DomainDefinedAttribute()
+{
+}
+
+DomainDefinedAttribute::DomainDefinedAttribute (const DomainDefinedAttribute &)
+{
+  Asn1Error << "use of incompletely defined DomainDefinedAttribute::DomainDefinedAttribute (const DomainDefinedAttribute &)" << endl;
+  abort();
+}
+
+DomainDefinedAttribute::~DomainDefinedAttribute()
+{
+}
+
+AsnType *DomainDefinedAttribute::Clone() const
+{
+  return new DomainDefinedAttribute;
+}
+
+AsnType *DomainDefinedAttribute::Copy() const
+{
+  return new DomainDefinedAttribute (*this);
+}
+
+#if SNACC_DEEP_COPY
+DomainDefinedAttribute &DomainDefinedAttribute::operator = (const DomainDefinedAttribute &that)
+#else // SNACC_DEEP_COPY
+DomainDefinedAttribute &DomainDefinedAttribute::operator = (const DomainDefinedAttribute &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    type = that.type;
+    value = that.value;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DomainDefinedAttribute &DomainDefinedAttribute::operator = (const DomainDefinedAttribute &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DomainDefinedAttribute::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = value.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+    totalLen += l;
+
+    l = type.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // DomainDefinedAttribute::BEncContent
+
+
+void DomainDefinedAttribute::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    type.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -108);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    value.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -109);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -110);
+  }
+  else
+    return;
+} // DomainDefinedAttribute::BDecContent
+
+AsnLen DomainDefinedAttribute::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DomainDefinedAttribute::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DomainDefinedAttribute::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -111);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DomainDefinedAttribute::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DomainDefinedAttribute::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DomainDefinedAttribute::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "type ";
+    os << type;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "value ";
+    os << value;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DomainDefinedAttribute::Print
+
+
+ExtensionAttribute::ExtensionAttribute()
+{
+}
+
+ExtensionAttribute::ExtensionAttribute (const ExtensionAttribute &)
+{
+  Asn1Error << "use of incompletely defined ExtensionAttribute::ExtensionAttribute (const ExtensionAttribute &)" << endl;
+  abort();
+}
+
+ExtensionAttribute::~ExtensionAttribute()
+{
+}
+
+AsnType *ExtensionAttribute::Clone() const
+{
+  return new ExtensionAttribute;
+}
+
+AsnType *ExtensionAttribute::Copy() const
+{
+  return new ExtensionAttribute (*this);
+}
+
+#if SNACC_DEEP_COPY
+ExtensionAttribute &ExtensionAttribute::operator = (const ExtensionAttribute &that)
+#else // SNACC_DEEP_COPY
+ExtensionAttribute &ExtensionAttribute::operator = (const ExtensionAttribute &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    extension_attribute_type = that.extension_attribute_type;
+    extension_attribute_value = that.extension_attribute_value;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ExtensionAttribute &ExtensionAttribute::operator = (const ExtensionAttribute &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ExtensionAttribute::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+        ENC_LOAD_ANYBUF(&extension_attribute_value, b, l);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+
+    l = extension_attribute_type.BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+
+  return totalLen;
+} // ExtensionAttribute::BEncContent
+
+
+void ExtensionAttribute::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    extension_attribute_type.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -112);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+        DEC_LOAD_ANYBUF(&extension_attribute_value, b, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -113);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -114);
+  }
+  else
+    return;
+} // ExtensionAttribute::BDecContent
+
+AsnLen ExtensionAttribute::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ExtensionAttribute::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ExtensionAttribute::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -115);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ExtensionAttribute::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ExtensionAttribute::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ExtensionAttribute::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "extension-attribute-type ";
+    os << extension_attribute_type;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "extension-attribute-value ";
+    os << extension_attribute_value;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ExtensionAttribute::Print
+
+
+TeletexDomainDefinedAttribute::TeletexDomainDefinedAttribute()
+{
+}
+
+TeletexDomainDefinedAttribute::TeletexDomainDefinedAttribute (const TeletexDomainDefinedAttribute &)
+{
+  Asn1Error << "use of incompletely defined TeletexDomainDefinedAttribute::TeletexDomainDefinedAttribute (const TeletexDomainDefinedAttribute &)" << endl;
+  abort();
+}
+
+TeletexDomainDefinedAttribute::~TeletexDomainDefinedAttribute()
+{
+}
+
+AsnType *TeletexDomainDefinedAttribute::Clone() const
+{
+  return new TeletexDomainDefinedAttribute;
+}
+
+AsnType *TeletexDomainDefinedAttribute::Copy() const
+{
+  return new TeletexDomainDefinedAttribute (*this);
+}
+
+#if SNACC_DEEP_COPY
+TeletexDomainDefinedAttribute &TeletexDomainDefinedAttribute::operator = (const TeletexDomainDefinedAttribute &that)
+#else // SNACC_DEEP_COPY
+TeletexDomainDefinedAttribute &TeletexDomainDefinedAttribute::operator = (const TeletexDomainDefinedAttribute &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    type = that.type;
+    value = that.value;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined TeletexDomainDefinedAttribute &TeletexDomainDefinedAttribute::operator = (const TeletexDomainDefinedAttribute &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+TeletexDomainDefinedAttribute::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = value.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    totalLen += l;
+
+    l = type.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // TeletexDomainDefinedAttribute::BEncContent
+
+
+void TeletexDomainDefinedAttribute::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    type.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -116);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    value.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -117);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -118);
+  }
+  else
+    return;
+} // TeletexDomainDefinedAttribute::BDecContent
+
+AsnLen TeletexDomainDefinedAttribute::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void TeletexDomainDefinedAttribute::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "TeletexDomainDefinedAttribute::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -119);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int TeletexDomainDefinedAttribute::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int TeletexDomainDefinedAttribute::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void TeletexDomainDefinedAttribute::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "type ";
+    os << type;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "value ";
+    os << value;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // TeletexDomainDefinedAttribute::Print
+
+
+AsnType *OrganizationUnitNames::Clone() const
+{
+  return new OrganizationUnitNames;
+}
+
+AsnType *OrganizationUnitNames::Copy() const
+{
+  return new OrganizationUnitNames (*this);
+}
+
+AsnLen OrganizationUnitNames::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void OrganizationUnitNames::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "OrganizationUnitNames::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -120);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+OrganizationUnitNames::OrganizationUnitNames (const OrganizationUnitNames &)
+{
+  Asn1Error << "use of incompletely defined OrganizationUnitNames::OrganizationUnitNames (const OrganizationUnitNames &)" << endl;
+  abort();
+}
+
+OrganizationUnitNames::~OrganizationUnitNames()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+OrganizationUnitNames &OrganizationUnitNames::operator = (const OrganizationUnitNames &that)
+#else // SNACC_DEEP_COPY
+OrganizationUnitNames &OrganizationUnitNames::operator = (const OrganizationUnitNames &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined OrganizationUnitNames &OrganizationUnitNames::operator = (const OrganizationUnitNames &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void OrganizationUnitNames::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  OrganizationUnitNames::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // OrganizationUnitNames::SetCurrElmt
+
+
+unsigned long int  OrganizationUnitNames::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // OrganizationUnitNames::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+OrganizationUnitName *OrganizationUnitNames::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new OrganizationUnitName;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // OrganizationUnitNames::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+OrganizationUnitName  *OrganizationUnitNames::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new OrganizationUnitName;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // OrganizationUnitNames::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+OrganizationUnitName  *OrganizationUnitNames::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new OrganizationUnitName;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // OrganizationUnitNames::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+OrganizationUnitName *OrganizationUnitNames::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new OrganizationUnitName;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // OrganizationUnitNames::InsertAfter
+
+
+OrganizationUnitNames  &OrganizationUnitNames::AppendCopy (OrganizationUnitName &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new OrganizationUnitName;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+OrganizationUnitNames  &OrganizationUnitNames::PrependCopy (OrganizationUnitName &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new OrganizationUnitName;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // OrganizationUnitNames::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+OrganizationUnitNames &OrganizationUnitNames::InsertBeforeAndCopy (OrganizationUnitName &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new OrganizationUnitName;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // OrganizationUnitNames::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+OrganizationUnitNames  &OrganizationUnitNames::InsertAfterAndCopy (OrganizationUnitName &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new OrganizationUnitName;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // OrganizationUnitNames::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void OrganizationUnitNames::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen OrganizationUnitNames::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncDefLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // OrganizationUnitNames::BEncContent
+
+
+void  OrganizationUnitNames::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    OrganizationUnitName *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE))
+         && (tag1 != MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -121);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // OrganizationUnitNames::BDecContent
+
+
+AsnType *DomainDefinedAttributes::Clone() const
+{
+  return new DomainDefinedAttributes;
+}
+
+AsnType *DomainDefinedAttributes::Copy() const
+{
+  return new DomainDefinedAttributes (*this);
+}
+
+AsnLen DomainDefinedAttributes::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DomainDefinedAttributes::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DomainDefinedAttributes::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -122);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+DomainDefinedAttributes::DomainDefinedAttributes (const DomainDefinedAttributes &)
+{
+  Asn1Error << "use of incompletely defined DomainDefinedAttributes::DomainDefinedAttributes (const DomainDefinedAttributes &)" << endl;
+  abort();
+}
+
+DomainDefinedAttributes::~DomainDefinedAttributes()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+DomainDefinedAttributes &DomainDefinedAttributes::operator = (const DomainDefinedAttributes &that)
+#else // SNACC_DEEP_COPY
+DomainDefinedAttributes &DomainDefinedAttributes::operator = (const DomainDefinedAttributes &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DomainDefinedAttributes &DomainDefinedAttributes::operator = (const DomainDefinedAttributes &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void DomainDefinedAttributes::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  DomainDefinedAttributes::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // DomainDefinedAttributes::SetCurrElmt
+
+
+unsigned long int  DomainDefinedAttributes::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // DomainDefinedAttributes::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+DomainDefinedAttribute *DomainDefinedAttributes::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new DomainDefinedAttribute;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // DomainDefinedAttributes::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+DomainDefinedAttribute  *DomainDefinedAttributes::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DomainDefinedAttribute;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // DomainDefinedAttributes::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+DomainDefinedAttribute  *DomainDefinedAttributes::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DomainDefinedAttribute;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // DomainDefinedAttributes::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+DomainDefinedAttribute *DomainDefinedAttributes::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DomainDefinedAttribute;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // DomainDefinedAttributes::InsertAfter
+
+
+DomainDefinedAttributes  &DomainDefinedAttributes::AppendCopy (DomainDefinedAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DomainDefinedAttribute;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+DomainDefinedAttributes  &DomainDefinedAttributes::PrependCopy (DomainDefinedAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DomainDefinedAttribute;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // DomainDefinedAttributes::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+DomainDefinedAttributes &DomainDefinedAttributes::InsertBeforeAndCopy (DomainDefinedAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DomainDefinedAttribute;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // DomainDefinedAttributes::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+DomainDefinedAttributes  &DomainDefinedAttributes::InsertAfterAndCopy (DomainDefinedAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DomainDefinedAttribute;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // DomainDefinedAttributes::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void DomainDefinedAttributes::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen DomainDefinedAttributes::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // DomainDefinedAttributes::BEncContent
+
+
+void  DomainDefinedAttributes::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    DomainDefinedAttribute *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -123);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // DomainDefinedAttributes::BDecContent
+
+
+AsnType *ExtensionAttributes::Clone() const
+{
+  return new ExtensionAttributes;
+}
+
+AsnType *ExtensionAttributes::Copy() const
+{
+  return new ExtensionAttributes (*this);
+}
+
+AsnLen ExtensionAttributes::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void ExtensionAttributes::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "ExtensionAttributes::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -124);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+ExtensionAttributes::ExtensionAttributes (const ExtensionAttributes &)
+{
+  Asn1Error << "use of incompletely defined ExtensionAttributes::ExtensionAttributes (const ExtensionAttributes &)" << endl;
+  abort();
+}
+
+ExtensionAttributes::~ExtensionAttributes()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+ExtensionAttributes &ExtensionAttributes::operator = (const ExtensionAttributes &that)
+#else // SNACC_DEEP_COPY
+ExtensionAttributes &ExtensionAttributes::operator = (const ExtensionAttributes &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ExtensionAttributes &ExtensionAttributes::operator = (const ExtensionAttributes &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void ExtensionAttributes::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  ExtensionAttributes::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // ExtensionAttributes::SetCurrElmt
+
+
+unsigned long int  ExtensionAttributes::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // ExtensionAttributes::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+ExtensionAttribute *ExtensionAttributes::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new ExtensionAttribute;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ExtensionAttributes::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+ExtensionAttribute  *ExtensionAttributes::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ExtensionAttribute;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ExtensionAttributes::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ExtensionAttribute  *ExtensionAttributes::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ExtensionAttribute;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ExtensionAttributes::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ExtensionAttribute *ExtensionAttributes::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ExtensionAttribute;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ExtensionAttributes::InsertAfter
+
+
+ExtensionAttributes  &ExtensionAttributes::AppendCopy (ExtensionAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ExtensionAttribute;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+ExtensionAttributes  &ExtensionAttributes::PrependCopy (ExtensionAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ExtensionAttribute;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // ExtensionAttributes::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ExtensionAttributes &ExtensionAttributes::InsertBeforeAndCopy (ExtensionAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ExtensionAttribute;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // ExtensionAttributes::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ExtensionAttributes  &ExtensionAttributes::InsertAfterAndCopy (ExtensionAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ExtensionAttribute;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // ExtensionAttributes::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void ExtensionAttributes::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen ExtensionAttributes::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // ExtensionAttributes::BEncContent
+
+
+void  ExtensionAttributes::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    ExtensionAttribute *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -125);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // ExtensionAttributes::BDecContent
+
+
+StandardAttributes::StandardAttributes()
+{
+  country_name = NULL;
+  administration_domain_name = NULL;
+  network_address = NULL;
+  terminal_identifier = NULL;
+  private_domain_name = NULL;
+  organization_name = NULL;
+  numeric_user_identifier = NULL;
+  personal_name = NULL;
+  organizational_unit_names = NULL;
+}
+
+StandardAttributes::StandardAttributes (const StandardAttributes &)
+{
+  Asn1Error << "use of incompletely defined StandardAttributes::StandardAttributes (const StandardAttributes &)" << endl;
+  abort();
+}
+
+StandardAttributes::~StandardAttributes()
+{
+  delete country_name;
+  delete administration_domain_name;
+  delete network_address;
+  delete terminal_identifier;
+  delete private_domain_name;
+  delete organization_name;
+  delete numeric_user_identifier;
+  delete personal_name;
+  delete organizational_unit_names;
+}
+
+AsnType *StandardAttributes::Clone() const
+{
+  return new StandardAttributes;
+}
+
+AsnType *StandardAttributes::Copy() const
+{
+  return new StandardAttributes (*this);
+}
+
+#if SNACC_DEEP_COPY
+StandardAttributes &StandardAttributes::operator = (const StandardAttributes &that)
+#else // SNACC_DEEP_COPY
+StandardAttributes &StandardAttributes::operator = (const StandardAttributes &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.country_name)
+    {
+      if (!country_name)
+        country_name = new CountryName;
+      *country_name = *that.country_name;
+    }
+    else
+    {
+      delete country_name;
+      country_name = NULL;
+    }
+    if (that.administration_domain_name)
+    {
+      if (!administration_domain_name)
+        administration_domain_name = new AdministrationDomainName;
+      *administration_domain_name = *that.administration_domain_name;
+    }
+    else
+    {
+      delete administration_domain_name;
+      administration_domain_name = NULL;
+    }
+    if (that.network_address)
+    {
+      if (!network_address)
+        network_address = new NetworkAddress;
+      *network_address = *that.network_address;
+    }
+    else
+    {
+      delete network_address;
+      network_address = NULL;
+    }
+    if (that.terminal_identifier)
+    {
+      if (!terminal_identifier)
+        terminal_identifier = new TerminalIdentifier;
+      *terminal_identifier = *that.terminal_identifier;
+    }
+    else
+    {
+      delete terminal_identifier;
+      terminal_identifier = NULL;
+    }
+    if (that.private_domain_name)
+    {
+      if (!private_domain_name)
+        private_domain_name = new PrivateDomainName;
+      *private_domain_name = *that.private_domain_name;
+    }
+    else
+    {
+      delete private_domain_name;
+      private_domain_name = NULL;
+    }
+    if (that.organization_name)
+    {
+      if (!organization_name)
+        organization_name = new OrganizationName;
+      *organization_name = *that.organization_name;
+    }
+    else
+    {
+      delete organization_name;
+      organization_name = NULL;
+    }
+    if (that.numeric_user_identifier)
+    {
+      if (!numeric_user_identifier)
+        numeric_user_identifier = new NumericUserIdentifier;
+      *numeric_user_identifier = *that.numeric_user_identifier;
+    }
+    else
+    {
+      delete numeric_user_identifier;
+      numeric_user_identifier = NULL;
+    }
+    if (that.personal_name)
+    {
+      if (!personal_name)
+        personal_name = new PersonalName;
+      *personal_name = *that.personal_name;
+    }
+    else
+    {
+      delete personal_name;
+      personal_name = NULL;
+    }
+    if (that.organizational_unit_names)
+    {
+      if (!organizational_unit_names)
+        organizational_unit_names = new OrganizationUnitNames;
+      *organizational_unit_names = *that.organizational_unit_names;
+    }
+    else
+    {
+      delete organizational_unit_names;
+      organizational_unit_names = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined StandardAttributes &StandardAttributes::operator = (const StandardAttributes &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+StandardAttributes::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (organizational_unit_names))
+  {
+      BEncEocIfNec (b);
+    l = organizational_unit_names->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 6);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (personal_name))
+  {
+      BEncEocIfNec (b);
+    l = personal_name->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 5);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (numeric_user_identifier))
+  {
+    l = numeric_user_identifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 4);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (organization_name))
+  {
+    l = organization_name->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 3);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (private_domain_name))
+  {
+      BEncEocIfNec (b);
+    l = private_domain_name->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 2);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (terminal_identifier))
+  {
+    l = terminal_identifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (network_address))
+  {
+    l = network_address->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (administration_domain_name))
+  {
+      BEncEocIfNec (b);
+    l = administration_domain_name->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, APPL, CONS, 2);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (country_name))
+  {
+      BEncEocIfNec (b);
+    l = country_name->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, APPL, CONS, 1);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // StandardAttributes::BEncContent
+
+
+void StandardAttributes::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (APPL, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    country_name = new CountryName;
+    country_name->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (APPL, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    administration_domain_name = new AdministrationDomainName;
+    administration_domain_name->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    network_address = new NetworkAddress;
+    network_address->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    terminal_identifier = new TerminalIdentifier;
+    terminal_identifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    private_domain_name = new PrivateDomainName;
+    private_domain_name->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 3))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 3)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    organization_name = new OrganizationName;
+    organization_name->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 4))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 4)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    numeric_user_identifier = new NumericUserIdentifier;
+    numeric_user_identifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 5)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    personal_name = new PersonalName;
+    personal_name->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 6)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    organizational_unit_names = new OrganizationUnitNames;
+    organizational_unit_names->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -126);
+  }
+  else
+    return;
+} // StandardAttributes::BDecContent
+
+AsnLen StandardAttributes::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void StandardAttributes::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "StandardAttributes::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -127);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int StandardAttributes::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int StandardAttributes::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void StandardAttributes::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (country_name))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "country-name ";
+    os << *country_name;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "country-name ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (administration_domain_name))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "administration-domain-name ";
+    os << *administration_domain_name;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "administration-domain-name ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (network_address))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "network-address ";
+    os << *network_address;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "network-address ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (terminal_identifier))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "terminal-identifier ";
+    os << *terminal_identifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "terminal-identifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (private_domain_name))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "private-domain-name ";
+    os << *private_domain_name;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "private-domain-name ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (organization_name))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "organization-name ";
+    os << *organization_name;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "organization-name ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (numeric_user_identifier))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "numeric-user-identifier ";
+    os << *numeric_user_identifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "numeric-user-identifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (personal_name))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "personal-name ";
+    os << *personal_name;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "personal-name ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (organizational_unit_names))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "organizational-unit-names ";
+    os << *organizational_unit_names;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "organizational-unit-names ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // StandardAttributes::Print
+
+
+ORAddress::ORAddress()
+{
+#if TCL
+  standard_attributes = new StandardAttributes;
+#else
+  standard_attributes = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  domain_defined_attributes = NULL;
+  extension_attributes = NULL;
+}
+
+ORAddress::ORAddress (const ORAddress &)
+{
+  Asn1Error << "use of incompletely defined ORAddress::ORAddress (const ORAddress &)" << endl;
+  abort();
+}
+
+ORAddress::~ORAddress()
+{
+  delete standard_attributes;
+  delete domain_defined_attributes;
+  delete extension_attributes;
+}
+
+AsnType *ORAddress::Clone() const
+{
+  return new ORAddress;
+}
+
+AsnType *ORAddress::Copy() const
+{
+  return new ORAddress (*this);
+}
+
+#if SNACC_DEEP_COPY
+ORAddress &ORAddress::operator = (const ORAddress &that)
+#else // SNACC_DEEP_COPY
+ORAddress &ORAddress::operator = (const ORAddress &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.standard_attributes)
+    {
+      if (!standard_attributes)
+        standard_attributes = new StandardAttributes;
+      *standard_attributes = *that.standard_attributes;
+    }
+    else
+    {
+      delete standard_attributes;
+      standard_attributes = NULL;
+    }
+    if (that.domain_defined_attributes)
+    {
+      if (!domain_defined_attributes)
+        domain_defined_attributes = new DomainDefinedAttributes;
+      *domain_defined_attributes = *that.domain_defined_attributes;
+    }
+    else
+    {
+      delete domain_defined_attributes;
+      domain_defined_attributes = NULL;
+    }
+    if (that.extension_attributes)
+    {
+      if (!extension_attributes)
+        extension_attributes = new ExtensionAttributes;
+      *extension_attributes = *that.extension_attributes;
+    }
+    else
+    {
+      delete extension_attributes;
+      extension_attributes = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ORAddress &ORAddress::operator = (const ORAddress &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ORAddress::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (extension_attributes))
+  {
+      BEncEocIfNec (b);
+    l = extension_attributes->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (domain_defined_attributes))
+  {
+      BEncEocIfNec (b);
+    l = domain_defined_attributes->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = standard_attributes->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // ORAddress::BEncContent
+
+
+void ORAddress::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    standard_attributes = new StandardAttributes;
+    standard_attributes->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -128);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    domain_defined_attributes = new DomainDefinedAttributes;
+    domain_defined_attributes->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    extension_attributes = new ExtensionAttributes;
+    extension_attributes->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -129);
+  }
+  else
+    return;
+} // ORAddress::BDecContent
+
+AsnLen ORAddress::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ORAddress::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ORAddress::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -130);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ORAddress::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ORAddress::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ORAddress::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (standard_attributes))
+  {
+    Indent (os, indentG);
+    os << "standard-attributes ";
+    os << *standard_attributes;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "standard-attributes ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (domain_defined_attributes))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "domain-defined-attributes ";
+    os << *domain_defined_attributes;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "domain-defined-attributes ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (extension_attributes))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "extension-attributes ";
+    os << *extension_attributes;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "extension-attributes ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ORAddress::Print
+
+
+TeletexPersonalName::TeletexPersonalName()
+{
+  given_name = NULL;
+  initials = NULL;
+  generation_qualifier = NULL;
+}
+
+TeletexPersonalName::TeletexPersonalName (const TeletexPersonalName &)
+{
+  Asn1Error << "use of incompletely defined TeletexPersonalName::TeletexPersonalName (const TeletexPersonalName &)" << endl;
+  abort();
+}
+
+TeletexPersonalName::~TeletexPersonalName()
+{
+  delete given_name;
+  delete initials;
+  delete generation_qualifier;
+}
+
+AsnType *TeletexPersonalName::Clone() const
+{
+  return new TeletexPersonalName;
+}
+
+AsnType *TeletexPersonalName::Copy() const
+{
+  return new TeletexPersonalName (*this);
+}
+
+#if SNACC_DEEP_COPY
+TeletexPersonalName &TeletexPersonalName::operator = (const TeletexPersonalName &that)
+#else // SNACC_DEEP_COPY
+TeletexPersonalName &TeletexPersonalName::operator = (const TeletexPersonalName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    surname = that.surname;
+    if (that.given_name)
+    {
+      if (!given_name)
+        given_name = new TeletexString;
+      *given_name = *that.given_name;
+    }
+    else
+    {
+      delete given_name;
+      given_name = NULL;
+    }
+    if (that.initials)
+    {
+      if (!initials)
+        initials = new TeletexString;
+      *initials = *that.initials;
+    }
+    else
+    {
+      delete initials;
+      initials = NULL;
+    }
+    if (that.generation_qualifier)
+    {
+      if (!generation_qualifier)
+        generation_qualifier = new TeletexString;
+      *generation_qualifier = *that.generation_qualifier;
+    }
+    else
+    {
+      delete generation_qualifier;
+      generation_qualifier = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined TeletexPersonalName &TeletexPersonalName::operator = (const TeletexPersonalName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen TeletexPersonalName::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      AsnBuf outputBuf;
+       int iii=0, tmpCount=0;
+      char *lpszBuf = (char *)calloc(1, 1024);
+      outputBuf.Init(lpszBuf, 1024);
+      outputBuf.ResetInWriteRvsMode();
+      CSM_Buffer *tmpEnc[4];
+  if (NOT_NULL (generation_qualifier))
+  {
+    l = generation_qualifier->BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, CNTX, PRIM, 3);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+  if (NOT_NULL (initials))
+  {
+    l = initials->BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, CNTX, PRIM, 2);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+  if (NOT_NULL (given_name))
+  {
+    l = given_name->BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, CNTX, PRIM, 1);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+  }
+
+    l = surname.BEncContent (outputBuf);
+    l += BEncDefLen (outputBuf, l);
+
+    l += BEncTag1 (outputBuf, CNTX, PRIM, 0);
+    totalLen += l;
+        SNACC_BUFRESET_READ(&outputBuf);
+        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);
+        SNACC_BUFRESET_WRITE(&outputBuf);
+        iii++;
+
+      vdasnacc_sortSet(tmpEnc, iii);
+      tmpCount = iii;  /** REMEMBER how many we have**/
+      for (iii=0; iii < tmpCount; iii++)
+         SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < tmpCount; iii++) delete tmpEnc[iii];
+      free(lpszBuf);
+  return totalLen;
+} // TeletexPersonalName::BEncContent
+
+
+void TeletexPersonalName::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen setBytesDecoded = 0;
+  unsigned int mandatoryElmtsDecoded = 0;
+  AsnLen elmtLen1;
+
+  for (; (setBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )
+  {
+    tag1 = BDecTag (b, setBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, setBytesDecoded, env)
+      break; /* exit for loop */
+    }
+    elmtLen1 = BDecLen (b, setBytesDecoded, env);
+    switch (tag1)
+    {
+      case MAKE_TAG_ID (CNTX, PRIM, 0):
+      case MAKE_TAG_ID (CNTX, CONS, 0):
+        surname.BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          mandatoryElmtsDecoded++;
+          break;
+
+      case MAKE_TAG_ID (CNTX, PRIM, 1):
+      case MAKE_TAG_ID (CNTX, CONS, 1):
+        given_name = new TeletexString;
+        given_name->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+      case MAKE_TAG_ID (CNTX, PRIM, 2):
+      case MAKE_TAG_ID (CNTX, CONS, 2):
+        initials = new TeletexString;
+        initials->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+      case MAKE_TAG_ID (CNTX, PRIM, 3):
+      case MAKE_TAG_ID (CNTX, CONS, 3):
+        generation_qualifier = new TeletexString;
+        generation_qualifier->BDecContent (b, tag1, elmtLen1, setBytesDecoded, env);
+          break;
+
+       default:
+         Asn1Error << "Unexpected Tag on SET elmt." << endl;
+         longjmp (env, -131);
+    } // end switch
+  } // end for loop
+  bytesDecoded += setBytesDecoded;
+  if (mandatoryElmtsDecoded != 1)
+  {
+     Asn1Error << "ERROR - non-optional SET element missing." << endl;
+     longjmp (env, -132);
+  }
+} // TeletexPersonalName::BDecContent
+
+AsnLen
+TeletexPersonalName::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void TeletexPersonalName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "TeletexPersonalName::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -133);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int TeletexPersonalName::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int TeletexPersonalName::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void TeletexPersonalName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SET --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "surname ";
+    os << surname;
+  }
+
+  if (NOT_NULL (given_name))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "given-name ";
+    os << *given_name;
+  }
+  else
+    os << "-- void2 --\n";
+
+  if (NOT_NULL (initials))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "initials ";
+    os << *initials;
+  }
+  else
+    os << "-- void2 --\n";
+
+  if (NOT_NULL (generation_qualifier))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "generation-qualifier ";
+    os << *generation_qualifier;
+  }
+  else
+    os << "-- void2 --\n";
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // TeletexPersonalName - operator <<
+
+
+AsnType *TeletexOrganizationUnitNames::Clone() const
+{
+  return new TeletexOrganizationUnitNames;
+}
+
+AsnType *TeletexOrganizationUnitNames::Copy() const
+{
+  return new TeletexOrganizationUnitNames (*this);
+}
+
+AsnLen TeletexOrganizationUnitNames::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void TeletexOrganizationUnitNames::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "TeletexOrganizationUnitNames::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -134);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+TeletexOrganizationUnitNames::TeletexOrganizationUnitNames (const TeletexOrganizationUnitNames &)
+{
+  Asn1Error << "use of incompletely defined TeletexOrganizationUnitNames::TeletexOrganizationUnitNames (const TeletexOrganizationUnitNames &)" << endl;
+  abort();
+}
+
+TeletexOrganizationUnitNames::~TeletexOrganizationUnitNames()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+TeletexOrganizationUnitNames &TeletexOrganizationUnitNames::operator = (const TeletexOrganizationUnitNames &that)
+#else // SNACC_DEEP_COPY
+TeletexOrganizationUnitNames &TeletexOrganizationUnitNames::operator = (const TeletexOrganizationUnitNames &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined TeletexOrganizationUnitNames &TeletexOrganizationUnitNames::operator = (const TeletexOrganizationUnitNames &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void TeletexOrganizationUnitNames::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  TeletexOrganizationUnitNames::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // TeletexOrganizationUnitNames::SetCurrElmt
+
+
+unsigned long int  TeletexOrganizationUnitNames::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // TeletexOrganizationUnitNames::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+TeletexOrganizationalUnitName *TeletexOrganizationUnitNames::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new TeletexOrganizationalUnitName;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // TeletexOrganizationUnitNames::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+TeletexOrganizationalUnitName  *TeletexOrganizationUnitNames::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexOrganizationalUnitName;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // TeletexOrganizationUnitNames::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+TeletexOrganizationalUnitName  *TeletexOrganizationUnitNames::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexOrganizationalUnitName;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // TeletexOrganizationUnitNames::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+TeletexOrganizationalUnitName *TeletexOrganizationUnitNames::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexOrganizationalUnitName;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // TeletexOrganizationUnitNames::InsertAfter
+
+
+TeletexOrganizationUnitNames  &TeletexOrganizationUnitNames::AppendCopy (TeletexOrganizationalUnitName &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexOrganizationalUnitName;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+TeletexOrganizationUnitNames  &TeletexOrganizationUnitNames::PrependCopy (TeletexOrganizationalUnitName &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexOrganizationalUnitName;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // TeletexOrganizationUnitNames::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+TeletexOrganizationUnitNames &TeletexOrganizationUnitNames::InsertBeforeAndCopy (TeletexOrganizationalUnitName &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexOrganizationalUnitName;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // TeletexOrganizationUnitNames::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+TeletexOrganizationUnitNames  &TeletexOrganizationUnitNames::InsertAfterAndCopy (TeletexOrganizationalUnitName &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexOrganizationalUnitName;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // TeletexOrganizationUnitNames::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void TeletexOrganizationUnitNames::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen TeletexOrganizationUnitNames::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncDefLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // TeletexOrganizationUnitNames::BEncContent
+
+
+void  TeletexOrganizationUnitNames::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    TeletexOrganizationalUnitName *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))
+         && (tag1 != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -135);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // TeletexOrganizationUnitNames::BDecContent
+
+
+AsnType *TeletexDomainDefinedAttributes::Clone() const
+{
+  return new TeletexDomainDefinedAttributes;
+}
+
+AsnType *TeletexDomainDefinedAttributes::Copy() const
+{
+  return new TeletexDomainDefinedAttributes (*this);
+}
+
+AsnLen TeletexDomainDefinedAttributes::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void TeletexDomainDefinedAttributes::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "TeletexDomainDefinedAttributes::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -136);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+TeletexDomainDefinedAttributes::TeletexDomainDefinedAttributes (const TeletexDomainDefinedAttributes &)
+{
+  Asn1Error << "use of incompletely defined TeletexDomainDefinedAttributes::TeletexDomainDefinedAttributes (const TeletexDomainDefinedAttributes &)" << endl;
+  abort();
+}
+
+TeletexDomainDefinedAttributes::~TeletexDomainDefinedAttributes()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+TeletexDomainDefinedAttributes &TeletexDomainDefinedAttributes::operator = (const TeletexDomainDefinedAttributes &that)
+#else // SNACC_DEEP_COPY
+TeletexDomainDefinedAttributes &TeletexDomainDefinedAttributes::operator = (const TeletexDomainDefinedAttributes &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined TeletexDomainDefinedAttributes &TeletexDomainDefinedAttributes::operator = (const TeletexDomainDefinedAttributes &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void TeletexDomainDefinedAttributes::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  TeletexDomainDefinedAttributes::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // TeletexDomainDefinedAttributes::SetCurrElmt
+
+
+unsigned long int  TeletexDomainDefinedAttributes::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // TeletexDomainDefinedAttributes::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+TeletexDomainDefinedAttribute *TeletexDomainDefinedAttributes::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new TeletexDomainDefinedAttribute;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // TeletexDomainDefinedAttributes::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+TeletexDomainDefinedAttribute  *TeletexDomainDefinedAttributes::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexDomainDefinedAttribute;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // TeletexDomainDefinedAttributes::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+TeletexDomainDefinedAttribute  *TeletexDomainDefinedAttributes::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexDomainDefinedAttribute;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // TeletexDomainDefinedAttributes::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+TeletexDomainDefinedAttribute *TeletexDomainDefinedAttributes::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexDomainDefinedAttribute;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // TeletexDomainDefinedAttributes::InsertAfter
+
+
+TeletexDomainDefinedAttributes  &TeletexDomainDefinedAttributes::AppendCopy (TeletexDomainDefinedAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexDomainDefinedAttribute;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+TeletexDomainDefinedAttributes  &TeletexDomainDefinedAttributes::PrependCopy (TeletexDomainDefinedAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexDomainDefinedAttribute;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // TeletexDomainDefinedAttributes::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+TeletexDomainDefinedAttributes &TeletexDomainDefinedAttributes::InsertBeforeAndCopy (TeletexDomainDefinedAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexDomainDefinedAttribute;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // TeletexDomainDefinedAttributes::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+TeletexDomainDefinedAttributes  &TeletexDomainDefinedAttributes::InsertAfterAndCopy (TeletexDomainDefinedAttribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new TeletexDomainDefinedAttribute;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // TeletexDomainDefinedAttributes::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void TeletexDomainDefinedAttributes::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen TeletexDomainDefinedAttributes::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // TeletexDomainDefinedAttributes::BEncContent
+
+
+void  TeletexDomainDefinedAttributes::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    TeletexDomainDefinedAttribute *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -137);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // TeletexDomainDefinedAttributes::BDecContent
+
+
diff --git a/SecurityASN1/c++/sm_x411ub.cpp b/SecurityASN1/c++/sm_x411ub.cpp
new file mode 100644
index 00000000..c9be1559
--- /dev/null
+++ b/SecurityASN1/c++/sm_x411ub.cpp
@@ -0,0 +1,34 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x411ub.cpp - class member functions for ASN.1 module UpperBounds
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
diff --git a/SecurityASN1/c++/sm_x501if.cpp b/SecurityASN1/c++/sm_x501if.cpp
new file mode 100644
index 00000000..0211d218
--- /dev/null
+++ b/SecurityASN1/c++/sm_x501if.cpp
@@ -0,0 +1,3553 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x501if.cpp - class member functions for ASN.1 module InformationFramework
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+AsnType *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Clone() const
+{
+  return new AttributeTypeAndDistinguishedValueSetOfSeqSetOf;
+}
+
+AsnType *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Copy() const
+{
+  return new AttributeTypeAndDistinguishedValueSetOfSeqSetOf (*this);
+}
+
+AsnLen AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -100);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+AttributeTypeAndDistinguishedValueSetOfSeqSetOf::AttributeTypeAndDistinguishedValueSetOfSeqSetOf (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &)
+{
+  Asn1Error << "use of incompletely defined AttributeTypeAndDistinguishedValueSetOfSeqSetOf::AttributeTypeAndDistinguishedValueSetOfSeqSetOf (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &)" << endl;
+  abort();
+}
+
+AttributeTypeAndDistinguishedValueSetOfSeqSetOf::~AttributeTypeAndDistinguishedValueSetOfSeqSetOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+AttributeTypeAndDistinguishedValueSetOfSeqSetOf &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &that)
+#else // SNACC_DEEP_COPY
+AttributeTypeAndDistinguishedValueSetOfSeqSetOf &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeTypeAndDistinguishedValueSetOfSeqSetOf &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  AttributeTypeAndDistinguishedValueSetOfSeqSetOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::SetCurrElmt
+
+
+unsigned long int  AttributeTypeAndDistinguishedValueSetOfSeqSetOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+AsnAny *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new AsnAny;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+AsnAny  *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AsnAny;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AsnAny  *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AsnAny;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AsnAny *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AsnAny;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertAfter
+
+
+AttributeTypeAndDistinguishedValueSetOfSeqSetOf  &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::AppendCopy (AsnAny &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AsnAny;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+AttributeTypeAndDistinguishedValueSetOfSeqSetOf  &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::PrependCopy (AsnAny &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AsnAny;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeTypeAndDistinguishedValueSetOfSeqSetOf &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertBeforeAndCopy (AsnAny &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AsnAny;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeTypeAndDistinguishedValueSetOfSeqSetOf  &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertAfterAndCopy (AsnAny &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AsnAny;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void AttributeTypeAndDistinguishedValueSetOfSeqSetOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+        tmpEnc[iii] = (CSM_Buffer *)currElmt->elmt->value;
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BEncContent
+
+
+void  AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnAny *listElmt;
+    AsnLen listBytesDecoded = 0;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        listElmt = Append();
+        DEC_LOAD_ANYBUF(listElmt, b, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BDecContent
+
+
+AttributeTypeAndDistinguishedValueSetOfSeq::AttributeTypeAndDistinguishedValueSetOfSeq()
+{
+  distingAttrValue = NULL;
+}
+
+AttributeTypeAndDistinguishedValueSetOfSeq::AttributeTypeAndDistinguishedValueSetOfSeq (const AttributeTypeAndDistinguishedValueSetOfSeq &)
+{
+  Asn1Error << "use of incompletely defined AttributeTypeAndDistinguishedValueSetOfSeq::AttributeTypeAndDistinguishedValueSetOfSeq (const AttributeTypeAndDistinguishedValueSetOfSeq &)" << endl;
+  abort();
+}
+
+AttributeTypeAndDistinguishedValueSetOfSeq::~AttributeTypeAndDistinguishedValueSetOfSeq()
+{
+  delete distingAttrValue;
+}
+
+AsnType *AttributeTypeAndDistinguishedValueSetOfSeq::Clone() const
+{
+  return new AttributeTypeAndDistinguishedValueSetOfSeq;
+}
+
+AsnType *AttributeTypeAndDistinguishedValueSetOfSeq::Copy() const
+{
+  return new AttributeTypeAndDistinguishedValueSetOfSeq (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttributeTypeAndDistinguishedValueSetOfSeq &AttributeTypeAndDistinguishedValueSetOfSeq::operator = (const AttributeTypeAndDistinguishedValueSetOfSeq &that)
+#else // SNACC_DEEP_COPY
+AttributeTypeAndDistinguishedValueSetOfSeq &AttributeTypeAndDistinguishedValueSetOfSeq::operator = (const AttributeTypeAndDistinguishedValueSetOfSeq &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.distingAttrValue)
+    {
+      if (!distingAttrValue)
+        distingAttrValue = new AsnOid;
+      *distingAttrValue = *that.distingAttrValue;
+    }
+    else
+    {
+      delete distingAttrValue;
+      distingAttrValue = NULL;
+    }
+    contextList = that.contextList;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeTypeAndDistinguishedValueSetOfSeq &AttributeTypeAndDistinguishedValueSetOfSeq::operator = (const AttributeTypeAndDistinguishedValueSetOfSeq &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttributeTypeAndDistinguishedValueSetOfSeq::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = contextList.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (distingAttrValue))
+  {
+    l = distingAttrValue->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // AttributeTypeAndDistinguishedValueSetOfSeq::BEncContent
+
+
+void AttributeTypeAndDistinguishedValueSetOfSeq::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    distingAttrValue = new AsnOid;
+    distingAttrValue->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    contextList.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -101);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -102);
+  }
+  else
+    return;
+} // AttributeTypeAndDistinguishedValueSetOfSeq::BDecContent
+
+AsnLen AttributeTypeAndDistinguishedValueSetOfSeq::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributeTypeAndDistinguishedValueSetOfSeq::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributeTypeAndDistinguishedValueSetOfSeq::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -103);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AttributeTypeAndDistinguishedValueSetOfSeq::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttributeTypeAndDistinguishedValueSetOfSeq::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttributeTypeAndDistinguishedValueSetOfSeq::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (distingAttrValue))
+  {
+    Indent (os, indentG);
+    os << "distingAttrValue ";
+    os << *distingAttrValue;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "distingAttrValue ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "contextList ";
+    os << contextList;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AttributeTypeAndDistinguishedValueSetOfSeq::Print
+
+
+AsnType *AttributeTypeAndDistinguishedValueSetOf::Clone() const
+{
+  return new AttributeTypeAndDistinguishedValueSetOf;
+}
+
+AsnType *AttributeTypeAndDistinguishedValueSetOf::Copy() const
+{
+  return new AttributeTypeAndDistinguishedValueSetOf (*this);
+}
+
+AsnLen AttributeTypeAndDistinguishedValueSetOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void AttributeTypeAndDistinguishedValueSetOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "AttributeTypeAndDistinguishedValueSetOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -104);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+AttributeTypeAndDistinguishedValueSetOf::AttributeTypeAndDistinguishedValueSetOf (const AttributeTypeAndDistinguishedValueSetOf &)
+{
+  Asn1Error << "use of incompletely defined AttributeTypeAndDistinguishedValueSetOf::AttributeTypeAndDistinguishedValueSetOf (const AttributeTypeAndDistinguishedValueSetOf &)" << endl;
+  abort();
+}
+
+AttributeTypeAndDistinguishedValueSetOf::~AttributeTypeAndDistinguishedValueSetOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+AttributeTypeAndDistinguishedValueSetOf &AttributeTypeAndDistinguishedValueSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOf &that)
+#else // SNACC_DEEP_COPY
+AttributeTypeAndDistinguishedValueSetOf &AttributeTypeAndDistinguishedValueSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeTypeAndDistinguishedValueSetOf &AttributeTypeAndDistinguishedValueSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void AttributeTypeAndDistinguishedValueSetOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  AttributeTypeAndDistinguishedValueSetOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // AttributeTypeAndDistinguishedValueSetOf::SetCurrElmt
+
+
+unsigned long int  AttributeTypeAndDistinguishedValueSetOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // AttributeTypeAndDistinguishedValueSetOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+AttributeTypeAndDistinguishedValueSetOfSeq *AttributeTypeAndDistinguishedValueSetOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new AttributeTypeAndDistinguishedValueSetOfSeq;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeTypeAndDistinguishedValueSetOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+AttributeTypeAndDistinguishedValueSetOfSeq  *AttributeTypeAndDistinguishedValueSetOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeTypeAndDistinguishedValueSetOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeTypeAndDistinguishedValueSetOfSeq  *AttributeTypeAndDistinguishedValueSetOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeTypeAndDistinguishedValueSetOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeTypeAndDistinguishedValueSetOfSeq *AttributeTypeAndDistinguishedValueSetOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeTypeAndDistinguishedValueSetOf::InsertAfter
+
+
+AttributeTypeAndDistinguishedValueSetOf  &AttributeTypeAndDistinguishedValueSetOf::AppendCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+AttributeTypeAndDistinguishedValueSetOf  &AttributeTypeAndDistinguishedValueSetOf::PrependCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeTypeAndDistinguishedValueSetOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeTypeAndDistinguishedValueSetOf &AttributeTypeAndDistinguishedValueSetOf::InsertBeforeAndCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeTypeAndDistinguishedValueSetOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeTypeAndDistinguishedValueSetOf  &AttributeTypeAndDistinguishedValueSetOf::InsertAfterAndCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeTypeAndDistinguishedValueSetOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void AttributeTypeAndDistinguishedValueSetOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen AttributeTypeAndDistinguishedValueSetOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // AttributeTypeAndDistinguishedValueSetOf::BEncContent
+
+
+void  AttributeTypeAndDistinguishedValueSetOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AttributeTypeAndDistinguishedValueSetOfSeq *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -105);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // AttributeTypeAndDistinguishedValueSetOf::BDecContent
+
+
+AsnType *AttributeSetOf::Clone() const
+{
+  return new AttributeSetOf;
+}
+
+AsnType *AttributeSetOf::Copy() const
+{
+  return new AttributeSetOf (*this);
+}
+
+AsnLen AttributeSetOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void AttributeSetOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "AttributeSetOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -106);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+AttributeSetOf::AttributeSetOf (const AttributeSetOf &)
+{
+  Asn1Error << "use of incompletely defined AttributeSetOf::AttributeSetOf (const AttributeSetOf &)" << endl;
+  abort();
+}
+
+AttributeSetOf::~AttributeSetOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+AttributeSetOf &AttributeSetOf::operator = (const AttributeSetOf &that)
+#else // SNACC_DEEP_COPY
+AttributeSetOf &AttributeSetOf::operator = (const AttributeSetOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeSetOf &AttributeSetOf::operator = (const AttributeSetOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void AttributeSetOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  AttributeSetOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // AttributeSetOf::SetCurrElmt
+
+
+unsigned long int  AttributeSetOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // AttributeSetOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+AttributeValue *AttributeSetOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new AttributeValue;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeSetOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+AttributeValue  *AttributeSetOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeValue;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeSetOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeValue  *AttributeSetOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeValue;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeSetOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeValue *AttributeSetOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeValue;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeSetOf::InsertAfter
+
+
+AttributeSetOf  &AttributeSetOf::AppendCopy (AttributeValue &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeValue;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+AttributeSetOf  &AttributeSetOf::PrependCopy (AttributeValue &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeValue;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeSetOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeSetOf &AttributeSetOf::InsertBeforeAndCopy (AttributeValue &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeValue;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeSetOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeSetOf  &AttributeSetOf::InsertAfterAndCopy (AttributeValue &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeValue;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeSetOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void AttributeSetOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen AttributeSetOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+        tmpEnc[iii] = (CSM_Buffer *)currElmt->elmt->value;
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // AttributeSetOf::BEncContent
+
+
+void  AttributeSetOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AttributeValue *listElmt;
+    AsnLen listBytesDecoded = 0;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        listElmt = Append();
+        DEC_LOAD_ANYBUF(listElmt, b, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // AttributeSetOf::BDecContent
+
+
+Attribute::Attribute()
+{
+}
+
+Attribute::Attribute (const Attribute &)
+{
+  Asn1Error << "use of incompletely defined Attribute::Attribute (const Attribute &)" << endl;
+  abort();
+}
+
+Attribute::~Attribute()
+{
+}
+
+AsnType *Attribute::Clone() const
+{
+  return new Attribute;
+}
+
+AsnType *Attribute::Copy() const
+{
+  return new Attribute (*this);
+}
+
+#if SNACC_DEEP_COPY
+Attribute &Attribute::operator = (const Attribute &that)
+#else // SNACC_DEEP_COPY
+Attribute &Attribute::operator = (const Attribute &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    type = that.type;
+    values = that.values;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Attribute &Attribute::operator = (const Attribute &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+Attribute::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = values.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+
+    l = type.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // Attribute::BEncContent
+
+
+void Attribute::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    type.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -107);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    values.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -108);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -109);
+  }
+  else
+    return;
+} // Attribute::BDecContent
+
+AsnLen Attribute::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void Attribute::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "Attribute::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -110);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int Attribute::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int Attribute::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void Attribute::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "type ";
+    os << type;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "values ";
+    os << values;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // Attribute::Print
+
+
+AttributeTypeAndDistinguishedValue::AttributeTypeAndDistinguishedValue()
+{
+  primaryDistinguished = NULL;
+  valuesWithContext = NULL;
+}
+
+AttributeTypeAndDistinguishedValue::AttributeTypeAndDistinguishedValue (const AttributeTypeAndDistinguishedValue &)
+{
+  Asn1Error << "use of incompletely defined AttributeTypeAndDistinguishedValue::AttributeTypeAndDistinguishedValue (const AttributeTypeAndDistinguishedValue &)" << endl;
+  abort();
+}
+
+AttributeTypeAndDistinguishedValue::~AttributeTypeAndDistinguishedValue()
+{
+  delete primaryDistinguished;
+  delete valuesWithContext;
+}
+
+AsnType *AttributeTypeAndDistinguishedValue::Clone() const
+{
+  return new AttributeTypeAndDistinguishedValue;
+}
+
+AsnType *AttributeTypeAndDistinguishedValue::Copy() const
+{
+  return new AttributeTypeAndDistinguishedValue (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttributeTypeAndDistinguishedValue &AttributeTypeAndDistinguishedValue::operator = (const AttributeTypeAndDistinguishedValue &that)
+#else // SNACC_DEEP_COPY
+AttributeTypeAndDistinguishedValue &AttributeTypeAndDistinguishedValue::operator = (const AttributeTypeAndDistinguishedValue &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    type = that.type;
+    value = that.value;
+    if (that.primaryDistinguished)
+    {
+      if (!primaryDistinguished)
+        primaryDistinguished = new AsnBool;
+      *primaryDistinguished = *that.primaryDistinguished;
+    }
+    else
+    {
+      delete primaryDistinguished;
+      primaryDistinguished = NULL;
+    }
+    if (that.valuesWithContext)
+    {
+      if (!valuesWithContext)
+        valuesWithContext = new AttributeTypeAndDistinguishedValueSetOf;
+      *valuesWithContext = *that.valuesWithContext;
+    }
+    else
+    {
+      delete valuesWithContext;
+      valuesWithContext = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeTypeAndDistinguishedValue &AttributeTypeAndDistinguishedValue::operator = (const AttributeTypeAndDistinguishedValue &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttributeTypeAndDistinguishedValue::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (valuesWithContext))
+  {
+      BEncEocIfNec (b);
+    l = valuesWithContext->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (primaryDistinguished))
+  {
+    l = primaryDistinguished->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE);
+    totalLen += l;
+  }
+
+        ENC_LOAD_ANYBUF(&value, b, l);
+    totalLen += l;
+
+    l = type.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // AttributeTypeAndDistinguishedValue::BEncContent
+
+
+void AttributeTypeAndDistinguishedValue::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    type.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -111);
+  }
+
+  // ANY type
+        DEC_LOAD_ANYBUF(&value, b, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    primaryDistinguished = new AsnBool;
+    primaryDistinguished->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    valuesWithContext = new AttributeTypeAndDistinguishedValueSetOf;
+    valuesWithContext->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -112);
+  }
+  else
+    return;
+} // AttributeTypeAndDistinguishedValue::BDecContent
+
+AsnLen AttributeTypeAndDistinguishedValue::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributeTypeAndDistinguishedValue::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributeTypeAndDistinguishedValue::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -113);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AttributeTypeAndDistinguishedValue::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttributeTypeAndDistinguishedValue::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttributeTypeAndDistinguishedValue::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "type ";
+    os << type;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "value ";
+    os << value;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (primaryDistinguished))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "primaryDistinguished ";
+    os << *primaryDistinguished;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "primaryDistinguished ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (valuesWithContext))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "valuesWithContext ";
+    os << *valuesWithContext;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "valuesWithContext ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AttributeTypeAndDistinguishedValue::Print
+
+
+AsnType *RelativeDistinguishedName::Clone() const
+{
+  return new RelativeDistinguishedName;
+}
+
+AsnType *RelativeDistinguishedName::Copy() const
+{
+  return new RelativeDistinguishedName (*this);
+}
+
+AsnLen RelativeDistinguishedName::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void RelativeDistinguishedName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "RelativeDistinguishedName::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -114);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+RelativeDistinguishedName::RelativeDistinguishedName (const RelativeDistinguishedName &)
+{
+  Asn1Error << "use of incompletely defined RelativeDistinguishedName::RelativeDistinguishedName (const RelativeDistinguishedName &)" << endl;
+  abort();
+}
+
+RelativeDistinguishedName::~RelativeDistinguishedName()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+RelativeDistinguishedName &RelativeDistinguishedName::operator = (const RelativeDistinguishedName &that)
+#else // SNACC_DEEP_COPY
+RelativeDistinguishedName &RelativeDistinguishedName::operator = (const RelativeDistinguishedName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RelativeDistinguishedName &RelativeDistinguishedName::operator = (const RelativeDistinguishedName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void RelativeDistinguishedName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  RelativeDistinguishedName::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // RelativeDistinguishedName::SetCurrElmt
+
+
+unsigned long int  RelativeDistinguishedName::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // RelativeDistinguishedName::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+AttributeTypeAndDistinguishedValue *RelativeDistinguishedName::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new AttributeTypeAndDistinguishedValue;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RelativeDistinguishedName::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+AttributeTypeAndDistinguishedValue  *RelativeDistinguishedName::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RelativeDistinguishedName::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeTypeAndDistinguishedValue  *RelativeDistinguishedName::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RelativeDistinguishedName::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeTypeAndDistinguishedValue *RelativeDistinguishedName::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RelativeDistinguishedName::InsertAfter
+
+
+RelativeDistinguishedName  &RelativeDistinguishedName::AppendCopy (AttributeTypeAndDistinguishedValue &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+RelativeDistinguishedName  &RelativeDistinguishedName::PrependCopy (AttributeTypeAndDistinguishedValue &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // RelativeDistinguishedName::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+RelativeDistinguishedName &RelativeDistinguishedName::InsertBeforeAndCopy (AttributeTypeAndDistinguishedValue &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // RelativeDistinguishedName::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+RelativeDistinguishedName  &RelativeDistinguishedName::InsertAfterAndCopy (AttributeTypeAndDistinguishedValue &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // RelativeDistinguishedName::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void RelativeDistinguishedName::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen RelativeDistinguishedName::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // RelativeDistinguishedName::BEncContent
+
+
+void  RelativeDistinguishedName::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AttributeTypeAndDistinguishedValue *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -115);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // RelativeDistinguishedName::BDecContent
+
+
+AsnType *RDNSequence::Clone() const
+{
+  return new RDNSequence;
+}
+
+AsnType *RDNSequence::Copy() const
+{
+  return new RDNSequence (*this);
+}
+
+AsnLen RDNSequence::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void RDNSequence::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "RDNSequence::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -116);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+RDNSequence::RDNSequence (const RDNSequence &)
+{
+  Asn1Error << "use of incompletely defined RDNSequence::RDNSequence (const RDNSequence &)" << endl;
+  abort();
+}
+
+RDNSequence::~RDNSequence()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+RDNSequence &RDNSequence::operator = (const RDNSequence &that)
+#else // SNACC_DEEP_COPY
+RDNSequence &RDNSequence::operator = (const RDNSequence &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined RDNSequence &RDNSequence::operator = (const RDNSequence &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void RDNSequence::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  RDNSequence::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // RDNSequence::SetCurrElmt
+
+
+unsigned long int  RDNSequence::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // RDNSequence::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+RelativeDistinguishedName *RDNSequence::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new RelativeDistinguishedName;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RDNSequence::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+RelativeDistinguishedName  *RDNSequence::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RelativeDistinguishedName;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RDNSequence::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+RelativeDistinguishedName  *RDNSequence::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RelativeDistinguishedName;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RDNSequence::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+RelativeDistinguishedName *RDNSequence::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RelativeDistinguishedName;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // RDNSequence::InsertAfter
+
+
+RDNSequence  &RDNSequence::AppendCopy (RelativeDistinguishedName &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RelativeDistinguishedName;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+RDNSequence  &RDNSequence::PrependCopy (RelativeDistinguishedName &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RelativeDistinguishedName;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // RDNSequence::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+RDNSequence &RDNSequence::InsertBeforeAndCopy (RelativeDistinguishedName &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RelativeDistinguishedName;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // RDNSequence::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+RDNSequence  &RDNSequence::InsertAfterAndCopy (RelativeDistinguishedName &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new RelativeDistinguishedName;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // RDNSequence::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void RDNSequence::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen RDNSequence::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // RDNSequence::BEncContent
+
+
+void  RDNSequence::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    RelativeDistinguishedName *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -117);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // RDNSequence::BDecContent
+
+
+AsnType *Attributes::Clone() const
+{
+  return new Attributes;
+}
+
+AsnType *Attributes::Copy() const
+{
+  return new Attributes (*this);
+}
+
+AsnLen Attributes::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void Attributes::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "Attributes::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -118);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+Attributes::Attributes (const Attributes &)
+{
+  Asn1Error << "use of incompletely defined Attributes::Attributes (const Attributes &)" << endl;
+  abort();
+}
+
+Attributes::~Attributes()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+Attributes &Attributes::operator = (const Attributes &that)
+#else // SNACC_DEEP_COPY
+Attributes &Attributes::operator = (const Attributes &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Attributes &Attributes::operator = (const Attributes &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void Attributes::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  Attributes::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // Attributes::SetCurrElmt
+
+
+unsigned long int  Attributes::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // Attributes::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+Attribute *Attributes::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new Attribute;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // Attributes::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+Attribute  *Attributes::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // Attributes::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+Attribute  *Attributes::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // Attributes::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+Attribute *Attributes::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // Attributes::InsertAfter
+
+
+Attributes  &Attributes::AppendCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+Attributes  &Attributes::PrependCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // Attributes::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+Attributes &Attributes::InsertBeforeAndCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // Attributes::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+Attributes  &Attributes::InsertAfterAndCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // Attributes::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void Attributes::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen Attributes::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // Attributes::BEncContent
+
+
+void  Attributes::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    Attribute *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -119);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // Attributes::BDecContent
+
+
+Name::Name()
+{
+  choiceId = rDNSequenceCid;
+#if TCL
+  rDNSequence = new RDNSequence;
+#else
+  rDNSequence = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+Name::Name (const Name &)
+{
+  Asn1Error << "use of incompletely defined Name::Name (const Name &)" << endl;
+  abort();
+}
+
+Name::~Name()
+{
+  switch (choiceId)
+  {
+    case rDNSequenceCid:
+      delete rDNSequence;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *Name::Clone() const
+{
+  return new Name;
+}
+
+AsnType *Name::Copy() const
+{
+  return new Name (*this);
+}
+
+#if SNACC_DEEP_COPY
+Name &Name::operator = (const Name &that)
+#else // SNACC_DEEP_COPY
+Name &Name::operator = (const Name &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case rDNSequenceCid:
+        delete rDNSequence;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case rDNSequenceCid:
+        rDNSequence = new RDNSequence;
+        *rDNSequence = *that.rDNSequence;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Name &Name::operator = (const Name &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+Name::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case rDNSequenceCid:
+      BEncEocIfNec (b);
+      l = rDNSequence->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+      break;
+
+  } // end switch
+  return l;
+} // Name::BEncContent
+
+
+void Name::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
+      choiceId = rDNSequenceCid;
+      rDNSequence = new RDNSequence;
+        rDNSequence->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -120);
+      break;
+  } // end switch
+} // Name::BDecContent
+
+
+AsnLen Name::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void Name::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int Name::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int Name::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void Name::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case rDNSequenceCid:
+      os << "rDNSequence ";
+      if (rDNSequence)
+        os << *rDNSequence;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // Name::Print
+
diff --git a/SecurityASN1/c++/sm_x501ud.cpp b/SecurityASN1/c++/sm_x501ud.cpp
new file mode 100644
index 00000000..75c1c3ff
--- /dev/null
+++ b/SecurityASN1/c++/sm_x501ud.cpp
@@ -0,0 +1,34 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x501ud.cpp - class member functions for ASN.1 module UsefulDefinitions
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
diff --git a/SecurityASN1/c++/sm_x509af.cpp b/SecurityASN1/c++/sm_x509af.cpp
new file mode 100644
index 00000000..e9fe5039
--- /dev/null
+++ b/SecurityASN1/c++/sm_x509af.cpp
@@ -0,0 +1,10047 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x509af.cpp - class member functions for ASN.1 module AuthenticationFramework
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+AsnType *AttributeCertificateAssertionSetOf::Clone() const
+{
+  return new AttributeCertificateAssertionSetOf;
+}
+
+AsnType *AttributeCertificateAssertionSetOf::Copy() const
+{
+  return new AttributeCertificateAssertionSetOf (*this);
+}
+
+AsnLen AttributeCertificateAssertionSetOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void AttributeCertificateAssertionSetOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "AttributeCertificateAssertionSetOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -100);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+AttributeCertificateAssertionSetOf::AttributeCertificateAssertionSetOf (const AttributeCertificateAssertionSetOf &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificateAssertionSetOf::AttributeCertificateAssertionSetOf (const AttributeCertificateAssertionSetOf &)" << endl;
+  abort();
+}
+
+AttributeCertificateAssertionSetOf::~AttributeCertificateAssertionSetOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+AttributeCertificateAssertionSetOf &AttributeCertificateAssertionSetOf::operator = (const AttributeCertificateAssertionSetOf &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificateAssertionSetOf &AttributeCertificateAssertionSetOf::operator = (const AttributeCertificateAssertionSetOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificateAssertionSetOf &AttributeCertificateAssertionSetOf::operator = (const AttributeCertificateAssertionSetOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void AttributeCertificateAssertionSetOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  AttributeCertificateAssertionSetOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // AttributeCertificateAssertionSetOf::SetCurrElmt
+
+
+unsigned long int  AttributeCertificateAssertionSetOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // AttributeCertificateAssertionSetOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+AttributeType *AttributeCertificateAssertionSetOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new AttributeType;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificateAssertionSetOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+AttributeType  *AttributeCertificateAssertionSetOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeType;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificateAssertionSetOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeType  *AttributeCertificateAssertionSetOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeType;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificateAssertionSetOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeType *AttributeCertificateAssertionSetOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeType;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificateAssertionSetOf::InsertAfter
+
+
+AttributeCertificateAssertionSetOf  &AttributeCertificateAssertionSetOf::AppendCopy (AttributeType &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeType;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+AttributeCertificateAssertionSetOf  &AttributeCertificateAssertionSetOf::PrependCopy (AttributeType &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeType;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificateAssertionSetOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeCertificateAssertionSetOf &AttributeCertificateAssertionSetOf::InsertBeforeAndCopy (AttributeType &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeType;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificateAssertionSetOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeCertificateAssertionSetOf  &AttributeCertificateAssertionSetOf::InsertAfterAndCopy (AttributeType &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new AttributeType;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificateAssertionSetOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void AttributeCertificateAssertionSetOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen AttributeCertificateAssertionSetOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncDefLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, PRIM, OID_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // AttributeCertificateAssertionSetOf::BEncContent
+
+
+void  AttributeCertificateAssertionSetOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AttributeType *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -101);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // AttributeCertificateAssertionSetOf::BDecContent
+
+
+AsnType *AttributeCertificateInfoSeqOf::Clone() const
+{
+  return new AttributeCertificateInfoSeqOf;
+}
+
+AsnType *AttributeCertificateInfoSeqOf::Copy() const
+{
+  return new AttributeCertificateInfoSeqOf (*this);
+}
+
+AsnLen AttributeCertificateInfoSeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributeCertificateInfoSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributeCertificateInfoSeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -102);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+AttributeCertificateInfoSeqOf::AttributeCertificateInfoSeqOf (const AttributeCertificateInfoSeqOf &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificateInfoSeqOf::AttributeCertificateInfoSeqOf (const AttributeCertificateInfoSeqOf &)" << endl;
+  abort();
+}
+
+AttributeCertificateInfoSeqOf::~AttributeCertificateInfoSeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+AttributeCertificateInfoSeqOf &AttributeCertificateInfoSeqOf::operator = (const AttributeCertificateInfoSeqOf &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificateInfoSeqOf &AttributeCertificateInfoSeqOf::operator = (const AttributeCertificateInfoSeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificateInfoSeqOf &AttributeCertificateInfoSeqOf::operator = (const AttributeCertificateInfoSeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void AttributeCertificateInfoSeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  AttributeCertificateInfoSeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // AttributeCertificateInfoSeqOf::SetCurrElmt
+
+
+unsigned long int  AttributeCertificateInfoSeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // AttributeCertificateInfoSeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+Attribute *AttributeCertificateInfoSeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new Attribute;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificateInfoSeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+Attribute  *AttributeCertificateInfoSeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificateInfoSeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+Attribute  *AttributeCertificateInfoSeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificateInfoSeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+Attribute *AttributeCertificateInfoSeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificateInfoSeqOf::InsertAfter
+
+
+AttributeCertificateInfoSeqOf  &AttributeCertificateInfoSeqOf::AppendCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+AttributeCertificateInfoSeqOf  &AttributeCertificateInfoSeqOf::PrependCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificateInfoSeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeCertificateInfoSeqOf &AttributeCertificateInfoSeqOf::InsertBeforeAndCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificateInfoSeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeCertificateInfoSeqOf  &AttributeCertificateInfoSeqOf::InsertAfterAndCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificateInfoSeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void AttributeCertificateInfoSeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen AttributeCertificateInfoSeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // AttributeCertificateInfoSeqOf::BEncContent
+
+
+void  AttributeCertificateInfoSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    Attribute *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -103);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // AttributeCertificateInfoSeqOf::BDecContent
+
+
+AlgorithmIdentifier::AlgorithmIdentifier()
+{
+  parameters = NULL;
+}
+
+AlgorithmIdentifier::AlgorithmIdentifier (const AlgorithmIdentifier &)
+{
+  Asn1Error << "use of incompletely defined AlgorithmIdentifier::AlgorithmIdentifier (const AlgorithmIdentifier &)" << endl;
+  abort();
+}
+
+AlgorithmIdentifier::~AlgorithmIdentifier()
+{
+  delete parameters;
+}
+
+AsnType *AlgorithmIdentifier::Clone() const
+{
+  return new AlgorithmIdentifier;
+}
+
+AsnType *AlgorithmIdentifier::Copy() const
+{
+  return new AlgorithmIdentifier (*this);
+}
+
+#if SNACC_DEEP_COPY
+AlgorithmIdentifier &AlgorithmIdentifier::operator = (const AlgorithmIdentifier &that)
+#else // SNACC_DEEP_COPY
+AlgorithmIdentifier &AlgorithmIdentifier::operator = (const AlgorithmIdentifier &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    algorithm = that.algorithm;
+    if (that.parameters)
+    {
+      if (!parameters)
+        parameters = new AsnAny;
+      *parameters = *that.parameters;
+    }
+    else
+    {
+      delete parameters;
+      parameters = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AlgorithmIdentifier &AlgorithmIdentifier::operator = (const AlgorithmIdentifier &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AlgorithmIdentifier::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (parameters))
+  {
+        ENC_LOAD_ANYBUF(parameters, b, l);
+    totalLen += l;
+  }
+
+    l = algorithm.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // AlgorithmIdentifier::BEncContent
+
+
+void AlgorithmIdentifier::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    algorithm.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = b.PeekByte();
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDecEoc (b, seqBytesDecoded, env);
+
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -104);
+  }
+
+  // ANY type
+    parameters = new AsnAny;
+        DEC_LOAD_ANYBUF(parameters, b, seqBytesDecoded, env);
+
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -105);
+  }
+  else
+    return;
+} // AlgorithmIdentifier::BDecContent
+
+AsnLen AlgorithmIdentifier::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AlgorithmIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AlgorithmIdentifier::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -106);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AlgorithmIdentifier::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AlgorithmIdentifier::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AlgorithmIdentifier::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "algorithm ";
+    os << algorithm;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (parameters))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "parameters ";
+    os << *parameters;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "parameters ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AlgorithmIdentifier::Print
+
+
+Time::Time()
+{
+  choiceId = utcTimeCid;
+#if TCL
+  utcTime = new UTCTime;
+#else
+  utcTime = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+Time::Time (const Time &)
+{
+  Asn1Error << "use of incompletely defined Time::Time (const Time &)" << endl;
+  abort();
+}
+
+Time::~Time()
+{
+  switch (choiceId)
+  {
+    case utcTimeCid:
+      delete utcTime;
+      break;
+    case generalizedTimeCid:
+      delete generalizedTime;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *Time::Clone() const
+{
+  return new Time;
+}
+
+AsnType *Time::Copy() const
+{
+  return new Time (*this);
+}
+
+#if SNACC_DEEP_COPY
+Time &Time::operator = (const Time &that)
+#else // SNACC_DEEP_COPY
+Time &Time::operator = (const Time &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case utcTimeCid:
+        delete utcTime;
+        break;
+      case generalizedTimeCid:
+        delete generalizedTime;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case utcTimeCid:
+        utcTime = new UTCTime;
+        *utcTime = *that.utcTime;
+        break;
+      case generalizedTimeCid:
+        generalizedTime = new GeneralizedTime;
+        *generalizedTime = *that.generalizedTime;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Time &Time::operator = (const Time &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+Time::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case utcTimeCid:
+      l = utcTime->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, UTCTIME_TAG_CODE);
+      break;
+
+    case generalizedTimeCid:
+      l = generalizedTime->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+      break;
+
+  } // end switch
+  return l;
+} // Time::BEncContent
+
+
+void Time::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE):
+      choiceId = utcTimeCid;
+      utcTime = new UTCTime;
+        utcTime->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE):
+      choiceId = generalizedTimeCid;
+      generalizedTime = new GeneralizedTime;
+        generalizedTime->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -107);
+      break;
+  } // end switch
+} // Time::BDecContent
+
+
+AsnLen Time::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void Time::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int Time::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int Time::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void Time::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case utcTimeCid:
+      os << "utcTime ";
+      if (utcTime)
+        os << *utcTime;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case generalizedTimeCid:
+      os << "generalizedTime ";
+      if (generalizedTime)
+        os << *generalizedTime;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // Time::Print
+
+Extension::Extension()
+{
+  critical = NULL;
+}
+
+Extension::Extension (const Extension &)
+{
+  Asn1Error << "use of incompletely defined Extension::Extension (const Extension &)" << endl;
+  abort();
+}
+
+Extension::~Extension()
+{
+  delete critical;
+}
+
+AsnType *Extension::Clone() const
+{
+  return new Extension;
+}
+
+AsnType *Extension::Copy() const
+{
+  return new Extension (*this);
+}
+
+#if SNACC_DEEP_COPY
+Extension &Extension::operator = (const Extension &that)
+#else // SNACC_DEEP_COPY
+Extension &Extension::operator = (const Extension &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    extnId = that.extnId;
+    if (that.critical)
+    {
+      if (!critical)
+        critical = new AsnBool;
+      *critical = *that.critical;
+    }
+    else
+    {
+      delete critical;
+      critical = NULL;
+    }
+    extnValue = that.extnValue;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Extension &Extension::operator = (const Extension &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+Extension::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = extnValue.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (critical))
+  {
+    l = critical->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = extnId.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // Extension::BEncContent
+
+
+void Extension::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    extnId.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -108);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    critical = new AsnBool;
+    critical->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    extnValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -109);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -110);
+  }
+  else
+    return;
+} // Extension::BDecContent
+
+AsnLen Extension::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void Extension::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "Extension::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -111);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int Extension::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int Extension::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void Extension::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "extnId ";
+    os << extnId;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (critical))
+  {
+    Indent (os, indentG);
+    os << "critical ";
+    os << *critical;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "critical ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "extnValue ";
+    os << extnValue;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // Extension::Print
+
+
+AttCertValidityPeriod::AttCertValidityPeriod()
+{
+}
+
+AttCertValidityPeriod::AttCertValidityPeriod (const AttCertValidityPeriod &)
+{
+  Asn1Error << "use of incompletely defined AttCertValidityPeriod::AttCertValidityPeriod (const AttCertValidityPeriod &)" << endl;
+  abort();
+}
+
+AttCertValidityPeriod::~AttCertValidityPeriod()
+{
+}
+
+AsnType *AttCertValidityPeriod::Clone() const
+{
+  return new AttCertValidityPeriod;
+}
+
+AsnType *AttCertValidityPeriod::Copy() const
+{
+  return new AttCertValidityPeriod (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttCertValidityPeriod &AttCertValidityPeriod::operator = (const AttCertValidityPeriod &that)
+#else // SNACC_DEEP_COPY
+AttCertValidityPeriod &AttCertValidityPeriod::operator = (const AttCertValidityPeriod &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    notBeforeTime = that.notBeforeTime;
+    notAfterTime = that.notAfterTime;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttCertValidityPeriod &AttCertValidityPeriod::operator = (const AttCertValidityPeriod &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttCertValidityPeriod::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = notAfterTime.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    totalLen += l;
+
+    l = notBeforeTime.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // AttCertValidityPeriod::BEncContent
+
+
+void AttCertValidityPeriod::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    notBeforeTime.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -112);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    notAfterTime.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -113);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -114);
+  }
+  else
+    return;
+} // AttCertValidityPeriod::BDecContent
+
+AsnLen AttCertValidityPeriod::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttCertValidityPeriod::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttCertValidityPeriod::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -115);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AttCertValidityPeriod::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttCertValidityPeriod::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttCertValidityPeriod::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "notBeforeTime ";
+    os << notBeforeTime;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "notAfterTime ";
+    os << notAfterTime;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AttCertValidityPeriod::Print
+
+
+Validity::Validity()
+{
+#if TCL
+  notBefore = new Time;
+#else
+  notBefore = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  notAfter = new Time;
+#else
+  notAfter = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+Validity::Validity (const Validity &)
+{
+  Asn1Error << "use of incompletely defined Validity::Validity (const Validity &)" << endl;
+  abort();
+}
+
+Validity::~Validity()
+{
+  delete notBefore;
+  delete notAfter;
+}
+
+AsnType *Validity::Clone() const
+{
+  return new Validity;
+}
+
+AsnType *Validity::Copy() const
+{
+  return new Validity (*this);
+}
+
+#if SNACC_DEEP_COPY
+Validity &Validity::operator = (const Validity &that)
+#else // SNACC_DEEP_COPY
+Validity &Validity::operator = (const Validity &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.notBefore)
+    {
+      if (!notBefore)
+        notBefore = new Time;
+      *notBefore = *that.notBefore;
+    }
+    else
+    {
+      delete notBefore;
+      notBefore = NULL;
+    }
+    if (that.notAfter)
+    {
+      if (!notAfter)
+        notAfter = new Time;
+      *notAfter = *that.notAfter;
+    }
+    else
+    {
+      delete notAfter;
+      notAfter = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Validity &Validity::operator = (const Validity &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+Validity::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = notAfter->BEncContent (b);
+    totalLen += l;
+
+    l = notBefore->BEncContent (b);
+    totalLen += l;
+
+  return totalLen;
+} // Validity::BEncContent
+
+
+void Validity::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    notBefore = new Time;
+    notBefore->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -116);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    notAfter = new Time;
+    notAfter->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -117);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -118);
+  }
+  else
+    return;
+} // Validity::BDecContent
+
+AsnLen Validity::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void Validity::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "Validity::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -119);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int Validity::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int Validity::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void Validity::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (notBefore))
+  {
+    Indent (os, indentG);
+    os << "notBefore ";
+    os << *notBefore;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "notBefore ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (notAfter))
+  {
+    Indent (os, indentG);
+    os << "notAfter ";
+    os << *notAfter;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "notAfter ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // Validity::Print
+
+
+SubjectPublicKeyInfo::SubjectPublicKeyInfo()
+{
+#if TCL
+  algorithm = new AlgorithmIdentifier;
+#else
+  algorithm = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+SubjectPublicKeyInfo::SubjectPublicKeyInfo (const SubjectPublicKeyInfo &)
+{
+  Asn1Error << "use of incompletely defined SubjectPublicKeyInfo::SubjectPublicKeyInfo (const SubjectPublicKeyInfo &)" << endl;
+  abort();
+}
+
+SubjectPublicKeyInfo::~SubjectPublicKeyInfo()
+{
+  delete algorithm;
+}
+
+AsnType *SubjectPublicKeyInfo::Clone() const
+{
+  return new SubjectPublicKeyInfo;
+}
+
+AsnType *SubjectPublicKeyInfo::Copy() const
+{
+  return new SubjectPublicKeyInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+SubjectPublicKeyInfo &SubjectPublicKeyInfo::operator = (const SubjectPublicKeyInfo &that)
+#else // SNACC_DEEP_COPY
+SubjectPublicKeyInfo &SubjectPublicKeyInfo::operator = (const SubjectPublicKeyInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.algorithm)
+    {
+      if (!algorithm)
+        algorithm = new AlgorithmIdentifier;
+      *algorithm = *that.algorithm;
+    }
+    else
+    {
+      delete algorithm;
+      algorithm = NULL;
+    }
+    subjectPublicKey = that.subjectPublicKey;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SubjectPublicKeyInfo &SubjectPublicKeyInfo::operator = (const SubjectPublicKeyInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+SubjectPublicKeyInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = subjectPublicKey.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = algorithm->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // SubjectPublicKeyInfo::BEncContent
+
+
+void SubjectPublicKeyInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    algorithm = new AlgorithmIdentifier;
+    algorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -120);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    subjectPublicKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -121);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -122);
+  }
+  else
+    return;
+} // SubjectPublicKeyInfo::BDecContent
+
+AsnLen SubjectPublicKeyInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void SubjectPublicKeyInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "SubjectPublicKeyInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -123);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int SubjectPublicKeyInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int SubjectPublicKeyInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void SubjectPublicKeyInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (algorithm))
+  {
+    Indent (os, indentG);
+    os << "algorithm ";
+    os << *algorithm;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "algorithm ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "subjectPublicKey ";
+    os << subjectPublicKey;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // SubjectPublicKeyInfo::Print
+
+
+AsnType *Extensions::Clone() const
+{
+  return new Extensions;
+}
+
+AsnType *Extensions::Copy() const
+{
+  return new Extensions (*this);
+}
+
+AsnLen Extensions::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void Extensions::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "Extensions::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -124);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+Extensions::Extensions (const Extensions &)
+{
+  Asn1Error << "use of incompletely defined Extensions::Extensions (const Extensions &)" << endl;
+  abort();
+}
+
+Extensions::~Extensions()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+Extensions &Extensions::operator = (const Extensions &that)
+#else // SNACC_DEEP_COPY
+Extensions &Extensions::operator = (const Extensions &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Extensions &Extensions::operator = (const Extensions &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void Extensions::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  Extensions::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // Extensions::SetCurrElmt
+
+
+unsigned long int  Extensions::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // Extensions::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+Extension *Extensions::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new Extension;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // Extensions::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+Extension  *Extensions::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Extension;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // Extensions::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+Extension  *Extensions::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Extension;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // Extensions::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+Extension *Extensions::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Extension;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // Extensions::InsertAfter
+
+
+Extensions  &Extensions::AppendCopy (Extension &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Extension;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+Extensions  &Extensions::PrependCopy (Extension &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Extension;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // Extensions::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+Extensions &Extensions::InsertBeforeAndCopy (Extension &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Extension;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // Extensions::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+Extensions  &Extensions::InsertAfterAndCopy (Extension &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Extension;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // Extensions::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void Extensions::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen Extensions::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // Extensions::BEncContent
+
+
+void  Extensions::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    Extension *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -125);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // Extensions::BDecContent
+
+
+IssuerSerial::IssuerSerial()
+{
+  issuerUID = NULL;
+}
+
+IssuerSerial::IssuerSerial (const IssuerSerial &)
+{
+  Asn1Error << "use of incompletely defined IssuerSerial::IssuerSerial (const IssuerSerial &)" << endl;
+  abort();
+}
+
+IssuerSerial::~IssuerSerial()
+{
+  delete issuerUID;
+}
+
+AsnType *IssuerSerial::Clone() const
+{
+  return new IssuerSerial;
+}
+
+AsnType *IssuerSerial::Copy() const
+{
+  return new IssuerSerial (*this);
+}
+
+#if SNACC_DEEP_COPY
+IssuerSerial &IssuerSerial::operator = (const IssuerSerial &that)
+#else // SNACC_DEEP_COPY
+IssuerSerial &IssuerSerial::operator = (const IssuerSerial &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    issuer = that.issuer;
+    serial = that.serial;
+    if (that.issuerUID)
+    {
+      if (!issuerUID)
+        issuerUID = new UniqueIdentifier;
+      *issuerUID = *that.issuerUID;
+    }
+    else
+    {
+      delete issuerUID;
+      issuerUID = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined IssuerSerial &IssuerSerial::operator = (const IssuerSerial &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+IssuerSerial::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (issuerUID))
+  {
+    l = issuerUID->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = serial.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = issuer.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // IssuerSerial::BEncContent
+
+
+void IssuerSerial::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuer.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -126);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    serial.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -127);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuerUID = new UniqueIdentifier;
+    issuerUID->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -128);
+  }
+  else
+    return;
+} // IssuerSerial::BDecContent
+
+AsnLen IssuerSerial::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void IssuerSerial::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "IssuerSerial::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -129);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int IssuerSerial::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int IssuerSerial::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void IssuerSerial::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << issuer;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "serial ";
+    os << serial;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (issuerUID))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "issuerUID ";
+    os << *issuerUID;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "issuerUID ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // IssuerSerial::Print
+
+
+AttributeCertificateAssertionChoice::AttributeCertificateAssertionChoice()
+{
+  choiceId = baseCertificateIDCid;
+#if TCL
+  baseCertificateID = new IssuerSerial;
+#else
+  baseCertificateID = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+AttributeCertificateAssertionChoice::AttributeCertificateAssertionChoice (const AttributeCertificateAssertionChoice &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificateAssertionChoice::AttributeCertificateAssertionChoice (const AttributeCertificateAssertionChoice &)" << endl;
+  abort();
+}
+
+AttributeCertificateAssertionChoice::~AttributeCertificateAssertionChoice()
+{
+  switch (choiceId)
+  {
+    case baseCertificateIDCid:
+      delete baseCertificateID;
+      break;
+    case subjectNameCid:
+      delete subjectName;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *AttributeCertificateAssertionChoice::Clone() const
+{
+  return new AttributeCertificateAssertionChoice;
+}
+
+AsnType *AttributeCertificateAssertionChoice::Copy() const
+{
+  return new AttributeCertificateAssertionChoice (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttributeCertificateAssertionChoice &AttributeCertificateAssertionChoice::operator = (const AttributeCertificateAssertionChoice &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificateAssertionChoice &AttributeCertificateAssertionChoice::operator = (const AttributeCertificateAssertionChoice &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case baseCertificateIDCid:
+        delete baseCertificateID;
+        break;
+      case subjectNameCid:
+        delete subjectName;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case baseCertificateIDCid:
+        baseCertificateID = new IssuerSerial;
+        *baseCertificateID = *that.baseCertificateID;
+        break;
+      case subjectNameCid:
+        subjectName = new Name;
+        *subjectName = *that.subjectName;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificateAssertionChoice &AttributeCertificateAssertionChoice::operator = (const AttributeCertificateAssertionChoice &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttributeCertificateAssertionChoice::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case baseCertificateIDCid:
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+      l = baseCertificateID->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+      break;
+
+    case subjectNameCid:
+      BEncEocIfNec (b);
+      l = subjectName->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+      break;
+
+  } // end switch
+  return l;
+} // AttributeCertificateAssertionChoice::BEncContent
+
+
+void AttributeCertificateAssertionChoice::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnLen elmtLen1;
+  switch (tag)
+  {
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      tag = BDecTag (b, bytesDecoded, env);
+      if (tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+      {
+         Asn1Error << "Unexpected Tag" << endl;
+         longjmp (env, -130);
+      }
+
+      elmtLen1 = BDecLen (b, bytesDecoded, env);
+      choiceId = baseCertificateIDCid;
+      baseCertificateID = new IssuerSerial;
+        baseCertificateID->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+      if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      tag = BDecTag (b, bytesDecoded, env);
+      elmtLen1 = BDecLen (b, bytesDecoded, env);
+      choiceId = subjectNameCid;
+      subjectName = new Name;
+        subjectName->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+      if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -131);
+      break;
+  } // end switch
+} // AttributeCertificateAssertionChoice::BDecContent
+
+
+AsnLen AttributeCertificateAssertionChoice::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void AttributeCertificateAssertionChoice::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int AttributeCertificateAssertionChoice::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttributeCertificateAssertionChoice::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttributeCertificateAssertionChoice::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case baseCertificateIDCid:
+      os << "baseCertificateID ";
+      if (baseCertificateID)
+        os << *baseCertificateID;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case subjectNameCid:
+      os << "subjectName ";
+      if (subjectName)
+        os << *subjectName;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // AttributeCertificateAssertionChoice::Print
+
+AttributeCertificateInfoChoice::AttributeCertificateInfoChoice()
+{
+  choiceId = baseCertificateIDCid;
+#if TCL
+  baseCertificateID = new IssuerSerial;
+#else
+  baseCertificateID = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+AttributeCertificateInfoChoice::AttributeCertificateInfoChoice (const AttributeCertificateInfoChoice &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificateInfoChoice::AttributeCertificateInfoChoice (const AttributeCertificateInfoChoice &)" << endl;
+  abort();
+}
+
+AttributeCertificateInfoChoice::~AttributeCertificateInfoChoice()
+{
+  switch (choiceId)
+  {
+    case baseCertificateIDCid:
+      delete baseCertificateID;
+      break;
+    case subjectNameCid:
+      delete subjectName;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *AttributeCertificateInfoChoice::Clone() const
+{
+  return new AttributeCertificateInfoChoice;
+}
+
+AsnType *AttributeCertificateInfoChoice::Copy() const
+{
+  return new AttributeCertificateInfoChoice (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttributeCertificateInfoChoice &AttributeCertificateInfoChoice::operator = (const AttributeCertificateInfoChoice &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificateInfoChoice &AttributeCertificateInfoChoice::operator = (const AttributeCertificateInfoChoice &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case baseCertificateIDCid:
+        delete baseCertificateID;
+        break;
+      case subjectNameCid:
+        delete subjectName;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case baseCertificateIDCid:
+        baseCertificateID = new IssuerSerial;
+        *baseCertificateID = *that.baseCertificateID;
+        break;
+      case subjectNameCid:
+        subjectName = new GeneralNames;
+        *subjectName = *that.subjectName;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificateInfoChoice &AttributeCertificateInfoChoice::operator = (const AttributeCertificateInfoChoice &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttributeCertificateInfoChoice::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case baseCertificateIDCid:
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+      l = baseCertificateID->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+      break;
+
+    case subjectNameCid:
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+      l = subjectName->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+      break;
+
+  } // end switch
+  return l;
+} // AttributeCertificateInfoChoice::BEncContent
+
+
+void AttributeCertificateInfoChoice::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnLen elmtLen1;
+  switch (tag)
+  {
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      tag = BDecTag (b, bytesDecoded, env);
+      if (tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+      {
+         Asn1Error << "Unexpected Tag" << endl;
+         longjmp (env, -132);
+      }
+
+      elmtLen1 = BDecLen (b, bytesDecoded, env);
+      choiceId = baseCertificateIDCid;
+      baseCertificateID = new IssuerSerial;
+        baseCertificateID->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+      if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      tag = BDecTag (b, bytesDecoded, env);
+      if (tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+      {
+         Asn1Error << "Unexpected Tag" << endl;
+         longjmp (env, -133);
+      }
+
+      elmtLen1 = BDecLen (b, bytesDecoded, env);
+      choiceId = subjectNameCid;
+      subjectName = new GeneralNames;
+        subjectName->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+      if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -134);
+      break;
+  } // end switch
+} // AttributeCertificateInfoChoice::BDecContent
+
+
+AsnLen AttributeCertificateInfoChoice::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void AttributeCertificateInfoChoice::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int AttributeCertificateInfoChoice::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttributeCertificateInfoChoice::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttributeCertificateInfoChoice::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case baseCertificateIDCid:
+      os << "baseCertificateID ";
+      if (baseCertificateID)
+        os << *baseCertificateID;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case subjectNameCid:
+      os << "subjectName ";
+      if (subjectName)
+        os << *subjectName;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // AttributeCertificateInfoChoice::Print
+
+CRLToSignSeqOfSeq::CRLToSignSeqOfSeq()
+{
+#if TCL
+  revocationDate = new Time;
+#else
+  revocationDate = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  crlEntryExtensions = NULL;
+}
+
+CRLToSignSeqOfSeq::CRLToSignSeqOfSeq (const CRLToSignSeqOfSeq &)
+{
+  Asn1Error << "use of incompletely defined CRLToSignSeqOfSeq::CRLToSignSeqOfSeq (const CRLToSignSeqOfSeq &)" << endl;
+  abort();
+}
+
+CRLToSignSeqOfSeq::~CRLToSignSeqOfSeq()
+{
+  delete revocationDate;
+  delete crlEntryExtensions;
+}
+
+AsnType *CRLToSignSeqOfSeq::Clone() const
+{
+  return new CRLToSignSeqOfSeq;
+}
+
+AsnType *CRLToSignSeqOfSeq::Copy() const
+{
+  return new CRLToSignSeqOfSeq (*this);
+}
+
+#if SNACC_DEEP_COPY
+CRLToSignSeqOfSeq &CRLToSignSeqOfSeq::operator = (const CRLToSignSeqOfSeq &that)
+#else // SNACC_DEEP_COPY
+CRLToSignSeqOfSeq &CRLToSignSeqOfSeq::operator = (const CRLToSignSeqOfSeq &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    userCertificate = that.userCertificate;
+    if (that.revocationDate)
+    {
+      if (!revocationDate)
+        revocationDate = new Time;
+      *revocationDate = *that.revocationDate;
+    }
+    else
+    {
+      delete revocationDate;
+      revocationDate = NULL;
+    }
+    if (that.crlEntryExtensions)
+    {
+      if (!crlEntryExtensions)
+        crlEntryExtensions = new Extensions;
+      *crlEntryExtensions = *that.crlEntryExtensions;
+    }
+    else
+    {
+      delete crlEntryExtensions;
+      crlEntryExtensions = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CRLToSignSeqOfSeq &CRLToSignSeqOfSeq::operator = (const CRLToSignSeqOfSeq &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+CRLToSignSeqOfSeq::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (crlEntryExtensions))
+  {
+      BEncEocIfNec (b);
+    l = crlEntryExtensions->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = revocationDate->BEncContent (b);
+    totalLen += l;
+
+    l = userCertificate.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // CRLToSignSeqOfSeq::BEncContent
+
+
+void CRLToSignSeqOfSeq::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    userCertificate.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -135);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    revocationDate = new Time;
+    revocationDate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -136);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    crlEntryExtensions = new Extensions;
+    crlEntryExtensions->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -137);
+  }
+  else
+    return;
+} // CRLToSignSeqOfSeq::BDecContent
+
+AsnLen CRLToSignSeqOfSeq::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CRLToSignSeqOfSeq::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CRLToSignSeqOfSeq::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -138);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int CRLToSignSeqOfSeq::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int CRLToSignSeqOfSeq::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void CRLToSignSeqOfSeq::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "userCertificate ";
+    os << userCertificate;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (revocationDate))
+  {
+    Indent (os, indentG);
+    os << "revocationDate ";
+    os << *revocationDate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "revocationDate ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (crlEntryExtensions))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "crlEntryExtensions ";
+    os << *crlEntryExtensions;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "crlEntryExtensions ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // CRLToSignSeqOfSeq::Print
+
+
+AsnType *CRLToSignSeqOf::Clone() const
+{
+  return new CRLToSignSeqOf;
+}
+
+AsnType *CRLToSignSeqOf::Copy() const
+{
+  return new CRLToSignSeqOf (*this);
+}
+
+AsnLen CRLToSignSeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CRLToSignSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CRLToSignSeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -139);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+CRLToSignSeqOf::CRLToSignSeqOf (const CRLToSignSeqOf &)
+{
+  Asn1Error << "use of incompletely defined CRLToSignSeqOf::CRLToSignSeqOf (const CRLToSignSeqOf &)" << endl;
+  abort();
+}
+
+CRLToSignSeqOf::~CRLToSignSeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+CRLToSignSeqOf &CRLToSignSeqOf::operator = (const CRLToSignSeqOf &that)
+#else // SNACC_DEEP_COPY
+CRLToSignSeqOf &CRLToSignSeqOf::operator = (const CRLToSignSeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CRLToSignSeqOf &CRLToSignSeqOf::operator = (const CRLToSignSeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void CRLToSignSeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  CRLToSignSeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // CRLToSignSeqOf::SetCurrElmt
+
+
+unsigned long int  CRLToSignSeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // CRLToSignSeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+CRLToSignSeqOfSeq *CRLToSignSeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new CRLToSignSeqOfSeq;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CRLToSignSeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+CRLToSignSeqOfSeq  *CRLToSignSeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CRLToSignSeqOfSeq;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CRLToSignSeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CRLToSignSeqOfSeq  *CRLToSignSeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CRLToSignSeqOfSeq;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CRLToSignSeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CRLToSignSeqOfSeq *CRLToSignSeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CRLToSignSeqOfSeq;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CRLToSignSeqOf::InsertAfter
+
+
+CRLToSignSeqOf  &CRLToSignSeqOf::AppendCopy (CRLToSignSeqOfSeq &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CRLToSignSeqOfSeq;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+CRLToSignSeqOf  &CRLToSignSeqOf::PrependCopy (CRLToSignSeqOfSeq &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CRLToSignSeqOfSeq;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // CRLToSignSeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CRLToSignSeqOf &CRLToSignSeqOf::InsertBeforeAndCopy (CRLToSignSeqOfSeq &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CRLToSignSeqOfSeq;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // CRLToSignSeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CRLToSignSeqOf  &CRLToSignSeqOf::InsertAfterAndCopy (CRLToSignSeqOfSeq &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CRLToSignSeqOfSeq;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // CRLToSignSeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void CRLToSignSeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen CRLToSignSeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // CRLToSignSeqOf::BEncContent
+
+
+void  CRLToSignSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    CRLToSignSeqOfSeq *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -140);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // CRLToSignSeqOf::BDecContent
+
+
+CertificateToSign::CertificateToSign()
+{
+  version = NULL;
+#if TCL
+  signature = new AlgorithmIdentifier;
+#else
+  signature = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  issuer = new Name;
+#else
+  issuer = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  validity = new Validity;
+#else
+  validity = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  subject = new Name;
+#else
+  subject = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  subjectPublicKeyInfo = new SubjectPublicKeyInfo;
+#else
+  subjectPublicKeyInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  issuerUniqueIdentifier = NULL;
+  subjectUniqueIdentifier = NULL;
+  extensions = NULL;
+}
+
+CertificateToSign::CertificateToSign (const CertificateToSign &)
+{
+  Asn1Error << "use of incompletely defined CertificateToSign::CertificateToSign (const CertificateToSign &)" << endl;
+  abort();
+}
+
+CertificateToSign::~CertificateToSign()
+{
+  delete version;
+  delete signature;
+  delete issuer;
+  delete validity;
+  delete subject;
+  delete subjectPublicKeyInfo;
+  delete issuerUniqueIdentifier;
+  delete subjectUniqueIdentifier;
+  delete extensions;
+}
+
+AsnType *CertificateToSign::Clone() const
+{
+  return new CertificateToSign;
+}
+
+AsnType *CertificateToSign::Copy() const
+{
+  return new CertificateToSign (*this);
+}
+
+#if SNACC_DEEP_COPY
+CertificateToSign &CertificateToSign::operator = (const CertificateToSign &that)
+#else // SNACC_DEEP_COPY
+CertificateToSign &CertificateToSign::operator = (const CertificateToSign &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.version)
+    {
+      if (!version)
+        version = new Version;
+      *version = *that.version;
+    }
+    else
+    {
+      delete version;
+      version = NULL;
+    }
+    serialNumber = that.serialNumber;
+    if (that.signature)
+    {
+      if (!signature)
+        signature = new AlgorithmIdentifier;
+      *signature = *that.signature;
+    }
+    else
+    {
+      delete signature;
+      signature = NULL;
+    }
+    if (that.issuer)
+    {
+      if (!issuer)
+        issuer = new Name;
+      *issuer = *that.issuer;
+    }
+    else
+    {
+      delete issuer;
+      issuer = NULL;
+    }
+    if (that.validity)
+    {
+      if (!validity)
+        validity = new Validity;
+      *validity = *that.validity;
+    }
+    else
+    {
+      delete validity;
+      validity = NULL;
+    }
+    if (that.subject)
+    {
+      if (!subject)
+        subject = new Name;
+      *subject = *that.subject;
+    }
+    else
+    {
+      delete subject;
+      subject = NULL;
+    }
+    if (that.subjectPublicKeyInfo)
+    {
+      if (!subjectPublicKeyInfo)
+        subjectPublicKeyInfo = new SubjectPublicKeyInfo;
+      *subjectPublicKeyInfo = *that.subjectPublicKeyInfo;
+    }
+    else
+    {
+      delete subjectPublicKeyInfo;
+      subjectPublicKeyInfo = NULL;
+    }
+    if (that.issuerUniqueIdentifier)
+    {
+      if (!issuerUniqueIdentifier)
+        issuerUniqueIdentifier = new UniqueIdentifier;
+      *issuerUniqueIdentifier = *that.issuerUniqueIdentifier;
+    }
+    else
+    {
+      delete issuerUniqueIdentifier;
+      issuerUniqueIdentifier = NULL;
+    }
+    if (that.subjectUniqueIdentifier)
+    {
+      if (!subjectUniqueIdentifier)
+        subjectUniqueIdentifier = new UniqueIdentifier;
+      *subjectUniqueIdentifier = *that.subjectUniqueIdentifier;
+    }
+    else
+    {
+      delete subjectUniqueIdentifier;
+      subjectUniqueIdentifier = NULL;
+    }
+    if (that.extensions)
+    {
+      if (!extensions)
+        extensions = new Extensions;
+      *extensions = *that.extensions;
+    }
+    else
+    {
+      delete extensions;
+      extensions = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificateToSign &CertificateToSign::operator = (const CertificateToSign &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+CertificateToSign::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (extensions))
+  {
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+    l = extensions->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 3);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (subjectUniqueIdentifier))
+  {
+    l = subjectUniqueIdentifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 2);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (issuerUniqueIdentifier))
+  {
+    l = issuerUniqueIdentifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = subjectPublicKeyInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = subject->BEncContent (b);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = validity->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = issuer->BEncContent (b);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = signature->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = serialNumber.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (version))
+  {
+      BEncEocIfNec (b);
+    l = version->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // CertificateToSign::BEncContent
+
+
+void CertificateToSign::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if (tag1 != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -141);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    version = new Version;
+    version->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    serialNumber.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -142);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signature = new AlgorithmIdentifier;
+    signature->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -143);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuer = new Name;
+    issuer->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -144);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    validity = new Validity;
+    validity->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -145);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    subject = new Name;
+    subject->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -146);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    subjectPublicKeyInfo = new SubjectPublicKeyInfo;
+    subjectPublicKeyInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -147);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuerUniqueIdentifier = new UniqueIdentifier;
+    issuerUniqueIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 2))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    subjectUniqueIdentifier = new UniqueIdentifier;
+    subjectUniqueIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 3)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -148);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    extensions = new Extensions;
+    extensions->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -149);
+  }
+  else
+    return;
+} // CertificateToSign::BDecContent
+
+AsnLen CertificateToSign::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CertificateToSign::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CertificateToSign::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -150);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int CertificateToSign::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int CertificateToSign::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void CertificateToSign::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (version))
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << *version;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "serialNumber ";
+    os << serialNumber;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (signature))
+  {
+    Indent (os, indentG);
+    os << "signature ";
+    os << *signature;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "signature ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (issuer))
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << *issuer;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (validity))
+  {
+    Indent (os, indentG);
+    os << "validity ";
+    os << *validity;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "validity ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (subject))
+  {
+    Indent (os, indentG);
+    os << "subject ";
+    os << *subject;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "subject ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (subjectPublicKeyInfo))
+  {
+    Indent (os, indentG);
+    os << "subjectPublicKeyInfo ";
+    os << *subjectPublicKeyInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "subjectPublicKeyInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (issuerUniqueIdentifier))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "issuerUniqueIdentifier ";
+    os << *issuerUniqueIdentifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "issuerUniqueIdentifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (subjectUniqueIdentifier))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "subjectUniqueIdentifier ";
+    os << *subjectUniqueIdentifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "subjectUniqueIdentifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (extensions))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "extensions ";
+    os << *extensions;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "extensions ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // CertificateToSign::Print
+
+
+CRLToSign::CRLToSign()
+{
+  version = NULL;
+#if TCL
+  signature = new AlgorithmIdentifier;
+#else
+  signature = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  issuer = new Name;
+#else
+  issuer = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  thisUpdate = new Time;
+#else
+  thisUpdate = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  nextUpdate = NULL;
+  revokedCertificates = NULL;
+  crlExtensions = NULL;
+}
+
+CRLToSign::CRLToSign (const CRLToSign &)
+{
+  Asn1Error << "use of incompletely defined CRLToSign::CRLToSign (const CRLToSign &)" << endl;
+  abort();
+}
+
+CRLToSign::~CRLToSign()
+{
+  delete version;
+  delete signature;
+  delete issuer;
+  delete thisUpdate;
+  delete nextUpdate;
+  delete revokedCertificates;
+  delete crlExtensions;
+}
+
+AsnType *CRLToSign::Clone() const
+{
+  return new CRLToSign;
+}
+
+AsnType *CRLToSign::Copy() const
+{
+  return new CRLToSign (*this);
+}
+
+#if SNACC_DEEP_COPY
+CRLToSign &CRLToSign::operator = (const CRLToSign &that)
+#else // SNACC_DEEP_COPY
+CRLToSign &CRLToSign::operator = (const CRLToSign &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.version)
+    {
+      if (!version)
+        version = new Version;
+      *version = *that.version;
+    }
+    else
+    {
+      delete version;
+      version = NULL;
+    }
+    if (that.signature)
+    {
+      if (!signature)
+        signature = new AlgorithmIdentifier;
+      *signature = *that.signature;
+    }
+    else
+    {
+      delete signature;
+      signature = NULL;
+    }
+    if (that.issuer)
+    {
+      if (!issuer)
+        issuer = new Name;
+      *issuer = *that.issuer;
+    }
+    else
+    {
+      delete issuer;
+      issuer = NULL;
+    }
+    if (that.thisUpdate)
+    {
+      if (!thisUpdate)
+        thisUpdate = new Time;
+      *thisUpdate = *that.thisUpdate;
+    }
+    else
+    {
+      delete thisUpdate;
+      thisUpdate = NULL;
+    }
+    if (that.nextUpdate)
+    {
+      if (!nextUpdate)
+        nextUpdate = new Time;
+      *nextUpdate = *that.nextUpdate;
+    }
+    else
+    {
+      delete nextUpdate;
+      nextUpdate = NULL;
+    }
+    if (that.revokedCertificates)
+    {
+      if (!revokedCertificates)
+        revokedCertificates = new CRLToSignSeqOf;
+      *revokedCertificates = *that.revokedCertificates;
+    }
+    else
+    {
+      delete revokedCertificates;
+      revokedCertificates = NULL;
+    }
+    if (that.crlExtensions)
+    {
+      if (!crlExtensions)
+        crlExtensions = new Extensions;
+      *crlExtensions = *that.crlExtensions;
+    }
+    else
+    {
+      delete crlExtensions;
+      crlExtensions = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CRLToSign &CRLToSign::operator = (const CRLToSign &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+CRLToSign::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (crlExtensions))
+  {
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+    l = crlExtensions->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (revokedCertificates))
+  {
+      BEncEocIfNec (b);
+    l = revokedCertificates->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (nextUpdate))
+  {
+    l = nextUpdate->BEncContent (b);
+    totalLen += l;
+  }
+
+    l = thisUpdate->BEncContent (b);
+    totalLen += l;
+
+    l = issuer->BEncContent (b);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = signature->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  if (NOT_NULL (version))
+  {
+    l = version->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // CRLToSign::BEncContent
+
+
+void CRLToSign::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version = new Version;
+    version->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signature = new AlgorithmIdentifier;
+    signature->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -151);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuer = new Name;
+    issuer->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -152);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    thisUpdate = new Time;
+    thisUpdate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -153);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    nextUpdate = new Time;
+    nextUpdate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    revokedCertificates = new CRLToSignSeqOf;
+    revokedCertificates->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -154);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    crlExtensions = new Extensions;
+    crlExtensions->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -155);
+  }
+  else
+    return;
+} // CRLToSign::BDecContent
+
+AsnLen CRLToSign::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CRLToSign::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CRLToSign::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -156);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int CRLToSign::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int CRLToSign::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void CRLToSign::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (version))
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << *version;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (signature))
+  {
+    Indent (os, indentG);
+    os << "signature ";
+    os << *signature;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "signature ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (issuer))
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << *issuer;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (thisUpdate))
+  {
+    Indent (os, indentG);
+    os << "thisUpdate ";
+    os << *thisUpdate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "thisUpdate ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (nextUpdate))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "nextUpdate ";
+    os << *nextUpdate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "nextUpdate ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (revokedCertificates))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "revokedCertificates ";
+    os << *revokedCertificates;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "revokedCertificates ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (crlExtensions))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "crlExtensions ";
+    os << *crlExtensions;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "crlExtensions ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // CRLToSign::Print
+
+
+AttributeCertificateInfo::AttributeCertificateInfo()
+{
+  version = NULL;
+#if TCL
+  subject = new AttributeCertificateInfoChoice;
+#else
+  subject = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  signature = new AlgorithmIdentifier;
+#else
+  signature = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  attCertValidityPeriod = new AttCertValidityPeriod;
+#else
+  attCertValidityPeriod = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  issuerUniqueID = NULL;
+  extensions = NULL;
+}
+
+AttributeCertificateInfo::AttributeCertificateInfo (const AttributeCertificateInfo &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificateInfo::AttributeCertificateInfo (const AttributeCertificateInfo &)" << endl;
+  abort();
+}
+
+AttributeCertificateInfo::~AttributeCertificateInfo()
+{
+  delete version;
+  delete subject;
+  delete signature;
+  delete attCertValidityPeriod;
+  delete issuerUniqueID;
+  delete extensions;
+}
+
+AsnType *AttributeCertificateInfo::Clone() const
+{
+  return new AttributeCertificateInfo;
+}
+
+AsnType *AttributeCertificateInfo::Copy() const
+{
+  return new AttributeCertificateInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttributeCertificateInfo &AttributeCertificateInfo::operator = (const AttributeCertificateInfo &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificateInfo &AttributeCertificateInfo::operator = (const AttributeCertificateInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.version)
+    {
+      if (!version)
+        version = new Version;
+      *version = *that.version;
+    }
+    else
+    {
+      delete version;
+      version = NULL;
+    }
+    if (that.subject)
+    {
+      if (!subject)
+        subject = new AttributeCertificateInfoChoice;
+      *subject = *that.subject;
+    }
+    else
+    {
+      delete subject;
+      subject = NULL;
+    }
+    issuer = that.issuer;
+    if (that.signature)
+    {
+      if (!signature)
+        signature = new AlgorithmIdentifier;
+      *signature = *that.signature;
+    }
+    else
+    {
+      delete signature;
+      signature = NULL;
+    }
+    serialNumber = that.serialNumber;
+    if (that.attCertValidityPeriod)
+    {
+      if (!attCertValidityPeriod)
+        attCertValidityPeriod = new AttCertValidityPeriod;
+      *attCertValidityPeriod = *that.attCertValidityPeriod;
+    }
+    else
+    {
+      delete attCertValidityPeriod;
+      attCertValidityPeriod = NULL;
+    }
+    attributes = that.attributes;
+    if (that.issuerUniqueID)
+    {
+      if (!issuerUniqueID)
+        issuerUniqueID = new UniqueIdentifier;
+      *issuerUniqueID = *that.issuerUniqueID;
+    }
+    else
+    {
+      delete issuerUniqueID;
+      issuerUniqueID = NULL;
+    }
+    if (that.extensions)
+    {
+      if (!extensions)
+        extensions = new Extensions;
+      *extensions = *that.extensions;
+    }
+    else
+    {
+      delete extensions;
+      extensions = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificateInfo &AttributeCertificateInfo::operator = (const AttributeCertificateInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttributeCertificateInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (extensions))
+  {
+      BEncEocIfNec (b);
+    l = extensions->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (issuerUniqueID))
+  {
+    l = issuerUniqueID->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = attributes.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = attCertValidityPeriod->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = serialNumber.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = signature->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = issuer.BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+    l = subject->BEncContent (b);
+    totalLen += l;
+
+  if (NOT_NULL (version))
+  {
+    l = version->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // AttributeCertificateInfo::BEncContent
+
+
+void AttributeCertificateInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    version = new Version;
+    version->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    subject = new AttributeCertificateInfoChoice;
+    subject->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -157);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuer.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -158);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signature = new AlgorithmIdentifier;
+    signature->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -159);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    serialNumber.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -160);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    attCertValidityPeriod = new AttCertValidityPeriod;
+    attCertValidityPeriod->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -161);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    attributes.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -162);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuerUniqueID = new UniqueIdentifier;
+    issuerUniqueID->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    extensions = new Extensions;
+    extensions->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -163);
+  }
+  else
+    return;
+} // AttributeCertificateInfo::BDecContent
+
+AsnLen AttributeCertificateInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributeCertificateInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributeCertificateInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -164);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AttributeCertificateInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttributeCertificateInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttributeCertificateInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (version))
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << *version;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "version ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (subject))
+  {
+    Indent (os, indentG);
+    os << "subject ";
+    os << *subject;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "subject ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << issuer;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (signature))
+  {
+    Indent (os, indentG);
+    os << "signature ";
+    os << *signature;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "signature ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "serialNumber ";
+    os << serialNumber;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (attCertValidityPeriod))
+  {
+    Indent (os, indentG);
+    os << "attCertValidityPeriod ";
+    os << *attCertValidityPeriod;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "attCertValidityPeriod ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "attributes ";
+    os << attributes;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (issuerUniqueID))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "issuerUniqueID ";
+    os << *issuerUniqueID;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "issuerUniqueID ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (extensions))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "extensions ";
+    os << *extensions;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "extensions ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AttributeCertificateInfo::Print
+
+
+Certificate::Certificate()
+{
+#if TCL
+  certificateToSign = new CertificateToSign;
+#else
+  certificateToSign = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  algorithmIdentifier = new AlgorithmIdentifier;
+#else
+  algorithmIdentifier = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+Certificate::Certificate (const Certificate &)
+{
+  Asn1Error << "use of incompletely defined Certificate::Certificate (const Certificate &)" << endl;
+  abort();
+}
+
+Certificate::~Certificate()
+{
+  delete certificateToSign;
+  delete algorithmIdentifier;
+}
+
+AsnType *Certificate::Clone() const
+{
+  return new Certificate;
+}
+
+AsnType *Certificate::Copy() const
+{
+  return new Certificate (*this);
+}
+
+#if SNACC_DEEP_COPY
+Certificate &Certificate::operator = (const Certificate &that)
+#else // SNACC_DEEP_COPY
+Certificate &Certificate::operator = (const Certificate &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.certificateToSign)
+    {
+      if (!certificateToSign)
+        certificateToSign = new CertificateToSign;
+      *certificateToSign = *that.certificateToSign;
+    }
+    else
+    {
+      delete certificateToSign;
+      certificateToSign = NULL;
+    }
+    if (that.algorithmIdentifier)
+    {
+      if (!algorithmIdentifier)
+        algorithmIdentifier = new AlgorithmIdentifier;
+      *algorithmIdentifier = *that.algorithmIdentifier;
+    }
+    else
+    {
+      delete algorithmIdentifier;
+      algorithmIdentifier = NULL;
+    }
+    signatureValue = that.signatureValue;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Certificate &Certificate::operator = (const Certificate &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+Certificate::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = signatureValue.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = algorithmIdentifier->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = certificateToSign->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // Certificate::BEncContent
+
+
+void Certificate::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    certificateToSign = new CertificateToSign;
+    certificateToSign->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -165);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    algorithmIdentifier = new AlgorithmIdentifier;
+    algorithmIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -166);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signatureValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -167);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -168);
+  }
+  else
+    return;
+} // Certificate::BDecContent
+
+AsnLen Certificate::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void Certificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "Certificate::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -169);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int Certificate::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int Certificate::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void Certificate::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (certificateToSign))
+  {
+    Indent (os, indentG);
+    os << "certificateToSign ";
+    os << *certificateToSign;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "certificateToSign ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (algorithmIdentifier))
+  {
+    Indent (os, indentG);
+    os << "algorithmIdentifier ";
+    os << *algorithmIdentifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "algorithmIdentifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "signatureValue ";
+    os << signatureValue;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // Certificate::Print
+
+
+AsnType *CrossCertificates::Clone() const
+{
+  return new CrossCertificates;
+}
+
+AsnType *CrossCertificates::Copy() const
+{
+  return new CrossCertificates (*this);
+}
+
+AsnLen CrossCertificates::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+  return l;
+}
+
+void CrossCertificates::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+  {
+    Asn1Error << "CrossCertificates::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -170);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+CrossCertificates::CrossCertificates (const CrossCertificates &)
+{
+  Asn1Error << "use of incompletely defined CrossCertificates::CrossCertificates (const CrossCertificates &)" << endl;
+  abort();
+}
+
+CrossCertificates::~CrossCertificates()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+CrossCertificates &CrossCertificates::operator = (const CrossCertificates &that)
+#else // SNACC_DEEP_COPY
+CrossCertificates &CrossCertificates::operator = (const CrossCertificates &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CrossCertificates &CrossCertificates::operator = (const CrossCertificates &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void CrossCertificates::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  CrossCertificates::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // CrossCertificates::SetCurrElmt
+
+
+unsigned long int  CrossCertificates::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // CrossCertificates::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+Certificate *CrossCertificates::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new Certificate;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CrossCertificates::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+Certificate  *CrossCertificates::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Certificate;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CrossCertificates::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+Certificate  *CrossCertificates::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Certificate;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CrossCertificates::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+Certificate *CrossCertificates::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Certificate;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CrossCertificates::InsertAfter
+
+
+CrossCertificates  &CrossCertificates::AppendCopy (Certificate &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Certificate;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+CrossCertificates  &CrossCertificates::PrependCopy (Certificate &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Certificate;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // CrossCertificates::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CrossCertificates &CrossCertificates::InsertBeforeAndCopy (Certificate &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Certificate;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // CrossCertificates::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CrossCertificates  &CrossCertificates::InsertAfterAndCopy (Certificate &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Certificate;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // CrossCertificates::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void CrossCertificates::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen CrossCertificates::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    {
+      int iii,icount;
+      CSM_Buffer **tmpEnc=NULL;
+      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
+      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
+      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
+      {
+      BEncEocIfNec (b);
+        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
+    elmtLen += BEncConsLen (outputBuf, elmtLen);
+
+    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
+        ENCODE_BUF2(tmpEnc[iii]);
+      }
+      vdasnacc_sortSetOf(tmpEnc, icount);
+      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
+            SM_WriteToAsnBuf(tmpEnc[iii], b);
+      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
+       free(tmpEnc);
+    }
+        totalLen += elmtLen;
+    return totalLen;
+} // CrossCertificates::BEncContent
+
+
+void  CrossCertificates::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    Certificate *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -171);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // CrossCertificates::BDecContent
+
+
+CertificatePair::CertificatePair()
+{
+  forward = NULL;
+  reverse = NULL;
+}
+
+CertificatePair::CertificatePair (const CertificatePair &)
+{
+  Asn1Error << "use of incompletely defined CertificatePair::CertificatePair (const CertificatePair &)" << endl;
+  abort();
+}
+
+CertificatePair::~CertificatePair()
+{
+  delete forward;
+  delete reverse;
+}
+
+AsnType *CertificatePair::Clone() const
+{
+  return new CertificatePair;
+}
+
+AsnType *CertificatePair::Copy() const
+{
+  return new CertificatePair (*this);
+}
+
+#if SNACC_DEEP_COPY
+CertificatePair &CertificatePair::operator = (const CertificatePair &that)
+#else // SNACC_DEEP_COPY
+CertificatePair &CertificatePair::operator = (const CertificatePair &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.forward)
+    {
+      if (!forward)
+        forward = new Certificate;
+      *forward = *that.forward;
+    }
+    else
+    {
+      delete forward;
+      forward = NULL;
+    }
+    if (that.reverse)
+    {
+      if (!reverse)
+        reverse = new Certificate;
+      *reverse = *that.reverse;
+    }
+    else
+    {
+      delete reverse;
+      reverse = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificatePair &CertificatePair::operator = (const CertificatePair &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+CertificatePair::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (reverse))
+  {
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+    l = reverse->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (forward))
+  {
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+    l = forward->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // CertificatePair::BEncContent
+
+
+void CertificatePair::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -172);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    forward = new Certificate;
+    forward->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -173);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    reverse = new Certificate;
+    reverse->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -174);
+  }
+  else
+    return;
+} // CertificatePair::BDecContent
+
+AsnLen CertificatePair::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CertificatePair::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CertificatePair::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -175);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int CertificatePair::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int CertificatePair::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void CertificatePair::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (forward))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "forward ";
+    os << *forward;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "forward ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (reverse))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "reverse ";
+    os << *reverse;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "reverse ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // CertificatePair::Print
+
+
+CertificateList::CertificateList()
+{
+#if TCL
+  crlToSign = new CRLToSign;
+#else
+  crlToSign = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  algorithmIdentifier = new AlgorithmIdentifier;
+#else
+  algorithmIdentifier = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+CertificateList::CertificateList (const CertificateList &)
+{
+  Asn1Error << "use of incompletely defined CertificateList::CertificateList (const CertificateList &)" << endl;
+  abort();
+}
+
+CertificateList::~CertificateList()
+{
+  delete crlToSign;
+  delete algorithmIdentifier;
+}
+
+AsnType *CertificateList::Clone() const
+{
+  return new CertificateList;
+}
+
+AsnType *CertificateList::Copy() const
+{
+  return new CertificateList (*this);
+}
+
+#if SNACC_DEEP_COPY
+CertificateList &CertificateList::operator = (const CertificateList &that)
+#else // SNACC_DEEP_COPY
+CertificateList &CertificateList::operator = (const CertificateList &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.crlToSign)
+    {
+      if (!crlToSign)
+        crlToSign = new CRLToSign;
+      *crlToSign = *that.crlToSign;
+    }
+    else
+    {
+      delete crlToSign;
+      crlToSign = NULL;
+    }
+    if (that.algorithmIdentifier)
+    {
+      if (!algorithmIdentifier)
+        algorithmIdentifier = new AlgorithmIdentifier;
+      *algorithmIdentifier = *that.algorithmIdentifier;
+    }
+    else
+    {
+      delete algorithmIdentifier;
+      algorithmIdentifier = NULL;
+    }
+    signatureValue = that.signatureValue;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificateList &CertificateList::operator = (const CertificateList &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+CertificateList::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = signatureValue.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = algorithmIdentifier->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = crlToSign->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // CertificateList::BEncContent
+
+
+void CertificateList::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    crlToSign = new CRLToSign;
+    crlToSign->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -176);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    algorithmIdentifier = new AlgorithmIdentifier;
+    algorithmIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -177);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signatureValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -178);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -179);
+  }
+  else
+    return;
+} // CertificateList::BDecContent
+
+AsnLen CertificateList::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CertificateList::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CertificateList::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -180);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int CertificateList::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int CertificateList::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void CertificateList::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (crlToSign))
+  {
+    Indent (os, indentG);
+    os << "crlToSign ";
+    os << *crlToSign;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "crlToSign ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (algorithmIdentifier))
+  {
+    Indent (os, indentG);
+    os << "algorithmIdentifier ";
+    os << *algorithmIdentifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "algorithmIdentifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "signatureValue ";
+    os << signatureValue;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // CertificateList::Print
+
+
+AttributeCertificate::AttributeCertificate()
+{
+#if TCL
+  attributeCertificateInfo = new AttributeCertificateInfo;
+#else
+  attributeCertificateInfo = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+#if TCL
+  algorithmIdentifier = new AlgorithmIdentifier;
+#else
+  algorithmIdentifier = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+AttributeCertificate::AttributeCertificate (const AttributeCertificate &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificate::AttributeCertificate (const AttributeCertificate &)" << endl;
+  abort();
+}
+
+AttributeCertificate::~AttributeCertificate()
+{
+  delete attributeCertificateInfo;
+  delete algorithmIdentifier;
+}
+
+AsnType *AttributeCertificate::Clone() const
+{
+  return new AttributeCertificate;
+}
+
+AsnType *AttributeCertificate::Copy() const
+{
+  return new AttributeCertificate (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttributeCertificate &AttributeCertificate::operator = (const AttributeCertificate &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificate &AttributeCertificate::operator = (const AttributeCertificate &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.attributeCertificateInfo)
+    {
+      if (!attributeCertificateInfo)
+        attributeCertificateInfo = new AttributeCertificateInfo;
+      *attributeCertificateInfo = *that.attributeCertificateInfo;
+    }
+    else
+    {
+      delete attributeCertificateInfo;
+      attributeCertificateInfo = NULL;
+    }
+    if (that.algorithmIdentifier)
+    {
+      if (!algorithmIdentifier)
+        algorithmIdentifier = new AlgorithmIdentifier;
+      *algorithmIdentifier = *that.algorithmIdentifier;
+    }
+    else
+    {
+      delete algorithmIdentifier;
+      algorithmIdentifier = NULL;
+    }
+    signatureValue = that.signatureValue;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificate &AttributeCertificate::operator = (const AttributeCertificate &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttributeCertificate::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = signatureValue.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = algorithmIdentifier->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+      BEncEocIfNec (b);
+    l = attributeCertificateInfo->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // AttributeCertificate::BEncContent
+
+
+void AttributeCertificate::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    attributeCertificateInfo = new AttributeCertificateInfo;
+    attributeCertificateInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -181);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    algorithmIdentifier = new AlgorithmIdentifier;
+    algorithmIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -182);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    signatureValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -183);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -184);
+  }
+  else
+    return;
+} // AttributeCertificate::BDecContent
+
+AsnLen AttributeCertificate::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributeCertificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributeCertificate::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -185);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AttributeCertificate::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttributeCertificate::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttributeCertificate::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (attributeCertificateInfo))
+  {
+    Indent (os, indentG);
+    os << "attributeCertificateInfo ";
+    os << *attributeCertificateInfo;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "attributeCertificateInfo ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (algorithmIdentifier))
+  {
+    Indent (os, indentG);
+    os << "algorithmIdentifier ";
+    os << *algorithmIdentifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "algorithmIdentifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "signatureValue ";
+    os << signatureValue;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AttributeCertificate::Print
+
+
+AsnType *CertificationPathSeqOf::Clone() const
+{
+  return new CertificationPathSeqOf;
+}
+
+AsnType *CertificationPathSeqOf::Copy() const
+{
+  return new CertificationPathSeqOf (*this);
+}
+
+AsnLen CertificationPathSeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CertificationPathSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CertificationPathSeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -186);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+CertificationPathSeqOf::CertificationPathSeqOf (const CertificationPathSeqOf &)
+{
+  Asn1Error << "use of incompletely defined CertificationPathSeqOf::CertificationPathSeqOf (const CertificationPathSeqOf &)" << endl;
+  abort();
+}
+
+CertificationPathSeqOf::~CertificationPathSeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+CertificationPathSeqOf &CertificationPathSeqOf::operator = (const CertificationPathSeqOf &that)
+#else // SNACC_DEEP_COPY
+CertificationPathSeqOf &CertificationPathSeqOf::operator = (const CertificationPathSeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificationPathSeqOf &CertificationPathSeqOf::operator = (const CertificationPathSeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void CertificationPathSeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  CertificationPathSeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // CertificationPathSeqOf::SetCurrElmt
+
+
+unsigned long int  CertificationPathSeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // CertificationPathSeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+CertificatePair *CertificationPathSeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new CertificatePair;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificationPathSeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+CertificatePair  *CertificationPathSeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificatePair;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificationPathSeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertificatePair  *CertificationPathSeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificatePair;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificationPathSeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertificatePair *CertificationPathSeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificatePair;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificationPathSeqOf::InsertAfter
+
+
+CertificationPathSeqOf  &CertificationPathSeqOf::AppendCopy (CertificatePair &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificatePair;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+CertificationPathSeqOf  &CertificationPathSeqOf::PrependCopy (CertificatePair &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificatePair;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificationPathSeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertificationPathSeqOf &CertificationPathSeqOf::InsertBeforeAndCopy (CertificatePair &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificatePair;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificationPathSeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertificationPathSeqOf  &CertificationPathSeqOf::InsertAfterAndCopy (CertificatePair &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertificatePair;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificationPathSeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void CertificationPathSeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen CertificationPathSeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // CertificationPathSeqOf::BEncContent
+
+
+void  CertificationPathSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    CertificatePair *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -187);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // CertificationPathSeqOf::BDecContent
+
+
+AsnType *ForwardCertificationPath::Clone() const
+{
+  return new ForwardCertificationPath;
+}
+
+AsnType *ForwardCertificationPath::Copy() const
+{
+  return new ForwardCertificationPath (*this);
+}
+
+AsnLen ForwardCertificationPath::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ForwardCertificationPath::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ForwardCertificationPath::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -188);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+ForwardCertificationPath::ForwardCertificationPath (const ForwardCertificationPath &)
+{
+  Asn1Error << "use of incompletely defined ForwardCertificationPath::ForwardCertificationPath (const ForwardCertificationPath &)" << endl;
+  abort();
+}
+
+ForwardCertificationPath::~ForwardCertificationPath()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+ForwardCertificationPath &ForwardCertificationPath::operator = (const ForwardCertificationPath &that)
+#else // SNACC_DEEP_COPY
+ForwardCertificationPath &ForwardCertificationPath::operator = (const ForwardCertificationPath &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ForwardCertificationPath &ForwardCertificationPath::operator = (const ForwardCertificationPath &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void ForwardCertificationPath::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  ForwardCertificationPath::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // ForwardCertificationPath::SetCurrElmt
+
+
+unsigned long int  ForwardCertificationPath::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // ForwardCertificationPath::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+CrossCertificates *ForwardCertificationPath::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new CrossCertificates;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ForwardCertificationPath::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+CrossCertificates  *ForwardCertificationPath::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CrossCertificates;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ForwardCertificationPath::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CrossCertificates  *ForwardCertificationPath::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CrossCertificates;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ForwardCertificationPath::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CrossCertificates *ForwardCertificationPath::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CrossCertificates;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ForwardCertificationPath::InsertAfter
+
+
+ForwardCertificationPath  &ForwardCertificationPath::AppendCopy (CrossCertificates &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CrossCertificates;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+ForwardCertificationPath  &ForwardCertificationPath::PrependCopy (CrossCertificates &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CrossCertificates;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // ForwardCertificationPath::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ForwardCertificationPath &ForwardCertificationPath::InsertBeforeAndCopy (CrossCertificates &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CrossCertificates;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // ForwardCertificationPath::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ForwardCertificationPath  &ForwardCertificationPath::InsertAfterAndCopy (CrossCertificates &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CrossCertificates;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // ForwardCertificationPath::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void ForwardCertificationPath::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen ForwardCertificationPath::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // ForwardCertificationPath::BEncContent
+
+
+void  ForwardCertificationPath::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    CrossCertificates *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -189);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // ForwardCertificationPath::BDecContent
+
+
+ACPathData::ACPathData()
+{
+  certificate = NULL;
+  attributeCertificate = NULL;
+}
+
+ACPathData::ACPathData (const ACPathData &)
+{
+  Asn1Error << "use of incompletely defined ACPathData::ACPathData (const ACPathData &)" << endl;
+  abort();
+}
+
+ACPathData::~ACPathData()
+{
+  delete certificate;
+  delete attributeCertificate;
+}
+
+AsnType *ACPathData::Clone() const
+{
+  return new ACPathData;
+}
+
+AsnType *ACPathData::Copy() const
+{
+  return new ACPathData (*this);
+}
+
+#if SNACC_DEEP_COPY
+ACPathData &ACPathData::operator = (const ACPathData &that)
+#else // SNACC_DEEP_COPY
+ACPathData &ACPathData::operator = (const ACPathData &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.certificate)
+    {
+      if (!certificate)
+        certificate = new Certificate;
+      *certificate = *that.certificate;
+    }
+    else
+    {
+      delete certificate;
+      certificate = NULL;
+    }
+    if (that.attributeCertificate)
+    {
+      if (!attributeCertificate)
+        attributeCertificate = new AttributeCertificate;
+      *attributeCertificate = *that.attributeCertificate;
+    }
+    else
+    {
+      delete attributeCertificate;
+      attributeCertificate = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ACPathData &ACPathData::operator = (const ACPathData &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+ACPathData::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (attributeCertificate))
+  {
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+    l = attributeCertificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (certificate))
+  {
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+    l = certificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // ACPathData::BEncContent
+
+
+void ACPathData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -190);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    certificate = new Certificate;
+    certificate->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -191);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    attributeCertificate = new AttributeCertificate;
+    attributeCertificate->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -192);
+  }
+  else
+    return;
+} // ACPathData::BDecContent
+
+AsnLen ACPathData::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ACPathData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ACPathData::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -193);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ACPathData::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ACPathData::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void ACPathData::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (certificate))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "certificate ";
+    os << *certificate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "certificate ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (attributeCertificate))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "attributeCertificate ";
+    os << *attributeCertificate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "attributeCertificate ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // ACPathData::Print
+
+
+AsnType *AttributeCertificationPathSeqOf::Clone() const
+{
+  return new AttributeCertificationPathSeqOf;
+}
+
+AsnType *AttributeCertificationPathSeqOf::Copy() const
+{
+  return new AttributeCertificationPathSeqOf (*this);
+}
+
+AsnLen AttributeCertificationPathSeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributeCertificationPathSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributeCertificationPathSeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -194);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+AttributeCertificationPathSeqOf::AttributeCertificationPathSeqOf (const AttributeCertificationPathSeqOf &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificationPathSeqOf::AttributeCertificationPathSeqOf (const AttributeCertificationPathSeqOf &)" << endl;
+  abort();
+}
+
+AttributeCertificationPathSeqOf::~AttributeCertificationPathSeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+AttributeCertificationPathSeqOf &AttributeCertificationPathSeqOf::operator = (const AttributeCertificationPathSeqOf &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificationPathSeqOf &AttributeCertificationPathSeqOf::operator = (const AttributeCertificationPathSeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificationPathSeqOf &AttributeCertificationPathSeqOf::operator = (const AttributeCertificationPathSeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void AttributeCertificationPathSeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  AttributeCertificationPathSeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // AttributeCertificationPathSeqOf::SetCurrElmt
+
+
+unsigned long int  AttributeCertificationPathSeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // AttributeCertificationPathSeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+ACPathData *AttributeCertificationPathSeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new ACPathData;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificationPathSeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+ACPathData  *AttributeCertificationPathSeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ACPathData;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificationPathSeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ACPathData  *AttributeCertificationPathSeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ACPathData;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificationPathSeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ACPathData *AttributeCertificationPathSeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ACPathData;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributeCertificationPathSeqOf::InsertAfter
+
+
+AttributeCertificationPathSeqOf  &AttributeCertificationPathSeqOf::AppendCopy (ACPathData &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ACPathData;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+AttributeCertificationPathSeqOf  &AttributeCertificationPathSeqOf::PrependCopy (ACPathData &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ACPathData;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificationPathSeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributeCertificationPathSeqOf &AttributeCertificationPathSeqOf::InsertBeforeAndCopy (ACPathData &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ACPathData;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificationPathSeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributeCertificationPathSeqOf  &AttributeCertificationPathSeqOf::InsertAfterAndCopy (ACPathData &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new ACPathData;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributeCertificationPathSeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void AttributeCertificationPathSeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen AttributeCertificationPathSeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // AttributeCertificationPathSeqOf::BEncContent
+
+
+void  AttributeCertificationPathSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    ACPathData *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -195);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // AttributeCertificationPathSeqOf::BDecContent
+
+
+Certificates::Certificates()
+{
+#if TCL
+  userCertificate = new Certificate;
+#else
+  userCertificate = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  certificationPath = NULL;
+}
+
+Certificates::Certificates (const Certificates &)
+{
+  Asn1Error << "use of incompletely defined Certificates::Certificates (const Certificates &)" << endl;
+  abort();
+}
+
+Certificates::~Certificates()
+{
+  delete userCertificate;
+  delete certificationPath;
+}
+
+AsnType *Certificates::Clone() const
+{
+  return new Certificates;
+}
+
+AsnType *Certificates::Copy() const
+{
+  return new Certificates (*this);
+}
+
+#if SNACC_DEEP_COPY
+Certificates &Certificates::operator = (const Certificates &that)
+#else // SNACC_DEEP_COPY
+Certificates &Certificates::operator = (const Certificates &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.userCertificate)
+    {
+      if (!userCertificate)
+        userCertificate = new Certificate;
+      *userCertificate = *that.userCertificate;
+    }
+    else
+    {
+      delete userCertificate;
+      userCertificate = NULL;
+    }
+    if (that.certificationPath)
+    {
+      if (!certificationPath)
+        certificationPath = new ForwardCertificationPath;
+      *certificationPath = *that.certificationPath;
+    }
+    else
+    {
+      delete certificationPath;
+      certificationPath = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined Certificates &Certificates::operator = (const Certificates &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+Certificates::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (certificationPath))
+  {
+      BEncEocIfNec (b);
+    l = certificationPath->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = userCertificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // Certificates::BEncContent
+
+
+void Certificates::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    userCertificate = new Certificate;
+    userCertificate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -196);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    certificationPath = new ForwardCertificationPath;
+    certificationPath->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -197);
+  }
+  else
+    return;
+} // Certificates::BDecContent
+
+AsnLen Certificates::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void Certificates::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "Certificates::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -198);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int Certificates::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int Certificates::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void Certificates::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (userCertificate))
+  {
+    Indent (os, indentG);
+    os << "userCertificate ";
+    os << *userCertificate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "userCertificate ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (certificationPath))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "certificationPath ";
+    os << *certificationPath;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "certificationPath ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // Certificates::Print
+
+
+CertificationPath::CertificationPath()
+{
+#if TCL
+  userCertificate = new Certificate;
+#else
+  userCertificate = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  theCACertificates = NULL;
+}
+
+CertificationPath::CertificationPath (const CertificationPath &)
+{
+  Asn1Error << "use of incompletely defined CertificationPath::CertificationPath (const CertificationPath &)" << endl;
+  abort();
+}
+
+CertificationPath::~CertificationPath()
+{
+  delete userCertificate;
+  delete theCACertificates;
+}
+
+AsnType *CertificationPath::Clone() const
+{
+  return new CertificationPath;
+}
+
+AsnType *CertificationPath::Copy() const
+{
+  return new CertificationPath (*this);
+}
+
+#if SNACC_DEEP_COPY
+CertificationPath &CertificationPath::operator = (const CertificationPath &that)
+#else // SNACC_DEEP_COPY
+CertificationPath &CertificationPath::operator = (const CertificationPath &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.userCertificate)
+    {
+      if (!userCertificate)
+        userCertificate = new Certificate;
+      *userCertificate = *that.userCertificate;
+    }
+    else
+    {
+      delete userCertificate;
+      userCertificate = NULL;
+    }
+    if (that.theCACertificates)
+    {
+      if (!theCACertificates)
+        theCACertificates = new CertificationPathSeqOf;
+      *theCACertificates = *that.theCACertificates;
+    }
+    else
+    {
+      delete theCACertificates;
+      theCACertificates = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificationPath &CertificationPath::operator = (const CertificationPath &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+CertificationPath::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (theCACertificates))
+  {
+      BEncEocIfNec (b);
+    l = theCACertificates->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = userCertificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // CertificationPath::BEncContent
+
+
+void CertificationPath::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    userCertificate = new Certificate;
+    userCertificate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -199);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    theCACertificates = new CertificationPathSeqOf;
+    theCACertificates->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -200);
+  }
+  else
+    return;
+} // CertificationPath::BDecContent
+
+AsnLen CertificationPath::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CertificationPath::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CertificationPath::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -201);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int CertificationPath::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int CertificationPath::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void CertificationPath::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (userCertificate))
+  {
+    Indent (os, indentG);
+    os << "userCertificate ";
+    os << *userCertificate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "userCertificate ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (theCACertificates))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "theCACertificates ";
+    os << *theCACertificates;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "theCACertificates ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // CertificationPath::Print
+
+
+AttributeCertificationPath::AttributeCertificationPath()
+{
+#if TCL
+  attributeCertificate = new AttributeCertificate;
+#else
+  attributeCertificate = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  acPath = NULL;
+}
+
+AttributeCertificationPath::AttributeCertificationPath (const AttributeCertificationPath &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificationPath::AttributeCertificationPath (const AttributeCertificationPath &)" << endl;
+  abort();
+}
+
+AttributeCertificationPath::~AttributeCertificationPath()
+{
+  delete attributeCertificate;
+  delete acPath;
+}
+
+AsnType *AttributeCertificationPath::Clone() const
+{
+  return new AttributeCertificationPath;
+}
+
+AsnType *AttributeCertificationPath::Copy() const
+{
+  return new AttributeCertificationPath (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttributeCertificationPath &AttributeCertificationPath::operator = (const AttributeCertificationPath &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificationPath &AttributeCertificationPath::operator = (const AttributeCertificationPath &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.attributeCertificate)
+    {
+      if (!attributeCertificate)
+        attributeCertificate = new AttributeCertificate;
+      *attributeCertificate = *that.attributeCertificate;
+    }
+    else
+    {
+      delete attributeCertificate;
+      attributeCertificate = NULL;
+    }
+    if (that.acPath)
+    {
+      if (!acPath)
+        acPath = new AttributeCertificationPathSeqOf;
+      *acPath = *that.acPath;
+    }
+    else
+    {
+      delete acPath;
+      acPath = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificationPath &AttributeCertificationPath::operator = (const AttributeCertificationPath &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttributeCertificationPath::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (acPath))
+  {
+      BEncEocIfNec (b);
+    l = acPath->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = attributeCertificate->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // AttributeCertificationPath::BEncContent
+
+
+void AttributeCertificationPath::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    attributeCertificate = new AttributeCertificate;
+    attributeCertificate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -202);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    acPath = new AttributeCertificationPathSeqOf;
+    acPath->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -203);
+  }
+  else
+    return;
+} // AttributeCertificationPath::BDecContent
+
+AsnLen AttributeCertificationPath::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributeCertificationPath::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributeCertificationPath::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -204);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AttributeCertificationPath::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttributeCertificationPath::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttributeCertificationPath::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (attributeCertificate))
+  {
+    Indent (os, indentG);
+    os << "attributeCertificate ";
+    os << *attributeCertificate;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "attributeCertificate ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (acPath))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "acPath ";
+    os << *acPath;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "acPath ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AttributeCertificationPath::Print
+
+
+AttributeCertificateAssertion::AttributeCertificateAssertion()
+{
+  subject = NULL;
+  issuer = NULL;
+  attCertValidity = NULL;
+  attType = NULL;
+}
+
+AttributeCertificateAssertion::AttributeCertificateAssertion (const AttributeCertificateAssertion &)
+{
+  Asn1Error << "use of incompletely defined AttributeCertificateAssertion::AttributeCertificateAssertion (const AttributeCertificateAssertion &)" << endl;
+  abort();
+}
+
+AttributeCertificateAssertion::~AttributeCertificateAssertion()
+{
+  delete subject;
+  delete issuer;
+  delete attCertValidity;
+  delete attType;
+}
+
+AsnType *AttributeCertificateAssertion::Clone() const
+{
+  return new AttributeCertificateAssertion;
+}
+
+AsnType *AttributeCertificateAssertion::Copy() const
+{
+  return new AttributeCertificateAssertion (*this);
+}
+
+#if SNACC_DEEP_COPY
+AttributeCertificateAssertion &AttributeCertificateAssertion::operator = (const AttributeCertificateAssertion &that)
+#else // SNACC_DEEP_COPY
+AttributeCertificateAssertion &AttributeCertificateAssertion::operator = (const AttributeCertificateAssertion &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.subject)
+    {
+      if (!subject)
+        subject = new AttributeCertificateAssertionChoice;
+      *subject = *that.subject;
+    }
+    else
+    {
+      delete subject;
+      subject = NULL;
+    }
+    if (that.issuer)
+    {
+      if (!issuer)
+        issuer = new Name;
+      *issuer = *that.issuer;
+    }
+    else
+    {
+      delete issuer;
+      issuer = NULL;
+    }
+    if (that.attCertValidity)
+    {
+      if (!attCertValidity)
+        attCertValidity = new GeneralizedTime;
+      *attCertValidity = *that.attCertValidity;
+    }
+    else
+    {
+      delete attCertValidity;
+      attCertValidity = NULL;
+    }
+    if (that.attType)
+    {
+      if (!attType)
+        attType = new AttributeCertificateAssertionSetOf;
+      *attType = *that.attType;
+    }
+    else
+    {
+      delete attType;
+      attType = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributeCertificateAssertion &AttributeCertificateAssertion::operator = (const AttributeCertificateAssertion &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AttributeCertificateAssertion::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (attType))
+  {
+      BEncEocIfNec (b);
+      BEncEocIfNec (b);
+    l = attType->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 3);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (attCertValidity))
+  {
+      BEncEocIfNec (b);
+    l = attCertValidity->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 2);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (issuer))
+  {
+      BEncEocIfNec (b);
+    l = issuer->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (subject))
+  {
+      BEncEocIfNec (b);
+    l = subject->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // AttributeCertificateAssertion::BEncContent
+
+
+void AttributeCertificateAssertion::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    subject = new AttributeCertificateAssertionChoice;
+    subject->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    issuer = new Name;
+    issuer->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+       && (tag1 != MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -205);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    attCertValidity = new GeneralizedTime;
+    attCertValidity->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 3)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
+    {
+       Asn1Error << "Unexpected Tag" << endl;
+       longjmp (env, -206);
+    }
+
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    attType = new AttributeCertificateAssertionSetOf;
+    attType->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -207);
+  }
+  else
+    return;
+} // AttributeCertificateAssertion::BDecContent
+
+AsnLen AttributeCertificateAssertion::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributeCertificateAssertion::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributeCertificateAssertion::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -208);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AttributeCertificateAssertion::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AttributeCertificateAssertion::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AttributeCertificateAssertion::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (subject))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "subject ";
+    os << *subject;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "subject ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (issuer))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "issuer ";
+    os << *issuer;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "issuer ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (attCertValidity))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "attCertValidity ";
+    os << *attCertValidity;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "attCertValidity ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (attType))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "attType ";
+    os << *attType;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "attType ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AttributeCertificateAssertion::Print
+
+
diff --git a/SecurityASN1/c++/sm_x509ce.cpp b/SecurityASN1/c++/sm_x509ce.cpp
new file mode 100644
index 00000000..2d50e092
--- /dev/null
+++ b/SecurityASN1/c++/sm_x509ce.cpp
@@ -0,0 +1,7109 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x509ce.cpp - class member functions for ASN.1 module CertificateExtensions
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+PolicyQualifierInfo::PolicyQualifierInfo()
+{
+  qualifier = NULL;
+}
+
+PolicyQualifierInfo::PolicyQualifierInfo (const PolicyQualifierInfo &)
+{
+  Asn1Error << "use of incompletely defined PolicyQualifierInfo::PolicyQualifierInfo (const PolicyQualifierInfo &)" << endl;
+  abort();
+}
+
+PolicyQualifierInfo::~PolicyQualifierInfo()
+{
+  delete qualifier;
+}
+
+AsnType *PolicyQualifierInfo::Clone() const
+{
+  return new PolicyQualifierInfo;
+}
+
+AsnType *PolicyQualifierInfo::Copy() const
+{
+  return new PolicyQualifierInfo (*this);
+}
+
+#if SNACC_DEEP_COPY
+PolicyQualifierInfo &PolicyQualifierInfo::operator = (const PolicyQualifierInfo &that)
+#else // SNACC_DEEP_COPY
+PolicyQualifierInfo &PolicyQualifierInfo::operator = (const PolicyQualifierInfo &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    policyQualifierId = that.policyQualifierId;
+    if (that.qualifier)
+    {
+      if (!qualifier)
+        qualifier = new AsnAny;
+      *qualifier = *that.qualifier;
+    }
+    else
+    {
+      delete qualifier;
+      qualifier = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PolicyQualifierInfo &PolicyQualifierInfo::operator = (const PolicyQualifierInfo &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+PolicyQualifierInfo::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (qualifier))
+  {
+        ENC_LOAD_ANYBUF(qualifier, b, l);
+    totalLen += l;
+  }
+
+    l = policyQualifierId.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // PolicyQualifierInfo::BEncContent
+
+
+void PolicyQualifierInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    policyQualifierId.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = b.PeekByte();
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDecEoc (b, seqBytesDecoded, env);
+
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -100);
+  }
+
+  // ANY type
+    qualifier = new AsnAny;
+        DEC_LOAD_ANYBUF(qualifier, b, seqBytesDecoded, env);
+
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -101);
+  }
+  else
+    return;
+} // PolicyQualifierInfo::BDecContent
+
+AsnLen PolicyQualifierInfo::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void PolicyQualifierInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "PolicyQualifierInfo::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -102);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PolicyQualifierInfo::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PolicyQualifierInfo::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void PolicyQualifierInfo::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "policyQualifierId ";
+    os << policyQualifierId;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (qualifier))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "qualifier ";
+    os << *qualifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "qualifier ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // PolicyQualifierInfo::Print
+
+
+AsnType *AttributesSyntax::Clone() const
+{
+  return new AttributesSyntax;
+}
+
+AsnType *AttributesSyntax::Copy() const
+{
+  return new AttributesSyntax (*this);
+}
+
+AsnLen AttributesSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AttributesSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AttributesSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -103);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+AttributesSyntax::AttributesSyntax (const AttributesSyntax &)
+{
+  Asn1Error << "use of incompletely defined AttributesSyntax::AttributesSyntax (const AttributesSyntax &)" << endl;
+  abort();
+}
+
+AttributesSyntax::~AttributesSyntax()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+AttributesSyntax &AttributesSyntax::operator = (const AttributesSyntax &that)
+#else // SNACC_DEEP_COPY
+AttributesSyntax &AttributesSyntax::operator = (const AttributesSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AttributesSyntax &AttributesSyntax::operator = (const AttributesSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void AttributesSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  AttributesSyntax::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // AttributesSyntax::SetCurrElmt
+
+
+unsigned long int  AttributesSyntax::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // AttributesSyntax::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+Attribute *AttributesSyntax::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new Attribute;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributesSyntax::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+Attribute  *AttributesSyntax::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributesSyntax::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+Attribute  *AttributesSyntax::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributesSyntax::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+Attribute *AttributesSyntax::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // AttributesSyntax::InsertAfter
+
+
+AttributesSyntax  &AttributesSyntax::AppendCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+AttributesSyntax  &AttributesSyntax::PrependCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributesSyntax::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+AttributesSyntax &AttributesSyntax::InsertBeforeAndCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributesSyntax::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+AttributesSyntax  &AttributesSyntax::InsertAfterAndCopy (Attribute &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new Attribute;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // AttributesSyntax::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void AttributesSyntax::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen AttributesSyntax::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // AttributesSyntax::BEncContent
+
+
+void  AttributesSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    Attribute *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -104);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // AttributesSyntax::BDecContent
+
+
+DistributionPointName::DistributionPointName()
+{
+  choiceId = fullNameCid;
+#if TCL
+  fullName = new GeneralNames;
+#else
+  fullName = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+DistributionPointName::DistributionPointName (const DistributionPointName &)
+{
+  Asn1Error << "use of incompletely defined DistributionPointName::DistributionPointName (const DistributionPointName &)" << endl;
+  abort();
+}
+
+DistributionPointName::~DistributionPointName()
+{
+  switch (choiceId)
+  {
+    case fullNameCid:
+      delete fullName;
+      break;
+    case nameRelativeToCRLIssuerCid:
+      delete nameRelativeToCRLIssuer;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *DistributionPointName::Clone() const
+{
+  return new DistributionPointName;
+}
+
+AsnType *DistributionPointName::Copy() const
+{
+  return new DistributionPointName (*this);
+}
+
+#if SNACC_DEEP_COPY
+DistributionPointName &DistributionPointName::operator = (const DistributionPointName &that)
+#else // SNACC_DEEP_COPY
+DistributionPointName &DistributionPointName::operator = (const DistributionPointName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case fullNameCid:
+        delete fullName;
+        break;
+      case nameRelativeToCRLIssuerCid:
+        delete nameRelativeToCRLIssuer;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case fullNameCid:
+        fullName = new GeneralNames;
+        *fullName = *that.fullName;
+        break;
+      case nameRelativeToCRLIssuerCid:
+        nameRelativeToCRLIssuer = new RelativeDistinguishedName;
+        *nameRelativeToCRLIssuer = *that.nameRelativeToCRLIssuer;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DistributionPointName &DistributionPointName::operator = (const DistributionPointName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DistributionPointName::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case fullNameCid:
+      BEncEocIfNec (b);
+      l = fullName->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+      break;
+
+    case nameRelativeToCRLIssuerCid:
+      BEncEocIfNec (b);
+      l = nameRelativeToCRLIssuer->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+      break;
+
+  } // end switch
+  return l;
+} // DistributionPointName::BEncContent
+
+
+void DistributionPointName::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      choiceId = fullNameCid;
+      fullName = new GeneralNames;
+        fullName->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = nameRelativeToCRLIssuerCid;
+      nameRelativeToCRLIssuer = new RelativeDistinguishedName;
+        nameRelativeToCRLIssuer->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -105);
+      break;
+  } // end switch
+} // DistributionPointName::BDecContent
+
+
+AsnLen DistributionPointName::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void DistributionPointName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int DistributionPointName::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DistributionPointName::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DistributionPointName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case fullNameCid:
+      os << "fullName ";
+      if (fullName)
+        os << *fullName;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case nameRelativeToCRLIssuerCid:
+      os << "nameRelativeToCRLIssuer ";
+      if (nameRelativeToCRLIssuer)
+        os << *nameRelativeToCRLIssuer;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // DistributionPointName::Print
+
+PolicyMappingsSyntaxSeq::PolicyMappingsSyntaxSeq()
+{
+}
+
+PolicyMappingsSyntaxSeq::PolicyMappingsSyntaxSeq (const PolicyMappingsSyntaxSeq &)
+{
+  Asn1Error << "use of incompletely defined PolicyMappingsSyntaxSeq::PolicyMappingsSyntaxSeq (const PolicyMappingsSyntaxSeq &)" << endl;
+  abort();
+}
+
+PolicyMappingsSyntaxSeq::~PolicyMappingsSyntaxSeq()
+{
+}
+
+AsnType *PolicyMappingsSyntaxSeq::Clone() const
+{
+  return new PolicyMappingsSyntaxSeq;
+}
+
+AsnType *PolicyMappingsSyntaxSeq::Copy() const
+{
+  return new PolicyMappingsSyntaxSeq (*this);
+}
+
+#if SNACC_DEEP_COPY
+PolicyMappingsSyntaxSeq &PolicyMappingsSyntaxSeq::operator = (const PolicyMappingsSyntaxSeq &that)
+#else // SNACC_DEEP_COPY
+PolicyMappingsSyntaxSeq &PolicyMappingsSyntaxSeq::operator = (const PolicyMappingsSyntaxSeq &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    issuerDomainPolicy = that.issuerDomainPolicy;
+    subjectDomainPolicy = that.subjectDomainPolicy;
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PolicyMappingsSyntaxSeq &PolicyMappingsSyntaxSeq::operator = (const PolicyMappingsSyntaxSeq &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+PolicyMappingsSyntaxSeq::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = subjectDomainPolicy.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+    l = issuerDomainPolicy.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // PolicyMappingsSyntaxSeq::BEncContent
+
+
+void PolicyMappingsSyntaxSeq::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    issuerDomainPolicy.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -106);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    subjectDomainPolicy.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -107);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -108);
+  }
+  else
+    return;
+} // PolicyMappingsSyntaxSeq::BDecContent
+
+AsnLen PolicyMappingsSyntaxSeq::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void PolicyMappingsSyntaxSeq::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "PolicyMappingsSyntaxSeq::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -109);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PolicyMappingsSyntaxSeq::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PolicyMappingsSyntaxSeq::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void PolicyMappingsSyntaxSeq::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "issuerDomainPolicy ";
+    os << issuerDomainPolicy;
+    os << "," << endl;
+  }
+
+  {
+    Indent (os, indentG);
+    os << "subjectDomainPolicy ";
+    os << subjectDomainPolicy;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // PolicyMappingsSyntaxSeq::Print
+
+
+AsnType *PolicyInformationSeqOf::Clone() const
+{
+  return new PolicyInformationSeqOf;
+}
+
+AsnType *PolicyInformationSeqOf::Copy() const
+{
+  return new PolicyInformationSeqOf (*this);
+}
+
+AsnLen PolicyInformationSeqOf::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void PolicyInformationSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "PolicyInformationSeqOf::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -110);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+PolicyInformationSeqOf::PolicyInformationSeqOf (const PolicyInformationSeqOf &)
+{
+  Asn1Error << "use of incompletely defined PolicyInformationSeqOf::PolicyInformationSeqOf (const PolicyInformationSeqOf &)" << endl;
+  abort();
+}
+
+PolicyInformationSeqOf::~PolicyInformationSeqOf()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+PolicyInformationSeqOf &PolicyInformationSeqOf::operator = (const PolicyInformationSeqOf &that)
+#else // SNACC_DEEP_COPY
+PolicyInformationSeqOf &PolicyInformationSeqOf::operator = (const PolicyInformationSeqOf &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PolicyInformationSeqOf &PolicyInformationSeqOf::operator = (const PolicyInformationSeqOf &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void PolicyInformationSeqOf::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  PolicyInformationSeqOf::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // PolicyInformationSeqOf::SetCurrElmt
+
+
+unsigned long int  PolicyInformationSeqOf::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // PolicyInformationSeqOf::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+PolicyQualifierInfo *PolicyInformationSeqOf::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new PolicyQualifierInfo;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // PolicyInformationSeqOf::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+PolicyQualifierInfo  *PolicyInformationSeqOf::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyQualifierInfo;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // PolicyInformationSeqOf::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+PolicyQualifierInfo  *PolicyInformationSeqOf::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyQualifierInfo;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // PolicyInformationSeqOf::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+PolicyQualifierInfo *PolicyInformationSeqOf::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyQualifierInfo;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // PolicyInformationSeqOf::InsertAfter
+
+
+PolicyInformationSeqOf  &PolicyInformationSeqOf::AppendCopy (PolicyQualifierInfo &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyQualifierInfo;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+PolicyInformationSeqOf  &PolicyInformationSeqOf::PrependCopy (PolicyQualifierInfo &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyQualifierInfo;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // PolicyInformationSeqOf::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+PolicyInformationSeqOf &PolicyInformationSeqOf::InsertBeforeAndCopy (PolicyQualifierInfo &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyQualifierInfo;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // PolicyInformationSeqOf::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+PolicyInformationSeqOf  &PolicyInformationSeqOf::InsertAfterAndCopy (PolicyQualifierInfo &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyQualifierInfo;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // PolicyInformationSeqOf::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void PolicyInformationSeqOf::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen PolicyInformationSeqOf::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // PolicyInformationSeqOf::BEncContent
+
+
+void  PolicyInformationSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    PolicyQualifierInfo *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -111);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // PolicyInformationSeqOf::BDecContent
+
+
+PolicyInformation::PolicyInformation()
+{
+  policyQualifiers = NULL;
+}
+
+PolicyInformation::PolicyInformation (const PolicyInformation &)
+{
+  Asn1Error << "use of incompletely defined PolicyInformation::PolicyInformation (const PolicyInformation &)" << endl;
+  abort();
+}
+
+PolicyInformation::~PolicyInformation()
+{
+  delete policyQualifiers;
+}
+
+AsnType *PolicyInformation::Clone() const
+{
+  return new PolicyInformation;
+}
+
+AsnType *PolicyInformation::Copy() const
+{
+  return new PolicyInformation (*this);
+}
+
+#if SNACC_DEEP_COPY
+PolicyInformation &PolicyInformation::operator = (const PolicyInformation &that)
+#else // SNACC_DEEP_COPY
+PolicyInformation &PolicyInformation::operator = (const PolicyInformation &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    policyIdentifier = that.policyIdentifier;
+    if (that.policyQualifiers)
+    {
+      if (!policyQualifiers)
+        policyQualifiers = new PolicyInformationSeqOf;
+      *policyQualifiers = *that.policyQualifiers;
+    }
+    else
+    {
+      delete policyQualifiers;
+      policyQualifiers = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PolicyInformation &PolicyInformation::operator = (const PolicyInformation &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+PolicyInformation::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (policyQualifiers))
+  {
+      BEncEocIfNec (b);
+    l = policyQualifiers->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+  }
+
+    l = policyIdentifier.BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // PolicyInformation::BEncContent
+
+
+void PolicyInformation::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    policyIdentifier.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -112);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    policyQualifiers = new PolicyInformationSeqOf;
+    policyQualifiers->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -113);
+  }
+  else
+    return;
+} // PolicyInformation::BDecContent
+
+AsnLen PolicyInformation::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void PolicyInformation::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "PolicyInformation::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -114);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PolicyInformation::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PolicyInformation::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void PolicyInformation::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  {
+    Indent (os, indentG);
+    os << "policyIdentifier ";
+    os << policyIdentifier;
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (policyQualifiers))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "policyQualifiers ";
+    os << *policyQualifiers;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "policyQualifiers ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // PolicyInformation::Print
+
+
+GeneralSubtree::GeneralSubtree()
+{
+#if TCL
+  base = new GeneralName;
+#else
+  base = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  minimum = NULL;
+  maximum = NULL;
+}
+
+GeneralSubtree::GeneralSubtree (const GeneralSubtree &)
+{
+  Asn1Error << "use of incompletely defined GeneralSubtree::GeneralSubtree (const GeneralSubtree &)" << endl;
+  abort();
+}
+
+GeneralSubtree::~GeneralSubtree()
+{
+  delete base;
+  delete minimum;
+  delete maximum;
+}
+
+AsnType *GeneralSubtree::Clone() const
+{
+  return new GeneralSubtree;
+}
+
+AsnType *GeneralSubtree::Copy() const
+{
+  return new GeneralSubtree (*this);
+}
+
+#if SNACC_DEEP_COPY
+GeneralSubtree &GeneralSubtree::operator = (const GeneralSubtree &that)
+#else // SNACC_DEEP_COPY
+GeneralSubtree &GeneralSubtree::operator = (const GeneralSubtree &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.base)
+    {
+      if (!base)
+        base = new GeneralName;
+      *base = *that.base;
+    }
+    else
+    {
+      delete base;
+      base = NULL;
+    }
+    if (that.minimum)
+    {
+      if (!minimum)
+        minimum = new BaseDistance;
+      *minimum = *that.minimum;
+    }
+    else
+    {
+      delete minimum;
+      minimum = NULL;
+    }
+    if (that.maximum)
+    {
+      if (!maximum)
+        maximum = new BaseDistance;
+      *maximum = *that.maximum;
+    }
+    else
+    {
+      delete maximum;
+      maximum = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined GeneralSubtree &GeneralSubtree::operator = (const GeneralSubtree &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+GeneralSubtree::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (maximum))
+  {
+    l = maximum->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (minimum))
+  {
+    l = minimum->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+  }
+
+    l = base->BEncContent (b);
+    totalLen += l;
+
+  return totalLen;
+} // GeneralSubtree::BEncContent
+
+
+void GeneralSubtree::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 2))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 3))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 4))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 5))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 6))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 6))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 7))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 7))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 8)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    base = new GeneralName;
+    base->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -115);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    minimum = new BaseDistance;
+    minimum->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    maximum = new BaseDistance;
+    maximum->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -116);
+  }
+  else
+    return;
+} // GeneralSubtree::BDecContent
+
+AsnLen GeneralSubtree::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void GeneralSubtree::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "GeneralSubtree::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -117);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int GeneralSubtree::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int GeneralSubtree::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void GeneralSubtree::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (base))
+  {
+    Indent (os, indentG);
+    os << "base ";
+    os << *base;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "base ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (minimum))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "minimum ";
+    os << *minimum;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "minimum ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (maximum))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "maximum ";
+    os << *maximum;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "maximum ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // GeneralSubtree::Print
+
+
+DistributionPoint::DistributionPoint()
+{
+  distributionPoint = NULL;
+  reasons = NULL;
+  cRLIssuer = NULL;
+}
+
+DistributionPoint::DistributionPoint (const DistributionPoint &)
+{
+  Asn1Error << "use of incompletely defined DistributionPoint::DistributionPoint (const DistributionPoint &)" << endl;
+  abort();
+}
+
+DistributionPoint::~DistributionPoint()
+{
+  delete distributionPoint;
+  delete reasons;
+  delete cRLIssuer;
+}
+
+AsnType *DistributionPoint::Clone() const
+{
+  return new DistributionPoint;
+}
+
+AsnType *DistributionPoint::Copy() const
+{
+  return new DistributionPoint (*this);
+}
+
+#if SNACC_DEEP_COPY
+DistributionPoint &DistributionPoint::operator = (const DistributionPoint &that)
+#else // SNACC_DEEP_COPY
+DistributionPoint &DistributionPoint::operator = (const DistributionPoint &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.distributionPoint)
+    {
+      if (!distributionPoint)
+        distributionPoint = new DistributionPointName;
+      *distributionPoint = *that.distributionPoint;
+    }
+    else
+    {
+      delete distributionPoint;
+      distributionPoint = NULL;
+    }
+    if (that.reasons)
+    {
+      if (!reasons)
+        reasons = new ReasonFlags;
+      *reasons = *that.reasons;
+    }
+    else
+    {
+      delete reasons;
+      reasons = NULL;
+    }
+    if (that.cRLIssuer)
+    {
+      if (!cRLIssuer)
+        cRLIssuer = new GeneralNames;
+      *cRLIssuer = *that.cRLIssuer;
+    }
+    else
+    {
+      delete cRLIssuer;
+      cRLIssuer = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DistributionPoint &DistributionPoint::operator = (const DistributionPoint &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DistributionPoint::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (cRLIssuer))
+  {
+      BEncEocIfNec (b);
+    l = cRLIssuer->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 2);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (reasons))
+  {
+    l = reasons->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (distributionPoint))
+  {
+      BEncEocIfNec (b);
+    l = distributionPoint->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // DistributionPoint::BEncContent
+
+
+void DistributionPoint::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    distributionPoint = new DistributionPointName;
+    distributionPoint->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    reasons = new ReasonFlags;
+    reasons->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    cRLIssuer = new GeneralNames;
+    cRLIssuer->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -118);
+  }
+  else
+    return;
+} // DistributionPoint::BDecContent
+
+AsnLen DistributionPoint::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void DistributionPoint::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "DistributionPoint::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -119);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int DistributionPoint::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DistributionPoint::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DistributionPoint::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (distributionPoint))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "distributionPoint ";
+    os << *distributionPoint;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "distributionPoint ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (reasons))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "reasons ";
+    os << *reasons;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "reasons ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (cRLIssuer))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "cRLIssuer ";
+    os << *cRLIssuer;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "cRLIssuer ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // DistributionPoint::Print
+
+
+AsnType *CertificatePoliciesSyntax::Clone() const
+{
+  return new CertificatePoliciesSyntax;
+}
+
+AsnType *CertificatePoliciesSyntax::Copy() const
+{
+  return new CertificatePoliciesSyntax (*this);
+}
+
+AsnLen CertificatePoliciesSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CertificatePoliciesSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CertificatePoliciesSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -120);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+CertificatePoliciesSyntax::CertificatePoliciesSyntax (const CertificatePoliciesSyntax &)
+{
+  Asn1Error << "use of incompletely defined CertificatePoliciesSyntax::CertificatePoliciesSyntax (const CertificatePoliciesSyntax &)" << endl;
+  abort();
+}
+
+CertificatePoliciesSyntax::~CertificatePoliciesSyntax()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+CertificatePoliciesSyntax &CertificatePoliciesSyntax::operator = (const CertificatePoliciesSyntax &that)
+#else // SNACC_DEEP_COPY
+CertificatePoliciesSyntax &CertificatePoliciesSyntax::operator = (const CertificatePoliciesSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertificatePoliciesSyntax &CertificatePoliciesSyntax::operator = (const CertificatePoliciesSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void CertificatePoliciesSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  CertificatePoliciesSyntax::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // CertificatePoliciesSyntax::SetCurrElmt
+
+
+unsigned long int  CertificatePoliciesSyntax::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // CertificatePoliciesSyntax::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+PolicyInformation *CertificatePoliciesSyntax::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new PolicyInformation;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificatePoliciesSyntax::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+PolicyInformation  *CertificatePoliciesSyntax::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificatePoliciesSyntax::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+PolicyInformation  *CertificatePoliciesSyntax::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificatePoliciesSyntax::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+PolicyInformation *CertificatePoliciesSyntax::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertificatePoliciesSyntax::InsertAfter
+
+
+CertificatePoliciesSyntax  &CertificatePoliciesSyntax::AppendCopy (PolicyInformation &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+CertificatePoliciesSyntax  &CertificatePoliciesSyntax::PrependCopy (PolicyInformation &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificatePoliciesSyntax::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertificatePoliciesSyntax &CertificatePoliciesSyntax::InsertBeforeAndCopy (PolicyInformation &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificatePoliciesSyntax::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertificatePoliciesSyntax  &CertificatePoliciesSyntax::InsertAfterAndCopy (PolicyInformation &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyInformation;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // CertificatePoliciesSyntax::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void CertificatePoliciesSyntax::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen CertificatePoliciesSyntax::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // CertificatePoliciesSyntax::BEncContent
+
+
+void  CertificatePoliciesSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    PolicyInformation *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -121);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // CertificatePoliciesSyntax::BDecContent
+
+
+AsnType *GeneralSubtrees::Clone() const
+{
+  return new GeneralSubtrees;
+}
+
+AsnType *GeneralSubtrees::Copy() const
+{
+  return new GeneralSubtrees (*this);
+}
+
+AsnLen GeneralSubtrees::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void GeneralSubtrees::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "GeneralSubtrees::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -122);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+GeneralSubtrees::GeneralSubtrees (const GeneralSubtrees &)
+{
+  Asn1Error << "use of incompletely defined GeneralSubtrees::GeneralSubtrees (const GeneralSubtrees &)" << endl;
+  abort();
+}
+
+GeneralSubtrees::~GeneralSubtrees()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+GeneralSubtrees &GeneralSubtrees::operator = (const GeneralSubtrees &that)
+#else // SNACC_DEEP_COPY
+GeneralSubtrees &GeneralSubtrees::operator = (const GeneralSubtrees &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined GeneralSubtrees &GeneralSubtrees::operator = (const GeneralSubtrees &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void GeneralSubtrees::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  GeneralSubtrees::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // GeneralSubtrees::SetCurrElmt
+
+
+unsigned long int  GeneralSubtrees::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // GeneralSubtrees::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+GeneralSubtree *GeneralSubtrees::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new GeneralSubtree;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // GeneralSubtrees::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+GeneralSubtree  *GeneralSubtrees::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralSubtree;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // GeneralSubtrees::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+GeneralSubtree  *GeneralSubtrees::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralSubtree;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // GeneralSubtrees::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+GeneralSubtree *GeneralSubtrees::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralSubtree;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // GeneralSubtrees::InsertAfter
+
+
+GeneralSubtrees  &GeneralSubtrees::AppendCopy (GeneralSubtree &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralSubtree;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+GeneralSubtrees  &GeneralSubtrees::PrependCopy (GeneralSubtree &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralSubtree;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // GeneralSubtrees::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+GeneralSubtrees &GeneralSubtrees::InsertBeforeAndCopy (GeneralSubtree &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralSubtree;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // GeneralSubtrees::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+GeneralSubtrees  &GeneralSubtrees::InsertAfterAndCopy (GeneralSubtree &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralSubtree;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // GeneralSubtrees::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void GeneralSubtrees::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen GeneralSubtrees::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // GeneralSubtrees::BEncContent
+
+
+void  GeneralSubtrees::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    GeneralSubtree *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -123);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // GeneralSubtrees::BDecContent
+
+
+AuthorityKeyIdentifier::AuthorityKeyIdentifier()
+{
+  keyIdentifier = NULL;
+  authorityCertIssuer = NULL;
+  authorityCertSerialNumber = NULL;
+}
+
+AuthorityKeyIdentifier::AuthorityKeyIdentifier (const AuthorityKeyIdentifier &)
+{
+  Asn1Error << "use of incompletely defined AuthorityKeyIdentifier::AuthorityKeyIdentifier (const AuthorityKeyIdentifier &)" << endl;
+  abort();
+}
+
+AuthorityKeyIdentifier::~AuthorityKeyIdentifier()
+{
+  delete keyIdentifier;
+  delete authorityCertIssuer;
+  delete authorityCertSerialNumber;
+}
+
+AsnType *AuthorityKeyIdentifier::Clone() const
+{
+  return new AuthorityKeyIdentifier;
+}
+
+AsnType *AuthorityKeyIdentifier::Copy() const
+{
+  return new AuthorityKeyIdentifier (*this);
+}
+
+#if SNACC_DEEP_COPY
+AuthorityKeyIdentifier &AuthorityKeyIdentifier::operator = (const AuthorityKeyIdentifier &that)
+#else // SNACC_DEEP_COPY
+AuthorityKeyIdentifier &AuthorityKeyIdentifier::operator = (const AuthorityKeyIdentifier &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.keyIdentifier)
+    {
+      if (!keyIdentifier)
+        keyIdentifier = new KeyIdentifier;
+      *keyIdentifier = *that.keyIdentifier;
+    }
+    else
+    {
+      delete keyIdentifier;
+      keyIdentifier = NULL;
+    }
+    if (that.authorityCertIssuer)
+    {
+      if (!authorityCertIssuer)
+        authorityCertIssuer = new GeneralNames;
+      *authorityCertIssuer = *that.authorityCertIssuer;
+    }
+    else
+    {
+      delete authorityCertIssuer;
+      authorityCertIssuer = NULL;
+    }
+    if (that.authorityCertSerialNumber)
+    {
+      if (!authorityCertSerialNumber)
+        authorityCertSerialNumber = new CertificateSerialNumber;
+      *authorityCertSerialNumber = *that.authorityCertSerialNumber;
+    }
+    else
+    {
+      delete authorityCertSerialNumber;
+      authorityCertSerialNumber = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined AuthorityKeyIdentifier &AuthorityKeyIdentifier::operator = (const AuthorityKeyIdentifier &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+AuthorityKeyIdentifier::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (authorityCertSerialNumber))
+  {
+    l = authorityCertSerialNumber->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 2);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (authorityCertIssuer))
+  {
+      BEncEocIfNec (b);
+    l = authorityCertIssuer->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (keyIdentifier))
+  {
+    l = keyIdentifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // AuthorityKeyIdentifier::BEncContent
+
+
+void AuthorityKeyIdentifier::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    keyIdentifier = new KeyIdentifier;
+    keyIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    authorityCertIssuer = new GeneralNames;
+    authorityCertIssuer->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 2))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    authorityCertSerialNumber = new CertificateSerialNumber;
+    authorityCertSerialNumber->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -124);
+  }
+  else
+    return;
+} // AuthorityKeyIdentifier::BDecContent
+
+AsnLen AuthorityKeyIdentifier::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void AuthorityKeyIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "AuthorityKeyIdentifier::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -125);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int AuthorityKeyIdentifier::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int AuthorityKeyIdentifier::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void AuthorityKeyIdentifier::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (keyIdentifier))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "keyIdentifier ";
+    os << *keyIdentifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "keyIdentifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (authorityCertIssuer))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "authorityCertIssuer ";
+    os << *authorityCertIssuer;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "authorityCertIssuer ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (authorityCertSerialNumber))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "authorityCertSerialNumber ";
+    os << *authorityCertSerialNumber;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "authorityCertSerialNumber ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // AuthorityKeyIdentifier::Print
+
+
+AsnType *ExtKeyUsageSyntax::Clone() const
+{
+  return new ExtKeyUsageSyntax;
+}
+
+AsnType *ExtKeyUsageSyntax::Copy() const
+{
+  return new ExtKeyUsageSyntax (*this);
+}
+
+AsnLen ExtKeyUsageSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void ExtKeyUsageSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "ExtKeyUsageSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -126);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+ExtKeyUsageSyntax::ExtKeyUsageSyntax (const ExtKeyUsageSyntax &)
+{
+  Asn1Error << "use of incompletely defined ExtKeyUsageSyntax::ExtKeyUsageSyntax (const ExtKeyUsageSyntax &)" << endl;
+  abort();
+}
+
+ExtKeyUsageSyntax::~ExtKeyUsageSyntax()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+ExtKeyUsageSyntax &ExtKeyUsageSyntax::operator = (const ExtKeyUsageSyntax &that)
+#else // SNACC_DEEP_COPY
+ExtKeyUsageSyntax &ExtKeyUsageSyntax::operator = (const ExtKeyUsageSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined ExtKeyUsageSyntax &ExtKeyUsageSyntax::operator = (const ExtKeyUsageSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void ExtKeyUsageSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  ExtKeyUsageSyntax::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // ExtKeyUsageSyntax::SetCurrElmt
+
+
+unsigned long int  ExtKeyUsageSyntax::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // ExtKeyUsageSyntax::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+KeyPurposeId *ExtKeyUsageSyntax::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new KeyPurposeId;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ExtKeyUsageSyntax::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+KeyPurposeId  *ExtKeyUsageSyntax::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new KeyPurposeId;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ExtKeyUsageSyntax::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+KeyPurposeId  *ExtKeyUsageSyntax::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new KeyPurposeId;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ExtKeyUsageSyntax::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+KeyPurposeId *ExtKeyUsageSyntax::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new KeyPurposeId;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // ExtKeyUsageSyntax::InsertAfter
+
+
+ExtKeyUsageSyntax  &ExtKeyUsageSyntax::AppendCopy (KeyPurposeId &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new KeyPurposeId;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+ExtKeyUsageSyntax  &ExtKeyUsageSyntax::PrependCopy (KeyPurposeId &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new KeyPurposeId;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // ExtKeyUsageSyntax::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+ExtKeyUsageSyntax &ExtKeyUsageSyntax::InsertBeforeAndCopy (KeyPurposeId &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new KeyPurposeId;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // ExtKeyUsageSyntax::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+ExtKeyUsageSyntax  &ExtKeyUsageSyntax::InsertAfterAndCopy (KeyPurposeId &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new KeyPurposeId;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // ExtKeyUsageSyntax::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void ExtKeyUsageSyntax::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen ExtKeyUsageSyntax::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncDefLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // ExtKeyUsageSyntax::BEncContent
+
+
+void  ExtKeyUsageSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    KeyPurposeId *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -127);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // ExtKeyUsageSyntax::BDecContent
+
+
+PrivateKeyUsagePeriod::PrivateKeyUsagePeriod()
+{
+  notBefore = NULL;
+  notAfter = NULL;
+}
+
+PrivateKeyUsagePeriod::PrivateKeyUsagePeriod (const PrivateKeyUsagePeriod &)
+{
+  Asn1Error << "use of incompletely defined PrivateKeyUsagePeriod::PrivateKeyUsagePeriod (const PrivateKeyUsagePeriod &)" << endl;
+  abort();
+}
+
+PrivateKeyUsagePeriod::~PrivateKeyUsagePeriod()
+{
+  delete notBefore;
+  delete notAfter;
+}
+
+AsnType *PrivateKeyUsagePeriod::Clone() const
+{
+  return new PrivateKeyUsagePeriod;
+}
+
+AsnType *PrivateKeyUsagePeriod::Copy() const
+{
+  return new PrivateKeyUsagePeriod (*this);
+}
+
+#if SNACC_DEEP_COPY
+PrivateKeyUsagePeriod &PrivateKeyUsagePeriod::operator = (const PrivateKeyUsagePeriod &that)
+#else // SNACC_DEEP_COPY
+PrivateKeyUsagePeriod &PrivateKeyUsagePeriod::operator = (const PrivateKeyUsagePeriod &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.notBefore)
+    {
+      if (!notBefore)
+        notBefore = new GeneralizedTime;
+      *notBefore = *that.notBefore;
+    }
+    else
+    {
+      delete notBefore;
+      notBefore = NULL;
+    }
+    if (that.notAfter)
+    {
+      if (!notAfter)
+        notAfter = new GeneralizedTime;
+      *notAfter = *that.notAfter;
+    }
+    else
+    {
+      delete notAfter;
+      notAfter = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PrivateKeyUsagePeriod &PrivateKeyUsagePeriod::operator = (const PrivateKeyUsagePeriod &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+PrivateKeyUsagePeriod::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (notAfter))
+  {
+    l = notAfter->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (notBefore))
+  {
+    l = notBefore->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // PrivateKeyUsagePeriod::BEncContent
+
+
+void PrivateKeyUsagePeriod::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    notBefore = new GeneralizedTime;
+    notBefore->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    notAfter = new GeneralizedTime;
+    notAfter->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -128);
+  }
+  else
+    return;
+} // PrivateKeyUsagePeriod::BDecContent
+
+AsnLen PrivateKeyUsagePeriod::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void PrivateKeyUsagePeriod::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "PrivateKeyUsagePeriod::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -129);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PrivateKeyUsagePeriod::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PrivateKeyUsagePeriod::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void PrivateKeyUsagePeriod::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (notBefore))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "notBefore ";
+    os << *notBefore;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "notBefore ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (notAfter))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "notAfter ";
+    os << *notAfter;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "notAfter ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // PrivateKeyUsagePeriod::Print
+
+
+AsnType *PolicyMappingsSyntax::Clone() const
+{
+  return new PolicyMappingsSyntax;
+}
+
+AsnType *PolicyMappingsSyntax::Copy() const
+{
+  return new PolicyMappingsSyntax (*this);
+}
+
+AsnLen PolicyMappingsSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void PolicyMappingsSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "PolicyMappingsSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -130);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+PolicyMappingsSyntax::PolicyMappingsSyntax (const PolicyMappingsSyntax &)
+{
+  Asn1Error << "use of incompletely defined PolicyMappingsSyntax::PolicyMappingsSyntax (const PolicyMappingsSyntax &)" << endl;
+  abort();
+}
+
+PolicyMappingsSyntax::~PolicyMappingsSyntax()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+PolicyMappingsSyntax &PolicyMappingsSyntax::operator = (const PolicyMappingsSyntax &that)
+#else // SNACC_DEEP_COPY
+PolicyMappingsSyntax &PolicyMappingsSyntax::operator = (const PolicyMappingsSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PolicyMappingsSyntax &PolicyMappingsSyntax::operator = (const PolicyMappingsSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void PolicyMappingsSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  PolicyMappingsSyntax::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // PolicyMappingsSyntax::SetCurrElmt
+
+
+unsigned long int  PolicyMappingsSyntax::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // PolicyMappingsSyntax::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+PolicyMappingsSyntaxSeq *PolicyMappingsSyntax::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new PolicyMappingsSyntaxSeq;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // PolicyMappingsSyntax::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+PolicyMappingsSyntaxSeq  *PolicyMappingsSyntax::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyMappingsSyntaxSeq;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // PolicyMappingsSyntax::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+PolicyMappingsSyntaxSeq  *PolicyMappingsSyntax::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyMappingsSyntaxSeq;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // PolicyMappingsSyntax::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+PolicyMappingsSyntaxSeq *PolicyMappingsSyntax::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyMappingsSyntaxSeq;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // PolicyMappingsSyntax::InsertAfter
+
+
+PolicyMappingsSyntax  &PolicyMappingsSyntax::AppendCopy (PolicyMappingsSyntaxSeq &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyMappingsSyntaxSeq;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+PolicyMappingsSyntax  &PolicyMappingsSyntax::PrependCopy (PolicyMappingsSyntaxSeq &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyMappingsSyntaxSeq;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // PolicyMappingsSyntax::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+PolicyMappingsSyntax &PolicyMappingsSyntax::InsertBeforeAndCopy (PolicyMappingsSyntaxSeq &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyMappingsSyntaxSeq;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // PolicyMappingsSyntax::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+PolicyMappingsSyntax  &PolicyMappingsSyntax::InsertAfterAndCopy (PolicyMappingsSyntaxSeq &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new PolicyMappingsSyntaxSeq;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // PolicyMappingsSyntax::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void PolicyMappingsSyntax::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen PolicyMappingsSyntax::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // PolicyMappingsSyntax::BEncContent
+
+
+void  PolicyMappingsSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    PolicyMappingsSyntaxSeq *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -131);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // PolicyMappingsSyntax::BDecContent
+
+
+SupportedAlgorithm::SupportedAlgorithm()
+{
+#if TCL
+  algorithmIdentifier = new AlgorithmIdentifier;
+#else
+  algorithmIdentifier = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+  intendedUsage = NULL;
+  intendedCertificatePolicies = NULL;
+}
+
+SupportedAlgorithm::SupportedAlgorithm (const SupportedAlgorithm &)
+{
+  Asn1Error << "use of incompletely defined SupportedAlgorithm::SupportedAlgorithm (const SupportedAlgorithm &)" << endl;
+  abort();
+}
+
+SupportedAlgorithm::~SupportedAlgorithm()
+{
+  delete algorithmIdentifier;
+  delete intendedUsage;
+  delete intendedCertificatePolicies;
+}
+
+AsnType *SupportedAlgorithm::Clone() const
+{
+  return new SupportedAlgorithm;
+}
+
+AsnType *SupportedAlgorithm::Copy() const
+{
+  return new SupportedAlgorithm (*this);
+}
+
+#if SNACC_DEEP_COPY
+SupportedAlgorithm &SupportedAlgorithm::operator = (const SupportedAlgorithm &that)
+#else // SNACC_DEEP_COPY
+SupportedAlgorithm &SupportedAlgorithm::operator = (const SupportedAlgorithm &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.algorithmIdentifier)
+    {
+      if (!algorithmIdentifier)
+        algorithmIdentifier = new AlgorithmIdentifier;
+      *algorithmIdentifier = *that.algorithmIdentifier;
+    }
+    else
+    {
+      delete algorithmIdentifier;
+      algorithmIdentifier = NULL;
+    }
+    if (that.intendedUsage)
+    {
+      if (!intendedUsage)
+        intendedUsage = new KeyUsage;
+      *intendedUsage = *that.intendedUsage;
+    }
+    else
+    {
+      delete intendedUsage;
+      intendedUsage = NULL;
+    }
+    if (that.intendedCertificatePolicies)
+    {
+      if (!intendedCertificatePolicies)
+        intendedCertificatePolicies = new CertificatePoliciesSyntax;
+      *intendedCertificatePolicies = *that.intendedCertificatePolicies;
+    }
+    else
+    {
+      delete intendedCertificatePolicies;
+      intendedCertificatePolicies = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined SupportedAlgorithm &SupportedAlgorithm::operator = (const SupportedAlgorithm &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+SupportedAlgorithm::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (intendedCertificatePolicies))
+  {
+      BEncEocIfNec (b);
+    l = intendedCertificatePolicies->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (intendedUsage))
+  {
+    l = intendedUsage->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+  }
+
+      BEncEocIfNec (b);
+    l = algorithmIdentifier->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    totalLen += l;
+
+  return totalLen;
+} // SupportedAlgorithm::BEncContent
+
+
+void SupportedAlgorithm::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    algorithmIdentifier = new AlgorithmIdentifier;
+    algorithmIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -132);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    intendedUsage = new KeyUsage;
+    intendedUsage->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    intendedCertificatePolicies = new CertificatePoliciesSyntax;
+    intendedCertificatePolicies->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -133);
+  }
+  else
+    return;
+} // SupportedAlgorithm::BDecContent
+
+AsnLen SupportedAlgorithm::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void SupportedAlgorithm::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "SupportedAlgorithm::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -134);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int SupportedAlgorithm::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int SupportedAlgorithm::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void SupportedAlgorithm::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (algorithmIdentifier))
+  {
+    Indent (os, indentG);
+    os << "algorithmIdentifier ";
+    os << *algorithmIdentifier;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "algorithmIdentifier ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (intendedUsage))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "intendedUsage ";
+    os << *intendedUsage;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "intendedUsage ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (intendedCertificatePolicies))
+  {
+    os << ","<< endl;
+    Indent (os, indentG);
+    os << "intendedCertificatePolicies ";
+    os << *intendedCertificatePolicies;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "intendedCertificatePolicies ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // SupportedAlgorithm::Print
+
+
+BasicConstraintsSyntax::BasicConstraintsSyntax()
+{
+  cA = NULL;
+  pathLenConstraint = NULL;
+}
+
+BasicConstraintsSyntax::BasicConstraintsSyntax (const BasicConstraintsSyntax &)
+{
+  Asn1Error << "use of incompletely defined BasicConstraintsSyntax::BasicConstraintsSyntax (const BasicConstraintsSyntax &)" << endl;
+  abort();
+}
+
+BasicConstraintsSyntax::~BasicConstraintsSyntax()
+{
+  delete cA;
+  delete pathLenConstraint;
+}
+
+AsnType *BasicConstraintsSyntax::Clone() const
+{
+  return new BasicConstraintsSyntax;
+}
+
+AsnType *BasicConstraintsSyntax::Copy() const
+{
+  return new BasicConstraintsSyntax (*this);
+}
+
+#if SNACC_DEEP_COPY
+BasicConstraintsSyntax &BasicConstraintsSyntax::operator = (const BasicConstraintsSyntax &that)
+#else // SNACC_DEEP_COPY
+BasicConstraintsSyntax &BasicConstraintsSyntax::operator = (const BasicConstraintsSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.cA)
+    {
+      if (!cA)
+        cA = new AsnBool;
+      *cA = *that.cA;
+    }
+    else
+    {
+      delete cA;
+      cA = NULL;
+    }
+    if (that.pathLenConstraint)
+    {
+      if (!pathLenConstraint)
+        pathLenConstraint = new AsnInt;
+      *pathLenConstraint = *that.pathLenConstraint;
+    }
+    else
+    {
+      delete pathLenConstraint;
+      pathLenConstraint = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined BasicConstraintsSyntax &BasicConstraintsSyntax::operator = (const BasicConstraintsSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+BasicConstraintsSyntax::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (pathLenConstraint))
+  {
+    l = pathLenConstraint->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (cA))
+  {
+    l = cA->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // BasicConstraintsSyntax::BEncContent
+
+
+void BasicConstraintsSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    cA = new AsnBool;
+    cA->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    pathLenConstraint = new AsnInt;
+    pathLenConstraint->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -135);
+  }
+  else
+    return;
+} // BasicConstraintsSyntax::BDecContent
+
+AsnLen BasicConstraintsSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void BasicConstraintsSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "BasicConstraintsSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -136);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int BasicConstraintsSyntax::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int BasicConstraintsSyntax::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void BasicConstraintsSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (cA))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "cA ";
+    os << *cA;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "cA ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (pathLenConstraint))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "pathLenConstraint ";
+    os << *pathLenConstraint;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "pathLenConstraint ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // BasicConstraintsSyntax::Print
+
+
+NameConstraintsSyntax::NameConstraintsSyntax()
+{
+  permittedSubtrees = NULL;
+  excludedSubtrees = NULL;
+}
+
+NameConstraintsSyntax::NameConstraintsSyntax (const NameConstraintsSyntax &)
+{
+  Asn1Error << "use of incompletely defined NameConstraintsSyntax::NameConstraintsSyntax (const NameConstraintsSyntax &)" << endl;
+  abort();
+}
+
+NameConstraintsSyntax::~NameConstraintsSyntax()
+{
+  delete permittedSubtrees;
+  delete excludedSubtrees;
+}
+
+AsnType *NameConstraintsSyntax::Clone() const
+{
+  return new NameConstraintsSyntax;
+}
+
+AsnType *NameConstraintsSyntax::Copy() const
+{
+  return new NameConstraintsSyntax (*this);
+}
+
+#if SNACC_DEEP_COPY
+NameConstraintsSyntax &NameConstraintsSyntax::operator = (const NameConstraintsSyntax &that)
+#else // SNACC_DEEP_COPY
+NameConstraintsSyntax &NameConstraintsSyntax::operator = (const NameConstraintsSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.permittedSubtrees)
+    {
+      if (!permittedSubtrees)
+        permittedSubtrees = new GeneralSubtrees;
+      *permittedSubtrees = *that.permittedSubtrees;
+    }
+    else
+    {
+      delete permittedSubtrees;
+      permittedSubtrees = NULL;
+    }
+    if (that.excludedSubtrees)
+    {
+      if (!excludedSubtrees)
+        excludedSubtrees = new GeneralSubtrees;
+      *excludedSubtrees = *that.excludedSubtrees;
+    }
+    else
+    {
+      delete excludedSubtrees;
+      excludedSubtrees = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined NameConstraintsSyntax &NameConstraintsSyntax::operator = (const NameConstraintsSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+NameConstraintsSyntax::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (excludedSubtrees))
+  {
+      BEncEocIfNec (b);
+    l = excludedSubtrees->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (permittedSubtrees))
+  {
+      BEncEocIfNec (b);
+    l = permittedSubtrees->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // NameConstraintsSyntax::BEncContent
+
+
+void NameConstraintsSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    permittedSubtrees = new GeneralSubtrees;
+    permittedSubtrees->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    excludedSubtrees = new GeneralSubtrees;
+    excludedSubtrees->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -137);
+  }
+  else
+    return;
+} // NameConstraintsSyntax::BDecContent
+
+AsnLen NameConstraintsSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void NameConstraintsSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "NameConstraintsSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -138);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int NameConstraintsSyntax::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int NameConstraintsSyntax::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void NameConstraintsSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (permittedSubtrees))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "permittedSubtrees ";
+    os << *permittedSubtrees;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "permittedSubtrees ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (excludedSubtrees))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "excludedSubtrees ";
+    os << *excludedSubtrees;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "excludedSubtrees ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // NameConstraintsSyntax::Print
+
+
+PolicyConstraintsSyntax::PolicyConstraintsSyntax()
+{
+  requireExplicitPolicy = NULL;
+  inhibitPolicyMapping = NULL;
+}
+
+PolicyConstraintsSyntax::PolicyConstraintsSyntax (const PolicyConstraintsSyntax &)
+{
+  Asn1Error << "use of incompletely defined PolicyConstraintsSyntax::PolicyConstraintsSyntax (const PolicyConstraintsSyntax &)" << endl;
+  abort();
+}
+
+PolicyConstraintsSyntax::~PolicyConstraintsSyntax()
+{
+  delete requireExplicitPolicy;
+  delete inhibitPolicyMapping;
+}
+
+AsnType *PolicyConstraintsSyntax::Clone() const
+{
+  return new PolicyConstraintsSyntax;
+}
+
+AsnType *PolicyConstraintsSyntax::Copy() const
+{
+  return new PolicyConstraintsSyntax (*this);
+}
+
+#if SNACC_DEEP_COPY
+PolicyConstraintsSyntax &PolicyConstraintsSyntax::operator = (const PolicyConstraintsSyntax &that)
+#else // SNACC_DEEP_COPY
+PolicyConstraintsSyntax &PolicyConstraintsSyntax::operator = (const PolicyConstraintsSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.requireExplicitPolicy)
+    {
+      if (!requireExplicitPolicy)
+        requireExplicitPolicy = new SkipCerts;
+      *requireExplicitPolicy = *that.requireExplicitPolicy;
+    }
+    else
+    {
+      delete requireExplicitPolicy;
+      requireExplicitPolicy = NULL;
+    }
+    if (that.inhibitPolicyMapping)
+    {
+      if (!inhibitPolicyMapping)
+        inhibitPolicyMapping = new SkipCerts;
+      *inhibitPolicyMapping = *that.inhibitPolicyMapping;
+    }
+    else
+    {
+      delete inhibitPolicyMapping;
+      inhibitPolicyMapping = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined PolicyConstraintsSyntax &PolicyConstraintsSyntax::operator = (const PolicyConstraintsSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+PolicyConstraintsSyntax::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (inhibitPolicyMapping))
+  {
+    l = inhibitPolicyMapping->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (requireExplicitPolicy))
+  {
+    l = requireExplicitPolicy->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // PolicyConstraintsSyntax::BEncContent
+
+
+void PolicyConstraintsSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    requireExplicitPolicy = new SkipCerts;
+    requireExplicitPolicy->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    inhibitPolicyMapping = new SkipCerts;
+    inhibitPolicyMapping->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -139);
+  }
+  else
+    return;
+} // PolicyConstraintsSyntax::BDecContent
+
+AsnLen PolicyConstraintsSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void PolicyConstraintsSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "PolicyConstraintsSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -140);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PolicyConstraintsSyntax::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PolicyConstraintsSyntax::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void PolicyConstraintsSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (requireExplicitPolicy))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "requireExplicitPolicy ";
+    os << *requireExplicitPolicy;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "requireExplicitPolicy ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (inhibitPolicyMapping))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "inhibitPolicyMapping ";
+    os << *inhibitPolicyMapping;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "inhibitPolicyMapping ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // PolicyConstraintsSyntax::Print
+
+
+AsnType *CertPolicySet::Clone() const
+{
+  return new CertPolicySet;
+}
+
+AsnType *CertPolicySet::Copy() const
+{
+  return new CertPolicySet (*this);
+}
+
+AsnLen CertPolicySet::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CertPolicySet::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CertPolicySet::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -141);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+CertPolicySet::CertPolicySet (const CertPolicySet &)
+{
+  Asn1Error << "use of incompletely defined CertPolicySet::CertPolicySet (const CertPolicySet &)" << endl;
+  abort();
+}
+
+CertPolicySet::~CertPolicySet()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+CertPolicySet &CertPolicySet::operator = (const CertPolicySet &that)
+#else // SNACC_DEEP_COPY
+CertPolicySet &CertPolicySet::operator = (const CertPolicySet &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CertPolicySet &CertPolicySet::operator = (const CertPolicySet &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void CertPolicySet::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  CertPolicySet::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // CertPolicySet::SetCurrElmt
+
+
+unsigned long int  CertPolicySet::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // CertPolicySet::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+CertPolicyId *CertPolicySet::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new CertPolicyId;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertPolicySet::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+CertPolicyId  *CertPolicySet::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertPolicyId;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertPolicySet::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertPolicyId  *CertPolicySet::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertPolicyId;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertPolicySet::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertPolicyId *CertPolicySet::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertPolicyId;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CertPolicySet::InsertAfter
+
+
+CertPolicySet  &CertPolicySet::AppendCopy (CertPolicyId &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertPolicyId;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+CertPolicySet  &CertPolicySet::PrependCopy (CertPolicyId &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertPolicyId;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // CertPolicySet::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CertPolicySet &CertPolicySet::InsertBeforeAndCopy (CertPolicyId &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertPolicyId;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // CertPolicySet::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CertPolicySet  &CertPolicySet::InsertAfterAndCopy (CertPolicyId &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new CertPolicyId;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // CertPolicySet::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void CertPolicySet::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen CertPolicySet::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncDefLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // CertPolicySet::BEncContent
+
+
+void  CertPolicySet::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    CertPolicyId *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -142);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // CertPolicySet::BDecContent
+
+
+AsnType *CRLDistPointsSyntax::Clone() const
+{
+  return new CRLDistPointsSyntax;
+}
+
+AsnType *CRLDistPointsSyntax::Copy() const
+{
+  return new CRLDistPointsSyntax (*this);
+}
+
+AsnLen CRLDistPointsSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void CRLDistPointsSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "CRLDistPointsSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -143);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+CRLDistPointsSyntax::CRLDistPointsSyntax (const CRLDistPointsSyntax &)
+{
+  Asn1Error << "use of incompletely defined CRLDistPointsSyntax::CRLDistPointsSyntax (const CRLDistPointsSyntax &)" << endl;
+  abort();
+}
+
+CRLDistPointsSyntax::~CRLDistPointsSyntax()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+CRLDistPointsSyntax &CRLDistPointsSyntax::operator = (const CRLDistPointsSyntax &that)
+#else // SNACC_DEEP_COPY
+CRLDistPointsSyntax &CRLDistPointsSyntax::operator = (const CRLDistPointsSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined CRLDistPointsSyntax &CRLDistPointsSyntax::operator = (const CRLDistPointsSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void CRLDistPointsSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  CRLDistPointsSyntax::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // CRLDistPointsSyntax::SetCurrElmt
+
+
+unsigned long int  CRLDistPointsSyntax::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // CRLDistPointsSyntax::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+DistributionPoint *CRLDistPointsSyntax::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new DistributionPoint;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CRLDistPointsSyntax::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+DistributionPoint  *CRLDistPointsSyntax::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DistributionPoint;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CRLDistPointsSyntax::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+DistributionPoint  *CRLDistPointsSyntax::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DistributionPoint;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CRLDistPointsSyntax::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+DistributionPoint *CRLDistPointsSyntax::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DistributionPoint;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // CRLDistPointsSyntax::InsertAfter
+
+
+CRLDistPointsSyntax  &CRLDistPointsSyntax::AppendCopy (DistributionPoint &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DistributionPoint;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+CRLDistPointsSyntax  &CRLDistPointsSyntax::PrependCopy (DistributionPoint &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DistributionPoint;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // CRLDistPointsSyntax::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+CRLDistPointsSyntax &CRLDistPointsSyntax::InsertBeforeAndCopy (DistributionPoint &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DistributionPoint;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // CRLDistPointsSyntax::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+CRLDistPointsSyntax  &CRLDistPointsSyntax::InsertAfterAndCopy (DistributionPoint &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new DistributionPoint;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // CRLDistPointsSyntax::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void CRLDistPointsSyntax::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen CRLDistPointsSyntax::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+      BEncEocIfNec (b);
+        elmtLen = currElmt->elmt->BEncContent (b);
+    elmtLen += BEncConsLen (b, elmtLen);
+
+    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // CRLDistPointsSyntax::BEncContent
+
+
+void  CRLDistPointsSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    DistributionPoint *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -144);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // CRLDistPointsSyntax::BDecContent
+
+
+IssuingDistPointSyntax::IssuingDistPointSyntax()
+{
+  distributionPoint = NULL;
+  onlyContainsUserCerts = NULL;
+  onlyContainsCACerts = NULL;
+  onlySomeReasons = NULL;
+  indirectCRL = NULL;
+}
+
+IssuingDistPointSyntax::IssuingDistPointSyntax (const IssuingDistPointSyntax &)
+{
+  Asn1Error << "use of incompletely defined IssuingDistPointSyntax::IssuingDistPointSyntax (const IssuingDistPointSyntax &)" << endl;
+  abort();
+}
+
+IssuingDistPointSyntax::~IssuingDistPointSyntax()
+{
+  delete distributionPoint;
+  delete onlyContainsUserCerts;
+  delete onlyContainsCACerts;
+  delete onlySomeReasons;
+  delete indirectCRL;
+}
+
+AsnType *IssuingDistPointSyntax::Clone() const
+{
+  return new IssuingDistPointSyntax;
+}
+
+AsnType *IssuingDistPointSyntax::Copy() const
+{
+  return new IssuingDistPointSyntax (*this);
+}
+
+#if SNACC_DEEP_COPY
+IssuingDistPointSyntax &IssuingDistPointSyntax::operator = (const IssuingDistPointSyntax &that)
+#else // SNACC_DEEP_COPY
+IssuingDistPointSyntax &IssuingDistPointSyntax::operator = (const IssuingDistPointSyntax &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.distributionPoint)
+    {
+      if (!distributionPoint)
+        distributionPoint = new DistributionPointName;
+      *distributionPoint = *that.distributionPoint;
+    }
+    else
+    {
+      delete distributionPoint;
+      distributionPoint = NULL;
+    }
+    if (that.onlyContainsUserCerts)
+    {
+      if (!onlyContainsUserCerts)
+        onlyContainsUserCerts = new AsnBool;
+      *onlyContainsUserCerts = *that.onlyContainsUserCerts;
+    }
+    else
+    {
+      delete onlyContainsUserCerts;
+      onlyContainsUserCerts = NULL;
+    }
+    if (that.onlyContainsCACerts)
+    {
+      if (!onlyContainsCACerts)
+        onlyContainsCACerts = new AsnBool;
+      *onlyContainsCACerts = *that.onlyContainsCACerts;
+    }
+    else
+    {
+      delete onlyContainsCACerts;
+      onlyContainsCACerts = NULL;
+    }
+    if (that.onlySomeReasons)
+    {
+      if (!onlySomeReasons)
+        onlySomeReasons = new ReasonFlags;
+      *onlySomeReasons = *that.onlySomeReasons;
+    }
+    else
+    {
+      delete onlySomeReasons;
+      onlySomeReasons = NULL;
+    }
+    if (that.indirectCRL)
+    {
+      if (!indirectCRL)
+        indirectCRL = new AsnBool;
+      *indirectCRL = *that.indirectCRL;
+    }
+    else
+    {
+      delete indirectCRL;
+      indirectCRL = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined IssuingDistPointSyntax &IssuingDistPointSyntax::operator = (const IssuingDistPointSyntax &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+IssuingDistPointSyntax::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+  if (NOT_NULL (indirectCRL))
+  {
+    l = indirectCRL->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 4);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (onlySomeReasons))
+  {
+    l = onlySomeReasons->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 3);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (onlyContainsCACerts))
+  {
+    l = onlyContainsCACerts->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 2);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (onlyContainsUserCerts))
+  {
+    l = onlyContainsUserCerts->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (distributionPoint))
+  {
+      BEncEocIfNec (b);
+    l = distributionPoint->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // IssuingDistPointSyntax::BEncContent
+
+
+void IssuingDistPointSyntax::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  if (elmtLen0 == 0)
+    return;
+  else
+  {
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+
+    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+    {
+      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    distributionPoint = new DistributionPointName;
+    distributionPoint->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    onlyContainsUserCerts = new AsnBool;
+    onlyContainsUserCerts->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    onlyContainsCACerts = new AsnBool;
+    onlyContainsCACerts->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 3))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 3)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    onlySomeReasons = new ReasonFlags;
+    onlySomeReasons->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    if (seqBytesDecoded == elmtLen0)
+    {
+      bytesDecoded += seqBytesDecoded;
+      return;
+    }
+    else
+    {
+      tag1 = BDecTag (b, seqBytesDecoded, env);
+
+      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
+      {
+        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
+        bytesDecoded += seqBytesDecoded;
+        return;
+      }
+    }
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 4)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    indirectCRL = new AsnBool;
+    indirectCRL->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -145);
+  }
+  else
+    return;
+} // IssuingDistPointSyntax::BDecContent
+
+AsnLen IssuingDistPointSyntax::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void IssuingDistPointSyntax::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "IssuingDistPointSyntax::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -146);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int IssuingDistPointSyntax::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int IssuingDistPointSyntax::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void IssuingDistPointSyntax::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  int nonePrinted = true;
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (distributionPoint))
+  {
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "distributionPoint ";
+    os << *distributionPoint;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "distributionPoint ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (onlyContainsUserCerts))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "onlyContainsUserCerts ";
+    os << *onlyContainsUserCerts;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "onlyContainsUserCerts ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (onlyContainsCACerts))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "onlyContainsCACerts ";
+    os << *onlyContainsCACerts;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "onlyContainsCACerts ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (onlySomeReasons))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "onlySomeReasons ";
+    os << *onlySomeReasons;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "onlySomeReasons ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (indirectCRL))
+  {
+    if (!nonePrinted)
+      os << "," << endl;
+    nonePrinted = false;
+    Indent (os, indentG);
+    os << "indirectCRL ";
+    os << *indirectCRL;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "indirectCRL ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // IssuingDistPointSyntax::Print
+
+
diff --git a/SecurityASN1/c++/sm_x509cmn.cpp b/SecurityASN1/c++/sm_x509cmn.cpp
new file mode 100644
index 00000000..215f1136
--- /dev/null
+++ b/SecurityASN1/c++/sm_x509cmn.cpp
@@ -0,0 +1,1149 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x509cmn.cpp - class member functions for ASN.1 module CommonX509Definitions
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+EDIPartyName::EDIPartyName()
+{
+  nameAssigner = NULL;
+#if TCL
+  partyName = new DirectoryString;
+#else
+  partyName = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EDIPartyName::EDIPartyName (const EDIPartyName &)
+{
+  Asn1Error << "use of incompletely defined EDIPartyName::EDIPartyName (const EDIPartyName &)" << endl;
+  abort();
+}
+
+EDIPartyName::~EDIPartyName()
+{
+  delete nameAssigner;
+  delete partyName;
+}
+
+AsnType *EDIPartyName::Clone() const
+{
+  return new EDIPartyName;
+}
+
+AsnType *EDIPartyName::Copy() const
+{
+  return new EDIPartyName (*this);
+}
+
+#if SNACC_DEEP_COPY
+EDIPartyName &EDIPartyName::operator = (const EDIPartyName &that)
+#else // SNACC_DEEP_COPY
+EDIPartyName &EDIPartyName::operator = (const EDIPartyName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.nameAssigner)
+    {
+      if (!nameAssigner)
+        nameAssigner = new DirectoryString;
+      *nameAssigner = *that.nameAssigner;
+    }
+    else
+    {
+      delete nameAssigner;
+      nameAssigner = NULL;
+    }
+    if (that.partyName)
+    {
+      if (!partyName)
+        partyName = new DirectoryString;
+      *partyName = *that.partyName;
+    }
+    else
+    {
+      delete partyName;
+      partyName = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EDIPartyName &EDIPartyName::operator = (const EDIPartyName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EDIPartyName::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+      BEncEocIfNec (b);
+    l = partyName->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 1);
+    totalLen += l;
+
+  if (NOT_NULL (nameAssigner))
+  {
+      BEncEocIfNec (b);
+    l = nameAssigner->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // EDIPartyName::BEncContent
+
+
+void EDIPartyName::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  AsnLen elmtLen2;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    nameAssigner = new DirectoryString;
+    nameAssigner->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
+    partyName = new DirectoryString;
+    partyName->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+      BDecEoc (b, seqBytesDecoded, env);
+
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, -100);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, -101);
+  }
+  else
+    return;
+} // EDIPartyName::BDecContent
+
+AsnLen EDIPartyName::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void EDIPartyName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "EDIPartyName::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -102);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EDIPartyName::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EDIPartyName::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EDIPartyName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (nameAssigner))
+  {
+    Indent (os, indentG);
+    os << "nameAssigner ";
+    os << *nameAssigner;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "nameAssigner ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (partyName))
+  {
+    Indent (os, indentG);
+    os << "partyName ";
+    os << *partyName;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "partyName ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+#endif /* NDEBUG */
+} // EDIPartyName::Print
+
+
+GeneralName::GeneralName()
+{
+  choiceId = otherNameCid;
+#if TCL
+  otherName = new OTHER_NAME;
+#else
+  otherName = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+GeneralName::GeneralName (const GeneralName &)
+{
+  Asn1Error << "use of incompletely defined GeneralName::GeneralName (const GeneralName &)" << endl;
+  abort();
+}
+
+GeneralName::~GeneralName()
+{
+  switch (choiceId)
+  {
+    case otherNameCid:
+      delete otherName;
+      break;
+    case rfc822NameCid:
+      delete rfc822Name;
+      break;
+    case dNSNameCid:
+      delete dNSName;
+      break;
+    case x400AddressCid:
+      delete x400Address;
+      break;
+    case directoryNameCid:
+      delete directoryName;
+      break;
+    case ediPartyNameCid:
+      delete ediPartyName;
+      break;
+    case uniformResourceIdentifierCid:
+      delete uniformResourceIdentifier;
+      break;
+    case iPAddressCid:
+      delete iPAddress;
+      break;
+    case registeredIDCid:
+      delete registeredID;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *GeneralName::Clone() const
+{
+  return new GeneralName;
+}
+
+AsnType *GeneralName::Copy() const
+{
+  return new GeneralName (*this);
+}
+
+#if SNACC_DEEP_COPY
+GeneralName &GeneralName::operator = (const GeneralName &that)
+#else // SNACC_DEEP_COPY
+GeneralName &GeneralName::operator = (const GeneralName &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case otherNameCid:
+        delete otherName;
+        break;
+      case rfc822NameCid:
+        delete rfc822Name;
+        break;
+      case dNSNameCid:
+        delete dNSName;
+        break;
+      case x400AddressCid:
+        delete x400Address;
+        break;
+      case directoryNameCid:
+        delete directoryName;
+        break;
+      case ediPartyNameCid:
+        delete ediPartyName;
+        break;
+      case uniformResourceIdentifierCid:
+        delete uniformResourceIdentifier;
+        break;
+      case iPAddressCid:
+        delete iPAddress;
+        break;
+      case registeredIDCid:
+        delete registeredID;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case otherNameCid:
+        otherName = new OTHER_NAME;
+        *otherName = *that.otherName;
+        break;
+      case rfc822NameCid:
+        rfc822Name = new IA5String;
+        *rfc822Name = *that.rfc822Name;
+        break;
+      case dNSNameCid:
+        dNSName = new IA5String;
+        *dNSName = *that.dNSName;
+        break;
+      case x400AddressCid:
+        x400Address = new ORAddress;
+        *x400Address = *that.x400Address;
+        break;
+      case directoryNameCid:
+        directoryName = new Name;
+        *directoryName = *that.directoryName;
+        break;
+      case ediPartyNameCid:
+        ediPartyName = new EDIPartyName;
+        *ediPartyName = *that.ediPartyName;
+        break;
+      case uniformResourceIdentifierCid:
+        uniformResourceIdentifier = new IA5String;
+        *uniformResourceIdentifier = *that.uniformResourceIdentifier;
+        break;
+      case iPAddressCid:
+        iPAddress = new AsnOcts;
+        *iPAddress = *that.iPAddress;
+        break;
+      case registeredIDCid:
+        registeredID = new AsnOid;
+        *registeredID = *that.registeredID;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined GeneralName &GeneralName::operator = (const GeneralName &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+GeneralName::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case otherNameCid:
+      l = otherName->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 0);
+      break;
+
+    case rfc822NameCid:
+      l = rfc822Name->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+      break;
+
+    case dNSNameCid:
+      l = dNSName->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 2);
+      break;
+
+    case x400AddressCid:
+      BEncEocIfNec (b);
+      l = x400Address->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 3);
+      break;
+
+    case directoryNameCid:
+      BEncEocIfNec (b);
+      l = directoryName->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 4);
+      break;
+
+    case ediPartyNameCid:
+      BEncEocIfNec (b);
+      l = ediPartyName->BEncContent (b);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 5);
+      break;
+
+    case uniformResourceIdentifierCid:
+      l = uniformResourceIdentifier->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 6);
+      break;
+
+    case iPAddressCid:
+      l = iPAddress->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 7);
+      break;
+
+    case registeredIDCid:
+      l = registeredID->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 8);
+      break;
+
+  } // end switch
+  return l;
+} // GeneralName::BEncContent
+
+
+void GeneralName::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnLen elmtLen1;
+  switch (tag)
+  {
+    case MAKE_TAG_ID (CNTX, PRIM, 0):
+      choiceId = otherNameCid;
+      otherName = new OTHER_NAME;
+        otherName->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 1):
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = rfc822NameCid;
+      rfc822Name = new IA5String;
+        rfc822Name->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 2):
+    case MAKE_TAG_ID (CNTX, CONS, 2):
+      choiceId = dNSNameCid;
+      dNSName = new IA5String;
+        dNSName->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 3):
+      choiceId = x400AddressCid;
+      x400Address = new ORAddress;
+        x400Address->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 4):
+      tag = BDecTag (b, bytesDecoded, env);
+      elmtLen1 = BDecLen (b, bytesDecoded, env);
+      choiceId = directoryNameCid;
+      directoryName = new Name;
+        directoryName->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+      if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, CONS, 5):
+      choiceId = ediPartyNameCid;
+      ediPartyName = new EDIPartyName;
+        ediPartyName->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 6):
+    case MAKE_TAG_ID (CNTX, CONS, 6):
+      choiceId = uniformResourceIdentifierCid;
+      uniformResourceIdentifier = new IA5String;
+        uniformResourceIdentifier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 7):
+    case MAKE_TAG_ID (CNTX, CONS, 7):
+      choiceId = iPAddressCid;
+      iPAddress = new AsnOcts;
+        iPAddress->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 8):
+      choiceId = registeredIDCid;
+      registeredID = new AsnOid;
+        registeredID->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -103);
+      break;
+  } // end switch
+} // GeneralName::BDecContent
+
+
+AsnLen GeneralName::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void GeneralName::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int GeneralName::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int GeneralName::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void GeneralName::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case otherNameCid:
+      os << "otherName ";
+      if (otherName)
+        os << *otherName;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case rfc822NameCid:
+      os << "rfc822Name ";
+      if (rfc822Name)
+        os << *rfc822Name;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case dNSNameCid:
+      os << "dNSName ";
+      if (dNSName)
+        os << *dNSName;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case x400AddressCid:
+      os << "x400Address ";
+      if (x400Address)
+        os << *x400Address;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case directoryNameCid:
+      os << "directoryName ";
+      if (directoryName)
+        os << *directoryName;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case ediPartyNameCid:
+      os << "ediPartyName ";
+      if (ediPartyName)
+        os << *ediPartyName;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case uniformResourceIdentifierCid:
+      os << "uniformResourceIdentifier ";
+      if (uniformResourceIdentifier)
+        os << *uniformResourceIdentifier;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case iPAddressCid:
+      os << "iPAddress ";
+      if (iPAddress)
+        os << *iPAddress;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case registeredIDCid:
+      os << "registeredID ";
+      if (registeredID)
+        os << *registeredID;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // GeneralName::Print
+
+AsnType *GeneralNames::Clone() const
+{
+  return new GeneralNames;
+}
+
+AsnType *GeneralNames::Copy() const
+{
+  return new GeneralNames (*this);
+}
+
+AsnLen GeneralNames::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+  return l;
+}
+
+void GeneralNames::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+  {
+    Asn1Error << "GeneralNames::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, -104);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+GeneralNames::GeneralNames (const GeneralNames &)
+{
+  Asn1Error << "use of incompletely defined GeneralNames::GeneralNames (const GeneralNames &)" << endl;
+  abort();
+}
+
+GeneralNames::~GeneralNames()
+{
+  SetCurrToFirst();
+  for (; Curr() != NULL; RemoveCurrFromList())
+    ;
+} // end of destructor
+
+#if SNACC_DEEP_COPY
+GeneralNames &GeneralNames::operator = (const GeneralNames &that)
+#else // SNACC_DEEP_COPY
+GeneralNames &GeneralNames::operator = (const GeneralNames &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    SetCurrToFirst();
+    for (; Curr(); RemoveCurrFromList())
+      ;
+
+    //that.SetCurrToFirst();
+    //for (; that.Curr(); that.GoNext())
+    //  AppendCopy (*that.Curr());
+    for (const AsnListElmt *run=that.first; run; run=run->next)
+      AppendCopy (*run->elmt);
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined GeneralNames &GeneralNames::operator = (const GeneralNames &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+void GeneralNames::Print (ostream &os) const
+{
+#ifndef NDEBUG
+    os << "{ -- SEQUENCE/SET OF -- " << endl;
+    indentG += stdIndentG;
+    //SetCurrToFirst();
+    //for (; Curr() != NULL; GoNext())
+    for (const AsnListElmt *run=first; run; run=run->next)
+    {
+        Indent (os, indentG);
+        //os << *Curr();
+        os << *run->elmt;
+        //if (Curr() != Last())
+        if (run != last)
+            os << ",";
+        os << endl;
+    }
+    indentG -= stdIndentG;
+    Indent (os, indentG);
+    os << "}\n";
+#endif /* NDEBUG */
+
+
+} // Print
+
+
+void  GeneralNames::SetCurrElmt (unsigned long int index)
+{
+  unsigned long int i;
+  curr = first;
+  if (count)
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+      curr = curr->next;
+} // GeneralNames::SetCurrElmt
+
+
+unsigned long int  GeneralNames::GetCurrElmtIndex()
+{
+    unsigned long int i;
+    AsnListElmt *tmp;
+    if (curr != NULL)
+    {
+        for (i = 0, tmp = first; tmp != NULL; i++)
+        {
+            if (tmp == curr)
+                return i;
+            else
+                tmp = tmp->next;
+        }
+    }
+    return count;
+} // GeneralNames::GetCurrElmtIndex
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+GeneralName *GeneralNames::Append()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt  = new GeneralName;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // GeneralNames::Append
+
+
+// alloc new list elmt, put at begining of list
+//  and return the component type
+GeneralName  *GeneralNames::Prepend()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralName;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // GeneralNames::Prepend
+
+
+// alloc new list elmt, insert it before the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+GeneralName  *GeneralNames::InsertBefore()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralName;
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // GeneralNames::InsertBefore
+
+
+// alloc new list elmt, insert it after the
+// current element and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+GeneralName *GeneralNames::InsertAfter()
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralName;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return (curr = newElmt)->elmt;
+} // GeneralNames::InsertAfter
+
+
+GeneralNames  &GeneralNames::AppendCopy (GeneralName &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralName;
+    *newElmt->elmt = elmt;
+    newElmt->next = NULL;
+    if (last == NULL)
+    {
+        newElmt->prev = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->prev = last;
+        last->next    = newElmt;
+        last          = newElmt;
+    }
+    count++;
+    return *this;
+} // AppendCopy
+
+
+GeneralNames  &GeneralNames::PrependCopy (GeneralName &elmt)
+{
+    AsnListElmt *newElmt;
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralName;
+    *newElmt->elmt = elmt;
+    newElmt->prev = NULL;
+    if (first == NULL)
+    {
+        newElmt->next = NULL;
+        first = last  = newElmt;
+    }
+    else
+    {
+        newElmt->next = first;
+        first->prev   = newElmt;
+        first         = newElmt;
+    }
+    count++;
+    return *this;
+} // GeneralNames::PrependCopy
+
+
+// alloc new list elmt, insert it before the
+// current element, copy the given elmt into the new elmt
+// and return the component type.
+// if the current element is null, the new element
+// is placed at the beginning of the list.
+GeneralNames &GeneralNames::InsertBeforeAndCopy (GeneralName &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralName;
+    *newElmt->elmt = elmt;
+
+    if (curr == NULL)
+    {
+        newElmt->next = first;
+        newElmt->prev = NULL;
+        first = newElmt;
+        if (last == NULL)
+            last = newElmt;
+    }
+    else
+    {
+        newElmt->next = curr;
+        newElmt->prev = curr->prev;
+        curr->prev = newElmt;
+        if (curr == first)
+            first = newElmt;
+        else
+            newElmt->prev->next = newElmt;
+    }
+    count++;
+    return *this;
+} // GeneralNames::InsertBeforeAndCopy
+
+
+// alloc new list elmt, insert it after the
+// current element, copy given elmt in to new elmt
+//  and return the component type
+// if the current element is null, the new element
+// is placed at the end of the list.
+GeneralNames  &GeneralNames::InsertAfterAndCopy (GeneralName &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt  = new AsnListElmt;
+    newElmt->elmt = new GeneralName;
+    *newElmt->elmt = elmt;
+    if (curr == NULL)
+    {
+        newElmt->prev = last;
+        newElmt->next = NULL;
+        last = newElmt;
+        if (first == NULL)
+            first = newElmt;
+    }
+    else
+    {
+        newElmt->prev = curr;
+        newElmt->next = curr->next;
+        curr->next = newElmt;
+        if (curr == last)
+            last = newElmt;
+        else
+            newElmt->next->prev = newElmt;
+    }
+    count++;
+    return *this;
+} // GeneralNames::InsertAfterAndCopy
+
+
+// remove current element from list if current element is not NULL 
+// The new current element will be the next element.
+// If the current element is the last element in the list
+// the second but last element will become the new current element.
+void GeneralNames::RemoveCurrFromList()
+{
+    AsnListElmt *del_elmt;
+
+    if (curr != NULL)
+    {
+        del_elmt = curr;
+        count--;
+
+        if (count == 0)
+            first = last = curr = NULL;
+        else if (curr == first)
+        {
+            curr = first= first->next;
+            first->prev = NULL;
+        }
+        else if (curr == last)
+        {
+            curr = last = last->prev;
+            last->next = NULL;
+        }
+        else
+        {
+            curr->prev->next = curr->next;
+            curr->next->prev = curr->prev;
+        }
+
+        delete del_elmt->elmt;
+        delete del_elmt;
+    }
+}
+
+
+AsnLen GeneralNames::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen elmtLen;
+    AsnLen totalLen = 0;
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+    {
+        elmtLen = currElmt->elmt->BEncContent (b);
+        totalLen += elmtLen;
+    }
+    return totalLen;
+} // GeneralNames::BEncContent
+
+
+void  GeneralNames::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
+                                  AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    GeneralName *listElmt;
+    AsnTag tag1;
+    AsnLen listBytesDecoded = 0;
+    AsnLen elmtLen1;
+
+    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
+    {
+        tag1 = BDecTag (b, listBytesDecoded, env);
+        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
+            break;
+        }
+        if (!((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
+         || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
+            || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))
+
+         || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 2))
+            || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2))
+
+         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 3))
+         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 4))
+         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 5))
+         || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 6))
+            || (tag1 == MAKE_TAG_ID (CNTX, CONS, 6))
+
+         || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 7))
+            || (tag1 == MAKE_TAG_ID (CNTX, CONS, 7))
+
+         || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 8))))
+        {
+            Asn1Error << "Unexpected Tag" << endl;
+            longjmp (env, -105);
+        }
+
+        elmtLen1 = BDecLen (b, listBytesDecoded, env);
+        listElmt = Append();
+        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
+    }
+
+    bytesDecoded += listBytesDecoded;
+} // GeneralNames::BDecContent
+
+
diff --git a/SecurityASN1/c++/sm_x520sa.cpp b/SecurityASN1/c++/sm_x520sa.cpp
new file mode 100644
index 00000000..63c4ab30
--- /dev/null
+++ b/SecurityASN1/c++/sm_x520sa.cpp
@@ -0,0 +1,324 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x520sa.cpp - class member functions for ASN.1 module SelectedAttributeTypes
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "sm_vdatypes.h"
+#include "sm_x501ud.h"
+#include "sm_x411ub.h"
+#include "sm_x411mtsas.h"
+#include "sm_x501if.h"
+#include "sm_x520sa.h"
+#include "sm_x509cmn.h"
+#include "sm_x509af.h"
+#include "sm_x509ce.h"
+#include "pkcs1oids.h"
+#include "pkcs9oids.h"
+#include "sm_cms.h"
+#include "sm_ess.h"
+#include "pkcs7.h"
+#include "pkcs8.h"
+#include "appleoids.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+DirectoryString::DirectoryString()
+{
+  choiceId = teletexStringCid;
+#if TCL
+  teletexString = new TeletexString;
+#else
+  teletexString = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+DirectoryString::DirectoryString (const DirectoryString &)
+{
+  Asn1Error << "use of incompletely defined DirectoryString::DirectoryString (const DirectoryString &)" << endl;
+  abort();
+}
+
+DirectoryString::~DirectoryString()
+{
+  switch (choiceId)
+  {
+    case teletexStringCid:
+      delete teletexString;
+      break;
+    case printableStringCid:
+      delete printableString;
+      break;
+    case universalStringCid:
+      delete universalString;
+      break;
+    case bmpStringCid:
+      delete bmpString;
+      break;
+    case utf8StringCid:
+      delete utf8String;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *DirectoryString::Clone() const
+{
+  return new DirectoryString;
+}
+
+AsnType *DirectoryString::Copy() const
+{
+  return new DirectoryString (*this);
+}
+
+#if SNACC_DEEP_COPY
+DirectoryString &DirectoryString::operator = (const DirectoryString &that)
+#else // SNACC_DEEP_COPY
+DirectoryString &DirectoryString::operator = (const DirectoryString &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case teletexStringCid:
+        delete teletexString;
+        break;
+      case printableStringCid:
+        delete printableString;
+        break;
+      case universalStringCid:
+        delete universalString;
+        break;
+      case bmpStringCid:
+        delete bmpString;
+        break;
+      case utf8StringCid:
+        delete utf8String;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case teletexStringCid:
+        teletexString = new TeletexString;
+        *teletexString = *that.teletexString;
+        break;
+      case printableStringCid:
+        printableString = new PrintableString;
+        *printableString = *that.printableString;
+        break;
+      case universalStringCid:
+        universalString = new UniversalString;
+        *universalString = *that.universalString;
+        break;
+      case bmpStringCid:
+        bmpString = new BMPString;
+        *bmpString = *that.bmpString;
+        break;
+      case utf8StringCid:
+        utf8String = new UTF8String;
+        *utf8String = *that.utf8String;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined DirectoryString &DirectoryString::operator = (const DirectoryString &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+DirectoryString::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case teletexStringCid:
+      l = teletexString->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+      break;
+
+    case printableStringCid:
+      l = printableString->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+      break;
+
+    case universalStringCid:
+      l = universalString->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, UNIVERSALSTRING_TAG_CODE);
+      break;
+
+    case bmpStringCid:
+      l = bmpString->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BMPSTRING_TAG_CODE);
+      break;
+
+    case utf8StringCid:
+      l = utf8String->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, 12);
+      break;
+
+  } // end switch
+  return l;
+} // DirectoryString::BEncContent
+
+
+void DirectoryString::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  switch (tag)
+  {
+    case MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE):
+      choiceId = teletexStringCid;
+      teletexString = new TeletexString;
+        teletexString->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE):
+      choiceId = printableStringCid;
+      printableString = new PrintableString;
+        printableString->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, UNIVERSALSTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, UNIVERSALSTRING_TAG_CODE):
+      choiceId = universalStringCid;
+      universalString = new UniversalString;
+        universalString->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, BMPSTRING_TAG_CODE):
+    case MAKE_TAG_ID (UNIV, CONS, BMPSTRING_TAG_CODE):
+      choiceId = bmpStringCid;
+      bmpString = new BMPString;
+        bmpString->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (UNIV, PRIM, 12):
+    case MAKE_TAG_ID (UNIV, CONS, 12):
+      choiceId = utf8StringCid;
+      utf8String = new UTF8String;
+        utf8String->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, -100);
+      break;
+  } // end switch
+} // DirectoryString::BDecContent
+
+
+AsnLen DirectoryString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void DirectoryString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int DirectoryString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int DirectoryString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void DirectoryString::Print (ostream &os) const
+{
+#ifndef NDEBUG
+  switch (choiceId)
+  {
+    case teletexStringCid:
+      os << "teletexString ";
+      if (teletexString)
+        os << *teletexString;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case printableStringCid:
+      os << "printableString ";
+      if (printableString)
+        os << *printableString;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case universalStringCid:
+      os << "universalString ";
+      if (universalString)
+        os << *universalString;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case bmpStringCid:
+      os << "bmpString ";
+      if (bmpString)
+        os << *bmpString;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case utf8StringCid:
+      os << "utf8String ";
+      if (utf8String)
+        os << *utf8String;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+#endif /* NDEBUG */
+} // DirectoryString::Print
+
diff --git a/SecurityASN1/inc/.cvsignore b/SecurityASN1/inc/.cvsignore
new file mode 100644
index 00000000..e69de29b
diff --git a/SecurityASN1/inc/appleoids.h b/SecurityASN1/inc/appleoids.h
new file mode 100644
index 00000000..fbcef0a2
--- /dev/null
+++ b/SecurityASN1/inc/appleoids.h
@@ -0,0 +1,429 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// appleoids.h - class definitions for ASN.1 module APPLE-OIDS
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _appleoids_h_
+#define _appleoids_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class FEEPrimeType;
+class FEECurveType;
+class DSABsafeParams;
+class FEECurveParameters;
+class DSAAlgorithmId;
+class FEEElGamalSignature;
+class FEEECDSASignature;
+class FEEPublicKey;
+class FEEPrivateKey;
+class DSAPrivateKey;
+class DSAPublicKey;
+class DSAPrivateKeyOcts;
+class DSASignature;
+class DSAAlgParams;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+/* INTEGER { pt_mersenne (0), pt_fee (1), pt_general (2) }  */
+class FEEPrimeType: public AsnInt
+{
+public:
+			FEEPrimeType(): AsnInt() {}
+			FEEPrimeType (int i): AsnInt (i) {}
+  enum
+  {
+    pt_mersenne = 0,
+    pt_fee = 1,
+    pt_general = 2
+  };
+};
+
+
+/* INTEGER { ct_montgomery (0), ct_weierstrass (1), ct_general (2) }  */
+class FEECurveType: public AsnInt
+{
+public:
+			FEECurveType(): AsnInt() {}
+			FEECurveType (int i): AsnInt (i) {}
+  enum
+  {
+    ct_montgomery = 0,
+    ct_weierstrass = 1,
+    ct_general = 2
+  };
+};
+
+
+class DSABsafeParams: public AsnType
+{
+public:
+  AsnInt		keySizeInBits;
+  BigIntegerStr		p;
+  BigIntegerStr		q;
+  BigIntegerStr		g;
+
+			DSABsafeParams();
+			DSABsafeParams (const DSABsafeParams &);
+  virtual		~DSABsafeParams();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DSABsafeParams		&operator = (const DSABsafeParams &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class FEECurveParameters: public AsnType
+{
+public:
+  FEEPrimeType		primeType;
+  FEECurveType		curveType;
+  AsnInt		q;
+  AsnInt		k;
+  AsnInt		m;
+  BigIntegerStr		a;
+  BigIntegerStr		bb;
+  BigIntegerStr		c;
+  BigIntegerStr		x1Plus;
+  BigIntegerStr		x1Minus;
+  BigIntegerStr		cOrderPlus;
+  BigIntegerStr		cOrderMinus;
+  BigIntegerStr		x1OrderPlus;
+  BigIntegerStr		x1OrderMinus;
+  BigIntegerStr		*basePrime;
+
+			FEECurveParameters();
+			FEECurveParameters (const FEECurveParameters &);
+  virtual		~FEECurveParameters();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  FEECurveParameters		&operator = (const FEECurveParameters &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DSAAlgorithmId: public AsnType
+{
+public:
+  AsnOid		algorithm;
+  DSABsafeParams		*params;
+
+			DSAAlgorithmId();
+			DSAAlgorithmId (const DSAAlgorithmId &);
+  virtual		~DSAAlgorithmId();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DSAAlgorithmId		&operator = (const DSAAlgorithmId &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class FEEElGamalSignature: public AsnType
+{
+public:
+  BigIntegerStr		u;
+  BigIntegerStr		pmX;
+
+			FEEElGamalSignature();
+			FEEElGamalSignature (const FEEElGamalSignature &);
+  virtual		~FEEElGamalSignature();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  FEEElGamalSignature		&operator = (const FEEElGamalSignature &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class FEEECDSASignature: public AsnType
+{
+public:
+  BigIntegerStr		c;
+  BigIntegerStr		d;
+
+			FEEECDSASignature();
+			FEEECDSASignature (const FEEECDSASignature &);
+  virtual		~FEEECDSASignature();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  FEEECDSASignature		&operator = (const FEEECDSASignature &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class FEEPublicKey: public AsnType
+{
+public:
+  AsnInt		version;
+  FEECurveParameters		*curveParams;
+  BigIntegerStr		plusX;
+  BigIntegerStr		minusX;
+  BigIntegerStr		*plusY;
+
+			FEEPublicKey();
+			FEEPublicKey (const FEEPublicKey &);
+  virtual		~FEEPublicKey();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  FEEPublicKey		&operator = (const FEEPublicKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class FEEPrivateKey: public AsnType
+{
+public:
+  AsnInt		version;
+  FEECurveParameters		*curveParams;
+  BigIntegerStr		privData;
+
+			FEEPrivateKey();
+			FEEPrivateKey (const FEEPrivateKey &);
+  virtual		~FEEPrivateKey();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  FEEPrivateKey		&operator = (const FEEPrivateKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DSAPrivateKey: public AsnType
+{
+public:
+  AsnInt		version;
+  DSAAlgorithmId		*dsaAlg;
+  AsnOcts		privateKey;
+
+			DSAPrivateKey();
+			DSAPrivateKey (const DSAPrivateKey &);
+  virtual		~DSAPrivateKey();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DSAPrivateKey		&operator = (const DSAPrivateKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DSAPublicKey: public AsnType
+{
+public:
+  DSAAlgorithmId		*dsaAlg;
+  AsnBits		publicKey;
+
+			DSAPublicKey();
+			DSAPublicKey (const DSAPublicKey &);
+  virtual		~DSAPublicKey();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DSAPublicKey		&operator = (const DSAPublicKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DSAPrivateKeyOcts: public AsnType
+{
+public:
+  BigIntegerStr		privateKey;
+
+			DSAPrivateKeyOcts();
+			DSAPrivateKeyOcts (const DSAPrivateKeyOcts &);
+  virtual		~DSAPrivateKeyOcts();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DSAPrivateKeyOcts		&operator = (const DSAPrivateKeyOcts &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DSASignature: public AsnType
+{
+public:
+  BigIntegerStr		r;
+  BigIntegerStr		s;
+
+			DSASignature();
+			DSASignature (const DSASignature &);
+  virtual		~DSASignature();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DSASignature		&operator = (const DSASignature &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DSAAlgParams: public AsnType
+{
+public:
+  BigIntegerStr		p;
+  BigIntegerStr		q;
+  BigIntegerStr		g;
+
+			DSAAlgParams();
+			DSAAlgParams (const DSAAlgParams &);
+  virtual		~DSAAlgParams();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DSAAlgParams		&operator = (const DSAAlgParams &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define appleBaseOid_arc 1, 2, 840, 113635
+#define appleBaseOid     AsnOid(appleBaseOid_arc)
+#define appleDataSecurity_arc 1, 2, 840, 113635, 100
+#define appleDataSecurity     AsnOid(appleDataSecurity_arc)
+#define appleTrustPolicy_arc 1, 2, 840, 113635, 100, 1
+#define appleTrustPolicy     AsnOid(appleTrustPolicy_arc)
+#define appleSecurityAlgorithm_arc 1, 2, 840, 113635, 100, 2
+#define appleSecurityAlgorithm     AsnOid(appleSecurityAlgorithm_arc)
+#define appleISignTP_arc 1, 2, 840, 113635, 100, 1, 1
+#define appleISignTP     AsnOid(appleISignTP_arc)
+#define appleX509Basic_arc 1, 2, 840, 113635, 100, 1, 2
+#define appleX509Basic     AsnOid(appleX509Basic_arc)
+#define appleSSLPolicy_arc 1, 2, 840, 113635, 100, 1, 3
+#define appleSSLPolicy     AsnOid(appleSSLPolicy_arc)
+#define appleFee_arc 1, 2, 840, 113635, 100, 2, 1
+#define appleFee     AsnOid(appleFee_arc)
+#define appleAsc_arc 1, 2, 840, 113635, 100, 2, 2
+#define appleAsc     AsnOid(appleAsc_arc)
+#define appleFeeMD5_arc 1, 2, 840, 113635, 100, 2, 3
+#define appleFeeMD5     AsnOid(appleFeeMD5_arc)
+#define appleFeeSHA1_arc 1, 2, 840, 113635, 100, 2, 4
+#define appleFeeSHA1     AsnOid(appleFeeSHA1_arc)
+#define appleFeed_arc 1, 2, 840, 113635, 100, 2, 5
+#define appleFeed     AsnOid(appleFeed_arc)
+#define appleFeedExp_arc 1, 2, 840, 113635, 100, 2, 6
+#define appleFeedExp     AsnOid(appleFeedExp_arc)
+#define appleECDSA_arc 1, 2, 840, 113635, 100, 2, 7
+#define appleECDSA     AsnOid(appleECDSA_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of appleoids.h */
diff --git a/SecurityASN1/inc/pkcs1oids.h b/SecurityASN1/inc/pkcs1oids.h
new file mode 100644
index 00000000..7fc99ef3
--- /dev/null
+++ b/SecurityASN1/inc/pkcs1oids.h
@@ -0,0 +1,110 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// pkcs1oids.h - class definitions for ASN.1 module PKCS1-OIDS
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _pkcs1oids_h_
+#define _pkcs1oids_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class RSAPublicKey;
+class RSAPrivateKey;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+class RSAPublicKey: public AsnType
+{
+public:
+  BigIntegerStr		modulus;
+  BigIntegerStr		publicExponent;
+
+			RSAPublicKey();
+			RSAPublicKey (const RSAPublicKey &);
+  virtual		~RSAPublicKey();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RSAPublicKey		&operator = (const RSAPublicKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class RSAPrivateKey: public AsnType
+{
+public:
+  AsnInt		version;
+  BigIntegerStr		modulus;
+  BigIntegerStr		publicExponent;
+  BigIntegerStr		privateExponent;
+  BigIntegerStr		prime1;
+  BigIntegerStr		prime2;
+  BigIntegerStr		exponent1;
+  BigIntegerStr		exponent2;
+  BigIntegerStr		coefficient;
+
+			RSAPrivateKey();
+			RSAPrivateKey (const RSAPrivateKey &);
+  virtual		~RSAPrivateKey();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RSAPrivateKey		&operator = (const RSAPrivateKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define rsadsi_arc 1, 2, 840, 113549
+#define rsadsi     AsnOid(rsadsi_arc)
+#define pkcs_arc 1, 2, 840, 113549, 1
+#define pkcs     AsnOid(pkcs_arc)
+#define pkcs_1_arc 1, 2, 840, 113549, 1, 1
+#define pkcs_1     AsnOid(pkcs_1_arc)
+#define rsaEncryption_arc 1, 2, 840, 113549, 1, 1, 1
+#define rsaEncryption     AsnOid(rsaEncryption_arc)
+#define md2WithRSAEncryption_arc 1, 2, 840, 113549, 1, 1, 2
+#define md2WithRSAEncryption     AsnOid(md2WithRSAEncryption_arc)
+#define md4WithRSAEncryption_arc 1, 2, 840, 113549, 1, 1, 3
+#define md4WithRSAEncryption     AsnOid(md4WithRSAEncryption_arc)
+#define md5WithRSAEncryption_arc 1, 2, 840, 113549, 1, 1, 4
+#define md5WithRSAEncryption     AsnOid(md5WithRSAEncryption_arc)
+#define sha1withRSAEncryption_arc 1, 2, 840, 113549, 1, 1, 5
+#define sha1withRSAEncryption     AsnOid(sha1withRSAEncryption_arc)
+#define rsaDigestAlgorithm_arc 1, 2, 840, 113549, 2
+#define rsaDigestAlgorithm     AsnOid(rsaDigestAlgorithm_arc)
+#define md2_arc 1, 2, 840, 113549, 2, 2
+#define md2     AsnOid(md2_arc)
+#define md4_arc 1, 2, 840, 113549, 2, 4
+#define md4     AsnOid(md4_arc)
+#define md5_arc 1, 2, 840, 113549, 2, 5
+#define md5     AsnOid(md5_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of pkcs1oids.h */
diff --git a/SecurityASN1/inc/pkcs7.h b/SecurityASN1/inc/pkcs7.h
new file mode 100644
index 00000000..25895ea6
--- /dev/null
+++ b/SecurityASN1/inc/pkcs7.h
@@ -0,0 +1,117 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// pkcs7.h - class definitions for ASN.1 module PKCS7
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _pkcs7_h_
+#define _pkcs7_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class EncryptedDataInt;
+class EncryptedContentInfo1;
+class EncryptedData1;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+/* INTEGER { edVer0 (0) }  */
+class EncryptedDataInt: public AsnInt
+{
+public:
+			EncryptedDataInt(): AsnInt() {}
+			EncryptedDataInt (int i): AsnInt (i) {}
+  enum
+  {
+    edVer0 = 0
+  };
+};
+
+
+/* OBJECT IDENTIFIER */
+typedef AsnOid ContentType1;
+
+/* OCTET STRING */
+typedef AsnOcts EncryptedContent1;
+
+/* AlgorithmIdentifier */
+typedef AlgorithmIdentifier ContentEncryptionAlgorithmIdentifier1;
+
+class EncryptedContentInfo1: public AsnType
+{
+public:
+  ContentType1		contentType;
+  ContentEncryptionAlgorithmIdentifier1		*contentEncryptionAlgorithm;
+  EncryptedContent1		*encryptedContent;
+
+			EncryptedContentInfo1();
+			EncryptedContentInfo1 (const EncryptedContentInfo1 &);
+  virtual		~EncryptedContentInfo1();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EncryptedContentInfo1		&operator = (const EncryptedContentInfo1 &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class EncryptedData1: public AsnType
+{
+public:
+  EncryptedDataInt		version;
+  EncryptedContentInfo1		*encryptedContentInfo;
+
+			EncryptedData1();
+			EncryptedData1 (const EncryptedData1 &);
+  virtual		~EncryptedData1();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EncryptedData1		&operator = (const EncryptedData1 &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define pkcs_7_arc 1, 2, 840, 113549, 1, 7
+#define pkcs_7     AsnOid(pkcs_7_arc)
+#define dataPkcs7_arc 1, 2, 840, 113549, 1, 7, 1
+#define dataPkcs7     AsnOid(dataPkcs7_arc)
+#define signedData_arc 1, 2, 840, 113549, 1, 7, 2
+#define signedData     AsnOid(signedData_arc)
+#define envelopedData_arc 1, 2, 840, 113549, 1, 7, 3
+#define envelopedData     AsnOid(envelopedData_arc)
+#define signedAndEnvelopedData_arc 1, 2, 840, 113549, 1, 7, 4
+#define signedAndEnvelopedData     AsnOid(signedAndEnvelopedData_arc)
+#define digestedData_arc 1, 2, 840, 113549, 1, 7, 5
+#define digestedData     AsnOid(digestedData_arc)
+#define encryptedData_arc 1, 2, 840, 113549, 1, 7, 6
+#define encryptedData     AsnOid(encryptedData_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of pkcs7.h */
diff --git a/SecurityASN1/inc/pkcs8.h b/SecurityASN1/inc/pkcs8.h
new file mode 100644
index 00000000..8f5ef9cf
--- /dev/null
+++ b/SecurityASN1/inc/pkcs8.h
@@ -0,0 +1,84 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// pkcs8.h - class definitions for ASN.1 module PrivateKeyInformationSyntax
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _pkcs8_h_
+#define _pkcs8_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class PrivateKeyInfo;
+class EncryptedPrivateKeyInfo;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+/* OCTET STRING */
+typedef AsnOcts PrivateKey;
+
+class PrivateKeyInfo: public AsnType
+{
+public:
+  AsnInt		version;
+  AlgorithmIdentifier		*privateKeyAlgorithm;
+  PrivateKey		privateKey;
+  Attributes		*attributes;
+
+			PrivateKeyInfo();
+			PrivateKeyInfo (const PrivateKeyInfo &);
+  virtual		~PrivateKeyInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PrivateKeyInfo		&operator = (const PrivateKeyInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class EncryptedPrivateKeyInfo: public AsnType
+{
+public:
+  AlgorithmIdentifier		*encryptionAlgorithm;
+  EncryptedKey		encryptedKey;
+
+			EncryptedPrivateKeyInfo();
+			EncryptedPrivateKeyInfo (const EncryptedPrivateKeyInfo &);
+  virtual		~EncryptedPrivateKeyInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EncryptedPrivateKeyInfo		&operator = (const EncryptedPrivateKeyInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of pkcs8.h */
diff --git a/SecurityASN1/inc/pkcs9oids.h b/SecurityASN1/inc/pkcs9oids.h
new file mode 100644
index 00000000..45d641bd
--- /dev/null
+++ b/SecurityASN1/inc/pkcs9oids.h
@@ -0,0 +1,45 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// pkcs9oids.h - class definitions for ASN.1 module PKCS9-OIDS
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _pkcs9oids_h_
+#define _pkcs9oids_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define pkcs_9_arc 1, 2, 840, 113549, 1, 9
+#define pkcs_9     AsnOid(pkcs_9_arc)
+#define emailAddress_arc 1, 2, 840, 113549, 1, 9, 1
+#define emailAddress     AsnOid(emailAddress_arc)
+#define unstructuredName_arc 1, 2, 840, 113549, 1, 9, 2
+#define unstructuredName     AsnOid(unstructuredName_arc)
+#define contentTypePkcs9_arc 1, 2, 840, 113549, 1, 9, 3
+#define contentTypePkcs9     AsnOid(contentTypePkcs9_arc)
+#define messageDigest_arc 1, 2, 840, 113549, 1, 9, 4
+#define messageDigest     AsnOid(messageDigest_arc)
+#define signingTime_arc 1, 2, 840, 113549, 1, 9, 5
+#define signingTime     AsnOid(signingTime_arc)
+#define countersignature_arc 1, 2, 840, 113549, 1, 9, 6
+#define countersignature     AsnOid(countersignature_arc)
+#define challengePassword_arc 1, 2, 840, 113549, 1, 9, 7
+#define challengePassword     AsnOid(challengePassword_arc)
+#define unstructuredAddress_arc 1, 2, 840, 113549, 1, 9, 8
+#define unstructuredAddress     AsnOid(unstructuredAddress_arc)
+#define extendedCertificateAttributes_arc 1, 2, 840, 113549, 1, 9, 9
+#define extendedCertificateAttributes     AsnOid(extendedCertificateAttributes_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of pkcs9oids.h */
diff --git a/SecurityASN1/inc/sm_cms.h b/SecurityASN1/inc/sm_cms.h
new file mode 100644
index 00000000..162c5d4e
--- /dev/null
+++ b/SecurityASN1/inc/sm_cms.h
@@ -0,0 +1,1544 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_cms.h - class definitions for ASN.1 module CryptographicMessageSyntax
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_cms_h_
+#define _sm_cms_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class CMSVersion;
+class OriginatorPublicKey;
+class CertificateRevocationLists;
+class IssuerAndSerialNumber;
+class OtherKeyAttribute;
+class DigestAlgorithmIdentifiers;
+class EncapsulatedContentInfo;
+class SignerIdentifier;
+class EncryptedContentInfo;
+class RecipientIdentifier;
+class OriginatorIdentifierOrKey;
+class RecipientKeyIdentifier;
+class KEKIdentifier;
+class ExtendedCertificateInfo;
+class SignerInfo;
+class KeyTransRecipientInfo;
+class KeyAgreeRecipientIdentifier;
+class KEKRecipientInfo;
+class ExtendedCertificate;
+class SignerInfos;
+class RecipientEncryptedKey;
+class CertificateChoices;
+class CertificateSet;
+class OriginatorInfo;
+class RecipientEncryptedKeys;
+class KeyAgreeRecipientInfo;
+class RecipientInfo;
+class RecipientInfos;
+class ContentInfo;
+class SignedData;
+class EnvelopedData;
+class DigestedData;
+class EncryptedData;
+class AuthenticatedData;
+class UserKeyingMaterials;
+class RC2CBCParameter;
+class ExtendedCertificateOrCertificate;
+class DigestInfo;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+typedef enum CryptographicMessageSyntaxAnyId
+{
+
+} CryptographicMessageSyntaxAnyId;
+
+
+/* OBJECT IDENTIFIER */
+typedef AsnOid ContentType;
+
+/* OCTET STRING */
+typedef AsnOcts SignatureValue;
+
+/* OCTET STRING */
+typedef AsnOcts EncryptedContent;
+
+/* OCTET STRING */
+typedef AsnOcts EncryptedKey;
+
+/* OCTET STRING */
+typedef AsnOcts Digest;
+
+/* OCTET STRING */
+typedef AsnOcts MessageAuthenticationCode;
+
+/* INTEGER { v0 (0), v1 (1), v2 (2), v3 (3), v4 (4) }  */
+class CMSVersion: public AsnInt
+{
+public:
+			CMSVersion(): AsnInt() {}
+			CMSVersion (int i): AsnInt (i) {}
+  enum
+  {
+    v0 = 0,
+    v1 = 1,
+    v2 = 2,
+    v3 = 3,
+    v4 = 4
+  };
+};
+
+
+/* OCTET STRING */
+typedef AsnOcts UserKeyingMaterial;
+
+/* OCTET STRING */
+typedef AsnOcts MessageDigest;
+
+/* INTEGER */
+typedef AsnInt RC2ParameterVersion;
+
+/* OCTET STRING */
+typedef AsnOcts IV;
+
+/* BIT STRING */
+typedef AsnBits Signature;
+
+class OriginatorPublicKey: public AsnType
+{
+public:
+  AlgorithmIdentifier		*algorithm;
+  AsnBits		publicKey;
+
+			OriginatorPublicKey();
+			OriginatorPublicKey (const OriginatorPublicKey &);
+  virtual		~OriginatorPublicKey();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  OriginatorPublicKey		&operator = (const OriginatorPublicKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+/* AlgorithmIdentifier */
+typedef AlgorithmIdentifier DigestAlgorithmIdentifier;
+
+/* AlgorithmIdentifier */
+typedef AlgorithmIdentifier SignatureAlgorithmIdentifier;
+
+/* AlgorithmIdentifier */
+typedef AlgorithmIdentifier KeyEncryptionAlgorithmIdentifier;
+
+/* AlgorithmIdentifier */
+typedef AlgorithmIdentifier ContentEncryptionAlgorithmIdentifier;
+
+/* AlgorithmIdentifier */
+typedef AlgorithmIdentifier MessageAuthenticationCodeAlgorithm;
+
+class CertificateRevocationLists: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    CertificateList	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			CertificateRevocationLists() { count = 0; first = curr = last = NULL; }
+			CertificateRevocationLists (const CertificateRevocationLists &);
+  virtual		~CertificateRevocationLists();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificateRevocationLists		&operator = (const CertificateRevocationLists &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  CertificateList	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  CertificateList	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  CertificateList	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  CertificateList	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  CertificateList	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  CertificateList	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  CertificateList	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  CertificateList	*Append();  // add elmt to end of list
+  CertificateList	*Prepend(); // add elmt to beginning of list
+  CertificateList	*InsertBefore(); //insert elmt before current elmt
+  CertificateList	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  CertificateRevocationLists	&AppendCopy (CertificateList &elmt);  // add elmt to end of list
+  CertificateRevocationLists	&PrependCopy (CertificateList &elmt); // add elmt to beginning of list
+  CertificateRevocationLists	&InsertBeforeAndCopy (CertificateList &elmt); //insert elmt before current elmt
+  CertificateRevocationLists	&InsertAfterAndCopy (CertificateList &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class IssuerAndSerialNumber: public AsnType
+{
+public:
+  Name		*issuer;
+  CertificateSerialNumber		serialNumber;
+
+			IssuerAndSerialNumber();
+			IssuerAndSerialNumber (const IssuerAndSerialNumber &);
+  virtual		~IssuerAndSerialNumber();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  IssuerAndSerialNumber		&operator = (const IssuerAndSerialNumber &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class OtherKeyAttribute: public AsnType
+{
+public:
+  AsnOid		keyAttrId;
+  AsnAny		*keyAttr;
+
+			OtherKeyAttribute();
+			OtherKeyAttribute (const OtherKeyAttribute &);
+  virtual		~OtherKeyAttribute();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  OtherKeyAttribute		&operator = (const OtherKeyAttribute &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DigestAlgorithmIdentifiers: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    DigestAlgorithmIdentifier	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			DigestAlgorithmIdentifiers() { count = 0; first = curr = last = NULL; }
+			DigestAlgorithmIdentifiers (const DigestAlgorithmIdentifiers &);
+  virtual		~DigestAlgorithmIdentifiers();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DigestAlgorithmIdentifiers		&operator = (const DigestAlgorithmIdentifiers &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  DigestAlgorithmIdentifier	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  DigestAlgorithmIdentifier	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  DigestAlgorithmIdentifier	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  DigestAlgorithmIdentifier	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  DigestAlgorithmIdentifier	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  DigestAlgorithmIdentifier	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  DigestAlgorithmIdentifier	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  DigestAlgorithmIdentifier	*Append();  // add elmt to end of list
+  DigestAlgorithmIdentifier	*Prepend(); // add elmt to beginning of list
+  DigestAlgorithmIdentifier	*InsertBefore(); //insert elmt before current elmt
+  DigestAlgorithmIdentifier	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  DigestAlgorithmIdentifiers	&AppendCopy (DigestAlgorithmIdentifier &elmt);  // add elmt to end of list
+  DigestAlgorithmIdentifiers	&PrependCopy (DigestAlgorithmIdentifier &elmt); // add elmt to beginning of list
+  DigestAlgorithmIdentifiers	&InsertBeforeAndCopy (DigestAlgorithmIdentifier &elmt); //insert elmt before current elmt
+  DigestAlgorithmIdentifiers	&InsertAfterAndCopy (DigestAlgorithmIdentifier &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class EncapsulatedContentInfo: public AsnType
+{
+public:
+  ContentType		eContentType;
+  AsnOcts		*eContent;
+
+			EncapsulatedContentInfo();
+			EncapsulatedContentInfo (const EncapsulatedContentInfo &);
+  virtual		~EncapsulatedContentInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EncapsulatedContentInfo		&operator = (const EncapsulatedContentInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class SignerIdentifier: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     issuerAndSerialNumberCid = 0,
+     subjectKeyIdentifierCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     IssuerAndSerialNumber		*issuerAndSerialNumber;
+     KeyIdentifier		*subjectKeyIdentifier;
+  };
+
+
+			SignerIdentifier();
+			SignerIdentifier (const SignerIdentifier &);
+  virtual		~SignerIdentifier();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SignerIdentifier		&operator = (const SignerIdentifier &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class EncryptedContentInfo: public AsnType
+{
+public:
+  ContentType		contentType;
+  ContentEncryptionAlgorithmIdentifier		*contentEncryptionAlgorithm;
+  EncryptedContent		*encryptedContent;
+
+			EncryptedContentInfo();
+			EncryptedContentInfo (const EncryptedContentInfo &);
+  virtual		~EncryptedContentInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EncryptedContentInfo		&operator = (const EncryptedContentInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class RecipientIdentifier: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     issuerAndSerialNumberCid = 0,
+     subjectKeyIdentifierCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     IssuerAndSerialNumber		*issuerAndSerialNumber;
+     KeyIdentifier		*subjectKeyIdentifier;
+  };
+
+
+			RecipientIdentifier();
+			RecipientIdentifier (const RecipientIdentifier &);
+  virtual		~RecipientIdentifier();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RecipientIdentifier		&operator = (const RecipientIdentifier &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class OriginatorIdentifierOrKey: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     issuerAndSerialNumberCid = 0,
+     subjectKeyIdentifierCid = 1,
+     originatorKeyCid = 2
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     IssuerAndSerialNumber		*issuerAndSerialNumber;
+     KeyIdentifier		*subjectKeyIdentifier;
+     OriginatorPublicKey		*originatorKey;
+  };
+
+
+			OriginatorIdentifierOrKey();
+			OriginatorIdentifierOrKey (const OriginatorIdentifierOrKey &);
+  virtual		~OriginatorIdentifierOrKey();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  OriginatorIdentifierOrKey		&operator = (const OriginatorIdentifierOrKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class RecipientKeyIdentifier: public AsnType
+{
+public:
+  KeyIdentifier		subjectKeyIdentifier;
+  GeneralizedTime		*date;
+  OtherKeyAttribute		*other;
+
+			RecipientKeyIdentifier();
+			RecipientKeyIdentifier (const RecipientKeyIdentifier &);
+  virtual		~RecipientKeyIdentifier();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RecipientKeyIdentifier		&operator = (const RecipientKeyIdentifier &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class KEKIdentifier: public AsnType
+{
+public:
+  AsnOcts		keyIdentifier;
+  GeneralizedTime		*date;
+  OtherKeyAttribute		*other;
+
+			KEKIdentifier();
+			KEKIdentifier (const KEKIdentifier &);
+  virtual		~KEKIdentifier();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  KEKIdentifier		&operator = (const KEKIdentifier &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class ExtendedCertificateInfo: public AsnType
+{
+public:
+  CMSVersion		version;
+  Certificate		*certificate;
+  Attributes		attributes;
+
+			ExtendedCertificateInfo();
+			ExtendedCertificateInfo (const ExtendedCertificateInfo &);
+  virtual		~ExtendedCertificateInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ExtendedCertificateInfo		&operator = (const ExtendedCertificateInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class SignerInfo: public AsnType
+{
+public:
+  CMSVersion		version;
+  SignerIdentifier		*sid;
+  DigestAlgorithmIdentifier		*digestAlgorithm;
+  Attributes		*signedAttrs;
+  SignatureAlgorithmIdentifier		*signatureAlgorithm;
+  SignatureValue		signature;
+  Attributes		*unsignedAttrs;
+
+			SignerInfo();
+			SignerInfo (const SignerInfo &);
+  virtual		~SignerInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SignerInfo		&operator = (const SignerInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class KeyTransRecipientInfo: public AsnType
+{
+public:
+  CMSVersion		version;
+  RecipientIdentifier		*rid;
+  KeyEncryptionAlgorithmIdentifier		*keyEncryptionAlgorithm;
+  EncryptedKey		encryptedKey;
+
+			KeyTransRecipientInfo();
+			KeyTransRecipientInfo (const KeyTransRecipientInfo &);
+  virtual		~KeyTransRecipientInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  KeyTransRecipientInfo		&operator = (const KeyTransRecipientInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class KeyAgreeRecipientIdentifier: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     issuerAndSerialNumberCid = 0,
+     rKeyIdCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     IssuerAndSerialNumber		*issuerAndSerialNumber;
+     RecipientKeyIdentifier		*rKeyId;
+  };
+
+
+			KeyAgreeRecipientIdentifier();
+			KeyAgreeRecipientIdentifier (const KeyAgreeRecipientIdentifier &);
+  virtual		~KeyAgreeRecipientIdentifier();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  KeyAgreeRecipientIdentifier		&operator = (const KeyAgreeRecipientIdentifier &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class KEKRecipientInfo: public AsnType
+{
+public:
+  CMSVersion		version;
+  KEKIdentifier		*kekid;
+  KeyEncryptionAlgorithmIdentifier		*keyEncryptionAlgorithm;
+  EncryptedKey		encryptedKey;
+
+			KEKRecipientInfo();
+			KEKRecipientInfo (const KEKRecipientInfo &);
+  virtual		~KEKRecipientInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  KEKRecipientInfo		&operator = (const KEKRecipientInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class ExtendedCertificate: public AsnType
+{
+public:
+  ExtendedCertificateInfo		*extendedCertificateInfo;
+  SignatureAlgorithmIdentifier		*signatureAlgorithm;
+  Signature		signature;
+
+			ExtendedCertificate();
+			ExtendedCertificate (const ExtendedCertificate &);
+  virtual		~ExtendedCertificate();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ExtendedCertificate		&operator = (const ExtendedCertificate &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class SignerInfos: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    SignerInfo	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			SignerInfos() { count = 0; first = curr = last = NULL; }
+			SignerInfos (const SignerInfos &);
+  virtual		~SignerInfos();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SignerInfos		&operator = (const SignerInfos &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  SignerInfo	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  SignerInfo	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  SignerInfo	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  SignerInfo	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  SignerInfo	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  SignerInfo	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  SignerInfo	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  SignerInfo	*Append();  // add elmt to end of list
+  SignerInfo	*Prepend(); // add elmt to beginning of list
+  SignerInfo	*InsertBefore(); //insert elmt before current elmt
+  SignerInfo	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  SignerInfos	&AppendCopy (SignerInfo &elmt);  // add elmt to end of list
+  SignerInfos	&PrependCopy (SignerInfo &elmt); // add elmt to beginning of list
+  SignerInfos	&InsertBeforeAndCopy (SignerInfo &elmt); //insert elmt before current elmt
+  SignerInfos	&InsertAfterAndCopy (SignerInfo &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class RecipientEncryptedKey: public AsnType
+{
+public:
+  KeyAgreeRecipientIdentifier		*rid;
+  EncryptedKey		encryptedKey;
+
+			RecipientEncryptedKey();
+			RecipientEncryptedKey (const RecipientEncryptedKey &);
+  virtual		~RecipientEncryptedKey();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RecipientEncryptedKey		&operator = (const RecipientEncryptedKey &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CertificateChoices: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     certificateCid = 0,
+     extendedCertificateCid = 1,
+     attrCertCid = 2
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     Certificate		*certificate;
+     ExtendedCertificate		*extendedCertificate;
+     AttributeCertificate		*attrCert;
+  };
+
+
+			CertificateChoices();
+			CertificateChoices (const CertificateChoices &);
+  virtual		~CertificateChoices();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificateChoices		&operator = (const CertificateChoices &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class CertificateSet: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    CertificateChoices	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			CertificateSet() { count = 0; first = curr = last = NULL; }
+			CertificateSet (const CertificateSet &);
+  virtual		~CertificateSet();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificateSet		&operator = (const CertificateSet &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  CertificateChoices	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  CertificateChoices	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  CertificateChoices	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  CertificateChoices	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  CertificateChoices	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  CertificateChoices	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  CertificateChoices	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  CertificateChoices	*Append();  // add elmt to end of list
+  CertificateChoices	*Prepend(); // add elmt to beginning of list
+  CertificateChoices	*InsertBefore(); //insert elmt before current elmt
+  CertificateChoices	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  CertificateSet	&AppendCopy (CertificateChoices &elmt);  // add elmt to end of list
+  CertificateSet	&PrependCopy (CertificateChoices &elmt); // add elmt to beginning of list
+  CertificateSet	&InsertBeforeAndCopy (CertificateChoices &elmt); //insert elmt before current elmt
+  CertificateSet	&InsertAfterAndCopy (CertificateChoices &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class OriginatorInfo: public AsnType
+{
+public:
+  CertificateSet		*certs;
+  CertificateRevocationLists		*crls;
+
+			OriginatorInfo();
+			OriginatorInfo (const OriginatorInfo &);
+  virtual		~OriginatorInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  OriginatorInfo		&operator = (const OriginatorInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class RecipientEncryptedKeys: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    RecipientEncryptedKey	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			RecipientEncryptedKeys() { count = 0; first = curr = last = NULL; }
+			RecipientEncryptedKeys (const RecipientEncryptedKeys &);
+  virtual		~RecipientEncryptedKeys();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RecipientEncryptedKeys		&operator = (const RecipientEncryptedKeys &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  RecipientEncryptedKey	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  RecipientEncryptedKey	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  RecipientEncryptedKey	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  RecipientEncryptedKey	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  RecipientEncryptedKey	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  RecipientEncryptedKey	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  RecipientEncryptedKey	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  RecipientEncryptedKey	*Append();  // add elmt to end of list
+  RecipientEncryptedKey	*Prepend(); // add elmt to beginning of list
+  RecipientEncryptedKey	*InsertBefore(); //insert elmt before current elmt
+  RecipientEncryptedKey	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  RecipientEncryptedKeys	&AppendCopy (RecipientEncryptedKey &elmt);  // add elmt to end of list
+  RecipientEncryptedKeys	&PrependCopy (RecipientEncryptedKey &elmt); // add elmt to beginning of list
+  RecipientEncryptedKeys	&InsertBeforeAndCopy (RecipientEncryptedKey &elmt); //insert elmt before current elmt
+  RecipientEncryptedKeys	&InsertAfterAndCopy (RecipientEncryptedKey &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class KeyAgreeRecipientInfo: public AsnType
+{
+public:
+  CMSVersion		version;
+  OriginatorIdentifierOrKey		*originator;
+  UserKeyingMaterial		*ukm;
+  KeyEncryptionAlgorithmIdentifier		*keyEncryptionAlgorithm;
+  RecipientEncryptedKeys		recipientEncryptedKeys;
+
+			KeyAgreeRecipientInfo();
+			KeyAgreeRecipientInfo (const KeyAgreeRecipientInfo &);
+  virtual		~KeyAgreeRecipientInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  KeyAgreeRecipientInfo		&operator = (const KeyAgreeRecipientInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class RecipientInfo: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     ktriCid = 0,
+     kariCid = 1,
+     kekriCid = 2
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     KeyTransRecipientInfo		*ktri;
+     KeyAgreeRecipientInfo		*kari;
+     KEKRecipientInfo		*kekri;
+  };
+
+
+			RecipientInfo();
+			RecipientInfo (const RecipientInfo &);
+  virtual		~RecipientInfo();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RecipientInfo		&operator = (const RecipientInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class RecipientInfos: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    RecipientInfo	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			RecipientInfos() { count = 0; first = curr = last = NULL; }
+			RecipientInfos (const RecipientInfos &);
+  virtual		~RecipientInfos();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RecipientInfos		&operator = (const RecipientInfos &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  RecipientInfo	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  RecipientInfo	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  RecipientInfo	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  RecipientInfo	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  RecipientInfo	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  RecipientInfo	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  RecipientInfo	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  RecipientInfo	*Append();  // add elmt to end of list
+  RecipientInfo	*Prepend(); // add elmt to beginning of list
+  RecipientInfo	*InsertBefore(); //insert elmt before current elmt
+  RecipientInfo	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  RecipientInfos	&AppendCopy (RecipientInfo &elmt);  // add elmt to end of list
+  RecipientInfos	&PrependCopy (RecipientInfo &elmt); // add elmt to beginning of list
+  RecipientInfos	&InsertBeforeAndCopy (RecipientInfo &elmt); //insert elmt before current elmt
+  RecipientInfos	&InsertAfterAndCopy (RecipientInfo &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class ContentInfo: public AsnType
+{
+public:
+  ContentType		contentType;
+  AsnAny		content;
+
+			ContentInfo();
+			ContentInfo (const ContentInfo &);
+  virtual		~ContentInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ContentInfo		&operator = (const ContentInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class SignedData: public AsnType
+{
+public:
+  CMSVersion		version;
+  DigestAlgorithmIdentifiers		digestAlgorithms;
+  EncapsulatedContentInfo		*encapContentInfo;
+  CertificateSet		*certificates;
+  CertificateRevocationLists		*crls;
+  SignerInfos		signerInfos;
+
+			SignedData();
+			SignedData (const SignedData &);
+  virtual		~SignedData();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SignedData		&operator = (const SignedData &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class EnvelopedData: public AsnType
+{
+public:
+  CMSVersion		version;
+  OriginatorInfo		*originatorInfo;
+  RecipientInfos		recipientInfos;
+  EncryptedContentInfo		*encryptedContentInfo;
+  Attributes		*unprotectedAttrs;
+
+			EnvelopedData();
+			EnvelopedData (const EnvelopedData &);
+  virtual		~EnvelopedData();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EnvelopedData		&operator = (const EnvelopedData &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DigestedData: public AsnType
+{
+public:
+  CMSVersion		version;
+  DigestAlgorithmIdentifier		*digestAlgorithm;
+  EncapsulatedContentInfo		*encapContentInfo;
+  Digest		digest;
+
+			DigestedData();
+			DigestedData (const DigestedData &);
+  virtual		~DigestedData();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DigestedData		&operator = (const DigestedData &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class EncryptedData: public AsnType
+{
+public:
+  CMSVersion		version;
+  EncryptedContentInfo		*encryptedContentInfo;
+
+			EncryptedData();
+			EncryptedData (const EncryptedData &);
+  virtual		~EncryptedData();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EncryptedData		&operator = (const EncryptedData &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AuthenticatedData: public AsnType
+{
+public:
+  CMSVersion		version;
+  OriginatorInfo		*originatorInfo;
+  RecipientInfos		recipientInfos;
+  MessageAuthenticationCodeAlgorithm		*macAlgorithm;
+  DigestAlgorithmIdentifier		*digestAlgorithm;
+  EncapsulatedContentInfo		*encapContentInfo;
+  Attributes		*authenctiatedAttributes;
+  MessageAuthenticationCode		mac;
+  Attributes		*unauthenticatedAttributes;
+
+			AuthenticatedData();
+			AuthenticatedData (const AuthenticatedData &);
+  virtual		~AuthenticatedData();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AuthenticatedData		&operator = (const AuthenticatedData &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class UserKeyingMaterials: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    UserKeyingMaterial	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			UserKeyingMaterials() { count = 0; first = curr = last = NULL; }
+			UserKeyingMaterials (const UserKeyingMaterials &);
+  virtual		~UserKeyingMaterials();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  UserKeyingMaterials		&operator = (const UserKeyingMaterials &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  UserKeyingMaterial	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  UserKeyingMaterial	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  UserKeyingMaterial	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  UserKeyingMaterial	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  UserKeyingMaterial	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  UserKeyingMaterial	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  UserKeyingMaterial	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  UserKeyingMaterial	*Append();  // add elmt to end of list
+  UserKeyingMaterial	*Prepend(); // add elmt to beginning of list
+  UserKeyingMaterial	*InsertBefore(); //insert elmt before current elmt
+  UserKeyingMaterial	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  UserKeyingMaterials	&AppendCopy (UserKeyingMaterial &elmt);  // add elmt to end of list
+  UserKeyingMaterials	&PrependCopy (UserKeyingMaterial &elmt); // add elmt to beginning of list
+  UserKeyingMaterials	&InsertBeforeAndCopy (UserKeyingMaterial &elmt); //insert elmt before current elmt
+  UserKeyingMaterials	&InsertAfterAndCopy (UserKeyingMaterial &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+/* Time */
+typedef Time SigningTime;
+
+/* SignerInfo */
+typedef SignerInfo Countersignature;
+
+/* AlgorithmIdentifier */
+typedef AlgorithmIdentifier KeyWrapAlgorithm;
+
+/* RC2ParameterVersion */
+typedef RC2ParameterVersion RC2wrapParameter;
+
+/* IV */
+typedef IV CBCParameter;
+
+class RC2CBCParameter: public AsnType
+{
+public:
+  AsnInt		rc2ParameterVersion;
+  AsnOcts		iv;
+
+			RC2CBCParameter();
+			RC2CBCParameter (const RC2CBCParameter &);
+  virtual		~RC2CBCParameter();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RC2CBCParameter		&operator = (const RC2CBCParameter &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class ExtendedCertificateOrCertificate: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     certificateCid = 0,
+     extendedCertificateCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     Certificate		*certificate;
+     ExtendedCertificate		*extendedCertificate;
+  };
+
+
+			ExtendedCertificateOrCertificate();
+			ExtendedCertificateOrCertificate (const ExtendedCertificateOrCertificate &);
+  virtual		~ExtendedCertificateOrCertificate();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ExtendedCertificateOrCertificate		&operator = (const ExtendedCertificateOrCertificate &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class DigestInfo: public AsnType
+{
+public:
+  DigestAlgorithmIdentifier		*digestAlgorithm;
+  Digest		digest;
+
+			DigestInfo();
+			DigestInfo (const DigestInfo &);
+  virtual		~DigestInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DigestInfo		&operator = (const DigestInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define sha_1_arc 1, 3, 14, 3, 2, 26
+#define sha_1     AsnOid(sha_1_arc)
+#define id_dsa_with_sha1_arc 1, 2, 840, 10040, 4, 3
+#define id_dsa_with_sha1     AsnOid(id_dsa_with_sha1_arc)
+#define dh_public_number_arc 1, 2, 840, 10046, 2, 1
+#define dh_public_number     AsnOid(dh_public_number_arc)
+#define id_alg_ESDH_arc 1, 2, 840, 113549, 1, 9, 16, 3, 5
+#define id_alg_ESDH     AsnOid(id_alg_ESDH_arc)
+#define id_alg_CMS3DESwrap_arc 1, 2, 840, 113549, 1, 9, 16, 3, 6
+#define id_alg_CMS3DESwrap     AsnOid(id_alg_CMS3DESwrap_arc)
+#define id_alg_CMSRC2wrap_arc 1, 2, 840, 113549, 1, 9, 16, 3, 7
+#define id_alg_CMSRC2wrap     AsnOid(id_alg_CMSRC2wrap_arc)
+#define des_ede3_cbc_arc 1, 2, 840, 113549, 3, 7
+#define des_ede3_cbc     AsnOid(des_ede3_cbc_arc)
+#define rc2_cbc_arc 1, 2, 840, 113549, 3, 2
+#define rc2_cbc     AsnOid(rc2_cbc_arc)
+#define hMAC_SHA1_arc 1, 3, 6, 1, 5, 5, 8, 1, 2
+#define hMAC_SHA1     AsnOid(hMAC_SHA1_arc)
+#define rc2_ecb_arc 1, 2, 840, 113549, 3, 3
+#define rc2_ecb     AsnOid(rc2_ecb_arc)
+#define rc4_arc 1, 2, 840, 113549, 3, 4
+#define rc4     AsnOid(rc4_arc)
+#define rc4WithMAC_arc 1, 2, 840, 113549, 3, 5
+#define rc4WithMAC     AsnOid(rc4WithMAC_arc)
+#define desx_CBC_arc 1, 2, 840, 113549, 3, 6
+#define desx_CBC     AsnOid(desx_CBC_arc)
+#define rc5CBC_arc 1, 2, 840, 113549, 3, 8
+#define rc5CBC     AsnOid(rc5CBC_arc)
+#define rc5_CBCPad_arc 1, 2, 840, 113549, 3, 9
+#define rc5_CBCPad     AsnOid(rc5_CBCPad_arc)
+#define desCDMF_arc 1, 2, 840, 113549, 3, 10
+#define desCDMF     AsnOid(desCDMF_arc)
+#define dsa_bsafe_arc 1, 3, 14, 3, 2, 12
+#define dsa_bsafe     AsnOid(dsa_bsafe_arc)
+#define id_data_arc 1, 2, 840, 113549, 1, 7, 1
+#define id_data     AsnOid(id_data_arc)
+#define id_signedData_arc 1, 2, 840, 113549, 1, 7, 2
+#define id_signedData     AsnOid(id_signedData_arc)
+#define id_envelopedData_arc 1, 2, 840, 113549, 1, 7, 3
+#define id_envelopedData     AsnOid(id_envelopedData_arc)
+#define id_digestedData_arc 1, 2, 840, 113549, 1, 7, 5
+#define id_digestedData     AsnOid(id_digestedData_arc)
+#define id_encryptedData_arc 1, 2, 840, 113549, 1, 7, 6
+#define id_encryptedData     AsnOid(id_encryptedData_arc)
+#define id_ct_authData_arc 1, 2, 840, 113549, 1, 9, 16, 1, 2
+#define id_ct_authData     AsnOid(id_ct_authData_arc)
+#define id_contentType_arc 1, 2, 840, 113549, 1, 9, 3
+#define id_contentType     AsnOid(id_contentType_arc)
+#define id_messageDigest_arc 1, 2, 840, 113549, 1, 9, 4
+#define id_messageDigest     AsnOid(id_messageDigest_arc)
+#define id_signingTime_arc 1, 2, 840, 113549, 1, 9, 5
+#define id_signingTime     AsnOid(id_signingTime_arc)
+#define id_countersignature_arc 1, 2, 840, 113549, 1, 9, 6
+#define id_countersignature     AsnOid(id_countersignature_arc)
+#define id_macValue_arc 1, 2, 840, 113549, 1, 9, 16, 2, 8
+#define id_macValue     AsnOid(id_macValue_arc)
+#define id_dsa_arc 1, 2, 840, 10040, 4, 1
+#define id_dsa     AsnOid(id_dsa_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_cms.h */
diff --git a/SecurityASN1/inc/sm_ess.h b/SecurityASN1/inc/sm_ess.h
new file mode 100644
index 00000000..7cc315ef
--- /dev/null
+++ b/SecurityASN1/inc/sm_ess.h
@@ -0,0 +1,1096 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_ess.h - class definitions for ASN.1 module ExtendedSecurityServices
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_ess_h_
+#define _sm_ess_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class AllOrFirstTier;
+class SecurityClassification;
+class SigningCertificateSeqOf1;
+class MLReceiptPolicySeqOf1;
+class MLReceiptPolicySeqOf;
+class ReceiptsFromSeqOf;
+class ReceiptRequestSeqOf;
+class ESSPrivacyMark;
+class SecurityCategory;
+class EntityIdentifier;
+class ReceiptsFrom;
+class SecurityCategories;
+class MLReceiptPolicy;
+class ESSCertID;
+class SigningCertificateSeqOf;
+class ESSSecurityLabel;
+class MLData;
+class ReceiptRequest;
+class Receipt;
+class ContentHints;
+class ContentReference;
+class EquivalentLabels;
+class MLExpansionHistory;
+class SigningCertificate;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+typedef enum ExtendedSecurityServicesAnyId
+{
+
+} ExtendedSecurityServicesAnyId;
+
+
+/* OCTET STRING */
+typedef AsnOcts ContentIdentifier;
+
+/* INTEGER { allReceipts (0), firstTierRecipients (1) }  */
+class AllOrFirstTier: public AsnInt
+{
+public:
+			AllOrFirstTier(): AsnInt() {}
+			AllOrFirstTier (int i): AsnInt (i) {}
+  enum
+  {
+    allReceipts = 0,
+    firstTierRecipients = 1
+  };
+};
+
+
+/* OCTET STRING */
+typedef AsnOcts MsgSigDigest;
+
+/* OBJECT IDENTIFIER */
+typedef AsnOid SecurityPolicyIdentifier;
+
+/* INTEGER { unmarked (0), unclassified (1), restricted (2), confidential (3), secret (4), top_secret (5) }  (0..ub-integer-options) */
+class SecurityClassification: public AsnInt
+{
+public:
+			SecurityClassification(): AsnInt() {}
+			SecurityClassification (int i): AsnInt (i) {}
+  enum
+  {
+    unmarked = 0,
+    unclassified = 1,
+    restricted = 2,
+    confidential = 3,
+    secret = 4,
+    top_secret = 5
+  };
+};
+
+
+/* OCTET STRING */
+typedef AsnOcts CertHash;
+
+/* OBJECT IDENTIFIER (id-qt-cps) | (id-qt-unotice) */
+typedef AsnOid PolicyQualifierId;
+
+class SigningCertificateSeqOf1: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    PolicyInformation	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			SigningCertificateSeqOf1() { count = 0; first = curr = last = NULL; }
+			SigningCertificateSeqOf1 (const SigningCertificateSeqOf1 &);
+  virtual		~SigningCertificateSeqOf1();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SigningCertificateSeqOf1		&operator = (const SigningCertificateSeqOf1 &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  PolicyInformation	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  PolicyInformation	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  PolicyInformation	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  PolicyInformation	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  PolicyInformation	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  PolicyInformation	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  PolicyInformation	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  PolicyInformation	*Append();  // add elmt to end of list
+  PolicyInformation	*Prepend(); // add elmt to beginning of list
+  PolicyInformation	*InsertBefore(); //insert elmt before current elmt
+  PolicyInformation	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  SigningCertificateSeqOf1	&AppendCopy (PolicyInformation &elmt);  // add elmt to end of list
+  SigningCertificateSeqOf1	&PrependCopy (PolicyInformation &elmt); // add elmt to beginning of list
+  SigningCertificateSeqOf1	&InsertBeforeAndCopy (PolicyInformation &elmt); //insert elmt before current elmt
+  SigningCertificateSeqOf1	&InsertAfterAndCopy (PolicyInformation &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class MLReceiptPolicySeqOf1: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    GeneralNames	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			MLReceiptPolicySeqOf1() { count = 0; first = curr = last = NULL; }
+			MLReceiptPolicySeqOf1 (const MLReceiptPolicySeqOf1 &);
+  virtual		~MLReceiptPolicySeqOf1();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  MLReceiptPolicySeqOf1		&operator = (const MLReceiptPolicySeqOf1 &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  GeneralNames	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  GeneralNames	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  GeneralNames	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  GeneralNames	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  GeneralNames	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  GeneralNames	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  GeneralNames	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  GeneralNames	*Append();  // add elmt to end of list
+  GeneralNames	*Prepend(); // add elmt to beginning of list
+  GeneralNames	*InsertBefore(); //insert elmt before current elmt
+  GeneralNames	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  MLReceiptPolicySeqOf1	&AppendCopy (GeneralNames &elmt);  // add elmt to end of list
+  MLReceiptPolicySeqOf1	&PrependCopy (GeneralNames &elmt); // add elmt to beginning of list
+  MLReceiptPolicySeqOf1	&InsertBeforeAndCopy (GeneralNames &elmt); //insert elmt before current elmt
+  MLReceiptPolicySeqOf1	&InsertAfterAndCopy (GeneralNames &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class MLReceiptPolicySeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    GeneralNames	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			MLReceiptPolicySeqOf() { count = 0; first = curr = last = NULL; }
+			MLReceiptPolicySeqOf (const MLReceiptPolicySeqOf &);
+  virtual		~MLReceiptPolicySeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  MLReceiptPolicySeqOf		&operator = (const MLReceiptPolicySeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  GeneralNames	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  GeneralNames	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  GeneralNames	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  GeneralNames	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  GeneralNames	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  GeneralNames	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  GeneralNames	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  GeneralNames	*Append();  // add elmt to end of list
+  GeneralNames	*Prepend(); // add elmt to beginning of list
+  GeneralNames	*InsertBefore(); //insert elmt before current elmt
+  GeneralNames	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  MLReceiptPolicySeqOf	&AppendCopy (GeneralNames &elmt);  // add elmt to end of list
+  MLReceiptPolicySeqOf	&PrependCopy (GeneralNames &elmt); // add elmt to beginning of list
+  MLReceiptPolicySeqOf	&InsertBeforeAndCopy (GeneralNames &elmt); //insert elmt before current elmt
+  MLReceiptPolicySeqOf	&InsertAfterAndCopy (GeneralNames &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class ReceiptsFromSeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    GeneralNames	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			ReceiptsFromSeqOf() { count = 0; first = curr = last = NULL; }
+			ReceiptsFromSeqOf (const ReceiptsFromSeqOf &);
+  virtual		~ReceiptsFromSeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ReceiptsFromSeqOf		&operator = (const ReceiptsFromSeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  GeneralNames	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  GeneralNames	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  GeneralNames	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  GeneralNames	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  GeneralNames	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  GeneralNames	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  GeneralNames	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  GeneralNames	*Append();  // add elmt to end of list
+  GeneralNames	*Prepend(); // add elmt to beginning of list
+  GeneralNames	*InsertBefore(); //insert elmt before current elmt
+  GeneralNames	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  ReceiptsFromSeqOf	&AppendCopy (GeneralNames &elmt);  // add elmt to end of list
+  ReceiptsFromSeqOf	&PrependCopy (GeneralNames &elmt); // add elmt to beginning of list
+  ReceiptsFromSeqOf	&InsertBeforeAndCopy (GeneralNames &elmt); //insert elmt before current elmt
+  ReceiptsFromSeqOf	&InsertAfterAndCopy (GeneralNames &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class ReceiptRequestSeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    GeneralNames	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			ReceiptRequestSeqOf() { count = 0; first = curr = last = NULL; }
+			ReceiptRequestSeqOf (const ReceiptRequestSeqOf &);
+  virtual		~ReceiptRequestSeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ReceiptRequestSeqOf		&operator = (const ReceiptRequestSeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  GeneralNames	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  GeneralNames	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  GeneralNames	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  GeneralNames	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  GeneralNames	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  GeneralNames	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  GeneralNames	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  GeneralNames	*Append();  // add elmt to end of list
+  GeneralNames	*Prepend(); // add elmt to beginning of list
+  GeneralNames	*InsertBefore(); //insert elmt before current elmt
+  GeneralNames	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  ReceiptRequestSeqOf	&AppendCopy (GeneralNames &elmt);  // add elmt to end of list
+  ReceiptRequestSeqOf	&PrependCopy (GeneralNames &elmt); // add elmt to beginning of list
+  ReceiptRequestSeqOf	&InsertBeforeAndCopy (GeneralNames &elmt); //insert elmt before current elmt
+  ReceiptRequestSeqOf	&InsertAfterAndCopy (GeneralNames &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class ESSPrivacyMark: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     pStringCid = 0,
+     utf8StringCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     PrintableString		*pString;
+     UTF8String		*utf8String;
+  };
+
+
+			ESSPrivacyMark();
+			ESSPrivacyMark (const ESSPrivacyMark &);
+  virtual		~ESSPrivacyMark();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ESSPrivacyMark		&operator = (const ESSPrivacyMark &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class SecurityCategory: public AsnType
+{
+public:
+  AsnOid		type;
+  AsnAny		value;
+
+			SecurityCategory();
+			SecurityCategory (const SecurityCategory &);
+  virtual		~SecurityCategory();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SecurityCategory		&operator = (const SecurityCategory &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class EntityIdentifier: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     issuerAndSerialNumberCid = 0,
+     subjectKeyIdentifierCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     IssuerAndSerialNumber		*issuerAndSerialNumber;
+     KeyIdentifier		*subjectKeyIdentifier;
+  };
+
+
+			EntityIdentifier();
+			EntityIdentifier (const EntityIdentifier &);
+  virtual		~EntityIdentifier();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EntityIdentifier		&operator = (const EntityIdentifier &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class ReceiptsFrom: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     allOrFirstTierCid = 0,
+     receiptListCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     AllOrFirstTier		*allOrFirstTier;
+     ReceiptsFromSeqOf		*receiptList;
+  };
+
+
+			ReceiptsFrom();
+			ReceiptsFrom (const ReceiptsFrom &);
+  virtual		~ReceiptsFrom();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ReceiptsFrom		&operator = (const ReceiptsFrom &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class SecurityCategories: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    SecurityCategory	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			SecurityCategories() { count = 0; first = curr = last = NULL; }
+			SecurityCategories (const SecurityCategories &);
+  virtual		~SecurityCategories();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SecurityCategories		&operator = (const SecurityCategories &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  SecurityCategory	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  SecurityCategory	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  SecurityCategory	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  SecurityCategory	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  SecurityCategory	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  SecurityCategory	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  SecurityCategory	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  SecurityCategory	*Append();  // add elmt to end of list
+  SecurityCategory	*Prepend(); // add elmt to beginning of list
+  SecurityCategory	*InsertBefore(); //insert elmt before current elmt
+  SecurityCategory	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  SecurityCategories	&AppendCopy (SecurityCategory &elmt);  // add elmt to end of list
+  SecurityCategories	&PrependCopy (SecurityCategory &elmt); // add elmt to beginning of list
+  SecurityCategories	&InsertBeforeAndCopy (SecurityCategory &elmt); //insert elmt before current elmt
+  SecurityCategories	&InsertAfterAndCopy (SecurityCategory &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class MLReceiptPolicy: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     noneCid = 0,
+     insteadOfCid = 1,
+     inAdditionToCid = 2
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     AsnNull		*none;
+     MLReceiptPolicySeqOf		*insteadOf;
+     MLReceiptPolicySeqOf1		*inAdditionTo;
+  };
+
+
+			MLReceiptPolicy();
+			MLReceiptPolicy (const MLReceiptPolicy &);
+  virtual		~MLReceiptPolicy();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  MLReceiptPolicy		&operator = (const MLReceiptPolicy &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class ESSCertID: public AsnType
+{
+public:
+  CertHash		certHash;
+  IssuerSerial		*issuerSerial;
+
+			ESSCertID();
+			ESSCertID (const ESSCertID &);
+  virtual		~ESSCertID();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ESSCertID		&operator = (const ESSCertID &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class SigningCertificateSeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    ESSCertID	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			SigningCertificateSeqOf() { count = 0; first = curr = last = NULL; }
+			SigningCertificateSeqOf (const SigningCertificateSeqOf &);
+  virtual		~SigningCertificateSeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SigningCertificateSeqOf		&operator = (const SigningCertificateSeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  ESSCertID	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  ESSCertID	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  ESSCertID	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  ESSCertID	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  ESSCertID	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  ESSCertID	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  ESSCertID	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  ESSCertID	*Append();  // add elmt to end of list
+  ESSCertID	*Prepend(); // add elmt to beginning of list
+  ESSCertID	*InsertBefore(); //insert elmt before current elmt
+  ESSCertID	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  SigningCertificateSeqOf	&AppendCopy (ESSCertID &elmt);  // add elmt to end of list
+  SigningCertificateSeqOf	&PrependCopy (ESSCertID &elmt); // add elmt to beginning of list
+  SigningCertificateSeqOf	&InsertBeforeAndCopy (ESSCertID &elmt); //insert elmt before current elmt
+  SigningCertificateSeqOf	&InsertAfterAndCopy (ESSCertID &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class ESSSecurityLabel: public AsnType
+{
+public:
+  SecurityPolicyIdentifier		security_policy_identifier;
+  SecurityClassification		*security_classification;
+  ESSPrivacyMark		*privacy_mark;
+  SecurityCategories		*security_categories;
+
+			ESSSecurityLabel();
+			ESSSecurityLabel (const ESSSecurityLabel &);
+  virtual		~ESSSecurityLabel();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ESSSecurityLabel		&operator = (const ESSSecurityLabel &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class MLData: public AsnType
+{
+public:
+  EntityIdentifier		*mailListIdentifier;
+  GeneralizedTime		expansionTime;
+  MLReceiptPolicy		*mlReceiptPolicy;
+
+			MLData();
+			MLData (const MLData &);
+  virtual		~MLData();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  MLData		&operator = (const MLData &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class ReceiptRequest: public AsnType
+{
+public:
+  ContentIdentifier		signedContentIdentifier;
+  ReceiptsFrom		*receiptsFrom;
+  ReceiptRequestSeqOf		receiptsTo;
+
+			ReceiptRequest();
+			ReceiptRequest (const ReceiptRequest &);
+  virtual		~ReceiptRequest();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ReceiptRequest		&operator = (const ReceiptRequest &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class Receipt: public AsnType
+{
+public:
+  CMSVersion		version;
+  ContentType		contentType;
+  ContentIdentifier		signedContentIdentifier;
+  AsnOcts		originatorSignatureValue;
+
+			Receipt();
+			Receipt (const Receipt &);
+  virtual		~Receipt();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Receipt		&operator = (const Receipt &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class ContentHints: public AsnType
+{
+public:
+  UTF8String		*contentDescription;
+  ContentType		contentType;
+
+			ContentHints();
+			ContentHints (const ContentHints &);
+  virtual		~ContentHints();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ContentHints		&operator = (const ContentHints &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class ContentReference: public AsnType
+{
+public:
+  ContentType		contentType;
+  ContentIdentifier		signedContentIdentifier;
+  AsnOcts		originatorSignatureValue;
+
+			ContentReference();
+			ContentReference (const ContentReference &);
+  virtual		~ContentReference();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ContentReference		&operator = (const ContentReference &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class EquivalentLabels: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    ESSSecurityLabel	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			EquivalentLabels() { count = 0; first = curr = last = NULL; }
+			EquivalentLabels (const EquivalentLabels &);
+  virtual		~EquivalentLabels();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EquivalentLabels		&operator = (const EquivalentLabels &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  ESSSecurityLabel	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  ESSSecurityLabel	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  ESSSecurityLabel	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  ESSSecurityLabel	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  ESSSecurityLabel	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  ESSSecurityLabel	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  ESSSecurityLabel	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  ESSSecurityLabel	*Append();  // add elmt to end of list
+  ESSSecurityLabel	*Prepend(); // add elmt to beginning of list
+  ESSSecurityLabel	*InsertBefore(); //insert elmt before current elmt
+  ESSSecurityLabel	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  EquivalentLabels	&AppendCopy (ESSSecurityLabel &elmt);  // add elmt to end of list
+  EquivalentLabels	&PrependCopy (ESSSecurityLabel &elmt); // add elmt to beginning of list
+  EquivalentLabels	&InsertBeforeAndCopy (ESSSecurityLabel &elmt); //insert elmt before current elmt
+  EquivalentLabels	&InsertAfterAndCopy (ESSSecurityLabel &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class MLExpansionHistory: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    MLData	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			MLExpansionHistory() { count = 0; first = curr = last = NULL; }
+			MLExpansionHistory (const MLExpansionHistory &);
+  virtual		~MLExpansionHistory();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  MLExpansionHistory		&operator = (const MLExpansionHistory &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  MLData	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  MLData	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  MLData	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  MLData	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  MLData	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  MLData	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  MLData	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  MLData	*Append();  // add elmt to end of list
+  MLData	*Prepend(); // add elmt to beginning of list
+  MLData	*InsertBefore(); //insert elmt before current elmt
+  MLData	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  MLExpansionHistory	&AppendCopy (MLData &elmt);  // add elmt to end of list
+  MLExpansionHistory	&PrependCopy (MLData &elmt); // add elmt to beginning of list
+  MLExpansionHistory	&InsertBeforeAndCopy (MLData &elmt); //insert elmt before current elmt
+  MLExpansionHistory	&InsertAfterAndCopy (MLData &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class SigningCertificate: public AsnType
+{
+public:
+  SigningCertificateSeqOf		certs;
+  SigningCertificateSeqOf1		*policies;
+
+			SigningCertificate();
+			SigningCertificate (const SigningCertificate &);
+  virtual		~SigningCertificate();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SigningCertificate		&operator = (const SigningCertificate &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define ub_receiptsTo_val 16
+#define ub_receiptsTo     AsnInt(ub_receiptsTo_val)
+#define smime_arc 1, 2, 840, 113549, 1, 9, 16
+#define smime     AsnOid(smime_arc)
+#define id_aa_arc 1, 2, 840, 113549, 1, 9, 16, 2
+#define id_aa     AsnOid(id_aa_arc)
+#define id_aa_receiptRequest_arc 1, 2, 840, 113549, 1, 9, 16, 2, 1
+#define id_aa_receiptRequest     AsnOid(id_aa_receiptRequest_arc)
+#define id_aa_contentIdentifier_arc 1, 2, 840, 113549, 1, 9, 16, 2, 7
+#define id_aa_contentIdentifier     AsnOid(id_aa_contentIdentifier_arc)
+#define id_ct_receipt_arc 1, 2, 840, 113549, 1, 9, 16, 1, 1
+#define id_ct_receipt     AsnOid(id_ct_receipt_arc)
+#define id_aa_contentHint_arc 1, 2, 840, 113549, 1, 9, 16, 2, 4
+#define id_aa_contentHint     AsnOid(id_aa_contentHint_arc)
+#define id_aa_msgSigDigest_arc 1, 2, 840, 113549, 1, 9, 16, 2, 5
+#define id_aa_msgSigDigest     AsnOid(id_aa_msgSigDigest_arc)
+#define id_aa_contentReference_arc 1, 2, 840, 113549, 1, 9, 16, 2, 10
+#define id_aa_contentReference     AsnOid(id_aa_contentReference_arc)
+#define id_aa_securityLabel_arc 1, 2, 840, 113549, 1, 9, 16, 2, 2
+#define id_aa_securityLabel     AsnOid(id_aa_securityLabel_arc)
+#define id_aa_equivalentLabels_arc 1, 2, 840, 113549, 1, 9, 16, 2, 9
+#define id_aa_equivalentLabels     AsnOid(id_aa_equivalentLabels_arc)
+#define id_aa_mlExpandHistory_arc 1, 2, 840, 113549, 1, 9, 16, 2, 3
+#define id_aa_mlExpandHistory     AsnOid(id_aa_mlExpandHistory_arc)
+#define ub_ml_expansion_history_val 64
+#define ub_ml_expansion_history     AsnInt(ub_ml_expansion_history_val)
+#define id_aa_signingCertificate_arc 1, 2, 840, 113549, 1, 9, 16, 2, 4444
+#define id_aa_signingCertificate     AsnOid(id_aa_signingCertificate_arc)
+#define id_pkix_arc 1, 3, 6, 1, 5, 5, 7
+#define id_pkix     AsnOid(id_pkix_arc)
+#define id_qt_arc 1, 3, 6, 1, 5, 5, 7, 2
+#define id_qt     AsnOid(id_qt_arc)
+#define id_qt_cps_arc 1, 3, 6, 1, 5, 5, 7, 2, 1
+#define id_qt_cps     AsnOid(id_qt_cps_arc)
+#define id_qt_unotice_arc 1, 3, 6, 1, 5, 5, 7, 2, 2
+#define id_qt_unotice     AsnOid(id_qt_unotice_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_ess.h */
diff --git a/SecurityASN1/inc/sm_vdatypes.h b/SecurityASN1/inc/sm_vdatypes.h
new file mode 100644
index 00000000..f48f6424
--- /dev/null
+++ b/SecurityASN1/inc/sm_vdatypes.h
@@ -0,0 +1,48 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_vdatypes.h - class definitions for ASN.1 module VdaEnhancedTypes
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_vdatypes_h_
+#define _sm_vdatypes_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class BigIntegerStr;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+/* [UNIVERSAL 2] IMPLICIT OCTET STRING */
+class BigIntegerStr: public AsnOcts
+{
+public:
+			BigIntegerStr(): AsnOcts() {}
+			BigIntegerStr (const char *str): AsnOcts (str) {}
+			BigIntegerStr (const char *str, const size_t len): AsnOcts (str, len) {}
+			BigIntegerStr (const AsnOcts &o): AsnOcts (o) {}
+  BigIntegerStr		&operator = (const BigIntegerStr &o)	{ ReSet (o); return *this; }
+  BigIntegerStr		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_vdatypes.h */
diff --git a/SecurityASN1/inc/sm_x411mtsas.h b/SecurityASN1/inc/sm_x411mtsas.h
new file mode 100644
index 00000000..4a2bde91
--- /dev/null
+++ b/SecurityASN1/inc/sm_x411mtsas.h
@@ -0,0 +1,696 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x411mtsas.h - class definitions for ASN.1 module MTSAbstractService
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_x411mtsas_h_
+#define _sm_x411mtsas_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class CountryName;
+class AdministrationDomainName;
+class PrivateDomainName;
+class PersonalName;
+class DomainDefinedAttribute;
+class ExtensionAttribute;
+class TeletexDomainDefinedAttribute;
+class OrganizationUnitNames;
+class DomainDefinedAttributes;
+class ExtensionAttributes;
+class StandardAttributes;
+class ORAddress;
+class TeletexPersonalName;
+class TeletexOrganizationUnitNames;
+class TeletexDomainDefinedAttributes;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+typedef enum MTSAbstractServiceAnyId
+{
+
+} MTSAbstractServiceAnyId;
+
+
+class CountryName: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     x121_dcc_codeCid = 0,
+     iso_3166_alpha2_codeCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     NumericString		*x121_dcc_code;
+     PrintableString		*iso_3166_alpha2_code;
+  };
+
+
+			CountryName();
+			CountryName (const CountryName &);
+  virtual		~CountryName();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CountryName		&operator = (const CountryName &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class AdministrationDomainName: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     numericCid = 0,
+     printableCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     NumericString		*numeric;
+     PrintableString		*printable;
+  };
+
+
+			AdministrationDomainName();
+			AdministrationDomainName (const AdministrationDomainName &);
+  virtual		~AdministrationDomainName();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AdministrationDomainName		&operator = (const AdministrationDomainName &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+/* NumericString (SIZE (1..ub-x121-address-length)) */
+typedef NumericString X121Address;
+
+/* PrintableString (SIZE (1..ub-terminal-id-length)) */
+typedef PrintableString TerminalIdentifier;
+
+class PrivateDomainName: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     numericCid = 0,
+     printableCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     NumericString		*numeric;
+     PrintableString		*printable;
+  };
+
+
+			PrivateDomainName();
+			PrivateDomainName (const PrivateDomainName &);
+  virtual		~PrivateDomainName();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PrivateDomainName		&operator = (const PrivateDomainName &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+/* PrintableString (SIZE (1..ub-organization-name-length)) */
+typedef PrintableString OrganizationName;
+
+/* NumericString (SIZE (1..ub-numeric-user-id-length)) */
+typedef NumericString NumericUserIdentifier;
+
+class PersonalName: public AsnType
+{
+public:
+  PrintableString		surname;
+  PrintableString		*given_name;
+  PrintableString		*initials;
+  PrintableString		*generation_qualifier;
+
+			PersonalName();
+			PersonalName (const PersonalName &);
+  virtual		~PersonalName();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PersonalName		&operator = (const PersonalName &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+/* PrintableString (SIZE (1..ub-organizational-unit-name-length)) */
+typedef PrintableString OrganizationUnitName;
+
+class DomainDefinedAttribute: public AsnType
+{
+public:
+  PrintableString		type;
+  PrintableString		value;
+
+			DomainDefinedAttribute();
+			DomainDefinedAttribute (const DomainDefinedAttribute &);
+  virtual		~DomainDefinedAttribute();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DomainDefinedAttribute		&operator = (const DomainDefinedAttribute &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class ExtensionAttribute: public AsnType
+{
+public:
+  AsnInt		extension_attribute_type;
+  AsnAny		extension_attribute_value;
+
+			ExtensionAttribute();
+			ExtensionAttribute (const ExtensionAttribute &);
+  virtual		~ExtensionAttribute();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ExtensionAttribute		&operator = (const ExtensionAttribute &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+/* TeletexString (SIZE (1..ub-organizational-unit-name-length)) */
+typedef TeletexString TeletexOrganizationalUnitName;
+
+class TeletexDomainDefinedAttribute: public AsnType
+{
+public:
+  TeletexString		type;
+  TeletexString		value;
+
+			TeletexDomainDefinedAttribute();
+			TeletexDomainDefinedAttribute (const TeletexDomainDefinedAttribute &);
+  virtual		~TeletexDomainDefinedAttribute();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  TeletexDomainDefinedAttribute		&operator = (const TeletexDomainDefinedAttribute &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+/* X121Address */
+typedef X121Address NetworkAddress;
+
+class OrganizationUnitNames: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    OrganizationUnitName	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			OrganizationUnitNames() { count = 0; first = curr = last = NULL; }
+			OrganizationUnitNames (const OrganizationUnitNames &);
+  virtual		~OrganizationUnitNames();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  OrganizationUnitNames		&operator = (const OrganizationUnitNames &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  OrganizationUnitName	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  OrganizationUnitName	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  OrganizationUnitName	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  OrganizationUnitName	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  OrganizationUnitName	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  OrganizationUnitName	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  OrganizationUnitName	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  OrganizationUnitName	*Append();  // add elmt to end of list
+  OrganizationUnitName	*Prepend(); // add elmt to beginning of list
+  OrganizationUnitName	*InsertBefore(); //insert elmt before current elmt
+  OrganizationUnitName	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  OrganizationUnitNames	&AppendCopy (OrganizationUnitName &elmt);  // add elmt to end of list
+  OrganizationUnitNames	&PrependCopy (OrganizationUnitName &elmt); // add elmt to beginning of list
+  OrganizationUnitNames	&InsertBeforeAndCopy (OrganizationUnitName &elmt); //insert elmt before current elmt
+  OrganizationUnitNames	&InsertAfterAndCopy (OrganizationUnitName &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class DomainDefinedAttributes: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    DomainDefinedAttribute	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			DomainDefinedAttributes() { count = 0; first = curr = last = NULL; }
+			DomainDefinedAttributes (const DomainDefinedAttributes &);
+  virtual		~DomainDefinedAttributes();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DomainDefinedAttributes		&operator = (const DomainDefinedAttributes &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  DomainDefinedAttribute	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  DomainDefinedAttribute	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  DomainDefinedAttribute	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  DomainDefinedAttribute	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  DomainDefinedAttribute	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  DomainDefinedAttribute	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  DomainDefinedAttribute	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  DomainDefinedAttribute	*Append();  // add elmt to end of list
+  DomainDefinedAttribute	*Prepend(); // add elmt to beginning of list
+  DomainDefinedAttribute	*InsertBefore(); //insert elmt before current elmt
+  DomainDefinedAttribute	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  DomainDefinedAttributes	&AppendCopy (DomainDefinedAttribute &elmt);  // add elmt to end of list
+  DomainDefinedAttributes	&PrependCopy (DomainDefinedAttribute &elmt); // add elmt to beginning of list
+  DomainDefinedAttributes	&InsertBeforeAndCopy (DomainDefinedAttribute &elmt); //insert elmt before current elmt
+  DomainDefinedAttributes	&InsertAfterAndCopy (DomainDefinedAttribute &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class ExtensionAttributes: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    ExtensionAttribute	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			ExtensionAttributes() { count = 0; first = curr = last = NULL; }
+			ExtensionAttributes (const ExtensionAttributes &);
+  virtual		~ExtensionAttributes();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ExtensionAttributes		&operator = (const ExtensionAttributes &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  ExtensionAttribute	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  ExtensionAttribute	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  ExtensionAttribute	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  ExtensionAttribute	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  ExtensionAttribute	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  ExtensionAttribute	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  ExtensionAttribute	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  ExtensionAttribute	*Append();  // add elmt to end of list
+  ExtensionAttribute	*Prepend(); // add elmt to beginning of list
+  ExtensionAttribute	*InsertBefore(); //insert elmt before current elmt
+  ExtensionAttribute	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  ExtensionAttributes	&AppendCopy (ExtensionAttribute &elmt);  // add elmt to end of list
+  ExtensionAttributes	&PrependCopy (ExtensionAttribute &elmt); // add elmt to beginning of list
+  ExtensionAttributes	&InsertBeforeAndCopy (ExtensionAttribute &elmt); //insert elmt before current elmt
+  ExtensionAttributes	&InsertAfterAndCopy (ExtensionAttribute &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class StandardAttributes: public AsnType
+{
+public:
+  CountryName		*country_name;
+  AdministrationDomainName		*administration_domain_name;
+  NetworkAddress		*network_address;
+  TerminalIdentifier		*terminal_identifier;
+  PrivateDomainName		*private_domain_name;
+  OrganizationName		*organization_name;
+  NumericUserIdentifier		*numeric_user_identifier;
+  PersonalName		*personal_name;
+  OrganizationUnitNames		*organizational_unit_names;
+
+			StandardAttributes();
+			StandardAttributes (const StandardAttributes &);
+  virtual		~StandardAttributes();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  StandardAttributes		&operator = (const StandardAttributes &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class ORAddress: public AsnType
+{
+public:
+  StandardAttributes		*standard_attributes;
+  DomainDefinedAttributes		*domain_defined_attributes;
+  ExtensionAttributes		*extension_attributes;
+
+			ORAddress();
+			ORAddress (const ORAddress &);
+  virtual		~ORAddress();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ORAddress		&operator = (const ORAddress &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+/* PrintableString (SIZE (1..ub-common-name-length)) */
+typedef PrintableString CommonName;
+
+/* TeletexString (SIZE (1..ub-common-name-length)) */
+typedef TeletexString TeletexCommonName;
+
+/* TeletexString (SIZE (1..ub-organization-name-length)) */
+typedef TeletexString TeletexOrganizationalName;
+
+class TeletexPersonalName: public AsnType
+{
+public:
+  TeletexString		surname;
+  TeletexString		*given_name;
+  TeletexString		*initials;
+  TeletexString		*generation_qualifier;
+
+			TeletexPersonalName();
+			TeletexPersonalName (const TeletexPersonalName &);
+  virtual		~TeletexPersonalName();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  TeletexPersonalName		&operator = (const TeletexPersonalName &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class TeletexOrganizationUnitNames: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    TeletexOrganizationalUnitName	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			TeletexOrganizationUnitNames() { count = 0; first = curr = last = NULL; }
+			TeletexOrganizationUnitNames (const TeletexOrganizationUnitNames &);
+  virtual		~TeletexOrganizationUnitNames();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  TeletexOrganizationUnitNames		&operator = (const TeletexOrganizationUnitNames &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  TeletexOrganizationalUnitName	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  TeletexOrganizationalUnitName	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  TeletexOrganizationalUnitName	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  TeletexOrganizationalUnitName	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  TeletexOrganizationalUnitName	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  TeletexOrganizationalUnitName	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  TeletexOrganizationalUnitName	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  TeletexOrganizationalUnitName	*Append();  // add elmt to end of list
+  TeletexOrganizationalUnitName	*Prepend(); // add elmt to beginning of list
+  TeletexOrganizationalUnitName	*InsertBefore(); //insert elmt before current elmt
+  TeletexOrganizationalUnitName	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  TeletexOrganizationUnitNames	&AppendCopy (TeletexOrganizationalUnitName &elmt);  // add elmt to end of list
+  TeletexOrganizationUnitNames	&PrependCopy (TeletexOrganizationalUnitName &elmt); // add elmt to beginning of list
+  TeletexOrganizationUnitNames	&InsertBeforeAndCopy (TeletexOrganizationalUnitName &elmt); //insert elmt before current elmt
+  TeletexOrganizationUnitNames	&InsertAfterAndCopy (TeletexOrganizationalUnitName &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class TeletexDomainDefinedAttributes: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    TeletexDomainDefinedAttribute	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			TeletexDomainDefinedAttributes() { count = 0; first = curr = last = NULL; }
+			TeletexDomainDefinedAttributes (const TeletexDomainDefinedAttributes &);
+  virtual		~TeletexDomainDefinedAttributes();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  TeletexDomainDefinedAttributes		&operator = (const TeletexDomainDefinedAttributes &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  TeletexDomainDefinedAttribute	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  TeletexDomainDefinedAttribute	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  TeletexDomainDefinedAttribute	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  TeletexDomainDefinedAttribute	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  TeletexDomainDefinedAttribute	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  TeletexDomainDefinedAttribute	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  TeletexDomainDefinedAttribute	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  TeletexDomainDefinedAttribute	*Append();  // add elmt to end of list
+  TeletexDomainDefinedAttribute	*Prepend(); // add elmt to beginning of list
+  TeletexDomainDefinedAttribute	*InsertBefore(); //insert elmt before current elmt
+  TeletexDomainDefinedAttribute	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  TeletexDomainDefinedAttributes	&AppendCopy (TeletexDomainDefinedAttribute &elmt);  // add elmt to end of list
+  TeletexDomainDefinedAttributes	&PrependCopy (TeletexDomainDefinedAttribute &elmt); // add elmt to beginning of list
+  TeletexDomainDefinedAttributes	&InsertBeforeAndCopy (TeletexDomainDefinedAttribute &elmt); //insert elmt before current elmt
+  TeletexDomainDefinedAttributes	&InsertAfterAndCopy (TeletexDomainDefinedAttribute &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_x411mtsas.h */
diff --git a/SecurityASN1/inc/sm_x411ub.h b/SecurityASN1/inc/sm_x411ub.h
new file mode 100644
index 00000000..fc4fd2e6
--- /dev/null
+++ b/SecurityASN1/inc/sm_x411ub.h
@@ -0,0 +1,139 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x411ub.h - class definitions for ASN.1 module UpperBounds
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_x411ub_h_
+#define _sm_x411ub_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define ub_integer_options_val 256
+#define ub_integer_options     AsnInt(ub_integer_options_val)
+#define ub_queue_size_val 2147483647
+#define ub_queue_size     AsnInt(ub_queue_size_val)
+#define ub_content_length_val 2147483647
+#define ub_content_length     AsnInt(ub_content_length_val)
+#define ub_password_length_val 62
+#define ub_password_length     AsnInt(ub_password_length_val)
+#define ub_bit_options_val 16
+#define ub_bit_options     AsnInt(ub_bit_options_val)
+#define ub_content_types_val 1024
+#define ub_content_types     AsnInt(ub_content_types_val)
+#define ub_tsap_id_length_val 16
+#define ub_tsap_id_length     AsnInt(ub_tsap_id_length_val)
+#define ub_recipients_val 32767
+#define ub_recipients     AsnInt(ub_recipients_val)
+#define ub_content_id_length_val 16
+#define ub_content_id_length     AsnInt(ub_content_id_length_val)
+#define ub_x121_address_length_val 15
+#define ub_x121_address_length     AsnInt(ub_x121_address_length_val)
+#define ub_mts_user_types_val 256
+#define ub_mts_user_types     AsnInt(ub_mts_user_types_val)
+#define ub_reason_codes_val 32767
+#define ub_reason_codes     AsnInt(ub_reason_codes_val)
+#define ub_diagnostic_codes_val 32767
+#define ub_diagnostic_codes     AsnInt(ub_diagnostic_codes_val)
+#define ub_supplementary_info_length_val 256
+#define ub_supplementary_info_length     AsnInt(ub_supplementary_info_length_val)
+#define ub_extension_types_val 256
+#define ub_extension_types     AsnInt(ub_extension_types_val)
+#define ub_recipient_number_for_advice_length_val 32
+#define ub_recipient_number_for_advice_length     AsnInt(ub_recipient_number_for_advice_length_val)
+#define ub_content_correlator_length_val 512
+#define ub_content_correlator_length     AsnInt(ub_content_correlator_length_val)
+#define ub_redirections_val 512
+#define ub_redirections     AsnInt(ub_redirections_val)
+#define ub_dl_expansions_val 512
+#define ub_dl_expansions     AsnInt(ub_dl_expansions_val)
+#define ub_built_in_content_type_val 32767
+#define ub_built_in_content_type     AsnInt(ub_built_in_content_type_val)
+#define ub_local_id_length_val 32
+#define ub_local_id_length     AsnInt(ub_local_id_length_val)
+#define ub_mta_name_length_val 32
+#define ub_mta_name_length     AsnInt(ub_mta_name_length_val)
+#define ub_country_name_numeric_length_val 3
+#define ub_country_name_numeric_length     AsnInt(ub_country_name_numeric_length_val)
+#define ub_country_name_alpha_length_val 2
+#define ub_country_name_alpha_length     AsnInt(ub_country_name_alpha_length_val)
+#define ub_domain_name_length_val 16
+#define ub_domain_name_length     AsnInt(ub_domain_name_length_val)
+#define ub_terminal_id_length_val 24
+#define ub_terminal_id_length     AsnInt(ub_terminal_id_length_val)
+#define ub_organization_name_length_val 64
+#define ub_organization_name_length     AsnInt(ub_organization_name_length_val)
+#define ub_numeric_user_id_length_val 32
+#define ub_numeric_user_id_length     AsnInt(ub_numeric_user_id_length_val)
+#define ub_surname_length_val 40
+#define ub_surname_length     AsnInt(ub_surname_length_val)
+#define ub_given_name_length_val 16
+#define ub_given_name_length     AsnInt(ub_given_name_length_val)
+#define ub_initials_length_val 5
+#define ub_initials_length     AsnInt(ub_initials_length_val)
+#define ub_generation_qualifier_length_val 3
+#define ub_generation_qualifier_length     AsnInt(ub_generation_qualifier_length_val)
+#define ub_organizational_units_val 4
+#define ub_organizational_units     AsnInt(ub_organizational_units_val)
+#define ub_organizational_unit_name_length_val 32
+#define ub_organizational_unit_name_length     AsnInt(ub_organizational_unit_name_length_val)
+#define ub_domain_defined_attributes_val 4
+#define ub_domain_defined_attributes     AsnInt(ub_domain_defined_attributes_val)
+#define ub_domain_defined_attribute_type_length_val 8
+#define ub_domain_defined_attribute_type_length     AsnInt(ub_domain_defined_attribute_type_length_val)
+#define ub_domain_defined_attribute_value_length_val 128
+#define ub_domain_defined_attribute_value_length     AsnInt(ub_domain_defined_attribute_value_length_val)
+#define ub_extension_attributes_val 256
+#define ub_extension_attributes     AsnInt(ub_extension_attributes_val)
+#define ub_common_name_length_val 64
+#define ub_common_name_length     AsnInt(ub_common_name_length_val)
+#define ub_pds_name_length_val 16
+#define ub_pds_name_length     AsnInt(ub_pds_name_length_val)
+#define ub_postal_code_length_val 16
+#define ub_postal_code_length     AsnInt(ub_postal_code_length_val)
+#define ub_pds_parameter_length_val 30
+#define ub_pds_parameter_length     AsnInt(ub_pds_parameter_length_val)
+#define ub_physical_address_lines_val 6
+#define ub_physical_address_lines     AsnInt(ub_physical_address_lines_val)
+#define ub_unformatted_address_length_val 180
+#define ub_unformatted_address_length     AsnInt(ub_unformatted_address_length_val)
+#define ub_e163_4_number_length_val 15
+#define ub_e163_4_number_length     AsnInt(ub_e163_4_number_length_val)
+#define ub_e163_4_sub_address_length_val 40
+#define ub_e163_4_sub_address_length     AsnInt(ub_e163_4_sub_address_length_val)
+#define ub_built_in_encoded_information_types_val 32
+#define ub_built_in_encoded_information_types     AsnInt(ub_built_in_encoded_information_types_val)
+#define ub_teletex_private_use_length_val 128
+#define ub_teletex_private_use_length     AsnInt(ub_teletex_private_use_length_val)
+#define ub_encoded_information_types_val 1024
+#define ub_encoded_information_types     AsnInt(ub_encoded_information_types_val)
+#define ub_security_labels_val 256
+#define ub_security_labels     AsnInt(ub_security_labels_val)
+#define ub_labels_and_redirections_val 256
+#define ub_labels_and_redirections     AsnInt(ub_labels_and_redirections_val)
+#define ub_security_problems_val 256
+#define ub_security_problems     AsnInt(ub_security_problems_val)
+#define ub_privacy_mark_length_val 128
+#define ub_privacy_mark_length     AsnInt(ub_privacy_mark_length_val)
+#define ub_security_categories_val 64
+#define ub_security_categories     AsnInt(ub_security_categories_val)
+#define ub_transfers_val 512
+#define ub_transfers     AsnInt(ub_transfers_val)
+#define ub_bilateral_info_val 1024
+#define ub_bilateral_info     AsnInt(ub_bilateral_info_val)
+#define ub_additional_info_val 1024
+#define ub_additional_info     AsnInt(ub_additional_info_val)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_x411ub.h */
diff --git a/SecurityASN1/inc/sm_x501if.h b/SecurityASN1/inc/sm_x501if.h
new file mode 100644
index 00000000..df4239bb
--- /dev/null
+++ b/SecurityASN1/inc/sm_x501if.h
@@ -0,0 +1,543 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x501if.h - class definitions for ASN.1 module InformationFramework
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_x501if_h_
+#define _sm_x501if_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class AttributeTypeAndDistinguishedValueSetOfSeqSetOf;
+class AttributeTypeAndDistinguishedValueSetOfSeq;
+class AttributeTypeAndDistinguishedValueSetOf;
+class AttributeSetOf;
+class Attribute;
+class AttributeTypeAndDistinguishedValue;
+class RelativeDistinguishedName;
+class RDNSequence;
+class Attributes;
+class Name;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+typedef enum InformationFrameworkAnyId
+{
+
+} InformationFrameworkAnyId;
+
+
+/* OBJECT IDENTIFIER */
+typedef AsnOid AttributeType;
+
+/* ANY */
+typedef AsnAny AttributeValue;
+
+class AttributeTypeAndDistinguishedValueSetOfSeqSetOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    AsnAny	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			AttributeTypeAndDistinguishedValueSetOfSeqSetOf() { count = 0; first = curr = last = NULL; }
+			AttributeTypeAndDistinguishedValueSetOfSeqSetOf (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &);
+  virtual		~AttributeTypeAndDistinguishedValueSetOfSeqSetOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeTypeAndDistinguishedValueSetOfSeqSetOf		&operator = (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  AsnAny	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  AsnAny	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  AsnAny	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  AsnAny	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  AsnAny	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  AsnAny	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  AsnAny	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  AsnAny	*Append();  // add elmt to end of list
+  AsnAny	*Prepend(); // add elmt to beginning of list
+  AsnAny	*InsertBefore(); //insert elmt before current elmt
+  AsnAny	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  AttributeTypeAndDistinguishedValueSetOfSeqSetOf	&AppendCopy (AsnAny &elmt);  // add elmt to end of list
+  AttributeTypeAndDistinguishedValueSetOfSeqSetOf	&PrependCopy (AsnAny &elmt); // add elmt to beginning of list
+  AttributeTypeAndDistinguishedValueSetOfSeqSetOf	&InsertBeforeAndCopy (AsnAny &elmt); //insert elmt before current elmt
+  AttributeTypeAndDistinguishedValueSetOfSeqSetOf	&InsertAfterAndCopy (AsnAny &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeTypeAndDistinguishedValueSetOfSeq: public AsnType
+{
+public:
+  AsnOid		*distingAttrValue;
+  AttributeTypeAndDistinguishedValueSetOfSeqSetOf		contextList;
+
+			AttributeTypeAndDistinguishedValueSetOfSeq();
+			AttributeTypeAndDistinguishedValueSetOfSeq (const AttributeTypeAndDistinguishedValueSetOfSeq &);
+  virtual		~AttributeTypeAndDistinguishedValueSetOfSeq();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeTypeAndDistinguishedValueSetOfSeq		&operator = (const AttributeTypeAndDistinguishedValueSetOfSeq &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeTypeAndDistinguishedValueSetOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    AttributeTypeAndDistinguishedValueSetOfSeq	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			AttributeTypeAndDistinguishedValueSetOf() { count = 0; first = curr = last = NULL; }
+			AttributeTypeAndDistinguishedValueSetOf (const AttributeTypeAndDistinguishedValueSetOf &);
+  virtual		~AttributeTypeAndDistinguishedValueSetOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeTypeAndDistinguishedValueSetOf		&operator = (const AttributeTypeAndDistinguishedValueSetOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  AttributeTypeAndDistinguishedValueSetOfSeq	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  AttributeTypeAndDistinguishedValueSetOfSeq	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  AttributeTypeAndDistinguishedValueSetOfSeq	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  AttributeTypeAndDistinguishedValueSetOfSeq	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  AttributeTypeAndDistinguishedValueSetOfSeq	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  AttributeTypeAndDistinguishedValueSetOfSeq	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  AttributeTypeAndDistinguishedValueSetOfSeq	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  AttributeTypeAndDistinguishedValueSetOfSeq	*Append();  // add elmt to end of list
+  AttributeTypeAndDistinguishedValueSetOfSeq	*Prepend(); // add elmt to beginning of list
+  AttributeTypeAndDistinguishedValueSetOfSeq	*InsertBefore(); //insert elmt before current elmt
+  AttributeTypeAndDistinguishedValueSetOfSeq	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  AttributeTypeAndDistinguishedValueSetOf	&AppendCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt);  // add elmt to end of list
+  AttributeTypeAndDistinguishedValueSetOf	&PrependCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt); // add elmt to beginning of list
+  AttributeTypeAndDistinguishedValueSetOf	&InsertBeforeAndCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt); //insert elmt before current elmt
+  AttributeTypeAndDistinguishedValueSetOf	&InsertAfterAndCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeSetOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    AttributeValue	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			AttributeSetOf() { count = 0; first = curr = last = NULL; }
+			AttributeSetOf (const AttributeSetOf &);
+  virtual		~AttributeSetOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeSetOf		&operator = (const AttributeSetOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  AttributeValue	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  AttributeValue	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  AttributeValue	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  AttributeValue	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  AttributeValue	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  AttributeValue	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  AttributeValue	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  AttributeValue	*Append();  // add elmt to end of list
+  AttributeValue	*Prepend(); // add elmt to beginning of list
+  AttributeValue	*InsertBefore(); //insert elmt before current elmt
+  AttributeValue	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  AttributeSetOf	&AppendCopy (AttributeValue &elmt);  // add elmt to end of list
+  AttributeSetOf	&PrependCopy (AttributeValue &elmt); // add elmt to beginning of list
+  AttributeSetOf	&InsertBeforeAndCopy (AttributeValue &elmt); //insert elmt before current elmt
+  AttributeSetOf	&InsertAfterAndCopy (AttributeValue &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class Attribute: public AsnType
+{
+public:
+  AttributeType		type;
+  AttributeSetOf		values;
+
+			Attribute();
+			Attribute (const Attribute &);
+  virtual		~Attribute();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Attribute		&operator = (const Attribute &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeTypeAndDistinguishedValue: public AsnType
+{
+public:
+  AsnOid		type;
+  AsnAny		value;
+  AsnBool		*primaryDistinguished;
+  AttributeTypeAndDistinguishedValueSetOf		*valuesWithContext;
+
+			AttributeTypeAndDistinguishedValue();
+			AttributeTypeAndDistinguishedValue (const AttributeTypeAndDistinguishedValue &);
+  virtual		~AttributeTypeAndDistinguishedValue();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeTypeAndDistinguishedValue		&operator = (const AttributeTypeAndDistinguishedValue &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class RelativeDistinguishedName: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    AttributeTypeAndDistinguishedValue	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			RelativeDistinguishedName() { count = 0; first = curr = last = NULL; }
+			RelativeDistinguishedName (const RelativeDistinguishedName &);
+  virtual		~RelativeDistinguishedName();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RelativeDistinguishedName		&operator = (const RelativeDistinguishedName &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  AttributeTypeAndDistinguishedValue	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  AttributeTypeAndDistinguishedValue	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  AttributeTypeAndDistinguishedValue	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  AttributeTypeAndDistinguishedValue	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  AttributeTypeAndDistinguishedValue	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  AttributeTypeAndDistinguishedValue	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  AttributeTypeAndDistinguishedValue	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  AttributeTypeAndDistinguishedValue	*Append();  // add elmt to end of list
+  AttributeTypeAndDistinguishedValue	*Prepend(); // add elmt to beginning of list
+  AttributeTypeAndDistinguishedValue	*InsertBefore(); //insert elmt before current elmt
+  AttributeTypeAndDistinguishedValue	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  RelativeDistinguishedName	&AppendCopy (AttributeTypeAndDistinguishedValue &elmt);  // add elmt to end of list
+  RelativeDistinguishedName	&PrependCopy (AttributeTypeAndDistinguishedValue &elmt); // add elmt to beginning of list
+  RelativeDistinguishedName	&InsertBeforeAndCopy (AttributeTypeAndDistinguishedValue &elmt); //insert elmt before current elmt
+  RelativeDistinguishedName	&InsertAfterAndCopy (AttributeTypeAndDistinguishedValue &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class RDNSequence: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    RelativeDistinguishedName	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			RDNSequence() { count = 0; first = curr = last = NULL; }
+			RDNSequence (const RDNSequence &);
+  virtual		~RDNSequence();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  RDNSequence		&operator = (const RDNSequence &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  RelativeDistinguishedName	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  RelativeDistinguishedName	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  RelativeDistinguishedName	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  RelativeDistinguishedName	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  RelativeDistinguishedName	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  RelativeDistinguishedName	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  RelativeDistinguishedName	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  RelativeDistinguishedName	*Append();  // add elmt to end of list
+  RelativeDistinguishedName	*Prepend(); // add elmt to beginning of list
+  RelativeDistinguishedName	*InsertBefore(); //insert elmt before current elmt
+  RelativeDistinguishedName	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  RDNSequence	&AppendCopy (RelativeDistinguishedName &elmt);  // add elmt to end of list
+  RDNSequence	&PrependCopy (RelativeDistinguishedName &elmt); // add elmt to beginning of list
+  RDNSequence	&InsertBeforeAndCopy (RelativeDistinguishedName &elmt); //insert elmt before current elmt
+  RDNSequence	&InsertAfterAndCopy (RelativeDistinguishedName &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class Attributes: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    Attribute	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			Attributes() { count = 0; first = curr = last = NULL; }
+			Attributes (const Attributes &);
+  virtual		~Attributes();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Attributes		&operator = (const Attributes &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  Attribute	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  Attribute	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  Attribute	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  Attribute	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  Attribute	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  Attribute	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  Attribute	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  Attribute	*Append();  // add elmt to end of list
+  Attribute	*Prepend(); // add elmt to beginning of list
+  Attribute	*InsertBefore(); //insert elmt before current elmt
+  Attribute	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  Attributes	&AppendCopy (Attribute &elmt);  // add elmt to end of list
+  Attributes	&PrependCopy (Attribute &elmt); // add elmt to beginning of list
+  Attributes	&InsertBeforeAndCopy (Attribute &elmt); //insert elmt before current elmt
+  Attributes	&InsertAfterAndCopy (Attribute &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class Name: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     rDNSequenceCid = 0
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     RDNSequence		*rDNSequence;
+  };
+
+
+			Name();
+			Name (const Name &);
+  virtual		~Name();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Name		&operator = (const Name &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+/* RDNSequence */
+typedef RDNSequence DistinguishedName;
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_x501if.h */
diff --git a/SecurityASN1/inc/sm_x501ud.h b/SecurityASN1/inc/sm_x501ud.h
new file mode 100644
index 00000000..b2a4e1a1
--- /dev/null
+++ b/SecurityASN1/inc/sm_x501ud.h
@@ -0,0 +1,133 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x501ud.h - class definitions for ASN.1 module UsefulDefinitions
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_x501ud_h_
+#define _sm_x501ud_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define ds_arc 2, 5
+#define ds     AsnOid(ds_arc)
+#define module_arc 2, 5, 1
+#define module     AsnOid(module_arc)
+#define serviceElement_arc 2, 5, 2
+#define serviceElement     AsnOid(serviceElement_arc)
+#define applicationContext_arc 2, 5, 3
+#define applicationContext     AsnOid(applicationContext_arc)
+#define attributeType_arc 2, 5, 4
+#define attributeType     AsnOid(attributeType_arc)
+#define attributeSyntax_arc 2, 5, 5
+#define attributeSyntax     AsnOid(attributeSyntax_arc)
+#define objectClass_arc 2, 5, 6
+#define objectClass     AsnOid(objectClass_arc)
+#define dsAlgorithm_arc 2, 5, 8
+#define dsAlgorithm     AsnOid(dsAlgorithm_arc)
+#define abstractSyntax_arc 2, 5, 9
+#define abstractSyntax     AsnOid(abstractSyntax_arc)
+#define dsaOperationalAttribute_arc 2, 5, 12
+#define dsaOperationalAttribute     AsnOid(dsaOperationalAttribute_arc)
+#define matchingRule_arc 2, 5, 13
+#define matchingRule     AsnOid(matchingRule_arc)
+#define knowledgeMatchingRule_arc 2, 5, 14
+#define knowledgeMatchingRule     AsnOid(knowledgeMatchingRule_arc)
+#define nameForm_arc 2, 5, 15
+#define nameForm     AsnOid(nameForm_arc)
+#define group_arc 2, 5, 16
+#define group     AsnOid(group_arc)
+#define subentry_arc 2, 5, 17
+#define subentry     AsnOid(subentry_arc)
+#define operationalAttributeType_arc 2, 5, 18
+#define operationalAttributeType     AsnOid(operationalAttributeType_arc)
+#define operationalBinding_arc 2, 5, 19
+#define operationalBinding     AsnOid(operationalBinding_arc)
+#define schemaObjectClass_arc 2, 5, 20
+#define schemaObjectClass     AsnOid(schemaObjectClass_arc)
+#define schemaOperationalAttribute_arc 2, 5, 21
+#define schemaOperationalAttribute     AsnOid(schemaOperationalAttribute_arc)
+#define administrativeRoles_arc 2, 5, 23
+#define administrativeRoles     AsnOid(administrativeRoles_arc)
+#define accessControlAttribute_arc 2, 5, 24
+#define accessControlAttribute     AsnOid(accessControlAttribute_arc)
+#define rosObject_arc 2, 5, 25
+#define rosObject     AsnOid(rosObject_arc)
+#define contract_arc 2, 5, 26
+#define contract     AsnOid(contract_arc)
+#define package_arc 2, 5, 27
+#define package     AsnOid(package_arc)
+#define accessControlSchemes_arc 2, 5, 28
+#define accessControlSchemes     AsnOid(accessControlSchemes_arc)
+#define certificateExtension_arc 2, 5, 29
+#define certificateExtension     AsnOid(certificateExtension_arc)
+#define managementObject_arc 2, 5, 30
+#define managementObject     AsnOid(managementObject_arc)
+#define informationFramework_arc 2, 5, 1, 1, 3
+#define informationFramework     AsnOid(informationFramework_arc)
+#define directoryAbstractService_arc 2, 5, 1, 2, 3
+#define directoryAbstractService     AsnOid(directoryAbstractService_arc)
+#define distributedOperations_arc 2, 5, 1, 3, 3
+#define distributedOperations     AsnOid(distributedOperations_arc)
+#define protocolObjectIdentifiers_arc 2, 5, 1, 4, 3
+#define protocolObjectIdentifiers     AsnOid(protocolObjectIdentifiers_arc)
+#define selectedAttributeTypes_arc 2, 5, 1, 5, 3
+#define selectedAttributeTypes     AsnOid(selectedAttributeTypes_arc)
+#define selectedObjectClasses_arc 2, 5, 1, 6, 3
+#define selectedObjectClasses     AsnOid(selectedObjectClasses_arc)
+#define authenticationFramework_arc 2, 5, 1, 7, 3
+#define authenticationFramework     AsnOid(authenticationFramework_arc)
+#define algorithmObjectIdentifiers_arc 2, 5, 1, 8, 3
+#define algorithmObjectIdentifiers     AsnOid(algorithmObjectIdentifiers_arc)
+#define directoryObjectIdentifiers_arc 2, 5, 1, 9, 3
+#define directoryObjectIdentifiers     AsnOid(directoryObjectIdentifiers_arc)
+#define upperBounds_arc 2, 5, 1, 10, 3
+#define upperBounds     AsnOid(upperBounds_arc)
+#define dap_arc 2, 5, 1, 11, 3
+#define dap     AsnOid(dap_arc)
+#define dsp_arc 2, 5, 1, 12, 3
+#define dsp     AsnOid(dsp_arc)
+#define distributedDirectoryOIDs_arc 2, 5, 1, 13, 3
+#define distributedDirectoryOIDs     AsnOid(distributedDirectoryOIDs_arc)
+#define directoryShadowOIDs_arc 2, 5, 1, 14, 3
+#define directoryShadowOIDs     AsnOid(directoryShadowOIDs_arc)
+#define directoryShadowAbstractService_arc 2, 5, 1, 15, 3
+#define directoryShadowAbstractService     AsnOid(directoryShadowAbstractService_arc)
+#define disp_arc 2, 5, 1, 16, 3
+#define disp     AsnOid(disp_arc)
+#define dop_arc 2, 5, 1, 17, 3
+#define dop     AsnOid(dop_arc)
+#define opBindingManagement_arc 2, 5, 1, 18, 3
+#define opBindingManagement     AsnOid(opBindingManagement_arc)
+#define opBindingOIDs_arc 2, 5, 1, 19, 3
+#define opBindingOIDs     AsnOid(opBindingOIDs_arc)
+#define hierarchicalOperationalBindings_arc 2, 5, 1, 20, 3
+#define hierarchicalOperationalBindings     AsnOid(hierarchicalOperationalBindings_arc)
+#define dsaOperationalAttributeTypes_arc 2, 5, 1, 22, 3
+#define dsaOperationalAttributeTypes     AsnOid(dsaOperationalAttributeTypes_arc)
+#define schemaAdministration_arc 2, 5, 1, 23, 3
+#define schemaAdministration     AsnOid(schemaAdministration_arc)
+#define basicAccessControl_arc 2, 5, 1, 24, 3
+#define basicAccessControl     AsnOid(basicAccessControl_arc)
+#define directoryOperationalBindingTypes_arc 2, 5, 1, 25, 3
+#define directoryOperationalBindingTypes     AsnOid(directoryOperationalBindingTypes_arc)
+#define certificateExtensions_arc 2, 5, 1, 26, 0
+#define certificateExtensions     AsnOid(certificateExtensions_arc)
+#define directoryManagement_arc 2, 5, 1, 27, 1
+#define directoryManagement     AsnOid(directoryManagement_arc)
+#define enhancedSecurity_arc 2, 5, 1, 28
+#define enhancedSecurity     AsnOid(enhancedSecurity_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_x501ud.h */
diff --git a/SecurityASN1/inc/sm_x509af.h b/SecurityASN1/inc/sm_x509af.h
new file mode 100644
index 00000000..71dadac2
--- /dev/null
+++ b/SecurityASN1/inc/sm_x509af.h
@@ -0,0 +1,1252 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x509af.h - class definitions for ASN.1 module AuthenticationFramework
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_x509af_h_
+#define _sm_x509af_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class Version;
+class AttributeCertificateAssertionSetOf;
+class AttributeCertificateInfoSeqOf;
+class AlgorithmIdentifier;
+class Time;
+class Extension;
+class AttCertValidityPeriod;
+class Validity;
+class SubjectPublicKeyInfo;
+class Extensions;
+class IssuerSerial;
+class AttributeCertificateAssertionChoice;
+class AttributeCertificateInfoChoice;
+class CRLToSignSeqOfSeq;
+class CRLToSignSeqOf;
+class CertificateToSign;
+class CRLToSign;
+class AttributeCertificateInfo;
+class Certificate;
+class CrossCertificates;
+class CertificatePair;
+class CertificateList;
+class AttributeCertificate;
+class CertificationPathSeqOf;
+class ForwardCertificationPath;
+class ACPathData;
+class AttributeCertificationPathSeqOf;
+class Certificates;
+class CertificationPath;
+class AttributeCertificationPath;
+class AttributeCertificateAssertion;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+typedef enum AuthenticationFrameworkAnyId
+{
+
+} AuthenticationFrameworkAnyId;
+
+
+/* INTEGER { v1 (0), v2 (1), v3 (2) }  */
+class Version: public AsnInt
+{
+public:
+			Version(): AsnInt() {}
+			Version (int i): AsnInt (i) {}
+  enum
+  {
+    v1 = 0,
+    v2 = 1,
+    v3 = 2
+  };
+};
+
+
+/* OCTET STRING (SIZE (0..ub-password-length)) */
+typedef AsnOcts UserPassword;
+
+class AttributeCertificateAssertionSetOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    AttributeType	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			AttributeCertificateAssertionSetOf() { count = 0; first = curr = last = NULL; }
+			AttributeCertificateAssertionSetOf (const AttributeCertificateAssertionSetOf &);
+  virtual		~AttributeCertificateAssertionSetOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificateAssertionSetOf		&operator = (const AttributeCertificateAssertionSetOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  AttributeType	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  AttributeType	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  AttributeType	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  AttributeType	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  AttributeType	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  AttributeType	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  AttributeType	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  AttributeType	*Append();  // add elmt to end of list
+  AttributeType	*Prepend(); // add elmt to beginning of list
+  AttributeType	*InsertBefore(); //insert elmt before current elmt
+  AttributeType	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  AttributeCertificateAssertionSetOf	&AppendCopy (AttributeType &elmt);  // add elmt to end of list
+  AttributeCertificateAssertionSetOf	&PrependCopy (AttributeType &elmt); // add elmt to beginning of list
+  AttributeCertificateAssertionSetOf	&InsertBeforeAndCopy (AttributeType &elmt); //insert elmt before current elmt
+  AttributeCertificateAssertionSetOf	&InsertAfterAndCopy (AttributeType &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeCertificateInfoSeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    Attribute	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			AttributeCertificateInfoSeqOf() { count = 0; first = curr = last = NULL; }
+			AttributeCertificateInfoSeqOf (const AttributeCertificateInfoSeqOf &);
+  virtual		~AttributeCertificateInfoSeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificateInfoSeqOf		&operator = (const AttributeCertificateInfoSeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  Attribute	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  Attribute	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  Attribute	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  Attribute	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  Attribute	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  Attribute	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  Attribute	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  Attribute	*Append();  // add elmt to end of list
+  Attribute	*Prepend(); // add elmt to beginning of list
+  Attribute	*InsertBefore(); //insert elmt before current elmt
+  Attribute	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  AttributeCertificateInfoSeqOf	&AppendCopy (Attribute &elmt);  // add elmt to end of list
+  AttributeCertificateInfoSeqOf	&PrependCopy (Attribute &elmt); // add elmt to beginning of list
+  AttributeCertificateInfoSeqOf	&InsertBeforeAndCopy (Attribute &elmt); //insert elmt before current elmt
+  AttributeCertificateInfoSeqOf	&InsertAfterAndCopy (Attribute &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+/* BigIntegerStr */
+typedef BigIntegerStr CertificateSerialNumber;
+
+class AlgorithmIdentifier: public AsnType
+{
+public:
+  AsnOid		algorithm;
+  AsnAny		*parameters;
+
+			AlgorithmIdentifier();
+			AlgorithmIdentifier (const AlgorithmIdentifier &);
+  virtual		~AlgorithmIdentifier();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AlgorithmIdentifier		&operator = (const AlgorithmIdentifier &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class Time: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     utcTimeCid = 0,
+     generalizedTimeCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     UTCTime		*utcTime;
+     GeneralizedTime		*generalizedTime;
+  };
+
+
+			Time();
+			Time (const Time &);
+  virtual		~Time();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Time		&operator = (const Time &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class Extension: public AsnType
+{
+public:
+  AsnOid		extnId;
+  AsnBool		*critical;
+  AsnOcts		extnValue;
+
+			Extension();
+			Extension (const Extension &);
+  virtual		~Extension();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Extension		&operator = (const Extension &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttCertValidityPeriod: public AsnType
+{
+public:
+  GeneralizedTime		notBeforeTime;
+  GeneralizedTime		notAfterTime;
+
+			AttCertValidityPeriod();
+			AttCertValidityPeriod (const AttCertValidityPeriod &);
+  virtual		~AttCertValidityPeriod();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttCertValidityPeriod		&operator = (const AttCertValidityPeriod &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class Validity: public AsnType
+{
+public:
+  Time		*notBefore;
+  Time		*notAfter;
+
+			Validity();
+			Validity (const Validity &);
+  virtual		~Validity();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Validity		&operator = (const Validity &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class SubjectPublicKeyInfo: public AsnType
+{
+public:
+  AlgorithmIdentifier		*algorithm;
+  AsnBits		subjectPublicKey;
+
+			SubjectPublicKeyInfo();
+			SubjectPublicKeyInfo (const SubjectPublicKeyInfo &);
+  virtual		~SubjectPublicKeyInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SubjectPublicKeyInfo		&operator = (const SubjectPublicKeyInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class Extensions: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    Extension	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			Extensions() { count = 0; first = curr = last = NULL; }
+			Extensions (const Extensions &);
+  virtual		~Extensions();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Extensions		&operator = (const Extensions &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  Extension	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  Extension	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  Extension	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  Extension	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  Extension	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  Extension	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  Extension	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  Extension	*Append();  // add elmt to end of list
+  Extension	*Prepend(); // add elmt to beginning of list
+  Extension	*InsertBefore(); //insert elmt before current elmt
+  Extension	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  Extensions	&AppendCopy (Extension &elmt);  // add elmt to end of list
+  Extensions	&PrependCopy (Extension &elmt); // add elmt to beginning of list
+  Extensions	&InsertBeforeAndCopy (Extension &elmt); //insert elmt before current elmt
+  Extensions	&InsertAfterAndCopy (Extension &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class IssuerSerial: public AsnType
+{
+public:
+  GeneralNames		issuer;
+  CertificateSerialNumber		serial;
+  UniqueIdentifier		*issuerUID;
+
+			IssuerSerial();
+			IssuerSerial (const IssuerSerial &);
+  virtual		~IssuerSerial();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  IssuerSerial		&operator = (const IssuerSerial &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeCertificateAssertionChoice: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     baseCertificateIDCid = 0,
+     subjectNameCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     IssuerSerial		*baseCertificateID;
+     Name		*subjectName;
+  };
+
+
+			AttributeCertificateAssertionChoice();
+			AttributeCertificateAssertionChoice (const AttributeCertificateAssertionChoice &);
+  virtual		~AttributeCertificateAssertionChoice();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificateAssertionChoice		&operator = (const AttributeCertificateAssertionChoice &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class AttributeCertificateInfoChoice: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     baseCertificateIDCid = 0,
+     subjectNameCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     IssuerSerial		*baseCertificateID;
+     GeneralNames		*subjectName;
+  };
+
+
+			AttributeCertificateInfoChoice();
+			AttributeCertificateInfoChoice (const AttributeCertificateInfoChoice &);
+  virtual		~AttributeCertificateInfoChoice();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificateInfoChoice		&operator = (const AttributeCertificateInfoChoice &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class CRLToSignSeqOfSeq: public AsnType
+{
+public:
+  CertificateSerialNumber		userCertificate;
+  Time		*revocationDate;
+  Extensions		*crlEntryExtensions;
+
+			CRLToSignSeqOfSeq();
+			CRLToSignSeqOfSeq (const CRLToSignSeqOfSeq &);
+  virtual		~CRLToSignSeqOfSeq();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CRLToSignSeqOfSeq		&operator = (const CRLToSignSeqOfSeq &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CRLToSignSeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    CRLToSignSeqOfSeq	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			CRLToSignSeqOf() { count = 0; first = curr = last = NULL; }
+			CRLToSignSeqOf (const CRLToSignSeqOf &);
+  virtual		~CRLToSignSeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CRLToSignSeqOf		&operator = (const CRLToSignSeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  CRLToSignSeqOfSeq	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  CRLToSignSeqOfSeq	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  CRLToSignSeqOfSeq	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  CRLToSignSeqOfSeq	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  CRLToSignSeqOfSeq	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  CRLToSignSeqOfSeq	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  CRLToSignSeqOfSeq	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  CRLToSignSeqOfSeq	*Append();  // add elmt to end of list
+  CRLToSignSeqOfSeq	*Prepend(); // add elmt to beginning of list
+  CRLToSignSeqOfSeq	*InsertBefore(); //insert elmt before current elmt
+  CRLToSignSeqOfSeq	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  CRLToSignSeqOf	&AppendCopy (CRLToSignSeqOfSeq &elmt);  // add elmt to end of list
+  CRLToSignSeqOf	&PrependCopy (CRLToSignSeqOfSeq &elmt); // add elmt to beginning of list
+  CRLToSignSeqOf	&InsertBeforeAndCopy (CRLToSignSeqOfSeq &elmt); //insert elmt before current elmt
+  CRLToSignSeqOf	&InsertAfterAndCopy (CRLToSignSeqOfSeq &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class CertificateToSign: public AsnType
+{
+public:
+  Version		*version;
+  CertificateSerialNumber		serialNumber;
+  AlgorithmIdentifier		*signature;
+  Name		*issuer;
+  Validity		*validity;
+  Name		*subject;
+  SubjectPublicKeyInfo		*subjectPublicKeyInfo;
+  UniqueIdentifier		*issuerUniqueIdentifier;
+  UniqueIdentifier		*subjectUniqueIdentifier;
+  Extensions		*extensions;
+
+			CertificateToSign();
+			CertificateToSign (const CertificateToSign &);
+  virtual		~CertificateToSign();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificateToSign		&operator = (const CertificateToSign &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CRLToSign: public AsnType
+{
+public:
+  Version		*version;
+  AlgorithmIdentifier		*signature;
+  Name		*issuer;
+  Time		*thisUpdate;
+  Time		*nextUpdate;
+  CRLToSignSeqOf		*revokedCertificates;
+  Extensions		*crlExtensions;
+
+			CRLToSign();
+			CRLToSign (const CRLToSign &);
+  virtual		~CRLToSign();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CRLToSign		&operator = (const CRLToSign &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeCertificateInfo: public AsnType
+{
+public:
+  Version		*version;
+  AttributeCertificateInfoChoice		*subject;
+  GeneralNames		issuer;
+  AlgorithmIdentifier		*signature;
+  CertificateSerialNumber		serialNumber;
+  AttCertValidityPeriod		*attCertValidityPeriod;
+  AttributeCertificateInfoSeqOf		attributes;
+  UniqueIdentifier		*issuerUniqueID;
+  Extensions		*extensions;
+
+			AttributeCertificateInfo();
+			AttributeCertificateInfo (const AttributeCertificateInfo &);
+  virtual		~AttributeCertificateInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificateInfo		&operator = (const AttributeCertificateInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class Certificate: public AsnType
+{
+public:
+  CertificateToSign		*certificateToSign;
+  AlgorithmIdentifier		*algorithmIdentifier;
+  AsnBits		signatureValue;
+
+			Certificate();
+			Certificate (const Certificate &);
+  virtual		~Certificate();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Certificate		&operator = (const Certificate &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CrossCertificates: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    Certificate	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			CrossCertificates() { count = 0; first = curr = last = NULL; }
+			CrossCertificates (const CrossCertificates &);
+  virtual		~CrossCertificates();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CrossCertificates		&operator = (const CrossCertificates &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  Certificate	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  Certificate	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  Certificate	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  Certificate	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  Certificate	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  Certificate	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  Certificate	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  Certificate	*Append();  // add elmt to end of list
+  Certificate	*Prepend(); // add elmt to beginning of list
+  Certificate	*InsertBefore(); //insert elmt before current elmt
+  Certificate	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  CrossCertificates	&AppendCopy (Certificate &elmt);  // add elmt to end of list
+  CrossCertificates	&PrependCopy (Certificate &elmt); // add elmt to beginning of list
+  CrossCertificates	&InsertBeforeAndCopy (Certificate &elmt); //insert elmt before current elmt
+  CrossCertificates	&InsertAfterAndCopy (Certificate &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class CertificatePair: public AsnType
+{
+public:
+  Certificate		*forward;
+  Certificate		*reverse;
+
+			CertificatePair();
+			CertificatePair (const CertificatePair &);
+  virtual		~CertificatePair();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificatePair		&operator = (const CertificatePair &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CertificateList: public AsnType
+{
+public:
+  CRLToSign		*crlToSign;
+  AlgorithmIdentifier		*algorithmIdentifier;
+  AsnBits		signatureValue;
+
+			CertificateList();
+			CertificateList (const CertificateList &);
+  virtual		~CertificateList();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificateList		&operator = (const CertificateList &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeCertificate: public AsnType
+{
+public:
+  AttributeCertificateInfo		*attributeCertificateInfo;
+  AlgorithmIdentifier		*algorithmIdentifier;
+  AsnBits		signatureValue;
+
+			AttributeCertificate();
+			AttributeCertificate (const AttributeCertificate &);
+  virtual		~AttributeCertificate();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificate		&operator = (const AttributeCertificate &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CertificationPathSeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    CertificatePair	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			CertificationPathSeqOf() { count = 0; first = curr = last = NULL; }
+			CertificationPathSeqOf (const CertificationPathSeqOf &);
+  virtual		~CertificationPathSeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificationPathSeqOf		&operator = (const CertificationPathSeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  CertificatePair	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  CertificatePair	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  CertificatePair	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  CertificatePair	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  CertificatePair	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  CertificatePair	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  CertificatePair	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  CertificatePair	*Append();  // add elmt to end of list
+  CertificatePair	*Prepend(); // add elmt to beginning of list
+  CertificatePair	*InsertBefore(); //insert elmt before current elmt
+  CertificatePair	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  CertificationPathSeqOf	&AppendCopy (CertificatePair &elmt);  // add elmt to end of list
+  CertificationPathSeqOf	&PrependCopy (CertificatePair &elmt); // add elmt to beginning of list
+  CertificationPathSeqOf	&InsertBeforeAndCopy (CertificatePair &elmt); //insert elmt before current elmt
+  CertificationPathSeqOf	&InsertAfterAndCopy (CertificatePair &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class ForwardCertificationPath: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    CrossCertificates	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			ForwardCertificationPath() { count = 0; first = curr = last = NULL; }
+			ForwardCertificationPath (const ForwardCertificationPath &);
+  virtual		~ForwardCertificationPath();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ForwardCertificationPath		&operator = (const ForwardCertificationPath &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  CrossCertificates	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  CrossCertificates	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  CrossCertificates	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  CrossCertificates	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  CrossCertificates	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  CrossCertificates	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  CrossCertificates	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  CrossCertificates	*Append();  // add elmt to end of list
+  CrossCertificates	*Prepend(); // add elmt to beginning of list
+  CrossCertificates	*InsertBefore(); //insert elmt before current elmt
+  CrossCertificates	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  ForwardCertificationPath	&AppendCopy (CrossCertificates &elmt);  // add elmt to end of list
+  ForwardCertificationPath	&PrependCopy (CrossCertificates &elmt); // add elmt to beginning of list
+  ForwardCertificationPath	&InsertBeforeAndCopy (CrossCertificates &elmt); //insert elmt before current elmt
+  ForwardCertificationPath	&InsertAfterAndCopy (CrossCertificates &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class ACPathData: public AsnType
+{
+public:
+  Certificate		*certificate;
+  AttributeCertificate		*attributeCertificate;
+
+			ACPathData();
+			ACPathData (const ACPathData &);
+  virtual		~ACPathData();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ACPathData		&operator = (const ACPathData &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeCertificationPathSeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    ACPathData	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			AttributeCertificationPathSeqOf() { count = 0; first = curr = last = NULL; }
+			AttributeCertificationPathSeqOf (const AttributeCertificationPathSeqOf &);
+  virtual		~AttributeCertificationPathSeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificationPathSeqOf		&operator = (const AttributeCertificationPathSeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  ACPathData	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  ACPathData	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  ACPathData	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  ACPathData	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  ACPathData	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  ACPathData	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  ACPathData	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  ACPathData	*Append();  // add elmt to end of list
+  ACPathData	*Prepend(); // add elmt to beginning of list
+  ACPathData	*InsertBefore(); //insert elmt before current elmt
+  ACPathData	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  AttributeCertificationPathSeqOf	&AppendCopy (ACPathData &elmt);  // add elmt to end of list
+  AttributeCertificationPathSeqOf	&PrependCopy (ACPathData &elmt); // add elmt to beginning of list
+  AttributeCertificationPathSeqOf	&InsertBeforeAndCopy (ACPathData &elmt); //insert elmt before current elmt
+  AttributeCertificationPathSeqOf	&InsertAfterAndCopy (ACPathData &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class Certificates: public AsnType
+{
+public:
+  Certificate		*userCertificate;
+  ForwardCertificationPath		*certificationPath;
+
+			Certificates();
+			Certificates (const Certificates &);
+  virtual		~Certificates();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  Certificates		&operator = (const Certificates &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CertificationPath: public AsnType
+{
+public:
+  Certificate		*userCertificate;
+  CertificationPathSeqOf		*theCACertificates;
+
+			CertificationPath();
+			CertificationPath (const CertificationPath &);
+  virtual		~CertificationPath();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificationPath		&operator = (const CertificationPath &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeCertificationPath: public AsnType
+{
+public:
+  AttributeCertificate		*attributeCertificate;
+  AttributeCertificationPathSeqOf		*acPath;
+
+			AttributeCertificationPath();
+			AttributeCertificationPath (const AttributeCertificationPath &);
+  virtual		~AttributeCertificationPath();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificationPath		&operator = (const AttributeCertificationPath &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributeCertificateAssertion: public AsnType
+{
+public:
+  AttributeCertificateAssertionChoice		*subject;
+  Name		*issuer;
+  GeneralizedTime		*attCertValidity;
+  AttributeCertificateAssertionSetOf		*attType;
+
+			AttributeCertificateAssertion();
+			AttributeCertificateAssertion (const AttributeCertificateAssertion &);
+  virtual		~AttributeCertificateAssertion();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributeCertificateAssertion		&operator = (const AttributeCertificateAssertion &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+/* Certificate */
+typedef Certificate UserCertificate;
+
+/* Certificate */
+typedef Certificate CACertificate;
+
+/* CertificatePair */
+typedef CertificatePair CrossCertificatePair;
+
+/* CertificateList */
+typedef CertificateList AuthorityRevocationList;
+
+/* CertificateList */
+typedef CertificateList CertificateRevocationList;
+
+/* CertificateList */
+typedef CertificateList AttributeCertificateRevocationList;
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define id_at_userPassword_arc 2, 5, 4, 35
+#define id_at_userPassword     AsnOid(id_at_userPassword_arc)
+#define id_at_userCertificate_arc 2, 5, 4, 36
+#define id_at_userCertificate     AsnOid(id_at_userCertificate_arc)
+#define id_at_cAcertificate_arc 2, 5, 4, 37
+#define id_at_cAcertificate     AsnOid(id_at_cAcertificate_arc)
+#define id_at_authorityRevocationList_arc 2, 5, 4, 38
+#define id_at_authorityRevocationList     AsnOid(id_at_authorityRevocationList_arc)
+#define id_at_certificateRevocationList_arc 2, 5, 4, 39
+#define id_at_certificateRevocationList     AsnOid(id_at_certificateRevocationList_arc)
+#define id_at_crossCertificatePair_arc 2, 5, 4, 40
+#define id_at_crossCertificatePair     AsnOid(id_at_crossCertificatePair_arc)
+#define id_at_attributeCertificate_arc 2, 5, 4, 58
+#define id_at_attributeCertificate     AsnOid(id_at_attributeCertificate_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_x509af.h */
diff --git a/SecurityASN1/inc/sm_x509ce.h b/SecurityASN1/inc/sm_x509ce.h
new file mode 100644
index 00000000..761a722e
--- /dev/null
+++ b/SecurityASN1/inc/sm_x509ce.h
@@ -0,0 +1,1098 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x509ce.h - class definitions for ASN.1 module CertificateExtensions
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_x509ce_h_
+#define _sm_x509ce_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class KeyUsage;
+class CRLReason;
+class ReasonFlags;
+class PolicyQualifierInfo;
+class AttributesSyntax;
+class DistributionPointName;
+class PolicyMappingsSyntaxSeq;
+class PolicyInformationSeqOf;
+class PolicyInformation;
+class GeneralSubtree;
+class DistributionPoint;
+class CertificatePoliciesSyntax;
+class GeneralSubtrees;
+class AuthorityKeyIdentifier;
+class ExtKeyUsageSyntax;
+class PrivateKeyUsagePeriod;
+class PolicyMappingsSyntax;
+class SupportedAlgorithm;
+class BasicConstraintsSyntax;
+class NameConstraintsSyntax;
+class PolicyConstraintsSyntax;
+class CertPolicySet;
+class CRLDistPointsSyntax;
+class IssuingDistPointSyntax;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+typedef enum CertificateExtensionsAnyId
+{
+
+} CertificateExtensionsAnyId;
+
+
+/* OCTET STRING */
+typedef AsnOcts KeyIdentifier;
+
+/* BIT STRING { digitalSignature (0), nonRepudiation (1), keyEncipherment (2), dataEncipherment (3), keyAgreement (4), keyCertSign (5), cRLSign (6), encipherOnly (7), decipherOnly (8) }  */
+class KeyUsage: public AsnBits
+{
+public:
+			KeyUsage(): AsnBits() {}
+			KeyUsage (const size_t bits): AsnBits (bits) {}
+			KeyUsage (const char *str, const size_t bitLen): AsnBits (str, bitLen) {}
+			KeyUsage (const AsnBits &b): AsnBits (b) {}
+  enum
+  {
+    digitalSignature = 0,
+    nonRepudiation = 1,
+    keyEncipherment = 2,
+    dataEncipherment = 3,
+    keyAgreement = 4,
+    keyCertSign = 5,
+    cRLSign = 6,
+    encipherOnly = 7,
+    decipherOnly = 8
+  };
+};
+
+
+/* OBJECT IDENTIFIER */
+typedef AsnOid KeyPurposeId;
+
+/* OBJECT IDENTIFIER */
+typedef AsnOid CertPolicyId;
+
+/* INTEGER (0..MAX) */
+typedef AsnInt BaseDistance;
+
+/* INTEGER (0..MAX) */
+typedef AsnInt SkipCerts;
+
+/* INTEGER (0..MAX) */
+typedef AsnInt CRLNumber;
+
+/* ENUMERATED { unspecified (0), keyCompromise (1), cACompromise (2), affiliationChanged (3), superseded (4), cessationOfOperation (5), certificateHold (6), removeFromCRL (8) }  */
+class CRLReason: public AsnEnum
+{
+public:
+			CRLReason(): AsnEnum() {}
+			CRLReason (int i): AsnEnum (i) {}
+  enum
+  {
+    unspecified = 0,
+    keyCompromise = 1,
+    cACompromise = 2,
+    affiliationChanged = 3,
+    superseded = 4,
+    cessationOfOperation = 5,
+    certificateHold = 6,
+    removeFromCRL = 8
+  };
+};
+
+
+/* OBJECT IDENTIFIER */
+typedef AsnOid HoldInstruction;
+
+/* BIT STRING { unused (0), keyCompromise (1), caCompromise (2), affiliationChanged (3), superseded (4), cessationOfOperation (5), certificateHold (6) }  */
+class ReasonFlags: public AsnBits
+{
+public:
+			ReasonFlags(): AsnBits() {}
+			ReasonFlags (const size_t bits): AsnBits (bits) {}
+			ReasonFlags (const char *str, const size_t bitLen): AsnBits (str, bitLen) {}
+			ReasonFlags (const AsnBits &b): AsnBits (b) {}
+  enum
+  {
+    unused = 0,
+    keyCompromise = 1,
+    caCompromise = 2,
+    affiliationChanged = 3,
+    superseded = 4,
+    cessationOfOperation = 5,
+    certificateHold = 6
+  };
+};
+
+
+class PolicyQualifierInfo: public AsnType
+{
+public:
+  AsnOid		policyQualifierId;
+  AsnAny		*qualifier;
+
+			PolicyQualifierInfo();
+			PolicyQualifierInfo (const PolicyQualifierInfo &);
+  virtual		~PolicyQualifierInfo();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PolicyQualifierInfo		&operator = (const PolicyQualifierInfo &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class AttributesSyntax: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    Attribute	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			AttributesSyntax() { count = 0; first = curr = last = NULL; }
+			AttributesSyntax (const AttributesSyntax &);
+  virtual		~AttributesSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AttributesSyntax		&operator = (const AttributesSyntax &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  Attribute	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  Attribute	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  Attribute	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  Attribute	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  Attribute	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  Attribute	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  Attribute	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  Attribute	*Append();  // add elmt to end of list
+  Attribute	*Prepend(); // add elmt to beginning of list
+  Attribute	*InsertBefore(); //insert elmt before current elmt
+  Attribute	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  AttributesSyntax	&AppendCopy (Attribute &elmt);  // add elmt to end of list
+  AttributesSyntax	&PrependCopy (Attribute &elmt); // add elmt to beginning of list
+  AttributesSyntax	&InsertBeforeAndCopy (Attribute &elmt); //insert elmt before current elmt
+  AttributesSyntax	&InsertAfterAndCopy (Attribute &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class DistributionPointName: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     fullNameCid = 0,
+     nameRelativeToCRLIssuerCid = 1
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     GeneralNames		*fullName;
+     RelativeDistinguishedName		*nameRelativeToCRLIssuer;
+  };
+
+
+			DistributionPointName();
+			DistributionPointName (const DistributionPointName &);
+  virtual		~DistributionPointName();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DistributionPointName		&operator = (const DistributionPointName &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class PolicyMappingsSyntaxSeq: public AsnType
+{
+public:
+  CertPolicyId		issuerDomainPolicy;
+  CertPolicyId		subjectDomainPolicy;
+
+			PolicyMappingsSyntaxSeq();
+			PolicyMappingsSyntaxSeq (const PolicyMappingsSyntaxSeq &);
+  virtual		~PolicyMappingsSyntaxSeq();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PolicyMappingsSyntaxSeq		&operator = (const PolicyMappingsSyntaxSeq &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class PolicyInformationSeqOf: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    PolicyQualifierInfo	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			PolicyInformationSeqOf() { count = 0; first = curr = last = NULL; }
+			PolicyInformationSeqOf (const PolicyInformationSeqOf &);
+  virtual		~PolicyInformationSeqOf();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PolicyInformationSeqOf		&operator = (const PolicyInformationSeqOf &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  PolicyQualifierInfo	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  PolicyQualifierInfo	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  PolicyQualifierInfo	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  PolicyQualifierInfo	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  PolicyQualifierInfo	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  PolicyQualifierInfo	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  PolicyQualifierInfo	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  PolicyQualifierInfo	*Append();  // add elmt to end of list
+  PolicyQualifierInfo	*Prepend(); // add elmt to beginning of list
+  PolicyQualifierInfo	*InsertBefore(); //insert elmt before current elmt
+  PolicyQualifierInfo	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  PolicyInformationSeqOf	&AppendCopy (PolicyQualifierInfo &elmt);  // add elmt to end of list
+  PolicyInformationSeqOf	&PrependCopy (PolicyQualifierInfo &elmt); // add elmt to beginning of list
+  PolicyInformationSeqOf	&InsertBeforeAndCopy (PolicyQualifierInfo &elmt); //insert elmt before current elmt
+  PolicyInformationSeqOf	&InsertAfterAndCopy (PolicyQualifierInfo &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class PolicyInformation: public AsnType
+{
+public:
+  CertPolicyId		policyIdentifier;
+  PolicyInformationSeqOf		*policyQualifiers;
+
+			PolicyInformation();
+			PolicyInformation (const PolicyInformation &);
+  virtual		~PolicyInformation();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PolicyInformation		&operator = (const PolicyInformation &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class GeneralSubtree: public AsnType
+{
+public:
+  GeneralName		*base;
+  BaseDistance		*minimum;
+  BaseDistance		*maximum;
+
+			GeneralSubtree();
+			GeneralSubtree (const GeneralSubtree &);
+  virtual		~GeneralSubtree();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  GeneralSubtree		&operator = (const GeneralSubtree &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class DistributionPoint: public AsnType
+{
+public:
+  DistributionPointName		*distributionPoint;
+  ReasonFlags		*reasons;
+  GeneralNames		*cRLIssuer;
+
+			DistributionPoint();
+			DistributionPoint (const DistributionPoint &);
+  virtual		~DistributionPoint();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DistributionPoint		&operator = (const DistributionPoint &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CertificatePoliciesSyntax: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    PolicyInformation	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			CertificatePoliciesSyntax() { count = 0; first = curr = last = NULL; }
+			CertificatePoliciesSyntax (const CertificatePoliciesSyntax &);
+  virtual		~CertificatePoliciesSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertificatePoliciesSyntax		&operator = (const CertificatePoliciesSyntax &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  PolicyInformation	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  PolicyInformation	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  PolicyInformation	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  PolicyInformation	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  PolicyInformation	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  PolicyInformation	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  PolicyInformation	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  PolicyInformation	*Append();  // add elmt to end of list
+  PolicyInformation	*Prepend(); // add elmt to beginning of list
+  PolicyInformation	*InsertBefore(); //insert elmt before current elmt
+  PolicyInformation	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  CertificatePoliciesSyntax	&AppendCopy (PolicyInformation &elmt);  // add elmt to end of list
+  CertificatePoliciesSyntax	&PrependCopy (PolicyInformation &elmt); // add elmt to beginning of list
+  CertificatePoliciesSyntax	&InsertBeforeAndCopy (PolicyInformation &elmt); //insert elmt before current elmt
+  CertificatePoliciesSyntax	&InsertAfterAndCopy (PolicyInformation &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class GeneralSubtrees: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    GeneralSubtree	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			GeneralSubtrees() { count = 0; first = curr = last = NULL; }
+			GeneralSubtrees (const GeneralSubtrees &);
+  virtual		~GeneralSubtrees();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  GeneralSubtrees		&operator = (const GeneralSubtrees &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  GeneralSubtree	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  GeneralSubtree	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  GeneralSubtree	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  GeneralSubtree	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  GeneralSubtree	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  GeneralSubtree	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  GeneralSubtree	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  GeneralSubtree	*Append();  // add elmt to end of list
+  GeneralSubtree	*Prepend(); // add elmt to beginning of list
+  GeneralSubtree	*InsertBefore(); //insert elmt before current elmt
+  GeneralSubtree	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  GeneralSubtrees	&AppendCopy (GeneralSubtree &elmt);  // add elmt to end of list
+  GeneralSubtrees	&PrependCopy (GeneralSubtree &elmt); // add elmt to beginning of list
+  GeneralSubtrees	&InsertBeforeAndCopy (GeneralSubtree &elmt); //insert elmt before current elmt
+  GeneralSubtrees	&InsertAfterAndCopy (GeneralSubtree &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class AuthorityKeyIdentifier: public AsnType
+{
+public:
+  KeyIdentifier		*keyIdentifier;
+  GeneralNames		*authorityCertIssuer;
+  CertificateSerialNumber		*authorityCertSerialNumber;
+
+			AuthorityKeyIdentifier();
+			AuthorityKeyIdentifier (const AuthorityKeyIdentifier &);
+  virtual		~AuthorityKeyIdentifier();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AuthorityKeyIdentifier		&operator = (const AuthorityKeyIdentifier &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+/* KeyIdentifier */
+typedef KeyIdentifier SubjectKeyIdentifier;
+
+class ExtKeyUsageSyntax: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    KeyPurposeId	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			ExtKeyUsageSyntax() { count = 0; first = curr = last = NULL; }
+			ExtKeyUsageSyntax (const ExtKeyUsageSyntax &);
+  virtual		~ExtKeyUsageSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  ExtKeyUsageSyntax		&operator = (const ExtKeyUsageSyntax &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  KeyPurposeId	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  KeyPurposeId	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  KeyPurposeId	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  KeyPurposeId	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  KeyPurposeId	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  KeyPurposeId	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  KeyPurposeId	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  KeyPurposeId	*Append();  // add elmt to end of list
+  KeyPurposeId	*Prepend(); // add elmt to beginning of list
+  KeyPurposeId	*InsertBefore(); //insert elmt before current elmt
+  KeyPurposeId	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  ExtKeyUsageSyntax	&AppendCopy (KeyPurposeId &elmt);  // add elmt to end of list
+  ExtKeyUsageSyntax	&PrependCopy (KeyPurposeId &elmt); // add elmt to beginning of list
+  ExtKeyUsageSyntax	&InsertBeforeAndCopy (KeyPurposeId &elmt); //insert elmt before current elmt
+  ExtKeyUsageSyntax	&InsertAfterAndCopy (KeyPurposeId &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class PrivateKeyUsagePeriod: public AsnType
+{
+public:
+  GeneralizedTime		*notBefore;
+  GeneralizedTime		*notAfter;
+
+			PrivateKeyUsagePeriod();
+			PrivateKeyUsagePeriod (const PrivateKeyUsagePeriod &);
+  virtual		~PrivateKeyUsagePeriod();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PrivateKeyUsagePeriod		&operator = (const PrivateKeyUsagePeriod &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class PolicyMappingsSyntax: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    PolicyMappingsSyntaxSeq	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			PolicyMappingsSyntax() { count = 0; first = curr = last = NULL; }
+			PolicyMappingsSyntax (const PolicyMappingsSyntax &);
+  virtual		~PolicyMappingsSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PolicyMappingsSyntax		&operator = (const PolicyMappingsSyntax &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  PolicyMappingsSyntaxSeq	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  PolicyMappingsSyntaxSeq	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  PolicyMappingsSyntaxSeq	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  PolicyMappingsSyntaxSeq	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  PolicyMappingsSyntaxSeq	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  PolicyMappingsSyntaxSeq	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  PolicyMappingsSyntaxSeq	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  PolicyMappingsSyntaxSeq	*Append();  // add elmt to end of list
+  PolicyMappingsSyntaxSeq	*Prepend(); // add elmt to beginning of list
+  PolicyMappingsSyntaxSeq	*InsertBefore(); //insert elmt before current elmt
+  PolicyMappingsSyntaxSeq	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  PolicyMappingsSyntax	&AppendCopy (PolicyMappingsSyntaxSeq &elmt);  // add elmt to end of list
+  PolicyMappingsSyntax	&PrependCopy (PolicyMappingsSyntaxSeq &elmt); // add elmt to beginning of list
+  PolicyMappingsSyntax	&InsertBeforeAndCopy (PolicyMappingsSyntaxSeq &elmt); //insert elmt before current elmt
+  PolicyMappingsSyntax	&InsertAfterAndCopy (PolicyMappingsSyntaxSeq &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class SupportedAlgorithm: public AsnType
+{
+public:
+  AlgorithmIdentifier		*algorithmIdentifier;
+  KeyUsage		*intendedUsage;
+  CertificatePoliciesSyntax		*intendedCertificatePolicies;
+
+			SupportedAlgorithm();
+			SupportedAlgorithm (const SupportedAlgorithm &);
+  virtual		~SupportedAlgorithm();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  SupportedAlgorithm		&operator = (const SupportedAlgorithm &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+/* GeneralNames */
+typedef GeneralNames SubjectName;
+
+/* GeneralNames */
+typedef GeneralNames IssuerAltName;
+
+/* AttributesSyntax */
+typedef AttributesSyntax SubjectDirectoryAttributes;
+
+class BasicConstraintsSyntax: public AsnType
+{
+public:
+  AsnBool		*cA;
+  AsnInt		*pathLenConstraint;
+
+			BasicConstraintsSyntax();
+			BasicConstraintsSyntax (const BasicConstraintsSyntax &);
+  virtual		~BasicConstraintsSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  BasicConstraintsSyntax		&operator = (const BasicConstraintsSyntax &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class NameConstraintsSyntax: public AsnType
+{
+public:
+  GeneralSubtrees		*permittedSubtrees;
+  GeneralSubtrees		*excludedSubtrees;
+
+			NameConstraintsSyntax();
+			NameConstraintsSyntax (const NameConstraintsSyntax &);
+  virtual		~NameConstraintsSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  NameConstraintsSyntax		&operator = (const NameConstraintsSyntax &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class PolicyConstraintsSyntax: public AsnType
+{
+public:
+  SkipCerts		*requireExplicitPolicy;
+  SkipCerts		*inhibitPolicyMapping;
+
+			PolicyConstraintsSyntax();
+			PolicyConstraintsSyntax (const PolicyConstraintsSyntax &);
+  virtual		~PolicyConstraintsSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  PolicyConstraintsSyntax		&operator = (const PolicyConstraintsSyntax &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class CertPolicySet: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    CertPolicyId	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			CertPolicySet() { count = 0; first = curr = last = NULL; }
+			CertPolicySet (const CertPolicySet &);
+  virtual		~CertPolicySet();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CertPolicySet		&operator = (const CertPolicySet &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  CertPolicyId	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  CertPolicyId	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  CertPolicyId	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  CertPolicyId	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  CertPolicyId	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  CertPolicyId	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  CertPolicyId	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  CertPolicyId	*Append();  // add elmt to end of list
+  CertPolicyId	*Prepend(); // add elmt to beginning of list
+  CertPolicyId	*InsertBefore(); //insert elmt before current elmt
+  CertPolicyId	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  CertPolicySet	&AppendCopy (CertPolicyId &elmt);  // add elmt to end of list
+  CertPolicySet	&PrependCopy (CertPolicyId &elmt); // add elmt to beginning of list
+  CertPolicySet	&InsertBeforeAndCopy (CertPolicyId &elmt); //insert elmt before current elmt
+  CertPolicySet	&InsertAfterAndCopy (CertPolicyId &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+/* GeneralizedTime */
+typedef GeneralizedTime InvalidityDate;
+
+class CRLDistPointsSyntax: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    DistributionPoint	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			CRLDistPointsSyntax() { count = 0; first = curr = last = NULL; }
+			CRLDistPointsSyntax (const CRLDistPointsSyntax &);
+  virtual		~CRLDistPointsSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  CRLDistPointsSyntax		&operator = (const CRLDistPointsSyntax &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  DistributionPoint	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  DistributionPoint	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  DistributionPoint	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  DistributionPoint	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  DistributionPoint	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  DistributionPoint	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  DistributionPoint	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  DistributionPoint	*Append();  // add elmt to end of list
+  DistributionPoint	*Prepend(); // add elmt to beginning of list
+  DistributionPoint	*InsertBefore(); //insert elmt before current elmt
+  DistributionPoint	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  CRLDistPointsSyntax	&AppendCopy (DistributionPoint &elmt);  // add elmt to end of list
+  CRLDistPointsSyntax	&PrependCopy (DistributionPoint &elmt); // add elmt to beginning of list
+  CRLDistPointsSyntax	&InsertBeforeAndCopy (DistributionPoint &elmt); //insert elmt before current elmt
+  CRLDistPointsSyntax	&InsertAfterAndCopy (DistributionPoint &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+class IssuingDistPointSyntax: public AsnType
+{
+public:
+  DistributionPointName		*distributionPoint;
+  AsnBool		*onlyContainsUserCerts;
+  AsnBool		*onlyContainsCACerts;
+  ReasonFlags		*onlySomeReasons;
+  AsnBool		*indirectCRL;
+
+			IssuingDistPointSyntax();
+			IssuingDistPointSyntax (const IssuingDistPointSyntax &);
+  virtual		~IssuingDistPointSyntax();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  IssuingDistPointSyntax		&operator = (const IssuingDistPointSyntax &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+/* GeneralNames */
+typedef GeneralNames CertificateIssuer;
+
+/* CRLNumber */
+typedef CRLNumber BaseCRLNumber;
+
+/* CertificateList */
+typedef CertificateList DeltaRevocationList;
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define id_at_supportedAlgorithms_arc 2, 5, 4, 52
+#define id_at_supportedAlgorithms     AsnOid(id_at_supportedAlgorithms_arc)
+#define id_at_deltaRevocationList_arc 2, 5, 4, 53
+#define id_at_deltaRevocationList     AsnOid(id_at_deltaRevocationList_arc)
+#define id_ce_subjectDirectoryAttributes_arc 2, 5, 29, 9
+#define id_ce_subjectDirectoryAttributes     AsnOid(id_ce_subjectDirectoryAttributes_arc)
+#define id_ce_subjectKeyIdentifier_arc 2, 5, 29, 14
+#define id_ce_subjectKeyIdentifier     AsnOid(id_ce_subjectKeyIdentifier_arc)
+#define id_ce_keyUsage_arc 2, 5, 29, 15
+#define id_ce_keyUsage     AsnOid(id_ce_keyUsage_arc)
+#define id_ce_privateKeyUsagePeriod_arc 2, 5, 29, 16
+#define id_ce_privateKeyUsagePeriod     AsnOid(id_ce_privateKeyUsagePeriod_arc)
+#define id_ce_subjectAltName_arc 2, 5, 29, 17
+#define id_ce_subjectAltName     AsnOid(id_ce_subjectAltName_arc)
+#define id_ce_issuerAltName_arc 2, 5, 29, 18
+#define id_ce_issuerAltName     AsnOid(id_ce_issuerAltName_arc)
+#define id_ce_basicConstraints_arc 2, 5, 29, 19
+#define id_ce_basicConstraints     AsnOid(id_ce_basicConstraints_arc)
+#define id_ce_cRLNumber_arc 2, 5, 29, 20
+#define id_ce_cRLNumber     AsnOid(id_ce_cRLNumber_arc)
+#define id_ce_reasonCode_arc 2, 5, 29, 21
+#define id_ce_reasonCode     AsnOid(id_ce_reasonCode_arc)
+#define id_ce_instructionCode_arc 2, 5, 29, 23
+#define id_ce_instructionCode     AsnOid(id_ce_instructionCode_arc)
+#define id_ce_invalidityDate_arc 2, 5, 29, 24
+#define id_ce_invalidityDate     AsnOid(id_ce_invalidityDate_arc)
+#define id_ce_deltaCRLIndicator_arc 2, 5, 29, 27
+#define id_ce_deltaCRLIndicator     AsnOid(id_ce_deltaCRLIndicator_arc)
+#define id_ce_issuingDistributionPoint_arc 2, 5, 29, 28
+#define id_ce_issuingDistributionPoint     AsnOid(id_ce_issuingDistributionPoint_arc)
+#define id_ce_certificateIssuer_arc 2, 5, 29, 29
+#define id_ce_certificateIssuer     AsnOid(id_ce_certificateIssuer_arc)
+#define id_ce_nameConstraints_arc 2, 5, 29, 30
+#define id_ce_nameConstraints     AsnOid(id_ce_nameConstraints_arc)
+#define id_ce_cRLDistributionPoints_arc 2, 5, 29, 31
+#define id_ce_cRLDistributionPoints     AsnOid(id_ce_cRLDistributionPoints_arc)
+#define id_ce_certificatePolicies_arc 2, 5, 29, 32
+#define id_ce_certificatePolicies     AsnOid(id_ce_certificatePolicies_arc)
+#define id_ce_policyMappings_arc 2, 5, 29, 33
+#define id_ce_policyMappings     AsnOid(id_ce_policyMappings_arc)
+#define id_ce_authorityKeyIdentifier_arc 2, 5, 29, 35
+#define id_ce_authorityKeyIdentifier     AsnOid(id_ce_authorityKeyIdentifier_arc)
+#define id_ce_policyConstraints_arc 2, 5, 29, 36
+#define id_ce_policyConstraints     AsnOid(id_ce_policyConstraints_arc)
+#define id_ce_extKeyUsage_arc 2, 5, 29, 37
+#define id_ce_extKeyUsage     AsnOid(id_ce_extKeyUsage_arc)
+#define id_mr_certificateExactMatch_arc 2, 5, 13, 34
+#define id_mr_certificateExactMatch     AsnOid(id_mr_certificateExactMatch_arc)
+#define id_mr_certificateMatch_arc 2, 5, 13, 35
+#define id_mr_certificateMatch     AsnOid(id_mr_certificateMatch_arc)
+#define id_mr_certificatePairExactMatch_arc 2, 5, 13, 36
+#define id_mr_certificatePairExactMatch     AsnOid(id_mr_certificatePairExactMatch_arc)
+#define id_mr_certificatePairMatch_arc 2, 5, 13, 37
+#define id_mr_certificatePairMatch     AsnOid(id_mr_certificatePairMatch_arc)
+#define id_mr_certificateListExactMatch_arc 2, 5, 13, 38
+#define id_mr_certificateListExactMatch     AsnOid(id_mr_certificateListExactMatch_arc)
+#define id_mr_certificateListMatch_arc 2, 5, 13, 39
+#define id_mr_certificateListMatch     AsnOid(id_mr_certificateListMatch_arc)
+#define id_mr_algorithmIdentifierMatch_arc 2, 5, 13, 40
+#define id_mr_algorithmIdentifierMatch     AsnOid(id_mr_algorithmIdentifierMatch_arc)
+#define id_kp_arc 1, 3, 6, 1, 5, 5, 7, 3
+#define id_kp     AsnOid(id_kp_arc)
+#define id_kp_serverAuth_arc 1, 3, 6, 1, 5, 5, 7, 3, 1
+#define id_kp_serverAuth     AsnOid(id_kp_serverAuth_arc)
+#define id_kp_clientAuth_arc 1, 3, 6, 1, 5, 5, 7, 3, 2
+#define id_kp_clientAuth     AsnOid(id_kp_clientAuth_arc)
+#define id_kp_codeSigning_arc 1, 3, 6, 1, 5, 5, 7, 3, 3
+#define id_kp_codeSigning     AsnOid(id_kp_codeSigning_arc)
+#define id_kp_emailProtection_arc 1, 3, 6, 1, 5, 5, 7, 3, 4
+#define id_kp_emailProtection     AsnOid(id_kp_emailProtection_arc)
+#define id_kp_timeStamping_arc 1, 3, 6, 1, 5, 5, 7, 3, 8
+#define id_kp_timeStamping     AsnOid(id_kp_timeStamping_arc)
+#define id_netscape_cert_type_arc 2, 16, 840, 1, 113730, 1, 1
+#define id_netscape_cert_type     AsnOid(id_netscape_cert_type_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_x509ce.h */
diff --git a/SecurityASN1/inc/sm_x509cmn.h b/SecurityASN1/inc/sm_x509cmn.h
new file mode 100644
index 00000000..657be718
--- /dev/null
+++ b/SecurityASN1/inc/sm_x509cmn.h
@@ -0,0 +1,171 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x509cmn.h - class definitions for ASN.1 module CommonX509Definitions
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_x509cmn_h_
+#define _sm_x509cmn_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class EDIPartyName;
+class GeneralName;
+class GeneralNames;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+/* OBJECT IDENTIFIER */
+typedef AsnOid OTHER_NAME;
+
+class EDIPartyName: public AsnType
+{
+public:
+  DirectoryString		*nameAssigner;
+  DirectoryString		*partyName;
+
+			EDIPartyName();
+			EDIPartyName (const EDIPartyName &);
+  virtual		~EDIPartyName();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EDIPartyName		&operator = (const EDIPartyName &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+class GeneralName: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     otherNameCid = 0,
+     rfc822NameCid = 1,
+     dNSNameCid = 2,
+     x400AddressCid = 3,
+     directoryNameCid = 4,
+     ediPartyNameCid = 5,
+     uniformResourceIdentifierCid = 6,
+     iPAddressCid = 7,
+     registeredIDCid = 8
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     OTHER_NAME		*otherName;
+     IA5String		*rfc822Name;
+     IA5String		*dNSName;
+     ORAddress		*x400Address;
+     Name		*directoryName;
+     EDIPartyName		*ediPartyName;
+     IA5String		*uniformResourceIdentifier;
+     AsnOcts		*iPAddress;
+     AsnOid		*registeredID;
+  };
+
+
+			GeneralName();
+			GeneralName (const GeneralName &);
+  virtual		~GeneralName();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  GeneralName		&operator = (const GeneralName &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class GeneralNames: public AsnType
+{
+protected:
+  unsigned long int	count;
+  struct AsnListElmt
+  {
+    AsnListElmt	*next;
+    AsnListElmt	*prev;
+    GeneralName	*elmt;
+  }			*first, *curr, *last;
+
+public:
+			GeneralNames() { count = 0; first = curr = last = NULL; }
+			GeneralNames (const GeneralNames &);
+  virtual		~GeneralNames();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  GeneralNames		&operator = (const GeneralNames &);
+  void		SetCurrElmt (unsigned long int index);
+  unsigned long int	GetCurrElmtIndex();
+  void		SetCurrToFirst() { curr = first; }
+  void		SetCurrToLast()  { curr = last; }
+  // reading member fcns
+  int			Count() const	{ return count; }
+  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)
+  GeneralName	*First() const	{ return count > 0 ? first->elmt : NULL; }
+  GeneralName	*Last() const	{ return count > 0 ? last->elmt : NULL; }
+  GeneralName	*Curr() const	{ return curr ? curr->elmt : NULL; }
+  GeneralName	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }
+  GeneralName	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  GeneralName	*GoNext() { if (curr) curr = curr->next; return Curr(); }
+  GeneralName	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  GeneralName	*Append();  // add elmt to end of list
+  GeneralName	*Prepend(); // add elmt to beginning of list
+  GeneralName	*InsertBefore(); //insert elmt before current elmt
+  GeneralName	*InsertAfter(); //insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  GeneralNames	&AppendCopy (GeneralName &elmt);  // add elmt to end of list
+  GeneralNames	&PrependCopy (GeneralName &elmt); // add elmt to beginning of list
+  GeneralNames	&InsertBeforeAndCopy (GeneralName &elmt); //insert elmt before current elmt
+  GeneralNames	&InsertAfterAndCopy (GeneralName &elmt); //insert elmt after current elmt
+
+  // removing the current elmt from the list
+  void		RemoveCurrFromList();
+
+  // encode and decode routines    
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_x509cmn.h */
diff --git a/SecurityASN1/inc/sm_x520sa.h b/SecurityASN1/inc/sm_x520sa.h
new file mode 100644
index 00000000..33de4c75
--- /dev/null
+++ b/SecurityASN1/inc/sm_x520sa.h
@@ -0,0 +1,334 @@
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_x520sa.h - class definitions for ASN.1 module SelectedAttributeTypes
+//
+//   This file was generated by snacc on Wed Jun 27 16:40:55 2001
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_x520sa_h_
+#define _sm_x520sa_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class DirectoryString;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+/* BIT STRING */
+typedef AsnBits UniqueIdentifier;
+
+class DirectoryString: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     teletexStringCid = 0,
+     printableStringCid = 1,
+     universalStringCid = 2,
+     bmpStringCid = 3,
+     utf8StringCid = 4
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     TeletexString		*teletexString;
+     PrintableString		*printableString;
+     UniversalString		*universalString;
+     BMPString		*bmpString;
+     UTF8String		*utf8String;
+  };
+
+
+			DirectoryString();
+			DirectoryString (const DirectoryString &);
+  virtual		~DirectoryString();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  DirectoryString		&operator = (const DirectoryString &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+#define id_at_encryptedAliasedEntryName_arc 2, 5, 4, 1, 2
+#define id_at_encryptedAliasedEntryName     AsnOid(id_at_encryptedAliasedEntryName_arc)
+#define id_at_knowledgeInformation_arc 2, 5, 4, 2
+#define id_at_knowledgeInformation     AsnOid(id_at_knowledgeInformation_arc)
+#define id_at_commonName_arc 2, 5, 4, 3
+#define id_at_commonName     AsnOid(id_at_commonName_arc)
+#define id_at_encryptedCommonName_arc 2, 5, 4, 3, 2
+#define id_at_encryptedCommonName     AsnOid(id_at_encryptedCommonName_arc)
+#define id_at_surname_arc 2, 5, 4, 4
+#define id_at_surname     AsnOid(id_at_surname_arc)
+#define id_at_encryptedSurname_arc 2, 5, 4, 4, 2
+#define id_at_encryptedSurname     AsnOid(id_at_encryptedSurname_arc)
+#define id_at_serialNumber_arc 2, 5, 4, 5
+#define id_at_serialNumber     AsnOid(id_at_serialNumber_arc)
+#define id_at_encryptedSerialNumber_arc 2, 5, 4, 5, 2
+#define id_at_encryptedSerialNumber     AsnOid(id_at_encryptedSerialNumber_arc)
+#define id_at_countryName_arc 2, 5, 4, 6
+#define id_at_countryName     AsnOid(id_at_countryName_arc)
+#define id_at_encryptedCountryName_arc 2, 5, 4, 6, 2
+#define id_at_encryptedCountryName     AsnOid(id_at_encryptedCountryName_arc)
+#define id_at_localityName_arc 2, 5, 4, 7
+#define id_at_localityName     AsnOid(id_at_localityName_arc)
+#define id_at_encryptedLocalityName_arc 2, 5, 4, 7, 2
+#define id_at_encryptedLocalityName     AsnOid(id_at_encryptedLocalityName_arc)
+#define id_at_collectiveLocalityName_arc 2, 5, 4, 7, 1
+#define id_at_collectiveLocalityName     AsnOid(id_at_collectiveLocalityName_arc)
+#define id_at_encryptedCollectiveLocalityName_arc 2, 5, 4, 7, 1, 2
+#define id_at_encryptedCollectiveLocalityName     AsnOid(id_at_encryptedCollectiveLocalityName_arc)
+#define id_at_stateOrProvinceName_arc 2, 5, 4, 8
+#define id_at_stateOrProvinceName     AsnOid(id_at_stateOrProvinceName_arc)
+#define id_at_encryptedStateOrProvinceName_arc 2, 5, 4, 8, 2
+#define id_at_encryptedStateOrProvinceName     AsnOid(id_at_encryptedStateOrProvinceName_arc)
+#define id_at_collectiveStateOrProvinceName_arc 2, 5, 4, 8, 1
+#define id_at_collectiveStateOrProvinceName     AsnOid(id_at_collectiveStateOrProvinceName_arc)
+#define id_at_encryptedCollectiveStateOrProvinceName_arc 2, 5, 4, 8, 1, 2
+#define id_at_encryptedCollectiveStateOrProvinceName     AsnOid(id_at_encryptedCollectiveStateOrProvinceName_arc)
+#define id_at_streetAddress_arc 2, 5, 4, 9
+#define id_at_streetAddress     AsnOid(id_at_streetAddress_arc)
+#define id_at_encryptedStreetAddress_arc 2, 5, 4, 9, 2
+#define id_at_encryptedStreetAddress     AsnOid(id_at_encryptedStreetAddress_arc)
+#define id_at_collectiveStreetAddress_arc 2, 5, 4, 9, 1
+#define id_at_collectiveStreetAddress     AsnOid(id_at_collectiveStreetAddress_arc)
+#define id_at_encryptedCollectiveStreetAddress_arc 2, 5, 4, 9, 1, 2
+#define id_at_encryptedCollectiveStreetAddress     AsnOid(id_at_encryptedCollectiveStreetAddress_arc)
+#define id_at_organizationName_arc 2, 5, 4, 10
+#define id_at_organizationName     AsnOid(id_at_organizationName_arc)
+#define id_at_encryptedOrganizationName_arc 2, 5, 4, 10, 2
+#define id_at_encryptedOrganizationName     AsnOid(id_at_encryptedOrganizationName_arc)
+#define id_at_collectiveOrganizationName_arc 2, 5, 4, 10, 1
+#define id_at_collectiveOrganizationName     AsnOid(id_at_collectiveOrganizationName_arc)
+#define id_at_encryptedCollectiveOrganizationName_arc 2, 5, 4, 10, 1, 2
+#define id_at_encryptedCollectiveOrganizationName     AsnOid(id_at_encryptedCollectiveOrganizationName_arc)
+#define id_at_organizationalUnitName_arc 2, 5, 4, 11
+#define id_at_organizationalUnitName     AsnOid(id_at_organizationalUnitName_arc)
+#define id_at_encryptedOrganizationalUnitName_arc 2, 5, 4, 11, 2
+#define id_at_encryptedOrganizationalUnitName     AsnOid(id_at_encryptedOrganizationalUnitName_arc)
+#define id_at_collectiveOrganizationalUnitName_arc 2, 5, 4, 11, 1
+#define id_at_collectiveOrganizationalUnitName     AsnOid(id_at_collectiveOrganizationalUnitName_arc)
+#define id_at_encryptedCollectiveOrganizationalUnitName_arc 2, 5, 4, 11, 1, 2
+#define id_at_encryptedCollectiveOrganizationalUnitName     AsnOid(id_at_encryptedCollectiveOrganizationalUnitName_arc)
+#define id_at_title_arc 2, 5, 4, 12
+#define id_at_title     AsnOid(id_at_title_arc)
+#define id_at_encryptedTitle_arc 2, 5, 4, 12, 2
+#define id_at_encryptedTitle     AsnOid(id_at_encryptedTitle_arc)
+#define id_at_description_arc 2, 5, 4, 13
+#define id_at_description     AsnOid(id_at_description_arc)
+#define id_at_encryptedDescription_arc 2, 5, 4, 13, 2
+#define id_at_encryptedDescription     AsnOid(id_at_encryptedDescription_arc)
+#define id_at_searchGuide_arc 2, 5, 4, 14
+#define id_at_searchGuide     AsnOid(id_at_searchGuide_arc)
+#define id_at_encryptedSearchGuide_arc 2, 5, 4, 14, 2
+#define id_at_encryptedSearchGuide     AsnOid(id_at_encryptedSearchGuide_arc)
+#define id_at_businessCategory_arc 2, 5, 4, 15
+#define id_at_businessCategory     AsnOid(id_at_businessCategory_arc)
+#define id_at_encryptedBusinessCategory_arc 2, 5, 4, 15, 2
+#define id_at_encryptedBusinessCategory     AsnOid(id_at_encryptedBusinessCategory_arc)
+#define id_at_postalAddress_arc 2, 5, 4, 16
+#define id_at_postalAddress     AsnOid(id_at_postalAddress_arc)
+#define id_at_encryptedPostalAddress_arc 2, 5, 4, 16, 2
+#define id_at_encryptedPostalAddress     AsnOid(id_at_encryptedPostalAddress_arc)
+#define id_at_collectivePostalAddress_arc 2, 5, 4, 16, 1
+#define id_at_collectivePostalAddress     AsnOid(id_at_collectivePostalAddress_arc)
+#define id_at_encryptedCollectivePostalAddress_arc 2, 5, 4, 16, 1, 2
+#define id_at_encryptedCollectivePostalAddress     AsnOid(id_at_encryptedCollectivePostalAddress_arc)
+#define id_at_postalCode_arc 2, 5, 4, 17
+#define id_at_postalCode     AsnOid(id_at_postalCode_arc)
+#define id_at_encryptedPostalCode_arc 2, 5, 4, 17, 2
+#define id_at_encryptedPostalCode     AsnOid(id_at_encryptedPostalCode_arc)
+#define id_at_collectivePostalCode_arc 2, 5, 4, 17, 1
+#define id_at_collectivePostalCode     AsnOid(id_at_collectivePostalCode_arc)
+#define id_at_encryptedCollectivePostalCode_arc 2, 5, 4, 17, 1, 2
+#define id_at_encryptedCollectivePostalCode     AsnOid(id_at_encryptedCollectivePostalCode_arc)
+#define id_at_postOfficeBox_arc 2, 5, 4, 18
+#define id_at_postOfficeBox     AsnOid(id_at_postOfficeBox_arc)
+#define id_at_encryptedPostOfficeBox_arc 2, 5, 4, 18, 2
+#define id_at_encryptedPostOfficeBox     AsnOid(id_at_encryptedPostOfficeBox_arc)
+#define id_at_collectivePostOfficeBox_arc 2, 5, 4, 18, 1
+#define id_at_collectivePostOfficeBox     AsnOid(id_at_collectivePostOfficeBox_arc)
+#define id_at_encryptedCollectivePostOfficeBox_arc 2, 5, 4, 18, 1, 2
+#define id_at_encryptedCollectivePostOfficeBox     AsnOid(id_at_encryptedCollectivePostOfficeBox_arc)
+#define id_at_physicalDeliveryOfficeName_arc 2, 5, 4, 19
+#define id_at_physicalDeliveryOfficeName     AsnOid(id_at_physicalDeliveryOfficeName_arc)
+#define id_at_encryptedPhysicalDeliveryOfficeName_arc 2, 5, 4, 19, 2
+#define id_at_encryptedPhysicalDeliveryOfficeName     AsnOid(id_at_encryptedPhysicalDeliveryOfficeName_arc)
+#define id_at_collectivePhysicalDeliveryOfficeName_arc 2, 5, 4, 19, 1
+#define id_at_collectivePhysicalDeliveryOfficeName     AsnOid(id_at_collectivePhysicalDeliveryOfficeName_arc)
+#define id_at_encryptedCollectivePhysicalDeliveryOfficeName_arc 2, 5, 4, 19, 1, 2
+#define id_at_encryptedCollectivePhysicalDeliveryOfficeName     AsnOid(id_at_encryptedCollectivePhysicalDeliveryOfficeName_arc)
+#define id_at_telephoneNumber_arc 2, 5, 4, 20
+#define id_at_telephoneNumber     AsnOid(id_at_telephoneNumber_arc)
+#define id_at_encryptedTelephoneNumber_arc 2, 5, 4, 20, 2
+#define id_at_encryptedTelephoneNumber     AsnOid(id_at_encryptedTelephoneNumber_arc)
+#define id_at_collectiveTelephoneNumber_arc 2, 5, 4, 20, 1
+#define id_at_collectiveTelephoneNumber     AsnOid(id_at_collectiveTelephoneNumber_arc)
+#define id_at_encryptedCollectiveTelephoneNumber_arc 2, 5, 4, 20, 1, 2
+#define id_at_encryptedCollectiveTelephoneNumber     AsnOid(id_at_encryptedCollectiveTelephoneNumber_arc)
+#define id_at_telexNumber_arc 2, 5, 4, 21
+#define id_at_telexNumber     AsnOid(id_at_telexNumber_arc)
+#define id_at_encryptedTelexNumber_arc 2, 5, 4, 21, 2
+#define id_at_encryptedTelexNumber     AsnOid(id_at_encryptedTelexNumber_arc)
+#define id_at_collectiveTelexNumber_arc 2, 5, 4, 21, 1
+#define id_at_collectiveTelexNumber     AsnOid(id_at_collectiveTelexNumber_arc)
+#define id_at_encryptedCollectiveTelexNumber_arc 2, 5, 4, 21, 1, 2
+#define id_at_encryptedCollectiveTelexNumber     AsnOid(id_at_encryptedCollectiveTelexNumber_arc)
+#define id_at_teletexTerminalIdentifier_arc 2, 5, 4, 22
+#define id_at_teletexTerminalIdentifier     AsnOid(id_at_teletexTerminalIdentifier_arc)
+#define id_at_encryptedTeletexTerminalIdentifier_arc 2, 5, 4, 22, 2
+#define id_at_encryptedTeletexTerminalIdentifier     AsnOid(id_at_encryptedTeletexTerminalIdentifier_arc)
+#define id_at_collectiveTeletexTerminalIdentifier_arc 2, 5, 4, 22, 1
+#define id_at_collectiveTeletexTerminalIdentifier     AsnOid(id_at_collectiveTeletexTerminalIdentifier_arc)
+#define id_at_encryptedCollectiveTeletexTerminalIdentifier_arc 2, 5, 4, 22, 1, 2
+#define id_at_encryptedCollectiveTeletexTerminalIdentifier     AsnOid(id_at_encryptedCollectiveTeletexTerminalIdentifier_arc)
+#define id_at_facsimileTelephoneNumber_arc 2, 5, 4, 23
+#define id_at_facsimileTelephoneNumber     AsnOid(id_at_facsimileTelephoneNumber_arc)
+#define id_at_encryptedFacsimileTelephoneNumber_arc 2, 5, 4, 23, 2
+#define id_at_encryptedFacsimileTelephoneNumber     AsnOid(id_at_encryptedFacsimileTelephoneNumber_arc)
+#define id_at_collectiveFacsimileTelephoneNumber_arc 2, 5, 4, 23, 1
+#define id_at_collectiveFacsimileTelephoneNumber     AsnOid(id_at_collectiveFacsimileTelephoneNumber_arc)
+#define id_at_encryptedCollectiveFacsimileTelephoneNumber_arc 2, 5, 4, 23, 1, 2
+#define id_at_encryptedCollectiveFacsimileTelephoneNumber     AsnOid(id_at_encryptedCollectiveFacsimileTelephoneNumber_arc)
+#define id_at_x121Address_arc 2, 5, 4, 24
+#define id_at_x121Address     AsnOid(id_at_x121Address_arc)
+#define id_at_encryptedX121Address_arc 2, 5, 4, 24, 2
+#define id_at_encryptedX121Address     AsnOid(id_at_encryptedX121Address_arc)
+#define id_at_internationalISDNNumber_arc 2, 5, 4, 25
+#define id_at_internationalISDNNumber     AsnOid(id_at_internationalISDNNumber_arc)
+#define id_at_encryptedInternationalISDNNumber_arc 2, 5, 4, 25, 2
+#define id_at_encryptedInternationalISDNNumber     AsnOid(id_at_encryptedInternationalISDNNumber_arc)
+#define id_at_collectiveInternationalISDNNumber_arc 2, 5, 4, 25, 1
+#define id_at_collectiveInternationalISDNNumber     AsnOid(id_at_collectiveInternationalISDNNumber_arc)
+#define id_at_encryptedCollectiveInternationalISDNNumber_arc 2, 5, 4, 25, 1, 2
+#define id_at_encryptedCollectiveInternationalISDNNumber     AsnOid(id_at_encryptedCollectiveInternationalISDNNumber_arc)
+#define id_at_registeredAddress_arc 2, 5, 4, 26
+#define id_at_registeredAddress     AsnOid(id_at_registeredAddress_arc)
+#define id_at_encryptedRegisteredAddress_arc 2, 5, 4, 26, 2
+#define id_at_encryptedRegisteredAddress     AsnOid(id_at_encryptedRegisteredAddress_arc)
+#define id_at_destinationIndicator_arc 2, 5, 4, 27
+#define id_at_destinationIndicator     AsnOid(id_at_destinationIndicator_arc)
+#define id_at_encryptedDestinationIndicator_arc 2, 5, 4, 27, 2
+#define id_at_encryptedDestinationIndicator     AsnOid(id_at_encryptedDestinationIndicator_arc)
+#define id_at_preferredDeliveryMethod_arc 2, 5, 4, 28
+#define id_at_preferredDeliveryMethod     AsnOid(id_at_preferredDeliveryMethod_arc)
+#define id_at_encryptedPreferredDeliveryMethod_arc 2, 5, 4, 28, 2
+#define id_at_encryptedPreferredDeliveryMethod     AsnOid(id_at_encryptedPreferredDeliveryMethod_arc)
+#define id_at_presentationAddress_arc 2, 5, 4, 29
+#define id_at_presentationAddress     AsnOid(id_at_presentationAddress_arc)
+#define id_at_encryptedPresentationAddress_arc 2, 5, 4, 29, 2
+#define id_at_encryptedPresentationAddress     AsnOid(id_at_encryptedPresentationAddress_arc)
+#define id_at_supportedApplicationContext_arc 2, 5, 4, 30
+#define id_at_supportedApplicationContext     AsnOid(id_at_supportedApplicationContext_arc)
+#define id_at_encryptedSupportedApplicationContext_arc 2, 5, 4, 30, 2
+#define id_at_encryptedSupportedApplicationContext     AsnOid(id_at_encryptedSupportedApplicationContext_arc)
+#define id_at_member_arc 2, 5, 4, 31
+#define id_at_member     AsnOid(id_at_member_arc)
+#define id_at_encryptedMember_arc 2, 5, 4, 31, 2
+#define id_at_encryptedMember     AsnOid(id_at_encryptedMember_arc)
+#define id_at_owner_arc 2, 5, 4, 32
+#define id_at_owner     AsnOid(id_at_owner_arc)
+#define id_at_encryptedOwner_arc 2, 5, 4, 32, 2
+#define id_at_encryptedOwner     AsnOid(id_at_encryptedOwner_arc)
+#define id_at_roleOccupant_arc 2, 5, 4, 33
+#define id_at_roleOccupant     AsnOid(id_at_roleOccupant_arc)
+#define id_at_encryptedRoleOccupant_arc 2, 5, 4, 33, 2
+#define id_at_encryptedRoleOccupant     AsnOid(id_at_encryptedRoleOccupant_arc)
+#define id_at_seeAlso_arc 2, 5, 4, 34
+#define id_at_seeAlso     AsnOid(id_at_seeAlso_arc)
+#define id_at_encryptedSeeAlso_arc 2, 5, 4, 34, 2
+#define id_at_encryptedSeeAlso     AsnOid(id_at_encryptedSeeAlso_arc)
+#define id_at_encryptedUserPassword_arc 2, 5, 4, 35, 2
+#define id_at_encryptedUserPassword     AsnOid(id_at_encryptedUserPassword_arc)
+#define id_at_encryptedUserCertificate_arc 2, 5, 4, 36, 2
+#define id_at_encryptedUserCertificate     AsnOid(id_at_encryptedUserCertificate_arc)
+#define id_at_encryptedCACertificate_arc 2, 5, 4, 37, 2
+#define id_at_encryptedCACertificate     AsnOid(id_at_encryptedCACertificate_arc)
+#define id_at_encryptedAuthorityRevocationList_arc 2, 5, 4, 38, 2
+#define id_at_encryptedAuthorityRevocationList     AsnOid(id_at_encryptedAuthorityRevocationList_arc)
+#define id_at_encryptedCertificateRevocationList_arc 2, 5, 4, 39, 2
+#define id_at_encryptedCertificateRevocationList     AsnOid(id_at_encryptedCertificateRevocationList_arc)
+#define id_at_encryptedCrossCertificatePair_arc 2, 5, 4, 40, 2
+#define id_at_encryptedCrossCertificatePair     AsnOid(id_at_encryptedCrossCertificatePair_arc)
+#define id_at_name_arc 2, 5, 4, 41
+#define id_at_name     AsnOid(id_at_name_arc)
+#define id_at_givenName_arc 2, 5, 4, 42
+#define id_at_givenName     AsnOid(id_at_givenName_arc)
+#define id_at_encryptedGivenName_arc 2, 5, 4, 42, 2
+#define id_at_encryptedGivenName     AsnOid(id_at_encryptedGivenName_arc)
+#define id_at_initials_arc 2, 5, 4, 43
+#define id_at_initials     AsnOid(id_at_initials_arc)
+#define id_at_encryptedInitials_arc 2, 5, 4, 43, 2
+#define id_at_encryptedInitials     AsnOid(id_at_encryptedInitials_arc)
+#define id_at_generationQualifier_arc 2, 5, 4, 44
+#define id_at_generationQualifier     AsnOid(id_at_generationQualifier_arc)
+#define id_at_encryptedGenerationQualifier_arc 2, 5, 4, 44, 2
+#define id_at_encryptedGenerationQualifier     AsnOid(id_at_encryptedGenerationQualifier_arc)
+#define id_at_uniqueIdentifier_arc 2, 5, 4, 45
+#define id_at_uniqueIdentifier     AsnOid(id_at_uniqueIdentifier_arc)
+#define id_at_encryptedUniqueIdentifier_arc 2, 5, 4, 45, 2
+#define id_at_encryptedUniqueIdentifier     AsnOid(id_at_encryptedUniqueIdentifier_arc)
+#define id_at_dnQualifier_arc 2, 5, 4, 46
+#define id_at_dnQualifier     AsnOid(id_at_dnQualifier_arc)
+#define id_at_encryptedDnQualifier_arc 2, 5, 4, 46, 2
+#define id_at_encryptedDnQualifier     AsnOid(id_at_encryptedDnQualifier_arc)
+#define id_at_enhancedSearchGuide_arc 2, 5, 4, 47
+#define id_at_enhancedSearchGuide     AsnOid(id_at_enhancedSearchGuide_arc)
+#define id_at_encryptedEnhancedSearchGuide_arc 2, 5, 4, 47, 2
+#define id_at_encryptedEnhancedSearchGuide     AsnOid(id_at_encryptedEnhancedSearchGuide_arc)
+#define id_at_protocolInformation_arc 2, 5, 4, 48
+#define id_at_protocolInformation     AsnOid(id_at_protocolInformation_arc)
+#define id_at_encryptedProtocolInformation_arc 2, 5, 4, 48, 2
+#define id_at_encryptedProtocolInformation     AsnOid(id_at_encryptedProtocolInformation_arc)
+#define id_at_distinguishedName_arc 2, 5, 4, 49
+#define id_at_distinguishedName     AsnOid(id_at_distinguishedName_arc)
+#define id_at_encryptedDistinguishedName_arc 2, 5, 4, 49, 2
+#define id_at_encryptedDistinguishedName     AsnOid(id_at_encryptedDistinguishedName_arc)
+#define id_at_uniqueMember_arc 2, 5, 4, 50
+#define id_at_uniqueMember     AsnOid(id_at_uniqueMember_arc)
+#define id_at_encryptedUniqueMember_arc 2, 5, 4, 50, 2
+#define id_at_encryptedUniqueMember     AsnOid(id_at_encryptedUniqueMember_arc)
+#define id_at_houseIdentifier_arc 2, 5, 4, 51
+#define id_at_houseIdentifier     AsnOid(id_at_houseIdentifier_arc)
+#define id_at_encryptedHouseIdentifier_arc 2, 5, 4, 51, 2
+#define id_at_encryptedHouseIdentifier     AsnOid(id_at_encryptedHouseIdentifier_arc)
+#define id_at_encryptedSupportedAlgorithms_arc 2, 5, 4, 52, 2
+#define id_at_encryptedSupportedAlgorithms     AsnOid(id_at_encryptedSupportedAlgorithms_arc)
+#define id_at_encryptedDeltaRevocationList_arc 2, 5, 4, 53, 2
+#define id_at_encryptedDeltaRevocationList     AsnOid(id_at_encryptedDeltaRevocationList_arc)
+#define id_at_dmdName_arc 2, 5, 4, 54
+#define id_at_dmdName     AsnOid(id_at_dmdName_arc)
+#define id_at_encryptedDmdName_arc 2, 5, 4, 54, 2
+#define id_at_encryptedDmdName     AsnOid(id_at_encryptedDmdName_arc)
+#define id_at_encryptedClearance_arc 2, 5, 4, 55, 2
+#define id_at_encryptedClearance     AsnOid(id_at_encryptedClearance_arc)
+#define id_at_encryptedDefaultDirQop_arc 2, 5, 4, 56, 2
+#define id_at_encryptedDefaultDirQop     AsnOid(id_at_encryptedDefaultDirQop_arc)
+#define id_at_encryptedAttributeIntegrityInfo_arc 2, 5, 4, 57, 2
+#define id_at_encryptedAttributeIntegrityInfo     AsnOid(id_at_encryptedAttributeIntegrityInfo_arc)
+#define id_at_encryptedAttributeCertificate_arc 2, 5, 4, 58, 2
+#define id_at_encryptedAttributeCertificate     AsnOid(id_at_encryptedAttributeCertificate_arc)
+#define id_at_encryptedAttributeCertificateRevocationList_arc 2, 5, 4, 59, 2
+#define id_at_encryptedAttributeCertificateRevocationList     AsnOid(id_at_encryptedAttributeCertificateRevocationList_arc)
+#define id_at_encryptedConfKeyInfo_arc 2, 5, 4, 60, 2
+#define id_at_encryptedConfKeyInfo     AsnOid(id_at_encryptedConfKeyInfo_arc)
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_x520sa.h */
diff --git a/SecuritySNACCRuntime/.cvsignore b/SecuritySNACCRuntime/.cvsignore
new file mode 100644
index 00000000..b083d03e
--- /dev/null
+++ b/SecuritySNACCRuntime/.cvsignore
@@ -0,0 +1 @@
+tcl-p
diff --git a/SecuritySNACCRuntime/Apple_README b/SecuritySNACCRuntime/Apple_README
new file mode 100644
index 00000000..9026bdd3
--- /dev/null
+++ b/SecuritySNACCRuntime/Apple_README
@@ -0,0 +1,44 @@
+                 MacOS X Porting notes
+				   20 June 2001 dmitch
+				   
+-- snacc.pbproj contains the following targets:
+
+	world: aggregate target, builds UnixBuild and snaccRuntime
+	
+	UnixBuild: Legacy target, invokes MacOSX-Install, a custom
+		script to config and build the snacc compiler and the 
+		Unix versions of the various libraries. This does not install
+		the snacc binary; maybe it should. 
+	  
+		Due to many brain dead Makefiles, this target always rebuilds
+		a ton of stuff even if nothing has changed. Feel free to rewrite
+		all the Makefiles to fix this.
+	  
+   snaccRuntime: builds the runtime support library as an OSX
+      framework using the same source as c++-lib. Currently 
+	  obsolete; this is now part of Security.framework. 
+	  
+-- There are a few header files which have duplicate copies
+   in the snacc-1.3vda root directory and in c++-lib/inc. They're
+   needed in the root by the compiler build and various configure
+   operations, and neneded in c++lib for the framework built
+   there (snaccRuntime.framework). The headers are needed by
+   other headers installed in that framework. A non-trivial 
+   amount of Makefile and configure.in hacking could eliminate
+   the need for maintaining duplicate copies of these files.
+   Be my guest.  One header, config.h, is generated at configure
+   time and is subsequently copied into the c++-lib/inc directory
+   by the MacOSX-Install script. The other headers are policy.h 
+   and snacc.h, which change rarely. 
+   
+-- The following examples are skipped during the build all.
+
+    c++-examples.simple - runtime failure
+	c-examples/snmp - runtime failure
+	tbl-example - runtime failure
+	tcl-example - build failure
+	
+-- When running the snacc compiler to generate C++ source, you 
+   must specify the (undocumented) -D argument to enable VDADER_RULES. 
+   When compiling that source, you must do a -DVDADER_RULES. 
+   
\ No newline at end of file
diff --git a/SecuritySNACCRuntime/COPYING b/SecuritySNACCRuntime/COPYING
new file mode 100644
index 00000000..a43ea212
--- /dev/null
+++ b/SecuritySNACCRuntime/COPYING
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/SecuritySNACCRuntime/CVSVersionInfo.txt b/SecuritySNACCRuntime/CVSVersionInfo.txt
new file mode 100644
index 00000000..01a08450
--- /dev/null
+++ b/SecuritySNACCRuntime/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Name: Security-28 $
+ProjectName: SecuritySNACCRuntime
+ProjectVersion: 6.1
diff --git a/SecuritySNACCRuntime/ChangeLog b/SecuritySNACCRuntime/ChangeLog
new file mode 100644
index 00000000..39db4b7a
--- /dev/null
+++ b/SecuritySNACCRuntime/ChangeLog
@@ -0,0 +1,761 @@
+Fri Oct 10 13:43:18 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* tcl-asn/makefile, tcl-asn/asnwish.c, tcl-asn/beredit, compiler/core/val-parser.c, tcl-asn/README, c-lib/src/tbl-gen.c, compiler/core/define.c, c++-examples/simple/good-pr.ber, c-examples/simple/good-pr.ber, version.h, README:
+	Corrected bug in generic table decoder wrt. indefinite length elements
+	Corrected compiler access to freed memory (bug reported by Markku Savela)
+	Broke asnwish.c into two pieces so that one can build ones on wish
+	Added beredit tool (based on asnwish, allowes to edit BER messages)
+
+Tue Sep 16 15:05:10 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* tbl-tools/berdecode/berdecode.c: Changed default value of strip to 0.
+
+	* entry.html: Documented current situation
+
+Tue Sep 16 14:57:59 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* README: Proper description of last-minute changes
+
+	* asn1specs/p-rec.asn1, tbl-example/p-rec.ber:
+	Added test for "tag dividable by 128" case.
+
+	* c-lib/src/tbl-enc.c, c-lib/src/tbl-gen.c:
+	Fixed "tag dividable by 128" case.
+	Fixed problem of peeking beyond tag size.
+
+Fri Sep  5 07:15:06 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* tcl-asn/asnwish.c: Picky compiler mods
+
+Thu Sep  4 13:54:10 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* tbl-tools/berdecode/berdecode.c, c++-lib/src/asn-list.C, configure.in:
+	A little more portability
+
+Wed Sep  3 12:50:33 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* compiler/makefile: Shifted parse and lex
+
+	* tcl-asn/makefile, tcl-asn/asnwish.c:
+	Reworked asnwish to neither strip nor encapsulate; instead,
+	buffer reads during decoding incrementally Tcl_Read the channel.
+
+	* c-lib/src/tbl-enc.c, c-lib/src/asn-tag.c:
+	Patch to tag decoding for tags > 2^14 (thanks to Enrico Badella)
+	Patch to TblEncTag to emit final 0x00 if previous octet signals continuation
+
+	* c++-lib/src/asn-tag.C:
+	Patch to tag decoding for tags > 2^14 (thanks to Enrico Badella)
+
+Mon Sep  1 14:21:03 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* compiler/core/err-chk.c: Improved error output in certain cases.
+
+Thu Aug 28 09:48:08 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* README, entry.html, ChangeLog: Added description of changes
+
+	* compiler/core/lex-asn1.l, compiler/core/parse-asn1.y:
+	Reworked number range checking, only gives warning now.
+
+Wed Aug 27 15:56:09 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* tcl-asn/README, tcl-asn/asnwish.c, tcl-asn/makefile, tbl-tools/berdecode/berdecode.c, tbl-tools/berdecode/makefile, tbl-tools/berdecode/README, tbl-tools/makefile, c-lib/src/tbl-dbg.c, c-lib/src/tbl-gen.c, c-lib/inc/tbl-dbg.h, c-lib/inc/tbl-gen.h, c-lib/makefile:
+	Added generic table decoding, debug routines, berdecode, and asnwish.
+
+	* c++-lib/src/asn-bits.C:
+	GetBit now returns 0 or 1, not 0 or <#bit>, even if bool type is emulated.
+
+	* version.h, makefile:
+	Added generic table decoding, debug routines, berdecode, and asnwish.
+
+Thu Jun 19 09:32:22 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* README: Added 1.3b3 change description
+
+	* doc/makefile: Disabled making new doc due to new version string.
+
+	* compiler/boot/tbl.h, compiler/boot/tbl.c, c-lib/boot/tbl.h, c-lib/boot/tbl.c:
+	Remade by make tar
+
+	* version.h: Fixed release date.
+
+	* tbl-tools/ptbl/pasn1.c, compiler/core/lex-asn1.l, compiler/core/parse-asn1.y, compiler/boot/tbl.c, compiler/boot/tbl.h, compiler/core/gen-tbls.c, c-lib/boot/tbl.h, c-lib/src/tbl-util.c, c-lib/boot/tbl.c, asn1specs/tbl.asn1, version.h:
+	Added isPdu flag to tables. Added value range checks during parsing.
+
+Wed May  7 15:20:57 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* README, tbl-tools/ptbl/pasn1.c, compiler/core/gen-tbls.h, compiler/core/snacc.c, c-lib/inc/tbl-incl.h, compiler/core/gen-tbls.c, asn1specs/tbl.asn1, version.h:
+	Added (limited) size constraints, bitstring and enumeration names to tables
+
+	* compiler/back-ends/c-gen/gen-vals.c:
+	Fixed bug in C value string generation.
+
+Mon Apr  7 13:14:16 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* README: Final README for 1.3b1
+
+	* snacc.h: Made more C++ readable (credits to Steve Walker)
+
+Thu Mar 20 15:50:25 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* version.h, README: Push to 1.3b1.
+
+Thu Mar 13 14:48:28 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* compiler/core/parse-asn1.y:
+	Parsed SEQUENCE SIZE(..) OF as SET, corrected.
+
+	* compiler/boot/tbl.h, compiler/boot/tbl.c, compiler/back-ends/idl-gen/gen-code.c, c-lib/src/print.c, c-lib/src/asn-tag.c, c-lib/inc/asn-config.h, c-lib/boot/tbl.h, c-lib/boot/tbl.c, c-lib/boot/asn-useful.h, c-lib/boot/asn-useful.c, c-lib/makefile, c++-lib/makefile, version.h:
+	Improved dependency generation for stupid makedepends.
+	Corrected PeekTag to peek into buffer only as far as necessary.
+	Added installable error handler.
+	Fixed small glitch in idl-code generator (Markku Savela <msa@msa.tte.vtt.fi>).
+
+Mon Mar  3 11:58:34 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* compiler/core/parse-asn1.y, compiler/boot/tbl.c, compiler/boot/tbl.h, compiler/makefile, c-lib/boot/tbl.c, c-lib/boot/tbl.h, c-lib/boot/asn-useful.c, c-lib/boot/asn-useful.h, c++-examples/test-lib/makefile, acconfig.h, makefile, ChangeLog:
+	Final pre-delivery stuff (I hope).
+
+Fri Feb 28 13:43:53 1997  Sebastian Wangnick  <sebastian.wangnick@eurocontrol.be>
+
+	* version.h: New version #.
+
+	* .cvsignore: Added config.cache
+
+	* tcl-lib/snacced.tcl, tcl-example/edex1.asn1, tcl-lib/selbox.tcl, compiler/core/parse-asn1.y, compiler/core/print.c, compiler/back-ends/c-gen/gen-dec.c, compiler/back-ends/c++-gen/gen-code.c, c-lib/src/tbl-util.c, compiler/makefile, c-lib/src/hash.c, c-lib/src/nibble-alloc.c, c-lib/src/tbl-free.c, c-lib/src/asn-real.c, c-lib/src/asn-tag.c, c-lib/inc/asn-any.h, c-lib/inc/hash.h, c-lib/src/asn-any.c, c++-lib/src/tkAppInit.c, c-lib/tbl.h.patch, c++-lib/src/meta.C, c++-lib/src/tcl-if.C, c++-lib/src/asn-oid.C, c++-lib/src/asn-real.C, c++-lib/src/hash.C, c++-lib/src/asn-int.C, c++-lib/src/asn-octs.C, c++-lib/src/asn-bits.C, c++-lib/src/asn-bool.C, c++-lib/src/asn-enum.C, c++-lib/inc/meta.h, c++-lib/src/asn-any.C, c++-examples/test-lib/test-lib.C, c++-lib/inc/hash.h, c++-examples/test-lib/makefile, configure.in, snacc.h, acconfig.h:
+	Modifications collected for new version 1.3: Bug fixes, tk4.2.
+
+Sun Feb 16 22:26:40 1997  rj  <rj@masoms2.mas.hide>
+
+	* README: url corrected
+
+	* c-examples/test-lib/README, c-examples/any/example.c, c-examples/any/README, c++-lib/src/str-stk.C, c++-lib/src/print.C, c++-lib/src/hash.C, c++-lib/src/asn-tag.C, c++-lib/src/asn-len.C, c++-lib/src/asn-bool.C, c++-lib/src/asn-any.C, c++-lib/inc/str-stk.h, c++-lib/inc/print.h, c++-lib/inc/hash.h, c++-lib/inc/asn-type.h, c++-lib/inc/asn-tag.h, c++-lib/inc/asn-real.h, c++-lib/inc/asn-octs.h, c++-lib/inc/asn-list.h, c++-lib/inc/asn-incl.h, c++-lib/inc/asn-buf.h, c++-lib/inc/asn-bits.h, c++-examples/test-lib/README, c++-examples/any/README, asn1specs/ex1.asn1, asn1specs/any.asn1:
+	check-in of a few cosmetic changes
+
+	* README, ChangeLog, version.h: final release of snacc 1.2rj
+
+	* makefile: remove tcl-p when making clobber
+
+	* INITIAL: first check-in
+
+	* tcl-example/.cvsignore: ignore yet two more generated files
+
+	* doc/makefile: typo fixed
+
+	* c++-examples/any/.cvsignore, c-examples/any/.cvsignore:
+	ignore more generated files and directories
+
+	* c++-examples/simple/.cvsignore, c-examples/simple/.cvsignore:
+	ignore generated directories
+
+	* c-examples/test-lib/.cvsignore: ignore yet another generated file
+
+	* tbl-example/.cvsignore: ignore two more generated files
+
+	* tbl-tools/pval/.cvsignore, tbl-tools/ptbl/.cvsignore, tbl-tools/mkchdr/.cvsignore:
+	ignore yet another generated file
+
+	* makefile: correct path to configure script
+
+	* compiler/makefile: snacc is needed to generate the distfiles
+
+	* tcl-example/.cvsignore: ignore more generated files
+
+	* tbl-tools/mkchdr/.cvsignore: ignore yet another generated file
+
+	* tbl-example/.cvsignore, doc/.cvsignore:
+	ignore yet two more generated files
+
+	* doc/.cvsignore: ignore yet another generated file
+
+	* tcl-example/.cvsignore, tbl-tools/pval/.cvsignore, tbl-tools/ptbl/.cvsignore, tbl-tools/mkchdr/.cvsignore, tbl-example/.cvsignore, c-examples/test-lib/.cvsignore:
+	ignore the dependencies file
+
+	* c-examples/snmp/.cvsignore, c-examples/simple/.cvsignore, c-examples/any/.cvsignore, c++-examples/test-lib/.cvsignore, c++-examples/snmp/.cvsignore, c++-examples/simple/.cvsignore, c++-examples/any/.cvsignore:
+	ignore yet another file
+
+	* c++-lib/.cvsignore: ignore generated directories
+
+	* c++-lib/.cvsignore, compiler/.cvsignore:
+	ignore yet another generated file
+
+	* c-lib/.cvsignore: ignore more generated files and directories
+
+	* doc/thisnextafter.tex, doc/misc-defs.tex, doc/list-popup.eps, doc/str-popup.eps, doc/struct.eps, doc/simple.eps, doc/selbox.eps, doc/recur.eps, doc/example.eps, c-lib/tbl.h.patch:
+	first check-in
+
+	* makefile: generate tcl-p before it is needed...
+
+	* configure.in, doc/intro-1.2.tex, c++-lib/makefile, c++-examples/snmp/makefile, c++-examples/simple/makefile, c++-examples/any/makefile:
+	made return *this after calling abort()'' a compile time option.
+
+	* maketail: rule to generate $(TCL-P) added
+
+	* makehead.in, doc/snacc.1, compiler/back-ends/c++-gen/gen-code.h, compiler/back-ends/c++-gen/gen-code.c:
+	made return *this after calling abort()'' a compile time option.
+
+	* compiler/core/snacc.c:
+	made ``return *this after calling abort()'' a compile time option.
+
+	* c++-lib/inc/asn-oid.h: construct in the order the members are defined
+
+	* tcl-example/makefile: remove more generated files
+
+	* compiler/back-ends/c++-gen/gen-code.c:
+	use the TIME_WITH_SYS_TIME flag (checked and generated by configure).
+	return *this after calling abort() for compilers that don't know about this volatile function.
+	comment out unused parameters, the compiler otherwise may complain.
+
+	* compiler/makefile:
+	let make clobber remove the link to install-sh that make made
+	let make clean remove more created files
+
+	* c-lib/makefile:
+	let make clobber remove the link to install-sh that make made
+
+	* c++-lib/src/asn-oid.C: name lookup of \for' scoping
+
+	* c++-lib/inc/asn-null.h: comment out an unused argument
+
+	* c++-lib/inc/asn-len.h: make the unsigned value unsigned :-)
+
+Sun Feb 16 05:22:42 1997  Robert Joop  <rj@rainbow.in-berlin.de>
+
+	* ***** this is the end, my last words on my final snacc release, 1.2rj.10. *****
+
+	* lots of files and directories added to the various .cvsignore files.
+
+	* added a file INITIAL to explain the first steps necessary after
+	an initial cvs checkout.
+
+	* made ``return *this after calling abort()'' a compile time
+ 	option.
+
+	* compiler/back-ends/c++-gen/gen-code.c: comment out unused
+	parameters, the compiler otherwise may complain.
+
+	* compiler/back-ends/c++-gen/gen-code.c: return *this after
+	calling abort() for compilers that don't know about this volatile
+	function.
+
+	* compiler/back-ends/c++-gen/gen-code.c: use the
+ 	TIME_WITH_SYS_TIME flag (checked and generated by configure)
+
+	* changes for new ANSI `for' scoping
+
+Sat Feb 15 19:09:43 1997  Robert Joop  <rj@rainbow.in-berlin.de>
+
+	* configure.in and acconfig.h: check whether the compiler supports
+ 	volatile functions (and whether abort() is volatile). In member
+ 	functions, return *this after calling abort() for those stupid
+ 	compilers (they would otherwise abort with an error).
+
+	* tbl-tools/ and tbl-example/ directoies added.
+
+	* compiler/core/snacc.c: do not silently ignore the -tcl option if
+ 	not compiled for tcl code generation
+
+	* compiler/core/snacc.c: use the TIME_WITH_SYS_TIME flag (checked
+ 	and generated by configure)
+
+	* c++-lib/src/asn-list.C: names of Tcl*-functions fixed (obviously
+ 	they weren't needed :-)
+
+	* c++-lib/inc/tcl-if.h, c++-lib/src/tcl-if.C: `typename' appears
+ 	to be a reserved word in gcc 2.7, so prefix it with `_'
+
+	* c++-lib/src/asn-bits.C: dereferencing pointer to member function
+ 	is neither necessary nor allowed
+
+	* c++-lib/src/asn-type.C: "virtual" removed from functions. (fix
+ 	due to changed C++ language.)
+
+Thu Sep  7 20:21:39 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* deep copying code added to C++ backend generated assignment
+	operators.
+
+	* c-lib/makefile and c++-lib/makefile: asn-useful.asn1 is compiled
+	with the -l 50 option, as recommended by MS in the documentation.
+
+	* compiler/back-ends/c++-gen/kwd.c: bool, true and false are
+	reserved words in new C++ (supported by gcc since version 2.6).
+
+	* new options -mA and -mC for snacc(1) that switch the names used
+	between those defined in the ASN.1 files and those used in the
+	generated C++ code. enum type MetaNameStyle introduced.
+
+	* c++-lib/src/tcl-if.C: duplicate code merged into a new function
+	SnaccTcl::gettypedesc().
+
+	* c++-lib/*: long int replaced by AsnIntType at a lot of
+	places. It shall provide a 32 bit integer type on all platforms.
+	new type introduced: AsnUIntType (32 bit unsigned integer type).
+
+Thu Aug 17 17:01:59 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* c++-lib/*/asn-real.[hC]: recognize and return "±inf" for
+	PLUS-INFINITY/MINUS-INFINITY
+
+	* c++-lib/*/asn-enum.[hC]: AsnEnumTypeDesc gets its own TclGetVal
+	and TclSetVal functions.
+
+	* c++-lib/*/meta.[hC]: introduce an AsnEnumTypeDesc class with its
+	own TclGetDesc2 function that returns the value names but omits
+	the numeric values.
+
+	* c++-lib/src/tcl-if.C &al.: set Tcl's errorCode variable
+
+	* c++-lib/{inc,src}: snacced.[hC] renamed to tcl-if.[hC]. class
+	SnaccEd renamed to SnaccTcl.
+
+	* the PDU flag belongs to the metacode, not only to the tcl
+	interface. (type and variable named adjusted)
+
+Thu Jul 27 10:27:07 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* cpp macro TBL changed to TTBL since some type table code uses
+	TBL as a type name.
+
+	* c++-lib/makefile: make $(TCL-P) if necessary.
+
+	* c++-lib/makefile: actions for stamp-useful rule: call diff only
+	if both input files exist.
+
+	* rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1
+	renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to
+	accomodate to snacc's new file name generation scheme.
+
+Tue Jul 25 13:35:58 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* policy.h: added switch for (en|dis)abling the compilation of the
+	idl code generator.
+
+	* compiler: PrintConditionalIncludeOpen() and
+	PrintConditionalIncludeClose() moved from
+	back-ends/c-gen/gen-code.[ch] to back-ends/cond.[ch].
+
+	* .../compiler/back-ends/c++-gen/gen-vals.c: use true/false
+	instead of AsnBool::true/false.
+
+	* the compiler is compiled from two files, tbl.h and tbl.c, it
+	generates itself. for bootstrapping purposes, initial versions are
+	supplied with the distribution.
+
+Mon Jul 24 14:26:16 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* .../c++-lib: code extracted from AsnOcts::TclGetVal and
+	AsnOcts::TclSetVal (src/asn-octs.C) into ::debinify and ::binify
+	(src/meta.C).
+
+	* Clone() added to AsnEnum.
+
+	* various C++ files: ``#error "..."'' instead of ``#error ...''
+
+	* c++-lib/*/asn-list.?: operator == and != return bool instead of int.
+
+	* .../maketail: the .C.o default rule now uses CXXFLAGS instead of
+	CFLAGS for compilation.
+
+	* .../c-lib and c++-lib call make recursively to generate the
+	different depencies for all the different makefiles.
+
+	* .../configure looks for tclsh(1)---the tcl-lib uses it to
+	construct the tclIndex file. .../configure doesn't look for Tcl/Tk
+	if the tclsh is absent.
+
+	* .../configure looks for patch(1)---the c-lib uses it to patch
+	tbl.h.
+
+	* .../configure searches for tree-3.6's libtktree.a and sets
+	TREELIBS in .../makehead accordingly.
+
+	* type table tools and the example merged into the distribution:
+	.../tbl-tools/ and .../tbl-example.
+
+	* dummy action added to config.h.in and config.h rules to trick
+	many makes' overoptimization.
+
+	* snacc -h now prints the usage to stdout.
+
+	* bug report address changed to protect an innocent's mailbox :-)
+
+	* .../version.h contains the snacc version---it is included in the
+	compiler source and is used by the .../makefile upon tar-file
+	generation.
+
+	* configure checks for memset(3), memcpy(3) and memcmp(3) and
+	.../snac.h defines replacements using bzero(3), bcopy(3) and
+	bcmp(3) if necessary.
+
+	* .../compiler/core/mem.c: Realloc() now checks realloc(3)'s
+	return value.
+
+	* changed `_' to `-' in file names.
+
+	* file names in .../compiler/back-ends/ have been shortened for
+	redundant parts (e.g. c_gen/gen_c_code -> c_gen/gen_code or
+	c++_gen/c++_kwd -> c++_gen/kwd).
+
+Sun Jul 23 12:51:24 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* an additional type description, AsnAliasTypeDesc, for type
+	definitions of the form ``TypeB ::= TypeA''. see the documentation
+	for further details.
+
+	* allow for more than one PDU per .asn1 file set:
+	- each type description gets a bool flag, pdu.
+	- each type description gets accompanied with a create function
+	that returns a newly allocated object of its mirror type. the type
+	description contains a pointer to this function. the getTclPDU()
+	function is deleted.
+	- compiler/core/meta.h: struct TclPDU becomes a linked list. it
+	gets a flag `used' to detect invalid command line arguments.
+
+	* additional function TclUnsetVal() to delete OPTIONAL members and
+	SEQUENCE OF and SET OF list elements.
+
+	*_getref() gets an additional optional argument, bool
+	create=false, to faciliate the different member access semantics
+	of TclGetVal() and TclSetVal().
+
+	* to accomodate to snacc's new file name generation scheme:
+	-  useful.asn1 renamed to asn-useful.asn1
+	- any-test.[hC] renamed to any.[hC]
+
+	* by default, snacc now derives output file names from the .asn1
+	input file name instead of the module name. a global variable,
+	`keepbaseG', is used to toggle between old and new behaviour.
+
+Sat Jul 22 22:49:25 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* use install-sh instead of install.sh, to prevent `make' implicit
+	rules from creating a file called install from it when there is no
+	makefile.
+
+Mon Feb 20 12:38:00 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* c{,++}_lib/makefile: remove stamp-useful before removing
+	asn_useful.[hcC].
+
+Sun Feb 19 19:13:50 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* some c{,++}_examples/*/makefile: some make(1)s leave a trailing
+	`/' on $(@D). since some mkdir(1)s deny their cooperation with
+	such arguments, this slash has got to be stripped.
+
+Sat Feb 18 14:12:23 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* in a lot of makefiles: dirname(1) and basename(1) do not exist
+	on every system. so we're using $(@D) and $(@F) instead.
+
+	* the code partially relied on big endianess. autoconf is used to
+	(un)define WORDS_BIGENDIAN accordingly and the byte order
+	dependent code parts have been fixed.
+
+	* instead of relying on (sizeof (int) == 4), autoconf now checks
+	some integer sizes and cpp is used to select appropiatly sized
+	integer types.
+
+	* c++_lib/{inc/asn_list.h,src/asn_list.C}: #pragma
+	interface/implementation are GNU specific and need to be wrapped
+	(by #ifdef __GNUG__).
+
+	* configure.in, acconfig.h, misc .C files: added #define
+	HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS (we need to check for this
+	since not every C++ compiler provides them.)
+
+	* snacc.h: added #defines GLASS and KHO for wrapping and enabling
+	of project and user specific code, resp.
+
+Fri Feb 17 15:27:31 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* c_examples/simple/README: reflect the test script's integration
+	into the makefile.
+
+	* makehead.in, maketail: added a small hack to find gcc's hidden
+	include directory to pass it to makedepend. this shall enable
+	X11's makedepend to find .h files a little more the way gcc does.
+
+	* configure.in, changes for autoconf 2.x
+
+Mon Feb 13 15:43:10 1995  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* miscelleanous makefiles: make depend builds snacc if and where
+	necessary.
+
+	* makefiles changed to augment CPPFLAGS instead of overriding
+	them.
+
+	* CFLAGS, CXXFLAGS and LDFLAGS moved from the various makefiles to
+	makehead(.in).
+
+	* settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from
+	{c_lib,c++_lib}/inc/asn_config.h to acconfig.h.
+
+Mon Oct 10 01:59:50 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* compiler/back_ends/c++_gen/gen_c++_code.c: the list functions
+	Append(), Prepend(), InsertBefore() and InsertAfter() now set the
+	current element to the element just inserted.
+
+Sat Oct  8 02:20:20 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* since autoconf substitutes in config.h.bot as well, we can't use
+	it. therefore it has been renamed to snacc.h and it includes the
+	config.h (generated by autoconf/configure) and policy.h (edited by
+	the person who wishes to compile/install/use snacc).
+
+	* the compiler is generated with a file it generates itself. for
+	bootstraping purposes,  an initial version is supplied in the
+	distribution (c_lib/boot/asn_useful.[hc]).
+
+	* to complement the destructors, T::T (const T&) and
+	T &T::operator = (const T &) have been added to override the
+	defaults supplied by the compiler. reason: simple pointer
+	duplication may lead to unreferenced objects and to objects
+	referenced more than once (on which the destructors delete may
+	choke).
+
+	* three bugs in compiler/back_ends/c++_gen/gen_c++_code.c's list
+	functions fixed (IBM ENC detected and fixed it at only place only).
+
+	* at the same places as the below two points: code for a Tcl
+	interface added.
+
+	* c++_lib/*: meta code for the basic types added. (and a little
+	glue code in compiler/core/snacc.c)
+
+	* compiler/back_ends/c++_gen/gen_c++_code.c: code added that (on
+	 request) added meta information to the C++ classes generated.
+
+	* compiler/back_ends/c++_gen/gen_c++_code.c: turned character
+	pointers into constant character arrays.
+
+	* several `unsigned long int' turned into `size_t' (C++ code
+	only).
+
+Thu Oct  6 19:25:31 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* c++_lib/*: virtual inline functions (the destructor and the
+	Clone() function) moved from inc/*.h to src/*.C because g++ turns
+	every one of them into a static non-inline function in every file
+	where the .h file gets included.
+
+Wed Sep 28 12:17:50 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* c++_lib/inc/asn_buf.h: fixed both Copy()'s name and
+	implementation to CopyOut() that always returns the number of
+	bytes copied out instead of 0 in case less than the requested
+	amount is available.
+
+Sat Sep 17 20:07:29 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* compiler/back_ends/c++_gen/gen_c++_code.c: reordered the
+	functions to get rid of their annoying declarations.
+
+Wed Sep 14 00:59:36 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* the constructors should initialize all pointers or else the
+	destructor may delete bogus pointers.
+
+	* c_lib/inc/asn_list.h: is unwise to #define unbalanced if()s!
+
+	* since i was still irritated by cpp standing for c++ and not the
+	C preprocessor, i renamed them to cxx (which is one known suffix
+	for C++ source files). since the standard #define is __cplusplus,
+	cplusplus would have been the more obvious choice, but it is a
+	little too long.
+
+	* made Print() const (and some other, mainly comparison functions).
+
+Thu Sep  1 01:11:17 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* compiler/core/snacc_config.h dissolved into mem.h and
+	snacc_util.h.
+
+	* the empty statement in a
+	    for (...; ...; ...);
+	  has often been overseen; the equivalent
+	    for (...; ...; ...)
+	      ;
+	  has proven to be less error prone.
+
+	* off-topic: cvs and rcs fixed to recognize .C and .asn1 as
+	suffices for C++ and ASN.1 code, respectively.
+
+Wed Aug 31 00:03:22 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* it is a good idea to have every .c file include its
+	corresponding .h file were its functions are declared, because
+	it's a very effictive way to let an ANSI compiler assert that
+	every function is defined with the same number and types of
+	arguments as it is declared with. proof: ParseValues() was
+	declared different than defined (different return type and
+	arguments reversed).
+
+	* for reasons unknown, the compiler files included two of the
+	various almost identical config.h files.
+
+	* compiler/back_ends/c++_gen/gen_c++_code.c: turned the huge
+	inline funtions into normal functions. (the change was actually
+	made by IBM ENC, but wasn't properly marked.) due to their size,
+	these inlines wouldn't get inlined anyway. due to their size they
+	wouldn't offer any speed advantage (the function call overhead
+	diminishes). instead, the compiler generated static functions in
+	every .C file were the .h file is included!  this inflates the .o
+	files and executables real quick (i'm speaking of MBytes per
+	executable).
+
+	* integrating c{,++}_examples:
+	.../simple: test csh-script integrated into makefile.
+
+Mon Aug 29 11:18:11 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* the dependencies have been moved into a separate file that is
+	not under cvs control. otherwise, the makefiles would inflate the
+	repository unnecessarily.
+
+Sun Aug 28 11:18:23 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* config.h defines TRUE/FALSE for C only. for C++, the built-in
+	bool type accompanied by true/false is used. for C++ compilers
+	that don't have bool built-in, an equivalent enum is defined.
+
+	* merged .../tbl_{lib,include}/ with .../c_lib/. changes detected
+	were:
+	- asn_any.h present in c_lib only.
+	- asn_bits.c ...
+	- tbl_*/asn_len.[ch] has an additional function PeekEoc().
+	- tbl_include/asn_list.h has an additonal macro
+	  FOR_REST_LIST_ELMT_RVS() and three additional functions,
+	  GetAsnListElmtIndex(), AsnListFree() and GetAsnListElmt().
+	  tbl_lib/asn_list.c defines only one additional function,
+	  GetAsnListElmt().
+	- asn_oid.h has the same extension as the compiler version.
+	- asn_real.c: the tbl version at two places has
+	    exponent >>= 8;
+	  where the c_lib has
+	    exponent >> 8;
+	  since the latter is a statement without any effect, that's
+	  probably the buggy version...
+	- tbl_*/asn_tag.[hc]: two additional macros, CONSIFY() and
+	  DECONSIFY(), and an additional function, PeekTag().
+	- asn_useful.c: the c_lib version contains two dozen used
+	  variables, so why not use the tbl version?
+	- exp_buf.h ...
+	- files only found in tbl_include: gen_buf.h,
+	  tbl{,_dec,_enc,_free,_gen_c_hdr,_incl,_print,_util}.h.
+	- files only found in tbl_lib: gen_buf.c,
+	  tbl{,_dec,_enc,_free,_print,_util}.c.
+	- sbuf.[hc]: tbl uses functions, c_lib defines cpp macros.
+
+	* modified the makefiles to include depend, install, clean and
+	clobber phony targets following the usual conventions.
+
+	* INSTALL, mkinstalldirs and install.sh copied from autoconf-1.11.
+
+	* 1.0-to-1.1-changes renamed to NEWS. README.changes that starts
+	with a line reading ``Changes between 1.0 and 1.1'' merged into NEWS.
+
+	* collected common code from compiler/core/snacc_config.h,
+	c_lib/inc/asn_config.h and c++_lib/inc/asn_config.h into config.h.bot.
+
+	* adding support for configuration via GNU autoconf:
+	- writing a configure.in, acconfig.h, makehead.in.
+	- replace a lot of macros in the makefiles with an inclusion of a
+	  makehead file generated by configure. since file inclusion has
+	  been a feature supported since UNIX System III, i consider it
+	  pretty portable.
+
+	* first cvs import.
+
+	* inserting RCS keywords as a preparation for cvs import.
+
+Sat Aug 27 11:59:08 1994  Robert Joop  (rj@rainbow.in-berlin.de)
+
+	* fixed the developer's nightmare that for every tiny change,
+	virtually everything was remade.
+
+	* -DFLEX ain't necessary since flex defines FLEX_SCANNER already.
+
+	* renamed asn1.lex to lex-asn1.l and asn1.yacc to parse-asn1.y to
+	take advantage of make's default rules.
+
+	* collision of #define Free() in the compiler's mem.h and a member
+	called Free in c_lib's struct AnyInfo in asn_any.h resolved.
+
+	* changed the directory structure. the content of .../c_lib/ +
+	.../c_include/ was almost identical to that of .../src/c_lib/, so
+	i merged them. .../src/ isn't the only directory containing
+	source, so i renamed it to compiler.  to sum it up:
+
+	old:			new:
+	.../src/back_ends	.../compiler/back_ends
+	.../src			.../compiler/core
+	.../src/c_lib			-> merged with .../c_{lib,include}
+	.../c_lib		.../c_lib/src
+	.../c_include		.../c_lib/inc
+	.../c++_lib		.../c++_lib/src
+	.../c++_include		.../c++_lib/inc
+
+	the differences found between .../src/c_lib/ and
+	.../c_{lib,include}/:
+	- Malloc()/Free() vs. NibbleAlloc()
+	- snacc_config.h partially copied to asn_config.h
+	- for the compiler, struct OID in asn_oid.h contains an additional
+	  member.
+	- the functions AsnListConcat(), AsnListFree() and
+	  GetAsnListElmtIndex() existed in the compiler version only.
+	  the mixture of Asn1Alloc() in combination with Free() and free()
+	  has been unified to using Asn1Free().
+
+	yet another almost identical copy of c_lib/ can be found in
+	.../tbl_{lib,include}/.
+
+	* since the code was quite inconsistent in respect of where lines
+	were broken (many short lines that unbroken are shorter than 72
+	columns were broken, and many long lines were broken into pieces
+	that were much longer than 80 columns), i took the liberty to
+	unify the layout.
+
+	* some international rules of typography:
+	- put a space before an opening parenthesis, and one after a
+	  closing one.
+	- no space after an opening parenthesis, or before a closing one.
+	- no space before punctuation.
+	- one space after punctuation (in some countries two after a full
+	  stop).
+
+	* a space somewhere between function name and first argument helps
+	to see that there are actually two words, not just one. for me,
+	  AlongFunctionName(andanArgument, ...)
+	looks too much like
+	  AlongFunctionNameCandanArgument, ...)
+	and thus i prefer
+	  AlongFunctionName (andanArgument, ...)
+
+	* moved `*' and `&' from the type to the value. that's where C and
+	C++ bind them to!  people are often mislead by this and generate
+	bugs like
+	  char* p1, p2;
+	instead of 
+	  char *p1, *p2;
+	which they really meant. blame K&R, not me :-)
+
+	* removed trailing blank lines. they simply produce blank pages
+	when the file is printed out. some files had got a dozen of them!
+
+	* trailing white space removed. noted here because it might cause
+	problems when someone wants to integrate patches; but vi users
+	hate empty lines that aren't empty because of white space, since
+	it keeps some movement commands from working.
+
+	* one of IBM ENC's changes is the addition of C++ destructors.
+	this change was clearly marked and therefore i removed the
+	#defines.
+
+	* i took the official snacc-1.1 distribution and made a diff(1) to
+	another version modified by IBM ENC. this diff has been merged
+	with the official version using `patch -D _IBM_ENC_`.
diff --git a/SecuritySNACCRuntime/INSTALL b/SecuritySNACCRuntime/INSTALL
new file mode 100644
index 00000000..8a7d026f
--- /dev/null
+++ b/SecuritySNACCRuntime/INSTALL
@@ -0,0 +1,146 @@
+   This is a generic INSTALL file for utilities distributions.
+If this package does not come with, e.g., installable documentation or
+data files, please ignore the references to them below.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation, and
+creates the Makefile(s) (one in each subdirectory of the source
+directory).  In some packages it creates a C header file containing
+system-dependent definitions.  It also creates a file `config.status'
+that you can run in the future to recreate the current configuration.
+
+To compile this package:
+
+1.  Configure the package for your system.
+
+   Normally, you just `cd' to the directory containing the package's
+source code and type `./configure'.  If you're using `csh' on an old
+version of System V, you might need to type `sh configure' instead to
+prevent `csh' from trying to execute `configure' itself.
+
+   Running `configure' takes awhile.  While it is running, it
+prints some messages that tell what it is doing.  If you don't want to
+see any messages, run `configure' with its standard output redirected
+to `/dev/null'; for example, `./configure >/dev/null'.
+
+   To compile the package in a different directory from the one
+containing the source code, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.  If
+for some reason `configure' is not in the source code directory that
+you are configuring, then it will report that it can't find the source
+code.  In that case, run `configure' with the option `--srcdir=DIR',
+where DIR is the directory that contains the source code.
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.  Alternately, you can do so by consistently
+giving a value for the `prefix' variable when you run `make', e.g.,
+     make prefix=/usr/gnu
+     make prefix=/usr/gnu install
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH' or set the `make'
+variable `exec_prefix' to PATH, the package will use PATH as the prefix
+for installing programs and libraries.  Data files and documentation
+will still use the regular prefix.  Normally, all files are installed
+using the same prefix.
+
+   Some packages pay attention to `--with-PACKAGE' options to
+`configure', where PACKAGE is something like `gnu-as' or `x' (for the
+X Window System).  They may also pay attention to `--enable-FEATURE'
+options, where FEATURE indicates an optional part of the package.  The
+README should mention any `--with-' and `--enable-' options that the
+package recognizes.
+
+   `configure' also recognizes the following options:
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+     Do not print messages saying which checks are being made.
+
+`--verbose'
+     Print the results of the checks.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--x-includes=DIR'
+     X include files are in DIR.
+
+`--x-libraries=DIR'
+     X library files are in DIR.
+
+   `configure' also accepts and ignores some other options.
+
+   On systems that require unusual options for compilation or linking
+that the package's `configure' script does not know about, you can give
+`configure' initial values for variables by setting them in the
+environment.  In Bourne-compatible shells, you can do that on the
+command line like this:
+
+     CC='gcc -traditional' LIBS=-lposix ./configure
+
+On systems that have the `env' program, you can do it like this:
+
+     env CC='gcc -traditional' LIBS=-lposix ./configure
+
+   Here are the `make' variables that you might want to override with
+environment variables when running `configure'.
+
+   For these variables, any value given in the environment overrides the
+value that `configure' would choose:
+
+ - Variable: CC
+     C compiler program.  The default is `cc'.
+
+ - Variable: INSTALL
+     Program to use to install files.  The default is `install' if you
+     have it, `cp' otherwise.
+
+   For these variables, any value given in the environment is added to
+the value that `configure' chooses:
+
+ - Variable: DEFS
+     Configuration options, in the form `-Dfoo -Dbar...'.  Do not use
+     this variable in packages that create a configuration header file.
+
+ - Variable: LIBS
+     Libraries to link with, in the form `-lfoo -lbar...'.
+
+   If you need to do unusual things to compile the package, we encourage
+you to figure out how `configure' could check whether to do them, and
+mail diffs or instructions to the address given in the README so we
+can include them in the next release.
+
+2.  Type `make' to compile the package.  If you want, you can override
+the `make' variables CFLAGS and LDFLAGS like this:
+
+	make CFLAGS=-O2 LDFLAGS=-s
+
+3.  If the package comes with self-tests and you want to run them,
+type `make check'.  If you're not sure whether there are any, try it;
+if `make' responds with something like
+	make: *** No way to make target `check'.  Stop.
+then the package does not come with self-tests.
+
+4.  Type `make install' to install programs, data files, and
+documentation.
+
+5.  You can remove the program binaries and object files from the
+source directory by typing `make clean'.  To also remove the
+Makefile(s), the header file containing system-dependent definitions
+(if the package uses one), and `config.status' (all the files that
+`configure' created), type `make distclean'.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need it if you want to regenerate
+`configure' using a newer version of `autoconf'.
diff --git a/SecuritySNACCRuntime/MacOSX-Install b/SecuritySNACCRuntime/MacOSX-Install
new file mode 100755
index 00000000..5151357a
--- /dev/null
+++ b/SecuritySNACCRuntime/MacOSX-Install
@@ -0,0 +1,13 @@
+:
+export LEXLIB="-ll"
+export CFLAGS="-DMACOS -DYYTEXT_POINTER"
+export srcdir=`pwd`
+echo === running configure....
+./configure
+rm -f c++-lib/inc/config.h
+cp -p config.h c++-lib/inc
+echo === running make depend for $srcdir....
+make depend srcdir=$srcdir
+echo === running make all....
+#make all srcdir=$srcdir
+make compiler srcdir=$srcdir
diff --git a/SecuritySNACCRuntime/MacOSX-configure b/SecuritySNACCRuntime/MacOSX-configure
new file mode 100644
index 00000000..3fea3a51
--- /dev/null
+++ b/SecuritySNACCRuntime/MacOSX-configure
@@ -0,0 +1,6 @@
+:
+export LEXLIB="-ll"
+export CFLAGS="-DMACOS -DYYTEXT_POINTER"
+./configure
+rm -f c++-lib/inc/config.h
+cp config.h c++-lib/inc
diff --git a/SecuritySNACCRuntime/MacOSX-make b/SecuritySNACCRuntime/MacOSX-make
new file mode 100644
index 00000000..760143f5
--- /dev/null
+++ b/SecuritySNACCRuntime/MacOSX-make
@@ -0,0 +1,12 @@
+#
+# dummy make file to launch MacOSX-Install
+#
+
+first all:
+	$(SRCROOT)/MacOSX-Install
+
+clean:
+	echo === Cleaning snacc source via Makefile ===
+	(cd $(SRCROOT); make clean srcdir=$(SRCROOT))
+
+# FIXME - install?
diff --git a/SecuritySNACCRuntime/NEWS b/SecuritySNACCRuntime/NEWS
new file mode 100644
index 00000000..ec1c5e27
--- /dev/null
+++ b/SecuritySNACCRuntime/NEWS
@@ -0,0 +1,160 @@
+=======================================================================
+
+main changes between versions 1.1 and 1.2:
+
+* ports to linux and alpha, which should make snacc both endianess and
+  64 bit clean.
+* to complement the destructors, T::T (const T&) and
+  T &T::operator = (const T &) have been added to override the defaults
+  supplied by the compiler. reason: simple pointer duplication may lead
+  to unreferenced objects and to objects referenced more than once (on
+  which the destructors delete may choke).
+* the files asn_useful.[hcC] and tbl.[ch] get regenerated automagically.
+  since the compiler itself is compiled with it, a bootstapping version
+  is included in the distribution.
+* the choice selector and all pointer members get initialized to get
+  predictable behaviour from the destructors (C++ code only, the C code
+  may still be broken!).
+* turned C++ inline functions into normal functions. this can reduce
+  the size of .o files and executables dramatically! (the change was
+  partially made by IBM ENC.)
+* the c++ lib compiles under gcc 2.6 (which has the bool type built-in).
+* GNU autoconf support added.
+* makefiles rewritten to provide the usual phony targets.
+* code duplication (4 config files, 3 c_libs) reduced.
+* C++ destructors added (partially contributed by IBM ENC).
+
+=======================================================================
+
+                  Snacc Changes from version 1.0 to 1.1
+
+Thanks to many bug reports from users of snacc 1.0, snacc 1.1 is more
+reliable.  Most of the changes between 1.0 and 1.1 are listed in the
+"1.0-to-1.1-changes" file.
+
+Type tables are the biggest addition.  The rest were mostly bug fixes.
+If you reported a bug and you don't see the fix, I either didn't have
+time or simply forgot.  Sorry.
+
+See README.future for the status of snacc now that I have graduated.
+
+The remainder of this file contains descriptions of many of the fixes
+between version 1.0 and 1.1.  I am sure there are fixes that are not
+documented here.
+
+=======================================================================
+
+The GNU Library Public License (LGPL) has been punted.
+
+=======================================================================
+Added table generation the compiler
+
+files: src/{ tbl.c tbl.h gen_tbls.c }
+=======================================================================
+
+Added table libraries and tools
+
+files: tbl_include/* tbl_lib/* tbl_tools/* tbl_example/*
+=======================================================================
+
+Re-aligned data structure for parse tree with code generated by
+newer version of snacc (yes, the parse tree was originally defined
+in ASN.1 - see asn1specs/asn1module.asn1)
+
+=======================================================================
+defined T61String and ISO646String Tag codes.
+
+files: snacc/c_inlcude/asn_tag.h and snacc/c++_inlcude/asn_tag.h
+
+#define TT61STRING_TAG_CODE TELETEXSTRING_TAG_CODE
+#define ISO646STRING_TAG_CODE VISIBLESTRING_TAG_CODE
+
+=======================================================================
+
+Named arcs in OBJECT IDENTIFER values no longer generate ASN.1 integers.
+e.g.  test OBJECT IDENTIFIER ::={2 3 4 ds(5) 1}
+
+used to be equivalent to:
+    ds INTEGER ::= 5
+    test OBJECT IDENTIFER ::= {2 3 4 ds 1}
+
+Snacc now ignores the name (ds in this case).  Ideally the arc could
+be entered into an object identifier tree maintained by snacc.
+
+files: snacc/src/val_parser.c
+
+=======================================================================
+
+Fixed bug in macro definition parsing that threw off the line
+number global.
+
+file: asn1.lex
+
+=======================================================================
+
+Added file and line number information to import errors.
+
+A lineNo field was added to the ImportElmt and ImportModule data
+structures.  The yacc code for the import elements & modules sets the
+lineNo values correctly.  The error reporting code in line_types.c and
+line_values.c now prints the line number info.
+
+files: link_types.c link_values.c asn1module.h asn1.yacc
+
+
+=======================================================================
+
+Added some line number info to multiply defined symbol error reports
+
+file: err_chk.c - uses importElmt line number info
+
+=======================================================================
+
+Added line number info to export errors.
+
+=======================================================================
+
+Added file and line number info to typing errors for OBJECT
+IDENTIFIER values.  Also stopped errors that cascade from other
+OID values referencing a malformed oid value.
+
+file: normalize.c
+
+
+=======================================================================
+
+Error messages will be printed for recursively defined OBJECT
+IDENTIIFER values.
+
+file: link_values.c
+
+=======================================================================
+
+Fixed bug #20. ie Not grabbing EOC on tagged (by def or in parent)
+   CHOICEs embedded in other SET, SEQ, CHOICE, SET OF or SEQ OF types.
+
+file: gen_c_dec.c
+
+=======================================================================
+
+Fixed bug #21. ie Value linking problem when assigning a value
+to a choice with a named number from one of the choice's elmts.
+
+file: link_values.c, snacc_util.c (added routine "GetAllNamedElmts")
+
+=======================================================================
+
+
+Fixed bug #22 - potentially not allocating enough space for
+ a C++ field name conflict
+
+file: snacc/src/back_ends/c++_gen/cpp_types.c
+
+=======================================================================
+
+Fixed nibble alloc bug.  curr pointer could be incremened past
+   end ptr which then caused problems with new allocs.
+
+file: c_lib/nibble_alloc.c tbl_lib/nibble_alloc.c
+
+=======================================================================
diff --git a/SecuritySNACCRuntime/README b/SecuritySNACCRuntime/README
new file mode 100644
index 00000000..87034b76
--- /dev/null
+++ b/SecuritySNACCRuntime/README
@@ -0,0 +1,230 @@
+This new release, 1.3, consists of some improvements and bug fixes:
+
+New in 1.3:
+ * Corrected bug in generic table decoder wrt. indefinite length elements
+ * Corrected compiler access to freed memory (bug reported by Markku Savela)
+ * Broke asnwish.c into two pieces so that one can build ones own wish
+ * Added "beredit" tool (based on asnwish, allowes to edit BER messages)
+
+New in 1.3b4:
+ * Generic table decoding routines with callback mechanism in tbl library
+ * New tool "berdecode", decoding any BER data, can also use table file
+ * New Tcl/Tk tool "asnwish", reads table files, access to grammar, en-/decoding
+ * Fix for tag values > 2^14 (credits to Enrico Badella)
+ * Fix for table-encoding tag values dividable by 128
+ * Small fix in AsnBits::GetBit to return TRUE (i.e., 1) instead of #bit in byte
+
+New in 1.3b3:
+ * Added isPdu flag to tables
+ * Added number range checks during parsing
+
+New in 1.3b2:
+ * Small fix of C value string generation w char >127 (credits to Marc LeFur)
+ * Added (limited) size constraints, bitstring and enumeration names to tables
+
+New in 1.3b1:
+ * Made snacc.h more C++-readable (credits to Steve Walker).
+ * Improved dependency generation for stupid makedepends.
+ * Corrected PeekTag to peek into buffer only as far as necessary.
+ * Added installable error handler.
+ * Fixed small glitch in idl-code generator (credits to Markku Savela).
+ * Finally fixed cut-and-paste error in SEQUENCE OF parsing.
+
+New in 1.3a<n>:
+ * Continued porting C, C++, tbl to 64 bit, any endianness: Hash typedef,
+   PeekTag algorithm used by tables.
+ * Fixed cut-and-paste error in SEQUENCE OF parsing.
+ * Added missing initialisation of exponent in asn-real.[Cc].
+ * Fixed tbl-free.c and some other table-related bugs.
+ * Added casts and stuff for picky C++ compilers.
+ * Incorporated all valid bug fixes from snacc-bugs.
+ * Initial move of tcl stuff to tcl7.6/tk4.2/tree4.1.
+
+
+WARNING: the rest of this README is out of date!
+
+
+For the newer releases, please look at
+
+  http://www.fokus.gmd.de/ovma/freeware/snacc/entry.html
+
+Please send comments and bug reports to the new maintainer you will find
+in the above web page.
+
+Newer Snacc versions will continue to be made available at:
+
+  ftp://ftp.fokus.gmd.de/pub/freeware/snacc/
+
+Robert Joop, 1997-02-16
+
+
+
+For more up-to-date information, please refer to doc/snacc.ps.
+
+The bug-report address given below was for Snacc 1.1.
+
+
+
+
+snacc ASN.1 Compiler Release  1.1 - (updated Jul 93)
+-----------------------------------------------------
+
+This package provides the C/yacc/lex source code for snacc, an ASN.1
+to C or C++ compiler.  Snacc is short for "Sample Neufeld Asn.1 to C
+Compiler" and ASN.1 stands for Abstract Syntax Notation One (CCITT
+X.208/ ISO 8824).  See the COPYRIGHT file for copyright information.
+
+
+What It Does
+------------
+
+Given an ASN.1 source file(s) snacc can produce:
+
+   1. C routines for BER encoding, decoding, printing and freeing.
+   2. C++ routines for BER encoding, decoding, and printing.
+   3. A type table that can be used with C driver routines
+      for BER encoding, decoding, printing and freeing.
+   4. if you are really lucky, a core dump! :)
+
+Snacc produces reasonably efficient C or C++ routines and data
+structures to support BER encoding and decoding values of the given
+ASN.1 data structures.  Printing routines for the decoded values are
+also generated.  For C only, hierarchical freeing routines are
+generated (but are not recommended for efficiency reasons).
+
+When using the C or C++ (not table) options, snacc creates the
+following C files for each ASN.1 source file (module):
+
+        1. .h file for the C/C++ translation of the ASN.1 data
+           structure and prototypes for the generated routines.
+
+        2. .c/.C file for the C/C++ encode, decode, print and free
+           routines.
+
+When using the table option, snacc produces a type table file
+(a BER encoding) that can later be loaded at runtime by the
+table driven encoding and decoding routines.
+
+See the latex or PostScript version of the documentation in the
+snacc/doc directory for indepth information on this tool.  For a quick
+introduction, look at the examples in snacc/c_examples,
+snacc/c++_examples and snacc/tbl_example.
+
+
+Features of ASN.1 Supported
+---------------------------
+
+   - parses ASN.1 '90 (subtype notation etc.)
+   - macro definitions do not generate syntax errors but are
+     are not processed. (retained as string)
+   - value notation is parsed and for OBJECT IDENTIFIERs, INTEGERs
+      and BOOLEANS (any other value in { }'s is currently kept as a string)
+   - handles multiple ASN.1 module compiling/linking (IMPORTS/EXPORTS)
+   - some X.400 and SNMP macros are parsed
+   - supports ";" separted type or value definitions in the ASN.1 source.
+     This is useful when dealing with some macros that introduce parsing
+     problems.  Does not require the ";"'s though.
+   - ANY DEFINED BY types are handled using the SNMP OBJECT-TYPE
+     macro to define the identifier to type mapping.
+
+
+Bugs are still quite likely even though this is the second release of
+snacc.  if you find any or have other comments please email:
+   snacc-bugs@cs.ubc.ca
+
+
+To Install It
+-------------
+
+By default, the snacc makefile uses GNU bison and GNU flex (instead of
+yacc and lex).  If you do not have these installed, see the
+snacc/src/README and snacc/src/makefile.  Otherwise, type "make" in
+this directory.  Hopefully this will put the snacc binary in the
+snacc/bin directory and build the C runtime library, the table library
+and the table tools. Alternatively, type "make all" to install these
+and the C++ library.
+
+Compiling problems may occurr on different flavours of UNIX but they
+should not be too difficult fix.  Likely sources of problems include
+non-standard include files and lex, yacc and cc idiosyncrasies.
+If your yacc croaks with a message about too many productions use
+bison.  Same thing with lex -> use flex.   Bison and flex are both
+freely available from numerous ftp sites. (even cs.ubc.ca in /mirror2/gnu)
+
+The makefiles take advantage of the file inclusion feature. Since this
+has already been supported by UNIX System III make (somewhen around
+1980), I consider it to be pretty portable. If your make is crippled,
+either use a newer one (e.g. GNU make), or as a last resort, remove the
+include statements and call make with `-f makehead makefile maketail'.
+  The dependencies have been moved into a separate file that is not
+under cvs control. Otherwise, the makefiles would inflate the
+repository unnecessarily. GNU make automatically makes the dependencies
+if the file does not exist, but other makes simply give up. In that
+case, an initial (empty) file has to be generated. The top level
+makefile does this for you.
+  The behaviour of makedepend has been changed between X11R5 and R6.
+The new version keeps the source files' dirname and replaces the suffix
+only, the old version removed the dirname.  The makefiles expect the
+new behaviour. If you've still got the R5 makedepend, the compiler's
+dependencies will be useless.  (If you only install the code and don't
+make any changes, this won't hurt you.)
+
+The snacc compiler and the generated code will compile under ANSI and
+non-ANSI C compilers.  See the README and the makefile in the
+snacc/src directory for more compiling information.  Snacc has been
+successfully installed on Sun SPARCs, HP700s, IBM RS 6000s, MIPS,
+i486/Linux, Alpha OSF/1 and many other machines.
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/README,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:04  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:50  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.14  1997/10/10 13:42:31  wan
+# Corrected bug in generic table decoder wrt. indefinite length elements
+# Corrected compiler access to freed memory (bug reported by Markku Savela)
+# Broke asnwish.c into two pieces so that one can build ones on wish
+# Added beredit tool (based on asnwish, allowes to edit BER messages)
+#
+# Revision 1.13  1997/09/16 14:57:59  wan
+# Proper description of last-minute changes
+#
+# Revision 1.12  1997/09/05 07:51:04  wan
+# Updated
+#
+# Revision 1.11  1997/08/28 09:48:08  wan
+# Added description of changes
+#
+# Revision 1.10  1997/06/19 09:32:22  wan
+# Added 1.3b3 change description
+#
+# Revision 1.9  1997/05/07 15:20:57  wan
+# Added (limited) size constraints, bitstring and enumeration names to tables
+#
+# Revision 1.8  1997/04/07 13:14:16  wan
+# Final README for 1.3b1
+#
+# Revision 1.7  1997/03/20 15:50:24  wan
+# Push to 1.3b1.
+#
+# Revision 1.6  1997/02/16 22:26:40  rj
+# url corrected
+#
+# Revision 1.5  1997/02/16 20:23:14  rj
+# final release of snacc 1.2rj
+#
+# Revision 1.4  1995/09/07 20:54:03  rj
+# check-in for release 1.2rj.8
+#
+# Revision 1.3  1995/02/22  09:54:05  rj
+# added Alpha OSF/1 to the list of supported platforms.
+#
+# Revision 1.2  1994/09/01  01:40:54  rj
+# some word about makefile inclusion and dependencies added.
+#
+# Revision 1.1  1994/08/28  11:02:04  rj
+# first check-in
diff --git a/SecuritySNACCRuntime/VDADER_RULES.TXT b/SecuritySNACCRuntime/VDADER_RULES.TXT
new file mode 100644
index 00000000..05779798
--- /dev/null
+++ b/SecuritySNACCRuntime/VDADER_RULES.TXT
@@ -0,0 +1,24 @@
+
+This is an interim release of the VDA Enchanced version of the SNACC 1.3.  To 
+enable the use of DER encoding you need to use the "-D" command line option.  
+The DER rules enchancements have been made to the C++ side only so don't 
+forget the "-C" (C++) option.
+
+At this time this modified version is closely tied to the VDA developed SFL
+library.  If you use the "-D" it's assumed that you are also using the SFL
+in which case there is no problem.  However, if you want to use this version
+of SNACC standalone you will need to acquire the sm_vdasnacc.h and 
+sm_vdasnacc.cpp files from the SFL distribution.  This situation is temporary.
+As we fix/add features into SNACC we will most likely move those files into
+our enchanced SNACC distribution.
+
+Also..  The file comments have not been updated yet.  However, I did include
+the SCCS (SunOS 4.1.3 SCCS) files so that the changes we made can be reviewed
+by those wishing to do so.  We will merge the comments from the SCCS history 
+into each modified file when modifications are complete.
+
+For more information on the SFL try http://www.jgvandyke.com
+
+Pierce Leonberger
+Systems Engineer
+J.G. Van Dyke & Associates (VDA)
diff --git a/SecuritySNACCRuntime/acconfig.h b/SecuritySNACCRuntime/acconfig.h
new file mode 100644
index 00000000..7ff3f65b
--- /dev/null
+++ b/SecuritySNACCRuntime/acconfig.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * file: acconfig.h
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/acconfig.h,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+ * $Log: acconfig.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:04  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:16  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:05:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.7  1997/03/03 11:58:26  wan
+ * Final pre-delivery stuff (I hope).
+ *
+ * Revision 1.6  1997/02/28 13:39:34  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.5  1997/02/15 20:01:37  rj
+ * check whether the compiler supports volatile functions (and whether abort() is volatile).
+ *
+ * Revision 1.4  1995/02/20  11:16:57  rj
+ * cpp switch HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS added.
+ *
+ * Revision 1.3  1995/02/13  14:46:49  rj
+ * settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h.
+ *
+ * Revision 1.2  1994/10/08  04:38:56  rj
+ * slot for autoconf Tcl detection added.
+ *
+ * Revision 1.1  1994/09/01  00:51:19  rj
+ * first check-in (new file).
+ *
+ */
+
+/*
+ * define IEEE_REAL_FMT if your system/compiler uses the native ieee double
+ * this should improve the performance of encoding reals.
+ * If your system has the IEEE library routines (iszero, isinf etc)
+ * then define IEEE_REAL_LIB.  If neither are defined then
+ * frexp is used.  Performance is probaby best for IEEE_REAL_FMT.
+ *
+ *  #define IEEE_REAL_FMT
+ *  #define IEEE_REAL_LIB
+ */
+/* use ANSI or K&R style C? */
+#undef __USE_ANSI_C__
+
+/* does the C++ compiler have the bool type built-in? */
+#undef BOOL_BUILTIN
+
+/* does the C++ compiler allow variable sized automatic arryas? */
+#undef HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS
+
+/* do we have all the libs we need for the Tcl interface? */
+#undef HAVE_TCL
+
+/* does the compiler support volatile functions (and is abort() volatile?) */
+#undef COMPILER_WITHOUT_VOLATILE_FUNCTIONS
diff --git a/SecuritySNACCRuntime/asn1specs/any.asn1 b/SecuritySNACCRuntime/asn1specs/any.asn1
new file mode 100644
index 00000000..27d3ef2c
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/any.asn1
@@ -0,0 +1,116 @@
+-- file: asn1specs/any.asn1
+--
+-- this file is used in ../c{,++}-examples/any/
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/any.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: any.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:55  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.2  1997/02/16 20:25:20  rj
+-- check-in of a few cosmetic changes
+--
+-- Revision 1.1  1994/08/31  22:44:44  rj
+-- first check-in.
+
+ANY-TEST DEFINITIONS ::= BEGIN
+
+--
+-- use the SNMP OBJECT type to define the correlation between
+-- the identifying INTEGER/OBJECT IDENTIFIER
+-- and the ANY DEFINED BY type
+--
+
+intId OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= 1
+
+boolId OBJECT-TYPE
+       SYNTAX  BOOLEAN
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= 2
+
+octsId OBJECT-TYPE
+       SYNTAX  [PRIVATE 2] IMPLICIT OCTET STRING
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= 3
+
+bitsId OBJECT-TYPE
+       SYNTAX  [PRIVATE 1] BIT STRING
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= 4
+
+realId OBJECT-TYPE
+       SYNTAX  REAL
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= 5
+
+--
+-- note that the following OBJECT-TYPE OBJECT IDENTIFIER values
+-- reference the previous OBJECT-TYPE INTEGER values
+
+intOid OBJECT-TYPE
+        SYNTAX  INTEGER
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { 0 1 2 3 4 intId}
+
+boolOid OBJECT-TYPE
+        SYNTAX  BOOLEAN
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { 0 1 2 3 4 boolId}
+
+octsOid OBJECT-TYPE
+        SYNTAX  OCTET STRING
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { 0 1 2 3 4 octsId}
+
+bitsOid OBJECT-TYPE
+        SYNTAX  BIT STRING
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { 0 1 2 3 4 bitsId}
+
+realOid OBJECT-TYPE
+        SYNTAX  REAL
+        ACCESS  read-write
+        STATUS  mandatory
+        ::= { 0 1 2 3 4 realId}
+
+
+-- this type tests both the INTEGER and OBJECT IDENTIFIER mapping
+AnyTestType ::= --snacc isPdu:"TRUE" -- SEQUENCE
+{
+    intMap TSeq1,
+    oidMap TSeq2
+}
+
+TSeq1 ::= SEQUENCE OF AttrValue1
+
+
+AttrValue1 ::= SEQUENCE
+{
+    id INTEGER,
+    ANY DEFINED BY id
+}
+
+TSeq2 ::= SEQUENCE OF AttrValue2
+
+AttrValue2 ::= SEQUENCE
+{
+    id OBJECT IDENTIFIER,
+    ANY DEFINED BY id
+}
+
+END
diff --git a/SecuritySNACCRuntime/asn1specs/asn-useful.asn1 b/SecuritySNACCRuntime/asn1specs/asn-useful.asn1
new file mode 100644
index 00000000..59d5be96
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/asn-useful.asn1
@@ -0,0 +1,99 @@
+ASN-USEFUL DEFINITIONS ::=
+BEGIN
+
+-- file: .../asn1specs/asn-useful.asn1
+--
+-- NOTE: every one of these types is marked as a PDU so the compiler
+--       will produce the encode and decode routines that
+--       enc/dec the top tag/len pairs, not just the content decoders.
+--       (only nec for re-generating the library files "asn_useful.[ch]").
+--       The isPdu field does not affect how this module is linked
+--       with other modules during compilation.
+--
+--  (type DEF comment directives immediately follow the "::=")
+--
+-- MS 92
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/asn-useful.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: asn-useful.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.2  2000/06/08 19:58:05  dmitch
+-- Added UTF8String.
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:55  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.3  1995/07/24 15:12:35  rj
+-- useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme.
+--
+-- Revision 1.2  1994/08/28  09:54:19  rj
+-- comment leader fixed.
+--
+-- Revision 1.1  1994/08/28  09:51:15  rj
+-- first check-in.
+
+
+ObjectDescriptor ::= -- isPdu:"TRUE" --
+                     [UNIVERSAL 7] IMPLICIT OCTET STRING
+
+UTF8String		 ::= --snacc isPdu:"TRUE" --
+					 [UNIVERSAL 12] IMPLICIT OCTET STRING
+
+NumericString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 18] IMPLICIT OCTET STRING
+
+PrintableString  ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 19] IMPLICIT OCTET STRING
+
+TeletexString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 20] IMPLICIT OCTET STRING
+
+T61String        ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 20] IMPLICIT OCTET STRING
+
+VideotexString   ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 21] IMPLICIT OCTET STRING
+
+IA5String        ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 22] IMPLICIT OCTET STRING
+
+GraphicString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 25] IMPLICIT OCTET STRING
+
+VisibleString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 26] IMPLICIT OCTET STRING
+
+ISO646String     ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 26] IMPLICIT OCTET STRING
+
+GeneralString    ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 27] IMPLICIT OCTET STRING
+
+UTCTime          ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 23] IMPLICIT OCTET STRING
+
+GeneralizedTime  ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 24] IMPLICIT OCTET STRING
+
+UniversalString  ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 28] IMPLICIT OCTET STRING
+
+BMPString        ::= --snacc isPdu:"TRUE" --
+                     [UNIVERSAL 30] IMPLICIT OCTET STRING
+
+EXTERNAL         ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 8] IMPLICIT SEQUENCE
+{
+        direct-reference      OBJECT IDENTIFIER OPTIONAL,
+        indirect-reference    INTEGER OPTIONAL,
+        data-value-descriptor ObjectDescriptor OPTIONAL,
+        encoding CHOICE
+        {
+                single-ASN1-type [0] OCTET STRING,  -- should be ANY
+                octet-aligned    [1] IMPLICIT OCTET STRING,
+                arbitrary        [2] IMPLICIT BIT STRING
+        }
+}
+
+END  -- of ASN-USEFUL  type definitions
diff --git a/SecuritySNACCRuntime/asn1specs/asn1module.asn1 b/SecuritySNACCRuntime/asn1specs/asn1module.asn1
new file mode 100644
index 00000000..2084f9f8
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/asn1module.asn1
@@ -0,0 +1,673 @@
+-- file: .../asn1specs/asn1module.asn1
+--
+-- This module describes the data structure used to reprsent the
+-- compiled ASN.1.
+-- Using ASN.1 for the internal data structure allows writing
+-- (encoding) to disk for storage (not done yet due to recursive
+--  refs back to the module)
+--
+-- Mike Sample 91/08/29
+-- Modifed 92/05  MS
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/asn1module.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: asn1module.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:55  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.3  1995/07/25 20:04:04  rj
+-- data structures added for idl backend.
+--
+-- Revision 1.2  1994/08/28  09:54:16  rj
+-- comment leader fixed.
+--
+-- Revision 1.1  1994/08/28  09:51:11  rj
+-- first check-in.
+
+Asn1Module DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+
+-- exports everything
+-- imports nothing
+
+
+Modules ::= [APPLICATION 0] IMPLICIT SEQUENCE
+{
+    creationTime INTEGER,
+    modules ModuleList
+}
+
+ModuleList ::= SEQUENCE OF Module
+
+
+Module ::= SEQUENCE
+{
+    status ENUMERATED { mod-ok(0), mod-not-linked(1), mod-error(2) },
+    modId      ModuleId,
+    tagDefault ENUMERATED { explicit-tags(0), implicit-tags(1) },
+    exportStatus  ENUMERATED { exports-all(0), exports-nothing(1),
+                               exports-some(2) },
+    imports    ImportModuleList,
+    typeDefs   TypeDefList,
+    valueDefs  ValueDefList,
+    hasAnys    BOOLEAN,
+
+    asn1SrcFileName MyString,
+    cHdrFileName    MyString,
+    cSrcFileName    MyString,
+    cxxHdrFileName  MyString,
+    cxxSrcFileName  MyString,
+
+    dbHdrFileName       MyString, -- IBM-ENC
+    dbSrcFileName       MyString, -- IBM-ENC
+
+    cxxname             MyString, -- META
+
+    idlFileName         MyString, -- IDL
+    idlname             MyString -- IDL
+}
+
+
+ModuleId ::= SEQUENCE
+{
+    name MyString,
+    oid  OBJECT IDENTIFIER OPTIONAL --snacc cTypeName:"OID" isPtr:"TRUE"
+}
+
+
+ImportModuleList ::= SEQUENCE OF ImportModule
+
+
+ImportModule ::= SEQUENCE
+{
+    modId       ModuleId,
+    importElmts ImportElmtList,
+    moduleRef   Module, --snacc isEncDec:"FALSE"
+    lineNo INTEGER
+}
+
+
+ImportElmtList ::= SEQUENCE OF ImportElmt
+
+
+ImportElmt ::= SEQUENCE
+{
+    resolvedRef CHOICE
+    {
+        type  [0] TypeDef,  -- not encoded
+        value [1] ValueDef  -- not encoded
+     } OPTIONAL,
+    name MyString,
+    privateScope BOOLEAN, -- true if from MODNAME.TYPE ref
+    lineNo INTEGER
+}
+
+TypeDefList ::= SEQUENCE OF TypeDef
+
+OidOrInt ::= CHOICE
+{
+    oid OBJECT IDENTIFIER,
+    intId INTEGER
+}
+
+AnyRef ::= SEQUENCE
+{
+    anyIdName MyString,
+    id OidOrInt
+}
+
+AnyRefList ::= SEQUENCE OF AnyRef
+
+TypeDef ::= SEQUENCE
+{
+    exported     BOOLEAN,
+    recursive    BOOLEAN,
+    isPdu    BOOLEAN,
+    localRefCount  INTEGER,
+    importRefCount INTEGER,
+    tmpRefCount    INTEGER,
+    visited      BOOLEAN,
+    definedName  MyString,
+    type         Type,
+    cTypeDefInfo CTDI,
+    cxxTypeDefInfo CxxTDI,
+    attrList     AttributeList,
+    refList      TypeDefList,
+    anyRefs      AnyRefList
+}
+
+
+Tag ::= SEQUENCE
+{
+    tclass INTEGER, -- swap this for the BER_CLASS enum from basetypes.h
+    form  INTEGER,  -- swap this for the BER_FORM enum
+    code  INTEGER,
+    explicit BOOLEAN,
+    valueRef Value
+}
+
+Type ::= SEQUENCE
+{
+    optional   BOOLEAN,
+    implicit   BOOLEAN,
+    tags       TagList,
+    defaultVal [0] IMPLICIT NamedValue OPTIONAL,
+    subtypes   [1] Subtype OPTIONAL,
+    basicType  [2] BasicType,
+    lineNo     INTEGER,
+    cTypeRefInfo CTRI,
+    cxxTypeRefInfo CxxTRI,
+    attrList   AttributeList
+}
+
+TagList ::= SEQUENCE OF Tag
+
+AttributeList ::= SEQUENCE OF MyString
+
+NamedNumberList ::= ValueDefList
+
+
+-- BasicTypes with NULL need no more info that which type it is
+-- (this is known from the choice id)
+
+BasicType ::= CHOICE
+{
+    unknown         [0]  IMPLICIT NULL,
+    boolean         [1]  IMPLICIT NULL,
+    integer         [2]  IMPLICIT NamedNumberList,
+    bitString       [3]  IMPLICIT NamedNumberList,
+    octetString     [4]  IMPLICIT NULL,
+    null            [5]  IMPLICIT NULL,
+    oid             [6]  IMPLICIT NULL,
+    real            [7]  IMPLICIT NULL,
+    enumerated      [8]  IMPLICIT NamedNumberList,
+    sequence        [9]  IMPLICIT NamedTypeList,
+    sequenceOf      [10] IMPLICIT Type,
+    set             [11] IMPLICIT NamedTypeList,
+    setOf           [12] IMPLICIT Type,
+    choice          [13] IMPLICIT NamedTypeList,
+    selection       [14] IMPLICIT SelectionType,
+    componentsOf    [15] IMPLICIT Type, --  [Resolved](local/import) type ref
+    any             [16] IMPLICIT NULL,
+    anyDefinedBy    [17] IMPLICIT AnyDefinedByType,
+    localTypeRef    [19] IMPLICIT TypeRef,
+    importTypeRef   [20] IMPLICIT TypeRef,
+    macroType       [21] MacroType,
+    macroDef        [22] IMPLICIT MacroDef --snacc isPtr:"FALSE"
+}
+
+MacroDef ::= MyString -- just keep the text for now
+
+MacroType ::= CHOICE
+{
+    rosOperation    [0] IMPLICIT RosOperationMacroType,
+    rosError        [1] IMPLICIT RosErrorMacroType,
+    rosBind         [2] IMPLICIT RosBindMacroType,
+    rosUnbind       [3] IMPLICIT RosBindMacroType,
+    rosAse          [4] IMPLICIT RosAseMacroType,
+    rosAc           [5] IMPLICIT RosAcMacroType,
+    mtsasExtension  [6] IMPLICIT MtsasExtensionMacroType,
+    mtsasExtensions [7] IMPLICIT MtsasExtensionsMacroType,
+    mtsasExtensionAttribute [8] IMPLICIT MtsasExtensionAttributeMacroType,
+    mtsasToken      [9] IMPLICIT MtsasTokenMacroType,
+    mtsasTokenData [10] IMPLICIT MtsasTokenDataMacroType,
+    mtsasSecurityCategory [11] IMPLICIT MtsasSecurityCategoryMacroType,
+    asnObject       [12] IMPLICIT AsnObjectMacroType,
+    asnPort         [13] IMPLICIT AsnPortMacroType,
+    asnRefine       [14] IMPLICIT AsnRefineMacroType,
+    asnAbstractBind      [15] IMPLICIT AsnAbstractBindMacroType,
+    asnAbstractUnbind    [16] IMPLICIT AsnAbstractBindMacroType,
+    asnAbstractOperation [17] IMPLICIT RosOperationMacroType,
+    asnAbstractError     [18] IMPLICIT RosErrorMacroType,
+    afAlgorithm     [19] IMPLICIT Type,
+    afEncrypted     [20] IMPLICIT Type,
+    afProtected     [21] IMPLICIT Type,
+    afSignature     [22] IMPLICIT Type,
+    afSigned        [23] IMPLICIT Type,
+    snmpObjectType  [24] IMPLICIT SnmpObjectTypeMacroType
+}
+
+
+AnyDefinedByType ::= SEQUENCE
+{
+    fieldName MyString,   -- name of field that its defined by
+    link NamedType OPTIONAL  -- REFERENCE not encoded
+}
+
+
+SelectionType ::= SEQUENCE
+{
+    fieldName MyString,   -- name of field in choice
+    typeRef   Type,      -- [Resolved](local/import) type ref
+    link NamedType OPTIONAL -- REFERENCE not encoded
+}
+
+NamedTypeList ::= SEQUENCE OF NamedType
+
+NamedType ::= SEQUENCE
+{
+    fieldName  MyString, -- may be empty or NULL str
+    type       Type
+}
+
+
+TypeRef ::= SEQUENCE
+{
+    typeName    MyString,
+    moduleName  MyString, -- used for "modname.type" refs(may be null)
+    module      Module,   --snacc isEncDec:"FALSE"
+    link        TypeDef   --snacc isEncDec:"FALSE"
+}
+
+
+
+RosOperationMacroType ::= SEQUENCE
+{
+    arguments NamedType,
+    result    NamedType,
+    errors    [0] IMPLICIT TypeOrValueList OPTIONAL,
+    linkedOps [1] IMPLICIT TypeOrValueList OPTIONAL
+}
+
+ValueList ::= SEQUENCE OF Value
+
+TypeOrValueList ::= SEQUENCE OF TypeOrValue
+
+TypeOrValue ::= CHOICE
+{
+    type  [0] IMPLICIT Type,
+    value [1] IMPLICIT Value
+}
+
+OidList ::= SEQUENCE OF OBJECT IDENTIFIER
+
+
+RosErrorMacroType ::= SEQUENCE
+{
+    parameter NamedType
+}
+
+RosBindMacroType ::= SEQUENCE
+{
+    argument NamedType,
+    result   NamedType,
+    error    NamedType
+}
+
+
+RosAseMacroType  ::= SEQUENCE
+{
+    operations       ValueList,
+    consumerInvokes  ValueList,
+    supplierInvokes  ValueList
+}
+
+RosAcMacroType ::= SEQUENCE
+{
+    nonRoElements       ValueList,
+    bindMacroType       Type,
+    unbindMacroType     Type,
+    remoteOperations    Value,
+    operationsOf        ValueList,
+    initiatorConsumerOf ValueList,
+    responderConsumerOf ValueList,
+    abstractSyntaxes    OidList
+}
+
+
+MtsasExtensionMacroType ::=  SEQUENCE
+{
+    elmtType              [0] IMPLICIT NamedType OPTIONAL,
+    defaultValue          [1] IMPLICIT Value    OPTIONAL,
+    criticalForSubmission [2] IMPLICIT BOOLEAN  OPTIONAL,
+    criticalForTransfer   [3] IMPLICIT BOOLEAN  OPTIONAL,
+    criticalForDelivery   [4] IMPLICIT BOOLEAN  OPTIONAL
+}
+
+
+MtsasExtensionsMacroType ::= SEQUENCE
+{
+    extensions ValueList
+}
+
+MtsasExtensionAttributeMacroType ::= SEQUENCE
+{
+    type Type OPTIONAL
+}
+
+MtsasTokenMacroType ::= SEQUENCE
+{
+    type Type OPTIONAL
+}
+
+MtsasTokenDataMacroType ::= SEQUENCE
+{
+    type Type OPTIONAL
+}
+
+MtsasSecurityCategoryMacroType ::= SEQUENCE
+{
+    type Type OPTIONAL
+}
+
+AsnObjectMacroType ::= SEQUENCE
+{
+   ports  AsnPortList OPTIONAL
+}
+
+AsnPortList ::= SEQUENCE OF AsnPort
+
+AsnPort ::= SEQUENCE
+{
+    portValue Value,
+    portType  ENUMERATED
+    {
+         consumer-port(0),
+         supplier-port(1),
+         symmetric-port(2)
+    }
+}
+
+
+AsnPortMacroType ::= SEQUENCE
+{
+    abstractOps     [0] IMPLICIT TypeOrValueList OPTIONAL,
+    consumerInvokes [1] IMPLICIT TypeOrValueList OPTIONAL,
+    supplierInvokes [2] IMPLICIT TypeOrValueList OPTIONAL
+}
+
+
+AsnRefineMacroType ::= INTEGER
+
+AsnAbstractBindMacroType ::= SEQUENCE
+{
+    ports [0] IMPLICIT AsnPortList OPTIONAL,
+    type  [1] IMPLICIT Type OPTIONAL
+}
+
+
+SnmpObjectTypeMacroType ::= SEQUENCE
+{
+   syntax Type,
+   access ENUMERATED
+       { snmp-read-only(0), snmp-read-write(1),
+         snmp-write-only(2), snmp-not-accessible(3)},
+   status ENUMERATED
+       { snmp-mandatory(0), snmp-optional(1),
+         snmp-obsolete(2), snmp-deprecated(3)},
+   description [0] IMPLICIT Value OPTIONAL,
+   reference   [1] IMPLICIT Value OPTIONAL,
+   index       [2] IMPLICIT TypeOrValueList OPTIONAL,
+   defVal      [3] IMPLICIT Value OPTIONAL
+}
+
+
+Subtype ::= CHOICE
+{
+    single [0] SubtypeValue,
+    and    [1] IMPLICIT SubtypeList,
+    or     [2] IMPLICIT SubtypeList,
+    not    [3] Subtype
+}
+
+SubtypeList ::= SEQUENCE OF Subtype
+
+SubtypeValue ::= CHOICE
+{
+    singleValue       [0] IMPLICIT Value,
+    contained         [1] IMPLICIT Type,
+    valueRange        [2] IMPLICIT ValueRangeSubtype,
+    permittedAlphabet [3] Subtype, -- only valuerange or singleval
+    sizeConstraint    [4] Subtype, -- only single value ints or val range
+    innerSubtype      [5] IMPLICIT InnerSubtype
+}
+
+
+ValueRangeSubtype ::= SEQUENCE
+{
+    lowerEndInclusive BOOLEAN,
+    upperEndInclusive BOOLEAN,
+    lowerEndValue Value,
+    upperEndValue Value
+}
+
+
+InnerSubtype ::= SEQUENCE
+{
+    constraintType ENUMERATED { full-ct(0), partial-ct(1), single-ct(2) },
+    constraints ConstraintList
+}
+
+ConstraintList ::= SEQUENCE OF Constraint
+
+Constraint ::= SEQUENCE
+{
+    fieldRef MyString,  -- not used if in single-ct, may be null
+    presenceConstraint ENUMERATED
+    {
+        present-ct(0),
+        absent-ct(1),
+        empty-ct(2),
+        optional-ct(3)
+    },
+    valueConstraints Subtype
+}
+
+
+ValueDefList ::= SEQUENCE OF ValueDef
+
+
+ValueDef ::= SEQUENCE
+{
+   exported    BOOLEAN,
+   definedName MyString,
+   value       Value
+}
+
+Value ::= SEQUENCE
+{
+    type    Type OPTIONAL,
+    valueType  INTEGER,  -- holds one of choiceId's def'd for BasicType
+    basicValue BasicValue,
+    lineNo     INTEGER
+}
+
+BasicValue ::= CHOICE
+{
+    unknown          [0]  IMPLICIT NULL,
+    empty            [1]  IMPLICIT NULL,
+    integer          [2]  IMPLICIT INTEGER,
+    specialInteger   [3]  IMPLICIT SpecialIntegerValue,
+    longInteger      [4]  IMPLICIT INTEGER,  -- put LONG before INTGEGER
+    boolean          [5]  IMPLICIT BOOLEAN,
+    real             [6]  IMPLICIT REAL,
+    specialReal      [7]  IMPLICIT SpecialRealValue,
+    asciiText        [8]  IMPLICIT OCTET STRING,
+    asciiHex         [9]  IMPLICIT OCTET STRING,
+    asciiBitString   [10] IMPLICIT OCTET STRING,
+    oid              [11] IMPLICIT OBJECT IDENTIFIER,
+    linkedOid        [12] IMPLICIT OBJECT IDENTIFIER, --snacc cTypeName:"OID"
+    berValue         [13] IMPLICIT OCTET STRING,
+    perValue         [14] IMPLICIT OCTET STRING,
+    namedValue       [15] IMPLICIT NamedValue,
+    null             [16] IMPLICIT NULL,
+    localValueRef    [17] IMPLICIT ValueRef,
+    importValueRef   [18] IMPLICIT ValueRef,
+    valueNotation    [19] IMPLICIT OCTET STRING
+}
+
+
+
+SpecialIntegerValue ::= ENUMERATED { min-int(0), max-int(1) }
+SpecialRealValue ::= ENUMERATED { minus-infinity-real(0), plus-infinity-real(1) }
+
+
+ValueRef ::= SEQUENCE
+{
+    valueName  MyString,
+    moduleName MyString, -- used for "modname.value" refs (may be null)
+    link       ValueDef, --snacc isEncDec:"FALSE"
+    module     Module    --snacc isEncDec:"FALSE"
+}
+
+NamedValue ::= SEQUENCE
+{
+   fieldName MyString, -- may be null
+   value     Value
+}
+
+NamedValueList ::= SEQUENCE OF NamedValue
+
+CTypeId  ::= ENUMERATED { c-choice(0), c-list(1), c-any(2), c-anydefinedby(3),
+                          c-lib(4), c-struct(5), c-typeref(6), c-no-type(7),
+                         c-typedef(8) }
+
+-- C Type Def Info - info used for routine naming
+-- and referencing from other types
+CTDI ::= SEQUENCE
+{
+    asn1TypeId         INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId"
+    cTypeId            CTypeId,
+    cTypeName          MyString,
+    isPdu              BOOLEAN,
+    isEncDec           BOOLEAN, -- if false, no routines are gen
+                                -- and not included in encodings
+    isPtrForTypeDef    BOOLEAN,
+    isPtrForTypeRef    BOOLEAN,
+    isPtrInChoice      BOOLEAN,
+    isPtrForOpt        BOOLEAN,
+
+               -- defines these names, used by references
+    optTestRoutineName MyString, -- routine/macro to check whether
+                                 -- opt type is present
+    defaultFieldName   MyString, -- base for generating field names
+
+    printRoutineName   MyString,
+    encodeRoutineName  MyString,
+    decodeRoutineName  MyString,
+    freeRoutineName    MyString,
+
+    genPrintRoutine    BOOLEAN,
+    genEncodeRoutine   BOOLEAN,
+    genDecodeRoutine   BOOLEAN,
+    genFreeRoutine     BOOLEAN,
+    genTypeDef         BOOLEAN
+}
+
+
+--
+-- CTRI (C Type Ref Info) is used for generating C typedefinitions
+-- from the ASN.1 types info
+CTRI ::= SEQUENCE
+{
+    cTypeId CTypeId,
+    cFieldName MyString,
+    cTypeName  MyString,
+    isPtr BOOLEAN,
+--    isEndCType BOOLEAN,        false for struct/union def --
+    cNamedElmts CNamedElmts OPTIONAL,      -- for C_LIB bits/int/enums
+    choiceIdValue INTEGER,     -- enum value of this c field
+    choiceIdSymbol MyString,   -- this fields sym in choiceId enum
+    choiceIdEnumName MyString,
+    choiceIdEnumFieldName MyString,
+    optTestRoutineName MyString, -- these names are gained from refd type def
+    printRoutineName   MyString,   -- or are over-ridden snacc attribute comment
+    encodeRoutineName  MyString,
+    decodeRoutineName  MyString,
+    freeRoutineName    MyString,
+    isEncDec           BOOLEAN -- whether part of enc value
+}
+
+CNamedElmts ::= SEQUENCE OF CNamedElmt
+
+CNamedElmt ::= SEQUENCE
+{
+    name MyString,
+    value INTEGER
+}
+
+
+CxxTDI ::= SEQUENCE
+{
+    asn1TypeId         INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId"
+    className          MyString,
+    isPdu              BOOLEAN,
+    isEnc              BOOLEAN,
+    isPtrForTypeDef    BOOLEAN,
+    isPtrForOpt        BOOLEAN,
+    isPtrInChoice      BOOLEAN,
+    isPtrInSetAndSeq   BOOLEAN,
+    isPtrInList        BOOLEAN,
+    optTestRoutineName MyString,
+    defaultFieldName   MyString -- base for generating field names
+}
+
+
+
+CxxTRI ::= SEQUENCE
+{
+    isEnc BOOLEAN,
+    className MyString,
+    fieldName MyString,
+    isPtr BOOLEAN,
+    namedElmts CNamedElmts,
+    choiceIdSymbol MyString,
+    choiceIdValue INTEGER,
+    optTestRoutineName MyString
+}
+
+IDLTDI ::= SEQUENCE
+{
+    asn1TypeId         INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId"
+    typeName           MyString,
+    isPdu              BOOLEAN,
+    isEnc              BOOLEAN,
+    isPtrForTypeDef    BOOLEAN,
+    isPtrForOpt        BOOLEAN,
+    isPtrInChoice      BOOLEAN,
+    isPtrInSetAndSeq   BOOLEAN,
+    isPtrInList        BOOLEAN,
+    optTestRoutineName MyString,
+    defaultFieldName   MyString -- base for generating field names
+}
+
+IDLTRI ::= SEQUENCE
+{
+    isEnc BOOLEAN,
+    typeName MyString,
+    fieldName MyString,
+    isPtr BOOLEAN,
+    namedElmts CNamedElmts,
+    choiceIdSymbol MyString,
+    choiceIdValue INTEGER,
+    optTestRoutineName MyString
+}
+
+-- use snacc compiler directives to overide the builtin types.
+--
+-- All strings used in module data struct are null terminated so
+-- can just use a char*
+-- Note the snacc comments before the PrintableString
+-- bind with the MyString TypeDef and the ones after PrintableString
+-- bind with the PrintableString Type ref.
+
+
+MyString ::= --snacc isPtrForTypeDef:"FALSE"
+             --snacc isPtrForTypeRef:"FALSE"
+             --snacc isPtrInChoice:"FALSE"
+             --snacc isPtrForOpt:"FALSE"
+             --snacc optTestRoutineName:"MYSTRING_NON_NULL"
+             --snacc genPrintRoutine:"FALSE"
+             --snacc genEncodeRoutine:"FALSE"
+             --snacc genDecodeRoutine:"FALSE"
+             --snacc genFreeRoutine:"FALSE"
+             --snacc printRoutineName:"printMyString"
+             --snacc encodeRoutineName:"EncMyString"
+             --snacc decodeRoutineName:"DecMyString"
+             --snacc freeRoutineName:"FreeMyString"
+             PrintableString --snacc cTypeName:"char*"
+
+END
diff --git a/SecuritySNACCRuntime/asn1specs/err-test.asn1 b/SecuritySNACCRuntime/asn1specs/err-test.asn1
new file mode 100644
index 00000000..3f7a5b68
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/err-test.asn1
@@ -0,0 +1,237 @@
+-- .../asn1specs/err_test.asn1
+--
+-- This module exercises snacc's semantic error checking of ASN.1 types.
+-- Every line that has the "error" comment should cause snacc to produce
+-- at least one error message
+--
+-- Mike Sample 92/07
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/err-test.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: err-test.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:55  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.3  1995/07/25 19:53:16  rj
+-- changed `_' to `-' in file names.
+--
+-- Revision 1.2  1994/08/28  09:54:17  rj
+-- comment leader fixed.
+--
+-- Revision 1.1  1994/08/28  09:51:13  rj
+-- first check-in.
+
+ERROR-TEST DEFINITIONS ::=
+BEGIN
+
+
+-- first check that CHOICEs and SETs  without distinct tags
+-- cause error msgs
+
+AChoice ::= CHOICE -- error
+{
+    f1 [0] INTEGER,  -- these two have the same
+    f2 [0] INTEGER,  -- tags
+    f3 INTEGER,      -- the tag of f3
+    f4 AChoice3      -- conflicts with one of AChoice3's elmt tags
+}
+
+ASet ::= SET  -- error
+{
+    f1 [0] INTEGER, -- same [0] tags
+    f2 [0] INTEGER
+}
+
+
+T1 ::= INTEGER
+T2 ::= BOOLEAN
+
+AChoice2 ::= CHOICE  -- error
+{
+   T1,
+   INTEGER
+}
+
+ASet2 ::= SET  -- error
+{
+   T2,
+   BOOLEAN
+}
+
+AChoice3 ::= CHOICE
+{
+   T1,
+   T2
+}
+
+
+--
+-- now check that Sequence have distinct tags
+-- on one or consective optional elmts and following (if any)
+-- non-optional elmt
+--
+
+ASequence ::= SEQUENCE  -- no errors
+{
+    f1 [0] INTEGER,
+    f2 [0] BOOLEAN
+}
+
+ASequence1 ::= SEQUENCE
+{
+    INTEGER OPTIONAL,
+    INTEGER OPTIONAL, -- error,  ambiguous values possible
+    INTEGER,          -- error
+    INTEGER
+}
+
+ASequence3 ::= SEQUENCE
+{
+    f1 [0] OBJECT IDENTIFIER OPTIONAL,
+    f2 [1] INTEGER OPTIONAL,
+    f3 [0] BOOLEAN,            -- error
+    f4 [2] OCTET STRING OPTIONAL,
+    f5 [2] BIT STRING OPTIONAL, -- error
+    f6 [3] ASequence OPTIONAL,
+    f7 [3] INTEGER,  -- error
+    f8 [4] BOOLEAN OPTIONAL,
+    f9 [4] INTEGER OPTIONAL  -- error
+}
+
+
+
+--
+-- now check that duplicate APPLICATION tag errors are reported
+--
+Foo1 ::= [APPLICATION 0] INTEGER
+Foo2 ::= [APPLICATION 1] INTEGER
+
+Bar1 ::= [APPLICATION 0] IMPLICIT INTEGER  -- error
+Bar2 ::= [APPLICATION 1] IMPLICIT INTEGER  -- error
+
+--
+-- check that field name errors are reported
+--
+
+AChoice4 ::= CHOICE
+{
+   f1 INTEGER,
+   f2 BOOLEAN,
+    [0] AChoice4
+}
+
+ASet3 ::= SET
+{
+   f1 [0] INTEGER,
+   f2 [1] INTEGER,
+   f3 [2] BOOLEAN,
+   f3 [3] BOOLEAN,  -- error, field name conflict
+      [4] AChoice4  -- error, field name conflict too
+}
+
+
+--
+-- now check some recursive type related errors
+--
+
+A2 ::= A2  -- error
+
+A1 ::= B1  -- error
+B1 ::= A1  -- error
+
+C1 ::= D1  -- error
+D1 ::= E1  -- error
+E1 ::= F1  -- error
+F1 ::= C1  -- error
+
+RecSeq ::= SEQUENCE
+{
+     INTEGER,
+     BOOLEAN,
+     RecSeq,  -- warning, infinitely large values?
+     RecSeq OPTIONAL -- this should be ok 'cause it's optional
+}
+
+
+--
+-- now check some named bit and named number related errors
+--
+aVal  INTEGER ::= -4
+
+Enum1 ::= ENUMERATED { zero(0), one(1), two(2), one(0) } -- 2 errors
+
+Int1 ::= INTEGER { zero(0), one(1), two(2), yoyo(2), one(7), foo(aVal) } -- 2 errors
+
+Bits1 ::= BIT STRING { zero(0), one(1), two(2), one(4), foo(-2), pogo(0),
+                       gogo(aVal) }  -- 4 errors
+
+
+
+--
+-- now check that implicitly tagged CHOICE, ANY and ANY DEFINED BY
+-- cause error msgs
+--
+BChoice1 ::= [APPLICATION 5] IMPLICIT CHOICE  -- error
+{
+    INTEGER,
+    BOOLEAN
+}
+
+BChoice2 ::= CHOICE -- no error
+{
+    INTEGER,
+    BOOLEAN
+}
+
+BChoice3 ::= [APPLICATION 6] CHOICE -- no error
+{
+    INTEGER,
+    BOOLEAN
+}
+
+BSeq ::= SEQUENCE
+{
+    INTEGER,
+    BOOLEAN,
+    [0] IMPLICIT BChoice2, -- error
+    [1] IMPLICIT BChoice3, -- no error
+    [2] IMPLICIT CHOICE {INTEGER, BOOLEAN} -- error
+}
+
+
+--
+-- now test that errors are reported for multiply defined
+-- types and valus
+--
+
+TypeCopy1 ::= INTEGER
+TypeCopy1 ::= BOOLEAN
+TypeCopy1 ::= INTEGER
+
+valCopy1 INTEGER ::= 1
+valCopy1 BOOLEAN ::= TRUE
+valCopy1 INTEGER ::= 1
+
+
+--
+--  test some OBJECT IDENTIFER value errors
+--
+
+oid1 OBJECT IDENTIFIER ::= { oid1 ms(1) 1 } -- error: recursive value
+oid2 OBJECT IDENTIFIER ::= { oid1 ms(1) 2 }
+
+ -- error: can only ref other oid values from first arc
+oid3 OBJECT IDENTIFIER ::= { ms(1) oid2 2 }
+
+boolVal BOOLEAN ::= TRUE
+intVal1 INTEGER ::= 1
+intVal2 INTEGER ::= -1
+oid4 OBJECT IDENTIFIER ::= { oid2 intVal1 intVal2 boolVal 1}
+
+oid5 OBJECT IDENTIFIER ::= { 1 2 -4}
+
+oid6 OBJECT IDENTIFIER ::= { oid7 1}
+oid7 OBJECT IDENTIFIER ::= { oid6 1 }
+END
diff --git a/SecuritySNACCRuntime/asn1specs/ex1.asn1 b/SecuritySNACCRuntime/asn1specs/ex1.asn1
new file mode 100644
index 00000000..36c9936d
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/ex1.asn1
@@ -0,0 +1,40 @@
+-- file: .../asn1specs/ex1.asn1
+--
+--  This is an example ASN.1 module used in the documentation
+--
+--  MS 92
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/ex1.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: ex1.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:55  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.2  1997/02/16 20:25:22  rj
+-- check-in of a few cosmetic changes
+--
+-- Revision 1.1  1994/10/08  05:41:32  rj
+-- initial check-in.
+--
+
+EX1 DEFINITIONS ::=
+BEGIN
+
+anOidVal      OBJECT IDENTIFIER ::= { joint-iso-ccitt 40 foobar(29) }
+theSameOidVal OBJECT IDENTIFIER ::= { 2 40 29 }
+anIntVal      INTEGER ::= 1
+aBoolVal      BOOLEAN ::= TRUE
+
+T1 ::= SEQUENCE
+{
+   INTEGER OPTIONAL,
+   OCTET STRING OPTIONAL,
+   ENUMERATED { a(0), b(1), c(2) },
+   SEQUENCE OF INTEGER,
+   SEQUENCE { id OBJECT IDENTIFIER, value OCTET STRING },
+   CHOICE { INTEGER, OBJECT IDENTIFIER }
+}
+
+END
diff --git a/SecuritySNACCRuntime/asn1specs/install-sh b/SecuritySNACCRuntime/asn1specs/install-sh
new file mode 100644
index 00000000..ab74c882
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/SecuritySNACCRuntime/asn1specs/makefile b/SecuritySNACCRuntime/asn1specs/makefile
new file mode 100644
index 00000000..3e8b37ac
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/makefile
@@ -0,0 +1,47 @@
+# .../asn1specs/makefile
+
+include ../makehead
+
+TOP	= ..
+
+ASN1FILES = \
+	rfc1155-smi.asn1	\
+	rfc1157-snmp.asn1	\
+	rfc1213-mib2.asn1	\
+	any.asn1		\
+	asn1module.asn1		\
+	err-test.asn1		\
+	ex1.asn1		\
+	p-rec.asn1		\
+	tbl.asn1		\
+	asn-useful.asn1
+
+DISTFILES = \
+	makefile	\
+	$(ASN1FILES)
+
+#-------------------------------------------------------------------------------
+
+.PHONY:	depend install distfiles clean clobber
+
+install-sh:
+		ln $(TOP)/install-sh $@
+
+$(incdir)/snacc/asn1:
+		$(TOP)/mkinstalldirs $@
+
+install::	$(ASN1FILES) install-sh $(incdir)/snacc/asn1
+
+install::
+		for a in $(ASN1FILES); do $(INSTALL_DATA) $$a $(incdir)/snacc/asn1/; done
+
+gen-distfiles::	$(DISTFILES)
+
+distfiles::
+		@echo $(DISTFILES)
+
+# dummies:
+depend clean::
+
+clobber::
+		$(RM) install-sh
diff --git a/SecuritySNACCRuntime/asn1specs/p-rec.asn1 b/SecuritySNACCRuntime/asn1specs/p-rec.asn1
new file mode 100644
index 00000000..8f95b0e4
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/p-rec.asn1
@@ -0,0 +1,56 @@
+-- file: .../asn1specs/p_rec.asn1
+--
+-- this file is used in ../c{,++}-examples/simple/
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/p-rec.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: p-rec.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:56  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.3  1997/09/16 14:55:30  wan
+-- Added test for "tag dividable by 128" case.
+--
+-- Revision 1.2  1995/07/25 19:53:17  rj
+-- changed `_' to `-' in file names.
+--
+-- Revision 1.1  1994/08/31  23:05:47  rj
+-- first check-in.
+--
+
+P-REC DEFINITIONS ::=
+BEGIN
+
+
+PersonnelRecord ::= --snacc isPdu:"TRUE" -- [APPLICATION 0] IMPLICIT SET
+{
+                     Name,
+    title        [0] IA5String,
+                     EmployeeNumber,
+    dateOfHire   [1] Date,
+    nameOfSpouse [2] Name,
+    children     [3] IMPLICIT SEQUENCE OF ChildInformation DEFAULT {}
+}
+
+ChildInformation ::= SET
+{
+                    Name,
+    dateOfBirth [0] Date
+}
+
+Name ::= [APPLICATION 1] IMPLICIT SEQUENCE
+{
+    givenName  IA5String,
+    initial    IA5String,
+    familyName IA5String
+}
+
+EmployeeNumber ::= [APPLICATION 128] IMPLICIT INTEGER
+
+Date ::= [APPLICATION 3] IMPLICIT IA5String -- YYYYMMDD
+
+
+
+END
diff --git a/SecuritySNACCRuntime/asn1specs/rfc1155-smi.asn1 b/SecuritySNACCRuntime/asn1specs/rfc1155-smi.asn1
new file mode 100644
index 00000000..0241d6b9
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/rfc1155-smi.asn1
@@ -0,0 +1,155 @@
+-- file: asn1specs/1155_smi.asn1
+--
+-- this file is used in ../c{,++}-examples/snmp/
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/rfc1155-smi.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: rfc1155-smi.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:56  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.3  1995/07/27 08:29:16  rj
+-- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme.
+--
+-- Revision 1.2  1995/07/25  19:53:12  rj
+-- changed `_' to `-' in file names.
+--
+-- Revision 1.1  1994/08/31  23:08:26  rj
+-- first check-in.
+--
+
+RFC1155-SMI DEFINITIONS ::= BEGIN
+
+           EXPORTS -- EVERYTHING
+                   internet, directory, mgmt,
+                   experimental, private, enterprises,
+                   OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax,
+                   ApplicationSyntax, NetworkAddress, IpAddress,
+                   Counter, Gauge, TimeTicks, Opaque;
+
+            -- the path to the root
+
+            internet      OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }
+
+            directory     OBJECT IDENTIFIER ::= { internet 1 }
+
+            mgmt          OBJECT IDENTIFIER ::= { internet 2 }
+
+            experimental  OBJECT IDENTIFIER ::= { internet 3 }
+
+            private       OBJECT IDENTIFIER ::= { internet 4 }
+            enterprises   OBJECT IDENTIFIER ::= { private 1 }
+
+
+            -- definition of object types
+
+            OBJECT-TYPE MACRO ::=
+            BEGIN
+                TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax)
+                                  "ACCESS" Access
+                                  "STATUS" Status
+                VALUE NOTATION ::= value (VALUE ObjectName)
+
+                Access ::= "read-only"
+                                | "read-write"
+                                | "write-only"
+                                | "not-accessible"
+                Status ::= "mandatory"
+                                | "optional"
+                                | "obsolete"
+            END
+
+               -- names of objects in the MIB
+
+               ObjectName ::=
+                   OBJECT IDENTIFIER
+
+
+
+
+
+               -- syntax of objects in the MIB
+
+               ObjectSyntax ::=
+                   CHOICE {
+                       simple
+                           SimpleSyntax,
+
+               -- note that simple SEQUENCEs are not directly
+               -- mentioned here to keep things simple (i.e.,
+               -- prevent mis-use).  However, application-wide
+               -- types which are IMPLICITly encoded simple
+               -- SEQUENCEs may appear in the following CHOICE
+
+                       application-wide
+                           ApplicationSyntax
+                   }
+
+                  SimpleSyntax ::=
+                      CHOICE {
+                          number
+                              INTEGER,
+
+                          string
+                              OCTET STRING,
+
+                          object
+                              OBJECT IDENTIFIER,
+
+                          empty
+                              NULL
+                      }
+
+                  ApplicationSyntax ::=
+                      CHOICE {
+                          address
+                              NetworkAddress,
+
+                          counter
+                              Counter,
+
+                          gauge
+                              Gauge,
+
+                          ticks
+                              TimeTicks,
+
+                          arbitrary
+                              Opaque
+
+                  -- other application-wide types, as they are
+                  -- defined, will be added here
+                      }
+
+
+                  -- application-wide types
+
+                  NetworkAddress ::=
+                      CHOICE {
+                          internet
+                              IpAddress
+                      }
+
+                  IpAddress ::=
+                      [APPLICATION 0]          -- in network-byte order
+                          IMPLICIT OCTET STRING (SIZE (4))
+
+                  Counter ::=
+                      [APPLICATION 1]
+                          IMPLICIT INTEGER (0..4294967295)
+
+                  Gauge ::=
+                      [APPLICATION 2]
+                          IMPLICIT INTEGER (0..4294967295)
+
+                  TimeTicks ::=
+                      [APPLICATION 3]
+                          IMPLICIT INTEGER (0..4294967295)
+
+                  Opaque ::=
+                      [APPLICATION 4]          -- arbitrary ASN.1 value,
+                          IMPLICIT OCTET STRING   --   "double-wrapped"
+
+                  END
diff --git a/SecuritySNACCRuntime/asn1specs/rfc1157-snmp.asn1 b/SecuritySNACCRuntime/asn1specs/rfc1157-snmp.asn1
new file mode 100644
index 00000000..b2e279fe
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/rfc1157-snmp.asn1
@@ -0,0 +1,166 @@
+-- file: asn1specs/1157_snmp.asn1
+--
+-- this file is used in ../c{,++}-examples/snmp/
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/rfc1157-snmp.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: rfc1157-snmp.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:56  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.3  1995/07/27 08:29:17  rj
+-- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme.
+--
+-- Revision 1.2  1995/07/25  19:53:13  rj
+-- changed `_' to `-' in file names.
+--
+-- Revision 1.1  1994/08/31  23:08:27  rj
+-- first check-in.
+--
+
+RFC1157-SNMP DEFINITIONS ::= BEGIN
+
+      IMPORTS
+          ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks
+              FROM RFC1155-SMI;
+
+
+          -- top-level message
+
+          Message ::=
+                  SEQUENCE {
+                      version          -- version-1 for this RFC
+                          INTEGER {
+                              version-1(0)
+                          },
+
+                      community        -- community name
+                          OCTET STRING,
+
+                      data             -- e.g., PDUs if trivial
+                          PDUs          -- authentication is being used
+                  }
+
+
+          -- protocol data units
+
+          PDUs ::=
+                  CHOICE {
+                              get-request
+                                  GetRequest-PDU,
+
+                              get-next-request
+                                  GetNextRequest-PDU,
+
+                              get-response
+                                  GetResponse-PDU,
+
+                              set-request
+                                  SetRequest-PDU,
+
+                              trap
+                                  Trap-PDU
+                          }
+
+
+
+
+
+          -- PDUs
+
+          GetRequest-PDU ::=
+              [0]
+                  IMPLICIT PDU
+
+          GetNextRequest-PDU ::=
+              [1]
+                  IMPLICIT PDU
+
+          GetResponse-PDU ::=
+              [2]
+                  IMPLICIT PDU
+
+          SetRequest-PDU ::=
+              [3]
+                  IMPLICIT PDU
+
+          PDU ::=
+                  SEQUENCE {
+                     request-id
+                          INTEGER,
+
+                      error-status      -- sometimes ignored
+                          INTEGER {
+                              noError(0),
+                              tooBig(1),
+                              noSuchName(2),
+                              badValue(3),
+                              readOnly(4),
+                              genErr(5)
+                          },
+
+                      error-index       -- sometimes ignored
+                         INTEGER,
+
+                      variable-bindings -- values are sometimes ignored
+                          VarBindList
+                  }
+
+          Trap-PDU ::=
+              [4]
+                 IMPLICIT SEQUENCE {
+                      enterprise        -- type of object generating
+                                        -- trap, see sysObjectID in [5]
+
+
+                          OBJECT IDENTIFIER,
+
+
+
+                      agent-addr        -- address of object generating
+                          NetworkAddress, -- trap
+
+                      generic-trap      -- generic trap type
+                          INTEGER {
+                              coldStart(0),
+                              warmStart(1),
+                              linkDown(2),
+                              linkUp(3),
+                              authenticationFailure(4),
+                              egpNeighborLoss(5),
+                              enterpriseSpecific(6)
+                          },
+
+                      specific-trap  -- specific code, present even
+                          INTEGER,   -- if generic-trap is not
+                                     -- enterpriseSpecific
+
+                      time-stamp     -- time elapsed between the last
+                          TimeTicks, -- (re)initialization of the
+                                     -- network
+                                     -- entity and the generation of the
+                                     -- trap
+
+                       variable-bindings -- "interesting" information
+                          VarBindList
+                  }
+
+
+          -- variable bindings
+
+          VarBind ::=
+                  SEQUENCE {
+                      name
+                          ObjectName,
+
+                      value
+                          ObjectSyntax
+                  }
+
+         VarBindList ::=
+                  SEQUENCE OF
+                     VarBind
+
+END
diff --git a/SecuritySNACCRuntime/asn1specs/rfc1213-mib2.asn1 b/SecuritySNACCRuntime/asn1specs/rfc1213-mib2.asn1
new file mode 100644
index 00000000..c57a3a58
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/rfc1213-mib2.asn1
@@ -0,0 +1,2663 @@
+-- file: asn1specs/1213_mib2.asn1
+--
+-- this file is used in ../c{,++}-examples/snmp/
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/rfc1213-mib2.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: rfc1213-mib2.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:56  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.3  1995/07/27 08:29:19  rj
+-- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme.
+--
+-- Revision 1.2  1995/07/25  19:53:14  rj
+-- changed `_' to `-' in file names.
+--
+-- Revision 1.1  1994/08/31  23:08:28  rj
+-- first check-in.
+--
+
+RFC1213-MIB DEFINITIONS ::= BEGIN
+
+          IMPORTS
+                  mgmt, NetworkAddress, IpAddress, Counter, Gauge,
+                          TimeTicks
+                      FROM RFC1155-SMI
+
+--                  OBJECT-TYPE
+--                          FROM RFC-1212
+
+        ;
+
+          --  This MIB module uses the extended OBJECT-TYPE macro as
+          --  defined in [14];
+
+
+          --  MIB-II (same prefix as MIB-I)
+
+          mib-2      OBJECT IDENTIFIER ::= { mgmt 1 }
+
+          -- textual conventions
+
+          DisplayString ::=
+              OCTET STRING
+          -- This data type is used to model textual information taken
+          -- from the NVT ASCII character set.  By convention, objects
+          -- with this syntax are declared as having
+          --      SIZE (0..255)
+
+          PhysAddress ::=
+              OCTET STRING
+          -- This data type is used to model media addresses.  For many
+          -- types of media, this will be in a binary representation.
+          -- For example, an ethernet address would be represented as
+          -- a string of 6 octets.
+
+
+          -- groups in MIB-II
+
+          system       OBJECT IDENTIFIER ::= { mib-2 1 }
+
+          interfaces   OBJECT IDENTIFIER ::= { mib-2 2 }
+
+          at           OBJECT IDENTIFIER ::= { mib-2 3 }
+
+          ip           OBJECT IDENTIFIER ::= { mib-2 4 }
+
+          icmp         OBJECT IDENTIFIER ::= { mib-2 5 }
+
+          tcp          OBJECT IDENTIFIER ::= { mib-2 6 }
+
+          udp          OBJECT IDENTIFIER ::= { mib-2 7 }
+
+          egp          OBJECT IDENTIFIER ::= { mib-2 8 }
+
+          -- historical (some say hysterical)
+          -- cmot      OBJECT IDENTIFIER ::= { mib-2 9 }
+
+          transmission OBJECT IDENTIFIER ::= { mib-2 10 }
+
+          snmp         OBJECT IDENTIFIER ::= { mib-2 11 }
+
+
+          -- the System group
+
+          -- Implementation of the System group is mandatory for all
+          -- systems.  If an agent is not configured to have a value
+          -- for any of these variables, a string of length 0 is
+          -- returned.
+
+          sysDescr OBJECT-TYPE
+              SYNTAX  DisplayString (SIZE (0..255))
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "A textual description of the entity.  This value
+                      should include the full name and version
+                      identification of the system's hardware type,
+                      software operating-system, and networking
+                      software.  It is mandatory that this only contain
+                      printable ASCII characters."
+              ::= { system 1 }
+
+          sysObjectID OBJECT-TYPE
+              SYNTAX  OBJECT IDENTIFIER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The vendor's authoritative identification of the
+                      network management subsystem contained in the
+                      entity.  This value is allocated within the SMI
+                      enterprises subtree (1.3.6.1.4.1) and provides an
+                      easy and unambiguous means for determining `what
+                      kind of box' is being managed.  For example, if
+                      vendor `Flintstones, Inc.' was assigned the
+                      subtree 1.3.6.1.4.1.4242, it could assign the
+                      identifier 1.3.6.1.4.1.4242.1.1 to its `Fred
+                      Router'."
+              ::= { system 2 }
+
+          sysUpTime OBJECT-TYPE
+              SYNTAX  TimeTicks
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The time (in hundredths of a second) since the
+                      network management portion of the system was last
+                      re-initialized."
+              ::= { system 3 }
+
+          sysContact OBJECT-TYPE
+              SYNTAX  DisplayString (SIZE (0..255))
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The textual identification of the contact person
+                      for this managed node, together with information
+                      on how to contact this person."
+              ::= { system 4 }
+
+          sysName OBJECT-TYPE
+              SYNTAX  DisplayString (SIZE (0..255))
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "An administratively-assigned name for this
+                      managed node.  By convention, this is the node's
+                      fully-qualified domain name."
+              ::= { system 5 }
+
+          sysLocation OBJECT-TYPE
+              SYNTAX  DisplayString (SIZE (0..255))
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The physical location of this node (e.g.,
+                      `telephone closet, 3rd floor')."
+              ::= { system 6 }
+
+          sysServices OBJECT-TYPE
+              SYNTAX  INTEGER (0..127)
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "A value which indicates the set of services that
+                      this entity primarily offers.
+
+                      The value is a sum.  This sum initially takes the
+                      value zero, Then, for each layer, L, in the range
+                      1 through 7, that this node performs transactions
+                      for, 2 raised to (L - 1) is added to the sum.  For
+                      example, a node which performs primarily routing
+                      functions would have a value of 4 (2^(3-1)).  In
+                      contrast, a node which is a host offering
+                      application services would have a value of 72
+                      (2^(4-1) + 2^(7-1)).  Note that in the context of
+                      the Internet suite of protocols, values should be
+                      calculated accordingly:
+
+                           layer  functionality
+                               1  physical (e.g., repeaters)
+                               2  datalink/subnetwork (e.g., bridges)
+                               3  internet (e.g., IP gateways)
+                               4  end-to-end  (e.g., IP hosts)
+                               7  applications (e.g., mail relays)
+
+                      For systems including OSI protocols, layers 5 and
+                      6 may also be counted."
+              ::= { system 7 }
+
+
+
+          -- the Interfaces group
+
+          -- Implementation of the Interfaces group is mandatory for
+          -- all systems.
+
+          ifNumber OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of network interfaces (regardless of
+                      their current state) present on this system."
+              ::= { interfaces 1 }
+
+
+          -- the Interfaces table
+
+          -- The Interfaces table contains information on the entity's
+          -- interfaces.  Each interface is thought of as being
+          -- attached to a `subnetwork'.  Note that this term should
+          -- not be confused with `subnet' which refers to an
+          -- addressing partitioning scheme used in the Internet suite
+          -- of protocols.
+
+          ifTable OBJECT-TYPE
+              SYNTAX  SEQUENCE OF IfEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "A list of interface entries.  The number of
+                      entries is given by the value of ifNumber."
+              ::= { interfaces 2 }
+
+          ifEntry OBJECT-TYPE
+              SYNTAX  IfEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "An interface entry containing objects at the
+                      subnetwork layer and below for a particular
+                      interface."
+              INDEX   { ifIndex }
+              ::= { ifTable 1 }
+
+          IfEntry ::=
+              SEQUENCE {
+                  ifIndex
+                      INTEGER,
+                  ifDescr
+                      DisplayString,
+                  ifType
+                      INTEGER,
+                  ifMtu
+                      INTEGER,
+                  ifSpeed
+                      Gauge,
+                  ifPhysAddress
+                      PhysAddress,
+                  ifAdminStatus
+                      INTEGER,
+                  ifOperStatus
+                      INTEGER,
+                  ifLastChange
+                      TimeTicks,
+                  ifInOctets
+                      Counter,
+                  ifInUcastPkts
+                      Counter,
+                  ifInNUcastPkts
+                      Counter,
+                  ifInDiscards
+                      Counter,
+                  ifInErrors
+                      Counter,
+                  ifInUnknownProtos
+                      Counter,
+                  ifOutOctets
+                      Counter,
+                  ifOutUcastPkts
+                      Counter,
+                  ifOutNUcastPkts
+                      Counter,
+                  ifOutDiscards
+                      Counter,
+                  ifOutErrors
+                      Counter,
+                  ifOutQLen
+                      Gauge,
+                  ifSpecific
+                      OBJECT IDENTIFIER
+              }
+
+          ifIndex OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "A unique value for each interface.  Its value
+                      ranges between 1 and the value of ifNumber.  The
+                      value for each interface must remain constant at
+                      least from one re-initialization of the entity's
+                      network management system to the next re-
+                      initialization."
+              ::= { ifEntry 1 }
+
+          ifDescr OBJECT-TYPE
+              SYNTAX  DisplayString (SIZE (0..255))
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "A textual string containing information about the
+                      interface.  This string should include the name of
+                      the manufacturer, the product name and the version
+                      of the hardware interface."
+              ::= { ifEntry 2 }
+
+          ifType OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          other(1),          -- none of the following
+                          regular1822(2),
+                          hdh1822(3),
+                          ddn-x25(4),
+                          rfc877-x25(5),
+                          ethernet-csmacd(6),
+                          iso88023-csmacd(7),
+                          iso88024-tokenBus(8),
+                          iso88025-tokenRing(9),
+                          iso88026-man(10),
+                          starLan(11),
+                          proteon-10Mbit(12),
+                          proteon-80Mbit(13),
+                          hyperchannel(14),
+                          fddi(15),
+                          lapb(16),
+                          sdlc(17),
+                          ds1(18),           -- T-1
+                          e1(19),            -- european equiv. of T-1
+                          basicISDN(20),
+                          primaryISDN(21),   -- proprietary serial
+                          propPointToPointSerial(22),
+                          ppp(23),
+                          softwareLoopback(24),
+                          eon(25),            -- CLNP over IP [11]
+                          ethernet-3Mbit(26),
+                          nsip(27),           -- XNS over IP
+                          slip(28),           -- generic SLIP
+                          ultra(29),          -- ULTRA technologies
+                          ds3(30),            -- T-3
+                          sip(31),            -- SMDS
+                          frame-relay(32)
+                      }
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The type of interface, distinguished according to
+                      the physical/link protocol(s) immediately `below'
+                      the network layer in the protocol stack."
+              ::= { ifEntry 3 }
+
+          ifMtu OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The size of the largest datagram which can be
+                      sent/received on the interface, specified in
+                      octets.  For interfaces that are used for
+                      transmitting network datagrams, this is the size
+                      of the largest network datagram that can be sent
+                      on the interface."
+              ::= { ifEntry 4 }
+
+          ifSpeed OBJECT-TYPE
+              SYNTAX  Gauge
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "An estimate of the interface's current bandwidth
+                      in bits per second.  For interfaces which do not
+                      vary in bandwidth or for those where no accurate
+                      estimation can be made, this object should contain
+                      the nominal bandwidth."
+              ::= { ifEntry 5 }
+
+          ifPhysAddress OBJECT-TYPE
+              SYNTAX  PhysAddress
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The interface's address at the protocol layer
+                      immediately `below' the network layer in the
+                      protocol stack.  For interfaces which do not have
+                      such an address (e.g., a serial line), this object
+                      should contain an octet string of zero length."
+              ::= { ifEntry 6 }
+
+          ifAdminStatus OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          up(1),       -- ready to pass packets
+                          down(2),
+                          testing(3)   -- in some test mode
+                      }
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The desired state of the interface.  The
+                      testing(3) state indicates that no operational
+                      packets can be passed."
+              ::= { ifEntry 7 }
+
+          ifOperStatus OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          up(1),       -- ready to pass packets
+                          down(2),
+                          testing(3)   -- in some test mode
+                      }
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The current operational state of the interface.
+                      The testing(3) state indicates that no operational
+                      packets can be passed."
+              ::= { ifEntry 8 }
+
+          ifLastChange OBJECT-TYPE
+              SYNTAX  TimeTicks
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The value of sysUpTime at the time the interface
+                      entered its current operational state.  If the
+                      current state was entered prior to the last re-
+                      initialization of the local network management
+                      subsystem, then this object contains a zero
+                      value."
+              ::= { ifEntry 9 }
+
+          ifInOctets OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of octets received on the
+                      interface, including framing characters."
+              ::= { ifEntry 10 }
+
+          ifInUcastPkts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of subnetwork-unicast packets
+                      delivered to a higher-layer protocol."
+              ::= { ifEntry 11 }
+
+          ifInNUcastPkts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of non-unicast (i.e., subnetwork-
+                      broadcast or subnetwork-multicast) packets
+                      delivered to a higher-layer protocol."
+              ::= { ifEntry 12 }
+
+          ifInDiscards OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of inbound packets which were chosen
+                      to be discarded even though no errors had been
+                      detected to prevent their being deliverable to a
+                      higher-layer protocol.  One possible reason for
+                      discarding such a packet could be to free up
+                      buffer space."
+              ::= { ifEntry 13 }
+
+          ifInErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of inbound packets that contained
+                      errors preventing them from being deliverable to a
+                      higher-layer protocol."
+              ::= { ifEntry 14 }
+
+
+          ifInUnknownProtos OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of packets received via the interface
+                      which were discarded because of an unknown or
+                      unsupported protocol."
+              ::= { ifEntry 15 }
+
+          ifOutOctets OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of octets transmitted out of the
+                      interface, including framing characters."
+              ::= { ifEntry 16 }
+
+          ifOutUcastPkts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of packets that higher-level
+                      protocols requested be transmitted to a
+                      subnetwork-unicast address, including those that
+                      were discarded or not sent."
+              ::= { ifEntry 17 }
+
+          ifOutNUcastPkts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of packets that higher-level
+                      protocols requested be transmitted to a non-
+                      unicast (i.e., a subnetwork-broadcast or
+                      subnetwork-multicast) address, including those
+                      that were discarded or not sent."
+              ::= { ifEntry 18 }
+
+          ifOutDiscards OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of outbound packets which were chosen
+                      to be discarded even though no errors had been
+                      detected to prevent their being transmitted.  One
+                      possible reason for discarding such a packet could
+                      be to free up buffer space."
+              ::= { ifEntry 19 }
+
+          ifOutErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of outbound packets that could not be
+                      transmitted because of errors."
+              ::= { ifEntry 20 }
+
+          ifOutQLen OBJECT-TYPE
+              SYNTAX  Gauge
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The length of the output packet queue (in
+                      packets)."
+              ::= { ifEntry 21 }
+
+          ifSpecific OBJECT-TYPE
+              SYNTAX  OBJECT IDENTIFIER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "A reference to MIB definitions specific to the
+                      particular media being used to realize the
+                      interface.  For example, if the interface is
+                      realized by an ethernet, then the value of this
+                      object refers to a document defining objects
+                      specific to ethernet.  If this information is not
+                      present, its value should be set to the OBJECT
+                      IDENTIFIER { 0 0 }, which is a syntatically valid
+                      object identifier, and any conformant
+                      implementation of ASN.1 and BER must be able to
+                      generate and recognize this value."
+              ::= { ifEntry 22 }
+
+
+          -- the Address Translation group
+
+          -- Implementation of the Address Translation group is
+          -- mandatory for all systems.  Note however that this group
+          -- is deprecated by MIB-II. That is, it is being included
+          -- solely for compatibility with MIB-I nodes, and will most
+          -- likely be excluded from MIB-III nodes.  From MIB-II and
+          -- onwards, each network protocol group contains its own
+          -- address translation tables.
+
+          -- The Address Translation group contains one table which is
+          -- the union across all interfaces of the translation tables
+          -- for converting a NetworkAddress (e.g., an IP address) into
+          -- a subnetwork-specific address.  For lack of a better term,
+          -- this document refers to such a subnetwork-specific address
+          -- as a `physical' address.
+
+          -- Examples of such translation tables are: for broadcast
+          -- media where ARP is in use, the translation table is
+          -- equivalent to the ARP cache; or, on an X.25 network where
+          -- non-algorithmic translation to X.121 addresses is
+          -- required, the translation table contains the
+          -- NetworkAddress to X.121 address equivalences.
+
+          atTable OBJECT-TYPE
+              SYNTAX  SEQUENCE OF AtEntry
+              ACCESS  not-accessible
+              STATUS  deprecated
+              DESCRIPTION
+                      "The Address Translation tables contain the
+                      NetworkAddress to `physical' address equivalences.
+                      Some interfaces do not use translation tables for
+                      determining address equivalences (e.g., DDN-X.25
+                      has an algorithmic method); if all interfaces are
+                      of this type, then the Address Translation table
+                      is empty, i.e., has zero entries."
+              ::= { at 1 }
+
+          atEntry OBJECT-TYPE
+              SYNTAX  AtEntry
+              ACCESS  not-accessible
+              STATUS  deprecated
+              DESCRIPTION
+                      "Each entry contains one NetworkAddress to
+                      `physical' address equivalence."
+              INDEX   { atIfIndex,
+                        atNetAddress }
+              ::= { atTable 1 }
+
+          AtEntry ::=
+              SEQUENCE {
+                  atIfIndex
+                      INTEGER,
+                  atPhysAddress
+                      PhysAddress,
+                  atNetAddress
+                      NetworkAddress
+              }
+
+          atIfIndex OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  deprecated
+              DESCRIPTION
+                      "The interface on which this entry's equivalence
+                      is effective.  The interface identified by a
+                      particular value of this index is the same
+                      interface as identified by the same value of
+                      ifIndex."
+              ::= { atEntry 1 }
+
+          atPhysAddress OBJECT-TYPE
+              SYNTAX  PhysAddress
+              ACCESS  read-write
+              STATUS  deprecated
+              DESCRIPTION
+                      "The media-dependent `physical' address.
+
+                      Setting this object to a null string (one of zero
+                      length) has the effect of invaliding the
+                      corresponding entry in the atTable object.  That
+                      is, it effectively dissasociates the interface
+                      identified with said entry from the mapping
+                      identified with said entry.  It is an
+                      implementation-specific matter as to whether the
+                      agent removes an invalidated entry from the table.
+                      Accordingly, management stations must be prepared
+                      to receive tabular information from agents that
+                      corresponds to entries not currently in use.
+                      Proper interpretation of such entries requires
+                      examination of the relevant atPhysAddress object."
+              ::= { atEntry 2 }
+
+          atNetAddress OBJECT-TYPE
+              SYNTAX  NetworkAddress
+              ACCESS  read-write
+              STATUS  deprecated
+              DESCRIPTION
+                      "The NetworkAddress (e.g., the IP address)
+                      corresponding to the media-dependent `physical'
+                      address."
+              ::= { atEntry 3 }
+
+
+          -- the IP group
+
+          -- Implementation of the IP group is mandatory for all
+          -- systems.
+
+          ipForwarding OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          forwarding(1),    -- acting as a gateway
+                          not-forwarding(2) -- NOT acting as a gateway
+                      }
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The indication of whether this entity is acting
+                      as an IP gateway in respect to the forwarding of
+                      datagrams received by, but not addressed to, this
+                      entity.  IP gateways forward datagrams.  IP hosts
+                      do not (except those source-routed via the host).
+
+                      Note that for some managed nodes, this object may
+                      take on only a subset of the values possible.
+                      Accordingly, it is appropriate for an agent to
+                      return a `badValue' response if a management
+                      station attempts to change this object to an
+                      inappropriate value."
+              ::= { ip 1 }
+
+          ipDefaultTTL OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The default value inserted into the Time-To-Live
+                      field of the IP header of datagrams originated at
+                      this entity, whenever a TTL value is not supplied
+                      by the transport layer protocol."
+              ::= { ip 2 }
+
+          ipInReceives OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of input datagrams received from
+                      interfaces, including those received in error."
+              ::= { ip 3 }
+
+          ipInHdrErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of input datagrams discarded due to
+                      errors in their IP headers, including bad
+                      checksums, version number mismatch, other format
+                      errors, time-to-live exceeded, errors discovered
+                      in processing their IP options, etc."
+              ::= { ip 4 }
+
+          ipInAddrErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of input datagrams discarded because
+                      the IP address in their IP header's destination
+                      field was not a valid address to be received at
+                      this entity.  This count includes invalid
+                      addresses (e.g., 0.0.0.0) and addresses of
+                      unsupported Classes (e.g., Class E).  For entities
+                      which are not IP Gateways and therefore do not
+                      forward datagrams, this counter includes datagrams
+                      discarded because the destination address was not
+                      a local address."
+              ::= { ip 5 }
+
+          ipForwDatagrams OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of input datagrams for which this
+                      entity was not their final IP destination, as a
+                      result of which an attempt was made to find a
+                      route to forward them to that final destination.
+                      In entities which do not act as IP Gateways, this
+                      counter will include only those packets which were
+                      Source-Routed via this entity, and the Source-
+                      Route option processing was successful."
+              ::= { ip 6 }
+
+          ipInUnknownProtos OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of locally-addressed datagrams
+                      received successfully but discarded because of an
+                      unknown or unsupported protocol."
+              ::= { ip 7 }
+
+          ipInDiscards OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of input IP datagrams for which no
+                      problems were encountered to prevent their
+                      continued processing, but which were discarded
+                      (e.g., for lack of buffer space).  Note that this
+                      counter does not include any datagrams discarded
+                      while awaiting re-assembly."
+              ::= { ip 8 }
+
+          ipInDelivers OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of input datagrams successfully
+                      delivered to IP user-protocols (including ICMP)."
+              ::= { ip 9 }
+
+          ipOutRequests OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of IP datagrams which local IP
+                      user-protocols (including ICMP) supplied to IP in
+                      requests for transmission.  Note that this counter
+                      does not include any datagrams counted in
+                      ipForwDatagrams."
+              ::= { ip 10 }
+
+          ipOutDiscards OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of output IP datagrams for which no
+                      problem was encountered to prevent their
+                      transmission to their destination, but which were
+                      discarded (e.g., for lack of buffer space).  Note
+                      that this counter would include datagrams counted
+                      in ipForwDatagrams if any such packets met this
+                      (discretionary) discard criterion."
+              ::= { ip 11 }
+
+          ipOutNoRoutes OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of IP datagrams discarded because no
+                      route could be found to transmit them to their
+                      destination.  Note that this counter includes any
+                      packets counted in ipForwDatagrams which meet this
+                      `no-route' criterion.  Note that this includes any
+                      datagarms which a host cannot route because all of
+                      its default gateways are down."
+              ::= { ip 12 }
+
+          ipReasmTimeout OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The maximum number of seconds which received
+                      fragments are held while they are awaiting
+                      reassembly at this entity."
+              ::= { ip 13 }
+
+          ipReasmReqds OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of IP fragments received which needed
+                      to be reassembled at this entity."
+              ::= { ip 14 }
+
+          ipReasmOKs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of IP datagrams successfully re-
+                      assembled."
+              ::= { ip 15 }
+
+          ipReasmFails OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of failures detected by the IP re-
+                      assembly algorithm (for whatever reason: timed
+                      out, errors, etc).  Note that this is not
+                      necessarily a count of discarded IP fragments
+                      since some algorithms (notably the algorithm in
+                      RFC 815) can lose track of the number of fragments
+                      by combining them as they are received."
+              ::= { ip 16 }
+
+          ipFragOKs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of IP datagrams that have been
+                      successfully fragmented at this entity."
+              ::= { ip 17 }
+
+          ipFragFails OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of IP datagrams that have been
+                      discarded because they needed to be fragmented at
+                      this entity but could not be, e.g., because their
+                      Don't Fragment flag was set."
+              ::= { ip 18 }
+
+          ipFragCreates OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of IP datagram fragments that have
+                      been generated as a result of fragmentation at
+                      this entity."
+              ::= { ip 19 }
+
+
+
+          -- the IP address table
+
+          -- The IP address table contains this entity's IP addressing
+          -- information.
+
+          ipAddrTable OBJECT-TYPE
+              SYNTAX  SEQUENCE OF IpAddrEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "The table of addressing information relevant to
+                      this entity's IP addresses."
+              ::= { ip 20 }
+
+          ipAddrEntry OBJECT-TYPE
+              SYNTAX  IpAddrEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "The addressing information for one of this
+                      entity's IP addresses."
+              INDEX   { ipAdEntAddr }
+              ::= { ipAddrTable 1 }
+
+          IpAddrEntry ::=
+              SEQUENCE {
+                  ipAdEntAddr
+                      IpAddress,
+                  ipAdEntIfIndex
+                      INTEGER,
+                  ipAdEntNetMask
+                      IpAddress,
+                  ipAdEntBcastAddr
+                      INTEGER,
+                  ipAdEntReasmMaxSize
+                      INTEGER (0..65535)
+              }
+
+          ipAdEntAddr OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The IP address to which this entry's addressing
+                      information pertains."
+              ::= { ipAddrEntry 1 }
+
+
+          ipAdEntIfIndex OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The index value which uniquely identifies the
+                      interface to which this entry is applicable.  The
+                      interface identified by a particular value of this
+                      index is the same interface as identified by the
+                      same value of ifIndex."
+              ::= { ipAddrEntry 2 }
+
+          ipAdEntNetMask OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The subnet mask associated with the IP address of
+                      this entry.  The value of the mask is an IP
+                      address with all the network bits set to 1 and all
+                      the hosts bits set to 0."
+              ::= { ipAddrEntry 3 }
+
+          ipAdEntBcastAddr OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The value of the least-significant bit in the IP
+                      broadcast address used for sending datagrams on
+                      the (logical) interface associated with the IP
+                      address of this entry.  For example, when the
+                      Internet standard all-ones broadcast address is
+                      used, the value will be 1.  This value applies to
+                      both the subnet and network broadcasts addresses
+                      used by the entity on this (logical) interface."
+              ::= { ipAddrEntry 4 }
+
+          ipAdEntReasmMaxSize OBJECT-TYPE
+              SYNTAX  INTEGER (0..65535)
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The size of the largest IP datagram which this
+                      entity can re-assemble from incoming IP fragmented
+                      datagrams received on this interface."
+              ::= { ipAddrEntry 5 }
+
+
+
+          -- the IP routing table
+
+          -- The IP routing table contains an entry for each route
+          -- presently known to this entity.
+
+          ipRouteTable OBJECT-TYPE
+              SYNTAX  SEQUENCE OF IpRouteEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "This entity's IP Routing table."
+              ::= { ip 21 }
+
+          ipRouteEntry OBJECT-TYPE
+              SYNTAX  IpRouteEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "A route to a particular destination."
+              INDEX   { ipRouteDest }
+              ::= { ipRouteTable 1 }
+
+          IpRouteEntry ::=
+              SEQUENCE {
+                  ipRouteDest
+                      IpAddress,
+                  ipRouteIfIndex
+                      INTEGER,
+                  ipRouteMetric1
+                      INTEGER,
+                  ipRouteMetric2
+                      INTEGER,
+                  ipRouteMetric3
+                      INTEGER,
+                  ipRouteMetric4
+                      INTEGER,
+                  ipRouteNextHop
+                      IpAddress,
+                  ipRouteType
+                      INTEGER,
+                  ipRouteProto
+                      INTEGER,
+                  ipRouteAge
+                      INTEGER,
+                  ipRouteMask
+                      IpAddress,
+                  ipRouteMetric5
+                      INTEGER,
+                  ipRouteInfo
+                      OBJECT IDENTIFIER
+              }
+
+          ipRouteDest OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The destination IP address of this route.  An
+                      entry with a value of 0.0.0.0 is considered a
+                      default route.  Multiple routes to a single
+                      destination can appear in the table, but access to
+                      such multiple entries is dependent on the table-
+                      access mechanisms defined by the network
+                      management protocol in use."
+              ::= { ipRouteEntry 1 }
+
+          ipRouteIfIndex OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The index value which uniquely identifies the
+                      local interface through which the next hop of this
+                      route should be reached.  The interface identified
+                      by a particular value of this index is the same
+                      interface as identified by the same value of
+                      ifIndex."
+              ::= { ipRouteEntry 2 }
+
+          ipRouteMetric1 OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The primary routing metric for this route.  The
+                      semantics of this metric are determined by the
+                      routing-protocol specified in the route's
+                      ipRouteProto value.  If this metric is not used,
+                      its value should be set to -1."
+              ::= { ipRouteEntry 3 }
+
+          ipRouteMetric2 OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "An alternate routing metric for this route.  The
+                      semantics of this metric are determined by the
+                      routing-protocol specified in the route's
+                      ipRouteProto value.  If this metric is not used,
+                      its value should be set to -1."
+              ::= { ipRouteEntry 4 }
+
+          ipRouteMetric3 OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "An alternate routing metric for this route.  The
+                      semantics of this metric are determined by the
+                      routing-protocol specified in the route's
+                      ipRouteProto value.  If this metric is not used,
+                      its value should be set to -1."
+              ::= { ipRouteEntry 5 }
+
+          ipRouteMetric4 OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "An alternate routing metric for this route.  The
+                      semantics of this metric are determined by the
+                      routing-protocol specified in the route's
+                      ipRouteProto value.  If this metric is not used,
+                      its value should be set to -1."
+              ::= { ipRouteEntry 6 }
+
+          ipRouteNextHop OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The IP address of the next hop of this route.
+                      (In the case of a route bound to an interface
+                      which is realized via a broadcast media, the value
+                      of this field is the agent's IP address on that
+                      interface.)"
+              ::= { ipRouteEntry 7 }
+
+          ipRouteType OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          other(1),        -- none of the following
+
+                          invalid(2),      -- an invalidated route
+                                           -- route to directly
+                          direct(3),       -- connected (sub-)network
+
+                                           -- route to a non-local
+                          indirect(4)      -- host/network/sub-network
+                      }
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The type of route.  Note that the values
+                      direct(3) and indirect(4) refer to the notion of
+                      direct and indirect routing in the IP
+                      architecture.
+
+                      Setting this object to the value invalid(2) has
+                      the effect of invalidating the corresponding entry
+                      in the ipRouteTable object.  That is, it
+                      effectively dissasociates the destination
+                      identified with said entry from the route
+                      identified with said entry.  It is an
+                      implementation-specific matter as to whether the
+                      agent removes an invalidated entry from the table.
+                      Accordingly, management stations must be prepared
+                      to receive tabular information from agents that
+                      corresponds to entries not currently in use.
+                      Proper interpretation of such entries requires
+                      examination of the relevant ipRouteType object."
+              ::= { ipRouteEntry 8 }
+
+          ipRouteProto OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          other(1),       -- none of the following
+
+                                          -- non-protocol information,
+                                          -- e.g., manually configured
+                          local(2),       -- entries
+
+                                          -- set via a network
+                          netmgmt(3),     -- management protocol
+
+                                          -- obtained via ICMP,
+                          icmp(4),        -- e.g., Redirect
+
+                                          -- the remaining values are
+                                          -- all gateway routing
+                                          -- protocols
+                          egp(5),
+                          ggp(6),
+                          hello(7),
+                          rip(8),
+                          is-is(9),
+                          es-is(10),
+                          ciscoIgrp(11),
+                          bbnSpfIgp(12),
+                          ospf(13),
+                          bgp(14)
+                      }
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The routing mechanism via which this route was
+                      learned.  Inclusion of values for gateway routing
+                      protocols is not intended to imply that hosts
+                      should support those protocols."
+              ::= { ipRouteEntry 9 }
+
+          ipRouteAge OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of seconds since this route was last
+                      updated or otherwise determined to be correct.
+                      Note that no semantics of `too old' can be implied
+                      except through knowledge of the routing protocol
+                      by which the route was learned."
+              ::= { ipRouteEntry 10 }
+
+          ipRouteMask OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "Indicate the mask to be logical-ANDed with the
+                      destination address before being compared to the
+                      value in the ipRouteDest field.  For those systems
+                      that do not support arbitrary subnet masks, an
+                      agent constructs the value of the ipRouteMask by
+                      determining whether the value of the correspondent
+                      ipRouteDest field belong to a class-A, B, or C
+                      network, and then using one of:
+
+                           mask           network
+                           255.0.0.0      class-A
+                           255.255.0.0    class-B
+                           255.255.255.0  class-C
+
+                      If the value of the ipRouteDest is 0.0.0.0 (a
+                      default route), then the mask value is also
+                      0.0.0.0.  It should be noted that all IP routing
+                      subsystems implicitly use this mechanism."
+              ::= { ipRouteEntry 11 }
+
+          ipRouteMetric5 OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "An alternate routing metric for this route.  The
+                      semantics of this metric are determined by the
+                      routing-protocol specified in the route's
+                      ipRouteProto value.  If this metric is not used,
+                      its value should be set to -1."
+              ::= { ipRouteEntry 12 }
+
+          ipRouteInfo OBJECT-TYPE
+              SYNTAX  OBJECT IDENTIFIER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "A reference to MIB definitions specific to the
+                      particular routing protocol which is responsible
+                      for this route, as determined by the value
+                      specified in the route's ipRouteProto value.  If
+                      this information is not present, its value should
+                      be set to the OBJECT IDENTIFIER { 0 0 }, which is
+                      a syntatically valid object identifier, and any
+                      conformant implementation of ASN.1 and BER must be
+                      able to generate and recognize this value."
+              ::= { ipRouteEntry 13 }
+
+
+          -- the IP Address Translation table
+
+          -- The IP address translation table contain the IpAddress to
+          -- `physical' address equivalences.  Some interfaces do not
+          -- use translation tables for determining address
+          -- equivalences (e.g., DDN-X.25 has an algorithmic method);
+          -- if all interfaces are of this type, then the Address
+          -- Translation table is empty, i.e., has zero entries.
+
+          ipNetToMediaTable OBJECT-TYPE
+              SYNTAX  SEQUENCE OF IpNetToMediaEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "The IP Address Translation table used for mapping
+                      from IP addresses to physical addresses."
+              ::= { ip 22 }
+
+          ipNetToMediaEntry OBJECT-TYPE
+              SYNTAX  IpNetToMediaEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "Each entry contains one IpAddress to `physical'
+                      address equivalence."
+              INDEX   { ipNetToMediaIfIndex,
+                        ipNetToMediaNetAddress }
+              ::= { ipNetToMediaTable 1 }
+
+          IpNetToMediaEntry ::=
+              SEQUENCE {
+                  ipNetToMediaIfIndex
+                      INTEGER,
+                  ipNetToMediaPhysAddress
+                      PhysAddress,
+                  ipNetToMediaNetAddress
+                      IpAddress,
+                  ipNetToMediaType
+                      INTEGER
+              }
+
+          ipNetToMediaIfIndex OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The interface on which this entry's equivalence
+                      is effective.  The interface identified by a
+                      particular value of this index is the same
+                      interface as identified by the same value of
+                      ifIndex."
+              ::= { ipNetToMediaEntry 1 }
+
+          ipNetToMediaPhysAddress OBJECT-TYPE
+              SYNTAX  PhysAddress
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The media-dependent `physical' address."
+              ::= { ipNetToMediaEntry 2 }
+
+
+
+          ipNetToMediaNetAddress OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The IpAddress corresponding to the media-
+                      dependent `physical' address."
+              ::= { ipNetToMediaEntry 3 }
+
+          ipNetToMediaType OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          other(1),        -- none of the following
+                          invalid(2),      -- an invalidated mapping
+                          dynamic(3),
+                          static(4)
+                      }
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The type of mapping.
+
+                      Setting this object to the value invalid(2) has
+                      the effect of invalidating the corresponding entry
+                      in the ipNetToMediaTable.  That is, it effectively
+                      dissasociates the interface identified with said
+                      entry from the mapping identified with said entry.
+                      It is an implementation-specific matter as to
+                      whether the agent removes an invalidated entry
+                      from the table.  Accordingly, management stations
+                      must be prepared to receive tabular information
+                      from agents that corresponds to entries not
+                      currently in use.  Proper interpretation of such
+                      entries requires examination of the relevant
+                      ipNetToMediaType object."
+              ::= { ipNetToMediaEntry 4 }
+
+
+          -- additional IP objects
+
+          ipRoutingDiscards OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of routing entries which were chosen
+                      to be discarded even though they are valid.  One
+                      possible reason for discarding such an entry could
+                      be to free-up buffer space for other routing
+                      entries."
+              ::= { ip 23 }
+
+
+          -- the ICMP group
+
+          -- Implementation of the ICMP group is mandatory for all
+          -- systems.
+
+          icmpInMsgs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of ICMP messages which the
+                      entity received.  Note that this counter includes
+                      all those counted by icmpInErrors."
+              ::= { icmp 1 }
+
+          icmpInErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP messages which the entity
+                      received but determined as having ICMP-specific
+                      errors (bad ICMP checksums, bad length, etc.)."
+              ::= { icmp 2 }
+
+          icmpInDestUnreachs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Destination Unreachable
+                      messages received."
+              ::= { icmp 3 }
+
+          icmpInTimeExcds OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Time Exceeded messages
+                      received."
+              ::= { icmp 4 }
+
+
+          icmpInParmProbs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Parameter Problem messages
+                      received."
+              ::= { icmp 5 }
+
+          icmpInSrcQuenchs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Source Quench messages
+                      received."
+              ::= { icmp 6 }
+
+          icmpInRedirects OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Redirect messages received."
+              ::= { icmp 7 }
+
+          icmpInEchos OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Echo (request) messages
+                      received."
+              ::= { icmp 8 }
+
+          icmpInEchoReps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Echo Reply messages received."
+              ::= { icmp 9 }
+
+          icmpInTimestamps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Timestamp (request) messages
+                      received."
+              ::= { icmp 10 }
+
+          icmpInTimestampReps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Timestamp Reply messages
+                      received."
+              ::= { icmp 11 }
+
+          icmpInAddrMasks OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Address Mask Request messages
+                      received."
+              ::= { icmp 12 }
+
+          icmpInAddrMaskReps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Address Mask Reply messages
+                      received."
+              ::= { icmp 13 }
+
+          icmpOutMsgs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of ICMP messages which this
+                      entity attempted to send.  Note that this counter
+                      includes all those counted by icmpOutErrors."
+              ::= { icmp 14 }
+
+          icmpOutErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP messages which this entity did
+                      not send due to problems discovered within ICMP
+                      such as a lack of buffers.  This value should not
+                      include errors discovered outside the ICMP layer
+                      such as the inability of IP to route the resultant
+                      datagram.  In some implementations there may be no
+                      types of error which contribute to this counter's
+                      value."
+              ::= { icmp 15 }
+
+          icmpOutDestUnreachs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Destination Unreachable
+                      messages sent."
+              ::= { icmp 16 }
+
+          icmpOutTimeExcds OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Time Exceeded messages sent."
+              ::= { icmp 17 }
+
+          icmpOutParmProbs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Parameter Problem messages
+                      sent."
+              ::= { icmp 18 }
+
+          icmpOutSrcQuenchs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Source Quench messages sent."
+              ::= { icmp 19 }
+
+          icmpOutRedirects OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Redirect messages sent.  For a
+                      host, this object will always be zero, since hosts
+                      do not send redirects."
+              ::= { icmp 20 }
+
+          icmpOutEchos OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Echo (request) messages sent."
+              ::= { icmp 21 }
+
+          icmpOutEchoReps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Echo Reply messages sent."
+              ::= { icmp 22 }
+
+          icmpOutTimestamps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Timestamp (request) messages
+                      sent."
+              ::= { icmp 23 }
+
+          icmpOutTimestampReps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Timestamp Reply messages
+                      sent."
+              ::= { icmp 24 }
+
+          icmpOutAddrMasks OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Address Mask Request messages
+                      sent."
+              ::= { icmp 25 }
+
+
+          icmpOutAddrMaskReps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of ICMP Address Mask Reply messages
+                      sent."
+              ::= { icmp 26 }
+
+
+          -- the TCP group
+
+          -- Implementation of the TCP group is mandatory for all
+          -- systems that implement the TCP.
+
+          -- Note that instances of object types that represent
+          -- information about a particular TCP connection are
+          -- transient; they persist only as long as the connection
+          -- in question.
+
+          tcpRtoAlgorithm OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          other(1),    -- none of the following
+
+                          constant(2), -- a constant rto
+                          rsre(3),     -- MIL-STD-1778, Appendix B
+                          vanj(4)      -- Van Jacobson's algorithm [10]
+                      }
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The algorithm used to determine the timeout value
+                      used for retransmitting unacknowledged octets."
+              ::= { tcp 1 }
+
+          tcpRtoMin OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The minimum value permitted by a TCP
+                      implementation for the retransmission timeout,
+                      measured in milliseconds.  More refined semantics
+                      for objects of this type depend upon the algorithm
+                      used to determine the retransmission timeout.  In
+                      particular, when the timeout algorithm is rsre(3),
+                      an object of this type has the semantics of the
+                      LBOUND quantity described in RFC 793."
+              ::= { tcp 2 }
+
+
+          tcpRtoMax OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The maximum value permitted by a TCP
+                      implementation for the retransmission timeout,
+                      measured in milliseconds.  More refined semantics
+                      for objects of this type depend upon the algorithm
+                      used to determine the retransmission timeout.  In
+                      particular, when the timeout algorithm is rsre(3),
+                      an object of this type has the semantics of the
+                      UBOUND quantity described in RFC 793."
+              ::= { tcp 3 }
+
+          tcpMaxConn OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The limit on the total number of TCP connections
+                      the entity can support.  In entities where the
+                      maximum number of connections is dynamic, this
+                      object should contain the value -1."
+              ::= { tcp 4 }
+
+          tcpActiveOpens OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of times TCP connections have made a
+                      direct transition to the SYN-SENT state from the
+                      CLOSED state."
+              ::= { tcp 5 }
+
+          tcpPassiveOpens OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of times TCP connections have made a
+                      direct transition to the SYN-RCVD state from the
+                      LISTEN state."
+              ::= { tcp 6 }
+
+
+
+          tcpAttemptFails OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of times TCP connections have made a
+                      direct transition to the CLOSED state from either
+                      the SYN-SENT state or the SYN-RCVD state, plus the
+                      number of times TCP connections have made a direct
+                      transition to the LISTEN state from the SYN-RCVD
+                      state."
+              ::= { tcp 7 }
+
+          tcpEstabResets OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of times TCP connections have made a
+                      direct transition to the CLOSED state from either
+                      the ESTABLISHED state or the CLOSE-WAIT state."
+              ::= { tcp 8 }
+
+          tcpCurrEstab OBJECT-TYPE
+              SYNTAX  Gauge
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of TCP connections for which the
+                      current state is either ESTABLISHED or CLOSE-
+                      WAIT."
+              ::= { tcp 9 }
+
+          tcpInSegs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of segments received, including
+                      those received in error.  This count includes
+                      segments received on currently established
+                      connections."
+              ::= { tcp 10 }
+
+          tcpOutSegs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of segments sent, including
+                      those on current connections but excluding those
+                      containing only retransmitted octets."
+              ::= { tcp 11 }
+
+          tcpRetransSegs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of segments retransmitted - that
+                      is, the number of TCP segments transmitted
+                      containing one or more previously transmitted
+                      octets."
+              ::= { tcp 12 }
+
+
+          -- the TCP Connection table
+
+          -- The TCP connection table contains information about this
+          -- entity's existing TCP connections.
+
+          tcpConnTable OBJECT-TYPE
+              SYNTAX  SEQUENCE OF TcpConnEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "A table containing TCP connection-specific
+                      information."
+              ::= { tcp 13 }
+
+          tcpConnEntry OBJECT-TYPE
+              SYNTAX  TcpConnEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "Information about a particular current TCP
+                      connection.  An object of this type is transient,
+                      in that it ceases to exist when (or soon after)
+                      the connection makes the transition to the CLOSED
+                      state."
+              INDEX   { tcpConnLocalAddress,
+                        tcpConnLocalPort,
+                        tcpConnRemAddress,
+                        tcpConnRemPort }
+              ::= { tcpConnTable 1 }
+
+
+          TcpConnEntry ::=
+              SEQUENCE {
+                  tcpConnState
+                      INTEGER,
+                  tcpConnLocalAddress
+                      IpAddress,
+                  tcpConnLocalPort
+                      INTEGER (0..65535),
+                  tcpConnRemAddress
+                      IpAddress,
+                  tcpConnRemPort
+                      INTEGER (0..65535)
+              }
+
+          tcpConnState OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          closed(1),
+                          listen(2),
+                          synSent(3),
+                          synReceived(4),
+                          established(5),
+                          finWait1(6),
+                          finWait2(7),
+                          closeWait(8),
+                          lastAck(9),
+                          closing(10),
+                          timeWait(11),
+                          deleteTCB(12)
+                      }
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "The state of this TCP connection.
+
+                      The only value which may be set by a management
+                      station is deleteTCB(12).  Accordingly, it is
+                      appropriate for an agent to return a `badValue'
+                      response if a management station attempts to set
+                      this object to any other value.
+
+                      If a management station sets this object to the
+                      value deleteTCB(12), then this has the effect of
+                      deleting the TCB (as defined in RFC 793) of the
+                      corresponding connection on the managed node,
+                      resulting in immediate termination of the
+                      connection.
+
+                      As an implementation-specific option, a RST
+                      segment may be sent from the managed node to the
+                      other TCP endpoint (note however that RST segments
+                      are not sent reliably)."
+              ::= { tcpConnEntry 1 }
+
+          tcpConnLocalAddress OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The local IP address for this TCP connection.  In
+                      the case of a connection in the listen state which
+                      is willing to accept connections for any IP
+                      interface associated with the node, the value
+                      0.0.0.0 is used."
+              ::= { tcpConnEntry 2 }
+
+          tcpConnLocalPort OBJECT-TYPE
+              SYNTAX  INTEGER (0..65535)
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The local port number for this TCP connection."
+              ::= { tcpConnEntry 3 }
+
+          tcpConnRemAddress OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The remote IP address for this TCP connection."
+              ::= { tcpConnEntry 4 }
+
+          tcpConnRemPort OBJECT-TYPE
+              SYNTAX  INTEGER (0..65535)
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The remote port number for this TCP connection."
+              ::= { tcpConnEntry 5 }
+
+
+          -- additional TCP objects
+
+          tcpInErrs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of segments received in error
+                      (e.g., bad TCP checksums)."
+              ::= { tcp 14 }
+
+          tcpOutRsts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of TCP segments sent containing the
+                      RST flag."
+              ::= { tcp 15 }
+
+
+          -- the UDP group
+
+          -- Implementation of the UDP group is mandatory for all
+          -- systems which implement the UDP.
+
+          udpInDatagrams OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of UDP datagrams delivered to
+                      UDP users."
+              ::= { udp 1 }
+
+          udpNoPorts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of received UDP datagrams for
+                      which there was no application at the destination
+                      port."
+              ::= { udp 2 }
+
+          udpInErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of received UDP datagrams that could
+                      not be delivered for reasons other than the lack
+                      of an application at the destination port."
+              ::= { udp 3 }
+
+
+          udpOutDatagrams OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of UDP datagrams sent from this
+                      entity."
+              ::= { udp 4 }
+
+
+          -- the UDP Listener table
+
+          -- The UDP listener table contains information about this
+          -- entity's UDP end-points on which a local application is
+          -- currently accepting datagrams.
+
+          udpTable OBJECT-TYPE
+              SYNTAX  SEQUENCE OF UdpEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "A table containing UDP listener information."
+              ::= { udp 5 }
+
+          udpEntry OBJECT-TYPE
+              SYNTAX  UdpEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "Information about a particular current UDP
+                      listener."
+              INDEX   { udpLocalAddress, udpLocalPort }
+              ::= { udpTable 1 }
+
+          UdpEntry ::=
+              SEQUENCE {
+                  udpLocalAddress
+                      IpAddress,
+                  udpLocalPort
+                      INTEGER (0..65535)
+              }
+
+          udpLocalAddress OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The local IP address for this UDP listener.  In
+                      the case of a UDP listener which is willing to
+                      accept datagrams for any IP interface associated
+                      with the node, the value 0.0.0.0 is used."
+              ::= { udpEntry 1 }
+
+          udpLocalPort OBJECT-TYPE
+              SYNTAX  INTEGER (0..65535)
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The local port number for this UDP listener."
+              ::= { udpEntry 2 }
+
+
+          -- the EGP group
+
+          -- Implementation of the EGP group is mandatory for all
+          -- systems which implement the EGP.
+
+          egpInMsgs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of EGP messages received without
+                      error."
+              ::= { egp 1 }
+
+          egpInErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of EGP messages received that proved
+                      to be in error."
+              ::= { egp 2 }
+
+          egpOutMsgs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of locally generated EGP
+                      messages."
+              ::= { egp 3 }
+
+          egpOutErrors OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of locally generated EGP messages not
+                      sent due to resource limitations within an EGP
+                      entity."
+              ::= { egp 4 }
+
+
+          -- the EGP Neighbor table
+
+          -- The EGP neighbor table contains information about this
+          -- entity's EGP neighbors.
+
+          egpNeighTable OBJECT-TYPE
+              SYNTAX  SEQUENCE OF EgpNeighEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "The EGP neighbor table."
+              ::= { egp 5 }
+
+          egpNeighEntry OBJECT-TYPE
+              SYNTAX  EgpNeighEntry
+              ACCESS  not-accessible
+              STATUS  mandatory
+              DESCRIPTION
+                      "Information about this entity's relationship with
+                      a particular EGP neighbor."
+              INDEX   { egpNeighAddr }
+              ::= { egpNeighTable 1 }
+
+          EgpNeighEntry ::=
+              SEQUENCE {
+                  egpNeighState
+                      INTEGER,
+                  egpNeighAddr
+                      IpAddress,
+                  egpNeighAs
+                      INTEGER,
+                  egpNeighInMsgs
+                      Counter,
+                  egpNeighInErrs
+                      Counter,
+                  egpNeighOutMsgs
+                      Counter,
+                  egpNeighOutErrs
+                      Counter,
+                  egpNeighInErrMsgs
+                      Counter,
+                  egpNeighOutErrMsgs
+                      Counter,
+                  egpNeighStateUps
+                      Counter,
+                  egpNeighStateDowns
+                      Counter,
+                  egpNeighIntervalHello
+                      INTEGER,
+                  egpNeighIntervalPoll
+                      INTEGER,
+                  egpNeighMode
+                      INTEGER,
+                  egpNeighEventTrigger
+                      INTEGER
+              }
+
+          egpNeighState OBJECT-TYPE
+              SYNTAX  INTEGER {
+                          idle(1),
+                          acquisition(2),
+                          down(3),
+                          up(4),
+                          cease(5)
+                      }
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The EGP state of the local system with respect to
+                      this entry's EGP neighbor.  Each EGP state is
+                      represented by a value that is one greater than
+                      the numerical value associated with said state in
+                      RFC 904."
+              ::= { egpNeighEntry 1 }
+
+          egpNeighAddr OBJECT-TYPE
+              SYNTAX  IpAddress
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The IP address of this entry's EGP neighbor."
+              ::= { egpNeighEntry 2 }
+
+          egpNeighAs OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The autonomous system of this EGP peer.  Zero
+                      should be specified if the autonomous system
+                      number of the neighbor is not yet known."
+              ::= { egpNeighEntry 3 }
+
+          egpNeighInMsgs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of EGP messages received without error
+                      from this EGP peer."
+              ::= { egpNeighEntry 4 }
+
+          egpNeighInErrs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of EGP messages received from this EGP
+                      peer that proved to be in error (e.g., bad EGP
+                      checksum)."
+              ::= { egpNeighEntry 5 }
+
+          egpNeighOutMsgs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of locally generated EGP messages to
+                      this EGP peer."
+              ::= { egpNeighEntry 6 }
+
+          egpNeighOutErrs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of locally generated EGP messages not
+                      sent to this EGP peer due to resource limitations
+                      within an EGP entity."
+              ::= { egpNeighEntry 7 }
+
+          egpNeighInErrMsgs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of EGP-defined error messages received
+                      from this EGP peer."
+              ::= { egpNeighEntry 8 }
+
+          egpNeighOutErrMsgs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of EGP-defined error messages sent to
+                      this EGP peer."
+              ::= { egpNeighEntry 9 }
+
+          egpNeighStateUps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of EGP state transitions to the UP
+                      state with this EGP peer."
+              ::= { egpNeighEntry 10 }
+
+          egpNeighStateDowns OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The number of EGP state transitions from the UP
+                      state to any other state with this EGP peer."
+              ::= { egpNeighEntry 11 }
+
+          egpNeighIntervalHello OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The interval between EGP Hello command
+                      retransmissions (in hundredths of a second).  This
+                      represents the t1 timer as defined in RFC 904."
+              ::= { egpNeighEntry 12 }
+
+          egpNeighIntervalPoll OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The interval between EGP poll command
+                      retransmissions (in hundredths of a second).  This
+                      represents the t3 timer as defined in RFC 904."
+              ::= { egpNeighEntry 13 }
+
+          egpNeighMode OBJECT-TYPE
+              SYNTAX  INTEGER { active(1), passive(2) }
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The polling mode of this EGP entity, either
+                      passive or active."
+              ::= { egpNeighEntry 14 }
+
+          egpNeighEventTrigger OBJECT-TYPE
+              SYNTAX  INTEGER { start(1), stop(2) }
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "A control variable used to trigger operator-
+                      initiated Start and Stop events.  When read, this
+                      variable always returns the most recent value that
+                      egpNeighEventTrigger was set to.  If it has not
+                      been set since the last initialization of the
+                      network management subsystem on the node, it
+                      returns a value of `stop'.
+
+                      When set, this variable causes a Start or Stop
+                      event on the specified neighbor, as specified on
+                      pages 8-10 of RFC 904.  Briefly, a Start event
+                      causes an Idle peer to begin neighbor acquisition
+                      and a non-Idle peer to reinitiate neighbor
+                      acquisition.  A stop event causes a non-Idle peer
+                      to return to the Idle state until a Start event
+                      occurs, either via egpNeighEventTrigger or
+                      otherwise."
+              ::= { egpNeighEntry 15 }
+
+
+          -- additional EGP objects
+
+          egpAs OBJECT-TYPE
+              SYNTAX  INTEGER
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The autonomous system number of this EGP entity."
+              ::= { egp 6 }
+
+
+
+          -- the Transmission group
+
+          -- Based on the transmission media underlying each interface
+          -- on a system, the corresponding portion of the Transmission
+          -- group is mandatory for that system.
+
+          -- When Internet-standard definitions for managing
+          -- transmission media are defined, the transmission group is
+          -- used to provide a prefix for the names of those objects.
+
+          -- Typically, such definitions reside in the experimental
+          -- portion of the MIB until they are "proven", then as a
+          -- part of the Internet standardization process, the
+          -- definitions are accordingly elevated and a new object
+          -- identifier, under the transmission group is defined. By
+          -- convention, the name assigned is:
+          --
+          --     type OBJECT IDENTIFIER    ::= { transmission number }
+          --
+          -- where "type" is the symbolic value used for the media in
+          -- the ifType column of the ifTable object, and "number" is
+          -- the actual integer value corresponding to the symbol.
+
+
+          -- the SNMP group
+
+          -- Implementation of the SNMP group is mandatory for all
+          -- systems which support an SNMP protocol entity.  Some of
+          -- the objects defined below will be zero-valued in those
+          -- SNMP implementations that are optimized to support only
+          -- those functions specific to either a management agent or
+          -- a management station.  In particular, it should be
+          -- observed that the objects below refer to an SNMP entity,
+          -- and there may be several SNMP entities residing on a
+          -- managed node (e.g., if the node is hosting acting as
+          -- a management station).
+
+          snmpInPkts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of Messages delivered to the
+                      SNMP entity from the transport service."
+              ::= { snmp 1 }
+
+          snmpOutPkts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Messages which were
+                      passed from the SNMP protocol entity to the
+                      transport service."
+              ::= { snmp 2 }
+
+          snmpInBadVersions OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Messages which were
+                      delivered to the SNMP protocol entity and were for
+                      an unsupported SNMP version."
+              ::= { snmp 3 }
+
+          snmpInBadCommunityNames OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Messages delivered to
+                      the SNMP protocol entity which used a SNMP
+                      community name not known to said entity."
+              ::= { snmp 4 }
+
+          snmpInBadCommunityUses OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Messages delivered to
+                      the SNMP protocol entity which represented an SNMP
+                      operation which was not allowed by the SNMP
+                      community named in the Message."
+              ::= { snmp 5 }
+
+          snmpInASNParseErrs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of ASN.1 or BER errors
+                      encountered by the SNMP protocol entity when
+                      decoding received SNMP Messages."
+              ::= { snmp 6 }
+
+
+          -- { snmp 7 } is not used
+
+          snmpInTooBigs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP PDUs which were
+                      delivered to the SNMP protocol entity and for
+                      which the value of the error-status field is
+                      `tooBig'."
+              ::= { snmp 8 }
+
+          snmpInNoSuchNames OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP PDUs which were
+                      delivered to the SNMP protocol entity and for
+                      which the value of the error-status field is
+                      `noSuchName'."
+              ::= { snmp 9 }
+
+          snmpInBadValues OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP PDUs which were
+                      delivered to the SNMP protocol entity and for
+                      which the value of the error-status field is
+                      `badValue'."
+              ::= { snmp 10 }
+
+          snmpInReadOnlys OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number valid SNMP PDUs which were
+                      delivered to the SNMP protocol entity and for
+                      which the value of the error-status field is
+                      `readOnly'.  It should be noted that it is a
+                      protocol error to generate an SNMP PDU which
+                      contains the value `readOnly' in the error-status
+                      field, as such this object is provided as a means
+                      of detecting incorrect implementations of the
+                      SNMP."
+              ::= { snmp 11 }
+
+          snmpInGenErrs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP PDUs which were
+                      delivered to the SNMP protocol entity and for
+                      which the value of the error-status field is
+                      `genErr'."
+              ::= { snmp 12 }
+
+          snmpInTotalReqVars OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of MIB objects which have been
+                      retrieved successfully by the SNMP protocol entity
+                      as the result of receiving valid SNMP Get-Request
+                      and Get-Next PDUs."
+              ::= { snmp 13 }
+
+          snmpInTotalSetVars OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of MIB objects which have been
+                      altered successfully by the SNMP protocol entity
+                      as the result of receiving valid SNMP Set-Request
+                      PDUs."
+              ::= { snmp 14 }
+
+          snmpInGetRequests OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Get-Request PDUs which
+                      have been accepted and processed by the SNMP
+                      protocol entity."
+              ::= { snmp 15 }
+
+          snmpInGetNexts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Get-Next PDUs which have
+                      been accepted and processed by the SNMP protocol
+                      entity."
+              ::= { snmp 16 }
+
+          snmpInSetRequests OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Set-Request PDUs which
+                      have been accepted and processed by the SNMP
+                      protocol entity."
+              ::= { snmp 17 }
+
+          snmpInGetResponses OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Get-Response PDUs which
+                      have been accepted and processed by the SNMP
+                      protocol entity."
+              ::= { snmp 18 }
+
+          snmpInTraps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Trap PDUs which have
+                      been accepted and processed by the SNMP protocol
+                      entity."
+              ::= { snmp 19 }
+
+          snmpOutTooBigs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP PDUs which were
+                      generated by the SNMP protocol entity and for
+                      which the value of the error-status field is
+                      `tooBig.'"
+              ::= { snmp 20 }
+
+
+          snmpOutNoSuchNames OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP PDUs which were
+                      generated by the SNMP protocol entity and for
+                      which the value of the error-status is
+                      `noSuchName'."
+              ::= { snmp 21 }
+
+          snmpOutBadValues OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP PDUs which were
+                      generated by the SNMP protocol entity and for
+                      which the value of the error-status field is
+                      `badValue'."
+              ::= { snmp 22 }
+
+          -- { snmp 23 } is not used
+
+          snmpOutGenErrs OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP PDUs which were
+                      generated by the SNMP protocol entity and for
+                      which the value of the error-status field is
+                      `genErr'."
+              ::= { snmp 24 }
+
+          snmpOutGetRequests OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Get-Request PDUs which
+                      have been generated by the SNMP protocol entity."
+              ::= { snmp 25 }
+
+          snmpOutGetNexts OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Get-Next PDUs which have
+                      been generated by the SNMP protocol entity."
+              ::= { snmp 26 }
+
+          snmpOutSetRequests OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Set-Request PDUs which
+                      have been generated by the SNMP protocol entity."
+              ::= { snmp 27 }
+
+          snmpOutGetResponses OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Get-Response PDUs which
+                      have been generated by the SNMP protocol entity."
+              ::= { snmp 28 }
+
+          snmpOutTraps OBJECT-TYPE
+              SYNTAX  Counter
+              ACCESS  read-only
+              STATUS  mandatory
+              DESCRIPTION
+                      "The total number of SNMP Trap PDUs which have
+                      been generated by the SNMP protocol entity."
+              ::= { snmp 29 }
+
+          snmpEnableAuthenTraps OBJECT-TYPE
+              SYNTAX  INTEGER { enabled(1), disabled(2) }
+              ACCESS  read-write
+              STATUS  mandatory
+              DESCRIPTION
+                      "Indicates whether the SNMP agent process is
+                      permitted to generate authentication-failure
+                      traps.  The value of this object overrides any
+                      configuration information; as such, it provides a
+                      means whereby all authentication-failure traps may
+                      be disabled.
+
+                      Note that it is strongly recommended that this
+                      object be stored in non-volatile memory so that it
+                      remains constant between re-initializations of the
+                      network management system."
+              ::= { snmp 30 }
+
+END
diff --git a/SecuritySNACCRuntime/asn1specs/tbl.asn1 b/SecuritySNACCRuntime/asn1specs/tbl.asn1
new file mode 100644
index 00000000..33b95055
--- /dev/null
+++ b/SecuritySNACCRuntime/asn1specs/tbl.asn1
@@ -0,0 +1,171 @@
+-- .../asn1specs/tbl.asn1
+--
+--  TBL types describe ASN.1 data structures.
+--  These can be used in generic, interpretive encoders/decoders.
+--  Interpretive decoders are typically slower, but don't eat memory
+--  with type-specific encoding and decoding code.
+--  The tbl types can also be sent over the network
+--  and allow dynamic re-configuration of encoders/decoders.
+--
+--  To understand how this type table structure is used
+--  look in:
+--      1. .../compiler/core/gen-tbls.c
+--           this will show you how various things are generated
+--           from the big parse tree (asn1module.asn1).
+--           Pay particular attention to the typeDefId use
+--
+--      2.  look in .../c-lib/makefile for an example of how you can
+--          modify the tbl.h file generated from this module to suit
+--          your own needs.
+--
+--      3.  look in .../tbl-tools/ptbl/pasn1.c to see how the
+--          TBL data struct relates to the original ASN.1
+--
+--
+--
+--  Mike Sample, April 11, 1992
+--  Mods MS Feb 7/93
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/asn1specs/tbl.asn1,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+-- $Log: tbl.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:05  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:05:56  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.5  1997/06/19 09:17:13  wan
+-- Added isPdu flag to tables. Added value range checks during parsing.
+--
+-- Revision 1.4  1997/05/07 15:18:33  wan
+-- Added (limited) size constraints, bitstring and enumeration names to tables
+--
+-- Revision 1.3  1995/07/25 19:56:00  rj
+-- introductory comments adjusted to match changed file names.
+--
+-- changed `_' to `-' in file names.
+--
+-- Revision 1.2  1994/08/28  09:54:18  rj
+-- comment leader fixed.
+--
+-- Revision 1.1  1994/08/28  09:51:14  rj
+-- first check-in.
+
+TBL DEFINITIONS ::=
+BEGIN
+
+
+-- imports nothing
+-- exports nothing
+
+TBL ::= --snacc isPdu:"TRUE" -- SEQUENCE
+{
+   totalNumModules  INTEGER,  -- these totals can help allocation
+   totalNumTypeDefs INTEGER,  -- when decoding (ie use arrays)
+   totalNumTypes    INTEGER,
+   totalNumTags     INTEGER,
+   totalNumStrings  INTEGER,
+   totalLenStrings  INTEGER,
+   modules SEQUENCE OF TBLModule
+}
+
+TBLModule ::= SEQUENCE
+{
+    name     [0] IMPLICIT PrintableString,
+    id       [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
+    isUseful [2] IMPLICIT BOOLEAN, -- true if useful types module
+    typeDefs [3] IMPLICIT SEQUENCE OF TBLTypeDef
+}
+
+--
+-- The typedefId is just an integer that uniquely identifies
+-- each TBLTypeDef (type references use these as "pointers").
+-- The typeDefId's in each module will have consecutive type ids.
+-- The first typedef in a module will have the lowest Id and the
+-- last typedef will have the highest.  Thus if the first typedef
+-- in a module has the id of 12 and the last typedef in that module
+-- has  the id of 27, the module contains the typdefs in the range
+-- 12..27 (inclusive).  This can be used  to re-compute the
+-- IMPORT information for modules in a type table.
+--
+-- (The LoadTBL routine hides this integer/ptr crap from the user
+-- by adding real pointers to the tbl.h data structures where useful.
+-- When loading, the typeDefIds are converted into these real ptrs)
+--
+TBLTypeDef ::= SEQUENCE
+{
+   typeDefId TBLTypeDefId,
+   typeName  PrintableString, -- OPTIONAL, I have forgotten why this is opt!
+                                        -- I can see no good reason for it
+   type      TBLType,
+   isPdu     NULL OPTIONAL
+}
+
+TBLType ::= SEQUENCE
+{
+   typeId    [0] IMPLICIT TBLTypeId,
+   optional  [1] IMPLICIT BOOLEAN,
+   tagList   [2] IMPLICIT SEQUENCE OF TBLTag OPTIONAL,
+   content   [3] TBLTypeContent,
+   fieldName [4] IMPLICIT PrintableString OPTIONAL,
+   constraint[5] IMPLICIT TBLRange OPTIONAL,
+   values    [6] IMPLICIT TBLNamedNumberList OPTIONAL
+}
+
+TBLRange ::= SEQUENCE
+{
+    from [0] IMPLICIT INTEGER,
+    to [1] IMPLICIT INTEGER
+}
+
+TBLNamedNumberList ::= SEQUENCE OF TBLNamedNumber
+
+TBLNamedNumber ::= SEQUENCE
+{
+    name [0] IMPLICIT PrintableString,
+    value [1] IMPLICIT INTEGER
+}
+
+TBLTypeContent ::= CHOICE
+{
+   primType [0] IMPLICIT NULL,
+   elmts    [1] IMPLICIT SEQUENCE OF TBLType,
+   typeRef  [2] IMPLICIT TBLTypeRef
+}
+
+TBLTypeRef ::= SEQUENCE
+{
+    typeDef TBLTypeDefId,
+    implicit BOOLEAN
+}
+
+TBLTypeId ::= ENUMERATED
+{
+    tbl-boolean (0),
+    tbl-integer (1),
+    tbl-bitstring (2),
+    tbl-octetstring (3),
+    tbl-null (4),
+    tbl-oid (5),
+    tbl-real (6),
+    tbl-enumerated (7),
+    tbl-sequence (8),
+    tbl-set (9),
+    tbl-sequenceof (10),
+    tbl-setof (11),
+    tbl-choice (12),
+    tbl-typeref (13)
+}
+
+TBLTypeDefId ::= INTEGER
+
+TBLTag ::= SEQUENCE
+{
+    tclass TBLTagClass,
+    code INTEGER (0..MAX)
+}
+
+TBLTagClass ::=  ENUMERATED { universal (0), application (1),
+                             context (2), private (3) }
+
+END
diff --git a/SecuritySNACCRuntime/c++-examples/any/README b/SecuritySNACCRuntime/c++-examples/any/README
new file mode 100644
index 00000000..4405a646
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/any/README
@@ -0,0 +1,96 @@
+(RCS control information is at the end of this file.)
+
+
+C++ ANY example README
+---------------------
+
+This example shows how the snacc compiler handles the ANY DEFINED BY
+type in C++.  ANY types (not ANY DEFINED BY) require modifications
+to the generated code.  Type "make" to build this example.
+
+This directory should have the following 4 files in it:
+
+        README
+        example.C
+        genber.C
+        makefile
+
+There are 3 programs generated by the makefile:
+
+        genber - builds a BER value of the AnyTestType and writes it
+                 to a file called "att.ber"
+
+        def    - takes file name of an AnyTestType BER value.  Decodes the
+                 file and re-encodes it to stdout.  Uses definite
+                 lengths for constructed values.
+
+        indef  - takes file name of an AnyTestType BER value.  Decodes the
+                 file and re-encodes it to stdout.  Uses indefinite
+                 lengths for constructed values.
+
+
+These files use the code generated by snacc from the
+snacc/asn1specs/any.asn1 file. (see the makefile)
+
+Look at genber.C to see how values can be built and printed.
+
+Look at the generated code in any_test.C and any_test.h to see how the
+any hash table is built.
+
+
+try the following commands in your c-shell:
+
+%1 genber                   # generate the att.ber file
+%2 indef att.ber > tmp.ber  # decode att.ber an re-encode into tmp.ber
+%3 def tmp.ber > tmp2.ber   # decode tmp.ber an re-encode into tmp2.ber
+%4 diff att.ber tmp2.ber    # compare .ber files (should be the same)
+
+When you are finished with the example type "make clean"  to remove
+the binaries and generated code.
+
+
+
+Things To Note
+--------------
+
+Snacc ASN.1 comment commands
+
+In the snacc/asn1specs/any.asn1 file, the AnyTestType has a special
+"--snacc" ASN.1 comment after ::= to give snacc some extra information
+about the AnyTestType.
+
+AnyTestType ::= --snacc isPdu:"TRUE" -- SEQUENCE { ... etc. ... }
+
+The "isPdu" flag only affects the generated C code, not C++.  Each
+C++ type gets PDU methods by default.
+
+
+SNMP OBJECT-TYPE Macro
+
+The SNMP OBJECT-TYPE macro is used to define the id value to type
+mapping for ANY DEFINED BY types.  The macro has been modified to
+accept both INTEGERs and OBJECT IDENTIFIERs as id values (see
+snacc/asn1specs/any.asn1).  This macro can be used with other
+protocols to define the id to type mapping.
+
+Two hash tables are used to hold the id to type mappings. One for
+INTEGER to type mappings and the other for OBJECT IDENTIFIER to type
+mappings.  The hash tables are automatically initialized in each
+module that has OBJECT-TYPE macros.  In C the hash table must be
+explicitly initialized.
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/any/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:57  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1997/02/16 20:25:26  rj
+# check-in of a few cosmetic changes
+#
+# Revision 1.1  1994/08/31  08:47:59  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
diff --git a/SecuritySNACCRuntime/c++-examples/any/example.C b/SecuritySNACCRuntime/c++-examples/any/example.C
new file mode 100644
index 00000000..e3aa4bd9
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/any/example.C
@@ -0,0 +1,142 @@
+/*
+ * 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/any/example.C - an example of how to use C++ ASN.1-BER
+//              for ANY Types
+//
+// AUTHOR: Mike Sample
+// DATE:   92
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/any/example.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Log: example.C,v $
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1.1.1  1999/03/16 18:05:57  aram
+// Originals from SMIME Free Library.
+//
+// Revision 1.5  1995/07/24 15:33:33  rj
+// changed `_' to `-' in file names.
+//
+// any-test.[hC] becomes any.[hC] due to to snacc's new file name generation scheme.
+//
+// check return value of new.
+//
+// Revision 1.4  1995/02/18  13:53:07  rj
+// added #define HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS since not every C++ compiler provides them.
+//
+// Revision 1.3  1994/10/08  01:26:21  rj
+// several \size_t'
+//
+// Revision 1.2  1994/08/31  08:56:29  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+//
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fstream.h>
+
+#include "asn-incl.h"
+#include "any.h"
+
+main (int argc, char *argv[])
+{
+    if (argc != 2)
+    {
+        cerr << "Usage: " << argv[0] << " <BER data file name>" << endl;
+        cerr << "   Decodes the given AnyTestType BER data file" << endl;
+        cerr << "   and re-encodes it to stdout" << endl;
+        exit (1);
+    }
+
+    ifstream dataFile;
+    // open the data file
+    dataFile.open (argv[1]);
+
+    if (!dataFile)
+    {
+        perror ("ifstream::open");
+        exit (1);
+    }
+
+    // get size of the data file file
+    dataFile.seekg (0, ios::end);
+    int dataSize = dataFile.tellg();
+    dataFile.seekg (0);
+
+    // read data from file into contiguous block for a buffer
+#if HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS
+    char data[dataSize];
+#else
+    char *data = new char[dataSize];
+    if (!data)
+	return 1;
+#endif /* HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS */
+    dataFile.read (data, dataSize);
+    dataFile.close();
+
+    //
+    // put the BER data read from the file
+    // into buffer format, ready for reading from the
+    // beginning
+    //
+    AsnBuf inputBuf;
+    inputBuf.InstallData ((char*)data, dataSize);
+
+    size_t decodedLen;
+    AnyTestType att;
+
+    if (!att.BDecPdu (inputBuf, decodedLen))
+    {
+        cerr << "ERROR - Decode routines failed, exiting..." << endl;
+        exit (1);
+    }
+
+    cerr  << "decodedValue AnyTestType ::= " << att << endl << endl;
+
+    //
+    // allocate a new buffer and set up for writing to
+    //
+    AsnBuf  outputBuf;
+#if HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS
+    char outputData[dataSize + 512];
+#else
+    char *outputData = new char[dataSize + 512];
+    if (!outputData)
+	return 1;
+#endif /* HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS */
+    outputBuf.Init (outputData, dataSize+512);
+    outputBuf.ResetInWriteRvsMode();
+
+    size_t encodedLen;
+    if (!att.BEncPdu (outputBuf, encodedLen))
+    {
+        cerr << "ERROR - Encode routines failed" << endl;
+    }
+
+    // write the BER value to cout
+    outputBuf.ResetInReadMode();
+    for ( ; encodedLen > 0; encodedLen--)
+        cout.put (outputBuf.GetByte());
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c++-examples/any/genber.C b/SecuritySNACCRuntime/c++-examples/any/genber.C
new file mode 100644
index 00000000..2581f798
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/any/genber.C
@@ -0,0 +1,220 @@
+/*
+ * 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/any/genber.C - builds an AnyTestType value and writes BER form
+//            of the value to a file called "att.ber"
+//
+//  Shows how to build internal rep of lists and ANY values.
+//
+// MS 92
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/any/genber.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Log: genber.C,v $
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/08 19:58:44  dmitch
+// Mods for X port.
+//
+// Revision 1.1.1.1  1999/03/16 18:05:57  aram
+// Originals from SMIME Free Library.
+//
+// Revision 1.5  1995/07/24 15:33:34  rj
+// changed `_' to `-' in file names.
+//
+// any-test.[hC] becomes any.[hC] due to to snacc's new file name generation scheme.
+//
+// check return value of new.
+//
+// Revision 1.4  1995/02/18  13:54:03  rj
+// added #define HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS since not every C++ compiler provides them.
+//
+// Revision 1.3  1994/10/08  01:26:22  rj
+// several \size_t'
+//
+// Revision 1.2  1994/08/31  08:56:30  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+//
+
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fstream.h>
+
+#include "asn-incl.h"
+#include "any.h"
+
+#define APPLE_ANY_HACK		1
+
+main (int argc, char *argv[])
+{
+    ofstream outputFile;
+    AsnBuf outputBuf;
+    size_t encodedLen;
+    size_t dataSize = 1024;
+#if HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS
+    char data[dataSize];
+#else
+    char *data = new char[dataSize];
+    if (!data)
+	return 1;
+#endif /* HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS */
+    AnyTestType att;
+    TSeq1 ts1;
+    TSeq2 ts2;
+    AttrValue1 *atv1ptr;
+    AttrValue2 *atv2ptr;
+    AsnInt intVal;
+    AsnBool boolVal;
+    AsnOcts octsVal ("Hi Mom");
+    OctsId octsIdVal = octsVal;
+    AsnBits bitsVal;
+    BitsId bitsIdVal (9);
+    AsnReal realVal;
+
+    // READ THIS!!!
+    // you must be really careful when setting the
+    // "value" field and "id" fields in an
+    // ANY/ANY DEFINED BY type because "value" is a
+    // "AsnType*" and will accept any
+    // pointer value.  It will even encode
+    // the wrong value without complaining if you
+    // set "value" to the wrong object.
+
+    atv1ptr = att.intMap.Append();
+    atv1ptr->id = intId;
+    intVal = -99;
+	#if	APPLE_ANY_HACK
+    atv1ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&intVal);
+	#else
+    atv1ptr->anyDefBy.value = &intVal;
+	#endif
+    atv1ptr = att.intMap.Append();
+    atv1ptr->id = boolId;
+    boolVal = true;
+	#if	APPLE_ANY_HACK
+    atv1ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&boolVal);
+	#else
+    atv1ptr->anyDefBy.value = &boolVal;
+	#endif
+	
+    atv1ptr = att.intMap.Append();
+    atv1ptr->id = octsId;
+	#if	APPLE_ANY_HACK
+    atv1ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&octsIdVal);
+	#else
+    atv1ptr->anyDefBy.value = &octsIdVal;
+	#endif
+	
+    atv1ptr = att.intMap.Append();
+    atv1ptr->id = bitsId;
+    bitsIdVal.SetBit (0);
+    bitsIdVal.ClrBit (1);
+    bitsIdVal.SetBit (2);
+    bitsIdVal.ClrBit (3);
+    bitsIdVal.SetBit (4);
+    bitsIdVal.ClrBit (5);
+    bitsIdVal.SetBit (6);
+    bitsIdVal.ClrBit (7);
+    bitsIdVal.SetBit (8);
+    bitsIdVal.ClrBit (9);
+	#if	APPLE_ANY_HACK
+    atv1ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&bitsIdVal);
+	#else
+    atv1ptr->anyDefBy.value = &bitsIdVal;
+	#endif
+	
+    atv1ptr = att.intMap.Append();
+    atv1ptr->id = realId;
+    realVal = 108.3838;
+	#if	APPLE_ANY_HACK
+    atv1ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&realVal);
+	#else
+    atv1ptr->anyDefBy.value = &realVal;
+	#endif
+	
+    // now do TSeq2 with same vals but use OID as identifier
+    atv2ptr = att.oidMap.Append();
+    atv2ptr->id = intOid;
+ 	#if	APPLE_ANY_HACK
+    atv2ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&intVal);
+	#else
+	atv2ptr->anyDefBy.value = &intVal;
+	#endif
+	
+    atv2ptr = att.oidMap.Append();
+    atv2ptr->id = boolOid;
+ 	#if	APPLE_ANY_HACK
+    atv2ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&boolVal);
+	#else
+    atv2ptr->anyDefBy.value = &boolVal;
+	#endif
+	
+    atv2ptr = att.oidMap.Append();
+    atv2ptr->id = octsOid;
+ 	#if	APPLE_ANY_HACK
+    atv2ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&octsVal);
+	#else
+    atv2ptr->anyDefBy.value = &octsVal;
+	#endif
+	
+    atv2ptr = att.oidMap.Append();
+    atv2ptr->id = bitsOid;
+    bitsVal = bitsIdVal; // copy bits
+ 	#if	APPLE_ANY_HACK
+    atv2ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&bitsVal);
+	#else
+    atv2ptr->anyDefBy.value = &bitsVal;
+	#endif
+	
+    atv2ptr = att.oidMap.Append();
+    atv2ptr->id = realOid;
+ 	#if	APPLE_ANY_HACK
+    atv2ptr->anyDefBy.value = reinterpret_cast<CSM_Buffer *>(&bitsVal);
+	#else
+    atv2ptr->anyDefBy.value = &bitsVal;
+	#endif
+	
+    outputBuf.Init (data, dataSize);
+    outputBuf.ResetInWriteRvsMode();
+
+    if (!att.BEncPdu (outputBuf, encodedLen))
+        cout << "failed encoding AnyTestType value" << endl;
+
+    outputFile.open ("att.ber");
+    if (!outputFile)
+    {
+        perror ("ofstream::open");
+        exit (1);
+    }
+
+    outputBuf.ResetInReadMode();
+    for ( ; encodedLen > 0; encodedLen--)
+        outputFile.put (outputBuf.GetByte());
+
+
+    cout << "Wrote the following BER AnyTestType value to att.ber." << endl;
+    cout << "Test it with \"def\" and \"indef\"" << endl;
+    //cout << att << endl;
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c++-examples/any/makefile b/SecuritySNACCRuntime/c++-examples/any/makefile
new file mode 100644
index 00000000..a9e45b91
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/any/makefile
@@ -0,0 +1,169 @@
+# c++-examples/any/makefile
+#
+# WARNING: this makefile isn't safe for parallel making!
+#
+# builds the C++ ANY example
+#
+# MS 92
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/any/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.3  2000/12/22 00:03:01  dmitch
+# Misc. updates for clean build on Cheetah 1D7.
+#
+# Revision 1.2  2000/06/08 19:58:44  dmitch
+# Mods for X port.
+#
+# Revision 1.1.1.1  1999/03/16 18:05:57  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.9  1997/02/16 16:47:46  rj
+# made return *this after calling abort()'' a compile time option.
+#
+# Revision 1.8  1995/07/24  15:29:07  rj
+# useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme.
+# any-test.[hC] becomes any.[hC] due to to snacc's new file name generation scheme.
+#
+# `cd && make' instead of `cd; make'.
+#
+# changed `_' to `-' in file names.
+#
+# Revision 1.7  1995/02/20  11:46:19  rj
+# build snacc if it doesn't exist.
+# some makes leave a trailing slash on $(@D), others don't. this causes some mkdir(1)s to deny their cooperation. therefore, the slash has got to be stripped.
+#
+# Revision 1.6  1995/02/13  14:58:12  rj
+# augment CPPFLAGS, not overwrite
+#
+# Revision 1.5  1994/10/08  04:35:42  rj
+# enhance portability by using standard make capabilities instead of utilies (basename, dirname) not found on every platform.
+#
+# for the dependencies, generate the snacc compiler if it doesn't exist.
+#
+# Revision 1.4  1994/09/01  02:26:53  rj
+# use CXX instead of CC to get another default linkage
+#
+# Revision 1.3  1994/08/31  21:38:34  rj
+# rebuild the executables when the c++-lib is newer.
+#
+# Revision 1.2  1994/08/31  10:31:47  rj
+# since .o files get moved, a few more dependencies are needed.
+#
+# Revision 1.1  1994/08/31  08:48:03  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../../makehead
+
+TOP		= ../..
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+
+ASN1_C++_LIB_DIR	= $(TOP)/c++-lib
+BUILD_DIR           = /Data_and_Apps/dmitchBuild
+ASN1_C++_INC_DIR	= $(ASN1_C++_LIB_DIR)/inc
+ASN1_C++_LIB		= $(ASN1_C++_LIB_DIR)/libasn1c++.a -framework cdsa_utilities -F/System/Library/PrivateFrameworks
+#ASN1_C++_LIB		= $(BUILD_DIR)/libsnacc++.a
+#ASN1_C++_LIB		= -framework snaccRuntime -F/Data_and_Apps/dmitchBuild -lstdc++
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+USEFUL_TYPES	= $(ASN1_SRC_DIR)/asn-useful.asn1
+SNACCFLAGS	= -C $(SNACC_NOVOLAT) -u $(USEFUL_TYPES)
+
+CC		= $(CXX)
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C++_INC_DIR) $(LENFLAG) -DVDADER_RULES -F/System/Library/PrivateFrameworks
+
+ASN1FILES	= $(ASN1_SRC_DIR)/any.asn1
+
+# generated by snacc from any.asn1:
+ASN1HFILES	= any.h
+ASN1CFILES	= any.cpp
+
+CFILES = \
+	genber.C	\
+	example.C
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(CFILES)
+
+#-------------------------------------------------------------------------------
+
+all::		genber def indef
+
+$(ASN1HFILES)	\
+$(ASN1CFILES):	$(SNACC) $(ASN1FILES)
+		$(REASON)
+		$(SNACC) $(SNACCFLAGS) $(ASN1FILES)
+
+$(SNACC):
+		cd $(@D) && $(MAKE) $(@F)
+
+def-obj		\
+indef-obj:
+		mkdir $@
+
+def-obj/any.o	\
+def-obj/example.o:
+		$(REASON)
+		$(MAKE) LENFLAG= `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+indef-obj/any.o	\
+indef-obj/example.o:
+		$(REASON)
+		$(MAKE) LENFLAG=-DUSE_INDEF_LEN `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+genber:		def-obj/any.o genber.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ def-obj/any.o genber.o $(ASN1_C++_LIB) $(LIBS) -lstdc++
+
+def: 		def-obj/any.o def-obj/example.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ def-obj/any.o def-obj/example.o $(ASN1_C++_LIB) $(LIBS) -lstdc++
+
+indef:		indef-obj/any.o indef-obj/example.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ indef-obj/any.o indef-obj/example.o $(ASN1_C++_LIB) $(LIBS) -lstdc++
+
+genber	\
+def	\
+indef:		
+
+.PHONY:	check
+
+check::		genber def indef
+		$(RM) foo.ber bar.ber
+		./genber
+		./indef att.ber > foo.ber
+		./def foo.ber > bar.ber
+		@echo ''
+		@if cmp -s bar.ber att.ber; then\
+		  echo "+++ Passed simple encode/decode tests using any.asn1.";\
+		else\
+		  echo "--- Failed simple encode/decode tests using any.asn1.";\
+		fi
+		@echo ''
+		$(RM) foo.ber bar.ber
+
+clean::
+		$(RM) *.o *~ .emacs* core def indef genber att.ber $(ASN1HFILES) $(ASN1CFILES)
+		$(RM) -r def-obj indef-obj
+		$(RM) foo.ber bar.ber
+
+depend::	$(SNACC)
+
+include ../../maketail
+
+depend::
+		cp dependencies deps
+		for dir in def-obj indef-obj; do\
+		  < dependencies sed -e 's:^\(.*\.o\):'"$$dir"'/\1:' >> deps;\
+		done
+		mv deps dependencies
diff --git a/SecuritySNACCRuntime/c++-examples/makefile b/SecuritySNACCRuntime/c++-examples/makefile
new file mode 100644
index 00000000..0b16647a
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/makefile
@@ -0,0 +1,36 @@
+# file: .../c++-examples/makefile
+
+# Apple change: simple doesn't run (yet). 
+#SUBDIRS		= test-lib simple any snmp
+SUBDIRS		= test-lib any snmp
+
+#-------------------------------------------------------------------------------
+
+.PHONY:	implicit_default
+implicit_default::
+		$(MAKE) subdirs
+
+subdirs::	$(SUBDIRS)
+$(SUBDIRS)::
+		cd $@ && $(MAKE) $(subtarget)
+
+# the following hack is needed for older make versions (gmake doesn't need it):
+init-depend::
+		@for dir in $(SUBDIRS); do\
+		  test -f $$dir/dependencies || touch $$dir/dependencies;\
+		done
+
+.DEFAULT::
+		$(MAKE) subdirs subtarget=$@
+
+distfiles::
+		echo makefile
+		for dir in $(SUBDIRS); do\
+		  subfiles=`cd $$dir && $(MAKE) -s $@`;\
+		  for file in $$subfiles; do\
+		    echo "$$dir/$$file";\
+		  done;\
+		done
+
+# dummy:
+install::
diff --git a/SecuritySNACCRuntime/c++-examples/simple/README b/SecuritySNACCRuntime/c++-examples/simple/README
new file mode 100644
index 00000000..18e5e2c5
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/simple/README
@@ -0,0 +1,111 @@
+(RCS control information is at the end of this file.)
+
+
+C++ Simple Example README
+-------------------------
+
+This directory should have 6 files in it:
+
+  README      - this file
+
+  genber.C    - C++ source code for a program that creates and encodes
+                a PersonnelRecord value to a file.
+
+  example.C   - C++ source code for a program that decodes a given
+                PersonnelRecord value and re-encodes it to stdout.
+
+  makefile    - compiles the example programs
+
+  good_pr.ber - BER encoding of a Personnel Record (all definite lengths)
+
+
+
+Type "make" to generate the 3 example programs:
+        genber
+        def
+        indef
+
+
+
+snacc is called from the makefile on .../asn1specs/p_rec.asn1 to
+generate the following files:
+
+p_rec.h  - C++ classes for PersonnelRecord types.
+
+p_rec.C  - C++ source code for the PersonnelRecord encode, decode,
+           print, and free methods.
+
+These source files are then compiled with example.C to make the
+programs def and indef.  Each program takes 1 argument, the name of a
+file containing an BER encoded PersonnelRecord value.
+
+
+Try the following:
+
+%1 genber                       # create a file called pr.ber
+%2 indef good_pr.ber > indef_pr.ber
+%3 def indef_pr.ber > def_pr.ber
+%4 diff good_pr.ber def_pr.ber  # should be no differences
+
+(commands 2-4 can be made via the `check' phony target.)
+
+The above commands decode the BER value in "good_pr.ber" and
+indef_pr.ber respectively and then re-encode them to stdout.
+Both programs will decode any valid BER representation of a
+PersonnelRecord value but, the def program will re-encode the
+given data using only the definite length BER format and the
+indef program will re-encode the given data using only the
+indefinite length BER format.
+
+Compare the lengths of the def_pr.ber and indef_pr.ber files,
+indefinite length encodings are usually larger.
+
+
+
+Things to Note
+--------------
+
+Look at genber.C to see how to build a C++ value and then encode it.
+look at the example.C file to see buffer usage.  Look at
+.../c++_lib/inc/asn_config.h and .../c++_lib/inc/asn_buf.h if you
+want to change the buffer managment.
+
+
+Snacc ASN.1 comment commands
+
+Notice the special "--snacc" ASN.1 comment in .../asn1specs/p_rec.asn1.
+
+PersonnelRecord ::= --snacc isPdu:"TRUE" -- [APPLICATION 0] IMPLICIT SET
+ { ... etc. ... }
+
+The "isPdu" flag tells snacc that the PersonnelRecord is a PDU type.
+This flag has no effect on the generated C++ code, since each type gets
+PDU members automatically for C++.
+
+
+
+Length formats
+
+Both the def and indef programs were generated from the same source
+file, example.c.  Indefinite length encoders can be created by giving
+the -DUSE_INDEF_LEN flag to the C++ compiler when compiling.  Currently
+the indefinite/definite length encoder choice is made a compile time.
+To change this to a run-time decision, a simple solution would be to
+modify BerEncodeConsLen and BerEncodeEocIfNec macros in
+.../c++_lib/inc/asn_len.h to check a global flag.
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/simple/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:57  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1994/10/08 04:43:46  rj
+# the test csh skript has been integrated into the makefile
+#
+# Revision 1.1  1994/08/31  08:48:05  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
diff --git a/SecuritySNACCRuntime/c++-examples/simple/example.C b/SecuritySNACCRuntime/c++-examples/simple/example.C
new file mode 100644
index 00000000..1dcccf2a
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/simple/example.C
@@ -0,0 +1,142 @@
+/*
+ * 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/simple/example.C - an example of how to use  C++ ASN.1-BER
+//             encoders and decoders generated by snacc
+//
+// AUTHOR: Mike Sample
+// DATE:   Aug 92
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/simple/example.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Log: example.C,v $
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1.1.1  1999/03/16 18:05:57  aram
+// Originals from SMIME Free Library.
+//
+// Revision 1.5  1995/07/24 15:36:03  rj
+// check return value of new.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1995/02/18  13:54:18  rj
+// added #define HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS since not every C++ compiler provides them.
+//
+// Revision 1.3  1994/10/08  01:27:02  rj
+// several \size_t'
+//
+// Revision 1.2  1994/08/31  08:56:32  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+//
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fstream.h>
+#include "asn-incl.h"
+#include "p-rec.h"
+
+
+main (int argc, char *argv[])
+{
+    AsnBuf  inputBuf;
+    AsnBuf  outputBuf;
+    size_t encodedLen;
+    size_t decodedLen;
+    size_t      dataSize;
+    ifstream dataFile;
+    PersonnelRecord pr;
+
+    if (argc != 2)
+    {
+        cerr << "Usage: " << argv[0] << " <BER data file name>" << endl;
+        cerr << "   Decodes the given PersonnelRecord BER data file" << endl;
+        cerr << "   and re-encodes it to stdout" << endl;
+        exit (1);
+    }
+
+
+    // open the data file
+    dataFile.open (argv[1]);
+
+    if (!dataFile)
+    {
+        perror ("ifstream::open");
+        exit (1);
+    }
+
+    // get size of the data file file
+    dataFile.seekg (0, ios::end);
+    dataSize = dataFile.tellg();
+    dataFile.seekg (0);
+
+    // read data from file into contiguous block for a buffer
+#if HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS
+    char data[dataSize];
+#else
+    char *data = new char[dataSize];
+    if (!data)
+	return 1;
+#endif /* HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS */
+    dataFile.read (data, dataSize);
+    dataFile.close();
+
+    //
+    // put the BER data read from the file
+    // into buffer format, ready for reading from the
+    // beginning
+    //
+    inputBuf.InstallData (data, dataSize);
+
+    if (!pr.BDecPdu (inputBuf, decodedLen))
+    {
+        cerr << "--- ERROR - Decode routines failed, exiting..." << endl;
+        exit (1);
+    }
+
+    cerr  << "decodedValue PersonnelRecord ::= " << pr << endl << endl;
+
+    //
+    // allocate a new buffer set up for writing to
+    //
+#if HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS
+    char outputData[dataSize + 512];
+#else
+    char *outputData = new char[dataSize + 512];
+    if (!outputData)
+	return 1;
+#endif /* HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS */
+    outputBuf.Init (outputData, dataSize+512);
+    outputBuf.ResetInWriteRvsMode();
+
+    if (!pr.BEncPdu (outputBuf, encodedLen))
+    {
+        cerr << "--- ERROR - Encode routines failed" << endl;
+    }
+
+    // write the BER value to cout
+    outputBuf.ResetInReadMode();
+    for (; encodedLen > 0; encodedLen--)
+        cout.put (outputBuf.GetByte());
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c++-examples/simple/genber.C b/SecuritySNACCRuntime/c++-examples/simple/genber.C
new file mode 100644
index 00000000..daac80b4
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/simple/genber.C
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++examples/simple/genber.C---builds an PersonnelRecord value and writes BER form of the value to a file called "pr.ber"
+//
+// MS 92
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/simple/genber.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Log: genber.C,v $
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1.1.1  1999/03/16 18:05:57  aram
+// Originals from SMIME Free Library.
+//
+// Revision 1.5  1995/07/24 15:40:32  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1994/12/11  15:36:14  rj
+// const for a constant value [DEC]
+//
+// Revision 1.3  1994/10/08  01:27:03  rj
+// several \size_t'
+//
+// Revision 1.2  1994/08/31  08:56:33  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+//
+
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fstream.h>
+
+#include "asn-incl.h"
+#include "p-rec.h"
+
+
+main (int argc, char *argv[])
+{
+    ofstream outputFile;
+    AsnBuf outputBuf;
+    size_t encodedLen;
+    const size_t dataSize = 1024;
+    char data[dataSize];
+    ChildInformation *ciPtr;
+    PersonnelRecord pr;
+
+    // build internal value of a PersonnelRecord
+    pr.name = new Name;
+    pr.name->givenName = "John";  // this calls pr.name->givenName.Set ("John");
+    pr.name->initial = "E";
+    pr.name->familyName = "Smith";
+
+    pr.title.Set ("The Big Cheese");
+    pr.employeeNumber = 99999;
+    pr.dateOfHire.Set ("19820104");
+
+    pr.nameOfSpouse = new Name;
+    pr.nameOfSpouse->givenName.Set ("Mary");
+    pr.nameOfSpouse->initial.Set ("L");
+    pr.nameOfSpouse->familyName.Set ("Smith");
+
+    pr.children = new PersonnelRecordSeqOf;
+
+    ciPtr = pr.children->Append();
+    ciPtr->name = new Name;
+    ciPtr->name->givenName.Set ("James");
+    ciPtr->name->initial.Set ("R");
+    ciPtr->name->familyName.Set ("Smith");
+    ciPtr->dateOfBirth.Set ("19570310");
+
+    ciPtr = pr.children->Append();
+    ciPtr->name = new Name;
+    ciPtr->name->givenName.Set ("Lisa");
+    ciPtr->name->initial.Set ("M");
+    ciPtr->name->familyName.Set ("Smith");
+    ciPtr->dateOfBirth.Set ("19610621");
+
+
+    // set up buffer for writing to
+    outputBuf.Init (data, dataSize);
+    outputBuf.ResetInWriteRvsMode();
+
+    // encode the internal value we just build into the buffer
+    if (!pr.BEncPdu (outputBuf, encodedLen))
+        cout << "failed encoding AnyTestType value" << endl;
+
+    // open file to hold the BER value
+    outputFile.open ("pr.ber");
+    if (!outputFile)
+    {
+        perror ("ofstream::open");
+        exit (1);
+    }
+
+    // copy the BER value from the buffer to the file
+    outputBuf.ResetInReadMode();
+    for (; encodedLen > 0; encodedLen--)
+        outputFile.put (outputBuf.GetByte());
+
+
+    cout << "Wrote the following BER PersonnelRecord value to pr.ber." << endl;
+    cout << "Test it with \"def\" and \"indef\"." << endl;
+    cout << pr << endl;
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c++-examples/simple/good-pr.ber b/SecuritySNACCRuntime/c++-examples/simple/good-pr.ber
new file mode 100644
index 0000000000000000000000000000000000000000..f8cc9410ed7be7741ca4c0e0805cce1fbee7df6a
GIT binary patch
literal 145
zcmYdj>`N37WAVz*$P;696=My~%`C}SARxvUl98(5l$oyJoROMZoEqQAz|7b-e<7DM
zhoPl~k%6Is$s!?;M&HDuN-;(ssK&*PhVqGmVys??xv9lsj6pE-z}igB4U7#94CO%D
Td@_p@#Tb22<jo8X%!~{HLggjQ

literal 0
HcmV?d00001

diff --git a/SecuritySNACCRuntime/c++-examples/simple/makefile b/SecuritySNACCRuntime/c++-examples/simple/makefile
new file mode 100644
index 00000000..483b5c90
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/simple/makefile
@@ -0,0 +1,158 @@
+# c++-examples/simple/makefile
+#
+# WARNING: this makefile isn't safe for parallel making!
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/simple/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.2  2000/06/08 19:59:04  dmitch
+# Mods for X port.
+#
+# Revision 1.1.1.1  1999/03/16 18:05:57  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.9  1997/02/16 16:47:58  rj
+# made return *this after calling abort()'' a compile time option.
+#
+# Revision 1.8  1995/07/24  15:29:44  rj
+# `cd && make' instead of `cd; make'.
+#
+# changed `_' to `-' in file names.
+#
+# Revision 1.7  1995/02/20  11:47:37  rj
+# build snacc if it doesn't exist.
+# some makes leave a trailing slash on $(@D), others don't. this causes some mkdir(1)s to deny their cooperation. therefore, the slash has got to be stripped.
+#
+# Revision 1.6  1995/02/13  14:58:14  rj
+# augment CPPFLAGS, not overwrite
+#
+# Revision 1.5  1994/10/08  04:35:59  rj
+# enhance portability by using standard make capabilities instead of utilies (basename, dirname) not found on every platform.
+#
+# for the dependencies, generate the snacc compiler if it doesn't exist.
+#
+# Revision 1.4  1994/09/01  02:26:54  rj
+# use CXX instead of CC to get another default linkage
+#
+# Revision 1.3  1994/08/31  21:40:00  rj
+# rebuild the executables when the c++-lib is newer.
+# the file good-pr.ber needs to be distributed.
+#
+# Revision 1.2  1994/08/31  10:31:50  rj
+# since .o files get moved, a few more dependencies are needed.
+#
+# Revision 1.1  1994/08/31  08:48:10  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../../makehead
+
+TOP		= ../..
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+
+ASN1_C++_LIB_DIR	= $(TOP)/c++-lib
+BUILD_DIR           = /Data_and_Apps/dmitchBuild
+ASN1_C++_INC_DIR	= $(ASN1_C++_LIB_DIR)/inc
+#ASN1_C++_LIB		= $(ASN1_C++_LIB_DIR)/libasn1c++.a
+#ASN1_C++_LIB		= $(BUILD_DIR)/libsnacc++.a
+ASN1_C++_LIB		= -framework snaccRuntime -F/Data_and_Apps/dmitchBuild -lstdc++
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+USEFUL_TYPES	= $(ASN1_SRC_DIR)/asn-useful.asn1
+SNACCFLAGS	= -C $(SNACC_NOVOLAT) -u $(USEFUL_TYPES)
+
+CC		= $(CXX)
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C++_INC_DIR) $(LENFLAG)
+
+ASN1FILES	= $(ASN1_SRC_DIR)/p-rec.asn1
+
+# generated by snacc from p-rec.asn1:
+ASN1HFILES	= p-rec.h
+ASN1CFILES	= p-rec.cpp
+
+CFILES = \
+	genber.C	\
+	example.C
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(CFILES)	\
+	good-pr.ber
+
+#-------------------------------------------------------------------------------
+
+all::		genber def indef
+
+$(ASN1HFILES)	\
+$(ASN1CFILES):	$(SNACC) $(ASN1FILES)
+		$(REASON)
+		$(SNACC) $(SNACCFLAGS) $(ASN1FILES)
+
+$(SNACC):
+		cd $(@D) && $(MAKE) $(@F)
+
+def-obj		\
+indef-obj:
+		mkdir $@
+
+def-obj/p-rec.o	\
+def-obj/example.o:
+		$(REASON)
+		$(MAKE) LENFLAG= `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+indef-obj/p-rec.o	\
+indef-obj/example.o:
+		$(REASON)
+		$(MAKE) LENFLAG=-DUSE_INDEF_LEN `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+genber:		def-obj/p-rec.o genber.o
+		$(REASON)
+		$(CXX) $(LDFLAGS) -o $@ def-obj/p-rec.o genber.o $(ASN1_C++_LIB) $(LIBS)
+
+def: 		def-obj/p-rec.o def-obj/example.o
+		$(REASON)
+		$(CXX) $(LDFLAGS) -o $@ def-obj/p-rec.o def-obj/example.o $(ASN1_C++_LIB) $(LIBS)
+
+indef:		indef-obj/p-rec.o indef-obj/example.o
+		$(REASON)
+		$(CXX) $(LDFLAGS) -o $@ indef-obj/p-rec.o indef-obj/example.o $(ASN1_C++_LIB) $(LIBS)
+
+genber	\
+def	\
+indef:		
+
+.PHONY:	check
+
+check::		def indef
+		$(RM) foo.ber bar.ber
+		./indef good-pr.ber > foo.ber
+		./def foo.ber > bar.ber
+		@if cmp -s bar.ber good-pr.ber; then\
+		  echo "+++ Passed simple encode/decode tests using p-rec.asn1.";\
+		else\
+		  echo "--- Failed simple encode/decode tests using p-rec.asn1.";\
+		fi
+		$(RM) foo.ber bar.ber
+
+clean::
+		$(RM) *.o *~ .emacs* core def indef genber pr.ber $(ASN1HFILES) $(ASN1CFILES)
+		$(RM) -r def-obj indef-obj
+		$(RM) foo.ber bar.ber
+
+depend::	$(SNACC)
+
+include ../../maketail
+
+depend::
+		cp dependencies deps
+		for dir in def-obj indef-obj; do\
+		  < dependencies sed -e 's:^\(.*\.o\):'"$$dir"'/\1:' >> deps;\
+		done
+		mv deps dependencies
diff --git a/SecuritySNACCRuntime/c++-examples/snmp/README b/SecuritySNACCRuntime/c++-examples/snmp/README
new file mode 100644
index 00000000..2662d287
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/snmp/README
@@ -0,0 +1,132 @@
+(RCS control information is at the end of this file.)
+
+
+C++ SNMP Example - Mike Sample Mar 92
+---------------------------------
+
+This example illustrates a few more features of the compiler than the
+simple example.  It also shows some deficiencies.  No executable
+programs are generated by the makefile, it only generates the snmp
+code and compiles it without linking.
+
+This directory contains 2 files:
+        README
+        makefile
+
+Snacc generates source from the following ASN.1 files:
+        .../asn1specs/rfc1155-smi.asn1
+        .../asn1specs/rfc1157-snmp.asn1
+        .../asn1specs/rfc1213-mib2.asn1
+
+multi-module compilation
+   The IMPORT/EXPORT mechanisms of ASN.1 '88 are supported so you don't
+   have to dump all of the ASN.1 definitions into a single file
+   The order of the ASN.1 file arguments is the order that they
+   are included in the generated source files.  For example:
+
+   %1 snacc rfc1155-smi.asn1 rfc1157-snmp.asn1 rfc1213-mib2.asn1
+
+   causes the order in which hdr files are included in rfc1213-mib2.C
+   to be:
+
+   #include "asn-incl.h"
+   #include "rfc1155-smi.h"
+   #include "rfc1157-snmp.h"
+   #include "rfc1213-mib2.h"
+
+
+    Currently, snacc assumes that each ASN.1 file given on the command
+    line depends on all of the others on the command line.  There is
+    no attempt to compute the dependencies via the import lists alone.
+
+SNMP OBJECT-TYPE macro parsing / ANY type hash table
+   The SNMP OBJECT-TYPE macro is parsed.   This results in the
+   type in the "SYNTAX" part of the macro is put into
+   the ANY type hash table using the  OBJECT-TYPE macro's value as the
+   hash key.  Also if the type in the SYNTAX field is not defined
+   outsided of the macro (could be different tagging etc), a proper
+   type definition is generated for it.  If you want to change the way
+   the macro is handled, modify the corresponding routine in "do_macros.c".
+
+value definitions
+   The OBJECT IDENTIFIER values are turned into statically initialized
+   C++ values and included in the generated source and include file.  This
+   is also done for INTEGER and BOOLEAN values.  More complex values
+   are ignored by the compiler at the moment. (modify parse_vals.c if
+   you want to improve this)
+
+
+-P option of snacc is demonstrated
+   The ASN.1 for the parsed modules is generated from the internal data
+   structure.  This can be useful for making sure the compiler is
+   handling your ASN.1 files correctly.  It is also useful to see how
+   the types are modified and sorted to simplify code generation.
+   (see the file snacc.output after typeing "make")
+
+Deficiencies
+   A deficiency in parsing large integers is shown when parsing the
+   following rfc 1155 types:
+
+                  Counter ::=
+                      [APPLICATION 1]
+                          IMPLICIT INTEGER (0..4294967295)
+
+                  Gauge ::=
+                      [APPLICATION 2]
+                          IMPLICIT INTEGER (0..4294967295)
+
+                  TimeTicks ::=
+                      [APPLICATION 3]
+                          IMPLICIT INTEGER (0..4294967295)
+
+Due the size of a C long int the above ASN.1 is represented internally as:
+
+Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..-1)
+
+Gauge ::= [APPLICATION 2] IMPLICIT INTEGER (0..-1)
+
+TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..-1)
+
+The ASN.1 library contains routines for encoding/decoding unsigned
+long integers but you must hand code the cases where it is used - the
+compiler never generates code that calls them.
+
+Note also that the produced code for the SNMP ASN.1 must be modified
+to correclty handle the "Opaque" data type.  SNMP does not use the ANY
+DEFINED BY type in an effort to simplify things.  Instead an OCTET
+STRING is used to hold and encoded value whose type is defined by an
+OBJECT IDENTIFIER.  With some simple modifications you can use the
+snacc AsnAnyDefinedBy type instead of the OCTET STRING to achieve
+the desired results.
+
+This should underline the danger of blindly trusting the compiler to
+do the right thing for protocols such as SNMP or X.500 where the type
+of an encoded value depends on a mechanism outside of ASN.1 or the ANY
+type (ANY DEFINED BY types should work automatically).
+
+There is a problem when generating C++ code with the SNMP ASN.1 files.
+Several of the ASN.1 value names conflict with C++ keywords.  The
+generated code will not compile properly as a result.  The best way to
+fix these is to modify the ASN.1 files directly.  The compiler will
+munge field or type names to avoid conflicts with the target language
+but currently does not check value names.  The SNMP ASN.1 module shows
+this problem the with value "private" in rfc1155-smi.asn1.
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/snmp/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:58  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.3  1995/07/27 11:36:13  rj
+# rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme.
+#
+# Revision 1.2  1995/07/24  15:41:22  rj
+# changed `_' to `-' in file names.
+#
+# Revision 1.1  1994/08/31  08:48:13  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
diff --git a/SecuritySNACCRuntime/c++-examples/snmp/makefile b/SecuritySNACCRuntime/c++-examples/snmp/makefile
new file mode 100644
index 00000000..e538256b
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/snmp/makefile
@@ -0,0 +1,115 @@
+# c++-examples/snmp/makefile
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/snmp/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.3  2000/12/22 00:03:17  dmitch
+# Misc. updates for clean build on Cheetah 1D7.
+#
+# Revision 1.2  2000/06/08 19:59:20  dmitch
+# Mods for X port.
+#
+# Revision 1.1.1.1  1999/03/16 18:05:58  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.10  1997/02/16 16:48:08  rj
+# made return *this after calling abort()'' a compile time option.
+#
+# Revision 1.9  1995/07/27  11:59:01  rj
+# rfc1213-mib -> rfc1213-mib2
+#
+# Revision 1.8  1995/07/27  08:29:58  rj
+# rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme.
+#
+# Revision 1.7  1995/07/24  15:30:11  rj
+# `cd && make' instead of `cd; make'.
+#
+# changed `_' to `-' in file names.
+#
+# Revision 1.6  1995/02/20  11:48:41  rj
+# build snacc if it doesn't exist.
+#
+# Revision 1.5  1995/02/13  14:58:15  rj
+# augment CPPFLAGS, not overwrite
+#
+# Revision 1.4  1994/10/08  04:36:28  rj
+# for the dependencies, generate the snacc compiler if it doesn't exist.
+#
+# Revision 1.3  1994/09/01  02:26:56  rj
+# use CXX instead of CC to get another default linkage
+#
+# Revision 1.2  1994/08/31  23:25:41  rj
+# print a less irritating usage.
+#
+# Revision 1.1  1994/08/31  08:48:14  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../../makehead
+
+TOP		= ../..
+
+ASN1_SPEC_DIR	= $(TOP)/asn1specs
+
+ASN1_C++_LIB_DIR	= $(TOP)/c++-lib
+ASN1_C++_INC_DIR	= $(ASN1_C++_LIB_DIR)/inc
+ASN1_C++_LIB		= $(ASN1_C++_LIB_DIR)/libasn1c++.a
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+
+CC		= $(CXX)
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C++_INC_DIR) -F/System/Library/PrivateFrameworks
+
+ASN1FILES = \
+	$(ASN1_SPEC_DIR)/rfc1155-smi.asn1	\
+	$(ASN1_SPEC_DIR)/rfc1157-snmp.asn1	\
+	$(ASN1_SPEC_DIR)/rfc1213-mib2.asn1
+
+ASN1HFILES = \
+	rfc1155-smi.h	\
+	rfc1213-mib2.h	\
+	rfc1157-snmp.h
+
+ASN1CFILES = \
+	rfc1155-smi.cpp	\
+	rfc1213-mib2.cpp	\
+	rfc1157-snmp.cpp
+
+DISTFILES = \
+	README		\
+	makefile	\
+
+#-------------------------------------------------------------------------------
+
+default::	warning
+
+warning::
+		@echo ''
+		@echo 'read the README and enter `$(MAKE) fail` to test for yourself'
+		@echo ''
+
+fail::		$(ASN1HFILES) $(ASN1CFILES)
+		$(CXX) $(CPPFLAGS) $(CFLAGS) -c $(ASN1CFILES)
+
+$(ASN1HFILES)	\
+$(ASN1CFILES):	$(SNACC) $(ASN1FILES)
+		$(REASON)
+		$(SNACC) -P -C $(SNACC_NOVOLAT) $(ASN1FILES) > snacc.output~
+		mv snacc.output~ snacc.output
+
+$(SNACC):
+		cd $(@D) && $(MAKE) $(@F)
+
+check::
+		@echo "the purpose of this directories' contents is to show deficiencies."
+		@echo "if you want to exercise 'em, make the phony target "'`'"fail'"
+
+clean::
+		$(RM) *.o *~ .emacs* core $(ASN1HFILES) $(ASN1CFILES) snacc.output
+
+depend::	$(SNACC)
+
+include ../../maketail
diff --git a/SecuritySNACCRuntime/c++-examples/test-lib/README b/SecuritySNACCRuntime/c++-examples/test-lib/README
new file mode 100644
index 00000000..5cfeeecc
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/test-lib/README
@@ -0,0 +1,43 @@
+(RCS control information is at the end of this file.)
+
+
+C++ test_lib README
+-------------------
+
+This directory should have 3 files:
+        README - this file
+        makefile
+        test_lib.C
+
+Type "make" to compile test_lib.
+
+test_lib tests each encode and decode routine in the C++ ASN.1
+runtime library. Errors will be reported.
+
+test_lib should be run for each machine architecture you install snacc on.
+If you modify the library routines you should run test_lib again.
+
+The general testing methodology is:
+        1. test the buffer routines
+        2. test tags
+        3. test lengths
+        4. test each libarary type.
+
+For each type, a range of values is encoded and then decoded
+and and compared with the original value.
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/test-lib/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:58  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1997/02/16 20:25:29  rj
+# check-in of a few cosmetic changes
+#
+# Revision 1.1  1994/08/31  08:48:16  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
diff --git a/SecuritySNACCRuntime/c++-examples/test-lib/makefile b/SecuritySNACCRuntime/c++-examples/test-lib/makefile
new file mode 100644
index 00000000..e232a28d
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/test-lib/makefile
@@ -0,0 +1,68 @@
+# c++-examples/test-lib/makefile
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/test-lib/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.2  2000/12/22 00:03:29  dmitch
+# Misc. updates for clean build on Cheetah 1D7.
+#
+# Revision 1.1.1.1  1999/03/16 18:05:58  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.7  1997/03/03 11:58:30  wan
+# Final pre-delivery stuff (I hope).
+#
+# Revision 1.6  1997/02/28 13:39:41  wan
+# Modifications collected for new version 1.3: Bug fixes, tk4.2.
+#
+# Revision 1.5  1995/07/24 15:31:14  rj
+# changed `_' to `-' in file names.
+#
+# Revision 1.4  1995/02/13  14:58:17  rj
+# augment CPPFLAGS, not overwrite
+#
+# Revision 1.3  1994/09/01  02:26:58  rj
+# use CXX instead of CC to get another default linkage
+#
+# Revision 1.2  1994/08/31  21:44:25  rj
+# rebuild the executables when the c++-lib is newer.
+#
+# Revision 1.1  1994/08/31  08:48:17  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../../makehead
+
+TOP		= ../..
+
+ASN1_C++_LIB_DIR	= $(TOP)/c++-lib
+ASN1_C++_INC_DIR	= $(ASN1_C++_LIB_DIR)/inc
+ASN1_C++_LIB		= $(ASN1_C++_LIB_DIR)/libasn1c++.a
+
+CC		= $(CXX)
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C++_INC_DIR) -F/System/Library/PrivateFrameworks
+
+CFILES = \
+	test-lib.C
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(CFILES)
+
+#-------------------------------------------------------------------------------
+
+default::	check
+
+check::		test-lib
+		./test-lib
+
+test-lib:	$(ASN1_C++_LIB) test-lib.o
+		$(CXX) $(LDFLAGS) -o $@ test-lib.o $(ASN1_C++_LIB) $(LIBS) -lstdc++
+
+clean::
+		$(RM) *.o *~ .emacs* test-lib core
+
+include ../../maketail
diff --git a/SecuritySNACCRuntime/c++-examples/test-lib/test-lib.C b/SecuritySNACCRuntime/c++-examples/test-lib/test-lib.C
new file mode 100644
index 00000000..e57bc60b
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-examples/test-lib/test-lib.C
@@ -0,0 +1,815 @@
+/*
+ * 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
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-examples/test-lib/test-lib.C,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Log: test-lib.C,v $
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/08 19:59:34  dmitch
+// Mods for X port.
+//
+// Revision 1.1.1.1  1999/03/16 18:05:58  aram
+// Originals from SMIME Free Library.
+//
+// Revision 1.5  1997/02/28 13:39:42  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.4  1995/07/24 15:44:10  rj
+// #error "..." instead of #error ...
+//
+// changed `_' to `-' in file names.
+//
+// function and file names adjusted.
+//
+// Revision 1.3  1995/02/18  16:40:08  rj
+// utilize either isinf(3) or finite(3), whatever happens to be present.
+//
+// Revision 1.2  1994/08/31  08:56:35  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+//
+
+#include <stdio.h>
+#include <iostream.h>
+#include "asn-incl.h"
+
+
+int TestAsnBuffers();
+int TestAsnTag();
+int TestAsnLen();
+int TestAsnBool();
+int TestAsnInt();
+int TestAsnReal();
+int TestAsnOcts();
+int TestAsnBits();
+int TestAsnOid();
+int TestAsnList();
+
+const int bufSize = 256;
+
+int main()
+{
+    int isErr = false;
+
+    if (!TestAsnBuffers())
+    {
+        cout << "Failed buffer tests, no point in proceeding ... bye!" << endl;
+        return 1;
+    }
+
+    if (!TestAsnTag())
+    {
+        cout << "Failed Tag test." << endl;
+        isErr = true;
+    }
+
+    if (!TestAsnLen())
+    {
+        cout << "Failed Length test." << endl;
+        isErr = true;
+    }
+
+    if (!TestAsnBool())
+    {
+        cout << "Failed BOOLEAN test." << endl;
+        isErr = true;
+    }
+
+
+    if (!TestAsnInt())
+    {
+        cout << "Failed INTEGER test." << endl;
+        isErr = true;
+    }
+
+    if (!TestAsnOcts())
+    {
+        cout << "Failed OCTET STRING test." << endl;
+        isErr = true;
+    }
+
+
+    if (!TestAsnBits())
+    {
+        cout << "Failed BIT STRING test." << endl;
+        isErr = true;
+    }
+
+
+    if (!TestAsnOid())
+    {
+        cout << "Failed OBJECT IDENTIFIER test." << endl;
+        isErr = true;
+    }
+
+
+    if (!TestAsnReal())
+    {
+        cout << "Failed REAL test." << endl;
+        isErr = true;
+    }
+
+
+
+    if (isErr)
+    {
+        cout << "There are errors in the primitive type encoding/decoding" << endl;
+        cout << "library for this architecture.  Time for gdb..." << endl;
+    }
+    else
+    {
+        cout << "The primitive type encoding/decoding library passed simple tests." << endl;
+        cout << "It should be safe to use..." << endl;
+    }
+    return isErr;
+}
+
+
+/*
+ * returns true if passes encode/decode tests
+ */
+int
+TestAsnBuffers()
+{
+    AsnBuf  b;
+    char bufData[256];
+    int i,j;
+    int noErr = true;
+
+    // initialize buffer
+    b.Init (bufData, 256);
+    b.ResetInWriteRvsMode();
+
+    // write whole range of byte (0..255)
+    // remember, write works in reverse
+    for (i = 0; i < 256; i++)
+        b.PutByteRvs (i);
+
+    if (b.WriteError())
+    {
+        cout << "Error writing to buffer." << endl;
+        noErr = false;
+    }
+
+    // read in values & verify
+    b.ResetInReadMode();
+    for (i = 255; i >= 0; i--)
+        if (b.GetByte() != i)
+        {
+            cout << "Error verifying data written to buffer." << endl;
+            noErr = false;
+        }
+
+    if (b.ReadError())
+    {
+        cout << "Error reading from buffer." << endl;
+        noErr = false;
+    }
+
+
+    /* now make sure errors are detected */
+    b.ResetInWriteRvsMode();
+
+    for (i = 0; i < 257; i++) // write past end of buffer
+        b.PutByteRvs (0);
+
+    if (!b.WriteError())
+    {
+        cout << "Buffers failed to report buffer write overflow." << endl;
+        noErr = false;
+    }
+
+
+    b.ResetInReadMode();
+    for (i = 256; i >= 0; i--)  // read past end of buffer
+        b.GetByte();
+
+    if (!b.ReadError())
+    {
+        cout << "Buffers failed to report buffer read overflow." << endl;
+        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;
+    AsnBuf  b;
+    char bufData[256];
+    long int val;
+    BER_CLASS tagClass;
+    BER_FORM form;
+    BER_UNIV_CODE code;
+
+
+    /* initialize buffer */
+    b.Init (bufData, 256);
+
+    /* encode a TRUE value and verify */
+    tagClass = UNIV;
+    form = PRIM;
+    code = INTEGER_TAG_CODE;
+    aTag1 = MAKE_TAG_ID (tagClass, form, code);
+
+    for (i = 0; i < 2; i++)
+    {
+        b.ResetInWriteRvsMode();
+        len1 = BEncTag1 (b, tagClass, form, code);
+
+        if (b.WriteError())
+        {
+            noErr = false;
+            cout << "Error encoding a Tag." << endl;
+        }
+
+        b.ResetInReadMode();
+
+        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;
+            cout << "Error decoding a Tag - error number " << val << endl;
+        }
+        if (noErr && ((aTag2 != aTag1) || (len1 != len2)))
+        {
+            noErr = false;
+            cout << "Error decoded Tag does not match encoded Tag." << endl;
+        }
+        /* set a new test tag value */
+        tagClass = CNTX;
+        form = CONS;
+        code = (BER_UNIV_CODE) 29;
+        aTag1 = MAKE_TAG_ID (tagClass, 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;
+    AsnBuf  b;
+    char bufData[256];
+    long int val;
+
+    /* initialize buffer */
+    b.Init (bufData, 256);
+
+
+    /* encode a TRUE value and verify */
+    aLen1 = 99999;
+    for (i = 0; i < 2; i++)
+    {
+        b.ResetInWriteRvsMode();
+        len1 = BEncDefLen (b, aLen1);
+
+        if (b.WriteError())
+        {
+            noErr = false;
+            cout <<  "Error encoding Length." << endl;
+        }
+
+        b.ResetInReadMode();
+
+        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;
+            cout << "Error decoding Length - error number " << val << endl;
+        }
+
+
+        if (noErr && ((aLen2 != aLen1) || (len1 != len2)))
+        {
+            noErr = false;
+            cout << "Error - decoded length does not match encoded length" << endl;
+        }
+        aLen1 = 2;
+    }
+
+
+    /* test indef len */
+    b.ResetInWriteRvsMode();
+    len1 = BEncIndefLen (b);
+
+    if (b.WriteError())
+    {
+        noErr = false;
+        cout << "Error encoding indefinite Length." << endl;
+    }
+
+    b.ResetInReadMode();
+
+    aLen2 = 0;
+
+    /* make sure no decode errors */
+    len2 = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+        aLen2 = BDecLen (b, len2, env);
+    }
+    else
+    {
+        noErr = false;
+        cout << "Error decoding Length - error number " << val << endl;
+    }
+
+
+    if (noErr && ((aLen2 != INDEFINITE_LEN) || (len1 != len2)))
+    {
+        noErr = false;
+        cout << "Error - decoded length does not match encoded length" << endl;
+    }
+
+    /* test EOC */
+    b.ResetInWriteRvsMode();
+    len1 = BEncEoc (b);
+
+    if (b.WriteError())
+    {
+        noErr = false;
+        cout << "Error encoding indefinite Length." << endl;
+    }
+
+    b.ResetInReadMode();
+
+    aLen2 = 0;
+
+    /* make sure no decode errors */
+    len2 = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+        BDecEoc (b, len2, env);
+    }
+    else
+    {
+        noErr = false;
+        cout << "Error decoding Length - error number " <<  val << endl;
+    }
+
+
+    if (noErr && (len1 != len2))
+    {
+        noErr = false;
+        cout << "Error - decoded EOC length error" << endl;
+    }
+
+    return noErr;
+}  /* TestAsnLen */
+
+
+
+/*
+ * returns true if passes encode/decode tests
+ */
+int
+TestAsnBool()
+{
+    AsnBuf  b;
+    char bufData[bufSize];
+    AsnBool aBool1;
+    AsnBool aBool2;
+    int j;
+    AsnLen len1;
+    AsnLen len2;
+    int noErr = true;
+
+    // initialize a small buffer
+    b.Init (bufData, bufSize);
+    b.ResetInWriteRvsMode();
+
+    // encode a true value and verify
+    aBool1 = true;
+
+    if (!aBool1.BEncPdu (b, len1))
+    {
+        noErr = false;
+        cout << "Error encoding TRUE BOOLEAN value." << endl;
+    }
+
+    b.ResetInReadMode();
+
+    aBool2 = false; // set to opposite of expected value
+
+    // make sure no decode errors and that it decodes to true
+    if (!aBool2.BDecPdu (b, len2) || !aBool2 || (len1 != len2))
+    {
+        noErr = false;
+        cout << "Error decoding TRUE BOOLEAN value." << endl;
+    }
+
+    // now encode a false value and verify
+    b.ResetInWriteRvsMode();
+    aBool1 = false;
+
+    if (!aBool1.BEncPdu (b, len1))
+    {
+        noErr = false;
+        cout << "Error encoding FALSE BOOLEAN value." << endl;
+    }
+
+    b.ResetInReadMode();
+
+    aBool2 = true; // set to opposite of expected value
+
+    // make sure no decode errors and that it decodes to false
+    if (!aBool2.BDecPdu (b, len2) || aBool2 || (len1 != len2))
+    {
+        noErr = false;
+        cout << "Error decoding FALSE BOOLEAN value." << endl;
+    }
+
+    return noErr;
+}  /* TestAsnBool */
+
+
+/*
+ * returns true if passes encode/decode tests
+ */
+int
+TestAsnInt()
+{
+    AsnBuf  b;
+    char bufData[bufSize];
+    AsnInt a1;
+    AsnInt a2;
+    int i,j, sign;
+    AsnLen len1;
+    AsnLen len2;
+    int noErr = true;
+
+    // initialize a small buffer
+    b.Init (bufData, bufSize);
+
+    //
+    // Encode a range of integers: negative & positive in
+    //  the 1 to sizeof (long int) range
+    //
+
+    sign = 1;
+    for (j = 0; j < 2; j++)
+    {
+        for (i = 0; i < sizeof (long int); i++)
+        {
+            b.ResetInWriteRvsMode();
+
+            a1 = sign * (17 << (i * 8)); // 17 is a random choice
+            if (!a1.BEncPdu (b, len1))
+            {
+                noErr = false;
+                cout << "Error encoding INTEGER value " << a1 << "." << endl;
+            }
+
+            b.ResetInReadMode();
+            a2 = 0;
+
+            // make sure no decode errors and that it decodes to the correc val
+            if (!a2.BDecPdu (b, len2) || (a2 != a1) || (len1 != len2))
+            {
+                noErr = false;
+                cout << "Error decoding INTEGER value " << a1 << "." << endl;
+            }
+        }
+        sign = -1;
+    }
+
+    return noErr;
+
+} /* TestAsnInt */
+
+
+/*
+ * returns true if passes encode/decode tests
+ */
+int
+TestAsnOcts()
+{
+    AsnBuf  b;
+    char bufData[bufSize];
+    AsnOcts a1;
+    AsnOcts a2;
+    int i,j;
+    AsnLen len1;
+    AsnLen len2;
+    int noErr = true;
+
+    // initialize a small buffer
+    b.Init (bufData, bufSize);
+
+    a1 = "Hello Gumby?";
+    for (j = 0; j < 2; j++)
+    {
+        b.ResetInWriteRvsMode();
+
+        if (!a1.BEncPdu (b, len1))
+        {
+            noErr = false;
+            cout << "Error encoding OCTET STRING value " << a1 << "." << endl;
+        }
+
+        b.ResetInReadMode();
+
+        // make sure no decode errors and that it decodes to the correc val
+        if (!a2.BDecPdu (b, len2) || (a2 != a1) || (len1 != len2))
+        {
+            noErr = false;
+            cout << "Error decoding OCTET STRING value " << a1 << "." << endl;
+        }
+        a1 = ""; // try an empty string
+    }
+
+    return noErr;
+
+} /* TestAsnOcts */
+
+
+
+/*
+ * returns true if passes encode/decode tests
+ */
+int
+TestAsnBits()
+{
+    AsnBuf  b;
+    char bufData[bufSize];
+    AsnBits a1 (32);
+    AsnBits a2 (32);
+    short bitsToSet[32] = { 0, 1, 0, 0, 1, 1, 0, 1,
+                            0, 1, 0, 0, 1, 1, 0, 1,
+                            0, 1, 0, 0, 1, 1, 0, 1,
+                            0, 1, 0, 0, 1, 1, 0, 1 };
+    int i,j;
+    AsnLen len1;
+    AsnLen len2;
+    int noErr = true;
+
+    // initialize a small buffer
+    b.Init (bufData, bufSize);
+
+
+    // set some bits
+    for (i = 0; i < 32; i++)
+    {
+        if (bitsToSet[i])
+            a1.SetBit (i);
+        else
+            a1.ClrBit (i);
+
+    }
+
+    b.ResetInWriteRvsMode();
+    if (!a1.BEncPdu (b, len1))
+    {
+        noErr = false;
+        cout << "Error encoding BIT STRING value " << a1 << "." << endl;
+    }
+
+    b.ResetInReadMode();
+
+    // make sure no decode errors and that it decodes to the correc val
+    if (!a2.BDecPdu (b, len2) || (a2 != a1) || (len1 != len2))
+    {
+        noErr = false;
+        cout << "Error decoding BIT STRING value " << a1 << "." << endl;
+    }
+
+
+    return noErr;
+
+} /* TestAsnBits */
+
+
+
+/*
+ * returns true if passes encode/decode tests
+ */
+int
+TestAsnOid()
+{
+    AsnBuf  b;
+    char bufData[bufSize];
+    AsnOid a1 (0,1,2,3,4,5,6);
+    AsnOid a2;
+    AsnOid a3 (2,38,29,40,200,10,4000);
+    int i,j;
+    AsnLen len1;
+    AsnLen len2;
+    int noErr = true;
+
+    // initialize a small buffer
+    b.Init (bufData, bufSize);
+
+    for (i = 0; i < 2; i++)
+    {
+        b.ResetInWriteRvsMode();
+
+        if (!a1.BEncPdu (b, len1))
+        {
+            noErr = false;
+            cout << "Error encoding OBJECT IDENTIFIER value " << a1 << "." << endl;
+        }
+
+        b.ResetInReadMode();
+
+        // make sure no decode errors and that it decodes to the correc val
+        if (!a2.BDecPdu (b, len2) || (a2 != a1) || (len1 != len2))
+        {
+            noErr = false;
+            cout << "Error decoding OBJECT IDENTIFIER value " << a1 << "." << endl;
+        }
+
+        a1 = a3;
+    }
+    return noErr;
+
+} /* TestAsnOid */
+
+/*
+ * returns true if passes encode/decode tests
+ *
+ * NOT USED - nuked template design.
+ */
+/*
+int
+TestAsnList()
+{
+    AsnBuf  b;
+    char bufData[bufSize];
+    AsnList<AsnInt> intList1;
+    AsnList<AsnInt> intList2;
+    AsnList<AsnBool> boolList1;
+    AsnList<AsnBool> boolList2;
+    int i,j;
+    AsnLen len1;
+    AsnLen len2;
+    int noErr = true;
+
+    b.Init (bufData, bufSize);
+
+    b.ResetInWriteRvsMode();
+
+    if (!intList1.BEncPdu (b, len1))
+    {
+        noErr = false;
+        cout << "Error encoding SEQUENCE OF value " << intList1 << "." << endl;
+    }
+
+    b.ResetInReadMode();
+
+    if (!intList2.BDecPdu (b, len2) || (len1 != len2))
+    {
+        noErr = false;
+        cout << "Error decoding SEQUENCE OF value " << intList1 << "." << endl;
+    }
+    cout << "intlist 1 = "  <<  intList1 << endl;
+    cout << "intlist 2 = "  <<  intList1 << endl;
+
+
+    if (!boolList1.BEncPdu (b, len1))
+    {
+        noErr = false;
+        cout << "Error encoding SEQUENCE OF value " << boolList1 << "." << endl;
+    }
+
+    b.ResetInReadMode();
+
+    if (!boolList2.BDecPdu (b, len2) ||  (len1 != len2))
+    {
+        noErr = false;
+        cout << "Error decoding SEQUENCE OF value " << boolList1 << "." << endl;
+    }
+    cout << "boolList 1 = "  <<  boolList1 << endl;
+    cout << "boolList 2 = "  <<  boolList1 << endl;
+
+    return noErr;
+
+}  TestAsnList */
+
+
+
+/*
+ * returns true if passes encode/decode tests
+ */
+int
+TestAsnReal()
+{
+#ifdef	__APPLE__
+	/* we don't seem to have any of this stuff */
+	return true;
+#else
+    AsnBuf  b;
+    char bufData[bufSize];
+    AsnReal  a2;
+    AsnReal  a[] = { 0.0, 0.8, -22.484848, PLUS_INFINITY, MINUS_INFINITY};
+    int i,j;
+    AsnLen len1;
+    AsnLen len2;
+    int noErr = true;
+
+
+    /*
+     * 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 ((double)PLUS_INFINITY)) || !isinf ((double)MINUS_INFINITY))
+#else
+#if HAVE_FINITE
+    if (finite ((double)PLUS_INFINITY) || finite ((double)MINUS_INFINITY))
+#else
+  #error "oops: you've got neither isinf(3) nor finite(3)?!"
+#endif
+#endif
+    {
+        cout << "WARNING: PLUS_INFINITY and MINUS_INFINITY in .../c++-lib/src/asn-real.C are" << endl;
+        cout << "not correct for this architecture.  Modify the AsnPlusInfinity() routine." << endl;
+    }
+
+
+    // initialize a small buffer
+    b.Init (bufData, bufSize);
+
+    for (i = 0; i < 5; i++)
+    {
+        b.ResetInWriteRvsMode();
+
+        if (!a[i].BEncPdu (b, len1))
+        {
+            noErr = false;
+            cout << "Error encoding REAL value " << a[i] << "." << endl;
+        }
+
+        b.ResetInReadMode();
+
+        // make sure no decode errors and that it decodes to the correc val
+        if (!a2.BDecPdu (b, len2) || (a2 != a[i]) || (len1 != len2))
+        {
+            noErr = false;
+            cout << "Error decoding REAL value " << a[i] << "." << endl;
+        }
+    }
+
+    return noErr;
+#endif
+} /* TestAsnReal */
diff --git a/SecuritySNACCRuntime/c++-lib/README b/SecuritySNACCRuntime/c++-lib/README
new file mode 100644
index 00000000..5328044c
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/README
@@ -0,0 +1,34 @@
+(RCS control information is at the end of this file.)
+
+
+C++ ASN.1 library README
+------------------------
+
+This directory contains the class definitions and the encode, decode,
+free and print methods for all of the built-in ASN.1 types.  It also
+contains buffer routines.
+
+The makefile will produce one or two libraries, libasn1c++.a and
+libasn1tcl.a.
+Whether the tcl library is to be generated or not is determined at
+configuration time.
+
+In addition to the normal C++ libraries contents, the Tcl library
+contains the meta code and the Tcl interface described in the
+documentation.
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/README,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:59  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.3  1995/07/24 15:45:53  rj
+# mention meta code and tcl interface and their additional libary.
+#
+# Revision 1.2  1994/09/01  00:55:55  rj
+# textual change to adapt to change of directory tree.
+#
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-any.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-any.cpp
new file mode 100644
index 00000000..9b183df8
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-any.cpp
@@ -0,0 +1,330 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-any.C
+//
+// MS 92
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//
+// ------------------------------------------------------------------------
+// -  J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3  -
+// ------------------------------------------------------------------------
+// 
+// All modification are relative to the v1.3 of SNACC.  We used SunOS 4.1.3's 
+// SCCS.  The revision #'s start at 1.1,  which is the original version from 
+// SNACC 1.3.
+// 
+// 
+// ../SCCS/s.asn-any.C:
+// 
+// D 1.2	98/05/01 13:47:09 pleonber	2 1	00046/00007/00164
+// added destructor and copy for CSM_Buffer handling.
+// 
+// D 1.1	98/05/01 13:19:19 pleonber	1 0	00171/00000/00000
+// date and time created 98/05/01 13:19:19 by pleonber
+// 
+// ----------------------- End of VDA Modifications ---------------------------
+// 
+// 
+// 
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-any.cpp,v 1.3 2001/06/27 23:09:14 dmitch Exp $
+// $Log: asn-any.cpp,v $
+// Revision 1.3  2001/06/27 23:09:14  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.2  2001/06/25 22:44:17  dmitch
+// Globalize hashTblLock with a ModuleNexus. Partial fix for Radar 2664258.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.6  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.5  2000/12/20 00:51:37  dmitch
+// Cosmetic changwe to resync with ../c++/asn-any.cpp.
+//
+// Revision 1.4  2000/12/20 00:43:14  dmitch
+// Acquire and release hashTblLock via an StLock.
+//
+// Revision 1.3  2000/12/07 22:32:03  dmitch
+// Thread-safe mods:  see comments for same file in ../c++/.
+//
+// Revision 1.2  2000/12/07 22:13:45  dmitch
+// Thread-safe mods: added hashTblLock.
+//
+// Revision 1.1  2000/06/15 18:44:59  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:37  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.5  1999/03/21 02:07:35  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.4  1999/03/19 23:59:21  mb
+// Invoke Print on our value since CSM_Buffer::Print now implements print too.
+//
+// Revision 1.3  1999/03/19 00:55:01  mb
+// Made CSM_Buffer a subclass of AsnType.
+//
+// Revision 1.2  1999/03/18 22:35:28  mb
+// Made all destructors virtual.
+//
+// Revision 1.1  1999/02/25 05:21:49  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/28 13:39:43  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.5  1997/02/16 20:26:01  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/24  20:12:48  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:20  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:10  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:55  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-incl.h"
+#include "sm_vdasnacc.h"
+
+//#include "asn-config.h"
+//#include "asn-len.h"
+//#include "asn-tag.h"
+//#include "asn-type.h"
+//#include "asn-oid.h"
+//#include "asn-int.h"
+//#include "asn-any.h"
+
+
+#ifdef	__APPLE__
+#include <Security/threading.h>
+#include <Security/globalizer.h>
+Table *AsnAny::oidHashTbl = NULL;
+Table *AsnAny::intHashTbl = NULL;
+ModuleNexus<Mutex> hashTblLock;
+#endif
+
+// Define this ANY value's type to the one that the given id hashes
+// to in the ANY table.
+void
+AsnAny::SetTypeByInt (AsnInt id)
+{
+    Hash hash;
+    void *anyInfo;
+
+    /* use int as hash string */
+    AsnIntType idval = (AsnIntType) id;
+    hash = MakeHash ((char*)&idval, sizeof (idval));
+	#ifdef	__APPLE__
+	StLock<Mutex> _(hashTblLock());
+	#endif
+	if (CheckForAndReturnValue (intHashTbl, hash, &anyInfo))
+		ai = (AnyInfo*) anyInfo;
+	else
+		ai = NULL; /* indicates failure */
+
+} /* SetAnyTypeByInt */
+
+// Define this ANY value's type to the one that the given id hashes
+// to in the ANY table.
+void AsnAny::SetTypeByOid (AsnOid &id)
+{
+    Hash hash;
+    void *anyInfo;
+
+    /* use encoded oid as hash string */
+    hash = MakeHash (id.Str(), id.Len());
+
+	#ifdef	__APPLE__
+	StLock<Mutex> _(hashTblLock());
+	#endif
+
+	if (CheckForAndReturnValue (oidHashTbl, hash, &anyInfo))
+		ai = (AnyInfo*) anyInfo;
+	else
+		ai = NULL; /* indicates failure */
+
+} /* SetAnyTypeByOid */
+
+
+
+// Given an integer, intId, to hash on, the type and it's anyId
+// are installed in the integer id hash tbl
+void
+AsnAny::InstallAnyByInt (AsnInt intId, int anyId, AsnType *type)
+{
+    AnyInfo *a;
+    Hash h;
+
+    a = new AnyInfo;
+    //  Oid will be NULL and 0 len by default constructor
+    a->anyId = anyId;
+    a->intId = intId;
+    a->typeToClone = type;
+
+	#ifdef	__APPLE__
+	StLock<Mutex> _(hashTblLock());
+	#endif
+	if (AsnAny::intHashTbl == NULL)
+		AsnAny::intHashTbl = InitHash();
+
+	AsnIntType idval = (AsnIntType) intId;
+	h = MakeHash ((char*)&idval, sizeof (idval));
+	Insert (AsnAny::intHashTbl, a, h);
+
+}  /* InstallAnyByInt */
+
+
+// given an OBJECT IDENTIFIER, oid, to hash on, the type and it's anyId
+// are installed in the OBJECT IDENTIFIER id hash tbl
+void
+AsnAny::InstallAnyByOid (AsnOid &oid, int anyId, AsnType *type)
+{
+    AnyInfo *a;
+    Hash h;
+
+    a =  new AnyInfo;
+    a->anyId = anyId;
+    a->oid = oid;  // copy given oid
+    a->typeToClone = type;
+
+    h = MakeHash (oid.Str(), oid.Len());
+
+	#ifdef	__APPLE__
+	StLock<Mutex> _(hashTblLock());
+	#endif
+    if (AsnAny::oidHashTbl == NULL)
+        AsnAny::oidHashTbl = InitHash();
+
+    Insert (AsnAny::oidHashTbl, a, h);
+}  /* InstallAnyByOid */
+
+
+AsnType *AsnAny::Clone() const
+{
+  return new AsnAny;
+}
+
+AsnType *AsnAny::Copy() const
+{
+  return new AsnAny (*this);
+}
+
+
+//
+// if you haven't set up the value properly
+// this will croak (since it's a programming error
+// - ie, you didn't initialize the data structure properly
+//
+AsnLen
+AsnAny::BEnc (BUF_TYPE b)
+{
+    return value->BEnc (b);
+}
+
+
+
+void
+AsnAny::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    if (ai == NULL)
+        longjmp (env, -81);
+
+	// XXX This is wrong.
+    value = static_cast<CSM_Buffer *>(ai->typeToClone->Clone());
+
+    if (value == NULL)
+        longjmp (env, -82);
+    else
+        value->BDec (b, bytesDecoded, env);
+}
+
+
+void AsnAny::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+   value->Print(os);
+#endif
+}
+
+#ifdef VDADER_RULES
+
+AsnAny::~AsnAny()
+{
+    delete this->value;
+}
+
+AsnAny &AsnAny::operator = (const AsnAny &o) 
+{ 
+    if (this->ai)      // take care of most copies.
+        delete this->ai;
+    this->ai = NULL;
+    if (o.ai)
+    {
+      this->ai = new AnyInfo;
+      *this->ai = *o.ai;
+    }
+	/* __APPLE__ - I don't think this needs a lock since it's
+	 * not modifying the hash tables */
+    if (o.intHashTbl)
+    {
+      this->intHashTbl = o.intHashTbl; // same pointer.
+    }
+    if (o.oidHashTbl)
+    {
+      this->oidHashTbl = o.oidHashTbl;
+    }
+
+    if (o.value)
+      this->value = static_cast<CSM_Buffer *>(o.value->Copy());
+
+    return *this; 
+}
+
+#endif
+
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-bits.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-bits.cpp
new file mode 100644
index 00000000..82280899
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-bits.cpp
@@ -0,0 +1,579 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-bits.C - AsnBits (ASN.1 BIT STRING) Type
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-bits.cpp,v 1.3 2001/06/28 23:36:11 dmitch Exp $
+// $Log: asn-bits.cpp,v $
+// Revision 1.3  2001/06/28 23:36:11  dmitch
+// Removed SccsId statics. numToHexCharTblG table now const. Radar 2705410.
+//
+// Revision 1.2  2001/06/27 23:09:14  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/12/07 22:15:49  dmitch
+// Thread-safe mods: added a local StrStk strStkG to the routines which need it.
+//
+// Revision 1.1  2000/06/15 18:44:57  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:34  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.3  1999/03/21 02:07:35  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.2  1999/02/26 00:23:39  mb
+// Fixed for Mac OS 8
+//
+// Revision 1.1  1999/02/25 05:21:50  mb
+// Added snacc c++ library
+//
+// Revision 1.9  1997/08/27 15:55:15  wan
+// GetBit now returns 0 or 1, not 0 or <#bit>, even if bool type is emulated.
+//
+// Revision 1.8  1997/02/28 13:39:44  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.7  1997/01/01 20:19:01  rj
+// dereferencing pointer to member function is neither necessary nor allowed
+//
+// Revision 1.6  1995/08/17  15:37:49  rj
+// set Tcl's errorCode variable
+//
+// Revision 1.5  1995/07/24  20:09:07  rj
+// use memzero that is defined in .../snacc.h to use either memset or bzero.
+// use memcmpeq that is defined in .../snacc.h to use either memcmp or bcmp.
+//
+// call constructor with additional pdu and create arguments.
+//
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1994/10/08  04:18:21  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.3  1994/08/31  23:37:57  rj
+// TRUE turned into true
+//
+// Revision 1.2  1994/08/28  10:01:11  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:57  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-bits.h"
+#include "str-stk.h"
+
+#ifndef	__APPLE__
+
+/* OS X - thread safe - the only routine which uses this allocates
+ * it on the stack */
+extern StrStk strStkG;
+unsigned short int  strStkUnusedBitsG;
+#endif	/* __APPLE__ */
+
+const
+char numToHexCharTblG[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+AsnBits::~AsnBits()
+{
+  delete bits;
+}
+
+AsnType *AsnBits::Clone() const
+{
+  return new AsnBits;
+}
+
+AsnType *AsnBits::Copy() const
+{
+  return new AsnBits (*this);
+}
+
+// Initializes the bits string with a bit string numBits in length.
+// All bits are zeroed.
+void AsnBits::Set (size_t numBits)
+{
+  bitLen = numBits;
+  size_t octetLen = (bitLen+7)/8;
+
+#ifndef _IBM_ENC_
+  bits = Asn1Alloc (octetLen);
+#else
+  bits = (char *) mem_mgr_ptr->Get (octetLen);       // Guido Grassel, 11.8.93
+#endif /* _IBM_ENC_ */
+  memzero (bits, octetLen); // init to zeros
+}
+
+// initializes a BIT STRING with the given string and bit length
+// Copies the bits from bitsOcts.
+void AsnBits::Set (const char *bitOcts, size_t numBits)
+{
+    if (bitOcts != bits)
+    {
+        bitLen = numBits;
+	size_t octetLen = (bitLen+7)/8;
+#ifndef _IBM_ENC_
+        bits = new char[octetLen];
+#else
+	bits = (char *) mem_mgr_ptr->Get (octetLen);       // Guido Grassel, 11.8.93
+#endif /* _IBM_ENC_ */
+        memcpy (bits, bitOcts, octetLen);
+    }
+}
+
+// initializes a BIT STRING by copying another BIT STRING's bits
+void AsnBits::Set (const AsnBits &b)
+{
+  if (&b != this)
+  {
+    bitLen = b.bitLen;
+    size_t octetLen = (bitLen+7)/8;
+#ifndef _IBM_ENC_
+    bits = new char[octetLen];
+#else
+    bits = (char *) mem_mgr_ptr->Get (octetLen);       // Guido Grassel, 11.8.93
+#endif /* _IBM_ENC_ */
+    memcpy (bits, b.bits, octetLen);
+  }
+}
+
+// Initializes the bits string with a bit string numBits in length.
+// All bits are zeroed.
+void AsnBits::ReSet (size_t numBits)
+{
+#ifndef _IBM_ENC_
+  delete bits;
+  Set (numBits);
+#else
+  mem_mgr_ptr->Put ((void *) bits);       // Guido Grassel, 11.8.93
+  Set (numBits);
+#endif /* _IBM_ENC_ */
+}
+
+// frees old bits value and then re-initializes the
+// BIT STRING with the given string and bit length
+// Copies the bitOcts into bits.
+void AsnBits::ReSet (const char *bitOcts, size_t numBits)
+{
+  if (bitOcts != bits)
+  {
+#ifndef _IBM_ENC_
+    delete bits;
+    Set (bitOcts, numBits);
+#else
+    mem_mgr_ptr->Put ((void *) bits);       // Guido Grassel, 11.8.93
+    Set (bitOcts, numBits);
+#endif /* _IBM_ENC_ */
+  }
+}
+
+// frees old bits value and then re-initializes the
+// BIT STRING by copying another BIT STRING's bits
+void AsnBits::ReSet (const AsnBits &b)
+{
+  if (&b != this)  // avoid b = b; probs
+  {
+#ifndef _IBM_ENC_
+    delete bits;
+    Set (b);
+#else
+    mem_mgr_ptr->Put ((void *) bits);       // Guido Grassel, 11.8.93
+    Set (b);
+#endif /* _IBM_ENC_ */
+  }
+}
+
+
+// Returns true if the given BIT STRING is the same as this one
+bool AsnBits::BitsEquiv (const AsnBits &ab) const
+{
+  size_t octetsLessOne = (bitLen-1)/8;
+  size_t octetBits = 7 - (bitLen % 8);
+
+  if (!bitLen && !ab.bitLen)
+    return true;
+
+  // trailing bits may not be significant
+  return bitLen == ab.bitLen
+    && !memcmpeq (bits, ab.bits, octetsLessOne)
+    && (bits[octetsLessOne] & (0xFF << octetBits)) == (ab.bits[octetsLessOne] & (0xFF << octetBits));
+}  /* AsnBits::BitsEquiv */
+
+
+// set given bit to 1. Most signif. bit is bit 0, least signif bit is bitLen-1
+void AsnBits::SetBit (size_t bit)
+{
+  if (bit < bitLen)
+  {
+    size_t octet = bit/8;
+    size_t octetsBit = 7 - (bit % 8);	// bit zero is first/most sig bit in octet
+    bits[octet] |= 1 << octetsBit;
+  }
+#ifdef DEBUG
+  else
+    Asn1Errror << "AsnBits::SetBit: ERROR - bit larger than bit string" << endl;
+#endif
+} /* AsnBits::SetBit */
+
+// Clr bit. Most signif. bit is bit 0, least signif bit is bitLen-1
+void AsnBits::ClrBit (size_t bit)
+{
+  if (bit < bitLen)
+  {
+    size_t octet = bit/8;
+    size_t octetsBit = 7 - (bit % 8);	// bit zero is first/most sig bit in octet
+    bits[octet] &= ~(1 << octetsBit);
+  }
+#ifdef DEBUG
+  else
+    Asn1Errror << "AsnBits::ClrBit: ERROR - bit larger than bit string" << endl;
+#endif
+} /* AsnBits::ClrBit */
+
+// returns given bit. Most signif. bit is bit 0, least signif bit is bitLen-1.
+// Returns false if the givnen bit index is out of range.
+bool AsnBits::GetBit (size_t bit) const
+{
+  if (bit < bitLen)
+  {
+    size_t octet = bit/8;
+    size_t octetsBit = 7 - (bit % 8);	// bit zero is first/most sig bit in octet
+    return !!(bits[octet] & (1 << octetsBit));
+  }
+#ifdef DEBUG
+  else
+    Asn1Errror << "AsnBits::GetBit: ERROR - bit larger than bit string" << endl;
+#endif
+
+  return false;
+}  /* AsnBits::GetBit */
+
+
+// Encoded the content (included unused bits octet) of the BIT STRING
+// to the given buffer.
+AsnLen AsnBits::BEncContent (BUF_TYPE b)
+{
+    size_t byteLen = (bitLen+7)/8;
+    b.PutSegRvs (bits, byteLen);
+
+    size_t unusedBits = (bitLen % 8);
+    if (unusedBits != 0)
+        unusedBits = 8 - unusedBits;
+    b.PutByteRvs (unusedBits);
+
+    return byteLen + 1;
+
+} /* AsnBits::BEncContent */
+
+
+// Decodes a BER BIT STRING from the given buffer and stores
+// the value in this object.
+void AsnBits::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+//    char *tmp;
+
+    /*
+     * tagId is encoded tag shifted into long int.
+     * if CONS bit is set then constructed bit string
+     */
+    if (tagId & 0x20000000)
+        BDecConsBits (b, elmtLen, bytesDecoded, env);
+
+    else /* primitive octet string */
+    {
+        bytesDecoded += elmtLen;
+        elmtLen--;
+        bitLen = (elmtLen * 8) - (unsigned int)b.GetByte();
+#ifndef _IBM_ENC_
+        bits =  Asn1Alloc (elmtLen);
+#else
+	bits = (char *) mem_mgr_ptr->Get (elmtLen);       // Guido Grassel, 11.8.93
+#endif /* _IBM_ENC_ */
+        b.CopyOut (bits, elmtLen);
+        if (b.ReadError())
+        {
+            Asn1Error << "BDecBitString: ERROR - decoded past end of data" << endl;
+            longjmp (env, -1);
+        }
+    }
+
+} /* AsnBits::BDecContent */
+
+AsnLen AsnBits::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l =  BEncContent (b);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    return l;
+}
+
+void AsnBits::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    tag = BDecTag (b, bytesDecoded, env);
+    if ((tag != MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+      && (tag != MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+    {
+	Asn1Error << "AsnBits::BDec: ERROR tag on BIT STRING is wrong." << endl;
+	longjmp (env,-50);
+    }
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+/*
+ * Used to concatentate constructed bit strings when decoding.
+ *
+ * fills string stack with references to the pieces of a
+ * construced bit string. sets strStkUnusedBitsG appropriately.
+ * and strStkTotalByteLenG to bytelen needed to hold the bitstring
+ */
+#ifdef	__APPLE__
+void AsnBits::FillBitStringStk (BUF_TYPE b, AsnLen elmtLen0, 
+	AsnLen &bytesDecoded, ENV_TYPE env,
+	StrStk &strStkG,
+	unsigned short int  &strStkUnusedBitsG)
+#else
+void AsnBits::FillBitStringStk (BUF_TYPE b, AsnLen elmtLen0, 
+	AsnLen &bytesDecoded, ENV_TYPE env)
+#endif
+{
+    size_t refdLen;
+    size_t totalRefdLen;
+    char *strPtr;
+    AsnLen totalElmtsLen1 = 0;
+    unsigned long int tagId1;
+    AsnLen elmtLen1;
+    size_t lenToRef;
+//    size_t unusedBits;
+
+    for (; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )
+    {
+        tagId1 = BDecTag (b, totalElmtsLen1, env);
+
+        if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, totalElmtsLen1, env);
+            break;
+        }
+
+        elmtLen1 = BDecLen (b, totalElmtsLen1, env);
+        if (tagId1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+        {
+            /*
+             * primitive part of string, put references to piece (s) in
+             * str stack
+             */
+
+            /*
+             * get unused bits octet
+             */
+            if (strStkUnusedBitsG != 0)
+            {
+                /*
+                 *  whoa - only allowed non-octed aligned bits on
+                 *  on last piece of bits string
+                 */
+                Asn1Error << "BDecConsBitString: ERROR - a component of a constructed BIT STRING that is not the last has non-zero unused bits" << endl;
+                longjmp (env, -2);
+            }
+
+            if (elmtLen1 != 0)
+                strStkUnusedBitsG = b.GetByte();
+
+            totalRefdLen = 0;
+            lenToRef =elmtLen1-1; /* remove one octet for the unused bits oct*/
+            refdLen = lenToRef;
+            while (1)
+            {
+                strPtr = b.GetSeg (&refdLen);
+
+                strStkG.Push (strPtr, refdLen);
+                totalRefdLen += refdLen;
+                if (totalRefdLen == lenToRef)
+                    break; /* exit this while loop */
+
+                if (refdLen == 0) /* end of data */
+                {
+                    Asn1Error << "BDecConsOctetString: ERROR - expecting more data" << endl;
+                    longjmp (env, -3);
+                }
+                refdLen = lenToRef - totalRefdLen;
+            }
+            totalElmtsLen1 += elmtLen1;
+        }
+
+
+        else if (tagId1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE))
+        {
+            /*
+             * constructed octets string embedding in this constructed
+             * octet string. decode it.
+             */
+            FillBitStringStk (b, elmtLen1, totalElmtsLen1, env
+				#ifdef	__APPLE__
+				, strStkG, strStkUnusedBitsG
+				#endif
+				);
+       }
+        else  /* wrong tag */
+        {
+            Asn1Error << "BDecConsBitString: ERROR - decoded non-BIT STRING tag inside a constructed BIT STRING" << endl;
+            longjmp (env, -4);
+        }
+    } /* end of for */
+
+    bytesDecoded += totalElmtsLen1;
+}  /* FillBitStringStk */
+
+
+/*
+ * decodes a seq of universally tagged bits until either EOC is
+ * encountered or the given len decoded.  Return them in a
+ * single concatenated bit string
+ */
+void AsnBits::BDecConsBits (BUF_TYPE b, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+	#ifdef	__APPLE__
+	StrStk strStkG(128, 64);
+	unsigned short int  strStkUnusedBitsG;
+	#endif
+    strStkG.Reset();
+    strStkUnusedBitsG = 0;
+
+    /*
+     * decode each piece of the octet string, puting
+     * an entry in the octet/bit string stack for each
+     */
+    FillBitStringStk (b, elmtLen, bytesDecoded, env, strStkG, 
+		strStkUnusedBitsG);
+
+    /* alloc single str long enough for combined bitstring */
+    bitLen = strStkG.totalByteLen*8 - strStkUnusedBitsG;
+
+#ifndef _IBM_ENC_
+    bits = Asn1Alloc (strStkG.totalByteLen);
+#else
+    bits = (char *) mem_mgr_ptr->Get (strStkG.totalByteLen);       // Guido Grassel, 11.8.93
+#endif /* _IBM_ENC_ */
+
+    strStkG.CopyOut (bits);
+
+}  /* BDecConsBits */
+
+// prints the BIT STRING to the given ostream.
+void AsnBits::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+    size_t octetLen = (bitLen+7)/8;
+
+    os << "'";
+    for (int i = 0; i < octetLen; i++)
+        os << TO_HEX (bits[i] >> 4) << (TO_HEX (bits[i]));
+    os << "'H  -- BIT STRING bitlen = " << bitLen << " --";
+#endif	/* NDEBUG */
+}
+
+#if META
+
+const AsnBitsTypeDesc AsnBits::_desc (NULL, NULL, false, AsnTypeDesc::BIT_STRING, NULL, NULL);
+
+const AsnTypeDesc *AsnBits::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+int AsnBits::TclGetVal (Tcl_Interp *interp) const
+{
+  Tcl_ResetResult(interp);
+  for (int i=0; i<bitLen; i++)
+    Tcl_AppendResult(interp,GetBit (i) ? "1" : "0",NULL);
+  return TCL_OK;
+}
+
+int AsnBits::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+  int		i;
+  const char	*p;
+
+  for (i=0, p=valstr; *p; i++, p++)
+    switch (*p)
+    {
+      case '0':
+      case '1':
+	break;
+      default:
+	const char c[2] = { *p, '\0' };
+	Tcl_AppendResult (interp, "illegal character '", c, "' for bit in type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL);
+	Tcl_SetErrorCode (interp, "SNACC", "ILLBIT", NULL);
+	return TCL_ERROR;
+    }
+
+  ReSet (i);
+
+  for (i=0, p=valstr; i<bitLen; i++, p++)
+    *p == '0' ? ClrBit(i) : SetBit(i);
+
+  return TCL_OK;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-bool.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-bool.cpp
new file mode 100644
index 00000000..846a3b9a
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-bool.cpp
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-bool.C - methods for AsnBool (ASN.1 BOOLEAN) class
+//
+// MS 92/06/16
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-bool.cpp,v 1.2 2001/06/27 23:09:14 dmitch Exp $
+// $Log: asn-bool.cpp,v $
+// Revision 1.2  2001/06/27 23:09:14  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:57  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:34  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:35  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:50  mb
+// Added snacc c++ library
+//
+// Revision 1.7  1997/02/28 13:39:44  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.6  1997/02/16 20:26:03  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.5  1995/07/24  20:10:43  rj
+// call constructor with additional pdu and create arguments.
+//
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1994/10/08  04:18:22  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.3  1994/08/31  23:30:48  rj
+// use the bool built-in where applicable, and a replacement type otherwise.
+//
+// Revision 1.2  1994/08/28  10:01:11  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:58  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-bool.h"
+
+AsnType *AsnBool::Clone() const
+{
+  return new AsnBool;
+}
+
+AsnType *AsnBool::Copy() const
+{
+  return new AsnBool (*this);
+}
+
+AsnLen AsnBool::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+    l += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE);
+    return l;
+}
+
+void AsnBool::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE))
+    {
+	Asn1Error << "AsnBool::BDec: ERROR tag on BOOLEAN wrong." << endl;
+	longjmp (env, -51);
+    }
+    elmtLen = BDecLen (b, bytesDecoded, env);
+
+    BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE), elmtLen, bytesDecoded, env);
+}
+
+// Decodes the content of a BOOLEAN and sets this object's value
+// to the decoded value. Flags an error if the length is wrong
+// or a read error occurs.
+void AsnBool::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    if (elmtLen != 1)
+    {
+        Asn1Error << "AsnBool::BDecContent: ERROR - boolean value too long." << endl;
+        longjmp (env, -5);
+    }
+
+    value = (b.GetByte() != 0);
+    bytesDecoded++;
+
+    if (b.ReadError())
+    {
+        Asn1Error << "AsnBool::BDecContent: ERROR - decoded past end of data " << endl;
+        longjmp (env, -6);
+    }
+}
+
+AsnLen AsnBool::BEncContent (BUF_TYPE b)
+{
+    b.PutByteRvs (value ? 0xFF : 0);
+    return 1;
+}
+
+// print the BOOLEAN's value in ASN.1 value notation to the given ostream
+void AsnBool::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+  os << (value ? "TRUE" : "FALSE");
+#endif
+}
+
+#if META
+
+const AsnTypeDesc AsnBool::_desc (NULL, NULL, false, AsnTypeDesc::BOOLEAN, NULL);
+
+const AsnTypeDesc *AsnBool::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+int AsnBool::TclGetVal (Tcl_Interp *interp) const
+{
+  Tcl_SetResult (interp, value ? "TRUE" : "FALSE", TCL_STATIC);
+  return TCL_OK;
+}
+
+int AsnBool::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+  int valval;
+
+  if (Tcl_GetBoolean (interp, (char*) valstr, &valval) != TCL_OK)
+    return TCL_ERROR;
+
+  value = valval;
+
+  return TCL_OK;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-enum.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-enum.cpp
new file mode 100644
index 00000000..751d7adb
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-enum.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-enum.C - methods for AsnEnum (ASN.1 ENUMERATED) class
+//
+// MS 92/06/16
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-enum.cpp,v 1.2 2001/06/26 23:49:52 dmitch Exp $
+// $Log: asn-enum.cpp,v $
+// Revision 1.2  2001/06/26 23:49:52  dmitch
+// Was cerr, is Asn1Error.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:57  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:35  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:35  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:51  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/28 13:39:44  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.4  1995/08/17 15:19:52  rj
+// AsnEnumTypeDesc gets its own TclGetVal and TclSetVal functions.
+//
+// Revision 1.3  1995/07/24  20:14:49  rj
+// Clone() added, or else the _desc would be wrong (and the wrong BEnc etc... would get called) for Clone-d objects.
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.2  1994/10/08  05:26:37  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/10/08  05:24:03  rj
+// functions extracted from ../inc/asn_enum.h
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-int.h"
+#include "asn-enum.h"
+
+AsnType *AsnEnum::Clone() const
+{
+  Asn1Error << "AsnEnum::Clone() called" << endl;
+  abort();
+  return NULL;
+}
+
+AsnType *AsnEnum::Copy() const
+{
+  Asn1Error << "AsnEnum::Copy() called" << endl;
+  abort();
+  return NULL;
+}
+
+AsnLen AsnEnum::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+    l += BEncTag1 (b, UNIV, PRIM, ENUM_TAG_CODE);
+    return l;
+}
+
+void AsnEnum::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE))
+    {
+	Asn1Error << "AsnEnum::BDec: ERROR tag on ENUMERATED is wrong." << endl;
+	longjmp (env,-52);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE), elmtLen, bytesDecoded, env);
+}
+
+#if META
+
+const AsnEnumTypeDesc AsnEnum::_desc (NULL, NULL, false, AsnTypeDesc::ENUMERATED, NULL, NULL);
+
+const AsnTypeDesc *AsnEnum::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+int AsnEnum::TclGetVal (Tcl_Interp *interp) const
+{
+  const AsnNameDesc *n = _getdesc()->getnames();
+  if (n)
+  {
+    for (; n->name; n++)
+      if (n->value == value)
+      {
+	Tcl_SetResult (interp, (char*)n->name, TCL_STATIC);
+	return TCL_OK;
+      }
+  }
+  char valstr[80];
+  sprintf (valstr, "%d", value);
+  Tcl_AppendResult (interp, "illegal numeric enumeration value ", valstr, " for type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL);
+  Tcl_SetErrorCode (interp, "SNACC", "ILLENUM", NULL);
+  return TCL_ERROR;
+}
+
+int AsnEnum::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+  const AsnNameDesc *n = _getdesc()->getnames();
+  if (n)
+  {
+    for (; n->name; n++)
+      if (!strcmp (n->name, valstr))
+      {
+	value = n->value;
+	return TCL_OK;
+      }
+  }
+  Tcl_SetErrorCode (interp, "SNACC", "ILLENUM", NULL);
+  Tcl_AppendResult (interp, "illegal symbolic enumeration value \"", valstr, "\" for type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL);
+  return TCL_ERROR;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp
new file mode 100644
index 00000000..218214be
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-int.C - methods for AsnInt (ASN.1 INTEGER) class
+//
+// MS 92/06/16
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp,v 1.2 2001/06/27 23:09:14 dmitch Exp $
+// $Log: asn-int.cpp,v $
+// Revision 1.2  2001/06/27 23:09:14  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:57  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:35  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:36  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:51  mb
+// Added snacc c++ library
+//
+// Revision 1.7  1997/02/28 13:39:45  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.6  1995/09/07 18:55:50  rj
+// (unsigned) long int replaced by newly introduced Asn(U)IntType at a lot of places.
+// they shall provide 32 bit integer types on all platforms.
+//
+// Revision 1.5  1995/07/24  20:17:32  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1995/02/18  16:48:05  rj
+// denote a long if we want a long
+//
+// Revision 1.3  1994/10/08  04:18:23  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:12  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:59  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-int.h"
+
+AsnType *AsnInt::Clone() const
+{
+  return new AsnInt;
+}
+
+AsnType *AsnInt::Copy() const
+{
+  return new AsnInt (*this);
+}
+
+// Encodes BER content of this AsnInt to the given buffer.
+// Returns the number of octets written to the buffer.
+AsnLen AsnInt::BEncContent (BUF_TYPE b)
+{
+    AsnLen		len;
+    int			i;
+    AsnUIntType	mask;
+    AsnUIntType	dataCpy;
+
+#define MASK	(0x7f80L << ((sizeof (AsnIntType) - 2) * 8))
+
+    dataCpy = value;
+
+    /*
+     * calculate encoded length of the integer (content)
+     */
+    mask = MASK;
+    if ((AsnIntType)dataCpy < 0)
+        for (len = sizeof (AsnIntType); len > 1; --len)
+        {
+            if ((dataCpy & mask) == mask)
+                mask >>= 8;
+            else
+                break;
+        }
+    else
+        for (len = sizeof (AsnIntType); len > 1; --len)
+        {
+            if ((dataCpy & mask) == 0)
+                mask >>= 8;
+            else
+                break;
+        }
+
+    /*
+     * write the BER integer
+     */
+    for (i = 0; i < len; i++)
+    {
+        b.PutByteRvs (dataCpy);
+        dataCpy >>= 8;
+    }
+
+    return len;
+}
+
+// Decodes the content of a BER INTEGER from the given buffer.
+// The value is placed in this object.  tagId is ignored.
+// bytesDecoded is incremented by the number of bytes read for this
+// integer value.
+void AsnInt::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    int   i;
+    AsnUIntType byte;
+
+    if (elmtLen > sizeof (AsnIntType))
+    {
+        Asn1Error << "AsnInt::BDecContent: ERROR - integer is too big to decode." << endl;
+        longjmp (env, -7);
+    }
+
+    /*
+     * look at integer value
+     */
+    byte =  (AsnUIntType) b.GetByte();
+
+    if (byte & 0x80)   /* top bit of first byte is sign bit */
+        value = (-1 << 8) | byte;
+    else
+        value = byte;
+
+    /*
+     * write from buffer into AsnIntType
+     */
+    for (i = 1; i < elmtLen; i++)
+        value = (value << 8) | (AsnUIntType)(b.GetByte());
+
+    bytesDecoded += elmtLen;
+
+    if (b.ReadError())
+    {
+        Asn1Error << "AsnInt::BDecContent: ERROR - decoded past end of data." << endl;
+        longjmp (env, -8);
+    }
+
+
+}  /* AsnInt::BDecContent */
+
+AsnLen AsnInt::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    return l;
+}
+
+void AsnInt::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    {
+	Asn1Error << "AsnInt::BDec: ERROR tag on INTEGER is wrong." << endl;
+	longjmp (env,-53);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE), elmtLen, bytesDecoded, env);
+}
+
+void AsnInt::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+    os << value;
+#endif
+}
+
+#if META
+
+const AsnIntTypeDesc AsnInt::_desc (NULL, NULL, false, AsnTypeDesc::INTEGER, NULL, NULL);
+
+const AsnTypeDesc *AsnInt::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+#define RETURN_NAME_INSTEAD_OF_VALUE	0
+
+int AsnInt::TclGetVal (Tcl_Interp *interp) const
+{
+#if RETURN_NAME_INSTEAD_OF_VALUE
+  const AsnNameDesc *n = _getdesc()->getnames();
+  if (n)
+    for (; n->name; n++)
+      if (n->value == value)
+      {
+	Tcl_SetResult (interp, n->name, TCL_STATIC);
+	return TCL_OK;
+      }
+#endif
+
+  char buf[32];
+  sprintf (buf, "%d", value);
+  Tcl_SetResult (interp, buf, TCL_VOLATILE);
+  return TCL_OK;
+}
+
+int AsnInt::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+  const AsnNameDesc *n = _getdesc()->getnames();
+  if (n)
+    for (; n->name; n++)
+      if (!strcmp (n->name, valstr))
+      {
+	value = n->value;
+	return TCL_OK;
+      }
+
+  int valval;
+  if (Tcl_GetInt (interp, (char*)valstr, &valval) != TCL_OK)
+    return TCL_ERROR;
+  value = valval;
+  return TCL_OK;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-len.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-len.cpp
new file mode 100644
index 00000000..ee10d337
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-len.cpp
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-len.C - ASN.1 Length manipluation routines
+//
+// MS 92/06/18
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-len.cpp,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+// $Log: asn-len.cpp,v $
+// Revision 1.1.1.1  2001/05/18 23:14:05  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:57  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:35  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:51  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 20:26:04  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/24  20:33:15  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:24  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:13  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:00  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+
+
+/*
+ * Encodes the given length to the given buffer.
+ * returns the number of octets written to the buffer.
+ */
+AsnLen
+BEncDefLen (BUF_TYPE  b, AsnLen len)
+{
+    /*
+     * unrolled for efficiency
+     * (check each possibitlity of the 4 byte integer)
+     */
+    if (len < 128)
+    {
+        b.PutByteRvs (len);
+        return 1;
+    }
+    else if (len < 256)
+    {
+        b.PutByteRvs (len);
+        b.PutByteRvs (0x81);
+        return 2;
+    }
+    else if (len < 65536)
+    {
+        b.PutByteRvs (len);
+        b.PutByteRvs (len >> 8);
+        b.PutByteRvs (0x82);
+        return 3;
+    }
+    else if (len < 16777126)
+    {
+        b.PutByteRvs (len);
+        b.PutByteRvs (len >> 8);
+        b.PutByteRvs (len >> 16);
+        b.PutByteRvs (0x83);
+        return 4;
+    }
+    else
+    {
+        b.PutByteRvs (len);
+        b.PutByteRvs (len >> 8);
+        b.PutByteRvs (len >> 16);
+        b.PutByteRvs (len >> 24);
+        b.PutByteRvs (0x84);
+        return 5;
+    }
+} /*  EncodeDefLen */
+
+/*
+ * Decode a BER length from the given buffer. Increments bytesDecoded
+ * by the number of octets of the encoded length.  Flags an
+ * error if the length is too large or a read error occurs
+ */
+AsnLen
+BDecLen (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen  len;
+    unsigned char  byte;
+    int  lenBytes;
+
+    byte = b.GetByte();
+
+    if (b.ReadError())
+    {
+        Asn1Error << "BDecLen: decoded past end of data" << endl;
+        longjmp (env, -9);
+    }
+
+    bytesDecoded++;
+    if (byte < 128)   /* short length */
+        return byte;
+
+    else if (byte == (unsigned char) 0x080)  /* indef len indicator */
+        return INDEFINITE_LEN;
+
+    else  /* long len form */
+    {
+        /*
+         * strip high bit to get # bytes left in len
+         */
+        lenBytes = byte & (unsigned char) 0x7f;
+
+        if (lenBytes > sizeof (long int))
+        {
+            Asn1Error << "BDecLen: ERROR - length overflow" << endl;
+            longjmp (env, -10);
+        }
+
+        bytesDecoded += lenBytes;
+
+        for (len = 0; lenBytes > 0; lenBytes--)
+            len = (len << 8) | (unsigned long int) b.GetByte();
+
+
+        if (b.ReadError())
+        {
+            Asn1Error << "BDecLen: decoded past end of data" << endl;
+            longjmp (env, -11);
+        }
+
+        return len;
+    }
+    /* not reached */
+}
+
+
+/*
+ * Encodes an End of Contents (EOC) to the given buffer.
+ * Returns the encoded length.
+ */
+AsnLen
+BEncEoc (BUF_TYPE b)
+{
+
+    b.PutByteRvs (0);
+    b.PutByteRvs (0);
+    return 2;
+}  /* BEncEoc */
+
+/*
+ * Decodes an EOC from the given buffer.  flags an error if the
+ * octets are non-zero or if read error occured.
+ */
+void
+BDecEoc (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+
+    if ((b.GetByte() != 0) || (b.GetByte() != 0) || b.ReadError())
+    {
+        Asn1Error << "BDecEoc: ERROR - non zero byte in EOC or end of data reached" << endl;
+        longjmp (env, -12);
+    }
+    bytesDecoded += 2;
+}  /* BDecEoc */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-list.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-list.cpp
new file mode 100644
index 00000000..87ff8e10
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-list.cpp
@@ -0,0 +1,376 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-list.C
+//
+//  Mike Sample
+//  92/07/02
+//
+// *** NOTE - this is not tested and not used  ****
+//     snacc generates a new class for each list type,
+//     methods and all.
+//       (gcc choked on templates)
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-list.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-list.cpp,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:57  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:35  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.3  1999/07/14 23:53:56  aram
+// Made const correct so things build with CW 5.0
+//
+// Revision 1.2  1999/03/21 02:07:36  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:52  mb
+// Added snacc c++ library
+//
+// Revision 1.8  1997/09/04 13:54:09  wan
+// A little more portability
+//
+// Revision 1.7  1997/01/02 08:42:39  rj
+// names of Tcl*-functions fixed (obviously they weren't needed :-)
+//
+// Revision 1.6  1995/07/24  20:18:15  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.5  1995/02/18  14:06:02  rj
+// #pragma interface/implementation are GNU specific and need to be wrapped.
+//
+// Revision 1.4  1994/10/08  04:18:25  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.3  1994/08/31  23:38:24  rj
+// FALSE/TRUE turned into false/true
+//
+// Revision 1.2  1994/08/28  10:01:14  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:02  rj
+// first check-in. for a list of changes to 1.1 please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include "asn-list.h"
+
+template <class T>
+void AsnList<T>::SetCurrElmt (unsigned long int index)
+{
+    unsigned long int i;
+    curr = first;
+    for (i = 0; (i < (count-1)) && (i < index); i++)
+        curr = curr->next;
+}
+
+
+// print routine for lists
+template <class T>
+ostream &operator << (ostream &os, AsnList<T> &l)
+{
+    os << "SEQUENCE OF { ";
+
+    l.SetCurrToFirst();
+    for (; l.Curr() != NULL; l.GoNext())
+    {
+        os << *l.Curr();
+        if (l.Curr() != l.Last())
+            os << ", ";
+    }
+
+    os << " }";
+    return os;
+}
+
+
+
+// alloc new list elmt, put at end of list
+//  and return the component type
+template <class T>
+T &AsnList<T>::Append()
+{
+    AsnListElmt *newElmt;
+
+    newElmt = new AsnListElmt;
+
+    newElmt->next = NULL;
+
+    if (last == NULL)
+    {
+	newElmt->prev = NULL;
+	first = last  = newElmt;
+    }
+    else
+    {
+	newElmt->prev = last;
+        last->next    = newElmt;
+	last          = newElmt;
+    }
+
+    count++;
+
+    return newElmt->elmt;
+
+} /* AsnList::Append */
+
+
+// alloc new list elmt, put at beggining of list
+//  and return the component type
+template <class T>
+T &AsnList<T>::Prepend()
+{
+    AsnListElmt *newElmt;
+
+    newElmt = new AsnListElmt;
+
+    newElmt->prev = NULL;
+
+    if (first == NULL)
+    {
+	newElmt->next = NULL;
+	first = last  = newElmt;
+    }
+    else
+    {
+	newElmt->next = first;
+        first->prev   = newElmt;
+	first         = newElmt;
+    }
+
+    count++;
+
+    return newElmt->elmt;
+
+} /* AsnList::Prepend */
+
+template <class T>
+AsnList<T>& AsnList<T>::AppendAndCopy (T &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt = new AsnListElmt;
+
+    newElmt->elmt = elmt;
+
+    newElmt->next = NULL;
+
+    if (last == NULL)
+    {
+	newElmt->prev = NULL;
+	first = last  = newElmt;
+    }
+    else
+    {
+	newElmt->prev = last;
+        last->next    = newElmt;
+	last          = newElmt;
+    }
+
+    count++;
+
+    return this;
+
+} /* AppendAndCopy */
+
+template <class T>
+AsnList<T>& AsnList<T>::PrependAndCopy (T &elmt)
+{
+    AsnListElmt *newElmt;
+
+    newElmt = new AsnListElmt;
+
+    newElmt->elmt = elmt;
+
+    newElmt->prev = NULL;
+
+    if (first == NULL)
+    {
+	newElmt->next = NULL;
+	first = last  = newElmt;
+    }
+    else
+    {
+	newElmt->next = first;
+        first->prev   = newElmt;
+	first         = newElmt;
+    }
+
+    count++;
+
+    return this;
+
+} /* PrependAndCopy */
+
+template <class T>
+AsnType	*AsnList<T>::Clone() const
+{
+	return new T;
+}
+
+template <class T>
+AsnType	*AsnList<T>::Copy() const
+{
+	return new T (*this);
+}
+
+template <class T>
+AsnLen AsnList<T>::BEncContent (BUF_TYPE b)
+{
+    AsnListElmt *currElmt;
+    AsnLen sum = 0;
+
+    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
+	sum += currElmt->elmt.BEnc (b);
+
+    return sum;
+}
+
+template <class T>
+void AsnList<T>::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    T listElmt;
+    AsnTag listElmtTagId;
+    AsnLen localBytesDecoded = 0;
+    AsnLen listElmtLen = 0;
+
+
+     while ((localBytesDecoded < elmtLen) || (elmtLen == INDEFINITE_LEN))
+     {
+         listElmtTagId = BDecTag (b, bytesDecoded, env);
+
+         if ((listElmtTagId == EOC) && (elmtLen == INDEFINITE_LEN))
+             break;
+
+
+         listElmt = Append();
+         listElmtLen = BDecLen (b, bytesDecoded, env);
+         listElmt.BDecContent (b, listElmtTagId, listElmtLen, localBytesDecoded, env);
+     }
+    bytesDecoded += localBytesDecoded;
+
+}  /* AsnList<T>::BDecContent */
+
+template <class T>
+AsnLen AsnList<T>::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l =  BEncContent (b);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    return l;
+}
+
+template <class T>
+void AsnList<T>::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
+    {
+	Asn1Error << "AsnList::BDec: ERROR tag on SEQUENCE OF is wrong." << endl;
+	longjmp (env,-54);
+    }
+    elmtLen = BDecLen (b, bytesDecoded, env);
+
+    BDecContent (b, MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE), elmtLen, bytesDecoded, env);
+}
+
+template <class T, class U>
+int ListsEquiv (AsnList<T>& l1, AsnList<U>& l2)
+{
+    if (l1.Count() != l2.Count())
+        return false;
+
+    l1.SetCurrToFirst();
+    l2.SetCurrToFirst();
+
+    for (; l1.Curr() != NULL; l1.GoNext(), l2.GoNext())
+    {
+        if (*l1.Curr() !=  *l2.Curr())
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+#if 0
+#if META
+
+const AsnTypeDesc AsnList::_desc (NULL, NULL, false, AsnTypeDesc::SET_or_SEQUENCE_OF, NULL);
+
+const AsnTypeDesc *AsnList::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+int AsnList::TclGetVal (Tcl_Interp *interp) const
+{
+	return TCL_ERROR;
+}
+
+int AsnList::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+	return TCL_ERROR;
+}
+
+#endif /* TCL */
+#endif /* META */
+#endif /* 0 */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-null.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-null.cpp
new file mode 100644
index 00000000..99e133d5
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-null.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-null.C
+//
+// MS 92
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-null.cpp,v 1.2 2001/06/27 23:09:14 dmitch Exp $
+// $Log: asn-null.cpp,v $
+// Revision 1.2  2001/06/27 23:09:14  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:57  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:35  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:36  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:52  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1995/08/17 15:38:19  rj
+// set Tcl's errorCode variable
+//
+// Revision 1.4  1995/07/24  20:18:27  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:26  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:15  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:04  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-null.h"
+
+AsnType *AsnNull::Clone() const
+{
+  return new AsnNull;
+}
+
+AsnType *AsnNull::Copy() const
+{
+  return new AsnNull (*this);
+}
+
+void AsnNull::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    if (elmtLen != 0)
+    {
+        Asn1Error << "AsnNull::BDecContent: ERROR - NULL values len is non-zero" << endl;
+        longjmp (env, -13);
+    }
+} /* AsnNull::BDecContent */
+
+AsnLen AsnNull::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+    l += BEncTag1 (b, UNIV, PRIM, NULLTYPE_TAG_CODE);
+    return l;
+}
+
+void AsnNull::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE))
+    {
+	Asn1Error << "AsnNull::BDec: ERROR tag on NULL is wrong." << endl;
+	longjmp (env, -55);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE), elmtLen, bytesDecoded, env);
+}
+
+void AsnNull::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+    os << "NULL";
+#endif
+}
+
+#if META
+
+const AsnNullTypeDesc AsnNull::_desc (NULL, NULL, false, AsnTypeDesc::NUL_, NULL);
+
+const AsnTypeDesc *AsnNull::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+int AsnNull::TclGetVal (Tcl_Interp *interp) const
+{
+  return TCL_OK;
+}
+
+int AsnNull::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+  if (*valstr)
+  {
+    Tcl_AppendResult (interp, "illegal non-null value `", valstr, "' for type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL);
+    Tcl_SetErrorCode (interp, "SNACC", "ILLNULL", NULL);
+    return TCL_ERROR;
+  }
+
+  return TCL_OK;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-octs.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-octs.cpp
new file mode 100644
index 00000000..53ab22c6
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-octs.cpp
@@ -0,0 +1,496 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-octs.C - ASN.1 OCTET STRING methods for AsnOcts Class
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-octs.cpp,v 1.2 2001/06/27 23:09:15 dmitch Exp $
+// $Log: asn-octs.cpp,v $
+// Revision 1.2  2001/06/27 23:09:15  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/12/07 22:16:14  dmitch
+// Thread-safe mods: added a local StrStk strStkG to the routines which need it.
+//
+// Revision 1.1  2000/06/15 18:44:57  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:35  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.4  1999/04/08 21:21:25  aram
+// Fixed AsnOcts destructor.
+//
+// Revision 1.3  1999/03/21 02:07:36  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.2  1999/02/26 00:23:40  mb
+// Fixed for Mac OS 8
+//
+// Revision 1.1  1999/02/25 05:21:53  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/28 13:39:45  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.5  1995/08/17 15:33:33  rj
+// augment binify()'s error message
+//
+// Revision 1.4  1995/07/24  20:23:32  rj
+// use memcmpeq that is defined in .../snacc.h to use either memcmp or bcmp.
+//
+// code extracted from AsnOcts::TclGetVal and AsnOcts::TclSetVal into ::debinify and ::binify in meta.C
+//
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:27  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:16  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:05  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-bits.h" /* for TO_HEX */
+#include "asn-octs.h"
+#include "str-stk.h"
+
+#ifndef	__APPLE__
+extern StrStk strStkG;
+#endif
+
+AsnOcts::~AsnOcts()
+{
+  Asn1Free( octs );
+}
+
+AsnType *AsnOcts::Clone() const
+{
+  return new AsnOcts;
+}
+
+AsnType *AsnOcts::Copy() const
+{
+  return new AsnOcts (*this);
+}
+
+// Initialize the AsnOcts with a char * and length.
+// copies the string str.
+void AsnOcts::Set (const char *str, size_t len)
+{
+    octetLen = len;
+#ifndef _IBM_ENC_
+    octs = new char[octetLen];
+#else
+    octs = (char *) mem_mgr_ptr->Get (octetLen+1);          /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+    memcpy (octs, str, octetLen);
+}
+
+// Initialize the AsnOcts from another AsnOcts
+// copies the string from o.
+void AsnOcts::Set (const AsnOcts &o)
+{
+    if (&o != this) // avoid o = o;
+    {
+        octetLen = o.octetLen;
+#ifndef _IBM_ENC_
+        octs = new char[octetLen];
+#else
+	octs = (char *) mem_mgr_ptr->Get (octetLen+1);         /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+        memcpy (octs, o.octs, octetLen);
+    }
+}
+
+// Initialize the AsnOcts from a Null terminated string.
+// copies the string str.
+void AsnOcts::Set (const char *str)
+{
+    octetLen = strlen (str);
+#ifndef _IBM_ENC_
+    octs = new char[octetLen];
+#else
+    octs = (char *) mem_mgr_ptr->Get (octetLen+1);         /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+    memcpy (octs, str, octetLen);
+}
+
+
+// free old octs value and tehn set the new
+// octs and octetLen values with the given char *and length.
+// copies the string str.
+void AsnOcts::ReSet (const char *str, size_t len)
+{
+    if (str != octs)
+    {
+#ifndef _IBM_ENC_
+        delete octs;
+        Set (str, len);
+#else
+      mem_mgr_ptr->Put ((void *)octs);                /* Guido Grassel, 11.8.93 */
+      Set (str, len);
+#endif /* _IBM_ENC_ */
+    }
+}
+
+// Free old octs value and then set the new
+// octs and octetLen from the given AsnOcts
+// copies the string in o.
+void AsnOcts::ReSet (const AsnOcts &o)
+{
+    if (&o != this) // avoid s = s;
+    {
+#ifndef _IBM_ENC_
+        delete octs;
+        Set (o);
+#else
+      mem_mgr_ptr->Put ((void *)octs);               /* Guido Grassel, 11.8.93 */
+      Set (o);
+#endif /* _IBM_ENC_ */
+    }
+}
+
+// Free old octs value and then set the new
+// octs and octetLen values from a null terminated string.
+// copies the string str.
+void AsnOcts::ReSet (const char *str)
+{
+    if (str != octs)
+    {
+#ifndef _IBM_ENC_
+        delete octs;
+        Set (str);
+#else
+      mem_mgr_ptr->Put ((void *)octs);                /* Guido Grassel, 11.8.93 */
+      Set (str);
+#endif /* _IBM_ENC_ */
+    }
+}
+
+
+// Prints the AsnOcts to the given ostream in Value Notation.
+void AsnOcts::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+    int i;
+    os << "'";
+    for (i = 0; i < octetLen; i++)
+        os << TO_HEX (octs[i] >> 4) << (TO_HEX (octs[i]));
+
+    os << "'H  -- \"";
+
+    /* put printable parts in ASN.1 comment */
+    for (i = 0; i < octetLen; i++)
+    {
+        if (isspace (octs[i]))
+            os << " ";  /* newlines->space (so don't screw up ASN.1 comment) */
+        else if (isprint (octs[i]))
+            os <<octs[i];
+        else
+            os << ".";
+    }
+    os << "\" --";
+#endif	/* NDEBUG */
+} /* AsnOcts::Print */
+
+
+AsnLen AsnOcts::BEncContent (BUF_TYPE b)
+{
+    b.PutSegRvs (octs, octetLen);
+    return octetLen;
+}
+
+// Decodes a BER OCTET STRING value and puts it in this object.
+// Constructed OCTET STRINGs are always concatenated into primitive ones.
+void AsnOcts::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    /*
+     * tagId is encoded tag shifted into long int.
+     * if CONS bit is set then constructed octet string
+     */
+    if (tagId & 0x20000000)
+        BDecConsOcts (b, elmtLen, bytesDecoded, env);
+
+    else /* primitive octet string */
+    {
+        octetLen = elmtLen;
+#ifndef _IBM_ENC_
+        octs =  Asn1Alloc (elmtLen+1);
+#else
+      octs = (char *) mem_mgr_ptr->Get (elmtLen+1);                /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+        b.CopyOut (octs, elmtLen);
+
+        if (b.ReadError())
+        {
+            Asn1Error << "BDecOctetString: ERROR - decoded past end of data" << endl;
+            longjmp (env, -14);
+        }
+
+        /* add null terminator - this is not included in the str's len */
+        octs[elmtLen] = '\0';
+        bytesDecoded += elmtLen;
+    }
+
+} /* AsnOcts::BDecContent */
+
+AsnLen AsnOcts::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l =  BEncContent (b);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    return l;
+}
+
+void AsnOcts::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    tag = BDecTag (b, bytesDecoded, env);
+    if ((tag != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) &&
+	(tag != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+    {
+	Asn1Error << "AsnOcts::BDec: ERROR tag on OCTET STRING is wrong." << endl;
+	longjmp (env,-56);
+    }
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+
+
+/*
+ * Used for concatenating constructed OCTET STRING values when decoding
+ *
+ * fills string stack with references to the pieces of a
+ * construced octet string
+ */
+#ifdef __APPLE__
+static void
+FillOctetStringStk (BUF_TYPE b, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env, StrStk &strStkG)
+#else
+static void
+FillOctetStringStk (BUF_TYPE b, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+#endif
+{
+    size_t refdLen;
+    size_t totalRefdLen;
+    char *strPtr;
+    AsnLen totalElmtsLen1 = 0;
+    unsigned long int tagId1;
+    AsnLen elmtLen1;
+
+    for (; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        tagId1 = BDecTag (b, totalElmtsLen1, env);
+
+        if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, totalElmtsLen1, env);
+            break;
+        }
+
+        elmtLen1 = BDecLen (b, totalElmtsLen1, env);
+        if (tagId1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+        {
+            /*
+             * primitive part of string, put references to piece (s) in
+             * str stack
+             */
+            totalRefdLen = 0;
+            refdLen = elmtLen1;
+            while (1)
+            {
+                strPtr = b.GetSeg (&refdLen);
+
+                strStkG.Push (strPtr, refdLen);
+                totalRefdLen += refdLen;
+                if (totalRefdLen == elmtLen1)
+                    break; /* exit this while loop */
+
+                if (refdLen == 0) /* end of data */
+                {
+                    Asn1Error << "BDecConsOctetString: ERROR - attempt to decode past end of data" << endl;
+                    longjmp (env, -15);
+                }
+                refdLen = elmtLen1 - totalRefdLen;
+            }
+            totalElmtsLen1 += elmtLen1;
+        }
+
+
+        else if (tagId1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE))
+        {
+            /*
+             * constructed octets string embedding in this constructed
+             * octet string. decode it.
+             */
+			#ifdef	__APPLE__
+            FillOctetStringStk (b, elmtLen1, totalElmtsLen1, env,
+				strStkG);
+			#else
+            FillOctetStringStk (b, elmtLen1, totalElmtsLen1, env);
+			#endif
+        }
+        else  /* wrong tag */
+        {
+            Asn1Error << "BDecConsOctetString: ERROR - decoded non-OCTET STRING tag inside a constructed OCTET STRING" << endl;
+            longjmp (env, -16);
+        }
+    } /* end of for */
+
+    bytesDecoded += totalElmtsLen1;
+
+}  /* AsnOcts::FillOctetStringStk */
+
+
+
+/*
+ * decodes a seq of universally tagged octets until either EOC is
+ * encountered or the given len decoded.  Return them in a
+ * single concatenated octet string
+ */
+void AsnOcts::BDecConsOcts (BUF_TYPE b, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+	#ifdef	__APPLE__
+	StrStk strStkG(128, 64);
+	#endif
+    strStkG.Reset();
+
+    /*
+     * decode each piece of the octet string, puting
+     * an entry in the octet/bit string stack for each
+     */
+	#ifdef	__APPLE__
+    FillOctetStringStk (b, elmtLen, bytesDecoded, env, strStkG);
+	#else
+    FillOctetStringStk (b, elmtLen, bytesDecoded, env);
+	#endif
+	
+    /* alloc single str long enough for combined octetstring */
+    octetLen = strStkG.totalByteLen;
+
+#ifndef _IBM_ENC_
+    octs = Asn1Alloc (octetLen);
+#else
+    octs = (char *) mem_mgr_ptr->Get (octetLen);                /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+
+    strStkG.CopyOut (octs);
+
+}  /* BDecConsOcts */
+
+int AsnOcts::OctsEquiv (const AsnOcts &o) const
+{
+    return o.octetLen == octetLen && !memcmpeq (o.octs, octs, octetLen);
+}
+
+#if META
+
+const AsnOctsTypeDesc AsnOcts::_desc (NULL, NULL, false, AsnTypeDesc::OCTET_STRING, NULL);
+
+const AsnTypeDesc *AsnOcts::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+int AsnOcts::TclGetVal (Tcl_Interp *interp) const
+{
+  return debinify (interp, octs, octetLen);
+}
+
+int AsnOcts::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+  char*		buf;
+  size_t	len;
+  int		result = TCL_OK;
+
+#ifndef _IBM_ENC_
+    buf = new char[strlen (valstr)];
+#else
+    buf = (char *) mem_mgr_ptr->Get (strlen (valstr)+1);
+#endif /* _IBM_ENC_ */
+
+  if (!buf)
+  {
+    Tcl_AppendResult (interp, "Malloc failed for type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL);
+    return TCL_ERROR;
+  }
+  if (binify (interp, valstr, buf, &len) != TCL_OK)
+  {
+    Tcl_AppendResult (interp, " for type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL);
+    result = TCL_ERROR;
+  }
+  else
+    ReSet (buf, len);
+
+#ifndef _IBM_ENC_
+  delete buf;
+#else
+  mem_mgr_ptr->Put ((void*) buf);
+#endif /* _IBM_ENC_ */
+
+  return result;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp
new file mode 100644
index 00000000..a89ce869
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp
@@ -0,0 +1,465 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-oid.C   - OBJECT IDENTIFIER
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp,v 1.3 2001/06/27 23:09:15 dmitch Exp $
+// $Log: asn-oid.cpp,v $
+// Revision 1.3  2001/06/27 23:09:15  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.2  2001/06/21 19:51:43  dmitch
+// Made AsnOid::Set(unsigned long...) thread-safe by making static arc arrays local.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.4  2001/05/05 00:59:19  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.3  2000/06/08 20:05:35  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.3  1999/03/21 02:07:37  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.2  1999/02/26 00:23:40  mb
+// Fixed for Mac OS 8
+//
+// Revision 1.1  1999/02/25 05:21:53  mb
+// Added snacc c++ library
+//
+// Revision 1.7  1997/02/28 13:39:46  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.6  1997/02/16 12:32:49  rj
+// name lookup of \for' scoping
+//
+// Revision 1.5  1995/08/17  15:31:14  rj
+// set Tcl's errorCode variable
+//
+// Revision 1.4  1995/07/24  20:25:38  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:28  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:17  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:06  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#if TCL
+#include <strstream.h>
+#endif
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-oid.h"
+#include "print.h"
+
+AsnOid::~AsnOid()
+{
+  delete oid;
+}
+
+AsnType *AsnOid::Clone() const
+{
+  return new AsnOid;
+}
+
+AsnType *AsnOid::Copy() const
+{
+  return new AsnOid (*this);
+}
+
+// Initializes an AsnOid with a string and it's length.
+// The string should hold the encoded OID.
+// The string is copied
+#ifndef _IBM_ENC_
+void AsnOid::Set (const char *encOid, size_t len)
+#else
+void AsnOid::Set (const char *encOid, const size_t len)
+#endif /* _IBM_ENC_ */
+{
+    if (encOid != oid)
+    {
+        octetLen = len;
+#ifndef _IBM_ENC_
+        oid = new char[octetLen];
+#else
+        oid = (char *) mem_mgr_ptr->Get (octetLen);         /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+        memcpy (oid, encOid, octetLen);
+    }
+}
+
+// Inits an AsnOid from another OID.
+// The oid string is copied.
+void AsnOid::Set (const AsnOid &o)
+{
+    if (&o != this)
+    {
+        octetLen = o.octetLen;
+#ifndef _IBM_ENC_
+        oid = new char[octetLen];
+#else
+        oid = (char *) mem_mgr_ptr->Get (octetLen);         /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+        memcpy (oid, o.oid, octetLen);
+    }
+}
+
+
+// Given some arc numbers, an AsnOid is built.
+// Set (1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1) results in
+// oid { 1 2 3 4 5 }.  The first negative arc number represnts
+// the end of the arc numbers - at least 2 are required.
+// The prototype in the AsnOid class provides default -1 parameters
+// so you only need to provide the number of arc number in the oid
+// as params. (eg Set (1,2,3,4,5))
+void AsnOid::Set (unsigned long int a1, unsigned long int a2, long int a3, long int a4, long int a5, long int a6, long int a7, long int a8, long int a9, long int a10, long int a11)
+{
+    long int arcNumArr[11];
+    char buf[11*5];  /* make big enough for max oid with 11 arcs*/
+    char *tmpBuf;
+    size_t totalLen;
+    size_t elmtLen;
+    long int tmpArcNum;
+    long int headArcNum;
+
+    tmpBuf = buf;
+
+    arcNumArr[0] = a1;
+    arcNumArr[1] = a2;
+    arcNumArr[2] = a3;
+    arcNumArr[3] = a4;
+    arcNumArr[4] = a5;
+    arcNumArr[5] = a6;
+    arcNumArr[6] = a7;
+    arcNumArr[7] = a8;
+    arcNumArr[8] = a9;
+    arcNumArr[9] = a10;
+    arcNumArr[10] = a11;
+
+    // munge together first oid arc numbers
+    headArcNum = tmpArcNum = (arcNumArr[0] * 40) + arcNumArr[1];
+
+    // figure encoded length for this arc number
+    for (elmtLen = 1; (tmpArcNum >>= 7) != 0; elmtLen++)
+	;
+
+    // write bytes except the last/least significant of the head arc number
+    // more bit is on
+    totalLen = elmtLen;
+    int i;
+    for (i = 1; i < elmtLen; i++)
+    {
+        *(tmpBuf++) = 0x80 | (headArcNum >> ((elmtLen-i)*7));
+    }
+
+    // write least significant (more bit is off)
+    *(tmpBuf++) = 0x7f & headArcNum;
+
+    // repeat for the rest of the arc numbers
+    for (i = 2; (i < 11) && (arcNumArr[i] > 0); i++)
+    {
+        tmpArcNum = arcNumArr[i];
+        for (elmtLen = 1; (tmpArcNum >>= 7) != 0; elmtLen++)
+	    ;
+        totalLen += elmtLen;
+        tmpArcNum = arcNumArr[i];
+        for (int j = 1; j < elmtLen; j++)
+        {
+            *(tmpBuf++) = 0x80 | (tmpArcNum >> ((elmtLen-j)*7));
+        }
+        *(tmpBuf++) = 0x7f & tmpArcNum;
+    }
+
+#ifndef _IBM_ENC_
+    oid = Asn1Alloc (totalLen);
+#else
+    oid = (char *) mem_mgr_ptr->Get (totalLen);               /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+    memcpy (oid, buf, totalLen);
+    octetLen = totalLen;
+
+}  /* AsnOid::Set */
+
+
+
+// Like Set except frees old oid value first
+#ifndef _IBM_ENC_
+void AsnOid::ReSet (const char *encOid, size_t len)
+#else
+void AsnOid::ReSet (const char *encOid, const size_t len)
+#endif /* _IBM_ENC_ */
+{
+    if (encOid != oid)
+    {
+#ifndef _IBM_ENC_
+        delete oid;
+#else
+      mem_mgr_ptr->Put ((void *) oid);                /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+        Set (encOid, len);
+    }
+}
+
+// Like Set except frees old oid value first
+void AsnOid::ReSet (const AsnOid &o)
+{
+    if (&o != this)
+    {
+#ifndef _IBM_ENC_
+        delete oid;
+#else
+      mem_mgr_ptr->Put ((void *) oid);                /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+        Set (o);
+    }
+}
+
+void AsnOid::ReSet (unsigned long int a1, unsigned long int a2, long int a3, long int a4, long int a5, long int a6, long int a7, long int a8, long int a9, long int a10, long int a11)
+{
+#ifndef _IBM_ENC_
+    delete oid;
+#else
+  mem_mgr_ptr->Put ((void *) oid);                /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+    Set (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+}
+
+
+// returns the number of arc numbers in the OID value
+unsigned long int AsnOid::NumArcs() const
+{
+    int i;
+    int numArcs;
+
+    for (numArcs=0, i=0; i < octetLen; )
+    {
+        // skip octets in this arc num with the 'more' bit set
+        for (; (i < octetLen) && (oid[i] & 0x80); i++)
+	    ;
+
+        // skip last octet in this arc num (no more bit)
+        i++;
+
+        numArcs++;
+    }
+
+    // add one to return value because the first two arcs are
+    // crunched together into a single one.
+    return numArcs +1;
+
+}  /* AsnOid::NumArcs */
+
+int AsnOid::OidEquiv (const AsnOid &o) const
+{
+    return o.octetLen == octetLen && !strncmp (o.oid, oid, octetLen);
+}
+
+
+
+// Decodes the content of a BER OBJECT IDENTIFIER value and puts
+// the results in this AsnOid object.
+void AsnOid::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    /* treat like primitive octet string */
+    octetLen = elmtLen;
+#ifndef _IBM_ENC_
+    oid =  Asn1Alloc (elmtLen);
+#else
+    oid = (char *) mem_mgr_ptr->Get (elmtLen);                /* Guido Grassel, 11.8.93 */
+#endif /* _IBM_ENC_ */
+    b.CopyOut (oid, elmtLen);
+
+    if (b.ReadError())
+    {
+        Asn1Error << "BDecOctetString: ERROR - decoded past end of data" << endl;
+        longjmp (env, -17);
+    }
+    bytesDecoded += elmtLen;
+} /* AsnOid::BDecContent */
+
+AsnLen AsnOid::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l =  BEncContent (b);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    return l;
+}
+
+void AsnOid::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE))
+    {
+	Asn1Error << "AsnOid::BDec: ERROR tag on OBJECT IDENTIFIER is wrong." << endl;
+	longjmp (env,-57);
+    }
+    elmtLen = BDecLen (b, bytesDecoded, env);
+
+    BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE), elmtLen, bytesDecoded, env);
+}
+
+AsnLen AsnOid::BEncContent (BUF_TYPE b)
+{
+    b.PutSegRvs (oid, octetLen);
+    return octetLen;
+}
+
+// Prints an AsnOid in ASN.1 Value Notation.
+// Decodes the oid to get the individual arc numbers
+void AsnOid::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+  unsigned short int firstArcNum;
+  unsigned long int arcNum;
+  int i;
+
+  // print oid in
+  os << "{";
+
+  if (oid)
+  {
+    // un-munge first two arc numbers
+    for (arcNum = 0, i=0; (i < octetLen) && (oid[i] & 0x80); i++)
+      arcNum = (arcNum << 7) + (oid[i] & 0x7f);
+
+    arcNum = (arcNum << 7) + (oid[i] & 0x7f);
+    i++;
+    firstArcNum = arcNum/40;
+    if (firstArcNum > 2)
+      firstArcNum = 2;
+
+    os << firstArcNum  << " " << arcNum - (firstArcNum * 40);
+
+    for (; i < octetLen; )
+    {
+      for (arcNum = 0; (i < octetLen) && (oid[i] & 0x80); i++)
+	arcNum = (arcNum << 7) + (oid[i] & 0x7f);
+
+      arcNum = (arcNum << 7) + (oid[i] & 0x7f);
+      i++;
+      os << " " << arcNum;
+    }
+  }
+  else
+    os << "-- void --";
+
+  os << "}";
+#endif	/* NDEBUG */
+} // AsnOid::Print
+
+#if META
+
+const AsnOidTypeDesc AsnOid::_desc (NULL, NULL, false, AsnTypeDesc::OBJECT_IDENTIFIER, NULL);
+
+const AsnTypeDesc *AsnOid::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+int AsnOid::TclGetVal (Tcl_Interp *interp) const
+{
+  if (oid)
+  {
+    strstream buf;
+    buf << *this;
+    buf.str()[strlen(buf.str())-1] = '\0';			// chop the trailing '}'
+    Tcl_SetResult (interp, buf.str()+1, TCL_VOLATILE);	// copy without leading '{'
+  }
+  return TCL_OK;
+}
+
+int AsnOid::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+  if (!*valstr)
+  {
+    delete oid;
+    oid = NULL;
+    octetLen = 0;
+    return TCL_OK;
+  }
+
+  Args arc;
+  if (Tcl_SplitList (interp, (char*)valstr, &arc.c, &arc.v) != TCL_OK)
+    return TCL_ERROR;
+  if (arc.c < 2)
+  {
+    Tcl_AppendResult (interp, "oid arc must contain at least two numbers", NULL);
+    Tcl_SetErrorCode (interp, "SNACC", "ILLARC", "<2", NULL);
+    return TCL_ERROR;
+  }
+  if (arc.c > 11)
+  {
+    Tcl_AppendResult (interp, "snacc limits oid arcs to no more than 11 numbers", NULL);
+    Tcl_SetErrorCode (interp, "SNACC", "ILLARC", ">11", NULL);
+    return TCL_ERROR;
+  }
+
+  int na[11], i;
+  for (i=0; i<arc.c; i++)
+    if (Tcl_GetInt (interp, arc.v[i], na+i) != TCL_OK)
+      return TCL_ERROR;
+  while (i < 11)
+    na[i++] = -1;
+
+  ReSet (na[0], na[1], na[2], na[3], na[4], na[5], na[6], na[7], na[8], na[9], na[10]);
+
+  return TCL_OK;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-real.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-real.cpp
new file mode 100644
index 00000000..7774792c
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-real.cpp
@@ -0,0 +1,933 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-real.C - AsnReal (ASN.1 REAL) type
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-real.cpp,v 1.3 2001/06/27 23:09:15 dmitch Exp $
+// $Log: asn-real.cpp,v $
+// Revision 1.3  2001/06/27 23:09:15  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.2  2001/06/21 21:57:00  dmitch
+// Avoid global const PLUS_INFINITY, MINUS_INFINITY
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:19  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/08 20:05:36  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.3  1999/03/21 02:07:37  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.2  1999/02/26 00:23:40  mb
+// Fixed for Mac OS 8
+//
+// Revision 1.1  1999/02/25 05:21:53  mb
+// Added snacc c++ library
+//
+// Revision 1.7  1997/02/28 13:39:46  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.6  1995/08/17 15:27:19  rj
+// recognize and return "±inf" for PLUS-INFINITY/MINUS-INFINITY.
+//
+// Revision 1.5  1995/07/24  20:29:24  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1995/02/18  17:01:49  rj
+// denote a long if we want a long.
+// make the code work on little endian CPUs.
+// ported to work with CPU/compiler combinations providing 64 bit longs.
+//
+// Revision 1.3  1994/10/08  04:18:29  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:18  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:07  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-real.h"
+
+#ifndef IEEE_REAL_LIB
+/* ieee functions (in case not in math.h)*/
+extern "C" {
+extern int iszero (double);
+//extern int isinf (double);
+//extern int signbit (double);
+extern int ilogb (double);
+//extern double scalbn (double, int);
+}
+#endif
+
+double AsnPlusInfinity();
+double AsnMinusInfinity();
+
+#define ENC_PLUS_INFINITY	0x40
+#define ENC_MINUS_INFINITY	0x41
+
+#define REAL_BINARY		0x80
+#define REAL_SIGN		0x40
+#define REAL_EXPLEN_MASK	0x03
+#define REAL_EXPLEN_1		0x00
+#define REAL_EXPLEN_2		0x01
+#define REAL_EXPLEN_3		0x02
+#define REAL_EXPLEN_LONG	0x03
+#define REAL_FACTOR_MASK	0x0c
+#define REAL_BASE_MASK		0x30
+#define REAL_BASE_2		0x00
+#define REAL_BASE_8		0x10
+#define REAL_BASE_16		0x20
+
+AsnType *AsnReal::Clone() const
+{
+  return new AsnReal;
+}
+
+AsnType *AsnReal::Copy() const
+{
+  return new AsnReal (*this);
+}
+
+// Returns the smallest octet length needed to hold the given long int value
+static unsigned int
+SignedIntOctetLen (long int val)
+{
+    unsigned long int mask = (0x7f80L << ((sizeof (long int) - 2) * 8));
+    unsigned int retVal = sizeof (long int);
+
+    if (val < 0)
+        val = val ^ (~0L);  /* XOR val with all 1's */
+
+    while ((retVal > 1) && ((val & mask) == 0))
+    {
+        mask >>= 8;
+        retVal--;
+    }
+
+    return retVal;
+
+} /* SignedIntOctetLen */
+
+
+
+#ifdef IEEE_REAL_FMT
+
+// Returns the PLUS INFINITY in double format
+// This assumes that a C++ double is an IEEE double.
+// The bits for IEEE double PLUS INFINITY are
+// 0x7ff0000000000000
+double AsnPlusInfinity()
+{
+#ifndef _IBM_ENC_
+    double d;
+    unsigned char *c = (unsigned char *)&d;
+
+#if WORDS_BIGENDIAN
+    c[0] = 0x7f;
+    c[1] = 0xf0;
+    c[2] = 0x0;
+    c[3] = 0x0;
+    c[4] = 0x0;
+    c[5] = 0x0;
+    c[6] = 0x0;
+    c[7] = 0x0;
+#else
+    c[7] = 0x7f;
+    c[6] = 0xf0;
+    c[5] = 0x0;
+    c[4] = 0x0;
+    c[3] = 0x0;
+    c[2] = 0x0;
+    c[1] = 0x0;
+    c[0] = 0x0;
+#endif
+
+    return d;
+#else
+     return 1.7976931348623158e+308;
+#endif /* _IBM_ENC_ */
+} /* AsnPlusInfinity */
+
+double AsnMinusInfinity()
+{
+    return -AsnPlusInfinity();
+}
+
+#if SIZEOF_DOUBLE != 8
+  #error oops: doubles are expected to be 8 bytes in size!
+#endif
+
+/*
+ * Use this routine if you system/compiler represents doubles in the IEEE format.
+ */
+AsnLen AsnReal::BEncContent (BUF_TYPE b)
+{
+    int	exponent;
+    int isNeg;
+#if SIZEOF_LONG == 8
+    unsigned long mantissa, val, *p;
+    int i;
+#elif SIZEOF_LONG == 4
+    unsigned char *dbl;
+    unsigned long int *first4;
+    unsigned long int *second4;
+#else
+  #error long neither 8 nor 4 bytes in size?
+#endif
+
+    /* no contents for 0.0 reals */
+    if (value == 0.0) /* all bits zero, disregarding top/sign bit */
+        return 0;
+
+#if SIZEOF_LONG == 8
+    /*
+     * this part assumes that sizeof (long) == sizeof (double) == 8
+     * It shouldn't be endian-dependent but I haven't verified that
+     */
+
+    p = (unsigned long*) &value;
+    val = *p;
+
+    isNeg = (val >> 63) & 1;
+    /* special real values for +/- oo */
+    if (!finite (value))
+    {
+        if (isNeg)
+            b.PutByteRvs(ENC_MINUS_INFINITY);
+        else
+            b.PutByteRvs(ENC_PLUS_INFINITY);
+        return 1;
+    }
+    else /* encode a binary real value */
+    {
+	exponent = (val >> 52) & 0x7ff;
+	mantissa = (val & 0xfffffffffffffL) | 0x10000000000000L;
+
+	for (i = 0; i < 7; i++)
+	{
+          b.PutByteRvs(mantissa & 0xff);
+	  mantissa >>= 8;
+        }
+        exponent -= (1023 + 52);
+
+#elif SIZEOF_LONG == 4
+    /*
+     * this part assumes that sizeof (long) == 4 and
+     * that sizeof (double) == 8
+     *
+     * sign  exponent
+     *     b 2-12 incl
+     *  Sv-----------v----- rest is mantissa
+     * -------------------------------------------
+     * |         |
+     * -------------------------------------------
+     *  123456878 1234
+     *
+     * sign bit is 1 if real is < 0
+     * exponent is an 11 bit unsigned value (subtract 1023 to get correct exp value)
+     * decimal pt implied before mantissa (ie mantissa is all fractional)
+     * and implicit 1 bit to left of decimal
+     *
+     * when given NaN (not a number - ie oo/oo) it encodes the wrong value
+     * instead of checking for the error. If you want to check for it,
+     *  a NaN is any sign bit with a max exponent (all bits a 1) followed
+     *  by any non-zero mantissa. (a zero mantissa is used for infinity)
+     *
+     */
+
+    first4 = (unsigned long int*) (dbl = (unsigned char*) &value);
+    second4 = (unsigned long int *) (dbl + sizeof (long int));
+
+    /* no contents for 0.0 reals */
+    if (value == 0.0) /* all bits zero, disregarding top/sign bit */
+        return 0;
+
+    isNeg = dbl[0] & 0x80;
+
+    /* special real values for +/- oo */
+    if (((*first4 & 0x7fffffff) == 0x7ff00000) && (*second4 == 0))
+    {
+        if (isNeg)
+            b.PutByteRvs (ENC_MINUS_INFINITY);
+        else
+            b.PutByteRvs (ENC_PLUS_INFINITY);
+
+        return 1;
+    }
+    else  /* encode a binary real value */
+    {
+        exponent = (((*first4) >> 20) & 0x07ff);
+
+        /* write the mantissa (N value) */
+        b.PutSegRvs ((char*)(dbl+2), sizeof (double)-2);
+
+        /*
+         * The rightmost 4 bits of a double 2nd octet are the
+         * most sig bits of the mantissa.
+         * write the most signficant byte of the asn1 real manitssa,
+         * adding implicit bit to 'left of decimal' if not de-normalized
+         * (de normalized if exponent == 0)
+         *
+         * if the double is not in de-normalized form subtract 1023
+         * from the exponent to get proper signed exponent.
+         *
+         * for both the normalized and de-norm forms
+         * correct the exponent by subtracting 52 since:
+         *   1. mantissa is 52 bits in the double (56 in ASN.1 REAL form)
+         *   2. implicit decimal at the beginning of double's mantissa
+         *   3. ASN.1 REAL's implicit decimal is after its mantissa
+         * so converting the double mantissa to the ASN.1 form has the
+         * effect of multiplying it by 2^52. Subtracting 52 from the
+         * exponent corrects this.
+         */
+        if (exponent == 0) /* de-normalized - no implicit 1 to left of dec.*/
+        {
+            b.PutByteRvs (dbl[1] & 0x0f);
+            exponent -= 52;
+        }
+        else
+        {
+            b.PutByteRvs ((dbl[1] & 0x0f) | 0x10); /* 0x10 adds implicit bit */
+            exponent -= (1023 + 52);
+        }
+
+#else
+  #error long neither 8 nor 4 bytes in size?
+#endif
+
+        /*  write the exponent  */
+        b.PutByteRvs (exponent & 0xff);
+        b.PutByteRvs (exponent >> 8);
+
+        /* write format octet */
+        /* bb is 00 since base is 2 so do nothing */
+        /* ff is 00 since no other shifting is nec */
+        if (isNeg)
+            b.PutByteRvs (REAL_BINARY | REAL_EXPLEN_2 | REAL_SIGN);
+        else
+            b.PutByteRvs (REAL_BINARY | REAL_EXPLEN_2);
+
+        return sizeof (double) + 2;
+    }
+
+    /* not reached */
+
+}  /*  AsnReal::BEncContent */
+
+#else  /* IEEE_REAL_FMT not def */
+
+#ifdef IEEE_REAL_LIB
+
+// Returns the PLUS INFINITY in double format
+// this assumes you have the IEEE functions in
+// the math lib
+double AsnPlusInfinity()
+{
+    return infinity();
+} /* AsnPlusInfinity */
+
+double AsnMinusInfinity()
+{
+    return -AsnPlusInfinity();
+}
+
+// This routine uses the ieee library routines to encode
+// this AsnReal's double value
+AsnLen AsnReal::BEncContent (BUF_TYPE b)
+{
+    AsnLen encLen;
+    double mantissa;
+    double tmpMantissa;
+    unsigned int truncatedMantissa;
+    int exponent;
+    unsigned int expLen;
+    int sign;
+    unsigned char buf[sizeof (double)];
+    int i, mantissaLen;
+    unsigned char firstOctet;
+
+    /* no contents for 0.0 reals */
+    if (iszero (value))
+        return 0;
+
+    /* special real values for +/- oo */
+    if (isinf (value))
+    {
+        if (signbit (value)) /* neg */
+            b.PutByteRvs (ENC_MINUS_INFINITY);
+        else
+            b.PutByteRvs (ENC_PLUS_INFINITY);
+
+        encLen = 1;
+    }
+    else  /* encode a binary real value */
+    {
+        if (signbit (value))
+            sign = -1;
+        else
+            sign = 1;
+
+        exponent =  ilogb (value);
+
+        /* get the absolute value of the mantissa (subtract 1 to make < 1) */
+        mantissa = scalbn (fabs (value), -exponent-1);
+
+
+        tmpMantissa = mantissa;
+
+        /* convert mantissa into an unsigned integer */
+        for (i = 0; i < sizeof (double); i++)
+        {
+            /* normalizied so shift 8 bits worth to the left of the decimal */
+            tmpMantissa *= (1<<8);
+
+            /* grab only (octet sized) the integer part */
+            truncatedMantissa = (unsigned int) tmpMantissa;
+
+            /* remove part to left of decimal now for next iteration */
+            tmpMantissa -= truncatedMantissa;
+
+            /* write into tmp buffer */
+            buf[i] = truncatedMantissa;
+
+            /* keep track of last non zero octet so can zap trailing zeros */
+            if (truncatedMantissa)
+                mantissaLen = i+1;
+        }
+
+        /*
+         * write format octet  (first octet of content)
+         *  field  1 S bb ff ee
+         *  bit#   8 7 65 43 21
+         *
+         * 1 in bit#1 means binary rep
+         * 1 in bit#2 means the mantissa is neg, 0 pos
+         * bb is the base:    65  base
+         *                    00    2
+         *                    01    8
+         *                    10    16
+         *                    11    future ext.
+         *
+         * ff is the Value of F where  Mantissa = sign x N x 2^F
+         *    FF can be one of 0 to 3 inclusive. (used to save re-alignment)
+         *
+         * ee is the length of the exponent:  21   length
+         *                                    00     1
+         *                                    01     2
+         *                                    10     3
+         *                                    11     long form
+         *
+         *
+         * encoded binary real value looks like
+         *
+         *     fmt oct
+         *   --------------------------------------------------------
+         *   |1Sbbffee|  exponent (2's comp)  |   N (unsigned int)  |
+         *   --------------------------------------------------------
+         *    87654321
+         */
+        firstOctet = REAL_BINARY;
+        if (signbit (value))
+            firstOctet |= REAL_SIGN;
+
+        /* bb is 00 since base is 2 so do nothing */
+        /* ff is 00 since no other shifting is nec */
+
+        /*
+         * get exponent calculate its encoded length
+         * Note that the process of converting the mantissa
+         * double to an int shifted the decimal mantissaLen * 8
+         * to the right - so correct that here
+         */
+        exponent++; /* compensate for trick to put mantissa < 1 */
+        exponent -= (mantissaLen * 8);
+        expLen = SignedIntOctetLen (exponent);
+
+        switch (expLen)
+        {
+            case 1:
+                firstOctet |= REAL_EXPLEN_1;
+                break;
+            case 2:
+                firstOctet |= REAL_EXPLEN_2;
+                break;
+            case 3:
+                firstOctet |= REAL_EXPLEN_3;
+                break;
+            default:
+                firstOctet |= REAL_EXPLEN_LONG;
+                break;
+        }
+
+        encLen = mantissaLen + expLen + 1;
+
+        /* write the mantissa (N value) */
+        b.PutSegRvs ((char*)buf, mantissaLen);
+
+        /* write the exponent */
+        for (i = expLen; i > 0; i--)
+        {
+            b.PutByteRvs (exponent);
+            exponent >> 8;
+        }
+
+        /* write the exponents length if nec */
+        if (expLen > 3)
+        {
+            encLen++;
+            b.PutByteRvs (expLen);
+        }
+
+        /* write the format octet */
+        b.PutByteRvs (firstOctet);
+
+    }
+    return encLen;
+
+}  /*  AsnReal::BEncContent */
+
+#else  /* neither IEEE_REAL_FMT or IEEE_REAL_LIB are def */
+
+
+// Returns the PLUS INFINITY in double format
+// This assumes that a C++ double is an IEEE double.
+// The bits for IEEE double PLUS INFINITY are
+// 0x7ff0000000000000
+// NOTE: this is a guess - you should set this up for
+// your architecture
+double AsnPlusInfinity()
+{
+    double d;
+    unsigned char *c;
+    int i;
+
+    c = (unsigned char*)&d;
+    c[0] = 0x7f;
+    c[1] = 0xf0;
+    for (i = 2; i < sizeof (double); i++)
+        c[i] = 0;
+    return d;
+} /* AsnPlusInfinity */
+
+double AsnMinusInfinity()
+{
+    return -AsnPlusInfinity();
+}
+
+/*
+ * Encodes the content of an ASN.1 REAL value to the given buffer.
+ * This version of the routine does not assume an IEEE double rep.
+ * or the existence of the IEEE library routines.  Uses old style
+ * UNIX frexp etc.
+ */
+AsnLen AsnReal::BEncContent (BUF_TYPE b)
+{
+    unsigned long int encLen;
+    double mantissa;
+    double tmpMantissa;
+    unsigned int truncatedMantissa;
+    int exponent;
+    unsigned int expLen;
+    int sign;
+    unsigned char buf[sizeof (double)];
+    int i, mantissaLen;
+    unsigned char firstOctet;
+
+    /* no contents for 0.0 reals */
+    if (value == 0.0)
+        return 0;
+
+    /* special real values for +/- oo */
+    if (value == MINUS_INFINITY)
+    {
+        b.PutByteRvs (ENC_MINUS_INFINITY);
+        encLen = 1;
+    }
+    else if (value == PLUS_INFINITY)
+    {
+        b.PutByteRvs (ENC_PLUS_INFINITY);
+        encLen = 1;
+    }
+    else  /* encode a binary real value */
+    {
+        /*
+         * this is what frexp gets from value
+         * value == mantissa * 2^exponent
+         * where 0.5 <= |manitissa| < 1.0
+         */
+        mantissa = frexp (value, &exponent);
+
+        /* set sign and make mantissa = | mantissa | */
+        if (mantissa < 0.0)
+        {
+            sign = -1;
+            mantissa *= -1;
+        }
+        else
+            sign = 1;
+
+
+        tmpMantissa = mantissa;
+
+        /* convert mantissa into an unsigned integer */
+        for (i = 0; i < sizeof (double); i++)
+        {
+            /* normalizied so shift 8 bits worth to the left of the decimal */
+            tmpMantissa *= (1<<8);
+
+            /* grab only (octet sized) the integer part */
+            truncatedMantissa = (unsigned int) tmpMantissa;
+
+            /* remove part to left of decimal now for next iteration */
+            tmpMantissa -= truncatedMantissa;
+
+            /* write into tmp buffer */
+            buf[i] = truncatedMantissa;
+
+            /* keep track of last non zero octet so can zap trailing zeros */
+            if (truncatedMantissa)
+                mantissaLen = i+1;
+        }
+
+        /*
+         * write format octet  (first octet of content)
+         *  field  1 S bb ff ee
+         *  bit#   8 7 65 43 21
+         *
+         * 1 in bit#1 means binary rep
+         * 1 in bit#2 means the mantissa is neg, 0 pos
+         * bb is the base:    65  base
+         *                    00    2
+         *                    01    8
+         *                    10    16
+         *                    11    future ext.
+         *
+         * ff is the Value of F where  Mantissa = sign x N x 2^F
+         *    FF can be one of 0 to 3 inclusive. (used to save re-alignment)
+         *
+         * ee is the length of the exponent:  21   length
+         *                                    00     1
+         *                                    01     2
+         *                                    10     3
+         *                                    11     long form
+         *
+         *
+         * encoded binary real value looks like
+         *
+         *     fmt oct
+         *   --------------------------------------------------------
+         *   |1Sbbffee|  exponent (2's comp)  |   N (unsigned int)  |
+         *   --------------------------------------------------------
+         *    87654321
+         */
+        firstOctet = REAL_BINARY;
+        if (sign == -1)
+            firstOctet |= REAL_SIGN;
+
+        /* bb is 00 since base is 2 so do nothing */
+        /* ff is 00 since no other shifting is nec */
+
+        /*
+         * get exponent calculate its encoded length
+         * Note that the process of converting the mantissa
+         * double to an int shifted the decimal mantissaLen * 8
+         * to the right - so correct that here
+         */
+        exponent -= (mantissaLen * 8);
+        expLen = SignedIntOctetLen (exponent);
+
+        switch (expLen)
+        {
+            case 1:
+                firstOctet |= REAL_EXPLEN_1;
+                break;
+            case 2:
+                firstOctet |= REAL_EXPLEN_2;
+                break;
+            case 3:
+                firstOctet |= REAL_EXPLEN_3;
+                break;
+            default:
+                firstOctet |= REAL_EXPLEN_LONG;
+                break;
+        }
+
+        encLen = mantissaLen + expLen + 1;
+
+        /* write the mantissa (N value) */
+        b.PutSegRvs ((char*)buf, mantissaLen);
+
+        /* write the exponent */
+        for (i = expLen; i > 0; i--)
+        {
+            b.PutByteRvs (exponent);
+            exponent >> 8;
+        }
+
+        /* write the exponents length if nec */
+        if (expLen > 3)
+        {
+            encLen++;
+            b.PutByteRvs (expLen);
+        }
+
+        /* write the format octet */
+        b.PutByteRvs (firstOctet);
+
+    }
+    return encLen;
+
+}  /*  AsnReal:BEncContent */
+
+
+
+#endif
+#endif
+
+
+// Decode a REAL value's content from the given buffer.
+// places the result in this object.
+void AsnReal::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    unsigned char firstOctet;
+    unsigned char firstExpOctet;
+    int i;
+    unsigned int expLen;
+    double mantissa;
+    unsigned short base;
+    long int exponent = 0;
+    double tmpBase;
+    double tmpExp;
+
+
+    if (elmtLen == 0)
+    {
+        value = 0.0;
+        return;
+    }
+
+    firstOctet = b.GetByte();
+    if (elmtLen == 1)
+    {
+        bytesDecoded += 1;
+        if (firstOctet == ENC_PLUS_INFINITY)
+            value = PLUS_INFINITY;
+        else if (firstOctet == ENC_MINUS_INFINITY)
+            value = MINUS_INFINITY;
+        else
+        {
+            Asn1Error << "AsnReal::BDecContent: ERROR - unrecognized 1 octet length real number" << endl;
+            longjmp (env, -18);
+        }
+    }
+    else
+    {
+        if (firstOctet & REAL_BINARY)
+        {
+            firstExpOctet = b.GetByte();
+            if (firstExpOctet & 0x80)
+                exponent = -1;
+            switch (firstOctet & REAL_EXPLEN_MASK)
+            {
+                case REAL_EXPLEN_1:
+                    expLen = 1;
+                    exponent =  (exponent << 8) | firstExpOctet;
+                    break;
+
+                case REAL_EXPLEN_2:
+                    expLen = 2;
+                    exponent =  (exponent << 16) | (((unsigned long int) firstExpOctet) << 8) | b.GetByte();
+                    break;
+
+                case REAL_EXPLEN_3:
+                    expLen = 3;
+                    exponent =  (exponent << 16) | (((unsigned long int) firstExpOctet) << 8) | b.GetByte();
+                    exponent =  (exponent << 8) | b.GetByte();
+                    break;
+
+                default:  /* long form */
+                    expLen = firstExpOctet +1;
+                    i = firstExpOctet-1;
+                    firstExpOctet =  b.GetByte();
+                    if (firstExpOctet & 0x80)
+                        exponent = (-1 <<8) | firstExpOctet;
+                    else
+                        exponent = firstExpOctet;
+                    for (;i > 0; firstExpOctet--)
+                        exponent = (exponent << 8) | b.GetByte();
+                    break;
+            }
+
+            mantissa = 0.0;
+            for (i = 1 + expLen; i < elmtLen; i++)
+            {
+                mantissa *= (1<<8);
+                mantissa +=  b.GetByte();
+            }
+
+            /* adjust N by scaling factor */
+            mantissa *= (1<<((firstOctet & REAL_FACTOR_MASK) >> 2));
+
+            switch (firstOctet & REAL_BASE_MASK)
+            {
+                case REAL_BASE_2:
+                    base = 2;
+                    break;
+
+                case REAL_BASE_8:
+                    base = 8;
+                    break;
+
+                case REAL_BASE_16:
+                    base = 16;
+                    break;
+
+                default:
+                    Asn1Error << "AsnReal::BDecContent: ERROR - unsupported base for a binary real number." << endl;
+                   longjmp (env, -19);
+                   break;
+
+            }
+
+            tmpBase = base;
+            tmpExp = exponent;
+
+            value =  mantissa * pow ((double)base, (double)exponent);
+
+            if (firstOctet & REAL_SIGN)
+                value = -value;
+
+            bytesDecoded += elmtLen;
+        }
+        else /* decimal version */
+        {
+            Asn1Error << "AsnReal::BDecContent: ERROR - decimal REAL form is not currently supported" << endl;
+            longjmp (env, -20);
+        }
+    }
+
+} /* AsnInt::BDecContent */
+
+AsnLen AsnReal::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l =  BEncContent (b);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, REAL_TAG_CODE);
+    return l;
+}
+
+void AsnReal::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, REAL_TAG_CODE))
+    {
+	Asn1Error << "AsnReal::BDec: ERROR tag on REAL is wrong." << endl;
+	longjmp (env,-58);
+    }
+    elmtLen = BDecLen (b, bytesDecoded, env);
+
+    BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, REAL_TAG_CODE), elmtLen, bytesDecoded, env);
+}
+
+void AsnReal::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+  os << value;
+#endif
+}
+
+#if META
+
+const AsnRealTypeDesc AsnReal::_desc (NULL, NULL, false, AsnTypeDesc::REAL, NULL);
+
+const AsnTypeDesc *AsnReal::_getdesc() const
+{
+  return &_desc;
+}
+
+#if TCL
+
+int AsnReal::TclGetVal (Tcl_Interp *interp) const
+{
+  if (value == PLUS_INFINITY)
+    strcpy (interp->result, "+inf");
+  else if (value == MINUS_INFINITY)
+    strcpy (interp->result, "-inf");
+  else
+    sprintf (interp->result, "%g", value);
+  return TCL_OK;
+}
+
+int AsnReal::TclSetVal (Tcl_Interp *interp, const char *valstr)
+{
+  double valval;
+
+  if (!strcmp (valstr, "+inf"))
+    valval = PLUS_INFINITY;
+  else if (!strcmp (valstr, "-inf"))
+    valval = MINUS_INFINITY;
+  else if (Tcl_GetDouble (interp, (char*)valstr, &valval) != TCL_OK)
+    return TCL_ERROR;
+
+  value = valval;
+
+  return TCL_OK;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-tag.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-tag.cpp
new file mode 100644
index 00000000..31bcbea9
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-tag.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-tag.C -  ASN.1 tag manipulation routines
+//
+// MS 92/06/18
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-tag.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-tag.cpp,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:58  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:36  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:54  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/09/03 12:10:30  wan
+// Patch to tag decoding for tags > 2^14 (thanks to Enrico Badella)
+//
+// Revision 1.5  1997/02/16 20:26:06  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/24  20:33:17  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:30  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:20  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:09  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+
+/*
+ * Decode a BER Tag from the given buffer.  Error is
+ * flagged if the tag is too long or if a read error occurs.
+ */
+AsnTag
+BDecTag (BUF_TYPE  b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tagId;
+    AsnTag tmpTagId;
+    int i;
+
+    tagId = ((AsnTag) b.GetByte()) << ((sizeof (AsnTag)-1) *8);
+    bytesDecoded++;
+
+    /* check if long tag format (ie code > 31) */
+    if ((tagId & (((AsnTag) 0x1f) << ((sizeof (AsnTag)-1)*8))) == (((AsnTag)0x1f) << ((sizeof (AsnTag)-1)*8)))
+    {
+        i = 2;
+        do
+        {
+            tmpTagId = (AsnTag) b.GetByte();
+            tagId |= (tmpTagId << ((sizeof (AsnTag)-i)*8));
+            bytesDecoded++;
+            i++;
+        }
+        while ((tmpTagId & (AsnTag)0x80) && (i <= sizeof (AsnTag)));
+
+        /*
+         * check for too long a tag
+         */
+        if (i > (sizeof (AsnTag)+1))
+        {
+            Asn1Error << "BDecTag: ERROR - tag value overflow" << endl;
+            longjmp (env, -21);
+        }
+    }
+
+    if (b.ReadError())
+    {
+        Asn1Error << "BDecTag: ERROR - decoded past the end of data" << endl;
+        longjmp (env, -22);
+    }
+
+    return tagId;
+
+} /* BDecTag */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-type.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-type.cpp
new file mode 100644
index 00000000..790d10e4
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-type.cpp
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/asn-type.C  - Abstract class that all ASN.1 types are derived from
+//               Design motivated by ANY type.
+//
+//               Runtime cost in speed and space for virtual fcns will
+//               hopefully not be too bad
+//
+//               If your ASN.1 code does not use ANY or ANY DEFIND BY
+//               types then you could  make the BEnc, BDec and Clone
+//               non-virtual in the AsnType to improve performance.
+//               (undef SUPPORT_ANY_TYPE)
+//
+//               NOTE: The virtual encode/decode/print etc fcns
+//               could be purely virtual (= 0) creating an abstract class
+//               but the ANY handling code needs to instantiate the AsnType
+//               base class (via Cloning).   Also it allows for default
+//               error reporting for ANY types that have not been
+//               instantiated properly.
+//
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// MS 92
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-type.cpp,v 1.2 2001/06/27 23:09:15 dmitch Exp $
+// $Log: asn-type.cpp,v $
+// Revision 1.2  2001/06/27 23:09:15  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:58  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:36  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:38  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:55  mb
+// Added snacc c++ library
+//
+// Revision 1.4  1997/01/01 20:13:55  rj
+// "virtual" removed from functions. (fix due to changed C++ language.)
+//
+// Revision 1.3  1995/07/24  20:35:21  rj
+// _getref() gets an additional optional argument to faciliate the different member access semantics of TclGetVal() and TclSetVal().
+//
+// additional function TclUnsetVal() to delete OPTIONAL members and SEQUENCE OF and SET OF list elements.
+// returns an error for all other types.
+//
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.2  1994/10/08  04:18:31  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.1  1994/09/13  14:18:45  rj
+// inline functions moved from asn_type.h to asn_type.C.
+// functions that are called upon error only don't need to be that fast.
+//
+// Revision 1.2  1994/08/28  10:00:57  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:44  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-type.h"
+
+AsnType::~AsnType()
+{
+}
+
+#ifdef SUPPORT_ANY_TYPE
+
+AsnType	 *AsnType::Clone() const
+{
+  return NULL;
+}
+
+AsnType	 *AsnType::Copy() const
+{
+  return NULL;
+}
+
+void AsnType::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  Asn1Error << "ERROR - Attempt to decode an improperly formed ANY type (programming error)." << endl;
+  longjmp (env, -80);
+}
+
+AsnLen AsnType::BEnc (BUF_TYPE b)
+{
+  Asn1Error << "ERROR - Attempt to encode an improperly formed ANY type (programming error)." << endl;
+  return 0;
+}
+
+#endif
+
+void AsnType::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+  os << "ERROR - Attempt to print an improperly formed ANY type (programming error)." << endl;
+#endif	/* NDEBUG */
+}
+
+#if META
+
+const AsnTypeDesc AsnType::_desc (NULL, NULL, false, AsnTypeDesc::VOID, NULL);
+
+const AsnTypeDesc *AsnType::_getdesc() const
+{
+  return &_desc;
+}
+
+AsnType	*AsnType::_getref (const char *membername, bool create)
+{
+  return NULL;
+}
+
+const char *AsnType::_typename() const
+{
+  return _desc.typenames[_getdesc()->type];
+}
+
+#if TCL
+
+int AsnType::TclGetDesc (Tcl_DString *valstr) const
+{
+  return TCL_OK;
+}
+
+int AsnType::TclGetVal (Tcl_Interp *interp) const
+{
+  Tcl_AppendResult (interp, "can't get value from ", _typename(), NULL);
+  return TCL_ERROR;
+}
+
+int AsnType::TclSetVal (Tcl_Interp *interp, const char *)
+{
+  Tcl_AppendResult (interp, "can't set value in ", _typename(), NULL);
+  return TCL_ERROR;
+}
+
+int AsnType::TclUnsetVal (Tcl_Interp *interp, const char *)
+{
+  Tcl_AppendResult (interp, "can't unset member(s) in ", _typename(), NULL);
+  return TCL_ERROR;
+}
+
+#endif /* TCL */
+#endif /* META */
diff --git a/SecuritySNACCRuntime/c++-lib/c++/asn-useful.cpp b/SecuritySNACCRuntime/c++-lib/c++/asn-useful.cpp
new file mode 100644
index 00000000..2c09583a
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/asn-useful.cpp
@@ -0,0 +1,1491 @@
+/*
+ * 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.
+ */
+
+
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// asn-useful.cpp - class member functions for ASN.1 module ASN-USEFUL
+//
+//   This file was generated by snacc on Wed Jun 14 14:50:26 2000
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "asn-useful.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+AsnType *ObjectDescriptor::Clone() const
+{
+  return new ObjectDescriptor;
+}
+
+AsnType *ObjectDescriptor::Copy() const
+{
+  return new ObjectDescriptor (*this);
+}
+
+AsnLen ObjectDescriptor::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OD_TAG_CODE);
+    return l;
+}
+
+void ObjectDescriptor::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, OD_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, OD_TAG_CODE)))
+    {
+        Asn1Error << "ObjectDescriptor::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 50);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ObjectDescriptor::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ObjectDescriptor::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *UTF8String::Clone() const
+{
+  return new UTF8String;
+}
+
+AsnType *UTF8String::Copy() const
+{
+  return new UTF8String (*this);
+}
+
+AsnLen UTF8String::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, 12);
+    return l;
+}
+
+void UTF8String::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, 12))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, 12)))
+    {
+        Asn1Error << "UTF8String::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 49);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int UTF8String::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int UTF8String::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *NumericString::Clone() const
+{
+  return new NumericString;
+}
+
+AsnType *NumericString::Copy() const
+{
+  return new NumericString (*this);
+}
+
+AsnLen NumericString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE);
+    return l;
+}
+
+void NumericString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE)))
+    {
+        Asn1Error << "NumericString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 48);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int NumericString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int NumericString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *PrintableString::Clone() const
+{
+  return new PrintableString;
+}
+
+AsnType *PrintableString::Copy() const
+{
+  return new PrintableString (*this);
+}
+
+AsnLen PrintableString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+    return l;
+}
+
+void PrintableString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))
+    {
+        Asn1Error << "PrintableString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 47);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PrintableString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PrintableString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *TeletexString::Clone() const
+{
+  return new TeletexString;
+}
+
+AsnType *TeletexString::Copy() const
+{
+  return new TeletexString (*this);
+}
+
+AsnLen TeletexString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+}
+
+void TeletexString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error << "TeletexString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 46);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int TeletexString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int TeletexString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *T61String::Clone() const
+{
+  return new T61String;
+}
+
+AsnType *T61String::Copy() const
+{
+  return new T61String (*this);
+}
+
+AsnLen T61String::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+}
+
+void T61String::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error << "T61String::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 45);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int T61String::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int T61String::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *VideotexString::Clone() const
+{
+  return new VideotexString;
+}
+
+AsnType *VideotexString::Copy() const
+{
+  return new VideotexString (*this);
+}
+
+AsnLen VideotexString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE);
+    return l;
+}
+
+void VideotexString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, VIDEOTEXSTRING_TAG_CODE)))
+    {
+        Asn1Error << "VideotexString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 44);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int VideotexString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int VideotexString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *IA5String::Clone() const
+{
+  return new IA5String;
+}
+
+AsnType *IA5String::Copy() const
+{
+  return new IA5String (*this);
+}
+
+AsnLen IA5String::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, IA5STRING_TAG_CODE);
+    return l;
+}
+
+void IA5String::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, IA5STRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, IA5STRING_TAG_CODE)))
+    {
+        Asn1Error << "IA5String::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 43);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int IA5String::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int IA5String::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *GraphicString::Clone() const
+{
+  return new GraphicString;
+}
+
+AsnType *GraphicString::Copy() const
+{
+  return new GraphicString (*this);
+}
+
+AsnLen GraphicString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GRAPHICSTRING_TAG_CODE);
+    return l;
+}
+
+void GraphicString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, GRAPHICSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, GRAPHICSTRING_TAG_CODE)))
+    {
+        Asn1Error << "GraphicString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 42);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int GraphicString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int GraphicString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *VisibleString::Clone() const
+{
+  return new VisibleString;
+}
+
+AsnType *VisibleString::Copy() const
+{
+  return new VisibleString (*this);
+}
+
+AsnLen VisibleString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+}
+
+void VisibleString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error << "VisibleString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 41);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int VisibleString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int VisibleString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *ISO646String::Clone() const
+{
+  return new ISO646String;
+}
+
+AsnType *ISO646String::Copy() const
+{
+  return new ISO646String (*this);
+}
+
+AsnLen ISO646String::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+}
+
+void ISO646String::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error << "ISO646String::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 40);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ISO646String::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ISO646String::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *GeneralString::Clone() const
+{
+  return new GeneralString;
+}
+
+AsnType *GeneralString::Copy() const
+{
+  return new GeneralString (*this);
+}
+
+AsnLen GeneralString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALSTRING_TAG_CODE);
+    return l;
+}
+
+void GeneralString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, GENERALSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, GENERALSTRING_TAG_CODE)))
+    {
+        Asn1Error << "GeneralString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 39);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int GeneralString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int GeneralString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *UTCTime::Clone() const
+{
+  return new UTCTime;
+}
+
+AsnType *UTCTime::Copy() const
+{
+  return new UTCTime (*this);
+}
+
+AsnLen UTCTime::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, UTCTIME_TAG_CODE);
+    return l;
+}
+
+void UTCTime::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE)))
+    {
+        Asn1Error << "UTCTime::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 38);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int UTCTime::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int UTCTime::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *GeneralizedTime::Clone() const
+{
+  return new GeneralizedTime;
+}
+
+AsnType *GeneralizedTime::Copy() const
+{
+  return new GeneralizedTime (*this);
+}
+
+AsnLen GeneralizedTime::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    return l;
+}
+
+void GeneralizedTime::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+    {
+        Asn1Error << "GeneralizedTime::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 37);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int GeneralizedTime::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int GeneralizedTime::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *UniversalString::Clone() const
+{
+  return new UniversalString;
+}
+
+AsnType *UniversalString::Copy() const
+{
+  return new UniversalString (*this);
+}
+
+AsnLen UniversalString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, UNIVERSALSTRING_TAG_CODE);
+    return l;
+}
+
+void UniversalString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, UNIVERSALSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, UNIVERSALSTRING_TAG_CODE)))
+    {
+        Asn1Error << "UniversalString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 36);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int UniversalString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int UniversalString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *BMPString::Clone() const
+{
+  return new BMPString;
+}
+
+AsnType *BMPString::Copy() const
+{
+  return new BMPString (*this);
+}
+
+AsnLen BMPString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BMPSTRING_TAG_CODE);
+    return l;
+}
+
+void BMPString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, BMPSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, BMPSTRING_TAG_CODE)))
+    {
+        Asn1Error << "BMPString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 35);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int BMPString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int BMPString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+EXTERNALChoice::EXTERNALChoice()
+{
+  choiceId = single_ASN1_typeCid;
+#if TCL
+  single_ASN1_type = new AsnOcts;
+#else
+  single_ASN1_type = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EXTERNALChoice::EXTERNALChoice (const EXTERNALChoice &)
+{
+  Asn1Error << "use of incompletely defined EXTERNALChoice::EXTERNALChoice (const EXTERNALChoice &)" << endl;
+  abort();
+}
+
+EXTERNALChoice::~EXTERNALChoice()
+{
+  switch (choiceId)
+  {
+    case single_ASN1_typeCid:
+      delete single_ASN1_type;
+      break;
+    case octet_alignedCid:
+      delete octet_aligned;
+      break;
+    case arbitraryCid:
+      delete arbitrary;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *EXTERNALChoice::Clone() const
+{
+  return new EXTERNALChoice;
+}
+
+AsnType *EXTERNALChoice::Copy() const
+{
+  return new EXTERNALChoice (*this);
+}
+
+#if SNACC_DEEP_COPY
+EXTERNALChoice &EXTERNALChoice::operator = (const EXTERNALChoice &that)
+#else // SNACC_DEEP_COPY
+EXTERNALChoice &EXTERNALChoice::operator = (const EXTERNALChoice &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case single_ASN1_typeCid:
+        delete single_ASN1_type;
+        break;
+      case octet_alignedCid:
+        delete octet_aligned;
+        break;
+      case arbitraryCid:
+        delete arbitrary;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case single_ASN1_typeCid:
+        single_ASN1_type = new AsnOcts;
+        *single_ASN1_type = *that.single_ASN1_type;
+        break;
+      case octet_alignedCid:
+        octet_aligned = new AsnOcts;
+        *octet_aligned = *that.octet_aligned;
+        break;
+      case arbitraryCid:
+        arbitrary = new AsnBits;
+        *arbitrary = *that.arbitrary;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EXTERNALChoice &EXTERNALChoice::operator = (const EXTERNALChoice &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EXTERNALChoice::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case single_ASN1_typeCid:
+      BEncEocIfNec (b);
+      l = single_ASN1_type->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+      break;
+
+    case octet_alignedCid:
+      l = octet_aligned->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+      break;
+
+    case arbitraryCid:
+      l = arbitrary->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 2);
+      break;
+
+  } // end switch
+  return l;
+} // EXTERNALChoice::BEncContent
+
+
+void EXTERNALChoice::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnLen elmtLen1;
+  switch (tag)
+  {
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      tag = BDecTag (b, bytesDecoded, env);
+      if ((tag != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+          && (tag != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+      {
+         Asn1Error << "Unexpected Tag" << endl;
+         longjmp (env, 34);
+      }
+
+      elmtLen1 = BDecLen (b, bytesDecoded, env);
+      choiceId = single_ASN1_typeCid;
+      single_ASN1_type = new AsnOcts;
+        single_ASN1_type->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+      if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 1):
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = octet_alignedCid;
+      octet_aligned = new AsnOcts;
+        octet_aligned->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 2):
+    case MAKE_TAG_ID (CNTX, CONS, 2):
+      choiceId = arbitraryCid;
+      arbitrary = new AsnBits;
+        arbitrary->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, 33);
+      break;
+  } // end switch
+} // EXTERNALChoice::BDecContent
+
+
+AsnLen EXTERNALChoice::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void EXTERNALChoice::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int EXTERNALChoice::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EXTERNALChoice::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EXTERNALChoice::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+  switch (choiceId)
+  {
+    case single_ASN1_typeCid:
+      os << "single-ASN1-type ";
+      if (single_ASN1_type)
+        os << *single_ASN1_type;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case octet_alignedCid:
+      os << "octet-aligned ";
+      if (octet_aligned)
+        os << *octet_aligned;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case arbitraryCid:
+      os << "arbitrary ";
+      if (arbitrary)
+        os << *arbitrary;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+  #endif	/* NDEBUG */ 
+} // EXTERNALChoice::Print
+
+EXTERNAL::EXTERNAL()
+{
+  direct_reference = NULL;
+  indirect_reference = NULL;
+  data_value_descriptor = NULL;
+#if TCL
+  encoding = new EXTERNALChoice;
+#else
+  encoding = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EXTERNAL::EXTERNAL (const EXTERNAL &)
+{
+  Asn1Error << "use of incompletely defined EXTERNAL::EXTERNAL (const EXTERNAL &)" << endl;
+  abort();
+}
+
+EXTERNAL::~EXTERNAL()
+{
+  delete direct_reference;
+  delete indirect_reference;
+  delete data_value_descriptor;
+  delete encoding;
+}
+
+AsnType *EXTERNAL::Clone() const
+{
+  return new EXTERNAL;
+}
+
+AsnType *EXTERNAL::Copy() const
+{
+  return new EXTERNAL (*this);
+}
+
+#if SNACC_DEEP_COPY
+EXTERNAL &EXTERNAL::operator = (const EXTERNAL &that)
+#else // SNACC_DEEP_COPY
+EXTERNAL &EXTERNAL::operator = (const EXTERNAL &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.direct_reference)
+    {
+      if (!direct_reference)
+        direct_reference = new AsnOid;
+      *direct_reference = *that.direct_reference;
+    }
+    else
+    {
+      delete direct_reference;
+      direct_reference = NULL;
+    }
+    if (that.indirect_reference)
+    {
+      if (!indirect_reference)
+        indirect_reference = new AsnInt;
+      *indirect_reference = *that.indirect_reference;
+    }
+    else
+    {
+      delete indirect_reference;
+      indirect_reference = NULL;
+    }
+    if (that.data_value_descriptor)
+    {
+      if (!data_value_descriptor)
+        data_value_descriptor = new ObjectDescriptor;
+      *data_value_descriptor = *that.data_value_descriptor;
+    }
+    else
+    {
+      delete data_value_descriptor;
+      data_value_descriptor = NULL;
+    }
+    if (that.encoding)
+    {
+      if (!encoding)
+        encoding = new EXTERNALChoice;
+      *encoding = *that.encoding;
+    }
+    else
+    {
+      delete encoding;
+      encoding = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EXTERNAL &EXTERNAL::operator = (const EXTERNAL &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EXTERNAL::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = encoding->BEncContent (b);
+    totalLen += l;
+
+  if (NOT_NULL (data_value_descriptor))
+  {
+    l = data_value_descriptor->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OD_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (indirect_reference))
+  {
+    l = indirect_reference->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (direct_reference))
+  {
+    l = direct_reference->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // EXTERNAL::BEncContent
+
+
+void EXTERNAL::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    direct_reference = new AsnOid;
+    direct_reference->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    indirect_reference = new AsnInt;
+    indirect_reference->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OD_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OD_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    data_value_descriptor = new ObjectDescriptor;
+    data_value_descriptor->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 2))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encoding = new EXTERNALChoice;
+    encoding->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, 32);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, 31);
+  }
+  else
+    return;
+} // EXTERNAL::BDecContent
+
+AsnLen EXTERNAL::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, EXTERNAL_TAG_CODE);
+  return l;
+}
+
+void EXTERNAL::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, EXTERNAL_TAG_CODE))
+  {
+    Asn1Error << "EXTERNAL::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, 30);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EXTERNAL::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EXTERNAL::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EXTERNAL::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (direct_reference))
+  {
+    Indent (os, indentG);
+    os << "direct-reference ";
+    os << *direct_reference;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "direct-reference ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (indirect_reference))
+  {
+    Indent (os, indentG);
+    os << "indirect-reference ";
+    os << *indirect_reference;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "indirect-reference ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (data_value_descriptor))
+  {
+    Indent (os, indentG);
+    os << "data-value-descriptor ";
+    os << *data_value_descriptor;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "data-value-descriptor ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encoding))
+  {
+    Indent (os, indentG);
+    os << "encoding ";
+    os << *encoding;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encoding ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+  #endif	/* NDEBUG */
+} // EXTERNAL::Print
+
+
diff --git a/SecuritySNACCRuntime/c++-lib/c++/hash.cpp b/SecuritySNACCRuntime/c++-lib/c++/hash.cpp
new file mode 100644
index 00000000..f8ae365b
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/hash.cpp
@@ -0,0 +1,291 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/hash.C
+//
+// This was borrowed from Don Acton and Terry Coatta's Raven Code.
+// It has been modified somewhat.
+//    - Mike Sample 92
+//
+// This is a set or routines that implements an extensible hashing
+// algorithm. At the moment it assumes that all the hash codes are unique
+// (ie. there are no collisions). For the way hash codes are currently being
+// supplied this is not a bad assumption.
+// The extensible hashing routine used is based on a multiway tree with
+// each node in the tree being a fixed array of (2^n) size. At a given
+// level, i, in the tree with the first level being level 0, bits
+// i*n through i*n through (i+1)*n-1 are used as the index into the table.
+// Each entry in the table is either NULL (unused) or a pointer to an
+// object of type entry. The entry contains all the information about a
+// hash entry. The entry also contains a field indicating whether or not this
+// is a leaf node. If an entry isn't a leaf node then it references a table at
+// at the next level and not a value. With the current implementation
+// a 32 hash value is used and table sizes are 256. The algorithm used
+// here is the same as the one used in the Set class of the Raven
+// class system.
+//
+// Copyright (C) 1992 the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/hash.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: hash.cpp,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:58  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:36  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:56  mb
+// Added snacc c++ library
+//
+// Revision 1.7  1997/02/28 13:39:46  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.6  1997/02/16 20:26:08  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.5  1995/07/24  20:34:07  rj
+// use memzero that is defined in .../snacc.h to use either memset or bzero.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1994/10/08  04:18:32  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.3  1994/08/31  23:43:05  rj
+// FALSE/TRUE turned into false/true
+//
+// Revision 1.2  1994/08/28  10:01:21  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:11  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "hash.h"
+
+
+/*
+ *
+ * From sdbm, an ndbm work-alike hashed database library
+ * Author: oz@nexus.yorku.ca
+ * Status: public domain.
+ *
+ * polynomial conversion ignoring overflows
+ * [this seems to work remarkably well, in fact better
+ * then the ndbm hash function. Replace at your own risk]
+ * use: 65599   nice.
+ *      65587   even better.
+ *
+ * [In one experiment, this function hashed 84165 symbols (English words
+ * plus symbol table values) with no collisions. -bjb]
+ *
+ */
+
+Hash
+MakeHash (const char *str, size_t len)
+{
+    register Hash n = 0;
+
+#define HASHC   n = *str++ + 65587 * n
+
+    if (len > 0)
+    {
+        int loop;
+        loop = (len + 8 - 1) >> 3;
+        switch (len & (8 - 1))
+	{
+          case 0:            /* very strange! - switch labels in do loop */
+            do
+	    {
+                HASHC;
+              case 7: HASHC;
+              case 6: HASHC;
+              case 5: HASHC;
+              case 4: HASHC;
+              case 3: HASHC;
+              case 2: HASHC;
+              case 1: HASHC;
+	    } while (--loop);
+	}
+    }
+    return n;
+}
+
+
+/* Creates and clears a new hash slot */
+static HashSlot *
+NewHashSlot()
+{
+  HashSlot *foo;
+
+  foo =  new HashSlot;
+  if (foo == NULL)
+      return NULL;
+  memzero (foo, sizeof (HashSlot));
+  return foo;
+}
+
+/* Create a new cleared hash table */
+static Table *
+NewTable()
+{
+  Table *new_table;
+
+//  new_table = new Table;
+// whose bug is it that gcc won't compile the above line?
+  new_table = (Table *) new Table;
+  if (new_table == NULL)
+      return NULL;
+  memzero (new_table, sizeof (Table));
+  return new_table;
+}
+
+/* This routine is used to initialize the hash tables. When it is called
+ * it returns a value which is used to identify which hash table
+ * a particular request is to operate on.
+ */
+Table *
+InitHash()
+{
+  Table *table;
+  table = NewTable();
+  if (table == NULL)
+      return 0;
+  else
+      return table;
+}
+
+/* When a hash collision occurs at a leaf slot this routine is called to
+ * split the entry and add a new level to the tree at this point.
+ */
+static int
+SplitAndInsert (HashSlot *entry, void *element, Hash hash_value)
+{
+
+  if (((entry->table = NewTable()) == NULL) ||
+      !Insert (entry->table, entry->value, entry->hash >> INDEXSHIFT) ||
+      !Insert (entry->table, element, hash_value >> INDEXSHIFT))
+    return false;
+
+  entry->leaf = false;
+  return true;
+}
+
+/* This routine takes a hash table identifier, an element (value) and the
+ * coresponding hash value for that element and enters it into the table
+ * assuming it isn't already there.
+ */
+int
+Insert (Table *table, void *element, Hash hash_value)
+{
+  HashSlot *entry;
+
+  entry = (HashSlot *) (*table)[hash_value & INDEXMASK];
+
+  if (entry == NULL) {
+    /* Need to add this element here */
+    entry = NewHashSlot();
+    if (entry == NULL)
+        return false;
+    entry->leaf = true;
+    entry->value = element;
+    entry->hash = hash_value;
+    (*table)[hash_value & INDEXMASK] = entry;
+    return true;
+  }
+
+  if (hash_value == entry->hash)
+      return true;
+
+  if (entry->leaf)
+      return SplitAndInsert (entry, element, hash_value);
+
+  return Insert (entry->table, element, hash_value >> INDEXSHIFT);
+}
+
+
+/* This routine looks to see if a particular hash value is already stored in
+ * the table. It returns true if it is and false otherwise.
+ */
+int
+CheckFor (Table *table, Hash hash)
+{
+  HashSlot *entry;
+
+  entry = (HashSlot *) table[hash & INDEXMASK];
+
+  if (entry == NULL)
+      return false;
+  if (entry->leaf)
+      return entry->hash == hash;
+  return CheckFor (entry->table, hash >> INDEXSHIFT);
+}
+
+/* In addition to checking for a hash value in the tree this function also
+ * returns the coresponding element value into the space pointed to by
+ * the value parameter. If the hash value isn't found false is returned
+ * the the space pointed to by value is not changed.
+ */
+int
+CheckForAndReturnValue (Table *table, Hash hash, void **value)
+{
+  HashSlot *entry;
+  entry = (HashSlot *) (*table)[hash & INDEXMASK];
+
+  if (entry == NULL)
+      return false;
+
+  if (entry->leaf)
+  {
+      if (entry->hash == hash)
+      {
+          *value = entry->value;
+          return true;
+      }
+      else
+          return false;
+  }
+  return CheckForAndReturnValue (entry->table, hash >> INDEXSHIFT, value);
+}
diff --git a/SecuritySNACCRuntime/c++-lib/c++/meta.cpp b/SecuritySNACCRuntime/c++-lib/c++/meta.cpp
new file mode 100644
index 00000000..eae36ee9
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/meta.cpp
@@ -0,0 +1,464 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/meta.C
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/meta.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: meta.cpp,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:58  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:36  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:56  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/28 13:39:47  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.4  1995/08/17 15:23:51  rj
+// introducing an AsnEnumTypeDesc class with its own TclGetDesc2 function that returns the value names but omits the numeric values.
+// utility function AsnSe_TypeDesc::mandatmemberr added.
+//
+// Revision 1.3  1995/07/26  19:39:35  rj
+// comment leader fixed
+//
+// Revision 1.2  1995/07/25  22:11:31  rj
+// lots of new data types, and new data and function members in old ones.
+//
+// use memcmpeq that is defined in .../snacc.h to use either memcmp or bcmp.
+//
+// code extracted from AsnOcts::TclGetVal and AsnOcts::TclSetVal in asn-octs.C into ::debinify and ::binify.
+//
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// call constructor with additional pdu and create arguments.
+//
+// changed `_' to `-' in file names.
+
+#include "asn-incl.h"
+
+#if META
+
+AsnMemberDesc::AsnMemberDesc (const char *_name, const AsnTypeDesc *_desc):
+  name (_name),
+  desc (_desc)
+{
+}
+
+AsnMemberDesc::AsnMemberDesc():
+  name (NULL), desc(NULL)
+{
+}
+
+int AsnMemberDesc::TclGetDesc (Tcl_DString *desc) const
+{
+  if (name)
+  {
+    Tcl_DStringStartSublist (desc);
+    Tcl_DStringAppendElement (desc, (char*)name);
+    this->desc->AsnTypeDesc::TclGetDesc (desc);
+    TclGetDesc2 (desc);
+    Tcl_DStringEndSublist (desc);
+    return TCL_OK;
+  }
+  else
+    return TCL_BREAK;
+}
+
+int AsnMemberDesc::TclGetDesc2 (Tcl_DString *desc) const
+{
+  return TCL_OK;
+}
+
+AsnSe_MemberDesc::AsnSe_MemberDesc (const char *name, const AsnTypeDesc *desc, bool _optional):
+  AsnMemberDesc (name, desc),
+  optional (_optional)
+{
+}
+
+AsnSe_MemberDesc::AsnSe_MemberDesc():
+  AsnMemberDesc()
+{
+}
+
+int AsnSe_MemberDesc::TclGetDesc2 (Tcl_DString *desc) const
+{
+  Tcl_DStringAppendElement (desc, optional ? "optional" : "mandatory");
+  return TCL_OK;
+}
+
+const char *const AsnTypeDesc::typenames[] =	// NOTE: keep this array in sync with the enum Type
+{
+  "(void)",
+  "(alias)",
+
+  "INTEGER",
+  "REAL",
+  "NULL",
+  "BOOLEAN",
+  "ENUMERATED",
+  "BIT STRING",
+  "OCTET STRING",
+  "OBJECT IDENTIFIER",
+
+  "SET",
+  "SEQUENCE",
+  "SET OF",
+  "SEQUENCE OF",
+  "CHOICE",
+  "ANY",
+};
+
+AsnTypeDesc::AsnTypeDesc (const AsnModuleDesc *_module, const char *_name, bool ispdu, Type _type, AsnType *(*_create)()):
+  module (_module),
+  name (_name),
+  pdu (ispdu),
+  type (_type),
+  create (_create)
+{
+}
+
+const AsnModuleDesc *AsnTypeDesc::getmodule() const
+{
+  return module;
+}
+
+const char *AsnTypeDesc::getname() const
+{
+  return name;
+}
+
+bool AsnTypeDesc::ispdu() const
+{
+  return pdu;
+}
+
+AsnTypeDesc::Type AsnTypeDesc::gettype() const
+{
+  return type;
+}
+
+const AsnNameDesc *AsnTypeDesc::getnames() const
+{
+  Asn1Error << typenames[type] << "::getnames() called" << endl;
+  abort();
+  return NULL;
+}
+
+//const AsnMemberDesc *AsnTypeDesc::getmembers() const
+//{
+  //Asn1Error << typenames[type] << "::getmembers() called" << endl;
+  //abort();
+//}
+
+//\[banner "names types (int, enum)"]-----------------------------------------------------------------------------------------------
+AsnNamesTypeDesc::AsnNamesTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnNameDesc *_names):
+  AsnTypeDesc (module, name, ispdu, type, create),
+  names (_names)
+{
+}
+
+const AsnNameDesc *AsnNamesTypeDesc::getnames() const
+{
+  return names;
+}
+
+//\[banner "enum type"]-------------------------------------------------------------------------------------------------------------
+AsnEnumTypeDesc::AsnEnumTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnNameDesc *names):
+  AsnNamesTypeDesc (module, name, ispdu, type, create, names)
+{
+}
+
+//\[banner "members types (choice, set, sequence)"]---------------------------------------------------------------------------------
+AsnMembersTypeDesc::AsnMembersTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)()):
+  AsnTypeDesc (module, name, ispdu, type, create)
+{
+}
+
+//\[banner "choice type"]-----------------------------------------------------------------------------------------------------------
+AsnChoiceTypeDesc::AsnChoiceTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnChoiceMemberDesc *_members):
+  AsnMembersTypeDesc (module, name, ispdu, type, create),
+  members (_members)
+{
+}
+
+int AsnChoiceTypeDesc::choicebyname (const char *name) const
+{
+  for (int m=0; members[m].name; m++)
+    if (!strcmp (members[m].name, name))
+      return m;
+
+  return -1;
+}
+
+const char *AsnChoiceTypeDesc::choicebyvalue (int value) const
+{
+  return members[value].name;
+}
+
+//\[banner "set/sequence type"]-----------------------------------------------------------------------------------------------------
+AsnSe_TypeDesc::AsnSe_TypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnSe_MemberDesc *_members):
+  AsnMembersTypeDesc (module, name, ispdu, type, create),
+  members (_members)
+{
+}
+
+//\[banner "list type"]-------------------------------------------------------------------------------------------------------------
+AsnListTypeDesc::AsnListTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnTypeDesc *_base):
+  AsnTypeDesc (module, name, ispdu, type, create),
+  base (_base)
+{
+}
+
+//\[banner "alias type"]------------------------------------------------------------------------------------------------------------
+AsnAliasTypeDesc::AsnAliasTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnTypeDesc *_alias):
+  AsnTypeDesc (module, name, ispdu, type, create),
+  alias (_alias)
+{
+}
+
+const AsnModuleDesc *AsnAliasTypeDesc::getmodule() const
+{
+  return module;
+}
+
+const char *AsnAliasTypeDesc::getname() const
+{
+  return name;
+}
+
+bool AsnAliasTypeDesc::ispdu() const
+{
+  return pdu;
+}
+
+AsnTypeDesc::Type AsnAliasTypeDesc::gettype() const
+{
+  return alias->gettype();
+}
+
+const AsnNameDesc *AsnAliasTypeDesc::getnames() const
+{
+  return alias->getnames();
+}
+
+//const AsnMemberDesc *AsnAliasTypeDesc::getmembers() const
+//{
+  //return alias->getmembers();
+//}
+
+//\[banner "Tcl routines"]----------------------------------------------------------------------------------------------------------
+#if TCL
+
+int AsnTypeDesc::TclGetDesc (Tcl_DString *desc) const
+{
+  Tcl_DStringStartSublist (desc);
+  Tcl_DStringAppendElement (desc, getmodule() ? (char*) getmodule()->name : "");
+  Tcl_DStringAppendElement (desc, getname() ? (char*) getname() : "");
+  Tcl_DStringEndSublist (desc);
+  Tcl_DStringAppendElement (desc, ispdu() ? "pdu" : "sub");
+  Tcl_DStringAppendElement (desc, (char*) typenames[gettype()]);
+
+  return TCL_OK;
+}
+
+int AsnTypeDesc::TclGetDesc2 (Tcl_DString *desc) const
+{
+  return TCL_OK;
+}
+
+int AsnNamesTypeDesc::TclGetDesc (Tcl_DString *desc) const
+{
+  AsnTypeDesc::TclGetDesc (desc);
+  return TclGetDesc2 (desc);
+}
+
+// for BIT STRING and INTEGER:
+int AsnNamesTypeDesc::TclGetDesc2 (Tcl_DString *desc) const
+{
+  Tcl_DStringStartSublist (desc);
+  const AsnNameDesc *n;
+  if (n = names)
+    for (; n->name; n++)
+    {
+      Tcl_DStringStartSublist (desc);
+      Tcl_DStringAppendElement (desc, (char*) n->name);
+      char buf[32];
+      sprintf (buf, "%d", n->value);
+      Tcl_DStringAppendElement (desc, buf);
+      Tcl_DStringEndSublist (desc);
+    }
+  Tcl_DStringEndSublist (desc);
+
+  return TCL_OK;
+}
+
+int AsnEnumTypeDesc::TclGetDesc2 (Tcl_DString *desc) const
+{
+  Tcl_DStringStartSublist (desc);
+  const AsnNameDesc *n;
+  if (n = names)
+    for (; n->name; n++)
+      Tcl_DStringAppendElement (desc, (char*) n->name);
+  Tcl_DStringEndSublist (desc);
+
+  return TCL_OK;
+}
+
+int AsnMembersTypeDesc::TclGetDesc (Tcl_DString *desc) const
+{
+  AsnTypeDesc::TclGetDesc (desc);
+  return TclGetDesc2 (desc);
+}
+
+int AsnChoiceTypeDesc::TclGetDesc2 (Tcl_DString *desc) const
+{
+  Tcl_DStringStartSublist (desc);
+  const AsnChoiceMemberDesc *m;
+  if (m = members)
+    for (; m->TclGetDesc (desc) == TCL_OK; m++)
+      ;
+  Tcl_DStringEndSublist (desc);
+
+  return TCL_OK;
+}
+
+int AsnSe_TypeDesc::mandatmemberr (Tcl_Interp *interp, const char *membername) const
+{
+  sprintf (interp->result, "(in type %s.%s:) member %s is mandatory and can't be deleted", getmodule()->name, getname(), membername);
+  Tcl_SetErrorCode (interp, "SNACC", "MANDMEMB", NULL);
+  return TCL_ERROR;
+}
+
+int AsnSe_TypeDesc::TclGetDesc2 (Tcl_DString *desc) const
+{
+  Tcl_DStringStartSublist (desc);
+  const AsnSe_MemberDesc *m;
+  if (m = members)
+    for (; m->TclGetDesc (desc) == TCL_OK; m++)
+      ;
+  Tcl_DStringEndSublist (desc);
+
+  return TCL_OK;
+}
+
+int AsnListTypeDesc::TclGetDesc (Tcl_DString *desc) const
+{
+  AsnTypeDesc::TclGetDesc (desc);
+  return base->AsnTypeDesc::TclGetDesc (desc);
+}
+
+int AsnAliasTypeDesc::TclGetDesc (Tcl_DString *desc) const
+{
+  AsnTypeDesc::TclGetDesc (desc);
+  return alias->TclGetDesc2 (desc);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+// designed to be used with Tcl_SplitList(): argument list that automagically frees itself when it goes out of scope:
+Args::Args()
+{
+  v = NULL;
+}
+
+Args::~Args()
+{
+  if (v)
+    free (v);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+// since Tcl cannot handle binary strings, the following hack is needed:
+
+int debinify (Tcl_Interp *interp, const char *bin, size_t len)
+{
+  char*	str;
+  int	i, o;
+
+#ifndef _IBM_ENC_
+    str = new char[2*len+1];
+#else
+    str = (char *) mem_mgr_ptr->Get (2*len+2);
+#endif /* _IBM_ENC_ */
+
+
+  for (o=i=0; i<len; i++)
+    switch (bin[i])
+    {
+      case '\0':
+	str[o++] = '\\';
+	str[o++] = '0';
+	break;
+      case '\\':
+	str[o++] = '\\';
+	// fall thru
+      default:
+	str[o++] = bin[i];
+    }
+  str[o] = '\0';
+
+  Tcl_SetResult (interp, str, TCL_VOLATILE);
+
+#ifndef _IBM_ENC_
+  delete str;
+#else
+  mem_mgr_ptr->Put ((void*) str);
+#endif /* _IBM_ENC_ */
+
+  return TCL_OK;
+}
+
+int binify (Tcl_Interp *interp, const char *str, char *buf, size_t *len)
+{
+  for (*len=0; *str; )
+    if (*str == '\\')
+      switch (*++str)
+      {
+	case '0':
+	  buf[(*len)++] = '\0';
+	  str++;
+	  break;
+	case '\\':
+	  buf[(*len)++] = *str++;
+	  break;
+	default:
+	  Tcl_AppendResult (interp, "illegal use of '\\' in string value", NULL);
+	  Tcl_SetErrorCode (interp, "SNACC", "ILLESC", NULL);
+	  return TCL_ERROR;
+      }
+    else
+      buf[(*len)++] = *str++;
+
+  return TCL_OK;
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+#endif // TCL
+
+#endif // META
diff --git a/SecuritySNACCRuntime/c++-lib/c++/print.cpp b/SecuritySNACCRuntime/c++-lib/c++/print.cpp
new file mode 100644
index 00000000..ab687f0e
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/print.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/print.C
+//
+// MS 92
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/print.cpp,v 1.4 2001/06/28 22:49:58 mb Exp $
+// $Log: print.cpp,v $
+// Revision 1.4  2001/06/28 22:49:58  mb
+// Saved 4 bytes of data when compiling with -DNDEBUG
+//
+// Revision 1.3  2001/06/27 23:57:50  dmitch
+// Reimplement partial fix for Radar 2664258: Print() routines are now empty stubs in NDEBUG config.
+//
+// Revision 1.2  2001/06/27 23:09:15  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:58  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:36  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:56  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 20:26:09  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/24  20:34:55  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:33  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:22  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:12  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-incl.h"
+
+#ifndef	NDEBUG
+// the generated operator << routines for aggregate types use these globals
+unsigned short int indentG = 0;
+unsigned short int stdIndentG = 4;
+#endif
+
+void
+Indent (ostream &os, unsigned short int i)
+{
+#ifndef	NDEBUG
+  while (i-->0)
+    os <<  ' ';
+#endif	
+}
+
+ostream &operator << (ostream &os, const AsnType &v)
+{
+#ifndef	NDEBUG
+  v.Print (os);
+#endif	
+  return os;
+}
diff --git a/SecuritySNACCRuntime/c++-lib/c++/str-stk.cpp b/SecuritySNACCRuntime/c++-lib/c++/str-stk.cpp
new file mode 100644
index 00000000..b893cb60
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/str-stk.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/str-stk.C
+//
+// MS 92/07/06
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/str-stk.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: str-stk.cpp,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/12/07 22:16:57  dmitch
+// Thread-safe mods: removed global StrStk strStkG.
+//
+//
+// 2000/12/7 dmitch
+// #ifdef'd out strStkG for thread safety
+//
+// Revision 1.1  2000/06/15 18:44:58  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:37  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/06/04 21:43:21  mb
+// Fixed several memory leaks.
+//
+// Revision 1.1  1999/02/25 05:21:57  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 20:26:11  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/24  20:34:57  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:15:22  rj
+// fixed both Copy()'s name and implementation to CopyOut() that always returns the number of bytes copied out instead of 0 in case less than the requested amount is available.
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:24  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:21:13  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#include "asn-config.h"
+#include "str-stk.h"
+
+#ifndef	__APPLE__
+/* clients each have their own for OS X */
+// global for use by AsnBits and AsnOcts
+
+StrStk strStkG (128, 64);
+#endif	/* 0 */
+
+StrStk::StrStk (int stkSize, int growIncrement)
+{
+  stk = new struct Elmt[stkSize];
+  size = stkSize;
+  growSize = growIncrement;
+}
+
+StrStk::~StrStk ()
+{
+  delete stk;
+}
+
+void StrStk::Reset()
+{
+  nextFreeElmt = 0;
+  totalByteLen = 0;
+}
+
+void StrStk::Push (char *str, size_t strLen)
+{
+  if (nextFreeElmt >= size)
+  {
+    struct Elmt *tmpStk;
+    // alloc bigger stack and copy old elmts to it
+    tmpStk = new struct Elmt[size + growSize];
+    for (int i = 0; i < size; i++)
+      tmpStk[i] = stk[i];
+    delete stk;
+    stk = tmpStk;
+    size += growSize;
+  }
+  totalByteLen += strLen;
+  stk[nextFreeElmt].str = str;
+  stk[nextFreeElmt++].len = strLen;
+}
+
+/*
+ * copy string pieces (buffer refs) into single block.
+ * assumes that the buf is at least totalByteLen byte long.
+ */
+void StrStk::CopyOut (char *buf)
+{
+  unsigned long int curr;
+  char *bufCurr;
+
+  bufCurr = buf;
+  for (curr = 0; curr < nextFreeElmt; curr++)
+  {
+      memcpy (bufCurr, stk[curr].str, stk[curr].len);
+      bufCurr += stk[curr].len;
+  }
+}
diff --git a/SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp b/SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp
new file mode 100644
index 00000000..9312f155
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp
@@ -0,0 +1,1103 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/src/tcl-if.C
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/tcl-if.cpp,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: tcl-if.cpp,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.2  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.1  2000/06/15 18:44:58  dmitch
+// These snacc-generated source files are now checked in to allow cross-platform build.
+//
+// Revision 1.2  2000/06/08 20:05:37  dmitch
+// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+//
+// Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/02/26 00:23:41  mb
+// Fixed for Mac OS 8
+//
+// Revision 1.1  1999/02/25 05:21:57  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/28 13:39:47  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.5  1997/01/01 23:24:35  rj
+// `typename' appears to be a reserved word in gcc 2.7, so prefix it with `_'
+//
+// Revision 1.4  1995/09/07  18:57:13  rj
+// duplicate code merged into a new function SnaccTcl::gettypedesc().
+//
+// Revision 1.3  1995/08/17  15:09:09  rj
+// snacced.[hC] renamed to tcl-if.[hC].
+// class SnaccEd renamed to SnaccTcl.
+// set Tcl's errorCode variable.
+//
+// Revision 1.2  1995/07/27  09:53:38  rj
+// comment leader fixed
+//
+// Revision 1.1  1995/07/27  09:52:22  rj
+// new file: tcl interface used by snacced.
+
+#if !defined(macintosh) && !defined(__APPLE__)
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <strstream.h>
+#include <fstream.h>
+#include <string.h>
+
+#include "asn-incl.h"
+
+#if TCL
+
+#ifdef _AIX32
+extern "C" int strncasecmp (const char* s1, const char* s2, size_t number);
+extern "C" int strcasecmp (const char* s1, const char* s2);
+#endif
+
+#include "tcl-if.h"
+#include "init.h"
+
+//\[banner "utility functions"]-----------------------------------------------------------------------------------------------------
+static bool strniabbr (const char *pattern, const char *test, size_t min)
+{
+  register      len;
+
+  if (strlen (pattern)<min)
+    fprintf (stderr, "strniabbr(): strlen (pattern) < min\n");
+  if ((len = strlen (test))<min)
+    return false;
+  return !strncasecmp (pattern, test, len);
+}
+
+//\[banner "ctor & dtor"]-----------------------------------------------------------------------------------------------------------
+ASN1File::ASN1File (const AsnTypeDesc *typedesc)
+{
+  type = typedesc;
+  pdu = type->create();
+  fn = NULL;
+  fd = -1;
+  filesize = 0;
+}
+
+ASN1File::ASN1File (const AsnTypeDesc *typedesc, const char *_fn, int _fd)
+{
+  type = typedesc;
+  pdu = type->create();
+
+  int fnlen = strlen (_fn) + 1;
+  fn = new char [fnlen];
+  memcpy (fn, _fn, fnlen);
+
+  fd = _fd;
+}
+
+ASN1File::~ASN1File()
+{
+  delete pdu;
+  delete fn;
+  if (fd >= 0)
+    close (fd);
+}
+
+bool ASN1File::bad()
+{
+  return fd < 0;
+}
+
+int ASN1File::finfo (Tcl_Interp *interp)
+{
+  Tcl_AppendElement (interp, fn ? fn : "");
+  char *acc = "bad";
+  if (!bad())
+  {
+    int flags;
+    if ((flags = fcntl (fd, F_GETFL)) != -1)
+      switch (flags & O_ACCMODE)
+      {
+	case O_RDONLY:
+	  acc = "ro";
+	  break;
+	case O_WRONLY:
+	  acc = "wo";
+	  break;
+	case O_RDWR:
+	  acc = "rw";
+	  break;
+      }
+  }
+  Tcl_AppendElement (interp, acc);
+
+  return TCL_OK;
+}
+
+int ASN1File::read (Tcl_Interp *interp, const char *rfn)
+{
+  int rfd;
+  TmpFD tmpfd;
+
+  delete pdu;
+  pdu = type->create();
+
+  if (rfn)
+  {
+    if ((rfd = open (rfn, O_RDONLY)) < 0)
+    {
+      Tcl_AppendResult (interp, "can't open \"", rfn, "\": ", Tcl_PosixError (interp), NULL);
+      return TCL_ERROR;
+    }
+    tmpfd = rfd;
+  }
+  else if (fd < 0)
+  {
+    Tcl_AppendResult (interp, "can't read, file is not open", NULL);
+    Tcl_SetErrorCode (interp, "SNACC", "MUSTOPEN", NULL);
+    return TCL_ERROR;
+  }
+  else
+  {
+    rfn = fn;
+    lseek (rfd = fd, 0l, SEEK_SET);
+  }
+
+  struct stat statbuf;
+  if (fstat (rfd, &statbuf))
+  {
+    Tcl_AppendResult (interp, "can't fstat \"", rfn, "\": ", Tcl_PosixError (interp), NULL);
+    return TCL_ERROR;
+  }
+
+  filesize = statbuf.st_size;
+
+  char* buf = new char[filesize];
+  if (::read (rfd, buf, filesize) != filesize)
+  {
+    Tcl_AppendResult (interp, "can't read \"", rfn, "\": ", Tcl_PosixError (interp), NULL);
+    delete buf;
+    return TCL_ERROR;
+  }
+
+  AsnBuf inputBuf;
+  inputBuf.InstallData (buf, filesize);
+
+  size_t decodedLen = 0;
+  jmp_buf env;
+  int eval;
+  if (eval = setjmp (env))
+  {
+    char eno[80];
+    sprintf (eno, "%d", eval);
+    Tcl_AppendResult (interp, "can't decode (error ", eno, ")", NULL);
+    Tcl_SetErrorCode (interp, "SNACC", "DECODE", eno, NULL);
+    delete buf;
+    return TCL_ERROR;
+  }
+  pdu->BDec (inputBuf, decodedLen, env);
+  if (inputBuf.ReadError())
+  {
+    Tcl_AppendResult (interp, "can't decode, out of data", NULL);
+    Tcl_SetErrorCode (interp, "SNACC", "DECODE", "EOBUF", NULL);
+    delete buf;
+    return TCL_ERROR;
+  }
+
+#if DEBUG
+cout << "DECODED:" << endl << *pdu << endl;
+#endif
+
+  if (decodedLen != filesize)
+    sprintf (interp->result, "decoded %d of %d bytes", decodedLen, filesize);
+
+  delete buf;
+  return TCL_OK;
+}
+
+int ASN1File::write (Tcl_Interp *interp, const char *wfn)
+{
+  int wfd;
+  TmpFD tmpfd;
+
+  if (wfn)
+  {
+    if ((wfd = open (wfn, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0)
+    {
+      Tcl_AppendResult (interp, "can't open \"", wfn, "\": ", Tcl_PosixError (interp), NULL);
+      return TCL_ERROR;
+    }
+    tmpfd = wfd;
+  }
+  else if (fd < 0)
+  {
+    Tcl_AppendResult (interp, "can't write, file is not open", NULL);
+    Tcl_SetErrorCode (interp, "SNACC", "MUSTOPEN", NULL);
+    return TCL_ERROR;
+  }
+  else
+  {
+    wfn = fn;
+    int flags;
+    if ((flags = fcntl (fd, F_GETFL)) == -1)
+    {
+      Tcl_AppendResult (interp, "can't fcntl \"", wfn, "\": ", Tcl_PosixError (interp), NULL);
+      return TCL_ERROR;
+    }
+    else
+    {
+      if ((flags & O_ACCMODE) == O_RDONLY)
+      {
+	Tcl_AppendResult (interp, "can't write, file is read only", NULL);
+	Tcl_SetErrorCode (interp, "SNACC", "WRITE", "RDONLY", NULL);
+	return TCL_ERROR;
+      }
+    }
+    lseek (wfd = fd, 0l, SEEK_SET);
+  }
+
+  size_t size = filesize ? filesize : 10240;
+  char *buf;
+  AsnBuf outputBuf;
+  size_t encodedLen;
+  for (;;)
+  {
+    size <<= 1;
+    buf = new char[size];
+    outputBuf.Init (buf, size);
+    outputBuf.ResetInWriteRvsMode();
+    encodedLen = pdu->BEnc (outputBuf);
+    if (!outputBuf.WriteError())
+      break;
+    delete buf;
+  }
+
+  outputBuf.ResetInReadMode();
+  size_t hunklen = 8192;
+  char* hunk = new char[hunklen];
+  for (size_t written=0; written<encodedLen; written+=hunklen)
+  {
+    if (encodedLen-written < hunklen)
+      hunklen = encodedLen - written;
+    outputBuf.CopyOut (hunk, hunklen);
+    if (::write (wfd, hunk, hunklen) != hunklen)
+    {
+      Tcl_AppendResult (interp, "write error on \"", wfn, "\": ", Tcl_PosixError (interp), NULL);
+      delete hunk; // may affect errno
+      delete buf; // may affect errno
+      return TCL_ERROR;
+    }
+  }
+
+  delete hunk;
+  delete buf;
+
+  filesize = encodedLen;
+  if (!wfn)
+    ftruncate (wfd, filesize);
+
+  return TCL_OK;
+}
+
+//\[banner "import & export"]-------------------------------------------------------------------------------------------------------
+int import (Tcl_Interp *interp, int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc import filename\"");
+    return TCL_ERROR;
+  }
+
+  const char *fn = argv[1];
+  int fd;
+  if ((fd = open (fn, O_RDONLY)) < 0)
+  {
+    Tcl_AppendResult (interp, "can't open \"", fn, "\": ", Tcl_PosixError (interp), NULL);
+    return TCL_ERROR;
+  }
+  TmpFD tmpfd (fd);
+
+  struct stat statbuf;
+  if (fstat (fd, &statbuf))
+  {
+    Tcl_AppendResult (interp, "can't fstat \"", fn, "\"'s fd: ", Tcl_PosixError (interp), NULL);
+    return TCL_ERROR;
+  }
+
+  off_t filesize = statbuf.st_size;
+
+  char* ibuf = new char[filesize];
+  if (::read (fd, ibuf, filesize) != filesize)
+  {
+    Tcl_AppendResult (interp, "read error on \"", fn, "\": ", Tcl_PosixError (interp), NULL);
+    delete ibuf;
+    return TCL_ERROR;
+  }
+
+  int result = debinify (interp, ibuf, filesize);
+  delete ibuf;
+  return result;
+}
+
+int export (Tcl_Interp *interp, int argc, char **argv)
+{
+  if (argc != 3)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc export str filename\"");
+    return TCL_ERROR;
+  }
+
+  const char *str = argv[1], *fn = argv[2];
+  char* obuf = new char[strlen (str)]; // the binary buffer is as most as long as the escaped Tcl string.
+  size_t olen;
+  if (binify (interp, str, obuf, &olen) != TCL_OK)
+  {
+    delete obuf;
+    return TCL_ERROR;
+  }
+
+  int fd;
+  if ((fd = open (fn, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0)
+  {
+    Tcl_AppendResult (interp, "can't open \"", fn, "\": ", Tcl_PosixError (interp), NULL);
+    delete obuf;
+    return TCL_ERROR;
+  }
+  TmpFD tmpfd (fd);
+
+  if (::write (fd, obuf, olen) != olen)
+  {
+    Tcl_AppendResult (interp, "write error on \"", fn, "\": ", Tcl_PosixError (interp), NULL);
+    delete obuf;
+    return TCL_ERROR;
+  }
+
+  delete obuf;
+  return TCL_OK;
+}
+
+//\[banner "ctor & dtor"]-----------------------------------------------------------------------------------------------------------
+SnaccTcl::SnaccTcl (Tcl_Interp *i)
+{
+  interp = i;
+
+  Tcl_InitHashTable (&modules, TCL_STRING_KEYS);
+  Tcl_InitHashTable (&types, TCL_STRING_KEYS);
+
+  const AsnModuleDesc **moddesc;
+  for (moddesc=asnModuleDescs; *moddesc; moddesc++)
+  {
+    int created;
+    Tcl_HashEntry *entry = Tcl_CreateHashEntry (&modules, (char*)(*moddesc)->name, &created);
+    assert (created);
+    Tcl_SetHashValue (entry, *moddesc);
+
+    const AsnTypeDesc **typedesc;
+    for (typedesc=(*moddesc)->types; *typedesc; typedesc++)
+    {
+      char buf[1024];
+      sprintf (buf, "%s %s", (*moddesc)->name, (*typedesc)->name);
+      char *_typename = strdup (buf);
+      int created;
+      Tcl_HashEntry *entry = Tcl_CreateHashEntry (&types, _typename, &created);
+      if (!created)
+      {
+	cerr << "fatal error: duplicate type " << _typename << endl;
+	exit (1);
+      }
+      Tcl_SetHashValue (entry, *typedesc);
+    }
+  }
+
+  Tcl_InitHashTable (&files, TCL_STRING_KEYS);
+}
+
+SnaccTcl::~SnaccTcl()
+{
+  Tcl_DeleteHashTable (&files);
+}
+
+//\[banner "utility functions"]-----------------------------------------------------------------------------------------------------
+const AsnTypeDesc *SnaccTcl::gettypedesc (const char *cmdname, const char *_typename)
+{
+  Tcl_HashEntry *typedescentry;
+  if (typedescentry = Tcl_FindHashEntry (&types, (char*)_typename))
+    return (const AsnTypeDesc *)Tcl_GetHashValue (typedescentry);
+  else
+  {
+    Tcl_SetErrorCode (interp, "SNACC", "ILLTYPE", NULL);
+    Tcl_AppendResult (interp, "snacc ", cmdname, ": no type \"", _typename, "\"", NULL);
+    return NULL;
+  }
+}
+
+//\[banner "data manipulation functions"]-------------------------------------------------------------------------------------------
+Tcl_HashEntry *SnaccTcl::create()
+{
+  static unsigned int id;
+  int created;
+  Tcl_HashEntry *entry;
+  do
+  {
+    sprintf (interp->result, "file%u", id++);
+    entry = Tcl_CreateHashEntry (&files, interp->result, &created);
+  }
+  while (!created);
+  return entry;
+}
+
+int SnaccTcl::create (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc create {module type}\"");
+    return TCL_ERROR;
+  }
+
+  const char	*_typename = argv[1];
+  const AsnTypeDesc *typedesc;
+  if (!(typedesc = gettypedesc ("type", _typename)))
+    return TCL_ERROR;
+
+  Tcl_HashEntry *entry = create();
+  ASN1File *file = new ASN1File (typedesc);
+  Tcl_SetHashValue (entry, file);
+
+  return TCL_OK;
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+// snacc open {module type} filename ?flags? ?permissions?
+
+int SnaccTcl::openfile (int argc, char **argv)
+{
+  if (argc < 3 || argc > 5)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc open {module type} filename ?flags? ?permissions?\"");
+    return TCL_ERROR;
+  }
+
+  const char	*_typename = argv[1];
+  const char	*filename = argv[2];
+  bool		rw_spec = false;
+  int		oflags = 0, omode = 0666, fd = -1;
+
+  switch (argc)
+  {
+    case 5:
+      if (Tcl_GetInt (interp, argv[4], &omode))
+	return TCL_ERROR;
+      // \(da fall thru
+    case 4:
+      {
+	Args flags;
+	if (Tcl_SplitList (interp, argv[3], &flags.c, &flags.v) != TCL_OK)
+	  return TCL_ERROR;
+
+	for (int i=0; i<flags.c; i++)
+	{
+	  if (strniabbr ("truncate", flags.v[i], 1))
+	    oflags |= O_TRUNC;
+	  else if (strniabbr ("create", flags.v[i], 1))
+	    oflags |= O_CREAT;
+	  else if (!strcasecmp ("ro", flags.v[i]))
+	  {
+	    oflags |= O_RDONLY;
+	    rw_spec = true;
+	  }
+	  else if (!strcasecmp ("rw", flags.v[i]))
+	  {
+	    oflags |= O_RDWR;
+	    rw_spec = true;
+	  }
+	  else
+	  {
+	    Tcl_AppendResult (interp, "snacc open: illegal argument \"", flags.v[i], "\" in flags", NULL);
+	    return TCL_ERROR;
+	  }
+	}
+      }
+      break;
+  }
+
+  const AsnTypeDesc *typedesc;
+  if (!(typedesc = gettypedesc ("open", _typename)))
+    return TCL_ERROR;
+
+  if (rw_spec)
+    fd = open (filename, oflags, omode);
+  else
+    if ((fd = open (filename, oflags | O_RDWR, omode)) < 0)
+      fd = open (filename, oflags | O_RDONLY, omode);
+
+  if (fd < 0)
+  {
+    Tcl_AppendResult (interp, "can't open \"", filename, "\": ", Tcl_PosixError (interp), NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = new ASN1File (typedesc, filename, fd);
+  if (file->bad())
+  {
+    delete file;
+    Tcl_AppendResult (interp, "internal error on \"", filename, "\": bad status", NULL);
+    Tcl_SetErrorCode (interp, "SNACC", "OPEN", "BAD", NULL);
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = create();
+  Tcl_SetHashValue (entry, file);
+
+  return file->read (interp);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::finfo (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc finfo file\"");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, argv[1]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "no file named \"", argv[1], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+
+  return file->finfo (interp);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+// snacc read file ?{module type} filename?
+
+int SnaccTcl::read (int argc, char **argv)
+{
+  const char	*_typename, *filename;
+
+  switch (argc)
+  {
+    case 2: // reread from old fd
+      _typename = filename = NULL;
+      break;
+    case 4:
+      _typename = argv[2];
+      filename = argv[3];
+      break;
+    default:
+      strcpy (interp->result, "wrong # args: should be \"snacc read file ?{module type} filename?\"");
+      return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, argv[1]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "no file named \"", argv[1], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+
+  if (_typename)
+  {
+    const AsnTypeDesc *typedesc;
+    if (!(typedesc = gettypedesc ("read", _typename)))
+      return TCL_ERROR;
+
+    delete file;
+    file = new ASN1File (typedesc);
+    Tcl_SetHashValue (entry, file);
+  }
+
+  return file->read (interp, filename);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::write (int argc, char **argv)
+{
+  if (argc < 2 || argc > 3)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc write file ?filename?\"");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, argv[1]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "no file named \"", argv[1], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+
+  return file->write (interp, argv[2]);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::closefile (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc close file\"");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, argv[1]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "no file named \"", argv[1], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+  delete file;
+
+  Tcl_DeleteHashEntry (entry);
+
+  return TCL_OK;
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::modulesinfo (int argc, char **argv)
+{
+  if (argc != 1)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc modules\"");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *moduleentry;
+  Tcl_HashSearch hi;
+  for (moduleentry=Tcl_FirstHashEntry (&modules, &hi); moduleentry; moduleentry=Tcl_NextHashEntry (&hi))
+    Tcl_AppendElement (interp, Tcl_GetHashKey (&modules, moduleentry));
+
+  return TCL_OK;
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::typesinfo (int argc, char **argv)
+{
+  switch (argc)
+  {
+    case 1:
+      Tcl_HashEntry *typeentry;
+      Tcl_HashSearch hi;
+      for (typeentry=Tcl_FirstHashEntry (&types, &hi); typeentry; typeentry=Tcl_NextHashEntry (&hi))
+	Tcl_AppendElement (interp, Tcl_GetHashKey (&types, typeentry));
+      return TCL_OK;
+    case 2:
+      Tcl_HashEntry *moduleentry;
+      if (moduleentry = Tcl_FindHashEntry (&modules, argv[1]))
+      {
+	const AsnModuleDesc *moddesc = (const AsnModuleDesc *)Tcl_GetHashValue (moduleentry);
+	const AsnTypeDesc **typedesc;
+	for (typedesc=moddesc->types; *typedesc; typedesc++)
+	  Tcl_AppendElement (interp, (char*)(*typedesc)->name);
+	return TCL_OK;
+      }
+      else
+      {
+	Tcl_AppendResult (interp, "snacc types: no module \"", argv[1], "\"", NULL);
+	return TCL_ERROR;
+      }
+    default:
+      strcpy (interp->result, "wrong # args: should be \"snacc types ?module?\"");
+      return TCL_ERROR;
+  }
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::typeinfo (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc type {module type}\"");
+    return TCL_ERROR;
+  }
+
+  const char	*_typename = argv[1];
+  const AsnTypeDesc *typedesc;
+  if (!(typedesc = gettypedesc ("type", _typename)))
+    return TCL_ERROR;
+
+  Tcl_DString desc;
+  Tcl_DStringInit (&desc);
+  int rc = typedesc->TclGetDesc (&desc);
+  Tcl_DStringResult (interp, &desc);
+  return rc;
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::info (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc info path\"");
+    return TCL_ERROR;
+  }
+
+  Args path;
+  if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK)
+    return TCL_ERROR;
+
+  if (path.c < 1)
+  {
+    strcpy (interp->result, "snacc info: wrong # args in path");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "snacc info: no file named \"", path.v[0], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+
+  AsnType *var = (AsnType *)*file;
+  for (int i=1; i<path.c; i++)
+    if (!(var = var->_getref (path.v[i])))
+    {
+      Tcl_AppendResult (interp, "snacc info: illegal component \"", path.v[i], "\" in path", NULL);
+      return TCL_ERROR;
+    }
+
+  Tcl_DString desc;
+  Tcl_DStringInit (&desc);
+  int rc;
+  if ((rc = var->_getdesc()->AsnTypeDesc::TclGetDesc (&desc)) == TCL_OK)
+    rc = var->TclGetDesc (&desc);
+  Tcl_DStringResult (interp, &desc);
+  return rc;
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::getval (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc get path\"");
+    return TCL_ERROR;
+  }
+
+  Args path;
+  if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK)
+    return TCL_ERROR;
+
+  if (path.c < 1)
+  {
+    strcpy (interp->result, "snacc get: wrong # args in path");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "snacc get: no file named \"", path.v[0], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+
+  AsnType *var = (AsnType *)*file;
+  for (int i=1; i<path.c; i++)
+    if (!(var = var->_getref (path.v[i])))
+    {
+      Tcl_AppendResult (interp, "snacc get: illegal component \"", path.v[i], "\" in path", NULL);
+      return TCL_ERROR;
+    }
+
+  return var->TclGetVal (interp);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::test (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc get path\"");
+    return TCL_ERROR;
+  }
+
+  Args path;
+  if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK)
+    return TCL_ERROR;
+
+  if (path.c < 1)
+  {
+    strcpy (interp->result, "snacc get: wrong # args in path");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "snacc get: no file named \"", path.v[0], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+
+  AsnType *var = (AsnType *)*file;
+  for (int i=1; i<path.c; i++)
+    if (!(var = var->_getref (path.v[i])))
+    {
+      Tcl_AppendResult (interp, "snacc test: illegal component \"", path.v[i], "\" in path", NULL);
+      return TCL_ERROR;
+    }
+
+cout << *var;
+  strstream s;
+  s << *var;
+  s.put ('\0');
+  cout << strlen(s.str()) << endl;
+  cout << s.str() << endl;
+
+  return TCL_OK;
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::setval (int argc, char **argv)
+{
+  if (argc != 3)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc set path value\"");
+    return TCL_ERROR;
+  }
+
+  Args path;
+  if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK)
+    return TCL_ERROR;
+
+  if (path.c < 1)
+  {
+    strcpy (interp->result, "snacc set: wrong # args in path");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "snacc set: no file named \"", path.v[0], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+
+  AsnType *var = (AsnType *)*file;
+  for (int i=1; i<path.c; i++)
+    if (!(var = var->_getref (path.v[i], true)))
+    {
+      Tcl_AppendResult (interp, "snacc set: illegal component \"", path.v[i], "\" in path", NULL);
+      return TCL_ERROR;
+    }
+
+  return var->TclSetVal (interp, argv[2]);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int SnaccTcl::unsetval (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc unset path\"");
+    return TCL_ERROR;
+  }
+
+  Args path;
+  if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK)
+    return TCL_ERROR;
+
+  if (path.c == 1)
+  {
+    strcpy (interp->result, "snacc unset: sorry, but you are not allowed to unset the file itself");
+    return TCL_ERROR;
+  }
+  else if (path.c < 1)
+  {
+    strcpy (interp->result, "snacc unset: wrong # args in path");
+    return TCL_ERROR;
+  }
+
+  Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]);
+  if (!entry)
+  {
+    Tcl_AppendResult (interp, "snacc unset: no file named \"", path.v[0], "\"", NULL);
+    return TCL_ERROR;
+  }
+
+  ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry);
+
+  AsnType *var = (AsnType *)*file;
+  for (int i=1; i<path.c-1; i++)
+  {
+    if (!(var = var->_getref (path.v[i])))
+    {
+      Tcl_AppendResult (interp, "snacc unset: illegal component \"", path.v[i], "\" in path", NULL);
+      return TCL_ERROR;
+    }
+  }
+
+  return var->TclUnsetVal (interp, path.v[path.c-1]);
+}
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+int Snacc_Cmd (ClientData cd, Tcl_Interp *interp, int argc, char **argv)
+{
+  SnaccTcl *ed = (SnaccTcl *)cd;
+
+#ifdef DEBUG
+  ed->ckip (interp);
+#endif
+
+  if (argc < 2)
+  {
+    strcpy (interp->result, "wrong # args: should be \"snacc option arg ?arg ...?\"");
+    return TCL_ERROR;
+  }
+  --argc;
+  argv++;
+
+  switch (**argv)
+  {
+    case 'c':
+      if (!strcmp (*argv, "close"))
+	return ed->closefile (argc, argv);
+      else if (!strcmp (*argv, "create"))
+	return ed->create (argc, argv);
+      break;
+    case 'e':
+      if (!strcmp (*argv, "export"))
+	return export (interp, argc, argv);
+      break;
+    case 'f':
+      if (!strcmp (*argv, "finfo"))
+	return ed->finfo (argc, argv);
+      break;
+    case 'g':
+      if (!strcmp (*argv, "get"))
+	return ed->getval (argc, argv);
+      break;
+    case 'i':
+      if (!strcmp (*argv, "import"))
+	return import (interp, argc, argv);
+      else if (!strcmp (*argv, "info"))
+	return ed->info (argc, argv);
+      break;
+    case 'm':
+      if (!strcmp (*argv, "modules"))
+	return ed->modulesinfo (argc, argv);
+      break;
+    case 'o':
+      if (!strcmp (*argv, "open"))
+	return ed->openfile (argc, argv);
+      break;
+    case 'r':
+      if (!strcmp (*argv, "read"))
+	return ed->read (argc, argv);
+      break;
+    case 's':
+      if (!strcmp (*argv, "set"))
+	return ed->setval (argc, argv);
+      break;
+    case 't':
+      if (!strcmp (*argv, "test"))
+	return ed->test (argc, argv);
+      else if (!strcmp (*argv, "type"))
+	return ed->typeinfo (argc, argv);
+      else if (!strcmp (*argv, "types"))
+	return ed->typesinfo (argc, argv);
+      break;
+    case 'u':
+      if (!strcmp (*argv, "unset"))
+	return ed->unsetval (argc, argv);
+      break;
+    case 'w':
+      if (!strcmp (*argv, "write"))
+	return ed->write (argc, argv);
+      break;
+  }
+  sprintf (interp->result, "bad command option %s: should be close, create, export, finfo, get, import, info, modules, open, read, set, type, types, unset or write", *argv);
+
+  return TCL_ERROR;
+}
+
+//\[banner "check for proper initialization & finalization"]------------------------------------------------------------------------
+
+struct check
+{
+  int	i, j;
+
+	check (int);
+
+  bool	bad();
+};
+
+static int cki;
+
+check::check (int v)
+{
+  i = v;
+  j = ~i;
+}
+
+#define CK	42
+
+bool check::bad()
+{
+  return i != CK || j != ~CK;
+}
+
+check	check (CK);
+
+//\[banner "initialization & finalization"]-----------------------------------------------------------------------------------------
+void Snacc_Exit (ClientData data)
+{
+  delete (SnaccTcl *)data;
+}
+
+// prohibit function name mangling to enable tkAppInit.c:Tcl_AppInit() to call this function:
+extern "C" int Snacc_Init (Tcl_Interp *interp)
+{
+  if (check.bad())
+  {
+    static const char emsg[] = "linkage error, constructors of static variables didn't get called!\n";
+    write (2, emsg, sizeof emsg);
+    exit (1);
+  }
+
+  SnaccTcl *data = new SnaccTcl (interp);
+  Tcl_CreateCommand (interp, "snacc", Snacc_Cmd, (ClientData)data, Snacc_Exit);
+  return TCL_OK;
+}
+
+#endif // TCL
diff --git a/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c b/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c
new file mode 100644
index 00000000..916f1f45
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * snacced -	Snacc_Init added to the default tkXAppInit.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+ * $Log: tkAppInit.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:06  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.3  2001/05/05 00:59:17  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.2  2000/06/15 18:44:59  dmitch
+ * These snacc-generated source files are now checked in to allow cross-platform build.
+ *
+ * Revision 1.2  2000/06/08 20:05:37  dmitch
+ * Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+ *
+ * Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+ * Base Fortissimo Tree
+ *
+ * Revision 1.1  1999/02/25 05:21:58  mb
+ * Added snacc c++ library
+ *
+ * Revision 1.2  1997/02/28 13:39:48  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.1  1997/01/02 09:07:59  rj
+ * first check-in
+ *
+ */
+
+#ifndef	__APPLE__
+/* I don't know why this gets configd to build but we don't have tk.h */
+
+#include "snacc.h"
+
+#if TCL
+
+/* 
+ * tkXAppInit.c --
+ *
+ *      Provides a default version of the TclX_AppInit procedure for use with
+ *      applications built with Extended Tcl and Tk.  This is based on the
+ *      the UCB Tk file tkAppInit.c
+ *
+ *-----------------------------------------------------------------------------
+ * Copyright 1991-1993 Karl Lehenbauer and Mark Diekhans.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies.  Karl Lehenbauer and
+ * Mark Diekhans make no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ *-----------------------------------------------------------------------------
+ * $Id: tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+ *-----------------------------------------------------------------------------
+ * Copyright (c) 1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef lint
+static char rcsid[] = "$Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $ SPRITE (Berkeley)";
+#endif /* not lint */
+
+#include <tk.h>
+
+#include "init.h"
+
+int
+main(argc, argv)
+    int argc;                   /* Number of command-line arguments. */
+    char **argv;                /* Values of command-line arguments. */
+{
+    Tk_Main(argc, argv, Tcl_AppInit);
+    return 0;                   /* Needed only to prevent compiler warning. */
+}
+
+int
+Tcl_AppInit (interp)
+    Tcl_Interp *interp;		/* Interpreter for application. */
+{
+    if (Tcl_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+    if (Tk_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+    Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
+
+    if (Snacc_Init (interp) == TCL_ERROR)
+	return TCL_ERROR;
+
+    if (Tree_Init (interp) == TCL_ERROR)
+	return TCL_ERROR;
+
+    Tcl_SetVar (interp, "tcl_rcFileName", "~/.snaccedrc", TCL_GLOBAL_ONLY);
+
+    return TCL_OK;
+}
+
+#endif
+
+#endif	// Apple
diff --git a/SecuritySNACCRuntime/c++-lib/dependencies b/SecuritySNACCRuntime/c++-lib/dependencies
new file mode 100644
index 00000000..bc4a7f58
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/dependencies
@@ -0,0 +1,792 @@
+c++/asn-any.o: src/asn-any.cpp inc/asn-incl.h inc/asn-config.h \
+ /usr/include/ctype.h /usr/include/runetype.h \
+ /usr/include/machine/ansi.h /usr/include/ppc/ansi.h \
+ /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-int.h \
+ inc/asn-bool.h inc/asn-real.h inc/asn-oid.h inc/asn-octs.h \
+ inc/asn-bits.h inc/str-stk.h inc/asn-enum.h inc/asn-null.h \
+ inc/asn-any.h inc/hash.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/threading.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utilities.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssm.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmconfig.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/MacTypes.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/emmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapi.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmerr.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapple.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utility_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../assert.h \
+ /usr/include/gcc/darwin/2.95.2/g++/exception \
+ /usr/include/gcc/darwin/2.95.2/g++/new \
+ /usr/include/gcc/darwin/2.95.2/g++/string \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cstddef \
+ /usr/include/gcc/darwin/2.95.2/g++/std/straits.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cctype \
+ /usr/include/gcc/darwin/2.95.2/g++/cstring \
+ /usr/include/gcc/darwin/2.95.2/g++/alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iterator \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_relops.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_iterator.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cassert \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.cc \
+ /usr/include/errno.h /usr/include/sys/errno.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread_impl.h \
+ /System/Library/Frameworks/System.framework/Headers/sched.h \
+ /usr/include/time.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h \
+ /usr/include/ppc/limits.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/mach_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/host_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_statistics.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/time_value.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/memory_object_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/port.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/exception_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/policy.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/clock_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_attributes.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_inherit.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_behavior.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_prot.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_sync.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_region.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/prof_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kmod.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/std_types.h \
+ /usr/include/limits.h /usr/include/sys/syslimits.h \
+ /usr/include/sys/time.h inc/asn-useful.h inc/print.h \
+ inc/sm_vdasnacc.h
+c++/asn-bits.o: src/asn-bits.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-bits.h \
+ inc/str-stk.h
+c++/asn-bool.o: src/asn-bool.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-bool.h
+c++/asn-enum.o: src/asn-enum.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-int.h \
+ inc/asn-enum.h
+c++/asn-int.o: src/asn-int.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-int.h
+c++/asn-len.o: src/asn-len.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h
+c++/asn-list.o: src/asn-list.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-list.h
+c++/asn-null.o: src/asn-null.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-null.h
+c++/asn-octs.o: src/asn-octs.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-bits.h \
+ inc/str-stk.h inc/asn-octs.h
+c++/asn-oid.o: src/asn-oid.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/strstream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/strfile.h inc/asn-len.h \
+ inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-oid.h \
+ inc/print.h
+c++/asn-real.o: src/asn-real.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-real.h
+c++/asn-tag.o: src/asn-tag.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h
+c++/asn-type.o: src/asn-type.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h
+c++/hash.o: src/hash.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/hash.h
+c++/meta.o: src/meta.cpp inc/asn-incl.h inc/asn-config.h \
+ /usr/include/ctype.h /usr/include/runetype.h \
+ /usr/include/machine/ansi.h /usr/include/ppc/ansi.h \
+ /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-int.h \
+ inc/asn-bool.h inc/asn-real.h inc/asn-oid.h inc/asn-octs.h \
+ inc/asn-bits.h inc/str-stk.h inc/asn-enum.h inc/asn-null.h \
+ inc/asn-any.h inc/hash.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/threading.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utilities.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssm.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmconfig.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/MacTypes.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/emmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapi.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmerr.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapple.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utility_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../assert.h \
+ /usr/include/gcc/darwin/2.95.2/g++/exception \
+ /usr/include/gcc/darwin/2.95.2/g++/new \
+ /usr/include/gcc/darwin/2.95.2/g++/string \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cstddef \
+ /usr/include/gcc/darwin/2.95.2/g++/std/straits.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cctype \
+ /usr/include/gcc/darwin/2.95.2/g++/cstring \
+ /usr/include/gcc/darwin/2.95.2/g++/alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iterator \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_relops.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_iterator.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cassert \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.cc \
+ /usr/include/errno.h /usr/include/sys/errno.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread_impl.h \
+ /System/Library/Frameworks/System.framework/Headers/sched.h \
+ /usr/include/time.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h \
+ /usr/include/ppc/limits.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/mach_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/host_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_statistics.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/time_value.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/memory_object_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/port.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/exception_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/policy.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/clock_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_attributes.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_inherit.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_behavior.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_prot.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_sync.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_region.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/prof_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kmod.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/std_types.h \
+ /usr/include/limits.h /usr/include/sys/syslimits.h \
+ /usr/include/sys/time.h inc/asn-useful.h inc/print.h
+c++/print.o: src/print.cpp inc/asn-incl.h inc/asn-config.h \
+ /usr/include/ctype.h /usr/include/runetype.h \
+ /usr/include/machine/ansi.h /usr/include/ppc/ansi.h \
+ /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-int.h \
+ inc/asn-bool.h inc/asn-real.h inc/asn-oid.h inc/asn-octs.h \
+ inc/asn-bits.h inc/str-stk.h inc/asn-enum.h inc/asn-null.h \
+ inc/asn-any.h inc/hash.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/threading.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utilities.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssm.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmconfig.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/MacTypes.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/emmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapi.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmerr.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapple.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utility_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../assert.h \
+ /usr/include/gcc/darwin/2.95.2/g++/exception \
+ /usr/include/gcc/darwin/2.95.2/g++/new \
+ /usr/include/gcc/darwin/2.95.2/g++/string \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cstddef \
+ /usr/include/gcc/darwin/2.95.2/g++/std/straits.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cctype \
+ /usr/include/gcc/darwin/2.95.2/g++/cstring \
+ /usr/include/gcc/darwin/2.95.2/g++/alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iterator \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_relops.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_iterator.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cassert \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.cc \
+ /usr/include/errno.h /usr/include/sys/errno.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread_impl.h \
+ /System/Library/Frameworks/System.framework/Headers/sched.h \
+ /usr/include/time.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h \
+ /usr/include/ppc/limits.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/mach_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/host_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_statistics.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/time_value.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/memory_object_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/port.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/exception_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/policy.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/clock_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_attributes.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_inherit.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_behavior.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_prot.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_sync.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_region.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/prof_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kmod.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/std_types.h \
+ /usr/include/limits.h /usr/include/sys/syslimits.h \
+ /usr/include/sys/time.h inc/asn-useful.h inc/print.h
+c++/tcl-if.o: src/tcl-if.cpp /usr/include/fcntl.h /usr/include/sys/fcntl.h \
+ /usr/include/sys/types.h /usr/include/sys/cdefs.h \
+ /usr/include/machine/types.h /usr/include/ppc/types.h \
+ /usr/include/machine/ansi.h /usr/include/ppc/ansi.h \
+ /usr/include/machine/endian.h /usr/include/ppc/endian.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../assert.h /usr/include/unistd.h \
+ /usr/include/sys/unistd.h /usr/include/signal.h \
+ /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/ppc/signal.h /usr/include/stdlib.h \
+ /usr/include/gcc/darwin/2.95.2/g++/strstream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h /usr/include/stddef.h \
+ /usr/include/stdio.h /usr/include/gcc/darwin/2.95.2/g++/strfile.h \
+ /usr/include/gcc/darwin/2.95.2/g++/fstream.h /usr/include/string.h \
+ inc/asn-incl.h inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/memory.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/math.h inc/snacc.h inc/config.h inc/policy.h \
+ inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h inc/asn-int.h inc/asn-bool.h inc/asn-real.h inc/asn-oid.h \
+ inc/asn-octs.h inc/asn-bits.h inc/str-stk.h inc/asn-enum.h \
+ inc/asn-null.h inc/asn-any.h inc/hash.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/threading.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utilities.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssm.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmconfig.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/MacTypes.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/emmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapi.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmerr.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapple.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utility_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/exception \
+ /usr/include/gcc/darwin/2.95.2/g++/new \
+ /usr/include/gcc/darwin/2.95.2/g++/string \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cstddef \
+ /usr/include/gcc/darwin/2.95.2/g++/std/straits.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cctype \
+ /usr/include/gcc/darwin/2.95.2/g++/cstring \
+ /usr/include/gcc/darwin/2.95.2/g++/alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iterator \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_relops.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_iterator.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cassert \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.cc \
+ /usr/include/errno.h /usr/include/sys/errno.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread_impl.h \
+ /System/Library/Frameworks/System.framework/Headers/sched.h \
+ /usr/include/time.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h \
+ /usr/include/ppc/limits.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/mach_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/host_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_statistics.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/time_value.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/memory_object_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/port.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/exception_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/policy.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/clock_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_attributes.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_inherit.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_behavior.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_prot.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_sync.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_region.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/prof_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kmod.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/std_types.h \
+ /usr/include/limits.h /usr/include/sys/syslimits.h \
+ /usr/include/sys/time.h inc/asn-useful.h inc/print.h inc/tcl-if.h \
+ inc/init.h
+c++/str-stk.o: src/str-stk.cpp inc/asn-config.h /usr/include/ctype.h \
+ /usr/include/runetype.h /usr/include/machine/ansi.h \
+ /usr/include/ppc/ansi.h /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/str-stk.h
+tkAppInit.o : 
+c++/asn-useful.o: src/asn-useful.cpp inc/asn-incl.h inc/asn-config.h \
+ /usr/include/ctype.h /usr/include/runetype.h \
+ /usr/include/machine/ansi.h /usr/include/ppc/ansi.h \
+ /usr/include/sys/cdefs.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iostream.h \
+ /usr/include/gcc/darwin/2.95.2/g++/streambuf.h \
+ /usr/include/gcc/darwin/2.95.2/g++/libio.h \
+ /usr/include/gcc/darwin/2.95.2/g++/_G_config.h \
+ /usr/include/sys/types.h /usr/include/machine/types.h \
+ /usr/include/ppc/types.h /usr/include/machine/endian.h \
+ /usr/include/ppc/endian.h /usr/include/stddef.h /usr/include/stdio.h \
+ /usr/include/memory.h /usr/include/string.h /usr/include/setjmp.h \
+ /usr/include/machine/setjmp.h /usr/include/ppc/setjmp.h \
+ /usr/include/machine/signal.h /usr/include/ppc/signal.h \
+ /usr/include/math.h inc/snacc.h inc/config.h /usr/include/stdlib.h \
+ inc/policy.h inc/asn-buf.h inc/asn-len.h inc/asn-tag.h inc/asn-type.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tcl.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../stdarg.h \
+ /System/Library/Frameworks/Tcl.framework/Headers/tclDecls.h \
+ inc/meta.h /usr/include/unistd.h /usr/include/sys/unistd.h \
+ /usr/include/signal.h /usr/include/sys/signal.h inc/asn-int.h \
+ inc/asn-bool.h inc/asn-real.h inc/asn-oid.h inc/asn-octs.h \
+ inc/asn-bits.h inc/str-stk.h inc/asn-enum.h inc/asn-null.h \
+ inc/asn-any.h inc/hash.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/threading.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utilities.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssm.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmconfig.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h \
+ /System/Library/Frameworks/CarbonCore.framework/Headers/MacTypes.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/emmtype.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapi.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmerr.h \
+ /System/Library/PrivateFrameworks/cdsa.framework/Headers/cssmapple.h \
+ /System/Library/PrivateFrameworks/cdsa_utilities.framework/Headers/utility_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../assert.h \
+ /usr/include/gcc/darwin/2.95.2/g++/exception \
+ /usr/include/gcc/darwin/2.95.2/g++/new \
+ /usr/include/gcc/darwin/2.95.2/g++/string \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cstddef \
+ /usr/include/gcc/darwin/2.95.2/g++/std/straits.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cctype \
+ /usr/include/gcc/darwin/2.95.2/g++/cstring \
+ /usr/include/gcc/darwin/2.95.2/g++/alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_config.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_alloc.h \
+ /usr/include/gcc/darwin/2.95.2/g++/iterator \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_relops.h \
+ /usr/include/gcc/darwin/2.95.2/g++/stl_iterator.h \
+ /usr/include/gcc/darwin/2.95.2/g++/cassert \
+ /usr/include/gcc/darwin/2.95.2/g++/std/bastring.cc \
+ /usr/include/errno.h /usr/include/sys/errno.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread.h \
+ /System/Library/Frameworks/System.framework/Headers/pthread_impl.h \
+ /System/Library/Frameworks/System.framework/Headers/sched.h \
+ /usr/include/time.h \
+ /usr/include/gcc/darwin/2.95.2/g++/../machine/limits.h \
+ /usr/include/ppc/limits.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/mach_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/host_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_statistics.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/boolean.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/time_value.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/memory_object_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/port.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/exception_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_status.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/thread_state.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/exception.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/processor_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/policy.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/task_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_info.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/thread_special_ports.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/clock_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_attributes.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_inherit.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_behavior.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_prot.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_sync.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/vm_region.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/prof_types.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kmod.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/machine/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/ppc/kern_return.h \
+ /System/Library/Frameworks/System.framework/Headers/mach/std_types.h \
+ /usr/include/limits.h /usr/include/sys/syslimits.h \
+ /usr/include/sys/time.h inc/asn-useful.h inc/print.h
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-any.h b/SecuritySNACCRuntime/c++-lib/inc/asn-any.h
new file mode 100644
index 00000000..639e93f0
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-any.h
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-any.h - C++ class for any type
+//
+// MS 92
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//
+// ------------------------------------------------------------------------
+// -  J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3  -
+// ------------------------------------------------------------------------
+// 
+// All modification are relative to the v1.3 of SNACC.  We used SunOS 4.1.3's 
+// SCCS.  The revision #'s start at 1.1,  which is the original version from 
+// SNACC 1.3.
+// 
+// 
+// ../SCCS/s.asn-any.h:
+// 
+// D 1.2	98/05/01 13:46:36 pleonber	2 1	00008/00000/00099
+// added destructor and copy for CSM_Buffer handling (cleans up memory).
+// 
+// D 1.1	98/05/01 13:16:05 pleonber	1 0	00099/00000/00000
+// date and time created 98/05/01 13:16:05 by pleonber
+// 
+// ----------------------- End of VDA Modifications ---------------------------
+// 
+// 
+// 
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-any.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-any.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.5  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.4  2000/12/22 20:33:26  mb
+// New Security framework fase 1 complete.
+//
+// Revision 1.3  2000/12/07 22:14:38  dmitch
+// Thread-safe mods: made oidHashTbl and intHashTbl private.
+//
+// Revision 1.2  2000/06/15 18:48:25  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.4  1999/03/21 02:07:31  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.3  1999/03/18 22:35:26  mb
+// Made all destructors virtual.
+//
+// Revision 1.2  1999/02/26 00:32:55  mb
+// Fix bug when not building with VDADER_RULES defined.
+//
+// Revision 1.1  1999/02/25 05:21:40  mb
+// Added snacc c++ library
+//
+// Revision 1.4  1997/01/02 08:39:42  rj
+// missing prototype added
+//
+// Revision 1.3  1994/10/08  04:17:56  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:43  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:24  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_any_h_
+#define _asn_any_h_
+
+#ifdef _IBM_ENC_
+#include "shmmgr.h"   // Guido Grassel 4.8.93
+#endif /* _IBM_ENC_ */
+
+#include "hash.h"
+
+#ifdef	__APPLE__
+#include <Security/threading.h>	/* for Mutex */
+#endif
+
+/* this is put into the hash table with the int or oid as the key */
+#ifndef _IBM_ENC_
+class AnyInfo
+#else
+class AnyInfo: public MemMgr   // Guido Grassel 4.8.93
+#endif /* _IBM_ENC_ */
+{
+public:
+  int				anyId;	// will be a value from the AnyId enum
+  AsnOid			oid;	// will be zero len/null if intId is valid
+  AsnInt			intId;
+  AsnType			*typeToClone;
+};
+
+#if	defined(macintosh) || defined(__APPLE__)
+class CSM_Buffer;
+#endif
+
+class AsnAny: public AsnType
+{
+#ifdef	__APPLE__
+/* need a lock to protect these, declared as a static in the .cpp file.
+ *...plus, I have no idea why these
+ * were declared public. They are not used anywhere else.
+ */
+private:
+  static Table			*oidHashTbl;	// all AsnAny class instances
+  static Table			*intHashTbl;	// share these tables
+public:
+#else
+public:
+  static Table			*oidHashTbl;	// all AsnAny class instances
+  static Table			*intHashTbl;	// share these tables
+#endif
+  AnyInfo			*ai;		// points to entry in hash tbl for this type
+#if	defined(macintosh) || defined(__APPLE__)
+// FIXME - needs work
+  CSM_Buffer		*value;
+#else
+  AsnType			*value;
+#endif
+				AsnAny()				{ ai = NULL; value = NULL; }
+
+  // class level methods
+  static void			InstallAnyByInt (AsnInt intId, int anyId, AsnType *type);
+  static void			InstallAnyByOid (AsnOid &oid,  int anyId, AsnType *type);
+
+  int				GetId()	const				{ return ai ? ai->anyId : -1; }
+  void				SetTypeByInt (AsnInt id);
+  void				SetTypeByOid (AsnOid &id);
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+  void				Print (ostream &) const;
+
+#if 0
+#if TCL
+  int				TclGetDesc (Tcl_DString *) const;
+  int				TclGetVal (Tcl_DString *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+  int				TclUnSetVal (Tcl_Interp *, const char *member);
+#endif /* TCL */
+#endif
+
+#ifdef VDADER_RULES
+  virtual		~AsnAny();
+				AsnAny &operator = (const AsnAny &o);  
+};
+
+// AnyDefinedBy is currently the same as AsnAny:
+typedef AsnAny			AsnAnyDefinedBy;
+
+#else
+};
+#endif /* _conditional_include_ */
+
+#endif /* _asn_any_h_ */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-bits.h b/SecuritySNACCRuntime/c++-lib/inc/asn-bits.h
new file mode 100644
index 00000000..db72567f
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-bits.h
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-bits.h - ASN.1 BIT STRING type
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-bits.h,v 1.2 2001/06/28 23:36:11 dmitch Exp $
+// $Log: asn-bits.h,v $
+// Revision 1.2  2001/06/28 23:36:11  dmitch
+// Removed SccsId statics. numToHexCharTblG table now const. Radar 2705410.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.5  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.4  2000/12/07 22:29:50  dmitch
+// Thread-safe mods: added strStkG, strStkUnusedBitsG arguments to FillBitStringStk .
+//
+// Revision 1.3  2000/08/24 20:00:25  dmitch
+// Added BitOcts() accessor.
+//
+// Revision 1.2  2000/06/15 18:48:22  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// 2000/8/24 dmitch at Apple
+// Added BitOcts() accessor.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.3  1999/03/21 02:07:31  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.2  1999/03/18 22:35:27  mb
+// Made all destructors virtual.
+//
+// Revision 1.1  1999/02/25 05:21:40  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/16 20:25:33  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.5  1995/07/24  17:53:51  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1995/02/18  19:26:18  rj
+// remove const from arguments that are passed by value.
+//
+// Revision 1.3  1994/10/08  04:17:57  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:44  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:25  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_bits_h_
+#define _asn_bits_h_
+
+#ifdef	__APPLE__
+#include "str-stk.h"
+#endif
+
+extern const char	numToHexCharTblG[];
+
+#define TO_HEX( fourBits)	(numToHexCharTblG[(fourBits) & 0x0F])
+
+class AsnBits: public AsnType
+{
+private:
+  bool				BitsEquiv (const AsnBits &ab) const;
+  void				BDecConsBits (BUF_TYPE b, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  #ifdef	__APPLE__
+  void				FillBitStringStk (BUF_TYPE b, AsnLen elmtLen0, 
+			AsnLen &bytesDecoded, ENV_TYPE env,
+			StrStk &strStkG, unsigned short int  &strStkUnusedBitsG);
+  #else
+  void				FillBitStringStk (BUF_TYPE b, AsnLen elmtLen0, 
+			AsnLen &bytesDecoded, ENV_TYPE env);
+  #endif
+
+protected:
+  size_t			bitLen;
+  char				*bits;
+
+public:
+
+				AsnBits()				{ bits = NULL; bitLen = 0; }
+				AsnBits (size_t numBits)		{ Set (numBits); }
+				AsnBits (const char *bitOcts, size_t numBits)
+									{ Set (bitOcts, numBits); }
+				AsnBits (const AsnBits &b)		{ Set (b); }
+#ifndef _IBM_ENC_
+  virtual		~AsnBits();
+#else
+  virtual		~AsnBits()				{ mem_mgr_ptr->Put ((void *) bits); } // Guido Grassel, 11.8.93
+#endif /* _IBM_ENC_ */
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+  AsnBits			&operator = (const AsnBits &b)		{ ReSet (b); return *this; }
+
+  // overwrite existing bits and bitLen values
+  void				Set (size_t numBits);
+  void				Set (const char *bitOcts, size_t numBits);
+  void				Set (const AsnBits &b);
+
+  // free old bits value, the reset bits and bitLen values
+  void				ReSet (size_t numBits);
+  void				ReSet (const char *bitOcts, size_t numBits);
+  void				ReSet (const AsnBits &b);
+
+  bool				operator == (const AsnBits &ab) const	{ return BitsEquiv (ab); }
+  bool				operator != (const AsnBits &ab) const	{ return !BitsEquiv (ab); }
+
+  void				SetBit (size_t);
+  void				ClrBit (size_t);
+  bool				GetBit (size_t) const;
+
+  // Apple addenda: this is just too useful to exclude. 
+  const char		*BitOcts() const { return bits; }
+
+  size_t			BitLen() const				{ return bitLen; }
+
+  AsnLen			BEncContent (BUF_TYPE b);
+  void				BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+  void				Print (ostream &) const;
+
+#if META
+  static const AsnBitsTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif /* TCL */
+#endif /* META */
+};
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-bool.h b/SecuritySNACCRuntime/c++-lib/inc/asn-bool.h
new file mode 100644
index 00000000..dfb54036
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-bool.h
@@ -0,0 +1,177 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-bool.h  - c++ version of ASN.1 integer
+//
+// MS 92/06/15
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//
+// ------------------------------------------------------------------------
+// -  J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3  -
+// ------------------------------------------------------------------------
+// 
+// All modification are relative to the v1.3 of SNACC.  We used SunOS 4.1.3's 
+// SCCS.  The revision #'s start at 1.1,  which is the original version from 
+// SNACC 1.3.
+// 
+// 
+// ../SCCS/s.asn-bool.h:
+// 
+// D 1.2	98/04/24 22:40:40 pleonber	2 1	00002/00000/00118
+// added INSERT_VDA_COMMENTS for script that adds SCCS history
+// 
+// D 1.1	97/11/11 15:48:58 cmmaster	1 0	00118/00000/00000
+// date and time created 97/11/11 15:48:58 by cmmaster
+// 
+// ----------------------- End of VDA Modifications ---------------------------
+// 
+// 
+// 
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-bool.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-bool.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:23  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:32  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:41  mb
+// Added snacc c++ library
+//
+// Revision 1.8  1995/09/07 18:45:13  rj
+// use AsnBoolTypeDesc instead of AsnTypeDesc (no real difference, it is the same type).
+//
+// Revision 1.7  1995/07/24  17:53:54  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.6  1995/02/18  19:17:19  rj
+// add TRUE/FALSE for backwards compatibility.
+//
+// Revision 1.5  1995/02/18  12:41:31  rj
+// a few more lines for the sake of backwards compatibility.
+//
+// Revision 1.4  1994/10/08  04:17:58  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.3  1994/08/31  23:32:13  rj
+// use the bool built-in where applicable, and a replacement type otherwise.
+//
+// Revision 1.2  1994/08/28  10:00:45  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:27  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_bool_h_
+#define _asn_bool_h_
+
+#if GLASS
+// for backwards compatibility:
+#ifndef FALSE
+enum { FALSE = false, TRUE = true };
+#endif
+#endif // GLASS
+
+class AsnBool: public AsnType
+{
+protected:
+
+// for backwards compatibility:
+#if GLASS
+#if BOOL_BUILTIN
+  typedef bool			_bool;
+#else
+  enum
+  {
+    false = ::false,
+    true = ::true
+  };
+#endif
+#endif
+
+  bool				value;
+
+public:
+				AsnBool (const bool val):
+#if BOOL_BUILTIN
+				  value (val)
+#else
+				  value (!!val)
+#endif
+				{}
+				AsnBool()				{}
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+				operator bool() const			{ return value; }
+  AsnBool			&operator = (bool newvalue)		{ value = newvalue; return *this; }
+
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen			BEncContent (BUF_TYPE b);
+  void				BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+  void				Print (ostream &) const;
+
+#if META
+  static const AsnBoolTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif // TCL
+#endif // META
+};
+
+#endif // conditional include
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-buf.h b/SecuritySNACCRuntime/c++-lib/inc/asn-buf.h
new file mode 100644
index 00000000..a9c2f1d1
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-buf.h
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-buf.h - buffer class
+//
+// MS 92
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-buf.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-buf.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:17  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:23  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.4  1999/08/06 16:13:18  mb
+// Set readError when doing a GetSeg past the end of the buffer.  This fixes many potential bugs and hangs when doing  streaming decodes with embedded data.
+//
+// Revision 1.3  1999/07/14 23:53:55  aram
+// Made const correct so things build with CW 5.0
+//
+// Revision 1.2  1999/03/04 00:43:20  mb
+// Made buffer full check work for NULL buffer in an unsigned int context
+//
+// Revision 1.1  1999/02/25 05:21:41  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 20:25:35  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/25  20:18:58  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:15:38  rj
+// fixed both Copy()'s name and implementation to CopyOut() that always returns the number of bytes copied out instead of 0 in case less than the requested amount is available.
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:46  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:28  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_buf_h_
+#define _asn_buf_h_
+
+class AsnBuf
+{
+protected:
+    char *dataStart;
+    char *dataEnd;
+    char *blkStart;
+    char *blkEnd;
+    char *readLoc;
+    bool writeError;
+    bool readError;
+
+public:
+    // install data for reading or blank blk for writing in buffer
+    // must be followed by 'mode' setting method call
+    void Init (char *data, size_t dataLen)
+    {
+	readError = writeError = 1;
+	blkStart = data;
+	blkEnd = data + dataLen;
+	dataStart = dataEnd = readLoc = blkEnd;
+    }
+
+    void ResetInReadMode()
+    {
+	readLoc = dataStart;
+	readError = false;
+	writeError = true;
+    }
+
+    void ResetInWriteRvsMode()
+    {
+	dataStart = dataEnd = blkEnd;
+	writeError = false;
+	readError = true;
+    }
+
+    void InstallData (const char *data, size_t dataLen)
+    {
+	Init (const_cast<char *>(data), dataLen);
+	dataStart = blkStart;
+	ResetInReadMode();
+    }
+
+    size_t			DataLen()		{ return dataEnd - dataStart; }
+    char			*DataPtr()		{ return dataStart; }
+    size_t			BlkLen()		{ return blkEnd - blkStart; }
+    char			*BlkPtr()		{ return blkStart; }
+    bool			Eod()			{ return readLoc >= dataEnd; }
+    bool			ReadError()		{ return readError; }
+    bool			WriteError()		{ return writeError; }
+
+    void Skip (size_t skipLen)
+    {
+	if ((readLoc + skipLen) > dataEnd)
+	{
+	    readLoc = dataEnd;
+	    readError = true;
+	}
+	else
+	    readLoc += skipLen;
+    }
+
+    size_t CopyOut (char *dst, size_t copyLen)
+    {
+	if (readLoc + copyLen > dataEnd)
+	{
+	    copyLen = dataEnd - readLoc;
+	    readError = true;
+	}
+	memcpy (dst, readLoc, copyLen);
+	readLoc += copyLen;
+	return copyLen;
+    }
+
+    unsigned char PeekByte()
+    {
+	if (Eod())
+	{
+	    readError = true;
+	    return 0;
+	}
+	else
+	    return *readLoc;
+    }
+
+    char *GetSeg (size_t *lenPtr)
+    {
+	char *retVal = readLoc;
+	if ((readLoc + *lenPtr) > dataEnd)
+	{
+	    *lenPtr = dataEnd - readLoc;
+	    readLoc = dataEnd;
+
+	    /* Attempting to read more bytes than left in the buffer is a read error --Michael. */
+	    readError = true;
+
+	    return retVal;
+	}
+	else
+	{
+	    readLoc += *lenPtr;
+	    return retVal;
+	}
+    }
+
+    void PutSegRvs (char *seg, size_t segLen)
+    {
+	if (dataStart < (blkStart + segLen))
+	    writeError = true;
+	else
+	{
+	    dataStart -= segLen;
+	    memcpy (dataStart, seg, segLen);
+	}
+    }
+
+    unsigned char GetByte()
+    {
+	if (Eod())
+	{
+	    readError = true;
+	    return 0;
+	}
+	else
+	    return *(readLoc++);
+    }
+
+    void PutByteRvs (unsigned char byte)
+    {
+	if (dataStart <= blkStart)
+	    writeError = true;
+	else
+	    *(--dataStart) = byte;
+    }
+};
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-config.h b/SecuritySNACCRuntime/c++-lib/inc/asn-config.h
new file mode 100644
index 00000000..7e7b846f
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-config.h
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-config.h - decoder alloc routines and buffer routines and other configuration stuff.
+//
+// MS 92/06/18
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-config.h,v 1.3 2001/06/27 23:09:16 dmitch Exp $
+// $Log: asn-config.h,v $
+// Revision 1.3  2001/06/27 23:09:16  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.2  2001/06/26 23:47:26  dmitch
+// Implemented AsnNullError as replacement for cerr in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:23  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.3  1999/04/08 21:20:18  aram
+// Fixed Asn1Free macro.
+//
+// Revision 1.2  1999/03/16 03:04:30  mb
+// Added common base class SecObject and implemented signing of the digest in SecSigner.
+//
+// Revision 1.1  1999/02/25 05:21:41  mb
+// Added snacc c++ library
+//
+// Revision 1.7  1995/09/07 18:48:36  rj
+// AsnIntType and AsnUIntType introduced to replace (unsigned) long int at a lot of places.
+// they shall provide 32 bit integer types on all platforms.
+//
+// Revision 1.6  1995/07/25  20:19:00  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.5  1995/02/13  14:47:46  rj
+// settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h.
+//
+// Revision 1.4  1994/10/08  04:17:59  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.3  1994/09/01  00:58:47  rj
+// redundant code moved into ../../config.h.bot; semicolon removed from end of macro texts.
+//
+// Revision 1.2  1994/08/28  10:00:47  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:29  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_config_h_
+#define _asn_config_h_
+
+#include <ctype.h>  /* for isprint() in <<op on AsnOcts */
+#include <iostream.h>
+#include <memory.h>
+#include <string.h>
+#include <setjmp.h>
+#include <math.h> /* to get ieee conversion functions & pow */
+
+#include "snacc.h"
+
+// used not only by AsnInt (asn-int.h), but by AsnNameDesc (meta.h) as well:
+#if SIZEOF_INT == 4
+#  define I		int
+#else
+#  if SIZEOF_LONG == 4
+#    define I		long
+#  else
+#    if SIZEOF_SHORT == 4
+#      define I		short
+#    endif
+#  endif
+#endif
+#ifdef I
+  typedef I		AsnIntType;
+  typedef unsigned I	AsnUIntType;
+#  undef I
+#else
+#  error "can't find integer type which is 4 bytes in size"
+#endif
+
+/* used to test if optionals are present */
+#define NOT_NULL( ptr)		((ptr) != NULL)
+
+
+/*
+ * Asn1Error (char *str)
+ *  - configure error handler
+ */
+#ifndef	NDEBUG
+#define Asn1Error		cerr
+#else
+
+/* silent ostream */
+class Asn1ErrorClass;
+class Asn1ErrorClass /* public ostream */
+{
+public:
+     Asn1ErrorClass& put (char c) { return *this; };
+     Asn1ErrorClass& write (const char * s, streamsize n) { return *this; };
+     Asn1ErrorClass& flush () { return *this; };
+	 template <class T>
+	 Asn1ErrorClass &operator << (const T &) { return *this; }
+};
+
+
+#ifdef	__APPLE__
+
+/* Avoid the static load-time init of AsnErrorClass */
+#include <Security/globalizer.h>
+extern ModuleNexus<Asn1ErrorClass> AsnNullError;
+
+/* Avoid instantiating cerr and endl */
+#define Asn1Error 	AsnNullError()
+#define endl		AsnNullError()
+
+#else	/* NDEBUG, !__APPLE__ */
+
+/* This does not currently have an instantiation */
+extern Asn1ErrorClass Asn1Error;
+
+#endif	/* __APPLE__ */
+#endif	/* NDEBUG */
+
+/*
+ * Asn1Warning (char *str)  - configure warning mechanism
+ * (currently not called)
+ */
+#define Asn1Warning		Asn1Error
+
+
+/*
+ * configure memory scheme used by decoder to allocate memory
+ * for the decoded value.  The include file name cannot be
+ * be null.
+ */
+#define Asn1New( class)		new class
+#define Asn1Delete( ptr)	delete ptr
+#define Asn1Alloc( size)	new char[size]
+#define Asn1Free( ptr)		delete[] ptr
+
+#include "asn-buf.h"
+#define BUF_TYPE		AsnBuf &
+#define ENV_TYPE		jmp_buf
+
+/* return true if succeeded, false otherwise */
+#define PDU_MEMBER_MACROS\
+    int BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)\
+    {\
+	bytesEncoded = BEnc (b);\
+	return !b.WriteError();\
+    }\
+\
+    int BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)\
+    {\
+	jmp_buf env;\
+	int val;\
+\
+	bytesDecoded = 0;\
+	if ((val = setjmp (env)) == 0)\
+	{\
+	    BDec (b, bytesDecoded, env);\
+	    return !b.ReadError();\
+	}\
+	else\
+	    return false;\
+    }
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-enum.h b/SecuritySNACCRuntime/c++-lib/inc/asn-enum.h
new file mode 100644
index 00000000..a5f91b2e
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-enum.h
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-enum.h - c++ version of ASN.1 ENUMERATED
+//
+//              inherits from AsnInt but changes universal tag stuff
+// MS 92/06/15
+//
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-enum.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-enum.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:23  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:32  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:42  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1995/08/17 15:17:07  rj
+// AsnEnumTypeDesc gets its own TclGetVal and TclSetVal functions.
+//
+// Revision 1.4  1995/07/24  17:52:00  rj
+// Clone() added, or else the _desc would be wrong (and the wrong BEnc etc... would get called for Clone-d objects).
+//
+// _desc changed from AsnIntTypeDesc to AsnEnumTypeDesc.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:17:59  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:48  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:31  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_enum_h_
+#define _asn_enum_h_
+
+class AsnEnum: public AsnInt
+{
+public:
+#if !TCL
+				AsnEnum():
+				  AsnInt()
+				{}
+#endif
+				AsnEnum (int i):
+				  AsnInt (i)
+				{}
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+#if META
+  static const AsnEnumTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif /* TCL */
+#endif /* META */
+};
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-incl.h b/SecuritySNACCRuntime/c++-lib/inc/asn-incl.h
new file mode 100644
index 00000000..160250f8
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-incl.h
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-incl.h - includes all of the asn1 library files
+//
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//
+// ------------------------------------------------------------------------
+// -  J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3  -
+// ------------------------------------------------------------------------
+// 
+// All modification are relative to the v1.3 of SNACC.  We used SunOS 4.1.3's 
+// SCCS.  The revision #'s start at 1.1,  which is the original version from 
+// SNACC 1.3.
+// 
+// 
+// ../SCCS/s.asn-incl.h:
+// 
+// D 1.2	98/05/01 13:14:40 pleonber	2 1	00006/00000/00059
+// added #include for sm_vdasnacc.h
+// 
+// D 1.1	98/05/01 13:13:30 pleonber	1 0	00059/00000/00000
+// date and time created 98/05/01 13:13:30 by pleonber
+// 
+// ----------------------- End of VDA Modifications ---------------------------
+// 
+// 
+// 
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-incl.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-incl.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.4  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.3  2001/01/10 01:12:03  dmitch
+// Rearranged #includes so sm_vdasnacc.h always sees asn-buf.h.
+//
+// Revision 1.2  2000/06/15 18:48:23  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:42  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 20:25:37  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/24  17:52:33  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:01  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:49  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:33  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifdef _IBM_ENC_
+#define ChoiceUnion
+#endif /* _IBM_ENC_ */
+
+
+#include "asn-config.h"
+#include "asn-buf.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-type.h"
+#include "asn-int.h"
+#include "asn-bool.h"
+#include "asn-real.h"
+#include "asn-oid.h"
+#include "asn-octs.h"
+#include "asn-bits.h"
+#include "asn-enum.h"
+#include "asn-null.h"
+#ifdef VDADER_RULES
+#include "sm_vdasnacc.h"
+#endif
+#include "asn-any.h"
+#include "asn-useful.h"
+#include "print.h"
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-int.h b/SecuritySNACCRuntime/c++-lib/inc/asn-int.h
new file mode 100644
index 00000000..28066332
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-int.h
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-int.h - c++ version of ASN.1 integer
+//
+// MS 92/06/15
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-int.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-int.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:23  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:32  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:42  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1995/09/07 18:49:19  rj
+// long int replaced by newly introduced AsnIntType at a lot of places.
+// it shall provide a 32 bit integer type on all platforms.
+//
+// Revision 1.4  1995/07/24  17:53:56  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:02  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:49  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:35  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_int_h_
+#define _asn_int_h_
+
+class AsnInt: public AsnType
+{
+protected:
+  AsnIntType			value;
+
+public:
+				AsnInt()				{}
+				AsnInt (AsnIntType val):
+				  value (val)
+				{}
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+				operator AsnIntType() const		{ return value; }
+  AsnInt			&operator = (AsnIntType newvalue)		{ value = newvalue; return *this; }
+
+  void				Set (AsnIntType i)			{ value = i; }
+  void				ReSet (AsnIntType i)			{ value = i; }
+
+  AsnLen			BEncContent (BUF_TYPE b);
+  void				BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+  void				Print (ostream &os) const;
+
+#if META
+  static const AsnIntTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif /* TCL */
+#endif /* META */
+};
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-len.h b/SecuritySNACCRuntime/c++-lib/inc/asn-len.h
new file mode 100644
index 00000000..61acfd7d
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-len.h
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-len.h - handle ASN.1 length encoding/decoding etc.
+//
+// MS 92/06/18
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-len.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-len.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:23  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:43  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/16 10:07:43  rj
+// make the unsigned value unsigned :-)
+//
+// Revision 1.5  1995/07/25  20:19:01  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1994/10/08  04:18:04  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.3  1994/08/31  23:35:00  rj
+// semicolon removed from end of macro text
+//
+// Revision 1.2  1994/08/28  10:00:50  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:36  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_len_h_
+#define _asn_len_h_
+
+typedef size_t		AsnLen;
+
+#define INDEFINITE_LEN	~0UL // max unsigned value used for indef rep
+
+#ifdef USE_INDEF_LEN
+
+#define BEncEocIfNec(b)\
+    BEncEoc (b)
+
+#define BEncConsLen(b, len)\
+    2 + BEncIndefLen (b) /* include len for EOC */
+
+#else // default -- use definite length -- usually faster (for snacc encoders) and smaller encodings
+
+#define BEncEocIfNec(b)  /* do nothing */
+
+#define BEncConsLen(b, len)\
+    BEncDefLen (b, len)
+
+#endif
+
+#define BEncIndefLen( b)\
+    1;\
+    b.PutByteRvs (0x80)
+
+/*
+ * use if you know the encoded length will be 0 >= len <= 127
+ * Eg for booleans, nulls, any resonable integers and reals
+ *
+ * NOTE: this particular Encode Routine does NOT return the length
+ * encoded (1).  The length counter must be explicity incremented
+ */
+#define BEncDefLenTo127( b, len)\
+    b.PutByteRvs ((unsigned char) len)
+
+#define BDEC_2ND_EOC_OCTET( b, bytesDecoded, env)\
+{\
+    if ((b.GetByte() != 0) || b.ReadError())\
+	Asn1Warning << "Warning - second octet of EOC not zero" << endl;\
+    (bytesDecoded)++;\
+}
+
+AsnLen BDecLen (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+AsnLen BEncDefLen ( BUF_TYPE b, AsnLen len);
+
+AsnLen BEncEoc (BUF_TYPE b);
+
+void  BDecEoc (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-list.h b/SecuritySNACCRuntime/c++-lib/inc/asn-list.h
new file mode 100644
index 00000000..96b94802
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-list.h
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-list.h
+//
+//   **** NOTE - this is not used or tested due to problems with gcc ****
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-list.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-list.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:24  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:32  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:43  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/16 20:25:38  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.5  1995/07/24  17:46:54  rj
+// operator == and != return bool instead of int.
+//
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1995/02/18  14:06:09  rj
+// #pragma interface/implementation are GNU specific and need to be wrapped.
+//
+// Revision 1.3  1994/10/08  04:18:05  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:51  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:37  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_list_h_
+#define _asn_list_h_
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#ifdef _IBM_ENC_
+#include "shmmgr.h"   // Guido Grassel 5.8.93
+#endif /* _IBM_ENC_ */
+
+template <class T>
+#ifndef _IBM_ENC_
+class AsnList
+#else
+class AsnList: public MemMgr  // Guido Grassel 12.8.93
+#endif /* _IBM_ENC_ */
+{
+protected:
+  unsigned long int		count;
+  struct AsnListElmt
+  {
+    T				elmt;
+    AsnListElmt			*next, *prev;
+  }				*first, *curr, *last;
+
+#ifdef _IBM_ENC_
+    AsnListElmt			*first, *curr, *last;
+#endif /* _IBM_ENC_ */
+
+public:
+				AsnList():
+				  count (0),
+				  first (NULL),
+				  curr (NULL),
+				  last (NULL)
+				{}
+
+  friend ostream		&operator << (ostream &os, AsnList &l);
+
+  void				SetCurrElmt (unsigned long int index);
+  void				SetCurrToFirst()			{ curr = first; }
+  void				SetCurrToLast()				{ curr = last; }
+
+  // reading member fcns
+  int				Count()					{ return count; }
+  T				*First()				{ return count > 0 ? &first->elmt : NULL; }
+  T				*Last()					{ return count > 0 ? &last->elmt : NULL; }
+  T				*Curr()					{ return curr ? &curr->elmt : NULL; }
+  T				*Next()					{ return curr && curr->next ? &curr->next->elmt : NULL; }
+  T				*Prev()					{ return curr && curr->prev ? &curr->prev->elmt : NULL; }
+
+  // routines that move the curr elmt
+  T				*GoNext()				{ if (curr) curr = curr->next; return Curr(); }
+  T				*GoPrev()				{ if (curr) curr = curr->prev; return Curr(); }
+
+  // write & alloc fcns - returns new elmt
+  T				&Append();		// add elmt to end of list
+  T				&Prepend();		// add elmt to begginning of list
+//    T				&InsertBefore();   insert elmt before current elmt
+//    T				&InsertAfter();   insert elmt after current elmt
+
+  // write & alloc & copy - returns list after copying elmt
+  AsnList			&AppendAndCopy (T &elmt);	// add elmt to end of list
+  AsnList			&PrependAndCopy (T &elmt);	// add elmt to begginning of list
+//    AsnList			&InsertBeforeAndCopy (T &elmt);   insert elmt before current elmt
+//    AsnList			&InsertAfterAndCopy (T &elmt);  insert elmt after current elmt
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+  // encode and decode routines
+  AsnLen			BEncContent (BUF_TYPE b);
+  void				BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+#if META
+  static const AsnTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif /* TCL */
+#endif /* META */
+};
+
+// This causes gcc2 on C++ to choke
+
+#if 0
+template <class T, class U>
+int ListsEquiv (AsnList<T> &l1, AsnList<U> &l2);
+
+template <class T, class U>
+inline bool operator == (AsnList<T> &l1, AsnList<U> &l2)
+{
+  return ListsEquiv (l1, l2);
+}
+
+template <class T, class U>
+inline bool operator != (AsnList<T> &l1, AsnList<U> &l2)
+{
+  return !ListsEquiv (l1,l2);
+}
+#endif
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-null.h b/SecuritySNACCRuntime/c++-lib/inc/asn-null.h
new file mode 100644
index 00000000..dda45094
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-null.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-null.h - C++ version of ASN.1 NULL
+//
+// MS 92/06/15
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-null.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-null.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:24  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:33  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:44  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 10:08:29  rj
+// comment out an unused argument
+//
+// Revision 1.4  1995/07/24  17:53:57  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:06  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:52  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:38  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_null_h_
+#define _asn_null_h_
+
+class AsnNull: public AsnType
+{
+public:
+				AsnNull()				{}
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+  AsnLen			BEncContent (BUF_TYPE /*b*/)		{ return 0; }
+  void				BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+  void				Print (ostream &os) const;
+
+#if META
+  static const AsnNullTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif /* TCL */
+#endif /* META */
+};
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-octs.h b/SecuritySNACCRuntime/c++-lib/inc/asn-octs.h
new file mode 100644
index 00000000..2dde1693
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-octs.h
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-octs.h - ASN.1 OCTET STRING type
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//
+// ------------------------------------------------------------------------
+// -  J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3  -
+// ------------------------------------------------------------------------
+// 
+// All modification are relative to the v1.3 of SNACC.  We used SunOS 4.1.3's 
+// SCCS.  The revision #'s start at 1.1,  which is the original version from 
+// SNACC 1.3.
+// 
+// 
+// ../SCCS/s.asn-octs.h:
+// 
+// D 1.3	98/04/24 22:46:51 pleonber	3 2	00002/00000/00129
+// added INSERT_VDA_COMMENTS for script that adds SCCS history to file
+// 
+// D 1.2	97/11/11 15:53:59 dharris	2 1	00004/00000/00125
+// changed == operator overide to remove warning
+// 
+// D 1.1	97/11/11 15:50:52 cmmaster	1 0	00125/00000/00000
+// date and time created 97/11/11 15:50:52 by cmmaster
+// 
+// ----------------------- End of VDA Modifications ---------------------------
+// 
+// 
+// 
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-octs.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-octs.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:24  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.3  1999/03/21 02:07:33  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.2  1999/03/18 22:35:27  mb
+// Made all destructors virtual.
+//
+// Revision 1.1  1999/02/25 05:21:44  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 20:25:40  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/24  17:46:52  rj
+// operator == and != return bool instead of int.
+//
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:07  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:53  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:39  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_octs_h_
+#define _asn_octs_h_
+
+#include <string.h>
+
+class AsnOcts: public AsnType
+{
+private:
+  int				OctsEquiv (const AsnOcts &o) const;
+
+  void				FillBitStringStk (BUF_TYPE b, AsnLen elmtLen0, AsnLen& bytesDecoded, ENV_TYPE env);
+
+  void				BDecConsOcts (BUF_TYPE b, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+protected:
+  size_t			octetLen;
+  char				*octs;
+
+public:
+
+  // constructor and Set alway copy strings so destructor can always delete
+				AsnOcts():
+				  octetLen (0),
+				  octs (NULL)
+				{}
+				AsnOcts (const char *str)		{ Set (str); }
+				AsnOcts (const char *str, const size_t len)
+									{ Set (str, len); }
+				AsnOcts (const AsnOcts &o)		{ Set (o); }
+#ifndef _IBM_ENC_
+  virtual		~AsnOcts();
+#else
+  virtual		~AsnOcts()				{ mem_mgr_ptr->Put ((void *)octs); }	// Guido Grassel, 11.8.93
+#endif /* _IBM_ENC_ */
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+  AsnOcts			&operator = (const AsnOcts &o)		{ ReSet (o); return *this; }
+  AsnOcts			&operator = (const char *str)		{ ReSet (str); return *this; }
+
+  // these set the octs and octetLen values
+  void				Set (const char *str, size_t len);
+  void				Set (const AsnOcts &o);
+  void				Set (const char *str);
+
+  // these free the old octs value and
+  // then reset the octs and octetLen values
+  void				ReSet (const char *str, size_t len);
+  void				ReSet (const AsnOcts &o);
+  void				ReSet (const char *str);
+
+  size_t			Len() const				{ return octetLen; }
+				operator const char* () const		{ return octs; }
+				operator char* ()			{ return octs; }
+
+#ifdef VDADER_RULES
+  bool operator == (const AsnOcts &o) const { if (OctsEquiv(o)) return true; else return false; }
+#else
+  bool				operator == (const AsnOcts &o) const	{ return OctsEquiv (o); }
+#endif
+  bool				operator != (const AsnOcts &o) const	{ return !OctsEquiv (o); }
+
+  AsnLen			BEncContent (BUF_TYPE b);
+  void				BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+  void				Print (ostream &os) const;
+
+#if META
+  static const AsnOctsTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif /* TCL */
+#endif /* META */
+};
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-oid.h b/SecuritySNACCRuntime/c++-lib/inc/asn-oid.h
new file mode 100644
index 00000000..e9785e68
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-oid.h
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-oid.h - ASN.1 OBJECT IDENTIFIER type
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//
+// ------------------------------------------------------------------------
+// -  J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3  -
+// ------------------------------------------------------------------------
+// 
+// All modification are relative to the v1.3 of SNACC.  We used SunOS 4.1.3's 
+// SCCS.  The revision #'s start at 1.1,  which is the original version from 
+// SNACC 1.3.
+// 
+// 
+// ../SCCS/s.asn-oid.h:
+// 
+// D 1.3	98/04/24 22:41:22 pleonber	3 2	00002/00000/00129
+// added INSERT_VDA_COMMENTS for script that adds SCCS history
+// 
+// D 1.2	97/11/11 15:55:44 dharris	2 1	00004/00000/00125
+// changed == operator to remove warnings
+// 
+// D 1.1	97/11/11 15:50:57 cmmaster	1 0	00125/00000/00000
+// date and time created 97/11/11 15:50:57 by cmmaster
+// 
+// ----------------------- End of VDA Modifications ---------------------------
+// 
+// 
+// 
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-oid.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-oid.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:24  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.3  1999/03/21 02:07:33  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.2  1999/03/18 22:35:27  mb
+// Made all destructors virtual.
+//
+// Revision 1.1  1999/02/25 05:21:44  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/16 12:56:15  rj
+// construct in the order the members are defined
+//
+// Revision 1.5  1995/07/24  18:37:59  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// _desc type corrected from AsnOctsTypeDesc to AsnOidTypeDesc.
+//
+// Revision 1.4  1995/02/18  19:25:16  rj
+// remove const from arguments that are passed by value.
+//
+// Revision 1.3  1994/10/08  04:18:08  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:54  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:40  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_oid_h_
+#define _asn_oid_h_
+
+class AsnOid: public AsnType
+{
+private:
+  int				OidEquiv (const AsnOid &o) const;
+
+protected:
+  size_t			octetLen;
+  char				*oid;
+
+public:
+				AsnOid():
+				  octetLen (0),
+				  oid (NULL)
+				{}
+
+				AsnOid (const char *encOid, size_t len)	{ Set (encOid, len); }
+				AsnOid (const AsnOid &o)		{ Set (o); }
+				AsnOid (unsigned long int a1, unsigned long int a2, long int a3 = -1, long int a4 = -1, long int a5 = -1, long int a6 = -1, long int a7 = -1, long int a8 = -1, long int a9 = -1, long int a10 = -1, long int a11 = -1)
+									{ Set (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+#ifndef _IBM_ENC_
+  virtual		~AsnOid();
+#else
+  virtual		~AsnOid()				{ mem_mgr_ptr->Put ((void*) oid); }     // Guido Grassel, 11.8.93
+#endif /* _IBM_ENC_ */
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+  AsnOid			&operator = (const AsnOid &o)		{ ReSet (o); return *this; }
+
+  size_t			Len() const				{ return octetLen; }
+  const char			*Str() const				{ return oid; }
+				operator char * ()			{ return oid; }
+				operator const char * () const		{ return oid; }
+  unsigned long int		NumArcs() const;
+
+#ifdef VDADER_RULES
+  bool operator == (const AsnOid &o) const { if (OidEquiv(o)) return true; else return false; }
+#else
+  bool				operator == (const AsnOid &o) const	{ return OidEquiv (o); }
+#endif
+  bool				operator != (const AsnOid &o) const	{ return !OidEquiv (o); }
+
+  // Set methods overwrite oid and octetLen values
+  void				Set (const char *encOid, size_t len);
+  void				Set (const AsnOid &o);
+
+  // first two arc numbers are mandatory.  rest are optional since negative arc nums are not allowed in the
+  // encodings, use them to indicate the 'end of arc numbers' in the optional parameters
+  void				Set (unsigned long int a1, unsigned long int a2, long int a3 = -1, long int a4 = -1, long int a5 = -1, long int a6 = -1, long int a7 = -1, long int a8 = -1, long int a9 = -1, long int a10 = -1, long int a11 = -1);
+
+
+  // ReSet routines are like Set except the old oid value is freed
+  void				ReSet (const char *encOid, size_t len);
+  void				ReSet (const AsnOid &o);
+  void				ReSet (unsigned long int a1, unsigned long int a2, long int a3 = -1, long int a4 = -1, long int a5 = -1, long int a6 = -1, long int a7 = -1, long int a8 = -1, long int a9 = -1, long int a10 = -1, long int a11 = -1);
+
+  AsnLen			BEncContent (BUF_TYPE b);
+  void				BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  PDU_MEMBER_MACROS
+
+  void				Print (ostream &os) const;
+
+#if META
+  static const AsnOidTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif /* TCL */
+#endif /* META */
+};
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-real.h b/SecuritySNACCRuntime/c++-lib/inc/asn-real.h
new file mode 100644
index 00000000..64019c32
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-real.h
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-real.h - ASN.1 REAL type
+//
+//  Mike Sample
+//  92/07/02
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-real.h,v 1.2 2001/06/21 21:57:00 dmitch Exp $
+// $Log: asn-real.h,v $
+// Revision 1.2  2001/06/21 21:57:00  dmitch
+// Avoid global const PLUS_INFINITY, MINUS_INFINITY
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:24  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:33  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:45  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 20:25:42  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/24  17:53:59  rj
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:18:09  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:55  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:41  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_real_h_
+#define _asn_real_h_
+
+class AsnReal: public AsnType
+{
+protected:
+  double			value;
+
+public:
+				AsnReal():
+				  value (0.0)
+				{}
+				AsnReal (double val):
+				  value (val)
+				{}
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+				operator double() const			{ return value; }
+  AsnReal			&operator = (double newvalue)		{ value = newvalue; return *this; }
+
+  AsnLen			BEncContent (BUF_TYPE b);
+  void				BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen			BEnc (BUF_TYPE b);
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  void				Print (ostream &os) const;
+
+  PDU_MEMBER_MACROS
+
+#if META
+  static const AsnRealTypeDesc	_desc;
+
+  const AsnTypeDesc		*_getdesc() const;
+
+#if TCL
+  int				TclGetVal (Tcl_Interp *) const;
+  int				TclSetVal (Tcl_Interp *, const char *val);
+#endif /* TCL */
+#endif /* META */
+};
+
+extern double AsnPlusInfinity();
+extern double AsnMinusInfinity();
+
+#define PLUS_INFINITY 	AsnReal(AsnPlusInfinity())
+#define MINUS_INFINITY	AsnReal(AsnMinusInfinity())
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-tag.h b/SecuritySNACCRuntime/c++-lib/inc/asn-tag.h
new file mode 100644
index 00000000..b72319ea
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-tag.h
@@ -0,0 +1,273 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-tag.h - stuff for dealing with tags
+//
+// MS 92
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+//
+// ------------------------------------------------------------------------
+// -  J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3  -
+// ------------------------------------------------------------------------
+// 
+// All modification are relative to the v1.3 of SNACC.  We used SunOS 4.1.3's 
+// SCCS.  The revision #'s start at 1.1,  which is the original version from 
+// SNACC 1.3.
+// 
+// 
+// ../SCCS/s.asn-tag.h:
+// 
+// D 1.2	98/04/24 22:39:52 pleonber	2 1	00012/00000/00204
+// added INSERT_VDA_COMMENT for script that adds SCCS history
+// 
+// D 1.1	98/04/17 10:30:00 pleonber	1 0	00204/00000/00000
+// date and time created 98/04/17 10:30:00 by pleonber
+// 
+// ----------------------- End of VDA Modifications ---------------------------
+// 
+// 
+// 
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-tag.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-tag.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.4  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.3  2000/12/22 00:20:55  dmitch
+// Added UTF8STRING_TAG_CODE.
+//
+// Revision 1.2  2000/06/15 18:48:24  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:45  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/16 20:25:45  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.5  1995/07/24  17:35:52  rj
+// ``#error "..."'' instead of ``#error ...''.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1995/02/18  16:45:53  rj
+// let cpp choose a 32 bit integer type.
+//
+// Revision 1.3  1994/10/08  04:18:09  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:56  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:43  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_tag_h_
+#define _asn_tag_h_
+
+#if SIZEOF_INT == 4
+  #define UL	unsigned int
+#elif SIZEOF_LONG == 4
+  #define UL	unsigned long
+#elif SIZEOF_SHORT == 4
+  #define UL	unsigned short
+#else
+  #error "can't find integer type which is 4 bytes in size"
+#endif
+typedef UL	AsnTag;
+
+// Tag Id's byte len
+#define TB	sizeof (AsnTag)
+
+// The MAKE_TAG_ID macro generates the TAG_ID rep for the
+// the given class/form/code (rep'd in long integer form)
+// if the class/form/code are constants the compiler (should)
+// calculate the tag completely --> zero runtime overhead.
+// This is good for efficiently comparing tags in switch statements
+// (decoding) etc.  because run-time bit fiddling (eliminated) minimized
+#ifndef _IBM_ENC_
+#define MAKE_TAG_ID( cl, fm, cd)\
+	((((UL)(cl)) << ((TB -1) * 8)) | (((UL)(fm)) << ((TB -1) * 8)) | (MAKE_TAG_ID_CODE (((UL)(cd)))))
+#else
+#define MAKE_TAG_ID( cl, fm, cd)\
+	((MAKE_TAG_ID_CODE (cd)) | (cl << ((TB -1) * 8)) | (fm << ((TB -1) * 8)))
+#endif /* _IBM_ENC_ */
+
+#define MAKE_TAG_ID_CODE( cd)\
+( (cd < 31) ?  (MAKE_TAG_ID_CODE1 (cd)):\
+      ((cd < 128)?  (MAKE_TAG_ID_CODE2 (cd)):\
+	 ((cd < 16384)?  (MAKE_TAG_ID_CODE3 (cd)):\
+	   (MAKE_TAG_ID_CODE4 (cd)))))
+
+#define MAKE_TAG_ID_CODE1( cd) ((long int)cd << ((TB -1) * 8))
+#define MAKE_TAG_ID_CODE2( cd) ((31l << ((TB -1) * 8)) | (cd << ((TB-2) * 8)))
+#define MAKE_TAG_ID_CODE3( cd) ((31l << ((TB -1) * 8))\
+				| ((cd & 0x3f80) << 9)\
+				| ( 0x0080 << ((TB-2) * 8))\
+				| ((cd & 0x007F) << ((TB-3)* 8)))
+
+#define MAKE_TAG_ID_CODE4( cd) ((31l << ((TB -1) * 8))\
+				| ((cd & 0x1fc000) << 2)\
+				| ( 0x0080 << ((TB-2) * 8))\
+				| ((cd & 0x3f80) << 1)\
+				| ( 0x0080 << ((TB-3) * 8))\
+				| ((cd & 0x007F) << ((TB-4)*8)))
+
+
+typedef enum BER_CLASS
+{
+    ANY_CLASS = -2,
+    NULL_CLASS = -1,
+    UNIV = 0,
+    APPL = (1 << 6),
+    CNTX = (2 << 6),
+    PRIV = (3 << 6)
+} BER_CLASS;
+
+typedef enum BER_FORM
+{
+    ANY_FORM = -2,
+    NULL_FORM = -1,
+    PRIM = 0,
+    CONS = (1 << 5)
+} BER_FORM;
+
+
+typedef enum BER_UNIV_CODE
+{
+    NO_TAG_CODE = 0,
+    BOOLEAN_TAG_CODE = 1,
+    INTEGER_TAG_CODE,
+    BITSTRING_TAG_CODE,
+    OCTETSTRING_TAG_CODE,
+    NULLTYPE_TAG_CODE,
+    OID_TAG_CODE,
+    OD_TAG_CODE,
+    EXTERNAL_TAG_CODE,
+    REAL_TAG_CODE,
+    ENUM_TAG_CODE,
+	UTF8STRING_TAG_CODE = 12,
+    SEQ_TAG_CODE =  16,
+    SET_TAG_CODE,
+    NUMERICSTRING_TAG_CODE,
+    PRINTABLESTRING_TAG_CODE,
+    TELETEXSTRING_TAG_CODE,
+    VIDEOTEXSTRING_TAG_CODE,
+    IA5STRING_TAG_CODE,
+    UTCTIME_TAG_CODE,
+    GENERALIZEDTIME_TAG_CODE,
+    GRAPHICSTRING_TAG_CODE,
+    VISIBLESTRING_TAG_CODE,
+
+#ifndef VDADER_RULES
+
+    GENERALSTRING_TAG_CODE
+
+#else
+    GENERALSTRING_TAG_CODE,
+    UNIVERSALSTRING_TAG_CODE = 28,
+    BMPSTRING_TAG_CODE = 30
+#endif
+
+} BER_UNIV_CODE;
+
+#define TT61STRING_TAG_CODE TELETEXSTRING_TAG_CODE
+#define ISO646STRING_TAG_CODE VISIBLESTRING_TAG_CODE
+
+/*
+ * the TAG_ID_[CLASS/FORM/CODE] macros are not
+ * super fast - try not to use during encoding/decoding
+ */
+#define TAG_ID_CLASS( tid) ( (tid & (0xC0 << ((TB-1) *8))) >> ((TB -1) * 8))
+#define TAG_ID_FORM( tid)  ( (tid & (0x20 << ((TB-1) *8))) >> ((TB -1) * 8))
+
+/*
+ * TAG_IS_CONS evaluates to true if the given AsnTag type
+ * tag has the constructed bit set.
+ */
+#define TAG_IS_CONS(tag) ((tag) & (CONS << ((TB-1) *8)))
+
+
+#define EOC_TAG_ID 0
+
+
+
+/*
+ * tag encoders.  given constant exprs for class form & code in the
+ * source, these can be optimized by the compiler (eg
+ * do the shifts and bitwise ors etc)
+ */
+
+#define BEncTag1( b, class, form, code)\
+    1;\
+    b.PutByteRvs ((class) | (form) | (code))
+
+#define BEncTag2( b, class, form, code)\
+    2;\
+    b.PutByteRvs (code);\
+    b.PutByteRvs ((class) | (form) | 31)
+
+#define BEncTag3( b, class, form, code)\
+    3;\
+    b.PutByteRvs ((code) & 0x7F);\
+    b.PutByteRvs (0x80 | ((code) >> 7));\
+    b.PutByteRvs ((class) | (form) | 31)
+
+#define BEncTag4( b, class, form, code)\
+    4;\
+    b.PutByteRvs ((code) & 0x7F);\
+    b.PutByteRvs (0x80 | ((code) >> 7));\
+    b.PutByteRvs (0x80 | ((code) >> 14));\
+    b.PutByteRvs ((class) | (form) | 31)
+
+#define BEncTag5( b, class, form, code)\
+    5;\
+    b.PutByteRvs ((code) & 0x7F);\
+    b.PutByteRvs (0x80 | ((code) >> 7));\
+    b.PutByteRvs (0x80 | ((code) >> 14));\
+    b.PutByteRvs (0x80 | ((code) >> 21));\
+    b.PutByteRvs ((class) | (form) | 31)
+
+
+AsnTag BDecTag (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-type.h b/SecuritySNACCRuntime/c++-lib/inc/asn-type.h
new file mode 100644
index 00000000..1bb5f829
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-type.h
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/asn-type.h - Abstract class that all ASN.1 types are derived from
+//               Design motivated by ANY type.
+//
+//               Runtime cost in speed and space for virtual fcns will
+//               hopefully not be too bad
+//
+//               If your ASN.1 code does not use ANY or ANY DEFIND BY
+//               types then you could  make the BEnc, BDec and Clone
+//               non-virtual in the AsnType to improve performance.
+//               (undef SUPPORT_ANY_TYPE)
+//
+//               NOTE: The virtual encode/decode/print etc fcns
+//               could be purely virtual (= 0) creating an abstract class
+//               but the ANY handling code needs to instantiate the AsnType
+//               base class (via Cloning).   Also it allows for default
+//               error reporting for ANY types that have not been
+//               instantiated properly.
+//
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// MS 92
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/asn-type.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: asn-type.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:24  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/03/21 02:07:33  mb
+// Added Copy to every AsnType.
+//
+// Revision 1.1  1999/02/25 05:21:46  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/16 20:25:48  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.5  1995/07/24  17:39:00  rj
+// _getref() gets an additional optional argument to faciliate the different member access semantics of TclGetVal() and TclSetVal().
+//
+// _typename() made private, no need to be public.
+//
+// additional function TclUnsetVal() to delete OPTIONAL members and SEQUENCE OF and SET OF list elements.
+//
+// #if TCL ... #endif wrapped into #if META ... #endif
+//
+// getTclPDU() deleted.
+//
+// changed `_' to `-' in file names.
+//
+// Revision 1.4  1994/10/08  04:18:10  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.3  1994/09/13  14:18:52  rj
+// inline functions moved from asn_type.h to asn_type.C.
+// functions that are called upon error only don't need to be that fast.
+//
+// Revision 1.2  1994/08/28  10:00:57  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:44  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_type_h_
+#define _asn_type_h_
+
+#ifdef _IBM_ENC_
+#include "shmmgr.h"   // Guido Grassel 4.8.93
+#endif /* _IBM_ENC_ */
+
+#define SUPPORT_ANY_TYPE
+
+#if TCL
+#include <Tcl/tcl.h>
+#undef VOID
+#endif
+
+#if META
+#include "meta.h"
+#endif
+
+#ifndef __IBM_ENC_
+class AsnType
+#else
+class AsnType: public MemMgr   // Guido Grassel, 12.8.93
+#endif /* __IBM_ENC_ */
+{
+public:
+  virtual			~AsnType();
+
+#ifdef SUPPORT_ANY_TYPE
+
+  virtual AsnType	*Clone() const;
+  virtual AsnType	*Copy() const;
+
+  virtual void		BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  virtual AsnLen	BEnc (BUF_TYPE b);
+
+#else
+
+  void				BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+									{}
+  AsnLen			BEnc (BUF_TYPE b)			{ return 0; }
+
+#endif
+
+  virtual void			Print (ostream &) const;
+
+#if META
+  static const AsnTypeDesc	_desc;
+
+  virtual const AsnTypeDesc	*_getdesc() const;
+  virtual AsnType		*_getref (const char *membername, bool create=false);
+
+private:
+  const char			*_typename() const;
+
+#if TCL
+public:
+  virtual int			TclGetDesc (Tcl_DString *) const;
+  virtual int			TclGetVal (Tcl_Interp *) const;
+  virtual int			TclSetVal (Tcl_Interp *, const char *val);
+  virtual int			TclUnsetVal (Tcl_Interp *, const char *membernames);
+#endif // TCL
+#endif // META
+};
+
+#endif // conditional include
diff --git a/SecuritySNACCRuntime/c++-lib/inc/asn-useful.h b/SecuritySNACCRuntime/c++-lib/inc/asn-useful.h
new file mode 100644
index 00000000..49835d5b
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/asn-useful.h
@@ -0,0 +1,480 @@
+/*
+ * 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.
+ */
+
+
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// asn-useful.h - class definitions for ASN.1 module ASN-USEFUL
+//
+//   This file was generated by snacc on Thu Dec 21 14:15:26 2000
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _asn_useful_h_
+#define _asn_useful_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class ObjectDescriptor;
+class UTF8String;
+class NumericString;
+class PrintableString;
+class TeletexString;
+class T61String;
+class VideotexString;
+class IA5String;
+class GraphicString;
+class VisibleString;
+class ISO646String;
+class GeneralString;
+class UTCTime;
+class GeneralizedTime;
+class UniversalString;
+class BMPString;
+class EXTERNALChoice;
+class EXTERNAL;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+/* [UNIVERSAL 7] IMPLICIT OCTET STRING */
+class ObjectDescriptor: public AsnOcts
+{
+public:
+			ObjectDescriptor(): AsnOcts() {}
+			ObjectDescriptor (const char *str): AsnOcts (str) {}
+			ObjectDescriptor (const char *str, const size_t len): AsnOcts (str, len) {}
+			ObjectDescriptor (const AsnOcts &o): AsnOcts (o) {}
+  ObjectDescriptor		&operator = (const ObjectDescriptor &o)	{ ReSet (o); return *this; }
+  ObjectDescriptor		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 12] IMPLICIT OCTET STRING */
+class UTF8String: public AsnOcts
+{
+public:
+			UTF8String(): AsnOcts() {}
+			UTF8String (const char *str): AsnOcts (str) {}
+			UTF8String (const char *str, const size_t len): AsnOcts (str, len) {}
+			UTF8String (const AsnOcts &o): AsnOcts (o) {}
+  UTF8String		&operator = (const UTF8String &o)	{ ReSet (o); return *this; }
+  UTF8String		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 18] IMPLICIT OCTET STRING */
+class NumericString: public AsnOcts
+{
+public:
+			NumericString(): AsnOcts() {}
+			NumericString (const char *str): AsnOcts (str) {}
+			NumericString (const char *str, const size_t len): AsnOcts (str, len) {}
+			NumericString (const AsnOcts &o): AsnOcts (o) {}
+  NumericString		&operator = (const NumericString &o)	{ ReSet (o); return *this; }
+  NumericString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 19] IMPLICIT OCTET STRING */
+class PrintableString: public AsnOcts
+{
+public:
+			PrintableString(): AsnOcts() {}
+			PrintableString (const char *str): AsnOcts (str) {}
+			PrintableString (const char *str, const size_t len): AsnOcts (str, len) {}
+			PrintableString (const AsnOcts &o): AsnOcts (o) {}
+  PrintableString		&operator = (const PrintableString &o)	{ ReSet (o); return *this; }
+  PrintableString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 20] IMPLICIT OCTET STRING */
+class TeletexString: public AsnOcts
+{
+public:
+			TeletexString(): AsnOcts() {}
+			TeletexString (const char *str): AsnOcts (str) {}
+			TeletexString (const char *str, const size_t len): AsnOcts (str, len) {}
+			TeletexString (const AsnOcts &o): AsnOcts (o) {}
+  TeletexString		&operator = (const TeletexString &o)	{ ReSet (o); return *this; }
+  TeletexString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 20] IMPLICIT OCTET STRING */
+class T61String: public AsnOcts
+{
+public:
+			T61String(): AsnOcts() {}
+			T61String (const char *str): AsnOcts (str) {}
+			T61String (const char *str, const size_t len): AsnOcts (str, len) {}
+			T61String (const AsnOcts &o): AsnOcts (o) {}
+  T61String		&operator = (const T61String &o)	{ ReSet (o); return *this; }
+  T61String		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 21] IMPLICIT OCTET STRING */
+class VideotexString: public AsnOcts
+{
+public:
+			VideotexString(): AsnOcts() {}
+			VideotexString (const char *str): AsnOcts (str) {}
+			VideotexString (const char *str, const size_t len): AsnOcts (str, len) {}
+			VideotexString (const AsnOcts &o): AsnOcts (o) {}
+  VideotexString		&operator = (const VideotexString &o)	{ ReSet (o); return *this; }
+  VideotexString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 22] IMPLICIT OCTET STRING */
+class IA5String: public AsnOcts
+{
+public:
+			IA5String(): AsnOcts() {}
+			IA5String (const char *str): AsnOcts (str) {}
+			IA5String (const char *str, const size_t len): AsnOcts (str, len) {}
+			IA5String (const AsnOcts &o): AsnOcts (o) {}
+  IA5String		&operator = (const IA5String &o)	{ ReSet (o); return *this; }
+  IA5String		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 25] IMPLICIT OCTET STRING */
+class GraphicString: public AsnOcts
+{
+public:
+			GraphicString(): AsnOcts() {}
+			GraphicString (const char *str): AsnOcts (str) {}
+			GraphicString (const char *str, const size_t len): AsnOcts (str, len) {}
+			GraphicString (const AsnOcts &o): AsnOcts (o) {}
+  GraphicString		&operator = (const GraphicString &o)	{ ReSet (o); return *this; }
+  GraphicString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 26] IMPLICIT OCTET STRING */
+class VisibleString: public AsnOcts
+{
+public:
+			VisibleString(): AsnOcts() {}
+			VisibleString (const char *str): AsnOcts (str) {}
+			VisibleString (const char *str, const size_t len): AsnOcts (str, len) {}
+			VisibleString (const AsnOcts &o): AsnOcts (o) {}
+  VisibleString		&operator = (const VisibleString &o)	{ ReSet (o); return *this; }
+  VisibleString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 26] IMPLICIT OCTET STRING */
+class ISO646String: public AsnOcts
+{
+public:
+			ISO646String(): AsnOcts() {}
+			ISO646String (const char *str): AsnOcts (str) {}
+			ISO646String (const char *str, const size_t len): AsnOcts (str, len) {}
+			ISO646String (const AsnOcts &o): AsnOcts (o) {}
+  ISO646String		&operator = (const ISO646String &o)	{ ReSet (o); return *this; }
+  ISO646String		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 27] IMPLICIT OCTET STRING */
+class GeneralString: public AsnOcts
+{
+public:
+			GeneralString(): AsnOcts() {}
+			GeneralString (const char *str): AsnOcts (str) {}
+			GeneralString (const char *str, const size_t len): AsnOcts (str, len) {}
+			GeneralString (const AsnOcts &o): AsnOcts (o) {}
+  GeneralString		&operator = (const GeneralString &o)	{ ReSet (o); return *this; }
+  GeneralString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 23] IMPLICIT OCTET STRING */
+class UTCTime: public AsnOcts
+{
+public:
+			UTCTime(): AsnOcts() {}
+			UTCTime (const char *str): AsnOcts (str) {}
+			UTCTime (const char *str, const size_t len): AsnOcts (str, len) {}
+			UTCTime (const AsnOcts &o): AsnOcts (o) {}
+  UTCTime		&operator = (const UTCTime &o)	{ ReSet (o); return *this; }
+  UTCTime		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 24] IMPLICIT OCTET STRING */
+class GeneralizedTime: public AsnOcts
+{
+public:
+			GeneralizedTime(): AsnOcts() {}
+			GeneralizedTime (const char *str): AsnOcts (str) {}
+			GeneralizedTime (const char *str, const size_t len): AsnOcts (str, len) {}
+			GeneralizedTime (const AsnOcts &o): AsnOcts (o) {}
+  GeneralizedTime		&operator = (const GeneralizedTime &o)	{ ReSet (o); return *this; }
+  GeneralizedTime		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 28] IMPLICIT OCTET STRING */
+class UniversalString: public AsnOcts
+{
+public:
+			UniversalString(): AsnOcts() {}
+			UniversalString (const char *str): AsnOcts (str) {}
+			UniversalString (const char *str, const size_t len): AsnOcts (str, len) {}
+			UniversalString (const AsnOcts &o): AsnOcts (o) {}
+  UniversalString		&operator = (const UniversalString &o)	{ ReSet (o); return *this; }
+  UniversalString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+/* [UNIVERSAL 30] IMPLICIT OCTET STRING */
+class BMPString: public AsnOcts
+{
+public:
+			BMPString(): AsnOcts() {}
+			BMPString (const char *str): AsnOcts (str) {}
+			BMPString (const char *str, const size_t len): AsnOcts (str, len) {}
+			BMPString (const AsnOcts &o): AsnOcts (o) {}
+  BMPString		&operator = (const BMPString &o)	{ ReSet (o); return *this; }
+  BMPString		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+class EXTERNALChoice: public AsnType
+{
+public:
+  enum ChoiceIdEnum
+  {
+     single_ASN1_typeCid = 0,
+     octet_alignedCid = 1,
+     arbitraryCid = 2
+  };
+
+  enum ChoiceIdEnum	choiceId;
+  union
+  {
+     AsnOcts		*single_ASN1_type;
+     AsnOcts		*octet_aligned;
+     AsnBits		*arbitrary;
+  };
+
+
+			EXTERNALChoice();
+			EXTERNALChoice (const EXTERNALChoice &);
+  virtual		~EXTERNALChoice();
+
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EXTERNALChoice		&operator = (const EXTERNALChoice &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void			Print (ostream &os) const;
+};
+
+
+class EXTERNAL: public AsnType
+{
+public:
+  AsnOid		*direct_reference;
+  AsnInt		*indirect_reference;
+  ObjectDescriptor		*data_value_descriptor;
+  EXTERNALChoice		*encoding;
+
+			EXTERNAL();
+			EXTERNAL (const EXTERNAL &);
+  virtual		~EXTERNAL();
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  EXTERNAL		&operator = (const EXTERNAL &);
+  AsnLen		BEncContent (BUF_TYPE b);
+  void			BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env);
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+  void		Print (ostream &os) const;
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of asn-useful.h */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/cdsaUtils.h b/SecuritySNACCRuntime/c++-lib/inc/cdsaUtils.h
new file mode 100644
index 00000000..f85019b1
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/cdsaUtils.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * cdsaUtils.h - utility functions for CDSA-related code
+ */
+
+#ifndef	_SNACC_CDSA_UTILS_H_
+#define _SNACC_CDSA_UTILS_H_
+
+#include <Security/asn-incl.h>
+#include <Security/utilities.h>
+#include <Security/cssmdata.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* all decoding errors throw CSSMERR_CL_UNKNOWN_FORMAT */
+
+/* malloc/copy AsnBits.bits -->CssmOwnedData */
+void SC_asnBitsToCssmData(
+	const AsnBits &bits,
+	CssmOwnedData &oData);
+
+/* given DER-encoded bit string, decoded it and malloc/copy results 
+ * back to a CssmOwnedData */
+void SC_decodeAsnBitsToCssmData(
+	const CssmData encodedBits,
+	CssmOwnedData &oData);
+
+/* DER-decode any AsnType object */
+void SC_decodeAsnObj(
+	const CssmData		&derEncoded,
+	AsnType				&asnObj);
+
+/* DER-encode any AsnType object. */
+void SC_encodeAsnObj(
+	AsnType				&asnObj,
+	CssmOwnedData		&derEncoded,
+	size_t				maxEncodedSize);
+
+/*
+ * Given a contentLength, obtain the length of the DER length encoding.
+ */
+size_t SC_lengthOfLength(
+	size_t 				contentLen);
+
+/*
+ * Encode a DER length field. Pass in the lengthOfLength if you've obtained
+ * it in a previous call to CL_lengthOfLength.
+ */
+void SC_encodeLength(
+	size_t 	contentLen,
+	void 	*cp,
+	size_t	lengthOfLength = 0);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SNACC_CDSA_UTILS_H_ */
\ No newline at end of file
diff --git a/SecuritySNACCRuntime/c++-lib/inc/config.h b/SecuritySNACCRuntime/c++-lib/inc/config.h
new file mode 100644
index 00000000..51b701f7
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/config.h
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+
+
+/* config.h.  Generated automatically by configure.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef gid_t */
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have the vprintf function.  */
+#define HAVE_VPRINTF 1
+
+/* Define if your C compiler doesn't accept -c and -o together.  */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Define if you need to in order for stat and other things to work.  */
+/* #undef _POSIX_SOURCE */
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef uid_t */
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#define WORDS_BIGENDIAN 1
+
+/* Define if the X Window System is missing or not being used.  */
+#define X_DISPLAY_MISSING 1
+
+/* Define if lex declares yytext as a char * by default, not a char[].  */
+/* #undef YYTEXT_POINTER */
+
+/*
+ * file: acconfig.h
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/config.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+ * $Log: config.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:06  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.3  2001/05/05 00:59:18  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.2  2000/12/22 00:21:57  dmitch
+ * Misc. update and sync for clean build on Cheetah 1D7.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:05:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.7  1997/03/03 11:58:26  wan
+ * Final pre-delivery stuff (I hope).
+ *
+ * Revision 1.6  1997/02/28 13:39:34  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.5  1997/02/15 20:01:37  rj
+ * check whether the compiler supports volatile functions (and whether abort() is volatile).
+ *
+ * Revision 1.4  1995/02/20  11:16:57  rj
+ * cpp switch HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS added.
+ *
+ * Revision 1.3  1995/02/13  14:46:49  rj
+ * settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h.
+ *
+ * Revision 1.2  1994/10/08  04:38:56  rj
+ * slot for autoconf Tcl detection added.
+ *
+ * Revision 1.1  1994/09/01  00:51:19  rj
+ * first check-in (new file).
+ *
+ */
+
+/*
+ * define IEEE_REAL_FMT if your system/compiler uses the native ieee double
+ * this should improve the performance of encoding reals.
+ * If your system has the IEEE library routines (iszero, isinf etc)
+ * then define IEEE_REAL_LIB.  If neither are defined then
+ * frexp is used.  Performance is probaby best for IEEE_REAL_FMT.
+ *
+ *  #define IEEE_REAL_FMT
+ *  #define IEEE_REAL_LIB
+ */
+/* use ANSI or K&R style C? */
+#define __USE_ANSI_C__ 1
+
+/* does the C++ compiler have the bool type built-in? */
+#define BOOL_BUILTIN 1
+
+/* does the C++ compiler allow variable sized automatic arryas? */
+#define HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS 1
+
+/* do we have all the libs we need for the Tcl interface? */
+/* #undef HAVE_TCL */
+
+/* does the compiler support volatile functions (and is abort() volatile?) */
+/* #undef COMPILER_WITHOUT_VOLATILE_FUNCTIONS */
+
+/* The number of bytes in a double.  */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long.  */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a short.  */
+#define SIZEOF_SHORT 2
+
+/* Define if you have the finite function.  */
+#define HAVE_FINITE 1
+
+/* Define if you have the isinf function.  */
+#define HAVE_ISINF 1
+
+/* Define if you have the memcmp function.  */
+#define HAVE_MEMCMP 1
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memset function.  */
+#define HAVE_MEMSET 1
+
+/* Define if you have the <dirent.h> header file.  */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <malloc.h> header file.  */
+/* #undef HAVE_MALLOC_H */
+
+/* Define if you have the <memory.h> header file.  */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <ndir.h> header file.  */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <string.h> header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file.  */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file.  */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the m library (-lm).  */
+/* #undef HAVE_LIBM */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/hash.h b/SecuritySNACCRuntime/c++-lib/inc/hash.h
new file mode 100644
index 00000000..a2dfb06b
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/hash.h
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/hash.h - C++ hash tbl routines
+//
+// Based on hashing stuff from UBC Raven Code (Terry Coatta & Don Acton)
+//
+// MS 92
+// Copyright (C) 1992 the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/hash.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: hash.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:25  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:46  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/28 13:39:42  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.4  1997/02/16 20:25:51  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.3  1994/10/08  04:18:12  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:00:59  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:46  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _asn_hash_h_
+#define _asn_hash_h_
+
+#define TABLESIZE 256
+#define INDEXMASK 0xFF
+#define INDEXSHIFT 8
+
+typedef void *Table[TABLESIZE];
+
+typedef unsigned int Hash;
+
+typedef struct HashSlot
+{
+  int    leaf;
+  Hash   hash;
+  void  *value;
+  Table *table;
+} HashSlot;
+
+Hash MakeHash (const char *str, size_t len);
+
+Table *InitHash();
+
+int Insert (Table *table, void *element, Hash hash);
+
+int CheckFor (Table *table, Hash hash);
+
+int CheckForAndReturnValue (Table *table, Hash hash, void **value);
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/init.h b/SecuritySNACCRuntime/c++-lib/inc/init.h
new file mode 100644
index 00000000..28a68cfe
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/init.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * file: .../c++-lib/inc/init.h
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/init.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+ * $Log: init.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:06  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.3  2001/05/05 00:59:18  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.2  2000/06/15 18:48:25  dmitch
+ * Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+ *
+ * Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+ * Base Fortissimo Tree
+ *
+ * Revision 1.1  1999/02/25 05:21:47  mb
+ * Added snacc c++ library
+ *
+ * Revision 1.1  1995/07/27 09:22:35  rj
+ * new file: .h file containing a declaration for a function defined in a C++ file, but with C linkage.
+ *
+ */
+
+extern
+#ifdef __cplusplus
+	"C"
+#endif
+	     int Snacc_Init (Tcl_Interp *interp);
diff --git a/SecuritySNACCRuntime/c++-lib/inc/meta.h b/SecuritySNACCRuntime/c++-lib/inc/meta.h
new file mode 100644
index 00000000..f31cbc31
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/meta.h
@@ -0,0 +1,284 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/meta.h
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/meta.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: meta.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:25  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:47  mb
+// Added snacc c++ library
+//
+// Revision 1.6  1997/02/28 13:39:43  wan
+// Modifications collected for new version 1.3: Bug fixes, tk4.2.
+//
+// Revision 1.5  1995/09/07 18:50:04  rj
+// long int replaced by newly introduced AsnIntType.
+// it shall provide a 32 bit integer type on all platforms.
+//
+// Revision 1.4  1995/08/17  15:23:47  rj
+// introducing an AsnEnumTypeDesc class with its own TclGetDesc2 function that returns the value names but omits the numeric values.
+// utility function AsnSe_TypeDesc::mandatmemberr added.
+//
+
+#include <unistd.h>
+#include <stdlib.h>
+
+struct AsnNameDesc
+{
+  const char			*const name;
+  const AsnIntType		value;
+};
+
+struct AsnTypeDesc;
+
+struct AsnMemberDesc // description of CHOICE member; base class for AsnSe_MemberDesc
+{
+  const char			*const name;
+  const AsnTypeDesc		*const desc;
+
+				AsnMemberDesc (const char *, const AsnTypeDesc *);
+				AsnMemberDesc();
+
+#if TCL
+  virtual int			TclGetDesc (Tcl_DString *) const;
+  virtual int			TclGetDesc2 (Tcl_DString *) const;
+#endif
+};
+
+struct AsnSe_MemberDesc: AsnMemberDesc	// _ == t/quence; description of SET or SEQUENCE member
+{
+  bool				optional;
+
+				AsnSe_MemberDesc (const char *, const AsnTypeDesc *, bool);
+				AsnSe_MemberDesc();
+
+#if TCL
+  int				TclGetDesc2 (Tcl_DString *) const;
+#endif
+};
+
+typedef AsnMemberDesc		AsnChoiceMemberDesc;
+typedef AsnSe_MemberDesc	AsnSetMemberDesc;
+typedef AsnSe_MemberDesc	AsnSequenceMemberDesc;
+
+struct AsnModuleDesc;
+
+class AsnType;
+
+struct AsnTypeDesc
+{
+  const AsnModuleDesc		*module;
+  const char			*const name;	// NULL for basic types
+  const bool			pdu;
+  const enum Type	// NOTE: keep this enum in sync with the typenames[]
+  {
+    VOID,
+    ALIAS,
+
+    INTEGER,
+    REAL,
+    NUL_, // sic! (can't fight the ubiquitous NULL #define)
+    BOOLEAN,
+    ENUMERATED,
+    BIT_STRING,
+    OCTET_STRING,
+    OBJECT_IDENTIFIER,
+
+    SET,
+    SEQUENCE,
+    SET_OF,
+    SEQUENCE_OF,
+    CHOICE,
+    ANY
+  }				type;
+
+  AsnType			*(*create)();
+
+  static const char		*const typenames[];
+
+				AsnTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)());
+
+  virtual const AsnModuleDesc	*getmodule() const;
+  virtual const char		*getname() const;
+  virtual bool			ispdu() const;
+  virtual Type			gettype() const;
+  virtual const AsnNameDesc	*getnames() const;
+  //virtual const AsnMemberDesc	*getmembers() const;
+
+#if TCL
+  virtual int			TclGetDesc (Tcl_DString *) const;
+  virtual int			TclGetDesc2 (Tcl_DString *) const;
+#endif
+};
+
+struct AsnNamesTypeDesc: AsnTypeDesc
+{
+  const AsnNameDesc		*const names;
+
+				AsnNamesTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnNameDesc *);
+
+  const AsnNameDesc		*getnames() const;
+
+#if TCL
+  int				TclGetDesc (Tcl_DString *) const;
+  // for BIT STRING and INTEGER, ENUMERATED has its own:
+  int				TclGetDesc2 (Tcl_DString *) const;
+#endif
+};
+
+struct AsnEnumTypeDesc: AsnNamesTypeDesc
+{
+				AsnEnumTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnNameDesc *);
+
+#if TCL
+  int				TclGetDesc2 (Tcl_DString *) const;
+#endif
+};
+
+struct AsnMembersTypeDesc: AsnTypeDesc
+{
+				AsnMembersTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)());
+
+#if TCL
+  int				TclGetDesc (Tcl_DString *) const;
+#endif
+};
+
+struct AsnChoiceTypeDesc: AsnMembersTypeDesc
+{
+  const AsnChoiceMemberDesc	*const members;
+
+				AsnChoiceTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnChoiceMemberDesc *);
+
+  int				choicebyname (const char *name) const;
+  const char			*choicebyvalue (int value) const;
+
+#if TCL
+  int				TclGetDesc2 (Tcl_DString *) const;
+#endif
+};
+
+struct AsnSe_TypeDesc: AsnMembersTypeDesc
+{
+  const AsnSe_MemberDesc	*const members;
+
+				AsnSe_TypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnSe_MemberDesc *);
+
+#if TCL
+  int				mandatmemberr (Tcl_Interp *interp, const char *membername) const;
+  int				TclGetDesc2 (Tcl_DString *) const;
+#endif
+};
+
+struct AsnListTypeDesc: AsnTypeDesc
+{
+  const AsnTypeDesc		*const base;
+
+				AsnListTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnTypeDesc *);
+
+#if TCL
+  int				TclGetDesc (Tcl_DString *) const;
+#endif
+};
+
+struct AsnAliasTypeDesc: AsnTypeDesc
+{
+  const AsnTypeDesc		*const alias;
+
+				AsnAliasTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnTypeDesc *);
+
+  const AsnModuleDesc		*getmodule() const;
+  const char			*getname() const;
+  bool				ispdu() const;
+  Type				gettype() const;
+
+  const AsnNameDesc		*getnames() const;
+  //const AsnMemberDesc		*getmembers() const;
+
+#if TCL
+  int				TclGetDesc (Tcl_DString *) const;
+#endif
+};
+
+typedef AsnTypeDesc		AsnRealTypeDesc;
+typedef AsnTypeDesc		AsnNullTypeDesc;
+typedef AsnTypeDesc		AsnBoolTypeDesc;
+typedef AsnNamesTypeDesc	AsnIntTypeDesc;
+typedef AsnNamesTypeDesc	AsnBitsTypeDesc;
+typedef AsnTypeDesc		AsnOctsTypeDesc;
+typedef AsnTypeDesc		AsnOidTypeDesc;
+typedef AsnSe_TypeDesc		AsnSetTypeDesc;
+typedef AsnSe_TypeDesc		AsnSequenceTypeDesc;
+
+struct AsnModuleDesc
+{
+  const char			*const name;
+  const AsnTypeDesc		**const types;
+};
+
+extern const AsnModuleDesc	*asnModuleDescs[];
+
+#if TCL
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+// designed to be used with Tcl_SplitList(): argument list that automagically frees itself when it goes out of scope:
+
+struct Args
+{
+  int				c;
+  char				**v;
+
+				Args();
+  virtual			~Args();
+};
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+// file that automagically closes itself when it goes out of scope:
+
+struct TmpFD
+{
+  int	fd;
+
+	TmpFD()			{ fd = -1; }
+	TmpFD (int _fd)		{ fd = _fd; }
+	~TmpFD()		{ if (fd > 0) ::close (fd); }
+
+	int operator = (int _fd){ return fd = _fd; }
+//	operator int()		{ return fd; }
+};
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+// hack to cope with Tcl's inability to handle binary strings:
+
+extern int	debinify (Tcl_Interp *interp, const char *in, size_t len);
+extern int	binify (Tcl_Interp *interp, const char *str, char *buf, size_t *len);
+
+//\[sep]----------------------------------------------------------------------------------------------------------------------------
+#endif /* TCL */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/policy.h b/SecuritySNACCRuntime/c++-lib/inc/policy.h
new file mode 100644
index 00000000..d69d0b20
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/policy.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * file: policy.h
+ *
+ */
+
+/*
+ * enable the snacc compiler's Tcl interface generating code?
+ * set it to 0 or 1.
+ */
+#ifndef NO_TCL
+#define NO_TCL		0
+#endif
+
+/*
+ * enable code for meta code generation?
+ * the Tcl code needs it.
+ */
+#ifndef NO_META
+#define NO_META		NO_TCL
+#endif
+
+/*
+ * enable code for CORBA IDL generation?
+ */
+#ifndef IDL
+#define IDL		1
+#endif
diff --git a/SecuritySNACCRuntime/c++-lib/inc/print.h b/SecuritySNACCRuntime/c++-lib/inc/print.h
new file mode 100644
index 00000000..b79f3eff
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/print.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/print.h
+//
+// MS 92
+//
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/print.h,v 1.3 2001/06/27 23:57:51 dmitch Exp $
+// $Log: print.h,v $
+// Revision 1.3  2001/06/27 23:57:51  dmitch
+// Reimplement partial fix for Radar 2664258: Print() routines are now empty stubs in NDEBUG config.
+//
+// Revision 1.2  2001/06/27 23:09:16  dmitch
+// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
+//
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:25  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:47  mb
+// Added snacc c++ library
+//
+// Revision 1.4  1997/02/16 20:25:54  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.3  1994/10/08  04:18:13  rj
+// code for meta structures added (provides information about the generated code itself).
+//
+// code for Tcl interface added (makes use of the above mentioned meta code).
+//
+// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+//
+// made Print() const (and some other, mainly comparison functions).
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:00  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:47  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _snacccpp_print_h_
+#define _snacccpp_print_h_
+
+extern unsigned short int	indentG;
+extern unsigned short int	stdIndentG;
+
+void				Indent (ostream &os, unsigned short int i);
+
+ostream				&operator << (ostream &os, const AsnType &a);
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/sm_vdasnacc.h b/SecuritySNACCRuntime/c++-lib/inc/sm_vdasnacc.h
new file mode 100644
index 00000000..aae41213
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/sm_vdasnacc.h
@@ -0,0 +1,389 @@
+/*
+ * 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.
+ */
+
+
+/* @(#) sm_vdasnacc.h 1.21 5/1/98 09:59:08 */
+// vdasnacc.h
+//
+#ifndef _SM_VDASNACC_H_
+#define _SM_VDASNACC_H_
+
+#include "asn-incl.h"
+
+#include <stdio.h>
+#ifndef SM_SIZE_T
+#define SM_SIZE_T size_t
+#endif
+
+#ifdef WIN32
+#include <stdlib.h>
+#define SM_FOPEN_WRITE "wb"
+#define SM_FOPEN_READ "rb"
+#define SM_FOPEN_APPEND "ab"
+#else
+#define SM_FOPEN_WRITE "w"
+#define SM_FOPEN_READ "r"
+#define SM_FOPEN_APPEND "a"
+#endif
+
+
+//////////////////////////////////////////////////////////////////////////
+// CSM_Buffer is the general purpose buffer used throughout the SFL
+class CSM_Buffer: public AsnType
+{
+private:
+   SM_SIZE_T m_lSize;
+   char *m_pMemory;
+#if	!defined(macintosh) && !defined(__APPLE__)
+   char *m_pszFN;
+   FILE *m_pFP;
+#endif
+   char *m_pMemFP;
+   char *m_pCache;
+   SM_SIZE_T m_lCacheSize;
+
+#if	!defined(macintosh) && !defined(__APPLE__)
+   // returns bool value indicating if the buffer is in a file
+   bool InFile() { if (m_pszFN == NULL) return false; else return true; }
+#endif
+
+   // AllocMoreMem allocates specified more bytes for mem buffer
+   void AllocMoreMem(SM_SIZE_T lSize);
+
+public:
+   // CONSTRUCTORS
+   // use this constructor to create a complete empty buffer
+   CSM_Buffer();
+   // use this constructor to create a memory buffer of size lSize
+   CSM_Buffer(size_t lSize);
+   // use this constructor to create a buffer in file pszFileName
+   //CSM_Buffer(char *pszFileName);
+   // use this constructor to init the memory buffer with a ptr and size
+   CSM_Buffer(const char *pBuf, SM_SIZE_T lSize);
+   // use this constructor to make a copy of the provided buffer
+   // and put it into this buffer
+   CSM_Buffer(const CSM_Buffer &b);
+
+   virtual ~CSM_Buffer(); // DESTRUCTOR
+
+   // Inheirited from AsnType.
+   virtual AsnType *Clone() const;
+   virtual AsnType *Copy() const;
+
+   virtual AsnLen BEnc (BUF_TYPE b);
+   void Print (ostream &os) const;
+
+   // CONTENT MODIFYING MEMBERS
+   void Clear();
+
+   // ATTRIBUTE MEMBERS
+   // return size of the buffer
+   SM_SIZE_T Length() const;
+   // copy the provided null terminated memory in memory buffer
+   void Set(const char *psz);
+   // copy the provided memory of size lSize in memory buffer
+   void Set(const char *p, SM_SIZE_T lSize);
+   // set the length of the buffer
+   void SetLength(SM_SIZE_T lSize) { m_lSize = lSize; }
+#if	!defined(macintosh) && !defined(__APPLE__)
+   // copy the provided file name into m_pszFN
+   void SetFileName(char *pszFN)
+   {
+#ifdef HAVE_STRDUP
+   		strdup(pszFN);
+#else
+   		m_pszFN = (char *)malloc (strlen (pszFN) + 1);
+   		strcpy (m_pszFN, pszFN);
+#endif
+   }
+#endif
+   // allocate memory in the buffer and return ptr to it
+   char* Alloc(SM_SIZE_T lSize);
+   // compare this with b, return 0 if match
+   long Compare(const CSM_Buffer &b);
+   // ReSet copies b into this
+   long ReSet(const CSM_Buffer &b);
+
+   // BUFFER DATA ACCESS MEMBERS
+   // return a pointer to the actual data, if in file, call CopyAll
+   const char* Access() const;
+   // return a copy of the actual data and return the size
+   char* Get(SM_SIZE_T &l) const;
+   // return a copy of the actual data
+   char* Get() const { SM_SIZE_T l; return Get(l); }
+
+   // COMPARISON OPERATORS
+   bool operator == (/*const*/ CSM_Buffer &b) { 
+         if (Compare(b) == 0) return true; else return false; }
+   bool operator != (/*const*/ CSM_Buffer &b) { 
+         if (Compare(b) == 0) return false; else return true; }
+
+   // ASSIGNMENT OPERATOR
+   CSM_Buffer &operator = (/*const*/ CSM_Buffer &b) { 
+         ReSet(b); return *this; }
+
+#if	!defined(macintosh) && !defined(__APPLE__)
+   // BUFFER CONVERSION MEMBERS
+   long ConvertFileToMemory();
+   long ConvertMemoryToFile(char *pszFN);
+#endif
+
+   // STREAMING MEMBERS
+   long Open(char *pszMode);
+   long Seek(SM_SIZE_T lOffset, SM_SIZE_T lOrigin);
+   void Close();
+
+   // STREAMING MEMBERS
+   long cRead(char *pBuffer, SM_SIZE_T lSize);
+   long Write(const char *pBuffer, SM_SIZE_T lSize);
+   char* nRead(SM_SIZE_T lSize, SM_SIZE_T &lBytesRead);
+   void Flush();
+};
+
+long vdasnacc_sortSet(CSM_Buffer *pEncBuf[], int icount);
+long vdasnacc_sortSetOf(CSM_Buffer **&pEncBuf, int icount);
+long SM_WriteToAsnBuf(CSM_Buffer *&pCBuf, AsnBuf &SNACCinputBuf);
+long SM_WriteToAsnBuf(CSM_Buffer &CBuf, AsnBuf &SNACCoutputBuf);
+long SM_ReadFromAsnBuf(CSM_Buffer *&pCBuf, // OUT,copied data.
+    AsnBuf &SNACCinputBuf,          // IN, input SNACC buffer
+    long length,                    // IN, length of data to read.
+    CSM_Buffer *preLoad);           // IN, optional data to be pre-loaded;
+                                    //   (for SNACC support)
+// no alloc version of SM_ReadFromAsnBuf
+long SM_ReadFromAsnBuf(
+    AsnBuf &SNACCinputBuf,          // IN, input SNACC buffer
+    CSM_Buffer *pCBuf,              // OUT,copied data.
+    long length,                    // IN, length of data to read.
+    CSM_Buffer *preLoad);           // IN, optional data to be pre-loaded;
+                                    //   (for SNACC support)
+// function to convert an AsnBits to a CSM_Buffer
+long SM_AsnBits2Buffer(AsnBits *pBits, CSM_Buffer *pBuffer);
+long SM_Buffer2AsnBits(CSM_Buffer *pBuffer, AsnBits *pBits, size_t lBits);
+long SM_BufferReverseBits(CSM_Buffer *pBuffer);
+
+class BigIntegerStr;
+#define SM_BUF_2_BIG_INT_STR	0
+#if		SM_BUF_2_BIG_INT_STR
+// FIXME - why doesn't this link properly? 
+// prototypes for converting to and from BigIntegerStr and CSM_Buffer.
+long SM_Buffer2BigIntegerStr( CSM_Buffer     *asn1Data,
+                              BigIntegerStr &pSnaccBigIntStr,
+                              bool            unsignedFlag);
+
+long SM_Buffer2BigIntegerStr( CSM_Buffer     *asn1Data,
+                              BigIntegerStr *&pSnaccBigIntStr,
+                              bool            unsignedFlag);
+#endif	/* SM_BUF_2_BIG_INT_STR */
+
+// VDASNACC_ENCDEC_BUFSIZE is the number of bytes in the global
+// buffer used for encoding and decoding
+#define VDASNACC_ENCDEC_BUFSIZE 100000
+
+//typedef struct
+//{
+//   long lgth;                           /* Number of characters in string */
+//   unsigned char *str;                     /* Pointer to character string */
+//}  Str_struct;
+
+#define NULL_STR (Str_struct *) NULL
+
+
+//extern "C" {
+//#include    <stdio.h>    /**** Standard I/O includes   ****/
+//long vdasnacc_sortSetOf(Str_struct **strEnc, int icount);
+//long vdasnacc_sortSet(Str_struct **strEnc, int icount);
+//void free_Str(Str_struct *str);
+//void free_Str_content(Str_struct *str);
+//}
+
+#define ENCODE_ANY(encodedData,asnAny)\
+   {\
+    CSM_Buffer *blob=new CSM_Buffer;\
+\
+    if ((encodedData) && (asnAny))\
+    {\
+      ENCODE_BUF((encodedData), blob)\
+      (asnAny)->value = (AsnType *)blob;\
+    }\
+   }
+
+#define DECODE_ANY(decodeData,asnAny)\
+   {\
+    CSM_Buffer *blob;\
+    if ((asnAny))\
+        blob=(CSM_Buffer *)(asnAny)->value;\
+\
+    if (blob)\
+      DECODE_BUF((decodeData), blob)\
+   }
+
+// This macro is usually only necessary if a SNACC AsnBuf is used
+//  immediately after being loaded by an application (e.g. consecutive 
+//  encode decode operations).
+#define SNACC_BUFRESET_READ(pSnaccBuf)   (pSnaccBuf)->ResetInReadMode();
+#define SNACC_BUFRESET_WRITE(pSnaccBuf)  (pSnaccBuf)->ResetInWriteRvsMode();
+
+#define ENCODE_BUF_NO_ALLOC(encodeData, blob)\
+   {\
+   char *pchBuffer = (char *)calloc(1, \
+        VDASNACC_ENCDEC_BUFSIZE);\
+   size_t encodedLen;\
+   AsnBuf  outputBuf;\
+   int status=0;\
+   \
+   outputBuf.Init(pchBuffer, VDASNACC_ENCDEC_BUFSIZE);\
+   outputBuf.ResetInWriteRvsMode();\
+   status = (encodeData)->BEncPdu (outputBuf, encodedLen);\
+   outputBuf.ResetInReadMode();\
+   SM_ReadFromAsnBuf(outputBuf, (blob), outputBuf.DataLen(),NULL);\
+   free(pchBuffer);\
+   }
+
+#define ENCODE_BUF(encodeData, blob)\
+   {\
+   char *pchBuffer = (char *)calloc(1, \
+        VDASNACC_ENCDEC_BUFSIZE);\
+   size_t encodedLen;\
+   AsnBuf  outputBuf;\
+   int status=0;\
+   \
+   outputBuf.Init(pchBuffer, VDASNACC_ENCDEC_BUFSIZE);\
+   outputBuf.ResetInWriteRvsMode();\
+   if((status = (encodeData)->BEncPdu (outputBuf, encodedLen))==false)\
+         SME_THROW(33, "BAD SNACC Encode", NULL);\
+   outputBuf.ResetInReadMode();\
+   SM_ReadFromAsnBuf((blob), outputBuf, outputBuf.DataLen(),NULL);\
+   free(pchBuffer);\
+   }
+
+#define DECODE_BUF(decodeData, blob)\
+   {\
+   char *pchBuffer = (char *)calloc(1, \
+         VDASNACC_ENCDEC_BUFSIZE);\
+   size_t encodedLen;\
+   AsnBuf outputBuf;\
+   int nDecStatus = 0;\
+   \
+   outputBuf.Init(pchBuffer, VDASNACC_ENCDEC_BUFSIZE);\
+   outputBuf.ResetInWriteRvsMode();\
+   SM_WriteToAsnBuf((blob), outputBuf);\
+   outputBuf.ResetInReadMode();\
+   if ((nDecStatus = (decodeData)->BDecPdu(outputBuf, encodedLen)) == false)\
+         SME_THROW(34, "BAD SNACC Decode", NULL);\
+   free(pchBuffer);\
+   }
+      
+#define SM_ASSIGN_ANYBUF(lpBuf, asnAny)\
+   {\
+    (asnAny)->value = (AsnType *)new CSM_Buffer(*(lpBuf));\
+   }
+
+/* don't know if this actually works... dave */
+#define SM_EXTRACT_ANYBUF(pSS, asnAny)\
+   {\
+   (pSS) = new CSM_Buffer(*(CSM_Buffer *)(asnAny)->value);\
+   }
+
+#define ENCODE_BUF1(encodeContent, encodeLen)\
+   {\
+    AsnBuf  outputBuf;\
+    char *lpszBuf;\
+\
+    lpszBuf = (char *)calloc(1, VDASNACC_ENCDEC_BUFSIZE/2);\
+    outputBuf.Init(lpszBuf, VDASNACC_ENCDEC_BUFSIZE/2);\
+    outputBuf.ResetInWriteRvsMode();\
+    (encodeLen) = encodeContent(outputBuf);
+
+#define ENCODE_BUF2(blob)\
+    outputBuf.ResetInReadMode();\
+    SM_ReadFromAsnBuf((blob), outputBuf, outputBuf.DataLen(),NULL);\
+    free(lpszBuf);\
+   }
+
+    // RWC; The following macro defines the ASN ANY load for "BEnc...()" 
+    // RWC;  operations into the final output buffers.  NO ERROR checking
+    // RWC;  is performed to be sure the buffer is ASN decodable.
+    // RWC; this convention for loading ANY results is only valid for
+    // RWC;  the SMIME/MSP library loads, where previous logic has
+    // RWC;  loaded the "AsnType *value" element with a "CSM_Buffer *"
+    // RWC;  containing the encoded ANY result.
+    // RWC;  The "Str_struct *" needs to be freed when class destroyed.
+    // RWC;  Place encoded ASN directly into buffer.
+#if	defined(macintosh) || defined(__APPLE__)
+#define ENC_LOAD_ANYBUF(asnType, Bbuf, l) \
+	if ((asnType)->value != NULL)\
+	{\
+		l = (asnType)->value->BEnc(Bbuf);\
+	}
+#else
+#define ENC_LOAD_ANYBUF(asnType, Bbuf, l) \
+    if ((CSM_Buffer *)(asnType)->value != NULL)\
+    {\
+       SM_WriteToAsnBuf(((CSM_Buffer *&)(asnType)->value), Bbuf);\
+       l = ((CSM_Buffer *)(asnType)->value)->Length();\
+    }
+#endif
+
+// RWC;  The following macro decodes the ANY buffer tag and length to 
+// RWC;    allocate a "CSM_Buffer", then copies the unencoded results.
+// RWC;    The assumption is that the "readloc" buffer will still be intact
+// RWC;    even after the decode of the tag and length. (HOPEFULLY!)
+// RWC;    Once the data for this ANY is copied, unencoded into the CSM_Buffer
+// RWC;    then we set the buffer "readloc" pointer to after this element.
+// RWC;    "bBuf.GetSeg(elmtLen)"
+#define DEC_LOAD_ANYBUF(asnType, Bbuf, l, env) \
+    {\
+      size_t len = (size_t) 0; \
+      AsnLen bytesDecoded = 0L; \
+      size_t elmtLen = (size_t) 0;  \
+      int tag = 0 ; \
+      char *readloc = NULL; \
+      CSM_Buffer *blob; \
+      CSM_Buffer *preLoad;\
+\
+      readloc = Bbuf.GetSeg (&len);\
+      tag = BDecTag (Bbuf, bytesDecoded, env);\
+      elmtLen = BDecLen (Bbuf, bytesDecoded, env);\
+      len = bytesDecoded;\
+      preLoad = new CSM_Buffer(readloc, len);\
+      SM_ReadFromAsnBuf(blob, (Bbuf), elmtLen,preLoad);\
+      (asnType)->value = blob;\
+      delete preLoad;\
+      l += len + elmtLen;\
+    }
+
+
+// RWC; Correctly process our OID values, the "char *" "asnOid->Set()" function
+//       directly loads the "->oid" private variable, no processing!!!
+//int SM_STR_TO_OID(char *lpStrOid, AsnOid *asnOid);
+//int SM_OID_TO_STR(char *lpStrOid, AsnOid *asnOid);
+
+#ifdef BOB
+#define SNACC_OID_FIX(asnOid, long_arr4) \
+  {\
+    unsigned long int a[11];\
+    int i;\
+    for (i=0; i < (long_arr4)->lgth; i++) a[i] = (long_arr4)->int_arr[i];\
+    for (i=(long_arr4)->lgth; i < 11; i++) a[i] = -1;\
+    (asnOid)->Set(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9],\
+        a[10]);\
+  }
+#endif
+
+#endif // _SM_VDASNACC_H_
+
+// EOF vdasnacc.h
diff --git a/SecuritySNACCRuntime/c++-lib/inc/sm_vdatypes.h b/SecuritySNACCRuntime/c++-lib/inc/sm_vdatypes.h
new file mode 100644
index 00000000..5f631a51
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/sm_vdatypes.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// sm_vdatypes.h - class definitions for ASN.1 module VdaEnhancedTypes
+//
+//   This file was generated by snacc on Mon Mar 22 21:49:57 1999
+//   UBC snacc by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+#ifndef _sm_vdatypes_h_
+#define _sm_vdatypes_h_
+
+
+//------------------------------------------------------------------------------
+// class declarations:
+
+class BigIntegerStr;
+
+//------------------------------------------------------------------------------
+// class definitions:
+
+/* [UNIVERSAL 2] IMPLICIT OCTET STRING */
+class BigIntegerStr: public AsnOcts
+{
+public:
+			BigIntegerStr(): AsnOcts() {}
+			BigIntegerStr (const char *str): AsnOcts (str) {}
+			BigIntegerStr (const char *str, const size_t len): AsnOcts (str, len) {}
+			BigIntegerStr (const AsnOcts &o): AsnOcts (o) {}
+  BigIntegerStr		&operator = (const BigIntegerStr &o)	{ ReSet (o); return *this; }
+  BigIntegerStr		&operator = (const char *str)	{ ReSet (str); return *this; }
+  virtual AsnType	*Clone() const;
+
+  virtual AsnType	*Copy() const;
+
+  AsnLen		BEnc (BUF_TYPE b);
+  void			BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env);
+  int			BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded);
+  int			BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded);
+
+};
+
+
+//------------------------------------------------------------------------------
+// externs for value defs
+
+//------------------------------------------------------------------------------
+
+#endif /* conditional include of sm_vdatypes.h */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/snacc.h b/SecuritySNACCRuntime/c++-lib/inc/snacc.h
new file mode 100644
index 00000000..4124e9db
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/snacc.h
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * file: snacc.h
+ *
+ *
+ * ------------------------------------------------------------------------
+ * -  J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3  -
+ * ------------------------------------------------------------------------
+ * 
+ * All modification are relative to the v1.3 of SNACC.  We used SunOS 4.1.3's 
+ * SCCS.  The revision #'s start at 1.1,  which is the original version from 
+ * SNACC 1.3.
+ * 
+ * 
+ * ../SCCS/s.snacc.h:
+ * 
+ * D 1.3	98/04/24 22:30:19 pleonber	3 2	00002/00000/00157
+ * added INSERT_VDA_COMMENTS comment for script that adds SCCS history.
+ * 
+ * D 1.2	97/11/07 08:01:08 pleonber	2 1	00004/00000/00153
+ * added #ifndef _gVDADER_RULES extern int gVDADER_RULES #endif
+ * 
+ * D 1.1	97/10/30 13:09:44 cmmaster	1 0	00153/00000/00000
+ * date and time created 97/10/30 13:09:44 by cmmaster
+ * 
+ * ----------------------- End of VDA Modifications ---------------------------
+ * 
+ * 
+ * 
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/snacc.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+ * $Log: snacc.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:06  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:18  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1  2000/06/15 18:47:21  dmitch
+ * Files duplicated or copied from elsewhere. See Apple_README for gory details.
+ *
+ * Revision 1.1.1.1  2000/03/09 01:00:04  rmurphy
+ * Base Fortissimo Tree
+ *
+ * Revision 1.1  1999/02/25 05:32:31  mb
+ * Added public headers.
+ *
+ * Revision 1.7  1997/04/07 13:13:18  wan
+ * Made more C++ readable (credits to Steve Walker)
+ *
+ * Revision 1.6  1997/02/28 13:39:35  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.5  1997/02/15 20:38:48  rj
+ * In member functions, return *this after calling abort() for stupid compilers that don't seem to know about volatile abort() (they would otherwise abort with an error).
+ *
+ * Revision 1.4  1995/07/24  15:06:52  rj
+ * configure checks for mem* functions. define replacements using b* functions, if necessary.
+ *
+ */
+
+#ifndef _SNACC_H_
+#define _SNACC_H_
+
+#define GLASS	1
+#define KHO	1
+
+#include "config.h"
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL	0
+#endif
+
+#if HAVE_MEMCMP /* memcmp(3) returns <0, 0 and 0, bcmp(3) returns only 0 and !0 */
+#define memcmpeq( a, b, len)	memcmp (a, b, len)
+#else
+#define memcmpeq( a, b, len)	bcmp (a, b, len)
+#endif
+#if HAVE_MEMSET
+#define memzero( p, len)	memset (p, 0, len)
+#else
+#define memzero( p, len)	bzero (p, len)
+#endif
+#if !HAVE_MEMCPY
+#define memcpy( dst, src, len)	bcopy (src, dst, len)
+#endif
+
+#ifdef __cplusplus
+
+#ifdef VOLATILE_RETRUN
+#  define RETURN_THIS_FOR_COMPILERS_WITHOUT_VOLATILE_FUNCTIONS	return *this;
+#else
+#  define RETURN_THIS_FOR_COMPILERS_WITHOUT_VOLATILE_FUNCTIONS
+#endif
+
+#if !BOOL_BUILTIN
+#ifndef true
+// enum bool { false, true };
+// the above looks elegant, but leads to anachronisms (<, ==, !=, ... return value of type int, not enum bool), therefore:
+typedef int bool;
+enum { false, true };
+#endif
+#endif
+
+#else /* !__cplusplus */
+
+#ifndef FALSE
+#define FALSE	0
+#endif
+#ifndef TRUE
+#define TRUE	1
+#endif
+
+#endif /* __cplusplus */
+
+/*
+ *  Inspired by gdb 4.0, for better or worse...
+ *  (grabbed from Barry Brachman - MS)
+ *
+ *  These macros munge C routine declarations such
+ *  that they work for ANSI or non-ANSI C compilers
+ */
+#ifdef __USE_ANSI_C__
+
+#define PROTO( X)			X
+#define PARAMS( arglist, args)  	(args)
+#define NOPARAMS()	        	(void)
+#define _AND_				,
+#define DOTS				, ...
+
+#else /* !__USE_ANSI_C__ */
+
+#define PROTO( X)			()
+#define PARAMS( arglist, args)	 	arglist args;
+#define NOPARAMS()	        	()
+#define _AND_				;
+#define DOTS
+#define void                            char
+
+#endif /* __USE_ANSI_C__ */
+
+#include "policy.h"
+
+#if COMPILER
+#define TCL	(HAVE_TCL && !NO_TCL)
+#define META	(TCL && !NO_META)
+#endif
+
+#if MAKEDEPEND
+#if !NO_META
+#ifdef META
+#undef META
+#endif
+#define META	1
+#endif
+#if !NO_TCL
+#ifdef TCL
+#undef TCL
+#endif
+#define TCL	1
+#endif
+#endif
+
+#if TCL
+#ifdef META
+#undef META
+#endif
+#define META	1
+#endif
+
+#define COMMA			,
+
+#ifdef _IBM_ENC_
+#define if_IBM_ENC( code)	code
+#else
+#define if_IBM_ENC( code)
+#endif
+
+#if META
+#define if_META( code)		code
+#else
+#define if_META( code)
+#endif
+
+#if TCL && META
+#define if_TCL( code)		code
+#else
+#define if_TCL( code)
+#endif
+
+#ifndef _gVDADER_RULES
+extern int gVDADER_RULES;
+#endif
+
+#endif /* _SNACC_H_ */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/str-stk.h b/SecuritySNACCRuntime/c++-lib/inc/str-stk.h
new file mode 100644
index 00000000..4dd05963
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/str-stk.h
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/str-stk.h - maintains a stack of the components of a bit string or octet string so they can be copied into a single chunk
+//
+// MS 92/07/06
+//
+// Copyright (C) 1992 Michael Sample and the University of British Columbia
+//
+// This library is free software; you can redistribute it and/or
+// modify it provided that this copyright/license information is retained
+// in original form.
+//
+// If you modify this file, you must clearly indicate your changes.
+//
+// This source code is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/str-stk.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: str-stk.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:25  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.2  1999/06/04 21:43:20  mb
+// Fixed several memory leaks.
+//
+// Revision 1.1  1999/02/25 05:21:48  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/02/16 20:25:56  rj
+// check-in of a few cosmetic changes
+//
+// Revision 1.4  1995/07/25  21:09:14  rj
+// changed `_' to `-' in file names.
+//
+// Revision 1.3  1994/10/08  04:15:30  rj
+// fixed both Copy()'s name and implementation to CopyOut() that always returns the number of bytes copied out instead of 0 in case less than the requested amount is available.
+//
+// several `unsigned long int' turned into `size_t'.
+//
+// Revision 1.2  1994/08/28  10:01:01  rj
+// comment leader fixed.
+//
+// Revision 1.1  1994/08/28  09:20:49  rj
+// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+
+#ifndef _str_stk_h_
+#define _str_stk_h_
+
+#ifndef _IBM_ENC_
+class StrStk
+#else
+#include "shmmgr.h"   // Guido Grassel 4.8.93
+
+class StrStk: public MemMgr     // Guido Grassel 12.8.93
+#endif /* _IBM_ENC_ */
+{
+public:
+  struct Elmt
+  {
+    char			*str;
+    size_t			len;
+  }				*stk;
+  size_t			size;
+  size_t			growSize;
+  size_t			nextFreeElmt;
+  size_t			totalByteLen;
+
+				StrStk (int stkSize, int growIncrement);
+				~StrStk ();
+
+  void				Reset();
+
+  void				Push (char *str, size_t strLen);
+
+  // copy string pieces (buffer refs) into single block.
+  // assumes that the buf is at least totalByteLen byte long.
+  void				CopyOut (char *buf);
+
+};
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c++-lib/inc/tcl-if.h b/SecuritySNACCRuntime/c++-lib/inc/tcl-if.h
new file mode 100644
index 00000000..09cfafa1
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/inc/tcl-if.h
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+
+// file: .../c++-lib/inc/tcl-if.h
+//
+// $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/inc/tcl-if.h,v 1.1.1.1 2001/05/18 23:14:06 mb Exp $
+// $Log: tcl-if.h,v $
+// Revision 1.1.1.1  2001/05/18 23:14:06  mb
+// Move from private repository to open source repository
+//
+// Revision 1.3  2001/05/05 00:59:18  rmurphy
+// Adding darwin license headers
+//
+// Revision 1.2  2000/06/15 18:48:25  dmitch
+// Snacc-generated source files, now part of CVS tree to allow for cross-platform build of snaccRuntime.
+//
+// Revision 1.1.1.1  2000/03/09 01:00:05  rmurphy
+// Base Fortissimo Tree
+//
+// Revision 1.1  1999/02/25 05:21:48  mb
+// Added snacc c++ library
+//
+// Revision 1.5  1997/01/01 23:27:22  rj
+// `typename' appears to be a reserved word in gcc 2.7, so prefix it with `_'
+//
+// Revision 1.4  1995/09/07  18:50:34  rj
+// duplicate code merged into a new function SnaccTcl::gettypedesc().
+//
+// Revision 1.3  1995/08/17  15:06:43  rj
+// snacced.[hC] renamed to tcl-if.[hC].
+// class SnaccEd renamed to SnaccTcl.
+//
+// Revision 1.2  1995/07/27  09:53:25  rj
+// comment leader fixed
+//
+// Revision 1.1  1995/07/27  09:52:12  rj
+// new file: tcl interface used by snacced.
+
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+class SnaccTcl
+{
+  Tcl_Interp		*interp;
+  Tcl_HashTable		modules,
+			types,
+			files;
+
+  Tcl_HashEntry		*create();
+  const AsnTypeDesc	*gettypedesc (const char *cmdname, const char *type_name);
+
+public:
+			SnaccTcl (Tcl_Interp *);
+			~SnaccTcl();
+
+  int			create (int argc, char **argv);
+  int			openfile (int argc, char **argv);
+  int			finfo (int argc, char **argv);
+  int			read (int argc, char **argv);
+  int			write (int argc, char **argv);
+  int			closefile (int argc, char **argv);
+
+  int			modulesinfo (int argc, char **argv);
+  int			typesinfo (int argc, char **argv);
+  int			typeinfo (int argc, char **argv);
+  int			info (int argc, char **argv);
+
+  int			getval (int argc, char **argv);
+  int			setval (int argc, char **argv);
+  int			unsetval (int argc, char **argv);
+
+  int			test (int argc, char **argv);
+
+#ifdef DEBUG
+  void			ckip (Tcl_Interp *i)	{ assert (i == interp); }
+#endif
+};
+
+class ASN1File
+{
+  const AsnTypeDesc	*type;
+  AsnType		*pdu;
+
+  char			*fn;
+  int			fd;
+  off_t			filesize;
+
+public:
+			ASN1File (const AsnTypeDesc *);
+			ASN1File (const AsnTypeDesc *, const char *fn, int fd);
+  virtual		~ASN1File();
+
+  bool			bad();
+
+			operator AsnType * ()	{ return pdu; }
+
+  int			finfo (Tcl_Interp *);
+
+  int			read (Tcl_Interp *, const char *fn=NULL);
+  int			write (Tcl_Interp *, const char *fn=NULL);
+};
diff --git a/SecuritySNACCRuntime/c++-lib/install-sh b/SecuritySNACCRuntime/c++-lib/install-sh
new file mode 100644
index 00000000..ab74c882
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/SecuritySNACCRuntime/c++-lib/makefile b/SecuritySNACCRuntime/c++-lib/makefile
new file mode 100644
index 00000000..84230b1e
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/makefile
@@ -0,0 +1,326 @@
+# c++-lib/makefile
+#
+#  makes C++ ASN.1 runtime library
+#
+# MS 92
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/makefile,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:05  mb
+# Move from private repository to open source repository
+#
+# Revision 1.3  2000/12/22 00:04:15  dmitch
+# Misc. updates for clean build on Cheetah 1D7.
+#
+# Revision 1.2  2000/05/10 23:38:06  rmurphy
+# Updating makefile  and install related files
+#
+# Revision 1.1.1.1  1999/03/16 18:05:58  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.12  1997/03/13 09:15:05  wan
+# Improved dependency generation for stupid makedepends.
+# Corrected PeekTag to peek into buffer only as far as necessary.
+# Added installable error handler.
+# Fixed small glitch in idl-code generator (Markku Savela <msa@msa.tte.vtt.fi>).
+#
+# Revision 1.11  1997/02/16 16:48:25  rj
+# made return *this after calling abort()'' a compile time option.
+#
+# Revision 1.10  1997/02/15 20:40:26  rj
+# clean/clobber simplified, no recursive call
+#
+# Revision 1.9  1995/09/07  18:44:09  rj
+# snacced.[hC] renamed into tcl-if.[hC],
+# tkXAppInit.c lost its X.
+#
+# asn-useful.asn1 is compiled with the -l 50 option, as recommended by MS in the documentation.
+#
+# Revision 1.8  1995/07/27  08:33:31  rj
+# make $(TCL-P) if necessary.
+#
+# actions for stamp-useful rule: call diff only if both input files exist.
+#
+# Revision 1.7  1995/07/24  15:52:59  rj
+# changed `_' to `-' in file names.
+#
+# useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme.
+#
+# make tcl interface as determined thru the $(TCL-P) utility prog.
+#
+# `cd && make' instead of `cd; make'.
+#
+# create installation directories only if they do not exist already.
+#
+# call make recursively to generate the libraries different dependencies and concatenate them.
+#
+# Revision 1.6  1995/02/20  11:40:24  rj
+# remove stamp-useful before removing asn-useful.[hC].
+# distribute install-sh.
+# use $(INSTALL*) in a for-loop as some install programs (namely the distributed install-sh) only process their first argument!
+#
+# Revision 1.5  1995/02/09  14:03:22  rj
+# enforce generation of inc/asn-useful.h and src/asn-useful.cpp when making dependencies
+#
+# Revision 1.4  1994/10/08  05:27:31  rj
+# don't distribute the non-bootstrapping version of asn-useful.[hc]
+#
+# Revision 1.3  1994/10/08  04:03:19  rj
+# a new asn-useful.[Ch] get generated every time the compiler or asn-useful.asn1 changes.
+#
+# the Tcl interface needs a separate library because conditional compilation and virtual tables don't match otherwise.
+#
+# Revision 1.2  1994/08/31  23:28:41  rj
+# DISTFILES and install phony target added.
+#
+# Revision 1.1  1994/08/28  09:20:22  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../makehead
+include ../makehead.static
+
+DEPENDENCIES	=
+
+TOP		= ..
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+USEFUL_TYPES	= $(ASN1_SRC_DIR)/asn-useful.asn1
+
+CPPFLAGS	+= -Iinc -I$(TOP) $(tcl_def) -F/System/Library/PrivateFrameworks
+
+#
+# hack around broken autoconf and missing makehead
+#
+RANLIB= /usr/bin/ranlib
+TCL-P = $(TOP)/tcl-p
+
+#- #ifdef _IBM_ENC_
+#- # Base directory of snacc11
+#- UserDir=/net/saturn/usr4/GLASS/tools
+#- Snacc11Dir=$(UserDir)/snacc
+#- #
+#- # where ShmMgr is located
+#- ShmMgrDir=/net/saturn/usr4/GLASS/tools/shmmgr
+#- #
+#- # Directories of the HeiTS
+#- # needed to include *.h files and Libs.
+#- HeiTSDir = /u/HeiTS
+#- OSSDir = $(HeiTSDir)/oss
+#- BMSDir = $(HeiTSDir)/bms
+#- MEMDir = $(HeiTSDir)/memmgr
+#- #
+#- # my own .h files for OSS are located at
+#- OwnOSSDir = $(UserDir)/include/HeiTS3.2.6/oss_aix
+#- OwnMemMgrDir = $(UserDir)/include/HeiTS3.2.6/memmgr
+#- #
+#- # OSS include and define for compiling
+#- # HeiTS 3.2.6
+#- HeiTSIncDirs = -I$(OwnOSSDir) -I$(OwnMemMgrDir) -D__AIX_32__ -D__AIX__
+#- # HeiTS 3.2.7
+#- #HeiTSIncDirs = -I$(OwnOSSDir) -I$(OwnMemMgrDir) -D__ALL_SOURCE -D__AIX_32__ -DMMSERV -DDEBUG -DMAP_MANAGEMENT -DMHEG
+#- #
+#- LIB_HDR_DIR = $(Snacc11Dir)/cpp_incl
+#-
+#- CC = xlC
+#- CFLAGS = -c -g -qchars=signed -+ -DIEEE_REAL_FMT -I$(LIB_HDR_DIR) -I$(ShmMgrDir) $(HeiTSIncDirs)
+#- #endif /* _IBM_ENC_ */
+
+HFILES.d = \
+	inc/asn-any.h		\
+	inc/asn-bits.h		\
+	inc/asn-bool.h		\
+	inc/asn-buf.h		\
+	inc/asn-config.h	\
+	inc/asn-enum.h		\
+	inc/asn-incl.h		\
+	inc/asn-int.h		\
+	inc/asn-len.h		\
+	inc/asn-list.h		\
+	inc/asn-null.h		\
+	inc/asn-octs.h		\
+	inc/asn-oid.h		\
+	inc/asn-real.h		\
+	inc/asn-tag.h		\
+	inc/asn-type.h		\
+	inc/hash.h		\
+	inc/init.h		\
+	inc/meta.h		\
+	inc/print.h		\
+	inc/tcl-if.h		\
+	inc/str-stk.h
+
+HFILES = \
+	$(HFILES.d)		\
+	inc/asn-useful.h
+
+HFILES.shared = \
+	$(TOP)/snacc.h		\
+	$(TOP)/config.h		\
+	$(TOP)/policy.h
+
+CFILES.d = \
+	src/asn-any.cpp		\
+	src/asn-bits.cpp		\
+	src/asn-bool.cpp		\
+	src/asn-enum.cpp		\
+	src/asn-int.cpp		\
+	src/asn-len.cpp		\
+	src/asn-list.cpp		\
+	src/asn-null.cpp		\
+	src/asn-octs.cpp		\
+	src/asn-oid.cpp		\
+	src/asn-real.cpp		\
+	src/asn-tag.cpp		\
+	src/asn-type.cpp		\
+	src/hash.cpp		\
+	src/meta.cpp		\
+	src/print.cpp		\
+	src/tcl-if.cpp		\
+	src/str-stk.cpp		\
+	src/tkAppInit.c
+
+CFILES = \
+	$(CFILES.d)		\
+	src/asn-useful.cpp
+
+d	= src
+
+OFILES = \
+	$d/asn-any.o		\
+	$d/asn-bits.o		\
+	$d/asn-bool.o		\
+	$d/asn-enum.o		\
+	$d/asn-int.o		\
+	$d/asn-len.o		\
+	$d/asn-list.o		\
+	$d/asn-null.o		\
+	$d/asn-octs.o		\
+	$d/asn-oid.o		\
+	$d/asn-real.o		\
+	$d/asn-tag.o		\
+	$d/asn-type.o		\
+	$d/asn-useful.o		\
+	$d/hash.o		\
+	$d/meta.o		\
+	$d/print.o		\
+	$d/tcl-if.o		\
+	$d/str-stk.o		\
+	$d/tkAppInit.o
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(HFILES.d)	\
+	$(CFILES.d)
+
+LIB		= libasn1c++.a
+
+#-------------------------------------------------------------------------------
+
+default::	c++-lib tcl-lib
+
+d = dummy
+
+$d::		$(CFILES)
+
+$d::
+		test -d $@ || mkdir $@
+		$(RM) $@/*.[Cc] $@/*.cpp
+		ln $(CFILES) $@
+
+.PHONY:	ofiles lib
+.PHONY:	c++-lib tcl-lib
+
+ofiles:		$(OFILES)
+
+lib:		libasn1$d.a
+
+c++-lib:
+		$(MAKE) d=c++ c++ ofiles lib tcl_def=-DMETA=0
+
+tcl-lib::	$(TCL-P)
+
+tcl-lib::
+		if $(TCL-P); then $(MAKE) d=tcl tcl ofiles lib tcl_def=-DTCL; fi
+
+libasn1c++.a	\
+libasn1tcl.a:	$(OFILES)
+		$(AR) rv $@ $?
+		$(RANLIB) $@
+
+#$(LIB)::	$(CFILES)
+
+inc/asn-useful.h	\
+src/asn-useful.cpp:	stamp-useful
+
+stamp-useful:	$(SNACC) $(USEFUL_TYPES) $(TCL-P)
+		if $(TCL-P); then\
+		  $(SNACC) -C $(SNACC_NOVOLAT) -l 50 -tcl "" $(USEFUL_TYPES);\
+		  $(RM) modules.cpp;\
+		else\
+		  $(SNACC) -C $(SNACC_NOVOLAT) -l 50 $(USEFUL_TYPES);\
+		fi
+# the dates in the two files will differ, so the files really differ if diff prints more than 4 lines of output:
+		@if [ ! -f inc/asn-useful.h ] || [ `diff asn-useful.h inc/asn-useful.h | wc -l` -gt 4 ]; then\
+		  mv asn-useful.h inc/asn-useful.h;\
+		else\
+		  echo "asn-useful.h hasn't changed";\
+		  $(RM) asn-useful.h;\
+		fi
+		@if [ ! -f src/asn-useful.cpp ] || [ `diff asn-useful.cpp src/asn-useful.cpp | wc -l` -gt 4 ]; then\
+		  mv asn-useful.cpp src/asn-useful.cpp;\
+		else\
+		  echo "asn-useful.cpp hasn't changed";\
+		  $(RM) asn-useful.cpp;\
+		fi
+		date > $@
+
+$(SNACC):
+		cd $(@D) && $(MAKE) $(@F)
+
+install-sh:
+		ln $(TOP)/install-sh $@
+
+$(incdir)/snacc/c++ $(libexecdir):
+		$(TOP)/mkinstalldirs $@
+
+install::	$(HFILES) c++-lib tcl-lib install-sh $(incdir)/snacc/c++ $(libexecdir)
+
+install::
+		for h in $(HFILES) $(HFILES.shared); do $(INSTALL_DATA) $$h $(incdir)/snacc/c++/; done
+		for l in $(LIB); do $(INSTALL_DATA) $$l $(libexecdir)/; $(RANLIB) -t $(libexecdir)/$$l; done
+		if [ $d != tcl ]; then $(MAKE) LIB=libasn1tcl.a d=tcl $@; fi
+
+clean::
+		$(RM) stamp-useful
+		$(RM) asn-useful.h inc/asn-useful.h
+		$(RM) asn-useful.cpp src/asn-useful.cpp
+		$(RM) $(OFILES)
+		$(RM) -r c++ tcl
+		$(RM) *.o *~ .emacs* core
+
+clobber::
+		$(RM) libasn1c++.a
+		$(RM) libasn1tcl.a
+		$(RM) install-sh
+
+depend::	inc/asn-useful.h src/asn-useful.cpp
+
+depend::
+		if [ x"$(DEPENDENCIES)" = x ]; then\
+		  $(MAKE) d=c++ c++ DEPENDENCIES=deps.c++ depend;\
+		  if $(TCL-P); then\
+		    $(MAKE) d=tcl tcl tcl_def=-DTCL DEPENDENCIES=deps.tcl depend;\
+		  fi;\
+		  cp /dev/null dependencies;\
+		  for dir in c++ tcl; do\
+		    < deps.$$dir sed -e "s/^src/$$dir/;s/^[a-z-]*\.o:/$$dir\/&/" >> dependencies;\
+		    $(RM) deps.$$dir;\
+		  done;\
+		fi
+
+include ../maketail
diff --git a/SecuritySNACCRuntime/c++-lib/src/asn-useful.cpp b/SecuritySNACCRuntime/c++-lib/src/asn-useful.cpp
new file mode 100644
index 00000000..bf34dbf9
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/src/asn-useful.cpp
@@ -0,0 +1,1487 @@
+/*
+ * 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.
+ */
+
+
+//   NOTE: this is a machine generated file--editing not recommended
+//
+// asn-useful.cpp - class member functions for ASN.1 module ASN-USEFUL
+//
+//   This file was generated by snacc on Wed Jun 14 14:50:26 2000
+//   UBC snacc written by Mike Sample
+//   A couple of enhancements made by IBM European Networking Center
+
+
+#include "asn-incl.h"
+#include "asn-useful.h"
+
+//------------------------------------------------------------------------------
+// value defs
+
+
+//------------------------------------------------------------------------------
+// class member definitions:
+
+AsnType *ObjectDescriptor::Clone() const
+{
+  return new ObjectDescriptor;
+}
+
+AsnType *ObjectDescriptor::Copy() const
+{
+  return new ObjectDescriptor (*this);
+}
+
+AsnLen ObjectDescriptor::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OD_TAG_CODE);
+    return l;
+}
+
+void ObjectDescriptor::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, OD_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, OD_TAG_CODE)))
+    {
+        Asn1Error << "ObjectDescriptor::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 50);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ObjectDescriptor::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ObjectDescriptor::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *UTF8String::Clone() const
+{
+  return new UTF8String;
+}
+
+AsnType *UTF8String::Copy() const
+{
+  return new UTF8String (*this);
+}
+
+AsnLen UTF8String::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, 12);
+    return l;
+}
+
+void UTF8String::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, 12))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, 12)))
+    {
+        Asn1Error << "UTF8String::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 49);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int UTF8String::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int UTF8String::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *NumericString::Clone() const
+{
+  return new NumericString;
+}
+
+AsnType *NumericString::Copy() const
+{
+  return new NumericString (*this);
+}
+
+AsnLen NumericString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE);
+    return l;
+}
+
+void NumericString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE)))
+    {
+        Asn1Error << "NumericString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 48);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int NumericString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int NumericString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *PrintableString::Clone() const
+{
+  return new PrintableString;
+}
+
+AsnType *PrintableString::Copy() const
+{
+  return new PrintableString (*this);
+}
+
+AsnLen PrintableString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+    return l;
+}
+
+void PrintableString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))
+    {
+        Asn1Error << "PrintableString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 47);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int PrintableString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int PrintableString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *TeletexString::Clone() const
+{
+  return new TeletexString;
+}
+
+AsnType *TeletexString::Copy() const
+{
+  return new TeletexString (*this);
+}
+
+AsnLen TeletexString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+}
+
+void TeletexString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error << "TeletexString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 46);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int TeletexString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int TeletexString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *T61String::Clone() const
+{
+  return new T61String;
+}
+
+AsnType *T61String::Copy() const
+{
+  return new T61String (*this);
+}
+
+AsnLen T61String::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+}
+
+void T61String::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error << "T61String::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 45);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int T61String::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int T61String::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *VideotexString::Clone() const
+{
+  return new VideotexString;
+}
+
+AsnType *VideotexString::Copy() const
+{
+  return new VideotexString (*this);
+}
+
+AsnLen VideotexString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE);
+    return l;
+}
+
+void VideotexString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, VIDEOTEXSTRING_TAG_CODE)))
+    {
+        Asn1Error << "VideotexString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 44);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int VideotexString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int VideotexString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *IA5String::Clone() const
+{
+  return new IA5String;
+}
+
+AsnType *IA5String::Copy() const
+{
+  return new IA5String (*this);
+}
+
+AsnLen IA5String::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, IA5STRING_TAG_CODE);
+    return l;
+}
+
+void IA5String::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, IA5STRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, IA5STRING_TAG_CODE)))
+    {
+        Asn1Error << "IA5String::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 43);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int IA5String::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int IA5String::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *GraphicString::Clone() const
+{
+  return new GraphicString;
+}
+
+AsnType *GraphicString::Copy() const
+{
+  return new GraphicString (*this);
+}
+
+AsnLen GraphicString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GRAPHICSTRING_TAG_CODE);
+    return l;
+}
+
+void GraphicString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, GRAPHICSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, GRAPHICSTRING_TAG_CODE)))
+    {
+        Asn1Error << "GraphicString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 42);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int GraphicString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int GraphicString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *VisibleString::Clone() const
+{
+  return new VisibleString;
+}
+
+AsnType *VisibleString::Copy() const
+{
+  return new VisibleString (*this);
+}
+
+AsnLen VisibleString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+}
+
+void VisibleString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error << "VisibleString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 41);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int VisibleString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int VisibleString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *ISO646String::Clone() const
+{
+  return new ISO646String;
+}
+
+AsnType *ISO646String::Copy() const
+{
+  return new ISO646String (*this);
+}
+
+AsnLen ISO646String::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+}
+
+void ISO646String::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error << "ISO646String::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 40);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int ISO646String::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int ISO646String::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *GeneralString::Clone() const
+{
+  return new GeneralString;
+}
+
+AsnType *GeneralString::Copy() const
+{
+  return new GeneralString (*this);
+}
+
+AsnLen GeneralString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALSTRING_TAG_CODE);
+    return l;
+}
+
+void GeneralString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, GENERALSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, GENERALSTRING_TAG_CODE)))
+    {
+        Asn1Error << "GeneralString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 39);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int GeneralString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int GeneralString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *UTCTime::Clone() const
+{
+  return new UTCTime;
+}
+
+AsnType *UTCTime::Copy() const
+{
+  return new UTCTime (*this);
+}
+
+AsnLen UTCTime::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, UTCTIME_TAG_CODE);
+    return l;
+}
+
+void UTCTime::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE)))
+    {
+        Asn1Error << "UTCTime::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 38);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int UTCTime::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int UTCTime::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *GeneralizedTime::Clone() const
+{
+  return new GeneralizedTime;
+}
+
+AsnType *GeneralizedTime::Copy() const
+{
+  return new GeneralizedTime (*this);
+}
+
+AsnLen GeneralizedTime::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    return l;
+}
+
+void GeneralizedTime::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+    {
+        Asn1Error << "GeneralizedTime::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 37);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int GeneralizedTime::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int GeneralizedTime::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *UniversalString::Clone() const
+{
+  return new UniversalString;
+}
+
+AsnType *UniversalString::Copy() const
+{
+  return new UniversalString (*this);
+}
+
+AsnLen UniversalString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, UNIVERSALSTRING_TAG_CODE);
+    return l;
+}
+
+void UniversalString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, UNIVERSALSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, UNIVERSALSTRING_TAG_CODE)))
+    {
+        Asn1Error << "UniversalString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 36);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int UniversalString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int UniversalString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+AsnType *BMPString::Clone() const
+{
+  return new BMPString;
+}
+
+AsnType *BMPString::Copy() const
+{
+  return new BMPString (*this);
+}
+
+AsnLen BMPString::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, BMPSTRING_TAG_CODE);
+    return l;
+}
+
+void BMPString::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, BMPSTRING_TAG_CODE))
+        && (tag != MAKE_TAG_ID (UNIV, CONS, BMPSTRING_TAG_CODE)))
+    {
+        Asn1Error << "BMPString::BDec: ERROR - wrong tag" << endl;
+        longjmp (env, 35);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int BMPString::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int BMPString::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+EXTERNALChoice::EXTERNALChoice()
+{
+  choiceId = single_ASN1_typeCid;
+#if TCL
+  single_ASN1_type = new AsnOcts;
+#else
+  single_ASN1_type = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EXTERNALChoice::EXTERNALChoice (const EXTERNALChoice &)
+{
+  Asn1Error << "use of incompletely defined EXTERNALChoice::EXTERNALChoice (const EXTERNALChoice &)" << endl;
+  abort();
+}
+
+EXTERNALChoice::~EXTERNALChoice()
+{
+  switch (choiceId)
+  {
+    case single_ASN1_typeCid:
+      delete single_ASN1_type;
+      break;
+    case octet_alignedCid:
+      delete octet_aligned;
+      break;
+    case arbitraryCid:
+      delete arbitrary;
+      break;
+  } // end of switch
+} // end of destructor
+
+AsnType *EXTERNALChoice::Clone() const
+{
+  return new EXTERNALChoice;
+}
+
+AsnType *EXTERNALChoice::Copy() const
+{
+  return new EXTERNALChoice (*this);
+}
+
+#if SNACC_DEEP_COPY
+EXTERNALChoice &EXTERNALChoice::operator = (const EXTERNALChoice &that)
+#else // SNACC_DEEP_COPY
+EXTERNALChoice &EXTERNALChoice::operator = (const EXTERNALChoice &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    switch (choiceId)
+    {
+      case single_ASN1_typeCid:
+        delete single_ASN1_type;
+        break;
+      case octet_alignedCid:
+        delete octet_aligned;
+        break;
+      case arbitraryCid:
+        delete arbitrary;
+        break;
+    }
+    switch (choiceId = that.choiceId)
+    {
+      case single_ASN1_typeCid:
+        single_ASN1_type = new AsnOcts;
+        *single_ASN1_type = *that.single_ASN1_type;
+        break;
+      case octet_alignedCid:
+        octet_aligned = new AsnOcts;
+        *octet_aligned = *that.octet_aligned;
+        break;
+      case arbitraryCid:
+        arbitrary = new AsnBits;
+        *arbitrary = *that.arbitrary;
+        break;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EXTERNALChoice &EXTERNALChoice::operator = (const EXTERNALChoice &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EXTERNALChoice::BEncContent (BUF_TYPE b)
+{
+  AsnLen l;
+  switch (choiceId)
+  {
+    case single_ASN1_typeCid:
+      BEncEocIfNec (b);
+      l = single_ASN1_type->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    l += BEncConsLen (b, l);
+
+    l += BEncTag1 (b, CNTX, CONS, 0);
+      break;
+
+    case octet_alignedCid:
+      l = octet_aligned->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 1);
+      break;
+
+    case arbitraryCid:
+      l = arbitrary->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, CNTX, PRIM, 2);
+      break;
+
+  } // end switch
+  return l;
+} // EXTERNALChoice::BEncContent
+
+
+void EXTERNALChoice::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnLen elmtLen1;
+  switch (tag)
+  {
+    case MAKE_TAG_ID (CNTX, CONS, 0):
+      tag = BDecTag (b, bytesDecoded, env);
+      if ((tag != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+          && (tag != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+      {
+         Asn1Error << "Unexpected Tag" << endl;
+         longjmp (env, 34);
+      }
+
+      elmtLen1 = BDecLen (b, bytesDecoded, env);
+      choiceId = single_ASN1_typeCid;
+      single_ASN1_type = new AsnOcts;
+        single_ASN1_type->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+      if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 1):
+    case MAKE_TAG_ID (CNTX, CONS, 1):
+      choiceId = octet_alignedCid;
+      octet_aligned = new AsnOcts;
+        octet_aligned->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    case MAKE_TAG_ID (CNTX, PRIM, 2):
+    case MAKE_TAG_ID (CNTX, CONS, 2):
+      choiceId = arbitraryCid;
+      arbitrary = new AsnBits;
+        arbitrary->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
+      break;
+
+    default:
+      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
+      longjmp (env, 33);
+      break;
+  } // end switch
+} // EXTERNALChoice::BDecContent
+
+
+AsnLen EXTERNALChoice::BEnc (BUF_TYPE b)
+{
+    AsnLen l;
+    l = BEncContent (b);
+    return l;
+}
+
+void EXTERNALChoice::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+    AsnLen elmtLen;
+    AsnTag tag;
+
+    /*  CHOICEs are a special case - grab identifying tag */
+    /*  this allows easier handling of nested CHOICEs */
+    tag = BDecTag (b, bytesDecoded, env);
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecContent (b, tag, elmtLen, bytesDecoded, env);
+}
+
+int EXTERNALChoice::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EXTERNALChoice::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EXTERNALChoice::Print (ostream &os) const
+{
+  switch (choiceId)
+  {
+    case single_ASN1_typeCid:
+      os << "single-ASN1-type ";
+      if (single_ASN1_type)
+        os << *single_ASN1_type;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case octet_alignedCid:
+      os << "octet-aligned ";
+      if (octet_aligned)
+        os << *octet_aligned;
+      else
+        os << "-- void3 --\n";
+      break;
+
+    case arbitraryCid:
+      os << "arbitrary ";
+      if (arbitrary)
+        os << *arbitrary;
+      else
+        os << "-- void3 --\n";
+      break;
+
+  } // end of switch
+} // EXTERNALChoice::Print
+
+EXTERNAL::EXTERNAL()
+{
+  direct_reference = NULL;
+  indirect_reference = NULL;
+  data_value_descriptor = NULL;
+#if TCL
+  encoding = new EXTERNALChoice;
+#else
+  encoding = NULL; // incomplete initialization of mandatory element!
+#endif // TCL
+}
+
+EXTERNAL::EXTERNAL (const EXTERNAL &)
+{
+  Asn1Error << "use of incompletely defined EXTERNAL::EXTERNAL (const EXTERNAL &)" << endl;
+  abort();
+}
+
+EXTERNAL::~EXTERNAL()
+{
+  delete direct_reference;
+  delete indirect_reference;
+  delete data_value_descriptor;
+  delete encoding;
+}
+
+AsnType *EXTERNAL::Clone() const
+{
+  return new EXTERNAL;
+}
+
+AsnType *EXTERNAL::Copy() const
+{
+  return new EXTERNAL (*this);
+}
+
+#if SNACC_DEEP_COPY
+EXTERNAL &EXTERNAL::operator = (const EXTERNAL &that)
+#else // SNACC_DEEP_COPY
+EXTERNAL &EXTERNAL::operator = (const EXTERNAL &)
+#endif // SNACC_DEEP_COPY
+{
+#if SNACC_DEEP_COPY
+  if (this != &that)
+  {
+    if (that.direct_reference)
+    {
+      if (!direct_reference)
+        direct_reference = new AsnOid;
+      *direct_reference = *that.direct_reference;
+    }
+    else
+    {
+      delete direct_reference;
+      direct_reference = NULL;
+    }
+    if (that.indirect_reference)
+    {
+      if (!indirect_reference)
+        indirect_reference = new AsnInt;
+      *indirect_reference = *that.indirect_reference;
+    }
+    else
+    {
+      delete indirect_reference;
+      indirect_reference = NULL;
+    }
+    if (that.data_value_descriptor)
+    {
+      if (!data_value_descriptor)
+        data_value_descriptor = new ObjectDescriptor;
+      *data_value_descriptor = *that.data_value_descriptor;
+    }
+    else
+    {
+      delete data_value_descriptor;
+      data_value_descriptor = NULL;
+    }
+    if (that.encoding)
+    {
+      if (!encoding)
+        encoding = new EXTERNALChoice;
+      *encoding = *that.encoding;
+    }
+    else
+    {
+      delete encoding;
+      encoding = NULL;
+    }
+  }
+
+  return *this;
+#else // SNACC_DEEP_COPY
+  Asn1Error << "use of incompletely defined EXTERNAL &EXTERNAL::operator = (const EXTERNAL &)" << endl;
+  abort();
+  // if your compiler complains here, check the -novolat option
+#endif // SNACC_DEEP_COPY
+}
+
+AsnLen
+EXTERNAL::BEncContent (BUF_TYPE b)
+{
+  AsnLen totalLen = 0;
+  AsnLen l;
+
+    l = encoding->BEncContent (b);
+    totalLen += l;
+
+  if (NOT_NULL (data_value_descriptor))
+  {
+    l = data_value_descriptor->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OD_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (indirect_reference))
+  {
+    l = indirect_reference->BEncContent (b);
+    BEncDefLenTo127 (b, l);
+    l++;
+
+    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    totalLen += l;
+  }
+
+  if (NOT_NULL (direct_reference))
+  {
+    l = direct_reference->BEncContent (b);
+    l += BEncDefLen (b, l);
+
+    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    totalLen += l;
+  }
+
+  return totalLen;
+} // EXTERNAL::BEncContent
+
+
+void EXTERNAL::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag1;
+  AsnLen seqBytesDecoded = 0;
+  AsnLen elmtLen1;
+  tag1 = BDecTag (b, seqBytesDecoded, env);
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    direct_reference = new AsnOid;
+    direct_reference->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    indirect_reference = new AsnInt;
+    indirect_reference->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OD_TAG_CODE))
+    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OD_TAG_CODE)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    data_value_descriptor = new ObjectDescriptor;
+    data_value_descriptor->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+    tag1 = BDecTag (b, seqBytesDecoded, env);
+  }
+
+  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))
+    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 2))
+    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
+  {
+    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
+    encoding = new EXTERNALChoice;
+    encoding->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
+  }
+  else
+  {
+    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
+    longjmp (env, 32);
+  }
+
+  bytesDecoded += seqBytesDecoded;
+  if (elmtLen0 == INDEFINITE_LEN)
+  {
+    BDecEoc (b, bytesDecoded, env);
+    return;
+  }
+  else if (seqBytesDecoded != elmtLen0)
+  {
+    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
+    longjmp (env, 31);
+  }
+  else
+    return;
+} // EXTERNAL::BDecContent
+
+AsnLen EXTERNAL::BEnc (BUF_TYPE b)
+{
+  AsnLen l;
+  l = BEncContent (b);
+  l += BEncConsLen (b, l);
+  l += BEncTag1 (b, UNIV, CONS, EXTERNAL_TAG_CODE);
+  return l;
+}
+
+void EXTERNAL::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
+{
+  AsnTag tag;
+  AsnLen elmtLen1;
+
+  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, EXTERNAL_TAG_CODE))
+  {
+    Asn1Error << "EXTERNAL::BDec: ERROR - wrong tag" << endl;
+    longjmp (env, 30);
+  }
+  elmtLen1 = BDecLen (b, bytesDecoded, env);
+  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
+}
+
+int EXTERNAL::BEncPdu (BUF_TYPE b, AsnLen &bytesEncoded)
+{
+    bytesEncoded = BEnc (b);
+    return !b.WriteError();
+}
+
+int EXTERNAL::BDecPdu (BUF_TYPE b, AsnLen &bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         BDec (b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+void EXTERNAL::Print (ostream &os) const
+{
+  os << "{ -- SEQUENCE --" << endl;
+  indentG += stdIndentG;
+
+  if (NOT_NULL (direct_reference))
+  {
+    Indent (os, indentG);
+    os << "direct-reference ";
+    os << *direct_reference;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "direct-reference ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (indirect_reference))
+  {
+    Indent (os, indentG);
+    os << "indirect-reference ";
+    os << *indirect_reference;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "indirect-reference ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (data_value_descriptor))
+  {
+    Indent (os, indentG);
+    os << "data-value-descriptor ";
+    os << *data_value_descriptor;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "data-value-descriptor ";
+    os << "-- void --";
+    os << "," << endl;
+  }
+
+  if (NOT_NULL (encoding))
+  {
+    Indent (os, indentG);
+    os << "encoding ";
+    os << *encoding;
+  }
+  else
+  {
+    Indent (os, indentG);
+    os << "encoding ";
+    os << "-- void --";
+    os << endl;
+  }
+
+  os << endl;
+  indentG -= stdIndentG;
+  Indent (os, indentG);
+  os << "}";
+} // EXTERNAL::Print
+
+
diff --git a/SecuritySNACCRuntime/c++-lib/src/cdsaUtils.cpp b/SecuritySNACCRuntime/c++-lib/src/cdsaUtils.cpp
new file mode 100644
index 00000000..d9b9fc82
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/src/cdsaUtils.cpp
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * cdsaUtils.cpp - utility functions for CDSA-related code
+ */
+
+#include "cdsaUtils.h"
+#include <Security/cssmerr.h>
+
+#ifdef	NDEBUG
+
+#include <Security/globalizer.h>
+
+/* silent cerr substitute */
+ModuleNexus<Asn1ErrorClass> AsnNullError;
+#endif	/* NDEBUG */
+
+/* malloc/copy AsnBits.bits -->CssmOwnedData */
+void SC_asnBitsToCssmData(
+	const AsnBits &bits,
+	CssmOwnedData &oData)
+{
+	size_t len = (bits.BitLen() + 7) / 8;
+	oData.copy(reinterpret_cast<const uint8 *>(bits.BitOcts()), len);
+}
+
+/* given DER-encoded bit string, decoded it and malloc/copy results 
+ * back to a CssmOwnedData */
+void SC_decodeAsnBitsToCssmData(
+	const CssmData encodedBits,
+	CssmOwnedData &oData)
+{
+	AsnBits decodedBits;
+	SC_decodeAsnObj(encodedBits, decodedBits);
+	size_t len = (decodedBits.BitLen() + 7) / 8;
+	oData.copy(reinterpret_cast<const uint8 *>(decodedBits.BitOcts()), len);
+}
+
+/*
+ * Universal BDecPdu/BEncPdu replacements, used below in SC_decodeAsnObj and
+ * SC_encodeAsnObj.
+ *
+ * All AsnType subclasses implement this either via PDU_MEMBER_MACROS
+ * for SecuritySNACCRuntime built-in types, or explicitly for all
+ * other classes using asn-useful.h. To faciliate a global "one
+ * routine for encode/decode" which operattes on AsnType &'s, we have 
+ * to explicitly provide this here. Why this is no in AsnType, I don't 
+ * know.
+ */
+static int SC_BDecPDU(
+	AsnType 	&asnObj, 
+	BUF_TYPE 	b, 
+	AsnLen 		&bytesDecoded)
+{
+    ENV_TYPE env;
+    int val;
+
+    bytesDecoded = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+         asnObj.BDec(b, bytesDecoded, env);
+         return !b.ReadError();
+    }
+    else
+        return false;
+}
+
+static int SC_BEncPdu(
+	AsnType		&asnObj,
+	BUF_TYPE 	b, 
+	AsnLen 		&bytesEncoded)
+{
+    bytesEncoded = asnObj.BEnc(b);
+    return !b.WriteError();
+}
+
+/* DER-decode any AsnType object */
+void SC_decodeAsnObj(
+	const CssmData		&derEncoded,
+	AsnType				&asnObj)
+{
+	AsnBuf					buf;
+	size_t					len = (size_t)derEncoded.length();
+	
+	buf.InstallData(reinterpret_cast<char *>(derEncoded.data()), len);
+	if(!SC_BDecPDU(asnObj, buf, len)) {
+		CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+	}
+}
+
+/* 
+ * DER-encode any AsnType object.
+ * Unfortunately the call has to give an estimate of the max encoded size of 
+ * the result. There is no way (that I know of) to figure this out at encode
+ * time. If this turns out to be a problem we might have to do a retry,
+ * doubling the size of the encoded buffer. Be liberal; the maxEncodedSize
+ * buffer is only temporary - due to snacc encoding style, a copy out is 
+ * necessary in any case, so the mallocd size of encodedBuf is exactly the
+ * right size. 
+ */
+void SC_encodeAsnObj(
+	AsnType				&asnObj,
+	CssmOwnedData		&derEncoded,
+	size_t				maxEncodedSize)
+{
+	CssmAutoData aData(derEncoded.allocator);		// temp encode target
+	aData.malloc(maxEncodedSize);
+	memset(aData.data(), 0, maxEncodedSize);
+	AsnBuf encBuf;
+	encBuf.Init(static_cast<char *>(aData.data()), maxEncodedSize);
+	encBuf.ResetInWriteRvsMode();
+	AsnLen encoded;
+	int rtn = SC_BEncPdu(asnObj, encBuf, encoded);
+	if(encoded > maxEncodedSize) {
+		CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL);
+	}
+	if(!rtn) {
+		/* not sure how this can happen... */
+		CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL);
+	}
+	/* success; copy out to caller */
+	derEncoded.get().clear();
+	derEncoded.copy(encBuf.DataPtr(), encBuf.DataLen());
+}
+
+/*
+ * Given a contentLength, obtain the length of the DER length encoding.
+ */
+size_t SC_lengthOfLength(
+	size_t contentLen)
+{
+	if(contentLen < 128) {
+		return 1;	
+	}
+	else if(contentLen < 256) {
+		return 2;
+	}
+	else if(contentLen < 65536) {
+		return 3;
+	}
+	else if(contentLen < 16777126) {
+		return 4;
+	}
+	else {
+		return 5;
+	}
+}
+
+/*
+ * Encode a DER length field. Pass in the lengthOfLength if you've obtained
+ * it in a previous call to SC_lengthOfLength.
+ */
+void SC_encodeLength(
+	size_t 	contentLen,
+	void 	*cp,
+	size_t	lengthOfLength)
+{
+	if(lengthOfLength == 0) {
+		lengthOfLength = SC_lengthOfLength(contentLen);
+	}
+	unsigned char *ucp = reinterpret_cast<unsigned char *>(cp);
+	if(lengthOfLength == 1) {
+		/* easy case */
+		*ucp = contentLen;
+		return;
+	}
+	lengthOfLength--;
+	*ucp = (0x80 + lengthOfLength);
+	ucp += lengthOfLength;
+	for(size_t i=0; i<lengthOfLength; i++) {
+		*ucp-- = contentLen & 0xff;
+		contentLen >>= 8;
+	}
+}
diff --git a/SecuritySNACCRuntime/c++-lib/src/sm_buffer.cpp b/SecuritySNACCRuntime/c++-lib/src/sm_buffer.cpp
new file mode 100644
index 00000000..68f9ae96
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/src/sm_buffer.cpp
@@ -0,0 +1,896 @@
+/*
+ * 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.
+ */
+
+#ifndef	__APPLE__
+#ifndef NO_SCCS_ID
+static char SccsId[ ] = "@(#) sm_buffer.cpp 1.17 5/7/98 16:36:20"; 
+#endif
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+// sm_buffer.cpp
+// This source file implements various members of the CSM_Buffer class.
+// Be careful when you modify these
+// members because code is being written based on the characteristics
+// of these members...
+//////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#if !defined(macintosh) && !defined(__APPLE__)
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include <string.h>
+
+#ifdef SUNOS     
+#include <unistd.h>   // for SEEK_CUR and SEEK_END
+#endif
+
+#include "sm_vdasnacc.h"
+#include <iomanip>
+
+#if	defined(macintosh) || defined(__APPLE__)
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+#define SME_SETUP(A)  try {
+#define SME_THROW(A, B, C)  throw(static_cast<SM_RET_VAL>(A))
+#define SME_FINISH }
+#define SME_CATCH_SETUP catch(SM_RET_VAL) {
+#define SME_CATCH_FINISH }
+#define SM_RET_VAL  long
+#define SM_NO_ERROR  0
+#define SME_FINISH_CATCH } catch(SM_RET_VAL) {}
+#define SME(S)  S
+
+#define SM_MEMORY_ERROR memFullErr
+#define SM_MISSING_PARAM paramErr
+#define SM_FILEIO_ERROR ioErr
+
+#else
+
+#define SME_SETUP(A)  do {} while (0)
+#define SME_THROW(A, B, C)  do {} while (0)
+#define SME_FINISH
+#define SME_CATCH_SETUP
+#define SME_CATCH_FINISH
+#define SM_RET_VAL  long
+#define SM_NO_ERROR  0
+#define SME_FINISH_CATCH
+#define SME(S)  S
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+void CSM_Buffer::Clear()
+{
+   m_lSize = 0;
+   m_pMemory = NULL;
+#if	!defined(macintosh) && !defined(__APPLE__)
+   m_pszFN = NULL;
+   m_pFP = NULL;
+#endif
+   m_pMemFP = NULL;
+   m_pCache = NULL;
+   m_lCacheSize = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CSM_Buffer::CSM_Buffer()
+{ 
+   SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)");
+
+   Clear();
+
+   if ((m_pMemory = (char *)calloc(1, 1)) == NULL)
+      SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+   SME(SetLength(0));
+
+   SME_FINISH_CATCH
+}
+
+//////////////////////////////////////////////////////////////////////////
+CSM_Buffer::CSM_Buffer(size_t lSize)
+{ 
+   SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)");
+
+   Clear();
+
+   if ((m_pMemory = (char *)calloc(1, lSize + 1)) == NULL)
+      SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+   SME(SetLength(lSize));
+
+   SME_FINISH_CATCH
+}
+
+//////////////////////////////////////////////////////////////////////////
+#if !defined(macintosh) && !defined(__APPLE__)
+CSM_Buffer::CSM_Buffer(char *pszFileName)
+{
+   SME_SETUP("CSM_Buffer::CSM_Buffer(char*)");
+
+   Clear();
+
+   if (pszFileName == NULL)
+      SME_THROW(SM_MISSING_PARAM, NULL, NULL);
+
+   if ((m_pszFN = strdup(pszFileName)) == NULL)
+      SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+
+   SME_FINISH_CATCH
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+CSM_Buffer::CSM_Buffer(const char *pBuf, SM_SIZE_T lSize) 
+{
+   SME_SETUP("CSM_Buffer::CSM_Buffer(char *, size_t)");
+
+   Clear();
+
+   if (pBuf == NULL)
+      SME_THROW(SM_MISSING_PARAM, NULL, NULL);
+
+   SME(Set(pBuf, lSize));
+
+   SME_FINISH_CATCH
+}
+
+//////////////////////////////////////////////////////////////////////////
+CSM_Buffer::CSM_Buffer(const CSM_Buffer &b) 
+{
+   SME_SETUP("CSM_Buffer::CSM_Buffer(CSM_Buffer&)");
+
+   Clear();
+
+   SME(ReSet(b));
+
+   SME_FINISH_CATCH
+}
+
+//////////////////////////////////////////////////////////////////////////
+CSM_Buffer::~CSM_Buffer()
+{
+   if (m_pMemory)
+      free (m_pMemory);
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (m_pszFN)
+      free (m_pszFN);
+   if (m_pFP)
+      fclose(m_pFP);
+#endif
+   if (m_pCache)
+      free (m_pCache);
+}
+
+//////////////////////////////////////////////////////////////////////////
+SM_SIZE_T CSM_Buffer::Length() const
+{
+   SM_SIZE_T lRet = 0;
+
+   SME_SETUP("CSM_Buffer::Length");
+
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (InFile())
+   {
+      // file version
+      struct stat statBuf;
+      // how big is data in file
+      if (stat(m_pszFN, &statBuf) == -1)
+      {
+         char szMsg[512];
+         sprintf(szMsg, "Couldn't stat file %s", m_pszFN);
+         SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
+      }
+      lRet = statBuf.st_size;
+   }
+   else
+#endif
+   {
+      // memory version
+      lRet = m_lSize;
+   }
+
+   SME_FINISH_CATCH
+
+   return lRet;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSM_Buffer::Set(const char *psz)
+{
+   SME_SETUP("CSM_Buffer::Set(char *)");
+   if (psz == NULL)
+      SME_THROW(SM_MISSING_PARAM, NULL, NULL);
+   if (m_pMemory)
+      free(m_pMemory);
+#if !defined(macintosh) && !defined(__APPLE__)
+   int len = strlen(psz);
+   m_pMemory = (char*)malloc(len + 1);
+   if (m_pMemory == NULL)
+      SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+   strcpy(m_pMemory, psz);
+   SME(SetLength(len));
+#else
+   if ((m_pMemory = strdup(psz)) == NULL)
+      SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+   SME(SetLength(strlen(psz)));
+#endif
+   SME_FINISH_CATCH
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSM_Buffer::Set(const char *p, SM_SIZE_T lSize)
+{
+   SME_SETUP("CSM_Buffer::Set(char *, size_t)");
+   if (m_pMemory)
+      free(m_pMemory);
+
+   if (p == NULL)
+   {
+      m_pMemory = NULL;
+      SME(SetLength(0));
+   }
+   else
+   {
+      m_pMemory = (char *)calloc(1, lSize + 1);
+      if (m_pMemory == NULL)
+         SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+      memcpy(m_pMemory, p, lSize);
+      SME(SetLength(lSize));
+   }
+   SME_FINISH_CATCH
+}
+
+//////////////////////////////////////////////////////////////////////////
+// allocate memory in the cache
+char* CSM_Buffer::Alloc(SM_SIZE_T lSize)
+{
+   SME_SETUP("CSM_Buffer::Alloc");
+
+   if (m_pCache)
+      free(m_pCache);
+   if ((m_pCache = (char *)calloc(1, lSize)) == NULL)
+      SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+   m_lCacheSize = lSize;
+
+   SME_FINISH_CATCH
+
+   return m_pCache;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSM_Buffer::AllocMoreMem(SM_SIZE_T lSize)
+{
+   char *pNew;
+   SM_SIZE_T lLength = Length();
+
+   SME_SETUP("CSM_Buffer::AllocMoreMem");
+
+   if ((pNew = (char *)calloc(1, lLength + lSize)) == NULL)
+      SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+   memcpy(pNew, m_pMemory, lLength);
+   SetLength(lLength + lSize);
+   m_pMemFP = pNew + (m_pMemFP - m_pMemory);
+   free(m_pMemory);
+   m_pMemory = pNew;
+
+   SME_FINISH_CATCH
+}
+
+//////////////////////////////////////////////////////////////////////////
+const char* CSM_Buffer::Access() const
+{
+   SME_SETUP("CSM_Buffer::Access");
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (InFile())
+   {
+      // if the data is in a file AND
+      // if there's already memory in m_pMemory then free it
+      if (m_pMemory != NULL)
+         free (m_pMemory);
+      SME(m_pMemory = Get());
+   }
+#endif
+   SME_FINISH_CATCH
+   return m_pMemory;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// return a copy of the actual data and return the size
+char* CSM_Buffer::Get(SM_SIZE_T &l) const
+{
+   char *pRet = NULL;
+   SME_SETUP("CSM_Buffer::Get");
+
+   SM_SIZE_T lSize = Length();
+
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (InFile()) // data in file
+   {
+      // allocate memory
+      if ((pRet = (char *)calloc(1, lSize + 1)) == NULL)
+         SME_THROW(SM_MEMORY_ERROR, "calloc failure", NULL);
+      // close file if present
+      if (m_pFP != NULL)
+         fclose(m_pFP);
+      // open the file
+      if ((m_pFP = fopen(m_pszFN, SM_FOPEN_READ)) == NULL)
+      {
+         char szMsg[512];
+         sprintf(szMsg, "Couldn't open file %s", m_pszFN);
+         SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
+      }
+      // read the data
+      long lRead = fread(pRet, 1, lSize, m_pFP);
+      if (ferror(m_pFP) != 0)
+      {
+         char szMsg[512];
+         sprintf(szMsg, "Couldn't read file %s", m_pszFN);
+         SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
+      }
+      // close and clear FP
+      fclose(m_pFP);
+      m_pFP = NULL;
+      l = lRead; // store the size that will be returned
+   }
+   else
+#endif
+   {
+      // if there is data, duplicate it
+      if (m_pMemory)
+      {
+         pRet = (char *)calloc(1, lSize);
+         memcpy(pRet, m_pMemory, lSize);
+         l = lSize; // store the size that will be returned
+      }
+   }
+
+   SME_FINISH
+   SME_CATCH_SETUP
+      if (pRet != NULL)
+      {
+         free(pRet);
+         pRet = NULL;
+	  }
+#if !defined(macintosh) && !defined(__APPLE__)
+      if (m_pFP != NULL)
+      {
+         fclose(m_pFP);
+         m_pFP = NULL;
+      }
+#endif
+   SME_CATCH_FINISH
+   return pRet;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// compare buffers regardless of memory/file status
+long CSM_Buffer::Compare(const CSM_Buffer &b)
+{
+   const char *p1 = NULL;
+   const char *p2 = NULL;
+   long lRet = -2;
+
+   SME_SETUP("CSM_Buffer::Compare");
+   // use AccessAll on both buffers for comparison.  If buffer is in
+   // file, then this results in a CopyAll which isn't as efficient,
+   // but this can be fixed later...
+   if ((p1 = Access()) != NULL)
+   {
+      if ((p2 = b.Access()) != NULL)
+      {
+         if (Length() == b.Length())
+            lRet = (long)memcmp(p1, p2, Length());
+         // p1 and p2 are the same as the memory pointers in
+         // the buffers so they do not need to be freed, they
+         // will be freed by the buffer's destructor
+      }
+#if !defined(macintosh) && !defined(__APPLE__)
+      else
+         if (InFile()) 
+            free (p1);
+#endif
+   }
+   SME_FINISH_CATCH
+   return lRet;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// copy b into this
+SM_RET_VAL CSM_Buffer::ReSet(const CSM_Buffer &b)
+{
+   char *p;
+   SM_SIZE_T l;
+   SME_SETUP("CSM_Buffer::ReSet");
+
+#if !defined(macintosh) && !defined(__APPLE__)
+	m_pszFNP = NULL;
+   m_pFP = NULL;
+#endif
+   if (m_pMemory)
+      free(m_pMemory);
+
+   m_pMemory = m_pMemFP = NULL;
+   SME(SetLength(0));
+   m_pCache = NULL;
+   m_lCacheSize = 0;
+   
+   SME(p = b.Get(l));
+
+   SME(Set(p, l));
+
+   free(p);
+
+   SME_FINISH_CATCH
+
+   return SM_NO_ERROR;
+}
+
+#if !defined(macintosh) && !defined(__APPLE__)
+//////////////////////////////////////////////////////////////////////////
+// ConvertFileToMemory makes a CSM_Buffer storing its contents in
+// file into a CSM_Buffer storing its contents in memory
+SM_RET_VAL CSM_Buffer::ConvertFileToMemory()
+{
+   SM_SIZE_T l;
+
+   SME_SETUP("CSM_Buffer::ConvertFileToMemory");
+
+   if (m_pszFN == NULL)
+      // we're already in memory
+      return SM_NO_ERROR;
+
+   // read everything into memory
+   SME(m_pMemory = Get(l));
+
+   // free the file name
+   free(m_pszFN);
+   m_pszFN = NULL;
+
+   // store the new size
+   SME(SetLength(l));
+
+   SME_FINISH_CATCH
+
+   return SM_NO_ERROR;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// ConvertMemoryToFile makes a CSM_Buffer storing its contents in
+// buffer into a CSM_Buffer storing its contents in file
+SM_RET_VAL CSM_Buffer::ConvertMemoryToFile(char *pszFN)
+{
+   SM_SIZE_T lRet = 0;
+
+   SME_SETUP("CSM_Buffer::ConvertMemoryToFile");
+
+   if (pszFN == NULL)
+      SME_THROW(SM_NO_FILENAME, NULL, NULL);
+
+   if (InFile())
+   {
+     if (strcmp(m_pszFN, pszFN) == 0)   // we're already in file
+        return SM_NO_ERROR;
+     else
+     {
+        SM_SIZE_T lBytesRead;
+        SM_SIZE_T lSize=4096;
+        char *ptr;
+        FILE *fp=fopen(pszFN, "w");
+        this->Open(SM_FOPEN_READ);
+        while ((ptr=this->nRead(lSize, lBytesRead)) != NULL && lBytesRead > 0)
+        {
+            fwrite(ptr, 1, lBytesRead, fp);
+        }
+        this->Close();
+        fclose(fp);
+        return(SM_NO_ERROR);
+     }
+   }
+
+   // open the new file
+   if ((m_pFP = fopen(pszFN, SM_FOPEN_WRITE)) == NULL)
+   {
+      char szMsg[512];
+      sprintf(szMsg, "Couldn't stat file %s", pszFN);
+      SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
+   }
+
+   // write the data
+   SM_SIZE_T lLength = Length();
+   // store the file name
+   if ((m_pszFN = strdup(pszFN)) == NULL)
+      SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+
+   if ((lRet = fwrite(m_pMemory, 1, lLength, m_pFP)) != lLength)
+   {
+      char szMsg[512];
+      sprintf(szMsg, "Couldn't write file %s", m_pszFN);
+      SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
+   }
+
+   fclose(m_pFP);
+   m_pFP = NULL;
+
+   SME_FINISH
+   SME_CATCH_SETUP
+      // cleanup/catch code
+      if ((m_pszFN != NULL) && (pszFN != NULL))
+      {
+         free(m_pszFN);
+         m_pszFN = NULL;
+      }
+   SME_CATCH_FINISH
+
+   return SM_NO_ERROR;
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+SM_RET_VAL CSM_Buffer::Open(char *pszMode)
+{
+   SME_SETUP("CSM_Buffer::Open");
+
+   if (pszMode == NULL)
+      SME_THROW(SM_MISSING_PARAM, NULL, NULL);
+
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (!InFile())
+#endif
+      // memory version
+      m_pMemFP = m_pMemory; // set current pointer to start
+#if !defined(macintosh) && !defined(__APPLE__)
+   else
+      // file version
+      if ((m_pFP = fopen(m_pszFN, pszMode)) == NULL)
+      {
+         char szMsg[512];
+         sprintf(szMsg, "Couldn't open file %s", m_pszFN);
+         SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
+      }
+#endif
+
+   SME_FINISH_CATCH
+   return SM_NO_ERROR;
+}
+
+//////////////////////////////////////////////////////////////////////////
+SM_RET_VAL CSM_Buffer::Seek(SM_SIZE_T lOffset, SM_SIZE_T lOrigin)
+{
+   SM_RET_VAL lRet = SM_NO_ERROR;
+
+   SME_SETUP("CSM_Buffer::Seek");
+
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (!InFile())
+#endif
+   {
+      // memory version
+      char *pSave = m_pMemFP;
+
+      if (m_pMemFP == NULL)
+         SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+
+      SM_SIZE_T lLength = Length();
+
+      switch (lOrigin)
+      {
+      case SEEK_CUR:
+         m_pMemFP += lOffset;
+         break;
+      case SEEK_END:
+         m_pMemFP = (m_pMemory + lLength - 1) + lOffset;
+         break;
+      default: // SEEK_SET
+         m_pMemFP = m_pMemory + lOffset;
+         break;
+      }
+      if ((m_pMemFP > (m_pMemory + lLength - 1)) ||
+          (m_pMemFP < m_pMemory))
+      {
+         m_pMemFP = pSave;
+         lRet = -1;
+      }
+   }
+#if !defined(macintosh) && !defined(__APPLE__)
+   else
+   {
+      // file version
+      if (m_pFP == NULL)
+         SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
+
+      lRet = fseek(m_pFP, lOffset, lOrigin);
+   }
+#endif
+
+   SME_FINISH_CATCH
+
+   return lRet;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSM_Buffer::Close()
+{
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (m_pFP != NULL)
+   {
+      fclose(m_pFP);
+      m_pFP = NULL;
+      if (m_pMemory)
+      {
+         free(m_pMemory);
+         m_pMemory = NULL;
+      }
+   }
+   else
+#endif
+		m_pMemFP = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AsnType *CSM_Buffer::Clone() const
+{
+  return new CSM_Buffer;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AsnType *CSM_Buffer::Copy() const
+{
+  return new CSM_Buffer (*this);
+}
+
+//////////////////////////////////////////////////////////////////////////
+AsnLen CSM_Buffer::BEnc(BUF_TYPE BBuf)
+{
+    char *ptr;
+    unsigned int jj=0;
+    SM_SIZE_T lRead=1;
+    SM_SIZE_T lOffset;
+
+    this->Open(SM_FOPEN_READ);
+    for (jj = 0; jj < this->Length() && lRead > 0; jj += lRead)
+    {
+        if (jj == 0)    // first time, only get last X bytes within 4096 block.
+        {
+            lOffset = this->Length() - (this->Length() % 4096);
+        }
+        else 
+            lOffset -= 4096;
+         this->Seek(lOffset, 0);
+         ptr = this->nRead(4096, lRead);
+         BBuf.PutSegRvs(ptr, lRead);
+    }
+    this->Close();
+
+	return this->Length();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSM_Buffer::Print (ostream &os) const
+{
+#ifndef	NDEBUG
+	int len = Length();
+	int i;
+
+	os << "{ -- ANY --" << endl;
+	indentG += stdIndentG;
+    Indent (os, indentG);
+
+	long oFlags = os.flags();
+	os << hex;
+	for (i = 0; i < len; i++)
+	{
+		os << setw(2) << setfill('0') 
+			<< static_cast<unsigned int>(static_cast<unsigned char>(m_pMemory[i])) << " ";
+
+		if (i == len - 1 || i % 16 == 15)
+		{
+			int j;
+			os << "  ";
+			for (j = i > 15 ? i - 15 : 0; j <= i; j++)
+			{
+				if (m_pMemory[j] >= 0x20 && m_pMemory[j] < 0x80)
+					os << m_pMemory[j];
+				else
+					os << '.';
+			}
+			os << endl;
+		}
+	}
+
+	os.flags(oFlags);
+	os << endl;
+	indentG -= stdIndentG;
+	Indent (os, indentG);
+	os << "}";
+#endif	NDEBUG
+}
+
+//////////////////////////////////////////////////////////////////////////
+SM_RET_VAL CSM_Buffer::cRead(char *pBuffer, SM_SIZE_T lSize)
+{
+   SM_RET_VAL lRet = 0;
+
+   SME_SETUP("CSM_Buffer::cRead");
+
+   if ((pBuffer == NULL) || (lSize <= 0))
+      SME_THROW(SM_MISSING_PARAM, NULL, NULL);
+
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (!InFile())
+#endif
+   {
+      // memory version
+      if (m_pMemFP == NULL)
+         SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+
+      SM_SIZE_T lReadSize = lSize;
+      SM_SIZE_T lLength = Length();
+      // adjust the read size to what's possible
+      if ((m_pMemFP + lReadSize) > (m_pMemory + lLength))
+         lReadSize = (m_pMemory + lLength) - m_pMemFP;
+      memcpy(pBuffer, m_pMemFP, lReadSize);
+      // adjust the current pointer
+      if (lReadSize > 0)
+      {
+         m_pMemFP += lReadSize;
+         lRet = lReadSize;
+      }
+      else
+         lRet = 0;
+   }
+#if !defined(macintosh) && !defined(__APPLE__)
+   else
+   {
+      // file version
+      if (m_pFP == NULL)
+         SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
+
+      lRet = fread(pBuffer, 1, lSize, m_pFP);
+   }
+#endif
+
+   SME_FINISH_CATCH
+
+   return lRet;
+}
+
+//////////////////////////////////////////////////////////////////////////
+SM_RET_VAL CSM_Buffer::Write(const char *pBuffer, SM_SIZE_T lSize)
+{
+   SM_RET_VAL lRet = 0;
+
+   SME_SETUP("CSM_Buffer::Write");
+
+   if ((pBuffer == NULL) || (lSize <= 0))
+      SME_THROW(SM_MISSING_PARAM, NULL, NULL);
+
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (!InFile())
+#endif
+   {
+      // memory version
+      if (m_pMemFP == NULL)
+      {
+         if (m_pMemory == NULL)
+         {
+            // if we get here, we assume that the memory
+            // hasn't been allocated yet, allocate it...
+            if ((m_pMemFP = m_pMemory = (char *)calloc(1, lSize)) == NULL)
+               SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+            SetLength(lSize);
+         }
+         else
+            m_pMemFP = m_pMemory;
+      }
+
+      // do we have enough space to write to this buffer?
+      if ((SM_SIZE_T)(((m_pMemory + Length()) - m_pMemFP)) < lSize)
+         // nope, get lSize more bytes
+         AllocMoreMem(lSize);
+      memcpy(m_pMemFP, pBuffer, lSize);
+      m_pMemFP += lSize;
+      lRet = lSize;
+   }
+#if !defined(macintosh) && !defined(__APPLE__)
+   else
+   {
+      // file version
+      if (m_pFP == NULL)
+         SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
+
+      if ((lRet = fwrite(pBuffer, 1, lSize, m_pFP)) > 0)
+         SetLength(m_lSize + lRet);
+   }
+#endif
+
+   SME_FINISH_CATCH
+
+   return lRet;
+}
+
+//////////////////////////////////////////////////////////////////////////
+char* CSM_Buffer::nRead(SM_SIZE_T lSize, SM_SIZE_T &lBytesRead)
+{
+   char *pRet = NULL;
+
+   SME_SETUP("CSM_Buffer::nRead");
+
+   if (lSize <= 0)
+      SME_THROW(SM_MISSING_PARAM, NULL, NULL);
+
+#if !defined(macintosh) && !defined(__APPLE__)
+   if (!InFile())
+#endif
+   {
+      // memory version
+      if (m_pMemFP == NULL)
+         SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+
+      SM_SIZE_T lReadSize = lSize;
+      SM_SIZE_T lLength = Length();
+      // adjust the read size to what's possible
+      if ((m_pMemFP + lReadSize) > (m_pMemory + lLength))
+         lReadSize = (m_pMemory + lLength) - m_pMemFP;
+      pRet = m_pMemFP;
+      // adjust the current pointer
+      if (lReadSize > 0)
+      {
+         m_pMemFP += lReadSize;
+         lBytesRead = lReadSize;
+      }
+      else
+         lBytesRead = 0;
+   }
+#if !defined(macintosh) && !defined(__APPLE__)
+   else
+   {
+      // file version
+      if (m_pFP == NULL)
+         SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
+      // if there's something already in the memory, free it
+      if (m_pMemory != NULL)
+         free (m_pMemory);
+      // allocate memory to receive the read data
+      if ((m_pMemory = (char *)calloc(1, lSize + 1)) == NULL)
+         SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
+      // now, read into the memory cache
+      lBytesRead = fread(m_pMemory, 1, lSize, m_pFP);
+      // now set what we'll return
+      pRet = m_pMemory;
+   }
+#endif
+
+   SME_FINISH_CATCH
+
+   return pRet;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSM_Buffer::Flush()
+{
+   if (m_pCache != NULL)
+   {
+      Write(m_pCache, m_lCacheSize);
+      free(m_pCache);
+      m_pCache = NULL;
+      m_lCacheSize = 0;
+   }
+}
+
+// EOF sm_buffer.cpp
diff --git a/SecuritySNACCRuntime/c++-lib/src/sm_vdasnacc.cpp b/SecuritySNACCRuntime/c++-lib/src/sm_vdasnacc.cpp
new file mode 100644
index 00000000..b7461f37
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/src/sm_vdasnacc.cpp
@@ -0,0 +1,560 @@
+/*
+ * 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.
+ */
+
+#ifndef	__APPLE__
+#ifndef NO_SCCS_ID
+static char SccsId[ ] = "@(#) sm_vdasnacc.cpp 1.18 6/1/98 11:07:01"; 
+#endif
+#endif
+
+/**
+  vdasnacc.CPP
+  This file handles any additional miscellaneous routines to support
+  the integration of the MSP into SNACC environment.
+  ***/
+
+//#include "sm_api.h"
+#include "sm_vdasnacc.h"
+#include "sm_vdatypes.h"
+
+long vdasnacc_sortSetTag(
+    CSM_Buffer *pEncBuf[],      // IN/OUT, buffer to sort
+    int start_index,            // IN, start index for sort.
+    int icount,                 // IN, size of array.
+    int tag);                    // IN, tag to place.
+long SM_DetermineLengthBuf(AsnBuf &SNACCinputBuf);
+
+
+/** This function sorts the specified "Str_struct" array in reverse order.
+    This is done for the "Set Of" ASN.1 ordering.  The ASN.1 components will 
+    be loaded in ascending order; they will be loaded in the reverse order
+    of this array (hence, we load them in descending order).
+***/
+long vdasnacc_sortSetOf(CSM_Buffer **&pEncBuf, int icount)
+{
+    long status=0;
+    int lessCount;
+    int i,j;
+    int l1,l2;
+    const char *ptr1,*ptr2;
+    CSM_Buffer *tmpEnc;
+
+    for (i=0; i < icount; i++)
+    {
+        for (j=i+1; j < icount; j++)  /** always start with present "i". **/
+        {
+            ptr1 = pEncBuf[i]->Access();
+            ptr2 = pEncBuf[j]->Access();
+            l1 = pEncBuf[i]->Length(); 
+            l2 = pEncBuf[j]->Length(); 
+            if (l1 < l2)
+                lessCount = l1;
+            else
+                lessCount = l2;
+            if (memcmp(ptr1, ptr2, lessCount) < 0 ||
+               (memcmp(ptr1, ptr2, lessCount) == 0 &&
+                l1 < l2)) /** check if = with more */
+            {   /** SWITCH buffers so that greater is first. **/
+                tmpEnc = pEncBuf[i];
+                pEncBuf[i] = pEncBuf[j];
+                pEncBuf[j] = tmpEnc;
+            }
+        }
+
+    }
+
+
+    return(status);
+}
+
+
+/** This function sorts the specified "Str_struct" array in reverse order.
+    This is done for the "Set" ASN.1 ordering.  The ASN.1 components will 
+    be loaded in ascending order; they will be loaded in the reverse order
+    of this array (hence, we load them in descending order).  The SET ordering
+    is based on the lower 5 bits of the tag item (guaranteed to be unique 
+    based on the ASN.1 definition of a SET).  This is based on the ISO rules.
+***/
+#define ASN_UNIVERSAL   0x00
+#define ASN_APPLICATION 0x40
+#define ASN_CONTEXT     0x80
+#define ASN_PRIVATE     0xC0
+long vdasnacc_sortSet(CSM_Buffer *pEncBuf[], int icount)
+{
+    long status=0;
+    int tag_count=0;
+    int tag_index=0;
+
+    // This algorithm for Set ordering requires Universal tags first
+    //  followed by Application, then Context specific tags.
+    //  Each entry in this category is then sorted by the lower 5 bits.
+    //  (They are loaded in reverse order for SNACC buffer loads.)
+    tag_count = vdasnacc_sortSetTag(pEncBuf, tag_index, icount, 
+        ASN_PRIVATE);
+    tag_index += tag_count;         // skip this set of tags, onto the next.
+    tag_count = vdasnacc_sortSetTag(pEncBuf, tag_index, icount, 
+        ASN_CONTEXT);
+    tag_index += tag_count;         // skip this set of tags, onto the next.
+    tag_count = vdasnacc_sortSetTag(pEncBuf, tag_index, icount, 
+        ASN_APPLICATION);
+    tag_index += tag_count;
+    tag_count = vdasnacc_sortSetTag(pEncBuf, tag_index, icount, 
+        ASN_UNIVERSAL);
+
+    return(status);
+}
+
+
+// vdasnacc_sortSetTag
+//  This routine sorts the specified buffer from the start index to the end 
+//  for the specified tag.  This entails switching all entries until the 
+//  tagged entries are consecutive, then sorting according the lower 5 bits
+//  of the tags within that tag.  The number of entries of that tag type
+//  are returned.
+long vdasnacc_sortSetTag(
+    CSM_Buffer *pEncBuf[],      // IN/OUT, buffer to sort
+    int start_index,            // IN, start index for sort.
+    int icount,                 // IN, size of array.
+    int tag)                    // IN, tag to place.
+{
+    int i,j;
+    int tag_count=0;
+    CSM_Buffer *tmpEnc;
+    const char *ptri,*ptrj;
+    int mask = 0x1f;        /** for SET, not SET OF logic, only sort based on 
+                                first 5 bits of tag. **/
+    int mask_TAG = 0xc0;    /** mask for upper tag bits indicating UNIVERSAL,
+                                APPLICATION or CONTEXT ASN.1 Class. **/
+
+    for (i=start_index; i < icount; i++)
+    {
+       ptri = pEncBuf[i]->Access();
+       if (((ptri[0]&mask_TAG)^tag) != 0)
+       {
+        for (j=i+1; (j < icount) && (((ptri[0]&mask_TAG)^tag) != 0); j++)  
+                                    /** always start with present "i". **/
+        {
+            ptrj = pEncBuf[j]->Access();
+            if (((ptri[0]&mask_TAG)^tag) != 0 &&
+                ((ptrj[0]&mask_TAG)^tag) == 0)
+            {   /** SWITCH buffers so that greater is first. **/
+                tmpEnc = pEncBuf[i];
+                pEncBuf[i] = pEncBuf[j];
+                pEncBuf[j] = tmpEnc;
+                ptri = pEncBuf[i]->Access();
+                ptrj = pEncBuf[j]->Access();
+            }
+        }
+       }
+       if (((ptri[0]&mask_TAG)^tag) == 0)
+            tag_count++;        // COUNT each of this tag type.
+    }
+
+    for (i=start_index; i < tag_count; i++)
+    {
+        for (j=i+1; j < tag_count; j++)  /** always start with present "i". **/
+        {
+            ptri = pEncBuf[i]->Access();
+            ptrj = pEncBuf[j]->Access();
+            if ((ptri[0]&mask) < (ptrj[0]&mask))
+            {   /** SWITCH buffers so that greater is first. **/
+                tmpEnc = pEncBuf[i];
+                pEncBuf[i] = pEncBuf[j];
+                pEncBuf[j] = tmpEnc;
+            }
+        }
+    }
+    return(tag_count);
+}
+ 
+
+//
+//  SM_WriteToAsnBuf
+long SM_WriteToAsnBuf(
+    CSM_Buffer &CBuf,     // IN,class must be pre-allocated
+    AsnBuf &SNACCoutputBuf)
+{
+    long status=0;
+    CSM_Buffer *pCBuf=&CBuf;
+
+    status = SM_WriteToAsnBuf(pCBuf, SNACCoutputBuf);
+    return(status);
+}
+long SM_WriteToAsnBuf(
+    CSM_Buffer *&pCBuf,     // IN,class must be pre-allocated
+    AsnBuf &SNACCoutputBuf)
+{
+    long status=0;
+    char *ptr;
+    unsigned int jj=0;
+    SM_SIZE_T lRead=1;
+    SM_SIZE_T lOffset;
+
+    pCBuf->Open(SM_FOPEN_READ);
+    for (jj = 0; jj < pCBuf->Length() && lRead > 0; jj += lRead)
+    {
+        if (jj == 0)    // first time, only get last X bytes within 4096 block.
+        {
+            lOffset = pCBuf->Length() - (pCBuf->Length() % 4096);
+        }
+        else 
+            lOffset -= 4096;
+         pCBuf->Seek(lOffset, 0);
+         ptr = pCBuf->nRead(4096, lRead);
+         SNACCoutputBuf.PutSegRvs(ptr, lRead);
+    }
+    pCBuf->Close();
+    //SNACCoutputBuf.ResetInReadMode();
+    if (lRead != jj)
+      status = 1;     // error.
+    return(status);
+}
+
+//  SM_ReadFromAsnBuf (pre-alloced version)
+//  This function does the same thing as SM_ReadFromAsnBuf but does not
+//  allocate the incoming CSM_Buffer...
+long SM_ReadFromAsnBuf(
+      AsnBuf &SNACCinputBuf, // IN, input SNACC buffer
+      CSM_Buffer *pCBuf, // OUT, copied data
+      long length, // IN, length of data to read.
+      CSM_Buffer *preLoad) // IN, optional data to be pre-loaded;
+                           //   (for SNACC support)
+{
+   char tmpBuf[4096];
+   unsigned int jj, lWritten, lToRead;
+   int tmpLength;
+
+   if (length == INDEFINITE_LEN)
+   {
+      // RWC; Call custom routine to trace the actual unknown ASN data in the 
+      // RWC;  buffer and determine the actual length of the buffer (this may 
+      // RWC;  be a recursive call).
+      AsnBuf SNACCinputBuf2 = SNACCinputBuf; // Create new, working copy for 
+                                             //  ASN ANY length determination.
+      length = SM_DetermineLengthBuf(SNACCinputBuf2);
+   }
+   
+     tmpLength = length;
+     if (preLoad)
+        tmpLength += preLoad->Length();
+     // pCBuf should already be allocated and ready for use...
+     if (pCBuf == NULL)
+        return -1;
+     pCBuf->Open(SM_FOPEN_WRITE);
+     if (preLoad)            // load requested data in front of SNACC buf.
+        pCBuf->Write(preLoad->Access(), preLoad->Length());
+     for (jj=0, lWritten=1;
+         jj < (unsigned int)length && lWritten > 0; jj += lWritten)
+     {
+      if (length - jj < 4096) lToRead = length - jj;
+      else lToRead = 4096;
+      lWritten = SNACCinputBuf.CopyOut(&tmpBuf[0], lToRead);
+      if (lWritten)
+         pCBuf->Write(&tmpBuf[0], lWritten); 
+     }
+     pCBuf->Close();
+   
+   return (length);
+}
+
+//  SM_ReadFromAsnBuf (allocating version)
+//  NOTE::: IMPORTANT NOT TO RESET CSM_Buffer Write BUFFER.
+//  ALSO, DO NOT RESET THE AsnBuf from SNACC; this function is used
+//  to read data from ANY components in the incomming SNACC message.
+long SM_ReadFromAsnBuf(CSM_Buffer *&pCBuf, // OUT,copied data.
+    AsnBuf &SNACCinputBuf,          // IN, input SNACC buffer
+    long length,                    // IN, length of data to read.
+    CSM_Buffer *preLoad)           // IN, optional data to be pre-loaded;
+                                    //   (for SNACC support)
+{
+    int tmpLength;
+
+    tmpLength = length;
+    if (preLoad)
+        tmpLength += preLoad->Length();
+#if defined(macintosh) || defined(__APPLE__)
+	pCBuf = new CSM_Buffer(length == INDEFINITE_LEN ? 0 : preLoad ? tmpLength : length);
+#else
+    if (SNACCinputBuf.DataLen() > 16384)   // RWC; MUST BE FIXED!!!!
+        pCBuf = new CSM_Buffer(tmpnam(NULL), 0);
+    else
+        pCBuf = new CSM_Buffer(0);
+#endif
+    return (SM_ReadFromAsnBuf(SNACCinputBuf, pCBuf, length, preLoad));
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SM_AsnBits2Buffer gets the bits out of the snacc AsnBits class and
+// stores them in a buffer LSB style.
+long SM_AsnBits2Buffer(AsnBits *pBits, CSM_Buffer *pBuffer)
+{
+   size_t lBits;
+   size_t lNumBytes;
+   size_t i, j;
+   char *pch;
+   long lRetVal = -1;
+
+   while (true)
+   {
+      if ((pBits == NULL) || (pBuffer == NULL))
+         break;
+
+      lBits = pBits->BitLen();
+      // calculate the number of bytes being put into the buffer
+      lNumBytes = lBits / 8;
+      if (lBits % 8 > 0)
+         lNumBytes++;
+
+      if ((pch = pBuffer->Alloc(lNumBytes)) == NULL)
+         break;
+
+      for (i = 0; i < lNumBytes; i++)
+      {
+         for (j = 0; j < 8 && ((i*8)+j) < lBits; j++)
+         {
+            pch[i] += (pBits->GetBit((i*8)+j) << j);
+         }
+      }
+
+      pBuffer->Open(SM_FOPEN_WRITE);
+      pBuffer->Flush();
+      pBuffer->Close();
+
+      lRetVal = 0;
+      break;
+   }
+   return lRetVal;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SM_Buffer2AsnBits gets the bits out of the snacc AsnBits class and
+// stores them in a buffer LSB style.
+long SM_Buffer2AsnBits(CSM_Buffer *pBuffer, AsnBits *pBits, size_t lBits)
+{
+   size_t lNumBytes;
+   size_t i, j;
+   const char *pch;
+   long lRetVal = -1;
+
+      if ((pBits != NULL) && (pBuffer != NULL))
+      {
+
+        pBits->ReSet(lBits);
+        // calculate the number of bytes being put into the buffer
+        lNumBytes = lBits / 8;
+        if (lBits % 8 > 0)
+           lNumBytes++;
+        pch = pBuffer->Access();
+
+        for (i = 0; i < lNumBytes; i++)
+        {
+           for (j = 0; j < 8 && ((i*8)+j) < lBits; j++)
+           {
+             if ((pch[i]  >> j) & 0x01)
+               pBits->SetBit((i*8)+j);
+           }
+        }
+        lRetVal = 0;
+      }
+
+    return lRetVal;
+}
+
+long SM_BufferReverseBits(CSM_Buffer *pBuffer)
+{
+    long status=0;
+    size_t i;
+    unsigned char *ptr;
+	#ifdef	__APPLE__
+    static const short bbb[256]=
+	#else
+    static short bbb[256]=
+	#endif
+        { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+          0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+          0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+          0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+          0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+          0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+          0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+          0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+          0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+          0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+          0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+          0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+          0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+          0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+          0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+          0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+        };
+
+    if (pBuffer)
+    {
+        ptr = (unsigned char *)pBuffer->Access();
+        for (i=0; i < pBuffer->Length(); i++)
+        {
+            ptr[i] = (char)bbb[ptr[i]];
+        }
+    }
+
+    return(status);
+}
+
+#if		SM_BUF_2_BIG_INT_STR
+
+long SM_Buffer2BigIntegerStr( CSM_Buffer    *asn1Data,
+                              BigIntegerStr &pSnaccBigIntStr,
+                              bool           unsignedFlag)
+{
+   BigIntegerStr *p = &pSnaccBigIntStr;
+
+   return(SM_Buffer2BigIntegerStr(asn1Data, p, unsignedFlag));
+}
+   
+// FUNCTION: SM_Buffer2BigIntegerStr()
+//
+// PURPOSE: Encforce ASN.1 encoding rules on the asn1Data.  Make sure it's
+//          unsigned if the unsignedFlag is set to true.
+//
+long SM_Buffer2BigIntegerStr( CSM_Buffer     *asn1Data, 
+                              BigIntegerStr *&ppSnaccBigIntStr,
+                              bool            unsignedFlag )
+{
+   char *pDataCopy = const_cast<char*>(asn1Data->Access());
+   SM_SIZE_T dataLen = asn1Data->Length();
+
+   // UPDATE comment
+
+   /* IF the Fortezza Card generates an r,s,p,q,g or y value in which the
+    * first 9 bits are all set to 0, then the encoding software deletes the
+    * first octet from the octets to be encoded.  This rule is applied
+    * repeatedly to the remaining octets until the first 9 bits are not all
+    * set to 0.
+    */
+   if (unsignedFlag == 1)
+   {
+      while ( !( (pDataCopy[0] & 0xFF) || (pDataCopy[1] & 0x80)) )
+      {
+         memcpy( &pDataCopy[0], &pDataCopy[1], (dataLen - 1));
+         dataLen --; 
+         pDataCopy[dataLen] = 0;
+      }
+
+      /* If the Fortezza Card generates a r,s,p,q,g, or y value in which the
+       * MSB is set to 1, THEN the software prepends a single octet in which
+       * all bits are set to 0.
+       */
+      if (pDataCopy[0] & 0x80)
+      {
+         char *tmp = NULL;
+
+         tmp = (char *) calloc(1, dataLen + 1);
+
+         tmp[0] = 0;
+         memcpy(&tmp[1], pDataCopy, dataLen);
+         free(pDataCopy);
+         pDataCopy = &tmp[0];
+         dataLen ++;
+
+      }
+   }
+   /*
+    * ASN.1 rules state that the first 9 bits of an integer encoding can
+    * not be all ones or all zeros.
+    */
+   else
+   {
+      /* check for first first 9 bits all ones
+       */
+      while ( (pDataCopy[0] & 0xFF) && (pDataCopy[1] & 0x80) )
+      {
+         memcpy( &pDataCopy[0], &pDataCopy[1], dataLen - 1);
+         dataLen --;
+         pDataCopy[dataLen] = 0;
+      }
+
+      /* check for first 9 bits all zeros
+       */
+      while (pDataCopy[0] == 0 && (pDataCopy[1] >> 7) == 0)
+      {
+         memcpy( &pDataCopy[0], &pDataCopy[1], (dataLen - 1));
+         dataLen --;
+         pDataCopy[dataLen] = 0;
+      }
+   }
+
+   if (ppSnaccBigIntStr == NULL)
+      ppSnaccBigIntStr = new BigIntegerStr( pDataCopy, dataLen);
+   else
+      ppSnaccBigIntStr->ReSet( pDataCopy, dataLen );
+
+   return (0);
+}
+
+#endif		/* SM_BUF_2_BIG_INT_STR */
+
+//
+//
+// RULES for recursive operation, determining the length of the specified 
+//  buffer:
+//  - Always assume only the data from a valid ANY was passed in, missing tag 
+//    and length.
+//  - Parse data from the 1st byte; if ASN data sets do not match the specified
+//    length or EOC designator, then we assume it is part of sequence and 
+//    continue parsing.
+//
+long SM_DetermineLengthBuf(AsnBuf &SNACCinputBuf)
+{
+    AsnLen length = 0;
+    unsigned long int tagId1;
+    AsnLen elmtLen1;
+    AsnLen elmtLen0=INDEFINITE_LEN;
+    ENV_TYPE env;
+
+    while (elmtLen0 == INDEFINITE_LEN)
+    {
+        tagId1 = BDecTag (SNACCinputBuf, length, env);
+
+        if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (SNACCinputBuf, length, env);
+            break;
+        }
+        elmtLen1 = BDecLen (SNACCinputBuf, length, env);
+        if (elmtLen1 == INDEFINITE_LEN)
+        {
+           elmtLen1 = SM_DetermineLengthBuf(SNACCinputBuf);
+           length += elmtLen1;
+        }
+        else if (!SNACCinputBuf.ReadError())
+        {
+          SNACCinputBuf.Skip(elmtLen1);  // SKIP this ASN.1 component.
+          length += elmtLen1;
+        }
+        else
+        {
+           length = 0;
+           break;
+        }
+    }
+
+    return((long)length);
+
+}
+
+
+/*** EOF smimesnacc.CPP ***/
diff --git a/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c b/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c
new file mode 100644
index 00000000..08430b34
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * snacced -	Snacc_Init added to the default tkXAppInit.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Log: tkAppInit.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:07  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.3  2001/05/05 00:59:19  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.2  2000/06/08 20:05:37  dmitch
+ * Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
+ *
+ * Revision 1.1.1.1  2000/03/09 01:00:06  rmurphy
+ * Base Fortissimo Tree
+ *
+ * Revision 1.1  1999/02/25 05:21:58  mb
+ * Added snacc c++ library
+ *
+ * Revision 1.2  1997/02/28 13:39:48  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.1  1997/01/02 09:07:59  rj
+ * first check-in
+ *
+ */
+
+#ifndef	__APPLE__
+/* I don't know why this gets configd to build but we don't have tk.h */
+
+#include "snacc.h"
+
+#if TCL
+
+/* 
+ * tkXAppInit.c --
+ *
+ *      Provides a default version of the TclX_AppInit procedure for use with
+ *      applications built with Extended Tcl and Tk.  This is based on the
+ *      the UCB Tk file tkAppInit.c
+ *
+ *-----------------------------------------------------------------------------
+ * Copyright 1991-1993 Karl Lehenbauer and Mark Diekhans.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies.  Karl Lehenbauer and
+ * Mark Diekhans make no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ *-----------------------------------------------------------------------------
+ * $Id: tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ *-----------------------------------------------------------------------------
+ * Copyright (c) 1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef lint
+static char rcsid[] = "$Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/src/tkAppInit.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $ SPRITE (Berkeley)";
+#endif /* not lint */
+
+#include <tk.h>
+
+#include "init.h"
+
+int
+main(argc, argv)
+    int argc;                   /* Number of command-line arguments. */
+    char **argv;                /* Values of command-line arguments. */
+{
+    Tk_Main(argc, argv, Tcl_AppInit);
+    return 0;                   /* Needed only to prevent compiler warning. */
+}
+
+int
+Tcl_AppInit (interp)
+    Tcl_Interp *interp;		/* Interpreter for application. */
+{
+    if (Tcl_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+    if (Tk_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+    Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
+
+    if (Snacc_Init (interp) == TCL_ERROR)
+	return TCL_ERROR;
+
+    if (Tree_Init (interp) == TCL_ERROR)
+	return TCL_ERROR;
+
+    Tcl_SetVar (interp, "tcl_rcFileName", "~/.snaccedrc", TCL_GLOBAL_ONLY);
+
+    return TCL_OK;
+}
+
+#endif
+
+#endif	// Apple
diff --git a/SecuritySNACCRuntime/c++-lib/stamp-useful b/SecuritySNACCRuntime/c++-lib/stamp-useful
new file mode 100644
index 00000000..6b0f2e8b
--- /dev/null
+++ b/SecuritySNACCRuntime/c++-lib/stamp-useful
@@ -0,0 +1 @@
+Thu Dec 21 14:52:17 PST 2000
diff --git a/SecuritySNACCRuntime/c-examples/any/README b/SecuritySNACCRuntime/c-examples/any/README
new file mode 100644
index 00000000..cb856399
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/any/README
@@ -0,0 +1,113 @@
+(RCS control information is at the end of this file.)
+
+
+C ANY example README
+------------------
+
+This example shows how the snacc compiler handles the ANY DEFINED BY
+type in C.  ANY types (not ANY DEFINED BY) require the modifications
+to the generated code.  Type "make" to build this example.
+
+This directory should have the following files in it:
+
+        README
+        genber.c
+        example.c
+        makefile
+
+There are 3 programs generated by the makefile:
+
+        genber - builds a BER value of the AnyTestType and writes it
+                 to a file called "att.ber"
+
+        def    - takes file name of an AnyTestType value.  Decodes the
+                 file and re-encodes it to stdout.  Uses definite
+                 lengths for constructed values.
+
+        indef  - takes file name of an AnyTestType value.  Decodes the
+                 file and re-encodes it to stdout.  Uses indefinite
+                 lengths for constructed values.
+
+
+These files use the code generated by snacc from the
+snacc/asn1specs/any.asn1 file. (see the makefile)
+
+Look at genber.c to see how values can be built and printed.
+
+Look at the generated code in any_test.c and any_test.h to see how the
+any hash table is built.
+
+
+try the following commands in your c-shell:
+
+%1 genber                   # generate the att.ber file
+%2 indef att.ber > tmp.ber  # decode att.ber an re-encode into tmp.ber
+%3 def tmp.ber > tmp2.ber   # decode tmp.ber an re-encode into tmp2.ber
+%4 diff att.ber tmp2.ber    # compare .ber files (should be the same)
+
+When you are finished with the example type "make clean"  to remove
+the binaries and generated code.
+
+
+
+Things To Note
+--------------
+
+Snacc ASN.1 comment commands
+
+In the snacc/asn1specs/any.asn1 file, the AnyTestType has a special
+"--snacc" ASN.1 comment after ::= to give snacc some extra information
+about the AnyTestType.
+
+AnyTestType ::= --snacc isPdu:"TRUE" -- SEQUENCE { ... etc. ... }
+
+The "isPdu" flag tells snacc that the AnyTestType is a PDU type that
+you will be calling the encoding and decoding routines directly
+from your code.  This causes snacc to generate the "BEncAnyTestType"
+and "BDecAnyTestType" routines in addition to the standard
+"BEncAnyTestTypeContent" and "BDecAnyTestTypeContent".
+
+The Content encoding and decoding routines only deal with the content
+of the type, ignoring all of the tag and length pairs on the given
+type (in this case the UNIVERSAL (CONSTRUCTED) 16 tag and the length
+for the SEQUENCE).  The "BEncAnyTestType" and "BDecAnyTestType"
+routines do encode the SEQUENCE tag and its length.  This design is
+motivated by IMPLICIT tagging.
+
+The compiler generated routines generally only call the content
+oriented routines except in the case of ANY and ANY DEFINED BY types.
+For ANY and ANY DEFINED BY types the PDU form of the rouine is called
+since the tags are not known by the containing type.
+
+
+SNMP OBJECT-TYPE Macro
+
+The SNMP OBJECT-TYPE macro is used to define the id to type mapping
+for ANY DEFINED BY types.  The macro has been modified to accept both
+INTEGERs and OBJECT IDENTIFIERs as values (see
+snacc/asn1specs/any.asn1).  This macro can be used with other
+protocols to define the id to type mapping.
+
+Two hash tables are used to hold the id to type mappings. One for
+INTEGER to type mappings and the other for OBJECT IDENTIFIER to type
+mappings.  You must explicitly initialize the hash tables by calling
+generated init routines once at the beginning of your program.  Each
+module that has OBJECT-TYPE macros in it will generate an
+"InitAny<module name>" routine.  You must call every init routine to
+add all the mappings to the hash table(s).
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/any/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:08  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1997/02/16 20:26:14  rj
+# check-in of a few cosmetic changes
+#
+# Revision 1.1  1994/08/31  08:46:17  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
diff --git a/SecuritySNACCRuntime/c-examples/any/example.c b/SecuritySNACCRuntime/c-examples/any/example.c
new file mode 100644
index 00000000..bc309981
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/any/example.c
@@ -0,0 +1,188 @@
+/*
+ * 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/any/example.c - an example of how to call C ASN.1-BER
+ *             encoders and decoders generated by snacc
+ *
+ * AUTHOR: Mike Sample
+ * DATE:   Mar 92
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/any/example.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Log: example.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:19  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:08  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.6  1997/02/16 20:26:15  rj
+ * check-in of a few cosmetic changes
+ *
+ * Revision 1.5  1995/07/24  20:40:19  rj
+ * any-test.[hc] becomes any.[hc] due to to snacc's new file name generation scheme.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.4  1995/02/18  15:17:35  rj
+ * cosmetic changes
+ *
+ * Revision 1.3  1994/08/31  23:45:45  rj
+ * more portable .h file inclusion.
+ *
+ * Revision 1.2  1994/08/31  08:59:31  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <stdio.h>
+
+#include "any.h"
+
+
+
+main PARAMS ((argc, argv),
+    int argc _AND_
+    char *argv[])
+{
+    int fd;
+    SBuf  buf;
+    SBuf  encBuf;
+    char *encData;
+    AsnLen encodedLen;
+    AsnLen decodedLen;
+    int     val;
+    AnyTestType att;
+    int      size;
+    char    *origData;
+    struct stat sbuf;
+    jmp_buf env;
+
+    if (argc != 2)
+    {
+        fprintf (stderr, "Usage: %s <BER data file name>\n", argv[0]);
+        fprintf (stderr, "   Decodes the given PersonnelRecord BER data file\n");
+        fprintf (stderr, "   and re-encodes it to stdout\n");
+        exit (1);
+    }
+
+    fd = open (argv[1], O_RDONLY, 0);
+    if (fd < 0)
+    {
+        perror ("main: fopen");
+        exit (1);
+    }
+
+    if (fstat (fd, &sbuf) < 0)
+    {
+        perror ("main: fstat");
+        exit (1);
+    }
+
+    size = sbuf.st_size;
+    origData = (char*)malloc (size);
+    if (read (fd, origData, size) != size)
+    {
+        perror ("main: read");
+        exit (1);
+    }
+
+    close (fd);
+
+    /*
+     * puts the given data 'origData' of 'size' bytes
+     * into an SBuf and sets the SBuf up for reading
+     * origData from the beginning
+     */
+    SBufInstallData (&buf, origData, size);
+
+    /*
+     * the first argument (512) is the number of bytes to
+     * initially allocate for the decoder to allocate from.
+     * The second argument (512) is the size in bytes to
+     * enlarge the nibble memory by when it fills up
+     */
+    InitNibbleMem (512, 512);
+
+
+    /*
+     * initialize the hash table for the
+     * the ANY type mappings.
+     * This only needs to be done once per execution
+     * (before any encoding or decoding is done)
+     */
+    InitAnyANY_TEST();
+
+    decodedLen = 0;
+    if ((val = setjmp (env)) == 0)
+    {
+        BDecAnyTestType (&buf, &att, &decodedLen, env);
+    }
+    else
+    {
+        fprintf (stderr, "ERROR - Decode routines returned %d\n",val);
+        exit (1);
+    }
+
+    fprintf (stderr, "decodedValue AnyTestType ::= ");
+    PrintAnyTestType (stderr, &att, 0);
+    fprintf (stderr, "\n\n");
+
+    /*
+     * setup a new buffer set up for writing.
+     * make sure size is big enough to hold the encoded
+     * value (may be larger than decoded value if encoding
+     * with indef lengths - so add 512 slush bytes)
+     */
+    encData = (char*) malloc (size + 512);
+    SBufInit (&encBuf, encData, size + 512);
+    SBufResetInWriteRvsMode (&encBuf);
+
+    encodedLen =  BEncAnyTestType (&encBuf, &att);
+    if ((encodedLen <= 0) || SBufWriteError (&encBuf))
+    {
+        fprintf (stderr, "ERROR - buffer to hold the encoded value was too small\n");
+        exit (1);
+    }
+
+    /*
+     * free all of the decoded value since
+     * it has been encoded into the buffer.
+     * This is much more efficient than freeing
+     * each compontent of the value individually
+     */
+    ResetNibbleMem();
+
+    /*
+     * write encoded value from encBuf
+     * to stdout
+     */
+    fwrite (SBufDataPtr (&encBuf), SBufDataLen (&encBuf), 1, stdout);
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c-examples/any/genber.c b/SecuritySNACCRuntime/c-examples/any/genber.c
new file mode 100644
index 00000000..0cb15c51
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/any/genber.c
@@ -0,0 +1,191 @@
+/*
+ * 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/any/genber.c - builds an AnyTestType value and writes BER form
+ *            of the value to a file called "att.ber"
+ *
+ *  Shows how to build internal rep of lists and ANY values.
+ *
+ *  MS 92
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/any/genber.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Log: genber.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:19  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:08  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.5  1995/07/24 20:40:50  rj
+ * any-test.[hc] becomes any.[hc] due to to snacc's new file name generation scheme.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.4  1995/02/18  15:17:36  rj
+ * cosmetic changes
+ *
+ * Revision 1.3  1994/08/31  23:48:06  rj
+ * more portable .h file inclusion.
+ *
+ * Revision 1.2  1994/08/31  08:59:32  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <sys/types.h> /* this must be before stddef for gcc-2.3.1 */
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "any.h"
+
+
+main (int argc, char *argv[])
+{
+    FILE *outputFile;
+    SBuf outputBuf;
+    unsigned long int encodedLen;
+    int dataSize = 1024;
+    int i;
+    char data[1024];
+    AnyTestType att;
+    TSeq1 ts1;
+    TSeq2 ts2;
+    AttrValue1 **atv1Hndl;
+    AttrValue2 **atv2Hndl;
+    AsnInt intVal;
+    AsnBool boolVal;
+    AsnOcts octsVal;
+    AsnBits bitsVal;
+    AsnReal realVal;
+
+    /* used to alloc part of value (Asn1Alloc & AsnListAppend) */
+    InitNibbleMem (512,512);
+
+    /* init id to type ANY hash table */
+    InitAnyANY_TEST();
+
+    att.intMap = AsnListNew (sizeof (void*));
+    atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap);
+    *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1));
+    (*atv1Hndl)->id = intId;  /* the id's are defined in the generated code */
+    intVal = -99;
+    (*atv1Hndl)->anyDefBy.value = (void*) &intVal;
+
+    atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap);
+    *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1));
+    (*atv1Hndl)->id = boolId;
+    boolVal = TRUE;
+    (*atv1Hndl)->anyDefBy.value = (void*)&boolVal;
+
+    atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap);
+    *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1));
+    (*atv1Hndl)->id = octsId;
+    octsVal.octs = "Hi Mom";
+    octsVal.octetLen = strlen (octsVal.octs);
+    (*atv1Hndl)->anyDefBy.value = (void*)&octsVal;
+
+    atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap);
+    *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1));
+    (*atv1Hndl)->id = bitsId;
+    bitsVal.bitLen = 10;
+    bitsVal.bits = (char*)&i;
+    SetAsnBit (&bitsVal, 0);
+    ClrAsnBit (&bitsVal, 1);
+    SetAsnBit (&bitsVal, 2);
+    ClrAsnBit (&bitsVal, 3);
+    SetAsnBit (&bitsVal, 4);
+    ClrAsnBit (&bitsVal, 5);
+    SetAsnBit (&bitsVal, 6);
+    ClrAsnBit (&bitsVal, 7);
+    SetAsnBit (&bitsVal, 8);
+    ClrAsnBit (&bitsVal, 9);
+    (*atv1Hndl)->anyDefBy.value = (void*)&bitsVal;
+
+    atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap);
+    *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1));
+    (*atv1Hndl)->id = realId;
+    realVal = 108.3838;
+    (*atv1Hndl)->anyDefBy.value = (void*)&realVal;
+
+    /* now do TSeq2 with same vals but use OID as identifier */
+    att.oidMap = AsnListNew (sizeof (void*));
+
+    atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap);
+    *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2));
+    (*atv2Hndl)->id = intOid;
+    (*atv2Hndl)->anyDefBy.value = (void*)&intVal;
+
+    atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap);
+    *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2));
+    (*atv2Hndl)->id = boolOid;
+    (*atv2Hndl)->anyDefBy.value = (void*)&boolVal;
+
+    atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap);
+    *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2));
+    (*atv2Hndl)->id = octsOid;
+    (*atv2Hndl)->anyDefBy.value = (void*)&octsVal;
+
+    atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap);
+    *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2));
+    (*atv2Hndl)->id = bitsOid;
+    (*atv2Hndl)->anyDefBy.value = (void*)&bitsVal;
+
+    atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap);
+    *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2));
+    (*atv2Hndl)->id = realOid;
+    (*atv2Hndl)->anyDefBy.value = (void*)&realVal;
+
+    SBufInit (&outputBuf,data, dataSize);
+    SBufResetInWriteRvsMode (&outputBuf);
+
+    encodedLen = BEncAnyTestType (&outputBuf, &att);
+    if ((encodedLen <= 0) || (SBufWriteError (&outputBuf)))
+    {
+        fprintf (stderr, "failed encoding AnyTestType value\n");
+        exit (1);
+    }
+
+    outputFile = fopen ("att.ber", "w");
+    if (!outputFile)
+    {
+        perror ("fopen:");
+        exit (1);
+    }
+
+    SBufResetInReadMode (&outputBuf);
+    for ( ; encodedLen > 0; encodedLen--)
+        fputc (SBufGetByte (&outputBuf), outputFile);
+
+
+    printf ("Wrote the following BER AnyTestType value to att.ber.\n");
+    printf ("Test it with \"def\" and \"indef\"\n");
+
+    PrintAnyTestType (stdout, &att, 0);
+    printf ("\n");
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c-examples/any/makefile b/SecuritySNACCRuntime/c-examples/any/makefile
new file mode 100644
index 00000000..bbc9e64a
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/any/makefile
@@ -0,0 +1,150 @@
+# c-examples/any/makefile
+#
+# WARNING: this makefile isn't safe for parallel making!
+#
+#  compile the any example
+#
+# MS 92
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/any/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:08  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.6  1995/07/24 20:42:31  rj
+# useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme.
+# any-test.[hc] becomes any.[hc] due to to snacc's new file name generation scheme.
+#
+# `cd && make' instead of `cd; make'.
+#
+# changed `_' to `-' in file names.
+#
+# Revision 1.5  1995/02/20  11:51:39  rj
+# build snacc if it doesn't exist.
+# some makes leave a trailing slash on $(@D), others don't. this causes some mkdir(1)s to deny their cooperation. therefore, the slash has got to be stripped.
+#
+# Revision 1.4  1995/02/13  15:05:05  rj
+# augment CPPFLAGS, not overwrite.
+# use $(@D) and $(@F) instead of `dirname $@` and `basename $@` (not every system's got the commands).
+# we need the compiler for the dependencies, so make it if it doesn't yet exist.
+#
+# Revision 1.3  1994/08/31  21:41:37  rj
+# rebuild the executables when the c-lib is newer.
+#
+# Revision 1.2  1994/08/31  10:31:49  rj
+# since .o files get moved, a few more dependencies are needed.
+#
+# Revision 1.1  1994/08/31  08:46:20  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../../makehead
+
+TOP		= ../..
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+
+ASN1_C_LIB_DIR	= $(TOP)/c-lib
+ASN1_C_INC_DIR	= $(ASN1_C_LIB_DIR)/inc
+ASN1_C_LIB	= $(ASN1_C_LIB_DIR)/libasn1csbuf.a
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+USEFUL_TYPES	= $(ASN1_SRC_DIR)/asn-useful.asn1
+SNACCFLAGS	= -u $(USEFUL_TYPES)
+
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C_INC_DIR) -DUSE_SBUF $(LENFLAG)
+
+ASN1FILES	= $(ASN1_SRC_DIR)/any.asn1
+
+# generated by snacc from any.asn1:
+ASN1HFILES	= any.h
+ASN1CFILES	= any.c
+
+CFILES = \
+	genber.c	\
+	example.c
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(CFILES)
+
+#-------------------------------------------------------------------------------
+
+all::		genber def indef
+
+$(ASN1HFILES)	\
+$(ASN1CFILES):	$(SNACC) $(ASN1FILES)
+		$(REASON)
+		$(SNACC) $(SNACCFLAGS) $(ASN1FILES)
+
+$(SNACC):
+		cd $(@D) && $(MAKE) $(@F)
+
+def-obj		\
+indef-obj:
+		mkdir $@
+
+def-obj/any.o	\
+def-obj/example.o:
+		$(REASON)
+		$(MAKE) LENFLAG= `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+indef-obj/any.o	\
+indef-obj/example.o:
+		$(REASON)
+		$(MAKE) LENFLAG=-DUSE_INDEF_LEN `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+genber:		def-obj/any.o genber.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ def-obj/any.o genber.o $(ASN1_C_LIB) $(LIBS)
+
+def: 		def-obj/any.o def-obj/example.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ def-obj/any.o def-obj/example.o $(ASN1_C_LIB) $(LIBS)
+
+indef:		indef-obj/any.o indef-obj/example.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ indef-obj/any.o indef-obj/example.o $(ASN1_C_LIB) $(LIBS)
+
+genber	\
+def	\
+indef:		$(ASN1_C_LIB)
+
+.PHONY:	check
+
+check::		genber def indef
+		$(RM) foo.ber bar.ber
+		./genber
+		./indef att.ber > foo.ber
+		./def foo.ber > bar.ber
+		@echo ''
+		@if cmp -s bar.ber att.ber; then\
+		  echo "+++ Passed simple encode/decode tests using any.asn1.";\
+		else\
+		  echo "--- Failed simple encode/decode tests using any.asn1.";\
+		fi
+		@echo ''
+		$(RM) foo.ber bar.ber
+
+clean::
+		$(RM) *.o *~ .emacs* core def indef genber att.ber $(ASN1HFILES) $(ASN1CFILES)
+		$(RM) -r def-obj indef-obj
+		$(RM) foo.ber bar.ber
+
+depend::	$(SNACC)
+
+include ../../maketail
+
+depend::
+		cp dependencies deps
+		for dir in def-obj indef-obj; do\
+		  < dependencies sed -e 's:^\(.*\.o\):'"$$dir"'/\1:' >> deps;\
+		done
+		mv deps dependencies
diff --git a/SecuritySNACCRuntime/c-examples/makefile b/SecuritySNACCRuntime/c-examples/makefile
new file mode 100644
index 00000000..e55fa940
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/makefile
@@ -0,0 +1,53 @@
+# c-examples/makefile
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.2  2000/06/08 20:06:37  dmitch
+# Mods for X port.
+#
+# Revision 1.1.1.1  1999/03/16 18:06:08  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1995/07/24 20:38:56  rj
+# `cd && make' instead of `cd; make'.
+#
+# changed `_' to `-' in file names.
+#
+
+# Appple change: snmp test does not work.
+#SUBDIRS		= test-lib simple any snmp
+SUBDIRS		= test-lib simple any
+
+#-------------------------------------------------------------------------------
+
+.PHONY:	implicit_default
+implicit_default::
+		$(MAKE) subdirs
+
+subdirs::	$(SUBDIRS)
+$(SUBDIRS)::
+		cd $@ && $(MAKE) $(subtarget)
+
+# the following hack is needed for older make versions (gmake doesn't need it):
+init-depend::
+		@for dir in $(SUBDIRS); do\
+		  test -f $$dir/dependencies || touch $$dir/dependencies;\
+		done
+
+.DEFAULT::
+		$(MAKE) subdirs subtarget=$@
+
+distfiles::
+		echo makefile
+		for dir in $(SUBDIRS); do\
+		  subfiles=`cd $$dir && $(MAKE) -s $@`;\
+		  for file in $$subfiles; do\
+		    echo "$$dir/$$file";\
+		  done;\
+		done
+
+# dummy:
+install::
diff --git a/SecuritySNACCRuntime/c-examples/simple/README b/SecuritySNACCRuntime/c-examples/simple/README
new file mode 100644
index 00000000..8ef401ec
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/simple/README
@@ -0,0 +1,134 @@
+(RCS control information is at the end of this file.)
+
+
+C Simple Example README
+-----------------------
+
+This directory should have 8 files in it:
+
+README       - this file
+genber.c     - C source code for a program that creates and encodes
+               a PersonnelRecord value to a file.
+expbuf_ex.c  - C source code for a program that calls the generated
+               PersonnelRecord encoder and decoder routines
+               using the ExpBuf buffer type
+minbuf_ex.c  - C source code for program that calls the generated
+               PersonnelRecord encoder and decoder routines
+               using the MinBuf buffer type
+sbuf_ex.c    - C source code for a program that calls the generated
+               PersonnelRecord encoder and decoder routines
+               using the MinBuf buffer type
+makefile     - compiles the example programs
+good_pr.ber  - BER encoding of a Personnel Record (all definite lengths)
+
+
+
+Type "make" to generate the 7 example programs:
+        genber
+        expbuf_def
+        expbuf_indef
+        minbuf_def
+        minbuf_indef
+        sbuf_def
+        sbuf_indef
+
+
+snacc is called from the makefile on snacc/asn1specs/p_rec.asn1 to
+generate the following files:
+
+p_rec.h  - C data structs for PersonnelRecord and prototypes for
+           the generated encode, decode, print and free routines.
+p_rec.c  - C source code for the PersonnelRecord encode, decode,
+           print, and free routines.
+
+These source files are then compiled with *_ex.c and genber.c files to
+make 7 programs.  Each program takes 1 argument (except genber), the
+name of a file containing an BER encoded PersonnelRecord value.
+
+
+Try the following: (or use the makefile's `check' phony target)
+
+eg% ./genber				# create a file called pr.ber
+eg% ./sbuf_indef good_pr.ber > indef_pr.ber
+eg% ./sbuf_def indef_pr.ber > def_pr.ber
+eg% diff good_pr.ber def_pr.ber		# should be no differences
+
+
+The above commands decode the BER value in "good_pr.ber" and
+indef_pr.ber respectively and then re-encode then to stdout.
+Both programs will decode any valid BER representation of a
+PersonnelRecord value but, the sbuf_def program will re-encode the
+given data using only the definite length BER format and the
+sbuf_indef program will re-encode the given data using only the
+indefinite length BER format.
+
+Compare the lengths of the def_pr.ber and indef_pr.ber files,
+indefinite length encodings are usually larger.
+
+
+
+Things to Note
+--------------
+
+
+Look at genber.c to see how to build a C value and then encode it.
+look at the *_ex.c files to see the different types of buffer
+manipulation.  Read the comments in the code.
+
+It should be relatively simple to change the memory and buffer
+management to fit your target environment.
+(see snacc/c_include/asn_config.h.)
+
+
+Snacc ASN.1 comment commands
+
+Notice the special "--snacc" ASN.1 comment in snacc/asn1specs/p_rec.asn1.
+
+PersonnelRecord ::= --snacc isPdu:"TRUE" -- [APPLICATION 0] IMPLICIT SET
+ { ... etc. ... }
+
+The "isPdu" flag tells snacc that the PersonnelRecord is a PDU type
+that you will be calling the encoding and decoding routines directly
+from your code.  This causes snacc to generate the
+"BEncPersonnelRecord" and "BDecPersonnelRecord" routines in addition
+to the standard "BEncPersonnelRecordContent" and
+"BDecPersonnelRecordContent".
+
+The Content encoding and decoding routines only deal with the content
+of the type, ignoring all of the tag and length pairs on the given
+type (in this case the APPLICATION (CONSTRUCTED) 0 tag and the length
+for the SET).  The "BEncPersonnelRecord" and "BDecPersonnelRecord"
+routines do encode the APPLICATION tag and the SET's length.  This
+design is motivated by IMPLICIT tagging.
+
+The compiler generated routines generally only call the content
+oriented routines except in the case of ANY and ANY DEFINED BY types.
+For ANY and ANY DEFINED BY types the PDU form of the rouine is called
+since the tags are not known by the containing type.
+
+
+Length formats
+
+Each pair of *_def and *_indef programs were generated from the same
+source file, *_ex.c.  Indefinite length encoders can be created by
+giving the -DUSE_INDEF_LEN flag to the C compiler when compiling.
+Currently the indefinite/definite length encoder choice is made a
+compile time.  To change this to a run-time decision, a simple
+solution would be to modify BerEncodeConsLen and BerEncodeEocIfNec
+macros in snacc/c_lib/asn_len.h to check a global flag.
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:09  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1995/02/17 16:17:24  rj
+# reflect the test script's integration into the makefile.
+#
+# Revision 1.1  1994/08/31  08:46:22  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
diff --git a/SecuritySNACCRuntime/c-examples/simple/expbuf-ex.c b/SecuritySNACCRuntime/c-examples/simple/expbuf-ex.c
new file mode 100644
index 00000000..ef3ea012
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/simple/expbuf-ex.c
@@ -0,0 +1,196 @@
+/*
+ * 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/simple/expbuf_ex.c - an example of how to call C ASN.1-BER
+ *              encoders and decoders generated by snacc
+ *              with the ExpBuf buffer.
+ *
+ * AUTHOR: Mike Sample
+ * DATE:   Mar 92
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/expbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Log: expbuf-ex.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:07  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.3  2001/05/05 00:59:20  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.2  2000/06/08 20:06:59  dmitch
+ * Mods for X port.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:08  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.5  1995/07/24 20:44:58  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.4  1995/02/18  15:12:53  rj
+ * cosmetic changes
+ *
+ * Revision 1.3  1994/08/31  23:48:29  rj
+ * more portable .h file inclusion.
+ *
+ * Revision 1.2  1994/08/31  08:59:34  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+
+#include <sys/file.h>
+#include <sys/stat.h>
+#if HAVE_FCNTL_H 
+#include <fcntl.h>
+#endif
+#include <stdio.h>
+
+#include "p-rec.h"
+#include "exp-buf.h"
+
+main PARAMS ((argc, argv),
+    int argc _AND_
+    char *argv[])
+{
+    int fd;
+    ExpBuf *buf;
+    ExpBuf  b;
+    ExpBuf *tmpBuf;
+    AsnLen encodedLen;
+    AsnLen decodedLen;
+    int     val;
+    PersonnelRecord pr;
+    int      size;
+    char    *origData;
+    struct stat sbuf;
+    jmp_buf env;
+    int  decodeErr;
+    AsnTag tag;
+
+
+    if (argc != 2)
+    {
+        fprintf (stderr, "Usage: %s <BER data file name>\n", argv[0]);
+        fprintf (stderr, "   Decodes the given PersonnelRecord BER data file\n");
+        fprintf (stderr, "   and re-encodes it to stdout\n");
+        exit (1);
+    }
+
+    fd = open (argv[1], O_RDONLY, 0);
+    if (fd < 0)
+    {
+        perror ("main: fopen");
+        exit (1);
+    }
+
+    if (fstat (fd, &sbuf) < 0)
+    {
+        perror ("main: fstat");
+        exit (1);
+    }
+
+    size = sbuf.st_size;
+    origData = (char*)malloc (size);
+    if (read (fd, origData, size) != size)
+    {
+        perror ("main: read");
+        exit (1);
+    }
+
+    close (fd);
+
+    /*
+     * the "1024" is the size in bytes of the data
+     * blk to allocate when writing to a buffer that
+     * fills up.
+     */
+    ExpBufInit (1024);
+
+    /*
+     * the first argument (512) is the number of bytes to
+     * initially allocate for the decoder to allocate from.
+     * The second argument (512) is the size in bytes to
+     * enlarge the nibble memory by when it fills up
+     */
+    InitNibbleMem (512, 512);
+
+    /*
+     * put the BER data read from the file
+     * into buffer format, ready for reading from the
+     * beginning
+     */
+    buf = &b;
+    ExpBufInstallDataInBuf (buf, origData, size);
+
+    decodedLen = 0;
+    decodeErr = FALSE;
+    if ((val = setjmp (env)) == 0)
+    {
+        BDecPersonnelRecord (&buf, &pr, &decodedLen, env);
+    }
+    else
+    {
+        decodeErr = TRUE;
+        fprintf (stderr, "ERROR - Decode routines returned %d\n",val);
+    }
+
+    if (decodeErr)
+        exit (1);
+
+    fprintf (stderr, "decodedValue PersonnelRecord ::= ");
+    PrintPersonnelRecord (stderr, &pr, 0);
+    fprintf (stderr, "\n\n");
+
+    /*
+     * allocate a new buffer set up for writing to
+     */
+    buf = ExpBufAllocBufAndData();
+
+    encodedLen =  BEncPersonnelRecord (&buf, &pr);
+
+    /*
+     * Alway check for a buffer write error after encoding
+     */
+    if (ExpBufWriteError (&buf))
+    {
+        fprintf (stderr, "ERROR - buffer write error during encoding\n");
+        exit (1);
+    }
+
+
+    /*
+     * free all of the decoded value since
+     * it has been encoded into the buffer.
+     * This is much more efficient than freeing
+     * each compontent of the value individually
+     */
+    ResetNibbleMem();
+
+    /*
+     * go through buffer (s) and write encoded value
+     * to stdout
+     */
+    buf->curr = buf->dataStart;
+    for ( tmpBuf = buf; tmpBuf != NULL; tmpBuf = tmpBuf->next)
+    {
+        fwrite (tmpBuf->dataStart, tmpBuf->dataEnd - tmpBuf->dataStart, 1, stdout);
+    }
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c-examples/simple/genber.c b/SecuritySNACCRuntime/c-examples/simple/genber.c
new file mode 100644
index 00000000..5f18e2ee
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/simple/genber.c
@@ -0,0 +1,181 @@
+/*
+ * 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/simple/genber.c - builds a PersonnelRecord value and writes BER form
+ *            of the value to a file called "pr.ber"
+ *
+ *
+ *  MS 92
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/genber.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Log: genber.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:08  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.6  1995/07/24 20:45:00  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.5  1995/02/18  15:12:54  rj
+ * cosmetic changes
+ *
+ * Revision 1.4  1995/02/17  16:21:03  rj
+ * unnecessary inclusion of <sys/stdtypes.h> removed.
+ *
+ * Revision 1.3  1994/09/01  01:02:37  rj
+ * more portable .h file inclusion.
+ *
+ * Revision 1.2  1994/08/31  08:59:35  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <stddef.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+
+#include "p-rec.h"
+
+
+main (int argc, char *argv[])
+{
+    FILE *outputFile;
+    SBuf outputBuf;
+    unsigned long int encodedLen;
+    int dataSize = 1024;
+    int i;
+    char data[1024];
+    PersonnelRecord pr;
+    ChildInformation **childHndl;
+
+    /* used to alloc part of value (Asn1Alloc & AsnListAppend) */
+    InitNibbleMem (512,512);
+
+    pr.name = Asn1Alloc (sizeof (Name));
+    pr.name->givenName.octs = "John";
+    pr.name->givenName.octetLen = strlen (pr.name->givenName.octs);
+    pr.name->initial.octs = "E";
+    pr.name->initial.octetLen = strlen (pr.name->initial.octs);
+    pr.name->familyName.octs = "Smith";
+    pr.name->familyName.octetLen = strlen (pr.name->familyName.octs);
+
+    pr.title.octs = "The Big Cheese";
+    pr.title.octetLen = strlen (pr.title.octs);
+
+    pr.employeeNumber = 99999;
+
+    pr.dateOfHire.octs = "19820104";
+    pr.dateOfHire.octetLen = strlen (pr.dateOfHire.octs);
+
+    pr.nameOfSpouse = (Name*) Asn1Alloc (sizeof (Name));
+    pr.nameOfSpouse->givenName.octs = "Mary";
+    pr.nameOfSpouse->givenName.octetLen =
+        strlen (pr.nameOfSpouse->givenName.octs);
+    pr.nameOfSpouse->initial.octs = "L";
+    pr.nameOfSpouse->initial.octetLen = strlen (pr.nameOfSpouse->initial.octs);
+    pr.nameOfSpouse->familyName.octs = "Smith";
+    pr.nameOfSpouse->familyName.octetLen =
+        strlen (pr.nameOfSpouse->familyName.octs);
+
+    pr.children = AsnListNew (sizeof (void*));
+
+    childHndl = AsnListAppend (pr.children);
+    *childHndl = Asn1Alloc (sizeof (ChildInformation));
+
+    (*childHndl)->dateOfBirth.octs = "19570310";
+    (*childHndl)->dateOfBirth.octetLen  = strlen ((*childHndl)->dateOfBirth.octs);
+    (*childHndl)->name = (Name*) Asn1Alloc (sizeof (Name));
+
+    (*childHndl)->name->givenName.octs = "James";
+    (*childHndl)->name->givenName.octetLen =
+        strlen ((*childHndl)->name->givenName.octs);
+    (*childHndl)->name->initial.octs = "R";
+    (*childHndl)->name->initial.octetLen =
+        strlen ((*childHndl)->name->initial.octs);
+    (*childHndl)->name->familyName.octs = "Smith";
+    (*childHndl)->name->familyName.octetLen =
+        strlen ((*childHndl)->name->familyName.octs);
+
+    childHndl = AsnListAppend (pr.children);
+    *childHndl = Asn1Alloc (sizeof (ChildInformation));
+
+    (*childHndl)->dateOfBirth.octs = "19610621";
+    (*childHndl)->dateOfBirth.octetLen  = strlen ((*childHndl)->dateOfBirth.octs);
+
+    (*childHndl)->name = (Name*) Asn1Alloc (sizeof (Name));
+
+    (*childHndl)->name->givenName.octs = "Lisa";
+    (*childHndl)->name->givenName.octetLen =
+        strlen ((*childHndl)->name->givenName.octs);
+    (*childHndl)->name->initial.octs = "M";
+    (*childHndl)->name->initial.octetLen =
+        strlen ((*childHndl)->name->initial.octs);
+    (*childHndl)->name->familyName.octs = "Smith";
+    (*childHndl)->name->familyName.octetLen =
+        strlen ((*childHndl)->name->familyName.octs);
+
+    SBufInit (&outputBuf,data, dataSize);
+    SBufResetInWriteRvsMode (&outputBuf);
+
+    encodedLen = BEncPersonnelRecord (&outputBuf, &pr);
+
+    /*
+     * after encoding a value ALWAYS check for write error
+     * in the buffer.  The encode routine do not use longjmp
+     * when they enter an error state
+     */
+    if ((encodedLen <= 0) || (SBufWriteError (&outputBuf)))
+    {
+        fprintf (stderr, "failed encoding PersonnelRecord value\n");
+        exit (1);
+    }
+
+    outputFile = fopen ("pr.ber", "w");
+    if (!outputFile)
+    {
+        perror ("fopen:");
+        exit (1);
+    }
+
+    SBufResetInReadMode (&outputBuf);
+    for ( ; encodedLen > 0; encodedLen--)
+        fputc (SBufGetByte (&outputBuf), outputFile);
+
+
+    printf ("Wrote the following BER PersonnelRecord value to pr.ber.\n");
+    printf ("Test it with \"def\" and \"indef\"\n");
+
+    PrintPersonnelRecord (stdout, &pr, 0);
+    printf ("\n");
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c-examples/simple/good-pr.ber b/SecuritySNACCRuntime/c-examples/simple/good-pr.ber
new file mode 100644
index 0000000000000000000000000000000000000000..f8cc9410ed7be7741ca4c0e0805cce1fbee7df6a
GIT binary patch
literal 145
zcmYdj>`N37WAVz*$P;696=My~%`C}SARxvUl98(5l$oyJoROMZoEqQAz|7b-e<7DM
zhoPl~k%6Is$s!?;M&HDuN-;(ssK&*PhVqGmVys??xv9lsj6pE-z}igB4U7#94CO%D
Td@_p@#Tb22<jo8X%!~{HLggjQ

literal 0
HcmV?d00001

diff --git a/SecuritySNACCRuntime/c-examples/simple/makefile b/SecuritySNACCRuntime/c-examples/simple/makefile
new file mode 100644
index 00000000..58f2c638
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/simple/makefile
@@ -0,0 +1,204 @@
+# file: c-examples/simple/makefile
+#
+# WARNING: this makefile isn't safe for parallel making!
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:08  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.6  1995/07/24 20:46:17  rj
+# useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme.
+#
+# `cd && make' instead of `cd; make'.
+#
+# changed `_' to `-' in file names.
+#
+# Revision 1.5  1995/02/20  11:50:49  rj
+# build snacc if it doesn't exist.
+# some makes leave a trailing slash on $(@D), others don't. this causes some mkdir(1)s to deny their cooperation. therefore, the slash has got to be stripped.
+#
+# Revision 1.4  1995/02/13  15:05:36  rj
+# augment CPPFLAGS, not overwrite.
+# use $(@D) and $(@F) instead of `dirname $@` and `basename $@` (not every system's got the commands).
+# we need the compiler for the dependencies, so make it if it doesn't yet exist.
+#
+# Revision 1.3  1994/08/31  21:42:52  rj
+# rebuild the executables when the c-lib they get linked against is newer.
+# the file good-pr.ber needs to be distributed.
+#
+# Revision 1.2  1994/08/31  10:31:52  rj
+# since .o files get moved, a few more dependencies are needed.
+#
+# Revision 1.1  1994/08/31  08:46:27  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../../makehead
+
+TOP		= ../..
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+
+ASN1_C_LIB_DIR	= $(TOP)/c-lib
+ASN1_C_INC_DIR	= $(ASN1_C_LIB_DIR)/inc
+MBUF_ASN1_LIB	= $(ASN1_C_LIB_DIR)/libasn1cmbuf.a
+SBUF_ASN1_LIB	= $(ASN1_C_LIB_DIR)/libasn1csbuf.a
+EBUF_ASN1_LIB	= $(ASN1_C_LIB_DIR)/libasn1cebuf.a
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+USEFUL_TYPES	= $(ASN1_SRC_DIR)/asn-useful.asn1
+SNACCFLAGS	= -u $(USEFUL_TYPES)
+
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C_INC_DIR) $(BUFFLAG) $(LENFLAG)
+
+ASN1FILES	= $(ASN1_SRC_DIR)/p-rec.asn1
+# generated by snacc from p-rec.asn1:
+ASN1HFILES	= p-rec.h
+ASN1CFILES	= p-rec.c
+
+CFILES = \
+	genber.c	\
+	minbuf-ex.c	\
+	expbuf-ex.c	\
+	sbuf-ex.c
+
+BUFFLAG		= -DUSE_SBUF
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(CFILES)	\
+	good-pr.ber
+
+#-------------------------------------------------------------------------------
+
+all::		genber minbuf-def minbuf-indef expbuf-def expbuf-indef sbuf-def sbuf-indef
+
+$(ASN1HFILES)	\
+$(ASN1CFILES):	$(SNACC) $(ASN1FILES)
+		$(REASON)
+		$(SNACC) $(SNACCFLAGS) $(ASN1FILES)
+
+$(SNACC):
+		cd $(@D) && $(MAKE) $(@F)
+
+min-def-obj	\
+min-indef-obj	\
+exp-def-obj	\
+exp-indef-obj	\
+s-def-obj	\
+s-indef-obj:
+		mkdir $@
+
+min-def-obj/p-rec.o	\
+min-def-obj/minbuf-ex.o:
+		$(REASON)
+		$(MAKE) BUFFLAG=-DUSE_MIN_BUF LENFLAG= `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+min-indef-obj/p-rec.o	\
+min-indef-obj/minbuf-ex.o:
+		$(REASON)
+		$(MAKE) BUFFLAG=-DUSE_MIN_BUF LENFLAG=-DUSE_INDEF_LEN `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+exp-def-obj/p-rec.o	\
+exp-def-obj/expbuf-ex.o:
+		$(REASON)
+		$(MAKE) BUFFLAG=-DUSE_EXP_BUF LENFLAG= `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+exp-indef-obj/p-rec.o	\
+exp-indef-obj/expbuf-ex.o:
+		$(REASON)
+		$(MAKE) BUFFLAG=-DUSE_EXP_BUF LENFLAG=-DUSE_INDEF_LEN `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+s-def-obj/p-rec.o	\
+s-def-obj/sbuf-ex.o:
+		$(REASON)
+		$(MAKE) LENFLAG= `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+s-indef-obj/p-rec.o	\
+s-indef-obj/sbuf-ex.o:
+		$(REASON)
+		$(MAKE) LENFLAG=-DUSE_INDEF_LEN `echo $(@D) | sed -e 's:/$$::'` $(@F)
+		mv $(@F) $@
+
+genber:		s-def-obj/p-rec.o genber.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ s-def-obj/p-rec.o genber.o $(SBUF_ASN1_LIB) $(LIBS)
+
+minbuf-def: 	min-def-obj/p-rec.o min-def-obj/minbuf-ex.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ min-def-obj/p-rec.o min-def-obj/minbuf-ex.o $(MBUF_ASN1_LIB) $(LIBS)
+
+minbuf-indef:	min-indef-obj/p-rec.o min-indef-obj/minbuf-ex.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ min-indef-obj/p-rec.o min-indef-obj/minbuf-ex.o $(MBUF_ASN1_LIB) $(LIBS)
+
+expbuf-def: 	exp-def-obj/p-rec.o exp-def-obj/expbuf-ex.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ exp-def-obj/p-rec.o exp-def-obj/expbuf-ex.o $(EBUF_ASN1_LIB) $(LIBS)
+
+expbuf-indef:	exp-indef-obj/p-rec.o exp-indef-obj/expbuf-ex.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ exp-indef-obj/p-rec.o exp-indef-obj/expbuf-ex.o $(EBUF_ASN1_LIB) $(LIBS)
+
+sbuf-def: 	s-def-obj/p-rec.o s-def-obj/sbuf-ex.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ s-def-obj/p-rec.o s-def-obj/sbuf-ex.o $(SBUF_ASN1_LIB) $(LIBS)
+
+sbuf-indef:	s-indef-obj/p-rec.o s-indef-obj/sbuf-ex.o
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $@ s-indef-obj/p-rec.o s-indef-obj/sbuf-ex.o $(SBUF_ASN1_LIB) $(LIBS)
+
+genber		\
+sbuf-def	\
+sbuf-indef:	$(SBUF_ASN1_LIB)
+
+minbuf-def	\
+minbuf-indef:	$(MINBUF_ASN1_LIB)
+
+expbuf-def	\
+expbuf-indef:	$(EXPBUF_ASN1_LIB)
+
+.PHONY:	check
+
+check::		minbuf-def minbuf-indef expbuf-def expbuf-indef sbuf-def sbuf-indef
+		for bt in min exp s; do\
+		  $(RM) $$bt-foo.ber $$bt-bar.ber;\
+		  ./$${bt}buf-indef good-pr.ber > $$bt-foo.ber;\
+		  ./$${bt}buf-def $$bt-foo.ber > $$bt-bar.ber;\
+		done
+		@for bt in min exp s; do\
+		  if cmp -s $$bt-bar.ber good-pr.ber; then\
+		    echo "+++ Passed simple encode/decode tests using p-rec.asn1 with $${bt}bufs.";\
+		  else\
+		    echo "--- Failed simple encode/decode tests using p-rec.asn1 with $${bt}bufs.";\
+		  fi;\
+		  $(RM) $$bt-foo.ber $$bt-bar.ber;\
+		done
+
+clean::
+		$(RM) *.o *~ core .emacs*
+		$(RM) expbuf-def expbuf-indef sbuf-indef sbuf-def minbuf-def minbuf-indef genber pr.ber $(ASN1HFILES) $(ASN1CFILES)
+		$(RM) -r *-def-obj *-indef-obj
+		$(RM) *-foo.ber *-bar.ber
+
+depend::	$(SNACC)
+
+include ../../maketail
+
+depend::
+		cp dependencies deps
+		for dir in min-def-obj min-indef-obj exp-def-obj exp-indef-obj s-def-obj s-indef-obj; do\
+		  < dependencies sed -e 's:^\(.*\.o\):'"$$dir"'/\1:' >> deps;\
+		done
+		mv deps dependencies
diff --git a/SecuritySNACCRuntime/c-examples/simple/minbuf-ex.c b/SecuritySNACCRuntime/c-examples/simple/minbuf-ex.c
new file mode 100644
index 00000000..701822b9
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/simple/minbuf-ex.c
@@ -0,0 +1,189 @@
+/*
+ * 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/simple/minbuf_ex.c - an example of how to call C ASN.1-BER
+ *               encoders and decoders generated by snacc
+ *               using the MinBuf buffer.
+ *
+ * AUTHOR: Mike Sample
+ * DATE:   Mar 92
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/minbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Log: minbuf-ex.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:46:59  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.4  1995/02/18  15:12:55  rj
+ * cosmetic changes
+ *
+ * Revision 1.3  1994/09/01  01:02:38  rj
+ * more portable .h file inclusion.
+ *
+ * Revision 1.2  1994/08/31  08:59:36  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+
+#include <sys/file.h>
+#include <sys/stat.h>
+#if HAVE_FCNTL_H 
+#include <fcntl.h>
+#endif
+#include <stdio.h>
+
+#include "p-rec.h"
+
+
+main PARAMS ((argc, argv),
+    int argc _AND_
+    char *argv[])
+{
+    int fd;
+    char  *buf;
+    char *encBuf;
+    char *encData;
+    int encBufSize;
+    AsnLen encodedLen;
+    AsnLen decodedLen;
+    int     val;
+    PersonnelRecord pr;
+    int      size;
+    char    *origData;
+    struct stat sbuf;
+    jmp_buf env;
+    int  decodeErr;
+    AsnTag tag;
+
+
+    if (argc != 2)
+    {
+        fprintf (stderr, "Usage: %s <BER data file name>\n", argv[0]);
+        fprintf (stderr, "   Decodes the given PersonnelRecord BER data file\n");
+        fprintf (stderr, "   and re-encodes it to stdout\n");
+        exit (1);
+    }
+
+    fd = open (argv[1], O_RDONLY, 0);
+    if (fd < 0)
+    {
+        perror ("main: fopen");
+        exit (1);
+    }
+
+    if (fstat (fd, &sbuf) < 0)
+    {
+        perror ("main: fstat");
+        exit (1);
+    }
+
+    size = sbuf.st_size;
+    origData = (char*)malloc (size);
+    if (read (fd, origData, size) != size)
+    {
+        perror ("main: read");
+        exit (1);
+    }
+
+    close (fd);
+
+    /* set up min buf  */
+    buf = origData;
+
+    /*
+     * the first argument (512) is the number of bytes to
+     * initially allocate for the decoder to allocate from.
+     * The second argument (512) is the size in bytes to
+     * enlarge the nibble memory by when it fills up
+     */
+    InitNibbleMem (512, 512);
+
+
+    decodedLen = 0;
+    decodeErr = FALSE;
+    if ((val = setjmp (env)) == 0)
+    {
+        BDecPersonnelRecord (&buf, &pr, &decodedLen, env);
+    }
+    else
+    {
+        decodeErr = TRUE;
+        fprintf (stderr, "ERROR - Decode routines returned %d\n",val);
+    }
+
+    if (decodeErr)
+        exit (1);
+
+    fprintf (stderr, "decodedValue PersonnelRecord ::= ");
+    PrintPersonnelRecord (stderr, &pr, 0);
+    fprintf (stderr, "\n\n");
+
+    /*
+     * setup a new buffer set up for writing.
+     * make sure size is big enough to hold the encoded
+     * value (may be larger than decoded value if encoding
+     * with indef lengths - so add 512 slush bytes)
+     */
+    encBufSize = size + 512;
+    encData = (char*) malloc (encBufSize);
+
+    /*
+     * set 'buffer' up for writing by setting ptr
+     * byte after last byte of the block
+     */
+    encBuf = encData + encBufSize;
+    encodedLen =  BEncPersonnelRecord (&encBuf, &pr);
+
+    /*
+     *  this will never report a write error
+     *  since no error checking done by MinBuf code
+     *  and alawys return false for when read or write errors.
+     */
+    if (MinBufWriteError (&encBuf))
+    {
+        fprintf (stderr, "ERROR - buffer to hold the encoded value was too small\n");
+        exit (1);
+    }
+
+    /*
+     * free all of the decoded value since
+     * it has been encoded into the buffer.
+     * This is much more efficient than freeing
+     * each compontent of the value individually
+     */
+    ResetNibbleMem();
+
+    /*
+     * write encoded value from encBuf
+     * to stdout
+     */
+    fwrite (encBuf, encData + encBufSize - encBuf, 1, stdout);
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c-examples/simple/sbuf-ex.c b/SecuritySNACCRuntime/c-examples/simple/sbuf-ex.c
new file mode 100644
index 00000000..e40cce10
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/simple/sbuf-ex.c
@@ -0,0 +1,181 @@
+/*
+ * 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/simple/sbuf_ex.c - an example of how to call C ASN.1-BER
+ *             encoders and decoders generated by snacc
+ *             using the SBuf buffer.
+ *
+ * AUTHOR: Mike Sample
+ * DATE:   Mar 92
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/simple/sbuf-ex.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+ * $Log: sbuf-ex.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:47:00  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.4  1995/02/18  15:12:56  rj
+ * cosmetic changes
+ *
+ * Revision 1.3  1994/09/01  01:02:39  rj
+ * more portable .h file inclusion.
+ *
+ * Revision 1.2  1994/08/31  08:59:37  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if HAVE_FCNTL_H 
+#include <fcntl.h>
+#endif
+#include <stdio.h>
+
+#include "p-rec.h"
+
+main PARAMS ((argc, argv),
+    int argc _AND_
+    char *argv[])
+{
+    int fd;
+    SBuf  buf;
+    SBuf  encBuf;
+    char *encData;
+    AsnLen encodedLen;
+    AsnLen decodedLen;
+    int     val;
+    PersonnelRecord pr;
+    int      size;
+    char    *origData;
+    struct stat sbuf;
+    jmp_buf env;
+    int  decodeErr;
+    AsnTag tag;
+
+    if (argc != 2)
+    {
+        fprintf (stderr, "Usage: %s <BER data file name>\n", argv[0]);
+        fprintf (stderr, "   Decodes the given PersonnelRecord BER data file\n");
+        fprintf (stderr, "   and re-encodes it to stdout\n");
+        exit (1);
+    }
+
+    fd = open (argv[1], O_RDONLY, 0);
+    if (fd < 0)
+    {
+        perror ("main: fopen");
+        exit (1);
+    }
+
+    if (fstat (fd, &sbuf) < 0)
+    {
+        perror ("main: fstat");
+        exit (1);
+    }
+
+    size = sbuf.st_size;
+    origData = (char*)malloc (size);
+    if (read (fd, origData, size) != size)
+    {
+        perror ("main: read");
+        exit (1);
+    }
+
+    close (fd);
+
+    /*
+     * puts the given data 'origData' of 'size' bytes
+     * into an SBuf and sets the SBuf up for reading
+     * origData from the beginning
+     */
+    SBufInstallData (&buf, origData, size);
+
+    /*
+     * the first argument (512) is the number of bytes to
+     * initially allocate for the decoder to allocate from.
+     * The second argument (512) is the size in bytes to
+     * enlarge the nibble memory by when it fills up
+     */
+    InitNibbleMem (512, 512);
+
+
+    decodedLen = 0;
+    decodeErr = FALSE;
+    if ((val = setjmp (env)) == 0)
+    {
+        BDecPersonnelRecord (&buf, &pr, &decodedLen, env);
+    }
+    else
+    {
+        decodeErr = TRUE;
+        fprintf (stderr, "ERROR - Decode routines returned %d\n",val);
+    }
+
+    if (decodeErr)
+        exit (1);
+
+    fprintf (stderr, "decodedValue PersonnelRecord ::= ");
+    PrintPersonnelRecord (stderr, &pr, 0);
+    fprintf (stderr, "\n\n");
+
+    /*
+     * setup a new buffer set up for writing.
+     * make sure size is big enough to hold the encoded
+     * value (may be larger than decoded value if encoding
+     * with indef lengths - so add 512 slush bytes)
+     */
+    encData = (char*) malloc (size + 512);
+    SBufInit (&encBuf, encData, size + 512);
+    SBufResetInWriteRvsMode (&encBuf);
+
+    encodedLen =  BEncPersonnelRecord (&encBuf, &pr);
+
+    if (SBufWriteError (&encBuf))
+    {
+        fprintf (stderr, "ERROR - buffer to hold the encoded value was too small\n");
+        exit (1);
+    }
+
+    /*
+     * free all of the decoded value since
+     * it has been encoded into the buffer.
+     * This is much more efficient than freeing
+     * each compontent of the value individually
+     */
+    ResetNibbleMem();
+
+    /*
+     * write encoded value from encBuf
+     * to stdout
+     */
+    fwrite (SBufDataPtr (&encBuf), SBufDataLen (&encBuf), 1, stdout);
+
+    return 0;
+}
diff --git a/SecuritySNACCRuntime/c-examples/snmp/README b/SecuritySNACCRuntime/c-examples/snmp/README
new file mode 100644
index 00000000..362184a2
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/snmp/README
@@ -0,0 +1,124 @@
+(RCS control information is at the end of this file.)
+
+
+C SNMP Example - Mike Sample Mar 92
+-----------------------------------
+
+This example illustrates a few more features of the compiler than the
+simple example.  It also shows some deficiencies.  No executable
+programs are generated by the makefile, it only generates the snmp
+code and compiles it without linking.
+
+This directory contains 2 files:
+        README
+        makefile
+
+Snacc generates source from the following ASN.1 files:
+        snacc/asn1specs/rfc1155_smi.asn1
+        snacc/asn1specs/rfc1157_snmp.asn1
+        snacc/asn1specs/rfc1213_mib2.asn1
+
+multi-module compilation
+   The IMPORT/EXPORT mechanisms of ASN.1 '88 are supported so you don't
+   have to dump all of the ASN.1 definitions into a single file
+   The order of the ASN.1 file arguments is the order that they
+   are included in the generated source files.  For example:
+
+   %1 snacc rfc1155-smi.asn1 rfc1157-snmp.asn1 rfc1213-mib2.asn1
+
+   causes the order in which hdr files are included  in rfc1213-mib.c
+   to be:
+
+   #include "asn-incl.h"
+   #include "rfc1155-smi.h"
+   #include "rfc1157-snmp.h"
+   #include "rfc1213-mib2.h"
+
+
+    Currently, snacc assumes that each ASN.1 file given on the command
+    line depends on all of the others on the command line.  There is
+    no attempt to compute the dependencies via the import lists alone.
+
+SNMP OBJECT-TYPE macro parsing / ANY type hash table
+   The SNMP OBJECT-TYPE macro is parsed.   This results in the
+   type in the "SYNTAX" part of the macro is put into
+   the ANY type hash table using the  OBJECT-TYPE macro's value as the
+   hash key.  Also if the type in the SYNTAX field is not defined
+   outsided of the macro (could be different tagging etc), a proper
+   type definition is generated for it.  If you want to change the way
+   the macro is handled, modify the corresponding routine in "do_macros.c".
+
+value definitions
+   The OBJECT IDENTIFIER values are turned into statically initialized
+   C values and included in the generated source and include file.  This
+   is also done for INTEGER and BOOLEAN values.  More complex values
+   are ignored by the compiler at the moment. (modify parse_vals.c if
+   you want to improve this)
+
+
+-P option of snacc is demonstrated
+   The ASN.1 for the parsed modules is generated from the internal data
+   structure.  This can be useful for making sure the compiler is
+   handling your ASN.1 files correctly.  It is also useful to see how
+   the types are modified and sorted to simplify code generation.
+   (see the snacc.output file after typeing "make")
+
+Deficiencies
+   A deficiency in parsing large integers is shown when parsing the
+   following rfc 1155 types:
+
+                  Counter ::=
+                      [APPLICATION 1]
+                          IMPLICIT INTEGER (0..4294967295)
+
+                  Gauge ::=
+                      [APPLICATION 2]
+                          IMPLICIT INTEGER (0..4294967295)
+
+                  TimeTicks ::=
+                      [APPLICATION 3]
+                          IMPLICIT INTEGER (0..4294967295)
+
+Due the size of a C long int the above ASN.1 is represented internally as:
+
+Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..-1)
+
+Gauge ::= [APPLICATION 2] IMPLICIT INTEGER (0..-1)
+
+TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..-1)
+
+The ASN.1 library contains routines for encoding/decoding unsigned
+long integers but you must hand code the cases where it is used - the
+compiler never generates code that calls them.
+
+Note also that the produced code for the SNMP ASN.1 must be modified
+to correclty handle the "Opaque" data type.  SNMP does not use the ANY
+DEFINED BY type in an effort to simplify things.  Instead an OCTET
+STRING is used to hold and encoded value whose type is defined by an
+OBJECT IDENTIFIER.  With some simple modifications you can use the
+snacc AsnAnyDefinedBy type instead of the OCTET STRING to achieve
+the desired results.
+
+This should underline the danger of blindly trusting the compiler to
+do the right thing for protocols such as SNMP or X.500 where the type
+of an encoded value depends on a mechanism outside of ASN.1 or the ANY
+type (ANY DEFINED BY types should work automatically).
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/snmp/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:09  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.3  1995/07/27 09:58:31  rj
+# rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme.
+#
+# Revision 1.2  1995/07/24  20:47:39  rj
+# changed `_' to `-' in file names.
+#
+# Revision 1.1  1994/08/31  08:46:33  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
diff --git a/SecuritySNACCRuntime/c-examples/snmp/makefile b/SecuritySNACCRuntime/c-examples/snmp/makefile
new file mode 100644
index 00000000..99508074
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/snmp/makefile
@@ -0,0 +1,97 @@
+# c-examples/snmp/makefile
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/snmp/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:09  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.6  1995/07/27 09:57:38  rj
+# rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme.
+#
+# Revision 1.5  1995/07/24  20:48:27  rj
+# `cd && make' instead of `cd; make'.
+#
+# changed `_' to `-' in file names.
+#
+# Revision 1.4  1995/02/20  11:52:11  rj
+# build snacc if it doesn't exist.
+#
+# Revision 1.3  1995/02/13  15:05:48  rj
+# augment CPPFLAGS, not overwrite.
+# we need the compiler for the dependencies, so make it if it doesn't yet exist.
+#
+# Revision 1.2  1994/08/31  23:25:46  rj
+# print a less irritating usage.
+#
+# Revision 1.1  1994/08/31  08:46:34  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../../makehead
+
+TOP		= ../..
+
+ASN1_SPEC_DIR	= $(TOP)/asn1specs
+
+ASN1_C_LIB_DIR	= $(TOP)/c-lib
+ASN1_C_INC_DIR	= $(ASN1_C_LIB_DIR)/inc
+ASN1_C_LIB	= $(ASN1_C_LIB_DIR)/libasn1csbuf.a
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C_INC_DIR) -DUSE_SBUF
+
+ASN1FILES = \
+	$(ASN1_SPEC_DIR)/rfc1155-smi.asn1	\
+	$(ASN1_SPEC_DIR)/rfc1157-snmp.asn1	\
+	$(ASN1_SPEC_DIR)/rfc1213-mib2.asn1
+
+ASN1HFILES = \
+	rfc1155-smi.h	\
+	rfc1213-mib2.h	\
+	rfc1157-snmp.h
+
+ASN1CFILES = \
+	rfc1155-smi.c	\
+	rfc1213-mib2.c	\
+	rfc1157-snmp.c
+
+DISTFILES = \
+	README		\
+	makefile	\
+
+#-------------------------------------------------------------------------------
+
+default::	warning
+
+warning::
+		@echo ''
+		@echo 'read the README and enter `$(MAKE) fail` to test for yourself'
+		@echo ''
+
+fail::		$(ASN1HFILES) $(ASN1CFILES)
+		$(CC) $(CPPFLAGS) $(CFLAGS) -c $(ASN1CFILES)
+
+$(ASN1HFILES)	\
+$(ASN1CFILES):	$(SNACC) $(ASN1FILES)
+		$(REASON)
+		$(SNACC) -P $(ASN1FILES) > snacc.output~
+		mv snacc.output~ snacc.output
+
+$(SNACC):
+		cd $(@D) && $(MAKE) $(@F)
+
+check::
+		@echo "the purpose of this directories' contents is to show deficiencies."
+		@echo "if you want to exercise 'em, make the phony target "'`'"fail'"
+
+clean::
+		$(RM) *.o *~ .emacs* core $(ASN1HFILES) $(ASN1CFILES) snacc.output
+
+depend::	$(SNACC)
+
+include ../../maketail
diff --git a/SecuritySNACCRuntime/c-examples/test-lib/README b/SecuritySNACCRuntime/c-examples/test-lib/README
new file mode 100644
index 00000000..e7eafa05
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/test-lib/README
@@ -0,0 +1,43 @@
+(RCS control information is at the end of this file.)
+
+
+C test_lib README
+-----------------
+
+This directory should have 3 files:
+        README - this file
+        makefile
+        test_lib.c
+
+Type "make" to compile test_lib.
+
+test_lib tests each encode and decode routine in the C ASN.1
+runtime library. Errors will be reported.
+
+test_lib should be run for each machine architecture you install snacc on.
+If you modify the library routines you should run test_lib again.
+
+The general testing methodology is:
+        1. test the buffer routines
+        2. test tags
+        3. test lengths
+        4. test each libarary type.
+
+For each type, a range of values is encoded and then decoded
+and and compared with the original value.
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/test-lib/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:09  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1997/02/16 20:26:19  rj
+# check-in of a few cosmetic changes
+#
+# Revision 1.1  1994/08/31  08:46:36  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
diff --git a/SecuritySNACCRuntime/c-examples/test-lib/makefile b/SecuritySNACCRuntime/c-examples/test-lib/makefile
new file mode 100644
index 00000000..748119ae
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/test-lib/makefile
@@ -0,0 +1,56 @@
+# c-examples/test-lib/makefile
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/test-lib/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:09  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.4  1995/07/24 20:50:11  rj
+# changed `_' to `-' in file names.
+#
+# Revision 1.3  1995/02/13  15:05:59  rj
+# augment CPPFLAGS, not overwrite.
+#
+# Revision 1.2  1994/08/31  21:43:20  rj
+# rebuild the executables when the c-lib is newer.
+#
+# Revision 1.1  1994/08/31  08:46:37  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../../makehead
+
+TOP		= ../..
+
+ASN1_C_LIB_DIR	= $(TOP)/c-lib
+ASN1_C_INC_DIR	= $(ASN1_C_LIB_DIR)/inc
+ASN1_C_LIB	= $(ASN1_C_LIB_DIR)/libasn1csbuf.a
+
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C_INC_DIR) -DUSE_SBUF
+
+LDLIBS		= $(ASN1_C_LIB) $(LIBS)
+
+CFILES = \
+	test-lib.c
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(CFILES)
+
+#-------------------------------------------------------------------------------
+
+default::	check
+
+check::		test-lib
+		./test-lib
+
+test-lib:	$(ASN1_C_LIB)
+
+clean::
+		$(RM) *.o *~ .emacs* test-lib core
+
+include ../../maketail
diff --git a/SecuritySNACCRuntime/c-examples/test-lib/test-lib.c b/SecuritySNACCRuntime/c-examples/test-lib/test-lib.c
new file mode 100644
index 00000000..d5ecae0f
--- /dev/null
+++ b/SecuritySNACCRuntime/c-examples/test-lib/test-lib.c
@@ -0,0 +1,962 @@
+/*
+ * 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 <stdio.h>
+
+#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 */
diff --git a/SecuritySNACCRuntime/c-lib/.cvsignore b/SecuritySNACCRuntime/c-lib/.cvsignore
new file mode 100644
index 00000000..1a2b4fa3
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/.cvsignore
@@ -0,0 +1,5 @@
+Cebuf
+ebuf
+mbuf
+sbuf
+tbl
diff --git a/SecuritySNACCRuntime/c-lib/README b/SecuritySNACCRuntime/c-lib/README
new file mode 100644
index 00000000..eabf5b07
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/README
@@ -0,0 +1,36 @@
+(RCS control information is at the end of this file.)
+
+
+C ASN.1 library README
+----------------------
+
+This directory contains the type definitions and the encode, decode,
+free and print routines for all of the built-in ASN.1 types.  It also
+contains the code for three different buffer types.
+
+The makefile will produce 3 different libraries, one for each buffer
+type.  Each buffer types requires a different library because many of
+the buffer routine calls made from the encode and decode library
+routines are macros (for performance reasons).
+
+The 3 libararies are:
+        libasn1cebuf.a - uses the ExpBufs
+        libasn1cmbuf.a - uses the MinBufs
+        libasn1csbuf.a - uses the SBufs
+
+See the documentation for a full descriptions of the buffer types.
+You must link your code with proper library (i.e. if you use SBufs,
+link with libasn1csbuf.a).
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/README,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:10  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1994/08/31 23:50:07  rj
+# textual change to adapt to change of directory tree.
+#
diff --git a/SecuritySNACCRuntime/c-lib/asn-useful.c b/SecuritySNACCRuntime/c-lib/asn-useful.c
new file mode 100644
index 00000000..a1439b56
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/asn-useful.c
@@ -0,0 +1,892 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    asn-useful.c
+ *
+ *    "ASN-USEFUL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Thu Jun  8 12:35:27 2000
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "asn-useful.h"
+
+
+AsnLen BEncUTF8String PARAMS ((b, v),
+BUF_TYPE b _AND_
+UTF8String *v)
+{
+    AsnLen l;
+    l = BEncUTF8StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, 12);
+    return l;
+} /* BEncUTF8String */
+
+void BDecUTF8String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+UTF8String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, 12))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, 12)))
+    {
+        Asn1Error ("BDecUTF8String: ERROR - wrong tag\n");
+        longjmp (env, 50);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecUTF8StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecUTF8String */
+
+AsnLen BEncNumericString PARAMS ((b, v),
+BUF_TYPE b _AND_
+NumericString *v)
+{
+    AsnLen l;
+    l = BEncNumericStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE);
+    return l;
+} /* BEncNumericString */
+
+void BDecNumericString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+NumericString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecNumericString: ERROR - wrong tag\n");
+        longjmp (env, 49);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecNumericStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecNumericString */
+
+AsnLen BEncPrintableString PARAMS ((b, v),
+BUF_TYPE b _AND_
+PrintableString *v)
+{
+    AsnLen l;
+    l = BEncPrintableStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+    return l;
+} /* BEncPrintableString */
+
+void BDecPrintableString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+PrintableString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecPrintableString: ERROR - wrong tag\n");
+        longjmp (env, 48);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecPrintableStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecPrintableString */
+
+AsnLen BEncTeletexString PARAMS ((b, v),
+BUF_TYPE b _AND_
+TeletexString *v)
+{
+    AsnLen l;
+    l = BEncTeletexStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+} /* BEncTeletexString */
+
+void BDecTeletexString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+TeletexString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecTeletexString: ERROR - wrong tag\n");
+        longjmp (env, 47);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecTeletexStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecTeletexString */
+
+AsnLen BEncT61String PARAMS ((b, v),
+BUF_TYPE b _AND_
+T61String *v)
+{
+    AsnLen l;
+    l = BEncT61StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+} /* BEncT61String */
+
+void BDecT61String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+T61String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecT61String: ERROR - wrong tag\n");
+        longjmp (env, 46);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecT61StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecT61String */
+
+AsnLen BEncVideotexString PARAMS ((b, v),
+BUF_TYPE b _AND_
+VideotexString *v)
+{
+    AsnLen l;
+    l = BEncVideotexStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE);
+    return l;
+} /* BEncVideotexString */
+
+void BDecVideotexString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+VideotexString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VIDEOTEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecVideotexString: ERROR - wrong tag\n");
+        longjmp (env, 45);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecVideotexStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecVideotexString */
+
+AsnLen BEncIA5String PARAMS ((b, v),
+BUF_TYPE b _AND_
+IA5String *v)
+{
+    AsnLen l;
+    l = BEncIA5StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, IA5STRING_TAG_CODE);
+    return l;
+} /* BEncIA5String */
+
+void BDecIA5String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+IA5String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, IA5STRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, IA5STRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecIA5String: ERROR - wrong tag\n");
+        longjmp (env, 44);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecIA5StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecIA5String */
+
+AsnLen BEncGraphicString PARAMS ((b, v),
+BUF_TYPE b _AND_
+GraphicString *v)
+{
+    AsnLen l;
+    l = BEncGraphicStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GRAPHICSTRING_TAG_CODE);
+    return l;
+} /* BEncGraphicString */
+
+void BDecGraphicString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GraphicString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GRAPHICSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GRAPHICSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecGraphicString: ERROR - wrong tag\n");
+        longjmp (env, 43);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGraphicStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGraphicString */
+
+AsnLen BEncVisibleString PARAMS ((b, v),
+BUF_TYPE b _AND_
+VisibleString *v)
+{
+    AsnLen l;
+    l = BEncVisibleStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+} /* BEncVisibleString */
+
+void BDecVisibleString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+VisibleString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecVisibleString: ERROR - wrong tag\n");
+        longjmp (env, 42);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecVisibleStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecVisibleString */
+
+AsnLen BEncISO646String PARAMS ((b, v),
+BUF_TYPE b _AND_
+ISO646String *v)
+{
+    AsnLen l;
+    l = BEncISO646StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+} /* BEncISO646String */
+
+void BDecISO646String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+ISO646String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecISO646String: ERROR - wrong tag\n");
+        longjmp (env, 41);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecISO646StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecISO646String */
+
+AsnLen BEncGeneralString PARAMS ((b, v),
+BUF_TYPE b _AND_
+GeneralString *v)
+{
+    AsnLen l;
+    l = BEncGeneralStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GENERALSTRING_TAG_CODE);
+    return l;
+} /* BEncGeneralString */
+
+void BDecGeneralString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GeneralString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GENERALSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GENERALSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecGeneralString: ERROR - wrong tag\n");
+        longjmp (env, 40);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGeneralStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGeneralString */
+
+AsnLen BEncUTCTime PARAMS ((b, v),
+BUF_TYPE b _AND_
+UTCTime *v)
+{
+    AsnLen l;
+    l = BEncUTCTimeContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, UTCTIME_TAG_CODE);
+    return l;
+} /* BEncUTCTime */
+
+void BDecUTCTime PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+UTCTime *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE)))
+    {
+        Asn1Error ("BDecUTCTime: ERROR - wrong tag\n");
+        longjmp (env, 39);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecUTCTimeContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecUTCTime */
+
+AsnLen BEncGeneralizedTime PARAMS ((b, v),
+BUF_TYPE b _AND_
+GeneralizedTime *v)
+{
+    AsnLen l;
+    l = BEncGeneralizedTimeContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    return l;
+} /* BEncGeneralizedTime */
+
+void BDecGeneralizedTime PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GeneralizedTime *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+    {
+        Asn1Error ("BDecGeneralizedTime: ERROR - wrong tag\n");
+        longjmp (env, 38);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGeneralizedTimeContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGeneralizedTime */
+
+AsnLen BEncUniversalString PARAMS ((b, v),
+BUF_TYPE b _AND_
+UniversalString *v)
+{
+    AsnLen l;
+    l = BEncUniversalStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, UNIVERSALSTRING_TAG_CODE);
+    return l;
+} /* BEncUniversalString */
+
+void BDecUniversalString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+UniversalString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, UNIVERSALSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, UNIVERSALSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecUniversalString: ERROR - wrong tag\n");
+        longjmp (env, 37);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecUniversalStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecUniversalString */
+
+AsnLen BEncBMPString PARAMS ((b, v),
+BUF_TYPE b _AND_
+BMPString *v)
+{
+    AsnLen l;
+    l = BEncBMPStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, BMPSTRING_TAG_CODE);
+    return l;
+} /* BEncBMPString */
+
+void BDecBMPString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+BMPString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, BMPSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, BMPSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecBMPString: ERROR - wrong tag\n");
+        longjmp (env, 36);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecBMPStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecBMPString */
+
+AsnLen
+BEncEXTERNALChoiceContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNALChoice *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+    BEncEocIfNec (b);
+    itemLen = BEncAsnOctsContent (b, (v->a.single_ASN1_type));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 4);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case EXTERNALCHOICE_OCTET_ALIGNED:
+    itemLen = BEncAsnOctsContent (b, (v->a.octet_aligned));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case EXTERNALCHOICE_ARBITRARY:
+    itemLen = BEncAsnBitsContent (b, (v->a.arbitrary));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncEXTERNALChoiceContent */
+
+void
+BDecEXTERNALChoiceContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+EXTERNALChoice *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+
+
+    switch (tagId0)
+    {
+       case MAKE_TAG_ID (CNTX, CONS, 0):
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+if ((tagId1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) &&
+   (tagId1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, 35);
+    }
+
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+        (v->choiceId) = EXTERNALCHOICE_SINGLE_ASN1_TYPE;
+    (v->a.single_ASN1_type) = (AsnOcts*) Asn1Alloc (sizeof (AsnOcts));
+    CheckAsn1Alloc ((v->a.single_ASN1_type), env);
+    BDecAsnOctsContent (b, tagId1, elmtLen1, (v->a.single_ASN1_type), &totalElmtsLen1, env);
+    if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, PRIM, 1):
+       case MAKE_TAG_ID (CNTX, CONS, 1):
+        (v->choiceId) = EXTERNALCHOICE_OCTET_ALIGNED;
+    (v->a.octet_aligned) = (AsnOcts*) Asn1Alloc (sizeof (AsnOcts));
+    CheckAsn1Alloc ((v->a.octet_aligned), env);
+    BDecAsnOctsContent (b, tagId0, elmtLen0, (v->a.octet_aligned), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, PRIM, 2):
+       case MAKE_TAG_ID (CNTX, CONS, 2):
+        (v->choiceId) = EXTERNALCHOICE_ARBITRARY;
+    (v->a.arbitrary) = (AsnBits*) Asn1Alloc (sizeof (AsnBits));
+    CheckAsn1Alloc ((v->a.arbitrary), env);
+    BDecAsnBitsContent (b, tagId0, elmtLen0, (v->a.arbitrary), &totalElmtsLen1, env);
+    break;
+
+    default:
+        Asn1Error ("ERROR - unexpected tag in CHOICE\n");
+        longjmp (env, 34);
+        break;
+    } /* end switch */
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecEXTERNALChoiceContent */
+
+void
+PrintEXTERNALChoice PARAMS ((f, v, indent),
+FILE* f _AND_
+EXTERNALChoice *v _AND_
+unsigned short int indent)
+{
+    switch (v->choiceId)
+    {
+      case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+          fprintf (f,"single-ASN1-type ");
+    PrintAsnOcts (f, (v->a.single_ASN1_type), indent + stdIndentG);
+          break;
+
+      case EXTERNALCHOICE_OCTET_ALIGNED:
+          fprintf (f,"octet-aligned ");
+    PrintAsnOcts (f, (v->a.octet_aligned), indent + stdIndentG);
+          break;
+
+      case EXTERNALCHOICE_ARBITRARY:
+          fprintf (f,"arbitrary ");
+    PrintAsnBits (f, (v->a.arbitrary), indent + stdIndentG);
+          break;
+
+    }
+}  /* PrintEXTERNALChoice */
+
+void
+FreeEXTERNALChoice PARAMS ((v),
+EXTERNALChoice *v)
+{
+
+    if (v == NULL)
+        return;
+    switch (v->choiceId)
+    {
+       case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+    FreeAsnOcts ((v->a.single_ASN1_type));
+    Asn1Free ((v->a.single_ASN1_type));
+
+    break;
+
+       case EXTERNALCHOICE_OCTET_ALIGNED:
+    FreeAsnOcts ((v->a.octet_aligned));
+    Asn1Free ((v->a.octet_aligned));
+
+    break;
+
+       case EXTERNALCHOICE_ARBITRARY:
+    FreeAsnBits ((v->a.arbitrary));
+    Asn1Free ((v->a.arbitrary));
+
+    break;
+
+    }
+}  /* FreeEXTERNALChoice */
+
+
+
+
+AsnLen BEncEXTERNAL PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNAL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncEXTERNALContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, EXTERNAL_TAG_CODE);
+    return l;
+} /* BEncEXTERNAL */
+
+void BDecEXTERNAL PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+EXTERNAL *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, CONS, EXTERNAL_TAG_CODE)))
+    {
+        Asn1Error ("BDecEXTERNAL: ERROR - wrong tag\n");
+        longjmp (env, 33);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecEXTERNALContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecEXTERNAL */
+
+AsnLen
+BEncEXTERNALContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNAL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncEXTERNALChoiceContent (b, (v->encoding));
+
+    totalLen += itemLen;
+
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    itemLen = BEncObjectDescriptorContent (b, (&v->data_value_descriptor));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 7);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    itemLen = BEncAsnIntContent (b, (v->indirect_reference));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->direct_reference));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 6);
+
+    totalLen += itemLen;
+    }
+
+    return totalLen;
+
+}  /* BEncEXTERNALContent */
+
+void
+BDecEXTERNALContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+EXTERNAL *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnOidContent (b, tagId1, elmtLen1, (&v->direct_reference), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->indirect_reference) = (AsnInt*) Asn1Alloc (sizeof (AsnInt));
+    CheckAsn1Alloc ((v->indirect_reference), env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (v->indirect_reference), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, OD_TAG_CODE)) ||
+(tagId1 == MAKE_TAG_ID (UNIV, CONS, OD_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecObjectDescriptorContent (b, tagId1, elmtLen1, (&v->data_value_descriptor), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 0)) ||
+    (tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))||
+    (tagId1 == MAKE_TAG_ID (CNTX, CONS, 1)) ||
+    (tagId1 == MAKE_TAG_ID (CNTX, PRIM, 2))||
+    (tagId1 == MAKE_TAG_ID (CNTX, CONS, 2))))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->encoding) = (EXTERNALChoice*) Asn1Alloc (sizeof (EXTERNALChoice));
+    CheckAsn1Alloc ((v->encoding), env);
+    BDecEXTERNALChoiceContent (b, tagId1, elmtLen1, (v->encoding), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, 32);
+    }
+    else
+        longjmp (env, 31);
+
+
+    if (!seqDone)
+        longjmp (env, 30);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecEXTERNALContent */
+
+void
+PrintEXTERNAL PARAMS ((f, v, indent),
+FILE* f _AND_
+EXTERNAL *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"direct-reference ");
+    PrintAsnOid (f, (&v->direct_reference), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"indirect-reference ");
+    PrintAsnInt (f, (v->indirect_reference), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"data-value-descriptor ");
+    PrintObjectDescriptor (f, (&v->data_value_descriptor), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"encoding ");
+    PrintEXTERNALChoice (f, (v->encoding), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintEXTERNAL */
+
+void
+FreeEXTERNAL PARAMS ((v),
+EXTERNAL *v)
+{
+
+    if (v == NULL)
+        return;
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    FreeAsnOid ((&v->direct_reference));
+    }
+
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    FreeAsnInt ((v->indirect_reference));
+    Asn1Free ((v->indirect_reference));
+    }
+
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    FreeObjectDescriptor ((&v->data_value_descriptor));
+    }
+
+    FreeEXTERNALChoice ((v->encoding));
+    Asn1Free ((v->encoding));
+
+}  /* FreeEXTERNAL */
+
+
+
+
diff --git a/SecuritySNACCRuntime/c-lib/asn-useful.h b/SecuritySNACCRuntime/c-lib/asn-useful.h
new file mode 100644
index 00000000..0f2f3f98
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/asn-useful.h
@@ -0,0 +1,343 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    asn-useful.h
+ *
+ *    "ASN-USEFUL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Thu Jun  8 12:35:27 2000
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _asn_useful_h_
+#define _asn_useful_h_
+
+
+
+
+typedef AsnOcts ObjectDescriptor; /* [UNIVERSAL 7] IMPLICIT OCTET STRING */
+
+#define BEncObjectDescriptorContent BEncAsnOctsContent
+
+#define BDecObjectDescriptorContent BDecAsnOctsContent
+
+#define PrintObjectDescriptor PrintAsnOcts
+
+#define FreeObjectDescriptor FreeAsnOcts 
+
+
+
+
+typedef AsnOcts UTF8String; /* [UNIVERSAL 12] IMPLICIT OCTET STRING */
+
+AsnLen BEncUTF8String PROTO ((BUF_TYPE b, UTF8String *v));
+
+void BDecUTF8String PROTO ((BUF_TYPE b, UTF8String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncUTF8StringContent BEncAsnOctsContent
+
+#define BDecUTF8StringContent BDecAsnOctsContent
+
+#define PrintUTF8String PrintAsnOcts
+
+#define FreeUTF8String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts NumericString; /* [UNIVERSAL 18] IMPLICIT OCTET STRING */
+
+AsnLen BEncNumericString PROTO ((BUF_TYPE b, NumericString *v));
+
+void BDecNumericString PROTO ((BUF_TYPE b, NumericString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncNumericStringContent BEncAsnOctsContent
+
+#define BDecNumericStringContent BDecAsnOctsContent
+
+#define PrintNumericString PrintAsnOcts
+
+#define FreeNumericString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts PrintableString; /* [UNIVERSAL 19] IMPLICIT OCTET STRING */
+
+AsnLen BEncPrintableString PROTO ((BUF_TYPE b, PrintableString *v));
+
+void BDecPrintableString PROTO ((BUF_TYPE b, PrintableString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncPrintableStringContent BEncAsnOctsContent
+
+#define BDecPrintableStringContent BDecAsnOctsContent
+
+#define PrintPrintableString PrintAsnOcts
+
+#define FreePrintableString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts TeletexString; /* [UNIVERSAL 20] IMPLICIT OCTET STRING */
+
+AsnLen BEncTeletexString PROTO ((BUF_TYPE b, TeletexString *v));
+
+void BDecTeletexString PROTO ((BUF_TYPE b, TeletexString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncTeletexStringContent BEncAsnOctsContent
+
+#define BDecTeletexStringContent BDecAsnOctsContent
+
+#define PrintTeletexString PrintAsnOcts
+
+#define FreeTeletexString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts T61String; /* [UNIVERSAL 20] IMPLICIT OCTET STRING */
+
+AsnLen BEncT61String PROTO ((BUF_TYPE b, T61String *v));
+
+void BDecT61String PROTO ((BUF_TYPE b, T61String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncT61StringContent BEncAsnOctsContent
+
+#define BDecT61StringContent BDecAsnOctsContent
+
+#define PrintT61String PrintAsnOcts
+
+#define FreeT61String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts VideotexString; /* [UNIVERSAL 21] IMPLICIT OCTET STRING */
+
+AsnLen BEncVideotexString PROTO ((BUF_TYPE b, VideotexString *v));
+
+void BDecVideotexString PROTO ((BUF_TYPE b, VideotexString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncVideotexStringContent BEncAsnOctsContent
+
+#define BDecVideotexStringContent BDecAsnOctsContent
+
+#define PrintVideotexString PrintAsnOcts
+
+#define FreeVideotexString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts IA5String; /* [UNIVERSAL 22] IMPLICIT OCTET STRING */
+
+AsnLen BEncIA5String PROTO ((BUF_TYPE b, IA5String *v));
+
+void BDecIA5String PROTO ((BUF_TYPE b, IA5String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncIA5StringContent BEncAsnOctsContent
+
+#define BDecIA5StringContent BDecAsnOctsContent
+
+#define PrintIA5String PrintAsnOcts
+
+#define FreeIA5String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GraphicString; /* [UNIVERSAL 25] IMPLICIT OCTET STRING */
+
+AsnLen BEncGraphicString PROTO ((BUF_TYPE b, GraphicString *v));
+
+void BDecGraphicString PROTO ((BUF_TYPE b, GraphicString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGraphicStringContent BEncAsnOctsContent
+
+#define BDecGraphicStringContent BDecAsnOctsContent
+
+#define PrintGraphicString PrintAsnOcts
+
+#define FreeGraphicString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts VisibleString; /* [UNIVERSAL 26] IMPLICIT OCTET STRING */
+
+AsnLen BEncVisibleString PROTO ((BUF_TYPE b, VisibleString *v));
+
+void BDecVisibleString PROTO ((BUF_TYPE b, VisibleString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncVisibleStringContent BEncAsnOctsContent
+
+#define BDecVisibleStringContent BDecAsnOctsContent
+
+#define PrintVisibleString PrintAsnOcts
+
+#define FreeVisibleString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts ISO646String; /* [UNIVERSAL 26] IMPLICIT OCTET STRING */
+
+AsnLen BEncISO646String PROTO ((BUF_TYPE b, ISO646String *v));
+
+void BDecISO646String PROTO ((BUF_TYPE b, ISO646String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncISO646StringContent BEncAsnOctsContent
+
+#define BDecISO646StringContent BDecAsnOctsContent
+
+#define PrintISO646String PrintAsnOcts
+
+#define FreeISO646String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GeneralString; /* [UNIVERSAL 27] IMPLICIT OCTET STRING */
+
+AsnLen BEncGeneralString PROTO ((BUF_TYPE b, GeneralString *v));
+
+void BDecGeneralString PROTO ((BUF_TYPE b, GeneralString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGeneralStringContent BEncAsnOctsContent
+
+#define BDecGeneralStringContent BDecAsnOctsContent
+
+#define PrintGeneralString PrintAsnOcts
+
+#define FreeGeneralString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts UTCTime; /* [UNIVERSAL 23] IMPLICIT OCTET STRING */
+
+AsnLen BEncUTCTime PROTO ((BUF_TYPE b, UTCTime *v));
+
+void BDecUTCTime PROTO ((BUF_TYPE b, UTCTime *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncUTCTimeContent BEncAsnOctsContent
+
+#define BDecUTCTimeContent BDecAsnOctsContent
+
+#define PrintUTCTime PrintAsnOcts
+
+#define FreeUTCTime FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GeneralizedTime; /* [UNIVERSAL 24] IMPLICIT OCTET STRING */
+
+AsnLen BEncGeneralizedTime PROTO ((BUF_TYPE b, GeneralizedTime *v));
+
+void BDecGeneralizedTime PROTO ((BUF_TYPE b, GeneralizedTime *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGeneralizedTimeContent BEncAsnOctsContent
+
+#define BDecGeneralizedTimeContent BDecAsnOctsContent
+
+#define PrintGeneralizedTime PrintAsnOcts
+
+#define FreeGeneralizedTime FreeAsnOcts 
+
+
+
+
+typedef AsnOcts UniversalString; /* [UNIVERSAL 28] IMPLICIT OCTET STRING */
+
+AsnLen BEncUniversalString PROTO ((BUF_TYPE b, UniversalString *v));
+
+void BDecUniversalString PROTO ((BUF_TYPE b, UniversalString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncUniversalStringContent BEncAsnOctsContent
+
+#define BDecUniversalStringContent BDecAsnOctsContent
+
+#define PrintUniversalString PrintAsnOcts
+
+#define FreeUniversalString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts BMPString; /* [UNIVERSAL 30] IMPLICIT OCTET STRING */
+
+AsnLen BEncBMPString PROTO ((BUF_TYPE b, BMPString *v));
+
+void BDecBMPString PROTO ((BUF_TYPE b, BMPString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncBMPStringContent BEncAsnOctsContent
+
+#define BDecBMPStringContent BDecAsnOctsContent
+
+#define PrintBMPString PrintAsnOcts
+
+#define FreeBMPString FreeAsnOcts 
+
+
+
+
+typedef struct EXTERNALChoice /* CHOICE */
+{
+    enum EXTERNALChoiceChoiceId
+    {
+        EXTERNALCHOICE_SINGLE_ASN1_TYPE,
+        EXTERNALCHOICE_OCTET_ALIGNED,
+        EXTERNALCHOICE_ARBITRARY
+    } choiceId;
+    union EXTERNALChoiceChoiceUnion
+    {
+    AsnOcts* single_ASN1_type; /* [0] OCTET STRING */
+    AsnOcts* octet_aligned; /* [1] IMPLICIT OCTET STRING */
+    AsnBits* arbitrary; /* [2] IMPLICIT BIT STRING */
+    } a;
+} EXTERNALChoice;
+
+AsnLen BEncEXTERNALChoiceContent PROTO ((BUF_TYPE b, EXTERNALChoice *v));
+
+void BDecEXTERNALChoiceContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, EXTERNALChoice *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintEXTERNALChoice PROTO ((FILE* f, EXTERNALChoice *v, unsigned short int indent));
+void FreeEXTERNALChoice PROTO ((EXTERNALChoice *v));
+
+
+
+
+
+typedef struct EXTERNAL /* [UNIVERSAL 8] IMPLICIT SEQUENCE */
+{
+    AsnOid direct_reference; /* OBJECT IDENTIFIER OPTIONAL */
+    AsnInt* indirect_reference; /* INTEGER OPTIONAL */
+    ObjectDescriptor data_value_descriptor; /* ObjectDescriptor OPTIONAL */
+    struct EXTERNALChoice* encoding; /* EXTERNALChoice */
+} EXTERNAL;
+
+AsnLen BEncEXTERNAL PROTO ((BUF_TYPE b, EXTERNAL *v));
+
+void BDecEXTERNAL PROTO ((BUF_TYPE b, EXTERNAL *result, AsnLen *bytesDecoded, ENV_TYPE env));
+AsnLen BEncEXTERNALContent PROTO ((BUF_TYPE b, EXTERNAL *v));
+
+void BDecEXTERNALContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, EXTERNAL *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintEXTERNAL PROTO ((FILE* f, EXTERNAL *v, unsigned short int indent));
+void FreeEXTERNAL PROTO ((EXTERNAL *v));
+
+
+
+
+
+
+#endif /* conditional include of asn-useful.h */
diff --git a/SecuritySNACCRuntime/c-lib/boot/asn-useful.c b/SecuritySNACCRuntime/c-lib/boot/asn-useful.c
new file mode 100644
index 00000000..415b7009
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/boot/asn-useful.c
@@ -0,0 +1,799 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    asn-useful.c
+ *
+ *    "ASN-USEFUL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Mon Mar  3 11:08:41 1997
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "asn-useful.h"
+
+
+AsnLen BEncNumericString PARAMS ((b, v),
+BUF_TYPE b _AND_
+NumericString *v)
+{
+    AsnLen l;
+    l = BEncNumericStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE);
+    return l;
+} /* BEncNumericString */
+
+void BDecNumericString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+NumericString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecNumericString: ERROR - wrong tag\n");
+        longjmp (env, 50);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecNumericStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecNumericString */
+
+AsnLen BEncPrintableString PARAMS ((b, v),
+BUF_TYPE b _AND_
+PrintableString *v)
+{
+    AsnLen l;
+    l = BEncPrintableStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+    return l;
+} /* BEncPrintableString */
+
+void BDecPrintableString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+PrintableString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecPrintableString: ERROR - wrong tag\n");
+        longjmp (env, 49);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecPrintableStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecPrintableString */
+
+AsnLen BEncTeletexString PARAMS ((b, v),
+BUF_TYPE b _AND_
+TeletexString *v)
+{
+    AsnLen l;
+    l = BEncTeletexStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+} /* BEncTeletexString */
+
+void BDecTeletexString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+TeletexString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecTeletexString: ERROR - wrong tag\n");
+        longjmp (env, 48);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecTeletexStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecTeletexString */
+
+AsnLen BEncT61String PARAMS ((b, v),
+BUF_TYPE b _AND_
+T61String *v)
+{
+    AsnLen l;
+    l = BEncT61StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+} /* BEncT61String */
+
+void BDecT61String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+T61String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecT61String: ERROR - wrong tag\n");
+        longjmp (env, 47);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecT61StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecT61String */
+
+AsnLen BEncVideotexString PARAMS ((b, v),
+BUF_TYPE b _AND_
+VideotexString *v)
+{
+    AsnLen l;
+    l = BEncVideotexStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE);
+    return l;
+} /* BEncVideotexString */
+
+void BDecVideotexString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+VideotexString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VIDEOTEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecVideotexString: ERROR - wrong tag\n");
+        longjmp (env, 46);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecVideotexStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecVideotexString */
+
+AsnLen BEncIA5String PARAMS ((b, v),
+BUF_TYPE b _AND_
+IA5String *v)
+{
+    AsnLen l;
+    l = BEncIA5StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, IA5STRING_TAG_CODE);
+    return l;
+} /* BEncIA5String */
+
+void BDecIA5String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+IA5String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, IA5STRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, IA5STRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecIA5String: ERROR - wrong tag\n");
+        longjmp (env, 45);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecIA5StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecIA5String */
+
+AsnLen BEncGraphicString PARAMS ((b, v),
+BUF_TYPE b _AND_
+GraphicString *v)
+{
+    AsnLen l;
+    l = BEncGraphicStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GRAPHICSTRING_TAG_CODE);
+    return l;
+} /* BEncGraphicString */
+
+void BDecGraphicString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GraphicString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GRAPHICSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GRAPHICSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecGraphicString: ERROR - wrong tag\n");
+        longjmp (env, 44);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGraphicStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGraphicString */
+
+AsnLen BEncVisibleString PARAMS ((b, v),
+BUF_TYPE b _AND_
+VisibleString *v)
+{
+    AsnLen l;
+    l = BEncVisibleStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+} /* BEncVisibleString */
+
+void BDecVisibleString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+VisibleString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecVisibleString: ERROR - wrong tag\n");
+        longjmp (env, 43);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecVisibleStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecVisibleString */
+
+AsnLen BEncISO646String PARAMS ((b, v),
+BUF_TYPE b _AND_
+ISO646String *v)
+{
+    AsnLen l;
+    l = BEncISO646StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+} /* BEncISO646String */
+
+void BDecISO646String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+ISO646String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecISO646String: ERROR - wrong tag\n");
+        longjmp (env, 42);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecISO646StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecISO646String */
+
+AsnLen BEncGeneralString PARAMS ((b, v),
+BUF_TYPE b _AND_
+GeneralString *v)
+{
+    AsnLen l;
+    l = BEncGeneralStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GENERALSTRING_TAG_CODE);
+    return l;
+} /* BEncGeneralString */
+
+void BDecGeneralString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GeneralString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GENERALSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GENERALSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecGeneralString: ERROR - wrong tag\n");
+        longjmp (env, 41);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGeneralStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGeneralString */
+
+AsnLen BEncUTCTime PARAMS ((b, v),
+BUF_TYPE b _AND_
+UTCTime *v)
+{
+    AsnLen l;
+    l = BEncUTCTimeContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, UTCTIME_TAG_CODE);
+    return l;
+} /* BEncUTCTime */
+
+void BDecUTCTime PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+UTCTime *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE)))
+    {
+        Asn1Error ("BDecUTCTime: ERROR - wrong tag\n");
+        longjmp (env, 40);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecUTCTimeContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecUTCTime */
+
+AsnLen BEncGeneralizedTime PARAMS ((b, v),
+BUF_TYPE b _AND_
+GeneralizedTime *v)
+{
+    AsnLen l;
+    l = BEncGeneralizedTimeContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    return l;
+} /* BEncGeneralizedTime */
+
+void BDecGeneralizedTime PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GeneralizedTime *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+    {
+        Asn1Error ("BDecGeneralizedTime: ERROR - wrong tag\n");
+        longjmp (env, 39);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGeneralizedTimeContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGeneralizedTime */
+
+AsnLen
+BEncEXTERNALChoiceContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNALChoice *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+    BEncEocIfNec (b);
+    itemLen = BEncAsnOctsContent (b, (v->a.single_ASN1_type));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 4);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case EXTERNALCHOICE_OCTET_ALIGNED:
+    itemLen = BEncAsnOctsContent (b, (v->a.octet_aligned));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case EXTERNALCHOICE_ARBITRARY:
+    itemLen = BEncAsnBitsContent (b, (v->a.arbitrary));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncEXTERNALChoiceContent */
+
+void
+BDecEXTERNALChoiceContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+EXTERNALChoice *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+
+
+    switch (tagId0)
+    {
+       case MAKE_TAG_ID (CNTX, CONS, 0):
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+if ((tagId1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) &&
+   (tagId1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, 38);
+    }
+
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+        (v->choiceId) = EXTERNALCHOICE_SINGLE_ASN1_TYPE;
+    (v->a.single_ASN1_type) = (AsnOcts*) Asn1Alloc (sizeof (AsnOcts));
+    CheckAsn1Alloc ((v->a.single_ASN1_type), env);
+    BDecAsnOctsContent (b, tagId1, elmtLen1, (v->a.single_ASN1_type), &totalElmtsLen1, env);
+    if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, PRIM, 1):
+       case MAKE_TAG_ID (CNTX, CONS, 1):
+        (v->choiceId) = EXTERNALCHOICE_OCTET_ALIGNED;
+    (v->a.octet_aligned) = (AsnOcts*) Asn1Alloc (sizeof (AsnOcts));
+    CheckAsn1Alloc ((v->a.octet_aligned), env);
+    BDecAsnOctsContent (b, tagId0, elmtLen0, (v->a.octet_aligned), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, PRIM, 2):
+       case MAKE_TAG_ID (CNTX, CONS, 2):
+        (v->choiceId) = EXTERNALCHOICE_ARBITRARY;
+    (v->a.arbitrary) = (AsnBits*) Asn1Alloc (sizeof (AsnBits));
+    CheckAsn1Alloc ((v->a.arbitrary), env);
+    BDecAsnBitsContent (b, tagId0, elmtLen0, (v->a.arbitrary), &totalElmtsLen1, env);
+    break;
+
+    default:
+        Asn1Error ("ERROR - unexpected tag in CHOICE\n");
+        longjmp (env, 37);
+        break;
+    } /* end switch */
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecEXTERNALChoiceContent */
+
+void
+PrintEXTERNALChoice PARAMS ((f, v, indent),
+FILE* f _AND_
+EXTERNALChoice *v _AND_
+unsigned short int indent)
+{
+    switch (v->choiceId)
+    {
+      case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+          fprintf (f,"single-ASN1-type ");
+    PrintAsnOcts (f, (v->a.single_ASN1_type), indent + stdIndentG);
+          break;
+
+      case EXTERNALCHOICE_OCTET_ALIGNED:
+          fprintf (f,"octet-aligned ");
+    PrintAsnOcts (f, (v->a.octet_aligned), indent + stdIndentG);
+          break;
+
+      case EXTERNALCHOICE_ARBITRARY:
+          fprintf (f,"arbitrary ");
+    PrintAsnBits (f, (v->a.arbitrary), indent + stdIndentG);
+          break;
+
+    }
+}  /* PrintEXTERNALChoice */
+
+void
+FreeEXTERNALChoice PARAMS ((v),
+EXTERNALChoice *v)
+{
+
+    if (v == NULL)
+        return;
+    switch (v->choiceId)
+    {
+       case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+    FreeAsnOcts ((v->a.single_ASN1_type));
+    Asn1Free ((v->a.single_ASN1_type));
+
+    break;
+
+       case EXTERNALCHOICE_OCTET_ALIGNED:
+    FreeAsnOcts ((v->a.octet_aligned));
+    Asn1Free ((v->a.octet_aligned));
+
+    break;
+
+       case EXTERNALCHOICE_ARBITRARY:
+    FreeAsnBits ((v->a.arbitrary));
+    Asn1Free ((v->a.arbitrary));
+
+    break;
+
+    }
+}  /* FreeEXTERNALChoice */
+
+
+
+
+AsnLen BEncEXTERNAL PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNAL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncEXTERNALContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, EXTERNAL_TAG_CODE);
+    return l;
+} /* BEncEXTERNAL */
+
+void BDecEXTERNAL PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+EXTERNAL *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, CONS, EXTERNAL_TAG_CODE)))
+    {
+        Asn1Error ("BDecEXTERNAL: ERROR - wrong tag\n");
+        longjmp (env, 36);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecEXTERNALContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecEXTERNAL */
+
+AsnLen
+BEncEXTERNALContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNAL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncEXTERNALChoiceContent (b, (v->encoding));
+
+    totalLen += itemLen;
+
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    itemLen = BEncObjectDescriptorContent (b, (&v->data_value_descriptor));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 7);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    itemLen = BEncAsnIntContent (b, (v->indirect_reference));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->direct_reference));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 6);
+
+    totalLen += itemLen;
+    }
+
+    return totalLen;
+
+}  /* BEncEXTERNALContent */
+
+void
+BDecEXTERNALContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+EXTERNAL *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnOidContent (b, tagId1, elmtLen1, (&v->direct_reference), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->indirect_reference) = (AsnInt*) Asn1Alloc (sizeof (AsnInt));
+    CheckAsn1Alloc ((v->indirect_reference), env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (v->indirect_reference), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, OD_TAG_CODE)) ||
+(tagId1 == MAKE_TAG_ID (UNIV, CONS, OD_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecObjectDescriptorContent (b, tagId1, elmtLen1, (&v->data_value_descriptor), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 0)) ||
+    (tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))||
+    (tagId1 == MAKE_TAG_ID (CNTX, CONS, 1)) ||
+    (tagId1 == MAKE_TAG_ID (CNTX, PRIM, 2))||
+    (tagId1 == MAKE_TAG_ID (CNTX, CONS, 2))))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->encoding) = (EXTERNALChoice*) Asn1Alloc (sizeof (EXTERNALChoice));
+    CheckAsn1Alloc ((v->encoding), env);
+    BDecEXTERNALChoiceContent (b, tagId1, elmtLen1, (v->encoding), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, 35);
+    }
+    else
+        longjmp (env, 34);
+
+
+    if (!seqDone)
+        longjmp (env, 33);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecEXTERNALContent */
+
+void
+PrintEXTERNAL PARAMS ((f, v, indent),
+FILE* f _AND_
+EXTERNAL *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"direct-reference ");
+    PrintAsnOid (f, (&v->direct_reference), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"indirect-reference ");
+    PrintAsnInt (f, (v->indirect_reference), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"data-value-descriptor ");
+    PrintObjectDescriptor (f, (&v->data_value_descriptor), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"encoding ");
+    PrintEXTERNALChoice (f, (v->encoding), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintEXTERNAL */
+
+void
+FreeEXTERNAL PARAMS ((v),
+EXTERNAL *v)
+{
+
+    if (v == NULL)
+        return;
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    FreeAsnOid ((&v->direct_reference));
+    }
+
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    FreeAsnInt ((v->indirect_reference));
+    Asn1Free ((v->indirect_reference));
+    }
+
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    FreeObjectDescriptor ((&v->data_value_descriptor));
+    }
+
+    FreeEXTERNALChoice ((v->encoding));
+    Asn1Free ((v->encoding));
+
+}  /* FreeEXTERNAL */
+
+
+
+
diff --git a/SecuritySNACCRuntime/c-lib/boot/asn-useful.h b/SecuritySNACCRuntime/c-lib/boot/asn-useful.h
new file mode 100644
index 00000000..bc7502ac
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/boot/asn-useful.h
@@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    asn-useful.h
+ *
+ *    "ASN-USEFUL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Mon Mar  3 11:08:41 1997
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _asn_useful_h_
+#define _asn_useful_h_
+
+
+
+
+typedef AsnOcts ObjectDescriptor; /* [UNIVERSAL 7] IMPLICIT OCTET STRING */
+
+#define BEncObjectDescriptorContent BEncAsnOctsContent
+
+#define BDecObjectDescriptorContent BDecAsnOctsContent
+
+#define PrintObjectDescriptor PrintAsnOcts
+
+#define FreeObjectDescriptor FreeAsnOcts 
+
+
+
+
+typedef AsnOcts NumericString; /* [UNIVERSAL 18] IMPLICIT OCTET STRING */
+
+AsnLen BEncNumericString PROTO ((BUF_TYPE b, NumericString *v));
+
+void BDecNumericString PROTO ((BUF_TYPE b, NumericString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncNumericStringContent BEncAsnOctsContent
+
+#define BDecNumericStringContent BDecAsnOctsContent
+
+#define PrintNumericString PrintAsnOcts
+
+#define FreeNumericString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts PrintableString; /* [UNIVERSAL 19] IMPLICIT OCTET STRING */
+
+AsnLen BEncPrintableString PROTO ((BUF_TYPE b, PrintableString *v));
+
+void BDecPrintableString PROTO ((BUF_TYPE b, PrintableString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncPrintableStringContent BEncAsnOctsContent
+
+#define BDecPrintableStringContent BDecAsnOctsContent
+
+#define PrintPrintableString PrintAsnOcts
+
+#define FreePrintableString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts TeletexString; /* [UNIVERSAL 20] IMPLICIT OCTET STRING */
+
+AsnLen BEncTeletexString PROTO ((BUF_TYPE b, TeletexString *v));
+
+void BDecTeletexString PROTO ((BUF_TYPE b, TeletexString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncTeletexStringContent BEncAsnOctsContent
+
+#define BDecTeletexStringContent BDecAsnOctsContent
+
+#define PrintTeletexString PrintAsnOcts
+
+#define FreeTeletexString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts T61String; /* [UNIVERSAL 20] IMPLICIT OCTET STRING */
+
+AsnLen BEncT61String PROTO ((BUF_TYPE b, T61String *v));
+
+void BDecT61String PROTO ((BUF_TYPE b, T61String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncT61StringContent BEncAsnOctsContent
+
+#define BDecT61StringContent BDecAsnOctsContent
+
+#define PrintT61String PrintAsnOcts
+
+#define FreeT61String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts VideotexString; /* [UNIVERSAL 21] IMPLICIT OCTET STRING */
+
+AsnLen BEncVideotexString PROTO ((BUF_TYPE b, VideotexString *v));
+
+void BDecVideotexString PROTO ((BUF_TYPE b, VideotexString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncVideotexStringContent BEncAsnOctsContent
+
+#define BDecVideotexStringContent BDecAsnOctsContent
+
+#define PrintVideotexString PrintAsnOcts
+
+#define FreeVideotexString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts IA5String; /* [UNIVERSAL 22] IMPLICIT OCTET STRING */
+
+AsnLen BEncIA5String PROTO ((BUF_TYPE b, IA5String *v));
+
+void BDecIA5String PROTO ((BUF_TYPE b, IA5String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncIA5StringContent BEncAsnOctsContent
+
+#define BDecIA5StringContent BDecAsnOctsContent
+
+#define PrintIA5String PrintAsnOcts
+
+#define FreeIA5String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GraphicString; /* [UNIVERSAL 25] IMPLICIT OCTET STRING */
+
+AsnLen BEncGraphicString PROTO ((BUF_TYPE b, GraphicString *v));
+
+void BDecGraphicString PROTO ((BUF_TYPE b, GraphicString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGraphicStringContent BEncAsnOctsContent
+
+#define BDecGraphicStringContent BDecAsnOctsContent
+
+#define PrintGraphicString PrintAsnOcts
+
+#define FreeGraphicString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts VisibleString; /* [UNIVERSAL 26] IMPLICIT OCTET STRING */
+
+AsnLen BEncVisibleString PROTO ((BUF_TYPE b, VisibleString *v));
+
+void BDecVisibleString PROTO ((BUF_TYPE b, VisibleString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncVisibleStringContent BEncAsnOctsContent
+
+#define BDecVisibleStringContent BDecAsnOctsContent
+
+#define PrintVisibleString PrintAsnOcts
+
+#define FreeVisibleString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts ISO646String; /* [UNIVERSAL 26] IMPLICIT OCTET STRING */
+
+AsnLen BEncISO646String PROTO ((BUF_TYPE b, ISO646String *v));
+
+void BDecISO646String PROTO ((BUF_TYPE b, ISO646String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncISO646StringContent BEncAsnOctsContent
+
+#define BDecISO646StringContent BDecAsnOctsContent
+
+#define PrintISO646String PrintAsnOcts
+
+#define FreeISO646String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GeneralString; /* [UNIVERSAL 27] IMPLICIT OCTET STRING */
+
+AsnLen BEncGeneralString PROTO ((BUF_TYPE b, GeneralString *v));
+
+void BDecGeneralString PROTO ((BUF_TYPE b, GeneralString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGeneralStringContent BEncAsnOctsContent
+
+#define BDecGeneralStringContent BDecAsnOctsContent
+
+#define PrintGeneralString PrintAsnOcts
+
+#define FreeGeneralString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts UTCTime; /* [UNIVERSAL 23] IMPLICIT OCTET STRING */
+
+AsnLen BEncUTCTime PROTO ((BUF_TYPE b, UTCTime *v));
+
+void BDecUTCTime PROTO ((BUF_TYPE b, UTCTime *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncUTCTimeContent BEncAsnOctsContent
+
+#define BDecUTCTimeContent BDecAsnOctsContent
+
+#define PrintUTCTime PrintAsnOcts
+
+#define FreeUTCTime FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GeneralizedTime; /* [UNIVERSAL 24] IMPLICIT OCTET STRING */
+
+AsnLen BEncGeneralizedTime PROTO ((BUF_TYPE b, GeneralizedTime *v));
+
+void BDecGeneralizedTime PROTO ((BUF_TYPE b, GeneralizedTime *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGeneralizedTimeContent BEncAsnOctsContent
+
+#define BDecGeneralizedTimeContent BDecAsnOctsContent
+
+#define PrintGeneralizedTime PrintAsnOcts
+
+#define FreeGeneralizedTime FreeAsnOcts 
+
+
+
+
+typedef struct EXTERNALChoice /* CHOICE */
+{
+    enum EXTERNALChoiceChoiceId
+    {
+        EXTERNALCHOICE_SINGLE_ASN1_TYPE,
+        EXTERNALCHOICE_OCTET_ALIGNED,
+        EXTERNALCHOICE_ARBITRARY
+    } choiceId;
+    union EXTERNALChoiceChoiceUnion
+    {
+    AsnOcts* single_ASN1_type; /* [0] OCTET STRING */
+    AsnOcts* octet_aligned; /* [1] IMPLICIT OCTET STRING */
+    AsnBits* arbitrary; /* [2] IMPLICIT BIT STRING */
+    } a;
+} EXTERNALChoice;
+
+AsnLen BEncEXTERNALChoiceContent PROTO ((BUF_TYPE b, EXTERNALChoice *v));
+
+void BDecEXTERNALChoiceContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, EXTERNALChoice *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintEXTERNALChoice PROTO ((FILE* f, EXTERNALChoice *v, unsigned short int indent));
+void FreeEXTERNALChoice PROTO ((EXTERNALChoice *v));
+
+
+
+
+
+typedef struct EXTERNAL /* [UNIVERSAL 8] IMPLICIT SEQUENCE */
+{
+    AsnOid direct_reference; /* OBJECT IDENTIFIER OPTIONAL */
+    AsnInt* indirect_reference; /* INTEGER OPTIONAL */
+    ObjectDescriptor data_value_descriptor; /* ObjectDescriptor OPTIONAL */
+    struct EXTERNALChoice* encoding; /* EXTERNALChoice */
+} EXTERNAL;
+
+AsnLen BEncEXTERNAL PROTO ((BUF_TYPE b, EXTERNAL *v));
+
+void BDecEXTERNAL PROTO ((BUF_TYPE b, EXTERNAL *result, AsnLen *bytesDecoded, ENV_TYPE env));
+AsnLen BEncEXTERNALContent PROTO ((BUF_TYPE b, EXTERNAL *v));
+
+void BDecEXTERNALContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, EXTERNAL *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintEXTERNAL PROTO ((FILE* f, EXTERNAL *v, unsigned short int indent));
+void FreeEXTERNAL PROTO ((EXTERNAL *v));
+
+
+
+
+
+
+#endif /* conditional include of asn-useful.h */
diff --git a/SecuritySNACCRuntime/c-lib/boot/tbl.c b/SecuritySNACCRuntime/c-lib/boot/tbl.c
new file mode 100644
index 00000000..f37ac7d0
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/boot/tbl.c
@@ -0,0 +1,2137 @@
+/*
+ * 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.
+ */
+
+
+#if TTBL
+/*
+ *    tbl.c
+ *
+ *    "TBL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Mon Jun  2 11:23:56 1997
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "tbl.h"
+
+
+AsnLen
+BEncTBLRangeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLRange *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->to));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->from));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLRangeContent */
+
+void
+BDecTBLRangeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLRange *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->from), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -100);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->to), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -101);
+    }
+    else
+        longjmp (env, -102);
+
+
+    if (!seqDone)
+        longjmp (env, -103);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLRangeContent */
+
+void
+PrintTBLRange PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLRange *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"from ");
+    PrintAsnInt (f, (&v->from), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"to ");
+    PrintAsnInt (f, (&v->to), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLRange */
+
+void
+FreeTBLRange PARAMS ((v),
+TBLRange *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeAsnInt ((&v->from));
+
+    FreeAsnInt ((&v->to));
+
+}  /* FreeTBLRange */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumber *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->value));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLNamedNumberContent */
+
+void
+BDecTBLNamedNumberContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLNamedNumber *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->name), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -104);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->value), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -105);
+    }
+    else
+        longjmp (env, -106);
+
+
+    if (!seqDone)
+        longjmp (env, -107);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLNamedNumberContent */
+
+void
+PrintTBLNamedNumber PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLNamedNumber *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"name ");
+    PrintPrintableString (f, (&v->name), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"value ");
+    PrintAsnInt (f, (&v->value), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLNamedNumber */
+
+void
+FreeTBLNamedNumber PARAMS ((v),
+TBLNamedNumber *v)
+{
+
+    if (v == NULL)
+        return;
+    FreePrintableString ((&v->name));
+
+    FreeAsnInt ((&v->value));
+
+}  /* FreeTBLNamedNumber */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberListContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumberList *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLNamedNumberListContent */
+
+void
+BDecTBLNamedNumberListContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLNamedNumberList *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLNamedNumber **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLNamedNumber**) AsnListAppend (v);
+    (*tmpVar) = (TBLNamedNumber*) Asn1Alloc (sizeof (TBLNamedNumber));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLNamedNumberContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -108);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLNamedNumberListContent */
+
+void
+PrintTBLNamedNumberList PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLNamedNumberList *v _AND_
+unsigned short int indent)
+{
+    TBLNamedNumber *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLNamedNumber (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLNamedNumber*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLNamedNumberList */
+
+void
+FreeTBLNamedNumberList PARAMS ((v),
+TBLNamedNumberList *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLNamedNumber ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLNamedNumberList */
+
+
+
+
+AsnLen
+BEncTBLTypeRefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeRef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnBoolContent (b, (&v->implicit));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeRefContent */
+
+void
+BDecTBLTypeRefContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeRef *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeDefIdContent (b, tagId1, elmtLen1, (&v->typeDef), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -109);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->implicit), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -110);
+    }
+    else
+        longjmp (env, -111);
+
+
+    if (!seqDone)
+        longjmp (env, -112);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeRefContent */
+
+void
+PrintTBLTypeRef PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeRef *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDef ");
+    PrintTBLTypeDefId (f, (&v->typeDef), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"implicit ");
+    PrintAsnBool (f, (&v->implicit), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeRef */
+
+void
+FreeTBLTypeRef PARAMS ((v),
+TBLTypeRef *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeDefId ((&v->typeDef));
+
+    FreeAsnBool ((&v->implicit));
+
+}  /* FreeTBLTypeRef */
+
+
+
+
+AsnLen
+BEncTBLTagContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTag *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->code));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTagClassContent (b, (&v->tclass));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 10);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTagContent */
+
+void
+BDecTBLTagContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTag *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTagClassContent (b, tagId1, elmtLen1, (&v->tclass), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -113);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->code), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -114);
+    }
+    else
+        longjmp (env, -115);
+
+
+    if (!seqDone)
+        longjmp (env, -116);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTagContent */
+
+void
+PrintTBLTag PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTag *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"tclass ");
+    PrintTBLTagClass (f, (&v->tclass), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"code ");
+    PrintAsnInt (f, (&v->code), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTag */
+
+void
+FreeTBLTag PARAMS ((v),
+TBLTag *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTagClass ((&v->tclass));
+
+    FreeAsnInt ((&v->code));
+
+}  /* FreeTBLTag */
+
+
+
+
+AsnLen
+BEncTBLTypeSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTagContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeSeqOfContent */
+
+void
+BDecTBLTypeSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLTag **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLTag**) AsnListAppend (v);
+    (*tmpVar) = (TBLTag*) Asn1Alloc (sizeof (TBLTag));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTagContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -117);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeSeqOfContent */
+
+void
+PrintTBLTypeSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLTag *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLTag (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLTag*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeSeqOf */
+
+void
+FreeTBLTypeSeqOf PARAMS ((v),
+TBLTypeSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLTag ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLTypeSeqOf */
+
+
+
+
+AsnLen
+BEncTBLTypeContentSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContentSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeContentSeqOfContent */
+
+void
+BDecTBLTypeContentSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeContentSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLType **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLType**) AsnListAppend (v);
+    (*tmpVar) = (TBLType*) Asn1Alloc (sizeof (TBLType));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTypeContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -118);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContentSeqOfContent */
+
+void
+PrintTBLTypeContentSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeContentSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLType *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLType (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLType*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeContentSeqOf */
+
+void
+FreeTBLTypeContentSeqOf PARAMS ((v),
+TBLTypeContentSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLType ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLTypeContentSeqOf */
+
+
+
+
+AsnLen
+BEncTBLTypeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLType *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->values)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberListContent (b, (v->values));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 6);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLRangeContent (b, (v->constraint));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 5);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    itemLen = BEncPrintableStringContent (b, (&v->fieldName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 4);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentContent (b, (v->content));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncAsnBoolContent (b, (&v->optional));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeIdContent (b, (&v->typeId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeContent */
+
+void
+BDecTBLTypeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLType *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+    AsnLen totalElmtsLen3 = 0;
+    AsnLen elmtLen3;
+    AsnTag tagId3;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeIdContent (b, tagId1, elmtLen1, (&v->typeId), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -119);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->optional), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -120);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 2))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->tagList) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->tagList), env);
+    BDecTBLTypeSeqOfContent (b, tagId1, elmtLen1, (v->tagList), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 3))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->content) = (TBLTypeContent*) Asn1Alloc (sizeof (TBLTypeContent));
+    CheckAsn1Alloc ((v->content), env);
+    tagId2 = BDecTag (b, &totalElmtsLen1, env);
+    elmtLen2 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeContentContent (b, tagId2, elmtLen2, (v->content), &totalElmtsLen1, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+        BDecEoc(b, &totalElmtsLen1, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+        BDecEoc (b, &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+    else
+        longjmp (env, -121);
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 4)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 4))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->fieldName), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, CONS, 5))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->constraint) = (TBLRange*) Asn1Alloc (sizeof (TBLRange));
+    CheckAsn1Alloc ((v->constraint), env);
+    BDecTBLRangeContent (b, tagId1, elmtLen1, (v->constraint), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, CONS, 6))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->values) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->values), env);
+    BDecTBLNamedNumberListContent (b, tagId1, elmtLen1, (v->values), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -122);
+    }
+
+
+    if (!seqDone)
+        longjmp (env, -123);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContent */
+
+void
+PrintTBLType PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLType *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeId ");
+    PrintTBLTypeId (f, (&v->typeId), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"optional ");
+    PrintAsnBool (f, (&v->optional), indent + stdIndentG);
+    fprintf (f, ",\n");
+    if (NOT_NULL ((v->tagList)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"tagList ");
+    PrintTBLTypeSeqOf (f, (v->tagList), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"content ");
+    PrintTBLTypeContent (f, (v->content), indent + stdIndentG);
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"fieldName ");
+    PrintPrintableString (f, (&v->fieldName), indent + stdIndentG);
+    }
+    if (NOT_NULL ((v->constraint)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"constraint ");
+    PrintTBLRange (f, (v->constraint), indent + stdIndentG);
+    }
+    if (NOT_NULL ((v->values)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"values ");
+    PrintTBLNamedNumberList (f, (v->values), indent + stdIndentG);
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLType */
+
+void
+FreeTBLType PARAMS ((v),
+TBLType *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeId ((&v->typeId));
+
+    FreeAsnBool ((&v->optional));
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    FreeTBLTypeSeqOf ((v->tagList));
+    Asn1Free ((v->tagList));
+    }
+
+    FreeTBLTypeContent ((v->content));
+    Asn1Free ((v->content));
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    FreePrintableString ((&v->fieldName));
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    FreeTBLRange ((v->constraint));
+    Asn1Free ((v->constraint));
+    }
+
+    if (NOT_NULL ((v->values)))
+    {
+    FreeTBLNamedNumberList ((v->values));
+    Asn1Free ((v->values));
+    }
+
+}  /* FreeTBLType */
+
+
+
+
+AsnLen
+BEncTBLTypeContentContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContent *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_PRIMTYPE:
+    itemLen = BEncAsnNullContent (b, (&v->a.primType));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_ELMTS:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncTBLTypeContentContent */
+
+void
+BDecTBLTypeContentContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeContent *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    switch (tagId0)
+    {
+       case MAKE_TAG_ID (CNTX, PRIM, 0):
+        (v->choiceId) = TBLTYPECONTENT_PRIMTYPE;
+    BDecAsnNullContent (b, tagId0, elmtLen0, (&v->a.primType), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, CONS, 1):
+        (v->choiceId) = TBLTYPECONTENT_ELMTS;
+    (v->a.elmts) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->a.elmts), env);
+    BDecTBLTypeContentSeqOfContent (b, tagId0, elmtLen0, (v->a.elmts), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, CONS, 2):
+        (v->choiceId) = TBLTYPECONTENT_TYPEREF;
+    (v->a.typeRef) = (TBLTypeRef*) Asn1Alloc (sizeof (TBLTypeRef));
+    CheckAsn1Alloc ((v->a.typeRef), env);
+    BDecTBLTypeRefContent (b, tagId0, elmtLen0, (v->a.typeRef), &totalElmtsLen1, env);
+    break;
+
+    default:
+        Asn1Error ("ERROR - unexpected tag in CHOICE\n");
+        longjmp (env, -124);
+        break;
+    } /* end switch */
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContentContent */
+
+void
+PrintTBLTypeContent PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeContent *v _AND_
+unsigned short int indent)
+{
+    switch (v->choiceId)
+    {
+      case TBLTYPECONTENT_PRIMTYPE:
+          fprintf (f,"primType ");
+    PrintAsnNull (f, (&v->a.primType), indent + stdIndentG);
+          break;
+
+      case TBLTYPECONTENT_ELMTS:
+          fprintf (f,"elmts ");
+    PrintTBLTypeContentSeqOf (f, (v->a.elmts), indent + stdIndentG);
+          break;
+
+      case TBLTYPECONTENT_TYPEREF:
+          fprintf (f,"typeRef ");
+    PrintTBLTypeRef (f, (v->a.typeRef), indent + stdIndentG);
+          break;
+
+    }
+}  /* PrintTBLTypeContent */
+
+void
+FreeTBLTypeContent PARAMS ((v),
+TBLTypeContent *v)
+{
+
+    if (v == NULL)
+        return;
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_ELMTS:
+    FreeTBLTypeContentSeqOf ((v->a.elmts));
+    Asn1Free ((v->a.elmts));
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    FreeTBLTypeRef ((v->a.typeRef));
+    Asn1Free ((v->a.typeRef));
+
+    break;
+
+    }
+}  /* FreeTBLTypeContent */
+
+
+
+
+AsnLen
+BEncTBLTypeDefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeDef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    itemLen = BEncAsnNullContent (b, (v->isPdu));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 5);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, (v->type));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->typeName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 19);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeDefContent */
+
+void
+BDecTBLTypeDefContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeDef *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeDefIdContent (b, tagId1, elmtLen1, (&v->typeDefId), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -125);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE)) ||
+(tagId1 == MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->typeName), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -126);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->type) = (TBLType*) Asn1Alloc (sizeof (TBLType));
+    CheckAsn1Alloc ((v->type), env);
+    BDecTBLTypeContent (b, tagId1, elmtLen1, (v->type), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+    else
+        longjmp (env, -127);
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->isPdu) = (AsnNull*) Asn1Alloc (sizeof (AsnNull));
+    CheckAsn1Alloc ((v->isPdu), env);
+    BDecAsnNullContent (b, tagId1, elmtLen1, (v->isPdu), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -128);
+    }
+
+
+    if (!seqDone)
+        longjmp (env, -129);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeDefContent */
+
+void
+PrintTBLTypeDef PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeDef *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDefId ");
+    PrintTBLTypeDefId (f, (&v->typeDefId), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeName ");
+    PrintPrintableString (f, (&v->typeName), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"type ");
+    PrintTBLType (f, (v->type), indent + stdIndentG);
+    if (NOT_NULL ((v->isPdu)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"isPdu ");
+    PrintAsnNull (f, (v->isPdu), indent + stdIndentG);
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeDef */
+
+void
+FreeTBLTypeDef PARAMS ((v),
+TBLTypeDef *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeDefId ((&v->typeDefId));
+
+    FreePrintableString ((&v->typeName));
+
+    FreeTBLType ((v->type));
+    Asn1Free ((v->type));
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    FreeAsnNull ((v->isPdu));
+    Asn1Free ((v->isPdu));
+    }
+
+}  /* FreeTBLTypeDef */
+
+
+
+
+AsnLen
+BEncTBLModuleSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModuleSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeDefContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLModuleSeqOfContent */
+
+void
+BDecTBLModuleSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLModuleSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLTypeDef **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLTypeDef**) AsnListAppend (v);
+    (*tmpVar) = (TBLTypeDef*) Asn1Alloc (sizeof (TBLTypeDef));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTypeDefContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -130);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLModuleSeqOfContent */
+
+void
+PrintTBLModuleSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLModuleSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLTypeDef *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLTypeDef (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLTypeDef*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLModuleSeqOf */
+
+void
+FreeTBLModuleSeqOf PARAMS ((v),
+TBLModuleSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLTypeDef ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLModuleSeqOf */
+
+
+
+
+AsnLen
+BEncTBLModuleContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModule *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnBoolContent (b, (&v->isUseful));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->id));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLModuleContent */
+
+void
+BDecTBLModuleContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLModule *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->name), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -131);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnOidContent (b, tagId1, elmtLen1, (&v->id), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 2))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->isUseful), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -132);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 3))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->typeDefs) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->typeDefs), env);
+    BDecTBLModuleSeqOfContent (b, tagId1, elmtLen1, (v->typeDefs), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -133);
+    }
+    else
+        longjmp (env, -134);
+
+
+    if (!seqDone)
+        longjmp (env, -135);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLModuleContent */
+
+void
+PrintTBLModule PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLModule *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"name ");
+    PrintPrintableString (f, (&v->name), indent + stdIndentG);
+    fprintf (f, ",\n");
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"id ");
+    PrintAsnOid (f, (&v->id), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"isUseful ");
+    PrintAsnBool (f, (&v->isUseful), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDefs ");
+    PrintTBLModuleSeqOf (f, (v->typeDefs), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLModule */
+
+void
+FreeTBLModule PARAMS ((v),
+TBLModule *v)
+{
+
+    if (v == NULL)
+        return;
+    FreePrintableString ((&v->name));
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    FreeAsnOid ((&v->id));
+    }
+
+    FreeAsnBool ((&v->isUseful));
+
+    FreeTBLModuleSeqOf ((v->typeDefs));
+    Asn1Free ((v->typeDefs));
+
+}  /* FreeTBLModule */
+
+
+
+
+AsnLen
+BEncTBLSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLSeqOfContent */
+
+void
+BDecTBLSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLModule **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLModule**) AsnListAppend (v);
+    (*tmpVar) = (TBLModule*) Asn1Alloc (sizeof (TBLModule));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLModuleContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -136);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLSeqOfContent */
+
+void
+PrintTBLSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLModule *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLModule (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLModule*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLSeqOf */
+
+void
+FreeTBLSeqOf PARAMS ((v),
+TBLSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLModule ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLSeqOf */
+
+
+
+
+AsnLen BEncTBL PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncTBLContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    return l;
+} /* BEncTBL */
+
+void BDecTBL PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+TBL *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        Asn1Error ("BDecTBL: ERROR - wrong tag\n");
+        longjmp (env, -137);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecTBLContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecTBL */
+
+AsnLen
+BEncTBLContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLSeqOfContent (b, (v->modules));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalLenStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTags));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypes));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumModules));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLContent */
+
+void
+BDecTBLContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBL *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumModules), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -138);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTypeDefs), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -139);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTypes), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -140);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTags), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -141);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumStrings), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -142);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalLenStrings), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -143);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->modules) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->modules), env);
+    BDecTBLSeqOfContent (b, tagId1, elmtLen1, (v->modules), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -144);
+    }
+    else
+        longjmp (env, -145);
+
+
+    if (!seqDone)
+        longjmp (env, -146);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLContent */
+
+void
+PrintTBL PARAMS ((f, v, indent),
+FILE* f _AND_
+TBL *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumModules ");
+    PrintAsnInt (f, (&v->totalNumModules), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTypeDefs ");
+    PrintAsnInt (f, (&v->totalNumTypeDefs), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTypes ");
+    PrintAsnInt (f, (&v->totalNumTypes), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTags ");
+    PrintAsnInt (f, (&v->totalNumTags), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumStrings ");
+    PrintAsnInt (f, (&v->totalNumStrings), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalLenStrings ");
+    PrintAsnInt (f, (&v->totalLenStrings), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"modules ");
+    PrintTBLSeqOf (f, (v->modules), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBL */
+
+void
+FreeTBL PARAMS ((v),
+TBL *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeAsnInt ((&v->totalNumModules));
+
+    FreeAsnInt ((&v->totalNumTypeDefs));
+
+    FreeAsnInt ((&v->totalNumTypes));
+
+    FreeAsnInt ((&v->totalNumTags));
+
+    FreeAsnInt ((&v->totalNumStrings));
+
+    FreeAsnInt ((&v->totalLenStrings));
+
+    FreeTBLSeqOf ((v->modules));
+    Asn1Free ((v->modules));
+
+}  /* FreeTBL */
+
+
+
+
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/boot/tbl.h b/SecuritySNACCRuntime/c-lib/boot/tbl.h
new file mode 100644
index 00000000..57842c63
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/boot/tbl.h
@@ -0,0 +1,362 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    tbl.h
+ *
+ *    "TBL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Mon Jun  2 11:23:56 1997
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _tbl_h_
+#define _tbl_h_
+
+
+
+
+typedef enum
+    {
+        TBL_BOOLEAN = 0,
+        TBL_INTEGER = 1,
+        TBL_BITSTRING = 2,
+        TBL_OCTETSTRING = 3,
+        TBL_NULL = 4,
+        TBL_OID = 5,
+        TBL_REAL = 6,
+        TBL_ENUMERATED = 7,
+        TBL_SEQUENCE = 8,
+        TBL_SET = 9,
+        TBL_SEQUENCEOF = 10,
+        TBL_SETOF = 11,
+        TBL_CHOICE = 12,
+        TBL_TYPEREF = 13
+    } TBLTypeId; /* ENUMERATED { TBL_BOOLEAN (0), TBL_INTEGER (1), TBL_BITSTRING (2), TBL_OCTETSTRING (3), TBL_NULL (4), TBL_OID (5), TBL_REAL (6), TBL_ENUMERATED (7), TBL_SEQUENCE (8), TBL_SET (9), TBL_SEQUENCEOF (10), TBL_SETOF (11), TBL_CHOICE (12), TBL_TYPEREF (13) }  */
+
+#define BEncTBLTypeIdContent BEncAsnEnumContent
+
+#define BDecTBLTypeIdContent BDecAsnEnumContent
+
+#define PrintTBLTypeId PrintAsnEnum
+
+#define FreeTBLTypeId FreeAsnEnum 
+
+
+
+
+typedef AsnInt TBLTypeDefId; /* INTEGER */
+
+#define BEncTBLTypeDefIdContent BEncAsnIntContent
+
+#define BDecTBLTypeDefIdContent BDecAsnIntContent
+
+#define PrintTBLTypeDefId PrintAsnInt
+
+#define FreeTBLTypeDefId FreeAsnInt 
+
+
+
+
+typedef enum
+    {
+        UNIVERSAL = 0,
+        APPLICATION = 1,
+        CONTEXT = 2,
+        PRIVATE = 3
+    } TBLTagClass; /* ENUMERATED { UNIVERSAL (0), APPLICATION (1), CONTEXT (2), PRIVATE (3) }  */
+
+#define BEncTBLTagClassContent BEncAsnEnumContent
+
+#define BDecTBLTagClassContent BDecAsnEnumContent
+
+#define PrintTBLTagClass PrintAsnEnum
+
+#define FreeTBLTagClass FreeAsnEnum 
+
+
+
+
+typedef struct TBLRange /* SEQUENCE */
+{
+    AsnInt from; /* [0] IMPLICIT INTEGER */
+    AsnInt to; /* [1] IMPLICIT INTEGER */
+} TBLRange;
+
+AsnLen BEncTBLRangeContent PROTO ((BUF_TYPE b, TBLRange *v));
+
+void BDecTBLRangeContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLRange *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLRange PROTO ((FILE* f, TBLRange *v, unsigned short int indent));
+void FreeTBLRange PROTO ((TBLRange *v));
+
+
+
+
+
+typedef struct TBLNamedNumber /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnInt value; /* [1] IMPLICIT INTEGER */
+} TBLNamedNumber;
+
+AsnLen BEncTBLNamedNumberContent PROTO ((BUF_TYPE b, TBLNamedNumber *v));
+
+void BDecTBLNamedNumberContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLNamedNumber *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLNamedNumber PROTO ((FILE* f, TBLNamedNumber *v, unsigned short int indent));
+void FreeTBLNamedNumber PROTO ((TBLNamedNumber *v));
+
+
+
+
+
+typedef AsnList TBLNamedNumberList; /* SEQUENCE OF TBLNamedNumber */
+
+AsnLen BEncTBLNamedNumberListContent PROTO ((BUF_TYPE b, TBLNamedNumberList *v));
+
+void BDecTBLNamedNumberListContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLNamedNumberList *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLNamedNumberList PROTO ((FILE* f, TBLNamedNumberList *v, unsigned short int indent));
+void FreeTBLNamedNumberList PROTO ((TBLNamedNumberList *v));
+
+
+
+
+
+typedef struct TBLTypeRef /* SEQUENCE */
+{
+    TBLTypeDefId typeDef; /* TBLTypeDefId */
+    AsnBool implicit; /* BOOLEAN */
+    struct TBLTypeDef *typeDefPtr;  /* Added by MS to hold resolved index */
+} TBLTypeRef;
+
+AsnLen BEncTBLTypeRefContent PROTO ((BUF_TYPE b, TBLTypeRef *v));
+
+void BDecTBLTypeRefContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeRef *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeRef PROTO ((FILE* f, TBLTypeRef *v, unsigned short int indent));
+void FreeTBLTypeRef PROTO ((TBLTypeRef *v));
+
+
+
+
+
+typedef struct TBLTag /* SEQUENCE */
+{
+    TBLTagClass tclass; /* TBLTagClass */
+    AsnInt code; /* INTEGER (0..MAX) */
+    BER_FORM form; /* added by MS to simplify enc/dec */
+    AsnTag encTag; /* added by MS to simplify enc/dec */
+} TBLTag;
+
+AsnLen BEncTBLTagContent PROTO ((BUF_TYPE b, TBLTag *v));
+
+void BDecTBLTagContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTag *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTag PROTO ((FILE* f, TBLTag *v, unsigned short int indent));
+void FreeTBLTag PROTO ((TBLTag *v));
+
+
+
+
+
+typedef AsnList TBLTypeSeqOf; /* SEQUENCE OF TBLTag */
+
+AsnLen BEncTBLTypeSeqOfContent PROTO ((BUF_TYPE b, TBLTypeSeqOf *v));
+
+void BDecTBLTypeSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeSeqOf PROTO ((FILE* f, TBLTypeSeqOf *v, unsigned short int indent));
+void FreeTBLTypeSeqOf PROTO ((TBLTypeSeqOf *v));
+
+
+
+
+
+typedef AsnList TBLTypeContentSeqOf; /* SEQUENCE OF TBLType */
+
+AsnLen BEncTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, TBLTypeContentSeqOf *v));
+
+void BDecTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeContentSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeContentSeqOf PROTO ((FILE* f, TBLTypeContentSeqOf *v, unsigned short int indent));
+void FreeTBLTypeContentSeqOf PROTO ((TBLTypeContentSeqOf *v));
+
+
+
+
+
+typedef struct TBLType /* SEQUENCE */
+{
+    TBLTypeId typeId; /* [0] IMPLICIT TBLTypeId */
+    AsnBool optional; /* [1] IMPLICIT BOOLEAN */
+    TBLTypeSeqOf* tagList; /* [2] IMPLICIT TBLTypeSeqOf OPTIONAL */
+    struct TBLTypeContent* content; /* [3] TBLTypeContent */
+    PrintableString fieldName; /* [4] IMPLICIT PrintableString OPTIONAL */
+    struct TBLRange* constraint; /* [5] IMPLICIT TBLRange OPTIONAL */
+    TBLNamedNumberList* values; /* [6] IMPLICIT TBLNamedNumberList OPTIONAL */
+} TBLType;
+
+AsnLen BEncTBLTypeContent PROTO ((BUF_TYPE b, TBLType *v));
+
+void BDecTBLTypeContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLType *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLType PROTO ((FILE* f, TBLType *v, unsigned short int indent));
+void FreeTBLType PROTO ((TBLType *v));
+
+
+
+
+
+typedef struct TBLTypeContent /* CHOICE */
+{
+    enum TBLTypeContentChoiceId
+    {
+        TBLTYPECONTENT_PRIMTYPE,
+        TBLTYPECONTENT_ELMTS,
+        TBLTYPECONTENT_TYPEREF
+    } choiceId;
+    union TBLTypeContentChoiceUnion
+    {
+    AsnNull primType; /* [0] IMPLICIT NULL */
+    TBLTypeContentSeqOf* elmts; /* [1] IMPLICIT TBLTypeContentSeqOf */
+    struct TBLTypeRef* typeRef; /* [2] IMPLICIT TBLTypeRef */
+    } a;
+} TBLTypeContent;
+
+AsnLen BEncTBLTypeContentContent PROTO ((BUF_TYPE b, TBLTypeContent *v));
+
+void BDecTBLTypeContentContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeContent *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeContent PROTO ((FILE* f, TBLTypeContent *v, unsigned short int indent));
+void FreeTBLTypeContent PROTO ((TBLTypeContent *v));
+
+
+
+
+
+typedef struct TBLTypeDef /* SEQUENCE */
+{
+    TBLTypeDefId typeDefId; /* TBLTypeDefId */
+    PrintableString typeName; /* PrintableString */
+    struct TBLType* type; /* TBLType */
+    AsnNull* isPdu; /* NULL OPTIONAL */
+} TBLTypeDef;
+
+AsnLen BEncTBLTypeDefContent PROTO ((BUF_TYPE b, TBLTypeDef *v));
+
+void BDecTBLTypeDefContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeDef *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeDef PROTO ((FILE* f, TBLTypeDef *v, unsigned short int indent));
+void FreeTBLTypeDef PROTO ((TBLTypeDef *v));
+
+
+
+
+
+typedef AsnList TBLModuleSeqOf; /* SEQUENCE OF TBLTypeDef */
+
+AsnLen BEncTBLModuleSeqOfContent PROTO ((BUF_TYPE b, TBLModuleSeqOf *v));
+
+void BDecTBLModuleSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLModuleSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLModuleSeqOf PROTO ((FILE* f, TBLModuleSeqOf *v, unsigned short int indent));
+void FreeTBLModuleSeqOf PROTO ((TBLModuleSeqOf *v));
+
+
+
+
+
+typedef struct TBLModule /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnOid id; /* [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL */
+    AsnBool isUseful; /* [2] IMPLICIT BOOLEAN */
+    TBLModuleSeqOf* typeDefs; /* [3] IMPLICIT TBLModuleSeqOf */
+} TBLModule;
+
+AsnLen BEncTBLModuleContent PROTO ((BUF_TYPE b, TBLModule *v));
+
+void BDecTBLModuleContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLModule *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLModule PROTO ((FILE* f, TBLModule *v, unsigned short int indent));
+void FreeTBLModule PROTO ((TBLModule *v));
+
+
+
+
+
+typedef AsnList TBLSeqOf; /* SEQUENCE OF TBLModule */
+
+AsnLen BEncTBLSeqOfContent PROTO ((BUF_TYPE b, TBLSeqOf *v));
+
+void BDecTBLSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLSeqOf PROTO ((FILE* f, TBLSeqOf *v, unsigned short int indent));
+void FreeTBLSeqOf PROTO ((TBLSeqOf *v));
+
+
+
+
+
+typedef struct TBL /* SEQUENCE */
+{
+    AsnInt totalNumModules; /* INTEGER */
+    AsnInt totalNumTypeDefs; /* INTEGER */
+    AsnInt totalNumTypes; /* INTEGER */
+    AsnInt totalNumTags; /* INTEGER */
+    AsnInt totalNumStrings; /* INTEGER */
+    AsnInt totalLenStrings; /* INTEGER */
+    TBLSeqOf* modules; /* TBLSeqOf */
+} TBL;
+
+AsnLen BEncTBL PROTO ((BUF_TYPE b, TBL *v));
+
+void BDecTBL PROTO ((BUF_TYPE b, TBL *result, AsnLen *bytesDecoded, ENV_TYPE env));
+AsnLen BEncTBLContent PROTO ((BUF_TYPE b, TBL *v));
+
+void BDecTBLContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBL *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBL PROTO ((FILE* f, TBL *v, unsigned short int indent));
+void FreeTBL PROTO ((TBL *v));
+
+
+
+
+
+
+#endif /* conditional include of tbl.h */
diff --git a/SecuritySNACCRuntime/c-lib/dependencies b/SecuritySNACCRuntime/c-lib/dependencies
new file mode 100644
index 00000000..8c9eaed9
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/dependencies
@@ -0,0 +1,2011 @@
+asn-len.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h 
+asn-tag.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h 
+asn-int.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h 
+asn-bool.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h 
+asn-bits.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  inc/asn-len.h inc/asn-tag.h inc/str-stk.h inc/asn-bits.h 
+asn-octs.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/str-stk.h inc/asn-bits.h inc/asn-octs.h 
+asn-oid.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-octs.h inc/asn-oid.h 
+asn-real.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-real.h 
+asn-null.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-null.h 
+asn-list.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-list.h 
+asn-enum.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h inc/asn-enum.h 
+str-stk.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/str-stk.h 
+nibble-alloc.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h 
+print.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h 
+asn-any.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-oid.h inc/asn-octs.h inc/asn-int.h inc/asn-any.h \
+  inc/hash.h 
+hash.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/hash.h 
+exp-buf.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/gen-buf.h 
+sbuf.o : 
+tbl-dec.o : 
+tbl-enc.o : 
+tbl-free.o : 
+tbl-gen.o : 
+tbl-dbg.o : 
+tbl-print.o : 
+tbl-util.o : 
+asn-useful.o : inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h 
+tbl.o : 
+asn-len.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h 
+asn-tag.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h 
+asn-int.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h 
+asn-bool.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h 
+asn-bits.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  inc/asn-len.h inc/asn-tag.h inc/str-stk.h inc/asn-bits.h 
+asn-octs.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/str-stk.h inc/asn-bits.h inc/asn-octs.h 
+asn-oid.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-octs.h inc/asn-oid.h 
+asn-real.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-real.h 
+asn-null.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-null.h 
+asn-list.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-list.h 
+asn-enum.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h inc/asn-enum.h 
+str-stk.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/str-stk.h 
+nibble-alloc.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h 
+print.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h 
+asn-any.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-oid.h inc/asn-octs.h inc/asn-int.h inc/asn-any.h \
+  inc/hash.h 
+hash.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/hash.h 
+exp-buf.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/gen-buf.h 
+sbuf.o : 
+tbl-dec.o : 
+tbl-enc.o : 
+tbl-free.o : 
+tbl-gen.o : 
+tbl-dbg.o : 
+tbl-print.o : 
+tbl-util.o : 
+asn-useful.o : inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/exp-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h 
+tbl.o : 
+asn-len.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h 
+asn-tag.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h 
+asn-int.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h 
+asn-bool.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h 
+asn-bits.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  inc/asn-len.h inc/asn-tag.h inc/str-stk.h inc/asn-bits.h 
+asn-octs.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/str-stk.h inc/asn-bits.h inc/asn-octs.h 
+asn-oid.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-octs.h inc/asn-oid.h 
+asn-real.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-real.h 
+asn-null.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-null.h 
+asn-list.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-list.h 
+asn-enum.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h inc/asn-enum.h 
+str-stk.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/str-stk.h 
+nibble-alloc.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h 
+print.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h 
+asn-any.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-oid.h inc/asn-octs.h inc/asn-int.h inc/asn-any.h \
+  inc/hash.h 
+hash.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/hash.h 
+exp-buf.o : 
+sbuf.o : 
+tbl-dec.o : 
+tbl-enc.o : 
+tbl-free.o : 
+tbl-gen.o : 
+tbl-dbg.o : 
+tbl-print.o : 
+tbl-util.o : 
+asn-useful.o : inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/min-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h 
+tbl.o : 
+asn-len.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h 
+asn-tag.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h 
+asn-int.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h 
+asn-bool.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h 
+asn-bits.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  inc/asn-len.h inc/asn-tag.h inc/str-stk.h inc/asn-bits.h 
+asn-octs.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/str-stk.h inc/asn-bits.h inc/asn-octs.h 
+asn-oid.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-octs.h inc/asn-oid.h 
+asn-real.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-real.h 
+asn-null.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-null.h 
+asn-list.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-list.h 
+asn-enum.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h inc/asn-enum.h 
+str-stk.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/str-stk.h 
+nibble-alloc.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h 
+print.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h 
+asn-any.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-oid.h inc/asn-octs.h inc/asn-int.h inc/asn-any.h \
+  inc/hash.h 
+hash.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/hash.h 
+exp-buf.o : 
+sbuf.o : 
+tbl-dec.o : 
+tbl-enc.o : 
+tbl-free.o : 
+tbl-gen.o : 
+tbl-dbg.o : 
+tbl-print.o : 
+tbl-util.o : 
+asn-useful.o : inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/sbuf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h 
+tbl.o : 
+asn-len.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h 
+asn-tag.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h 
+asn-int.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h 
+asn-bool.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h 
+asn-bits.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  inc/asn-len.h inc/asn-tag.h inc/str-stk.h inc/asn-bits.h 
+asn-octs.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/str-stk.h inc/asn-bits.h inc/asn-octs.h 
+asn-oid.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-octs.h inc/asn-oid.h 
+asn-real.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-real.h 
+asn-null.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-null.h 
+asn-list.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-list.h 
+asn-enum.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-int.h inc/asn-enum.h 
+str-stk.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/str-stk.h 
+nibble-alloc.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h 
+print.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h 
+asn-any.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-oid.h inc/asn-octs.h inc/asn-int.h inc/asn-any.h \
+  inc/hash.h 
+hash.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/hash.h 
+exp-buf.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/exp-buf.h 
+sbuf.o : inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/sbuf.h 
+tbl-dec.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  inc/tbl-incl.h inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h inc/tbl.h inc/tbl-util.h \
+  inc/tbl-enc.h inc/tbl-dec.h inc/tbl-print.h inc/tbl-free.h 
+tbl-enc.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  inc/tbl-incl.h inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h inc/tbl.h inc/tbl-util.h \
+  inc/tbl-enc.h inc/tbl-dec.h inc/tbl-print.h inc/tbl-free.h 
+tbl-free.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  inc/tbl-incl.h inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h inc/tbl.h inc/tbl-util.h \
+  inc/tbl-enc.h inc/tbl-dec.h inc/tbl-print.h inc/tbl-free.h 
+tbl-gen.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  inc/tbl-gen.h inc/tbl-incl.h inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h inc/tbl.h inc/tbl-util.h \
+  inc/tbl-enc.h inc/tbl-dec.h inc/tbl-print.h inc/tbl-free.h 
+tbl-dbg.o : inc/tbl-dbg.h inc/tbl-gen.h inc/tbl-incl.h inc/asn-incl.h \
+  inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h inc/tbl.h inc/tbl-util.h \
+  inc/tbl-enc.h inc/tbl-dec.h inc/tbl-print.h inc/tbl-free.h 
+tbl-print.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  inc/tbl-incl.h inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h inc/tbl.h inc/tbl-util.h \
+  inc/tbl-enc.h inc/tbl-dec.h inc/tbl-print.h inc/tbl-free.h 
+tbl-util.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  inc/tbl-incl.h inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h inc/tbl.h inc/tbl-util.h \
+  inc/tbl-enc.h inc/tbl-dec.h inc/tbl-print.h inc/tbl-free.h inc/sbuf.h 
+asn-useful.o : inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h 
+tbl.o : inc/asn-incl.h inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h inc/nibble-alloc.h inc/gen-buf.h inc/print.h inc/asn-len.h \
+  inc/asn-tag.h inc/asn-bool.h inc/asn-int.h inc/asn-enum.h inc/asn-real.h \
+  inc/asn-octs.h inc/asn-bits.h inc/asn-oid.h inc/asn-null.h inc/asn-any.h \
+  inc/hash.h inc/asn-list.h inc/asn-useful.h inc/tbl.h 
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-any.h b/SecuritySNACCRuntime/c-lib/inc/asn-any.h
new file mode 100644
index 00000000..06914627
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-any.h
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_any.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-any.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-any.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:19  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1997/02/28 13:39:49  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.2  1995/07/24 21:01:07  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:22  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_any_h_
+#define _asn_any_h_
+
+#include "hash.h"
+
+/*
+ * 1 hash table for integer keys
+ * 1 hash table for oid keys
+ */
+extern Table *anyOidHashTblG;
+extern Table *anyIntHashTblG;
+
+typedef AsnLen (*EncodeFcn) PROTO ((BUF_TYPE b, void *value));
+typedef void (*DecodeFcn) PROTO ((BUF_TYPE b, void *value, AsnLen *bytesDecoded, ENV_TYPE env));
+typedef void (*FreeFcn)   PROTO ((void *v));
+typedef void (*PrintFcn)  PROTO ((FILE *f, void *v));
+
+/*
+ * this is put into the hash table with the
+ * int or oid as the key
+ */
+typedef struct AnyInfo
+{
+  int		anyId;  /* will be a value from the AnyId enum */
+  AsnOid	oid;    /* will be zero len/null if intId is valid */
+  AsnInt	intId;
+  unsigned int	size;  /* size of the C data type (ie as ret'd by sizeof) */
+  EncodeFcn	Encode;
+  DecodeFcn	Decode;
+  FreeFcn	Free;
+  PrintFcn	Print;
+} AnyInfo;
+
+
+typedef struct AsnAny
+{
+  AnyInfo	*ai; /* point to entry in hash tbl that has routine ptrs */
+  void		*value; /* points to the value */
+} AsnAny;
+
+/*
+ * Returns anyId value for the given ANY type.
+ * Use this to determine to the type of an ANY after decoding
+ * it. Returns -1 if the ANY info is not available
+ */
+#define GetAsnAnyId( a)		(((a)->ai)? (a)->ai->anyId: -1)
+
+/*
+ * used before encoding or decoding a type so the proper
+ * encode or decode routine is used.
+ */
+void SetAnyTypeByInt PROTO ((AsnAny *v, AsnInt id));
+void SetAnyTypeByOid PROTO ((AsnAny *v, AsnOid *id));
+
+
+/*
+ * used to initialize the hash table (s)
+ */
+void InstallAnyByInt PROTO ((int anyId, AsnInt intId, unsigned int size, EncodeFcn encode, DecodeFcn decode, FreeFcn free, PrintFcn print));
+
+void InstallAnyByOid PROTO ((int anyId, AsnOid *oid, unsigned int size, EncodeFcn encode, DecodeFcn decode, FreeFcn free, PrintFcn print));
+
+
+/*
+ * Standard enc, dec, free, & print routines
+ * for the AsnAny type.
+ * These call the routines referenced from the
+ * given value's hash table entry.
+ */
+void FreeAsnAny PROTO ((AsnAny *v));
+
+AsnLen BEncAsnAny PROTO ((BUF_TYPE b, AsnAny *v));
+
+void BDecAsnAny PROTO ((BUF_TYPE b, AsnAny *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+void PrintAsnAny PROTO ((FILE *f, AsnAny *v, unsigned short indent));
+
+
+
+/* AnyDefinedBy is currently the same as AsnAny */
+
+typedef AsnAny			AsnAnyDefinedBy;
+
+#define FreeAsnAnyDefinedBy	FreeAsnAny
+
+#define BEncAsnAnyDefinedBy	BEncAsnAny
+
+#define BDecAsnAnyDefinedBy	BDecAsnAny
+
+#define PrintAsnAnyDefinedBy	PrintAsnAny
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-bits.h b/SecuritySNACCRuntime/c-lib/inc/asn-bits.h
new file mode 100644
index 00000000..2c404851
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-bits.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_bits.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-bits.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-bits.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:19  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 21:01:09  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/12/11  21:48:28  rj
+ * argument order of BDecAsnBitsContent() fixed.
+ *
+ * Revision 1.1  1994/08/28  09:21:23  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+#ifndef _asn_bits_h_
+#define _asn_bits_h_
+
+
+typedef struct AsnBits
+{
+  int	bitLen;
+  char	*bits;
+} AsnBits;
+
+extern char numToHexCharTblG[];
+
+#define TO_HEX( fourBits)	(numToHexCharTblG[(fourBits) & 0x0f])
+
+
+#define ASNBITS_PRESENT( abits)	((abits)->bits != NULL)
+
+
+AsnLen BEncAsnBits PROTO ((BUF_TYPE b, AsnBits *data));
+
+void BDecAsnBits PROTO ((BUF_TYPE b, AsnBits *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+AsnLen BEncAsnBitsContent PROTO ((BUF_TYPE b, AsnBits *bits));
+
+void BDecAsnBitsContent PROTO ((BUF_TYPE b, AsnTag tagId, AsnLen len, AsnBits *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+void FreeAsnBits PROTO ((AsnBits *v));
+
+void PrintAsnBits PROTO ((FILE *f, AsnBits *b, unsigned short int indent));
+
+int AsnBitsEquiv PROTO ((AsnBits *b1, AsnBits *b2));
+
+void SetAsnBit PROTO ((AsnBits *b1, unsigned long int bit));
+
+void ClrAsnBit PROTO ((AsnBits *b1, unsigned long int bit));
+
+int GetAsnBit PROTO ((AsnBits *b1, unsigned long int bit));
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-bool.h b/SecuritySNACCRuntime/c-lib/inc/asn-bool.h
new file mode 100644
index 00000000..991a7f0b
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-bool.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_bool.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-bool.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-bool.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:10  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:24  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_bool_h_
+#define _asn_bool_h_
+
+typedef unsigned char AsnBool;
+
+
+AsnLen BEncAsnBool PROTO ((BUF_TYPE b, AsnBool *data));
+
+void BDecAsnBool PROTO ((BUF_TYPE b, AsnBool *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+AsnLen BEncAsnBoolContent PROTO ((BUF_TYPE b, AsnBool *data));
+
+void BDecAsnBoolContent PROTO ((BUF_TYPE b, AsnTag tag, AsnLen len, AsnBool *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+/* do nothing  */
+#define FreeAsnBool( v)
+
+void PrintAsnBool PROTO ((FILE *f, AsnBool *b, unsigned short int indent));
+
+#endif
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-config.h b/SecuritySNACCRuntime/c-lib/inc/asn-config.h
new file mode 100644
index 00000000..ac9e7e68
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-config.h
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_config.h - configures the ANSI/non ansi, defines
+ *                decoder alloc routines and buffer routines
+ *
+ * MS 91
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-config.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-config.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.6  1997/03/13 09:15:16  wan
+ * Improved dependency generation for stupid makedepends.
+ * Corrected PeekTag to peek into buffer only as far as necessary.
+ * Added installable error handler.
+ * Fixed small glitch in idl-code generator (Markku Savela <msa@msa.tte.vtt.fi>).
+ *
+ * Revision 1.5  1995/07/24 21:01:11  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.4  1995/02/13  14:47:33  rj
+ * settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h.
+ *
+ * Revision 1.3  1994/10/08  04:46:20  rj
+ * config.h -> snacc.h, which now is the toplevel config file.
+ *
+ * Revision 1.2  1994/08/31  23:53:05  rj
+ * redundant code moved into ../../config.h.bot
+ *
+ * Revision 1.1  1994/08/28  09:21:25  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_config_h_
+#define _asn_config_h_
+
+#include <stdio.h>
+#include <setjmp.h> /* for jmp_buf type, setjmp and longjmp */
+
+/* for pow() used in asn_real.c - must include to avoid casting err on pow */
+#include <math.h>
+
+#include "snacc.h"
+
+
+/* used to test if optionals are present */
+#define NOT_NULL( ptr)			((ptr) != NULL)
+
+
+/*
+ * Asn1Error (char *str) - configure error handler
+ */
+void Asn1Error PROTO ((char* str));
+
+
+/*
+ * Asn1Warning (char *str) - configure warning mechanism
+ * (currently never called)
+ */
+void Asn1Warning PROTO ((char* str));
+
+/*
+ * Asn1ErrorHandler - procedure to call upon Asn1Warning (severity 0)
+ * and Asn1Error (severity 1).
+ */
+typedef void (*Asn1ErrorHandler) PROTO ((char* str, int severity));
+
+/*
+ * Asn1InstallErrorHandler - installs new error handler, returns former one
+ */
+Asn1ErrorHandler Asn1InstallErrorHandler PROTO ((Asn1ErrorHandler handler));
+
+/*
+ * configure memory scheme used by decoder to allocate memory
+ * for the decoded value.
+ * The Asn1Free will be called in the optionally generated
+ * hierachical free routines.
+ *
+ * nibble_alloc allocs from a single buffer and EVERYTHING
+ * is freed by a single fcn call. Individual elmts cannot be freed
+ */
+
+#ifndef USE_NIBBLE_MEMORY
+#define USE_NIBBLE_MEMORY		1
+#endif
+
+#if USE_NIBBLE_MEMORY
+
+#include "nibble-alloc.h"
+
+#define Asn1Alloc( size)		NibbleAlloc (size)
+#define Asn1Free( ptr)			/* empty */
+#define CheckAsn1Alloc( ptr, env)	\
+	if ((ptr) == NULL)\
+	  longjmp (env, -27)
+
+#else /* !USE_NIBBLE_MEMORY */
+
+#include "mem.h"
+
+#define Asn1Alloc( size)		Malloc (size)
+#define Asn1Free( ptr)			Free (ptr)
+#define CheckAsn1Alloc( ptr, env)	\
+	if ((ptr) == NULL)\
+	  longjmp (env, -27)
+
+#endif /* USE_NIBBLE_MEMORY */
+
+#define ENV_TYPE jmp_buf
+
+/*
+ * configure buffer routines that the encoders (write)
+ * and decoders (read) use.  This config technique kind
+ * of bites but is allows efficient macro calls.  The
+ * Generated code & lib routines  call/use the "Buf????"
+ * version of the macro - you define their meaning here.
+ */
+#ifdef USE_EXP_BUF
+
+#include "exp-buf.h"
+
+#define BUF_TYPE			ExpBuf **
+#define BufGetByte( b)			ExpBufGetByte (b)
+#define BufGetSeg( b, lenPtr)		ExpBufGetSeg (b, lenPtr)
+#define BufCopy( dst, b, len)		ExpBufCopy (dst, b, len)
+#define BufSkip( b, len)		ExpBufSkip (b, len)
+#define BufPeekByte( b)			ExpBufPeekByte (b)
+#define BufPutByteRvs( b, byte)		ExpBufPutByteRvs (b, byte)
+#define BufPutSegRvs( b, data, len)	ExpBufPutSegRvs (b, data, len)
+#define BufReadError( b)		ExpBufReadError (b)
+#define BufWriteError( b)		ExpBufWriteError (b)
+
+#else /* !USE_EXP_BUF */
+
+#ifdef USE_MIN_BUF
+
+#include "min-buf.h"
+
+#define BUF_TYPE			char **
+#define BufGetByte( b)			MinBufGetByte (b)
+#define BufGetSeg( b, lenPtr)		MinBufGetSeg (b, lenPtr)
+#define BufCopy( dst, b, len)		MinBufCopy (dst, b, len)
+#define BufSkip( b, len)		MinBufSkip (b, len)
+#define BufPeekByte( b)			MinBufPeekByte (b)
+#define BufPutByteRvs( b, byte)		MinBufPutByteRvs (b, byte)
+#define BufPutSegRvs( b, data, len)	MinBufPutSegRvs (b, data, len)
+#define BufReadError( b)		MinBufReadError (b)
+#define BufWriteError( b)		MinBufWriteError (b)
+
+#else /* !USE_EXP_BUF && !USE_MIN_BUF */
+
+#ifdef USE_SBUF
+
+#include "sbuf.h"
+
+#define BUF_TYPE			SBuf *
+#define BufGetByte( b)			SBufGetByte (b)
+#define BufGetSeg( b, lenPtr)		SBufGetSeg (b, lenPtr)
+#define BufCopy( dst, b, len)		SBufCopy (dst, b, len)
+#define BufSkip( b, len)		SBufSkip (b, len)
+#define BufPeekByte( b)			SBufPeekByte (b)
+#define BufPutByteRvs( b, byte)		SBufPutByteRvs (b, byte)
+#define BufPutSegRvs( b, data, len)	SBufPutSegRvs (b, data, len)
+#define BufReadError( b)		SBufReadError (b)
+#define BufWriteError( b)		SBufWriteError (b)
+
+#else /* !USE_EXP_BUF && !USE_MIN_BUF && !USE_SBUF*/
+
+#ifdef USE_GEN_BUF
+
+/*
+ * NOTE: for use with tables, I defined the (slower)
+ *  GenBuf type that is more flexible (à la ISODE and XDR).
+ *  This allows the encode/decode libs to support other
+ *  buffer types dynamically instead of having different
+ *  libs for each buffer type.
+ *  The GenBufs are not provided for the compiled code
+ *  (ie the c_lib directory) but could easily be added
+ *  (I don't have time, tho).  Tables tools are
+ *  around 4x slower than the compiled version so a
+ *  the GenBufs aren't such a big performance hit for table stuff.
+ *
+ */
+#include "gen-buf.h"
+
+#define BUF_TYPE			GenBuf *
+#define BufGetByte( b)			GenBufGetByte (b)
+#define BufGetSeg( b, lenPtr)		GenBufGetSeg (b, lenPtr)
+#define BufCopy( dst, b, len)		GenBufCopy (dst, b, len)
+#define BufSkip( b, len)		GenBufSkip (b, len)
+#define BufPeekByte( b)			GenBufPeekByte (b)
+#define BufPeekSeg( b, lenPtr)		GenBufPeekSeg (b, lenPtr)
+#define BufPeekCopy( dst, b, len)	GenBufPeekCopy (dst, b, len)
+#define BufPutByteRvs( b, byte)		GenBufPutByteRvs (b, byte)
+#define BufPutSegRvs( b, data, len)	GenBufPutSegRvs (b, data, len)
+#define BufReadError( b)		GenBufReadError (b)
+#define BufWriteError( b)		GenBufWriteError (b)
+
+#else /* none?! */
+
+#ifndef MAKEDEPEND
+  #error "don't know what buffer type to use!"
+#endif
+
+#endif /* USE_GEN_BUF */
+#endif /* USE_SBUF */
+#endif /* USE_MIN_BUF */
+#endif /* USE_EXP_BUF */
+
+#include "print.h"  /* for printing set up */
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-enum.h b/SecuritySNACCRuntime/c-lib/inc/asn-enum.h
new file mode 100644
index 00000000..74d6f838
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-enum.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_enum.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-enum.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-enum.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:12  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:26  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_enum_h_
+#define _asn_enum_h_
+
+typedef AsnInt AsnEnum;
+
+/*
+ * ENUMERATED have a UNIVERSAL tag that is diff from INTEGERS
+ * so need diff encoding routine tho content stuff is the same
+ */
+AsnLen BEncAsnEnum PROTO ((BUF_TYPE b, AsnEnum *data));
+
+void BDecAsnEnum PROTO ((BUF_TYPE b, AsnEnum *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+#define BEncAsnEnumContent BEncAsnIntContent
+
+#define BDecAsnEnumContent BDecAsnIntContent
+
+#define FreeAsnEnum FreeAsnInt
+
+#define PrintAsnEnum PrintAsnInt
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-incl.h b/SecuritySNACCRuntime/c-lib/inc/asn-incl.h
new file mode 100644
index 00000000..dd7f8dd0
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-incl.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_incl.h
+ *   includes hdr files nec for a user prg that calls the generated
+ *   encoding/decoding routines.
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-incl.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-incl.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:13  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:27  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-bool.h"
+#include "asn-int.h"
+#include "asn-enum.h"
+#include "asn-real.h"
+#include "asn-octs.h"
+#include "asn-bits.h"
+#include "asn-oid.h"
+#include "asn-null.h"
+#include "asn-any.h"
+#include "asn-list.h"
+#include "asn-useful.h"
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-int.h b/SecuritySNACCRuntime/c-lib/inc/asn-int.h
new file mode 100644
index 00000000..b1e92809
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-int.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_int.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-int.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-int.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/27 08:38:58  rj
+ * ``#error "..."'' instead of ``#error ...''.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1995/02/18  16:19:42  rj
+ * let cpp choose a 32 bit integer type.
+ *
+ * Revision 1.1  1994/08/28  09:21:28  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_int_h_
+#define _asn_int_h_
+
+#if SIZEOF_INT == 4
+#  define I		int
+#else
+#  if SIZEOF_LONG == 4
+#    define I		long
+#  else
+#    if SIZEOF_SHORT == 4
+#      define I		short
+#    endif
+#  endif
+#endif
+#ifdef I
+  typedef I		AsnInt;
+  typedef unsigned I	UAsnInt;
+#else
+  #error "can't find integer type which is 4 bytes in size"
+#endif
+#undef I
+
+AsnLen BEncAsnInt PROTO ((BUF_TYPE b, AsnInt *data));
+
+void BDecAsnInt PROTO ((BUF_TYPE b, AsnInt *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+AsnLen BEncAsnIntContent PROTO ((BUF_TYPE b, AsnInt *data));
+
+void BDecAsnIntContent PROTO ((BUF_TYPE b, AsnTag tag, AsnLen elmtLen, AsnInt  *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+/* do nothing  */
+#define FreeAsnInt( v)
+
+void PrintAsnInt PROTO ((FILE *f, AsnInt *v, unsigned short int indent));
+
+
+
+
+AsnLen BEncUAsnInt PROTO ((BUF_TYPE b, UAsnInt *data));
+
+void BDecUAsnInt PROTO ((BUF_TYPE b, UAsnInt *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+AsnLen BEncUAsnIntContent PROTO ((BUF_TYPE b, UAsnInt *data));
+
+void BDecUAsnIntContent PROTO ((BUF_TYPE b, AsnTag tagId, AsnLen len, UAsnInt *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+/* do nothing  */
+#define FreeUAsnInt( v)
+
+void PrintUAsnInt PROTO ((FILE *f, UAsnInt *v, unsigned short int indent));
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-len.h b/SecuritySNACCRuntime/c-lib/inc/asn-len.h
new file mode 100644
index 00000000..64d07b00
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-len.h
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_len.h
+ *
+ * Warning: many of these routines are MACROs for performance reasons
+ *          - be carful where you use them.  Don't use more than one per
+ *          assignment statement -
+ *          (eg itemLen += BEncEoc (b) + BEncFoo (b) ..; this
+ *           will break the code)
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-len.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-len.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/27 08:42:40  rj
+ * cpp macro TBL changed to TTBL since some type table code uses TBL as a type name.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:29  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_len_h_
+#define _asn_len_h_
+
+typedef unsigned long int AsnLen;
+
+/* max unsigned value  - used for internal rep of indef len */
+#define INDEFINITE_LEN		~0L
+
+
+#ifdef USE_INDEF_LEN
+
+#define BEncEocIfNec( b)	BEncEoc (b)
+
+/*
+ * include len for EOC  (2 must be first due to BEncIndefLen
+ * - ack! ugly macros!)
+ */
+#define BEncConsLen( b, len)	2 + BEncIndefLen(b)
+
+
+#else  /* use definite length - faster?/smaller encodings */
+
+
+/* do nothing since only using definite lens */
+#define BEncEocIfNec( b)
+
+#define BEncConsLen( b, len)	BEncDefLen(b, len)
+
+
+#endif
+
+
+
+/*
+ * writes indefinite length byte to buffer. 'returns' encoded len (1)
+ */
+#define BEncIndefLen( b)\
+    1;\
+    BufPutByteRvs (b, 0x80);
+
+
+#define BEncEoc( b)\
+    2;\
+    BufPutByteRvs (b, 0);\
+    BufPutByteRvs (b, 0);
+
+
+/*
+ * use if you know the encoded length will be 0 >= len <= 127
+ * Eg for booleans, nulls, any resonable integers and reals
+ *
+ * NOTE: this particular Encode Routine does NOT return the length
+ * encoded (1).
+ */
+#define BEncDefLenTo127( b, len)\
+    BufPutByteRvs (b, (unsigned char) len)
+
+#define BDEC_2ND_EOC_OCTET( b, bytesDecoded, env)\
+{\
+    if ((BufGetByte (b) != 0) || BufReadError (b)) {\
+        Asn1Error ("ERROR - second octet of EOC not zero\n");\
+        longjmp (env, -28);}\
+     (*bytesDecoded)++;\
+}
+
+
+AsnLen BEncDefLen PROTO ((BUF_TYPE  b, AsnLen len));
+
+AsnLen BDecLen PROTO ((BUF_TYPE b, AsnLen  *bytesDecoded, ENV_TYPE env));
+
+/*
+AsnLen BEncEoc PROTO ((BUF_TYPE b));
+*/
+void BDecEoc PROTO ((BUF_TYPE b, AsnLen *bytesDecoded, ENV_TYPE env));
+
+#if TTBL
+int PeekEoc PROTO ((BUF_TYPE b));
+#endif
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-list.h b/SecuritySNACCRuntime/c-lib/inc/asn-list.h
new file mode 100644
index 00000000..6d611fdd
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-list.h
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_list.h
+ *
+ *  ---------
+ *  | AsnList |
+ *  |  last |-------------------------------------------|
+ *  |  curr |--------------------------|                |
+ *  |  first|--------|                 |                |
+ *  ---------        |                 |                |
+ *                   V                 V                V
+ *                ---------        ---------        ---------
+ *                |AsnListNode       |AsnListNode       |AsnListNode
+ *                | next  |---...->|  next |--...-->| next  |-----|i.
+ *         .i|----| prev  |<--...--|  prev |<--...--| prev  |
+ *                | data  |        |  data |        | data  |
+ *                ---------        ---------        ---------
+ *
+ * Originally by Murray Goldberg
+ * Modified for ASN.1 use.
+ * MS 92
+ * Copyright (C) 1992 the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-list.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-list.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:22  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 21:01:14  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  01:40:22  rj
+ * it is unwise to #define unbalanced if()s! (fixed.)
+ * three declarations added.
+ *
+ * Revision 1.1  1994/08/28  09:21:30  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_list_h_
+#define _asn_list_h_
+
+typedef struct AsnListNode
+{
+    struct AsnListNode	*prev;
+    struct AsnListNode	*next;
+    void		*data;		/* this must be the last field of this structure  */
+} AsnListNode;
+
+typedef struct AsnList
+{
+    AsnListNode		*first;
+    AsnListNode		*last;
+    AsnListNode		*curr;
+    int			count;		/* number of elements in list               */
+    int			dataSize;	/* space required in each node for the data */
+} AsnList;
+
+#define FOR_EACH_LIST_ELMT( elmt,  al)\
+  if (!(al))\
+    ;\
+  else\
+    for ((al)->curr = (al)->first; (al)->curr && ((elmt) = (void *)(al)->curr->data); (al)->curr = (al)->curr->next)
+
+#define FOR_EACH_LIST_ELMT_RVS( elmt,  al)\
+  if (!(al))\
+    ;\
+  else\
+    for ((al)->curr = (al)->last; (al)->curr && ((elmt) = (void *)(al)->curr->data); (al)->curr = (al)->curr->prev)
+
+
+#define FOR_REST_LIST_ELMT( elmt,  al)\
+  if (!(al))\
+    ;\
+  else\
+    for (; (al)->curr && ((elmt) = (void *)(al)->curr->data); (al)->curr = (al)->curr->next)
+
+#define FOR_REST_LIST_ELMT_RVS( elmt,  al)\
+  if (!(al))\
+    ;\
+  else\
+    for (; ((al)->curr && ((elmt) = (void *)(al)->curr->data); (al)->curr = (al)->curr->prev)
+
+/*
+ * The following macros return the pointer stored in the
+ * data part of the listNode.  The do not change the current
+ * list pointer.
+ */
+#define CURR_LIST_ELMT( al)			((al)->curr->data)
+#define NEXT_LIST_ELMT( al)			((al)->curr->next->data)
+#define PREV_LIST_ELMT( al)			((al)->curr->prev->data)
+#define LAST_LIST_ELMT( al)			((al)->last->data)
+#define FIRST_LIST_ELMT( al)			((al)->first->data)
+#define LIST_EMPTY( al)				((al)->count == 0)
+#define LIST_COUNT( al)				((al)->count)
+
+/*
+ * list nodes are the parts of the list that contain ptrs/data
+ * to/of the list elmts.
+ */
+#define CURR_LIST_NODE( al)			((al)->curr)
+#define FIRST_LIST_NODE( al)			((al)->first)
+#define LAST_LIST_NODE( al)			((al)->last)
+#define PREV_LIST_NODE( al)			((al)->curr->prev)
+#define NEXT_LIST_NODE( al)			((al)->curr->next)
+#define SET_CURR_LIST_NODE( al, listNode)	((al)->curr = (listNode))
+
+void	AsnListRemove PROTO ((AsnList *));
+void	*AsnListAdd PROTO ((AsnList *));
+void	*AsnListInsert PROTO ((AsnList *));
+void	AsnListInit PROTO ((AsnList *list, int dataSize));
+AsnList	*AsnListNew PROTO ((int));
+void	*AsnListPrev PROTO ((AsnList *));
+void	*AsnListNext PROTO ((AsnList *));
+void	*AsnListLast PROTO ((AsnList *));
+void	*AsnListFirst PROTO ((AsnList *));
+void	*AsnListPrepend PROTO ((AsnList *));
+void	*AsnListAppend PROTO ((AsnList *));
+void	*AsnListCurr PROTO ((AsnList *));
+int	AsnListCount PROTO ((AsnList *));
+AsnList	*AsnListConcat PROTO ((AsnList *, AsnList *));
+long int GetAsnListElmtIndex PROTO ((void *elmt,AsnList *list));
+void	AsnListFree PROTO (( AsnList *));
+void	*GetAsnListElmt PROTO ((AsnList *list, unsigned int index));
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-null.h b/SecuritySNACCRuntime/c-lib/inc/asn-null.h
new file mode 100644
index 00000000..f733fdb0
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-null.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_null.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-null.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-null.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:16  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:31  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_null_h_
+#define _asn_null_h_
+
+typedef char AsnNull;
+
+
+AsnLen BEncAsnNull PROTO ((BUF_TYPE b, AsnNull *data));
+
+void BDecAsnNull PROTO ((BUF_TYPE b, AsnNull *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+/* 'return' length of encoded NULL value, 0 */
+#define BEncAsnNullContent(b, data) 0
+
+void BDecAsnNullContent PROTO ((BUF_TYPE b, AsnTag tag, AsnLen len, AsnNull *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+ /* do nothing */
+#define FreeAsnNull( v)
+
+void PrintAsnNull PROTO ((FILE *f, AsnNull * b, unsigned short int indent));
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-octs.h b/SecuritySNACCRuntime/c-lib/inc/asn-octs.h
new file mode 100644
index 00000000..99844fc0
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-octs.h
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_octs.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-octs.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-octs.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 21:01:17  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/12/11  21:49:38  rj
+ * argument order of BDecAsnOctsContent() fixed.
+ *
+ * Revision 1.1  1994/08/28  09:21:32  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+#ifndef _asn_octs_h_
+#define _asn_octs_h_
+
+typedef struct AsnOcts
+{
+  unsigned long int	octetLen;
+  char			*octs;
+} AsnOcts;
+
+#define ASNOCTS_PRESENT( aocts)	((aocts)->octs != NULL)
+
+
+
+AsnLen BEncAsnOcts PROTO ((BUF_TYPE b, AsnOcts *data));
+
+void BDecAsnOcts PROTO ((BUF_TYPE b, AsnOcts *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+AsnLen BEncAsnOctsContent PROTO ((BUF_TYPE b, AsnOcts *octs));
+
+void BDecAsnOctsContent PROTO ((BUF_TYPE b, AsnTag tagId, AsnLen len, AsnOcts *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+void FreeAsnOcts PROTO ((AsnOcts *o));
+
+void PrintAsnOcts PROTO ((FILE *f, AsnOcts *o, unsigned short int indent));
+
+int AsnOctsEquiv PROTO ((AsnOcts *o1, AsnOcts *o2));
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-oid.h b/SecuritySNACCRuntime/c-lib/inc/asn-oid.h
new file mode 100644
index 00000000..27089723
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-oid.h
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_oid.h
+ *
+ *  this file depends on asn_octs.h
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-oid.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-oid.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/27 10:24:00  rj
+ * minor change to merge with type table code.
+ *
+ * Revision 1.1  1994/08/28  09:21:34  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+#ifndef _asn_oid_h_
+#define _asn_oid_h_
+
+#include "asn-octs.h"
+
+typedef AsnOcts AsnOid;  /* standard oid type  */
+
+
+#define ASNOID_PRESENT( aoid)	ASNOCTS_PRESENT (aoid)
+
+AsnLen BEncAsnOid PROTO ((BUF_TYPE b, AsnOid *data));
+
+void BDecAsnOid PROTO ((BUF_TYPE b, AsnOid *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+#define BEncAsnOidContent( b, oid)   BEncAsnOctsContent (b, oid)
+
+
+void BDecAsnOidContent PROTO ((BUF_TYPE b, AsnTag tag, AsnLen len, AsnOid  *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+#define FreeAsnOid	FreeAsnOcts
+
+void PrintAsnOid PROTO ((FILE *f, AsnOid *b, unsigned short int indent));
+
+#define AsnOidsEquiv( o1, o2) AsnOctsEquiv (o1, o2)
+
+/* linked oid type that may be easier to use in some circumstances */
+#define NULL_OID_ARCNUM	-1
+typedef struct OID
+{
+  struct OID	*next;
+  long int	arcNum;
+#if COMPILER || TTBL
+  struct Value	*valueRef;
+#endif
+} OID;
+
+AsnLen EncodedOidLen PROTO ((OID *oid));
+
+void BuildEncodedOid PROTO ((OID *oid, AsnOid *result));
+
+void UnbuildEncodedOid PROTO ((AsnOid *eoid, OID **result));
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-real.h b/SecuritySNACCRuntime/c-lib/inc/asn-real.h
new file mode 100644
index 00000000..07afb432
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-real.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_real.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-real.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-real.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:20  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:18  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:35  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+#ifndef _asn_real_h_
+#define _asn_real_h_
+
+typedef double AsnReal;
+
+extern AsnReal PLUS_INFINITY;
+extern AsnReal MINUS_INFINITY;
+
+
+void InitAsnInfinity();
+
+AsnLen BEncAsnReal PROTO ((BUF_TYPE b, AsnReal *data));
+
+void BDecAsnReal PROTO ((BUF_TYPE b, AsnReal *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+AsnLen BEncAsnRealContent PROTO ((BUF_TYPE b, AsnReal *data));
+
+void BDecAsnRealContent PROTO ((BUF_TYPE b, AsnTag tag, AsnLen len, AsnReal *result, AsnLen *bytesDecoded, ENV_TYPE env));
+
+/* do nothing */
+#define FreeAsnReal( v)
+
+void PrintAsnReal PROTO ((FILE *f, AsnReal *b, unsigned short int indent));
+
+#endif
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-tag.h b/SecuritySNACCRuntime/c-lib/inc/asn-tag.h
new file mode 100644
index 00000000..8cec358a
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-tag.h
@@ -0,0 +1,260 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_tag.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * INSERT_VDA_COMMENTS
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/asn-tag.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-tag.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:21  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/27 08:44:15  rj
+ * cpp macro TBL changed to TTBL since some type table code uses TBL as a type name.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1995/02/18  16:22:23  rj
+ * let cpp choose a 32 bit integer type.
+ *
+ * Revision 1.1  1994/08/28  09:21:37  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_tag_h_
+#define _asn_tag_h_
+
+#if SIZEOF_INT == 4
+#  define UL		unsigned int
+#else
+#  if SIZEOF_LONG == 4
+#    define UL		unsigned long
+#  else
+#    if SIZEOF_SHORT == 4
+#      define UL	unsigned short
+#    endif
+#  endif
+#endif
+#ifndef UL
+  #error "can't find integer type which is 4 bytes in size"
+#endif
+typedef UL	AsnTag;
+
+/* Tag Id's byte length */
+#define TB	sizeof (AsnTag)
+
+/*
+ * The MAKE_TAG_ID macro generates the TAG_ID rep for the
+ * the given class/form/code (rep'd in long integer form)
+ * if the class/form/code are constants the compiler (should)
+ * calculate the tag completely --> zero runtime overhead.
+ * This is good for efficiently comparing tags in switch statements
+ * (decoding) etc.  because run-time bit fiddling (eliminated) minimized
+ */
+#ifndef _IBM_ENC_
+#define MAKE_TAG_ID( cl, fm, cd)\
+	((((UL)(cl)) << ((TB -1) * 8)) | (((UL)(fm)) << ((TB -1) * 8)) | (MAKE_TAG_ID_CODE (((UL)(cd)))))
+#else
+#define MAKE_TAG_ID( cl, fm, cd)\
+	((MAKE_TAG_ID_CODE (cd)) | (cl << ((TB -1) * 8)) | (fm << ((TB -1) * 8)))
+#endif /* _IBM_ENC_ */
+
+#define MAKE_TAG_ID_CODE(cd)\
+( (cd < 31) ?  (MAKE_TAG_ID_CODE1 (cd)):\
+      ((cd < 128)?  (MAKE_TAG_ID_CODE2 (cd)):\
+         ((cd < 16384)?  (MAKE_TAG_ID_CODE3 (cd)):\
+           (MAKE_TAG_ID_CODE4 (cd)))))
+
+#define MAKE_TAG_ID_CODE1(cd)  (cd << ((TB -1) * 8))
+#define MAKE_TAG_ID_CODE2(cd)  ((31 << ((TB -1) * 8)) | (cd << ((TB-2) * 8)))
+#define MAKE_TAG_ID_CODE3(cd)  ((31 << ((TB -1) * 8))\
+                                | ((cd & 0x3f80) << 9)\
+                                | ( 0x0080 << ((TB-2) * 8))\
+                                | ((cd & 0x007F) << ((TB-3)* 8)))
+
+#define MAKE_TAG_ID_CODE4(cd)  ((31 << ((TB -1) * 8))\
+                                | ((cd & 0x1fc000) << 2)\
+                                | ( 0x0080 << ((TB-2) * 8))\
+                                | ((cd & 0x3f80) << 1)\
+                                | ( 0x0080 << ((TB-3) * 8))\
+                                | ((cd & 0x007F) << ((TB-4)*8)))
+
+
+
+typedef enum
+{
+    ANY_CLASS = -2,
+    NULL_CLASS = -1,
+    UNIV = 0,
+    APPL = (1 << 6),
+    CNTX = (2 << 6),
+    PRIV = (3 << 6)
+} BER_CLASS;
+
+typedef enum
+{
+    ANY_FORM = -2,
+    NULL_FORM = -1,
+    PRIM = 0,
+    CONS = (1 << 5)
+} BER_FORM;
+
+
+typedef enum
+{
+    NO_TAG_CODE = 0,
+    BOOLEAN_TAG_CODE = 1,
+    INTEGER_TAG_CODE,
+    BITSTRING_TAG_CODE,
+    OCTETSTRING_TAG_CODE,
+    NULLTYPE_TAG_CODE,
+    OID_TAG_CODE,
+    OD_TAG_CODE,
+    EXTERNAL_TAG_CODE,
+    REAL_TAG_CODE,
+    ENUM_TAG_CODE,
+    SEQ_TAG_CODE =  16,
+    SET_TAG_CODE,
+    NUMERICSTRING_TAG_CODE,
+    PRINTABLESTRING_TAG_CODE,
+    TELETEXSTRING_TAG_CODE,
+    VIDEOTEXSTRING_TAG_CODE,
+    IA5STRING_TAG_CODE,
+    UTCTIME_TAG_CODE,
+    GENERALIZEDTIME_TAG_CODE,
+    GRAPHICSTRING_TAG_CODE,
+    VISIBLESTRING_TAG_CODE,
+
+#ifndef VDADER_RULES
+
+    GENERALSTRING_TAG_CODE
+
+#else
+    GENERALSTRING_TAG_CODE,
+    UNIVERSALSTRING_TAG_CODE = 28,
+    BMPSTRING_TAG_CODE = 30
+#endif
+
+} BER_UNIV_CODE;
+
+#define TT61STRING_TAG_CODE	TELETEXSTRING_TAG_CODE
+#define ISO646STRING_TAG_CODE	VISIBLESTRING_TAG_CODE
+
+
+/*
+ * the TAG_ID_[CLASS/FORM/CODE] macros are not
+ * super fast - try not to use during encoding/decoding
+ */
+#define TAG_ID_CLASS( tid)	((tid & (0xC0 << ((TB-1) *8))) >> ((TB -1) * 8))
+#define TAG_ID_FORM( tid)	((tid & (0x20 << ((TB-1) *8))) >> ((TB -1) * 8))
+
+/*
+ * TAG_IS_CONS evaluates to true if the given AsnTag type
+ * tag has the constructed bit set.
+ */
+#define TAG_IS_CONS( tag)	((tag) & (CONS << ((TB-1) *8)))
+#define CONSIFY( tag)		(tag | (CONS << ((TB-1) *8)))
+#define DECONSIFY( tag)		(tag &  ~(CONS << ((TB-1) *8)))
+
+
+/* not a valid tag - usually the first EOC octet */
+#define EOC_TAG_ID		0
+
+
+
+/*
+ * tag encoders.  given constant values for class form &
+ * code in the  source, these can be optimized by the compiler
+ * (e.g.  do the shifts and bitwise ands & ors etc)
+ *
+ * This is the prototype that the following BEncTag routines
+ * would use if they were routines.  They return the number of
+ * octets written to the buffer.
+ *
+ *
+ *AsnLen BEncTag PROTO ((BUF_TYPE b, BER_CLASS class, BER_FORM form, int code));
+ *
+ * WARNING: these are FRAGILE macros (What people will do for performance!)
+ *          Be careful of situations like:
+ *            if (foo)
+ *                  encLen += BEncTag1 (...);
+ *          Use {}'s to enclose any ASN.1 related routine that you are
+ *          treating as a single statement in your code.
+ */
+#define BEncTag1( b, class, form, code)\
+    1;\
+    BufPutByteRvs (b, (class) | (form) | (code));
+
+#define BEncTag2( b, class, form, code)\
+    2;\
+    BufPutByteRvs (b, code);\
+    BufPutByteRvs (b, (class) | (form) | 31);
+
+#define BEncTag3( b, class, form, code)\
+    3;\
+    BufPutByteRvs (b, (code) & 0x7F);\
+    BufPutByteRvs (b, 0x80 | ((code) >> 7));\
+    BufPutByteRvs (b, (class) | (form) | 31);
+
+#define BEncTag4( b, class, form, code)\
+    4;\
+    BufPutByteRvs (b, (code) & 0x7F);\
+    BufPutByteRvs (b, 0x80 | ((code) >> 7));\
+    BufPutByteRvs (b, 0x80 | ((code) >> 14));\
+    BufPutByteRvs (b, (class) | (form) | 31);
+
+#define BEncTag5( b, class, form, code)\
+    5;\
+    BufPutByteRvs (b, (code) & 0x7F);\
+    BufPutByteRvs (b, 0x80 | ((code) >> 7));\
+    BufPutByteRvs (b, 0x80 | ((code) >> 14));\
+    BufPutByteRvs (b, 0x80 | ((code) >> 21));\
+    BufPutByteRvs (b, (class) | (form) | 31);
+
+
+/* the following are protos for routines ins asn_tag.c */
+
+
+AsnTag BDecTag PROTO ((BUF_TYPE  b, AsnLen *bytesDecoded, ENV_TYPE env));
+#if TTBL
+AsnTag PeekTag PROTO ((BUF_TYPE b, ENV_TYPE env));
+#endif
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/asn-useful.h b/SecuritySNACCRuntime/c-lib/inc/asn-useful.h
new file mode 100644
index 00000000..0f2f3f98
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/asn-useful.h
@@ -0,0 +1,343 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    asn-useful.h
+ *
+ *    "ASN-USEFUL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Thu Jun  8 12:35:27 2000
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _asn_useful_h_
+#define _asn_useful_h_
+
+
+
+
+typedef AsnOcts ObjectDescriptor; /* [UNIVERSAL 7] IMPLICIT OCTET STRING */
+
+#define BEncObjectDescriptorContent BEncAsnOctsContent
+
+#define BDecObjectDescriptorContent BDecAsnOctsContent
+
+#define PrintObjectDescriptor PrintAsnOcts
+
+#define FreeObjectDescriptor FreeAsnOcts 
+
+
+
+
+typedef AsnOcts UTF8String; /* [UNIVERSAL 12] IMPLICIT OCTET STRING */
+
+AsnLen BEncUTF8String PROTO ((BUF_TYPE b, UTF8String *v));
+
+void BDecUTF8String PROTO ((BUF_TYPE b, UTF8String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncUTF8StringContent BEncAsnOctsContent
+
+#define BDecUTF8StringContent BDecAsnOctsContent
+
+#define PrintUTF8String PrintAsnOcts
+
+#define FreeUTF8String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts NumericString; /* [UNIVERSAL 18] IMPLICIT OCTET STRING */
+
+AsnLen BEncNumericString PROTO ((BUF_TYPE b, NumericString *v));
+
+void BDecNumericString PROTO ((BUF_TYPE b, NumericString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncNumericStringContent BEncAsnOctsContent
+
+#define BDecNumericStringContent BDecAsnOctsContent
+
+#define PrintNumericString PrintAsnOcts
+
+#define FreeNumericString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts PrintableString; /* [UNIVERSAL 19] IMPLICIT OCTET STRING */
+
+AsnLen BEncPrintableString PROTO ((BUF_TYPE b, PrintableString *v));
+
+void BDecPrintableString PROTO ((BUF_TYPE b, PrintableString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncPrintableStringContent BEncAsnOctsContent
+
+#define BDecPrintableStringContent BDecAsnOctsContent
+
+#define PrintPrintableString PrintAsnOcts
+
+#define FreePrintableString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts TeletexString; /* [UNIVERSAL 20] IMPLICIT OCTET STRING */
+
+AsnLen BEncTeletexString PROTO ((BUF_TYPE b, TeletexString *v));
+
+void BDecTeletexString PROTO ((BUF_TYPE b, TeletexString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncTeletexStringContent BEncAsnOctsContent
+
+#define BDecTeletexStringContent BDecAsnOctsContent
+
+#define PrintTeletexString PrintAsnOcts
+
+#define FreeTeletexString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts T61String; /* [UNIVERSAL 20] IMPLICIT OCTET STRING */
+
+AsnLen BEncT61String PROTO ((BUF_TYPE b, T61String *v));
+
+void BDecT61String PROTO ((BUF_TYPE b, T61String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncT61StringContent BEncAsnOctsContent
+
+#define BDecT61StringContent BDecAsnOctsContent
+
+#define PrintT61String PrintAsnOcts
+
+#define FreeT61String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts VideotexString; /* [UNIVERSAL 21] IMPLICIT OCTET STRING */
+
+AsnLen BEncVideotexString PROTO ((BUF_TYPE b, VideotexString *v));
+
+void BDecVideotexString PROTO ((BUF_TYPE b, VideotexString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncVideotexStringContent BEncAsnOctsContent
+
+#define BDecVideotexStringContent BDecAsnOctsContent
+
+#define PrintVideotexString PrintAsnOcts
+
+#define FreeVideotexString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts IA5String; /* [UNIVERSAL 22] IMPLICIT OCTET STRING */
+
+AsnLen BEncIA5String PROTO ((BUF_TYPE b, IA5String *v));
+
+void BDecIA5String PROTO ((BUF_TYPE b, IA5String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncIA5StringContent BEncAsnOctsContent
+
+#define BDecIA5StringContent BDecAsnOctsContent
+
+#define PrintIA5String PrintAsnOcts
+
+#define FreeIA5String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GraphicString; /* [UNIVERSAL 25] IMPLICIT OCTET STRING */
+
+AsnLen BEncGraphicString PROTO ((BUF_TYPE b, GraphicString *v));
+
+void BDecGraphicString PROTO ((BUF_TYPE b, GraphicString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGraphicStringContent BEncAsnOctsContent
+
+#define BDecGraphicStringContent BDecAsnOctsContent
+
+#define PrintGraphicString PrintAsnOcts
+
+#define FreeGraphicString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts VisibleString; /* [UNIVERSAL 26] IMPLICIT OCTET STRING */
+
+AsnLen BEncVisibleString PROTO ((BUF_TYPE b, VisibleString *v));
+
+void BDecVisibleString PROTO ((BUF_TYPE b, VisibleString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncVisibleStringContent BEncAsnOctsContent
+
+#define BDecVisibleStringContent BDecAsnOctsContent
+
+#define PrintVisibleString PrintAsnOcts
+
+#define FreeVisibleString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts ISO646String; /* [UNIVERSAL 26] IMPLICIT OCTET STRING */
+
+AsnLen BEncISO646String PROTO ((BUF_TYPE b, ISO646String *v));
+
+void BDecISO646String PROTO ((BUF_TYPE b, ISO646String *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncISO646StringContent BEncAsnOctsContent
+
+#define BDecISO646StringContent BDecAsnOctsContent
+
+#define PrintISO646String PrintAsnOcts
+
+#define FreeISO646String FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GeneralString; /* [UNIVERSAL 27] IMPLICIT OCTET STRING */
+
+AsnLen BEncGeneralString PROTO ((BUF_TYPE b, GeneralString *v));
+
+void BDecGeneralString PROTO ((BUF_TYPE b, GeneralString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGeneralStringContent BEncAsnOctsContent
+
+#define BDecGeneralStringContent BDecAsnOctsContent
+
+#define PrintGeneralString PrintAsnOcts
+
+#define FreeGeneralString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts UTCTime; /* [UNIVERSAL 23] IMPLICIT OCTET STRING */
+
+AsnLen BEncUTCTime PROTO ((BUF_TYPE b, UTCTime *v));
+
+void BDecUTCTime PROTO ((BUF_TYPE b, UTCTime *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncUTCTimeContent BEncAsnOctsContent
+
+#define BDecUTCTimeContent BDecAsnOctsContent
+
+#define PrintUTCTime PrintAsnOcts
+
+#define FreeUTCTime FreeAsnOcts 
+
+
+
+
+typedef AsnOcts GeneralizedTime; /* [UNIVERSAL 24] IMPLICIT OCTET STRING */
+
+AsnLen BEncGeneralizedTime PROTO ((BUF_TYPE b, GeneralizedTime *v));
+
+void BDecGeneralizedTime PROTO ((BUF_TYPE b, GeneralizedTime *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncGeneralizedTimeContent BEncAsnOctsContent
+
+#define BDecGeneralizedTimeContent BDecAsnOctsContent
+
+#define PrintGeneralizedTime PrintAsnOcts
+
+#define FreeGeneralizedTime FreeAsnOcts 
+
+
+
+
+typedef AsnOcts UniversalString; /* [UNIVERSAL 28] IMPLICIT OCTET STRING */
+
+AsnLen BEncUniversalString PROTO ((BUF_TYPE b, UniversalString *v));
+
+void BDecUniversalString PROTO ((BUF_TYPE b, UniversalString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncUniversalStringContent BEncAsnOctsContent
+
+#define BDecUniversalStringContent BDecAsnOctsContent
+
+#define PrintUniversalString PrintAsnOcts
+
+#define FreeUniversalString FreeAsnOcts 
+
+
+
+
+typedef AsnOcts BMPString; /* [UNIVERSAL 30] IMPLICIT OCTET STRING */
+
+AsnLen BEncBMPString PROTO ((BUF_TYPE b, BMPString *v));
+
+void BDecBMPString PROTO ((BUF_TYPE b, BMPString *result, AsnLen *bytesDecoded, ENV_TYPE env));
+#define BEncBMPStringContent BEncAsnOctsContent
+
+#define BDecBMPStringContent BDecAsnOctsContent
+
+#define PrintBMPString PrintAsnOcts
+
+#define FreeBMPString FreeAsnOcts 
+
+
+
+
+typedef struct EXTERNALChoice /* CHOICE */
+{
+    enum EXTERNALChoiceChoiceId
+    {
+        EXTERNALCHOICE_SINGLE_ASN1_TYPE,
+        EXTERNALCHOICE_OCTET_ALIGNED,
+        EXTERNALCHOICE_ARBITRARY
+    } choiceId;
+    union EXTERNALChoiceChoiceUnion
+    {
+    AsnOcts* single_ASN1_type; /* [0] OCTET STRING */
+    AsnOcts* octet_aligned; /* [1] IMPLICIT OCTET STRING */
+    AsnBits* arbitrary; /* [2] IMPLICIT BIT STRING */
+    } a;
+} EXTERNALChoice;
+
+AsnLen BEncEXTERNALChoiceContent PROTO ((BUF_TYPE b, EXTERNALChoice *v));
+
+void BDecEXTERNALChoiceContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, EXTERNALChoice *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintEXTERNALChoice PROTO ((FILE* f, EXTERNALChoice *v, unsigned short int indent));
+void FreeEXTERNALChoice PROTO ((EXTERNALChoice *v));
+
+
+
+
+
+typedef struct EXTERNAL /* [UNIVERSAL 8] IMPLICIT SEQUENCE */
+{
+    AsnOid direct_reference; /* OBJECT IDENTIFIER OPTIONAL */
+    AsnInt* indirect_reference; /* INTEGER OPTIONAL */
+    ObjectDescriptor data_value_descriptor; /* ObjectDescriptor OPTIONAL */
+    struct EXTERNALChoice* encoding; /* EXTERNALChoice */
+} EXTERNAL;
+
+AsnLen BEncEXTERNAL PROTO ((BUF_TYPE b, EXTERNAL *v));
+
+void BDecEXTERNAL PROTO ((BUF_TYPE b, EXTERNAL *result, AsnLen *bytesDecoded, ENV_TYPE env));
+AsnLen BEncEXTERNALContent PROTO ((BUF_TYPE b, EXTERNAL *v));
+
+void BDecEXTERNALContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, EXTERNAL *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintEXTERNAL PROTO ((FILE* f, EXTERNAL *v, unsigned short int indent));
+void FreeEXTERNAL PROTO ((EXTERNAL *v));
+
+
+
+
+
+
+#endif /* conditional include of asn-useful.h */
diff --git a/SecuritySNACCRuntime/c-lib/inc/exp-buf.h b/SecuritySNACCRuntime/c-lib/inc/exp-buf.h
new file mode 100644
index 00000000..10704003
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/exp-buf.h
@@ -0,0 +1,168 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * exp_buf.h - read/write/alloc/free routines for a simple buffer structure
+ *
+ * MACROS are gross but execution speed is important
+ *
+ * NOTE: replacing the malloc and free with a allocs/frees
+ *       from/to buffer pools or similar tuned/fixed size
+ *       mem mgmt will improve performance.
+ *
+ *  You should tune the buffer management to your environment
+ *  for best results
+ *
+ * MS 91
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/exp-buf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: exp-buf.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:21  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/27 08:54:45  rj
+ * functions used by gen-bufs or type tables merged.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:40  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _exp_buf_h_
+#define _exp_buf_h_
+
+typedef struct ExpBuf
+{
+    char          *dataStart; /* points to first valid data byte */
+                              /* when empty, 1 byte past blk end (rvs write)*/
+    char          *dataEnd;   /* pts to first byte AFTER last valid data byte*/
+    char          *curr;      /* current location to read form */
+                              /* points to next byte to read */
+    struct ExpBuf *next;      /* next buf (NULL if no next buffer)*/
+    struct ExpBuf *prev;      /* prev buf (NULL if no prev buffer)*/
+    char          *blkStart;  /* points to first byte of the blk */
+    char          *blkEnd;    /* points the first byte AFTER blks last byte */
+    int            readError; /* non-zero is attempt to read past end of data*/
+    int            writeError;/* non-zero is attempt write fails (no mor bufs)*/
+} ExpBuf;
+
+
+
+/* init, alloc and free routines */
+#if defined (DEBUG) /* use fcns when debugging/macros later */ || defined (USE_GEN_BUF)
+
+#ifdef USE_GEN_BUF
+void		PutExpBufInGenBuf PROTO ((ExpBuf *eb,GenBuf *gb));
+#endif
+
+void		ExpBufInit PROTO ((unsigned long dataBlkSize));
+ExpBuf		*ExpBufAllocBuf();
+void		ExpBufFreeBuf PROTO ((ExpBuf *ptr));
+char		*ExpBufAllocData();
+void		ExpBufFreeData PROTO ((char *ptr));
+void		ExpBufFreeBufAndData PROTO (( ExpBuf *b));
+
+ExpBuf		*ExpBufNext PROTO ((ExpBuf *b));
+ExpBuf		*ExpBufPrev PROTO ((ExpBuf *b));
+void		ExpBufResetInReadMode PROTO ((ExpBuf *b));
+void		ExpBufResetInWriteRvsMode PROTO ((ExpBuf *b));
+
+int		ExpBufAtEod PROTO ((ExpBuf *b));
+int		ExpBufFull PROTO ((ExpBuf *b));
+int		ExpBufHasNoData PROTO ((ExpBuf *b));
+unsigned long	ExpBufDataSize PROTO ((ExpBuf *b));
+unsigned long	ExpBufDataBlkSize PROTO ((ExpBuf *b));
+char		*ExpBufDataPtr PROTO ((ExpBuf *b));
+
+#else
+
+extern unsigned long expBufDataBlkSizeG;
+
+#define ExpBufInit( size)		expBufDataBlkSizeG = size;
+#define ExpBufAllocBuf()		((ExpBuf *)malloc (sizeof (ExpBuf)))
+#define ExpBufFreeBuf( ptr)		free (ptr)
+#define ExpBufAllocData()		((void *)malloc (expBufDataBlkSizeG))
+#define ExpBufFreeData( ptr)		free (ptr)
+#define ExpBufFreeBufAndData( b)	{ ExpBufFreeData ((b)->blkStart); ExpBufFreeBuf (b); }
+#define ExpBufNext( b)			((b)->next)
+#define ExpBufPrev( b)			((b)->prev)
+#define ExpBufResetInReadMode( b)	{ (b)->curr = (b)->dataStart; (b)->readError = 0; (b)->writeError = 1; }
+#define ExpBufResetInWriteRvsMode( b)	{ (b)->dataStart = (b)->dataEnd = (b)->blkEnd; (b)->writeError = 0; (b)->readError = 1; }
+
+/* ExpBufAtEod only valid during reads (fwd) */
+#define ExpBufAtEod( b)			((b)->curr == (b)->dataEnd)
+
+/* ExpBufFull only valid during write (reverse) */
+#define ExpBufFull( b)			((b)->dataStart == (b)->blkStart)
+#define ExpBufHasNoData( b)		((b)->dataStart == (b)->dataEnd)
+#define ExpBufDataSize( b)		((b)->dataEnd - (b)->dataStart)
+#define ExpBufDataBlkSize( b)		((b)->blkEnd - (b)->blkStart)
+#define ExpBufDataPtr( b)		(ExpBufHasNoData (b)? NULL: (b)->dataStart)
+
+#endif  /* DEBUG || USE_GEN_BUF */
+
+#ifdef USE_GEN_BUF
+int           ExpBufReadError PROTO ((ExpBuf **b));
+int           ExpBufWriteError PROTO ((ExpBuf **b));
+#else
+#define ExpBufReadError( b)		((*b)->readError)
+#define ExpBufWriteError( b)		((*b)->writeError)
+#endif
+
+ExpBuf		*ExpBufAllocBufAndData();
+void		ExpBufInstallDataInBuf PROTO ((ExpBuf *b, char *data, unsigned long int len));
+void		ExpBufFreeBufAndDataList PROTO (( ExpBuf *b));
+ExpBuf		*ExpBufListLastBuf PROTO ((ExpBuf *b));
+ExpBuf		*ExpBufListFirstBuf PROTO ((ExpBuf *b));
+
+void ExpBufCopyToFile PROTO ((ExpBuf *b, FILE *f));
+
+/* reading and writing routines */
+
+void		ExpBufSkip PROTO (( ExpBuf**, unsigned long len));
+int		ExpBufCopy PROTO (( char *dst, ExpBuf **b, unsigned long len));
+unsigned char	ExpBufPeekByte PROTO (( ExpBuf **b));
+#if TTBL
+int		ExpBufPeekCopy PROTO ((char *dst, ExpBuf **b, unsigned long len));
+char		*ExpBufPeekSeg PROTO ((ExpBuf **b, unsigned long *len));
+#endif
+char		*ExpBufGetSeg PROTO ((ExpBuf **b, unsigned long *len));
+void		ExpBufPutSegRvs PROTO ((ExpBuf **b, char *data, unsigned long len));
+unsigned char	ExpBufGetByte PROTO ((ExpBuf **b));
+void		ExpBufPutByteRvs PROTO ((ExpBuf **b, unsigned char byte));
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/gen-buf.h b/SecuritySNACCRuntime/c-lib/inc/gen-buf.h
new file mode 100644
index 00000000..cf5633e0
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/gen-buf.h
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * gen_buf.h  - flexible (runtime configurable) buffer mgmt stuff.
+ *
+ *  These are somewhat slower than the direct approach used in
+ *  the compiled stuff.  Since tables are around 4x slower,
+ *  the flexibility of the GenBufs can be justified.  This
+ *  also allows one enc/dec library to support all buffer types.
+ *
+ * MS 93
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if USE_GEN_BUF
+
+#ifndef _gen_buf_h_
+#define _gen_buf_h_
+
+/*
+ *  These are the standard buffer routines that the lib
+ *  routines need. Note that the Peek routines have be
+ *  added to the standard list - they are necessary
+ *  to nicely support  the table oriented decoder.
+ *  The "void *b" param's real type will be the buffer
+ *  type that is used inside the GenBuf
+ *  (ie SBuf * or ExpBuf ** have been defined).
+ *
+ *  Note that macros can not be used for these standard functions
+ *  because the GenBuf keeps a pointer to these routines.
+ *  Thus the exp_buf.[ch] and sbuf.[ch] files are somewhat
+ *  differnt than those in snacc/c_lib and snacc/c_include
+ *
+ */
+
+typedef unsigned char	(*BufGetByteFcn) PROTO ((void *b));
+typedef unsigned char	*(*BufGetSegFcn) PROTO ((void *b, unsigned long int *lenPtr));
+typedef long int	(*BufCopyFcn) PROTO ((char *dst, void *b, unsigned long int len));
+typedef void		(*BufSkipFcn) PROTO ((void *b, unsigned long int len));
+typedef unsigned char	(*BufPeekByteFcn) PROTO ((void *b));
+typedef unsigned char	*(*BufPeekSegFcn) PROTO ((void *b, unsigned long int lenPtr));
+typedef long int	(*BufPeekCopyFcn) PROTO ((char *dst, void *b, unsigned long int len));
+typedef void		(*BufPutByteRvsFcn) PROTO ((void *b, unsigned char byte));
+typedef void		(*BufPutSegRvsFcn) PROTO ((void *b, char *data, unsigned long int len));
+typedef int		(*BufReadErrorFcn) PROTO ((void *b));
+typedef int		(*BufWriteErrorFcn) PROTO ((void *b));
+
+
+typedef struct GenBuf
+{
+  BufGetByteFcn		getByte;
+  BufGetSegFcn		getSeg;
+  BufCopyFcn		copy;
+  BufSkipFcn		skip;
+  BufPeekByteFcn	peekByte;
+  BufPeekSegFcn		peekSeg;
+  BufPeekCopyFcn	peekCopy;
+  BufPutByteRvsFcn	putByteRvs;
+  BufPutSegRvsFcn	putSegRvs;
+  BufReadErrorFcn	readError;
+  BufWriteErrorFcn	writeError;
+  void			*bufInfo;
+  void			*spare; /* hack to save space for ExpBuf ** type */
+} GenBuf;
+
+
+#define GenBufGetByte( b)		((b)->getByte (b->bufInfo))
+#define GenBufGetSeg( b, lenPtr)	((b)->getSeg (b->bufInfo, lenPtr))
+#define GenBufCopy( dst, b, len)	((b)->copy (dst, b->bufInfo, len))
+#define GenBufSkip( b, len)		((b)->skip (b->bufInfo,len))
+#define GenBufPeekByte( b)		((b)->peekByte (b->bufInfo))
+#define GenBufPeekSeg( b, lenPtr)	((b)->peekSeg (b->bufInfo, lenPtr))
+#define GenBufPeekCopy( dst, b, len)	((b)->peekCopy (dst, b->bufInfo, len))
+#define GenBufPutByteRvs( b, byte)	((b)->putByteRvs (b->bufInfo, byte))
+#define GenBufPutSegRvs( b, data, len)	((b)->putSegRvs (b->bufInfo, data, len))
+#define GenBufReadError( b)		((b)->readError (b->bufInfo))
+#define GenBufWriteError( b)		((b)->writeError (b->bufInfo))
+
+
+#endif /* _gen_buf_h_ conditional include  */
+
+#endif /* USE_GEN_BUF */
diff --git a/SecuritySNACCRuntime/c-lib/inc/hash.h b/SecuritySNACCRuntime/c-lib/inc/hash.h
new file mode 100644
index 00000000..72ecc887
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/hash.h
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * hash.h
+ *
+ * Based on hashing stuff from UBC Raven Code (Terry Coatta & Don Acton)
+ *
+ * MS 92
+ * Copyright (C) 1992 the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/hash.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: hash.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:21  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1997/02/28 13:39:49  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.2  1995/07/24 21:01:19  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:41  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_hash_h_
+#define _asn_hash_h_
+
+#define TABLESIZE 256
+#define INDEXMASK 0xFF
+#define INDEXSHIFT 8
+
+typedef void *Table[TABLESIZE];
+
+typedef unsigned int Hash;
+
+typedef struct HashSlot
+{
+  int    leaf;
+  Hash   hash;
+  void  *value;
+  Table *table;
+} HashSlot;
+
+Hash MakeHash PROTO ((char *str, unsigned long int len));
+
+Table *InitHash();
+
+int Insert PROTO ((Table *table, void *element, Hash hash));
+
+int CheckFor PROTO ((Table *table, Hash hash));
+
+int CheckForAndReturnValue PROTO ((Table *table, Hash hash, void **value));
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/mem.h b/SecuritySNACCRuntime/c-lib/inc/mem.h
new file mode 100644
index 00000000..587e8f1e
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/mem.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  compiler/core/mem.h
+ *
+ * MS 91/08/03
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/mem.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: mem.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:21  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1994/09/01 00:40:32  rj
+ * snacc_config.h's last macro, MT ( ) got here.
+ *
+ * Revision 1.1  1994/08/28  09:49:22  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _snacc_mem_h_
+#define _snacc_mem_h_
+
+void	*Malloc PROTO ((int size));
+void	*Realloc PROTO ((void *ptr, int newsize));
+void	Free PROTO ((void *ptr));
+
+/* malloc type */
+#define MT( type)	(type *)Malloc (sizeof (type))
+
+#endif
diff --git a/SecuritySNACCRuntime/c-lib/inc/min-buf.h b/SecuritySNACCRuntime/c-lib/inc/min-buf.h
new file mode 100644
index 00000000..0dbc6c0f
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/min-buf.h
@@ -0,0 +1,100 @@
+/*
+ * 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-lib/inc/min-buf.h - trivial buffer routines.
+ *             only use these for
+ *                encoding - if you know you 'buffer' is big enough
+ *                            to hold the encoded value
+ *
+ *                decoding - if you know that the encoding is error
+ *                           free.
+ *
+ *
+ * The minimal buffer is simply a block of mem referenced
+ * by a char **(ie BUF_TYPE char**).  These are very efficient
+ * but should only be used when it is safe (see above) or you're
+ * willing to risk reading past the end of the buffer or writing
+ * 'past' the beginning (segmentation faults/bus errors etc).
+ *
+ * No checks for reading or writing past the buffer are done.
+ * every operation is assumed to succeed.
+ * MS 92
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/min-buf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: min-buf.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:21  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:21  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:42  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _min_buf_h_
+#define _min_buf_h_
+
+#define MinBufGetByte(b)\
+    (unsigned char)(*((*(b))++))
+
+#define MinBufGetSeg( b, lenPtr)\
+    *(b);\
+    (*b) += *lenPtr;
+
+#define MinBufCopy( dst, b, len)\
+    memcpy ((dst), *(b), (len));\
+    (*(b)) += (len);
+
+#define MinBufSkip( b, len) ((*(b)) += len)
+
+#define MinBufPeekByte( b)  (**(b))
+
+
+#define MinBufPutByteRvs( b,  byte)\
+    (*(--(*(b))) = (byte))
+
+#define MinBufPutSegRvs( b, data, len)\
+    ((*(b)) = (*(b)) - (len));\
+    memcpy (*(b), (data), (len));
+
+
+#define MinBufReadError( b)	0  /* always false */
+#define MinBufWriteError( b)	0  /* always false */
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/nibble-alloc.h b/SecuritySNACCRuntime/c-lib/inc/nibble-alloc.h
new file mode 100644
index 00000000..5f11b904
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/nibble-alloc.h
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * nibble_alloc.h - handles buffer allocation
+ * MS 91
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/nibble-alloc.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: nibble-alloc.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:21  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:22  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:21:43  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _nibble_alloc_h_
+#define _nibble_alloc_h_
+
+typedef struct NibbleBuf
+{
+    char *start;
+    char *end;
+    char *curr;
+    struct NibbleBuf *next;
+} NibbleBuf;
+
+
+typedef struct NibbleMem
+{
+    NibbleBuf *firstNibbleBuf;
+    NibbleBuf *currNibbleBuf;
+    unsigned long int incrementSize;
+} NibbleMem;
+
+
+
+void InitNibbleMem PROTO ((unsigned long int initialSize, unsigned long int incrementSize));
+
+void ShutdownNibbleMem();
+
+void ServiceNibbleFault PROTO ((unsigned long int size));
+
+void *NibbleAlloc PROTO ((unsigned long int size));
+
+void ResetNibbleMem();
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/print.h b/SecuritySNACCRuntime/c-lib/inc/print.h
new file mode 100644
index 00000000..10eaceb3
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/print.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * print.h
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/print.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: print.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:21  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:23  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:45:38  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _snaccc_print_h_
+#define _snaccc_print_h_
+
+extern unsigned short int stdIndentG;
+
+void Indent PROTO ((FILE *f, unsigned short int i));
+
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/sbuf.h b/SecuritySNACCRuntime/c-lib/inc/sbuf.h
new file mode 100644
index 00000000..cb91d1b9
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/sbuf.h
@@ -0,0 +1,249 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * sbuf.h  - a buffer consisting of one contiguous block
+ *               that checks for read and write range errors.
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/sbuf.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: sbuf.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:21  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/27 08:54:46  rj
+ * functions used by gen-bufs or type tables merged.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:45:39  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifndef _asn_buf_h_
+#define _asn_buf_h_
+
+typedef struct SBuf
+{
+    char *dataStart;  /* byte last written (or end) */
+    char *dataEnd;    /* ptr to first byte after last valid data byte */
+    char *blkStart;   /* ptr to first byte of the buffer */
+    char *blkEnd;     /* ptr to first byte past end of the buffer */
+    char *readLoc;    /* next byte to read (or end) */
+    int writeError;   /* whether write error occurred */
+    int readError;    /* whether read error occurred */
+} SBuf;
+
+#ifdef USE_GEN_BUF
+
+/* use functions (-> src/sbuf.c) instead of cpp macros */
+
+void		PutSBufInGenBuf PROTO ((SBuf *sb, GenBuf *gb));
+void		SBufInit PROTO ((SBuf *b, char *data, long int dataLen));
+void		SBufResetInReadMode PROTO ((SBuf *b));
+void		SBufResetInWriteRvsMode PROTO ((SBuf *b));
+void		SBufInstallData PROTO ((SBuf *b, char *data, long int dataLen));
+long int	SBufDataLen PROTO ((SBuf *b));
+char		*SBufDataPtr PROTO ((SBuf *b));
+long int	SBufBlkLen PROTO ((SBuf *b));
+char		*SBufBlkPtr PROTO ((SBuf *b));
+int		SBufEod PROTO ((SBuf *b));
+int		SBufReadError PROTO ((SBuf *b));
+int		SBufWriteError PROTO ((SBuf *b));
+void		SBufSkip PROTO ((SBuf *b, long int skipLen));
+void		SBufCopy PROTO ((char *dst, SBuf *b, long int copyLen));
+unsigned char	SBufPeekByte PROTO ((SBuf *b));
+#if TTBL
+char		*SBufPeekSeg PROTO ((SBuf *b, long int *lenPtr));
+void		SBufPeekCopy PROTO ((char *dst, SBuf *b, long int copyLen));
+#endif
+char		*SBufGetSeg PROTO ((SBuf *b,long int *lenPtr));
+void		SBufPutSegRvs PROTO ((SBuf *b, char *seg, long int segLen));
+unsigned char	SBufGetByte PROTO ((SBuf *b));
+void		SBufPutByteRvs PROTO ((SBuf *b, unsigned char byte));
+
+#else
+
+/* initializes a buffer into an 'empty' state */
+#define SBufInit(b, data, dataLen)\
+{ (b)->readError = (b)->writeError = 1;\
+  (b)->blkStart = data;\
+  (b)->blkEnd = data + dataLen;\
+  (b)->dataStart = (b)->dataEnd = (b)->readLoc = (b)->blkEnd;\
+}
+
+#define SBufResetInReadMode(b)\
+{ (b)->readLoc = (b)->dataStart;\
+  (b)->readError = 0;\
+  (b)->writeError = 1;\
+}
+
+#define SBufResetInWriteRvsMode(b)\
+{ (b)->dataStart = (b)->dataEnd = (b)->blkEnd;\
+  (b)->writeError = 0;\
+  (b)->readError = 1;\
+}
+
+/* installs given block of data into a buffer and sets it up for reading */
+#define SBufInstallData(b, data, dataLen)\
+   SBufInit (b, data, dataLen);\
+   (b)->dataStart = (b)->blkStart;\
+   SBufResetInReadMode (b);
+
+/* returns the number of bytes in the data portion */
+#define SBufDataLen(b)\
+  ((b)->dataEnd - (b)->dataStart)
+
+/* returns the pointer to the first data byte */
+#define SBufDataPtr(b)\
+  ((b)->dataStart)
+
+/* returns the size of block, the maximum size for data */
+#define SBufBlkLen(b)\
+  ((b)->blkEnd - (b)->blkStart)
+
+/* returns a pointer to the first byte of the block */
+#define SBufBlkPtr(b)\
+  ((b)->blkStart)
+
+/* returns true if there is no more data to be read in the SBuf */
+#define SBufEod(b)\
+  ((b)->readLoc >= (b)->dataEnd)
+
+/* returns true if you attempted to read past the end of data */
+#define SBufReadError(b)\
+  ((b)->readError)
+
+/*
+ * returns true if you attempted to write past the end of the block
+ * (remember SBufs do not expand like ExpBufs)
+ */
+#define SBufWriteError(b)\
+  ((b)->writeError)
+
+/* Skips the next skipLen bytes for reading */
+#define SBufSkip(b, skipLen)\
+{ if ( ((b)->readLoc + skipLen) > (b)->dataEnd)\
+  {\
+      (b)->readLoc = (b)->dataEnd;\
+      (b)->readError = 1;\
+  }\
+  else\
+      (b)->readLoc += skipLen;\
+}
+
+
+/*
+ * copies copyLen bytes from buffer b into char *dst.
+ * assumes dst is pre-allocated and is large enough.
+ * Will set the read error flag is you attempt to copy
+ * more than the number of unread bytes available.
+ */
+#define SBufCopy(dst, b, copyLen)\
+{ if (((b)->readLoc + copyLen) > (b)->dataEnd)\
+  {\
+      memcpy (dst, (b)->readLoc, (b)->dataEnd - (b)->readLoc);\
+      (b)->readLoc = (b)->dataEnd;\
+      (b)->readError = 1;\
+  }\
+  else\
+  {\
+      memcpy (dst, (b)->readLoc, copyLen);\
+      (b)->readLoc += copyLen;\
+  }\
+}
+
+/*
+ * returns the next byte from the buffer without advancing the
+ * current read location.
+ */
+#define SBufPeekByte(b)\
+    ((SBufEod (b))? ((b)->readError = 1):(unsigned char) *((b)->readLoc))
+
+/*
+ * WARNING: this is a fragile macro. be careful where you use it.
+ * return a pointer into the buffer for the next bytes to be read
+ * if *lenPtr uread bytes are not available, *lenPtr will be set
+ * to the number of byte that are available.  The current read location
+ * is advance by the number of bytes returned in *lenPtr.  The read error
+ * flag will NOT set, ever, by this routine.
+ */
+#define SBufGetSeg( b, lenPtr)\
+    ((b)->readLoc);\
+    if (((b)->readLoc + *lenPtr) > (b)->dataEnd)\
+    {\
+         *lenPtr = (b)->dataEnd - (b)->readLoc;\
+         (b)->readLoc = (b)->dataEnd;\
+    }\
+    else\
+        (b)->readLoc += *lenPtr;
+
+/*
+ * Write in reverse the char *seg of segLen bytes to the buffer b.
+ * A reverse write of segement really just prepends the given seg
+ * (in original order) to the buffers existing data
+ */
+#define SBufPutSegRvs(b, seg, segLen)\
+{ if (((b)->dataStart - segLen) < (b)->blkStart)\
+      (b)->writeError = 1;\
+  else\
+  {\
+     (b)->dataStart -= segLen;\
+     memcpy ((b)->dataStart, seg, segLen);\
+  }\
+}
+
+/*
+ * returns the next byte from buffer b's data and advances the
+ * current read location by one byte.  This will set the read error
+ * flag if you attempt to read past the end of the SBuf
+ */
+#define SBufGetByte(b)\
+   (unsigned char)((SBufEod (b))? ((b)->readError = 1):*((b)->readLoc++))
+
+/*
+ * writes (prepends) the given byte to buffer b's data
+ */
+#define SBufPutByteRvs(b, byte)\
+{ if ((b)->dataStart <= (b)->blkStart)\
+      (b)->writeError = 1;\
+  else\
+      *(--(b)->dataStart) = byte;\
+}
+
+#endif /* USE_GEN_BUF */
+
+#endif /* conditional include */
diff --git a/SecuritySNACCRuntime/c-lib/inc/str-stk.h b/SecuritySNACCRuntime/c-lib/inc/str-stk.h
new file mode 100644
index 00000000..95fb8dd2
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/str-stk.h
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * str_stk.h  - maintains a stack of the components of a bit string
+ * or octet string so they can be copied into a single chunk
+ *
+ *
+ *  CONSTRUCTED BIT AND OCTET STRINGS SUCK. They should be
+ *  specified in the application's ASN.1 spec as SEQUENCE OF OCTET STRING
+ *
+ * this stack stuff is for decoding constructed bit/octet strings
+ * so the user gets a single contiguous bit/octet str instead of
+ * irritating little pieces.  This does not cost a lot more than
+ * a linked octet/bit string type since we're copying from the
+ * buffer anyway, not referencing it directly (even in simple case).
+ * It will cost more if the string stk overflows and
+ * needs to be enlarged via realloc - set the values of
+ * initialStkSizeG, and stkGrowSize carefully for your application.
+ * Once the StkSize grows, it doesn't shrink back ever.
+ *
+ * Only three routine use/deal with this stack garbage
+ *  BDecConsAsnOcts
+ *  BDecConsAsnBits
+ *  SetupConsBitsOctsStringStk
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/str-stk.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: str-stk.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:22  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:01:24  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:45:41  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+typedef struct StrStkElmt
+{
+    char *str;
+    unsigned long int len;
+} StrStkElmt;
+
+typedef struct StrStk
+{
+    StrStkElmt *stk; /* ptr to array of SSElmts with 'size' elmts */
+    unsigned long int initialNumElmts;
+    unsigned long int numElmts;  /* total # of elements in str stk */
+    unsigned long int growElmts; /* # elmts to increase size by when nec */
+    unsigned long int nextFreeElmt; /* index of next free element */
+    unsigned long int totalByteLen; /* octet len of string stored in stk */
+} StrStk;
+
+
+extern StrStk strStkG;
+
+/*
+ * initializes stk (Allocates if nec.)
+ * once stk is enlarged, it doesn't shrink
+ */
+#define RESET_STR_STK()\
+{\
+    strStkG.nextFreeElmt = 0;\
+    strStkG.totalByteLen = 0;\
+    if (strStkG.stk == NULL){\
+       strStkG.stk = (StrStkElmt*) malloc ((strStkG.initialNumElmts) *sizeof (StrStkElmt));\
+       strStkG.numElmts = strStkG.initialNumElmts;}\
+}
+
+
+/*
+ * add a char*,len pair to top of stack.
+ * grows stack if necessary using realloc (!)
+ */
+#define PUSH_STR(strPtr, strsLen, env)\
+{\
+    if (strStkG.nextFreeElmt >= strStkG.numElmts)\
+    {\
+       strStkG.stk = (StrStkElmt*) realloc (strStkG.stk, (strStkG.numElmts + strStkG.growElmts) *sizeof (StrStkElmt));\
+       strStkG.numElmts += strStkG.growElmts;\
+    }\
+    strStkG.totalByteLen += strsLen;\
+    strStkG.stk[strStkG.nextFreeElmt].str = strPtr;\
+    strStkG.stk[strStkG.nextFreeElmt].len = strsLen;\
+    strStkG.nextFreeElmt++;\
+}
+
+
+/*
+ * Set up size values for the stack that is used for merging constructed
+ * octet or bit string into single strings.
+ * ****  Call this before decoding anything. *****
+ * Note: you don't have to call this if the default values
+ * for initialStkSizeG and stkGrowSizeG are acceptable
+ */
+#define SetupConsBitsOctsStringStk (initialNumberOfElmts, numberOfElmtsToGrowBy)\
+{\
+    strStkG.initialNumElmts = initialNumberOfElmts; \
+    strStkG.growElmts = numberOfElmtsToGrowBy;\
+}
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-dbg.h b/SecuritySNACCRuntime/c-lib/inc/tbl-dbg.h
new file mode 100644
index 00000000..9709c03c
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-dbg.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+
+#ifndef TBL_DBG_H
+#define TBL_DBG_H
+
+#include "tbl-gen.h"
+
+extern TdeExceptionCode DBGMinCode; /* Defaults to TDEINFO */
+int DBGSimple PROTO ((AsnTag tag, AsnOcts* v, int begin));
+int DBGType PROTO ((TBLType* type, AVal* val, int begin));
+int DBGExc PROTO ((TdeExceptionCode code, void* p1, void* p2, void* p3));
+
+#endif
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-dec.h b/SecuritySNACCRuntime/c-lib/inc/tbl-dec.h
new file mode 100644
index 00000000..209bd05f
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-dec.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tbl-util.h - type table utilities.
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-dec.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: tbl-dec.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:22  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/27 08:55:52  rj
+ * first check-in after being merged into .../c-lib/.
+ *
+ */
+
+
+AVal *TblDecode PROTO ((TBL *tbl, char *modName, char *typeName, BUF_TYPE b, unsigned long int *bytesDecoded));
+
+AVal *TblDecodeType PROTO ((TBLType *tblT, BUF_TYPE b, int implicit, unsigned long int *bytesDecoded, ENV_TYPE env));
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-enc.h b/SecuritySNACCRuntime/c-lib/inc/tbl-enc.h
new file mode 100644
index 00000000..d9fd1961
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-enc.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tbl-enc.h - type table encoder
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-enc.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: tbl-enc.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:22  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/27 08:55:54  rj
+ * first check-in after being merged into .../c-lib/.
+ *
+ */
+
+
+int TblEncode PROTO ((TBL *tbl, char *modName, char *typeName, BUF_TYPE b, AVal *v, unsigned long int *bytesEncoded));
+
+int TblEncodeType PROTO ((TBLType *tblT, BUF_TYPE b, AVal *v, int implicit, unsigned long int *bytesEncoded));
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-free.h b/SecuritySNACCRuntime/c-lib/inc/tbl-free.h
new file mode 100644
index 00000000..7821a118
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-free.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tbl-free.h - frees data structs returned by type table driven decoder.
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-free.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: tbl-free.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:22  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/27 08:55:55  rj
+ * first check-in after being merged into .../c-lib/.
+ *
+ */
+
+
+void TblFree PROTO ((TBL *tbl, char *modName, char *typeName, AVal *v));
+
+void TblFreeType PROTO ((TBLType *tblT, AVal *v));
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-gen-c-hdr.h b/SecuritySNACCRuntime/c-lib/inc/tbl-gen-c-hdr.h
new file mode 100644
index 00000000..2c82fea7
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-gen-c-hdr.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tbl-gen-c-hdr.h -  prints C type defs for vals
+ *                  tbl decoder will return for the given type table.
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-gen-c-hdr.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: tbl-gen-c-hdr.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:22  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/27 08:55:56  rj
+ * first check-in after being merged into .../c-lib/.
+ *
+ */
+
+void TblPrintCHdr PROTO ((TBL *tbl, FILE *f));
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-gen.h b/SecuritySNACCRuntime/c-lib/inc/tbl-gen.h
new file mode 100644
index 00000000..03bbea75
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-gen.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+
+#ifndef TBL_GEN_H
+#define TBL_GEN_H
+
+#define USE_GEN_BUF 1
+#include "tbl-incl.h"
+
+typedef enum {TDEINFO, TDEEOC=TDEINFO, TDEPEEKTAG, TDEPUSHTAG,
+	TDEWARNING, TDEUNEXPECTED=TDEWARNING, TDENONOPTIONAL, TDEMANDATORY,
+	TDECONSTRAINT, TDENOMATCH,
+	TDEERROR} TdeExceptionCode;
+
+typedef int (*TdeTypeProc) PROTO ((TBLType* type, AVal* val, int begin));
+typedef int (*TdeSimpleProc) PROTO ((AsnTag tag, AsnOcts* val, int begin));
+typedef int (*TdeExcProc) PROTO ((TdeExceptionCode code, void* p1, void* p2, void* p3));
+
+int
+TdeDecode PROTO ((TBL* tbl, BUF_TYPE b, unsigned long int* bytesDecoded,
+    	TdeTypeProc typeproc, TdeSimpleProc simpleproc, TdeExcProc excproc));
+
+int
+TdeDecodeSpecific PROTO ((TBL* tbl, BUF_TYPE b, TBLType* type,
+	unsigned long int* bytesDecoded,
+    	TdeTypeProc typeproc, TdeSimpleProc simpleproc, TdeExcProc excproc));
+#endif
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-incl.h b/SecuritySNACCRuntime/c-lib/inc/tbl-incl.h
new file mode 100644
index 00000000..6a62d448
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-incl.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tbl-incl.h  - wraps all nec tbl stuff in one file
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-incl.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: tbl-incl.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:22  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1997/05/07 15:18:34  wan
+ * Added (limited) size constraints, bitstring and enumeration names to tables
+ *
+ * Revision 1.1  1995/07/27 08:55:57  rj
+ * first check-in after being merged into .../c-lib/.
+ *
+ */
+
+#define TTBL	3
+
+#include "asn-incl.h"
+#include "tbl.h"
+
+typedef void AVal;
+
+typedef AVal *AStructVal;  /* an array of AVal ptrs */
+
+typedef struct AChoiceVal
+{
+    enum { achoiceval_notused } choiceId;
+    AVal *val;
+} AChoiceVal;
+
+
+#include "tbl-util.h"
+#include "tbl-enc.h"
+#include "tbl-dec.h"
+#include "tbl-print.h"
+#include "tbl-free.h"
+
+/*
+ * TblError (char *str) - configure error handler
+ */
+#define TblError( str)		fprintf (stderr, "%s", str)
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-print.h b/SecuritySNACCRuntime/c-lib/inc/tbl-print.h
new file mode 100644
index 00000000..fc901e45
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-print.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tbl-print.h - type table value printer
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-print.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: tbl-print.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:22  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/27 08:55:58  rj
+ * first check-in after being merged into .../c-lib/.
+ *
+ */
+
+
+void TblPrintValue PROTO ((TBL *tbl, char *modName, char *typeName, FILE *f, AVal *v));
+
+void TblPrintTypeValue PROTO ((TBLType *tblT, FILE *f, AVal *v, unsigned short int indent));
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl-util.h b/SecuritySNACCRuntime/c-lib/inc/tbl-util.h
new file mode 100644
index 00000000..d8ad5353
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl-util.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * tbl-util.h - type table utilities.
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/inc/tbl-util.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: tbl-util.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:23  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:23  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/27 08:55:59  rj
+ * first check-in after being merged into .../c-lib/.
+ *
+ */
+
+/*
+ * these rely on the TBLTagClass enum starting at zero
+ * and being in the order: UNIVERSAL, APPLICATION, CONTEXT, PRIVATE
+ */
+#define TblTagClassToBer(tblClass) (tblClass << 6)
+#define BerTagClassToTbl(berClass) (berClass >> 6)
+#define TagsEquiv(asnTag, tblTag) (((tblTag)->encTag == (asnTag)) ||\
+         (((tblTag)->form == ANY_FORM) &&\
+          ((tblTag)->encTag == DECONSIFY (asnTag))))
+
+
+char *LoadFile PROTO ((char *tblFileName, unsigned long int *size));
+
+TBL *LoadTblFile PROTO ((char *tblFileName));
+
+TBLTypeDef *TblFindTypeDef PROTO ((TBL *tbl, char *moduleName, char *typeName, TBLModule **tblModHndl));
+
+TBLTypeDef *TblFindTypeDefInMod PROTO ((TBLModule *tbl, char *typeName));
+
+TBLTypeDef *TblFindTypeDefByIndex PROTO ((TBL *tbl,TBLTypeDefId id));
+
+TBLModule *TblFindModule PROTO ((TBL *tbl, char *modName));
diff --git a/SecuritySNACCRuntime/c-lib/inc/tbl.h b/SecuritySNACCRuntime/c-lib/inc/tbl.h
new file mode 100644
index 00000000..45cdc3be
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/inc/tbl.h
@@ -0,0 +1,362 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    tbl.h
+ *
+ *    "TBL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Thu Jun  8 12:35:28 2000
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _tbl_h_
+#define _tbl_h_
+
+
+
+
+typedef enum
+    {
+        TBL_BOOLEAN = 0,
+        TBL_INTEGER = 1,
+        TBL_BITSTRING = 2,
+        TBL_OCTETSTRING = 3,
+        TBL_NULL = 4,
+        TBL_OID = 5,
+        TBL_REAL = 6,
+        TBL_ENUMERATED = 7,
+        TBL_SEQUENCE = 8,
+        TBL_SET = 9,
+        TBL_SEQUENCEOF = 10,
+        TBL_SETOF = 11,
+        TBL_CHOICE = 12,
+        TBL_TYPEREF = 13
+    } TBLTypeId; /* ENUMERATED { TBL_BOOLEAN (0), TBL_INTEGER (1), TBL_BITSTRING (2), TBL_OCTETSTRING (3), TBL_NULL (4), TBL_OID (5), TBL_REAL (6), TBL_ENUMERATED (7), TBL_SEQUENCE (8), TBL_SET (9), TBL_SEQUENCEOF (10), TBL_SETOF (11), TBL_CHOICE (12), TBL_TYPEREF (13) }  */
+
+#define BEncTBLTypeIdContent BEncAsnEnumContent
+
+#define BDecTBLTypeIdContent BDecAsnEnumContent
+
+#define PrintTBLTypeId PrintAsnEnum
+
+#define FreeTBLTypeId FreeAsnEnum 
+
+
+
+
+typedef AsnInt TBLTypeDefId; /* INTEGER */
+
+#define BEncTBLTypeDefIdContent BEncAsnIntContent
+
+#define BDecTBLTypeDefIdContent BDecAsnIntContent
+
+#define PrintTBLTypeDefId PrintAsnInt
+
+#define FreeTBLTypeDefId FreeAsnInt 
+
+
+
+
+typedef enum
+    {
+        UNIVERSAL = 0,
+        APPLICATION = 1,
+        CONTEXT = 2,
+        PRIVATE = 3
+    } TBLTagClass; /* ENUMERATED { UNIVERSAL (0), APPLICATION (1), CONTEXT (2), PRIVATE (3) }  */
+
+#define BEncTBLTagClassContent BEncAsnEnumContent
+
+#define BDecTBLTagClassContent BDecAsnEnumContent
+
+#define PrintTBLTagClass PrintAsnEnum
+
+#define FreeTBLTagClass FreeAsnEnum 
+
+
+
+
+typedef struct TBLRange /* SEQUENCE */
+{
+    AsnInt from; /* [0] IMPLICIT INTEGER */
+    AsnInt to; /* [1] IMPLICIT INTEGER */
+} TBLRange;
+
+AsnLen BEncTBLRangeContent PROTO ((BUF_TYPE b, TBLRange *v));
+
+void BDecTBLRangeContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLRange *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLRange PROTO ((FILE* f, TBLRange *v, unsigned short int indent));
+void FreeTBLRange PROTO ((TBLRange *v));
+
+
+
+
+
+typedef struct TBLNamedNumber /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnInt value; /* [1] IMPLICIT INTEGER */
+} TBLNamedNumber;
+
+AsnLen BEncTBLNamedNumberContent PROTO ((BUF_TYPE b, TBLNamedNumber *v));
+
+void BDecTBLNamedNumberContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLNamedNumber *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLNamedNumber PROTO ((FILE* f, TBLNamedNumber *v, unsigned short int indent));
+void FreeTBLNamedNumber PROTO ((TBLNamedNumber *v));
+
+
+
+
+
+typedef AsnList TBLNamedNumberList; /* SEQUENCE OF TBLNamedNumber */
+
+AsnLen BEncTBLNamedNumberListContent PROTO ((BUF_TYPE b, TBLNamedNumberList *v));
+
+void BDecTBLNamedNumberListContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLNamedNumberList *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLNamedNumberList PROTO ((FILE* f, TBLNamedNumberList *v, unsigned short int indent));
+void FreeTBLNamedNumberList PROTO ((TBLNamedNumberList *v));
+
+
+
+
+
+typedef struct TBLTypeRef /* SEQUENCE */
+{
+    TBLTypeDefId typeDef; /* TBLTypeDefId */
+    AsnBool implicit; /* BOOLEAN */
+    struct TBLTypeDef *typeDefPtr;  /* Added by MS to hold resolved index */
+} TBLTypeRef;
+
+AsnLen BEncTBLTypeRefContent PROTO ((BUF_TYPE b, TBLTypeRef *v));
+
+void BDecTBLTypeRefContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeRef *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeRef PROTO ((FILE* f, TBLTypeRef *v, unsigned short int indent));
+void FreeTBLTypeRef PROTO ((TBLTypeRef *v));
+
+
+
+
+
+typedef struct TBLTag /* SEQUENCE */
+{
+    TBLTagClass tclass; /* TBLTagClass */
+    AsnInt code; /* INTEGER (0..MAX) */
+    BER_FORM form; /* added by MS to simplify enc/dec */
+    AsnTag encTag; /* added by MS to simplify enc/dec */
+} TBLTag;
+
+AsnLen BEncTBLTagContent PROTO ((BUF_TYPE b, TBLTag *v));
+
+void BDecTBLTagContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTag *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTag PROTO ((FILE* f, TBLTag *v, unsigned short int indent));
+void FreeTBLTag PROTO ((TBLTag *v));
+
+
+
+
+
+typedef AsnList TBLTypeSeqOf; /* SEQUENCE OF TBLTag */
+
+AsnLen BEncTBLTypeSeqOfContent PROTO ((BUF_TYPE b, TBLTypeSeqOf *v));
+
+void BDecTBLTypeSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeSeqOf PROTO ((FILE* f, TBLTypeSeqOf *v, unsigned short int indent));
+void FreeTBLTypeSeqOf PROTO ((TBLTypeSeqOf *v));
+
+
+
+
+
+typedef AsnList TBLTypeContentSeqOf; /* SEQUENCE OF TBLType */
+
+AsnLen BEncTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, TBLTypeContentSeqOf *v));
+
+void BDecTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeContentSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeContentSeqOf PROTO ((FILE* f, TBLTypeContentSeqOf *v, unsigned short int indent));
+void FreeTBLTypeContentSeqOf PROTO ((TBLTypeContentSeqOf *v));
+
+
+
+
+
+typedef struct TBLType /* SEQUENCE */
+{
+    TBLTypeId typeId; /* [0] IMPLICIT TBLTypeId */
+    AsnBool optional; /* [1] IMPLICIT BOOLEAN */
+    TBLTypeSeqOf* tagList; /* [2] IMPLICIT TBLTypeSeqOf OPTIONAL */
+    struct TBLTypeContent* content; /* [3] TBLTypeContent */
+    PrintableString fieldName; /* [4] IMPLICIT PrintableString OPTIONAL */
+    struct TBLRange* constraint; /* [5] IMPLICIT TBLRange OPTIONAL */
+    TBLNamedNumberList* values; /* [6] IMPLICIT TBLNamedNumberList OPTIONAL */
+} TBLType;
+
+AsnLen BEncTBLTypeContent PROTO ((BUF_TYPE b, TBLType *v));
+
+void BDecTBLTypeContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLType *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLType PROTO ((FILE* f, TBLType *v, unsigned short int indent));
+void FreeTBLType PROTO ((TBLType *v));
+
+
+
+
+
+typedef struct TBLTypeContent /* CHOICE */
+{
+    enum TBLTypeContentChoiceId
+    {
+        TBLTYPECONTENT_PRIMTYPE,
+        TBLTYPECONTENT_ELMTS,
+        TBLTYPECONTENT_TYPEREF
+    } choiceId;
+    union TBLTypeContentChoiceUnion
+    {
+    AsnNull primType; /* [0] IMPLICIT NULL */
+    TBLTypeContentSeqOf* elmts; /* [1] IMPLICIT TBLTypeContentSeqOf */
+    struct TBLTypeRef* typeRef; /* [2] IMPLICIT TBLTypeRef */
+    } a;
+} TBLTypeContent;
+
+AsnLen BEncTBLTypeContentContent PROTO ((BUF_TYPE b, TBLTypeContent *v));
+
+void BDecTBLTypeContentContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeContent *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeContent PROTO ((FILE* f, TBLTypeContent *v, unsigned short int indent));
+void FreeTBLTypeContent PROTO ((TBLTypeContent *v));
+
+
+
+
+
+typedef struct TBLTypeDef /* SEQUENCE */
+{
+    TBLTypeDefId typeDefId; /* TBLTypeDefId */
+    PrintableString typeName; /* PrintableString */
+    struct TBLType* type; /* TBLType */
+    AsnNull* isPdu; /* NULL OPTIONAL */
+} TBLTypeDef;
+
+AsnLen BEncTBLTypeDefContent PROTO ((BUF_TYPE b, TBLTypeDef *v));
+
+void BDecTBLTypeDefContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeDef *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeDef PROTO ((FILE* f, TBLTypeDef *v, unsigned short int indent));
+void FreeTBLTypeDef PROTO ((TBLTypeDef *v));
+
+
+
+
+
+typedef AsnList TBLModuleSeqOf; /* SEQUENCE OF TBLTypeDef */
+
+AsnLen BEncTBLModuleSeqOfContent PROTO ((BUF_TYPE b, TBLModuleSeqOf *v));
+
+void BDecTBLModuleSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLModuleSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLModuleSeqOf PROTO ((FILE* f, TBLModuleSeqOf *v, unsigned short int indent));
+void FreeTBLModuleSeqOf PROTO ((TBLModuleSeqOf *v));
+
+
+
+
+
+typedef struct TBLModule /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnOid id; /* [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL */
+    AsnBool isUseful; /* [2] IMPLICIT BOOLEAN */
+    TBLModuleSeqOf* typeDefs; /* [3] IMPLICIT TBLModuleSeqOf */
+} TBLModule;
+
+AsnLen BEncTBLModuleContent PROTO ((BUF_TYPE b, TBLModule *v));
+
+void BDecTBLModuleContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLModule *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLModule PROTO ((FILE* f, TBLModule *v, unsigned short int indent));
+void FreeTBLModule PROTO ((TBLModule *v));
+
+
+
+
+
+typedef AsnList TBLSeqOf; /* SEQUENCE OF TBLModule */
+
+AsnLen BEncTBLSeqOfContent PROTO ((BUF_TYPE b, TBLSeqOf *v));
+
+void BDecTBLSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLSeqOf PROTO ((FILE* f, TBLSeqOf *v, unsigned short int indent));
+void FreeTBLSeqOf PROTO ((TBLSeqOf *v));
+
+
+
+
+
+typedef struct TBL /* SEQUENCE */
+{
+    AsnInt totalNumModules; /* INTEGER */
+    AsnInt totalNumTypeDefs; /* INTEGER */
+    AsnInt totalNumTypes; /* INTEGER */
+    AsnInt totalNumTags; /* INTEGER */
+    AsnInt totalNumStrings; /* INTEGER */
+    AsnInt totalLenStrings; /* INTEGER */
+    TBLSeqOf* modules; /* TBLSeqOf */
+} TBL;
+
+AsnLen BEncTBL PROTO ((BUF_TYPE b, TBL *v));
+
+void BDecTBL PROTO ((BUF_TYPE b, TBL *result, AsnLen *bytesDecoded, ENV_TYPE env));
+AsnLen BEncTBLContent PROTO ((BUF_TYPE b, TBL *v));
+
+void BDecTBLContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBL *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBL PROTO ((FILE* f, TBL *v, unsigned short int indent));
+void FreeTBL PROTO ((TBL *v));
+
+
+
+
+
+
+#endif /* conditional include of tbl.h */
diff --git a/SecuritySNACCRuntime/c-lib/install-sh b/SecuritySNACCRuntime/c-lib/install-sh
new file mode 100644
index 00000000..ab74c882
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/SecuritySNACCRuntime/c-lib/makefile b/SecuritySNACCRuntime/c-lib/makefile
new file mode 100644
index 00000000..c76c5047
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/makefile
@@ -0,0 +1,401 @@
+# c-lib/makefile
+#
+# makes C ASN.1 runtime libraries (one for each flavour of buffer)
+#
+# MS 92
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/makefile,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:07  mb
+# Move from private repository to open source repository
+#
+# Revision 1.3  2000/12/22 01:22:41  dmitch
+# Misc. mods for clean build on Cheetah 1D7.
+#
+# Revision 1.2  2000/06/08 20:07:49  dmitch
+# Mods for X port.
+#
+# Revision 1.1.1.1  1999/03/16 18:06:10  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.12  1997/08/27 15:55:30  wan
+# Added generic table decoding, debug routines, berdecode, and asnwish.
+#
+# Revision 1.11  1997/03/13 09:15:08  wan
+# Improved dependency generation for stupid makedepends.
+# Corrected PeekTag to peek into buffer only as far as necessary.
+# Added installable error handler.
+# Fixed small glitch in idl-code generator (Markku Savela <msa@msa.tte.vtt.fi>).
+#
+# Revision 1.10  1997/02/16 12:34:03  rj
+# let make clobber remove the link to install-sh that make made
+#
+# Revision 1.9  1995/09/07 18:58:15  rj
+# asn-useful.asn1 is compiled with the -l 50 option, as recommended by MS in the documentation
+#
+# Revision 1.8  1995/07/24  20:56:31  rj
+# useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme.
+#
+# generate tbl.[hc] from .../asn1specs/tbl.asn1
+# patch tbl.h to add some data members.
+# distribute boot versions of tbl.[ch] and tbl.h.path.
+#
+# generate type table library.
+#
+# create installation directories only if they do not exist already.
+#
+# ranlib the copied libraries.
+#
+# call make recursively to generate the libraries different dependencies and concatenate them.
+#
+# changed `_' to `-' in file names.
+#
+# Revision 1.7  1995/02/20  11:42:04  rj
+# remove stamp-useful before removing asn-useful.[hc].
+# distribute install-sh.
+# use $(INSTALL*) in a for-loop as some install programs (namely the distributed install-sh) only process their first argument!
+#
+# Revision 1.6  1995/02/09  14:02:47  rj
+# enforce generation of inc/asn-useful.h and src/asn-useful.c when making dependencies
+#
+# Revision 1.5  1994/10/08  05:27:56  rj
+# typo fixed.
+#
+# Revision 1.4  1994/10/08  05:20:07  rj
+# don't distribute the non-bootstrapping version of asn-useful.[hc]
+#
+# Revision 1.3  1994/10/08  04:47:42  rj
+# the files asn-useful.[hc] get regenerated automagically. since the compiler itself is compiled with it, a bootstapping version is included in the distribution.
+#
+# Revision 1.2  1994/08/31  23:51:42  rj
+# DISTFILES and install phony target added.
+#
+# Revision 1.1  1994/08/28  09:21:20  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../makehead
+include ../makehead.static
+
+DEPENDENCIES	=
+
+TOP		= ..
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+USEFUL_TYPES	= $(ASN1_SRC_DIR)/asn-useful.asn1
+
+CPPFLAGS	+= -I$(TOP) -Iinc $(bufFLAGS) $(compilerFLAGS)
+
+RANLIB= /usr/bin/ranlib
+
+HFILES.d = \
+	inc/asn-any.h		\
+	inc/asn-bits.h		\
+	inc/asn-bool.h		\
+	inc/asn-config.h	\
+	inc/asn-enum.h		\
+	inc/asn-incl.h		\
+	inc/asn-int.h		\
+	inc/asn-len.h		\
+	inc/asn-list.h		\
+	inc/asn-null.h		\
+	inc/asn-octs.h		\
+	inc/asn-oid.h		\
+	inc/asn-real.h		\
+	inc/asn-tag.h		\
+	inc/exp-buf.h		\
+	inc/gen-buf.h		\
+	inc/hash.h		\
+	inc/min-buf.h		\
+	inc/nibble-alloc.h	\
+	inc/print.h		\
+	inc/sbuf.h		\
+	inc/str-stk.h		\
+	\
+	inc/tbl-dec.h		\
+	inc/tbl-enc.h		\
+	inc/tbl-free.h		\
+	inc/tbl-gen.h		\
+	inc/tbl-dbg.h		\
+	inc/tbl-gen-c-hdr.h	\
+	inc/tbl-incl.h		\
+	inc/tbl-print.h		\
+	inc/tbl-util.h
+
+HFILES = \
+	$(HFILES.d)		\
+	inc/asn-useful.h	\
+	inc/tbl.h
+
+HFILES.shared = \
+	$(TOP)/snacc.h		\
+	$(TOP)/config.h		\
+	$(TOP)/policy.h
+
+CFILES.d = \
+	src/asn-len.c		\
+	src/asn-tag.c		\
+	src/asn-int.c		\
+	src/asn-bool.c		\
+	src/asn-bits.c		\
+	src/asn-octs.c		\
+	src/asn-oid.c		\
+	src/asn-real.c		\
+	src/asn-null.c		\
+	src/asn-list.c		\
+	src/asn-enum.c		\
+	src/str-stk.c		\
+	src/nibble-alloc.c	\
+	src/print.c		\
+	src/asn-any.c		\
+	src/hash.c		\
+	src/exp-buf.c		\
+	src/sbuf.c		\
+	\
+	src/tbl-dec.c		\
+	src/tbl-enc.c		\
+	src/tbl-free.c 		\
+	src/tbl-gen.c		\
+	src/tbl-dbg.c		\
+	src/tbl-print.c		\
+	src/tbl-util.c
+
+CFILES = \
+	$(CFILES.d)		\
+	src/asn-useful.c	\
+	src/tbl.c
+
+OFILES = \
+	$b/asn-len.o		\
+	$b/asn-tag.o		\
+	$b/asn-int.o		\
+	$b/asn-bool.o		\
+	$b/asn-bits.o		\
+	$b/asn-octs.o		\
+	$b/asn-oid.o		\
+	$b/asn-real.o		\
+	$b/asn-null.o		\
+	$b/asn-list.o		\
+	$b/asn-useful.o		\
+	$b/asn-enum.o		\
+	$b/str-stk.o		\
+	$b/nibble-alloc.o	\
+	$b/print.o		\
+	$b/asn-any.o		\
+	$b/hash.o		\
+	$b/exp-buf.o		\
+	$b/sbuf.o		\
+	\
+	$b/tbl.o		\
+	$b/tbl-dec.o		\
+	$b/tbl-enc.o		\
+	$b/tbl-free.o 		\
+	$b/tbl-gen.o		\
+	$b/tbl-dbg.o		\
+	$b/tbl-print.o		\
+	$b/tbl-util.o
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(HFILES.d)	\
+	$(CFILES.d)	\
+	boot/asn-useful.h	\
+	boot/asn-useful.c	\
+	tbl.h.patch	\
+	boot/tbl.h	\
+	boot/tbl.c
+
+EXPORTLIBS	= libasn1cebuf.a libasn1cmbuf.a libasn1csbuf.a libasn1ctbl.a
+compilerLIB	= libasn1cCebuf.a
+
+LIBS	= \
+	$(EXPORTLIBS)	\
+	$(compilerLIB)
+
+MAKEFLAGS.ebuf	= bufFLAGS=-DUSE_EXP_BUF b=ebuf ebuf
+MAKEFLAGS.Cebuf	= bufFLAGS=-DUSE_EXP_BUF b=Cebuf Cebuf
+MAKEFLAGS.mbuf	= bufFLAGS=-DUSE_MIN_BUF b=mbuf mbuf
+MAKEFLAGS.sbuf	= bufFLAGS=-DUSE_SBUF b=sbuf sbuf
+MAKEFLAGS.tbl	= bufFLAGS="-DUSE_GEN_BUF -DTTBL" b=tbl tbl
+
+#-------------------------------------------------------------------------------
+
+.PHONY:	ebuf Cebuf mbuf sbuf tbl
+
+default::	ebuf-lib mbuf-lib sbuf-lib tbl-lib
+		@echo "C ASN.1 libraries made"
+
+all::		default Cebuf-lib
+
+b = dummy
+
+$b::		$(CFILES)
+
+$b::
+		test -d $@ || mkdir $@
+		$(RM) $@/*.c
+		-ln $(CFILES) $@
+
+.PHONY:	ofiles lib
+.PHONY:	ebuf-lib Cebuf-lib mbuf-lib sbuf-lib tbl-lib
+
+ofiles:		$(OFILES)
+
+lib:		libasn1c$b.a
+
+ebuf-lib:
+		$(MAKE) $(MAKEFLAGS.ebuf) ofiles lib
+
+Cebuf-lib:
+		$(MAKE) $(MAKEFLAGS.Cebuf) ofiles lib
+
+mbuf-lib:
+		$(MAKE) $(MAKEFLAGS.mbuf) ofiles lib
+
+sbuf-lib:
+		$(MAKE) $(MAKEFLAGS.sbuf) ofiles lib
+
+tbl-lib:
+		$(MAKE) $(MAKEFLAGS.tbl) ofiles lib
+
+libasn1cebuf.a	\
+libasn1cCebuf.a	\
+libasn1cmbuf.a	\
+libasn1csbuf.a	\
+libasn1ctbl.a:	$(OFILES)
+		$(AR) rv $@ $?
+		$(RANLIB) $@
+
+inc/asn-useful.h	\
+src/asn-useful.c::
+		$(RM) inc/asn-useful.h src/asn-useful.c
+		if [ -f $(SNACC) ]; then\
+		  $(MAKE) stamp-useful;\
+		else\
+		  $(RM) asn-useful.h asn-useful.c;\
+		  ln boot/asn-useful.h boot/asn-useful.c .;\
+		fi
+		ln asn-useful.h inc
+		ln asn-useful.c src
+
+stamp-useful:	$(SNACC) $(USEFUL_TYPES) makefile
+		-mv asn-useful.h asn-useful.h.prev
+		-mv asn-useful.c asn-useful.c.prev
+		$(SNACC) -c -l 50 $(USEFUL_TYPES)
+# the dates in the two files will differ, so the files really differ if diff prints more than 4 lines of output:
+		@if [ -f asn-useful.h.prev ]; then\
+		  if [ `diff asn-useful.h.prev asn-useful.h | wc -l` -gt 4 ]; then\
+		    $(RM) asn-useful.h.prev;\
+		  else\
+		    echo "asn-useful.h hasn't changed";\
+		    mv asn-useful.h.prev asn-useful.h;\
+		  fi;\
+		fi
+		@if [ -f asn-useful.c.prev ]; then\
+		  if [ `diff asn-useful.c.prev asn-useful.c | wc -l` -gt 4 ]; then\
+		    $(RM) asn-useful.c.prev;\
+		  else\
+		    echo "asn-useful.c hasn't changed";\
+		    mv asn-useful.c.prev asn-useful.c;\
+		  fi;\
+		fi
+		date > $@
+
+boot/asn-useful.h	\
+boot/asn-useful.c:	stamp-useful
+		$(RM) boot/asn-useful.h boot/asn-useful.c
+		cp -p asn-useful.h asn-useful.c boot
+
+inc/tbl.h	\
+src/tbl.c::
+		$(RM) inc/tbl.h src/tbl.c
+		if [ -f $(SNACC) ]; then\
+		  $(MAKE) stamp-tbl;\
+		else\
+		  $(RM) tbl.h tbl.c;\
+		  ln boot/tbl.h boot/tbl.c .;\
+		fi
+		ln tbl.h inc
+		ln tbl.c src
+
+stamp-tbl:	$(SNACC) $(USEFUL_TYPES) $(ASN1_SRC_DIR)/tbl.asn1 makefile
+		-mv tbl.h tbl.h.prev
+		-mv tbl.c tbl.c.prev
+		$(SNACC) -u $(USEFUL_TYPES) $(ASN1_SRC_DIR)/tbl.asn1
+		$(PATCH) < tbl.h.patch
+		echo '#if TTBL' > tbl.c.tmp
+		cat tbl.c >> tbl.c.tmp
+		echo '#endif /* TTBL */' >> tbl.c.tmp
+		mv tbl.c.tmp tbl.c
+# the dates in the two files will differ, so the files really differ if diff prints more than 4 lines of output:
+		@if [ -f tbl.h.prev ]; then\
+		  if [ `diff tbl.h.prev tbl.h | wc -l` -gt 4 ]; then\
+		    $(RM) tbl.h.prev;\
+		  else\
+		    echo "tbl.h hasn't changed";\
+		    mv tbl.h.prev tbl.h;\
+		  fi;\
+		fi
+		@if [ -f tbl.c.prev ]; then\
+		  if [ `diff tbl.c.prev tbl.c | wc -l` -gt 4 ]; then\
+		    $(RM) tbl.c.prev;\
+		  else\
+		    echo "tbl.c hasn't changed";\
+		    mv tbl.c.prev tbl.c;\
+		  fi;\
+		fi
+		date > $@
+
+boot/tbl.h	\
+boot/tbl.c:	stamp-tbl
+		$(RM) boot/tbl.h boot/tbl.c
+		cp -p tbl.h tbl.c boot
+
+install-sh:
+		ln $(TOP)/install-sh $@
+
+$(incdir)/snacc/c $(libdir):
+		$(TOP)/mkinstalldirs $@
+
+install::	$(HFILES) ebuf-lib mbuf-lib sbuf-lib tbl-lib install-sh $(incdir)/snacc/c $(libdir)
+
+install::
+		for h in $(HFILES) $(HFILES.shared); do $(INSTALL_DATA) $$h $(incdir)/snacc/c/; done
+		for l in $(EXPORTLIBS); do $(INSTALL_DATA) $$l $(libexecdir)/; $(RANLIB) -t $(libexecdir)/$$l; done
+
+clean::
+		$(RM) *.o *~ *.prev .emacs* core
+		$(RM) stamp-useful stamp-tbl
+		$(RM) asn-useful.h inc/asn-useful.h
+		$(RM) asn-useful.c src/asn-useful.c
+		$(RM) tbl.h inc/tbl.h
+		$(RM) tbl.c src/tbl.c
+		$(RM) -r ebuf Cebuf mbuf sbuf tbl
+		$(RM) $(compilerLIB)
+
+clobber::
+		$(RM) $(LIBS)
+		$(RM) install-sh
+
+depend::	inc/asn-useful.h src/asn-useful.c
+depend::	inc/tbl.h src/tbl.c
+
+depend::
+		if [ x"$(DEPENDENCIES)" = x ]; then\
+		  $(MAKE) $(MAKEFLAGS.ebuf) DEPENDENCIES=deps.ebuf depend;\
+		  $(MAKE) $(MAKEFLAGS.Cebuf) DEPENDENCIES=deps.Cebuf depend;\
+		  $(MAKE) $(MAKEFLAGS.mbuf) DEPENDENCIES=deps.mbuf depend;\
+		  $(MAKE) $(MAKEFLAGS.sbuf) DEPENDENCIES=deps.sbuf depend;\
+		  $(MAKE) $(MAKEFLAGS.tbl) DEPENDENCIES=deps.tbl depend;\
+		  cp /dev/null dependencies;\
+		  for dir in ebuf Cebuf mbuf sbuf tbl; do\
+		    < deps.$$dir sed -e "s/^src/$$dir/;s/^[a-z-]*\.o:/$$dir\/&/" >> dependencies;\
+		    $(RM) deps.$$dir;\
+		  done;\
+		fi
+
+include ../maketail
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-any.c b/SecuritySNACCRuntime/c-lib/src/asn-any.c
new file mode 100644
index 00000000..4b5c8ab9
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-any.c
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_any.c - BER encode, decode, print, free, type set up and installation
+ *             routines for the ASN.1 ANY and ANY DEFINED BY types.
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-any.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-any.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:30  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1997/02/28 13:39:49  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.2  1995/07/24 21:04:48  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:45:49  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-oid.h"
+#include "asn-int.h"
+#include "asn-any.h"
+
+/*
+ * 2 hash tables. 1 for INTEGER to type mappings the other
+ * for OBJECT IDENTIFER to type mappings.
+ */
+Table *anyOidHashTblG = NULL;
+Table *anyIntHashTblG = NULL;
+
+/*
+ * given an ANY type value and a integer hash key, this defines
+ * this any values type (gets ptr to hash tbl entry from int key).
+ * The hash table entry contains ptrs to the encode/decode etc. routines.
+ */
+void
+SetAnyTypeByInt PARAMS ((v, id),
+    AsnAny *v _AND_
+    AsnInt id)
+{
+    Hash hash;
+    void *anyInfo;
+
+    /* use int as hash string */
+    hash = MakeHash ((char*)&id, sizeof (id));
+    if (CheckForAndReturnValue (anyIntHashTblG, hash, &anyInfo))
+        v->ai = (AnyInfo*) anyInfo;
+    else
+        v->ai = NULL; /* indicates failure */
+
+} /* SetAnyTypeByInt */
+
+
+/*
+ * Same as SetAnyTypeByInt except that the hash key is an OBJECT IDENTIFER.
+ */
+void SetAnyTypeByOid PARAMS ((v, id),
+    AsnAny *v _AND_
+    AsnOid *id)
+{
+    Hash hash;
+    void *anyInfo;
+
+    /* use encoded oid as hash string */
+    hash = MakeHash (id->octs, id->octetLen);
+    if (CheckForAndReturnValue (anyOidHashTblG, hash, &anyInfo))
+        v->ai = (AnyInfo*) anyInfo;
+    else
+        v->ai = NULL; /* indicates failure */
+
+} /* SetAnyTypeByOid */
+
+
+/*
+ * Creates an entry in the hash table that contains the
+ * type's size, encode, decode, free, and print routines and anyId.
+ * The given intId is used as the hash key so future calls to
+ * SetAnyTypeByInt with that intId as the id will reference this entry.
+ * The anyId is stored in the hash tbl entry as well so the user can
+ * figure out the type with a simple integer comparison.
+ *
+ * This routine is usually called from the AnyInit routine that
+ * the compiler generates from MACRO info.  Call this routine
+ * once for each possible ANY type to set up the hash table.
+ * Future calls to SetAnyTypeByInt/Oid will reference this table.
+ */
+void
+InstallAnyByInt PARAMS ((anyId, intId, size, Encode, Decode, Free, Print),
+    int anyId _AND_
+    AsnInt intId _AND_
+    unsigned int size _AND_
+    EncodeFcn Encode _AND_
+    DecodeFcn Decode _AND_
+    FreeFcn Free _AND_
+    PrintFcn Print)
+{
+    AnyInfo *a;
+    Hash h;
+
+    a = (AnyInfo*) malloc (sizeof (AnyInfo));
+    a->anyId = anyId;
+    a->oid.octs = NULL;
+    a->oid.octetLen = 0;
+    a->intId = intId;
+    a->size = size;
+    a->Encode = Encode;
+    a->Decode = Decode;
+    a->Free = Free;
+    a->Print = Print;
+
+    if (anyIntHashTblG == NULL)
+        anyIntHashTblG = InitHash();
+
+    h = MakeHash ((char*)&intId, sizeof (intId));
+    Insert (anyIntHashTblG, a, h);
+
+}  /* InstallAnyByOid */
+
+
+/*
+ * Same as InstallAnyByInt except the oid is used as the hash key
+ */
+void
+InstallAnyByOid PARAMS ((anyId, oid, size, Encode, Decode, Free, Print),
+    int anyId _AND_
+    AsnOid *oid _AND_
+    unsigned int size _AND_
+    EncodeFcn Encode _AND_
+    DecodeFcn Decode _AND_
+    FreeFcn Free _AND_
+    PrintFcn Print)
+{
+    AnyInfo *a;
+    Hash h;
+
+    a = (AnyInfo*) malloc (sizeof (AnyInfo));
+    a->anyId = anyId;
+    a->oid.octs = oid->octs;
+    a->oid.octetLen = oid->octetLen;
+    a->size = size;
+    a->Encode = Encode;
+    a->Decode = Decode;
+    a->Free = Free;
+    a->Print = Print;
+
+    h = MakeHash (oid->octs, oid->octetLen);
+
+    if (anyOidHashTblG == NULL)
+        anyOidHashTblG = InitHash();
+
+    Insert (anyOidHashTblG, a, h);
+
+}  /* InstallAnyByOid */
+
+
+/*
+ * Calls the free routine in this type's any info.
+ * If the routine ptr is NULL, nothing is done
+ * (This is the case for INTEGERs, BOOLEANs and other simple
+ * values)
+ */
+void
+FreeAsnAny PARAMS ((v),
+    AsnAny *v)
+{
+    if ((v->ai != NULL) && (v->ai->Free != NULL))
+        v->ai->Free (v->value);
+} /* FreeAsnAny */
+
+
+/*
+ * Calls the Encode routine pointed to in the given type's
+ * Any Info.  If the routine ptr is NULL nothing is encoded
+ * (This should set some type of error).
+ * Note: this calls the BEncFoo not BEncFooContent routine form
+ * since the tags are needed too.
+ */
+AsnLen
+BEncAsnAny PARAMS ((b, v),
+    BUF_TYPE b _AND_
+    AsnAny *v)
+{
+    if ((v->ai != NULL) && (v->ai->Encode != NULL))
+        return v->ai->Encode (b, v->value);
+    else
+        return 0;
+} /* BEncAsnAny */
+
+
+/*
+ * Calls the Decode routine pointed to in the given type's
+ * Any Info.  If the routine ptr is NULL any error is flagged.
+ * Note: this calls the BDecFoo not BDecFooContent routine form
+ * since the tags are needed too.
+ */
+void BDecAsnAny PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnAny  *result _AND_
+    AsnLen *bytesDecoded _AND_
+    ENV_TYPE env)
+{
+    if ((result->ai != NULL) && (result->ai->Decode != NULL))
+    {
+        result->value = (void*) Asn1Alloc (result->ai->size);
+        result->ai->Decode (b, result->value, bytesDecoded, env);
+    }
+    else
+    {
+        Asn1Error ("ERROR - ANY Decode routine is NULL\n");
+        longjmp (env, -44);
+    }
+}
+
+/*
+ * Calls the print routine pointed to from the given type's
+ * Any Info.  Prints an error if the type does not have
+ * any 'AnyInfo' or if the AnyInfo has a NULL Print routine ptr.
+ */
+void PrintAsnAny PARAMS ((f, v, indent),
+    FILE *f _AND_
+    AsnAny *v _AND_
+    unsigned short indent)
+{
+    if ((v->ai != NULL) && (v->ai->Print != NULL))
+        v->ai->Print (f, v->value);
+    else
+        fprintf (f," -- ERROR: malformed ANY value --");
+}
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-bits.c b/SecuritySNACCRuntime/c-lib/src/asn-bits.c
new file mode 100644
index 00000000..13109d6d
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-bits.c
@@ -0,0 +1,450 @@
+/*
+ * 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-lib/src/asn-bits.c - BER encode, decode, print and free routines for ASN.1 BIT STRING type
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-bits.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-bits.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:30  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/27 08:57:33  rj
+ * use memcmpeq that is defined in .../snacc.h to use either memcmp or bcmp.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/12/11  21:51:31  rj
+ * #include <string(s).h>
+ *
+ * Revision 1.2  1994/08/31  23:56:27  rj
+ * two unused variables removed.
+ *
+ * Revision 1.1  1994/08/28  09:45:50  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "str-stk.h"
+#include "asn-bits.h"
+
+static unsigned short int unusedBitsG;
+
+char numToHexCharTblG[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 BIT STRING
+ */
+AsnLen
+BEncAsnBits PARAMS ((b, data),
+    BUF_TYPE     b _AND_
+    AsnBits *data)
+{
+    AsnLen len;
+
+    len =  BEncAsnBitsContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
+    return len;
+}  /* BEncAsnInt */
+
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 BIT STRING
+ */
+void
+BDecAsnBits PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE   b _AND_
+    AsnBits    *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if (((tag =BDecTag (b, bytesDecoded, env)) !=
+         MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE)) &&
+        (tag != MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
+    {
+         Asn1Error ("BDecAsnBits: ERROR - wrong tag on BIT STRING.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecAsnBitsContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecAsnBits */
+
+
+
+/*
+ * Encodes the BIT STRING value (including the unused bits
+ * byte) to the given buffer.
+ */
+AsnLen
+BEncAsnBitsContent PARAMS ((b, bits),
+    BUF_TYPE b _AND_
+    AsnBits *bits)
+{
+    unsigned long int unusedBits;
+    unsigned long int byteLen;
+
+    if (bits->bitLen == 0)
+        byteLen = 0;
+    else
+        byteLen = ((bits->bitLen-1) / 8) + 1;
+
+    BufPutSegRvs (b, bits->bits, byteLen);
+    unusedBits = (bits->bitLen % 8);
+    if (unusedBits != 0)
+        unusedBits = 8 - unusedBits;
+    BufPutByteRvs (b, unusedBits);
+    return byteLen + 1;
+
+} /* BEncAsnBitsContent */
+
+
+/*
+ * Used when decoding to combine constructed pieces into one
+ * contiguous block.
+ * Fills string stack with references to the pieces of a
+ * construced bit string. sets unusedBitsG appropriately.
+ * and strStkG.totalByteLenG to bytelen needed to hold the bitstring
+ */
+static void
+FillBitStringStk PARAMS ((b, elmtLen0, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnLen elmtLen0 _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    unsigned long int refdLen;
+    unsigned long int totalRefdLen;
+    char *strPtr;
+    unsigned long int totalElmtsLen1 = 0;
+    unsigned long int tagId1;
+    unsigned long int elmtLen1;
+    unsigned long int lenToRef;
+
+    for (; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+        if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env);
+            break;
+        }
+
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+        if (tagId1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
+        {
+            /*
+             * primitive part of string, put references to piece (s) in
+             * str stack
+             */
+
+            /*
+             * get unused bits octet
+             */
+            if (unusedBitsG != 0)
+            {
+                /*
+                 *  whoa - only allowed non-octet aligned bits on
+                 *  on last piece of bits string
+                 */
+                Asn1Error ("FillBitStringStk: ERROR - a component of a constructed BIT STRING that is not the last has non-zero unused bits\n");
+                longjmp (env, -1);
+            }
+
+            if (elmtLen1 != 0)
+                unusedBitsG = BufGetByte (b);
+
+            totalRefdLen = 0;
+            lenToRef =elmtLen1-1; /* remove one octet for the unused bits oct*/
+            refdLen = lenToRef;
+            while (1)
+            {
+                strPtr = BufGetSeg (b, &refdLen);
+
+                PUSH_STR (strPtr, refdLen, env);
+                totalRefdLen += refdLen;
+                if (totalRefdLen == lenToRef)
+                    break; /* exit this while loop */
+
+                if (refdLen == 0) /* end of data */
+                {
+                    Asn1Error ("FillBitStringStk: ERROR - expecting more data\n");
+                    longjmp (env, -2);
+                }
+                refdLen = lenToRef - totalRefdLen;
+            }
+            totalElmtsLen1 += elmtLen1;
+        }
+
+
+        else if (tagId1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE))
+        {
+            /*
+             * constructed octets string embedding in this constructed
+             * octet string. decode it.
+             */
+            FillBitStringStk (b, elmtLen1, &totalElmtsLen1, env);
+        }
+        else  /* wrong tag */
+        {
+            Asn1Error ("FillBitStringStk: ERROR - decoded non-BIT STRING tag inside a constructed BIT STRING\n");
+            longjmp (env, -3);
+        }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+
+}  /* FillBitStringStk */
+
+
+/*
+ * Decodes a seq of universally tagged bits until either EOC is
+ * encountered or the given len decoded.  Returns them in a
+ * single concatenated bit string
+ */
+static void
+BDecConsAsnBits PARAMS ((b, len, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnLen len _AND_
+    AsnBits *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    char *bufCurr;
+    unsigned long int curr;
+
+    RESET_STR_STK();
+
+    /*
+     * decode each piece of the octet string, puting
+     * an entry in the octet/bit string stack for each
+     */
+    FillBitStringStk (b, len, bytesDecoded, env);
+
+    /* alloc single str long enough for combined bitstring */
+    result->bitLen = strStkG.totalByteLen*8 - unusedBitsG;
+
+    bufCurr = result->bits = Asn1Alloc (strStkG.totalByteLen);
+
+    /* copy bit string pieces (buffer refs) into single block */
+    for (curr = 0; curr < strStkG.nextFreeElmt; curr++)
+    {
+        memcpy (bufCurr, strStkG.stk[curr].str, strStkG.stk[curr].len);
+        bufCurr += strStkG.stk[curr].len;
+    }
+
+}  /* BDecConsAsnBits */
+
+/*
+ * Decodes the content of a BIT STRING (including the unused bits octet)
+ * Always returns a single contiguous bit string
+ */
+void
+BDecAsnBitsContent PARAMS ((b, tagId, len, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnTag tagId _AND_
+    AsnLen len _AND_
+    AsnBits *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    /*
+     * tagId is encoded tag shifted into long int.
+     * if CONS bit is set then constructed bit string
+     */
+    if (TAG_IS_CONS (tagId))
+        BDecConsAsnBits (b, len, result, bytesDecoded, env);
+    else /* primitive octet string */
+    {
+        (*bytesDecoded) += len;
+        len--;
+        result->bitLen = (len * 8) - (unsigned int)BufGetByte (b);
+        result->bits =  Asn1Alloc (len);
+        BufCopy (result->bits, b, len);
+        if (BufReadError (b))
+        {
+            Asn1Error ("BDecAsnBitsContent: ERROR - decoded past end of data\n");
+            longjmp (env, -4);
+        }
+    }
+}  /* BDecAsnBitsContent */
+
+
+
+/*
+ * Frees the string part of a BIT STRING
+ */
+void
+FreeAsnBits PARAMS ((v),
+    AsnBits *v)
+{
+    Asn1Free (v->bits);
+} /* FreeAsnBits  */
+
+
+/*
+ * Prints the contents of the given BIT STRING to the
+ * given file. indent is ignored.  Always uses ASN.1 Value Notaion
+ * Hex format. (Should be binary versions in some cases)
+ */
+void
+PrintAsnBits PARAMS ((f,v, indent),
+    FILE *f _AND_
+    AsnBits *v _AND_
+    unsigned short indent)
+{
+    int i;
+    unsigned long int octetLen;
+
+    if (v->bitLen == 0)
+        octetLen = 0;
+    else
+        octetLen = (v->bitLen-1)/8 +1;
+
+    fprintf (f,"'");
+    for (i = 0; i < octetLen; i++)
+        fprintf (f,"%c%c", TO_HEX (v->bits[i] >> 4), TO_HEX (v->bits[i]));
+    fprintf (f,"'H");
+
+} /* PrintAsnBits  */
+
+/*
+ * Returns TRUE if the given BIT STRINGs are identical.
+ * Otherwise returns FALSE.
+ */
+int
+AsnBitsEquiv PARAMS ((b1, b2),
+    AsnBits *b1 _AND_
+    AsnBits *b2)
+{
+    int octetsLessOne;
+    int octetBits;
+
+    if ((b1->bitLen == 0) && (b2->bitLen == 0))
+        return TRUE;
+
+    octetsLessOne = (b1->bitLen-1)/8;
+    octetBits = 7 - (b1->bitLen % 8);
+
+    /* trailing bits may not be significant  */
+    return b1->bitLen == b2->bitLen && !memcmpeq (b1->bits, b2->bits, octetsLessOne) && ((b1->bits[octetsLessOne] & (0xFF << octetBits)) == (b1->bits[octetsLessOne] & (0xFF << octetBits)));
+
+} /* AsnBitsEquiv */
+
+
+/*
+ * Set given bit to 1.  Most significant bit is bit 0, least significant
+ * is bit (v1->bitLen -1)
+ */
+void
+SetAsnBit PARAMS ((b1, bit),
+    AsnBits *b1 _AND_
+    unsigned long int bit)
+{
+    unsigned long int octet;
+    unsigned long int octetsBit;
+
+    if (bit < b1->bitLen)
+    {
+        octet = bit/8;
+        octetsBit = 7 - (bit % 8);/* bit zero is first/most sig bit in octet */
+        b1->bits[octet] |= 1 << octetsBit;
+    }
+}  /* SetAsnBit */
+
+
+/*
+ * Set given bit to 0.  Most significant bit is bit 0, least significant
+ * is bit (v1->bitLen -1)
+ */
+void
+ClrAsnBit PARAMS ((b1, bit),
+    AsnBits *b1 _AND_
+    unsigned long int bit)
+{
+    unsigned long int octet;
+    unsigned long int octetsBit;
+
+    if (bit <  b1->bitLen)
+    {
+        octet = bit/8;
+        octetsBit = 7 - (bit % 8);/* bit zero is first/most sig bit in octet */
+        b1->bits[octet] &= ~(1 << octetsBit);
+    }
+
+}  /* ClrAsnBit */
+
+
+/*
+ * Get given bit.  Most significant bit is bit 0, least significant
+ * is bit (v1->bitLen -1).  Returns TRUE if the bit is 1. Returns FALSE
+ * if the bit is 0.  if the bit is out of range then returns 0.
+ */
+int
+GetAsnBit PARAMS ((b1, bit),
+    AsnBits *b1 _AND_
+    unsigned long int bit)
+{
+    unsigned long int octet;
+    unsigned long int octetsBit;
+
+    if (bit < b1->bitLen)
+    {
+        octet = bit/8;
+        octetsBit = 7 - (bit % 8); /* bit zero is first/most sig bit in octet*/
+        return b1->bits[octet] & (1 << octetsBit);
+    }
+    return 0;
+}  /* AsnBits::GetBit */
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-bool.c b/SecuritySNACCRuntime/c-lib/src/asn-bool.c
new file mode 100644
index 00000000..c9ac838f
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-bool.c
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_bool.c
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-bool.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-bool.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:30  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 21:04:49  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:05:57  rj
+ * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens.
+ *
+ * Revision 1.1  1994/08/28  09:45:51  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-bool.h"
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 BOOLEAN
+ */
+AsnLen
+BEncAsnBool PARAMS ((b, data),
+    BUF_TYPE b _AND_
+    AsnBool *data)
+{
+    AsnLen len;
+
+    len =  BEncAsnBoolContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE);
+    return len;
+}  /* BEncAsnBool */
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 BOOLEAN
+ */
+void
+BDecAsnBool PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE   b _AND_
+    AsnBool    *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE))
+    {
+         Asn1Error ("BDecAsnBool: ERROR - wrong tag on BOOLEAN.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecAsnBoolContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecAsnBool */
+
+/*
+ * Encodes just the content of the given BOOLEAN value to the given buffer.
+ */
+AsnLen
+BEncAsnBoolContent PARAMS ((b, data),
+    BUF_TYPE  b _AND_
+    AsnBool  *data)
+{
+    BufPutByteRvs (b, *data ? 0xFF : 0);
+    return 1;
+}  /* BEncAsnBoolContent */
+
+/*
+ * Decodes just the content of an ASN.1 BOOLEAN from the given buffer.
+ * longjmps if there is a buffer reading problem
+ */
+void
+BDecAsnBoolContent PARAMS ((b, tagId, len, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnTag tagId _AND_
+    AsnLen len _AND_
+    AsnBool  *result _AND_
+    AsnLen  *bytesDecoded _AND_
+    jmp_buf env)
+{
+    if (len != 1)
+    {
+        Asn1Error ("BDecAsnBoolContent: ERROR - BOOLEAN length must be 1\n");
+        longjmp (env,-5);
+    }
+
+    (*bytesDecoded)++;
+    *result = (BufGetByte (b) != 0);
+
+    if (BufReadError (b))
+    {
+         Asn1Error ("BDecAsnBoolContent: ERROR - decoded past end of data\n");
+         longjmp (env, -6);
+    }
+}  /* BDecAsnBoolContent */
+
+/*
+ * Prints the given BOOLEAN to the given FILE * in ASN.1 Value notation.
+ * Does not use the indent.
+ */
+void
+PrintAsnBool PARAMS ((f, v, indent),
+    FILE *f _AND_
+    AsnBool *v _AND_
+    unsigned short int indent)
+{
+    if (*v)
+        fprintf (f, "TRUE");
+    else
+        fprintf (f, "FALSE");
+}
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-enum.c b/SecuritySNACCRuntime/c-lib/src/asn-enum.c
new file mode 100644
index 00000000..417daab1
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-enum.c
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_enum.c - routines for the ASN.1 ENUMERATED type
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-enum.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-enum.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:30  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 21:04:50  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  01:04:38  rj
+ * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens.
+ *
+ * Revision 1.1  1994/08/28  09:45:52  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-int.h"
+#include "asn-enum.h"
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 ENUMERATED
+ */
+AsnLen
+BEncAsnEnum PARAMS ((b, data),
+    BUF_TYPE     b _AND_
+    AsnEnum *data)
+{
+    AsnLen len;
+
+    len =  BEncAsnEnumContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, ENUM_TAG_CODE);
+    return len;
+}  /* BEncAsnEnum */
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 ENUMERATED
+ */
+void
+BDecAsnEnum PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE   b _AND_
+    AsnEnum    *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE))
+    {
+         Asn1Error ("BDecAsnInt: ERROR wrong tag on ENUMERATED.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecAsnEnumContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecAsnEnum */
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-int.c b/SecuritySNACCRuntime/c-lib/src/asn-int.c
new file mode 100644
index 00000000..93f4259b
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-int.c
@@ -0,0 +1,399 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_int.c - BER encode, decode, print and free routines for the
+ *             ASN.1 INTEGER type
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-int.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-int.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:30  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 21:04:51  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:05:05  rj
+ * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens.
+ *
+ * Revision 1.1  1994/08/28  09:45:53  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-int.h"
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 INTEGER
+ */
+AsnLen
+BEncAsnInt PARAMS ((b, data),
+    BUF_TYPE     b _AND_
+    AsnInt *data)
+{
+    AsnLen len;
+
+    len =  BEncAsnIntContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    return len;
+}  /* BEncAsnInt */
+
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 INTEGER
+ */
+void
+BDecAsnInt PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE   b _AND_
+    AsnInt    *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    {
+         Asn1Error ("BDecAsnInt: ERROR wrong tag on INTEGER.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecAsnIntContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecAsnInt */
+
+
+/*
+ * encodes signed long integer's contents
+ */
+AsnLen
+BEncAsnIntContent PARAMS ((b, data),
+    BUF_TYPE     b _AND_
+    AsnInt *data)
+{
+    int             len;
+    int             i;
+    unsigned long int   mask;
+    unsigned long int   dataCpy;
+
+#define INT_MASK (0x7f80 << ((sizeof(AsnInt) - 2) * 8))
+
+    dataCpy = *data;
+
+    /*
+     * calculate encoded length of the integer (content)
+     */
+    mask = INT_MASK;
+    if ((long int)dataCpy < 0)
+        for (len = sizeof (AsnInt); len > 1; --len)
+        {
+            if ((dataCpy & mask) == mask)
+                mask >>= 8;
+            else
+                break;
+        }
+    else
+        for (len = sizeof (AsnInt); len > 1; --len)
+        {
+            if ((dataCpy & mask) == 0)
+                mask >>= 8;
+            else
+                break;
+        }
+
+    /*
+     * write the BER integer
+     */
+    for (i = 0; i < len; i++)
+    {
+        BufPutByteRvs (b, dataCpy);
+        dataCpy >>= 8;
+    }
+
+    return len;
+
+}  /* BEncAsnIntContent */
+
+
+/*
+ * Decodes content of BER a INTEGER value.  The given tag is ignored.
+ */
+void
+BDecAsnIntContent PARAMS ((b, tagId, len, result, bytesDecoded, env),
+    BUF_TYPE   b _AND_
+    AsnTag     tagId _AND_
+    AsnLen     len _AND_
+    AsnInt    *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    int   i;
+    long int   retVal;
+    unsigned long int  byte;
+
+
+    if (len > sizeof (AsnInt))
+    {
+        Asn1Error ("BDecAsnIntContent: ERROR - integer to big to decode.\n");
+        longjmp (env, -7);
+    }
+
+    /*
+     * look at integer value
+     */
+    byte = (unsigned long int) BufGetByte (b);
+
+    if (byte & 0x80)   /* top bit of first byte is sign bit */
+        retVal = (-1 << 8) | byte;
+    else
+        retVal = byte;
+
+    /*
+     * write from buffer into long int
+     */
+    for (i = 1; i < len; i++)
+        retVal = (retVal << 8) | (unsigned long int)(BufGetByte (b));
+
+    if (BufReadError (b))
+    {
+        Asn1Error ("BDecAsnIntContent: ERROR - decoded past end of data \n");
+        longjmp (env, -8);
+    }
+    (*bytesDecoded) += len;
+
+    *result = retVal;
+
+}  /* BDecAsnIntContent */
+
+
+/*
+ * Prints the given integer to the given FILE * in Value Notation.
+ * indent is ignored.
+ */
+void
+PrintAsnInt PARAMS ((f, v, indent),
+    FILE *f _AND_
+    AsnInt *v _AND_
+    unsigned short int indent)
+{
+    fprintf (f,"%d", *v);
+}
+
+
+/*
+ * The following deal with UNSIGNED long ints.
+ * They do the same as the above routines for unsigned values.
+ *
+ * The compiler generated code does not call them. (It should
+ * based on subtype info but it does not).
+ */
+
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 INTEGER
+ */
+AsnLen
+BEncUAsnInt PARAMS ((b, data),
+    BUF_TYPE b _AND_
+    UAsnInt *data)
+{
+    AsnLen len;
+
+    len =  BEncUAsnIntContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
+    return len;
+}  /* BEncUAsnInt */
+
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 INTEGER
+ */
+void
+BDecUAsnInt PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    UAsnInt *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    {
+         Asn1Error ("BDecAsnInt: ERROR wrong tag on INTGER.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecUAsnIntContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecUAsnInt */
+
+
+/*
+ * encodes unsigned long integer.  This allows you to correctly
+ * handle unsiged values that used the most significant (sign) bit.
+ */
+AsnLen
+BEncUAsnIntContent PARAMS ((b, data),
+    BUF_TYPE b _AND_
+    UAsnInt *data)
+{
+    int             len;
+    int             i;
+    unsigned long int   mask;
+    unsigned long int   dataCpy;
+
+    dataCpy = *data;
+
+    /*
+     * calculate encoded length of the integer (content)
+     */
+    mask = INT_MASK;
+    if ((long int)dataCpy < 0)
+    {
+        /*write integer as normal (remember writing in reverse) */
+        for (i = 0; i < sizeof (UAsnInt); i++)
+        {
+            BufPutByteRvs (b, dataCpy);
+            dataCpy >>= 8;
+        }
+        /*
+         * write zero byte at beginning of int, since high bit
+         * is set and need to differentiate between sign
+         * bit and high bit in unsigned case.
+         * (this code follows the prev for loop since writing
+         *  in reverse)
+         */
+        BufPutByteRvs (b, 0);
+
+        return sizeof (UAsnInt)+1;
+    }
+    else
+    {
+        for (len = sizeof (UAsnInt); len > 1; --len)
+        {
+            if ((dataCpy & mask) == 0)
+                mask >>= 8;
+            else
+                break;
+        }
+
+        /* write the BER integer */
+        for (i = 0; i < len; i++)
+        {
+            BufPutByteRvs (b, dataCpy);
+            dataCpy >>= 8;
+        }
+        return len;
+    }
+
+}  /* BEncUAsnIntContent */
+
+
+/*
+ * decode integer portion - no tag or length expected or decoded
+ * assumes unsigned integer - This routine is useful for
+ * integer subtyped to > 0 eg Guage ::= INTEGER (0..4294967295)
+ */
+void
+BDecUAsnIntContent PARAMS ((b, tag, len, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnTag   tag _AND_
+    AsnLen   len _AND_
+    UAsnInt *result _AND_
+    AsnLen  *bytesDecoded _AND_
+    jmp_buf  env)
+{
+    int   i;
+    unsigned long int retVal;
+
+    retVal =  (unsigned long int) BufGetByte (b);
+
+    if (len > (sizeof (UAsnInt)+1))
+    {
+        Asn1Error ("BDecUAsnIntContent: ERROR - integer to big to decode.\n");
+        longjmp (env, -9);
+    }
+    else if (retVal & 0x80)   /* top bit of first byte is sign bit */
+    {
+        Asn1Error ("BDecUAsnIntContent: ERROR - integer is negative.\n");
+        longjmp (env, -10);
+    }
+    else if ((len == (sizeof (UAsnInt)+1)) && (retVal != 0))
+    {
+        /*
+         * first octet must be zero 5 octets long - extra 0 octet
+         * at beginning is only used for value > 0 that need the
+         * high bit
+         */
+        Asn1Error ("BDecUAsnIntContent: ERROR - integer is negative.\n");
+        longjmp (env, -11);
+    }
+
+    /*
+     * write from buffer into long int
+     */
+    for (i = 1; i < len; i++)
+        retVal = (retVal << 8) | (unsigned long int)(BufGetByte (b));
+
+    if (BufReadError (b))
+    {
+        Asn1Error ("BDecUIntegerContent: ERROR - decoded past end of data\n");
+        longjmp (env, -12);
+    }
+    (*bytesDecoded) += len;
+
+    *result = retVal;
+
+}  /* BDecUAsnIntContent */
+
+
+void
+PrintUAsnInt PARAMS ((f, v, indent),
+    FILE *f _AND_
+    UAsnInt *v _AND_
+    unsigned short int indent)
+{
+    fprintf (f, "%u", *v);
+}
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-len.c b/SecuritySNACCRuntime/c-lib/src/asn-len.c
new file mode 100644
index 00000000..e4723679
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-len.c
@@ -0,0 +1,233 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_len.c - BER encode, decode and utilities for ASN.1 lengths.
+ *
+ *   indefinite lens are representd by the highest AsnLen
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-len.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-len.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:30  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/27 08:58:36  rj
+ * merged PeekEoc(), a function used only by the type table code.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:45:54  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+
+
+AsnLen
+BEncDefLen PARAMS ((b, len),
+    BUF_TYPE b _AND_
+    AsnLen len)
+{
+    /*
+     * unrolled for efficiency
+     * check each possibitlity of the 4 byte integer
+     */
+    if (len < 128)
+    {
+        BufPutByteRvs (b, len);
+        return 1;
+    }
+    else if (len < 256)
+    {
+        BufPutByteRvs (b, len);
+        BufPutByteRvs (b, 0x81);
+        return 2;
+    }
+    else if (len < 65536)
+    {
+        BufPutByteRvs (b, len);
+        BufPutByteRvs (b, len >> 8);
+        BufPutByteRvs (b, 0x82);
+        return 3;
+    }
+    else if (len < 16777126)
+    {
+        BufPutByteRvs (b, len);
+        BufPutByteRvs (b, len >> 8);
+        BufPutByteRvs (b, len >> 16);
+        BufPutByteRvs (b, 0x83);
+        return 4;
+    }
+    else
+    {
+        BufPutByteRvs (b, len);
+        BufPutByteRvs (b, len >> 8);
+        BufPutByteRvs (b, len >> 16);
+        BufPutByteRvs (b, len >> 24);
+        BufPutByteRvs (b, 0x84);
+        return 5;
+    }
+} /*  BEncDefLen */
+
+
+/*
+ * non unrolled version
+ */
+AsnLen
+BEncDefLen2 PARAMS ((b, len),
+    BUF_TYPE  b _AND_
+    long int  len)
+{
+    int i;
+    unsigned long int j;
+
+    if (len < 128)
+    {
+        BufPutByteRvs (b, len);
+        return 1;
+    }
+    else
+    {
+        for (i = 0, j = len; j > 0; j >>= 8, i++)
+            BufPutByteRvs (b, j);
+
+        BufPutByteRvs (b, 0x80 | i);
+        return i + 1;
+    }
+
+} /*  BEncDefLen2 */
+
+
+/*
+ * decodes and returns an ASN.1 length
+ */
+AsnLen
+BDecLen PARAMS ((b, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    unsigned long int  *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnLen len;
+    AsnLen byte;
+    int lenBytes;
+
+    byte = (unsigned long int) BufGetByte (b);
+
+    if (BufReadError (b))
+    {
+        Asn1Error ("BDecLen: ERROR - decoded past end of data\n");
+        longjmp (env, -13);
+    }
+
+    (*bytesDecoded)++;
+    if (byte < 128)   /* short length */
+        return byte;
+
+    else if (byte == (AsnLen) 0x080)  /* indef len indicator */
+        return INDEFINITE_LEN;
+
+    else  /* long len form */
+    {
+        /*
+         * strip high bit to get # bytes left in len
+         */
+        lenBytes = byte & (AsnLen) 0x7f;
+
+        if (lenBytes > sizeof (AsnLen))
+        {
+            Asn1Error ("BDecLen: ERROR - length overflow\n");
+            longjmp (env, -14);
+        }
+
+        (*bytesDecoded) += lenBytes;
+
+        for (len = 0; lenBytes > 0; lenBytes--)
+            len = (len << 8) | (AsnLen) BufGetByte (b);
+
+
+        if (BufReadError (b))
+        {
+            Asn1Error ("BDecLen: ERROR - decoded past end of data\n");
+            longjmp (env, -15);
+        }
+
+        return len;
+    }
+    /* not reached */
+} /* BDecLen */
+
+
+/* MACRO
+AsnLen
+BEncEoc PARAMS ((b),
+    BUF_TYPE b)
+{
+    BufPutByteRvs (b, 0);
+    BufPutByteRvs (b, 0);
+    return 2;
+}   BEncEoc */
+
+/*
+ * Decodes an End of Contents (EOC) marker from the given buffer.
+ * Flags and error if the octets are non-zero or if a read error
+ * occurs.  Increments bytesDecoded by the length of the EOC marker.
+ */
+void
+BDecEoc PARAMS ((b, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    if ((BufGetByte (b) != 0) || (BufGetByte (b) != 0) || BufReadError (b))
+    {
+        Asn1Error ("BDecEoc: ERROR - non zero byte in EOC or end of data reached\n");
+        longjmp (env, -16);
+    }
+    (*bytesDecoded) += 2;
+
+}  /* BDecEoc */
+
+#if TTBL
+/* returns true if the next tag is actually and EOC */
+int PeekEoc PARAMS ((b),
+    BUF_TYPE b)
+{
+    return BufPeekByte (b) == 0;
+}  /* PeekEoc */
+#endif
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-list.c b/SecuritySNACCRuntime/c-lib/src/asn-list.c
new file mode 100644
index 00000000..705af3c5
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-list.c
@@ -0,0 +1,486 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_list.c  - borrowed from Murray Goldberg
+ *
+ * the following routines implement the list data structure
+ *
+ * Copyright (C) 1992 the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-list.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-list.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:30  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/27 08:59:36  rj
+ * merged GetAsnListElmt(), a function used only by the type table code.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:45:55  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-list.h"
+
+/* remove the entire list and all its nodes (not the actual list data elmts) */
+/* this is set up for the snace compiler */
+void
+AsnListFree PARAMS ((list),
+    AsnList *list)
+{
+    AsnListNode *node, *next;
+
+    node = list->first;
+    while (node)
+    {
+	next = node->next;
+	Asn1Free (node);
+	node = next;
+    }
+
+    Asn1Free (list);
+}  /* AsnListFree */
+
+
+/*
+ * this routine removes the current node from the list. After removal the
+ * current pointer will point to the next node in line, or NULL if the
+ * removed item was at the tail of the list.
+ */
+void
+AsnListRemove PARAMS ((list),
+    AsnList *list)
+{
+    AsnListNode *node;
+
+    if (list->curr)
+    {
+	if (list->curr->next)
+	    list->curr->next->prev = list->curr->prev;
+	else
+	    list->last = list->curr->prev;
+
+	if (list->curr->prev)
+	    list->curr->prev->next = list->curr->next;
+	else
+	    list->first = list->curr->next;
+
+	node       = list->curr;
+
+	list->curr = list->curr->next;
+	list->count--;
+
+	Asn1Free (node);
+    }
+}
+
+/*
+ * this creates a new node after the current node and returns the
+ * address of the memory allocated for data. The current pointer is changed
+ * to point to the newly added node in the list. If the current pointer is
+ * initially off the list then this operation fails.
+ */
+void*
+AsnListAdd PARAMS ((list),
+    AsnList *list)
+{
+    AsnListNode *newNode;
+    void      *dataAddr;
+
+    if (list->curr)
+    {
+	newNode  = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize);
+	dataAddr = (void *) &(newNode->data);
+
+	newNode->next = list->curr->next;
+	newNode->prev = list->curr;
+	if (list->curr->next)
+	    list->curr->next->prev = newNode;
+	else
+	    list->last = newNode;
+	list->curr->next = newNode;
+
+	list->curr = newNode;
+	list->count++;
+    }
+
+    else
+	dataAddr = NULL;
+
+    return dataAddr;
+}
+
+/*
+ * this creates a new node before the current node and returns the
+ * address of the memory allocated for data. The current pointer is changed
+ * to point to the newly added node in the list. If the current pointer is
+ * initially off the list then this operation fails.
+ */
+void*
+AsnListInsert PARAMS ((list),
+    AsnList *list)
+{
+    AsnListNode *newNode;
+    void      *dataAddr;
+
+    if (list->curr)
+    {
+	newNode  = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize);
+	dataAddr = (void *) &(newNode->data);
+
+	newNode->next = list->curr;
+	newNode->prev = list->curr->prev;
+	if (list->curr->prev)
+	    list->curr->prev->next = newNode;
+	else
+	    list->first  = newNode;
+	list->curr->prev = newNode;
+
+	list->curr = newNode;
+	list->count++;
+    }
+
+    else
+	dataAddr = NULL;
+
+    return dataAddr;
+}
+
+
+void
+AsnListInit PARAMS ((list, dataSize),
+    AsnList *list _AND_
+    int dataSize)
+{
+    list->first = list->last = list->curr = NULL;
+    list->count = 0;
+    list->dataSize = dataSize;
+
+}  /* AsnListInit */
+
+
+AsnList*
+AsnListNew PARAMS ((dataSize),
+    int dataSize)
+{
+    AsnList *list;
+
+    list = (AsnList *) Asn1Alloc (sizeof (AsnList));
+    list->first = list->last = list->curr = NULL;
+    list->count = 0;
+    list->dataSize = dataSize;
+
+    return list;
+}
+
+/*
+ * backs up the current pointer by one and returns the data address of the new
+ * current node. If the current pointer is off the list, the new current node
+ * will be the last node of the list (unless the list is empty).
+ */
+void*
+AsnListPrev PARAMS ((list),
+    AsnList *list)
+{
+    void *retVal;
+
+    if (list->curr == NULL)
+	list->curr = list->last;
+    else
+	list->curr = list->curr->prev;
+
+    if (list->curr == NULL)
+	retVal = NULL;
+    else
+	retVal = (void *) &(list->curr->data);
+
+    return retVal;
+}
+
+/*
+ * advances the current pointer by one and returns the data address of the new
+ * current node. If the current pointer is off the list, the new current node
+ * will be the first node of the list (unless the list is empty).
+ */
+void*
+AsnListNext PARAMS ((list),
+    AsnList *list)
+{
+    void *retVal;
+
+    if (list->curr == NULL)
+	list->curr = list->first;
+    else
+	list->curr = list->curr->next;
+
+    if (list->curr == NULL)
+	retVal = NULL;
+    else
+	retVal = (void *) &(list->curr->data);
+
+    return retVal;
+}
+
+/*
+ * returns the data address of the last node (if there is one) and sets the
+ * current pointer to this node.
+ */
+void*
+AsnListLast PARAMS ((list),
+    AsnList *list)
+{
+    void *retVal;
+
+    list->curr = list->last;
+
+    if (list->curr == NULL)
+	retVal = NULL;
+    else
+	retVal = (void *) &(list->curr->data);
+
+    return retVal;
+}
+
+/*
+ * returns the data address of the first node (if there is one) and sets the
+ * current pointer to this node.
+ */
+void*
+AsnListFirst PARAMS ((list),
+    AsnList *list)
+{
+    void *retVal;
+
+    list->curr = list->first;
+
+    if (list->curr == NULL)
+	retVal = NULL;
+    else
+	retVal = (void *) &(list->curr->data);
+
+    return retVal;
+}
+
+/*
+ * this creates a new node at the beginning of the list and returns the
+ * address of the memory allocated for data. The current pointer is changed
+ * to point to the newly added node in the list.
+ */
+void*
+AsnListPrepend PARAMS ((list),
+    AsnList *list)
+{
+    AsnListNode *newNode;
+    void      *dataAddr;
+
+    newNode  = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize);
+    dataAddr = (void *) &(newNode->data);
+
+    newNode->prev = NULL;
+
+    if (list->first == NULL)
+    {
+	newNode->next = NULL;
+	list->first   = list->last = newNode;
+    }
+    else
+    {
+	newNode->next     = list->first;
+	list->first->prev = newNode;
+	list->first       = newNode;
+    }
+
+    list->curr = newNode;
+    list->count++;
+
+    return dataAddr;
+}
+
+/*
+ * this creates a new node at the end of the list and returns the
+ * address of the memory allocated for data. The current pointer is changed
+ * to point to the newly added node in the list.
+ */
+void*
+AsnListAppend PARAMS ((list),
+    AsnList *list)
+{
+    AsnListNode *newNode;
+    void      *dataAddr;
+
+    newNode  = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize);
+    dataAddr = (void *) &(newNode->data);
+
+    newNode->next = NULL;
+
+    if (list->last == NULL)
+    {
+        newNode->prev = NULL;
+        list->first   = list->last = newNode;
+    }
+    else
+    {
+        newNode->prev     = list->last;
+        list->last->next  = newNode;
+        list->last        = newNode;
+    }
+
+    list->curr = newNode;
+    list->count++;
+
+    return dataAddr;
+}
+
+void*
+AsnListCurr PARAMS ((list),
+    AsnList *list)
+{
+    void *retVal;
+
+    if (list->curr)
+	retVal = (void *) &(list->curr->data);
+    else
+	retVal = NULL;
+
+    return retVal;
+}
+
+int
+AsnListCount PARAMS ((list),
+    AsnList *list)
+{
+    return list->count;
+}
+
+
+AsnList*
+AsnListConcat PARAMS ((l1,l2),
+    AsnList *l1 _AND_
+    AsnList *l2)
+{
+    if (l2->count == 0)
+        return l1;
+
+    if (l1->count == 0)
+    {
+        l1->count = l2->count;
+        l1->last = l2->last;
+        l1->first = l2->first;
+        l1->curr = l1->first;
+    }
+    else
+    {
+        l1->count += l2->count;
+        l1->last->next = l2->first;
+        l2->first->prev = l1->last;
+        l1->last = l2->last;
+    }
+
+    return l1;
+}
+
+
+/*
+ * Returns the index (starting a 0 for the first elmt)
+ * of the given elmt in the given list
+ * returns -1 if the elmt is not in the list
+ * Assumes that the list node contains a single pointer
+ */
+long int
+GetAsnListElmtIndex PARAMS ((elmt, list),
+    void *elmt _AND_
+    AsnList *list)
+{
+    void *tmp;
+    void *tmpElmt;
+    long int index;
+
+    index = 0;
+    tmp = (void*) CURR_LIST_NODE (list);
+    FOR_EACH_LIST_ELMT (tmpElmt, list)
+    {
+        if (tmpElmt == elmt)
+        {
+            SET_CURR_LIST_NODE (list, tmp);
+            return index;
+        }
+        else
+            index++;
+    }
+
+    SET_CURR_LIST_NODE (list, tmp);
+    return -1;
+
+}  /* GetAsnListElmtIndex */
+
+
+#if TTBL
+/*
+ * Returns the element with the given index.
+ * indexes start a 0 for the first elmt.
+ * returns NULL if the index is too large.
+ * Assumes that the list node contains a single pointer.
+ */
+void*
+GetAsnListElmt PARAMS ((list, index),
+    AsnList *list _AND_
+    unsigned int index)
+{
+    void *tmp;
+    void *tmpElmt;
+    long int currIndex;
+
+    if (index > LIST_COUNT (list))
+        return NULL;
+
+    currIndex = 0;
+    tmp = (void*) CURR_LIST_NODE (list);
+    FOR_EACH_LIST_ELMT (tmpElmt, list)
+    {
+        if (currIndex == index)
+        {
+            SET_CURR_LIST_NODE (list, tmp);
+            return tmpElmt;
+        }
+        currIndex++;
+    }
+    SET_CURR_LIST_NODE (list, tmp);
+    return NULL;
+
+}  /* GetAsnListElmt */
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-null.c b/SecuritySNACCRuntime/c-lib/src/asn-null.c
new file mode 100644
index 00000000..259f382c
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-null.c
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_null.c - BER encode, decode, print and free routines for the
+ *              ASN.1 NULL type.
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-null.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-null.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:31  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 21:04:52  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:06:08  rj
+ * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens.
+ *
+ * Revision 1.1  1994/08/28  09:45:57  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-null.h"
+
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 NULL
+ */
+AsnLen
+BEncAsnNull PARAMS ((b, data),
+    BUF_TYPE     b _AND_
+    AsnNull *data)
+{
+    AsnLen len;
+
+    len =  BEncAsnNullContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, NULLTYPE_TAG_CODE);
+    return len;
+}  /* BEncAsnNull */
+
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 NULL
+ */
+void
+BDecAsnNull PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnNull *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE))
+    {
+         Asn1Error ("BDecAsnNull: ERROR wrong tag on NULL.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecAsnNullContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecAsnNull */
+
+
+void
+BDecAsnNullContent PARAMS ((b, tagId, len, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnTag tagId _AND_
+    AsnLen len _AND_
+    AsnNull *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    if (len != 0)
+    {
+        Asn1Error ("BDecAsnNullContent: ERROR - NULL type's len must be 0\n");
+        longjmp (env, -17);
+    }
+}  /* BDecAsnNullContent */
+
+/*
+ * Prints the NULL value to the given FILE * in Value Notation.
+ * ignores the indent.
+ */
+void
+PrintAsnNull PARAMS ((f,v, indent),
+    FILE *f _AND_
+    AsnNull *v _AND_
+    unsigned short int indent)
+{
+    fprintf (f, "NULL");
+}
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-octs.c b/SecuritySNACCRuntime/c-lib/src/asn-octs.c
new file mode 100644
index 00000000..0dacbb2c
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-octs.c
@@ -0,0 +1,338 @@
+/*
+ * 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-lib/src/asn-octs.c - BER encode, decode, print and free routines for the ASN.1 OCTET STRING type.
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-octs.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-octs.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:31  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/27 09:00:32  rj
+ * use memcmpeq that is defined in .../snacc.h to use either memcmp or bcmp.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:06:15  rj
+ * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens.
+ *
+ * Revision 1.1  1994/08/28  09:45:58  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <ctype.h>
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "str-stk.h"
+#include "asn-bits.h" /* for TO_HEX macro */
+#include "asn-octs.h"
+
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 OCTET STRING
+ */
+AsnLen
+BEncAsnOcts PARAMS ((b, data),
+    BUF_TYPE     b _AND_
+    AsnOcts *data)
+{
+    AsnLen len;
+
+    len =  BEncAsnOctsContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
+    return len;
+}  /* BEncAsnOcts */
+
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 OCTET STRING
+ */
+void
+BDecAsnOcts PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE   b _AND_
+    AsnOcts    *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+    {
+         Asn1Error ("BDecAsnOcts: ERROR - wrong tag on OCTET STRING.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecAsnOctsContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecAsnOcts */
+
+/*
+ * BER encodes just the content of an OCTET STRING.
+ */
+AsnLen
+BEncAsnOctsContent PARAMS ((b, o),
+    BUF_TYPE b _AND_
+    AsnOcts *o)
+{
+    BufPutSegRvs (b, o->octs, o->octetLen);
+    return o->octetLen;
+}  /* BEncAsnOctsContent */
+
+
+
+/*
+ * Used for decoding constructed OCTET STRING values into
+ * a contiguous local rep.
+ * fills string stack with references to the pieces of a
+ * construced octet string
+ */
+static void
+FillOctetStringStk PARAMS ((b, elmtLen0, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnLen elmtLen0 _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    unsigned long int refdLen;
+    unsigned long int totalRefdLen;
+    char *strPtr;
+    unsigned long int totalElmtsLen1 = 0;
+    unsigned long int tagId1;
+    unsigned long int elmtLen1;
+
+    for (; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+        if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env);
+            break;
+        }
+
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+        if (tagId1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
+        {
+            /*
+             * primitive part of string, put references to piece (s) in
+             * str stack
+             */
+            totalRefdLen = 0;
+            refdLen = elmtLen1;
+            while (1)
+            {
+                strPtr = BufGetSeg (b, &refdLen);
+
+                PUSH_STR (strPtr, refdLen, env);
+                totalRefdLen += refdLen;
+                if (totalRefdLen == elmtLen1)
+                    break; /* exit this while loop */
+
+                if (refdLen == 0) /* end of data */
+                {
+                    Asn1Error ("BDecConsOctetString: ERROR - attempt to decode past end of data\n");
+                    longjmp (env, -18);
+                }
+                refdLen = elmtLen1 - totalRefdLen;
+            }
+            totalElmtsLen1 += elmtLen1;
+        }
+
+
+        else if (tagId1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE))
+        {
+            /*
+             * constructed octets string embedding in this constructed
+             * octet string. decode it.
+             */
+            FillOctetStringStk (b, elmtLen1, &totalElmtsLen1, env);
+        }
+        else  /* wrong tag */
+        {
+            Asn1Error ("BDecConsOctetString: ERROR - decoded non-OCTET STRING tag inside a constructed OCTET STRING\n");
+            longjmp (env, -19);
+        }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+
+}  /* FillOctetStringStk */
+
+
+/*
+ * Decodes a seq of universally tagged octets strings until either EOC is
+ * encountered or the given len is decoded.  Merges them into a single
+ * string. puts a NULL terminator on the string but does not include
+ * this in the length.
+ */
+static void
+BDecConsAsnOcts PARAMS ((b, len, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnLen len _AND_
+    AsnOcts *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    char *bufCurr;
+    unsigned long int curr;
+
+    RESET_STR_STK();
+
+    /*
+     * decode each piece of the octet string, puting
+     * an entry in the octet string stack for each
+     */
+    FillOctetStringStk (b, len, bytesDecoded, env);
+
+    result->octetLen = strStkG.totalByteLen;
+
+    /* alloc str for all octs pieces with extra byte for null terminator */
+    bufCurr = result->octs = Asn1Alloc (strStkG.totalByteLen +1);
+
+    /* copy octet str pieces into single blk */
+    for (curr = 0; curr < strStkG.nextFreeElmt; curr++)
+    {
+        memcpy (bufCurr, strStkG.stk[curr].str, strStkG.stk[curr].len);
+        bufCurr += strStkG.stk[curr].len;
+    }
+
+    /* add null terminator - this is not included in the str's len */
+    *bufCurr = '\0';
+
+}  /* BDecConsAsnOcts */
+
+/*
+ * Decodes the content of a BER OCTET STRING value
+ */
+void
+BDecAsnOctsContent PARAMS ((b, tagId, len, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnTag tagId _AND_
+    AsnLen len _AND_
+    AsnOcts *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    /*
+     * tagId is encoded tag shifted into long int.
+     * if CONS bit is set then constructed octet string
+     */
+    if (TAG_IS_CONS (tagId))
+        BDecConsAsnOcts (b, len, result, bytesDecoded, env);
+
+    else /* primitive octet string */
+    {
+        result->octetLen = len;
+        result->octs =  Asn1Alloc (len+1);
+        BufCopy (result->octs, b, len);
+
+        if (BufReadError (b))
+        {
+            Asn1Error ("BDecOctetString: ERROR - decoded past end of data\n");
+            longjmp (env, -20);
+        }
+
+        /* add null terminator - this is not included in the str's len */
+        result->octs[len] = '\0';
+        (*bytesDecoded) += len;
+    }
+}  /* BDecAsnOctsContent */
+
+
+/*
+ * Frees the string part of the given OCTET STRING
+ */
+void
+FreeAsnOcts PARAMS ((v),
+    AsnOcts *v)
+{
+    Asn1Free (v->octs);
+}  /* FreeAsnOcts */
+
+/*
+ * Prints the given OCTET STRING value to the given FILE * in ASN.1
+ * Value Notation.  Since the value notation uses the hard to read
+ * hex format, the ASCII version is included in an ASN.1 comment.
+ */
+void
+PrintAsnOcts PARAMS ((f,v, indent),
+    FILE *f _AND_
+    AsnOcts *v _AND_
+    unsigned short indent)
+{
+    int i;
+
+    /* print hstring value */
+    fprintf (f,"'");
+
+    for (i = 0; i < v->octetLen; i++)
+	  fprintf (f,"%c%c", TO_HEX (v->octs[i] >> 4), TO_HEX (v->octs[i]));
+
+    fprintf (f,"'H");
+
+    /* show printable chars in comment */
+    fprintf (f,"  -- \"");
+
+    for (i = 0; i < v->octetLen; i++)
+    {
+	if (isprint (v->octs[i]))
+	    fprintf (f,"%c", v->octs[i]);
+	else
+	  fprintf (f,".");
+    }
+    fprintf (f,"\" --");
+}
+
+
+/*
+ * Returns TRUE if the given OCTET STRING values are identical.
+ * Returns FALSE otherwise.
+ */
+int
+AsnOctsEquiv PARAMS ((o1, o2),
+    AsnOcts *o1 _AND_
+    AsnOcts *o2)
+{
+    return o1->octetLen == o2->octetLen && !memcmpeq (o1->octs, o2->octs, o1->octetLen);
+} /* AsnOctsEquiv */
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-oid.c b/SecuritySNACCRuntime/c-lib/src/asn-oid.c
new file mode 100644
index 00000000..ce0675f1
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-oid.c
@@ -0,0 +1,348 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_oid.c - BER encode, decode, print and free routines for the
+ *             ASN.1 OBJECT IDENTIFIER type.
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-oid.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-oid.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:31  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 21:04:53  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:06:21  rj
+ * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens.
+ *
+ * Revision 1.1  1994/08/28  09:45:59  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-octs.h"
+#include "asn-oid.h"
+
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 OBJECT ID
+ */
+AsnLen
+BEncAsnOid PARAMS ((b, data),
+    BUF_TYPE     b _AND_
+    AsnOid *data)
+{
+    AsnLen len;
+
+    len =  BEncAsnOidContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
+    return len;
+}  /* BEncAsnOid */
+
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 OBJECT ID
+ */
+void
+BDecAsnOid PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE   b _AND_
+    AsnOid    *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
+    {
+         Asn1Error ("BDecAsnOid: ERROR - wrong tag on OBJECT IDENTIFIER.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecAsnOidContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecAsnOid */
+
+
+
+/*
+ * Decodes just the content of the OID.
+ * AsnOid is handled the same as a primtive octet string
+ */
+void
+BDecAsnOidContent PARAMS ((b, tagId, len, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnTag tagId _AND_
+    AsnLen len _AND_
+    AsnOid *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    result->octetLen = len;
+    result->octs =  Asn1Alloc (len);
+    BufCopy (result->octs, b, len);
+    if (BufReadError (b))
+    {
+         Asn1Error ("BDecAsnOidContent: ERROR - decoded past end of data\n");
+         longjmp (env, -21);
+    }
+    (*bytesDecoded) += len;
+}  /* BDecAsnOidContent */
+
+
+
+/*
+ * Prints the given OID to the given FILE * in ASN.1 Value Notation.
+ * Since the internal rep of an OID is 'encoded', this routine
+ * decodes each individual arc number to print it.
+ */
+void
+PrintAsnOid PARAMS ((f,v, indent),
+    FILE *f _AND_
+    AsnOid *v _AND_
+    unsigned short int indent)
+{
+    unsigned short int firstArcNum;
+    unsigned long int arcNum;
+    int i;
+
+    fprintf (f,"{");
+
+    /* un-munge first two arc numbers */
+    for (arcNum = 0, i=0; (i < v->octetLen) && (v->octs[i] & 0x80);i++)
+        arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+
+    arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+    i++;
+    firstArcNum = arcNum/40;
+    if (firstArcNum > 2)
+        firstArcNum = 2;
+
+    fprintf (f,"%u %u", firstArcNum, arcNum - (firstArcNum * 40));
+
+    for (; i < v->octetLen; )
+    {
+        for (arcNum = 0; (i < v->octetLen) && (v->octs[i] & 0x80);i++)
+            arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+
+        arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+        i++;
+        fprintf (f," %u", arcNum);
+    }
+    fprintf (f,"}");
+
+} /* PrintAsnOid */
+
+
+
+/*
+ * given an OID, figures out the length for the encoded version
+ */
+AsnLen
+EncodedOidLen PARAMS ((oid),
+    OID *oid)
+{
+    AsnLen totalLen;
+    unsigned long headArcNum;
+    unsigned long tmpArcNum;
+    OID *tmpOid;
+
+    /*
+     * oid must have at least 2 elmts
+     */
+    if (oid->next == NULL)
+       return 0;
+
+    headArcNum = (oid->arcNum * 40) + oid->next->arcNum;
+
+    /*
+     * figure out total encoded length of oid
+     */
+    tmpArcNum = headArcNum;
+    for (totalLen = 1; (tmpArcNum >>= 7) != 0; totalLen++)
+	;
+    for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next)
+    {
+        totalLen++;
+        tmpArcNum = tmpOid->arcNum;
+        for (; (tmpArcNum >>= 7) != 0; totalLen++)
+	    ;
+    }
+
+    return totalLen;
+
+}  /* EncodedOidLen */
+
+
+/*
+ * given an oid list and a pre-allocated ENC_OID
+ * (use EncodedOidLen to figure out byte length needed)
+ * fills the ENC_OID with a BER encoded version
+ * of the oid.
+ */
+void
+BuildEncodedOid PARAMS ((oid, result),
+    OID *oid _AND_
+    AsnOid *result)
+{
+    unsigned long len;
+    unsigned long headArcNum;
+    unsigned long tmpArcNum;
+    char         *buf;
+    int           i;
+    OID          *tmpOid;
+
+    buf = result->octs;
+
+    /*
+     * oid must have at least 2 elmts
+     */
+    if (oid->next == NULL)
+       return;
+    /*
+     * munge together first two arcNum
+     * note first arcnum must be <= 2
+     * and second must be < 39 if first = 0 or 1
+     * see (X.209) for ref to this stupidity
+     */
+    headArcNum = (oid->arcNum * 40) + oid->next->arcNum;
+
+    tmpArcNum = headArcNum;
+
+    /*
+     * calc # bytes needed for head arc num
+     */
+    for (len = 0; (tmpArcNum >>= 7) != 0; len++)
+	;
+
+    /*
+     * write more signifcant bytes (if any) of head arc num
+     * with 'more' bit set
+     */
+    for (i=0; i < len; i++)
+        *(buf++) = 0x80 | (headArcNum >> ((len-i)*7));
+
+    /*
+     * write least significant byte of head arc num
+     */
+    *(buf++) = 0x7f & headArcNum;
+
+
+    /*
+     * write following arc nums, if any
+     */
+    for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next)
+    {
+        /*
+         * figure out encoded length -1 of this arcNum
+         */
+        tmpArcNum = tmpOid->arcNum;
+        for (len = 0; (tmpArcNum >>= 7) != 0; len++)
+	    ;
+
+
+        /*
+         * write more signifcant bytes (if any)
+         * with 'more' bit set
+         */
+        for (i=0; i < len; i++)
+            *(buf++) = 0x80 | (tmpOid->arcNum >> ((len-i)*7));
+
+        /*
+         * write least significant byte
+         */
+        *(buf++) = 0x7f & tmpOid->arcNum;
+    }
+
+} /* BuildEncodedOid */
+
+
+/*
+ * convert an AsnOid into an OID (linked list)
+ * NOT RECOMMENDED for use in protocol implementations
+ */
+void
+UnbuildEncodedOid PARAMS ((eoid, result),
+    AsnOid *eoid _AND_
+    OID **result)
+{
+    OID **nextOid;
+    OID *headOid;
+    int arcNum;
+    int i;
+    int firstArcNum;
+    int secondArcNum;
+
+    for (arcNum = 0, i=0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80);i++)
+        arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+
+    arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+    i++;
+
+    firstArcNum = arcNum / 40;
+    if (firstArcNum > 2)
+        firstArcNum = 2;
+
+    secondArcNum = arcNum - (firstArcNum * 40);
+
+    headOid = (OID*)malloc (sizeof (OID));
+    headOid->arcNum = firstArcNum;
+    headOid->next = (OID*)malloc (sizeof (OID));
+    headOid->next->arcNum = secondArcNum;
+    nextOid = &headOid->next->next;
+
+    for (; i < eoid->octetLen; )
+    {
+        for (arcNum = 0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80); i++)
+            arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+
+        arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+        i++;
+        *nextOid = (OID*)malloc (sizeof (OID));
+        (*nextOid)->arcNum = arcNum;
+        nextOid = &(*nextOid)->next;
+    }
+
+    *result = headOid;
+
+} /* UnbuildEncodedOid */
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-real.c b/SecuritySNACCRuntime/c-lib/src/asn-real.c
new file mode 100644
index 00000000..e301e62c
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-real.c
@@ -0,0 +1,884 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_real.c - BER encode, decode, print and free routines for ASN.1 REAL type.
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-real.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-real.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:31  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.5  1997/02/28 13:39:50  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.4  1995/07/24 21:04:54  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1995/02/18  16:25:13  rj
+ * added support for CPU/compiler combination presenting 64 bit little endian long integers
+ * (in addition to the aforesupported 32 bit big endian long ints).
+ *
+ * Revision 1.2  1994/09/01  00:06:28  rj
+ * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens.
+ *
+ * Revision 1.1  1994/08/28  09:46:00  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+#include "asn-real.h"
+
+double pow PROTO ((double base, double exp));
+
+#ifdef IEEE_REAL_LIB
+/* ieee functions (in case not in math.h)*/
+extern int iszero (double);
+extern int isinf (double);
+extern int signbit (double);
+extern int ilogb (double);
+extern double scalbn (double, int);
+#endif
+
+
+/*
+ *  You must call InitAsnInfinity() to initailize these values
+ *  (necessary if you deal with REAL values.)
+ */
+AsnReal PLUS_INFINITY;
+AsnReal MINUS_INFINITY;
+
+
+#define ENC_PLUS_INFINITY 0x40
+#define ENC_MINUS_INFINITY 0x41
+
+#define REAL_BINARY 0x80
+#define REAL_SIGN   0x40
+#define REAL_EXPLEN_MASK 0x03
+#define REAL_EXPLEN_1 0x00
+#define REAL_EXPLEN_2 0x01
+#define REAL_EXPLEN_3 0x02
+#define REAL_EXPLEN_LONG 0x03
+#define REAL_FACTOR_MASK 0x0c
+#define REAL_BASE_MASK 0x30
+#define REAL_BASE_2 0x00
+#define REAL_BASE_8 0x10
+#define REAL_BASE_16 0x20
+
+
+/*
+ * Returns the smallest octet length needed to
+ * hold the given long int value
+ */
+unsigned int
+SignedIntOctetLen PARAMS ((val),
+    long int val)
+{
+    unsigned long int mask = (0x7f80L << ((sizeof (long int) - 2) * 8));
+    unsigned int retVal = sizeof (long int);
+
+    if (val < 0)
+        val = val ^ (~0L);  /* XOR val with all 1's */
+
+    while ((retVal > 1) && ((val & mask) == 0))
+    {
+        mask >>= 8;
+        retVal--;
+    }
+
+    return retVal;
+
+} /* SignedIntOctetLen */
+
+
+/*
+ * encodes universal TAG LENGTH and Contents of and ASN.1 REAL
+ */
+AsnLen
+BEncAsnReal PARAMS ((b, data),
+    BUF_TYPE b _AND_
+    AsnReal *data)
+{
+    AsnLen len;
+
+    len =  BEncAsnRealContent (b, data);
+    len += BEncDefLen (b, len);
+    len += BEncTag1 (b, UNIV, PRIM, REAL_TAG_CODE);
+    return len;
+}  /* BEncAsnReal */
+
+
+/*
+ * decodes universal TAG LENGTH and Contents of and ASN.1 REAL
+ */
+void
+BDecAsnReal PARAMS ((b, result, bytesDecoded, env),
+    BUF_TYPE b _AND_
+    AsnReal *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tag;
+    AsnLen elmtLen;
+
+    if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, REAL_TAG_CODE))
+    {
+         Asn1Error ("BDecAsnReal: ERROR wrong tag on REAL.\n");
+         longjmp (env, -40);
+    }
+
+    elmtLen = BDecLen (b, bytesDecoded, env);
+    BDecAsnRealContent (b, tag, elmtLen, result, bytesDecoded, env);
+
+}  /* BDecAsnReal */
+
+
+
+#ifdef IEEE_REAL_FMT
+
+/*
+ * Inits the PLUS_INFINITY and MINUS_INFINITY globals assuming
+ * that the double is an IEEE DOUBLE
+ * The bits for MINUS_INFINITY are 0xfff0000000000000
+ * The bits for PLUS_INFINITY are  0x7ff0000000000000
+ */
+void
+InitAsnInfinity()
+{
+    unsigned char *c = (unsigned char *)&PLUS_INFINITY;
+    int i;
+
+    if (sizeof (double) != 8)
+        Asn1Error ("InitAsnInfinity: ERROR expected sizeof (AsnReal) to be 8");
+
+#if WORDS_BIGENDIAN				/* Big endian */
+    c[0] = 0x7f;
+    c[1] = 0xf0;
+    for (i = 2; i < sizeof (double); i++)
+        c[i] = 0;
+#else						/* Little endian */
+    c[7] = 0x7f;
+    c[6] = 0xf0;
+    for (i = 0; i < 6; i++)
+        c[i] = 0;
+#endif
+
+    MINUS_INFINITY = -PLUS_INFINITY;
+} /* InitAsnInfinity */
+
+/*
+ * Encodes the content of an ASN.1 REAL value to the given buffer.
+ * This version of the routine ASSUMES that the C rep. of a double
+ * is the same as the IEEE std.
+ */
+AsnLen
+BEncAsnRealContent PARAMS ((b, value),
+    BUF_TYPE  b _AND_
+    AsnReal  *value)
+{
+    int	exponent;
+    int isNeg;
+#if SIZEOF_LONG == 4
+    unsigned char *dbl;
+    unsigned long int *first4;
+    unsigned long int *second4;
+#else
+#if SIZEOF_LONG == 8
+    unsigned long mantissa, val, *p;
+    int i;
+#endif
+#endif
+
+    /* no contents for 0.0 reals */
+    if (*value == 0.0) /* all bits zero, disregarding top/sign bit */
+        return 0;
+
+#if SIZEOF_LONG == 4
+#if !WORDS_BIGENDIAN
+  #error sorry! this 32 bit code requires big endianess.
+#endif
+
+    /* this code is designed to work were longs are 32 bit wide and big endian */
+
+    dbl = (unsigned char *) value;
+
+    first4 = (unsigned long int *) dbl;
+    second4 = (unsigned long int *) (dbl + sizeof (long int));
+
+    isNeg = dbl[0] & 0x80;
+
+    /* special real values for +/- oo */
+    if (((*first4 & 0x7fffffff) == 0x7ff00000) && (*second4 == 0))
+    {
+        if (isNeg)
+	    {
+            BufPutByteRvs (b, ENC_MINUS_INFINITY);
+	    }
+        else
+	    {
+            BufPutByteRvs (b, ENC_PLUS_INFINITY);
+	    }
+        return 1;
+    }
+    else  /* encode a binary real value */
+    {
+        exponent = (((*first4) >> 20) & 0x07ff);
+
+        /* write the mantissa (N value) */
+        BufPutSegRvs (b, (char *)(dbl+2), sizeof (double)-2);
+
+        /*
+         * The rightmost 4 bits of a double 2nd octet are the
+         * most sig bits of the mantissa.
+         * write the most signficant byte of the asn1 real mantissa,
+         * adding implicit bit to 'left of decimal' if not de-normalized
+         * (de normalized if exponent == 0)
+         *
+         * if the double is not in de-normalized form subtract 1023
+         * from the exponent to get proper signed exponent.
+         *
+         * for both the normalized and de-norm forms
+         * correct the exponent by subtracting 52 since:
+         *   1. mantissa is 52 bits in the double (56 in ASN.1 REAL form)
+         *   2. implicit decimal at the beginning of double's mantissa
+         *   3. ASN.1 REAL's implicit decimal is after its mantissa
+         * so converting the double mantissa to the ASN.1 form has the
+         * effect of multiplying it by 2^52. Subtracting 52 from the
+         * exponent corrects this.
+         */
+        if (exponent == 0) /* de-normalized - no implicit 1 to left of dec.*/
+        {
+            BufPutByteRvs (b, dbl[1] & 0x0f);
+            exponent -= 52;
+        }
+        else
+        {
+            BufPutByteRvs (b, (dbl[1] & 0x0f) | 0x10); /* 0x10 adds implicit bit */
+            exponent -= (1023 + 52);
+        }
+
+#else
+#if SIZEOF_LONG == 8
+#if WORDS_BIGENDIAN
+  #error sorry! this 64 bit code requires little endianess.
+#endif
+
+    /* this code is designed to work on Alpha under OSF/1 (64 bit longs, little endian) */
+
+    p = (unsigned long *) value;
+    val = *p;
+
+    isNeg = (val >> 63) & 1;
+    /* special real values for +/- oo */
+    if (!finite (*value))
+    {
+        if (isNeg)
+	    {
+            BufPutByteRvs (b, ENC_MINUS_INFINITY);
+	    }
+        else
+	    {
+            BufPutByteRvs (b, ENC_PLUS_INFINITY);
+	    }
+        return 1;
+    }
+    else /* encode a binary real value */
+    {
+	exponent = (val >> 52) & 0x7ff;
+	mantissa = (val & 0xfffffffffffffL) | 0x10000000000000L;
+
+	for (i = 0; i < 7; i++)
+	{
+	    BufPutByteRvs (b, mantissa & 0xff);
+	    mantissa >>= 8;
+        }
+        exponent -= (1023 + 52);
+
+#else
+  #error long neither 8 nor 4 bytes in size?
+#endif
+#endif
+
+        /*  write the exponent  */
+        BufPutByteRvs (b, exponent & 0xff);
+        BufPutByteRvs (b, exponent >> 8);
+
+        /* write format octet */
+        /* bb is 00 since base is 2 so do nothing */
+        /* ff is 00 since no other shifting is nec */
+        if (isNeg)
+	    {
+            BufPutByteRvs (b, REAL_BINARY | REAL_EXPLEN_2 | REAL_SIGN);
+	    }
+        else
+	    {
+            BufPutByteRvs (b, REAL_BINARY | REAL_EXPLEN_2);
+	    }
+
+        return sizeof (double) + 2;
+    }
+
+    /* not reached */
+
+} /* BEncAsnRealContent */
+
+#else  /* IEEE_REAL_FMT not def */
+
+#ifdef IEEE_REAL_LIB
+
+
+/*
+ * Inits the PLUS_INFINITY and MINUS_INFINITY globals assuming
+ * that the ieee_values library is present
+ */
+void
+InitAsnInfinity()
+{
+    PLUS_INFINITY = infinity();
+    MINUS_INFINITY = -PLUS_INFINITY;
+} /* InitAsnInfinity */
+
+/*
+ * Encodes the content of an ASN.1 REAL value to the given buffer.
+ * This version of the routine does not assume an IEEE double rep.
+ * ieee library conversion routine are used instead.
+ */
+AsnLen
+BEncAsnRealContent PARAMS ((b, value),
+    BUF_TYPE  b _AND_
+    AsnReal  *value)
+{
+    unsigned long int encLen;
+    double mantissa;
+    double tmpMantissa;
+    unsigned int truncatedMantissa;
+    int	exponent;
+    unsigned int expLen;
+    int	sign;
+    unsigned char buf[sizeof (double)];
+    int i, mantissaLen;
+    unsigned char firstOctet;
+
+    /* no contents for 0.0 reals */
+    if (iszero (*value))
+        return 0;
+
+    /* special real values for +/- oo */
+    if (isinf (*value))
+    {
+        if (signbit (*value)) /* neg */
+            BufPutByteRvs (b, ENC_MINUS_INFINITY);
+        else
+            BufPutByteRvs (b, ENC_PLUS_INFINITY);
+        encLen = 1;
+    }
+    else  /* encode a binary real value */
+    {
+        if (signbit (*value))
+            sign = -1;
+        else
+            sign = 1;
+
+        exponent =  ilogb (*value);
+
+        /* get the absolute value of the mantissa (subtract 1 to make < 1) */
+        mantissa = scalbn (fabs (*value), -exponent-1);
+
+
+        tmpMantissa = mantissa;
+
+        /* convert mantissa into an unsigned integer */
+        for (i = 0; i < sizeof (double); i++)
+        {
+            /* normalizied so shift 8 bits worth to the left of the decimal */
+            tmpMantissa *= (1<<8);
+
+            /* grab only (octet sized) the integer part */
+            truncatedMantissa = (unsigned int) tmpMantissa;
+
+            /* remove part to left of decimal now for next iteration */
+            tmpMantissa -= truncatedMantissa;
+
+            /* write into tmp buffer */
+            buf[i] = truncatedMantissa;
+
+            /* keep track of last non zero octet so can zap trailing zeros */
+            if (truncatedMantissa)
+                mantissaLen = i+1;
+        }
+
+        /*
+         * write format octet  (first octet of content)
+         *  field  1 S bb ff ee
+         *  bit#   8 7 65 43 21
+         *
+         * 1 in bit#1 means binary rep
+         * 1 in bit#2 means the mantissa is neg, 0 pos
+         * bb is the base:    65  base
+         *                    00    2
+         *                    01    8
+         *                    10    16
+         *                    11    future ext.
+         *
+         * ff is the Value of F where  Mantissa = sign x N x 2^F
+         *    FF can be one of 0 to 3 inclusive. (used to save re-alignment)
+         *
+         * ee is the length of the exponent:  21   length
+         *                                    00     1
+         *                                    01     2
+         *                                    10     3
+         *                                    11     long form
+         *
+         *
+         * encoded binary real value looks like
+         *
+         *     fmt oct
+         *   --------------------------------------------------------
+         *   |1Sbbffee|  exponent (2's comp)  |   N (unsigned int)  |
+         *   --------------------------------------------------------
+         *    87654321
+         */
+        firstOctet = REAL_BINARY;
+        if (signbit (*value))
+            firstOctet |= REAL_SIGN;
+
+        /* bb is 00 since base is 2 so do nothing */
+        /* ff is 00 since no other shifting is nec */
+
+        /*
+         * get exponent calculate its encoded length
+         * Note that the process of converting the mantissa
+         * double to an int shifted the decimal mantissaLen * 8
+         * to the right - so correct that here
+         */
+        exponent++; /* compensate for trick to put mantissa < 1 */
+        exponent -= (mantissaLen * 8);
+        expLen = SignedIntOctetLen (exponent);
+
+        switch (expLen)
+        {
+            case 1:
+                firstOctet |= REAL_EXPLEN_1;
+                break;
+            case 2:
+                firstOctet |= REAL_EXPLEN_2;
+                break;
+            case 3:
+                firstOctet |= REAL_EXPLEN_3;
+                break;
+            default:
+                firstOctet |= REAL_EXPLEN_LONG;
+                break;
+        }
+
+        encLen = mantissaLen + expLen + 1;
+
+        /* write the mantissa (N value) */
+        BufPutSegRvs (b, (char*)buf, mantissaLen);
+
+        /* write the exponent */
+        for (i = expLen; i > 0; i--)
+        {
+            BufPutByteRvs (b, exponent);
+            exponent >>= 8;
+        }
+
+        /* write the exponents length if nec */
+        if (expLen > 3)
+        {
+            encLen++;
+            BufPutByteRvs (b, expLen);
+        }
+
+        /* write the format octet */
+        BufPutByteRvs (b, firstOctet);
+
+    }
+    return encLen;
+
+}  /*  BEncAsnRealContent */
+
+#else  /* neither IEEE_REAL_FMT or IEEE_REAL_LIB are def */
+
+/*
+ * Inits the PLUS_INFINITY and MINUS_INFINITY globals assuming
+ * that the double is an IEEE DOUBLE.  This should be changed
+ * for the target architecture (if it is not IEEE)
+ */
+void
+InitAsnInfinity()
+{
+    unsigned char *c;
+    int i;
+
+    if (sizeof (double) != 8)
+        Asn1Error ("InitAsnInfinity: ERROR expected sizeof (AsnReal) to be 8");
+
+    c = (unsigned char*)&PLUS_INFINITY;
+    c[0] = 0x7f;
+    c[1] = 0xf0;
+    for (i = 2; i < sizeof (double); i++)
+        c[i] = 0;
+
+    MINUS_INFINITY = -PLUS_INFINITY;
+} /* InitAsnInfinity */
+
+/*
+ * Encodes the content of an ASN.1 REAL value to the given buffer.
+ * This version of the routine does not assume an IEEE double rep.
+ * or the existence of the IEEE library routines.  Uses old style
+ * UNIX frexp etc.
+ */
+AsnLen
+BEncAsnRealContent PARAMS ((b, value),
+    BUF_TYPE  b _AND_
+    AsnReal  *value)
+{
+    unsigned long int encLen;
+    double mantissa;
+    double tmpMantissa;
+    unsigned int truncatedMantissa;
+    int	exponent;
+    unsigned int expLen;
+    int	sign;
+    unsigned char buf[sizeof (double)];
+    int i, mantissaLen;
+    unsigned char firstOctet;
+
+    /* no contents for 0.0 reals */
+    if (*value == 0.0)
+        return 0;
+
+    /* special real values for +/- oo */
+    if (*value == MINUS_INFINITY)
+    {
+        BufPutByteRvs (b, ENC_MINUS_INFINITY);
+        encLen = 1;
+    }
+    else if (*value == PLUS_INFINITY)
+    {
+        BufPutByteRvs (b, ENC_PLUS_INFINITY);
+        encLen = 1;
+    }
+    else  /* encode a binary real value */
+    {
+        /*
+         * this is what frexp gets from *value
+         * *value == mantissa * 2^exponent
+         * where 0.5 <= |manitissa| < 1.0
+         */
+        mantissa = frexp (*value, &exponent);
+
+        /* set sign and make mantissa = | mantissa | */
+        if (mantissa < 0.0)
+        {
+            sign = -1;
+            mantissa *= -1;
+        }
+        else
+            sign = 1;
+
+
+        tmpMantissa = mantissa;
+
+        /* convert mantissa into an unsigned integer */
+        for (i = 0; i < sizeof (double); i++)
+        {
+            /* normalizied so shift 8 bits worth to the left of the decimal */
+            tmpMantissa *= (1<<8);
+
+            /* grab only (octet sized) the integer part */
+            truncatedMantissa = (unsigned int) tmpMantissa;
+
+            /* remove part to left of decimal now for next iteration */
+            tmpMantissa -= truncatedMantissa;
+
+            /* write into tmp buffer */
+            buf[i] = truncatedMantissa;
+
+            /* keep track of last non zero octet so can zap trailing zeros */
+            if (truncatedMantissa)
+                mantissaLen = i+1;
+        }
+
+        /*
+         * write format octet  (first octet of content)
+         *  field  1 S bb ff ee
+         *  bit#   8 7 65 43 21
+         *
+         * 1 in bit#1 means binary rep
+         * 1 in bit#2 means the mantissa is neg, 0 pos
+         * bb is the base:    65  base
+         *                    00    2
+         *                    01    8
+         *                    10    16
+         *                    11    future ext.
+         *
+         * ff is the Value of F where  Mantissa = sign x N x 2^F
+         *    FF can be one of 0 to 3 inclusive. (used to save re-alignment)
+         *
+         * ee is the length of the exponent:  21   length
+         *                                    00     1
+         *                                    01     2
+         *                                    10     3
+         *                                    11     long form
+         *
+         *
+         * encoded binary real value looks like
+         *
+         *     fmt oct
+         *   --------------------------------------------------------
+         *   |1Sbbffee|  exponent (2's comp)  |   N (unsigned int)  |
+         *   --------------------------------------------------------
+         *    87654321
+         */
+        firstOctet = REAL_BINARY;
+        if (sign == -1)
+            firstOctet |= REAL_SIGN;
+
+        /* bb is 00 since base is 2 so do nothing */
+        /* ff is 00 since no other shifting is nec */
+
+        /*
+         * get exponent calculate its encoded length
+         * Note that the process of converting the mantissa
+         * double to an int shifted the decimal mantissaLen * 8
+         * to the right - so correct that here
+         */
+        exponent -= (mantissaLen * 8);
+        expLen = SignedIntOctetLen (exponent);
+
+        switch (expLen)
+        {
+            case 1:
+                firstOctet |= REAL_EXPLEN_1;
+                break;
+            case 2:
+                firstOctet |= REAL_EXPLEN_2;
+                break;
+            case 3:
+                firstOctet |= REAL_EXPLEN_3;
+                break;
+            default:
+                firstOctet |= REAL_EXPLEN_LONG;
+                break;
+        }
+
+        encLen = mantissaLen + expLen + 1;
+
+        /* write the mantissa (N value) */
+        BufPutSegRvs (b, (char*)buf, mantissaLen);
+
+        /* write the exponent */
+        for (i = expLen; i > 0; i--)
+        {
+            BufPutByteRvs (b, exponent);
+            exponent >>= 8;
+        }
+
+        /* write the exponents length if nec */
+        if (expLen > 3)
+        {
+            encLen++;
+            BufPutByteRvs (b, expLen);
+        }
+
+        /* write the format octet */
+        BufPutByteRvs (b, firstOctet);
+
+    }
+    return encLen;
+
+}  /*  BEncAsnRealContent */
+
+#endif /* IEEE_REAL_LIB */
+#endif /* IEEE_REAL_FMT */
+
+
+
+/*
+ * Decodes the content of a BER REAL value.
+ * This only supports the binary REAL encoding.  The decimal encoding
+ * is left as an exercise to the reader.
+ */
+void
+BDecAsnRealContent PARAMS ((b, tagId, len, result, bytesDecoded, env),
+    BUF_TYPE  b _AND_
+    AsnTag    tagId _AND_
+    AsnLen    len _AND_
+    AsnReal  *result _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    unsigned char firstOctet;
+    unsigned char firstExpOctet;
+    int i;
+    unsigned int expLen;
+    double mantissa;
+    unsigned short base;
+    long int exponent = 0;
+    double tmpBase;
+    double tmpExp;
+
+    if (len == 0)
+    {
+        *result = 0.0;
+        return;
+    }
+
+    firstOctet = BufGetByte (b);
+    if (len == 1)
+    {
+        (*bytesDecoded) += 1;
+        if (firstOctet == ENC_PLUS_INFINITY)
+            *result = PLUS_INFINITY;
+        else if (firstOctet == ENC_MINUS_INFINITY)
+            *result = MINUS_INFINITY;
+        else
+        {
+            Asn1Error ("BDecAsnRealContent: ERROR - unrecognized real number of length 1 octet.\n");
+            longjmp (env, -22);
+        }
+    }
+    else
+    {
+        if (firstOctet & REAL_BINARY)
+        {
+            firstExpOctet = BufGetByte (b);
+            if (firstExpOctet & 0x80)
+                exponent = -1;
+            switch (firstOctet & REAL_EXPLEN_MASK)
+            {
+                case REAL_EXPLEN_1:
+                    expLen = 1;
+                    exponent =  (exponent << 8)| firstExpOctet;
+                    break;
+
+                case REAL_EXPLEN_2:
+                    expLen = 2;
+                    exponent =  (exponent << 16) |
+                        (((unsigned long int) firstExpOctet) << 8) |
+                        BufGetByte (b);
+                    break;
+
+                case REAL_EXPLEN_3:
+                    expLen = 3;
+                    exponent =  (exponent << 16) |
+                        (((unsigned long int) firstExpOctet) << 8) |
+                            BufGetByte (b);
+                    exponent =  (exponent << 8) | BufGetByte (b);
+                    break;
+
+                default:  /* long form */
+                    expLen = firstExpOctet +1;
+                    i = firstExpOctet-1;
+                    firstExpOctet =  BufGetByte (b);
+                    if (firstExpOctet & 0x80)
+                        exponent = (-1 <<8) | firstExpOctet;
+                    else
+                        exponent = firstExpOctet;
+                    for (;i > 0; firstExpOctet--)
+                        exponent = (exponent << 8) | BufGetByte (b);
+                    break;
+            }
+
+            mantissa = 0.0;
+            for (i = 1 + expLen; i < len; i++)
+            {
+                mantissa *= (1<<8);
+                mantissa +=  BufGetByte (b);
+            }
+
+            /* adjust N by scaling factor */
+            mantissa *= (1<<((firstOctet & REAL_FACTOR_MASK) >> 2));
+
+            switch (firstOctet & REAL_BASE_MASK)
+            {
+                case REAL_BASE_2:
+                    base = 2;
+                    break;
+
+                case REAL_BASE_8:
+                    base = 8;
+                    break;
+
+                case REAL_BASE_16:
+                    base = 16;
+                    break;
+
+                default:
+                    Asn1Error ("BDecAsnRealContent: ERROR - unsupported base for a binary real number.\n");
+                    longjmp (env, -23);
+                    break;
+
+            }
+
+            tmpBase = base;
+            tmpExp = exponent;
+
+            *result =  mantissa * pow ((double)base, (double)exponent);
+
+            if (firstOctet & REAL_SIGN)
+                *result = -*result;
+
+            (*bytesDecoded) += len;
+        }
+        else /* decimal version */
+        {
+            Asn1Error ("BDecAsnRealContent: ERROR - decimal REAL form is not currently supported\n");
+            longjmp (env, -24);
+        }
+    }
+
+}  /* BDecAsnRealContent */
+
+
+/*
+ * Prints given REAL value to the given FILE * in ASN.1 Value Notation.
+ * indent is ignored.
+ */
+void
+PrintAsnReal PARAMS ((f, v, indent),
+    FILE *f _AND_
+    AsnReal *v _AND_
+    unsigned short int indent)
+{
+    fprintf (f, "%.17E", *v);
+}
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-tag.c b/SecuritySNACCRuntime/c-lib/src/asn-tag.c
new file mode 100644
index 00000000..52f13bd5
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-tag.c
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * asn_tag.c - BER encode, decode and untility routines for ASN.1 Tags.
+ *
+ * MS 92
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/asn-tag.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: asn-tag.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:32  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.5  1997/09/03 12:11:41  wan
+ * Patch to tag decoding for tags > 2^14 (thanks to Enrico Badella)
+ * Patch to TblEncTag to emit final 0x00 if previous octet signals continuation
+ *
+ * Revision 1.4  1997/03/13 09:15:18  wan
+ * Improved dependency generation for stupid makedepends.
+ * Corrected PeekTag to peek into buffer only as far as necessary.
+ * Added installable error handler.
+ * Fixed small glitch in idl-code generator (Markku Savela <msa@msa.tte.vtt.fi>).
+ *
+ * Revision 1.3  1997/02/28 13:39:50  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.2  1995/07/27 09:01:25  rj
+ * merged PeekTag(), a function used only by the type table code.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:46:01  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "asn-len.h"
+#include "asn-tag.h"
+
+
+/*
+ * Returns an AsnTag.  An AsnTag is simply an encoded tag
+ * shifted to fill up an unsigned long int (first tag byte
+ * in most sig byte of long int)
+ * This rep permits easy case stmt comparison of tags.
+ * NOTE: The unsigned long rep for tag BREAKS if the
+ *       the tag's code is over 2^21 (very unlikely)
+ *
+ * RETURNS 0 if decoded a 0 byte (ie first byte of an EOC)
+ */
+AsnTag
+BDecTag PARAMS ((b, bytesDecoded, env),
+    BUF_TYPE  b _AND_
+    AsnLen *bytesDecoded _AND_
+    jmp_buf env)
+{
+    AsnTag tagId;
+    AsnTag tmpTagId;
+    int i;
+
+    tagId = ((AsnTag)BufGetByte (b)) << ((sizeof (AsnTag)-1)*8);
+    (*bytesDecoded)++;
+
+    /* check if long tag format (ie code > 31) */
+    if ((tagId & (((AsnTag) 0x1f) << ((sizeof (AsnTag)-1)*8))) == (((AsnTag)0x1f) << ((sizeof (AsnTag)-1)*8)))
+    {
+        i = 2;
+        do
+        {
+            tmpTagId = (AsnTag) BufGetByte (b);
+            tagId |= (tmpTagId << ((sizeof (AsnTag)-i)*8));
+            (*bytesDecoded)++;
+            i++;
+        }
+        while ((tmpTagId & (AsnTag)0x80) && (i <= sizeof (AsnTag)));
+
+        /*
+         * check for tag that is too long
+         */
+        if (i > (sizeof (AsnTag)+1))
+        {
+            Asn1Error ("BDecTag: ERROR - tag value overflow\n");
+            longjmp (env, -25);
+        }
+    }
+
+    if (BufReadError (b))
+    {
+        Asn1Error ("BDecTag: ERROR - decoded past the end of data\n");
+        longjmp (env, -26);
+    }
+
+    return tagId;
+
+}  /* BDecTag */
+
+
+#if TTBL
+AsnTag PeekTag PARAMS ((b, env),
+    BUF_TYPE b _AND_
+    ENV_TYPE env)
+{
+    AsnTag tagId, tmpTagId;
+    int i;
+    unsigned char buf[sizeof(AsnTag)];
+    unsigned char* p = buf;
+
+    /*
+     * peek/copy the next (max size of tag) bytes
+     * to get the tag info.  The Peek buffer routines
+     * were added to the standard set for this function.
+     */
+
+    BufPeekCopy ((char*)buf, b, 1);
+    tagId = ((AsnTag)*p++) << ((sizeof (AsnTag)-1)*8);
+
+    /* check if long tag format (ie code > 31) */
+    if ((tagId & (((AsnTag) 0x1f) << ((sizeof (AsnTag)-1)*8))) == (((AsnTag)0x1f) << ((sizeof (AsnTag)-1)*8)))
+    {
+        i = 2;
+        do
+        {
+	    BufPeekCopy ((char*)buf, b, i);
+            tmpTagId = (AsnTag) *p++;
+            tagId |= (tmpTagId << ((sizeof (AsnTag)-i)*8));
+            i++;
+        }
+        while ((tmpTagId & (AsnTag)0x80) && (i <= sizeof (AsnTag)));
+
+        /*
+         * check for tag that is too long
+         */
+        if (i > (sizeof (AsnTag)+1))
+        {
+            Asn1Error ("BDecTag: ERROR - tag value overflow\n");
+            longjmp (env, -1004);
+        }
+    }
+
+    return tagId;
+
+} /* PeekTag */
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/src/asn-useful.c b/SecuritySNACCRuntime/c-lib/src/asn-useful.c
new file mode 100644
index 00000000..a1439b56
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/asn-useful.c
@@ -0,0 +1,892 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    asn-useful.c
+ *
+ *    "ASN-USEFUL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Thu Jun  8 12:35:27 2000
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "asn-useful.h"
+
+
+AsnLen BEncUTF8String PARAMS ((b, v),
+BUF_TYPE b _AND_
+UTF8String *v)
+{
+    AsnLen l;
+    l = BEncUTF8StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, 12);
+    return l;
+} /* BEncUTF8String */
+
+void BDecUTF8String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+UTF8String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, 12))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, 12)))
+    {
+        Asn1Error ("BDecUTF8String: ERROR - wrong tag\n");
+        longjmp (env, 50);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecUTF8StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecUTF8String */
+
+AsnLen BEncNumericString PARAMS ((b, v),
+BUF_TYPE b _AND_
+NumericString *v)
+{
+    AsnLen l;
+    l = BEncNumericStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE);
+    return l;
+} /* BEncNumericString */
+
+void BDecNumericString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+NumericString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecNumericString: ERROR - wrong tag\n");
+        longjmp (env, 49);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecNumericStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecNumericString */
+
+AsnLen BEncPrintableString PARAMS ((b, v),
+BUF_TYPE b _AND_
+PrintableString *v)
+{
+    AsnLen l;
+    l = BEncPrintableStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE);
+    return l;
+} /* BEncPrintableString */
+
+void BDecPrintableString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+PrintableString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecPrintableString: ERROR - wrong tag\n");
+        longjmp (env, 48);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecPrintableStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecPrintableString */
+
+AsnLen BEncTeletexString PARAMS ((b, v),
+BUF_TYPE b _AND_
+TeletexString *v)
+{
+    AsnLen l;
+    l = BEncTeletexStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+} /* BEncTeletexString */
+
+void BDecTeletexString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+TeletexString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecTeletexString: ERROR - wrong tag\n");
+        longjmp (env, 47);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecTeletexStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecTeletexString */
+
+AsnLen BEncT61String PARAMS ((b, v),
+BUF_TYPE b _AND_
+T61String *v)
+{
+    AsnLen l;
+    l = BEncT61StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE);
+    return l;
+} /* BEncT61String */
+
+void BDecT61String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+T61String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecT61String: ERROR - wrong tag\n");
+        longjmp (env, 46);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecT61StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecT61String */
+
+AsnLen BEncVideotexString PARAMS ((b, v),
+BUF_TYPE b _AND_
+VideotexString *v)
+{
+    AsnLen l;
+    l = BEncVideotexStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE);
+    return l;
+} /* BEncVideotexString */
+
+void BDecVideotexString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+VideotexString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VIDEOTEXSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VIDEOTEXSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecVideotexString: ERROR - wrong tag\n");
+        longjmp (env, 45);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecVideotexStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecVideotexString */
+
+AsnLen BEncIA5String PARAMS ((b, v),
+BUF_TYPE b _AND_
+IA5String *v)
+{
+    AsnLen l;
+    l = BEncIA5StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, IA5STRING_TAG_CODE);
+    return l;
+} /* BEncIA5String */
+
+void BDecIA5String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+IA5String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, IA5STRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, IA5STRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecIA5String: ERROR - wrong tag\n");
+        longjmp (env, 44);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecIA5StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecIA5String */
+
+AsnLen BEncGraphicString PARAMS ((b, v),
+BUF_TYPE b _AND_
+GraphicString *v)
+{
+    AsnLen l;
+    l = BEncGraphicStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GRAPHICSTRING_TAG_CODE);
+    return l;
+} /* BEncGraphicString */
+
+void BDecGraphicString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GraphicString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GRAPHICSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GRAPHICSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecGraphicString: ERROR - wrong tag\n");
+        longjmp (env, 43);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGraphicStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGraphicString */
+
+AsnLen BEncVisibleString PARAMS ((b, v),
+BUF_TYPE b _AND_
+VisibleString *v)
+{
+    AsnLen l;
+    l = BEncVisibleStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+} /* BEncVisibleString */
+
+void BDecVisibleString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+VisibleString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecVisibleString: ERROR - wrong tag\n");
+        longjmp (env, 42);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecVisibleStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecVisibleString */
+
+AsnLen BEncISO646String PARAMS ((b, v),
+BUF_TYPE b _AND_
+ISO646String *v)
+{
+    AsnLen l;
+    l = BEncISO646StringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE);
+    return l;
+} /* BEncISO646String */
+
+void BDecISO646String PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+ISO646String *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecISO646String: ERROR - wrong tag\n");
+        longjmp (env, 41);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecISO646StringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecISO646String */
+
+AsnLen BEncGeneralString PARAMS ((b, v),
+BUF_TYPE b _AND_
+GeneralString *v)
+{
+    AsnLen l;
+    l = BEncGeneralStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GENERALSTRING_TAG_CODE);
+    return l;
+} /* BEncGeneralString */
+
+void BDecGeneralString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GeneralString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GENERALSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GENERALSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecGeneralString: ERROR - wrong tag\n");
+        longjmp (env, 40);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGeneralStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGeneralString */
+
+AsnLen BEncUTCTime PARAMS ((b, v),
+BUF_TYPE b _AND_
+UTCTime *v)
+{
+    AsnLen l;
+    l = BEncUTCTimeContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, UTCTIME_TAG_CODE);
+    return l;
+} /* BEncUTCTime */
+
+void BDecUTCTime PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+UTCTime *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE)))
+    {
+        Asn1Error ("BDecUTCTime: ERROR - wrong tag\n");
+        longjmp (env, 39);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecUTCTimeContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecUTCTime */
+
+AsnLen BEncGeneralizedTime PARAMS ((b, v),
+BUF_TYPE b _AND_
+GeneralizedTime *v)
+{
+    AsnLen l;
+    l = BEncGeneralizedTimeContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
+    return l;
+} /* BEncGeneralizedTime */
+
+void BDecGeneralizedTime PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+GeneralizedTime *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
+    {
+        Asn1Error ("BDecGeneralizedTime: ERROR - wrong tag\n");
+        longjmp (env, 38);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecGeneralizedTimeContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecGeneralizedTime */
+
+AsnLen BEncUniversalString PARAMS ((b, v),
+BUF_TYPE b _AND_
+UniversalString *v)
+{
+    AsnLen l;
+    l = BEncUniversalStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, UNIVERSALSTRING_TAG_CODE);
+    return l;
+} /* BEncUniversalString */
+
+void BDecUniversalString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+UniversalString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, UNIVERSALSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, UNIVERSALSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecUniversalString: ERROR - wrong tag\n");
+        longjmp (env, 37);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecUniversalStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecUniversalString */
+
+AsnLen BEncBMPString PARAMS ((b, v),
+BUF_TYPE b _AND_
+BMPString *v)
+{
+    AsnLen l;
+    l = BEncBMPStringContent (b, v);
+    l += BEncDefLen (b, l);
+    l += BEncTag1 (b, UNIV, PRIM, BMPSTRING_TAG_CODE);
+    return l;
+} /* BEncBMPString */
+
+void BDecBMPString PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+BMPString *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, PRIM, BMPSTRING_TAG_CODE))&&
+         (tag != MAKE_TAG_ID (UNIV, CONS, BMPSTRING_TAG_CODE)))
+    {
+        Asn1Error ("BDecBMPString: ERROR - wrong tag\n");
+        longjmp (env, 36);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecBMPStringContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecBMPString */
+
+AsnLen
+BEncEXTERNALChoiceContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNALChoice *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+    BEncEocIfNec (b);
+    itemLen = BEncAsnOctsContent (b, (v->a.single_ASN1_type));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 4);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case EXTERNALCHOICE_OCTET_ALIGNED:
+    itemLen = BEncAsnOctsContent (b, (v->a.octet_aligned));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case EXTERNALCHOICE_ARBITRARY:
+    itemLen = BEncAsnBitsContent (b, (v->a.arbitrary));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncEXTERNALChoiceContent */
+
+void
+BDecEXTERNALChoiceContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+EXTERNALChoice *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+
+
+    switch (tagId0)
+    {
+       case MAKE_TAG_ID (CNTX, CONS, 0):
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+if ((tagId1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) &&
+   (tagId1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, 35);
+    }
+
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+        (v->choiceId) = EXTERNALCHOICE_SINGLE_ASN1_TYPE;
+    (v->a.single_ASN1_type) = (AsnOcts*) Asn1Alloc (sizeof (AsnOcts));
+    CheckAsn1Alloc ((v->a.single_ASN1_type), env);
+    BDecAsnOctsContent (b, tagId1, elmtLen1, (v->a.single_ASN1_type), &totalElmtsLen1, env);
+    if (elmtLen0 == INDEFINITE_LEN)
+        BDecEoc (b, &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, PRIM, 1):
+       case MAKE_TAG_ID (CNTX, CONS, 1):
+        (v->choiceId) = EXTERNALCHOICE_OCTET_ALIGNED;
+    (v->a.octet_aligned) = (AsnOcts*) Asn1Alloc (sizeof (AsnOcts));
+    CheckAsn1Alloc ((v->a.octet_aligned), env);
+    BDecAsnOctsContent (b, tagId0, elmtLen0, (v->a.octet_aligned), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, PRIM, 2):
+       case MAKE_TAG_ID (CNTX, CONS, 2):
+        (v->choiceId) = EXTERNALCHOICE_ARBITRARY;
+    (v->a.arbitrary) = (AsnBits*) Asn1Alloc (sizeof (AsnBits));
+    CheckAsn1Alloc ((v->a.arbitrary), env);
+    BDecAsnBitsContent (b, tagId0, elmtLen0, (v->a.arbitrary), &totalElmtsLen1, env);
+    break;
+
+    default:
+        Asn1Error ("ERROR - unexpected tag in CHOICE\n");
+        longjmp (env, 34);
+        break;
+    } /* end switch */
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecEXTERNALChoiceContent */
+
+void
+PrintEXTERNALChoice PARAMS ((f, v, indent),
+FILE* f _AND_
+EXTERNALChoice *v _AND_
+unsigned short int indent)
+{
+    switch (v->choiceId)
+    {
+      case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+          fprintf (f,"single-ASN1-type ");
+    PrintAsnOcts (f, (v->a.single_ASN1_type), indent + stdIndentG);
+          break;
+
+      case EXTERNALCHOICE_OCTET_ALIGNED:
+          fprintf (f,"octet-aligned ");
+    PrintAsnOcts (f, (v->a.octet_aligned), indent + stdIndentG);
+          break;
+
+      case EXTERNALCHOICE_ARBITRARY:
+          fprintf (f,"arbitrary ");
+    PrintAsnBits (f, (v->a.arbitrary), indent + stdIndentG);
+          break;
+
+    }
+}  /* PrintEXTERNALChoice */
+
+void
+FreeEXTERNALChoice PARAMS ((v),
+EXTERNALChoice *v)
+{
+
+    if (v == NULL)
+        return;
+    switch (v->choiceId)
+    {
+       case EXTERNALCHOICE_SINGLE_ASN1_TYPE:
+    FreeAsnOcts ((v->a.single_ASN1_type));
+    Asn1Free ((v->a.single_ASN1_type));
+
+    break;
+
+       case EXTERNALCHOICE_OCTET_ALIGNED:
+    FreeAsnOcts ((v->a.octet_aligned));
+    Asn1Free ((v->a.octet_aligned));
+
+    break;
+
+       case EXTERNALCHOICE_ARBITRARY:
+    FreeAsnBits ((v->a.arbitrary));
+    Asn1Free ((v->a.arbitrary));
+
+    break;
+
+    }
+}  /* FreeEXTERNALChoice */
+
+
+
+
+AsnLen BEncEXTERNAL PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNAL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncEXTERNALContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, EXTERNAL_TAG_CODE);
+    return l;
+} /* BEncEXTERNAL */
+
+void BDecEXTERNAL PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+EXTERNAL *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, CONS, EXTERNAL_TAG_CODE)))
+    {
+        Asn1Error ("BDecEXTERNAL: ERROR - wrong tag\n");
+        longjmp (env, 33);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecEXTERNALContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecEXTERNAL */
+
+AsnLen
+BEncEXTERNALContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+EXTERNAL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncEXTERNALChoiceContent (b, (v->encoding));
+
+    totalLen += itemLen;
+
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    itemLen = BEncObjectDescriptorContent (b, (&v->data_value_descriptor));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 7);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    itemLen = BEncAsnIntContent (b, (v->indirect_reference));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->direct_reference));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 6);
+
+    totalLen += itemLen;
+    }
+
+    return totalLen;
+
+}  /* BEncEXTERNALContent */
+
+void
+BDecEXTERNALContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+EXTERNAL *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnOidContent (b, tagId1, elmtLen1, (&v->direct_reference), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->indirect_reference) = (AsnInt*) Asn1Alloc (sizeof (AsnInt));
+    CheckAsn1Alloc ((v->indirect_reference), env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (v->indirect_reference), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, OD_TAG_CODE)) ||
+(tagId1 == MAKE_TAG_ID (UNIV, CONS, OD_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecObjectDescriptorContent (b, tagId1, elmtLen1, (&v->data_value_descriptor), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 0)) ||
+    (tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))||
+    (tagId1 == MAKE_TAG_ID (CNTX, CONS, 1)) ||
+    (tagId1 == MAKE_TAG_ID (CNTX, PRIM, 2))||
+    (tagId1 == MAKE_TAG_ID (CNTX, CONS, 2))))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->encoding) = (EXTERNALChoice*) Asn1Alloc (sizeof (EXTERNALChoice));
+    CheckAsn1Alloc ((v->encoding), env);
+    BDecEXTERNALChoiceContent (b, tagId1, elmtLen1, (v->encoding), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, 32);
+    }
+    else
+        longjmp (env, 31);
+
+
+    if (!seqDone)
+        longjmp (env, 30);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecEXTERNALContent */
+
+void
+PrintEXTERNAL PARAMS ((f, v, indent),
+FILE* f _AND_
+EXTERNAL *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"direct-reference ");
+    PrintAsnOid (f, (&v->direct_reference), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"indirect-reference ");
+    PrintAsnInt (f, (v->indirect_reference), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"data-value-descriptor ");
+    PrintObjectDescriptor (f, (&v->data_value_descriptor), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"encoding ");
+    PrintEXTERNALChoice (f, (v->encoding), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintEXTERNAL */
+
+void
+FreeEXTERNAL PARAMS ((v),
+EXTERNAL *v)
+{
+
+    if (v == NULL)
+        return;
+    if (ASNOID_PRESENT ((&v->direct_reference)))
+    {
+    FreeAsnOid ((&v->direct_reference));
+    }
+
+    if (NOT_NULL ((v->indirect_reference)))
+    {
+    FreeAsnInt ((v->indirect_reference));
+    Asn1Free ((v->indirect_reference));
+    }
+
+    if (ASNOCTS_PRESENT ((&v->data_value_descriptor)))
+    {
+    FreeObjectDescriptor ((&v->data_value_descriptor));
+    }
+
+    FreeEXTERNALChoice ((v->encoding));
+    Asn1Free ((v->encoding));
+
+}  /* FreeEXTERNAL */
+
+
+
+
diff --git a/SecuritySNACCRuntime/c-lib/src/exp-buf.c b/SecuritySNACCRuntime/c-lib/src/exp-buf.c
new file mode 100644
index 00000000..6c6ef77c
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/exp-buf.c
@@ -0,0 +1,896 @@
+/*
+ * 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.
+ */
+
+
+#if defined (USE_EXP_BUF) || defined (USE_GEN_BUF)
+/*
+ * .../c-lib/src/exp-buf.c - buffer routines for the buffer structure
+ *
+ *
+ *  ---------         ----------
+ *  | ExpBuf |<------>| ExpBuf |<------> ...ExpBufs
+ *  |        |---     |        |---
+ *  ----------  |     ----------  |
+ *              V                 V
+ *              --------          --------
+ *              | DATA |          | DATA |
+ *              | BLK  |          | BLK  |
+ *              --------          --------
+ *
+ *
+ *     ExpBuf
+ *   --------------
+ *   | readError  |
+ *   | writeError |
+ *   | dataStart  |-----------
+ *   | dataEnd    |--------  |
+ *   | curr       |------ |  |
+ *   | next       |     | |  |
+ *   | prev       |     | |  |            data
+ *   | blkStart   |=====|=|==|==>--------------------------
+ *   | blkEnd     |---  | |  |   |                        | (each line
+ *   --------------  |  | |  |   |                        |  reps a byte
+ *                   |  | |  |-->| - - - - - - - - - - - -|  diff in addr)
+ *                   |  | |      |       valid            |
+ *                   |  |-|----->|                        |
+ *                   |    |      |        data            |
+ *                   |    |      |                        |
+ *                   |    |      | - - - - - - - - - - - -|
+ *                   |    |----->|(one byte after last valid data byte)
+ *                   |           |                        |
+ *                   |           --------------------------
+ *                   |-----------> (one byte after last byte in data blk)
+ *
+ *
+ *   readError - set to non-zero to indicate attempt to read past end of
+ *               of data
+ *   writeError- set to non-zero to indicate write error.
+ *               Set if Alloc of new buf fails
+ *   dataStart - pts to first VALID data byte ie  *dataStart is first byte
+ *   dataEnd   - pts to byte AFTER last VALID byte *dataEnd is not in the data
+ *               but *(dataEnd -1) is in the data
+ *   curr      - used for current read ptr - points to next byte to be read
+ *               so *curr is the next byte to be read.
+ *   next      - pts to next BUF in list, NULL for last BUF in list
+ *   prev      - pts to prev BUF in list, NULL for first BUF in list
+ *   blkStart  - pts to start of the data blk. *blkStart is first byte
+ *               in the buffer's data blk.
+ *   blkEnd    - pts to byte AFTER last writable byte of the dataBlk.
+ *               *(blkEnd-1) is the last byte in the buffer's data blk.
+ *
+ * NOTES:
+ *   - dataEnd is currently always the same as blkEnd
+ *   - at End Of Data (EOD) (no more data to be read)
+ *     if (curr == dataEnd)
+ *   - buffer has no valid data if (dataStart == dataEnd)
+ *   - number of valid data bytes = (dataEnd - dataStart)
+ *   - size of the data block = (blkEnd - blkStart)
+ *
+ *   - the write reverse routines modify dataStart
+ *   - the read routines modify the curr ptr.
+ *   - there are no 'forward' write routines at the moment
+ *     (if there were they would adjust dataEnd)
+ *
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/exp-buf.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: exp-buf.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:32  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/27 09:05:29  rj
+ * merged type table routines and code used by its gen-bufs.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:46:05  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "gen-buf.h"
+#include "exp-buf.h"
+
+
+/* default buffer data block size (used when allocating) */
+unsigned long expBufDataBlkSizeG = 1024;
+
+
+#if defined (DEBUG) || defined (USE_GEN_BUF)  /* otherwise macros */
+
+#ifdef USE_GEN_BUF
+
+/*
+ * casts are used to overcome void * - ExpBuf * conflict
+ * be careful if you modify param lists etc.
+ */
+static struct GenBuf expBufOpsG =
+{
+  (BufGetByteFcn)    ExpBufGetByte,
+  (BufGetSegFcn)     ExpBufGetSeg,
+  (BufCopyFcn)       ExpBufCopy,
+  (BufSkipFcn)       ExpBufSkip,
+  (BufPeekByteFcn)   ExpBufPeekByte,
+  (BufPeekSegFcn)    ExpBufPeekSeg,
+  (BufPeekCopyFcn)   ExpBufPeekCopy,
+  (BufPutByteRvsFcn) ExpBufPutByteRvs,
+  (BufPutSegRvsFcn)  ExpBufPutSegRvs,
+  (BufReadErrorFcn)  ExpBufReadError,
+  (BufWriteErrorFcn) ExpBufWriteError,
+  NULL,
+  NULL
+};
+
+#endif
+
+/*
+ * remember: ExpBufs are used via a handle (double ptr)
+ * in the standardized buffer routines. This allows
+ * the 'current' expbuf in the list of expbuf to be the arg.
+ * The list is doubly linked so you can always find
+ * the head or tail given any expbuf in the list
+ */
+void
+PutExpBufInGenBuf PARAMS ((eb, gb),
+    ExpBuf *eb _AND_
+    GenBuf *gb)
+{
+    *gb = expBufOpsG; /* structure assignemnt */
+    gb->bufInfo = &gb->spare;  /* handle to expbuf */
+    gb->spare = eb;
+} /* PutExpBufInGenBuf */
+
+/*
+ * sets the size of the data block to attach to
+ * an ExpBuf when allocating a new one
+ */
+void
+ExpBufInit PARAMS ((dataBlkSize),
+    unsigned long dataBlkSize)
+{
+    expBufDataBlkSizeG = dataBlkSize;
+}  /* InitBuffers */
+
+/*
+ * Allocates and returns an uninitialized ExpBuf with
+ * no a data attached.
+ */
+ExpBuf*
+ExpBufAllocBuf()
+{
+    return (ExpBuf*)malloc (sizeof (ExpBuf));
+}
+
+void
+ExpBufFreeBuf PARAMS ((ptr),
+    ExpBuf *ptr)
+{
+    free (ptr);
+}
+
+char*
+ExpBufAllocData()
+{
+    return (char*)malloc (expBufDataBlkSizeG);
+}
+
+void
+ExpBufFreeData PARAMS ((ptr),
+    char *ptr)
+{
+    free (ptr);
+}
+
+void
+ExpBufFreeBufAndData PARAMS ((b),
+    ExpBuf *b)
+{
+    ExpBufFreeData ((b)->blkStart);
+    ExpBufFreeBuf (b);
+} /* ExpBufFreeBufAndData */
+
+ExpBuf*
+ExpBufNext PARAMS ((b),
+    ExpBuf *b)
+{
+    return b->next;
+}
+
+ExpBuf*
+ExpBufPrev PARAMS ((b),
+    ExpBuf *b)
+{
+    return b->prev;
+}
+
+int
+ExpBufReadError PARAMS ((b),
+    ExpBuf **b)
+{
+    return (*b)->readError;
+} /* ExpBufReadError */
+
+int
+ExpBufWriteError PARAMS ((b),
+    ExpBuf **b)
+{
+    return (*b)->writeError;
+} /* ExpBufWriteError */
+
+/*
+ * set curr ptr used in reads to the first byte
+ * to be read
+ */
+void
+ExpBufResetInReadMode PARAMS ((b),
+    ExpBuf *b)
+{
+    b->curr = b->dataStart;
+    b->readError = 0;
+    b->writeError = 1; /* catch wrong mode errors */
+}
+
+/*
+ * sets dataStart to end of buffer
+ * so following writes (backward)
+ * over-write any existing data associated with
+ * the buffer
+ */
+void
+ExpBufResetInWriteRvsMode PARAMS ((b),
+    ExpBuf *b)
+{
+    b->dataEnd = b->dataStart = b->blkEnd;
+    b->writeError = 0;
+    b->readError = 1;  /* catch wrong mode errors */
+}
+
+
+/*
+ * returns true if no more data can be read from
+ * the given buffer. only valid when buffer in read (fwd)
+ * mode.
+ */
+int
+ExpBufAtEod PARAMS ((b),
+    ExpBuf *b)
+{
+    return b->curr == b->dataEnd;
+}
+
+
+/*
+ * returns true if no more reverse writes can be done
+ * to the buffer.  Only valid when buffers in reverse
+ * write mode
+ */
+int
+ExpBufFull PARAMS ((b),
+    ExpBuf *b)
+{
+    return (b)->dataStart == (b)->blkStart;
+}
+
+
+/*
+ * returns true if the given buffer has no
+ * valid data in it's data block
+ */
+int
+ExpBufHasNoData PARAMS ((b),
+    ExpBuf *b)
+{
+    return b->dataStart == b->dataEnd;
+}
+
+
+/*
+ * returns the number of valid data bytes in the
+ * given buffer's data block
+ */
+unsigned long
+ExpBufDataSize PARAMS ((b),
+    ExpBuf *b)
+{
+    return b->dataEnd - b->dataStart;
+}
+
+/*
+ * returns size of data block that is attached to
+ * the given buffer.
+ */
+unsigned long
+ExpBufDataBlkSize PARAMS ((b),
+    ExpBuf *b)
+{
+    return b->blkEnd - b->blkStart;
+}
+
+/*
+ * returns a ptr the beginning of the valid data of
+ * the given buffer.
+ * returns NULL is there is no valid data.
+ */
+char*
+ExpBufDataPtr PARAMS ((b),
+    ExpBuf *b)
+{
+    if (ExpBufHasNoData (b))
+        return NULL;
+    else
+        return b->dataStart;
+}
+
+#endif /* DEBUG || USE_EXP_BUF */
+
+
+/*
+ * returns last ExpBuf in a list of bufs.
+ * The given buf can be any buf in the list.
+ */
+ExpBuf*
+ExpBufListLastBuf PARAMS ((b),
+    ExpBuf *b)
+{
+    for (; b->next != NULL; b = b->next)
+	;
+    return b;
+}
+
+/*
+ * returns first buf in a list of bufs .
+ * The given buf can be any buf in the list
+ */
+ExpBuf*
+ExpBufListFirstBuf PARAMS ((b),
+    ExpBuf *b)
+{
+    for (; b->prev != NULL; b = b->prev)
+	;
+    return b;
+}
+
+/*
+ *  Allocates a Buf and allocates an attaches a
+ *  data block of expBufDataBlkSizeG to that buffer.
+ *  sets up the blk for writing in that the data start
+ *  and data end point to the byte after the data blk.
+ */
+ExpBuf*
+ExpBufAllocBufAndData()
+{
+    ExpBuf *retVal;
+
+    retVal = ExpBufAllocBuf();
+
+    if (retVal == NULL)
+        return NULL;
+
+    retVal->readError = 0;
+    retVal->writeError = 0;
+    retVal->blkStart = ExpBufAllocData();
+
+    if (retVal->blkStart == NULL)
+    {
+        ExpBufFreeBuf (retVal);
+        return NULL;
+    }
+
+    retVal->next = NULL;
+    retVal->prev = NULL;
+    retVal->curr = retVal->blkEnd = retVal->dataStart = retVal->dataEnd =
+        retVal->blkStart + expBufDataBlkSizeG;
+
+    return retVal;
+} /* ExpBufAllocBufAndData */
+
+
+/*
+ * Frees ExpBuf's and associated data blocks after
+ * after (next ptr) and including the given buffer, b.
+ */
+void
+ExpBufFreeBufAndDataList PARAMS ((b),
+    ExpBuf *b)
+{
+    ExpBuf *tmp;
+
+    for (; b != NULL;)
+    {
+        tmp = b->next;
+        ExpBufFreeBufAndData (b);
+        b = tmp;
+    }
+}  /* ExpBufFreeBufAndDataList */
+
+
+/*
+ * puts the given data in a buffer and sets it up for reading
+ * the data.  This results in a "full" buffer with a data
+ * blk size of given data's len
+ */
+void
+ExpBufInstallDataInBuf PARAMS ((buf, data, len),
+    ExpBuf *buf _AND_
+    char *data _AND_
+    unsigned long int len)
+{
+    buf->readError = 0;
+    buf->writeError = 0;
+    buf->blkStart = buf->dataStart = buf->curr = data;
+    buf->next = NULL;
+    buf->prev = NULL;
+    buf->blkEnd = buf->dataEnd = data + len;
+}  /* ExpBufInstallDataInBuf */
+
+
+
+/*  Buf reading and writing routines follow */
+
+/* READ
+ * returns the next byte to be read without
+ * advancing the pointer. No check for end of
+ * data - this is lame
+ */
+unsigned char
+ExpBufPeekByte PARAMS ((b),
+    ExpBuf **b)
+{
+    if ((*b)->curr == (*b)->dataEnd)
+        (*b)->readError = 1;
+    return *(*b)->curr;
+}  /* ExpBufPeek */
+
+#if TTBL
+
+/*   READ
+ *   returns a ptr to the next "len" bytes (contiguous).
+ *   if "len" is greater than the available contiguous bytes
+ *   len is set the the number of contig. bytes the returned
+ *   ptr references. The next call to ExpBufGetSeg or other ExpBufGet
+ *   routines will return a ptrsto the SAME bytes (ie curr is NOT advanced).
+ *
+ *   Does not change the buffer
+ *
+ *   if the value returned in the len param is zero or the
+ *   returned char * is NULL then at end of data.
+ *
+ */
+char*
+ExpBufPeekSeg PARAMS ((b, len),
+    ExpBuf **b _AND_
+    unsigned long int *len)
+{
+    int bytesLeft;
+
+    if (ExpBufAtEod (*b))
+    {
+        *len = 0;
+        return NULL;
+    }
+
+    /* check for "buffer fault" and adjust "peeked" len */
+    if (((*b)->dataEnd - (*b)->curr) <= *len)
+        *len = bytesLeft;
+
+    return (*b)->curr;
+
+}  /* ExpBufPeekSeg */
+
+
+/*  READ
+ *  copy the next len chars in the buffer to the given
+ *  dst char string.  The curr ptr in the buffer is
+ *  NOT advanced so the next read will get the same bytes.
+ */
+int
+ExpBufPeekCopy PARAMS ((dst, b, len),
+    char *dst _AND_
+    ExpBuf **b _AND_
+    unsigned long int len)
+{
+    unsigned long int gotLen;
+    int totalGotLen = 0;
+    char *srcPtr;
+    ExpBuf *origBuf;
+
+    origBuf = *b;
+
+    gotLen = len;
+    while (1)   /* optimize std path - eg only one ExpBufGetPeekSeg needed */
+    {
+        srcPtr = ExpBufPeekSeg (b, &gotLen);
+        memcpy (dst + totalGotLen, srcPtr, gotLen);
+
+        totalGotLen += gotLen;
+
+        if ((totalGotLen >= len) ||  ((*b)->next == NULL))
+        {
+            *b = origBuf;
+            return totalGotLen;
+        }
+
+        if (gotLen == 0)  /* eod */
+        {
+            (*b)->readError = 1;
+            *b = origBuf;
+            return totalGotLen;
+        }
+
+        *b = (*b)->next;
+        /* get next buffer with valid data */
+        while (((*b)->next != NULL) && ExpBufHasNoData (*b))
+            *b = (*b)->next;
+
+        /* reset current pointer to beggining of data if nec */
+        (*b)->curr = (*b)->dataStart;
+
+        gotLen = len - totalGotLen;
+    }
+
+    /* not reached */
+
+}  /* ExpBufPeekCopy */
+
+#endif /* TTBL */
+
+/*  READ
+ *  copy the next len chars in the buffer  to the given
+ *  dst char string.  The curr ptr in the buffer is advanced
+ *  appropriately
+ */
+int
+ExpBufCopy PARAMS ((dst, b, len),
+    char *dst _AND_
+    ExpBuf **b _AND_
+    unsigned long int len)
+{
+    unsigned long int gotLen;
+    int totalGotLen = 0;
+    char *srcPtr;
+
+    gotLen = len;
+    while (1)         /* optimize std path - eg only one ExpBufGetSeg needed */
+    {
+        srcPtr = ExpBufGetSeg (b, &gotLen);
+        memcpy (dst + totalGotLen, srcPtr, gotLen);
+
+        totalGotLen += gotLen;
+
+        if (totalGotLen >= len)
+            return totalGotLen;
+
+        if (gotLen == 0)  /* eod */
+        {
+            (*b)->readError = 1;
+            return totalGotLen;
+        }
+
+        gotLen = len - totalGotLen;
+    }
+
+    /* not reached */
+
+}  /* ExpBufCopy */
+
+
+/*
+ * advance the curr ptr in the given buffer over the next
+ * len bytes
+ */
+void
+ExpBufSkip PARAMS ((b, len),
+    ExpBuf **b _AND_
+    unsigned long int len)
+{
+    unsigned long int lenRemaining;
+
+    lenRemaining = len;
+    while ((len > 0) && ExpBufGetSeg (b, &lenRemaining))
+    {
+        len -= lenRemaining;
+
+        if (lenRemaining == 0)
+        {
+            (*b)->readError = 1;
+            return;
+        }
+
+        lenRemaining = len;
+    }
+}  /* ExpBufSkip */
+
+
+/*   READ
+ *   returns a ptr to the next "len" bytes (contiguous).
+ *   if "len" is greater than the available contiguous bytes
+ *   len is set the the number of contig. bytes the returned
+ *   ptr references. Subsequent call to ExpBufGetSeg or other ExpBufGet
+ *   routines will return ptrs to the following bytes (ie curr is advanced).
+ *   Changes *b to pt to the next buffer and sets curr for the
+ *   that buffer to dataStart if the current one has been totally read.
+ *
+ *   if the value returned in the len param is zero or the
+ *   returned char * is NULL then at end of data (eod)
+ *
+ */
+
+char*
+ExpBufGetSeg PARAMS ((b, len),
+    ExpBuf **b _AND_
+    unsigned long int *len)
+{
+    int bytesLeft;
+    char *retVal;
+
+    if (ExpBufAtEod (*b))
+    {
+        *len = 0;
+        return NULL;
+    }
+
+    bytesLeft = (*b)->dataEnd - (*b)->curr;
+    retVal = (*b)->curr;
+
+    /* check for "buffer fault" */
+    if (bytesLeft <= *len)
+    {
+        *len = bytesLeft;
+
+        if ((*b)->next != NULL)
+        {
+            *b = (*b)->next;
+
+            /* get next buffer with valid data */
+            while (((*b)->next != NULL) && ExpBufHasNoData (*b))
+                *b = (*b)->next;
+
+            /* reset current pointer to beggining of data if nec */
+            (*b)->curr = (*b)->dataStart;
+        }
+        else
+            (*b)->curr += *len;
+    }
+    else
+        (*b)->curr += *len;
+
+    return retVal;
+
+}  /* ExpBufGetSeg */
+
+
+
+/*
+ *   WRITE
+ *   Copies len bytes from the data pointer into the given buffer
+ *
+ *   FILLS EXP_BUFFERS BACKWARDS! from the end of the data to the beginning
+ *   LINKS BUFFERS BACKWARDS! if a buf is full it allocs another an
+ *                            puts it at the HEAD of the buffer list
+ *
+ *   changes *b to pt to the new "prev" buffer if the current one
+ *   has been totally filled
+ *   Rvs is for REVERSE!
+ *
+ *   modifies the dataStart pointer to reflect the new data
+ */
+
+void
+ExpBufPutSegRvs PARAMS ((b, data, len),
+    ExpBuf **b _AND_
+    char *data _AND_
+    unsigned long int len)
+{
+    int bytesLeft;
+    ExpBuf *buf;
+    char *dataPtr;
+
+    buf = *b;
+
+    if (buf->writeError)
+        return;
+
+    bytesLeft = buf->dataStart - buf->blkStart;
+    dataPtr = data + len;  /* pts to end of data to be written */
+
+    /* optimize fast path */
+
+    do
+    {
+        if (bytesLeft > len) /* enough room in this buffer for write */
+        {
+            buf->dataStart -= len;
+            memcpy (buf->dataStart, data, len);
+            break; /* this is the normal exit from this loop */
+        }
+        else
+        {
+            /*
+             * going to fill this buffer completely,
+             * so alloc other one (only if one is not
+             * already linked in)
+             */
+            dataPtr  = dataPtr - bytesLeft;
+            buf->dataStart = buf->blkStart;
+            memcpy (buf->dataStart, dataPtr, bytesLeft);
+
+            len -= bytesLeft;
+
+            if (buf->prev == NULL)
+            {
+                /* alloc & insert new buf at head of buffer list */
+                buf = ExpBufAllocBufAndData();
+
+                if (buf == NULL)
+                {
+                    (*b)->writeError = 1;
+                    return;
+                }
+
+                buf->next = *b;
+                (*b)->prev = buf;
+            }
+            else
+                buf = buf->prev;
+
+            *b = buf; /* update head of list */
+
+            bytesLeft = buf->dataStart - buf->blkStart;
+        }
+    }
+    while (1);
+
+    /* not reached */
+
+}  /* ExpBufPutSegRvs */
+
+
+
+/*
+ *   returns the next byte and advances the curr ptr by one.
+ *   sets the readError flag if there is no byte to read
+ *   (ie at end of data)
+ */
+unsigned char
+ExpBufGetByte PARAMS ((b),
+    ExpBuf **b)
+{
+    unsigned char retVal;
+
+
+    if (ExpBufAtEod (*b))
+    {
+        (*b)->readError = 1;
+        return (unsigned char)0;
+    }
+
+    retVal = *(*b)->curr++;
+
+    /* "buffer fault" - if end of this buf, go on to next, if any */
+    if (ExpBufAtEod (*b) && ((*b)->next != NULL))
+    {
+        *b = (*b)->next;
+
+        /* get next buffer with valid data */
+        while (((*b)->next != NULL) && ExpBufHasNoData (*b))
+            *b = (*b)->next;
+
+        /* reset current pointer to beggining of data if nec */
+        (*b)->curr = (*b)->dataStart;
+    }
+
+    return retVal;
+
+}  /* ExpBufGetByte */
+
+
+/* WRITE
+ * Puts a single octet into the buffer
+ * writes in reverse.
+ * allocates new buffers as nec - may change
+ * (*b) to new buffer since writing backwards
+ */
+void
+ExpBufPutByteRvs PARAMS ((b, byte),
+    ExpBuf **b _AND_
+    unsigned char byte)
+{
+    ExpBuf *new;
+
+    if ((*b)->writeError)
+        return;
+
+    *(--(*b)->dataStart) = byte;
+
+    /*
+     * check if buffer is full and alloc new one if nec
+     * and insert it before this one since writing backwards
+     */
+    if (ExpBufFull (*b))
+    {
+        if ((*b)->prev == NULL)
+        {
+            /*
+             * no prev buf so alloc & insert
+             * new buf as head of buffer list
+             */
+            new = ExpBufAllocBufAndData();
+            if (new == NULL)
+            {
+                (*b)->writeError = 1;
+                return;
+            }
+
+            new->next = *b;
+            (*b)->prev = new;
+            *b = new;
+        }
+        else
+        {
+            (*b) = (*b)->prev;
+            ExpBufResetInWriteRvsMode (*b);
+        }
+
+    }
+} /* ExpBufPutByteRvs */
+
+
+void
+ExpBufCopyToFile PARAMS ((b, f),
+    ExpBuf *b _AND_
+    FILE *f)
+{
+    long int writeLen;
+
+    b = ExpBufListFirstBuf (b);
+
+    for ( ; b != NULL; b = ExpBufNext (b))
+    {
+        writeLen = fwrite (ExpBufDataPtr (b), sizeof (char), ExpBufDataSize (b), f);
+
+        if (writeLen != ExpBufDataSize (b))
+            fprintf (stderr, "ExpBufCopyToFile: error during writing\n");
+    }
+}
+
+#else /* !USE_EXP_BUF */
+
+#ifdef __alpha
+static void dummy()
+{
+}
+#endif
+
+#endif /* USE_EXP_BUF */
diff --git a/SecuritySNACCRuntime/c-lib/src/hash.c b/SecuritySNACCRuntime/c-lib/src/hash.c
new file mode 100644
index 00000000..c34970b6
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/hash.c
@@ -0,0 +1,274 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * This was borrowed from Don Acton and Terry Coatta's Raven Code.
+ * It has been modified somewhat.
+ *    - Mike Sample 92
+ *
+ * This is a set or routines that implements an extensible hashing
+ * algorithm. At the moment it assumes that all the hash codes are unique
+ * (ie. there are no collisions). For the way hash codes are currently being
+ * supplied this is not a bad assumption.
+ * The extensible hashing routine used is based on a multiway tree with
+ * each node in the tree being a fixed array of (2^n) size. At a given
+ * level, i, in the tree with the first level being level 0, bits
+ * i*n through i*n through (i+1)*n-1 are used as the index into the table.
+ * Each entry in the table is either NULL (unused) or a pointer to an
+ * object of type entry. The entry contains all the information about a
+ * hash entry. The entry also contains a field indicating whether or not this
+ * is a leaf node. If an entry isn't a leaf node then it references a table at
+ * at the next level and not a value. With the current implementation
+ * a 32 hash value is used and table sizes are 256. The algorithm used
+ * here is the same as the one used in the Set class of the Raven
+ * class system.
+ *
+ * Copyright (C) 1992 University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/hash.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: hash.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:32  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1997/02/28 13:39:51  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.2  1995/07/27 09:05:54  rj
+ * use memzero that is defined in .../snacc.h to use either memset or bzero.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:46:06  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "hash.h"
+
+
+/*
+ *
+ * From sdbm, an ndbm work-alike hashed database library
+ * Author: oz@nexus.yorku.ca
+ * Status: public domain.
+ *
+ * polynomial conversion ignoring overflows
+ * [this seems to work remarkably well, in fact better
+ * then the ndbm hash function. Replace at your own risk]
+ * use: 65599   nice.
+ *      65587   even better.
+ *
+ * [In one experiment, this function hashed 84165 symbols (English words
+ * plus symbol table values) with no collisions. -bjb]
+ *
+ */
+
+Hash
+MakeHash PARAMS ((str, len),
+    char *str _AND_
+    unsigned long int len)
+{
+    register Hash n;
+    n = 0;
+
+#define HASHC   n = *str++ + 65587 * n
+
+    if (len > 0)
+    {
+        int loop;
+        loop = (len + 8 - 1) >> 3;
+        switch (len & (8 - 1))
+	{
+          case 0:
+            do
+	    {
+                HASHC;
+              case 7: HASHC;
+              case 6: HASHC;
+              case 5: HASHC;
+              case 4: HASHC;
+              case 3: HASHC;
+              case 2: HASHC;
+              case 1: HASHC;
+	    } while (--loop);
+	}
+    }
+    return n;
+}
+
+/* Creates and clears a new hash slot */
+static HashSlot*
+NewHashSlot()
+{
+  HashSlot *foo;
+
+  foo = (HashSlot *) malloc (sizeof (HashSlot));
+  if (foo == NULL)
+      return NULL;
+  memzero (foo, sizeof (HashSlot));
+  return foo;
+}
+
+/* Create a new cleared hash table */
+static Table*
+NewTable()
+{
+  Table *new_table;
+
+  new_table = (Table *) malloc (sizeof (Table));
+  if (new_table == NULL)
+      return NULL;
+  memzero (new_table, sizeof (Table));
+  return new_table;
+}
+
+/* This routine is used to initialize the hash tables. When it is called
+ * it returns a value which is used to identify which hash table
+ * a particular request is to operate on.
+ */
+Table*
+InitHash()
+{
+  Table *table;
+  table = NewTable();
+  if (table == NULL)
+      return 0;
+  else
+      return table;
+}
+
+/* When a hash collision occurs at a leaf slot this routine is called to
+ * split the entry and add a new level to the tree at this point.
+ */
+static int
+SplitAndInsert PARAMS ((entry, element, hash_value),
+    HashSlot *entry _AND_
+    void *element _AND_
+    Hash hash_value)
+{
+
+  if (((entry->table = NewTable()) == NULL) ||
+      !Insert (entry->table, entry->value, entry->hash >> INDEXSHIFT) ||
+      !Insert (entry->table, element, hash_value >> INDEXSHIFT))
+    return FALSE;
+
+  entry->leaf = FALSE;
+  return TRUE;
+}
+
+/* This routine takes a hash table identifier, an element (value) and the
+ * coresponding hash value for that element and enters it into the table
+ * assuming it isn't already there.
+ */
+int
+Insert PARAMS ((table, element, hash_value),
+    Table *table _AND_
+    void *element _AND_
+    Hash hash_value)
+{
+  HashSlot *entry;
+
+  entry = (HashSlot *) (*table)[hash_value & INDEXMASK];
+
+  if (entry == NULL) {
+    /* Need to add this element here */
+    entry = NewHashSlot();
+    if (entry == NULL)
+        return FALSE;
+    entry->leaf = TRUE;
+    entry->value = element;
+    entry->hash = hash_value;
+    (*table)[hash_value & INDEXMASK] = (void*)entry;
+    return TRUE;
+  }
+
+  if (hash_value == entry->hash)
+      return TRUE;
+
+  if (entry->leaf)
+      return SplitAndInsert (entry, element, hash_value);
+
+  return Insert (entry->table, element, hash_value >> INDEXSHIFT);
+}
+
+
+/* This routine looks to see if a particular hash value is already stored in
+ * the table. It returns true if it is and false otherwise.
+ */
+int
+CheckFor PARAMS ((table, hash),
+    Table *table _AND_
+    Hash hash)
+{
+  HashSlot *entry;
+
+  entry = (HashSlot *) table[hash & INDEXMASK];
+
+  if (entry == NULL)
+      return FALSE;
+  if (entry->leaf)
+      return entry->hash == hash;
+  return CheckFor (entry->table, hash >> INDEXSHIFT);
+}
+
+/* In addition to checking for a hash value in the tree this function also
+ * returns the coresponding element value into the space pointed to by
+ * the value parameter. If the hash value isn't found FALSE is returned
+ * the the space pointed to by value is not changed.
+ */
+int
+CheckForAndReturnValue PARAMS ((table, hash, value),
+    Table *table _AND_
+    Hash hash _AND_
+    void **value)
+{
+  HashSlot *entry;
+  entry = (HashSlot *) (*table)[hash & INDEXMASK];
+
+  if (entry == NULL)
+      return FALSE;
+
+  if (entry->leaf)
+  {
+      if (entry->hash == hash)
+      {
+          *value = entry->value;
+          return TRUE;
+      }
+      else
+          return FALSE;
+  }
+  return CheckForAndReturnValue (entry->table, hash >> INDEXSHIFT, value);
+}
diff --git a/SecuritySNACCRuntime/c-lib/src/nibble-alloc.c b/SecuritySNACCRuntime/c-lib/src/nibble-alloc.c
new file mode 100644
index 00000000..0a2502df
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/nibble-alloc.c
@@ -0,0 +1,231 @@
+/*
+ * 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-lib/src/nibble-alloc.c - fast mem allocation for decoded values
+ *
+ * MS Dec 31/91
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/nibble-alloc.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: nibble-alloc.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:32  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1997/02/28 13:39:51  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.3  1995/07/27 09:06:37  rj
+ * use memzero that is defined in .../snacc.h to use either memset or bzero.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:07:16  rj
+ * more portable .h file inclusion.
+ *
+ * Revision 1.1  1994/08/28  09:46:07  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+/* An ANSI string.h and pre-ANSI memory.h might conflict. */
+#if !STDC_HEADERS && HAVE_MEMORY_H
+#include <memory.h>
+#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
+#endif /* not STDC_HEADERS and not HAVE_STRING_H */
+
+#include "nibble-alloc.h"
+
+
+NibbleMem *nmG = NULL;
+
+void
+InitNibbleMem PARAMS ((initialSize, incrementSize),
+    unsigned long int initialSize _AND_
+    unsigned long int incrementSize)
+{
+    NibbleMem *nm;
+
+    nm = (NibbleMem*) malloc (sizeof (NibbleMem));
+    nm->incrementSize = incrementSize;
+
+    nm->currNibbleBuf = nm->firstNibbleBuf = (NibbleBuf*)malloc (sizeof (NibbleBuf));
+    nm->firstNibbleBuf->curr = nm->firstNibbleBuf->start = (char*) malloc (initialSize);
+    nm->firstNibbleBuf->end = nm->firstNibbleBuf->start + initialSize;
+    nm->firstNibbleBuf->next = NULL;
+    memzero (nm->currNibbleBuf->start, initialSize);
+
+    nmG = nm;/* set global */
+
+}  /* InitNibbleAlloc */
+
+
+/*
+ * alloc new nibble buf, link in, reset to curr nibble buf
+ */
+void
+ServiceNibbleFault PARAMS ((size),
+    unsigned long size)
+{
+    NibbleMem *nm;
+    unsigned long newBufSize;
+
+    nm = nmG;
+
+    if (size > nm->incrementSize)
+        newBufSize = size;
+    else
+        newBufSize = nm->incrementSize;
+
+    nm->currNibbleBuf->next = (NibbleBuf*) malloc (sizeof (NibbleBuf));
+    nm->currNibbleBuf = nm->currNibbleBuf->next;
+    nm->currNibbleBuf->curr = nm->currNibbleBuf->start = (char*) malloc (newBufSize);
+    nm->currNibbleBuf->end = nm->currNibbleBuf->start + newBufSize;
+    nm->currNibbleBuf->next = NULL;
+    memzero (nm->currNibbleBuf->start, newBufSize);
+} /* serviceNibbleFault */
+
+
+
+/*
+ * returns requested space filled with zeros
+ */
+void*
+NibbleAlloc PARAMS ((size),
+    unsigned long size)
+{
+    NibbleMem *nm;
+    char *retVal;
+    unsigned long ndiff;
+
+    nm = nmG;
+
+    if ((nm->currNibbleBuf->end - nm->currNibbleBuf->curr) < size)
+         ServiceNibbleFault (size);
+
+    retVal = nm->currNibbleBuf->curr;
+
+    /*
+     * maintain word alignment
+     */
+    ndiff = size % sizeof (long);
+    if (ndiff != 0)
+    {
+        nm->currNibbleBuf->curr += size + sizeof (long) - ndiff;
+
+        /*
+         * this is a fix from Terry Sullivan <FCLTPS@nervm.nerdc.ufl.edu>
+         *
+         * makes sure curr does not go past the end ptr
+         */
+        if (nm->currNibbleBuf->curr > nm->currNibbleBuf->end)
+            nm->currNibbleBuf->curr = nm->currNibbleBuf->end;
+    }
+    else
+        nm->currNibbleBuf->curr += size;
+
+    return retVal;
+}  /* NibbleAlloc */
+
+
+
+/*
+ * frees all nibble buffers except the first,
+ * resets the first to empty and zero's it
+ */
+void
+ResetNibbleMem()
+{
+    NibbleMem *nm;
+    NibbleBuf *tmp;
+    NibbleBuf *nextTmp;
+
+    nm = nmG;
+
+    /*
+     * reset first nibble buf
+     */
+    memzero (nm->firstNibbleBuf->start, nm->firstNibbleBuf->curr - nm->firstNibbleBuf->start);
+
+    nm->firstNibbleBuf->curr = nm->firstNibbleBuf->start;
+
+    /*
+     * free incrementally added nibble bufs
+     */
+    for (tmp = nm->firstNibbleBuf->next; tmp != NULL; )
+    {
+        free (tmp->start);
+        nextTmp = tmp->next;
+        free (tmp);
+        tmp = nextTmp;
+    }
+
+    /* From ftp://ftp.cs.ubc.ca/pub/local/src/snacc/bugs-in-1.1 */
+    nm->firstNibbleBuf->next = NULL;
+    nm->currNibbleBuf = nm->firstNibbleBuf;
+
+} /* ResetNibbleMem */
+
+
+/*
+ * frees all nibble buffers, closing this
+ * NibbleMem completely
+ */
+void
+ShutdownNibbleMem()
+{
+    NibbleMem *nm;
+    NibbleBuf *tmp;
+    NibbleBuf *nextTmp;
+
+    nm = nmG;
+    nmG = NULL;
+    /*
+     * free nibble bufs
+     */
+    for (tmp = nm->firstNibbleBuf; tmp != NULL; )
+    {
+        free (tmp->start);
+        nextTmp = tmp->next;
+        free (tmp);
+        tmp = nextTmp;
+    }
+
+    free (nm);
+} /* ShutdownNibbleMem */
diff --git a/SecuritySNACCRuntime/c-lib/src/print.c b/SecuritySNACCRuntime/c-lib/src/print.c
new file mode 100644
index 00000000..240b78f0
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/print.c
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * print.c - library routines for printing ASN.1 values.
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/print.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: print.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:25  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:32  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1997/03/13 09:15:19  wan
+ * Improved dependency generation for stupid makedepends.
+ * Corrected PeekTag to peek into buffer only as far as necessary.
+ * Added installable error handler.
+ * Fixed small glitch in idl-code generator (Markku Savela <msa@msa.tte.vtt.fi>).
+ *
+ * Revision 1.2  1995/07/24 21:04:55  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:46:08  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "print.h"
+
+unsigned short int stdIndentG = 4;
+
+
+void
+Indent PARAMS ((f, i),
+    FILE *f _AND_
+    unsigned short int i)
+{
+    for (; i > 0; i--)
+        fputc (' ', f);  /* this may be slow */
+}
+
+void Asn1DefaultErrorHandler PARAMS ((str, severity),
+    char* str _AND_
+    int severity)
+{
+    fprintf(stderr,"%s",str);
+}
+
+static Asn1ErrorHandler asn1CurrentErrorHandler = Asn1DefaultErrorHandler;
+
+void
+Asn1Error PARAMS ((str),
+    char* str)
+{
+    (*asn1CurrentErrorHandler)(str,1);
+}
+
+void
+Asn1Warning PARAMS ((str),
+    char* str)
+{
+    (*asn1CurrentErrorHandler)(str,0);
+}
+
+Asn1ErrorHandler
+Asn1InstallErrorHandler PARAMS ((handler),
+    Asn1ErrorHandler handler)
+{
+    Asn1ErrorHandler former = asn1CurrentErrorHandler;
+    asn1CurrentErrorHandler = handler;
+    return former;
+}
+
diff --git a/SecuritySNACCRuntime/c-lib/src/sbuf.c b/SecuritySNACCRuntime/c-lib/src/sbuf.c
new file mode 100644
index 00000000..7bf05c63
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/sbuf.c
@@ -0,0 +1,405 @@
+/*
+ * 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-lib/src/sbuf.c
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *  MS
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifdef USE_GEN_BUF
+
+#include "asn-config.h"
+#include "gen-buf.h"
+#include "sbuf.h"
+
+/*
+ * casts are used to overcome void * - SBuf * conflict
+ * be careful if you modify param lists etc.
+ */
+static struct GenBuf sBufOpsG =
+{
+  (BufGetByteFcn)    SBufGetByte,
+  (BufGetSegFcn)     SBufGetSeg,
+  (BufCopyFcn)       SBufCopy,
+  (BufSkipFcn)       SBufSkip,
+  (BufPeekByteFcn)   SBufPeekByte,
+  (BufPeekSegFcn)    SBufPeekSeg,
+  (BufPeekCopyFcn)   SBufPeekCopy,
+  (BufPutByteRvsFcn) SBufPutByteRvs,
+  (BufPutSegRvsFcn)  SBufPutSegRvs,
+  (BufReadErrorFcn)  SBufReadError,
+  (BufWriteErrorFcn) SBufWriteError,
+  NULL,
+  NULL
+};
+
+void
+PutSBufInGenBuf PARAMS ((sb, gb),
+    SBuf *sb _AND_
+    GenBuf *gb)
+{
+    *gb = sBufOpsG; /* structure assignemnt */
+    gb->bufInfo = sb;
+}
+
+/*
+ * given an SBuf,b, and a block of data
+ * and its length this initializes a the SBuf
+ * to point to the data block.  The data
+ * block is assumed to contain no valid data-
+ * ie it is empty and ready for writing
+ */
+void
+SBufInit PARAMS ((b, data, dataLen),
+    SBuf *b _AND_
+    char *data _AND_
+    long int dataLen)
+{
+    b->readError = b->writeError = 1;
+    b->blkStart = data;
+    b->blkEnd = data + dataLen;
+    b->dataStart = b->dataEnd = b->readLoc = b->blkEnd;
+}  /* SBufInit */
+
+
+/*
+ * puts the given buffer in read mode and sets
+ * the current read location to the beginning of
+ * the buffer's data.
+ * The read error flag is cleared.
+ * The writeError flag is set so that attempted writes
+ * will be fail and be detectable via a call to
+ * SBufWriteError().
+ */
+void
+SBufResetInReadMode PARAMS ((b),
+    SBuf *b)
+{
+    b->readLoc = b->dataStart;
+    b->readError = 0;
+    b->writeError = 1;
+} /* SBufResetInnReadMode */
+
+
+/*
+ * puts the given buffer in reverse writing mode and sets
+ * the current write location to the end of the
+ * buffer's data block.
+ * The data start and end pointers are set to point to
+ * the end of the block - ie no data.
+ * The write error flag is cleared.
+ * The readError flag is set so that attempted reads
+ * will be fail and be detectable via a call to
+ * SBufReadError().
+ */
+void
+SBufResetInWriteRvsMode PARAMS ((b),
+    SBuf *b)
+{
+    b->dataStart = b->dataEnd = b->blkEnd;
+    b->writeError = 0;
+    b->readError = 1;
+} /* SBufResetInWriteRvsMode */
+
+/*
+ * installs given block of data into a buffer
+ * and sets it up for reading
+ */
+void
+SBufInstallData PARAMS ((b, data, dataLen),
+    SBuf *b _AND_
+    char *data _AND_
+    long int dataLen)
+{
+    SBufInit (b, data, dataLen);
+    b->dataStart = b->blkStart;
+    SBufResetInReadMode (b);
+} /* SBufInstallData */
+
+/*
+ * returns the number of bytes in the data portion
+ */
+long int
+SBufDataLen PARAMS ((b),
+    SBuf *b)
+{
+    return b->dataEnd - b->dataStart;
+} /* SBufDataLen */
+
+/*
+ *  returns the pointer to the first data byte
+ */
+char*
+SBufDataPtr PARAMS ((b),
+    SBuf *b)
+{
+  b->dataStart;
+} /* SBufDataPtr */
+
+/*
+ * returns the size of block, the maximum size for data
+ * (does not look at how much data is present, just the
+ * max size if the block were empty)
+ */
+long int
+SBufBlkLen PARAMS ((b),
+    SBuf *b)
+{
+    return b->blkEnd - b->blkStart;
+} /* SBufBlkLen */
+
+/*
+ * returns a pointer to the first byte of the block
+ */
+char*
+SBufBlkPtr PARAMS ((b),
+    SBuf *b)
+{
+    return b->blkStart;
+} /* SBufBlkPtr */
+
+/*
+ *  returns true if there is no more data
+ *  to be read in the SBuf
+ */
+int
+SBufEod PARAMS ((b),
+    SBuf *b)
+{
+  return b->readLoc >= b->dataEnd;
+} /* SBufEod */
+
+
+/* returns true if you attempted to read past the end of data */
+int
+SBufReadError PARAMS ((b),
+    SBuf *b)
+{
+    return b->readError;
+} /* SBufReadError */
+
+/*
+ * returns true if you attempted to write past the end of the block
+ * (remember SBufs do not expand like ExpBufs)
+ */
+int
+SBufWriteError PARAMS ((b),
+    SBuf *b)
+{
+    return b->writeError;
+} /* SBufWriteError */
+
+/*
+ *  Skips the next skipLen bytes for reading
+ */
+void
+SBufSkip PARAMS ((b, skipLen),
+    SBuf *b _AND_
+    long int skipLen)
+{
+    if (b->readLoc + skipLen > b->dataEnd)
+    {
+        b->readLoc = b->dataEnd;
+        b->readError = 1;
+    }
+    else
+        b->readLoc += skipLen;
+} /* SBufSkip */
+
+
+/*
+ * copies copyLen bytes from buffer b into char *dst.
+ * Advances the curr read loc by copyLen
+ * Assumes dst is pre-allocated and is large enough.
+ * Will set the read error flag is you attempt to copy
+ * more than the number of unread bytes available.
+ */
+void
+SBufCopy PARAMS ((dst, b, copyLen),
+    char *dst _AND_
+    SBuf *b _AND_
+    long int copyLen)
+{
+    if (b->readLoc + copyLen > b->dataEnd)
+    {
+        memcpy (dst, b->readLoc, b->dataEnd - b->readLoc);
+        b->readLoc = b->dataEnd;
+        b->readError = 1;
+    }
+    else
+    {
+        memcpy (dst, b->readLoc, copyLen);
+        b->readLoc += copyLen;
+    }
+} /* SBufCopy */
+
+
+/*
+ * returns the next byte from the buffer without advancing the
+ * current read location.
+ */
+unsigned char
+SBufPeekByte PARAMS ((b),
+    SBuf *b)
+{
+    if (SBufEod (b))
+    {
+        b->readError = 1;
+        return (unsigned char)0;
+    }
+    else
+        return (unsigned char) *b->readLoc;
+} /* SBufPeekByte */
+
+#if TTBL
+
+/*
+ * returns a pointer into the buffer to the next bytes to be read.
+ * If *lenPtr unread bytes are not available, *lenPtr will be set
+ * to the number of bytes that are available.  The current read location
+ * is *NOT* advanced at all.  The read error flag will NOT be set
+ *  by this routine.
+ */
+char*
+SBufPeekSeg PARAMS ((b, lenPtr),
+    SBuf *b _AND_
+    long int *lenPtr)
+{
+    if (b->readLoc + *lenPtr > b->dataEnd)
+         *lenPtr = b->dataEnd - b->readLoc;
+
+    return b->readLoc;
+} /* SBufPeekSeg */
+
+
+
+/*
+ * copies copyLen bytes from buffer b into char *dst.
+ * Does NOT advance the curr read location.
+ * assumes dst is pre-allocated and is large enough.
+ * Will set the read error flag is you attempt to copy
+ * more than the number of unread bytes available.
+ */
+void
+SBufPeekCopy PARAMS ((dst, b, copyLen),
+    char *dst _AND_
+    SBuf *b _AND_
+    long int copyLen)
+{
+    if (b->readLoc + copyLen > b->dataEnd)
+    {
+        memcpy (dst, b->readLoc, b->dataEnd - b->readLoc);
+        b->readError = 1;
+    }
+    else
+        memcpy (dst, b->readLoc, copyLen);
+
+} /* SBufCopy */
+
+#endif /* TTBL */
+
+/*
+ * returns a pointer into the buffer to the next bytes to be read.
+ * If *lenPtr unread bytes are not available, *lenPtr will be set
+ * to the number of bytes that are available.  The current read location
+ * is advance by the number of bytes returned in *lenPtr.  The read error
+ * flag will NOT be set, ever, by this routine.
+ */
+char*
+SBufGetSeg PARAMS ((b, lenPtr),
+    SBuf *b _AND_
+    long int *lenPtr)
+{
+    char *retVal;
+    retVal = b->readLoc;
+
+    if (b->readLoc + *lenPtr > b->dataEnd)
+    {
+         *lenPtr = b->dataEnd - b->readLoc;
+         b->readLoc = b->dataEnd;
+    }
+    else
+        b->readLoc += *lenPtr;
+
+    return retVal;
+} /* SBufGetSeg */
+
+/*
+ * Write in reverse the char *seg of segLen bytes to the buffer b.
+ * A reverse write of segement really just prepends the given seg
+ * (in original order) to the buffers existing data.
+ * If the SBuf does not have enough room for the segment,
+ * the writeError flag is set and *NO* copying is done at all.
+ */
+void
+SBufPutSegRvs PARAMS ((b, seg, segLen),
+    SBuf *b _AND_
+    char *seg _AND_
+    long int segLen)
+{
+    if (b->dataStart - segLen < b->blkStart)
+        b->writeError = 1;
+    else
+    {
+        b->dataStart -= segLen;
+        memcpy (b->dataStart, seg, segLen);
+    }
+} /* SBufPutSegRvs */
+
+/*
+ * returns the next byte from buffer b's data and advances the
+ * current read location by one byte.  This will set the read error
+ * flag if you attempt to read past the end of the SBuf
+ */
+unsigned char
+SBufGetByte PARAMS ((b),
+    SBuf *b)
+{
+    if (SBufEod (b))
+        b->readError = 1;
+    else
+        return (unsigned char)(*(b->readLoc++));
+} /* SBufGetByte */
+
+
+/*
+ * writes (prepends) the given byte to buffer b's data
+ */
+void
+SBufPutByteRvs PARAMS ((b, byte),
+    SBuf *b _AND_
+    unsigned char byte)
+{
+    if (b->dataStart <= b->blkStart)
+        b->writeError = 1;
+    else
+        *--b->dataStart = byte;
+} /* SBufPutByteRvs */
+
+#endif /* USE_GEN_BUF */
diff --git a/SecuritySNACCRuntime/c-lib/src/str-stk.c b/SecuritySNACCRuntime/c-lib/src/str-stk.c
new file mode 100644
index 00000000..1ea0a837
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/str-stk.c
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * str_stk.c  - maintains a stack of the components of a bit string
+ *        or octet string so they can be copied into a single chunk
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-lib/src/str-stk.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: str-stk.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:26  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:32  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/07/24 21:04:57  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.1  1994/08/28  09:46:09  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-config.h"
+#include "str-stk.h"
+
+/* global for use by AsnBits and AsnOcts */
+
+StrStk strStkG = { NULL, 128, 0, 64, 0, 0 };
diff --git a/SecuritySNACCRuntime/c-lib/src/tbl-dbg.c b/SecuritySNACCRuntime/c-lib/src/tbl-dbg.c
new file mode 100644
index 00000000..4f50c0e9
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/tbl-dbg.c
@@ -0,0 +1,466 @@
+/*
+ * 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.
+ */
+
+
+#ifdef TTBL
+#include "tbl-dbg.h"
+
+TdeExceptionCode DBGMinCode = TDEINFO;
+
+void DBGOcts PARAMS ((v),
+   AsnOcts* v)
+{
+    int i;
+    for (i = 0; i < v->octetLen; i++)
+	fprintf (stdout, "%c", isprint(v->octs[i])?v->octs[i]:'.');
+}
+
+char*
+Class2ClassStr PARAMS ((class),
+    int class)
+{
+    switch (class)
+    {
+        case UNIV:
+            return "UNIV";
+            break;
+
+        case APPL:
+            return "APPL";
+            break;
+
+        case CNTX:
+            return "CNTX";
+            break;
+
+        case PRIV:
+            return "PRIV";
+            break;
+
+        default:
+            return "UNKNOWN";
+            break;
+    }
+}
+
+char*
+Form2FormStr PARAMS ((form),
+    BER_FORM form)
+{
+    switch (form)
+    {
+        case PRIM:
+            return "PRIM";
+            break;
+
+        case CONS:
+            return "CONS";
+            break;
+
+        default:
+            return "UNKNOWN";
+            break;
+    }
+}
+
+char*
+Code2UnivCodeStr PARAMS ((code),
+    BER_UNIV_CODE code)
+{
+    switch (code)
+    {
+      case BOOLEAN_TAG_CODE:
+        return "BOOLEAN";
+        break;
+
+      case INTEGER_TAG_CODE:
+        return "INTEGER";
+        break;
+
+      case BITSTRING_TAG_CODE:
+        return "BIT STRING";
+        break;
+
+      case OCTETSTRING_TAG_CODE:
+        return "OCTET STRING";
+        break;
+
+      case NULLTYPE_TAG_CODE:
+        return "NULL";
+        break;
+
+      case OID_TAG_CODE:
+        return "OBJECT IDENTIFIER";
+        break;
+
+      case OD_TAG_CODE:
+        return "OD";
+        break;
+
+      case EXTERNAL_TAG_CODE:
+        return "EXTERNAL";
+        break;
+
+      case REAL_TAG_CODE:
+        return "REAL";
+        break;
+
+      case ENUM_TAG_CODE:
+        return "ENUM";
+        break;
+
+      case SEQ_TAG_CODE:
+        return "SEQUENCE";
+        break;
+
+      case SET_TAG_CODE:
+        return "SET";
+        break;
+
+      case NUMERICSTRING_TAG_CODE:
+        return "NUMERICSTRING";
+        break;
+
+      case PRINTABLESTRING_TAG_CODE:
+        return "PRINTABLESTRING";
+        break;
+
+      case TELETEXSTRING_TAG_CODE:
+        return "TELETEXSTRING";
+        break;
+
+      case VIDEOTEXSTRING_TAG_CODE:
+        return "VIDEOTEXSTRING";
+        break;
+
+      case IA5STRING_TAG_CODE:
+        return "IA5STRING";
+        break;
+
+      case UTCTIME_TAG_CODE:
+        return "UTCTIME";
+        break;
+
+      case GENERALIZEDTIME_TAG_CODE:
+        return "GENERALIZEDTIME";
+        break;
+
+      case GRAPHICSTRING_TAG_CODE:
+        return "GRAPHICSTRING";
+        break;
+
+      case VISIBLESTRING_TAG_CODE:
+        return "VISIBLESTRING";
+        break;
+
+      case GENERALSTRING_TAG_CODE:
+        return "GENERALSTRING";
+        break;
+
+      default:
+        return "UNKNOWN";
+
+    }
+} /* Form2FormStr */
+
+#define SOT 0
+#define EOL 1
+#define EOLINC 2
+#define DECSOTEOL 3
+#define SOTSPC 4
+#define EOLIF 5
+
+void DBGIndent PARAMS ((mode),
+    int mode)
+{
+    static int indent = 0;
+    static int withinline = 0;
+    int i;
+    
+    /*DEC*/
+    if (mode==DECSOTEOL)
+    	indent--;
+
+    /*SPC*/
+    if (mode==SOTSPC && withinline)
+    	fprintf(stdout," ");
+
+    /*SOT*/
+    if ((mode==SOT || mode==DECSOTEOL || mode==SOTSPC) && !withinline)
+    	{
+    	for (i=0; i<indent; i++)
+    	    fprintf(stdout,"   ");
+    	withinline = 1;
+    	}
+
+    /*IF*/
+    if (mode==EOLIF && withinline)
+	fprintf(stdout,"\n");
+
+    /*EOL*/
+    if (mode==EOL || mode==EOLINC || mode==DECSOTEOL || mode==EOLIF)
+    	withinline = 0;
+    
+    /*INC*/
+    if (mode==EOLINC)
+    	indent++;
+}
+
+int DBGSimple PARAMS ((tag, v, begin),
+    AsnTag tag _AND_
+    AsnOcts* v _AND_
+    int begin)
+{
+    BER_CLASS tclass = TAG_ID_CLASS(tag);
+    BER_FORM form = TAG_ID_FORM(tag);
+    unsigned long int code = tag & 0x1FFFFFFF;
+    BER_UNIV_CODE bcode;
+    char* codename;
+    int i;
+    if (tclass==UNIV)
+	{
+	bcode = code>>24;
+	codename = Code2UnivCodeStr(bcode);
+	}
+    else
+	{
+	bcode = OCTETSTRING_TAG_CODE;
+	codename = "NOT_UNIV";
+	}
+    if (begin)
+    	{
+    	DBGIndent(SOTSPC);
+	fprintf (stdout, "%s", codename);
+	if (TAG_IS_CONS(tag))
+	    {
+	    if (tclass==UNIV) 
+		{
+    		fprintf(stdout, " {\n");
+		DBGIndent(EOLINC);
+		}
+    	    }
+    	else
+    	    {
+    	    fprintf(stdout,": ");
+    	    PrintAsnOcts(stdout,v,0);
+	    fprintf(stdout,"\n");
+	    DBGIndent(EOL);
+    	    }
+	}
+    else
+    	{
+	if (TAG_IS_CONS(tag) && tclass==UNIV)
+    	    {
+    	    DBGIndent(DECSOTEOL);
+    	    fprintf(stdout, "}\n");
+    	    }
+    	}
+    return 0;
+}
+
+void DBGNamedValue PARAMS ((tnnl, val, mode),
+    TBLNamedNumberList* tnnl _AND_
+    AsnInt val _AND_
+    int mode)
+{
+    /* mode 0: Don't print if no named value. postfix print with -- */
+    /* mode 0|1: prefix with -- */
+    /* mode >1: prefix with , */
+    TBLNamedNumber* tnn;
+    char* name = NULL;
+    FOR_EACH_LIST_ELMT (tnn, tnnl)
+	if (tnn->value == val)
+	    {
+	    name = tnn->name.octs;
+	    break;
+	    }
+    if (!mode && !name)
+	return;
+    if (mode<=1)
+	fprintf(stdout," -- ");
+    else
+	fprintf(stdout,", ");
+    if (name)
+	fprintf(stdout,"%s",name);
+    fprintf(stdout,"(%d)",val);
+    if (!mode)
+    	fprintf(stdout," --");
+}
+
+void
+DBGPrintType PARAMS ((type),
+    TBLType* type)
+{
+    static char* TIN [] = { "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
+    	"NULL", "OBJECT IDENTIFIER", "REAL", "ENUMERATED", "SEQUENCE", "SET", 
+    	"SEQUENCE OF", "SET OF", "CHOICE", NULL };
+    	
+    if (type->typeId == TBL_TYPEREF)
+	DBGOcts(&type->content->a.typeRef->typeDefPtr->typeName);
+    else
+	fprintf(stdout,TIN[type->typeId]);
+    if (type->fieldName.octetLen)
+    {
+	fprintf(stdout," ");
+	DBGOcts(&type->fieldName);
+    }
+}
+
+typedef int (*Proc) PROTO (());
+
+int
+DBGType PARAMS ((type, val, begin),
+    TBLType* type _AND_
+    AVal* val _AND_
+    int begin)
+{
+    static Proc printproc [] = {PrintAsnBool, PrintAsnInt, PrintAsnBits,
+    PrintAsnOcts,
+            PrintAsnNull, PrintAsnOid, PrintAsnReal, PrintAsnInt, NULL, NULL,
+            NULL, NULL, NULL,
+            NULL};
+    
+    if (begin)
+    {
+	DBGIndent(SOTSPC);
+	DBGPrintType(type);
+	if (type->typeId >= TBL_SEQUENCE && type->typeId <= TBL_CHOICE)
+    	{
+    	    fprintf(stdout," {\n");
+    	    DBGIndent(EOLINC);
+    	}
+    }
+    else
+    {
+	if (printproc[type->typeId])
+	{
+    	    DBGIndent(SOT);
+    	    fprintf(stdout,": ");
+    	    (*printproc[type->typeId])(stdout,val,0);
+	    switch (type->typeId)
+	    {
+	    case TBL_BITSTRING:
+		{
+		AsnInt i;
+		AsnBits* b = (AsnBits*)val;
+		int mode = 1;
+		for (i=0; i<b->bitLen;i++)
+		    if (GetAsnBit(b,i))
+			DBGNamedValue(type->values,i,mode++);
+		if (mode>1)
+	    	    fprintf(stdout," --");
+		}
+		break;
+	    case TBL_ENUMERATED:
+		DBGNamedValue(type->values,*(AsnInt*)val,0);
+		break;
+	    default:
+		break;
+	    }
+	    fprintf(stdout,"\n");
+	    DBGIndent(EOL);
+	}
+	if (type->typeId >= TBL_SEQUENCE && type->typeId <= TBL_CHOICE)
+    	{
+    	    DBGIndent(DECSOTEOL);
+    	    fprintf(stdout,"}\n");
+    	}
+    }
+    return 0;
+}
+
+int DBGExc PARAMS ((code, p1, p2, p3),
+    TdeExceptionCode code _AND_
+    void* p1 _AND_
+    void* p2 _AND_
+    void* p3)
+{
+    if (code<DBGMinCode)
+	return 0;
+    switch (code) 
+    {
+    case TDEEOC:
+	DBGIndent(SOTSPC);
+	fprintf(stdout,"[EOC]");
+	break;
+    case TDEPEEKTAG:
+	DBGIndent(SOTSPC);
+	fprintf(stdout,"[%08X]",*(AsnTag*)p1);
+	break;
+    case TDEPUSHTAG:
+	DBGIndent(SOTSPC);
+	fprintf(stdout,"[%08X/%d(%d)]",*(AsnTag*)p1,*(int*)p2,*(int*)p3);
+	break;
+    case TDEUNEXPECTED:
+	DBGIndent(EOLIF);
+	DBGIndent(SOT);
+	fprintf(stdout,"WARNING: Unexpected type encountered");
+	if (p2) {
+	    fprintf(stdout," when expecting ");
+	    DBGPrintType((TBLType*)p2);
+	}
+	fprintf(stdout," while decoding ");
+	DBGPrintType((TBLType*)p1);
+	fprintf(stdout,", decoding it in simple mode.\n");
+	DBGIndent(EOL);
+	break;
+    case TDENONOPTIONAL:
+	DBGIndent(EOLIF);
+	DBGIndent(SOT);
+	fprintf(stdout,"WARNING: Non-optional element ");
+	DBGPrintType((TBLType*)p2);
+	fprintf(stdout," missing in ");
+	DBGPrintType((TBLType*)p1);
+	fprintf(stdout,".\n");
+	DBGIndent(EOL);
+	break;
+    case TDEMANDATORY:
+	DBGIndent(EOLIF);
+	DBGIndent(SOT);
+	fprintf(stdout,"WARNING: Mandatory elements missing in ");
+	DBGPrintType((TBLType*)p1);
+	fprintf(stdout,".\n");
+	DBGIndent(EOL);
+	break;
+    case TDECONSTRAINT:
+	DBGIndent(EOLIF);
+	DBGIndent(SOT);
+	fprintf(stdout,"WARNING: Value %d not in SIZE(%d..%d) in ",
+		*(AsnInt*)p3,((TBLRange*)p2)->from,((TBLRange*)p2)->to);
+	DBGPrintType((TBLType*)p1);
+	fprintf(stdout,".\n");
+	DBGIndent(EOL);
+	break;
+    case TDENOMATCH:
+	DBGIndent(EOLIF);
+	DBGIndent(SOT);
+	fprintf(stdout,"WARNING: Tag [%08X] does not match tag [%08X] of type ",
+		*(AsnTag*)p3,*(AsnTag*)p2);
+	DBGPrintType((TBLType*)p1);
+	fprintf(stdout,".\n");
+	DBGIndent(EOL);
+	break;
+    case TDEERROR:
+	DBGIndent(EOLIF);
+	DBGIndent(SOT);
+	fprintf(stdout,"ERROR: %s.\n",(char*)p1);
+	DBGIndent(EOL);
+	break;
+    }
+    return 0;
+}
+#endif
diff --git a/SecuritySNACCRuntime/c-lib/src/tbl-dec.c b/SecuritySNACCRuntime/c-lib/src/tbl-dec.c
new file mode 100644
index 00000000..4a4317f4
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/tbl-dec.c
@@ -0,0 +1,456 @@
+/*
+ * 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.
+ */
+
+
+#ifdef TTBL
+
+/*
+ * tbl_dec.c - type table decoder.
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include "tbl-incl.h"
+
+int  TagsMatch PROTO ((TBLType *tblT, AsnTag asnTag));
+void TblPopTagsAndLens PROTO ((TBLType *tblT, BUF_TYPE b, int implicit, unsigned long int *bytesDecoded, ENV_TYPE env));
+
+void TblDecodeTagsAndLens PROTO ((TBLType *tblT, BUF_TYPE b, int implicit, ENV_TYPE env));
+
+int CountMandatoryElmts PROTO ((TBLType *tblT));
+
+
+typedef struct TagNLen
+{
+    AsnTag tag;
+    AsnLen len;
+    unsigned int size; /* encoded len for this tag len pair */
+} TagNLen;
+
+#define TL_STK_SIZE 128
+static TagNLen tlStkG[TL_STK_SIZE];
+static int nextFreeTLG = 0;
+
+#define PUSH_TL(t,l,sz, env)\
+  { if (nextFreeTLG >= TL_STK_SIZE)\
+      longjmp (env, -1000);\
+    tlStkG[nextFreeTLG].tag = t;\
+    tlStkG[nextFreeTLG].len = l;\
+    tlStkG[nextFreeTLG++].size = sz; }
+
+#define POP_TL(env)\
+  { nextFreeTLG--;\
+    if (nextFreeTLG < 0)\
+        longjmp (env, -1001);}
+
+#define LAST_TAG() (tlStkG[nextFreeTLG-1].tag)
+#define LAST_LEN() (tlStkG[nextFreeTLG-1].len)
+#define LAST_SIZE() (tlStkG[nextFreeTLG-1].size)
+
+
+
+AVal*
+TblDecode PARAMS ((tbl, modName, typeName, b, bytesDecoded),
+    TBL *tbl _AND_
+    char *modName _AND_
+    char *typeName _AND_
+    BUF_TYPE b _AND_
+    unsigned long int *bytesDecoded)
+{
+    TBLModule *tblMod;
+    TBLTypeDef *tblTd;
+    ENV_TYPE env;
+    AVal *retVal;
+    int val;
+
+    tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod);
+    if (tblTd == NULL)
+    {
+        TblError ("TblDecode: Could not find a type definition with the given module and name");
+        return NULL;
+    }
+    *bytesDecoded = 0;
+
+    if ((val = setjmp (env)) == 0)
+    {
+        retVal = TblDecodeType (tblTd->type, b, FALSE, bytesDecoded, env);
+    }
+    else
+        retVal = NULL;
+
+    if (val != 0)
+        fprintf (stderr,"ack! longjmp error number: %d\n", val);
+
+    return retVal;
+}  /* TblDecode p*/
+
+
+AVal*
+TblDecodeType PARAMS ((tblT, b, implicit, bytesDecoded, env),
+    TBLType *tblT _AND_
+    BUF_TYPE b _AND_
+    int implicit _AND_
+    unsigned long int *bytesDecoded _AND_
+    ENV_TYPE env)
+{
+    AVal *elmtVPtr;
+    unsigned long int tmpBytesDecoded = 0;
+    unsigned int currElmt;
+    TBLType *listElmtType;
+    TBLType *structElmtType;
+    TBLType *choiceElmtType;
+    AChoiceVal *cVal;
+    AStructVal *sVal;
+    AVal *retVal;
+    AVal **tmpHndl;
+    AsnTag asnTag;
+    int i, mandatoryCount, mandatoryElmts;
+    int implicitRef;
+    void *tmp;
+
+
+    TblDecodeTagsAndLens (tblT, b, implicit, env);
+
+    switch (tblT->typeId)
+    {
+      case TBL_TYPEREF:
+          /*
+           * carry over implicit ref if goes
+           * through typeref with no tags
+           */
+          implicitRef = tblT->content->a.typeRef->implicit ||
+              (implicit &&
+               ((tblT->tagList == NULL) || LIST_EMPTY (tblT->tagList)));
+
+          retVal = TblDecodeType (tblT->content->a.typeRef->typeDefPtr->type, b, implicitRef, &tmpBytesDecoded, env);
+          break;
+
+      case TBL_SEQUENCE:
+          /* go fwd though elmt type list */
+          currElmt = 0;
+          sVal = (AStructVal*) Asn1Alloc (sizeof (AVal*)*
+                                        LIST_COUNT (tblT->content->a.elmts));
+          tmp = CURR_LIST_NODE (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts)
+          {
+              if (TagsMatch (structElmtType, PeekTag (b,env)))
+              {
+                  sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env);
+              }
+              else if (!structElmtType->optional)
+                  longjmp (env,-1008);
+
+              currElmt++;
+          }
+          SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
+          retVal = (AVal*) sVal;
+          break;
+
+      case TBL_SET:
+          sVal = (AStructVal*) Asn1Alloc (sizeof (AVal*)*
+                                        LIST_COUNT (tblT->content->a.elmts));
+          mandatoryCount = 0;
+          mandatoryElmts = CountMandatoryElmts (tblT);
+          if (LAST_LEN() == INDEFINITE_LEN)
+              while (!PeekEoc (b))
+              {
+                  asnTag = PeekTag (b,env);
+                  currElmt = 0;
+                  /* find elmt that matches the peeked tag */
+                  FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts)
+                  {
+                      if (TagsMatch (structElmtType, asnTag))
+                          break;
+                      currElmt++;
+                  }
+
+                  /* didn't find a match */
+                  if (currElmt >= LIST_COUNT (tblT->content->a.elmts))
+                      longjmp (env,-1009);
+
+                  if (!structElmtType->optional)
+                      mandatoryCount++;
+
+                  sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env);
+              }
+          else
+              while (tmpBytesDecoded < LAST_LEN())
+              {
+                  asnTag = PeekTag (b,env);
+                  currElmt = 0;
+                  /* find elmt that matches the peeked tag */
+                  FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts)
+                  {
+                      if (TagsMatch (structElmtType, asnTag))
+                          break;
+                      currElmt++;
+                  }
+
+                  if (currElmt >= LIST_COUNT (tblT->content->a.elmts))
+                      longjmp (env, -1007);
+
+                  if (!structElmtType->optional)
+                      mandatoryCount++;
+
+                  sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env);
+              }
+          if (mandatoryCount != mandatoryElmts)
+              longjmp (env,-1006);
+          else
+              retVal = sVal;
+
+        break;
+
+
+      case TBL_SEQUENCEOF:
+      case TBL_SETOF:
+          retVal = (AsnList*)Asn1Alloc (sizeof (AsnList));
+          listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts);
+
+          if (LAST_LEN() == INDEFINITE_LEN)
+              while (!PeekEoc (b))
+              {
+                  elmtVPtr = TblDecodeType (listElmtType, b, FALSE, &tmpBytesDecoded, env);
+                  tmpHndl = AsnListAppend ((AsnList*)retVal);
+                  *tmpHndl = elmtVPtr;
+              }
+          else
+              while (tmpBytesDecoded < LAST_LEN())
+              {
+                  elmtVPtr = TblDecodeType (listElmtType, b, FALSE, &tmpBytesDecoded, env);
+                  tmpHndl = AsnListAppend ((AsnList*)retVal);
+                  *tmpHndl = elmtVPtr;
+              }
+
+        break;
+
+      case TBL_CHOICE:
+          retVal = cVal = (AChoiceVal*) Asn1Alloc (sizeof (AChoiceVal));
+          asnTag = PeekTag (b,env);
+          i = 0;
+          /* find elmt that matches the peeked tag */
+          tmp = CURR_LIST_NODE (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT (choiceElmtType, tblT->content->a.elmts)
+          {
+              if (TagsMatch (choiceElmtType, asnTag))
+              {
+                  cVal->choiceId = i;
+                  break;
+              }
+              i++;
+          }
+          SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
+          cVal->val = TblDecodeType (choiceElmtType, b, FALSE, &tmpBytesDecoded, env);
+        break;
+
+      case TBL_BOOLEAN:
+          retVal = Asn1Alloc (sizeof (AsnBool));
+          BDecAsnBoolContent (b, LAST_TAG(), LAST_LEN(), (AsnBool*) retVal, &tmpBytesDecoded, env);
+        break;
+
+      case TBL_INTEGER:
+      case TBL_ENUMERATED:
+          retVal = Asn1Alloc (sizeof (AsnInt));
+          BDecAsnIntContent (b, LAST_TAG(), LAST_LEN(), (AsnInt*) retVal, &tmpBytesDecoded, env);
+        break;
+
+      case TBL_BITSTRING:
+          retVal = Asn1Alloc (sizeof (AsnBits));
+          BDecAsnBitsContent (b, LAST_TAG(), LAST_LEN(), (AsnBits*) retVal, &tmpBytesDecoded, env);
+        break;
+
+      case TBL_OCTETSTRING:
+          retVal = Asn1Alloc (sizeof (AsnOcts));
+          BDecAsnOctsContent (b, LAST_TAG(), LAST_LEN(), (AsnOcts*) retVal, &tmpBytesDecoded, env);
+        break;
+
+      case TBL_NULL:
+          retVal = Asn1Alloc (sizeof (AsnNull));
+          BDecAsnNullContent (b, LAST_TAG(), LAST_LEN(), (AsnNull*) retVal, &tmpBytesDecoded, env);
+        break;
+
+      case TBL_OID:
+          retVal = Asn1Alloc (sizeof (AsnOid));
+          BDecAsnOidContent (b, LAST_TAG(), LAST_LEN(), (AsnOid*) retVal, &tmpBytesDecoded, env);
+        break;
+
+      case TBL_REAL:
+          retVal = Asn1Alloc (sizeof (AsnReal));
+          BDecAsnRealContent (b, LAST_TAG(), LAST_LEN(), (AsnReal*) retVal, &tmpBytesDecoded, env);
+        break;
+
+      default:
+         retVal = NULL;
+         break;
+    }
+
+    TblPopTagsAndLens (tblT, b, implicit, &tmpBytesDecoded, env);
+
+    (*bytesDecoded) += tmpBytesDecoded;
+
+    return retVal;
+
+}  /* TblDecodeType */
+
+
+void
+TblDecodeTagsAndLens PARAMS ((tblT, b, implicit, env),
+    TBLType *tblT _AND_
+    BUF_TYPE b _AND_
+    int implicit _AND_
+    ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen len;
+    AsnLen encSize;
+    TBLTag *tblTag;
+
+    if ((tblT->tagList == NULL) || (LIST_EMPTY (tblT->tagList)))
+        return;
+
+    SET_CURR_LIST_NODE (tblT->tagList, FIRST_LIST_NODE (tblT->tagList));
+    if (implicit)
+    {
+       SET_CURR_LIST_NODE (tblT->tagList, NEXT_LIST_NODE (tblT->tagList));
+    }
+
+
+    FOR_REST_LIST_ELMT (tblTag, tblT->tagList)
+    {
+        encSize = 0;
+        tag = BDecTag (b, &encSize, env);
+        len = BDecLen (b, &encSize, env);
+
+        if (!TagsEquiv (tag, tblTag))
+            longjmp (env, -1002);
+
+        PUSH_TL (tag, len, encSize, env);
+    }
+} /* TblDecodeTagsAndLens */
+
+/*
+ * bytesDecoded should hold the length of the content that
+ * was just decoded.  This verifies the lengths as it pops
+ * them off the stack.  Also decodes EOCs.
+ */
+void
+TblPopTagsAndLens PARAMS ((tblT, b, implicit, bytesDecoded, env),
+    TBLType *tblT _AND_
+    BUF_TYPE b _AND_
+    int implicit _AND_
+    unsigned long int *bytesDecoded _AND_
+    ENV_TYPE env)
+{
+    TBLTag *tblTag;
+
+    FOR_EACH_LIST_ELMT_RVS (tblTag, tblT->tagList)
+    {
+        if (implicit && (tblTag == FIRST_LIST_ELMT (tblT->tagList)))
+            break;
+
+        if (LAST_LEN() == INDEFINITE_LEN)
+            BDecEoc (b, bytesDecoded, env);
+        else if (*bytesDecoded != LAST_LEN())
+            longjmp (env, -1003);
+
+        (*bytesDecoded) += LAST_SIZE();
+        POP_TL (env);
+    }
+} /* TblPopTagsAndLens */
+
+
+int TagsMatch PARAMS ((tblT, asnTag),
+    TBLType *tblT _AND_
+    AsnTag asnTag)
+{
+    TBLType *tmpTblT;
+    TBLType *elmtTblT;
+    TBLTag *tblTag;
+    void *tmp;
+
+    /*
+     * skip through type refs until encounter first tag or
+     * untagged CHOICE (only TYPEREFs and CHOICEs can
+     * have empty tag lists).
+     */
+    for (tmpTblT = tblT; ((tmpTblT->typeId == TBL_TYPEREF) &&
+               ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList)));
+         tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type);
+
+
+    /*
+     * if untagged CHOICE must check for a match with the first tag
+     * of each component of the CHOICE
+     */
+    if ((tmpTblT->typeId == TBL_CHOICE) &&
+        ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList)))
+    {
+        tmp = CURR_LIST_NODE (tmpTblT->content->a.elmts);
+        FOR_EACH_LIST_ELMT (elmtTblT, tmpTblT->content->a.elmts)
+        {
+            /*
+             * remember the elmt type can be an untagged choice too
+             * so call TagsMatch again.
+             */
+            if (TagsMatch (elmtTblT, asnTag))
+            {
+                SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp);
+                return TRUE;  /* match in choice */
+            }
+        }
+        SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp);
+        return FALSE; /* no match in choice */
+    }
+    else /* is type other than untagged choice or type ref */
+    {
+        tblTag =  FIRST_LIST_ELMT (tmpTblT->tagList);
+        return TagsEquiv (asnTag, tblTag);
+    }
+} /* TagsMatch */
+
+
+int
+CountMandatoryElmts PARAMS ((tblT),
+    TBLType *tblT)
+{
+    TBLType *tblElmtT;
+    int count = 0;
+    FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts)
+    {
+        if (!tblElmtT->optional)
+            count++;
+    }
+    return count;
+} /* CountMandatoryElmts */
+
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/src/tbl-enc.c b/SecuritySNACCRuntime/c-lib/src/tbl-enc.c
new file mode 100644
index 00000000..9f9370f6
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/tbl-enc.c
@@ -0,0 +1,346 @@
+/*
+ * 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.
+ */
+
+
+#ifdef TTBL
+
+/*
+ * tbl_enc.c - type table encoder
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include "tbl-incl.h"
+
+/* protos for non exported routines */
+
+/*
+int TblEncodePrimTagsAndLens PROTO ((TBLType *tblT, BUF_TYPE b, int implicit, unsigned long int *bytesEncoded));
+
+int TblEncodeConsTagsAndLens PROTO ((TBLType *tblT, BUF_TYPE b, int implicit, unsigned long int *bytesEncoded));
+*/
+
+int TblEncodeTagsAndLens PROTO ((TBLType *tblT, BUF_TYPE b, int implicit, unsigned long int *bytesEncoded));
+
+AsnLen TblEncTag PROTO ((BUF_TYPE b, TBLTag *tag));
+
+
+
+
+/*
+ * Encode value v as though it is of type modName.typeName.
+ * bytesEncoded is set the actual number of bytes in the
+ * encode value.
+ * returns less than zero if an error occurs otherwise
+ * returns 0 for success.
+ */
+int
+TblEncode PARAMS ((tbl, modName, typeName, b, v, bytesEncoded),
+    TBL *tbl _AND_
+    char *modName _AND_
+    char *typeName _AND_
+    BUF_TYPE b _AND_
+    AVal *v _AND_
+    unsigned long int *bytesEncoded)
+{
+    TBLModule *tblMod;
+    TBLTypeDef *tblTd;
+    int retVal;
+
+    tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod);
+    if (tblTd == NULL)
+    {
+        TblError ("TblEncode: Could not find a type definition with the given module and name");
+        return -1;
+    }
+    *bytesEncoded = 0;
+    retVal = TblEncodeType (tblTd->type, b, v, FALSE, bytesEncoded);
+
+    if (BufWriteError (b))
+        retVal = -1;
+
+    return retVal;
+}  /* TblEncode */
+
+
+/*
+ * returns less than zero if an error occurs
+ */
+int
+TblEncodeType PARAMS ((tblT, b, v, implicit, bytesEncoded),
+    TBLType *tblT _AND_
+    BUF_TYPE b _AND_
+    AVal *v _AND_
+    int implicit _AND_
+    unsigned long int *bytesEncoded)
+{
+    AVal *elmtV;
+    AsnList *lVal;
+    int retVal = 0;
+    unsigned long int tmpBytesEncoded = 0;
+    unsigned int currElmt;
+    TBLType *listElmtType;
+    TBLType *structElmtType;
+    TBLType *choiceElmtType;
+    AChoiceVal *cVal;
+    AStructVal *sVal;
+    int implicitRef;
+    void *tmp;
+
+    switch (tblT->typeId)
+    {
+      case TBL_TYPEREF:
+
+          /*
+           * carry over implicit ref if goes
+           * through typeref with no tags
+           */
+          implicitRef = tblT->content->a.typeRef->implicit ||
+              (implicit &&
+               ((tblT->tagList == NULL) || LIST_EMPTY (tblT->tagList)));
+
+          retVal = TblEncodeType (tblT->content->a.typeRef->typeDefPtr->type, b, v, implicitRef, &tmpBytesEncoded);
+          break;
+
+      case TBL_SEQUENCE:
+      case TBL_SET:
+          /* rvs though list value and list type def */
+          currElmt = LIST_COUNT (tblT->content->a.elmts)-1;
+          sVal = (AStructVal*)v;
+          tmp = CURR_LIST_NODE (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT_RVS (structElmtType, tblT->content->a.elmts)
+          {
+              elmtV = sVal[currElmt--];
+              if (!(structElmtType->optional && (elmtV == NULL)))
+              {
+                  retVal = TblEncodeType (structElmtType, b, elmtV, FALSE, &tmpBytesEncoded);
+                  if (retVal < 0)
+                      break; /* exit for loop */
+              }
+          }
+          /* restore list curr in case recursive type */
+          SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
+          break;
+
+      case TBL_SEQUENCEOF:
+      case TBL_SETOF:
+          lVal = (AsnList*)v;
+          listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT_RVS (elmtV, lVal)
+          {
+              retVal = TblEncodeType (listElmtType, b, elmtV, FALSE, &tmpBytesEncoded);
+              if (retVal < 0)
+                  break; /* exit for loop */
+          }
+        break;
+
+      case TBL_CHOICE:
+          cVal = (AChoiceVal*) v;
+          choiceElmtType = (TBLType*)GetAsnListElmt (tblT->content->a.elmts, cVal->choiceId);
+          retVal = TblEncodeType (choiceElmtType, b, cVal->val, FALSE, &tmpBytesEncoded);
+        break;
+
+      case TBL_BOOLEAN:
+          tmpBytesEncoded += BEncAsnBoolContent (b, (AsnBool*)v);
+        break;
+
+      case TBL_INTEGER:
+      case TBL_ENUMERATED:
+          tmpBytesEncoded += BEncAsnIntContent (b, (AsnInt*)v);
+        break;
+
+      case TBL_BITSTRING:
+          tmpBytesEncoded += BEncAsnBitsContent (b, (AsnBits*)v);
+        break;
+
+      case TBL_OCTETSTRING:
+          tmpBytesEncoded += BEncAsnOctsContent (b, (AsnOcts*)v);
+        break;
+
+      case TBL_NULL:
+          tmpBytesEncoded += BEncAsnNullContent (b, (AsnNull*)v);
+        break;
+
+      case TBL_OID:
+          tmpBytesEncoded += BEncAsnOidContent (b, (AsnOid*)v);
+        break;
+
+      case TBL_REAL:
+          tmpBytesEncoded += BEncAsnRealContent (b, (AsnReal*)v);
+        break;
+
+      default:
+         retVal = -1;
+    }
+
+    if (retVal >= 0)
+        retVal = TblEncodeTagsAndLens (tblT, b, implicit, &tmpBytesEncoded);
+
+    (*bytesEncoded) += tmpBytesEncoded;
+
+    return retVal;
+
+}  /* TblEncodeTd */
+
+
+int
+TblEncodeTagsAndLens PARAMS ((tblT, b, implicit, bytesEncoded),
+    TBLType *tblT _AND_
+    BUF_TYPE b _AND_
+    int implicit _AND_
+    unsigned long int *bytesEncoded)
+{
+    TBLTag *tag;
+
+    FOR_EACH_LIST_ELMT_RVS (tag, tblT->tagList)
+    {
+        if (!(implicit && (tag == FIRST_LIST_ELMT (tblT->tagList))))
+        {
+            if (tag->form == CONS)
+                (*bytesEncoded) += BEncConsLen (b, *bytesEncoded);
+            else /* ANY_FORM or PRIM */
+                (*bytesEncoded) += BEncDefLen (b, *bytesEncoded);
+
+            (*bytesEncoded) += TblEncTag (b, tag);
+        }
+    }
+    return 0; /* no errors */
+} /* TblEncodeTagsAndLens */
+
+/*
+int
+TblEncodePrimTagsAndLens PARAMS ((tblT, b, implicit, bytesEncoded),
+    TBLType *tblT _AND_
+    BUF_TYPE b _AND_
+    int implicit _AND_
+    unsigned long int *bytesEncoded)
+{
+    TBLTag *tag;
+    int tagsEncoded;
+    int numTags;
+
+    if ((tblT->tagList == NULL) ||(LIST_EMPTY (tblT->tagList)))
+        untaggedPrimG = TRUE;
+    else
+    {
+        numTags = LIST_COUNT (tblT->tagList);
+        if ((numTags != 1) || !implicit)
+        {
+            untaggedPrimG = FALSE;
+            tag = FIRST_LIST_ELMT (tblT->tagList);
+            (*bytesEncoded) += BEncDefLen (b, *bytesEncoded);
+            (*bytesEncoded) += TblEncTag (b, tag->tclass, PRIM, tag->code);
+            tagsEncoded = 1;
+            SET_CURR_LIST_NODE (tblT->tagList, LAST_LIST_NODE (tblT->tagList)->prev);
+            FOR_REST_LIST_ELMT_RVS (tag, tblT->tagList)
+            {
+                if (implicit && (tagsEncoded == (numTags -1)))
+                    break;
+                (*bytesEncoded) += BEncConsLen (b, *bytesEncoded);
+                (*bytesEncoded) += TblEncTag (b, tag->tclass, CONS, tag->code);
+                tagsEncoded++;
+            }
+        }
+        else
+            untaggedPrimG = TRUE;
+    }
+    return 0;
+} TblEncodeTagsAndLens */
+
+
+/*
+ * write encoded version of tag stored in the tag to
+ * the bufer
+ */
+AsnLen TblEncTag PARAMS ((b, tag),
+    BUF_TYPE b _AND_
+    TBLTag *tag)
+{
+    AsnTag shifted;
+    unsigned char octet;
+    AsnLen encLen = 0;
+    int i;
+
+    for (i = 0; i < sizeof (AsnTag); i++)
+    {
+        shifted = (tag->encTag >> (i * 8));
+	octet =  shifted & 0xff;
+        if (octet || i<sizeof(AsnTag)-2 && (shifted & 0x8000))
+        {
+            encLen++;
+            BufPutByteRvs (b, octet);
+        }
+
+    }
+    return encLen;
+} /* TblEncTag */
+
+
+/* OLD NOT USED ANY MORE
+  returns encoded length of tag
+AsnLen TblEncTag PARAMS ((b, tclass, form, code),
+    BUF_TYPE b _AND_
+    TBLTagClass tclass _AND_
+    BER_FORM form _AND_
+    AsnInt code)
+{
+    AsnLen retVal;
+    BER_CLASS  bclass;
+
+    bclass = TblTagClassToBer (tclass);
+
+     warning: keep the BEncTagX calls in braces ({}) cause macros
+    if (code < 31)
+    {
+        retVal = BEncTag1 (b, bclass, form, code);
+    }
+    else if (code < 128)
+    {
+        retVal = BEncTag2 (b, bclass, form, code);
+    }
+    else if (code < 16384)
+    {
+        retVal = BEncTag3 (b, bclass, form, code);
+    }
+    else if (code < 2097152)
+    {
+        retVal = BEncTag4 (b, bclass, form, code);
+    }
+    else
+    {
+        retVal = BEncTag5 (b, bclass, form, code);
+    }
+    return retVal;
+}
+*/
+
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/src/tbl-free.c b/SecuritySNACCRuntime/c-lib/src/tbl-free.c
new file mode 100644
index 00000000..08691d07
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/tbl-free.c
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+
+#ifdef TTBL
+
+/*
+ * tbl_free.c - frees data structs returned by type table driven decoder.
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include "tbl-incl.h"
+
+
+void
+TblFree PARAMS ((tbl, modName, typeName, v),
+    TBL *tbl _AND_
+    char *modName _AND_
+    char *typeName _AND_
+    AVal *v)
+{
+    TBLModule *tblMod;
+    TBLTypeDef *tblTd;
+
+    tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod);
+    if (tblTd == NULL)
+    {
+        TblError ("TblFree: Could not find a type definition with the given module and name");
+    }
+
+    TblFreeType (tblTd->type, v);
+}  /* TblDecode p*/
+
+
+void
+TblFreeType PARAMS ((tblT, v),
+    TBLType *tblT _AND_
+    AVal *v)
+{
+    AVal *elmtVPtr;
+    unsigned int currElmt;
+    TBLType *listElmtType;
+    TBLType *structElmtType;
+    TBLType *choiceElmtType;
+    AChoiceVal *cVal;
+    AStructVal *sVal;
+    AsnList *lVal;
+    void *tmp;
+
+
+    switch (tblT->typeId)
+    {
+      case TBL_TYPEREF:
+          TblFreeType (tblT->content->a.typeRef->typeDefPtr->type, v);
+          break;
+
+      case TBL_SEQUENCE:
+      case TBL_SET:
+          sVal = (AStructVal*)v;
+          currElmt = 0;
+          tmp = CURR_LIST_NODE (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts)
+          {
+              if (!((structElmtType->optional) && (sVal[currElmt] == NULL)))
+                  TblFreeType (structElmtType, sVal[currElmt]);
+              currElmt++;
+          }
+          SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
+          Asn1Free (v);
+          break;
+
+
+      case TBL_SEQUENCEOF:
+      case TBL_SETOF:
+          listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts);
+          lVal  = (AsnList*)v;
+          FOR_EACH_LIST_ELMT (elmtVPtr, lVal)
+          {
+              TblFreeType (listElmtType, elmtVPtr);
+          }
+          AsnListFree (lVal);
+        break;
+
+      case TBL_CHOICE:
+          cVal = (AChoiceVal*)v;
+          choiceElmtType = (TBLType*)GetAsnListElmt (tblT->content->a.elmts, cVal->choiceId);
+          TblFreeType (choiceElmtType, cVal->val);
+          Asn1Free (cVal);
+        break;
+
+      case TBL_BOOLEAN:
+          FreeAsnBool ((AsnBool*)v);
+          Asn1Free (v);
+        break;
+
+      case TBL_INTEGER:
+      case TBL_ENUMERATED:
+          FreeAsnInt ((AsnInt*)v);
+          Asn1Free (v);
+        break;
+
+      case TBL_BITSTRING:
+          FreeAsnBits ((AsnBits*)v);
+          Asn1Free (v);
+        break;
+
+      case TBL_OCTETSTRING:
+          FreeAsnOcts ((AsnOcts*)v);
+          Asn1Free (v);
+        break;
+
+      case TBL_NULL:
+          FreeAsnNull ((AsnNull*)v);
+          Asn1Free (v);
+        break;
+
+      case TBL_OID:
+          FreeAsnOid ((AsnOid*)v);
+          Asn1Free (v);
+        break;
+
+      case TBL_REAL:
+          FreeAsnReal ((AsnReal*)v);
+          Asn1Free (v);
+        break;
+
+      default:
+         break;
+    }
+
+}  /* TblFreeType */
+
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/src/tbl-gen.c b/SecuritySNACCRuntime/c-lib/src/tbl-gen.c
new file mode 100644
index 00000000..ded07407
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/tbl-gen.c
@@ -0,0 +1,669 @@
+/*
+ * 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.
+ */
+
+
+#ifdef TTBL
+#include <stdio.h>
+#include "tbl-gen.h"
+
+typedef struct TagNLen
+{
+    AsnTag tag;
+    AsnLen len;
+    unsigned int size; /* encoded len for this tag len pair */
+} TagNLen;
+
+#define TL_STK_SIZE 128
+
+typedef struct STDEDecoder
+{
+    TBL* tbl;
+    BUF_TYPE b;
+    ENV_TYPE env;
+    TagNLen tlStk[TL_STK_SIZE];
+    int nTlStk;
+    int rewindsize;
+    TdeTypeProc typeproc;
+    TdeSimpleProc simpleproc;
+    TdeExcProc excproc;
+} * TDEDecoder;
+
+
+#define TDEEXCEPTION(dec,code,p1,p2,p3) if ((dec)->excproc) if ((*(dec)->excproc)(code,p1,p2,p3)) longjmp((dec)->env,-236)
+
+#define TDEERRORMSG(dec,msg) TDEEXCEPTION(dec,TDEERROR,msg,NULL,NULL)
+
+#define TDEWARNUNEXPECTED(dec,type,elmtType) TDEEXCEPTION(dec,TDEUNEXPECTED,type,elmtType,NULL)
+#define TDEWARNNONOPTIONAL(dec,type,elmtType) TDEEXCEPTION(dec,TDENONOPTIONAL,type,elmtType,NULL)
+#define TDEWARNMANDATORY(dec,type) TDEEXCEPTION(dec,TDEMANDATORY,type,NULL,NULL)
+#define TDEWARNCONSTRAINT(dec,type,cons,val) TDEEXCEPTION(dec,TDECONSTRAINT,type,cons,&val)
+#define TDEWARNNOMATCH(dec,type,typetag,tag) TDEEXCEPTION(dec,TDENOMATCH,type,&typetag,&tag)
+
+#define TDEINFOEOC(dec) TDEEXCEPTION(dec,TDEEOC,NULL,NULL,NULL)
+#define TDEINFOPEEKTAG(dec,tag) TDEEXCEPTION(dec,TDEPEEKTAG,&tag,NULL,NULL)
+#define TDEINFOPUSHTAG(dec,tag,len,size) TDEEXCEPTION(dec,TDEPUSHTAG,&tag,&len,&size)
+
+#define TDETYPE(dec,type,val,begin) if (dec->typeproc) if ((*dec->typeproc)(type,val,begin)) longjmp(dec->env,-234)
+#define TDESIMPLE(dec,tag,octs,begin) if (dec->simpleproc) if ((*dec->simpleproc)(tag,octs,begin)) longjmp(dec->env,-235)
+
+#define LAST_TAG() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].tag)
+#define LAST_LEN() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].len)
+#define LAST_SIZE() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].size)
+
+AsnTag
+TDEPeekTag PARAMS ((dec),
+    TDEDecoder dec)
+{
+    AsnTag tag;
+    if (dec->rewindsize)
+    	tag = dec->tlStk[dec->nTlStk-dec->rewindsize].tag;
+    else
+    	tag = PeekTag(dec->b,dec->env);
+    TDEINFOPEEKTAG(dec,tag);
+    return tag;
+}
+
+AsnTag
+TDEPushTag PARAMS ((dec),
+    TDEDecoder dec)
+{
+    if (dec->rewindsize)
+    	dec->rewindsize--;
+    else
+    {
+        unsigned long encSize = 0;
+        if (dec->nTlStk >= TL_STK_SIZE)
+            longjmp (dec->env, -1000);
+    	dec->tlStk[dec->nTlStk].tag = BDecTag (dec->b, &encSize, dec->env);
+	dec->tlStk[dec->nTlStk].len = BDecLen (dec->b, &encSize, dec->env);
+	dec->tlStk[dec->nTlStk++].size = encSize;
+	TDEINFOPUSHTAG(dec,LAST_TAG(),LAST_LEN(),LAST_SIZE());
+    }
+    return LAST_TAG();
+}
+
+void 
+TDEDoPop PARAMS ((dec),
+    TDEDecoder dec)
+{
+    dec->nTlStk--;
+    if (dec->nTlStk < 0)
+        longjmp (dec->env, -1001);
+}
+
+void
+TDEPopTag PARAMS ((dec, bytesDecoded),
+    TDEDecoder dec _AND_
+    unsigned long int *bytesDecoded)
+{
+    if (LAST_LEN()==INDEFINITE_LEN)
+    {
+        BDecEoc (dec->b, bytesDecoded, dec->env);
+        TDEINFOEOC(dec);
+    }
+    else if (*bytesDecoded != LAST_LEN())
+    {
+        TDEERRORMSG(dec,"Lost BER synchronisation");
+        longjmp (dec->env, -1003);
+    }
+    (*bytesDecoded) += LAST_SIZE();
+    TDEDoPop(dec);
+}
+
+void
+TDECheckConstraint PARAMS ((dec, type, constraint, value),
+    TDEDecoder dec _AND_
+    TBLType* type _AND_
+    TBLRange* constraint _AND_
+    AsnInt value)
+{
+    if (constraint && (value<constraint->from || value>constraint->to))
+    	TDEWARNCONSTRAINT(dec,type,constraint,value);
+}
+
+int
+TDEInTag PARAMS ((dec, bytesDecodedInTag),
+    TDEDecoder dec _AND_
+    unsigned long int bytesDecodedInTag)
+{
+    return LAST_LEN()==INDEFINITE_LEN? !PeekEoc(dec->b): (bytesDecodedInTag<LAST_LEN());
+}
+
+int
+TDECountMandatoryElmts PARAMS ((type),
+    TBLType *type)
+{
+    TBLType *elmtType;
+    int count = 0;
+    FOR_EACH_LIST_ELMT (elmtType, type->content->a.elmts)
+    {
+        if (!elmtType->optional)
+            count++;
+    }
+    return count;
+}
+
+void 
+TDESimpleDecode PARAMS ((dec, bytesDecoded),
+    TDEDecoder dec _AND_
+    unsigned long int *bytesDecoded)
+{
+    AsnTag tag = TDEPushTag(dec);
+    unsigned long int bytesDecodedInTag = 0;
+
+    BER_CLASS tclass = TAG_ID_CLASS(tag);
+    BER_FORM form = TAG_ID_FORM(tag);
+    unsigned long int code = tag & 0x1FFFFFFF;
+    BER_UNIV_CODE bcode;
+    if (tclass==UNIV)
+	bcode = code>>24;
+    else
+	bcode = OCTETSTRING_TAG_CODE;
+	
+    if (TAG_IS_CONS(tag))
+    {
+    	TDESIMPLE(dec,tag,NULL,1);
+        while (TDEInTag(dec,bytesDecodedInTag))
+        {
+    	    TDESimpleDecode (dec, &bytesDecodedInTag);
+        }
+        TDESIMPLE(dec,tag,NULL,0);
+    }
+    else
+    {
+    	PrintableString v;
+    	switch (bcode)
+    	{
+    	case INTEGER_TAG_CODE:
+    	case OCTETSTRING_TAG_CODE:
+    	default:
+    	    v.octetLen = LAST_LEN();
+    	    v.octs = Asn1Alloc(v.octetLen);
+    	    BufCopy(v.octs,dec->b,v.octetLen);
+    	    TDESIMPLE(dec,tag,&v,1);
+    	    Asn1Free(v.octs);
+    	    break;
+    	}
+    	bytesDecodedInTag += LAST_LEN();
+    }
+    TDEPopTag(dec,&bytesDecodedInTag);
+    *bytesDecoded += bytesDecodedInTag;
+}
+
+int
+TDEPushTagsAndLens PARAMS ((dec, type, implicit),
+    TDEDecoder dec _AND_
+    TBLType *type _AND_
+    int implicit)
+{
+    AsnTag tag;
+    AsnLen len;
+    AsnLen encSize;
+    TBLTag *tblTag;
+    int fullMatch = TRUE;
+    int origTLG = dec->nTlStk;
+    int origRewindsize = dec->rewindsize;
+
+    if ((type->tagList == NULL) || (LIST_EMPTY (type->tagList)))
+        return TRUE;
+
+    SET_CURR_LIST_NODE (type->tagList, FIRST_LIST_NODE (type->tagList));
+    if (implicit)
+    {
+       SET_CURR_LIST_NODE (type->tagList, NEXT_LIST_NODE (type->tagList));
+    }
+
+    FOR_REST_LIST_ELMT (tblTag, type->tagList)
+    {
+    	tag = TDEPushTag(dec);
+        if (!TagsEquiv (tag, tblTag))
+        {
+            /*
+             * Whoops! The expected tags do not completely fit! So what to do?
+             *
+             * This is a complicated situation since might have already read some
+             * tags from the buffer (and pushed), but now we should return  failure
+             * AND REWIND TO THE STATE WE WERE IN WHEN CALLED,
+             * so that future PeekTag and then TblDecodeTagsAndLens calls start
+             * off there again!
+             * 
+             * The idea is to modify PeekTag and this routine to first check
+             * whether there is information pending that was read already.
+             *
+             * Luckily, this can not happen recursively, only in sequence:
+             * ... -> ...
+             * ... -> Tags fit -> Tags fit -> ...
+             * ... -> Tags fit -> Tags fit -> ...
+             *                    Tags fit -> ...
+             *                    Tags don't fit -<
+             *                    Tags don't fit -<
+             *                    Complete subtype decoding remaining tags in simple manner
+             *                 <-
+             *        Tags don't fit -<
+             *        Tags fit -> ...
+             *        Complete subtype decoding remaining tags in simple manner
+             *        <-
+             * ...
+             */
+            fullMatch = FALSE;
+            dec->rewindsize = origRewindsize + dec->nTlStk - origTLG;
+            TDEWARNNOMATCH(dec,type,tblTag->encTag,tag);
+            break;
+        }
+    }
+    if (fullMatch)
+    	dec->rewindsize = 0;
+    return fullMatch;
+}
+
+void
+TDEPopTagsAndLens PARAMS ((dec, bytesDecoded, type, implicit),
+    TDEDecoder dec _AND_
+    unsigned long int *bytesDecoded _AND_
+    TBLType *type _AND_
+    int implicit)
+{
+    TBLTag *tblTag;
+    if (dec->rewindsize)
+    	TDEERRORMSG(dec,"Still rewinding at end of tag");
+    FOR_EACH_LIST_ELMT_RVS (tblTag, type->tagList)
+    {
+        if (implicit && (tblTag == FIRST_LIST_ELMT (type->tagList)))
+            break;
+    	TDEPopTag(dec,bytesDecoded);
+    }
+}
+
+int 
+TDETagsMatch PARAMS ((type, asnTag),
+    TBLType *type _AND_
+    AsnTag asnTag)
+{
+    TBLType *tmpTblT;
+    TBLType *elmtTblT;
+    TBLTag *tblTag;
+    void *tmp;
+
+    /*
+     * skip through type refs until encounter first tag or
+     * untagged CHOICE (only TYPEREFs and CHOICEs can
+     * have empty tag lists).
+     */
+    for (tmpTblT = type; ((tmpTblT->typeId == TBL_TYPEREF) &&
+               ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList)));
+         )
+         tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type;
+
+    /*
+     * if untagged CHOICE must check for a match with the first tag
+     * of each component of the CHOICE
+     */
+    if ((tmpTblT->typeId == TBL_CHOICE) &&
+        ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList)))
+    {
+        tmp = CURR_LIST_NODE (tmpTblT->content->a.elmts);
+        FOR_EACH_LIST_ELMT (elmtTblT, tmpTblT->content->a.elmts)
+        {
+            /*
+             * remember the elmt type can be an untagged choice too
+             * so call TagsMatch again.
+             */
+            if (TagsMatch (elmtTblT, asnTag))
+            {
+                SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp);
+                return TRUE;  /* match in choice */
+            }
+        }
+        SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp);
+        return FALSE; /* no match in choice */
+    }
+    else /* is type other than untagged choice or type ref */
+    {
+	int result;
+        tblTag =  FIRST_LIST_ELMT (tmpTblT->tagList);
+        result = TagsEquiv (asnTag, tblTag);
+	return result;
+    }
+}
+
+int
+TDEDecodeType PARAMS ((dec, bytesDecoded, type, implicit, constraint),
+    TDEDecoder dec _AND_
+    unsigned long int *bytesDecoded _AND_
+    TBLType *type _AND_
+    int implicit _AND_
+    TBLRange* constraint)
+{
+    AVal *elmtVPtr;
+    unsigned long int tmpBytesDecoded = 0;
+    unsigned int currElmt;
+    TBLType *elmtType;
+    AVal *retVal = NULL;
+    AVal *eleVal;
+    AVal **tmpHndl;
+    AsnTag asnTag;
+    int i, mandatoryCount, mandatoryElmts;
+    int implicitRef;
+    void *tmp;
+    AsnInt value;
+    char* constraintmsg = NULL;
+    int elmtfound;
+    int indefinite;
+    
+    if (!TDEPushTagsAndLens (dec, type, implicit))
+        return FALSE;
+        
+#if TTBL>1
+    if (!constraint)
+	constraint = type->constraint;
+#endif
+
+    TDETYPE(dec,type,NULL,1);
+
+    switch (type->typeId)
+	{
+	  case TBL_TYPEREF:
+              /*
+               * carry over implicit ref if goes
+               * through typeref with no tags
+               */
+              implicitRef = type->content->a.typeRef->implicit ||
+        	  (implicit &&
+        	   ((type->tagList == NULL) || LIST_EMPTY (type->tagList)));
+
+              if (!TDEDecodeType (dec, &tmpBytesDecoded,
+            	    type->content->a.typeRef->typeDefPtr->type,
+              	    implicitRef, constraint))
+              {
+        	  TDEWARNUNEXPECTED(dec,type,type->content->a.typeRef->typeDefPtr->type);
+        	  TDESimpleDecode(dec, &tmpBytesDecoded);
+              }
+              break;
+
+	  case TBL_SEQUENCE:
+              /* go fwd though elmt type list */
+              tmp = CURR_LIST_NODE (type->content->a.elmts);
+              FOR_EACH_LIST_ELMT (elmtType, type->content->a.elmts)
+              {
+                  elmtfound = FALSE;
+        	  while (!elmtfound 
+			  && TDEInTag(dec,tmpBytesDecoded)
+			  && TDETagsMatch (elmtType, TDEPeekTag (dec)))
+                      elmtfound = TDEDecodeType (dec,&tmpBytesDecoded,
+                      	    elmtType, FALSE, NULL);
+        	  if (!elmtfound && !elmtType->optional)
+                      TDEWARNNONOPTIONAL(dec,type,elmtType);
+              }
+              SET_CURR_LIST_NODE (type->content->a.elmts, tmp);
+              
+              /* process remaining stuff in sequence */
+              while (TDEInTag(dec,tmpBytesDecoded))
+        	  {
+        	  TDEWARNUNEXPECTED(dec,type,NULL);
+        	  TDESimpleDecode(dec, &tmpBytesDecoded);
+        	  }
+              break;
+
+	  case TBL_SET:
+              mandatoryCount = 0;
+              mandatoryElmts = TDECountMandatoryElmts (type);
+              while (TDEInTag(dec,tmpBytesDecoded))
+        	  {
+                  asnTag = TDEPeekTag (dec);
+                  elmtfound = FALSE;
+                 /* find elmt that matches the peeked tag */
+                  tmp = CURR_LIST_NODE (type->content->a.elmts);
+                  FOR_EACH_LIST_ELMT (elmtType,
+                      	  type->content->a.elmts)
+                  {
+                      if (TDETagsMatch (elmtType, asnTag))
+                      {
+                          elmtfound = TRUE;
+                          break;
+                      }
+                  }
+                  SET_CURR_LIST_NODE (type->content->a.elmts, tmp);
+
+                  /* didn't find a match */
+                  if (!elmtfound || !TDEDecodeType (dec, &tmpBytesDecoded, 
+                    	     elmtType, FALSE, NULL))
+                      {
+                      TDEWARNUNEXPECTED(dec,type,elmtfound?elmtType:NULL);
+                      TDESimpleDecode(dec, &tmpBytesDecoded);
+                      }
+                  else
+                      {
+                      if (!elmtType->optional)
+                      	  mandatoryCount++;
+                      }
+
+        	  }
+              if (mandatoryCount != mandatoryElmts)
+              	  TDEWARNMANDATORY(dec,type);
+            break;
+
+
+	  case TBL_SEQUENCEOF:
+	  case TBL_SETOF:
+              elmtType = FIRST_LIST_ELMT (type->content->a.elmts);
+	      constraintmsg = "Size of SEQUENCE/SET OF";
+	      value = 0;
+
+              while (TDEInTag(dec,tmpBytesDecoded))
+              {
+                  if (!TDEDecodeType (dec, &tmpBytesDecoded, elmtType, 
+                      	      FALSE,NULL))
+                      {
+                      TDEWARNUNEXPECTED(dec,type,elmtType);
+                      TDESimpleDecode(dec, &tmpBytesDecoded);
+                      }
+                  else
+                      value++;
+              }
+            break;
+
+	  case TBL_CHOICE:
+              elmtfound = FALSE;
+	      if (TDEInTag(dec,tmpBytesDecoded)) 
+	      {
+		  asnTag = TDEPeekTag (dec);
+		  /* find elmt that matches the peeked tag */
+		  tmp = CURR_LIST_NODE (type->content->a.elmts);
+		  FOR_EACH_LIST_ELMT (elmtType, type->content->a.elmts)
+		  {
+		      if (TDETagsMatch (elmtType, asnTag))
+		      {
+			  elmtfound = TRUE;
+			  break;
+		      }
+		  }
+	      }
+              SET_CURR_LIST_NODE (type->content->a.elmts, tmp);
+              if (!elmtfound || !TDEDecodeType (dec, &tmpBytesDecoded, 
+                    	 elmtType, FALSE, NULL))
+                  {
+                  TDEWARNUNEXPECTED(dec,type,elmtfound?elmtType:NULL);
+                  TDESimpleDecode(dec, &tmpBytesDecoded);
+                  }
+            break;
+
+	  case TBL_BOOLEAN:
+              retVal = Asn1Alloc (sizeof (AsnBool));
+              BDecAsnBoolContent (dec->b, LAST_TAG(), LAST_LEN(),
+		    (AsnBool*) retVal, &tmpBytesDecoded, dec->env);
+            break;
+
+	  case TBL_INTEGER:
+	  case TBL_ENUMERATED:
+              retVal = Asn1Alloc (sizeof (AsnInt));
+              BDecAsnIntContent (dec->b, LAST_TAG(), LAST_LEN(),
+		    (AsnInt*) retVal, &tmpBytesDecoded, dec->env);
+	      constraintmsg = "INTEGER/ENUMERATED";
+	      value = *(AsnInt*)retVal;
+            break;
+
+	  case TBL_BITSTRING:
+              retVal = Asn1Alloc (sizeof (AsnBits));
+              BDecAsnBitsContent (dec->b, LAST_TAG(), LAST_LEN(),
+		    (AsnBits*) retVal, &tmpBytesDecoded, dec->env);
+            break;
+
+	  case TBL_OCTETSTRING:
+              retVal = Asn1Alloc (sizeof (AsnOcts));
+              BDecAsnOctsContent (dec->b, LAST_TAG(), LAST_LEN(),
+		    (AsnOcts*) retVal, &tmpBytesDecoded, dec->env);
+	      constraintmsg = "Length of OCTET STRING";
+	      value = ((AsnOcts*)retVal)->octetLen;
+	   break;
+
+	  case TBL_NULL:
+              retVal = Asn1Alloc (sizeof (AsnNull));
+              BDecAsnNullContent (dec->b, LAST_TAG(), LAST_LEN(),
+		    (AsnNull*) retVal, &tmpBytesDecoded, dec->env);
+            break;
+
+	  case TBL_OID:
+              retVal = Asn1Alloc (sizeof (AsnOid));
+              BDecAsnOidContent (dec->b, LAST_TAG(), LAST_LEN(),
+		    (AsnOid*) retVal, &tmpBytesDecoded, dec->env);
+            break;
+
+	  case TBL_REAL:
+              retVal = Asn1Alloc (sizeof (AsnReal));
+              BDecAsnRealContent (dec->b, LAST_TAG(), LAST_LEN(),
+		    (AsnReal*) retVal, &tmpBytesDecoded, dec->env);
+	   break;
+
+	  default:
+             retVal = NULL;
+             break;
+	}
+
+    TDETYPE(dec,type,retVal,0);
+    if (retVal)
+    	Asn1Free(retVal);
+
+    if (constraintmsg)
+	TDECheckConstraint(dec,type,constraint,value);
+
+    TDEPopTagsAndLens (dec, &tmpBytesDecoded, type, implicit);
+    (*bytesDecoded) += tmpBytesDecoded;
+    return TRUE;
+}
+
+int
+TDEDecodeSpecific PARAMS ((dec, bytesDecoded, type),
+    TDEDecoder dec _AND_
+    unsigned long int *bytesDecoded _AND_
+    TBLType* type)
+{
+    int val;
+    
+    *bytesDecoded = 0;
+    dec->rewindsize = 0;
+    dec->nTlStk = 0;
+    
+    if ((val = setjmp (dec->env)) == 0)
+    {
+        TDEDecodeType (dec, bytesDecoded, type, FALSE, NULL);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+int
+TDEDecodeUnknown PARAMS ((dec, bytesDecoded),
+    TDEDecoder dec _AND_
+    unsigned long int *bytesDecoded)
+{
+    TBLModule *tblMod = NULL;
+    TBLTypeDef *tblTd = NULL;
+    
+    *bytesDecoded = 0;
+
+    FOR_EACH_LIST_ELMT (tblMod, dec->tbl->modules)
+	break;
+    if (!tblMod)
+    {
+        TDEERRORMSG (dec,"No module in grammar");
+	return FALSE;
+    }
+
+    FOR_EACH_LIST_ELMT_RVS (tblTd, tblMod->typeDefs)
+	break;
+    if (!tblTd)
+    {
+        TDEERRORMSG (dec,"No type in first module of grammar");
+        return FALSE;
+    }
+    
+    return TDEDecodeSpecific (dec, bytesDecoded, tblTd->type);
+}
+
+struct STDEDecoder sdec;
+
+void
+TDEErrorHandler PARAMS ((str, severity),
+    char* str _AND_
+    int severity)
+{
+    TDEERRORMSG(&sdec,str);
+}
+
+int 
+TdeDecodeSpecific PARAMS ((tbl, b, type, bytesDecoded, typeproc, simpleproc, excproc),
+    TBL *tbl _AND_
+    BUF_TYPE b _AND_
+    TBLType* type _AND_
+    unsigned long int *bytesDecoded _AND_
+    TdeTypeProc typeproc _AND_
+    TdeSimpleProc simpleproc _AND_
+    TdeExcProc excproc)
+{
+    int result;
+    Asn1ErrorHandler former = Asn1InstallErrorHandler(TDEErrorHandler);
+    sdec.tbl = tbl;
+    sdec.b = b;
+    sdec.typeproc = typeproc;
+    sdec.simpleproc = simpleproc;
+    sdec.excproc = excproc;
+    result = TDEDecodeSpecific(&sdec,bytesDecoded,type);
+    Asn1InstallErrorHandler(former);
+    return result;
+}
+
+int 
+TdeDecode PARAMS ((tbl, b, bytesDecoded, typeproc, simpleproc, excproc),
+    TBL *tbl _AND_
+    BUF_TYPE b _AND_
+    unsigned long int *bytesDecoded _AND_
+    TdeTypeProc typeproc _AND_
+    TdeSimpleProc simpleproc _AND_
+    TdeExcProc excproc)
+{
+    int result;
+    Asn1ErrorHandler former = Asn1InstallErrorHandler(TDEErrorHandler);
+    sdec.tbl = tbl;
+    sdec.b = b;
+    sdec.typeproc = typeproc;
+    sdec.simpleproc = simpleproc;
+    sdec.excproc = excproc;
+    result = TDEDecodeUnknown(&sdec,bytesDecoded);
+    Asn1InstallErrorHandler(former);
+    return result;
+}
+#endif
diff --git a/SecuritySNACCRuntime/c-lib/src/tbl-print.c b/SecuritySNACCRuntime/c-lib/src/tbl-print.c
new file mode 100644
index 00000000..128f3d29
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/tbl-print.c
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+
+#ifdef TTBL
+
+/*
+ * tbl_print.c - type table value printer
+ *
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include "tbl-incl.h"
+
+static int indentIncrG = 2;
+
+/*
+ * Print value v to file f as though it is of type modName.typeName in
+ * table tbl.
+ */
+void
+TblPrintValue PARAMS ((tbl, modName, typeName, f, v),
+    TBL *tbl _AND_
+    char *modName _AND_
+    char *typeName _AND_
+    FILE *f _AND_
+    AVal *v)
+{
+    TBLTypeDef *tblTd;
+    TBLModule *tblMod;
+
+    tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod);
+
+    if (tblTd == NULL)
+    {
+        TblError ("TblEncode: Could not find a type definition with the given module and name");
+    }
+    else
+    {
+        fprintf (f, "value %s.%s ::= \n", tblMod->name.octs, typeName);
+        TblPrintTypeValue (tblTd->type, f, v, 0);
+    }
+
+}  /* TblPrint */
+
+/*
+ * starts using indent after first newline printed by this routine
+ */
+void
+TblPrintTypeValue PARAMS ((tblT, f, v, indent),
+    TBLType *tblT _AND_
+    FILE *f _AND_
+    AVal *v _AND_
+    unsigned short int indent)
+{
+    AVal *elmtV;
+    AsnList *lVal;
+    unsigned int currElmt;
+    TBLType *listElmtType;
+    TBLType *structElmtType;
+    TBLType *choiceElmtType;
+    AChoiceVal *cVal;
+    AStructVal *sVal;
+    void *tmp;
+
+    switch (tblT->typeId)
+    {
+      case TBL_TYPEREF:
+          TblPrintTypeValue (tblT->content->a.typeRef->typeDefPtr->type, f, v, indent);
+          break;
+
+      case TBL_SEQUENCE:
+      case TBL_SET:
+          fprintf (f,"{\n");
+          currElmt = 0;
+          sVal = (AStructVal*)v;
+          tmp = CURR_LIST_NODE (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts)
+          {
+              Indent (f, indent+indentIncrG);
+              elmtV = sVal[currElmt++];
+              if (!(structElmtType->optional && (elmtV == NULL)))
+              {
+                  if (structElmtType->fieldName.octs != NULL)
+                      fprintf (f,"%s ", structElmtType->fieldName.octs);
+
+                  TblPrintTypeValue (structElmtType, f, elmtV, indent+indentIncrG);
+
+                  if (structElmtType != LAST_LIST_ELMT (tblT->content->a.elmts))
+                      fprintf (f,",\n");
+                  else
+                      fprintf (f,"\n");
+              }
+          }
+          /* restore list curr in case recursive type */
+          SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
+          Indent (f,indent);
+          fprintf (f,"}");
+          break;
+
+      case TBL_SEQUENCEOF:
+      case TBL_SETOF:
+          fprintf (f,"{\n");
+          lVal = (AsnList*)v;
+          listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts);
+          tmp = CURR_LIST_NODE (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT (elmtV, lVal)
+          {
+              Indent (f, indent+indentIncrG);
+              TblPrintTypeValue (listElmtType, f, elmtV, indent+indentIncrG);
+              if (elmtV != LAST_LIST_ELMT (lVal))
+                  fprintf (f,",\n");
+              else
+                  fprintf (f,"\n");
+          }
+          /* restore old list curr ptr */
+          SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
+          Indent (f,indent);
+          fprintf (f,"}");
+        break;
+
+      case TBL_CHOICE:
+          cVal = (AChoiceVal*) v;
+          choiceElmtType = (TBLType*)GetAsnListElmt (tblT->content->a.elmts, cVal->choiceId);
+          if (choiceElmtType->fieldName.octs != NULL)
+              fprintf (f,"%s ", choiceElmtType->fieldName.octs);
+          TblPrintTypeValue (choiceElmtType, f, cVal->val, indent+indentIncrG);
+        break;
+
+      case TBL_BOOLEAN:
+          PrintAsnBool (f, (AsnBool*)v,indent);
+        break;
+
+      case TBL_INTEGER:
+      case TBL_ENUMERATED:
+          PrintAsnInt (f, (AsnInt*)v, indent);
+        break;
+
+      case TBL_BITSTRING:
+          PrintAsnBits (f, (AsnBits*)v, indent);
+        break;
+
+      case TBL_OCTETSTRING:
+           PrintAsnOcts (f, (AsnOcts*)v, indent);
+        break;
+
+      case TBL_NULL:
+          PrintAsnNull (f, (AsnNull*)v, indent);
+        break;
+
+      case TBL_OID:
+          PrintAsnOid (f, (AsnOid*)v, indent);
+        break;
+
+      case TBL_REAL:
+          PrintAsnReal (f, (AsnReal*)v, indent);
+        break;
+
+      default:
+         fprintf (f, "<ERROR - unknown type!>");
+    }
+
+}  /* TblPrintTypeValue */
+
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/src/tbl-util.c b/SecuritySNACCRuntime/c-lib/src/tbl-util.c
new file mode 100644
index 00000000..512ff5ca
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/tbl-util.c
@@ -0,0 +1,443 @@
+/*
+ * 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.
+ */
+
+
+#ifdef TTBL
+
+/*
+ * tbl_util.c - type table utilities.
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it provided that this copyright/license information is retained
+ * in original form.
+ *
+ * If you modify this file, you must clearly indicate your changes.
+ *
+ * This source code is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include "tbl-incl.h"
+#include "sbuf.h"
+
+/* non -exported routine protos */
+void TblLinkIndexes PROTO ((TBL *tbl));
+void TblLinkTypeRefs PROTO ((TBL *tbl, TBLType *tblT));
+
+void TblFixTags PROTO ((TBL *tbl));
+void TblFixTypeTags PROTO ((TBLType *tblT));
+void TblSetTagForms PROTO ((TBLType *t));
+
+
+/*
+ * opens given filename, determines its size, allocs a block
+ * of that size and reads the file into it. returns a pointer
+ * to this block.  Prints an err msgs is something screwed up
+ * and returns NULL.  Sets the size param to the size of the file.
+ */
+char*
+LoadFile PARAMS ((fileName, size),
+    char *fileName _AND_
+    unsigned long int *size)
+{
+    FILE *f;
+    unsigned long int fsize;
+    char *fileData;
+
+    f = fopen (fileName, "r");
+
+    if (f == NULL)
+    {
+        Asn1Error("Could not open file for reading.\n");
+        return NULL;
+    }
+
+    fseek (f, 0, 2);    /* seek to end */
+    fsize = ftell (f);  /* get size of file */
+    fseek (f, 0, 0);    /* seek to beginning */
+
+    *size = fsize;
+    fileData = (char *) malloc (fsize);
+
+    if (fileData == NULL)
+    {
+        Asn1Error("Not enough memory to read in file.\n");
+        return NULL;
+    }
+
+    if (fread (fileData, sizeof (char), fsize, f) != fsize)
+    {
+        free (fileData);
+        fileData = NULL;
+        Asn1Error("Trouble reading file.\n");
+    }
+
+    fclose (f);
+    return fileData;
+}  /* LoadFile */
+
+
+TBL*
+LoadTblFile PARAMS ((tblFileName),
+    char *tblFileName)
+{
+    SBuf sb;
+    SBuf *sbPtr;
+    GenBuf gb;
+    TBL *tbl;
+    unsigned long int fsize;
+    char *fileData;
+    AsnLen decodedLen;
+    ENV_TYPE env;
+    int val;
+
+
+    fileData = LoadFile (tblFileName, &fsize);
+    if (fileData == NULL)
+        return NULL;
+
+    SBufInstallData (&sb, fileData, fsize);
+    SBufResetInReadMode (&sb);
+    PutSBufInGenBuf (&sb, &gb);
+
+    decodedLen = 0;
+
+    tbl = (TBL*)Asn1Alloc (sizeof (TBL));
+
+    if ((val = setjmp (env)) == 0)
+        BDecTBL (&gb, tbl, &decodedLen, env);
+    else
+        return NULL;
+
+    /* convert the typeDefIndexes into real pointers */
+    TblLinkIndexes (tbl);
+
+    TblFixTags (tbl);
+
+    free (fileData); /* malloc'd in LoadFile */
+
+    return tbl;
+}
+
+
+/*
+ * just use slow individual lookup instead of creating a table
+ * (a conversion tbl could be built during decoding)
+ */
+void
+TblLinkIndexes PARAMS ((tbl),
+    TBL *tbl)
+{
+    TBLModule *tblMod;
+    TBLTypeDef *tblTd;
+
+    FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
+    {
+        FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs)
+        {
+            /* go through the types looking for TBLTypeRefs */
+            TblLinkTypeRefs (tbl, tblTd->type);
+        }
+    }
+} /* TBLLinkIndexes */
+
+
+/*
+ * set tags forms and include encoded version to improve
+ * decoding and encoding performance.
+ */
+void
+TblFixTags PARAMS ((tbl),
+    TBL *tbl)
+{
+    TBLModule *tblMod;
+    TBLTypeDef *tblTd;
+
+    FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
+    {
+        FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs)
+        {
+            TblFixTypeTags (tblTd->type);
+        }
+    }
+} /* TBLFixTags */
+
+
+
+/*
+ * recursively descends type looking for typeDefIds in type refs
+ * to convert to the type defs actual ptr
+ *
+ * Also sets the form field for each tag. (this speeds up enc/dec).
+ * Note that the form bit is not in the encoded version of a TBLTag.
+ */
+void
+TblLinkTypeRefs PARAMS ((tbl, tblT),
+    TBL *tbl _AND_
+    TBLType *tblT)
+{
+    TBLType *tblElmtT;
+    void *tmp;
+
+    switch (tblT->typeId)
+    {
+      case TBL_BOOLEAN:
+      case TBL_INTEGER:
+      case TBL_BITSTRING:
+      case TBL_OCTETSTRING:
+      case TBL_NULL:
+      case TBL_OID:
+      case TBL_REAL:
+      case TBL_ENUMERATED:
+          /* not contained type refs so return */
+          break;
+
+      case TBL_SEQUENCE:
+      case TBL_SET:
+      case TBL_SEQUENCEOF:
+      case TBL_SETOF:
+      case TBL_CHOICE:
+          /* look for contained type refs */
+          tmp = CURR_LIST_NODE (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts)
+          {
+              TblLinkTypeRefs (tbl, tblElmtT);
+          }
+          SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
+          break;
+
+      case TBL_TYPEREF:
+          /* convert type def index into a pointer to the type def */
+          tblT->content->a.typeRef->typeDefPtr =
+              TblFindTypeDefByIndex (tbl, tblT->content->a.typeRef->typeDef);
+          break;
+    }
+} /* TblLinkTypeRefs */
+void
+TblFixTypeTags PARAMS ((tblT),
+    TBLType *tblT)
+{
+    void *tmp;
+    TBLType *tblElmtT;
+
+    TblSetTagForms (tblT);
+    switch (tblT->typeId)
+    {
+      case TBL_SEQUENCE:
+      case TBL_SET:
+      case TBL_SEQUENCEOF:
+      case TBL_SETOF:
+      case TBL_CHOICE:
+          /* fix tags in elmt types */
+          tmp = CURR_LIST_NODE (tblT->content->a.elmts);
+          FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts)
+          {
+              TblFixTypeTags (tblElmtT);
+          }
+          SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
+          break;
+
+      default:
+        break;
+   }
+}
+
+void
+TblSetTagForms PARAMS ((tblT),
+    TBLType *tblT)
+{
+    TBLTag *tblTag;
+    TBLType *tmpTblT;
+    int numTags;
+    TBLTypeId tid;
+    BER_FORM form;
+
+    if (tblT->tagList == NULL)
+        return;
+
+    numTags = LIST_COUNT (tblT->tagList);
+
+    /*
+     * get real type id (skip through type refs)
+     * count total number of tags too.
+     */
+    for (tmpTblT = tblT; tmpTblT->typeId == TBL_TYPEREF; tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type)
+    {
+	if (tmpTblT->tagList)
+	    numTags += LIST_COUNT (tmpTblT->tagList);
+        if (tmpTblT->content->a.typeRef->implicit)
+            numTags--;
+    }
+    tid = tmpTblT->typeId;
+
+    /* only traverse this types tags */
+    FOR_EACH_LIST_ELMT (tblTag, tblT->tagList)
+    {
+        if (numTags > 1)
+            form = tblTag->form = CONS;
+        else
+            switch (tid)
+            {
+              case TBL_SEQUENCE:
+              case TBL_SET:
+              case TBL_SEQUENCEOF:
+              case TBL_SETOF:
+              case TBL_CHOICE:
+                  form = tblTag->form = CONS;
+                  break;
+
+              case TBL_OCTETSTRING:
+              case TBL_BITSTRING:
+                  tblTag->form = ANY_FORM;
+                  form = PRIM; /* store as prim (for encoder - always prim) */
+                  break;
+
+              default:
+                  form = tblTag->form = PRIM;
+                  break;
+          }
+
+        tblTag->encTag = MAKE_TAG_ID (TblTagClassToBer (tblTag->tclass), form, tblTag->code);
+        numTags--;
+    }
+} /* TblSetTagForms */
+
+
+
+TBLTypeDef*
+TblFindTypeDef PARAMS ((tbl, modName, typeName, tblModHndl),
+    TBL *tbl _AND_
+    char *modName _AND_
+    char *typeName _AND_
+    TBLModule **tblModHndl)
+{
+    TBLModule *tblMod;
+    TBLTypeDef *tblTd;
+    void *tmp;
+
+    /* look in named module only if given */
+    if (modName != NULL)
+    {
+        tblMod = TblFindModule (tbl, modName);
+        *tblModHndl = tblMod;
+        if (tblMod == NULL)
+            return NULL;
+
+        return TblFindTypeDefInMod (tblMod, typeName);
+    }
+    else /* look in all modules and return first instance */
+    {
+        tmp = CURR_LIST_NODE (tbl->modules);
+        FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
+        {
+            tblTd = TblFindTypeDefInMod (tblMod, typeName);
+            if (tblTd != NULL)
+            {
+                *tblModHndl = tblMod;
+                SET_CURR_LIST_NODE (tbl->modules, tmp);
+                return tblTd;
+            }
+        }
+        SET_CURR_LIST_NODE (tbl->modules, tmp);
+    }
+    return NULL; /* not found */
+} /* TblFindTypeDef */
+
+
+TBLTypeDef*
+TblFindTypeDefInMod PARAMS ((tblMod, typeName),
+    TBLModule *tblMod _AND_
+    char *typeName)
+{
+    TBLTypeDef *tblTd;
+    void *tmp;
+
+    tmp = CURR_LIST_NODE (tblMod->typeDefs);
+    FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs)
+    {
+        if (strcmp (tblTd->typeName.octs, typeName) == 0)
+        {
+            SET_CURR_LIST_NODE (tblMod->typeDefs, tmp);
+            return tblTd;
+        }
+    }
+    SET_CURR_LIST_NODE (tblMod->typeDefs, tmp);
+    return NULL;
+} /* TblFindTypeDefInMod */
+
+
+TBLTypeDef*
+TblFindTypeDefByIndex PARAMS ((tbl, id),
+    TBL *tbl _AND_
+    TBLTypeDefId id)
+{
+    TBLModule *tblMod;
+    TBLTypeDef *tblTd;
+    void *tmp1;
+    void *tmp2;
+
+     /* look in all modules and return typedef with given id */
+    tmp1 = CURR_LIST_NODE (tbl->modules);
+    FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
+    {
+        tmp2 = CURR_LIST_NODE (tblMod->typeDefs);
+        FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs)
+        {
+            if (tblTd->typeDefId == id)
+            {
+                SET_CURR_LIST_NODE (tblMod->typeDefs, tmp2);
+                SET_CURR_LIST_NODE (tbl->modules, tmp1);
+                return tblTd;
+            }
+        }
+        SET_CURR_LIST_NODE (tblMod->typeDefs, tmp2);
+    }
+    SET_CURR_LIST_NODE (tbl->modules, tmp1);
+
+    return NULL;
+} /* TblFindTypeDefByIndex */
+
+
+TBLModule*
+TblFindModule PARAMS ((tbl, modName),
+    TBL *tbl _AND_
+    char *modName)
+{
+    TBLModule *tblMod;
+    void *tmp;
+
+    tmp = CURR_LIST_NODE (tbl->modules);
+    FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
+    {
+        if (strcmp (tblMod->name.octs, modName) == 0)
+        {
+            SET_CURR_LIST_NODE (tbl->modules, tmp);
+            return tblMod;
+        }
+    }
+    SET_CURR_LIST_NODE (tbl->modules, tmp);
+    return NULL;
+
+} /* TblFindModule */
+
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/src/tbl.c b/SecuritySNACCRuntime/c-lib/src/tbl.c
new file mode 100644
index 00000000..c2daa0fe
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/src/tbl.c
@@ -0,0 +1,2137 @@
+/*
+ * 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.
+ */
+
+
+#if TTBL
+/*
+ *    tbl.c
+ *
+ *    "TBL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Thu Jun  8 12:35:28 2000
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "tbl.h"
+
+
+AsnLen
+BEncTBLRangeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLRange *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->to));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->from));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLRangeContent */
+
+void
+BDecTBLRangeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLRange *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->from), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -100);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->to), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -101);
+    }
+    else
+        longjmp (env, -102);
+
+
+    if (!seqDone)
+        longjmp (env, -103);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLRangeContent */
+
+void
+PrintTBLRange PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLRange *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"from ");
+    PrintAsnInt (f, (&v->from), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"to ");
+    PrintAsnInt (f, (&v->to), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLRange */
+
+void
+FreeTBLRange PARAMS ((v),
+TBLRange *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeAsnInt ((&v->from));
+
+    FreeAsnInt ((&v->to));
+
+}  /* FreeTBLRange */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumber *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->value));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLNamedNumberContent */
+
+void
+BDecTBLNamedNumberContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLNamedNumber *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->name), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -104);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->value), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -105);
+    }
+    else
+        longjmp (env, -106);
+
+
+    if (!seqDone)
+        longjmp (env, -107);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLNamedNumberContent */
+
+void
+PrintTBLNamedNumber PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLNamedNumber *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"name ");
+    PrintPrintableString (f, (&v->name), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"value ");
+    PrintAsnInt (f, (&v->value), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLNamedNumber */
+
+void
+FreeTBLNamedNumber PARAMS ((v),
+TBLNamedNumber *v)
+{
+
+    if (v == NULL)
+        return;
+    FreePrintableString ((&v->name));
+
+    FreeAsnInt ((&v->value));
+
+}  /* FreeTBLNamedNumber */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberListContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumberList *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLNamedNumberListContent */
+
+void
+BDecTBLNamedNumberListContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLNamedNumberList *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLNamedNumber **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLNamedNumber**) AsnListAppend (v);
+    (*tmpVar) = (TBLNamedNumber*) Asn1Alloc (sizeof (TBLNamedNumber));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLNamedNumberContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -108);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLNamedNumberListContent */
+
+void
+PrintTBLNamedNumberList PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLNamedNumberList *v _AND_
+unsigned short int indent)
+{
+    TBLNamedNumber *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLNamedNumber (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLNamedNumber*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLNamedNumberList */
+
+void
+FreeTBLNamedNumberList PARAMS ((v),
+TBLNamedNumberList *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLNamedNumber ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLNamedNumberList */
+
+
+
+
+AsnLen
+BEncTBLTypeRefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeRef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnBoolContent (b, (&v->implicit));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeRefContent */
+
+void
+BDecTBLTypeRefContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeRef *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeDefIdContent (b, tagId1, elmtLen1, (&v->typeDef), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -109);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->implicit), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -110);
+    }
+    else
+        longjmp (env, -111);
+
+
+    if (!seqDone)
+        longjmp (env, -112);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeRefContent */
+
+void
+PrintTBLTypeRef PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeRef *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDef ");
+    PrintTBLTypeDefId (f, (&v->typeDef), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"implicit ");
+    PrintAsnBool (f, (&v->implicit), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeRef */
+
+void
+FreeTBLTypeRef PARAMS ((v),
+TBLTypeRef *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeDefId ((&v->typeDef));
+
+    FreeAsnBool ((&v->implicit));
+
+}  /* FreeTBLTypeRef */
+
+
+
+
+AsnLen
+BEncTBLTagContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTag *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->code));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTagClassContent (b, (&v->tclass));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 10);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTagContent */
+
+void
+BDecTBLTagContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTag *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTagClassContent (b, tagId1, elmtLen1, (&v->tclass), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -113);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->code), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -114);
+    }
+    else
+        longjmp (env, -115);
+
+
+    if (!seqDone)
+        longjmp (env, -116);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTagContent */
+
+void
+PrintTBLTag PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTag *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"tclass ");
+    PrintTBLTagClass (f, (&v->tclass), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"code ");
+    PrintAsnInt (f, (&v->code), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTag */
+
+void
+FreeTBLTag PARAMS ((v),
+TBLTag *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTagClass ((&v->tclass));
+
+    FreeAsnInt ((&v->code));
+
+}  /* FreeTBLTag */
+
+
+
+
+AsnLen
+BEncTBLTypeSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTagContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeSeqOfContent */
+
+void
+BDecTBLTypeSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLTag **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLTag**) AsnListAppend (v);
+    (*tmpVar) = (TBLTag*) Asn1Alloc (sizeof (TBLTag));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTagContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -117);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeSeqOfContent */
+
+void
+PrintTBLTypeSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLTag *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLTag (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLTag*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeSeqOf */
+
+void
+FreeTBLTypeSeqOf PARAMS ((v),
+TBLTypeSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLTag ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLTypeSeqOf */
+
+
+
+
+AsnLen
+BEncTBLTypeContentSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContentSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeContentSeqOfContent */
+
+void
+BDecTBLTypeContentSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeContentSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLType **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLType**) AsnListAppend (v);
+    (*tmpVar) = (TBLType*) Asn1Alloc (sizeof (TBLType));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTypeContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -118);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContentSeqOfContent */
+
+void
+PrintTBLTypeContentSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeContentSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLType *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLType (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLType*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeContentSeqOf */
+
+void
+FreeTBLTypeContentSeqOf PARAMS ((v),
+TBLTypeContentSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLType ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLTypeContentSeqOf */
+
+
+
+
+AsnLen
+BEncTBLTypeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLType *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->values)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberListContent (b, (v->values));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 6);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLRangeContent (b, (v->constraint));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 5);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    itemLen = BEncPrintableStringContent (b, (&v->fieldName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 4);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentContent (b, (v->content));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncAsnBoolContent (b, (&v->optional));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeIdContent (b, (&v->typeId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeContent */
+
+void
+BDecTBLTypeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLType *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+    AsnLen totalElmtsLen3 = 0;
+    AsnLen elmtLen3;
+    AsnTag tagId3;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeIdContent (b, tagId1, elmtLen1, (&v->typeId), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -119);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->optional), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -120);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 2))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->tagList) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->tagList), env);
+    BDecTBLTypeSeqOfContent (b, tagId1, elmtLen1, (v->tagList), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 3))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->content) = (TBLTypeContent*) Asn1Alloc (sizeof (TBLTypeContent));
+    CheckAsn1Alloc ((v->content), env);
+    tagId2 = BDecTag (b, &totalElmtsLen1, env);
+    elmtLen2 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeContentContent (b, tagId2, elmtLen2, (v->content), &totalElmtsLen1, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+        BDecEoc(b, &totalElmtsLen1, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+        BDecEoc (b, &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+    else
+        longjmp (env, -121);
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 4)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 4))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->fieldName), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, CONS, 5))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->constraint) = (TBLRange*) Asn1Alloc (sizeof (TBLRange));
+    CheckAsn1Alloc ((v->constraint), env);
+    BDecTBLRangeContent (b, tagId1, elmtLen1, (v->constraint), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, CONS, 6))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->values) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->values), env);
+    BDecTBLNamedNumberListContent (b, tagId1, elmtLen1, (v->values), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -122);
+    }
+
+
+    if (!seqDone)
+        longjmp (env, -123);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContent */
+
+void
+PrintTBLType PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLType *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeId ");
+    PrintTBLTypeId (f, (&v->typeId), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"optional ");
+    PrintAsnBool (f, (&v->optional), indent + stdIndentG);
+    fprintf (f, ",\n");
+    if (NOT_NULL ((v->tagList)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"tagList ");
+    PrintTBLTypeSeqOf (f, (v->tagList), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"content ");
+    PrintTBLTypeContent (f, (v->content), indent + stdIndentG);
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"fieldName ");
+    PrintPrintableString (f, (&v->fieldName), indent + stdIndentG);
+    }
+    if (NOT_NULL ((v->constraint)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"constraint ");
+    PrintTBLRange (f, (v->constraint), indent + stdIndentG);
+    }
+    if (NOT_NULL ((v->values)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"values ");
+    PrintTBLNamedNumberList (f, (v->values), indent + stdIndentG);
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLType */
+
+void
+FreeTBLType PARAMS ((v),
+TBLType *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeId ((&v->typeId));
+
+    FreeAsnBool ((&v->optional));
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    FreeTBLTypeSeqOf ((v->tagList));
+    Asn1Free ((v->tagList));
+    }
+
+    FreeTBLTypeContent ((v->content));
+    Asn1Free ((v->content));
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    FreePrintableString ((&v->fieldName));
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    FreeTBLRange ((v->constraint));
+    Asn1Free ((v->constraint));
+    }
+
+    if (NOT_NULL ((v->values)))
+    {
+    FreeTBLNamedNumberList ((v->values));
+    Asn1Free ((v->values));
+    }
+
+}  /* FreeTBLType */
+
+
+
+
+AsnLen
+BEncTBLTypeContentContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContent *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_PRIMTYPE:
+    itemLen = BEncAsnNullContent (b, (&v->a.primType));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_ELMTS:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncTBLTypeContentContent */
+
+void
+BDecTBLTypeContentContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeContent *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    switch (tagId0)
+    {
+       case MAKE_TAG_ID (CNTX, PRIM, 0):
+        (v->choiceId) = TBLTYPECONTENT_PRIMTYPE;
+    BDecAsnNullContent (b, tagId0, elmtLen0, (&v->a.primType), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, CONS, 1):
+        (v->choiceId) = TBLTYPECONTENT_ELMTS;
+    (v->a.elmts) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->a.elmts), env);
+    BDecTBLTypeContentSeqOfContent (b, tagId0, elmtLen0, (v->a.elmts), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, CONS, 2):
+        (v->choiceId) = TBLTYPECONTENT_TYPEREF;
+    (v->a.typeRef) = (TBLTypeRef*) Asn1Alloc (sizeof (TBLTypeRef));
+    CheckAsn1Alloc ((v->a.typeRef), env);
+    BDecTBLTypeRefContent (b, tagId0, elmtLen0, (v->a.typeRef), &totalElmtsLen1, env);
+    break;
+
+    default:
+        Asn1Error ("ERROR - unexpected tag in CHOICE\n");
+        longjmp (env, -124);
+        break;
+    } /* end switch */
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContentContent */
+
+void
+PrintTBLTypeContent PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeContent *v _AND_
+unsigned short int indent)
+{
+    switch (v->choiceId)
+    {
+      case TBLTYPECONTENT_PRIMTYPE:
+          fprintf (f,"primType ");
+    PrintAsnNull (f, (&v->a.primType), indent + stdIndentG);
+          break;
+
+      case TBLTYPECONTENT_ELMTS:
+          fprintf (f,"elmts ");
+    PrintTBLTypeContentSeqOf (f, (v->a.elmts), indent + stdIndentG);
+          break;
+
+      case TBLTYPECONTENT_TYPEREF:
+          fprintf (f,"typeRef ");
+    PrintTBLTypeRef (f, (v->a.typeRef), indent + stdIndentG);
+          break;
+
+    }
+}  /* PrintTBLTypeContent */
+
+void
+FreeTBLTypeContent PARAMS ((v),
+TBLTypeContent *v)
+{
+
+    if (v == NULL)
+        return;
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_ELMTS:
+    FreeTBLTypeContentSeqOf ((v->a.elmts));
+    Asn1Free ((v->a.elmts));
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    FreeTBLTypeRef ((v->a.typeRef));
+    Asn1Free ((v->a.typeRef));
+
+    break;
+
+    }
+}  /* FreeTBLTypeContent */
+
+
+
+
+AsnLen
+BEncTBLTypeDefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeDef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    itemLen = BEncAsnNullContent (b, (v->isPdu));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 5);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, (v->type));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->typeName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 19);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeDefContent */
+
+void
+BDecTBLTypeDefContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeDef *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeDefIdContent (b, tagId1, elmtLen1, (&v->typeDefId), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -125);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE)) ||
+(tagId1 == MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->typeName), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -126);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->type) = (TBLType*) Asn1Alloc (sizeof (TBLType));
+    CheckAsn1Alloc ((v->type), env);
+    BDecTBLTypeContent (b, tagId1, elmtLen1, (v->type), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+    else
+        longjmp (env, -127);
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->isPdu) = (AsnNull*) Asn1Alloc (sizeof (AsnNull));
+    CheckAsn1Alloc ((v->isPdu), env);
+    BDecAsnNullContent (b, tagId1, elmtLen1, (v->isPdu), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -128);
+    }
+
+
+    if (!seqDone)
+        longjmp (env, -129);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeDefContent */
+
+void
+PrintTBLTypeDef PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeDef *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDefId ");
+    PrintTBLTypeDefId (f, (&v->typeDefId), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeName ");
+    PrintPrintableString (f, (&v->typeName), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"type ");
+    PrintTBLType (f, (v->type), indent + stdIndentG);
+    if (NOT_NULL ((v->isPdu)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"isPdu ");
+    PrintAsnNull (f, (v->isPdu), indent + stdIndentG);
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeDef */
+
+void
+FreeTBLTypeDef PARAMS ((v),
+TBLTypeDef *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeDefId ((&v->typeDefId));
+
+    FreePrintableString ((&v->typeName));
+
+    FreeTBLType ((v->type));
+    Asn1Free ((v->type));
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    FreeAsnNull ((v->isPdu));
+    Asn1Free ((v->isPdu));
+    }
+
+}  /* FreeTBLTypeDef */
+
+
+
+
+AsnLen
+BEncTBLModuleSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModuleSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeDefContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLModuleSeqOfContent */
+
+void
+BDecTBLModuleSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLModuleSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLTypeDef **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLTypeDef**) AsnListAppend (v);
+    (*tmpVar) = (TBLTypeDef*) Asn1Alloc (sizeof (TBLTypeDef));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTypeDefContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -130);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLModuleSeqOfContent */
+
+void
+PrintTBLModuleSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLModuleSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLTypeDef *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLTypeDef (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLTypeDef*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLModuleSeqOf */
+
+void
+FreeTBLModuleSeqOf PARAMS ((v),
+TBLModuleSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLTypeDef ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLModuleSeqOf */
+
+
+
+
+AsnLen
+BEncTBLModuleContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModule *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnBoolContent (b, (&v->isUseful));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->id));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLModuleContent */
+
+void
+BDecTBLModuleContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLModule *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->name), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -131);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnOidContent (b, tagId1, elmtLen1, (&v->id), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 2))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->isUseful), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -132);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 3))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->typeDefs) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->typeDefs), env);
+    BDecTBLModuleSeqOfContent (b, tagId1, elmtLen1, (v->typeDefs), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -133);
+    }
+    else
+        longjmp (env, -134);
+
+
+    if (!seqDone)
+        longjmp (env, -135);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLModuleContent */
+
+void
+PrintTBLModule PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLModule *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"name ");
+    PrintPrintableString (f, (&v->name), indent + stdIndentG);
+    fprintf (f, ",\n");
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"id ");
+    PrintAsnOid (f, (&v->id), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"isUseful ");
+    PrintAsnBool (f, (&v->isUseful), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDefs ");
+    PrintTBLModuleSeqOf (f, (v->typeDefs), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLModule */
+
+void
+FreeTBLModule PARAMS ((v),
+TBLModule *v)
+{
+
+    if (v == NULL)
+        return;
+    FreePrintableString ((&v->name));
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    FreeAsnOid ((&v->id));
+    }
+
+    FreeAsnBool ((&v->isUseful));
+
+    FreeTBLModuleSeqOf ((v->typeDefs));
+    Asn1Free ((v->typeDefs));
+
+}  /* FreeTBLModule */
+
+
+
+
+AsnLen
+BEncTBLSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLSeqOfContent */
+
+void
+BDecTBLSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLModule **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLModule**) AsnListAppend (v);
+    (*tmpVar) = (TBLModule*) Asn1Alloc (sizeof (TBLModule));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLModuleContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -136);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLSeqOfContent */
+
+void
+PrintTBLSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLModule *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLModule (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLModule*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLSeqOf */
+
+void
+FreeTBLSeqOf PARAMS ((v),
+TBLSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLModule ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLSeqOf */
+
+
+
+
+AsnLen BEncTBL PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncTBLContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    return l;
+} /* BEncTBL */
+
+void BDecTBL PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+TBL *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        Asn1Error ("BDecTBL: ERROR - wrong tag\n");
+        longjmp (env, -137);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecTBLContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecTBL */
+
+AsnLen
+BEncTBLContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLSeqOfContent (b, (v->modules));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalLenStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTags));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypes));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumModules));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLContent */
+
+void
+BDecTBLContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBL *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumModules), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -138);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTypeDefs), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -139);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTypes), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -140);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTags), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -141);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumStrings), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -142);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalLenStrings), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -143);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->modules) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->modules), env);
+    BDecTBLSeqOfContent (b, tagId1, elmtLen1, (v->modules), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -144);
+    }
+    else
+        longjmp (env, -145);
+
+
+    if (!seqDone)
+        longjmp (env, -146);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLContent */
+
+void
+PrintTBL PARAMS ((f, v, indent),
+FILE* f _AND_
+TBL *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumModules ");
+    PrintAsnInt (f, (&v->totalNumModules), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTypeDefs ");
+    PrintAsnInt (f, (&v->totalNumTypeDefs), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTypes ");
+    PrintAsnInt (f, (&v->totalNumTypes), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTags ");
+    PrintAsnInt (f, (&v->totalNumTags), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumStrings ");
+    PrintAsnInt (f, (&v->totalNumStrings), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalLenStrings ");
+    PrintAsnInt (f, (&v->totalLenStrings), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"modules ");
+    PrintTBLSeqOf (f, (v->modules), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBL */
+
+void
+FreeTBL PARAMS ((v),
+TBL *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeAsnInt ((&v->totalNumModules));
+
+    FreeAsnInt ((&v->totalNumTypeDefs));
+
+    FreeAsnInt ((&v->totalNumTypes));
+
+    FreeAsnInt ((&v->totalNumTags));
+
+    FreeAsnInt ((&v->totalNumStrings));
+
+    FreeAsnInt ((&v->totalLenStrings));
+
+    FreeTBLSeqOf ((v->modules));
+    Asn1Free ((v->modules));
+
+}  /* FreeTBL */
+
+
+
+
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/stamp-tbl b/SecuritySNACCRuntime/c-lib/stamp-tbl
new file mode 100644
index 00000000..b5b986da
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/stamp-tbl
@@ -0,0 +1 @@
+Thu Jun  8 12:37:29 PDT 2000
diff --git a/SecuritySNACCRuntime/c-lib/stamp-useful b/SecuritySNACCRuntime/c-lib/stamp-useful
new file mode 100644
index 00000000..a707c1a4
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/stamp-useful
@@ -0,0 +1 @@
+Thu Jun  8 12:37:28 PDT 2000
diff --git a/SecuritySNACCRuntime/c-lib/tbl.c b/SecuritySNACCRuntime/c-lib/tbl.c
new file mode 100644
index 00000000..c2daa0fe
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/tbl.c
@@ -0,0 +1,2137 @@
+/*
+ * 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.
+ */
+
+
+#if TTBL
+/*
+ *    tbl.c
+ *
+ *    "TBL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Thu Jun  8 12:35:28 2000
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "tbl.h"
+
+
+AsnLen
+BEncTBLRangeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLRange *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->to));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->from));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLRangeContent */
+
+void
+BDecTBLRangeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLRange *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->from), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -100);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->to), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -101);
+    }
+    else
+        longjmp (env, -102);
+
+
+    if (!seqDone)
+        longjmp (env, -103);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLRangeContent */
+
+void
+PrintTBLRange PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLRange *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"from ");
+    PrintAsnInt (f, (&v->from), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"to ");
+    PrintAsnInt (f, (&v->to), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLRange */
+
+void
+FreeTBLRange PARAMS ((v),
+TBLRange *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeAsnInt ((&v->from));
+
+    FreeAsnInt ((&v->to));
+
+}  /* FreeTBLRange */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumber *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->value));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLNamedNumberContent */
+
+void
+BDecTBLNamedNumberContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLNamedNumber *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->name), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -104);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->value), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -105);
+    }
+    else
+        longjmp (env, -106);
+
+
+    if (!seqDone)
+        longjmp (env, -107);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLNamedNumberContent */
+
+void
+PrintTBLNamedNumber PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLNamedNumber *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"name ");
+    PrintPrintableString (f, (&v->name), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"value ");
+    PrintAsnInt (f, (&v->value), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLNamedNumber */
+
+void
+FreeTBLNamedNumber PARAMS ((v),
+TBLNamedNumber *v)
+{
+
+    if (v == NULL)
+        return;
+    FreePrintableString ((&v->name));
+
+    FreeAsnInt ((&v->value));
+
+}  /* FreeTBLNamedNumber */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberListContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumberList *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLNamedNumberListContent */
+
+void
+BDecTBLNamedNumberListContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLNamedNumberList *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLNamedNumber **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLNamedNumber**) AsnListAppend (v);
+    (*tmpVar) = (TBLNamedNumber*) Asn1Alloc (sizeof (TBLNamedNumber));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLNamedNumberContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -108);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLNamedNumberListContent */
+
+void
+PrintTBLNamedNumberList PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLNamedNumberList *v _AND_
+unsigned short int indent)
+{
+    TBLNamedNumber *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLNamedNumber (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLNamedNumber*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLNamedNumberList */
+
+void
+FreeTBLNamedNumberList PARAMS ((v),
+TBLNamedNumberList *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLNamedNumber ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLNamedNumberList */
+
+
+
+
+AsnLen
+BEncTBLTypeRefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeRef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnBoolContent (b, (&v->implicit));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeRefContent */
+
+void
+BDecTBLTypeRefContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeRef *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeDefIdContent (b, tagId1, elmtLen1, (&v->typeDef), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -109);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->implicit), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -110);
+    }
+    else
+        longjmp (env, -111);
+
+
+    if (!seqDone)
+        longjmp (env, -112);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeRefContent */
+
+void
+PrintTBLTypeRef PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeRef *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDef ");
+    PrintTBLTypeDefId (f, (&v->typeDef), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"implicit ");
+    PrintAsnBool (f, (&v->implicit), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeRef */
+
+void
+FreeTBLTypeRef PARAMS ((v),
+TBLTypeRef *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeDefId ((&v->typeDef));
+
+    FreeAsnBool ((&v->implicit));
+
+}  /* FreeTBLTypeRef */
+
+
+
+
+AsnLen
+BEncTBLTagContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTag *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->code));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTagClassContent (b, (&v->tclass));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 10);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTagContent */
+
+void
+BDecTBLTagContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTag *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTagClassContent (b, tagId1, elmtLen1, (&v->tclass), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -113);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->code), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -114);
+    }
+    else
+        longjmp (env, -115);
+
+
+    if (!seqDone)
+        longjmp (env, -116);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTagContent */
+
+void
+PrintTBLTag PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTag *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"tclass ");
+    PrintTBLTagClass (f, (&v->tclass), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"code ");
+    PrintAsnInt (f, (&v->code), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTag */
+
+void
+FreeTBLTag PARAMS ((v),
+TBLTag *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTagClass ((&v->tclass));
+
+    FreeAsnInt ((&v->code));
+
+}  /* FreeTBLTag */
+
+
+
+
+AsnLen
+BEncTBLTypeSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTagContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeSeqOfContent */
+
+void
+BDecTBLTypeSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLTag **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLTag**) AsnListAppend (v);
+    (*tmpVar) = (TBLTag*) Asn1Alloc (sizeof (TBLTag));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTagContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -117);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeSeqOfContent */
+
+void
+PrintTBLTypeSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLTag *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLTag (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLTag*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeSeqOf */
+
+void
+FreeTBLTypeSeqOf PARAMS ((v),
+TBLTypeSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLTag ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLTypeSeqOf */
+
+
+
+
+AsnLen
+BEncTBLTypeContentSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContentSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeContentSeqOfContent */
+
+void
+BDecTBLTypeContentSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeContentSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLType **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLType**) AsnListAppend (v);
+    (*tmpVar) = (TBLType*) Asn1Alloc (sizeof (TBLType));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTypeContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -118);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContentSeqOfContent */
+
+void
+PrintTBLTypeContentSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeContentSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLType *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLType (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLType*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeContentSeqOf */
+
+void
+FreeTBLTypeContentSeqOf PARAMS ((v),
+TBLTypeContentSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLType ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLTypeContentSeqOf */
+
+
+
+
+AsnLen
+BEncTBLTypeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLType *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->values)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberListContent (b, (v->values));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 6);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLRangeContent (b, (v->constraint));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 5);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    itemLen = BEncPrintableStringContent (b, (&v->fieldName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 4);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentContent (b, (v->content));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncAsnBoolContent (b, (&v->optional));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeIdContent (b, (&v->typeId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeContent */
+
+void
+BDecTBLTypeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLType *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+    AsnLen totalElmtsLen2 = 0;
+    AsnLen elmtLen2;
+    AsnTag tagId2;
+    AsnLen totalElmtsLen3 = 0;
+    AsnLen elmtLen3;
+    AsnTag tagId3;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeIdContent (b, tagId1, elmtLen1, (&v->typeId), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -119);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->optional), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -120);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 2))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->tagList) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->tagList), env);
+    BDecTBLTypeSeqOfContent (b, tagId1, elmtLen1, (v->tagList), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 3))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->content) = (TBLTypeContent*) Asn1Alloc (sizeof (TBLTypeContent));
+    CheckAsn1Alloc ((v->content), env);
+    tagId2 = BDecTag (b, &totalElmtsLen1, env);
+    elmtLen2 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeContentContent (b, tagId2, elmtLen2, (v->content), &totalElmtsLen1, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+        BDecEoc(b, &totalElmtsLen1, env);
+    if (elmtLen1 == INDEFINITE_LEN)
+        BDecEoc (b, &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+    else
+        longjmp (env, -121);
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 4)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 4))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->fieldName), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, CONS, 5))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->constraint) = (TBLRange*) Asn1Alloc (sizeof (TBLRange));
+    CheckAsn1Alloc ((v->constraint), env);
+    BDecTBLRangeContent (b, tagId1, elmtLen1, (v->constraint), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, CONS, 6))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->values) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->values), env);
+    BDecTBLNamedNumberListContent (b, tagId1, elmtLen1, (v->values), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -122);
+    }
+
+
+    if (!seqDone)
+        longjmp (env, -123);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContent */
+
+void
+PrintTBLType PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLType *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeId ");
+    PrintTBLTypeId (f, (&v->typeId), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"optional ");
+    PrintAsnBool (f, (&v->optional), indent + stdIndentG);
+    fprintf (f, ",\n");
+    if (NOT_NULL ((v->tagList)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"tagList ");
+    PrintTBLTypeSeqOf (f, (v->tagList), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"content ");
+    PrintTBLTypeContent (f, (v->content), indent + stdIndentG);
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"fieldName ");
+    PrintPrintableString (f, (&v->fieldName), indent + stdIndentG);
+    }
+    if (NOT_NULL ((v->constraint)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"constraint ");
+    PrintTBLRange (f, (v->constraint), indent + stdIndentG);
+    }
+    if (NOT_NULL ((v->values)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"values ");
+    PrintTBLNamedNumberList (f, (v->values), indent + stdIndentG);
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLType */
+
+void
+FreeTBLType PARAMS ((v),
+TBLType *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeId ((&v->typeId));
+
+    FreeAsnBool ((&v->optional));
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    FreeTBLTypeSeqOf ((v->tagList));
+    Asn1Free ((v->tagList));
+    }
+
+    FreeTBLTypeContent ((v->content));
+    Asn1Free ((v->content));
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    FreePrintableString ((&v->fieldName));
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    FreeTBLRange ((v->constraint));
+    Asn1Free ((v->constraint));
+    }
+
+    if (NOT_NULL ((v->values)))
+    {
+    FreeTBLNamedNumberList ((v->values));
+    Asn1Free ((v->values));
+    }
+
+}  /* FreeTBLType */
+
+
+
+
+AsnLen
+BEncTBLTypeContentContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContent *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_PRIMTYPE:
+    itemLen = BEncAsnNullContent (b, (&v->a.primType));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_ELMTS:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncTBLTypeContentContent */
+
+void
+BDecTBLTypeContentContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeContent *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    switch (tagId0)
+    {
+       case MAKE_TAG_ID (CNTX, PRIM, 0):
+        (v->choiceId) = TBLTYPECONTENT_PRIMTYPE;
+    BDecAsnNullContent (b, tagId0, elmtLen0, (&v->a.primType), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, CONS, 1):
+        (v->choiceId) = TBLTYPECONTENT_ELMTS;
+    (v->a.elmts) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->a.elmts), env);
+    BDecTBLTypeContentSeqOfContent (b, tagId0, elmtLen0, (v->a.elmts), &totalElmtsLen1, env);
+    break;
+
+       case MAKE_TAG_ID (CNTX, CONS, 2):
+        (v->choiceId) = TBLTYPECONTENT_TYPEREF;
+    (v->a.typeRef) = (TBLTypeRef*) Asn1Alloc (sizeof (TBLTypeRef));
+    CheckAsn1Alloc ((v->a.typeRef), env);
+    BDecTBLTypeRefContent (b, tagId0, elmtLen0, (v->a.typeRef), &totalElmtsLen1, env);
+    break;
+
+    default:
+        Asn1Error ("ERROR - unexpected tag in CHOICE\n");
+        longjmp (env, -124);
+        break;
+    } /* end switch */
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeContentContent */
+
+void
+PrintTBLTypeContent PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeContent *v _AND_
+unsigned short int indent)
+{
+    switch (v->choiceId)
+    {
+      case TBLTYPECONTENT_PRIMTYPE:
+          fprintf (f,"primType ");
+    PrintAsnNull (f, (&v->a.primType), indent + stdIndentG);
+          break;
+
+      case TBLTYPECONTENT_ELMTS:
+          fprintf (f,"elmts ");
+    PrintTBLTypeContentSeqOf (f, (v->a.elmts), indent + stdIndentG);
+          break;
+
+      case TBLTYPECONTENT_TYPEREF:
+          fprintf (f,"typeRef ");
+    PrintTBLTypeRef (f, (v->a.typeRef), indent + stdIndentG);
+          break;
+
+    }
+}  /* PrintTBLTypeContent */
+
+void
+FreeTBLTypeContent PARAMS ((v),
+TBLTypeContent *v)
+{
+
+    if (v == NULL)
+        return;
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_ELMTS:
+    FreeTBLTypeContentSeqOf ((v->a.elmts));
+    Asn1Free ((v->a.elmts));
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    FreeTBLTypeRef ((v->a.typeRef));
+    Asn1Free ((v->a.typeRef));
+
+    break;
+
+    }
+}  /* FreeTBLTypeContent */
+
+
+
+
+AsnLen
+BEncTBLTypeDefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeDef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    itemLen = BEncAsnNullContent (b, (v->isPdu));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 5);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, (v->type));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->typeName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 19);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeDefContent */
+
+void
+BDecTBLTypeDefContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLTypeDef *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecTBLTypeDefIdContent (b, tagId1, elmtLen1, (&v->typeDefId), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -125);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE)) ||
+(tagId1 == MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->typeName), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -126);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->type) = (TBLType*) Asn1Alloc (sizeof (TBLType));
+    CheckAsn1Alloc ((v->type), env);
+    BDecTBLTypeContent (b, tagId1, elmtLen1, (v->type), &totalElmtsLen1, env);
+    if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0))
+        seqDone = TRUE;
+    else
+    {
+        tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+         if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID))
+        {
+            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+            seqDone = TRUE;
+        }
+    }
+    }
+    else
+        longjmp (env, -127);
+
+
+    if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->isPdu) = (AsnNull*) Asn1Alloc (sizeof (AsnNull));
+    CheckAsn1Alloc ((v->isPdu), env);
+    BDecAsnNullContent (b, tagId1, elmtLen1, (v->isPdu), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -128);
+    }
+
+
+    if (!seqDone)
+        longjmp (env, -129);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLTypeDefContent */
+
+void
+PrintTBLTypeDef PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLTypeDef *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDefId ");
+    PrintTBLTypeDefId (f, (&v->typeDefId), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeName ");
+    PrintPrintableString (f, (&v->typeName), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"type ");
+    PrintTBLType (f, (v->type), indent + stdIndentG);
+    if (NOT_NULL ((v->isPdu)))
+    {
+    fprintf (f,",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"isPdu ");
+    PrintAsnNull (f, (v->isPdu), indent + stdIndentG);
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLTypeDef */
+
+void
+FreeTBLTypeDef PARAMS ((v),
+TBLTypeDef *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeTBLTypeDefId ((&v->typeDefId));
+
+    FreePrintableString ((&v->typeName));
+
+    FreeTBLType ((v->type));
+    Asn1Free ((v->type));
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    FreeAsnNull ((v->isPdu));
+    Asn1Free ((v->isPdu));
+    }
+
+}  /* FreeTBLTypeDef */
+
+
+
+
+AsnLen
+BEncTBLModuleSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModuleSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeDefContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLModuleSeqOfContent */
+
+void
+BDecTBLModuleSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLModuleSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLTypeDef **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLTypeDef**) AsnListAppend (v);
+    (*tmpVar) = (TBLTypeDef*) Asn1Alloc (sizeof (TBLTypeDef));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLTypeDefContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -130);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLModuleSeqOfContent */
+
+void
+PrintTBLModuleSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLModuleSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLTypeDef *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLTypeDef (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLTypeDef*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLModuleSeqOf */
+
+void
+FreeTBLModuleSeqOf PARAMS ((v),
+TBLModuleSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLTypeDef ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLModuleSeqOf */
+
+
+
+
+AsnLen
+BEncTBLModuleContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModule *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnBoolContent (b, (&v->isUseful));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->id));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLModuleContent */
+
+void
+BDecTBLModuleContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLModule *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)) ||
+(tagId1 == MAKE_TAG_ID (CNTX, CONS, 0))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->name), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -131);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnOidContent (b, tagId1, elmtLen1, (&v->id), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 2))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->isUseful), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -132);
+
+
+    if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 3))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->typeDefs) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->typeDefs), env);
+    BDecTBLModuleSeqOfContent (b, tagId1, elmtLen1, (v->typeDefs), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -133);
+    }
+    else
+        longjmp (env, -134);
+
+
+    if (!seqDone)
+        longjmp (env, -135);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLModuleContent */
+
+void
+PrintTBLModule PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLModule *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"name ");
+    PrintPrintableString (f, (&v->name), indent + stdIndentG);
+    fprintf (f, ",\n");
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"id ");
+    PrintAsnOid (f, (&v->id), indent + stdIndentG);
+    fprintf (f, ",\n");
+    }
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"isUseful ");
+    PrintAsnBool (f, (&v->isUseful), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"typeDefs ");
+    PrintTBLModuleSeqOf (f, (v->typeDefs), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLModule */
+
+void
+FreeTBLModule PARAMS ((v),
+TBLModule *v)
+{
+
+    if (v == NULL)
+        return;
+    FreePrintableString ((&v->name));
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    FreeAsnOid ((&v->id));
+    }
+
+    FreeAsnBool ((&v->isUseful));
+
+    FreeTBLModuleSeqOf ((v->typeDefs));
+    Asn1Free ((v->typeDefs));
+
+}  /* FreeTBLModule */
+
+
+
+
+AsnLen
+BEncTBLSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLSeqOfContent */
+
+void
+BDecTBLSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBLSeqOf *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)
+    {
+        TBLModule **tmpVar;
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
+    {
+        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env)
+        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/
+    }
+    if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    tmpVar = (TBLModule**) AsnListAppend (v);
+    (*tmpVar) = (TBLModule*) Asn1Alloc (sizeof (TBLModule));
+    CheckAsn1Alloc ((*tmpVar), env);
+    BDecTBLModuleContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env);
+    }  /* end of tag check if */
+    else  /* wrong tag */
+    {
+         Asn1Error ("Unexpected Tag\n");
+         longjmp (env, -136);
+    }
+    } /* end of for */
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLSeqOfContent */
+
+void
+PrintTBLSeqOf PARAMS ((f, v, indent),
+FILE* f _AND_
+TBLSeqOf *v _AND_
+unsigned short int indent)
+{
+    TBLModule *tmp;
+    if (v == NULL)
+        return;
+    fprintf (f,"{ -- SEQUENCE OF -- \n");
+    FOR_EACH_LIST_ELMT (tmp, v)
+    {
+        Indent (f, indent+ stdIndentG);
+        PrintTBLModule (f, tmp, indent + stdIndentG);
+        if (tmp != (TBLModule*)LAST_LIST_ELMT (v))
+            fprintf (f,",\n");
+    }
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBLSeqOf */
+
+void
+FreeTBLSeqOf PARAMS ((v),
+TBLSeqOf *v)
+{
+
+    AsnListNode *l;
+    AsnListNode *tmp;
+    if (v == NULL)
+        return;
+    for (l = FIRST_LIST_NODE (v); l != NULL; )
+    {
+        FreeTBLModule ((l->data));
+        tmp = l->next;
+        Asn1Free (l->data);
+        Asn1Free (l);
+        l = tmp;
+    }
+}  /* FreeTBLSeqOf */
+
+
+
+
+AsnLen BEncTBL PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncTBLContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    return l;
+} /* BEncTBL */
+
+void BDecTBL PARAMS ((b, result, bytesDecoded, env),
+BUF_TYPE b _AND_
+TBL *result _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    AsnTag tag;
+    AsnLen elmtLen1;
+
+    if (((tag = BDecTag (b, bytesDecoded, env)) != 
+MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
+    {
+        Asn1Error ("BDecTBL: ERROR - wrong tag\n");
+        longjmp (env, -137);
+    }
+    elmtLen1 = BDecLen (b, bytesDecoded, env);
+    BDecTBLContent (b, tag, elmtLen1, result, bytesDecoded, env);
+}  /* BDecTBL */
+
+AsnLen
+BEncTBLContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLSeqOfContent (b, (v->modules));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalLenStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTags));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypes));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumModules));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLContent */
+
+void
+BDecTBLContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env),
+BUF_TYPE b _AND_
+AsnTag tagId0 _AND_
+AsnLen elmtLen0 _AND_
+TBL *v _AND_
+AsnLen *bytesDecoded _AND_
+ENV_TYPE env)
+{
+    int seqDone = FALSE;
+    AsnLen totalElmtsLen1 = 0;
+    AsnLen elmtLen1;
+    AsnTag tagId1;
+    int mandatoryElmtCount1 = 0;
+
+
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumModules), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -138);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTypeDefs), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -139);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTypes), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -140);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTags), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -141);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumStrings), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -142);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalLenStrings), &totalElmtsLen1, env);
+    tagId1 = BDecTag (b, &totalElmtsLen1, env);
+    }
+    else
+        longjmp (env, -143);
+
+
+    if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))))
+    {
+    elmtLen1 = BDecLen (b, &totalElmtsLen1, env);
+    (v->modules) = AsnListNew (sizeof (char*));
+    CheckAsn1Alloc ((v->modules), env);
+    BDecTBLSeqOfContent (b, tagId1, elmtLen1, (v->modules), &totalElmtsLen1, env);
+        seqDone = TRUE;
+        if (elmtLen0 == INDEFINITE_LEN)
+            BDecEoc (b, &totalElmtsLen1, env);
+        else if (totalElmtsLen1 != elmtLen0)
+            longjmp (env, -144);
+    }
+    else
+        longjmp (env, -145);
+
+
+    if (!seqDone)
+        longjmp (env, -146);
+
+    (*bytesDecoded) += totalElmtsLen1;
+}  /* BDecTBLContent */
+
+void
+PrintTBL PARAMS ((f, v, indent),
+FILE* f _AND_
+TBL *v _AND_
+unsigned short int indent)
+{
+    if (v == NULL)
+        return;
+
+    fprintf (f,"{ -- SEQUENCE --\n");
+
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumModules ");
+    PrintAsnInt (f, (&v->totalNumModules), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTypeDefs ");
+    PrintAsnInt (f, (&v->totalNumTypeDefs), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTypes ");
+    PrintAsnInt (f, (&v->totalNumTypes), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumTags ");
+    PrintAsnInt (f, (&v->totalNumTags), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalNumStrings ");
+    PrintAsnInt (f, (&v->totalNumStrings), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"totalLenStrings ");
+    PrintAsnInt (f, (&v->totalLenStrings), indent + stdIndentG);
+    fprintf (f, ",\n");
+    Indent (f, indent + stdIndentG);
+    fprintf (f,"modules ");
+    PrintTBLSeqOf (f, (v->modules), indent + stdIndentG);
+    fprintf (f,"\n");
+    Indent (f, indent);
+    fprintf (f,"}");
+}  /* PrintTBL */
+
+void
+FreeTBL PARAMS ((v),
+TBL *v)
+{
+
+    if (v == NULL)
+        return;
+    FreeAsnInt ((&v->totalNumModules));
+
+    FreeAsnInt ((&v->totalNumTypeDefs));
+
+    FreeAsnInt ((&v->totalNumTypes));
+
+    FreeAsnInt ((&v->totalNumTags));
+
+    FreeAsnInt ((&v->totalNumStrings));
+
+    FreeAsnInt ((&v->totalLenStrings));
+
+    FreeTBLSeqOf ((v->modules));
+    Asn1Free ((v->modules));
+
+}  /* FreeTBL */
+
+
+
+
+#endif /* TTBL */
diff --git a/SecuritySNACCRuntime/c-lib/tbl.h b/SecuritySNACCRuntime/c-lib/tbl.h
new file mode 100644
index 00000000..45cdc3be
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/tbl.h
@@ -0,0 +1,362 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    tbl.h
+ *
+ *    "TBL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Thu Jun  8 12:35:28 2000
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _tbl_h_
+#define _tbl_h_
+
+
+
+
+typedef enum
+    {
+        TBL_BOOLEAN = 0,
+        TBL_INTEGER = 1,
+        TBL_BITSTRING = 2,
+        TBL_OCTETSTRING = 3,
+        TBL_NULL = 4,
+        TBL_OID = 5,
+        TBL_REAL = 6,
+        TBL_ENUMERATED = 7,
+        TBL_SEQUENCE = 8,
+        TBL_SET = 9,
+        TBL_SEQUENCEOF = 10,
+        TBL_SETOF = 11,
+        TBL_CHOICE = 12,
+        TBL_TYPEREF = 13
+    } TBLTypeId; /* ENUMERATED { TBL_BOOLEAN (0), TBL_INTEGER (1), TBL_BITSTRING (2), TBL_OCTETSTRING (3), TBL_NULL (4), TBL_OID (5), TBL_REAL (6), TBL_ENUMERATED (7), TBL_SEQUENCE (8), TBL_SET (9), TBL_SEQUENCEOF (10), TBL_SETOF (11), TBL_CHOICE (12), TBL_TYPEREF (13) }  */
+
+#define BEncTBLTypeIdContent BEncAsnEnumContent
+
+#define BDecTBLTypeIdContent BDecAsnEnumContent
+
+#define PrintTBLTypeId PrintAsnEnum
+
+#define FreeTBLTypeId FreeAsnEnum 
+
+
+
+
+typedef AsnInt TBLTypeDefId; /* INTEGER */
+
+#define BEncTBLTypeDefIdContent BEncAsnIntContent
+
+#define BDecTBLTypeDefIdContent BDecAsnIntContent
+
+#define PrintTBLTypeDefId PrintAsnInt
+
+#define FreeTBLTypeDefId FreeAsnInt 
+
+
+
+
+typedef enum
+    {
+        UNIVERSAL = 0,
+        APPLICATION = 1,
+        CONTEXT = 2,
+        PRIVATE = 3
+    } TBLTagClass; /* ENUMERATED { UNIVERSAL (0), APPLICATION (1), CONTEXT (2), PRIVATE (3) }  */
+
+#define BEncTBLTagClassContent BEncAsnEnumContent
+
+#define BDecTBLTagClassContent BDecAsnEnumContent
+
+#define PrintTBLTagClass PrintAsnEnum
+
+#define FreeTBLTagClass FreeAsnEnum 
+
+
+
+
+typedef struct TBLRange /* SEQUENCE */
+{
+    AsnInt from; /* [0] IMPLICIT INTEGER */
+    AsnInt to; /* [1] IMPLICIT INTEGER */
+} TBLRange;
+
+AsnLen BEncTBLRangeContent PROTO ((BUF_TYPE b, TBLRange *v));
+
+void BDecTBLRangeContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLRange *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLRange PROTO ((FILE* f, TBLRange *v, unsigned short int indent));
+void FreeTBLRange PROTO ((TBLRange *v));
+
+
+
+
+
+typedef struct TBLNamedNumber /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnInt value; /* [1] IMPLICIT INTEGER */
+} TBLNamedNumber;
+
+AsnLen BEncTBLNamedNumberContent PROTO ((BUF_TYPE b, TBLNamedNumber *v));
+
+void BDecTBLNamedNumberContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLNamedNumber *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLNamedNumber PROTO ((FILE* f, TBLNamedNumber *v, unsigned short int indent));
+void FreeTBLNamedNumber PROTO ((TBLNamedNumber *v));
+
+
+
+
+
+typedef AsnList TBLNamedNumberList; /* SEQUENCE OF TBLNamedNumber */
+
+AsnLen BEncTBLNamedNumberListContent PROTO ((BUF_TYPE b, TBLNamedNumberList *v));
+
+void BDecTBLNamedNumberListContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLNamedNumberList *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLNamedNumberList PROTO ((FILE* f, TBLNamedNumberList *v, unsigned short int indent));
+void FreeTBLNamedNumberList PROTO ((TBLNamedNumberList *v));
+
+
+
+
+
+typedef struct TBLTypeRef /* SEQUENCE */
+{
+    TBLTypeDefId typeDef; /* TBLTypeDefId */
+    AsnBool implicit; /* BOOLEAN */
+    struct TBLTypeDef *typeDefPtr;  /* Added by MS to hold resolved index */
+} TBLTypeRef;
+
+AsnLen BEncTBLTypeRefContent PROTO ((BUF_TYPE b, TBLTypeRef *v));
+
+void BDecTBLTypeRefContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeRef *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeRef PROTO ((FILE* f, TBLTypeRef *v, unsigned short int indent));
+void FreeTBLTypeRef PROTO ((TBLTypeRef *v));
+
+
+
+
+
+typedef struct TBLTag /* SEQUENCE */
+{
+    TBLTagClass tclass; /* TBLTagClass */
+    AsnInt code; /* INTEGER (0..MAX) */
+    BER_FORM form; /* added by MS to simplify enc/dec */
+    AsnTag encTag; /* added by MS to simplify enc/dec */
+} TBLTag;
+
+AsnLen BEncTBLTagContent PROTO ((BUF_TYPE b, TBLTag *v));
+
+void BDecTBLTagContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTag *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTag PROTO ((FILE* f, TBLTag *v, unsigned short int indent));
+void FreeTBLTag PROTO ((TBLTag *v));
+
+
+
+
+
+typedef AsnList TBLTypeSeqOf; /* SEQUENCE OF TBLTag */
+
+AsnLen BEncTBLTypeSeqOfContent PROTO ((BUF_TYPE b, TBLTypeSeqOf *v));
+
+void BDecTBLTypeSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeSeqOf PROTO ((FILE* f, TBLTypeSeqOf *v, unsigned short int indent));
+void FreeTBLTypeSeqOf PROTO ((TBLTypeSeqOf *v));
+
+
+
+
+
+typedef AsnList TBLTypeContentSeqOf; /* SEQUENCE OF TBLType */
+
+AsnLen BEncTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, TBLTypeContentSeqOf *v));
+
+void BDecTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeContentSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeContentSeqOf PROTO ((FILE* f, TBLTypeContentSeqOf *v, unsigned short int indent));
+void FreeTBLTypeContentSeqOf PROTO ((TBLTypeContentSeqOf *v));
+
+
+
+
+
+typedef struct TBLType /* SEQUENCE */
+{
+    TBLTypeId typeId; /* [0] IMPLICIT TBLTypeId */
+    AsnBool optional; /* [1] IMPLICIT BOOLEAN */
+    TBLTypeSeqOf* tagList; /* [2] IMPLICIT TBLTypeSeqOf OPTIONAL */
+    struct TBLTypeContent* content; /* [3] TBLTypeContent */
+    PrintableString fieldName; /* [4] IMPLICIT PrintableString OPTIONAL */
+    struct TBLRange* constraint; /* [5] IMPLICIT TBLRange OPTIONAL */
+    TBLNamedNumberList* values; /* [6] IMPLICIT TBLNamedNumberList OPTIONAL */
+} TBLType;
+
+AsnLen BEncTBLTypeContent PROTO ((BUF_TYPE b, TBLType *v));
+
+void BDecTBLTypeContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLType *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLType PROTO ((FILE* f, TBLType *v, unsigned short int indent));
+void FreeTBLType PROTO ((TBLType *v));
+
+
+
+
+
+typedef struct TBLTypeContent /* CHOICE */
+{
+    enum TBLTypeContentChoiceId
+    {
+        TBLTYPECONTENT_PRIMTYPE,
+        TBLTYPECONTENT_ELMTS,
+        TBLTYPECONTENT_TYPEREF
+    } choiceId;
+    union TBLTypeContentChoiceUnion
+    {
+    AsnNull primType; /* [0] IMPLICIT NULL */
+    TBLTypeContentSeqOf* elmts; /* [1] IMPLICIT TBLTypeContentSeqOf */
+    struct TBLTypeRef* typeRef; /* [2] IMPLICIT TBLTypeRef */
+    } a;
+} TBLTypeContent;
+
+AsnLen BEncTBLTypeContentContent PROTO ((BUF_TYPE b, TBLTypeContent *v));
+
+void BDecTBLTypeContentContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeContent *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeContent PROTO ((FILE* f, TBLTypeContent *v, unsigned short int indent));
+void FreeTBLTypeContent PROTO ((TBLTypeContent *v));
+
+
+
+
+
+typedef struct TBLTypeDef /* SEQUENCE */
+{
+    TBLTypeDefId typeDefId; /* TBLTypeDefId */
+    PrintableString typeName; /* PrintableString */
+    struct TBLType* type; /* TBLType */
+    AsnNull* isPdu; /* NULL OPTIONAL */
+} TBLTypeDef;
+
+AsnLen BEncTBLTypeDefContent PROTO ((BUF_TYPE b, TBLTypeDef *v));
+
+void BDecTBLTypeDefContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeDef *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLTypeDef PROTO ((FILE* f, TBLTypeDef *v, unsigned short int indent));
+void FreeTBLTypeDef PROTO ((TBLTypeDef *v));
+
+
+
+
+
+typedef AsnList TBLModuleSeqOf; /* SEQUENCE OF TBLTypeDef */
+
+AsnLen BEncTBLModuleSeqOfContent PROTO ((BUF_TYPE b, TBLModuleSeqOf *v));
+
+void BDecTBLModuleSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLModuleSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLModuleSeqOf PROTO ((FILE* f, TBLModuleSeqOf *v, unsigned short int indent));
+void FreeTBLModuleSeqOf PROTO ((TBLModuleSeqOf *v));
+
+
+
+
+
+typedef struct TBLModule /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnOid id; /* [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL */
+    AsnBool isUseful; /* [2] IMPLICIT BOOLEAN */
+    TBLModuleSeqOf* typeDefs; /* [3] IMPLICIT TBLModuleSeqOf */
+} TBLModule;
+
+AsnLen BEncTBLModuleContent PROTO ((BUF_TYPE b, TBLModule *v));
+
+void BDecTBLModuleContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLModule *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLModule PROTO ((FILE* f, TBLModule *v, unsigned short int indent));
+void FreeTBLModule PROTO ((TBLModule *v));
+
+
+
+
+
+typedef AsnList TBLSeqOf; /* SEQUENCE OF TBLModule */
+
+AsnLen BEncTBLSeqOfContent PROTO ((BUF_TYPE b, TBLSeqOf *v));
+
+void BDecTBLSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBLSeqOf PROTO ((FILE* f, TBLSeqOf *v, unsigned short int indent));
+void FreeTBLSeqOf PROTO ((TBLSeqOf *v));
+
+
+
+
+
+typedef struct TBL /* SEQUENCE */
+{
+    AsnInt totalNumModules; /* INTEGER */
+    AsnInt totalNumTypeDefs; /* INTEGER */
+    AsnInt totalNumTypes; /* INTEGER */
+    AsnInt totalNumTags; /* INTEGER */
+    AsnInt totalNumStrings; /* INTEGER */
+    AsnInt totalLenStrings; /* INTEGER */
+    TBLSeqOf* modules; /* TBLSeqOf */
+} TBL;
+
+AsnLen BEncTBL PROTO ((BUF_TYPE b, TBL *v));
+
+void BDecTBL PROTO ((BUF_TYPE b, TBL *result, AsnLen *bytesDecoded, ENV_TYPE env));
+AsnLen BEncTBLContent PROTO ((BUF_TYPE b, TBL *v));
+
+void BDecTBLContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBL *v, AsnLen *bytesDecoded, ENV_TYPE env));
+
+
+void PrintTBL PROTO ((FILE* f, TBL *v, unsigned short int indent));
+void FreeTBL PROTO ((TBL *v));
+
+
+
+
+
+
+#endif /* conditional include of tbl.h */
diff --git a/SecuritySNACCRuntime/c-lib/tbl.h.patch b/SecuritySNACCRuntime/c-lib/tbl.h.patch
new file mode 100644
index 00000000..6e74ce2d
--- /dev/null
+++ b/SecuritySNACCRuntime/c-lib/tbl.h.patch
@@ -0,0 +1,23 @@
+*** tbl.h	Wed Feb  5 17:37:16 1997
+--- boot/tbl.h	Wed Jul 19 16:58:58 1995
+***************
+*** 82,87 ****
+--- 82,88 ----
+  {
+      TBLTypeDefId typeDef; /* TBLTypeDefId */
+      AsnBool implicit; /* BOOLEAN */
++     struct TBLTypeDef *typeDefPtr;  /* Added by MS to hold resolved index */
+  } TBLTypeRef;
+  
+  AsnLen BEncTBLTypeRefContent PROTO ((BUF_TYPE b, TBLTypeRef *v));
+***************
+*** 100,105 ****
+--- 101,108 ----
+  {
+      TBLTagClass tclass; /* TBLTagClass */
+      AsnInt code; /* INTEGER (0..MAX) */
++     BER_FORM form; /* added by MS to simplify enc/dec */
++     AsnTag encTag; /* added by MS to simplify enc/dec */
+  } TBLTag;
+  
+  AsnLen BEncTBLTagContent PROTO ((BUF_TYPE b, TBLTag *v));
diff --git a/SecuritySNACCRuntime/compiler/README b/SecuritySNACCRuntime/compiler/README
new file mode 100644
index 00000000..b1b7e229
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/README
@@ -0,0 +1,111 @@
+(RCS control information is at the end of this file.)
+
+
+README: snacc compiler source code - Mike Sample 92
+----------------------------------------------------
+
+
+Compiling the snacc compiler
+----------------------------
+
+The snacc source code can be compiled with ANSI and non-ANSI C
+compilers.  The configure script automatically determines the type of
+your C compiler and defines __USE_ANSI_C__ accordingly.
+
+If you use lex, you should change the YYLMAX value in the lex
+generated lex-asn1.c file from its measly default value (200 or so) to
+something like 2048.  YYLMAX is the longest token that the lexical
+analyzer can match.  I found this problem when snacc choked on the
+DESCRIPTION field of an OBJECT-TYPE macro that was longer than 200
+characters.  GNU flex does not have this problem (and seems to produce
+smaller code than the old lex).
+
+Compiling parse-asn1.y with bison or yacc will produce 61 shift/reduce
+errors and 2 reduce/reduce errors.  These are mostly due to the macros
+that are parsed.  The reduce/reduce errors result from type or value
+lists in some macros - the a "NULL" value and "NULL" type are both
+represented by "NULL" - don't worry about this ambiguity.  Bizzare
+syntax errors that arise from these shift-reduce errors can be
+handled by separating types/values with semi-colons.
+
+The length of generated files' names will be truncated to match your
+system has the posix "pathconf" routine.  If it does not the maximum
+file length will be set at 14 chars.  If you want to change this,
+modify the "MakeBaseFileName" routine in back_ends/c_gen/str_util.c or
+use the -mf cmd line option.
+
+snacc has been successfully installed on SPARCs, HP700s, RS 6000s, and
+MIPS machines.  You may have to fiddle with system include files.
+
+Outline of what snacc does
+--------------------------
+
+The snacc compiler uses yacc and lex (or bison/flex) parser to produce
+an attributed parse tree for an ASN.1 source file.  The main steps of
+the snacc are (see main() in core/snacc.c):
+
+
+ 1. parse USEFUL types module (if given on command line with -u option)
+      related src:  core/snacc.c core/lex-asn1.l core/parse-asn1.y
+                    core/asn1module.h
+
+ 2. parse the ASN.1 source file(s)
+      related src:  core/snacc.c core/lex-asn1.l core/parse-asn1.y
+                    core/asn1module.h
+
+ 3. link import and local type references to the type proper
+    definitions in the parsed modules (including useful types module).
+      related src:  core/link_types.c
+
+ 4. do parsing for OBJECT IDENTIFIER values. Simple recursive descent
+    parser.  Could be expanded to handle more complex values.
+      related src:  core/val_parser.c
+
+5. link any value references (some may be internal to OBJECT IDENTIFIERs)
+      related src:  core/link_values.c
+
+ 6. process macros - change type definitions in the macros to separate
+    type definitions and do systemd dependent processing.
+      related src:  core/do_macros.c
+
+ 7. normalize types and values - eg swap COMPONENTS OF and SELECTION types
+    for actual types/field. (and more)
+      related src:  core/normalize.c
+
+ 8. mark recursive type and report any recursion related errors.
+    (e.g. empty recursive types A ::= B  B ::= A)
+      related src:  core/recursive.c
+
+ 9. check for sematic errors in each ASN.1 module.
+      related src:  core/err_chk.c
+
+10. fill in the C or C++ type and routine naming information.
+    (done before dependency sorting so the sorter can make
+    decisions on the basis of whether a type is ref'd by pointer
+    (last resort))
+      related src:  back_ends/c++_gen/c++_types.c
+                    back_ends/c++_gen/c++_rules.c
+                    back_ends/c_gen/types_info.c
+                    back_ends/c_gen/rules.c
+
+11. do type dependency sorting. Ordered from least dependent
+    to most dependent.  Saves some irritations in the C/C++ code.
+      related src:  core/dependency.c
+
+12. Generate C/C++ .h and .c/.C files
+      related src:  core/snacc.c back_ends/*
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/README,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:08  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:38  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1994/09/01 01:37:51  rj
+# document the changes:
+# - autoconf stuff
+# - filename changes.
+#
diff --git a/SecuritySNACCRuntime/compiler/back-ends/.cvsignore b/SecuritySNACCRuntime/compiler/back-ends/.cvsignore
new file mode 100644
index 00000000..5761abcf
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/.cvsignore
@@ -0,0 +1 @@
+*.o
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.c b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.c
new file mode 100644
index 00000000..b0e66753
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.c
@@ -0,0 +1,309 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/gen_any.c
+ *
+ *     prints Routine to initialize the ANY Hash table.  The
+ *     ANY Hash table maps the OBJECT IDENTIFIERS or INTEGERS
+ *     to the correct decoding routines.
+ *
+ *     Also prints an enum to identify each ANY mapping.
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * INSERT_VDA_COMMENTS
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-any.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:39  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:19:11  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:47:53  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  01:06:31  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:47:58  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "define.h"
+#include "str-util.h"
+#include "rules.h"
+#include "gen-vals.h"
+#include "lib-types.h"
+#include "gen-any.h"
+
+static int anyEnumValG = 0;
+
+
+void PrintCxxAnyEnum PROTO ((FILE *hdr, Module *m, CxxRules *r));
+
+void PrintCxxAnyHashInitRoutine PROTO ((FILE *src, FILE *hdr, ModuleList *mods, Module *m, CxxRules *r));
+
+
+void
+PrintCxxAnyCode PARAMS ((src, hdr, r, mods, m),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CxxRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m)
+{
+
+    if (!m->hasAnys)
+        return;
+
+    PrintCxxAnyEnum (hdr, m, r);
+    PrintCxxAnyHashInitRoutine (src, hdr, mods, m, r);
+
+}  /* PrintAnyCode */
+
+
+
+void
+PrintCxxAnyEnum PARAMS ((hdr, m, r),
+    FILE *hdr _AND_
+    Module *m _AND_
+    CxxRules *r)
+{
+    TypeDef *td;
+    AnyRef *ar;
+    AnyRefList *arl;
+    int firstPrinted = TRUE;
+    int i;
+    char *modName;
+
+    modName = Asn1TypeName2CTypeName (m->modId->name);
+
+    fprintf (hdr,"typedef enum %sAnyId\n", modName);
+    fprintf (hdr,"{\n");
+
+    /* do any lib types */
+    for (i = BASICTYPE_BOOLEAN; i < BASICTYPE_MACRODEF; i++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (i);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                if (!firstPrinted)
+                    fprintf (hdr,",\n");
+                fprintf (hdr,"    %s = %d", ar->anyIdName, anyEnumValG++);
+                firstPrinted = FALSE;
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                if (!firstPrinted)
+                    fprintf (hdr,",\n");
+                fprintf (hdr,"    %s = %d", ar->anyIdName, anyEnumValG++);
+                firstPrinted = FALSE;
+            }
+        }
+    }
+
+#ifndef VDADER_RULES
+    if (firstPrinted) /* none have been printed */
+        fprintf (hdr,"/* NO INTEGER or OBJECT IDENTIFIER to ANY type relationships were defined (via MACROs or other mechanism) */\n ??? \n");
+#endif
+
+    fprintf (hdr,"\n} %sAnyId;\n\n\n", modName);
+    Free (modName);
+
+}  /* PrintAnyEnum */
+
+
+void
+PrintCxxAnyHashInitRoutine PARAMS ((src, hdr, mods, m, r),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r)
+{
+    TypeDef *td;
+    AnyRefList *arl;
+    AnyRef *ar;
+    CxxTDI *cxxtdi;
+    int i;
+    int j;
+    enum BasicTypeChoiceId typeId;
+    int installedSomeHashes = FALSE;
+
+
+#ifndef VDADER_RULES
+    /* print InitAny class src file */
+    fprintf (src,"// this class will automatically intialize the any hash tbl\n");
+    fprintf (src,"class InitAny\n");
+    fprintf (src,"{\n");
+    fprintf (src,"  public:\n");
+    fprintf (src,"    InitAny();\n");
+    fprintf (src,"};\n\n");
+
+    fprintf (src,"static InitAny anyInitalizer;\n");
+
+    /* print constructor method that build hash tbl to src file*/
+    fprintf (src,"InitAny::InitAny()\n");
+    fprintf (src,"{\n");
+
+    /* first print value for OID's */
+
+    /* do any lib types first */
+    i = 0;
+    for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (j);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                installedSomeHashes = TRUE;
+                if (ar->id->choiceId == OIDORINT_OID)
+                {
+                    fprintf (src,"    %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++);
+                    PrintCxxOidValue (src, r, ar->id->a.oid);
+                    fprintf (src,";\n");
+                }
+                else if (ar->id->choiceId == OIDORINT_INTID)
+                {
+                    fprintf (src,"    %s int%d", r->typeConvTbl[BASICTYPE_INTEGER].className, i++);
+                    PrintCxxIntValue (src, r, ar->id->a.intId);
+                    fprintf (src,";\n");
+                }
+            }
+        }
+    }
+
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            cxxtdi = td->cxxTypeDefInfo;
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                installedSomeHashes = TRUE;
+                if (ar->id->choiceId == OIDORINT_OID)
+                {
+                    fprintf (src,"    %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++);
+                    PrintCxxOidValue (src, r, ar->id->a.oid);
+                    fprintf (src,";\n");
+                }
+                else if (ar->id->choiceId == OIDORINT_INTID)
+                {
+                    fprintf (src,"    %s int%d", r->typeConvTbl[BASICTYPE_INTEGER].className, i++);
+                    PrintCxxIntValue (src, r, ar->id->a.intId);
+                    fprintf (src,";\n");
+                }
+            }
+        }
+    }
+
+
+    /* now print hash init calls */
+    i = 0;
+    for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (j);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                if (ar->id->choiceId == OIDORINT_OID)
+                    fprintf (src,"    AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, ar->anyIdName, r->typeConvTbl[j].className);
+
+                else
+                    fprintf (src,"    AsnAny::InstallAnyByInt (int%d, %s, new %s);\n", i++, ar->anyIdName, r->typeConvTbl[j].className);
+
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                cxxtdi = td->cxxTypeDefInfo;
+
+                if (ar->id->choiceId == OIDORINT_OID)
+                    fprintf (src,"    AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, ar->anyIdName, cxxtdi->className);
+
+                else
+                    fprintf (src,"    AsnAny::InstallAnyByInt (int%d, %s, new %s);\n", i++, ar->anyIdName, cxxtdi->className);
+
+            }
+        }
+    }
+
+    if (!installedSomeHashes)
+    {
+        fprintf (src,"    /* Since no INTEGER/OID to ANY type relations were defined\n");
+        fprintf (src,"     * (usually done via MACROs) you must manually do the code\n");
+        fprintf (src,"     * to fill the hash tbl.\n");
+        fprintf (src,"     * if the ids are INTEGER use the following:\n");
+        fprintf (src,"     * AsnAny::InstallAnyByInt (3, ??_ANY_ID, new <className>);\n");
+        fprintf (src,"     * if the ids are OBJECT IDENTIFIERs use the following:\n");
+        fprintf (src,"     * AsnAny::InstallAnyByOid (OidValue, ??_ANY_ID, new <className>);\n");
+        fprintf (src,"     * put the ??_ANY_IDs in the AnyId enum.\n\n");
+        fprintf (src,"     * For example if you have some thing like\n");
+        fprintf (src,"     * T1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id }\n");
+        fprintf (src,"     * and the id 1 maps to the type BOOLEAN use the following:\n");
+        fprintf (src,"     * AsnAny::InstallAnyByInt (1, SOMEBOOL_ANY_ID, new AsnBool);\n");
+        fprintf (src,"     */\n ???????\n");  /* generate compile error */
+        fprintf (src,"    /* VDADER_RULES is selected UPDATE THIS COMMENT\n");
+        fprintf (src,"     */\n");
+    }
+
+
+    fprintf (src,"}  /* InitAny::InitAny */\n\n\n");
+#endif
+
+}  /* PrintAnyHashInitRoutine */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.h b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.h
new file mode 100644
index 00000000..5fec1f8d
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/gen_any.h
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-any.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:39  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:19:12  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:47:54  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:47:59  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+void PrintCxxAnyCode PROTO ((FILE *src, FILE *hdr, CxxRules *r, ModuleList *mods, Module *m));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.c b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.c
new file mode 100644
index 00000000..4ba6419e
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.c
@@ -0,0 +1,5556 @@
+/*
+ * 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.
+ */
+
+
+
+/*
+ *   compiler/back_ends/c++_gen/gen_code.c - routines for printing C++ code from type trees
+ *
+ *   assumes that the type tree has already been run through the
+ *   c++ type generator (c++_gen/types.c).
+ *
+ *  This was hastily written - it has some huge routines in it.
+ *  Needs a lot of cleaning up and modularization...
+ *
+ * Mike Sample
+ * 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * INSERT_VDA_COMMENTS
+ *
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.c,v 1.3 2001/06/27 23:51:42 dmitch Exp $
+ * $Log: gen-code.c,v $
+ * Revision 1.3  2001/06/27 23:51:42  dmitch
+ * Reimplement partial fix for Radar 2664258: Print() routines are now empty stubs in NDEBUG config.
+ *
+ * Revision 1.2  2001/06/27 23:07:00  dmitch
+ * Pusuant to Radar 2664258, Print() member functions are now conditional on #ifndef NDEBUG.
+ *
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.4  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.3  1999/03/20 03:13:48  mb
+ * Generate Copy member functions.
+ *
+ * Revision 1.2  1999/03/17 01:54:54  aram
+ * Changed compiler so that the destructors and Clone methods are virtual.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:39  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.12  1997/02/28 13:39:53  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.11  1997/02/16 15:14:06  rj
+ * made return *this after calling abort()'' a compile time option.
+ *
+ * Revision 1.10  1997/02/16 12:46:31  rj
+ * use the TIME_WITH_SYS_TIME flag (checked and generated by configure).
+ * return *this after calling abort() for compilers that don't know about this volatile function.
+ * comment out unused parameters, the compiler otherwise may complain.
+ *
+ * Revision 1.9  1995/09/07  20:47:32  rj
+ * deep copying assingment operators added.
+ *
+ * Revision 1.8  1995/09/07  19:25:27  rj
+ * PrintCxxCode(): boolean genMeta changed to enum type MetaNameStyle. used globally in printMetaG.
+ *
+ * set Tcl's errorCode variable.
+ *
+ * Revision 1.7  1995/08/17  15:00:06  rj
+ * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted)
+ *
+ * Revision 1.6  1995/07/27  10:52:28  rj
+ * include config.h before using its #define's :-)
+ *
+ * file name has been shortened for redundant part: c++-gen/gen-c++-code -> c++-gen/gen-code.
+ *
+ * functions used only locally made static.
+ *
+ * #if TCL ... #endif wrapped into #if META ... #endif, both here and in generated files.
+ *
+ * code changes to allow for more than one PDU (meta code), e.g. generate -create() functions.
+ *
+ * generate additional TclUnsetVal() function to delete OPTIONAL members and SEQUENCE OF and SET OF list elements.
+ *
+ * _getref() gets an additional optional argument to faciliate the different member access semantics of TclGetVal() and TclSetVal().
+ *
+ * the list functions Append(), Prepend(), InsertBefore() and InsertAfter() now set the current element to the element just inserted.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.5  1995/02/18  14:45:16  rj
+ * tried to make the print function's output a little more readable. [kho]
+ *
+ * Revision 1.4  1994/10/08  03:19:24  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * turned the functions order upside down to get rid of those annoying declarations.
+ *
+ * turned character pointers into constant character arrays.
+ *
+ * code for meta structures added (provides information about the generated code itself).
+ *
+ * code for Tcl interface added (makes use of the above mentioned meta code).
+ *
+ * instead of being a no-op, the no-arg-constructors (that get used by Clone()) do something useful now, namely:
+ * - initialize the pointer in a choice union. (the destruktor may try to free the bogus pointer).
+ * - for the same reason: initialize pointers in sequences and sets.
+ *
+ * to complement the destructors, T::T (const T&) and T &T::operator = (const T &) have been added to override the defaults supplied by the compiler.
+ * reason: simple pointer duplication may lead to unreferenced objects and to objects referenced more than once (on which the destructors delete may choke).
+ *
+ * virtual inline functions (the destructor and the Clone() function) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
+ *
+ * made Print() const (and some other, mainly comparison functions).
+ *
+ * Revision 1.3  1994/09/01  00:16:29  rj
+ * change of IBM ENC integrated: large inlines turned into normal functions.
+ * more portable .h file inclusion.
+ *
+ * Revision 1.2  1994/08/31  09:49:05  rj
+ * for the C++ code generated: turned TRUE/FALSE into true/false;
+ * the keyword `struct' had to be removed before AsnListElmt, or gcc 2.6 wouldn't compile the generated code.
+ *
+ * Revision 1.1  1994/08/28  09:48:01  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "snacc.h"
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "define.h"
+#include "mem.h"
+#include "lib-types.h"
+#include "rules.h"
+#include "types.h"
+#include "cond.h"
+#include "str-util.h"
+#include "snacc-util.h"
+#include "print.h"
+#include "tag-util.h"  /* get GetTags/FreeTags/CountTags/TagByteLen */
+#if META
+#include "meta.h"
+#endif
+#include "gen-vals.h"
+#include "gen-any.h"
+#include "gen-code.h"
+
+#ifdef VDADER_RULES
+long VDA_ProcessSetOf(FILE *src,TypeDef *td,Type *lst,CxxRules *r);
+#endif
+
+
+static const char	bufTypeNameG[] = "BUF_TYPE";
+static const char	lenTypeNameG[] = "AsnLen";
+static const char	tagTypeNameG[] = "AsnTag";
+static const char	envTypeNameG[] = "ENV_TYPE";
+static long int		longJmpValG  = -100;
+static const char	baseClassesG[] = ": public AsnType";
+
+static int		printTypesG;
+static int		printEncodersG;
+static int		printDecodersG;
+static int		printPrintersG;
+static int		printFreeG;
+#if META
+static MetaNameStyle	printMetaG;
+static MetaPDU		*meta_pdus_G;
+#if TCL
+static int		printTclG;
+#endif
+#endif /* META */
+
+
+static void
+PrintHdrComment PARAMS ((hdr, m),
+    FILE *hdr _AND_
+    Module *m)
+{
+    time_t now = time (NULL);
+
+    fprintf (hdr, "//   NOTE: this is a machine generated file--editing not recommended\n");
+    fprintf (hdr, "//\n");
+    fprintf (hdr, "// %s - class definitions for ASN.1 module %s\n", m->cxxHdrFileName, m->modId->name);
+    fprintf (hdr, "//\n");
+    fprintf (hdr, "//   This file was generated by snacc on %s", ctime (&now));
+    fprintf (hdr, "//   UBC snacc by Mike Sample\n");
+    fprintf (hdr, "//   A couple of enhancements made by IBM European Networking Center\n"); /* 20.8.93 Thomas Meyer */
+    fprintf (hdr, "\n");
+
+} /* PrintHdrComment */
+
+static void
+PrintSrcComment PARAMS ((src, m),
+    FILE *src _AND_
+    Module *m)
+{
+    time_t now = time (NULL);
+
+    fprintf (src, "//   NOTE: this is a machine generated file--editing not recommended\n");
+    fprintf (src, "//\n");
+    fprintf (src, "// %s - class member functions for ASN.1 module %s\n", m->cxxSrcFileName, m->modId->name);
+    fprintf (src, "//\n");
+    fprintf (src, "//   This file was generated by snacc on %s", ctime (&now));
+    fprintf (src, "//   UBC snacc written by Mike Sample\n");
+    fprintf (src, "//   A couple of enhancements made by IBM European Networking Center\n"); /* 20.8.93 Thomas Meyer */
+    fprintf (src, "\n");
+
+} /* PrintSrcComment */
+
+
+static void
+PrintSrcIncludes PARAMS ((src, if_IBM_ENC (srcdb COMMA) mods, m),
+    FILE *src _AND_
+    if_IBM_ENC (FILE *srcdb _AND_)
+    ModuleList *mods _AND_
+    Module *m)
+{
+    void *tmp;
+    Module *currMod;
+#ifdef _IBM_ENC_
+    size_t length;
+    char *inclstring;
+#endif /* _IBM_ENC_ */
+
+    fprintf (src, "#include \"asn-incl.h\"\n");
+
+    tmp = (void *)CURR_LIST_NODE (mods); /* remember curr loc */
+    FOR_EACH_LIST_ELMT (currMod, mods)
+        fprintf (src, "#include \"%s\"\n", currMod->cxxHdrFileName);
+    SET_CURR_LIST_NODE (mods, tmp);
+
+#ifdef _IBM_ENC_
+#include "./ibm_editor/print_src_includes.h"
+#endif /* _IBM_ENC_ */
+} /* PrintSrcIncludes */
+
+
+static void
+PrintTypeDecl PARAMS ((f, td),
+    FILE *f _AND_
+    TypeDef *td)
+{
+    switch (td->type->basicType->choiceId)
+    {
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_SELECTION:
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_MACRODEF:
+        case BASICTYPE_MACROTYPE:
+            return; /* do nothing */
+
+        default:
+            if (IsNewType (td->type))
+                fprintf (f, "class %s;\n", td->cxxTypeDefInfo->className);
+    }
+
+} /* PrintTypeDecl */
+
+
+static void
+PrintCxxType PARAMS ((hdr, mods, m, r, td, parent, t),
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    fprintf (hdr, "%s		", t->cxxTypeRefInfo->className);
+
+    if (t->cxxTypeRefInfo->isPtr)
+        fprintf (hdr, "*");
+
+} /* PrintCxxType */
+
+
+#ifdef _IBM_ENC_
+static void
+PrintCxxTypedb PARAMS ((srcdb, mods, m, r, td, parent, t),
+    FILE *srcdb _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+#include "./ibm_editor/print_cxx_type_db.h"
+} /* PrintCxxTypedb */
+#endif
+
+
+/*
+ *  Uses the Constructor that takes no args.
+ *  Assumes file f is positioned inside a class definition.
+ *  All Classes get this to support the ANY type.
+ */
+static void
+PrintCloneMethod PARAMS ((hdr, src, td),
+    FILE *hdr _AND_
+    FILE *src _AND_
+    TypeDef *td)
+{
+    fprintf (hdr, "  virtual AsnType	*Clone() const;\n\n", td->cxxTypeDefInfo->className);
+
+    fprintf (src, "AsnType *%s::Clone() const\n", td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    fprintf (src, "  return new %s;\n", td->cxxTypeDefInfo->className);
+    fprintf (src, "}\n\n");
+
+    /* Print the Copy method as well.  Use the copy constuctor. */
+	fprintf (hdr, "  virtual AsnType	*Copy() const;\n\n", td->cxxTypeDefInfo->className);
+
+    fprintf (src, "AsnType *%s::Copy() const\n", td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    fprintf (src, "  return new %s (*this);\n", td->cxxTypeDefInfo->className);
+    fprintf (src, "}\n\n");
+} /* PrintCloneMethod */
+
+
+/*
+ * prints inline definition of constructors if this class is
+ * derived from a library class.
+ * assumes FILE *f is positioned in the derived class definition (.h)
+ *
+ * 12/92 MS - added overloaded "=" ops for string types.
+ */
+static void
+PrintDerivedConstructors PARAMS ((f, r, td),
+    FILE *f _AND_
+    CxxRules *r _AND_
+    TypeDef *td)
+{
+    enum BasicTypeChoiceId typeId;
+    char *derivedClassName;
+    char *baseClassName;
+
+    typeId = GetBuiltinType (td->type);
+    derivedClassName = td->cxxTypeDefInfo->className;
+    baseClassName = td->type->cxxTypeRefInfo->className;
+
+    /* every class gets the no-arg constructor */
+#if TCL
+    if (printTclG && typeId == BASICTYPE_ENUMERATED)
+    {
+	fprintf (f, "#if TCL\n");
+	fprintf (f, "			%s(): %s (_nmdescs[0].value) {}\n", derivedClassName, baseClassName);
+	fprintf (f, "#else\n");
+    }
+#endif /* TCL */
+    fprintf (f, "			%s(): %s() {}\n", derivedClassName, baseClassName);
+#if TCL
+    if (printTclG && typeId == BASICTYPE_ENUMERATED)
+      fprintf (f, "#endif\n");
+#endif /* TCL */
+
+    switch (typeId)
+    {
+        case BASICTYPE_BOOLEAN:
+            fprintf (f, "			%s (bool b): %s (b) {}\n", derivedClassName, baseClassName);
+            break;
+
+        case BASICTYPE_ENUMERATED:
+        case BASICTYPE_INTEGER:
+            fprintf (f, "			%s (int i): %s (i) {}\n", derivedClassName, baseClassName);
+            break;
+
+        case BASICTYPE_REAL:
+            fprintf (f, "			%s (double d): %s (d) {}\n", derivedClassName, baseClassName);
+            break;
+
+	case BASICTYPE_OCTETSTRING:
+            fprintf (f, "			%s (const char *str): %s (str) {}\n", derivedClassName, baseClassName);
+
+            fprintf (f, "			%s (const char *str, const size_t len): %s (str, len) {}\n", derivedClassName, baseClassName);
+
+            fprintf (f, "			%s (const %s &o): %s (o) {}\n", derivedClassName, baseClassName, baseClassName);
+
+            /* include overloading of = op. MS 12/92 */
+            fprintf (f, "  %s		&operator = (const %s &o)	{ ReSet (o); return *this; }\n", derivedClassName, derivedClassName);
+            fprintf (f, "  %s		&operator = (const char *str)	{ ReSet (str); return *this; }\n", derivedClassName);
+            break;
+
+        case BASICTYPE_BITSTRING:
+            fprintf (f, "			%s (const size_t bits): %s (bits) {}\n", derivedClassName, baseClassName);
+
+            fprintf (f, "			%s (const char *str, const size_t bitLen): %s (str, bitLen) {}\n", derivedClassName, baseClassName);
+
+            fprintf (f, "			%s (const %s &b): %s (b) {}\n",  derivedClassName, baseClassName, baseClassName);
+            break;
+
+            /* include overloading of = op. MS 12/92 */
+            fprintf (f, "  %s		&operator = (const %s &b)	{ ReSet (b); return *this; }\n", derivedClassName, derivedClassName);
+
+        case BASICTYPE_OID:
+            fprintf (f, "			%s (const char *encOid, size_t len): %s (encOid, len) {}\n", derivedClassName, baseClassName);
+
+            fprintf (f, "			%s (const %s &o): %s (o) {}\n", derivedClassName, baseClassName, baseClassName);
+
+            fprintf (f, "			%s (unsigned long int a1, unsigned long int a2, long int a3=-1, long int a4=-1, long int a5=-1, long int a6=-1, long int a7=-1, long int a8=-1, long int a9=-1, long int a10=-1, long int a11=-1): %s (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {}\n", baseClassName, derivedClassName, baseClassName);
+
+            /* include overloading of = op. MS 12/92 */
+            fprintf (f, "  %s		&operator = (const %s &o)	{ ReSet (o); return *this; }\n", derivedClassName, derivedClassName);
+
+            break;
+
+
+        default:
+            /* do nothing */
+            break;
+    }
+
+} /* PrintDerivedConstructors */
+
+
+static void
+PrintMakeTag PARAMS ((f, tag),
+    FILE *f _AND_
+    Tag *tag)
+{
+    char *classStr;
+    char *formStr;
+
+    classStr = Class2ClassStr (tag->tclass);
+
+    if (tag->form == ANY_FORM)  /* default to PRIM for dual form tags */
+        formStr = Form2FormStr (PRIM);
+    else
+        formStr = Form2FormStr (tag->form);
+
+    fprintf (f, "MAKE_TAG_ID (%s, %s, ", classStr, formStr);
+    if (tag->tclass == UNIV)
+        fprintf (f, "%s)", Code2UnivCodeStr (tag->code));
+    else
+        fprintf (f, "%d)", tag->code);
+
+} /* PrintMakeTag */
+
+
+static void
+PrintPduMemberFcns PARAMS ((src, hdr, r, cln),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CxxRules *r _AND_
+    char *cln)
+{
+    if (printEncodersG)
+    {
+        fprintf (hdr, "  int			B%s (%s b, %s &bytesEncoded);\n", r->encodePduBaseName, bufTypeNameG, lenTypeNameG);
+
+        fprintf (src, "int %s::B%s (%s b, %s &bytesEncoded)\n", cln, r->encodePduBaseName, bufTypeNameG, lenTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "    bytesEncoded = B%s (b);\n", r->encodeBaseName);
+        fprintf (src, "    return !b.WriteError();\n");
+        fprintf (src, "}\n\n");
+    }
+
+    if (printDecodersG)
+    {
+        fprintf (hdr, "  int			B%s (%s b, %s &bytesDecoded);\n", r->decodePduBaseName, bufTypeNameG, lenTypeNameG);
+
+        fprintf (src, "int %s::B%s (%s b, %s &bytesDecoded)\n", cln, r->decodePduBaseName, bufTypeNameG, lenTypeNameG);
+	fprintf (src, "{\n");
+        fprintf (src, "    %s env;\n", envTypeNameG);
+        fprintf (src, "    int val;\n\n");
+        fprintf (src, "    bytesDecoded = 0;\n");
+        fprintf (src, "    if ((val = setjmp (env)) == 0)\n");
+        fprintf (src, "    {\n");
+        fprintf (src, "         BDec (b, bytesDecoded, env);\n");
+        fprintf (src, "         return !b.ReadError();\n");
+        fprintf (src, "    }\n");
+        fprintf (src, "    else\n");
+        fprintf (src, "        return false;\n");
+/*
+        fprintf (src, "    { cerr << \"longjmp return value is \" << val << endl;\n");
+        fprintf (src, "        return false; }\n");
+*/
+        fprintf (src, "}\n\n");
+    }
+
+    fprintf (hdr, "\n");
+
+} /* PrintPduMemberFcns */
+
+
+static void
+PrintCxxEocEncoders PARAMS ((src, td, t, bufVarName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    char *bufVarName)
+{
+    TagList *tl;
+    Tag *tag;
+    int stoleChoiceTags;
+
+    /*
+     * get all the tags on this type
+     */
+    tl = (TagList*) GetTags (t, &stoleChoiceTags);
+
+    /*
+     * leave choice elmt tag enc to encoding routine
+     */
+    if (!stoleChoiceTags)
+    {
+        FOR_EACH_LIST_ELMT (tag, tl)
+            if (tag->form == CONS)
+                fprintf (src, "      BEncEocIfNec (b);\n");
+    }
+
+    FreeTags (tl);
+
+} /* PrintCxxEocEncoders */
+
+
+static int
+HasShortLen PARAMS ((t),
+    Type *t)
+{
+    enum BasicTypeChoiceId typesType;
+    /*
+     * efficiency hack - use simple length (1 byte)
+     * encoded for type (almost) guaranteed to have
+     * encoded lengths of 0 <= len <= 127
+     */
+    typesType = GetBuiltinType (t);
+    return typesType == BASICTYPE_BOOLEAN || typesType == BASICTYPE_INTEGER || typesType == BASICTYPE_NULL || typesType == BASICTYPE_REAL || typesType == BASICTYPE_ENUMERATED;
+} /* HasShortLen */
+
+
+/*
+ * prints length encoding code.  Primitives always use
+ * definite length and constructors get "ConsLen"
+ * which can be configured at compile to to be indefinite
+ * or definite.  Primitives can also be "short" (isShort is true)
+ * in which case a fast macro is used to write the length.
+ * Types for which isShort apply are: boolean, null and
+ * (almost always) integer and reals
+ */
+static void
+PrintCxxLenEncodingCode PARAMS ((f, isCons, isShort, lenVarName, bufVarName),
+    FILE *f _AND_
+    int isCons _AND_
+    int isShort _AND_
+    char *lenVarName _AND_
+    char *bufVarName)
+{
+    if (isCons)
+        fprintf (f, "    %s += BEncConsLen (%s, %s);\n", lenVarName, bufVarName, lenVarName);
+    else
+    {
+        if (isShort)
+        {
+            fprintf (f, "    BEncDefLenTo127 (%s, %s);\n", bufVarName, lenVarName);
+            fprintf (f, "    %s++;\n", lenVarName);
+        }
+        else
+            fprintf (f, "    %s += BEncDefLen (%s, %s);\n", lenVarName, bufVarName, lenVarName);
+    }
+} /* PrintCxxLenEncodingCode */
+
+
+/*
+ * prints last tag's encoding code first
+ */
+static void
+PrintCxxTagAndLenList PARAMS ((src, t, tagList, lenVarName, bufVarName),
+    FILE *src _AND_
+    Type *t _AND_
+    TagList *tagList _AND_
+    char *lenVarName _AND_
+    char *bufVarName)
+{
+    char *classStr;
+    char *formStr;
+    char *codeStr;
+    Tag *tg;
+    Tag *last;
+    int tagLen;
+    enum BasicTypeChoiceId typesType;
+    int isShort;
+
+    if ((tagList == NULL) || LIST_EMPTY (tagList))
+        return;
+
+    /*
+     * efficiency hack - use simple length (1 byte)
+     * encoded for type (almost) guaranteed to have
+     * encoded lengths of 0 <= len <= 127
+     */
+    isShort = HasShortLen (t);
+
+    /*
+     * since encoding backward encode tags backwards
+     */
+    last = (Tag*)LAST_LIST_ELMT (tagList);
+    FOR_EACH_LIST_ELMT_RVS (tg, tagList)
+    {
+        classStr = Class2ClassStr (tg->tclass);
+
+        if (tg->form == CONS)
+        {
+            formStr = Form2FormStr (CONS);
+            PrintCxxLenEncodingCode (src, TRUE, isShort, lenVarName, bufVarName);
+        }
+        else /* PRIM or ANY_FORM */
+        {
+            formStr = Form2FormStr (PRIM);
+            PrintCxxLenEncodingCode (src, FALSE, isShort, lenVarName, bufVarName);
+        }
+
+/*      GetTags sets the form properly now
+        if (IsPrimitiveByDefOrRef (t) && (tg == last))
+        {
+            formStr = Form2FormStr (PRIM);
+            PrintCxxLenEncodingCode (src, FALSE, isShort, lenVarName, bufVarName);
+        }
+        else
+        {
+            formStr = Form2FormStr (CONS);
+            PrintCxxLenEncodingCode (src, TRUE, isShort, lenVarName, bufVarName);
+        }
+*/
+
+        fprintf (src, "\n");
+
+        tagLen = TagByteLen (tg->code);
+
+        if (tg->tclass == UNIV)
+            fprintf (src, "    %s += BEncTag%d (%s, %s, %s, %s);\n", lenVarName, tagLen, bufVarName, classStr, formStr, Code2UnivCodeStr (tg->code));
+        else
+            fprintf (src, "    %s += BEncTag%d (%s, %s, %s, %d);\n", lenVarName, tagLen, bufVarName, classStr, formStr, tg->code);
+    }
+
+} /* PrintCxxTagAndLenList */
+
+
+/*
+ *  Recursively walks through tags, printing lower lvl tags
+ *  first (since encoding is done backwards).
+ *
+ */
+static void
+PrintCxxTagAndLenEncodingCode PARAMS ((src, td, t, lenVarName, bufVarName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    char *lenVarName _AND_
+    char *bufVarName)
+{
+    TagList *tl;
+    int stoleChoiceTags;
+
+    /*
+     * get all the tags on this type
+     */
+    tl = (TagList*) GetTags (t, &stoleChoiceTags);
+
+    /*
+     * leave choice elmt tag enc to encoding routine
+     */
+    if (!stoleChoiceTags)
+        PrintCxxTagAndLenList (src, t, tl, lenVarName, bufVarName);
+
+    FreeTags (tl);
+
+} /* PrintCxxTagAndLenEncodingCode */
+
+
+/*
+ * used to figure out local variables to declare
+ * for decoding tags/len pairs on type t
+ */
+static int
+CxxCountVariableLevels PARAMS ((t),
+    Type *t)
+{
+    if (GetBuiltinType (t) == BASICTYPE_CHOICE)
+        return CountTags (t) +1; /* since must decode 1 internal tag type */
+    else
+        return CountTags (t);
+} /* CxxCountVariableLevels */
+
+
+/*
+ * returns true if elmts curr following
+ *  onward are all optional ow. false
+ */
+static int
+RestAreTailOptional PARAMS ((e),
+    NamedTypeList *e)
+{
+    NamedType *elmt;
+    void *tmp;
+    int retVal;
+
+    if (e == NULL)
+        return TRUE;
+
+    tmp = (void*)CURR_LIST_NODE (e);
+    retVal = TRUE;
+    AsnListNext (e);
+    FOR_REST_LIST_ELMT (elmt, e)
+    {
+        if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL))
+        {
+            retVal = FALSE;
+            break;
+        }
+    }
+    SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */
+    return retVal;
+}
+
+
+/*
+ * prints typedef or new class given an ASN.1  type def of a primitive type
+ * or typeref.  Uses inheritance to cover re-tagging and named elmts.
+ */
+static void
+PrintCxxSimpleDef PARAMS ((hdr, src, if_IBM_ENC (hdrdb COMMA srcdb COMMA) if_META (m COMMA) r, td),
+    FILE *hdr _AND_
+    FILE *src _AND_
+    if_IBM_ENC (FILE *hdrdb _AND_)
+    if_IBM_ENC (FILE *srcdb _AND_)
+    if_META (Module *m _AND_)
+    CxxRules *r _AND_
+    TypeDef *td)
+{
+    Tag *tag;
+    TagList *tags;
+    char *formStr;
+    char *classStr;
+    int tagLen;
+    int i;
+    CNamedElmt *n;
+    int stoleChoiceTags;
+    int elmtLevel;
+    enum BasicTypeChoiceId typeId;
+
+    fprintf (hdr, "/* ");
+    SpecialPrintType (hdr, td, td->type);
+    fprintf (hdr, " */\n");
+
+    /* check if has been re-tagged
+     *   eg Foo ::= [APPLICATION 2] IMPLICIT REAL
+     * or if it has named elmts in which case a new class must
+     * be defined
+     *  eg Foo ::= INTEGER { one (1), two (2), three (3) }
+     */
+
+    if (IsNewType (td->type))
+    {
+	int	hasNamedElmts;
+
+#ifdef _IBM_ENC_
+#include "./ibm_editor/print_cxx_simple_def.h"
+#endif /* _IBM_ENC_ */
+
+        fprintf (hdr, "class %s: public %s\n", td->cxxTypeDefInfo->className, td->type->cxxTypeRefInfo->className);
+        fprintf (hdr, "{\n");
+        fprintf (hdr, "public:\n");
+
+        /*
+         * must explicitly call constructors for base class
+         */
+        PrintDerivedConstructors (hdr, r, td);
+
+        /* do named elmts enum if any */
+        /* for types with named elements, inherit from the base
+         * class and define and enum eg:
+         * Foo ::= INTEGER { one (1), two (2), five (5) }
+         *  ->
+         * class Foo: public AsnInt
+         * {
+         * public:
+         *		Foo(): AsnInt() {}
+         *		Foo (int val): AsnInt (int val) {}
+         *    enum { one = 1, two = 2, five = 5 };
+         * };
+         * or
+         * Foo2 ::= [APPLICATION 2] INTEGER
+         * -->
+         * class Foo: public AsnInt
+         * {
+         * public:
+         *		Foo(): AsnInt() {}
+         *		Foo (int val): AsnInt (int val) {}
+         *     AsnLen	BEnc { ....... } <-- holds new tag enc/dec
+         *     void	BDec { ....... }   <--/
+         *     int	BEncPdu { ....... }
+         *     int	BDecPdu { ....... }
+         * };
+         * (must 'inherit' constructors explicitly)
+         */
+
+        if (hasNamedElmts = HasNamedElmts (td->type))
+        {
+            fprintf (hdr, "  enum\n");
+            fprintf (hdr, "  {\n");
+            FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts)
+            {
+                fprintf (hdr, "    %s = %d", n->name, n->value);
+                if (n != (CNamedElmt *)LAST_LIST_ELMT (td->type->cxxTypeRefInfo->namedElmts))
+                    fprintf (hdr, ",\n");
+                else
+                    fprintf (hdr, "\n");
+            }
+            fprintf (hdr, "  };\n");
+        }
+#if META
+	if (printMetaG)
+	{
+	    const char	*T, *t;
+	    int a3;
+
+	    fprintf (hdr, "\n");
+	    fprintf (hdr, "#if META\n");
+	    fprintf (src, "#if META\n\n");
+
+	    fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  return new %s;\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "}\n\n");
+
+	    if (hasNamedElmts = HasNamedElmts (td->type))
+	    {
+		fprintf (hdr, "  static const AsnNameDesc	_nmdescs[];\n");
+
+		fprintf (src, "const AsnNameDesc %s::_nmdescs[] =\n", td->cxxTypeDefInfo->className);
+		fprintf (src, "{\n");
+		FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts)
+#if 0 /* (no asn1 names available!) */
+		    if (printMetaG == META_backend_names)
+		    else /* META_asn1_names */
+#endif
+			fprintf (src, "  \"%s\", %s, // %d\n", n->name, n->name, n->value);
+		fprintf (src, "  NULL, -1\n");
+		fprintf (src, "};\n\n");
+	    }
+
+	    switch (GetBuiltinType (td->type))
+	    {
+		case BASICTYPE_BOOLEAN:
+		    T = "BOOLEAN";
+		    t = "Bool";
+		    a3 = FALSE;
+		    break;
+		case BASICTYPE_ENUMERATED:
+		    T = "ENUMERATED";
+		    t = "Enum";
+		    a3 = TRUE;
+		    break;
+		case BASICTYPE_INTEGER:
+		    T = "INTEGER";
+		    t = "Int";
+		    a3 = TRUE;
+		    break;
+		case BASICTYPE_REAL:
+		    T = "REAL";
+		    t = "Real";
+		    a3 = FALSE;
+		    break;
+		case BASICTYPE_OCTETSTRING:
+		    T = "OCTET_STRING";
+		    t = "Octs";
+		    a3 = FALSE;
+		    break;
+		case BASICTYPE_BITSTRING:
+		    T = "BIT_STRING";
+		    t = "Bits";
+		    a3 = TRUE;
+		    break;
+		case BASICTYPE_OID:
+		    T = "OID";
+		    t = "Oid";
+		    a3 = FALSE;
+	    	default:
+		    T =
+		    t = "?";
+		    a3 = FALSE;
+	    }
+
+	    fprintf (hdr, "  static const Asn%sTypeDesc	_desc;\n", t);
+	    fprintf (hdr, "  const AsnTypeDesc	*_getdesc() const;\n");
+
+	    fprintf (src, "const Asn%sTypeDesc %s::_desc\n", t, td->cxxTypeDefInfo->className);
+	    fprintf (src, "(\n");
+	    fprintf (src, "  &%sModuleDesc,\n", m->cxxname);
+	    if (printMetaG == META_backend_names)
+		fprintf (src, "  \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName);
+	    else /* META_asn1_names */
+		fprintf (src, "  \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className);
+	    fprintf (src, "  %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false");
+	    fprintf (src, "  AsnTypeDesc::%s,\n", T);
+	    fprintf (src, "  create%s", td->cxxTypeDefInfo->className);
+	    if (a3)
+		fprintf (src, ",\n  %s", hasNamedElmts ? "_nmdescs" : "NULL");
+	    fprintf (src, "\n);\n\n");
+
+	    fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  return &_desc;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (hdr, "#endif // META\n");
+	    fprintf (src, "#endif // META\n\n");
+
+#if TCL
+#endif
+	}
+#endif /* META */
+
+        /*
+         * Re-do BerEncode, BerDeocode, BerDecodePdu and BerDecodePdu
+         * if this type has been re-tagged
+         */
+        if ((IsDefinedByLibraryType (td->type) && !HasDefaultTag (td->type))
+	  || (IsTypeRef (td->type) && ((td->type->tags != NULL) && !LIST_EMPTY (td->type->tags))))
+        {
+            /* only BerEn/Decode BerEn/DecodePdu need to be re-done if tags are different */
+
+            /* print clone routine for ANY mgmt */
+            PrintCloneMethod (hdr, src, td);
+
+            tags = GetTags (td->type, &stoleChoiceTags);
+            typeId = GetBuiltinType (td->type);
+
+            /* do BerEncode function */
+            if (printEncodersG)
+            {
+                fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG);
+                fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG);
+                fprintf (src, "{\n");
+                fprintf (src, "    %s l;\n", lenTypeNameG);
+
+                PrintCxxEocEncoders (src, td, td->type, "b");
+
+                fprintf (src, "    l = BEncContent (b);\n");
+
+                /* encode each tag/len pair if any */
+                if (!stoleChoiceTags)
+                {
+                    FOR_EACH_LIST_ELMT_RVS (tag, tags)
+                    {
+                        classStr = Class2ClassStr (tag->tclass);
+
+                        if (tag->form == ANY_FORM)
+                        {
+                            formStr = Form2FormStr (PRIM);
+                            PrintCxxLenEncodingCode (src, FALSE, HasShortLen (td->type), "l", "b");
+                        }
+                        else
+                        {
+                            formStr = Form2FormStr (tag->form);
+                            PrintCxxLenEncodingCode (src, TRUE, HasShortLen (td->type), "l", "b");
+                        }
+
+                        fprintf (src, "\n");
+                        tagLen = TagByteLen (tag->code);
+
+                        if (tag->tclass == UNIV)
+                            fprintf (src, "    l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code));
+                        else
+                            fprintf (src, "    l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code);
+                    }
+                }
+                fprintf (src, "    return l;\n");
+                fprintf (src, "}\n\n");
+            }
+            /* end of BEnc function */
+
+            /* Do BDec function */
+            if (printDecodersG)
+            {
+                fprintf (hdr, "  void			B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG);
+                fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG);
+                fprintf (src, "{\n");
+                fprintf (src, "    %s tag;\n", tagTypeNameG);
+
+                /* print extra locals for redundant lengths */
+                for (i = 1; (tags != NULL) && (i <= LIST_COUNT (tags)); i++)
+                    fprintf (src, "    %s elmtLen%d;\n", lenTypeNameG, i);
+                if (typeId == BASICTYPE_CHOICE)
+                    fprintf (src, "    %s elmtLen%d;\n", lenTypeNameG, i++);
+                fprintf (src, "\n");
+
+                /*  decode tag/length pair (s) */
+                elmtLevel = 0;
+                if (!stoleChoiceTags)
+                {
+                    FOR_EACH_LIST_ELMT (tag, tags)
+                    {
+                        classStr = Class2ClassStr (tag->tclass);
+
+                        if (tag->form == ANY_FORM)
+                            formStr = Form2FormStr (PRIM);
+                        else
+                            formStr = Form2FormStr (tag->form);
+
+                        fprintf (src, "    if (((tag = BDecTag (b, bytesDecoded, env)) != ");
+
+                        if (tag->tclass == UNIV)
+                        {
+                            fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, Code2UnivCodeStr (tag->code));
+                            if (tag->form == ANY_FORM)
+                                fprintf (src, "\n        && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), Code2UnivCodeStr (tag->code));
+                            else
+                                fprintf (src, ")\n");
+                        }
+                        else
+                        {
+                            fprintf (src, "MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code);
+                            if (tag->form == ANY_FORM)
+                                fprintf (src, "\n        && (tag != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code);
+                            else
+                                fprintf (src, ")\n");
+                        }
+                        fprintf (src, "    {\n");
+            		fprintf (src, "        Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName);
+                        fprintf (src, "        longjmp (env, %d);\n", longJmpValG--);
+                        fprintf (src, "    }\n");
+
+                        fprintf (src, "    elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+                    }
+                }
+
+                /* decode first tag from CHOICE's content */
+                if (typeId == BASICTYPE_CHOICE)
+                {
+                    fprintf (src, "    tag = BDecTag (b, bytesDecoded, env);\n");
+                    fprintf (src, "    elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+                }
+
+                fprintf (src, "    B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, i-1);
+
+                /* grab any EOCs that match redundant, indef lengths */
+                for (i = elmtLevel-1; i > 0; i--)
+                {
+                    fprintf (src, "    if (elmtLen%d == INDEFINITE_LEN)\n", i);
+                    fprintf (src, "        BDecEoc (b, bytesDecoded, env);\n");
+                }
+
+                fprintf (src, "}\n\n");
+            }
+            /* end of BDec function */
+
+            PrintPduMemberFcns (src, hdr, r, td->cxxTypeDefInfo->className);
+
+            FreeTags (tags);
+        }
+        /* close class def */
+        fprintf (hdr, "};\n\n\n");
+
+    }
+    else  /* isomorphic with referenced type, so just to a typedef */
+    {
+#ifdef _IBM_ENC_
+#include "./ibm_editor/print_cxx_simple_def1.h"
+#endif /* _IBM_ENC_ */
+
+#if META
+	if (printMetaG)
+	{
+	    fprintf (hdr, "#if META\n");
+	    fprintf (src, "#if META\n\n");
+
+	    fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  return new %s;\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "}\n\n");
+
+	    fprintf (hdr, "struct %s: public %s\n", td->cxxTypeDefInfo->className, td->type->cxxTypeRefInfo->className);
+	    fprintf (hdr, "{\n");
+
+	    PrintDerivedConstructors (hdr, r, td);
+
+            PrintCloneMethod (hdr, src, td);
+
+	    fprintf (hdr, "  static const AsnAliasTypeDesc	_desc;\n");
+	    fprintf (hdr, "  const AsnTypeDesc	*_getdesc() const;\n");
+
+	    fprintf (src, "const AsnAliasTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "(\n");
+	    fprintf (src, "  &%sModuleDesc,\n", m->cxxname);
+	    if (printMetaG == META_backend_names)
+		fprintf (src, "  \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName);
+	    else /* META_asn1_names */
+		fprintf (src, "  \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className);
+	    fprintf (src, "  %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false");
+	    fprintf (src, "  AsnTypeDesc::ALIAS,\n");
+	    fprintf (src, "  create%s,\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "  &%s::_desc\n);\n\n", td->type->cxxTypeRefInfo->className);
+
+	    fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  return &_desc;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (hdr, "};\n\n");
+
+	    fprintf (hdr, "#else // META\n\n");
+	    fprintf (src, "#endif // META\n\n");
+	}
+#endif /* META */
+
+        fprintf (hdr, "typedef %s %s;\n\n", td->type->cxxTypeRefInfo->className, td->cxxTypeDefInfo->className);
+
+#if META
+	if (printMetaG)
+	    fprintf (hdr, "#endif // META\n\n");
+#endif /* META */
+    }
+} /* PrintCxxSimpleDef */
+
+static void
+PrintCxxChoiceDefCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, choice, novolatilefuncs),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    if_IBM_ENC (FILE *srcdb _AND_)
+    if_IBM_ENC (FILE *hdrdb _AND_)
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *choice _AND_
+    int novolatilefuncs)
+{
+    NamedType *e;
+    char *classStr;
+    char *formStr;
+    char *codeStr;
+    int tagLen, i;
+    Tag *tag;
+    TagList *tags;
+    char *varName;
+    CxxTRI *cxxtri;
+    int elmtLevel;
+    int varCount, tmpVarCount;
+    int stoleChoiceTags;
+    enum BasicTypeChoiceId tmpTypeId;
+    NamedType *defByNamedType;
+
+#ifdef _IBM_ENC_
+#include "./ibm_editor/print_cxx_choice_def_code.h"
+#endif /* _IBM_ENC_ */
+
+    /* put class spec in hdr file */
+
+    fprintf (hdr, "class %s%s\n", td->cxxTypeDefInfo->className, baseClassesG);
+    fprintf (hdr, "{\n");
+    fprintf (hdr, "public:\n");
+
+    /* write out choiceId enum type */
+
+    fprintf (hdr, "  enum %s\n", r->choiceIdEnumName);
+    fprintf (hdr, "  {\n");
+    FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+    {
+        fprintf (hdr, "     %s = %d", e->type->cxxTypeRefInfo->choiceIdSymbol, e->type->cxxTypeRefInfo->choiceIdValue);
+        if (e != (NamedType*)LAST_LIST_ELMT (choice->basicType->a.choice))
+            fprintf (hdr, ",\n");
+        else
+            fprintf (hdr, "\n");
+    }
+    fprintf (hdr, "  };\n\n");
+
+    /* write out the choice Id field */
+    /*     fprintf (hdr, "protected:\n"); */
+    fprintf (hdr, "  enum %s	%s;\n", r->choiceIdEnumName, r->choiceIdFieldName);
+
+    /* write out the choice element anonymous union */
+    fprintf (hdr, "  union\n");
+    fprintf (hdr, "  {\n");
+    FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+    {
+        fprintf (hdr, "     ");
+        PrintCxxType (hdr, mods, m, r, td, choice, e->type);
+        fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName);
+    }
+    fprintf (hdr, "  };\n\n");
+
+#if META
+    if (printMetaG)
+    {
+	fprintf (hdr, "#if META\n");
+	fprintf (src, "#if META\n\n");
+
+	fprintf (hdr, "  static const AsnChoiceTypeDesc	_desc;\n");
+	fprintf (hdr, "  static const AsnChoiceMemberDesc	_mdescs[];\n\n");
+	fprintf (hdr, "  const AsnTypeDesc		*_getdesc() const;\n");
+	fprintf (hdr, "  AsnType			*_getref (const char *membername, bool create = false);\n\n");
+
+	fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  return new %s;\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "}\n\n");
+
+	fprintf (src, "const AsnChoiceMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+	    if (printMetaG == META_backend_names)
+		fprintf (src, "  AsnChoiceMemberDesc (\"%s\", &%s::_desc), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->fieldName ? e->fieldName : "");
+	    else /* META_asn1_names */
+		fprintf (src, "  AsnChoiceMemberDesc (\"%s\", &%s::_desc), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->cxxTypeRefInfo->fieldName);
+	fprintf (src, "  AsnChoiceMemberDesc()\n");
+	fprintf (src, "};\n\n");
+
+	fprintf (src, "const AsnChoiceTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "(\n");
+	fprintf (src, "  &%sModuleDesc,\n", m->cxxname);
+	if (printMetaG == META_backend_names)
+	    fprintf (src, "  \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName);
+	else /* META_asn1_names */
+	    fprintf (src, "  \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className);
+	fprintf (src, "  %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false");
+	fprintf (src, "  AsnTypeDesc::CHOICE,\n");
+	fprintf (src, "  create%s,\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "  _mdescs\n");
+	fprintf (src, ");\n\n");
+
+	fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  return &_desc;\n");
+	fprintf (src, "}\n\n");
+
+	fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  ChoiceIdEnum newCid = (ChoiceIdEnum)_desc.choicebyname (membername);\n");
+	fprintf (src, "  if (newCid == -1)\n");
+	fprintf (src, "    return NULL;\n");
+	fprintf (src, "  if (newCid == choiceId)\n");
+	fprintf (src, "  {\n");
+	fprintf (src, "    switch (choiceId)\n");
+	fprintf (src, "    {\n");
+	FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+	{
+	    fprintf (src, "      case %sCid:\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "        return %s;\n", e->type->cxxTypeRefInfo->fieldName);
+	}
+	fprintf (src, "      default:\n");
+	fprintf (src, "        return NULL;\n");
+	fprintf (src, "    }\n");
+	fprintf (src, "  }\n");
+	fprintf (src, "  else\n");
+	fprintf (src, "  {\n");
+	fprintf (src, "    if (create)\n");
+	fprintf (src, "    {\n");
+	fprintf (src, "//      switch (choiceId)\n");
+	fprintf (src, "//      {\n");
+	FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+	{
+	    fprintf (src, "//        case %sCid:\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "//          delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "//          %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "//          break;\n");
+	}
+	fprintf (src, "//        default:\n");
+	fprintf (src, "//          return NULL;\n");
+	fprintf (src, "//      }\n");
+	e = FIRST_LIST_ELMT (choice->basicType->a.choice);
+	fprintf (src, "      // simply delete any member, the virtual function table takes care of the rest:\n");
+	fprintf (src, "      delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+	fprintf (src, "      %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+	fprintf (src, "      switch (choiceId = newCid)\n");
+	fprintf (src, "      {\n");
+	FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+	{
+	    fprintf (src, "        case %sCid:\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "          return %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+	}
+	fprintf (src, "        default: // internal error!\n");
+	fprintf (src, "          return NULL;\n");
+	fprintf (src, "      }\n");
+	fprintf (src, "    }\n");
+	fprintf (src, "    else\n");
+	fprintf (src, "      return NULL;\n");
+	fprintf (src, "  }\n");
+	fprintf (src, "}\n\n");
+
+#if TCL
+	if (printTclG)
+	{
+	    fprintf (hdr, "#if TCL\n");
+	    fprintf (src, "#if TCL\n\n");
+
+	    fprintf (hdr, "  int			TclGetDesc (Tcl_DString *) const;\n");
+	    fprintf (hdr, "  int			TclGetVal (Tcl_Interp *) const;\n");
+	    fprintf (hdr, "  int			TclSetVal (Tcl_Interp *, const char *valstr);\n\n");
+
+	    fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Tcl_DStringAppendElement (valstr, (char*)_desc.choicebyvalue (choiceId));\n");
+	    fprintf (src, "  // hack: since all members are pointers, we don't have to check for its type via choiceId, because all we want to know is whether it's NULL or not:\n");
+	    e = FIRST_LIST_ELMT (choice->basicType->a.choice);
+	    fprintf (src, "  Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  switch (choiceId)\n");
+	    fprintf (src, "  {\n");
+	    FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+	    {
+		fprintf (src, "    case %sCid:\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "      if (%s)\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "        if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "          return TCL_ERROR;\n");
+		fprintf (src, "      break;\n");
+	    }
+	    fprintf (src, "    default:\n");
+	    fprintf (src, "      Tcl_SetResult (interp, \"illegal choiceId in %s\", TCL_STATIC);\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "      Tcl_SetErrorCode (interp, \"SNACC\", \"ILLCHOICE\", NULL);\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "  Tcl_DString valstr;\n");
+	    fprintf (src, "  Tcl_DStringInit (&valstr);\n");
+	    fprintf (src, "  Tcl_DStringAppendElement (&valstr, (char*)_desc.choicebyvalue (choiceId));\n");
+	    fprintf (src, "  Tcl_DStringAppendElement (&valstr, interp->result);\n");
+	    fprintf (src, "  Tcl_ResetResult (interp);\n");
+	    fprintf (src, "  Tcl_DStringResult (interp, &valstr);\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Args elem;\n");
+	    fprintf (src, "  if (Tcl_SplitList (interp, (char*)valstr, &elem.c, &elem.v) != TCL_OK)\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "  if (elem.c != 2)\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    sprintf (interp->result, \"syntax error: expected a pair, but it's got %%d element(s)\", elem.c);\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "  AsnType *member = _getref (elem.v[0], true);\n");
+	    fprintf (src, "  if (!member)\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    Tcl_AppendResult (interp, \"illegal choice \", elem.v[0], \" for %s\", NULL);\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "    Tcl_SetErrorCode (interp, \"SNACC\", \"ILLCHOICE\", NULL);\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "  return member->TclSetVal (interp, elem.v[1]);\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (hdr, "#endif // TCL\n");
+	    fprintf (src, "#endif // TCL\n\n");
+	}
+#endif /* TCL */
+
+	fprintf (hdr, "#endif // META\n");
+	fprintf (src, "#endif // META\n\n");
+    }
+#endif /* META */
+
+    fprintf (hdr, "\n");
+
+    /* constructors and destructor */
+
+    fprintf (hdr, "			%s();\n", td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    e = FIRST_LIST_ELMT (choice->basicType->a.choice);
+    fprintf (src, "  choiceId = %sCid;\n", e->type->cxxTypeRefInfo->fieldName);
+    fprintf (src, "#if TCL\n");
+    fprintf (src, "  %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+    fprintf (src, "#else\n");
+    fprintf (src, "  %s = NULL; // incomplete initialization of mandatory element!\n", e->type->cxxTypeRefInfo->fieldName);
+    fprintf (src, "#endif // TCL\n");
+    fprintf (src, "}\n\n");
+
+    fprintf (hdr, "			%s (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::%s (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    fprintf (src, "  Asn1Error << \"use of incompletely defined %s::%s (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "  abort();\n");
+    fprintf (src, "}\n\n");
+
+    fprintf (hdr, "  virtual		~%s();\n\n", td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::~%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    fprintf (src, "  switch (choiceId)\n");
+    fprintf (src, "  {\n");
+    FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+    {
+	fprintf (src, "    case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol);
+	if (e->type->cxxTypeRefInfo->isPtr)
+	    fprintf (src, "      delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+	fprintf (src, "      break;\n");
+    }
+    fprintf (src, "  } // end of switch\n");
+    fprintf (src, "} // end of destructor\n");
+    fprintf (src, "\n");
+
+    /* print clone routine for ANY mgmt */
+    PrintCloneMethod (hdr, src, td);
+
+    fprintf (hdr, "  %s		&operator = (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+
+    fprintf (src, "#if SNACC_DEEP_COPY\n");
+    fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "#else // SNACC_DEEP_COPY\n");
+    fprintf (src, "%s &%s::operator = (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "#endif // SNACC_DEEP_COPY\n");
+    fprintf (src, "{\n");
+    fprintf (src, "#if SNACC_DEEP_COPY\n");
+    fprintf (src, "  if (this != &that)\n");
+    fprintf (src, "  {\n");
+    fprintf (src, "    switch (choiceId)\n");
+    fprintf (src, "    {\n");
+    FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+    {
+	if (e->type->cxxTypeRefInfo->isPtr)
+	{
+	    fprintf (src, "      case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol);
+	    fprintf (src, "        delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "        break;\n");
+	}
+    }
+    fprintf (src, "    }\n");
+    fprintf (src, "    switch (choiceId = that.choiceId)\n");
+    fprintf (src, "    {\n");
+    FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+    {
+	fprintf (src, "      case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol);
+	if (e->type->cxxTypeRefInfo->isPtr)
+	{
+	    fprintf (src, "        %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+	    fprintf (src, "        *%s = *that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName);
+	}
+	else
+	    fprintf (src, "        %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName);
+	fprintf (src, "        break;\n");
+    }
+    fprintf (src, "    }\n");
+    fprintf (src, "  }\n");
+    fprintf (src, "\n");
+    fprintf (src, "  return *this;\n");
+    fprintf (src, "#else // SNACC_DEEP_COPY\n");
+    fprintf (src, "  Asn1Error << \"use of incompletely defined %s &%s::operator = (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "  abort();\n");
+    fprintf (src, "  // if your compiler complains here, check the -novolat option\n");
+    if (novolatilefuncs)
+    {
+      fprintf (src, "  return *this;\n");
+    }
+    fprintf (src, "#endif // SNACC_DEEP_COPY\n");
+    fprintf (src, "}\n\n");
+
+    /* BerEncodeContent */
+    if (printEncodersG)
+    {
+        fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG);
+
+        fprintf (src, "%s\n", lenTypeNameG);
+        fprintf (src, "%s::B%s (%s b)\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG);
+        fprintf (src, "{\n");
+
+        /* print local vars */
+        fprintf (src, "  %s l;\n", lenTypeNameG);
+
+        fprintf (src, "  switch (%s)\n", r->choiceIdFieldName);
+        fprintf (src, "  {\n");
+        FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+        {
+            cxxtri =  e->type->cxxTypeRefInfo;
+            fprintf (src, "    case %s:\n", cxxtri->choiceIdSymbol);
+
+            varName = cxxtri->fieldName;
+
+            /* encode Eoc (s) if nec */
+            PrintCxxEocEncoders (src, td, e->type, "b");
+
+            /* encode content */
+            tmpTypeId = GetBuiltinType (e->type);
+            if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+            {
+                fprintf (src, "        %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+
+                defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+                if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID)
+                {
+                    fprintf (src, "SetTypeByOid (");
+                    if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                        fprintf (src, " *");
+                    fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                }
+                else
+                {
+                    fprintf (src, "SetTypeByInt (");
+                    if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                        fprintf (src, " *");
+                    fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                }
+
+                fprintf (src, "      l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "B%s (b);\n", r->encodeBaseName);
+            }
+            else if (tmpTypeId == BASICTYPE_ANY)
+            {
+#ifdef VDADER_RULES
+if (! gVDADER_RULES)
+{
+#endif
+                fprintf (src, "        %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "SetTypeBy???(???);\n");
+
+                fprintf (src, "      l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "B%s (b);\n", r->encodeBaseName);
+
+#ifdef VDADER_RULES
+}
+else
+{
+                    fprintf (src, "        ENC_LOAD_ANYBUF(");
+                    if (!cxxtri->isPtr)
+                      fprintf (src, "&");
+                    fprintf (src, "%s, b, l);\n", varName);
+}
+#endif
+            }
+            else
+            {
+                fprintf (src, "      l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+
+                fprintf (src, "B%s (b);\n", r->encodeContentBaseName);
+            }
+
+
+            /* encode tag (s) & len (s) */
+            PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "b");
+
+
+            fprintf (src, "      break;\n\n");
+        }
+        fprintf (src, "  } // end switch\n");
+
+        fprintf (src, "  return l;\n");
+        fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName);
+    }
+    /* end of BerEncodeContent method */
+
+    /* BerDecodeContent */
+    if (printDecodersG)
+    {
+        fprintf (hdr, "  void			B%s (%s b, %s tag, %s elmtLen, %s &bytesDecoded, %s env);\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "void %s::B%s (%s b, %s tag, %s elmtLen0, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "{\n");
+
+        /* print local vars */
+        /* count max number of extra length var nec
+         * by counting tag/len pairs on components of the CHOICE
+         */
+        varCount = 0;
+        FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+        {
+            tmpVarCount = CxxCountVariableLevels (e->type);
+            if (tmpVarCount > varCount)
+                varCount = tmpVarCount;
+        }
+        /* write extra length vars - remeber choice content
+         * decoders are passed the 'key' tag so need one less
+         * than max var count.
+         */
+        for (i = 1; i < varCount; i++)
+            fprintf (src, "  %s elmtLen%d;\n", lenTypeNameG, i);
+
+        /* switch on given tag - choices always have the key tag decoded */
+        fprintf (src, "  switch (tag)\n");
+        fprintf (src, "  {\n");
+        FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+        {
+            cxxtri =  e->type->cxxTypeRefInfo;
+
+            tags = GetTags (e->type, &stoleChoiceTags);
+
+            if (LIST_EMPTY (tags))
+            {
+                fprintf (src, "    // ANY Type?\n");
+                fprintf (src, "    case MAKE_TAG_ID (?, ?, ?):\n");
+            }
+            else
+            {
+                tag = (Tag*)FIRST_LIST_ELMT (tags);
+                classStr = Class2ClassStr (tag->tclass);
+                codeStr = Code2UnivCodeStr (tag->code);
+                formStr = Form2FormStr (tag->form);
+
+                if (tag->tclass == UNIV)
+                {
+                    if (tag->form == ANY_FORM)
+                    {
+                        fprintf (src, "    case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+                        fprintf (src, "    case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+                    }
+                    else
+                        fprintf (src, "    case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+                }
+                else
+                {
+                    if (tag->form == ANY_FORM)
+                    {
+                        fprintf (src, "    case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                        fprintf (src, "    case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+                    }
+                    else
+                        fprintf (src, "    case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code);
+                }
+
+                /* now decode extra tags/length pairs */
+                AsnListFirst (tags);
+                AsnListNext (tags);
+                elmtLevel = 0;
+                if (stoleChoiceTags)
+                {
+                    FOR_REST_LIST_ELMT (tag, tags)
+                    {
+                        classStr = Class2ClassStr (tag->tclass);
+                        codeStr = Code2UnivCodeStr (tag->code);
+                        formStr = Form2FormStr (tag->form);
+
+                        if (tag->tclass == UNIV)
+                        {
+                            if (tag->form == ANY_FORM)
+                            {
+                                fprintf (src, "    case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+                                fprintf (src, "    case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+                            }
+                            else
+                                fprintf (src, "    case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+                        }
+                        else
+                        {
+                            if (tag->form == ANY_FORM)
+                            {
+                                fprintf (src, "    case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                                fprintf (src, "    case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+                            }
+                            else
+                                fprintf (src, "    case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code);
+                        }
+                    }
+                }
+                else /* didn't steal nested choice's tags */
+                {
+                    FOR_REST_LIST_ELMT (tag, tags)
+                    {
+                        classStr = Class2ClassStr (tag->tclass);
+                        codeStr = Code2UnivCodeStr (tag->code);
+                        formStr = Form2FormStr (tag->form);
+
+                        fprintf (src, "      tag = BDecTag (b, bytesDecoded, env);\n");
+                        if (tag->form == ANY_FORM)
+                        {
+                            if (tag->tclass == UNIV)
+                            {
+                                fprintf (src, "      if ((tag != MAKE_TAG_ID (%s, %s, %s))\n",  classStr, Form2FormStr (PRIM), codeStr);
+                                fprintf (src, "          && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr);
+                            }
+                            else
+                            {
+                                fprintf (src, "      if ((tag != MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code);
+                                fprintf (src, "          && (tag != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code);
+                            }
+
+                        }
+                        else
+                        {
+                            if (tag->tclass == UNIV)
+                                fprintf (src, "      if (tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr);
+                            else
+                                fprintf (src, "      if (tag != MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code);
+                        }
+
+                        fprintf (src, "      {\n");
+                        fprintf (src, "         Asn1Error << \"Unexpected Tag\" << endl;\n");
+                        fprintf (src, "         longjmp (env, %d);\n", longJmpValG--);
+                        fprintf (src, "      }\n\n");
+
+                        fprintf (src, "      elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+                    }
+                }
+            }
+            /*
+             * if the choices element is another choice &&
+             * we didn't steal its tags then we must grab
+             * the key tag out of the contained CHOICE
+             */
+            if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE))
+            {
+                fprintf (src, "      tag = BDecTag (b, bytesDecoded, env);\n");
+                fprintf (src, "      elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+            }
+
+            varName = cxxtri->fieldName;
+
+            /* set choice id for to this elment */
+            fprintf (src, "      %s = %s;\n", r->choiceIdFieldName, cxxtri->choiceIdSymbol);
+
+            /* alloc elmt if nec */
+            if (cxxtri->isPtr)
+                fprintf (src, "      %s = new %s;\n", varName, cxxtri->className);
+
+            /* decode content */
+            tmpTypeId = GetBuiltinType (e->type);
+            if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+            {
+                /*
+                 * must check for another EOC for ANYs
+                 * since the any decode routines decode
+                 * their own first tag/len pair
+                 */
+                elmtLevel++;
+
+                fprintf (src, "      %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+
+                defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+                if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID)
+                {
+                    fprintf (src, "SetTypeByOid (");
+                    if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                        fprintf (src, " *");
+                    fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                }
+                else
+                {
+                    fprintf (src, "SetTypeByInt (");
+                    if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                        fprintf (src, " *");
+                    fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                }
+
+                fprintf (src, "      %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "B%s (b, bytesDecoded, env);\n",  r->decodeBaseName);
+            }
+            else if (tmpTypeId == BASICTYPE_ANY)
+            {
+                /*
+                 * must check for another EOC for ANYs
+                 * since the any decode routines decode
+                 * their own first tag/len pair
+                 */
+                elmtLevel++;
+
+#ifdef VDADER_RULES
+if (! gVDADER_RULES )
+{
+#endif
+                fprintf (src, "      %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "SetTypeBy???(???);\n");
+
+                fprintf (src, "      %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "B%s (b, bytesDecoded, env);\n",  r->decodeBaseName);
+
+#ifdef VDADER_RULES
+}
+else 
+                {
+                    fprintf (src, "        DEC_LOAD_ANYBUF(");
+                    if (!cxxtri->isPtr)
+                      fprintf (src, "&");
+                    fprintf (src, "%s, b, bytesDecoded, env);\n", varName);
+                }
+#endif
+            }
+            else
+            {
+                fprintf (src, "        %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+
+                fprintf (src, "B%s (b, tag, elmtLen%d, bytesDecoded, env);\n",  r->decodeContentBaseName, elmtLevel);
+            }
+
+            /* decode Eoc (s) */
+            for (i = elmtLevel-1; i >= 0; i--)
+            {
+                fprintf (src, "      if (elmtLen%d == INDEFINITE_LEN)\n", i);
+                fprintf (src, "        BDecEoc (b, bytesDecoded, env);\n");
+            }
+
+            fprintf (src, "      break;\n\n");
+            FreeTags (tags);
+        }
+
+        fprintf (src, "    default:\n");
+        fprintf (src, "      Asn1Error << \"ERROR - unexpected tag in CHOICE\" << endl;\n");
+        fprintf (src, "      longjmp (env, %d);\n", longJmpValG--);
+        fprintf (src, "      break;\n");
+
+        fprintf (src, "  } // end switch\n");
+        fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName);
+    }
+    /* end of code for printing BDecodeContent method */
+
+    /* do BEnc function */
+    if (printEncodersG)
+    {
+        fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG);
+        fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "    %s l;\n", lenTypeNameG);
+        fprintf (src, "    l = B%s (b);\n", r->encodeContentBaseName);
+
+        /* encode each tag/len pair if any */
+        FOR_EACH_LIST_ELMT_RVS (tag, choice->tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            formStr = Form2FormStr (CONS);  /* choices are constructed */
+            tagLen = TagByteLen (tag->code);
+
+            fprintf (src, "    l += BEncConsLen (b, l);\n");
+
+            if (tag->tclass == UNIV)
+                fprintf (src, "    l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src, "    l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code);
+        }
+        fprintf (src, "    return l;\n");
+        fprintf (src, "}\n\n");
+    }
+    /* end of BEnc function */
+
+    /* Do BDec function */
+    if (printDecodersG)
+    {
+        fprintf (hdr, "  void			B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "    %s elmtLen;\n", lenTypeNameG);
+        fprintf (src, "    %s tag;\n", tagTypeNameG);
+
+        /* print extra locals for redundant lengths */
+        for (i = 1; (choice->tags != NULL) && (i <= LIST_COUNT (choice->tags)); i++)
+        {
+            fprintf (src, "    %s extraLen%d;\n", lenTypeNameG, i);
+        }
+        fprintf (src, "\n");
+
+        /*  decode tag/length pair (s) */
+        elmtLevel = 0;
+        FOR_EACH_LIST_ELMT (tag, choice->tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            formStr = Form2FormStr (CONS);  /* choices are constructed */
+
+            fprintf (src, "    if (BDecTag (b, bytesDecoded, env) != ");
+            if (tag->tclass == UNIV)
+                fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src, "MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code);
+            fprintf (src, "    {\n");
+	    fprintf (src, "        Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName);
+            fprintf (src, "        longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "    }\n");
+            fprintf (src, "    extraLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+        }
+
+        /* decode identifying tag from choice body */
+        fprintf (src, "    /*  CHOICEs are a special case - grab identifying tag */\n");
+        fprintf (src, "    /*  this allows easier handling of nested CHOICEs */\n");
+        fprintf (src, "    tag = BDecTag (b, bytesDecoded, env);\n");
+        fprintf (src, "    elmtLen = BDecLen (b, bytesDecoded, env);\n");
+        fprintf (src, "    B%s (b, tag, elmtLen, bytesDecoded, env);\n", r->decodeContentBaseName);
+
+        /* grab any EOCs that match redundant, indef lengths */
+        for (i = elmtLevel; i > 0; i--)
+        {
+            fprintf (src, "    if (extraLen%d == INDEFINITE_LEN)\n", i);
+            fprintf (src, "        BDecEoc (b, bytesDecoded, env);\n");
+        }
+
+        fprintf (src, "}\n\n");
+    }
+    /* end of BDec function */
+
+    PrintPduMemberFcns (src, hdr, r, td->cxxTypeDefInfo->className);
+
+    /* ostream printing routine */
+    if (printPrintersG)
+    {
+        fprintf (hdr, "  void			Print (ostream &os) const;\n", td->cxxTypeDefInfo->className);
+
+        fprintf (src, "void %s::Print (ostream &os) const\n", td->cxxTypeDefInfo->className);
+        fprintf (src, "{\n");
+		#ifdef	__APPLE__
+		fprintf (src, "#ifndef NDEBUG\n");
+		#endif
+        /*    fprintf (src, "  os << \"{\" << endl;\n") */
+        fprintf (src, "  switch (choiceId)\n");
+        fprintf (src, "  {\n");
+        FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+        {
+            fprintf (src, "    case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol);
+
+            /* value notation so print the choice elmts field name */
+            if (e->fieldName != NULL)
+                fprintf (src, "      os << \"%s \";\n", e->fieldName);
+
+            if (e->type->cxxTypeRefInfo->isPtr)
+	    {
+                fprintf (src, "      if (%s)\n", e->type->cxxTypeRefInfo->fieldName);
+                fprintf (src, "        os << *%s;\n", e->type->cxxTypeRefInfo->fieldName);
+                fprintf (src, "      else\n");
+#ifdef KHO
+                fprintf (src, "        os << \"-- void3 --\\n\";\n", e->type->cxxTypeRefInfo->fieldName);
+#else
+                fprintf (src, "        os << \"-- void --\";\n", e->type->cxxTypeRefInfo->fieldName);
+#endif
+	    }
+            else
+                fprintf (src, "      os << %s;\n", e->type->cxxTypeRefInfo->fieldName);
+
+            fprintf (src, "      break;\n\n");
+        }
+        fprintf (src, "  } // end of switch\n");
+
+		#ifdef	__APPLE__
+		fprintf (src, "#endif /* NDEBUG */\n");
+		#endif
+        /*    fprintf (src, "  os << \"}\" << endl;\n") */
+        fprintf (src, "} // %s::Print\n\n", td->cxxTypeDefInfo->className);
+    }
+    /* end of Print Method code */
+
+    /* close class definition */
+    fprintf (hdr, "};\n\n\n");
+
+} /* PrintCxxChoiceDefCode */
+
+
+
+static void
+PrintCxxSeqDefCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, seq, novolatilefuncs),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    if_IBM_ENC (FILE *srcdb _AND_)
+    if_IBM_ENC (FILE *hdrdb _AND_)
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *seq _AND_
+    int novolatilefuncs)
+{
+    NamedType *e;
+    char *classStr;
+    char *formStr;
+    char *codeStr;
+    int tagLen, i;
+    Tag *tag;
+    TagList *tags;
+    char *varName;
+    CxxTRI *cxxtri;
+    int elmtLevel;
+    int varCount, tmpVarCount;
+    int stoleChoiceTags;
+    int inTailOptElmts;
+    enum BasicTypeChoiceId tmpTypeId;
+    NamedType *defByNamedType;
+    NamedType *tmpElmt;
+    int allOpt;
+
+#ifdef _IBM_ENC_
+#include "./ibm_editor/print_cxx_seq_def_code.h"
+#endif /* _IBM_ENC_ */
+
+    /* put class spec in hdr file */
+
+    fprintf (hdr, "class %s%s\n", td->cxxTypeDefInfo->className, baseClassesG);
+    fprintf (hdr, "{\n");
+    fprintf (hdr, "public:\n");
+
+    /* write out the sequence elmts */
+    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+    {
+        fprintf (hdr, "  ");
+        PrintCxxType (hdr, mods, m, r, td, seq, e->type);
+        fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName);
+    }
+
+    fprintf (hdr, "\n");
+
+#if META
+    if (printMetaG)
+    {
+	fprintf (hdr, "#if META\n");
+	fprintf (src, "#if META\n\n");
+
+	fprintf (hdr, "  static const AsnSequenceTypeDesc	_desc;\n");
+	fprintf (hdr, "  static const AsnSequenceMemberDesc	_mdescs[];\n");
+	fprintf (hdr, "  const AsnTypeDesc		*_getdesc() const;\n");
+	fprintf (hdr, "  AsnType			*_getref (const char *membername, bool create = false);\n\n");
+
+	fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  return new %s;\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "}\n\n");
+
+	fprintf (src, "const AsnSequenceMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+	    if (printMetaG == META_backend_names)
+		fprintf (src, "  AsnSequenceMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->fieldName ? e->fieldName : "");
+	    else /* META_asn1_names */
+		fprintf (src, "  AsnSequenceMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->type->cxxTypeRefInfo->fieldName);
+	fprintf (src, "  AsnSequenceMemberDesc()\n");
+	fprintf (src, "};\n\n");
+
+	fprintf (src, "const AsnSequenceTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "(\n");
+	fprintf (src, "  &%sModuleDesc,\n", m->cxxname);
+	if (printMetaG == META_backend_names)
+	    fprintf (src, "  \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName);
+	else /* META_asn1_names */
+	    fprintf (src, "  \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className);
+	fprintf (src, "  %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false");
+	fprintf (src, "  AsnTypeDesc::SEQUENCE,\n");
+	fprintf (src, "  create%s,\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "  _mdescs\n");
+	fprintf (src, ");\n\n");
+
+	fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  return &_desc;\n");
+	fprintf (src, "}\n\n");
+
+	fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+	{
+	    fprintf (src, "  if (!strcmp (membername, \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName);
+	    if (e->type->cxxTypeRefInfo->isPtr)
+	    {
+		fprintf (src, "  {\n");
+		fprintf (src, "    if (!%s && create)\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "      %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+		fprintf (src, "    return %s;\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "  }\n");
+	    }
+	    else
+		fprintf (src, "    return &%s;\n", e->type->cxxTypeRefInfo->fieldName);
+	}
+	fprintf (src, "  return NULL;\n");
+	fprintf (src, "}\n\n");
+
+#if TCL
+	if (printTclG)
+	{
+	    fprintf (hdr, "#if TCL\n");
+	    fprintf (src, "#if TCL\n\n");
+
+	    fprintf (hdr, "  int			TclGetDesc (Tcl_DString *) const;\n");
+	    fprintf (hdr, "  int			TclGetVal (Tcl_Interp *) const;\n");
+	    fprintf (hdr, "  int			TclSetVal (Tcl_Interp *, const char *valstr);\n");
+	    fprintf (hdr, "  int			TclUnsetVal (Tcl_Interp *, const char *membname);\n\n");
+
+	    fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Tcl_DStringStartSublist (valstr);\n\n");
+	    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+	    {
+		fprintf (src, "  Tcl_DStringStartSublist (valstr);\n");
+		fprintf (src, "  Tcl_DStringAppendElement (valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName);
+		if (e->type->cxxTypeRefInfo->isPtr)
+		    fprintf (src, "  Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName);
+		else
+		    fprintf (src, "  Tcl_DStringAppendElement (valstr, \"valid\");\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "  Tcl_DStringEndSublist (valstr);\n\n");
+	    }
+	    fprintf (src, "  Tcl_DStringEndSublist (valstr);\n\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Tcl_DString valstr;\n\n");
+	    fprintf (src, "  Tcl_DStringInit (&valstr);\n\n");
+	    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+	    {
+		if (e->type->cxxTypeRefInfo->isPtr)
+		{
+		    fprintf (src, "  if (%s)\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "  {\n");
+		    fprintf (src, "    Tcl_DStringStartSublist (&valstr);\n");
+		    fprintf (src, "    Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "    if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      goto Error;\n");
+		    fprintf (src, "    Tcl_DStringAppendElement (&valstr, interp->result);\n");
+		    fprintf (src, "    Tcl_ResetResult (interp);\n");
+		    fprintf (src, "    Tcl_DStringEndSublist (&valstr);\n");
+		    fprintf (src, "  }\n\n");
+		}
+		else
+		{
+		    fprintf (src, "  Tcl_DStringStartSublist (&valstr);\n");
+		    fprintf (src, "  Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "  if (%s.TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "    goto Error;\n");
+		    fprintf (src, "  Tcl_DStringAppendElement (&valstr, interp->result);\n");
+		    fprintf (src, "  Tcl_ResetResult (interp);\n");
+		    fprintf (src, "  Tcl_DStringEndSublist (&valstr);\n\n");
+		}
+	    }
+	    fprintf (src, "  Tcl_DStringResult (interp, &valstr);\n");
+	    fprintf (src, "  return TCL_OK;\n\n");
+	    fprintf (src, "Error:\n");
+	    fprintf (src, "  Tcl_DStringFree (&valstr);\n");
+	    fprintf (src, "  return TCL_ERROR;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  int i;\n");
+	    fprintf (src, "  Args elems;\n");
+	    fprintf (src, "  if (Tcl_SplitList (interp, (char*)valstr, &elems.c, &elems.v) != TCL_OK)\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "  Args* elempairs = new Args[elems.c];\n");
+	    fprintf (src, "  for (i=0; i<elems.c; i++)\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    if (Tcl_SplitList (interp, elems.v[i], &elempairs[i].c, &elempairs[i].v) != TCL_OK)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      delete elempairs;\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    if (elempairs[i].c != 2)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      sprintf (interp->result, \"syntax error in element #%%d: expected a pair, but it's got %%d element(s)\", i, elempairs[i].c);\n");
+	    fprintf (src, "      delete elempairs;\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  for (const AsnSequenceMemberDesc *m=_mdescs; m->name; m++)\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    int count = 0;\n");
+	    fprintf (src, "    for (i=0; i<elems.c; i++)\n");
+	    fprintf (src, "      if (!strcmp (elempairs[i].v[0], m->name))\n");
+	    fprintf (src, "        count++;\n");
+	    fprintf (src, "    if (count > 1)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      sprintf (interp->result, \"duplicate value for member \\\"%%s\\\" in list\", m->name);\n");
+	    fprintf (src, "      Tcl_SetErrorCode (interp, \"SNACC\", \"DUPMEMB\", NULL);\n");
+	    fprintf (src, "      delete elempairs;\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    if (!m->optional && count < 1)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      sprintf (interp->result, \"mandatory member \\\"%%s\\\" is missing in list\", m->name);\n");
+	    fprintf (src, "      Tcl_SetErrorCode (interp, \"SNACC\", \"MISSMAND\", NULL);\n");
+	    fprintf (src, "      delete elempairs;\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    \n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  for (i=0; i<elems.c; i++)\n");
+	    fprintf (src, "  {\n");
+	    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+	    {
+		fprintf (src, "    if (!strcmp (elempairs[i].v[0], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "    {\n");
+		if (e->type->cxxTypeRefInfo->isPtr)
+		{
+		    fprintf (src, "      if (!%s)\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "        %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+		    fprintf (src, "      if (%s->TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      {\n");
+		    fprintf (src, "        delete elempairs;\n");
+		    fprintf (src, "        return TCL_ERROR;\n");
+		    fprintf (src, "      }\n");
+		}
+		else
+		{
+		    fprintf (src, "      if (%s.TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      {\n");
+		    fprintf (src, "        delete elempairs;\n");
+		    fprintf (src, "        return TCL_ERROR;\n");
+		    fprintf (src, "      }\n");
+		}
+		fprintf (src, "    }\n");
+	    }
+	    fprintf (src, "  }\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  // look for unmentioned optional members and delete them:\n");
+	    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+	    {
+		if (e->type->optional || e->type->defaultVal)
+		{
+		    fprintf (src, "  {\n");
+		    fprintf (src, "    bool present = false;\n");
+		    fprintf (src, "    for (i=0; i<elems.c; i++)\n");
+		    fprintf (src, "      if (!strcmp (elempairs[i].v[0], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "        present = true;\n");
+		    fprintf (src, "    if (!present)\n");
+		    fprintf (src, "    {\n");
+		    fprintf (src, "      delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "    }\n");
+		    fprintf (src, "  }\n");
+		}
+	    }
+	    fprintf (src, "\n");
+	    fprintf (src, "  delete elempairs;\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclUnsetVal (Tcl_Interp *interp, const char *membernames)\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Args elems;\n");
+	    fprintf (src, "  if (Tcl_SplitList (interp, (char*)membernames, &elems.c, &elems.v) != TCL_OK)\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  for (int i=0; i<elems.c; i++)\n");
+	    fprintf (src, "  {\n");
+	    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+	    {
+		fprintf (src, "    if (!strcmp (elems.v[i], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "    {\n");
+		if (e->type->optional || e->type->defaultVal)
+		{
+		    fprintf (src, "        delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "        %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+		}
+		else
+		{
+		    fprintf (src, "        return _desc.mandatmemberr (interp, elems.v[i]);\n");
+		}
+		fprintf (src, "    }\n");
+	    }
+	    fprintf (src, "  }\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (hdr, "#endif // TCL\n");
+	    fprintf (src, "#endif // TCL\n\n");
+	}
+#endif /* TCL */
+
+	fprintf (hdr, "#endif // META\n\n");
+	fprintf (src, "#endif // META\n\n");
+    }
+#endif /* META */
+
+    /* constructors and destructor: */
+
+    fprintf (hdr, "			%s();\n", td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+    {
+	if (e->type->cxxTypeRefInfo->isPtr)
+	    if (e->type->optional || e->type->defaultVal)
+		fprintf (src, "  %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+	    else
+	    {
+		fprintf (src, "#if TCL\n");
+		fprintf (src, "  %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+		fprintf (src, "#else\n");
+		fprintf (src, "  %s = NULL; // incomplete initialization of mandatory element!\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "#endif // TCL\n");
+	    }
+    }
+    fprintf (src, "}\n\n");
+
+    fprintf (hdr, "			%s (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::%s (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    fprintf (src, "  Asn1Error << \"use of incompletely defined %s::%s (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "  abort();\n");
+    fprintf (src, "}\n\n");
+
+    fprintf (hdr, "  virtual		~%s();\n", td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::~%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+	if (e->type->cxxTypeRefInfo->isPtr)
+	    fprintf (src, "  delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+    fprintf (src, "}\n\n");
+
+    /* print clone routine for ANY mgmt */
+    PrintCloneMethod (hdr, src, td);
+
+    fprintf (hdr, "  %s		&operator = (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+
+    fprintf (src, "#if SNACC_DEEP_COPY\n");
+    fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "#else // SNACC_DEEP_COPY\n");
+    fprintf (src, "%s &%s::operator = (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "#endif // SNACC_DEEP_COPY\n");
+    fprintf (src, "{\n");
+    fprintf (src, "#if SNACC_DEEP_COPY\n");
+    fprintf (src, "  if (this != &that)\n");
+    fprintf (src, "  {\n");
+    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+    {
+	if (e->type->cxxTypeRefInfo->isPtr)
+	{
+	    fprintf (src, "    if (that.%s)\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      if (!%s)\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "        %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+	    fprintf (src, "      *%s = *that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    else\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "      %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "    }\n");
+	}
+	else
+	    fprintf (src, "    %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName);
+    }
+    fprintf (src, "  }\n");
+    fprintf (src, "\n");
+    fprintf (src, "  return *this;\n");
+    fprintf (src, "#else // SNACC_DEEP_COPY\n");
+    fprintf (src, "  Asn1Error << \"use of incompletely defined %s &%s::operator = (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "  abort();\n");
+    fprintf (src, "  // if your compiler complains here, check the -novolat option\n");
+    if (novolatilefuncs)
+    {
+      fprintf (src, "  return *this;\n");
+    }
+    fprintf (src, "#endif // SNACC_DEEP_COPY\n");
+    fprintf (src, "}\n\n");
+
+    /* BerEncodeContent method */
+    if (printEncodersG)
+    {
+        fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG);
+
+        fprintf (src, "%s\n", lenTypeNameG);
+        fprintf (src, "%s::B%s (%s b)\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG);
+
+        fprintf (src, "{\n");
+
+        /* print local vars */
+        fprintf (src, "  %s totalLen = 0;\n", lenTypeNameG);
+        fprintf (src, "  %s l;\n\n", lenTypeNameG);
+
+        FOR_EACH_LIST_ELMT_RVS (e, seq->basicType->a.sequence)
+        {
+            cxxtri =  e->type->cxxTypeRefInfo;
+
+            varName = cxxtri->fieldName;
+
+            /* print optional test if nec */
+            if (e->type->optional || (e->type->defaultVal != NULL))
+	    {
+                fprintf (src, "  if (%s (%s))\n", cxxtri->optTestRoutineName, varName);
+                fprintf (src, "  {\n");
+	    }
+
+            /* encode Eoc (s) if nec */
+            PrintCxxEocEncoders (src, td, e->type, "b");
+
+            /* encode content */
+            tmpTypeId = GetBuiltinType (e->type);
+            if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+            {
+                fprintf (src, "    %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+
+                defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+                if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID)
+                {
+                    fprintf (src, "SetTypeByOid (");
+                    if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                        fprintf (src, " *");
+                    fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                }
+                else
+                {
+                    fprintf (src, "SetTypeByInt (");
+                    if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                        fprintf (src, " *");
+                    fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                }
+
+                fprintf (src, "    l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "B%s (b);\n", r->encodeBaseName);
+            }
+            else if (tmpTypeId == BASICTYPE_ANY)
+            {
+#ifdef VDADER_RULES
+if (! gVDADER_RULES)
+{
+#endif
+                fprintf (src, "    %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "SetTypeBy???(???);\n");
+
+                fprintf (src, "    l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "B%s (b);\n", r->encodeBaseName);
+
+#ifdef VDADER_RULES
+}
+else
+                {
+                    fprintf (src, "        ENC_LOAD_ANYBUF(");
+                    if (!cxxtri->isPtr)
+                      fprintf (src, "&");
+                    fprintf (src, "%s, b, l);\n", varName);
+                }
+#endif
+            }
+            else
+            {
+                fprintf (src, "    l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+
+                fprintf (src, "B%s (b);\n", r->encodeContentBaseName);
+            }
+
+
+            /* encode tag (s) & len (s) */
+            PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "b");
+
+
+            fprintf (src, "    totalLen += l;\n");
+
+            /* close optional test if nec */
+            if (e->type->optional || (e->type->defaultVal != NULL))
+                fprintf (src, "  }\n\n");
+            else
+                fprintf (src, "\n");
+        }
+        fprintf (src, "  return totalLen;\n");
+        fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName);
+    }
+    /* end of BerEncodeContent method printing code */
+
+    /* write BerDecodeContent to src */
+    if (printDecodersG)
+    {
+        fprintf (hdr, "  void			B%s (%s b, %s tag, %s elmtLen, %s &bytesDecoded, %s env);\n\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "void %s::B%s (%s b, %s /*tag0*/, %s elmtLen0, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "{\n");
+
+        /* print local vars */
+        fprintf (src, "  %s tag1;\n", tagTypeNameG);
+        fprintf (src, "  %s seqBytesDecoded = 0;\n", lenTypeNameG);
+        /* count max number of extra length var nec */
+        varCount = 0;
+        FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+        {
+            tmpVarCount = CxxCountVariableLevels (e->type);
+
+            if (tmpVarCount > varCount)
+                varCount = tmpVarCount;
+        }
+        /* write extra length vars */
+        for (i = 1; i <= varCount; i++)
+            fprintf (src, "  %s elmtLen%d;\n", lenTypeNameG, i);
+
+        /* handle empty seq */
+        if ((seq->basicType->a.sequence == NULL) || LIST_EMPTY (seq->basicType->a.sequence))
+        {
+            fprintf (src, "  if (elmtLen0 == INDEFINITE_LEN)\n");
+            fprintf (src, "    BDecEoc (b, bytesDecoded, env);\n");
+            fprintf (src, "  else if (elmtLen0 != 0)\n");
+            fprintf (src, "  {\n");
+            fprintf (src, "     Asn1Error << \"Expected an empty sequence\" << endl;\n");
+            fprintf (src, "     longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "  }\n");
+
+/*
+            forget about posssible extensions to the type
+            fprintf (src, "  {\n");
+            fprintf (src, "    tag1 = BDecTag (b, bytesDecoded, env);\n\n");
+            fprintf (src, "    if (tag1 == EOC_TAG_ID)\n");
+            fprintf (src, "      BDEC_2ND_EOC_OCTET (b, bytesDecoded, env)\n");
+            fprintf (src, "    else\n");
+
+            fprintf (src, "      BerDiscardElmt (b, bytesDecoded, env);\n\n");
+            fprintf (src, "  }\n");
+            fprintf (src, "  else\n");
+            fprintf (src, "  {\n");
+            fprintf (src, "    BufSkip (b, elmtLen0);\n");
+            fprintf (src, "    bytesDecoded%d += elmtLen0;\n");
+            fprintf (src, "  }\n");
+*/
+        }
+        else
+        {
+            /*  check if all elmts are optional */
+            AsnListFirst (seq->basicType->a.sequence);
+            inTailOptElmts = IsTailOptional (seq->basicType->a.sequence);
+            e = (NamedType*)FIRST_LIST_ELMT (seq->basicType->a.sequence);
+
+            tmpTypeId = GetBuiltinType (e->type);
+
+            if (!inTailOptElmts)
+            {
+                if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (e->type) == 0))
+                {
+                    if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence)))
+                        fprintf (src, "<untagged optional ANY - you must fix this>\n");
+                }
+                else
+                    fprintf (src, "  tag1 = BDecTag (b, seqBytesDecoded, env);\n\n");
+            }
+            else
+            {
+                fprintf (src, "  if (elmtLen0 == 0)\n");
+                fprintf (src, "    return;\n");
+                fprintf (src, "  else\n");
+                fprintf (src, "  {\n");
+                if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (e->type) == 0))
+                {
+                    if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence)))
+                        fprintf (src, "<untagged optional ANY - you must fix this>\n");
+                }
+                else
+                    fprintf (src, "    tag1 = BDecTag (b, seqBytesDecoded, env);\n\n");
+                fprintf (src, "    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n");
+                fprintf (src, "    {\n");
+                fprintf (src, "      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)\n");
+                fprintf (src, "      bytesDecoded += seqBytesDecoded;\n");
+                fprintf (src, "      return;\n");
+                fprintf (src, "    }\n");
+                fprintf (src, "  }\n\n");
+            }
+
+
+            FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+            {
+                cxxtri =  e->type->cxxTypeRefInfo;
+                elmtLevel = 0;
+
+                tags = GetTags (e->type, &stoleChoiceTags);
+
+                /*            if (inTailOptElmts)
+                              fprintf (src, " (!seqDone) && ");
+                              */
+                if (LIST_EMPTY (tags))
+                    fprintf (src, "  // ANY type\n");
+                else
+                {
+                    tag = (Tag*)FIRST_LIST_ELMT (tags);
+                    classStr = Class2ClassStr (tag->tclass);
+                    codeStr = Code2UnivCodeStr (tag->code);
+                    formStr = Form2FormStr (tag->form);
+
+                    fprintf (src, "  if (");
+                    if (tag->tclass == UNIV)
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr);
+                            fprintf (src, "    || (tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, Form2FormStr (CONS), codeStr);
+                        }
+                        else
+                            fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, codeStr);
+                    }
+                    else
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code);
+                            fprintf (src, "    || (tag1 == MAKE_TAG_ID (%s, %s, %d))", classStr, Form2FormStr (CONS), tag->code);
+                        }
+                        else
+                            fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code);
+                    }
+
+
+                    /* now decode extra tags/length pairs */
+                    AsnListFirst (tags);
+                    AsnListNext (tags);
+                    if (stoleChoiceTags)
+                    {
+                        FOR_REST_LIST_ELMT (tag, tags)
+                        {
+                            fprintf (src, "\n    || ");
+                            classStr = Class2ClassStr (tag->tclass);
+                            codeStr = Code2UnivCodeStr (tag->code);
+                            formStr = Form2FormStr (tag->form);
+
+                            if (tag->tclass == UNIV)
+                            {
+                                if (tag->form == ANY_FORM)
+                                {
+                                    fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr);
+                                    fprintf (src, "    || (tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, Form2FormStr (CONS), codeStr);
+                                }
+                                else
+                                    fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, codeStr);
+                            }
+                            else
+                            {
+                                if (tag->form == ANY_FORM)
+                                {
+                                    fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code);
+                                    fprintf (src, "    || (tag1 == MAKE_TAG_ID (%s, %s, %d))", classStr, Form2FormStr (CONS), tag->code);
+                                }
+                                else
+                                    fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code);
+                            }
+                        }
+                        fprintf (src, ")\n");
+                        fprintf (src, "  {\n");
+                        fprintf (src, "    elmtLen%d = BDecLen (b, seqBytesDecoded, env);\n", ++elmtLevel);
+                    }
+
+                    else /* didn't steal nested choice's tags */
+                    {
+                        fprintf (src, ")\n");
+                        fprintf (src, "  {\n");
+                        fprintf (src, "    elmtLen%d = BDecLen (b, seqBytesDecoded, env);\n", ++elmtLevel);
+
+                        FOR_REST_LIST_ELMT (tag, tags)
+                        {
+                            classStr = Class2ClassStr (tag->tclass);
+                            codeStr = Code2UnivCodeStr (tag->code);
+                            formStr = Form2FormStr (tag->form);
+
+                            fprintf (src, "    tag1 = BDecTag (b, seqBytesDecoded, env);\n\n");
+                            if (tag->tclass == UNIV)
+                            {
+                                if (tag->form == ANY_FORM)
+                                {
+                                    fprintf (src, "    if ((tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr);
+                                    fprintf (src, "       && (tag1 != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr);
+                                }
+                                else
+                                    fprintf (src, "    if (tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr);
+                            }
+                            else
+                            {
+                                if (tag->form == ANY_FORM)
+                                {
+                                    fprintf (src, "    if ((tag1 != MAKE_TAG_ID (%s, %s, %d))\n",  classStr, Form2FormStr (PRIM), tag->code);
+                                    fprintf (src, "      && (tag1 != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code);
+                                }
+                                else
+                                    fprintf (src, "    if (tag1 != MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code);
+                            }
+
+                            fprintf (src, "    {\n");
+                            fprintf (src, "       Asn1Error << \"Unexpected Tag\" << endl;\n");
+                            fprintf (src, "       longjmp (env, %d);\n", longJmpValG--);
+                            fprintf (src, "    }\n\n");
+                            fprintf (src, "    elmtLen%d = BDecLen (b, seqBytesDecoded, env);\n", ++elmtLevel);
+                        }
+                    }
+                }
+                /*
+                 * if this seq element is CHOICE &&
+                 * we didn't steal its tags then we must grab
+                 * the key tag out of the contained CHOICE
+                 */
+                if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE))
+                {
+                    fprintf (src, "    tag1 = BDecTag (b, seqBytesDecoded, env);\n");
+                    fprintf (src, "    elmtLen%d = BDecLen (b, seqBytesDecoded, env);\n", ++elmtLevel);
+                }
+
+
+
+                varName = cxxtri->fieldName;
+
+                /* decode content */
+                if (cxxtri->isPtr)
+                    fprintf (src, "    %s = new %s;\n", varName, cxxtri->className);
+
+
+                /* decode content */
+                tmpTypeId = GetBuiltinType (e->type);
+                if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+                {
+                    /*
+                     * must check for another EOC for ANYs
+                     * since the any decode routines decode
+                     * their own first tag/len pair
+                     */
+                    elmtLevel++;
+                    fprintf (src, "    %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+
+                    defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+                    if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID)
+                    {
+                        fprintf (src, "SetTypeByOid (");
+                        if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                            fprintf (src, " *");
+                        fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                    }
+                    else
+                    {
+                        fprintf (src, "SetTypeByInt (");
+                        if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                            fprintf (src, " *");
+                        fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                    }
+
+                    fprintf (src, "    %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+                    fprintf (src, "B%s (b, seqBytesDecoded, env);\n",  r->decodeBaseName);
+                }
+                else if (tmpTypeId == BASICTYPE_ANY)
+                {
+                    /*
+                     * must check for another EOC for ANYs
+                     * since the any decode routines decode
+                     * their own first tag/len pair
+                     */
+                    elmtLevel++;
+
+#ifdef VDADER_RULES
+if (! gVDADER_RULES)
+{
+#endif
+                    fprintf (src, "    %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+                    fprintf (src, "SetTypeBy???(???);\n");
+
+                    fprintf (src, "    %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+                    fprintf (src, "B%s (b, seqBytesDecoded, env);\n",  r->decodeBaseName);
+
+#ifdef VDADER_RULES
+}
+else
+                  {
+                    fprintf (src, "        DEC_LOAD_ANYBUF(");
+                    if (!cxxtri->isPtr)
+                      fprintf (src, "&");
+                    fprintf (src, "%s, b, seqBytesDecoded, env);\n", varName);
+                  }
+#endif
+                }
+                else
+                {
+                    fprintf (src, "    %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+
+                    fprintf (src, "B%s (b, tag1, elmtLen%d, seqBytesDecoded, env);\n",  r->decodeContentBaseName, elmtLevel);
+                }
+
+                /* decode Eoc (s) */
+                for (i = elmtLevel-1; i > 0; i--)
+                {
+                    fprintf (src, "    if (elmtLen%d == INDEFINITE_LEN)\n", i);
+                    fprintf (src, "      BDecEoc (b, seqBytesDecoded, env);\n\n");
+                }
+
+                /*
+                 * print code for getting the next tag
+                 */
+                inTailOptElmts = RestAreTailOptional (seq->basicType->a.sequence);
+                if  (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence))
+                {
+                    tmpElmt = (NamedType*)NEXT_LIST_ELMT (seq->basicType->a.sequence);
+                    tmpTypeId = GetBuiltinType (tmpElmt->type);
+                    if (!inTailOptElmts)
+                    {
+                        if ((tmpTypeId == BASICTYPE_ANY || tmpTypeId == BASICTYPE_ANYDEFINEDBY) && CountTags (tmpElmt->type) == 0)
+                        {
+                            /* don't get a tag since ANY's decode their own */
+                            if (e->type->optional || (tmpElmt->type->optional && tmpElmt != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence)))
+                                /* let this cause a compile error in the generated code */
+                                fprintf (src, "  <problems with untagged ANY that is optional or follows an optional sequence element - you must fix this>\n");
+                        }
+                        else
+                            fprintf (src, "    tag1 = BDecTag (b, seqBytesDecoded, env);\n");
+                    }
+                    else
+                    {
+                        fprintf (src, "    if (seqBytesDecoded == elmtLen0)\n");
+                        fprintf (src, "    {\n");
+                        fprintf (src, "      bytesDecoded += seqBytesDecoded;\n");
+                        fprintf (src, "      return;\n");
+                        fprintf (src, "    }\n");
+                        fprintf (src, "    else\n");
+                        fprintf (src, "    {\n");
+
+                        if ((tmpTypeId == BASICTYPE_ANY || tmpTypeId == BASICTYPE_ANYDEFINEDBY) && !CountTags (tmpElmt->type))
+                        {
+                            /* don't get a tag since ANY's decode their own */
+                            if (e->type->optional || (tmpElmt->type->optional && tmpElmt != (NamedType *)LAST_LIST_ELMT (seq->basicType->a.sequence)))
+                            {
+                                /*
+                                 * let this cause a compile error in the generated code
+                                 */
+                                fprintf (src, "  <problems with untagged ANY that is optional or follows an optional sequence element - you must fix this>\n");
+                            }
+                            fprintf (src, "      tag1 = b.PeekByte();\n\n");
+                            fprintf (src, "      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n");
+                            fprintf (src, "      {\n");
+                            fprintf (src, "        BDecEoc (b, seqBytesDecoded, env);\n\n");
+                            fprintf (src, "        bytesDecoded += seqBytesDecoded;\n");
+                            fprintf (src, "        return;\n");
+                            fprintf (src, "      }\n");
+
+                        }
+                        else
+                        {
+                            fprintf (src, "      tag1 = BDecTag (b, seqBytesDecoded, env);\n\n");
+                            fprintf (src, "      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n");
+                            fprintf (src, "      {\n");
+                            fprintf (src, "        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)\n");
+                            fprintf (src, "        bytesDecoded += seqBytesDecoded;\n");
+                            fprintf (src, "        return;\n");
+                            fprintf (src, "      }\n");
+                        }
+                        fprintf (src, "    }\n");
+
+                    }
+                }
+
+
+                /*
+                 * close tag check if (if there is one) and
+                 * print else clause to handle missing non-optional elmt
+                 * errors
+                 */
+                tmpTypeId = GetBuiltinType (e->type);
+                if ((tmpTypeId == BASICTYPE_ANYDEFINEDBY || tmpTypeId == BASICTYPE_ANY) && !CountTags (e->type))
+                {
+                    /* do nothing - no tag check if stmt to close */
+                    fprintf (src, "\n\n");
+                }
+                else if (!e->type->optional && !e->type->defaultVal)
+                {
+                    fprintf (src, "  }\n"); /* end of tag check if */
+                    fprintf (src, "  else\n");
+                    fprintf (src, "  {\n");
+                    fprintf (src, "    Asn1Error << \"ERROR - SEQUENCE is missing non-optional elmt.\" << endl;\n");
+                    fprintf (src, "    longjmp (env, %d);\n", longJmpValG--);
+                    fprintf (src, "  }\n\n");
+                }
+                else
+                    fprintf (src, "  }\n\n"); /* end of tag check if */
+
+                FreeTags (tags);
+            }
+
+            /* for last elmt only */
+            fprintf (src, "  bytesDecoded += seqBytesDecoded;\n");
+            fprintf (src, "  if (elmtLen0 == INDEFINITE_LEN)\n");
+            fprintf (src, "  {\n");
+            fprintf (src, "    BDecEoc (b, bytesDecoded, env);\n");
+            fprintf (src, "    return;\n");
+            fprintf (src, "  }\n");
+            fprintf (src, "  else if (seqBytesDecoded != elmtLen0)\n");
+            fprintf (src, "  {\n");
+            fprintf (src, "    Asn1Error << \"ERROR - Length discrepancy on sequence.\" << endl;\n");
+            fprintf (src, "    longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "  }\n");
+            fprintf (src, "  else\n");
+            fprintf (src, "    return;\n");
+
+        } /* end of non-empty set else clause */
+
+        fprintf (src, "} // %s::B%s\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName);
+    }
+    /* end of code for printing ber decode content method */
+
+    /* do BEnc function */
+    if (printEncodersG)
+    {
+        fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG);
+
+        fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName,  bufTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "  %s l;\n", lenTypeNameG);
+        fprintf (src, "  l = B%s (b);\n", r->encodeContentBaseName);
+
+        /* encode each tag/len pair if any */
+        FOR_EACH_LIST_ELMT_RVS (tag, seq->tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            formStr = Form2FormStr (CONS);  /* seq's are constructed */
+            tagLen = TagByteLen (tag->code);
+
+            fprintf (src, "  l += BEncConsLen (b, l);\n");
+
+            if (tag->tclass == UNIV)
+                fprintf (src, "  l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src, "  l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code);
+        }
+        fprintf (src, "  return l;\n");
+        fprintf (src, "}\n\n");
+    }
+    /* end of BEnc function */
+
+    /* Do BDec function */
+    if (printDecodersG)
+    {
+        fprintf (hdr, "  void			B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName,  bufTypeNameG, lenTypeNameG, envTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "  %s tag;\n", tagTypeNameG);
+
+        /* print extra locals for redundant lengths */
+        for (i = 1; (seq->tags != NULL) && (i <= LIST_COUNT (seq->tags)); i++)
+            fprintf (src, "  %s elmtLen%d;\n", lenTypeNameG, i);
+        fprintf (src, "\n");
+
+        /*  decode tag/length pair (s) */
+        elmtLevel = 0;
+        FOR_EACH_LIST_ELMT (tag, seq->tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            formStr = Form2FormStr (CONS);  /* seqs are constructed */
+
+            fprintf (src, "  if ((tag = BDecTag (b, bytesDecoded, env)) != ");
+
+            if (tag->tclass == UNIV)
+                fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src, "MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code);
+            fprintf (src, "  {\n");
+	    fprintf (src, "    Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName);
+            fprintf (src, "    longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "  }\n");
+
+            fprintf (src, "  elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+        }
+
+        fprintf (src, "  B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel);
+
+        /* grab any EOCs that match redundant, indef lengths */
+        for (i = elmtLevel-1; i > 0; i--)
+        {
+            fprintf (src, "  if (elmtLen%d == INDEFINITE_LEN)\n", i);
+            fprintf (src, "    BDecEoc (b, bytesDecoded, env);\n");
+        }
+
+        fprintf (src, "}\n\n");
+    }
+    /* end of BDec function */
+
+    PrintPduMemberFcns (src, hdr, r, td->cxxTypeDefInfo->className);
+
+    /* write code for printing */
+    if (printPrintersG)
+    {
+        fprintf (hdr, "  void		Print (ostream &os) const;\n");
+
+        fprintf (src, "void %s::Print (ostream &os) const\n", td->cxxTypeDefInfo->className);
+        fprintf (src, "{\n");
+		#ifdef	__APPLE__
+		fprintf (src, "#ifndef NDEBUG\n");
+		#endif
+        allOpt = AllElmtsOptional (seq->basicType->a.sequence);
+        if (allOpt)
+            fprintf (src, "  int nonePrinted = true;\n");
+        fprintf (src, "  os << \"{ -- SEQUENCE --\" << endl;\n");
+        fprintf (src, "  indentG += stdIndentG;\n\n");
+
+        FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+        {
+            inTailOptElmts = IsTailOptional (seq->basicType->a.sequence);
+
+            if (e->type->cxxTypeRefInfo->isPtr)
+                fprintf (src, "  if (%s (%s))\n", cxxtri->optTestRoutineName, e->type->cxxTypeRefInfo->fieldName);
+
+	    fprintf (src, "  {\n");
+
+            if (allOpt)
+            {
+                if (e != FIRST_LIST_ELMT (seq->basicType->a.sequence))
+                {
+                    fprintf (src, "    if (!nonePrinted)\n");
+                    fprintf (src, "      os << \",\" << endl;\n");
+                }
+                fprintf (src, "    nonePrinted = false;\n", i);
+            }
+            else if (inTailOptElmts) /* cannot be first elmt ow allOpt is true */
+                fprintf (src, "    os << \",\"<< endl;\n");
+
+            fprintf (src, "    Indent (os, indentG);\n");
+
+            if (e->fieldName != NULL)
+                fprintf (src, "    os << \"%s \";\n", e->fieldName);
+
+            if (e->type->cxxTypeRefInfo->isPtr)
+                fprintf (src, "    os << *%s;\n", e->type->cxxTypeRefInfo->fieldName);
+            else
+                fprintf (src, "    os << %s;\n", e->type->cxxTypeRefInfo->fieldName);
+
+#ifdef KHO
+            if (e != LAST_LIST_ELMT (seq->basicType->a.sequence)&&(!e->type->cxxTypeRefInfo->isPtr) )
+                fprintf (src, "    os << \",\" << endl;\n");
+#else
+            if (e != LAST_LIST_ELMT (seq->basicType->a.sequence) && !inTailOptElmts && !NextIsTailOptional (seq->basicType->a.sequence))
+                fprintf (src, "    os << \",\" << endl;\n");
+#endif
+
+	    fprintf (src, "  }\n");
+
+            if (e->type->cxxTypeRefInfo->isPtr)
+	    {
+		fprintf (src, "  else\n");
+#ifdef KHO
+                fprintf (src, "  {\n");
+                fprintf (src, "    Indent (os, indentG);\n");
+                if (e->fieldName != NULL)
+                  fprintf (src, "    os << \"%s \";\n", e->fieldName);
+		fprintf (src, "    os << \"-- void --\";\n");
+    		if (e != LAST_LIST_ELMT (seq->basicType->a.sequence))
+                   fprintf (src, "    os << \",\" << endl;\n");
+                else
+                   fprintf (src, "    os << endl;\n");
+		fprintf (src, "  }\n");
+#else
+		fprintf (src, "    os << \"-- void --\";\n");
+#endif
+	    }
+
+	    fprintf (src, "\n");
+
+            if (e == LAST_LIST_ELMT (seq->basicType->a.sequence))
+                fprintf (src, "  os << endl;\n");
+        }
+
+        fprintf (src, "  indentG -= stdIndentG;\n");
+        fprintf (src, "  Indent (os, indentG);\n");
+        fprintf (src, "  os << \"}\";\n");
+ 		#ifdef	__APPLE__
+		fprintf (src, "#endif /* NDEBUG */\n");
+		#endif
+       fprintf (src, "} // %s::Print\n\n\n", td->cxxTypeDefInfo->className);
+    }
+    /* end of print method code printer */
+
+    /* close class definition */
+    fprintf (hdr, "};\n\n\n");
+
+} /* PrintCxxSeqDefCode */
+
+
+static void
+PrintCxxSetDefCode PARAMS ((src, hdr, mods, m, r, td, parent, set, novolatilefuncs),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *set _AND_
+    int novolatilefuncs)
+{
+    NamedType *e;
+    char *classStr;
+    char *formStr;
+    char *codeStr;
+    int tagLen, i;
+    Tag *tag;
+    TagList *tags;
+    char *varName;
+    CxxTRI *cxxtri;
+    int elmtLevel;
+    int varCount, tmpVarCount;
+    int stoleChoiceTags;
+    int inTailOptElmts;
+    int mandatoryElmtCount;
+    enum BasicTypeChoiceId tmpTypeId;
+    NamedType *defByNamedType;
+    int allOpt;
+
+    /* put class spec in hdr file */
+
+    fprintf (hdr, "class %s%s\n", td->cxxTypeDefInfo->className, baseClassesG);
+    fprintf (hdr, "{\n");
+    fprintf (hdr, "public:\n");
+
+    /* write out the set elmts */
+    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+    {
+        fprintf (hdr, "  ");
+        PrintCxxType (hdr, mods, m, r, td, set, e->type);
+        fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName);
+    }
+
+    fprintf (hdr, "\n");
+
+#if META
+    if (printMetaG)
+    {
+	fprintf (hdr, "#if META\n");
+	fprintf (src, "#if META\n\n");
+
+	fprintf (hdr, "  static const AsnSetTypeDesc	_desc;\n");
+	fprintf (hdr, "  static const AsnSetMemberDesc	_mdescs[];\n");
+	fprintf (hdr, "  const AsnTypeDesc		*_getdesc() const;\n");
+	fprintf (hdr, "  AsnType			*_getref (const char *membername, bool create = false);\n\n");
+
+	fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  return new %s;\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "}\n\n");
+
+	fprintf (src, "const AsnSetMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+	    if (printMetaG == META_backend_names)
+		fprintf (src, "  AsnSetMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->fieldName ? e->fieldName : "");
+	    else /* META_asn1_names */
+		fprintf (src, "  AsnSetMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->type->cxxTypeRefInfo->fieldName);
+	fprintf (src, "  AsnSetMemberDesc()\n");
+	fprintf (src, "};\n\n");
+
+	fprintf (src, "const AsnSetTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "(\n");
+	fprintf (src, "  &%sModuleDesc,\n", m->cxxname);
+	if (printMetaG == META_backend_names)
+	    fprintf (src, "  \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName);
+	else /* META_asn1_names */
+	    fprintf (src, "  \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className);
+	fprintf (src, "  %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false");
+	fprintf (src, "  AsnTypeDesc::SET,\n");
+	fprintf (src, "  create%s,\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "  _mdescs\n");
+	fprintf (src, ");\n\n");
+
+	fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  return &_desc;\n");
+	fprintf (src, "}\n\n");
+
+	fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+	{
+	    fprintf (src, "  if (!strcmp (membername, \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName);
+	    if (e->type->cxxTypeRefInfo->isPtr)
+	    {
+		fprintf (src, "  {\n");
+		fprintf (src, "    if (!%s && create)\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "      %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+		fprintf (src, "    return %s;\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "  }\n");
+	    }
+	    else
+		fprintf (src, "    return &%s;\n", e->type->cxxTypeRefInfo->fieldName);
+	}
+	fprintf (src, "  return NULL;\n");
+	fprintf (src, "}\n\n");
+
+#if TCL
+	if (printTclG)
+	{
+	    fprintf (hdr, "#if TCL\n");
+	    fprintf (src, "#if TCL\n\n");
+
+	    fprintf (hdr, "  int			TclGetDesc (Tcl_DString *) const;\n");
+	    fprintf (hdr, "  int			TclGetVal (Tcl_Interp *) const;\n");
+	    fprintf (hdr, "  int			TclSetVal (Tcl_Interp *, const char *valstr);\n");
+	    fprintf (hdr, "  int			TclUnsetVal (Tcl_Interp *, const char *membernames);\n\n");
+
+	    fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Tcl_DStringStartSublist (valstr);\n\n");
+	    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+	    {
+		fprintf (src, "  Tcl_DStringStartSublist (valstr);\n");
+		fprintf (src, "  Tcl_DStringAppendElement (valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName);
+		if (e->type->cxxTypeRefInfo->isPtr)
+		    fprintf (src, "  Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName);
+		else
+		    fprintf (src, "  Tcl_DStringAppendElement (valstr, \"valid\");\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "  Tcl_DStringEndSublist (valstr);\n\n");
+	    }
+	    fprintf (src, "  Tcl_DStringEndSublist (valstr);\n\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Tcl_DString valstr;\n\n");
+	    fprintf (src, "  Tcl_DStringInit (&valstr);\n\n");
+	    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+	    {
+		if (e->type->cxxTypeRefInfo->isPtr)
+		{
+		    fprintf (src, "  if (%s)\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "  {\n");
+		    fprintf (src, "    Tcl_DStringStartSublist (&valstr);\n");
+		    fprintf (src, "    Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "    if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      goto Error;\n");
+		    fprintf (src, "    Tcl_DStringAppendElement (&valstr, interp->result);\n");
+		    fprintf (src, "    Tcl_ResetResult (interp);\n");
+		    fprintf (src, "    Tcl_DStringEndSublist (&valstr);\n");
+		    fprintf (src, "  }\n\n");
+		}
+		else
+		{
+		    fprintf (src, "  Tcl_DStringStartSublist (&valstr);\n");
+		    fprintf (src, "  Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "  if (%s.TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "    goto Error;\n");
+		    fprintf (src, "  Tcl_DStringAppendElement (&valstr, interp->result);\n");
+		    fprintf (src, "  Tcl_ResetResult (interp);\n");
+		    fprintf (src, "  Tcl_DStringEndSublist (&valstr);\n\n");
+		}
+	    }
+	    fprintf (src, "  Tcl_DStringResult (interp, &valstr);\n");
+	    fprintf (src, "  return TCL_OK;\n\n");
+	    fprintf (src, "Error:\n");
+	    fprintf (src, "  Tcl_DStringFree (&valstr);\n");
+	    fprintf (src, "  return TCL_ERROR;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  int i;\n");
+	    fprintf (src, "  Args elems;\n");
+	    fprintf (src, "  if (Tcl_SplitList (interp, (char*)valstr, &elems.c, &elems.v) != TCL_OK)\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "  Args* elempairs = new Args[elems.c];\n");
+	    fprintf (src, "  for (i=0; i<elems.c; i++)\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    if (Tcl_SplitList (interp, elems.v[i], &elempairs[i].c, &elempairs[i].v) != TCL_OK)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      delete elempairs;\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    if (elempairs[i].c != 2)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      sprintf (interp->result, \"syntax error in element #%%d: expected a pair, but it's got %%d element(s)\", i, elempairs[i].c);\n");
+	    fprintf (src, "      delete elempairs;\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  for (const AsnSetMemberDesc *m=_mdescs; m->name; m++)\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    int count = 0;\n");
+	    fprintf (src, "    for (i=0; i<elems.c; i++)\n");
+	    fprintf (src, "      if (!strcmp (elempairs[i].v[0], m->name))\n");
+	    fprintf (src, "        count++;\n");
+	    fprintf (src, "    if (count > 1)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      sprintf (interp->result, \"duplicate value for member \\\"%%s\\\" in list\", m->name);\n");
+	    fprintf (src, "      Tcl_SetErrorCode (interp, \"SNACC\", \"DUPMEMB\", NULL);\n");
+	    fprintf (src, "      delete elempairs;\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    if (!m->optional && count < 1)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      sprintf (interp->result, \"mandatory member \\\"%%s\\\" is missing in list\", m->name);\n");
+	    fprintf (src, "      Tcl_SetErrorCode (interp, \"SNACC\", \"MISSMAND\", NULL);\n");
+	    fprintf (src, "      delete elempairs;\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    \n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  for (i=0; i<elems.c; i++)\n");
+	    fprintf (src, "  {\n");
+	    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+	    {
+		fprintf (src, "    if (!strcmp (elempairs[i].v[0], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "    {\n");
+		if (e->type->cxxTypeRefInfo->isPtr)
+		{
+		    fprintf (src, "      if (!%s)\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "        %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+		    fprintf (src, "      if (%s->TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      {\n");
+		    fprintf (src, "        delete elempairs;\n");
+		    fprintf (src, "        return TCL_ERROR;\n");
+		    fprintf (src, "      }\n");
+		}
+		else
+		{
+		    fprintf (src, "      if (%s.TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      {\n");
+		    fprintf (src, "        return TCL_ERROR;\n");
+		    fprintf (src, "        delete elempairs;\n");
+		    fprintf (src, "      }\n");
+		}
+		fprintf (src, "    }\n");
+	    }
+	    fprintf (src, "  }\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  // look for unmentioned optional members and delete them:\n");
+	    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+	    {
+		if (e->type->optional || e->type->defaultVal)
+		{
+		    fprintf (src, "  {\n");
+		    fprintf (src, "    bool present = false;\n");
+		    fprintf (src, "    for (i=0; i<elems.c; i++)\n");
+		    fprintf (src, "      if (!strcmp (elempairs[i].v[0], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "        present = true;\n");
+		    fprintf (src, "    if (!present)\n");
+		    fprintf (src, "    {\n");
+		    fprintf (src, "      delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "    }\n");
+		    fprintf (src, "  }\n");
+		}
+	    }
+	    fprintf (src, "\n");
+	    fprintf (src, "  delete elempairs;\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclUnsetVal (Tcl_Interp *interp, const char *membernames)\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Args elems;\n");
+	    fprintf (src, "  if (Tcl_SplitList (interp, (char*)membernames, &elems.c, &elems.v) != TCL_OK)\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  for (int i=0; i<elems.c; i++)\n");
+	    fprintf (src, "  {\n");
+	    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+	    {
+		fprintf (src, "    if (!strcmp (elems.v[i], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "    {\n");
+		if (e->type->optional || e->type->defaultVal)
+		{
+		    fprintf (src, "      delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+		    fprintf (src, "      %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+		}
+		else
+		{
+		    fprintf (src, "      return _desc.mandatmemberr (interp, elems.v[i]);\n");
+		}
+		fprintf (src, "    }\n");
+	    }
+	    fprintf (src, "  }\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (hdr, "#endif // TCL\n");
+	    fprintf (src, "#endif // TCL\n\n");
+	}
+#endif /* TCL */
+
+	fprintf (hdr, "#endif // META\n\n");
+	fprintf (src, "#endif // META\n\n");
+    }
+#endif /* META */
+
+    /* constructors and destructor: */
+
+    fprintf (hdr, "			%s();\n", td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+    {
+	if (e->type->cxxTypeRefInfo->isPtr)
+	    if (e->type->optional || e->type->defaultVal)
+		fprintf (src, "  %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+	    else
+	    {
+		fprintf (src, "#if TCL\n");
+		fprintf (src, "  %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+		fprintf (src, "#else\n");
+		fprintf (src, "  %s = NULL; // incomplete initialization of mandatory element!\n", e->type->cxxTypeRefInfo->fieldName);
+		fprintf (src, "#endif // TCL\n");
+	    }
+    }
+    fprintf (src, "}\n\n");
+
+    fprintf (hdr, "			%s (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::%s (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    fprintf (src, "  Asn1Error << \"use of incompletely defined %s::%s (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "  abort();\n");
+    fprintf (src, "}\n\n");
+
+    fprintf (hdr, "  virtual		~%s();\n", td->cxxTypeDefInfo->className);
+
+    fprintf (src, "%s::~%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+	if (e->type->cxxTypeRefInfo->isPtr)
+	    fprintf (src, "  delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+    fprintf (src, "}\n\n");
+
+    /* print clone routine for ANY mgmt */
+    PrintCloneMethod (hdr, src, td);
+
+    fprintf (hdr, "  %s		&operator = (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+
+    fprintf (src, "#if SNACC_DEEP_COPY\n");
+    fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "#else // SNACC_DEEP_COPY\n");
+    fprintf (src, "%s &%s::operator = (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "#endif // SNACC_DEEP_COPY\n");
+    fprintf (src, "{\n");
+    fprintf (src, "#if SNACC_DEEP_COPY\n");
+    fprintf (src, "  if (this != &that)\n");
+    fprintf (src, "  {\n");
+    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+    {
+	if (e->type->cxxTypeRefInfo->isPtr)
+	{
+	    fprintf (src, "    if (that.%s)\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      if (!%s)\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "        %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className);
+	    fprintf (src, "      *%s = *that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    else\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "      %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+	    fprintf (src, "    }\n");
+	}
+	else
+	    fprintf (src, "    %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName);
+    }
+    fprintf (src, "  }\n");
+    fprintf (src, "\n");
+    fprintf (src, "  return *this;\n");
+    fprintf (src, "#else // SNACC_DEEP_COPY\n");
+    fprintf (src, "  Asn1Error << \"use of incompletely defined %s &%s::operator = (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "  abort();\n");
+    fprintf (src, "  // if your compiler complains here, check the -novolat option\n");
+    if (novolatilefuncs)
+    {
+      fprintf (src, "  return *this;\n");
+    }
+    fprintf (src, "#endif // SNACC_DEEP_COPY\n");
+    fprintf (src, "}\n\n");
+
+    /* BerEncode */
+    if (printEncodersG)
+    {
+        fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG);
+
+        fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG);
+        fprintf (src, "{\n");
+
+        /* print local vars */
+        fprintf (src, "  %s totalLen = 0;\n", lenTypeNameG);
+        fprintf (src, "  %s l;\n\n", lenTypeNameG);
+
+#ifdef VDADER_RULES
+        {
+        if (gVDADER_RULES)
+        { int tmpCount=0;
+          FOR_EACH_LIST_ELMT_RVS (e, set->basicType->a.set)
+            tmpCount++;
+          fprintf (src, "      AsnBuf outputBuf;\n       int iii=0, tmpCount=0;\n");
+          fprintf (src, "      char *lpszBuf = (char *)calloc(1, 1024);\n");
+          fprintf (src, "      outputBuf.Init(lpszBuf, 1024);\n");
+          fprintf (src, "      outputBuf.ResetInWriteRvsMode();\n");
+
+          fprintf (src, "      CSM_Buffer *tmpEnc[%d];\n", tmpCount);   
+                        /** allocate enough tmp CSM_Buffer(s) to sort SET.
+                            NOT ALL MAY BE filled, there may be OPTIONAL SET
+                            elements!!  */
+        }
+#endif
+
+        FOR_EACH_LIST_ELMT_RVS (e, set->basicType->a.set)
+        {
+            cxxtri =  e->type->cxxTypeRefInfo;
+
+            varName = cxxtri->fieldName;
+
+            /* print optional test if nec*/
+            if (e->type->optional || (e->type->defaultVal != NULL))
+	    {
+                fprintf (src, "  if (%s (%s))\n", cxxtri->optTestRoutineName, varName);
+                fprintf (src, "  {\n");
+	    }
+
+            /* encode Eoc (s) if nec */
+#ifdef VDADER_RULES
+            if (gVDADER_RULES)
+              PrintCxxEocEncoders (src, td, e->type, "outputBuf");
+            else
+#endif
+            PrintCxxEocEncoders (src, td, e->type, "b");
+
+            /* encode content */
+            tmpTypeId = GetBuiltinType (e->type);
+            if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+            {
+                fprintf (src, "    %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+
+                defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+                if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID)
+                {
+                    fprintf (src, "SetTypeByOid (");
+                    if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                        fprintf (src, " *");
+                    fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                }
+                else
+                {
+                    fprintf (src, "SetTypeByInt (");
+                    if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                        fprintf (src, " *");
+                    fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                }
+
+                fprintf (src, "    l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+#ifdef VDADER_RULES
+                if (gVDADER_RULES)
+                  fprintf (src, "B%s (outputBuf);\n", r->encodeBaseName);
+                else
+#endif
+                fprintf (src, "B%s (b);\n", r->encodeBaseName);
+            }
+            else if (tmpTypeId == BASICTYPE_ANY)
+            {
+
+#ifdef VDADER_RULES
+if (! gVDADER_RULES)
+{
+#endif
+                fprintf (src, "    %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "SetTypeBy???(???);\n");
+
+                fprintf (src, "    l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+                fprintf (src, "B%s (b);\n", r->encodeBaseName);
+
+#ifdef VDADER_RULES
+}
+else
+                {
+                    fprintf (src, "        ENC_LOAD_ANYBUF(");
+                    if (!cxxtri->isPtr)
+                      fprintf (src, "&");
+                    fprintf (src, "%s, outputBuf, l);\n", varName);
+                }
+#endif
+            }
+            else
+            {
+                fprintf (src, "    l = %s", varName);
+                if (cxxtri->isPtr)
+                    fprintf (src, "->");
+                else
+                    fprintf (src, ".");
+
+#ifdef VDADER_RULES
+                if (gVDADER_RULES)
+                  fprintf (src, "B%s (outputBuf);\n", r->encodeContentBaseName);
+		else
+#endif
+                fprintf (src, "B%s (b);\n", r->encodeContentBaseName);
+            }
+
+            /* encode tag (s) & len (s) */
+
+#ifdef VDADER_RULES
+            if (gVDADER_RULES)
+              PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "outputBuf");
+            else
+#endif
+            PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "b");
+
+            fprintf (src, "    totalLen += l;\n");
+
+#ifdef VDADER_RULES
+            if (gVDADER_RULES) /** NOW, encode for SET DER rule ordering.*/
+            {                  /** RWC; Buffers handle files or memory. **/
+               fprintf (src, "        SNACC_BUFRESET_READ(&outputBuf);\n");
+               fprintf (src, "        SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);\n");
+               fprintf (src, "        SNACC_BUFRESET_WRITE(&outputBuf);\n");
+               fprintf (src, "        iii++;\n");
+            }
+#endif
+
+            /* close optional test if nec */
+            if (e->type->optional || (e->type->defaultVal != NULL))
+                fprintf (src, "  }\n\n");
+            else
+                fprintf (src, "\n");
+        }
+#ifdef VDADER_RULES
+            if (gVDADER_RULES) /** LAST, Order for SET DER rule ordering.*/
+            {                  /**   re-order all elements, add to "b".*/
+              fprintf (src, "      vdasnacc_sortSet(tmpEnc, iii);\n");
+              /** These "SET" components are now ordered in ascending order, 
+               ** ready to be loaded into the output buffer. (RWC; TBD; make output 
+               ** buffers accept these allocated buffers directly, no copy). 
+               **/
+              fprintf (src, "      tmpCount = iii;  /** REMEMBER how many we have**/\n");
+              fprintf (src, "      for (iii=0; iii < tmpCount; iii++)\n");
+              fprintf (src, "         SM_WriteToAsnBuf(tmpEnc[iii], b);\n");
+
+              fprintf (src, "      for (iii=0; iii < tmpCount; iii++) delete tmpEnc[iii];\n");
+              fprintf (src, "      free(lpszBuf);\n");
+
+           }
+        }       /** internal definition bracket for "tmpCount".**/
+#endif
+        fprintf (src, "  return totalLen;\n");
+        fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName);
+    }
+    /* end of BerEncodeContent */
+
+    /* write BerDecodeContent */
+    if (printDecodersG)
+    {
+        fprintf (hdr, "  void			B%s (%s b, %s tag, %s elmtLen, %s &bytesDecoded, %s env);\n\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "void %s::B%s (%s b, %s /*tag0*/, %s elmtLen0, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG);
+        fprintf (src, "{\n");
+
+        /* print local vars */
+        fprintf (src, "  %s tag1;\n", tagTypeNameG);
+        fprintf (src, "  %s setBytesDecoded = 0;\n", lenTypeNameG);
+        fprintf (src, "  unsigned int mandatoryElmtsDecoded = 0;\n");
+        /* count max number of extra length var nec */
+        varCount = 0;
+        FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+        {
+            tmpVarCount = CxxCountVariableLevels (e->type);
+            if (tmpVarCount > varCount)
+                varCount = tmpVarCount;
+        }
+        /* write extra length vars */
+        for (i = 1; i <= varCount; i++)
+            fprintf (src, "  %s elmtLen%d;\n", lenTypeNameG, i);
+        fprintf (src, "\n");
+
+        /* handle empty set */
+        if ((set->basicType->a.set == NULL) || LIST_EMPTY (set->basicType->a.set))
+        {
+            fprintf (src, "  if (elmtLen0 == INDEFINITE_LEN)\n");
+            fprintf (src, "    BDecEoc (b, bytesDecoded, env);\n");
+            fprintf (src, "  else if (elmtLen0 != 0)\n");
+            fprintf (src, "  {\n");
+            fprintf (src, "     Asn1Error << \"Expected an empty sequence\" << endl;\n");
+            fprintf (src, "     longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "  }\n");
+
+/*   forget about potential extension types for now
+            fprintf (src, "  if (elmtLen0 == INDEFINITE_LEN)\n");
+            fprintf (src, "  {\n");
+            fprintf (src, "    tag1 = BDecTag (b, bytesDecoded, env);\n\n");
+            fprintf (src, "    if (tag1 == EOC_TAG_ID)\n");
+            fprintf (src, "      BDEC_2ND_EOC_OCTET (b, bytesDecoded, env)\n");
+            fprintf (src, "    else\n");
+            fprintf (src, "      BerDiscardElmt (b, bytesDecoded, env);\n\n");
+            fprintf (src, "  }\n");
+            fprintf (src, "  else\n");
+            fprintf (src, "  {\n");
+            fprintf (src, "    BufSkip (b, elmtLen0);\n");
+            fprintf (src, "    bytesDecoded += elmtLen0;\n");
+            fprintf (src, "  }\n");
+*/
+        }
+        else
+        {
+            fprintf (src, "  for (; (setBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )\n");
+            fprintf (src, "  {\n");
+            fprintf (src, "    tag1 = BDecTag (b, setBytesDecoded, env);\n\n");
+            fprintf (src, "    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n");
+            fprintf (src, "    {\n");
+            fprintf (src, "      BDEC_2ND_EOC_OCTET (b, setBytesDecoded, env)\n");
+            fprintf (src, "      break; /* exit for loop */\n");
+            fprintf (src, "    }\n");
+
+            fprintf (src, "    elmtLen1 = BDecLen (b, setBytesDecoded, env);\n");
+            fprintf (src, "    switch (tag1)\n");
+            fprintf (src, "    {\n");
+            mandatoryElmtCount = 0;
+            FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+            {
+                cxxtri =  e->type->cxxTypeRefInfo;
+
+                tags = GetTags (e->type, &stoleChoiceTags);
+
+                if (LIST_EMPTY (tags))
+                {
+                    fprintf (src, "      // ANY Type ?\n");
+                    fprintf (src, "      case MAKE_TAG_ID (?, ?, ?):\n");
+                }
+                else
+                {
+                    tag = (Tag*)FIRST_LIST_ELMT (tags);
+                    classStr = Class2ClassStr (tag->tclass);
+                    codeStr = Code2UnivCodeStr (tag->code);
+                    formStr = Form2FormStr (tag->form);
+
+                    if (tag->tclass == UNIV)
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src, "      case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+                            fprintf (src, "      case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+                        }
+                        else
+                            fprintf (src, "      case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+                    }
+                    else
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src, "      case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                            fprintf (src, "      case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+                        }
+                        else
+                            fprintf (src, "      case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code);
+                    }
+
+                    /* now decode extra tags/length pairs */
+                    AsnListFirst (tags);
+                    AsnListNext (tags);
+                    elmtLevel = 1;
+                    if (stoleChoiceTags)
+                    {
+                        FOR_REST_LIST_ELMT (tag, tags)
+                        {
+                            classStr = Class2ClassStr (tag->tclass);
+                            codeStr = Code2UnivCodeStr (tag->code);
+                            formStr = Form2FormStr (tag->form);
+
+                            if (tag->tclass == UNIV)
+                            {
+                                if (tag->form == ANY_FORM)
+                                {
+                                    fprintf (src, "      case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+                                    fprintf (src, "      case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+                                }
+                                else
+                                    fprintf (src, "      case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+                            }
+                            else
+                            {
+                                if (tag->form == ANY_FORM)
+                                {
+                                    fprintf (src, "      case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                                    fprintf (src, "      case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+                                }
+                                else
+                                    fprintf (src, "      case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code);
+                            }
+                        }
+                    }
+                    else /* didn't steal nested choice's tags */
+                    {
+                        FOR_REST_LIST_ELMT (tag, tags)
+                        {
+                            classStr = Class2ClassStr (tag->tclass);
+                            codeStr = Code2UnivCodeStr (tag->code);
+                            formStr = Form2FormStr (tag->form);
+
+                            fprintf (src, "        tag1 = BDecTag (b, setBytesDecoded, env);\n");
+                            if (tag->form == ANY_FORM)
+                            {
+                                if (tag->tclass == UNIV)
+                                {
+                                    fprintf (src, "        if ((tag1 != MAKE_TAG_ID (%s, %s, %s))\n",  classStr, Form2FormStr (PRIM), codeStr);
+                                    fprintf (src, "           && (tag1 != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr);
+                                }
+                                else
+                                {
+                                    fprintf (src, "        if ((tag1 != MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code);
+                                    fprintf (src, "           && (tag1 != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code);
+                                }
+
+                            }
+                            else
+                            {
+                                if (tag->tclass == UNIV)
+                                    fprintf (src, "        if (tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr);
+                                else
+                                    fprintf (src, "        if (tag1 != MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code);
+                            }
+
+                            fprintf (src, "        {\n");
+                            fprintf (src, "           Asn1Error << \"Unexpected Tag\" << endl;\n");
+                            fprintf (src, "           longjmp (env, %d);\n", longJmpValG--);
+                            fprintf (src, "        }\n\n");
+
+                            fprintf (src, "        elmtLen%d = BDecLen (b, setBytesDecoded, env);\n", ++elmtLevel);
+                        }
+                    }
+                }
+                /*
+                 * if the choices element is another choice &&
+                 * we didn't steal its tags then we must grab
+                 * the key tag out of the contained CHOICE
+                 */
+                if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE))
+                {
+                    fprintf (src, "        tag1 = BDecTag (b, setBytesDecoded, env);\n");
+                    fprintf (src, "        elmtLen%d = BDecLen (b, setBytesDecoded, env);\n", ++elmtLevel);
+                }
+
+                varName = cxxtri->fieldName;
+
+                /* decode content */
+                if (cxxtri->isPtr)
+                    fprintf (src, "        %s = new %s;\n", varName, cxxtri->className);
+
+                /* decode content */
+                tmpTypeId = GetBuiltinType (e->type);
+                if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+                {
+                    /*
+                     * must check for another EOC for ANYs
+                     * since the any decode routines decode
+                     * their own first tag/len pair
+                     */
+                    elmtLevel++;
+
+                    fprintf (src, "        %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+
+                    defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+                    if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID)
+                    {
+                        fprintf (src, "SetTypeByOid (");
+                        if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                            fprintf (src, " *");
+                        fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                    }
+                    else
+                    {
+                        fprintf (src, "SetTypeByInt (");
+                        if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+                            fprintf (src, " *");
+                        fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+                    }
+
+                    fprintf (src, "        %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+                    fprintf (src, "B%s (b, setBytesDecoded, env);\n",  r->decodeBaseName);
+                }
+                else if (tmpTypeId == BASICTYPE_ANY)
+                {
+                    /*
+                     * must check for another EOC for ANYs
+                     * since the any decode routines decode
+                     * their own first tag/len pair
+                     */
+                    elmtLevel++;
+
+#ifdef VDADER_RULES
+if (!gVDADER_RULES)
+{
+#endif
+                    fprintf (src, "        %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+                    fprintf (src, "SetTypeBy???(???);\n");
+
+                    fprintf (src, "        %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+                    fprintf (src, "B%s (b, setBytesDecoded, env);\n",  r->decodeBaseName);
+
+#ifdef VDADER_RULES
+}
+else
+                  {
+                    fprintf (src, "        DEC_LOAD_ANYBUF(");
+                    if (!cxxtri->isPtr)
+                      fprintf (src, "&");
+                    fprintf (src, "%s, b, setBytesDecoded, env);\n", varName);
+                  }
+#endif
+                }
+                else
+                {
+                    fprintf (src, "        %s", varName);
+                    if (cxxtri->isPtr)
+                        fprintf (src, "->");
+                    else
+                        fprintf (src, ".");
+
+                    fprintf (src, "B%s (b, tag1, elmtLen%d, setBytesDecoded, env);\n",  r->decodeContentBaseName, elmtLevel);
+                }
+
+                /* decode Eoc (s) */
+                for (i = elmtLevel-1; i >= 1; i--)
+                {
+                    fprintf (src, "          if (elmtLen%d == INDEFINITE_LEN)\n", i);
+                    fprintf (src, "            BDecEoc (b, setBytesDecoded, env);\n\n");
+                }
+
+                /* keep track of decoded non-optional elmts */
+                if (!e->type->optional && (e->type->defaultVal == NULL))
+                {
+                    mandatoryElmtCount++;
+                    fprintf (src, "          mandatoryElmtsDecoded++;\n");
+                }
+                fprintf (src, "          break;\n\n");
+
+                FreeTags (tags);
+            } /* for each elmt */
+            fprintf (src, "       default:\n");
+            fprintf (src, "         Asn1Error << \"Unexpected Tag on SET elmt.\" << endl;\n");
+            fprintf (src, "         longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "    } // end switch\n");
+            fprintf (src, "  } // end for loop\n");
+            fprintf (src, "  bytesDecoded += setBytesDecoded;\n");
+            fprintf (src, "  if (mandatoryElmtsDecoded != %d)\n", mandatoryElmtCount);
+            fprintf (src, "  {\n");
+            fprintf (src, "     Asn1Error << \"ERROR - non-optional SET element missing.\" << endl;\n");
+            fprintf (src, "     longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "  }\n");
+
+        } /* if not empty set clause */
+
+        fprintf (src, "} // %s::B%s\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName);
+    }
+    /* end of decode content method code */
+
+    /* BerEncode */
+    if (printEncodersG)
+    {
+        fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG);
+
+        fprintf (src, "%s\n", lenTypeNameG);
+        fprintf (src, "%s::B%s (%s b)\n", td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "  %s l;\n", lenTypeNameG);
+        fprintf (src, "  l = B%s (b);\n", r->encodeContentBaseName);
+
+        /* encode each tag/len pair if any */
+        FOR_EACH_LIST_ELMT_RVS (tag, set->tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            formStr = Form2FormStr (CONS);  /* set's are constructed */
+            tagLen = TagByteLen (tag->code);
+
+            fprintf (src, "  l += BEncConsLen (b, l);\n");
+
+            if (tag->tclass == UNIV)
+                fprintf (src, "  l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src, "  l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code);
+        }
+        fprintf (src, "  return l;\n");
+        fprintf (src, "}\n\n");
+    }
+    /* end of BerEncode */
+
+    /* BerDecode */
+    if (printDecodersG)
+    {
+        fprintf (hdr, "  void			B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "  %s tag;\n", tagTypeNameG);
+
+        /* print extra locals for redundant lengths */
+        for (i = 1; (set->tags != NULL) && (i <= LIST_COUNT (set->tags)); i++)
+            fprintf (src, "  %s elmtLen%d;\n", lenTypeNameG, i);
+        fprintf (src, "\n");
+
+        /*  decode tag/length pair (s) */
+        elmtLevel = 0;
+        FOR_EACH_LIST_ELMT (tag, set->tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            formStr = Form2FormStr (CONS);  /* sets are constructed */
+
+            fprintf (src, "  if ((tag = BDecTag (b, bytesDecoded, env)) != ");
+
+            if (tag->tclass == UNIV)
+                fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src, "MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code);
+            fprintf (src, "  {\n");
+	    fprintf (src, "    Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName);
+            fprintf (src, "    longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "  }\n");
+
+            fprintf (src, "  elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+        }
+
+        fprintf (src, "  B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, i-1);
+
+        /* grab any EOCs that match redundant, indef lengths */
+        for (i = elmtLevel-1; i > 0; i--)
+        {
+            fprintf (src, "  if (elmtLen%d == INDEFINITE_LEN)\n", i);
+            fprintf (src, "    BDecEoc (b, bytesDecoded, env);\n");
+        }
+
+        fprintf (src, "}\n\n");
+    }
+    /* end of BerDecode */
+
+    PrintPduMemberFcns (src, hdr, r, td->cxxTypeDefInfo->className);
+
+    /* write code for printing */
+    if (printPrintersG)
+    {
+        fprintf (hdr, "  void			Print (ostream &os) const;\n");
+
+        fprintf (src, "void %s::Print (ostream &os) const\n", td->cxxTypeDefInfo->className);
+        fprintf (src, "{\n");
+ 		#ifdef	__APPLE__
+		fprintf (src, "#ifndef NDEBUG\n");
+		#endif
+       allOpt = AllElmtsOptional (set->basicType->a.set);
+        if (allOpt)
+            fprintf (src, "  int nonePrinted = true;\n");
+
+        fprintf (src, "  os << \"{ -- SET --\" << endl;\n");
+        fprintf (src, "  indentG += stdIndentG;\n\n");
+
+        FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+        {
+            inTailOptElmts = IsTailOptional (set->basicType->a.set);
+
+            if (e->type->cxxTypeRefInfo->isPtr)
+                fprintf (src, "  if (%s (%s))\n", cxxtri->optTestRoutineName, e->type->cxxTypeRefInfo->fieldName);
+
+	    fprintf (src, "  {\n");
+
+            if (allOpt)
+            {
+                if (e != FIRST_LIST_ELMT (set->basicType->a.set))
+                {
+                    fprintf (src, "    if (!nonePrinted)\n");
+                    fprintf (src, "      os << \",\" << endl;\n");
+                }
+                fprintf (src, "    nonePrinted = false;\n", i);
+            }
+            else if (inTailOptElmts) /* cannot be first elmt ow allOpt is true */
+                fprintf (src, "    os << \",\"<< endl;\n");
+
+            fprintf (src, "    Indent (os, indentG);\n");
+
+            if (e->fieldName != NULL)
+                fprintf (src, "    os << \"%s \";\n", e->fieldName);
+
+            if (e->type->cxxTypeRefInfo->isPtr)
+                fprintf (src, "    os << *%s;\n", e->type->cxxTypeRefInfo->fieldName);
+            else
+                fprintf (src, "    os << %s;\n", e->type->cxxTypeRefInfo->fieldName);
+
+            if (e != LAST_LIST_ELMT (set->basicType->a.set) && !inTailOptElmts && !NextIsTailOptional (set->basicType->a.set))
+                fprintf (src, "    os << \",\" << endl;\n");
+
+	    fprintf (src, "  }\n");
+
+            if (e->type->cxxTypeRefInfo->isPtr)
+	    {
+		fprintf (src, "  else\n");
+#ifdef KHO
+		fprintf (src, "    os << \"-- void2 --\\n\";\n");
+#else
+		fprintf (src, "    os << \"-- void --\";\n");
+#endif
+	    }
+
+	    fprintf (src, "\n");
+
+            if (e == LAST_LIST_ELMT (set->basicType->a.set))
+                fprintf (src, "  os << endl;\n");
+        }
+        fprintf (src, "  indentG -= stdIndentG;\n");
+        fprintf (src, "  Indent (os, indentG);\n");
+        fprintf (src, "  os << \"}\";\n");
+		#ifdef	__APPLE__
+		fprintf (src, "#endif /* NDEBUG */\n");
+		#endif	__APPLE__
+        fprintf (src, "} // %s - operator <<\n\n\n", td->cxxTypeDefInfo->className);
+    }
+    /* end of print method code */
+
+    /* close class definition */
+    fprintf (hdr, "};\n\n\n");
+
+} /* PrintCxxSetDefCode */
+
+
+/*
+ * This major Bogosity results from gcc2.2.2 inability to handle
+ * template properly
+ */
+static void
+PrintCxxListClass PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, lst),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    if_IBM_ENC (FILE *srcdb _AND_)
+    if_IBM_ENC (FILE *hdrdb _AND_)
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *lst)
+{
+    char *lcn; /* list class name */
+    char *ecn; /* (list) elmt class name */
+    char *classStr;
+    char *formStr;
+    int tagLen;
+    Tag *tag;
+    int i, elmtLevel;
+
+    lcn = td->cxxTypeDefInfo->className;
+    ecn = lst->basicType->a.setOf->cxxTypeRefInfo->className;
+
+#ifdef _IBM_ENC_
+#include "./ibm_editor/print_cxx_list_class.h"
+#endif /* _IBM_ENC_ */
+
+    fprintf (hdr, "class %s%s\n", lcn, baseClassesG);
+    fprintf (hdr, "{\n");
+    fprintf (hdr, "protected:\n");
+
+    fprintf (hdr, "  unsigned long int	count;\n");
+    fprintf (hdr, "  struct AsnListElmt\n");
+    fprintf (hdr, "  {\n");
+    fprintf (hdr, "    AsnListElmt	*next;\n");
+    fprintf (hdr, "    AsnListElmt	*prev;\n");
+#ifdef _IBM_ENC_
+    fprintf (hdr, "    void		*operator new (size_t t) { return mem_mgr_ptr->Get (t); }    // Guido Grassel 12.8.93\n");
+    fprintf (hdr, "    void		operator delete (void *p) { mem_mgr_ptr->Put (p); }	// Guido Grassel 12.8.93\n");
+#endif /* _IBM_ENC_ */
+    fprintf (hdr, "    %s	*elmt;\n", ecn);
+    fprintf (hdr, "  }			*first, *curr, *last;\n\n");
+
+    fprintf (hdr, "public:\n");
+
+#if META
+    if (printMetaG)
+    {
+	const char *emtn = "?";
+	switch (lst->basicType->choiceId)
+	{
+	    case BASICTYPE_SEQUENCEOF:
+		emtn = "SEQUENCE_OF";
+		break;
+	    case BASICTYPE_SETOF:
+		emtn = "SET_OF";
+		break;
+	}
+
+	fprintf (hdr, "#if META\n");
+	fprintf (src, "#if META\n\n");
+
+	fprintf (hdr, "  static const AsnListTypeDesc	_desc;\n");
+	fprintf (hdr, "  const AsnTypeDesc		*_getdesc() const;\n");
+	fprintf (hdr, "  AsnType			*_getref (const char *index, bool create = false);\n\n");
+
+	fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  return new %s;\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "}\n\n");
+
+	fprintf (src, "const AsnListTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "(\n");
+	fprintf (src, "  &%sModuleDesc,\n", m->cxxname);
+	if (printMetaG == META_backend_names)
+	    fprintf (src, "  \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName);
+	else /* META_asn1_names */
+	    fprintf (src, "  \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className);
+	fprintf (src, "  %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false");
+	fprintf (src, "  AsnTypeDesc::%s,\n", emtn);
+	fprintf (src, "  create%s,\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "  &%s::_desc\n", ecn);
+	fprintf (src, ");\n\n");
+
+	fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  return &_desc;\n");
+	fprintf (src, "}\n\n");
+
+	fprintf (src, "AsnType *%s::_getref (const char *strindex, bool create)\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "{\n");
+	fprintf (src, "  bool insert;\n");
+	fprintf (src, "  unsigned long index;\n");
+	fprintf (src, "  char c;\n");
+	fprintf (src, "  if (sscanf (strindex, \"insert %%lu%%c\", &index, &c) == 1)\n");
+	fprintf (src, "  {\n");
+	fprintf (src, "    insert = true;\n");
+	fprintf (src, "  }\n");
+	fprintf (src, "  else if (sscanf (strindex, \"%%lu%%c\", &index, &c) == 1)\n");
+	fprintf (src, "  {\n");
+	fprintf (src, "    insert = false;\n");
+	fprintf (src, "  }\n");
+	fprintf (src, "  else\n");
+	fprintf (src, "    return NULL;\n");
+	fprintf (src, "  if (insert && index == Count())\n");
+	fprintf (src, "    return Append();\n");
+	fprintf (src, "  if (index >= Count())\n");
+	fprintf (src, "    return NULL;\n");
+	fprintf (src, "  SetCurrElmt (index);\n");
+	fprintf (src, "  return insert ? InsertBefore() : Curr();\n");
+	fprintf (src, "}\n\n");
+
+#if TCL
+	if (printTclG)
+	{
+	    fprintf (hdr, "#if TCL\n");
+	    fprintf (src, "#if TCL\n\n");
+
+	    fprintf (hdr, "  int			TclGetDesc (Tcl_DString *) const;\n");
+	    fprintf (hdr, "  int			TclGetVal (Tcl_Interp *) const;\n");
+	    fprintf (hdr, "  int			TclSetVal (Tcl_Interp *, const char *valstr);\n");
+	    fprintf (hdr, "  int			TclUnsetVal (Tcl_Interp *, const char *indexstr);\n");
+
+	    fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  char countstr[80];\n");
+	    fprintf (src, "  sprintf (countstr, \"%%lu\", count);\n");
+	    fprintf (src, "  Tcl_DStringAppendElement (valstr, countstr);\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "  return _desc.base->AsnTypeDesc::TclGetDesc (valstr);\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Tcl_DString valstr;\n");
+	    fprintf (src, "  Tcl_DStringInit (&valstr);\n");
+	    fprintf (src, "  //for (SetCurrToFirst(); Curr(); GoNext())\n");
+	    fprintf (src, "  for (const AsnListElmt *run=first; run; run=run->next)\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    if (run->elmt->TclGetVal (interp) != TCL_OK)\n");
+	    fprintf (src, "    {\n");
+	    fprintf (src, "      Tcl_DStringFree (&valstr);\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "    }\n");
+	    fprintf (src, "    Tcl_DStringAppendElement (&valstr, interp->result);\n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "  Tcl_ResetResult (interp);\n");
+	    fprintf (src, "  Tcl_DStringResult (interp, &valstr);\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  Args elem;\n");
+	    fprintf (src, "  if (Tcl_SplitList (interp, (char*)valstr, &elem.c, &elem.v) != TCL_OK)\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  while (First())\n");
+	    fprintf (src, "    RemoveCurrFromList();\n");
+	    fprintf (src, "\n");
+	    fprintf (src, "  for (int i=0; i<elem.c; i++)\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    if (Append()->TclSetVal (interp, elem.v[i]) != TCL_OK)\n");
+	    fprintf (src, "      return TCL_ERROR;\n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (src, "int %s::TclUnsetVal (Tcl_Interp *interp, const char *indexstr)\n", td->cxxTypeDefInfo->className);
+	    fprintf (src, "{\n");
+	    fprintf (src, "  int index;\n");
+	    fprintf (src, "  if (Tcl_GetInt (interp, (char*)indexstr, &index) != TCL_OK)\n");
+	    fprintf (src, "    return TCL_ERROR;\n");
+	    fprintf (src, "  if (index >= Count())\n");
+	    fprintf (src, "  {\n");
+	    fprintf (src, "    sprintf (interp->result, \"error: list: index %%d out of range (0-%%d)\", index, Count()-1);\n");
+	    fprintf (src, "    return NULL;\n");
+	    fprintf (src, "  }\n");
+	    fprintf (src, "  SetCurrElmt (index);\n");
+	    fprintf (src, "  RemoveCurrFromList();\n");
+	    fprintf (src, "  return TCL_OK;\n");
+	    fprintf (src, "}\n\n");
+
+	    fprintf (hdr, "#endif // TCL\n");
+	    fprintf (src, "#endif // TCL\n\n");
+	}
+#endif /* TCL */
+
+	fprintf (hdr, "#endif // META\n\n");
+	fprintf (src, "#endif // META\n\n");
+    }
+#endif /* META */
+
+
+    fprintf (hdr, "			%s() { count = 0; first = curr = last = NULL; }\n", lcn);
+
+    fprintf (hdr, "			%s (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+
+    fprintf (hdr, "  virtual		~%s();\n", td->cxxTypeDefInfo->className);
+
+    /* print clone routine for ANY mgmt */
+    PrintCloneMethod (hdr, src, td);
+
+    fprintf (hdr, "  %s		&operator = (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+
+    fprintf (hdr, "  void		SetCurrElmt (unsigned long int index);\n");
+    fprintf (hdr, "  unsigned long int	GetCurrElmtIndex();\n");
+    fprintf (hdr, "  void		SetCurrToFirst() { curr = first; }\n");
+    fprintf (hdr, "  void		SetCurrToLast()  { curr = last; }\n");
+
+    fprintf (hdr, "  // reading member fcns\n");
+    fprintf (hdr, "  int			Count() const	{ return count; }\n");
+    fprintf (hdr, "  // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)\n");
+    fprintf (hdr, "  %s	*First() const	{ return count > 0 ? first->elmt : NULL; }\n", ecn);
+    fprintf (hdr, "  %s	*Last() const	{ return count > 0 ? last->elmt : NULL; }\n", ecn);
+    fprintf (hdr, "  %s	*Curr() const	{ return curr ? curr->elmt : NULL; }\n", ecn);
+    fprintf (hdr, "  %s	*Next() const	{ return curr && curr->next ? curr->next->elmt : NULL; }\n", ecn);
+    fprintf (hdr, "  %s	*Prev() const	{ return curr && curr->prev ? curr->prev->elmt : NULL; }\n\n", ecn);
+
+    fprintf (hdr, "  // routines that move the curr elmt\n");
+    fprintf (hdr, "  %s	*GoNext() { if (curr) curr = curr->next; return Curr(); }\n", ecn);
+    fprintf (hdr, "  %s	*GoPrev() { if (curr) curr = curr->prev; return Curr(); }\n\n", ecn);
+
+    fprintf (hdr, "  // write & alloc fcns - returns new elmt\n");
+    fprintf (hdr, "  %s	*Append();  // add elmt to end of list\n", ecn);
+    fprintf (hdr, "  %s	*Prepend(); // add elmt to beginning of list\n", ecn);
+    fprintf (hdr, "  %s	*InsertBefore(); //insert elmt before current elmt\n", ecn);
+    fprintf (hdr, "  %s	*InsertAfter(); //insert elmt after current elmt\n\n", ecn);
+
+    fprintf (hdr, "  // write & alloc & copy - returns list after copying elmt\n");
+    fprintf (hdr, "  %s	&AppendCopy (%s &elmt);  // add elmt to end of list\n", lcn, ecn);
+    fprintf (hdr, "  %s	&PrependCopy (%s &elmt); // add elmt to beginning of list\n", lcn, ecn);
+    fprintf (hdr, "  %s	&InsertBeforeAndCopy (%s &elmt); //insert elmt before current elmt\n", lcn, ecn);
+    fprintf (hdr, "  %s	&InsertAfterAndCopy (%s &elmt); //insert elmt after current elmt\n\n", lcn, ecn);
+
+    fprintf (hdr, "  // removing the current elmt from the list\n");
+    fprintf (hdr, "  void		RemoveCurrFromList();\n\n");
+
+    fprintf (hdr, "  // encode and decode routines    \n");
+
+    /* print PDU oriented encode routine */
+    if (printEncodersG)
+    {
+        fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG);
+
+        fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "  %s l;\n", lenTypeNameG);
+
+        /* encode the list content */
+        fprintf (src, "  l = B%s (b);\n", r->encodeContentBaseName);
+
+        /* encode each tag/len pair if any */
+        FOR_EACH_LIST_ELMT_RVS (tag, lst->tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            formStr = Form2FormStr (CONS);  /* choices are constructed */
+            tagLen = TagByteLen (tag->code);
+
+            /* always constructed lengths for list */
+            fprintf (src, "  l += BEncConsLen (b, l);\n");
+
+            if (tag->tclass == UNIV)
+                fprintf (src, "  l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src, "  l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code);
+        }
+        fprintf (src, "  return l;\n");
+        fprintf (src, "}\n\n");
+    }
+    /* end of ber encode function */
+
+    /* do BerDecode function */
+    if (printDecodersG)
+    {
+        fprintf (hdr, "  void			B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG);
+
+        fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName,  bufTypeNameG, lenTypeNameG, envTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "  %s tag;\n", tagTypeNameG);
+
+        /* print extra locals for redundant lengths */
+        for (i = 1; (lst->tags != NULL) && (i <= LIST_COUNT (lst->tags)); i++)
+            fprintf (src, "  %s elmtLen%d;\n", lenTypeNameG, i);
+        fprintf (src, "\n");
+
+        /*  decode tag/length pair (s) */
+        elmtLevel = 0;
+        FOR_EACH_LIST_ELMT (tag, lst->tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            formStr = Form2FormStr (CONS);  /* lists are constructed */
+
+            fprintf (src, "  if ((tag = BDecTag (b, bytesDecoded, env)) != ");
+
+            if (tag->tclass == UNIV)
+                fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src, "MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code);
+            fprintf (src, "  {\n");
+	    fprintf (src, "    Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName);
+            fprintf (src, "    longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "  }\n");
+
+            fprintf (src, "  elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+        }
+
+        fprintf (src, "  B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel);
+
+        /* grab any EOCs that match redundant, indef lengths */
+        for (i = elmtLevel-1; i > 0; i--)
+        {
+            fprintf (src, "  if (elmtLen%d == INDEFINITE_LEN)\n", i);
+            fprintf (src, "     BDecEoc (b, bytesDecoded, env);\n");
+        }
+
+        fprintf (src, "}\n\n");
+    }
+    /* end of BDec function */
+
+
+    if (printEncodersG)
+        fprintf (hdr, "  %s		B%s (%s b);\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG);
+
+    if (printDecodersG)
+        fprintf (hdr, "  void			B%s (%s b, %s tag, %s elmtLen, %s &bytesDecoded, %s env);\n\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG);
+
+    fprintf (hdr, "  PDU_MEMBER_MACROS\n");
+
+    if (printPrintersG) {
+        fprintf (hdr, "  void		Print (ostream &os) const;\n");
+	}
+    fprintf (hdr, "};\n\n\n");
+
+} /* PrintCxxListClass */
+
+
+/*
+ * Prints code to decode and check tags and lengths for a
+ * SEQ OF/SET OF element.
+ *
+ * as usual, assumes:
+ *  b for buf var name
+ *  elmtLen for elmts len var name
+ *  env for environment var name
+ *  listBytesDecoded for the runing total bytes decoded
+ *  tag1 for tag
+ *
+ *  Assumes first tag has been decoded and is in 'tag1' var
+ */
+static void
+PrintCxxListTagAndLenDecCode PARAMS ((src, td, t),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t)
+{
+    TagList *tags;
+    Tag *tag;
+    int elmtLevel;
+    int stoleChoiceTags;
+
+    elmtLevel = 0;
+
+    tags = GetTags (t, &stoleChoiceTags);
+    if (stoleChoiceTags)
+    {
+        fprintf (src, "        if (!(");
+        FOR_EACH_LIST_ELMT (tag, tags)
+        {
+            fprintf (src, "(tag1 == ");
+            PrintMakeTag (src, tag);
+            if (tag->form == ANY_FORM)
+            {
+                fprintf (src, ")\n            || (tag1 == ");
+                tag->form = CONS;
+                PrintMakeTag (src, tag);
+                fprintf (src, ")\n");
+            }
+            else
+                fprintf (src, ")");
+
+            if (tag != (Tag *)LAST_LIST_ELMT (tags))
+                fprintf (src, "\n         || ");
+        }
+        fprintf (src, "))\n");
+        fprintf (src, "        {\n");
+        fprintf (src, "            Asn1Error << \"Unexpected Tag\" << endl;\n");
+        fprintf (src, "            longjmp (env, %d);\n", longJmpValG--);
+        fprintf (src, "        }\n\n");
+        fprintf (src, "        elmtLen%d = BDecLen (b, listBytesDecoded, env);\n", ++elmtLevel);
+    }
+
+    else /* didn't steal nested choice's tags */
+    {
+        AsnListFirst (tags);
+
+        FOR_EACH_LIST_ELMT (tag, tags)
+        {
+
+            fprintf (src, "        if ((tag1 != ");
+            PrintMakeTag (src, tag);
+            if (tag->form == ANY_FORM)
+            {
+                fprintf (src, ")\n         && (tag1 != ");
+                tag->form = CONS;
+                PrintMakeTag (src, tag);
+                fprintf (src, "))\n");
+            }
+            else
+                fprintf (src, "))\n");
+
+            fprintf (src, "        {\n");
+            fprintf (src, "            Asn1Error << \"Unexpected Tag\" << endl;\n");
+            fprintf (src, "            longjmp (env, %d);\n", longJmpValG--);
+            fprintf (src, "        }\n\n");
+            fprintf (src, "        elmtLen%d = BDecLen (b, listBytesDecoded, env);\n", ++elmtLevel);
+
+            if (tag != (Tag*)LAST_LIST_ELMT (tags))
+                fprintf (src, "        tag1 = BDecTag (b, listBytesDecoded, env);\n\n");
+
+        }
+
+        /*
+         * if this seq element is CHOICE &&
+         * we didn't steal its tags then we must grab
+         * the key tag out of the contained CHOICE
+         */
+        if (GetBuiltinType (t) == BASICTYPE_CHOICE)
+        {
+            fprintf (src, "        tag1 = BDecTag (b, listBytesDecoded, env);\n");
+            fprintf (src, "        elmtLen%d = BDecLen (b, listBytesDecoded, env);\n", ++elmtLevel);
+        }
+    }
+    FreeTags (tags);
+} /* PrintCxxListTagAndLenDecCode */
+
+/*
+ * This major Bogosity results from gcc2.2.2 inability to handle
+ * templates properly
+ */
+static void
+PrintCxxListMethods PARAMS ((src, hdr, mods, m, r, td, parent, lst, novolatilefuncs),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *lst _AND_
+    int novolatilefuncs)
+{
+    char *lcn; /* list class name */
+    char *ecn; /* (list) elmt class name */
+    int elmtLevel;
+    int i;
+    enum BasicTypeChoiceId tmpTypeId;
+    Tag *tag;
+    char *classStr;
+    char *formStr;
+    int tagLen;
+
+    lcn = td->cxxTypeDefInfo->className;
+    ecn = lst->basicType->a.setOf->cxxTypeRefInfo->className;
+
+    fprintf (src, "%s::%s (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    fprintf (src, "  Asn1Error << \"use of incompletely defined %s::%s (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "  abort();\n");
+    fprintf (src, "}\n\n");
+
+    fprintf (src, "%s::~%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "{\n");
+    fprintf (src, "  SetCurrToFirst();\n");
+    fprintf (src, "  for (; Curr() != NULL; RemoveCurrFromList())\n");
+    fprintf (src, "    ;\n");
+    fprintf (src, "} // end of destructor\n\n");
+
+    fprintf (src, "#if SNACC_DEEP_COPY\n");
+    fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "#else // SNACC_DEEP_COPY\n");
+    fprintf (src, "%s &%s::operator = (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "#endif // SNACC_DEEP_COPY\n");
+    fprintf (src, "{\n");
+    fprintf (src, "#if SNACC_DEEP_COPY\n");
+    fprintf (src, "  if (this != &that)\n");
+    fprintf (src, "  {\n");
+    fprintf (src, "    SetCurrToFirst();\n");
+    fprintf (src, "    for (; Curr(); RemoveCurrFromList())\n");
+    fprintf (src, "      ;\n");
+    fprintf (src, "\n");
+    fprintf (src, "    //that.SetCurrToFirst();\n");
+    fprintf (src, "    //for (; that.Curr(); that.GoNext())\n");
+    fprintf (src, "    //  AppendCopy (*that.Curr());\n");
+    fprintf (src, "    for (const AsnListElmt *run=that.first; run; run=run->next)\n");
+    fprintf (src, "      AppendCopy (*run->elmt);\n");
+    fprintf (src, "  }\n");
+    fprintf (src, "\n");
+    fprintf (src, "  return *this;\n");
+    fprintf (src, "#else // SNACC_DEEP_COPY\n");
+    fprintf (src, "  Asn1Error << \"use of incompletely defined %s &%s::operator = (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className);
+    fprintf (src, "  abort();\n");
+    fprintf (src, "  // if your compiler complains here, check the -novolat option\n");
+    if (novolatilefuncs)
+    {
+      fprintf (src, "  return *this;\n");
+    }
+    fprintf (src, "#endif // SNACC_DEEP_COPY\n");
+    fprintf (src, "}\n\n");
+
+    if (printPrintersG)
+    {
+        fprintf (src, "void %s::Print (ostream &os) const\n", td->cxxTypeDefInfo->className);
+        fprintf (src, "{\n");
+		#ifdef	__APPLE__
+		fprintf (src, "#ifndef NDEBUG\n");
+		#endif
+        fprintf (src, "    os << \"{ -- SEQUENCE/SET OF -- \" << endl;\n");
+        fprintf (src, "    indentG += stdIndentG;\n");
+
+        fprintf (src, "    //SetCurrToFirst();\n");
+        fprintf (src, "    //for (; Curr() != NULL; GoNext())\n");
+        fprintf (src, "    for (const AsnListElmt *run=first; run; run=run->next)\n");
+        fprintf (src, "    {\n");
+        fprintf (src, "        Indent (os, indentG);\n");
+        fprintf (src, "        //os << *Curr();\n");
+        fprintf (src, "        os << *run->elmt;\n");
+        fprintf (src, "        //if (Curr() != Last())\n");
+        fprintf (src, "        if (run != last)\n");
+        fprintf (src, "            os << \",\";\n");
+        fprintf (src, "        os << endl;\n");
+        fprintf (src, "    }\n");
+
+        fprintf (src, "    indentG -= stdIndentG;\n");
+        fprintf (src, "    Indent (os, indentG);\n");
+#ifdef KHO
+        fprintf (src, "    os << \"}\\n\";\n");
+#else
+        fprintf (src, "    os << \"}\";\n");
+#endif
+
+ 		#ifdef	__APPLE__
+		fprintf (src, "#endif /* NDEBUG */\n\n\n");
+		#endif
+       fprintf (src, "} // Print\n\n\n");
+    }
+
+    fprintf (src, "void  %s::SetCurrElmt (unsigned long int index)\n", lcn);
+    fprintf (src, "{\n");
+    fprintf (src, "  unsigned long int i;\n");
+    fprintf (src, "  curr = first;\n");
+    fprintf (src, "  if (count)\n");
+    fprintf (src, "    for (i = 0; (i < (count-1)) && (i < index); i++)\n");
+    fprintf (src, "      curr = curr->next;\n");
+    fprintf (src, "} // %s::SetCurrElmt\n\n\n", lcn);
+
+
+    fprintf (src, "unsigned long int  %s::GetCurrElmtIndex()\n", lcn);
+    fprintf (src, "{\n");
+    fprintf (src, "    unsigned long int i;\n");
+    fprintf (src, "    AsnListElmt *tmp;\n");
+    fprintf (src, "    if (curr != NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        for (i = 0, tmp = first; tmp != NULL; i++)\n");
+    fprintf (src, "        {\n");
+    fprintf (src, "            if (tmp == curr)\n");
+    fprintf (src, "                return i;\n");
+    fprintf (src, "            else\n");
+    fprintf (src, "                tmp = tmp->next;\n");
+    fprintf (src, "        }\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    return count;\n");
+    fprintf (src, "} // %s::GetCurrElmtIndex\n\n\n", lcn);
+
+
+    fprintf (src, "// alloc new list elmt, put at end of list\n");
+    fprintf (src, "//  and return the component type\n");
+    fprintf (src, "%s *%s::Append()\n", ecn, lcn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *newElmt;\n");
+    fprintf (src, "    newElmt  = new AsnListElmt;\n");
+    fprintf (src, "    newElmt->elmt  = new %s;\n", ecn);
+    fprintf (src, "    newElmt->next = NULL;\n");
+    fprintf (src, "    if (last == NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->prev = NULL;\n");
+    fprintf (src, "        first = last  = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    else\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->prev = last;\n");
+    fprintf (src, "        last->next    = newElmt;\n");
+    fprintf (src, "        last          = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    count++;\n");
+    fprintf (src, "    return (curr = newElmt)->elmt;\n");
+    fprintf (src, "} // %s::Append\n\n\n", lcn);
+
+
+    fprintf (src, "// alloc new list elmt, put at begining of list\n");
+    fprintf (src, "//  and return the component type\n");
+    fprintf (src, "%s  *%s::Prepend()\n", ecn, lcn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *newElmt;\n");
+    fprintf (src, "    newElmt  = new AsnListElmt;\n");
+    fprintf (src, "    newElmt->elmt = new %s;\n", ecn);
+    fprintf (src, "    newElmt->prev = NULL;\n");
+    fprintf (src, "    if (first == NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->next = NULL;\n");
+    fprintf (src, "        first = last  = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    else\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->next = first;\n");
+    fprintf (src, "        first->prev   = newElmt;\n");
+    fprintf (src, "        first         = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    count++;\n");
+    fprintf (src, "    return (curr = newElmt)->elmt;\n");
+    fprintf (src, "} // %s::Prepend\n\n\n", lcn);
+
+
+    fprintf (src, "// alloc new list elmt, insert it before the\n");
+    fprintf (src, "// current element and return the component type\n");
+    fprintf (src, "// if the current element is null, the new element\n");
+    fprintf (src, "// is placed at the beginning of the list.\n");
+    fprintf (src, "%s  *%s::InsertBefore()\n", ecn, lcn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *newElmt;\n");
+    fprintf (src, "    newElmt  = new AsnListElmt;\n");
+    fprintf (src, "    newElmt->elmt = new %s;\n", ecn);
+    fprintf (src, "    if (curr == NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->next = first;\n");
+    fprintf (src, "        newElmt->prev = NULL;\n");
+    fprintf (src, "        first = newElmt;\n");
+    fprintf (src, "        if (last == NULL)\n");
+    fprintf (src, "            last = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    else\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->next = curr;\n");
+    fprintf (src, "        newElmt->prev = curr->prev;\n");
+    fprintf (src, "        curr->prev = newElmt;\n");
+    fprintf (src, "        if (curr == first)\n");
+    fprintf (src, "            first = newElmt;\n");
+    fprintf (src, "        else\n");
+    fprintf (src, "            newElmt->prev->next = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    count++;\n");
+    fprintf (src, "    return (curr = newElmt)->elmt;\n");
+    fprintf (src, "} // %s::InsertBefore\n\n\n", lcn);
+
+
+    fprintf (src, "// alloc new list elmt, insert it after the\n");
+    fprintf (src, "// current element and return the component type\n");
+    fprintf (src, "// if the current element is null, the new element\n");
+    fprintf (src, "// is placed at the end of the list.\n");
+    fprintf (src, "%s *%s::InsertAfter()\n", ecn, lcn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *newElmt;\n");
+    fprintf (src, "    newElmt  = new AsnListElmt;\n");
+    fprintf (src, "    newElmt->elmt = new %s;\n", ecn);
+    fprintf (src, "    if (curr == NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->prev = last;\n");
+    fprintf (src, "        newElmt->next = NULL;\n");
+    fprintf (src, "        last = newElmt;\n");
+    fprintf (src, "        if (first == NULL)\n");
+    fprintf (src, "            first = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    else\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->prev = curr;\n");
+    fprintf (src, "        newElmt->next = curr->next;\n");
+    fprintf (src, "        curr->next = newElmt;\n");
+    fprintf (src, "        if (curr == last)\n");
+    fprintf (src, "            last = newElmt;\n");
+    fprintf (src, "        else\n");
+    fprintf (src, "            newElmt->next->prev = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    count++;\n");
+    fprintf (src, "    return (curr = newElmt)->elmt;\n");
+    fprintf (src, "} // %s::InsertAfter\n\n\n", lcn);
+
+
+    fprintf (src, "%s  &%s::AppendCopy (%s &elmt)\n", lcn, lcn, ecn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *newElmt;\n");
+    fprintf (src, "    newElmt  = new AsnListElmt;\n");
+    fprintf (src, "    newElmt->elmt = new %s;\n", ecn);
+    fprintf (src, "    *newElmt->elmt = elmt;\n");
+    fprintf (src, "    newElmt->next = NULL;\n");
+    fprintf (src, "    if (last == NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->prev = NULL;\n");
+    fprintf (src, "        first = last  = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    else\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->prev = last;\n");
+    fprintf (src, "        last->next    = newElmt;\n");
+    fprintf (src, "        last          = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    count++;\n");
+    fprintf (src, "    return *this;\n");
+    fprintf (src, "} // AppendCopy\n\n\n");
+
+
+    fprintf (src, "%s  &%s::PrependCopy (%s &elmt)\n", lcn, lcn, ecn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *newElmt;\n");
+    fprintf (src, "    newElmt  = new AsnListElmt;\n");
+    fprintf (src, "    newElmt->elmt = new %s;\n", ecn);
+    fprintf (src, "    *newElmt->elmt = elmt;\n");
+    fprintf (src, "    newElmt->prev = NULL;\n");
+    fprintf (src, "    if (first == NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->next = NULL;\n");
+    fprintf (src, "        first = last  = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    else\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->next = first;\n");
+    fprintf (src, "        first->prev   = newElmt;\n");
+    fprintf (src, "        first         = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    count++;\n");
+    fprintf (src, "    return *this;\n");
+    fprintf (src, "} // %s::PrependCopy\n\n\n", lcn);
+
+
+    fprintf (src, "// alloc new list elmt, insert it before the\n");
+    fprintf (src, "// current element, copy the given elmt into the new elmt\n");
+    fprintf (src, "// and return the component type.\n");
+    fprintf (src, "// if the current element is null, the new element\n");
+    fprintf (src, "// is placed at the beginning of the list.\n");
+    fprintf (src, "%s &%s::InsertBeforeAndCopy (%s &elmt)\n", lcn, lcn, ecn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *newElmt;\n");
+    fprintf (src, "\n");
+    fprintf (src, "    newElmt  = new AsnListElmt;\n");
+    fprintf (src, "    newElmt->elmt = new %s;\n", ecn);
+    fprintf (src, "    *newElmt->elmt = elmt;\n");
+    fprintf (src, "\n");
+    fprintf (src, "    if (curr == NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->next = first;\n");
+    fprintf (src, "        newElmt->prev = NULL;\n");
+    fprintf (src, "        first = newElmt;\n");
+    fprintf (src, "        if (last == NULL)\n");
+    fprintf (src, "            last = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    else\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->next = curr;\n");
+    fprintf (src, "        newElmt->prev = curr->prev;\n");
+    fprintf (src, "        curr->prev = newElmt;\n");
+    fprintf (src, "        if (curr == first)\n");
+    fprintf (src, "            first = newElmt;\n");
+    fprintf (src, "        else\n");
+    fprintf (src, "            newElmt->prev->next = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    count++;\n");
+    fprintf (src, "    return *this;\n");
+    fprintf (src, "} // %s::InsertBeforeAndCopy\n\n\n", lcn);
+
+
+    fprintf (src, "// alloc new list elmt, insert it after the\n");
+    fprintf (src, "// current element, copy given elmt in to new elmt\n");
+    fprintf (src, "//  and return the component type\n");
+    fprintf (src, "// if the current element is null, the new element\n");
+    fprintf (src, "// is placed at the end of the list.\n");
+    fprintf (src, "%s  &%s::InsertAfterAndCopy (%s &elmt)\n", lcn, lcn, ecn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *newElmt;\n");
+    fprintf (src, "\n");
+    fprintf (src, "    newElmt  = new AsnListElmt;\n");
+    fprintf (src, "    newElmt->elmt = new %s;\n", ecn);
+    fprintf (src, "    *newElmt->elmt = elmt;\n");
+    fprintf (src, "    if (curr == NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->prev = last;\n");
+    fprintf (src, "        newElmt->next = NULL;\n");
+    fprintf (src, "        last = newElmt;\n");
+    fprintf (src, "        if (first == NULL)\n");
+    fprintf (src, "            first = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    else\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        newElmt->prev = curr;\n");
+    fprintf (src, "        newElmt->next = curr->next;\n");
+    fprintf (src, "        curr->next = newElmt;\n");
+    fprintf (src, "        if (curr == last)\n");
+    fprintf (src, "            last = newElmt;\n");
+    fprintf (src, "        else\n");
+    fprintf (src, "            newElmt->next->prev = newElmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "    count++;\n");
+    fprintf (src, "    return *this;\n");
+    fprintf (src, "} // %s::InsertAfterAndCopy\n\n\n", lcn);
+
+
+    fprintf (src, "// remove current element from list if current element is not NULL \n");
+    fprintf (src, "// The new current element will be the next element.\n");
+    fprintf (src, "// If the current element is the last element in the list\n");
+    fprintf (src, "// the second but last element will become the new current element.\n");
+    fprintf (src, "void %s::RemoveCurrFromList()\n", lcn);
+    fprintf (src, "{\n");
+    fprintf (src, "    AsnListElmt *del_elmt;\n");
+    fprintf (src, "\n");
+    fprintf (src, "    if (curr != NULL)\n");
+    fprintf (src, "    {\n");
+    fprintf (src, "        del_elmt = curr;\n");
+    fprintf (src, "        count--;\n");
+    fprintf (src, "\n");
+    fprintf (src, "        if (count == 0)\n");
+    fprintf (src, "            first = last = curr = NULL;\n");
+    fprintf (src, "        else if (curr == first)\n");
+    fprintf (src, "        {\n");
+    fprintf (src, "            curr = first= first->next;\n");
+    fprintf (src, "            first->prev = NULL;\n");
+    fprintf (src, "        }\n");
+    fprintf (src, "        else if (curr == last)\n");
+    fprintf (src, "        {\n");
+    fprintf (src, "            curr = last = last->prev;\n");
+    fprintf (src, "            last->next = NULL;\n");
+    fprintf (src, "        }\n");
+    fprintf (src, "        else\n");
+    fprintf (src, "        {\n");
+    fprintf (src, "            curr->prev->next = curr->next;\n");
+    fprintf (src, "            curr->next->prev = curr->prev;\n");
+    fprintf (src, "        }\n");
+    fprintf (src, "\n");
+    fprintf (src, "        delete del_elmt->elmt;\n");
+    fprintf (src, "        delete del_elmt;\n");
+    fprintf (src, "    }\n");
+    fprintf (src, "}\n\n\n");
+
+    if (printEncodersG)
+    {
+        fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, lcn, r->encodeContentBaseName, bufTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "    AsnListElmt *currElmt;\n");
+        fprintf (src, "    %s elmtLen;\n", lenTypeNameG);
+        fprintf (src, "    %s totalLen = 0;\n", lenTypeNameG);
+
+#ifdef VDADER_RULES
+    if (gVDADER_RULES && lst->basicType->choiceId != BASICTYPE_SETOF)
+    {
+#endif
+        fprintf (src, "    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)\n");
+        fprintf (src, "    {\n");
+        /* encode Eoc (s) if nec */
+        PrintCxxEocEncoders (src, td, lst->basicType->a.setOf, "b");
+
+        tmpTypeId = GetBuiltinType (lst->basicType->a.setOf);
+        /* list element types cannot by ANY DEFINED BY */
+        if (tmpTypeId == BASICTYPE_ANY)
+        {
+            fprintf (src, "        currElmt->elmt->SetTypeBy???(???);\n");
+            fprintf (src, "        elmtLen = currElmt->elmt->B%s (b);\n", r->encodeBaseName);
+        }
+        else
+        {
+            fprintf (src, "        elmtLen = currElmt->elmt->B%s (b);\n", r->encodeContentBaseName);
+        }
+
+        /* encode list elmt tag/len pairs here */
+        PrintCxxTagAndLenEncodingCode (src, td, lst->basicType->a.setOf, "elmtLen", "b");
+
+        fprintf (src, "        totalLen += elmtLen;\n");
+        fprintf (src, "    }\n");
+
+#ifdef VDADER_RULES
+	}
+    /** handling of SET OF encoding
+     **/
+    else if (gVDADER_RULES && lst->basicType->choiceId == BASICTYPE_SETOF)
+		VDA_ProcessSetOf(src, td, lst, r);
+#endif
+
+        fprintf (src, "    return totalLen;\n");
+        fprintf (src, "} // %s::B%s\n\n\n", lcn, r->encodeContentBaseName);
+    } /** END IF for printDecodersG **/
+
+    if (printDecodersG)
+    {
+        fprintf (src, "void  %s::B%s (%s b, %s /*tag0*/, %s elmtLen0,\n", lcn, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG);
+        fprintf (src, "                                  %s &bytesDecoded, %s env)\n", lenTypeNameG, envTypeNameG);
+        fprintf (src, "{\n");
+        fprintf (src, "    %s *listElmt;\n", ecn);
+
+#ifdef VDADER_RULES 
+        tmpTypeId = GetBuiltinType (lst->basicType->a.setOf);
+
+        if ( tmpTypeId != BASICTYPE_ANY ||  ! gVDADER_RULES )
+           fprintf (src, "    %s tag1;\n", tagTypeNameG);
+#endif
+
+        fprintf (src, "    %s listBytesDecoded = 0;\n", lenTypeNameG);
+
+        /* print local vars elmtLen for decoding list component */
+        elmtLevel = CxxCountVariableLevels (lst->basicType->a.setOf);
+
+        for (i = 1; i <= elmtLevel; i++)
+            fprintf (src, "    %s elmtLen%d;\n", lenTypeNameG, i);
+
+        fprintf (src, "\n");
+
+
+        fprintf (src, "    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))\n");
+        fprintf (src, "    {\n");
+
+#ifdef VDADER_RULES
+        /* decode content */
+        /* note: cannot be ANY DEFINED BY as SET OF/SEQ OF ELMT */
+        if ( tmpTypeId != BASICTYPE_ANY ||  ! gVDADER_RULES)  /** RWC; 4/98 **/
+        {
+#endif
+
+
+        fprintf (src, "        tag1 = BDecTag (b, listBytesDecoded, env);\n");
+
+        fprintf (src, "        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))\n");
+        fprintf (src, "        {\n");
+        fprintf (src, "            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);\n");
+        fprintf (src, "            break;\n");
+        fprintf (src, "        }\n");
+
+        PrintCxxListTagAndLenDecCode (src, td, lst->basicType->a.setOf);
+
+        fprintf (src, "        listElmt = Append();\n");
+
+#ifdef VDADER_RULES
+        fprintf (src, "        listElmt->B%s (b, tag1, elmtLen%d, listBytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel);
+
+        }
+        else
+        {
+           fprintf (src, "        listElmt = Append();\n");
+#else
+        /* decode content */
+        tmpTypeId = GetBuiltinType (lst->basicType->a.setOf);
+        /* note: cannot be ANY DEFINED BY as SET OF/SEQ OF ELMT */
+        if (tmpTypeId == BASICTYPE_ANY)
+        {
+#endif
+
+#ifdef VDADER_RULES
+if (!gVDADER_RULES)
+{
+#endif
+            fprintf (src, "        listElmt->SetTypeBy???(???);\n");
+
+            fprintf (src, "        listElmt->B%s (b, listBytesDecoded, env);\n", r->decodeBaseName, elmtLevel);
+
+#ifdef VDADER_RULES
+}
+else
+            {
+                fprintf (src, "        DEC_LOAD_ANYBUF(");
+                fprintf (src, "listElmt, b, listBytesDecoded, env);\n");
+            }
+        }  /* end of else */
+#else
+        }  /* end of if BASIC_ANY_TYPE */
+        else
+            fprintf (src, "        listElmt->B%s (b, tag1, elmtLen%d, listBytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel);
+#endif
+        /* grab any EOCs that match redundant, indef lengths */
+        for (i = elmtLevel-1; i > 0; i--)
+        {
+            fprintf (src, "        if (elmtLen%d == INDEFINITE_LEN)\n", i);
+            fprintf (src, "            BDecEoc (b, listBytesDecoded, env);\n");
+        }
+
+
+        fprintf (src, "    }\n\n"); /* end of while */
+
+        fprintf (src, "    bytesDecoded += listBytesDecoded;\n");
+
+        fprintf (src, "} // %s::B%s\n\n\n", lcn, r->decodeContentBaseName);
+    }
+
+} /* PrintCxxListMethods */
+
+static void
+PrintCxxSetOfDefCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, setOf, novolatilefuncs),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    if_IBM_ENC (FILE *srcdb _AND_)
+    if_IBM_ENC (FILE *hdrdb _AND_)
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *setOf _AND_
+    int novolatilefuncs)
+{
+    /* do class */
+    PrintCxxListClass (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, setOf);
+
+    /* do methods */
+    PrintCxxListMethods (src, hdr, mods, m, r, td, parent, setOf, novolatilefuncs);
+
+} /* PrintCxxSetOfDefCode */
+
+
+static void
+PrintCxxAnyDefCode PARAMS ((src, hdr, mods, m, r, td, parent, any),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *any)
+{
+    fprintf (hdr, "/* ");
+    SpecialPrintType (hdr, td, td->type);
+    fprintf (hdr, " */\n");
+    fprintf (hdr, "typedef %s %s;\n\n", td->type->cxxTypeRefInfo->className, td->cxxTypeDefInfo->className);
+} /* PrintCxxAnyDefCode */
+
+
+static void
+PrintCxxTypeDefCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, novolatilefuncs),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    if_IBM_ENC (FILE *srcdb _AND_)
+    if_IBM_ENC (FILE *hdrdb _AND_)
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    int novolatilefuncs)
+{
+    CNamedElmt *n;
+
+    switch (td->type->basicType->choiceId)
+    {
+        case BASICTYPE_BOOLEAN:  /* library type */
+        case BASICTYPE_REAL:  /* library type */
+        case BASICTYPE_OCTETSTRING:  /* library type */
+        case BASICTYPE_NULL:  /* library type */
+        case BASICTYPE_OID:  /* library type */
+        case BASICTYPE_INTEGER:  /* library type */
+        case BASICTYPE_BITSTRING:  /* library type */
+        case BASICTYPE_ENUMERATED:  /* library type */
+            PrintCxxSimpleDef (hdr, src, if_IBM_ENC (hdrdb COMMA srcdb COMMA) if_META (m COMMA) r, td);
+            break;
+
+        case BASICTYPE_SEQUENCEOF:  /* list types */
+        case BASICTYPE_SETOF:
+            PrintCxxSetOfDefCode (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, NULL, td->type, novolatilefuncs);
+            break;
+
+        case BASICTYPE_IMPORTTYPEREF:  /* type references */
+        case BASICTYPE_LOCALTYPEREF:
+            /*
+             * if this type has been re-tagged then
+             * must create new class instead of using a typedef
+             */
+            PrintCxxSimpleDef (hdr, src, if_IBM_ENC (hdrdb COMMA srcdb COMMA) if_META (m COMMA) r, td);
+            break;
+
+        case BASICTYPE_ANYDEFINEDBY:  /* ANY types */
+        case BASICTYPE_ANY:
+/*
+            fprintf (stderr, "  ANY types require modification. ");
+            fprintf (stderr, "  The source files will have a \" ANY - Fix Me! \" comment before related code.\n\n");
+*/
+            PrintCxxAnyDefCode (src, hdr, mods, m, r, td, NULL, td->type);
+            break;
+
+        case BASICTYPE_CHOICE:
+            PrintCxxChoiceDefCode (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, NULL, td->type, novolatilefuncs);
+            break;
+
+        case BASICTYPE_SET:
+            PrintCxxSetDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs);
+            break;
+
+        case BASICTYPE_SEQUENCE:
+            PrintCxxSeqDefCode (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, NULL, td->type, novolatilefuncs);
+            break;
+
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_SELECTION:
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_MACRODEF:
+        case BASICTYPE_MACROTYPE:
+            /* do nothing */
+            break;
+    }
+} /* PrintCxxTypeDefCode */
+
+void
+PrintCxxCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) if_META (printMeta COMMA meta COMMA meta_pdus COMMA) mods, m, r, longJmpVal, printTypes, printValues, printEncoders, printDecoders, printPrinters, printFree if_TCL (COMMA printTcl), novolatilefuncs),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    if_IBM_ENC (FILE *srcdb _AND_)
+    if_IBM_ENC (FILE *hdrdb _AND_)
+    if_META (MetaNameStyle printMeta _AND_)
+    if_META (const Meta *meta _AND_)
+    if_META (MetaPDU *meta_pdus _AND_)
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CxxRules *r _AND_
+    long int longJmpVal _AND_
+    int printTypes _AND_
+    int printValues _AND_
+    int printEncoders _AND_
+    int printDecoders _AND_
+    int printPrinters _AND_
+    int printFree
+    if_TCL (_AND_ int printTcl) _AND_
+    int novolatilefuncs)
+{
+    TypeDef *td;
+    ValueDef *vd;
+#ifdef _IBM_ENC_
+    char mm_name[40];
+#endif /* _IBM_ENC_ */
+
+    longJmpValG = longJmpVal;
+    printTypesG = printTypes;
+    printEncodersG = printEncoders;
+    printDecodersG = printDecoders;
+    printPrintersG = printPrinters;
+    printFreeG = printFree;
+#if META
+    printMetaG = printMeta;
+    meta_pdus_G = meta_pdus;
+#if TCL
+    printTclG = printTcl;
+#endif /* TCL */
+#endif /* META */
+
+    PrintSrcComment (src, m);
+    PrintHdrComment (hdr, m);
+#ifdef _IBM_ENC_
+    PrintSrcComment (srcdb, m);   /* 20.8.93 IBM-ENC */
+    PrintHdrComment (hdrdb, m);   /* 20.8.93 IBM-ENC */
+
+    strcpy (mm_name, m->cxxHdrFileName);
+#endif /* _IBM_ENC_ */
+
+    PrintConditionalIncludeOpen (hdr, m->cxxHdrFileName);
+
+#ifdef _IBM_ENC_
+    mm_name[strlen (mm_name)-2]='\0';
+    fprintf (hdrdb, "#ifndef _%sdb_h_\n", mm_name);
+    fprintf(hdrdb, "#define _%sdb_h_\n", mm_name);
+#endif /* _IBM_ENC_ */
+
+#if META
+    if (printMetaG)
+    {
+	fprintf (src, "\n");
+	fprintf (src, "#ifndef META\n");
+	fprintf (src, "#define META	1\n");
+	fprintf (src, "#endif\n");
+#if TCL
+	if (printTclG)
+	{
+	    fprintf (src, "#ifndef TCL\n");
+	    fprintf (src, "#define TCL	META\n");
+	    fprintf (src, "#endif\n");
+	}
+#endif /* TCL */
+    }
+#endif /* META */
+
+    fprintf (src, "\n");
+
+    PrintSrcIncludes (src, if_IBM_ENC (srcdb COMMA) mods, m);
+
+    fprintf (src, "\n");
+
+    fprintf (hdr, "//------------------------------------------------------------------------------\n");
+    fprintf (hdr, "// class declarations:\n\n");
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+        PrintTypeDecl (hdr, td);
+    fprintf (hdr, "\n");
+
+#if META
+    if (printMeta)
+    {
+	fprintf (hdr, "#if META\n");
+	fprintf (src, "#if META\n\n");
+
+	fprintf (hdr, "//------------------------------------------------------------------------------\n");
+	fprintf (hdr, "extern const AsnModuleDesc %sModuleDesc;\n", m->cxxname);
+
+	fprintf (src, "//------------------------------------------------------------------------------\n");
+	fprintf (src, "static const AsnTypeDesc *%sModuleTypes[] =\n", m->cxxname);
+	fprintf (src, "{\n");
+	FOR_EACH_LIST_ELMT (td, m->typeDefs)
+	    fprintf (src, "  &%s::_desc,\n", td->cxxTypeDefInfo->className);
+	fprintf (src, "  NULL\n");
+	fprintf (src, "};\n\n");
+#if 0 /* yet unused: */
+	if (printMetaG == META_backend_names)
+	else /* META_asn1_names */
+#endif
+	    fprintf (src, "const AsnModuleDesc %sModuleDesc = { \"%s\", %sModuleTypes };\n\n", m->cxxname, m->modId->name, m->cxxname);
+
+	fprintf (hdr, "#endif // META\n\n");
+	fprintf (src, "#endif // META\n\n");
+    }
+#endif /* META */
+
+    if (printValues)
+    {
+	fprintf (src, "//------------------------------------------------------------------------------\n");
+        fprintf (src, "// value defs\n\n");
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+            PrintCxxValueDef (src, r, vd);
+        fprintf (src, "\n");
+    }
+
+    fprintf (hdr, "//------------------------------------------------------------------------------\n");
+    fprintf (hdr, "// class definitions:\n\n");
+    fprintf (src, "//------------------------------------------------------------------------------\n");
+    fprintf (src, "// class member definitions:\n\n");
+
+    PrintCxxAnyCode (src, hdr, r, mods, m);
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+        PrintCxxTypeDefCode (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, novolatilefuncs);
+
+    if (printValues)
+    {
+	fprintf (hdr, "//------------------------------------------------------------------------------\n");
+        fprintf (hdr, "// externs for value defs\n\n");
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+            PrintCxxValueExtern (hdr, r, vd);
+    }
+
+    fprintf (hdr, "//------------------------------------------------------------------------------\n");
+    PrintConditionalIncludeClose (hdr, m->cxxHdrFileName);
+
+#ifdef _IBM_ENC_
+    fprintf (hdrdb, "#endif\n");
+#endif /* _IBM_ENC_ */
+} /* PrintCxxCode */
+
+
+#ifdef VDADER_RULES
+
+/* this routine will generate code which will encode a SET OF in using DER
+ * rules.
+ */
+long VDA_ProcessSetOf(FILE *src,
+    TypeDef *td,
+    Type *lst,
+	CxxRules *r)
+{
+    enum BasicTypeChoiceId tmpTypeId;
+
+ 
+        fprintf (src, "    {\n");
+        fprintf (src, "      int iii,icount;\n      CSM_Buffer **tmpEnc=NULL;\n");
+        fprintf (src, "      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);\n");
+        fprintf (src, "      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);\n");
+        fprintf (src, "      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)\n");
+        fprintf (src, "      {\n");
+        /* encode Eoc (s) if nec */
+        PrintCxxEocEncoders (src, td, lst->basicType->a.setOf, "b");
+
+        tmpTypeId = GetBuiltinType (lst->basicType->a.setOf);
+
+        /* list element types cannot by ANY DEFINED BY */
+        if (tmpTypeId == BASICTYPE_ANY)
+        {
+            fprintf (src, "        tmpEnc[iii] = (CSM_Buffer *)currElmt->elmt->value;\n");
+        }
+        else
+        {   /** SEE "smimesnacc.h" for a description of these ODD macros, to
+             ** save space.
+             **/
+            fprintf (src, "        ENCODE_BUF1(currElmt->elmt->B%s, elmtLen);\n", r->encodeContentBaseName);
+
+            /** encode content only into buffer. 
+             **/
+            PrintCxxTagAndLenEncodingCode (src, td, lst->basicType->a.setOf,
+                                           "elmtLen", "outputBuf");
+
+            /** set tag and length in "outputBuf" buffer (DEFINED IN MACRO).
+             **/
+            fprintf (src, "        ENCODE_BUF2(tmpEnc[iii]);\n");
+
+            /** extract buffer to "Str_struct *".
+             **/
+        }
+        fprintf (src, "      }\n");
+
+        /* encode list elmt tag/len pairs here */
+
+        /** NOW, we have a list of icount "CSM_Buffer"s, which are the ASN.1 
+         ** encoded results of all of the specified "SET OF" components here.
+         ** THESE MUST be re-ordered in ascending order for proper DER 
+         ** Encoding Rule encoding.
+         **/
+
+        fprintf (src, "      vdasnacc_sortSetOf(tmpEnc, icount);\n");
+        /** These "SET OF" components are now ordered in ascending order, 
+         ** ready to be loaded into the output buffer. (RWC; TBD; make output 
+         ** buffers accept these allocated buffers directly, no copy). 
+         **/
+
+        fprintf (src, "      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())\n");
+        fprintf (src, "            SM_WriteToAsnBuf(tmpEnc[iii], b);\n");
+        /**fprintf (src, "            b.PutSegRvs((char *)tmpEnc[iii]->str, tmpEnc[iii]->lgth);\n");**/
+        if (tmpTypeId != BASICTYPE_ANY)  /** FREE resources loaded here. **/
+          fprintf (src, "      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];\n");
+        fprintf (src, "       free(tmpEnc);\n");
+        fprintf (src, "    }\n");
+        fprintf (src, "        totalLen += elmtLen;\n");
+
+		return(0);
+} /** END else BASICTYPE_SETOF, RWC; only for VDADER_RULES define **/
+
+#endif
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.h b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.h
new file mode 100644
index 00000000..dc1a054a
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/gen_code.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-code.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:40  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.6  1997/02/16 15:14:10  rj
+ * made return *this after calling abort()'' a compile time option.
+ *
+ * Revision 1.5  1995/09/07  19:18:25  rj
+ * boolean genMeta changed to enum type MetaNameStyle
+ *
+ * Revision 1.4  1995/08/17  15:00:08  rj
+ * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted)
+ *
+ * Revision 1.3  1995/07/27  10:53:03  rj
+ * file name has been shortened for redundant part: c++-gen/gen-c++-code -> c++-gen/gen-code.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:47:55  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:04  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+void PrintCxxCode PROTO ((FILE *src, FILE *hdr, if_IBM_ENC (FILE *dbsrc COMMA FILE *dbhdr COMMA) if_META (MetaNameStyle genMeta COMMA const Meta *meta COMMA MetaPDU *metapdus COMMA) ModuleList *mods, Module *m, CxxRules *r, long int longJmpVal, int printTypes, int printValues, int printEncoders, int printDecoders, int printPrinters, int printFree, if_TCL (int printTcl COMMA) int novolatilefuncs));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.c b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.c
new file mode 100644
index 00000000..2b67a8cb
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.c
@@ -0,0 +1,325 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/gen_vals.c - prints ASN.1 values in c++ format
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.c,v 1.3 2001/06/25 21:51:10 dmitch Exp $
+ * $Log: gen-vals.c,v $
+ * Revision 1.3  2001/06/25 21:51:10  dmitch
+ * Avoid instantiating AsnInt constants; use #define instead. Partial fix for Radar 2664258.
+ *
+ * Revision 1.2  2001/06/20 21:30:32  dmitch
+ * Per SNACC_OIDS_AS_DEFINES #define, optionally define OIDs as #defines in the header rather than as statically initialized objects in the .cpp file.
+ *
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:40  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:20:05  rj
+ * use true/false instead of AsnBool::true/false.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:47:57  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:17:22  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:05  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "oid.h"
+#include "mem.h"
+#include "define.h"
+#include "lib-types.h"
+#include "str-util.h"
+#include "snacc-util.h"
+#include "rules.h"
+#include "gen-vals.h"
+
+/* non-exported routines' prototypes */
+
+static void PrintCxxValueDefsName PROTO ((FILE *f, CxxRules *r, ValueDef *v));
+
+
+
+
+void
+PrintCxxValueDef PARAMS ((src, r, v),
+    FILE *src _AND_
+    CxxRules *r _AND_
+    ValueDef *v)
+{
+    /* just do oid's, ints and bools for now */
+    if (
+		#if		!SNACC_OIDS_AS_DEFINES
+		(v->value->basicValue->choiceId != BASICVALUE_OID) &&
+		#endif	/* SNACC_OIDS_AS_DEFINES */
+		#if		!SNACC_INTS_AS_DEFINES
+        (v->value->basicValue->choiceId != BASICVALUE_INTEGER) &&
+		#endif	/* !SNACC_INTS_AS_DEFINES */
+        (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN))
+        return;
+
+    /*
+     * put instantiation in src file
+     */
+    fprintf (src, "const ");
+    PrintCxxValuesClass (src, r, v->value);
+    fprintf (src, " ");
+    PrintCxxValueDefsName (src, r, v);
+    fprintf (src, " ");
+    PrintCxxValueInstatiation (src, r, v->value);
+    fprintf (src, ";\n\n");
+
+
+}  /* PrintCxxValueDef */
+
+void
+PrintCxxValueExtern PARAMS ((hdr, r, v),
+    FILE *hdr _AND_
+    CxxRules *r _AND_
+    ValueDef *v)
+{
+    /* just do oid's, ints and bools for now */
+    if ((v->value->basicValue->choiceId != BASICVALUE_OID) &&
+        (v->value->basicValue->choiceId != BASICVALUE_INTEGER) &&
+        (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN))
+        return;
+
+	#if		SNACC_OIDS_AS_DEFINES
+	/*
+	 * Special case for OIDs. The format is 
+	 *
+	 *   #define oidname_arc  x,y,z,...
+	 *   #define oidname AsnOid(oidname_arc)
+	 */
+    if (v->value->basicValue->choiceId == BASICVALUE_OID) {
+		/* first just the arc */
+		fprintf (hdr, "#define ");
+		PrintCxxValueDefsName (hdr, r, v);
+		fprintf (hdr, "_arc ");
+		PrintCxxValueInstatiation (hdr, r, v->value);
+		fprintf (hdr, "\n");
+		
+		/* now the declaration using the arc */
+		fprintf (hdr, "#define ");
+		PrintCxxValueDefsName (hdr, r, v);
+		fprintf (hdr, "     ");
+		PrintCxxValuesClass (hdr, r, v->value);
+		fprintf (hdr, "(");
+		PrintCxxValueDefsName (hdr, r, v);
+		fprintf (hdr, "_arc)\n");
+
+		return;
+	}
+	#endif	/* SNACC_OIDS_AS_DEFINES */
+	
+	#if		SNACC_INTS_AS_DEFINES
+	/*
+	 * Special case for AsnInt. The format is 
+	 *
+	 *   #define oidname_val  x
+	 *   #define oidname AsnInt(oidname_val)
+	 */
+    if (v->value->basicValue->choiceId == BASICVALUE_INTEGER) {
+		/* first just the integer value */
+		fprintf (hdr, "#define ");
+		PrintCxxValueDefsName (hdr, r, v);
+		fprintf (hdr, "_val %d\n", v->value->basicValue->a.integer);
+		
+		/* now the declaration using the val */
+		fprintf (hdr, "#define ");
+		PrintCxxValueDefsName (hdr, r, v);
+		fprintf (hdr, "     ");
+		PrintCxxValuesClass (hdr, r, v->value);
+		fprintf (hdr, "(");
+		PrintCxxValueDefsName (hdr, r, v);
+		fprintf (hdr, "_val)\n");
+
+		return;
+	}
+	#endif	/* SNACC_OIDS_AS_DEFINES */
+
+    /*
+     * put extern declaration in hdr file
+     */
+    fprintf (hdr, "extern const ");
+    PrintCxxValuesClass (hdr, r, v->value);
+    fprintf (hdr, " ");
+    PrintCxxValueDefsName (hdr, r, v);
+    fprintf (hdr, ";\n");
+
+}  /* PrintCxxValueExtern */
+
+
+static void
+PrintCxxValueDefsName PARAMS ((f, r, v),
+    FILE *f _AND_
+    CxxRules *r _AND_
+    ValueDef *v)
+{
+    char *cName;
+    cName = Asn1ValueName2CValueName (v->definedName);
+    fprintf (f, "%s", cName);
+    Free (cName);
+}
+
+void
+PrintCxxValuesClass PARAMS ((f, r, v),
+    FILE *f _AND_
+    CxxRules *r _AND_
+    Value *v)
+{
+    /* needs work - just do ints bools and oid's for now */
+    switch (v->basicValue->choiceId)
+    {
+        case BASICVALUE_OID:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_OID].className);
+            break;
+
+        case BASICVALUE_INTEGER:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_INTEGER].className);
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_BOOLEAN].className);
+            break;
+
+        default:
+           break;
+    }
+}
+
+
+void
+PrintCxxValueInstatiation PARAMS ((f, r, v),
+    FILE *f _AND_
+    CxxRules *r _AND_
+    Value *v)
+{
+    /* needs work - just do oids, ints and bools for now */
+    switch (v->basicValue->choiceId)
+    {
+        case BASICVALUE_OID:
+            PrintCxxOidValue (f, r, v->basicValue->a.oid);
+            break;
+
+        case BASICVALUE_INTEGER:
+            PrintCxxIntValue (f, r, v->basicValue->a.integer);
+            break;
+
+        case BASICVALUE_BOOLEAN:
+	    fprintf (f, "(%s)", v->basicValue->a.boolean ? "true" : "false");
+            break;
+
+        default:
+           break;
+    }
+}
+
+
+
+/*
+ * given an AOID, c++ AOID constructors params are produced.
+ * This is used for turning ASN.1 OBJECT ID values
+ * into usable c++ values.
+ *
+ * eg for the oid { 0 1 2 } (in AOID format)
+ *   (0,1,2)
+ * is produced.
+ *
+ * The parentheses are omitted in the SNACC_OIDS_AS_DEFINES case; we're just printing
+ * the arc which can be used as an arg elsewhere. 
+
+ */
+void
+PrintCxxOidValue PARAMS ((f, r, v),
+    FILE *f _AND_
+    CxxRules *r _AND_
+    AsnOid *v)
+{
+    unsigned short int firstArcNum;
+    unsigned long int arcNum;
+    int i;
+
+	#if !SNACC_OIDS_AS_DEFINES
+    fprintf (f, "(");
+	#endif
+	
+    /* un-munge first two arc numbers */
+    for (arcNum = 0, i=0; (i < v->octetLen) && (v->octs[i] & 0x80);i++)
+        arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+
+    arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+    i++;
+    firstArcNum = arcNum/40;
+    if (firstArcNum > 2)
+        firstArcNum = 2;
+
+    fprintf (f, "%u, %u", firstArcNum, arcNum - (firstArcNum * 40));
+
+    for (; i < v->octetLen; )
+    {
+        for (arcNum = 0; (i < v->octetLen) && (v->octs[i] & 0x80);i++)
+            arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+
+        arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+        i++;
+
+        fprintf (f, ", %u", arcNum);
+    }
+	
+	#if	!SNACC_OIDS_AS_DEFINES
+    fprintf (f, ")");
+	#endif
+
+} /* PrintCxxOidValue */
+
+
+
+void
+PrintCxxIntValue PARAMS ((f, r, v),
+    FILE *f _AND_
+    CxxRules *r _AND_
+    AsnInt v)
+{
+    fprintf (f, "(%d)", v);
+} /* PrintCxxIntValue */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.h b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.h
new file mode 100644
index 00000000..66ab1fd5
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/gen_vals.h
+ *
+ * MS 92
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-vals.h,v 1.3 2001/06/25 21:51:10 dmitch Exp $
+ * $Log: gen-vals.h,v $
+ * Revision 1.3  2001/06/25 21:51:10  dmitch
+ * Avoid instantiating AsnInt constants; use #define instead. Partial fix for Radar 2664258.
+ *
+ * Revision 1.2  2001/06/20 21:30:32  dmitch
+ * Per SNACC_OIDS_AS_DEFINES #define, optionally define OIDs as #defines in the header rather than as statically initialized objects in the .cpp file.
+ *
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:40  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:23:19  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:47:58  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:06  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+/*
+ * When true, compile OIDs as #defines in the header, not as 
+ * statically declared constants.
+ */
+#define SNACC_OIDS_AS_DEFINES	1
+
+/*
+ * When true, compile AsnInts as #defines in the header, not as 
+ * statically declared constants.
+ */
+#define SNACC_INTS_AS_DEFINES	1
+
+
+void PrintCxxValueDef PROTO ((FILE *src, CxxRules *r, ValueDef *v));
+
+void PrintCxxValueExtern PROTO ((FILE *hdr, CxxRules *r, ValueDef *v));
+
+void PrintCxxValuesClass PROTO ((FILE *f, CxxRules *r, Value *v));
+
+void PrintCxxValueInstatiation PROTO ((FILE *f, CxxRules *r, Value *v));
+
+void PrintCxxOidValue PROTO ((FILE *f, CxxRules *r, AsnOid *oid));
+
+void PrintCxxIntValue PROTO ((FILE *f, CxxRules *r, AsnInt oid));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.c b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.c
new file mode 100644
index 00000000..e9b9fdcd
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.c
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/kwd.c - routines for determining whether a given str is a C++
+ *             keyword
+ *
+ *    NOTE: this was hacked up really quickly.  It uses a slow linear
+ *          search. A much better approach is to use a hash tbl.
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: kwd.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:40  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.7  1995/09/07 19:05:01  rj
+ * where the C++ compiler has got the bool type built-in, let the C++ backend avoid conflicts with the new keywords.
+ *
+ * Revision 1.6  1995/08/17  14:56:12  rj
+ * bool added to the list of reserved words
+ *
+ * Revision 1.5  1995/07/25  18:22:40  rj
+ * file name has been shortened for redundant part: c++-gen/c++-kwd -> c++-gen/kwd.
+ *
+ * Revision 1.4  1995/02/17  20:10:40  rj
+ * inclusion order fixed.
+ *
+ * Revision 1.3  1994/10/08  03:48:04  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:19:44  rj
+ * snacc_config.h removed; more portable .h file inclusion.
+ *
+ * Revision 1.1  1994/08/28  09:48:11  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "snacc.h"
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include "kwd.h"
+
+/*
+ * last elmt will be NULL.
+ * key words grabbed from C++/Stroustrup 2.0
+ */
+static char *cxxKWdG[] =
+{
+    "asm", "auto", "break", "case", "catch", "char", "class", "const",
+    "continue", "default", "delete", "do", "double", "else", "enum",
+    "extern", "float", "for", "friend", "goto", "if", "inline", "int",
+    "long", "new", "operator", "private", "protected", "public",
+    "register", "return", "short", "signed", "sizeof", "static",
+    "struct", "switch", "template", "this", "throw", "try", "typedef",
+    "union", "unsigned", "virtual", "void", "volatile", "while",
+#if BOOL_BUILTIN
+    "bool", "true", "false",
+#endif
+    NULL
+};
+
+
+/*
+ * returns non-zero if the given str is a C++ key word
+ */
+int
+IsCxxKeyWord PARAMS ((str),
+    char *str)
+{
+    int i;
+
+    for (i=0; (cxxKWdG[i] != NULL) && (strcmp (cxxKWdG[i],str) != 0); i++)
+	;
+
+    return cxxKWdG[i] != NULL;
+}
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.h b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.h
new file mode 100644
index 00000000..decd701c
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/kwd.h - routines for determining whether a given str is a C++ keyword
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/kwd.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: kwd.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:40  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:22:41  rj
+ * file name has been shortened for redundant part: c++-gen/c++-kwd -> c++-gen/kwd.
+ *
+ * Revision 1.2  1994/10/08  03:48:05  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:12  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+int IsCxxKeyWord PROTO ((char *str));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.c b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.c
new file mode 100644
index 00000000..d5c449dc
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.c
@@ -0,0 +1,366 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/rules.c - initialized c rule structure
+ *           inits a table that contains info about
+ *           converting each ASN.1 type to a C++ class
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: rules.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:40  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:24:13  rj
+ * file name has been shortened for redundant part: c++-gen/c++-rules -> c++-gen/rules.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:47:49  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  01:53:33  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:47:54  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "rules.h"
+
+
+CxxRules cxxRulesG =
+{
+    4,
+    "choiceId",
+    "ChoiceIdEnum",
+    "a",
+    "ChoiceUnion",
+    FALSE,
+    "Enc",
+    "Dec",
+    "EncContent",
+    "DecContent",
+    "EncPdu",
+    "DecPdu",
+    {
+        {
+            BASICTYPE_UNKNOWN,
+            "???",
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "unknown"
+        },
+        {
+            BASICTYPE_BOOLEAN,
+            "AsnBool",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bool"
+        },
+        {
+            BASICTYPE_INTEGER,
+            "AsnInt",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "integer"
+        },
+        {
+            BASICTYPE_BITSTRING,
+            "AsnBits",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bits"
+        },
+        {
+            BASICTYPE_OCTETSTRING,
+            "AsnOcts",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "octs"
+        },
+        {
+            BASICTYPE_NULL,
+            "AsnNull",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "null"
+        },
+        {
+            BASICTYPE_OID,
+            "AsnOid",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "oid"
+        },
+        {
+            BASICTYPE_REAL,
+            "AsnReal",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "real"
+        },
+        {
+            BASICTYPE_ENUMERATED,
+            "AsnEnum",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "enumeration"
+        },
+        {
+            BASICTYPE_SEQUENCE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "seq"
+        },
+        {
+            BASICTYPE_SEQUENCEOF,
+            "AsnList",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "seqOf"
+        },
+        {
+            BASICTYPE_SET,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            FALSE,
+            "NOT_NULL",
+            "set"
+        },
+        {
+            BASICTYPE_SETOF,
+            "AsnList",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "setOf"
+        },
+        {
+            BASICTYPE_CHOICE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            FALSE,
+            "NOT_NULL",
+            "choice"
+        },
+        {
+            BASICTYPE_SELECTION,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "foo"
+        },
+        {
+            BASICTYPE_COMPONENTSOF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bar"
+        },
+        {
+            BASICTYPE_ANY,
+            "AsnAny",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "any"
+        },
+        {
+            BASICTYPE_ANYDEFINEDBY,
+            "AsnAnyDefinedBy",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "anyDefBy"
+        },
+        {
+            BASICTYPE_LOCALTYPEREF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "foo"
+        },
+        {
+            BASICTYPE_IMPORTTYPEREF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bar"
+        },
+        {
+            BASICTYPE_MACROTYPE,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "foo"
+        },
+        {
+            BASICTYPE_MACRODEF,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "foo"
+        }
+    }
+};
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.h b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.h
new file mode 100644
index 00000000..4eaf797b
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/rules.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: rules.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:40  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:24:21  rj
+ * file name has been shortened for redundant part: c++-gen/c++-rules -> c++-gen/rules.
+ *
+ * Revision 1.2  1994/10/08  03:47:50  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:47:55  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+/* see asn1module.h for CxxTDI (C++ type def info) */
+
+typedef struct CxxRules
+{
+    int  maxDigitsToAppend;
+    char *choiceIdFieldName;   /* name of choiceId field */
+    char *choiceIdEnumName;  /* name (tag) for choiceId enum def name */
+    char *choiceUnionFieldName; /* what the name of the choice's union is */
+    char *choiceUnionName;  /* name (tag) for choice union def name */
+    int   capitalizeNamedElmts;
+    char *encodeBaseName;
+    char *decodeBaseName;
+    char *encodeContentBaseName;
+    char *decodeContentBaseName;
+    char *encodePduBaseName;
+    char *decodePduBaseName;
+    CxxTDI typeConvTbl[BASICTYPE_MACRODEF + 1];
+}  CxxRules;
+
+extern CxxRules cxxRulesG;
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.c b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.c
new file mode 100644
index 00000000..afc9b5e3
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.c
@@ -0,0 +1,677 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c++-gen/types.c  - fills in c++ type information
+ *
+ * MS 91/92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * INSERT_VDA_COMMENTS
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: types.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:40  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:25:11  rj
+ * file name has been shortened for redundant part: c++-gen/c++-types -> c++-gen/types.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:47:51  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  01:06:02  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:47:56  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "define.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "snacc-util.h"
+#include "str-util.h"
+#include "rules.h"
+#include "kwd.h"
+#include "types.h"
+
+extern Module *usefulTypeModG;
+static DefinedObj *definedNamesG;
+
+/* unexported prototypes */
+
+void FillCxxTypeDefInfo PROTO ((CxxRules *r,  Module *m,  TypeDef *td));
+
+static void FillCxxFieldNames PROTO ((CxxRules *r, NamedTypeList *firstSibling));
+
+static void FillCxxTypeRefInfo PROTO ((CxxRules *r,  Module *m,  TypeDef *head, Type *parent, Type *t));
+
+static void FillCxxStructElmts PROTO ((CxxRules *r,  Module *m,  TypeDef *head, Type *parent, NamedTypeList *t));
+
+static void FillCxxChoiceElmts PROTO ((CxxRules *r, Module *m, TypeDef *head, Type *parent, NamedTypeList *first));
+
+static int IsCxxPtr PROTO ((CxxRules *r, TypeDef *td, Type *parent, Type *t));
+
+void FillCxxTDIDefaults PROTO ((CxxRules *r, CxxTDI *ctdi, TypeDef *td));
+
+
+/*
+ *  allocates and fills all the cxxTypeInfos
+ *  in the type trees for every module in the list
+ */
+void
+FillCxxTypeInfo PARAMS ((r, modList),
+    CxxRules *r _AND_
+    ModuleList *modList)
+{
+    TypeDef *td;
+    Module *m;
+
+    /*
+     * go through each module's type defs and fill
+     * in the C type and enc/dec routines etc
+     */
+    definedNamesG = NULL;
+
+    /* do useful types first */
+    if (usefulTypeModG != NULL)
+    {
+        FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
+            FillCxxTypeDefInfo (r, usefulTypeModG, td);
+    }
+
+    FOR_EACH_LIST_ELMT (m, modList)
+    {
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+            FillCxxTypeDefInfo (r, m, td);
+    }
+
+    /*
+     * now that type def info is filled in
+     * set up set/seq/list/choice elements that ref
+     * those definitions
+     */
+
+    /* do useful types first */
+    if (usefulTypeModG != NULL)
+    {
+        FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
+            FillCxxTypeRefInfo (r, usefulTypeModG, td, NULL, td->type);
+    }
+
+    FOR_EACH_LIST_ELMT (m, modList)
+    {
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+            FillCxxTypeRefInfo (r, m, td, NULL, td->type);
+    }
+
+    /*
+     * modules compiled together (ie one call to snacc with
+     * multiple args) likely to be C compiled together so
+     * need a unique routines/types/defines/enum values
+     * since assuming they share same name space.
+     *  All Typedefs, union, struct & enum Tags, and defined values
+     * (enum consts), #define names
+     *  are assumed to share the same name space
+     */
+
+    /* done with checking for name conflicts */
+    FreeDefinedObjs (&definedNamesG);
+
+}  /* FillCxxTypeInfo */
+
+
+/*
+ *  allocates and fills structure holding C type definition information
+ *  fo the given ASN.1 type definition.  Does not fill CTRI for contained
+ *  types etc.
+ */
+void
+FillCxxTypeDefInfo PARAMS ((r, m, td),
+    CxxRules *r _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    int digit;
+    int len;
+    char *tmpName;
+    CxxTDI *cxxtdi;
+
+    /*
+     * if CxxTDI is present this type def has already been 'filled'
+     */
+    if (td->cxxTypeDefInfo != NULL)
+        return;
+
+
+    cxxtdi = MT (CxxTDI);
+    td->cxxTypeDefInfo = cxxtdi;
+
+    /* get default type def attributes from table for type on rhs of ::= */
+
+    FillCxxTDIDefaults (r, cxxtdi, td);
+
+
+    /*
+     * if defined by a ref to another type definition fill in that type
+     * def's CxxTDI so can inherit (actully completly replace default
+     * attributes) from it
+     */
+    if ((td->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+        (td->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+    {
+        /*
+         * Fill in CxxTDI for defining type if nec.
+         * this works for importTypeRef as well since both a.localTypeRef
+         * and a.importTypeRef are of type TypeRef
+         */
+        FillCxxTypeDefInfo (r, td->type->basicType->a.localTypeRef->module, td->type->basicType->a.localTypeRef->link);
+
+        tmpName = cxxtdi->className; /* save className */
+        /* copy all type def info and restore name related stuff - hack*/
+        *cxxtdi = *td->type->basicType->a.localTypeRef->link->cxxTypeDefInfo;
+        cxxtdi->className = tmpName; /* restore className */
+    }
+
+
+    /*
+     * check for any "--snacc" attributes that overide the current
+     * cxxtdi fields
+     * UNDEFINED FOR C++
+    ParseTypeDefAttribs (cxxtdi, td->attrList);
+    */
+
+}  /* FillCxxTypeDefInfo */
+
+
+static void
+FillCxxTypeRefInfo PARAMS ((r, m, head, parent, t),
+    CxxRules *r _AND_
+    Module *m _AND_
+    TypeDef *head _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    CxxTRI *cxxtri;
+    CxxTDI *tmpCxxtdi;
+    ValueDef *namedElmt;
+    CNamedElmt *cne;
+    CNamedElmt **cneHndl;
+    char       *elmtName;
+    char       *listName;
+    char       *choiceName;
+    char       *unionName;
+    Type *tmpT;
+    int         len, digit;
+    enum BasicTypeChoiceId basicTypeId;
+
+    /*
+     * you must check for cycles yourself before calling this
+     */
+    if (t->cxxTypeRefInfo == NULL)
+    {
+        cxxtri = MT (CxxTRI);
+        t->cxxTypeRefInfo = cxxtri;
+    }
+    else
+        cxxtri =  t->cxxTypeRefInfo;
+
+    basicTypeId = t->basicType->choiceId;
+
+    tmpCxxtdi = &r->typeConvTbl[basicTypeId];
+
+    /* get base type def info from the conversion table in the rules */
+    cxxtri->isEnc = tmpCxxtdi->isEnc;
+    cxxtri->className = tmpCxxtdi->className;
+    cxxtri->optTestRoutineName = tmpCxxtdi->optTestRoutineName;
+
+
+    /*
+     * convert named elmts to C++ names.
+     * check for name conflict with other defined Types/Names/Values
+     */
+    if (((basicTypeId == BASICTYPE_INTEGER) ||
+         (basicTypeId == BASICTYPE_ENUMERATED) ||
+         (basicTypeId == BASICTYPE_BITSTRING)) &&
+        !(LIST_EMPTY (t->basicType->a.integer)))
+    {
+        cxxtri->namedElmts = AsnListNew (sizeof (void*));
+        FOR_EACH_LIST_ELMT (namedElmt, t->basicType->a.integer)
+        {
+            cneHndl = (CNamedElmt**)AsnListAppend (cxxtri->namedElmts);
+            cne = *cneHndl = MT (CNamedElmt);
+            elmtName = Asn1ValueName2CValueName (namedElmt->definedName);
+            len = strlen (elmtName);
+            cne->name = Malloc (len + 1 + r->maxDigitsToAppend);
+            strcpy (cne->name, elmtName);
+            Free (elmtName); /* not very efficient */
+
+            if (namedElmt->value->basicValue->choiceId == BASICVALUE_INTEGER)
+                cne->value = namedElmt->value->basicValue->a.integer;
+            else
+            {
+                fprintf (stderr,"Warning: unlinked defined value. Using -9999999\n");
+                cne->value = -9999999;
+            }
+
+            if (r->capitalizeNamedElmts)
+                Str2UCase (cne->name, len);
+
+            /*
+             * append digits if enum value name is a keyword
+             */
+            MakeCxxStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1);
+           /*  not nec since each class hides the enum scope
+             DefineObj (&definedNamesG, cne->name); */
+        }
+    }
+
+    /* fill in rest of type info depending on the type */
+    switch (basicTypeId)
+    {
+        case BASICTYPE_BOOLEAN:  /* library types */
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_BITSTRING:
+        case BASICTYPE_OCTETSTRING:
+        case BASICTYPE_NULL:
+        case BASICTYPE_OID:
+        case BASICTYPE_REAL:
+        case BASICTYPE_ENUMERATED:
+            /* don't need to do anything else */
+            break;
+
+
+        case BASICTYPE_SEQUENCEOF:  /* list types */
+        case BASICTYPE_SETOF:
+            /* fill in component type */
+            FillCxxTypeRefInfo (r, m, head, t, t->basicType->a.setOf);
+            break;
+
+        case BASICTYPE_IMPORTTYPEREF:  /* type references */
+        case BASICTYPE_LOCALTYPEREF:
+            /*
+             * grab class name from link (link is the def of the
+             * the ref'd type)
+             */
+            if (t->basicType->a.localTypeRef->link != NULL)
+            {
+                /* inherit attributes from referenced type */
+                tmpCxxtdi=  t->basicType->a.localTypeRef->link->cxxTypeDefInfo;
+                cxxtri->className = tmpCxxtdi->className;
+                cxxtri->isEnc = tmpCxxtdi->isEnc;
+                cxxtri->optTestRoutineName = tmpCxxtdi->optTestRoutineName;
+            }
+
+            break;
+
+        case BASICTYPE_ANYDEFINEDBY:  /* ANY types */
+            break;  /* these are handled now */
+
+        case BASICTYPE_ANY:
+            PrintErrLoc (m->asn1SrcFileName, t->lineNo);
+#ifndef VDADER_RULES
+            fprintf (stderr,"Warning - generated code for the \"ANY\" type in type \"%s\" will need modification by YOU.", head->definedName);
+            fprintf (stderr,"  The source files will have a \"/* ANY - Fix Me! */\" comment before related code.\n\n");
+#else
+if (gVDADER_RULES)
+{
+            fprintf (stderr,"Warning - VDA Enchanced ANY processing being used.\n");
+}
+#endif
+            break;
+
+        case BASICTYPE_CHOICE:
+           /*
+            * must fill field names BEFORE filling choice elmts
+            * (allows better naming for choice ids)
+            */
+            FillCxxFieldNames (r, t->basicType->a.choice);
+            FillCxxChoiceElmts (r, m, head, t, t->basicType->a.choice);
+            break;
+
+        case BASICTYPE_SET:
+        case BASICTYPE_SEQUENCE:
+            FillCxxStructElmts (r, m, head, t, t->basicType->a.set);
+            FillCxxFieldNames (r, t->basicType->a.set);
+            break;
+
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_SELECTION:
+            fprintf (stderr,"Compiler error - COMPONENTS OF or SELECTION type slipped through normalizing phase.\n");
+            break;
+
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_MACRODEF:
+        case BASICTYPE_MACROTYPE:
+            /* do nothing */
+            break;
+
+    }
+
+    /*
+     * figure out whether this is a ptr based on the enclosing
+     * type (if any) and optionality/default
+     */
+    cxxtri->isPtr = IsCxxPtr (r, head, parent, t);
+
+    /* let user overide any defaults with the --snacc attributes */
+    /* undefined for C++ ParseTypeRefAttribs (ctri, t->attrList); */
+
+
+}  /* FillCxxTypeRefInfo */
+
+
+
+static void
+FillCxxStructElmts PARAMS ((r, m, head, parent, elmts),
+    CxxRules *r _AND_
+    Module *m _AND_
+    TypeDef *head _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts)
+{
+    NamedType *et;
+
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        FillCxxTypeRefInfo (r, m, head, parent, et->type);
+    }
+
+}  /* FillCxxStructElmts */
+
+
+
+/*
+ *  Figures out non-conflicting enum names for the
+ *  choice id's
+ */
+static void
+FillCxxChoiceElmts PARAMS ((r, m, head, parent, elmts),
+    CxxRules *r _AND_
+    Module *m _AND_
+    TypeDef *head _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts)
+{
+    NamedType *et;
+    int idCount = 0;
+    CxxTRI *cxxtri;
+    int   len;
+
+    /*
+     * fill in type info for elmt types first
+     */
+    FOR_EACH_LIST_ELMT (et, elmts)
+        FillCxxTypeRefInfo (r, m, head, parent, et->type);
+
+    /*
+     * set choiceId Symbol & value
+     * eg
+     *  Car ::= CHOICE {          class Car {
+     *     chev ChevCar,   ->         enum ChoiceIdEnum {
+     *     ford FordCar                  chevCid,
+     *     toyota ToyotaCar              fordCid,
+     *     }                             toyotaCid } choiceId;
+     *                                union CarChoiceUnion {
+     *                                      ChevCar *chev;
+     *                                      FordCar *ford;
+     *                                      ToyotaCar *toyota; };
+     *                                  ...
+     *                               }
+     * NOTE that the union is anonymous
+     */
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        cxxtri =  et->type->cxxTypeRefInfo;
+
+        if (cxxtri == NULL)
+            continue; /* wierd type */
+
+        cxxtri->choiceIdValue = idCount++;
+
+        len = strlen (cxxtri->fieldName);
+        cxxtri->choiceIdSymbol = Malloc (len + 4);
+        strcpy (cxxtri->choiceIdSymbol, cxxtri->fieldName);
+        strcat (cxxtri->choiceIdSymbol, "Cid");
+
+        if (r->capitalizeNamedElmts)
+            Str2UCase (cxxtri->choiceIdSymbol, len);
+
+    }
+
+}  /* FillCxxChoiceElmts */
+
+
+/*
+ * takes a list of "sibling" (eg same level in a structure)
+ * ElmtTypes and fills sets up the c field names in
+ * the CxxTRI struct
+ */
+static void
+FillCxxFieldNames PARAMS ((r, elmts),
+    CxxRules *r _AND_
+    NamedTypeList *elmts)
+{
+    NamedType  *et;
+    CxxTRI *cxxtri;
+    DefinedObj *fieldNames;
+    int        len, num, digit, i, tmpLen;
+    char      *tmpName;
+    char      *asn1FieldName;
+    char      *cFieldName;
+
+    /*
+     * Initialize fieldname data
+     * allocate (if nec) and fill in CTRI fieldname if poss
+     * from asn1 field name.  leave blank otherwise
+     */
+    fieldNames = NewObjList();
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        cxxtri =  et->type->cxxTypeRefInfo;
+        if (cxxtri == NULL)
+        {
+            cxxtri = MT (CxxTRI);
+            et->type->cxxTypeRefInfo = cxxtri;
+        }
+        if (et->fieldName != NULL)
+        {
+            /*
+             * can assume that the field names are
+             * distinct because they have passed the
+             * error checking step.
+             * However, still call MakeCxxStrUnique
+             * to change any field names that
+             * conflict with C++ keywords
+             */
+            asn1FieldName = et->fieldName;
+            tmpName = Asn1FieldName2CFieldName (asn1FieldName);
+            cxxtri->fieldName = Malloc (strlen (tmpName) + 1 +
+                                       r->maxDigitsToAppend);
+            strcpy (cxxtri->fieldName, tmpName);
+            Free (tmpName);
+
+/*   old    cxxtri->fieldName = Asn1FieldName2CFieldName (asn1FieldName); */
+
+            MakeCxxStrUnique (fieldNames, cxxtri->fieldName, r->maxDigitsToAppend, 1);
+            DefineObj (&fieldNames, cxxtri->fieldName);
+        }
+    }
+
+
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        cxxtri =  et->type->cxxTypeRefInfo;
+
+        /*
+         * generate field names for those without them
+         */
+        if (cxxtri->fieldName == NULL)
+        {
+            if ((et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+                 (et->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+            {
+                /*
+                 * take ref'd type name as field name
+                 * convert first let to lower case
+                 */
+                tmpName = et->type->basicType->a.localTypeRef->link->cxxTypeDefInfo->className;
+                tmpName =  Asn1TypeName2CTypeName (tmpName);
+                cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
+                strcpy (cFieldName, tmpName);
+                Free (tmpName);
+                if (isupper (cFieldName[0]))
+                    cFieldName[0] = tolower (cFieldName[0]);
+            }
+            else
+            {
+                /*
+                 * get default field name for this type
+                 */
+                tmpName = r->typeConvTbl[et->type->basicType->choiceId].defaultFieldName;
+                cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
+                strcpy (cFieldName, tmpName);
+
+                if (isupper (cFieldName[0]))
+                    cFieldName[0] = tolower (cFieldName[0]);
+            }
+
+
+            len = strlen (cFieldName);
+
+            /*
+             * try to use just the type name (with lower case first char).
+             * if that is already used in this type or a C++ keyword,
+             * append ascii digits to field name until unique
+             * in this type
+             */
+            MakeCxxStrUnique (fieldNames, cFieldName, r->maxDigitsToAppend, 1);
+            DefineObj (&fieldNames, cFieldName);
+            cxxtri->fieldName = cFieldName;
+        }
+    }
+    FreeDefinedObjs (&fieldNames);
+}  /* FillCxxFieldNames */
+
+
+
+/*
+ * returns true if this c type for this type should be
+ * be ref'd as a ptr
+ */
+static int
+IsCxxPtr PARAMS ((r, td, parent, t),
+    CxxRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    CxxTDI *cxxtdi;
+    int retVal = FALSE;
+
+    /*
+     * inherit ptr attriubutes from ref'd type if any
+     * otherwise grab lib c type def from the CxxRules
+     */
+    if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+        (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+    {
+        cxxtdi = t->basicType->a.localTypeRef->link->cxxTypeDefInfo;
+    }
+    else
+        cxxtdi = &r->typeConvTbl[GetBuiltinType (t)];
+
+    /* no parent means t is the root of a typedef */
+    if ((parent == NULL) && (cxxtdi->isPtrForTypeDef))
+        retVal = TRUE;
+
+    else if ((parent != NULL) &&
+             ((parent->basicType->choiceId == BASICTYPE_SET) ||
+             (parent->basicType->choiceId == BASICTYPE_SEQUENCE)) &&
+             (cxxtdi->isPtrInSetAndSeq))
+        retVal = TRUE;
+
+    else if ((parent != NULL) &&
+             ((parent->basicType->choiceId == BASICTYPE_SETOF) ||
+             (parent->basicType->choiceId == BASICTYPE_SEQUENCEOF)) &&
+             (cxxtdi->isPtrInList))
+        retVal = TRUE;
+
+    else if ((parent != NULL) &&
+             (parent->basicType->choiceId == BASICTYPE_CHOICE) &&
+             (cxxtdi->isPtrInChoice))
+        retVal = TRUE;
+
+    else if (((t->optional) || (t->defaultVal != NULL)) && (cxxtdi->isPtrForOpt))
+        retVal = TRUE;
+
+    return retVal;
+}  /* IsCxxPtr */
+
+
+
+/* fill given cxxtdi with defaults from table for given typedef */
+void
+FillCxxTDIDefaults PARAMS ((r, cxxtdi, td),
+    CxxRules *r _AND_
+    CxxTDI *cxxtdi _AND_
+    TypeDef *td)
+{
+    CxxTDI *tblCxxtdi;
+    int typeIndex;
+    char *tmpName;
+
+    typeIndex = GetBuiltinType (td->type);
+
+    if (typeIndex < 0)
+        return;
+
+    tblCxxtdi = &r->typeConvTbl[typeIndex];
+
+    memcpy (cxxtdi, tblCxxtdi, sizeof (CxxTDI));
+
+    /* make sure class name is unique wrt to previously defined classes */
+    tmpName = Asn1TypeName2CTypeName (td->definedName);
+    cxxtdi->className = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
+    strcpy (cxxtdi->className, tmpName);
+    Free (tmpName);
+
+    MakeCxxStrUnique (definedNamesG, cxxtdi->className, r->maxDigitsToAppend, 1);
+    DefineObj (&definedNamesG, cxxtdi->className);
+
+} /* FillCxxTDIDefaults */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.h b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.h
new file mode 100644
index 00000000..edfa4813
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c++_gen/types.h  - fills in c++ type information
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/types.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: types.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:41  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:25:19  rj
+ * file name has been shortened for redundant part: c++-gen/c++-types -> c++-gen/types.
+ *
+ * Revision 1.2  1994/10/08  03:47:52  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:47:57  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+void FillCxxTypeInfo PROTO ((CxxRules *r, ModuleList *m));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.c
new file mode 100644
index 00000000..38d0c9b5
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.c
@@ -0,0 +1,338 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-any.c
+ *
+ *     prints Routine to initialize the ANY Hash table.  The
+ *     ANY Hash table maps the OBJECT IDENTIFIERS or INTEGERS
+ *     to the correct encoding/decoding etc routines.
+ *
+ *     Also prints an enum to identify each ANY mapping.
+ *
+ *     if the given module has no ANY or ANY DEFINED BY  types
+ *     nothing is printed.
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-any.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1  2000/05/10 21:35:01  rmurphy
+ * Adding back in base code files which had been moved to "2" versions.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:41  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:33:43  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-any -> c-gen/gen-any.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:21:15  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:15  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "rules.h"
+#include "define.h"
+#include "str-util.h"
+#include "gen-vals.h"
+#include "lib-types.h"
+#include "gen-any.h"
+
+int anyEnumValG = 0;
+
+
+void PrintCAnyEnum PROTO ((FILE *hdr, Module *m, CRules *r));
+
+void PrintCAnyHashInitRoutine PROTO ((FILE *src, FILE *hdr, ModuleList *mods, Module *m, CRules *r));
+
+
+
+
+void
+PrintCAnyCode PARAMS ((src, hdr, r, mods, m),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m)
+{
+
+    if (!m->hasAnys)
+        return;
+
+    PrintCAnyEnum (hdr, m, r);
+    PrintCAnyHashInitRoutine (src, hdr, mods, m, r);
+
+}  /* PrintAnyCode */
+
+
+
+void
+PrintCAnyEnum PARAMS ((hdr, m, r),
+    FILE *hdr _AND_
+    Module *m _AND_
+    CRules *r)
+{
+    TypeDef *td;
+    AnyRef *ar;
+    AnyRefList *arl;
+    int i;
+    int firstPrinted = TRUE;
+    char *modName;
+
+    modName = Asn1TypeName2CTypeName (m->modId->name);
+
+    fprintf (hdr,"typedef enum %sAnyId\n", modName);
+    fprintf (hdr,"{\n");
+
+    /* do any lib types */
+    for (i = BASICTYPE_BOOLEAN; i < BASICTYPE_MACRODEF; i++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (i);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                if (!firstPrinted)
+                    fprintf (hdr,",\n");
+                fprintf (hdr,"    %s = %d", ar->anyIdName, anyEnumValG++);
+                firstPrinted = FALSE;
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                if (!firstPrinted)
+                    fprintf (hdr,",\n");
+                fprintf (hdr,"    %s = %d", ar->anyIdName, anyEnumValG++);
+                firstPrinted = FALSE;
+            }
+        }
+    }
+    if (firstPrinted) /* none have been printed */
+        fprintf (hdr,"/* NO INTEGER or OBJECT IDENTIFIER to ANY type relationships were defined (via MACROs or other mechanism) */\n???\n");
+
+    fprintf (hdr,"} %sAnyId;\n\n\n", modName);
+    Free (modName);
+
+}  /* PrintAnyEnum */
+
+
+void
+PrintCAnyHashInitRoutine PARAMS ((src, hdr, mods, m, r),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CRules *r)
+{
+    TypeDef *td;
+    AnyRef *ar;
+    AnyRefList *arl;
+    char *modName;
+    CTDI *ctdi;
+    int i,j;
+    enum BasicTypeChoiceId typeId;
+    char *encRoutineName;
+    char *decRoutineName;
+    char *freeRoutineName;
+    char *printRoutineName;
+    int installedSomeHashes = FALSE;
+
+    /* print proto in hdr file */
+    modName = Asn1TypeName2CTypeName (m->modId->name);
+    fprintf (hdr,"void InitAny%s();\n\n", modName);
+
+    /* print routine to src file */
+    fprintf (src,"void\nInitAny%s()\n", modName);
+    fprintf (src,"{\n");
+
+    /* first print value for OID's */
+    /* do any lib types first */
+    i = 0;
+    for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (j);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                installedSomeHashes = TRUE;
+                if (ar->id->choiceId == OIDORINT_OID)
+                {
+                    fprintf (src,"    %s oid%d =", r->typeConvTbl[BASICTYPE_OID].cTypeName, i++);
+                    PrintCOidValue (src, r, ar->id->a.oid);
+                    fprintf (src,";\n");
+                }
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            ctdi = td->cTypeDefInfo;
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                installedSomeHashes = TRUE;
+                if (ar->id->choiceId == OIDORINT_OID)
+                {
+                    fprintf (src,"    %s oid%d =", r->typeConvTbl[BASICTYPE_OID].cTypeName, i++);
+                    PrintCOidValue (src, r, ar->id->a.oid);
+                    fprintf (src,";\n");
+                }
+            }
+        }
+    }
+
+    fprintf (src,"\n\n");
+
+    /* now print hash init calls */
+    i = 0;
+
+    /* do lib types first */
+    for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (j);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+
+                encRoutineName = r->typeConvTbl[j].encodeRoutineName;
+                decRoutineName = r->typeConvTbl[j].decodeRoutineName;
+                printRoutineName = r->typeConvTbl[j].printRoutineName;
+
+                /*
+                 * use NULL free routine for types that
+                 * have empyt macros for their free routines
+                 * (since the any hash tbl needs the addr of the routine)
+                 */
+                switch (j)
+                {
+                    case BASICTYPE_BOOLEAN:
+                    case BASICTYPE_INTEGER:
+                    case BASICTYPE_NULL:
+                    case BASICTYPE_REAL:
+                    case BASICTYPE_ENUMERATED:
+                        freeRoutineName = "NULL";
+                        break;
+                    default:
+                        freeRoutineName =  r->typeConvTbl[j].freeRoutineName;
+                }
+
+                if (ar->id->choiceId == OIDORINT_OID)
+                    fprintf (src,"    InstallAnyByOid (%s, &oid%d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, i++,  r->typeConvTbl[j].cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName);
+                else
+                    fprintf (src,"    InstallAnyByInt (%s, %d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, ar->id->a.intId, r->typeConvTbl[j].cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName);
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            ctdi = td->cTypeDefInfo;
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                typeId = GetBuiltinType (td->type);
+
+                encRoutineName = ctdi->encodeRoutineName;
+                decRoutineName = ctdi->decodeRoutineName;
+                printRoutineName = ctdi->printRoutineName;
+
+                /*
+                 * use NULL free routine for types that
+                 * have empyt macros for their free routines
+                 * (since the any hash tbl needs the addr of the routine)
+                 */
+                switch (typeId)
+                {
+                    case BASICTYPE_BOOLEAN:
+                    case BASICTYPE_INTEGER:
+                    case BASICTYPE_NULL:
+                    case BASICTYPE_REAL:
+                    case BASICTYPE_ENUMERATED:
+                        freeRoutineName = "NULL";
+                        break;
+                    default:
+                        freeRoutineName = ctdi->freeRoutineName;
+                }
+
+                if (ar->id->choiceId == OIDORINT_OID)
+                    fprintf (src,"    InstallAnyByOid (%s, &oid%d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, i++, ctdi->cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName);
+                else
+                    fprintf (src,"    InstallAnyByInt (%s, %d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, ar->id->a.intId, ctdi->cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName);
+            }
+        }
+    }
+
+
+    if (!installedSomeHashes)
+    {
+        fprintf (src,"    /* Since no INTEGER/OID to ANY type relations were defined\n");
+        fprintf (src,"     * (usually done via MACROs) you must manually do the code\n");
+        fprintf (src,"     * to fill the hash tbl.\n");
+        fprintf (src,"     * if the ids are INTEGER use the following:\n");
+        fprintf (src,"     * InstallAnyByInt (??_ANY_ID, intVal, sizeof (Foo), (EncodeFcn) BEncFoo, (DecodeFcn)BDecFoo, (FreeFcn)FreeFoo, (PrintFcn)PrintFoo);\n");
+        fprintf (src,"     * if the ids are OBJECT IDENTIFIERs use the following:\n");
+        fprintf (src,"     *     InstallAnyByOid (??_ANY_ID, oidVal, sizeof (Foo), (EncodeFcn) BEncFoo, (DecodeFcn)BDecFoo, (FreeFcn)FreeFoo, (PrintFcn)PrintFoo);\n");
+        fprintf (src,"     * put the ??_ANY_IDs in the AnyId enum.\n\n");
+        fprintf (src,"     * For example if you have some thing like\n");
+        fprintf (src,"     * T1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id }\n");
+        fprintf (src,"     * and the id 1 maps to the type BOOLEAN use the following:\n");
+        fprintf (src,"     * InstallAnyByInt (SOMEBOOL_ANY_ID, 1, sizeof (AsnBool), (EncodeFcn) BEncAsnBool, (DecodeFcn)BDecAsnBool, (FreeFcn)NULL, (PrintFcn)PrintAsnBool);;\n");
+        fprintf (src,"     */\n ???????\n");  /* generate compile error */
+    }
+
+
+    fprintf (src,"}  /* InitAny%s */\n\n\n", modName);
+
+    Free (modName);
+
+}  /* PrintAnyHashInitRoutine */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.h
new file mode 100644
index 00000000..9bb84c97
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  compiler/back-ends/c-gen/gen-any.h
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-any.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:41  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:33:59  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-any -> c-gen/gen-any.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:08  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:16  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+extern int anyEnumValG;
+
+
+void PrintCAnyCode PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any2.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any2.c
new file mode 100644
index 00000000..71fbcde3
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any2.c
@@ -0,0 +1,335 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-any.c
+ *
+ *     prints Routine to initialize the ANY Hash table.  The
+ *     ANY Hash table maps the OBJECT IDENTIFIERS or INTEGERS
+ *     to the correct encoding/decoding etc routines.
+ *
+ *     Also prints an enum to identify each ANY mapping.
+ *
+ *     if the given module has no ANY or ANY DEFINED BY  types
+ *     nothing is printed.
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-any2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-any2.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:41  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:33:43  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-any -> c-gen/gen-any.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:21:15  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:15  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "rules.h"
+#include "define.h"
+#include "str-util.h"
+#include "gen-vals.h"
+#include "lib-types.h"
+#include "gen-any.h"
+
+int anyEnumValG = 0;
+
+
+void PrintCAnyEnum PROTO ((FILE *hdr, Module *m, CRules *r));
+
+void PrintCAnyHashInitRoutine PROTO ((FILE *src, FILE *hdr, ModuleList *mods, Module *m, CRules *r));
+
+
+
+
+void
+PrintCAnyCode PARAMS ((src, hdr, r, mods, m),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m)
+{
+
+    if (!m->hasAnys)
+        return;
+
+    PrintCAnyEnum (hdr, m, r);
+    PrintCAnyHashInitRoutine (src, hdr, mods, m, r);
+
+}  /* PrintAnyCode */
+
+
+
+void
+PrintCAnyEnum PARAMS ((hdr, m, r),
+    FILE *hdr _AND_
+    Module *m _AND_
+    CRules *r)
+{
+    TypeDef *td;
+    AnyRef *ar;
+    AnyRefList *arl;
+    int i;
+    int firstPrinted = TRUE;
+    char *modName;
+
+    modName = Asn1TypeName2CTypeName (m->modId->name);
+
+    fprintf (hdr,"typedef enum %sAnyId\n", modName);
+    fprintf (hdr,"{\n");
+
+    /* do any lib types */
+    for (i = BASICTYPE_BOOLEAN; i < BASICTYPE_MACRODEF; i++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (i);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                if (!firstPrinted)
+                    fprintf (hdr,",\n");
+                fprintf (hdr,"    %s = %d", ar->anyIdName, anyEnumValG++);
+                firstPrinted = FALSE;
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                if (!firstPrinted)
+                    fprintf (hdr,",\n");
+                fprintf (hdr,"    %s = %d", ar->anyIdName, anyEnumValG++);
+                firstPrinted = FALSE;
+            }
+        }
+    }
+    if (firstPrinted) /* none have been printed */
+        fprintf (hdr,"/* NO INTEGER or OBJECT IDENTIFIER to ANY type relationships were defined (via MACROs or other mechanism) */\n???\n");
+
+    fprintf (hdr,"} %sAnyId;\n\n\n", modName);
+    Free (modName);
+
+}  /* PrintAnyEnum */
+
+
+void
+PrintCAnyHashInitRoutine PARAMS ((src, hdr, mods, m, r),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CRules *r)
+{
+    TypeDef *td;
+    AnyRef *ar;
+    AnyRefList *arl;
+    char *modName;
+    CTDI *ctdi;
+    int i,j;
+    enum BasicTypeChoiceId typeId;
+    char *encRoutineName;
+    char *decRoutineName;
+    char *freeRoutineName;
+    char *printRoutineName;
+    int installedSomeHashes = FALSE;
+
+    /* print proto in hdr file */
+    modName = Asn1TypeName2CTypeName (m->modId->name);
+    fprintf (hdr,"void InitAny%s();\n\n", modName);
+
+    /* print routine to src file */
+    fprintf (src,"void\nInitAny%s()\n", modName);
+    fprintf (src,"{\n");
+
+    /* first print value for OID's */
+    /* do any lib types first */
+    i = 0;
+    for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (j);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                installedSomeHashes = TRUE;
+                if (ar->id->choiceId == OIDORINT_OID)
+                {
+                    fprintf (src,"    %s oid%d =", r->typeConvTbl[BASICTYPE_OID].cTypeName, i++);
+                    PrintCOidValue (src, r, ar->id->a.oid);
+                    fprintf (src,";\n");
+                }
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            ctdi = td->cTypeDefInfo;
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                installedSomeHashes = TRUE;
+                if (ar->id->choiceId == OIDORINT_OID)
+                {
+                    fprintf (src,"    %s oid%d =", r->typeConvTbl[BASICTYPE_OID].cTypeName, i++);
+                    PrintCOidValue (src, r, ar->id->a.oid);
+                    fprintf (src,";\n");
+                }
+            }
+        }
+    }
+
+    fprintf (src,"\n\n");
+
+    /* now print hash init calls */
+    i = 0;
+
+    /* do lib types first */
+    for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (j);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+
+                encRoutineName = r->typeConvTbl[j].encodeRoutineName;
+                decRoutineName = r->typeConvTbl[j].decodeRoutineName;
+                printRoutineName = r->typeConvTbl[j].printRoutineName;
+
+                /*
+                 * use NULL free routine for types that
+                 * have empyt macros for their free routines
+                 * (since the any hash tbl needs the addr of the routine)
+                 */
+                switch (j)
+                {
+                    case BASICTYPE_BOOLEAN:
+                    case BASICTYPE_INTEGER:
+                    case BASICTYPE_NULL:
+                    case BASICTYPE_REAL:
+                    case BASICTYPE_ENUMERATED:
+                        freeRoutineName = "NULL";
+                        break;
+                    default:
+                        freeRoutineName =  r->typeConvTbl[j].freeRoutineName;
+                }
+
+                if (ar->id->choiceId == OIDORINT_OID)
+                    fprintf (src,"    InstallAnyByOid (%s, &oid%d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, i++,  r->typeConvTbl[j].cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName);
+                else
+                    fprintf (src,"    InstallAnyByInt (%s, %d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, ar->id->a.intId, r->typeConvTbl[j].cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName);
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            ctdi = td->cTypeDefInfo;
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                typeId = GetBuiltinType (td->type);
+
+                encRoutineName = ctdi->encodeRoutineName;
+                decRoutineName = ctdi->decodeRoutineName;
+                printRoutineName = ctdi->printRoutineName;
+
+                /*
+                 * use NULL free routine for types that
+                 * have empyt macros for their free routines
+                 * (since the any hash tbl needs the addr of the routine)
+                 */
+                switch (typeId)
+                {
+                    case BASICTYPE_BOOLEAN:
+                    case BASICTYPE_INTEGER:
+                    case BASICTYPE_NULL:
+                    case BASICTYPE_REAL:
+                    case BASICTYPE_ENUMERATED:
+                        freeRoutineName = "NULL";
+                        break;
+                    default:
+                        freeRoutineName = ctdi->freeRoutineName;
+                }
+
+                if (ar->id->choiceId == OIDORINT_OID)
+                    fprintf (src,"    InstallAnyByOid (%s, &oid%d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, i++, ctdi->cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName);
+                else
+                    fprintf (src,"    InstallAnyByInt (%s, %d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, ar->id->a.intId, ctdi->cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName);
+            }
+        }
+    }
+
+
+    if (!installedSomeHashes)
+    {
+        fprintf (src,"    /* Since no INTEGER/OID to ANY type relations were defined\n");
+        fprintf (src,"     * (usually done via MACROs) you must manually do the code\n");
+        fprintf (src,"     * to fill the hash tbl.\n");
+        fprintf (src,"     * if the ids are INTEGER use the following:\n");
+        fprintf (src,"     * InstallAnyByInt (??_ANY_ID, intVal, sizeof (Foo), (EncodeFcn) BEncFoo, (DecodeFcn)BDecFoo, (FreeFcn)FreeFoo, (PrintFcn)PrintFoo);\n");
+        fprintf (src,"     * if the ids are OBJECT IDENTIFIERs use the following:\n");
+        fprintf (src,"     *     InstallAnyByOid (??_ANY_ID, oidVal, sizeof (Foo), (EncodeFcn) BEncFoo, (DecodeFcn)BDecFoo, (FreeFcn)FreeFoo, (PrintFcn)PrintFoo);\n");
+        fprintf (src,"     * put the ??_ANY_IDs in the AnyId enum.\n\n");
+        fprintf (src,"     * For example if you have some thing like\n");
+        fprintf (src,"     * T1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id }\n");
+        fprintf (src,"     * and the id 1 maps to the type BOOLEAN use the following:\n");
+        fprintf (src,"     * InstallAnyByInt (SOMEBOOL_ANY_ID, 1, sizeof (AsnBool), (EncodeFcn) BEncAsnBool, (DecodeFcn)BDecAsnBool, (FreeFcn)NULL, (PrintFcn)PrintAsnBool);;\n");
+        fprintf (src,"     */\n ???????\n");  /* generate compile error */
+    }
+
+
+    fprintf (src,"}  /* InitAny%s */\n\n\n", modName);
+
+    Free (modName);
+
+}  /* PrintAnyHashInitRoutine */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.c
new file mode 100644
index 00000000..91b4c2eb
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.c
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-code.c - generate C hdr and src files
+ *
+ * Assumes you have called FillCTypeInfo
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-code.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1  2000/05/10 21:35:01  rmurphy
+ * Adding back in base code files which had been moved to "2" versions.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:41  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:39:46  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-code -> c-gen/gen-code.
+ *
+ * PrintConditionalIncludeOpen() and PrintConditionalIncludeClose() moved to back-ends/cond.c
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1995/02/18  12:50:53  rj
+ * typo fixed.
+ *
+ * Revision 1.2  1994/09/01  00:21:54  rj
+ * snacc_config.h and other superfluous .h files removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:17  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "print.h"
+#include "rules.h"
+#include "type-info.h"
+#include "util.h"
+#include "cond.h"
+#include "gen-type.h"
+#include "gen-enc.h"
+#include "gen-dec.h"
+#include "gen-vals.h"
+#include "gen-free.h"
+#include "gen-print.h"
+#include "gen-any.h"
+#include "gen-code.h"
+
+/* unexported prototypes */
+static void PrintCSrcComment PROTO ((FILE *src, Module *m));
+static void PrintCSrcIncludes PROTO ((FILE *src, Module *m, ModuleList *mods));
+static void PrintCHdrComment PROTO ((FILE *hdr, Module *m));
+
+/*
+ * Fills the hdr file with the C type and encode/decode prototypes
+ * Fills the src file with the encoded/decode routine definitions
+ */
+void
+PrintCCode PARAMS ((src, hdr, mods, m, r, longJmpVal, printTypes, printValues, printEncoders, printDecoders, printPrinters, printFree),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CRules *r _AND_
+    long int longJmpVal _AND_
+    int printTypes _AND_
+    int printValues _AND_
+    int printEncoders _AND_
+    int printDecoders _AND_
+    int printPrinters _AND_
+    int printFree)
+{
+    TypeDef *td;
+    ValueDef *vd;
+
+    PrintCSrcComment (src, m);
+    PrintCSrcIncludes (src, m, mods);
+
+    PrintCHdrComment (hdr, m);
+    PrintConditionalIncludeOpen (hdr, m->cHdrFileName);
+
+    fprintf (hdr,"\n\n");
+    fprintf (src,"\n\n");
+
+
+    if (printValues)
+    {
+        /* put value defs at beginning of .c file */
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+        {
+            PrintCValueDef (src, r, vd);
+        }
+    }
+
+    PrintCAnyCode (src, hdr, r, mods, m);
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (printTypes)
+            PrintCTypeDef (hdr, r, m, td);
+
+        /* for PDU type or types ref'd with ANY/ANY DEF BY */
+        if (printEncoders &&
+            ((td->anyRefs != NULL) || td->cTypeDefInfo->isPdu))
+            PrintCBerEncoder (src, hdr, r, m, td);
+
+        /* for PDU type or types ref'd with ANY/ANY DEF BY */
+        if (printDecoders &&
+            ((td->anyRefs != NULL) || td->cTypeDefInfo->isPdu))
+            PrintCBerDecoder (src, hdr, r, m, td, &longJmpVal);
+
+        if (printEncoders)
+            PrintCBerContentEncoder (src, hdr, r, m, td);
+
+        if (printDecoders)
+            PrintCBerContentDecoder (src, hdr, r, m, td, &longJmpVal);
+
+
+        if (printPrinters)
+            PrintCPrinter (src, hdr, r, mods, m, td);
+
+        if (printFree)
+            PrintCFree (src, hdr, r, mods, m, td);
+
+        /* only print new lines for normal types */
+        switch (td->type->basicType->choiceId)
+        {
+            case BASICTYPE_SEQUENCEOF:  /* list types */
+            case BASICTYPE_SETOF:
+            case BASICTYPE_CHOICE:
+            case BASICTYPE_SET:
+            case BASICTYPE_SEQUENCE:
+                fprintf (src, "\n\n\n");
+                /* fall through */
+
+            case BASICTYPE_IMPORTTYPEREF:  /* type references */
+            case BASICTYPE_LOCALTYPEREF:
+            case BASICTYPE_BOOLEAN:  /* library type */
+            case BASICTYPE_REAL:  /* library type */
+            case BASICTYPE_OCTETSTRING:  /* library type */
+            case BASICTYPE_NULL:  /* library type */
+            case BASICTYPE_OID:  /* library type */
+            case BASICTYPE_INTEGER:  /* library type */
+            case BASICTYPE_BITSTRING:  /* library type */
+            case BASICTYPE_ENUMERATED:  /* library type */
+            case BASICTYPE_ANYDEFINEDBY:  /* ANY types */
+            case BASICTYPE_ANY:
+                fprintf (hdr, "\n\n\n");
+                break;
+        }
+
+    }
+
+    if (printValues)
+    {
+        /* put value externs at end of .h file */
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+        {
+            PrintCValueExtern (hdr, r, vd);
+        }
+    }
+
+    PrintConditionalIncludeClose (hdr, m->cHdrFileName);
+
+} /* PrintCCode */
+
+
+static void
+PrintCSrcComment PARAMS ((src, m),
+    FILE *src _AND_
+    Module *m)
+{
+    long int t;
+
+    t = time (0);
+    fprintf (src, "/*\n");
+    fprintf (src, " *    %s\n *\n", m->cSrcFileName);
+    fprintf (src, " *    \"%s\" ASN.1 module encode/decode/print/free C src.\n *\n", m->modId->name);
+    fprintf (src, " *    This file was generated by snacc on %s *\n", ctime (&t));
+    fprintf (src, " *    UBC snacc written by Mike Sample\n *\n");
+    fprintf (src, " *    NOTE: This is a machine generated file - editing not recommended\n");
+    fprintf (src, " */\n\n\n");
+
+} /* PrintSrcComment */
+
+
+
+static void
+PrintCSrcIncludes PARAMS ((src, m, mods),
+    FILE *src _AND_
+    Module *m _AND_
+    ModuleList *mods)
+{
+    void *tmp;
+    Module *impMod;
+
+    /*
+     * include snacc runtime library related hdrs
+     */
+    fprintf (src, "\n#include \"asn-incl.h\"\n");
+
+    /*
+     * print out include files in same order of the module
+     * list. every module in the list includes the others and it's
+     * own .h
+     */
+    tmp = (void*)CURR_LIST_NODE (mods);
+    FOR_EACH_LIST_ELMT (impMod, mods)
+    {
+        fprintf (src, "#include \"%s\"\n", impMod->cHdrFileName);
+    }
+    SET_CURR_LIST_NODE (mods, tmp);
+
+}  /* PrintCSrcIncludes */
+
+
+static void
+PrintCHdrComment PARAMS ((f, m),
+    FILE *f _AND_
+    Module *m)
+{
+    long int t;
+
+    t = time (0);
+    fprintf (f, "/*\n");
+    fprintf (f, " *    %s\n *\n", m->cHdrFileName);
+    fprintf (f, " *    \"%s\" ASN.1 module C type definitions and prototypes\n *\n", m->modId->name);
+    fprintf (f, " *    This .h file was generated by snacc on %s *\n", ctime (&t));
+    fprintf (f, " *    UBC snacc written compiler by Mike Sample\n *\n");
+    fprintf (f, " *    NOTE: This is a machine generated file--editing not recommended\n");
+    fprintf (f, " */\n\n\n");
+} /* PrintCHdrComment */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.h
new file mode 100644
index 00000000..ae864d00
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-code.h - generates C hdr and source files
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-code.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:41  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:38:30  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-code -> c-gen/gen-code.
+ *
+ * PrintConditionalIncludeOpen() and PrintConditionalIncludeClose() moved to back-ends/cond.h
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:09  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:19  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+void PrintCCode PROTO ((FILE *src, FILE *hdr, ModuleList *mods, Module *m, CRules *r, long int longJmpVal, int printTypes, int printValues, int printEncoders, int printDecoders, int printPrinters, int printFree));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code2.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code2.c
new file mode 100644
index 00000000..6fca2fba
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code2.c
@@ -0,0 +1,264 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-code.c - generate C hdr and src files
+ *
+ * Assumes you have called FillCTypeInfo
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-code2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-code2.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:41  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:39:46  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-code -> c-gen/gen-code.
+ *
+ * PrintConditionalIncludeOpen() and PrintConditionalIncludeClose() moved to back-ends/cond.c
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1995/02/18  12:50:53  rj
+ * typo fixed.
+ *
+ * Revision 1.2  1994/09/01  00:21:54  rj
+ * snacc_config.h and other superfluous .h files removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:17  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "print.h"
+#include "rules.h"
+#include "type-info.h"
+#include "util.h"
+#include "cond.h"
+#include "gen-type.h"
+#include "gen-enc.h"
+#include "gen-dec.h"
+#include "gen-vals.h"
+#include "gen-free.h"
+#include "gen-print.h"
+#include "gen-any.h"
+#include "gen-code.h"
+
+/* unexported prototypes */
+static void PrintCSrcComment PROTO ((FILE *src, Module *m));
+static void PrintCSrcIncludes PROTO ((FILE *src, Module *m, ModuleList *mods));
+static void PrintCHdrComment PROTO ((FILE *hdr, Module *m));
+
+/*
+ * Fills the hdr file with the C type and encode/decode prototypes
+ * Fills the src file with the encoded/decode routine definitions
+ */
+void
+PrintCCode PARAMS ((src, hdr, mods, m, r, longJmpVal, printTypes, printValues, printEncoders, printDecoders, printPrinters, printFree),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    CRules *r _AND_
+    long int longJmpVal _AND_
+    int printTypes _AND_
+    int printValues _AND_
+    int printEncoders _AND_
+    int printDecoders _AND_
+    int printPrinters _AND_
+    int printFree)
+{
+    TypeDef *td;
+    ValueDef *vd;
+
+    PrintCSrcComment (src, m);
+    PrintCSrcIncludes (src, m, mods);
+
+    PrintCHdrComment (hdr, m);
+    PrintConditionalIncludeOpen (hdr, m->cHdrFileName);
+
+    fprintf (hdr,"\n\n");
+    fprintf (src,"\n\n");
+
+
+    if (printValues)
+    {
+        /* put value defs at beginning of .c file */
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+        {
+            PrintCValueDef (src, r, vd);
+        }
+    }
+
+    PrintCAnyCode (src, hdr, r, mods, m);
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (printTypes)
+            PrintCTypeDef (hdr, r, m, td);
+
+        /* for PDU type or types ref'd with ANY/ANY DEF BY */
+        if (printEncoders &&
+            ((td->anyRefs != NULL) || td->cTypeDefInfo->isPdu))
+            PrintCBerEncoder (src, hdr, r, m, td);
+
+        /* for PDU type or types ref'd with ANY/ANY DEF BY */
+        if (printDecoders &&
+            ((td->anyRefs != NULL) || td->cTypeDefInfo->isPdu))
+            PrintCBerDecoder (src, hdr, r, m, td, &longJmpVal);
+
+        if (printEncoders)
+            PrintCBerContentEncoder (src, hdr, r, m, td);
+
+        if (printDecoders)
+            PrintCBerContentDecoder (src, hdr, r, m, td, &longJmpVal);
+
+
+        if (printPrinters)
+            PrintCPrinter (src, hdr, r, mods, m, td);
+
+        if (printFree)
+            PrintCFree (src, hdr, r, mods, m, td);
+
+        /* only print new lines for normal types */
+        switch (td->type->basicType->choiceId)
+        {
+            case BASICTYPE_SEQUENCEOF:  /* list types */
+            case BASICTYPE_SETOF:
+            case BASICTYPE_CHOICE:
+            case BASICTYPE_SET:
+            case BASICTYPE_SEQUENCE:
+                fprintf (src, "\n\n\n");
+                /* fall through */
+
+            case BASICTYPE_IMPORTTYPEREF:  /* type references */
+            case BASICTYPE_LOCALTYPEREF:
+            case BASICTYPE_BOOLEAN:  /* library type */
+            case BASICTYPE_REAL:  /* library type */
+            case BASICTYPE_OCTETSTRING:  /* library type */
+            case BASICTYPE_NULL:  /* library type */
+            case BASICTYPE_OID:  /* library type */
+            case BASICTYPE_INTEGER:  /* library type */
+            case BASICTYPE_BITSTRING:  /* library type */
+            case BASICTYPE_ENUMERATED:  /* library type */
+            case BASICTYPE_ANYDEFINEDBY:  /* ANY types */
+            case BASICTYPE_ANY:
+                fprintf (hdr, "\n\n\n");
+                break;
+        }
+
+    }
+
+    if (printValues)
+    {
+        /* put value externs at end of .h file */
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+        {
+            PrintCValueExtern (hdr, r, vd);
+        }
+    }
+
+    PrintConditionalIncludeClose (hdr, m->cHdrFileName);
+
+} /* PrintCCode */
+
+
+static void
+PrintCSrcComment PARAMS ((src, m),
+    FILE *src _AND_
+    Module *m)
+{
+    long int t;
+
+    t = time (0);
+    fprintf (src, "/*\n");
+    fprintf (src, " *    %s\n *\n", m->cSrcFileName);
+    fprintf (src, " *    \"%s\" ASN.1 module encode/decode/print/free C src.\n *\n", m->modId->name);
+    fprintf (src, " *    This file was generated by snacc on %s *\n", ctime (&t));
+    fprintf (src, " *    UBC snacc written by Mike Sample\n *\n");
+    fprintf (src, " *    NOTE: This is a machine generated file - editing not recommended\n");
+    fprintf (src, " */\n\n\n");
+
+} /* PrintSrcComment */
+
+
+
+static void
+PrintCSrcIncludes PARAMS ((src, m, mods),
+    FILE *src _AND_
+    Module *m _AND_
+    ModuleList *mods)
+{
+    void *tmp;
+    Module *impMod;
+
+    /*
+     * include snacc runtime library related hdrs
+     */
+    fprintf (src, "\n#include \"asn-incl.h\"\n");
+
+    /*
+     * print out include files in same order of the module
+     * list. every module in the list includes the others and it's
+     * own .h
+     */
+    tmp = (void*)CURR_LIST_NODE (mods);
+    FOR_EACH_LIST_ELMT (impMod, mods)
+    {
+        fprintf (src, "#include \"%s\"\n", impMod->cHdrFileName);
+    }
+    SET_CURR_LIST_NODE (mods, tmp);
+
+}  /* PrintCSrcIncludes */
+
+
+static void
+PrintCHdrComment PARAMS ((f, m),
+    FILE *f _AND_
+    Module *m)
+{
+    long int t;
+
+    t = time (0);
+    fprintf (f, "/*\n");
+    fprintf (f, " *    %s\n *\n", m->cHdrFileName);
+    fprintf (f, " *    \"%s\" ASN.1 module C type definitions and prototypes\n *\n", m->modId->name);
+    fprintf (f, " *    This .h file was generated by snacc on %s *\n", ctime (&t));
+    fprintf (f, " *    UBC snacc written compiler by Mike Sample\n *\n");
+    fprintf (f, " *    NOTE: This is a machine generated file--editing not recommended\n");
+    fprintf (f, " */\n\n\n");
+} /* PrintCHdrComment */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.c
new file mode 100644
index 00000000..0bdce013
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.c
@@ -0,0 +1,1912 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-dec.c - routines for printing C decoders from type trees
+ *
+ *   The type tree has already been run through the c type generator
+ *   (type-info.c).  Types that the type generator didn't know how
+ *   to handle (or didn't want/need to handle eg macros) get the
+ *   C_NO_TYPE label and are ignored for code generation.
+ *
+ *   NOTE: this is a real rats nest - it sort of evolved.  It was
+ *         written assuming SETs/SEQ/CHOICE etc could be nested
+ *         hence all the crap about 'levels'.
+ *
+ * Mike Sample
+ * 91/10/23
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-dec.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:41  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1997/02/28 13:39:54  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.3  1995/07/25 18:41:01  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-dec -> c-gen/gen-dec.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:22:06  rj
+ * snacc_config.h and other superfluous .h files removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:20  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "define.h"
+#include "lib-types.h"
+#include "rules.h"
+#include "type-info.h"
+#include "str-util.h"
+#include "snacc-util.h"
+#include "util.h"
+#include "tag-util.h"
+#include "gen-dec.h"
+
+
+static CRules *genDecCRulesG;
+char *valueArgNameG = "v";
+static long int *longJmpValG;
+static char *decodedLenVarNameG = "totalElmtsLen";
+static char *itemLenVarNameG = "elmtLen";
+static char *mecVarNameG = "mandatoryElmtCount";
+static char *tagIdVarNameG = "tagId";
+char *bufTypeNameG  = "BUF_TYPE";
+char *lenTypeNameG = "AsnLen";
+char *tagTypeNameG = "AsnTag";
+char *envTypeNameG = "ENV_TYPE";
+
+
+
+/* non-exported prototypes */
+
+static void PrintCBerDecoderPrototype PROTO ((FILE *hdr, TypeDef *td));
+static void PrintCBerDecoderDeclaration PROTO ((FILE *src, TypeDef *td));
+static void PrintCBerDecoderDefine PROTO ((FILE *src, TypeDef *td));
+
+static int RecCountVariableLevels PROTO ((Type *t));
+static int CountVariableLevels PROTO ((Type *t));
+static void PrintCBerDecoderLocals PROTO ((FILE *src, TypeDef *td));
+static void PrintCBerListDecoderLocals PROTO ((FILE *src));
+
+static void PrintCBerSetDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int elmtLevel, int totalLevel, int tagLevel, char *varName));
+
+static void PrintCBerSeqDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int elmtLevel, int totalLevel, int tagLevel, char *varName));
+
+static void PrintCBerListDecoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *varName));
+
+static void PrintCBerChoiceDecodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *varName));
+
+static void PrintCLenDecodingCode PROTO ((FILE *f));
+
+static void PrintCBerDecoderIncludes PROTO ((FILE *src, Module *m, ModuleList *mods));
+
+static void PrintCBerElmtDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *parnetVarName, char *elmtVarName, int stoleChoiceTags));
+
+
+void
+PrintCBerDecoder PARAMS ((src, hdr, r, m,  td, longJmpVal),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td _AND_
+    long int *longJmpVal)
+{
+    int i;
+    enum BasicTypeChoiceId typeId;
+    int elmtLevel;
+    CTDI *ctdi;
+    Tag *tag;
+    char *classStr;
+    char *formStr;
+    int stoleChoiceTags;
+    TagList *tags;
+
+    ctdi = td->cTypeDefInfo;
+    if (!ctdi->genDecodeRoutine)
+        return;
+
+    /*
+     *  if is type that refs another pdu type or lib type
+     *  without generating a new type via tagging or named elmts
+     *  print define to the hdr file
+     * (a type is a pdu by default if it is ref'd by an ANY)
+     */
+    if (!IsNewType (td->type)  &&
+          (!IsTypeRef (td->type) ||
+           (IsTypeRef (td->type) &&
+            (td->type->basicType->a.localTypeRef->link->cTypeDefInfo->isPdu ||
+             ((td->type->basicType->a.localTypeRef->link->anyRefs != NULL) &&
+              !LIST_EMPTY (td->type->basicType->a.localTypeRef->link->anyRefs))))))
+    {
+        fprintf(hdr,"#define B%s B%s\n", td->cTypeDefInfo->decodeRoutineName, td->type->cTypeRefInfo->decodeRoutineName);
+/*
+         fprintf(hdr,"#define B%s(b, v, bytesDecoded, env) B%s(b, v, bytesDecoded, env)\n", td->cTypeDefInfo->decodeRoutineName, td->type->cTypeRefInfo->decodeRoutineName);
+*/
+        return;
+    }
+
+
+
+    typeId = GetBuiltinType (td->type);
+
+    /* print proto type to hdr file */
+    fprintf (hdr, "void B%s PROTO ((%s b, %s *result, %s *bytesDecoded, %s env));\n", ctdi->decodeRoutineName, bufTypeNameG, ctdi->cTypeName, lenTypeNameG, envTypeNameG);
+
+    /* print routine in src */
+    fprintf (src,"void B%s PARAMS ((b, result, bytesDecoded, env),\n", ctdi->decodeRoutineName);
+    fprintf (src,"%s b _AND_\n", bufTypeNameG);
+    fprintf (src,"%s *result _AND_\n", ctdi->cTypeName);
+    fprintf (src,"%s *bytesDecoded _AND_\n", lenTypeNameG);
+    fprintf (src,"%s env)\n", envTypeNameG);
+    fprintf (src,"{\n");
+    fprintf (src,"    %s tag;\n", tagTypeNameG);
+
+    /* print extra locals for redundant lengths */
+    tags = GetTags (td->type, &stoleChoiceTags);
+    for (i = 1; !stoleChoiceTags && (i <= LIST_COUNT (tags)); i++)
+        fprintf (src,"    %s elmtLen%d;\n", lenTypeNameG, i);
+
+    /* add extra len for choice */
+    if (typeId == BASICTYPE_CHOICE)
+        fprintf (src,"    %s elmtLen%d;\n", lenTypeNameG, i);
+
+    fprintf (src,"\n");
+
+    /* decode tag/length pairs */
+    elmtLevel = 0;
+    if (!stoleChoiceTags)
+    {
+        FOR_EACH_LIST_ELMT (tag, tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+            if (tag->form == ANY_FORM)
+                formStr = Form2FormStr (PRIM);
+            else
+                formStr = Form2FormStr (tag->form);
+
+            fprintf (src,"    if (((tag = BDecTag (b, bytesDecoded, env)) != \n");
+
+            if (tag->tclass == UNIV)
+            {
+                fprintf (src,"MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, Code2UnivCodeStr (tag->code));
+                if (tag->form == ANY_FORM)
+                    fprintf (src,"&&\n         (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), Code2UnivCodeStr (tag->code));
+                else
+                    fprintf (src,")\n");
+            }
+            else
+            {
+                fprintf (src,"MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code);
+                if (tag->form == ANY_FORM)
+                    fprintf (src,"&&\n        (tag != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code);
+                else
+                    fprintf (src,")\n");
+
+            }
+            fprintf (src,"    {\n");
+            fprintf (src,"        Asn1Error (\"B%s: ERROR - wrong tag\\n\");\n", ctdi->decodeRoutineName);
+            fprintf (src,"        longjmp (env, %d);\n", (*longJmpVal)--);
+            fprintf (src,"    }\n");
+
+            fprintf (src,"    elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+        }
+    }
+
+    /* for choices always decode first tag of the choice's content */
+    if (typeId == BASICTYPE_CHOICE)
+    {
+        fprintf (src,"    tag = BDecTag (b, bytesDecoded, env);\n");
+        fprintf (src,"    elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel);
+    }
+
+    if ((typeId != BASICTYPE_ANY) && (typeId != BASICTYPE_ANYDEFINEDBY))
+        fprintf (src,"    B%sContent (b, tag, elmtLen%d, result, bytesDecoded, env);\n", ctdi->decodeRoutineName, elmtLevel);
+    else
+        fprintf (src,"    B%s (b, result, bytesDecoded, env);\n", ctdi->decodeRoutineName, elmtLevel);
+
+
+    /* grab any EOCs that match redundant, indef lengths */
+    for (i = elmtLevel-1; i > 0; i--)
+    {
+        fprintf (src,"    if (elmtLen%d == INDEFINITE_LEN)\n", i);
+        fprintf (src,"        BDecEoc (b, bytesDecoded, env);\n");
+    }
+
+
+    fprintf (src,"}  /* B%s */\n\n", ctdi->decodeRoutineName);
+
+    FreeTags (tags);
+}  /*  PrintCBerDecoder */
+
+
+void
+PrintCBerContentDecoder PARAMS ((src, hdr, r, m,  td, longJmpVal),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td _AND_
+    long int *longJmpVal)
+{
+    NamedType *e;
+    CTDI *ctdi;
+    CTypeId rhsTypeId;  /* cTypeId of the type that defined this typedef */
+    Type *t;
+    BER_FORM form;
+
+    longJmpValG = longJmpVal;
+
+    genDecCRulesG = r;
+
+    ctdi =  td->cTypeDefInfo;
+    if ((ctdi == NULL) || (td->type->cTypeRefInfo == NULL))
+    {
+        fprintf (stderr,"PrintCBerDecoder: ERROR - no type info\n");
+        return;
+    }
+
+    if (!ctdi->genDecodeRoutine)
+        return;
+
+    rhsTypeId = td->type->cTypeRefInfo->cTypeId;
+    switch (rhsTypeId)
+    {
+        /*
+         * type refs or primitive types are
+         * defined as calls to the referenced type
+         */
+        case C_ANY:
+            fprintf (hdr, "/* ANY - Fix Me! */\n");
+        case C_ANYDEFINEDBY:
+            fprintf(hdr, "#define B%s B%s\n", td->cTypeDefInfo->decodeRoutineName, td->type->cTypeRefInfo->decodeRoutineName);
+
+/*
+            fprintf(hdr, "#define B%s( b, tagId, elmtLen, v, bytesDecoded, env)  ", td->cTypeDefInfo->decodeRoutineName);
+            fprintf (hdr, "B%s (b, tagId, elmtLen, v, bytesDecoded, env)", td->type->cTypeRefInfo->decodeRoutineName);
+*/
+            fprintf (hdr,"\n\n");
+            break;
+
+        case C_LIB:
+        case C_TYPEREF:
+            PrintCBerDecoderDefine (hdr, td);
+            fprintf (hdr,"\n\n");
+            break;
+
+
+        case C_CHOICE:
+            PrintCBerDecoderPrototype (hdr, td);
+            fprintf (hdr,"\n\n");
+            PrintCBerDecoderDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCBerDecoderLocals (src, td);
+            fprintf (src,"\n\n");
+            PrintCBerChoiceDecodeCode (src, td, td->type, FIRST_LEVEL-1, FIRST_LEVEL,FIRST_LEVEL-1, valueArgNameG);
+
+            fprintf (src, "    (*bytesDecoded) += totalElmtsLen1;\n");
+            fprintf (src,"}  /* B%sContent */",td->cTypeDefInfo->decodeRoutineName);
+            fprintf (src,"\n\n");
+            break;
+
+        case C_STRUCT:
+            PrintCBerDecoderPrototype (hdr, td);
+            fprintf (hdr,"\n\n");
+            PrintCBerDecoderDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCBerDecoderLocals (src, td);
+            fprintf (src,"\n\n");
+            if (td->type->basicType->choiceId == BASICTYPE_SET)
+                PrintCBerSetDecodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG);
+            else
+                PrintCBerSeqDecodeCode (src, td, td->type, td->type->basicType->a.sequence, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG);
+
+            fprintf (src, "    (*bytesDecoded) += totalElmtsLen1;\n");
+            fprintf (src,"}  /* B%sContent */",td->cTypeDefInfo->decodeRoutineName);
+            fprintf (src,"\n\n");
+            break;
+
+
+        case C_LIST:
+            PrintCBerDecoderPrototype (hdr, td);
+            fprintf (hdr,"\n\n");
+
+            PrintCBerDecoderDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCBerDecoderLocals (src, td);
+            fprintf (src,"\n\n");
+            PrintCBerListDecoderCode (src, td, td->type,  FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG);
+
+            fprintf (src, "    (*bytesDecoded) += totalElmtsLen1;\n");
+            fprintf (src,"}  /* B%sContent */",td->cTypeDefInfo->decodeRoutineName);
+            fprintf (src,"\n\n");
+            break;
+
+        case C_NO_TYPE:
+/*            fprintf (src,"< sorry, unsupported type >\n\n"); */
+            return; /* dont' print newlines */
+            break;
+
+        default:
+            fprintf (stderr,"PrintCBerContentDecoder: ERROR - unknown c type id\n");
+            return;
+            break;
+    }
+
+}  /*  PrintCBerContentDecoder */
+
+
+
+
+/*
+ * Prints prototype for decode routine in hdr file
+ */
+
+static void
+PrintCBerDecoderPrototype PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+    CTDI *ctdi;
+
+    ctdi =  td->cTypeDefInfo;
+    fprintf (hdr,"void B%sContent PROTO ((%s b, %s tagId%d, %s elmtLen%d, %s *v, %s *bytesDecoded, %s env));\n", ctdi->decodeRoutineName, bufTypeNameG, tagTypeNameG, FIRST_LEVEL-1, lenTypeNameG, FIRST_LEVEL-1, ctdi->cTypeName,lenTypeNameG, envTypeNameG);
+
+}  /*  PrintCBerDecoderPrototype */
+
+
+
+/*
+ * Prints declarations of decode routine for the given type def
+ */
+static void
+PrintCBerDecoderDeclaration PARAMS ((src,td),
+    FILE *src _AND_
+    TypeDef *td)
+{
+    CTDI *ctdi;
+
+    ctdi =  td->cTypeDefInfo;
+    fprintf (src,"void\n");
+    fprintf (src,"B%sContent PARAMS ((b, tagId%d, elmtLen%d, v, bytesDecoded, env),\n", ctdi->decodeRoutineName, FIRST_LEVEL -1,  FIRST_LEVEL -1);
+    fprintf (src,"%s b _AND_\n", bufTypeNameG);
+    fprintf (src,"%s tagId%d _AND_\n", tagTypeNameG, FIRST_LEVEL -1);
+    fprintf (src,"%s elmtLen%d _AND_\n", lenTypeNameG, FIRST_LEVEL -1);
+    fprintf (src,"%s *v _AND_\n", ctdi->cTypeName);
+    fprintf (src,"%s *bytesDecoded _AND_\n", lenTypeNameG);
+    fprintf (src,"%s env)\n", envTypeNameG);
+
+}  /*  PrintCBerDecoderDeclaration */
+
+
+
+/*
+ * makes a define for type refs or primitive type renaming
+ * EG:
+ * TypeX ::= INTEGER --> #define BerDecodeTypeX(b,v) BerDecodeInteger(b,v)
+ * TypeX ::= TypeY --> #define BerDecodeTypeX(b,v) BerDecodeTypeY(b,v)
+ */
+static void
+PrintCBerDecoderDefine PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+    fprintf(hdr, "#define B%sContent B%sContent", td->cTypeDefInfo->decodeRoutineName, td->type->cTypeRefInfo->decodeRoutineName);
+
+/*
+    fprintf(hdr, "#define B%sContent( b, tagId, elmtLen, v, bytesDecoded, env)  ", td->cTypeDefInfo->decodeRoutineName);
+    fprintf (hdr, "B%sContent (b, tagId, elmtLen, v, bytesDecoded, env)", td->type->cTypeRefInfo->decodeRoutineName);
+*/
+}  /*  PrintCBerDecoderDefine */
+
+
+
+/*
+ * used to figure out local variables to declare
+ */
+static int
+RecCountVariableLevels PARAMS ((t),
+    Type *t)
+{
+    CTRI *ctri;
+    int maxLevels = 0;
+    NamedType *e;
+    TagList *tl;
+    int tagCount;
+    int typeCount;
+    void *tmp;
+    enum BasicTypeChoiceId typeId;
+
+    ctri = t->cTypeRefInfo;
+    typeId = GetBuiltinType (t);
+
+    /* embedded struct/choices aren't really an issue any more */
+    if ((ctri->cTypeId == C_STRUCT) ||
+        (ctri->cTypeId == C_CHOICE))
+    {
+        maxLevels = 1;
+
+        tagCount = CountTags (t);
+
+        tmp = (void*)CURR_LIST_NODE (t->basicType->a.set);
+        FOR_EACH_LIST_ELMT (e, t->basicType->a.set)
+        {
+            if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL))
+                continue;
+
+            typeCount = RecCountVariableLevels (e->type);
+
+            if (typeCount > maxLevels)
+                maxLevels = typeCount;
+        }
+        SET_CURR_LIST_NODE (t->basicType->a.set, tmp);
+        return maxLevels + tagCount;
+    }
+    else if (ctri->cTypeId == C_LIST)
+    {
+        return CountTags (t) +RecCountVariableLevels (t->basicType->a.setOf);
+    }
+    else if (typeId == BASICTYPE_CHOICE)
+        return CountTags (t) +1;
+    else if ((typeId == BASICTYPE_ANY) || (typeId == BASICTYPE_ANYDEFINEDBY))
+        return CountTags (t) +1;
+    else
+        return CountTags (t);
+
+}  /* RecCountVariableLevels */
+
+
+
+/*
+ * returns the number of variable contexts needed for
+ * decoding the contents of this type.  Does not consider tags on this type.
+ */
+static int
+CountVariableLevels PARAMS ((t),
+    Type *t)
+{
+    CTRI *ctri;
+    int maxLevels = 0;
+    NamedType *e;
+    TagList *tl;
+    int tagCount;
+    int typeCount;
+    void *tmp;
+
+    ctri =  t->cTypeRefInfo;
+
+    if ((ctri->cTypeId == C_STRUCT) ||
+        (ctri->cTypeId == C_CHOICE))
+    {
+        maxLevels = 1;
+        tmp = (void*)CURR_LIST_NODE (t->basicType->a.set);
+        FOR_EACH_LIST_ELMT (e, t->basicType->a.set)
+        {
+            if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL))
+                continue;
+
+            typeCount = RecCountVariableLevels (e->type);
+
+            /* add extra level since must decode key tag in choice */
+            if (GetBuiltinType (e->type) == BASICTYPE_CHOICE)
+                typeCount++;
+
+            if (typeCount > maxLevels)
+                maxLevels = typeCount;
+        }
+        SET_CURR_LIST_NODE (t->basicType->a.set, tmp);
+        return maxLevels;
+    }
+    else if (ctri->cTypeId == C_LIST)
+        return RecCountVariableLevels (t->basicType->a.setOf);
+    else if ((ctri->cTypeId == C_ANY) ||
+             (ctri->cTypeId == C_ANYDEFINEDBY))
+        return 1;
+    else
+        return 0;
+}  /* CountVariableLevels */
+
+
+
+/*
+ * prints local vars for constructed types (set/seq/choice)
+ */
+static void
+PrintCBerDecoderLocals PARAMS ((src,td),
+    FILE *src _AND_
+    TypeDef *td)
+{
+    int levels;
+    int i;
+
+    levels = CountVariableLevels (td->type);
+
+    fprintf (src, "    int seqDone = FALSE;\n");
+
+    for (i = 0; i < levels; i++)
+    {
+        fprintf (src, "    %s totalElmtsLen%d = 0;\n", lenTypeNameG, i + FIRST_LEVEL);
+        fprintf (src, "    %s elmtLen%d;\n", lenTypeNameG, i + FIRST_LEVEL);
+        fprintf (src, "    %s tagId%d;\n", tagTypeNameG, i + FIRST_LEVEL);
+        if (i == 0)
+            fprintf (src, "    int mandatoryElmtCount%d = 0;\n", i + FIRST_LEVEL);
+    }
+
+}  /*  PrintCBerDecoderLocals */
+
+
+/*
+ * given the Type *(t) of an elmt in a set/seq/choice/list,
+ * prints decoding code.
+ *   elmtVarName is string ptr ref to field being decoded
+ *     eg "(&personnelRecord.name)"
+ *   stoleChoiceTags is as returned by GetTags
+ *
+ * elmtLevel - last elmtLen# var that is valid/used (has a len)
+ * totalLevel - totalElmtsLen# to be used for running total of dec bytes
+ * tagIdLevel - last tagId# var that is valid/used (contains a tag)
+ */
+static void
+PrintCBerElmtDecodeCode PARAMS ((src, td, parent, t, elmtLevel, totalLevel, tagLevel, parentVarName, elmtVarName, stoleChoiceTags),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t _AND_
+    int elmtLevel _AND_
+    int totalLevel _AND_
+    int tagLevel _AND_
+    char *parentVarName _AND_
+    char *elmtVarName _AND_
+    int stoleChoiceTags)
+{
+    CTRI *ctri;
+    Type *tmpType;
+    char idVarRef[MAX_VAR_REF];
+    NamedType *idNamedType;
+    enum BasicTypeChoiceId tmpTypeId;
+
+    ctri =  t->cTypeRefInfo;
+
+    /* check if meant to be encoded */
+    if (!ctri->isEncDec)
+        return;
+
+    tmpType = GetType (t);
+
+    if (tmpType->basicType->choiceId == BASICTYPE_ANY)
+    {
+        fprintf (src,"/* ANY - Fix Me ! */\n");
+        fprintf (src,"    SetAnyTypeBy???(%s, ???);\n", elmtVarName);
+        fprintf (src,"    B%s (b, %s, &%s%d, env);\n", ctri->decodeRoutineName, elmtVarName, decodedLenVarNameG, totalLevel);
+    }
+    else if (tmpType->basicType->choiceId == BASICTYPE_ANYDEFINEDBY)
+    {
+        /* get type of 'defining' field (int/enum/oid)*/
+        idNamedType = t->basicType->a.anyDefinedBy->link;
+        tmpTypeId = GetBuiltinType (idNamedType->type);
+
+        if (tmpTypeId == BASICTYPE_OID)
+        {
+            MakeVarPtrRef (genDecCRulesG, td, parent, idNamedType->type, parentVarName, idVarRef);
+            fprintf (src, "    SetAnyTypeByOid (%s, %s);\n", elmtVarName, idVarRef);
+        }
+        else
+        {
+            /* want to ref int by value not ptr */
+            MakeVarValueRef (genDecCRulesG, td, parent, idNamedType->type, parentVarName, idVarRef);
+            fprintf (src, "    SetAnyTypeByInt (%s, %s);\n", elmtVarName, idVarRef);
+        }
+        fprintf (src,"    B%s (b, %s, &%s%d, env);\n", ctri->decodeRoutineName, elmtVarName, decodedLenVarNameG, totalLevel);
+    }
+    else switch (ctri->cTypeId)
+    {
+        case C_LIB:
+        case C_TYPEREF:
+            /*
+             * choices and octet/bit str types need tagId argument
+             */
+            if ((tmpType->basicType->choiceId == BASICTYPE_CHOICE) &&
+                !stoleChoiceTags)
+            {
+                /*
+                 * strip off top tag of choice in not already done
+                 * since choice decoders assume you are passing in
+                 * their top tag
+                 */
+                fprintf (src, "    %s%d = BDecTag (b, &%s%d, env);\n", tagIdVarNameG, ++tagLevel, decodedLenVarNameG, totalLevel);
+                fprintf (src, "    %s%d = BDecLen (b, &%s%d, env);\n", itemLenVarNameG, ++elmtLevel, decodedLenVarNameG, totalLevel);
+            }
+            fprintf (src,"    B%sContent (b, %s%d, %s%d, %s, &%s%d, env);\n", ctri->decodeRoutineName, tagIdVarNameG, tagLevel, itemLenVarNameG, elmtLevel, elmtVarName, decodedLenVarNameG, totalLevel);
+
+	    /* From ftp://ftp.cs.ubc.ca/pub/local/src/snacc/bugs-in-1.1 */
+	    if ((tmpType->basicType->choiceId == BASICTYPE_CHOICE)
+		    && !stoleChoiceTags)
+	    {
+		fprintf(src,"    if (elmtLen%d == INDEFINITE_LEN)\n", elmtLevel-1);
+		fprintf(src,"        BDecEoc(b, &totalElmtsLen%d, env);\n", totalLevel);
+	    }
+
+        break;
+
+
+        /*
+         * NOTE: the CHOICE, STRUCT and LIST switch clauses won't
+         * fire due to the current 'normalization'
+         * (see normalize.c)
+         */
+
+        case C_CHOICE:
+                /*
+                 * strip off top tag of choice in not already done
+                 * since choice decoders assume you are passing in
+                 * their top tag
+                 */
+            if (!stoleChoiceTags)
+            {
+                fprintf (src, "    %s%d = BDecTag (b, &%s%d, env);\n\n", tagIdVarNameG, ++tagLevel, decodedLenVarNameG, totalLevel);
+
+                fprintf (src, "    %s%d = BDecLen (b, &%s%d, env);\n", itemLenVarNameG, ++elmtLevel, decodedLenVarNameG, totalLevel);
+            }
+            PrintCBerChoiceDecodeCode (src, td, t, elmtLevel, totalLevel+1, tagLevel, elmtVarName);
+        break;
+
+
+        case C_STRUCT:
+            if (t->basicType->choiceId == BASICTYPE_SET)
+                PrintCBerSetDecodeCode (src, td, t, t->basicType->a.set, elmtLevel, totalLevel+1, tagLevel, elmtVarName);
+            else
+            {
+                PrintCBerSeqDecodeCode (src, td, t, t->basicType->a.sequence, elmtLevel,totalLevel+1, tagLevel, elmtVarName);
+                fprintf (src,"    seqDone = FALSE;\n");
+            }
+            fprintf (src,"             %s%d += %s%d;\n", decodedLenVarNameG, totalLevel, decodedLenVarNameG, totalLevel+1);
+        break;
+
+
+        case C_LIST:
+            PrintCBerListDecoderCode (src, td, t,  elmtLevel, totalLevel+1, tagLevel, elmtVarName);
+            fprintf (src,"\n\n");
+            fprintf (src,"             %s%d += %s%d;\n", decodedLenVarNameG, totalLevel, decodedLenVarNameG, totalLevel+1);
+        break;
+
+
+        case C_NO_TYPE:
+            break;
+
+        default:
+            fprintf (stderr,"PrintCBerElmtDecodeCode: ERROR - unknown c type id\n");
+        break;
+    }
+
+} /* PrintCBerElmtDecodeCode */
+
+
+/*
+ * Prints code for decoding the elmts of SET
+ */
+static void
+PrintCBerSetDecodeCode PARAMS ((src, td, parent, elmts, elmtLevel, totalLevel, tagLevel, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts _AND_
+    int elmtLevel _AND_
+    int totalLevel _AND_
+    int tagLevel _AND_
+    char *varName)
+{
+    NamedType *e;
+    CTRI *ctri;
+    TagList *tags;
+    Tag *tag;
+    TagList *tl;
+    enum BasicTypeChoiceId builtinType;
+    char *classStr;
+    char *formStr;
+    char *codeStr;
+    int   mandatoryCount = 0;
+    int   i;
+    char  tmpVarName[MAX_VAR_REF];
+    int   stoleChoiceTags;
+    char *routineName;
+    int initialTagLevel;
+    int initialElmtLevel;
+
+
+    initialTagLevel = tagLevel;
+    initialElmtLevel = elmtLevel;
+
+
+    routineName = td->cTypeDefInfo->decodeRoutineName;
+
+    if ((elmts == NULL) || LIST_EMPTY (elmts)) /* empty set */
+    {
+        fprintf (src,"    if (elmtLen%d == INDEFINITE_LEN)\n", elmtLevel);
+        fprintf (src,"    {\n");
+        fprintf (src,"        BDecEoc (b, &totalElmtsLen%d, env);\n", totalLevel);
+        fprintf (src,"    }\n");
+        fprintf (src,"    else if (elmtLen%d != 0)\n", elmtLevel);
+        fprintf (src,"    {\n");
+        fprintf (src,"         Asn1Error (\"Expected an empty SET\\n\");\n");
+        fprintf (src,"         longjmp (env, %d);\n",(*longJmpValG)--);
+
+        fprintf (src,"    }\n");
+
+/* forget about possible extension types for now
+        fprintf (src,"    if (elmtLen%d == INDEFINITE_LEN)\n", elmtLevel);
+        fprintf (src,"    {\n");
+        fprintf (src,"        tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", ++tagLevel, totalLevel);
+
+        fprintf (src,"        if (tagId%d == EOC_TAG_ID)\n", tagLevel);
+        fprintf (src,"            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", totalLevel);
+        fprintf (src,"        else\n");
+        fprintf (src,"            BerDiscardElmt (b, &totalElmtsLen%d, env);\n\n",totalLevel);
+        fprintf (src,"    }\n");
+        fprintf (src,"    else\n");
+        fprintf (src,"    {\n");
+        fprintf (src,"        BufSkip (b, elmtLen%d);\n", elmtLevel);
+        fprintf (src,"        totalElmtsLen%d += elmtLen%d;\n", totalLevel, elmtLevel);
+        fprintf (src,"    }\n");
+*/
+        return;
+    }
+
+
+    fprintf (src, "for ( ; (totalElmtsLen%d < elmtLen%d) || (elmtLen%d == INDEFINITE_LEN);)\n", totalLevel, elmtLevel, elmtLevel);
+    fprintf (src, "{\n");
+    fprintf (src, "    tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", ++tagLevel, totalLevel);
+    fprintf (src, "    if ((tagId%d == EOC_TAG_ID) && (elmtLen%d == INDEFINITE_LEN))\n", tagLevel, elmtLevel);
+    fprintf (src, "    {\n");
+    fprintf (src, "        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", totalLevel);
+    fprintf (src, "        break; /* got EOC so can exit this SET's for loop*/\n");
+    fprintf (src, "    }\n");
+
+    fprintf (src, "    elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+
+    fprintf (src, "    switch (tagId%d)\n", tagLevel);
+    fprintf (src, "    {\n");
+
+    FOR_EACH_LIST_ELMT (e, elmts)
+    {
+
+        elmtLevel = initialElmtLevel+1;
+        tagLevel = initialTagLevel+1;
+        if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL))
+        {
+            fprintf (src, "< ERROR - no c type information - prob unsuported type>\n");
+            continue;
+        }
+
+        ctri = e->type->cTypeRefInfo;
+
+        /* check if meant to be encoded */
+        if (!ctri->isEncDec)
+            continue;
+
+        tags  = GetTags (e->type, &stoleChoiceTags);
+        builtinType = GetBuiltinType (e->type);
+
+        if ((tags == NULL) || LIST_EMPTY (tags))
+        {
+            if ((builtinType != BASICTYPE_ANY) &&
+                (builtinType != BASICTYPE_ANYDEFINEDBY))
+                fprintf (src, "<What? no tag on a SetElmt?>\n");
+            else
+            {
+                fprintf (src,"       /* ANY - Fix Me ! */\n");
+                fprintf (src,"       case MAKE_TAG_ID (?,?,?):\n");
+            }
+        }
+        else
+        {
+            tag = (Tag*)FIRST_LIST_ELMT (tags);
+            classStr = Class2ClassStr (tag->tclass);
+            codeStr = Code2UnivCodeStr (tag->code);
+            formStr = Form2FormStr (tag->form);
+
+            if (tag->tclass == UNIV)
+            {
+                if (tag->form == ANY_FORM)
+                {
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+                }
+                else
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+            }
+            else
+            {
+                if (tag->form == ANY_FORM)
+                {
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                }
+                else
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code);
+            }
+
+            AsnListFirst (tags);
+            AsnListNext (tags); /* set curr to 2nd tag */
+            FOR_REST_LIST_ELMT (tag, tags)
+            {
+
+                codeStr = Code2UnivCodeStr (tag->code);
+                classStr = Class2ClassStr (tag->tclass);
+                formStr = Form2FormStr (tag->form);
+
+                if (stoleChoiceTags)
+                {
+                    if (tag->tclass == UNIV)
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                        }
+                        fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+                    }
+                    else
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                        }
+                        fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code);
+                    }
+                }
+                else
+                {
+                    tagLevel = initialTagLevel+2;
+                    if (tag->form == ANY_FORM)
+                    {
+                        fprintf (src,"    tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n", tagLevel, totalLevel);
+                        if (tag->tclass == UNIV)
+                        {
+                            fprintf (src,"if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr);
+                            fprintf (src,"   (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr);
+                        }
+                        else
+                        {
+                            fprintf (src,"if ((tagId%d != MAKE_TAG_ID (%s, %s, %d)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), tag->code);
+                            fprintf (src,"   (tagId%d != MAKE_TAG_ID (%s, %s, %d)))\n", tagLevel, classStr, Form2FormStr (CONS), tag->code);
+                        }
+
+                    }
+                    else
+                    {
+                        if (tag->tclass == UNIV)
+                            fprintf (src,"if (BDecTag (b, &totalElmtsLen%d, env) != MAKE_TAG_ID (%s, %s, %s))\n", totalLevel, classStr, formStr, codeStr);
+                        else
+                            fprintf (src,"if (BDecTag (b, &totalElmtsLen%d, env) != MAKE_TAG_ID (%s, %s, %d))\n", totalLevel, classStr, formStr, tag->code);
+                    }
+
+                    fprintf (src,"    {\n");
+                    fprintf (src,"         Asn1Error (\"Unexpected Tag\\n\");\n");
+                    fprintf (src,"         longjmp (env, %d);\n", (*longJmpValG)--);
+                    fprintf (src,"    }\n\n");
+                    fprintf (src,"elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+                }
+            }
+        }
+
+        MakeVarPtrRef (genDecCRulesG, td, parent, e->type, varName, tmpVarName);
+
+        /*
+         * allocate mem for decoding result
+         */
+        PrintElmtAllocCode (src, e->type, tmpVarName);
+
+        PrintCBerElmtDecodeCode (src, td, parent, e->type, elmtLevel, totalLevel, tagLevel, varName, tmpVarName, stoleChoiceTags);
+
+        /*
+         * must check for another EOC for ANYs
+         * Since the any decode routines
+         * decode their own first tag/len pair
+         */
+        if ((builtinType == BASICTYPE_ANY) ||
+            (builtinType == BASICTYPE_ANYDEFINEDBY))
+            PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+        /*
+         * must check for another EOC for tagged CHOICEs
+         * since the choice decoder routines do not check
+         * for an EOC on the choice's overall length -
+         * they are only passed the tag/len of the choice's
+         * component.
+         */
+        else if ((builtinType == BASICTYPE_CHOICE) && !(stoleChoiceTags) &&
+                ((tags != NULL) && !LIST_EMPTY (tags)))
+            PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+
+        else
+            PrintEocDecoders (src, elmtLevel-1, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+
+        if ((!e->type->optional) && (e->type->defaultVal == NULL))
+        {
+            mandatoryCount++;
+            fprintf (src, "    mandatoryElmtCount%d++;\n", totalLevel);
+        }
+
+        FreeTags (tags);
+
+        fprintf (src,"    break;\n\n");
+    }  /* end for */
+
+    fprintf (src, "    default:\n");
+    fprintf (src, "        Asn1Error (\"B%sContent: ERROR - Unexpected tag in SET\\n\");\n", routineName);
+    fprintf (src, "        longjmp (env, %d);\n",(*longJmpValG)--);
+    fprintf (src, "        break;\n");
+
+/*
+    fprintf (src, "        Asn1Warning (\"B%sContent: Warning - unexpected tag in SET, discarding elmt\\n\");\n", routineName);
+    fprintf (src, "        BerDiscardElmt (b, &totalElmtsLen%d, env);\n\n", totalLevel);
+*/
+
+    fprintf (src, "        } /* end switch */\n");
+    fprintf (src, "    } /* end for */\n");
+
+    fprintf (src, "    if (mandatoryElmtCount%d != %d)\n", totalLevel, mandatoryCount);
+
+    fprintf (src, "    {\n");
+    fprintf (src, "        Asn1Error (\"B%sContent: ERROR - non-optional elmt missing from SET\\n\");\n", routineName);
+    fprintf (src, "        longjmp (env, %d);\n",(*longJmpValG)--);
+    fprintf (src, "    }\n");
+
+}  /*  PrintCBerSetDecodeCode */
+
+
+
+
+/*
+ * Prints code for decoding the elmts of a SEQUENCE
+ */
+static void
+PrintCBerSeqDecodeCode PARAMS ((src, td, parent, elmts, elmtLevel, totalLevel, tagLevel, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts _AND_
+    int elmtLevel _AND_
+    int totalLevel _AND_
+    int tagLevel _AND_
+    char *varName)
+{
+    CTRI *ctri;
+    CTDI *ctdi;
+    NamedType *e;
+    NamedType *tmpElmt;
+    NamedType *last;
+    TagList *tags;
+    Tag *tag;
+    Tag *lastTag;
+    enum BasicTypeChoiceId builtinType;
+    enum BasicTypeChoiceId tmpTypeId;
+    char *classStr;
+    BER_FORM form;
+    char *formStr;
+    char *codeStr;
+    int   i;
+    char  tmpVarName[MAX_VAR_REF];
+    int   stoleChoiceTags;
+    char *routineName;
+    int   inTailOptElmts = FALSE;
+    int   initialElmtLevel;
+    int   initialTagLevel;
+
+
+    initialTagLevel = tagLevel;
+    initialElmtLevel = elmtLevel;
+
+
+    routineName = td->cTypeDefInfo->decodeRoutineName;
+
+    if ((elmts == NULL) || LIST_EMPTY (elmts)) /* empty seq */
+    {
+        fprintf (src,"    if (elmtLen%d == INDEFINITE_LEN)\n", elmtLevel);
+        fprintf (src,"    {\n");
+        fprintf (src,"        BDecEoc (b, &totalElmtsLen%d, env);\n", totalLevel);
+        fprintf (src,"    }\n");
+        fprintf (src,"    else if (elmtLen%d != 0)\n", elmtLevel);
+        fprintf (src,"    {\n");
+        fprintf (src,"         Asn1Error (\"Expected an empty SEQUENCE\\n\");\n");
+        fprintf (src,"         longjmp (env, %d);\n",(*longJmpValG)--);
+
+        fprintf (src,"    }\n");
+
+/*
+        forget about extended types for now
+        fprintf (src,"        tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel+1, totalLevel);
+        fprintf (src,"    {\n");
+        fprintf (src,"        if (tagId%d == EOC_TAG_ID)\n", tagLevel+1);
+        fprintf (src,"            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", totalLevel);
+        fprintf (src,"        else\n");
+        fprintf (src,"            BerDiscardElmt (b, &totalElmtsLen%d, env);\n\n",totalLevel);
+        fprintf (src,"    }\n");
+        fprintf (src,"    else \n");
+        fprintf (src,"    {\n");
+        fprintf (src,"        BufSkip (b, elmtLen%d);\n", elmtLevel);
+        fprintf (src,"        totalElmtsLen%d += elmtLen%d\n", totalLevel, elmtLevel);
+        fprintf (src,"    }\n");
+*/
+        return;
+    }
+
+    /*
+     * must set list curr since IsTailOptional checks from curr pt
+     * onward
+     */
+    AsnListFirst (elmts);
+    inTailOptElmts = IsTailOptional (elmts);
+    e = (NamedType*)FIRST_LIST_ELMT (elmts);
+    tmpTypeId = GetBuiltinType (e->type);
+
+    /*
+     * print code to decode the first tag
+     */
+    tagLevel++;
+    if (!inTailOptElmts)
+    {
+        if (((tmpTypeId == BASICTYPE_ANY) ||
+             (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) &&
+            (CountTags (e->type) == 0))
+        {
+            if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (elmts)))
+            {
+                /* let this cause a compile error in the generated code */
+                fprintf (src,"<untagged optional ANY - you must fix this>\n");
+            }
+        }
+        else
+            fprintf (src, "    tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel, totalLevel);
+    }
+    else
+    {
+        fprintf (src, "    if ((elmtLen%d != INDEFINITE_LEN) && (totalElmtsLen%d == elmtLen%d))\n", elmtLevel, totalLevel, elmtLevel);
+        fprintf (src, "        seqDone = TRUE;\n");
+        fprintf (src, "    else\n");
+        fprintf (src, "    {\n");
+
+        if (((tmpTypeId == BASICTYPE_ANY) ||
+             (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) &&
+            (CountTags (e->type) == 0))
+        {
+            if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (elmts)))
+            {
+                /* let this cause a compile error in the generated code */
+                fprintf (src,"<untagged optional ANY - you must fix this>\n");
+            }
+        }
+        else
+            fprintf (src, "        tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel, totalLevel);
+        fprintf (src,"         if ((elmtLen%d == INDEFINITE_LEN) && (tagId%d == EOC_TAG_ID))\n", elmtLevel, tagLevel);
+        fprintf (src, "        {\n");
+        fprintf (src, "            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", totalLevel);
+        fprintf (src, "            seqDone = TRUE;\n");
+        fprintf (src, "        }\n");
+        fprintf (src, "    }\n\n");
+    }
+
+    last = (NamedType*)LAST_LIST_ELMT (elmts);
+    FOR_EACH_LIST_ELMT (e, elmts)
+    {
+        elmtLevel = initialElmtLevel;
+        tagLevel = initialTagLevel+1;
+
+        if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL))
+        {
+            fprintf (src, "< ERROR - no c type information - prob unsuported type>\n");
+            continue;
+        }
+
+        ctri = e->type->cTypeRefInfo;
+
+        /* check if meant to be encoded */
+        if (!ctri->isEncDec)
+            continue;
+
+        tags  = GetTags (e->type, &stoleChoiceTags);
+        builtinType = GetBuiltinType (e->type);
+
+
+        if ((tags == NULL) || LIST_EMPTY (tags))
+        {
+            if ((builtinType != BASICTYPE_ANY) &&
+                (builtinType != BASICTYPE_ANYDEFINEDBY))
+                fprintf (src, "<What? no tag on a SetElmt?>\n");
+
+            if (inTailOptElmts)
+            {
+                fprintf (src,"    if (!seqDone)");
+            }
+            /* always enclose elmt decoder in block */
+            fprintf (src,"    {\n");
+
+/*
+             else
+            {
+                fprintf (src,"    if (tagId%d == MAKE_TAG_ID (?, ?, ?))\n", tagLevel);
+                fprintf (src,"    {\n");
+            }
+*/
+        }
+        else  /* has tags */
+        {
+            tag = (Tag*)FIRST_LIST_ELMT (tags);
+
+            classStr = Class2ClassStr (tag->tclass);
+            codeStr = Code2UnivCodeStr (tag->code);
+            formStr = Form2FormStr (tag->form);
+
+
+
+            if (inTailOptElmts)
+                fprintf (src,"    if ((!seqDone) && (");
+            else
+                fprintf (src,"    if ((");
+
+            if (tag->tclass == UNIV)
+            {
+                if (tag->form == ANY_FORM)
+                {
+                    fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %s)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr);
+                fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), codeStr);
+                }
+                else
+                    fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, codeStr);
+            }
+            else
+            {
+                if (tag->form == ANY_FORM)
+                {
+                    fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %d)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), tag->code);
+                fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %d))", tagLevel, classStr, Form2FormStr (CONS), tag->code);
+                }
+                else
+                    fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %d))", tagLevel, classStr, formStr, tag->code);
+            }
+
+            if (!stoleChoiceTags)
+            {
+                fprintf (src,"))\n");
+                fprintf (src, "    {\n");
+                fprintf (src,"    elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+            }
+
+            AsnListFirst (tags);
+            AsnListNext (tags);
+
+            FOR_REST_LIST_ELMT (tag, tags)
+            {
+                classStr = Class2ClassStr (tag->tclass);
+                codeStr = Code2UnivCodeStr (tag->code);
+                formStr = Form2FormStr (tag->form);
+
+
+                if (stoleChoiceTags)
+                {
+                    fprintf (src," ||\n");
+                    if (tag->tclass == UNIV)
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src,"     (tagId%d ==MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (PRIM), codeStr);
+                            fprintf (src,"||\n    (tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), codeStr);
+                        }
+                        else
+                            fprintf (src,"     (tagId%d ==MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, codeStr);
+                    }
+                    else
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src,"    (tagId%d == MAKE_TAG_ID (%s, %s, %d))", tagLevel, classStr, Form2FormStr (PRIM), tag->code);
+                            fprintf (src,"||\n    (tagId%d == MAKE_TAG_ID (%s, %s, %d))", tagLevel, classStr, Form2FormStr (CONS), tag->code);
+                        }
+                        else
+                            fprintf (src,"    (tagId%d == MAKE_TAG_ID (%s, %s, %d))", tagLevel, classStr, formStr, tag->code);
+                    }
+                }
+                else
+                {
+
+                    tagLevel = initialTagLevel + 2;
+                    fprintf (src, "        tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel, totalLevel);
+                    if (tag->tclass == UNIV)
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src,"    if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr);
+                            fprintf (src,"       (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr);
+                        }
+                        else
+                            fprintf (src,"    if (tagId%d != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, classStr, formStr, codeStr);
+                    }
+                    else
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src,"    if ((tagId%d != MAKE_TAG_ID (%s, %s, %d)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), tag->code);
+                            fprintf (src,"        (tagId%d != MAKE_TAG_ID (%s, %s, %d)))\n", tagLevel, classStr, Form2FormStr (CONS), tag->code);
+                        }
+                        else
+                            fprintf (src,"    if (tagId%d != MAKE_TAG_ID (%s, %s, %d))\n", tagLevel, classStr, formStr, tag->code);
+                    }
+
+
+                    fprintf (src,"    {\n");
+                    fprintf (src,"         Asn1Error (\"Unexpected Tag\\n\");\n");
+                    fprintf (src,"         longjmp (env, %d);\n",(*longJmpValG)--);
+                    fprintf (src,"    }\n\n");
+                    fprintf (src,"    elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+                }
+            } /* end tag list for */
+
+            if (stoleChoiceTags)
+            {
+                fprintf (src,"))\n");
+                fprintf (src, "    {\n");
+                fprintf (src, "        elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+            }
+        }
+
+
+        MakeVarPtrRef (genDecCRulesG, td, parent, e->type, varName, tmpVarName);
+
+        /*
+         * allocate mem for decoding result
+         */
+        PrintElmtAllocCode (src, e->type, tmpVarName);
+
+        PrintCBerElmtDecodeCode (src, td, parent, e->type, elmtLevel, totalLevel, tagLevel, varName, tmpVarName, stoleChoiceTags);
+
+        /*
+         * must check for another EOC for ANYs
+         * Since the any decode routines
+         * decode their own first tag/len pair
+         */
+        if ((builtinType == BASICTYPE_ANY) ||
+            (builtinType == BASICTYPE_ANYDEFINEDBY))
+            PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+        /*
+         * must check for another EOC for tagged CHOICEs
+         * since the choice decoder routines do not check
+         * for an EOC on the choice's overall length -
+         * they are only passed the tag/len of the choice's
+         * component.
+         */
+        else if ((builtinType == BASICTYPE_CHOICE) && (!stoleChoiceTags) &&
+                ((tags != NULL) && !LIST_EMPTY (tags)))
+            PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+
+        else
+            PrintEocDecoders (src, elmtLevel-1, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+
+
+        /*  could check cons len vs decode len here */
+
+        if (!inTailOptElmts)
+        {
+            /*
+             * determine whether next elmt in Seq is start
+             * of tailing optionals
+             */
+            AsnListNext (elmts);
+            inTailOptElmts = IsTailOptional (elmts);
+            AsnListPrev (elmts);
+        }
+
+        /*
+         * print code for getting the next tag
+         */
+        tmpTypeId = GetBuiltinType (e->type);
+
+        if  (e != last)
+        {
+            tmpElmt = (NamedType*)NEXT_LIST_ELMT (elmts);
+            tmpTypeId = GetBuiltinType (tmpElmt->type);
+            if (!inTailOptElmts)
+            {
+                if (((tmpTypeId == BASICTYPE_ANY) ||
+                     (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) &&
+                    (CountTags (tmpElmt->type) == 0))
+                {
+                    if ((e->type->optional) ||
+                        ((tmpElmt->type->optional) && (tmpElmt != last)))
+                    {
+                        /* let this cause a compile error in the gen'd code */
+                        fprintf (src,"  <problems with untagged ANY that is optional or follows an optional sequence element - you must fix this>\n");
+                    }
+                    /* don't get a tag since ANY's decode their own */
+                }
+                else
+                    fprintf (src, "    tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n", initialTagLevel+1, totalLevel);
+            }
+            else
+            {
+                fprintf (src, "    if ((elmtLen%d != INDEFINITE_LEN) && (totalElmtsLen%d == elmtLen%d))\n", initialElmtLevel, totalLevel, initialElmtLevel);
+                fprintf (src, "        seqDone = TRUE;\n");
+                fprintf (src, "    else\n");
+                fprintf (src, "    {\n");
+                if (((tmpTypeId == BASICTYPE_ANY) ||
+                     (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) &&
+                    (CountTags (tmpElmt->type) == 0))
+                {
+                    if ((e->type->optional) ||
+                        ((tmpElmt->type->optional) && (tmpElmt != last)))
+                    {
+                        /* let this cause a compile error in the gen'd code */
+                        fprintf (src,"  <problems with untagged ANY that is optional or follows an optional sequence element - you must fix this>\n");
+
+                    }
+
+                    /* peek ahead for first octet of eoc */
+                    fprintf (src,"         tagId%d = BufPeekByte (b);\n", initialTagLevel+1);
+                    fprintf (src,"         if ((elmtLen%d == INDEFINITE_LEN) && (tagId%d == EOC_TAG_ID))\n", initialElmtLevel, initialTagLevel+1);
+                    fprintf (src, "        {\n");
+                    fprintf (src, "            BDecEoc (b, &totalElmtsLen%d, env);\n", totalLevel);
+                    fprintf (src, "            seqDone = TRUE;\n");
+                    fprintf (src, "        }\n");
+                }
+                else
+                {
+                    fprintf (src, "        tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", initialTagLevel+1, totalLevel);
+                    fprintf (src,"         if ((elmtLen%d == INDEFINITE_LEN) && (tagId%d == EOC_TAG_ID))\n", initialElmtLevel, initialTagLevel+1);
+                    fprintf (src, "        {\n");
+                    fprintf (src, "            BDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", totalLevel);
+                    fprintf (src, "            seqDone = TRUE;\n");
+                    fprintf (src, "        }\n");
+                }
+                fprintf (src, "    }\n");
+            }
+        }
+        else /* for last elmt only */
+        {
+            fprintf (src,"        seqDone = TRUE;\n");
+            fprintf (src,"        if (elmtLen%d == INDEFINITE_LEN)\n", initialElmtLevel);
+            fprintf (src,"            BDecEoc (b, &totalElmtsLen%d, env);\n", totalLevel);
+            fprintf (src,"        else if (totalElmtsLen%d != elmtLen%d)\n", totalLevel, initialElmtLevel);
+            fprintf (src,"            longjmp (env, %d);\n",(*longJmpValG)--);
+        }
+
+        /*
+         * close (tag check/seqDone test) if block and
+         * print else clause to handle missing non-optional elmt
+         * errors
+         */
+        tmpTypeId = GetBuiltinType (e->type);
+        if (((tmpTypeId == BASICTYPE_ANYDEFINEDBY) ||
+             (tmpTypeId == BASICTYPE_ANY)) &&
+            (CountTags (e->type) == 0))
+        {
+            /* close if stmt block */
+            fprintf (src,"    }\n");
+        }
+        else if (!e->type->optional && (e->type->defaultVal == NULL))
+        {
+
+            fprintf (src, "    }\n"); /* end of tag check if */
+            fprintf (src, "    else\n");
+            fprintf (src, "        longjmp (env, %d);\n", (*longJmpValG)--);
+        }
+        else
+        {
+            fprintf (src, "    }\n"); /* end of tag check if */
+        }
+
+        fprintf (src,"\n\n");
+        FreeTags (tags);
+    }
+
+
+    /*
+     * print code to make sure that truly finished with sequence
+     */
+
+    fprintf (src,"    if (!seqDone)\n");
+    fprintf (src, "        longjmp (env, %d);\n\n", (*longJmpValG)--);
+
+}  /*  PrintCBerSeqDecodeCode */
+
+
+/*
+ * Generates code for internally defined lists
+ * eg:
+ * TypeX = SET { foo INTEGER, bar SEQUENCE OF INTEGER } -->
+ * BerDecodeTypeX (b, len, v, bytesDecoded, env)
+ * {
+ *    ...
+ *         listLen1 = BerDecodeLen (b, &totalElmtsLen, env);
+ *         retVal->bar = NewList();
+ *         for ( ; totalElmtsLen1 < listLen1 || listLen1== INDEFINITE_LEN;)
+ *         {
+ *              tagId1 = BerDecodeTag (b, &totalElmtsLen1, env);
+ *               check for EOC
+ *              elmtLen1 = BerDecodeLen (b, &totalElmtsLen1, env)
+ *              tmpInt = Asn1Alloc (sizeof (int));
+ *              BerDecodeInteger (b, elmtLen1, tmpInt, &totalElmtsLen1, env);
+ *              AppendList (retVal->bar, tmpInt);
+ *         }
+ *         totalElmtsLen += totalElmtsLen1;
+ *    ...
+ * }
+ */
+static void
+PrintCBerListDecoderCode PARAMS ((src, td, list, elmtLevel, totalLevel, tagLevel, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *list _AND_
+    int elmtLevel _AND_
+    int totalLevel _AND_
+    int tagLevel _AND_
+ char *varName)
+{
+    CTRI *ctri;
+    TagList *tags;
+    Tag  *tag;
+    Tag  *lastTag;
+    enum BasicTypeChoiceId builtinType;
+    char *classStr;
+    BER_FORM form;
+    char *formStr;
+    char *codeStr;
+    int   mandatoryCount = 0;
+    int   i;
+    char tmpVarName[MAX_VAR_REF];
+    int  stoleChoiceTags;
+    char *routineName;
+    int initialTagLevel;
+    int initialElmtLevel;
+    int taglessAny;
+
+    initialTagLevel = tagLevel;
+    initialElmtLevel = elmtLevel;
+
+
+    routineName = td->cTypeDefInfo->decodeRoutineName;
+    ctri = list->basicType->a.setOf->cTypeRefInfo;
+    tags  = GetTags (list->basicType->a.setOf, &stoleChoiceTags);
+    builtinType = GetBuiltinType (list->basicType->a.setOf);
+
+    taglessAny = (((tags == NULL) || LIST_EMPTY (tags)) &&
+                  ((builtinType == BASICTYPE_ANY) ||
+                   (builtinType == BASICTYPE_ANYDEFINEDBY)));
+
+    fprintf (src, "    for (totalElmtsLen%d = 0; (totalElmtsLen%d < elmtLen%d) || (elmtLen%d == INDEFINITE_LEN);)\n", totalLevel, totalLevel, elmtLevel, elmtLevel);
+    fprintf (src, "    {\n");
+    fprintf (src,"        %s **tmpVar;\n", ctri->cTypeName);
+
+    if (taglessAny)
+    {
+        fprintf (src, "    tagId%d = BufPeekByte (b);\n\n", ++tagLevel);
+        fprintf (src, "    if ((tagId%d == EOC_TAG_ID) && (elmtLen%d == INDEFINITE_LEN))\n", tagLevel, elmtLevel);
+        fprintf (src, "    {\n");
+        fprintf (src, "        BDecEoc (b, &totalElmtsLen%d, env);\n", totalLevel);
+        fprintf (src, "        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/\n");
+        fprintf (src, "    }\n");
+    }
+    else
+    {
+        fprintf (src, "    tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", ++tagLevel, totalLevel);
+        fprintf (src, "    if ((tagId%d == EOC_TAG_ID) && (elmtLen%d == INDEFINITE_LEN))\n", tagLevel, elmtLevel);
+        fprintf (src, "    {\n");
+        fprintf (src, "        BDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", totalLevel);
+        fprintf (src, "        break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/\n");
+        fprintf (src, "    }\n");
+    }
+
+
+    if ((tags == NULL) || LIST_EMPTY (tags))
+    {
+        if (!taglessAny)
+            fprintf (src, "<What? no tag on a SET OF/SEQ OF Elmt?>\n");
+/*
+        else
+        {
+            fprintf (src,"    if (tagId%d == MAKE_TAG_ID (?, ?, ?))",tagLevel);
+            fprintf (src,"    {\n");
+        }
+*/
+
+    }
+    else if (!stoleChoiceTags) /* choice decoder will check tag */
+    {
+        tag = (Tag*)FIRST_LIST_ELMT (tags);
+        classStr = Class2ClassStr (tag->tclass);
+        codeStr = Code2UnivCodeStr (tag->code);
+        formStr = Form2FormStr (tag->form);
+
+        if (tag->tclass == UNIV)
+        {
+            if (tag->form == ANY_FORM)
+            {
+                fprintf (src,"    if ((tagId%d == MAKE_TAG_ID (%s, %s, %s)) ||", tagLevel, classStr, Form2FormStr (PRIM), codeStr);
+
+                fprintf (src,"         (tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), codeStr);
+            }
+            else
+                fprintf (src,"    if ((tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, codeStr);
+        }
+        else
+        {
+            if (tag->form == ANY_FORM)
+            {
+                fprintf (src,"    if ((tagId%d == MAKE_TAG_ID (%s, %s, %d)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), tag->code);
+                fprintf (src,"       (tagId%d == MAKE_TAG_ID (%s, %s, %d))", tagLevel, classStr, Form2FormStr (CONS), tag->code);
+            }
+            else
+                fprintf (src,"    if ((tagId%d == MAKE_TAG_ID (%s, %s, %d))", tagLevel, classStr, formStr, tag->code);
+        }
+
+        fprintf (src,")\n");
+        fprintf (src, "    {\n");
+        fprintf (src, "        elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+
+        AsnListFirst (tags);
+        AsnListNext (tags);
+        FOR_REST_LIST_ELMT (tag, tags)
+        {
+            tagLevel = initialTagLevel+2;
+            fprintf (src, "        tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel, totalLevel);
+            classStr = Class2ClassStr (tag->tclass);
+            codeStr = Code2UnivCodeStr (tag->code);
+            formStr = Form2FormStr (tag->form);
+
+            if (tag->tclass == UNIV)
+            {
+                if (tag->form == ANY_FORM)
+                {
+                    fprintf (src,"    if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr);
+                    fprintf (src,"        (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr);
+                }
+                else
+                    fprintf (src,"    if (tagId%d != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, classStr, formStr, codeStr);
+            }
+            else
+            {
+                if (tag->form == ANY_FORM)
+                {
+                    fprintf (src,"    if ((tagId%d != MAKE_TAG_ID (%s, %s, %d)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), tag->code);
+                    fprintf (src,"        (tagId%d != MAKE_TAG_ID (%s, %s, %d)))\n", tagLevel, classStr, Form2FormStr (CONS), tag->code);
+
+                }
+                else
+                    fprintf (src,"    if (tagId%d != MAKE_TAG_ID (%s, %s, %d))\n", tagLevel, classStr, formStr, tag->code);
+            }
+
+
+            fprintf (src,"    {\n");
+            fprintf (src,"         Asn1Error (\"Unexpected Tag\\n\");\n");
+            fprintf (src,"         longjmp (env, %d);\n", (*longJmpValG)--);
+            fprintf (src,"    }\n\n");
+            fprintf (src,"    elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+        }
+    }
+    if (stoleChoiceTags)
+    {
+        fprintf (src, "        elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+    }
+
+
+
+    strcpy (tmpVarName, "(*tmpVar)");
+    fprintf (src,"    tmpVar = (%s**) AsnListAppend (%s);\n", ctri->cTypeName, varName);
+    fprintf (src, "    %s = (%s*) Asn1Alloc (sizeof (%s));\n", tmpVarName, ctri->cTypeName, ctri->cTypeName);
+
+    fprintf (src,"    CheckAsn1Alloc (%s, env);\n", tmpVarName);
+    PrintCBerElmtDecodeCode (src, td, list, list->basicType->a.setOf, elmtLevel, totalLevel, tagLevel, varName, tmpVarName, stoleChoiceTags);
+
+    /*
+     * must check for another EOC for ANYs
+     * Since the any decode routines
+     * decode their own first tag/len pair
+     */
+    if ((builtinType == BASICTYPE_ANY) ||
+        (builtinType == BASICTYPE_ANYDEFINEDBY))
+        PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+        /*
+         * must check for another EOC for tagged CHOICEs
+         * since the choice decoder routines do not check
+         * for an EOC on the choice's overall length -
+         * they are only passed the tag/len of the choice's
+         * component.
+         */
+    else if ((builtinType == BASICTYPE_CHOICE) && (!stoleChoiceTags) &&
+             ((tags != NULL) && !LIST_EMPTY (tags)))
+        PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+
+    else
+        PrintEocDecoders (src, elmtLevel-1, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+
+
+    if ((!stoleChoiceTags) && (!taglessAny))
+    {
+        fprintf (src, "    }  /* end of tag check if */\n");
+        fprintf (src, "    else  /* wrong tag */\n");
+        fprintf (src,"    {\n");
+        fprintf (src,"         Asn1Error (\"Unexpected Tag\\n\");\n");
+        fprintf (src,"         longjmp (env, %d);\n", (*longJmpValG)--);
+        fprintf (src,"    }\n");
+    }
+    fprintf (src, "    } /* end of for */\n\n");
+
+    FreeTags (tags);
+
+}  /*  PrintCBerListDecodeCode */
+
+
+
+/*
+ * t is the choice type pointer
+ */
+static void
+PrintCBerChoiceDecodeCode PARAMS ((src, td, t, elmtLevel, totalLevel, tagLevel, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    int elmtLevel _AND_
+    int totalLevel _AND_
+    int tagLevel _AND_
+    char *varName)
+{
+    NamedType *e;
+    CTRI *ctri;
+    TagList *tags;
+    Tag *tag;
+    Tag *lastTag;
+    enum BasicTypeChoiceId builtinType;
+    char *classStr;
+    BER_FORM form;
+    char *formStr;
+    char *codeStr;
+    int   mandatoryCount = 0;
+    int   i;
+    char  tmpVarName[MAX_VAR_REF];
+    char  choiceIdVarName[MAX_VAR_REF];
+    CTRI *parentCtri;
+    int   stoleChoiceTags;
+    void *tmp;
+    int initialTagLevel;
+    int initialElmtLevel;
+
+    initialTagLevel = tagLevel;
+    initialElmtLevel = elmtLevel;
+
+    parentCtri = t->cTypeRefInfo;
+
+
+    fprintf (src, "    switch (tagId%d)\n", tagLevel);
+    fprintf (src, "    {\n");
+
+
+    FOR_EACH_LIST_ELMT (e,  t->basicType->a.choice)
+    {
+        /* hack ! remember curr loc cause called routine hacks it */
+        tmp = (void*)CURR_LIST_NODE (t->basicType->a.choice);
+
+        tagLevel = initialTagLevel;
+        elmtLevel = initialElmtLevel;
+
+        if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL))
+        {
+            fprintf (src, "< ERROR - no c type information - prob unsuported type>\n");
+            continue;
+        }
+
+        ctri =  e->type->cTypeRefInfo;
+
+        tags  = GetTags (e->type, &stoleChoiceTags);
+        builtinType = GetBuiltinType (e->type);
+
+        if ((tags == NULL) || LIST_EMPTY (tags))
+        {
+            if ((builtinType != BASICTYPE_ANY) &&
+                (builtinType != BASICTYPE_ANYDEFINEDBY))
+                fprintf (src, "<What? no tag on a CHOICE elmt?>\n");
+            else
+            {
+                fprintf (src, "    /* You must hand code ANY type refs */\n");
+                fprintf (src,"       case MAKE_TAG_ID (?, ?, ?):\n");
+
+            }
+
+        }
+        else
+        {
+            tag = (Tag*)FIRST_LIST_ELMT (tags);
+            classStr = Class2ClassStr (tag->tclass);
+            codeStr = Code2UnivCodeStr (tag->code);
+            formStr = Form2FormStr (tag->form);
+
+            if (tag->tclass == UNIV)
+            {
+                if (tag->form == ANY_FORM)
+                {
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+                }
+                else
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+            }
+            else
+            {
+                if (tag->form == ANY_FORM)
+                {
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+                }
+                else
+                    fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code);
+            }
+
+
+	    AsnListFirst (tags);
+	    AsnListNext (tags); /* set curr ptr to 2nd elmt */
+            FOR_REST_LIST_ELMT (tag, tags)
+            {
+                classStr = Class2ClassStr (tag->tclass);
+                codeStr = Code2UnivCodeStr (tag->code);
+                formStr = Form2FormStr (tag->form);
+
+
+                if (stoleChoiceTags)
+                {
+                    if (tag->tclass == UNIV)
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+                        }
+                        else
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+                    }
+                    else
+                    {
+                        if (tag->form == ANY_FORM)
+                        {
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code);
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code);
+                        }
+                        else
+                            fprintf (src,"       case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code);
+                    }
+                }
+                else
+                {
+                    tagLevel = initialTagLevel +1;
+                    if (tag->form == ANY_FORM)
+                    {
+                        fprintf (src,"    tagId%d = BDecTag (b, &totalElmtsLen%d, env);\n", tagLevel, totalLevel);
+                        if (tag->tclass == UNIV)
+                        {
+                            fprintf (src,"if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr);
+                            fprintf (src,"   (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr);
+                        }
+                        else
+                        {
+                            fprintf (src,"if ((tagId%d != MAKE_TAG_ID (%s, %s, %d)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), tag->code);
+                            fprintf (src,"   (tagId%d != MAKE_TAG_ID (%s, %s, %d)))\n", tagLevel, classStr, Form2FormStr (CONS), tag->code);
+                        }
+
+                    }
+                    else
+                    {
+                        if (tag->tclass == UNIV)
+                            fprintf (src,"if (BDecTag (b, &totalElmtsLen%d, env) != MAKE_TAG_ID (%s, %s, %s))\n", totalLevel, classStr, formStr, codeStr);
+                        else
+                            fprintf (src,"if (BDecTag (b, &totalElmtsLen%d, env) != MAKE_TAG_ID (%s, %s, %d))\n", totalLevel, classStr, formStr, tag->code);
+                    }
+
+                    fprintf (src,"    {\n");
+                    fprintf (src,"         Asn1Error (\"Unexpected Tag\\n\");\n");
+                    fprintf (src,"         longjmp (env, %d);\n", (*longJmpValG)--);
+                    fprintf (src,"    }\n\n");
+                    fprintf (src,"    elmtLen%d = BDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, totalLevel);
+                }
+            }
+        }
+
+
+        MakeChoiceIdValueRef (genDecCRulesG, td, t, e->type, varName, choiceIdVarName);
+        fprintf (src, "        %s = %s;\n", choiceIdVarName, ctri->choiceIdSymbol);
+
+        MakeVarPtrRef (genDecCRulesG, td, t, e->type, varName, tmpVarName);
+
+        PrintElmtAllocCode (src, e->type, tmpVarName);
+
+        PrintCBerElmtDecodeCode (src, td, t, e->type, elmtLevel, totalLevel, tagLevel, varName, tmpVarName, stoleChoiceTags);
+
+        /*
+         * this is slightly diff from set/seq since
+         * no loop checking for eoc (set) and no next elmt (seq)
+         * so should check elmtLen0 for EOC if nec
+         * (therefore (initialElmtLevel-1) instead of initialElmtLevel)
+         *
+         * must check for another EOC for ANYs
+         * Since the any decode routines
+         * decode their own first tag/len pair
+         */
+        if ((builtinType == BASICTYPE_ANY) ||
+            (builtinType == BASICTYPE_ANYDEFINEDBY))
+            PrintEocDecoders (src, elmtLevel, initialElmtLevel-1, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+        /*
+         * must check for another EOC for tagged CHOICEs
+         * since the choice decoder routines do not check
+         * for an EOC on the choice's overall length -
+         * they are only passed the tag/len of the choice's
+         * component.
+         */
+        else if ((builtinType == BASICTYPE_CHOICE) && (!stoleChoiceTags) &&
+                ((tags != NULL) && !LIST_EMPTY (tags)))
+            PrintEocDecoders (src, elmtLevel, initialElmtLevel-1, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+
+        else
+            PrintEocDecoders (src, elmtLevel-1, initialElmtLevel-1, itemLenVarNameG, totalLevel, decodedLenVarNameG);
+
+
+        FreeTags (tags);
+
+        fprintf (src,"    break;\n\n");
+
+        /* reset curr list node to value remember at beg of loop */
+        SET_CURR_LIST_NODE (t->basicType->a.choice, tmp);
+    }  /* end for */
+
+    fprintf (src,"    default:\n");
+    fprintf (src,"        Asn1Error (\"ERROR - unexpected tag in CHOICE\\n\");\n");
+    fprintf (src,"        longjmp (env, %d);\n",(*longJmpValG)--);
+    fprintf (src,"        break;\n");
+
+    fprintf (src, "    } /* end switch */\n");
+
+}  /* PrintCBerChoiceDecodeCode */
+
+
+
+static void
+PrintCLenDecodingCode PARAMS ((f),
+    FILE *f)
+{
+    fprintf (f, "    itemLen += BDecDefLen (b, itemLen);");
+}  /* PrintCLenDecodingCode */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.h
new file mode 100644
index 00000000..f8fb767c
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-dec.h - routines for printing C decoders from type trees
+ *
+ * Mike Sample
+ * 91/09/26
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-dec.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-dec.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:42  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:41:03  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-dec -> c-gen/gen-dec.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:10  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:22  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+void PrintCBerDecoder PROTO ((FILE *src, FILE *hdr, CRules *r, Module *m, TypeDef *td, long int *longJmpVal));
+
+
+void PrintCBerContentDecoder PROTO ((FILE *src, FILE *hdr, CRules *r, Module *m, TypeDef *td, long int *longJmpVal));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c
new file mode 100644
index 00000000..7bd20845
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c
@@ -0,0 +1,852 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-enc.c - routines for printing c encoders from type trees
+ *
+ * Mike Sample
+ * 91/09/26
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-enc.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:42  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:42:24  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-enc -> c-gen/gen-enc.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:23:10  rj
+ * snacc_config.h and other superfluous .h files removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:24  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "define.h"
+#include "rules.h"
+#include "type-info.h"
+#include "str-util.h"
+#include "util.h"
+#include "tag-util.h"
+#include "snacc-util.h"
+#include "gen-enc.h"
+
+
+
+static int moduleImplicitTagsG;
+static CRules *genEncCRulesG;
+extern char *valueArgNameG;
+
+char *encodedLenVarNameG = "totalLen";
+char *itemLenNameG = "itemLen";
+char *listComponentNameG = "component";
+char *listLenNameG = "listLen";
+char *returnTypeG = "AsnLen";
+extern char *bufTypeNameG;
+extern char *lenTypeNameG;
+extern char *tagTypeNameG;
+extern char *envTypeNameG;
+
+
+/* non-exported prototypes */
+
+static void PrintCBerEncoderPrototype PROTO ((FILE *hdr, TypeDef *td));
+static void PrintCBerEncoderDeclaration PROTO ((FILE *src, TypeDef *td));
+static void PrintCBerEncoderDefine PROTO ((FILE *src, TypeDef *td));
+
+static void PrintCBerEncoderLocals PROTO ((FILE *src, TypeDef *td));
+
+static void PrintCBerElmtsEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int level, char *varName));
+static void PrintCBerElmtEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedType *e, int level, char *varName));
+
+static void PrintCBerListEncoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName));
+static void PrintCBerChoiceEncodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName));
+
+static void PrintCTagAndLenEncodingCode PROTO ((FILE *src, TypeDef *td, Type *t));
+
+static void PrintEocEncoders PROTO ((FILE *src, TypeDef *td, Type *t));
+
+static void PrintCLenEncodingCode PROTO ((FILE *f, int isCons, int isShort));
+
+static void PrintCTagAndLenList PROTO ((FILE *src, Type *t,TagList *tg));
+
+
+
+
+void
+PrintCBerEncoder PARAMS ((src, hdr, r, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    enum BasicTypeChoiceId typeId;
+    int elmtLevel;
+    CTDI *ctdi;
+    TagList *tags;
+    Tag *tag;
+    char *formStr;
+    char *classStr;
+    int tagLen;
+    int stoleChoiceTags;
+
+
+    ctdi = td->cTypeDefInfo;
+    if (!ctdi->genEncodeRoutine)
+        return;
+
+    /*
+     *  if is type that refs another pdu type or lib type
+     *  without generating a new type via tagging or named elmts
+     *  print define to the hdr file
+     * (a type is a pdu by default if it is ref'd by an ANY)
+     */
+    if (!IsNewType (td->type)  &&
+          (!IsTypeRef (td->type) ||
+           (IsTypeRef (td->type) &&
+            (td->type->basicType->a.localTypeRef->link->cTypeDefInfo->isPdu ||
+             ((td->type->basicType->a.localTypeRef->link->anyRefs != NULL) &&
+              !LIST_EMPTY (td->type->basicType->a.localTypeRef->link->anyRefs))))))
+    {
+        fprintf(hdr,"#define B%s B%s\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
+/*
+        fprintf(hdr,"#define B%s(b, v, bytesDecoded, env) B%s(b, v, bytesDecoded, env)\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
+  */
+        return;
+    }
+
+    typeId = GetBuiltinType (td->type);
+
+    /* print proto to hdr file */
+    fprintf (hdr,"%s B%s PROTO ((%s b, %s *v));\n\n", lenTypeNameG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
+
+    /* print routine to src file */
+    fprintf (src,"%s B%s PARAMS ((b, v),\n", lenTypeNameG, ctdi->encodeRoutineName);
+    fprintf (src,"%s b _AND_\n",bufTypeNameG);
+    fprintf (src,"%s *v)\n",ctdi->cTypeName);
+    fprintf (src,"{\n");
+    fprintf (src,"    %s l;\n", lenTypeNameG);
+
+    PrintEocEncoders (src, td, td->type);
+
+    fprintf (src,"    l = B%sContent (b, v);\n", ctdi->encodeRoutineName);
+
+    /* encode each tag/len pair if any */
+    tags = GetTags (td->type, &stoleChoiceTags);
+    if (! stoleChoiceTags)
+    {
+        FOR_EACH_LIST_ELMT_RVS (tag, tags)
+        {
+            classStr = Class2ClassStr (tag->tclass);
+
+            if (tag->form == ANY_FORM)
+                tag->form = PRIM;
+            formStr = Form2FormStr (tag->form);
+            tagLen = TagByteLen (tag->code);
+
+
+            if (tag->form == CONS)
+                fprintf (src,"    l += BEncConsLen (b, l);\n");
+            else
+                fprintf (src,"    l += BEncDefLen (b, l);\n");
+
+            if (tag->tclass == UNIV)
+                fprintf (src,"    l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code));
+            else
+                fprintf (src,"    l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code);
+        }
+    }
+    fprintf (src,"    return l;\n");
+    fprintf (src,"} /* B%s */\n\n", ctdi->encodeRoutineName);
+
+    FreeTags (tags);
+}  /*  PrintCBerEncoder */
+
+void
+PrintCBerContentEncoder PARAMS ((src, hdr, r, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    NamedType *e;
+    CTDI *ctdi;
+    CTypeId rhsTypeId;  /* cTypeId of the type that defined this typedef */
+
+    genEncCRulesG = r;
+
+    ctdi =  td->cTypeDefInfo;
+    if (!ctdi->genEncodeRoutine)
+        return;
+
+    rhsTypeId = td->type->cTypeRefInfo->cTypeId;
+    switch (rhsTypeId)
+    {
+        case C_ANY:
+            fprintf (hdr, "/* ANY - Fix Me! */\n");
+
+            /*
+             * Note - ANY's don't have the 'Content' suffix cause they
+             * encode their tags and lengths
+             */
+            fprintf(hdr, "#define B%s B%s\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
+
+/*
+            fprintf(hdr, "#define B%s( b, v)  ",td->cTypeDefInfo->encodeRoutineName);
+            fprintf (hdr, "B%s (b, v)", td->type->cTypeRefInfo->encodeRoutineName);
+*/
+
+
+            break;
+
+        case C_LIB:
+        case C_TYPEREF:
+            PrintCBerEncoderDefine (hdr, td);
+            fprintf (hdr,"\n\n");
+            break;
+
+        case C_CHOICE:
+            PrintCBerEncoderPrototype (hdr, td);
+            PrintCBerEncoderDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCBerEncoderLocals (src, td);
+            fprintf (src,"\n\n");
+            PrintCBerChoiceEncodeCode (src, td, td->type, FIRST_LEVEL, valueArgNameG);
+            fprintf (src,"    return %s;\n\n", encodedLenVarNameG);
+            fprintf (src,"}  /* B%sContent */",td->cTypeDefInfo->encodeRoutineName);
+            fprintf (hdr,"\n\n");
+            fprintf (src,"\n\n");
+            break;
+
+        case C_STRUCT:
+            PrintCBerEncoderPrototype (hdr, td);
+            PrintCBerEncoderDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCBerEncoderLocals (src, td);
+            fprintf (src,"\n\n");
+            PrintCBerElmtsEncodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL, valueArgNameG);
+            fprintf (src,"    return %s;\n\n", encodedLenVarNameG);
+            fprintf (src,"}  /* B%sContent */",td->cTypeDefInfo->encodeRoutineName);
+            fprintf (hdr,"\n\n");
+            fprintf (src,"\n\n");
+            break;
+
+
+        case C_LIST:
+            PrintCBerEncoderPrototype (hdr, td);
+            fprintf (hdr,"\n\n");
+
+            PrintCBerEncoderDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCBerEncoderLocals (src, td);
+            fprintf (src,"\n\n");
+            PrintCBerListEncoderCode (src, td, td->type, FIRST_LEVEL, valueArgNameG);
+            fprintf (src,"    return %s;\n\n", listLenNameG);
+            fprintf (src,"}  /* B%sContent */", td->cTypeDefInfo->encodeRoutineName);
+            fprintf (src,"\n\n");
+            break;
+
+        case C_NO_TYPE:
+/*            fprintf (src," sorry, unsupported type \n\n"); */
+            break;
+
+        default:
+            fprintf (stderr,"PrintCBerEncoder: ERROR - unknown c type id\n");
+            break;
+    }
+
+}  /*  PrintCBerContentEncoder */
+
+
+
+/*
+ * Prints prototype for encode routine in hdr file
+ */
+static void
+PrintCBerEncoderPrototype PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+    CTDI *ctdi;
+
+    ctdi =  td->cTypeDefInfo;
+    fprintf (hdr,"%s B%sContent PROTO ((%s b, %s *v));", returnTypeG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
+
+}  /*  PrintCBerEncoderPrototype */
+
+
+
+/*
+ * Prints declarations of encode routine for the given type def
+ */
+static void
+PrintCBerEncoderDeclaration PARAMS ((src, td),
+    FILE *src _AND_
+    TypeDef *td)
+{
+    CTDI *ctdi;
+
+    ctdi =  td->cTypeDefInfo;
+    fprintf (src,"%s\nB%sContent PARAMS ((b, v),\n%s b _AND_\n%s *v)\n", returnTypeG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
+
+}  /*  PrintCBerEncoderDeclaration */
+
+
+
+
+/*
+ * makes a define for type refs or primitive type renaming
+ * EG:
+ * TypeX ::= INTEGER --> #define BerEncodeTypeX(b,v) BerEncodeInteger(b,v)
+ * TypeX ::= TypeY --> #define BerEncodeTypeX(b,v) BerEncodeTypeY(b,v)
+ */
+static void
+PrintCBerEncoderDefine PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+    fprintf(hdr, "#define B%sContent B%sContent", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
+
+/*
+    fprintf(hdr, "#define B%sContent( b, v)  ",td->cTypeDefInfo->encodeRoutineName);
+    fprintf (hdr, "B%sContent (b, v)", td->type->cTypeRefInfo->encodeRoutineName);
+*/
+}  /*  PrintCBerEncoderDefine */
+
+
+
+
+static void
+PrintCBerEncoderLocals PARAMS ((src, td),
+    FILE *src _AND_
+    TypeDef *td)
+{
+    fprintf (src, "    AsnLen %s = 0;\n", encodedLenVarNameG);
+    fprintf (src, "    AsnLen %s;\n", itemLenNameG);
+    fprintf (src, "    AsnLen %s;\n", listLenNameG);
+    fprintf (src, "    void *%s;", listComponentNameG);
+
+}  /*  PrintCBerEncoderLocals */
+
+
+
+/*
+ * runs through elmts backwards and prints
+ * encoding code for each one
+ */
+static void
+PrintCBerElmtsEncodeCode PARAMS ((src, td, parent, elmts, level, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts _AND_
+    int level _AND_
+    char *varName)
+{
+    NamedType *e;
+
+    if (elmts == NULL)
+    {
+        fprintf (src,"/* ERROR? - expected elmts for this type*/\n");
+        return;
+    }
+
+    /*
+     * remember! encoding "backwards" so recursively traverse
+     * list backwards
+     */
+    FOR_EACH_LIST_ELMT_RVS (e, elmts)
+    {
+        PrintCBerElmtEncodeCode (src, td, parent, e, level, varName);
+    }
+
+}  /* PrintCBerElmtsEncodeCode */
+
+
+
+/*
+ * Prints code for encoding the elmts of a SEQ or SET
+ */
+static void
+PrintCBerElmtEncodeCode PARAMS ((src, td, parent, e, level, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedType *e _AND_
+    int level _AND_
+    char *varName)
+{
+    CTRI *ctri;
+    char elmtVarRef[MAX_VAR_REF];
+    char idVarRef[MAX_VAR_REF];
+    enum BasicTypeChoiceId tmpTypeId;
+    Type *tmpType;
+    NamedType *idNamedType;
+
+    if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL))
+        return;
+
+    ctri =  e->type->cTypeRefInfo;
+
+    /* check if meant to be encoded */
+    if (!ctri->isEncDec)
+        return;
+
+
+    MakeVarPtrRef (genEncCRulesG, td, parent, e->type, varName, elmtVarRef);
+
+    if (e->type->optional || (e->type->defaultVal != NULL))
+        fprintf (src, "    if (%s (%s))\n    {\n", ctri->optTestRoutineName, elmtVarRef);
+
+    PrintEocEncoders (src, td, e->type);
+
+    switch (ctri->cTypeId)
+    {
+        case C_ANYDEFINEDBY:
+
+            /* get type of 'defining' field (int/enum/oid)*/
+            idNamedType = e->type->basicType->a.anyDefinedBy->link;
+            tmpTypeId = GetBuiltinType (idNamedType->type);
+
+            if (tmpTypeId == BASICTYPE_OID)
+            {
+                MakeVarPtrRef (genEncCRulesG, td, parent, idNamedType->type, varName, idVarRef);
+                fprintf (src, "    SetAnyTypeByOid (%s, %s);\n", elmtVarRef, idVarRef);
+            }
+            else
+            {
+                /* want to ref int by value not ptr */
+                MakeVarValueRef (genEncCRulesG, td, parent, idNamedType->type, varName, idVarRef);
+                fprintf (src, "    SetAnyTypeByInt (%s, %s);\n", elmtVarRef, idVarRef);
+            }
+
+            /* ANY's enc's do tag and len so zap the Content suffix */
+            fprintf (src, "    %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
+            break;
+
+        case C_TYPEREF:
+            tmpType = GetType (e->type);
+
+             /* NOTE: ANY DEFINED BY must be directly in the parent (not ref)*/
+            if (tmpType->cTypeRefInfo->cTypeId != C_ANY)
+            {
+                fprintf (src, "    %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
+                break;
+            }
+            else  /* fall through */
+
+        case C_ANY:
+            /* ANY's enc's do tag and len so zap the Content suffix */
+            fprintf (src,"     /* ANY - Fix Me! */\n");
+            fprintf (src, "    SetAnyTypeBy???(%s, ???);\n", elmtVarRef);
+            fprintf (src, "    %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
+            break;
+
+
+        case C_LIB:
+            fprintf (src, "    %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
+            break;
+
+        case C_CHOICE:
+            PrintCBerChoiceEncodeCode (src, td, e->type, level+1, elmtVarRef);
+            break;
+
+        case C_STRUCT:
+            PrintCBerElmtsEncodeCode (src, td, e->type, e->type->basicType->a.set, level+1, elmtVarRef);
+            break;
+
+        case C_LIST:
+            PrintCBerListEncoderCode (src, td, e->type, level+1, elmtVarRef);
+            fprintf (src, "    %s = %s;\n", itemLenNameG, listLenNameG);
+            fprintf (src,"\n\n");
+            break;
+
+        case C_NO_TYPE:
+            break;
+
+        default:
+            fprintf (stderr,"PrintCBerElmtEncodeCode: ERROR - unknown c type id\n");
+            break;
+    }
+
+    if (ctri->cTypeId != C_ANY) /* ANY's do their own tag/lens */
+    {
+        PrintCTagAndLenEncodingCode (src, td, e->type);
+        fprintf (src,"\n    %s += %s;\n", encodedLenVarNameG, itemLenNameG);
+    }
+
+    if (e->type->optional || (e->type->defaultVal != NULL))
+        fprintf (src, "    }\n");
+
+    fprintf (src,"\n");
+
+}  /*  PrintCBerElmtEncodeCode */
+
+
+
+
+/*
+ * Generates code for internally defined lists
+ * eg:
+ * TypeX = SET { foo INTEGER, bar SEQUENCE OF INTEGER } -->
+ * BerEncodeTypeX (b, v)
+ * {
+ *    ...
+ *         listLen = 0;
+ *         FOR_EACH_LIST_ELMT (component, v->bar)
+ *         {
+ *              itemLen = BerEncodeInteger (b, (int*) component);
+ *              itemLen+= EncodeLen (b, itemLen)
+ *              itemLen += ENCODE_TAG (b, INTEGER_TAG);
+ *              listLen += itemLen;
+ *         }
+ *    ...
+ * }
+ */
+static void
+PrintCBerListEncoderCode PARAMS ((src, td, t, level, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    int level _AND_
+    char *varName)
+{
+    CTRI *ctri;
+    char *elmtVarRef = "component";
+    Type *tmpType;
+    enum BasicTypeChoiceId tmpTypeId;
+    TypeDef *idNamedType;
+
+
+    ctri =  t->basicType->a.setOf->cTypeRefInfo;
+
+    if (ctri == NULL)
+        return;
+
+    fprintf (src, "        listLen = 0;\n");
+    fprintf (src, "    FOR_EACH_LIST_ELMT_RVS (component, %s)\n", varName);
+    fprintf (src, "    {\n");
+
+    PrintEocEncoders (src, td, t->basicType->a.setOf);
+
+    /*
+     * need extra case here for SET OF typedef not just SET OF typeref
+     */
+    switch (ctri->cTypeId)
+    {
+
+        case C_TYPEREF:
+            tmpType = GetType (t->basicType->a.setOf);
+
+             /* NOTE: ANY DEFINED BY must be directly in the parent (not ref)*/
+            if (tmpType->cTypeRefInfo->cTypeId != C_ANY)
+            {
+                fprintf (src, "    %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
+                break;
+            }
+            else  /* fall through */
+
+        case C_ANY:
+            /* ANY's enc's do tag and len so zap the Content suffix */
+            fprintf (src,"     /* ANY - Fix Me! */\n");
+            fprintf (src, "    SetAnyTypeBy???(%s, ???);\n", elmtVarRef);
+            fprintf (src, "    %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
+            break;
+
+
+
+        default:
+            fprintf (src, "    %s = B%sContent (b, (%s*) %s);\n", itemLenNameG, ctri->encodeRoutineName, ctri->cTypeName, elmtVarRef);
+            break;
+
+    }
+
+    PrintCTagAndLenEncodingCode (src, td, t->basicType->a.setOf);
+    fprintf (src,"\n");
+    fprintf (src, "        %s += %s;\n", listLenNameG, itemLenNameG);
+    fprintf (src, "    }\n");
+
+}  /*  PrintCBerListEncoderCode */
+
+
+
+static void
+PrintCBerChoiceEncodeCode PARAMS ((src, td, t, level, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    int level _AND_
+    char *varName)
+{
+    NamedType *e;
+    CTRI *ctri;
+    void *tmp;
+
+    ctri =  t->cTypeRefInfo;
+
+    fprintf (src,"    switch (%s->%s)\n    {\n", varName, ctri->choiceIdEnumFieldName);
+
+    FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
+    {
+        tmp = (void*)CURR_LIST_NODE (t->basicType->a.choice);
+
+        if (e->type == NULL)
+            continue;
+
+        ctri =  e->type->cTypeRefInfo;
+
+        if (ctri != NULL)
+            fprintf (src, "       case %s:\n", ctri->choiceIdSymbol);
+        else
+            fprintf (src, "       case ????:\n");
+
+
+
+        PrintCBerElmtEncodeCode (src, td, t, e, level+1, varName);
+        fprintf (src,"    break;\n\n");
+
+        SET_CURR_LIST_NODE (t->basicType->a.choice, tmp);
+    }
+
+    fprintf (src, "    }\n");
+}  /* PrintCBerChoiceEncodeCode */
+
+
+
+/*
+ *  prints DecodeBerEocIfNec (b) for each constructed len
+ *  assoc with given type
+ */
+static void
+PrintEocEncoders PARAMS ((src, td, t),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t)
+{
+    TagList *tl;
+    Tag *tag;
+    int consTagCount;
+    int stoleChoiceTags;
+
+    /*
+     * get all the tags on this type
+     */
+    tl = (TagList*) GetTags (t, &stoleChoiceTags);
+
+    /*
+     * leave choice elmt tag enc to encoding routine
+     */
+
+    if (!stoleChoiceTags)
+    {
+        FOR_EACH_LIST_ELMT (tag, tl)
+        {
+            if (tag->form == CONS)
+                fprintf (src,"    BEncEocIfNec (b);\n");
+        }
+    }
+/*
+    consTagCount = 0;
+    if (!stoleChoiceTags)
+    {
+        FOR_EACH_LIST_ELMT (tag, tl)
+            consTagCount++;
+    }
+
+    if (IsPrimitiveByDefOrRef (t))
+        consTagCount--;
+
+    for (; consTagCount > 0; consTagCount--)
+        fprintf (src,"    BEncEocIfNec (b);\n");
+
+*/
+
+    FreeTags (tl);
+
+}  /* PrintEocEncoders */
+
+
+/*
+ *  Recursively walks throught type refs printing lower lvl tags
+ *  first (since encoding is done backwards).
+ *
+ */
+static void
+PrintCTagAndLenEncodingCode PARAMS ((src, td, t),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t)
+{
+    TagList *tl;
+    int stoleChoiceTags;
+
+    /*
+     * get all the tags on this type
+     */
+    tl = (TagList*) GetTags (t, &stoleChoiceTags);
+
+    /*
+     * leave choice elmt tag enc to encoding routine
+     */
+    if (!stoleChoiceTags)
+        PrintCTagAndLenList (src, t, tl);
+
+    FreeTags (tl);
+
+}  /* PrintCTagAndLenEncodingCode */
+
+
+
+/*
+ * prints last tag's encoding code first
+ */
+static void
+PrintCTagAndLenList PARAMS ((src, t, tagList),
+    FILE *src _AND_
+    Type *t _AND_
+    TagList *tagList)
+{
+    char *classStr;
+    char *formStr;
+    char *codeStr;
+    Tag *tg;
+    Tag *last;
+    int tagLen;
+    enum BasicTypeChoiceId typesType;
+    int isShort;
+
+    if ((tagList == NULL) || LIST_EMPTY (tagList))
+        return;
+
+    /*
+     * efficiency hack - use simple length (1 byte)
+     * encoded for type (almost) guaranteed to have
+     * encoded lengths of 0 <= len <= 127
+     */
+    typesType = GetBuiltinType (t);
+    if ((typesType == BASICTYPE_BOOLEAN) ||
+        (typesType == BASICTYPE_INTEGER) ||
+        (typesType == BASICTYPE_NULL) ||
+        (typesType == BASICTYPE_REAL) ||
+        (typesType == BASICTYPE_ENUMERATED))
+        isShort = 1;
+    else
+        isShort = 0;
+
+    /*
+     * since encoding backward encode tags backwards
+     */
+    last = (Tag*)LAST_LIST_ELMT (tagList);
+    FOR_EACH_LIST_ELMT_RVS (tg, tagList)
+    {
+        classStr = Class2ClassStr (tg->tclass);
+
+        if (tg->form == CONS)
+        {
+            formStr = Form2FormStr (CONS);
+            PrintCLenEncodingCode (src, TRUE, isShort);
+        }
+        else /* PRIM or ANY_FORM */
+        {
+            formStr = Form2FormStr (PRIM);
+            PrintCLenEncodingCode (src, FALSE, isShort);
+        }
+
+/*       GetTags sets the form bit correctly now
+        if (IsPrimitiveByDefOrRef (t) && (tg == last))
+        {
+            formStr = Form2FormStr (PRIM);
+            PrintCLenEncodingCode (src, FALSE, isShort);
+        }
+        else
+        {
+            formStr = Form2FormStr (CONS);
+            PrintCLenEncodingCode (src, TRUE, isShort);
+        }
+  */
+
+        fprintf (src,"\n");
+
+        if (tg->code < 31)
+            tagLen = 1;
+        else if (tg->code < 128)
+            tagLen = 2;
+        else if (tg->code < 16384)
+            tagLen = 3;
+        else if (tg->code < 2097152)
+            tagLen = 4;
+        else
+            tagLen = 5;
+
+        fprintf (src,"    %s += BEncTag%d (b, %s, %s, %d);\n", itemLenNameG, tagLen, classStr, formStr, tg->code);
+    }
+
+}  /* PrintCTagAndLenList */
+
+/*
+ * prints length encoding code.  Primitives always use
+ * definite length and constructors get "ConsLen"
+ * which can be configured at compile to to be indefinite
+ * or definite.  Primitives can also be "short" (isShort is true)
+ * in which case a fast macro is used to write the length.
+ * Types for which isShort apply are: boolean, null and
+ * (almost always) integer and reals
+ */
+static void
+PrintCLenEncodingCode PARAMS ((f, isCons, isShort),
+    FILE *f _AND_
+    int isCons _AND_
+    int isShort)
+{
+   /* fprintf (f, "    BER_ENCODE_DEF_LEN (b, itemLen, itemLen);"); */
+    if (isCons)
+        fprintf (f, "    itemLen += BEncConsLen (b, itemLen);");
+    else
+    {
+        if (isShort)
+        {
+            fprintf (f, "    BEncDefLenTo127 (b, itemLen);\n");
+            fprintf (f, "    itemLen++;");
+        }
+        else
+            fprintf (f, "    itemLen += BEncDefLen (b, itemLen);");
+    }
+}  /* PrintCLenEncodingCode */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.h
new file mode 100644
index 00000000..0ea99920
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-enc.h - routines for printing C encoders from type trees
+ *
+ * Mike Sample
+ * 91/09/26
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-enc.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:42  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:42:25  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-enc -> c-gen/gen-enc.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:11  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:25  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+
+void PrintCBerEncoder PROTO ((FILE *src, FILE *hdr, CRules *r, Module *m, TypeDef *td));
+
+void PrintCBerContentEncoder PROTO ((FILE *src, FILE *hdr, CRules *r, Module *m, TypeDef *td));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.c
new file mode 100644
index 00000000..0a90c179
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.c
@@ -0,0 +1,514 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-free.c - routines for printing C hierachical free routines
+ *
+ * Mike Sample
+ * 92/04
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-free.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:42  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:42:47  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-free -> c-gen/gen-free.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:23:29  rj
+ * snacc_config.h and other superfluous .h files removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:26  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "define.h"
+#include "rules.h"
+#include "type-info.h"
+#include "str-util.h"
+#include "util.h"
+#include "gen-free.h"
+
+static char *returnTypeG = "void";
+static char *valueArgNameG = "v";
+static CRules *genFreeCRulesG;
+
+/* non-exported prototypes */
+
+static void PrintCFreePrototype PROTO ((FILE *hdr, TypeDef *td));
+static void PrintCFreeDeclaration PROTO ((FILE *src, TypeDef *td));
+static void PrintCFreeDefine PROTO ((FILE *hdr, TypeDef *td));
+static void PrintCFreeLocals PROTO ((FILE *src,TypeDef *td));
+static void PrintCFreeElmts PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *elmts, char *varName));
+static void PrintCElmtFree PROTO ((FILE *src, TypeDef *td, Type *parent, Type *e, char *varName));
+static void PrintCFreeListElmts PROTO ((FILE *src, TypeDef *td, Type *t, char *varName));
+static void PrintCFreeListRoutineBody PROTO ((FILE *src, TypeDef *td, Type *t,char *varName));
+static void PrintCFreeListDefine PROTO ((FILE *hdr,TypeDef *td));
+static void PrintCFreeChoiceElmts PROTO ((FILE *src, TypeDef *td, Type *t, char *varName));
+
+
+
+void
+PrintCFree PARAMS ((src, hdr, r, mods, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    NamedType *e;
+    CTDI *ctdi;
+    CTypeId rhsTypeId;  /* cTypeId of the type that defined this typedef */
+
+    genFreeCRulesG = r;
+
+    ctdi =  td->cTypeDefInfo;
+    if ((ctdi == NULL) || (td->type->cTypeRefInfo == NULL))
+    {
+        fprintf (stderr,"PrintCFree: ERROR - no type info\n");
+        return;
+    }
+
+    if (!ctdi->genFreeRoutine)
+        return;
+
+    rhsTypeId = td->type->cTypeRefInfo->cTypeId;
+    switch (rhsTypeId)
+    {
+        case C_ANY:
+        case C_ANYDEFINEDBY:
+        case C_LIB:
+        case C_TYPEREF:
+            PrintCFreeDefine (hdr, td);
+            fprintf (hdr,"\n\n");
+            break;
+
+        case C_CHOICE:
+            PrintCFreePrototype (hdr, td);
+            PrintCFreeDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCFreeLocals (src, td);
+            fprintf (src,"    if (%s == NULL)\n", valueArgNameG);
+            fprintf (src,"        return;\n", valueArgNameG);
+            PrintCFreeChoiceElmts (src, td, td->type, valueArgNameG);
+            fprintf (src,"}  /* %s */",td->cTypeDefInfo->freeRoutineName);
+            fprintf (hdr,"\n\n");
+            fprintf (src,"\n\n");
+            break;
+
+        case C_STRUCT:
+            PrintCFreePrototype (hdr, td);
+            PrintCFreeDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCFreeLocals (src, td);
+            fprintf (src,"    if (%s == NULL)\n", valueArgNameG);
+            fprintf (src,"        return;\n", valueArgNameG);
+            PrintCFreeElmts (src, td, td->type, td->type->basicType->a.set, valueArgNameG);
+            fprintf (src,"}  /* %s */", td->cTypeDefInfo->freeRoutineName);
+            fprintf (hdr,"\n\n");
+            fprintf (src,"\n\n");
+            break;
+
+
+        case C_LIST:
+            PrintCFreePrototype (hdr, td);
+            PrintCFreeDeclaration (src, td);
+            fprintf (src,"{\n");
+            PrintCFreeLocals (src, td);
+            fprintf (src,"    if (%s == NULL)\n", valueArgNameG);
+            fprintf (src,"        return;\n", valueArgNameG);
+            PrintCFreeListRoutineBody (src, td, td->type, valueArgNameG);
+            fprintf (src,"}  /* %s */", td->cTypeDefInfo->freeRoutineName);
+            fprintf (hdr,"\n\n");
+            fprintf (src,"\n\n");
+            break;
+
+
+
+        case C_NO_TYPE:
+            break;
+
+        default:
+            fprintf (stderr,"PrintCFree: ERROR - unknown c type id\n");
+            break;
+    }
+
+}  /*  PrintCFree */
+
+
+
+/*
+ * Prints prototype for encode routine in hdr file
+ */
+static void
+PrintCFreePrototype PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+    CTDI *ctdi;
+
+    ctdi = td->cTypeDefInfo;
+    fprintf (hdr,"%s %s PROTO ((%s *v));\n", returnTypeG, ctdi->freeRoutineName, ctdi->cTypeName);
+
+}  /*  PrintCFreePrototype */
+
+
+
+/*
+ * Prints declarations of encode routine for the given type def
+ */
+static void
+PrintCFreeDeclaration PARAMS ((src, td),
+    FILE *src _AND_
+    TypeDef *td)
+{
+    CTDI *ctdi;
+
+    ctdi =  td->cTypeDefInfo;
+    fprintf (src,"%s\n%s PARAMS ((v),\n%s *v)\n", returnTypeG, ctdi->freeRoutineName,  ctdi->cTypeName);
+
+}  /*  PrintCFreeDeclaration */
+
+
+
+
+static void
+PrintCFreeDefine PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+
+    fprintf(hdr, "#define %s %s ", td->cTypeDefInfo->freeRoutineName, td->type->cTypeRefInfo->freeRoutineName);
+
+/*
+    fprintf(hdr, "#define %s(v)  ", td->cTypeDefInfo->freeRoutineName);
+    fprintf (hdr, "%s (v)", td->type->cTypeRefInfo->freeRoutineName);
+*/
+}  /*  PrintCFreeDefine */
+
+
+
+
+static void
+PrintCFreeLocals PARAMS ((src, td),
+    FILE *src _AND_
+    TypeDef *td)
+{
+    fprintf (src, "\n");
+
+    if ((td->type->basicType->choiceId == BASICTYPE_SETOF) ||
+        (td->type->basicType->choiceId == BASICTYPE_SEQUENCEOF))
+    {
+        fprintf (src,"    AsnListNode *l;\n");
+        fprintf (src,"    AsnListNode *tmp;\n");
+    }
+
+}  /*  PrintCFreeLocals */
+
+
+
+static void
+PrintCFreeElmts PARAMS ((src, td, parent, elmts, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts _AND_
+    char *varName)
+{
+    NamedType *e;
+
+    if (elmts == NULL)
+    {
+        fprintf (src,"/* ERROR? - expected elmts for this type*/\n");
+        return;
+    }
+
+    FOR_EACH_LIST_ELMT (e, elmts)
+        PrintCElmtFree (src, td, parent, e->type, varName);
+
+}  /* PrintCBerElmtsEncodeCode */
+
+
+
+/*
+ * Prints code for encoding the elmts of a SEQ or SET
+ */
+static void
+PrintCElmtFree PARAMS ((src, td, parent, e, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *e _AND_
+    char *varName)
+{
+    CTRI *ctri;
+    char elmtVarRef[MAX_VAR_REF];
+    Type *tmpType;
+
+    if ((e == NULL) || (e->cTypeRefInfo == NULL))
+        return;
+
+    ctri =  e->cTypeRefInfo;
+
+    /* build ref to the elmt */
+    MakeVarPtrRef (genFreeCRulesG, td, parent, e, varName, elmtVarRef);
+
+    /* if optional then put in NULL check */
+    if (e->optional || (e->defaultVal != NULL))
+        fprintf (src, "    if (%s (%s))\n    {\n", ctri->optTestRoutineName, elmtVarRef);
+
+    /* free contents of elmt first */
+    switch (ctri->cTypeId)
+    {
+        case C_ANY:
+        case C_ANYDEFINEDBY:
+        case C_LIB:
+        case C_TYPEREF:
+            fprintf (src,"    %s (%s);\n", ctri->freeRoutineName, elmtVarRef);
+            break;
+
+        case C_LIST:
+            PrintCFreeListElmts (src, td, e, elmtVarRef);
+            break;
+
+        /*
+         * this  follwing shouldn't happen since embedded
+         * choices/struct are moved to separate typedefs
+         * in normalize.c.
+         */
+        case C_CHOICE:
+            PrintCFreeChoiceElmts (src, td, e, elmtVarRef);
+            break;
+
+        case C_STRUCT:
+            PrintCFreeElmts (src, td, e, e->basicType->a.set, elmtVarRef);
+            break;
+
+
+        case C_NO_TYPE:
+            break;
+
+        default:
+            fprintf (stderr,"PrintCElmtFree: ERROR - unknown c type id\n");
+            break;
+    }
+
+    /* free elmt itself if it is ref'd by ptr */
+    if (ctri->isPtr)
+        fprintf (src,"    Asn1Free (%s);\n",elmtVarRef);
+
+    /* write closing brkt for NULL check for optional elmts */
+    if (e->optional || (e->defaultVal != NULL))
+        fprintf (src, "    }\n");
+
+    fprintf (src,"\n");
+
+}  /*  PrintCElmtFree */
+
+
+static void
+PrintCFreeListDefine PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+    fprintf(hdr, "#define %s(v)  ", td->cTypeDefInfo->freeRoutineName);
+    fprintf (hdr, "ASN1_FREE_LIST (v, %s)", td->type->cTypeRefInfo->freeRoutineName);
+}
+
+
+static void
+PrintCFreeListRoutineBody PARAMS ((src, td, t, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    char *varName)
+{
+    Type *e;
+    CTRI *ctri;
+    char *elmtVarRef;
+
+    fprintf (src,"    for (l = FIRST_LIST_NODE (%s); l != NULL; )\n", varName);
+    fprintf (src,"    {\n");
+
+    e = t->basicType->a.setOf;
+    ctri = e->cTypeRefInfo;
+    elmtVarRef = "(l->data)";
+    switch (ctri->cTypeId)
+    {
+        case C_LIB:
+        case C_TYPEREF:
+            fprintf (src,"        %s (%s);\n", ctri->freeRoutineName, elmtVarRef);
+            break;
+
+        case C_LIST:
+            PrintCFreeListElmts (src, td, e, elmtVarRef);
+            break;
+
+        /*
+         * this  follwing shouldn't happen since embedded
+         * choices/struct are moved to separate typedefs
+         * in normalize.c.
+         */
+        case C_CHOICE:
+            PrintCFreeChoiceElmts (src, td, e, elmtVarRef);
+            break;
+
+        case C_STRUCT:
+            PrintCFreeElmts (src, td, e, e->basicType->a.set, elmtVarRef);
+            break;
+
+
+        case C_NO_TYPE:
+            break;
+
+        default:
+            fprintf (stderr,"PrintCElmtFree: ERROR - unknown c type id\n");
+            break;
+    }
+
+    fprintf (src,"        tmp = l->next;\n");
+    fprintf (src,"        Asn1Free (l->data);\n");
+    fprintf (src,"        Asn1Free (l);\n");
+    fprintf (src,"        l = tmp;\n");
+    fprintf (src,"    }\n");
+}
+
+static void
+PrintCFreeListElmts PARAMS ((src, td, t, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    char *varName)
+{
+    Type *e;
+    CTRI *ctri;
+    char *elmtVarRef;
+
+    fprintf (src,"    {\n");
+    fprintf (src,"        AsnListNode *l;\n");
+    fprintf (src,"        AsnListNode *tmp;\n");
+    fprintf (src,"        for (l = FIRST_LIST_NODE (%s); l != NULL; )\n", varName);
+    fprintf (src,"        {\n");
+
+
+    e = t->basicType->a.setOf;
+    ctri = e->cTypeRefInfo;
+    elmtVarRef = "(l->data)";
+    switch (ctri->cTypeId)
+    {
+        case C_LIB:
+        case C_TYPEREF:
+            fprintf (src,"        %s (%s);\n", ctri->freeRoutineName, elmtVarRef);
+            break;
+
+        case C_LIST:
+            PrintCFreeListElmts (src, td, e, elmtVarRef);
+            break;
+
+        /*
+         * this  follwing shouldn't happen since embedded
+         * choices/struct are moved to separate typedefs
+         * in normalize.c.
+         */
+        case C_CHOICE:
+            PrintCFreeChoiceElmts (src, td, e, elmtVarRef);
+            break;
+
+        case C_STRUCT:
+            PrintCFreeElmts (src, td, e, e->basicType->a.set, elmtVarRef);
+            break;
+
+
+        case C_NO_TYPE:
+            break;
+
+        default:
+            fprintf (stderr,"PrintCElmtFree: ERROR - unknown c type id\n");
+            break;
+    }
+
+    fprintf (src,"           tmp = l->next;\n");
+    fprintf (src,"           Asn1Free (l->data);\n");
+    fprintf (src,"           Asn1Free (l);\n");
+    fprintf (src,"           l = tmp;\n");
+    fprintf (src,"        }\n");
+    fprintf (src,"    }\n");
+} /* PrintCFreeListELmts */
+
+
+
+static void
+PrintCFreeChoiceElmts PARAMS ((src, td, t, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    char *varName)
+{
+    NamedType *e;
+    CTRI *ctri;
+    void *tmp;
+
+    ctri =  t->cTypeRefInfo;
+
+    fprintf (src,"    switch (%s->%s)\n    {\n", varName, ctri->choiceIdEnumFieldName);
+
+    FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
+    {
+        tmp = (void*)CURR_LIST_NODE (t->basicType->a.choice);
+
+        if (e->type == NULL)
+            continue;
+
+        ctri =  e->type->cTypeRefInfo;
+
+        if (e->type->cTypeRefInfo == NULL)
+            fprintf (src, "       case ????:\n");
+        else if (ctri->isPtr)
+        {
+            fprintf (src, "       case %s:\n", ctri->choiceIdSymbol);
+            PrintCElmtFree (src, td, t, e->type, varName);
+            fprintf (src,"    break;\n\n");
+        }
+
+        SET_CURR_LIST_NODE (t->basicType->a.choice, tmp);
+    }
+
+    fprintf (src, "    }\n");
+}
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.h
new file mode 100644
index 00000000..12addd48
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-free.h
+ *
+ * Mike Sample
+ * 92/04
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-free.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-free.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:42  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:42:48  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-free -> c-gen/gen-free.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:12  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:27  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+void PrintCFree PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.c
new file mode 100644
index 00000000..f3ca2603
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.c
@@ -0,0 +1,547 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-print.c - routines for printing C hierachical print routines
+ *
+ * Mike Sample
+ * 92/04
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-print.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:42  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:43:18  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-print -> c-gen/gen-print.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:23:43  rj
+ * snacc_config.h and other superfluous .h files removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:28  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "define.h"
+#include "rules.h"
+#include "type-info.h"
+#include "str-util.h"
+#include "util.h"
+#include "gen-print.h"
+
+static char *returnTypeG = "void";
+static char *valueArgNameG = "v";
+static char *fileTypeNameG = "FILE*";
+static char *indentTypeNameG = "unsigned short int";
+static CRules *genPrintCRulesG;
+/* non-exported prototypes */
+
+static void PrintCPrintPrototype PROTO ((FILE *hdr, TypeDef *td));
+static void PrintCPrintDeclaration PROTO ((FILE *src, TypeDef *td));
+static void PrintCPrintDefine PROTO ((FILE *hdr, TypeDef *td));
+static void PrintCPrintLocals PROTO ((FILE *src,TypeDef *td));
+/*
+static void PrintCPrintElmts PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *elmts, char *varName));
+*/
+static void PrintCChoiceElmtPrint PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *elmts, NamedType *e, char *varName));
+
+
+static void PrintCElmtPrintWithIndent PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *elmts, NamedType *e, char *varName, int allOpt));
+
+static void PrintCChoicePrintRoutine PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td));
+
+static void PrintCSetPrintRoutine  PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td));
+static void PrintCSeqPrintRoutine  PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td));
+static void PrintCSeqOfPrintRoutine PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td));
+static void PrintCSetOfPrintRoutine PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td));
+
+
+
+void
+PrintCPrinter PARAMS ((src, hdr, r, mods, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    if ((td->cTypeDefInfo == NULL) || !(td->cTypeDefInfo->genPrintRoutine))
+        return;
+
+    genPrintCRulesG = r;
+    switch (td->type->basicType->choiceId)
+    {
+        case BASICTYPE_IMPORTTYPEREF:  /* type references */
+        case BASICTYPE_LOCALTYPEREF:
+        case BASICTYPE_BOOLEAN:  /* library type */
+        case BASICTYPE_REAL:  /* library type */
+        case BASICTYPE_OCTETSTRING:  /* library type */
+        case BASICTYPE_NULL:  /* library type */
+        case BASICTYPE_OID:  /* library type */
+        case BASICTYPE_INTEGER:  /* library type */
+        case BASICTYPE_BITSTRING:  /* library type */
+        case BASICTYPE_ENUMERATED:  /* library type */
+        case BASICTYPE_ANYDEFINEDBY:  /* ANY types */
+        case BASICTYPE_ANY:
+            PrintCPrintDefine (hdr, td);
+            fprintf (hdr, "\n\n");
+            break;
+
+        case BASICTYPE_SETOF:
+            PrintCSetOfPrintRoutine (src, hdr, r, mods, m, td);
+            break;
+
+        case BASICTYPE_SEQUENCEOF:
+            PrintCSeqOfPrintRoutine (src, hdr, r, mods, m, td);
+            break;
+
+        case BASICTYPE_CHOICE:
+            PrintCChoicePrintRoutine (src, hdr, r, mods, m, td);
+            break;
+
+        case BASICTYPE_SET:
+            PrintCSetPrintRoutine (src, hdr, r, mods, m, td);
+            break;
+
+
+        case BASICTYPE_SEQUENCE:
+            PrintCSeqPrintRoutine (src, hdr, r, mods, m, td);
+            break;
+
+        default:
+            break;
+    }
+}  /*  PrintCPrint */
+
+
+/*
+ * Prints prototype for encode routine in hdr file
+ */
+static void
+PrintCPrintPrototype PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+    CTDI *ctdi;
+
+    ctdi = td->cTypeDefInfo;
+    fprintf (hdr,"%s %s PROTO ((%s f, %s *v, %s indent));\n", returnTypeG, ctdi->printRoutineName, fileTypeNameG, ctdi->cTypeName, indentTypeNameG);
+
+}  /*  PrintCPrintPrototype */
+
+
+
+/*
+ * Prints declarations of encode routine for the given type def
+ */
+static void
+PrintCPrintDeclaration PARAMS ((src, td),
+    FILE *src _AND_
+    TypeDef *td)
+{
+    CTDI *ctdi;
+
+    ctdi =  td->cTypeDefInfo;
+    fprintf (src,"%s\n%s PARAMS ((f, v, indent),\n%s f _AND_\n%s *v _AND_\n%s indent)\n", returnTypeG, ctdi->printRoutineName, fileTypeNameG, ctdi->cTypeName, indentTypeNameG);
+
+}  /*  PrintCPrintDeclaration */
+
+
+
+
+static void
+PrintCPrintDefine PARAMS ((hdr, td),
+    FILE *hdr _AND_
+    TypeDef *td)
+{
+    fprintf(hdr, "#define %s %s", td->cTypeDefInfo->printRoutineName, td->type->cTypeRefInfo->printRoutineName);
+/*
+    fprintf(hdr, "#define %s(f, v, indent)  ", td->cTypeDefInfo->printRoutineName);
+    fprintf (hdr, "%s (f, v, indent)", td->type->cTypeRefInfo->printRoutineName);
+*/
+}  /*  PrintCPrintDefine */
+
+
+
+
+static void
+PrintCPrintLocals PARAMS ((src, td),
+    FILE *src _AND_
+    TypeDef *td)
+{
+    /* none yet */
+}  /*  PrintCPrintLocals */
+
+
+/*
+static void
+PrintCPrintElmts PARAMS ((src, td, parent, elmts, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts _AND_
+    char *varName)
+{
+    NamedType *e;
+
+
+    FOR_EACH_LIST_ELMT (e, elmts)
+        PrintCElmtPrint (src, td, parent, elmts, e, varName);
+}  PrintCBerElmtsEncodeCode */
+
+
+
+/*
+ * Prints code for printing a CHOICE element
+ *
+ */
+static void
+PrintCChoiceElmtPrint PARAMS ((src, td, parent, elmts,  e, varName),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts _AND_
+    NamedType *e _AND_
+    char *varName)
+{
+    CTRI *ctri;
+    char elmtVarRef[MAX_VAR_REF];
+    Type *tmpType;
+    int inTailOpts;
+
+    ctri =  e->type->cTypeRefInfo;
+
+
+    /* build ref to the elmt */
+    MakeVarPtrRef (genPrintCRulesG, td, parent, e->type, varName, elmtVarRef);
+
+    if (e->fieldName != NULL)
+    {
+        fprintf (src,"    fprintf (f,\"%s \");\n", e->fieldName);
+        fprintf (src,"    %s (f, %s, indent + stdIndentG);\n", e->type->cTypeRefInfo->printRoutineName, elmtVarRef);
+    }
+    else
+    {
+        fprintf (src,"    %s (f, %s, indent + stdIndentG);\n", e->type->cTypeRefInfo->printRoutineName, elmtVarRef);
+    }
+
+}  /*  PrintCChoiceElmtPrint */
+
+/*
+ * Prints code for printing an elmt of a SEQ or SET
+ *
+ * Does funny things to print commas correctly
+ * eg for the following type
+ * Foo ::= SET
+ * {
+ *      A,                   --> print   A ",\n"
+ *      B,                               B ",\n"
+ *      C OPTIONAL,                      C ",\n" if C present
+ *      D,                               D ",\n"
+ *      E,                               E ",\n"
+ *      F,                               F       <- nothing after last non-opt
+ *                                                  before tail opts.
+ *      G OPTIONAL,                      ",\n" G
+ *      H OPTIONAL                       ",\n" H "\n"
+ * }
+
+ */
+static void
+PrintCElmtPrintWithIndent PARAMS ((src, td, parent, elmts, e, varName, allOpt),
+    FILE *src _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts _AND_
+    NamedType *e _AND_
+    char *varName _AND_
+    int allOpt)
+{
+    CTRI *ctri;
+    char elmtVarRef[MAX_VAR_REF];
+    Type *tmpType;
+    int inTailOpts;
+
+    ctri =  e->type->cTypeRefInfo;
+
+    /* this assumes the elmts->curr == e */
+    inTailOpts = IsTailOptional (elmts);
+
+    /* build ref to the elmt */
+    MakeVarPtrRef (genPrintCRulesG, td, parent, e->type, varName, elmtVarRef);
+
+    /* if optional then put in NULL check */
+    if (e->type->optional || (e->type->defaultVal != NULL))
+        fprintf (src, "    if (%s (%s))\n    {\n", ctri->optTestRoutineName, elmtVarRef);
+
+    if (allOpt)
+    {
+        if (e != FIRST_LIST_ELMT (elmts))
+        {
+            fprintf (src, "    if (!nonePrinted)\n");
+            fprintf (src, "        fprintf (f,\",\\n\");\n");
+        }
+        fprintf (src, "    nonePrinted = FALSE;\n");
+    }
+    else if ((inTailOpts) && (e != FIRST_LIST_ELMT (elmts)))
+        fprintf (src, "    fprintf (f,\",\\n\");\n");
+
+    fprintf (src,"    Indent (f, indent + stdIndentG);\n");
+
+    if (e->fieldName != NULL)
+        fprintf (src,"    fprintf (f,\"%s \");\n", e->fieldName);
+
+    fprintf (src,"    %s (f, %s, indent + stdIndentG);\n", e->type->cTypeRefInfo->printRoutineName, elmtVarRef);
+
+    if ((e != LAST_LIST_ELMT (elmts)) &&
+         (!inTailOpts) &&
+         (!NextIsTailOptional (elmts)))
+        fprintf (src,"    fprintf (f, \",\\n\");\n");
+
+
+    /* write closing brkt for NULL check for optional elmts */
+    if (e->type->optional || (e->type->defaultVal != NULL))
+        fprintf (src, "    }\n");
+
+    if (e == LAST_LIST_ELMT (elmts))
+        fprintf (src,"    fprintf (f,\"\\n\");\n");
+
+}  /*  PrintCElmtPrintWithIndent */
+
+
+static void
+PrintCChoicePrintRoutine PARAMS ((src, hdr, r, mods, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    NamedType *e;
+
+    PrintCPrintPrototype (hdr,td);
+
+    PrintCPrintDeclaration (src, td);
+    fprintf (src,"{\n");
+    PrintCPrintLocals (src,td);
+    fprintf (src,"    switch (%s->%s)\n", valueArgNameG, td->type->cTypeRefInfo->choiceIdEnumFieldName);
+    fprintf (src,"    {\n");
+
+    FOR_EACH_LIST_ELMT (e, td->type->basicType->a.choice)
+    {
+        fprintf (src,"      case %s:\n",e->type->cTypeRefInfo->choiceIdSymbol);
+        fprintf (src,"      ");
+        PrintCChoiceElmtPrint (src, td, td->type, td->type->basicType->a.choice, e, valueArgNameG);
+        fprintf (src,"          break;\n\n");
+    }
+    fprintf (src,"    }\n");
+/*    fprintf (src,"    fprintf (f,\"\\n\");\n"); */
+
+    fprintf (src,"}  /* %s */\n\n", td->cTypeDefInfo->printRoutineName);
+
+} /* PrintCChoicePrintRoutine */
+
+
+
+static void
+PrintCSetPrintRoutine PARAMS ((src, hdr, r, mods, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    NamedType *e;
+    int allOpt;
+
+    PrintCPrintPrototype (hdr,td);
+
+    PrintCPrintDeclaration (src, td);
+    fprintf (src,"{\n");
+    PrintCPrintLocals (src,td);
+
+    allOpt = AllElmtsOptional (td->type->basicType->a.set);
+    /*
+     * print extra local variable so commas are handled correctly
+     * when all elements are optional
+     */
+    if (allOpt)
+        fprintf (src,"    int nonePrinted = TRUE;\n\n");
+
+    fprintf (src,"    if (%s == NULL)\n", valueArgNameG);
+    fprintf (src,"        return;\n\n");
+
+    fprintf (src,"    fprintf (f,\"{ -- SET --\\n\");\n\n");
+
+
+    FOR_EACH_LIST_ELMT (e, td->type->basicType->a.set)
+    {
+        PrintCElmtPrintWithIndent (src, td, td->type, td->type->basicType->a.set, e, valueArgNameG, allOpt);
+    }
+    fprintf (src,"    Indent (f, indent);\n");
+    fprintf (src,"    fprintf (f,\"}\");\n");
+
+    fprintf (src,"}  /* %s */\n\n", td->cTypeDefInfo->printRoutineName);
+
+} /* PrintCSetPrintRoutine */
+
+
+
+static void
+PrintCSeqPrintRoutine PARAMS ((src, hdr, r, mods, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    NamedType *e;
+    int allOpt;
+
+    PrintCPrintPrototype (hdr,td);
+
+    PrintCPrintDeclaration (src, td);
+    fprintf (src,"{\n");
+    PrintCPrintLocals (src,td);
+
+    allOpt = AllElmtsOptional (td->type->basicType->a.set);
+    /*
+     * print extra local variable so commas are handled correctly
+     * when all elements are optional
+     */
+    if (allOpt)
+        fprintf (src,"    int nonePrinted = TRUE;\n\n");
+
+    fprintf (src,"    if (%s == NULL)\n", valueArgNameG);
+    fprintf (src,"        return;\n\n");
+
+    fprintf (src,"    fprintf (f,\"{ -- SEQUENCE --\\n\");\n\n");
+
+    FOR_EACH_LIST_ELMT (e, td->type->basicType->a.sequence)
+    {
+        PrintCElmtPrintWithIndent (src, td, td->type, td->type->basicType->a.sequence, e, valueArgNameG, allOpt);
+    }
+    fprintf (src,"    Indent (f, indent);\n");
+    fprintf (src,"    fprintf (f,\"}\");\n");
+
+    fprintf (src,"}  /* %s */\n\n", td->cTypeDefInfo->printRoutineName);
+} /* PrintCSeqPrintRoutine */
+
+
+
+static void
+PrintCSetOfPrintRoutine PARAMS ((src, hdr, r, mods, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    NamedType *e;
+
+    PrintCPrintPrototype (hdr,td);
+
+    PrintCPrintDeclaration (src, td);
+    fprintf (src,"{\n");
+    PrintCPrintLocals (src,td);
+
+    fprintf (src,"    %s *tmp;\n", td->type->basicType->a.setOf->cTypeRefInfo->cTypeName);
+
+    fprintf (src,"    if (%s == NULL)\n", valueArgNameG);
+    fprintf (src,"        return;\n");
+
+    fprintf (src,"    fprintf (f,\"{ -- SET OF -- \\n\");\n");
+
+    fprintf (src,"    FOR_EACH_LIST_ELMT (tmp, %s)\n", valueArgNameG);
+    fprintf (src,"    {\n");
+    fprintf (src,"        Indent (f, indent+ stdIndentG);\n");
+    fprintf (src,"        %s (f, tmp, indent + stdIndentG);\n", td->type->basicType->a.setOf->cTypeRefInfo->printRoutineName);
+    fprintf (src,"        if (tmp != (%s*)LAST_LIST_ELMT (%s))\n", td->type->basicType->a.setOf->cTypeRefInfo->cTypeName, valueArgNameG);
+    fprintf (src,"            fprintf (f,\",\\n\");\n");
+    fprintf (src,"    }\n");
+    fprintf (src,"    fprintf (f,\"\\n\");\n");
+    fprintf (src,"    Indent (f, indent);\n");
+    fprintf (src,"    fprintf (f,\"}\");\n");
+
+    fprintf (src,"}  /* %s */\n\n", td->cTypeDefInfo->printRoutineName);
+
+} /* PrintCSetOfPrintRoutine */
+
+static void
+PrintCSeqOfPrintRoutine PARAMS ((src, hdr, r, mods, m, td),
+    FILE *src _AND_
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    NamedType *e;
+
+    PrintCPrintPrototype (hdr,td);
+
+    PrintCPrintDeclaration (src, td);
+    fprintf (src,"{\n");
+    PrintCPrintLocals (src,td);
+
+    fprintf (src,"    %s *tmp;\n", td->type->basicType->a.setOf->cTypeRefInfo->cTypeName);
+
+    fprintf (src,"    if (%s == NULL)\n", valueArgNameG);
+    fprintf (src,"        return;\n");
+
+    fprintf (src,"    fprintf (f,\"{ -- SEQUENCE OF -- \\n\");\n");
+
+    fprintf (src,"    FOR_EACH_LIST_ELMT (tmp, %s)\n", valueArgNameG);
+    fprintf (src,"    {\n");
+    fprintf (src,"        Indent (f, indent+ stdIndentG);\n");
+    fprintf (src,"        %s (f, tmp, indent + stdIndentG);\n", td->type->basicType->a.setOf->cTypeRefInfo->printRoutineName);
+    fprintf (src,"        if (tmp != (%s*)LAST_LIST_ELMT (%s))\n", td->type->basicType->a.setOf->cTypeRefInfo->cTypeName, valueArgNameG);
+    fprintf (src,"            fprintf (f,\",\\n\");\n");
+    fprintf (src,"    }\n");
+    fprintf (src,"    fprintf (f,\"\\n\");\n");
+    fprintf (src,"    Indent (f, indent);\n");
+    fprintf (src,"    fprintf (f,\"}\");\n");
+
+    fprintf (src,"}  /* %s */\n\n", td->cTypeDefInfo->printRoutineName);
+
+} /* PrintCSeqOfPrintRoutine */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.h
new file mode 100644
index 00000000..abb1f517
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-print.h
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-print.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-print.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:43:19  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-print -> c-gen/gen-print.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:13  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:29  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+void PrintCPrinter PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.c
new file mode 100644
index 00000000..47b240c0
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.c
@@ -0,0 +1,401 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-type.c - routines for printing c types from  ASN.1 from type trees
+ *
+ * Mike Sample
+ * 91/09/26
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-type.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:43:44  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-type -> c-gen/gen-type.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:23:58  rj
+ * snacc_config.h and other superfluous .h files removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:31  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "print.h"
+#include "rules.h"
+#include "type-info.h"
+#include "util.h"
+#include "gen-type.h"
+
+
+/* non-exported prototypes */
+
+static void PrintCType PROTO ((FILE *f,  CRules *r, Module *m, TypeDef *td, Type *parent, Type *t));
+
+static void PrintCStructElmts PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t));
+
+
+static void PrintCChoiceIdEnum PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t));
+
+static void PrintCChoiceUnion  PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t));
+
+static void PrintCChoiceTypeDef PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td));
+
+static void PrintTypeComment PROTO ((FILE *f, TypeDef *head, Type *t));
+
+
+static void PrintPreTypeDefStuff PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t));
+
+
+
+void
+PrintCTypeDef PARAMS ((f, r, m, td),
+    FILE *f _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    CTRI *ctri;
+    CTDI *ctdi;
+    Type *t;
+
+    ctdi = td->cTypeDefInfo;
+    if ((ctdi == NULL) || (!ctdi->genTypeDef))
+        return;
+
+    t = td->type;
+    ctri = t->cTypeRefInfo;
+
+    PrintPreTypeDefStuff (f, r, m, td, NULL, t);
+
+    switch (ctri->cTypeId)
+    {
+        case C_TYPEREF:
+        case C_LIB:
+        case C_ANY:
+        case C_ANYDEFINEDBY:
+        case C_LIST:
+            fprintf (f, "typedef ");
+            PrintCType (f, r, m, td, NULL, t);
+            fprintf (f, " %s;", ctdi->cTypeName);
+            PrintTypeComment (f, td, t);
+            fprintf (f, "\n\n");
+            break;
+
+
+        case C_CHOICE:
+            PrintCChoiceTypeDef (f, r,  m, td);
+            break;
+
+        case C_STRUCT:
+            fprintf (f, "typedef ");
+            fprintf (f,"%s %s", "struct", t->cTypeRefInfo->cTypeName);
+            PrintTypeComment (f, td, t);
+            fprintf (f,"\n{\n");
+            PrintCStructElmts (f, r, m, td, NULL, t);
+            fprintf (f, "} %s;", ctdi->cTypeName);
+            fprintf (f, "\n\n");
+            break;
+
+        default:
+            break;
+        /* else do nothing - some unprocessed or unknown type (macros etc) */
+    }
+
+}  /* PrintCTypeDef */
+
+
+
+static void
+PrintCType PARAMS ((f, r, m, td, parent, t),
+    FILE *f _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    CTRI *ctri;
+    CNamedElmt *n;
+
+    ctri = t->cTypeRefInfo;
+
+    if (ctri == NULL)
+        return;
+
+
+    switch (ctri->cTypeId)
+    {
+        case C_TYPEREF:
+            /*
+             * put struct in front of def if
+             * defined from a struct type (set/seq/choice)
+             * but only if not a ref of a ref
+             */
+            if ((t->basicType->a.localTypeRef->link->type->cTypeRefInfo->cTypeId == C_STRUCT)||
+                 (t->basicType->a.localTypeRef->link->type->cTypeRefInfo->cTypeId == C_CHOICE))
+            {
+                fprintf (f,"struct ");
+            }
+
+            fprintf (f,"%s", ctri->cTypeName);
+
+            if (ctri->isPtr)
+                fprintf (f,"*");
+            break;
+
+        case C_ANY:
+            fprintf (f,"/* ANY- Fix Me ! */\n");
+        case C_ANYDEFINEDBY:
+        case C_LIST:
+        case C_LIB:
+            fprintf (f,"%s", ctri->cTypeName);
+            /*
+             * print enum constant defs
+             */
+            if ((ctri->cNamedElmts != NULL) &&
+                (t->basicType->choiceId  == BASICTYPE_ENUMERATED))
+            {
+                fprintf (f, "\n    {\n");
+
+                FOR_EACH_LIST_ELMT (n, ctri->cNamedElmts)
+                {
+                    fprintf (f,"        %s = %d", n->name, n->value);
+                    if (n != (CNamedElmt*)LAST_LIST_ELMT (ctri->cNamedElmts))
+                        fprintf (f,",");
+
+                    fprintf (f,"\n");
+                }
+                fprintf (f, "    }");
+            }
+
+            if (ctri->isPtr)
+               fprintf (f,"*");
+            break;
+
+       default:
+           break;
+             /* nothing */
+    }
+
+}  /* PrintCType */
+
+
+static void
+PrintCStructElmts PARAMS ((f, r, m, td, parent, t),
+    FILE *f _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    CTRI *ctri;
+    NamedType *et;
+    NamedTypeList *elmts;
+
+    elmts = t->basicType->a.sequence;
+
+    if ((elmts == NULL) || (LIST_EMPTY (elmts)))
+    {
+        fprintf (f, "    char unused; /* empty ASN1 SET/SEQ - not used */\n");
+    }
+
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+
+        ctri =  et->type->cTypeRefInfo;
+        fprintf (f,"    ");  /* cheap, fixed indent */
+        PrintCType (f, r, m, td, t, et->type);
+        fprintf (f, " %s;", ctri->cFieldName);
+        PrintTypeComment (f, td, et->type);
+        fprintf (f, "\n");
+    }
+}  /* PrintCStructElmts */
+
+
+
+static void
+PrintCChoiceIdEnum PARAMS ((f, r, m, td, parent, t),
+    FILE *f _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    NamedType *et;
+    NamedType *last;
+    CTRI *ctri;
+
+    ctri =  t->cTypeRefInfo;
+    fprintf (f, "    enum %s\n    {\n", ctri->choiceIdEnumName);
+
+    if ((t->basicType->a.choice != NULL) &&
+        !(LIST_EMPTY (t->basicType->a.choice)))
+        last = (NamedType*)LAST_LIST_ELMT (t->basicType->a.choice);
+
+    FOR_EACH_LIST_ELMT (et, t->basicType->a.choice)
+    {
+        ctri =  et->type->cTypeRefInfo;
+        fprintf (f,"        %s", ctri->choiceIdSymbol);
+        if (et == last)
+            fprintf (f, "\n");
+        else
+            fprintf (f, ",\n");
+    }
+
+    ctri =  t->cTypeRefInfo;
+    fprintf (f, "    } %s;", ctri->choiceIdEnumFieldName);
+
+}  /* PrintCChoiceIdEnum */
+
+
+static void
+PrintCChoiceUnion PARAMS ((f, r, m, td, parent, t),
+    FILE *f _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    CTRI *ctri;
+    ctri = t->cTypeRefInfo;
+
+    fprintf (f,"    union %s\n    {\n",  ctri->cTypeName);
+    PrintCStructElmts (f, r, m, td, parent, t);
+    fprintf (f, "    }");
+}  /* PrintCChoiceUnion */
+
+
+static void
+PrintCChoiceTypeDef PARAMS ((f, r, m, td),
+    FILE *f _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    CTRI *ctri;
+    char *choiceName;
+    Type *t;
+
+    t = td->type;
+    ctri =  t->cTypeRefInfo;
+    choiceName = td->cTypeDefInfo->cTypeName;
+
+    fprintf (f, "typedef ");
+    fprintf (f, "struct %s", choiceName);
+    PrintTypeComment (f, td, t);
+    fprintf (f,"\n{\n");
+    PrintCChoiceIdEnum (f, r, m, td, NULL, t);
+    fprintf (f,"\n");
+    PrintCChoiceUnion (f, r, m, td, NULL, t);
+    fprintf (f, " %s;", ctri->cFieldName);
+    fprintf (f,"\n} %s;\n\n", choiceName);
+}  /* PrintCChoiceDef */
+
+
+
+/*
+ * used to print snippet of the defining ASN.1  after the
+ * C type.
+ */
+static void
+PrintTypeComment PARAMS ((f, td, t),
+    FILE *f _AND_
+    TypeDef *td _AND_
+    Type *t)
+{
+    fprintf (f," /* ");
+    SpecialPrintType (f, td, t);
+    fprintf (f," */");
+}
+
+
+
+/*
+ * print any #defines for integers/bits with named elements
+ * (currenly only the first option will fire due to the
+ *  steps taken in normalize.c)
+ */
+static void
+PrintPreTypeDefStuff PARAMS ((f, r, m, td, parent, t),
+    FILE *f _AND_
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    CTRI *ctri;
+    NamedType *et;
+    CNamedElmt *n;
+
+    ctri = td->type->cTypeRefInfo;
+
+    /*
+     * print defined stmts for non enumerated type with named elmts
+     */
+    if ((ctri->cNamedElmts != NULL) &&
+        (t->basicType->choiceId  != BASICTYPE_ENUMERATED))
+    {
+        FOR_EACH_LIST_ELMT (n, ctri->cNamedElmts)
+        {
+            fprintf(f, "\n#define %s %d", n->name, n->value);
+        }
+        fprintf (f, "\n\n");
+    }
+
+    else if ((t->basicType->choiceId == BASICTYPE_SET) ||
+             (t->basicType->choiceId == BASICTYPE_SEQUENCE) ||
+             (t->basicType->choiceId == BASICTYPE_CHOICE))
+    {
+
+        FOR_EACH_LIST_ELMT (et, t->basicType->a.set)
+            PrintPreTypeDefStuff (f, r, m, td, t, et->type);
+    }
+
+    else if ((t->basicType->choiceId == BASICTYPE_SETOF) ||
+             (t->basicType->choiceId == BASICTYPE_SEQUENCEOF))
+    {
+        PrintPreTypeDefStuff (f, r,  m, td, t, t->basicType->a.setOf);
+    }
+}  /* PrintPreTypeDefStuff */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.h
new file mode 100644
index 00000000..0ffa7e42
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-type.h - routines for printing c types ASN.1 from type trees
+ *
+ * Mike Sample
+ * 91/09/26
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-type.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-type.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:43:45  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-type -> c-gen/gen-type.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:14  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:32  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+void PrintCTypeDef PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.c
new file mode 100644
index 00000000..ca6b50cc
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.c
@@ -0,0 +1,238 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-vals.c - prints ASN.1 values in C format
+ *
+ *
+ * MS Feb 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-vals.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1  2000/05/10 21:35:01  rmurphy
+ * Adding back in base code files which had been moved to "2" versions.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1997/05/07 14:59:31  wan
+ * Fixed bug in C value string generation.
+ *
+ * Revision 1.3  1995/07/25 18:44:12  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-vals -> c-gen/gen-vals.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:24:18  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:33  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "oid.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "define.h"
+#include "lib-types.h"
+#include "rules.h"
+#include "type-info.h"
+#include "str-util.h"
+#include "snacc-util.h"
+#include "util.h"
+#include "kwd.h"
+#include "gen-vals.h"
+
+/* non-exported routines' prototypes */
+
+static void PrintValueDefsName PROTO ((FILE *f, CRules *r, ValueDef *v));
+static void PrintValueDefsType PROTO ((FILE *f, CRules *r, ValueDef *v));
+static void PrintValueInstatiation PROTO ((FILE *f, CRules *r, ValueDef *v));
+
+
+
+
+void
+PrintCValueDef PARAMS ((src, r, v),
+    FILE *src _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    /* just do oid's, ints and bools for now */
+    if ((v->value->basicValue->choiceId != BASICVALUE_OID) &&
+        (v->value->basicValue->choiceId != BASICVALUE_INTEGER) &&
+        (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN))
+        return;
+
+    /*
+     * put instantiation in src file
+     */
+    PrintValueDefsType (src, r, v);
+    fprintf (src," ");
+    PrintValueDefsName (src, r, v);
+    fprintf (src," = ");
+    PrintValueInstatiation (src, r, v);
+    fprintf (src,";\n\n");
+
+}  /* PrintCValueDef */
+
+void
+PrintCValueExtern PARAMS ((hdr, r, v),
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    /* just do oid's, ints and bools for now */
+    if ((v->value->basicValue->choiceId != BASICVALUE_OID) &&
+        (v->value->basicValue->choiceId != BASICVALUE_INTEGER) &&
+        (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN))
+        return;
+
+    /*
+     * put extern declaration in hdr file
+     */
+    fprintf (hdr,"extern ");
+    PrintValueDefsType (hdr, r, v);
+    fprintf (hdr," ");
+    PrintValueDefsName (hdr, r, v);
+    fprintf (hdr,";\n");
+
+}  /* PrintCValueExtern */
+
+
+static void
+PrintValueDefsName PARAMS ((f, r, v),
+    FILE *f _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    char *cName;
+    cName = Asn1ValueName2CValueName (v->definedName);
+    fprintf (f, "%s", cName);
+    Free (cName);
+}
+
+static void
+PrintValueDefsType PARAMS ((f, r, v),
+    FILE *f _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    /* needs work - just do ints bools and oid's for now */
+    switch (v->value->basicValue->choiceId)
+    {
+        case BASICVALUE_OID:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_OID].cTypeName);
+            break;
+
+        case BASICVALUE_INTEGER:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_INTEGER].cTypeName);
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_BOOLEAN].cTypeName);
+            break;
+
+        default:
+           break;
+    }
+}
+
+
+static void
+PrintValueInstatiation PARAMS ((f, r, v),
+    FILE *f _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    /* needs work - just do ints, bools and oids for now */
+    switch (v->value->basicValue->choiceId)
+    {
+        case BASICVALUE_OID:
+            PrintCOidValue (f, r, v->value->basicValue->a.oid);
+            break;
+
+        case BASICVALUE_INTEGER:
+            fprintf (f, "%d", v->value->basicValue->a.integer);
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            if (v->value->basicValue->a.boolean)
+                fprintf (f, "TRUE");
+            else
+               fprintf (f, "FALSE");
+            break;
+
+        default:
+           break;
+    }
+
+
+}
+
+
+
+/*
+ * given an AOID, a c value is produced.
+ * This is used for turning ASN.1 OBJECT ID values
+ * into usable c values.
+ *
+ * eg for the oid { 0 1 2 } (in AOID format)
+ *
+ * {
+ *     2,
+ *     "\1\2"
+ * }
+ * is produced.
+ */
+void
+PrintCOidValue PARAMS ((f, r, oid),
+    FILE *f _AND_
+    CRules *r _AND_
+    AsnOid *oid)
+{
+    int i;
+
+    fprintf (f, "{ ");
+    fprintf (f, "%d, ",oid->octetLen);
+    fprintf (f, "\"");
+
+    /* print encoded oid string in C's 'octal' escape format */
+    for (i = 0; i < oid->octetLen; i++)
+        fprintf (f, "\\%o", (unsigned char) oid->octs[i]);
+    fprintf (f, "\"");
+    fprintf (f, " }");
+
+} /* PrintCOidValue */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.h
new file mode 100644
index 00000000..908ad4cd
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-vals.h
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-vals.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:44:13  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-vals -> c-gen/gen-vals.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:15  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:34  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+void PrintCValueDef PROTO ((FILE *src, CRules *r, ValueDef *v));
+
+void PrintCValueExtern  PROTO ((FILE *hdr, CRules *r, ValueDef *v));
+
+void PrintCOidValue PROTO ((FILE *f, CRules *r, AsnOid *oid));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals2.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals2.c
new file mode 100644
index 00000000..c9da8f77
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals2.c
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/gen-vals.c - prints ASN.1 values in C format
+ *
+ *
+ * MS Feb 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-vals2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-vals2.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1997/05/07 14:59:31  wan
+ * Fixed bug in C value string generation.
+ *
+ * Revision 1.3  1995/07/25 18:44:12  rj
+ * file name has been shortened for redundant part: c-gen/gen-c-vals -> c-gen/gen-vals.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:24:18  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:33  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "oid.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "define.h"
+#include "lib-types.h"
+#include "rules.h"
+#include "type-info.h"
+#include "str-util.h"
+#include "snacc-util.h"
+#include "util.h"
+#include "kwd.h"
+#include "gen-vals.h"
+
+/* non-exported routines' prototypes */
+
+static void PrintValueDefsName PROTO ((FILE *f, CRules *r, ValueDef *v));
+static void PrintValueDefsType PROTO ((FILE *f, CRules *r, ValueDef *v));
+static void PrintValueInstatiation PROTO ((FILE *f, CRules *r, ValueDef *v));
+
+
+
+
+void
+PrintCValueDef PARAMS ((src, r, v),
+    FILE *src _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    /* just do oid's, ints and bools for now */
+    if ((v->value->basicValue->choiceId != BASICVALUE_OID) &&
+        (v->value->basicValue->choiceId != BASICVALUE_INTEGER) &&
+        (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN))
+        return;
+
+    /*
+     * put instantiation in src file
+     */
+    PrintValueDefsType (src, r, v);
+    fprintf (src," ");
+    PrintValueDefsName (src, r, v);
+    fprintf (src," = ");
+    PrintValueInstatiation (src, r, v);
+    fprintf (src,";\n\n");
+
+}  /* PrintCValueDef */
+
+void
+PrintCValueExtern PARAMS ((hdr, r, v),
+    FILE *hdr _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    /* just do oid's, ints and bools for now */
+    if ((v->value->basicValue->choiceId != BASICVALUE_OID) &&
+        (v->value->basicValue->choiceId != BASICVALUE_INTEGER) &&
+        (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN))
+        return;
+
+    /*
+     * put extern declaration in hdr file
+     */
+    fprintf (hdr,"extern ");
+    PrintValueDefsType (hdr, r, v);
+    fprintf (hdr," ");
+    PrintValueDefsName (hdr, r, v);
+    fprintf (hdr,";\n");
+
+}  /* PrintCValueExtern */
+
+
+static void
+PrintValueDefsName PARAMS ((f, r, v),
+    FILE *f _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    char *cName;
+    cName = Asn1ValueName2CValueName (v->definedName);
+    fprintf (f, "%s", cName);
+    Free (cName);
+}
+
+static void
+PrintValueDefsType PARAMS ((f, r, v),
+    FILE *f _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    /* needs work - just do ints bools and oid's for now */
+    switch (v->value->basicValue->choiceId)
+    {
+        case BASICVALUE_OID:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_OID].cTypeName);
+            break;
+
+        case BASICVALUE_INTEGER:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_INTEGER].cTypeName);
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_BOOLEAN].cTypeName);
+            break;
+
+        default:
+           break;
+    }
+}
+
+
+static void
+PrintValueInstatiation PARAMS ((f, r, v),
+    FILE *f _AND_
+    CRules *r _AND_
+    ValueDef *v)
+{
+    /* needs work - just do ints, bools and oids for now */
+    switch (v->value->basicValue->choiceId)
+    {
+        case BASICVALUE_OID:
+            PrintCOidValue (f, r, v->value->basicValue->a.oid);
+            break;
+
+        case BASICVALUE_INTEGER:
+            fprintf (f, "%d", v->value->basicValue->a.integer);
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            if (v->value->basicValue->a.boolean)
+                fprintf (f, "TRUE");
+            else
+               fprintf (f, "FALSE");
+            break;
+
+        default:
+           break;
+    }
+
+
+}
+
+
+
+/*
+ * given an AOID, a c value is produced.
+ * This is used for turning ASN.1 OBJECT ID values
+ * into usable c values.
+ *
+ * eg for the oid { 0 1 2 } (in AOID format)
+ *
+ * {
+ *     2,
+ *     "\1\2"
+ * }
+ * is produced.
+ */
+void
+PrintCOidValue PARAMS ((f, r, oid),
+    FILE *f _AND_
+    CRules *r _AND_
+    AsnOid *oid)
+{
+    int i;
+
+    fprintf (f, "{ ");
+    fprintf (f, "%d, ",oid->octetLen);
+    fprintf (f, "\"");
+
+    /* print encoded oid string in C's 'octal' escape format */
+    for (i = 0; i < oid->octetLen; i++)
+        fprintf (f, "\\%o", (unsigned char) oid->octs[i]);
+    fprintf (f, "\"");
+    fprintf (f, " }");
+
+} /* PrintCOidValue */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.c
new file mode 100644
index 00000000..4c6777b2
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.c
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/kwd.c - routines for determining whether a given str is a C keyword
+ *
+ *    NOTE: this was hacked up really quickly.  It uses a slow linear
+ *          search. A much better approach is to use a hash tbl.
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: kwd.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1  2000/05/10 21:35:02  rmurphy
+ * Adding back in base code files which had been moved to "2" versions.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:45:38  rj
+ * file name has been shortened for redundant part: c-gen/c-kwd -> c-gen/kwd.
+ *
+ * Revision 1.3  1994/10/08  03:48:06  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:20:28  rj
+ * snacc_config.h removed; more portable .h file inclusion.
+ *
+ * Revision 1.1  1994/08/28  09:48:13  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "snacc.h"
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include "kwd.h"
+
+/*
+ * last elmt must be NULL.
+ * key words grabbed from K&R 2nd Ed
+ */
+static char *cKWdG[] =
+{
+    "auto", "break", "case", "char", "const", "continue",
+    "default", "do", "double", "else", "enum", "extern",
+    "float", "for", "goto", "if", "int", "long", "register",
+    "return", "short", "signed", "sizeof", "static", "struct",
+    "switch",  "typedef", "union", "unsigned", "void", "volatile",
+    "while", NULL
+};
+
+
+/*
+ * returns non-zero if the given str is a C key word
+ */
+int
+IsCKeyWord PARAMS ((str),
+    char *str)
+{
+    int i;
+
+    for (i=0; (cKWdG[i] != NULL) && (strcmp (cKWdG[i],str) != 0); i++)
+	;
+
+    return cKWdG[i] != NULL;
+}
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.h
new file mode 100644
index 00000000..2426ba6f
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/kwd.h - for determining whether a string is a C keyword
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: kwd.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:45:39  rj
+ * file name has been shortened for redundant part: c-gen/c-kwd -> c-gen/kwd.
+ *
+ * Revision 1.2  1994/10/08  03:48:07  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:14  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+int IsCKeyWord PROTO ((char *str));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd2.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd2.c
new file mode 100644
index 00000000..052d91c4
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd2.c
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/kwd.c - routines for determining whether a given str is a C keyword
+ *
+ *    NOTE: this was hacked up really quickly.  It uses a slow linear
+ *          search. A much better approach is to use a hash tbl.
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/kwd2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: kwd2.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:45:38  rj
+ * file name has been shortened for redundant part: c-gen/c-kwd -> c-gen/kwd.
+ *
+ * Revision 1.3  1994/10/08  03:48:06  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:20:28  rj
+ * snacc_config.h removed; more portable .h file inclusion.
+ *
+ * Revision 1.1  1994/08/28  09:48:13  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "snacc.h"
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include "kwd.h"
+
+/*
+ * last elmt must be NULL.
+ * key words grabbed from K&R 2nd Ed
+ */
+static char *cKWdG[] =
+{
+    "auto", "break", "case", "char", "const", "continue",
+    "default", "do", "double", "else", "enum", "extern",
+    "float", "for", "goto", "if", "int", "long", "register",
+    "return", "short", "signed", "sizeof", "static", "struct",
+    "switch",  "typedef", "union", "unsigned", "void", "volatile",
+    "while", NULL
+};
+
+
+/*
+ * returns non-zero if the given str is a C key word
+ */
+int
+IsCKeyWord PARAMS ((str),
+    char *str)
+{
+    int i;
+
+    for (i=0; (cKWdG[i] != NULL) && (strcmp (cKWdG[i],str) != 0); i++)
+	;
+
+    return cKWdG[i] != NULL;
+}
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.c
new file mode 100644
index 00000000..70b76438
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.c
@@ -0,0 +1,564 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/rules.c - initialized c rule structure
+ *           inits a table that contains info about
+ *           converting each ASN.1 type to C type
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: rules.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1  2000/05/10 21:35:02  rmurphy
+ * Adding back in base code files which had been moved to "2" versions.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:44  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:46:34  rj
+ * file name has been shortened for redundant part: c-gen/c-rules -> c-gen/rules.
+ *
+ * Revision 1.2  1994/09/01  00:24:35  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:35  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "rules.h"
+
+/*
+ *  (see rule.h and asn1module.h)
+*
+*/
+
+
+CRules cRulesG =
+{
+    4,
+    "choiceId",
+    "ChoiceId",
+    "a",
+    "ChoiceUnion",
+    TRUE,
+    "Print",
+    "Enc",
+    "Dec",
+    "Free",
+    {
+        {
+            BASICTYPE_UNKNOWN,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "unknown",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE
+        },
+        {
+            BASICTYPE_BOOLEAN,
+            C_LIB,
+            "AsnBool",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bool",
+            "PrintAsnBool",
+            "EncAsnBool",
+            "DecAsnBool",
+            "FreeAsnBool",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_INTEGER,
+            C_LIB,
+            "AsnInt",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "int",
+            "PrintAsnInt",
+            "EncAsnInt",
+            "DecAsnInt",
+            "FreeAsnInt",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_BITSTRING,
+            C_LIB,
+            "AsnBits",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            TRUE,
+            FALSE,
+            "ASNBITS_PRESENT",
+            "bits",
+            "PrintAsnBits",
+            "EncAsnBits",
+            "DecAsnBits",
+            "FreeAsnBits",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_OCTETSTRING,
+            C_LIB,
+            "AsnOcts",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            TRUE,
+            FALSE,
+            "ASNOCTS_PRESENT",
+            "octs",
+            "PrintAsnOcts",
+            "EncAsnOcts",
+            "DecAsnOcts",
+            "FreeAsnOcts",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_NULL,
+            C_LIB,
+            "AsnNull",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "null",
+            "PrintAsnNull",
+            "EncAsnNull",
+            "DecAsnNull",
+            "FreeAsnNull",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_OID,
+            C_LIB,
+            "AsnOid",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            TRUE,
+            FALSE,
+            "ASNOID_PRESENT",
+            "oid",
+            "PrintAsnOid",
+            "EncAsnOid",
+            "DecAsnOid",
+            "FreeAsnOid",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_REAL,
+            C_LIB,
+            "AsnReal",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "real",
+            "PrintAsnReal",
+            "EncAsnReal",
+            "DecAsnReal",
+            "FreeAsnReal",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_ENUMERATED,
+            C_LIB,
+            "enum",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "enum",
+            "PrintAsnEnum",
+            "EncAsnEnum",
+            "DecAsnEnum",
+            "FreeAsnEnum",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SEQUENCE,
+            C_STRUCT,
+            "struct",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "seq",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SEQUENCEOF,
+            C_LIST,
+            "AsnList",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "list",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SET,
+            C_STRUCT,
+            "struct",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "set",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SETOF,
+            C_LIST,
+            "AsnList",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "list",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_CHOICE,
+            C_CHOICE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "choice",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SELECTION,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "selection",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_COMPONENTSOF,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "compsOf",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_ANY,
+            C_ANY,
+            "AsnAny",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "any",
+            "PrintAsnAny",
+            "EncAsnAny",
+            "DecAsnAny",
+            "FreeAsnAny",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_ANYDEFINEDBY,
+            C_ANYDEFINEDBY,
+            "AsnAnyDefinedBy",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "anyDefBy",
+            "PrintAsnAnyDefinedBy",
+            "EncAsnAnyDefinedBy",
+            "DecAsnAnyDefinedBy",
+            "FreeAsnAnyDefinedBy",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_LOCALTYPEREF,
+            C_TYPEREF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "t",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_IMPORTTYPEREF,
+            C_TYPEREF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "t",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_MACROTYPE,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "macroType",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE
+        },
+        {
+            BASICTYPE_MACRODEF,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "macroDef",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE
+        }
+    }
+};
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.h
new file mode 100644
index 00000000..d1a977c0
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/rules.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: rules.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:43  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:46:35  rj
+ * file name has been shortened for redundant part: c-gen/c-rules -> c-gen/rules.
+ *
+ * Revision 1.2  1994/10/08  03:48:16  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:36  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+/* see asn1module.h for CTDI (C type def info) */
+
+typedef struct CRules
+{
+    int  maxDigitsToAppend;
+    char *choiceIdFieldName;   /* name of choiceId field */
+    char *choiceIdEnumSuffix;  /* suffix for choiceId enum def name */
+    char *choiceUnionFieldName; /* what the name of the choice's union is */
+    char *choiceUnionDefSuffix;  /* suffix for choice union def name */
+    int   capitalizeNamedElmts;
+    char *printRoutineBaseName;  /* eg if "Print" -> PrintFoo (..) */
+    char *encodeRoutineBaseName;
+    char *decodeRoutineBaseName;
+    char *freeRoutineBaseName;
+    CTDI typeConvTbl[BASICTYPE_MACRODEF + 1];
+}  CRules;
+
+extern CRules cRulesG;
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules2.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules2.c
new file mode 100644
index 00000000..466ff8e8
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules2.c
@@ -0,0 +1,561 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/rules.c - initialized c rule structure
+ *           inits a table that contains info about
+ *           converting each ASN.1 type to C type
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/rules2.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: rules2.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:44  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:46:34  rj
+ * file name has been shortened for redundant part: c-gen/c-rules -> c-gen/rules.
+ *
+ * Revision 1.2  1994/09/01  00:24:35  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:35  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "rules.h"
+
+/*
+ *  (see rule.h and asn1module.h)
+*
+*/
+
+
+CRules cRulesG =
+{
+    4,
+    "choiceId",
+    "ChoiceId",
+    "a",
+    "ChoiceUnion",
+    TRUE,
+    "Print",
+    "Enc",
+    "Dec",
+    "Free",
+    {
+        {
+            BASICTYPE_UNKNOWN,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "unknown",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE
+        },
+        {
+            BASICTYPE_BOOLEAN,
+            C_LIB,
+            "AsnBool",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bool",
+            "PrintAsnBool",
+            "EncAsnBool",
+            "DecAsnBool",
+            "FreeAsnBool",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_INTEGER,
+            C_LIB,
+            "AsnInt",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "int",
+            "PrintAsnInt",
+            "EncAsnInt",
+            "DecAsnInt",
+            "FreeAsnInt",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_BITSTRING,
+            C_LIB,
+            "AsnBits",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            TRUE,
+            FALSE,
+            "ASNBITS_PRESENT",
+            "bits",
+            "PrintAsnBits",
+            "EncAsnBits",
+            "DecAsnBits",
+            "FreeAsnBits",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_OCTETSTRING,
+            C_LIB,
+            "AsnOcts",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            TRUE,
+            FALSE,
+            "ASNOCTS_PRESENT",
+            "octs",
+            "PrintAsnOcts",
+            "EncAsnOcts",
+            "DecAsnOcts",
+            "FreeAsnOcts",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_NULL,
+            C_LIB,
+            "AsnNull",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "null",
+            "PrintAsnNull",
+            "EncAsnNull",
+            "DecAsnNull",
+            "FreeAsnNull",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_OID,
+            C_LIB,
+            "AsnOid",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            TRUE,
+            FALSE,
+            "ASNOID_PRESENT",
+            "oid",
+            "PrintAsnOid",
+            "EncAsnOid",
+            "DecAsnOid",
+            "FreeAsnOid",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_REAL,
+            C_LIB,
+            "AsnReal",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "real",
+            "PrintAsnReal",
+            "EncAsnReal",
+            "DecAsnReal",
+            "FreeAsnReal",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_ENUMERATED,
+            C_LIB,
+            "enum",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "enum",
+            "PrintAsnEnum",
+            "EncAsnEnum",
+            "DecAsnEnum",
+            "FreeAsnEnum",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SEQUENCE,
+            C_STRUCT,
+            "struct",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "seq",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SEQUENCEOF,
+            C_LIST,
+            "AsnList",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "list",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SET,
+            C_STRUCT,
+            "struct",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "set",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SETOF,
+            C_LIST,
+            "AsnList",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "list",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_CHOICE,
+            C_CHOICE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "choice",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_SELECTION,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "selection",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_COMPONENTSOF,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "compsOf",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_ANY,
+            C_ANY,
+            "AsnAny",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "any",
+            "PrintAsnAny",
+            "EncAsnAny",
+            "DecAsnAny",
+            "FreeAsnAny",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_ANYDEFINEDBY,
+            C_ANYDEFINEDBY,
+            "AsnAnyDefinedBy",
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "anyDefBy",
+            "PrintAsnAnyDefinedBy",
+            "EncAsnAnyDefinedBy",
+            "DecAsnAnyDefinedBy",
+            "FreeAsnAnyDefinedBy",
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_LOCALTYPEREF,
+            C_TYPEREF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "t",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_IMPORTTYPEREF,
+            C_TYPEREF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "t",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE
+        },
+        {
+            BASICTYPE_MACROTYPE,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "macroType",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE
+        },
+        {
+            BASICTYPE_MACRODEF,
+            C_NO_TYPE,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            "NOT_NULL",
+            "macroDef",
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE,
+            FALSE
+        }
+    }
+};
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.c
new file mode 100644
index 00000000..41ffe33c
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.c
@@ -0,0 +1,1315 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/type-info.c  - fills in c type information
+ *
+ * MS 91/92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: type-info.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:44  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:47:45  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:26:44  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:42  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "snacc-util.h"
+#include "define.h"
+#include "str-util.h"
+#include "rules.h"
+#include "type-info.h"
+
+
+extern Module *usefulTypeModG;
+static DefinedObj *definedNamesG;
+/*
+ *  All Typedefs, union,struct & enum Tags, and definedvalues (enum consts)
+ *  are assumed to share the same name space - this list is used to
+ *  assure uniqueness. (actually 4 name spaces in C - see pg 227 KR 2nd Ed)
+ */
+
+
+/* unexported prototypes */
+
+void FillCTypeDefInfo PROTO ((CRules *r,  Module *m,  TypeDef *td));
+
+static void FillCFieldNames PROTO ((CRules *r, NamedTypeList *firstSibling));
+
+static void FillCTypeRefInfo PROTO ((CRules *r,  Module *m,  TypeDef *head, Type *t, CTypeId parentTypeId));
+
+static void FillCStructElmts PROTO ((CRules *r,  Module *m,  TypeDef *head, NamedTypeList *t));
+
+static void FillCChoiceElmts PROTO ((CRules *r, Module *m, TypeDef *head, NamedTypeList *first));
+
+static int IsCPtr PROTO ((CRules *r, TypeDef *td, Type *t, CTypeId parentTypeId));
+
+
+void ParseTypeDefAttribs PROTO ((CTDI *ctdi, AttributeList *attrList));
+void ParseTypeRefAttribs PROTO ((CTRI *ctri, AttributeList *attrList));
+void ParseAttr PROTO ((char *str, int *startLoc, char **attrName, char **attrValue));
+
+int ParseBool PROTO ((char *str, int *result));
+int ParseInt PROTO ((char *str, int *result));
+int ParseCTypeId PROTO ((char *str, int *result));
+
+void FillCTDIDefaults PROTO ((CRules *r, CTDI *ctdi, TypeDef *td));
+
+
+/*
+ *  allocates and fills all the "cTypeDefInfo" for each type def
+ *  and "cTypeRefInfo" for each type in the given modules.
+ *  Also does the useful types module if it is not null.
+ */
+void
+FillCTypeInfo PARAMS ((r, modList),
+    CRules *r _AND_
+    ModuleList *modList)
+{
+    TypeDef *td;
+    Module *m;
+
+    /*
+     * go through each module's type defs and fill
+     * in the C type and enc/dec routines etc
+     */
+    definedNamesG = NewObjList();
+
+    /* do useful types first */
+    if (usefulTypeModG != NULL)
+    {
+        FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
+            FillCTypeDefInfo (r, usefulTypeModG, td);
+    }
+
+    FOR_EACH_LIST_ELMT (m, modList)
+    {
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+            FillCTypeDefInfo (r, m, td);
+    }
+
+    /*
+     * now that type def info is filled in
+     * set up set/seq/list/choice elements that ref
+     * those definitions
+     */
+
+    /* do useful types first */
+    if (usefulTypeModG != NULL)
+    {
+        FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
+            FillCTypeRefInfo (r, usefulTypeModG, td, td->type, C_TYPEDEF);
+    }
+
+    FOR_EACH_LIST_ELMT (m, modList)
+    {
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+            FillCTypeRefInfo (r, m, td, td->type, C_TYPEDEF);
+    }
+
+    /*
+     * modules compiled together (ie one call to snacc with
+     * multiple args) likely to be C compiled together so
+     * need a unique routines/types/defines/enum values
+     * since assuming they share same name space.
+     *  All Typedefs, union, struct & enum Tags, and defined values
+     * (enum consts), #define names
+     *  are assumed to share the same name space
+     */
+
+    FreeDefinedObjs (&definedNamesG);
+
+}  /* FillCTypeInfo */
+
+
+/*
+ *  allocates and fills structure holding C type definition information
+ *  fo the given ASN.1 type definition.  Does not fill CTRI for contained
+ *  types etc.
+ */
+void
+FillCTypeDefInfo PARAMS ((r, m, td),
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    int digit;
+    int len;
+    char *tmpName;
+    CTDI *ctdi;
+
+    /*
+     * if CTDI is present this type def has already been 'filled'
+     */
+    if (td->cTypeDefInfo != NULL)
+        return;
+
+    ctdi = td->cTypeDefInfo = MT (CTDI);
+    ctdi->cTypeId = C_TYPEDEF;
+
+    /* get default type def attributes from table for type on rhs of ::= */
+
+    FillCTDIDefaults (r, ctdi, td);
+
+
+    /*
+     * if defined by a ref to another type definition fill in that type
+     * def's CTDI so can inherit (actully completly replace default
+     * attributes) from it
+     */
+    if ((td->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+        (td->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+    {
+        /*
+         * Fill in CTDI for defining type if nec.
+         * this works for importTypeRef as well since both a.localTypeRef
+         * and a.importTypeRef are of type TypeRef
+         */
+        FillCTypeDefInfo (r, td->type->basicType->a.localTypeRef->module, td->type->basicType->a.localTypeRef->link);
+
+        memcpy (ctdi, td->type->basicType->a.localTypeRef->link->cTypeDefInfo, sizeof (CTDI));
+    }
+
+
+    /*
+     * Zap default names for routines/type with NULL so
+     * can determine if the --snacc attributes specified any
+     */
+    ctdi->cTypeName = NULL;
+    ctdi->printRoutineName = NULL;
+    ctdi->encodeRoutineName = NULL;
+    ctdi->decodeRoutineName = NULL;
+    ctdi->freeRoutineName = NULL;
+
+
+    /*
+     * check for any "--snacc" attributes that overide the current
+     * ctdi fields
+     */
+    ParseTypeDefAttribs (ctdi, td->attrList);
+
+
+    /*
+     * generate c typename for this  type def if not given by
+     * --snacc attributes
+     */
+    if (ctdi->cTypeName == NULL)
+    {
+        tmpName = Asn1TypeName2CTypeName (td->definedName);
+        len = strlen (tmpName);
+        ctdi->cTypeName = Malloc (len + r->maxDigitsToAppend + 1);
+        strcpy (ctdi->cTypeName, tmpName);
+        Free (tmpName);
+
+       /*
+        * make sure c type def name is unique
+        * (no need to check if cTypeName was specified by --snacc attribs)
+        */
+       MakeCStrUnique (definedNamesG, ctdi->cTypeName,r->maxDigitsToAppend, 1);
+       DefineObj (&definedNamesG, ctdi->cTypeName);
+    }
+
+
+    /*
+     * make names for encoder,decoder, print and free routines
+     * (if not already set by --snacc attributes
+     */
+    if (ctdi->encodeRoutineName == NULL)
+    {
+        ctdi->encodeRoutineName =
+            Malloc (strlen (ctdi->cTypeName) + strlen (r->encodeRoutineBaseName)
+                   + 1);
+        strcpy (ctdi->encodeRoutineName, r->encodeRoutineBaseName);
+        strcat (ctdi->encodeRoutineName, ctdi->cTypeName);
+    }
+
+    if (ctdi->decodeRoutineName == NULL)
+    {
+        ctdi->decodeRoutineName =
+            Malloc (strlen (ctdi->cTypeName) + strlen (r->decodeRoutineBaseName) + 1);
+        strcpy (ctdi->decodeRoutineName, r->decodeRoutineBaseName);
+        strcat (ctdi->decodeRoutineName, ctdi->cTypeName);
+    }
+
+    if (ctdi->printRoutineName == NULL)
+    {
+        ctdi->printRoutineName =
+            Malloc (strlen (ctdi->cTypeName) + strlen (r->printRoutineBaseName) + 1);
+        strcpy (ctdi->printRoutineName, r->printRoutineBaseName);
+        strcat (ctdi->printRoutineName, ctdi->cTypeName);
+    }
+
+    if (ctdi->freeRoutineName == NULL)
+    {
+        ctdi->freeRoutineName =
+            Malloc (strlen (ctdi->cTypeName) + strlen (r->freeRoutineBaseName) + 1);
+        strcpy (ctdi->freeRoutineName, r->freeRoutineBaseName);
+        strcat (ctdi->freeRoutineName, ctdi->cTypeName);
+    }
+
+}  /* FillCTypeDefInfo */
+
+
+static void
+FillCTypeRefInfo PARAMS ((r, m, head, t, parentTypeId),
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    CTypeId parentTypeId)
+{
+    char	*typeStr;
+    CTRI	*ctri;
+    CTDI	*tmpCtdi;
+    ValueDef	*namedElmt;
+    CNamedElmt	*cne;
+    CNamedElmt	**cneHndl;
+    char	*elmtName;
+    char	*listName;
+    char	*choiceName;
+    char	*unionName;
+    Type	*tmpT;
+    int		len, digit;
+    enum BasicTypeChoiceId basicTypeId;
+
+    /*
+     * you must check for cycles yourself before calling this
+     */
+    if (t->cTypeRefInfo == NULL)
+    {
+        ctri = MT (CTRI);
+        t->cTypeRefInfo = ctri;
+    }
+    else
+        ctri =  t->cTypeRefInfo;
+
+    basicTypeId = t->basicType->choiceId;
+
+    tmpCtdi = &r->typeConvTbl[basicTypeId];
+
+    /* get base type def info from the conversion table in the rules */
+    /* if the cTypeId is C_LIB, nothing more needs to be done */
+    ctri->cTypeId = tmpCtdi->cTypeId;
+    ctri->cTypeName = tmpCtdi->cTypeName;
+    ctri->optTestRoutineName = tmpCtdi->optTestRoutineName;
+    ctri->printRoutineName = tmpCtdi->printRoutineName;
+    ctri->encodeRoutineName = tmpCtdi->encodeRoutineName;
+    ctri->decodeRoutineName = tmpCtdi->decodeRoutineName;
+    ctri->freeRoutineName = tmpCtdi->freeRoutineName;
+    ctri->isEncDec = tmpCtdi->isEncDec;
+
+
+    if (ctri->cTypeId == C_ANY)
+    {
+        fprintf (stderr,"Warning - generated code for the \"ANY\" type in type \"%s\" will need modification by YOU.", head->definedName);
+        fprintf (stderr,"  The source files will have a \"/* ANY - Fix Me! */\" comment before related code.\n\n");
+     }
+
+    /*
+     * convert named elmts to C.
+     * check for name conflict with other defined Types/Names/Values
+     */
+    if ((basicTypeId == BASICTYPE_INTEGER || basicTypeId == BASICTYPE_ENUMERATED || basicTypeId == BASICTYPE_BITSTRING) && !(LIST_EMPTY (t->basicType->a.integer)))
+    {
+        ctri->cNamedElmts = AsnListNew (sizeof (void *));
+        FOR_EACH_LIST_ELMT (namedElmt, t->basicType->a.integer)
+        {
+            cneHndl = (CNamedElmt **)AsnListAppend (ctri->cNamedElmts);
+            cne = *cneHndl = MT (CNamedElmt);
+            elmtName = Asn1ValueName2CValueName (namedElmt->definedName);
+            len = strlen (elmtName);
+            cne->name = Malloc (len + 1 + r->maxDigitsToAppend);
+            strcpy (cne->name, elmtName);
+            Free (elmtName); /* not very efficient */
+
+            if (namedElmt->value->basicValue->choiceId == BASICVALUE_INTEGER)
+                cne->value = namedElmt->value->basicValue->a.integer;
+            else
+            {
+                fprintf (stderr,"Warning: unlinked defined value using -9999999\n");
+                cne->value = -9999999;
+            }
+
+            if (r->capitalizeNamedElmts)
+                Str2UCase (cne->name, len);
+
+            /*
+             * append digits until there is not name conflict
+             * if nec
+             */
+            MakeCStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1);
+            DefineObj (&definedNamesG, cne->name);
+        }
+    }
+
+    /*
+     *  Fill in c type name, routines, ptr attibutes etc
+     */
+    if (r->typeConvTbl[basicTypeId].cTypeId == C_TYPEREF)
+    {
+        /*
+         * don't do this anymore - it cause problems since FillTypeDef
+         * changes name ie ORName -> ORName1 and other type use new name
+         *
+         * don't define type or print/enc/dec/free routines
+         * if typedef name is the same as the defining type ref name
+         * in P2: ORName ::= P1.ORName
+        if ((parentTypeId == C_TYPEDEF) &&
+            (strcmp (head->definedName, t->basicType->a.localTypeRef->typeName)
+             == 0))
+        {
+            tmpCtdi = head->cTypeDefInfo;
+            tmpCtdi->genPrintRoutine = FALSE;
+            tmpCtdi->genEncodeRoutine = FALSE;
+            tmpCtdi->genDecodeRoutine = FALSE;
+            tmpCtdi->genFreeRoutine = FALSE;
+            tmpCtdi->genTypeDef = FALSE;
+        }
+         */
+
+        /*
+         * grab type name from link (link is the def of the
+         * the ref'd type)
+         */
+        if (t->basicType->a.localTypeRef->link != NULL)
+        {
+            /* inherit attributes from referenced type */
+            tmpCtdi=  t->basicType->a.localTypeRef->link->cTypeDefInfo;
+            ctri->cTypeName = tmpCtdi->cTypeName;
+            ctri->printRoutineName  = tmpCtdi->printRoutineName;
+            ctri->encodeRoutineName = tmpCtdi->encodeRoutineName;
+            ctri->decodeRoutineName = tmpCtdi->decodeRoutineName;
+            ctri->freeRoutineName = tmpCtdi->freeRoutineName;
+            ctri->isEncDec = tmpCtdi->isEncDec;
+            ctri->optTestRoutineName = tmpCtdi->optTestRoutineName;
+
+        }
+        else
+        {
+            /*
+             * guess type and routine names
+             */
+            fprintf (stderr,"Assuming C Type and Routine names for unresolved type ref \"%s\"\n",t->basicType->a.localTypeRef->typeName);
+
+            ctri->cTypeName = Asn1TypeName2CTypeName (t->basicType->a.localTypeRef->typeName);
+
+            ctri->printRoutineName = Malloc (strlen (r->printRoutineBaseName) + strlen (ctri->cTypeName) + 1);
+            strcpy (ctri->printRoutineName, r->printRoutineBaseName);
+            strcat (ctri->printRoutineName, ctri->cTypeName);
+
+            ctri->encodeRoutineName = Malloc (strlen (r->encodeRoutineBaseName)+ strlen (ctri->cTypeName) +  1);
+            strcpy (ctri->encodeRoutineName, r->encodeRoutineBaseName);
+            strcat (ctri->encodeRoutineName, ctri->cTypeName);
+
+            ctri->decodeRoutineName = Malloc (strlen (r->decodeRoutineBaseName)+ strlen (ctri->cTypeName) + 1);
+            strcpy (ctri->decodeRoutineName, r->decodeRoutineBaseName);
+            strcat (ctri->decodeRoutineName, ctri->cTypeName);
+
+            ctri->freeRoutineName = Malloc (strlen (ctri->cTypeName) + strlen (r->freeRoutineBaseName) + 1);
+            strcpy (ctri->freeRoutineName, r->freeRoutineBaseName);
+            strcat (ctri->freeRoutineName, ctri->cTypeName);
+        }
+
+    }
+
+    else if (r->typeConvTbl[basicTypeId].cTypeId == C_LIST)
+    {
+        /*
+         * List  types (SET OF/ SEQ OF)
+         * fill in component type
+         */
+
+        FillCTypeRefInfo (r, m, head, t->basicType->a.setOf, C_LIST);
+    }
+
+    else if (r->typeConvTbl[basicTypeId].cTypeId == C_CHOICE)
+    {
+        /*
+         * Choice - set up choice Id elmt names, choiceid enum name
+         * choiceid enum fieldName, choice union name.
+         * this will only be the first type in the typedef
+         * ie will not be embedded (those are turned into type
+         * refs in nomalize.c)
+         */
+
+        /*
+         * make union name (tag) from enclosing typedefs name plus "Choice"
+         * put in the cTypeName part. (the typeDef name is already unique
+         * but make sure union tag/name does not conflict with other types)
+         */
+        len = strlen (head->cTypeDefInfo->cTypeName);
+        unionName = (char*) Malloc (len + strlen (r->choiceUnionDefSuffix) + r->maxDigitsToAppend + 1);
+        strcpy (unionName, head->cTypeDefInfo->cTypeName);
+        strcat (unionName, r->choiceUnionDefSuffix);
+        MakeCStrUnique (definedNamesG, unionName,  r->maxDigitsToAppend, 1);
+        DefineObj (&definedNamesG, unionName);
+        ctri->cTypeName = unionName;
+
+        ctri->choiceIdEnumName = Malloc (len + strlen (r->choiceIdEnumSuffix) + r->maxDigitsToAppend + 1);
+        strcpy (ctri->choiceIdEnumName, head->cTypeDefInfo->cTypeName);
+        strcat (ctri->choiceIdEnumName, r->choiceIdEnumSuffix);
+        MakeCStrUnique (definedNamesG, ctri->choiceIdEnumName,  r->maxDigitsToAppend, 1);
+        DefineObj (&definedNamesG, ctri->choiceIdEnumName);
+
+        ctri->choiceIdEnumFieldName = r->choiceIdFieldName; /* "choiceId" */
+        ctri->cFieldName = r->choiceUnionFieldName;         /* "a" */
+
+        /*
+         * must fill field names BEFORE filling choice elmts
+         * (allows better naming for choice ids
+         */
+        FillCFieldNames (r, t->basicType->a.choice);
+        FillCChoiceElmts (r, m, head, t->basicType->a.choice);
+
+    }
+
+    else if (r->typeConvTbl[basicTypeId].cTypeId == C_STRUCT)
+    {
+        /*
+         * SETs and SEQUENCEs
+         */
+
+        /*
+         * make struct name (tag) (the typeDef name is already unique)
+         * the same as the enclosing typeDef
+         */
+        unionName = Malloc (strlen (head->cTypeDefInfo->cTypeName) +1);
+        strcpy (unionName, head->cTypeDefInfo->cTypeName);
+        ctri->cTypeName = unionName;
+
+        FillCStructElmts (r, m, head, t->basicType->a.set);
+        FillCFieldNames (r, t->basicType->a.set);
+    }
+
+    /*
+     * figure out whether this is a ptr based on the enclosing
+     * type (if any) and optionality/default
+     */
+    ctri->isPtr = IsCPtr (r, head, t, parentTypeId);
+
+    /* let user overide any defaults with the --snacc attributes */
+    ParseTypeRefAttribs (ctri, t->attrList);
+
+
+}  /* FillCTypeRefInfo */
+
+
+
+static void
+FillCStructElmts PARAMS ((r, m, head, elmts),
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *head _AND_
+    NamedTypeList *elmts)
+{
+    NamedType *et;
+
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        FillCTypeRefInfo (r, m, head, et->type, C_STRUCT);
+    }
+
+}  /* FillCStructElmts */
+
+
+
+/*
+ *  Figures out non-conflicting enum names for the
+ *  choice id's
+ */
+static void
+FillCChoiceElmts PARAMS ((r, m, head, elmts),
+    CRules *r _AND_
+    Module *m _AND_
+    TypeDef *head _AND_
+    NamedTypeList *elmts)
+{
+    NamedType *et;
+    int idCount = 0;
+    CTRI *ctri;
+    char *firstName;
+    char *secondName;
+    int   len;
+
+    /*
+     * fill in type info for elmt types first
+     */
+    FOR_EACH_LIST_ELMT (et, elmts)
+        FillCTypeRefInfo (r, m, head, et->type, C_CHOICE);
+
+    /*
+     * set choiceId Symbol & value
+     * eg
+     *  Car ::= CHOICE {          typedef struct Car {
+     *     chev ChevCar,   ->         enum CarChoiceId {
+     *     ford FordCar                  CAR_CHEV,  <- typename_fieldName
+     *     toyota ToyotaCar              CAR_FORD,
+     *     }                             CAR_TOYOTA } choiceId;
+     *                                union CarChoiceUnion {
+     *                                      ChevCar *chev;
+     *                                      FordCar *ford;
+     *                                      ToyotaCar *toyota; } a;
+     *                               }
+     */
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        ctri =  et->type->cTypeRefInfo;
+
+        if (ctri == NULL)
+            continue; /* wierd type */
+
+        ctri->choiceIdValue = idCount++;
+
+        firstName = Asn1TypeName2CTypeName (head->cTypeDefInfo->cTypeName);
+        secondName = ctri->cFieldName;
+        ctri->choiceIdSymbol = Malloc (strlen (firstName) + strlen (secondName) + 2 + r->maxDigitsToAppend);
+        strcpy (ctri->choiceIdSymbol, firstName);
+        strcat (ctri->choiceIdSymbol, "_");
+        strcat (ctri->choiceIdSymbol, secondName);
+        Free (firstName);
+        len = strlen (ctri->choiceIdSymbol);
+
+        if (r->capitalizeNamedElmts)
+            Str2UCase (ctri->choiceIdSymbol, len);
+
+        MakeCStrUnique (definedNamesG, ctri->choiceIdSymbol, r->maxDigitsToAppend, 0);
+        DefineObj (&definedNamesG, ctri->choiceIdSymbol);
+    }
+
+}  /* FillCChoiceElmts */
+
+
+/*
+ * takes a list of "sibling" (eg same level in a structure)
+ * ElmtTypes and fills sets up the c field names in
+ * the CTypeRefInfo struct
+ */
+static void
+FillCFieldNames PARAMS ((r, elmts),
+    CRules *r _AND_
+    NamedTypeList *elmts)
+{
+    NamedType  *et;
+    CTRI *ctri;
+    DefinedObj *fieldNames;
+    int        len, num, digit, i, tmpLen;
+    char      *tmpName;
+    char      *asn1FieldName;
+    char      *cFieldName;
+
+    fieldNames = NewObjList();
+
+    /*
+     * Initialize fieldname data
+     * allocate (if nec) and fill in CTRI fieldname if poss
+     * from asn1 field name.  leave blank otherwise
+     */
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        ctri =  et->type->cTypeRefInfo;
+        if (ctri == NULL)
+        {
+            ctri = MT (CTRI);
+            et->type->cTypeRefInfo = ctri;
+        }
+        if (et->fieldName != NULL)
+        {
+            asn1FieldName = et->fieldName;
+            ctri->cFieldName = Asn1FieldName2CFieldName (asn1FieldName);
+            DefineObj (&fieldNames, ctri->cFieldName);
+        }
+    }
+
+
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        ctri =  et->type->cTypeRefInfo;
+
+        /*
+         * generate field names for those without them
+         */
+        if (ctri->cFieldName == NULL)
+        {
+            if ((et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+                 (et->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+            {
+                /*
+                 * take ref'd type name as field name
+                 * convert first let to lower case
+                 */
+                tmpName = et->type->basicType->a.localTypeRef->link->cTypeDefInfo->cTypeName;
+                tmpName =  Asn1TypeName2CTypeName (tmpName);
+                cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
+                strcpy (cFieldName, tmpName);
+                Free (tmpName);
+                if (isupper (cFieldName[0]))
+                    cFieldName[0] = tolower (cFieldName[0]);
+            }
+            else
+            {
+                /*
+                 * get default field name for this type
+                 */
+                tmpName = r->typeConvTbl[et->type->basicType->choiceId].defaultFieldName;
+                cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
+                strcpy (cFieldName, tmpName);
+
+                if (isupper (cFieldName[0]))
+                    cFieldName[0] = tolower (cFieldName[0]);
+            }
+
+
+            MakeCStrUnique (fieldNames, cFieldName, r->maxDigitsToAppend, 1);
+
+            DefineObj (&fieldNames, cFieldName);
+            ctri->cFieldName = cFieldName;
+        }
+    }
+    FreeDefinedObjs (&fieldNames);
+}  /* FillCFieldNames */
+
+
+
+/*
+ * returns true if this c type for this type should be
+ * be ref'd as a ptr
+ */
+static int
+IsCPtr PARAMS ((r, td, t, parentCTypeId),
+    CRules *r _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    CTypeId parentCTypeId)
+{
+    CTDI *ctdi;
+    int retVal = FALSE;
+
+    /*
+     * inherit ptr attriubutes from ref'd type if any
+     * otherwise grab lib c type def from the CRules
+     */
+    if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+        (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+    {
+        ctdi = t->basicType->a.localTypeRef->link->cTypeDefInfo;
+    }
+    else
+        ctdi = &r->typeConvTbl[GetBuiltinType (t)];
+
+    if ((parentCTypeId == C_TYPEDEF) && (ctdi->isPtrForTypeDef))
+        retVal = TRUE;
+
+    else if ((parentCTypeId == C_STRUCT) && (ctdi->isPtrForTypeRef))
+        retVal = TRUE;
+
+    else if ((parentCTypeId == C_CHOICE) && (ctdi->isPtrInChoice))
+        retVal = TRUE;
+
+    else if (((t->optional) || (t->defaultVal != NULL)) && (ctdi->isPtrForOpt))
+        retVal = TRUE;
+
+    return retVal;
+}  /* IsCPtr */
+
+
+
+#define BAD_VALUE(attrValue, attrType)\
+    fprintf (stderr,"Warning: ignoring attribute with improper value (%s/%s)\n",attrType, attrValue)
+
+/*
+ * attrList is a list of strings that hold attribute value
+ * pairs.  A list is used in case the attr/value pairs are
+ * given in multiple ASN.1 comments around the type.
+ */
+void ParseTypeDefAttribs PARAMS ((ctdi, attrList),
+    CTDI *ctdi _AND_
+    AttributeList *attrList)
+{
+    char *attrName;
+    char *attrValue;
+    int loc;
+    MyString attr;
+    int result;
+
+    if (attrList == NULL)
+        return;
+
+    FOR_EACH_LIST_ELMT (attr, attrList)
+    {
+        loc = 0;  /* loc is location to start/continue parse from */
+
+        while (1)
+        {
+            ParseAttr (attr, &loc, &attrName, &attrValue);
+
+            if (attrName == NULL)
+               break;
+
+            if (strcmp (attrName, "asn1TypeId") == 0)
+            {
+               if (ParseTypeId (attrValue, &result) < 0)
+                   BAD_VALUE (attrValue, attrName);
+               else
+                   ctdi->asn1TypeId = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "cTypeId") == 0)
+            {
+               if (ParseCTypeId (attrValue, &result) < 0)
+                   BAD_VALUE (attrValue, attrName);
+               else
+                   ctdi->cTypeId = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "cTypeName") == 0)
+                ctdi->cTypeName = attrValue;
+
+            else if (strcmp (attrName, "isPdu") == 0)
+            {
+               if (ParseBool (attrValue, &result) < 0)
+                   BAD_VALUE (attrValue, attrName);
+               else
+                   ctdi->isPdu = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "isPtrForTypeDef") == 0)
+            {
+               if (ParseBool (attrValue, &result) < 0)
+                   BAD_VALUE (attrValue, attrName);
+               else
+                   ctdi->isPtrForTypeDef = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "isPtrForTypeRef") == 0)
+            {
+               if (ParseBool (attrValue, &result) < 0)
+                   BAD_VALUE (attrValue, attrName);
+               else
+                   ctdi->isPtrForTypeRef = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "isPtrInChoice") == 0)
+            {
+               if (ParseBool (attrValue, &result) < 0)
+                   BAD_VALUE (attrValue, attrName);
+               else
+                   ctdi->isPtrInChoice = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "isPtrForOpt") == 0)
+            {
+               if (ParseBool (attrValue, &result) < 0)
+                   BAD_VALUE (attrValue, attrName);
+               else
+                   ctdi->isPtrForOpt = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "optTestRoutineName") == 0)
+                ctdi->optTestRoutineName = attrValue;
+
+            else if (strcmp (attrName, "defaultFieldName") == 0)
+                ctdi->defaultFieldName = attrValue;
+
+            else if (strcmp (attrName, "printRoutineName") == 0)
+                ctdi->printRoutineName = attrValue;
+
+            else if (strcmp (attrName, "encodeRoutineName") == 0)
+                ctdi->encodeRoutineName = attrValue;
+
+            else if (strcmp (attrName, "decodeRoutineName") == 0)
+                ctdi->decodeRoutineName = attrValue;
+
+            else if (strcmp (attrName, "freeRoutineName") == 0)
+                ctdi->freeRoutineName = attrValue;
+
+            else if (strcmp (attrName, "isEncDec") == 0)
+            {
+                if  (ParseBool (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                {
+                    ctdi->isEncDec = result;
+                }
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "genTypeDef") == 0)
+            {
+                if  (ParseBool (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                {
+                    ctdi->genTypeDef = result;
+                }
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "genPrintRoutine") == 0)
+            {
+                if  (ParseBool (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                    ctdi->genPrintRoutine = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "genEncodeRoutine") == 0)
+            {
+                if  (ParseBool (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                    ctdi->genEncodeRoutine = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "genDecodeRoutine") == 0)
+            {
+                if  (ParseBool (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                    ctdi->genDecodeRoutine = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "genFreeRoutine") == 0)
+            {
+                if  (ParseBool (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                    ctdi->genFreeRoutine = result;
+                Free (attrValue);
+            }
+
+            else
+                fprintf (stderr,"Warning: ignoring unrecognized type def attribute value pair (%s/%s)\n", attrName, attrValue);
+
+        } /* end while */
+    } /* end for */
+
+} /* ParseTypeDefAttribs */
+
+
+void ParseTypeRefAttribs PARAMS ((ctri, attrList),
+    CTRI *ctri _AND_
+    AttributeList *attrList)
+{
+    char *attrName;
+    char *attrValue;
+    int loc;
+    int result;
+    MyString attr;
+
+    if (attrList == NULL)
+        return;
+
+    FOR_EACH_LIST_ELMT (attr, attrList)
+    {
+        loc = 0;  /* loc is location to start/continue parse from */
+
+        while (1)
+        {
+            ParseAttr (attr, &loc, &attrName, &attrValue);
+
+            if (attrName == NULL)
+               break;
+
+            if (strcmp (attrName, "cTypeId") == 0)
+            {
+                if  (ParseCTypeId (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                    ctri->cTypeId = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "cTypeName") == 0)
+                ctri->cTypeName = attrValue;
+
+            else if (strcmp (attrName, "cFieldName") == 0)
+                ctri->cFieldName = attrValue;
+
+            else if (strcmp (attrName, "isPtr") == 0)
+            {
+                if  (ParseBool (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                    ctri->isPtr = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "choiceIdValue") == 0)
+            {
+                if  (ParseInt (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                    ctri->choiceIdValue = result;
+                Free (attrValue);
+            }
+            else if (strcmp (attrName, "choiceIdSymbol") == 0)
+                    ctri->choiceIdSymbol = attrValue;
+
+            else if (strcmp (attrName, "choiceIdEnumName") == 0)
+                    ctri->choiceIdEnumName = attrValue;
+
+            else if (strcmp (attrName, "choiceIdEnumFieldName") == 0)
+                    ctri->choiceIdEnumFieldName = attrValue;
+
+            else if (strcmp (attrName, "optTestRoutineName") == 0)
+                    ctri->optTestRoutineName = attrValue;
+
+            else if (strcmp (attrName, "printRoutineName") == 0)
+                    ctri->printRoutineName = attrValue;
+
+            else if (strcmp (attrName, "encodeRoutineName") == 0)
+                    ctri->encodeRoutineName = attrValue;
+
+            else if (strcmp (attrName, "decodeRoutineName") == 0)
+                    ctri->decodeRoutineName = attrValue;
+
+            else if (strcmp (attrName, "isEncDec") == 0)
+            {
+                if  (ParseBool (attrValue, &result) < 0)
+                    BAD_VALUE (attrValue, attrName);
+                else
+                    ctri->isEncDec = result;
+                Free (attrValue);
+            }
+
+            else
+                fprintf (stderr,"Warning: ignoring unrecognized type ref attribute value pair (%s/%s)\n", attrName, attrValue);
+
+
+        } /* end while/ per comment */
+    } /* end per att str */
+} /* ParseTypeRefAttribs */
+
+
+int
+ParseBool PARAMS ((str, result),
+    char *str _AND_
+    int *result)
+{
+   if (strcmp (str,"TRUE")==0)
+   {
+       *result = TRUE;
+       return 0;
+   }
+
+   if (strcmp (str,"FALSE")==0)
+   {
+       *result = FALSE;
+       return 0;
+   }
+   return -1;
+}
+
+int
+ParseInt PARAMS ((str, result),
+    char *str _AND_
+    int *result)
+{
+    *result = atoi (str);
+    return 0;
+}
+
+int
+ParseCTypeId PARAMS ((str, result),
+    char *str _AND_
+    int *result)
+{
+    if (strcmp (str,"C_CHOICE"))
+    {
+        *result = C_CHOICE;
+        return 0;
+    }
+    if (strcmp (str,"C_LIST"))
+    {
+        *result = C_LIST;
+        return 0;
+    }
+    if (strcmp (str,"C_ANY"))
+    {
+        *result = C_ANY;
+        return 0;
+    }
+    if (strcmp (str,"C_ANYDEFINEDBY"))
+    {
+        *result = C_ANYDEFINEDBY;
+        return 0;
+    }
+    if (strcmp (str,"C_LIB"))
+    {
+        *result = C_LIB;
+        return 0;
+    }
+    if (strcmp (str,"C_STRUCT"))
+    {
+        *result = C_STRUCT;
+        return 0;
+    }
+    if (strcmp (str,"C_TYPEREF"))
+    {
+        *result = C_TYPEREF;
+        return 0;
+    }
+    if (strcmp (str,"C_TYPEDEF"))
+    {
+        *result = C_TYPEDEF;
+        return 0;
+    }
+    if (strcmp (str,"C_NO_TYPE"))
+    {
+        *result = C_NO_TYPE;
+        return 0;
+    }
+    return -1;
+}
+
+int
+ParseTypeId PARAMS ((str, result),
+    char *str _AND_
+    int *result)
+{
+    if (strcmp (str,"UNKNOWN"))
+    {
+        *result = BASICTYPE_UNKNOWN;
+        return 0;
+    }
+    if (strcmp (str,"BOOLEAN"))
+    {
+        *result = BASICTYPE_BOOLEAN;
+        return 0;
+    }
+    if (strcmp (str,"INTEGER"))
+    {
+        *result = BASICTYPE_INTEGER;
+        return 0;
+    }
+    if (strcmp (str,"BITSTRING"))
+    {
+        *result = BASICTYPE_BITSTRING;
+        return 0;
+    }
+    if (strcmp (str,"OCTETSTRING"))
+    {
+        *result = BASICTYPE_OCTETSTRING;
+        return 0;
+    }
+    if (strcmp (str,"NULL"))
+    {
+        *result = BASICTYPE_NULL;
+        return 0;
+    }
+    if (strcmp (str,"OID"))
+    {
+        *result = BASICTYPE_OID;
+        return 0;
+    }
+    if (strcmp (str,"REAL"))
+    {
+        *result = BASICTYPE_REAL;
+        return 0;
+    }
+    if (strcmp (str,"ENUMERATED"))
+    {
+        *result = BASICTYPE_ENUMERATED;
+        return 0;
+    }
+    if (strcmp (str,"SEQUENCE"))
+    {
+        *result = BASICTYPE_SEQUENCE;
+        return 0;
+    }
+    if (strcmp (str,"SEQUENCEOF"))
+    {
+        *result = BASICTYPE_SEQUENCEOF;
+        return 0;
+    }
+    if (strcmp (str,"SET"))
+    {
+        *result = BASICTYPE_SET;
+        return 0;
+    }
+    if (strcmp (str,"SETOF"))
+    {
+        *result = BASICTYPE_SETOF;
+        return 0;
+    }
+    if (strcmp (str,"CHOICE"))
+    {
+        *result = BASICTYPE_CHOICE;
+        return 0;
+    }
+    if (strcmp (str,"ANY"))
+    {
+        *result = BASICTYPE_ANY;
+        return 0;
+    }
+    if (strcmp (str,"ANYDEFINEDBY"))
+    {
+        *result = BASICTYPE_ANYDEFINEDBY;
+        return 0;
+    }
+    if (strcmp (str,"LOCALTYPEREF"))
+    {
+        *result = BASICTYPE_LOCALTYPEREF;
+        return 0;
+    }
+    if (strcmp (str,"IMPORTYPEREF"))
+    {
+        *result = BASICTYPE_IMPORTTYPEREF;
+        return 0;
+    }
+    return -1;
+} /* ParseTypeId */
+
+
+/*
+ * read attribute value pair from given str starting
+ * at str[loc].  Allocate and return attibute value
+ * in the attrValue  parameter. The attribute name is
+ * returned in the attrName parameter - do not free this
+ * as it is statically defined and overwritten with
+ * each call to ParseAttr.
+ * str must be NULL terminated.
+ *
+ */
+void
+ParseAttr PARAMS ((str, startLoc, attrName, attrValue),
+    char *str _AND_
+    int *startLoc _AND_
+    char **attrName _AND_
+    char **attrValue)
+{
+    int len;
+    int loc;
+    int attrNameStart;
+    int attrNameEnd;
+    int attrValueStart;
+    int attrValueEnd;
+    static char retAttrName[200];
+    char *retAttrValue;
+
+    loc = *startLoc;
+
+    len = strlen (str)-1;
+
+    /* skip whitespc */
+    for (; (loc <= len)  && str[loc] == ' '; loc++)
+	;
+
+    if (loc >= len)
+    {
+        *attrName = NULL;
+        *attrValue = NULL;
+        return;
+    }
+
+    attrNameStart = loc;
+
+    for (; (loc <= len) && str[loc] != ':'; loc++)
+	;
+
+    if (loc > len)
+    {
+        *attrName = NULL;
+        *attrValue = NULL;
+        return;
+    }
+
+    attrNameEnd = loc-1;
+
+    loc++; /* skip: */
+
+    /* check for and skip "  */
+    if (str[loc++] != '"')
+    {
+        *attrName = NULL;
+        *attrValue = NULL;
+        fprintf (stderr,"ERROR in snacc comment attribute string \"%s\".  Missing quote at beggining of field value\n",str);
+        return;
+    }
+
+    attrValueStart = loc;
+
+    for (; (loc <= len) && str[loc] != '"'; loc++)
+	;
+
+    attrValueEnd = loc-1;
+
+    if ((loc > len) || (str[attrValueStart-1] != '"'))
+    {
+        *attrName = NULL;
+        *attrValue = NULL;
+        fprintf (stderr,"Parsing Error after position %d in snacc attribute string \"%s\".\n",*startLoc, str);
+        return;
+    }
+
+    *startLoc = loc + 1;
+    retAttrValue = (char*) Malloc (attrValueEnd - attrValueStart + 2);
+    strncpy (retAttrName, &str[attrNameStart], attrNameEnd-attrNameStart+1);
+    strncpy (retAttrValue, &str[attrValueStart], attrValueEnd-attrValueStart+1);
+    retAttrValue[attrValueEnd-attrValueStart+1] = '\0';
+    retAttrName[attrNameEnd-attrNameStart+1] = '\0';
+
+    *attrName = retAttrName;
+    *attrValue = retAttrValue;
+} /* ParseAttr */
+
+
+
+/* fill given ctdi with defaults from table for given typedef */
+void
+FillCTDIDefaults PARAMS ((r, ctdi, td),
+    CRules *r _AND_
+    CTDI *ctdi _AND_
+    TypeDef *td)
+{
+    CTDI *tblCtdi;
+    int typeIndex;
+
+    typeIndex = GetBuiltinType (td->type);
+
+    if (typeIndex < 0)
+        return;
+
+    tblCtdi = &r->typeConvTbl[typeIndex];
+
+    memcpy (ctdi, tblCtdi, sizeof (CTDI));
+
+}
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.h
new file mode 100644
index 00000000..dee9fa5b
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.h
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/type-info.h  - fills in c type information
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/type-info.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: type-info.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:44  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:47:46  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:20  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:43  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+/*
+typedef struct CNamedElmt
+{
+    struct CNamedElmt *next;
+    int value;
+    char *name;
+} CNamedElmt;
+
+
+
+typedef struct CTypeInfo
+{
+    CTypeId           cTypeId;
+    char             *cFieldName;
+    char             *cTypeName;
+    int               isPtr;
+    int               isEndCType;
+    CNamedElmt       *cNamedElmts;
+    int               choiceIdValue;
+    char             *choiceIdSymbol;
+    char             *choiceIdEnumName;
+    char             *choiceIdEnumFieldName;
+    char             *printRoutineName;
+    char             *encodeRoutineName;
+    char             *decodeRoutineName;
+}  CTypeInfo;
+
+
+*/
+
+/*
+ * allows upto 9999 unamed fields of the same type in a single structure
+ * or 9999 values (diff asn1 scopes -> global c scope) with same name
+ */
+
+/*
+#define MAX_C_FIELD_NAME_DIGITS    4
+#define MAX_C_VALUE_NAME_DIGITS    4
+#define MAX_C_TYPE_NAME_DIGITS     4
+#define MAX_C_ROUTINE_NAME_DIGITS  4
+
+*/
+
+void PrintCTypeInfo PROTO ((FILE *f, Type *t));
+
+void FillCTypeInfo PROTO ((CRules *r, ModuleList *m));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.c b/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.c
new file mode 100644
index 00000000..83b73b21
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.c
@@ -0,0 +1,227 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/util.c  - utilities for generating C encoders and decoders
+ *
+ *  MS 91/11/04
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: util.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:44  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:48:38  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:26:52  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:44  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "rules.h"
+#include "snacc-util.h"
+#include "util.h"
+
+
+void
+MakeVarPtrRef PARAMS ((r, td, parent, fieldType, parentVarName, newVarName),
+    CRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *fieldType _AND_
+    char *parentVarName _AND_
+    char *newVarName)
+{
+    CTRI *ctri;
+
+    ctri = fieldType->cTypeRefInfo;
+
+    /* always put in brackets to save future referencing hassles */
+    strcpy (newVarName, "(");
+
+    /* make ref'd field into a ptr by taking it's addr if nec */
+    if (!ctri->isPtr)
+        strcat (newVarName, "&");
+
+    /* start with ref to parent */
+    strcat (newVarName, parentVarName);
+
+    /* ref this field */
+    if ((td->type == parent) || (parent->cTypeRefInfo->isPtr))
+        strcat (newVarName, "->");
+    else
+        strcat (newVarName, ".");
+
+    /* ref choice union field if nec */
+    if (parent->basicType->choiceId == BASICTYPE_CHOICE)
+    {
+        strcat (newVarName, r->choiceUnionFieldName);
+        strcat (newVarName, ".");
+    }
+
+    strcat (newVarName, ctri->cFieldName);
+    strcat (newVarName, ")");
+
+}  /* MakeVarPtrRef */
+
+
+
+
+void
+MakeVarValueRef PARAMS ((r, td, parent, fieldType, parentVarName, newVarName),
+    CRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *fieldType _AND_
+    char *parentVarName _AND_
+    char *newVarName)
+{
+    CTRI *ctri;
+
+    ctri = fieldType->cTypeRefInfo;
+
+    /* always put in brackets to save future referencing hassles */
+    strcpy (newVarName, "(");
+
+    /* make ref'd field into a value by de-referencing if nec */
+    if (ctri->isPtr)
+        strcat (newVarName, "*");
+
+    /* start with ref to parent */
+    strcat (newVarName, parentVarName);
+
+    /* ref this field */
+    if ((td->type == parent) || (parent->cTypeRefInfo->isPtr))
+        strcat (newVarName, "->");
+    else
+        strcat (newVarName, ".");
+
+    /* ref choice union field if nec */
+    if (parent->basicType->choiceId == BASICTYPE_CHOICE)
+    {
+        strcat (newVarName, r->choiceUnionFieldName);
+        strcat (newVarName, ".");
+    }
+
+    strcat (newVarName, ctri->cFieldName);
+    strcat (newVarName, ")");
+
+}  /* MakeVarValueRef */
+
+void
+MakeChoiceIdValueRef PARAMS ((r, td, parent, fieldType, parentVarName, newVarName),
+    CRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *fieldType _AND_
+    char *parentVarName _AND_
+    char *newVarName)
+{
+    CTRI *ctri;
+
+    ctri = fieldType->cTypeRefInfo;
+
+    /* always put in brackets to save future referencing hassles */
+    strcpy (newVarName, "(");
+
+    /* start with ref to parent */
+    strcat (newVarName, parentVarName);
+
+    /* ref this field */
+    if ((td->type == parent) || (parent->cTypeRefInfo->isPtr))
+        strcat (newVarName, "->");
+    else
+        strcat (newVarName, ".");
+
+    strcat (newVarName, parent->cTypeRefInfo->choiceIdEnumFieldName);
+    strcat (newVarName, ")");
+
+}  /* MakeChoiceIdValueRef */
+
+
+void
+PrintElmtAllocCode PARAMS ((src, type, varRefPtrName),
+    FILE *src _AND_
+    Type *type _AND_
+    char *varRefPtrName)
+{
+    CTRI *ctri1;
+    CTRI *ctri2;
+    Type *t;
+
+    t = GetType (type);
+    ctri1 =  type->cTypeRefInfo;
+    ctri2 =  t->cTypeRefInfo;
+    if (ctri1->isPtr)
+    {
+        if (ctri2->cTypeId == C_LIST)
+           fprintf (src, "    %s = AsnListNew (sizeof (char*));\n", varRefPtrName);
+        else
+           fprintf (src, "    %s = (%s*) Asn1Alloc (sizeof (%s));\n", varRefPtrName, ctri1->cTypeName, ctri1->cTypeName);
+         fprintf (src,"    CheckAsn1Alloc (%s, env);\n", varRefPtrName);
+    }
+
+} /* PrintElmtAllocCode */
+
+
+/*
+ * prints code to decode EOCs for the lengths that go with extra tagging
+ * maxLenLevel - the highest used length variable (ie 2 for elmtLen2)
+ * minLenLevel - the lowest valid length variable (ie 0 for elmtLen0)
+ * lenBaseVarName - len var name sans number (ie elmtLen for elmtLen2)
+ * totalLevel - current level for the running total
+ * totalBaseName - total var name sans number
+ *                        (ie totalElmtLen for totalElmtLen1)
+ */
+void
+PrintEocDecoders PARAMS ((f, maxLenLevel, minLenLevel, lenBaseVarName, totalLevel, totalBaseVarName),
+    FILE *f _AND_
+    int maxLenLevel _AND_
+    int minLenLevel _AND_
+    char *lenBaseVarName _AND_
+    int totalLevel _AND_
+    char *totalBaseVarName)
+{
+    int i;
+    for (i = maxLenLevel; i > minLenLevel; i--)
+    {
+        fprintf (f,"    if (%s%d == INDEFINITE_LEN)\n", lenBaseVarName, i);
+        fprintf (f,"        BDecEoc (b, &%s%d, env);\n", totalBaseVarName, totalLevel);
+    }
+} /* PrintEocDeocoders */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.h b/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.h
new file mode 100644
index 00000000..dcc02e2a
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back-ends/c-gen/util.c - C encoder/decode related utility routines
+ *
+ *  MS 91/11/04
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/util.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: util.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:44  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:48:39  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:21  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:45  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+#define FIRST_LEVEL	1	/* must be 1 or greater */
+#define MAX_VAR_REF	512	/* max chars for ref'ing a var eg v->foo->bar.x->v*/
+
+void   MakeVarPtrRef PROTO ((CRules *r, TypeDef *td, Type *parent, Type *fieldType, char *parentVarName, char *newVarName));
+
+void   MakeVarValueRef PROTO ((CRules *r, TypeDef *td, Type *parent, Type *fieldType, char *parentVarName, char *newVarName));
+
+void   MakeChoiceIdValueRef PROTO ((CRules *r, TypeDef *td, Type *parent, Type *fieldType, char *parentVarName, char *newVarName));
+
+void   PrintElmtAllocCode PROTO ((FILE *f, Type *type, char *varPtrRefName));
+
+void   PrintEocDecoders PROTO ((FILE *f, int maxLenLevel, int minLenLevel, char *lenBaseVarName, int totalLevel, char *totalBaseVarName));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/cond.c b/SecuritySNACCRuntime/compiler/back-ends/cond.c
new file mode 100644
index 00000000..72976188
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/cond.c
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/cond.c - generate conditional include for C(++) hdr files
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/cond.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: cond.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:38  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/25 19:13:49  rj
+ * PrintConditionalIncludeOpen() and PrintConditionalIncludeClose() moved from back-ends/c-gen/gen-code.[ch].
+ *
+ */
+
+#include "asn-incl.h"
+#include "cond.h"
+
+
+void
+PrintConditionalIncludeOpen PARAMS ((f, fileName),
+    FILE *f _AND_
+    char *fileName)
+{
+    char hdrFileDefSym[256];
+    int i;
+
+    strcpy (hdrFileDefSym, fileName);
+    for (i = 0; i < strlen (hdrFileDefSym); i++)
+        if (hdrFileDefSym[i] == '-' || hdrFileDefSym[i] == '.')
+            hdrFileDefSym[i] = '_';
+
+    fprintf (f, "#ifndef _%s_\n", hdrFileDefSym);
+    fprintf(f, "#define _%s_\n\n\n", hdrFileDefSym);
+} /* PrintConditionalIncludeOpen */
+
+
+void
+PrintConditionalIncludeClose PARAMS ((f, fileName),
+    FILE *f _AND_
+    char *fileName)
+{
+    fprintf (f, "\n#endif /* conditional include of %s */\n", fileName);
+
+} /* PrintConditionalIncludeClose */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/cond.h b/SecuritySNACCRuntime/compiler/back-ends/cond.h
new file mode 100644
index 00000000..38d7663d
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/cond.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/cond.h - generate conditional include for C(++) hdr files
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/cond.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: cond.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:38  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/25 19:13:50  rj
+ * PrintConditionalIncludeOpen() and PrintConditionalIncludeClose() moved from back-ends/c-gen/gen-code.[ch].
+ *
+ * Revision 1.2  1994/10/08  03:48:09  rj
+ */
+
+
+void PrintConditionalIncludeOpen PROTO ((FILE *f, char *fileName));
+void PrintConditionalIncludeClose PROTO ((FILE *f, char *fileName));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.c b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.c
new file mode 100644
index 00000000..dfdcbe91
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.c
@@ -0,0 +1,294 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/gen_any.c
+ *
+ *     prints Routine to initialize the ANY Hash table.  The
+ *     ANY Hash table maps the OBJECT IDENTIFIERS or INTEGERS
+ *     to the correct decoding routines.
+ *
+ *     Also prints an enum to identify each ANY mapping.
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-any.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:32  rj
+ * first draft
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "define.h"
+#include "str-util.h"
+#include "rules.h"
+#include "gen-vals.h"
+#include "lib-types.h"
+#include "gen-any.h"
+
+static int anyEnumValG = 0;
+
+
+void PrintIDLAnyEnum PROTO ((FILE *idl, Module *m, IDLRules *r));
+
+void PrintIDLAnyHashInitRoutine PROTO ((FILE *idl, ModuleList *mods, Module *m, IDLRules *r));
+
+
+void
+PrintIDLAnyCode PARAMS ((idl, r, mods, m),
+    FILE *idl _AND_
+    IDLRules *r _AND_
+    ModuleList *mods _AND_
+    Module *m)
+{
+
+    if (!m->hasAnys)
+        return;
+
+    PrintIDLAnyEnum (idl, m, r);
+#if 0
+    PrintIDLAnyHashInitRoutine (idl, mods, m, r);
+#endif
+
+}  /* PrintAnyCode */
+
+
+
+void
+PrintIDLAnyEnum PARAMS ((idl, m, r),
+    FILE *idl _AND_
+    Module *m _AND_
+    IDLRules *r)
+{
+    TypeDef *td;
+    AnyRef *ar;
+    AnyRefList *arl;
+    int firstPrinted = TRUE;
+    int i;
+    char *modName;
+
+    modName = Asn1TypeName2CTypeName (m->modId->name);
+
+    fprintf (idl,"typedef enum %sAnyId\n", modName);
+    fprintf (idl,"{\n");
+
+    /* do any lib types */
+    for (i = BASICTYPE_BOOLEAN; i < BASICTYPE_MACRODEF; i++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (i);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                if (!firstPrinted)
+                    fprintf (idl,",\n");
+                fprintf (idl,"    %s = %d", ar->anyIdName, anyEnumValG++);
+                firstPrinted = FALSE;
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                if (!firstPrinted)
+                    fprintf (idl,",\n");
+                fprintf (idl,"    %s = %d", ar->anyIdName, anyEnumValG++);
+                firstPrinted = FALSE;
+            }
+        }
+    }
+
+    if (firstPrinted) /* none have been printed */
+        fprintf (idl,"/* NO INTEGER or OBJECT IDENTIFIER to ANY type relationships were defined (via MACROs or other mechanism) */\n ??? \n");
+
+    fprintf (idl,"\n} %sAnyId;\n\n\n", modName);
+    Free (modName);
+
+}  /* PrintAnyEnum */
+
+
+#if 0
+void
+PrintIDLAnyHashInitRoutine PARAMS ((idl, mods, m, r),
+    FILE *idl _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    IDLRules *r)
+{
+    TypeDef *td;
+    AnyRefList *arl;
+    AnyRef *ar;
+    IDLTDI *idltdi;
+    int i;
+    int j;
+    enum BasicTypeChoiceId typeId;
+    int installedSomeHashes = FALSE;
+
+
+    /* print InitAny class src file */
+    fprintf (src,"// this class will automatically intialize the any hash tbl\n");
+    fprintf (src,"class InitAny\n");
+    fprintf (src,"{\n");
+    fprintf (src,"  public:\n");
+    fprintf (src,"    InitAny();\n");
+    fprintf (src,"};\n\n");
+
+    fprintf (src,"static InitAny anyInitalizer;\n");
+
+    /* print constructor method that build hash tbl to src file*/
+    fprintf (src,"InitAny::InitAny()\n");
+    fprintf (src,"{\n");
+
+    /* first print value for OID's */
+
+    /* do any lib types first */
+    i = 0;
+    for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (j);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                installedSomeHashes = TRUE;
+                if (ar->id->choiceId == OIDORINT_OID)
+                {
+                    fprintf (src,"    %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++);
+                    PrintIDLOidValue (src, r, ar->id->a.oid);
+                    fprintf (src,";\n");
+                }
+                else if (ar->id->choiceId == OIDORINT_INTID)
+                {
+                    fprintf (src,"    %s int%d", r->typeConvTbl[BASICTYPE_INTEGER].className, i++);
+                    PrintIDLIntValue (src, r, ar->id->a.intId);
+                    fprintf (src,";\n");
+                }
+            }
+        }
+    }
+
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            idltdi = td->idlTypeDefInfo;
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                installedSomeHashes = TRUE;
+                if (ar->id->choiceId == OIDORINT_OID)
+                {
+                    fprintf (src,"    %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++);
+                    PrintIDLOidValue (src, r, ar->id->a.oid);
+                    fprintf (src,";\n");
+                }
+                else if (ar->id->choiceId == OIDORINT_INTID)
+                {
+                    fprintf (src,"    %s int%d", r->typeConvTbl[BASICTYPE_INTEGER].className, i++);
+                    PrintIDLIntValue (src, r, ar->id->a.intId);
+                    fprintf (src,";\n");
+                }
+            }
+        }
+    }
+
+
+    /* now print hash init calls */
+    i = 0;
+    for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++)
+    {
+        arl = LIBTYPE_GET_ANY_REFS (j);
+        if (arl != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, arl)
+            {
+                if (ar->id->choiceId == OIDORINT_OID)
+                    fprintf (src,"    AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, ar->anyIdName, r->typeConvTbl[j].className);
+
+                else
+                    fprintf (src,"    AsnAny::InstallAnyByInt (int%d, %s, new %s);\n", i++, ar->anyIdName, r->typeConvTbl[j].className);
+
+            }
+        }
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        if (td->anyRefs != NULL)
+        {
+            FOR_EACH_LIST_ELMT (ar, td->anyRefs)
+            {
+                idltdi = td->idlTypeDefInfo;
+
+                if (ar->id->choiceId == OIDORINT_OID)
+                    fprintf (src,"    AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, ar->anyIdName, idltdi->className);
+
+                else
+                    fprintf (src,"    AsnAny::InstallAnyByInt (int%d, %s, new %s);\n", i++, ar->anyIdName, idltdi->className);
+
+            }
+        }
+    }
+
+    if (!installedSomeHashes)
+    {
+        fprintf (src,"    /* Since no INTEGER/OID to ANY type relations were defined\n");
+        fprintf (src,"     * (usually done via MACROs) you must manually do the code\n");
+        fprintf (src,"     * to fill the hash tbl.\n");
+        fprintf (src,"     * if the ids are INTEGER use the following:\n");
+        fprintf (src,"     * AsnAny::InstallAnyByInt (3, ??_ANY_ID, new <className>);\n");
+        fprintf (src,"     * if the ids are OBJECT IDENTIFIERs use the following:\n");
+        fprintf (src,"     * AsnAny::InstallAnyByOid (OidValue, ??_ANY_ID, new <className>);\n");
+        fprintf (src,"     * put the ??_ANY_IDs in the AnyId enum.\n\n");
+        fprintf (src,"     * For example if you have some thing like\n");
+        fprintf (src,"     * T1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id }\n");
+        fprintf (src,"     * and the id 1 maps to the type BOOLEAN use the following:\n");
+        fprintf (src,"     * AsnAny::InstallAnyByInt (1, SOMEBOOL_ANY_ID, new AsnBool);\n");
+        fprintf (src,"     */\n ???????\n");  /* generate compile error */
+    }
+
+
+    fprintf (src,"}  /* InitAny::InitAny */\n\n\n");
+
+}  /* PrintAnyHashInitRoutine */
+#endif
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.h b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.h
new file mode 100644
index 00000000..f9f11077
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/gen_any.h
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-any.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-any.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:33  rj
+ * first draft
+ *
+ */
+
+void PrintIDLAnyCode PROTO ((FILE *src, IDLRules *r, ModuleList *mods, Module *m));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.c b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.c
new file mode 100644
index 00000000..04deefa0
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.c
@@ -0,0 +1,498 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *   compiler/back_ends/idl_gen/gen_idl_code.c - routines for printing CORBA IDL code from type trees
+ *
+ *   assumes that the type tree has already been run through the
+ *   IDL type generator (idl_gen/types.c).
+ *
+ * Mike Sample
+ * 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * Copyright © 1995 Robert Joop
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-code.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:28  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1997/03/13 09:15:21  wan
+ * Improved dependency generation for stupid makedepends.
+ * Corrected PeekTag to peek into buffer only as far as necessary.
+ * Added installable error handler.
+ * Fixed small glitch in idl-code generator (Markku Savela <msa@msa.tte.vtt.fi>).
+ *
+ * Revision 1.1  1997/01/01 20:25:34  rj
+ * first draft
+ *
+ */
+
+#include "snacc.h"
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "define.h"
+#include "mem.h"
+#include "lib-types.h"
+#include "rules.h"
+#include "types.h"
+#include "cond.h"
+#include "str-util.h"
+#include "snacc-util.h"
+#include "print.h"
+#include "tag-util.h"  /* get GetTags/FreeTags/CountTags/TagByteLen */
+#include "gen-vals.h"
+#include "gen-any.h"
+#include "gen-code.h"
+
+
+static long int		longJmpValG  = -100;
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintComment PARAMS ((idl, m),
+    FILE *idl _AND_
+    Module *m)
+{
+    long int t;
+
+    t = time (0);
+    fprintf (idl, "//   NOTE: this is a machine generated file -- editing not recommended\n");
+    fprintf (idl, "//\n");
+    fprintf (idl, "// %s -- IDL for ASN.1 module %s\n", m->idlFileName, m->modId->name);
+    fprintf (idl, "//\n");
+    fprintf (idl, "//   This file was generated by snacc on %s", ctime (&t));
+    fprintf (idl, "//   UBC snacc written by Mike Sample\n");
+    fprintf (idl, "//   IDL generator written by Robert Joop\n");
+    fprintf (idl, "\n");
+
+} /* PrintComment */
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintIncludes PARAMS ((idl, mods, m),
+    FILE	*idl _AND_
+    ModuleList	*mods _AND_
+    Module	*m)
+{
+    void	*tmp;
+    Module	*currMod;
+
+    fprintf (idl, "#include \"ASN1Types.idl\"\n");
+    fprintf (idl, "#include \"BitString.idl\"\n");
+
+    tmp = (void *)CURR_LIST_NODE (mods); /* remember curr loc */
+    FOR_EACH_LIST_ELMT (currMod, mods)
+        fprintf (idl, "#include \"%s\"\n", currMod->idlFileName);
+    SET_CURR_LIST_NODE (mods, tmp);
+
+} /* PrintIncludes */
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintTypeDecl PARAMS ((f, td),
+    FILE	*f _AND_
+    TypeDef	*td)
+{
+    switch (td->type->basicType->choiceId)
+    {
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_SELECTION:
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_MACRODEF:
+        case BASICTYPE_MACROTYPE:
+            return; /* do nothing */
+
+        case BASICTYPE_ENUMERATED:
+            if (IsNewType (td->type))
+                fprintf (f, "  enum %s;\n", td->idlTypeDefInfo->typeName);
+	    break;
+
+        default:
+            if (IsNewType (td->type))
+                fprintf (f, "  struct %s;\n", td->idlTypeDefInfo->typeName);
+    }
+
+} /* PrintTypeDecl */
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintIDLTypeAndName PARAMS ((idl, mods, m, r, td, parent, t),
+    FILE	*idl _AND_
+    ModuleList	*mods _AND_
+    Module	*m _AND_
+    IDLRules	*r _AND_
+    TypeDef	*td _AND_
+    Type	*parent _AND_
+    Type	*t)
+{
+    if (t->optional)
+	fprintf (idl, "union %sOptional switch (boolean) { case True: %s %s; };\n", t->idlTypeRefInfo->typeName, t->idlTypeRefInfo->typeName, t->idlTypeRefInfo->fieldName);
+    else
+	fprintf (idl, "%s	%s;\n", t->idlTypeRefInfo->typeName, t->idlTypeRefInfo->fieldName);
+
+#if 0
+    if (t->idlTypeRefInfo->isPtr)
+        fprintf (idl, "*");
+#endif
+
+} /* PrintIDLTypeAndName */
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+/*
+ * prints typedef or new class given an ASN.1  type def of a primitive type
+ * or typeref.  Uses inheritance to cover re-tagging and named elmts.
+ */
+static void
+PrintIDLSimpleDef PARAMS ((idl, r, td),
+    FILE *idl _AND_
+    IDLRules *r _AND_
+    TypeDef *td)
+{
+    int	hasNamedElmts;
+    CNamedElmt *n;
+
+    fprintf (idl, "  /* ");
+    SpecialPrintType (idl, td, td->type);
+    fprintf (idl, " */\n");
+
+    if (hasNamedElmts = HasNamedElmts (td->type))
+    {
+	int	tlen = strlen (td->idlTypeDefInfo->typeName) - strlen (r->typeSuffix);
+	switch (GetBuiltinType (td->type))
+	{
+	    case BASICTYPE_INTEGER:
+		fprintf (idl, "  typedef %s %s;\n", td->type->idlTypeRefInfo->typeName, td->idlTypeDefInfo->typeName);
+		FOR_EACH_LIST_ELMT (n, td->type->idlTypeRefInfo->namedElmts)
+		    fprintf (idl, "  const %s %.*s_%s = %d;\n", td->idlTypeDefInfo->typeName, tlen, td->idlTypeDefInfo->typeName, n->name, n->value);
+		break;
+	    case BASICTYPE_ENUMERATED:
+		fprintf (idl, "  enum %s\n", td->idlTypeDefInfo->typeName);
+		fprintf (idl, "  {\n");
+		FOR_EACH_LIST_ELMT (n, td->type->idlTypeRefInfo->namedElmts)
+		{
+		    char comma = (n != (CNamedElmt *)LAST_LIST_ELMT (td->type->idlTypeRefInfo->namedElmts)) ? ',' : ' ';
+		    fprintf (idl, "    %s%c	// (original value = %d)\n", n->name, comma, n->value);
+		}
+		fprintf (idl, "  };\n");
+		break;
+	    case BASICTYPE_BITSTRING:
+		fprintf (idl, "  typedef %s %s;\n", td->type->idlTypeRefInfo->typeName, td->idlTypeDefInfo->typeName);
+		FOR_EACH_LIST_ELMT (n, td->type->idlTypeRefInfo->namedElmts)
+		    fprintf (idl, "  const unsigned long %.*s_%s = %d;\n", tlen, td->idlTypeDefInfo->typeName, n->name, n->value);
+		break;
+	    default:
+		fprintf (idl, "  ???!\n");
+	}
+    }
+    else
+	fprintf (idl, "  typedef %s %s;\n\n", td->type->idlTypeRefInfo->typeName, td->idlTypeDefInfo->typeName);
+
+} /* PrintIDLSimpleDef */
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintIDLChoiceDefCode PARAMS ((idl, mods, m, r, td, parent, choice),
+    FILE	*idl _AND_
+    ModuleList	*mods _AND_
+    Module	*m _AND_
+    IDLRules	*r _AND_
+    TypeDef	*td _AND_
+    Type	*parent _AND_
+    Type	*choice)
+{
+    NamedType	*e;
+
+    /* put class spec in idl file */
+
+    /* write out choiceId enum type */
+
+    fprintf (idl, "  enum %s%s\n", td->idlTypeDefInfo->typeName, r->choiceEnumSuffix);
+    fprintf (idl, "  {\n");
+    FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+    {
+        fprintf (idl, "    %s", e->type->idlTypeRefInfo->choiceIdSymbol);
+        if (e != (NamedType *)LAST_LIST_ELMT (choice->basicType->a.choice))
+            fprintf (idl, ",\n");
+        else
+            fprintf (idl, "\n");
+    }
+    fprintf (idl, "  };\n\n");
+
+    /* write out the choice element anonymous union */
+    fprintf (idl, "  union %s switch (%s%s)\n", td->idlTypeDefInfo->typeName, td->idlTypeDefInfo->typeName, r->choiceEnumSuffix);
+    fprintf (idl, "  {\n");
+    FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+    {
+#if 0
+        fprintf (idl, "    case %s:	%s %s;\n", e->type->idlTypeRefInfo->choiceIdSymbol, e->type->idlTypeRefInfo->typeName, e->type->idlTypeRefInfo->fieldName);
+#else
+        fprintf (idl, "    case %s:	", e->type->idlTypeRefInfo->choiceIdSymbol);
+	PrintIDLTypeAndName (idl, mods, m, r, td, choice, e->type);
+#endif
+    }
+    fprintf (idl, "  };\n\n");
+
+} /* PrintIDLChoiceDefCode */
+
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintIDLSeqDefCode PARAMS ((idl, mods, m, r, td, parent, seq),
+    FILE *idl _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    IDLRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *seq)
+{
+    NamedType *e;
+
+    /* put class spec in idl file */
+
+    fprintf (idl, "  struct %s\n", td->idlTypeDefInfo->typeName);
+    fprintf (idl, "  {\n");
+
+    /* write out the sequence elmts */
+    FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence)
+    {
+        fprintf (idl, "    ");
+	PrintIDLTypeAndName (idl, mods, m, r, td, seq, e->type);
+    }
+
+    /* close struct definition */
+    fprintf (idl, "  };\n\n\n");
+
+} /* PrintIDLSeqDefCode */
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintIDLSetDefCode PARAMS ((idl, mods, m, r, td, parent, set),
+    FILE *idl _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    IDLRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *set)
+{
+    NamedType *e;
+
+    /* put class spec in idl file */
+
+    fprintf (idl, "  struct %s\n", td->idlTypeDefInfo->typeName);
+    fprintf (idl, "  {\n");
+
+    /* write out the set elmts */
+    FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+    {
+        fprintf (idl, "    ");
+        PrintIDLTypeAndName (idl, mods, m, r, td, set, e->type);
+    }
+
+    fprintf (idl, "  };\n\n");
+
+} /* PrintIDLSetDefCode */
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintCxxSetOfDefCode PARAMS ((idl, mods, m, r, td, parent, setOf),
+    FILE *idl _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    IDLRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *setOf)
+{
+    char *lcn; /* list class name */
+    char *ecn; /* (list) elmt class name */
+
+    lcn = td->idlTypeDefInfo->typeName;
+    ecn = setOf->basicType->a.setOf->idlTypeRefInfo->typeName;
+    fprintf (idl, "  typedef sequence<%s> %s;\n", ecn, lcn);
+
+} /* PrintCxxSetOfDefCode */
+
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintCxxAnyDefCode PARAMS ((idl, mods, m, r, td, parent, any),
+    FILE *idl _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    IDLRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *any)
+{
+    fprintf (idl, "  /* ");
+    SpecialPrintType (idl, td, td->type);
+    fprintf (idl, " */\n");
+    fprintf (idl, "  typedef %s %s;\n\n", td->type->idlTypeRefInfo->typeName, td->idlTypeDefInfo->typeName);
+} /* PrintCxxAnyDefCode */
+
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+static void
+PrintIDLTypeDefCode PARAMS ((idl, mods, m, r, td),
+    FILE *idl _AND_
+    ModuleList *mods _AND_
+    Module *m _AND_
+    IDLRules *r _AND_
+    TypeDef *td)
+{
+    switch (td->type->basicType->choiceId)
+    {
+        case BASICTYPE_BOOLEAN:  /* library type */
+        case BASICTYPE_REAL:  /* library type */
+        case BASICTYPE_OCTETSTRING:  /* library type */
+        case BASICTYPE_NULL:  /* library type */
+        case BASICTYPE_OID:  /* library type */
+        case BASICTYPE_INTEGER:  /* library type */
+        case BASICTYPE_BITSTRING:  /* library type */
+        case BASICTYPE_ENUMERATED:  /* library type */
+            PrintIDLSimpleDef (idl, r, td);
+            break;
+
+        case BASICTYPE_SEQUENCEOF:  /* list types */
+        case BASICTYPE_SETOF:
+            PrintCxxSetOfDefCode (idl, mods, m, r, td, NULL, td->type);
+            break;
+
+        case BASICTYPE_IMPORTTYPEREF:  /* type references */
+        case BASICTYPE_LOCALTYPEREF:
+            /*
+             * if this type has been re-tagged then
+             * must create new class instead of using a typedef
+             */
+            PrintIDLSimpleDef (idl, r, td);
+            break;
+
+        case BASICTYPE_ANYDEFINEDBY:  /* ANY types */
+        case BASICTYPE_ANY:
+/*
+            fprintf (stderr, "  ANY types require modification. ");
+            fprintf (stderr, "  The source files will have a \" ANY - Fix Me! \" comment before related code.\n\n");
+*/
+            PrintCxxAnyDefCode (idl, mods, m, r, td, NULL, td->type);
+            break;
+
+        case BASICTYPE_CHOICE:
+            PrintIDLChoiceDefCode (idl, mods, m, r, td, NULL, td->type);
+            break;
+
+        case BASICTYPE_SET:
+            PrintIDLSetDefCode (idl, mods, m, r, td, NULL, td->type);
+            break;
+
+        case BASICTYPE_SEQUENCE:
+            PrintIDLSeqDefCode (idl, mods, m, r, td, NULL, td->type);
+            break;
+
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_SELECTION:
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_MACRODEF:
+        case BASICTYPE_MACROTYPE:
+            /* do nothing */
+            break;
+    }
+} /* PrintIDLTypeDefCode */
+
+/*\[sep]--------------------------------------------------------------------------------------------------------------------------*/
+void
+PrintIDLCode PARAMS ((idl, mods, m, r, longJmpVal),
+    FILE	*idl _AND_
+    ModuleList	*mods _AND_
+    Module	*m _AND_
+    IDLRules	*r _AND_
+    long int	longJmpVal _AND_
+    int		printValues)
+{
+    TypeDef	*td;
+    ValueDef	*vd;
+
+    longJmpValG = longJmpVal;
+
+    PrintComment (idl, m);
+
+    PrintConditionalIncludeOpen (idl, m->idlFileName);
+
+    PrintIncludes (idl, mods, m);
+
+    fprintf (idl, "\n");
+    fprintf (idl, "module %s\n{\n\n", m->idlname);
+
+    fprintf (idl, "  //----------------------------------------------------------------------------\n");
+    fprintf (idl, "  // type declarations:\n\n");
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+        PrintTypeDecl (idl, td);
+    fprintf (idl, "\n");
+
+    if (printValues)
+    {
+	fprintf (idl, "  //----------------------------------------------------------------------------\n");
+        fprintf (idl, "  // value definitions:\n\n");
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+            PrintIDLValueDef (idl, r, vd);
+        fprintf (idl, "\n");
+    }
+
+    fprintf (idl, "  //----------------------------------------------------------------------------\n");
+    fprintf (idl, "  // type definitions:\n\n");
+
+#if 0
+    PrintIDLAnyCode (idl, r, mods, m);
+#endif
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        PrintIDLTypeDefCode (idl, mods, m, r, td);
+	fputc ('\n', idl);
+    }
+
+    fprintf (idl, "}; // end of module %s\n", m->idlname);
+
+    PrintConditionalIncludeClose (idl, m->idlFileName);
+
+} /* PrintIDLCode */
+
+/*\[banner "EOF"]-----------------------------------------------------------------------------------------------------------------*/
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.h b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.h
new file mode 100644
index 00000000..c5c985d1
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/gen_code.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-code.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-code.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:29  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:35  rj
+ * first draft
+ *
+ */
+
+void PrintIDLCode PROTO ((FILE *idl, ModuleList *mods, Module *m, IDLRules *r, long int longJmpVal, int printValues));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.c b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.c
new file mode 100644
index 00000000..c691644a
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.c
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/gen_vals.c - prints ASN.1 values in IDL format
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-vals.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:29  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:36  rj
+ * first draft
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "oid.h"
+#include "mem.h"
+#include "define.h"
+#include "lib-types.h"
+#include "str-util.h"
+#include "snacc-util.h"
+#include "rules.h"
+#include "gen-vals.h"
+
+/* non-exported routines' prototypes */
+
+static void PrintIDLValueDefsName PROTO ((FILE *f, IDLRules *r, ValueDef *v));
+
+
+
+
+void
+PrintIDLValueDef PARAMS ((idl, r, v),
+    FILE	*idl _AND_
+    IDLRules	*r _AND_
+    ValueDef	*v)
+{
+    /* just do oid's, ints and bools for now */
+    if ((v->value->basicValue->choiceId != BASICVALUE_OID) &&
+        (v->value->basicValue->choiceId != BASICVALUE_INTEGER) &&
+        (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN))
+        return;
+
+    /*
+     * put instantiation in idl file
+     */
+    fprintf (idl, "  const ");
+    PrintIDLValuesClass (idl, r, v->value);
+    fprintf (idl, " ");
+    PrintIDLValueDefsName (idl, r, v);
+    fprintf (idl, " = ");
+    PrintIDLValueInstatiation (idl, r, v->value);
+    fprintf (idl, ";\n\n");
+
+}  /* PrintIDLValueDef */
+
+
+static void
+PrintIDLValueDefsName PARAMS ((f, r, v),
+    FILE *f _AND_
+    IDLRules *r _AND_
+    ValueDef *v)
+{
+    char *cName;
+    cName = Asn1ValueName2CValueName (v->definedName);
+    fprintf (f, "%s", cName);
+    Free (cName);
+}
+
+void
+PrintIDLValuesClass PARAMS ((f, r, v),
+    FILE *f _AND_
+    IDLRules *r _AND_
+    Value *v)
+{
+    /* needs work - just do ints bools and oid's for now */
+    switch (v->basicValue->choiceId)
+    {
+        case BASICVALUE_OID:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_OID].typeName);
+            break;
+
+        case BASICVALUE_INTEGER:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_INTEGER].typeName);
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            fprintf (f, "%s", r->typeConvTbl[BASICTYPE_BOOLEAN].typeName);
+            break;
+
+        default:
+           break;
+    }
+}
+
+
+void
+PrintIDLValueInstatiation PARAMS ((f, r, v),
+    FILE *f _AND_
+    IDLRules *r _AND_
+    Value *v)
+{
+    /* needs work - just do oids, ints and bools for now */
+    switch (v->basicValue->choiceId)
+    {
+        case BASICVALUE_OID:
+            PrintIDLOidValue (f, r, v->basicValue->a.oid);
+            break;
+
+        case BASICVALUE_INTEGER:
+            PrintIDLIntValue (f, r, v->basicValue->a.integer);
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            fprintf (f, v->basicValue->a.boolean ? "TRUE" : "FALSE");
+            break;
+
+        default:
+           break;
+    }
+}
+
+
+
+/*
+ * given an AOID, c++ AOID constructors params are produced.
+ * This is used for turning ASN.1 OBJECT ID values
+ * into usable c++ values.
+ *
+ * eg for the oid { 0 1 2 } (in AOID format)
+ *   (0,1,2)
+ * is produced.
+ */
+void
+PrintIDLOidValue PARAMS ((f, r, v),
+    FILE *f _AND_
+    IDLRules *r _AND_
+    AsnOid *v)
+{
+    unsigned short int firstArcNum;
+    unsigned long int arcNum;
+    int i;
+
+    fprintf (f, "(");
+
+    /* un-munge first two arc numbers */
+    for (arcNum = 0, i=0; (i < v->octetLen) && (v->octs[i] & 0x80);i++)
+        arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+
+    arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+    i++;
+    firstArcNum = arcNum/40;
+    if (firstArcNum > 2)
+        firstArcNum = 2;
+
+    fprintf (f, "%u, %u", firstArcNum, arcNum - (firstArcNum * 40));
+
+    for (; i < v->octetLen; )
+    {
+        for (arcNum = 0; (i < v->octetLen) && (v->octs[i] & 0x80);i++)
+            arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+
+        arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+        i++;
+
+        fprintf (f, ", %u", arcNum);
+    }
+    fprintf (f, ")");
+
+} /* PrintIDLOidValue */
+
+
+
+void
+PrintIDLIntValue PARAMS ((f, r, v),
+    FILE *f _AND_
+    IDLRules *r _AND_
+    AsnInt v)
+{
+    fprintf (f, "%d", v);
+
+} /* PrintIDLIntValue */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.h b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.h
new file mode 100644
index 00000000..3e9d48c1
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/gen_vals.h
+ *
+ * MS 92
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/gen-vals.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: gen-vals.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:29  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:37  rj
+ * first draft
+ *
+ */
+
+
+void PrintIDLValueDef PROTO ((FILE *src, IDLRules *r, ValueDef *v));
+
+void PrintIDLValueExtern PROTO ((FILE *hdr, IDLRules *r, ValueDef *v));
+
+void PrintIDLValuesClass PROTO ((FILE *f, IDLRules *r, Value *v));
+
+void PrintIDLValueInstatiation PROTO ((FILE *f, IDLRules *r, Value *v));
+
+void PrintIDLOidValue PROTO ((FILE *f, IDLRules *r, AsnOid *oid));
+
+void PrintIDLIntValue PROTO ((FILE *f, IDLRules *r, AsnInt oid));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.c b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.c
new file mode 100644
index 00000000..8d7b149f
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.c
@@ -0,0 +1,353 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/rules.c - initialized c rule structure
+ *           inits a table that contains info about
+ *           converting each ASN.1 type to an IDL type
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: rules.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:29  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:38  rj
+ * first draft
+ *
+ * Revision 1.3  1994/10/08  03:47:49  rj
+ */
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "rules.h"
+
+
+IDLRules idlRulesG =
+{
+    4,
+
+    "",
+    "_T",
+
+    "Choice",
+    "a",
+    "ChoiceUnion",
+    FALSE,
+    {
+        {
+            BASICTYPE_UNKNOWN,
+            "???",
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "unknown"
+        },
+        {
+            BASICTYPE_BOOLEAN,
+            "BOOLEAN",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bool"
+        },
+        {
+            BASICTYPE_INTEGER,
+            "INTEGER",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "integer"
+        },
+        {
+            BASICTYPE_BITSTRING,
+            "BitString",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bits"
+        },
+        {
+            BASICTYPE_OCTETSTRING,
+            "OctetString",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "octs"
+        },
+        {
+            BASICTYPE_NULL,
+            "NULL",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "null"
+        },
+        {
+            BASICTYPE_OID,
+            "ObjectIdentifier",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "oid"
+        },
+        {
+            BASICTYPE_REAL,
+            "REAL",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "real"
+        },
+        {
+            BASICTYPE_ENUMERATED,
+            "???",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "enumeration"
+        },
+        {
+            BASICTYPE_SEQUENCE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            TRUE,
+            "NOT_NULL",
+            "seq"
+        },
+        {
+            BASICTYPE_SEQUENCEOF,
+            "AsnList",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "seqOf"
+        },
+        {
+            BASICTYPE_SET,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            FALSE,
+            "NOT_NULL",
+            "set"
+        },
+        {
+            BASICTYPE_SETOF,
+            "AsnList",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "setOf"
+        },
+        {
+            BASICTYPE_CHOICE,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            TRUE,
+            FALSE,
+            "NOT_NULL",
+            "choice"
+        },
+        {
+            BASICTYPE_SELECTION,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "foo"
+        },
+        {
+            BASICTYPE_COMPONENTSOF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bar"
+        },
+        {
+            BASICTYPE_ANY,
+            "any",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "any"
+        },
+        {
+            BASICTYPE_ANYDEFINEDBY,
+            "any",
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "anyDefBy"
+        },
+        {
+            BASICTYPE_LOCALTYPEREF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "foo"
+        },
+        {
+            BASICTYPE_IMPORTTYPEREF,
+            NULL,
+            FALSE,
+            TRUE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "bar"
+        },
+        {
+            BASICTYPE_MACROTYPE,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "foo"
+        },
+        {
+            BASICTYPE_MACRODEF,
+            NULL,
+            FALSE,
+            FALSE,
+            FALSE,
+            TRUE,
+            TRUE,
+            FALSE,
+            TRUE,
+            "NOT_NULL",
+            "foo"
+        }
+    }
+};
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.h b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.h
new file mode 100644
index 00000000..c9ca285d
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/rules.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/rules.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: rules.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:29  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:39  rj
+ * first draft
+ *
+ * Revision 1.2  1994/10/08  03:47:50  rj
+ */
+
+/* see ../../core/asn1module.h for IDLTDI (C++ type def info) */
+
+typedef struct IDLRules
+{
+  int		maxDigitsToAppend;
+
+  char		*typePrefix,
+		*typeSuffix;
+
+  char		*choiceEnumSuffix;
+  char		*choiceUnionFieldName;	/* what the name of the choice's union is */
+  char		*choiceUnionName;	/* name (tag) for choice union def name */
+
+  int		capitalizeNamedElmts;
+
+  IDLTDI	typeConvTbl[BASICTYPE_MACRODEF + 1];
+} IDLRules;
+
+extern IDLRules idlRulesG;
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.c b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.c
new file mode 100644
index 00000000..2ade80d5
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.c
@@ -0,0 +1,675 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/types.c  - fills in IDL type information
+ *
+ * MS 91/92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: types.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:29  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:45  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:40  rj
+ * first draft
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "define.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "snacc-util.h"
+#include "str-util.h"
+#include "rules.h"
+#include "c++-gen/kwd.h"
+#include "types.h"
+
+extern Module		*usefulTypeModG;
+
+static DefinedObj	*definedNamesG;
+
+/* unexported prototypes */
+
+void FillIDLTypeDefInfo PROTO ((IDLRules *r, Module *m, TypeDef *td));
+
+static void FillIDLFieldNames PROTO ((IDLRules *r, NamedTypeList *firstSibling));
+
+static void FillIDLTypeRefInfo PROTO ((IDLRules *r, Module *m, TypeDef *td, Type *parent, Type *t));
+
+static void FillIDLStructElmts PROTO ((IDLRules *r, Module *m, TypeDef *td, Type *parent, NamedTypeList *t));
+
+static void FillIDLChoiceElmts PROTO ((IDLRules *r, Module *m, TypeDef *td, Type *parent, NamedTypeList *first));
+
+static int IsIDLPtr PROTO ((IDLRules *r, TypeDef *td, Type *parent, Type *t));
+
+void FillIDLTDIDefaults PROTO ((IDLRules *r, IDLTDI *ctdi, TypeDef *td));
+
+
+/*
+ *  allocates and fills all the idlTypeInfos
+ *  in the type trees for every module in the list
+ */
+void
+FillIDLTypeInfo PARAMS ((r, modList),
+    IDLRules *r _AND_
+    ModuleList *modList)
+{
+    TypeDef *td;
+    Module *m;
+
+    /*
+     * go through each module's type defs and fill
+     * in the C type and enc/dec routines etc
+     */
+    definedNamesG = NULL;
+
+    /* do useful types first */
+    if (usefulTypeModG != NULL)
+    {
+        FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
+            FillIDLTypeDefInfo (r, usefulTypeModG, td);
+    }
+
+    FOR_EACH_LIST_ELMT (m, modList)
+    {
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+            FillIDLTypeDefInfo (r, m, td);
+    }
+
+    /*
+     * now that type def info is filled in
+     * set up set/seq/list/choice elements that ref
+     * those definitions
+     */
+
+    /* do useful types first */
+    if (usefulTypeModG != NULL)
+    {
+        FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
+            FillIDLTypeRefInfo (r, usefulTypeModG, td, NULL, td->type);
+    }
+
+    FOR_EACH_LIST_ELMT (m, modList)
+    {
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+            FillIDLTypeRefInfo (r, m, td, NULL, td->type);
+    }
+
+    /*
+     * modules compiled together (ie one call to snacc with
+     * multiple args) likely to be C compiled together so
+     * need a unique routines/types/defines/enum values
+     * since assuming they share same name space.
+     *  All Typedefs, union, struct & enum Tags, and defined values
+     * (enum consts), #define names
+     *  are assumed to share the same name space
+     */
+
+    /* done with checking for name conflicts */
+    FreeDefinedObjs (&definedNamesG);
+
+}  /* FillIDLTypeInfo */
+
+
+/*
+ *  allocates and fills structure holding C type definition information
+ *  fo the given ASN.1 type definition.  Does not fill CTRI for contained
+ *  types etc.
+ */
+void
+FillIDLTypeDefInfo PARAMS ((r, m, td),
+    IDLRules *r _AND_
+    Module *m _AND_
+    TypeDef *td)
+{
+    int digit;
+    int len;
+    char *tmpName;
+    IDLTDI *idltdi;
+
+    /*
+     * if IDLTDI is present this type def has already been 'filled'
+     */
+    if (td->idlTypeDefInfo != NULL)
+        return;
+
+
+    idltdi = MT (IDLTDI);
+    td->idlTypeDefInfo = idltdi;
+
+    /* get default type def attributes from table for type on rhs of ::= */
+
+    FillIDLTDIDefaults (r, idltdi, td);
+
+
+    /*
+     * if defined by a ref to another type definition fill in that type
+     * def's IDLTDI so can inherit (actully completly replace default
+     * attributes) from it
+     */
+    if ((td->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+        (td->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+    {
+        /*
+         * Fill in IDLTDI for defining type if nec.
+         * this works for importTypeRef as well since both a.localTypeRef
+         * and a.importTypeRef are of type TypeRef
+         */
+        FillIDLTypeDefInfo (r, td->type->basicType->a.localTypeRef->module, td->type->basicType->a.localTypeRef->link);
+
+        tmpName = idltdi->typeName; /* save typeName */
+        /* copy all type def info and restore name related stuff - hack*/
+        *idltdi = *td->type->basicType->a.localTypeRef->link->idlTypeDefInfo;
+        idltdi->typeName = tmpName; /* restore typeName */
+    }
+
+
+    /*
+     * check for any "--snacc" attributes that overide the current
+     * idltdi fields
+     * UNDEFINED FOR C++
+    ParseTypeDefAttribs (idltdi, td->attrList);
+     */
+
+}  /* FillIDLTypeDefInfo */
+
+
+static void
+FillIDLTypeRefInfo PARAMS ((r, m, td, parent, t),
+    IDLRules	*r _AND_
+    Module	*m _AND_
+    TypeDef	*td _AND_
+    Type	*parent _AND_
+    Type	*t)
+{
+    IDLTRI	*idltri;
+    IDLTDI	*tmpidltdi;
+    ValueDef	*namedElmt;
+    CNamedElmt	*cne;
+    CNamedElmt	**cneHndl;
+    char	*elmtName;
+    char	*listName;
+    char	*choiceName;
+    char	*unionName;
+    Type	*tmpT;
+    int		len, digit;
+    enum BasicTypeChoiceId
+		basicTypeId;
+
+    /*
+     * you must check for cycles yourself before calling this
+     */
+    if (t->idlTypeRefInfo == NULL)
+    {
+        idltri = MT (IDLTRI);
+        t->idlTypeRefInfo = idltri;
+    }
+    else
+        idltri = t->idlTypeRefInfo;
+
+    basicTypeId = t->basicType->choiceId;
+
+    tmpidltdi = &r->typeConvTbl[basicTypeId];
+
+    /* get base type def info from the conversion table in the rules */
+    idltri->isEnc = tmpidltdi->isEnc;
+    idltri->typeName = tmpidltdi->typeName;
+    idltri->optTestRoutineName = tmpidltdi->optTestRoutineName;
+
+
+    /*
+     * convert named elmts to IDL names.
+     * check for name conflict with other defined Types/Names/Values
+     */
+    if ((basicTypeId == BASICTYPE_INTEGER || basicTypeId == BASICTYPE_ENUMERATED || basicTypeId == BASICTYPE_BITSTRING) && !(LIST_EMPTY (t->basicType->a.integer)))
+    {
+        idltri->namedElmts = AsnListNew (sizeof (void *));
+        FOR_EACH_LIST_ELMT (namedElmt, t->basicType->a.integer)
+        {
+            cneHndl = (CNamedElmt **)AsnListAppend (idltri->namedElmts);
+            cne = *cneHndl = MT (CNamedElmt);
+            elmtName = Asn1ValueName2CValueName (namedElmt->definedName);
+#if 0
+	    if (basicTypeId == BASICTYPE_BITSTRING)
+#endif
+	    {
+		len = strlen (elmtName);
+		cne->name = Malloc (len + 1 + r->maxDigitsToAppend);
+		strcpy (cne->name, elmtName);
+	    }
+#if 0
+	    else
+	    {
+		len = strlen (idltri->typeName) + 7 + strlen (elmtName);
+		cne->name = Malloc (len + 1 + r->maxDigitsToAppend);
+		strcpy (cne->name, idltri->typeName);
+		strcat (cne->name, "Choice_");
+		strcat (cne->name, elmtName);
+	    }
+#endif
+            Free (elmtName); /* not very efficient */
+
+            if (namedElmt->value->basicValue->choiceId == BASICVALUE_INTEGER)
+                cne->value = namedElmt->value->basicValue->a.integer;
+            else
+            {
+                fprintf (stderr, "Warning: unlinked defined value. Using -9999999\n");
+                cne->value = -9999999;
+            }
+
+            if (r->capitalizeNamedElmts)
+                Str2UCase (cne->name, len);
+
+            /*
+             * append digits if enum value name is a keyword
+             */
+            MakeCxxStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1);
+            DefineObj (&definedNamesG, cne->name);
+        }
+    }
+
+    /* fill in rest of type info depending on the type */
+    switch (basicTypeId)
+    {
+        case BASICTYPE_BOOLEAN:  /* library types */
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_BITSTRING:
+        case BASICTYPE_OCTETSTRING:
+        case BASICTYPE_NULL:
+        case BASICTYPE_OID:
+        case BASICTYPE_REAL:
+        case BASICTYPE_ENUMERATED:
+            /* don't need to do anything else */
+            break;
+
+
+        case BASICTYPE_SEQUENCEOF:  /* list types */
+        case BASICTYPE_SETOF:
+            /* fill in component type */
+            FillIDLTypeRefInfo (r, m, td, t, t->basicType->a.setOf);
+            break;
+
+        case BASICTYPE_IMPORTTYPEREF:  /* type references */
+        case BASICTYPE_LOCALTYPEREF:
+            /*
+             * grab class name from link (link is the def of the
+             * the ref'd type)
+             */
+            if (t->basicType->a.localTypeRef->link != NULL)
+            {
+                /* inherit attributes from referenced type */
+                tmpidltdi=  t->basicType->a.localTypeRef->link->idlTypeDefInfo;
+                idltri->typeName = tmpidltdi->typeName;
+                idltri->isEnc = tmpidltdi->isEnc;
+                idltri->optTestRoutineName = tmpidltdi->optTestRoutineName;
+            }
+
+            break;
+
+        case BASICTYPE_ANYDEFINEDBY:  /* ANY types */
+            break;  /* these are handled now */
+
+        case BASICTYPE_ANY:
+#if 0
+            PrintErrLoc (m->asn1SrcFileName, t->lineNo);
+            fprintf (stderr, "Warning - generated code for the \"ANY\" type in type \"%s\" will need modification by YOU.", td->definedName);
+            fprintf (stderr, "  The source files will have a \"/* ANY - Fix Me! */\" comment before related code.\n\n");
+#endif
+
+            break;
+
+        case BASICTYPE_CHOICE:
+           /*
+            * must fill field names BEFORE filling choice elmts
+            * (allows better naming for choice ids)
+            */
+            FillIDLFieldNames (r, t->basicType->a.choice);
+            FillIDLChoiceElmts (r, m, td, t, t->basicType->a.choice);
+            break;
+
+        case BASICTYPE_SET:
+        case BASICTYPE_SEQUENCE:
+            FillIDLStructElmts (r, m, td, t, t->basicType->a.set);
+            FillIDLFieldNames (r, t->basicType->a.set);
+            break;
+
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_SELECTION:
+            fprintf (stderr, "Compiler error - COMPONENTS OF or SELECTION type slipped through normalizing phase.\n");
+            break;
+
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_MACRODEF:
+        case BASICTYPE_MACROTYPE:
+            /* do nothing */
+            break;
+
+    }
+
+    /*
+     * figure out whether this is a ptr based on the enclosing
+     * type (if any) and optionality/default
+     */
+    idltri->isPtr = IsIDLPtr (r, td, parent, t);
+
+    /* let user overide any defaults with the --snacc attributes */
+    /* undefined for C++ ParseTypeRefAttribs (ctri, t->attrList); */
+
+
+}  /* FillIDLTypeRefInfo */
+
+
+
+static void
+FillIDLStructElmts PARAMS ((r, m, td, parent, elmts),
+    IDLRules *r _AND_
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts)
+{
+    NamedType *et;
+
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        FillIDLTypeRefInfo (r, m, td, parent, et->type);
+    }
+
+}  /* FillIDLStructElmts */
+
+
+
+/*
+ *  Figures out non-conflicting enum names for the
+ *  choice id's
+ */
+static void
+FillIDLChoiceElmts PARAMS ((r, m, td, parent, elmts),
+    IDLRules	*r _AND_
+    Module	*m _AND_
+    TypeDef	*td _AND_
+    Type	*parent _AND_
+    NamedTypeList *elmts)
+{
+    NamedType	*et;
+    int		idCount = 0;
+    IDLTRI	*idltri;
+    int		len;
+
+    /*
+     * fill in type info for elmt types first
+     */
+    FOR_EACH_LIST_ELMT (et, elmts)
+        FillIDLTypeRefInfo (r, m, td, parent, et->type);
+
+    /*
+     * set choiceId Symbol & value
+     * eg
+     *  Car ::= CHOICE {          enum CarChoice {
+     *     chev ChevCar,              carChoice_chev,
+     *     ford FordCar,              carChoice_ford,
+     *     toyota ToyotaCar           carChoice_toyota
+     *  }                         };
+     *                            union Car switch (CarChoice) {
+     *                                ChevCar *chev;
+     *                                FordCar *ford;
+     *                                ToyotaCar *toyota; };
+     *                            };
+     * NOTE that the union is anonymous
+     */
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        idltri =  et->type->idlTypeRefInfo;
+
+        if (idltri == NULL)
+            continue; /* wierd type */
+
+        idltri->choiceIdValue = idCount++;
+
+        len = strlen (td->idlTypeDefInfo->typeName) + strlen (idltri->fieldName);
+        idltri->choiceIdSymbol = Malloc (len + 6 + 1);
+        strcpy (idltri->choiceIdSymbol, td->idlTypeDefInfo->typeName);
+	strcat (idltri->choiceIdSymbol, "Choice_");
+        strcat (idltri->choiceIdSymbol, idltri->fieldName);
+
+        if (r->capitalizeNamedElmts)
+            Str2UCase (idltri->choiceIdSymbol, len);
+
+	Str2LCase (idltri->choiceIdSymbol, 1);
+    }
+
+}  /* FillIDLChoiceElmts */
+
+
+/*
+ * takes a list of "sibling" (eg same level in a structure)
+ * ElmtTypes and fills sets up the c field names in
+ * the IDLTRI struct
+ */
+static void
+FillIDLFieldNames PARAMS ((r, elmts),
+    IDLRules *r _AND_
+    NamedTypeList *elmts)
+{
+    NamedType  *et;
+    IDLTRI *idltri;
+    DefinedObj *fieldNames;
+    int        len, num, digit, i, tmpLen;
+    char      *tmpName;
+    char      *asn1FieldName;
+    char      *cFieldName;
+
+    /*
+     * Initialize fieldname data
+     * allocate (if nec) and fill in CTRI fieldname if poss
+     * from asn1 field name.  leave blank otherwise
+     */
+    fieldNames = NewObjList();
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        idltri =  et->type->idlTypeRefInfo;
+        if (idltri == NULL)
+        {
+            idltri = MT (IDLTRI);
+            et->type->idlTypeRefInfo = idltri;
+        }
+        if (et->fieldName != NULL)
+        {
+            /*
+             * can assume that the field names are
+             * distinct because they have passed the
+             * error checking step.
+             * However, still call MakeCxxStrUnique
+             * to change any field names that
+             * conflict with C++ keywords
+             */
+            asn1FieldName = et->fieldName;
+            tmpName = Asn1FieldName2CFieldName (asn1FieldName);
+            idltri->fieldName = Malloc (strlen (tmpName) + 1 + r->maxDigitsToAppend);
+            strcpy (idltri->fieldName, tmpName);
+            Free (tmpName);
+
+/*   old    idltri->fieldName = Asn1FieldName2CFieldName (asn1FieldName); */
+
+            MakeCxxStrUnique (fieldNames, idltri->fieldName, r->maxDigitsToAppend, 1);
+            DefineObj (&fieldNames, idltri->fieldName);
+        }
+    }
+
+
+    FOR_EACH_LIST_ELMT (et, elmts)
+    {
+        idltri =  et->type->idlTypeRefInfo;
+
+        /*
+         * generate field names for those without them
+         */
+        if (idltri->fieldName == NULL)
+        {
+            if ((et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+                 (et->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+            {
+                /*
+                 * take ref'd type name as field name
+                 * convert first let to lower case
+                 */
+                tmpName = et->type->basicType->a.localTypeRef->link->idlTypeDefInfo->typeName;
+                tmpName =  Asn1TypeName2CTypeName (tmpName);
+                cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
+                strcpy (cFieldName, tmpName);
+                Free (tmpName);
+                if (isupper (cFieldName[0]))
+                    cFieldName[0] = tolower (cFieldName[0]);
+            }
+            else
+            {
+                /*
+                 * get default field name for this type
+                 */
+                tmpName = r->typeConvTbl[et->type->basicType->choiceId].defaultFieldName;
+                cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
+                strcpy (cFieldName, tmpName);
+
+                if (isupper (cFieldName[0]))
+                    cFieldName[0] = tolower (cFieldName[0]);
+            }
+
+
+            len = strlen (cFieldName);
+
+            /*
+             * try to use just the type name (with lower case first char).
+             * if that is already used in this type or a C++ keyword,
+             * append ascii digits to field name until unique
+             * in this type
+             */
+            MakeCxxStrUnique (fieldNames, cFieldName, r->maxDigitsToAppend, 1);
+            DefineObj (&fieldNames, cFieldName);
+            idltri->fieldName = cFieldName;
+        }
+    }
+    FreeDefinedObjs (&fieldNames);
+}  /* FillIDLFieldNames */
+
+
+
+/*
+ * returns true if this c type for this type should be
+ * be ref'd as a ptr
+ */
+static int
+IsIDLPtr PARAMS ((r, td, parent, t),
+    IDLRules *r _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    Type *t)
+{
+    IDLTDI *idltdi;
+    int retVal = FALSE;
+
+    /*
+     * inherit ptr attriubutes from ref'd type if any
+     * otherwise grab lib c type def from the IDLRules
+     */
+    if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+        (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+    {
+        idltdi = t->basicType->a.localTypeRef->link->idlTypeDefInfo;
+    }
+    else
+        idltdi = &r->typeConvTbl[GetBuiltinType (t)];
+
+    /* no parent means t is the root of a typedef */
+    if ((parent == NULL) && (idltdi->isPtrForTypeDef))
+        retVal = TRUE;
+
+    else if ((parent != NULL) &&
+             ((parent->basicType->choiceId == BASICTYPE_SET) ||
+             (parent->basicType->choiceId == BASICTYPE_SEQUENCE)) &&
+             (idltdi->isPtrInSetAndSeq))
+        retVal = TRUE;
+
+    else if ((parent != NULL) &&
+             ((parent->basicType->choiceId == BASICTYPE_SETOF) ||
+             (parent->basicType->choiceId == BASICTYPE_SEQUENCEOF)) &&
+             (idltdi->isPtrInList))
+        retVal = TRUE;
+
+    else if ((parent != NULL) &&
+             (parent->basicType->choiceId == BASICTYPE_CHOICE) &&
+             (idltdi->isPtrInChoice))
+        retVal = TRUE;
+
+    else if (((t->optional) || (t->defaultVal != NULL)) && (idltdi->isPtrForOpt))
+        retVal = TRUE;
+
+    return retVal;
+}  /* IsIDLPtr */
+
+
+
+/* fill given idltdi with defaults from table for given typedef */
+void
+FillIDLTDIDefaults PARAMS ((r, idltdi, td),
+    IDLRules *r _AND_
+    IDLTDI *idltdi _AND_
+    TypeDef *td)
+{
+    IDLTDI *tblidltdi;
+    int typeIndex;
+    char *tmpName;
+
+    typeIndex = GetBuiltinType (td->type);
+
+    if (typeIndex < 0)
+        return;
+
+    tblidltdi = &r->typeConvTbl[typeIndex];
+
+    memcpy (idltdi, tblidltdi, sizeof (IDLTDI));
+
+    /* make sure class name is unique wrt to previously defined classes */
+    tmpName = Asn1TypeName2CTypeName (td->definedName);
+    idltdi->typeName = Malloc (strlen (tmpName) + 2 + r->maxDigitsToAppend +1);
+    strcpy (idltdi->typeName, tmpName);
+    if (tblidltdi->asn1TypeId != BASICTYPE_CHOICE)
+	strcat (idltdi->typeName, "_T");
+    Free (tmpName);
+
+    MakeCxxStrUnique (definedNamesG, idltdi->typeName, r->maxDigitsToAppend, 1);
+    DefineObj (&definedNamesG, idltdi->typeName);
+
+} /* FillIDLTDIDefaults */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.h b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.h
new file mode 100644
index 00000000..8576a660
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/idl_gen/types.h  - fills in c++ type information
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *           and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: types.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:29  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:46  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/01/01 20:25:42  rj
+ * first draft
+ *
+ */
+
+
+void FillIDLTypeInfo PROTO ((IDLRules *r, ModuleList *m));
diff --git a/SecuritySNACCRuntime/compiler/back-ends/str-util.c b/SecuritySNACCRuntime/compiler/back-ends/str-util.c
new file mode 100644
index 00000000..55b2c2b8
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/str-util.c
@@ -0,0 +1,606 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c_gen/str_util.c  - bunch of ASN.1/C string utilities
+ *
+ *
+ * Mike Sample
+ * 91/08/12
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/str-util.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: str-util.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.3  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.2  2000/05/10 21:36:43  rmurphy
+ * changing the suffix for c++ output files to .cpp - requires -DMACOS on the compilation line
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:39  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 18:13:31  rj
+ * include string(s).h
+ *
+ * by default, snacc now derives output file names from the .asn1 input file name instead of the module name.
+ * the global keepbaseG variable switches between the two behaviours.
+ *
+ * additional filename generator for idl backend.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:48:17  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:25:31  rj
+ * snacc_config.h removed; more portable .h file inclusion.
+ *
+ * Revision 1.1  1994/08/28  09:48:37  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+
+#include <ctype.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>  /* for pathconf (..) */
+#endif
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdio.h>
+
+#include "asn1module.h"
+#include "mem.h"
+#include "define.h"
+#include "c-gen/rules.h"
+#include "c-gen/type-info.h"
+#include "c-gen/kwd.h"
+#include "c++-gen/kwd.h"
+#include "str-util.h"
+
+
+#define DIGIT_TO_ASCII( d)	(((d) % 10) + '0')
+
+int	keepbaseG = TRUE;
+
+/*
+ * allocates new and returns a copy of the given
+ * string with '-'s (dashes) replaced by  '_'s (underscores)
+ */
+char *
+Asn1TypeName2CTypeName PARAMS ((aName),
+    char *aName)
+{
+    char *retVal;
+    if (aName == NULL)
+        return NULL;
+
+    retVal = Malloc (strlen (aName) + 1);
+    strcpy (retVal, aName);
+    Dash2Underscore (retVal, strlen (retVal));
+
+    return retVal;
+}  /* Asn1TypeName2CTypeName */
+
+
+/*
+ * allocates new str and returns a copy of the given
+ * string with '-'s (dashes) replaced by  '_'s (underscores)
+ */
+char *
+Asn1FieldName2CFieldName PARAMS ((aName),
+    char *aName)
+{
+    char *retVal;
+    if (aName == NULL)
+        return NULL;
+
+    retVal = Malloc (strlen (aName) + 1);
+    strcpy (retVal, aName);
+    Dash2Underscore (retVal, strlen (retVal));
+
+    return retVal;
+}  /* Asn1FieldName2CFieldName */
+
+
+/*
+ * allocates new str and returns a copy of the given
+ * string with '-'s (dashes) replaced by  '_'s (underscores)
+ */
+char *
+Asn1ValueName2CValueName PARAMS ((aName),
+    char *aName)
+{
+    char *retVal;
+    if (aName == NULL)
+        return NULL;
+
+    retVal = Malloc (strlen (aName) + 1);
+    strcpy (retVal, aName);
+    Dash2Underscore (retVal, strlen (retVal));
+
+    return retVal;
+}  /* Asn1FieldName2CFieldName */
+
+
+/*
+ * allocates and returns a string with all of
+ * the caps from the given string
+ */
+char *
+GetCaps PARAMS ((str),
+    char *str)
+{
+    int i, j;
+    char *retVal;
+
+    if (str == NULL)
+        return NULL;
+
+    retVal = Malloc (strlen (str) + 1);
+
+    for (j = 0, i = 0; i < strlen (str); i++)
+    {
+        if (isupper (str[i]))
+            retVal[j++] = str[i];
+    }
+
+    retVal[j] = '\0';  /* null terminate */
+
+    return retVal;
+
+}  /* GetCaps */
+
+
+/*
+ * allocates and returns a string with all of
+ * the caps and digits from the given string
+ */
+char *
+GetCapsAndDigits PARAMS ((str),
+    char *str)
+{
+    int i, j;
+    char *retVal;
+
+    if (str == NULL)
+        return NULL;
+
+    retVal = Malloc (strlen (str) + 1);
+
+    for (j = 0, i = 0; i < strlen (str); i++)
+    {
+        if ((isupper (str[i])) ||  (isdigit (str[i])))
+            retVal[j++] = str[i];
+    }
+
+    retVal[j] = '\0';  /* null terminate */
+
+    return retVal;
+
+}  /* GetCapsAndDigits */
+
+
+/*
+ * replaces lowercase chars in given str
+ * with upper case version
+ * NOTE: modifies given str
+ */
+void
+Str2UCase PARAMS ((str, len),
+    char *str _AND_
+    int len)
+{
+    int i;
+    for (i=0; i < len; i++)
+    {
+        if (islower (str[i]))
+            str[i] = toupper (str[i]);
+    }
+} /* Str2UCase */
+
+
+/*
+ * replaces uppercase chars in given str
+ * with lower case version
+ * NOTE: modifies given str
+ */
+void
+Str2LCase PARAMS ((str, len),
+    char *str _AND_
+    int len)
+{
+    int i;
+    for (i=0; i < len; i++)
+    {
+        if (isupper (str[i]))
+            str[i] = tolower (str[i]);
+    }
+} /* Str2LCase */
+
+
+/*
+ * replace dash chars in given str
+ * with underscores
+ * NOTE: modifies given str
+ */
+void
+Dash2Underscore PARAMS ((str, len),
+    char *str _AND_
+    int len)
+{
+    int i;
+    for (i=0; i < len; i++)
+    {
+        if (str[i] == '-')
+            str[i] = '_';
+    }
+} /* Dash2Underscore */
+
+
+/*
+ * tacks on the ascii version of the given digit
+ * at the end of the given str.
+ * NOTE: make sure the str you give has enough space
+ * for the digits
+ */
+void
+AppendDigit PARAMS ((str, digit),
+    char *str _AND_
+    int digit)
+{
+    int high = 1000000000;
+    int currDigit;
+    int value;
+    char digitStr[20]; /* arbitrary length > max */
+
+    if (digit < 0)
+        digit *= -1;
+
+    currDigit = 0;
+    while (high > 0)
+    {
+        value = digit / high;
+        if (value != 0)
+            digitStr[currDigit++]= DIGIT_TO_ASCII (value);
+
+        digit = digit % high;
+        high  = high/10;
+    }
+
+    if (currDigit == 0)
+        strcat (str, "0");
+    else
+    {
+        digitStr[currDigit] = '\0';  /* null terminate */
+        strcat (str, digitStr);
+    }
+} /* AppendDigit */
+
+
+
+
+/*
+ * given a defined object list containing null termintated strs,
+ * a str to be made unique wrt to the list by adding digits to the
+ * end, the max number of digits to add and the digit to start
+ * at, str is modified to be unique.  It is not added to the
+ * defined object list.  The given str must have enough spare,
+ * allocated chars after it's null terminator to hold maxDigits
+ * more characters.
+ * Only appends digits if the string is not unique or is a C keyword.
+ *
+ * Eg  MakeCStrUnique ({ "Foo", "Bar" }, "Foo\0   ", 3, 1)
+ *         modifies the the Str "Foo" to "Foo1"
+ */
+void
+MakeCStrUnique PARAMS ((nameList, str, maxDigits, startingDigit),
+    DefinedObj *nameList _AND_
+    char *str _AND_
+    int maxDigits _AND_
+    int startingDigit)
+{
+    int digit, len, maxDigitVal;
+
+    if (ObjIsDefined (nameList, str, StrObjCmp) || IsCKeyWord (str))
+    {
+        for (maxDigitVal = 1; maxDigits > 0; maxDigits--)
+            maxDigitVal *= 10;
+
+        len = strlen (str);
+        digit = startingDigit;
+        do
+        {
+            str[len] = '\0';
+            AppendDigit (str, digit++);
+        } while (ObjIsDefined (nameList, str, StrObjCmp) &&  (digit < maxDigitVal));
+    }
+}  /* MakeCStrUnique */
+
+
+/*
+ * same as MakeCStrUnique except checks against C++ keywords
+ */
+void
+MakeCxxStrUnique PARAMS ((nameList, str, maxDigits, startingDigit),
+    DefinedObj *nameList _AND_
+    char *str _AND_
+    int maxDigits _AND_
+    int startingDigit)
+{
+    int digit, len, maxDigitVal;
+
+    if (ObjIsDefined (nameList, str, StrObjCmp) || IsCxxKeyWord (str))
+    {
+        for (maxDigitVal = 1; maxDigits > 0; maxDigits--)
+            maxDigitVal *= 10;
+
+        len = strlen (str);
+        digit = startingDigit;
+        do
+        {
+            str[len] = '\0';
+            AppendDigit (str, digit++);
+        } while (ObjIsDefined (nameList, str, StrObjCmp) &&  (digit < maxDigitVal));
+    }
+}  /* MakeCxxStrUnique */
+
+
+/*
+ * if (keepbaseG)
+ * {
+ *   strip leading path and trailing suffix
+ * }
+ * else
+ * {
+ *   allocates and returns a base file name generated from
+ *   the module's name.  May shorten the name if the
+ *   expected length exceed the systems max path component length
+ *   (eg to support SYS V 14 char filename len limit)
+ * }
+ * Base file name is used as the base name for the generated C source files.
+ */
+char *
+MakeBaseFileName PARAMS ((refName),
+    const char *refName)
+{
+  if (keepbaseG)
+  {
+    char	*base, *dot;
+    int		stublen;
+    char	*stub;
+
+    if (base = strrchr (refName, '/'))
+      base++;
+    else
+      base = refName;
+
+    if (dot = strrchr (base, '.'))
+      stublen = dot - base;
+    else
+      stublen = strlen (base);
+
+    stub = Malloc (stublen+1);
+    memcpy (stub, base, stublen);
+    stub[stublen] = '\0';
+
+    return stub;
+  }
+  else
+  {
+    int fNameLen;
+    int cpyLen;
+    char *retVal;
+    int maxPathComponentLen;
+    char pathName[1024];
+#   define MAX_SUFFIX_LEN 2 /* .c, .h, .C */
+    extern int maxFileNameLenG; /* declared in snacc.c */
+
+    /*
+     * if the user has not given the max file name len
+     * via the -mf option,
+     * find the max filename len (ala POSIX method)
+     * if possible.  Otherwise hardwire it to 14
+     * to support underpowered OSes
+     */
+    if (maxFileNameLenG > 2)
+        maxPathComponentLen = maxFileNameLenG;
+    else
+#ifdef _PC_NAME_MAX
+        maxPathComponentLen = pathconf (getcwd (pathName, 1024), _PC_NAME_MAX);
+#else
+        maxPathComponentLen = 14;
+#endif
+
+    retVal = (char *)Malloc (strlen (refName) +1);
+    fNameLen = strlen (refName) + MAX_SUFFIX_LEN;
+    if ((fNameLen > maxPathComponentLen) && (maxPathComponentLen != -1))
+    {
+        cpyLen = maxPathComponentLen - MAX_SUFFIX_LEN;
+
+        /* don't allow trailing dash */
+        if (refName[cpyLen-1] == '-')
+            cpyLen--;
+
+        strncpy (retVal, refName, cpyLen);
+        retVal[cpyLen] = '\0';
+    }
+    else
+        strcpy (retVal, refName);
+
+    return retVal;
+  }
+} /* MakeBaseFileName */
+
+
+
+
+/*
+ * given a module name and a suffix, the
+ * suffix is appended to the module name
+ * and the whole string is put into lower case
+ * and underscores are inserted in likely places
+ * (ie MTSAbstractSvc.h -> mts_abstract_svc.h)
+ */
+char *
+MakeFileName PARAMS ((refName, suffix),
+    const char *refName _AND_
+    const char *suffix)
+{
+  if (keepbaseG)
+  {
+    size_t	baselen = strlen (refName),
+		sufflen = strlen (suffix);
+    char *filename = Malloc (baselen + sufflen + 1);
+
+    memcpy (filename, refName, baselen);
+    memcpy (filename+baselen, suffix, sufflen);
+    filename[baselen+sufflen] = '\0';
+
+    return filename;
+  }
+  else
+  {
+    int i, cpyIndex, len;
+    char *hdrCpy;
+    int fNameLen;
+    char *fName;
+#define MAX_UNDERSCORE 10
+
+    fName = Malloc (strlen (refName) + strlen (suffix) + 1);
+    strcpy (fName, refName);
+    strcat (fName, suffix);
+
+
+    fNameLen = strlen (fName);
+
+    /*
+     * convert dashes to underscores, add spaces
+     */
+    Dash2Underscore (fName, fNameLen);
+
+
+    /*
+     * remove the next two lines if you uncomment the
+     * following underscore inserter
+     */
+    Str2LCase (fName, fNameLen - strlen (suffix));
+    return fName;
+
+    /*
+     *  NO LONGER DONE - LET THE USER MODIFY THE ASN.1 IF DESIRED
+     *  add underscore between Lcase/Ucase of UCase/UcaseLcasce
+     *  eg MTSAbstractSvc -> MTS_Abstract_Svc
+     *  (if enough space)
+    len = strlen (fName) + MAX_UNDERSCORE + 1;
+    hdrCpy = (char *) Malloc (len);
+
+    hdrCpy[0] = fName[0];
+    for (i = 1, cpyIndex = 1; (cpyIndex < len) && (i < fNameLen); i++)
+    {
+        if (((islower (fName[i-1])) && (isupper (fName[i]))) ||
+             ((isupper (fName[i-1])) && (isupper (fName[i])) &&
+                            ((i < (fNameLen-1)) && (islower (fName[i+1])))))
+        {
+            hdrCpy[cpyIndex++] = '_';
+            hdrCpy[cpyIndex++] = fName[i];
+        }
+        else
+            hdrCpy[cpyIndex++] = fName[i];
+    }
+    hdrCpy[cpyIndex++] = '\0';
+
+    Str2LCase (hdrCpy, cpyIndex - strlen (suffix));
+
+    Free (fName);
+    return hdrCpy;
+    */
+  }
+}  /* MakeFileName */
+
+
+char *
+MakeCHdrFileName PARAMS ((refName),
+    const char *refName)
+{
+    return MakeFileName (refName, ".h");
+}
+
+char *
+MakeCSrcFileName PARAMS ((refName),
+    const char *refName)
+{
+    return MakeFileName (refName, ".c");
+}
+
+char *
+MakeCxxHdrFileName PARAMS ((refName),
+    const char *refName)
+{
+    return MakeFileName (refName, ".h");
+}
+
+char *
+MakeCxxSrcFileName PARAMS ((refName),
+    const char *refName)
+{
+#ifndef MACOS
+    return MakeFileName (refName, ".C");
+#else
+    return MakeFileName (refName, ".cpp");      /* ignore cpp rant */
+#endif
+}
+
+#ifdef _IBM_ENC_
+char *                                           /* 19.8.93 IBM-ENC */
+MakedbHdrFileName PARAMS ((refName),
+    const char *refName)
+{
+    return MakeFileName (refName, "db.h");
+}
+
+char *                                           /* 19.8.93 IBM-ENC */
+MakedbSrcFileName PARAMS ((refName),
+    const char *refName)
+{
+    return MakeFileName (refName, "db.C");
+}
+#endif /* _IBM_ENC_ */
+
+#if IDL
+char *
+MakeIDLFileName PARAMS ((refName),
+    const char *refName)
+{
+    return MakeFileName (refName, ".idl");
+}
+#endif
diff --git a/SecuritySNACCRuntime/compiler/back-ends/str-util.h b/SecuritySNACCRuntime/compiler/back-ends/str-util.h
new file mode 100644
index 00000000..67bf36a6
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/str-util.h
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c_gen/str_util.h
+ *
+ * Mike Sample
+ * 91/08/12
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/str-util.h,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: str-util.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:39  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:13:55  rj
+ * by default, snacc now derives output file names from the .asn1 input file name instead of the module name.
+ * the global keepbaseG variable switches between the two behaviours.
+ *
+ * additional filename generator for idl backend.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:18  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:38  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+char *Asn1TypeName2CTypeName PROTO ((char *aName));
+
+char *Asn1FieldName2CFieldName PROTO ((char *aName));
+
+char *Asn1ValueName2CValueName PROTO ((char *aName));
+
+char *GetCaps PROTO ((char *str));
+
+char *GetCapsAndDigits PROTO ((char *str));
+
+void  Str2UCase PROTO ((char *str, int len));
+
+void  Str2LCase PROTO ((char *str, int len));
+
+void  Dash2Underscore PROTO ((char *str, int len));
+
+void  AppendDigit PROTO ((char *str, int digit));
+
+void  MakeCStrUnique PROTO ((DefinedObj *nameList, char *str, int maxDigits, int startingDigit));
+
+void  MakeCxxStrUnique PROTO ((DefinedObj *nameList, char *str, int maxDigits, int startingDigit));
+
+extern int	keepbaseG;
+
+char *MakeBaseFileName PROTO ((const char *moduleName));
+char *MakeFileName PROTO ((const char *moduleName, const char *suffix));
+char *MakeCHdrFileName PROTO ((const char *moduleName));
+char *MakeCSrcFileName PROTO ((const char *moduleName));
+char *MakeCxxHdrFileName PROTO ((const char *moduleName));
+char *MakeCxxSrcFileName PROTO ((const char *moduleName));
+#ifdef _IBM_ENC_
+char *MakedbHdrFileName PROTO ((const char *moduleName)); /* 19.8.93 IBM-ENC */
+char *MakedbSrcFileName PROTO ((const char *moduleName)); /* 19.8.93 IBM-ENC */
+#endif /* _IBM_ENC_ */
+#if IDL
+char *MakeIDLFileName PROTO ((const char *moduleName));
+#endif
diff --git a/SecuritySNACCRuntime/compiler/back-ends/tag-util.c b/SecuritySNACCRuntime/compiler/back-ends/tag-util.c
new file mode 100644
index 00000000..17746a3f
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/tag-util.c
@@ -0,0 +1,536 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c_gen/tag_util.c  - utilities for dealing with tags
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * INSERT_VDA_COMMENTS
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/tag-util.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+ * $Log: tag-util.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:08  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:39  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:15:28  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:26:07  rj
+ * snacc_config.h and other superfluous .h files removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:39  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "define.h"
+#include "lib-types.h"
+#include "c-gen/rules.h"
+#include "c-gen/type-info.h"
+#include "str-util.h"
+#include "snacc-util.h"
+#include "c-gen/util.h"
+#include "tag-util.h"
+
+
+
+/*
+ * returns the tags for the given type (stops at next type definition).
+ * if no tags have been grabbed yet and an untagged CHOICE is encountered,
+ * all of the CHOICE's top level tags are returned and the stoleChoiceTags
+ * flag is set.  If the type has no tags an empty list is returned, not
+ * NULL.
+ *
+ * ASSUMES: tag list's and implicit flags have been adjusted according
+ *          to module level IMPLICIT/EXPLICIT-TAGS and type level
+ *          IMPLICIT/EXPLICIT tagging.
+ *
+ * EXAMPLE:
+ *
+ *   typeX ::= SEQUENCE                         SomeChoice ::= CHOICE
+ *   {                                          {
+ *         foo [0] INTEGER,                          [0] INTEGER,
+ *         bar SomeChoice,                           [1] BOOLEAN,
+ *         bell [1] IMPLICIT BOOLEAN,                [2] IA5String
+ *         gumby [2] SomeChoice,                }
+           poki SomeOtherChoice
+ *   }
+ *
+ *  SomeOtherChoice ::= [APPLICATION 99] CHOICE { ....}
+ *
+ *  GetTags (foo's type) -->  CNTX 0, UNIV INTEGER_TAG_CODE   stoleChoiceTags = FALSE
+ *  GetTags (bar)        -->  CNTX 0, CNTX 1, CNTX 2   (SomeChoice Elmt's first Tags)
+ *                                                      stoleChoiceTags = TRUE
+ *  GetTags (bell)       -->  CNTX 1    stoleChoiceTags = FALSE
+ *  GetTags (gumby)      -->  CNTX 2    stoleChoiceTags = FALSE
+ *  GetTags (poki)       -->  APPLICATION 99    stoleChoiceTags = FALSE
+ *
+ * MS 92/03/04 Added tag form information
+ */
+TagList*
+GetTags PARAMS ((t, stoleChoiceTags),
+    Type *t _AND_
+    int *stoleChoiceTags)
+{
+    Tag *tag;
+    TagList *tl;
+    TagList *retVal;
+    Tag *last;
+    Tag  *tagCopy;
+    Tag **tagHndl;
+    int implicitRef;
+    int stoleChoicesAgain;
+    NamedType *e;
+
+    tl = t->tags;
+    if (tl != NULL)
+        AsnListFirst (tl);
+
+    retVal = (TagList*) AsnListNew (sizeof (void*));
+    implicitRef = FALSE;
+    *stoleChoiceTags = FALSE;
+
+    for (;;)
+    {
+         /*
+          * go through tag list local to this type if any
+          */
+
+        FOR_REST_LIST_ELMT (tag, tl)
+        {
+            tagCopy = (Tag*)Malloc (sizeof (Tag));
+            memcpy (tagCopy, tag, sizeof (Tag));
+            tagHndl = (Tag**)AsnListAppend (retVal);
+            *tagHndl = tagCopy;
+
+        }
+
+        /*
+         * follow tags of referenced types
+         */
+
+        if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+             (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+        {
+            if (!implicitRef)
+                implicitRef = t->implicit;
+
+
+            if (t->basicType->a.localTypeRef->link == NULL)
+            {
+                fprintf (stderr,"ERROR - unresolved type ref, cannot get tags for decoding>\n");
+                break;
+            }
+            t = t->basicType->a.localTypeRef->link->type;
+            tl = t->tags;
+
+            if (tl != NULL)
+            {
+                AsnListFirst (tl); /* set curr ptr to first node */
+                if ((!LIST_EMPTY (tl)) && implicitRef)
+                {
+                    AsnListNext (tl);
+                    implicitRef = FALSE;
+                }
+            }
+
+        }
+
+        /*
+         * if untagged choice and no tags found yet
+         */
+        else if ((t->basicType->choiceId == BASICTYPE_CHOICE) && (LIST_EMPTY (retVal)))
+        {
+            /*
+             * Return list of top level tags from this choice
+             * and set "stoleChoiceTags" bool param
+             */
+            if (implicitRef)
+                fprintf (stderr,"ERROR - IMPLICITLY Tagged CHOICE\n");
+
+            *stoleChoiceTags = TRUE;
+
+            FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
+            {
+                stoleChoicesAgain = FALSE;
+                tl = GetTags (e->type, &stoleChoicesAgain);
+
+                if (tl == NULL)
+                    break;
+
+		AsnListFirst (tl);
+                if (stoleChoicesAgain)
+                {
+                    FOR_EACH_LIST_ELMT (tag, tl)
+                    {
+                        tagCopy = (Tag*)Malloc (sizeof (Tag));
+                        memcpy (tagCopy, tag, sizeof (Tag));
+			tagHndl = (Tag**)AsnListAppend (retVal);
+			*tagHndl = tagCopy;
+
+                    }
+                }
+                else
+                {
+		  tag = (Tag*)FIRST_LIST_ELMT (tl);
+		  tagCopy = (Tag*)Malloc (sizeof (Tag));
+		  memcpy (tagCopy, tag, sizeof (Tag));
+		  tagHndl = (Tag**)AsnListAppend (retVal);
+		  *tagHndl = tagCopy;
+                }
+                FreeTags (tl);
+            }
+
+            break;  /* exit for loop */
+        }
+
+        else
+            break; /* exit for loop */
+    }
+
+
+    if (!*stoleChoiceTags && (retVal != NULL) && !LIST_EMPTY (retVal))
+    {
+        last = (Tag*)LAST_LIST_ELMT (retVal);
+        FOR_EACH_LIST_ELMT (tag, retVal)
+        {
+            tag->form = CONS;
+        }
+        last->form = LIBTYPE_GET_TAG_FORM (GetBuiltinType (t));
+    }
+
+    AsnListFirst (retVal);
+    return retVal;
+
+}  /* GetTags */
+
+
+void
+FreeTags PARAMS ((tl),
+    TagList *tl)
+{
+    Tag *tag;
+    AsnListNode *listNode;
+    AsnListNode *ln;
+
+    /* free tags */
+    FOR_EACH_LIST_ELMT (tag, tl)
+    {
+        Free (tag);
+    }
+
+    /* free list nodes */
+    for (ln = FIRST_LIST_NODE (tl); ln != NULL; )
+    {
+        listNode = ln;
+	ln = ln->next;
+        Free (listNode);
+    }
+
+    /* free list head */
+    Free (tl);
+
+}  /* FreeTags */
+
+/*
+ * Returns the number of tags that GetTags would return for
+ * the same type.
+ */
+int
+CountTags PARAMS ((t),
+    Type *t)
+{
+    int tagCount;
+    Tag *tag;
+    TagList *tl;
+    int implicitRef;
+    int stoleChoicesAgain;
+    NamedType *e;
+
+    tl = t->tags;
+    if (tl != NULL)
+        AsnListFirst (tl);
+
+    tagCount = 0;
+    implicitRef = FALSE;
+
+    for (;;)
+    {
+         /*
+          * go through tag list local to this type if any
+          */
+
+        FOR_REST_LIST_ELMT (tag, tl)
+        {
+	    tagCount++;
+        }
+
+        /*
+         * follow tags of referenced types
+         */
+
+        if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+             (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+        {
+            if (!implicitRef)
+                implicitRef = t->implicit;
+
+
+            if (t->basicType->a.localTypeRef->link == NULL)
+            {
+                fprintf (stderr,"ERROR - unresolved type ref, cannot get tags for decoding>\n");
+                break;
+            }
+            t = t->basicType->a.localTypeRef->link->type;
+            tl = t->tags;
+
+            if (tl != NULL)
+            {
+                AsnListFirst (tl); /* set curr ptr to first node */
+                if ((!LIST_EMPTY (tl)) && implicitRef)
+                {
+                    AsnListNext (tl);
+                    implicitRef = FALSE;
+                }
+            }
+
+        }
+        else
+            break;
+    }
+
+    return tagCount;
+
+}  /* CountTags */
+
+
+unsigned long int
+TagByteLen PARAMS ((tagCode),
+    unsigned long int tagCode)
+{
+    unsigned long int tagLen;
+
+    if (tagCode < 31)
+        tagLen = 1;
+    else if (tagCode < 128)
+        tagLen = 2;
+    else if (tagCode < 16384)
+        tagLen = 3;
+    else if (tagCode < 2097152)
+        tagLen = 4;
+    else
+        tagLen = 5;
+
+    return tagLen;
+} /* TagByteLen */
+
+
+
+char*
+Class2ClassStr PARAMS ((class),
+    int class)
+{
+    switch (class)
+    {
+        case UNIV:
+            return "UNIV";
+            break;
+
+        case APPL:
+            return "APPL";
+            break;
+
+        case CNTX:
+            return "CNTX";
+            break;
+
+        case PRIV:
+            return "PRIV";
+            break;
+
+        default:
+            return "UNKNOWN";
+            break;
+    }
+} /* Class2ClassStr */
+
+
+
+char*
+Form2FormStr PARAMS ((form),
+    BER_FORM form)
+{
+    switch (form)
+    {
+        case PRIM:
+            return "PRIM";
+            break;
+
+        case CONS:
+            return "CONS";
+            break;
+
+        default:
+            return "UNKNOWN";
+            break;
+    }
+} /* Form2FormStr */
+
+
+
+char*
+Code2UnivCodeStr PARAMS ((code),
+    BER_UNIV_CODE code)
+{
+    switch (code)
+    {
+      case BOOLEAN_TAG_CODE:
+        return "BOOLEAN_TAG_CODE";
+        break;
+
+      case INTEGER_TAG_CODE:
+        return "INTEGER_TAG_CODE";
+        break;
+
+      case BITSTRING_TAG_CODE:
+        return "BITSTRING_TAG_CODE";
+        break;
+
+      case OCTETSTRING_TAG_CODE:
+        return "OCTETSTRING_TAG_CODE";
+        break;
+
+      case NULLTYPE_TAG_CODE:
+        return "NULLTYPE_TAG_CODE";
+        break;
+
+      case OID_TAG_CODE:
+        return "OID_TAG_CODE";
+        break;
+
+      case OD_TAG_CODE:
+        return "OD_TAG_CODE";
+        break;
+
+      case EXTERNAL_TAG_CODE:
+        return "EXTERNAL_TAG_CODE";
+        break;
+
+      case REAL_TAG_CODE:
+        return "REAL_TAG_CODE";
+        break;
+
+      case ENUM_TAG_CODE:
+        return "ENUM_TAG_CODE";
+        break;
+
+      case SEQ_TAG_CODE:
+        return "SEQ_TAG_CODE";
+        break;
+
+      case SET_TAG_CODE:
+        return "SET_TAG_CODE";
+        break;
+
+      case NUMERICSTRING_TAG_CODE:
+        return "NUMERICSTRING_TAG_CODE";
+        break;
+
+      case PRINTABLESTRING_TAG_CODE:
+        return "PRINTABLESTRING_TAG_CODE";
+        break;
+
+      case TELETEXSTRING_TAG_CODE:
+        return "TELETEXSTRING_TAG_CODE";
+        break;
+
+      case VIDEOTEXSTRING_TAG_CODE:
+        return "VIDEOTEXSTRING_TAG_CODE";
+        break;
+
+      case IA5STRING_TAG_CODE:
+        return "IA5STRING_TAG_CODE";
+        break;
+
+      case UTCTIME_TAG_CODE:
+        return "UTCTIME_TAG_CODE";
+        break;
+
+      case GENERALIZEDTIME_TAG_CODE:
+        return "GENERALIZEDTIME_TAG_CODE";
+        break;
+
+      case GRAPHICSTRING_TAG_CODE:
+        return "GRAPHICSTRING_TAG_CODE";
+        break;
+
+      case VISIBLESTRING_TAG_CODE:
+        return "VISIBLESTRING_TAG_CODE";
+        break;
+
+      case GENERALSTRING_TAG_CODE:
+        return "GENERALSTRING_TAG_CODE";
+        break;
+
+#ifdef VDADER_RULES
+
+      case UNIVERSALSTRING_TAG_CODE:
+        return "UNIVERSALSTRING_TAG_CODE";
+        break;
+
+      case BMPSTRING_TAG_CODE:
+        return "BMPSTRING_TAG_CODE";
+        break;
+
+       default:
+        { 
+            /* if the universal type is not known then just return the
+             * unvisersal tag code.  This is useful for defining new types
+             * in local modules w/o having to modify the compiler.
+             */
+            static char retstring[3];
+            sprintf(retstring, "%d", code); 
+            return retstring; 
+        }
+#else
+
+      default:
+        return "UNKNOWN";
+#endif
+
+    }
+} /* TagId2FormStr */
diff --git a/SecuritySNACCRuntime/compiler/back-ends/tag-util.h b/SecuritySNACCRuntime/compiler/back-ends/tag-util.h
new file mode 100644
index 00000000..5ef25f9f
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/back-ends/tag-util.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * compiler/back_ends/c_gen/tag_util.h - utilities for dealing with tags
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/tag-util.h,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
+ * $Log: tag-util.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:09  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:27  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:39  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 18:15:29  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:19  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:40  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+TagList		*GetTags PROTO ((Type *t, int *stoleChoiceTags));
+void		FreeTags PROTO ((TagList *tl));
+int		CountTags PROTO ((Type *t));
+unsigned long int TagByteLen PROTO ((unsigned long int tagCode));
+char		*Class2ClassStr PROTO ((int class));  /* class defined in asn1module.h */
+char		*Form2FormStr PROTO ((BER_FORM form));
+char		*Code2UnivCodeStr PROTO ((BER_UNIV_CODE code));
diff --git a/SecuritySNACCRuntime/compiler/boot/tbl.c b/SecuritySNACCRuntime/compiler/boot/tbl.c
new file mode 100644
index 00000000..e57bf15d
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/boot/tbl.c
@@ -0,0 +1,592 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    tbl.c
+ *
+ *    "TBL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Mon Jun  2 11:23:51 1997
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "tbl.h"
+
+
+AsnLen
+BEncTBLRangeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLRange *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->to));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->from));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLRangeContent */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumber *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->value));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLNamedNumberContent */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberListContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumberList *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLNamedNumberListContent */
+
+
+
+
+AsnLen
+BEncTBLTypeRefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeRef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnBoolContent (b, (&v->implicit));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeRefContent */
+
+
+
+
+AsnLen
+BEncTBLTagContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTag *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->code));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTagClassContent (b, (&v->tclass));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 10);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTagContent */
+
+
+
+
+AsnLen
+BEncTBLTypeSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTagContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContentSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContentSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeContentSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLType *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->values)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberListContent (b, (v->values));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 6);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLRangeContent (b, (v->constraint));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 5);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    itemLen = BEncPrintableStringContent (b, (&v->fieldName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 4);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentContent (b, (v->content));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncAsnBoolContent (b, (&v->optional));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeIdContent (b, (&v->typeId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContentContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContent *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_PRIMTYPE:
+    itemLen = BEncAsnNullContent (b, (&v->a.primType));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_ELMTS:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncTBLTypeContentContent */
+
+
+
+
+AsnLen
+BEncTBLTypeDefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeDef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    itemLen = BEncAsnNullContent (b, (v->isPdu));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 5);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, (v->type));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->typeName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 19);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeDefContent */
+
+
+
+
+AsnLen
+BEncTBLModuleSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModuleSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeDefContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLModuleSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLModuleContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModule *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnBoolContent (b, (&v->isUseful));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->id));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLModuleContent */
+
+
+
+
+AsnLen
+BEncTBLSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLSeqOfContent */
+
+
+
+
+AsnLen BEncTBL PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncTBLContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    return l;
+} /* BEncTBL */
+
+AsnLen
+BEncTBLContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLSeqOfContent (b, (v->modules));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalLenStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTags));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypes));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumModules));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLContent */
+
+
+
+
diff --git a/SecuritySNACCRuntime/compiler/boot/tbl.h b/SecuritySNACCRuntime/compiler/boot/tbl.h
new file mode 100644
index 00000000..bc046218
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/boot/tbl.h
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    tbl.h
+ *
+ *    "TBL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Mon Jun  2 11:23:51 1997
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _tbl_h_
+#define _tbl_h_
+
+
+
+
+typedef enum
+    {
+        TBL_BOOLEAN = 0,
+        TBL_INTEGER = 1,
+        TBL_BITSTRING = 2,
+        TBL_OCTETSTRING = 3,
+        TBL_NULL = 4,
+        TBL_OID = 5,
+        TBL_REAL = 6,
+        TBL_ENUMERATED = 7,
+        TBL_SEQUENCE = 8,
+        TBL_SET = 9,
+        TBL_SEQUENCEOF = 10,
+        TBL_SETOF = 11,
+        TBL_CHOICE = 12,
+        TBL_TYPEREF = 13
+    } TBLTypeId; /* ENUMERATED { TBL_BOOLEAN (0), TBL_INTEGER (1), TBL_BITSTRING (2), TBL_OCTETSTRING (3), TBL_NULL (4), TBL_OID (5), TBL_REAL (6), TBL_ENUMERATED (7), TBL_SEQUENCE (8), TBL_SET (9), TBL_SEQUENCEOF (10), TBL_SETOF (11), TBL_CHOICE (12), TBL_TYPEREF (13) }  */
+
+#define BEncTBLTypeIdContent BEncAsnEnumContent
+
+
+
+
+typedef AsnInt TBLTypeDefId; /* INTEGER */
+
+#define BEncTBLTypeDefIdContent BEncAsnIntContent
+
+
+
+
+typedef enum
+    {
+        UNIVERSAL = 0,
+        APPLICATION = 1,
+        CONTEXT = 2,
+        PRIVATE = 3
+    } TBLTagClass; /* ENUMERATED { UNIVERSAL (0), APPLICATION (1), CONTEXT (2), PRIVATE (3) }  */
+
+#define BEncTBLTagClassContent BEncAsnEnumContent
+
+
+
+
+typedef struct TBLRange /* SEQUENCE */
+{
+    AsnInt from; /* [0] IMPLICIT INTEGER */
+    AsnInt to; /* [1] IMPLICIT INTEGER */
+} TBLRange;
+
+AsnLen BEncTBLRangeContent PROTO ((BUF_TYPE b, TBLRange *v));
+
+
+
+
+typedef struct TBLNamedNumber /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnInt value; /* [1] IMPLICIT INTEGER */
+} TBLNamedNumber;
+
+AsnLen BEncTBLNamedNumberContent PROTO ((BUF_TYPE b, TBLNamedNumber *v));
+
+
+
+
+typedef AsnList TBLNamedNumberList; /* SEQUENCE OF TBLNamedNumber */
+
+AsnLen BEncTBLNamedNumberListContent PROTO ((BUF_TYPE b, TBLNamedNumberList *v));
+
+
+
+
+typedef struct TBLTypeRef /* SEQUENCE */
+{
+    TBLTypeDefId typeDef; /* TBLTypeDefId */
+    AsnBool implicit; /* BOOLEAN */
+} TBLTypeRef;
+
+AsnLen BEncTBLTypeRefContent PROTO ((BUF_TYPE b, TBLTypeRef *v));
+
+
+
+
+typedef struct TBLTag /* SEQUENCE */
+{
+    TBLTagClass tclass; /* TBLTagClass */
+    AsnInt code; /* INTEGER (0..MAX) */
+} TBLTag;
+
+AsnLen BEncTBLTagContent PROTO ((BUF_TYPE b, TBLTag *v));
+
+
+
+
+typedef AsnList TBLTypeSeqOf; /* SEQUENCE OF TBLTag */
+
+AsnLen BEncTBLTypeSeqOfContent PROTO ((BUF_TYPE b, TBLTypeSeqOf *v));
+
+
+
+
+typedef AsnList TBLTypeContentSeqOf; /* SEQUENCE OF TBLType */
+
+AsnLen BEncTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, TBLTypeContentSeqOf *v));
+
+
+
+
+typedef struct TBLType /* SEQUENCE */
+{
+    TBLTypeId typeId; /* [0] IMPLICIT TBLTypeId */
+    AsnBool optional; /* [1] IMPLICIT BOOLEAN */
+    TBLTypeSeqOf* tagList; /* [2] IMPLICIT TBLTypeSeqOf OPTIONAL */
+    struct TBLTypeContent* content; /* [3] TBLTypeContent */
+    PrintableString fieldName; /* [4] IMPLICIT PrintableString OPTIONAL */
+    struct TBLRange* constraint; /* [5] IMPLICIT TBLRange OPTIONAL */
+    TBLNamedNumberList* values; /* [6] IMPLICIT TBLNamedNumberList OPTIONAL */
+} TBLType;
+
+AsnLen BEncTBLTypeContent PROTO ((BUF_TYPE b, TBLType *v));
+
+
+
+
+typedef struct TBLTypeContent /* CHOICE */
+{
+    enum TBLTypeContentChoiceId
+    {
+        TBLTYPECONTENT_PRIMTYPE,
+        TBLTYPECONTENT_ELMTS,
+        TBLTYPECONTENT_TYPEREF
+    } choiceId;
+    union TBLTypeContentChoiceUnion
+    {
+    AsnNull primType; /* [0] IMPLICIT NULL */
+    TBLTypeContentSeqOf* elmts; /* [1] IMPLICIT TBLTypeContentSeqOf */
+    struct TBLTypeRef* typeRef; /* [2] IMPLICIT TBLTypeRef */
+    } a;
+} TBLTypeContent;
+
+AsnLen BEncTBLTypeContentContent PROTO ((BUF_TYPE b, TBLTypeContent *v));
+
+
+
+
+typedef struct TBLTypeDef /* SEQUENCE */
+{
+    TBLTypeDefId typeDefId; /* TBLTypeDefId */
+    PrintableString typeName; /* PrintableString */
+    struct TBLType* type; /* TBLType */
+    AsnNull* isPdu; /* NULL OPTIONAL */
+} TBLTypeDef;
+
+AsnLen BEncTBLTypeDefContent PROTO ((BUF_TYPE b, TBLTypeDef *v));
+
+
+
+
+typedef AsnList TBLModuleSeqOf; /* SEQUENCE OF TBLTypeDef */
+
+AsnLen BEncTBLModuleSeqOfContent PROTO ((BUF_TYPE b, TBLModuleSeqOf *v));
+
+
+
+
+typedef struct TBLModule /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnOid id; /* [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL */
+    AsnBool isUseful; /* [2] IMPLICIT BOOLEAN */
+    TBLModuleSeqOf* typeDefs; /* [3] IMPLICIT TBLModuleSeqOf */
+} TBLModule;
+
+AsnLen BEncTBLModuleContent PROTO ((BUF_TYPE b, TBLModule *v));
+
+
+
+
+typedef AsnList TBLSeqOf; /* SEQUENCE OF TBLModule */
+
+AsnLen BEncTBLSeqOfContent PROTO ((BUF_TYPE b, TBLSeqOf *v));
+
+
+
+
+typedef struct TBL /* SEQUENCE */
+{
+    AsnInt totalNumModules; /* INTEGER */
+    AsnInt totalNumTypeDefs; /* INTEGER */
+    AsnInt totalNumTypes; /* INTEGER */
+    AsnInt totalNumTags; /* INTEGER */
+    AsnInt totalNumStrings; /* INTEGER */
+    AsnInt totalLenStrings; /* INTEGER */
+    TBLSeqOf* modules; /* TBLSeqOf */
+} TBL;
+
+AsnLen BEncTBL PROTO ((BUF_TYPE b, TBL *v));
+
+AsnLen BEncTBLContent PROTO ((BUF_TYPE b, TBL *v));
+
+
+
+
+
+#endif /* conditional include of tbl.h */
diff --git a/SecuritySNACCRuntime/compiler/core/.cvsignore b/SecuritySNACCRuntime/compiler/core/.cvsignore
new file mode 100644
index 00000000..5761abcf
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/.cvsignore
@@ -0,0 +1 @@
+*.o
diff --git a/SecuritySNACCRuntime/compiler/core/asn1module.h b/SecuritySNACCRuntime/compiler/core/asn1module.h
new file mode 100644
index 00000000..af4026c2
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/asn1module.h
@@ -0,0 +1,1028 @@
+/*
+ *    compiler/core/asn1module.h
+ *
+ *    "Asn1Module" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was by snacc on Sun Feb  7 23:38:26 1993
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+#ifndef _asn1module_h_
+#define _asn1module_h_
+
+
+
+
+typedef enum
+    {
+        PRESENT_CT = 0,
+        ABSENT_CT = 1,
+        EMPTY_CT = 2,
+        OPTIONAL_CT = 3
+    } ConstraintEnum; /* ENUMERATED { PRESENT_CT (0), ABSENT_CT (1), EMPTY_CT (2), OPTIONAL_CT (3) }  */
+
+
+
+
+typedef enum
+    {
+        FULL_CT = 0,
+        PARTIAL_CT = 1,
+        SINGLE_CT = 2
+    } InnerSubtypeEnum; /* ENUMERATED { FULL_CT (0), PARTIAL_CT (1), SINGLE_CT (2) }  */
+
+
+
+
+typedef enum
+    {
+        SNMP_MANDATORY = 0,
+        SNMP_OPTIONAL = 1,
+        SNMP_OBSOLETE = 2,
+        SNMP_DEPRECATED = 3
+    } SnmpObjectTypeMacroTypeEnum1; /* ENUMERATED { SNMP_MANDATORY (0), SNMP_OPTIONAL (1), SNMP_OBSOLETE (2), SNMP_DEPRECATED (3) }  */
+
+
+
+
+typedef enum
+    {
+        SNMP_READ_ONLY = 0,
+        SNMP_READ_WRITE = 1,
+        SNMP_WRITE_ONLY = 2,
+        SNMP_NOT_ACCESSIBLE = 3
+    } SnmpObjectTypeMacroTypeEnum; /* ENUMERATED { SNMP_READ_ONLY (0), SNMP_READ_WRITE (1), SNMP_WRITE_ONLY (2), SNMP_NOT_ACCESSIBLE (3) }  */
+
+
+
+
+typedef enum
+    {
+        CONSUMER_PORT = 0,
+        SUPPLIER_PORT = 1,
+        SYMMETRIC_PORT = 2
+    } AsnPortEnum; /* ENUMERATED { CONSUMER_PORT (0), SUPPLIER_PORT (1), SYMMETRIC_PORT (2) }  */
+
+
+
+
+typedef enum
+    {
+        EXPORTS_ALL = 0,
+        EXPORTS_NOTHING = 1,
+        EXPORTS_SOME = 2
+    } ModuleEnum2; /* ENUMERATED { EXPORTS_ALL (0), EXPORTS_NOTHING (1), EXPORTS_SOME (2) }  */
+
+
+
+
+typedef enum
+    {
+        EXPLICIT_TAGS = 0,
+        IMPLICIT_TAGS = 1
+    } ModuleEnum1; /* ENUMERATED { EXPLICIT_TAGS (0), IMPLICIT_TAGS (1) }  */
+
+
+
+
+typedef enum
+    {
+        MOD_OK = 0,
+        MOD_NOT_LINKED = 1,
+        MOD_ERROR = 2
+    } ModuleEnum; /* ENUMERATED { MOD_OK (0), MOD_NOT_LINKED (1), MOD_ERROR (2) }  */
+
+
+
+
+typedef AsnInt AsnRefineMacroType; /* INTEGER */
+
+
+
+
+typedef enum
+    {
+        MIN_INT = 0,
+        MAX_INT = 1
+    } SpecialIntegerValue; /* ENUMERATED { MIN_INT (0), MAX_INT (1) }  */
+
+
+
+
+typedef enum
+    {
+        MINUS_INFINITY_REAL = 0,
+        PLUS_INFINITY_REAL = 1
+    } SpecialRealValue; /* ENUMERATED { MINUS_INFINITY_REAL (0), PLUS_INFINITY_REAL (1) }  */
+
+
+
+
+typedef enum
+    {
+        C_CHOICE = 0,
+        C_LIST = 1,
+        C_ANY = 2,
+        C_ANYDEFINEDBY = 3,
+        C_LIB = 4,
+        C_STRUCT = 5,
+        C_TYPEREF = 6,
+        C_NO_TYPE = 7,
+        C_TYPEDEF = 8
+    } CTypeId; /* ENUMERATED { C_CHOICE (0), C_LIST (1), C_ANY (2), C_ANYDEFINEDBY (3), C_LIB (4), C_STRUCT (5), C_TYPEREF (6), C_NO_TYPE (7), C_TYPEDEF (8) }  */
+
+
+
+
+typedef struct OidOrInt /* CHOICE */
+{
+    enum OidOrIntChoiceId
+    {
+        OIDORINT_OID,
+        OIDORINT_INTID
+    } choiceId;
+    union OidOrIntChoiceUnion
+    {
+    AsnOid *oid; /* OBJECT IDENTIFIER */
+    AsnInt intId; /* INTEGER */
+    } a;
+} OidOrInt;
+
+
+
+
+typedef AsnList OidList; /* SEQUENCE OF OBJECT IDENTIFIER */
+
+
+
+
+typedef char *MyString; /* PrintableString */
+
+
+
+
+typedef struct ModuleId /* SEQUENCE */
+{
+    MyString name; /* MyString */
+    OID *oid; /* OBJECT IDENTIFIER OPTIONAL */
+} ModuleId;
+
+
+
+
+typedef struct AnyRef /* SEQUENCE */
+{
+    MyString anyIdName; /* MyString */
+    struct OidOrInt *id; /* OidOrInt */
+} AnyRef;
+
+
+
+
+typedef AsnList AnyRefList; /* SEQUENCE OF AnyRef */
+
+
+
+
+typedef AsnList AttributeList; /* SEQUENCE OF MyString */
+
+
+
+
+typedef MyString MacroDef; /* MyString */
+
+
+
+
+
+
+
+
+typedef AsnList ImportModuleList; /* SEQUENCE OF ImportModule */
+
+
+
+
+typedef AsnList ImportElmtList; /* SEQUENCE OF ImportElmt */
+
+
+
+
+typedef AsnList TypeDefList; /* SEQUENCE OF TypeDef */
+
+
+
+
+typedef AsnList TagList; /* SEQUENCE OF Tag */
+
+
+
+
+typedef AsnList NamedTypeList; /* SEQUENCE OF NamedType */
+
+
+
+
+typedef AsnList ValueList; /* SEQUENCE OF Value */
+
+
+
+
+typedef AsnList TypeOrValueList; /* SEQUENCE OF TypeOrValue */
+
+
+
+
+typedef AsnList AsnPortList; /* SEQUENCE OF AsnPort */
+
+
+
+
+typedef AsnList SubtypeList; /* SEQUENCE OF Subtype */
+
+
+
+
+typedef AsnList ConstraintList; /* SEQUENCE OF Constraint */
+
+
+
+
+typedef AsnList ValueDefList; /* SEQUENCE OF ValueDef */
+
+
+
+
+typedef struct ImportElmtChoice /* CHOICE */
+{
+    enum ImportElmtChoiceChoiceId
+    {
+        IMPORTELMTCHOICE_TYPE,
+        IMPORTELMTCHOICE_VALUE
+    } choiceId;
+    union ImportElmtChoiceChoiceUnion
+    {
+    struct TypeDef *type; /* [0] IMPLICIT TypeDef */
+    struct ValueDef *value; /* [1] IMPLICIT ValueDef */
+    } a;
+} ImportElmtChoice;
+
+
+
+
+typedef struct Module /* SEQUENCE */
+{
+    ModuleEnum status; /* ModuleEnum */
+    struct ModuleId *modId; /* ModuleId */
+    ModuleEnum1 tagDefault; /* ModuleEnum1 */
+    ModuleEnum2 exportStatus; /* ModuleEnum2 */
+    ImportModuleList *imports; /* ImportModuleList */
+    TypeDefList *typeDefs; /* TypeDefList */
+    ValueDefList *valueDefs; /* ValueDefList */
+    AsnBool hasAnys; /* BOOLEAN */
+    MyString asn1SrcFileName; /* MyString */
+    MyString cHdrFileName; /* MyString */
+    MyString cSrcFileName; /* MyString */
+    MyString cxxHdrFileName; /* MyString */
+    MyString cxxSrcFileName; /* MyString */
+#ifdef _IBM_ENC_
+    MyString dbHdrFileName;  /* 19.8.93 IBM-ENC */
+    MyString dbSrcFileName;  /* 19.8.93 IBM-ENC */
+#endif /* _IBM_ENC_ */
+#if META
+    MyString	cxxname;
+#endif
+#if IDL
+    MyString	idlFileName; /* MyString */
+    MyString	idlname;
+#endif
+} Module;
+
+
+
+
+typedef struct ImportModule /* SEQUENCE */
+{
+    struct ModuleId *modId; /* ModuleId */
+    ImportElmtList *importElmts; /* ImportElmtList */
+    struct Module *moduleRef; /* Module */
+    AsnInt lineNo; /* INTEGER */
+} ImportModule;
+
+
+
+
+typedef struct ImportElmt /* SEQUENCE */
+{
+    struct ImportElmtChoice *resolvedRef; /* ImportElmtChoice OPTIONAL */
+    MyString name; /* MyString */
+    AsnBool privateScope; /* BOOLEAN */
+    AsnInt lineNo; /* INTEGER */
+} ImportElmt;
+
+
+
+
+typedef struct TypeDef /* SEQUENCE */
+{
+    AsnBool exported; /* BOOLEAN */
+    AsnBool recursive; /* BOOLEAN */
+    AsnBool isPdu; /* BOOLEAN */
+    AsnInt localRefCount; /* INTEGER */
+    AsnInt importRefCount; /* INTEGER */
+    AsnInt tmpRefCount; /* INTEGER */
+    AsnBool visited; /* BOOLEAN */
+    MyString definedName; /* MyString */
+    struct Type *type; /* Type */
+    struct CTDI *cTypeDefInfo; /* CTDI */
+    struct CxxTDI *cxxTypeDefInfo; /* CxxTDI */
+    struct IDLTDI *idlTypeDefInfo; /* IDLTDI */
+    AttributeList *attrList; /* AttributeList */
+    TypeDefList *refList; /* TypeDefList */
+    AnyRefList *anyRefs; /* AnyRefList */
+} TypeDef;
+
+
+
+
+typedef struct Tag /* SEQUENCE */
+{
+    AsnInt tclass; /* INTEGER */
+    AsnInt form; /* INTEGER */
+    AsnInt code; /* INTEGER */
+    AsnBool explicit; /* BOOLEAN */
+    struct Value *valueRef; /* Value */
+} Tag;
+
+
+
+
+typedef struct Type /* SEQUENCE */
+{
+    AsnBool optional; /* BOOLEAN */
+    AsnBool implicit; /* BOOLEAN */
+    TagList *tags; /* TagList */
+    struct NamedValue *defaultVal; /* [0] IMPLICIT NamedValue OPTIONAL */
+    struct Subtype *subtypes; /* [1] Subtype OPTIONAL */
+    struct BasicType *basicType; /* [2] BasicType */
+    AsnInt lineNo; /* INTEGER */
+    struct CTRI *cTypeRefInfo; /* CTRI */
+    struct CxxTRI *cxxTypeRefInfo; /* CxxTRI */
+    struct IDLTRI *idlTypeRefInfo; /* IDLTRI */
+    AttributeList *attrList; /* AttributeList */
+} Type;
+
+
+
+
+typedef ValueDefList NamedNumberList; /* ValueDefList */
+
+
+
+
+typedef struct BasicType /* CHOICE */
+{
+    enum BasicTypeChoiceId
+    {
+        BASICTYPE_UNKNOWN,
+        BASICTYPE_BOOLEAN,
+        BASICTYPE_INTEGER,
+        BASICTYPE_BITSTRING,
+        BASICTYPE_OCTETSTRING,
+        BASICTYPE_NULL,
+        BASICTYPE_OID,
+        BASICTYPE_REAL,
+        BASICTYPE_ENUMERATED,
+        BASICTYPE_SEQUENCE,
+        BASICTYPE_SEQUENCEOF,
+        BASICTYPE_SET,
+        BASICTYPE_SETOF,
+        BASICTYPE_CHOICE,
+        BASICTYPE_SELECTION,
+        BASICTYPE_COMPONENTSOF,
+        BASICTYPE_ANY,
+        BASICTYPE_ANYDEFINEDBY,
+        BASICTYPE_LOCALTYPEREF,
+        BASICTYPE_IMPORTTYPEREF,
+        BASICTYPE_MACROTYPE,
+        BASICTYPE_MACRODEF
+    } choiceId;
+    union BasicTypeChoiceUnion
+    {
+    AsnNull unknown; /* [0] IMPLICIT NULL */
+    AsnNull boolean; /* [1] IMPLICIT NULL */
+    NamedNumberList *integer; /* [2] IMPLICIT NamedNumberList */
+    NamedNumberList *bitString; /* [3] IMPLICIT NamedNumberList */
+    AsnNull octetString; /* [4] IMPLICIT NULL */
+    AsnNull null; /* [5] IMPLICIT NULL */
+    AsnNull oid; /* [6] IMPLICIT NULL */
+    AsnNull real; /* [7] IMPLICIT NULL */
+    NamedNumberList *enumerated; /* [8] IMPLICIT NamedNumberList */
+    NamedTypeList *sequence; /* [9] IMPLICIT NamedTypeList */
+    struct Type *sequenceOf; /* [10] IMPLICIT Type */
+    NamedTypeList *set; /* [11] IMPLICIT NamedTypeList */
+    struct Type *setOf; /* [12] IMPLICIT Type */
+    NamedTypeList *choice; /* [13] IMPLICIT NamedTypeList */
+    struct SelectionType *selection; /* [14] IMPLICIT SelectionType */
+    struct Type *componentsOf; /* [15] IMPLICIT Type */
+    AsnNull any; /* [16] IMPLICIT NULL */
+    struct AnyDefinedByType *anyDefinedBy; /* [17] IMPLICIT AnyDefinedByType */
+    struct TypeRef *localTypeRef; /* [19] IMPLICIT TypeRef */
+    struct TypeRef *importTypeRef; /* [20] IMPLICIT TypeRef */
+    struct MacroType *macroType; /* [21] MacroType */
+    MacroDef macroDef; /* [22] IMPLICIT MacroDef */
+    } a;
+} BasicType;
+
+
+
+
+typedef struct MacroType /* CHOICE */
+{
+    enum MacroTypeChoiceId
+    {
+        MACROTYPE_ROSOPERATION,
+        MACROTYPE_ROSERROR,
+        MACROTYPE_ROSBIND,
+        MACROTYPE_ROSUNBIND,
+        MACROTYPE_ROSASE,
+        MACROTYPE_ROSAC,
+        MACROTYPE_MTSASEXTENSION,
+        MACROTYPE_MTSASEXTENSIONS,
+        MACROTYPE_MTSASEXTENSIONATTRIBUTE,
+        MACROTYPE_MTSASTOKEN,
+        MACROTYPE_MTSASTOKENDATA,
+        MACROTYPE_MTSASSECURITYCATEGORY,
+        MACROTYPE_ASNOBJECT,
+        MACROTYPE_ASNPORT,
+        MACROTYPE_ASNREFINE,
+        MACROTYPE_ASNABSTRACTBIND,
+        MACROTYPE_ASNABSTRACTUNBIND,
+        MACROTYPE_ASNABSTRACTOPERATION,
+        MACROTYPE_ASNABSTRACTERROR,
+        MACROTYPE_AFALGORITHM,
+        MACROTYPE_AFENCRYPTED,
+        MACROTYPE_AFPROTECTED,
+        MACROTYPE_AFSIGNATURE,
+        MACROTYPE_AFSIGNED,
+        MACROTYPE_SNMPOBJECTTYPE
+    } choiceId;
+    union MacroTypeChoiceUnion
+    {
+    struct RosOperationMacroType *rosOperation; /* [0] IMPLICIT RosOperationMacroType */
+    struct RosErrorMacroType *rosError; /* [1] IMPLICIT RosErrorMacroType */
+    struct RosBindMacroType *rosBind; /* [2] IMPLICIT RosBindMacroType */
+    struct RosBindMacroType *rosUnbind; /* [3] IMPLICIT RosBindMacroType */
+    struct RosAseMacroType *rosAse; /* [4] IMPLICIT RosAseMacroType */
+    struct RosAcMacroType *rosAc; /* [5] IMPLICIT RosAcMacroType */
+    struct MtsasExtensionMacroType *mtsasExtension; /* [6] IMPLICIT MtsasExtensionMacroType */
+    struct MtsasExtensionsMacroType *mtsasExtensions; /* [7] IMPLICIT MtsasExtensionsMacroType */
+    struct MtsasExtensionAttributeMacroType *mtsasExtensionAttribute; /* [8] IMPLICIT MtsasExtensionAttributeMacroType */
+    struct MtsasTokenMacroType *mtsasToken; /* [9] IMPLICIT MtsasTokenMacroType */
+    struct MtsasTokenDataMacroType *mtsasTokenData; /* [10] IMPLICIT MtsasTokenDataMacroType */
+    struct MtsasSecurityCategoryMacroType *mtsasSecurityCategory; /* [11] IMPLICIT MtsasSecurityCategoryMacroType */
+    struct AsnObjectMacroType *asnObject; /* [12] IMPLICIT AsnObjectMacroType */
+    struct AsnPortMacroType *asnPort; /* [13] IMPLICIT AsnPortMacroType */
+    AsnRefineMacroType asnRefine; /* [14] IMPLICIT AsnRefineMacroType */
+    struct AsnAbstractBindMacroType *asnAbstractBind; /* [15] IMPLICIT AsnAbstractBindMacroType */
+    struct AsnAbstractBindMacroType *asnAbstractUnbind; /* [16] IMPLICIT AsnAbstractBindMacroType */
+    struct RosOperationMacroType *asnAbstractOperation; /* [17] IMPLICIT RosOperationMacroType */
+    struct RosErrorMacroType *asnAbstractError; /* [18] IMPLICIT RosErrorMacroType */
+    struct Type *afAlgorithm; /* [19] IMPLICIT Type */
+    struct Type *afEncrypted; /* [20] IMPLICIT Type */
+    struct Type *afProtected; /* [21] IMPLICIT Type */
+    struct Type *afSignature; /* [22] IMPLICIT Type */
+    struct Type *afSigned; /* [23] IMPLICIT Type */
+    struct SnmpObjectTypeMacroType *snmpObjectType; /* [24] IMPLICIT SnmpObjectTypeMacroType */
+    } a;
+} MacroType;
+
+
+
+
+typedef struct AnyDefinedByType /* SEQUENCE */
+{
+    MyString fieldName; /* MyString */
+    struct NamedType *link; /* NamedType OPTIONAL */
+} AnyDefinedByType;
+
+
+
+
+typedef struct SelectionType /* SEQUENCE */
+{
+    MyString fieldName; /* MyString */
+    struct Type *typeRef; /* Type */
+    struct NamedType *link; /* NamedType OPTIONAL */
+} SelectionType;
+
+
+
+
+typedef struct NamedType /* SEQUENCE */
+{
+    MyString fieldName; /* MyString */
+    struct Type *type; /* Type */
+} NamedType;
+
+
+
+
+typedef struct TypeRef /* SEQUENCE */
+{
+    MyString typeName; /* MyString */
+    MyString moduleName; /* MyString */
+    struct Module *module; /* Module */
+    struct TypeDef *link; /* TypeDef */
+} TypeRef;
+
+
+
+
+typedef struct RosOperationMacroType /* SEQUENCE */
+{
+    struct NamedType *arguments; /* NamedType */
+    struct NamedType *result; /* NamedType */
+    TypeOrValueList *errors; /* [0] IMPLICIT TypeOrValueList OPTIONAL */
+    TypeOrValueList *linkedOps; /* [1] IMPLICIT TypeOrValueList OPTIONAL */
+} RosOperationMacroType;
+
+
+
+
+typedef struct TypeOrValue /* CHOICE */
+{
+    enum TypeOrValueChoiceId
+    {
+        TYPEORVALUE_TYPE,
+        TYPEORVALUE_VALUE
+    } choiceId;
+    union TypeOrValueChoiceUnion
+    {
+    struct Type *type; /* [0] IMPLICIT Type */
+    struct Value *value; /* [1] IMPLICIT Value */
+    } a;
+} TypeOrValue;
+
+
+
+
+typedef struct RosErrorMacroType /* SEQUENCE */
+{
+    struct NamedType *parameter; /* NamedType */
+} RosErrorMacroType;
+
+
+
+
+typedef struct RosBindMacroType /* SEQUENCE */
+{
+    struct NamedType *argument; /* NamedType */
+    struct NamedType *result; /* NamedType */
+    struct NamedType *error; /* NamedType */
+} RosBindMacroType;
+
+
+
+
+typedef struct RosAseMacroType /* SEQUENCE */
+{
+    ValueList *operations; /* ValueList */
+    ValueList *consumerInvokes; /* ValueList */
+    ValueList *supplierInvokes; /* ValueList */
+} RosAseMacroType;
+
+
+
+
+typedef struct RosAcMacroType /* SEQUENCE */
+{
+    ValueList *nonRoElements; /* ValueList */
+    struct Type *bindMacroType; /* Type */
+    struct Type *unbindMacroType; /* Type */
+    struct Value *remoteOperations; /* Value */
+    ValueList *operationsOf; /* ValueList */
+    ValueList *initiatorConsumerOf; /* ValueList */
+    ValueList *responderConsumerOf; /* ValueList */
+    OidList *abstractSyntaxes; /* OidList */
+} RosAcMacroType;
+
+
+
+
+typedef struct MtsasExtensionMacroType /* SEQUENCE */
+{
+    struct NamedType *elmtType; /* [0] IMPLICIT NamedType OPTIONAL */
+    struct Value *defaultValue; /* [1] IMPLICIT Value OPTIONAL */
+    AsnBool *criticalForSubmission; /* [2] IMPLICIT BOOLEAN OPTIONAL */
+    AsnBool *criticalForTransfer; /* [3] IMPLICIT BOOLEAN OPTIONAL */
+    AsnBool *criticalForDelivery; /* [4] IMPLICIT BOOLEAN OPTIONAL */
+} MtsasExtensionMacroType;
+
+
+
+
+typedef struct MtsasExtensionsMacroType /* SEQUENCE */
+{
+    ValueList *extensions; /* ValueList */
+} MtsasExtensionsMacroType;
+
+
+
+
+typedef struct MtsasExtensionAttributeMacroType /* SEQUENCE */
+{
+    struct Type *type; /* Type OPTIONAL */
+} MtsasExtensionAttributeMacroType;
+
+
+
+
+typedef struct MtsasTokenMacroType /* SEQUENCE */
+{
+    struct Type *type; /* Type OPTIONAL */
+} MtsasTokenMacroType;
+
+
+
+
+typedef struct MtsasTokenDataMacroType /* SEQUENCE */
+{
+    struct Type *type; /* Type OPTIONAL */
+} MtsasTokenDataMacroType;
+
+
+
+
+typedef struct MtsasSecurityCategoryMacroType /* SEQUENCE */
+{
+    struct Type *type; /* Type OPTIONAL */
+} MtsasSecurityCategoryMacroType;
+
+
+
+
+typedef struct AsnObjectMacroType /* SEQUENCE */
+{
+    AsnPortList *ports; /* AsnPortList OPTIONAL */
+} AsnObjectMacroType;
+
+
+
+
+typedef struct AsnPort /* SEQUENCE */
+{
+    struct Value *portValue; /* Value */
+    AsnPortEnum portType; /* AsnPortEnum */
+} AsnPort;
+
+
+
+
+typedef struct AsnPortMacroType /* SEQUENCE */
+{
+    TypeOrValueList *abstractOps; /* [0] IMPLICIT TypeOrValueList OPTIONAL */
+    TypeOrValueList *consumerInvokes; /* [1] IMPLICIT TypeOrValueList OPTIONAL */
+    TypeOrValueList *supplierInvokes; /* [2] IMPLICIT TypeOrValueList OPTIONAL */
+} AsnPortMacroType;
+
+
+
+
+typedef struct AsnAbstractBindMacroType /* SEQUENCE */
+{
+    AsnPortList *ports; /* [0] IMPLICIT AsnPortList OPTIONAL */
+    struct Type *type; /* [1] IMPLICIT Type OPTIONAL */
+} AsnAbstractBindMacroType;
+
+
+
+
+typedef struct SnmpObjectTypeMacroType /* SEQUENCE */
+{
+    struct Type *syntax; /* Type */
+    SnmpObjectTypeMacroTypeEnum access; /* SnmpObjectTypeMacroTypeEnum */
+    SnmpObjectTypeMacroTypeEnum1 status; /* SnmpObjectTypeMacroTypeEnum1 */
+    struct Value *description; /* [0] IMPLICIT Value OPTIONAL */
+    struct Value *reference; /* [1] IMPLICIT Value OPTIONAL */
+    TypeOrValueList *index; /* [2] IMPLICIT TypeOrValueList OPTIONAL */
+    struct Value *defVal; /* [3] IMPLICIT Value OPTIONAL */
+} SnmpObjectTypeMacroType;
+
+
+
+
+typedef struct Subtype /* CHOICE */
+{
+    enum SubtypeChoiceId
+    {
+        SUBTYPE_SINGLE,
+        SUBTYPE_AND,
+        SUBTYPE_OR,
+        SUBTYPE_NOT
+    } choiceId;
+    union SubtypeChoiceUnion
+    {
+    struct SubtypeValue *single; /* [0] SubtypeValue */
+    SubtypeList *and; /* [1] IMPLICIT SubtypeList */
+    SubtypeList *or; /* [2] IMPLICIT SubtypeList */
+    struct Subtype *not; /* [3] Subtype */
+    } a;
+} Subtype;
+
+
+
+
+typedef struct SubtypeValue /* CHOICE */
+{
+    enum SubtypeValueChoiceId
+    {
+        SUBTYPEVALUE_SINGLEVALUE,
+        SUBTYPEVALUE_CONTAINED,
+        SUBTYPEVALUE_VALUERANGE,
+        SUBTYPEVALUE_PERMITTEDALPHABET,
+        SUBTYPEVALUE_SIZECONSTRAINT,
+        SUBTYPEVALUE_INNERSUBTYPE
+    } choiceId;
+    union SubtypeValueChoiceUnion
+    {
+    struct Value *singleValue; /* [0] IMPLICIT Value */
+    struct Type *contained; /* [1] IMPLICIT Type */
+    struct ValueRangeSubtype *valueRange; /* [2] IMPLICIT ValueRangeSubtype */
+    struct Subtype *permittedAlphabet; /* [3] Subtype */
+    struct Subtype *sizeConstraint; /* [4] Subtype */
+    struct InnerSubtype *innerSubtype; /* [5] IMPLICIT InnerSubtype */
+    } a;
+} SubtypeValue;
+
+
+
+
+typedef struct ValueRangeSubtype /* SEQUENCE */
+{
+    AsnBool lowerEndInclusive; /* BOOLEAN */
+    AsnBool upperEndInclusive; /* BOOLEAN */
+    struct Value *lowerEndValue; /* Value */
+    struct Value *upperEndValue; /* Value */
+} ValueRangeSubtype;
+
+
+
+
+typedef struct InnerSubtype /* SEQUENCE */
+{
+    InnerSubtypeEnum constraintType; /* InnerSubtypeEnum */
+    ConstraintList *constraints; /* ConstraintList */
+} InnerSubtype;
+
+
+
+
+typedef struct Constraint /* SEQUENCE */
+{
+    MyString fieldRef; /* MyString */
+    ConstraintEnum presenceConstraint; /* ConstraintEnum */
+    struct Subtype *valueConstraints; /* Subtype */
+} Constraint;
+
+
+
+
+typedef struct ValueDef /* SEQUENCE */
+{
+    AsnBool exported; /* BOOLEAN */
+    MyString definedName; /* MyString */
+    struct Value *value; /* Value */
+} ValueDef;
+
+
+
+
+typedef struct Value /* SEQUENCE */
+{
+    struct Type *type; /* Type OPTIONAL */
+    AsnInt valueType; /* INTEGER */
+    struct BasicValue *basicValue; /* BasicValue */
+    AsnInt lineNo; /* INTEGER */
+} Value;
+
+
+
+
+typedef struct BasicValue /* CHOICE */
+{
+    enum BasicValueChoiceId
+    {
+        BASICVALUE_UNKNOWN,
+        BASICVALUE_EMPTY,
+        BASICVALUE_INTEGER,
+        BASICVALUE_SPECIALINTEGER,
+        BASICVALUE_LONGINTEGER,
+        BASICVALUE_BOOLEAN,
+        BASICVALUE_REAL,
+        BASICVALUE_SPECIALREAL,
+        BASICVALUE_ASCIITEXT,
+        BASICVALUE_ASCIIHEX,
+        BASICVALUE_ASCIIBITSTRING,
+        BASICVALUE_OID,
+        BASICVALUE_LINKEDOID,
+        BASICVALUE_BERVALUE,
+        BASICVALUE_PERVALUE,
+        BASICVALUE_NAMEDVALUE,
+        BASICVALUE_NULL,
+        BASICVALUE_LOCALVALUEREF,
+        BASICVALUE_IMPORTVALUEREF,
+        BASICVALUE_VALUENOTATION
+    } choiceId;
+    union BasicValueChoiceUnion
+    {
+    AsnNull unknown; /* [0] IMPLICIT NULL */
+    AsnNull empty; /* [1] IMPLICIT NULL */
+    AsnInt integer; /* [2] IMPLICIT INTEGER */
+    SpecialIntegerValue specialInteger; /* [3] IMPLICIT SpecialIntegerValue */
+    AsnInt longInteger; /* [4] IMPLICIT INTEGER */
+    AsnBool boolean; /* [5] IMPLICIT BOOLEAN */
+    AsnReal real; /* [6] IMPLICIT REAL */
+    SpecialRealValue specialReal; /* [7] IMPLICIT SpecialRealValue */
+    AsnOcts *asciiText; /* [8] IMPLICIT OCTET STRING */
+    AsnOcts *asciiHex; /* [9] IMPLICIT OCTET STRING */
+    AsnOcts *asciiBitString; /* [10] IMPLICIT OCTET STRING */
+    AsnOid *oid; /* [11] IMPLICIT OBJECT IDENTIFIER */
+    OID *linkedOid; /* [12] IMPLICIT OBJECT IDENTIFIER */
+    AsnOcts *berValue; /* [13] IMPLICIT OCTET STRING */
+    AsnOcts *perValue; /* [14] IMPLICIT OCTET STRING */
+    struct NamedValue *namedValue; /* [15] IMPLICIT NamedValue */
+    AsnNull null; /* [16] IMPLICIT NULL */
+    struct ValueRef *localValueRef; /* [17] IMPLICIT ValueRef */
+    struct ValueRef *importValueRef; /* [18] IMPLICIT ValueRef */
+    AsnOcts *valueNotation; /* [19] IMPLICIT OCTET STRING */
+    } a;
+} BasicValue;
+
+
+
+
+typedef struct ValueRef /* SEQUENCE */
+{
+    MyString valueName; /* MyString */
+    MyString moduleName; /* MyString */
+    struct ValueDef *link; /* ValueDef */
+    struct Module *module; /* Module */
+} ValueRef;
+
+
+
+
+typedef struct NamedValue /* SEQUENCE */
+{
+    MyString fieldName; /* MyString */
+    struct Value *value; /* Value */
+} NamedValue;
+
+
+
+
+typedef AsnList ModuleList; /* SEQUENCE OF Module */
+
+
+
+
+typedef struct Modules /* [APPLICATION 0] IMPLICIT SEQUENCE */
+{
+    AsnInt creationTime; /* INTEGER */
+    ModuleList *modules; /* ModuleList */
+} Modules;
+
+
+
+
+typedef AsnList NamedValueList; /* SEQUENCE OF NamedValue */
+
+
+typedef struct CTDI /* SEQUENCE */
+{
+    enum BasicTypeChoiceId asn1TypeId; /* INTEGER */
+    CTypeId cTypeId; /* CTypeId */
+    MyString cTypeName; /* MyString */
+    AsnBool isPdu; /* BOOLEAN */
+    AsnBool isEncDec; /* BOOLEAN */
+    AsnBool isPtrForTypeDef; /* BOOLEAN */
+    AsnBool isPtrForTypeRef; /* BOOLEAN */
+    AsnBool isPtrInChoice; /* BOOLEAN */
+    AsnBool isPtrForOpt; /* BOOLEAN */
+    MyString optTestRoutineName; /* MyString */
+    MyString defaultFieldName; /* MyString */
+    MyString printRoutineName; /* MyString */
+    MyString encodeRoutineName; /* MyString */
+    MyString decodeRoutineName; /* MyString */
+    MyString freeRoutineName; /* MyString */
+    AsnBool genPrintRoutine; /* BOOLEAN */
+    AsnBool genEncodeRoutine; /* BOOLEAN */
+    AsnBool genDecodeRoutine; /* BOOLEAN */
+    AsnBool genFreeRoutine; /* BOOLEAN */
+    AsnBool genTypeDef; /* BOOLEAN */
+} CTDI;
+
+
+
+
+typedef struct CNamedElmt /* SEQUENCE */
+{
+    MyString name; /* MyString */
+    AsnInt value; /* INTEGER */
+} CNamedElmt;
+
+
+
+
+typedef struct CxxTDI /* SEQUENCE */
+{
+    enum BasicTypeChoiceId asn1TypeId; /* INTEGER */
+    MyString className; /* MyString */
+    AsnBool isPdu; /* BOOLEAN */
+    AsnBool isEnc; /* BOOLEAN */
+    AsnBool isPtrForTypeDef; /* BOOLEAN */
+    AsnBool isPtrForOpt; /* BOOLEAN */
+    AsnBool isPtrInChoice; /* BOOLEAN */
+    AsnBool isPtrInSetAndSeq; /* BOOLEAN */
+    AsnBool isPtrInList; /* BOOLEAN */
+    MyString optTestRoutineName; /* MyString */
+    MyString defaultFieldName; /* MyString */
+} CxxTDI;
+
+typedef struct IDLTDI /* SEQUENCE */
+{
+    enum BasicTypeChoiceId asn1TypeId; /* INTEGER */
+    MyString typeName; /* MyString */
+    AsnBool isPdu; /* BOOLEAN */
+    AsnBool isEnc; /* BOOLEAN */
+    AsnBool isPtrForTypeDef; /* BOOLEAN */
+    AsnBool isPtrForOpt; /* BOOLEAN */
+    AsnBool isPtrInChoice; /* BOOLEAN */
+    AsnBool isPtrInSetAndSeq; /* BOOLEAN */
+    AsnBool isPtrInList; /* BOOLEAN */
+    MyString optTestRoutineName; /* MyString */
+    MyString defaultFieldName; /* MyString */
+} IDLTDI;
+
+
+
+
+typedef AsnList CNamedElmts; /* SEQUENCE OF CNamedElmt */
+
+
+
+
+typedef struct CxxTRI /* SEQUENCE */
+{
+    AsnBool isEnc; /* BOOLEAN */
+    MyString className; /* MyString */
+    MyString fieldName; /* MyString */
+    AsnBool isPtr; /* BOOLEAN */
+    CNamedElmts *namedElmts; /* CNamedElmts */
+    MyString choiceIdSymbol; /* MyString */
+    AsnInt choiceIdValue; /* INTEGER */
+    MyString optTestRoutineName; /* MyString */
+} CxxTRI;
+
+typedef struct IDLTRI /* SEQUENCE */
+{
+    AsnBool isEnc; /* BOOLEAN */
+    MyString typeName; /* MyString */
+    MyString fieldName; /* MyString */
+    AsnBool isPtr; /* BOOLEAN */
+    CNamedElmts *namedElmts; /* CNamedElmts */
+    MyString choiceIdSymbol; /* MyString */
+    AsnInt choiceIdValue; /* INTEGER */
+    MyString optTestRoutineName; /* MyString */
+} IDLTRI;
+
+
+
+
+typedef struct CTRI /* SEQUENCE */
+{
+    CTypeId cTypeId; /* CTypeId */
+    MyString cFieldName; /* MyString */
+    MyString cTypeName; /* MyString */
+    AsnBool isPtr; /* BOOLEAN */
+    CNamedElmts *cNamedElmts; /* CNamedElmts OPTIONAL */
+    AsnInt choiceIdValue; /* INTEGER */
+    MyString choiceIdSymbol; /* MyString */
+    MyString choiceIdEnumName; /* MyString */
+    MyString choiceIdEnumFieldName; /* MyString */
+    MyString optTestRoutineName; /* MyString */
+    MyString printRoutineName; /* MyString */
+    MyString encodeRoutineName; /* MyString */
+    MyString decodeRoutineName; /* MyString */
+    MyString freeRoutineName; /* MyString */
+    AsnBool isEncDec; /* BOOLEAN */
+} CTRI;
+
+
+
+#endif /* conditional include of asn1module.h */
diff --git a/SecuritySNACCRuntime/compiler/core/define.c b/SecuritySNACCRuntime/compiler/core/define.c
new file mode 100644
index 00000000..0ccfc97b
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/define.c
@@ -0,0 +1,220 @@
+/*
+ * compiler/core/define.c - keeps a list of things that have been defined
+ *            and provided means for checking if something has been
+ *            defined
+ *
+ * MS 92
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/define.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: define.c,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:46  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1997/10/10 13:43:15  wan
+ * Corrected bug in generic table decoder wrt. indefinite length elements
+ * Corrected compiler access to freed memory (bug reported by Markku Savela)
+ * Broke asnwish.c into two pieces so that one can build ones on wish
+ * Added beredit tool (based on asnwish, allowes to edit BER messages)
+ *
+ * Revision 1.3  1995/07/25 19:41:21  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:27:38  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:48:58  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "define.h"
+
+/* for CompareOids from snacc_util.c*/
+int CompareOids PROTO ((OID *oid1, OID *oid2));
+
+
+/* cmp routine for a null terminated string object type */
+int
+StrObjCmp PARAMS ((s1, s2),
+    void *s1 _AND_
+    void *s2)
+{
+    if (strcmp ((char*)s1, (char*) s2) == 0)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+/* cmp routine for a integer object type */
+int
+IntObjCmp PARAMS ((s1, s2),
+    void *s1 _AND_
+    void *s2)
+{
+    if (*((int*) s1) == *((int*) s2))
+        return TRUE;
+    else
+        return FALSE;
+}
+
+
+/* cmp routine for a OID object type */
+int
+OidObjCmp PARAMS ((o1, o2),
+    void *o1 _AND_
+    void *o2)
+{
+    return CompareOids ((OID*)o1, (OID*)o2);
+}
+
+/* special cmp routine - compares the pointers themselves */
+int
+ObjPtrCmp PARAMS ((s1, s2),
+    void *s1 _AND_
+    void *s2)
+{
+    if (s1 == s2)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+
+DefinedObj*
+NewObjList()
+{
+    return NULL;
+}
+
+/*
+ * puts the given object into the give object list
+ * does not check for duplicates - you should do that
+ * before calling this - if you care.
+ */
+void
+DefineObj PARAMS ((objListHndl, obj),
+    DefinedObj **objListHndl _AND_
+    void *obj)
+{
+    DefinedObj *new;
+
+    new =  MT (DefinedObj);
+    new->obj = obj;
+
+    /* insert new one at head */
+    new->next = *objListHndl;
+    *objListHndl = new;
+
+}  /* DefineObj */
+
+
+/*
+ * removes the first identical object from the list
+ * - if you are allowing duplicates use another routine.
+ *   this only removes the first for efficiency reasons - all
+ *   current usage of the DefineObj stuff does not allow duplicates.
+ */
+void
+UndefineObj PARAMS ((objListHndl, obj, cmpRoutine),
+    DefinedObj **objListHndl _AND_
+    void *obj _AND_
+    CmpObjsRoutine cmpRoutine)
+{
+    DefinedObj *objListPtr;
+    DefinedObj **prevHndl;
+
+    objListPtr = *objListHndl;
+
+    prevHndl = objListHndl;
+    for ( ; objListPtr != NULL; objListPtr = *prevHndl)
+    {
+        if (cmpRoutine (objListPtr->obj, obj))
+        {
+            /* found object, now remove it */
+            *prevHndl = objListPtr->next;
+            Free (objListPtr);
+        }
+        else
+            prevHndl = &objListPtr->next;
+    }
+
+}  /* UndefineObj */
+
+
+/*
+ * given an object list, an object and an object comparison routine,
+ * ObjIsDefined returns non-zero if the given object is already in
+ * the object list.  The comparison routine should take two objects and
+ * return non-zero if the objects are equivalent
+ */
+int
+ObjIsDefined PARAMS ((objListPtr, obj, cmpRoutine),
+    DefinedObj *objListPtr _AND_
+    void *obj _AND_
+    CmpObjsRoutine cmpRoutine)
+{
+    for ( ; objListPtr != NULL; objListPtr = objListPtr->next)
+    {
+        if (cmpRoutine (objListPtr->obj, obj))
+            return TRUE;
+    }
+    return FALSE;
+
+}  /* ObjIsDefined */
+
+/*
+ * Frees the list holding the defined objects.
+ * Does not free the objects.
+ */
+void
+FreeDefinedObjs PARAMS ((objListHndl),
+    DefinedObj **objListHndl)
+{
+    DefinedObj *dO;
+    DefinedObj *tmpDO;
+
+    for (dO = *objListHndl; dO != NULL; )
+    {
+        tmpDO = dO->next;
+        Free (dO);
+        dO = tmpDO;
+    }
+    *objListHndl = NULL;
+
+}  /* FreeDefinedObjs */
+
+
+
+/*
+ * Frees the list holding the defined objects.
+ * Does free the objects.
+ */
+void
+FreeDefinedObjsAndContent PARAMS ((objListHndl),
+    DefinedObj **objListHndl)
+{
+    DefinedObj *dO;
+    DefinedObj *tmpDO;
+
+    for (dO = *objListHndl; dO != NULL; )
+    {
+        tmpDO = dO->next;
+        Free (dO->obj);
+        Free (dO);
+        dO = tmpDO;
+    }
+    *objListHndl = NULL;
+
+}  /* FreeDefinedObjs */
diff --git a/SecuritySNACCRuntime/compiler/core/define.h b/SecuritySNACCRuntime/compiler/core/define.h
new file mode 100644
index 00000000..c32e45ba
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/define.h
@@ -0,0 +1,57 @@
+/*
+ * compiler/core/define.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/define.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: define.h,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:46  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1994/10/08 03:48:35  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:48:59  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+typedef struct DefinedObj
+{
+    void *obj;
+    struct DefinedObj *next;
+} DefinedObj;
+
+
+typedef int (*CmpObjsRoutine) PROTO ((void *obj1, void *obj2));
+typedef int (*FreeObjRoutine) PROTO ((void *obj));
+
+int StrObjCmp PROTO ((void *s1, void *s2));
+
+int IntObjCmp PROTO ((void *s1, void *s2));
+
+int OidObjCmp PROTO ((void *o1, void *o2));
+
+int ObjPtrCmp PROTO ((void *s1, void *s2));
+
+DefinedObj  *NewObjList();
+
+void DefineObj PROTO ((DefinedObj **l, void *obj));
+
+void UndefineObj PROTO ((DefinedObj **l, void *obj, CmpObjsRoutine cmpRoutine));
+
+int  ObjIsDefined PROTO ((DefinedObj *l, void *obj, CmpObjsRoutine cmp));
+
+void FreeDefinedObjs PROTO ((DefinedObj **l));
+
+void FreeDefinedObjsAndContent PROTO ((DefinedObj **l));
diff --git a/SecuritySNACCRuntime/compiler/core/dependency.c b/SecuritySNACCRuntime/compiler/core/dependency.c
new file mode 100644
index 00000000..5b86a7d0
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/dependency.c
@@ -0,0 +1,750 @@
+/*
+ * compiler/core/dependency.c - sorts types/values in order of dependency.
+ *                typeDefs list is re-ordered
+ *                going from independent->dependent types
+ *
+ * this is done after all import linking is done
+ *
+ * Mike Sample
+ * 91/08/12
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/dependency.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: dependency.c,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:46  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 19:41:22  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:48:37  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:31:56  rj
+ * snacc_config.h removed; dependency.h includet.
+ *
+ * Revision 1.1  1994/08/28  09:49:00  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "snacc-util.h"
+#include "dependency.h"
+
+
+/* prototypes */
+
+void SortTypeDependencies PROTO ((Module *m));
+
+void SortInterModuleDependencies PROTO ((ModuleList *m));
+
+TypeDefList *RemoveAndSortIndependents PROTO ((TypeDefList *tdl));
+
+void SortTypeDefs PROTO ((TypeDefList *tdl));
+
+void BuildLocalRefList PROTO ((Type *t, TypeDefList *refList));
+
+void BuildWeightedLocalRefList PROTO ((Type *t, TypeDefList *refList));
+
+
+long int GetElmtIndex PROTO ((TypeDef *td, TypeDefList *tdl));
+
+/*
+void MoveAfter PROTO ((unsigned long int currIndex, unsigned long int afterIndex, AsnList *l));
+*/
+
+/*
+ * Sorts type dependencies by reodering TypeDefs linear list
+ * with least dependent types followed by dependent types
+ */
+void
+SortAllDependencies PARAMS ((modList),
+    ModuleList *modList)
+{
+    Module *m;
+
+    FOR_EACH_LIST_ELMT (m, modList)
+    {
+        SortTypeDependencies (m);
+    }
+
+/*    SortInterModuleDependencies (modList); */
+
+} /* SortAllDependencies */
+
+
+/*
+ * This attempts to sort the types in order of dependency
+ * (least dependent --> dependent)
+ *
+ *  This should only be called after the CTypeInfo or CxxTypeInfo
+ *  has been added to the  types.
+ *    (the isPtr field is used to help determine ordering)
+ *
+ *  Algorithm: (wierd!)
+ *
+ *  First separte the ASN.1 type defs into 4 separate groups
+ *
+ *    1. Type defs that are defined directly from primitive/library types
+ *         eg Foo ::= INTEGER {one (1), two (2) }
+ *
+ *    2. Type defs reference no local types in a way that needs a
+ *       forward decl. of the ref'd type (ie ptr refs)
+ *
+ *    3. Type defs that reference local types in a way that needs
+ *       a previous decl of the ref'd type (ie non ptr refs for SET/SEQ
+ *       elmts)
+ *
+ *    4. Type defs that are not referenced by any local types
+ *       (hence no local types depend on them so they can go last)
+ *
+ *
+ *  The type defs in group 3 are further sorted by the SortTypeDefs routine
+ *
+ *  Then all of the groups are merged in the order 1-2-3-4.
+ *
+ * Some wierd recursive types might cause problems...
+ *
+ *
+ * MS 92
+ */
+void
+SortTypeDependencies PARAMS ((m),
+    Module *m)
+{
+    TypeDef *curr;
+    TypeDefList *prims;
+    TypeDefList *noRefs;
+    TypeDefList *refs;
+    TypeDefList *notRefd;
+    TypeDef **newElmtHndl;
+
+    prims = AsnListNew (sizeof (void*));
+    noRefs = AsnListNew (sizeof (void*));
+    refs = AsnListNew (sizeof (void*));
+    notRefd = AsnListNew (sizeof (void*));
+
+    /* put each TypeDef in the appropriate list (1-4)*/
+    FOR_EACH_LIST_ELMT (curr, m->typeDefs)
+    {
+        if (IsDefinedByLibraryType (curr->type))
+            newElmtHndl = (TypeDef**) AsnListAppend (prims);
+
+        else if (curr->localRefCount == 0)
+            newElmtHndl = (TypeDef**) AsnListAppend (notRefd);
+
+        else
+        {
+            /* get list of local types that this type def refs */
+            curr->refList = AsnListNew (sizeof (void*));
+            BuildLocalRefList (curr->type, curr->refList);
+
+            if (LIST_EMPTY (curr->refList))
+            {
+                newElmtHndl = (TypeDef**) AsnListAppend (noRefs);
+                Free (curr->refList);
+                curr->refList = NULL;
+            }
+            else
+                newElmtHndl = (TypeDef**) AsnListAppend (refs);
+        }
+
+        *newElmtHndl = curr;
+    }
+
+    /* sort problem types */
+    SortTypeDefs (refs);
+
+    /* free refList space */
+    FOR_EACH_LIST_ELMT (curr, refs)
+    {
+        if (curr->refList != NULL)
+        {
+            AsnListFree (curr->refList);
+            curr->refList = NULL;
+        }
+    }
+
+    /*
+     * combine the typdef lists with the prims followed by the
+     * types that don't reference other types
+     * then prims, followed by composite types
+     */
+    prims = AsnListConcat (prims, noRefs);
+    prims = AsnListConcat (prims, refs);
+    prims = AsnListConcat (prims, notRefd);
+
+    AsnListFree (m->typeDefs);
+    Free (noRefs);
+    Free (refs);
+    Free (notRefd);
+
+    m->typeDefs = prims;
+
+} /* SortTypeDependencies */
+
+
+
+
+/*
+ * Attempt to sort modules in order of "depends on none" to
+ * "depends on all" where a dependency is caused by importing
+ * from another module.
+ * cyclic dependencies are a pain
+ */
+/*
+ *  Not implemented yet... perhaps best left in user's hands
+ *  ie set it by the cmd line order
+ */
+/*
+void
+SortInterModuleDependencies PARAMS ((m),
+    ModuleList *m)
+{
+
+}  SortInterModuleDependencies */
+
+
+
+/*
+ * Given a non-empty TypeDef list, the refLists of TypeDefs
+ * are used to divide the list into two lists, one list
+ * that is sorted the order of dependency (independed-->dependent)
+ * and the other list contains types that are mutually dependent
+ * (recursive or depend on recursive types)
+ * The sorted list is returned and the passed in list has those
+ * TypeDefs that are now in the sorted list removed.
+ */
+TypeDefList*
+RemoveAndSortIndependents PARAMS ((tdl),
+    TypeDefList *tdl)
+{
+    TypeDef *last;
+    TypeDef *currTd;
+    TypeDef **tdHndl;
+    TypeDef *tdRef;
+    AsnListNode *nextListNode;
+    long int tdIndex;
+    long int lastSLCount;
+    TypeDefList *subList;
+    int keep;
+
+    /*
+     * iterate through the list making sub lists that don't depend
+     * on the others in the active list.  Join sub lists in order
+     * and then deal with the active list if any
+     */
+    lastSLCount = -1; /* just to start */
+    subList = AsnListNew (sizeof (void*));
+
+    if (LIST_EMPTY (tdl))
+        return subList;
+
+    /* iterate through each type def in the tdl */
+    while ((LIST_COUNT (subList) > lastSLCount) && !LIST_EMPTY (tdl))
+    {
+        lastSLCount = LIST_COUNT (subList);
+        last = (TypeDef*)LAST_LIST_ELMT (tdl);
+        SET_CURR_LIST_NODE (tdl, FIRST_LIST_NODE (tdl));
+        currTd = (TypeDef*)CURR_LIST_ELMT (tdl);
+        while (1)
+        {
+            nextListNode = NEXT_LIST_NODE (tdl);
+            keep = 0;
+
+            /*
+             * iterate through this type def's local type refs.
+             *
+             * if any type def in the current type's local type ref list
+             * is in the tdl, then teh current type must remain in the tdl
+             * because it depends on that type.
+             */
+            FOR_EACH_LIST_ELMT (tdRef, currTd->refList)
+            {
+                /* don't worry about recursive refs to self */
+                if (tdRef != currTd)
+                {
+                    /*
+                     * if the tdRef is not in tdl
+                     * GetElmtIndex will return < 0
+                     * if the tdRef is in the tdl, then the
+                     * currTd must remain in the tdl.
+                     */
+                    tdIndex = GetElmtIndex (tdRef, tdl);
+                    if (tdIndex >= 0)
+                        keep = 1;
+                }
+            }
+            if (!keep)
+            {
+                /* append to sublist and remove for tdl */
+                tdHndl = (TypeDef**) AsnListAppend (subList);
+                *tdHndl = currTd;
+                AsnListRemove (tdl);
+            }
+            if (currTd == last)
+                break; /* exit while */
+
+            SET_CURR_LIST_NODE (tdl, nextListNode);
+            currTd = (TypeDef*)CURR_LIST_ELMT (tdl);
+        }
+    }
+    return subList;
+
+} /* RemoveAndSortIndependents */
+
+
+/*
+ * Given a list of types that depend on each other, this attempts
+ * to sort the list from independent--> most dependent.
+ *
+ * Kind of wierd algorithm
+ *  1. first separate and sort out linearly dependent types and place in
+ *     a properly ordered list (RemoveAndSortIndependents) (call it "A")
+ *
+ *  2. if types with non-linear (recursive) dependencies remain,
+ *     divide them into two groups, recursive (call it "B")(see recursive.c)
+ *     and non-recursive (call it "C".  The non-recursive ones will depend
+ *     on the recursive ones (otherwise step 1 would have grabbed 'em).
+ *
+ *  3. Sort the types in list C as done in step one - there should be
+ *     no problems (ie unsorted leftovers) since none of them are recursive.
+ *
+ *  4. For the recursive types in list B, re-do their refLists such that
+ *     any types ref'd by a Ptr are not included in the refList
+ *     (may have to update this wrt how the ref is used -
+ *         eg in an inline of the ref'ing type).  Then sort as in Step 1.
+ *     Any types that could not be sorted have a definite problem and
+ *     compiliation problems will occur. (.. And the code generation
+ *     technique must be changed)
+ *     (for C only the SET OF and SEQ OF Types are stripped from this
+ *     since they are 'generic' - ie don't depend on the list elmt type)
+ *
+ *   5. re-combine all of the lists in order of dependency ie
+ *      A-B-(B's leftovers)-C
+ *
+ *     (the stripped C lists go after 'A')
+ */
+void
+SortTypeDefs PARAMS ((tdl),
+    TypeDefList *tdl)
+{
+    TypeDef *last;
+    TypeDef *currTd;
+    TypeDef **tdHndl;
+    TypeDef *tmpTd;
+    TypeDef *tdRef;
+    AsnListNode *tdNodeToMove;
+    AsnListNode *nextListNode;
+    long int maxRefCount;
+    TypeDefList *subList;  /* "A" */
+    TypeDefList *nonRec;
+    TypeDefList *sortedRec;  /* "B" */
+    TypeDefList *sortedNonRec; /* "C" */
+    TypeDefList *cLists;
+
+    if ((tdl == NULL) || (LIST_EMPTY (tdl)))
+        return;
+
+    subList = RemoveAndSortIndependents (tdl);
+
+    /* return if simple sort worked (no recursive types) */
+    if (LIST_EMPTY (tdl))
+    {
+        *tdl = *subList;
+        Free (subList);
+        return;
+    }
+
+    /*
+     * divide the remaining interdepedent types into
+     * two groups recursive and non-recursive.
+     * leave the recursive in the tdl and put the others in a new list.
+     * The non-recursive ones obviously depend on the recursive
+     * on since all of the simple type dependencies have been
+     * dealt with by RemoveAndSortIndependents
+     */
+    last = (TypeDef*)LAST_LIST_ELMT (tdl);
+    SET_CURR_LIST_NODE (tdl, FIRST_LIST_NODE (tdl));
+    currTd = (TypeDef*)CURR_LIST_ELMT (tdl);
+    nonRec = AsnListNew (sizeof (void*));
+
+    while (1)
+    {
+        nextListNode = NEXT_LIST_NODE (tdl);
+
+        if (!currTd->recursive)
+        {
+            tdHndl = (TypeDef**)AsnListAppend (nonRec);
+            *tdHndl = currTd;
+            AsnListRemove (tdl);
+        }
+
+        if (currTd == last)
+            break; /* exit while */
+
+        SET_CURR_LIST_NODE (tdl, nextListNode);
+        currTd = (TypeDef*)CURR_LIST_ELMT (tdl);
+    }
+
+    /* sort the non-recusive types */
+    sortedNonRec = RemoveAndSortIndependents (nonRec);
+
+    if (!LIST_EMPTY (nonRec))
+    {
+        fprintf (stderr,"SortTypeDefs: internal compiler error - non recursive type defs failed sort.\n");
+        sortedNonRec = AsnListConcat (sortedNonRec, nonRec);
+    }
+    Free (nonRec);
+
+    /*
+     * Remove list types from the list since they are generic.
+     * put them in "cLists".
+     * then re-do the dependency list for each type definition that
+     * remain in the recursive list with weighting - ie types
+     * that are ref'd as ptrs don't count. Then re-sort.
+     */
+    last = (TypeDef*)LAST_LIST_ELMT (tdl);
+    SET_CURR_LIST_NODE (tdl, FIRST_LIST_NODE (tdl));
+    currTd = (TypeDef*)CURR_LIST_ELMT (tdl);
+
+    cLists = AsnListNew (sizeof (void*));
+    while (1)
+    {
+        nextListNode = NEXT_LIST_NODE (tdl);
+
+        /* nuke old ref list */
+        AsnListFree (currTd->refList);
+        currTd->refList = NULL;
+
+        /* for C only, remove lists since they are generic */
+        if ((currTd->cTypeDefInfo != NULL) &&
+            ((currTd->type->basicType->choiceId == BASICTYPE_SETOF) ||
+             (currTd->type->basicType->choiceId == BASICTYPE_SEQUENCEOF)))
+        {
+            tdHndl = (TypeDef**)AsnListAppend (cLists);
+            *tdHndl = currTd;
+            AsnListRemove (tdl);
+        }
+
+        if (currTd == last)
+            break; /* exit while */
+
+        SET_CURR_LIST_NODE (tdl, nextListNode);
+        currTd = (TypeDef*)CURR_LIST_ELMT (tdl);
+    }
+
+
+
+    FOR_EACH_LIST_ELMT (currTd, tdl)
+    {
+        currTd->refList = AsnListNew (sizeof (void*));
+        BuildWeightedLocalRefList (currTd->type, currTd->refList);
+    }
+
+    sortedRec = RemoveAndSortIndependents (tdl);
+
+    /*
+     * now merge subLists and put in tdl:
+     *  tdl = cLists + sortedRec + impossible rec in tdl  + sorted nonRec
+     */
+    subList = AsnListConcat (subList, cLists);
+    subList = AsnListConcat (subList, sortedRec);
+    subList = AsnListConcat (subList, tdl);
+    subList = AsnListConcat (subList, sortedNonRec);
+    *tdl = *subList;
+
+    Free (cLists);
+    Free (subList);
+    Free (sortedRec);
+    Free (sortedNonRec);
+
+}  /* SortTypeDefs */
+
+
+
+
+/*
+ * Builds list of TypeDefs in this module that the given type refs.
+ * Does not follow type refs to include their type refs.
+ */
+void
+BuildLocalRefList PARAMS ((t, refList),
+    Type *t _AND_
+    TypeDefList *refList)
+{
+    NamedType *e;
+    TypeDef **tdHndl;
+
+    switch (t->basicType->choiceId)
+    {
+        case BASICTYPE_CHOICE:
+        case BASICTYPE_SET:
+        case BASICTYPE_SEQUENCE:
+            FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
+            {
+                BuildLocalRefList (e->type, refList);
+            }
+            break;
+
+        case BASICTYPE_SETOF:
+        case BASICTYPE_SEQUENCEOF:
+            BuildLocalRefList (t->basicType->a.setOf, refList);
+            break;
+
+       case BASICTYPE_LOCALTYPEREF:
+            tdHndl = (TypeDef**)AsnListAppend (refList);
+            *tdHndl = t->basicType->a.localTypeRef->link;
+            break;
+
+        /*
+         * default: other types are not aggregate and
+         * and can be ignored
+         */
+    }
+} /* BuildLocalRefList */
+
+
+/*
+ * Builds list of TypeDefs in this module that the given type references.
+ * Does not follow type refs to include their type refs.
+ * Does not include types that are ref'd as ptrs since
+ * If the target lang is C the type SET OF/SEQ OF types reference
+ * are not counted due to the current 'genericness' of the C list type
+ * (it doesn't need type info)
+ * they shouldn't affect type ordering.
+ */
+void
+BuildWeightedLocalRefList PARAMS ((t, refList),
+    Type *t _AND_
+    TypeDefList *refList)
+{
+    NamedType *e;
+    TypeDef **tdHndl;
+
+    switch (t->basicType->choiceId)
+    {
+        case BASICTYPE_CHOICE:
+        case BASICTYPE_SET:
+        case BASICTYPE_SEQUENCE:
+            FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
+            {
+                BuildWeightedLocalRefList (e->type, refList);
+            }
+            break;
+
+
+
+        case BASICTYPE_SETOF:
+        case BASICTYPE_SEQUENCEOF:
+            /*
+             * normalize makes embedded list defs into
+             * separate type defs now so this clause will
+             * not fire. (ie they will be a LOCAL_TYPEREF
+             * to the removed list type instead)
+             */
+
+            /*
+             * list types for C don't really depend on
+             * the component type (void*). So if the target lang
+             * is C then can achieve better ordering
+             * for ugly recursive defs by using this relaxation
+             * (ie not including the component type in the ref list)
+             */
+            if (t->cTypeRefInfo == NULL)
+                BuildWeightedLocalRefList (t->basicType->a.setOf, refList);
+
+            break;
+
+        case BASICTYPE_LOCALTYPEREF:
+
+            if (((t->cxxTypeRefInfo != NULL) &&
+                  !(t->cxxTypeRefInfo->isPtr)) ||
+                ((t->cTypeRefInfo != NULL) && !(t->cTypeRefInfo->isPtr)))
+            {
+                tdHndl = (TypeDef**)AsnListAppend (refList);
+                *tdHndl = t->basicType->a.localTypeRef->link;
+            }
+            break;
+
+        /*
+         * default: other types are not aggregate and
+         * and can be ignored
+         */
+    }
+} /* BuildWeightedLocalRefList */
+
+
+
+/*
+ * Returns the index (starting a 0 for the first elmt)
+ * of the given td in the td list (tdl)
+ * returns -1 if td is not in the list
+ */
+long int
+GetElmtIndex PARAMS ((td, tdl),
+    TypeDef *td _AND_
+    TypeDefList *tdl)
+{
+    void *tmp;
+    TypeDef *tmpTd;
+    long int index;
+
+    index = 0;
+    tmp = (void*) CURR_LIST_NODE (tdl);
+    FOR_EACH_LIST_ELMT (tmpTd, tdl)
+    {
+        if (tmpTd == td)
+        {
+            SET_CURR_LIST_NODE (tdl, tmp);
+            return index;
+        }
+        else
+            index++;
+    }
+
+    SET_CURR_LIST_NODE (tdl, tmp);
+    return -1;
+
+}  /* GetElmtIndex */
+
+
+
+
+
+/*
+ * Attempts to order the types in tdl from independent-->most depenedent
+ * uses insertion after TypeDef that the given type def depends on.
+ * Hoky - doesn't work very well - differing results depending on
+ * initial order
+  NO LONGER USED
+void
+AttemptDependencySort PARAMS ((tdl),
+    TypeDefList *tdl)
+{
+    TypeDef *last;
+    TypeDef *currTd;
+    TypeDef **tdHndl;
+    TypeDef *tdRef;
+    AsnListNode *nextListNode;
+    long int tdIndex;
+    long int maxTdIndex;
+    long int currIndex;
+
+    if (LIST_EMPTY (tdl))
+        return;
+
+    last = (TypeDef*)LAST_LIST_ELMT (tdl);
+
+    FOR_EACH_LIST_ELMT (currTd, tdl)
+    {
+        currTd->visited = FALSE;
+    }
+
+    SET_CURR_LIST_NODE (tdl, FIRST_LIST_NODE (tdl));
+    currTd = (TypeDef*)CURR_LIST_ELMT (tdl);
+
+    while (1)
+    {
+        nextListNode = NEXT_LIST_NODE (tdl);
+
+        if (!currTd->visited)
+        {
+            currTd->visited = TRUE;
+            maxTdIndex = -1;
+            FOR_EACH_LIST_ELMT (tdRef, currTd->refList)
+            {
+                tdIndex = GetElmtIndex (tdRef, tdl);
+                if (tdIndex > maxTdIndex)
+                    maxTdIndex = tdIndex;
+            }
+        }
+
+        currIndex = GetElmtIndex (currTd, tdl);
+
+        if ((maxTdIndex >= 0) && (currIndex < maxTdIndex))
+        {
+            MoveAfter (currIndex, maxTdIndex, tdl);
+        }
+
+        if (currTd == last)
+            break;
+
+        SET_CURR_LIST_NODE (tdl, nextListNode);
+        currTd = (TypeDef*)CURR_LIST_ELMT (tdl);
+    }
+}  AttemptDependencySort */
+
+
+
+/*
+ * Moves list node at currIndex to after Node at afterIndex
+ * in the given list l.  Indexes start at 0 for the first elmt.
+ * May confuse the 'curr' pointer of the list
+  NO LONGER USED
+void
+MoveAfter PARAMS ((currIndex, afterIndex, l),
+    unsigned long int currIndex _AND_
+    unsigned long int afterIndex _AND_
+    AsnList *l)
+{
+    void *tmp;
+    AsnListNode *nodeToMove;
+    AsnListNode *afterNode;
+    int i;
+
+    if ((l == NULL) ||
+        (LIST_COUNT (l) <= currIndex) ||
+        (LIST_COUNT (l) <= afterIndex))
+    {
+        fprintf (stderr,"Internal compiler error - index confusion in MoveAfter\n");
+        return;
+    }
+
+    tmp = (void*) CURR_LIST_NODE (l);
+
+    nodeToMove = l->first;
+    for (i = 0; i < currIndex; i++)
+        nodeToMove = nodeToMove->next;
+
+    afterNode = l->first;
+    for (i = 0; i < afterIndex; i++)
+        afterNode = afterNode->next;
+
+     pop out node to move
+    if (nodeToMove->next)
+        nodeToMove->next->prev = nodeToMove->prev;
+    else
+        l->last = nodeToMove->prev;
+
+    if (nodeToMove->prev)
+        nodeToMove->prev->next = nodeToMove->next;
+    else
+        l->first = nodeToMove->next;
+
+    insert node to move after selected node
+    nodeToMove->next = afterNode->next;
+    nodeToMove->prev = afterNode;
+
+    if (afterNode->next)
+        afterNode->next->prev = nodeToMove;
+    else
+        l->last = nodeToMove;
+
+    afterNode->next = nodeToMove;
+
+} MoveAfter */
diff --git a/SecuritySNACCRuntime/compiler/core/dependency.h b/SecuritySNACCRuntime/compiler/core/dependency.h
new file mode 100644
index 00000000..6cd55910
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/dependency.h
@@ -0,0 +1,29 @@
+/*
+ * compiler/core/depedency.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/dependency.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: dependency.h,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1994/10/08 03:48:38  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:01  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+void SortAllDependencies PROTO ((ModuleList *m));
diff --git a/SecuritySNACCRuntime/compiler/core/do-macros.c b/SecuritySNACCRuntime/compiler/core/do-macros.c
new file mode 100644
index 00000000..dfed1f4b
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/do-macros.c
@@ -0,0 +1,732 @@
+/*
+ * compiler/core/do_macros.c
+ *
+ * Runs through type and value def lists and does any processing nec.
+ * for any macro encountered.
+ *
+ * Processing could consist of making stubs for OPERATION macro etc.
+ * What is done is very environment dependent.
+ *
+ * You should change this file to match your environment.
+ *
+ * Any Type Defs hidden in a MACRO Type are popped into the normal
+ * type def list and REFERENCED from the macro (instead of being
+ * defined there)
+ *
+ * SNMP Objectype macro fills the ANY Ref lists so the id to ANY
+ * type hash table is filled.
+ *
+ * Mike Sample
+ * 91/12/12
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/do-macros.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: do-macros.c,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:23  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:32:28  rj
+ * snacc_config.h removed; do_macros.h includet.
+ *
+ * Revision 1.1  1994/08/28  09:49:03  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>  /* for islower/toupper */
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "define.h"
+#include "str-util.h"
+#include "normalize.h"
+#include "snacc-util.h"
+#include "do-macros.h"
+
+void AddAnyRefByOid PROTO ((AnyRefList **arl, char *enumIdName, AsnOid *oid));
+
+void AddAnyRefByInt PROTO ((AnyRefList **arl, char *enumIdName, AsnInt intId));
+
+
+void ProcessMacrosInTypeDef PROTO ((Module *m, TypeDef *td));
+
+void ProcessMacrosInValueDef PROTO ((Module *m, ValueDef *vd));
+
+void ProcessMacrosInType PROTO ((Module *m, TypeDef *td, Type *t, ValueDef *v));
+
+void ProcessMacrosInElmtTypes PROTO ((Module *m, TypeDef *td, NamedTypeList *e, ValueDef *v));
+
+void ProcessMacrosInBasicType PROTO ((Module  *m, TypeDef *td, Type *type, BasicType *bt, ValueDef *v));
+
+void DefineType PROTO ((Module *m, TypeDef *td, Type *t, char *name));
+
+void ProcessRosOperationMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosOperationMacroType *op, ValueDef *v));
+
+void ProcessRosErrorMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosErrorMacroType *err, ValueDef *v));
+
+void ProcessRosBindMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosBindMacroType *bind, ValueDef *v));
+
+void ProcessRosAseMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosAseMacroType *ase, ValueDef *v));
+
+void ProcessRosAcMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosAcMacroType *ac, ValueDef *v));
+
+void ProcessMtsasExtensionsMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasExtensionsMacroType *exts, ValueDef *v));
+
+void ProcessMtsasExtensionMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasExtensionMacroType *ext, ValueDef *v));
+
+void ProcessMtsasExtensionAttributeMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasExtensionAttributeMacroType *ext, ValueDef *v));
+
+void ProcessMtsasTokenMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasTokenMacroType *tok, ValueDef *v));
+
+void ProcessMtsasTokenDataMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasTokenDataMacroType *tok, ValueDef *v));
+
+void ProcessMtsasSecurityCategoryMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasSecurityCategoryMacroType *sec, ValueDef *v));
+
+void ProcessAsnObjectMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, AsnObjectMacroType *obj, ValueDef *v));
+
+void ProcessAsnPortMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, AsnPortMacroType *p, ValueDef *v));
+
+void ProcessAsnAbstractBindMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, AsnAbstractBindMacroType *bind, ValueDef *v));
+
+void ProcessSnmpObjectTypeMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, SnmpObjectTypeMacroType *bind, ValueDef *v));
+
+/*
+static TypeDef  *snmpObjectSyntaxesG = NULL;
+*/
+
+/*
+ * Hunts for macros in TypeDefs or ValueDefs and
+ * might do something with them.
+ */
+void
+ProcessMacros PARAMS ((m),
+    Module *m)
+{
+    TypeDef *td;
+    TypeDef **tmpTypeDefHndl;
+    ValueDef *vd;
+
+    /*
+     * go through each type in typeList
+     */
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        ProcessMacrosInTypeDef (m, td);
+    }
+
+    /*
+     *  go through each value in valueList and link
+     */
+    FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+    {
+        ProcessMacrosInValueDef (m, vd);
+    }
+
+    /* add snmp object syntaxes choice to typedef list */
+/*
+    tmpTypeDefHndl = (TypeDef**) AsnListAppend (m->typeDefs);
+    *tmpTypeDefHndl =  snmpObjectSyntaxesG;
+    snmpObjectSyntaxesG = NULL;
+*/
+
+
+}   /* ProcessMacros */
+
+/*
+ * Given an AnyRefList, char string for an enum Id,
+ *  and an OBJECT IDENTIFIER,
+ * this routine puts the id and oid into the AnyRefList.
+ * When the code is generated, the AnyInit routine for
+ * the module to which the typeDef that owns the given AnyRefList
+ * belongs, calls a routine that will cause the given oid to
+ * hash to the TypeDef that owns the AnyRefList.
+ * The enumId value at runtime is used for simple determination of
+ * the ANY type by the user.
+ */
+void
+AddAnyRefByOid PARAMS ((arl, enumId, oid),
+    AnyRefList **arl _AND_
+    char *enumId _AND_
+    AsnOid *oid)
+{
+    AnyRef **anyRefHndl;
+
+    if (*arl == NULL)
+        *arl = AsnListNew (sizeof (void*));
+
+    anyRefHndl = (AnyRef**)AsnListAppend (*arl);
+    *anyRefHndl = MT (AnyRef);
+
+    (*anyRefHndl)->anyIdName = Malloc (strlen (enumId)+1);
+    strcpy ((*anyRefHndl)->anyIdName, enumId);
+
+    (*anyRefHndl)->id = MT (OidOrInt);
+    (*anyRefHndl)->id->choiceId = OIDORINT_OID;
+    (*anyRefHndl)->id->a.oid = MT (AsnOid);
+    (*anyRefHndl)->id->a.oid->octs = Malloc (oid->octetLen);
+    memcpy ((*anyRefHndl)->id->a.oid->octs, oid->octs, oid->octetLen);
+    (*anyRefHndl)->id->a.oid->octetLen =  oid->octetLen;
+
+} /* AddAnyRefByOid */
+
+/*
+ * Like AddAnyRefByOid except that an int maps to the type def
+ * instead of an OBJECT IDENTIFIER
+ */
+void
+AddAnyRefByInt PARAMS ((arl, enumId, intId),
+    AnyRefList **arl _AND_
+    char *enumId _AND_
+    AsnInt intId)
+{
+    AnyRef **anyRefHndl;
+
+    if (*arl == NULL)
+        *arl = AsnListNew (sizeof (void*));
+
+    anyRefHndl = (AnyRef**)AsnListAppend (*arl);
+    *anyRefHndl = MT (AnyRef);
+
+    (*anyRefHndl)->anyIdName = Malloc (strlen (enumId)+1);
+    strcpy ((*anyRefHndl)->anyIdName, enumId);
+    (*anyRefHndl)->id = MT (OidOrInt);
+    (*anyRefHndl)->id->choiceId = OIDORINT_INTID;
+    (*anyRefHndl)->id->a.intId = intId;
+
+} /* AddAnyRefByInt */
+
+
+void
+ProcessMacrosInValueDef PARAMS ((m, vd),
+    Module *m _AND_
+    ValueDef *vd)
+{
+   if (vd == NULL)
+       return;
+
+   /* turn linked oid's into encoded oids */
+    if (vd->value->basicValue->choiceId == BASICVALUE_LINKEDOID)
+        NormalizeValue (m, vd, vd->value, FALSE);
+
+   ProcessMacrosInType (m, NULL, vd->value->type, vd);
+
+} /* ProcessMacrosInValueDef */
+
+
+
+void
+ProcessMacrosInTypeDef PARAMS ((m,td),
+    Module *m _AND_
+    TypeDef *td)
+{
+   if (td == NULL)
+       return;
+
+   ProcessMacrosInType (m, td, td->type, NULL);
+
+} /* ProcessMacrosInTypeDef */
+
+
+
+void
+ProcessMacrosInType PARAMS ((m, td,t, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    ValueDef *v)
+{
+   if (t == NULL)
+       return;
+
+   ProcessMacrosInBasicType (m, td, t, t->basicType, v);
+
+} /* ProcessMacrosInTypeDef */
+
+
+
+void
+ProcessMacrosInElmtTypes PARAMS ((m, td, e, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    NamedTypeList *e _AND_
+    ValueDef *v)
+{
+    NamedType *nt;
+    FOR_EACH_LIST_ELMT (nt, e)
+    {
+        ProcessMacrosInType (m, td, nt->type, v);
+    }
+}  /* ProcessElmtTypes */
+
+
+
+void
+ProcessMacrosInBasicType PARAMS ((m,td,type,bt, v),
+    Module  *m _AND_
+    TypeDef *td _AND_
+    Type *type _AND_
+    BasicType *bt _AND_
+    ValueDef *v)
+{
+
+    if (bt == NULL)
+        return;
+
+    switch (bt->choiceId)
+    {
+
+        case BASICTYPE_SEQUENCE:
+        case BASICTYPE_SET:
+        case BASICTYPE_CHOICE:
+            ProcessMacrosInElmtTypes (m, td, bt->a.set,v);
+            break;
+
+
+
+        case BASICTYPE_SEQUENCEOF:
+        case BASICTYPE_SETOF:
+            ProcessMacrosInType (m, td, bt->a.setOf, v);
+            break;
+
+
+
+        case BASICTYPE_MACROTYPE:
+            switch (bt->a.macroType->choiceId)
+            {
+        case MACROTYPE_ASNABSTRACTOPERATION:
+        case MACROTYPE_ROSOPERATION:
+
+            ProcessRosOperationMacroType (m, td, type, bt, bt->a.macroType->a.rosOperation, v);
+            break;
+
+        case MACROTYPE_ROSERROR:
+        case MACROTYPE_ASNABSTRACTERROR:
+            ProcessRosErrorMacroType (m, td, type, bt, bt->a.macroType->a.rosError, v);
+             break;
+
+        case MACROTYPE_ROSBIND:
+        case MACROTYPE_ROSUNBIND:
+            ProcessRosBindMacroType (m, td, type, bt, bt->a.macroType->a.rosBind,v);
+             break;
+
+        case MACROTYPE_ROSASE:
+            ProcessRosAseMacroType (m, td, type, bt, bt->a.macroType->a.rosAse,v);
+             break;
+
+        case MACROTYPE_MTSASEXTENSIONS:
+            ProcessMtsasExtensionsMacroType (m, td, type, bt, bt->a.macroType->a.mtsasExtensions,v);
+            break;
+
+        case MACROTYPE_MTSASEXTENSION:
+            ProcessMtsasExtensionMacroType (m, td, type, bt, bt->a.macroType->a.mtsasExtension,v);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONATTRIBUTE:
+            ProcessMtsasExtensionAttributeMacroType (m, td, type, bt, bt->a.macroType->a.mtsasExtensionAttribute,v);
+            break;
+
+        case MACROTYPE_MTSASTOKEN:
+            ProcessMtsasTokenMacroType (m, td, type, bt, bt->a.macroType->a.mtsasToken,v);
+            break;
+
+        case MACROTYPE_MTSASTOKENDATA:
+            ProcessMtsasTokenDataMacroType (m, td, type, bt, bt->a.macroType->a.mtsasTokenData,v);
+            break;
+
+        case MACROTYPE_MTSASSECURITYCATEGORY:
+            ProcessMtsasSecurityCategoryMacroType (m, td, type, bt, bt->a.macroType->a.mtsasSecurityCategory,v);
+            break;
+
+        case MACROTYPE_ASNOBJECT:
+            ProcessAsnObjectMacroType (m, td, type, bt, bt->a.macroType->a.asnObject,v);
+            break;
+
+        case MACROTYPE_ASNPORT:
+            ProcessAsnPortMacroType (m, td, type, bt, bt->a.macroType->a.asnPort,v);
+            break;
+
+        case MACROTYPE_ASNABSTRACTBIND:
+        case MACROTYPE_ASNABSTRACTUNBIND:
+            ProcessAsnAbstractBindMacroType (m, td, type, bt, bt->a.macroType->a.asnAbstractBind,v);
+            break;
+
+        case MACROTYPE_AFALGORITHM:
+        case MACROTYPE_AFENCRYPTED:
+        case MACROTYPE_AFPROTECTED:
+        case MACROTYPE_AFSIGNATURE:
+        case MACROTYPE_AFSIGNED:
+            break;
+
+        case MACROTYPE_SNMPOBJECTTYPE:
+            ProcessSnmpObjectTypeMacroType (m, td, type, bt, bt->a.macroType->a.snmpObjectType,v);
+            break;
+
+        default:
+           /* ignore any others */
+        break;
+    }
+
+        default:
+          /* the rest do not need processing */
+
+        break;
+    }
+}  /* ProcessMacrosInBasicType */
+
+
+/*
+ * Given a Type referenced in a macro, makes up a name and defines
+ * the type iff the type is not a simple type ref or library type.
+ * Returns the typedef of the type given type. (may be new may
+ * be from the typeref if t was a local or import type ref)
+ */
+void
+DefineType PARAMS ((m, td, t, name),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    char *name)
+{
+   int digit;
+   TypeDef *newDef;
+   TypeDef **tmpTypeDefHndl;
+   Type *tmpType;
+   TypeDef *retVal;
+
+   if (IsNewType (t))
+   {
+       newDef = (TypeDef*)Malloc (sizeof (TypeDef));
+       newDef->exported = FALSE;
+       newDef->type = (Type*)Malloc (sizeof (Type));
+       memcpy (newDef->type, t, sizeof (Type));
+
+
+       newDef->definedName = Malloc (strlen (name)+4);
+       strcpy (newDef->definedName, name);
+
+       if (islower (newDef->definedName[0]))
+           newDef->definedName[0] =
+               toupper (newDef->definedName[0]);
+
+
+       /* set up unique type name for new type */
+       for (digit = 0;
+           (LookupType (m->typeDefs, newDef->definedName) != NULL);
+           digit++)
+           AppendDigit (newDef->definedName, digit);
+
+       /*
+        * now put new typedef  at head of list
+        */
+       tmpTypeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs);
+       *tmpTypeDefHndl = newDef;
+
+       /* convert macro's type def into a ref */
+
+       SetupType (&tmpType, BASICTYPE_LOCALTYPEREF, 0);
+       memcpy (t, tmpType, sizeof (Type));
+       Free (tmpType);
+       t->implicit = FALSE;
+       t->basicType->a.localTypeRef = (TypeRef*)Malloc (sizeof (TypeRef));
+       t->basicType->a.localTypeRef->link = newDef;
+       t->basicType->a.localTypeRef->module = m;
+       t->basicType->a.localTypeRef->typeName =
+           newDef->definedName;
+
+    }
+} /* DefineType */
+
+
+void
+ProcessRosOperationMacroType PARAMS ((m, td, t, bt, op, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosOperationMacroType *op _AND_
+    ValueDef *v)
+{
+
+    if (op->arguments != NULL)
+        DefineType (m, td, op->arguments->type, v->definedName);
+
+    if (op->result != NULL)
+        DefineType (m, td, op->result->type, v->definedName);
+
+}  /* ProcessRosOperationMacroType */
+
+
+
+void
+ProcessRosErrorMacroType PARAMS ((m, td, t, bt, err, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosErrorMacroType *err _AND_
+    ValueDef *v)
+{
+    if ((err != NULL) && (err->parameter != NULL))
+        DefineType (m, td, err->parameter->type, v->definedName);
+
+}   /* ProcessRosErrorMacroType */
+
+
+void
+ProcessRosBindMacroType PARAMS ((m, td, t, bt, bind, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosBindMacroType *bind _AND_
+    ValueDef *v)
+{
+    if (bind != NULL)
+    {
+        DefineType (m, td, bind->argument->type, v->definedName);
+        DefineType (m, td, bind->result->type, v->definedName);
+        DefineType (m, td, bind->error->type, v->definedName);
+    }
+}   /* ProcessRosBindMacroType */
+
+
+void
+ProcessRosAseMacroType PARAMS ((m, td, t, bt, ase, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAseMacroType *ase _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessRosAseMacroType */
+
+
+
+void
+ProcessRosAcMacroType PARAMS ((m, td, t, bt, ac, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAcMacroType *ac  _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessRosAcMacroType */
+
+
+
+void
+ProcessMtsasExtensionsMacroType PARAMS ((m, td, t, bt, exts, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionsMacroType *exts _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessMtsasExtensionsMacroType */
+
+
+void
+ProcessMtsasExtensionMacroType PARAMS ((m, td, t, bt, ext, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionMacroType *ext _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessMtsasExtensionMacroType */
+
+
+void
+ProcessMtsasExtensionAttributeMacroType PARAMS ((m, td, t, bt, ext, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionAttributeMacroType *ext _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessMtsasExtensionAttributeMacroType */
+
+
+void
+ProcessMtsasTokenMacroType PARAMS ((m, td, t, bt, tok, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenMacroType *tok _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessMtsasTokenMacroType */
+
+
+void
+ProcessMtsasTokenDataMacroType PARAMS ((m, td, t, bt, tok, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenDataMacroType *tok _AND_
+    ValueDef *v)
+{
+
+
+}  /* ProcessMtsasTokenDataMacroType */
+
+
+void
+ProcessMtsasSecurityCategoryMacroType PARAMS ((m, td, t, bt, sec, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasSecurityCategoryMacroType *sec _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessMtsasSecurityCategoryMacroType */
+
+
+
+void
+ProcessAsnObjectMacroType PARAMS ((m, td, t, bt, obj, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnObjectMacroType *obj _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessAsnObjectMacroType */
+
+
+void
+ProcessAsnPortMacroType PARAMS ((m, td, t, bt, p, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnPortMacroType *p _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessAsnPortMacroType */
+
+
+
+void
+ProcessAsnAbstractBindMacroType PARAMS ((m, td, t, bt, bind, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnAbstractBindMacroType *bind _AND_
+    ValueDef *v)
+{
+
+}  /* ProcessAsnBindMacroType */
+
+
+void
+ProcessSnmpObjectTypeMacroType  PARAMS ((m, td, t, bt, ot, v),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    SnmpObjectTypeMacroType *ot _AND_
+    ValueDef *v)
+{
+    NamedType *nt;
+    NamedType **tmpNtHndl;
+    char anyId[256];
+    AnyRefList **arlHndl;
+
+    if ((ot != NULL) && (ot->syntax != NULL))
+         DefineType (m, td, ot->syntax, v->definedName);
+
+    /*
+     * add ANY ref stuff to type ref'd by this macro so it is
+     * included in the ANY hash table.
+     */
+
+    /*
+     * do this since the SNMP spec doesn't have an ANY type
+     * but uses the mechanism. (SNMP uses an OCTET STRING
+     * where the 'ANY' value is
+     */
+    m->hasAnys = TRUE;
+
+    strcpy (anyId, v->definedName);
+/*    Str2UCase (anyId, strlen (anyId)); */
+    strcat (anyId, "_ANY_ID");
+
+    arlHndl = GetAnyRefListHndl (ot->syntax);
+
+
+    if (v->value->basicValue->choiceId == BASICVALUE_OID)
+        AddAnyRefByOid (arlHndl, anyId, v->value->basicValue->a.oid);
+
+    /*  integer types are not allowed, but relax constraints anyway */
+    else
+        AddAnyRefByInt (arlHndl, anyId, v->value->basicValue->a.integer);
+
+
+
+    /* make a choice with all the object type elmts */
+    /*   USING THE ANY HASH TABLE NOW
+    if (snmpObjectSyntaxesG == NULL)
+    {
+        snmpObjectSyntaxesG = (TypeDef*) Malloc (sizeof (TypeDef));
+        SetupType (&snmpObjectSyntaxesG->type, BASICTYPE_CHOICE, 0);
+        snmpObjectSyntaxesG->type->basicType->a.choice =
+            AsnListNew (sizeof (void*));
+        snmpObjectSyntaxesG->definedName = "SnmpOpaqueTypes";
+
+    }
+    */
+
+    /*  NOT DONE ANYMORE
+     * make each field in the choice the same as the object
+     * types SYNTAX field type (adjusted by Define type)
+     * make choice field name same as OBJ-TYPE value Defs name
+     *
+     * NOTE - using ptrs to type/fieldname, not duplicating them
+     * this may cause freeing probs
+     */
+    /*
+    nt = MT (NamedType);
+    nt->fieldName = v->definedName;
+    nt->type = ot->syntax;
+
+    tmpNtHndl = (NamedType**)
+        AsnListAppend (snmpObjectSyntaxesG->type->basicType->a.choice);
+    *tmpNtHndl = nt;
+    */
+
+}  /* ProcessSnmpObjectTypeMacro */
diff --git a/SecuritySNACCRuntime/compiler/core/do-macros.h b/SecuritySNACCRuntime/compiler/core/do-macros.h
new file mode 100644
index 00000000..1b4e3da2
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/do-macros.h
@@ -0,0 +1,33 @@
+/*
+ * compiler/core/do_macros.h
+ *
+ * MS 92
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/do-macros.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: do-macros.h,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:24  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:40  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:04  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+void ProcessMacros PROTO ((Module *m));
diff --git a/SecuritySNACCRuntime/compiler/core/err-chk.c b/SecuritySNACCRuntime/compiler/core/err-chk.c
new file mode 100644
index 00000000..5f5eae6f
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/err-chk.c
@@ -0,0 +1,996 @@
+/*
+ * compiler/core/err_chk.c - Check for semantic errors an ASN.1 module
+ *
+ * The following are checked:
+ *
+ * - Components of CHOICE and SET types must have distinct tags. x
+ *
+ * - CHOICE, ANY, and ANY DEFINED BY types cannot be implicitly tagged. x
+ *
+ * - Type and value names within the same scope must be unique. x
+ *
+ * - Field names in a SET, SEQUENCE or CHOICE must be distinct.  If
+ *   a CHOICE with no field name is embedded in a SET, SEQUENCE or CHOICE,
+ *   then the embedded CHOICE's field names must be distinct from its
+ *   parents to avoid ambiguity in value notation. x
+ *
+ * - An APPLICATION tag can only be used once per module. x (done in asn1.yacc)
+ *
+ * - Each value in a named bit (BIT STRINGs) or named number x
+ *   (INTEGERs and ENUMERATED) list must be different.
+ *
+ * - Each identifier in a named bit or named number list must be different. x
+ *
+ * - The tags on a series of one or more consecutive OPTIONAL or DEFAULT
+ *   SEQUENCE elements and the following element must be distinct. x
+ *
+ * link_types.c does the following three checks
+ * A COMPONENTS OF type in a SET must reference a SET
+ * A COMPONENTS OF type in a SEQUENCE must reference a SEQUENCE
+ * SELECTION types must reference a field of a CHOICE type.
+ *
+ * - gives a warning if an ANY DEFINED BY type appears in a SET or
+ * if and ANY DEFINED BY appears in a SEQUENCE before its identifier.
+ * these cases make decoding difficult.
+ *
+ *  ******* following are not done yet - need improved value proc. first*****
+ *
+ * - Each identifier in a BIT STRING value must from that BIT
+ *   STRING's named bit list.
+ *
+ * - SET or SEQUENCE values can be empty {} only if the SET or
+ *   SEQUENCE type was defined as empty or all of its elements are marked
+ *   as OPTIONAL or DEFAULT.
+ *
+ * Mike Sample
+ * 92/07/13
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/err-chk.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: err-chk.c,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1997/09/01 14:19:43  wan
+ * Improved error output in certain cases.
+ *
+ * Revision 1.3  1995/07/25 19:41:25  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:33:02  rj
+ * snacc_config.h removed; err_chk.h includet.
+ *
+ * Revision 1.1  1994/08/28  09:49:05  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "snacc-util.h"
+#include "tag-util.h"
+#include "define.h"
+#include "err-chk.h"
+
+typedef struct DefinedTag
+{
+    Tag *tag;
+    struct DefinedTag *next;
+} DefinedTag;
+
+
+typedef struct DefinedName
+{
+    char *name;
+    struct DefinedName *next;
+} DefinedName;
+
+
+static NamedType *badNamedType;
+static DefinedName *fieldNames = NULL;
+
+
+void ErrChkTypeDef PROTO ((Module *m, TypeDef *td));
+
+void ErrChkType PROTO ((Module *m, TypeDef *td, Type *parent, NamedType *nt, Type *t));
+
+void ErrChkElmtTypes PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e));
+
+void ErrChkBasicType PROTO ((Module  *m, TypeDef *td, Type *parent, NamedType *nt, Type *type));
+
+void ErrChkValueDef PROTO ((Module *m, ValueDef *vd));
+
+void ErrChkValue PROTO ((Module *m, ValueDef *vd, Value *v));
+
+int HasDistinctTags PROTO ((NamedTypeList *elmts));
+
+int AddFirstTag PROTO ((DefinedObj **definedTags, Type *t));
+
+void ChkFieldNames PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *elmts));
+
+void ChkNamedNumbers PROTO ((Module *m, Type *t, NamedNumberList *n));
+
+void ChkNamedBits PROTO ((Module *m, Type *t, NamedNumberList *n));
+
+void ChkSeqTags PROTO ((Module *m, TypeDef *td, Type *t));
+
+
+/* return TRUE if the Tag *t1 and t2 are the same in class and code */
+int
+TagObjCmp PARAMS ((t1, t2),
+    void *t1 _AND_
+    void *t2)
+{
+    return (((Tag*) t1)->tclass ==  ((Tag*) t2)->tclass) &&
+             (((Tag*) t1)->code ==  ((Tag*) t2)->code);
+}
+
+
+/*
+ * Checks for errors listed above.
+ * sets module status to MOD_ERROR if any errors occured
+ */
+void
+ErrChkModule PARAMS ((m),
+    Module *m)
+{
+    TypeDef *td;
+    ValueDef *vd;
+    DefinedObj *typeNames;
+    DefinedObj *valueNames;
+    ImportModule *impList;
+    ImportElmt *impElmt;
+
+    /*
+     * go through each type in typeList
+     */
+    typeNames = NewObjList();
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        /* first check for name conflicts */
+        if (ObjIsDefined (typeNames, td->definedName, StrObjCmp))
+        {
+            PrintErrLoc (m->asn1SrcFileName, td->type->lineNo);
+            fprintf (stderr,"ERROR - type \"%s\" is multiply defined.\n", td->definedName);
+            m->status = MOD_ERROR;
+        }
+        else
+            DefineObj (&typeNames, td->definedName);
+
+        /* now check type def internals */
+        ErrChkTypeDef (m, td);
+    }
+
+    /*  now check for name conflicts with imported types */
+    FOR_EACH_LIST_ELMT (impList, m->imports)
+    {
+        FOR_EACH_LIST_ELMT (impElmt, impList->importElmts)
+        {
+            if ((!impElmt->privateScope) && (isupper (impElmt->name[0])))
+            {
+                if (ObjIsDefined (typeNames, impElmt->name, StrObjCmp))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, impElmt->lineNo);
+                    fprintf (stderr,"ERROR - type \"%s\" is multiply defined.\n", impElmt->name);
+                    m->status = MOD_ERROR;
+                }
+                else
+                    DefineObj (&typeNames, impElmt->name);
+            }
+        }
+    }
+    FreeDefinedObjs (&typeNames);
+
+
+    /*
+     *  go through each value for types
+     */
+    valueNames = NewObjList();
+    FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+    {
+        /* check for name conflict */
+        if (ObjIsDefined (valueNames, vd->definedName, StrObjCmp))
+        {
+            PrintErrLoc (m->asn1SrcFileName, vd->value->lineNo);
+            fprintf (stderr,"ERROR - value \"%s\" is multiply defined.\n", vd->definedName);
+            m->status = MOD_ERROR;
+        }
+        else
+            DefineObj (&valueNames, vd->definedName);
+
+        /* check value internal info */
+        ErrChkValueDef (m, vd);
+    }
+    /*  now check for name conflicts with imported values */
+    FOR_EACH_LIST_ELMT (impList, m->imports)
+    {
+        FOR_EACH_LIST_ELMT (impElmt, impList->importElmts)
+        {
+            if ((!impElmt->privateScope) && (islower (impElmt->name[0])))
+            {
+                if (ObjIsDefined (valueNames, impElmt->name, StrObjCmp))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, impElmt->lineNo);
+                    fprintf (stderr,"ERROR - value \"%s\" is multiply defined.\n", vd->definedName);
+                    m->status = MOD_ERROR;
+                }
+                else
+                    DefineObj (&valueNames, impElmt->name);
+            }
+        }
+    }
+
+
+    FreeDefinedObjs (&valueNames);
+
+}   /* ErrChkModule */
+
+
+
+void
+ErrChkTypeDef PARAMS ((m, td),
+    Module *m _AND_
+    TypeDef *td)
+{
+   if (td == NULL)
+       return;
+
+   ErrChkType (m, td, NULL, NULL, td->type);
+
+} /* ErrChkTypeDef */
+
+
+
+void
+ErrChkType PARAMS ((m, td, parent, nt, t),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedType *nt _AND_
+    Type *t)
+{
+    if (t == NULL)
+        return;
+
+    ErrChkBasicType (m, td, parent, nt, t);
+
+} /* ErrChkType */
+
+
+
+void
+ErrChkElmtTypes PARAMS ((m, td, parent, e),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *e)
+{
+    NamedType *nt;
+
+    /*
+     * if starting new type aggregate type,
+     * check that the field names are distinct
+     * (goes 'through' un-named elements that are CHOICEs)
+     */
+    if (td->type == parent)
+    {
+        ChkFieldNames (m, td, parent, e);
+    }
+
+
+    FOR_EACH_LIST_ELMT (nt, e)
+    {
+        ErrChkType (m, td, parent, nt, nt->type);
+    }
+}  /* ErrChkElmtTypes */
+
+
+
+void
+ErrChkBasicType PARAMS ((m, td, parent, tnt, type),
+    Module  *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedType *tnt _AND_
+    Type *type)
+{
+    int i, numElmtsAdded;
+    NamedType *newElmt;
+    NamedType **newElmtHndl;
+    NamedType *nt;
+    NamedTypeList *elmts;
+    NamedType *origNext;
+    Type *refdType;
+    enum BasicTypeChoiceId refdTypeId;
+    TypeDef *newDef;
+
+    if ((type == NULL) || (type->basicType == NULL))
+        return;
+
+    switch (type->basicType->choiceId)
+    {
+        case BASICTYPE_LOCALTYPEREF:
+        case BASICTYPE_IMPORTTYPEREF:
+            /*
+             * make sure that untagged CHOICE and ANY types
+             * are not implicitly tagged
+             */
+            refdTypeId = ParanoidGetBuiltinType (type);
+            if ((type->implicit) &&
+                 ((refdTypeId == BASICTYPE_CHOICE) ||
+                  (refdTypeId == BASICTYPE_ANY) ||
+                  (refdTypeId == BASICTYPE_ANYDEFINEDBY)) &&
+                (CountTags (type->basicType->a.localTypeRef->link->type) == 0))
+            {
+                m->status = MOD_ERROR;
+                PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - IMPLICITLY tagged CHOICE, ANY or ANY DEFINED BY type.\n");
+            }
+
+            if ((parent != NULL) &&
+                ((refdTypeId == BASICTYPE_ANY) ||
+                 (refdTypeId == BASICTYPE_ANYDEFINEDBY)))
+            {
+
+                /*
+                 * give a warning.  It is stupid to have an ANY DEFINED
+                 * BY type in a SET since they are not ordered and hence
+                 * the ANY DEFINED BY type may need to be decoded before
+                 * its identifer which is very difficult
+                 */
+                if ((refdTypeId == BASICTYPE_ANYDEFINEDBY) &&
+                    (parent->basicType->choiceId == BASICTYPE_SET))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"WARNING - ANY DEFINED BY in a SET needs to be decoded before its identifier. This is not guaranteed since SETs are not ordered.  Use a SEQUENCE instead, if possible.\n");
+                }
+
+                /*
+                 * give a warning.  It is stupid to have an ANY DEFINED
+                 * BY type in a SEQUENCE before its identifier.
+                 * The ANY DEFINED BY type will need to be decoded before
+                 * its identifer which is very difficult.
+                 * tnt is the NamedType holding "type"
+                 */
+                if ((refdTypeId == BASICTYPE_ANYDEFINEDBY) && (tnt != NULL) &&
+                    (parent->basicType->choiceId == BASICTYPE_SEQUENCE) &&
+                    (GetAsnListElmtIndex (tnt, parent->basicType->a.sequence) <
+                     GetAsnListElmtIndex (type->basicType->a.anyDefinedBy->link, parent->basicType->a.sequence)))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"WARNING - ANY DEFINED BY in SEQUENCE should appear before its identifier since the identifier must be decoded before the ANY DEFINED BY type.\n");
+                }
+
+
+                if (parent->basicType->choiceId == BASICTYPE_SEQUENCE)
+                    nt = LAST_LIST_ELMT (parent->basicType->a.sequence);
+
+                /*
+                 * untagged, optional ANYs are strange and will cause faulty
+                 * decoding code to be generated unless they are the last
+                 * elmt in a SEQUENCE.
+                 * (if they are the last elmt it is easy to check
+                 *  for the presence of the ANY if definite lengths are used)
+                 * (must peek ahead for EOC otherwise)
+                 */
+                if (!((parent->basicType->choiceId == BASICTYPE_SEQUENCE) &&
+                      (type == nt->type)) &&
+                    (type->optional) && (CountTags (type) == 0))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"WARNING - untagged optional ANY encountered, the produced code will be wrong.\n");
+                }
+
+                /*
+                 *  if parent is SET or CHOICE then ANY or ANY DEFINED BY
+                 *  should be tagged to help determine its presence
+                 *
+                 * NOTE: there are also probs with untagged ANYs in SEQs
+                 * where the ANY is preceeded by optional elmts
+                 * (err msg written in produced code)
+                 */
+                if (((parent->basicType->choiceId == BASICTYPE_SET) ||
+                     (parent->basicType->choiceId == BASICTYPE_CHOICE)) &&
+                    (CountTags == 0))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"WARNING - untagged ANY in a SET or CHOICE, the produced code will be wrong.\n");
+                }
+            }
+
+            break;
+
+
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_ENUMERATED:
+            ChkNamedNumbers (m, type, type->basicType->a.integer);
+            break;
+
+        case BASICTYPE_BITSTRING:
+            ChkNamedBits (m, type, type->basicType->a.bitString);
+            break;
+
+
+        case BASICTYPE_SEQUENCEOF:
+        case BASICTYPE_SETOF:
+            ErrChkType (m, td, type, NULL, type->basicType->a.setOf);
+            break;
+
+        case BASICTYPE_SEQUENCE:
+            ErrChkElmtTypes (m, td, type, type->basicType->a.sequence);
+
+            /*
+             * check that tags on one or more consecutive optional elmts
+             * and following (if any) non-optional elmt are distinct
+             */
+            ChkSeqTags (m, td, type);
+            break;
+
+
+        case BASICTYPE_CHOICE:
+            /* CHOICE elements must have distinct tags */
+            if (!HasDistinctTags (type->basicType->a.choice))
+            {
+                PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - tag conflict among ");
+		PrintType (stderr, NULL, badNamedType->type);
+		fprintf (stderr," and the other CHOICE elements.\n");
+                m->status = MOD_ERROR;
+            }
+
+            /*
+             * untagged choices cannot be implicitily tagged
+             * (this would make it impossible/difficult to figure out which
+             * elmt of the choice was present when decoding)
+             */
+            if (((type->tags == NULL) || LIST_EMPTY (type->tags)) &&
+                 (type->implicit))
+            {
+                PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - IMPLICITLy tagged CHOICE type.\n");
+                m->status = MOD_ERROR;
+            }
+
+            /* Check out each of the components */
+            ErrChkElmtTypes (m, td, type, type->basicType->a.choice);
+
+
+            break;
+
+            case BASICTYPE_ANYDEFINEDBY:
+                /* for ANY DEFINED BY make sure id field is int or oid */
+                refdType = GetType (type->basicType->a.anyDefinedBy->link->type);
+                if ((refdType->basicType->choiceId != BASICTYPE_INTEGER) &&
+                    (refdType->basicType->choiceId != BASICTYPE_ENUMERATED) &&
+                    (refdType->basicType->choiceId != BASICTYPE_OID))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"ERROR - Field referenced by ANY DEFINED BY type must be of INTEGER or OBJECT IDENTIFIER type.\n");
+                    m->status = MOD_ERROR;
+                }
+
+                /* make sure id field is not optional */
+                if (type->basicType->a.anyDefinedBy->link->type->optional)
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"ERROR - Field referenced by ANY DEFINED BY cannot be optional.\n");
+                    m->status = MOD_ERROR;
+                }
+
+                /*
+                 * give a warning.  It is stupid to have an ANY DEFINED
+                 * BY type in a SET since they are not ordered and hence
+                 * the ANY DEFINED BY type may need to be decoded before
+                 * its identifer which is very difficult
+                 */
+                if ((parent != NULL) &&
+                    (parent->basicType->choiceId == BASICTYPE_SET))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"WARNING - ANY DEFINED BY in a SET needs to be decoded before its identifier. This is not guaranteed since SETs are not ordered.  Use a SEQUENCE instead, if possible.\n");
+                }
+
+                /*
+                 * give a warning.  It is stupid to have an ANY DEFINED
+                 * BY type in a SEQUENCE before its identifier.
+                 * The ANY DEFINED BY type will need to be decoded before
+                 * its identifer which is very difficult.
+                 * tnt is the NamedType holding "type"
+                 */
+                if ((parent != NULL) && (tnt != NULL) &&
+                    (parent->basicType->choiceId == BASICTYPE_SEQUENCE) &&
+                    (GetAsnListElmtIndex (tnt, parent->basicType->a.sequence) <
+                     GetAsnListElmtIndex (type->basicType->a.anyDefinedBy->link, parent->basicType->a.sequence)))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"WARNING - ANY DEFINED BY in SEQUENCE should appear before its identifier since the identifier must be decoded before the ANY DEFINED BY type.\n");
+                }
+
+
+            /* fall through - arrrrrg! */
+
+
+            case BASICTYPE_ANY:
+            /* ANY cannot be implicitily tagged */
+            if (((type->tags == NULL) || LIST_EMPTY (type->tags)) &&
+                 (type->implicit))
+            {
+                PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - IMPLICITLy tagged ANY type.\n");
+                m->status = MOD_ERROR;
+            }
+
+
+            if (parent != NULL)
+            {
+                if (parent->basicType->choiceId == BASICTYPE_SEQUENCE)
+                    nt = LAST_LIST_ELMT (parent->basicType->a.sequence);
+
+                /*
+                 * untagged, optional ANYs are strange and will cause faulty
+                 * decoding code to be generated unless they are the last
+                 * elmt in a SEQUENCE
+                 */
+                if (!((parent->basicType->choiceId == BASICTYPE_SEQUENCE) &&
+                      (type == nt->type)) &&
+                    (type->optional) && (CountTags (type) == 0))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"WARNING - untagged optional ANY encountered, the produced code will be wrong.\n");
+                }
+
+                /*
+                 *  if parent is SET or CHOICE then ANY or ANY DEFINED BY
+                 *  should be tagged to help determine its presence
+                 *
+                 * NOTE: there are also probs with untagged ANYs in SEQs
+                 * where the ANY is preceeded by optional elmts
+                 * (err msg written in produced code)
+                 */
+                if (((parent->basicType->choiceId == BASICTYPE_SET) ||
+                     (parent->basicType->choiceId == BASICTYPE_CHOICE)) &&
+                    (CountTags (type) == 0))
+                {
+                    PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"WARNING - untagged ANY in a SET or CHOICE, the produced code will be wrong.\n");
+                }
+            }
+
+
+            break;
+
+
+
+        case BASICTYPE_SET:
+            /* SET elements must have distinct tags */
+            if (!HasDistinctTags (type->basicType->a.set))
+            {
+                PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - tag conflict among ");
+		PrintType (stderr, NULL, badNamedType->type);
+                fprintf (stderr," and the other SET elements.\n");
+                m->status = MOD_ERROR;
+            }
+
+            /* Check out each of the components */
+            ErrChkElmtTypes (m, td, type, type->basicType->a.set);
+            break;
+
+
+        default:
+          /* the rest do not need checking */
+        break;
+    }
+}  /* ErrChkBasicType */
+
+
+void
+ErrChkValueDef PARAMS ((m, vd),
+    Module *m _AND_
+    ValueDef *vd)
+{
+    ErrChkValue (m, vd, vd->value);
+}
+
+void
+ErrChkValue PARAMS ((m, vd, v),
+    Module *m _AND_
+    ValueDef *vd _AND_
+    Value *v)
+{
+}
+
+
+/*
+ * returns non-zero if the first tags on the elements
+ * are all different.  Otherwise 0 is returned
+ *
+ *  algorithm: add each tag to a list, adding only if
+ *             not already in list. if there, free list
+ *             and return FALSE. if finished adding tags
+ *             and no duplicates occurred then return TRUE;
+ */
+int
+HasDistinctTags PARAMS ((elmts),
+    NamedTypeList *elmts)
+{
+    DefinedObj *tL;
+    NamedType *e;
+
+    tL = NewObjList();
+    FOR_EACH_LIST_ELMT (e, elmts)
+    {
+        if (!AddFirstTag (&tL, e->type))
+        {
+            FreeDefinedObjs (&tL);
+            badNamedType = e;
+            return FALSE;
+        }
+    }
+    FreeDefinedObjs (&tL);
+    badNamedType = NULL;
+    return TRUE;
+} /* HasDistinctTags */
+
+
+/*
+ * puts first tag of the given type into the defined tags list
+ * returns FALSE if the tag was already in the defined tags list.
+ * return TRUE otherwise
+ */
+int
+AddFirstTag PARAMS ((definedTags, t),
+    DefinedObj **definedTags _AND_
+    Type *t)
+{
+    Tag *tag;
+    TagList *tl;
+    Tag *last;
+    int implicitRef;
+    NamedType *e;
+
+    tl = t->tags;
+    if (tl != NULL)
+        AsnListFirst (tl);
+
+    implicitRef = FALSE;
+
+    for (;;)
+    {
+         /*
+          * get first tag from tag list local to this type if any
+          */
+
+        if ((tl != NULL) && (CURR_LIST_NODE (tl) != NULL) &&
+            (CURR_LIST_ELMT (tl) != NULL))
+        {
+            tag = (Tag*) CURR_LIST_ELMT (tl);
+
+            if (ObjIsDefined (*definedTags, tag, TagObjCmp))
+                return FALSE;
+            else
+            {
+                DefineObj (definedTags, tag);
+                return TRUE;
+            }
+        }
+
+        /*
+         * follow tags of referenced types if no tags on this type
+         */
+
+        if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+             (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+        {
+            if (!implicitRef)
+                implicitRef = t->implicit;
+
+
+            if (t->basicType->a.localTypeRef->link == NULL)
+            {
+                /* this should be found in the type link stage */
+                fprintf (stderr,"ERROR - unresolved type ref, cannot get tags for decoding\n");
+                break;
+            }
+            t = t->basicType->a.localTypeRef->link->type;
+            tl = t->tags;
+
+            if (tl != NULL)
+            {
+                AsnListFirst (tl); /* set curr ptr to first node */
+                if ((!LIST_EMPTY (tl)) && implicitRef)
+                {
+                    AsnListNext (tl);
+                    implicitRef = FALSE;
+                }
+            }
+
+        }
+
+        /*
+         * if untagged choice and no tags found yet
+         */
+        else if ((t->basicType->choiceId == BASICTYPE_CHOICE))
+        {
+            /*
+             * add top level tags from each choice elmt
+             */
+            if (implicitRef)
+            {
+                fprintf (stderr,"ERROR - IMPLICITLY Tagged CHOICE\n");
+            }
+
+
+            FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
+            {
+                if (!AddFirstTag (definedTags, e->type))
+                    return FALSE;
+            }
+
+            return TRUE;
+        }
+
+        else /* could be ANY type - assume correct tagging */
+            return TRUE;
+
+    }
+
+}  /* AddFirstTag */
+
+
+
+
+/*
+ *  Prints Errors if the field names of the elements are
+ *  not distinct.
+ *  currently an endless recursion problem here
+ *  for recursive types involving CHOICEs - Fixed MS
+ */
+void
+ChkFieldNamesRec PARAMS ((m, td, parent, elmts, fieldNames, followedTypeRefs),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts _AND_
+    DefinedObj **fieldNames _AND_
+    DefinedObj **followedTypeRefs)
+{
+    NamedType *e;
+    Type *definingType;
+
+    FOR_EACH_LIST_ELMT (e, elmts)
+    {
+        definingType = ParanoidGetType (e->type);
+        if (e->fieldName != NULL)
+        {
+            if (ObjIsDefined (*fieldNames, e->fieldName, StrObjCmp))
+            {
+                if (parent->basicType->a.choice == elmts)
+                {
+                    PrintErrLoc (m->asn1SrcFileName, e->type->lineNo);
+                    fprintf (stderr,"WARNING - field name \"%s\" is used more than once in same value notation scope.\n", e->fieldName);
+                }
+                else
+                {
+                    PrintErrLoc (m->asn1SrcFileName, parent->lineNo);
+                    fprintf (stderr,"WARNING - field name \"%s\" in embedded CHOICE conflicts with field name in type \"%s\".", e->fieldName, td->definedName);
+                    fprintf (stderr," This may lead to ambiguous value notation.\n");
+                }
+                /* m->status = MOD_ERROR; */
+            }
+            else
+                DefineObj (fieldNames, e->fieldName);
+        }
+
+        /*
+         * must include embedded CHOICE's field names
+         * if it has no field name (this case is a reference to
+         * a CHOICE) (fieldName is NULL)
+         */
+        else if (((e->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+                  (e->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) &&
+                 (definingType->basicType->choiceId == BASICTYPE_CHOICE))
+        {
+            /* stop if this is a recursive ref we have already checked */
+            if (!ObjIsDefined (*followedTypeRefs, e->type->basicType->a.localTypeRef->typeName, StrObjCmp))
+            {
+                /* push this type name so we don't go through it again */
+                DefineObj (followedTypeRefs,  e->type->basicType->a.localTypeRef->typeName);
+                /* pass in field type not defining type as parent for line no*/
+                ChkFieldNamesRec (m, td, e->type, definingType->basicType->a.choice, fieldNames, followedTypeRefs);
+
+                /* pop this type name since we're done checking it */
+                UndefineObj (followedTypeRefs,  e->type->basicType->a.localTypeRef->typeName, StrObjCmp);
+            }
+        }
+
+        /* this is an embedded CHOICE definition (fieldName is NULL) */
+        else if (e->type->basicType->choiceId == BASICTYPE_CHOICE)
+        {
+            ChkFieldNamesRec (m, td, e->type, /* pass in field type for line */
+                             definingType->basicType->a.choice, fieldNames, followedTypeRefs);
+        }
+
+    }
+}  /* ChkFieldNamesRec */
+
+
+
+/*
+ * wrapper for ChkFieldNamesRec
+ * Checks that the field names of an aggregate type (CHOICE/SET/SEQ)
+ * are distinct.  Violations are printed to stderr.
+ */
+void
+ChkFieldNames PARAMS ((m, td, parent, elmts),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *elmts)
+{
+    DefinedObj *fieldNames;
+    DefinedObj *followedTypeRefs;
+
+    fieldNames = NewObjList();
+    followedTypeRefs = NewObjList();
+
+    /*
+     * first define the type itself as followed to prevent
+     * infinintely checking it
+     */
+    DefineObj (&followedTypeRefs, td->definedName);
+
+    ChkFieldNamesRec (m, td, parent, elmts, &fieldNames, &followedTypeRefs);
+
+    FreeDefinedObjs (&fieldNames);
+    FreeDefinedObjs (&followedTypeRefs);
+
+} /* ChkFieldNames */
+
+
+
+/*
+ * make sure that the identifiers of the named numbers are unique
+ * among themselves.
+ *
+ * also check that the values of the named numbers are unique
+ * among themselves.
+ */
+void
+ChkNamedNumbers PARAMS ((m, t, n),
+    Module *m _AND_
+    Type *t _AND_
+    NamedNumberList *n)
+{
+    DefinedObj *ids;
+    DefinedObj *nums;
+    ValueDef *nn;
+    Value *baseVal;
+
+
+    if (n == NULL)
+        return;
+
+    ids = NewObjList();
+    nums = NewObjList();
+    FOR_EACH_LIST_ELMT (nn, n)
+    {
+        if (ObjIsDefined (ids, nn->definedName, StrObjCmp))
+        {
+            PrintErrLoc (m->asn1SrcFileName, t->lineNo);
+            fprintf (stderr,"ERROR - named numbers (%s) must have unique identifiers.\n", nn->definedName);
+        }
+        else
+            DefineObj (&ids, nn->definedName);
+
+        baseVal = GetValue (nn->value);
+        if (baseVal->basicValue->choiceId != BASICVALUE_INTEGER)
+        {
+            PrintErrLoc (m->asn1SrcFileName, t->lineNo);
+            fprintf (stderr,"ERROR - value format problem (%s)- named numbers must be integers.\n", nn->definedName);
+        }
+        else if (ObjIsDefined (nums, &baseVal->basicValue->a.integer, IntObjCmp))
+        {
+            PrintErrLoc (m->asn1SrcFileName, t->lineNo);
+            fprintf (stderr,"ERROR - named numbers (%s) must have unique values.\n", nn->definedName);
+        }
+        else
+            DefineObj (&nums, &baseVal->basicValue->a.integer);
+
+    }
+
+    FreeDefinedObjs (&ids);
+    FreeDefinedObjs (&nums);
+
+}  /* ChkNamedNumbers */
+
+
+
+/*
+ * The same as ChkNamedNumbers except that the elmt values must be
+ * > 0 (needed for BIT STRINGs)
+ */
+void
+ChkNamedBits PARAMS ((m, t, n),
+    Module *m _AND_
+    Type *t _AND_
+    NamedNumberList *n)
+{
+    ValueDef *vd;
+    Value *baseVal;
+
+    ChkNamedNumbers (m, t, n);
+
+    FOR_EACH_LIST_ELMT (vd, n)
+    {
+        baseVal = GetValue (vd->value);
+        if ((baseVal->basicValue->choiceId == BASICVALUE_INTEGER) &&
+            (baseVal->basicValue->a.integer < 0))
+        {
+            PrintErrLoc (m->asn1SrcFileName, t->lineNo);
+            fprintf (stderr,"ERROR - named bits (%s) must have positive values.\n", vd->definedName);
+        }
+    }
+
+} /* ChkNamedBits */
+
+
+
+/*
+ * check that tags on one or more consecutive optional elmts
+ * and following (if any) non-optional elmt are distinct
+ */
+void
+ChkSeqTags PARAMS ((m, td, t),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t)
+{
+    DefinedObj *dO;
+    NamedType *e;
+
+    if (t->basicType->choiceId != BASICTYPE_SEQUENCE)
+        return;
+
+    dO = NewObjList();
+    FOR_EACH_LIST_ELMT (e, t->basicType->a.sequence)
+    {
+        /* if optional add tag */
+        if (e->type->optional || (e->type->defaultVal != NULL))
+        {
+            if (!AddFirstTag (&dO, e->type))
+            {
+                PrintErrLoc (m->asn1SrcFileName, e->type->lineNo);
+                fprintf (stderr,"ERROR - one or more consecutive optional SEQUENCE elmements and the the following non-optional elmt (if any) must have distinct tags.\n");
+                m->status = MOD_ERROR;
+            }
+        }
+        else if (dO != NULL)   /* first non-opt after opt elmts */
+        {
+            if (!AddFirstTag (&dO, e->type))
+            {
+                PrintErrLoc (m->asn1SrcFileName, e->type->lineNo);
+                fprintf (stderr,"ERROR - one or more consecutive optional SEQUENCE elmements and the the following non-optional elmt (if any) must have distinct tags.\n");
+                m->status = MOD_ERROR;
+            }
+            FreeDefinedObjs (&dO);
+            dO = NewObjList();
+        }
+    }
+    FreeDefinedObjs (&dO);
+
+}  /* ChkSeqTags */
diff --git a/SecuritySNACCRuntime/compiler/core/err-chk.h b/SecuritySNACCRuntime/compiler/core/err-chk.h
new file mode 100644
index 00000000..ebd81fe8
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/err-chk.h
@@ -0,0 +1,34 @@
+/*
+ * compiler/core/err_chk.h - check parsed, linked & normalized module for semantic errors
+ *
+ * MS 92
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/err-chk.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: err-chk.h,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:26  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:42  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:07  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+void ErrChkModule PROTO ((Module *m));
diff --git a/SecuritySNACCRuntime/compiler/core/exports.c b/SecuritySNACCRuntime/compiler/core/exports.c
new file mode 100644
index 00000000..03f8f40c
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/exports.c
@@ -0,0 +1,117 @@
+/*
+ * compiler/core/exports.c
+ *
+ *      ExportElmt list set up during  parse.
+ *      (not kept in Module data struct)
+ *
+ *  SetExports runs through type, value & macro defs and sets the
+ *  exported flag accordingly.
+ *
+ *  The exportsParsed boolean means whether the symbol "EXPORTS"
+ *  was parsed - since if EXPORTS was parsed and the export list
+ *  is empty, NOTHING is exported, otherwise if the "EXPORTS"
+ *  symbol was not parsed (export list is empty) then EVERYTHING
+ *  is exported.  If "EXPORTS" was parsed and the list is not
+ *  empty, then mark each item is the list as exported and the
+ *  rest (that are not in the list) as not exported.
+ *
+ * Mike Sample
+ * 91/09/04
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/exports.c,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: exports.c,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:48  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:27  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:33:28  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:08  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "snacc-util.h"
+#include "exports.h"
+
+/*
+ * called from main in snacc.c to set exported flags for
+ * typeDefs and valueDefs in the given module
+ */
+void
+SetExports PARAMS ((m, e, exportsParsed),
+    Module *m _AND_
+    ExportElmt *e _AND_
+    int exportsParsed)
+{
+    TypeDef *td;
+    ValueDef *vd;
+
+    if (!exportsParsed)  /* export everything */
+    {
+        /*
+         * set all typedefs', valuedefs' and macrodefs' exported flag
+         */
+        m->exportStatus = EXPORTS_ALL;
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+        {
+            td->exported = TRUE;
+        }
+
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+        {
+            vd->exported = TRUE;
+        }
+    }
+    else  /* EXPORTS sym parsed */
+    {
+        /* init every exports flag to false */
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+        {
+            td->exported = FALSE;
+        }
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+        {
+            vd->exported = FALSE;
+        }
+
+        if (e == NULL) /* export nothing */
+        {
+            m->exportStatus = EXPORTS_NOTHING;
+        }
+        else /* just export types/values in export list */
+        {
+            m->exportStatus = EXPORTS_SOME;
+            for (; e != NULL; e = e->next)
+            {
+                if ((td = LookupType (m->typeDefs,  e->name)) != NULL)
+                    td->exported = TRUE;
+
+                else if ((vd = LookupValue (m->valueDefs,  e->name)) != NULL)
+                    vd->exported = TRUE;
+                else
+                {
+                    PrintErrLoc (m->asn1SrcFileName, e->lineNo);
+                    fprintf (stderr, "ERROR - exporting undefined type/value \"%s\"\n", e->name);
+                }
+            }
+        }
+    }
+}  /* SetExports */
diff --git a/SecuritySNACCRuntime/compiler/core/exports.h b/SecuritySNACCRuntime/compiler/core/exports.h
new file mode 100644
index 00000000..61914817
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/exports.h
@@ -0,0 +1,52 @@
+/*
+ * compiler/core/exports.h -
+ *
+ *      ExportElmt list set up during  parse.
+ *      (not kept in Module data struct)
+ *
+ *  SetExports runs through type, value & macro defs and sets the
+ *  exports flag accordingly.
+ *
+ *  the exportsParsed boolean means whether the symbol "EXPORTS"
+ *  was parsed - since if EXPORTS was parsed and the export list
+ *  is empty, NOTHING is exported, otherwise if the "EXPORTS"
+ *  symbol was not parsed (export list is empty) then EVERYTHING
+ *  is exported
+ *
+ * Mike Sample
+ * 91/09/04
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/exports.h,v 1.1 2001/06/20 21:27:56 dmitch Exp $
+ * $Log: exports.h,v $
+ * Revision 1.1  2001/06/20 21:27:56  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:48  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1994/10/08 03:48:43  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:09  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+typedef struct ExportElmt
+{
+    char *name;
+    long int lineNo;
+    struct ExportElmt *next;
+} ExportElmt;
+
+
+void SetExports PROTO ((Module *m, ExportElmt *e, int exportsParsed));
diff --git a/SecuritySNACCRuntime/compiler/core/gen-tbls.c b/SecuritySNACCRuntime/compiler/core/gen-tbls.c
new file mode 100644
index 00000000..6952d00f
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/gen-tbls.c
@@ -0,0 +1,741 @@
+/*
+ * compiler/core/gen_tbls.c
+ *
+ * generates type tables and writes them to a file.
+ *
+ * MS
+ * 93/02/07
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/gen-tbls.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: gen-tbls.c,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:48  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.5  1997/06/19 09:17:16  wan
+ * Added isPdu flag to tables. Added value range checks during parsing.
+ *
+ * Revision 1.4  1997/05/07 15:18:34  wan
+ * Added (limited) size constraints, bitstring and enumeration names to tables
+ *
+ * Revision 1.3  1995/07/25 19:41:28  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:33:41  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:10  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "tbl.h"
+#include "gen-tbls.h"
+
+extern Module *usefulTypeModG;
+
+/* non-exported routine protos */
+void GenTypeDefIds  PROTO ((TBL *tbl, Module *m));
+int  GenTblModule   PROTO ((TBL *tbl, Module *m, TBLModule **newTbl));
+int  GenTblTypeDefs PROTO ((TBL *tbl, Module *m, TBLModule *tblMod));
+int  GenTblTypes    PROTO ((TBL *tbl, Module *m, TBLModule *tblMod, TypeDef *td, TBLTypeDef *tblTd));
+TBLType *GenTblTypesRec PROTO ((TBL *tbl,Module *m, TBLModule *tblMod, TypeDef *td, TBLTypeDef *tblTd, Type *t));
+
+
+static int abortTblTypeDefG;
+static int tblTypesTotalG;
+static int tblTagsTotalG;
+static int tblStringsTotalG;
+static int tblStringLenTotalG;
+
+static int tableFileVersionG;
+
+void
+GenTypeTbls PARAMS ((mods, fileName, tableFileVersion),
+    ModuleList *mods _AND_
+    char *fileName _AND_
+    int tableFileVersion)
+{
+    TBL tbl;
+    TBLModule *newTblMod;
+    FILE *tblFile;
+    ExpBuf *buf;
+    ExpBuf *tmpBuf;
+    Module *m;
+
+    tableFileVersionG = tableFileVersion;
+
+    tbl.modules = AsnListNew (sizeof (void*));
+    tbl.totalNumModules = 0;
+    tbl.totalNumTypeDefs = 0;
+    tbl.totalNumTypes = 0;
+    tbl.totalNumTags = 0;
+    tbl.totalNumStrings = 0;
+    tbl.totalLenStrings = 0;
+
+    /*
+     * Give each type def a unique id
+     * Id is stored in TypeDef's "tmpRefCount" since
+     * it was only used in the recursion pass.
+     * Also updates tbl.totalNumModules and
+     * tbl.totalNumTypeDefs appropriately
+     */
+    FOR_EACH_LIST_ELMT (m, mods)
+    {
+        GenTypeDefIds (&tbl, m);
+    }
+
+    /* number useful types if they are there any */
+    if (usefulTypeModG != NULL)
+        GenTypeDefIds (&tbl, usefulTypeModG);
+
+    /* convert each module from parse format to simpler table format */
+    FOR_EACH_LIST_ELMT (m, mods)
+    {
+        if (!GenTblModule (&tbl, m, &newTblMod))
+        {
+            fprintf (stderr,"ERROR: type table generator failed for module \"%s\", so file \"%s\" will not be written.\n", m->modId->name, fileName);
+            return;
+        }
+    }
+
+    /*
+     *  convert useful type mod from parse format to
+     *  simpler table format, if one was given
+     */
+    if (usefulTypeModG != NULL)
+    {
+        if (!GenTblModule (&tbl, usefulTypeModG, &newTblMod))
+        {
+            fprintf (stderr,"ERROR: type table generator failed for useful types module, file \"%s\" will not be written.\n",fileName);
+            return;
+        }
+        /* mark the module as useful */
+        newTblMod->isUseful = TRUE;
+    }
+
+    /* encode the TBLModules */
+    ExpBufInit (1024);
+    buf = ExpBufAllocBufAndData();
+
+    BEncTBL (&buf, &tbl);
+
+    if (ExpBufWriteError (&buf))
+    {
+        fprintf (stderr,"ERROR: buffer write error during encoding of type table.\n", fileName);
+        return;
+    }
+
+
+    /* open & truncate or create as file with given filename */
+    tblFile = fopen (fileName,"w");
+
+    if (tblFile == NULL)
+    {
+        fprintf (stderr,"ERROR: Could not open file \"%s\" for the type table.\n", fileName);
+        return;
+    }
+
+
+    /*
+     * go through buffer (s) and write encoded value
+     * to stdout
+     */
+    buf->curr = buf->dataStart;
+    for (tmpBuf = buf; tmpBuf != NULL; tmpBuf = tmpBuf->next)
+    {
+        fwrite (tmpBuf->dataStart, tmpBuf->dataEnd - tmpBuf->dataStart, 1, tblFile);
+    }
+
+    fclose (tblFile);
+
+} /* GenTypeTbls */
+
+
+/*
+ * The typeDefIds start at zero.  They are used as "portable"
+ * pointers.  Each TBLTypeDef has a unique typeDefId.
+ * The typeDefIds in a given TBLModule will be consecutive
+ * and increasing from the first typedef to the last.
+ *
+ * This routine gives each type def in the given module a unique
+ * integer identifier.
+ * This id is temporarily stored in the tmpRefCount field of the TypeDef
+ * (in the big parse tree).  The typeDefId is transfered
+ * to the TBL data structure after this.
+ *
+ * tbl.totalNumModules and tbl.totalNumTypeDefs are updated.
+ *
+ * ASSUMES: that tbl->totalNumModules is initialized to zero
+ *          and that tbl->totalNumTypeDefs is initialized to zero
+ *          on the first call to this routine.
+ *          This allows subsequent calls to give out the proper ids
+ *          to the types in the next module.
+ *
+ *  (the type ids range from 0 to tbl->totalNumTypeDefs-1 (inclusive))
+ */
+void
+GenTypeDefIds PARAMS ((tbl,m),
+    TBL *tbl _AND_
+    Module *m)
+{
+    TypeDef *td;
+
+    tbl->totalNumModules++;
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        td->tmpRefCount = tbl->totalNumTypeDefs;
+        tbl->totalNumTypeDefs++;
+    }
+
+} /* GenTypeDefIds */
+
+
+/*
+ * builds a TBLModule from the given module and appends it to
+ * the given TBL's module list.  Also updates the TBLs
+ * totals for modules, tags, typedefs and types.
+ * Returns TRUE is succeeded. FALSE is failed.
+ */
+int
+GenTblModule PARAMS ((tbl, m, newTblMod),
+    TBL *tbl _AND_
+    Module *m _AND_
+    TBLModule **newTblMod)
+{
+    TBLModule **mHndl;
+    TBLModule *tblMod;
+    int eLen;
+    AsnOid *result;
+
+    mHndl = AsnListAppend (tbl->modules);
+
+    tblMod = MT (TBLModule);
+    *newTblMod = *mHndl = tblMod;
+
+    /* copy the name */
+    tblMod->name.octetLen = strlen (m->modId->name);
+    tblMod->name.octs = Malloc (tblMod->name.octetLen + 1);
+    strcpy (tblMod->name.octs, m->modId->name);
+    tbl->totalNumStrings++;
+    tbl->totalLenStrings += tblMod->name.octetLen;
+
+    /* copy the OBJECT IDENTIFIER (if any) */
+    if (m->modId->oid != NULL)
+    {
+        /* convert the (linked) OID into a (encoded) AsnOid */
+        if (FlattenLinkedOid (m->modId->oid))
+        {
+            eLen = EncodedOidLen (m->modId->oid);
+            tblMod->id.octetLen = eLen;
+            tblMod->id.octs = (char*)Malloc (eLen);
+            BuildEncodedOid (m->modId->oid, &tblMod->id);
+            tbl->totalNumStrings++;
+            tbl->totalLenStrings += eLen;
+        }
+    }
+
+    /*
+     * useful defaults to false
+     * (ie assume the it is not the usefultypes modules)
+     */
+    tblMod->isUseful = FALSE;
+
+    /* now copy each of the type defs */
+    return GenTblTypeDefs (tbl, m, tblMod);
+
+} /* GenTblModule */
+
+
+/*
+ * converts typeDefs in Module format to TBLModule format
+ * returns TRUE for success, FALSE for failure.
+ */
+int
+GenTblTypeDefs PARAMS ((tbl, m, tblMod),
+    TBL *tbl _AND_
+    Module *m _AND_
+    TBLModule *tblMod)
+{
+    TypeDef *td;
+    TBLTypeDef **tblTdHndl;
+    TBLTypeDef *tblTd;
+    int isOk = TRUE;  /* init to no errors */
+
+    tblMod->typeDefs = AsnListNew (sizeof (void*));
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+
+        tblTd = MT (TBLTypeDef);
+
+        /* set type def id */
+        tblTd->typeDefId = td->tmpRefCount;
+
+        /* copy type def name */
+        tblTd->typeName.octetLen = strlen (td->definedName);
+        tblTd->typeName.octs = Malloc (tblTd->typeName.octetLen + 1);
+        strcpy (tblTd->typeName.octs, td->definedName);
+        tbl->totalNumStrings++;
+        tbl->totalLenStrings += tblTd->typeName.octetLen;
+
+/*
+	if (td->isPdu)
+	    tblTd->isPdu = MT (AsnNull);
+*/
+	if (m!=usefulTypeModG)
+	{
+	    MyString attr;
+	    char* attrName;
+	    char* attrValue;
+	    int result = FALSE;
+	    FOR_EACH_LIST_ELMT(attr,td->attrList)
+	    {
+		int loc = 0;
+		while (TRUE) 
+		{
+		    ParseAttr(attr,&loc,&attrName,&attrValue);
+		    if (!attrName)
+			break;
+		    if (!strcmp(attrName,"isPdu"))
+			if (ParseBool(attrValue,&result)<0)
+			    fprintf(stderr,"Warning: ignoring attribute with improper value (%s/%s)\n",attrName,attrValue);
+		    Free(attrValue);
+		}
+	    }
+	    if (result)
+		tblTd->isPdu = MT (AsnNull);
+	}
+
+
+        /* fill in type portion */
+        if (!GenTblTypes (tbl, m, tblMod, td, tblTd) && !abortTblTypeDefG)
+            isOk = FALSE;
+
+
+        /*
+         * add TBLtypeDef to TBLModule
+         * if no weird types were found
+         * (weird types are skipped)
+         */
+        if (!abortTblTypeDefG)
+        {
+            tblTdHndl = AsnListAppend (tblMod->typeDefs);
+            *tblTdHndl = tblTd;
+            tbl->totalNumTypes += tblTypesTotalG;
+            tbl->totalNumTags += tblTagsTotalG;
+            tbl->totalNumStrings += tblStringsTotalG;
+            tbl->totalLenStrings += tblStringLenTotalG;
+        }
+        /* else could free it */
+
+    }
+    return isOk;
+} /* GenTblTypeDefs */
+
+
+/*
+ * converts Module Type to a TBLModule Type.  attaches converted
+ * type info to the given tblTd.
+ * Returns TRUE for success, FALSE for failure.
+ */
+int
+GenTblTypes PARAMS ((tbl, m, tblMod, td, tblTd),
+    TBL *tbl _AND_
+    Module *m _AND_
+    TBLModule *tblMod _AND_
+    TypeDef *td _AND_
+    TBLTypeDef *tblTd)
+{
+    abortTblTypeDefG = FALSE;
+    tblTypesTotalG = 0;
+    tblTagsTotalG = 0;
+    tblStringsTotalG = 0;
+    tblStringLenTotalG = 0;
+
+    tblTd->type = GenTblTypesRec (tbl, m, tblMod, td, tblTd, td->type);
+
+    if (tblTd->type == NULL)
+        return FALSE; /* failed */
+    else
+        return TRUE;
+
+} /* GenTblTypes */
+
+BasicValue* 
+GetTblValue PARAMS ((v),
+    Value* v)
+{
+    switch (v->basicValue->choiceId)
+    {
+	case BASICVALUE_INTEGER:
+	    return v->basicValue;
+	default:
+	    return NULL;
+    }
+}
+
+enum BasicTypeChoiceId 
+GetTblBasicType PARAMS ((bt),
+    BasicType* bt)
+{
+    switch (bt->choiceId)
+    {
+    case BASICTYPE_LOCALTYPEREF:
+    case BASICTYPE_IMPORTTYPEREF:
+	return GetTblBasicType (bt->a.localTypeRef->link->type->basicType);
+    default:
+	return bt->choiceId;
+    }
+}
+
+TBLRange*
+GenTblValueRange PARAMS ((tbl, m, tblMod, s, doSize),
+    TBL *tbl _AND_
+    Module *m _AND_
+    TBLModule *tblMod _AND_
+    Subtype *s _AND_
+    int doSize)
+{
+    TBLRange* range;
+    BasicValue* from;
+    BasicValue* to;
+
+    if (tableFileVersionG<=1)
+	return NULL;
+
+    switch (s->choiceId) 
+    {
+	case SUBTYPE_SINGLE:
+	    switch (s->a.single->choiceId)
+	    {
+		case SUBTYPEVALUE_SINGLEVALUE:
+		    if (doSize)
+			return NULL;
+		    from = to = GetTblValue (s->a.single->a.singleValue);
+		    break;
+		case SUBTYPEVALUE_VALUERANGE:
+		    if (doSize)
+			return NULL;
+		    from =GetTblValue(s->a.single->a.valueRange->lowerEndValue);
+		    to = GetTblValue (s->a.single->a.valueRange->upperEndValue);
+		    break;
+		case SUBTYPEVALUE_SIZECONSTRAINT:
+		    if (!doSize)
+			return NULL;
+		    return GenTblValueRange (tbl, m, tblMod, 
+			    s->a.single->a.sizeConstraint, 0);
+		    break;
+		default:
+		    return NULL;
+	    }
+	    break;
+	case SUBTYPE_AND:
+	    if (s->a.and && LIST_COUNT(s->a.and)==1)
+		return GenTblValueRange (tbl, m, tblMod,
+			FIRST_LIST_ELMT(s->a.and), doSize);
+	    return NULL;
+	case SUBTYPE_OR:
+	    if (s->a.and && LIST_COUNT(s->a.or)==1)
+		return GenTblValueRange (tbl, m, tblMod,
+			FIRST_LIST_ELMT(s->a.or), doSize);
+	    return NULL;
+	case SUBTYPE_NOT:
+	    return NULL;
+    }
+    if (!from || !to)
+	return NULL;
+    range = MT (TBLRange);
+    range->from = from->a.integer;
+    range->to = to->a.integer;
+    return range;
+}
+
+TBLNamedNumberList*
+GenTblValues PARAMS ((tbl, m, tblMod, list),
+    TBL *tbl _AND_
+    Module *m _AND_
+    TBLModule *tblMod _AND_
+    NamedNumberList* list)
+{
+    TBLNamedNumberList* tnnl = NULL;
+
+    if (tableFileVersionG<=1)
+	return NULL;
+
+    if (list && !LIST_EMPTY(list))
+    {
+	ValueDef* vd;
+	tnnl = (TBLNamedNumberList*) AsnListNew(sizeof(void*));
+	FOR_EACH_LIST_ELMT(vd,list)
+	{
+	    BasicValue* bv = GetTblValue(vd->value);
+	    if (bv)
+	    {
+		TBLNamedNumber* tnn = MT(TBLNamedNumber);
+		*(TBLNamedNumber**)AsnListAppend(tnnl) = tnn;
+		tnn->value = bv->a.integer;
+		if (vd->definedName)
+		{
+		    tnn->name.octetLen = strlen(vd->definedName);
+		    tnn->name.octs = Malloc(tnn->name.octetLen+1);
+		    strcpy(tnn->name.octs,vd->definedName);
+		    tblStringsTotalG++;
+		    tblStringLenTotalG += tnn->name.octetLen;
+		}
+	    }
+	}
+
+    }
+    return tnnl;
+}
+
+TBLType*
+GenTblTypesRec PARAMS ((tbl, m, tblMod, td, tblTd, t),
+    TBL *tbl _AND_
+    Module *m _AND_
+    TBLModule *tblMod _AND_
+    TypeDef *td _AND_
+    TBLTypeDef *tblTd _AND_
+    Type *t)
+{
+    TBLType *tblT;
+    NamedType *e;
+    TBLType **tblTHndl;
+    Tag *tag;
+    TBLTag **tblTagHndl;
+
+    tblTypesTotalG++;
+    tblT = MT (TBLType);
+    tblT->content = MT (TBLTypeContent);
+    switch (t->basicType->choiceId)
+    {
+      case BASICTYPE_BOOLEAN:
+          tblT->typeId = TBL_BOOLEAN;
+          tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE;
+          break;
+
+      case BASICTYPE_INTEGER:
+          tblT->typeId = TBL_INTEGER;
+          tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE;
+          break;
+
+      case BASICTYPE_BITSTRING:
+          tblT->typeId = TBL_BITSTRING;
+          tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE;
+	  tblT->values = GenTblValues(tbl,m,tblMod,t->basicType->a.bitString);
+          break;
+
+      case BASICTYPE_OCTETSTRING:
+          tblT->typeId = TBL_OCTETSTRING;
+          tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE;
+	  if (t->subtypes)
+	      tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1);
+          break;
+
+      case BASICTYPE_NULL:
+          tblT->typeId = TBL_NULL;
+          tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE;
+          break;
+
+      case BASICTYPE_OID:
+          tblT->typeId = TBL_OID;
+          tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE;
+          break;
+
+      case BASICTYPE_REAL:
+          tblT->typeId = TBL_REAL;
+          tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE;
+          break;
+
+      case BASICTYPE_ENUMERATED:
+          tblT->typeId = TBL_ENUMERATED;
+          tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE;
+	  tblT->values = GenTblValues(tbl,m,tblMod,t->basicType->a.enumerated);
+          break;
+
+      case BASICTYPE_SEQUENCE:
+          tblT->typeId = TBL_SEQUENCE;
+          tblT->content->choiceId = TBLTYPECONTENT_ELMTS;
+          tblT->content->a.elmts = AsnListNew (sizeof (void*));
+          FOR_EACH_LIST_ELMT (e, t->basicType->a.sequence)
+          {
+              tblTHndl = AsnListAppend (tblT->content->a.elmts);
+              *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type);
+
+              if (*tblTHndl == NULL)
+                  break;
+
+              if (e->fieldName != NULL)
+              {
+                  (**tblTHndl).fieldName.octetLen = strlen (e->fieldName);
+                  (**tblTHndl).fieldName.octs =
+                      Malloc ((**tblTHndl).fieldName.octetLen + 1);
+                  strcpy ((**tblTHndl).fieldName.octs, e->fieldName);
+                  tblStringsTotalG++;
+                  tblStringLenTotalG += (**tblTHndl).fieldName.octetLen;
+              }
+
+             (**tblTHndl).optional =
+                 ((e->type->optional) || (e->type->defaultVal != NULL));
+          }
+
+          break;
+
+      case BASICTYPE_SET:
+          tblT->typeId = TBL_SET;
+          tblT->content->choiceId = TBLTYPECONTENT_ELMTS;
+          tblT->content->a.elmts = AsnListNew (sizeof (void*));
+          FOR_EACH_LIST_ELMT (e, t->basicType->a.set)
+          {
+              tblTHndl = AsnListAppend (tblT->content->a.elmts);
+              *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type);
+
+              if (*tblTHndl == NULL)
+                  break;
+
+              if (e->fieldName != NULL)
+              {
+                  (**tblTHndl).fieldName.octetLen = strlen (e->fieldName);
+                  (**tblTHndl).fieldName.octs =
+                      Malloc ((**tblTHndl).fieldName.octetLen + 1);
+                  strcpy ((**tblTHndl).fieldName.octs, e->fieldName);
+                  tblStringsTotalG++;
+                  tblStringLenTotalG += (**tblTHndl).fieldName.octetLen;
+              }
+
+             (**tblTHndl).optional =
+                 ((e->type->optional) || (e->type->defaultVal != NULL));
+
+          }
+          break;
+
+      case BASICTYPE_SEQUENCEOF:
+          tblT->typeId = TBL_SEQUENCEOF;
+          tblT->content->choiceId = TBLTYPECONTENT_ELMTS;
+          tblT->content->a.elmts = AsnListNew (sizeof (void*));
+          tblTHndl = AsnListAppend (tblT->content->a.elmts);
+          *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, t->basicType->a.sequenceOf);
+	  if (t->subtypes)
+	      tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1);
+          break;
+
+      case BASICTYPE_SETOF:
+          tblT->typeId = TBL_SETOF;
+          tblT->content->choiceId = TBLTYPECONTENT_ELMTS;
+          tblT->content->a.elmts = AsnListNew (sizeof (void*));
+          tblTHndl = AsnListAppend (tblT->content->a.elmts);
+          *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, t->basicType->a.setOf);
+	  if (t->subtypes)
+	      tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1);
+          break;
+
+      case BASICTYPE_CHOICE:
+          tblT->typeId = TBL_CHOICE;
+          tblT->content->choiceId = TBLTYPECONTENT_ELMTS;
+          tblT->content->a.elmts = AsnListNew (sizeof (void*));
+          FOR_EACH_LIST_ELMT (e, t->basicType->a.set)
+          {
+              tblTHndl = AsnListAppend (tblT->content->a.elmts);
+              *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type);
+
+              if (*tblTHndl == NULL)
+                  break;
+
+              if (e->fieldName != NULL)
+              {
+                  (**tblTHndl).fieldName.octetLen = strlen (e->fieldName);
+                  (**tblTHndl).fieldName.octs =
+                      Malloc ((**tblTHndl).fieldName.octetLen + 1);
+                  strcpy ((**tblTHndl).fieldName.octs, e->fieldName);
+                  tblStringsTotalG++;
+                  tblStringLenTotalG += (**tblTHndl).fieldName.octetLen;
+              }
+
+             (**tblTHndl).optional =
+                 ((e->type->optional) || (e->type->defaultVal != NULL));
+
+          }
+          break;
+
+      case BASICTYPE_LOCALTYPEREF:
+      case BASICTYPE_IMPORTTYPEREF:
+          tblT->typeId = TBL_TYPEREF;
+          tblT->content->choiceId = TBLTYPECONTENT_TYPEREF;
+          tblT->content->a.typeRef = MT (TBLTypeRef);
+          tblT->content->a.typeRef->implicit = t->implicit;
+          tblT->content->a.typeRef->typeDef  =
+              t->basicType->a.localTypeRef->link->tmpRefCount;
+          break;
+
+      default:
+          if (!abortTblTypeDefG) /* only print first time  */
+              fprintf (stderr,"WARNING: Type definition \"%s\" will not be included in the type table because it contains a weird type.\n",td->definedName);
+          abortTblTypeDefG = TRUE;
+          Free (tblT->content);
+          Free (tblT);
+          tblT = NULL;
+          break;
+    }
+
+    /* handle constraints */
+    if (t->subtypes)
+    {
+	switch (GetTblBasicType(t->basicType))
+	{
+	case BASICTYPE_INTEGER:
+	    tblT->constraint = GenTblValueRange(tbl,m,tblMod,t->subtypes,0);
+	    break;
+	case BASICTYPE_OCTETSTRING:
+	case BASICTYPE_SEQUENCEOF:
+	    tblT->constraint = GenTblValueRange(tbl,m,tblMod,t->subtypes,1);
+	    break;
+	default:
+	    break;
+	}
+    }
+
+    /* copy the tags */
+    if ((tblT != NULL) &&
+        ((t->tags != NULL) && (!LIST_EMPTY (t->tags))))
+    {
+        tblT->tagList = AsnListNew (sizeof (void*));
+        FOR_EACH_LIST_ELMT (tag, t->tags)
+        {
+            tblTagsTotalG++;
+            tblTagHndl = AsnListAppend (tblT->tagList);
+            *tblTagHndl = MT (TBLTag);
+            switch (tag->tclass)
+            {
+              case UNIV:
+                (**tblTagHndl).tclass = UNIVERSAL;
+                break;
+              case APPL:
+                (**tblTagHndl).tclass = APPLICATION;
+                break;
+              case CNTX:
+                (**tblTagHndl).tclass = CONTEXT;
+                break;
+              case PRIV:
+                (**tblTagHndl).tclass = PRIVATE;
+                break;
+            }
+            (**tblTagHndl).code = tag->code;
+        }
+    }
+
+    return tblT;
+} /* GenTblTypesRec */
diff --git a/SecuritySNACCRuntime/compiler/core/gen-tbls.h b/SecuritySNACCRuntime/compiler/core/gen-tbls.h
new file mode 100644
index 00000000..b986c0cf
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/gen-tbls.h
@@ -0,0 +1,40 @@
+/*
+ * compiler/core/gen_tbls.h
+ *
+ * generates type tables and writes them to a file.
+ *
+ * MS
+ * 93/02/07
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/gen-tbls.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: gen-tbls.h,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:48  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1997/05/07 15:18:35  wan
+ * Added (limited) size constraints, bitstring and enumeration names to tables
+ *
+ * Revision 1.3  1995/07/25 19:41:29  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:44  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:11  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+void GenTypeTbls PROTO ((ModuleList *mods, char *fileName, int tableFileVersion));
diff --git a/SecuritySNACCRuntime/compiler/core/lex-asn1.c b/SecuritySNACCRuntime/compiler/core/lex-asn1.c
new file mode 100644
index 00000000..209ad803
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/lex-asn1.c
@@ -0,0 +1,3496 @@
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yyleng = (int) (yy_cp - yy_bp); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 132
+#define YY_END_OF_BUFFER 133
+static yyconst short int yy_accept[698] =
+    {   0,
+        0,    0,    0,    0,    0,    0,  133,  132,    3,  132,
+      132,    8,    9,    5,   13,    4,  129,  128,  132,   16,
+       12,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+      126,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+       10,   11,  127,    6,   15,    7,   60,  122,    3,    0,
+      125,    0,    0,    0,    0,  128,    0,    0,    0,  126,
+      126,  126,  126,  126,  126,  126,  126,   97,  126,  126,
+      126,  126,   57,  126,  126,  126,  126,  126,  126,  126,
+      126,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+      126,   25,  126,  126,  126,  126,  126,  126,  126,  126,
+
+      126,  126,  126,  126,  102,  126,  126,  126,  126,    0,
+        0,    0,  127,  123,  124,    0,    0,  131,    0,    0,
+       14,    0,  126,  126,  126,  126,   29,  126,  126,    0,
+      126,  126,   20,  126,  126,  126,  126,  126,  126,  126,
+      126,  126,   40,  126,  126,  126,  126,  126,   88,  126,
+      126,  126,  126,  126,  126,  126,   49,   48,  126,  126,
+      126,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+      126,  126,  126,  126,  126,  126,  126,   26,  126,  126,
+      126,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+      126,  126,  126,    1,    2,    0,    0,  126,  126,  126,
+
+      126,  126,  126,  126,  126,   69,  126,  126,  126,  126,
+      126,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+      126,  126,  126,  126,   51,  126,  126,  126,  126,  126,
+      126,  126,  126,   23,  126,  126,  126,  126,  126,  126,
+      126,   94,  126,  126,  126,   46,  126,  126,  126,  126,
+      126,  126,  126,  126,  126,   50,  126,  126,  126,  126,
+      126,   17,  126,  126,   37,  126,  126,  126,   52,    0,
+        0,  126,  126,  126,  126,  126,  126,  126,   39,    0,
+      126,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+      126,  126,  126,   67,  126,  126,  126,   38,  126,  126,
+
+      126,  120,  126,  126,  126,  126,  126,   22,  126,  126,
+      126,  126,    0,   93,  126,  126,  126,  126,  126,  126,
+      126,  126,  126,  126,  126,  126,  126,  126,  126,  126,
+      126,  126,  106,  126,  126,  126,  126,    0,    0,   55,
+      126,  116,  126,   61,  126,  126,  126,  126,   28,   85,
+      126,  126,  126,  126,  126,  126,  121,  126,  126,  126,
+      126,   65,  126,  126,  126,  126,  126,  126,  126,  126,
+       66,    0,   92,  126,  126,  100,  126,  126,  126,  126,
+      126,  126,  126,   96,   75,  126,   64,  126,  126,  126,
+      111,  117,   21,  126,  126,  115,    0,  126,   71,  126,
+
+      126,    0,   61,  126,  126,  126,  126,  126,   18,  126,
+      126,  126,   32,   56,  126,  126,  126,  126,  126,  126,
+       44,  126,  126,   45,  126,  126,   19,  126,    0,    0,
+      126,  126,  126,  126,  126,   54,   36,  126,  126,  126,
+      126,  126,  126,  126,  126,  126,  126,  126,    0,  126,
+       99,    0,  130,    0,  126,  126,  126,   63,  126,  126,
+      126,   87,  126,   90,  126,  126,  126,   42,  126,   27,
+       47,  126,  126,    0,  126,  126,  126,   31,  126,  126,
+      126,  126,  126,  126,  126,   24,  126,  126,  126,  126,
+       91,  126,  126,    0,    0,  126,  126,  109,  126,  126,
+
+       53,    0,  126,  126,  126,  110,  126,   86,   76,  126,
+        0,  126,  126,   62,   68,  126,  113,   98,  119,   77,
+        0,  112,  126,    0,  126,  126,  126,   34,    0,    0,
+      126,  126,  126,  126,  126,  126,  126,   70,   33,    0,
+      126,  126,  126,   43,    0,   84,  126,    0,  126,  126,
+       80,  126,  126,   89,    0,  126,  107,  126,    0,    0,
+      126,  126,  126,  126,  126,  126,   35,    0,  126,   41,
+      118,  126,  126,    0,  114,  126,  126,  126,    0,  126,
+      126,    0,    0,  126,  126,  126,  126,  126,  126,    0,
+        0,  126,  126,  126,    0,  126,  126,  126,    0,  126,
+
+       72,    0,    0,  101,  126,  126,  126,  126,  126,  126,
+      126,    0,  126,  126,  126,    0,  126,   58,  126,    0,
+      126,    0,    0,  104,  126,  126,  126,  126,  126,  126,
+        0,  126,  126,   59,    0,  126,  126,    0,  126,    0,
+        0,  126,  103,  126,  126,  126,  126,    0,   81,  126,
+        0,  126,  126,    0,   82,    0,    0,  126,  126,   78,
+      126,  126,   81,  126,    0,   30,  126,   82,    0,   78,
+      126,  126,  126,  126,  126,   30,  108,    0,  105,   95,
+      126,  126,  126,   95,   73,  126,   83,    0,  126,  126,
+      126,  126,  126,  126,   79,   74,    0
+
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    4,    1,    1,    1,    1,    5,    6,
+        7,    1,    1,    8,    9,   10,    1,   11,   12,   13,
+       13,   13,   13,   13,   13,   13,   13,   14,   15,   16,
+       17,    1,    1,    1,   18,   19,   20,   21,   22,   23,
+       24,   25,   26,   27,   28,   29,   30,   31,   32,   33,
+       34,   35,   36,   37,   38,   39,   40,   41,   42,   43,
+       44,    1,   45,    1,    1,    1,   46,   47,   48,   47,
+
+       47,   47,   49,   49,   49,   49,   49,   49,   49,   50,
+       49,   49,   49,   49,   51,   49,   49,   49,   49,   49,
+       49,   49,   52,   53,   54,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst int yy_meta[55] =
+    {   0,
+        1,    1,    1,    1,    2,    1,    1,    1,    3,    1,
+        4,    4,    4,    1,    1,    1,    1,    4,    4,    4,
+        4,    4,    4,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    1,    1,    4,    4,    4,    3,    3,
+        3,    1,    1,    1
+    } ;
+
+static yyconst short int yy_base[706] =
+    {   0,
+        0,    0,    0,    0,    0,    0,  508, 3540,   53,  499,
+       52, 3540, 3540, 3540,  491, 3540, 3540,   47,  482, 3540,
+     3540,   63,   96,   98,  113,  115,  126,  127,  140,  141,
+      158,  153,  179,  188,  155,  187,  200,  205,  212,  217,
+       41, 3540,  484, 3540, 3540, 3540, 3540, 3540,   65,  478,
+      472,   54,  131,  466,  237,   58,  452,  162,  248,  226,
+      239,  243,  263,  274,  247,  279,  281,  290,  456,  296,
+      302,  302,  304,  305,  339,  323,  331,  338,  333,  354,
+      359,  361,  363,  379,  387,  395,  402,  411,  417,  428,
+      433,  439,  441,  397,  442,  453,  455,  471,  479,  486,
+
+      502,  495,  507,  522,  524,  530,  539,  541,  547,  415,
+      412,  440,  436, 3540, 3540,  416,  151, 3540,  185,  282,
+     3540,  420,  549,  547,  556,  573,  580,  582,  589,  407,
+      588,  597,  599,  606,  611,  626,  631,  637,  640,  639,
+      657,  664,  669,  666,  669,  678,  683,  686,  691,  727,
+      705,  713,  718,  726,  727,  739,  740,  748,  762,  751,
+      753,  770,  775,  784,  796,  789,  798,  801,  810,  819,
+      828,  833,  836,  851,  861,  867,  869,  780,  878,  882,
+      884,  891,  844,  899,  908,  915,  914,  921,  928,  933,
+      935,  936,  947, 3540, 3540,  408,  384,  954,  962,  969,
+
+      977,  988,  976, 1004, 1013, 1022,  995, 1009, 1013, 1014,
+     1025, 1027, 1028, 1042, 1053, 1050, 1055, 1072, 1081, 1074,
+     1079, 1093, 1098, 1100, 1115, 1112, 1117, 1124, 1129, 1141,
+     1150, 1143, 1155, 1158, 1175, 1182, 1191, 1181, 1190, 1218,
+     1226, 1228, 1212, 1221, 1219, 1220, 1233, 1244, 1251, 1252,
+     1259, 1266, 1274, 1281, 1292, 1289, 1300, 1313, 1311, 1325,
+     1330, 1337, 1339, 1342, 1351, 1354, 1365, 1369, 1375,  483,
+      366, 1380, 1386, 1391, 1390, 1399, 1410, 1416, 1413,  378,
+     1444, 1418, 1435, 1437, 1462, 1453, 1461, 1456, 1467, 1465,
+     1478, 1482, 1493, 1498, 1504, 1510, 1516, 1521, 1536, 1538,
+
+     1543, 1554, 1560, 1559, 1568, 1593, 1595, 1603, 1605, 1613,
+     1615, 1608,  367, 1618, 1644, 1649, 1636, 1643, 1577, 1635,
+     1638, 1659, 1661, 1662, 1674, 1685, 1687, 1688, 1699, 1706,
+     1711, 1713, 1747, 1738, 1743, 1749, 1760,  508,  351, 1755,
+     1767, 1772, 1778, 1783, 1789, 1794, 1800, 1809, 1811, 1818,
+     1817, 1828, 1830, 1831, 1843, 1845, 1852, 1854, 1872, 1878,
+     1884, 1889, 1884, 1892, 1897, 1899, 1910, 1911, 1918, 1932,
+     1937,  349, 1959, 1944, 1955, 1956, 1958, 1970, 1977, 1984,
+     1985, 1998, 2003, 2006, 2011, 2020, 2025, 2028, 1985, 2036,
+     2052, 2057, 2059, 2064, 2067, 2069,  351, 2072, 2103, 2113,
+
+     2081,  308, 3540, 2095, 2103, 2104, 2116, 2125, 2130, 2133,
+     2144, 2151, 2152, 2159, 2166, 2173, 2174, 2181, 2188, 2195,
+     2196, 2207, 2209, 2218, 2221, 2226, 2233, 2240,  360,  306,
+     2267, 2251, 2252, 2263, 2267, 2279, 2284, 2284, 2287, 2301,
+     2301, 2306, 2309, 2314, 2328, 2331, 2343, 2336,  318, 2374,
+     2377,  400, 3540,  424, 2379, 2387, 2371, 2376, 2384, 2397,
+     2418, 2392, 2409, 2410, 2411, 2424, 2432, 2433, 2441, 2454,
+     2455, 2456, 2405,  317, 2463, 2468, 2477, 2480, 2485, 2492,
+     2504, 2507, 2506, 2515, 2542, 2550, 2532, 2534, 2559, 2568,
+     2579, 2581, 2584, 2576,  844, 2577, 2593, 2600, 2595, 2598,
+
+     2612, 1669, 2619, 2621, 2633, 2634, 2636, 2668, 2670, 2659,
+      296, 2663, 2674, 2683, 2689, 2694, 2701, 2709, 2716, 2718,
+      288, 2741, 2743, 1945, 2745, 2754, 2756, 2758,  273,  261,
+     2755, 2757, 2775, 2781, 2781, 2784, 2796, 2798, 2799,  264,
+     2807, 2821, 2828, 2810,  266, 2842, 2853,  246, 2839, 2853,
+     2854, 2856, 2871, 2878,  241, 2879, 2880, 2893,  245,  233,
+     2901, 2902, 2904, 2854, 2919, 2928, 2947,  221, 2931, 2936,
+     2938, 2949, 2950,  219, 2957, 2962, 2971, 2974,  216, 2983,
+     2988,  218,  208, 2996, 3005, 3007, 3014, 3026, 3033,   42,
+      209, 3032, 3061, 3064,  207, 3057, 3057, 3060,  196, 3078,
+
+     3071,  198,  197, 3083, 3086, 3101, 3100, 3108, 3115, 3122,
+     3127,  180, 3129, 3140, 3141,  184, 3148, 3155, 3162,  176,
+     3163,  166,  155, 3170, 3177, 3185, 3194, 3196, 3199, 3207,
+      171, 3218, 3221, 3226,  163, 3229, 3240,  164, 3243,  152,
+      152, 3248, 3251, 3262, 3265, 3273, 3270,  115, 3291, 3299,
+      112, 3301, 3306,   90, 3323,   89,   83, 3305, 3318, 3326,
+     3329, 3331, 3540, 3340,   82, 3343, 3348, 3540,   77, 3540,
+     3355, 3357, 3362, 3372, 3387, 3540, 3389,   71, 3394, 3396,
+     3411, 3410, 3411, 3540, 3413, 3438, 3447,   58, 3455, 3437,
+     3458, 3444, 3449, 3461, 3468, 3470, 3540, 3512, 3516, 3520,
+
+     3523, 3525, 3529, 3531, 3535
+    } ;
+
+static yyconst short int yy_def[706] =
+    {   0,
+      697,    1,  698,  698,  699,  699,  697,  697,  697,  700,
+      701,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,   22,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
+      697,  697,  702,  697,  697,  697,  697,  697,  697,  700,
+      697,  697,  701,  701,  703,  697,  697,  697,   23,   23,
+       23,   33,   33,   33,   23,   33,   33,   33,  704,   33,
+       33,   23,   23,   23,   59,   23,   33,   33,   33,   33,
+       33,   33,   23,   33,   33,   33,   33,   33,   33,   33,
+       33,   33,   23,   23,   23,   23,   23,   33,   33,   33,
+
+       33,   33,   33,   33,   33,   33,   33,   33,   33,  697,
+      697,  702,  702,  697,  697,  697,  703,  697,  703,  703,
+      697,  697,   23,   23,   23,   33,   33,   33,   33,  704,
+       23,   23,   23,   23,   23,   33,   33,   33,   23,   23,
+       33,   33,   33,   59,   23,   23,   23,   23,   23,   59,
+       23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   33,   33,   33,   33,   33,   23,
+       23,   23,   59,   33,   33,   33,   23,   23,   23,   23,
+       23,   23,   23,  697,  697,  703,  697,   23,   23,   23,
+
+       23,   23,   23,   59,   59,   59,   23,   33,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   33,   33,   33,   23,   23,   59,
+       59,   59,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   33,   33,  703,
+      697,   33,   33,   33,   23,   23,   33,   23,   23,   59,
+       59,   23,   23,   23,   59,   33,   33,   23,   23,   23,
+       23,   33,   33,   33,   33,   33,   33,   33,   33,   33,
+
+       33,   33,   33,   23,   23,   59,   59,   59,   59,   59,
+       59,   23,   59,   59,   59,   59,   33,   33,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   59,   33,   33,   33,   33,  703,  697,   33,
+       33,   33,   33,   33,   33,   33,   33,   33,   33,   33,
+       23,   23,   23,   23,   23,   23,   23,   23,   33,   33,
+       33,   33,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   59,   59,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,   33,   33,
+       33,   33,   33,   33,   23,   23,   59,   23,   59,   59,
+
+       23,  705,  697,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   23,   23,   23,   23,  697,   59,
+       59,   23,   23,   23,   33,   33,   33,   23,   23,   33,
+       23,   23,   23,   23,   23,   23,   23,   23,   59,   59,
+       59,  705,  697,  705,   59,   59,   23,   23,   23,   23,
+       59,   59,   23,   23,   23,   23,   23,   23,   23,   23,
+       23,   23,   33,  697,   23,   23,   23,   23,   23,   23,
+       23,   23,   23,   23,   59,   59,   23,   23,   59,   59,
+       59,   59,   59,  697,   59,   33,   23,   23,   23,   23,
+
+       23,  697,   23,   23,   23,   23,   23,   59,   59,   23,
+      697,   33,   33,   33,   33,   33,   33,   33,   33,   33,
+       59,   59,   59,  697,   59,   59,   59,   59,  697,  697,
+       23,   23,   33,   33,   23,   23,   23,   23,   23,  697,
+       23,   23,   23,   23,   59,   59,   59,  697,   23,   23,
+       23,   23,   23,   23,  697,   23,   23,   23,  697,  697,
+       23,   23,   23,   33,   33,   33,   59,  697,   23,   23,
+       23,   23,   23,  697,   23,   23,   23,   23,  697,   23,
+       23,  697,  697,   23,   23,   23,   23,   23,   23,   59,
+      697,   59,   59,   59,  697,   33,   23,   23,  697,   23,
+
+       23,  697,  697,   23,   23,   23,   23,   23,   23,   23,
+       23,  697,   23,   23,   23,  697,   23,   23,   23,  697,
+       23,  697,  697,   23,   23,   23,   23,   23,   23,   23,
+      697,   23,   23,   23,  697,   23,   23,  697,   23,  697,
+      697,   23,   23,   23,   23,   23,   23,  697,   23,   33,
+      697,   33,   33,  697,   33,  697,  697,   23,   23,   23,
+       23,   23,  697,   23,  697,   23,   23,  697,  697,  697,
+       23,   23,   23,   33,   33,  697,   33,  697,   33,   33,
+       33,   23,   23,  697,   23,   59,   59,   59,   59,   23,
+       59,   23,   23,   23,   23,   23,    0,  697,  697,  697,
+
+      697,  697,  697,  697,  697
+    } ;
+
+static yyconst short int yy_nxt[3595] =
+    {   0,
+        8,    9,    9,   10,   11,   12,   13,   14,   15,   16,
+       17,   18,   18,   19,   20,   21,    8,   22,   23,   24,
+       25,   26,   27,   28,   28,   29,   28,   28,   30,   31,
+       32,   33,   34,   28,   35,   36,   37,   38,   39,   40,
+       28,   28,   28,   41,   42,   43,   43,   43,   43,   43,
+       43,   44,   45,   46,   49,   49,   52,   56,   56,   56,
+      110,  610,   53,   53,   58,   58,   49,   49,   56,   56,
+       56,   59,  114,   60,   60,   60,  111,  611,  115,  689,
+       60,   61,   62,   60,   60,   60,   60,   60,   60,   60,
+       60,   63,   64,   65,   60,   66,   60,   67,   68,   60,
+
+       60,   60,   60,   60,   60,   60,  684,  678,   69,   69,
+       69,   69,   69,   69,   60,   60,  676,   70,  670,   60,
+      669,   71,   74,   60,   60,  668,   60,   72,   60,   75,
+       60,   60,   76,  665,   77,   52,   60,   73,   60,   60,
+       60,   53,   53,   81,   60,   78,   60,   60,   60,   79,
+      663,   60,   60,  118,   60,   80,   60,   82,   60,  119,
+       83,   60,   60,   58,   58,   60,   86,   60,   60,   84,
+       85,   60,   60,  657,   60,   87,   98,  656,   60,   60,
+       60,   60,   60,   88,   60,  654,   60,  118,  651,   60,
+       89,  122,  648,  118,   60,  641,   60,   90,   91,   60,
+
+       60,   92,  640,  638,   60,   94,  635,  631,   99,   60,
+       60,   93,  100,   60,  623,  622,   95,  104,   60,   96,
+       60,   60,   97,  101,  102,   60,   60,  620,  103,   60,
+       60,  105,  616,   60,  106,  107,   60,  108,   60,  118,
+      612,   60,  109,   60,  603,  119,   60,   60,   60,  697,
+      697,   60,  602,   60,  599,  595,  697,   60,   60,  591,
+       60,   60,  124,  583,   60,   60,  582,   60,   60,   60,
+       60,  579,   60,   60,  123,   60,  574,   60,   60,   60,
+       60,   60,   60,  572,  118,   60,  125,  120,  127,   60,
+      119,  126,   60,   60,  568,   60,   60,   60,   60,   60,
+
+       60,   60,  560,   60,  129,  559,   60,  553,   60,   60,
+      453,  128,   60,   60,   60,   60,  454,  548,   60,  131,
+       60,   60,   60,   60,   60,   60,   60,   60,   60,   60,
+       60,  196,  132,  134,   60,   60,  135,  511,  133,  492,
+       58,   58,  475,   60,   60,   60,   60,   59,  138,   60,
+       60,   60,   60,  139,   60,   60,   60,  142,  143,  140,
+       60,  429,  429,   60,   60,   60,  141,  145,  136,  137,
+       60,  447,   60,   60,  428,  144,   60,   60,   60,   60,
+       60,   60,  403,   60,   60,  474,  146,  148,   60,  122,
+      147,   60,  378,   60,  150,  149,  126,   60,   60,  347,
+
+      339,   60,  453,  271,   60,   60,  152,  153,  454,   60,
+      118,  151,  154,   60,   60,  697,  119,   60,   60,   60,
+       60,   60,  164,  155,   60,  156,  118,   60,   60,   60,
+       60,  165,  453,   60,   60,   60,   60,  197,   60,   60,
+      115,  158,  157,   60,  112,  159,   60,   60,  697,   60,
+       60,   60,   60,  270,  160,   60,  195,   60,   60,  194,
+       60,   60,  162,   60,  130,   60,   60,   60,  121,  161,
+      116,   60,   60,   60,   60,   50,  168,  163,   60,  166,
+      169,   51,   60,   60,   60,  118,  170,  167,  171,   60,
+      172,  119,  112,  173,   60,   57,   60,   60,  176,   55,
+
+      174,   60,   51,   60,   60,   60,  175,  697,   60,  179,
+      118,   60,  177,  183,   60,  178,  119,   60,   60,  181,
+       60,   60,  697,  697,   60,   60,   60,  184,  180,   60,
+      338,  697,  697,  697,   60,  697,  182,  185,  697,   60,
+       60,   60,   60,   60,   60,  186,   60,  188,   60,   60,
+      697,  187,   60,  697,   60,  402,   60,  190,   60,   60,
+       60,   60,   60,   60,  191,   60,   60,  189,  200,   60,
+      198,   60,   60,   60,   60,  697,  192,   60,   60,   60,
+       60,   60,  697,  193,  697,  199,  697,  201,   60,  697,
+       60,   60,  202,  697,  697,   60,  697,   60,   60,   60,
+
+       60,   60,   60,  697,   60,   60,  697,   60,   60,   60,
+      203,   60,   60,  205,   60,  697,  697,  206,   60,   60,
+       60,   60,   60,  697,   60,  697,  204,   60,   60,   60,
+       60,   60,   60,  697,  207,  697,  208,   60,   60,  697,
+       60,  697,   60,  126,   60,   60,  209,   60,   60,   60,
+       60,  697,   60,   60,  697,   60,   60,  213,  210,   60,
+       60,   60,  697,   60,  216,  214,  211,   58,   58,   60,
+       60,   60,  697,  212,   59,   60,  217,  697,  215,   60,
+       60,   60,   60,   60,  697,  697,   60,   60,   60,   60,
+       60,   60,  697,  697,   60,  219,   60,  697,  218,   60,
+
+      220,   60,  697,   60,  223,  697,  221,   60,   60,  222,
+       60,   60,   60,  697,   60,  697,   60,   60,  697,   60,
+      697,  224,   60,  697,   60,  697,   60,   60,   58,   58,
+       60,  697,   60,  226,   60,   59,  227,  697,   60,  229,
+      697,  228,  697,   60,   60,  697,   60,   60,  231,   60,
+      697,   60,   60,  697,   60,  697,  225,   60,   60,   60,
+       60,   60,  230,  697,   60,   60,  232,   60,   60,   60,
+       60,   60,  235,   60,  236,  697,   60,  697,   60,   60,
+       60,   60,   60,   60,   60,  233,  697,   60,  697,   60,
+      234,   60,   60,   60,   60,   60,   60,  697,   60,   60,
+
+      238,   60,   60,   60,  237,   60,   60,  697,  697,   60,
+       60,   60,   60,  240,   60,   60,   60,   60,  239,   60,
+       60,   60,   60,   60,  241,   60,   60,   60,  697,   60,
+       60,   60,   60,  697,  242,   60,  243,   60,  697,   60,
+       60,   60,   60,  697,   60,   58,   58,  697,  244,   60,
+       60,   60,   59,   60,   60,  245,  246,  248,   60,   60,
+       60,  249,  531,  697,   60,  532,  697,   60,  126,   60,
+      247,  697,   60,  259,   60,  533,   60,   60,  697,   60,
+       60,  534,  250,   60,  697,   60,   60,   60,   60,   60,
+      697,   60,   60,  251,  697,  697,   60,   60,  252,   60,
+
+       60,   60,  697,  256,  253,   60,  254,   60,  255,   60,
+       60,  697,   60,   60,  697,   60,  258,   60,   60,  697,
+      257,   60,   60,   60,  697,   60,   60,   60,  697,  697,
+       60,  260,   60,   60,   60,  263,  697,   60,  697,   60,
+       60,  697,   60,  697,  261,   60,   60,   60,  697,  265,
+      262,  264,   60,   60,   60,   60,   60,   60,  266,   60,
+       60,  268,   60,  697,   60,  697,   60,   60,   60,   60,
+      697,  269,   60,  267,   60,   60,   60,   60,   60,   60,
+      697,  697,  697,   60,  272,   60,  697,   60,   60,  697,
+       60,  697,  697,   60,   60,   60,  273,   60,   60,  697,
+
+       60,  277,   60,   60,  274,   58,   58,   60,   60,   60,
+       60,  275,   59,   60,   58,   58,  281,   60,   60,   60,
+       60,   59,  276,   58,   58,  697,   60,   60,  282,   60,
+      280,   60,  697,  278,  283,   60,   60,  697,   60,   60,
+      697,   60,   64,  279,   60,  284,   60,  697,   60,   60,
+       60,   64,  286,   60,   60,   60,   60,  697,   60,   60,
+      697,  697,  285,   60,  697,  287,   60,   60,   60,   60,
+      289,   60,  288,   60,   60,   60,   60,  697,   60,  697,
+       60,   60,  697,   60,   60,  697,   60,  697,  290,  291,
+      697,   60,  697,   60,   60,   60,   60,   60,  126,   60,
+
+       60,  697,  293,   60,  295,   60,   60,  697,  294,  697,
+       60,  697,   60,  292,   60,   60,  697,  697,   60,   60,
+       60,  298,   60,   60,   60,   60,  697,  296,  297,   60,
+      697,   60,  126,   60,   60,  697,   60,  299,   60,   60,
+       60,   60,   60,   60,  697,   60,   60,  697,   60,   60,
+       60,  300,  697,   60,   60,   60,   60,  697,   60,  697,
+       60,  301,   60,  697,  305,   60,  303,  697,   60,  302,
+       60,   60,   60,  304,   60,   60,   60,  697,  697,   60,
+       60,   60,   60,   60,   60,  697,   60,  697,  697,   60,
+      306,   60,  697,   60,  307,  697,   60,   60,  697,   60,
+
+       60,   60,   60,  697,   60,  697,   60,   60,  309,   60,
+       60,  311,  310,   60,   60,   60,  697,  697,  308,   58,
+       58,   60,   60,   60,  697,  697,   59,   58,   58,   58,
+       58,   60,  697,  315,  313,  697,   59,   60,  316,  697,
+      317,   60,   60,   60,   60,   60,   60,  312,  697,  697,
+       60,   60,   60,   60,   60,   64,  697,   64,   60,  697,
+       60,   60,   60,  314,   60,   60,  697,  318,  697,   60,
+      697,  697,   60,   60,   60,   60,   60,   60,  319,  697,
+       60,  320,   60,   60,   60,   60,  697,   60,  321,  697,
+      322,   60,   60,   60,  323,   60,  697,   60,  697,   60,
+
+       60,  697,  325,  697,  697,   60,   60,   60,  324,  326,
+       60,  697,   60,  327,   60,   60,  697,   60,  697,  697,
+       60,   60,   60,   60,  697,   60,  697,  697,  126,  697,
+       60,   60,   60,   60,   60,  697,  330,  328,   60,  697,
+      697,   60,   60,  329,   60,  697,   60,  332,  697,  697,
+       60,   60,   60,  331,   60,   60,   60,  697,   60,  697,
+       60,   60,   60,   60,   60,  697,   60,   60,   60,  333,
+       60,   60,   60,   60,  697,   60,   60,  334,   60,   60,
+       60,  697,   60,   60,  335,   60,  336,  337,   60,  697,
+       60,   60,   60,   60,   60,   60,   60,   60,   60,   60,
+
+      697,   60,   60,  341,   60,   60,   60,   60,   60,   60,
+       60,   60,   60,   60,  697,  343,  340,  697,   60,  697,
+       60,   60,  697,   60,   60,  697,  342,  697,   60,  345,
+      344,   60,   60,  126,   60,  697,  697,  346,   60,  349,
+       60,   60,   60,   60,   60,   58,   58,   60,  697,   60,
+      697,  697,   59,  697,   60,  697,   60,   60,   60,   60,
+       60,  348,   60,   58,   58,  350,   60,  351,   60,  697,
+       59,   60,  353,   64,  697,   60,   60,  355,   60,   60,
+       60,  356,  697,   60,  697,   60,  358,   60,   60,  354,
+       60,  352,   60,   60,  697,  357,   60,   60,   60,   60,
+
+       60,   60,  697,  359,   60,  697,   60,  697,   60,   60,
+      697,   60,   60,  697,  360,   60,   60,   60,  697,   60,
+       60,  697,   60,  363,  697,   60,   60,  361,   60,   60,
+       60,  697,   60,  362,   60,   60,   60,  697,   60,   60,
+       60,  697,   60,   60,  697,  697,  364,  697,   60,  697,
+      697,  365,  697,   60,   60,  366,   60,   60,   60,  697,
+       60,   60,   60,  368,  697,   60,  697,  697,   60,  697,
+       60,  697,   60,   60,  367,   60,   60,  369,   60,   60,
+      370,  697,   60,  697,   60,  697,   60,  697,  371,   60,
+       60,  697,   60,   60,   58,   58,   58,   58,  383,   60,
+
+       60,  372,   60,   59,   58,   58,   58,   58,   60,   60,
+      697,   59,  697,   59,   58,   58,   58,   58,   60,   58,
+       58,   59,   64,   59,   64,  126,   59,  697,  697,  377,
+      697,  373,   64,   60,   64,  376,  697,  697,  697,   60,
+      697,  374,   64,  375,   64,   58,   58,   64,  697,   60,
+       58,   58,   59,  697,   60,  381,  384,   59,   60,  385,
+       60,   60,   60,   60,  697,   60,   60,  697,   60,   60,
+      502,  502,  697,   64,  379,   60,   60,  382,   64,   60,
+       60,  697,   60,   60,   60,  380,   60,  388,  697,  386,
+       60,  697,   60,   60,  540,   60,  697,  387,  122,   60,
+
+       60,  697,   60,   60,  389,   60,   60,  391,   60,   60,
+       60,  697,   60,   60,  697,   60,   60,  697,   60,   60,
+       60,  390,  393,  392,   60,  697,   60,   60,   60,   60,
+       60,   60,   60,  697,   60,  697,  395,   60,   60,  697,
+       60,  394,   60,  697,   60,  697,  697,   60,   58,   58,
+      697,  697,   60,  396,   60,  397,   60,   60,  697,  697,
+      398,   60,   60,  399,  697,   60,  697,   60,   60,  697,
+       60,   60,  697,   60,   60,   60,   64,   60,   60,   60,
+      697,   60,   60,  400,  697,   60,  404,   60,  401,   60,
+       60,   60,   60,  697,   60,  697,   60,   60,  697,   60,
+
+       60,   60,   60,  697,   60,   60,  406,   60,   60,  697,
+       60,   60,   60,   60,  405,   60,   60,  697,   60,   60,
+      697,   60,   60,  697,  407,  697,   60,   60,   60,   60,
+       60,   60,   60,   60,  408,  697,   60,   60,  410,  409,
+       60,   60,   60,   60,  697,  126,  697,  412,   60,  411,
+       60,   60,   60,   60,  697,   60,   60,  697,   60,   60,
+      697,   60,   60,  414,   60,  697,   60,  413,   60,   60,
+       60,   60,   60,   60,   60,   60,   60,   60,  697,   60,
+      697,  415,  697,   60,   60,   60,   60,  697,  416,  697,
+       60,   60,  697,   60,   60,   60,   60,   60,  697,  697,
+
+       60,  419,   60,   60,  417,   60,   60,   60,   60,  420,
+       60,   60,  697,   60,  418,   60,   60,   60,   60,  697,
+       60,   60,  422,   60,  423,   60,  697,  421,   60,  697,
+       60,   60,  425,   60,  697,   60,   60,  697,   60,   60,
+       60,   60,   60,   60,  697,  424,  524,  524,  697,   60,
+      697,   60,   60,   60,  426,  697,  697,   60,   60,   60,
+      429,  429,   60,   60,  697,   60,  427,  430,   60,  432,
+      555,  697,  433,   60,  122,   60,   60,   60,   60,   60,
+       60,   60,  697,   60,  431,   60,   60,   60,   64,   60,
+      697,   60,  697,  697,  434,   60,   60,   60,   60,   60,
+
+      435,   60,   60,   60,  443,  437,   60,   60,   60,   60,
+       60,   60,  697,  436,  697,   60,   60,   60,   60,   60,
+      697,  438,  697,  439,   60,   60,   60,   60,   60,   60,
+      697,   60,   60,  440,   60,  697,   60,   60,  697,   60,
+      441,   60,   60,  697,   60,   60,   60,   60,  697,   60,
+       60,   60,   60,   60,   60,   60,   60,  697,   60,   60,
+      697,   60,  697,  697,  442,  697,   60,  697,   60,   60,
+       60,   60,  697,  444,   60,   60,   60,   60,   60,   60,
+      697,   60,   60,   60,   60,  697,   60,  697,  446,   60,
+       60,   60,   60,  448,   60,  697,   60,   60,   60,  445,
+
+       60,  697,  451,   60,   58,   58,   60,  697,   60,  697,
+       60,  449,   60,   60,   58,   58,   60,  697,  697,  697,
+       60,   59,   60,  697,   60,   60,   60,  456,   60,   60,
+      697,  455,   64,  697,   60,   60,   60,   60,  697,  697,
+      457,   60,   64,  697,   60,   60,   60,   60,  450,  697,
+       60,   60,  458,  697,   60,   60,   60,   60,   60,  459,
+      697,   60,  697,  460,   60,   60,   60,  697,  697,   60,
+      697,   60,   60,   60,   60,   60,   60,   60,  461,  462,
+       60,  697,   60,   60,   60,   60,  697,   60,  697,  697,
+       60,  463,   60,   60,   60,   60,  697,   60,   60,   60,
+
+       60,  697,  466,  697,   60,   60,   60,   60,  697,   60,
+      465,  697,   60,   60,  464,   60,   60,   60,  697,   60,
+       60,   60,   60,  697,  467,  697,   60,   60,   60,   60,
+       60,  468,   60,  697,   60,  697,   60,   60,  469,   60,
+       60,  697,   60,   60,  697,  470,   60,   60,   60,   60,
+       60,   60,   60,  697,   60,  697,  471,  472,   60,   60,
+      697,   60,   60,  697,   60,   60,  697,   60,   58,   58,
+      473,   60,   60,   60,   60,   59,   60,   60,  697,  697,
+      478,   60,  477,   60,  479,   60,   60,  476,   60,  480,
+      697,  697,   60,   60,   60,  697,   64,   60,   60,   60,
+
+      697,   60,   60,   60,   60,  481,   60,  697,   60,   60,
+      697,   60,   60,  697,  697,   60,   60,  482,   60,   60,
+      483,  697,  484,   60,  697,   60,   60,   60,   60,  697,
+      486,   60,   60,   60,   60,   60,  697,   60,  697,   60,
+       60,  697,   60,  697,  697,   60,  697,  485,  487,   60,
+       60,  697,   60,  488,  697,   60,   60,   60,  697,   60,
+      490,   60,   60,  697,   60,  489,  697,   60,   60,   60,
+      491,  697,   60,  697,   60,   58,   58,   60,   58,   58,
+      494,  494,   59,  697,   60,   59,  697,  495,   58,   58,
+      697,  493,   60,   58,   58,   59,  499,   60,  697,  697,
+
+       59,   60,   60,   64,  697,   60,   64,   60,   64,   60,
+      496,  697,   60,  697,  497,  500,  498,   60,   60,  502,
+      502,   64,   60,   60,   60,   60,   59,  510,   60,  697,
+       60,   60,   60,  501,   60,   60,  505,   60,   60,  697,
+      504,   60,   60,  503,  506,   60,  697,   64,  697,   60,
+       60,   60,   60,  507,   60,   60,  697,   60,   60,  697,
+      697,  697,   60,   60,   60,   60,   60,  697,  697,  697,
+      697,  508,   60,   60,   60,   60,   60,   60,  697,   60,
+       60,   60,   60,  697,   60,   60,   60,   60,   60,  513,
+      509,  697,  697,   60,   60,   60,   60,   60,   60,   60,
+
+      697,   60,   60,  697,  512,   60,   60,  514,   60,   60,
+       60,   60,  697,   60,  697,  697,   60,  516,   60,  515,
+      697,   60,  697,   60,  517,   60,   60,  519,   60,   60,
+      518,   60,   60,   60,  697,   60,   60,   60,   60,  697,
+       60,  697,  697,   58,   58,   60,   60,   60,   60,  520,
+      521,   58,   58,  522,  697,   60,   60,   60,   59,   60,
+      524,  524,  697,   60,  697,  523,  697,   59,  697,   58,
+       58,   64,  697,   60,  697,   60,   59,  494,  494,   64,
+       58,   58,   58,   58,  525,   58,   58,   59,   64,   59,
+      697,  697,   59,  697,  697,   60,   60,   64,  697,   60,
+
+      697,  697,  697,  697,  526,  122,  697,  529,   64,  535,
+       64,  530,  528,   64,   60,  527,   60,  126,   60,   60,
+       60,   60,  697,   60,   60,   60,  537,  697,  697,   60,
+      697,   60,  538,   60,  536,  697,   60,   60,  697,   60,
+       60,   60,   60,   60,   60,  697,   60,  539,  697,  541,
+       60,  542,   60,   60,   60,   60,  544,   60,   60,   60,
+       60,   60,   60,  697,  543,   60,  697,   60,  697,   58,
+       58,   58,   58,  697,   60,   60,  545,   60,   59,  697,
+       60,   60,   60,  697,  547,   60,  697,  697,  697,  697,
+       60,  697,   60,   60,  697,  549,   60,   64,  697,   64,
+
+       60,   60,   60,  546,  550,   60,   60,   60,   60,  697,
+      697,   60,   60,   60,  697,   60,   60,  697,  551,   60,
+       60,   60,  697,   60,  552,  697,   60,   60,   60,  697,
+      697,   60,  697,   60,   60,   60,   60,   60,   60,  697,
+       60,   60,   58,   58,   58,   58,   58,   58,   60,   59,
+       60,   59,  697,   59,  697,   58,   58,   58,   58,   58,
+       58,  697,   59,  697,   59,  697,   59,  697,  697,  697,
+       64,  557,   64,  554,   64,  556,   60,  697,   60,  697,
+      561,  697,   60,   64,  697,   64,   60,   64,   60,  697,
+      558,  562,  697,   60,   60,  697,   60,   60,   60,   60,
+
+       60,  697,  565,   60,  697,   60,   60,  563,  697,   60,
+      697,  564,   60,   60,  566,   60,  697,   60,  697,   60,
+       60,   60,   60,   60,   60,   60,  567,   60,   60,   60,
+       60,   60,   60,  697,  697,   60,  697,   60,   60,   60,
+       60,   60,   60,   58,   58,  569,   60,  697,   60,   60,
+       59,   60,   60,   60,   58,   58,  570,  697,  571,   60,
+      575,   59,   60,  697,   60,  697,  697,  697,  697,   60,
+       60,   64,  587,   60,   60,   60,   60,   60,   60,   60,
+       60,  577,   64,  573,   60,   60,   60,   60,  578,  576,
+      697,  697,   60,  697,   60,   60,   60,   60,  697,   60,
+
+       60,   60,   60,   60,   60,   60,  697,  697,  697,   60,
+       60,   60,   60,  697,   60,  697,  697,  580,   60,   60,
+       60,   60,   60,   60,  581,  586,   60,   60,  697,   60,
+      697,  584,   60,   60,   60,   60,  585,   60,   60,  697,
+      697,   60,   60,   60,  697,   60,   60,   60,   58,   58,
+       60,   60,   60,  588,  697,  590,   60,   60,  697,   60,
+       60,   60,  592,   60,  589,  697,  697,   60,  697,   60,
+       60,   60,   60,  697,   60,  594,   64,   60,   60,   60,
+       60,   60,   60,   60,  697,  593,  697,  596,   60,  697,
+       60,   60,   60,   60,  697,   60,   60,  697,   60,   60,
+
+      697,  697,   60,   60,   60,   60,  697,  597,   60,   60,
+      598,  697,   60,   60,  600,   60,  604,   60,  697,   60,
+      697,   60,  601,  697,   60,  697,   60,   60,   60,   60,
+       60,  697,   60,   58,   58,   60,  605,   60,   60,  607,
+       59,  606,  697,  608,  697,   60,   60,   60,   60,  697,
+      609,   60,  697,  697,   60,   60,  697,   60,   60,  613,
+      697,   64,   58,   58,   60,   58,   58,   60,  697,   59,
+      697,  697,   59,  697,   60,   60,   60,  697,   60,  617,
+      697,  619,   60,  697,  697,   60,  697,  697,   60,   60,
+       64,   60,   60,   64,  697,  697,   60,  614,  618,   60,
+
+      615,   60,   60,   60,   60,  621,  697,   60,   60,   60,
+      697,   60,   60,  697,   60,  697,  697,   60,  625,   60,
+      624,   60,   60,  697,   60,   60,   60,   60,  697,   60,
+      626,   60,   60,   60,  697,  697,   60,  697,  697,   60,
+       60,   60,   60,   60,  627,  697,   60,   60,  630,   60,
+      632,  697,   60,  629,   60,  628,   60,  697,   60,  697,
+       60,   60,   60,   60,  697,   60,   60,  697,   60,   60,
+       60,   60,   60,  636,  633,  697,   60,  697,  697,   60,
+       60,   60,  634,   60,  639,  637,   60,   60,   60,   60,
+      697,   60,  697,   60,   60,   60,   60,  697,   60,  697,
+
+      697,   60,   60,   60,   60,  643,   60,  697,   60,  697,
+       60,   60,  697,  642,  697,   60,   60,  645,   60,  644,
+       60,   60,  697,  697,   60,   60,   60,   60,   60,  646,
+       60,  697,   60,  697,  697,   60,  697,   60,   60,   60,
+       60,  647,   60,   60,  697,  697,  650,   60,   60,   60,
+      652,   60,   60,  649,   60,  697,  697,   60,  697,   60,
+       60,   60,   60,  697,   60,   60,  697,   60,   60,   60,
+       60,  653,   60,  658,   60,  697,   60,  697,  655,   60,
+      697,   60,   60,   60,   60,  697,   60,   60,  697,   60,
+       60,   60,   60,  659,   60,   60,   60,  697,   60,  697,
+
+      660,   60,  697,   60,   60,  697,   60,  697,  662,  661,
+      697,   60,   60,  697,   60,  697,   60,  664,   60,   60,
+       60,   60,   60,   60,   60,   60,   60,  697,   60,  697,
+       60,   60,   60,   60,  697,  666,  671,  697,   60,   60,
+      667,   60,   60,   60,  697,   60,   60,   60,  672,   60,
+      673,   60,   60,  697,   60,   60,  674,   60,  697,   60,
+       60,   60,   60,  697,   60,   60,  697,   60,   60,   60,
+       60,   60,   60,   60,   60,  697,   60,  675,   60,   60,
+       60,   60,   60,   60,   60,  679,   60,   60,   60,  677,
+       60,  682,  680,   60,   60,  697,   60,  697,   60,  697,
+
+      697,  697,  681,   60,   60,   60,   60,   60,   60,   60,
+      697,   60,   60,   60,   60,   60,   60,  697,   60,   60,
+      697,   60,  697,  683,  697,  697,   60,  697,   60,   60,
+       60,  686,  687,   60,   60,   60,   60,  697,   60,   58,
+       58,   60,   60,   60,   60,  697,  688,  685,   58,   58,
+      697,   60,   60,  697,   60,   59,   58,   58,  691,   58,
+       58,  126,   60,   59,  697,  693,   59,   64,   60,   60,
+       60,  697,  697,  697,   60,   60,   64,  697,   60,  694,
+       60,  697,   60,  690,   64,   60,   60,  692,  697,   60,
+       60,   60,   60,   60,  697,   60,  697,  695,  697,   60,
+
+      697,   60,   60,  696,  697,  697,  697,  697,  697,   60,
+      697,   60,   47,   47,   47,   47,   48,   48,   48,   48,
+       50,   50,   50,   50,   54,  697,   54,  113,  113,  117,
+      117,  117,  117,   69,   69,  452,  452,  452,  452,    7,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697
+
+    } ;
+
+static yyconst short int yy_chk[3595] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    9,    9,   11,   18,   18,   18,
+       41,  590,   11,   11,   22,   22,   49,   49,   56,   56,
+       56,   22,   52,   22,   22,   22,   41,  590,   52,  688,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+
+       22,   22,   22,   22,   22,   22,  678,  669,   22,   22,
+       22,   22,   22,   22,   23,   23,  665,   23,  657,   24,
+      656,   23,   24,   24,   23,  654,   23,   23,   23,   24,
+       23,   23,   24,  651,   25,   53,   26,   23,   25,   24,
+       26,   53,   53,   27,   25,   26,   26,   27,   28,   26,
+      648,   27,   28,  117,   25,   26,   26,   27,   28,  117,
+       27,   29,   30,   58,   58,   29,   30,   27,   28,   29,
+       29,   29,   30,  641,   32,   31,   35,  640,   32,   31,
+       35,   29,   30,   31,   32,  638,   35,  119,  635,   31,
+       32,   58,  631,  119,   32,  623,   35,   33,   33,   31,
+
+       33,   33,  622,  620,   33,   34,  616,  612,   36,   34,
+       33,   33,   36,   34,  603,  602,   34,   37,   36,   34,
+       33,   37,   34,   36,   36,   37,   38,  599,   36,   34,
+       38,   37,  595,   39,   37,   38,   38,   39,   40,   55,
+      591,   37,   40,   39,  583,   55,   38,   60,   40,   59,
+       59,   60,  582,   39,  579,  574,   59,   60,   40,  568,
+       61,   62,   62,  560,   61,   62,  559,   60,   65,   59,
+       61,  555,   65,   59,   61,   62,  548,   59,   65,   59,
+       61,   63,   63,  545,  120,   63,   63,   55,   65,   59,
+      120,   64,   64,   64,  540,   63,   64,   66,   66,   67,
+
+       67,   66,  530,   67,   67,  529,   64,  521,   68,   68,
+      402,   66,   68,   67,   70,   70,  402,  511,   70,   70,
+       71,   71,   68,   72,   71,   73,   74,   72,   70,   73,
+       74,  120,   71,   72,   71,   73,   74,  474,   71,  449,
+       75,   75,  430,   72,   76,   73,   74,   75,   76,   77,
+       77,   79,   79,   77,   76,   79,   78,   78,   78,   77,
+       78,  429,  429,   77,   76,   79,   77,   79,   75,   75,
+       78,  397,   80,   80,  372,   78,   80,   81,   81,   82,
+       82,   81,  339,   82,   83,  429,   80,   81,   83,  429,
+       80,   81,  313,   82,   83,   82,   84,   84,   84,  280,
+
+      271,   84,  452,  197,   83,   85,   85,   85,  452,   85,
+      196,   84,   85,   86,   86,  130,  196,   86,   94,   85,
+       87,   87,   94,   85,   87,   86,  454,   86,   94,   88,
+       88,   94,  454,   88,   87,   89,   89,  122,   94,   89,
+      116,   88,   87,   88,  113,   89,   90,   90,  112,   89,
+       90,   91,   91,  196,   90,   91,  111,   92,   92,  110,
+       90,   92,   93,   95,   69,   91,   93,   95,   57,   91,
+       54,   92,   93,   95,   96,   51,   97,   93,   96,   95,
+       97,   50,   93,   95,   96,  270,   97,   96,   98,   98,
+       98,  270,   43,   98,   96,   19,   97,   99,   99,   15,
+
+       98,   99,   10,   98,  100,  100,   98,    7,  100,  100,
+      338,   99,   99,  102,  102,   99,  338,  102,  100,  101,
+      101,  101,    0,    0,  101,  103,  103,  102,  100,  103,
+      270,    0,    0,    0,  101,    0,  101,  103,    0,  103,
+      104,  104,  105,  105,  104,  104,  105,  106,  106,  106,
+        0,  105,  106,    0,  104,  338,  105,  107,  107,  108,
+      108,  107,  106,  108,  107,  109,  109,  106,  124,  109,
+      123,  107,  124,  108,  123,    0,  108,  125,  124,  109,
+      123,  125,    0,  109,    0,  123,    0,  125,  124,    0,
+      123,  126,  126,    0,    0,  126,    0,  125,  127,  127,
+
+      128,  128,  127,    0,  128,  126,    0,  129,  129,  131,
+      128,  129,  127,  131,  128,    0,    0,  132,  132,  131,
+      133,  129,  132,    0,  133,    0,  129,  134,  132,  131,
+      133,  134,  135,    0,  134,    0,  135,  134,  132,    0,
+      133,    0,  135,  136,  136,  136,  135,  134,  136,  137,
+      137,    0,  135,  137,    0,  138,  138,  139,  136,  138,
+      140,  139,    0,  137,  140,  139,  137,  144,  144,  138,
+      140,  139,    0,  138,  144,  141,  141,    0,  139,  141,
+      140,  139,  142,  142,    0,    0,  142,  143,  143,  141,
+      145,  143,    0,    0,  145,  144,  142,    0,  142,  146,
+
+      145,  143,    0,  146,  147,    0,  146,  148,  147,  146,
+      145,  148,  149,    0,  147,    0,  149,  148,    0,  146,
+        0,  148,  149,    0,  147,    0,  151,  148,  150,  150,
+      151,    0,  149,  151,  152,  150,  151,    0,  152,  153,
+        0,  152,    0,  153,  152,    0,  151,  154,  155,  153,
+        0,  154,  155,    0,  152,    0,  150,  154,  155,  153,
+      156,  157,  154,    0,  156,  157,  156,  154,  155,  158,
+      156,  157,  160,  158,  161,    0,  160,    0,  161,  158,
+      156,  157,  160,  159,  161,  158,    0,  159,    0,  158,
+      159,  162,  160,  159,  161,  162,  163,    0,  178,  178,
+
+      163,  162,  178,  159,  162,  164,  163,    0,    0,  164,
+      166,  162,  178,  165,  166,  164,  163,  165,  164,  167,
+      166,  165,  168,  167,  166,  164,  168,  165,    0,  167,
+      166,  169,  168,    0,  167,  169,  168,  165,    0,  167,
+      170,  169,  168,    0,  170,  183,  183,    0,  169,  171,
+      170,  169,  183,  171,  172,  170,  171,  173,  172,  171,
+      170,  173,  495,    0,  172,  495,    0,  173,  174,  171,
+      172,    0,  174,  183,  172,  495,  174,  173,    0,  175,
+      175,  495,  174,  175,    0,  176,  176,  177,  177,  176,
+        0,  177,  174,  175,    0,    0,  179,  179,  175,  176,
+
+      179,  177,    0,  180,  176,  181,  177,  180,  179,  181,
+      179,    0,  182,  180,    0,  181,  182,  184,  184,    0,
+      181,  184,  182,  180,    0,  181,  185,  185,    0,    0,
+      185,  184,  182,  186,  186,  187,    0,  186,    0,  187,
+      185,    0,  188,    0,  185,  187,  188,  186,    0,  189,
+      186,  188,  188,  189,  190,  187,  191,  192,  190,  189,
+      191,  192,  188,    0,  190,    0,  191,  192,  193,  189,
+        0,  193,  193,  191,  190,  198,  191,  192,  193,  198,
+        0,    0,    0,  199,  198,  198,    0,  199,  193,    0,
+      200,    0,    0,  199,  200,  198,  199,  203,  201,    0,
+
+      200,  203,  201,  199,  200,  204,  204,  203,  201,  202,
+      200,  201,  204,  202,  205,  205,  207,  203,  201,  202,
+      207,  205,  202,  206,  206,    0,  207,  208,  208,  202,
+      206,  208,    0,  204,  209,  210,  207,    0,  209,  210,
+        0,  208,  205,  205,  209,  210,  211,    0,  212,  213,
+      211,  206,  212,  213,  209,  210,  211,    0,  212,  213,
+        0,    0,  211,  214,    0,  213,  211,  214,  212,  213,
+      215,  216,  214,  214,  215,  216,  217,    0,  215,    0,
+      217,  216,    0,  214,  215,    0,  217,    0,  216,  217,
+        0,  216,    0,  218,  215,  220,  217,  218,  219,  220,
+
+      221,    0,  219,  218,  221,  220,  219,    0,  220,    0,
+      221,    0,  219,  218,  222,  220,    0,    0,  222,  223,
+      221,  224,  219,  223,  222,  224,    0,  222,  223,  223,
+        0,  224,  225,  226,  222,    0,  225,  226,  227,  223,
+      225,  224,  227,  226,    0,  228,  225,    0,  227,  228,
+      229,  227,    0,  226,  229,  228,  225,    0,  227,    0,
+      229,  228,  230,    0,  232,  228,  230,    0,  232,  229,
+      229,  231,  230,  231,  232,  231,  233,    0,    0,  234,
+      233,  231,  230,  234,  232,    0,  233,    0,    0,  234,
+      233,  231,    0,  235,  235,    0,  233,  235,    0,  234,
+
+      236,  236,  238,    0,  236,    0,  238,  235,  237,  237,
+      237,  239,  238,  237,  236,  239,    0,    0,  236,  240,
+      240,  239,  238,  237,    0,    0,  240,  241,  241,  242,
+      242,  239,    0,  243,  241,    0,  242,  243,  244,    0,
+      245,  246,  244,  243,  245,  246,  244,  240,    0,    0,
+      245,  246,  244,  243,  247,  241,    0,  242,  247,    0,
+      245,  246,  244,  242,  247,  248,    0,  247,    0,  248,
+        0,    0,  249,  250,  247,  248,  249,  250,  248,    0,
+      251,  249,  249,  250,  251,  248,    0,  252,  250,    0,
+      251,  252,  249,  250,  252,  253,    0,  252,    0,  253,
+
+      251,    0,  254,    0,    0,  253,  254,  252,  253,  255,
+      256,    0,  254,  255,  256,  253,    0,  255,    0,    0,
+      256,  257,  254,  255,    0,  257,    0,    0,  259,    0,
+      256,  257,  259,  255,  258,    0,  259,  257,  258,    0,
+        0,  257,  259,  258,  258,    0,  260,  261,    0,    0,
+      260,  261,  259,  260,  258,  261,  260,    0,  262,    0,
+      263,  261,  262,  264,  263,    0,  260,  264,  262,  263,
+      263,  261,  265,  264,    0,  266,  265,  264,  262,  266,
+      263,    0,  265,  264,  266,  266,  267,  268,  268,    0,
+      267,  268,  265,  269,  269,  266,  267,  269,  272,  272,
+
+        0,  268,  272,  273,  273,  273,  267,  269,  273,  274,
+      274,  275,  272,  274,    0,  275,  272,    0,  273,    0,
+      276,  275,    0,  274,  276,    0,  274,    0,  277,  277,
+      276,  275,  277,  278,  279,    0,    0,  278,  279,  282,
+      276,  278,  277,  282,  279,  281,  281,  278,    0,  282,
+        0,    0,  281,    0,  279,    0,  283,  278,  284,  282,
+      283,  281,  284,  285,  285,  283,  283,  284,  284,    0,
+      285,  286,  286,  281,    0,  286,  283,  288,  284,  287,
+      287,  288,    0,  287,    0,  286,  290,  288,  289,  287,
+      290,  285,  289,  287,    0,  289,  290,  288,  289,  291,
+
+      292,  292,    0,  291,  292,    0,  290,    0,  289,  291,
+        0,  293,  293,    0,  292,  293,  294,  294,    0,  291,
+      294,    0,  295,  295,    0,  293,  295,  293,  296,  296,
+      294,    0,  296,  294,  297,  297,  295,    0,  297,  298,
+      298,    0,  296,  298,    0,    0,  296,    0,  297,    0,
+        0,  297,    0,  298,  299,  299,  300,  300,  299,    0,
+      300,  301,  301,  301,    0,  301,    0,    0,  299,    0,
+      300,    0,  302,  302,  300,  301,  302,  303,  303,  303,
+      304,    0,  303,    0,  304,    0,  302,    0,  305,  305,
+      304,    0,  303,  305,  306,  306,  307,  307,  319,  305,
+
+      304,  306,  319,  307,  308,  308,  309,  309,  319,  305,
+        0,  308,    0,  309,  310,  310,  311,  311,  319,  314,
+      314,  310,  306,  311,  307,  312,  314,    0,    0,  312,
+        0,  307,  308,  312,  309,  311,    0,    0,    0,  312,
+        0,  309,  310,  310,  311,  315,  315,  314,    0,  312,
+      316,  316,  315,    0,  317,  317,  320,  316,  317,  321,
+      320,  318,  318,  321,    0,  318,  320,    0,  317,  321,
+      502,  502,    0,  315,  315,  318,  320,  318,  316,  321,
+      322,    0,  323,  324,  322,  316,  323,  324,    0,  322,
+      322,    0,  323,  324,  502,  325,    0,  323,  502,  325,
+
+      322,    0,  323,  324,  325,  325,  326,  327,  327,  328,
+      326,    0,  327,  328,    0,  325,  326,    0,  327,  328,
+      329,  326,  329,  328,  329,    0,  326,  330,  327,  328,
+      329,  330,  331,    0,  332,    0,  331,  330,  332,    0,
+      329,  330,  331,    0,  332,    0,    0,  330,  333,  333,
+        0,    0,  331,  332,  332,  333,  334,  334,    0,    0,
+      334,  335,  335,  335,    0,  335,    0,  336,  336,    0,
+      334,  336,    0,  340,  340,  335,  333,  340,  337,  337,
+        0,  336,  337,  336,    0,  341,  341,  340,  337,  341,
+      342,  342,  337,    0,  342,    0,  343,  343,    0,  341,
+
+      343,  344,  344,    0,  342,  344,  345,  345,  345,    0,
+      343,  345,  346,  346,  343,  344,  346,    0,  347,  347,
+        0,  345,  347,    0,  346,    0,  346,  348,  348,  349,
+      349,  348,  347,  349,  347,    0,  350,  350,  351,  348,
+      350,  348,  351,  349,    0,  352,    0,  353,  351,  352,
+      350,  353,  354,  352,    0,  353,  354,    0,  351,  352,
+        0,  353,  354,  355,  355,    0,  356,  354,  355,  352,
+      356,  353,  354,  357,  355,  358,  356,  357,    0,  358,
+        0,  356,    0,  357,  355,  358,  356,    0,  358,    0,
+      359,  359,    0,  357,  359,  358,  360,  360,    0,    0,
+
+      360,  361,  361,  361,  359,  363,  361,  362,  362,  363,
+      360,  362,    0,  364,  360,  363,  361,  364,  365,    0,
+      366,  362,  365,  364,  366,  363,    0,  364,  365,    0,
+      366,  367,  368,  364,    0,  367,  368,    0,  365,  369,
+      366,  367,  368,  369,    0,  367,  524,  524,    0,  369,
+        0,  367,  368,  370,  369,    0,    0,  370,  371,  369,
+      373,  373,  371,  370,    0,  374,  370,  373,  371,  374,
+      524,    0,  375,  370,  524,  374,  375,  376,  371,  377,
+      375,  376,    0,  377,  373,  374,  375,  376,  373,  377,
+        0,  378,    0,    0,  377,  378,  375,  376,  379,  377,
+
+      378,  378,  379,  389,  389,  380,  381,  389,  379,  380,
+      381,  378,    0,  379,    0,  380,  381,  389,  379,  382,
+        0,  381,    0,  382,  383,  380,  381,  384,  383,  382,
+        0,  384,  385,  383,  383,    0,  385,  384,    0,  382,
+      386,  386,  385,    0,  383,  386,  387,  384,    0,  388,
+      387,  386,  385,  388,  390,  390,  387,    0,  390,  388,
+        0,  386,    0,    0,  388,    0,  387,    0,  390,  388,
+      391,  391,    0,  390,  391,  392,  392,  393,  393,  392,
+        0,  393,  394,  394,  391,    0,  394,    0,  395,  392,
+      396,  393,  395,  398,  396,    0,  394,  398,  395,  394,
+
+      396,    0,  401,  398,  399,  399,  401,    0,  395,    0,
+      396,  399,  401,  398,  400,  400,  404,    0,    0,    0,
+      404,  400,  401,    0,  405,  406,  404,  405,  405,  406,
+        0,  404,  399,    0,  405,  406,  404,  407,    0,    0,
+      406,  407,  400,    0,  405,  406,  408,  407,  400,    0,
+      408,  409,  407,    0,  410,  409,  408,  407,  410,  408,
+        0,  409,    0,  410,  410,  411,  408,    0,    0,  411,
+        0,  409,  412,  413,  410,  411,  412,  413,  411,  412,
+      414,    0,  412,  413,  414,  411,    0,  415,    0,    0,
+      414,  415,  412,  413,  416,  417,    0,  415,  416,  417,
+
+      414,    0,  418,    0,  416,  417,  418,  415,    0,  419,
+      417,    0,  418,  419,  416,  417,  420,  421,    0,  419,
+      420,  421,  418,    0,  419,    0,  420,  421,  422,  419,
+      423,  420,  422,    0,  423,    0,  420,  421,  422,  424,
+      423,    0,  425,  424,    0,  423,  425,  426,  422,  424,
+      423,  426,  425,    0,  427,    0,  425,  426,  427,  424,
+        0,  428,  425,    0,  427,  428,    0,  426,  431,  431,
+      428,  428,  432,  433,  427,  431,  432,  433,    0,    0,
+      433,  428,  432,  433,  434,  435,  435,  431,  434,  435,
+        0,    0,  432,  433,  434,    0,  431,  436,  436,  435,
+
+        0,  436,  437,  437,  434,  438,  437,    0,  439,  438,
+        0,  436,  439,    0,    0,  438,  437,  439,  439,  440,
+      440,    0,  441,  440,    0,  438,  441,  442,  439,    0,
+      443,  442,  441,  440,  443,  444,    0,  442,    0,  444,
+      443,    0,  441,    0,    0,  444,    0,  442,  444,  445,
+      443,    0,  446,  445,    0,  444,  446,  448,    0,  445,
+      447,  448,  446,    0,  447,  446,    0,  448,  447,  445,
+      448,    0,  446,    0,  447,  450,  450,  448,  451,  451,
+      455,  455,  450,    0,  447,  451,    0,  455,  456,  456,
+        0,  450,  457,  462,  462,  456,  457,  458,    0,    0,
+
+      462,  458,  457,  450,    0,  459,  451,  458,  455,  459,
+      455,    0,  457,    0,  455,  459,  456,  458,  460,  461,
+      461,  462,  460,  473,  473,  459,  461,  473,  460,    0,
+      463,  464,  465,  460,  463,  464,  465,  473,  460,    0,
+      463,  464,  465,  461,  466,  466,    0,  461,    0,  466,
+      463,  464,  465,  467,  468,  466,    0,  467,  468,    0,
+        0,    0,  469,  467,  468,  466,  469,    0,    0,    0,
+        0,  469,  469,  467,  468,  470,  471,  472,    0,  470,
+      471,  472,  469,    0,  475,  470,  471,  472,  475,  476,
+      472,    0,    0,  476,  475,  470,  471,  472,  477,  476,
+
+        0,  478,  477,    0,  475,  478,  479,  477,  477,  476,
+      479,  478,    0,  480,    0,    0,  479,  480,  477,  479,
+        0,  478,    0,  480,  481,  481,  479,  483,  482,  481,
+      482,  483,  482,  480,    0,  481,  484,  483,  482,    0,
+      484,    0,    0,  485,  485,  481,  484,  483,  482,  484,
+      485,  486,  486,  487,    0,  488,  484,  487,  486,  488,
+      489,  489,    0,  487,    0,  488,    0,  489,    0,  490,
+      490,  485,    0,  487,    0,  488,  490,  494,  494,  486,
+      491,  491,  492,  492,  489,  493,  493,  491,  489,  492,
+        0,    0,  493,    0,    0,  496,  496,  490,    0,  496,
+
+        0,    0,    0,    0,  490,  494,    0,  494,  491,  496,
+      492,  494,  493,  493,  497,  492,  499,  498,  497,  500,
+      499,  498,    0,  500,  497,  498,  499,    0,    0,  500,
+        0,  498,  500,  501,  497,    0,  499,  501,    0,  500,
+      503,  498,  504,  501,  503,    0,  504,  501,    0,  503,
+      503,  504,  504,  501,  505,  506,  507,  507,  505,  506,
+      503,  507,  504,    0,  505,  506,    0,  507,    0,  508,
+      508,  509,  509,    0,  505,  506,  508,  507,  509,    0,
+      510,  512,  512,    0,  510,  512,    0,    0,    0,    0,
+      510,    0,  513,  513,    0,  512,  513,  508,    0,  509,
+
+      510,  514,  514,  508,  513,  514,  513,  515,  515,    0,
+        0,  515,  516,  516,    0,  514,  516,    0,  514,  517,
+      517,  515,    0,  517,  516,    0,  516,  518,  518,    0,
+        0,  518,    0,  517,  519,  519,  520,  520,  519,    0,
+      520,  518,  522,  522,  523,  523,  525,  525,  519,  522,
+      520,  523,    0,  525,    0,  526,  526,  527,  527,  528,
+      528,    0,  526,    0,  527,    0,  528,    0,    0,    0,
+      522,  526,  523,  523,  525,  525,  531,    0,  532,    0,
+      531,    0,  532,  526,    0,  527,  531,  528,  532,    0,
+      527,  532,    0,  533,  533,    0,  531,  533,  532,  534,
+
+      534,    0,  535,  534,    0,  536,  535,  533,    0,  536,
+        0,  534,  535,  534,  536,  536,    0,  537,    0,  538,
+      539,  537,  535,  538,  539,  536,  537,  537,  541,  538,
+      539,  544,  541,    0,    0,  544,    0,  537,  541,  538,
+      539,  544,  542,  546,  546,  541,  542,    0,  541,  543,
+      546,  544,  542,  543,  547,  547,  542,    0,  543,  543,
+      549,  547,  542,    0,  549,    0,    0,    0,    0,  543,
+      549,  546,  564,  564,  550,  551,  564,  552,  550,  551,
+      549,  552,  547,  547,  550,  551,  564,  552,  553,  550,
+        0,    0,  553,    0,  550,  551,  553,  552,    0,  554,
+
+      556,  557,  553,  554,  556,  557,    0,    0,    0,  554,
+      556,  557,  553,    0,  558,    0,    0,  556,  558,  554,
+      556,  557,  561,  562,  558,  563,  561,  562,    0,  563,
+        0,  561,  561,  562,  558,  563,  562,  565,  565,    0,
+        0,  565,  561,  562,    0,  563,  566,  566,  567,  567,
+      566,  565,  569,  565,    0,  567,  569,  570,    0,  571,
+      566,  570,  569,  571,  566,    0,    0,  570,    0,  571,
+      572,  573,  569,    0,  572,  573,  567,  570,  575,  571,
+      572,  573,  575,  576,    0,  572,    0,  576,  575,    0,
+      572,  573,  577,  576,    0,  578,  577,    0,  575,  578,
+
+        0,    0,  577,  576,  580,  578,    0,  577,  580,  581,
+      578,    0,  577,  581,  580,  578,  584,  584,    0,  581,
+        0,  584,  581,    0,  580,    0,  585,  584,  586,  581,
+      585,    0,  586,  592,  592,  587,  585,  584,  586,  587,
+      592,  586,    0,  588,    0,  587,  585,  588,  586,    0,
+      589,  588,    0,    0,  589,  587,    0,  588,  589,  592,
+        0,  592,  593,  593,  589,  594,  594,  588,    0,  593,
+        0,    0,  594,    0,  589,  596,  596,    0,  597,  596,
+        0,  598,  597,    0,    0,  598,    0,    0,  597,  596,
+      593,  598,  601,  594,    0,    0,  601,  593,  597,  600,
+
+      594,  598,  601,  600,  604,  600,    0,  605,  604,  600,
+        0,  605,  601,    0,  604,    0,    0,  605,  606,  600,
+      605,  607,  606,    0,  604,  607,  606,  605,    0,  608,
+      607,  607,  606,  608,    0,    0,  609,    0,    0,  608,
+      609,  607,  606,  610,  608,    0,  609,  610,  611,  608,
+      613,    0,  611,  610,  613,  609,  609,    0,  611,    0,
+      613,  614,  615,  610,    0,  614,  615,    0,  611,  617,
+      613,  614,  615,  617,  614,    0,  618,    0,    0,  617,
+      618,  614,  615,  619,  621,  619,  618,  619,  621,  617,
+        0,  624,    0,  619,  621,  624,  618,    0,  625,    0,
+
+        0,  624,  625,  619,  621,  626,  626,    0,  625,    0,
+      626,  624,    0,  625,    0,  627,  626,  628,  625,  627,
+      629,  628,    0,    0,  629,  627,  626,  628,  630,  629,
+      629,    0,  630,    0,    0,  627,    0,  628,  630,  632,
+      629,  630,  633,  632,    0,    0,  633,  634,  630,  632,
+      636,  634,  633,  632,  636,    0,    0,  634,    0,  632,
+      636,  637,  633,    0,  639,  637,    0,  634,  639,  642,
+      636,  637,  643,  642,  639,    0,  643,    0,  639,  642,
+        0,  637,  643,  644,  639,    0,  645,  644,    0,  642,
+      645,  647,  643,  644,  646,  647,  645,    0,  646,    0,
+
+      645,  647,    0,  644,  646,    0,  645,    0,  647,  646,
+        0,  647,  649,    0,  646,    0,  649,  650,  650,  652,
+      652,  650,  649,  652,  653,  653,  658,    0,  653,    0,
+      658,  650,  649,  652,    0,  652,  658,    0,  653,  659,
+      653,  655,  655,  659,    0,  655,  658,  660,  659,  659,
+      661,  660,  662,    0,  661,  655,  662,  660,    0,  659,
+      661,  664,  662,    0,  666,  664,    0,  660,  666,  667,
+      661,  664,  662,  667,  666,    0,  671,  664,  672,  667,
+      671,  664,  672,  673,  666,  671,  671,  673,  672,  667,
+      674,  674,  672,  673,  674,    0,  671,    0,  672,    0,
+
+        0,    0,  673,  673,  674,  675,  675,  677,  677,  675,
+        0,  677,  679,  679,  680,  680,  679,    0,  680,  675,
+        0,  677,    0,  675,    0,    0,  679,    0,  680,  681,
+      681,  682,  683,  681,  685,  682,  683,    0,  685,  686,
+      686,  682,  683,  681,  685,    0,  686,  681,  687,  687,
+        0,  682,  683,    0,  685,  687,  689,  689,  690,  691,
+      691,  692,  690,  689,    0,  692,  691,  686,  690,  692,
+      693,    0,    0,    0,  693,  692,  687,    0,  690,  693,
+      693,    0,  694,  689,  689,  692,  694,  691,    0,  695,
+      693,  696,  694,  695,    0,  696,    0,  694,    0,  695,
+
+        0,  696,  694,  695,    0,    0,    0,    0,    0,  695,
+        0,  696,  698,  698,  698,  698,  699,  699,  699,  699,
+      700,  700,  700,  700,  701,    0,  701,  702,  702,  703,
+      703,  703,  703,  704,  704,  705,  705,  705,  705,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697,  697,  697,  697,  697,  697,  697,
+      697,  697,  697,  697
+
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "core/lex-asn1.l"
+#define INITIAL 0
+#define MACRO_DEF 1
+#define BRACE_BAL 2
+
+/* compiler/core/lex-asn1.l */
+/* AUTHOR: Mike Sample */
+/* DATE:   91/92 */
+/* Copyright (C) 1991, 1992 Michael Sample */
+/*               and the University of British Columbia */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 2 of the License, or */
+/* (at your option) any later version. */
+/* these comments must only be a single line each - lex blows it otherwise */
+/* due to this claim, the rcs log is at the end of this file. */
+/* $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $ */
+/* This lex spec should compile under either lex or flex. */
+/* There are three modes to the lexical analyzer, INITIAL, MACRO_DEF, */
+/* and BRACE_BAL.  INITIAL is the normal mode. MACRO_DEF is used by   */
+/* a lexical tie-in from the yacc code to eat a MACRO DEFINTION as a  */
+/* single blk of text.  BRACE_BAL is used to by a lexical tie-in for  */
+/* eating values inside { }'s.  */
+/* if your ASN.1 source file has control characters that cause      */
+/* snacc to choke, use a program like 'tr' to condition them first. */
+#line 41 "core/lex-asn1.l"
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "exports.h"
+#include "parse-asn1.h"  /* defines the returned token values */
+#include "parser.h"
+#include "lex-stuff.h"
+#include "errno.h"
+
+unsigned long int myLineNoG = 0;
+
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+
+#line 55 "core/lex-asn1.l"
+
+
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yy_last_accepting_state = yy_current_state;
+				yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 698 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 3540 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yy_hold_char;
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 57 "core/lex-asn1.l"
+return BOXC_SYM;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 58 "core/lex-asn1.l"
+return BOXS_SYM;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 60 "core/lex-asn1.l"
+{ COUNT_NEWLINES (myLineNoG, yytext);}
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 61 "core/lex-asn1.l"
+return DOT_SYM;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 62 "core/lex-asn1.l"
+return COMMA_SYM;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 63 "core/lex-asn1.l"
+return LEFTBRACE_SYM;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 64 "core/lex-asn1.l"
+return RIGHTBRACE_SYM;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 65 "core/lex-asn1.l"
+return LEFTPAREN_SYM;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 66 "core/lex-asn1.l"
+return RIGHTPAREN_SYM;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 67 "core/lex-asn1.l"
+return LEFTBRACKET_SYM;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 68 "core/lex-asn1.l"
+return RIGHTBRACKET_SYM;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 69 "core/lex-asn1.l"
+return LESSTHAN_SYM;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 70 "core/lex-asn1.l"
+return MINUS_SYM;
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 71 "core/lex-asn1.l"
+return GETS_SYM;
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 72 "core/lex-asn1.l"
+return BAR_SYM;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 73 "core/lex-asn1.l"
+return SEMI_COLON_SYM;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 74 "core/lex-asn1.l"
+return TAGS_SYM;
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 75 "core/lex-asn1.l"
+return BOOLEAN_SYM;
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 76 "core/lex-asn1.l"
+return INTEGER_SYM;
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 77 "core/lex-asn1.l"
+return BIT_SYM;
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 78 "core/lex-asn1.l"
+return STRING_SYM;
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 79 "core/lex-asn1.l"
+return OCTET_SYM;
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 80 "core/lex-asn1.l"
+return NULL_SYM;
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 81 "core/lex-asn1.l"
+return SEQUENCE_SYM;
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 82 "core/lex-asn1.l"
+return OF_SYM;
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 83 "core/lex-asn1.l"
+return SET_SYM;
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 84 "core/lex-asn1.l"
+return IMPLICIT_SYM;
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 85 "core/lex-asn1.l"
+return CHOICE_SYM;
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 86 "core/lex-asn1.l"
+return ANY_SYM;
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 87 "core/lex-asn1.l"
+{
+      COUNT_NEWLINES (myLineNoG, yytext);
+      return OBJECT_IDENTIFIER_SYM;}
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 90 "core/lex-asn1.l"
+return OPTIONAL_SYM;
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 91 "core/lex-asn1.l"
+return DEFAULT_SYM;
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 92 "core/lex-asn1.l"
+return COMPONENTS_SYM;
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 93 "core/lex-asn1.l"
+return UNIVERSAL_SYM;
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 94 "core/lex-asn1.l"
+return APPLICATION_SYM;
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 95 "core/lex-asn1.l"
+return PRIVATE_SYM;
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 96 "core/lex-asn1.l"
+return TRUE_SYM;
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 97 "core/lex-asn1.l"
+return FALSE_SYM;
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 98 "core/lex-asn1.l"
+return BEGIN_SYM;
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 99 "core/lex-asn1.l"
+return END_SYM;
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 100 "core/lex-asn1.l"
+return DEFINITIONS_SYM;
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 101 "core/lex-asn1.l"
+return EXPLICIT_SYM;
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 102 "core/lex-asn1.l"
+return ENUMERATED_SYM;
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 103 "core/lex-asn1.l"
+return EXPORTS_SYM;
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 104 "core/lex-asn1.l"
+return IMPORTS_SYM;
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 105 "core/lex-asn1.l"
+return REAL_SYM;
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 106 "core/lex-asn1.l"
+return INCLUDES_SYM;
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 107 "core/lex-asn1.l"
+return MIN_SYM;
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 108 "core/lex-asn1.l"
+return MAX_SYM;
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 109 "core/lex-asn1.l"
+return SIZE_SYM;
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 110 "core/lex-asn1.l"
+return FROM_SYM;
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 111 "core/lex-asn1.l"
+return WITH_SYM;
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 112 "core/lex-asn1.l"
+return COMPONENT_SYM;
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 113 "core/lex-asn1.l"
+return PRESENT_SYM;
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 114 "core/lex-asn1.l"
+return ABSENT_SYM;
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 115 "core/lex-asn1.l"
+return DEFINED_SYM;
+	YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 116 "core/lex-asn1.l"
+return BY_SYM;
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 117 "core/lex-asn1.l"
+return PLUS_INFINITY_SYM;
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 118 "core/lex-asn1.l"
+return MINUS_INFINITY_SYM;
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 122 "core/lex-asn1.l"
+{
+    int i;
+    char *buf;
+    int bufSize;
+    int inComment;
+    int inStr;
+    unsigned int c, c1, c2;
+
+    /*
+     * matches any first char, then
+     * copies everything until an uncommented,
+     * unquoted END.  This Lex state is started
+     * from the yacc src (lexical tie in)
+     * from the MACRO_DEF production.
+     *
+     * if you don't like realloc and don't care about
+     * macro defs just have this return a constant string
+     * like "BEGIN <not parsed> END" after eating the definition
+     */
+
+    unput (yytext[0]);
+
+    bufSize = 1024;
+    buf = Malloc (1024);
+
+    i = 0;          /* put BEGIN str at beginning */
+    buf[i++] = 'B';
+    buf[i++] = 'E';
+    buf[i++] = 'G';
+    buf[i++] = 'I';
+    buf[i++] = 'N';
+    buf[i++] = '\n';
+
+    inStr = FALSE;
+    inComment = FALSE;
+    for ( ; ; i++)
+    {
+        c = input();
+
+        if (i >= (bufSize - 4))
+        {
+            bufSize += 512;
+            buf = (char*) Realloc (buf, bufSize);
+        }
+
+        buf[i] = c;
+
+        if ((inComment) && (c == '\n'))
+              inComment = FALSE;
+        else if (!(inStr) &&  (c == '-'))
+        {
+            c = input();
+            if (c  == '-')
+            {
+                buf[++i] = c;
+                inComment = !inComment;
+            }
+            else
+                unput (c);
+        }
+        else  if (inComment)
+            continue;
+        else if (c == '"')
+              inStr = !inStr;
+        else if (inStr)
+            continue;
+        else if (c == 'E')
+        {
+            c1 = input();
+            c2 = input();
+            if ((c1 == 'N') && (c2 == 'D'))
+            {
+                buf[++i] = 'N';
+                buf[++i] = 'D';
+                buf[++i] = '\0';
+                yylval.charPtr = buf;
+                COUNT_NEWLINES (myLineNoG, buf);
+                myLineNoG -=1; /* take off 1 added after "BEGIN" */
+                return MACRODEFBODY_SYM;
+            }
+            else
+            {
+                unput (c2);
+                unput (c1);
+            }
+        }
+    }
+   /* not reached */
+}
+	YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 214 "core/lex-asn1.l"
+{
+         int i;
+        /* copy and return the Macro's name only */
+        /* doesn't handle comments between macro name and MACRO sym */
+         for (i = 0; (yytext[i] != ' ') &&
+                     (yytext[i] != '\t') &&
+                     (yytext[i] != '\n') &&
+                     (yytext[i] != '\r'); i++);
+         yylval.charPtr = Malloc (i+1);
+         strncpy (yylval.charPtr, yytext, i);
+         yylval.charPtr[i] = '\0';
+         return NAMEDMACRO_SYM; }
+	YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 228 "core/lex-asn1.l"
+return OPERATION_SYM;
+	YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 229 "core/lex-asn1.l"
+return ARGUMENT_SYM;
+	YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 230 "core/lex-asn1.l"
+return RESULT_SYM;
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 231 "core/lex-asn1.l"
+return ERRORS_SYM;
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 232 "core/lex-asn1.l"
+return LINKED_SYM;
+	YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 234 "core/lex-asn1.l"
+return ERROR_SYM;
+	YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 235 "core/lex-asn1.l"
+return PARAMETER_SYM;
+	YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 237 "core/lex-asn1.l"
+return BIND_SYM;
+	YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 238 "core/lex-asn1.l"
+return BINDERROR_SYM;
+	YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 239 "core/lex-asn1.l"
+return UNBIND_SYM;
+	YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 240 "core/lex-asn1.l"
+return UNBINDERROR_SYM;
+	YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 242 "core/lex-asn1.l"
+return AC_SYM;
+	YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 243 "core/lex-asn1.l"
+return ASES_SYM;
+	YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 244 "core/lex-asn1.l"
+return REMOTE_SYM;
+	YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 245 "core/lex-asn1.l"
+return INITIATOR_SYM;
+	YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 246 "core/lex-asn1.l"
+return RESPONDER_SYM;
+	YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 247 "core/lex-asn1.l"
+{
+        COUNT_NEWLINES (myLineNoG, yytext);
+        return ABSTRACTSYNTAXES_SYM;}
+	YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 251 "core/lex-asn1.l"
+return ASE_SYM;
+	YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 252 "core/lex-asn1.l"
+return OPERATIONS_SYM;
+	YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 253 "core/lex-asn1.l"
+{
+        COUNT_NEWLINES (myLineNoG, yytext);
+        return CONSUMERINVOKES_SYM;}
+	YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 257 "core/lex-asn1.l"
+{
+        COUNT_NEWLINES (myLineNoG, yytext);
+        return SUPPLIERINVOKES_SYM;}
+	YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 261 "core/lex-asn1.l"
+return EXTENSIONATTRIBUTE_SYM;
+	YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 262 "core/lex-asn1.l"
+return EXTENSIONS_SYM;
+	YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 263 "core/lex-asn1.l"
+return CHOSEN_SYM;
+	YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 265 "core/lex-asn1.l"
+return EXTENSION_SYM;
+	YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 266 "core/lex-asn1.l"
+return CRITICAL_SYM;
+	YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 267 "core/lex-asn1.l"
+return FOR_SYM;
+	YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 268 "core/lex-asn1.l"
+return SUBMISSION_SYM;
+	YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 269 "core/lex-asn1.l"
+return DELIVERY_SYM;
+	YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 270 "core/lex-asn1.l"
+return TRANSFER_SYM;
+	YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 272 "core/lex-asn1.l"
+return OBJECT_SYM;
+	YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 273 "core/lex-asn1.l"
+return PORTS_SYM;
+	YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 275 "core/lex-asn1.l"
+return PORT_SYM;
+	YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 276 "core/lex-asn1.l"
+{
+       COUNT_NEWLINES (myLineNoG, yytext);
+       return ABSTRACTOPS_SYM;}
+	YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 281 "core/lex-asn1.l"
+return REFINE_SYM;
+	YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 282 "core/lex-asn1.l"
+return AS_SYM;
+	YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 283 "core/lex-asn1.l"
+return RECURRING_SYM;
+	YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 284 "core/lex-asn1.l"
+return VISIBLE_SYM;
+	YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 285 "core/lex-asn1.l"
+return PAIRED_SYM;
+	YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 287 "core/lex-asn1.l"
+return ABSTRACTBIND_SYM;
+	YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 288 "core/lex-asn1.l"
+return TO_SYM;
+	YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 290 "core/lex-asn1.l"
+return ABSTRACTUNBIND_SYM;
+	YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 292 "core/lex-asn1.l"
+return ABSTRACTERROR_SYM;
+	YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 294 "core/lex-asn1.l"
+return ABSTRACTOPERATION_SYM;
+	YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 296 "core/lex-asn1.l"
+return TOKEN_SYM;
+	YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 298 "core/lex-asn1.l"
+return TOKENDATA_SYM;
+	YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 300 "core/lex-asn1.l"
+return SECURITYCATEGORY_SYM;
+	YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 302 "core/lex-asn1.l"
+return ALGORITHM_SYM;
+	YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 303 "core/lex-asn1.l"
+return ENCRYPTED_SYM;
+	YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 304 "core/lex-asn1.l"
+return SIGNED_SYM;
+	YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 305 "core/lex-asn1.l"
+return SIGNATURE_SYM;
+	YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 306 "core/lex-asn1.l"
+return PROTECTED_SYM;
+	YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 308 "core/lex-asn1.l"
+return OBJECTTYPE_SYM;
+	YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 309 "core/lex-asn1.l"
+return SYNTAX_SYM;
+	YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 310 "core/lex-asn1.l"
+return ACCESS_SYM;
+	YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 311 "core/lex-asn1.l"
+return STATUS_SYM;
+	YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 312 "core/lex-asn1.l"
+return DESCRIPTION_SYM;
+	YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 313 "core/lex-asn1.l"
+return REFERENCE_SYM;
+	YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 314 "core/lex-asn1.l"
+return INDEX_SYM;
+	YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 315 "core/lex-asn1.l"
+return DEFVAL_SYM;
+	YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 319 "core/lex-asn1.l"
+{
+    int i;
+    char *buf;
+    int bufSize;
+    int inComment;
+    int inStr;
+    int braceDepth;
+    char c, c1, c2;
+
+    /*
+     * matches any first char, then
+     * copies everything until an ending "}"
+     * Assumes that initially parsed a "{"
+     * and puts one at beg. of returned string
+     */
+    unput (yytext[0]);
+
+    bufSize = 256;
+    buf = Malloc (256);
+
+    i = 0;          /* put openning brace at beginning */
+    buf[i++] = '{';
+    buf[i++] = ' ';
+
+    inStr = FALSE;
+    inComment = FALSE;
+    braceDepth = 1;
+    for ( ; ; i++)
+    {
+        c = input();
+
+        if (i >= (bufSize - 2))
+        {
+            bufSize += 256;
+            buf = (char*) Realloc (buf, bufSize);
+        }
+
+        buf[i] = c;
+
+        if ((inComment) && (c == '\n'))
+              inComment = FALSE;
+        else if (!(inStr) &&  (c == '-'))
+        {
+            c = input();
+            if (c  == '-')
+            {
+                buf[++i] = c;
+                inComment = !inComment;
+            }
+            else
+                unput (c);
+        }
+        else  if (inComment)
+            continue;
+        else if (c == '"')
+              inStr = !inStr;
+        else if (inStr)
+            continue;
+        else if (c == '{')
+            braceDepth++;
+        else if (c == '}')
+        {
+            braceDepth--;
+            if (braceDepth == 0)
+            {
+                buf[++i] = '\0';
+                yylval.charPtr = buf;
+                COUNT_NEWLINES (myLineNoG, buf);
+                return BRACEBAL_SYM;
+            }
+        }
+    }
+   /* not reached */
+}
+	YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 396 "core/lex-asn1.l"
+{
+          COUNT_NEWLINES (myLineNoG, yytext);
+          yylval.charPtr = (char*)Malloc (yyleng);
+          strncpy (yylval.charPtr, yytext+1, yyleng -1);  /* strip "'"s */
+          yylval.charPtr[yyleng-2] = '\0';
+          return BSTRING_SYM;}
+	YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 403 "core/lex-asn1.l"
+{
+          COUNT_NEWLINES (myLineNoG, yytext);
+          yylval.charPtr = (char*)Malloc (yyleng);
+          strncpy (yylval.charPtr, yytext+1, yyleng -1);   /* strip "'"s */
+          yylval.charPtr[yyleng-2] = '\0';
+          return HSTRING_SYM;}
+	YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 410 "core/lex-asn1.l"
+{
+          COUNT_NEWLINES (myLineNoG, yytext);
+          yylval.charPtr = (char*)Malloc (yyleng);
+          strncpy (yylval.charPtr, yytext+1, yyleng -1);       /* strip '"'s */
+          yylval.charPtr[yyleng-2] = '\0'; /* 2 quotes == quote in a quote */
+          return CSTRING_SYM;}
+	YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 417 "core/lex-asn1.l"
+{
+          yylval.charPtr = (char*)Malloc (yyleng+1);
+          strcpy (yylval.charPtr, yytext);
+          yylval.charPtr[yyleng] = '\0';
+          return UCASEFIRST_IDENT_SYM;}
+	YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 424 "core/lex-asn1.l"
+{
+          yylval.charPtr = (char*)Malloc (yyleng+1);
+          strcpy (yylval.charPtr, yytext);
+          yylval.charPtr[yyleng] = '\0';
+          return LCASEFIRST_IDENT_SYM;}
+	YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 430 "core/lex-asn1.l"
+{ /*first digit cannot be zero on multi-digit #'s*/
+	  errno = 0;
+	  {
+	      unsigned long ul = (unsigned long) strtol(yytext,NULL,10);
+	      if (!errno && ul>(unsigned long)0xFFFFFFFF) {
+		  errno = ERANGE;
+	      }
+	      if (!errno) {
+		  yylval.uintVal = (unsigned int) ul;
+		  return NUMBER_SYM;
+	      }
+	  }
+          yylval.charPtr = (char*)Malloc (yyleng+1);
+          strcpy (yylval.charPtr, yytext);
+          yylval.charPtr[yyleng] = '\0';
+          return NUMBER_ERANGE;}
+	YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 447 "core/lex-asn1.l"
+{  /*allow zero as first digit on single digit #'s*/
+          yylval.uintVal = 0;
+          return NUMBER_SYM;}
+	YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 452 "core/lex-asn1.l"
+{
+         /* this must be before the normal comment eater so that snacc attribs
+          * are not treated as normal comments
+          */
+        /* eat comments, update line no */
+        int len;
+        COUNT_NEWLINES (myLineNoG, yytext);
+        yylval.charPtr = (char*)Malloc (yyleng-4);
+        /* skip first "--snacc" in copy to ret val */
+        strcpy (yylval.charPtr, yytext + 7);
+        len = strlen (yylval.charPtr);
+        /* strip off newline or -- terminator for comment */
+        if (yylval.charPtr[len-1] == '\n')
+           yylval.charPtr[len-1] = '\0';
+        else
+           yylval.charPtr[len-2] = '\0';
+        return SNACC_ATTRIBUTES; }
+	YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 471 "core/lex-asn1.l"
+{
+        /* eat comments, update line no */
+        COUNT_NEWLINES (myLineNoG, yytext);}
+	YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 476 "core/lex-asn1.l"
+ECHO;
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(MACRO_DEF):
+case YY_STATE_EOF(BRACE_BAL):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yy_last_accepting_state = yy_current_state;
+			yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 698 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+	register char *yy_cp = yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yy_last_accepting_state = yy_current_state;
+		yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 698 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 697);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 476 "core/lex-asn1.l"
+
+
+
+/*
+ * these "LexBegin..." routines are used by yacc for (ack!)
+ * lexical tie ins
+ */
+
+int
+LexBeginMacroDefContext()
+{
+    BEGIN (MACRO_DEF);
+}
+
+int
+LexBeginBraceBalContext()
+{
+    BEGIN (BRACE_BAL);
+}
+
+int
+LexBeginInitialContext()
+{
+    BEGIN (INITIAL);
+}
+
+/*
+ * $Log: lex-asn1.c,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.3  2000/06/08 20:12:24  dmitch
+ * Mods for X port.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:49  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.5  1997/08/28 09:46:41  wan
+ * Reworked number range checking, only gives warning now.
+ *
+ * Revision 1.4  1997/06/19 09:17:17  wan
+ * Added isPdu flag to tables. Added value range checks during parsing.
+ *
+ * Revision 1.3  1995/07/25 19:41:30  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:37:12  rj
+ * snacc_config.h removed.
+ *
+ * for a list of changes relative to the 1.1 distribution, please refer to the ChangeLog.
+ */
diff --git a/SecuritySNACCRuntime/compiler/core/lex-asn1.l b/SecuritySNACCRuntime/compiler/core/lex-asn1.l
new file mode 100644
index 00000000..caa55f01
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/lex-asn1.l
@@ -0,0 +1,523 @@
+%START  MACRO_DEF BRACE_BAL
+%a 14000
+%p 12000
+%e 2000
+%n 1000
+%o 20000
+
+
+
+/* compiler/core/lex-asn1.l */
+/* AUTHOR: Mike Sample */
+/* DATE:   91/92 */
+
+/* Copyright (C) 1991, 1992 Michael Sample */
+/*               and the University of British Columbia */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 2 of the License, or */
+/* (at your option) any later version. */
+
+/* these comments must only be a single line each - lex blows it otherwise */
+/* due to this claim, the rcs log is at the end of this file. */
+/* $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lex-asn1.l,v 1.1 2001/06/20 21:27:57 dmitch Exp $ */
+
+/* This lex spec should compile under either lex or flex. */
+
+/* There are three modes to the lexical analyzer, INITIAL, MACRO_DEF, */
+/* and BRACE_BAL.  INITIAL is the normal mode. MACRO_DEF is used by   */
+/* a lexical tie-in from the yacc code to eat a MACRO DEFINTION as a  */
+/* single blk of text.  BRACE_BAL is used to by a lexical tie-in for  */
+/* eating values inside { }'s.  */
+
+/* if your ASN.1 source file has control characters that cause      */
+/* snacc to choke, use a program like 'tr' to condition them first. */
+
+
+WHITESPC  [ \t\n\r]
+
+
+%{
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "exports.h"
+#include "parse-asn1.h"  /* defines the returned token values */
+#include "parser.h"
+#include "lex-stuff.h"
+#include "errno.h"
+
+unsigned long int myLineNoG = 0;
+
+%}
+
+%%
+
+<INITIAL>"[C]"       return BOXC_SYM;
+<INITIAL>"[S]"       return BOXS_SYM;
+
+<INITIAL>{WHITESPC}+ { COUNT_NEWLINES (myLineNoG, yytext);}
+<INITIAL>"."      return DOT_SYM;
+<INITIAL>","      return COMMA_SYM;
+<INITIAL>"{"      return LEFTBRACE_SYM;
+<INITIAL>"}"      return RIGHTBRACE_SYM;
+<INITIAL>"("      return LEFTPAREN_SYM;
+<INITIAL>")"      return RIGHTPAREN_SYM;
+<INITIAL>"["      return LEFTBRACKET_SYM;
+<INITIAL>"]"      return RIGHTBRACKET_SYM;
+<INITIAL>"<"      return LESSTHAN_SYM;
+<INITIAL>"-"      return MINUS_SYM;
+<INITIAL>"::="    return GETS_SYM;
+<INITIAL>"|"      return BAR_SYM;
+<INITIAL>";"      return SEMI_COLON_SYM;
+<INITIAL>TAGS     return TAGS_SYM;
+<INITIAL>BOOLEAN  return BOOLEAN_SYM;
+<INITIAL>INTEGER  return INTEGER_SYM;
+<INITIAL>BIT      return BIT_SYM;
+<INITIAL>STRING   return STRING_SYM;
+<INITIAL>OCTET    return OCTET_SYM;
+<INITIAL>NULL     return NULL_SYM;
+<INITIAL>SEQUENCE return SEQUENCE_SYM;
+<INITIAL>OF       return OF_SYM;
+<INITIAL>SET      return SET_SYM;
+<INITIAL>IMPLICIT return IMPLICIT_SYM;
+<INITIAL>CHOICE   return CHOICE_SYM;
+<INITIAL>ANY      return ANY_SYM;
+<INITIAL>OBJECT{WHITESPC}*IDENTIFIER {
+      COUNT_NEWLINES (myLineNoG, yytext);
+      return OBJECT_IDENTIFIER_SYM;}
+<INITIAL>OPTIONAL return OPTIONAL_SYM;
+<INITIAL>DEFAULT  return DEFAULT_SYM;
+<INITIAL>COMPONENTS return COMPONENTS_SYM;
+<INITIAL>UNIVERSAL return UNIVERSAL_SYM;
+<INITIAL>APPLICATION return APPLICATION_SYM;
+<INITIAL>PRIVATE  return PRIVATE_SYM;
+<INITIAL>TRUE     return TRUE_SYM;
+<INITIAL>FALSE    return FALSE_SYM;
+<INITIAL>BEGIN    return BEGIN_SYM;
+<INITIAL>END      return END_SYM;
+<INITIAL>DEFINITIONS return DEFINITIONS_SYM;
+<INITIAL>EXPLICIT return EXPLICIT_SYM;
+<INITIAL>ENUMERATED return ENUMERATED_SYM;
+<INITIAL>EXPORTS  return EXPORTS_SYM;
+<INITIAL>IMPORTS  return IMPORTS_SYM;
+<INITIAL>REAL     return REAL_SYM;
+<INITIAL>INCLUDES return INCLUDES_SYM;
+<INITIAL>MIN      return MIN_SYM;
+<INITIAL>MAX      return MAX_SYM;
+<INITIAL>SIZE     return SIZE_SYM;
+<INITIAL>FROM     return FROM_SYM;
+<INITIAL>WITH     return WITH_SYM;
+<INITIAL>COMPONENT return COMPONENT_SYM;
+<INITIAL>PRESENT  return PRESENT_SYM;
+<INITIAL>ABSENT   return ABSENT_SYM;
+<INITIAL>DEFINED  return DEFINED_SYM;
+<INITIAL>BY       return BY_SYM;
+<INITIAL>PLUS-INFINITY return PLUS_INFINITY_SYM;
+<INITIAL>MINUS-INFINITY return MINUS_INFINITY_SYM;
+
+
+
+<MACRO_DEF>(.|\n) {
+    int i;
+    char *buf;
+    int bufSize;
+    int inComment;
+    int inStr;
+    unsigned int c, c1, c2;
+
+    /*
+     * matches any first char, then
+     * copies everything until an uncommented,
+     * unquoted END.  This Lex state is started
+     * from the yacc src (lexical tie in)
+     * from the MACRO_DEF production.
+     *
+     * if you don't like realloc and don't care about
+     * macro defs just have this return a constant string
+     * like "BEGIN <not parsed> END" after eating the definition
+     */
+
+    unput (yytext[0]);
+
+    bufSize = 1024;
+    buf = Malloc (1024);
+
+    i = 0;          /* put BEGIN str at beginning */
+    buf[i++] = 'B';
+    buf[i++] = 'E';
+    buf[i++] = 'G';
+    buf[i++] = 'I';
+    buf[i++] = 'N';
+    buf[i++] = '\n';
+
+    inStr = FALSE;
+    inComment = FALSE;
+    for ( ; ; i++)
+    {
+        c = input();
+
+        if (i >= (bufSize - 4))
+        {
+            bufSize += 512;
+            buf = (char*) Realloc (buf, bufSize);
+        }
+
+        buf[i] = c;
+
+        if ((inComment) && (c == '\n'))
+              inComment = FALSE;
+        else if (!(inStr) &&  (c == '-'))
+        {
+            c = input();
+            if (c  == '-')
+            {
+                buf[++i] = c;
+                inComment = !inComment;
+            }
+            else
+                unput (c);
+        }
+        else  if (inComment)
+            continue;
+        else if (c == '"')
+              inStr = !inStr;
+        else if (inStr)
+            continue;
+        else if (c == 'E')
+        {
+            c1 = input();
+            c2 = input();
+            if ((c1 == 'N') && (c2 == 'D'))
+            {
+                buf[++i] = 'N';
+                buf[++i] = 'D';
+                buf[++i] = '\0';
+                yylval.charPtr = buf;
+                COUNT_NEWLINES (myLineNoG, buf);
+                myLineNoG -=1; /* take off 1 added after "BEGIN" */
+                return MACRODEFBODY_SYM;
+            }
+            else
+            {
+                unput (c2);
+                unput (c1);
+            }
+        }
+    }
+   /* not reached */
+}
+
+
+
+<INITIAL>[A-Z](-[A-Z0-9]|[A-Z0-9])*{WHITESPC}*MACRO {
+         int i;
+        /* copy and return the Macro's name only */
+        /* doesn't handle comments between macro name and MACRO sym */
+         for (i = 0; (yytext[i] != ' ') &&
+                     (yytext[i] != '\t') &&
+                     (yytext[i] != '\n') &&
+                     (yytext[i] != '\r'); i++);
+         yylval.charPtr = Malloc (i+1);
+         strncpy (yylval.charPtr, yytext, i);
+         yylval.charPtr[i] = '\0';
+         return NAMEDMACRO_SYM; }
+
+
+<INITIAL>OPERATION        return OPERATION_SYM;
+<INITIAL>ARGUMENT         return ARGUMENT_SYM;
+<INITIAL>RESULT           return RESULT_SYM;
+<INITIAL>ERRORS           return ERRORS_SYM;
+<INITIAL>LINKED           return LINKED_SYM;
+
+<INITIAL>ERROR            return ERROR_SYM;
+<INITIAL>PARAMETER        return PARAMETER_SYM;
+
+<INITIAL>BIND             return BIND_SYM;
+<INITIAL>BIND-ERROR       return BINDERROR_SYM;
+<INITIAL>UNBIND           return UNBIND_SYM;
+<INITIAL>UNBIND-ERROR     return UNBINDERROR_SYM;
+
+<INITIAL>APPLICATION-CONTEXT          return AC_SYM;
+<INITIAL>APPLICATION-SERVICE-ELEMENTS return ASES_SYM;
+<INITIAL>REMOTE                       return REMOTE_SYM;
+<INITIAL>INITIATOR                    return INITIATOR_SYM;
+<INITIAL>RESPONDER                    return RESPONDER_SYM;
+<INITIAL>ABSTRACT{WHITESPC}*SYNTAXES {
+        COUNT_NEWLINES (myLineNoG, yytext);
+        return ABSTRACTSYNTAXES_SYM;}
+
+<INITIAL>APPLICATION-SERVICE-ELEMENT return ASE_SYM;
+<INITIAL>OPERATIONS                  return OPERATIONS_SYM;
+<INITIAL>CONSUMER{WHITESPC}*INVOKES {
+        COUNT_NEWLINES (myLineNoG, yytext);
+        return CONSUMERINVOKES_SYM;}
+
+<INITIAL>SUPPLIER{WHITESPC}*INVOKES  {
+        COUNT_NEWLINES (myLineNoG, yytext);
+        return SUPPLIERINVOKES_SYM;}
+
+<INITIAL>EXTENSION-ATTRIBUTE          return EXTENSIONATTRIBUTE_SYM;
+<INITIAL>EXTENSIONS                   return EXTENSIONS_SYM;
+<INITIAL>CHOSEN                       return CHOSEN_SYM;
+
+<INITIAL>EXTENSION                   return EXTENSION_SYM;
+<INITIAL>CRITICAL                    return CRITICAL_SYM;
+<INITIAL>FOR                         return FOR_SYM;
+<INITIAL>SUBMISSION                  return SUBMISSION_SYM;
+<INITIAL>DELIVERY                    return DELIVERY_SYM;
+<INITIAL>TRANSFER                    return TRANSFER_SYM;
+
+<INITIAL>OBJECT                  return OBJECT_SYM;
+<INITIAL>PORTS                   return PORTS_SYM;
+
+<INITIAL>PORT                      return PORT_SYM;
+<INITIAL>ABSTRACT{WHITESPC}*OPERATIONS  {
+       COUNT_NEWLINES (myLineNoG, yytext);
+       return ABSTRACTOPS_SYM;}
+
+
+<INITIAL>REFINE                    return REFINE_SYM;
+<INITIAL>AS                        return AS_SYM;
+<INITIAL>RECURRING                 return RECURRING_SYM;
+<INITIAL>VISIBLE                   return VISIBLE_SYM;
+<INITIAL>PAIRED                    return PAIRED_SYM;
+
+<INITIAL>ABSTRACT-BIND             return ABSTRACTBIND_SYM;
+<INITIAL>TO                        return TO_SYM;
+
+<INITIAL>ABSTRACT-UNBIND           return ABSTRACTUNBIND_SYM;
+
+<INITIAL>ABSTRACT-ERROR            return ABSTRACTERROR_SYM;
+
+<INITIAL>ABSTRACT-OPERATION        return ABSTRACTOPERATION_SYM;
+
+<INITIAL>TOKEN                     return TOKEN_SYM;
+
+<INITIAL>TOKEN-DATA                return TOKENDATA_SYM;
+
+<INITIAL>SECURITY-CATEGORY         return SECURITYCATEGORY_SYM;
+
+<INITIAL>ALGORITHM         return ALGORITHM_SYM;
+<INITIAL>ENCRYPTED         return ENCRYPTED_SYM;
+<INITIAL>SIGNED            return SIGNED_SYM;
+<INITIAL>SIGNATURE         return SIGNATURE_SYM;
+<INITIAL>PROTECTED         return PROTECTED_SYM;
+
+<INITIAL>OBJECT-TYPE       return OBJECTTYPE_SYM;
+<INITIAL>SYNTAX            return SYNTAX_SYM;
+<INITIAL>ACCESS            return ACCESS_SYM;
+<INITIAL>STATUS            return STATUS_SYM;
+<INITIAL>DESCRIPTION       return DESCRIPTION_SYM;
+<INITIAL>REFERENCE         return REFERENCE_SYM;
+<INITIAL>INDEX             return INDEX_SYM;
+<INITIAL>DEFVAL            return DEFVAL_SYM;
+
+
+
+<BRACE_BAL>(.|\n) {
+    int i;
+    char *buf;
+    int bufSize;
+    int inComment;
+    int inStr;
+    int braceDepth;
+    char c, c1, c2;
+
+    /*
+     * matches any first char, then
+     * copies everything until an ending "}"
+     * Assumes that initially parsed a "{"
+     * and puts one at beg. of returned string
+     */
+    unput (yytext[0]);
+
+    bufSize = 256;
+    buf = Malloc (256);
+
+    i = 0;          /* put openning brace at beginning */
+    buf[i++] = '{';
+    buf[i++] = ' ';
+
+    inStr = FALSE;
+    inComment = FALSE;
+    braceDepth = 1;
+    for ( ; ; i++)
+    {
+        c = input();
+
+        if (i >= (bufSize - 2))
+        {
+            bufSize += 256;
+            buf = (char*) Realloc (buf, bufSize);
+        }
+
+        buf[i] = c;
+
+        if ((inComment) && (c == '\n'))
+              inComment = FALSE;
+        else if (!(inStr) &&  (c == '-'))
+        {
+            c = input();
+            if (c  == '-')
+            {
+                buf[++i] = c;
+                inComment = !inComment;
+            }
+            else
+                unput (c);
+        }
+        else  if (inComment)
+            continue;
+        else if (c == '"')
+              inStr = !inStr;
+        else if (inStr)
+            continue;
+        else if (c == '{')
+            braceDepth++;
+        else if (c == '}')
+        {
+            braceDepth--;
+            if (braceDepth == 0)
+            {
+                buf[++i] = '\0';
+                yylval.charPtr = buf;
+                COUNT_NEWLINES (myLineNoG, buf);
+                return BRACEBAL_SYM;
+            }
+        }
+    }
+   /* not reached */
+}
+
+
+
+<INITIAL>\'[0-1]*\'B {
+          COUNT_NEWLINES (myLineNoG, yytext);
+          yylval.charPtr = (char*)Malloc (yyleng);
+          strncpy (yylval.charPtr, yytext+1, yyleng -1);  /* strip "'"s */
+          yylval.charPtr[yyleng-2] = '\0';
+          return BSTRING_SYM;}
+
+<INITIAL>\'[0-9A-Fa-f]*\'H {
+          COUNT_NEWLINES (myLineNoG, yytext);
+          yylval.charPtr = (char*)Malloc (yyleng);
+          strncpy (yylval.charPtr, yytext+1, yyleng -1);   /* strip "'"s */
+          yylval.charPtr[yyleng-2] = '\0';
+          return HSTRING_SYM;}
+
+<INITIAL>\"([^\"]|"\"\"")*\"  {
+          COUNT_NEWLINES (myLineNoG, yytext);
+          yylval.charPtr = (char*)Malloc (yyleng);
+          strncpy (yylval.charPtr, yytext+1, yyleng -1);       /* strip '"'s */
+          yylval.charPtr[yyleng-2] = '\0'; /* 2 quotes == quote in a quote */
+          return CSTRING_SYM;}
+
+<INITIAL>[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])* {
+          yylval.charPtr = (char*)Malloc (yyleng+1);
+          strcpy (yylval.charPtr, yytext);
+          yylval.charPtr[yyleng] = '\0';
+          return UCASEFIRST_IDENT_SYM;}
+
+
+<INITIAL>[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])* {
+          yylval.charPtr = (char*)Malloc (yyleng+1);
+          strcpy (yylval.charPtr, yytext);
+          yylval.charPtr[yyleng] = '\0';
+          return LCASEFIRST_IDENT_SYM;}
+
+<INITIAL>[1-9][0-9]* { /*first digit cannot be zero on multi-digit #'s*/
+	  errno = 0;
+	  {
+	      unsigned long ul = (unsigned long) strtol(yytext,NULL,10);
+	      if (!errno && ul>(unsigned long)0xFFFFFFFF) {
+		  errno = ERANGE;
+	      }
+	      if (!errno) {
+		  yylval.uintVal = (unsigned int) ul;
+		  return NUMBER_SYM;
+	      }
+	  }
+          yylval.charPtr = (char*)Malloc (yyleng+1);
+          strcpy (yylval.charPtr, yytext);
+          yylval.charPtr[yyleng] = '\0';
+          return NUMBER_ERANGE;}
+
+<INITIAL>0 {  /*allow zero as first digit on single digit #'s*/
+          yylval.uintVal = 0;
+          return NUMBER_SYM;}
+
+
+<INITIAL>"--snacc"(-[^-\n]|[^\-\n])*("--"|\n) {
+         /* this must be before the normal comment eater so that snacc attribs
+          * are not treated as normal comments
+          */
+        /* eat comments, update line no */
+        int len;
+        COUNT_NEWLINES (myLineNoG, yytext);
+        yylval.charPtr = (char*)Malloc (yyleng-4);
+        /* skip first "--snacc" in copy to ret val */
+        strcpy (yylval.charPtr, yytext + 7);
+        len = strlen (yylval.charPtr);
+        /* strip off newline or -- terminator for comment */
+        if (yylval.charPtr[len-1] == '\n')
+           yylval.charPtr[len-1] = '\0';
+        else
+           yylval.charPtr[len-2] = '\0';
+        return SNACC_ATTRIBUTES; }
+
+
+<INITIAL>"--"(-[^\-\n]|[^\-\n])*("--"|\n|"-\n") {
+        /* eat comments, update line no */
+        COUNT_NEWLINES (myLineNoG, yytext);}
+
+
+%%
+
+
+/*
+ * these "LexBegin..." routines are used by yacc for (ack!)
+ * lexical tie ins
+ */
+
+int
+LexBeginMacroDefContext()
+{
+    BEGIN (MACRO_DEF);
+}
+
+int
+LexBeginBraceBalContext()
+{
+    BEGIN (BRACE_BAL);
+}
+
+int
+LexBeginInitialContext()
+{
+    BEGIN (INITIAL);
+}
+
+/*
+ * $Log: lex-asn1.l,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:49  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.5  1997/08/28 09:46:41  wan
+ * Reworked number range checking, only gives warning now.
+ *
+ * Revision 1.4  1997/06/19 09:17:17  wan
+ * Added isPdu flag to tables. Added value range checks during parsing.
+ *
+ * Revision 1.3  1995/07/25 19:41:30  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:37:12  rj
+ * snacc_config.h removed.
+ *
+ * for a list of changes relative to the 1.1 distribution, please refer to the ChangeLog.
+ */
diff --git a/SecuritySNACCRuntime/compiler/core/lex-stuff.h b/SecuritySNACCRuntime/compiler/core/lex-stuff.h
new file mode 100644
index 00000000..3b68b773
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/lex-stuff.h
@@ -0,0 +1,56 @@
+/*
+ * compiler/core/lex_stuff.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lex-stuff.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: lex-stuff.h,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:49  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 19:41:31  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:48:45  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  01:16:07  rj
+ * decide upon type of yytext thru cxx macro provided by autoconf.
+ *
+ * Revision 1.1  1994/08/28  09:49:13  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+extern unsigned long myLineNoG;
+
+#ifdef YYTEXT_POINTER
+extern char	*yytext;
+#else
+extern char	yytext[];
+#endif
+
+extern FILE	*yyin;
+
+int LexBeginIntialContext();
+int LexBeginMacroDefContext();
+int LexBeginBraceBalContext();
+int LexBeginCommentContext();
+
+
+#define COUNT_NEWLINES( cumulativeTotal, nullTermStr)\
+{\
+     int cnlStrIndex;\
+     for (cnlStrIndex = 0; nullTermStr[cnlStrIndex] != '\0'; cnlStrIndex++)\
+        if (nullTermStr[cnlStrIndex] == '\n')\
+           cumulativeTotal++;\
+}
diff --git a/SecuritySNACCRuntime/compiler/core/lib-types.c b/SecuritySNACCRuntime/compiler/core/lib-types.c
new file mode 100644
index 00000000..5afaaae5
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/lib-types.c
@@ -0,0 +1,66 @@
+/*
+ * compiler/core/lib_types.c - tag form/code and any refs info
+ *
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lib-types.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: lib-types.c,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:49  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:33  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:37:51  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:14  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include "asn-incl.h"
+#include "asn1module.h"  /* for BASICTYPE_... choice ids */
+#include "lib-types.h"
+
+/*
+ * Warning: this table must be in order of ascending
+ * BASICTYPE ids such that
+ *    libTypesG[BASICTYPE_X].typeId == BASICTYPE_X
+ * is alwas true
+ */
+LibType libTypesG[ BASICTYPE_MACRODEF + 1] =
+{
+  { BASICTYPE_UNKNOWN,       NO_TAG_CODE,          NULL_FORM, NULL },
+  { BASICTYPE_BOOLEAN,       BOOLEAN_TAG_CODE,     PRIM,      NULL },
+  { BASICTYPE_INTEGER,       INTEGER_TAG_CODE,     PRIM,      NULL },
+  { BASICTYPE_BITSTRING,     BITSTRING_TAG_CODE,   ANY_FORM,  NULL },
+  { BASICTYPE_OCTETSTRING,   OCTETSTRING_TAG_CODE, ANY_FORM,  NULL },
+  { BASICTYPE_NULL,          NULLTYPE_TAG_CODE,    PRIM,      NULL },
+  { BASICTYPE_OID,           OID_TAG_CODE,         PRIM,      NULL },
+  { BASICTYPE_REAL,          REAL_TAG_CODE,        PRIM,      NULL },
+  { BASICTYPE_ENUMERATED,    ENUM_TAG_CODE,        PRIM,      NULL },
+  { BASICTYPE_SEQUENCE,      SEQ_TAG_CODE,         CONS,      NULL },
+  { BASICTYPE_SEQUENCEOF,    SEQ_TAG_CODE,         CONS,      NULL },
+  { BASICTYPE_SET,           SET_TAG_CODE,         CONS,      NULL },
+  { BASICTYPE_SETOF,         SET_TAG_CODE,         CONS,      NULL },
+  { BASICTYPE_CHOICE,        NO_TAG_CODE,          CONS,      NULL },
+  { BASICTYPE_SELECTION,     NO_TAG_CODE,          NULL_FORM, NULL },
+  { BASICTYPE_COMPONENTSOF,  NO_TAG_CODE,          CONS,      NULL },
+  { BASICTYPE_ANY,           NO_TAG_CODE,          CONS,      NULL },
+  { BASICTYPE_ANYDEFINEDBY,  NO_TAG_CODE,          CONS,      NULL },
+  { BASICTYPE_LOCALTYPEREF,  NO_TAG_CODE,          NULL_FORM, NULL },
+  { BASICTYPE_IMPORTTYPEREF, NO_TAG_CODE,          NULL_FORM, NULL },
+  { BASICTYPE_MACROTYPE,     NO_TAG_CODE,          NULL_FORM, NULL },
+  { BASICTYPE_MACRODEF,      NO_TAG_CODE,          NULL_FORM, NULL }
+};
diff --git a/SecuritySNACCRuntime/compiler/core/lib-types.h b/SecuritySNACCRuntime/compiler/core/lib-types.h
new file mode 100644
index 00000000..8c34333f
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/lib-types.h
@@ -0,0 +1,47 @@
+/*
+ * compiler/core/lib_types.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/lib-types.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: lib-types.h,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:49  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:34  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:46  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:15  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+typedef struct LibType
+{
+    enum BasicTypeChoiceId typeId;
+    BER_UNIV_CODE          univTagCode;
+    BER_FORM               tagForm;
+    AnyRefList            *anyRefs;  /* these may be filled in do_macros.c*/
+}  LibType;
+
+
+extern LibType libTypesG[];
+
+#define LIBTYPE_GET_UNIV_TAG_CODE( tId)		(libTypesG[tId].univTagCode)
+#define LIBTYPE_GET_TAG_FORM( tId)		(libTypesG[tId].tagForm)
+#define LIBTYPE_GET_ANY_REFS( tId)		(libTypesG[tId].anyRefs)
+#define LIBTYPE_GET_ANY_REFS_HNDL( tId)		(&libTypesG[tId].anyRefs)
+#define LIBTYPE_GET_ANY_REFS( tId)		(libTypesG[tId].anyRefs)
diff --git a/SecuritySNACCRuntime/compiler/core/link-types.c b/SecuritySNACCRuntime/compiler/core/link-types.c
new file mode 100644
index 00000000..a04e4bf1
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/link-types.c
@@ -0,0 +1,1273 @@
+/*
+ * compiler/core/link_types.c
+ *
+ *  Links type references. Also increments 'refCount' in a TypeDef
+ *
+ *  Does type checking when linking SELECTION and COMPONENTS OF types
+ *
+ * MS
+ * 91/09/04
+ * Completely Rewritten for new ModuleList data structure (ASN.1 based)
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/link-types.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: link-types.c,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:49  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:36  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:38:30  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:17  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "snacc-util.h"
+#include "link-types.h"
+
+extern Module *usefulTypeModG;
+
+/* non-exported prototypes */
+
+void TypeLinkImportLists PROTO ((ModuleList *m));
+
+void TypeLinkTypeDef PROTO ((ModuleList *m, Module *currMod, TypeDef *head));
+
+void TypeLinkElmtTypes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, NamedTypeList *e));
+
+void TypeLinkElmtType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, NamedType *n));
+
+void TypeLinkType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType));
+
+void TypeLinkBasicType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *type, BasicType *bt));
+
+void TypeLinkSubtypes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType, Subtype *s));
+
+void TypeLinkSubtypeValue PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType, SubtypeValue *s));
+
+void TypeLinkNamedElmts PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, ValueDefList *v));
+
+
+
+void TypeLinkValueDef PROTO ((ModuleList *m, Module *currMod, ValueDef *v));
+
+
+void TypeLinkValue PROTO ((ModuleList *m, Module *currMod, ValueDef *head, Type *valuesType, Value *v));
+
+void TypeLinkRosOperationMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosOperationMacroType *op));
+
+
+void TypeLinkRosErrorMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosErrorMacroType *err));
+
+
+void TypeLinkRosBindMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosBindMacroType *bind));
+
+
+void TypeLinkRosAseMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosAseMacroType *ase));
+
+void TypeLinkRosAcMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosAcMacroType *ac));
+
+void TypeLinkMtsasExtensionsMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionsMacroType *exts));
+
+void TypeLinkMtsasExtensionMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionMacroType *ext));
+
+void TypeLinkMtsasExtensionAttributeMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionAttributeMacroType *ext));
+
+void TypeLinkMtsasTokenMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasTokenMacroType *tok));
+
+void TypeLinkMtsasTokenDataMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasTokenDataMacroType *tok));
+
+void TypeLinkMtsasSecurityCategoryMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasSecurityCategoryMacroType *sec));
+
+void TypeLinkAsnObjectMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnObjectMacroType *obj));
+
+void TypeLinkAsnPortMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnPortMacroType *p));
+
+void TypeLinkAsnAbstractBindMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnAbstractBindMacroType *bind));
+
+void TypeLinkSnmpObjectTypeMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, SnmpObjectTypeMacroType *ot));
+
+
+/* end of prototypes */
+
+
+
+
+static char *asn1SrcFileNameG;
+
+/*
+ * returns 0 if no link error occured,
+ * otherwise returns a value < 0.
+ * Processing should not continue if an error is returned
+ */
+int
+LinkTypeRefs PARAMS ((m),
+    ModuleList *m)
+{
+    Module   *currMod;
+    TypeDef  *td;
+    ValueDef *vd;
+    int linkErr = 0;
+
+    /*
+     * link imported types/values to their definition if
+     * the defining module is in the modulelist
+     */
+    TypeLinkImportLists (m);
+
+
+    /* link useful types */
+    if (usefulTypeModG != NULL)
+    {
+        FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
+        {
+            TypeLinkTypeDef (m, usefulTypeModG, td);
+        }
+
+        FOR_EACH_LIST_ELMT (vd, usefulTypeModG->valueDefs)
+        {
+            TypeLinkValueDef (m, usefulTypeModG, vd);
+        }
+
+        if (usefulTypeModG->status != MOD_ERROR)
+            usefulTypeModG->status = MOD_OK;
+        else
+            linkErr = -1;
+    }
+
+    /*
+     * go through types, values & macros of  each module
+     */
+    FOR_EACH_LIST_ELMT (currMod, m)
+    {
+        asn1SrcFileNameG = currMod->asn1SrcFileName;
+
+        /*
+         * go through each type in typeList and link as nec
+         */
+        FOR_EACH_LIST_ELMT (td, currMod->typeDefs)
+        {
+            TypeLinkTypeDef (m, currMod, td);
+        }
+
+
+        /*
+         *  go through each value in valueList and link as nec
+         */
+        FOR_EACH_LIST_ELMT (vd, currMod->valueDefs)
+        {
+            TypeLinkValueDef (m, currMod, vd);
+        }
+
+        if (currMod->status != MOD_ERROR)
+            currMod->status = MOD_OK;
+        else
+            linkErr = -1;
+    }
+
+    return linkErr;
+
+} /* LinkRefs */
+
+
+/*
+ * goes through import lists of each module making sure each
+ * imported type is in the referenced module.  Will flag
+ * errors if the imported type cannot be found or is not
+ * exported by the referenced module.
+ */
+void
+TypeLinkImportLists PARAMS ((m),
+    ModuleList *m)
+{
+    Module *currMod;
+    TypeDef *t;
+    ValueDef *v;
+    ImportModule *currImpList;
+    ImportElmt *currImpElmt;
+    Module *impRefMod;
+
+
+    /* Link each modules imports */
+    FOR_EACH_LIST_ELMT (currMod, m)
+    {
+        /*
+         * Link each import list in the currMod.
+         * (there is an import list for every module
+         * imported from by this module
+         */
+        FOR_EACH_LIST_ELMT (currImpList, currMod->imports)
+        {
+            /* lookup ref'd module by it's name and oid (if any) */
+            impRefMod = LookupModule (m, currImpList->modId->name, currImpList->modId->oid);
+
+            if (impRefMod == NULL)
+            {
+                /*
+                 * The needed module is not available.
+                 * Let user know and set fatal error
+                 */
+                currMod->status = MOD_ERROR;
+                PrintErrLoc (currMod->asn1SrcFileName, currImpList->lineNo);
+                fprintf (stderr,"ERROR - cannot locate IMPORT module \"%s\", ", currImpList->modId->name);
+
+                fprintf (stderr,"so the following types/values are missing:\n");
+                FOR_EACH_LIST_ELMT (currImpElmt, currImpList->importElmts)
+                {
+                    fprintf (stderr,"        "); /* indent */
+                    if (currImpElmt->privateScope)
+                        fprintf (stderr,"%s.", currImpList->modId->name);
+                    fprintf (stderr,"%s\n", currImpElmt->name);
+                }
+                fprintf (stderr,"\n");
+                /*
+                 * go onto next import list in this module
+                 * to report more errors if any
+                 */
+                continue;
+            }
+
+            /*
+             * go through each import elements and look for the
+             * the referenced type in the ref'd module
+             */
+            FOR_EACH_LIST_ELMT (currImpElmt, currImpList->importElmts)
+            {
+                /*
+                 * only do types (types have uppercase first letter)
+                 */
+                if  (!isupper (currImpElmt->name[0]))
+                    continue;
+
+                /* look for the type in the ref'd module */
+                t = LookupType (impRefMod->typeDefs, currImpElmt->name);
+
+                if (t != NULL)
+                {
+                    if (!t->exported)
+                    {
+                        currMod->status = MOD_ERROR;
+                        PrintErrLoc (currMod->asn1SrcFileName, currImpElmt->lineNo);
+                        fprintf (stderr,"ERROR - \"%s\" module imports \"%s\", which is not exported from module \"%s\".\n", currMod->modId->name, currImpElmt->name, impRefMod->modId->name);
+                    }
+
+                    /* set as ref'd if imported by someone */
+                    t->importRefCount++;
+                    currImpElmt->resolvedRef =
+                        (ImportElmtChoice*)Malloc (sizeof (ImportElmtChoice));
+                    currImpElmt->resolvedRef->choiceId = IMPORTELMTCHOICE_TYPE;
+                    currImpElmt->resolvedRef->a.type = t;
+
+                }
+                else /* type not found in ref'd module */
+                {
+                    currMod->status = MOD_ERROR;
+                    PrintErrLoc (currMod->asn1SrcFileName, currImpElmt->lineNo);
+                    fprintf (stderr,"ERROR - \"%s\" is imported from module \"%s\" by module \"%s\", but is not defined in the referenced module\n", currImpElmt->name, impRefMod->modId->name, currMod->modId->name);
+                }
+
+            }
+        }
+    }
+} /* TypeLinkImportLists */
+
+
+/*
+ * given a type def, it goes through the entire typedef
+ * (aggregate parts if any) and links refs
+ */
+void
+TypeLinkTypeDef PARAMS ((m, currMod, head),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head)
+{
+    if (head == NULL)
+        return;
+
+    TypeLinkType (m, currMod, head, head->type);
+}  /* LinkTypeDef */
+
+
+/*
+ * given a type t, this routine goes through the components of
+ * the type and links any type references
+ */
+void
+TypeLinkType PARAMS ((m, currMod, head, t),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t)
+{
+    if (t == NULL)
+        return;
+
+    /* like main type information */
+    TypeLinkBasicType (m, currMod, head, t, t->basicType);
+
+    /* link any type references in the subtypes (if any)*/
+    TypeLinkSubtypes (m, currMod, head, t, t->subtypes);
+
+    /* like type refs in the default value (if any) */
+    if (t->defaultVal != NULL)
+        TypeLinkValue (m, currMod, NULL, t,  t->defaultVal->value);
+
+}  /* TypeLinkType */
+
+
+/*
+ * given a sequence of NamedTypes (components of a SET, SEQ or
+ * CHOICE etc), this links any type refs in each one.
+ */
+void
+TypeLinkElmtTypes PARAMS ((m, currMod, head, e),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    NamedTypeList *e)
+{
+    NamedType *n;
+    FOR_EACH_LIST_ELMT (n, e)
+    {
+        TypeLinkElmtType (m, currMod, head, n);
+    }
+}  /* TypeLinkElmtTypes */
+
+
+void
+TypeLinkElmtType PARAMS ((m, currMod, head, n),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    NamedType *n)
+{
+    if (n != NULL)
+        TypeLinkType (m, currMod, head, n->type);
+}
+
+/*
+ * given a BasicType, this links any type refs that are
+ * part of it.
+ */
+void
+TypeLinkBasicType PARAMS ((m, currMod, head, type, bt),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *type _AND_
+    BasicType *bt)
+{
+    TypeDef *tmpTypeDef;
+    TypeDefList *tmpTypeDefs;
+    Type *tmpType;
+    Module *tmpMod;
+    NamedType *tmpElmtType;
+    ImportElmt *impElmt;
+    ImportModule *impMod;
+    int implicitRef;
+
+    if (bt == NULL)
+        return;
+
+    switch (bt->choiceId)
+    {
+
+        case BASICTYPE_SEQUENCE:
+        case BASICTYPE_SET:
+        case BASICTYPE_CHOICE:
+            TypeLinkElmtTypes (m, currMod, head, bt->a.set);
+            break;
+
+        case BASICTYPE_SEQUENCEOF:
+        case BASICTYPE_SETOF:
+            TypeLinkType (m, currMod, head, bt->a.setOf);
+            break;
+
+        case BASICTYPE_SELECTION:
+            TypeLinkType (m, currMod, head, bt->a.selection->typeRef);
+
+            /*
+             * check that elmt type is CHOICE
+             * and set up link  (if resolved)
+             */
+            tmpType = bt->a.selection->typeRef;
+            if ((tmpType->basicType->choiceId == BASICTYPE_IMPORTTYPEREF) ||
+                (tmpType->basicType->choiceId == BASICTYPE_LOCALTYPEREF))
+            {
+                tmpTypeDef = tmpType->basicType->a.importTypeRef->link;
+                if (tmpTypeDef == NULL) /* unlinked import or local type */
+                {
+                    currMod->status = MOD_ERROR;
+                    return;
+                }
+            }
+            else
+            {
+                PrintErrLoc (currMod->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - selection type defines type instead of referencing CHOICE field.\n");
+                currMod->status = MOD_ERROR;
+                return;
+            }
+
+            /*
+             * selections types must reference choice types
+             */
+            tmpType = ParanoidGetType (tmpTypeDef->type);
+            if (tmpType->basicType->choiceId != BASICTYPE_CHOICE)
+            {
+                PrintErrLoc (currMod->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - SELECTION types must reference a CHOICE type\n");
+                currMod->status = MOD_ERROR;
+                return;
+            }
+
+            /*
+             * find field ref'd by selection
+             */
+            tmpElmtType = LookupFieldInType (tmpTypeDef->type, bt->a.selection->fieldName);
+            if (tmpElmtType == NULL)
+            {
+                PrintErrLoc (currMod->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - selection type's reference field name \"%s\" is not in CHOICE \"%s\".\n", bt->a.selection->fieldName, tmpTypeDef->definedName);
+                currMod->status = MOD_ERROR;
+                return;
+            }
+
+            bt->a.selection->link = tmpElmtType;
+            break;
+
+
+        case BASICTYPE_COMPONENTSOF:
+            TypeLinkType (m, currMod, head, bt->a.componentsOf);
+            /* error checks done in normalize.c */
+            break;
+
+
+        case BASICTYPE_ANYDEFINEDBY:
+            /*
+             *  set the link to the defining field if not already linked
+             */
+            if (bt->a.anyDefinedBy->link == NULL)
+            {
+                /*
+                 * get set or seq that holds this any def'd by
+                 */
+                tmpType = GetParent (head->type, type);
+
+                if (tmpType == NULL)
+                {
+                    PrintErrLoc (currMod->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr," ERROR - could not find parent type for linking ANY DEFINED BY\n");
+                }
+
+                /*
+                 * find "defining" field
+                 */
+                tmpElmtType = LookupFieldInType (tmpType, bt->a.anyDefinedBy->fieldName);
+
+                if (tmpElmtType == NULL)
+                {
+                    currMod->status = MOD_ERROR;
+                    PrintErrLoc (currMod->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr," ERROR - could not find identifier field \"%s\" in type \"%s\" for linking ANY DEFINED BY\n", bt->a.anyDefinedBy->fieldName, head->definedName);
+                }
+
+                bt->a.anyDefinedBy->link = tmpElmtType;
+            }
+            break;
+
+
+        case BASICTYPE_LOCALTYPEREF:
+            /*
+             * Remember: the parser sets any typeref it encounters
+             * to LOCALTYPE_REF, so some Localtyperefs may be import
+             * type refs.
+             */
+            /*
+             * First, look in this module's type defs and create a
+             * resolvedLocalTypeRef if it's there.
+             */
+            if ((tmpTypeDef = LookupType (currMod->typeDefs, bt->a.localTypeRef->typeName)) != NULL)
+            {
+                /*
+                 * locally defined type
+                 */
+                tmpTypeDef->localRefCount++;
+
+                bt->a.localTypeRef->link = tmpTypeDef;
+                bt->a.localTypeRef->module = currMod;
+                break; /* finished here */
+            }
+            else /* not locally defined type */
+                bt->choiceId = BASICTYPE_IMPORTTYPEREF;
+               /*  !!!!!! fall through !!!!!!!! */
+
+        case BASICTYPE_IMPORTTYPEREF:
+
+            /* This handles "modname.type" type refs. */
+            if (bt->a.importTypeRef->moduleName != NULL)
+            {
+                /*
+                 * Lookup the import list maintained in this module
+                 * from the named module.  (the parser generates
+                 * an import list from Foo module for "Foo.Bar" style
+                 * import refs)
+                 */
+                impMod = LookupImportModule (currMod, bt->a.importTypeRef->moduleName);
+
+                if (impMod == NULL) /* whoa, compiler error */
+                {
+                    currMod->status = MOD_ERROR;
+                    fprintf (stderr,"Compiler Error: \"%s.%s\" typeref - no import list defined from module \"%s\"\n", bt->a.importTypeRef->moduleName, bt->a.importTypeRef->typeName, bt->a.importTypeRef->moduleName);
+
+                    return;
+                }
+                impElmt = LookupImportElmtInImportElmtList (impMod->importElmts, bt->a.importTypeRef->typeName);
+
+                if (impElmt == NULL) /* whoa, compiler error again */
+                {
+                    currMod->status = MOD_ERROR;
+                    fprintf (stderr,"Compiler Error: \"%s.%s\" typeref - no import element defined for type \"%s\"\n", bt->a.importTypeRef->moduleName, bt->a.importTypeRef->typeName, bt->a.importTypeRef->typeName);
+
+                    return;
+                }
+                /*
+                 * should already be resolved unless could not find
+                 * the import for some reason
+                 */
+                if (impElmt->resolvedRef != NULL)
+                {
+                   if (impElmt->resolvedRef->choiceId != IMPORTELMTCHOICE_TYPE)
+                        fprintf (stderr,"Linker Warning: import TYPE ref \"%s\" resolves with an imported VALUE\n", impElmt->name);
+
+                   bt->a.importTypeRef->link = impElmt->resolvedRef->a.type;
+                   bt->a.importTypeRef->link->importRefCount++;
+                   bt->a.importTypeRef->module = impMod->moduleRef;
+                }
+                else
+                {
+                    /* print loc of refs to unresolved imports */
+                    PrintErrLoc (currMod->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"reference to unresolved imported type \"%s\"\n", impElmt->name);
+                }
+
+            }
+            else    /* not a "modname.type" type ref */
+            {
+                impElmt = LookupImportElmtInModule (currMod, bt->a.importTypeRef->typeName, &impMod);
+
+                /*
+                 * privateScope one's should only resolve with one's
+                 * non-null module names (see last if) (mod.type form)
+                 */
+                if ((impElmt != NULL) && (!impElmt->privateScope))
+                {
+                    /*
+                     * should already be resolved unless could not find
+                     * the import for some reason
+                     */
+                    if (impElmt->resolvedRef != NULL)
+                    {
+                        if (impElmt->resolvedRef->choiceId != IMPORTELMTCHOICE_TYPE)
+                            fprintf (stderr,"Linker Warning: import TYPE ref \"%s\" resolves with an imported VALUE\n", impElmt->name);
+
+                        bt->a.importTypeRef->link = impElmt->resolvedRef->a.type;
+                        bt->a.importTypeRef->link->importRefCount++;
+                        bt->a.importTypeRef->module = impMod->moduleRef;
+                    }
+                    else
+                    {
+                        /* print loc of refs to unresolved imports */
+                        PrintErrLoc (currMod->asn1SrcFileName, type->lineNo);
+                        fprintf (stderr,"reference to unresolved imported type \"%s\"\n", impElmt->name);
+                    }
+                }
+                /*
+                 * Since not locally defined or imported,
+                 * look in useful types module (if any).
+                 * Useful type references are treated as imported
+                 * type references (from the useful types module)
+                 */
+                else if ((usefulTypeModG != NULL) && (tmpTypeDef = LookupType (usefulTypeModG->typeDefs, bt->a.localTypeRef->typeName)) != NULL)
+                {
+                    bt->a.importTypeRef->link = tmpTypeDef;
+                    bt->a.importTypeRef->module = usefulTypeModG;
+                }
+                else  /* impElmt == NULL */
+                {
+                    /*
+                     *  Type not defined locally, imported or
+                     *  in useful types module.
+                     */
+                    currMod->status = MOD_ERROR;
+                    PrintErrLoc (currMod->asn1SrcFileName, type->lineNo);
+                    fprintf (stderr,"ERROR - type \"%s\" is referenced but not defined or imported.\n", bt->a.importTypeRef->typeName);
+                }
+            }
+            break;
+
+
+        /*
+         * these types may optionally have named elmts
+         */
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_BITSTRING:
+        case BASICTYPE_ENUMERATED:
+            TypeLinkNamedElmts (m, currMod, head, type, bt->a.integer);
+            break;
+
+
+        /*
+         * these types have no extra info and cause no linking action
+         */
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_BOOLEAN:
+        case BASICTYPE_OCTETSTRING:
+        case BASICTYPE_NULL:
+        case BASICTYPE_OID:
+        case BASICTYPE_REAL:
+        case BASICTYPE_ANY:
+        case BASICTYPE_MACRODEF:
+            break;
+
+        case BASICTYPE_MACROTYPE:
+            switch (bt->a.macroType->choiceId)
+            {
+                case MACROTYPE_ROSOPERATION:
+                case MACROTYPE_ASNABSTRACTOPERATION:
+                    TypeLinkRosOperationMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosOperation);
+                    break;
+
+                case MACROTYPE_ROSERROR:
+                case MACROTYPE_ASNABSTRACTERROR:
+                    TypeLinkRosErrorMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosError);
+                    break;
+
+                case MACROTYPE_ROSBIND:
+                case MACROTYPE_ROSUNBIND:
+                    TypeLinkRosBindMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosBind);
+                    break;
+
+                case MACROTYPE_ROSASE:
+                    TypeLinkRosAseMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosAse);
+                    break;
+
+                case MACROTYPE_MTSASEXTENSIONS:
+                    TypeLinkMtsasExtensionsMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtensions);
+                    break;
+
+                case MACROTYPE_MTSASEXTENSION:
+                    TypeLinkMtsasExtensionMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtension);
+                    break;
+
+                case MACROTYPE_MTSASEXTENSIONATTRIBUTE:
+                    TypeLinkMtsasExtensionAttributeMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtensionAttribute);
+                    break;
+
+                case MACROTYPE_MTSASTOKEN:
+                    TypeLinkMtsasTokenMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasToken);
+                    break;
+
+                case MACROTYPE_MTSASTOKENDATA:
+                    TypeLinkMtsasTokenDataMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasTokenData);
+                    break;
+
+                case MACROTYPE_MTSASSECURITYCATEGORY:
+                    TypeLinkMtsasSecurityCategoryMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasSecurityCategory);
+                    break;
+
+                case MACROTYPE_ASNOBJECT:
+                    TypeLinkAsnObjectMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnObject);
+                    break;
+
+                case MACROTYPE_ASNPORT:
+                    TypeLinkAsnPortMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnPort);
+                    break;
+
+                case MACROTYPE_ASNABSTRACTBIND:
+                case MACROTYPE_ASNABSTRACTUNBIND:
+                    TypeLinkAsnAbstractBindMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnAbstractBind);
+                    break;
+
+                case MACROTYPE_AFALGORITHM:
+                case MACROTYPE_AFENCRYPTED:
+                case MACROTYPE_AFPROTECTED:
+                case MACROTYPE_AFSIGNATURE:
+                case MACROTYPE_AFSIGNED:
+                    TypeLinkType (m, currMod, head, bt->a.macroType->a.afAlgorithm);
+                    break;
+
+                case MACROTYPE_SNMPOBJECTTYPE:
+                    TypeLinkSnmpObjectTypeMacroType (m, currMod, head, type, bt, bt->a.macroType->a.snmpObjectType);
+                    break;
+
+                default:
+                    fprintf (stderr, "TypeLinkBasicType: ERROR - unknown macro type id!\n");
+            }
+            break;
+
+        default:
+            fprintf (stderr, "TypeLinkBasicType: ERROR - unknown basic type id!\n");
+    }
+
+}  /* LinkBasicType */
+
+
+
+
+/*
+ * resolve any type/value refs in the subtypes (if any)
+ */
+void
+TypeLinkSubtypes PARAMS ((m, currMod, head, currType, s),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *currType _AND_
+    Subtype *s)
+{
+    Subtype *sElmt;
+
+    if (s == NULL)
+        return;
+
+    switch (s->choiceId)
+    {
+        case SUBTYPE_SINGLE:
+            TypeLinkSubtypeValue (m, currMod, head, currType, s->a.single);
+        break;
+
+        case SUBTYPE_AND:
+        case SUBTYPE_OR:
+        case SUBTYPE_NOT:
+            FOR_EACH_LIST_ELMT (sElmt, s->a.and)
+            {
+                TypeLinkSubtypes (m, currMod, head, currType, sElmt);
+            }
+        break;
+
+        default:
+            fprintf (stderr, "TypeLinkSubtypes: ERROR - unknown Subtype id\n");
+        break;
+    }
+}  /* TypeLinkSubtypes */
+
+
+
+
+/*
+ * link any type referenced in the value parts of subtypes
+ */
+void
+TypeLinkSubtypeValue PARAMS ((m, currMod, head, currType, s),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *currType _AND_
+    SubtypeValue *s)
+{
+    Constraint *constraint;
+
+    if (s == NULL)
+        return;
+
+    switch (s->choiceId)
+    {
+        case SUBTYPEVALUE_SINGLEVALUE:
+            TypeLinkValue (m, currMod, NULL, currType, s->a.singleValue);
+            break;
+
+        case SUBTYPEVALUE_CONTAINED:
+            TypeLinkType (m, currMod, head, s->a.contained);
+            break;
+
+        case SUBTYPEVALUE_VALUERANGE:
+            TypeLinkValue (m, currMod, NULL, currType, s->a.valueRange->lowerEndValue);
+            TypeLinkValue (m, currMod, NULL, currType, s->a.valueRange->upperEndValue);
+            break;
+
+        case SUBTYPEVALUE_PERMITTEDALPHABET:
+            TypeLinkSubtypes (m, currMod, head, currType, s->a.permittedAlphabet);
+           break;
+
+        case SUBTYPEVALUE_SIZECONSTRAINT:
+            TypeLinkSubtypes (m, currMod, head, currType, s->a.sizeConstraint);
+            break;
+
+        case SUBTYPEVALUE_INNERSUBTYPE:
+            FOR_EACH_LIST_ELMT (constraint, s->a.innerSubtype->constraints)
+            {
+                TypeLinkSubtypes (m, currMod, head, currType, constraint->valueConstraints);
+            }
+            break;
+
+        default:
+            fprintf (stderr,"TypeLinkSubtype: ERROR - unknown subtype choiceId\n");
+    }
+
+} /* TypeLinkSubtype */
+
+
+
+/*
+ * go through named elements of INTEGER/ENUMERATED/BOOLEAN
+ * and link any type refs in the values
+ */
+void
+TypeLinkNamedElmts PARAMS ((m, currMod, head, t, v),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    ValueDefList *v)
+{
+    ValueDef *vd;
+    FOR_EACH_LIST_ELMT (vd, v)
+    {
+        TypeLinkValue (m, currMod, vd, vd->value->type, vd->value);
+    }
+
+}  /* TypeLinkNamedElmts */
+
+
+
+/*
+ * only use this for 'real' value defs
+ * ie those in the value def list - not ones for namedElmts
+ * since infinitite recursion can result from the
+ * attempt to link the values type which will try to link
+ * this value again.
+*/
+void
+TypeLinkValueDef PARAMS ((m, currMod, v),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    ValueDef *v)
+{
+    if (v == NULL)
+        return;
+
+    TypeLinkType (m, currMod, NULL, v->value->type);
+
+    if ((v->value->valueType == BASICTYPE_UNKNOWN) &&
+        (v->value->type != NULL))
+        v->value->valueType = v->value->type->basicType->choiceId;
+
+}  /* TypeLinkValueDef */
+
+
+
+/*
+ * link any type refs associated with the given value.
+ * also sets the values type field with the given
+ * 'valuesType' Type.
+ */
+void
+TypeLinkValue PARAMS ((m, currMod, head, valuesType, v),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    ValueDef *head _AND_
+    Type *valuesType _AND_
+    Value *v)
+{
+
+    if (v == NULL)
+        return;
+
+    v->type = valuesType;
+/*    TypeLinkType (m, currMod, NULL, v->typeRef); */
+
+    if ((v->valueType == BASICTYPE_UNKNOWN) && (valuesType != NULL))
+        v->valueType = valuesType->basicType->choiceId;
+
+}  /* TypeLinkValue */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkRosOperationMacroType PARAMS ((m, currMod, head, t, bt, op),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosOperationMacroType *op)
+{
+    TypeOrValue *tOrV;
+
+    if (op->arguments != NULL)
+        TypeLinkType (m, currMod, head, op->arguments->type);
+
+    if (op->result != NULL)
+        TypeLinkType (m, currMod, head, op->result->type);
+
+    /*
+     *  go through errors (if any) and link types/values
+     */
+    FOR_EACH_LIST_ELMT (tOrV,  op->errors)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            TypeLinkType (m, currMod, head, tOrV->a.type);
+        else
+            TypeLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+    /*
+     *  go through linked operations (if any) and
+     *  link types/values
+     */
+    FOR_EACH_LIST_ELMT (tOrV,  op->linkedOps)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            TypeLinkType (m, currMod, head, tOrV->a.type);
+        else
+            TypeLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+}  /* TypeLinkRosOperationMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkRosErrorMacroType PARAMS ((m, currMod, head, t, bt, err),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosErrorMacroType *err)
+{
+    if ((err != NULL) && (err->parameter != NULL))
+    {
+        TypeLinkType (m, currMod, head, err->parameter->type);
+    }
+}   /* TypeLinkRosErrorMacroType */
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkRosBindMacroType PARAMS ((m, currMod, head, t, bt, bind),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosBindMacroType *bind)
+{
+    if (bind != NULL)
+    {
+        TypeLinkElmtType (m, currMod, head, bind->argument);
+        TypeLinkElmtType (m, currMod, head, bind->result);
+        TypeLinkElmtType (m, currMod, head, bind->error);
+    }
+}   /* TypeLinkRosBindMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkRosAseMacroType PARAMS ((m, currMod, head, t, bt, ase),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAseMacroType *ase)
+{
+    Value *v;
+
+    FOR_EACH_LIST_ELMT (v, ase->operations)
+        TypeLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (v, ase->consumerInvokes)
+        TypeLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (v, ase->supplierInvokes)
+        TypeLinkValue (m, currMod, NULL, t, v);
+
+}  /* TypeLinkRosAseMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkRosAcMacroType PARAMS ((m, currMod, head, t, bt, ac),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAcMacroType *ac)
+{
+    Value *v;
+    OID *oid;
+
+    FOR_EACH_LIST_ELMT (v,  ac->nonRoElements)
+        TypeLinkValue (m, currMod, NULL, t, v);
+
+
+    TypeLinkType (m, currMod, head, ac->bindMacroType);
+    TypeLinkType (m, currMod, head, ac->unbindMacroType);
+
+    FOR_EACH_LIST_ELMT (v, ac->operationsOf)
+        TypeLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (v, ac->initiatorConsumerOf)
+        TypeLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (v, ac->responderConsumerOf)
+        TypeLinkValue (m, currMod, NULL, t, v);
+
+}  /* TypeLinkRosAcMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkMtsasExtensionsMacroType PARAMS ((m, currMod, head, t, bt, exts),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionsMacroType *exts)
+{
+    Value *v;
+
+    FOR_EACH_LIST_ELMT (v, exts->extensions)
+        TypeLinkValue (m, currMod, NULL, t, v);
+
+}  /* TypeLinkMtsasExtensionsMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkMtsasExtensionMacroType PARAMS ((m, currMod, head, t, bt, ext),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionMacroType *ext)
+{
+    TypeLinkElmtType (m, currMod, head, ext->elmtType);
+    TypeLinkValue (m, currMod, NULL, t, ext->defaultValue);
+
+}  /* TypeLinkMtsasExtensionMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkMtsasExtensionAttributeMacroType PARAMS ((m, currMod, head, t, bt, ext),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionAttributeMacroType *ext)
+{
+
+    if (ext != NULL)
+        TypeLinkType (m, currMod, head, ext->type);
+
+}  /* TypeLinkMtsasExtensionAttributeMacroType */
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkMtsasTokenMacroType PARAMS ((m, currMod, head, t, bt, tok),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenMacroType *tok)
+{
+    if (tok != NULL)
+        TypeLinkType (m, currMod, head, tok->type);
+
+}  /* TypeLinkMtsasTokenMacroType */
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkMtsasTokenDataMacroType PARAMS ((m, currMod, head, t, bt, tok),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenDataMacroType *tok)
+{
+    if (tok != NULL)
+        TypeLinkType (m, currMod, head, tok->type);
+
+}  /* TypeLinkMtsasTokenDataMacroType */
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkMtsasSecurityCategoryMacroType PARAMS ((m, currMod, head, t, bt, sec),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasSecurityCategoryMacroType *sec)
+{
+
+    if (sec != NULL)
+        TypeLinkType (m, currMod, head, sec->type);
+
+}  /* TypeLinkMtsasSecurityCategoryMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkAsnObjectMacroType PARAMS ((m, currMod, head, t, bt, obj),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnObjectMacroType *obj)
+{
+    AsnPort *ap;
+
+    FOR_EACH_LIST_ELMT (ap, obj->ports)
+        TypeLinkValue (m, currMod, NULL, t, ap->portValue);
+
+}  /* TypeLinkAsnObjectMacroType */
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkAsnPortMacroType PARAMS ((m, currMod, head, t, bt, p),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnPortMacroType *p)
+{
+    TypeOrValue *tOrV;
+
+    FOR_EACH_LIST_ELMT (tOrV, p->abstractOps)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            TypeLinkType (m, currMod, head, tOrV->a.type);
+        else
+            TypeLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+
+    FOR_EACH_LIST_ELMT (tOrV, p->supplierInvokes)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            TypeLinkType (m, currMod, head, tOrV->a.type);
+        else
+            TypeLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+
+    FOR_EACH_LIST_ELMT (tOrV, p->consumerInvokes)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            TypeLinkType (m, currMod, head, tOrV->a.type);
+        else
+            TypeLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+}  /* TypeLinkAsnPortMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkAsnAbstractBindMacroType PARAMS ((m, currMod, head, t, bt, bind),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnAbstractBindMacroType *bind)
+{
+    AsnPort *ap;
+
+    FOR_EACH_LIST_ELMT (ap, bind->ports)
+        TypeLinkValue (m, currMod, NULL, t, ap->portValue);
+
+}  /* TypeLinkAsnBindMacroType */
+
+
+/*
+ * link any type refs in this macro's parsed data struct
+ */
+void
+TypeLinkSnmpObjectTypeMacroType PARAMS ((m, currMod, head, t, bt, ot),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    SnmpObjectTypeMacroType *ot)
+{
+    TypeOrValue *tOrV;
+
+    TypeLinkType (m, currMod, head, ot->syntax);
+    TypeLinkValue (m, currMod, NULL, t, ot->description);
+    TypeLinkValue (m, currMod, NULL, t, ot->reference);
+    TypeLinkValue (m, currMod, NULL, t, ot->defVal);
+
+    FOR_EACH_LIST_ELMT (tOrV, ot->index)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            TypeLinkType (m, currMod, head, tOrV->a.type);
+        else
+            TypeLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+}  /* TypeLinkSnmpObjectTypeMacroType */
diff --git a/SecuritySNACCRuntime/compiler/core/link-types.h b/SecuritySNACCRuntime/compiler/core/link-types.h
new file mode 100644
index 00000000..9dbddcff
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/link-types.h
@@ -0,0 +1,34 @@
+/*
+ *  compiler/core/link.h
+ *
+ *   links type references
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/link-types.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: link-types.h,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:49  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:37  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:47  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:18  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+int LinkTypeRefs PROTO ((ModuleList *m));
diff --git a/SecuritySNACCRuntime/compiler/core/link-values.c b/SecuritySNACCRuntime/compiler/core/link-values.c
new file mode 100644
index 00000000..2f421943
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/link-values.c
@@ -0,0 +1,1266 @@
+/*
+ * compiler/core/link.c
+ *
+ *  first links value refs in the import list then
+ *  links value references in value defs and types' default values
+ *
+ *
+ * Mike Sample
+ * 91/09/04
+ * Completely Rewritten for new ModuleList data structure (ASN.1 based)
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/link-values.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: link-values.c,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:49  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:38  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:38:43  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:19  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "snacc-util.h"
+#include "link-values.h"
+
+extern Module *usefulTypeModG;
+
+/* non-exported fcn prototypes */
+
+
+void ValueLinkImportLists PROTO ((ModuleList *m));
+
+void ValueLinkTypeDef PROTO ((ModuleList *m, Module *currMod, TypeDef *head));
+
+void ValueLinkElmtTypes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, NamedTypeList *e));
+
+void ValueLinkElmtType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, NamedType *n));
+
+void ValueLinkType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType));
+
+void ValueLinkBasicType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *type, BasicType *bt));
+
+void ValueLinkSubtypes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType, Subtype *s));
+
+void ValueLinkSubtypeValue PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType, SubtypeValue *s));
+
+void ValueLinkNamedElmts PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, ValueDefList *v));
+
+
+void ValueLinkValueDef PROTO ((ModuleList *m, Module *currMod, ValueDef *v));
+
+
+void ValueLinkValue PROTO ((ModuleList *m, Module *currMod, ValueDef *head, Type *valuesType, Value *v));
+
+void ValueLinkBasicValue PROTO ((ModuleList *m, Module *currMod, ValueDef *head, Type *valuesType, Value *v, BasicValue *bv));
+
+void ValueLinkOid PROTO ((ModuleList *m, Module *currMod, ValueDef *head, Value *v, OID *oid));
+
+void ValueLinkRosOperationMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosOperationMacroType *op));
+
+void ValueLinkRosErrorMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosErrorMacroType *err));
+
+
+void ValueLinkRosBindMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosBindMacroType *bind));
+
+void ValueLinkRosAseMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosAseMacroType *ase));
+
+void ValueLinkRosAcMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosAcMacroType *ac));
+
+void ValueLinkMtsasExtensionsMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionsMacroType *exts));
+
+void ValueLinkMtsasExtensionMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionMacroType *ext));
+
+void ValueLinkMtsasExtensionAttributeMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionAttributeMacroType *ext));
+
+void ValueLinkMtsasTokenMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasTokenMacroType *tok));
+
+void ValueLinkMtsasTokenDataMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasTokenDataMacroType *tok));
+
+void ValueLinkMtsasSecurityCategoryMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasSecurityCategoryMacroType *sec));
+
+void ValueLinkAsnObjectMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnObjectMacroType *obj));
+
+void ValueLinkAsnPortMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnPortMacroType *p));
+
+void ValueLinkAsnAbstractBindMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnAbstractBindMacroType *bind));
+
+void ValueLinkSnmpObjectTypeMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, SnmpObjectTypeMacroType *ot));
+
+
+/* end of prototypes */
+
+
+
+
+static char *asn1SrcFileNameG;
+static int linkOidCallDepthG = 0; /* big hack!! */
+
+/*
+ * returns 0 if no link error occured
+ * otherwise returns a value < 0.
+ * processing should not continue is an error is returned
+ */
+int
+LinkValueRefs PARAMS ((m),
+    ModuleList *m)
+{
+    Module   *currMod;
+    TypeDef  *td;
+    ValueDef *vd;
+    int linkErr = 0;
+
+    /*
+     * link imported types/values to there definition if
+     * the defining module is in the modulelist
+     */
+    ValueLinkImportLists (m);
+
+
+    /* link useful module, in case there are value defs there */
+    if (usefulTypeModG != NULL)
+    {
+        currMod = usefulTypeModG;
+        asn1SrcFileNameG = currMod->asn1SrcFileName;
+
+        /*
+         * link this modules object identifier value
+         */
+        ValueLinkOid (m, currMod, NULL, NULL, currMod->modId->oid);
+
+
+        /*
+         * go through each type in typeList and link as nec
+         */
+        FOR_EACH_LIST_ELMT (td, currMod->typeDefs)
+        {
+            ValueLinkTypeDef (m, currMod, td);
+        }
+
+
+        /*
+         *  go through each value in valueList and link as nec
+         */
+        FOR_EACH_LIST_ELMT (vd, currMod->valueDefs)
+        {
+            ValueLinkValueDef (m, currMod, vd);
+        }
+
+        if (currMod->status != MOD_ERROR)
+            currMod->status = MOD_OK;
+        else
+            linkErr = -1;
+    }
+
+    /*
+     * go through types, values & macros of each parsed module
+     */
+
+    FOR_EACH_LIST_ELMT (currMod, m)
+    {
+
+        asn1SrcFileNameG = currMod->asn1SrcFileName;
+
+        /*
+         * link this modules object identifier value
+         */
+        ValueLinkOid (m, currMod, NULL, NULL, currMod->modId->oid);
+
+
+        /*
+         * go through each type in typeList and link as nec
+         */
+        FOR_EACH_LIST_ELMT (td, currMod->typeDefs)
+        {
+            ValueLinkTypeDef (m, currMod, td);
+        }
+
+        /*
+         *  go through each value in valueList and link as nec
+         */
+        FOR_EACH_LIST_ELMT (vd, currMod->valueDefs)
+        {
+            ValueLinkValueDef (m, currMod, vd);
+        }
+
+        if (currMod->status != MOD_ERROR)
+            currMod->status = MOD_OK;
+        else
+            linkErr = -1;
+    }
+
+    return linkErr;
+
+} /* ValueLinkRefs */
+
+
+/*
+ * go through each modules import lists and link
+ * any values as nec. values'symbols start with a
+ * lowercase letter
+ */
+void
+ValueLinkImportLists PARAMS ((m),
+    ModuleList *m)
+{
+    Module *currMod;
+    TypeDef *t;
+    ValueDef *v;
+    ImportModule *currImpList;
+    ImportElmt *currImpElmt;
+    Module *impRefMod;
+
+
+    /* link imports of each module in the list */
+    FOR_EACH_LIST_ELMT (currMod, m)
+    {
+        /* for each import list in the current module */
+        FOR_EACH_LIST_ELMT (currImpList, currMod->imports)
+        {
+            /* see if the referenced module is in the list */
+            impRefMod = LookupModule (m, currImpList->modId->name, currImpList->modId->oid);
+
+            if (impRefMod == NULL)
+            {
+                /* the type linker will have reported this error */
+                continue;
+            }
+
+            /*
+             * link each value referencing import elmt in
+             * the current import list
+             */
+            FOR_EACH_LIST_ELMT (currImpElmt, currImpList->importElmts)
+            {
+                /*
+                 * only link values (all vals have lowercase first letter)
+                 */
+                if (!islower (currImpElmt->name[0]))
+                    continue;
+
+                v = LookupValue (impRefMod->valueDefs, currImpElmt->name);
+                if (v != NULL)
+                {
+                    if (!v->exported)
+                    {
+                        currMod->status = MOD_ERROR;
+                        PrintErrLoc (currMod->asn1SrcFileName, currImpElmt->lineNo);
+                        fprintf (stderr,"ERROR - \"%s\" module imports value \"%s\", which is not exported from module \"%s\".\n", currMod->modId->name, currImpElmt->name, impRefMod->modId->name);
+                    }
+                    /* resolve value */
+                    currImpElmt->resolvedRef =
+                        (ImportElmtChoice*)Malloc (sizeof (ImportElmtChoice));
+                    currImpElmt->resolvedRef->choiceId = IMPORTELMTCHOICE_VALUE;
+                    currImpElmt->resolvedRef->a.value = v;
+                }
+                else /* value not found in ref'd module */
+                {
+                    currMod->status = MOD_ERROR;
+                    PrintErrLoc (currMod->asn1SrcFileName, currImpElmt->lineNo);
+                    fprintf (stderr,"ERROR - \"%s\" is imported from module \"%s\" by module \"%s\", but is not defined in the referenced module\n", currImpElmt->name, impRefMod->modId->name, currMod->modId->name);
+		}
+
+            }
+        }
+    }
+} /* ValueLinkImportLists */
+
+
+
+void
+ValueLinkTypeDef PARAMS ((m, currMod, head),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head)
+{
+
+    if (head == NULL)
+        return;
+
+    ValueLinkType (m, currMod, head, head->type);
+
+}  /* ValueLinkTypeDef */
+
+
+
+void
+ValueLinkType PARAMS ((m, currMod, head, t),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t)
+{
+
+    if (t == NULL)
+        return;
+
+    ValueLinkBasicType (m, currMod, head, t, t->basicType);
+
+    ValueLinkSubtypes (m, currMod, head, t, t->subtypes);
+
+    if (t->defaultVal != NULL)
+        ValueLinkValue (m, currMod, NULL, t,  t->defaultVal->value);
+
+}  /* ValueLinkType */
+
+
+
+void
+ValueLinkElmtTypes PARAMS ((m, currMod, head, e),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    NamedTypeList *e)
+{
+    NamedType *n;
+    FOR_EACH_LIST_ELMT (n, e)
+    {
+        ValueLinkElmtType (m, currMod, head, n);
+    }
+}  /* ValueLinkElmtTypes */
+
+
+void
+ValueLinkElmtType PARAMS ((m, currMod, head, n),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    NamedType *n)
+{
+    if (n != NULL)
+        ValueLinkType (m, currMod, head, n->type);
+}
+
+
+void
+ValueLinkBasicType PARAMS ((m, currMod, head, type, bt),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *type _AND_
+    BasicType *bt)
+{
+    TypeDef *tmpTypeDef;
+    TypeDefList *tmpTypeDefs;
+    Type *tmpType;
+    Module *tmpMod;
+    NamedType *tmpElmtType;
+    ImportElmt *impElmt;
+    ImportModule *impMod;
+    int implicitRef;
+
+    if (bt == NULL)
+        return;
+
+    switch (bt->choiceId)
+    {
+
+        case BASICTYPE_SEQUENCE:
+        case BASICTYPE_SET:
+        case BASICTYPE_CHOICE:
+            ValueLinkElmtTypes (m, currMod, head, bt->a.set);
+            break;
+
+
+
+        case BASICTYPE_SEQUENCEOF:
+        case BASICTYPE_SETOF:
+            ValueLinkType (m, currMod, head, bt->a.setOf);
+            break;
+
+
+
+        case BASICTYPE_SELECTION:
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_ANYDEFINEDBY:
+        case BASICTYPE_LOCALTYPEREF:
+        case BASICTYPE_IMPORTTYPEREF:
+            break;
+
+        /*
+         * these types may optionally have named elmts
+         */
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_BITSTRING:
+        case BASICTYPE_ENUMERATED:
+            ValueLinkNamedElmts (m, currMod, head, type, bt->a.integer);
+            break;
+
+
+
+        /*
+         * these types have no extra info and cause no linking action
+         */
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_BOOLEAN:
+        case BASICTYPE_OCTETSTRING:
+        case BASICTYPE_NULL:
+        case BASICTYPE_OID:
+        case BASICTYPE_REAL:
+        case BASICTYPE_ANY:
+        case BASICTYPE_MACRODEF:
+            /*
+             * these have no more info -  only the  choiceId is used
+             */
+            break;
+
+        case BASICTYPE_MACROTYPE:
+            switch (bt->a.macroType->choiceId)
+            {
+        case MACROTYPE_ROSOPERATION:
+        case MACROTYPE_ASNABSTRACTOPERATION:
+
+            ValueLinkRosOperationMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosOperation);
+            break;
+
+        case MACROTYPE_ROSERROR:
+        case MACROTYPE_ASNABSTRACTERROR:
+            ValueLinkRosErrorMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosError);
+             break;
+
+        case MACROTYPE_ROSBIND:
+        case MACROTYPE_ROSUNBIND:
+            ValueLinkRosBindMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosBind);
+             break;
+
+        case MACROTYPE_ROSASE:
+            ValueLinkRosAseMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosAse);
+             break;
+
+        case MACROTYPE_MTSASEXTENSIONS:
+            ValueLinkMtsasExtensionsMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtensions);
+            break;
+
+        case MACROTYPE_MTSASEXTENSION:
+            ValueLinkMtsasExtensionMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtension);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONATTRIBUTE:
+            ValueLinkMtsasExtensionAttributeMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtensionAttribute);
+            break;
+
+        case MACROTYPE_MTSASTOKEN:
+            ValueLinkMtsasTokenMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasToken);
+            break;
+
+        case MACROTYPE_MTSASTOKENDATA:
+            ValueLinkMtsasTokenDataMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasTokenData);
+            break;
+
+        case MACROTYPE_MTSASSECURITYCATEGORY:
+            ValueLinkMtsasSecurityCategoryMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasSecurityCategory);
+            break;
+
+        case MACROTYPE_ASNOBJECT:
+            ValueLinkAsnObjectMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnObject);
+            break;
+
+        case MACROTYPE_ASNPORT:
+            ValueLinkAsnPortMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnPort);
+            break;
+
+        case MACROTYPE_ASNABSTRACTBIND:
+        case MACROTYPE_ASNABSTRACTUNBIND:
+            ValueLinkAsnAbstractBindMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnAbstractBind);
+            break;
+
+        case MACROTYPE_AFALGORITHM:
+        case MACROTYPE_AFENCRYPTED:
+        case MACROTYPE_AFPROTECTED:
+        case MACROTYPE_AFSIGNATURE:
+        case MACROTYPE_AFSIGNED:
+            ValueLinkType (m, currMod, head, bt->a.macroType->a.afAlgorithm);
+            break;
+
+        case MACROTYPE_SNMPOBJECTTYPE:
+            ValueLinkSnmpObjectTypeMacroType (m, currMod, head, type, bt, bt->a.macroType->a.snmpObjectType);
+            break;
+
+        default:
+            fprintf (stderr, "ValueLinkBasicType: ERROR - unknown macro type id!\n");
+        break;
+    }
+        break;
+
+        default:
+            fprintf (stderr, "ValueLinkBasicType: ERROR - unknown basic type id!\n");
+
+    }
+}  /* ValueLinkBasicType */
+
+
+
+
+/*
+ * resolve any type/value refs in the subtypes (if any)
+ */
+void
+ValueLinkSubtypes PARAMS ((m, currMod, head, currType, s),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *currType _AND_
+    Subtype *s)
+{
+    Subtype *sElmt;
+
+    if (s == NULL)
+        return;
+
+    switch (s->choiceId)
+    {
+        case SUBTYPE_SINGLE:
+            ValueLinkSubtypeValue (m, currMod, head, currType, s->a.single);
+        break;
+
+        case SUBTYPE_AND:
+        case SUBTYPE_OR:
+        case SUBTYPE_NOT:
+            FOR_EACH_LIST_ELMT (sElmt, s->a.and)
+            {
+                ValueLinkSubtypes (m, currMod, head, currType, sElmt);
+            }
+        break;
+
+        default:
+            fprintf (stderr, "ValueLinkSubtypes: ERROR - unknown Subtype id\n");
+        break;
+    }
+}  /* ValueLinkSubtypes */
+
+
+
+
+
+void
+ValueLinkSubtypeValue PARAMS ((m, currMod, head, currType, s),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *currType _AND_
+    SubtypeValue *s)
+{
+    Constraint *constraint;
+
+    if (s == NULL)
+        return;
+
+    switch (s->choiceId)
+    {
+        case SUBTYPEVALUE_SINGLEVALUE:
+            ValueLinkValue (m, currMod, NULL, currType, s->a.singleValue);
+            break;
+
+        case SUBTYPEVALUE_CONTAINED:
+            ValueLinkType (m, currMod, head, s->a.contained);
+            break;
+
+        case SUBTYPEVALUE_VALUERANGE:
+            ValueLinkValue (m, currMod, NULL, currType, s->a.valueRange->lowerEndValue);
+            ValueLinkValue (m, currMod, NULL, currType, s->a.valueRange->upperEndValue);
+            break;
+
+        case SUBTYPEVALUE_PERMITTEDALPHABET:
+            ValueLinkSubtypes (m, currMod, head, currType, s->a.permittedAlphabet);
+           break;
+
+        case SUBTYPEVALUE_SIZECONSTRAINT:
+            ValueLinkSubtypes (m, currMod, head, currType, s->a.sizeConstraint);
+            break;
+
+        case SUBTYPEVALUE_INNERSUBTYPE:
+            FOR_EACH_LIST_ELMT (constraint, s->a.innerSubtype->constraints)
+            {
+                ValueLinkSubtypes (m, currMod, head, currType, constraint->valueConstraints);
+            }
+            break;
+
+        default:
+            fprintf (stderr,"ValueLinkSubtype: ERROR - unknown subtype choiceId\n");
+    }
+
+} /* ValueLinkSubtype */
+
+
+
+
+void
+ValueLinkNamedElmts PARAMS ((m, currMod, head, t, v),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    ValueDefList *v)
+{
+    ValueDef *vd;
+    FOR_EACH_LIST_ELMT (vd, v)
+    {
+        ValueLinkValue (m, currMod, vd, vd->value->type, vd->value);
+    }
+
+}  /* ValueLinkNamedElmts */
+
+
+
+
+void
+ValueLinkValueDef PARAMS ((m, currMod, v),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    ValueDef *v)
+{
+    if (v == NULL)
+        return;
+
+    ValueLinkType (m, currMod, NULL, v->value->type);
+    ValueLinkValue (m, currMod, v, v->value->type, v->value);
+
+}  /* ValueLinkValueDef */
+
+
+
+
+void
+ValueLinkValue PARAMS ((m, currMod, head, valuesType, v),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    ValueDef *head _AND_
+    Type *valuesType _AND_
+    Value *v)
+{
+
+    if (v == NULL)
+        return;
+
+    ValueLinkBasicValue (m, currMod, head, valuesType, v, v->basicValue);
+
+}  /* ValueLinkValue */
+
+
+
+void
+ValueLinkBasicValue PARAMS ((m, currMod, head, valuesType, v, bv),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    ValueDef *head _AND_
+    Type *valuesType _AND_
+    Value *v _AND_
+    BasicValue *bv)
+{
+    ValueDef *tmpValueDef;
+    Module *tmpMod;
+    ImportElmt *impElmt;
+    ImportModule *impMod;
+    ValueDef *n;
+    ValueDefList *namedElmtList;
+
+
+    if (v == NULL)
+        return;
+
+
+    switch (bv->choiceId)
+    {
+        case BASICVALUE_UNKNOWN:
+        case BASICVALUE_EMPTY:
+        case BASICVALUE_INTEGER:
+        case BASICVALUE_SPECIALINTEGER:
+        case BASICVALUE_BOOLEAN:
+        case BASICVALUE_REAL:
+        case BASICVALUE_SPECIALREAL:
+        case BASICVALUE_ASCIITEXT:
+        case BASICVALUE_ASCIIHEX:
+        case BASICVALUE_ASCIIBITSTRING:
+        case BASICVALUE_BERVALUE:
+        case BASICVALUE_PERVALUE:
+        case BASICVALUE_NAMEDVALUE:
+        case BASICVALUE_NULL:
+        case BASICVALUE_VALUENOTATION:
+        case BASICVALUE_OID:
+            break;
+
+
+        case BASICVALUE_LOCALVALUEREF:
+
+            /*
+             * parser sets all value refs to "Local" so must
+             * check if local, then if import ....
+             */
+
+            /*
+             * first check in named elmts of the given type
+             */
+            namedElmtList = GetAllNamedElmts (valuesType);
+            if (namedElmtList != NULL)
+            {
+                n = LookupValue (namedElmtList, bv->a.localValueRef->valueName);
+
+                if (n != NULL)
+                {
+                    bv->a.localValueRef->link = n;
+                    bv->a.localValueRef->module = currMod;
+
+                    /* now free list structure (not data elmts) */
+                    AsnListFree (namedElmtList);
+
+                    break; /* exit switch since done here. */
+                }
+            }
+
+            /*
+             * second, look for values defined in this module
+             */
+            tmpValueDef = LookupValue (currMod->valueDefs, bv->a.localValueRef->valueName);
+
+            if (tmpValueDef != NULL)
+            {
+                bv->a.localValueRef->link = tmpValueDef;
+                break; /* exit switch since done here. */
+            }
+
+            else
+                bv->choiceId = BASICVALUE_IMPORTVALUEREF;
+                /*!!!!!!!!!! fall through from else clause */
+
+
+        case BASICVALUE_IMPORTVALUEREF:
+            /* This handles "modname.value" value refs. */
+            if (bv->a.importValueRef->moduleName != NULL)
+            {
+                /*
+                 * Lookup the import list maintained in this module
+                 * from the named module.  (the parser generates
+                 * an import list from Foo module for "Foo.Bar" style
+                 * import refs)
+                 */
+                impMod = LookupImportModule (currMod, bv->a.importValueRef->moduleName);
+
+                if (impMod == NULL) /* whoa, compiler error */
+                {
+                    currMod->status = MOD_ERROR;
+                    fprintf (stderr,"Compiler Error: \"%s.%s\" valueref - no import list defined from module \"%s\".\n", bv->a.importValueRef->moduleName, bv->a.importValueRef->valueName, bv->a.importValueRef->moduleName);
+
+                    return;
+                }
+                impElmt = LookupImportElmtInImportElmtList (impMod->importElmts, bv->a.importValueRef->valueName);
+
+                if (impElmt == NULL) /* whoa, compiler error again */
+                {
+                    currMod->status = MOD_ERROR;
+                    fprintf (stderr,"Compiler Error: \"%s.%s\" valueref - no import element defined for value \"%s\".\n", bv->a.importValueRef->moduleName, bv->a.importValueRef->valueName, bv->a.importValueRef->valueName);
+
+
+                }
+                else if (impElmt->resolvedRef != NULL)
+                {
+                    if (impElmt->resolvedRef->choiceId !=
+                        IMPORTELMTCHOICE_VALUE)
+                        fprintf (stderr,"Linker Warning: import VALUE ref \"%s\" resolves with an imported TYPE\n", impElmt->name);
+
+                    bv->a.importValueRef->link = impElmt->resolvedRef->a.value;
+                    bv->a.importValueRef->module = impMod->moduleRef;
+                }
+                else
+                {
+                    PrintErrLoc (currMod->asn1SrcFileName, v->lineNo);
+                    fprintf (stderr,"reference to unresolved imported value \"%s\"\n", impElmt->name);
+                }
+            }
+            else
+            {
+                impElmt = LookupImportElmtInModule (currMod, bv->a.importValueRef->valueName, &impMod);
+                if ((impElmt != NULL) && (!impElmt->privateScope))
+                {
+                    /*
+                     * if import elmt is resolved then
+                     * set up link
+                     */
+
+                    if (impElmt->resolvedRef != NULL)
+                    {
+                        if (impElmt->resolvedRef->choiceId !=
+                            IMPORTELMTCHOICE_VALUE)
+                            fprintf (stderr,"Linker Warning: import VALUE ref \"%s\" resolves with an imported TYPE\n", impElmt->name);
+
+                        bv->a.importValueRef->link = impElmt->resolvedRef->a.value;
+                        bv->a.importValueRef->module = impMod->moduleRef;
+                    }
+                    else
+                    {
+                        PrintErrLoc (currMod->asn1SrcFileName, v->lineNo);
+                        fprintf (stderr,"reference to unresolved imported value \"%s\"\n", impElmt->name);
+                    }
+                }
+
+                /*
+                 * third, look for values defined in the useful module
+                 */
+                else if ((usefulTypeModG != NULL) &&
+                         ((tmpValueDef = LookupValue (usefulTypeModG->valueDefs, bv->a.localValueRef->valueName)) != NULL))
+                {
+                    bv->a.localValueRef->link = tmpValueDef;
+                    bv->a.localValueRef->module = usefulTypeModG;
+                }
+                else
+                {
+                    /*
+                     *  value not defined locally, nor imported nor
+                     *  defined in useful types module
+                     */
+                    currMod->status = MOD_ERROR;
+                    PrintErrLoc (currMod->asn1SrcFileName, v->lineNo);
+                    fprintf (stderr,"ERROR - value \"%s\" is referenced but not defined or imported.\n", bv->a.importValueRef->valueName);
+                }
+            }
+            break;
+
+        case BASICVALUE_LINKEDOID:
+            ValueLinkOid (m, currMod, head, v, bv->a.linkedOid);
+            break;
+
+        default:
+           fprintf (stderr,"ValueLinkBasicValue: ERROR - unknown value type\n");
+    }
+
+}  /* ValueLinkBasicValue */
+
+
+/*
+ * link the value refs from an object identifier
+ *
+ *
+ * eg
+ * for { ccitt foo (1) bar bell (bunt) 2 } the format is
+ *
+ * ccitt
+ *    arcnum is set to number from oid table (oid.c)
+ * foo (1)
+ *   - arc num is set to 1
+ *   - sets up a new value def foo defined as 1
+ *   - makes oid valueref a value ref to foo (doesn't link it tho)
+ * bar
+ *   - makes oid valueref a value ref to bar (doesn't link it tho)
+ * bell (bunt)
+ *   - sets up a new value def bell defined as a val ref to bunt
+ *   - makes oid valueref a value ref to bell (doesn't link it tho)
+ * 2
+ *  -arc num is set to 2
+ *
+ */
+void
+ValueLinkOid PARAMS ((m, currMod, head, v, oid),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    ValueDef *head _AND_
+    Value *v _AND_
+    OID *oid)
+{
+    ValueDef *tmpValueDef;
+    ImportElmt *impElmt;
+    ImportModule *impMod;
+    int lineNo;
+    OID *firstElmt;
+    Value *val;
+
+    /*
+     * WARNING: for cyclic oid value definintions like.
+     * foo OID ::= { bar 1 3 }
+     * bar OID ::= { foo 1 3 }
+     * infinite recursion is prevented by
+     * a hack (linkOidCallDepth)
+     */
+    if (linkOidCallDepthG > 100)
+    {
+        currMod->status = MOD_ERROR;
+        PrintErrLoc (currMod->asn1SrcFileName, v->lineNo);
+        fprintf (stderr,"ERROR - OBJECT IDENTIFIER value \"%s\" appears to be defined recursively\n", head->definedName);
+        linkOidCallDepthG = 0;
+        return;
+    }
+    else
+        linkOidCallDepthG++;
+
+    for (firstElmt = oid; oid != NULL; oid = oid->next)
+    {
+        if (oid->valueRef != NULL)
+        {
+            ValueLinkValue (m, currMod, head, NULL, oid->valueRef);
+
+            if ((oid->valueRef->basicValue->choiceId !=
+                  BASICVALUE_LOCALVALUEREF) &&
+                (oid->valueRef->basicValue->choiceId !=
+                 BASICVALUE_IMPORTVALUEREF))
+            {
+                fprintf (stderr,"Internal error: Oid valueref is not a ref\n");
+                break; /* exit for */
+            }
+
+            /*
+             * leave simplification (replacement of value refs with values)
+             * of oid values to normalize.c
+             */
+        }
+    }
+
+    linkOidCallDepthG--;
+
+}  /* ValueLinkOid */
+
+
+void
+ValueLinkRosOperationMacroType PARAMS ((m, currMod, head, t, bt, op),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosOperationMacroType *op)
+{
+    TypeOrValue *tOrV;
+
+    if (op->arguments != NULL)
+        ValueLinkType (m, currMod, head, op->arguments->type);
+
+    if (op->result != NULL)
+        ValueLinkType (m, currMod, head, op->result->type);
+
+    /*
+     *  go through errors (if any) and link types/values
+     */
+    FOR_EACH_LIST_ELMT (tOrV,  op->errors)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            ValueLinkType (m, currMod, head, tOrV->a.type);
+        else
+            ValueLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+    /*
+     *  go through linked operations (if any) and
+     *  link types/values
+     */
+    FOR_EACH_LIST_ELMT (tOrV,  op->linkedOps)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            ValueLinkType (m, currMod, head, tOrV->a.type);
+        else
+            ValueLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+}  /* ValueLinkRosOperationMacroType */
+
+
+void
+ValueLinkRosErrorMacroType PARAMS ((m, currMod, head, t, bt, err),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosErrorMacroType *err)
+{
+    if ((err != NULL) && (err->parameter != NULL))
+    {
+        ValueLinkType (m, currMod, head, err->parameter->type);
+    }
+}   /* ValueLinkRosErrorMacroType */
+
+
+void
+ValueLinkRosBindMacroType PARAMS ((m, currMod, head, t, bt, bind),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosBindMacroType *bind)
+{
+    if (bind != NULL)
+    {
+        ValueLinkElmtType (m, currMod, head, bind->argument);
+        ValueLinkElmtType (m, currMod, head, bind->result);
+        ValueLinkElmtType (m, currMod, head, bind->error);
+    }
+}   /* ValueLinkRosBindMacroType */
+
+
+void
+ValueLinkRosAseMacroType PARAMS ((m, currMod, head, t, bt, ase),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAseMacroType *ase)
+{
+    Value *v;
+
+    FOR_EACH_LIST_ELMT (v, ase->operations)
+        ValueLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (v, ase->consumerInvokes)
+        ValueLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (v, ase->supplierInvokes)
+        ValueLinkValue (m, currMod, NULL, t, v);
+
+}  /* ValueLinkRosAseMacroType */
+
+
+
+void
+ValueLinkRosAcMacroType PARAMS ((m, currMod, head, t, bt, ac),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAcMacroType *ac)
+{
+    Value *v;
+    OID *oid;
+
+    FOR_EACH_LIST_ELMT (v,  ac->nonRoElements)
+        ValueLinkValue (m, currMod, NULL, t, v);
+
+
+    ValueLinkType (m, currMod, head, ac->bindMacroType);
+    ValueLinkType (m, currMod, head, ac->unbindMacroType);
+
+    FOR_EACH_LIST_ELMT (v, ac->operationsOf)
+        ValueLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (v, ac->initiatorConsumerOf)
+        ValueLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (v, ac->responderConsumerOf)
+        ValueLinkValue (m, currMod, NULL, t, v);
+
+
+    FOR_EACH_LIST_ELMT (oid, ac->abstractSyntaxes)
+        ValueLinkOid (m, currMod, NULL, NULL,  oid);
+
+}  /* ValueLinkRosAcMacroType */
+
+
+
+void
+ValueLinkMtsasExtensionsMacroType PARAMS ((m, currMod, head, t, bt, exts),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionsMacroType *exts)
+{
+    Value *v;
+
+    FOR_EACH_LIST_ELMT (v, exts->extensions)
+        ValueLinkValue (m, currMod, NULL, t, v);
+
+}  /* ValueLinkMtsasExtensionsMacroType */
+
+
+void
+ValueLinkMtsasExtensionMacroType PARAMS ((m, currMod, head, t, bt, ext),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionMacroType *ext)
+{
+    ValueLinkElmtType (m, currMod, head, ext->elmtType);
+    ValueLinkValue (m, currMod, NULL, t, ext->defaultValue);
+
+}  /* ValueLinkMtsasExtensionMacroType */
+
+
+void
+ValueLinkMtsasExtensionAttributeMacroType PARAMS ((m, currMod, head, t,bt, ext),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionAttributeMacroType *ext)
+{
+
+    if (ext != NULL)
+        ValueLinkType (m, currMod, head, ext->type);
+
+}  /* ValueLinkMtsasExtensionAttributeMacroType */
+
+
+void
+ValueLinkMtsasTokenMacroType PARAMS ((m, currMod, head, t, bt, tok),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenMacroType *tok)
+{
+    if (tok != NULL)
+        ValueLinkType (m, currMod, head, tok->type);
+
+}  /* ValueLinkMtsasTokenMacroType */
+
+
+void
+ValueLinkMtsasTokenDataMacroType PARAMS ((m, currMod, head, t, bt, tok),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenDataMacroType *tok)
+{
+    if (tok != NULL)
+        ValueLinkType (m, currMod, head, tok->type);
+
+}  /* ValueLinkMtsasTokenDataMacroType */
+
+void
+ValueLinkMtsasSecurityCategoryMacroType PARAMS ((m, currMod, head, t, bt, sec),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasSecurityCategoryMacroType *sec)
+{
+
+    if (sec != NULL)
+        ValueLinkType (m, currMod, head, sec->type);
+
+}  /* ValueLinkMtsasSecurityCategoryMacroType */
+
+
+
+void
+ValueLinkAsnObjectMacroType PARAMS ((m, currMod, head, t, bt, obj),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnObjectMacroType *obj)
+{
+    AsnPort *ap;
+
+    FOR_EACH_LIST_ELMT (ap, obj->ports)
+        ValueLinkValue (m, currMod, NULL, t, ap->portValue);
+
+}  /* ValueLinkAsnObjectMacroType */
+
+
+void
+ValueLinkAsnPortMacroType PARAMS ((m, currMod, head, t, bt, p),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnPortMacroType *p)
+{
+    TypeOrValue *tOrV;
+
+    FOR_EACH_LIST_ELMT (tOrV, p->abstractOps)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            ValueLinkType (m, currMod, head, tOrV->a.type);
+        else
+            ValueLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+
+    FOR_EACH_LIST_ELMT (tOrV, p->supplierInvokes)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            ValueLinkType (m, currMod, head, tOrV->a.type);
+        else
+            ValueLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+
+    FOR_EACH_LIST_ELMT (tOrV, p->consumerInvokes)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            ValueLinkType (m, currMod, head, tOrV->a.type);
+        else
+            ValueLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+}  /* ValueLinkAsnPortMacroType */
+
+
+
+void
+ValueLinkAsnAbstractBindMacroType PARAMS ((m, currMod, head, t, bt, bind),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnAbstractBindMacroType *bind)
+{
+    AsnPort *ap;
+
+    FOR_EACH_LIST_ELMT (ap, bind->ports)
+        ValueLinkValue (m, currMod, NULL, t, ap->portValue);
+
+}  /* ValueLinkAsnBindMacroType */
+
+
+
+void
+ValueLinkSnmpObjectTypeMacroType PARAMS ((m, currMod, head, t, bt, ot),
+    ModuleList *m _AND_
+    Module *currMod _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    SnmpObjectTypeMacroType *ot)
+{
+    TypeOrValue *tOrV;
+
+    ValueLinkType (m, currMod, head, ot->syntax);
+    ValueLinkValue (m, currMod, NULL, t, ot->description);
+    ValueLinkValue (m, currMod, NULL, t, ot->reference);
+    ValueLinkValue (m, currMod, NULL, t, ot->defVal);
+
+    FOR_EACH_LIST_ELMT (tOrV, ot->index)
+    {
+        if (tOrV->choiceId == TYPEORVALUE_TYPE)
+            ValueLinkType (m, currMod, head, tOrV->a.type);
+        else
+            ValueLinkValue (m, currMod, NULL, t, tOrV->a.value);
+    }
+
+}  /* ValueLinkSnmpObjectTypeMacroType */
diff --git a/SecuritySNACCRuntime/compiler/core/link-values.h b/SecuritySNACCRuntime/compiler/core/link-values.h
new file mode 100644
index 00000000..fd278178
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/link-values.h
@@ -0,0 +1,34 @@
+/*
+ *  compiler/core/link_values.h
+ *
+ *   links value references
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/link-values.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: link-values.h,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:50  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:39  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/10/08  03:48:48  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:20  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+int LinkValueRefs PROTO ((ModuleList *m));
diff --git a/SecuritySNACCRuntime/compiler/core/mem.c b/SecuritySNACCRuntime/compiler/core/mem.c
new file mode 100644
index 00000000..d33fb78f
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/mem.c
@@ -0,0 +1,97 @@
+/*
+ * compiler/core/mem.c - used for allocating the components of the Module
+ *         data structure.  The program expects 0'ed memory
+ *         to be returned by Malloc - this initializes ptrs
+ *         to NULL.
+ *
+ *         If there is not enough memory the Malloc exits
+ *         (Callers of Malloc will never get a NULL return value)
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/mem.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: mem.c,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:50  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/07/25 19:11:50  rj
+ * use memzero that is defined in .../snacc.h to use either memset or bzero.
+ *
+ * Realloc() now checks realloc(3)'s return value.
+ *
+ * Revision 1.3  1994/10/08  03:48:49  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:39:27  rj
+ * snacc_config.h removed; more portable .h file inclusion.
+ *
+ * Revision 1.1  1994/08/28  09:49:21  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ */
+
+#include "snacc.h"
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#else
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <memory.h>
+#endif
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#endif
+
+#include <stdio.h>
+
+#include "mem.h"
+
+void*
+Malloc PARAMS ((size), int size)
+{
+    void *retVal = malloc (size);
+
+    if (retVal == NULL)
+    {
+        fprintf (stderr, "out of memory! bye!\n");
+        fprintf (stderr, "tried to allocate %d byes\n", size);
+        exit (1);
+    }
+
+    memzero (retVal, size);
+    return retVal;
+
+}  /* Malloc */
+
+void *Realloc PARAMS ((ptr, newsize),
+    void *ptr _AND_
+    int newsize)
+{
+    void *retval = realloc (ptr, newsize);
+
+    if (retval == NULL)
+    {
+        fprintf (stderr, "out of memory! bye!\n");
+        fprintf (stderr, "tried to reallocate %d byes\n", newsize);
+        exit (1);
+    }
+
+    return retval;
+}
+
+void Free PARAMS ((ptr),
+    void *ptr)
+{
+    free (ptr);
+}
diff --git a/SecuritySNACCRuntime/compiler/core/meta.c b/SecuritySNACCRuntime/compiler/core/meta.c
new file mode 100644
index 00000000..e9cc0e6b
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/meta.c
@@ -0,0 +1,57 @@
+/*
+ * file: compiler/core/meta.c
+ *
+ * Copyright © 1994 1995 Robert Joop <rj@rainbow.in-berlin.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program and the associated libraries are distributed in the hope
+ * that they will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License and GNU Library General
+ * Public License for more details.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/meta.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: meta.c,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:50  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1995/08/17 15:00:11  rj
+ * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted)
+ *
+ * Revision 1.1  1995/07/27  10:54:11  rj
+ * new file
+ *
+ */
+
+#include <stdio.h>
+
+#include "snacc.h"
+#include "meta.h"
+
+#if META
+
+int isMetaPDU PARAMS ((module, type, pdus),
+  const char *module _AND_
+  const char *type _AND_
+  MetaPDU *pdus)
+{
+  MetaPDU *pdu;
+
+  for (pdu=pdus; pdu; pdu=pdu->next)
+    if (!strcmp (pdu->module, module) && !strcmp (pdu->type, type))
+    {
+      pdu->used = TRUE;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+#endif /* META */
diff --git a/SecuritySNACCRuntime/compiler/core/meta.h b/SecuritySNACCRuntime/compiler/core/meta.h
new file mode 100644
index 00000000..ca1615be
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/meta.h
@@ -0,0 +1,60 @@
+/*
+ * file: compiler/core/meta.h
+ *
+ * Copyright © 1994 1995 Robert Joop <rj@rainbow.in-berlin.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program and the associated libraries are distributed in the hope
+ * that they will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License and GNU Library General
+ * Public License for more details.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/meta.h,v 1.1 2001/06/20 21:27:57 dmitch Exp $
+ * $Log: meta.h,v $
+ * Revision 1.1  2001/06/20 21:27:57  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:50  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1995/09/07 19:14:26  rj
+ * enum MetaNameStyle introduced.
+ *
+ * Revision 1.3  1995/08/17  15:00:12  rj
+ * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted)
+ *
+ * Revision 1.1  1995/07/27  10:54:11  rj
+ * new file
+ */
+
+#if META
+
+typedef enum
+{
+  META_off = 0,		/* metacode generation disabled */
+  META_asn1_names,	/* names as defined in .asn1 file */
+  META_backend_names,	/* names as being used by the backend code */
+} MetaNameStyle;
+
+typedef struct
+{
+  const char	*srcfn;
+  FILE		*srcfp;
+} Meta;
+
+typedef struct MetaPDU
+{
+  const char	*module, *type;
+  int		used;
+
+  struct MetaPDU	*next;
+} MetaPDU;
+
+extern int	isMetaPDU PROTO ((const char *module, const char *type, MetaPDU *pdus));
+
+#endif /* META */
diff --git a/SecuritySNACCRuntime/compiler/core/normalize.c b/SecuritySNACCRuntime/compiler/core/normalize.c
new file mode 100644
index 00000000..44679f3a
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/normalize.c
@@ -0,0 +1,860 @@
+/*
+ * compiler/core/normalize.c
+ *
+ * 1. swap COMPONENTS OF for actual types
+ *     - do this since save lots of special case handling in
+ *       code generation
+ *
+ * 2. change SEQUENCE OF/SET OF (type def (not ref))
+ *    to     SEQUENCE OF/SEQ OF (type ref)
+ *           and add type def for orig.
+ *     - do this since OF type are AsnList
+ *
+ * 3. change CHOICE defs within other constructed types
+ *      into CHOICE refs
+ *        - makes code production easier. can be changed
+ *          with some work
+ *
+ * 4. change SEQUENCE/SET defs within other constructed types
+ *      into SEQUENCE/SET refs
+ *        - makes code production easier. can be changed
+ *          with some work (allocation in decode is wrong
+ *                          - isPtr set incorrectly)
+ *
+ * 5. change SELECTION types to the actual field from the choice
+ *
+ * 6. convert Linked oid's with value refs into a ENC_OID's
+ *    so values can be easily defined in C/C++. MS 92/03/01
+ *
+ * 7. if IMPLICIT-TAGS is specified, mark type references
+ *    as implicit, if the ref'd type is not CHOICE or ANY.
+ *    (Extra tags on primitives (ie not references) are already
+ *     removed in the parsing step (asn1.yacc)).
+ *
+ * 8.  SET OF/SEQ OF defs nested in other SETs/SEQ/CHOICEs/SET OF/SEQ OF
+ *     types are moved to separate type defs - added 08/92 to support
+ *     C++ lists more easily.
+ *
+ * 9.  INTEGERs with named elmts and ENUM defs nested in other
+ * SETs/SEQ/CHOICEs/SET OF/SEQ OF types are moved to separate type
+ * defs - added 08/92 to support C++ class hierarchy better.
+ *
+ * ******** 10 is no longer done - in fact it was stupid for ******
+ * ******** ANY DEFINED BY types                MS 09/92     ******
+ * 10.  Move ANY and ANY DEFINED BY type defs nested in SET/SEQ/CHOICE/SET OF
+ * /SEQ OF to a separate definition - this should make fixing the
+ * produced code simpler.
+ *
+ * Mike Sample
+ * 91/12/12
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/normalize.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: normalize.c,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:50  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:40  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:40:56  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:23  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "oid.h"
+#include "lib-types.h"
+#include "snacc-util.h"
+#include "normalize.h"
+
+#define LIST_ELMT_SUFFIX "ListElmt"
+#define CHOICE_SUFFIX "Choice"
+#define SET_SUFFIX "Set"
+#define SEQ_SUFFIX "Seq"
+#define SETOF_SUFFIX "SetOf"
+#define SEQOF_SUFFIX "SeqOf"
+#define INT_SUFFIX "Int"
+#define ENUM_SUFFIX "Enum"
+#define BITS_SUFFIX "Bits"
+#define ANY_SUFFIX "Any"
+
+long int oidRecursionCountG = 0;
+
+void NormalizeTypeDef PROTO ((Module *m, TypeDef *td));
+
+void NormalizeType PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e, Type *t));
+
+void NormalizeElmtTypes PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e));
+
+void NormalizeBasicType PROTO ((Module  *m, TypeDef *td, Type *parent, NamedTypeList *e, Type *type, BasicType *bt));
+
+TypeDef *AddListElmtTypeDef PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt));
+
+TypeDef *AddConsTypeDef PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, char *suffix));
+
+void NormalizeValueDef PROTO ((Module *m, ValueDef *vd));
+
+int  FlattenLinkedOid PROTO ((OID *o, char *asn1FileName, AsnInt lineNo, int quiet));
+
+/*
+ * looks through the given module and performs the operations
+ * mentioned above
+ */
+void
+NormalizeModule PARAMS ((m),
+    Module *m)
+{
+    TypeDef *td;
+    ValueDef *vd;
+
+    /*
+     * go through each type in typeList
+     */
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        NormalizeTypeDef (m, td);
+    }
+
+    /*
+     *  go through each value for types?
+     */
+    FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+    {
+        NormalizeValueDef (m, vd);
+    }
+
+}   /* NormalizeModule */
+
+
+void
+NormalizeTypeDef PARAMS ((m, td),
+    Module *m _AND_
+    TypeDef *td)
+{
+    if (td == NULL)
+        return;
+
+    NormalizeType (m, td, NULL, NULL, td->type);
+
+} /* NormalizeTypeDef */
+
+
+void
+NormalizeType PARAMS ((m, td, parent, e, t),
+ Module *m _AND_
+ TypeDef *td _AND_
+ Type *parent _AND_
+ NamedTypeList *e _AND_
+ Type *t)
+{
+    enum BasicTypeChoiceId typeId;
+    Type *tmpType;
+    Tag *lastTag;
+
+    if (t == NULL)
+        return;
+
+    NormalizeBasicType (m, td, parent, e,  t, t->basicType);
+
+    /*
+     * make type refs implicit if IMPLICIT-TAGS specified and
+     * ref'd type is OK for implicit tagging.
+     * Tag removal work is done in parsing (yacc).
+     */
+    if ((m->tagDefault == IMPLICIT_TAGS))
+    {
+        tmpType = ParanoidGetType (t);
+        typeId = tmpType->basicType->choiceId;
+
+        if ((t->tags != NULL) && (!LIST_EMPTY (t->tags)))
+            lastTag = (Tag*)LAST_LIST_ELMT (t->tags);
+        else
+            lastTag = NULL;
+
+        /*
+         * only mark as implicit if
+         *  1. This type has a tag in it's taglist
+         *  2. This type is a reference to another type
+         *  3. the referenced type is not an untagged CHOICE, ANY or
+         *     ANY DEFINED BY (just need to check that it has
+         *     tags since all other types have tags)
+         */
+        if (((lastTag != NULL) && !(lastTag->explicit)) &&
+            ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+             (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) &&
+            (CountTags (t->basicType->a.localTypeRef->link->type) != 0))
+        {
+            t->implicit = TRUE;
+        }
+    }
+
+} /* NormalizeType */
+
+
+
+void
+NormalizeElmtTypes PARAMS ((m, td, parent, e),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *e)
+{
+    NamedType *nt;
+
+    FOR_EACH_LIST_ELMT (nt, e)
+    {
+        NormalizeType (m, td, parent, e, nt->type);
+    }
+}  /* NormalizeElmtTypes */
+
+
+/*
+ * this is where most of the action happens
+ * assumes that "e"'s curr ptr is namedtype that holds "type"
+ */
+void
+NormalizeBasicType PARAMS ((m, td, parent, e, type, bt),
+    Module  *m _AND_
+    TypeDef *td _AND_
+    Type *parent _AND_
+    NamedTypeList *e _AND_
+    Type *type _AND_
+    BasicType *bt)
+{
+    int i, numElmtsAdded;
+    NamedType *newElmt;
+    NamedType **newElmtHndl;
+    NamedType *nt;
+    NamedTypeList *elmts;
+    NamedType *origNext;
+    Type *compType;
+    Type *parentType;
+    TypeDef *newDef;
+    BasicType *tmpBasicType;
+    TagList *tags;
+    Tag *tag;
+    Tag **tagHndl;
+
+    if (bt == NULL)
+        return;
+
+    switch (bt->choiceId)
+    {
+
+        case BASICTYPE_COMPONENTSOF:
+            /*
+             * copy elmts of COMPONENTS OF type into this type
+             */
+            if (parent == NULL)
+            {
+                PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - COMPONENTS OF must be a SET or SEQUENCE element\n");
+                m->status = MOD_ERROR;
+                return;
+            }
+
+        compType = ParanoidGetType (bt->a.componentsOf);
+        parentType = ParanoidGetType (parent);
+
+        /* COMPONENTS OF must be nested in a SET or SEQUENCE type */
+        if ((parentType->basicType->choiceId != BASICTYPE_SET) &&
+            (parentType->basicType->choiceId != BASICTYPE_SEQUENCE))
+        {
+            PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+            fprintf (stderr,"ERROR - COMPONENTS OF must be a SET or SEQUENCE element\n");
+            m->status = MOD_ERROR;
+            return;
+        }
+
+            /* COMPONENTS OF in a SET must ref a SET and vice versa for SEQ */
+            if (((parentType->basicType->choiceId == BASICTYPE_SET) &&
+                 (compType->basicType->choiceId != BASICTYPE_SET)) ||
+                ((parentType->basicType->choiceId == BASICTYPE_SEQUENCE) &&
+                (compType->basicType->choiceId != BASICTYPE_SEQUENCE)))
+            {
+                PrintErrLoc (m->asn1SrcFileName, type->lineNo);
+                fprintf (stderr,"ERROR - COMPONENTS OF in a SET must reference a SET type and  COMPONENTS OF in SEQUENCE must reference a SEQUENCE type\n");
+                type->basicType = compType->basicType;
+                m->status = MOD_ERROR;
+                return;
+            }
+
+            /*
+             * replace "COMPONENTS OF" with elmts from ref'd set
+             */
+            elmts = compType->basicType->a.set;
+
+            if (elmts == NULL)
+                break;
+
+            /*
+             * add new list elmts that  point to elmts
+             * of type ref'd by COMPONENTS OF
+             */
+            FOR_EACH_LIST_ELMT (nt, elmts)
+            {
+                newElmtHndl = (NamedType**)AsnListAdd (e);
+                *newElmtHndl = nt;
+            }
+
+            /*
+             * Set e list's curr  ptr to first of of the
+             * newly added components.
+             * Do this so NormalizeElmtTypes will do the
+             * newly added ones as well
+             */
+            numElmtsAdded = AsnListCount (elmts);
+            for (i = 0; i < numElmtsAdded; i++)
+                AsnListPrev (e);
+
+            /* remove the componets of ref since elmts copied in */
+            AsnListRemove (e);
+
+            break;
+
+
+        case BASICTYPE_SELECTION:
+            /*
+             * first normalize the CHOICE that is selected from
+             * - this will be done twice to the CHOICE but nothing
+             * bad should happen.  The main reason for 'normalizing'
+             * the CHOICE first is to strip tags from the choice elmts
+             * if IMPLICIT-TAGS is set.
+             * NOTE: this call assumes that import/local type refs
+             * both use the 'TypeRef' struct and that a selection references
+             * a CHOICE by name (not definition)
+             */
+            NormalizeType (m, type->basicType->a.selection->typeRef->basicType->a.localTypeRef->link, NULL, NULL, type->basicType->a.selection->typeRef->basicType->a.localTypeRef->link->type);
+
+            /*
+             * use SELECTION field name if this is an elmt type with no
+             * field name.
+             */
+            if ((e != NULL) &&
+                (((NamedType*) e->curr->data)->fieldName == NULL))
+                ((NamedType*) e->curr->data)->fieldName =
+                    type->basicType->a.selection->link->fieldName;
+
+            /*
+             * replace SELECTION type with refd type.
+             * must append the named CHOICE field's tags to
+             * any existing tags on this SELECTION type.
+             */
+            tmpBasicType =  type->basicType->a.selection->link->type->basicType;
+            tags = type->basicType->a.selection->link->type->tags;
+
+
+            FOR_EACH_LIST_ELMT (tag, tags)
+            {
+                if (!(((m->tagDefault == IMPLICIT_TAGS) || (type->implicit)) &&
+                    (tag == (Tag*)FIRST_LIST_ELMT (tags))))
+                {
+                    tagHndl = (Tag**) AsnListAppend (type->tags);
+                    *tagHndl = tag;
+                }
+                type->implicit = FALSE;
+            }
+
+            if (type->basicType->a.selection->link->type->implicit)
+                type->implicit = TRUE;
+
+            Free (type->basicType->a.selection->fieldName);
+            Free (type->basicType->a.selection->typeRef->basicType);
+            Free (type->basicType->a.selection->typeRef);
+            type->basicType = tmpBasicType;
+
+        break;
+
+
+
+        case BASICTYPE_SEQUENCEOF:
+        case BASICTYPE_SETOF:
+            /* convert def inside other type into a ref */
+            if (td->type != type)
+            {
+                if (bt->choiceId == BASICTYPE_SETOF)
+                    newDef = AddConsTypeDef (m, td, type, bt, SETOF_SUFFIX);
+                else
+                    newDef = AddConsTypeDef (m, td, type, bt, SEQOF_SUFFIX);
+
+                NormalizeType (m, newDef, NULL, NULL, newDef->type);
+            }
+            else
+                NormalizeType (m, td, type, NULL, type->basicType->a.setOf);
+            break;
+
+            /*  NOT NEEDED ANY MORE
+             * convert typdef after SET OF/SEQ OF to type REFS
+            switch (bt->a.setOf->basicType->choiceId)
+            {
+                case BASICTYPE_SEQUENCE:
+                case BASICTYPE_SET:
+                case BASICTYPE_CHOICE:
+                case BASICTYPE_SEQUENCEOF:
+                case BASICTYPE_SETOF:
+                case BASICTYPE_COMPONENTSOF:
+                    newDef = AddListElmtTypeDef (m, td, type, bt);
+                    NormalizeType (m, newDef, NULL, NULL, newDef->type);
+                break;
+
+                default:
+                    NormalizeType (m, td, NULL, NULL, bt->a.setOf);
+                break;
+            }
+            */
+            break;
+
+
+        case BASICTYPE_CHOICE:
+            /*
+             * change CHOICE defs embedded in other types
+             * into type refs
+             */
+            if (td->type != type)
+            {
+                newDef = AddConsTypeDef (m, td, type, bt, CHOICE_SUFFIX);
+                NormalizeType (m, newDef, NULL, NULL, newDef->type);
+            }
+            else
+                NormalizeElmtTypes (m, td, type, bt->a.set);
+
+            break;
+
+
+        case BASICTYPE_SEQUENCE:
+            /*
+             * change SEQ defs embedded in other types
+             * into type refs
+             */
+            if (td->type != type)
+            {
+                newDef = AddConsTypeDef (m, td, type, bt, SEQ_SUFFIX);
+                NormalizeType (m, newDef, NULL, NULL, newDef->type);
+            }
+            else
+                NormalizeElmtTypes (m, td, type, bt->a.sequence);
+            break;
+
+
+        case BASICTYPE_SET:
+            /*
+             * change SET defs embedded in other types
+             * into type refs
+             */
+            if (td->type != type)
+            {
+                newDef = AddConsTypeDef (m, td, type, bt, SET_SUFFIX);
+                NormalizeType (m, newDef, NULL, NULL, newDef->type);
+            }
+            else
+                NormalizeElmtTypes (m, td, type, bt->a.set);
+            break;
+
+
+        case BASICTYPE_INTEGER:
+            /* if they have named elements convert this def into a ref */
+            if ((td->type != type) && (bt->a.integer !=  NULL) &&
+                (!LIST_EMPTY (bt->a.integer)))
+            {
+                newDef = AddConsTypeDef (m, td, type, bt, INT_SUFFIX);
+            }
+            break;
+
+        case BASICTYPE_ENUMERATED:
+            /* if they have named elements convert this def into a ref */
+            if ((td->type != type) && (bt->a.enumerated !=  NULL) &&
+                (!LIST_EMPTY (bt->a.enumerated)))
+            {
+                newDef = AddConsTypeDef (m, td, type, bt, ENUM_SUFFIX);
+            }
+            break;
+
+        case BASICTYPE_BITSTRING:
+            /* if they have named elements convert this def into a ref */
+            if ((td->type != type) && (bt->a.bitString !=  NULL) &&
+                (!LIST_EMPTY (bt->a.bitString)))
+            {
+                newDef = AddConsTypeDef (m, td, type, bt, BITS_SUFFIX);
+            }
+            break;
+
+        case BASICTYPE_ANY:
+        case BASICTYPE_ANYDEFINEDBY:
+            m->hasAnys = TRUE;
+            /*  NO LONGER DONE
+             * change ANY defs embedded in other types
+             * into type refs
+
+            if (td->type != type)
+                newDef = AddConsTypeDef (m, td, type, bt, ANY_SUFFIX);
+             */
+            break;
+
+        default:
+          /* the rest are not processed */
+        break;
+    }
+}  /* NormalizeBasicType */
+
+
+
+
+/*
+ * given a set of/seq of type t within typedef td, change the
+ * set of /seq of elmt type def  into a type ref and
+ * add a type def for the elmt at the top level.
+ */
+TypeDef*
+AddListElmtTypeDef PARAMS ((m, td, t, bt),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt)
+{
+    TypeDef *newDef;
+    TypeDef **typeDefHndl;
+    int end;
+    int digit;
+
+    /*
+     * make new  type def
+     */
+    newDef = (TypeDef*)Malloc (sizeof (TypeDef));
+    newDef->exported = FALSE;
+    newDef->type = bt->a.setOf;
+    /*
+     * make name for new type
+     * Foo ::= SET OF SEQUENCE {...}
+     *  -->
+     * FooListElmt ::=  SEQUENCE {...}
+     * Foo ::=  SET OF FooListElmt
+     */
+    newDef->definedName =
+        Malloc (strlen (td->definedName) +
+               strlen (LIST_ELMT_SUFFIX) + 4);
+
+    strcpy (newDef->definedName, td->definedName);
+    strcat (newDef->definedName, LIST_ELMT_SUFFIX);
+    end = strlen (newDef->definedName);
+    digit  = 1;
+    while (LookupType (m->typeDefs, newDef->definedName) != NULL)
+    {
+        newDef->definedName[end] = '\0';
+        AppendDigit (newDef->definedName, digit++);
+    }
+
+    /*
+     * now put new type at head of list
+     */
+    typeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs);
+    *typeDefHndl = newDef;
+
+
+
+    /*
+     * replace SET OF/SEQ OF body with type ref
+     */
+    bt->a.setOf = (Type*)Malloc (sizeof (Type));
+    bt->a.setOf->optional = FALSE;
+    bt->a.setOf->implicit = FALSE;
+    bt->a.setOf->lineNo = t->lineNo;
+    bt->a.setOf->basicType = (BasicType*)Malloc (sizeof (BasicType));
+    bt->a.setOf->basicType->choiceId = BASICTYPE_LOCALTYPEREF;
+    bt->a.setOf->basicType->a.localTypeRef = (TypeRef*)Malloc (sizeof (TypeRef));
+    bt->a.setOf->basicType->a.localTypeRef->link = newDef;
+    bt->a.setOf->basicType->a.localTypeRef->typeName =
+        newDef->definedName;
+    bt->a.setOf->basicType->a.localTypeRef->moduleName = NULL;
+
+
+    return newDef;
+
+} /* AddListElmtTypeDefs */
+
+
+
+/*
+ * given a CHOICE/SET/SEQ/etc type t within typedef td, make t into a ref
+ * to a new  top level typdef of the CHOICE/SET/SEQ
+ */
+TypeDef*
+AddConsTypeDef PARAMS ((m, td, t, bt, suffix),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    char *suffix)
+{
+    TypeDef *newDef;
+    TypeDef **typeDefHndl;
+    Tag **tmpPtr;
+    Tag  *lastTag;
+    int end;
+    int digit;
+
+    /*
+     * make new  type def
+     */
+    newDef = (TypeDef*)Malloc (sizeof (TypeDef));
+    newDef->exported = FALSE;
+    newDef->recursive = FALSE;
+    newDef->localRefCount = 1;
+    newDef->type = (Type*)Malloc (sizeof (Type));
+    newDef->type->optional = FALSE;
+    newDef->type->lineNo = t->lineNo;
+    newDef->type->basicType = bt;
+
+    /*
+     * make name for new choice/SET/SEQ
+     * Foo ::= SEQUENCE { .., bar CHOICE { ...}, ..}
+     *  -->
+     * FooChoice ::=  CHOICE { ...}
+     * Foo ::=  SEQUENCE { .., bar FooChoice, .. }
+     */
+    newDef->definedName =
+        Malloc (strlen (td->definedName) +
+               strlen (suffix) + 4);
+
+    strcpy (newDef->definedName, td->definedName);
+    strcat (newDef->definedName, suffix);
+    end = strlen (newDef->definedName);
+    digit  = 1;
+
+    /* keep name unique */
+    while (LookupType (m->typeDefs, newDef->definedName) != NULL)
+    {
+        newDef->definedName[end] = '\0';
+        AppendDigit (newDef->definedName, digit++);
+    }
+
+    /*
+     * now put new type at head of list
+     */
+    typeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs);
+    *typeDefHndl = newDef;
+
+    /*
+     * what to do with tags? Use default universal type on
+     * newly defined type and adjust (new) reference's tags
+     * appropriately
+     *
+     *  NOTE: may be simpler just to move all the tags to the
+     *        new def.
+     */
+
+    newDef->type->tags = (TagList*)AsnListNew (sizeof (void*));
+    if (LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId))
+        != NO_TAG_CODE)
+    {
+         tmpPtr = (Tag**)AsnListAppend (newDef->type->tags);
+         *tmpPtr = (Tag*)Malloc (sizeof (Tag));
+         (*tmpPtr)->tclass = UNIV;
+         (*tmpPtr)->code = LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId));
+
+
+    /* adjust tags of new ref to new def */
+    if ((t->tags != NULL) && (!LIST_EMPTY (t->tags)))
+    {
+        lastTag = (Tag*)LAST_LIST_ELMT (t->tags);
+        if ((lastTag->tclass == UNIV) &&
+            (lastTag->code ==
+             LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId))))
+        {
+            /* zap it since same as default universal tag */
+            SET_CURR_LIST_NODE (t->tags, LAST_LIST_NODE (t->tags));
+            AsnListRemove (t->tags);
+            t->implicit = FALSE;
+        }
+        else
+        {
+            t->implicit = TRUE; /* this will probably already be true */
+        }
+    }
+
+     }
+    /*
+     * replace embeded CHOICE/SET/SEQ def with ref to newly defined type
+     */
+    t->basicType = (BasicType*)Malloc (sizeof (BasicType));
+    t->basicType->choiceId = BASICTYPE_LOCALTYPEREF;
+    t->basicType->a.localTypeRef = (TypeRef*)Malloc (sizeof (TypeRef));
+    t->basicType->a.localTypeRef->link = newDef;
+    t->basicType->a.localTypeRef->typeName =
+        newDef->definedName;
+    t->basicType->a.localTypeRef->moduleName = NULL;
+
+
+    return newDef;
+
+} /* AddConsTypeDef */
+
+
+void
+NormalizeValueDef PARAMS ((m, vd),
+    Module *m _AND_
+    ValueDef *vd)
+{
+    NormalizeValue (m, vd, vd->value, FALSE);
+}
+
+void
+NormalizeValue PARAMS ((m, vd, v, quiet),
+    Module *m _AND_
+    ValueDef *vd _AND_
+    Value *v _AND_
+    int quiet)
+{
+    AsnOid *eoid;
+    OID *o;
+    OID *tmp;
+    int eLen;
+
+    /*
+     * convert linked oids into ENC_OID's
+     */
+    if (v->basicValue->choiceId == BASICVALUE_LINKEDOID)
+    {
+        if (!FlattenLinkedOid (v->basicValue->a.linkedOid, m->asn1SrcFileName, v->lineNo, quiet))
+            return;
+        eLen = EncodedOidLen (v->basicValue->a.linkedOid);
+        eoid = MT (AsnOid);
+        eoid->octetLen = eLen;
+        eoid->octs = (char*)Malloc (eLen);
+        BuildEncodedOid (v->basicValue->a.linkedOid, eoid);
+
+        /* free linked  oid */
+        for (o = v->basicValue->a.linkedOid; o != NULL; )
+        {
+            tmp = o->next;
+            Free (o);
+            o = tmp;
+        }
+        v->basicValue->choiceId = BASICVALUE_OID;
+        v->basicValue->a.oid = eoid;
+    }
+}
+
+
+/*
+ * replaces value refs with the value's number if poss
+ * returns TRUE if successfully done.
+ * returns FALSE if a value ref could not be traced
+ *  (false should not happen if the value link succeeded)
+ * "quiet" parameter allows err msg to be turned off
+ *  which prevents cascading errors by other oid's that
+ *  reference a bad oid.
+ */
+int
+FlattenLinkedOid PARAMS ((o, asn1FileName, lineNo, quiet),
+    OID *o _AND_
+    char *asn1FileName _AND_
+    AsnInt lineNo _AND_
+    int quiet)
+{
+    OID *firstElmt;
+    OID *refdOid;
+    OID *tmpOid;
+    OID **nextOid;
+    Value *val;
+    Value *valRef;
+
+    if (oidRecursionCountG > 100)
+    {
+        PrintErrLoc (asn1FileName, lineNo);
+        fprintf (stderr,"ERROR - recursive OBJECT IDENTIFIER value.\n");
+        return FALSE;
+    }
+
+    firstElmt = o;
+
+    for (; o != NULL; o = o->next)
+    {
+        valRef = o->valueRef;
+        if ((valRef == NULL) || (o->arcNum != NULL_OID_ARCNUM))
+            continue; /* no linking nec for this one */
+
+        val = GetValue (o->valueRef);
+
+        /*
+         * if the very first component is an oid val ref
+         * then insert that value
+         */
+        if ((o == firstElmt) && (val->basicValue->choiceId == BASICVALUE_OID))
+        {
+            UnbuildEncodedOid (val->basicValue->a.oid, &refdOid);
+            for (tmpOid = refdOid; tmpOid->next != NULL; tmpOid = tmpOid->next)
+		;
+            tmpOid->next = o->next;
+            memcpy (firstElmt, refdOid, sizeof (OID));
+            Free (refdOid); /* free first component of OID since copied */
+        }
+
+        else if ((o == firstElmt) && (val->basicValue->choiceId == BASICVALUE_LINKEDOID))
+        {
+            oidRecursionCountG++;
+            if (!FlattenLinkedOid (val->basicValue->a.linkedOid, asn1FileName, lineNo, TRUE))
+            {
+                oidRecursionCountG--;
+                return FALSE;
+            }
+            oidRecursionCountG--;
+
+            nextOid = &refdOid;
+            for (tmpOid = val->basicValue->a.linkedOid;
+                tmpOid != NULL; tmpOid = tmpOid->next)
+            {
+                *nextOid = (OID*)Malloc (sizeof (OID));
+                (*nextOid)->arcNum = tmpOid->arcNum;
+                nextOid = &(*nextOid)->next;
+            }
+            (*nextOid) = o->next;
+            memcpy (firstElmt, refdOid, sizeof (OID));
+            Free (refdOid); /* since copied into firstElmt */
+        }
+
+        else if ((val->basicValue->choiceId == BASICVALUE_INTEGER))
+        {
+            o->arcNum = val->basicValue->a.integer;
+            if ((o->arcNum < 0) && !quiet)
+            {
+                PrintErrLoc (asn1FileName, lineNo);
+                fprintf (stderr,"ERROR - OBJECT IDENTIFIER arc values cannot be negative.\n");
+            }
+        }
+        else /* bad arc value type */
+        {
+            if (!quiet)
+            {
+                PrintErrLoc (asn1FileName, lineNo);
+                fprintf (stderr,"ERROR - type mismatch for an arc value. Values ref'd from an OBJECT IDENTIFIER value must be either an OBJECT IDENTIFIER (first oid elmt only) or INTEGER value (this may be reported twice!)\n");
+            }
+            return FALSE;
+        }
+
+        /* free mem assoc with value ref */
+        Free (valRef->basicValue->a.localValueRef->valueName);
+        Free (valRef->basicValue->a.localValueRef);
+        Free (valRef->basicValue);
+        Free (valRef);
+        o->valueRef = NULL;
+    }
+    return TRUE;
+} /* FlattenLinkedOid */
diff --git a/SecuritySNACCRuntime/compiler/core/normalize.h b/SecuritySNACCRuntime/compiler/core/normalize.h
new file mode 100644
index 00000000..d05deb4d
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/normalize.h
@@ -0,0 +1,30 @@
+/*
+ * compiler/core/normalize.h
+ *
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/normalize.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: normalize.h,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:50  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1994/10/08 03:48:50  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:25  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+void NormalizeModule PROTO ((Module *m));
+void NormalizeValue PROTO ((Module *m, ValueDef *vd, Value *v, int quiet));
diff --git a/SecuritySNACCRuntime/compiler/core/oid.c b/SecuritySNACCRuntime/compiler/core/oid.c
new file mode 100644
index 00000000..bdeb45ca
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/oid.c
@@ -0,0 +1,270 @@
+/*
+ * compiler/core/oid.c - routines for:
+ *          converting an arc number list to an ENC_OID
+ *          converting an ENC_OID to an arc number list
+ *          arcName mapping routine
+ *
+ *       does not handle OID's with unresolved valueRefs instead of arcNums
+ *
+ *  MS 91
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/oid.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: oid.c,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:51  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:41  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:41:33  rj
+ * snacc_config.h removed; oid.h includet.
+ *
+ * Revision 1.1  1994/08/28  09:49:26  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h> /* for FILE * */
+
+#include "asn-incl.h"
+#include "oid.h"
+
+typedef struct ArcNameMapElmt
+{
+    char *arcName;
+    int   arcNum;
+} ArcNameMapElmt;
+
+
+/*
+ * these are the CCITT and ISO pre-defined arc names for the
+ * OBJECT IDENTIFIER tree.
+ * Ref: CCITT X.208 1988 - Annexes B C and D
+ *
+ * NOTE: the last entry must have a NULL string and a
+ *       -1 arcnumber to indicate the end of the array.
+ */
+ArcNameMapElmt oidArcNameMapG[] =
+{
+    "ccitt", 0,
+    "iso", 1,
+    "joint-iso-ccitt", 2,
+    "standard", 0,
+    "registration-authority", 1,
+    "member-body", 2,
+    "identified-organization", 3,
+    "recommendation", 0,
+    "question", 1,
+    "administration", 2,
+    "network-operator", 3,
+    NULL,-1
+};
+
+
+/*
+ * returns the arcnum (>0) of the given name if it
+ * is a defined oid arc name like "iso" or "ccitt"
+ * returns -1 if the name was  not found
+ *
+ * name must be null terminated.
+ */
+int
+OidArcNameToNum PARAMS ((name),
+    char *name)
+{
+    int i;
+    for (i= 0; oidArcNameMapG[i].arcName != NULL; i++)
+    {
+        if (strcmp (name, oidArcNameMapG[i].arcName) == 0)
+            return oidArcNameMapG[i].arcNum;
+    }
+    return -1;
+} /* OidArcNameToNum */
+
+
+
+/*
+ * Takes and OBJECT IDENTIFER in the linked format
+ * (produced by parser) and returns the number of octets
+ * that are needed to hold the encoded version of that
+ * OBJECT IDENTIFIER.
+ */
+unsigned long int
+EncodedOidLen PARAMS ((oid),
+    OID *oid)
+{
+    unsigned long totalLen;
+    unsigned long headArcNum;
+    unsigned long tmpArcNum;
+    OID *tmpOid;
+
+    /*
+     * oid must have at least 2 elmts
+     */
+    if (oid->next == NULL)
+       return 0;
+
+    headArcNum = (oid->arcNum * 40) + oid->next->arcNum;
+
+    /*
+     * figure out total encoded length of oid
+     */
+    tmpArcNum = headArcNum;
+    for (totalLen = 1; (tmpArcNum >>= 7) != 0; totalLen++)
+	;
+    for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next)
+    {
+        totalLen++;
+        tmpArcNum = tmpOid->arcNum;
+        for (; (tmpArcNum >>= 7) != 0; totalLen++)
+	    ;
+    }
+
+    return totalLen;
+
+}  /* EncodedOidLen */
+
+
+/*
+ * Given an oid arc number list and a pre-allocated ENC_OID
+ * (use EncodedOidLen to figure out byte length needed)
+ * fills the ENC_OID with a BER encoded version
+ * of the oid.
+ */
+void
+BuildEncodedOid PARAMS ((oid, result),
+    OID *oid _AND_
+    AsnOid *result)
+{
+    unsigned long len;
+    unsigned long headArcNum;
+    unsigned long tmpArcNum;
+    char         *buf;
+    int           i;
+    OID          *tmpOid;
+
+    buf = result->octs;
+
+    /*
+     * oid must have at least 2 elmts
+     */
+    if (oid->next == NULL)
+       return;
+    /*
+     * munge together first two arcNum
+     * note first arcnum must be <= 2
+     * and second must be < 39 if first = 0 or 1
+     * see (X.209) for ref to this stupidity
+     */
+    headArcNum = (oid->arcNum * 40) + oid->next->arcNum;
+
+    tmpArcNum = headArcNum;
+
+    /*
+     * calc # bytes needed for head arc num
+     */
+    for (len = 0; (tmpArcNum >>= 7) != 0; len++)
+	;
+
+    /*
+     * write more signifcant bytes (if any) of head arc num
+     * with 'more' bit set
+     */
+    for (i=0; i < len; i++)
+        *(buf++) = 0x80 | (headArcNum >> ((len-i)*7));
+
+    /*
+     * write least significant byte of head arc num
+     */
+    *(buf++) = 0x7f & headArcNum;
+
+
+    /*
+     * write following arc nums, if any
+     */
+    for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next)
+    {
+        /*
+         * figure out encoded length -1 of this arcNum
+         */
+        tmpArcNum = tmpOid->arcNum;
+        for (len = 0; (tmpArcNum >>= 7) != 0; len++)
+	    ;
+
+
+        /*
+         * write more signifcant bytes (if any)
+         * with 'more' bit set
+         */
+        for (i=0; i < len; i++)
+            *(buf++) = 0x80 | (tmpOid->arcNum >> ((len-i)*7));
+
+        /*
+         * write least significant byte
+         */
+        *(buf++) = 0x7f & tmpOid->arcNum;
+    }
+
+} /* BuildEncodedOid */
+
+
+/*
+ * Given an ENC_OID, this routine converts it into a
+ * linked oid (OID).
+ */
+void
+UnbuildEncodedOid PARAMS ((eoid, result),
+    AsnOid *eoid _AND_
+    OID **result)
+{
+    OID **nextOid;
+    OID *headOid;
+    int arcNum;
+    int i;
+    int firstArcNum;
+    int secondArcNum;
+
+    for (arcNum = 0, i=0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80);i++)
+        arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+
+    arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+    i++;
+
+    firstArcNum = arcNum / 40;
+    if (firstArcNum > 2)
+        firstArcNum = 2;
+
+    secondArcNum = arcNum - (firstArcNum * 40);
+
+    headOid = (OID*)Malloc (sizeof (OID));
+    headOid->arcNum = firstArcNum;
+    headOid->next = (OID*)Malloc (sizeof (OID));
+    headOid->next->arcNum = secondArcNum;
+    nextOid = &headOid->next->next;
+
+    for ( ; i < eoid->octetLen; )
+    {
+        for (arcNum = 0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80);i++)
+            arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+
+        arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+        i++;
+        *nextOid = (OID*)Malloc (sizeof (OID));
+        (*nextOid)->arcNum = arcNum;
+        nextOid = &(*nextOid)->next;
+    }
+
+    *result = headOid;
+
+} /* UnbuildEncodedOid */
diff --git a/SecuritySNACCRuntime/compiler/core/oid.h b/SecuritySNACCRuntime/compiler/core/oid.h
new file mode 100644
index 00000000..1aeb650c
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/oid.h
@@ -0,0 +1,32 @@
+/*
+ * compiler/core/oid.h - routine for building an ENC_OID from an arc number list
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/oid.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: oid.h,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:51  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1994/10/08 03:48:51  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:27  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+int           OidArcNameToNum PROTO ((char *name));
+unsigned long EncodedOidLen PROTO ((OID *oid));
+void          BuildEncodedOid PROTO ((OID *oid, AsnOid *result));
+void          UnbuildEncodedOid PROTO ((AsnOid *eoid, OID **result));
diff --git a/SecuritySNACCRuntime/compiler/core/parse-asn1.c b/SecuritySNACCRuntime/compiler/core/parse-asn1.c
new file mode 100644
index 00000000..faf5a414
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/parse-asn1.c
@@ -0,0 +1,4619 @@
+
+/*  A Bison parser, made from core/parse-asn1.y
+ by  GNU Bison version 1.25
+  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+#define	BSTRING_SYM	258
+#define	HSTRING_SYM	259
+#define	CSTRING_SYM	260
+#define	UCASEFIRST_IDENT_SYM	261
+#define	LCASEFIRST_IDENT_SYM	262
+#define	NAMEDMACRO_SYM	263
+#define	MACRODEFBODY_SYM	264
+#define	BRACEBAL_SYM	265
+#define	NUMBER_ERANGE	266
+#define	NUMBER_SYM	267
+#define	SNACC_ATTRIBUTES	268
+#define	DOT_SYM	269
+#define	COMMA_SYM	270
+#define	LEFTBRACE_SYM	271
+#define	RIGHTBRACE_SYM	272
+#define	LEFTPAREN_SYM	273
+#define	RIGHTPAREN_SYM	274
+#define	LEFTBRACKET_SYM	275
+#define	RIGHTBRACKET_SYM	276
+#define	LESSTHAN_SYM	277
+#define	MINUS_SYM	278
+#define	GETS_SYM	279
+#define	BAR_SYM	280
+#define	TAGS_SYM	281
+#define	BOOLEAN_SYM	282
+#define	INTEGER_SYM	283
+#define	BIT_SYM	284
+#define	STRING_SYM	285
+#define	OCTET_SYM	286
+#define	NULL_SYM	287
+#define	SEQUENCE_SYM	288
+#define	OF_SYM	289
+#define	SET_SYM	290
+#define	IMPLICIT_SYM	291
+#define	CHOICE_SYM	292
+#define	ANY_SYM	293
+#define	OBJECT_IDENTIFIER_SYM	294
+#define	OPTIONAL_SYM	295
+#define	DEFAULT_SYM	296
+#define	COMPONENTS_SYM	297
+#define	UNIVERSAL_SYM	298
+#define	APPLICATION_SYM	299
+#define	PRIVATE_SYM	300
+#define	TRUE_SYM	301
+#define	FALSE_SYM	302
+#define	BEGIN_SYM	303
+#define	END_SYM	304
+#define	DEFINITIONS_SYM	305
+#define	EXPLICIT_SYM	306
+#define	ENUMERATED_SYM	307
+#define	EXPORTS_SYM	308
+#define	IMPORTS_SYM	309
+#define	REAL_SYM	310
+#define	INCLUDES_SYM	311
+#define	MIN_SYM	312
+#define	MAX_SYM	313
+#define	SIZE_SYM	314
+#define	FROM_SYM	315
+#define	WITH_SYM	316
+#define	COMPONENT_SYM	317
+#define	PRESENT_SYM	318
+#define	ABSENT_SYM	319
+#define	DEFINED_SYM	320
+#define	BY_SYM	321
+#define	PLUS_INFINITY_SYM	322
+#define	MINUS_INFINITY_SYM	323
+#define	SEMI_COLON_SYM	324
+#define	IA5STRING_SYM	325
+#define	PRINTABLESTRING_SYM	326
+#define	NUMERICSTRING_SYM	327
+#define	TELETEXSTRING_SYM	328
+#define	T61STRING_SYM	329
+#define	VIDEOTEXSTRING_SYM	330
+#define	VISIBLESTRING_SYM	331
+#define	ISO646STRING_SYM	332
+#define	GRAPHICSTRING_SYM	333
+#define	GENERALSTRING_SYM	334
+#define	GENERALIZEDTIME_SYM	335
+#define	UTCTIME_SYM	336
+#define	EXTERNAL_SYM	337
+#define	OBJECTDESCRIPTOR_SYM	338
+#define	OPERATION_SYM	339
+#define	ARGUMENT_SYM	340
+#define	RESULT_SYM	341
+#define	ERRORS_SYM	342
+#define	LINKED_SYM	343
+#define	ERROR_SYM	344
+#define	PARAMETER_SYM	345
+#define	BIND_SYM	346
+#define	BINDERROR_SYM	347
+#define	UNBIND_SYM	348
+#define	UNBINDERROR_SYM	349
+#define	ASE_SYM	350
+#define	OPERATIONS_SYM	351
+#define	CONSUMERINVOKES_SYM	352
+#define	SUPPLIERINVOKES_SYM	353
+#define	AC_SYM	354
+#define	ASES_SYM	355
+#define	REMOTE_SYM	356
+#define	INITIATOR_SYM	357
+#define	RESPONDER_SYM	358
+#define	ABSTRACTSYNTAXES_SYM	359
+#define	CONSUMER_SYM	360
+#define	EXTENSIONS_SYM	361
+#define	CHOSEN_SYM	362
+#define	EXTENSION_SYM	363
+#define	CRITICAL_SYM	364
+#define	FOR_SYM	365
+#define	DELIVERY_SYM	366
+#define	SUBMISSION_SYM	367
+#define	TRANSFER_SYM	368
+#define	EXTENSIONATTRIBUTE_SYM	369
+#define	TOKEN_SYM	370
+#define	TOKENDATA_SYM	371
+#define	SECURITYCATEGORY_SYM	372
+#define	OBJECT_SYM	373
+#define	PORTS_SYM	374
+#define	BOXC_SYM	375
+#define	BOXS_SYM	376
+#define	PORT_SYM	377
+#define	ABSTRACTOPS_SYM	378
+#define	REFINE_SYM	379
+#define	AS_SYM	380
+#define	RECURRING_SYM	381
+#define	VISIBLE_SYM	382
+#define	PAIRED_SYM	383
+#define	ABSTRACTBIND_SYM	384
+#define	ABSTRACTUNBIND_SYM	385
+#define	TO_SYM	386
+#define	ABSTRACTERROR_SYM	387
+#define	ABSTRACTOPERATION_SYM	388
+#define	ALGORITHM_SYM	389
+#define	ENCRYPTED_SYM	390
+#define	SIGNED_SYM	391
+#define	SIGNATURE_SYM	392
+#define	PROTECTED_SYM	393
+#define	OBJECTTYPE_SYM	394
+#define	SYNTAX_SYM	395
+#define	ACCESS_SYM	396
+#define	STATUS_SYM	397
+#define	DESCRIPTION_SYM	398
+#define	REFERENCE_SYM	399
+#define	INDEX_SYM	400
+#define	DEFVAL_SYM	401
+
+#line 66 "core/parse-asn1.y"
+
+
+#include "snacc.h"
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "lib-types.h"
+#include "snacc-util.h"
+#include "exports.h"
+#include "parser.h"
+#include "lex-stuff.h"
+
+/*
+ * smallErrG
+ *    used for small errors that should prevent code generation but not
+ *    prevent the later error checking passes
+ */
+int smallErrG = FALSE;
+
+/*
+ * firstTimeThroughG
+ *    used incase the asn1.lex was compiled with flex in which
+ *    case the lexical analyzer must be reset for every ASN.1 file
+ *    parsed, except the first
+ */
+static int firstTimeThroughG = TRUE;
+
+/*
+ *  modulePtrG
+ *    used to hold the parsed value.  The root of the parse tree.
+ */
+Module *modulePtrG;
+
+
+/*
+ * oidElmtValDefsG
+ *    used to hold integer values that are defined as arc numbers
+ *    the modules object identifiers.
+ * eg. FOO-MODULE { joint-iso-ccitt dod (2) foo (2) 3 2 } DEFINITIONS ::=
+ *     would put dod/2 and foo/2 in the oidElmtValDefsG list
+ * Note: only some oid's (modules name/import list module names)
+ *       are parsed by the yacc code.  The rest are parsed later
+ *       due to ambiguities that arise without type info.
+ */
+ValueDefList *oidElmtValDefsG = NULL;
+
+
+/*
+ * ApplTag
+ *   used to hold APPLICATION tags that have been defined in
+ *   a module.  This permits checking for the the error of
+ *   using the same APPLICATION tag in 1 module.  The
+ *   ApplTags list (appTagsG) is emptied for each module.
+ */
+typedef struct ApplTag
+{
+    unsigned long int lineNo;
+    unsigned long int tagCode;
+    struct ApplTag *next;
+} ApplTag;
+
+ApplTag *applTagsG  = NULL;
+
+/*
+ * Protos for ApplTag related stuff. These are defined at the
+ * end  of this file
+ */
+void PushApplTag PROTO ((unsigned long int tagCode, unsigned long int lineNo));
+void FreeApplTags();
+
+
+
+/*
+ * the following are globals to simplify disparity between
+ * productions and produced data structure
+ */
+
+/*
+ * these are used in the ValueRange subtype production
+ */
+static int      valueRangeUpperEndInclusiveG;
+static int      valueRangeLowerEndInclusiveG;
+
+/*
+ * used to set exports flag in Type/value defs
+ * exportListG holds the explicitly exported elements.
+ * see SetExports routine in export.c
+ */
+ExportElmt *exportListG = NULL;
+int         exportsParsedG;
+
+
+/*
+ * globals for the APPLICATION-CONTEXT macro productions
+ */
+static ValueList *rosAcSymmetricAsesG;
+static ValueList *rosAcResponderConsumerOfG;
+static ValueList *rosAcInitiatorConsumerOfG;
+
+/*
+ * used with MTSAS Extension macro
+ * set to NULL for the initial parse.
+ */
+static AsnBool *mtsasCriticalForSubmissionG = NULL;
+static AsnBool *mtsasCriticalForTransferG = NULL;
+static AsnBool *mtsasCriticalForDeliveryG = NULL;
+
+/*
+ * Asn PORT macro globals
+ */
+static TypeOrValueList *asnConsumerG;
+static TypeOrValueList *asnSupplierG;
+
+
+/*
+ * parseErrCountG
+ *   used to prevent too many cascade errors
+ */
+int parseErrCountG = 0;
+#define MAX_ERR 50
+#define PARSE_ERROR()\
+    parseErrCountG++;\
+    modulePtrG->status = MOD_ERROR;\
+    if (parseErrCountG > MAX_ERR)\
+    {\
+        fprintf (stderr, "Ackkkkk! too many errors - bye!\n");\
+        exit (1);\
+    }
+
+
+
+#line 212 "core/parse-asn1.y"
+typedef union
+{
+    int              intVal;
+    unsigned int     uintVal;
+    char            *charPtr;
+    Type            *typePtr;
+    NamedType       *namedTypePtr;
+    NamedTypeList   *namedTypeListPtr;
+    Value           *valuePtr;
+    NamedValue      *namedValuePtr;
+    SubtypeValue    *subtypeValuePtr;
+    Subtype         *subtypePtr;
+    ModuleId        *moduleId;
+    OID             *oidPtr;
+    OidList         *oidListPtr;
+    TypeDef         *typeDefPtr;
+    TypeDefList     *typeDefListPtr;
+    ValueDef        *valueDefPtr;
+    ValueDefList    *valueDefListPtr;
+    ExportElmt      *exportList;
+    ImportModule    *importModulePtr;
+    ImportModuleList *importModuleListPtr;
+    ImportElmt      *importElmtPtr;
+    ImportElmtList  *importElmtListPtr;
+    Tag             *tagPtr;
+    TagList         *tagListPtr;
+    Constraint      *constraintPtr;
+    ConstraintList  *constraintListPtr;
+    InnerSubtype    *innerSubtypePtr;
+    ValueList       *valueListPtr;
+    TypeOrValueList *typeOrValueListPtr;
+    TypeOrValue     *typeOrValuePtr;
+    AsnPort         *asnPortPtr;
+    AsnPortList     *asnPortListPtr;
+    AttributeList   *attrList;
+} YYSTYPE;
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define	YYFINAL		671
+#define	YYFLAG		-32768
+#define	YYNTBASE	147
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 401 ? yytranslate[x] : 334)
+
+static const short yytranslate[] = {     0,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     1,     2,     3,     4,     5,
+     6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+    16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
+    26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
+    36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
+    46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
+    56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
+    66,    67,    68,    69,    70,    71,    72,    73,    74,    75,
+    76,    77,    78,    79,    80,    81,    82,    83,    84,    85,
+    86,    87,    88,    89,    90,    91,    92,    93,    94,    95,
+    96,    97,    98,    99,   100,   101,   102,   103,   104,   105,
+   106,   107,   108,   109,   110,   111,   112,   113,   114,   115,
+   116,   117,   118,   119,   120,   121,   122,   123,   124,   125,
+   126,   127,   128,   129,   130,   131,   132,   133,   134,   135,
+   136,   137,   138,   139,   140,   141,   142,   143,   144,   145,
+   146
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = {     0,
+     0,     1,     2,    11,    14,    17,    19,    22,    24,    26,
+    30,    32,    36,    40,    42,    44,    46,    48,    53,    57,
+    61,    63,    65,    67,    70,    72,    77,    81,    83,    85,
+    87,    89,    92,    94,    96,    99,   102,   104,   106,   107,
+   114,   118,   124,   126,   128,   135,   140,   142,   144,   146,
+   148,   150,   152,   154,   156,   158,   160,   162,   164,   166,
+   168,   170,   172,   174,   176,   178,   180,   182,   185,   188,
+   190,   192,   194,   199,   201,   205,   210,   215,   217,   219,
+   222,   225,   230,   232,   235,   241,   243,   245,   249,   253,
+   256,   259,   261,   267,   269,   272,   276,   280,   285,   289,
+   293,   297,   300,   304,   310,   313,   315,   320,   324,   327,
+   331,   335,   340,   342,   344,   346,   348,   350,   352,   354,
+   359,   361,   364,   369,   374,   378,   380,   384,   386,   388,
+   390,   392,   394,   396,   398,   401,   406,   408,   411,   413,
+   416,   418,   420,   422,   424,   427,   430,   434,   438,   440,
+   442,   444,   448,   456,   458,   462,   465,   467,   470,   472,
+   474,   476,   478,   480,   482,   488,   490,   492,   494,   496,
+   501,   503,   505,   507,   509,   511,   513,   515,   516,   520,
+   522,   524,   526,   528,   530,   532,   535,   539,   542,   544,
+   546,   548,   550,   552,   554,   559,   564,   566,   568,   570,
+   572,   574,   576,   578,   580,   581,   583,   585,   587,   590,
+   592,   594,   596,   598,   600,   602,   604,   606,   608,   610,
+   612,   614,   616,   618,   620,   622,   624,   626,   628,   630,
+   632,   634,   636,   638,   640,   642,   644,   646,   648,   650,
+   652,   654,   656,   658,   660,   662,   664,   666,   668,   670,
+   672,   674,   676,   678,   680,   682,   684,   686,   688,   690,
+   693,   698,   701,   703,   706,   708,   710,   712,   717,   719,
+   724,   726,   729,   732,   734,   739,   742,   744,   747,   749,
+   752,   754,   759,   762,   764,   767,   771,   776,   781,   783,
+   788,   790,   792,   801,   806,   814,   816,   822,   824,   827,
+   834,   836,   843,   845,   850,   852,   854,   858,   865,   867,
+   869,   871,   875,   877,   879,   881,   885,   887,   889,   894,
+   896,   899,   901,   905,   907,   909,   913,   915,   917,   919,
+   921,   924,   926,   929,   931,   934,   936,   939,   942,   947,
+   949,   951,   955,   958,   960,   962,   964,   967,   969,   974,
+   976,   978,   981,   984,   989,   994,   999,  1001,  1005,  1008,
+  1010,  1013,  1015,  1019,  1023,  1025,  1029,  1031,  1035,  1037,
+  1040,  1044,  1049,  1051,  1054,  1058,  1063,  1065,  1068,  1071,
+  1075,  1078,  1081,  1084,  1087,  1099,  1101,  1103,  1106,  1107,
+  1110,  1111,  1116,  1117,  1122
+};
+
+static const short yyrhs[] = {    -1,
+     0,   151,    50,   150,   149,    24,    48,   153,    49,     0,
+    51,    26,     0,    36,    26,     0,   249,     0,   247,   152,
+     0,   236,     0,   249,     0,   154,   157,   163,     0,   249,
+     0,    53,   155,    69,     0,    53,     1,    69,     0,   249,
+     0,   156,     0,   249,     0,   162,     0,   156,    15,   147,
+   162,     0,    54,   158,    69,     0,    54,     1,    69,     0,
+   249,     0,   159,     0,   249,     0,   159,   160,     0,   160,
+     0,   161,    60,   147,   151,     0,   161,    15,   162,     0,
+   162,     0,   248,     0,   246,     0,   253,     0,   163,   164,
+     0,   164,     0,   165,     0,   165,    69,     0,     1,    69,
+     0,   168,     0,   226,     0,     0,     8,    24,    48,   147,
+   166,     9,     0,     8,    24,   167,     0,     8,    24,   247,
+    14,   167,     0,   248,     0,   253,     0,   248,    24,   250,
+   147,   171,   250,     0,   247,    14,   147,   248,     0,   169,
+     0,   248,     0,   252,     0,   172,     0,   170,     0,   203,
+     0,   174,     0,   175,     0,   181,     0,   183,     0,   185,
+     0,   189,     0,   191,     0,   192,     0,   193,     0,   196,
+     0,   197,     0,   201,     0,   202,     0,   179,     0,   180,
+     0,    31,    30,     0,   246,   171,     0,   171,     0,    27,
+     0,    28,     0,    28,    16,   176,    17,     0,   177,     0,
+   176,    15,   177,     0,   246,    18,   178,    19,     0,   246,
+    18,   228,    19,     0,    12,     0,    11,     0,    23,    12,
+     0,    23,    11,     0,    52,    16,   176,    17,     0,    55,
+     0,    29,    30,     0,    29,    30,    16,   182,    17,     0,
+   176,     0,    32,     0,    33,   147,    16,     0,   184,   186,
+    17,     0,   184,    17,     0,   187,   250,     0,   188,     0,
+   187,    15,   250,   147,   188,     0,   173,     0,   173,    40,
+     0,   173,    41,   235,     0,    42,    34,   171,     0,   246,
+    42,    34,   171,     0,    33,    34,   171,     0,    35,   147,
+    16,     0,   190,   186,    17,     0,   190,    17,     0,    35,
+    34,   171,     0,    37,   147,    16,   194,    17,     0,   195,
+   250,     0,   173,     0,   195,    15,   250,   173,     0,   246,
+    22,   171,     0,   198,   171,     0,   198,    36,   171,     0,
+   198,    51,   171,     0,    20,   200,   199,    21,     0,   245,
+     0,   228,     0,    43,     0,    44,     0,    45,     0,   249,
+     0,    38,     0,    38,    65,    66,   246,     0,    39,     0,
+   171,   204,     0,    35,   214,    34,   171,     0,    33,   214,
+    34,   171,     0,    18,   205,    19,     0,   206,     0,   205,
+    25,   206,     0,   207,     0,   208,     0,   209,     0,   215,
+     0,   214,     0,   216,     0,   227,     0,    56,   171,     0,
+   210,    14,    14,   211,     0,   212,     0,   212,    22,     0,
+   213,     0,    22,   213,     0,   227,     0,    57,     0,   227,
+     0,    58,     0,    59,   204,     0,    60,   204,     0,    61,
+    62,   217,     0,    61,    42,   218,     0,   204,     0,   219,
+     0,   220,     0,    16,   221,    17,     0,    16,    14,    14,
+    14,    15,   221,    17,     0,   222,     0,   221,    15,   222,
+     0,   246,   223,     0,   223,     0,   224,   225,     0,   204,
+     0,   249,     0,    63,     0,    64,     0,   249,     0,    40,
+     0,   246,   171,    24,   147,   227,     0,   230,     0,   228,
+     0,   229,     0,   246,     0,   247,    14,   147,   246,     0,
+   232,     0,   234,     0,   233,     0,   178,     0,   243,     0,
+   242,     0,   244,     0,     0,    16,   231,    10,     0,    46,
+     0,    47,     0,    67,     0,    68,     0,    32,     0,   227,
+     0,   246,   227,     0,    16,   237,    17,     0,   237,   238,
+     0,   238,     0,   239,     0,   240,     0,   241,     0,   245,
+     0,   246,     0,   246,    18,   239,    19,     0,   246,    18,
+   228,    19,     0,     3,     0,     4,     0,     5,     0,    12,
+     0,    11,     0,     7,     0,     6,     0,     6,     0,     0,
+   251,     0,   249,     0,    13,     0,   251,    13,     0,   254,
+     0,   261,     0,   263,     0,   267,     0,   269,     0,   274,
+     0,   289,     0,   283,     0,   294,     0,   295,     0,   296,
+     0,   297,     0,   298,     0,   303,     0,   307,     0,   316,
+     0,   318,     0,   320,     0,   321,     0,   322,     0,   323,
+     0,   326,     0,   325,     0,   324,     0,   327,     0,    84,
+     0,    89,     0,    91,     0,    93,     0,    95,     0,    99,
+     0,   108,     0,   106,     0,   114,     0,   115,     0,   116,
+     0,   117,     0,   118,     0,   122,     0,   124,     0,   129,
+     0,   130,     0,   133,     0,   132,     0,   134,     0,   135,
+     0,   136,     0,   137,     0,   138,     0,   139,     0,    84,
+   255,     0,   256,   257,   259,   260,     0,    85,   173,     0,
+   249,     0,    86,   258,     0,   249,     0,   173,     0,   249,
+     0,    87,    16,   286,    17,     0,   249,     0,    88,    16,
+   286,    17,     0,   249,     0,    89,   262,     0,    90,   173,
+     0,   249,     0,    91,   264,   265,   266,     0,    85,   173,
+     0,   249,     0,    86,   173,     0,   249,     0,    92,   173,
+     0,   249,     0,    93,   264,   265,   268,     0,    94,   173,
+     0,   249,     0,    95,   270,     0,    95,   271,   272,     0,
+    96,    16,   273,    17,     0,    97,    16,   273,    17,     0,
+   249,     0,    98,    16,   273,    17,     0,   249,     0,   285,
+     0,    99,   275,    91,   171,    93,   171,   276,   281,     0,
+   100,    16,   285,    17,     0,   101,    96,    16,   227,    17,
+   277,   278,     0,   249,     0,    96,    34,    16,   285,    17,
+     0,   249,     0,   279,   280,     0,   102,   105,    34,    16,
+   285,    17,     0,   249,     0,   103,   105,    34,    16,   285,
+    17,     0,   249,     0,   104,    16,   282,    17,     0,   249,
+     0,   236,     0,   282,    15,   236,     0,   106,   107,    60,
+    16,   284,    17,     0,   285,     0,   249,     0,   227,     0,
+   285,    15,   227,     0,   287,     0,   249,     0,   288,     0,
+   287,    15,   288,     0,   171,     0,   227,     0,   108,   173,
+   290,   291,     0,   108,     0,    41,   227,     0,   249,     0,
+   109,   110,   292,     0,   249,     0,   293,     0,   292,    15,
+   293,     0,   112,     0,   113,     0,   111,     0,   114,     0,
+   114,   171,     0,   115,     0,   115,   171,     0,   116,     0,
+   116,   171,     0,   117,     0,   117,   171,     0,   118,   299,
+     0,   119,    16,   300,    17,     0,   249,     0,   301,     0,
+   300,    15,   301,     0,   227,   302,     0,   120,     0,   121,
+     0,   249,     0,   122,   304,     0,   122,     0,   123,    16,
+   287,    17,     0,   305,     0,   306,     0,   305,   306,     0,
+   306,   305,     0,    97,    16,   287,    17,     0,    98,    16,
+   287,    17,     0,   124,   315,   125,   308,     0,   309,     0,
+   308,    15,   309,     0,   310,   311,     0,   315,     0,   315,
+   126,     0,   312,     0,   311,    15,   312,     0,   227,   302,
+   313,     0,   127,     0,   128,    61,   314,     0,   315,     0,
+   314,    15,   315,     0,   227,     0,   129,   317,     0,   129,
+   317,   171,     0,   131,    16,   300,    17,     0,   249,     0,
+   130,   319,     0,   130,   319,   171,     0,    60,    16,   300,
+    17,     0,   249,     0,   133,   255,     0,   132,   262,     0,
+   134,    90,   171,     0,   135,   171,     0,   136,   171,     0,
+   137,   171,     0,   138,   171,     0,   139,   140,   171,   141,
+   328,   142,   329,   330,   331,   332,   333,     0,   246,     0,
+   246,     0,   143,   227,     0,     0,   144,   227,     0,     0,
+   145,    16,   287,    17,     0,     0,   146,    16,   227,    17,
+     0,     0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+   461,   463,   468,   500,   502,   503,   510,   519,   521,   524,
+   526,   529,   540,   547,   550,   552,   555,   563,   572,   574,
+   579,   582,   584,   587,   592,   599,   610,   621,   634,   636,
+   637,   650,   652,   655,   657,   658,   665,   680,   693,   695,
+   734,   750,   775,   777,   784,   805,   820,   822,   832,   834,
+   835,   836,   839,   841,   842,   843,   844,   845,   846,   847,
+   848,   849,   850,   851,   852,   853,   854,   855,   861,   868,
+   875,   882,   888,   896,   902,   909,   917,   925,   933,   939,
+   950,   958,   967,   974,   980,   987,   993,  1000,  1005,  1021,
+  1035,  1049,  1055,  1072,  1074,  1079,  1093,  1099,  1110,  1126,
+  1130,  1145,  1160,  1174,  1191,  1204,  1210,  1225,  1240,  1266,
+  1307,  1316,  1334,  1340,  1348,  1350,  1351,  1352,  1356,  1361,
+  1370,  1378,  1388,  1401,  1417,  1424,  1440,  1452,  1454,  1455,
+  1456,  1457,  1458,  1461,  1469,  1478,  1493,  1499,  1506,  1512,
+  1519,  1521,  1528,  1530,  1537,  1547,  1556,  1563,  1571,  1586,
+  1588,  1591,  1600,  1610,  1616,  1623,  1629,  1633,  1642,  1644,
+  1647,  1649,  1650,  1651,  1663,  1675,  1677,  1680,  1682,  1695,
+  1710,  1712,  1713,  1714,  1720,  1728,  1736,  1744,  1745,  1761,
+  1768,  1777,  1784,  1794,  1804,  1810,  1819,  1846,  1856,  1861,
+  1863,  1884,  1888,  1896,  1901,  1920,  1941,  1945,  1949,  1953,
+  1961,  1969,  1973,  1977,  1981,  1988,  1990,  1993,  1999,  2010,
+  2012,  2013,  2014,  2015,  2016,  2017,  2018,  2019,  2020,  2021,
+  2022,  2023,  2024,  2025,  2026,  2027,  2028,  2029,  2030,  2031,
+  2032,  2033,  2034,  2035,  2038,  2040,  2041,  2042,  2043,  2044,
+  2045,  2046,  2047,  2048,  2049,  2050,  2051,  2052,  2053,  2054,
+  2055,  2056,  2057,  2058,  2059,  2060,  2061,  2062,  2063,  2071,
+  2075,  2091,  2093,  2096,  2098,  2102,  2104,  2108,  2113,  2118,
+  2123,  2134,  2148,  2150,  2158,  2172,  2174,  2178,  2180,  2184,
+  2186,  2194,  2209,  2211,  2219,  2228,  2240,  2248,  2253,  2257,
+  2262,  2266,  2275,  2299,  2307,  2313,  2322,  2327,  2330,  2334,
+  2339,  2342,  2347,  2350,  2355,  2359,  2365,  2377,  2391,  2393,
+  2396,  2402,  2409,  2411,  2414,  2420,  2427,  2434,  2446,  2464,
+  2476,  2478,  2481,  2483,  2487,  2489,  2492,  2498,  2503,  2516,
+  2526,  2541,  2550,  2564,  2574,  2589,  2599,  2620,  2630,  2635,
+  2638,  2644,  2651,  2660,  2666,  2671,  2683,  2694,  2702,  2707,
+  2713,  2719,  2725,  2733,  2740,  2756,  2763,  2765,  2768,  2772,
+  2774,  2777,  2779,  2782,  2789,  2791,  2795,  2797,  2800,  2813,
+  2823,  2835,  2840,  2849,  2860,  2873,  2878,  2886,  2898,  2911,
+  2922,  2934,  2945,  2959,  2969,  2995,  3017,  3038,  3040,  3043,
+  3045,  3048,  3053,  3056,  3061
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = {   "$","error","$undefined.","BSTRING_SYM",
+"HSTRING_SYM","CSTRING_SYM","UCASEFIRST_IDENT_SYM","LCASEFIRST_IDENT_SYM","NAMEDMACRO_SYM",
+"MACRODEFBODY_SYM","BRACEBAL_SYM","NUMBER_ERANGE","NUMBER_SYM","SNACC_ATTRIBUTES",
+"DOT_SYM","COMMA_SYM","LEFTBRACE_SYM","RIGHTBRACE_SYM","LEFTPAREN_SYM","RIGHTPAREN_SYM",
+"LEFTBRACKET_SYM","RIGHTBRACKET_SYM","LESSTHAN_SYM","MINUS_SYM","GETS_SYM","BAR_SYM",
+"TAGS_SYM","BOOLEAN_SYM","INTEGER_SYM","BIT_SYM","STRING_SYM","OCTET_SYM","NULL_SYM",
+"SEQUENCE_SYM","OF_SYM","SET_SYM","IMPLICIT_SYM","CHOICE_SYM","ANY_SYM","OBJECT_IDENTIFIER_SYM",
+"OPTIONAL_SYM","DEFAULT_SYM","COMPONENTS_SYM","UNIVERSAL_SYM","APPLICATION_SYM",
+"PRIVATE_SYM","TRUE_SYM","FALSE_SYM","BEGIN_SYM","END_SYM","DEFINITIONS_SYM",
+"EXPLICIT_SYM","ENUMERATED_SYM","EXPORTS_SYM","IMPORTS_SYM","REAL_SYM","INCLUDES_SYM",
+"MIN_SYM","MAX_SYM","SIZE_SYM","FROM_SYM","WITH_SYM","COMPONENT_SYM","PRESENT_SYM",
+"ABSENT_SYM","DEFINED_SYM","BY_SYM","PLUS_INFINITY_SYM","MINUS_INFINITY_SYM",
+"SEMI_COLON_SYM","IA5STRING_SYM","PRINTABLESTRING_SYM","NUMERICSTRING_SYM","TELETEXSTRING_SYM",
+"T61STRING_SYM","VIDEOTEXSTRING_SYM","VISIBLESTRING_SYM","ISO646STRING_SYM",
+"GRAPHICSTRING_SYM","GENERALSTRING_SYM","GENERALIZEDTIME_SYM","UTCTIME_SYM",
+"EXTERNAL_SYM","OBJECTDESCRIPTOR_SYM","OPERATION_SYM","ARGUMENT_SYM","RESULT_SYM",
+"ERRORS_SYM","LINKED_SYM","ERROR_SYM","PARAMETER_SYM","BIND_SYM","BINDERROR_SYM",
+"UNBIND_SYM","UNBINDERROR_SYM","ASE_SYM","OPERATIONS_SYM","CONSUMERINVOKES_SYM",
+"SUPPLIERINVOKES_SYM","AC_SYM","ASES_SYM","REMOTE_SYM","INITIATOR_SYM","RESPONDER_SYM",
+"ABSTRACTSYNTAXES_SYM","CONSUMER_SYM","EXTENSIONS_SYM","CHOSEN_SYM","EXTENSION_SYM",
+"CRITICAL_SYM","FOR_SYM","DELIVERY_SYM","SUBMISSION_SYM","TRANSFER_SYM","EXTENSIONATTRIBUTE_SYM",
+"TOKEN_SYM","TOKENDATA_SYM","SECURITYCATEGORY_SYM","OBJECT_SYM","PORTS_SYM",
+"BOXC_SYM","BOXS_SYM","PORT_SYM","ABSTRACTOPS_SYM","REFINE_SYM","AS_SYM","RECURRING_SYM",
+"VISIBLE_SYM","PAIRED_SYM","ABSTRACTBIND_SYM","ABSTRACTUNBIND_SYM","TO_SYM",
+"ABSTRACTERROR_SYM","ABSTRACTOPERATION_SYM","ALGORITHM_SYM","ENCRYPTED_SYM",
+"SIGNED_SYM","SIGNATURE_SYM","PROTECTED_SYM","OBJECTTYPE_SYM","SYNTAX_SYM","ACCESS_SYM",
+"STATUS_SYM","DESCRIPTION_SYM","REFERENCE_SYM","INDEX_SYM","DEFVAL_SYM","LineNo",
+"ModuleDefinition","@1","TagDefault","ModuleIdentifier","AssignedIdentifier",
+"ModuleBody","Exports","SymbolsExported","ExportSymbolList","Imports","SymbolsImported",
+"SymbolsFromModuleList","SymbolsFromModule","SymbolList","Symbol","AssignmentList",
+"AssignmentOrError","Assignment","@2","MacroReference","TypeAssignment","ExternalTypeReference",
+"DefinedType","Type","BuiltinType","NamedType","BooleanType","IntegerType","NamedNumberList",
+"NamedNumber","SignedNumber","EnumeratedType","RealType","BitStringType","NamedBitList",
+"NullType","SequenceOpening","SequenceType","ElementTypes","ElementTypeList",
+"ElementType","SequenceOfType","SetOpening","SetType","SetOfType","ChoiceType",
+"AlternativeTypes","AlternativeTypeList","SelectionType","TaggedType","Tag",
+"ClassNumber","Class","AnyType","ObjectIdentifierType","Subtype","SubtypeSpec",
+"SubtypeValueSetList","SubtypeValueSet","SingleValue","ContainedSubtype","ValueRange",
+"LowerEndPoint","UpperEndPoint","LowerEndValue","UpperEndValue","SizeConstraint",
+"PermittedAlphabet","InnerTypeConstraints","SingleTypeConstraint","MultipleTypeConstraints",
+"FullSpecification","PartialSpecification","TypeConstraints","NamedConstraint",
+"Constraint","ValueConstraint","PresenceConstraint","ValueAssignment","Value",
+"DefinedValue","ExternalValueReference","BuiltinValue","@3","BooleanValue","SpecialRealValue",
+"NullValue","NamedValue","ObjectIdentifierValue","ObjIdComponentList","ObjIdComponent",
+"NumberForm","NameForm","NameAndNumberForm","BinaryString","HexString","CharString",
+"number","identifier","modulereference","typereference","empty","SnaccAttributes",
+"SnaccAttributeCommentList","DefinedMacroType","DefinedMacroName","RosOperationMacroType",
+"RosOperationMacroBody","RosOpArgument","RosOpResult","RosOpResultType","RosOpErrors",
+"RosOpLinkedOps","RosErrorMacroType","RosErrParameter","RosBindMacroType","RosBindArgument",
+"RosBindResult","RosBindError","RosUnbindMacroType","RosUnbindError","RosAseMacroType",
+"RosAseSymmetricAse","RosAseConsumerInvokes","RosAseSupplierInvokes","RosAseOperationList",
+"RosAcMacroType","RosAcNonRoElements","RosAcRoElements","RosAcSymmetricAses",
+"RosAcAsymmetricAses","RosAcInitiatorConsumerOf","RosAcResponderConsumerOf",
+"RosAcAbstractSyntaxes","OidList","MtsasExtensionsMacroType","PossiblyEmptyValueList",
+"ValueList","PossiblyEmptyTypeOrValueList","TypeOrValueList","TypeOrValue","MtsasExtensionMacroType",
+"MtsasExtDefaultVal","MtsasExtCritical","MtsasExtCriticalityList","MtsasExtCriticality",
+"MtsasExtensionAttributeMacroType","MtsasTokenMacroType","MtsasTokenDataMacroType",
+"MtsasSecurityCategoryMacroType","AsnObjectMacroType","AsnPorts","AsnPortList",
+"AsnPort","AsnPortType","AsnPortMacroType","AsnOperations","AsnConsumer","AsnSupplier",
+"AsnRefineMacroType","AsnComponentList","AsnComponent","AsnObjectSpec","AsnPortSpecList",
+"AsnPortSpec","AsnPortStatus","AsnObjectList","AsnObject","AsnAbstractBindMacroType",
+"AsnAbstractBindPorts","AsnAbstractUnbindMacroType","AsnAbstractUnbindPorts",
+"AsnAbstractOperationMacroType","AsnAbstractErrorMacroType","AfAlgorithmMacroType",
+"AfEncryptedMacroType","AfSignedMacroType","AfSignatureMacroType","AfProtectedMacroType",
+"SnmpObjectTypeMacroType","SnmpAccess","SnmpStatus","SnmpDescrPart","SnmpReferPart",
+"SnmpIndexPart","SnmpDefValPart", NULL
+};
+#endif
+
+static const short yyr1[] = {     0,
+   147,   149,   148,   150,   150,   150,   151,   152,   152,   153,
+   153,   154,   154,   154,   155,   155,   156,   156,   157,   157,
+   157,   158,   158,   159,   159,   160,   161,   161,   162,   162,
+   162,   163,   163,   164,   164,   164,   165,   165,   166,   165,
+   165,   165,   167,   167,   168,   169,   170,   170,   171,   171,
+   171,   171,   172,   172,   172,   172,   172,   172,   172,   172,
+   172,   172,   172,   172,   172,   172,   172,   172,   173,   173,
+   174,   175,   175,   176,   176,   177,   177,   178,   178,   178,
+   178,   179,   180,   181,   181,   182,   183,   184,   185,   185,
+   186,   187,   187,   188,   188,   188,   188,   188,   189,   190,
+   191,   191,   192,   193,   194,   195,   195,   196,   197,   197,
+   197,   198,   199,   199,   200,   200,   200,   200,   201,   201,
+   202,   203,   203,   203,   204,   205,   205,   206,   206,   206,
+   206,   206,   206,   207,   208,   209,   210,   210,   211,   211,
+   212,   212,   213,   213,   214,   215,   216,   216,   217,   218,
+   218,   219,   220,   221,   221,   222,   222,   223,   224,   224,
+   225,   225,   225,   225,   226,   227,   227,   228,   228,   229,
+   230,   230,   230,   230,   230,   230,   230,   231,   230,   232,
+   232,   233,   233,   234,   235,   235,   236,   237,   237,   238,
+   238,   238,   239,   240,   241,   241,   242,   243,   244,   245,
+   245,   246,   247,   248,   249,   250,   250,   251,   251,   252,
+   252,   252,   252,   252,   252,   252,   252,   252,   252,   252,
+   252,   252,   252,   252,   252,   252,   252,   252,   252,   252,
+   252,   252,   252,   252,   253,   253,   253,   253,   253,   253,
+   253,   253,   253,   253,   253,   253,   253,   253,   253,   253,
+   253,   253,   253,   253,   253,   253,   253,   253,   253,   254,
+   255,   256,   256,   257,   257,   258,   258,   259,   259,   260,
+   260,   261,   262,   262,   263,   264,   264,   265,   265,   266,
+   266,   267,   268,   268,   269,   269,   270,   271,   271,   272,
+   272,   273,   274,   275,   276,   276,   277,   277,   278,   279,
+   279,   280,   280,   281,   281,   282,   282,   283,   284,   284,
+   285,   285,   286,   286,   287,   287,   288,   288,   289,   289,
+   290,   290,   291,   291,   292,   292,   293,   293,   293,   294,
+   294,   295,   295,   296,   296,   297,   297,   298,   299,   299,
+   300,   300,   301,   302,   302,   302,   303,   303,   304,   304,
+   304,   304,   304,   305,   306,   307,   308,   308,   309,   310,
+   310,   311,   311,   312,   313,   313,   314,   314,   315,   316,
+   316,   317,   317,   318,   318,   319,   319,   320,   321,   322,
+   323,   324,   325,   326,   327,   328,   329,   330,   330,   331,
+   331,   332,   332,   333,   333
+};
+
+static const short yyr2[] = {     0,
+     0,     0,     8,     2,     2,     1,     2,     1,     1,     3,
+     1,     3,     3,     1,     1,     1,     1,     4,     3,     3,
+     1,     1,     1,     2,     1,     4,     3,     1,     1,     1,
+     1,     2,     1,     1,     2,     2,     1,     1,     0,     6,
+     3,     5,     1,     1,     6,     4,     1,     1,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     2,     2,     1,
+     1,     1,     4,     1,     3,     4,     4,     1,     1,     2,
+     2,     4,     1,     2,     5,     1,     1,     3,     3,     2,
+     2,     1,     5,     1,     2,     3,     3,     4,     3,     3,
+     3,     2,     3,     5,     2,     1,     4,     3,     2,     3,
+     3,     4,     1,     1,     1,     1,     1,     1,     1,     4,
+     1,     2,     4,     4,     3,     1,     3,     1,     1,     1,
+     1,     1,     1,     1,     2,     4,     1,     2,     1,     2,
+     1,     1,     1,     1,     2,     2,     3,     3,     1,     1,
+     1,     3,     7,     1,     3,     2,     1,     2,     1,     1,
+     1,     1,     1,     1,     5,     1,     1,     1,     1,     4,
+     1,     1,     1,     1,     1,     1,     1,     0,     3,     1,
+     1,     1,     1,     1,     1,     2,     3,     2,     1,     1,
+     1,     1,     1,     1,     4,     4,     1,     1,     1,     1,
+     1,     1,     1,     1,     0,     1,     1,     1,     2,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     2,
+     4,     2,     1,     2,     1,     1,     1,     4,     1,     4,
+     1,     2,     2,     1,     4,     2,     1,     2,     1,     2,
+     1,     4,     2,     1,     2,     3,     4,     4,     1,     4,
+     1,     1,     8,     4,     7,     1,     5,     1,     2,     6,
+     1,     6,     1,     4,     1,     1,     3,     6,     1,     1,
+     1,     3,     1,     1,     1,     3,     1,     1,     4,     1,
+     2,     1,     3,     1,     1,     3,     1,     1,     1,     1,
+     2,     1,     2,     1,     2,     1,     2,     2,     4,     1,
+     1,     3,     2,     1,     1,     1,     2,     1,     4,     1,
+     1,     2,     2,     4,     4,     4,     1,     3,     2,     1,
+     2,     1,     3,     3,     1,     3,     1,     3,     1,     2,
+     3,     4,     1,     2,     3,     4,     1,     2,     2,     3,
+     2,     2,     2,     2,    11,     1,     1,     2,     0,     2,
+     0,     4,     0,     4,     0
+};
+
+static const short yydefact[] = {     0,
+   203,     0,   205,   205,     0,     7,     8,     9,     0,     0,
+     2,     6,   202,   201,   200,     0,   189,   190,   191,   192,
+   193,   194,     5,     4,     0,   187,   188,     0,     0,     0,
+   168,     0,   169,     0,   205,   196,   195,     1,     0,     0,
+   205,    14,     0,     0,   204,   235,   236,   237,   238,   239,
+   240,   242,   241,   243,   244,   245,   246,   247,   248,   249,
+   250,   251,   253,   252,   254,   255,   256,   257,   258,   259,
+     0,    15,    17,    30,    29,    16,    31,     3,     0,     0,
+    21,   170,    13,    12,     1,     0,     0,    22,    25,     0,
+    28,    23,     0,     0,     0,    33,    34,    37,    38,     0,
+     0,     0,    20,    19,    24,     0,     1,    36,     0,    32,
+    35,   204,   205,    71,    72,     0,     0,    87,     1,     1,
+     1,   119,   121,     0,    83,   205,   205,   205,   205,   205,
+     0,     0,   320,   330,   332,   334,   336,   205,   348,     0,
+   205,   205,   205,   205,     0,     0,     0,     0,     0,     0,
+    47,    51,     0,    50,    53,    54,    66,    67,    55,    56,
+     0,    57,    58,     0,    59,    60,    61,    62,    63,     0,
+    64,    65,    52,     0,     0,    48,    49,   210,   211,   212,
+   213,   214,   215,   217,   216,   218,   219,   220,   221,   222,
+   223,   224,   225,   226,   227,   228,   229,   230,   233,   232,
+   231,   234,   205,    18,    27,     0,     1,    41,     0,    43,
+    44,   115,   116,   117,     0,   118,     0,    84,    68,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+   263,   260,   205,     0,   274,   272,     0,   277,   205,   205,
+     0,     0,   289,   285,   205,     0,     0,     0,    70,   205,
+     0,   331,   333,   335,   337,     0,   340,   338,     0,     0,
+     0,   347,   350,   351,   197,   198,   199,    79,    78,   178,
+     0,   184,   180,   181,   182,   183,   174,   369,   167,   166,
+   171,   173,   172,   176,   175,   177,     0,     0,   373,   370,
+     0,   377,   374,   379,   378,     0,   381,   382,   383,   384,
+     0,     0,     1,   122,    90,     0,    94,     0,   205,    92,
+     0,   102,     0,     0,     0,   109,     0,     1,   208,   207,
+     1,   206,    26,    39,     0,     0,   114,   113,     0,    74,
+     0,     0,    99,   145,    88,     0,   103,   100,     0,     0,
+     0,     0,   262,   205,   265,   205,   273,   276,     0,   279,
+   205,   205,     0,     0,     0,   291,   286,     0,     0,     0,
+     0,   322,   205,    69,     0,     0,     0,     0,   352,   353,
+     0,    81,    80,     0,     0,   371,     0,   375,   380,     0,
+     0,   142,     0,     0,     0,   126,   128,   129,   130,     0,
+   137,   132,   131,   133,   134,     0,     0,    95,     0,    89,
+   205,    91,     0,   101,   110,   111,   108,     0,     0,   209,
+     0,    42,   112,     0,    73,     0,    86,     0,   124,   123,
+   106,     0,   205,   120,    82,   266,   267,   264,     0,   269,
+   205,   278,     0,   281,   275,     0,   284,   282,   311,     0,
+   292,     0,     0,     0,     0,   205,   321,     0,   324,   319,
+   205,     0,   341,    87,   317,   318,   169,     0,     0,   315,
+     0,     0,   179,   356,   357,     0,   360,     0,     0,     0,
+   135,   146,     0,     0,   125,     0,     0,   138,   165,    97,
+   185,    96,   169,     1,     0,    46,   205,    40,    75,     0,
+     0,    85,   104,   205,   105,   205,     0,   271,   261,   280,
+   283,   287,     0,   288,     0,   294,     0,   310,     0,   309,
+     0,   344,   345,   346,   343,     0,   339,     1,     0,   354,
+   355,   349,     0,   205,   359,   362,   361,   372,   376,   386,
+     0,   205,   148,   150,   151,   149,   147,   127,     0,   186,
+     0,    98,    45,    76,    77,     0,   314,     0,   313,   205,
+   312,   290,   205,   308,   329,   327,   328,   323,   325,   342,
+     0,   316,   358,     0,     0,     0,     0,   159,     0,   154,
+   157,   205,   205,   160,     0,   144,   136,   139,   143,    93,
+   107,   268,     0,     0,   296,   205,     0,   365,     0,   364,
+   363,   387,   389,     0,   205,   152,   164,   161,   162,   158,
+   163,   156,   140,   270,     0,     0,   305,   293,   326,     0,
+     0,   391,     0,   155,     0,     0,   366,   367,   388,     0,
+   393,   205,     0,   306,     0,     0,   390,     0,   395,     0,
+   205,     0,   304,   368,     0,     0,   385,   153,     0,   298,
+   205,   307,     0,     0,     0,     0,   301,   295,   205,   392,
+     0,     0,     0,     0,   303,   299,   394,     0,     0,     0,
+   297,     0,     0,     0,     0,   300,     0,   302,     0,     0,
+     0
+};
+
+static const short yydefgoto[] = {    43,
+   669,    25,    11,     2,     6,    40,    41,    71,    72,    80,
+    87,    88,    89,    90,    91,    95,    96,    97,   411,   208,
+    98,   151,   152,   249,   154,   307,   155,   156,   329,   330,
+   277,   157,   158,   159,   418,   160,   161,   162,   308,   309,
+   310,   163,   164,   165,   166,   167,   422,   423,   168,   169,
+   170,   326,   215,   171,   172,   173,   304,   385,   386,   387,
+   388,   389,   390,   577,   391,   578,   392,   393,   394,   537,
+   533,   534,   535,   569,   570,   571,   572,   600,    99,   439,
+   279,    31,   280,   371,   281,   282,   283,   482,     7,    16,
+    17,    18,    19,    20,   284,   285,   286,    21,    33,   175,
+   176,   320,   321,   322,   177,    77,   178,   232,   233,   346,
+   428,   431,   499,   179,   236,   180,   239,   351,   435,   181,
+   438,   182,   244,   245,   357,   440,   183,   247,   586,   641,
+   648,   649,   656,   608,   625,   184,   509,   441,   548,   549,
+   460,   185,   363,   450,   558,   559,   186,   187,   188,   189,
+   190,   258,   452,   453,   515,   191,   262,   263,   264,   192,
+   464,   465,   466,   525,   526,   590,   617,   467,   193,   290,
+   194,   293,   195,   196,   197,   198,   199,   200,   201,   202,
+   531,   593,   612,   621,   629,   637
+};
+
+static const short yypact[] = {    66,
+-32768,    25,    20,   -12,   117,-32768,-32768,-32768,    53,    63,
+-32768,-32768,-32768,-32768,-32768,    71,-32768,-32768,-32768,-32768,
+-32768,    77,-32768,-32768,    86,-32768,-32768,    92,    68,    82,
+-32768,   108,-32768,   121,    78,-32768,-32768,-32768,   630,   152,
+    85,   156,   175,   147,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+   161,   188,-32768,-32768,-32768,-32768,-32768,-32768,   893,   113,
+-32768,-32768,-32768,-32768,-32768,   164,   165,   701,-32768,     5,
+-32768,-32768,   167,   190,    15,-32768,   169,-32768,-32768,  1989,
+   195,   701,-32768,-32768,-32768,   701,-32768,-32768,  2045,-32768,
+-32768,   217,    93,-32768,   216,   205,   207,-32768,    -2,    -1,
+-32768,   174,-32768,   224,-32768,   158,   151,   159,   159,    89,
+   148,   139,  1989,  1989,  1989,  1989,  1989,   128,   -72,   557,
+   118,   191,   151,   158,   160,  1989,  1989,  1989,  1989,   112,
+-32768,-32768,    42,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+  1255,-32768,-32768,  1389,-32768,-32768,-32768,-32768,-32768,  1509,
+-32768,-32768,-32768,   231,   240,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,   242,-32768,-32768,    66,-32768,-32768,   243,-32768,
+-32768,-32768,-32768,-32768,    92,-32768,   175,   244,-32768,  1989,
+   238,   245,   225,  1989,   246,   229,   248,   200,   175,  1989,
+-32768,-32768,   181,  1989,-32768,-32768,  1989,-32768,   182,   182,
+   253,   254,-32768,-32768,   177,   260,   186,   218,   238,   239,
+  1749,   238,   238,   238,   238,   265,-32768,-32768,   267,   268,
+   272,-32768,   192,   197,-32768,-32768,-32768,-32768,-32768,-32768,
+   183,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,   170,   276,-32768,  1989,
+   281,-32768,  1989,-32768,-32768,  1989,   238,   238,   238,   238,
+  1989,  1037,-32768,-32768,-32768,   264,   168,   282,    79,-32768,
+  1629,-32768,   283,  1989,  1989,   238,  1989,-32768,-32768,-32768,
+-32768,   288,-32768,-32768,  2102,   284,-32768,-32768,    44,-32768,
+   290,   175,   238,-32768,-32768,  1989,   238,-32768,  1989,  1989,
+   175,   129,-32768,  1989,-32768,   222,-32768,-32768,  1989,-32768,
+   220,   219,   557,   557,   294,-32768,-32768,   557,  1989,   302,
+   557,-32768,   211,   238,   557,  1121,  1121,  1121,-32768,-32768,
+   315,-32768,-32768,   557,   557,   238,   557,   238,   238,    -9,
+  1989,-32768,   238,   -24,    12,-32768,-32768,-32768,-32768,   312,
+   305,-32768,-32768,-32768,    13,   557,  1989,-32768,   557,-32768,
+   242,-32768,   295,-32768,   238,   238,   238,   322,  1989,-32768,
+   323,-32768,-32768,   175,-32768,   111,   319,   318,   238,   238,
+-32768,   320,   132,-32768,-32768,-32768,-32768,-32768,   325,-32768,
+   250,-32768,  1989,-32768,-32768,  1989,-32768,-32768,-32768,   326,
+   321,   327,   557,   133,    -3,   557,-32768,   232,-32768,-32768,
+    90,   134,-32768,-32768,   238,-32768,   231,   331,   137,-32768,
+   138,   141,-32768,   324,-32768,   557,   221,   145,   146,   175,
+   238,-32768,   330,   238,-32768,  1037,   334,-32768,-32768,   238,
+-32768,-32768,   557,-32768,  1989,-32768,    73,-32768,-32768,   332,
+   337,-32768,-32768,   242,-32768,  1121,   333,-32768,-32768,-32768,
+-32768,-32768,   557,-32768,   340,-32768,  1989,-32768,   342,   321,
+    30,-32768,-32768,-32768,-32768,   557,-32768,-32768,  1121,-32768,
+-32768,-32768,   557,    90,   335,-32768,-32768,-32768,-32768,-32768,
+   227,    55,-32768,-32768,-32768,-32768,-32768,-32768,   844,-32768,
+  1869,   238,-32768,-32768,-32768,  1989,-32768,   343,   347,  1121,
+-32768,-32768,    -4,-32768,-32768,-32768,-32768,   348,-32768,-32768,
+   206,-32768,-32768,    98,   557,   175,   350,-32768,   149,-32768,
+-32768,     4,   238,-32768,  2239,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,   353,   275,-32768,   269,    30,-32768,   311,-32768,
+-32768,-32768,   235,   365,    27,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,   364,   366,-32768,-32768,-32768,   557,
+   557,   241,   368,-32768,   557,    20,   369,-32768,-32768,   557,
+   249,    27,   370,-32768,   150,   557,-32768,   372,   255,   153,
+   293,    20,-32768,-32768,  1121,   379,-32768,-32768,   352,-32768,
+   298,-32768,   154,   557,   388,   300,-32768,-32768,   303,-32768,
+   390,   557,   374,   306,-32768,-32768,-32768,   162,   394,   378,
+-32768,   557,   398,   163,   557,-32768,   166,-32768,   415,   417,
+-32768
+};
+
+static const short yypgoto[] = {   -14,
+-32768,-32768,-32768,   212,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,   338,-32768,   -22,-32768,   328,-32768,-32768,    94,
+-32768,-32768,-32768,   -94,-32768,  -122,-32768,-32768,  -219,     6,
+    11,-32768,-32768,-32768,-32768,-32768,-32768,-32768,   257,-32768,
+  -113,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,  -192,-32768,   -47,-32768,
+-32768,-32768,-32768,-32768,-32768,  -144,   109,-32768,-32768,-32768,
+-32768,-32768,-32768,  -189,  -161,  -138,-32768,-32768,-32768,   -44,
+   -23,-32768,-32768,-32768,-32768,-32768,-32768,-32768,  -586,-32768,
+   420,   409,-32768,-32768,-32768,-32768,-32768,   223,   569,     0,
+   -32,    46,  -290,-32768,-32768,  -101,-32768,   296,-32768,-32768,
+-32768,-32768,-32768,-32768,   299,-32768,   316,   201,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,  -341,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,  -346,  -106,  -364,
+   -71,-32768,-32768,-32768,-32768,  -140,-32768,-32768,-32768,-32768,
+-32768,-32768,  -177,   -67,   -74,-32768,-32768,   187,   194,-32768,
+-32768,   -70,-32768,-32768,  -111,-32768,-32768,  -139,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768
+};
+
+
+#define	YYLAST		2307
+
+
+static const short yytable[] = {     3,
+   287,   459,   461,   462,    30,   153,    75,   211,   302,   342,
+   250,   444,   442,   302,   302,    93,    73,   473,   402,   106,
+    45,    13,    94,     9,   259,   260,  -141,    34,   334,   624,
+   475,   220,   224,    13,  -141,     5,   476,   474,    10,   252,
+   253,   254,   255,   597,   302,   642,    75,   101,     8,    12,
+   261,   297,   298,   299,   300,    75,   221,   221,   414,   302,
+   415,    13,   101,   -10,   107,   303,   598,   599,   567,    75,
+   102,     1,   302,    75,     4,   316,   210,    13,    23,   204,
+    42,    14,    15,   205,    76,   319,    81,    26,    24,   507,
+   302,   319,   206,   401,    28,   278,   584,     1,    13,   510,
+    36,   505,    14,    15,   222,   225,   227,   343,   209,    29,
+   484,   347,   417,    93,   348,    35,     1,    13,    45,    13,
+    94,   268,   269,    13,    92,   333,    37,    14,    15,   337,
+    39,   470,   495,   271,    38,   212,   213,   214,    79,    34,
+   555,   556,   557,   414,   319,   425,   494,   503,   516,   506,
+   517,   519,   519,   520,   521,   519,   364,   522,   216,   516,
+   516,   528,   529,   595,   632,   596,   633,   595,   519,   638,
+   650,   231,   235,   238,   238,   243,   503,   503,   661,   666,
+   503,    13,   668,   257,   241,   242,   289,   292,   235,   231,
+   472,   327,   324,   372,   373,   376,   543,   468,   378,   469,
+    78,   379,    85,   546,   -11,     3,   380,   398,   399,   512,
+   513,    45,    13,   109,    34,    83,   364,   421,   203,   405,
+   406,   426,   407,   211,   588,   589,   432,   223,   226,    84,
+  -203,   217,   103,   104,   218,   108,   219,   111,   228,   229,
+   234,   419,   230,   237,   420,   248,   256,   246,   288,   296,
+   291,   301,   317,   318,   319,   302,   325,   395,   336,   332,
+   335,   338,   339,   340,   445,   341,   344,   349,   353,   354,
+   643,   455,   455,   455,   355,   358,   359,   360,   345,   361,
+   365,   536,   366,   367,   350,   350,   471,   368,   396,   260,
+   356,   375,   210,   259,   374,   362,   377,   397,   400,   404,
+   410,    34,   480,   408,   413,   658,   409,   416,   429,   443,
+   500,   433,   436,   501,   487,   664,   447,   446,   667,   448,
+   451,   456,   456,   456,   463,   477,   478,    45,   485,   278,
+   451,   488,   451,   414,   492,   503,   493,   497,   523,   568,
+   496,   511,   502,   504,   518,   532,   527,   539,   550,   565,
+   544,   479,    34,    34,   481,   545,   552,    34,   554,   582,
+    34,   519,   587,   594,    34,   458,   458,   458,   566,   604,
+   605,   610,   606,    34,    34,   486,    34,   611,   613,   615,
+   568,   616,   622,   626,   620,   645,   631,   635,   639,   427,
+   542,   430,   491,   628,   644,    34,   434,   437,    34,   646,
+   636,   455,   568,   652,   653,   654,   657,   659,   449,   662,
+   660,   663,   553,   665,   670,    34,   671,   323,   412,   489,
+   313,   524,   110,   581,   455,   105,   490,   580,   538,   568,
+   603,   395,   630,   614,   602,    27,    32,   328,   540,   295,
+   352,   294,    34,   583,   240,    34,   609,   562,   560,   564,
+   370,   456,   563,   591,     0,   455,   369,     0,   551,     0,
+     0,     0,     0,     0,     0,    34,     0,     0,     0,   541,
+   618,   451,     0,     0,   456,    34,   498,     0,   278,     0,
+     0,     0,    34,     0,     0,     0,   634,     0,     0,     0,
+     0,   508,     0,     0,   579,   458,   514,     0,     0,     0,
+     0,     0,    34,   561,     0,   456,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,    34,     0,     0,   458,     0,
+   524,     0,    34,     0,     0,     0,     0,     0,   486,     0,
+   579,     0,     0,     0,     0,     0,     0,     0,    34,     0,
+   455,   547,     0,     0,     0,     0,     0,     0,     0,   458,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,   265,
+   266,   267,     1,    13,    34,   278,   619,   268,   269,   514,
+   623,     0,   270,    22,    34,   627,     0,   574,     0,   271,
+     0,   278,     0,     0,    22,     0,     0,     0,   272,     0,
+   456,     0,     0,     0,     0,   547,     0,     0,   585,   651,
+     0,     0,   273,   274,     0,     0,     0,    74,     0,    34,
+    34,    82,     0,     0,    34,     0,     0,   601,   574,    34,
+     0,     0,     0,   275,   276,    34,     0,     0,     0,     0,
+    44,   607,     0,     0,   458,    45,    13,     0,     0,     0,
+   574,     0,     0,    34,     0,     0,     0,    74,   100,     0,
+     0,    34,     0,     0,     0,     0,    74,     0,     0,     0,
+     0,    34,     0,   100,    34,     0,     0,   574,   174,     0,
+    74,     0,     0,     0,    74,     0,   640,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,   647,     0,     0,     0,
+     0,     0,     0,     0,   655,     0,     0,     0,  -205,     0,
+     0,   251,   174,   174,   174,   174,    45,    13,     0,     0,
+     0,     0,     0,    46,   174,   174,   174,   174,    47,     0,
+    48,     0,    49,     0,    50,     0,     0,     0,    51,   311,
+     0,     0,   311,     0,     0,    52,     0,    53,   174,     0,
+     0,     0,     0,    54,    55,    56,    57,    58,     0,     0,
+     0,    59,     0,    60,     0,     0,     0,     0,    61,    62,
+     0,    63,    64,    65,    66,    67,    68,    69,    70,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    46,   331,     0,     0,   174,    47,
+     0,    48,   174,    49,     0,    50,     0,   331,   251,    51,
+     0,     0,   251,     0,     0,   251,    52,     0,    53,     0,
+     0,     0,     0,     0,    54,    55,    56,    57,    58,   174,
+     0,     0,    59,     0,    60,     0,     0,     0,     0,    61,
+    62,     0,    63,    64,    65,    66,    67,    68,    69,    70,
+     0,     0,     0,     0,     0,     0,   265,   266,   267,     1,
+    13,     0,     0,     0,   268,   269,     0,     0,   174,   270,
+     0,   174,     0,     0,   174,   575,   271,     0,     0,   174,
+     0,     0,     0,     0,     0,   272,     0,     0,     0,   174,
+     0,     0,   174,   174,     0,   174,     0,     0,     0,   273,
+   274,     0,     0,    86,     0,     0,     0,     0,    45,    13,
+   331,   576,     0,     0,   174,     0,     0,   174,   251,   424,
+   275,   276,   251,     0,     0,     0,     0,   251,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,   174,     0,     0,
+     0,     0,     0,     0,   457,   457,   457,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,   174,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,  -205,     0,     0,     0,   174,     0,   483,     0,     0,
+     0,     0,     0,     0,     0,     0,    46,   174,     0,     0,
+     0,    47,   331,    48,     0,    49,     0,    50,     0,     0,
+     0,    51,     0,     0,     0,     0,     0,     0,    52,     0,
+    53,   251,     0,     0,   251,     0,    54,    55,    56,    57,
+    58,     0,     0,     0,    59,     0,    60,     0,     0,     0,
+     0,    61,    62,     0,    63,    64,    65,    66,    67,    68,
+    69,    70,     0,     0,     0,     0,     0,     0,   530,   265,
+   266,   267,     1,    13,     0,     0,     0,   268,   269,     0,
+     0,     0,   270,   174,     0,     0,     0,     0,     0,   271,
+     0,     0,     0,     0,   457,     0,     0,     0,   272,     0,
+     0,     0,     0,     0,     0,   174,     0,     0,     0,     0,
+     0,     0,   273,   274,     0,     0,     0,   457,     0,     0,
+     0,     0,   381,   382,     0,   221,   383,   384,     0,     0,
+   573,     0,     0,   275,   276,     0,     0,     0,     0,   311,
+     0,     0,     0,     0,   251,     0,     0,     0,   457,     0,
+     0,     0,     0,   265,   266,   267,   112,    13,     0,    82,
+     0,   268,   269,     0,   592,     0,   270,     0,     0,     0,
+   113,     0,     0,   271,     0,     0,     0,   114,   115,   116,
+     0,   117,   454,   119,     0,   120,     0,   121,   122,   123,
+     0,     0,     0,   573,     0,     0,   273,   274,     0,     0,
+     0,     0,   124,     0,     0,   125,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,   275,   276,     0,
+   573,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,   457,   126,     0,     0,     0,     0,   127,
+     0,   128,     0,   129,     0,   130,     0,     0,     0,   131,
+     0,     0,     0,     0,     0,     0,   132,     0,   133,     0,
+     0,     0,     0,     0,   134,   135,   136,   137,   138,     0,
+     0,     0,   139,     0,   140,     0,     0,     0,     0,   141,
+   142,     0,   143,   144,   145,   146,   147,   148,   149,   150,
+   112,    13,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,   305,     0,     0,   113,     0,     0,     0,     0,     0,
+     0,   114,   115,   116,     0,   117,   118,   119,     0,   120,
+     0,   121,   122,   123,     0,     0,   306,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,   124,     0,     0,   125,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,   126,     0,
+     0,     0,     0,   127,     0,   128,     0,   129,     0,   130,
+     0,     0,     0,   131,     0,     0,     0,     0,     0,     0,
+   132,     0,   133,     0,     0,     0,     0,     0,   134,   135,
+   136,   137,   138,     0,     0,     0,   139,     0,   140,     0,
+     0,     0,     0,   141,   142,     0,   143,   144,   145,   146,
+   147,   148,   149,   150,   112,    13,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,   312,     0,     0,   113,     0,
+     0,     0,     0,     0,     0,   114,   115,   116,     0,   117,
+   118,   119,     0,   120,     0,   121,   122,   123,     0,     0,
+   306,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+   124,     0,     0,   125,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,   126,     0,     0,     0,     0,   127,     0,   128,
+     0,   129,     0,   130,     0,     0,     0,   131,     0,     0,
+     0,     0,     0,     0,   132,     0,   133,     0,     0,     0,
+     0,     0,   134,   135,   136,   137,   138,     0,     0,     0,
+   139,     0,   140,     0,   112,    13,     0,   141,   142,     0,
+   143,   144,   145,   146,   147,   148,   149,   150,   113,     0,
+     0,     0,     0,     0,     0,   114,   115,   116,     0,   117,
+   118,   119,     0,   120,   314,   121,   122,   123,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,   315,
+   124,     0,     0,   125,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,   126,     0,     0,     0,     0,   127,     0,   128,
+     0,   129,     0,   130,     0,     0,     0,   131,     0,     0,
+     0,     0,     0,     0,   132,     0,   133,     0,     0,     0,
+     0,     0,   134,   135,   136,   137,   138,     0,     0,     0,
+   139,     0,   140,     0,   112,    13,     0,   141,   142,     0,
+   143,   144,   145,   146,   147,   148,   149,   150,   113,     0,
+   317,     0,     0,     0,     0,   114,   115,   116,     0,   117,
+   118,   119,     0,   120,     0,   121,   122,   123,     0,     0,
+   403,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+   124,     0,     0,   125,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,   126,     0,     0,     0,     0,   127,     0,   128,
+     0,   129,     0,   130,     0,     0,     0,   131,     0,     0,
+     0,     0,     0,     0,   132,     0,   133,     0,     0,     0,
+     0,     0,   134,   135,   136,   137,   138,     0,     0,     0,
+   139,     0,   140,     0,   112,    13,     0,   141,   142,     0,
+   143,   144,   145,   146,   147,   148,   149,   150,   113,     0,
+   317,     0,     0,     0,     0,   114,   115,   116,     0,   117,
+   118,   119,     0,   120,     0,   121,   122,   123,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+   124,     0,     0,   125,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,   126,     0,     0,     0,     0,   127,     0,   128,
+     0,   129,     0,   130,     0,     0,     0,   131,     0,     0,
+     0,     0,     0,     0,   132,     0,   133,     0,     0,     0,
+     0,     0,   134,   135,   136,   137,   138,     0,     0,     0,
+   139,     0,   140,     0,   112,    13,     0,   141,   142,     0,
+   143,   144,   145,   146,   147,   148,   149,   150,   113,     0,
+     0,     0,     0,     0,     0,   114,   115,   116,     0,   117,
+   118,   119,     0,   120,     0,   121,   122,   123,     0,     0,
+   306,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+   124,     0,     0,   125,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,   126,     0,     0,     0,     0,   127,     0,   128,
+     0,   129,     0,   130,     0,     0,     0,   131,     0,     0,
+     0,     0,     0,     0,   132,     0,   133,     0,     0,     0,
+     0,     0,   134,   135,   136,   137,   138,     0,     0,     0,
+   139,     0,   140,     0,   112,    13,     0,   141,   142,     0,
+   143,   144,   145,   146,   147,   148,   149,   150,   113,     0,
+     0,     0,     0,     0,     0,   114,   115,   116,     0,   117,
+   118,   119,     0,   120,     0,   121,   122,   123,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+   124,     0,     0,   125,     0,     0,     0,     0,     0,     0,
+   112,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,   126,     0,     0,     0,     0,   127,     0,   128,
+     0,   129,     0,   130,     0,     0,     0,   131,     0,     0,
+     0,     0,   207,     0,   132,     0,   133,     0,     0,     0,
+     0,     0,   134,   135,   136,   137,   138,    45,     0,     0,
+   139,     0,   140,     0,     0,     0,     0,   141,   142,     0,
+   143,   144,   145,   146,   147,   148,   149,   150,    46,     0,
+     0,     0,     0,    47,     0,    48,     0,    49,     0,    50,
+     0,     0,     0,    51,     0,     0,     0,     0,     0,     0,
+    52,     0,    53,     0,     0,     0,     0,     0,    54,    55,
+    56,    57,    58,     0,     0,     0,    59,     0,    60,     0,
+     0,     0,     0,    61,    62,     0,    63,    64,    65,    66,
+    67,    68,    69,    70,     0,    46,     0,     0,     0,     0,
+    47,     0,    48,     0,    49,     0,    50,     0,     0,     0,
+    51,     0,     0,     0,     0,     0,     0,    52,     0,    53,
+     0,     0,     0,     0,     0,    54,    55,    56,    57,    58,
+     0,     0,     0,    59,     0,    60,     0,     0,     0,     0,
+    61,    62,     0,    63,    64,    65,    66,    67,    68,    69,
+    70,   265,   266,   267,     1,    13,     0,     0,     0,   268,
+   269,     0,     0,     0,   270,     0,     0,     0,     0,     0,
+     0,   271,     0,     0,     0,     0,     0,     0,     0,     0,
+   272,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,   273,   274,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,   576,     0,     0,     0,
+     0,     0,     0,     0,     0,   275,   276
+};
+
+static const short yycheck[] = {     0,
+   140,   366,   367,   368,    28,   100,    39,   109,    18,   229,
+   133,   358,   354,    18,    18,     1,    39,    42,   309,    15,
+     6,     7,     8,    36,    97,    98,    14,    28,   221,   616,
+    19,    34,    34,     7,    22,    16,    25,    62,    51,   134,
+   135,   136,   137,    40,    18,   632,    79,    80,     3,     4,
+   123,   146,   147,   148,   149,    88,    59,    59,    15,    18,
+    17,     7,    95,    49,    60,    24,    63,    64,    14,   102,
+    85,     6,    18,   106,    50,   170,   109,     7,    26,   102,
+    35,    11,    12,   106,    39,    13,    41,    17,    26,    93,
+    18,    13,   107,    15,    18,   140,   101,     6,     7,   446,
+    19,   443,    11,    12,   119,   120,   121,   230,   109,    24,
+   401,   234,   332,     1,   237,    48,     6,     7,     6,     7,
+     8,    11,    12,     7,    79,   220,    19,    11,    12,   224,
+    53,   141,   423,    23,    14,    43,    44,    45,    54,   140,
+   111,   112,   113,    15,    13,    17,    15,    15,    15,    17,
+    17,    15,    15,    17,    17,    15,   251,    17,   113,    15,
+    15,    17,    17,    15,    15,    17,    17,    15,    15,    17,
+    17,   126,   127,   128,   129,   130,    15,    15,    17,    17,
+    15,     7,    17,   138,    96,    97,   141,   142,   143,   144,
+   383,   215,   207,    11,    12,   290,   487,   375,   293,   377,
+    49,   296,    15,   494,    49,   206,   301,    40,    41,   120,
+   121,     6,     7,    24,   215,    69,   311,   340,    24,   314,
+   315,   344,   317,   325,   127,   128,   349,   119,   120,    69,
+    14,    16,    69,    69,    30,    69,    30,    69,    65,    16,
+    90,   336,    85,    85,   339,   107,   119,   100,   131,    90,
+    60,   140,    22,    14,    13,    18,    14,   302,    34,    16,
+    16,    16,    34,    16,   359,    66,    86,    86,    16,    16,
+   635,   366,   367,   368,    98,    16,    91,    60,   233,    41,
+    16,   474,    16,    16,   239,   240,   381,    16,   303,    98,
+   245,    16,   325,    97,   125,   250,    16,    34,    17,    17,
+    13,   302,   397,   318,    21,   652,   321,    18,    87,    16,
+   433,    92,    94,   436,   409,   662,   361,    16,   665,   109,
+   365,   366,   367,   368,    10,    14,    22,     6,    34,   374,
+   375,     9,   377,    15,    17,    15,    17,    88,    15,   532,
+    16,   110,    17,    17,    14,    16,   126,    14,    16,    15,
+    19,   396,   353,   354,   399,    19,    17,   358,    17,    17,
+   361,    15,    15,    14,   365,   366,   367,   368,   142,    17,
+    96,    61,   104,   374,   375,   408,   377,   143,    14,    16,
+   573,    16,    15,    15,   144,    34,    17,    16,    96,   344,
+   485,   346,   416,   145,    16,   396,   351,   352,   399,   102,
+   146,   496,   595,    16,   105,   103,    17,    34,   363,    16,
+   105,    34,   507,    16,     0,   416,     0,   206,   325,   414,
+   164,   466,    95,   546,   519,    88,   416,   541,   476,   622,
+   575,   476,   622,   595,   573,    16,    28,   215,   483,   144,
+   240,   143,   443,   550,   129,   446,   587,   519,   516,   524,
+   264,   496,   523,   565,    -1,   550,   263,    -1,   503,    -1,
+    -1,    -1,    -1,    -1,    -1,   466,    -1,    -1,    -1,   484,
+   610,   516,    -1,    -1,   519,   476,   431,    -1,   523,    -1,
+    -1,    -1,   483,    -1,    -1,    -1,   626,    -1,    -1,    -1,
+    -1,   446,    -1,    -1,   539,   496,   451,    -1,    -1,    -1,
+    -1,    -1,   503,   518,    -1,   550,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,   516,    -1,    -1,   519,    -1,
+   565,    -1,   523,    -1,    -1,    -1,    -1,    -1,   561,    -1,
+   575,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   539,    -1,
+   635,   496,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   550,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,
+     4,     5,     6,     7,   565,   610,   611,    11,    12,   524,
+   615,    -1,    16,     5,   575,   620,    -1,   532,    -1,    23,
+    -1,   626,    -1,    -1,    16,    -1,    -1,    -1,    32,    -1,
+   635,    -1,    -1,    -1,    -1,   550,    -1,    -1,   553,   644,
+    -1,    -1,    46,    47,    -1,    -1,    -1,    39,    -1,   610,
+   611,    43,    -1,    -1,   615,    -1,    -1,   572,   573,   620,
+    -1,    -1,    -1,    67,    68,   626,    -1,    -1,    -1,    -1,
+     1,   586,    -1,    -1,   635,     6,     7,    -1,    -1,    -1,
+   595,    -1,    -1,   644,    -1,    -1,    -1,    79,    80,    -1,
+    -1,   652,    -1,    -1,    -1,    -1,    88,    -1,    -1,    -1,
+    -1,   662,    -1,    95,   665,    -1,    -1,   622,   100,    -1,
+   102,    -1,    -1,    -1,   106,    -1,   631,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,   641,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,   649,    -1,    -1,    -1,    69,    -1,
+    -1,   133,   134,   135,   136,   137,     6,     7,    -1,    -1,
+    -1,    -1,    -1,    84,   146,   147,   148,   149,    89,    -1,
+    91,    -1,    93,    -1,    95,    -1,    -1,    -1,    99,   161,
+    -1,    -1,   164,    -1,    -1,   106,    -1,   108,   170,    -1,
+    -1,    -1,    -1,   114,   115,   116,   117,   118,    -1,    -1,
+    -1,   122,    -1,   124,    -1,    -1,    -1,    -1,   129,   130,
+    -1,   132,   133,   134,   135,   136,   137,   138,   139,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    84,   217,    -1,    -1,   220,    89,
+    -1,    91,   224,    93,    -1,    95,    -1,   229,   230,    99,
+    -1,    -1,   234,    -1,    -1,   237,   106,    -1,   108,    -1,
+    -1,    -1,    -1,    -1,   114,   115,   116,   117,   118,   251,
+    -1,    -1,   122,    -1,   124,    -1,    -1,    -1,    -1,   129,
+   130,    -1,   132,   133,   134,   135,   136,   137,   138,   139,
+    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,     5,     6,
+     7,    -1,    -1,    -1,    11,    12,    -1,    -1,   290,    16,
+    -1,   293,    -1,    -1,   296,    22,    23,    -1,    -1,   301,
+    -1,    -1,    -1,    -1,    -1,    32,    -1,    -1,    -1,   311,
+    -1,    -1,   314,   315,    -1,   317,    -1,    -1,    -1,    46,
+    47,    -1,    -1,     1,    -1,    -1,    -1,    -1,     6,     7,
+   332,    58,    -1,    -1,   336,    -1,    -1,   339,   340,   341,
+    67,    68,   344,    -1,    -1,    -1,    -1,   349,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,   359,    -1,    -1,
+    -1,    -1,    -1,    -1,   366,   367,   368,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   381,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    69,    -1,    -1,    -1,   397,    -1,   399,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    84,   409,    -1,    -1,
+    -1,    89,   414,    91,    -1,    93,    -1,    95,    -1,    -1,
+    -1,    99,    -1,    -1,    -1,    -1,    -1,    -1,   106,    -1,
+   108,   433,    -1,    -1,   436,    -1,   114,   115,   116,   117,
+   118,    -1,    -1,    -1,   122,    -1,   124,    -1,    -1,    -1,
+    -1,   129,   130,    -1,   132,   133,   134,   135,   136,   137,
+   138,   139,    -1,    -1,    -1,    -1,    -1,    -1,   470,     3,
+     4,     5,     6,     7,    -1,    -1,    -1,    11,    12,    -1,
+    -1,    -1,    16,   485,    -1,    -1,    -1,    -1,    -1,    23,
+    -1,    -1,    -1,    -1,   496,    -1,    -1,    -1,    32,    -1,
+    -1,    -1,    -1,    -1,    -1,   507,    -1,    -1,    -1,    -1,
+    -1,    -1,    46,    47,    -1,    -1,    -1,   519,    -1,    -1,
+    -1,    -1,    56,    57,    -1,    59,    60,    61,    -1,    -1,
+   532,    -1,    -1,    67,    68,    -1,    -1,    -1,    -1,   541,
+    -1,    -1,    -1,    -1,   546,    -1,    -1,    -1,   550,    -1,
+    -1,    -1,    -1,     3,     4,     5,     6,     7,    -1,   561,
+    -1,    11,    12,    -1,   566,    -1,    16,    -1,    -1,    -1,
+    20,    -1,    -1,    23,    -1,    -1,    -1,    27,    28,    29,
+    -1,    31,    32,    33,    -1,    35,    -1,    37,    38,    39,
+    -1,    -1,    -1,   595,    -1,    -1,    46,    47,    -1,    -1,
+    -1,    -1,    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    67,    68,    -1,
+   622,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,   635,    84,    -1,    -1,    -1,    -1,    89,
+    -1,    91,    -1,    93,    -1,    95,    -1,    -1,    -1,    99,
+    -1,    -1,    -1,    -1,    -1,    -1,   106,    -1,   108,    -1,
+    -1,    -1,    -1,    -1,   114,   115,   116,   117,   118,    -1,
+    -1,    -1,   122,    -1,   124,    -1,    -1,    -1,    -1,   129,
+   130,    -1,   132,   133,   134,   135,   136,   137,   138,   139,
+     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    17,    -1,    -1,    20,    -1,    -1,    -1,    -1,    -1,
+    -1,    27,    28,    29,    -1,    31,    32,    33,    -1,    35,
+    -1,    37,    38,    39,    -1,    -1,    42,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    52,    -1,    -1,    55,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    84,    -1,
+    -1,    -1,    -1,    89,    -1,    91,    -1,    93,    -1,    95,
+    -1,    -1,    -1,    99,    -1,    -1,    -1,    -1,    -1,    -1,
+   106,    -1,   108,    -1,    -1,    -1,    -1,    -1,   114,   115,
+   116,   117,   118,    -1,    -1,    -1,   122,    -1,   124,    -1,
+    -1,    -1,    -1,   129,   130,    -1,   132,   133,   134,   135,
+   136,   137,   138,   139,     6,     7,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    17,    -1,    -1,    20,    -1,
+    -1,    -1,    -1,    -1,    -1,    27,    28,    29,    -1,    31,
+    32,    33,    -1,    35,    -1,    37,    38,    39,    -1,    -1,
+    42,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    84,    -1,    -1,    -1,    -1,    89,    -1,    91,
+    -1,    93,    -1,    95,    -1,    -1,    -1,    99,    -1,    -1,
+    -1,    -1,    -1,    -1,   106,    -1,   108,    -1,    -1,    -1,
+    -1,    -1,   114,   115,   116,   117,   118,    -1,    -1,    -1,
+   122,    -1,   124,    -1,     6,     7,    -1,   129,   130,    -1,
+   132,   133,   134,   135,   136,   137,   138,   139,    20,    -1,
+    -1,    -1,    -1,    -1,    -1,    27,    28,    29,    -1,    31,
+    32,    33,    -1,    35,    36,    37,    38,    39,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    51,
+    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    84,    -1,    -1,    -1,    -1,    89,    -1,    91,
+    -1,    93,    -1,    95,    -1,    -1,    -1,    99,    -1,    -1,
+    -1,    -1,    -1,    -1,   106,    -1,   108,    -1,    -1,    -1,
+    -1,    -1,   114,   115,   116,   117,   118,    -1,    -1,    -1,
+   122,    -1,   124,    -1,     6,     7,    -1,   129,   130,    -1,
+   132,   133,   134,   135,   136,   137,   138,   139,    20,    -1,
+    22,    -1,    -1,    -1,    -1,    27,    28,    29,    -1,    31,
+    32,    33,    -1,    35,    -1,    37,    38,    39,    -1,    -1,
+    42,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    84,    -1,    -1,    -1,    -1,    89,    -1,    91,
+    -1,    93,    -1,    95,    -1,    -1,    -1,    99,    -1,    -1,
+    -1,    -1,    -1,    -1,   106,    -1,   108,    -1,    -1,    -1,
+    -1,    -1,   114,   115,   116,   117,   118,    -1,    -1,    -1,
+   122,    -1,   124,    -1,     6,     7,    -1,   129,   130,    -1,
+   132,   133,   134,   135,   136,   137,   138,   139,    20,    -1,
+    22,    -1,    -1,    -1,    -1,    27,    28,    29,    -1,    31,
+    32,    33,    -1,    35,    -1,    37,    38,    39,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    84,    -1,    -1,    -1,    -1,    89,    -1,    91,
+    -1,    93,    -1,    95,    -1,    -1,    -1,    99,    -1,    -1,
+    -1,    -1,    -1,    -1,   106,    -1,   108,    -1,    -1,    -1,
+    -1,    -1,   114,   115,   116,   117,   118,    -1,    -1,    -1,
+   122,    -1,   124,    -1,     6,     7,    -1,   129,   130,    -1,
+   132,   133,   134,   135,   136,   137,   138,   139,    20,    -1,
+    -1,    -1,    -1,    -1,    -1,    27,    28,    29,    -1,    31,
+    32,    33,    -1,    35,    -1,    37,    38,    39,    -1,    -1,
+    42,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    84,    -1,    -1,    -1,    -1,    89,    -1,    91,
+    -1,    93,    -1,    95,    -1,    -1,    -1,    99,    -1,    -1,
+    -1,    -1,    -1,    -1,   106,    -1,   108,    -1,    -1,    -1,
+    -1,    -1,   114,   115,   116,   117,   118,    -1,    -1,    -1,
+   122,    -1,   124,    -1,     6,     7,    -1,   129,   130,    -1,
+   132,   133,   134,   135,   136,   137,   138,   139,    20,    -1,
+    -1,    -1,    -1,    -1,    -1,    27,    28,    29,    -1,    31,
+    32,    33,    -1,    35,    -1,    37,    38,    39,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,    -1,    -1,
+     6,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    84,    -1,    -1,    -1,    -1,    89,    -1,    91,
+    -1,    93,    -1,    95,    -1,    -1,    -1,    99,    -1,    -1,
+    -1,    -1,    48,    -1,   106,    -1,   108,    -1,    -1,    -1,
+    -1,    -1,   114,   115,   116,   117,   118,     6,    -1,    -1,
+   122,    -1,   124,    -1,    -1,    -1,    -1,   129,   130,    -1,
+   132,   133,   134,   135,   136,   137,   138,   139,    84,    -1,
+    -1,    -1,    -1,    89,    -1,    91,    -1,    93,    -1,    95,
+    -1,    -1,    -1,    99,    -1,    -1,    -1,    -1,    -1,    -1,
+   106,    -1,   108,    -1,    -1,    -1,    -1,    -1,   114,   115,
+   116,   117,   118,    -1,    -1,    -1,   122,    -1,   124,    -1,
+    -1,    -1,    -1,   129,   130,    -1,   132,   133,   134,   135,
+   136,   137,   138,   139,    -1,    84,    -1,    -1,    -1,    -1,
+    89,    -1,    91,    -1,    93,    -1,    95,    -1,    -1,    -1,
+    99,    -1,    -1,    -1,    -1,    -1,    -1,   106,    -1,   108,
+    -1,    -1,    -1,    -1,    -1,   114,   115,   116,   117,   118,
+    -1,    -1,    -1,   122,    -1,   124,    -1,    -1,    -1,    -1,
+   129,   130,    -1,   132,   133,   134,   135,   136,   137,   138,
+   139,     3,     4,     5,     6,     7,    -1,    -1,    -1,    11,
+    12,    -1,    -1,    -1,    16,    -1,    -1,    -1,    -1,    -1,
+    -1,    23,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    32,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    46,    47,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    58,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    67,    68
+};
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/local/lib/bison.simple"
+
+/* Skeleton output parser for bison,
+   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C.  */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #pragma alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
+#endif /* __hpux */
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc.  */
+#endif /* not GNU C.  */
+#endif /* alloca not defined.  */
+
+/* This is the parser code that is written into each bison parser
+  when the %semantic_parser declaration is not specified in the grammar.
+  It was written by Richard Stallman by simplifying the hairy parser
+  used when %semantic_parser is specified.  */
+
+/* Note: there must be only one dollar sign in this file.
+   It is replaced by the list of actions, each action
+   as one case of the switch.  */
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+#define YYACCEPT	return(0)
+#define YYABORT 	return(1)
+#define YYERROR		goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+   This remains here temporarily to ease the
+   transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+#define YYFAIL		goto yyerrlab
+#define YYRECOVERING()  (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    { yychar = (token), yylval = (value);			\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { yyerror ("syntax error: cannot back up"); YYERROR; }	\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+#ifndef YYPURE
+#define YYLEX		yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int	yychar;			/*  the lookahead symbol		*/
+YYSTYPE	yylval;			/*  the semantic value of the		*/
+				/*  lookahead symbol			*/
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc;			/*  location data for the lookahead	*/
+				/*  symbol				*/
+#endif
+
+int yynerrs;			/*  number of parse errors so far       */
+#endif  /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug;			/*  nonzero means print parse trace	*/
+/* Since this is uninitialized, it does not stop multiple parsers
+   from coexisting.  */
+#endif
+
+/*  YYINITDEPTH indicates the initial size of the parser's stacks	*/
+
+#ifndef	YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/*  YYMAXDEPTH is the maximum size the stacks can grow to
+    (effective only if the built-in stack extension method is used).  */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+int yyparse (void);
+#endif
+
+#if __GNUC__ > 1		/* GNU C and GNU C++ define this.  */
+#define __yy_memcpy(TO,FROM,COUNT)	__builtin_memcpy(TO,FROM,COUNT)
+#else				/* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (to, from, count)
+     char *to;
+     char *from;
+     int count;
+{
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (char *to, char *from, int count)
+{
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 196 "/usr/local/lib/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  register int yystate;
+  register int yyn;
+  register short *yyssp;
+  register YYSTYPE *yyvsp;
+  int yyerrstatus;	/*  number of tokens to shift before error messages enabled */
+  int yychar1 = 0;		/*  lookahead token as an internal (translated) token number */
+
+  short	yyssa[YYINITDEPTH];	/*  the state stack			*/
+  YYSTYPE yyvsa[YYINITDEPTH];	/*  the semantic value stack		*/
+
+  short *yyss = yyssa;		/*  refer to the stacks thru separate pointers */
+  YYSTYPE *yyvs = yyvsa;	/*  to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylsa[YYINITDEPTH];	/*  the location stack			*/
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  int yystacksize = YYINITDEPTH;
+
+#ifdef YYPURE
+  int yychar;
+  YYSTYPE yylval;
+  int yynerrs;
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylloc;
+#endif
+#endif
+
+  YYSTYPE yyval;		/*  the variable used to return		*/
+				/*  semantic values from the action	*/
+				/*  routines				*/
+
+  int yylen;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Starting parse\n");
+#endif
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss - 1;
+  yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in  yystate  .  */
+/* In all cases, when you get here, the value and location stacks
+   have just been pushed. so pushing a state here evens the stacks.  */
+yynewstate:
+
+  *++yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Give user a chance to reallocate the stack */
+      /* Use copies of these so that the &'s don't force the real ones into memory. */
+      YYSTYPE *yyvs1 = yyvs;
+      short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+      YYLTYPE *yyls1 = yyls;
+#endif
+
+      /* Get the current used size of the three stacks, in elements.  */
+      int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      /* Each stack pointer address is followed by the size of
+	 the data in use in that stack, in bytes.  */
+#ifdef YYLSP_NEEDED
+      /* This used to be a conditional around just the two extra args,
+	 but that might be undefined if yyoverflow is a macro.  */
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yyls1, size * sizeof (*yylsp),
+		 &yystacksize);
+#else
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yystacksize);
+#endif
+
+      yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+      yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+	{
+	  yyerror("parser stack overflow");
+	  return 2;
+	}
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+	yystacksize = YYMAXDEPTH;
+      yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+      __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
+      yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+      __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+      yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+      __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + size - 1;
+      yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+      yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+      if (yyssp >= yyss + yystacksize - 1)
+	YYABORT;
+    }
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+  goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Reading a token: ");
+#endif
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)		/* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;		/* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Now at end of input.\n");
+#endif
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+      if (yydebug)
+	{
+	  fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+	  /* Give the individual parser a way to print the precise meaning
+	     of a token, for further debugging info.  */
+#ifdef YYPRINT
+	  YYPRINT (stderr, yychar, yylval);
+#endif
+	  fprintf (stderr, ")\n");
+	}
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrlab;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  /* count tokens shifted since error; after three, turn off error status.  */
+  if (yyerrstatus) yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+/* Do the default action for the current state.  */
+yydefault:
+
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+yyreduce:
+  yylen = yyr2[yyn];
+  if (yylen > 0)
+    yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      int i;
+
+      fprintf (stderr, "Reducing via rule %d (line %d), ",
+	       yyn, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+	fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+
+
+  switch (yyn) {
+
+case 1:
+#line 461 "core/parse-asn1.y"
+{ yyval.intVal = myLineNoG; ;
+    break;}
+case 2:
+#line 466 "core/parse-asn1.y"
+{ modulePtrG->tagDefault = yyvsp[0].intVal; ;
+    break;}
+case 3:
+#line 471 "core/parse-asn1.y"
+{
+         modulePtrG->modId      = yyvsp[-7].moduleId;
+
+         /*
+          * Set exported flags in type/value defs as appropriate
+          */
+         SetExports (modulePtrG, exportListG, exportsParsedG);
+
+         /* clean up */
+
+         /* Free Application tag list */
+         FreeApplTags();
+
+         /*
+          * Add values defined in any parsed object identifiers.
+          * Only the Module name and some macro oids have been parsed,
+          * the rest are just "{...}" strings at this point
+          * (they will be parsed in later)
+          */
+         modulePtrG->valueDefs =
+             AsnListConcat (modulePtrG->valueDefs, oidElmtValDefsG);
+
+         /*
+          * free list head only
+          */
+         Free (oidElmtValDefsG);
+     ;
+    break;}
+case 4:
+#line 501 "core/parse-asn1.y"
+{ yyval.intVal = EXPLICIT_TAGS; ;
+    break;}
+case 5:
+#line 502 "core/parse-asn1.y"
+{ yyval.intVal = IMPLICIT_TAGS; ;
+    break;}
+case 6:
+#line 504 "core/parse-asn1.y"
+{
+        /* default is EXPLICIT TAGS */
+        yyval.intVal = EXPLICIT_TAGS;
+    ;
+    break;}
+case 7:
+#line 512 "core/parse-asn1.y"
+{
+        yyval.moduleId = MT (ModuleId);
+        yyval.moduleId->name = yyvsp[-1].charPtr;
+        yyval.moduleId->oid = yyvsp[0].oidPtr;
+    ;
+    break;}
+case 9:
+#line 521 "core/parse-asn1.y"
+{ yyval.oidPtr = NULL; ;
+    break;}
+case 12:
+#line 531 "core/parse-asn1.y"
+{
+        /*
+         *  allows differentiation between "EXPORTS;"
+         *         (in which no exports allowed)
+         *  and when the EXPORTS symbol does not appear
+         *         (then all are exported)
+         */
+        exportsParsedG = TRUE;
+    ;
+    break;}
+case 13:
+#line 541 "core/parse-asn1.y"
+{
+        PARSE_ERROR();
+        exportsParsedG = FALSE;
+        exportListG = NULL;
+        yyerrok;
+    ;
+    break;}
+case 14:
+#line 547 "core/parse-asn1.y"
+{ exportsParsedG = FALSE; ;
+    break;}
+case 15:
+#line 551 "core/parse-asn1.y"
+{ exportListG = yyvsp[0].exportList; ;
+    break;}
+case 16:
+#line 552 "core/parse-asn1.y"
+{ exportListG = NULL; ;
+    break;}
+case 17:
+#line 557 "core/parse-asn1.y"
+{
+        yyval.exportList = MT (ExportElmt);
+        yyval.exportList->name = yyvsp[0].charPtr;
+        yyval.exportList->lineNo = myLineNoG;
+        yyval.exportList->next = NULL;
+    ;
+    break;}
+case 18:
+#line 564 "core/parse-asn1.y"
+{
+        yyval.exportList = MT (ExportElmt);
+        yyval.exportList->name = yyvsp[0].charPtr;
+        yyval.exportList->next = yyvsp[-3].exportList;
+        yyval.exportList->lineNo = yyvsp[-1].intVal;
+    ;
+    break;}
+case 20:
+#line 575 "core/parse-asn1.y"
+{
+       PARSE_ERROR();
+       yyerrok;
+    ;
+    break;}
+case 22:
+#line 583 "core/parse-asn1.y"
+{ modulePtrG->imports = yyvsp[0].importModuleListPtr; ;
+    break;}
+case 24:
+#line 589 "core/parse-asn1.y"
+{
+        APPEND (yyvsp[0].importModulePtr,yyvsp[-1].importModuleListPtr);
+    ;
+    break;}
+case 25:
+#line 593 "core/parse-asn1.y"
+{
+        yyval.importModuleListPtr = NEWLIST();
+        APPEND (yyvsp[0].importModulePtr, yyval.importModuleListPtr);
+    ;
+    break;}
+case 26:
+#line 601 "core/parse-asn1.y"
+{
+        yyval.importModulePtr = MT (ImportModule);
+        yyval.importModulePtr->modId   = yyvsp[0].moduleId;
+        yyval.importModulePtr->lineNo = yyvsp[-1].intVal;
+        yyval.importModulePtr->importElmts = yyvsp[-3].importElmtListPtr;
+    ;
+    break;}
+case 27:
+#line 612 "core/parse-asn1.y"
+{
+        ImportElmt *ie;
+
+        ie = MT (ImportElmt);
+        ie->name = yyvsp[0].charPtr;
+        ie->lineNo = myLineNoG;
+        APPEND (ie, yyvsp[-2].importElmtListPtr);
+        yyval.importElmtListPtr = yyvsp[-2].importElmtListPtr;
+    ;
+    break;}
+case 28:
+#line 622 "core/parse-asn1.y"
+{
+        ImportElmt *ie;
+
+        /* called for the first element only, so create list head */
+        yyval.importElmtListPtr = NEWLIST();
+        ie = MT (ImportElmt);
+        ie->name = yyvsp[0].charPtr;
+        ie->lineNo = myLineNoG;
+        APPEND (ie, yyval.importElmtListPtr);
+    ;
+    break;}
+case 31:
+#line 638 "core/parse-asn1.y"
+{
+        /*
+         * hack to make DefinedMacroNames "freeable"
+         * like idents and typeref
+         */
+        yyval.charPtr = Malloc (strlen (yyvsp[0].charPtr)+1);
+        strcpy (yyval.charPtr, yyvsp[0].charPtr);
+    ;
+    break;}
+case 36:
+#line 659 "core/parse-asn1.y"
+{
+        PARSE_ERROR();
+        yyerrok;
+    ;
+    break;}
+case 37:
+#line 667 "core/parse-asn1.y"
+{
+        /*
+         * a macro may produce a null type
+         */
+        if (yyvsp[0].typeDefPtr != NULL)
+        {
+            /*
+             * add to head of  type def list
+             */
+            APPEND (yyvsp[0].typeDefPtr, modulePtrG->typeDefs);
+        }
+
+    ;
+    break;}
+case 38:
+#line 681 "core/parse-asn1.y"
+{
+        /*
+         * a macro may produce a null value
+         */
+        if (yyvsp[0].valueDefPtr != NULL)
+        {
+            /*
+             * add to head of value def list
+             */
+            APPEND (yyvsp[0].valueDefPtr, modulePtrG->valueDefs);
+        }
+    ;
+    break;}
+case 39:
+#line 693 "core/parse-asn1.y"
+{ LexBeginMacroDefContext(); ;
+    break;}
+case 40:
+#line 695 "core/parse-asn1.y"
+{
+        TypeDef *tmpTypeDef;
+
+        /*
+         *  LEXICAL TIE IN!!
+         * create macro type to eliminate import resolution
+         * errors msgs from other modules importing the macro.
+         * (hopefully) Only the import list will link with
+         * these type defs.
+         * keeps macro def around incase of future processing needs
+         *
+         * NOTE: MACRODEFBODY_SYM returns the macro def body with
+         * with "BEGIN" at the begininning and "END" at the end
+         */
+
+        /*
+         * put lexical analyzer back in normal state
+         */
+        /*  BEGIN (INITIAL);  */
+        LexBeginInitialContext();
+
+        tmpTypeDef = MT (TypeDef);
+        SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, yyvsp[-2].intVal);
+        tmpTypeDef->definedName = yyvsp[-5].charPtr;
+
+        /*
+         * keeps the macro def body
+         * (all text between & including the BEGIN and END)
+         * as a simple string - incase you want to fart around with
+         * it.
+         */
+        tmpTypeDef->type->basicType->a.macroDef = yyvsp[0].charPtr;
+
+        /*
+         * put in type list
+         */
+        APPEND (tmpTypeDef, modulePtrG->typeDefs);
+
+    ;
+    break;}
+case 41:
+#line 735 "core/parse-asn1.y"
+{
+        TypeDef *tmpTypeDef;
+
+        tmpTypeDef = MT (TypeDef);
+        SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, myLineNoG);
+        tmpTypeDef->definedName = yyvsp[-2].charPtr;
+
+        tmpTypeDef->type->basicType->a.macroDef = yyvsp[0].charPtr;
+
+        /*
+         * put in type list
+         */
+        APPEND (tmpTypeDef, modulePtrG->typeDefs);
+
+    ;
+    break;}
+case 42:
+#line 751 "core/parse-asn1.y"
+{
+        TypeDef *tmpTypeDef;
+
+        tmpTypeDef = MT (TypeDef);
+        SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, myLineNoG);
+        tmpTypeDef->definedName = yyvsp[-4].charPtr;
+
+        tmpTypeDef->type->basicType->a.macroDef =
+               (MyString) Malloc (strlen (yyvsp[-2].charPtr) + strlen (yyvsp[0].charPtr) + 2);
+
+        strcpy (tmpTypeDef->type->basicType->a.macroDef, yyvsp[-2].charPtr);
+        strcat (tmpTypeDef->type->basicType->a.macroDef, ".");
+        strcat (tmpTypeDef->type->basicType->a.macroDef, yyvsp[0].charPtr);
+
+       /*
+         * put in type list
+         */
+        APPEND (tmpTypeDef, modulePtrG->typeDefs);
+
+        Free (yyvsp[-2].charPtr);
+        Free (yyvsp[0].charPtr);
+    ;
+    break;}
+case 45:
+#line 786 "core/parse-asn1.y"
+{
+        /*
+         * a macro type may produce a null type
+         */
+        if (yyvsp[-1].typePtr != NULL)
+        {
+            yyval.typeDefPtr = MT (TypeDef);
+            yyval.typeDefPtr->type =  yyvsp[-1].typePtr;
+            yyval.typeDefPtr->type->lineNo = yyvsp[-2].intVal;
+            yyval.typeDefPtr->type->attrList = yyvsp[0].attrList;
+            yyval.typeDefPtr->definedName = yyvsp[-5].charPtr;
+            yyval.typeDefPtr->attrList = yyvsp[-3].attrList;
+        }
+        else
+            yyval.typeDefPtr = NULL;
+    ;
+    break;}
+case 46:
+#line 807 "core/parse-asn1.y"
+{
+        /* allocate a Type with basic type of ImportTypeRef */
+        SetupType (&yyval.typePtr, BASICTYPE_IMPORTTYPEREF, yyvsp[-1].intVal);
+        yyval.typePtr->basicType->a.importTypeRef = MT (TypeRef);
+        yyval.typePtr->basicType->a.importTypeRef->typeName = yyvsp[0].charPtr;
+        yyval.typePtr->basicType->a.importTypeRef->moduleName = yyvsp[-3].charPtr;
+
+        /* add entry to this module's import list */
+        AddPrivateImportElmt (modulePtrG, yyvsp[0].charPtr, yyvsp[-3].charPtr, yyvsp[-1].intVal);
+    ;
+    break;}
+case 47:
+#line 821 "core/parse-asn1.y"
+{ yyval.typePtr = yyvsp[0].typePtr; ;
+    break;}
+case 48:
+#line 823 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_LOCALTYPEREF, myLineNoG);
+        yyval.typePtr->basicType->a.localTypeRef = MT (TypeRef);
+        yyval.typePtr->basicType->a.localTypeRef->typeName = yyvsp[0].charPtr;
+    ;
+    break;}
+case 68:
+#line 856 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_OCTETSTRING, myLineNoG);
+    ;
+    break;}
+case 69:
+#line 863 "core/parse-asn1.y"
+{
+        yyval.namedTypePtr = MT (NamedType);
+        yyval.namedTypePtr->type = yyvsp[0].typePtr;
+        yyval.namedTypePtr->fieldName = yyvsp[-1].charPtr;
+    ;
+    break;}
+case 70:
+#line 869 "core/parse-asn1.y"
+{
+        yyval.namedTypePtr = MT (NamedType);
+        yyval.namedTypePtr->type = yyvsp[0].typePtr;
+    ;
+    break;}
+case 71:
+#line 877 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_BOOLEAN, myLineNoG);
+    ;
+    break;}
+case 72:
+#line 884 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_INTEGER, myLineNoG);
+        yyval.typePtr->basicType->a.integer = NEWLIST();  /* empty list */
+    ;
+    break;}
+case 73:
+#line 889 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_INTEGER, myLineNoG);
+        yyval.typePtr->basicType->a.integer = yyvsp[-1].valueDefListPtr;
+    ;
+    break;}
+case 74:
+#line 898 "core/parse-asn1.y"
+{
+        yyval.valueDefListPtr = NEWLIST();
+        APPEND (yyvsp[0].valueDefPtr, yyval.valueDefListPtr);
+    ;
+    break;}
+case 75:
+#line 903 "core/parse-asn1.y"
+{
+        APPEND (yyvsp[0].valueDefPtr,yyvsp[-2].valueDefListPtr);
+        yyval.valueDefListPtr = yyvsp[-2].valueDefListPtr;
+    ;
+    break;}
+case 76:
+#line 911 "core/parse-asn1.y"
+{
+        yyval.valueDefPtr = MT (ValueDef);
+        yyval.valueDefPtr->definedName = yyvsp[-3].charPtr;
+        SetupValue (&yyval.valueDefPtr->value, BASICVALUE_INTEGER, myLineNoG);
+        yyval.valueDefPtr->value->basicValue->a.integer = yyvsp[-1].intVal;
+    ;
+    break;}
+case 77:
+#line 918 "core/parse-asn1.y"
+{
+        yyval.valueDefPtr = MT (ValueDef);
+        yyval.valueDefPtr->definedName = yyvsp[-3].charPtr;
+        yyval.valueDefPtr->value = yyvsp[-1].valuePtr;
+    ;
+    break;}
+case 78:
+#line 927 "core/parse-asn1.y"
+{
+	if (yyvsp[0].uintVal>0x7FFFFFFF) {
+	    yyerror("Warning: positive signed number out of range");
+	    yyval.intVal = 0x7FFFFFFF;
+	}
+    ;
+    break;}
+case 79:
+#line 934 "core/parse-asn1.y"
+{
+	yyerror ("Warning: positive signed number out of range");
+	yyval.intVal = 0x7FFFFFFF;
+	/* modulePtrG->status = MOD_ERROR; */
+    ;
+    break;}
+case 80:
+#line 940 "core/parse-asn1.y"
+{
+	if (yyvsp[0].uintVal>0x80000000) {
+	    yyerror("Warning: negative signed number out of range");
+	    yyval.intVal = -0x80000000;
+	} else if (yyvsp[0].uintVal==0x80000000) {
+	    yyval.intVal = -0x80000000;
+	} else {
+	    yyval.intVal = -yyvsp[0].uintVal;
+	}
+    ;
+    break;}
+case 81:
+#line 951 "core/parse-asn1.y"
+{
+	yyerror ("Warning: negative signed number out of range");
+	yyval.intVal = -0x80000000;
+	/* modulePtrG->status = MOD_ERROR; */
+    ;
+    break;}
+case 82:
+#line 960 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_ENUMERATED, myLineNoG);
+        yyval.typePtr->basicType->a.enumerated = yyvsp[-1].valueDefListPtr;
+    ;
+    break;}
+case 83:
+#line 969 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_REAL, myLineNoG);
+    ;
+    break;}
+case 84:
+#line 976 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_BITSTRING, myLineNoG);
+        yyval.typePtr->basicType->a.bitString = NEWLIST(); /* empty list */
+    ;
+    break;}
+case 85:
+#line 981 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_BITSTRING, myLineNoG);
+        yyval.typePtr->basicType->a.bitString = yyvsp[-1].valueDefListPtr;
+    ;
+    break;}
+case 87:
+#line 995 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_NULL, myLineNoG);
+    ;
+    break;}
+case 88:
+#line 1002 "core/parse-asn1.y"
+{ yyval.intVal = yyvsp[-1].intVal; ;
+    break;}
+case 89:
+#line 1007 "core/parse-asn1.y"
+{
+        NamedType *n;
+
+        SetupType (&yyval.typePtr, BASICTYPE_SEQUENCE, yyvsp[-2].intVal);
+
+        if (AsnListCount ((AsnList*)yyvsp[-1].namedTypeListPtr) != 0)
+        {
+            n = (NamedType*) FIRST_LIST_ELMT ((AsnList*)yyvsp[-1].namedTypeListPtr);
+            n->type->lineNo = yyvsp[-2].intVal;
+        }
+
+        yyval.typePtr->basicType->a.sequence = yyvsp[-1].namedTypeListPtr;
+
+    ;
+    break;}
+case 90:
+#line 1022 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_SEQUENCE, yyvsp[-1].intVal);
+
+        /* set up empty list for SEQ with no elmts */
+        yyval.typePtr->basicType->a.sequence = AsnListNew (sizeof (void*));
+    ;
+    break;}
+case 91:
+#line 1037 "core/parse-asn1.y"
+{
+        NamedType *lastElmt;
+
+        if (yyvsp[0].attrList != NULL)
+        {
+            lastElmt = (NamedType*)LAST_LIST_ELMT (yyvsp[-1].namedTypeListPtr);
+            lastElmt->type->attrList = yyvsp[0].attrList;
+        }
+        yyval.namedTypeListPtr = yyvsp[-1].namedTypeListPtr;
+    ;
+    break;}
+case 92:
+#line 1051 "core/parse-asn1.y"
+{
+        yyval.namedTypeListPtr = NEWLIST();
+        APPEND (yyvsp[0].namedTypePtr,yyval.namedTypeListPtr);
+    ;
+    break;}
+case 93:
+#line 1056 "core/parse-asn1.y"
+{
+        NamedType *lastElmt;
+
+        if (yyvsp[-2].attrList != NULL)
+        {
+            lastElmt = (NamedType*)LAST_LIST_ELMT (yyvsp[-4].namedTypeListPtr);
+            lastElmt->type->attrList = yyvsp[-2].attrList;
+        }
+
+       APPEND (yyvsp[0].namedTypePtr, yyvsp[-4].namedTypeListPtr);
+       lastElmt = (NamedType*)LAST_LIST_ELMT (yyvsp[-4].namedTypeListPtr);
+       lastElmt->type->lineNo = yyvsp[-1].intVal;
+       yyval.namedTypeListPtr = yyvsp[-4].namedTypeListPtr;
+    ;
+    break;}
+case 95:
+#line 1075 "core/parse-asn1.y"
+{
+        yyval.namedTypePtr = yyvsp[-1].namedTypePtr;
+        yyval.namedTypePtr->type->optional = TRUE;
+    ;
+    break;}
+case 96:
+#line 1080 "core/parse-asn1.y"
+{
+        /*
+         * this rules uses NamedValue instead of Value
+         * for the stupid choice value syntax (fieldname value)
+         * it should be like a set/seq value (ie with
+         * enclosing { }
+         */
+        yyval.namedTypePtr = yyvsp[-2].namedTypePtr;
+        yyval.namedTypePtr->type->defaultVal = yyvsp[0].namedValuePtr;
+        /*
+         * could link value to the elmt type here (done in link_types.c)
+         */
+    ;
+    break;}
+case 97:
+#line 1094 "core/parse-asn1.y"
+{
+        yyval.namedTypePtr = MT (NamedType);
+        SetupType (&yyval.namedTypePtr->type, BASICTYPE_COMPONENTSOF, myLineNoG);
+        yyval.namedTypePtr->type->basicType->a.componentsOf = yyvsp[0].typePtr;
+    ;
+    break;}
+case 98:
+#line 1100 "core/parse-asn1.y"
+{
+        yyval.namedTypePtr = MT (NamedType);
+        SetupType (&yyval.namedTypePtr->type, BASICTYPE_COMPONENTSOF, myLineNoG);
+        yyval.namedTypePtr->fieldName = yyvsp[-3].charPtr;
+        yyval.namedTypePtr->type->basicType->a.componentsOf = yyvsp[0].typePtr;
+    ;
+    break;}
+case 99:
+#line 1112 "core/parse-asn1.y"
+{
+        NamedType *n;
+
+        /* does not use SEQUENCE == SEQ OF ANY abrev*/
+        SetupType (&yyval.typePtr, BASICTYPE_SEQUENCEOF, myLineNoG);
+
+        /* grab line number from first elmt */
+        if (yyvsp[0].typePtr != NULL)
+            yyval.typePtr->lineNo = yyvsp[0].typePtr->lineNo - 1;
+
+        yyval.typePtr->basicType->a.sequenceOf = yyvsp[0].typePtr;
+    ;
+    break;}
+case 100:
+#line 1127 "core/parse-asn1.y"
+{ yyval.intVal = yyvsp[-1].intVal; ;
+    break;}
+case 101:
+#line 1132 "core/parse-asn1.y"
+{
+        NamedType *n;
+
+        SetupType (&yyval.typePtr, BASICTYPE_SET, yyvsp[-2].intVal);
+
+        /* reset first elmt's line number */
+        if (AsnListCount ((AsnList*)yyvsp[-1].namedTypeListPtr) != 0)
+        {
+            n = (NamedType*)FIRST_LIST_ELMT ((AsnList*)yyvsp[-1].namedTypeListPtr);
+            n->type->lineNo = yyvsp[-2].intVal;
+        }
+        yyval.typePtr->basicType->a.set = yyvsp[-1].namedTypeListPtr;
+    ;
+    break;}
+case 102:
+#line 1146 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_SET, yyvsp[-1].intVal);
+
+        /* set up empty elmt list for SET */
+        yyval.typePtr->basicType->a.set = AsnListNew (sizeof (void*));
+    ;
+    break;}
+case 103:
+#line 1162 "core/parse-asn1.y"
+{
+       /* does not allow SET == SET OF ANY Abrev */
+        SetupType (&yyval.typePtr, BASICTYPE_SETOF, myLineNoG);
+
+        if (yyvsp[0].typePtr != NULL)
+            yyval.typePtr->lineNo = yyvsp[0].typePtr->lineNo;
+
+        yyval.typePtr->basicType->a.setOf = yyvsp[0].typePtr;
+    ;
+    break;}
+case 104:
+#line 1176 "core/parse-asn1.y"
+{
+        NamedType *n;
+
+        SetupType (&yyval.typePtr, BASICTYPE_CHOICE, yyvsp[-3].intVal);
+
+        yyval.typePtr->basicType->a.choice = yyvsp[-1].namedTypeListPtr;
+
+        if (AsnListCount (yyvsp[-1].namedTypeListPtr) != 0)
+        {
+            n = (NamedType*)FIRST_LIST_ELMT (yyvsp[-1].namedTypeListPtr);
+            n->type->lineNo = yyvsp[-3].intVal;
+        }
+    ;
+    break;}
+case 105:
+#line 1193 "core/parse-asn1.y"
+{
+        NamedType *lastElmt;
+        if (yyvsp[0].attrList != NULL)
+        {
+            lastElmt = (NamedType*)LAST_LIST_ELMT (yyvsp[-1].namedTypeListPtr);
+            lastElmt->type->attrList = yyvsp[0].attrList;
+        }
+        yyval.namedTypeListPtr = yyvsp[-1].namedTypeListPtr;
+    ;
+    break;}
+case 106:
+#line 1206 "core/parse-asn1.y"
+{
+        yyval.namedTypeListPtr = NEWLIST();
+        APPEND (yyvsp[0].namedTypePtr, yyval.namedTypeListPtr);
+    ;
+    break;}
+case 107:
+#line 1211 "core/parse-asn1.y"
+{
+        NamedType *lastElmt;
+
+        if (yyvsp[-1].attrList != NULL)
+        {
+            lastElmt = (NamedType*)LAST_LIST_ELMT (yyvsp[-3].namedTypeListPtr);
+            lastElmt->type->attrList = yyvsp[-1].attrList;
+        }
+        APPEND (yyvsp[0].namedTypePtr,yyvsp[-3].namedTypeListPtr);
+        yyval.namedTypeListPtr = yyvsp[-3].namedTypeListPtr;
+    ;
+    break;}
+case 108:
+#line 1227 "core/parse-asn1.y"
+{
+        /*
+         * the selection type should be replaced after
+         * link with actual type
+         */
+        SetupType (&yyval.typePtr, BASICTYPE_SELECTION, myLineNoG);
+
+        yyval.typePtr->basicType->a.selection = MT (SelectionType);
+        yyval.typePtr->basicType->a.selection->typeRef = yyvsp[0].typePtr;
+        yyval.typePtr->basicType->a.selection->fieldName = yyvsp[-2].charPtr;
+    ;
+    break;}
+case 109:
+#line 1242 "core/parse-asn1.y"
+{
+        Tag *tag;
+
+        /* remove next tag if any  && IMPLICIT_TAGS */
+ 	if ((modulePtrG->tagDefault == IMPLICIT_TAGS) &&
+            (yyvsp[0].typePtr->tags != NULL) && !LIST_EMPTY (yyvsp[0].typePtr->tags))
+        {
+            tag = (Tag*)FIRST_LIST_ELMT (yyvsp[0].typePtr->tags); /* set curr to first */
+	    AsnListFirst (yyvsp[0].typePtr->tags); /* set curr to first elmt */
+            AsnListRemove (yyvsp[0].typePtr->tags);      /* remove first elmt */
+
+            /*
+             * set implicit if implicitly tagged built in type (ie not ref)
+             * (this simplifies the module ASN.1 printer (print.c))
+             */
+            if (tag->tclass == UNIV)
+                 yyvsp[0].typePtr->implicit = TRUE;
+
+            Free (tag);
+        }
+
+        PREPEND (yyvsp[-1].tagPtr, yyvsp[0].typePtr->tags);
+        yyval.typePtr = yyvsp[0].typePtr;
+    ;
+    break;}
+case 110:
+#line 1267 "core/parse-asn1.y"
+{
+        Tag *tag;
+
+        /* remove next tag if any */
+ 	if ((yyvsp[0].typePtr->tags != NULL) && !LIST_EMPTY (yyvsp[0].typePtr->tags))
+        {
+            tag = (Tag*)FIRST_LIST_ELMT (yyvsp[0].typePtr->tags); /* set curr to first */
+	    AsnListFirst (yyvsp[0].typePtr->tags); /* set curr to first elmt */
+            AsnListRemove (yyvsp[0].typePtr->tags);      /* remove first elmt */
+
+            if (tag->tclass == UNIV)
+                 yyvsp[0].typePtr->implicit = TRUE;
+
+            Free (tag);
+        }
+
+        /*
+         * must check after linking that implicitly tagged
+         * local/import type refs are not untagged choice/any etc
+         */
+        else if ((yyvsp[0].typePtr->basicType->choiceId == BASICTYPE_IMPORTTYPEREF) ||
+                 (yyvsp[0].typePtr->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+                 (yyvsp[0].typePtr->basicType->choiceId == BASICTYPE_SELECTION))
+            yyvsp[0].typePtr->implicit = TRUE;
+
+        /*
+         *  all other implicitly tagable types should have tags
+         *  to remove - if this else clause fires then it is
+         *  probably a CHOICE or ANY type
+         */
+        else
+        {
+            PrintErrLoc (modulePtrG->asn1SrcFileName, yyvsp[0].typePtr->lineNo);
+            fprintf (stderr, "ERROR - attempt to implicitly reference untagged type\n");
+            smallErrG = 1;
+        }
+
+        PREPEND (yyvsp[-2].tagPtr, yyvsp[0].typePtr->tags);
+        yyval.typePtr = yyvsp[0].typePtr;
+    ;
+    break;}
+case 111:
+#line 1308 "core/parse-asn1.y"
+{
+        /* insert tag at head of list */
+        yyvsp[-2].tagPtr->explicit = TRUE;
+        PREPEND (yyvsp[-2].tagPtr, yyvsp[0].typePtr->tags);
+        yyval.typePtr = yyvsp[0].typePtr;
+    ;
+    break;}
+case 112:
+#line 1318 "core/parse-asn1.y"
+{
+        yyval.tagPtr = yyvsp[-1].tagPtr;
+        yyval.tagPtr->tclass = yyvsp[-2].intVal;
+        yyval.tagPtr->explicit = FALSE; /* default to false */
+
+        /*
+         *  keep track of APPLICATION Tags per module
+         *  should only be used once
+         */
+        if (yyvsp[-2].intVal == APPL)
+        {
+            PushApplTag (yyval.tagPtr->code, myLineNoG);
+        }
+    ;
+    break;}
+case 113:
+#line 1336 "core/parse-asn1.y"
+{
+        yyval.tagPtr = MT (Tag);
+        yyval.tagPtr->code = yyvsp[0].intVal;
+    ;
+    break;}
+case 114:
+#line 1341 "core/parse-asn1.y"
+{
+        yyval.tagPtr = MT (Tag);
+        yyval.tagPtr->code = NO_TAG_CODE;
+        yyval.tagPtr->valueRef = yyvsp[0].valuePtr;
+    ;
+    break;}
+case 115:
+#line 1349 "core/parse-asn1.y"
+{ yyval.intVal = UNIV; ;
+    break;}
+case 116:
+#line 1350 "core/parse-asn1.y"
+{ yyval.intVal = APPL; ;
+    break;}
+case 117:
+#line 1351 "core/parse-asn1.y"
+{ yyval.intVal = PRIV; ;
+    break;}
+case 118:
+#line 1352 "core/parse-asn1.y"
+{ yyval.intVal = CNTX; ;
+    break;}
+case 119:
+#line 1358 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_ANY, myLineNoG);
+    ;
+    break;}
+case 120:
+#line 1362 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_ANYDEFINEDBY, myLineNoG);
+        yyval.typePtr->basicType->a.anyDefinedBy = MT (AnyDefinedByType);
+        yyval.typePtr->basicType->a.anyDefinedBy->fieldName = yyvsp[0].charPtr;
+    ;
+    break;}
+case 121:
+#line 1372 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_OID, myLineNoG);
+    ;
+    break;}
+case 122:
+#line 1380 "core/parse-asn1.y"
+{
+        /*
+         * append new subtype list to existing one (s) if any
+         * with AND relation
+         */
+        AppendSubtype (&yyvsp[-1].typePtr->subtypes, yyvsp[0].subtypePtr, SUBTYPE_AND);
+        yyval.typePtr = yyvsp[-1].typePtr;
+    ;
+    break;}
+case 123:
+#line 1389 "core/parse-asn1.y"
+{
+        Subtype *s;
+
+        SetupType (&yyval.typePtr, BASICTYPE_SETOF, myLineNoG);
+        yyval.typePtr->basicType->a.setOf = yyvsp[0].typePtr;
+
+        /* add size constraint */
+        s = MT (Subtype);
+        s->choiceId = SUBTYPE_SINGLE;
+        s->a.single = yyvsp[-2].subtypeValuePtr;
+        AppendSubtype (&yyval.typePtr->subtypes, s, SUBTYPE_AND);
+    ;
+    break;}
+case 124:
+#line 1402 "core/parse-asn1.y"
+{
+        Subtype *s;
+
+        SetupType (&yyval.typePtr, BASICTYPE_SEQUENCEOF, myLineNoG);
+        yyval.typePtr->basicType->a.sequenceOf = yyvsp[0].typePtr;
+
+        /* add size constraint */
+        s = MT (Subtype);
+        s->choiceId = SUBTYPE_SINGLE;
+        s->a.single = yyvsp[-2].subtypeValuePtr;
+        AppendSubtype (&yyval.typePtr->subtypes, s, SUBTYPE_AND);
+    ;
+    break;}
+case 125:
+#line 1419 "core/parse-asn1.y"
+{
+        yyval.subtypePtr = yyvsp[-1].subtypePtr;
+    ;
+    break;}
+case 126:
+#line 1426 "core/parse-asn1.y"
+{
+        Subtype *s;
+
+        /* OR relation between all elmts of in  ValueSetList */
+
+        yyval.subtypePtr = MT (Subtype);
+        yyval.subtypePtr->choiceId = SUBTYPE_OR;
+        yyval.subtypePtr->a.or = NEWLIST();
+
+        s = MT (Subtype);
+        s->choiceId = SUBTYPE_SINGLE;
+        s->a.single = yyvsp[0].subtypeValuePtr;
+        APPEND (s, yyval.subtypePtr->a.or);
+    ;
+    break;}
+case 127:
+#line 1441 "core/parse-asn1.y"
+{
+        Subtype *s;
+        s = MT (Subtype);
+        s->choiceId = SUBTYPE_SINGLE;
+        s->a.single = yyvsp[0].subtypeValuePtr;
+        APPEND (s, yyvsp[-2].subtypePtr->a.or);
+        yyval.subtypePtr = yyvsp[-2].subtypePtr;
+    ;
+    break;}
+case 134:
+#line 1463 "core/parse-asn1.y"
+{
+        yyval.subtypeValuePtr = MT (SubtypeValue);
+        yyval.subtypeValuePtr->choiceId = SUBTYPEVALUE_SINGLEVALUE;
+        yyval.subtypeValuePtr->a.singleValue = yyvsp[0].valuePtr;
+    ;
+    break;}
+case 135:
+#line 1471 "core/parse-asn1.y"
+{
+        yyval.subtypeValuePtr = MT (SubtypeValue);
+        yyval.subtypeValuePtr->choiceId = SUBTYPEVALUE_CONTAINED;
+        yyval.subtypeValuePtr->a.contained = yyvsp[0].typePtr;
+    ;
+    break;}
+case 136:
+#line 1480 "core/parse-asn1.y"
+{
+        yyval.subtypeValuePtr = MT (SubtypeValue);
+        yyval.subtypeValuePtr->choiceId = SUBTYPEVALUE_VALUERANGE;
+        yyval.subtypeValuePtr->a.valueRange = MT (ValueRangeSubtype);
+        yyval.subtypeValuePtr->a.valueRange->lowerEndInclusive =
+            valueRangeLowerEndInclusiveG;
+        yyval.subtypeValuePtr->a.valueRange->upperEndInclusive =
+            valueRangeUpperEndInclusiveG;
+        yyval.subtypeValuePtr->a.valueRange->lowerEndValue  = yyvsp[-3].valuePtr;
+        yyval.subtypeValuePtr->a.valueRange->upperEndValue = yyvsp[0].valuePtr;
+    ;
+    break;}
+case 137:
+#line 1495 "core/parse-asn1.y"
+{
+       yyval.valuePtr = yyvsp[0].valuePtr;
+       valueRangeLowerEndInclusiveG = TRUE;
+    ;
+    break;}
+case 138:
+#line 1500 "core/parse-asn1.y"
+{
+       yyval.valuePtr = yyvsp[-1].valuePtr;
+       valueRangeLowerEndInclusiveG = FALSE;
+    ;
+    break;}
+case 139:
+#line 1508 "core/parse-asn1.y"
+{
+       yyval.valuePtr = yyvsp[0].valuePtr;
+       valueRangeUpperEndInclusiveG = TRUE;
+    ;
+    break;}
+case 140:
+#line 1513 "core/parse-asn1.y"
+{
+       yyval.valuePtr = yyvsp[0].valuePtr;
+       valueRangeUpperEndInclusiveG = FALSE;
+    ;
+    break;}
+case 141:
+#line 1520 "core/parse-asn1.y"
+{ yyval.valuePtr = yyvsp[0].valuePtr; ;
+    break;}
+case 142:
+#line 1522 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_SPECIALINTEGER, myLineNoG);
+        yyval.valuePtr->basicValue->a.specialInteger =  MIN_INT;
+    ;
+    break;}
+case 143:
+#line 1529 "core/parse-asn1.y"
+{ yyval.valuePtr = yyvsp[0].valuePtr; ;
+    break;}
+case 144:
+#line 1531 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_SPECIALINTEGER, myLineNoG);
+        yyval.valuePtr->basicValue->a.specialInteger =  MAX_INT;
+    ;
+    break;}
+case 145:
+#line 1539 "core/parse-asn1.y"
+{
+        yyval.subtypeValuePtr = MT (SubtypeValue);
+        yyval.subtypeValuePtr->choiceId = SUBTYPEVALUE_SIZECONSTRAINT;
+        yyval.subtypeValuePtr->a.sizeConstraint = yyvsp[0].subtypePtr;
+    ;
+    break;}
+case 146:
+#line 1549 "core/parse-asn1.y"
+{
+        yyval.subtypeValuePtr = MT (SubtypeValue);
+        yyval.subtypeValuePtr->choiceId = SUBTYPEVALUE_PERMITTEDALPHABET;
+        yyval.subtypeValuePtr->a.permittedAlphabet = yyvsp[0].subtypePtr;
+    ;
+    break;}
+case 147:
+#line 1558 "core/parse-asn1.y"
+{
+        yyval.subtypeValuePtr = MT (SubtypeValue);
+        yyval.subtypeValuePtr->choiceId = SUBTYPEVALUE_INNERSUBTYPE;
+        yyval.subtypeValuePtr->a.innerSubtype = yyvsp[0].innerSubtypePtr;
+    ;
+    break;}
+case 148:
+#line 1564 "core/parse-asn1.y"
+{
+        yyval.subtypeValuePtr = MT (SubtypeValue);
+        yyval.subtypeValuePtr->choiceId = SUBTYPEVALUE_INNERSUBTYPE;
+        yyval.subtypeValuePtr->a.innerSubtype = yyvsp[0].innerSubtypePtr;
+    ;
+    break;}
+case 149:
+#line 1573 "core/parse-asn1.y"
+{
+        Constraint *constraint;
+
+        /* this constrains the elmt of setof or seq of */
+        yyval.innerSubtypePtr = MT (InnerSubtype);
+        yyval.innerSubtypePtr->constraintType = SINGLE_CT;
+        yyval.innerSubtypePtr->constraints = NEWLIST();
+        constraint = MT (Constraint);
+        APPEND (constraint, yyval.innerSubtypePtr->constraints);
+        constraint->valueConstraints = yyvsp[0].subtypePtr;
+    ;
+    break;}
+case 152:
+#line 1593 "core/parse-asn1.y"
+{
+        yyval.innerSubtypePtr = MT (InnerSubtype);
+        yyval.innerSubtypePtr->constraintType = FULL_CT;
+        yyval.innerSubtypePtr->constraints = yyvsp[-1].constraintListPtr;
+    ;
+    break;}
+case 153:
+#line 1602 "core/parse-asn1.y"
+{
+        yyval.innerSubtypePtr = MT (InnerSubtype);
+        yyval.innerSubtypePtr->constraintType = PARTIAL_CT;
+        yyval.innerSubtypePtr->constraints = yyvsp[-1].constraintListPtr;
+    ;
+    break;}
+case 154:
+#line 1612 "core/parse-asn1.y"
+{
+        yyval.constraintListPtr = NEWLIST();
+        APPEND (yyvsp[0].constraintPtr, yyval.constraintListPtr);
+    ;
+    break;}
+case 155:
+#line 1617 "core/parse-asn1.y"
+{
+        APPEND (yyvsp[0].constraintPtr, yyvsp[-2].constraintListPtr);
+        yyval.constraintListPtr = yyvsp[-2].constraintListPtr;
+    ;
+    break;}
+case 156:
+#line 1625 "core/parse-asn1.y"
+{
+        yyval.constraintPtr = yyvsp[0].constraintPtr;
+        yyval.constraintPtr->fieldRef = yyvsp[-1].charPtr;
+    ;
+    break;}
+case 158:
+#line 1635 "core/parse-asn1.y"
+{
+        yyval.constraintPtr = MT (Constraint);
+        yyval.constraintPtr->presenceConstraint = yyvsp[0].intVal;
+        yyval.constraintPtr->valueConstraints = yyvsp[-1].subtypePtr;
+    ;
+    break;}
+case 159:
+#line 1643 "core/parse-asn1.y"
+{ yyval.subtypePtr = yyvsp[0].subtypePtr; ;
+    break;}
+case 160:
+#line 1644 "core/parse-asn1.y"
+{ yyval.subtypePtr = NULL; ;
+    break;}
+case 161:
+#line 1648 "core/parse-asn1.y"
+{ yyval.intVal = PRESENT_CT; ;
+    break;}
+case 162:
+#line 1649 "core/parse-asn1.y"
+{ yyval.intVal = ABSENT_CT; ;
+    break;}
+case 163:
+#line 1650 "core/parse-asn1.y"
+{ yyval.intVal = EMPTY_CT; ;
+    break;}
+case 164:
+#line 1651 "core/parse-asn1.y"
+{ yyval.intVal = OPTIONAL_CT; ;
+    break;}
+case 165:
+#line 1665 "core/parse-asn1.y"
+{
+        yyval.valueDefPtr = MT (ValueDef);
+        yyval.valueDefPtr->definedName = yyvsp[-4].charPtr;
+        yyval.valueDefPtr->value = yyvsp[0].valuePtr;
+        yyval.valueDefPtr->value->lineNo = yyvsp[-1].intVal;
+        yyval.valueDefPtr->value->type = yyvsp[-3].typePtr;
+    ;
+    break;}
+case 168:
+#line 1681 "core/parse-asn1.y"
+{ yyval.valuePtr =  yyvsp[0].valuePtr; ;
+    break;}
+case 169:
+#line 1683 "core/parse-asn1.y"
+{
+        /*
+         * for parse, may be set to BASICVALUE_IMPORTEDTYPEREF
+         * by linker
+         */
+        SetupValue (&yyval.valuePtr, BASICVALUE_LOCALVALUEREF, myLineNoG);
+        yyval.valuePtr->basicValue->a.localValueRef = MT (ValueRef);
+        yyval.valuePtr->basicValue->a.localValueRef->valueName = yyvsp[0].charPtr;
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+   ;
+    break;}
+case 170:
+#line 1697 "core/parse-asn1.y"
+{
+        /* Alloc value with basicValue of importValueRef */
+        SetupValue (&yyval.valuePtr, BASICVALUE_IMPORTVALUEREF, yyvsp[-1].intVal);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.importValueRef = MT (ValueRef);
+        yyval.valuePtr->basicValue->a.importValueRef->valueName = yyvsp[0].charPtr;
+        yyval.valuePtr->basicValue->a.importValueRef->moduleName = yyvsp[-3].charPtr;
+
+        /* add entry to this module's import list */
+        AddPrivateImportElmt (modulePtrG, yyvsp[0].charPtr, yyvsp[-3].charPtr, yyvsp[-1].intVal);
+    ;
+    break;}
+case 174:
+#line 1715 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_INTEGER, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.integer = yyvsp[0].intVal;
+    ;
+    break;}
+case 175:
+#line 1721 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_ASCIIHEX, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.asciiHex = MT (AsnOcts);
+        yyval.valuePtr->basicValue->a.asciiHex->octs = yyvsp[0].charPtr;
+        yyval.valuePtr->basicValue->a.asciiHex->octetLen = strlen (yyvsp[0].charPtr);
+    ;
+    break;}
+case 176:
+#line 1729 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_ASCIIBITSTRING, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.asciiBitString = MT (AsnOcts);
+        yyval.valuePtr->basicValue->a.asciiBitString->octs = yyvsp[0].charPtr;
+        yyval.valuePtr->basicValue->a.asciiBitString->octetLen = strlen (yyvsp[0].charPtr);
+    ;
+    break;}
+case 177:
+#line 1737 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_ASCIITEXT, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.asciiText = MT (AsnOcts);
+        yyval.valuePtr->basicValue->a.asciiText->octs = yyvsp[0].charPtr;
+        yyval.valuePtr->basicValue->a.asciiText->octetLen = strlen (yyvsp[0].charPtr);
+    ;
+    break;}
+case 178:
+#line 1744 "core/parse-asn1.y"
+{ LexBeginBraceBalContext(); ;
+    break;}
+case 179:
+#line 1745 "core/parse-asn1.y"
+{
+        /*
+         *  LEXICAL TIE IN!!
+         * string returned by BRACEBAL_SYM has
+         * the $1 '{' prepended and includes everything
+         * upto and including '}' that balances $1
+         */
+        LexBeginInitialContext();
+        SetupValue (&yyval.valuePtr, BASICVALUE_VALUENOTATION, myLineNoG);
+        yyval.valuePtr->basicValue->a.valueNotation = MT (AsnOcts);
+        yyval.valuePtr->basicValue->a.valueNotation->octs = yyvsp[0].charPtr;
+        yyval.valuePtr->basicValue->a.valueNotation->octetLen = strlen (yyvsp[0].charPtr);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+    ;
+    break;}
+case 180:
+#line 1763 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_BOOLEAN, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.boolean =  TRUE;
+    ;
+    break;}
+case 181:
+#line 1769 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_BOOLEAN, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.boolean = FALSE;
+    ;
+    break;}
+case 182:
+#line 1779 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_SPECIALREAL, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.specialReal =  PLUS_INFINITY_REAL;
+    ;
+    break;}
+case 183:
+#line 1785 "core/parse-asn1.y"
+{
+        SetupValue (&yyval.valuePtr, BASICVALUE_SPECIALREAL, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+        yyval.valuePtr->basicValue->a.specialReal = MINUS_INFINITY_REAL;
+    ;
+    break;}
+case 184:
+#line 1796 "core/parse-asn1.y"
+{
+        /* create a NULL value  */
+        SetupValue (&yyval.valuePtr, BASICVALUE_NULL, myLineNoG);
+        yyval.valuePtr->valueType = BASICTYPE_UNKNOWN;
+    ;
+    break;}
+case 185:
+#line 1806 "core/parse-asn1.y"
+{
+        yyval.namedValuePtr = MT (NamedValue);
+        yyval.namedValuePtr->value = yyvsp[0].valuePtr;
+    ;
+    break;}
+case 186:
+#line 1811 "core/parse-asn1.y"
+{
+        yyval.namedValuePtr = MT (NamedValue);
+        yyval.namedValuePtr->value = yyvsp[0].valuePtr;
+        yyval.namedValuePtr->fieldName = yyvsp[-1].charPtr;
+    ;
+    break;}
+case 187:
+#line 1821 "core/parse-asn1.y"
+{
+        /*
+         * example OID setup
+         *
+         * for { ccitt foo (1) bar bell (bunt) 2 }
+         *
+         * ccitt
+         *   - arcnum is set to number from oid table (oid.c)
+         * foo (1)
+         *   - sets up a new value def foo defined as 1
+         *   - makes oid valueref a value ref to foo (doesn't link it tho)
+         * bar
+         *   - makes oid valueref a value ref to bar (doesn't link it tho)
+         * bell (bunt)
+         *   - sets up a new value def bell defined as a val ref to bunt
+         *   - makes oid valueref a value ref to bell (doesn't link it tho)
+         * 2
+         *  - arcnum is set to 2
+         */
+
+        yyval.oidPtr = yyvsp[-1].oidPtr;
+    ;
+    break;}
+case 188:
+#line 1848 "core/parse-asn1.y"
+{
+        OID *o;
+        /* append component */
+        for (o = yyvsp[-1].oidPtr; o->next != NULL; o = o->next)
+	    ;
+        o->next = yyvsp[0].oidPtr;
+        yyval.oidPtr = yyvsp[-1].oidPtr;
+    ;
+    break;}
+case 191:
+#line 1864 "core/parse-asn1.y"
+{
+        Value *newVal;
+        /*
+         * if the arcName is a defined arc name like
+         * ccitt or iso etc, fill in the arc number.
+         * otherwise make a value ref to that named value
+         */
+        yyval.oidPtr = MT (OID);
+
+        yyval.oidPtr->arcNum = OidArcNameToNum (yyvsp[0].charPtr);
+        if (yyval.oidPtr->arcNum == NULL_OID_ARCNUM)
+        {
+            /* set up value ref to named value */
+            SetupValue (&newVal, BASICVALUE_LOCALVALUEREF, myLineNoG);
+            newVal->basicValue->a.localValueRef = MT (ValueRef);
+            newVal->valueType = BASICTYPE_INTEGER;
+            newVal->basicValue->a.localValueRef->valueName = yyvsp[0].charPtr;
+            yyval.oidPtr->valueRef = newVal;
+        }
+    ;
+    break;}
+case 193:
+#line 1890 "core/parse-asn1.y"
+{
+        yyval.oidPtr = MT (OID);
+        yyval.oidPtr->arcNum = yyvsp[0].intVal;
+    ;
+    break;}
+case 195:
+#line 1903 "core/parse-asn1.y"
+{
+        Value *newVal;
+
+        yyval.oidPtr = yyvsp[-1].oidPtr;
+
+        /* shared refs to named numbers name */
+        SetupValue (&newVal, BASICVALUE_INTEGER, myLineNoG);
+        newVal->basicValue->a.integer = yyval.oidPtr->arcNum;
+        newVal->valueType = BASICTYPE_INTEGER;
+        AddNewValueDef (oidElmtValDefsG, yyvsp[-3].charPtr, newVal);
+
+        SetupValue (&newVal, BASICVALUE_LOCALVALUEREF, myLineNoG);
+        newVal->basicValue->a.localValueRef = MT (ValueRef);
+        newVal->basicValue->a.localValueRef->valueName = yyvsp[-3].charPtr;
+
+        yyval.oidPtr->valueRef = newVal;
+    ;
+    break;}
+case 196:
+#line 1921 "core/parse-asn1.y"
+{
+        Value *newVal;
+
+        /* shared refs to named numbers name */
+        yyval.oidPtr = MT (OID);
+        yyval.oidPtr->arcNum = NULL_OID_ARCNUM;
+
+        AddNewValueDef (oidElmtValDefsG, yyvsp[-3].charPtr, yyvsp[-1].valuePtr);
+
+        SetupValue (&newVal, BASICVALUE_LOCALVALUEREF, myLineNoG);
+        newVal->basicValue->a.localValueRef = MT (ValueRef);
+        newVal->basicValue->a.localValueRef->valueName = yyvsp[-3].charPtr;
+
+        yyval.oidPtr->valueRef = newVal;
+    ;
+    break;}
+case 200:
+#line 1955 "core/parse-asn1.y"
+{
+	if (yyvsp[0].uintVal>0x7FFFFFFF) {
+	    yyerror("Warning: number out of range");
+	    yyval.intVal = 0x7FFFFFFF;
+	}
+	;
+    break;}
+case 201:
+#line 1962 "core/parse-asn1.y"
+{
+	yyerror ("Warning: number out of range");
+	yyval.intVal = 0x7FFFFFFF;
+	/* modulePtrG->status = MOD_ERROR; */
+	;
+    break;}
+case 207:
+#line 1990 "core/parse-asn1.y"
+{yyval.attrList = NULL;;
+    break;}
+case 208:
+#line 1995 "core/parse-asn1.y"
+{
+        yyval.attrList = NEWLIST();
+        APPEND (yyvsp[0].charPtr,yyval.attrList);
+    ;
+    break;}
+case 209:
+#line 2000 "core/parse-asn1.y"
+{
+        APPEND (yyvsp[0].charPtr,yyvsp[-1].attrList);
+        yyval.attrList = yyvsp[-1].attrList;
+    ;
+    break;}
+case 235:
+#line 2039 "core/parse-asn1.y"
+{ yyval.charPtr = "OPERATION"; ;
+    break;}
+case 236:
+#line 2040 "core/parse-asn1.y"
+{ yyval.charPtr = "ERROR"; ;
+    break;}
+case 237:
+#line 2041 "core/parse-asn1.y"
+{ yyval.charPtr = "BIND"; ;
+    break;}
+case 238:
+#line 2042 "core/parse-asn1.y"
+{ yyval.charPtr = "UNBIND"; ;
+    break;}
+case 239:
+#line 2043 "core/parse-asn1.y"
+{ yyval.charPtr = "APPLICATION-SERVICE-ELEMENT"; ;
+    break;}
+case 240:
+#line 2044 "core/parse-asn1.y"
+{ yyval.charPtr = "APPLICATION-CONTEXT"; ;
+    break;}
+case 241:
+#line 2045 "core/parse-asn1.y"
+{ yyval.charPtr = "EXTENSION"; ;
+    break;}
+case 242:
+#line 2046 "core/parse-asn1.y"
+{ yyval.charPtr = "EXTENSIONS"; ;
+    break;}
+case 243:
+#line 2047 "core/parse-asn1.y"
+{ yyval.charPtr = "EXTENSION-ATTRIBUTE"; ;
+    break;}
+case 244:
+#line 2048 "core/parse-asn1.y"
+{ yyval.charPtr = "TOKEN"; ;
+    break;}
+case 245:
+#line 2049 "core/parse-asn1.y"
+{ yyval.charPtr = "TOKEN-DATA"; ;
+    break;}
+case 246:
+#line 2050 "core/parse-asn1.y"
+{ yyval.charPtr = "SECURITY-CATEGORY"; ;
+    break;}
+case 247:
+#line 2051 "core/parse-asn1.y"
+{ yyval.charPtr = "OBJECT"; ;
+    break;}
+case 248:
+#line 2052 "core/parse-asn1.y"
+{ yyval.charPtr = "PORT"; ;
+    break;}
+case 249:
+#line 2053 "core/parse-asn1.y"
+{ yyval.charPtr = "REFINE"; ;
+    break;}
+case 250:
+#line 2054 "core/parse-asn1.y"
+{ yyval.charPtr = "ABSTRACT-BIND"; ;
+    break;}
+case 251:
+#line 2055 "core/parse-asn1.y"
+{ yyval.charPtr = "ABSTRACT-UNBIND"; ;
+    break;}
+case 252:
+#line 2056 "core/parse-asn1.y"
+{ yyval.charPtr = "ABSTRACT-OPERATION"; ;
+    break;}
+case 253:
+#line 2057 "core/parse-asn1.y"
+{ yyval.charPtr = "ABSTRACT-ERROR"; ;
+    break;}
+case 254:
+#line 2058 "core/parse-asn1.y"
+{ yyval.charPtr = "ALGORITHM"; ;
+    break;}
+case 255:
+#line 2059 "core/parse-asn1.y"
+{ yyval.charPtr = "ENCRYPTED"; ;
+    break;}
+case 256:
+#line 2060 "core/parse-asn1.y"
+{ yyval.charPtr = "SIGNED"; ;
+    break;}
+case 257:
+#line 2061 "core/parse-asn1.y"
+{ yyval.charPtr = "SIGNATURE"; ;
+    break;}
+case 258:
+#line 2062 "core/parse-asn1.y"
+{ yyval.charPtr = "PROTECTED"; ;
+    break;}
+case 259:
+#line 2063 "core/parse-asn1.y"
+{ yyval.charPtr = "OBJECT-TYPE"; ;
+    break;}
+case 260:
+#line 2072 "core/parse-asn1.y"
+{ yyval.typePtr = yyvsp[0].typePtr; ;
+    break;}
+case 261:
+#line 2077 "core/parse-asn1.y"
+{
+        RosOperationMacroType *r;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ROSOPERATION, myLineNoG);
+        r = yyval.typePtr->basicType->a.macroType->a.rosOperation  =
+            MT (RosOperationMacroType);
+        r->arguments = yyvsp[-3].namedTypePtr;
+        r->result    = yyvsp[-2].namedTypePtr;
+        r->errors    = yyvsp[-1].typeOrValueListPtr;
+        r->linkedOps = yyvsp[0].typeOrValueListPtr;
+    ;
+    break;}
+case 262:
+#line 2092 "core/parse-asn1.y"
+{ yyval.namedTypePtr = yyvsp[0].namedTypePtr; ;
+    break;}
+case 263:
+#line 2093 "core/parse-asn1.y"
+{ yyval.namedTypePtr = NULL; ;
+    break;}
+case 264:
+#line 2097 "core/parse-asn1.y"
+{ yyval.namedTypePtr = yyvsp[0].namedTypePtr; ;
+    break;}
+case 265:
+#line 2098 "core/parse-asn1.y"
+{ yyval.namedTypePtr = NULL; ;
+    break;}
+case 267:
+#line 2104 "core/parse-asn1.y"
+{ yyval.namedTypePtr = NULL; ;
+    break;}
+case 268:
+#line 2110 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = yyvsp[-1].typeOrValueListPtr;
+    ;
+    break;}
+case 269:
+#line 2113 "core/parse-asn1.y"
+{ yyval.typeOrValueListPtr = NULL; ;
+    break;}
+case 270:
+#line 2120 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = yyvsp[-1].typeOrValueListPtr;
+    ;
+    break;}
+case 271:
+#line 2123 "core/parse-asn1.y"
+{ yyval.typeOrValueListPtr = NULL; ;
+    break;}
+case 272:
+#line 2136 "core/parse-asn1.y"
+{
+        RosErrorMacroType *r;
+        /*
+         * defines error macro type
+         */
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ROSERROR, myLineNoG);
+        r = yyval.typePtr->basicType->a.macroType->a.rosError = MT (RosErrorMacroType);
+        r->parameter = yyvsp[0].namedTypePtr;
+    ;
+    break;}
+case 273:
+#line 2149 "core/parse-asn1.y"
+{ yyval.namedTypePtr = yyvsp[0].namedTypePtr; ;
+    break;}
+case 274:
+#line 2150 "core/parse-asn1.y"
+{ yyval.namedTypePtr = NULL; ;
+    break;}
+case 275:
+#line 2160 "core/parse-asn1.y"
+{
+        RosBindMacroType *r;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ROSBIND, myLineNoG);
+
+        r = yyval.typePtr->basicType->a.macroType->a.rosBind = MT (RosBindMacroType);
+        r->argument  = yyvsp[-2].namedTypePtr;
+        r->result = yyvsp[-1].namedTypePtr;
+        r->error  = yyvsp[0].namedTypePtr;
+    ;
+    break;}
+case 276:
+#line 2173 "core/parse-asn1.y"
+{ yyval.namedTypePtr = yyvsp[0].namedTypePtr; ;
+    break;}
+case 277:
+#line 2174 "core/parse-asn1.y"
+{ yyval.namedTypePtr = NULL; ;
+    break;}
+case 278:
+#line 2179 "core/parse-asn1.y"
+{ yyval.namedTypePtr = yyvsp[0].namedTypePtr; ;
+    break;}
+case 279:
+#line 2180 "core/parse-asn1.y"
+{ yyval.namedTypePtr = NULL; ;
+    break;}
+case 280:
+#line 2185 "core/parse-asn1.y"
+{ yyval.namedTypePtr = yyvsp[0].namedTypePtr; ;
+    break;}
+case 281:
+#line 2186 "core/parse-asn1.y"
+{ yyval.namedTypePtr = NULL; ;
+    break;}
+case 282:
+#line 2196 "core/parse-asn1.y"
+{
+        RosBindMacroType *r;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ROSUNBIND, myLineNoG);
+
+        r = yyval.typePtr->basicType->a.macroType->a.rosUnbind = MT (RosBindMacroType);
+        r->argument = yyvsp[-2].namedTypePtr;
+        r->result = yyvsp[-1].namedTypePtr;
+        r->error  = yyvsp[0].namedTypePtr;
+    ;
+    break;}
+case 283:
+#line 2210 "core/parse-asn1.y"
+{ yyval.namedTypePtr = yyvsp[0].namedTypePtr; ;
+    break;}
+case 284:
+#line 2211 "core/parse-asn1.y"
+{ yyval.namedTypePtr = NULL; ;
+    break;}
+case 285:
+#line 2221 "core/parse-asn1.y"
+{
+        RosAseMacroType *r;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ROSASE, myLineNoG);
+        r = yyval.typePtr->basicType->a.macroType->a.rosAse  = MT (RosAseMacroType);
+        r->operations = yyvsp[0].valueListPtr;
+    ;
+    break;}
+case 286:
+#line 2229 "core/parse-asn1.y"
+{
+        RosAseMacroType *r;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ROSASE, myLineNoG);
+        r = yyval.typePtr->basicType->a.macroType->a.rosAse  = MT (RosAseMacroType);
+        r->consumerInvokes = yyvsp[-1].valueListPtr;
+        r->supplierInvokes = yyvsp[0].valueListPtr;
+    ;
+    break;}
+case 287:
+#line 2242 "core/parse-asn1.y"
+{
+        yyval.valueListPtr = yyvsp[-1].valueListPtr;
+    ;
+    break;}
+case 288:
+#line 2250 "core/parse-asn1.y"
+{
+        yyval.valueListPtr = yyvsp[-1].valueListPtr;
+    ;
+    break;}
+case 289:
+#line 2253 "core/parse-asn1.y"
+{ yyval.valueListPtr = NULL; ;
+    break;}
+case 290:
+#line 2259 "core/parse-asn1.y"
+{
+        yyval.valueListPtr = yyvsp[-1].valueListPtr;
+    ;
+    break;}
+case 291:
+#line 2262 "core/parse-asn1.y"
+{ yyval.valueListPtr = NULL; ;
+    break;}
+case 293:
+#line 2282 "core/parse-asn1.y"
+{
+        RosAcMacroType *r;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ROSAC, myLineNoG);
+        r = yyval.typePtr->basicType->a.macroType->a.rosAc = MT (RosAcMacroType);
+        r->nonRoElements = yyvsp[-6].valueListPtr;
+        r->bindMacroType = yyvsp[-4].typePtr;
+        r->unbindMacroType = yyvsp[-2].typePtr;
+        r->remoteOperations = yyvsp[-1].valuePtr;
+        r->operationsOf = rosAcSymmetricAsesG;
+        r->initiatorConsumerOf = rosAcInitiatorConsumerOfG;
+        r->responderConsumerOf = rosAcResponderConsumerOfG;
+        r->abstractSyntaxes = yyvsp[0].oidListPtr;
+    ;
+    break;}
+case 294:
+#line 2301 "core/parse-asn1.y"
+{
+        yyval.valueListPtr = yyvsp[-1].valueListPtr;
+    ;
+    break;}
+case 295:
+#line 2310 "core/parse-asn1.y"
+{
+        yyval.valuePtr = yyvsp[-3].valuePtr;
+    ;
+    break;}
+case 296:
+#line 2314 "core/parse-asn1.y"
+{
+        yyval.valuePtr = NULL;
+        rosAcSymmetricAsesG = NULL;
+        rosAcInitiatorConsumerOfG = NULL;
+        rosAcResponderConsumerOfG = NULL;
+    ;
+    break;}
+case 297:
+#line 2324 "core/parse-asn1.y"
+{
+        rosAcSymmetricAsesG = yyvsp[-1].valueListPtr;
+    ;
+    break;}
+case 298:
+#line 2327 "core/parse-asn1.y"
+{ rosAcSymmetricAsesG = NULL; ;
+    break;}
+case 300:
+#line 2336 "core/parse-asn1.y"
+{
+        rosAcInitiatorConsumerOfG = yyvsp[-1].valueListPtr;
+    ;
+    break;}
+case 301:
+#line 2339 "core/parse-asn1.y"
+{ rosAcInitiatorConsumerOfG = NULL; ;
+    break;}
+case 302:
+#line 2344 "core/parse-asn1.y"
+{
+        rosAcResponderConsumerOfG = yyvsp[-1].valueListPtr;
+    ;
+    break;}
+case 303:
+#line 2347 "core/parse-asn1.y"
+{ rosAcResponderConsumerOfG = NULL; ;
+    break;}
+case 304:
+#line 2352 "core/parse-asn1.y"
+{
+        yyval.oidListPtr = yyvsp[-1].oidListPtr;
+    ;
+    break;}
+case 305:
+#line 2355 "core/parse-asn1.y"
+{ yyval.oidListPtr = NULL; ;
+    break;}
+case 306:
+#line 2361 "core/parse-asn1.y"
+{
+        yyval.oidListPtr = NEWLIST();
+        APPEND (yyvsp[0].oidPtr,yyval.oidListPtr);
+    ;
+    break;}
+case 307:
+#line 2366 "core/parse-asn1.y"
+{
+        APPEND (yyvsp[0].oidPtr, yyvsp[-2].oidListPtr);
+        yyval.oidListPtr = yyvsp[-2].oidListPtr;
+    ;
+    break;}
+case 308:
+#line 2380 "core/parse-asn1.y"
+{
+          MtsasExtensionsMacroType *m;
+
+          SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASEXTENSIONS, myLineNoG);
+          m = yyval.typePtr->basicType->a.macroType->a.mtsasExtensions =
+              MT (MtsasExtensionsMacroType);
+          m->extensions = yyvsp[-1].valueListPtr;
+      ;
+    break;}
+case 310:
+#line 2393 "core/parse-asn1.y"
+{ yyval.valueListPtr = NULL; ;
+    break;}
+case 311:
+#line 2398 "core/parse-asn1.y"
+{
+         yyval.valueListPtr = NEWLIST();
+         APPEND (yyvsp[0].valuePtr, yyval.valueListPtr);
+     ;
+    break;}
+case 312:
+#line 2403 "core/parse-asn1.y"
+{
+         APPEND (yyvsp[0].valuePtr,yyvsp[-2].valueListPtr);
+         yyval.valueListPtr = yyvsp[-2].valueListPtr;
+     ;
+    break;}
+case 314:
+#line 2411 "core/parse-asn1.y"
+{ yyval.typeOrValueListPtr = NULL; ;
+    break;}
+case 315:
+#line 2416 "core/parse-asn1.y"
+{
+         yyval.typeOrValueListPtr = NEWLIST();
+         APPEND (yyvsp[0].typeOrValuePtr, yyval.typeOrValueListPtr);
+     ;
+    break;}
+case 316:
+#line 2421 "core/parse-asn1.y"
+{
+         APPEND (yyvsp[0].typeOrValuePtr,yyvsp[-2].typeOrValueListPtr);
+         yyval.typeOrValueListPtr = yyvsp[-2].typeOrValueListPtr;
+     ;
+    break;}
+case 317:
+#line 2429 "core/parse-asn1.y"
+{
+         yyval.typeOrValuePtr = MT (TypeOrValue);
+         yyval.typeOrValuePtr->choiceId = TYPEORVALUE_TYPE;
+         yyval.typeOrValuePtr->a.type = yyvsp[0].typePtr;
+     ;
+    break;}
+case 318:
+#line 2435 "core/parse-asn1.y"
+{
+         yyval.typeOrValuePtr = MT (TypeOrValue);
+         yyval.typeOrValuePtr->choiceId = TYPEORVALUE_VALUE;
+         yyval.typeOrValuePtr->a.value = yyvsp[0].valuePtr;
+     ;
+    break;}
+case 319:
+#line 2448 "core/parse-asn1.y"
+{
+        MtsasExtensionMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASEXTENSION, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasExtension =
+            MT (MtsasExtensionMacroType);
+        m->elmtType = yyvsp[-2].namedTypePtr;
+        m->defaultValue = yyvsp[-1].valuePtr;
+        m->criticalForSubmission = mtsasCriticalForSubmissionG;
+        m->criticalForTransfer = mtsasCriticalForTransferG;
+        m->criticalForDelivery = mtsasCriticalForDeliveryG;
+
+        mtsasCriticalForSubmissionG = NULL;  /* set up for next parse */
+        mtsasCriticalForTransferG = NULL;
+        mtsasCriticalForDeliveryG = NULL;
+    ;
+    break;}
+case 320:
+#line 2465 "core/parse-asn1.y"
+{
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASEXTENSION, myLineNoG);
+        yyval.typePtr->basicType->a.macroType->a.mtsasExtension =
+            MT (MtsasExtensionMacroType);
+        /*
+         * all fields are NULL in the MtsasExtensionsMacroType
+         * for this production
+         */
+    ;
+    break;}
+case 321:
+#line 2477 "core/parse-asn1.y"
+{ yyval.valuePtr = yyvsp[0].valuePtr; ;
+    break;}
+case 322:
+#line 2478 "core/parse-asn1.y"
+{ yyval.valuePtr = NULL; ;
+    break;}
+case 327:
+#line 2494 "core/parse-asn1.y"
+{
+        mtsasCriticalForSubmissionG = MT (AsnBool);
+        *mtsasCriticalForSubmissionG = TRUE;
+    ;
+    break;}
+case 328:
+#line 2499 "core/parse-asn1.y"
+{
+        mtsasCriticalForTransferG = MT (AsnBool);
+        *mtsasCriticalForTransferG = TRUE;
+    ;
+    break;}
+case 329:
+#line 2504 "core/parse-asn1.y"
+{
+        mtsasCriticalForDeliveryG = MT (AsnBool);
+        *mtsasCriticalForDeliveryG = TRUE;
+    ;
+    break;}
+case 330:
+#line 2518 "core/parse-asn1.y"
+{
+        MtsasExtensionAttributeMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASEXTENSIONATTRIBUTE, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasExtensionAttribute =
+            MT (MtsasExtensionAttributeMacroType);
+        m->type = NULL;
+    ;
+    break;}
+case 331:
+#line 2527 "core/parse-asn1.y"
+{
+        MtsasExtensionAttributeMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASEXTENSIONATTRIBUTE, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasExtensionAttribute =
+            MT (MtsasExtensionAttributeMacroType);
+        m->type = yyvsp[0].typePtr;
+    ;
+    break;}
+case 332:
+#line 2543 "core/parse-asn1.y"
+{
+        MtsasTokenMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASTOKEN, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasToken = MT (MtsasTokenMacroType);
+        m->type = NULL;
+    ;
+    break;}
+case 333:
+#line 2551 "core/parse-asn1.y"
+{
+        MtsasTokenMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASTOKEN, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasToken = MT (MtsasTokenMacroType);
+        m->type = yyvsp[0].typePtr;
+    ;
+    break;}
+case 334:
+#line 2566 "core/parse-asn1.y"
+{
+        MtsasTokenDataMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASTOKENDATA, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasTokenData =
+            MT (MtsasTokenDataMacroType);
+        m->type = NULL;
+    ;
+    break;}
+case 335:
+#line 2575 "core/parse-asn1.y"
+{
+        MtsasTokenDataMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASTOKENDATA, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasTokenData =
+            MT (MtsasTokenDataMacroType);
+        m->type = yyvsp[0].typePtr;
+    ;
+    break;}
+case 336:
+#line 2591 "core/parse-asn1.y"
+{
+        MtsasSecurityCategoryMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASSECURITYCATEGORY, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasSecurityCategory =
+            MT (MtsasSecurityCategoryMacroType);
+        m->type = NULL;
+    ;
+    break;}
+case 337:
+#line 2600 "core/parse-asn1.y"
+{
+        MtsasSecurityCategoryMacroType *m;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_MTSASSECURITYCATEGORY, myLineNoG);
+        m = yyval.typePtr->basicType->a.macroType->a.mtsasSecurityCategory =
+            MT (MtsasSecurityCategoryMacroType);
+        m->type = yyvsp[0].typePtr;
+    ;
+    break;}
+case 338:
+#line 2622 "core/parse-asn1.y"
+{
+        AsnObjectMacroType *a;
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ASNOBJECT, myLineNoG);
+        a = yyval.typePtr->basicType->a.macroType->a.asnObject = MT (AsnObjectMacroType);
+        a->ports = yyvsp[0].asnPortListPtr;
+    ;
+    break;}
+case 339:
+#line 2632 "core/parse-asn1.y"
+{
+        yyval.asnPortListPtr = yyvsp[-1].asnPortListPtr;
+    ;
+    break;}
+case 340:
+#line 2635 "core/parse-asn1.y"
+{ yyval.asnPortListPtr = NULL; ;
+    break;}
+case 341:
+#line 2640 "core/parse-asn1.y"
+{
+        yyval.asnPortListPtr = NEWLIST();
+        APPEND (yyvsp[0].asnPortPtr, yyval.asnPortListPtr);
+    ;
+    break;}
+case 342:
+#line 2645 "core/parse-asn1.y"
+{
+        APPEND (yyvsp[0].asnPortPtr, yyvsp[-2].asnPortListPtr);
+        yyval.asnPortListPtr = yyvsp[-2].asnPortListPtr;
+    ;
+    break;}
+case 343:
+#line 2653 "core/parse-asn1.y"
+{
+        yyval.asnPortPtr = MT (AsnPort);
+        yyval.asnPortPtr->portValue = yyvsp[-1].valuePtr;
+        yyval.asnPortPtr->portType = yyvsp[0].intVal;
+    ;
+    break;}
+case 344:
+#line 2662 "core/parse-asn1.y"
+{
+        /* [C] consumer */
+        yyval.intVal = CONSUMER_PORT;
+    ;
+    break;}
+case 345:
+#line 2667 "core/parse-asn1.y"
+{
+        /* [S] supplier */
+        yyval.intVal = SUPPLIER_PORT;
+    ;
+    break;}
+case 346:
+#line 2672 "core/parse-asn1.y"
+{
+       /* symmetric */
+        yyval.intVal = SYMMETRIC_PORT;
+    ;
+    break;}
+case 347:
+#line 2685 "core/parse-asn1.y"
+{
+        AsnPortMacroType *a;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ASNPORT, myLineNoG);
+        a = yyval.typePtr->basicType->a.macroType->a.asnPort = MT (AsnPortMacroType);
+        a->abstractOps = yyvsp[0].typeOrValueListPtr;
+        a->consumerInvokes = asnConsumerG;
+        a->supplierInvokes = asnSupplierG;
+    ;
+    break;}
+case 348:
+#line 2695 "core/parse-asn1.y"
+{
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ASNPORT, myLineNoG);
+        yyval.typePtr->basicType->a.macroType->a.asnPort = MT (AsnPortMacroType);
+    ;
+    break;}
+case 349:
+#line 2704 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = yyvsp[-1].typeOrValueListPtr;
+    ;
+    break;}
+case 350:
+#line 2708 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = NULL;
+        asnConsumerG = yyvsp[0].typeOrValueListPtr;
+        asnSupplierG = NULL;
+    ;
+    break;}
+case 351:
+#line 2714 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = NULL;
+        asnConsumerG = yyvsp[0].typeOrValueListPtr;
+        asnSupplierG = NULL;
+    ;
+    break;}
+case 352:
+#line 2720 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = NULL;
+        asnConsumerG = yyvsp[-1].typeOrValueListPtr;
+        asnSupplierG = NULL;
+    ;
+    break;}
+case 353:
+#line 2726 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = NULL;
+        asnConsumerG = yyvsp[-1].typeOrValueListPtr;
+        asnSupplierG = NULL;
+    ;
+    break;}
+case 354:
+#line 2735 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = yyvsp[-1].typeOrValueListPtr;
+    ;
+    break;}
+case 355:
+#line 2742 "core/parse-asn1.y"
+{
+        yyval.typeOrValueListPtr = yyvsp[-1].typeOrValueListPtr;
+    ;
+    break;}
+case 356:
+#line 2758 "core/parse-asn1.y"
+{
+        SetupType (&yyval.typePtr, BASICTYPE_UNKNOWN, myLineNoG);
+    ;
+    break;}
+case 364:
+#line 2784 "core/parse-asn1.y"
+{
+       yyval.intVal = 0; /* just to quiet yacc warning */
+    ;
+    break;}
+case 369:
+#line 2802 "core/parse-asn1.y"
+{
+        yyval.intVal = 0; /* just to quiet yacc warning */
+    ;
+    break;}
+case 370:
+#line 2815 "core/parse-asn1.y"
+{
+        AsnAbstractBindMacroType *a;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ASNABSTRACTBIND, myLineNoG);
+        a = yyval.typePtr->basicType->a.macroType->a.asnAbstractBind =
+            MT (AsnAbstractBindMacroType);
+        a->ports = yyvsp[0].asnPortListPtr;
+    ;
+    break;}
+case 371:
+#line 2824 "core/parse-asn1.y"
+{
+        AsnAbstractBindMacroType *a;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ASNABSTRACTBIND, myLineNoG);
+        a = yyval.typePtr->basicType->a.macroType->a.asnAbstractBind =
+            MT (AsnAbstractBindMacroType);
+        a->ports = yyvsp[-1].asnPortListPtr;
+        a->type = yyvsp[0].typePtr;
+    ;
+    break;}
+case 372:
+#line 2837 "core/parse-asn1.y"
+{
+        yyval.asnPortListPtr = yyvsp[-1].asnPortListPtr;
+    ;
+    break;}
+case 373:
+#line 2840 "core/parse-asn1.y"
+{ yyval.asnPortListPtr = NULL; ;
+    break;}
+case 374:
+#line 2851 "core/parse-asn1.y"
+{
+        AsnAbstractBindMacroType *a;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ASNABSTRACTUNBIND, myLineNoG);
+        a = yyval.typePtr->basicType->a.macroType->a.asnAbstractUnbind =
+            MT (AsnAbstractBindMacroType);
+
+        a->ports = yyvsp[0].asnPortListPtr;
+    ;
+    break;}
+case 375:
+#line 2861 "core/parse-asn1.y"
+{
+        AsnAbstractBindMacroType *a;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ASNABSTRACTUNBIND, myLineNoG);
+        a = yyval.typePtr->basicType->a.macroType->a.asnAbstractUnbind =
+            MT (AsnAbstractBindMacroType);
+
+        a->ports = yyvsp[-1].asnPortListPtr;
+        a->type = yyvsp[0].typePtr;
+    ;
+    break;}
+case 376:
+#line 2875 "core/parse-asn1.y"
+{
+        yyval.asnPortListPtr = yyvsp[-1].asnPortListPtr;
+    ;
+    break;}
+case 377:
+#line 2878 "core/parse-asn1.y"
+{ yyval.asnPortListPtr = NULL; ;
+    break;}
+case 378:
+#line 2888 "core/parse-asn1.y"
+{
+       yyval.typePtr = yyvsp[0].typePtr;
+       yyvsp[0].typePtr->basicType->a.macroType->choiceId = MACROTYPE_ASNABSTRACTOPERATION;
+    ;
+    break;}
+case 379:
+#line 2900 "core/parse-asn1.y"
+{
+        SetupMacroType (&yyval.typePtr, MACROTYPE_ASNABSTRACTERROR, myLineNoG);
+        yyval.typePtr->basicType->a.macroType->a.asnAbstractError = MT (RosErrorMacroType);
+        yyval.typePtr->basicType->a.macroType->a.asnAbstractError->parameter = yyvsp[0].namedTypePtr;
+    ;
+    break;}
+case 380:
+#line 2913 "core/parse-asn1.y"
+{
+        SetupMacroType (&yyval.typePtr, MACROTYPE_AFALGORITHM, myLineNoG);
+        yyval.typePtr->basicType->a.macroType->a.afAlgorithm = yyvsp[0].typePtr;
+    ;
+    break;}
+case 381:
+#line 2924 "core/parse-asn1.y"
+{
+        SetupMacroType (&yyval.typePtr, MACROTYPE_AFENCRYPTED, myLineNoG);
+        yyval.typePtr->basicType->a.macroType->a.afEncrypted = yyvsp[0].typePtr;
+    ;
+    break;}
+case 382:
+#line 2936 "core/parse-asn1.y"
+{
+        SetupMacroType (&yyval.typePtr, MACROTYPE_AFSIGNED, myLineNoG);
+        yyval.typePtr->basicType->a.macroType->a.afSigned = yyvsp[0].typePtr;
+    ;
+    break;}
+case 383:
+#line 2947 "core/parse-asn1.y"
+{
+        SetupMacroType (&yyval.typePtr, MACROTYPE_AFSIGNATURE, myLineNoG);
+        yyval.typePtr->basicType->a.macroType->a.afSignature = yyvsp[0].typePtr;
+    ;
+    break;}
+case 384:
+#line 2961 "core/parse-asn1.y"
+{
+        SetupMacroType (&yyval.typePtr, MACROTYPE_AFPROTECTED, myLineNoG);
+        yyval.typePtr->basicType->a.macroType->a.afProtected = yyvsp[0].typePtr;
+    ;
+    break;}
+case 385:
+#line 2978 "core/parse-asn1.y"
+{
+        SnmpObjectTypeMacroType *s;
+
+        SetupMacroType (&yyval.typePtr, MACROTYPE_SNMPOBJECTTYPE, myLineNoG);
+        s = yyval.typePtr->basicType->a.macroType->a.snmpObjectType =
+            MT (SnmpObjectTypeMacroType);
+
+        s->syntax = yyvsp[-8].typePtr;
+        s->access = yyvsp[-6].intVal;
+        s->status = yyvsp[-4].intVal;
+        s->description = yyvsp[-3].valuePtr;
+        s->reference = yyvsp[-2].valuePtr;
+        s->index = yyvsp[-1].typeOrValueListPtr;
+        s->defVal = yyvsp[0].valuePtr;
+    ;
+    break;}
+case 386:
+#line 2997 "core/parse-asn1.y"
+{
+        if (strcmp (yyvsp[0].charPtr, "read-only") == 0)
+            yyval.intVal = SNMP_READ_ONLY;
+        else if (strcmp (yyvsp[0].charPtr, "read-write") == 0)
+            yyval.intVal = SNMP_READ_WRITE;
+        else if (strcmp (yyvsp[0].charPtr, "write-only") == 0)
+            yyval.intVal = SNMP_WRITE_ONLY;
+        else if (strcmp (yyvsp[0].charPtr, "not-accessible") == 0)
+            yyval.intVal = SNMP_NOT_ACCESSIBLE;
+        else
+        {
+            yyerror ("ACCESS field of SNMP OBJECT-TYPE MACRO can only be one of \"read-write\", \"write-only\" or \"not-accessible\"");
+            yyval.intVal = -1;
+            modulePtrG->status = MOD_ERROR;
+        }
+        Free (yyvsp[0].charPtr);
+   ;
+    break;}
+case 387:
+#line 3019 "core/parse-asn1.y"
+{
+        if (strcmp (yyvsp[0].charPtr, "mandatory") == 0)
+            yyval.intVal = SNMP_MANDATORY;
+        else if (strcmp (yyvsp[0].charPtr, "optional") == 0)
+            yyval.intVal = SNMP_OPTIONAL;
+        else if (strcmp (yyvsp[0].charPtr, "obsolete") == 0)
+            yyval.intVal = SNMP_OBSOLETE;
+        else if (strcmp (yyvsp[0].charPtr, "deprecated") == 0)
+            yyval.intVal = SNMP_DEPRECATED;
+        else
+        {
+            yyerror ("STATUS field of SNMP OBJECT-TYPE MACRO can only be one of \"optional\", \"obsolete\" or \"deprecated\"");
+            yyval.intVal = -1;
+            modulePtrG->status = MOD_ERROR;
+        }
+        Free (yyvsp[0].charPtr);
+   ;
+    break;}
+case 388:
+#line 3039 "core/parse-asn1.y"
+{ yyval.valuePtr = yyvsp[0].valuePtr; ;
+    break;}
+case 389:
+#line 3040 "core/parse-asn1.y"
+{ yyval.valuePtr = NULL; ;
+    break;}
+case 390:
+#line 3044 "core/parse-asn1.y"
+{ yyval.valuePtr = yyvsp[0].valuePtr; ;
+    break;}
+case 391:
+#line 3045 "core/parse-asn1.y"
+{ yyval.valuePtr = NULL; ;
+    break;}
+case 392:
+#line 3050 "core/parse-asn1.y"
+{
+       yyval.typeOrValueListPtr  = yyvsp[-1].typeOrValueListPtr;
+   ;
+    break;}
+case 393:
+#line 3053 "core/parse-asn1.y"
+{ yyval.typeOrValueListPtr = NULL; ;
+    break;}
+case 394:
+#line 3058 "core/parse-asn1.y"
+{
+       yyval.valuePtr  = yyvsp[-1].valuePtr;
+   ;
+    break;}
+case 395:
+#line 3061 "core/parse-asn1.y"
+{ yyval.valuePtr = NULL; ;
+    break;}
+}
+   /* the action file gets copied in in place of this dollarsign */
+#line 498 "/usr/local/lib/bison.simple"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+  yylsp++;
+  if (yylen == 0)
+    {
+      yylsp->first_line = yylloc.first_line;
+      yylsp->first_column = yylloc.first_column;
+      yylsp->last_line = (yylsp-1)->last_line;
+      yylsp->last_column = (yylsp-1)->last_column;
+      yylsp->text = 0;
+    }
+  else
+    {
+      yylsp->last_line = (yylsp+yylen-1)->last_line;
+      yylsp->last_column = (yylsp+yylen-1)->last_column;
+    }
+#endif
+
+  /* Now "shift" the result of the reduction.
+     Determine what state that goes to,
+     based on the state we popped back to
+     and the rule number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTBASE];
+
+  goto yynewstate;
+
+yyerrlab:   /* here on detecting error */
+
+  if (! yyerrstatus)
+    /* If not already recovering from an error, report this error.  */
+    {
+      ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (yyn > YYFLAG && yyn < YYLAST)
+	{
+	  int size = 0;
+	  char *msg;
+	  int x, count;
+
+	  count = 0;
+	  /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
+	  for (x = (yyn < 0 ? -yyn : 0);
+	       x < (sizeof(yytname) / sizeof(char *)); x++)
+	    if (yycheck[x + yyn] == x)
+	      size += strlen(yytname[x]) + 15, count++;
+	  msg = (char *) malloc(size + 15);
+	  if (msg != 0)
+	    {
+	      strcpy(msg, "parse error");
+
+	      if (count < 5)
+		{
+		  count = 0;
+		  for (x = (yyn < 0 ? -yyn : 0);
+		       x < (sizeof(yytname) / sizeof(char *)); x++)
+		    if (yycheck[x + yyn] == x)
+		      {
+			strcat(msg, count == 0 ? ", expecting `" : " or `");
+			strcat(msg, yytname[x]);
+			strcat(msg, "'");
+			count++;
+		      }
+		}
+	      yyerror(msg);
+	      free(msg);
+	    }
+	  else
+	    yyerror ("parse error; also virtual memory exceeded");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror("parse error");
+    }
+
+  goto yyerrlab1;
+yyerrlab1:   /* here on error raised explicitly by an action */
+
+  if (yyerrstatus == 3)
+    {
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+	YYABORT;
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token
+     after shifting the error token.  */
+
+  yyerrstatus = 3;		/* Each real token shifted decrements this */
+
+  goto yyerrhandle;
+
+yyerrdefault:  /* current state does not do anything special for the error token. */
+
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
+  if (yyn) goto yydefault;
+#endif
+
+yyerrpop:   /* pop the current state because it cannot handle the error token */
+
+  if (yyssp == yyss) YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+  yylsp--;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "Error: state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+yyerrhandle:
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
+
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
+
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrpop;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting error token, ");
+#endif
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  yystate = yyn;
+  goto yynewstate;
+}
+#line 3064 "core/parse-asn1.y"
+
+
+yyerror (s)
+char*s;
+{
+	fprintf (stderr,"file \"%s\", line %d: %s at symbol \"%s\"\n\n", modulePtrG->asn1SrcFileName, myLineNoG, s, yytext);
+}
+
+
+/*
+ * given a Module*, the file name associated witht the open
+ * FILE *fPtr, InitAsn1Parser sets up the yacc/lex parser
+ * to parse an ASN.1 module read from fPtr and write the
+ * parse results into the given Module *mod.
+ */
+int
+InitAsn1Parser PARAMS ((mod, fileName, fPtr),
+    Module	*mod _AND_
+    char	*fileName _AND_
+    FILE	*fPtr)
+{
+    yyin = fPtr;
+
+    /*
+     * reset lexical analyzer input file ptr
+     * (only do this on succesive calls ow yyrestart seg faults
+     */
+#ifdef FLEX_IN_USE
+    if (!firstTimeThroughG)
+        yyrestart (fPtr);
+
+    firstTimeThroughG = FALSE;
+#endif
+
+
+    /*
+     * init modulePtr
+     */
+    memzero (mod, sizeof (Module));
+    modulePtrG = mod;
+    mod->asn1SrcFileName = fileName;
+    mod->status = MOD_NOT_LINKED;
+    mod->hasAnys = FALSE;
+
+    /* init lists to empty */
+    mod->typeDefs = AsnListNew (sizeof (void*));
+    mod->valueDefs = AsnListNew (sizeof (void*));
+
+    /*
+     * init export list stuff
+     */
+    exportListG = NULL;
+    exportsParsedG = FALSE;
+
+    /*
+     * reset line number to 1
+     */
+    myLineNoG = 1;
+
+    /*
+     * reset error count
+     */
+    parseErrCountG = 0;
+
+   /*
+    * set up list to hold values defined in parsed oids
+    */
+    oidElmtValDefsG = AsnListNew (sizeof (void *));
+
+    smallErrG = 0;
+
+    return 0;
+
+}  /* InitAsn1Parser */
+
+
+/*
+ * puts the applicatin tag code, tagCode, and line number it was
+ * parsed at into the applTagsG list.  If the APPLICATION tag code
+ * is already in the applTagsG list then an error is printed.
+ * and the smallErrG flag set to prevent code production.
+ */
+void
+PushApplTag PARAMS ((tagCode, lineNo),
+    unsigned long int tagCode _AND_
+    unsigned long int lineNo)
+{
+    ApplTag *l;
+    ApplTag *new;
+    int wasDefined = 0;
+
+    /* make sure not already in list */
+    for (l = applTagsG; l != NULL; l = l->next)
+    {
+        if (l->tagCode == tagCode)
+        {
+            PrintErrLoc (modulePtrG->asn1SrcFileName, lineNo);
+            fprintf (stderr,"ERROR - APPLICATION tags can be used only once per ASN.1 module.  The tag \"[APPLICATION %d]\" was previously used on line %d.\n", tagCode, l->lineNo);
+            wasDefined = 1;
+            smallErrG = 1;
+        }
+    }
+    if (!wasDefined)
+    {
+        new = MT (ApplTag);
+        new->lineNo = lineNo;
+        new->tagCode = tagCode;
+        new->next = applTagsG;
+        applTagsG = new;
+    }
+}  /* PushApplTag */
+
+
+/*
+ * Empties the applTagsG list.  Usually done between modules.
+ */
+void
+FreeApplTags()
+{
+    ApplTag *l;
+    ApplTag *lTmp;
+
+    for (l = applTagsG; l != NULL; )
+    {
+        lTmp = l->next;
+        Free (l);
+        l = lTmp;
+    }
+    applTagsG = NULL;
+}  /* FreeApplTags */
diff --git a/SecuritySNACCRuntime/compiler/core/parse-asn1.h b/SecuritySNACCRuntime/compiler/core/parse-asn1.h
new file mode 100644
index 00000000..46e6443c
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/parse-asn1.h
@@ -0,0 +1,183 @@
+typedef union
+{
+    int              intVal;
+    unsigned int     uintVal;
+    char            *charPtr;
+    Type            *typePtr;
+    NamedType       *namedTypePtr;
+    NamedTypeList   *namedTypeListPtr;
+    Value           *valuePtr;
+    NamedValue      *namedValuePtr;
+    SubtypeValue    *subtypeValuePtr;
+    Subtype         *subtypePtr;
+    ModuleId        *moduleId;
+    OID             *oidPtr;
+    OidList         *oidListPtr;
+    TypeDef         *typeDefPtr;
+    TypeDefList     *typeDefListPtr;
+    ValueDef        *valueDefPtr;
+    ValueDefList    *valueDefListPtr;
+    ExportElmt      *exportList;
+    ImportModule    *importModulePtr;
+    ImportModuleList *importModuleListPtr;
+    ImportElmt      *importElmtPtr;
+    ImportElmtList  *importElmtListPtr;
+    Tag             *tagPtr;
+    TagList         *tagListPtr;
+    Constraint      *constraintPtr;
+    ConstraintList  *constraintListPtr;
+    InnerSubtype    *innerSubtypePtr;
+    ValueList       *valueListPtr;
+    TypeOrValueList *typeOrValueListPtr;
+    TypeOrValue     *typeOrValuePtr;
+    AsnPort         *asnPortPtr;
+    AsnPortList     *asnPortListPtr;
+    AttributeList   *attrList;
+} YYSTYPE;
+#define	BSTRING_SYM	258
+#define	HSTRING_SYM	259
+#define	CSTRING_SYM	260
+#define	UCASEFIRST_IDENT_SYM	261
+#define	LCASEFIRST_IDENT_SYM	262
+#define	NAMEDMACRO_SYM	263
+#define	MACRODEFBODY_SYM	264
+#define	BRACEBAL_SYM	265
+#define	NUMBER_ERANGE	266
+#define	NUMBER_SYM	267
+#define	SNACC_ATTRIBUTES	268
+#define	DOT_SYM	269
+#define	COMMA_SYM	270
+#define	LEFTBRACE_SYM	271
+#define	RIGHTBRACE_SYM	272
+#define	LEFTPAREN_SYM	273
+#define	RIGHTPAREN_SYM	274
+#define	LEFTBRACKET_SYM	275
+#define	RIGHTBRACKET_SYM	276
+#define	LESSTHAN_SYM	277
+#define	MINUS_SYM	278
+#define	GETS_SYM	279
+#define	BAR_SYM	280
+#define	TAGS_SYM	281
+#define	BOOLEAN_SYM	282
+#define	INTEGER_SYM	283
+#define	BIT_SYM	284
+#define	STRING_SYM	285
+#define	OCTET_SYM	286
+#define	NULL_SYM	287
+#define	SEQUENCE_SYM	288
+#define	OF_SYM	289
+#define	SET_SYM	290
+#define	IMPLICIT_SYM	291
+#define	CHOICE_SYM	292
+#define	ANY_SYM	293
+#define	OBJECT_IDENTIFIER_SYM	294
+#define	OPTIONAL_SYM	295
+#define	DEFAULT_SYM	296
+#define	COMPONENTS_SYM	297
+#define	UNIVERSAL_SYM	298
+#define	APPLICATION_SYM	299
+#define	PRIVATE_SYM	300
+#define	TRUE_SYM	301
+#define	FALSE_SYM	302
+#define	BEGIN_SYM	303
+#define	END_SYM	304
+#define	DEFINITIONS_SYM	305
+#define	EXPLICIT_SYM	306
+#define	ENUMERATED_SYM	307
+#define	EXPORTS_SYM	308
+#define	IMPORTS_SYM	309
+#define	REAL_SYM	310
+#define	INCLUDES_SYM	311
+#define	MIN_SYM	312
+#define	MAX_SYM	313
+#define	SIZE_SYM	314
+#define	FROM_SYM	315
+#define	WITH_SYM	316
+#define	COMPONENT_SYM	317
+#define	PRESENT_SYM	318
+#define	ABSENT_SYM	319
+#define	DEFINED_SYM	320
+#define	BY_SYM	321
+#define	PLUS_INFINITY_SYM	322
+#define	MINUS_INFINITY_SYM	323
+#define	SEMI_COLON_SYM	324
+#define	IA5STRING_SYM	325
+#define	PRINTABLESTRING_SYM	326
+#define	NUMERICSTRING_SYM	327
+#define	TELETEXSTRING_SYM	328
+#define	T61STRING_SYM	329
+#define	VIDEOTEXSTRING_SYM	330
+#define	VISIBLESTRING_SYM	331
+#define	ISO646STRING_SYM	332
+#define	GRAPHICSTRING_SYM	333
+#define	GENERALSTRING_SYM	334
+#define	GENERALIZEDTIME_SYM	335
+#define	UTCTIME_SYM	336
+#define	EXTERNAL_SYM	337
+#define	OBJECTDESCRIPTOR_SYM	338
+#define	OPERATION_SYM	339
+#define	ARGUMENT_SYM	340
+#define	RESULT_SYM	341
+#define	ERRORS_SYM	342
+#define	LINKED_SYM	343
+#define	ERROR_SYM	344
+#define	PARAMETER_SYM	345
+#define	BIND_SYM	346
+#define	BINDERROR_SYM	347
+#define	UNBIND_SYM	348
+#define	UNBINDERROR_SYM	349
+#define	ASE_SYM	350
+#define	OPERATIONS_SYM	351
+#define	CONSUMERINVOKES_SYM	352
+#define	SUPPLIERINVOKES_SYM	353
+#define	AC_SYM	354
+#define	ASES_SYM	355
+#define	REMOTE_SYM	356
+#define	INITIATOR_SYM	357
+#define	RESPONDER_SYM	358
+#define	ABSTRACTSYNTAXES_SYM	359
+#define	CONSUMER_SYM	360
+#define	EXTENSIONS_SYM	361
+#define	CHOSEN_SYM	362
+#define	EXTENSION_SYM	363
+#define	CRITICAL_SYM	364
+#define	FOR_SYM	365
+#define	DELIVERY_SYM	366
+#define	SUBMISSION_SYM	367
+#define	TRANSFER_SYM	368
+#define	EXTENSIONATTRIBUTE_SYM	369
+#define	TOKEN_SYM	370
+#define	TOKENDATA_SYM	371
+#define	SECURITYCATEGORY_SYM	372
+#define	OBJECT_SYM	373
+#define	PORTS_SYM	374
+#define	BOXC_SYM	375
+#define	BOXS_SYM	376
+#define	PORT_SYM	377
+#define	ABSTRACTOPS_SYM	378
+#define	REFINE_SYM	379
+#define	AS_SYM	380
+#define	RECURRING_SYM	381
+#define	VISIBLE_SYM	382
+#define	PAIRED_SYM	383
+#define	ABSTRACTBIND_SYM	384
+#define	ABSTRACTUNBIND_SYM	385
+#define	TO_SYM	386
+#define	ABSTRACTERROR_SYM	387
+#define	ABSTRACTOPERATION_SYM	388
+#define	ALGORITHM_SYM	389
+#define	ENCRYPTED_SYM	390
+#define	SIGNED_SYM	391
+#define	SIGNATURE_SYM	392
+#define	PROTECTED_SYM	393
+#define	OBJECTTYPE_SYM	394
+#define	SYNTAX_SYM	395
+#define	ACCESS_SYM	396
+#define	STATUS_SYM	397
+#define	DESCRIPTION_SYM	398
+#define	REFERENCE_SYM	399
+#define	INDEX_SYM	400
+#define	DEFVAL_SYM	401
+
+
+extern YYSTYPE yylval;
diff --git a/SecuritySNACCRuntime/compiler/core/parse-asn1.y b/SecuritySNACCRuntime/compiler/core/parse-asn1.y
new file mode 100644
index 00000000..c9945a16
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/parse-asn1.y
@@ -0,0 +1,3196 @@
+/*
+ * compiler/core/parse-asn1.y
+ *
+ *	yacc source for ASN.1 '88 Parser
+ *	As interpreted from Appendix II of CCITT recomendation X.208
+ *
+ *       Parses ASN.1 into a monster data structure
+ *
+ *       Some old versions of yacc will croak due the length
+ *       of some of the symbols  (use -Nc10000 with other versions)
+ *
+ *	Mike Sample
+ *	90/05/03
+ *       91/09/02  Rewritten with "ASN.1" generated data struct
+ *
+ * Copyright (C) 1990, 1991, 1992  Michael Sample
+ *               and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/parse-asn1.y,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: parse-asn1.y,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:51  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.11  1997/08/28 09:46:41  wan
+ * Reworked number range checking, only gives warning now.
+ *
+ * Revision 1.10  1997/06/19 09:17:17  wan
+ * Added isPdu flag to tables. Added value range checks during parsing.
+ *
+ * Revision 1.9  1997/03/13 14:48:28  wan
+ * Parsed SEQUENCE SIZE(..) OF as SET, corrected.
+ *
+ * Revision 1.8  1997/03/03 11:58:34  wan
+ * Final pre-delivery stuff (I hope).
+ *
+ * Revision 1.7  1997/02/28 13:39:55  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.6  1995/07/25 19:17:55  rj
+ * use memzero that is defined in .../snacc.h to use either memset or bzero.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.5  1995/02/18  12:52:21  rj
+ * portablity fix (string(s).h)
+ *
+ * Revision 1.4  1995/02/17  20:13:21  rj
+ * portablity fix (string(s).h)
+ *
+ * Revision 1.3  1994/10/08  03:42:46  rj
+ * renamed the FLEX cpp define to FLEX_SCANNER since that's what flex defines.
+ *
+ * Revision 1.2  1994/09/01  00:42:03  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:29  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+%{
+
+#include "snacc.h"
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "lib-types.h"
+#include "snacc-util.h"
+#include "exports.h"
+#include "parser.h"
+#include "lex-stuff.h"
+
+/*
+ * smallErrG
+ *    used for small errors that should prevent code generation but not
+ *    prevent the later error checking passes
+ */
+int smallErrG = FALSE;
+
+/*
+ * firstTimeThroughG
+ *    used incase the asn1.lex was compiled with flex in which
+ *    case the lexical analyzer must be reset for every ASN.1 file
+ *    parsed, except the first
+ */
+static int firstTimeThroughG = TRUE;
+
+/*
+ *  modulePtrG
+ *    used to hold the parsed value.  The root of the parse tree.
+ */
+Module *modulePtrG;
+
+
+/*
+ * oidElmtValDefsG
+ *    used to hold integer values that are defined as arc numbers
+ *    the modules object identifiers.
+ * eg. FOO-MODULE { joint-iso-ccitt dod (2) foo (2) 3 2 } DEFINITIONS ::=
+ *     would put dod/2 and foo/2 in the oidElmtValDefsG list
+ * Note: only some oid's (modules name/import list module names)
+ *       are parsed by the yacc code.  The rest are parsed later
+ *       due to ambiguities that arise without type info.
+ */
+ValueDefList *oidElmtValDefsG = NULL;
+
+
+/*
+ * ApplTag
+ *   used to hold APPLICATION tags that have been defined in
+ *   a module.  This permits checking for the the error of
+ *   using the same APPLICATION tag in 1 module.  The
+ *   ApplTags list (appTagsG) is emptied for each module.
+ */
+typedef struct ApplTag
+{
+    unsigned long int lineNo;
+    unsigned long int tagCode;
+    struct ApplTag *next;
+} ApplTag;
+
+ApplTag *applTagsG  = NULL;
+
+/*
+ * Protos for ApplTag related stuff. These are defined at the
+ * end  of this file
+ */
+void PushApplTag PROTO ((unsigned long int tagCode, unsigned long int lineNo));
+void FreeApplTags();
+
+
+
+/*
+ * the following are globals to simplify disparity between
+ * productions and produced data structure
+ */
+
+/*
+ * these are used in the ValueRange subtype production
+ */
+static int      valueRangeUpperEndInclusiveG;
+static int      valueRangeLowerEndInclusiveG;
+
+/*
+ * used to set exports flag in Type/value defs
+ * exportListG holds the explicitly exported elements.
+ * see SetExports routine in export.c
+ */
+ExportElmt *exportListG = NULL;
+int         exportsParsedG;
+
+
+/*
+ * globals for the APPLICATION-CONTEXT macro productions
+ */
+static ValueList *rosAcSymmetricAsesG;
+static ValueList *rosAcResponderConsumerOfG;
+static ValueList *rosAcInitiatorConsumerOfG;
+
+/*
+ * used with MTSAS Extension macro
+ * set to NULL for the initial parse.
+ */
+static AsnBool *mtsasCriticalForSubmissionG = NULL;
+static AsnBool *mtsasCriticalForTransferG = NULL;
+static AsnBool *mtsasCriticalForDeliveryG = NULL;
+
+/*
+ * Asn PORT macro globals
+ */
+static TypeOrValueList *asnConsumerG;
+static TypeOrValueList *asnSupplierG;
+
+
+/*
+ * parseErrCountG
+ *   used to prevent too many cascade errors
+ */
+int parseErrCountG = 0;
+#define MAX_ERR 50
+#define PARSE_ERROR()\
+    parseErrCountG++;\
+    modulePtrG->status = MOD_ERROR;\
+    if (parseErrCountG > MAX_ERR)\
+    {\
+        fprintf (stderr, "Ackkkkk! too many errors - bye!\n");\
+        exit (1);\
+    }
+
+
+%}
+
+
+/*
+ *	Union structure.  A terminal or non-terminal can have
+ *	one of these type values.
+ */
+
+%union
+{
+    int              intVal;
+    unsigned int     uintVal;
+    char            *charPtr;
+    Type            *typePtr;
+    NamedType       *namedTypePtr;
+    NamedTypeList   *namedTypeListPtr;
+    Value           *valuePtr;
+    NamedValue      *namedValuePtr;
+    SubtypeValue    *subtypeValuePtr;
+    Subtype         *subtypePtr;
+    ModuleId        *moduleId;
+    OID             *oidPtr;
+    OidList         *oidListPtr;
+    TypeDef         *typeDefPtr;
+    TypeDefList     *typeDefListPtr;
+    ValueDef        *valueDefPtr;
+    ValueDefList    *valueDefListPtr;
+    ExportElmt      *exportList;
+    ImportModule    *importModulePtr;
+    ImportModuleList *importModuleListPtr;
+    ImportElmt      *importElmtPtr;
+    ImportElmtList  *importElmtListPtr;
+    Tag             *tagPtr;
+    TagList         *tagListPtr;
+    Constraint      *constraintPtr;
+    ConstraintList  *constraintListPtr;
+    InnerSubtype    *innerSubtypePtr;
+    ValueList       *valueListPtr;
+    TypeOrValueList *typeOrValueListPtr;
+    TypeOrValue     *typeOrValuePtr;
+    AsnPort         *asnPortPtr;
+    AsnPortList     *asnPortListPtr;
+    AttributeList   *attrList;
+}
+
+/*
+ *	Terminals. Definitions can be found in input.lex.
+ */
+
+/*
+ * these tokens (literals) have attributes (set in asn1.lex)
+ */
+%token <charPtr> BSTRING_SYM HSTRING_SYM CSTRING_SYM
+                 UCASEFIRST_IDENT_SYM LCASEFIRST_IDENT_SYM
+                 NAMEDMACRO_SYM MACRODEFBODY_SYM
+                 BRACEBAL_SYM NUMBER_ERANGE
+
+%token <uintVal> NUMBER_SYM
+
+%token <charPtr> SNACC_ATTRIBUTES
+
+/*
+ * these tokens have no attributes
+ */
+%token        DOT_SYM COMMA_SYM LEFTBRACE_SYM RIGHTBRACE_SYM LEFTPAREN_SYM
+              RIGHTPAREN_SYM LEFTBRACKET_SYM RIGHTBRACKET_SYM LESSTHAN_SYM
+              MINUS_SYM GETS_SYM BAR_SYM TAGS_SYM BOOLEAN_SYM INTEGER_SYM
+              BIT_SYM STRING_SYM OCTET_SYM NULL_SYM SEQUENCE_SYM OF_SYM
+              SET_SYM IMPLICIT_SYM CHOICE_SYM ANY_SYM
+              OBJECT_IDENTIFIER_SYM OPTIONAL_SYM DEFAULT_SYM COMPONENTS_SYM
+              UNIVERSAL_SYM APPLICATION_SYM PRIVATE_SYM TRUE_SYM FALSE_SYM
+              BEGIN_SYM END_SYM DEFINITIONS_SYM EXPLICIT_SYM ENUMERATED_SYM
+              EXPORTS_SYM IMPORTS_SYM REAL_SYM INCLUDES_SYM MIN_SYM MAX_SYM
+              SIZE_SYM FROM_SYM WITH_SYM COMPONENT_SYM PRESENT_SYM ABSENT_SYM
+              DEFINED_SYM BY_SYM PLUS_INFINITY_SYM MINUS_INFINITY_SYM
+              SEMI_COLON_SYM IA5STRING_SYM PRINTABLESTRING_SYM
+              NUMERICSTRING_SYM TELETEXSTRING_SYM T61STRING_SYM
+              VIDEOTEXSTRING_SYM VISIBLESTRING_SYM ISO646STRING_SYM
+              GRAPHICSTRING_SYM GENERALSTRING_SYM
+              GENERALIZEDTIME_SYM UTCTIME_SYM EXTERNAL_SYM
+              OBJECTDESCRIPTOR_SYM
+              /* the following are used in macros */
+              OPERATION_SYM ARGUMENT_SYM RESULT_SYM ERRORS_SYM LINKED_SYM
+              ERROR_SYM PARAMETER_SYM
+              BIND_SYM BINDERROR_SYM UNBIND_SYM UNBINDERROR_SYM
+              ASE_SYM OPERATIONS_SYM CONSUMERINVOKES_SYM
+              SUPPLIERINVOKES_SYM
+              AC_SYM ASES_SYM REMOTE_SYM INITIATOR_SYM RESPONDER_SYM
+              ABSTRACTSYNTAXES_SYM CONSUMER_SYM
+              EXTENSIONS_SYM CHOSEN_SYM
+              EXTENSION_SYM CRITICAL_SYM FOR_SYM DELIVERY_SYM SUBMISSION_SYM
+              TRANSFER_SYM  EXTENSIONATTRIBUTE_SYM
+              TOKEN_SYM TOKENDATA_SYM
+              SECURITYCATEGORY_SYM
+              OBJECT_SYM PORTS_SYM BOXC_SYM BOXS_SYM
+              PORT_SYM ABSTRACTOPS_SYM
+              REFINE_SYM AS_SYM RECURRING_SYM VISIBLE_SYM PAIRED_SYM
+              ABSTRACTBIND_SYM ABSTRACTUNBIND_SYM TO_SYM
+              ABSTRACTERROR_SYM ABSTRACTOPERATION_SYM
+              ALGORITHM_SYM ENCRYPTED_SYM SIGNED_SYM
+              SIGNATURE_SYM PROTECTED_SYM
+              OBJECTTYPE_SYM SYNTAX_SYM ACCESS_SYM STATUS_SYM
+              DESCRIPTION_SYM REFERENCE_SYM INDEX_SYM
+              DEFVAL_SYM
+
+/*
+ *  Type definitions of non-terminal symbols
+ */
+
+%type <intVal>  LineNo SetOpening SequenceOpening
+
+%type <intVal>  TagDefault
+
+%type <importElmtListPtr> SymbolList
+
+%type <importModuleListPtr> SymbolsFromModuleList
+
+%type <importModulePtr>  SymbolsFromModule
+
+%type <typeDefPtr>    TypeAssignment
+
+%type <valueDefPtr>    ValueAssignment
+
+%type <charPtr> BinaryString HexString CharString
+
+%type <intVal>   number Class
+
+%type <intVal>   SignedNumber
+
+%type <charPtr> modulereference typereference identifier Symbol
+
+
+%type <valuePtr> ExternalValueReference
+%type <valuePtr> Value DefinedValue BuiltinValue BooleanValue
+                 NullValue SpecialRealValue
+
+%type <namedValuePtr>  NamedValue
+
+%type <moduleId>   ModuleIdentifier
+
+%type <oidPtr>     ObjectIdentifierValue AssignedIdentifier
+                   ObjIdComponent NumberForm NameAndNumberForm
+                   ObjIdComponentList
+%type <charPtr>    NameForm
+%type <typePtr> BuiltinType DefinedType Subtype BooleanType IntegerType
+                BitStringType NullType SequenceType
+                SequenceOfType SetType SetOfType ChoiceType SelectionType
+                TaggedType AnyType ObjectIdentifierType
+                EnumeratedType RealType Type ExternalTypeReference
+
+
+
+%type <namedTypePtr> NamedType ElementType
+
+%type <namedTypeListPtr> AlternativeTypes AlternativeTypeList
+                         ElementTypes ElementTypeList
+
+%type <subtypeValuePtr> SubtypeValueSet SingleValue ContainedSubtype ValueRange
+                        PermittedAlphabet SizeConstraint InnerTypeConstraints
+
+%type <subtypePtr> SubtypeSpec SubtypeValueSetList
+
+%type <constraintPtr> NamedConstraint Constraint
+
+%type <constraintListPtr> TypeConstraints
+
+%type <innerSubtypePtr>  FullSpecification PartialSpecification
+                         SingleTypeConstraint MultipleTypeConstraints
+
+%type <valuePtr> LowerEndPoint UpperEndPoint LowerEndValue UpperEndValue
+
+%type <intVal>       PresenceConstraint
+
+%type <subtypePtr>    ValueConstraint
+
+%type <exportList>    ExportSymbolList
+
+%type <valueDefPtr>   NamedNumber
+
+%type <valueDefListPtr> NamedNumberList NamedBitList
+
+%type <tagPtr>       Tag ClassNumber
+
+%type <attrList>  SnaccAttributes SnaccAttributeCommentList
+
+%type <charPtr>  DefinedMacroName MacroReference
+
+%type <typePtr>  DefinedMacroType
+
+%type <valueListPtr> PossiblyEmptyValueList  ValueList
+
+%type <typeOrValueListPtr> PossiblyEmptyTypeOrValueList TypeOrValueList
+
+%type <typeOrValuePtr> TypeOrValue
+
+%type <typePtr>  RosOperationMacroType RosOperationMacroBody RosErrorMacroType
+                 RosBindMacroType RosUnbindMacroType
+                 RosAseMacroType RosAcMacroType
+
+%type <namedTypePtr> RosOpArgument RosOpResult RosOpResultType
+
+%type <typeOrValueListPtr>  RosOpErrors RosOpLinkedOps
+
+%type <namedTypePtr> RosErrParameter
+
+%type <namedTypePtr>  RosBindArgument RosBindResult RosBindError RosUnbindError
+
+%type <valueListPtr>  RosAseSymmetricAse RosAseConsumerInvokes
+                     RosAseSupplierInvokes RosAseOperationList
+
+%type <valueListPtr>  RosAcNonRoElements
+
+%type <valuePtr>  RosAcRoElements
+
+%type <oidListPtr>  OidList RosAcAbstractSyntaxes
+
+%type <typePtr> MtsasExtensionsMacroType MtsasExtensionMacroType
+                MtsasExtensionAttributeMacroType MtsasTokenMacroType
+                MtsasTokenDataMacroType MtsasSecurityCategoryMacroType
+
+%type <valuePtr> MtsasExtDefaultVal
+
+%type <typePtr>    AsnObjectMacroType AsnPortMacroType AsnRefineMacroType
+                   AsnAbstractBindMacroType AsnAbstractUnbindMacroType
+                   AsnAbstractOperationMacroType AsnAbstractErrorMacroType
+
+%type <asnPortListPtr> AsnPorts AsnPortList
+
+%type <asnPortPtr> AsnPort
+
+%type <intVal>     AsnPortType
+
+%type <intVal>     AsnObject AsnObjectList AsnPortSpec AsnPortSpecList
+                   AsnObjectSpec AsnComponent AsnComponentList
+
+%type <typeOrValueListPtr> AsnOperations AsnConsumer AsnSupplier
+
+%type <asnPortListPtr> AsnAbstractBindPorts AsnAbstractUnbindPorts
+
+%type <typePtr>    AfAlgorithmMacroType AfEncryptedMacroType
+                   AfSignedMacroType AfSignatureMacroType
+                   AfProtectedMacroType
+
+%type <typePtr>  SnmpObjectTypeMacroType
+%type <intVal>   SnmpStatus SnmpAccess
+%type <valuePtr> SnmpDescrPart SnmpReferPart SnmpDefValPart
+%type <typeOrValueListPtr>  SnmpIndexPart
+
+%start ModuleDefinition
+%%
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Module def/import/export productions */
+/*-----------------------------------------------------------------------*/
+
+LineNo: { $$ = myLineNoG; }
+
+ModuleDefinition:
+     ModuleIdentifier
+     DEFINITIONS_SYM
+     TagDefault { modulePtrG->tagDefault = $3; }
+     GETS_SYM
+     BEGIN_SYM
+     ModuleBody
+     END_SYM
+     {
+         modulePtrG->modId      = $1;
+
+         /*
+          * Set exported flags in type/value defs as appropriate
+          */
+         SetExports (modulePtrG, exportListG, exportsParsedG);
+
+         /* clean up */
+
+         /* Free Application tag list */
+         FreeApplTags();
+
+         /*
+          * Add values defined in any parsed object identifiers.
+          * Only the Module name and some macro oids have been parsed,
+          * the rest are just "{...}" strings at this point
+          * (they will be parsed in later)
+          */
+         modulePtrG->valueDefs =
+             AsnListConcat (modulePtrG->valueDefs, oidElmtValDefsG);
+
+         /*
+          * free list head only
+          */
+         Free (oidElmtValDefsG);
+     }
+;
+
+TagDefault:
+    EXPLICIT_SYM TAGS_SYM { $$ = EXPLICIT_TAGS; }
+  | IMPLICIT_SYM TAGS_SYM { $$ = IMPLICIT_TAGS; }
+  | empty
+    {
+        /* default is EXPLICIT TAGS */
+        $$ = EXPLICIT_TAGS;
+    }
+;
+
+ModuleIdentifier:
+    modulereference AssignedIdentifier
+    {
+        $$ = MT (ModuleId);
+        $$->name = $1;
+        $$->oid = $2;
+    }
+;
+
+AssignedIdentifier:
+    ObjectIdentifierValue
+  | empty { $$ = NULL; }
+;
+
+ModuleBody:
+    Exports Imports AssignmentList
+  | empty
+;
+
+Exports:
+    EXPORTS_SYM SymbolsExported SEMI_COLON_SYM
+    {
+        /*
+         *  allows differentiation between "EXPORTS;"
+         *         (in which no exports allowed)
+         *  and when the EXPORTS symbol does not appear
+         *         (then all are exported)
+         */
+        exportsParsedG = TRUE;
+    }
+  | EXPORTS_SYM error SEMI_COLON_SYM
+    {
+        PARSE_ERROR();
+        exportsParsedG = FALSE;
+        exportListG = NULL;
+        yyerrok;
+    }
+  | empty { exportsParsedG = FALSE; }
+;
+
+SymbolsExported:
+    ExportSymbolList { exportListG = $1; }
+  | empty { exportListG = NULL; }
+;
+
+ExportSymbolList:
+    Symbol
+    {
+        $$ = MT (ExportElmt);
+        $$->name = $1;
+        $$->lineNo = myLineNoG;
+        $$->next = NULL;
+    }
+  | ExportSymbolList COMMA_SYM LineNo Symbol
+    {
+        $$ = MT (ExportElmt);
+        $$->name = $4;
+        $$->next = $1;
+        $$->lineNo = $3;
+    }
+;
+
+Imports:
+    IMPORTS_SYM SymbolsImported SEMI_COLON_SYM
+  | IMPORTS_SYM error SEMI_COLON_SYM
+    {
+       PARSE_ERROR();
+       yyerrok;
+    }
+  | empty
+;
+
+SymbolsImported:
+    SymbolsFromModuleList { modulePtrG->imports = $1; }
+  | empty
+;
+
+SymbolsFromModuleList:
+    SymbolsFromModuleList SymbolsFromModule
+    {
+        APPEND ($2,$1);
+    }
+  | SymbolsFromModule
+    {
+        $$ = NEWLIST();
+        APPEND ($1, $$);
+    }
+;
+
+SymbolsFromModule:
+    SymbolList FROM_SYM LineNo ModuleIdentifier
+    {
+        $$ = MT (ImportModule);
+        $$->modId   = $4;
+        $$->lineNo = $3;
+        $$->importElmts = $1;
+    }
+;
+
+
+SymbolList:
+    SymbolList COMMA_SYM Symbol
+    {
+        ImportElmt *ie;
+
+        ie = MT (ImportElmt);
+        ie->name = $3;
+        ie->lineNo = myLineNoG;
+        APPEND (ie, $1);
+        $$ = $1;
+    }
+  | Symbol
+    {
+        ImportElmt *ie;
+
+        /* called for the first element only, so create list head */
+        $$ = NEWLIST();
+        ie = MT (ImportElmt);
+        ie->name = $1;
+        ie->lineNo = myLineNoG;
+        APPEND (ie, $$);
+    }
+;
+
+Symbol:
+    typereference
+  | identifier
+  | DefinedMacroName  /* This solves macro "keyword" problem */
+    {
+        /*
+         * hack to make DefinedMacroNames "freeable"
+         * like idents and typeref
+         */
+        $$ = Malloc (strlen ($1)+1);
+        strcpy ($$, $1);
+    }
+;
+
+
+
+AssignmentList:
+    AssignmentList AssignmentOrError
+  | AssignmentOrError
+;
+
+AssignmentOrError:
+    Assignment
+  | Assignment SEMI_COLON_SYM
+  | error SEMI_COLON_SYM
+    {
+        PARSE_ERROR();
+        yyerrok;
+    }
+;
+
+Assignment:
+    TypeAssignment
+    {
+        /*
+         * a macro may produce a null type
+         */
+        if ($1 != NULL)
+        {
+            /*
+             * add to head of  type def list
+             */
+            APPEND ($1, modulePtrG->typeDefs);
+        }
+
+    }
+  | ValueAssignment
+    {
+        /*
+         * a macro may produce a null value
+         */
+        if ($1 != NULL)
+        {
+            /*
+             * add to head of value def list
+             */
+            APPEND ($1, modulePtrG->valueDefs);
+        }
+    }
+  | NAMEDMACRO_SYM GETS_SYM BEGIN_SYM LineNo { LexBeginMacroDefContext(); }
+    MACRODEFBODY_SYM
+    {
+        TypeDef *tmpTypeDef;
+
+        /*
+         *  LEXICAL TIE IN!!
+         * create macro type to eliminate import resolution
+         * errors msgs from other modules importing the macro.
+         * (hopefully) Only the import list will link with
+         * these type defs.
+         * keeps macro def around incase of future processing needs
+         *
+         * NOTE: MACRODEFBODY_SYM returns the macro def body with
+         * with "BEGIN" at the begininning and "END" at the end
+         */
+
+        /*
+         * put lexical analyzer back in normal state
+         */
+        /*  BEGIN (INITIAL);  */
+        LexBeginInitialContext();
+
+        tmpTypeDef = MT (TypeDef);
+        SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, $4);
+        tmpTypeDef->definedName = $1;
+
+        /*
+         * keeps the macro def body
+         * (all text between & including the BEGIN and END)
+         * as a simple string - incase you want to fart around with
+         * it.
+         */
+        tmpTypeDef->type->basicType->a.macroDef = $6;
+
+        /*
+         * put in type list
+         */
+        APPEND (tmpTypeDef, modulePtrG->typeDefs);
+
+    }
+  | NAMEDMACRO_SYM GETS_SYM MacroReference
+    {
+        TypeDef *tmpTypeDef;
+
+        tmpTypeDef = MT (TypeDef);
+        SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, myLineNoG);
+        tmpTypeDef->definedName = $1;
+
+        tmpTypeDef->type->basicType->a.macroDef = $3;
+
+        /*
+         * put in type list
+         */
+        APPEND (tmpTypeDef, modulePtrG->typeDefs);
+
+    }
+  | NAMEDMACRO_SYM GETS_SYM modulereference DOT_SYM MacroReference
+    {
+        TypeDef *tmpTypeDef;
+
+        tmpTypeDef = MT (TypeDef);
+        SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, myLineNoG);
+        tmpTypeDef->definedName = $1;
+
+        tmpTypeDef->type->basicType->a.macroDef =
+               (MyString) Malloc (strlen ($3) + strlen ($5) + 2);
+
+        strcpy (tmpTypeDef->type->basicType->a.macroDef, $3);
+        strcat (tmpTypeDef->type->basicType->a.macroDef, ".");
+        strcat (tmpTypeDef->type->basicType->a.macroDef, $5);
+
+       /*
+         * put in type list
+         */
+        APPEND (tmpTypeDef, modulePtrG->typeDefs);
+
+        Free ($3);
+        Free ($5);
+    }
+;
+
+MacroReference:
+    typereference
+  | DefinedMacroName
+;
+
+/*-----------------------------------------------------------------------*/
+/* Type Notation Productions */
+/*-----------------------------------------------------------------------*/
+
+TypeAssignment:
+    typereference GETS_SYM SnaccAttributes LineNo Type SnaccAttributes
+    {
+        /*
+         * a macro type may produce a null type
+         */
+        if ($5 != NULL)
+        {
+            $$ = MT (TypeDef);
+            $$->type =  $5;
+            $$->type->lineNo = $4;
+            $$->type->attrList = $6;
+            $$->definedName = $1;
+            $$->attrList = $3;
+        }
+        else
+            $$ = NULL;
+    }
+;
+
+
+ExternalTypeReference:
+    modulereference DOT_SYM LineNo typereference
+    {
+        /* allocate a Type with basic type of ImportTypeRef */
+        SetupType (&$$, BASICTYPE_IMPORTTYPEREF, $3);
+        $$->basicType->a.importTypeRef = MT (TypeRef);
+        $$->basicType->a.importTypeRef->typeName = $4;
+        $$->basicType->a.importTypeRef->moduleName = $1;
+
+        /* add entry to this module's import list */
+        AddPrivateImportElmt (modulePtrG, $4, $1, $3);
+    }
+;
+
+
+DefinedType:      /* could by CharacterString or Useful types too */
+    ExternalTypeReference { $$ = $1; }
+  | typereference
+    {
+        SetupType (&$$, BASICTYPE_LOCALTYPEREF, myLineNoG);
+        $$->basicType->a.localTypeRef = MT (TypeRef);
+        $$->basicType->a.localTypeRef->typeName = $1;
+    }
+;
+
+
+
+Type:
+    DefinedMacroType
+  | BuiltinType
+  | DefinedType
+  | Subtype
+;
+
+BuiltinType:
+    BooleanType
+  | IntegerType
+  | BitStringType
+  | NullType
+  | SequenceType
+  | SequenceOfType
+  | SetType
+  | SetOfType
+  | ChoiceType
+  | SelectionType
+  | TaggedType
+  | AnyType
+  | ObjectIdentifierType
+  | EnumeratedType
+  | RealType
+  | OCTET_SYM STRING_SYM
+    {
+        SetupType (&$$, BASICTYPE_OCTETSTRING, myLineNoG);
+    }
+;
+
+NamedType:
+    identifier Type
+    {
+        $$ = MT (NamedType);
+        $$->type = $2;
+        $$->fieldName = $1;
+    }
+  | Type       /* this handles selectionType as well */
+    {
+        $$ = MT (NamedType);
+        $$->type = $1;
+    }
+;
+
+BooleanType:
+    BOOLEAN_SYM
+    {
+        SetupType (&$$, BASICTYPE_BOOLEAN, myLineNoG);
+    }
+;
+
+IntegerType:
+    INTEGER_SYM
+    {
+        SetupType (&$$, BASICTYPE_INTEGER, myLineNoG);
+        $$->basicType->a.integer = NEWLIST();  /* empty list */
+    }
+  | INTEGER_SYM LEFTBRACE_SYM NamedNumberList RIGHTBRACE_SYM
+    {
+        SetupType (&$$, BASICTYPE_INTEGER, myLineNoG);
+        $$->basicType->a.integer = $3;
+    }
+;
+
+
+NamedNumberList:
+    NamedNumber
+    {
+        $$ = NEWLIST();
+        APPEND ($1, $$);
+    }
+  | NamedNumberList COMMA_SYM NamedNumber
+    {
+        APPEND ($3,$1);
+        $$ = $1;
+    }
+;
+
+NamedNumber:
+    identifier LEFTPAREN_SYM SignedNumber RIGHTPAREN_SYM
+    {
+        $$ = MT (ValueDef);
+        $$->definedName = $1;
+        SetupValue (&$$->value, BASICVALUE_INTEGER, myLineNoG);
+        $$->value->basicValue->a.integer = $3;
+    }
+  | identifier LEFTPAREN_SYM DefinedValue RIGHTPAREN_SYM
+    {
+        $$ = MT (ValueDef);
+        $$->definedName = $1;
+        $$->value = $3;
+    }
+;
+
+SignedNumber:
+    NUMBER_SYM
+    {
+	if ($1>0x7FFFFFFF) {
+	    yyerror("Warning: positive signed number out of range");
+	    $$ = 0x7FFFFFFF;
+	}
+    }
+    | NUMBER_ERANGE
+    {
+	yyerror ("Warning: positive signed number out of range");
+	$$ = 0x7FFFFFFF;
+	/* modulePtrG->status = MOD_ERROR; */
+    }
+    | MINUS_SYM NUMBER_SYM
+    {
+	if ($2>0x80000000) {
+	    yyerror("Warning: negative signed number out of range");
+	    $$ = -0x80000000;
+	} else if ($2==0x80000000) {
+	    $$ = -0x80000000;
+	} else {
+	    $$ = -$2;
+	}
+    }
+    | MINUS_SYM NUMBER_ERANGE
+    {
+	yyerror ("Warning: negative signed number out of range");
+	$$ = -0x80000000;
+	/* modulePtrG->status = MOD_ERROR; */
+    }
+;
+
+EnumeratedType:
+    ENUMERATED_SYM LEFTBRACE_SYM NamedNumberList RIGHTBRACE_SYM
+    {
+        SetupType (&$$, BASICTYPE_ENUMERATED, myLineNoG);
+        $$->basicType->a.enumerated = $3;
+    }
+;
+
+
+RealType:
+    REAL_SYM
+    {
+        SetupType (&$$, BASICTYPE_REAL, myLineNoG);
+    }
+;
+
+BitStringType:
+    BIT_SYM STRING_SYM
+    {
+        SetupType (&$$, BASICTYPE_BITSTRING, myLineNoG);
+        $$->basicType->a.bitString = NEWLIST(); /* empty list */
+    }
+  | BIT_SYM STRING_SYM LEFTBRACE_SYM NamedBitList RIGHTBRACE_SYM
+    {
+        SetupType (&$$, BASICTYPE_BITSTRING, myLineNoG);
+        $$->basicType->a.bitString = $4;
+    }
+;
+
+NamedBitList:
+    NamedNumberList
+;
+
+
+
+NullType:
+    NULL_SYM
+    {
+        SetupType (&$$, BASICTYPE_NULL, myLineNoG);
+    }
+;
+
+SequenceOpening:
+    SEQUENCE_SYM LineNo LEFTBRACE_SYM
+    { $$ = $2; }
+;
+
+SequenceType:
+    SequenceOpening ElementTypes RIGHTBRACE_SYM
+    {
+        NamedType *n;
+
+        SetupType (&$$, BASICTYPE_SEQUENCE, $1);
+
+        if (AsnListCount ((AsnList*)$2) != 0)
+        {
+            n = (NamedType*) FIRST_LIST_ELMT ((AsnList*)$2);
+            n->type->lineNo = $1;
+        }
+
+        $$->basicType->a.sequence = $2;
+
+    }
+  | SequenceOpening RIGHTBRACE_SYM
+    {
+        SetupType (&$$, BASICTYPE_SEQUENCE, $1);
+
+        /* set up empty list for SEQ with no elmts */
+        $$->basicType->a.sequence = AsnListNew (sizeof (void*));
+    }
+/*  | SEQUENCE_SYM LEFTBRACE_SYM error RIGHTBRACE_SYM
+    {
+        PARSE_ERROR();
+        yyerrok;
+    } */
+;
+
+ElementTypes:
+    ElementTypeList SnaccAttributes
+    {
+        NamedType *lastElmt;
+
+        if ($2 != NULL)
+        {
+            lastElmt = (NamedType*)LAST_LIST_ELMT ($1);
+            lastElmt->type->attrList = $2;
+        }
+        $$ = $1;
+    }
+;
+
+ElementTypeList:
+    ElementType
+    {
+        $$ = NEWLIST();
+        APPEND ($1,$$);
+    }
+  | ElementTypeList COMMA_SYM SnaccAttributes LineNo ElementType
+    {
+        NamedType *lastElmt;
+
+        if ($3 != NULL)
+        {
+            lastElmt = (NamedType*)LAST_LIST_ELMT ($1);
+            lastElmt->type->attrList = $3;
+        }
+
+       APPEND ($5, $1);
+       lastElmt = (NamedType*)LAST_LIST_ELMT ($1);
+       lastElmt->type->lineNo = $4;
+       $$ = $1;
+    }
+;
+
+ElementType:
+    NamedType
+  | NamedType OPTIONAL_SYM
+    {
+        $$ = $1;
+        $$->type->optional = TRUE;
+    }
+  | NamedType DEFAULT_SYM NamedValue
+    {
+        /*
+         * this rules uses NamedValue instead of Value
+         * for the stupid choice value syntax (fieldname value)
+         * it should be like a set/seq value (ie with
+         * enclosing { }
+         */
+        $$ = $1;
+        $$->type->defaultVal = $3;
+        /*
+         * could link value to the elmt type here (done in link_types.c)
+         */
+    }
+  | COMPONENTS_SYM OF_SYM Type
+    {
+        $$ = MT (NamedType);
+        SetupType (&$$->type, BASICTYPE_COMPONENTSOF, myLineNoG);
+        $$->type->basicType->a.componentsOf = $3;
+    }
+  | identifier COMPONENTS_SYM OF_SYM Type
+    {
+        $$ = MT (NamedType);
+        SetupType (&$$->type, BASICTYPE_COMPONENTSOF, myLineNoG);
+        $$->fieldName = $1;
+        $$->type->basicType->a.componentsOf = $4;
+    }
+;
+
+
+
+SequenceOfType:
+    SEQUENCE_SYM OF_SYM Type
+    {
+        NamedType *n;
+
+        /* does not use SEQUENCE == SEQ OF ANY abrev*/
+        SetupType (&$$, BASICTYPE_SEQUENCEOF, myLineNoG);
+
+        /* grab line number from first elmt */
+        if ($3 != NULL)
+            $$->lineNo = $3->lineNo - 1;
+
+        $$->basicType->a.sequenceOf = $3;
+    }
+;
+
+SetOpening:
+    SET_SYM LineNo LEFTBRACE_SYM { $$ = $2; }
+;
+
+SetType:
+    SetOpening ElementTypes RIGHTBRACE_SYM
+    {
+        NamedType *n;
+
+        SetupType (&$$, BASICTYPE_SET, $1);
+
+        /* reset first elmt's line number */
+        if (AsnListCount ((AsnList*)$2) != 0)
+        {
+            n = (NamedType*)FIRST_LIST_ELMT ((AsnList*)$2);
+            n->type->lineNo = $1;
+        }
+        $$->basicType->a.set = $2;
+    }
+  | SetOpening RIGHTBRACE_SYM
+    {
+        SetupType (&$$, BASICTYPE_SET, $1);
+
+        /* set up empty elmt list for SET */
+        $$->basicType->a.set = AsnListNew (sizeof (void*));
+    }
+/*  | SET_SYM LEFTBRACE_SYM error RIGHTBRACE_SYM
+    {
+        PARSE_ERROR();
+        yyerrok;
+    } */
+;
+
+
+SetOfType:
+    SET_SYM OF_SYM Type
+    {
+       /* does not allow SET == SET OF ANY Abrev */
+        SetupType (&$$, BASICTYPE_SETOF, myLineNoG);
+
+        if ($3 != NULL)
+            $$->lineNo = $3->lineNo;
+
+        $$->basicType->a.setOf = $3;
+    }
+;
+
+
+ChoiceType:
+    CHOICE_SYM LineNo LEFTBRACE_SYM AlternativeTypes RIGHTBRACE_SYM
+    {
+        NamedType *n;
+
+        SetupType (&$$, BASICTYPE_CHOICE, $2);
+
+        $$->basicType->a.choice = $4;
+
+        if (AsnListCount ($4) != 0)
+        {
+            n = (NamedType*)FIRST_LIST_ELMT ($4);
+            n->type->lineNo = $2;
+        }
+    }
+;
+
+AlternativeTypes:
+    AlternativeTypeList SnaccAttributes
+    {
+        NamedType *lastElmt;
+        if ($2 != NULL)
+        {
+            lastElmt = (NamedType*)LAST_LIST_ELMT ($1);
+            lastElmt->type->attrList = $2;
+        }
+        $$ = $1;
+    }
+;
+
+AlternativeTypeList:
+    NamedType
+    {
+        $$ = NEWLIST();
+        APPEND ($1, $$);
+    }
+  | AlternativeTypeList COMMA_SYM SnaccAttributes NamedType
+    {
+        NamedType *lastElmt;
+
+        if ($3 != NULL)
+        {
+            lastElmt = (NamedType*)LAST_LIST_ELMT ($1);
+            lastElmt->type->attrList = $3;
+        }
+        APPEND ($4,$1);
+        $$ = $1;
+    }
+;
+
+
+SelectionType:
+    identifier LESSTHAN_SYM Type
+    {
+        /*
+         * the selection type should be replaced after
+         * link with actual type
+         */
+        SetupType (&$$, BASICTYPE_SELECTION, myLineNoG);
+
+        $$->basicType->a.selection = MT (SelectionType);
+        $$->basicType->a.selection->typeRef = $3;
+        $$->basicType->a.selection->fieldName = $1;
+    }
+;
+
+TaggedType:
+    Tag Type
+    {
+        Tag *tag;
+
+        /* remove next tag if any  && IMPLICIT_TAGS */
+ 	if ((modulePtrG->tagDefault == IMPLICIT_TAGS) &&
+            ($2->tags != NULL) && !LIST_EMPTY ($2->tags))
+        {
+            tag = (Tag*)FIRST_LIST_ELMT ($2->tags); /* set curr to first */
+	    AsnListFirst ($2->tags); /* set curr to first elmt */
+            AsnListRemove ($2->tags);      /* remove first elmt */
+
+            /*
+             * set implicit if implicitly tagged built in type (ie not ref)
+             * (this simplifies the module ASN.1 printer (print.c))
+             */
+            if (tag->tclass == UNIV)
+                 $2->implicit = TRUE;
+
+            Free (tag);
+        }
+
+        PREPEND ($1, $2->tags);
+        $$ = $2;
+    }
+  | Tag IMPLICIT_SYM Type
+    {
+        Tag *tag;
+
+        /* remove next tag if any */
+ 	if (($3->tags != NULL) && !LIST_EMPTY ($3->tags))
+        {
+            tag = (Tag*)FIRST_LIST_ELMT ($3->tags); /* set curr to first */
+	    AsnListFirst ($3->tags); /* set curr to first elmt */
+            AsnListRemove ($3->tags);      /* remove first elmt */
+
+            if (tag->tclass == UNIV)
+                 $3->implicit = TRUE;
+
+            Free (tag);
+        }
+
+        /*
+         * must check after linking that implicitly tagged
+         * local/import type refs are not untagged choice/any etc
+         */
+        else if (($3->basicType->choiceId == BASICTYPE_IMPORTTYPEREF) ||
+                 ($3->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+                 ($3->basicType->choiceId == BASICTYPE_SELECTION))
+            $3->implicit = TRUE;
+
+        /*
+         *  all other implicitly tagable types should have tags
+         *  to remove - if this else clause fires then it is
+         *  probably a CHOICE or ANY type
+         */
+        else
+        {
+            PrintErrLoc (modulePtrG->asn1SrcFileName, $3->lineNo);
+            fprintf (stderr, "ERROR - attempt to implicitly reference untagged type\n");
+            smallErrG = 1;
+        }
+
+        PREPEND ($1, $3->tags);
+        $$ = $3;
+    }
+  | Tag EXPLICIT_SYM Type
+    {
+        /* insert tag at head of list */
+        $1->explicit = TRUE;
+        PREPEND ($1, $3->tags);
+        $$ = $3;
+    }
+;
+
+Tag:
+    LEFTBRACKET_SYM Class ClassNumber RIGHTBRACKET_SYM
+    {
+        $$ = $3;
+        $$->tclass = $2;
+        $$->explicit = FALSE; /* default to false */
+
+        /*
+         *  keep track of APPLICATION Tags per module
+         *  should only be used once
+         */
+        if ($2 == APPL)
+        {
+            PushApplTag ($$->code, myLineNoG);
+        }
+    }
+;
+
+ClassNumber:
+    number
+    {
+        $$ = MT (Tag);
+        $$->code = $1;
+    }
+  | DefinedValue
+    {
+        $$ = MT (Tag);
+        $$->code = NO_TAG_CODE;
+        $$->valueRef = $1;
+    }
+;
+
+Class:
+    UNIVERSAL_SYM    { $$ = UNIV; }
+  | APPLICATION_SYM  { $$ = APPL; }
+  | PRIVATE_SYM      { $$ = PRIV; }
+  | empty            { $$ = CNTX; }
+;
+
+
+AnyType:
+    ANY_SYM
+    {
+        SetupType (&$$, BASICTYPE_ANY, myLineNoG);
+    }
+  | ANY_SYM DEFINED_SYM BY_SYM identifier
+    {
+        SetupType (&$$, BASICTYPE_ANYDEFINEDBY, myLineNoG);
+        $$->basicType->a.anyDefinedBy = MT (AnyDefinedByType);
+        $$->basicType->a.anyDefinedBy->fieldName = $4;
+    }
+;
+
+
+ObjectIdentifierType:
+    OBJECT_IDENTIFIER_SYM
+    {
+        SetupType (&$$, BASICTYPE_OID, myLineNoG);
+    }
+;
+
+
+Subtype:
+    Type SubtypeSpec
+    {
+        /*
+         * append new subtype list to existing one (s) if any
+         * with AND relation
+         */
+        AppendSubtype (&$1->subtypes, $2, SUBTYPE_AND);
+        $$ = $1;
+    }
+  | SET_SYM SizeConstraint OF_SYM Type
+    {
+        Subtype *s;
+
+        SetupType (&$$, BASICTYPE_SETOF, myLineNoG);
+        $$->basicType->a.setOf = $4;
+
+        /* add size constraint */
+        s = MT (Subtype);
+        s->choiceId = SUBTYPE_SINGLE;
+        s->a.single = $2;
+        AppendSubtype (&$$->subtypes, s, SUBTYPE_AND);
+    }
+  | SEQUENCE_SYM SizeConstraint OF_SYM Type
+    {
+        Subtype *s;
+
+        SetupType (&$$, BASICTYPE_SEQUENCEOF, myLineNoG);
+        $$->basicType->a.sequenceOf = $4;
+
+        /* add size constraint */
+        s = MT (Subtype);
+        s->choiceId = SUBTYPE_SINGLE;
+        s->a.single = $2;
+        AppendSubtype (&$$->subtypes, s, SUBTYPE_AND);
+    }
+;
+
+
+SubtypeSpec:
+    LEFTPAREN_SYM SubtypeValueSetList RIGHTPAREN_SYM
+    {
+        $$ = $2;
+    }
+;
+
+SubtypeValueSetList:
+    SubtypeValueSet
+    {
+        Subtype *s;
+
+        /* OR relation between all elmts of in  ValueSetList */
+
+        $$ = MT (Subtype);
+        $$->choiceId = SUBTYPE_OR;
+        $$->a.or = NEWLIST();
+
+        s = MT (Subtype);
+        s->choiceId = SUBTYPE_SINGLE;
+        s->a.single = $1;
+        APPEND (s, $$->a.or);
+    }
+  | SubtypeValueSetList BAR_SYM SubtypeValueSet
+    {
+        Subtype *s;
+        s = MT (Subtype);
+        s->choiceId = SUBTYPE_SINGLE;
+        s->a.single = $3;
+        APPEND (s, $1->a.or);
+        $$ = $1;
+    }
+;
+
+
+SubtypeValueSet:
+    SingleValue
+  | ContainedSubtype
+  | ValueRange
+  | PermittedAlphabet
+  | SizeConstraint
+  | InnerTypeConstraints
+;
+
+SingleValue:
+    Value
+    {
+        $$ = MT (SubtypeValue);
+        $$->choiceId = SUBTYPEVALUE_SINGLEVALUE;
+        $$->a.singleValue = $1;
+    }
+
+ContainedSubtype:
+    INCLUDES_SYM Type
+    {
+        $$ = MT (SubtypeValue);
+        $$->choiceId = SUBTYPEVALUE_CONTAINED;
+        $$->a.contained = $2;
+    }
+;
+
+ValueRange:
+    LowerEndPoint DOT_SYM DOT_SYM UpperEndPoint
+    {
+        $$ = MT (SubtypeValue);
+        $$->choiceId = SUBTYPEVALUE_VALUERANGE;
+        $$->a.valueRange = MT (ValueRangeSubtype);
+        $$->a.valueRange->lowerEndInclusive =
+            valueRangeLowerEndInclusiveG;
+        $$->a.valueRange->upperEndInclusive =
+            valueRangeUpperEndInclusiveG;
+        $$->a.valueRange->lowerEndValue  = $1;
+        $$->a.valueRange->upperEndValue = $4;
+    }
+;
+
+LowerEndPoint:
+    LowerEndValue
+    {
+       $$ = $1;
+       valueRangeLowerEndInclusiveG = TRUE;
+    }
+  | LowerEndValue LESSTHAN_SYM
+    {
+       $$ = $1;
+       valueRangeLowerEndInclusiveG = FALSE;
+    }
+;
+
+UpperEndPoint:
+    UpperEndValue
+    {
+       $$ = $1;
+       valueRangeUpperEndInclusiveG = TRUE;
+    }
+  | LESSTHAN_SYM UpperEndValue
+    {
+       $$ = $2;
+       valueRangeUpperEndInclusiveG = FALSE;
+    }
+;
+
+LowerEndValue:
+    Value { $$ = $1; }
+  | MIN_SYM
+    {
+        SetupValue (&$$, BASICVALUE_SPECIALINTEGER, myLineNoG);
+        $$->basicValue->a.specialInteger =  MIN_INT;
+    }
+;
+
+UpperEndValue:
+    Value { $$ = $1; }
+  | MAX_SYM
+    {
+        SetupValue (&$$, BASICVALUE_SPECIALINTEGER, myLineNoG);
+        $$->basicValue->a.specialInteger =  MAX_INT;
+    }
+;
+
+SizeConstraint:
+    SIZE_SYM SubtypeSpec
+    {
+        $$ = MT (SubtypeValue);
+        $$->choiceId = SUBTYPEVALUE_SIZECONSTRAINT;
+        $$->a.sizeConstraint = $2;
+    }
+;
+
+
+PermittedAlphabet:
+    FROM_SYM SubtypeSpec
+    {
+        $$ = MT (SubtypeValue);
+        $$->choiceId = SUBTYPEVALUE_PERMITTEDALPHABET;
+        $$->a.permittedAlphabet = $2;
+    }
+;
+
+InnerTypeConstraints:
+    WITH_SYM COMPONENT_SYM SingleTypeConstraint
+    {
+        $$ = MT (SubtypeValue);
+        $$->choiceId = SUBTYPEVALUE_INNERSUBTYPE;
+        $$->a.innerSubtype = $3;
+    }
+  | WITH_SYM COMPONENTS_SYM MultipleTypeConstraints
+    {
+        $$ = MT (SubtypeValue);
+        $$->choiceId = SUBTYPEVALUE_INNERSUBTYPE;
+        $$->a.innerSubtype = $3;
+    }
+;
+
+SingleTypeConstraint:
+    SubtypeSpec
+    {
+        Constraint *constraint;
+
+        /* this constrains the elmt of setof or seq of */
+        $$ = MT (InnerSubtype);
+        $$->constraintType = SINGLE_CT;
+        $$->constraints = NEWLIST();
+        constraint = MT (Constraint);
+        APPEND (constraint, $$->constraints);
+        constraint->valueConstraints = $1;
+    }
+;
+
+MultipleTypeConstraints:
+    FullSpecification
+  | PartialSpecification
+;
+
+FullSpecification:
+    LEFTBRACE_SYM TypeConstraints RIGHTBRACE_SYM
+    {
+        $$ = MT (InnerSubtype);
+        $$->constraintType = FULL_CT;
+        $$->constraints = $2;
+    }
+;
+
+PartialSpecification:
+    LEFTBRACE_SYM DOT_SYM DOT_SYM DOT_SYM COMMA_SYM TypeConstraints RIGHTBRACE_SYM
+    {
+        $$ = MT (InnerSubtype);
+        $$->constraintType = PARTIAL_CT;
+        $$->constraints = $6;
+    }
+;
+
+
+TypeConstraints:
+    NamedConstraint
+    {
+        $$ = NEWLIST();
+        APPEND ($1, $$);
+    }
+  | TypeConstraints COMMA_SYM NamedConstraint
+    {
+        APPEND ($3, $1);
+        $$ = $1;
+    }
+;
+
+NamedConstraint:
+    identifier Constraint
+    {
+        $$ = $2;
+        $$->fieldRef = $1;
+    }
+  | Constraint
+
+;
+
+Constraint:
+    ValueConstraint PresenceConstraint
+    {
+        $$ = MT (Constraint);
+        $$->presenceConstraint = $2;
+        $$->valueConstraints = $1;
+    }
+;
+
+ValueConstraint:
+    SubtypeSpec { $$ = $1; }
+  | empty       { $$ = NULL; }
+;
+
+PresenceConstraint:
+    PRESENT_SYM   { $$ = PRESENT_CT; }
+  | ABSENT_SYM    { $$ = ABSENT_CT; }
+  | empty         { $$ = EMPTY_CT; }
+  | OPTIONAL_SYM  { $$ = OPTIONAL_CT; }
+;
+
+
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Value Notation Productions */
+/*-----------------------------------------------------------------------*/
+
+ValueAssignment:
+    identifier Type GETS_SYM LineNo Value
+    {
+        $$ = MT (ValueDef);
+        $$->definedName = $1;
+        $$->value = $5;
+        $$->value->lineNo = $4;
+        $$->value->type = $2;
+    }
+;
+
+
+Value:
+    BuiltinValue
+  | DefinedValue
+;
+
+DefinedValue:
+    ExternalValueReference { $$ =  $1; }
+  | identifier  /* a defined value or a named elmt ref  */
+    {
+        /*
+         * for parse, may be set to BASICVALUE_IMPORTEDTYPEREF
+         * by linker
+         */
+        SetupValue (&$$, BASICVALUE_LOCALVALUEREF, myLineNoG);
+        $$->basicValue->a.localValueRef = MT (ValueRef);
+        $$->basicValue->a.localValueRef->valueName = $1;
+        $$->valueType = BASICTYPE_UNKNOWN;
+   }
+;
+
+ExternalValueReference:
+    modulereference  DOT_SYM LineNo identifier
+    {
+        /* Alloc value with basicValue of importValueRef */
+        SetupValue (&$$, BASICVALUE_IMPORTVALUEREF, $3);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.importValueRef = MT (ValueRef);
+        $$->basicValue->a.importValueRef->valueName = $4;
+        $$->basicValue->a.importValueRef->moduleName = $1;
+
+        /* add entry to this module's import list */
+        AddPrivateImportElmt (modulePtrG, $4, $1, $3);
+    }
+;
+
+BuiltinValue:
+    BooleanValue
+  | NullValue
+  | SpecialRealValue
+  | SignedNumber         /* IntegerValue  or "0" real val*/
+    {
+        SetupValue (&$$, BASICVALUE_INTEGER, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.integer = $1;
+    }
+  | HexString    /* OctetStringValue or BinaryStringValue */
+    {
+        SetupValue (&$$, BASICVALUE_ASCIIHEX, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.asciiHex = MT (AsnOcts);
+        $$->basicValue->a.asciiHex->octs = $1;
+        $$->basicValue->a.asciiHex->octetLen = strlen ($1);
+    }
+  | BinaryString    /*  BinaryStringValue */
+    {
+        SetupValue (&$$, BASICVALUE_ASCIIBITSTRING, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.asciiBitString = MT (AsnOcts);
+        $$->basicValue->a.asciiBitString->octs = $1;
+        $$->basicValue->a.asciiBitString->octetLen = strlen ($1);
+    }
+  | CharString
+    {
+        SetupValue (&$$, BASICVALUE_ASCIITEXT, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.asciiText = MT (AsnOcts);
+        $$->basicValue->a.asciiText->octs = $1;
+        $$->basicValue->a.asciiText->octetLen = strlen ($1);
+    }
+  | LEFTBRACE_SYM { LexBeginBraceBalContext(); } BRACEBAL_SYM
+    {
+        /*
+         *  LEXICAL TIE IN!!
+         * string returned by BRACEBAL_SYM has
+         * the $1 '{' prepended and includes everything
+         * upto and including '}' that balances $1
+         */
+        LexBeginInitialContext();
+        SetupValue (&$$, BASICVALUE_VALUENOTATION, myLineNoG);
+        $$->basicValue->a.valueNotation = MT (AsnOcts);
+        $$->basicValue->a.valueNotation->octs = $3;
+        $$->basicValue->a.valueNotation->octetLen = strlen ($3);
+        $$->valueType = BASICTYPE_UNKNOWN;
+    }
+;
+
+BooleanValue:
+    TRUE_SYM
+    {
+        SetupValue (&$$, BASICVALUE_BOOLEAN, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.boolean =  TRUE;
+    }
+  | FALSE_SYM
+    {
+        SetupValue (&$$, BASICVALUE_BOOLEAN, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.boolean = FALSE;
+    }
+;
+
+
+SpecialRealValue:
+    PLUS_INFINITY_SYM
+    {
+        SetupValue (&$$, BASICVALUE_SPECIALREAL, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.specialReal =  PLUS_INFINITY_REAL;
+    }
+  | MINUS_INFINITY_SYM
+    {
+        SetupValue (&$$, BASICVALUE_SPECIALREAL, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+        $$->basicValue->a.specialReal = MINUS_INFINITY_REAL;
+    }
+;
+
+
+
+NullValue:
+    NULL_SYM
+    {
+        /* create a NULL value  */
+        SetupValue (&$$, BASICVALUE_NULL, myLineNoG);
+        $$->valueType = BASICTYPE_UNKNOWN;
+    }
+;
+
+
+NamedValue:
+    Value
+    {
+        $$ = MT (NamedValue);
+        $$->value = $1;
+    }
+  | identifier Value
+    {
+        $$ = MT (NamedValue);
+        $$->value = $2;
+        $$->fieldName = $1;
+    }
+;
+
+
+ObjectIdentifierValue:
+    LEFTBRACE_SYM ObjIdComponentList RIGHTBRACE_SYM
+    {
+        /*
+         * example OID setup
+         *
+         * for { ccitt foo (1) bar bell (bunt) 2 }
+         *
+         * ccitt
+         *   - arcnum is set to number from oid table (oid.c)
+         * foo (1)
+         *   - sets up a new value def foo defined as 1
+         *   - makes oid valueref a value ref to foo (doesn't link it tho)
+         * bar
+         *   - makes oid valueref a value ref to bar (doesn't link it tho)
+         * bell (bunt)
+         *   - sets up a new value def bell defined as a val ref to bunt
+         *   - makes oid valueref a value ref to bell (doesn't link it tho)
+         * 2
+         *  - arcnum is set to 2
+         */
+
+        $$ = $2;
+    }
+;
+
+
+ObjIdComponentList:
+    ObjIdComponentList ObjIdComponent
+    {
+        OID *o;
+        /* append component */
+        for (o = $1; o->next != NULL; o = o->next)
+	    ;
+        o->next = $2;
+        $$ = $1;
+    }
+  | ObjIdComponent
+
+;
+
+
+ObjIdComponent:
+    NumberForm
+  | NameForm
+    {
+        Value *newVal;
+        /*
+         * if the arcName is a defined arc name like
+         * ccitt or iso etc, fill in the arc number.
+         * otherwise make a value ref to that named value
+         */
+        $$ = MT (OID);
+
+        $$->arcNum = OidArcNameToNum ($1);
+        if ($$->arcNum == NULL_OID_ARCNUM)
+        {
+            /* set up value ref to named value */
+            SetupValue (&newVal, BASICVALUE_LOCALVALUEREF, myLineNoG);
+            newVal->basicValue->a.localValueRef = MT (ValueRef);
+            newVal->valueType = BASICTYPE_INTEGER;
+            newVal->basicValue->a.localValueRef->valueName = $1;
+            $$->valueRef = newVal;
+        }
+    }
+  | NameAndNumberForm
+;
+
+
+NumberForm:
+    number
+    {
+        $$ = MT (OID);
+        $$->arcNum = $1;
+    }
+;
+
+NameForm:
+    identifier
+;
+
+
+NameAndNumberForm:
+    identifier LEFTPAREN_SYM NumberForm RIGHTPAREN_SYM
+    {
+        Value *newVal;
+
+        $$ = $3;
+
+        /* shared refs to named numbers name */
+        SetupValue (&newVal, BASICVALUE_INTEGER, myLineNoG);
+        newVal->basicValue->a.integer = $$->arcNum;
+        newVal->valueType = BASICTYPE_INTEGER;
+        AddNewValueDef (oidElmtValDefsG, $1, newVal);
+
+        SetupValue (&newVal, BASICVALUE_LOCALVALUEREF, myLineNoG);
+        newVal->basicValue->a.localValueRef = MT (ValueRef);
+        newVal->basicValue->a.localValueRef->valueName = $1;
+
+        $$->valueRef = newVal;
+    }
+  | identifier LEFTPAREN_SYM DefinedValue RIGHTPAREN_SYM
+    {
+        Value *newVal;
+
+        /* shared refs to named numbers name */
+        $$ = MT (OID);
+        $$->arcNum = NULL_OID_ARCNUM;
+
+        AddNewValueDef (oidElmtValDefsG, $1, $3);
+
+        SetupValue (&newVal, BASICVALUE_LOCALVALUEREF, myLineNoG);
+        newVal->basicValue->a.localValueRef = MT (ValueRef);
+        newVal->basicValue->a.localValueRef->valueName = $1;
+
+        $$->valueRef = newVal;
+    }
+
+;
+
+
+
+BinaryString:
+    BSTRING_SYM
+;
+
+HexString:
+    HSTRING_SYM
+;
+
+CharString:
+    CSTRING_SYM
+;
+
+number:
+    NUMBER_SYM
+	{
+	if ($1>0x7FFFFFFF) {
+	    yyerror("Warning: number out of range");
+	    $$ = 0x7FFFFFFF;
+	}
+	}
+    | NUMBER_ERANGE
+	{
+	yyerror ("Warning: number out of range");
+	$$ = 0x7FFFFFFF;
+	/* modulePtrG->status = MOD_ERROR; */
+	}
+;
+
+identifier:
+    LCASEFIRST_IDENT_SYM
+;
+
+modulereference:
+    UCASEFIRST_IDENT_SYM
+;
+
+typereference:
+    UCASEFIRST_IDENT_SYM
+;
+
+empty:
+;
+
+
+/* Snacc attributes/extra type info
+ *  - encapsulated in special comments
+ */
+SnaccAttributes:
+    SnaccAttributeCommentList
+  | empty {$$ = NULL;}
+;
+
+SnaccAttributeCommentList:
+    SNACC_ATTRIBUTES
+    {
+        $$ = NEWLIST();
+        APPEND ($1,$$);
+    }
+  | SnaccAttributeCommentList  SNACC_ATTRIBUTES
+    {
+        APPEND ($2,$1);
+        $$ = $1;
+    }
+;
+
+/*
+ *  Macro Syntax definitions
+ **************************/
+
+DefinedMacroType:
+    RosOperationMacroType
+  | RosErrorMacroType
+  | RosBindMacroType
+  | RosUnbindMacroType
+  | RosAseMacroType
+  | RosAcMacroType
+  | MtsasExtensionMacroType
+  | MtsasExtensionsMacroType
+  | MtsasExtensionAttributeMacroType
+  | MtsasTokenMacroType
+  | MtsasTokenDataMacroType
+  | MtsasSecurityCategoryMacroType
+  | AsnObjectMacroType
+  | AsnPortMacroType
+  | AsnRefineMacroType
+  | AsnAbstractBindMacroType
+  | AsnAbstractUnbindMacroType
+  | AsnAbstractOperationMacroType
+  | AsnAbstractErrorMacroType
+  | AfAlgorithmMacroType
+  | AfEncryptedMacroType
+  | AfProtectedMacroType
+  | AfSignatureMacroType
+  | AfSignedMacroType
+  | SnmpObjectTypeMacroType
+;
+
+DefinedMacroName:
+   OPERATION_SYM          { $$ = "OPERATION"; }
+ | ERROR_SYM              { $$ = "ERROR"; }
+ | BIND_SYM               { $$ = "BIND"; }
+ | UNBIND_SYM             { $$ = "UNBIND"; }
+ | ASE_SYM                { $$ = "APPLICATION-SERVICE-ELEMENT"; }
+ | AC_SYM                 { $$ = "APPLICATION-CONTEXT"; }
+ | EXTENSION_SYM          { $$ = "EXTENSION"; }
+ | EXTENSIONS_SYM         { $$ = "EXTENSIONS"; }
+ | EXTENSIONATTRIBUTE_SYM { $$ = "EXTENSION-ATTRIBUTE"; }
+ | TOKEN_SYM              { $$ = "TOKEN"; }
+ | TOKENDATA_SYM          { $$ = "TOKEN-DATA"; }
+ | SECURITYCATEGORY_SYM   { $$ = "SECURITY-CATEGORY"; }
+ | OBJECT_SYM             { $$ = "OBJECT"; }
+ | PORT_SYM               { $$ = "PORT"; }
+ | REFINE_SYM             { $$ = "REFINE"; }
+ | ABSTRACTBIND_SYM       { $$ = "ABSTRACT-BIND"; }
+ | ABSTRACTUNBIND_SYM     { $$ = "ABSTRACT-UNBIND"; }
+ | ABSTRACTOPERATION_SYM  { $$ = "ABSTRACT-OPERATION"; }
+ | ABSTRACTERROR_SYM      { $$ = "ABSTRACT-ERROR"; }
+ | ALGORITHM_SYM          { $$ = "ALGORITHM"; }
+ | ENCRYPTED_SYM          { $$ = "ENCRYPTED"; }
+ | SIGNED_SYM             { $$ = "SIGNED"; }
+ | SIGNATURE_SYM          { $$ = "SIGNATURE"; }
+ | PROTECTED_SYM          { $$ = "PROTECTED"; }
+ | OBJECTTYPE_SYM         { $$ = "OBJECT-TYPE"; }
+;
+
+
+/*
+ * Operation Macro (ROS)  added by MS 91/08/27
+ */
+
+RosOperationMacroType:
+    OPERATION_SYM RosOperationMacroBody { $$ = $2; }
+;
+
+RosOperationMacroBody:
+    RosOpArgument RosOpResult RosOpErrors RosOpLinkedOps
+    {
+        RosOperationMacroType *r;
+
+        SetupMacroType (&$$, MACROTYPE_ROSOPERATION, myLineNoG);
+        r = $$->basicType->a.macroType->a.rosOperation  =
+            MT (RosOperationMacroType);
+        r->arguments = $1;
+        r->result    = $2;
+        r->errors    = $3;
+        r->linkedOps = $4;
+    }
+;
+
+
+RosOpArgument:
+    ARGUMENT_SYM NamedType { $$ = $2; }
+  | empty { $$ = NULL; }
+;
+
+RosOpResult:
+    RESULT_SYM RosOpResultType { $$ = $2; }
+  | empty { $$ = NULL; }
+;
+
+
+RosOpResultType:
+    NamedType
+  | empty { $$ = NULL; }
+;
+
+
+RosOpErrors:
+    ERRORS_SYM LEFTBRACE_SYM PossiblyEmptyTypeOrValueList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | empty { $$ = NULL; }
+;
+
+
+
+RosOpLinkedOps:
+    LINKED_SYM LEFTBRACE_SYM PossiblyEmptyTypeOrValueList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | empty { $$ = NULL; }
+;
+
+
+
+
+/*
+ * ROS ERROR macro - ms 91/08/27
+ */
+
+
+RosErrorMacroType:
+    ERROR_SYM RosErrParameter
+    {
+        RosErrorMacroType *r;
+        /*
+         * defines error macro type
+         */
+        SetupMacroType (&$$, MACROTYPE_ROSERROR, myLineNoG);
+        r = $$->basicType->a.macroType->a.rosError = MT (RosErrorMacroType);
+        r->parameter = $2;
+    }
+;
+
+
+RosErrParameter:
+    PARAMETER_SYM NamedType { $$ = $2; }
+  | empty { $$ = NULL; }
+;
+
+
+/*
+ * ROS BIND macro - ms 91/09/13
+ */
+
+RosBindMacroType:
+    BIND_SYM RosBindArgument RosBindResult RosBindError
+    {
+        RosBindMacroType *r;
+
+        SetupMacroType (&$$, MACROTYPE_ROSBIND, myLineNoG);
+
+        r = $$->basicType->a.macroType->a.rosBind = MT (RosBindMacroType);
+        r->argument  = $2;
+        r->result = $3;
+        r->error  = $4;
+    }
+;
+
+RosBindArgument:
+    ARGUMENT_SYM NamedType { $$ = $2; }
+  | empty { $$ = NULL; }
+;
+
+
+RosBindResult:
+    RESULT_SYM NamedType { $$ = $2; }
+  | empty { $$ = NULL; }
+;
+
+
+RosBindError:
+    BINDERROR_SYM NamedType { $$ = $2; }
+  | empty { $$ = NULL; }
+;
+
+
+/*
+ * ROS UNBIND ms 91/09/13
+ */
+
+RosUnbindMacroType:
+     UNBIND_SYM RosBindArgument RosBindResult RosUnbindError
+    {
+        RosBindMacroType *r;
+
+        SetupMacroType (&$$, MACROTYPE_ROSUNBIND, myLineNoG);
+
+        r = $$->basicType->a.macroType->a.rosUnbind = MT (RosBindMacroType);
+        r->argument = $2;
+        r->result = $3;
+        r->error  = $4;
+    }
+;
+
+
+RosUnbindError:
+    UNBINDERROR_SYM NamedType { $$ = $2; }
+  | empty { $$ = NULL; }
+;
+
+
+/*
+ * ROS APPLICATION-SERVICE-ELEMENT macro ms 91/09/13
+ */
+
+RosAseMacroType:
+    ASE_SYM RosAseSymmetricAse
+    {
+        RosAseMacroType *r;
+
+        SetupMacroType (&$$, MACROTYPE_ROSASE, myLineNoG);
+        r = $$->basicType->a.macroType->a.rosAse  = MT (RosAseMacroType);
+        r->operations = $2;
+    }
+  | ASE_SYM RosAseConsumerInvokes RosAseSupplierInvokes
+    {
+        RosAseMacroType *r;
+
+        SetupMacroType (&$$, MACROTYPE_ROSASE, myLineNoG);
+        r = $$->basicType->a.macroType->a.rosAse  = MT (RosAseMacroType);
+        r->consumerInvokes = $2;
+        r->supplierInvokes = $3;
+    }
+;
+
+
+RosAseSymmetricAse:
+    OPERATIONS_SYM LEFTBRACE_SYM RosAseOperationList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+;
+
+
+RosAseConsumerInvokes:
+    CONSUMERINVOKES_SYM LEFTBRACE_SYM RosAseOperationList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | empty { $$ = NULL; }
+;
+
+
+RosAseSupplierInvokes:
+    SUPPLIERINVOKES_SYM  LEFTBRACE_SYM RosAseOperationList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | empty { $$ = NULL; }
+;
+
+
+RosAseOperationList:
+    ValueList
+;
+
+
+/*
+ * ROS APPLICATION-CONTEXT macro ms 91/09/13
+ */
+
+RosAcMacroType:
+    AC_SYM
+    RosAcNonRoElements
+    BIND_SYM Type
+    UNBIND_SYM Type
+    RosAcRoElements
+    RosAcAbstractSyntaxes
+    {
+        RosAcMacroType *r;
+
+        SetupMacroType (&$$, MACROTYPE_ROSAC, myLineNoG);
+        r = $$->basicType->a.macroType->a.rosAc = MT (RosAcMacroType);
+        r->nonRoElements = $2;
+        r->bindMacroType = $4;
+        r->unbindMacroType = $6;
+        r->remoteOperations = $7;
+        r->operationsOf = rosAcSymmetricAsesG;
+        r->initiatorConsumerOf = rosAcInitiatorConsumerOfG;
+        r->responderConsumerOf = rosAcResponderConsumerOfG;
+        r->abstractSyntaxes = $8;
+    }
+;
+
+
+RosAcNonRoElements:
+    ASES_SYM LEFTBRACE_SYM ValueList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+;
+
+
+RosAcRoElements:
+    REMOTE_SYM OPERATIONS_SYM LEFTBRACE_SYM Value RIGHTBRACE_SYM
+    RosAcSymmetricAses RosAcAsymmetricAses
+    {
+        $$ = $4;
+    }
+  | empty
+    {
+        $$ = NULL;
+        rosAcSymmetricAsesG = NULL;
+        rosAcInitiatorConsumerOfG = NULL;
+        rosAcResponderConsumerOfG = NULL;
+    }
+;
+
+RosAcSymmetricAses:
+    OPERATIONS_SYM OF_SYM  LEFTBRACE_SYM  ValueList RIGHTBRACE_SYM
+    {
+        rosAcSymmetricAsesG = $4;
+    }
+  | empty { rosAcSymmetricAsesG = NULL; }
+;
+
+RosAcAsymmetricAses:
+    RosAcInitiatorConsumerOf RosAcResponderConsumerOf
+;
+
+RosAcInitiatorConsumerOf:
+    INITIATOR_SYM CONSUMER_SYM OF_SYM LEFTBRACE_SYM  ValueList RIGHTBRACE_SYM
+    {
+        rosAcInitiatorConsumerOfG = $5;
+    }
+  | empty { rosAcInitiatorConsumerOfG = NULL; }
+;
+
+RosAcResponderConsumerOf:
+    RESPONDER_SYM CONSUMER_SYM OF_SYM LEFTBRACE_SYM  ValueList RIGHTBRACE_SYM
+    {
+        rosAcResponderConsumerOfG = $5;
+    }
+  | empty { rosAcResponderConsumerOfG = NULL; }
+;
+
+RosAcAbstractSyntaxes:
+    ABSTRACTSYNTAXES_SYM LEFTBRACE_SYM  OidList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | empty { $$ = NULL; }
+;
+
+
+OidList:
+    ObjectIdentifierValue
+    {
+        $$ = NEWLIST();
+        APPEND ($1,$$);
+    }
+  | OidList COMMA_SYM ObjectIdentifierValue
+    {
+        APPEND ($3, $1);
+        $$ = $1;
+    }
+;
+
+
+/*
+ * MTSAbstractSvc EXTENSIONS macro
+ */
+
+MtsasExtensionsMacroType:
+      EXTENSIONS_SYM CHOSEN_SYM FROM_SYM
+      LEFTBRACE_SYM PossiblyEmptyValueList RIGHTBRACE_SYM
+      {
+          MtsasExtensionsMacroType *m;
+
+          SetupMacroType (&$$, MACROTYPE_MTSASEXTENSIONS, myLineNoG);
+          m = $$->basicType->a.macroType->a.mtsasExtensions =
+              MT (MtsasExtensionsMacroType);
+          m->extensions = $5;
+      }
+;
+
+
+PossiblyEmptyValueList:
+    ValueList
+  | empty { $$ = NULL; }
+;
+
+ValueList:
+     Value
+     {
+         $$ = NEWLIST();
+         APPEND ($1, $$);
+     }
+  | ValueList COMMA_SYM Value
+     {
+         APPEND ($3,$1);
+         $$ = $1;
+     }
+;
+
+PossiblyEmptyTypeOrValueList:
+    TypeOrValueList
+  | empty { $$ = NULL; }
+;
+
+TypeOrValueList:
+    TypeOrValue
+     {
+         $$ = NEWLIST();
+         APPEND ($1, $$);
+     }
+  | TypeOrValueList COMMA_SYM TypeOrValue
+     {
+         APPEND ($3,$1);
+         $$ = $1;
+     }
+;
+
+TypeOrValue:
+    Type
+    {
+         $$ = MT (TypeOrValue);
+         $$->choiceId = TYPEORVALUE_TYPE;
+         $$->a.type = $1;
+     }
+  | Value
+    {
+         $$ = MT (TypeOrValue);
+         $$->choiceId = TYPEORVALUE_VALUE;
+         $$->a.value = $1;
+     }
+;
+
+/*
+ *  MTSAbstractSvc EXTENSION macro
+ */
+
+MtsasExtensionMacroType:
+    EXTENSION_SYM NamedType MtsasExtDefaultVal MtsasExtCritical
+    {
+        MtsasExtensionMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASEXTENSION, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasExtension =
+            MT (MtsasExtensionMacroType);
+        m->elmtType = $2;
+        m->defaultValue = $3;
+        m->criticalForSubmission = mtsasCriticalForSubmissionG;
+        m->criticalForTransfer = mtsasCriticalForTransferG;
+        m->criticalForDelivery = mtsasCriticalForDeliveryG;
+
+        mtsasCriticalForSubmissionG = NULL;  /* set up for next parse */
+        mtsasCriticalForTransferG = NULL;
+        mtsasCriticalForDeliveryG = NULL;
+    }
+  | EXTENSION_SYM
+    {
+        SetupMacroType (&$$, MACROTYPE_MTSASEXTENSION, myLineNoG);
+        $$->basicType->a.macroType->a.mtsasExtension =
+            MT (MtsasExtensionMacroType);
+        /*
+         * all fields are NULL in the MtsasExtensionsMacroType
+         * for this production
+         */
+    }
+;
+
+MtsasExtDefaultVal:
+    DEFAULT_SYM Value { $$ = $2; }
+  | empty { $$ = NULL; }
+;
+
+MtsasExtCritical:
+     CRITICAL_SYM FOR_SYM MtsasExtCriticalityList
+   | empty
+;
+
+
+MtsasExtCriticalityList:
+    MtsasExtCriticality
+  | MtsasExtCriticalityList COMMA_SYM MtsasExtCriticality
+;
+
+MtsasExtCriticality:
+    SUBMISSION_SYM
+    {
+        mtsasCriticalForSubmissionG = MT (AsnBool);
+        *mtsasCriticalForSubmissionG = TRUE;
+    }
+  | TRANSFER_SYM
+    {
+        mtsasCriticalForTransferG = MT (AsnBool);
+        *mtsasCriticalForTransferG = TRUE;
+    }
+  | DELIVERY_SYM
+    {
+        mtsasCriticalForDeliveryG = MT (AsnBool);
+        *mtsasCriticalForDeliveryG = TRUE;
+    }
+;
+
+
+
+/*
+ * MTSAbstractSvc X.411  EXTENSION-ATTRIBUTE macro
+ */
+
+MtsasExtensionAttributeMacroType:
+    EXTENSIONATTRIBUTE_SYM
+    {
+        MtsasExtensionAttributeMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASEXTENSIONATTRIBUTE, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasExtensionAttribute =
+            MT (MtsasExtensionAttributeMacroType);
+        m->type = NULL;
+    }
+  | EXTENSIONATTRIBUTE_SYM Type
+    {
+        MtsasExtensionAttributeMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASEXTENSIONATTRIBUTE, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasExtensionAttribute =
+            MT (MtsasExtensionAttributeMacroType);
+        m->type = $2;
+    }
+;
+
+
+/*
+ * X.411 MTSAbstractSvc TOKEN macro
+ */
+MtsasTokenMacroType:
+    TOKEN_SYM
+    {
+        MtsasTokenMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASTOKEN, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasToken = MT (MtsasTokenMacroType);
+        m->type = NULL;
+    }
+  | TOKEN_SYM Type
+    {
+        MtsasTokenMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASTOKEN, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasToken = MT (MtsasTokenMacroType);
+        m->type = $2;
+    }
+;
+
+
+/*
+ * X.411 MTSAS TOKEN-DATA macro type
+ */
+MtsasTokenDataMacroType:
+    TOKENDATA_SYM
+    {
+        MtsasTokenDataMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASTOKENDATA, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasTokenData =
+            MT (MtsasTokenDataMacroType);
+        m->type = NULL;
+    }
+  | TOKENDATA_SYM Type
+    {
+        MtsasTokenDataMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASTOKENDATA, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasTokenData =
+            MT (MtsasTokenDataMacroType);
+        m->type = $2;
+    }
+;
+
+
+/*
+ * X.411 MTSAS SECURITY-CATEGORY
+ */
+MtsasSecurityCategoryMacroType:
+    SECURITYCATEGORY_SYM
+    {
+        MtsasSecurityCategoryMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASSECURITYCATEGORY, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasSecurityCategory =
+            MT (MtsasSecurityCategoryMacroType);
+        m->type = NULL;
+    }
+  | SECURITYCATEGORY_SYM Type
+    {
+        MtsasSecurityCategoryMacroType *m;
+
+        SetupMacroType (&$$, MACROTYPE_MTSASSECURITYCATEGORY, myLineNoG);
+        m = $$->basicType->a.macroType->a.mtsasSecurityCategory =
+            MT (MtsasSecurityCategoryMacroType);
+        m->type = $2;
+    }
+;
+
+
+/*
+ * X.407 Abstract Service Notation Macro Type productions
+ * MS 91/09/14
+ */
+
+
+/*
+ * OBJECT Macro X.407
+ */
+AsnObjectMacroType:
+    OBJECT_SYM AsnPorts
+    {
+        AsnObjectMacroType *a;
+        SetupMacroType (&$$, MACROTYPE_ASNOBJECT, myLineNoG);
+        a = $$->basicType->a.macroType->a.asnObject = MT (AsnObjectMacroType);
+        a->ports = $2;
+    }
+;
+
+AsnPorts:
+    PORTS_SYM LEFTBRACE_SYM AsnPortList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | empty { $$ = NULL; }
+;
+
+AsnPortList:
+    AsnPort
+    {
+        $$ = NEWLIST();
+        APPEND ($1, $$);
+    }
+  | AsnPortList COMMA_SYM AsnPort
+    {
+        APPEND ($3, $1);
+        $$ = $1;
+    }
+;
+
+AsnPort:
+    Value AsnPortType
+    {
+        $$ = MT (AsnPort);
+        $$->portValue = $1;
+        $$->portType = $2;
+    }
+;
+
+AsnPortType:
+    BOXC_SYM
+    {
+        /* [C] consumer */
+        $$ = CONSUMER_PORT;
+    }
+  | BOXS_SYM
+    {
+        /* [S] supplier */
+        $$ = SUPPLIER_PORT;
+    }
+  | empty
+    {
+       /* symmetric */
+        $$ = SYMMETRIC_PORT;
+    }
+;
+
+
+
+/*
+ * PORT Macro X.407
+ */
+AsnPortMacroType:
+    PORT_SYM AsnOperations
+    {
+        AsnPortMacroType *a;
+
+        SetupMacroType (&$$, MACROTYPE_ASNPORT, myLineNoG);
+        a = $$->basicType->a.macroType->a.asnPort = MT (AsnPortMacroType);
+        a->abstractOps = $2;
+        a->consumerInvokes = asnConsumerG;
+        a->supplierInvokes = asnSupplierG;
+    }
+  | PORT_SYM
+    {
+        SetupMacroType (&$$, MACROTYPE_ASNPORT, myLineNoG);
+        $$->basicType->a.macroType->a.asnPort = MT (AsnPortMacroType);
+    }
+;
+
+
+AsnOperations:
+    ABSTRACTOPS_SYM LEFTBRACE_SYM TypeOrValueList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | AsnConsumer
+    {
+        $$ = NULL;
+        asnConsumerG = $1;
+        asnSupplierG = NULL;
+    }
+  | AsnSupplier
+    {
+        $$ = NULL;
+        asnConsumerG = $1;
+        asnSupplierG = NULL;
+    }
+  | AsnConsumer AsnSupplier
+    {
+        $$ = NULL;
+        asnConsumerG = $1;
+        asnSupplierG = NULL;
+    }
+  | AsnSupplier AsnConsumer
+    {
+        $$ = NULL;
+        asnConsumerG = $1;
+        asnSupplierG = NULL;
+    }
+;
+
+AsnConsumer:
+    CONSUMERINVOKES_SYM LEFTBRACE_SYM TypeOrValueList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+;
+
+AsnSupplier:
+    SUPPLIERINVOKES_SYM LEFTBRACE_SYM TypeOrValueList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+
+;
+
+
+
+
+/*
+ * REFINE Macro X.407
+ *
+ * just parse it - don't keep any info at the moment
+ */
+AsnRefineMacroType:
+    REFINE_SYM AsnObject AS_SYM AsnComponentList
+    {
+        SetupType (&$$, BASICTYPE_UNKNOWN, myLineNoG);
+    }
+;
+
+AsnComponentList:
+    AsnComponent
+  | AsnComponentList COMMA_SYM AsnComponent
+;
+
+AsnComponent:
+    AsnObjectSpec AsnPortSpecList
+;
+
+AsnObjectSpec:
+    AsnObject
+  | AsnObject RECURRING_SYM
+;
+
+AsnPortSpecList:
+    AsnPortSpec
+  | AsnPortSpecList COMMA_SYM AsnPortSpec
+;
+
+AsnPortSpec:
+    Value AsnPortType AsnPortStatus
+    {
+       $$ = 0; /* just to quiet yacc warning */
+    }
+;
+
+AsnPortStatus:
+    VISIBLE_SYM
+  | PAIRED_SYM WITH_SYM AsnObjectList
+;
+
+
+AsnObjectList:
+    AsnObject
+  | AsnObjectList COMMA_SYM AsnObject
+;
+
+AsnObject:
+    Value
+    {
+        $$ = 0; /* just to quiet yacc warning */
+    }
+;
+
+
+
+
+/*
+ * ABSTRACT-BIND Macro X.407
+ */
+AsnAbstractBindMacroType:
+    ABSTRACTBIND_SYM AsnAbstractBindPorts
+    {
+        AsnAbstractBindMacroType *a;
+
+        SetupMacroType (&$$, MACROTYPE_ASNABSTRACTBIND, myLineNoG);
+        a = $$->basicType->a.macroType->a.asnAbstractBind =
+            MT (AsnAbstractBindMacroType);
+        a->ports = $2;
+    }
+  | ABSTRACTBIND_SYM AsnAbstractBindPorts Type
+    {
+        AsnAbstractBindMacroType *a;
+
+        SetupMacroType (&$$, MACROTYPE_ASNABSTRACTBIND, myLineNoG);
+        a = $$->basicType->a.macroType->a.asnAbstractBind =
+            MT (AsnAbstractBindMacroType);
+        a->ports = $2;
+        a->type = $3;
+    }
+;
+
+AsnAbstractBindPorts:
+    TO_SYM LEFTBRACE_SYM AsnPortList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | empty { $$ = NULL; }
+;
+
+
+
+
+/*
+ * ABSTRACT-UNBIND Macro X.407
+ */
+AsnAbstractUnbindMacroType:
+    ABSTRACTUNBIND_SYM AsnAbstractUnbindPorts
+    {
+        AsnAbstractBindMacroType *a;
+
+        SetupMacroType (&$$, MACROTYPE_ASNABSTRACTUNBIND, myLineNoG);
+        a = $$->basicType->a.macroType->a.asnAbstractUnbind =
+            MT (AsnAbstractBindMacroType);
+
+        a->ports = $2;
+    }
+  | ABSTRACTUNBIND_SYM AsnAbstractUnbindPorts Type
+    {
+        AsnAbstractBindMacroType *a;
+
+        SetupMacroType (&$$, MACROTYPE_ASNABSTRACTUNBIND, myLineNoG);
+        a = $$->basicType->a.macroType->a.asnAbstractUnbind =
+            MT (AsnAbstractBindMacroType);
+
+        a->ports = $2;
+        a->type = $3;
+    }
+;
+
+AsnAbstractUnbindPorts:
+    FROM_SYM LEFTBRACE_SYM AsnPortList RIGHTBRACE_SYM
+    {
+        $$ = $3;
+    }
+  | empty { $$ = NULL; }
+;
+
+
+
+/*
+ * ABSTRACT-OPERATION Macro X.407 (same as ROS Operation)
+ */
+AsnAbstractOperationMacroType:
+    ABSTRACTOPERATION_SYM RosOperationMacroBody
+    {
+       $$ = $2;
+       $2->basicType->a.macroType->choiceId = MACROTYPE_ASNABSTRACTOPERATION;
+    }
+;
+
+
+/*
+ * ABSTRACT-ERROR Macro X.407 (same as ROS Error)
+ */
+AsnAbstractErrorMacroType:
+    ABSTRACTERROR_SYM RosErrParameter
+    {
+        SetupMacroType (&$$, MACROTYPE_ASNABSTRACTERROR, myLineNoG);
+        $$->basicType->a.macroType->a.asnAbstractError = MT (RosErrorMacroType);
+        $$->basicType->a.macroType->a.asnAbstractError->parameter = $2;
+    }
+;
+
+
+/*
+ * X.509 Authentication Framework  ALGORITHM macro type
+ */
+AfAlgorithmMacroType:
+    ALGORITHM_SYM PARAMETER_SYM Type
+    {
+        SetupMacroType (&$$, MACROTYPE_AFALGORITHM, myLineNoG);
+        $$->basicType->a.macroType->a.afAlgorithm = $3;
+    }
+;
+
+/*
+ * X.509 Authentication Framework  ENCRYPTED macro type
+ */
+AfEncryptedMacroType:
+    ENCRYPTED_SYM Type
+    {
+        SetupMacroType (&$$, MACROTYPE_AFENCRYPTED, myLineNoG);
+        $$->basicType->a.macroType->a.afEncrypted = $2;
+    }
+;
+
+
+/*
+ * X.509 Authentication Framework SIGNED macro type
+ */
+AfSignedMacroType:
+    SIGNED_SYM Type
+    {
+        SetupMacroType (&$$, MACROTYPE_AFSIGNED, myLineNoG);
+        $$->basicType->a.macroType->a.afSigned = $2;
+    }
+;
+
+/*
+ * X.509 Authentication Framework SIGNATURE macro type
+ */
+AfSignatureMacroType:
+    SIGNATURE_SYM Type
+    {
+        SetupMacroType (&$$, MACROTYPE_AFSIGNATURE, myLineNoG);
+        $$->basicType->a.macroType->a.afSignature = $2;
+    }
+;
+
+
+
+/*
+ * X.509 Authentication Framework PROTECTED macro type
+ *  (same as SIGNATURE except for key word)
+ */
+AfProtectedMacroType:
+    PROTECTED_SYM Type
+    {
+        SetupMacroType (&$$, MACROTYPE_AFPROTECTED, myLineNoG);
+        $$->basicType->a.macroType->a.afProtected = $2;
+    }
+;
+
+
+
+SnmpObjectTypeMacroType:
+    OBJECTTYPE_SYM
+    SYNTAX_SYM Type
+    ACCESS_SYM SnmpAccess
+    STATUS_SYM SnmpStatus
+    SnmpDescrPart
+    SnmpReferPart
+    SnmpIndexPart
+    SnmpDefValPart
+    {
+        SnmpObjectTypeMacroType *s;
+
+        SetupMacroType (&$$, MACROTYPE_SNMPOBJECTTYPE, myLineNoG);
+        s = $$->basicType->a.macroType->a.snmpObjectType =
+            MT (SnmpObjectTypeMacroType);
+
+        s->syntax = $3;
+        s->access = $5;
+        s->status = $7;
+        s->description = $8;
+        s->reference = $9;
+        s->index = $10;
+        s->defVal = $11;
+    }
+;
+
+SnmpAccess:
+   identifier
+   {
+        if (strcmp ($1, "read-only") == 0)
+            $$ = SNMP_READ_ONLY;
+        else if (strcmp ($1, "read-write") == 0)
+            $$ = SNMP_READ_WRITE;
+        else if (strcmp ($1, "write-only") == 0)
+            $$ = SNMP_WRITE_ONLY;
+        else if (strcmp ($1, "not-accessible") == 0)
+            $$ = SNMP_NOT_ACCESSIBLE;
+        else
+        {
+            yyerror ("ACCESS field of SNMP OBJECT-TYPE MACRO can only be one of \"read-write\", \"write-only\" or \"not-accessible\"");
+            $$ = -1;
+            modulePtrG->status = MOD_ERROR;
+        }
+        Free ($1);
+   }
+;
+
+
+SnmpStatus:
+   identifier
+   {
+        if (strcmp ($1, "mandatory") == 0)
+            $$ = SNMP_MANDATORY;
+        else if (strcmp ($1, "optional") == 0)
+            $$ = SNMP_OPTIONAL;
+        else if (strcmp ($1, "obsolete") == 0)
+            $$ = SNMP_OBSOLETE;
+        else if (strcmp ($1, "deprecated") == 0)
+            $$ = SNMP_DEPRECATED;
+        else
+        {
+            yyerror ("STATUS field of SNMP OBJECT-TYPE MACRO can only be one of \"optional\", \"obsolete\" or \"deprecated\"");
+            $$ = -1;
+            modulePtrG->status = MOD_ERROR;
+        }
+        Free ($1);
+   }
+;
+
+SnmpDescrPart:
+   DESCRIPTION_SYM Value { $$ = $2; }
+  | { $$ = NULL; }
+;
+
+SnmpReferPart:
+   REFERENCE_SYM Value { $$ = $2; }
+ | { $$ = NULL; }
+;
+
+SnmpIndexPart:
+   INDEX_SYM LEFTBRACE_SYM TypeOrValueList RIGHTBRACE_SYM
+   {
+       $$  = $3;
+   }
+  | { $$ = NULL; }
+;
+
+SnmpDefValPart:
+   DEFVAL_SYM LEFTBRACE_SYM Value RIGHTBRACE_SYM
+   {
+       $$  = $3;
+   }
+  | { $$ = NULL; }
+;
+
+%%
+
+yyerror (s)
+char*s;
+{
+	fprintf (stderr,"file \"%s\", line %d: %s at symbol \"%s\"\n\n", modulePtrG->asn1SrcFileName, myLineNoG, s, yytext);
+}
+
+
+/*
+ * given a Module*, the file name associated witht the open
+ * FILE *fPtr, InitAsn1Parser sets up the yacc/lex parser
+ * to parse an ASN.1 module read from fPtr and write the
+ * parse results into the given Module *mod.
+ */
+int
+InitAsn1Parser PARAMS ((mod, fileName, fPtr),
+    Module	*mod _AND_
+    char	*fileName _AND_
+    FILE	*fPtr)
+{
+    yyin = fPtr;
+
+    /*
+     * reset lexical analyzer input file ptr
+     * (only do this on succesive calls ow yyrestart seg faults
+     */
+#ifdef FLEX_IN_USE
+    if (!firstTimeThroughG)
+        yyrestart (fPtr);
+
+    firstTimeThroughG = FALSE;
+#endif
+
+
+    /*
+     * init modulePtr
+     */
+    memzero (mod, sizeof (Module));
+    modulePtrG = mod;
+    mod->asn1SrcFileName = fileName;
+    mod->status = MOD_NOT_LINKED;
+    mod->hasAnys = FALSE;
+
+    /* init lists to empty */
+    mod->typeDefs = AsnListNew (sizeof (void*));
+    mod->valueDefs = AsnListNew (sizeof (void*));
+
+    /*
+     * init export list stuff
+     */
+    exportListG = NULL;
+    exportsParsedG = FALSE;
+
+    /*
+     * reset line number to 1
+     */
+    myLineNoG = 1;
+
+    /*
+     * reset error count
+     */
+    parseErrCountG = 0;
+
+   /*
+    * set up list to hold values defined in parsed oids
+    */
+    oidElmtValDefsG = AsnListNew (sizeof (void *));
+
+    smallErrG = 0;
+
+    return 0;
+
+}  /* InitAsn1Parser */
+
+
+/*
+ * puts the applicatin tag code, tagCode, and line number it was
+ * parsed at into the applTagsG list.  If the APPLICATION tag code
+ * is already in the applTagsG list then an error is printed.
+ * and the smallErrG flag set to prevent code production.
+ */
+void
+PushApplTag PARAMS ((tagCode, lineNo),
+    unsigned long int tagCode _AND_
+    unsigned long int lineNo)
+{
+    ApplTag *l;
+    ApplTag *new;
+    int wasDefined = 0;
+
+    /* make sure not already in list */
+    for (l = applTagsG; l != NULL; l = l->next)
+    {
+        if (l->tagCode == tagCode)
+        {
+            PrintErrLoc (modulePtrG->asn1SrcFileName, lineNo);
+            fprintf (stderr,"ERROR - APPLICATION tags can be used only once per ASN.1 module.  The tag \"[APPLICATION %d]\" was previously used on line %d.\n", tagCode, l->lineNo);
+            wasDefined = 1;
+            smallErrG = 1;
+        }
+    }
+    if (!wasDefined)
+    {
+        new = MT (ApplTag);
+        new->lineNo = lineNo;
+        new->tagCode = tagCode;
+        new->next = applTagsG;
+        applTagsG = new;
+    }
+}  /* PushApplTag */
+
+
+/*
+ * Empties the applTagsG list.  Usually done between modules.
+ */
+void
+FreeApplTags()
+{
+    ApplTag *l;
+    ApplTag *lTmp;
+
+    for (l = applTagsG; l != NULL; )
+    {
+        lTmp = l->next;
+        Free (l);
+        l = lTmp;
+    }
+    applTagsG = NULL;
+}  /* FreeApplTags */
diff --git a/SecuritySNACCRuntime/compiler/core/parser.h b/SecuritySNACCRuntime/compiler/core/parser.h
new file mode 100644
index 00000000..c22a7050
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/parser.h
@@ -0,0 +1,36 @@
+/*
+ * compiler/core/parser.h
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/parser.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: parser.h,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/24 13:33:19  rj
+ * typo fixed: Pasrser -> Parser
+ *
+ * Revision 1.2  1994/10/08  03:48:52  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:31  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+extern int	smallErrG;   /* can continue processing but don't produce code - see more errs */
+extern int	yydebug;     /* set to 1 to enable debugging */
+
+int InitAsn1Parser PROTO ((Module *mod, char *fileName, FILE *fPtr));
+
+int  yyparse();
diff --git a/SecuritySNACCRuntime/compiler/core/print.c b/SecuritySNACCRuntime/compiler/core/print.c
new file mode 100644
index 00000000..2b20588b
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/print.c
@@ -0,0 +1,2767 @@
+/*
+ * compiler/core/print.c
+ *
+ *  These routines are for printing the information from a Module
+ *  Data strucuture in ASN.1 form.
+ *
+ *  Useful for debugging the parser and seeing changes caused by
+ *  normalization and sorting.
+ *
+ * Mike Sample
+ * Feb 28/91
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/print.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: print.c,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1  2000/05/10 21:37:46  rmurphy
+ * Adding back in code which had been renamed to file2.c
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.6  1997/02/28 13:39:55  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.5  1995/08/17 14:58:57  rj
+ * minor typographic change
+ *
+ * Revision 1.4  1995/07/25  19:41:42  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:48:53  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:42:16  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:32  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "lib-types.h"
+#include "print.h"
+
+
+static int  indentCountG;
+static int  indentG = 0;
+static int  indentStepG =  4;
+
+#define INDENT(f, i)\
+    for (indentCountG = 0; indentCountG < (i); indentCountG++)\
+        fputc (' ', (f))\
+
+/*
+ * Prints the given Module *, mod, to the given FILE *f in
+ * ASN.1 format
+ */
+void
+PrintModule PARAMS ((f, mod),
+    FILE *f _AND_
+    Module *mod)
+{
+
+   if (mod->status == MOD_ERROR)
+   {
+       fprintf (f, "WARNING: this module contains errors\n");
+       fprintf (f,"(probably some type/value is referenced but is not defined or imported)\n");
+       fprintf (f,"The prog. may croak, cross your fingers!\n");
+   }
+
+
+   fprintf (f, "%s ",mod->modId->name);
+   PrintOid (f, mod->modId->oid);
+
+   fprintf (f, "\nDEFINITIONS ");
+
+   if (mod->tagDefault == EXPLICIT_TAGS)
+       fprintf (f, "EXPLICIT TAGS");
+
+   else if (mod->tagDefault == IMPLICIT_TAGS)
+       fprintf (f, "IMPLICIT TAGS");
+   else
+       fprintf (f, "\n\n -- compiler error unknown tag default");
+
+
+   fprintf (f, " ::=\nBEGIN\n\n");
+
+
+
+   PrintExports (f, mod);
+
+   PrintImportLists (f, mod->imports);
+
+   PrintTypeDefs (f, mod->typeDefs);
+   PrintValueDefs (f, mod->valueDefs);
+
+   fprintf (f, "END\n");
+
+}  /* PrintModule */
+
+
+void
+PrintExports PARAMS ((f, m),
+    FILE *f _AND_
+    Module *m)
+{
+    TypeDef *td;
+    ValueDef *vd;
+    int first;
+
+    if (m->exportStatus == EXPORTS_ALL)
+    {
+        fprintf (f, "\n\n-- exports everything\n\n");
+    }
+    else if  (m->exportStatus == EXPORTS_NOTHING)
+    {
+        fprintf (f, "\n\nEXPORTS   -- exports nothing\n\n");
+    }
+    else
+    {
+        fprintf (f, "\n\nEXPORTS\n");
+        first = 1;
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+            if (td->exported)
+            {
+                if (!first)
+                    fprintf (f,", ");
+                fprintf (f, "%s", td->definedName);
+                first = 0;
+            }
+
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+            if (vd->exported)
+            {
+                if (!first)
+                    fprintf (f,", ");
+                fprintf (f, "%s", vd->definedName);
+                first = 0;
+            }
+
+        fprintf (f, "\n;\n\n");
+    }
+}  /* PrintExports */
+
+
+
+void
+PrintOid PARAMS ((f, oid),
+    FILE *f _AND_
+    OID *oid)
+{
+    int i;
+
+    if (oid == NULL)
+       return;
+
+    fprintf (f, "{ ");
+    for (;  oid != NULL; oid = oid->next)
+    {
+        /*
+         *  value ref to an integer or if first elmt in
+         *  oid can ref other oid value
+         *  { id-asdc }
+         */
+        if (oid->valueRef != NULL)
+            PrintValue (f, NULL, NULL, oid->valueRef);
+
+        /*
+         * just  "arcNum" format
+         *  { 2 }
+         */
+        else if (oid->arcNum != NULL_OID_ARCNUM)
+            fprintf (f, "%d", oid->arcNum);
+
+
+        fprintf (f, " ");
+    }
+    fprintf (f, "}");
+
+}  /* PrintOid */
+
+
+
+void
+PrintImportElmt PARAMS ((f, impElmt),
+    FILE *f _AND_
+    ImportElmt *impElmt)
+{
+     fprintf (f, "%s",impElmt->name);
+}   /* PrintImportElmt */
+
+
+void
+PrintImportElmts PARAMS ((f, impElmtList),
+    FILE *f _AND_
+    ImportElmtList *impElmtList)
+{
+    ImportElmt *ie;
+    ImportElmt *last;
+
+    if ((impElmtList == NULL) || (LIST_EMPTY (impElmtList)))
+        return;
+
+    last = (ImportElmt*)LAST_LIST_ELMT (impElmtList);
+    FOR_EACH_LIST_ELMT (ie, impElmtList)
+    {
+        PrintImportElmt (f, ie);
+
+        if (ie != last)
+            fprintf (f, ", ");
+    }
+
+}  /* PrintImportElmts */
+
+
+
+void
+PrintImportLists PARAMS ((f, impLists),
+    FILE *f _AND_
+    ImportModuleList *impLists)
+{
+   ImportModule *impMod;
+
+   if (impLists == NULL)
+   {
+       fprintf (f,"\n\n-- imports nothing\n\n");
+       return;
+   }
+
+   fprintf (f, "IMPORTS\n\n");
+   FOR_EACH_LIST_ELMT (impMod, impLists)
+   {
+       PrintImportElmts (f, impMod->importElmts);
+
+       fprintf (f, "\n    FROM %s ", impMod->modId->name);
+
+       PrintOid (f, impMod->modId->oid);
+
+       fprintf (f, "\n\n\n");
+   }
+   fprintf (f, ";\n\n\n");
+
+}  /* PrintImportLists */
+
+
+
+void
+PrintTypeDefs PARAMS ((f, typeDefs),
+    FILE *f _AND_
+    TypeDefList *typeDefs)
+{
+    TypeDef *td;
+
+    FOR_EACH_LIST_ELMT (td, typeDefs)
+    {
+        if (td->type->basicType->choiceId == BASICTYPE_MACRODEF)
+            PrintMacroDef (f, td);
+        else
+        {
+            fprintf (f,"-- %s notes: ", td->definedName);
+
+            if (td->recursive)
+                fprintf (f,"recursive, ");
+            else
+                fprintf (f,"not recursive, ");
+
+            if (td->exported)
+                fprintf (f,"exported,\n");
+            else
+                fprintf (f,"not exported,\n");
+
+            fprintf (f,"-- locally refd %d times, ", td->localRefCount);
+            fprintf (f,"import refd %d times\n", td->importRefCount);
+
+
+            fprintf (f, "%s ::= ", td->definedName);
+            PrintType (f, td, td->type);
+        }
+        fprintf (f, "\n\n\n");
+    }
+}  /* PrintTypeDefs */
+
+
+
+
+void
+PrintType PARAMS ((f, head, t),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t)
+{
+    Tag *tag;
+    Tag *lastTag;
+
+    if (t == NULL)
+        return;
+
+    lastTag = NULL;
+    FOR_EACH_LIST_ELMT (tag, t->tags)
+    {
+
+
+
+        if (! ((tag->tclass == UNIV) &&
+               (tag->code == LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId))))
+        {
+            PrintTag (f, tag);
+            fprintf (f, " ");
+        }
+        lastTag = tag;
+    }
+
+    /*
+     * check type has been implicitly tagged
+     */
+    if (t->implicit)
+        fprintf (f, "IMPLICIT ");
+
+    PrintBasicType (f, head, t, t->basicType);
+
+
+    /*
+     * sequences of and set of print subtypes a special way
+     * so ignore them here
+     */
+    if ((t->subtypes != NULL) &&
+        (t->basicType->choiceId != BASICTYPE_SETOF) &&
+        (t->basicType->choiceId != BASICTYPE_SEQUENCEOF))
+    {
+        fprintf (f," ");
+        PrintSubtype (f, head, t, t->subtypes);
+    }
+
+
+    if (t->defaultVal != NULL)
+    {
+        fprintf (f, " DEFAULT ");
+        if (t->defaultVal->fieldName != NULL)
+            fprintf (f, "%s ", t->defaultVal->fieldName);
+        PrintValue (f, NULL, t, t->defaultVal->value);
+    }
+
+    else if (t->optional)
+        fprintf (f, " OPTIONAL");
+
+
+#ifdef DEBUG
+    fprintf (f, "  -- lineNo = %d --", t->lineNo);
+#endif
+
+}  /* PrintType */
+
+
+void
+PrintBasicType PARAMS ((f, head, t, bt),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt)
+{
+    switch (bt->choiceId)
+    {
+
+        case BASICTYPE_SEQUENCE:
+            fprintf (f, "SEQUENCE\n");
+            INDENT (f, indentG);
+            fprintf (f,"{\n");
+            indentG += indentStepG;
+            INDENT (f, indentG);
+            PrintElmtTypes (f, head, t, bt->a.sequence);
+            indentG -= indentStepG;
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f, "}");
+            break;
+
+        case BASICTYPE_SET:
+            fprintf (f, "SET\n");
+            INDENT (f, indentG);
+            fprintf (f,"{\n");
+            indentG += indentStepG;
+            INDENT (f, indentG);
+            PrintElmtTypes (f, head, t, bt->a.set);
+            indentG -= indentStepG;
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f, "}");
+            break;
+
+        case BASICTYPE_CHOICE:
+            fprintf (f, "CHOICE\n");
+            INDENT (f, indentG);
+            fprintf (f,"{\n");
+            indentG += indentStepG;
+            INDENT (f, indentG);
+            PrintElmtTypes (f, head, t, bt->a.choice);
+            indentG -= indentStepG;
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f, "}");
+            break;
+
+
+
+        case BASICTYPE_SEQUENCEOF:
+            fprintf (f, "SEQUENCE ");
+            if (t->subtypes != NULL)
+            {
+                PrintSubtype (f, head, t, t->subtypes);
+                fprintf (f," ");
+            }
+            fprintf (f, "OF ");
+            PrintType (f, head, bt->a.sequenceOf);
+            break;
+
+        case BASICTYPE_SETOF:
+            fprintf (f, "SET ");
+            if (t->subtypes != NULL)
+            {
+                PrintSubtype (f, head, t, t->subtypes);
+                fprintf (f," ");
+            }
+            fprintf (f, "OF ");
+            PrintType (f, head, bt->a.setOf);
+            break;
+
+
+        case BASICTYPE_SELECTION:
+            fprintf (f, "%s < ", bt->a.selection->fieldName);
+            PrintType (f, head, bt->a.selection->typeRef);
+            break;
+
+
+
+
+        case BASICTYPE_COMPONENTSOF:
+            fprintf (f, "COMPONENTS OF ");
+            PrintType (f, NULL, bt->a.componentsOf);
+            break;
+
+
+
+        case BASICTYPE_ANYDEFINEDBY:
+            fprintf (f, "ANY DEFINED BY %s", bt->a.anyDefinedBy->fieldName);
+            break;
+
+
+        case BASICTYPE_LOCALTYPEREF:
+            fprintf (f, "%s", bt->a.localTypeRef->typeName);
+            break;
+
+        case BASICTYPE_IMPORTTYPEREF:
+            /* attempt to keep special scoping, ie modname.type forms */
+            if (bt->a.importTypeRef->moduleName != NULL)
+                fprintf (f,"%s.", bt->a.importTypeRef->moduleName);
+            fprintf (f, "%s", bt->a.importTypeRef->typeName);
+            break;
+
+
+        case BASICTYPE_UNKNOWN:
+            fprintf (f, "unknown type !?!");
+            break;
+
+        case BASICTYPE_BOOLEAN:
+            fprintf (f, "BOOLEAN");
+            break;
+
+
+        case BASICTYPE_INTEGER:
+            fprintf (f, "INTEGER");
+            if ((bt->a.integer != NULL) && !LIST_EMPTY (bt->a.integer))
+            {
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "{\n");
+                indentG += indentStepG;
+                PrintNamedElmts (f, head, t, bt->a.integer);
+                indentG -= indentStepG;
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "}");
+            }
+            break;
+
+
+        case BASICTYPE_BITSTRING:
+            fprintf (f, "BIT STRING");
+            if ((bt->a.bitString != NULL) && !LIST_EMPTY (bt->a.bitString))
+            {
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "{\n");
+                indentG += indentStepG;
+                PrintNamedElmts (f, head, t, bt->a.bitString);
+                indentG -= indentStepG;
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "}");
+            }
+            break;
+
+        case BASICTYPE_OCTETSTRING:
+            fprintf (f, "OCTET STRING");
+            break;
+
+        case BASICTYPE_NULL:
+            fprintf (f, "NULL");
+            break;
+
+        case BASICTYPE_OID:
+            fprintf (f, "OBJECT IDENTIFIER");
+            break;
+
+        case BASICTYPE_REAL:
+            fprintf (f, "REAL");
+            break;
+
+        case BASICTYPE_ENUMERATED:
+            fprintf (f, "ENUMERATED");
+            if ((bt->a.enumerated != NULL) && !LIST_EMPTY (bt->a.enumerated))
+            {
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "{\n");
+                indentG += indentStepG;
+                PrintNamedElmts (f, head, t, bt->a.enumerated);
+                indentG -= indentStepG;
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "}");
+            }
+            break;
+
+        case BASICTYPE_ANY:
+            fprintf (f, "ANY");
+            break;
+
+        case BASICTYPE_MACROTYPE:
+            switch (bt->a.macroType->choiceId)
+            {
+        case MACROTYPE_ROSOPERATION:
+        case MACROTYPE_ASNABSTRACTOPERATION:
+            PrintRosOperationMacroType (f, head, t, bt, bt->a.macroType->a.rosOperation);
+            break;
+
+        case MACROTYPE_ROSERROR:
+        case MACROTYPE_ASNABSTRACTERROR:
+            PrintRosErrorMacroType (f, head, t, bt, bt->a.macroType->a.rosError);
+            break;
+
+        case MACROTYPE_ROSBIND:
+        case MACROTYPE_ROSUNBIND:
+            PrintRosBindMacroType (f, head, t, bt, bt->a.macroType->a.rosBind);
+            break;
+
+        case MACROTYPE_ROSASE:
+            PrintRosAseMacroType (f, head, t, bt, bt->a.macroType->a.rosAse);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONS:
+            PrintMtsasExtensionsMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensions);
+            break;
+
+        case MACROTYPE_MTSASEXTENSION:
+            PrintMtsasExtensionMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtension);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONATTRIBUTE:
+            PrintMtsasExtensionAttributeMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensionAttribute);
+            break;
+
+        case MACROTYPE_MTSASTOKEN:
+            PrintMtsasTokenMacroType (f, head, t, bt, bt->a.macroType->a.mtsasToken);
+            break;
+
+        case MACROTYPE_MTSASTOKENDATA:
+            PrintMtsasTokenDataMacroType (f, head, t, bt, bt->a.macroType->a.mtsasTokenData);
+            break;
+
+        case MACROTYPE_MTSASSECURITYCATEGORY:
+            PrintMtsasSecurityCategoryMacroType (f, head, t, bt, bt->a.macroType->a.mtsasSecurityCategory);
+            break;
+
+        case MACROTYPE_ASNOBJECT:
+            PrintAsnObjectMacroType (f, head, t, bt, bt->a.macroType->a.asnObject);
+            break;
+
+        case MACROTYPE_ASNPORT:
+            PrintAsnPortMacroType (f, head, t, bt, bt->a.macroType->a.asnPort);
+            break;
+
+        case MACROTYPE_ASNABSTRACTBIND:
+        case MACROTYPE_ASNABSTRACTUNBIND:
+            PrintAsnAbstractBindMacroType (f, head, t, bt, bt->a.macroType->a.asnAbstractBind);
+            break;
+
+        case MACROTYPE_AFALGORITHM:
+            PrintAfAlgorithmMacroType (f, head, t, bt, bt->a.macroType->a.afAlgorithm);
+            break;
+
+        case MACROTYPE_AFENCRYPTED:
+            PrintAfEncryptedMacroType (f, head, t, bt, bt->a.macroType->a.afEncrypted);
+            break;
+
+        case MACROTYPE_AFSIGNED:
+            PrintAfSignedMacroType (f, head, t, bt, bt->a.macroType->a.afSigned);
+            break;
+
+        case MACROTYPE_AFSIGNATURE:
+            PrintAfSignatureMacroType (f, head, t, bt, bt->a.macroType->a.afSignature);
+            break;
+
+        case MACROTYPE_AFPROTECTED:
+            PrintAfProtectedMacroType (f, head, t, bt, bt->a.macroType->a.afProtected);
+            break;
+
+        case MACROTYPE_SNMPOBJECTTYPE:
+            PrintSnmpObjectTypeMacroType (f, head, t, bt, bt->a.macroType->a.snmpObjectType);
+            break;
+
+        default:
+            fprintf (f, "< unknown macro type id ?! >");
+
+    } /* end macro type switch */
+    break;
+
+        /*
+         * @MACRO@ add new macro printers above this point
+         */
+
+        case BASICTYPE_MACRODEF:
+            /*
+             * printing this should be handled in PrintTypeDefs
+             */
+            break;
+
+
+        default:
+            fprintf (f, "< unknown type id ?! >");
+
+    }
+}  /* PrintBasicType */
+
+
+
+void
+PrintElmtType PARAMS ((f, head, t, nt),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    NamedType *nt)
+{
+    if (nt->fieldName != NULL)
+        fprintf (f, "%s ", nt->fieldName);
+
+    PrintType (f, head, nt->type);
+
+}  /* PrintElmtType */
+
+void
+PrintElmtTypes PARAMS ((f, head, t, e),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    NamedTypeList *e)
+{
+    NamedType *nt;
+    NamedType *last;
+
+    if ((e == NULL) || LIST_EMPTY (e))
+        return;
+
+    last = (NamedType*)LAST_LIST_ELMT (e);
+    FOR_EACH_LIST_ELMT (nt, e)
+    {
+
+        PrintElmtType (f, head, t, nt);
+        if (nt != last)
+        {
+            fprintf (f, ",\n");
+            INDENT (f, indentG);
+        }
+    }
+}  /* PrintElmtTypes */
+
+
+
+
+void
+PrintValueDefs PARAMS ((f, vList),
+    FILE *f _AND_
+    ValueDefList *vList)
+{
+    ValueDef *v;
+    FOR_EACH_LIST_ELMT (v, vList)
+    {
+        PrintValueDef (f, v);
+    }
+}  /* PrintValueDefs */
+
+
+void
+PrintValueDef PARAMS ((f, v),
+    FILE *f _AND_
+    ValueDef *v)
+{
+    fprintf (f, "%s ", v->definedName);
+
+    if (v->value->type != NULL)
+        PrintType (f, NULL, v->value->type);
+    else
+        /* just go by valueType */
+        PrintTypeById (f, v->value->valueType);
+
+    fprintf (f, " ::= ");
+    indentG += indentStepG;
+    PrintValue (f, v, v->value->type, v->value);
+    fprintf (f, "\n\n");
+    indentG -= indentStepG;
+}  /* PrintValueDef */
+
+
+void
+PrintValue PARAMS ((f, head, valuesType, v),
+    FILE *f _AND_
+    ValueDef *head _AND_
+    Type *valuesType _AND_
+    Value *v)
+{
+    if (v == NULL)
+        return;
+
+    PrintBasicValue (f, head, valuesType, v, v->basicValue);
+
+}  /* PrintValue */
+
+
+void
+PrintBasicValue PARAMS ((f, head, valuesType, v, bv),
+    FILE *f _AND_
+    ValueDef *head _AND_
+    Type *valuesType _AND_
+    Value *v _AND_
+    BasicValue *bv)
+{
+    if (v == NULL)
+        return;
+
+
+    switch (bv->choiceId)
+    {
+        case BASICVALUE_UNKNOWN:
+            fprintf (f, "<unknown value>");
+            break;
+
+        case BASICVALUE_EMPTY:
+            fprintf (f,"{ }");
+            break;
+
+        case BASICVALUE_INTEGER:
+            fprintf (f, "%d", bv->a.integer);
+            break;
+
+        case BASICVALUE_SPECIALINTEGER:
+            if (bv->a.specialInteger == MAX_INT)
+                fprintf (f, "MAX");
+            else
+                fprintf (f, "MIN");
+
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            if (bv->a.boolean)
+                fprintf (f,"TRUE");
+            else
+                fprintf (f,"FALSE");
+            break;
+
+        case BASICVALUE_REAL:
+            fprintf (f, "%f", bv->a.real);
+            break;
+
+        case BASICVALUE_SPECIALREAL:
+            if (bv->a.specialReal == PLUS_INFINITY_REAL)
+                fprintf (f, "PLUS INFINITY");
+            else
+                fprintf (f, "MINUS INFINITY");
+
+            break;
+
+        case BASICVALUE_ASCIITEXT:
+            fprintf (f, "\"%s\"", bv->a.asciiText->octs);
+            break;
+
+        case BASICVALUE_ASCIIHEX:
+            fprintf (f, "\"%s\"", bv->a.asciiHex->octs);
+            break;
+
+        case BASICVALUE_ASCIIBITSTRING:
+            fprintf (f, "\"%s\"", bv->a.asciiBitString->octs);
+            break;
+
+        case BASICVALUE_OID:
+            PrintEncodedOid (f, bv->a.oid);
+            break;
+
+        case BASICVALUE_LINKEDOID:
+            PrintOid (f, bv->a.linkedOid);
+            break;
+
+        case BASICVALUE_BERVALUE:
+            fprintf (f,"<PrintBerValue not coded yet");
+            break;
+
+        case BASICVALUE_PERVALUE:
+            fprintf (f,"<PrintPerValue not coded yet");
+            break;
+
+        case BASICVALUE_NAMEDVALUE:
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f,"{\n");
+            indentG += indentStepG;
+            PrintElmtValue (f, head, v, bv->a.namedValue);
+            indentG -= indentStepG;
+            fprintf (f,"\n");
+            INDENT (f, indentG);
+            fprintf (f,"}");
+            break;
+
+        case BASICVALUE_NULL:
+            fprintf (f,"NULL");
+            break;
+
+        case BASICVALUE_LOCALVALUEREF:
+            fprintf (f, "%s", bv->a.localValueRef->valueName);
+            break;
+
+        case BASICVALUE_IMPORTVALUEREF:
+            fprintf (f, "%s", bv->a.importValueRef->valueName);
+            break;
+
+        case BASICVALUE_VALUENOTATION:
+            fprintf (f, "-- snacc warning: can't parse this value yet --");
+            fprintf (f, "%s", bv->a.valueNotation->octs);
+            break;
+
+
+        default:
+           fprintf (stderr,"PrintBasicValue: ERROR - unknown value type\n");
+    }
+
+}  /* PrintBasicValue */
+
+
+void
+PrintElmtValue PARAMS ((f, head, v, nv),
+    FILE *f _AND_
+    ValueDef *head _AND_
+    Value *v _AND_
+    NamedValue *nv)
+{
+    if (nv->fieldName != NULL)
+        fprintf (f, "%s ", nv->fieldName);
+
+    PrintValue (f, NULL, NULL,  nv->value);
+}  /* PrintElmtValue */
+
+
+void
+PrintElmtValues PARAMS ((f, head, v, e),
+    FILE *f _AND_
+    ValueDef *head _AND_
+    Value *v _AND_
+    NamedValueList *e)
+{
+    NamedValue *nv;
+    NamedValue *last;
+
+    if ((e == NULL) || LIST_EMPTY (e))
+        return;
+
+    last = (NamedValue*)LAST_LIST_ELMT (e);
+    FOR_EACH_LIST_ELMT (nv, e)
+    {
+        PrintElmtValue (f, head, v, nv);
+        if (nv != last)
+        {
+            fprintf (f, ",\n");
+            INDENT (f, indentG);
+        }
+    }
+}  /* PrintElmtValues */
+
+
+void
+PrintTypeById PARAMS ((f, typeId),
+    FILE *f _AND_
+    int typeId)
+{
+    switch (typeId)
+    {
+        case BASICTYPE_UNKNOWN:
+            fprintf (f, "UNKNOWN");
+            break;
+
+        case BASICTYPE_BOOLEAN:
+            fprintf (f, "BOOLEAN");
+            break;
+
+        case BASICTYPE_INTEGER:
+            fprintf (f, "INTEGER");
+            break;
+
+        case BASICTYPE_BITSTRING:
+            fprintf (f, "BIT STRING");
+            break;
+
+        case BASICTYPE_OCTETSTRING:
+            fprintf (f, "OCTET STRING");
+            break;
+
+
+        case BASICTYPE_NULL:
+            fprintf (f, "NULL");
+            break;
+
+        case BASICTYPE_SEQUENCE:
+            fprintf (f, "SEQUENCE");
+            break;
+
+        case BASICTYPE_SEQUENCEOF:
+            fprintf (f, "SEQUENCE OF");
+            break;
+
+        case BASICTYPE_SET:
+            fprintf (f, "SET");
+            break;
+
+        case BASICTYPE_SETOF:
+            fprintf (f, "SET OF");
+            break;
+
+        case BASICTYPE_CHOICE:
+            fprintf (f, "CHOICE");
+            break;
+
+        case BASICTYPE_SELECTION:
+            fprintf (f, "SELECTION");
+            break;
+
+        case BASICTYPE_ANY:
+            fprintf (f, "ANY");
+            break;
+
+        case BASICTYPE_ANYDEFINEDBY:
+            fprintf (f, "ANY DEFINED BY");
+            break;
+
+        case BASICTYPE_OID:
+            fprintf (f, "OBJECT IDENTIFIER");
+            break;
+
+        case BASICTYPE_ENUMERATED:
+            fprintf (f, "ENUMERATED");
+            break;
+
+        case BASICTYPE_REAL:
+            fprintf (f, "REAL");
+            break;
+
+        case BASICTYPE_COMPONENTSOF:
+            fprintf (f, "COMPONENTS OF");
+            break;
+
+        default:
+            fprintf (f, "ERROR - %d is an unknown type id\n", typeId);
+    }
+}  /* PrintTypeById */
+
+
+void
+PrintTag PARAMS ((f, tag),
+    FILE *f _AND_
+    Tag *tag)
+{
+    char *name=NULL;
+
+    if (tag->tclass == UNIV)
+    {
+        switch (tag->code)
+        {
+           case BOOLEAN_TAG_CODE: name = "BOOLEAN";
+                        break;
+           case INTEGER_TAG_CODE: name = "INTEGER";
+                        break;
+           case BITSTRING_TAG_CODE: name = "BITSTRING";
+                        break;
+           case OCTETSTRING_TAG_CODE: name = "OCTETSTRING";
+                        break;
+           case NULLTYPE_TAG_CODE: name = "NULL TYPE";
+                        break;
+           case OID_TAG_CODE: name = "OBJECT ID";
+                        break;
+           case OD_TAG_CODE: name = "OBEJECT DESCRIPTOR";
+                        break;
+           case EXTERNAL_TAG_CODE: name = "EXTERNAL";
+                        break;
+           case REAL_TAG_CODE: name = "REAL";
+                        break;
+           case ENUM_TAG_CODE: name = "ENUMERATED";
+                        break;
+           case SEQ_TAG_CODE: name = "SEQUENCE";
+                        break;
+           case SET_TAG_CODE: name = "SET";
+                        break;
+           case NUMERICSTRING_TAG_CODE: name = "NUMERIC STRING";
+                        break;
+           case PRINTABLESTRING_TAG_CODE: name = "PRINTABLE STRING";
+                        break;
+           case TELETEXSTRING_TAG_CODE: name = "TELETEX STRING";
+                        break;
+           case VIDEOTEXSTRING_TAG_CODE: name = "VIDEOTEX STRING";
+                        break;
+           case IA5STRING_TAG_CODE: name = "IA5 STRING";
+                        break;
+           case UTCTIME_TAG_CODE:  name = "UTC TIME";
+                        break;
+           case GENERALIZEDTIME_TAG_CODE: name = "GENERALIZED TIME";
+                        break;
+           case GRAPHICSTRING_TAG_CODE: name = "GRAPHIC STRING";
+                        break;
+           case VISIBLESTRING_TAG_CODE: name = "VISIBLE STRING";
+                        break;
+           case GENERALSTRING_TAG_CODE: name = "GENERAL STRING";
+                        break;
+
+           default: name = "UNKNOWN UNIVERSAL TYPE";
+        }
+        fprintf (f, "[UNIVERSAL %d]", tag->code);
+    }
+    else  if (tag->tclass  == APPL)
+    {
+        fprintf (f, "[APPLICATION %d]", tag->code);
+    }
+    else  if (tag->tclass  == PRIV)
+    {
+        fprintf (f, "[PRIVATE %d]", tag->code);
+    }
+    else  if (tag->tclass  == CNTX)
+    {
+        fprintf (f, "[%d]", tag->code);
+    }
+
+    if (tag->explicit)
+        fprintf (f, " EXPLICIT");
+
+}  /* PrintTag */
+
+
+void
+PrintSubtype PARAMS ((f, head, t, s),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    Subtype *s)
+{
+    Subtype *tmpS;
+    Subtype *last;
+
+    if (s == NULL)
+        return;
+
+/*     fprintf (f, "("); */
+
+    switch (s->choiceId)
+    {
+        case SUBTYPE_SINGLE:
+            PrintSubtypeValue (f, head, t, s->a.single);
+        break;
+
+        case SUBTYPE_AND:
+            FOR_EACH_LIST_ELMT (tmpS, s->a.and)
+            {
+                fprintf (f, "(");
+                PrintSubtype (f, head, t, tmpS);
+                fprintf (f, ")");
+            }
+        break;
+
+
+        case SUBTYPE_OR:
+            if ((s->a.or != NULL) && !LIST_EMPTY (s->a.or))
+                last = (Subtype*)LAST_LIST_ELMT (s->a.or);
+            FOR_EACH_LIST_ELMT (tmpS, s->a.or)
+            {
+                fprintf (f, "(");
+                PrintSubtype (f, head, t, tmpS);
+                fprintf (f, ")");
+                if (tmpS != last)
+                    fprintf (f, " | ");
+            }
+        break;
+
+        case SUBTYPE_NOT:
+            fprintf (f, "NOT (");
+        PrintSubtype (f, head, t, s->a.not);
+        fprintf (f, ")");
+        break;
+
+        default:
+        fprintf (stderr, "PrintSubtype: ERROR - unknown Subtypes choiceId\n");
+        break;
+    }
+
+/*     fprintf (f, ")"); */
+
+
+}  /* PrintSubtype */
+
+
+
+void
+PrintSubtypeValue PARAMS ((f, head, t, s),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    SubtypeValue *s)
+{
+    if (s == NULL)
+        return;
+
+    switch (s->choiceId)
+    {
+        case SUBTYPEVALUE_SINGLEVALUE:
+            PrintValue (f, NULL, NULL, s->a.singleValue);
+            break;
+
+        case SUBTYPEVALUE_CONTAINED:
+            fprintf (f, "<PrintContainedSubtype not coded yet\n");
+            break;
+
+        case SUBTYPEVALUE_VALUERANGE:
+            PrintValue (f, NULL, NULL, s->a.valueRange->lowerEndValue);
+            if (!s->a.valueRange->lowerEndInclusive)
+                fprintf (f, " >");
+            fprintf (f,"..");
+            if (!s->a.valueRange->upperEndInclusive)
+                fprintf (f, "< ");
+            PrintValue (f, NULL, NULL, s->a.valueRange->upperEndValue);
+            break;
+
+
+        case SUBTYPEVALUE_PERMITTEDALPHABET:
+            fprintf (f,"FROM ");
+            PrintSubtype (f, head, t, s->a.permittedAlphabet);
+            break;
+
+        case SUBTYPEVALUE_SIZECONSTRAINT:
+            fprintf (f,"SIZE ");
+            PrintSubtype (f, head, t, s->a.sizeConstraint);
+            break;
+
+        case SUBTYPEVALUE_INNERSUBTYPE:
+            PrintInnerSubtype (f, head, t, s->a.innerSubtype);
+            break;
+
+        default:
+           fprintf (stderr, "PrintSubtype: ERROR - unknown Subtype choiceId\n");
+            break;
+    }
+}   /* PrintSubtype */
+
+
+void
+PrintInnerSubtype PARAMS ((f, head, t, i),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    InnerSubtype *i)
+{
+    Constraint *constraint;
+    if (i->constraintType == SINGLE_CT)
+    {
+        fprintf (f,"WITH COMPONENT ");
+        constraint = *(Constraint**)AsnListFirst (i->constraints);
+        PrintSubtype (f, head, t, constraint->valueConstraints);
+    }
+    else
+    {
+        fprintf (f, "WITH COMPONENTS\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+        if (i->constraintType == PARTIAL_CT)
+        {
+            INDENT (f, indentG);
+            fprintf (f, "...,\n");
+        }
+        PrintMultipleTypeConstraints (f, head, t, i->constraints);
+        indentG -= indentStepG;
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        fprintf (f, "}");
+
+    }
+}  /* PrintInnerSubtype */
+
+
+
+void
+PrintMultipleTypeConstraints PARAMS ((f, head, t, cList),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    ConstraintList *cList)
+{
+    Constraint *c;
+    Constraint *last;
+
+    if ((cList == NULL) || LIST_EMPTY (cList))
+        return;
+
+    last  = (Constraint*)LAST_LIST_ELMT (cList);
+    FOR_EACH_LIST_ELMT (c, cList)
+    {
+        if (c->fieldRef != NULL)
+        {
+            INDENT (f, indentG);
+            fprintf (f, "%s ", c->fieldRef);
+        }
+
+
+        PrintSubtype (f, head, t, c->valueConstraints);
+
+        if (c->presenceConstraint == ABSENT_CT)
+            fprintf (f, " ABSENT");
+        if (c->presenceConstraint == PRESENT_CT)
+            fprintf (f, " PRESENT");
+        if (c->presenceConstraint == OPTIONAL_CT)
+            fprintf (f, " OPTIONAL");
+
+        if (c != last)
+            fprintf (f, ",\n");
+
+    }
+} /* PrintMultipleTypeConstraints */
+
+
+
+void
+PrintNamedElmts PARAMS ((f, head, t, n),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    ValueDefList *n)
+{
+    ValueDef *vd;
+    ValueDef *last;
+
+    if ((n == NULL) || LIST_EMPTY (n))
+        return;
+
+    last = (ValueDef*)LAST_LIST_ELMT (n);
+    FOR_EACH_LIST_ELMT (vd, n)
+    {
+        INDENT (f, indentG);
+        fprintf (f, "%s (", vd->definedName);
+        PrintValue (f, NULL, NULL, vd->value);
+        fprintf (f,")");
+        if (vd != last)
+            fprintf (f,",\n");
+    }
+}  /* PrintNamedElmts */
+
+
+
+
+void
+PrintRosOperationMacroType PARAMS ((f, head, t, bt, op),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosOperationMacroType *op)
+{
+    TypeOrValue *tOrV;
+    TypeOrValue *last;
+
+    if (bt->a.macroType->choiceId == MACROTYPE_ROSOPERATION)
+        fprintf (f, "OPERATION");
+    else
+        fprintf (f, "ABSTRACT-OPERATION");
+
+    indentG += indentStepG;
+    if (op->arguments != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "ARGUMENT\n");
+        indentG += indentStepG;
+
+        INDENT (f, indentG);
+
+        if (op->arguments->fieldName != NULL)
+            fprintf (f, "%s ", op->arguments->fieldName);
+
+        PrintType (f, head, op->arguments->type);
+        indentG -= indentStepG;
+    }
+
+    if (op->result != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "RESULT\n");
+        indentG += indentStepG;
+
+        INDENT (f, indentG);
+
+        if (op->arguments->fieldName != NULL)
+            fprintf (f, "%s ", op->arguments->fieldName);
+
+        PrintType (f, head, op->result->type);
+        indentG -= indentStepG;
+    }
+
+    if ((op->errors == NULL) || (!LIST_EMPTY (op->errors)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "ERRORS\n");
+        INDENT (f, indentG);
+        fprintf (f,"{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (op->errors);
+        FOR_EACH_LIST_ELMT (tOrV, op->errors)
+        {
+            INDENT (f, indentG);
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV  != last)
+                fprintf (f, ",\n");
+
+        }
+        indentG -= indentStepG;
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    if ((op->linkedOps != NULL) && (!LIST_EMPTY (op->linkedOps)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "LINKED\n");
+        INDENT (f, indentG);
+        fprintf (f,"{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (op->linkedOps);
+        FOR_EACH_LIST_ELMT (tOrV, op->linkedOps)
+        {
+            INDENT (f, indentG);
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV != last)
+                fprintf (f, ",\n");
+        }
+        indentG -= indentStepG;
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, " }");
+    }
+
+    indentG -= indentStepG;
+
+} /* PrintRosOperationMacroType */
+
+
+
+void
+PrintRosErrorMacroType PARAMS ((f, head, t, bt, err),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosErrorMacroType *err)
+{
+    if (bt->a.macroType->choiceId == MACROTYPE_ROSERROR)
+        fprintf (f,"ERROR\n");
+    else
+        fprintf (f,"ABSTRACT-ERROR\n");
+
+    indentG += indentStepG;
+
+    if (err->parameter != NULL)
+    {
+        INDENT (f, indentG);
+        fprintf (f,"PARAMETER ");
+        indentG += indentStepG;
+        PrintElmtType (f, head, t, err->parameter);
+        indentG -= indentStepG;
+    }
+    indentG -= indentStepG;
+
+}  /* PrintRosErrorMacroType */
+
+
+void
+PrintRosBindMacroType PARAMS ((f, head, t, bt, bind),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosBindMacroType *bind)
+{
+    if (bt->a.macroType->choiceId == MACROTYPE_ROSBIND)
+        fprintf (f,"BIND");
+    else
+        fprintf (f,"UNBIND");
+
+    indentG += indentStepG;
+
+    if (bind->argument != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        fprintf (f,"ARGUMENT\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintElmtType (f, head, t, bind->argument);
+        indentG -= indentStepG;
+    }
+
+    if (bind->result != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        fprintf (f,"RESULT\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintElmtType (f, head, t, bind->result);
+        indentG -= indentStepG;
+    }
+
+    if (bind->error != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        if (bt->a.macroType->choiceId == MACROTYPE_ROSBIND)
+            fprintf (f,"BIND-ERROR\n");
+        else
+            fprintf (f,"UNBIND-ERROR\n");
+
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintElmtType (f, head, t, bind->error);
+        indentG -= indentStepG;
+    }
+
+    indentG -= indentStepG;
+
+}  /* PrintRosBindMacroType */
+
+
+void
+PrintRosAseMacroType PARAMS ((f, head, t, bt, ase),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAseMacroType *ase)
+{
+    Value *v;
+    Value *last;
+
+    fprintf (f, "APPLICATION-SERVICE-ELEMENT");
+    indentG += indentStepG;
+
+    if ((ase->operations != NULL)&& (!LIST_EMPTY (ase->operations)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"OPERATIONS\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+
+        indentG += indentStepG;
+
+        last = (Value*)LAST_LIST_ELMT (ase->operations);
+        FOR_EACH_LIST_ELMT (v, ase->operations)
+        {
+            INDENT (f, indentG);
+            PrintValue (f, NULL, t, v);
+            if (v != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    else  /* either suuplier invokes or consumer invokes will be valid */
+    {
+        if ((ase->consumerInvokes != NULL) && (!LIST_EMPTY (ase->consumerInvokes)))
+        {
+            fprintf (f,"\n");
+            INDENT (f, indentG);
+            fprintf (f,"CONSUMER INVOKES\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*) LAST_LIST_ELMT (ase->consumerInvokes);
+            FOR_EACH_LIST_ELMT (v, ase->consumerInvokes)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+        if ((ase->operations != NULL) && (!LIST_EMPTY (ase->operations)))
+        {
+            fprintf (f,"\n");
+            INDENT (f, indentG);
+            fprintf (f,"SUPPLIER INVOKES\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*)LAST_LIST_ELMT (ase->supplierInvokes);
+            FOR_EACH_LIST_ELMT (v, ase->supplierInvokes)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+    }
+    indentG -= indentStepG;
+
+}  /* PrintRosAseMacrType */
+
+
+
+
+void
+PrintRosAcMacroType PARAMS ((f, head, t, bt, ac),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAcMacroType *ac)
+{
+    Value *v;
+    Value *last;
+    OID *oid;
+    OID *lastOid;
+
+    fprintf (f, "APPLICATION-CONTEXT");
+    indentG += indentStepG;
+
+    /*
+     * print non Ros Elements
+     */
+    fprintf (f,"\n");
+    INDENT (f, indentG);
+    fprintf (f,"APPLICATION-SERVICE-ELEMENTS\n");
+    INDENT (f, indentG);
+    fprintf (f, "{\n");
+
+    indentG += indentStepG;
+    if ((ac->nonRoElements == NULL) && (!LIST_EMPTY (ac->nonRoElements)))
+        last = (Value*)LAST_LIST_ELMT (ac->nonRoElements);
+    FOR_EACH_LIST_ELMT (v, ac->nonRoElements)
+    {
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, v);
+        if (v != last)
+            fprintf (f, ",\n");
+    }
+    fprintf (f, "}\n");
+
+    /*
+     * Print Bind Type
+     */
+    INDENT (f, indentG);
+    fprintf (f,"BIND\n");
+    INDENT (f, indentG);
+    PrintType (f, head, ac->bindMacroType);
+    fprintf (f, "\n");
+
+    /*
+     * Print unbind Type
+     */
+    INDENT (f, indentG);
+    fprintf (f,"UNBIND\n");
+    INDENT (f, indentG);
+    PrintType (f, head, ac->unbindMacroType);
+
+
+    if (ac->remoteOperations != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        fprintf (f,"REMOTE OPERATIONS { ");
+        PrintValue (f, NULL, t, ac->remoteOperations);
+        fprintf (f, " }");
+
+        if ((ac->operationsOf != NULL) && (!LIST_EMPTY (ac->operationsOf)))
+        {
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f,"OPERATIONS OF\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*)LAST_LIST_ELMT (ac->operationsOf);
+            FOR_EACH_LIST_ELMT (v,  ac->operationsOf)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+
+        if ((ac->initiatorConsumerOf != NULL) && (!LIST_EMPTY (ac->initiatorConsumerOf)))
+        {
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f,"INITIATOR CONSUMER OF\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*)LAST_LIST_ELMT (ac->initiatorConsumerOf);
+            FOR_EACH_LIST_ELMT (v, ac->initiatorConsumerOf)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+
+        if ((ac->responderConsumerOf != NULL) && (!LIST_EMPTY (ac->responderConsumerOf)))
+        {
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f,"RESPONDER CONSUMER OF\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*)LAST_LIST_ELMT (ac->responderConsumerOf);
+            FOR_EACH_LIST_ELMT (v, ac->responderConsumerOf)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+    }
+
+    fprintf (f,"\n");
+    INDENT (f, indentG);
+    fprintf (f,"ABSTRACT SYNTAXES\n");
+    INDENT (f, indentG);
+    fprintf (f, "{\n");
+
+    if ((ac->abstractSyntaxes != NULL) && (!LIST_EMPTY (ac->abstractSyntaxes)))
+    lastOid = (OID*)LAST_LIST_ELMT (ac->abstractSyntaxes);
+    FOR_EACH_LIST_ELMT (oid, ac->abstractSyntaxes)
+    {
+        INDENT (f, indentG);
+        PrintOid (f, oid);
+        if (oid != lastOid)
+            fprintf (f, ",\n");
+    }
+    fprintf (f, "\n");
+    indentG -= indentStepG;
+    INDENT (f, indentG);
+    fprintf (f, "}");
+
+    indentG -= indentStepG;
+
+}  /* PrintRosAcMacroType */
+
+
+void
+PrintMtsasExtensionsMacroType PARAMS ((f, head, t, bt, exts),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionsMacroType *exts)
+{
+    Value *v;
+    Value *last;
+
+    fprintf (f, "EXTENSIONS CHOSEN FROM");
+
+    INDENT (f, indentG);
+    fprintf (f, "{\n");
+
+    indentG += indentStepG;
+    if ((exts->extensions == NULL) && (!LIST_EMPTY (exts->extensions)))
+        last = (Value*)LAST_LIST_ELMT (exts->extensions);
+    FOR_EACH_LIST_ELMT (v, exts->extensions)
+    {
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, v);
+        if (v != last)
+            fprintf (f, ",\n");
+    }
+    fprintf (f, "\n");
+    indentG -= indentStepG;
+    INDENT (f, indentG);
+    fprintf (f, "}");
+
+}  /* PrintMtsasExtensionsMacroType */
+
+
+void
+PrintMtsasExtensionMacroType PARAMS ((f, head, t, bt, ext),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionMacroType *ext)
+{
+
+    fprintf (f, "EXTENSION");
+
+    indentG += indentStepG;
+    if (ext->elmtType != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        PrintElmtType (f, head, t, ext->elmtType);
+
+        if (ext->defaultValue != NULL)
+        {
+            fprintf (f, " DEFAULT ");
+            PrintValue (f, NULL, t, ext->defaultValue);
+        }
+    }
+
+    if ((ext->criticalForSubmission != NULL) ||
+         (ext->criticalForTransfer != NULL) ||
+         (ext->criticalForDelivery != NULL))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "CRITICAL FOR ");
+
+        if (ext->criticalForSubmission != NULL)
+        {
+            fprintf (f, "SUBMISSION");
+            if ((ext->criticalForTransfer != NULL) ||
+                (ext->criticalForDelivery != NULL))
+                fprintf (f,", ");
+        }
+
+        if (ext->criticalForTransfer != NULL)
+        {
+            fprintf (f, "TRANSFER, ");
+            if  (ext->criticalForDelivery != NULL)
+                fprintf (f,", ");
+        }
+
+        if (ext->criticalForDelivery != NULL)
+            fprintf (f, "DELIVERY");
+
+    }
+
+    indentG -= indentStepG;
+
+}  /* PrintMtsasExtensionMacroType */
+
+
+
+
+void
+PrintMtsasExtensionAttributeMacroType PARAMS ((f, head, t, bt, ext),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionAttributeMacroType *ext)
+{
+
+    fprintf (f, "EXTENSION-ATTRIBUTE");
+    if (ext->type != NULL)
+    {
+        fprintf (f, "\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+
+        PrintType (f, head, ext->type);
+        indentG -= indentStepG;
+    }
+
+}  /* PrintMtsasExtensionAttributeMacroType */
+
+
+
+void
+PrintMtsasTokenMacroType PARAMS ((f, head, t, bt, tok),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenMacroType *tok)
+{
+
+    fprintf (f, "TOKEN");
+    if (tok->type != NULL)
+    {
+        fprintf (f, "\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintType (f, head, tok->type);
+        indentG -= indentStepG;
+    }
+
+}  /* PrintMtsasTokenMacro */
+
+
+void
+PrintMtsasTokenDataMacroType PARAMS ((f, head, t, bt, tok),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenDataMacroType *tok)
+{
+
+    fprintf (f, "TOKEN-DATA");
+    if (tok->type != NULL)
+    {
+        fprintf (f, "\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+
+        PrintType (f, head, tok->type);
+        indentG -= indentStepG;
+    }
+
+}  /* PrintMtsasTokenDataMacro */
+
+
+void
+PrintMtsasSecurityCategoryMacroType PARAMS ((f, head, t, bt, sec),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasSecurityCategoryMacroType *sec)
+{
+
+    fprintf (f, "SECURITY-CATEGORY");
+    if (sec->type != NULL)
+    {
+        fprintf (f, "\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+
+        PrintType (f, head, sec->type);
+        indentG -= indentStepG;
+    }
+
+}  /* PrintMtsasSecurityCategoryMacroType */
+
+
+
+void
+PrintAsnObjectMacroType PARAMS ((f, head, t, bt, obj),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnObjectMacroType *obj)
+{
+    AsnPort *ap;
+    AsnPort *last;
+
+    fprintf (f, "OBJECT");
+
+    indentG += indentStepG;
+
+    if ((obj->ports != NULL) && !LIST_EMPTY (obj->ports))
+    {
+
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "PORTS\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (AsnPort*)LAST_LIST_ELMT (obj->ports);
+        FOR_EACH_LIST_ELMT (ap, obj->ports)
+        {
+            INDENT (f, indentG);
+            PrintValue (f, NULL, t, ap->portValue);
+
+            if (ap->portType == CONSUMER_PORT)
+                fprintf (f, " [C]");
+            else if (ap->portType == SUPPLIER_PORT)
+                fprintf (f, " [S]");
+
+            if (ap != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+    indentG -= indentStepG;
+
+}  /* PrintAsnObjectMacroType */
+
+
+
+void
+PrintAsnPortMacroType PARAMS ((f, head, t, bt, p),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnPortMacroType *p)
+{
+    TypeOrValue *tOrV;
+    TypeOrValue *last;
+
+    fprintf (f, "PORT");
+    indentG += indentStepG;
+    if ((p->abstractOps != NULL) && (!LIST_EMPTY (p->abstractOps)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "ABSTRACT OPERATIONS\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (p->abstractOps);
+        FOR_EACH_LIST_ELMT (tOrV, p->abstractOps)
+        {
+            INDENT (f, indentG);
+
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    if ((p->consumerInvokes != NULL) && (!LIST_EMPTY (p->consumerInvokes)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "CONSUMER INVOKES\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (p->consumerInvokes);
+        FOR_EACH_LIST_ELMT (tOrV, p->consumerInvokes)
+        {
+            INDENT (f, indentG);
+
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    if ((p->supplierInvokes != NULL) && (!LIST_EMPTY (p->supplierInvokes)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "SUPPLIER INVOKES\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (p->supplierInvokes);
+        FOR_EACH_LIST_ELMT (tOrV, p->supplierInvokes)
+
+        {
+            INDENT (f, indentG);
+
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    indentG -= indentStepG;
+
+}  /* PrintAsnPortMacroType */
+
+
+
+
+void
+PrintAsnAbstractBindMacroType PARAMS ((f, head, t, bt, bind),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnAbstractBindMacroType *bind)
+{
+    AsnPort *ap;
+    AsnPort *last;
+
+    if (bt->a.macroType->choiceId == MACROTYPE_ASNABSTRACTBIND)
+        fprintf (f, "ABSTRACT-BIND");
+    else
+        fprintf (f, "ABSTRACT-UNBIND");
+
+    indentG += indentStepG;
+
+    if ((bind->ports != NULL) && (!LIST_EMPTY (bind->ports)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        if (bt->a.macroType->choiceId == MACROTYPE_ASNABSTRACTBIND)
+            fprintf (f, "TO\n");
+        else
+            fprintf (f, "FROM\n");
+
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (AsnPort*)LAST_LIST_ELMT (bind->ports);
+        FOR_EACH_LIST_ELMT (ap, bind->ports)
+        {
+            INDENT (f, indentG);
+            PrintValue (f, NULL, t, ap->portValue);
+
+            if (ap->portType == CONSUMER_PORT)
+                fprintf (f, " [C]");
+            else if (ap->portType == SUPPLIER_PORT)
+                fprintf (f, " [S]");
+
+            if (ap != last)
+                fprintf (f, ",\n");
+        }
+
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    if (bind->type != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        PrintType (f, head, bind->type);
+    }
+
+    indentG -= indentStepG;
+
+}  /* PrintAsnAbstractBindMacroType */
+
+
+
+void
+PrintAfAlgorithmMacroType PARAMS ((f, head, t, bt, alg),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *alg)
+{
+    indentG += indentStepG;
+    fprintf (f, "ALGORITHM PARAMETER ");
+    PrintType (f, head, alg);
+    indentG -= indentStepG;
+}  /* PrintAfAlgorithmMacroType */
+
+
+void
+PrintAfEncryptedMacroType PARAMS ((f, head, t, bt, encrypt),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *encrypt)
+{
+    indentG += indentStepG;
+    fprintf (f, "ENCRYPTED ");
+    PrintType (f, head, encrypt);
+    indentG -= indentStepG;
+}  /* PrintAfEncryptedMacroType */
+
+
+void
+PrintAfSignedMacroType PARAMS ((f, head, t, bt, sign),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *sign)
+{
+    indentG += indentStepG;
+    fprintf (f, "SIGNED ");
+    PrintType (f, head, sign);
+    indentG -= indentStepG;
+}  /* PrintAfSignedMacroType */
+
+
+void
+PrintAfSignatureMacroType PARAMS ((f, head, t, bt, sig),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *sig)
+{
+    indentG += indentStepG;
+    fprintf (f, "SIGNATURE ");
+    PrintType (f, head, sig);
+    indentG -= indentStepG;
+}  /* PrintAfSignatureMacroType */
+
+
+void
+PrintAfProtectedMacroType PARAMS ((f, head, t, bt, p),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *p)
+{
+    indentG += indentStepG;
+    fprintf (f, "PROTECTED ");
+    PrintType (f, head, p);
+    indentG -= indentStepG;
+}  /* PrintAfMacroType */
+
+
+void
+PrintSnmpObjectTypeMacroType PARAMS ((f, head, t, bt, ot),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    SnmpObjectTypeMacroType *ot)
+{
+    TypeOrValue *tOrV;
+    TypeOrValue *last;
+
+    fprintf (f, "OBJECT-TYPE\n");
+    indentG += indentStepG;
+    INDENT (f,indentG);
+    fprintf (f,"SYNTAX ");
+    indentG += indentStepG;
+    PrintType (f, head, ot->syntax);
+    indentG -= indentStepG;
+
+    fprintf (f,"\n");
+    INDENT (f,indentG);
+    fprintf (f,"ACCESS ");
+    switch (ot->access)
+    {
+        case SNMP_READ_ONLY:
+            fprintf (f,"read-only");
+            break;
+
+        case SNMP_READ_WRITE:
+            fprintf (f,"read-write");
+            break;
+
+        case SNMP_WRITE_ONLY:
+            fprintf (f,"write-only");
+            break;
+
+        case SNMP_NOT_ACCESSIBLE:
+            fprintf (f,"not-accessible");
+            break;
+
+        default:
+            fprintf (f," < ?? unknown access type ?? >");
+    }
+
+    fprintf (f,"\n");
+    INDENT (f, indentG);
+    fprintf (f,"STATUS ");
+    switch (ot->status)
+    {
+        case SNMP_MANDATORY:
+            fprintf (f,"mandatory");
+            break;
+
+        case SNMP_OPTIONAL:
+            fprintf (f,"optional");
+            break;
+
+        case SNMP_OBSOLETE:
+            fprintf (f,"obsolete");
+            break;
+
+        case SNMP_DEPRECATED:
+            fprintf (f,"deprecated");
+            break;
+
+        default:
+            fprintf (f," < ?? unknown status type ?? >");
+    }
+
+    if (ot->description != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"DESCRIPTION\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, ot->description);
+        indentG -= indentStepG;
+    }
+
+    if (ot->reference != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"REFERENCE\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, ot->reference);
+        indentG -= indentStepG;
+    }
+
+    if (ot->index != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"INDEX\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        last = (TypeOrValue*)LAST_LIST_ELMT (ot->index);
+        FOR_EACH_LIST_ELMT (tOrV, ot->index)
+        {
+            INDENT (f, indentG);
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV  != last)
+                fprintf (f, ",\n");
+        }
+        indentG -= indentStepG;
+    }
+
+    if (ot->defVal != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"DEFVAL\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, ot->defVal);
+        indentG -= indentStepG;
+    }
+
+    fprintf (f,"\n");
+
+    indentG -= indentStepG;
+}  /* PrintSnmpObjectTypeMacroType */
+
+
+/*
+ * @MACRO@ add new macro print routines above this point
+ */
+
+void
+PrintMacroDef PARAMS ((f, head),
+    FILE *f _AND_
+    TypeDef *head)
+{
+    char *s;
+
+    fprintf (f,"\n--  Note: snacc does not use macro defs to extend the compiler.");
+    fprintf (f,"\n--  All macros that are understood have been hand coded.");
+    fprintf (f,"\n--  The macro def body is kept as a string only.\n\n");
+
+    s =  head->type->basicType->a.macroDef;
+
+    fprintf (f, "%s MACRO ::=\n", head->definedName);
+    fprintf (f, "%s", s);
+
+}  /* PrintMacroDef */
+
+
+
+void
+PrintEncodedOid PARAMS ((f, eoid),
+    FILE *f _AND_
+    AsnOid *eoid)
+{
+    int i;
+    int arcNum;
+    int firstArcNum;
+    int secondArcNum;
+
+    if (eoid == NULL)
+       return;
+
+    fprintf (f, "{ ");
+
+    for (arcNum = 0, i=0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80);i++)
+        arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+
+    arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+    i++;
+
+    firstArcNum = arcNum / 40;
+    if (firstArcNum > 2)
+        firstArcNum = 2;
+
+    secondArcNum = arcNum - (firstArcNum * 40);
+
+    fprintf (f, "%d ", firstArcNum);
+    fprintf (f, "%d ", secondArcNum);
+    for (; i < eoid->octetLen; )
+    {
+        for (arcNum = 0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80);i++)
+            arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+
+        arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+        i++;
+
+        fprintf (f, "%d ", arcNum);
+    }
+
+    fprintf (f, "}");
+
+}  /* PrintEncodedOid */
+
+
+
+/*
+ * this just prints  a short form of the given type.  It
+ * does not print the components of a constructed type
+ * such as a SEQUENCE
+ * This is used by the header file generators to annotate
+ * the C/C++ types
+ */
+void
+SpecialPrintBasicType PARAMS ((f, head, t, bt),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt)
+{
+    switch (bt->choiceId)
+    {
+
+        case BASICTYPE_SEQUENCE:
+            fprintf (f, "SEQUENCE");
+            break;
+
+        case BASICTYPE_SET:
+            fprintf (f, "SET");
+            break;
+
+        case BASICTYPE_CHOICE:
+            fprintf (f, "CHOICE");
+            break;
+
+
+
+        case BASICTYPE_SEQUENCEOF:
+            fprintf (f, "SEQUENCE ");
+            if (t->subtypes != NULL)
+            {
+                PrintSubtype (f, head, t, t->subtypes);
+                fprintf (f," ");
+            }
+            fprintf (f, "OF ");
+            SpecialPrintType (f, head, t->basicType->a.sequenceOf);
+            break;
+
+        case BASICTYPE_SETOF:
+            fprintf (f, "SET ");
+            if (t->subtypes != NULL)
+            {
+                PrintSubtype (f, head, t, t->subtypes);
+                fprintf (f," ");
+            }
+            fprintf (f, "OF ");
+            SpecialPrintType (f, head, t->basicType->a.sequenceOf);
+            break;
+
+
+        case BASICTYPE_SELECTION:
+            fprintf (f, "%s < ", bt->a.selection->fieldName);
+            PrintType (f, head, bt->a.selection->typeRef);
+            break;
+
+
+
+
+        case BASICTYPE_COMPONENTSOF:
+            fprintf (f, "COMPONENTS OF ");
+            PrintType (f, NULL, bt->a.componentsOf);
+            break;
+
+
+
+        case BASICTYPE_ANYDEFINEDBY:
+            fprintf (f, "ANY DEFINED BY %s", bt->a.anyDefinedBy->fieldName);
+            break;
+
+
+        case BASICTYPE_LOCALTYPEREF:
+            fprintf (f, "%s", bt->a.localTypeRef->typeName);
+            break;
+
+        case BASICTYPE_IMPORTTYPEREF:
+            fprintf (f, "%s", bt->a.importTypeRef->typeName);
+            break;
+
+
+        case BASICTYPE_UNKNOWN:
+            fprintf (f, "unknown type !?!");
+            break;
+
+        case BASICTYPE_BOOLEAN:
+            fprintf (f, "BOOLEAN");
+            break;
+
+
+        case BASICTYPE_INTEGER:
+            fprintf (f, "INTEGER");
+            if ((bt->a.integer != NULL) && !LIST_EMPTY (bt->a.integer))
+                SpecialPrintNamedElmts (f, head, t);
+            break;
+
+
+        case BASICTYPE_BITSTRING:
+            fprintf (f, "BIT STRING");
+            if ((bt->a.bitString != NULL) && !LIST_EMPTY (bt->a.bitString))
+                SpecialPrintNamedElmts (f, head, t);
+            break;
+
+        case BASICTYPE_OCTETSTRING:
+            fprintf (f, "OCTET STRING");
+            break;
+
+        case BASICTYPE_NULL:
+            fprintf (f, "NULL");
+            break;
+
+        case BASICTYPE_OID:
+            fprintf (f, "OBJECT IDENTIFIER");
+            break;
+
+        case BASICTYPE_REAL:
+            fprintf (f, "REAL");
+            break;
+
+        case BASICTYPE_ENUMERATED:
+            fprintf (f, "ENUMERATED");
+            if ((bt->a.enumerated != NULL) && !LIST_EMPTY (bt->a.enumerated))
+                SpecialPrintNamedElmts (f, head, t);
+
+            break;
+
+        case BASICTYPE_ANY:
+            fprintf (f, "ANY");
+            break;
+
+        case BASICTYPE_MACROTYPE:
+            switch (bt->a.macroType->choiceId)
+            {
+        case MACROTYPE_ROSOPERATION:
+        case MACROTYPE_ASNABSTRACTOPERATION:
+            PrintRosOperationMacroType (f, head, t, bt, bt->a.macroType->a.rosOperation);
+            break;
+
+        case MACROTYPE_ROSERROR:
+        case MACROTYPE_ASNABSTRACTERROR:
+            PrintRosErrorMacroType (f, head, t, bt, bt->a.macroType->a.rosError);
+            break;
+
+        case MACROTYPE_ROSBIND:
+        case MACROTYPE_ROSUNBIND:
+            PrintRosBindMacroType (f, head, t, bt, bt->a.macroType->a.rosBind);
+            break;
+
+        case MACROTYPE_ROSASE:
+            PrintRosAseMacroType (f, head, t, bt, bt->a.macroType->a.rosAse);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONS:
+            PrintMtsasExtensionsMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensions);
+            break;
+
+        case MACROTYPE_MTSASEXTENSION:
+            PrintMtsasExtensionMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtension);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONATTRIBUTE:
+            PrintMtsasExtensionAttributeMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensionAttribute);
+            break;
+
+        case MACROTYPE_MTSASTOKEN:
+            PrintMtsasTokenMacroType (f, head, t, bt, bt->a.macroType->a.mtsasToken);
+            break;
+
+        case MACROTYPE_MTSASTOKENDATA:
+            PrintMtsasTokenDataMacroType (f, head, t, bt, bt->a.macroType->a.mtsasTokenData);
+            break;
+
+        case MACROTYPE_MTSASSECURITYCATEGORY:
+            PrintMtsasSecurityCategoryMacroType (f, head, t, bt, bt->a.macroType->a.mtsasSecurityCategory);
+            break;
+
+        case MACROTYPE_ASNOBJECT:
+            PrintAsnObjectMacroType (f, head, t, bt, bt->a.macroType->a.asnObject);
+            break;
+
+        case MACROTYPE_ASNPORT:
+            PrintAsnPortMacroType (f, head, t, bt, bt->a.macroType->a.asnPort);
+            break;
+
+        case MACROTYPE_ASNABSTRACTBIND:
+        case MACROTYPE_ASNABSTRACTUNBIND:
+            PrintAsnAbstractBindMacroType (f, head, t, bt, bt->a.macroType->a.asnAbstractBind);
+            break;
+
+        case MACROTYPE_AFALGORITHM:
+            PrintAfAlgorithmMacroType (f, head, t, bt, bt->a.macroType->a.afAlgorithm);
+            break;
+
+        case MACROTYPE_AFENCRYPTED:
+            PrintAfEncryptedMacroType (f, head, t, bt, bt->a.macroType->a.afEncrypted);
+            break;
+
+        case MACROTYPE_AFSIGNED:
+            PrintAfSignedMacroType (f, head, t, bt, bt->a.macroType->a.afSigned);
+            break;
+
+        case MACROTYPE_AFSIGNATURE:
+            PrintAfSignatureMacroType (f, head, t, bt, bt->a.macroType->a.afSignature);
+            break;
+
+        case MACROTYPE_AFPROTECTED:
+            PrintAfProtectedMacroType (f, head, t, bt, bt->a.macroType->a.afProtected);
+            break;
+
+        case MACROTYPE_SNMPOBJECTTYPE:
+            PrintSnmpObjectTypeMacroType (f, head, t, bt, bt->a.macroType->a.snmpObjectType);
+            break;
+
+        default:
+            fprintf (f, "< unknown macro type id ?! >");
+
+    } /* end macro type switch */
+    break;
+
+        /*
+         * @MACRO@ add new macro printers above this point
+         */
+
+        case BASICTYPE_MACRODEF:
+            /*
+             * printing this should be handled in PrintTypeDefs
+             */
+            break;
+
+
+        default:
+            fprintf (f, "< unknown type id ?! >");
+
+    }
+}  /* SpecialPrintBasicType */
+
+
+/*
+ * this just prints  a short form of the given type.  It
+ * does not print the components of a constructed type
+ * such as a SEQUENCE
+ * This is used by the header file generators to annotate
+ * the C types
+ */
+void
+SpecialPrintType PARAMS ((f, head, t),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t)
+{
+    Tag *tag;
+    Tag *lastTag;
+
+    if (t == NULL)
+        return;
+
+    lastTag = NULL;
+    FOR_EACH_LIST_ELMT (tag, t->tags)
+    {
+        if (!(tag->tclass == UNIV && tag->code == LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId)))
+        {
+            PrintTag (f, tag);
+            fprintf (f, " ");
+        }
+        lastTag = tag;
+    }
+
+    /*
+     * check type has been implicitly tagged
+     */
+    if (t->implicit)
+        fprintf (f, "IMPLICIT ");
+
+    SpecialPrintBasicType (f, head, t, t->basicType);
+
+
+    /*
+     * sequences of and set of print subtypes a special way
+     * so ignore them here
+     */
+    if ((t->subtypes != NULL) &&
+        (t->basicType->choiceId != BASICTYPE_SETOF) &&
+        (t->basicType->choiceId != BASICTYPE_SEQUENCEOF))
+    {
+        fprintf (f," ");
+        PrintSubtype (f, head, t, t->subtypes);
+    }
+
+
+    if (t->defaultVal != NULL)
+    {
+        fprintf (f, " DEFAULT ");
+        if (t->defaultVal->fieldName != NULL)
+            fprintf (f, "%s ", t->defaultVal->fieldName);
+        PrintValue (f, NULL, t, t->defaultVal->value);
+    }
+
+    else if (t->optional)
+        fprintf (f, " OPTIONAL");
+
+
+#ifdef DEBUG
+    fprintf (f, "  -- lineNo = %d", t->lineNo);
+    fprintf (f, " --");
+#endif
+
+}  /* SpecialPrintType */
+
+
+/*
+ * This is used by the header file generators to annotate
+ * the C/C++ types.  This version prints the C version of the
+ * enum/bits elmt names to make sure the programmer can use
+ * the correct defines/enum constants.
+ * NOTE: this can only be called after the CTRI infor is filled in
+ * so the C/C++ names can be accessed
+ */
+void
+SpecialPrintNamedElmts PARAMS ((f, head, t),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t)
+{
+    CNamedElmt *last;
+    CNamedElmt *cne;
+    CNamedElmts *n = NULL;
+
+    if (t->cTypeRefInfo != NULL)
+        n = t->cTypeRefInfo->cNamedElmts;
+
+    if ((n == NULL) && (t->cxxTypeRefInfo != NULL))
+        n = t->cxxTypeRefInfo->namedElmts;
+
+
+    if ((n == NULL) || LIST_EMPTY (n))
+        return;
+
+    fprintf (f," { ");
+    last = (CNamedElmt*)LAST_LIST_ELMT (n);
+    FOR_EACH_LIST_ELMT (cne, n)
+    {
+        fprintf (f, "%s (%d)", cne->name, cne->value);
+        if (cne != last)
+            fprintf (f,", ");
+    }
+    fprintf (f," } ");
+}  /* SpecialPrintNamedElmts */
diff --git a/SecuritySNACCRuntime/compiler/core/print.h b/SecuritySNACCRuntime/compiler/core/print.h
new file mode 100644
index 00000000..51904d72
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/print.h
@@ -0,0 +1,136 @@
+/*
+ * compiler/core/print.h
+ *
+ * These are the prototypes for the typetree printing
+ * routines.  Attempts to convert a typetree back into its original
+ * ASN.1 def.
+ *
+ * Mike Sample
+ * Mar 3/91
+ *
+ * Rewritten 91/09/05
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/print.h,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: print.h,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1994/10/08 03:48:56  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:33  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+
+
+void PrintModule PROTO ((FILE *f, Module *mod));
+
+void PrintExports PROTO ((FILE *f, Module *m));
+
+void PrintOid PROTO ((FILE *f, OID *oid));
+
+void PrintImportElmt PROTO ((FILE *f, ImportElmt *impElmt));
+
+void PrintImportLists PROTO ((FILE *f, ImportModuleList *impLists));
+
+void PrintTypeDefs PROTO ((FILE *f, TypeDefList *typeDefs));
+
+void PrintType PROTO ((FILE *f, TypeDef *head, Type *t));
+
+void PrintBasicType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt));
+
+void PrintElmtType PROTO ((FILE *f, TypeDef *head, Type *t, NamedType *nt));
+
+void PrintElmtTypes PROTO ((FILE *f, TypeDef *head, Type *t, NamedTypeList *e));
+
+void PrintValueDefs PROTO ((FILE *f, ValueDefList *v));
+
+void PrintValueDef PROTO ((FILE *f, ValueDef *v));
+
+void PrintValue PROTO ((FILE *f, ValueDef *head, Type *valuesType, Value *v));
+
+void PrintBasicValue PROTO ((FILE *f, ValueDef *head, Type *valuesType, Value *v, BasicValue *bv));
+
+void PrintElmtValue PROTO ((FILE *f, ValueDef *head, Value *v, NamedValue *nv));
+
+void PrintElmtValues PROTO ((FILE *f, ValueDef *head, Value *v, NamedValueList *e));
+
+void PrintTag PROTO ((FILE *f, Tag *tag));
+
+void PrintSubtype PROTO ((FILE *f, TypeDef *head, Type *t, Subtype *s));
+
+void PrintSubtypeValue PROTO ((FILE *f, TypeDef *head, Type *t, SubtypeValue *s));
+
+void PrintNamedElmts PROTO ((FILE *f, TypeDef *head, Type *t, ValueDefList *n));
+
+void PrintInnerSubtype PROTO ((FILE *f, TypeDef *head, Type *t, InnerSubtype *i));
+
+void PrintMultipleTypeConstraints PROTO ((FILE *f, TypeDef *head, Type *t, ConstraintList *c));
+
+void PrintTypeById PROTO ((FILE *f, int typeId));
+
+
+void PrintRosOperationMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosOperationMacroType *op));
+
+void PrintRosErrorMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosErrorMacroType *err));
+
+void PrintRosBindMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosBindMacroType *bind));
+
+void PrintRosAseMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosAseMacroType *ase));
+
+void PrintRosAcMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosAcMacroType *ac));
+
+void PrintMtsasExtensionsMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionsMacroType *exts));
+
+void PrintMtsasExtensionMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionMacroType *ext));
+
+void PrintMtsasExtensionAttributeMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionAttributeMacroType *ext));
+
+void PrintMtsasTokenMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasTokenMacroType *tok));
+
+void PrintMtsasTokenDataMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasTokenDataMacroType *tok));
+
+void PrintMtsasSecurityCategoryMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasSecurityCategoryMacroType *sec));
+
+void PrintAsnObjectMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, AsnObjectMacroType *obj));
+
+void PrintAsnPortMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, AsnPortMacroType *p));
+
+void PrintAsnAbstractBindMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, AsnAbstractBindMacroType *bind));
+
+void PrintAfAlgorithmMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *alg));
+
+void PrintAfEncryptedMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *encrypt));
+
+void PrintAfSignedMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *sign));
+
+void PrintAfSignatureMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *sig));
+
+void PrintAfProtectedMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *p));
+
+void PrintSnmpObjectTypeMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, SnmpObjectTypeMacroType *ot));
+
+void PrintMacroDef PROTO ((FILE *f, TypeDef *head));
+
+void PrintEncodedOid PROTO ((FILE *f, AsnOid *eoid));
+
+
+void SpecialPrintType PROTO ((FILE *f, TypeDef *head, Type *t));
+
+void SpecialPrintBasicType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt));
+
+void SpecialPrintNamedElmts PROTO ((FILE *f, TypeDef *head, Type *t));
diff --git a/SecuritySNACCRuntime/compiler/core/print2.c b/SecuritySNACCRuntime/compiler/core/print2.c
new file mode 100644
index 00000000..b1591f70
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/print2.c
@@ -0,0 +1,2764 @@
+/*
+ * compiler/core/print.c
+ *
+ *  These routines are for printing the information from a Module
+ *  Data strucuture in ASN.1 form.
+ *
+ *  Useful for debugging the parser and seeing changes caused by
+ *  normalization and sorting.
+ *
+ * Mike Sample
+ * Feb 28/91
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/print2.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: print2.c,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.6  1997/02/28 13:39:55  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.5  1995/08/17 14:58:57  rj
+ * minor typographic change
+ *
+ * Revision 1.4  1995/07/25  19:41:42  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.3  1994/10/08  03:48:53  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.2  1994/09/01  00:42:16  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:32  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "lib-types.h"
+#include "print.h"
+
+
+static int  indentCountG;
+static int  indentG = 0;
+static int  indentStepG =  4;
+
+#define INDENT(f, i)\
+    for (indentCountG = 0; indentCountG < (i); indentCountG++)\
+        fputc (' ', (f))\
+
+/*
+ * Prints the given Module *, mod, to the given FILE *f in
+ * ASN.1 format
+ */
+void
+PrintModule PARAMS ((f, mod),
+    FILE *f _AND_
+    Module *mod)
+{
+
+   if (mod->status == MOD_ERROR)
+   {
+       fprintf (f, "WARNING: this module contains errors\n");
+       fprintf (f,"(probably some type/value is referenced but is not defined or imported)\n");
+       fprintf (f,"The prog. may croak, cross your fingers!\n");
+   }
+
+
+   fprintf (f, "%s ",mod->modId->name);
+   PrintOid (f, mod->modId->oid);
+
+   fprintf (f, "\nDEFINITIONS ");
+
+   if (mod->tagDefault == EXPLICIT_TAGS)
+       fprintf (f, "EXPLICIT TAGS");
+
+   else if (mod->tagDefault == IMPLICIT_TAGS)
+       fprintf (f, "IMPLICIT TAGS");
+   else
+       fprintf (f, "\n\n -- compiler error unknown tag default");
+
+
+   fprintf (f, " ::=\nBEGIN\n\n");
+
+
+
+   PrintExports (f, mod);
+
+   PrintImportLists (f, mod->imports);
+
+   PrintTypeDefs (f, mod->typeDefs);
+   PrintValueDefs (f, mod->valueDefs);
+
+   fprintf (f, "END\n");
+
+}  /* PrintModule */
+
+
+void
+PrintExports PARAMS ((f, m),
+    FILE *f _AND_
+    Module *m)
+{
+    TypeDef *td;
+    ValueDef *vd;
+    int first;
+
+    if (m->exportStatus == EXPORTS_ALL)
+    {
+        fprintf (f, "\n\n-- exports everything\n\n");
+    }
+    else if  (m->exportStatus == EXPORTS_NOTHING)
+    {
+        fprintf (f, "\n\nEXPORTS   -- exports nothing\n\n");
+    }
+    else
+    {
+        fprintf (f, "\n\nEXPORTS\n");
+        first = 1;
+        FOR_EACH_LIST_ELMT (td, m->typeDefs)
+            if (td->exported)
+            {
+                if (!first)
+                    fprintf (f,", ");
+                fprintf (f, "%s", td->definedName);
+                first = 0;
+            }
+
+        FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+            if (vd->exported)
+            {
+                if (!first)
+                    fprintf (f,", ");
+                fprintf (f, "%s", vd->definedName);
+                first = 0;
+            }
+
+        fprintf (f, "\n;\n\n");
+    }
+}  /* PrintExports */
+
+
+
+void
+PrintOid PARAMS ((f, oid),
+    FILE *f _AND_
+    OID *oid)
+{
+    int i;
+
+    if (oid == NULL)
+       return;
+
+    fprintf (f, "{ ");
+    for (;  oid != NULL; oid = oid->next)
+    {
+        /*
+         *  value ref to an integer or if first elmt in
+         *  oid can ref other oid value
+         *  { id-asdc }
+         */
+        if (oid->valueRef != NULL)
+            PrintValue (f, NULL, NULL, oid->valueRef);
+
+        /*
+         * just  "arcNum" format
+         *  { 2 }
+         */
+        else if (oid->arcNum != NULL_OID_ARCNUM)
+            fprintf (f, "%d", oid->arcNum);
+
+
+        fprintf (f, " ");
+    }
+    fprintf (f, "}");
+
+}  /* PrintOid */
+
+
+
+void
+PrintImportElmt PARAMS ((f, impElmt),
+    FILE *f _AND_
+    ImportElmt *impElmt)
+{
+     fprintf (f, "%s",impElmt->name);
+}   /* PrintImportElmt */
+
+
+void
+PrintImportElmts PARAMS ((f, impElmtList),
+    FILE *f _AND_
+    ImportElmtList *impElmtList)
+{
+    ImportElmt *ie;
+    ImportElmt *last;
+
+    if ((impElmtList == NULL) || (LIST_EMPTY (impElmtList)))
+        return;
+
+    last = (ImportElmt*)LAST_LIST_ELMT (impElmtList);
+    FOR_EACH_LIST_ELMT (ie, impElmtList)
+    {
+        PrintImportElmt (f, ie);
+
+        if (ie != last)
+            fprintf (f, ", ");
+    }
+
+}  /* PrintImportElmts */
+
+
+
+void
+PrintImportLists PARAMS ((f, impLists),
+    FILE *f _AND_
+    ImportModuleList *impLists)
+{
+   ImportModule *impMod;
+
+   if (impLists == NULL)
+   {
+       fprintf (f,"\n\n-- imports nothing\n\n");
+       return;
+   }
+
+   fprintf (f, "IMPORTS\n\n");
+   FOR_EACH_LIST_ELMT (impMod, impLists)
+   {
+       PrintImportElmts (f, impMod->importElmts);
+
+       fprintf (f, "\n    FROM %s ", impMod->modId->name);
+
+       PrintOid (f, impMod->modId->oid);
+
+       fprintf (f, "\n\n\n");
+   }
+   fprintf (f, ";\n\n\n");
+
+}  /* PrintImportLists */
+
+
+
+void
+PrintTypeDefs PARAMS ((f, typeDefs),
+    FILE *f _AND_
+    TypeDefList *typeDefs)
+{
+    TypeDef *td;
+
+    FOR_EACH_LIST_ELMT (td, typeDefs)
+    {
+        if (td->type->basicType->choiceId == BASICTYPE_MACRODEF)
+            PrintMacroDef (f, td);
+        else
+        {
+            fprintf (f,"-- %s notes: ", td->definedName);
+
+            if (td->recursive)
+                fprintf (f,"recursive, ");
+            else
+                fprintf (f,"not recursive, ");
+
+            if (td->exported)
+                fprintf (f,"exported,\n");
+            else
+                fprintf (f,"not exported,\n");
+
+            fprintf (f,"-- locally refd %d times, ", td->localRefCount);
+            fprintf (f,"import refd %d times\n", td->importRefCount);
+
+
+            fprintf (f, "%s ::= ", td->definedName);
+            PrintType (f, td, td->type);
+        }
+        fprintf (f, "\n\n\n");
+    }
+}  /* PrintTypeDefs */
+
+
+
+
+void
+PrintType PARAMS ((f, head, t),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t)
+{
+    Tag *tag;
+    Tag *lastTag;
+
+    if (t == NULL)
+        return;
+
+    lastTag = NULL;
+    FOR_EACH_LIST_ELMT (tag, t->tags)
+    {
+
+
+
+        if (! ((tag->tclass == UNIV) &&
+               (tag->code == LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId))))
+        {
+            PrintTag (f, tag);
+            fprintf (f, " ");
+        }
+        lastTag = tag;
+    }
+
+    /*
+     * check type has been implicitly tagged
+     */
+    if (t->implicit)
+        fprintf (f, "IMPLICIT ");
+
+    PrintBasicType (f, head, t, t->basicType);
+
+
+    /*
+     * sequences of and set of print subtypes a special way
+     * so ignore them here
+     */
+    if ((t->subtypes != NULL) &&
+        (t->basicType->choiceId != BASICTYPE_SETOF) &&
+        (t->basicType->choiceId != BASICTYPE_SEQUENCEOF))
+    {
+        fprintf (f," ");
+        PrintSubtype (f, head, t, t->subtypes);
+    }
+
+
+    if (t->defaultVal != NULL)
+    {
+        fprintf (f, " DEFAULT ");
+        if (t->defaultVal->fieldName != NULL)
+            fprintf (f, "%s ", t->defaultVal->fieldName);
+        PrintValue (f, NULL, t, t->defaultVal->value);
+    }
+
+    else if (t->optional)
+        fprintf (f, " OPTIONAL");
+
+
+#ifdef DEBUG
+    fprintf (f, "  -- lineNo = %d --", t->lineNo);
+#endif
+
+}  /* PrintType */
+
+
+void
+PrintBasicType PARAMS ((f, head, t, bt),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt)
+{
+    switch (bt->choiceId)
+    {
+
+        case BASICTYPE_SEQUENCE:
+            fprintf (f, "SEQUENCE\n");
+            INDENT (f, indentG);
+            fprintf (f,"{\n");
+            indentG += indentStepG;
+            INDENT (f, indentG);
+            PrintElmtTypes (f, head, t, bt->a.sequence);
+            indentG -= indentStepG;
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f, "}");
+            break;
+
+        case BASICTYPE_SET:
+            fprintf (f, "SET\n");
+            INDENT (f, indentG);
+            fprintf (f,"{\n");
+            indentG += indentStepG;
+            INDENT (f, indentG);
+            PrintElmtTypes (f, head, t, bt->a.set);
+            indentG -= indentStepG;
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f, "}");
+            break;
+
+        case BASICTYPE_CHOICE:
+            fprintf (f, "CHOICE\n");
+            INDENT (f, indentG);
+            fprintf (f,"{\n");
+            indentG += indentStepG;
+            INDENT (f, indentG);
+            PrintElmtTypes (f, head, t, bt->a.choice);
+            indentG -= indentStepG;
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f, "}");
+            break;
+
+
+
+        case BASICTYPE_SEQUENCEOF:
+            fprintf (f, "SEQUENCE ");
+            if (t->subtypes != NULL)
+            {
+                PrintSubtype (f, head, t, t->subtypes);
+                fprintf (f," ");
+            }
+            fprintf (f, "OF ");
+            PrintType (f, head, bt->a.sequenceOf);
+            break;
+
+        case BASICTYPE_SETOF:
+            fprintf (f, "SET ");
+            if (t->subtypes != NULL)
+            {
+                PrintSubtype (f, head, t, t->subtypes);
+                fprintf (f," ");
+            }
+            fprintf (f, "OF ");
+            PrintType (f, head, bt->a.setOf);
+            break;
+
+
+        case BASICTYPE_SELECTION:
+            fprintf (f, "%s < ", bt->a.selection->fieldName);
+            PrintType (f, head, bt->a.selection->typeRef);
+            break;
+
+
+
+
+        case BASICTYPE_COMPONENTSOF:
+            fprintf (f, "COMPONENTS OF ");
+            PrintType (f, NULL, bt->a.componentsOf);
+            break;
+
+
+
+        case BASICTYPE_ANYDEFINEDBY:
+            fprintf (f, "ANY DEFINED BY %s", bt->a.anyDefinedBy->fieldName);
+            break;
+
+
+        case BASICTYPE_LOCALTYPEREF:
+            fprintf (f, "%s", bt->a.localTypeRef->typeName);
+            break;
+
+        case BASICTYPE_IMPORTTYPEREF:
+            /* attempt to keep special scoping, ie modname.type forms */
+            if (bt->a.importTypeRef->moduleName != NULL)
+                fprintf (f,"%s.", bt->a.importTypeRef->moduleName);
+            fprintf (f, "%s", bt->a.importTypeRef->typeName);
+            break;
+
+
+        case BASICTYPE_UNKNOWN:
+            fprintf (f, "unknown type !?!");
+            break;
+
+        case BASICTYPE_BOOLEAN:
+            fprintf (f, "BOOLEAN");
+            break;
+
+
+        case BASICTYPE_INTEGER:
+            fprintf (f, "INTEGER");
+            if ((bt->a.integer != NULL) && !LIST_EMPTY (bt->a.integer))
+            {
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "{\n");
+                indentG += indentStepG;
+                PrintNamedElmts (f, head, t, bt->a.integer);
+                indentG -= indentStepG;
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "}");
+            }
+            break;
+
+
+        case BASICTYPE_BITSTRING:
+            fprintf (f, "BIT STRING");
+            if ((bt->a.bitString != NULL) && !LIST_EMPTY (bt->a.bitString))
+            {
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "{\n");
+                indentG += indentStepG;
+                PrintNamedElmts (f, head, t, bt->a.bitString);
+                indentG -= indentStepG;
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "}");
+            }
+            break;
+
+        case BASICTYPE_OCTETSTRING:
+            fprintf (f, "OCTET STRING");
+            break;
+
+        case BASICTYPE_NULL:
+            fprintf (f, "NULL");
+            break;
+
+        case BASICTYPE_OID:
+            fprintf (f, "OBJECT IDENTIFIER");
+            break;
+
+        case BASICTYPE_REAL:
+            fprintf (f, "REAL");
+            break;
+
+        case BASICTYPE_ENUMERATED:
+            fprintf (f, "ENUMERATED");
+            if ((bt->a.enumerated != NULL) && !LIST_EMPTY (bt->a.enumerated))
+            {
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "{\n");
+                indentG += indentStepG;
+                PrintNamedElmts (f, head, t, bt->a.enumerated);
+                indentG -= indentStepG;
+                fprintf (f, "\n");
+                INDENT (f, indentG);
+                fprintf (f, "}");
+            }
+            break;
+
+        case BASICTYPE_ANY:
+            fprintf (f, "ANY");
+            break;
+
+        case BASICTYPE_MACROTYPE:
+            switch (bt->a.macroType->choiceId)
+            {
+        case MACROTYPE_ROSOPERATION:
+        case MACROTYPE_ASNABSTRACTOPERATION:
+            PrintRosOperationMacroType (f, head, t, bt, bt->a.macroType->a.rosOperation);
+            break;
+
+        case MACROTYPE_ROSERROR:
+        case MACROTYPE_ASNABSTRACTERROR:
+            PrintRosErrorMacroType (f, head, t, bt, bt->a.macroType->a.rosError);
+            break;
+
+        case MACROTYPE_ROSBIND:
+        case MACROTYPE_ROSUNBIND:
+            PrintRosBindMacroType (f, head, t, bt, bt->a.macroType->a.rosBind);
+            break;
+
+        case MACROTYPE_ROSASE:
+            PrintRosAseMacroType (f, head, t, bt, bt->a.macroType->a.rosAse);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONS:
+            PrintMtsasExtensionsMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensions);
+            break;
+
+        case MACROTYPE_MTSASEXTENSION:
+            PrintMtsasExtensionMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtension);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONATTRIBUTE:
+            PrintMtsasExtensionAttributeMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensionAttribute);
+            break;
+
+        case MACROTYPE_MTSASTOKEN:
+            PrintMtsasTokenMacroType (f, head, t, bt, bt->a.macroType->a.mtsasToken);
+            break;
+
+        case MACROTYPE_MTSASTOKENDATA:
+            PrintMtsasTokenDataMacroType (f, head, t, bt, bt->a.macroType->a.mtsasTokenData);
+            break;
+
+        case MACROTYPE_MTSASSECURITYCATEGORY:
+            PrintMtsasSecurityCategoryMacroType (f, head, t, bt, bt->a.macroType->a.mtsasSecurityCategory);
+            break;
+
+        case MACROTYPE_ASNOBJECT:
+            PrintAsnObjectMacroType (f, head, t, bt, bt->a.macroType->a.asnObject);
+            break;
+
+        case MACROTYPE_ASNPORT:
+            PrintAsnPortMacroType (f, head, t, bt, bt->a.macroType->a.asnPort);
+            break;
+
+        case MACROTYPE_ASNABSTRACTBIND:
+        case MACROTYPE_ASNABSTRACTUNBIND:
+            PrintAsnAbstractBindMacroType (f, head, t, bt, bt->a.macroType->a.asnAbstractBind);
+            break;
+
+        case MACROTYPE_AFALGORITHM:
+            PrintAfAlgorithmMacroType (f, head, t, bt, bt->a.macroType->a.afAlgorithm);
+            break;
+
+        case MACROTYPE_AFENCRYPTED:
+            PrintAfEncryptedMacroType (f, head, t, bt, bt->a.macroType->a.afEncrypted);
+            break;
+
+        case MACROTYPE_AFSIGNED:
+            PrintAfSignedMacroType (f, head, t, bt, bt->a.macroType->a.afSigned);
+            break;
+
+        case MACROTYPE_AFSIGNATURE:
+            PrintAfSignatureMacroType (f, head, t, bt, bt->a.macroType->a.afSignature);
+            break;
+
+        case MACROTYPE_AFPROTECTED:
+            PrintAfProtectedMacroType (f, head, t, bt, bt->a.macroType->a.afProtected);
+            break;
+
+        case MACROTYPE_SNMPOBJECTTYPE:
+            PrintSnmpObjectTypeMacroType (f, head, t, bt, bt->a.macroType->a.snmpObjectType);
+            break;
+
+        default:
+            fprintf (f, "< unknown macro type id ?! >");
+
+    } /* end macro type switch */
+    break;
+
+        /*
+         * @MACRO@ add new macro printers above this point
+         */
+
+        case BASICTYPE_MACRODEF:
+            /*
+             * printing this should be handled in PrintTypeDefs
+             */
+            break;
+
+
+        default:
+            fprintf (f, "< unknown type id ?! >");
+
+    }
+}  /* PrintBasicType */
+
+
+
+void
+PrintElmtType PARAMS ((f, head, t, nt),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    NamedType *nt)
+{
+    if (nt->fieldName != NULL)
+        fprintf (f, "%s ", nt->fieldName);
+
+    PrintType (f, head, nt->type);
+
+}  /* PrintElmtType */
+
+void
+PrintElmtTypes PARAMS ((f, head, t, e),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    NamedTypeList *e)
+{
+    NamedType *nt;
+    NamedType *last;
+
+    if ((e == NULL) || LIST_EMPTY (e))
+        return;
+
+    last = (NamedType*)LAST_LIST_ELMT (e);
+    FOR_EACH_LIST_ELMT (nt, e)
+    {
+
+        PrintElmtType (f, head, t, nt);
+        if (nt != last)
+        {
+            fprintf (f, ",\n");
+            INDENT (f, indentG);
+        }
+    }
+}  /* PrintElmtTypes */
+
+
+
+
+void
+PrintValueDefs PARAMS ((f, vList),
+    FILE *f _AND_
+    ValueDefList *vList)
+{
+    ValueDef *v;
+    FOR_EACH_LIST_ELMT (v, vList)
+    {
+        PrintValueDef (f, v);
+    }
+}  /* PrintValueDefs */
+
+
+void
+PrintValueDef PARAMS ((f, v),
+    FILE *f _AND_
+    ValueDef *v)
+{
+    fprintf (f, "%s ", v->definedName);
+
+    if (v->value->type != NULL)
+        PrintType (f, NULL, v->value->type);
+    else
+        /* just go by valueType */
+        PrintTypeById (f, v->value->valueType);
+
+    fprintf (f, " ::= ");
+    indentG += indentStepG;
+    PrintValue (f, v, v->value->type, v->value);
+    fprintf (f, "\n\n");
+    indentG -= indentStepG;
+}  /* PrintValueDef */
+
+
+void
+PrintValue PARAMS ((f, head, valuesType, v),
+    FILE *f _AND_
+    ValueDef *head _AND_
+    Type *valuesType _AND_
+    Value *v)
+{
+    if (v == NULL)
+        return;
+
+    PrintBasicValue (f, head, valuesType, v, v->basicValue);
+
+}  /* PrintValue */
+
+
+void
+PrintBasicValue PARAMS ((f, head, valuesType, v, bv),
+    FILE *f _AND_
+    ValueDef *head _AND_
+    Type *valuesType _AND_
+    Value *v _AND_
+    BasicValue *bv)
+{
+    if (v == NULL)
+        return;
+
+
+    switch (bv->choiceId)
+    {
+        case BASICVALUE_UNKNOWN:
+            fprintf (f, "<unknown value>");
+            break;
+
+        case BASICVALUE_EMPTY:
+            fprintf (f,"{ }");
+            break;
+
+        case BASICVALUE_INTEGER:
+            fprintf (f, "%d", bv->a.integer);
+            break;
+
+        case BASICVALUE_SPECIALINTEGER:
+            if (bv->a.specialInteger == MAX_INT)
+                fprintf (f, "MAX");
+            else
+                fprintf (f, "MIN");
+
+            break;
+
+        case BASICVALUE_BOOLEAN:
+            if (bv->a.boolean)
+                fprintf (f,"TRUE");
+            else
+                fprintf (f,"FALSE");
+            break;
+
+        case BASICVALUE_REAL:
+            fprintf (f, "%f", bv->a.real);
+            break;
+
+        case BASICVALUE_SPECIALREAL:
+            if (bv->a.specialReal == PLUS_INFINITY_REAL)
+                fprintf (f, "PLUS INFINITY");
+            else
+                fprintf (f, "MINUS INFINITY");
+
+            break;
+
+        case BASICVALUE_ASCIITEXT:
+            fprintf (f, "\"%s\"", bv->a.asciiText->octs);
+            break;
+
+        case BASICVALUE_ASCIIHEX:
+            fprintf (f, "\"%s\"", bv->a.asciiHex->octs);
+            break;
+
+        case BASICVALUE_ASCIIBITSTRING:
+            fprintf (f, "\"%s\"", bv->a.asciiBitString->octs);
+            break;
+
+        case BASICVALUE_OID:
+            PrintEncodedOid (f, bv->a.oid);
+            break;
+
+        case BASICVALUE_LINKEDOID:
+            PrintOid (f, bv->a.linkedOid);
+            break;
+
+        case BASICVALUE_BERVALUE:
+            fprintf (f,"<PrintBerValue not coded yet");
+            break;
+
+        case BASICVALUE_PERVALUE:
+            fprintf (f,"<PrintPerValue not coded yet");
+            break;
+
+        case BASICVALUE_NAMEDVALUE:
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f,"{\n");
+            indentG += indentStepG;
+            PrintElmtValue (f, head, v, bv->a.namedValue);
+            indentG -= indentStepG;
+            fprintf (f,"\n");
+            INDENT (f, indentG);
+            fprintf (f,"}");
+            break;
+
+        case BASICVALUE_NULL:
+            fprintf (f,"NULL");
+            break;
+
+        case BASICVALUE_LOCALVALUEREF:
+            fprintf (f, "%s", bv->a.localValueRef->valueName);
+            break;
+
+        case BASICVALUE_IMPORTVALUEREF:
+            fprintf (f, "%s", bv->a.importValueRef->valueName);
+            break;
+
+        case BASICVALUE_VALUENOTATION:
+            fprintf (f, "-- snacc warning: can't parse this value yet --");
+            fprintf (f, "%s", bv->a.valueNotation->octs);
+            break;
+
+
+        default:
+           fprintf (stderr,"PrintBasicValue: ERROR - unknown value type\n");
+    }
+
+}  /* PrintBasicValue */
+
+
+void
+PrintElmtValue PARAMS ((f, head, v, nv),
+    FILE *f _AND_
+    ValueDef *head _AND_
+    Value *v _AND_
+    NamedValue *nv)
+{
+    if (nv->fieldName != NULL)
+        fprintf (f, "%s ", nv->fieldName);
+
+    PrintValue (f, NULL, NULL,  nv->value);
+}  /* PrintElmtValue */
+
+
+void
+PrintElmtValues PARAMS ((f, head, v, e),
+    FILE *f _AND_
+    ValueDef *head _AND_
+    Value *v _AND_
+    NamedValueList *e)
+{
+    NamedValue *nv;
+    NamedValue *last;
+
+    if ((e == NULL) || LIST_EMPTY (e))
+        return;
+
+    last = (NamedValue*)LAST_LIST_ELMT (e);
+    FOR_EACH_LIST_ELMT (nv, e)
+    {
+        PrintElmtValue (f, head, v, nv);
+        if (nv != last)
+        {
+            fprintf (f, ",\n");
+            INDENT (f, indentG);
+        }
+    }
+}  /* PrintElmtValues */
+
+
+void
+PrintTypeById PARAMS ((f, typeId),
+    FILE *f _AND_
+    int typeId)
+{
+    switch (typeId)
+    {
+        case BASICTYPE_UNKNOWN:
+            fprintf (f, "UNKNOWN");
+            break;
+
+        case BASICTYPE_BOOLEAN:
+            fprintf (f, "BOOLEAN");
+            break;
+
+        case BASICTYPE_INTEGER:
+            fprintf (f, "INTEGER");
+            break;
+
+        case BASICTYPE_BITSTRING:
+            fprintf (f, "BIT STRING");
+            break;
+
+        case BASICTYPE_OCTETSTRING:
+            fprintf (f, "OCTET STRING");
+            break;
+
+
+        case BASICTYPE_NULL:
+            fprintf (f, "NULL");
+            break;
+
+        case BASICTYPE_SEQUENCE:
+            fprintf (f, "SEQUENCE");
+            break;
+
+        case BASICTYPE_SEQUENCEOF:
+            fprintf (f, "SEQUENCE OF");
+            break;
+
+        case BASICTYPE_SET:
+            fprintf (f, "SET");
+            break;
+
+        case BASICTYPE_SETOF:
+            fprintf (f, "SET OF");
+            break;
+
+        case BASICTYPE_CHOICE:
+            fprintf (f, "CHOICE");
+            break;
+
+        case BASICTYPE_SELECTION:
+            fprintf (f, "SELECTION");
+            break;
+
+        case BASICTYPE_ANY:
+            fprintf (f, "ANY");
+            break;
+
+        case BASICTYPE_ANYDEFINEDBY:
+            fprintf (f, "ANY DEFINED BY");
+            break;
+
+        case BASICTYPE_OID:
+            fprintf (f, "OBJECT IDENTIFIER");
+            break;
+
+        case BASICTYPE_ENUMERATED:
+            fprintf (f, "ENUMERATED");
+            break;
+
+        case BASICTYPE_REAL:
+            fprintf (f, "REAL");
+            break;
+
+        case BASICTYPE_COMPONENTSOF:
+            fprintf (f, "COMPONENTS OF");
+            break;
+
+        default:
+            fprintf (f, "ERROR - %d is an unknown type id\n", typeId);
+    }
+}  /* PrintTypeById */
+
+
+void
+PrintTag PARAMS ((f, tag),
+    FILE *f _AND_
+    Tag *tag)
+{
+    char *name=NULL;
+
+    if (tag->tclass == UNIV)
+    {
+        switch (tag->code)
+        {
+           case BOOLEAN_TAG_CODE: name = "BOOLEAN";
+                        break;
+           case INTEGER_TAG_CODE: name = "INTEGER";
+                        break;
+           case BITSTRING_TAG_CODE: name = "BITSTRING";
+                        break;
+           case OCTETSTRING_TAG_CODE: name = "OCTETSTRING";
+                        break;
+           case NULLTYPE_TAG_CODE: name = "NULL TYPE";
+                        break;
+           case OID_TAG_CODE: name = "OBJECT ID";
+                        break;
+           case OD_TAG_CODE: name = "OBEJECT DESCRIPTOR";
+                        break;
+           case EXTERNAL_TAG_CODE: name = "EXTERNAL";
+                        break;
+           case REAL_TAG_CODE: name = "REAL";
+                        break;
+           case ENUM_TAG_CODE: name = "ENUMERATED";
+                        break;
+           case SEQ_TAG_CODE: name = "SEQUENCE";
+                        break;
+           case SET_TAG_CODE: name = "SET";
+                        break;
+           case NUMERICSTRING_TAG_CODE: name = "NUMERIC STRING";
+                        break;
+           case PRINTABLESTRING_TAG_CODE: name = "PRINTABLE STRING";
+                        break;
+           case TELETEXSTRING_TAG_CODE: name = "TELETEX STRING";
+                        break;
+           case VIDEOTEXSTRING_TAG_CODE: name = "VIDEOTEX STRING";
+                        break;
+           case IA5STRING_TAG_CODE: name = "IA5 STRING";
+                        break;
+           case UTCTIME_TAG_CODE:  name = "UTC TIME";
+                        break;
+           case GENERALIZEDTIME_TAG_CODE: name = "GENERALIZED TIME";
+                        break;
+           case GRAPHICSTRING_TAG_CODE: name = "GRAPHIC STRING";
+                        break;
+           case VISIBLESTRING_TAG_CODE: name = "VISIBLE STRING";
+                        break;
+           case GENERALSTRING_TAG_CODE: name = "GENERAL STRING";
+                        break;
+
+           default: name = "UNKNOWN UNIVERSAL TYPE";
+        }
+        fprintf (f, "[UNIVERSAL %d]", tag->code);
+    }
+    else  if (tag->tclass  == APPL)
+    {
+        fprintf (f, "[APPLICATION %d]", tag->code);
+    }
+    else  if (tag->tclass  == PRIV)
+    {
+        fprintf (f, "[PRIVATE %d]", tag->code);
+    }
+    else  if (tag->tclass  == CNTX)
+    {
+        fprintf (f, "[%d]", tag->code);
+    }
+
+    if (tag->explicit)
+        fprintf (f, " EXPLICIT");
+
+}  /* PrintTag */
+
+
+void
+PrintSubtype PARAMS ((f, head, t, s),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    Subtype *s)
+{
+    Subtype *tmpS;
+    Subtype *last;
+
+    if (s == NULL)
+        return;
+
+/*     fprintf (f, "("); */
+
+    switch (s->choiceId)
+    {
+        case SUBTYPE_SINGLE:
+            PrintSubtypeValue (f, head, t, s->a.single);
+        break;
+
+        case SUBTYPE_AND:
+            FOR_EACH_LIST_ELMT (tmpS, s->a.and)
+            {
+                fprintf (f, "(");
+                PrintSubtype (f, head, t, tmpS);
+                fprintf (f, ")");
+            }
+        break;
+
+
+        case SUBTYPE_OR:
+            if ((s->a.or != NULL) && !LIST_EMPTY (s->a.or))
+                last = (Subtype*)LAST_LIST_ELMT (s->a.or);
+            FOR_EACH_LIST_ELMT (tmpS, s->a.or)
+            {
+                fprintf (f, "(");
+                PrintSubtype (f, head, t, tmpS);
+                fprintf (f, ")");
+                if (tmpS != last)
+                    fprintf (f, " | ");
+            }
+        break;
+
+        case SUBTYPE_NOT:
+            fprintf (f, "NOT (");
+        PrintSubtype (f, head, t, s->a.not);
+        fprintf (f, ")");
+        break;
+
+        default:
+        fprintf (stderr, "PrintSubtype: ERROR - unknown Subtypes choiceId\n");
+        break;
+    }
+
+/*     fprintf (f, ")"); */
+
+
+}  /* PrintSubtype */
+
+
+
+void
+PrintSubtypeValue PARAMS ((f, head, t, s),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    SubtypeValue *s)
+{
+    if (s == NULL)
+        return;
+
+    switch (s->choiceId)
+    {
+        case SUBTYPEVALUE_SINGLEVALUE:
+            PrintValue (f, NULL, NULL, s->a.singleValue);
+            break;
+
+        case SUBTYPEVALUE_CONTAINED:
+            fprintf (f, "<PrintContainedSubtype not coded yet\n");
+            break;
+
+        case SUBTYPEVALUE_VALUERANGE:
+            PrintValue (f, NULL, NULL, s->a.valueRange->lowerEndValue);
+            if (!s->a.valueRange->lowerEndInclusive)
+                fprintf (f, " >");
+            fprintf (f,"..");
+            if (!s->a.valueRange->upperEndInclusive)
+                fprintf (f, "< ");
+            PrintValue (f, NULL, NULL, s->a.valueRange->upperEndValue);
+            break;
+
+
+        case SUBTYPEVALUE_PERMITTEDALPHABET:
+            fprintf (f,"FROM ");
+            PrintSubtype (f, head, t, s->a.permittedAlphabet);
+            break;
+
+        case SUBTYPEVALUE_SIZECONSTRAINT:
+            fprintf (f,"SIZE ");
+            PrintSubtype (f, head, t, s->a.sizeConstraint);
+            break;
+
+        case SUBTYPEVALUE_INNERSUBTYPE:
+            PrintInnerSubtype (f, head, t, s->a.innerSubtype);
+            break;
+
+        default:
+           fprintf (stderr, "PrintSubtype: ERROR - unknown Subtype choiceId\n");
+            break;
+    }
+}   /* PrintSubtype */
+
+
+void
+PrintInnerSubtype PARAMS ((f, head, t, i),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    InnerSubtype *i)
+{
+    Constraint *constraint;
+    if (i->constraintType == SINGLE_CT)
+    {
+        fprintf (f,"WITH COMPONENT ");
+        constraint = *(Constraint**)AsnListFirst (i->constraints);
+        PrintSubtype (f, head, t, constraint->valueConstraints);
+    }
+    else
+    {
+        fprintf (f, "WITH COMPONENTS\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+        if (i->constraintType == PARTIAL_CT)
+        {
+            INDENT (f, indentG);
+            fprintf (f, "...,\n");
+        }
+        PrintMultipleTypeConstraints (f, head, t, i->constraints);
+        indentG -= indentStepG;
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        fprintf (f, "}");
+
+    }
+}  /* PrintInnerSubtype */
+
+
+
+void
+PrintMultipleTypeConstraints PARAMS ((f, head, t, cList),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    ConstraintList *cList)
+{
+    Constraint *c;
+    Constraint *last;
+
+    if ((cList == NULL) || LIST_EMPTY (cList))
+        return;
+
+    last  = (Constraint*)LAST_LIST_ELMT (cList);
+    FOR_EACH_LIST_ELMT (c, cList)
+    {
+        if (c->fieldRef != NULL)
+        {
+            INDENT (f, indentG);
+            fprintf (f, "%s ", c->fieldRef);
+        }
+
+
+        PrintSubtype (f, head, t, c->valueConstraints);
+
+        if (c->presenceConstraint == ABSENT_CT)
+            fprintf (f, " ABSENT");
+        if (c->presenceConstraint == PRESENT_CT)
+            fprintf (f, " PRESENT");
+        if (c->presenceConstraint == OPTIONAL_CT)
+            fprintf (f, " OPTIONAL");
+
+        if (c != last)
+            fprintf (f, ",\n");
+
+    }
+} /* PrintMultipleTypeConstraints */
+
+
+
+void
+PrintNamedElmts PARAMS ((f, head, t, n),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    ValueDefList *n)
+{
+    ValueDef *vd;
+    ValueDef *last;
+
+    if ((n == NULL) || LIST_EMPTY (n))
+        return;
+
+    last = (ValueDef*)LAST_LIST_ELMT (n);
+    FOR_EACH_LIST_ELMT (vd, n)
+    {
+        INDENT (f, indentG);
+        fprintf (f, "%s (", vd->definedName);
+        PrintValue (f, NULL, NULL, vd->value);
+        fprintf (f,")");
+        if (vd != last)
+            fprintf (f,",\n");
+    }
+}  /* PrintNamedElmts */
+
+
+
+
+void
+PrintRosOperationMacroType PARAMS ((f, head, t, bt, op),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosOperationMacroType *op)
+{
+    TypeOrValue *tOrV;
+    TypeOrValue *last;
+
+    if (bt->a.macroType->choiceId == MACROTYPE_ROSOPERATION)
+        fprintf (f, "OPERATION");
+    else
+        fprintf (f, "ABSTRACT-OPERATION");
+
+    indentG += indentStepG;
+    if (op->arguments != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "ARGUMENT\n");
+        indentG += indentStepG;
+
+        INDENT (f, indentG);
+
+        if (op->arguments->fieldName != NULL)
+            fprintf (f, "%s ", op->arguments->fieldName);
+
+        PrintType (f, head, op->arguments->type);
+        indentG -= indentStepG;
+    }
+
+    if (op->result != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "RESULT\n");
+        indentG += indentStepG;
+
+        INDENT (f, indentG);
+
+        if (op->arguments->fieldName != NULL)
+            fprintf (f, "%s ", op->arguments->fieldName);
+
+        PrintType (f, head, op->result->type);
+        indentG -= indentStepG;
+    }
+
+    if ((op->errors == NULL) || (!LIST_EMPTY (op->errors)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "ERRORS\n");
+        INDENT (f, indentG);
+        fprintf (f,"{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (op->errors);
+        FOR_EACH_LIST_ELMT (tOrV, op->errors)
+        {
+            INDENT (f, indentG);
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV  != last)
+                fprintf (f, ",\n");
+
+        }
+        indentG -= indentStepG;
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    if ((op->linkedOps != NULL) && (!LIST_EMPTY (op->linkedOps)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "LINKED\n");
+        INDENT (f, indentG);
+        fprintf (f,"{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (op->linkedOps);
+        FOR_EACH_LIST_ELMT (tOrV, op->linkedOps)
+        {
+            INDENT (f, indentG);
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV != last)
+                fprintf (f, ",\n");
+        }
+        indentG -= indentStepG;
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, " }");
+    }
+
+    indentG -= indentStepG;
+
+} /* PrintRosOperationMacroType */
+
+
+
+void
+PrintRosErrorMacroType PARAMS ((f, head, t, bt, err),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosErrorMacroType *err)
+{
+    if (bt->a.macroType->choiceId == MACROTYPE_ROSERROR)
+        fprintf (f,"ERROR\n");
+    else
+        fprintf (f,"ABSTRACT-ERROR\n");
+
+    indentG += indentStepG;
+
+    if (err->parameter != NULL)
+    {
+        INDENT (f, indentG);
+        fprintf (f,"PARAMETER ");
+        indentG += indentStepG;
+        PrintElmtType (f, head, t, err->parameter);
+        indentG -= indentStepG;
+    }
+    indentG -= indentStepG;
+
+}  /* PrintRosErrorMacroType */
+
+
+void
+PrintRosBindMacroType PARAMS ((f, head, t, bt, bind),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosBindMacroType *bind)
+{
+    if (bt->a.macroType->choiceId == MACROTYPE_ROSBIND)
+        fprintf (f,"BIND");
+    else
+        fprintf (f,"UNBIND");
+
+    indentG += indentStepG;
+
+    if (bind->argument != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        fprintf (f,"ARGUMENT\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintElmtType (f, head, t, bind->argument);
+        indentG -= indentStepG;
+    }
+
+    if (bind->result != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        fprintf (f,"RESULT\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintElmtType (f, head, t, bind->result);
+        indentG -= indentStepG;
+    }
+
+    if (bind->error != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        if (bt->a.macroType->choiceId == MACROTYPE_ROSBIND)
+            fprintf (f,"BIND-ERROR\n");
+        else
+            fprintf (f,"UNBIND-ERROR\n");
+
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintElmtType (f, head, t, bind->error);
+        indentG -= indentStepG;
+    }
+
+    indentG -= indentStepG;
+
+}  /* PrintRosBindMacroType */
+
+
+void
+PrintRosAseMacroType PARAMS ((f, head, t, bt, ase),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAseMacroType *ase)
+{
+    Value *v;
+    Value *last;
+
+    fprintf (f, "APPLICATION-SERVICE-ELEMENT");
+    indentG += indentStepG;
+
+    if ((ase->operations != NULL)&& (!LIST_EMPTY (ase->operations)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"OPERATIONS\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+
+        indentG += indentStepG;
+
+        last = (Value*)LAST_LIST_ELMT (ase->operations);
+        FOR_EACH_LIST_ELMT (v, ase->operations)
+        {
+            INDENT (f, indentG);
+            PrintValue (f, NULL, t, v);
+            if (v != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    else  /* either suuplier invokes or consumer invokes will be valid */
+    {
+        if ((ase->consumerInvokes != NULL) && (!LIST_EMPTY (ase->consumerInvokes)))
+        {
+            fprintf (f,"\n");
+            INDENT (f, indentG);
+            fprintf (f,"CONSUMER INVOKES\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*) LAST_LIST_ELMT (ase->consumerInvokes);
+            FOR_EACH_LIST_ELMT (v, ase->consumerInvokes)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+        if ((ase->operations != NULL) && (!LIST_EMPTY (ase->operations)))
+        {
+            fprintf (f,"\n");
+            INDENT (f, indentG);
+            fprintf (f,"SUPPLIER INVOKES\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*)LAST_LIST_ELMT (ase->supplierInvokes);
+            FOR_EACH_LIST_ELMT (v, ase->supplierInvokes)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+    }
+    indentG -= indentStepG;
+
+}  /* PrintRosAseMacrType */
+
+
+
+
+void
+PrintRosAcMacroType PARAMS ((f, head, t, bt, ac),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    RosAcMacroType *ac)
+{
+    Value *v;
+    Value *last;
+    OID *oid;
+    OID *lastOid;
+
+    fprintf (f, "APPLICATION-CONTEXT");
+    indentG += indentStepG;
+
+    /*
+     * print non Ros Elements
+     */
+    fprintf (f,"\n");
+    INDENT (f, indentG);
+    fprintf (f,"APPLICATION-SERVICE-ELEMENTS\n");
+    INDENT (f, indentG);
+    fprintf (f, "{\n");
+
+    indentG += indentStepG;
+    if ((ac->nonRoElements == NULL) && (!LIST_EMPTY (ac->nonRoElements)))
+        last = (Value*)LAST_LIST_ELMT (ac->nonRoElements);
+    FOR_EACH_LIST_ELMT (v, ac->nonRoElements)
+    {
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, v);
+        if (v != last)
+            fprintf (f, ",\n");
+    }
+    fprintf (f, "}\n");
+
+    /*
+     * Print Bind Type
+     */
+    INDENT (f, indentG);
+    fprintf (f,"BIND\n");
+    INDENT (f, indentG);
+    PrintType (f, head, ac->bindMacroType);
+    fprintf (f, "\n");
+
+    /*
+     * Print unbind Type
+     */
+    INDENT (f, indentG);
+    fprintf (f,"UNBIND\n");
+    INDENT (f, indentG);
+    PrintType (f, head, ac->unbindMacroType);
+
+
+    if (ac->remoteOperations != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        fprintf (f,"REMOTE OPERATIONS { ");
+        PrintValue (f, NULL, t, ac->remoteOperations);
+        fprintf (f, " }");
+
+        if ((ac->operationsOf != NULL) && (!LIST_EMPTY (ac->operationsOf)))
+        {
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f,"OPERATIONS OF\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*)LAST_LIST_ELMT (ac->operationsOf);
+            FOR_EACH_LIST_ELMT (v,  ac->operationsOf)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+
+        if ((ac->initiatorConsumerOf != NULL) && (!LIST_EMPTY (ac->initiatorConsumerOf)))
+        {
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f,"INITIATOR CONSUMER OF\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*)LAST_LIST_ELMT (ac->initiatorConsumerOf);
+            FOR_EACH_LIST_ELMT (v, ac->initiatorConsumerOf)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+
+        if ((ac->responderConsumerOf != NULL) && (!LIST_EMPTY (ac->responderConsumerOf)))
+        {
+            fprintf (f, "\n");
+            INDENT (f, indentG);
+            fprintf (f,"RESPONDER CONSUMER OF\n");
+            INDENT (f, indentG);
+            fprintf (f, "{\n");
+
+            indentG += indentStepG;
+            last = (Value*)LAST_LIST_ELMT (ac->responderConsumerOf);
+            FOR_EACH_LIST_ELMT (v, ac->responderConsumerOf)
+            {
+                INDENT (f, indentG);
+                PrintValue (f, NULL, t, v);
+                if (v != last)
+                    fprintf (f, ",\n");
+            }
+            fprintf (f, "\n");
+            indentG -= indentStepG;
+            INDENT (f, indentG);
+            fprintf (f, "}");
+        }
+    }
+
+    fprintf (f,"\n");
+    INDENT (f, indentG);
+    fprintf (f,"ABSTRACT SYNTAXES\n");
+    INDENT (f, indentG);
+    fprintf (f, "{\n");
+
+    if ((ac->abstractSyntaxes != NULL) && (!LIST_EMPTY (ac->abstractSyntaxes)))
+    lastOid = (OID*)LAST_LIST_ELMT (ac->abstractSyntaxes);
+    FOR_EACH_LIST_ELMT (oid, ac->abstractSyntaxes)
+    {
+        INDENT (f, indentG);
+        PrintOid (f, oid);
+        if (oid != lastOid)
+            fprintf (f, ",\n");
+    }
+    fprintf (f, "\n");
+    indentG -= indentStepG;
+    INDENT (f, indentG);
+    fprintf (f, "}");
+
+    indentG -= indentStepG;
+
+}  /* PrintRosAcMacroType */
+
+
+void
+PrintMtsasExtensionsMacroType PARAMS ((f, head, t, bt, exts),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionsMacroType *exts)
+{
+    Value *v;
+    Value *last;
+
+    fprintf (f, "EXTENSIONS CHOSEN FROM");
+
+    INDENT (f, indentG);
+    fprintf (f, "{\n");
+
+    indentG += indentStepG;
+    if ((exts->extensions == NULL) && (!LIST_EMPTY (exts->extensions)))
+        last = (Value*)LAST_LIST_ELMT (exts->extensions);
+    FOR_EACH_LIST_ELMT (v, exts->extensions)
+    {
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, v);
+        if (v != last)
+            fprintf (f, ",\n");
+    }
+    fprintf (f, "\n");
+    indentG -= indentStepG;
+    INDENT (f, indentG);
+    fprintf (f, "}");
+
+}  /* PrintMtsasExtensionsMacroType */
+
+
+void
+PrintMtsasExtensionMacroType PARAMS ((f, head, t, bt, ext),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionMacroType *ext)
+{
+
+    fprintf (f, "EXTENSION");
+
+    indentG += indentStepG;
+    if (ext->elmtType != NULL)
+    {
+        fprintf (f, "\n");
+        INDENT (f, indentG);
+        PrintElmtType (f, head, t, ext->elmtType);
+
+        if (ext->defaultValue != NULL)
+        {
+            fprintf (f, " DEFAULT ");
+            PrintValue (f, NULL, t, ext->defaultValue);
+        }
+    }
+
+    if ((ext->criticalForSubmission != NULL) ||
+         (ext->criticalForTransfer != NULL) ||
+         (ext->criticalForDelivery != NULL))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "CRITICAL FOR ");
+
+        if (ext->criticalForSubmission != NULL)
+        {
+            fprintf (f, "SUBMISSION");
+            if ((ext->criticalForTransfer != NULL) ||
+                (ext->criticalForDelivery != NULL))
+                fprintf (f,", ");
+        }
+
+        if (ext->criticalForTransfer != NULL)
+        {
+            fprintf (f, "TRANSFER, ");
+            if  (ext->criticalForDelivery != NULL)
+                fprintf (f,", ");
+        }
+
+        if (ext->criticalForDelivery != NULL)
+            fprintf (f, "DELIVERY");
+
+    }
+
+    indentG -= indentStepG;
+
+}  /* PrintMtsasExtensionMacroType */
+
+
+
+
+void
+PrintMtsasExtensionAttributeMacroType PARAMS ((f, head, t, bt, ext),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasExtensionAttributeMacroType *ext)
+{
+
+    fprintf (f, "EXTENSION-ATTRIBUTE");
+    if (ext->type != NULL)
+    {
+        fprintf (f, "\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+
+        PrintType (f, head, ext->type);
+        indentG -= indentStepG;
+    }
+
+}  /* PrintMtsasExtensionAttributeMacroType */
+
+
+
+void
+PrintMtsasTokenMacroType PARAMS ((f, head, t, bt, tok),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenMacroType *tok)
+{
+
+    fprintf (f, "TOKEN");
+    if (tok->type != NULL)
+    {
+        fprintf (f, "\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintType (f, head, tok->type);
+        indentG -= indentStepG;
+    }
+
+}  /* PrintMtsasTokenMacro */
+
+
+void
+PrintMtsasTokenDataMacroType PARAMS ((f, head, t, bt, tok),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasTokenDataMacroType *tok)
+{
+
+    fprintf (f, "TOKEN-DATA");
+    if (tok->type != NULL)
+    {
+        fprintf (f, "\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+
+        PrintType (f, head, tok->type);
+        indentG -= indentStepG;
+    }
+
+}  /* PrintMtsasTokenDataMacro */
+
+
+void
+PrintMtsasSecurityCategoryMacroType PARAMS ((f, head, t, bt, sec),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    MtsasSecurityCategoryMacroType *sec)
+{
+
+    fprintf (f, "SECURITY-CATEGORY");
+    if (sec->type != NULL)
+    {
+        fprintf (f, "\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+
+        PrintType (f, head, sec->type);
+        indentG -= indentStepG;
+    }
+
+}  /* PrintMtsasSecurityCategoryMacroType */
+
+
+
+void
+PrintAsnObjectMacroType PARAMS ((f, head, t, bt, obj),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnObjectMacroType *obj)
+{
+    AsnPort *ap;
+    AsnPort *last;
+
+    fprintf (f, "OBJECT");
+
+    indentG += indentStepG;
+
+    if ((obj->ports != NULL) && !LIST_EMPTY (obj->ports))
+    {
+
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "PORTS\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (AsnPort*)LAST_LIST_ELMT (obj->ports);
+        FOR_EACH_LIST_ELMT (ap, obj->ports)
+        {
+            INDENT (f, indentG);
+            PrintValue (f, NULL, t, ap->portValue);
+
+            if (ap->portType == CONSUMER_PORT)
+                fprintf (f, " [C]");
+            else if (ap->portType == SUPPLIER_PORT)
+                fprintf (f, " [S]");
+
+            if (ap != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+    indentG -= indentStepG;
+
+}  /* PrintAsnObjectMacroType */
+
+
+
+void
+PrintAsnPortMacroType PARAMS ((f, head, t, bt, p),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnPortMacroType *p)
+{
+    TypeOrValue *tOrV;
+    TypeOrValue *last;
+
+    fprintf (f, "PORT");
+    indentG += indentStepG;
+    if ((p->abstractOps != NULL) && (!LIST_EMPTY (p->abstractOps)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "ABSTRACT OPERATIONS\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (p->abstractOps);
+        FOR_EACH_LIST_ELMT (tOrV, p->abstractOps)
+        {
+            INDENT (f, indentG);
+
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    if ((p->consumerInvokes != NULL) && (!LIST_EMPTY (p->consumerInvokes)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "CONSUMER INVOKES\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (p->consumerInvokes);
+        FOR_EACH_LIST_ELMT (tOrV, p->consumerInvokes)
+        {
+            INDENT (f, indentG);
+
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    if ((p->supplierInvokes != NULL) && (!LIST_EMPTY (p->supplierInvokes)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f, "SUPPLIER INVOKES\n");
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (TypeOrValue*)LAST_LIST_ELMT (p->supplierInvokes);
+        FOR_EACH_LIST_ELMT (tOrV, p->supplierInvokes)
+
+        {
+            INDENT (f, indentG);
+
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV != last)
+                fprintf (f, ",\n");
+        }
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    indentG -= indentStepG;
+
+}  /* PrintAsnPortMacroType */
+
+
+
+
+void
+PrintAsnAbstractBindMacroType PARAMS ((f, head, t, bt, bind),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    AsnAbstractBindMacroType *bind)
+{
+    AsnPort *ap;
+    AsnPort *last;
+
+    if (bt->a.macroType->choiceId == MACROTYPE_ASNABSTRACTBIND)
+        fprintf (f, "ABSTRACT-BIND");
+    else
+        fprintf (f, "ABSTRACT-UNBIND");
+
+    indentG += indentStepG;
+
+    if ((bind->ports != NULL) && (!LIST_EMPTY (bind->ports)))
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        if (bt->a.macroType->choiceId == MACROTYPE_ASNABSTRACTBIND)
+            fprintf (f, "TO\n");
+        else
+            fprintf (f, "FROM\n");
+
+        INDENT (f, indentG);
+        fprintf (f, "{\n");
+        indentG += indentStepG;
+
+        last = (AsnPort*)LAST_LIST_ELMT (bind->ports);
+        FOR_EACH_LIST_ELMT (ap, bind->ports)
+        {
+            INDENT (f, indentG);
+            PrintValue (f, NULL, t, ap->portValue);
+
+            if (ap->portType == CONSUMER_PORT)
+                fprintf (f, " [C]");
+            else if (ap->portType == SUPPLIER_PORT)
+                fprintf (f, " [S]");
+
+            if (ap != last)
+                fprintf (f, ",\n");
+        }
+
+        fprintf (f, "\n");
+        indentG -= indentStepG;
+        INDENT (f, indentG);
+        fprintf (f, "}");
+    }
+
+    if (bind->type != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        PrintType (f, head, bind->type);
+    }
+
+    indentG -= indentStepG;
+
+}  /* PrintAsnAbstractBindMacroType */
+
+
+
+void
+PrintAfAlgorithmMacroType PARAMS ((f, head, t, bt, alg),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *alg)
+{
+    indentG += indentStepG;
+    fprintf (f, "ALGORITHM PARAMETER ");
+    PrintType (f, head, alg);
+    indentG -= indentStepG;
+}  /* PrintAfAlgorithmMacroType */
+
+
+void
+PrintAfEncryptedMacroType PARAMS ((f, head, t, bt, encrypt),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *encrypt)
+{
+    indentG += indentStepG;
+    fprintf (f, "ENCRYPTED ");
+    PrintType (f, head, encrypt);
+    indentG -= indentStepG;
+}  /* PrintAfEncryptedMacroType */
+
+
+void
+PrintAfSignedMacroType PARAMS ((f, head, t, bt, sign),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *sign)
+{
+    indentG += indentStepG;
+    fprintf (f, "SIGNED ");
+    PrintType (f, head, sign);
+    indentG -= indentStepG;
+}  /* PrintAfSignedMacroType */
+
+
+void
+PrintAfSignatureMacroType PARAMS ((f, head, t, bt, sig),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *sig)
+{
+    indentG += indentStepG;
+    fprintf (f, "SIGNATURE ");
+    PrintType (f, head, sig);
+    indentG -= indentStepG;
+}  /* PrintAfSignatureMacroType */
+
+
+void
+PrintAfProtectedMacroType PARAMS ((f, head, t, bt, p),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    Type *p)
+{
+    indentG += indentStepG;
+    fprintf (f, "PROTECTED ");
+    PrintType (f, head, p);
+    indentG -= indentStepG;
+}  /* PrintAfMacroType */
+
+
+void
+PrintSnmpObjectTypeMacroType PARAMS ((f, head, t, bt, ot),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt _AND_
+    SnmpObjectTypeMacroType *ot)
+{
+    TypeOrValue *tOrV;
+    TypeOrValue *last;
+
+    fprintf (f, "OBJECT-TYPE\n");
+    indentG += indentStepG;
+    INDENT (f,indentG);
+    fprintf (f,"SYNTAX ");
+    indentG += indentStepG;
+    PrintType (f, head, ot->syntax);
+    indentG -= indentStepG;
+
+    fprintf (f,"\n");
+    INDENT (f,indentG);
+    fprintf (f,"ACCESS ");
+    switch (ot->access)
+    {
+        case SNMP_READ_ONLY:
+            fprintf (f,"read-only");
+            break;
+
+        case SNMP_READ_WRITE:
+            fprintf (f,"read-write");
+            break;
+
+        case SNMP_WRITE_ONLY:
+            fprintf (f,"write-only");
+            break;
+
+        case SNMP_NOT_ACCESSIBLE:
+            fprintf (f,"not-accessible");
+            break;
+
+        default:
+            fprintf (f," < ?? unknown access type ?? >");
+    }
+
+    fprintf (f,"\n");
+    INDENT (f, indentG);
+    fprintf (f,"STATUS ");
+    switch (ot->status)
+    {
+        case SNMP_MANDATORY:
+            fprintf (f,"mandatory");
+            break;
+
+        case SNMP_OPTIONAL:
+            fprintf (f,"optional");
+            break;
+
+        case SNMP_OBSOLETE:
+            fprintf (f,"obsolete");
+            break;
+
+        case SNMP_DEPRECATED:
+            fprintf (f,"deprecated");
+            break;
+
+        default:
+            fprintf (f," < ?? unknown status type ?? >");
+    }
+
+    if (ot->description != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"DESCRIPTION\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, ot->description);
+        indentG -= indentStepG;
+    }
+
+    if (ot->reference != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"REFERENCE\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, ot->reference);
+        indentG -= indentStepG;
+    }
+
+    if (ot->index != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"INDEX\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        last = (TypeOrValue*)LAST_LIST_ELMT (ot->index);
+        FOR_EACH_LIST_ELMT (tOrV, ot->index)
+        {
+            INDENT (f, indentG);
+            if (tOrV->choiceId == TYPEORVALUE_TYPE)
+                PrintType (f, head, tOrV->a.type);
+            else
+                PrintValue (f, NULL, t, tOrV->a.value);
+
+            if (tOrV  != last)
+                fprintf (f, ",\n");
+        }
+        indentG -= indentStepG;
+    }
+
+    if (ot->defVal != NULL)
+    {
+        fprintf (f,"\n");
+        INDENT (f, indentG);
+        fprintf (f,"DEFVAL\n");
+        indentG += indentStepG;
+        INDENT (f, indentG);
+        PrintValue (f, NULL, t, ot->defVal);
+        indentG -= indentStepG;
+    }
+
+    fprintf (f,"\n");
+
+    indentG -= indentStepG;
+}  /* PrintSnmpObjectTypeMacroType */
+
+
+/*
+ * @MACRO@ add new macro print routines above this point
+ */
+
+void
+PrintMacroDef PARAMS ((f, head),
+    FILE *f _AND_
+    TypeDef *head)
+{
+    char *s;
+
+    fprintf (f,"\n--  Note: snacc does not use macro defs to extend the compiler.");
+    fprintf (f,"\n--  All macros that are understood have been hand coded.");
+    fprintf (f,"\n--  The macro def body is kept as a string only.\n\n");
+
+    s =  head->type->basicType->a.macroDef;
+
+    fprintf (f, "%s MACRO ::=\n", head->definedName);
+    fprintf (f, "%s", s);
+
+}  /* PrintMacroDef */
+
+
+
+void
+PrintEncodedOid PARAMS ((f, eoid),
+    FILE *f _AND_
+    AsnOid *eoid)
+{
+    int i;
+    int arcNum;
+    int firstArcNum;
+    int secondArcNum;
+
+    if (eoid == NULL)
+       return;
+
+    fprintf (f, "{ ");
+
+    for (arcNum = 0, i=0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80);i++)
+        arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+
+    arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+    i++;
+
+    firstArcNum = arcNum / 40;
+    if (firstArcNum > 2)
+        firstArcNum = 2;
+
+    secondArcNum = arcNum - (firstArcNum * 40);
+
+    fprintf (f, "%d ", firstArcNum);
+    fprintf (f, "%d ", secondArcNum);
+    for (; i < eoid->octetLen; )
+    {
+        for (arcNum = 0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80);i++)
+            arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+
+        arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
+        i++;
+
+        fprintf (f, "%d ", arcNum);
+    }
+
+    fprintf (f, "}");
+
+}  /* PrintEncodedOid */
+
+
+
+/*
+ * this just prints  a short form of the given type.  It
+ * does not print the components of a constructed type
+ * such as a SEQUENCE
+ * This is used by the header file generators to annotate
+ * the C/C++ types
+ */
+void
+SpecialPrintBasicType PARAMS ((f, head, t, bt),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t _AND_
+    BasicType *bt)
+{
+    switch (bt->choiceId)
+    {
+
+        case BASICTYPE_SEQUENCE:
+            fprintf (f, "SEQUENCE");
+            break;
+
+        case BASICTYPE_SET:
+            fprintf (f, "SET");
+            break;
+
+        case BASICTYPE_CHOICE:
+            fprintf (f, "CHOICE");
+            break;
+
+
+
+        case BASICTYPE_SEQUENCEOF:
+            fprintf (f, "SEQUENCE ");
+            if (t->subtypes != NULL)
+            {
+                PrintSubtype (f, head, t, t->subtypes);
+                fprintf (f," ");
+            }
+            fprintf (f, "OF ");
+            SpecialPrintType (f, head, t->basicType->a.sequenceOf);
+            break;
+
+        case BASICTYPE_SETOF:
+            fprintf (f, "SET ");
+            if (t->subtypes != NULL)
+            {
+                PrintSubtype (f, head, t, t->subtypes);
+                fprintf (f," ");
+            }
+            fprintf (f, "OF ");
+            SpecialPrintType (f, head, t->basicType->a.sequenceOf);
+            break;
+
+
+        case BASICTYPE_SELECTION:
+            fprintf (f, "%s < ", bt->a.selection->fieldName);
+            PrintType (f, head, bt->a.selection->typeRef);
+            break;
+
+
+
+
+        case BASICTYPE_COMPONENTSOF:
+            fprintf (f, "COMPONENTS OF ");
+            PrintType (f, NULL, bt->a.componentsOf);
+            break;
+
+
+
+        case BASICTYPE_ANYDEFINEDBY:
+            fprintf (f, "ANY DEFINED BY %s", bt->a.anyDefinedBy->fieldName);
+            break;
+
+
+        case BASICTYPE_LOCALTYPEREF:
+            fprintf (f, "%s", bt->a.localTypeRef->typeName);
+            break;
+
+        case BASICTYPE_IMPORTTYPEREF:
+            fprintf (f, "%s", bt->a.importTypeRef->typeName);
+            break;
+
+
+        case BASICTYPE_UNKNOWN:
+            fprintf (f, "unknown type !?!");
+            break;
+
+        case BASICTYPE_BOOLEAN:
+            fprintf (f, "BOOLEAN");
+            break;
+
+
+        case BASICTYPE_INTEGER:
+            fprintf (f, "INTEGER");
+            if ((bt->a.integer != NULL) && !LIST_EMPTY (bt->a.integer))
+                SpecialPrintNamedElmts (f, head, t);
+            break;
+
+
+        case BASICTYPE_BITSTRING:
+            fprintf (f, "BIT STRING");
+            if ((bt->a.bitString != NULL) && !LIST_EMPTY (bt->a.bitString))
+                SpecialPrintNamedElmts (f, head, t);
+            break;
+
+        case BASICTYPE_OCTETSTRING:
+            fprintf (f, "OCTET STRING");
+            break;
+
+        case BASICTYPE_NULL:
+            fprintf (f, "NULL");
+            break;
+
+        case BASICTYPE_OID:
+            fprintf (f, "OBJECT IDENTIFIER");
+            break;
+
+        case BASICTYPE_REAL:
+            fprintf (f, "REAL");
+            break;
+
+        case BASICTYPE_ENUMERATED:
+            fprintf (f, "ENUMERATED");
+            if ((bt->a.enumerated != NULL) && !LIST_EMPTY (bt->a.enumerated))
+                SpecialPrintNamedElmts (f, head, t);
+
+            break;
+
+        case BASICTYPE_ANY:
+            fprintf (f, "ANY");
+            break;
+
+        case BASICTYPE_MACROTYPE:
+            switch (bt->a.macroType->choiceId)
+            {
+        case MACROTYPE_ROSOPERATION:
+        case MACROTYPE_ASNABSTRACTOPERATION:
+            PrintRosOperationMacroType (f, head, t, bt, bt->a.macroType->a.rosOperation);
+            break;
+
+        case MACROTYPE_ROSERROR:
+        case MACROTYPE_ASNABSTRACTERROR:
+            PrintRosErrorMacroType (f, head, t, bt, bt->a.macroType->a.rosError);
+            break;
+
+        case MACROTYPE_ROSBIND:
+        case MACROTYPE_ROSUNBIND:
+            PrintRosBindMacroType (f, head, t, bt, bt->a.macroType->a.rosBind);
+            break;
+
+        case MACROTYPE_ROSASE:
+            PrintRosAseMacroType (f, head, t, bt, bt->a.macroType->a.rosAse);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONS:
+            PrintMtsasExtensionsMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensions);
+            break;
+
+        case MACROTYPE_MTSASEXTENSION:
+            PrintMtsasExtensionMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtension);
+            break;
+
+        case MACROTYPE_MTSASEXTENSIONATTRIBUTE:
+            PrintMtsasExtensionAttributeMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensionAttribute);
+            break;
+
+        case MACROTYPE_MTSASTOKEN:
+            PrintMtsasTokenMacroType (f, head, t, bt, bt->a.macroType->a.mtsasToken);
+            break;
+
+        case MACROTYPE_MTSASTOKENDATA:
+            PrintMtsasTokenDataMacroType (f, head, t, bt, bt->a.macroType->a.mtsasTokenData);
+            break;
+
+        case MACROTYPE_MTSASSECURITYCATEGORY:
+            PrintMtsasSecurityCategoryMacroType (f, head, t, bt, bt->a.macroType->a.mtsasSecurityCategory);
+            break;
+
+        case MACROTYPE_ASNOBJECT:
+            PrintAsnObjectMacroType (f, head, t, bt, bt->a.macroType->a.asnObject);
+            break;
+
+        case MACROTYPE_ASNPORT:
+            PrintAsnPortMacroType (f, head, t, bt, bt->a.macroType->a.asnPort);
+            break;
+
+        case MACROTYPE_ASNABSTRACTBIND:
+        case MACROTYPE_ASNABSTRACTUNBIND:
+            PrintAsnAbstractBindMacroType (f, head, t, bt, bt->a.macroType->a.asnAbstractBind);
+            break;
+
+        case MACROTYPE_AFALGORITHM:
+            PrintAfAlgorithmMacroType (f, head, t, bt, bt->a.macroType->a.afAlgorithm);
+            break;
+
+        case MACROTYPE_AFENCRYPTED:
+            PrintAfEncryptedMacroType (f, head, t, bt, bt->a.macroType->a.afEncrypted);
+            break;
+
+        case MACROTYPE_AFSIGNED:
+            PrintAfSignedMacroType (f, head, t, bt, bt->a.macroType->a.afSigned);
+            break;
+
+        case MACROTYPE_AFSIGNATURE:
+            PrintAfSignatureMacroType (f, head, t, bt, bt->a.macroType->a.afSignature);
+            break;
+
+        case MACROTYPE_AFPROTECTED:
+            PrintAfProtectedMacroType (f, head, t, bt, bt->a.macroType->a.afProtected);
+            break;
+
+        case MACROTYPE_SNMPOBJECTTYPE:
+            PrintSnmpObjectTypeMacroType (f, head, t, bt, bt->a.macroType->a.snmpObjectType);
+            break;
+
+        default:
+            fprintf (f, "< unknown macro type id ?! >");
+
+    } /* end macro type switch */
+    break;
+
+        /*
+         * @MACRO@ add new macro printers above this point
+         */
+
+        case BASICTYPE_MACRODEF:
+            /*
+             * printing this should be handled in PrintTypeDefs
+             */
+            break;
+
+
+        default:
+            fprintf (f, "< unknown type id ?! >");
+
+    }
+}  /* SpecialPrintBasicType */
+
+
+/*
+ * this just prints  a short form of the given type.  It
+ * does not print the components of a constructed type
+ * such as a SEQUENCE
+ * This is used by the header file generators to annotate
+ * the C types
+ */
+void
+SpecialPrintType PARAMS ((f, head, t),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t)
+{
+    Tag *tag;
+    Tag *lastTag;
+
+    if (t == NULL)
+        return;
+
+    lastTag = NULL;
+    FOR_EACH_LIST_ELMT (tag, t->tags)
+    {
+        if (!(tag->tclass == UNIV && tag->code == LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId)))
+        {
+            PrintTag (f, tag);
+            fprintf (f, " ");
+        }
+        lastTag = tag;
+    }
+
+    /*
+     * check type has been implicitly tagged
+     */
+    if (t->implicit)
+        fprintf (f, "IMPLICIT ");
+
+    SpecialPrintBasicType (f, head, t, t->basicType);
+
+
+    /*
+     * sequences of and set of print subtypes a special way
+     * so ignore them here
+     */
+    if ((t->subtypes != NULL) &&
+        (t->basicType->choiceId != BASICTYPE_SETOF) &&
+        (t->basicType->choiceId != BASICTYPE_SEQUENCEOF))
+    {
+        fprintf (f," ");
+        PrintSubtype (f, head, t, t->subtypes);
+    }
+
+
+    if (t->defaultVal != NULL)
+    {
+        fprintf (f, " DEFAULT ");
+        if (t->defaultVal->fieldName != NULL)
+            fprintf (f, "%s ", t->defaultVal->fieldName);
+        PrintValue (f, NULL, t, t->defaultVal->value);
+    }
+
+    else if (t->optional)
+        fprintf (f, " OPTIONAL");
+
+
+#ifdef DEBUG
+    fprintf (f, "  -- lineNo = %d", t->lineNo);
+    fprintf (f, " --");
+#endif
+
+}  /* SpecialPrintType */
+
+
+/*
+ * This is used by the header file generators to annotate
+ * the C/C++ types.  This version prints the C version of the
+ * enum/bits elmt names to make sure the programmer can use
+ * the correct defines/enum constants.
+ * NOTE: this can only be called after the CTRI infor is filled in
+ * so the C/C++ names can be accessed
+ */
+void
+SpecialPrintNamedElmts PARAMS ((f, head, t),
+    FILE *f _AND_
+    TypeDef *head _AND_
+    Type *t)
+{
+    CNamedElmt *last;
+    CNamedElmt *cne;
+    CNamedElmts *n = NULL;
+
+    if (t->cTypeRefInfo != NULL)
+        n = t->cTypeRefInfo->cNamedElmts;
+
+    if ((n == NULL) && (t->cxxTypeRefInfo != NULL))
+        n = t->cxxTypeRefInfo->namedElmts;
+
+
+    if ((n == NULL) || LIST_EMPTY (n))
+        return;
+
+    fprintf (f," { ");
+    last = (CNamedElmt*)LAST_LIST_ELMT (n);
+    FOR_EACH_LIST_ELMT (cne, n)
+    {
+        fprintf (f, "%s (%d)", cne->name, cne->value);
+        if (cne != last)
+            fprintf (f,", ");
+    }
+    fprintf (f," } ");
+}  /* SpecialPrintNamedElmts */
diff --git a/SecuritySNACCRuntime/compiler/core/recursive.c b/SecuritySNACCRuntime/compiler/core/recursive.c
new file mode 100644
index 00000000..446f2ca4
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/recursive.c
@@ -0,0 +1,199 @@
+/*
+ * compiler/core/recursive.c - finds and marks the recursive types in a module.
+ *
+ * ALSO:
+ * prints msgs for infinitely recursive types (ie recursive component
+ * is not OPTIONAL, nor a CHOICE elmt, nor a SET OF nor a SEQ OF elmt.
+ * (OPTIONALs can be left out, CHOICE elements have alternatives (hopefully),
+ * and SET OF and SEQUENCE OF values can have zero elements)
+ *
+ * prints msg for recursive types that hold no real information
+ *     Foo ::= SET OF Foo (sets of sets of .... of empty sets)
+ *
+ * finds bogus recursive types (hold no info) (same as above)
+ *  A ::= B
+ *  B ::= C
+ *  D ::= A
+ *
+ * MS 92
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/recursive.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
+ * $Log: recursive.c,v $
+ * Revision 1.1  2001/06/20 21:27:58  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:43  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:43:10  rj
+ * snacc_config.h removed; recursive.h includet.
+ *
+ * Revision 1.1  1994/08/28  09:49:35  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "recursive.h"
+#include "snacc-util.h"
+
+void MkRecTypeDef PROTO ((Module *m, TypeDef *td));
+
+void MkRecType  PROTO ((Module *m, TypeDef *td,Type *t, int optional, int empty));
+
+
+void
+MarkRecursiveTypes PARAMS ((m),
+    Module *m)
+{
+    TypeDef *td;
+
+    /* first set all typedef as un-visited */
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        td->visited = FALSE;
+        td->tmpRefCount = 0;
+    }
+
+    FOR_EACH_LIST_ELMT (td, m->typeDefs)
+    {
+        MkRecTypeDef (m, td);
+    }
+}  /* MarkRecursiveTypes */
+
+
+
+void
+MkRecTypeDef PARAMS ((m, td),
+    Module *m _AND_
+    TypeDef *td)
+{
+    MkRecType (m, td, td->type, 0, 1);
+}  /* MkRecTypeDef */
+
+
+
+/*
+ * cruise through aggregate types and type refs looking for
+ * a type ref to the original type def, td.  If is a ref to
+ * the td, then mark the td as recusive.
+ *
+ * the optional flag is set if the current type branch is
+ * optional via an OPTIONAL SET/SEQ elmt, CHOICE elmt, SET OF elmt
+ * or SEQ OF elmt.
+ *
+ * the empty flag is initially TRUE and remains true until a
+ * non-type reference type is encountered
+ */
+void
+MkRecType  PARAMS ((m, td, t, optional, empty),
+    Module *m _AND_
+    TypeDef *td _AND_
+    Type *t _AND_
+    int optional _AND_
+    int empty)
+{
+    int newOptional;
+    NamedType *e;
+
+    switch (t->basicType->choiceId)
+    {
+        case BASICTYPE_CHOICE:
+            if (AsnListCount (t->basicType->a.choice) > 1)
+            {
+                empty = 0;
+                optional = 1;
+            }
+            FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
+            {
+                MkRecType (m, td, e->type, optional, empty);
+            }
+            break;
+
+        case BASICTYPE_SET:
+        case BASICTYPE_SEQUENCE:
+            empty = 0;
+
+            FOR_EACH_LIST_ELMT (e, t->basicType->a.set)
+            {
+                newOptional = optional || (e->type->optional) ||
+                              (e->type->defaultVal != NULL);
+                MkRecType (m, td, e->type, newOptional, empty);
+            }
+            break;
+
+        case BASICTYPE_SETOF:
+        case BASICTYPE_SEQUENCEOF:
+            empty = 0;  /* since an empty set is actual data */
+            optional = 1; /* since SET OF and SEQ OF's can be empty */
+            MkRecType (m, td, t->basicType->a.setOf, optional, empty);
+            break;
+
+        case BASICTYPE_LOCALTYPEREF:
+        case BASICTYPE_IMPORTTYPEREF:
+
+            /*
+             * check if ref to original type def & mark recursive if so.
+             */
+/*            if ((strcmp (t->basicType->a.localTypeRef->typeName, td->definedName) == 0) && (t->basicType->a.localTypeRef->module == m))
+ easier to just check ptrs!
+*/
+            if (t->basicType->a.localTypeRef->link == td)
+            {
+                td->recursive = 1;
+                if (empty)
+                {
+                    PrintErrLoc (m->asn1SrcFileName, td->type->lineNo);
+                    fprintf (stderr,"WARNING: Type \"%s\" appears to be infinitely recursive and can hold no values! (circular type references)\n", td->definedName);
+                }
+                else if (!optional)
+                {
+                    PrintErrLoc (m->asn1SrcFileName, t->lineNo);
+                    fprintf (stderr,"WARNING: Type \"%s\" appears to be infinitely recursive! (infinitely sized values)\n", td->definedName);
+                }
+            }
+
+            /*
+             * else follow this type reference if we aren't in it already
+             * (ie another recursive type in td)
+             */
+            else if (t->basicType->a.localTypeRef->link->tmpRefCount == 0)
+            {
+                /*
+                 * mark this typedef as 'entered' to
+                 * detect when looping in a recusive type that is contained
+                 * in the original td (use tmpRefCount)
+                 */
+                 t->basicType->a.localTypeRef->link->tmpRefCount = 1;
+
+                 newOptional = optional || (t->optional) || (t->defaultVal != NULL);
+                 MkRecType (m, td, t->basicType->a.localTypeRef->link->type, newOptional, empty);
+
+                /*
+                 * un-mark this type since finished with it
+                 * for recursive ref's to td
+                 */
+                 t->basicType->a.localTypeRef->link->tmpRefCount = 0;
+            }
+            break;
+
+        /*
+         * default: other types are not aggregate and
+         * do not make recursive refs - they can be ignored
+         */
+    }
+} /* MkRecType */
diff --git a/SecuritySNACCRuntime/compiler/core/recursive.h b/SecuritySNACCRuntime/compiler/core/recursive.h
new file mode 100644
index 00000000..08070452
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/recursive.h
@@ -0,0 +1,29 @@
+/*
+ * compiler/core/recursive.h - find and mark the recursive types in a module
+ *
+ * MS 92
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/recursive.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Log: recursive.h,v $
+ * Revision 1.1  2001/06/20 21:27:59  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.2  1994/10/08 03:48:57  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * Revision 1.1  1994/08/28  09:49:36  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+void MarkRecursiveTypes PROTO ((Module *m));
diff --git a/SecuritySNACCRuntime/compiler/core/snacc-util.c b/SecuritySNACCRuntime/compiler/core/snacc-util.c
new file mode 100644
index 00000000..5b3ac50c
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/snacc-util.c
@@ -0,0 +1,1334 @@
+/*
+ * compiler/core/snacc_util.c
+ *
+ * utilities for dealing with the Module data structure
+ *
+ * AUTHOR: Mike Sample
+ * DATE:   91/09/02
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/snacc-util.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Log: snacc-util.c,v $
+ * Revision 1.1  2001/06/20 21:27:59  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:44  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:45:09  rj
+ * snacc_config.h removed.
+ *
+ * Revision 1.1  1994/08/28  09:49:39  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "lib-types.h"
+#include "define.h"
+#include "snacc-util.h"
+
+
+
+/*
+ * Allocates and initializes a type and it's basicType info
+ * used extensively by asn1.yacc
+ * (was a macro)
+ */
+void
+SetupType PARAMS ((t, typeId, lineNum),
+    Type **t _AND_
+    enum BasicTypeChoiceId typeId _AND_
+    unsigned long lineNum)
+{
+    Tag **tmpPtr;
+
+    (*t) = (Type*)Malloc (sizeof (Type));
+    (*t)->lineNo = lineNum;
+    (*t)->basicType = (BasicType*)Malloc (sizeof (BasicType));
+    (*t)->basicType->choiceId = typeId;
+    (*t)->tags = (TagList*)AsnListNew (sizeof (void*));
+    if (LIBTYPE_GET_UNIV_TAG_CODE ((typeId)) != NO_TAG_CODE)
+    {
+         tmpPtr = (Tag**)AsnListAppend ((AsnList*)(*t)->tags);
+         *tmpPtr = (Tag*)Malloc (sizeof (Tag));
+         (*tmpPtr)->tclass = UNIV;
+         (*tmpPtr)->code = LIBTYPE_GET_UNIV_TAG_CODE ((typeId));
+    }
+} /* SetupType */
+
+
+/*
+ * Allocates and initializes a type and it's basicType to MACROTYPE
+ * and sets the MACROTYPE type to the given macrotype
+ */
+void
+SetupMacroType PARAMS ((t, macroTypeId, lineNum),
+    Type **t _AND_
+    enum MacroTypeChoiceId macroTypeId _AND_
+    unsigned long lineNum)
+{
+    Tag **tmpPtr;
+
+    (*t) = MT (Type);
+    (*t)->lineNo = lineNum;
+    (*t)->basicType = MT (BasicType);
+    (*t)->basicType->choiceId = BASICTYPE_MACROTYPE;
+    (*t)->tags = (TagList*)AsnListNew (sizeof (void*));
+    (*t)->basicType->a.macroType = MT (MacroType);
+    (*t)->basicType->a.macroType->choiceId = macroTypeId;
+} /* SetupMacroType */
+
+
+/*
+ * similar to SetupType but for values instead
+ */
+void
+SetupValue PARAMS ((v, valId, lineNum),
+    Value **v _AND_
+    enum BasicValueChoiceId valId _AND_
+    unsigned long lineNum)
+{
+    *v = (Value*)Malloc (sizeof (Value));
+    (*v)->basicValue = (BasicValue*)Malloc (sizeof (BasicValue));
+    (*v)->basicValue->choiceId = valId;
+    (*v)->lineNo = lineNum;
+} /* SetupValue */
+
+
+/*
+ * adds elmt with given name to module m's import list from
+ * the module with name refdModuleName.  If module m does not
+ * have an import list from that module one is created.
+ * The import element is given the private scope implied
+ * by the ASN.1 modname.typ-or-val-name reference format
+ * The passed in strings (name, refdModuleName) are copied.
+ */
+void
+AddPrivateImportElmt PARAMS ((m, name, refdModuleName, lineNo),
+    Module *m _AND_
+    char *name _AND_
+    char *refdModuleName _AND_
+    long int lineNo)
+{
+    ImportElmt   *newElmt;
+    ImportElmt   *ie;
+    ImportModule *impMod;
+
+
+    /* see if module m already imports something from "refdModule" */
+    if ((impMod = LookupImportModule (m, refdModuleName)) == NULL)
+    {
+        impMod = MT (ImportModule);
+        impMod->modId = MT (ModuleId);
+        impMod->modId->name = Malloc (strlen (refdModuleName)+1);
+        strcpy (impMod->modId->name, refdModuleName);
+
+        newElmt = MT (ImportElmt);
+        newElmt->name = Malloc (strlen (name)+1);
+        strcpy (newElmt->name, name);
+        newElmt->privateScope = TRUE;
+
+        APPEND (newElmt, impMod->importElmts);
+        APPEND (impMod, m->imports);
+    }
+    else  /* module "refdModule is already imported from */
+    {
+        ie = LookupImportElmtInImportElmtList (impMod->importElmts, name);
+
+        if (ie == NULL)
+        {
+            newElmt  = MT (ImportElmt);
+            newElmt->name = Malloc (strlen (name)+1);
+            strcpy (newElmt->name, name);
+            APPEND (newElmt, impMod->importElmts);
+        }
+        else if (!ie->privateScope)
+        {
+            PrintErrLoc (m->asn1SrcFileName, lineNo);
+            fprintf (stderr, "WARNING - \"%s.%s\" type/value reference refers to a type/value already in the import list that does not have private scope.\n", refdModuleName, name);
+        }
+    }
+} /* AddPrivateImportElmt */
+
+/*
+ *   looks for the named import type/value in all of the IMPORT lists of the
+ *   given module.
+ *   RETURNS a ptr to the import elmt if found, NULL if it was not found.
+ *   If the item was found (ptr returned) the foundImportModule addr
+ *   parameter will be set to the module's importModule that holds
+ *   the found elmt.
+ *
+ *   returns NULL if the named import name was not found
+ *
+ */
+ImportElmt*
+LookupImportElmtInModule PARAMS ((m, name, foundImportModule),
+    Module *m _AND_
+    char *name _AND_
+    ImportModule **foundImportModule)
+{
+     ImportModule *importMod;
+     ImportElmt *importElmt;
+     ImportElmt *retVal;
+     void *tmp;
+
+     if (m->imports == NULL)
+         return NULL;
+
+     tmp = (void*)CURR_LIST_NODE (m->imports);
+     retVal = NULL;
+     FOR_EACH_LIST_ELMT (importMod, m->imports)
+     {
+         importElmt = LookupImportElmtInImportElmtList (importMod->importElmts, name);
+         if (importElmt != NULL)
+         {
+             *foundImportModule = importMod;
+             retVal = importElmt;
+             break;
+         }
+     }
+
+     SET_CURR_LIST_NODE (m->imports, tmp); /* restore orig loc */
+     return retVal;
+
+}  /* LookupImportElmtInModule */
+
+
+/*
+ * given a list of import elmts, returns ptr to the elmt with
+ * the matching name. NULL if not found
+ */
+ImportElmt*
+LookupImportElmtInImportElmtList PARAMS ((impElmtList, name),
+    ImportElmtList *impElmtList _AND_
+    char *name)
+    
+{
+     ImportElmt *impElmt;
+     ImportElmt *retVal;
+     void *tmp;
+
+     if (impElmtList == NULL)
+         return NULL;
+
+     tmp = (void*) CURR_LIST_NODE (impElmtList);
+     retVal = NULL;
+     FOR_EACH_LIST_ELMT (impElmt, impElmtList)
+     {
+         if (strcmp (impElmt->name, name) == 0)
+         {
+             retVal = impElmt;
+             break;
+         }
+     }
+
+     SET_CURR_LIST_NODE (impElmtList, tmp);
+     return retVal;
+
+}  /* LookupImportElmtInImportElmtList */
+
+
+
+
+/*
+ *   looks for an import list that imports from "importModuleName"
+ *   module in the given module.
+ *
+ *   returns a ptr to the ImportList if found
+ *   returns NULL if not found
+ */
+ImportModule*
+LookupImportModule PARAMS ((m, importModuleName),
+    Module *m _AND_
+    char *importModuleName)
+{
+    ImportModule *importModule;
+    ImportModule *retVal;
+    void *tmp;
+
+    if (m->imports == NULL)
+        return NULL;
+
+    tmp = (void*)CURR_LIST_NODE (m->imports);
+    retVal = NULL;
+    FOR_EACH_LIST_ELMT (importModule, m->imports)
+    {
+        if (strcmp (importModule->modId->name, importModuleName) == 0)
+        {
+            retVal= importModule;
+            break;
+        }
+    }
+
+    SET_CURR_LIST_NODE (m->imports, tmp);
+    return retVal;
+
+}  /* LookupImportModule */
+
+
+
+
+/*
+ *  Looks for the type with name matching typeName (null terminated char*)
+ *  in the given the TypeDef list
+ *
+ *  RETURNS: ptr to the TypeDef with the matching typeName (if any)
+ *           NULL if no match was made
+ */
+TypeDef*
+LookupType PARAMS ((typeDefList, typeName),
+    TypeDefList *typeDefList _AND_
+    char *typeName)
+{
+    TypeDef *td;
+    TypeDef *retVal;
+    void *tmp;
+
+    if (typeDefList == NULL)
+        return NULL;
+
+    if (typeName == NULL)
+    {
+#ifdef DEBUG
+        fprintf (stderr,"LookupType: warning - failure due to NULL key\n");
+#endif
+        return NULL;
+    }
+
+    tmp = (void*)CURR_LIST_NODE (typeDefList); /* remember curr list spot */
+    retVal = NULL;
+    FOR_EACH_LIST_ELMT (td, typeDefList)
+    {
+        if (strcmp (typeName, td->definedName) == 0)
+        {
+            retVal = td;
+            break;
+        }
+    }
+
+    SET_CURR_LIST_NODE (typeDefList,tmp); /* restore curr location */
+
+    return retVal;
+
+}  /* LookupType */
+
+
+/*
+ * Returns ptr to module that has matching name or OID
+ * if oid is not null, lookup done only by oid
+ *
+ * returns NULL if no match was found
+ */
+Module*
+LookupModule PARAMS ((moduleList, modName, oid),
+    ModuleList *moduleList _AND_
+    char *modName _AND_
+    OID *oid)
+{
+    Module *currMod;
+    Module *retVal;
+    int strMatch = FALSE;
+    int oidMatch = FALSE;
+    OID *oid1;
+    OID *oid2;
+    void *tmp;
+
+    if ((moduleList == NULL) || ((modName == NULL) && (oid == NULL)))
+        return NULL;
+
+    tmp = (void*)CURR_LIST_NODE (moduleList); /* remember orig loc */
+    retVal = NULL;
+    FOR_EACH_LIST_ELMT (currMod, moduleList)
+    {
+
+        /*
+         *  may fail due to unresolved int or oid value ref
+         *  so try name match anyway.
+         *  This is not standard (CCITT) if the oids were resolved
+         *  but different, in which case the match should
+         *  fail regardless of the name match. oh well, ts.
+         */
+        if (CompareOids (oid, currMod->modId->oid))
+        {
+            retVal = currMod;
+            break; /* exit for loop */
+        }
+
+        else if ((modName != NULL) &&
+            (strcmp (modName, currMod->modId->name) == 0))
+        {
+            retVal = currMod;
+            break; /* exit for loop */
+        }
+    }
+
+    SET_CURR_LIST_NODE (moduleList, tmp);
+    return retVal;
+
+}  /* LookupModule */
+
+
+
+
+/*
+ * Given a constructed type, it returns the component of that
+ * type with the matching field name.  Returns NULL if teh
+ * given type does not have the named field or is not
+ * a type that has fields.
+ */
+NamedType*
+LookupFieldInType PARAMS ((tRef, fieldName),
+    Type *tRef _AND_
+    char *fieldName)
+{
+    NamedType *e;
+    NamedType *retVal;
+    Type *t;
+    void *tmp;
+
+    t = ParanoidGetType (tRef); /* skip any references etc */
+
+    if ((t->basicType->choiceId != BASICTYPE_SET) &&
+        (t->basicType->choiceId != BASICTYPE_SEQUENCE) &&
+        (t->basicType->choiceId != BASICTYPE_CHOICE))
+    {
+#ifdef DEBUG
+        fprintf (stderr,"LookupFieldInType: ERROR - attempt to look for field in a non SET/SEQ/CHOICE type\n");
+#endif
+        return NULL;
+    }
+
+    /* return if null list */
+    if (t->basicType->a.set == NULL)
+        return NULL;
+
+    /* remember set's original curr elmt */
+    tmp = (void*)CURR_LIST_NODE (t->basicType->a.set);
+    retVal = NULL;
+    FOR_EACH_LIST_ELMT (e, t->basicType->a.set)
+    {
+        /* remember fieldname is optional so it can be null */
+        if ((e->fieldName != NULL) && (strcmp (e->fieldName, fieldName) == 0))
+        {
+            retVal = e;
+            break; /* exit  for loop */
+        }
+    }
+    SET_CURR_LIST_NODE (t->basicType->a.set, tmp);
+    return retVal;
+
+} /* LookupFieldInType */
+
+
+
+/*
+ *  Goes through typerefs (if any) to get to actual
+ *  ASN1 type. Returns the found "defining" type.
+ *  May return the given type t, if it's not a typeref
+ *  or if it is an unlinked type ref
+ */
+Type*
+GetType PARAMS ((type),
+    Type *type)
+{
+    TypeDef *td;
+    Type *t;
+
+    t = type;
+    if (t == NULL)
+        return NULL;
+
+    while (1)
+    {
+        switch (t->basicType->choiceId)
+        {
+            case BASICTYPE_LOCALTYPEREF:
+            case BASICTYPE_IMPORTTYPEREF:
+                td = t->basicType->a.localTypeRef->link;
+                if (td == NULL)
+                    return type;
+                else
+                    t = td->type;
+                break;
+
+            default:
+                return t;
+        }
+    }
+}  /* GetType */
+
+
+/*
+ * like GetType ie, skips type references to return the defining type.
+ * This is a paranoid version - it checks for circular type errors.
+ *  eg: A ::= B
+ *      B ::= A
+ * would make the normal GetType recurse forever (until no stk mem)
+ */
+Type*
+ParanoidGetType PARAMS ((type),
+    Type *type)
+{
+    TypeDef *td;
+    Type *t;
+    DefinedObj *l;
+
+    t = type;
+    if (t == NULL)
+        return NULL;
+
+    l = NewObjList();
+    while (1)
+    {
+        switch (t->basicType->choiceId)
+        {
+            case BASICTYPE_LOCALTYPEREF:
+            case BASICTYPE_IMPORTTYPEREF:
+                td = t->basicType->a.localTypeRef->link;
+                if ((td == NULL) || (ObjIsDefined (l, td->type, ObjPtrCmp)))
+                {
+                    return type;
+                }
+                else
+                {
+                    t = td->type;
+                    DefineObj (&l, t);
+                }
+                break;
+
+            default:
+                FreeDefinedObjs (&l);
+                return t;
+        }
+    }
+
+}  /* ParnoidGetType */
+
+
+/*
+ *  Goes through typerefs (if any) to get to actual
+ *  ASN1 basic type (eg int, bool, seq, seq of, set,
+ *  set of, choice, any, etc.
+ *  Returns the typeId of that type, otherwise -1.
+ */
+enum BasicTypeChoiceId
+GetBuiltinType PARAMS ((t),
+    Type *t)
+{
+    Type *definingType;
+
+    definingType = GetType (t);
+    if (definingType != NULL)
+        return definingType->basicType->choiceId;
+    else
+        return -1;
+
+}  /* GetBuiltinType */
+
+
+/*  Paranoid version of GetBuiltinType
+ *  goes through typerefs (if any) to get to actual
+ *  ASN1 basic type (eg int, bool, seq, seq of, set,
+ *  set of, choice, any, etc.
+ *  Returns the typeId of that type, otherwise -1.
+ */
+enum BasicTypeChoiceId
+ParanoidGetBuiltinType PARAMS ((t),
+    Type *t)
+{
+    Type *definingType;
+
+    definingType = ParanoidGetType (t);
+    if (definingType != NULL)
+        return definingType->basicType->choiceId;
+    else
+        return -1;
+
+}  /* GetBuiltinType */
+
+
+
+/*
+ * Goes through typerefs (if any) to get to
+ * the namedElmts (if any) associated with the
+ * given type (INTEGER, ENUMERATED, BITSTRING or
+ * LOCAL/IMPORT REFS to these types).
+ * Returns NULL if there are no associated Named Elmts
+ */
+NamedNumberList*
+GetNamedElmts PARAMS ((t),
+    Type *t)
+{
+    Type *definingType;
+
+    if (t == NULL)
+        return NULL;
+
+    definingType = ParanoidGetType (t);
+
+    if (definingType == NULL)
+        return NULL;
+
+    switch (definingType->basicType->choiceId)
+    {
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_ENUMERATED:
+        case BASICTYPE_BITSTRING:
+            return definingType->basicType->a.integer;
+
+        /*
+         * for non-named elmt types
+         * just return NULL
+         */
+        default:
+            return NULL;
+    }
+
+    /* not reached */
+}  /* GetNamedElmts */
+
+
+/*
+ * [Same as GetNamedElmts except goes through CHOICEs as well &
+ *  REQUIRES you to deallocate the list (but not its members).]
+ *  This is nec. for CHOICEs that contain INTs etc. with named #'s]
+ *  This is used for value linking.
+ *
+ * Goes through typerefs (if any) to get to
+ * the namedElmts (if any) associated with the
+ * given type (INTEGER, ENUMERATED, BITSTRING or
+ * LOCAL/IMPORT REFS to these types).  Also returns
+ * a named element list for CHOICE types that contain
+ * named elemnts
+ * Returns an empty list if there are no associated Named Elmts.
+ * you are responsible  for freeing this list.  Do not free the list
+ * elmts - they are part of the types.
+ */
+NamedNumberList*
+GetAllNamedElmts PARAMS ((t),
+    Type *t)
+{
+    Type *definingType;
+    NamedType *nt;
+    NamedNumberList *retVal;
+    NamedNumberList *ntElmtList;
+    ValueDef *nn;  /* named number is a valuedef */
+    ValueDef **nnHndl;
+
+    retVal = AsnListNew (sizeof (void*));
+
+    if (t == NULL)
+        return retVal;
+
+    definingType = ParanoidGetType (t);
+
+    if (definingType == NULL)
+        return retVal;
+
+
+    switch (definingType->basicType->choiceId)
+    {
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_ENUMERATED:
+        case BASICTYPE_BITSTRING:
+            /*
+             * add the named elmts (if any) to the new list
+             */
+            FOR_EACH_LIST_ELMT (nn, definingType->basicType->a.integer)
+            {
+                nnHndl = (ValueDef**)AsnListAppend (retVal);
+                *nnHndl = nn;
+            }
+            break;
+
+        /*
+         * for choices must group all named elmts from choice components
+         * and return in a list.
+         */
+        case BASICTYPE_CHOICE:
+            FOR_EACH_LIST_ELMT (nt, definingType->basicType->a.choice)
+            {
+                ntElmtList = GetAllNamedElmts (nt->type);
+                retVal = AsnListConcat (retVal, ntElmtList);
+                Free (ntElmtList); /* zap now unused list head */
+            }
+            break;
+    }
+    return retVal;
+}  /* GetAllNamedElmts */
+
+
+/*
+ * Recursively does pseudo breadth first search from the given ancestor
+ * looking for the given child node.  Returns the direct parent Type
+ * of the child if found, NULL otherwise.  This routine does not follow
+ * type references.
+ */
+Type*
+GetParent PARAMS ((ancestor, child),
+    Type *ancestor _AND_
+    Type *child)
+{
+    NamedType *e;
+    Type *parent;
+    void *tmp;
+
+    if ((ancestor->basicType->choiceId != BASICTYPE_SET) &&
+        (ancestor->basicType->choiceId != BASICTYPE_SEQUENCE) &&
+        (ancestor->basicType->choiceId != BASICTYPE_CHOICE) &&
+        (ancestor->basicType->choiceId != BASICTYPE_SETOF) &&
+        (ancestor->basicType->choiceId != BASICTYPE_SEQUENCEOF))
+    {
+        return NULL;
+    }
+
+    if (ancestor->basicType->a.set == NULL)
+        return NULL;
+
+    if ((ancestor->basicType->choiceId == BASICTYPE_SETOF) ||
+        (ancestor->basicType->choiceId == BASICTYPE_SEQUENCEOF))
+    {
+        if (child == ancestor->basicType->a.setOf)
+            return ancestor;
+        else
+            return GetParent (ancestor->basicType->a.setOf, child);
+    }
+
+    tmp = (void*)CURR_LIST_NODE (ancestor->basicType->a.set);
+    /*
+     * look through direct children of ancestor first
+     */
+    FOR_EACH_LIST_ELMT (e,  ancestor->basicType->a.set)
+    {
+        if (child == e->type)
+        {
+            SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp);
+            return ancestor;
+        }
+    }
+
+
+    /*
+     * look through grandchildren if not in children
+     */
+    FOR_EACH_LIST_ELMT (e,  ancestor->basicType->a.set)
+    {
+        if ((parent = GetParent (e->type, child)) != NULL)
+        {
+            SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp);
+            return parent;
+        }
+    }
+
+    SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp);
+    return NULL;
+}  /* GetParent */
+
+
+
+/*
+ *  Looks for the value with the given valueName (null term char*) in the
+ *  given list of ValueDefs
+ *  RETURNS: ptr to ValueDef with matching key (if any)
+ *           NULL if no match was made
+ */
+
+ValueDef*
+LookupValue PARAMS ((valueList, valueName),
+    ValueDefList *valueList _AND_
+    char *valueName)
+{
+    ValueDef *v;
+    ValueDef *retVal;
+    void *tmp;
+
+    if (valueName == NULL)
+    {
+#ifdef DEBUG
+        fprintf (stderr,"LookupType: warning - failure due to NULL key\n");
+#endif
+        return NULL;
+    }
+
+    if (valueList == NULL)
+        return NULL;
+
+    tmp = (void*)CURR_LIST_NODE (valueList);
+    retVal = NULL;
+    FOR_EACH_LIST_ELMT (v, valueList)
+    {
+        if (strcmp (valueName, v->definedName) == 0)
+        {
+            retVal = v;
+            break; /* exit for loop */
+        }
+    }
+
+    SET_CURR_LIST_NODE (valueList, tmp);
+    return retVal;
+
+}  /* LookupValue */
+
+
+
+/*
+ *  Goes through valuerefs (if any) to get to actual
+ *  ASN1 value.  Analogous to GetType.
+ */
+Value*
+GetValue PARAMS ((v),
+    Value *v)
+{
+    ValueDef *vd;
+
+    while (v != NULL)
+    {
+        switch (v->basicValue->choiceId)
+        {
+            case BASICVALUE_LOCALVALUEREF:
+            case BASICVALUE_IMPORTVALUEREF:
+                vd = v->basicValue->a.localValueRef->link;
+                if (vd == NULL)
+                    v = NULL;
+                else
+                    v = vd->value;
+                break;
+
+            default:
+                return v;
+        }
+    }
+    fprintf (stderr, "GetValue: ERROR - cannot get value for unlinked local/import value refs\n");
+    return NULL;
+
+}  /* GetValue */
+
+
+/*
+ * Returns TRUE if oid1 and oid2 are identical otherwise FALSE
+ */
+int
+CompareOids PARAMS ((oid1, oid2),
+    OID *oid1 _AND_
+    OID *oid2)
+{
+    if ((oid1 == NULL) && (oid2 == NULL))
+        return FALSE;
+
+    for (; (oid1 != NULL) && (oid2 != NULL); oid1 = oid1->next, oid2 = oid2->next)
+    {
+        /*
+         *  fail if value refs have not been resolved or
+         *   no match between arcnums
+         */
+        if ((oid1->arcNum == NULL_OID_ARCNUM) ||
+             (oid2->arcNum == NULL_OID_ARCNUM) ||
+             (oid1->arcNum != oid2->arcNum))
+            return FALSE;
+
+        /*
+         * could check ref'd values for same name
+         * incase value ref has not been resolved
+         * and put in arcNum
+         */
+    }
+
+    if ((oid1 == NULL) && (oid2 == NULL))
+        return TRUE;
+    else
+        return FALSE;
+
+}  /*  CompareOids */
+
+
+/*
+ *  Returns TRUE if the given type is INTEGER, ENUMERATED or
+ *  BIT STRING and it has named elements
+ *  ie Foo ::= INTEGER { one (1), two (2) } would return TRUE
+ */
+int
+HasNamedElmts PARAMS ((t),
+    Type *t)
+{
+    return ((t->basicType->choiceId == BASICTYPE_INTEGER) ||
+             (t->basicType->choiceId == BASICTYPE_ENUMERATED) ||
+             (t->basicType->choiceId == BASICTYPE_BITSTRING)) &&
+           (t->basicType->a.integer != NULL) &&
+           !LIST_EMPTY (t->basicType->a.integer);
+} /* HasNamedElmts */
+
+
+/*
+ * Returns true if the given tag lists are the same
+ * (assumes value refs have be resolved)
+ */
+int
+TagsAreIdentical PARAMS ((t1, t2),
+    TagList *t1 _AND_
+    TagList *t2)
+{
+    Tag *tag1;
+    Tag *tag2;
+
+    /* both lists are empty */
+    if (((t1 == NULL) || LIST_EMPTY (t1)) &&
+        ((t2 == NULL) || LIST_EMPTY (t2)))
+        return TRUE;
+
+    else if ((t1 == NULL) || (t2 == NULL))
+        return FALSE;
+
+    else if (LIST_COUNT (t1) == LIST_COUNT (t2))
+    {
+        SET_CURR_LIST_NODE (t2, FIRST_LIST_NODE (t2));
+        FOR_EACH_LIST_ELMT (tag1, t1)
+        {
+            tag2 = (Tag*) CURR_LIST_ELMT (t2);
+            if ((tag1->tclass != tag2->tclass) || (tag1->code == tag2->code))
+                return FALSE;
+            SET_CURR_LIST_NODE (t2, NEXT_LIST_NODE (t2));
+        }
+        return TRUE;
+    }
+    else
+        return FALSE;
+
+} /* TagsAreIdentical */
+
+
+
+/*
+ * Returns TRUE if the tag currently on the given type has the default
+ * tag specified in the type tbl. otherwise returns FALSE.
+ */
+int
+HasDefaultTag PARAMS ((t),
+    Type *t)
+{
+    Tag *firstTag = NULL;
+    int dfltCode;
+    int dfltClass;
+
+    dfltClass = UNIV;
+    dfltCode = LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId);
+    if ((t->tags != NULL) && !LIST_EMPTY (t->tags))
+        firstTag = (Tag*)FIRST_LIST_ELMT (t->tags);
+
+    return ((firstTag != NULL) && (LIST_COUNT (t->tags) == 1) &&
+             (firstTag->tclass == dfltClass) && (firstTag->code == dfltCode)) ||
+            ((firstTag == NULL) && (dfltCode == NO_TAG_CODE));
+
+} /* HasDefaultTag */
+
+
+/*
+ * Returns TRUE if t is a primitive type or if it is
+ * defined by a reference to a primitive type
+ */
+int
+IsPrimitiveByDefOrRef PARAMS ((t),
+    Type *t)
+{
+    Type *definingType;
+
+    definingType = GetType (t);
+
+    if (definingType == NULL)
+        return FALSE; /* bad error handling */
+
+    return IsPrimitiveByDef (definingType);
+}  /* IsPrimitiveByDefOrRef */
+
+
+/*
+ * Returns TRUE if the given type is a primitive type. Does NOT
+ * follow type references - type refs are not considered primitive.
+ * The following types are considered primitive:
+ *  BOOLEAN
+ *  INTEGER
+ *  BITSTRING
+ *  OCTETSTRING
+ *  NULL
+ *  OID
+ *  REAL
+ *  ENUMERATED
+ */
+int
+IsPrimitiveByDef PARAMS ((t),
+    Type *t)
+{
+    switch (t->basicType->choiceId)
+    {
+        case BASICTYPE_LOCALTYPEREF:
+        case BASICTYPE_IMPORTTYPEREF:
+        case BASICTYPE_SEQUENCE:
+        case BASICTYPE_SET:
+        case BASICTYPE_CHOICE:
+        case BASICTYPE_SEQUENCEOF:
+        case BASICTYPE_SETOF:
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_ANYDEFINEDBY:
+        case BASICTYPE_ANY:
+            return FALSE;
+            break;
+
+
+        case BASICTYPE_SELECTION:
+            if (t->basicType->a.selection->link != NULL)
+            return IsPrimitiveByDef (t->basicType->a.selection->link->type);
+                   break;
+
+        case BASICTYPE_BOOLEAN:
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_BITSTRING:
+        case BASICTYPE_OCTETSTRING:
+        case BASICTYPE_NULL:
+        case BASICTYPE_OID:
+        case BASICTYPE_REAL:
+        case BASICTYPE_ENUMERATED:
+            return TRUE;
+            break;
+
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_MACROTYPE:
+        case BASICTYPE_MACRODEF:
+            return FALSE;
+            break;
+
+        default:
+            fprintf (stderr, "IsPrimitiveByDef: ERROR - unknown type id ?!");
+    }
+    return FALSE;
+}  /* IsPrimitiveByDef */
+
+
+/*
+ * Returns TRUE if the given type is a local type reference or an
+ * import type ref.
+ * e.g.
+ *
+ * Gumby ::= P1.ORName   --> isTypeRef returns TRUE P1.ORName
+ * Bar ::= INTEGER       --> isTypeRef returns FALSE for INTEGER
+ * Foo ::= Bar           --> isTypeRef returns TRUE for Bar
+ */
+int
+IsTypeRef PARAMS ((t),
+    Type *t)
+{
+    if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+        (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+        return TRUE;
+    else
+        return FALSE;
+}  /* IsTypeRef */
+
+
+
+/*
+ * Returns TRUE if the given type is defined
+ * by a library type such as OCTET STRING.
+ * Does NOT follow type refs - type refs return FALSE.
+ *
+ * NOTE - some possibly non-primitive types are defined by
+ *        library types (ANY, ANY DEFINED BY)
+ *
+ * types defined by type refs or structured defs
+ * cause FALSE to be returned. i.e.
+ *  Foo ::= Bar  -> FALSE for Bar
+ *  Bell ::= SEQUENCE { .. } -> False for SEQ...
+ *
+ * useful types are considered as type references and hence
+ * return FALSE.
+ */
+int
+IsDefinedByLibraryType PARAMS ((t),
+    Type *t)
+{
+    int retVal;
+
+    if (t == NULL)
+        retVal = FALSE;
+
+    else if (IsPrimitiveByDef (t))
+        retVal = TRUE;
+
+    /*
+     * check for non-primitive types that
+     * are defined by a library type
+     */
+    else
+        switch (t->basicType->choiceId)
+        {
+            case BASICTYPE_ANYDEFINEDBY:
+            case BASICTYPE_ANY:
+                retVal = TRUE;
+            break;
+
+           default:
+                retVal = FALSE;
+    }
+    return retVal;
+
+} /* IsDefinedByLibraryType*/
+
+
+/*
+ * Returns FALSE if type t is
+ *    a. a library type with default universal tags and no named elements
+ *       OR
+ *    b. a reference to a type with no extra tagging
+ *
+ * otherwise returns true, indicating that is is a new type derived
+ * by tagging or adding named elmts to another type.
+ *
+ * eg  INTEGER  --> FALSE   (same as lib type)
+ *     [APPLICATION 2] INTEGER --> TRUE (re-tagged lib type)
+ *     INTEGER { one (1), two (2) } --> TRUE (lib type with named elmts)
+ *     Bar2 --> FALSE (simple type ref)
+ */
+int
+IsNewType PARAMS ((t),
+    Type *t)
+{
+    /*
+     * Type = [re-tagging] DefiningType [namedelmts]
+     * identical: no retagging and no named elements
+     */
+    if (IsDefinedByLibraryType (t) && HasDefaultTag (t) && ! HasNamedElmts (t))
+        return FALSE;
+
+    else if (IsTypeRef (t) && ((t->tags == NULL) || (LIST_EMPTY (t->tags))))
+        return FALSE;
+
+    else
+        return TRUE;
+
+} /* IsNewType */
+
+
+/*
+ * Returns TRUE if elmts including curr list elmt
+ * onward are all optional otherwise returns FALSE.
+ * (note: this relies on the 'curr' ptr in the list)
+ * if the list is null or the curr elmt is null
+ * then returns TRUE
+ */
+int
+IsTailOptional PARAMS ((e),
+    NamedTypeList *e)
+{
+    NamedType *elmt;
+    void *tmp;
+    int retVal;
+
+    if (e == NULL)
+        return TRUE;
+
+    tmp = (void*)CURR_LIST_NODE (e);
+    if (tmp == NULL)
+        return TRUE;
+
+    retVal = TRUE;
+    FOR_REST_LIST_ELMT (elmt, e)
+    {
+        if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL))
+        {
+            retVal = FALSE;
+            break;
+        }
+    }
+    SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */
+    return retVal;
+} /* IsTailOptional */
+
+
+
+/*
+ * Returns TRUE if all elmts after but not including the curr list elmt
+ * are optional otherwise returns FALSE.
+ * (note: this relies on the 'curr' ptr in the list)
+ * if the list is null or the curr elmt is null
+ * then returns TRUE. if there are no elmts after the curr elmt
+ * returns TRUE.
+ */
+int
+NextIsTailOptional PARAMS ((e),
+    NamedTypeList *e)
+{
+    NamedType *elmt;
+    void *tmp;
+    void *tmp2;
+    int retVal;
+
+    if ((e == NULL) || (LIST_EMPTY (e)))
+        return TRUE;
+
+    tmp = (void*)CURR_LIST_NODE (e);
+    if (tmp == NULL)
+        return TRUE;
+
+    tmp2 = (void*)NEXT_LIST_NODE (e);
+    if (tmp2 == NULL)
+        return TRUE;
+
+    SET_CURR_LIST_NODE (e, tmp2);
+
+    retVal = TRUE;
+    FOR_REST_LIST_ELMT (elmt, e)
+    {
+        if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL))
+        {
+            retVal = FALSE;
+            break;
+        }
+    }
+    SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */
+    return retVal;
+} /* NextIsTailOptional */
+
+
+/*
+ * Returns TRUE if all elmts of the curr list are optional
+ * or have default values.  Useful with SET and SEQ elements.
+ */
+int
+AllElmtsOptional PARAMS ((e),
+    NamedTypeList *e)
+{
+    NamedType *elmt;
+    void *tmp;
+    int retVal;
+
+    if ((e == NULL) || LIST_EMPTY (e))
+        return TRUE;
+
+    tmp = (void*)CURR_LIST_NODE (e);
+    SET_CURR_LIST_NODE (e, FIRST_LIST_NODE (e));
+
+    retVal = TRUE;
+    FOR_REST_LIST_ELMT (elmt, e)
+    {
+        if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL))
+        {
+            retVal = FALSE;
+            break;
+        }
+    }
+    SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */
+    return retVal;
+} /* AllElmtsOptional */
+
+
+
+
+
+/*
+ * Follows single levely of type ref or library type and returns a
+ * handle to its AnyRefList.  Typically used in do_macros.c to
+ * add a hash key for the type that t is or refs.  Need to get
+ * to the type def of type t to give the AnyRefListHndl.
+ */
+AnyRefList**
+GetAnyRefListHndl PARAMS ((t),
+    Type *t)
+{
+    TypeDef *td;
+
+    if (IsDefinedByLibraryType (t))
+        return LIBTYPE_GET_ANY_REFS_HNDL (t->basicType->choiceId);
+    else
+    {
+        if (!IsTypeRef (t))
+            return NULL;
+        else
+        {
+            td = t->basicType->a.localTypeRef->link;
+            return &td->anyRefs;
+        }
+    }
+} /* GetAnyRefListHndl */
+
+
+/*
+ * Given a subtype list s (possibly empty *s == NULL) it tacks on
+ * the newSubtype in a appropriate fashion, possible chaning *s.
+ * Op can be SUBTYPE_AND or SUBTYPE_OR.
+ *
+ * e.g. Foo ::= INTEGER ((1..100) | 200)
+ *
+ * Add the subtypes by
+ *   AppendSubtype (&t->subtypes, (1..100), SUBTYPE_AND)
+ *   AppendSubtype (&t->subtypes, 200, SUBTYPE_OR)
+ *
+ * op is meaningless if s is empty
+ */
+void
+AppendSubtype PARAMS ((s, newSubtype, op),
+    Subtype **s _AND_
+    Subtype *newSubtype _AND_
+    enum SubtypeChoiceId op)
+{
+    void **tmpPtr;
+    Subtype *sPtr;
+
+    if (*s == NULL)
+        *s = newSubtype;
+
+    else if (op == SUBTYPE_AND)
+    {
+        if ((*s)->choiceId == SUBTYPE_AND)
+        {
+            tmpPtr = (void**)AsnListAppend ((*s)->a.and);
+            *tmpPtr = (void*)newSubtype;
+        }
+        else
+        {
+            sPtr = (Subtype*)Malloc (sizeof (Subtype));
+            sPtr->choiceId  = SUBTYPE_AND;
+            sPtr->a.and = NEWLIST();
+            tmpPtr = (void**)AsnListAppend (sPtr->a.and);
+            *tmpPtr = (void*)*s;
+            tmpPtr = (void**)AsnListAppend (sPtr->a.and);
+            *tmpPtr = (void*)newSubtype;
+            *s = sPtr;
+        }
+    }
+    else if (op == SUBTYPE_OR)
+    {
+        if ((*s)->choiceId == SUBTYPE_OR)
+        {
+            tmpPtr = (void**)AsnListAppend ((*s)->a.or);
+            *tmpPtr = (void*)newSubtype;
+        }
+        else
+        {
+            sPtr = (Subtype*)Malloc (sizeof (Subtype));
+            sPtr->choiceId  = SUBTYPE_OR;
+            sPtr->a.or = NEWLIST();
+            tmpPtr = (void**)AsnListAppend (sPtr->a.or);
+            *tmpPtr = (void*)*s;
+            tmpPtr = (void**)AsnListAppend (sPtr->a.or);
+            *tmpPtr = (void*)newSubtype;
+            *s = sPtr;
+        }
+    }
+    else
+        /* NOT not supported here */
+        fprintf (stderr,"AppendSubtype - unknown operation\n");
+
+}  /* AppendSubtype */
diff --git a/SecuritySNACCRuntime/compiler/core/snacc-util.h b/SecuritySNACCRuntime/compiler/core/snacc-util.h
new file mode 100644
index 00000000..fc7a98be
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/snacc-util.h
@@ -0,0 +1,139 @@
+/*
+ * compiler/core/snacc_util.h
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/snacc-util.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Log: snacc-util.h,v $
+ * Revision 1.1  2001/06/20 21:27:59  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:46  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:46:41  rj
+ * snacc_config.h's 2nd last macro, PrintErrLoc(), got here.
+ *
+ * Revision 1.1  1994/08/28  09:49:41  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#define PrintErrLoc( fileName, lineNo)\
+			fprintf (stderr, "file \"%s\", line %d: ", fileName, lineNo)
+
+/*
+ * macro to allocate room for str & null & put in give STR*
+ */
+#define SETUP_STR( strPtr, string)\
+    (strPtr)->str = Malloc (strlen (string) + 1);\
+    strcpy ((strPtr)->str, string);\
+    (strPtr)->len = strlen (string) + 1
+
+
+/*
+ * Create a new list type such that each elmt has space
+ * to hold a pointer
+ */
+#define NEWLIST()	AsnListNew (sizeof (void *))
+
+/*
+ *    macro to append an element to the end of linked list
+ *    - helps on left recursion when order must be maintained
+ *
+ *  be careful of calling context if list is null
+ *  that is, make sure the change to list is not lost.
+ */
+#define APPEND( elmt, list) \
+{\
+    void **tmpPtr;\
+    if ((list) == NULL)\
+        (list) = NEWLIST();\
+    tmpPtr = (void **) AsnListAppend ((AsnList *)list);\
+    *tmpPtr = (void *) (elmt);\
+}
+
+/*
+ * like APPEND except puts elmt at head of  list
+ */
+#define PREPEND( elmt, list) \
+{\
+    void **tmpPtr;\
+    if ((list) == NULL)\
+        (list) = NEWLIST();\
+    tmpPtr = (void **)AsnListPrepend ((AsnList *)list);\
+    *tmpPtr = (void *) (elmt);\
+}
+
+void SetupType PROTO ((Type **t, enum BasicTypeChoiceId typeId, unsigned long lineNum));
+
+void SetupMacroType PROTO ((Type **t, enum MacroTypeChoiceId macroTypeId, unsigned long lineNum));
+
+void SetupValue PROTO ((Value **v, enum BasicValueChoiceId valId, unsigned long lineNum));
+
+
+void AddPrivateImportElmt PROTO ((Module *m, char *name, char *refModuleName, long int lineNo));
+
+ImportElmt *LookupImportElmtInModule PROTO ((Module *m, char *name, ImportModule **importModule));
+
+ImportElmt *LookupImportElmtInImportElmtList PROTO ((ImportElmtList *importElmtList, char *name));
+
+ImportModule *LookupImportModule PROTO ((Module *m, char *importModuleName));
+
+TypeDef *LookupType PROTO ((TypeDefList *t, char *typeName));
+
+Module *LookupModule PROTO ((ModuleList *m, char *modName, OID *oid));
+
+NamedType *LookupFieldInType PROTO ((Type *t, char *fieldName));
+
+Type *GetType PROTO ((Type *t));
+
+Type *ParanoidGetType PROTO ((Type *t));
+
+enum BasicTypeChoiceId GetBuiltinType PROTO ((Type *t));
+
+NamedNumberList *GetNamedElmts PROTO ((Type *t));
+
+NamedNumberList *GetAllNamedElmts PROTO ((Type *t));
+
+Type *GetParent PROTO ((Type *ancestor, Type *child));
+
+ValueDef *LookupValue PROTO ((ValueDefList *v, char *valueName));
+
+Value *GetValue PROTO ((Value *v));
+
+int CompareOids PROTO ((OID *oid1, OID *oid2));
+
+int HasNamedElmts PROTO ((Type *t));
+
+int TagsAreIdentical PROTO ((TagList *t1, TagList *t2));
+
+int HasDefaultTag PROTO ((Type *t));
+
+int IsPrimitiveByDefOrRef PROTO ((Type *t));
+
+int IsPrimitiveByDef PROTO ((Type *t));
+
+int IsDefinedByLibraryType PROTO ((Type *t));
+
+int IsTypeRef PROTO ((Type *t));
+
+int IsNewType PROTO ((Type *t));
+
+int IsTailOptional PROTO ((NamedTypeList *e));
+
+int NextIsTailOptional PROTO ((NamedTypeList *e));
+
+int AllElmtsOptional PROTO ((NamedTypeList *e));
+
+AnyRefList **GetAnyRefListHndl PROTO ((Type *t));
+
+void AppendSubtype PROTO ((Subtype **s, Subtype *newSubtype, enum SubtypeChoiceId op));
diff --git a/SecuritySNACCRuntime/compiler/core/snacc.c b/SecuritySNACCRuntime/compiler/core/snacc.c
new file mode 100644
index 00000000..f750c6d2
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/snacc.c
@@ -0,0 +1,1361 @@
+/*
+ * compiler/core/snacc.c---Compiles ASN.1 src files into an internal type tree.
+ *        Imported type/value references are resolved if possible.
+ *        Produces C or C++ encoder/decoder/print/free code and .h for
+ *        data struct and prototypes.
+ *        Generated C can be either ANSI or old style via macros.
+ *        Produces values for OBJECT IDENTIFIERs, INTEGERs and BOOLEANs
+ *
+ * Mike Sample 1991/92
+ *
+ * NOTES
+ *
+ *  See the README file for compiling tips.  This should compile
+ *  with ANSI or non-ANSI c compilers.
+ *
+ *  each ASN.1 source file must contain a complete ASN.1 module:
+ *       <ModName> DEFINITIONS ::= BEGIN ... END
+ *
+ * 91/09/04---modified to handle new data struct (ASN.1 generated)
+ *            for module info. MS.
+ *
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program and the associated libraries are distributed in the hope
+ * that they will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License and GNU Library General
+ * Public License for more details.
+ *
+ * INSERT_VDA_COMMENTS
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/snacc.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Log: snacc.c,v $
+ * Revision 1.1  2001/06/20 21:27:59  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:52  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.10  1997/05/07 15:18:35  wan
+ * Added (limited) size constraints, bitstring and enumeration names to tables
+ *
+ * Revision 1.9  1997/02/16 15:12:21  rj
+ * made ``return *this after calling abort()'' a compile time option.
+ *
+ * Revision 1.8  1997/01/02 08:50:55  rj
+ * - use the TIME_WITH_SYS_TIME flag (checked and generated by configure)
+ * - do not silently ignore the -tcl option if not compiled for tcl code generation
+ *
+ * Revision 1.7  1995/09/07  19:13:39  rj
+ * new options -mA and -mC for snacc(1) that switch the names used between those defined in the ASN.1 files and those used in the generated C++ code.
+ * uses newly introduced enum MetaNameStyle.
+ *
+ * Revision 1.6  1995/08/17  15:00:13  rj
+ * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted)
+ *
+ * Revision 1.5  1995/07/25  19:34:06  rj
+ * bug report address changed to protect an innocent's mailbox :-)
+ *
+ * snacc -h now prints the usage to stdout.
+ *
+ * allow for more than one PDU per .asn1 file set:
+ * - struct TclPDU becomes a linked list.
+ * - it gets a flag `used' to detect invalid command line arguments.
+ *
+ * code for idl backend added.
+ *
+ * by default, snacc now derives output file names from the .asn1 input file name instead of the module name.
+ *
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.4  1994/12/11  20:21:06  rj
+ * #include string(s).h
+ *
+ * Revision 1.3  1994/10/08  03:23:27  rj
+ * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long.
+ *
+ * code for meta structures added (provides information about the generated code itself).
+ *
+ * code for Tcl interface added (makes use of the above mentioned meta code).
+ *
+ * Revision 1.2  1994/09/01  00:44:31  rj
+ * snacc_config.h and other superfluous .h files removed. version string moved into a separate version.h file.
+ *
+ * Revision 1.1  1994/08/28  09:49:37  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+#ifdef VDADER_RULES
+/* Enables VDA's DER SUPPORT.  If gVDADER_RULES == 1 then support is on,
+ * other wise it is off.  Define _gVDADER_RULES so snacc.h does not 
+ * redefine the global gVDADER_RULES with it's extern (avoids a compile
+ * time warning).
+ ** COMPILER EXECUTION FLAGS: "-D -C -u ../../../snaccVC/asn-useful.asn1 
+               sm_vdatypes.asn sm_x501ud.asn  sm_x411ub.asn sm_x411mtsas.asn 
+               sm_x501if.asn  sm_x520sa.asn sm_x509cmn.asn sm_x509af.asn 
+               sm_x509ce.asn sm_cms.asn sm_ess.asn  tst_email.asn 
+               tst_email2.asn"
+               -D -C -u ../../../snaccVC/asn-useful.asn1 sm_vdatypes.asn sm_x501ud.asn  sm_x411ub.asn sm_x411mtsas.asn sm_x501if.asn  sm_x520sa.asn sm_x509cmn.asn sm_x509af.asn sm_x509ce.asn sm_cms.asn sm_ess.asn  tst_email.asn tst_email2.asn
+ */
+#define _gVDADER_RULES 
+int gVDADER_RULES=0;
+#endif
+
+#include "snacc.h"
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#if STDC_HEADERS || HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "version.h"
+#include "mem.h"
+#include "asn1module.h"
+#include "exports.h"
+#include "parser.h"          /* for parser (ech!) globals */
+#include "dependency.h"
+#include "link-types.h"
+#include "link-values.h"
+#include "err-chk.h"
+#include "print.h"
+#include "recursive.h"
+#include "define.h"
+#include "normalize.h"
+#include "do-macros.h"
+#include "snacc-util.h"
+#if META
+#include "meta.h"
+#endif
+
+#include "str-util.h"
+
+#include "c-gen/rules.h"       /* for c file generation */
+#include "c-gen/type-info.h"
+#include "c-gen/gen-code.h"
+
+#include "c++-gen/rules.h"       /* for c++ file generation */
+#include "c++-gen/types.h"
+#include "c++-gen/gen-code.h"
+
+#include "gen-tbls.h"  /* for type table generation */
+
+#if IDL
+#include "idl-gen/rules.h"
+#include "idl-gen/types.h"
+#include "idl-gen/gen-code.h"
+#endif
+
+
+/* prototypes for this file's routines */
+
+Module *ParseAsn1File PROTO ((char *fileName));
+
+void GenCCode PROTO ((ModuleList *allMods, long int longJmpVal, int genTypes, int genEncoders, int genDecoders, int genPrinters, int genValues, int genFree));
+
+void GenCxxCode PROTO ((ModuleList *allMods, long int longJmpVal, int genTypes, int genEncoders, int genDecoders, int genPrinters, int genValues, int genFree, if_META (MetaNameStyle genMeta COMMA MetaPDU *meta_pdus COMMA) if_TCL (int genTcl COMMA) int novolatilefuncs));
+
+void GenIDLCode PROTO ((ModuleList *allMods, long int longJmpVal, int genTypes, int genPrinters, int genValues, int genFree));
+
+int ModNamesUnique PROTO ((ModuleList *m));
+
+Module		*usefulTypeModG = NULL;
+static char	versionG[] = VERSION;
+static char	releasedateG[] = RELDATE;
+static char	bugreportaddressG[] = BUGREPADDR;
+int		maxFileNameLenG = -1; /* values > 2 are considered valid */
+                          /* this is used in back_ends/c_gen/str_util.c */
+
+void
+Usage PARAMS ((prgName, fp),
+    char	*prgName _AND_
+    FILE	*fp)
+{
+    fprintf (fp, "\nUsage: %s ", prgName);
+    fprintf (fp, "[-h] [-P] [-t] [-v] [-e] [-d] [-p] [-f]\n");
+#if IDL
+    fprintf (fp, "            [-c | -C | -[T|O] <table output file> | -idl ]\n");
+#else
+    fprintf (fp, "            [-c | -C | -[T|O] <table output file>]\n");
+#endif
+    fprintf (fp, "            [-u <useful types ASN.1 file>]\n");
+    fprintf (fp, "            [-mm] [-mf <max file name length>]\n");
+    fprintf (fp, "            [-l <neg number>]\n");
+#if META
+    fprintf (fp, "            [-meta <type list>] [-mA | -mC]\n");
+#if TCL
+    fprintf (fp, "            [-tcl <type list>]\n");
+#endif
+#endif
+    fprintf (fp, "            <ASN.1 file list>\n\n");
+    fprintf (fp, "  -h   prints this msg\n");
+    fprintf (fp, "  -c   generate C encoders and decoders (default)\n");
+    fprintf (fp, "  -C   generate C++ encoders and decoders\n");
+    fprintf (fp, "  -novolat   for broken C++ compilers: return *this after calling abort()\n");
+    fprintf (fp, "  -T <filename> write a type table file for the ASN.1 modules to file filename\n");
+    fprintf (fp, "  -O <filename> writes the type table file in the original (<1.3b2) format\n");
+#if IDL
+    fprintf (fp, "  -idl generate CORBA IDL\n");
+#endif
+    fprintf (fp, "  -u <filename> specifies the ASN.1 file with definition of the useful types\n");
+    fprintf (fp, "       (i.e. PrintableString). See the useful.asn1 file (in the\n");
+    fprintf (fp, "       snacc/asn1specs/ directory).\n");
+    fprintf (fp, "  -P   print the parsed ASN.1 modules to stdout from their parse trees\n");
+    fprintf (fp, "       (helpful debugging)\n");
+    fprintf (fp, "  -t   generate type definitions\n");
+    fprintf (fp, "  -v   generate value definitions (limited)\n");
+    fprintf (fp, "  -e   generate encode routines\n");
+    fprintf (fp, "  -d   generate decode routines\n");
+    fprintf (fp, "  -p   generate print routines\n");
+    fprintf (fp, "  -f   generate hierarchical free routines (C only)\n");
+    fprintf (fp, "      note: if none of -t -v -e -d -p -f are given, all are generated.\n");
+    fprintf (fp, "      These do not affect type tables.\n");
+
+
+    fprintf (fp, "  -mm  mangle output file name into module name (by default, the output file\n");
+    fprintf (fp, "       inherits the input file's name, with only the suffix replaced)\n");
+    fprintf (fp, "  -mf <num> num is maximum file name length for the generated source files\n");
+
+    fprintf (fp, "  -l <neg num> where to start error longjmp values decending from (obscure).\n");
+
+#if META
+    fprintf (fp, "  -meta <type list> generate meta code that describes the generated types. Implies -C.\n");
+    fprintf (fp, "  -mA  metacode: use names as defined in the ASN.1 files.\n");
+    fprintf (fp, "  -mC  metacode: use names as used in the generated C++ files.\n");
+#if TCL
+    fprintf (fp, "  -tcl <type list> generate code for a Tcl interpreter. Implies -meta.\n");
+#endif
+    fprintf (fp, "    <type list> has the following syntax: <module>.<type>[,<module>.<type>[...]]\n");
+    fprintf (fp, "    the types listed are the top level PDUs.\n");
+#endif
+
+    fprintf (fp, "\nUse `-' as the ASN.1 source file name to parse stdin.\n\n");
+
+
+    fprintf (fp, "This ASN.1 compiler produces C or C++ BER encoders and decoders or type tables.\n");
+
+    fprintf (fp, "\nVersion %s, %s.\n", versionG, releasedateG);
+#if 0
+    fprintf (fp, "Please send bug reports and comments to %s.\n\n", bugreportaddressG);
+#else
+    fprintf (fp, "Please see %s for new versions and where to send bug reports and comments.\n\n", bugreportaddressG);
+#endif
+
+    fprintf (fp, "Copyright (C) 1993 Michael Sample and UBC\n");
+    fprintf (fp, "Copyright (C) 1994, 1995 by Robert Joop and GMD FOKUS\n\n");
+
+    fprintf (fp, "This program is free software; you can redistribute it and/or modify\n");
+    fprintf (fp, "it under the terms of the GNU General Public License as published by\n");
+    fprintf (fp, "the Free Software Foundation; either version 2 of the License, or\n");
+    fprintf (fp, "(at your option) any later version.\n\n");
+
+    fprintf (fp, "This program is distributed in the hope that it will be useful,\n");
+    fprintf (fp, "but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
+    fprintf (fp, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
+    fprintf (fp, "GNU General Public License for more details.\n\n");
+
+/*
+    fprintf (fp, "You should have received a copy of the GNU General Public License\n");
+    fprintf (fp, "along with this program; if not, write to the Free Software\n");
+    fprintf (fp, "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n");
+*/
+}
+
+
+typedef struct
+{
+    char      *fileName;
+} SRC_FILE;
+
+
+#if META
+static MetaPDU *parse_type_list (arg)
+    char *arg;
+{
+    MetaPDU *meta_pdus = NULL;
+    char *module;
+    for (module = strtok (arg, ".:"); module; module = strtok (NULL, ".:"))
+    {
+      MetaPDU *pdu = MT (MetaPDU);
+      char *type = strtok (NULL, " /,;");
+      if (!type)
+      {
+	  fprintf (stderr, "usage: {-meta|-tcl} module.type[,module.type[...]]\n");
+	  exit (1);
+      }
+      pdu->module = module;
+      pdu->type = type;
+      pdu->used = FALSE;
+
+      pdu->next = meta_pdus;
+      meta_pdus = pdu;
+    }
+    return meta_pdus;
+}
+#endif
+
+int main PARAMS ((argc, argv),
+    int			argc _AND_
+    char		**argv)
+{
+    int			i, j, semErr;
+    int			retVal;
+    int			fd;
+    SRC_FILE		*srcList;
+    int			numSrcFiles;
+    ModuleList		*allMods;
+    Module		*currMod;
+    Module		**tmpModHndl;
+    int			currArg;
+    int			argsProcessed;
+    char		*usefulTypeModFileName;
+    FILE		*fPtr;
+    int			printModuleFlag = FALSE;  /* default: Don't print */
+    int			genTypeTbls = 0; /* default: Don't gen tbls */
+    char		*tblFileName;
+    int			genTypeCode = FALSE;
+    int			genEncodeCode = FALSE;
+    int			genDecodeCode = FALSE;
+    int			genPrintCode = FALSE;
+    int			genValueCode = FALSE;
+    int			genFreeCode = FALSE;
+#if META
+    MetaNameStyle	genMetaCode = META_off;
+    MetaPDU		*meta_pdus = NULL;
+#if TCL
+    int			genTclCode = FALSE;
+#endif
+#endif
+    int			genCCode = FALSE;        /* defaults to C if neither specified */
+    int			genCxxCode = FALSE;
+#if IDL
+    int			genIDLCode = FALSE;
+#endif
+    long		longJmpVal = -100;
+    int			novolatilefuncs = FALSE;
+
+#ifdef YYDEBUG
+    /* prints yacc debugging info to stdout */
+    yydebug = 1;
+#endif
+
+
+    if (argc <= 1)
+    {
+        Usage (argv[0], stderr);
+        exit (1);
+    }
+
+    srcList = (SRC_FILE*) Malloc ((argc -1) * sizeof (SRC_FILE));
+
+
+    /*
+     * parse cmd line args
+     */
+    numSrcFiles = 0;
+    usefulTypeModFileName = NULL;
+    for (currArg = 1; (currArg < argc); )
+    {
+        if ((argv[currArg][0] == '-') && (argv[currArg][1] != '\0'))
+            switch (argv[currArg][1])
+            {
+#ifdef VDADER_RULES
+                case 'D':
+                   gVDADER_RULES=1;
+                   currArg++;
+                   break;
+#endif
+                case 'h':
+                    Usage (argv[0], stdout);
+                    exit (1);
+                break;
+
+                case 'P':
+                    printModuleFlag = TRUE;
+                    currArg++;
+                break;
+
+                case 'v':
+                    genValueCode = TRUE;
+                    currArg++;
+                break;
+
+#if IDL
+                case 'i':
+		    if (!strcmp (argv[currArg]+1, "idl"))
+		    {
+			genIDLCode = TRUE;
+			currArg++;
+		    }
+		    else
+			goto error;
+                break;
+#endif
+
+                case 't':
+		    if (!strcmp (argv[currArg]+1, "tcl"))
+		    {
+#if TCL
+			meta_pdus = parse_type_list (argv[++currArg]);
+			genTclCode = TRUE;
+			if (!genMetaCode)
+			  genMetaCode = META_backend_names;
+			genCxxCode = TRUE;
+#else
+			goto error;
+#endif
+		    }
+		    else
+		      genTypeCode = TRUE;
+                    currArg++;
+                break;
+
+                case 'e':
+                    genEncodeCode = TRUE;
+                    currArg++;
+                break;
+
+                case 'd':
+                    genDecodeCode = TRUE;
+                    currArg++;
+                break;
+
+                case 'p':
+                    genPrintCode = TRUE;
+                    currArg++;
+                break;
+
+                case 'f':
+                    genFreeCode = TRUE;
+                    currArg++;
+                break;
+
+                case 'C':
+                    genCxxCode = TRUE;
+                    currArg++;
+                break;
+
+                case 'n':
+		    if (!strcmp (argv[currArg]+1, "novolat"))
+		    {
+			novolatilefuncs = TRUE;
+			currArg++;
+		    }
+		    else
+			goto error;
+                break;
+
+                case 'c':
+                    genCCode = TRUE;
+                    currArg++;
+                break;
+
+                case 'u':
+                    if (argv[currArg][2] != '\0')  /* no space after -u */
+                    {
+                        usefulTypeModFileName = &argv[currArg][2];
+                        currArg++;
+                    }
+                    else
+                    {
+                        usefulTypeModFileName = argv[currArg+1];
+                        currArg += 2;
+                    }
+                break;
+
+                case 'l':
+                    if (argv[currArg][2] != '\0')  /* no space after -l */
+                    {
+                        longJmpVal = atoi (&argv[currArg][2]);
+                        currArg++;
+                    }
+                    else
+                    {
+                        longJmpVal = atoi (argv[currArg+1]);
+                        currArg += 2;
+                    }
+                break;
+
+                case 'T':
+                case 'O':
+                    genTypeTbls = argv[currArg][1]=='T'?2:1;
+                    if (argv[currArg][2] != '\0')  /* no space after -T */
+                    {
+                        tblFileName = &argv[currArg][2];
+                        currArg++;
+                    }
+                    else
+                    {
+                        tblFileName = argv[currArg+1];
+                        currArg += 2;
+                    }
+                break;
+
+
+                case 'm':
+                    if (argv[currArg][2] == 'f')
+                    {
+                        if (argv[currArg][3] != '\0')  /* no space after -mf */
+                        {
+                            maxFileNameLenG = atoi (&argv[currArg][3]);
+                            currArg++;
+                        }
+                        else
+                        {
+                            maxFileNameLenG = atoi (argv[currArg+1]);
+                            currArg += 2;
+                        }
+                        break;
+                    }
+#if META
+		    else if (!strcmp (argv[currArg]+1, "meta"))
+		    {
+			meta_pdus = parse_type_list (argv[++currArg]);
+			if (!genMetaCode)
+			  genMetaCode = META_backend_names;
+			genCxxCode = TRUE;
+			currArg++;
+			break;
+		    }
+		    else if (!strcmp (argv[currArg]+1, "mA"))
+		    {
+			genMetaCode = META_asn1_names;
+			genCxxCode = TRUE;
+			currArg++;
+			break;
+		    }
+		    else if (!strcmp (argv[currArg]+1, "mC"))
+		    {
+			genMetaCode = META_backend_names;
+			genCxxCode = TRUE;
+			currArg++;
+			break;
+		    }
+#endif
+                    else if (argv[currArg][2] == 'm')
+                    {
+			keepbaseG = FALSE;
+			currArg++;
+                        break;
+                    }
+
+		    /* else fall through to default error */
+
+error:
+                default:
+                    fprintf (stderr, "%s: ERROR---unknown cmd line option `%s'\n\n", argv[0], argv[currArg]);
+                    Usage (argv[0], stderr);
+                    exit (1);
+            }
+
+        else /* asn1srcFileName */
+            srcList[numSrcFiles++].fileName = argv[currArg++];
+
+    }
+
+
+    if (numSrcFiles == 0)
+    {
+        fprintf (stderr, "%s: ERROR---no ASN.1 source files were specified\n", argv[0]);
+        Usage (argv[0], stderr);
+        exit (1);
+    }
+
+
+    /*
+     * set default options
+     */
+    if (!(genTypeCode || genValueCode || genEncodeCode || genDecodeCode ||
+          genFreeCode || genPrintCode))
+    {
+        genTypeCode = TRUE;
+        genValueCode = TRUE;
+        genEncodeCode = TRUE;
+        genDecodeCode = TRUE;
+        genFreeCode = TRUE;
+        genPrintCode = TRUE;
+    }
+
+    else if (genCCode + genCxxCode + genTypeTbls
+#if IDL
+						  + genIDLCode
+#endif
+								> 1)
+    {
+        fprintf (stderr, "%s: ERROR---Choose only one of the -c -C or -T options\n", argv[0]);
+        Usage (argv[0], stderr);
+        exit (1);
+    }
+
+    if (!genCCode && !genCxxCode && !genTypeTbls
+#if IDL
+						 && !genIDLCode
+#endif
+								)
+        genCCode = TRUE;  /* default to C if neither specified */
+
+
+    /*
+     * STEP 1
+     * parse 'useful' type module for linking purposes only (if given)
+     * the useful type encode, decode, print, free routines are
+     * already in the runtime library.
+     */
+    if (usefulTypeModFileName != NULL)
+    {
+        usefulTypeModG = ParseAsn1File (usefulTypeModFileName);
+
+        if (usefulTypeModG == NULL)
+            exit (1);
+    }
+    else
+    {
+        fprintf (stderr, "  Hmmm, you didn't specify a useful types ASN.1 file with the `-u' option.\n");
+        fprintf (stderr, "  I'll continue assuming your ASN.1 file(s) don't need any useful types.\n");
+    }
+
+
+    /*
+     * STEP 2---parse each ASN.1 src file
+     */
+    allMods = (ModuleList *)AsnListNew (sizeof (void*));
+    for (i = 0; i < numSrcFiles; i++)
+    {
+        currMod = ParseAsn1File (srcList[i].fileName);
+
+        if (currMod == NULL)
+            exit (1);
+
+        /*
+         * insert this module at the head of the list
+         * of already parsed (if any) modules
+         */
+        tmpModHndl = (Module **)AsnListAppend (allMods);
+        *tmpModHndl = currMod;
+
+    }  /* end per src file for loop */
+
+
+    /*
+     * Check that the module names/oids are unique.
+     */
+    if (!ModNamesUnique (allMods))
+    {
+        fprintf (stderr, "Conflicting module names, cannot proceed.\n");
+        exit (1);
+    }
+
+
+
+    /*
+     * STEP 3
+     * Now that all files have been parsed,
+     * link local and locatable import type refs
+     */
+    if (LinkTypeRefs (allMods) < 0)
+    {
+        fprintf (stderr, "Type linking errors---cannot proceed\n");
+        exit (1);
+    }
+
+
+
+    /*
+     * STEP 4
+     * Parse constructed values now that types are all parsed
+     * and have been linked.  Need type info to be able to
+     * parse values easily (elimitate ambiguity).
+     */
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        if (ParseValues (allMods, currMod) != 0)
+            fprintf (stderr, "WARNING: Value parsing error (s), attempting to continue\n");
+    }
+
+
+    /*
+     * STEP 5
+     * Value parsing may have defined some new values
+     * so can link local and locatable import value refs now.
+     */
+    if (LinkValueRefs (allMods) < 0)
+    {
+        fprintf (stderr, "Value linking errors---cannot proceed\n");
+        exit (1);
+    }
+
+
+
+    /*
+     * STEP 6
+     * process macros
+     *   - adding type/value defs as nec
+     *   - mark type defs with ANY DEFINED BY id if nec
+     *     so they are put in the id to ANY type hash tbl.
+     */
+    semErr = 0;
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        ProcessMacros (currMod);
+        if (currMod->status == MOD_ERROR)
+            semErr = 1;
+    }
+    if (semErr)
+        exit (1);
+
+    /*
+     * STEP 7
+     * convert silly type constructs into
+     * a normal format, leaving behind pure type/value info
+     * eg: expand COMPONENTS OF refs, SELECTION types.
+     * boil down values into simplest rep. (eg OID -> ENC_OID)
+     */
+    semErr = 0;
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        NormalizeModule (currMod);
+        if (currMod->status == MOD_ERROR)
+            semErr = 1;
+    }
+    if (semErr)
+        exit (1);
+
+
+    /*
+     * STEP 8
+     * Mark recusive types.  Currently the recursive information is
+     * not used elsewhere.
+     */
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        MarkRecursiveTypes (currMod);
+    }
+
+
+    /*
+     * STEP 9
+     * Check for errors in the ASN.1 modules.
+     * Check all modules and exit if errors were found
+     */
+    semErr = 0;
+    if (usefulTypeModG != NULL)
+    {
+        ErrChkModule (usefulTypeModG);
+        if (usefulTypeModG->status == MOD_ERROR)
+            semErr = 1;
+    }
+
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        ErrChkModule (currMod);
+        if (currMod->status == MOD_ERROR)
+            semErr = 1;
+    }
+
+
+    if (semErr)
+        exit (1);
+
+
+
+
+    /*
+     *  exit if any sundry errors occurred at any point.
+     *  smallErrG is set upon finding small errors that prevent code
+     *  production but should not affect the other processing/error
+     *  checking steps.  This allows full display of errors.
+     */
+    if (smallErrG)
+    {
+        /*
+         * for debugging show "parsed" version of ASN.1 module if
+         * the print flag is set.
+         * Dumps each module to stdout. Printed from Module data struct
+         * print here before exiting otherwise print after sorting
+         */
+        if (printModuleFlag)
+        {
+            FOR_EACH_LIST_ELMT (currMod, allMods)
+            {
+                printf ("\n\n");
+                PrintModule (stdout, currMod);
+            }
+        }
+
+        exit (1);
+    }
+
+    /*
+     * STEP 10
+     * Make C/C++ typenames/routine names for enc/decode.
+     * Type/Value renaming will occur if name conflicts
+     * arise between modules.
+     *
+     * NOTE: this is done before sorting the types because
+     *       the type sorting routine may use the 'isPtr'
+     *       information to help order knots of recursive types.
+     */
+    if (genCCode)
+        FillCTypeInfo (&cRulesG, allMods);
+
+    else if (genCxxCode)
+        FillCxxTypeInfo (&cxxRulesG, allMods);
+
+#if IDL
+    else if (genIDLCode)
+        FillIDLTypeInfo (&idlRulesG, allMods);
+#endif
+
+
+    /*
+     * STEP 11
+     * Sort each typedef list such that independent types are
+     * before the types that depend on them
+     *
+     *  modules remain in same order as given on command line
+     *  (cmd line file order should be
+     *      least dependent module-> most dependent module
+     *      so that include file order in generated src is correct)
+     *  (useful.asn1 is always considered 'first' if given)
+     */
+    SortAllDependencies (allMods);
+
+    /*
+     * for debugging show "parsed" version of ASN.1 module.
+     * dumps each module to stdout. Printed from Module data struct
+     * Shows the results of normalization and sorting.
+     */
+    if (printModuleFlag)
+    {
+        FOR_EACH_LIST_ELMT (currMod, allMods)
+        {
+            printf ("\n\n");
+            PrintModule (stdout, currMod);
+        }
+    }
+
+    /*
+     * Step 12
+     * Final Step: Code/Type Table generation
+     */
+    if (genCCode)
+        GenCCode (allMods, longJmpVal, genTypeCode, genValueCode, genEncodeCode, genDecodeCode, genPrintCode, genFreeCode);
+
+    else if (genCxxCode)
+        GenCxxCode (allMods, longJmpVal, genTypeCode, genValueCode, genEncodeCode, genDecodeCode, genPrintCode, genFreeCode, if_META (genMetaCode COMMA meta_pdus COMMA) if_TCL (genTclCode COMMA) novolatilefuncs);
+
+    else if (genTypeTbls)
+        GenTypeTbls (allMods, tblFileName, genTypeTbls);
+
+#if IDL
+    else if (genIDLCode)
+        GenIDLCode (allMods, longJmpVal, genTypeCode, genValueCode, genPrintCode, genFreeCode);
+#endif
+
+    return 0; /* keep make happy */
+
+} /* end main */
+
+
+
+/*
+ * Calls the yacc/lex parser given a the ASN.1 src file's filename.
+ * Returns a Module *for the given ASN.1 module. If the filename is
+ * "-" stdin is used.
+ */
+Module *
+ParseAsn1File PARAMS ((fileName),
+    char *fileName)
+{
+    FILE *fPtr;
+    Module *retVal;
+    int parseResult;
+
+    /*
+     *  Open input file for lexical analyzer/parser
+     *  Use stdin if the filename is "-"
+     */
+    if (strcmp (fileName, "-") == 0)
+      if (keepbaseG)
+      {
+	fprintf (stderr, "ERROR---asn1 src file `%s' cannot be processed without output filename mangling\n", fileName);
+	return NULL;
+      }
+      else
+        fPtr = stdin;
+    else
+        fPtr = fopen (fileName, "r");
+
+    if (fPtr == NULL)
+    {
+        fprintf (stderr, "ERROR---asn1 src file `%s' cannot be opened for reading\n", fileName);
+        return NULL;
+    }
+
+    retVal = (Module *)Malloc (sizeof (Module));
+
+    /*
+     * Init Parser by giving it a ptr to the Module data struct
+     * to initialize/use, and the file name associtated with
+     * the given FILE *, fPtr (for error reporting).
+     * fPtr should be an opened FILE *to an ASN.1 source FILE
+     */
+    InitAsn1Parser (retVal, fileName, fPtr);
+
+
+    /*
+     * parse the current asn1 src file into the
+     * Module data struct
+     */
+    parseResult = yyparse();
+
+    if (parseResult != 0 || retVal->status == MOD_ERROR)
+    {
+        /* parser will print exact err msg */
+        fprintf (stderr, "Parsing errors---cannot proceed\n");
+        return NULL;
+    }
+
+    if (fPtr != stdin)
+        fclose (fPtr);
+
+    return retVal;
+
+}  /* ParseAsn1File */
+
+
+/*
+ * Given the list of parsed, linked, normalized, error-checked and sorted
+ * modules, and some code generation flags, generates C code and
+ * writes it to files derived from each modules name.  Each module
+ * gets 2 source files, one .h for data struct and prototypes, the other .c
+ * for the enc/dec/print/free routine code.
+ */
+void
+GenCCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genEncoders, genDecoders, genPrinters, genFree),
+    ModuleList *allMods _AND_
+    long int longJmpVal _AND_
+    int genTypes _AND_
+    int genValues _AND_
+    int genEncoders _AND_
+    int genDecoders _AND_
+    int genPrinters _AND_
+    int genFree)
+{
+    Module *currMod;
+    char *modBaseFileName;
+    FILE *cHdrFilePtr;
+    FILE *cSrcFilePtr;
+    DefinedObj *fNames;
+    int fNameConflict = FALSE;
+
+    /*
+     * Make names for each module's encoder/decoder src and hdr files
+     * so import references can be made via include files.
+     * If file names conflict, print error msg & exit.
+     */
+    fNames = NewObjList();
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        modBaseFileName = MakeBaseFileName (keepbaseG
+		? currMod->asn1SrcFileName
+		: currMod->modId->name); /* shorten module name if necessary (SYSV etc) */
+        currMod->cHdrFileName = MakeCHdrFileName (modBaseFileName);
+        currMod->cSrcFileName = MakeCSrcFileName (modBaseFileName);
+
+        if (ObjIsDefined (fNames, currMod->cHdrFileName, StrObjCmp) ||
+            ObjIsDefined (fNames, currMod->cSrcFileName, StrObjCmp))
+        {
+            fprintf (stderr, "Ack! ERROR---file name conflict for generated source files with names `%s' and `%s'.\n\n", currMod->cHdrFileName, currMod->cSrcFileName);
+            fprintf (stderr, "This usually means the max file name length is truncating the file names.\n");
+            fprintf (stderr, "Try re-naming the modules with shorter names or increasing the argument to -mf option (if you are using it).\n");
+            fprintf (stderr, "This error can also be caused by 2 modules with the same names but different OBJECT IDENTIFIERs.");
+            fprintf (stderr, "  Try renaming the modules to correct this.\n");
+            fNameConflict = TRUE;
+        }
+        else
+        {
+            DefineObj (&fNames, currMod->cHdrFileName);
+            DefineObj (&fNames, currMod->cSrcFileName);
+        }
+        Free (modBaseFileName);
+    }
+    if (fNameConflict)
+        exit (1);
+
+    FreeDefinedObjs (&fNames);
+    /*
+     * make c files
+     */
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        cHdrFilePtr = fopen (currMod->cHdrFileName, "w");
+        cSrcFilePtr = fopen (currMod->cSrcFileName, "w");
+        if ((cSrcFilePtr == NULL) || (cHdrFilePtr == NULL))
+            perror ("fopen");
+        else
+        {
+            PrintCCode (cSrcFilePtr, cHdrFilePtr, allMods, currMod, &cRulesG, longJmpVal, genTypes,  genValues, genEncoders, genDecoders, genPrinters, genFree);
+
+            fclose (cHdrFilePtr);
+            fclose (cSrcFilePtr);
+        }
+    }
+
+}  /* GenCCode */
+
+
+/*
+ * Given the list of parsed, linked, normalized, error-checked and sorted
+ * modules, and some code generation flags, generates C++ code and
+ * writes it to files derived from each modules name.  Each module
+ * gets 2 source files, one .h for data struct and prototypes, the other .C
+ * for the enc/dec/print/free routine code.
+ */
+void
+GenCxxCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genEncoders, genDecoders, genPrinters, genFree, if_META (genMeta COMMA meta_pdus COMMA) if_TCL (genTcl COMMA) novolatilefuncs),
+    ModuleList *allMods _AND_
+    long int longJmpVal _AND_
+    int genTypes _AND_
+    int genValues _AND_
+    int genEncoders _AND_
+    int genDecoders _AND_
+    int genPrinters _AND_
+    int genFree _AND_
+    if_META (MetaNameStyle genMeta _AND_)
+    if_META (MetaPDU *meta_pdus _AND_)
+    if_TCL (int genTcl _AND_)
+    int novolatilefuncs)
+{
+    Module		*currMod;
+    char		*modBaseFileName;
+    FILE		*hdrFilePtr;
+    FILE		*srcFilePtr;
+#ifdef _IBM_ENC_
+    FILE		*hdbFilePtr;    /* 19.8.93 IBM-ENC */
+    FILE		*sdbFilePtr;    /* 19.8.93 IBM-ENC */
+#endif /* _IBM_ENC_ */
+    DefinedObj		*fNames;
+    int			fNameConflict = FALSE;
+
+#if META
+    static const char	metabasefn[] = "modules";
+    Meta		meta;
+#if TCL
+    const MetaPDU	*pdu;
+#endif
+#endif
+
+    /*
+     * Make names for each module's encoder/decoder src and hdr files
+     * so import references can be made via include files
+     * check for truncation --> name conflicts & exit if nec
+     */
+    fNames = NewObjList();
+#if META
+    if (genMeta)
+	DefineObj (&fNames, meta.srcfn = MakeCxxSrcFileName (metabasefn));
+#endif
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        modBaseFileName = MakeBaseFileName (keepbaseG
+		? currMod->asn1SrcFileName
+		: currMod->modId->name); /* shorten module name if necessary (SYSV etc) */
+        currMod->cxxHdrFileName = MakeCxxHdrFileName (modBaseFileName);
+        currMod->cxxSrcFileName = MakeCxxSrcFileName (modBaseFileName);
+#ifdef _IBM_ENC_
+        currMod->dbHdrFileName  = MakedbHdrFileName (modBaseFileName); /* 19.8.93 IBM-ENC */
+        currMod->dbSrcFileName  = MakedbSrcFileName (modBaseFileName); /* 19.8.93 IBM-ENC */
+#endif /* _IBM_ENC_ */
+#if META
+	{
+	    char *in, *out;
+
+	    out = currMod->cxxname = (char *)malloc (strlen (in = currMod->modId->name)+1);
+	    do
+		*out++ = *in == '-' ? '_' : *in;
+	    while (*in++);
+	}
+#endif
+
+        if (ObjIsDefined (fNames, currMod->cxxHdrFileName, StrObjCmp) || ObjIsDefined (fNames, currMod->cxxSrcFileName, StrObjCmp))
+        {
+            fprintf (stderr, "Ack! ERROR---file name conflict for generated source files with names `%s' and `%s'.\n\n", currMod->cxxHdrFileName, currMod->cxxSrcFileName);
+            fprintf (stderr, "This usually means the max file name length is truncating the file names.\n");
+            fprintf (stderr, "Try re-naming the modules with shorter names or increasing the argument to -mf option (if you are using it).\n");
+            fprintf (stderr, "This error can also be caused by 2 modules have the same names but different OBJECT IDENTIFIERs.");
+            fprintf (stderr, "  Try renaming the modules to correct this.\n");
+            fNameConflict = TRUE;
+        }
+        else
+        {
+            DefineObj (&fNames, currMod->cxxHdrFileName);
+            DefineObj (&fNames, currMod->cxxSrcFileName);
+        }
+        Free (modBaseFileName);
+    }
+    if (fNameConflict)
+        exit (1);
+
+    FreeDefinedObjs (&fNames);
+
+    /*
+     * make C++ files
+     */
+#if META
+    if (genMeta)
+    {
+	time_t now = time (NULL);
+
+	if (!(meta.srcfp = fopen (meta.srcfn, "w")))
+	{
+	  perror ("fopen");
+	  exit (1);
+	}
+	fprintf (meta.srcfp, "// NOTE: this is a machine generated file--editing not recommended\n");
+	fprintf (meta.srcfp, "//\n");
+	fprintf (meta.srcfp, "// modules.C - reference to all modules and their types\n");
+	fprintf (meta.srcfp, "//\n");
+	fprintf (meta.srcfp, "// This file was generated by snacc on %s", ctime (&now));
+    }
+#endif
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        /*
+         * create and fill .h file for module's data structs
+         */
+        hdrFilePtr = fopen (currMod->cxxHdrFileName, "w");
+        srcFilePtr = fopen (currMod->cxxSrcFileName, "w");
+#ifndef _IBM_ENC_
+        if ((hdrFilePtr == NULL) || (srcFilePtr == NULL))
+#else
+        hdbFilePtr = fopen (currMod->dbHdrFileName, "w");       /* 19.8.93 IBM-ENC */
+        sdbFilePtr = fopen (currMod->dbSrcFileName, "w");       /* 19.8.93 IBM-ENC */
+        if ((hdrFilePtr == NULL) || (srcFilePtr == NULL) ||
+            (hdbFilePtr == NULL) || (sdbFilePtr == NULL))      /* 19.8.93 IBM-ENC */
+#endif /* _IBM_ENC_ */
+            perror ("fopen");
+        else
+        {
+            PrintCxxCode (srcFilePtr, hdrFilePtr,
+			if_IBM_ENC (sdbFilePtr COMMA hdbFilePtr COMMA /* 19.8.93 IBM-ENC */)
+			if_META (genMeta COMMA &meta COMMA meta_pdus COMMA)
+			allMods, currMod, &cxxRulesG, longJmpVal,
+			genTypes, genValues, genEncoders, genDecoders, genPrinters, genFree,
+			if_TCL (genTcl COMMA) novolatilefuncs);
+
+            fclose (hdrFilePtr);
+            fclose (srcFilePtr);
+#ifdef _IBM_ENC_
+            fclose (hdbFilePtr);       /* 19.8.93 IBM-ENC */
+            fclose (sdbFilePtr);       /* 19.8.93 IBM-ENC */
+#endif /* _IBM_ENC_ */
+        }
+    }
+#if META
+    if (genMeta)
+    {
+	fprintf (meta.srcfp, "\n");
+	fprintf (meta.srcfp, "#ifndef META\n");
+	fprintf (meta.srcfp, "#define META	1\n");
+	fprintf (meta.srcfp, "#endif\n");
+	if (meta_pdus)
+	{
+	    for (pdu=meta_pdus; pdu; pdu=pdu->next)
+		if (!pdu->used)
+		    fprintf (stderr, "warning: PDU %s.%s couldn't be found\n", pdu->module, pdu->type);
+	}
+#if TCL
+	fprintf (meta.srcfp, "#ifndef TCL\n");
+	fprintf (meta.srcfp, "#define TCL	META\n");
+	fprintf (meta.srcfp, "#endif\n");
+#endif
+	fprintf (meta.srcfp, "\n");
+
+	fprintf (meta.srcfp, "#include \"asn-incl.h\"\n");
+	FOR_EACH_LIST_ELMT (currMod, allMods)
+	    fprintf (meta.srcfp, "#include \"%s\"\n", currMod->cxxHdrFileName);
+	fprintf (meta.srcfp, "\n");
+
+	fprintf (meta.srcfp, "#if META\n\n");
+
+	fprintf (meta.srcfp, "const AsnModuleDesc *asnModuleDescs[] =\n");
+	fprintf (meta.srcfp, "{\n");
+	FOR_EACH_LIST_ELMT (currMod, allMods)
+	    fprintf (meta.srcfp, "  &%sModuleDesc,\n", currMod->cxxname);
+	fprintf (meta.srcfp, "  NULL\n");
+	fprintf (meta.srcfp, "};\n\n");
+
+	if (genTcl)
+	{
+	  fprintf (meta.srcfp, "#if TCL\n\n");
+
+	  fprintf (meta.srcfp, "// hack to avoid the neccessity to list -ltk -ltcl both before and after -lasn1tcl:\n");
+	  fprintf (meta.srcfp, "static int (*dummy)(Tcl_Interp *) = Tcl_AppInit;\n\n");
+
+	  fprintf (meta.srcfp, "#endif // TCL\n\n");
+	}
+
+	fprintf (meta.srcfp, "#endif // META\n");
+
+	fclose (meta.srcfp);
+    }
+#endif
+}  /* GenCxxCode */
+
+
+#if IDL
+/*
+ * Given the list of parsed, linked, normalized, error-checked and sorted
+ * modules, and some code generation flags, generates C++ code and
+ * writes it to files derived from each modules name.  Each module
+ * gets 2 source files, one .h for data struct and prototypes, the other .C
+ * for the enc/dec/print/free routine code.
+ */
+void
+GenIDLCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genPrinters, genFree),
+    ModuleList *allMods _AND_
+    long int longJmpVal _AND_
+    int genTypes _AND_
+    int genValues _AND_
+    int genPrinters _AND_
+    int genFree)
+{
+    Module		*currMod;
+    char		*modBaseFileName;
+    FILE		*idlFilePtr;
+    DefinedObj		*fNames;
+    int			fNameConflict = FALSE;
+
+    /*
+     * Make names for each module's encoder/decoder src and hdr files
+     * so import references can be made via include files
+     * check for truncation --> name conflicts & exit if nec
+     */
+    fNames = NewObjList();
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        modBaseFileName = MakeBaseFileName (keepbaseG
+		? currMod->asn1SrcFileName
+		: currMod->modId->name); /* shorten module name if necessary (SYSV etc) */
+        currMod->idlFileName = MakeIDLFileName (modBaseFileName);
+	{
+	    char *in, *out;
+
+	    out = currMod->idlname = (char *)malloc (strlen (in = currMod->modId->name)+1);
+	    do
+		*out++ = *in == '-' ? '_' : *in;
+	    while (*in++);
+	}
+
+        if (ObjIsDefined (fNames, currMod->idlFileName, StrObjCmp))
+        {
+            fprintf (stderr, "Ack! ERROR---file name conflict for generated source file with name `%s'.\n\n", currMod->idlFileName);
+            fprintf (stderr, "This usually means the max file name length is truncating the file names.\n");
+            fprintf (stderr, "Try re-naming the modules with shorter names or increasing the argument to -mf option (if you are using it).\n");
+            fprintf (stderr, "This error can also be caused by 2 modules have the same names but different OBJECT IDENTIFIERs.");
+            fprintf (stderr, "  Try renaming the modules to correct this.\n");
+            fNameConflict = TRUE;
+        }
+        else
+        {
+            DefineObj (&fNames, currMod->idlFileName);
+        }
+        Free (modBaseFileName);
+    }
+    if (fNameConflict)
+        exit (1);
+
+    FreeDefinedObjs (&fNames);
+
+    /*
+     * make C++ files
+     */
+    FOR_EACH_LIST_ELMT (currMod, allMods)
+    {
+        /*
+         * create and fill .h file for module's data structs
+         */
+        idlFilePtr = fopen (currMod->idlFileName, "w");
+        if (idlFilePtr == NULL)
+            perror ("fopen");
+        else
+        {
+            PrintIDLCode (idlFilePtr, allMods, currMod, &idlRulesG, longJmpVal, genValues);
+
+            fclose (idlFilePtr);
+        }
+    }
+}  /* GenIDLCode */
+#endif /* IDL */
+
+
+/*
+ * returns 1 if the module names and oid's are unique.
+ * otherwise returns 0
+ */
+int ModNamesUnique PARAMS ((mods),
+    ModuleList *mods)
+{
+    DefinedObj *names;
+    DefinedObj *oids;
+    Module *m;
+    int retVal = 1;
+
+    names = NewObjList();
+    oids = NewObjList();
+
+    FOR_EACH_LIST_ELMT (m, mods)
+    {
+        if (((m->modId->oid != NULL) &&
+            ObjIsDefined (oids, m->modId->oid, OidObjCmp)))
+        {
+            /* oops, 2 modules have the same oid */
+            PrintErrLoc (m->asn1SrcFileName, 1);
+            fprintf (stderr, "ERROR---2 modules have the OBJECT IDENTIFIER `");
+            PrintOid (stderr, m->modId->oid);
+            fprintf (stderr, "'.\n");
+            retVal = 0;
+        }
+        /* name is only signficant if oid is empty */
+        else if ((m->modId->oid == NULL) &&
+             (ObjIsDefined (names, m->modId->name, StrObjCmp)))
+        {
+            /* oops, 2 modules have the same name */
+            PrintErrLoc (m->asn1SrcFileName, 1);
+            fprintf (stderr, "ERROR---2 modules have the name `%s'\n", m->modId->name);
+            retVal = 0;
+        }
+        else
+        {
+            DefineObj (&names, m->modId->name);
+            if (m->modId->oid != NULL)
+                DefineObj (&oids, m->modId->oid);
+        }
+    }
+    FreeDefinedObjs (&names);
+    FreeDefinedObjs (&oids);
+    return retVal;
+} /* ModNamesUnique */
diff --git a/SecuritySNACCRuntime/compiler/core/tbl.c b/SecuritySNACCRuntime/compiler/core/tbl.c
new file mode 100644
index 00000000..ca825f8d
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/tbl.c
@@ -0,0 +1,574 @@
+/*
+ *    tbl.c
+ *
+ *    "TBL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Tue Jun 19 16:55:23 2001
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "tbl.h"
+
+
+AsnLen
+BEncTBLRangeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLRange *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->to));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->from));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLRangeContent */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumber *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->value));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLNamedNumberContent */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberListContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumberList *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLNamedNumberListContent */
+
+
+
+
+AsnLen
+BEncTBLTypeRefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeRef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnBoolContent (b, (&v->implicit));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeRefContent */
+
+
+
+
+AsnLen
+BEncTBLTagContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTag *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->code));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTagClassContent (b, (&v->tclass));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 10);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTagContent */
+
+
+
+
+AsnLen
+BEncTBLTypeSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTagContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContentSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContentSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeContentSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLType *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->values)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberListContent (b, (v->values));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 6);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLRangeContent (b, (v->constraint));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 5);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    itemLen = BEncPrintableStringContent (b, (&v->fieldName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 4);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentContent (b, (v->content));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncAsnBoolContent (b, (&v->optional));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeIdContent (b, (&v->typeId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContentContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContent *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_PRIMTYPE:
+    itemLen = BEncAsnNullContent (b, (&v->a.primType));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_ELMTS:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncTBLTypeContentContent */
+
+
+
+
+AsnLen
+BEncTBLTypeDefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeDef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    itemLen = BEncAsnNullContent (b, (v->isPdu));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 5);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, (v->type));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->typeName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 19);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeDefContent */
+
+
+
+
+AsnLen
+BEncTBLModuleSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModuleSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeDefContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLModuleSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLModuleContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModule *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnBoolContent (b, (&v->isUseful));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->id));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLModuleContent */
+
+
+
+
+AsnLen
+BEncTBLSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLSeqOfContent */
+
+
+
+
+AsnLen BEncTBL PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncTBLContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    return l;
+} /* BEncTBL */
+
+AsnLen
+BEncTBLContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLSeqOfContent (b, (v->modules));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalLenStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTags));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypes));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumModules));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLContent */
+
+
+
+
diff --git a/SecuritySNACCRuntime/compiler/core/tbl.h b/SecuritySNACCRuntime/compiler/core/tbl.h
new file mode 100644
index 00000000..2a81b7c7
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/tbl.h
@@ -0,0 +1,224 @@
+/*
+ *    tbl.h
+ *
+ *    "TBL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Tue Jun 19 16:55:23 2001
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _tbl_h_
+#define _tbl_h_
+
+
+
+
+typedef enum
+    {
+        TBL_BOOLEAN = 0,
+        TBL_INTEGER = 1,
+        TBL_BITSTRING = 2,
+        TBL_OCTETSTRING = 3,
+        TBL_NULL = 4,
+        TBL_OID = 5,
+        TBL_REAL = 6,
+        TBL_ENUMERATED = 7,
+        TBL_SEQUENCE = 8,
+        TBL_SET = 9,
+        TBL_SEQUENCEOF = 10,
+        TBL_SETOF = 11,
+        TBL_CHOICE = 12,
+        TBL_TYPEREF = 13
+    } TBLTypeId; /* ENUMERATED { TBL_BOOLEAN (0), TBL_INTEGER (1), TBL_BITSTRING (2), TBL_OCTETSTRING (3), TBL_NULL (4), TBL_OID (5), TBL_REAL (6), TBL_ENUMERATED (7), TBL_SEQUENCE (8), TBL_SET (9), TBL_SEQUENCEOF (10), TBL_SETOF (11), TBL_CHOICE (12), TBL_TYPEREF (13) }  */
+
+#define BEncTBLTypeIdContent BEncAsnEnumContent
+
+
+
+
+typedef AsnInt TBLTypeDefId; /* INTEGER */
+
+#define BEncTBLTypeDefIdContent BEncAsnIntContent
+
+
+
+
+typedef enum
+    {
+        UNIVERSAL = 0,
+        APPLICATION = 1,
+        CONTEXT = 2,
+        PRIVATE = 3
+    } TBLTagClass; /* ENUMERATED { UNIVERSAL (0), APPLICATION (1), CONTEXT (2), PRIVATE (3) }  */
+
+#define BEncTBLTagClassContent BEncAsnEnumContent
+
+
+
+
+typedef struct TBLRange /* SEQUENCE */
+{
+    AsnInt from; /* [0] IMPLICIT INTEGER */
+    AsnInt to; /* [1] IMPLICIT INTEGER */
+} TBLRange;
+
+AsnLen BEncTBLRangeContent PROTO ((BUF_TYPE b, TBLRange *v));
+
+
+
+
+typedef struct TBLNamedNumber /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnInt value; /* [1] IMPLICIT INTEGER */
+} TBLNamedNumber;
+
+AsnLen BEncTBLNamedNumberContent PROTO ((BUF_TYPE b, TBLNamedNumber *v));
+
+
+
+
+typedef AsnList TBLNamedNumberList; /* SEQUENCE OF TBLNamedNumber */
+
+AsnLen BEncTBLNamedNumberListContent PROTO ((BUF_TYPE b, TBLNamedNumberList *v));
+
+
+
+
+typedef struct TBLTypeRef /* SEQUENCE */
+{
+    TBLTypeDefId typeDef; /* TBLTypeDefId */
+    AsnBool implicit; /* BOOLEAN */
+} TBLTypeRef;
+
+AsnLen BEncTBLTypeRefContent PROTO ((BUF_TYPE b, TBLTypeRef *v));
+
+
+
+
+typedef struct TBLTag /* SEQUENCE */
+{
+    TBLTagClass tclass; /* TBLTagClass */
+    AsnInt code; /* INTEGER (0..MAX) */
+} TBLTag;
+
+AsnLen BEncTBLTagContent PROTO ((BUF_TYPE b, TBLTag *v));
+
+
+
+
+typedef AsnList TBLTypeSeqOf; /* SEQUENCE OF TBLTag */
+
+AsnLen BEncTBLTypeSeqOfContent PROTO ((BUF_TYPE b, TBLTypeSeqOf *v));
+
+
+
+
+typedef AsnList TBLTypeContentSeqOf; /* SEQUENCE OF TBLType */
+
+AsnLen BEncTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, TBLTypeContentSeqOf *v));
+
+
+
+
+typedef struct TBLType /* SEQUENCE */
+{
+    TBLTypeId typeId; /* [0] IMPLICIT TBLTypeId */
+    AsnBool optional; /* [1] IMPLICIT BOOLEAN */
+    TBLTypeSeqOf* tagList; /* [2] IMPLICIT TBLTypeSeqOf OPTIONAL */
+    struct TBLTypeContent* content; /* [3] TBLTypeContent */
+    PrintableString fieldName; /* [4] IMPLICIT PrintableString OPTIONAL */
+    struct TBLRange* constraint; /* [5] IMPLICIT TBLRange OPTIONAL */
+    TBLNamedNumberList* values; /* [6] IMPLICIT TBLNamedNumberList OPTIONAL */
+} TBLType;
+
+AsnLen BEncTBLTypeContent PROTO ((BUF_TYPE b, TBLType *v));
+
+
+
+
+typedef struct TBLTypeContent /* CHOICE */
+{
+    enum TBLTypeContentChoiceId
+    {
+        TBLTYPECONTENT_PRIMTYPE,
+        TBLTYPECONTENT_ELMTS,
+        TBLTYPECONTENT_TYPEREF
+    } choiceId;
+    union TBLTypeContentChoiceUnion
+    {
+    AsnNull primType; /* [0] IMPLICIT NULL */
+    TBLTypeContentSeqOf* elmts; /* [1] IMPLICIT TBLTypeContentSeqOf */
+    struct TBLTypeRef* typeRef; /* [2] IMPLICIT TBLTypeRef */
+    } a;
+} TBLTypeContent;
+
+AsnLen BEncTBLTypeContentContent PROTO ((BUF_TYPE b, TBLTypeContent *v));
+
+
+
+
+typedef struct TBLTypeDef /* SEQUENCE */
+{
+    TBLTypeDefId typeDefId; /* TBLTypeDefId */
+    PrintableString typeName; /* PrintableString */
+    struct TBLType* type; /* TBLType */
+    AsnNull* isPdu; /* NULL OPTIONAL */
+} TBLTypeDef;
+
+AsnLen BEncTBLTypeDefContent PROTO ((BUF_TYPE b, TBLTypeDef *v));
+
+
+
+
+typedef AsnList TBLModuleSeqOf; /* SEQUENCE OF TBLTypeDef */
+
+AsnLen BEncTBLModuleSeqOfContent PROTO ((BUF_TYPE b, TBLModuleSeqOf *v));
+
+
+
+
+typedef struct TBLModule /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnOid id; /* [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL */
+    AsnBool isUseful; /* [2] IMPLICIT BOOLEAN */
+    TBLModuleSeqOf* typeDefs; /* [3] IMPLICIT TBLModuleSeqOf */
+} TBLModule;
+
+AsnLen BEncTBLModuleContent PROTO ((BUF_TYPE b, TBLModule *v));
+
+
+
+
+typedef AsnList TBLSeqOf; /* SEQUENCE OF TBLModule */
+
+AsnLen BEncTBLSeqOfContent PROTO ((BUF_TYPE b, TBLSeqOf *v));
+
+
+
+
+typedef struct TBL /* SEQUENCE */
+{
+    AsnInt totalNumModules; /* INTEGER */
+    AsnInt totalNumTypeDefs; /* INTEGER */
+    AsnInt totalNumTypes; /* INTEGER */
+    AsnInt totalNumTags; /* INTEGER */
+    AsnInt totalNumStrings; /* INTEGER */
+    AsnInt totalLenStrings; /* INTEGER */
+    TBLSeqOf* modules; /* TBLSeqOf */
+} TBL;
+
+AsnLen BEncTBL PROTO ((BUF_TYPE b, TBL *v));
+
+AsnLen BEncTBLContent PROTO ((BUF_TYPE b, TBL *v));
+
+
+
+
+
+#endif /* conditional include of tbl.h */
diff --git a/SecuritySNACCRuntime/compiler/core/tblCompiler.c b/SecuritySNACCRuntime/compiler/core/tblCompiler.c
new file mode 100644
index 00000000..a3362278
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/tblCompiler.c
@@ -0,0 +1,574 @@
+/*
+ *    tbl.c
+ *
+ *    "TBL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Mon Jun  2 11:23:51 1997
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "tbl.h"
+
+
+AsnLen
+BEncTBLRangeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLRange *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->to));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->from));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLRangeContent */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumber *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->value));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLNamedNumberContent */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberListContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumberList *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLNamedNumberListContent */
+
+
+
+
+AsnLen
+BEncTBLTypeRefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeRef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnBoolContent (b, (&v->implicit));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeRefContent */
+
+
+
+
+AsnLen
+BEncTBLTagContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTag *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->code));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTagClassContent (b, (&v->tclass));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 10);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTagContent */
+
+
+
+
+AsnLen
+BEncTBLTypeSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTagContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContentSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContentSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeContentSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLType *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->values)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberListContent (b, (v->values));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 6);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLRangeContent (b, (v->constraint));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 5);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    itemLen = BEncPrintableStringContent (b, (&v->fieldName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 4);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentContent (b, (v->content));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncAsnBoolContent (b, (&v->optional));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeIdContent (b, (&v->typeId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContentContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContent *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_PRIMTYPE:
+    itemLen = BEncAsnNullContent (b, (&v->a.primType));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_ELMTS:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncTBLTypeContentContent */
+
+
+
+
+AsnLen
+BEncTBLTypeDefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeDef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    itemLen = BEncAsnNullContent (b, (v->isPdu));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 5);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, (v->type));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->typeName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 19);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeDefContent */
+
+
+
+
+AsnLen
+BEncTBLModuleSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModuleSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeDefContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLModuleSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLModuleContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModule *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnBoolContent (b, (&v->isUseful));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->id));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLModuleContent */
+
+
+
+
+AsnLen
+BEncTBLSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLSeqOfContent */
+
+
+
+
+AsnLen BEncTBL PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncTBLContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    return l;
+} /* BEncTBL */
+
+AsnLen
+BEncTBLContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLSeqOfContent (b, (v->modules));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalLenStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTags));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypes));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumModules));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLContent */
+
+
+
+
diff --git a/SecuritySNACCRuntime/compiler/core/val-parser.c b/SecuritySNACCRuntime/compiler/core/val-parser.c
new file mode 100644
index 00000000..ab81ebfd
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/val-parser.c
@@ -0,0 +1,734 @@
+/*
+ * compiler/core/val_parser.c
+ *         given a string with txt ASN.1 value notation, the length of
+ *         the string and the ASN.1 type the value notion defines a value
+ *         for, return a Value that contains the internal version
+ *
+ *
+ * currently limited to parsing OBJECT IDENTIFIERs.
+ * should be easy to extend for other values as needed
+ *
+ * Copyright (C) 1991, 1992 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/val-parser.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Log: val-parser.c,v $
+ * Revision 1.1  2001/06/20 21:27:59  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:53  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.4  1997/10/10 13:43:16  wan
+ * Corrected bug in generic table decoder wrt. indefinite length elements
+ * Corrected compiler access to freed memory (bug reported by Markku Savela)
+ * Broke asnwish.c into two pieces so that one can build ones on wish
+ * Added beredit tool (based on asnwish, allowes to edit BER messages)
+ *
+ * Revision 1.3  1995/07/25 19:41:46  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/09/01  00:47:33  rj
+ * snacc_config.h removed; val_parser.h includet.
+ *
+ * Revision 1.1  1994/08/28  09:49:44  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+
+#include <ctype.h> /* for isalpha, isdigit etc macros */
+#include <stdio.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "mem.h"
+#include "snacc-util.h"
+#include "oid.h"  /* arcname->number mapping */
+#include "val-parser.h"
+
+/*
+ * a bunch of macros for 'standard' parse routines
+ */
+#define P_LOCALS\
+    char *startStr
+
+#define SAVE_POS()\
+    startStr = *vStr;
+
+#define RESTORE_POS()\
+    *vStr = startStr;
+
+#define AT_EOF()\
+      (*vStr == eof)
+
+#define FAIL()\
+{\
+    if (*vStr > farthestPosG)\
+        farthestPosG = *vStr;\
+    RESTORE_POS();\
+    return FALSE;\
+}
+
+#define SUCCEED()\
+    return TRUE;
+
+#define FATAL_ERR()\
+    parseValuesErrG = 1;
+
+/*
+ * a couple macros for errmsg generation
+ */
+#define PRINT_ERR_LOC(m, vd)\
+   fprintf (stderr,"file \"%s\", line %d (or near): ", m->asn1SrcFileName, valLineNoG);
+
+
+#define PRINT_VAL(vd)\
+    PrintValueDef (stderr, vd);
+
+/*
+ * globals
+ */
+static ValueDefList *newValsG;
+static int parseValuesErrG;
+static unsigned long valLineNoG;
+static char *farthestPosG;
+
+/*
+ * prototypes for non-exported routines
+ */
+char *StripComments PROTO ((char *asn1Str, int len));
+Value *ParseValue PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char *valueNotation, int len));
+
+Value *ParseValueInternal PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char **valueNotation, char *eof));
+
+int ParseOidValue PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char **valueNotation, char *eof, Value **result));
+
+void SkipWht PROTO ((char **vStr, char *eof));
+int  ParseIdentifier PROTO ((char **valueNotation, char *eof, char **result));
+int  ParseNum PROTO ((char **valueNotation, char *eof, char **result));
+void AddNewValueDef PROTO ((ValueDefList *vdl, char *name, Value *value));
+
+
+
+/*
+ * returns 0 if no parse errors occurred
+ * otherwise returns non-zero
+ */
+int
+ParseValues PARAMS ((mods, m),
+    ModuleList *mods _AND_
+    Module *m)
+{
+    ValueDef *v;
+    Value *pv;
+
+    newValsG = AsnListNew (sizeof (void*));
+
+    FOR_EACH_LIST_ELMT (v, m->valueDefs)
+    {
+        if (v->value->basicValue->choiceId == BASICVALUE_VALUENOTATION)
+        {
+            valLineNoG = v->value->lineNo;
+            pv = ParseValue (mods, m, v, v->value->type, v->value->basicValue->a.valueNotation->octs, v->value->basicValue->a.valueNotation->octetLen);
+
+            /* replace value notation value with parsed version */
+            if (pv != NULL)
+            {
+                pv->lineNo = v->value->lineNo;
+                pv->type = v->value->type;
+                Free (v->value->basicValue->a.valueNotation->octs);
+                Free (v->value->basicValue->a.valueNotation);
+                Free (v->value->basicValue);
+                Free (v->value);
+                v->value = pv;
+            }
+        }
+    }
+
+    /*
+     * should traverse type structures for default values etc
+     * that need parsing
+     */
+
+    /* add any new value defs */
+    m->valueDefs = AsnListConcat (m->valueDefs, newValsG);
+    Free (newValsG);
+
+    return parseValuesErrG;
+
+} /* ParseValues */
+
+
+
+/*
+ * returns the Value that resuls from parsing the given
+ * value notation string
+ */
+Value*
+ParseValue PARAMS ((mods, m, vd, t, valueNotationStr, vnLen),
+    ModuleList *mods _AND_
+    Module *m _AND_
+    ValueDef *vd _AND_
+    Type *t _AND_
+    char *valueNotationStr _AND_
+    int vnLen)
+{
+    char *vStr;
+    char *vStrOrig;
+    int vStrLen;
+    Value *retVal;
+
+    /* make copy of value notation with ASN.1 comments zapped */
+    vStrOrig = vStr = StripComments (valueNotationStr, vnLen);
+    vStrLen = strlen (vStr);
+
+    retVal = ParseValueInternal (mods, m, vd, t, &vStr, (vStr + vStrLen));
+
+    /* use original since parsing has changed vStr */
+    free (vStrOrig);
+
+    return retVal;
+}
+
+/*
+ * vStr is a handle to a commentless ASN.1 value string,
+ * eof is a char * to character after the last valid character
+ * in vStr.  vStr will be advanced to the current parse location.
+ */
+Value*
+ParseValueInternal PARAMS ((mods, m, vd, t, vStr, eof),
+    ModuleList *mods _AND_
+    Module *m _AND_
+    ValueDef *vd _AND_
+    Type *t _AND_
+    char **vStr _AND_
+    char *eof)
+{
+    Type *dT;
+    Value *retVal;
+    int parseResult = FALSE;
+
+    dT = ParanoidGetType (t); /* skip type refs to get defining type */
+
+    if (dT == NULL)
+        return NULL;
+
+    retVal = NULL;
+
+    switch (dT->basicType->choiceId)
+    {
+        case BASICTYPE_SEQUENCE:
+        case BASICTYPE_SET:
+        case BASICTYPE_CHOICE:
+        case BASICTYPE_SEQUENCEOF:
+        case BASICTYPE_SETOF:
+            /* don't do constructed types yet */
+            break;
+
+
+        case BASICTYPE_SELECTION:
+        case BASICTYPE_COMPONENTSOF:
+        case BASICTYPE_ANYDEFINEDBY:
+        case BASICTYPE_UNKNOWN:
+        case BASICTYPE_ANY:
+            /* don't do weird types */
+            break;
+
+
+        /*
+         * The following simple types will need to be filled in
+         * when the constructed types are parsed.
+         * (ie ParseValueInternal becomes recursive)
+         * (currenly all simple types not in {}'s are parsed
+         * in the main yacc parser.)
+         */
+
+        case BASICTYPE_BOOLEAN:
+            break;
+
+        case BASICTYPE_INTEGER:
+        case BASICTYPE_ENUMERATED:
+            break;
+
+        case BASICTYPE_REAL:
+            break;
+
+        case BASICTYPE_BITSTRING:
+            break;
+
+        case BASICTYPE_NULL:
+            break;
+
+        case BASICTYPE_OCTETSTRING:
+            break;
+
+
+        /* assume all macro values in {}'s are OID values */
+        case BASICTYPE_OID:
+        case BASICTYPE_MACROTYPE:
+            parseResult = ParseOidValue (mods, m, vd, t, vStr, eof, &retVal);
+            if (!parseResult)
+                FATAL_ERR();
+            break;
+
+
+        default:
+           break;
+    }
+
+    if (parseResult)
+        return retVal;
+    else
+        return NULL;
+
+}  /* ParseValueInternal */
+
+
+/*
+ *  Strips ASN.1 comments from the given string.
+ *  returns a null terminated malloc'd copy without the comments
+ */
+char*
+StripComments PARAMS ((s, len),
+    char *s _AND_
+    int len)
+{
+    char *cpy;
+    int sIndex, cpyIndex;
+    int inComment;
+
+    cpy = (char*)Malloc (len +1);
+    cpyIndex = 0;
+    for (sIndex = 0; sIndex < len; )
+    {
+        if ((s[sIndex] == '-') &&
+             ((sIndex+1) < len) && (s[sIndex+1]== '-'))
+        {
+            /* eat comment body */
+            for (sIndex += 2; sIndex < len; )
+            {
+                if ((s[sIndex] == '-') &&
+                    ((sIndex+1) < len) && (s[sIndex+1]== '-'))
+                {
+                    sIndex += 2;
+                    break; /* exit for */
+                }
+                else if (s[sIndex] == '\n')
+                {
+                    sIndex++;
+                    break; /* exit for */
+                }
+                else
+                    sIndex++;
+            }
+        }
+        else   /* not in or start of comment */
+            cpy[cpyIndex++] = s[sIndex++];
+    }
+
+    cpy[cpyIndex] == '\0';  /* add  NULL terminator */
+    return cpy;
+}  /* StripComments */
+
+
+
+
+/*
+ * Returns TRUE if successfully parsed an OID
+ * otherwise returns FALSE.  Puts the resulting OID Value in
+ * result if successful.
+ *  The result Value's type is BASICVALUE_LINKEDOID
+ *
+ * Pseudo reg expr of the expected oid format:
+ *  "{"
+ *    (oid_val_ref)?
+ *(defined_oid_elmt_name | digit+ | int_or_enum_val_ref |name"(" digit")")*
+ * "}"
+ *
+ * Does not attempt to link/lookup referenced values
+ *
+ * eg
+ * for { ccitt foo (1) bar bell (bunt) 2 }
+ *
+ * ccitt
+ *    arcnum is set to number from oid table (oid.c)
+ * foo (1)
+ *   - arcnum set to 1
+ *   - sets up a new integer value def "foo"
+ *      defined as 1 *CHANGED -see changes*
+ *   - makes oid valueref a value ref to foo (doesn't link it tho)
+ * bar
+ *   - makes oid valueref a value ref to bar (doesn't link it tho)
+ * bell (bunt)
+ *   - sets up a new integer value def "bell" defined
+ *      as a val ref to "bunt" *CHANGED -see changes*
+ *   - makes oid valueref a value ref to bell (doesn't link it tho)
+ * 2
+ *  -arc num is set to 2
+ *
+ * CHANGES:
+ *   93/05/03 - named arcs such as foo (1) or bell (bunt) handling
+ *              changed. The names (foo and bell) are now ignored
+ *              and *do not* define new integer values.
+ *              The old way led to problems of defining some values
+ *              more than once. E.g. in X.500 the { .. ds (5) }
+ *              arc name is used everywhere - "ds INTEGER ::= 5"
+ *              was defined multiple times as a result.
+ *              Then the snacc error checker halted the compilation
+ *              since the integer value "ds" was mulitply defined.
+ *
+ */
+int
+ParseOidValue PARAMS ((mods, m, vd, t, vStr, eof, result),
+    ModuleList *mods _AND_
+    Module *m _AND_
+    ValueDef *vd _AND_
+    Type *t _AND_
+    char **vStr _AND_
+    char *eof _AND_
+    Value **result)
+{
+    Value *newVal;
+    Type  *newType;
+    Value *oidVal;
+    OID *parsedOid;
+    OID **nextOid;
+    char *id;
+    char *id2;
+    char *id3;
+    char *num;
+    int  arcNum;
+    int  namedNumVal;
+    P_LOCALS;
+
+
+    SAVE_POS();
+
+    if (AT_EOF())
+    {
+        PRINT_ERR_LOC (m, vd);
+        fprintf (stderr,"ERROR - expecting more data in OBJECT IDENTIFER value\n");
+        FAIL();
+    }
+
+    SkipWht (vStr, eof);
+
+    if (**vStr != '{')
+    {
+        PRINT_ERR_LOC (m, vd);
+        fprintf (stderr,"ERROR - OBJECT IDENTIFER values must begin with an \"{\".\n");
+        FAIL();
+    }
+    else
+        (*vStr)++; /* skip opening { */
+
+    SkipWht (vStr, eof);
+
+    parsedOid = NULL;
+    nextOid = &parsedOid;
+
+    while (**vStr != '}')
+    {
+        if (ParseIdentifier (vStr, eof, &id))
+        {
+            /*
+             * check for named number ident (num) or ident (valref)
+             * make a new value def with the name ident if is name
+             * and number form
+             */
+            SkipWht (vStr, eof);
+            if (**vStr == '(')
+            {
+
+                (*vStr)++; /* skip opening ( */
+                SkipWht (vStr, eof);
+
+                arcNum = NULL_OID_ARCNUM;
+                /*
+                 * ident (num)/ident (valref) yields a new value definition
+                 * ident.  The oid then refences this new value def.
+                 */
+
+                /*
+                 * first case check if of form
+                 * { ... ident (valref) ... }
+                 */
+                if (ParseIdentifier (vStr, eof, &id2))
+                {
+                    id3 = NULL;
+                    /* check if modname.val format */
+                    if (**vStr == '.')
+                    {
+                        (*vStr)++;
+                        if (!ParseIdentifier (vStr, eof, &id3))
+                        {
+                            PRINT_ERR_LOC (m, vd);
+                            fprintf (stderr,"ERROR - missing a module name after the \"%s.\" value reference", id2);
+                            FAIL();
+                        }
+                    }
+
+                    /* grab closing ) */
+                    SkipWht (vStr, eof);
+                    if (**vStr == ')')
+                        (*vStr)++;
+                    else
+                    {
+                        PRINT_ERR_LOC (m, vd);
+                        fprintf (stderr,"ERROR - missing a closing \")\", after the \"%s\" value reference.\n", id2);
+                        FAIL();
+                    }
+
+                    if (id3 != NULL) /* modname.val format */
+                    {
+                        SetupValue (&newVal, BASICVALUE_IMPORTVALUEREF,valLineNoG);
+                        newVal->basicValue->a.importValueRef =
+                            (ValueRef*)Malloc (sizeof (ValueRef));
+                        newVal->basicValue->a.importValueRef->valueName = id2;
+                        newVal->basicValue->a.importValueRef->moduleName = id3;
+
+                        AddPrivateImportElmt (m, id2, id3, valLineNoG);
+
+                    }
+                    else
+                    {
+                        SetupValue (&newVal, BASICVALUE_LOCALVALUEREF,valLineNoG);
+                        newVal->basicValue->a.localValueRef =
+                            (ValueRef*)Malloc (sizeof (ValueRef));
+                        newVal->basicValue->a.localValueRef->valueName = id2;
+                    }
+
+                }
+                /* check this form { ... ident (2)...}*/
+                else if (ParseNum (vStr, eof, &num))
+                {
+                    /* grab closing ) */
+                    SkipWht (vStr, eof);
+                    if (**vStr == ')')
+                        (*vStr)++;
+                    else
+                    {
+                        PRINT_ERR_LOC (m, vd);
+                        fprintf (stderr,"ERROR - missing a closing \")\" after the \"%s (%s\".\n", id2, num);
+                        Free (num);
+                        FAIL();
+                    }
+                    arcNum = atoi (num);
+                    Free (num);
+                    newVal = NULL;
+                }
+                else /* neither an ident or num after the "(" */
+                {
+                    PRINT_ERR_LOC (m, vd);
+                    fprintf (stderr,"ERROR - expecting either a value reference or number after the \"(\".\n");
+                    FAIL();
+                }
+
+                *nextOid = (OID*) Malloc (sizeof (OID));
+                (*nextOid)->valueRef = newVal;
+                (*nextOid)->arcNum = arcNum;
+                nextOid = &(*nextOid)->next;
+
+            }  /* end of ident (num) and ident (ident) form */
+
+            else /* value ref: { ... ident .... } */
+            {
+                *nextOid = (OID*) Malloc (sizeof (OID));
+                (*nextOid)->arcNum = NULL_OID_ARCNUM;
+
+                /*
+                 * check if special defined oid elmt name
+                 * like joint-iso-ccitt, iso, standard etc.
+                 */
+
+                arcNum = OidArcNameToNum (id);
+                if (arcNum != -1)
+                {
+                    (*nextOid)->arcNum = arcNum;
+                }
+                else /* value reference */
+                {
+                    SetupValue (&newVal, BASICVALUE_LOCALVALUEREF,valLineNoG);
+                    newVal->basicValue->a.localValueRef =
+                        (ValueRef*)Malloc (sizeof (ValueRef));
+                    newVal->basicValue->a.localValueRef->valueName = id;
+
+                    (*nextOid)->valueRef = newVal;
+                }
+                nextOid = &(*nextOid)->next;
+            }
+        }
+        else if (ParseNum (vStr, eof, &num))  /* { .. 2 .. } */
+        {
+            *nextOid = (OID*) Malloc (sizeof (OID));
+            (*nextOid)->arcNum = atoi (num);
+            nextOid = &(*nextOid)->next;
+            Free (num);
+        }
+        else
+        {
+            PRINT_ERR_LOC (m, vd);
+            fprintf (stderr,"ERROR - bady formed arc number\n");
+            FAIL();
+        }
+
+        SkipWht (vStr, eof);
+    }
+
+    (*vStr)++; /* move over closing } */
+
+    SetupValue (&oidVal, BASICVALUE_LINKEDOID, valLineNoG);
+    oidVal->basicValue->a.linkedOid = parsedOid;
+    *result = oidVal;
+    SUCCEED();
+}
+
+
+void
+SkipWht PARAMS ((vStr, eof),
+    char **vStr _AND_
+    char *eof)
+{
+    while (!AT_EOF())
+        switch (**vStr)
+        {
+            case '\n': /* newline */
+            case '\f': /* form feed  ?*/
+            case '\v': /* vertical tab ?*/
+            case '\r':  valLineNoG++; /* carriage return */
+            case '\t': /* tab */
+            case ' ':  /* space */
+            case '\007': /* bell? */
+            case '\b':   /* back spc */
+                (*vStr)++;
+                break;
+
+            default:
+               return;
+        }
+}
+
+
+/*
+ * advances the vStr over ASN.1 identifier, returns a copy
+ * in result, and returns TRUE. otherwise returns FALSE
+ *
+ * ASN.1 identifier is: lowercase letter followed by a
+ * string of letters (upper and lower case allowed), digtits, or single
+ * hyphens. last char cannot be a hyphen.
+ */
+int
+ParseIdentifier PARAMS ((vStr, eof, result),
+    char **vStr _AND_
+    char *eof _AND_
+    char **result)
+{
+    char *start;
+    int len;
+    P_LOCALS;
+
+    SAVE_POS();
+
+    if (AT_EOF())
+        FAIL();
+
+    start = *vStr;
+    if (!islower (**vStr))
+        FAIL();
+
+    (*vStr)++;
+
+    while (!AT_EOF())
+    {
+        /* allow letters, digits  and single hyphens */
+        if ((isalpha (**vStr)) || isdigit (**vStr) ||
+            ((**vStr == '-') && !(*(*vStr - 1) == '-')))
+            (*vStr)++;
+        else
+            break; /* exit for loop */
+
+    }
+
+    /* don't allow hyphens on the end */
+    if (*(*vStr - 1) == '-')
+        (*vStr)--;
+
+    len  = *vStr - start;
+    *result = Malloc (len +1);
+    strncpy (*result, start, len);
+    (*result)[len] = '\0';  /* null terminate */
+
+    SUCCEED();
+} /* ParseIdentifier */
+
+
+
+/*
+ * advances the vStr over ASN.1 number, returns a
+ * null terminated ascii copy of the number
+ * in result, and returns TRUE. otherwise returns FALSE
+ */
+int
+ParseNum PARAMS ((vStr, eof, result),
+    char **vStr _AND_
+    char *eof _AND_
+    char **result)
+{
+    P_LOCALS;
+    char *start;
+    int len;
+
+    SAVE_POS();
+
+    if (AT_EOF())
+        FAIL();
+
+    start = *vStr;
+
+    while (!AT_EOF())
+    {
+        if (isdigit (**vStr))
+            (*vStr)++;
+        else
+            break; /* exit for loop */
+    }
+    len  = *vStr - start;
+
+    if (len == 0)
+        FAIL();
+
+    *result = Malloc (len +1);
+    strncpy (*result, start, len);
+    (*result)[len] = '\0';  /* null terminate */
+
+    SUCCEED();
+} /* ParseNum */
+
+/*
+ * adds a new value def to the vdl.  Used
+ * when parsing oid's that defined arc values
+ * eg { 1 2 foo (3) } --> defined foo INTEGER ::= 3
+ * (should be  foo INTEGER (0..MAX) ::= 3)
+ */
+void
+AddNewValueDef PARAMS ((vdl, name, value),
+    ValueDefList *vdl _AND_
+    char *name _AND_
+    Value *value)
+{
+    ValueDef *vd;
+    ValueDef **tmpVd;
+
+    vd = (ValueDef*)Malloc (sizeof (ValueDef));
+    vd->definedName = name;
+    vd->value = value;
+    tmpVd = (ValueDef**)AsnListAppend (vdl);
+    *tmpVd = vd;
+}  /* AddNewValueDef */
diff --git a/SecuritySNACCRuntime/compiler/core/val-parser.h b/SecuritySNACCRuntime/compiler/core/val-parser.h
new file mode 100644
index 00000000..c8437b85
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/core/val-parser.h
@@ -0,0 +1,37 @@
+/*
+ * compiler/core/val_parser.h
+ *
+ * Value  *ParseValue (Type *t, char *valueNotation, int vnlen);
+ *         given a string with txt ASN.1 value notation, the length of
+ *         the string and the ASN.1 type the value notion defines a value
+ *         for, return a Value that contains the internal version
+ *
+ *
+ * Copyright (C) 1992 Michael Sample and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/val-parser.h,v 1.1 2001/06/20 21:27:59 dmitch Exp $
+ * $Log: val-parser.h,v $
+ * Revision 1.1  2001/06/20 21:27:59  dmitch
+ * Adding missing snacc compiler files.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:53  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.3  1995/07/25 19:41:48  rj
+ * changed `_' to `-' in file names.
+ *
+ * Revision 1.2  1994/08/31  21:47:26  rj
+ * adjust the function declaration to the function definition. this went undetected because the .c file didn't include its .h file.
+ *
+ * Revision 1.1  1994/08/28  09:49:45  rj
+ * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+ *
+ */
+
+
+int	ParseValues PROTO ((ModuleList *mods, Module *m));
diff --git a/SecuritySNACCRuntime/compiler/dependencies b/SecuritySNACCRuntime/compiler/dependencies
new file mode 100644
index 00000000..6871fc24
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/dependencies
@@ -0,0 +1,1232 @@
+lex-asn1.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/exports.h core/parse-asn1.h core/parser.h \
+  core/lex-stuff.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/errno.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/errno.h 
+parse-asn1.o : ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  ../policy.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h ../c-lib/inc/print.h \
+  ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h ../c-lib/inc/asn-bool.h \
+  ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h ../c-lib/inc/asn-real.h \
+  ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h ../c-lib/inc/asn-oid.h \
+  ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h ../c-lib/inc/hash.h \
+  ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h core/asn1module.h \
+  core/lib-types.h core/snacc-util.h core/exports.h core/parser.h \
+  core/lex-stuff.h 
+define.o : ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/define.h 
+dependency.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/snacc-util.h core/dependency.h 
+do-macros.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/define.h back-ends/str-util.h core/normalize.h \
+  core/snacc-util.h core/do-macros.h 
+err-chk.o : /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/snacc-util.h back-ends/tag-util.h core/define.h \
+  core/err-chk.h 
+exports.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/snacc-util.h core/exports.h 
+gen-tbls.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/tbl.h core/gen-tbls.h 
+lib-types.o : ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/lib-types.h 
+link-types.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/snacc-util.h core/link-types.h 
+link-values.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/snacc-util.h core/link-values.h 
+mem.o : ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  ../policy.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/mem.h 
+meta.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h core/meta.h 
+normalize.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/oid.h core/lib-types.h core/snacc-util.h \
+  core/normalize.h 
+oid.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/oid.h 
+print.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/lib-types.h core/print.h 
+recursive.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/recursive.h core/snacc-util.h 
+snacc.o : ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  ../policy.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/time.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/time.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/limits.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/limits.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h ../c-lib/inc/print.h \
+  ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h ../c-lib/inc/asn-bool.h \
+  ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h ../c-lib/inc/asn-real.h \
+  ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h ../c-lib/inc/asn-oid.h \
+  ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h ../c-lib/inc/hash.h \
+  ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h ../version.h \
+  core/asn1module.h core/exports.h core/parser.h core/dependency.h \
+  core/link-types.h core/link-values.h core/err-chk.h core/print.h \
+  core/recursive.h core/define.h core/normalize.h core/do-macros.h \
+  core/snacc-util.h core/meta.h back-ends/str-util.h \
+  back-ends/c-gen/rules.h back-ends/c-gen/type-info.h \
+  back-ends/c-gen/gen-code.h back-ends/c++-gen/rules.h \
+  back-ends/c++-gen/types.h back-ends/c++-gen/gen-code.h core/gen-tbls.h \
+  back-ends/idl-gen/rules.h back-ends/idl-gen/types.h \
+  back-ends/idl-gen/gen-code.h 
+snacc-util.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/lib-types.h core/define.h core/snacc-util.h 
+val-parser.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/snacc-util.h core/oid.h core/val-parser.h 
+str-util.o : ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/unistd.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  core/asn1module.h core/define.h back-ends/c-gen/rules.h \
+  back-ends/c-gen/type-info.h back-ends/c-gen/kwd.h \
+  back-ends/c++-gen/kwd.h back-ends/str-util.h 
+tag-util.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/define.h core/lib-types.h back-ends/c-gen/rules.h \
+  back-ends/c-gen/type-info.h back-ends/str-util.h core/snacc-util.h \
+  back-ends/c-gen/util.h back-ends/tag-util.h 
+cond.o : ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  back-ends/cond.h 
+type-info.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/snacc-util.h core/define.h back-ends/str-util.h \
+  back-ends/c-gen/rules.h back-ends/c-gen/type-info.h 
+util.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h back-ends/c-gen/rules.h core/snacc-util.h \
+  back-ends/c-gen/util.h 
+rules.o : ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h back-ends/c-gen/rules.h 
+gen-code.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/print.h back-ends/c-gen/rules.h \
+  back-ends/c-gen/type-info.h back-ends/c-gen/util.h back-ends/cond.h \
+  back-ends/c-gen/gen-type.h back-ends/c-gen/gen-enc.h \
+  back-ends/c-gen/gen-dec.h back-ends/c-gen/gen-vals.h \
+  back-ends/c-gen/gen-free.h back-ends/c-gen/gen-print.h \
+  back-ends/c-gen/gen-any.h back-ends/c-gen/gen-code.h 
+gen-type.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/print.h back-ends/c-gen/rules.h \
+  back-ends/c-gen/type-info.h back-ends/c-gen/util.h \
+  back-ends/c-gen/gen-type.h 
+gen-enc.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/define.h back-ends/c-gen/rules.h \
+  back-ends/c-gen/type-info.h back-ends/str-util.h back-ends/c-gen/util.h \
+  back-ends/tag-util.h core/snacc-util.h back-ends/c-gen/gen-enc.h 
+gen-dec.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/define.h core/lib-types.h back-ends/c-gen/rules.h \
+  back-ends/c-gen/type-info.h back-ends/str-util.h core/snacc-util.h \
+  back-ends/c-gen/util.h back-ends/tag-util.h back-ends/c-gen/gen-dec.h 
+gen-vals.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/oid.h core/asn1module.h core/define.h core/lib-types.h \
+  back-ends/c-gen/rules.h back-ends/c-gen/type-info.h back-ends/str-util.h \
+  core/snacc-util.h back-ends/c-gen/util.h back-ends/c-gen/kwd.h \
+  back-ends/c-gen/gen-vals.h 
+gen-free.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/define.h back-ends/c-gen/rules.h \
+  back-ends/c-gen/type-info.h back-ends/str-util.h back-ends/c-gen/util.h \
+  back-ends/c-gen/gen-free.h 
+gen-print.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/define.h back-ends/c-gen/rules.h \
+  back-ends/c-gen/type-info.h back-ends/str-util.h back-ends/c-gen/util.h \
+  back-ends/c-gen/gen-print.h 
+gen-any.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h back-ends/c-gen/rules.h core/define.h \
+  back-ends/str-util.h back-ends/c-gen/gen-vals.h core/lib-types.h \
+  back-ends/c-gen/gen-any.h 
+kwd.o : ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  ../policy.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  back-ends/c-gen/kwd.h 
+kwd.o : ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  ../policy.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  back-ends/c++-gen/kwd.h 
+types.o : /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/define.h core/asn1module.h core/snacc-util.h back-ends/str-util.h \
+  back-ends/c++-gen/rules.h back-ends/c++-gen/kwd.h \
+  back-ends/c++-gen/types.h 
+rules.o : ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h back-ends/c++-gen/rules.h 
+gen-code.o : ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  ../policy.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/time.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/time.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/limits.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/limits.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h ../c-lib/inc/print.h \
+  ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h ../c-lib/inc/asn-bool.h \
+  ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h ../c-lib/inc/asn-real.h \
+  ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h ../c-lib/inc/asn-oid.h \
+  ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h ../c-lib/inc/hash.h \
+  ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h core/asn1module.h \
+  core/define.h core/lib-types.h back-ends/c++-gen/rules.h \
+  back-ends/c++-gen/types.h back-ends/cond.h back-ends/str-util.h \
+  core/snacc-util.h core/print.h back-ends/tag-util.h core/meta.h \
+  back-ends/c++-gen/gen-vals.h back-ends/c++-gen/gen-any.h \
+  back-ends/c++-gen/gen-code.h 
+gen-vals.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/oid.h core/define.h core/lib-types.h \
+  back-ends/str-util.h core/snacc-util.h back-ends/c++-gen/rules.h \
+  back-ends/c++-gen/gen-vals.h 
+gen-any.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/define.h back-ends/str-util.h \
+  back-ends/c++-gen/rules.h back-ends/c++-gen/gen-vals.h core/lib-types.h \
+  back-ends/c++-gen/gen-any.h 
+rules.o : ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h back-ends/idl-gen/rules.h 
+types.o : /System/Library/Frameworks/System.framework/Headers/bsd/ctype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/runetype.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/define.h core/asn1module.h core/snacc-util.h back-ends/str-util.h \
+  back-ends/idl-gen/rules.h back-ends/c++-gen/kwd.h \
+  back-ends/idl-gen/types.h 
+gen-any.o : /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/define.h back-ends/str-util.h \
+  back-ends/idl-gen/rules.h back-ends/idl-gen/gen-vals.h core/lib-types.h \
+  back-ends/idl-gen/gen-any.h 
+gen-code.o : ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  ../policy.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/string.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h ../c-lib/inc/print.h \
+  ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h ../c-lib/inc/asn-bool.h \
+  ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h ../c-lib/inc/asn-real.h \
+  ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h ../c-lib/inc/asn-oid.h \
+  ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h ../c-lib/inc/hash.h \
+  ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h core/asn1module.h \
+  core/define.h core/lib-types.h back-ends/idl-gen/rules.h \
+  back-ends/idl-gen/types.h back-ends/cond.h back-ends/str-util.h \
+  core/snacc-util.h core/print.h back-ends/tag-util.h \
+  back-ends/idl-gen/gen-vals.h back-ends/idl-gen/gen-any.h \
+  back-ends/idl-gen/gen-code.h 
+gen-vals.o : \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/asn1module.h core/oid.h core/define.h core/lib-types.h \
+  back-ends/str-util.h core/snacc-util.h back-ends/idl-gen/rules.h \
+  back-ends/idl-gen/gen-vals.h 
+tbl.o : ../c-lib/inc/asn-incl.h ../c-lib/inc/asn-config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdio.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/sys/cdefs.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/types.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/ansi.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/endian.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/setjmp.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/machine/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/ppc/signal.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/math.h \
+  ../snacc.h ../config.h \
+  /System/Library/Frameworks/System.framework/Headers/bsd/stdlib.h \
+  ../policy.h ../c-lib/inc/mem.h ../c-lib/inc/exp-buf.h \
+  ../c-lib/inc/print.h ../c-lib/inc/asn-len.h ../c-lib/inc/asn-tag.h \
+  ../c-lib/inc/asn-bool.h ../c-lib/inc/asn-int.h ../c-lib/inc/asn-enum.h \
+  ../c-lib/inc/asn-real.h ../c-lib/inc/asn-octs.h ../c-lib/inc/asn-bits.h \
+  ../c-lib/inc/asn-oid.h ../c-lib/inc/asn-null.h ../c-lib/inc/asn-any.h \
+  ../c-lib/inc/hash.h ../c-lib/inc/asn-list.h ../c-lib/boot/asn-useful.h \
+  core/tbl.h 
diff --git a/SecuritySNACCRuntime/compiler/install-sh b/SecuritySNACCRuntime/compiler/install-sh
new file mode 100644
index 00000000..ab74c882
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/SecuritySNACCRuntime/compiler/makefile b/SecuritySNACCRuntime/compiler/makefile
new file mode 100644
index 00000000..3f4ce84d
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/makefile
@@ -0,0 +1,386 @@
+# file: .../compiler/makefile
+#
+#	makefile for ASN.1 '88 parser
+#
+#  compiles the snacc ASN.1 compiler
+#
+# Mike Sample
+# 1992
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/makefile,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:08  mb
+# Move from private repository to open source repository
+#
+# Revision 1.2  2000/12/22 01:11:42  dmitch
+# include ../makehead.static to workaround broken autoconf.
+#
+# Revision 1.1.1.1  1999/03/16 18:06:38  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.12  1997/09/03 12:50:33  wan
+# Shifted parse and lex
+#
+# Revision 1.11  1997/03/03 11:58:33  wan
+# Final pre-delivery stuff (I hope).
+#
+# Revision 1.10  1997/02/28 13:39:52  wan
+# Modifications collected for new version 1.3: Bug fixes, tk4.2.
+#
+# Revision 1.9  1997/02/16 18:02:49  rj
+# snacc is needed to generate the distfiles
+#
+# Revision 1.8  1997/02/16 12:34:47  rj
+# let make clobber remove the link to install-sh that make made
+# let make clean remove more created files
+#
+# Revision 1.7  1997/01/02 08:47:20  rj
+# an option to snacc added (when compiling the tbl.asn1 file)
+#
+# Revision 1.6  1995/07/25  18:09:18  rj
+# the compiler is compiled from two files, tbl.h and tbl.c, it generates itself.
+# for bootstrapping purposes, initial versions are supplied with the distribution.
+#
+# `cd && make' instead of `cd; make'.
+#
+# create installation directories only if they do not exist already.
+#
+# the compiler is compiled from two files, tbl.h and tbl.c, it generates itself.
+# for bootstrapping purposes, initial versions are supplied with the distribution.
+#
+# changed `_' to `-' in file names.
+#
+# Revision 1.5  1995/02/20  11:53:57  rj
+# distribute install-sh.
+#
+# Revision 1.4  1995/02/13  15:06:52  rj
+# augment CPPFLAGS, not overwrite.
+# CFLAGS moved to ../makehead.
+#
+# Revision 1.3  1994/10/08  03:47:23  rj
+# added bootstrapping functionality for asn-useful.[ch].
+#
+# Revision 1.2  1994/09/01  00:08:49  rj
+# gnu autoconf stuff added, DISTFILES, install phony target.
+#
+# Revision 1.1  1994/08/28  09:47:52  rj
+# first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
+#
+
+include ../makehead
+include ../makehead.static
+
+TOP		= ..
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+USEFUL_TYPES	= $(ASN1_SRC_DIR)/asn-useful.asn1
+
+CORE_DIR	= core
+BACKEND_DIR	= back-ends
+C_BACKEND_DIR	= $(BACKEND_DIR)/c-gen
+C++_BACKEND_DIR	= $(BACKEND_DIR)/c++-gen
+IDL_BACKEND_DIR	= $(BACKEND_DIR)/idl-gen
+
+ASN1_LIB_DIR	= ../c-lib
+ASN1_INC_DIR	= $(ASN1_LIB_DIR)/inc
+ASN1_BOOT_DIR	= $(ASN1_LIB_DIR)/boot
+ASN1_LIB	= $(ASN1_LIB_DIR)/libasn1cCebuf.a
+
+# some CFLAG options:
+#  -DYYDEBUG use for yacc/lex debug info
+#  -DDEBUG use to get general debug info
+
+DEFS		= -DCOMPILER -DUSE_NIBBLE_MEMORY=0 -DUSE_EXP_BUF
+INCLUDES	= -I$(CORE_DIR) -I$(ASN1_INC_DIR) -I$(ASN1_BOOT_DIR) -I$(BACKEND_DIR) -I$(TOP)
+CPPFLAGS	+= $(DEFS) $(INCLUDES)
+
+compilerFLAGS	= $(DEFS) -I../compiler/$(CORE_DIR)
+
+LFILES	= \
+	$(CORE_DIR)/lex-asn1.l
+LCFILES	= \
+	$(CORE_DIR)/lex-asn1.c
+
+YFILES	= \
+	$(CORE_DIR)/parse-asn1.y
+YHFILES	= \
+	$(CORE_DIR)/parse-asn1.h
+YCFILES	= \
+	$(CORE_DIR)/parse-asn1.c
+
+HFILES.d = \
+	$(CORE_DIR)/asn1module.h	\
+	$(CORE_DIR)/define.h		\
+	$(CORE_DIR)/dependency.h	\
+	$(CORE_DIR)/do-macros.h	\
+	$(CORE_DIR)/err-chk.h		\
+	$(CORE_DIR)/exports.h		\
+	$(CORE_DIR)/gen-tbls.h		\
+	$(CORE_DIR)/lex-stuff.h	\
+	$(CORE_DIR)/lib-types.h	\
+	$(CORE_DIR)/link-types.h	\
+	$(CORE_DIR)/link-values.h	\
+	$(CORE_DIR)/mem.h		\
+	$(CORE_DIR)/meta.h		\
+	$(CORE_DIR)/normalize.h	\
+	$(CORE_DIR)/oid.h		\
+	$(CORE_DIR)/parser.h		\
+	$(CORE_DIR)/print.h		\
+	$(CORE_DIR)/recursive.h	\
+	$(CORE_DIR)/snacc-util.h	\
+	$(CORE_DIR)/tbl.h		\
+	$(CORE_DIR)/val-parser.h	\
+	\
+	$(BACKEND_DIR)/str-util.h	\
+	$(BACKEND_DIR)/tag-util.h	\
+	$(BACKEND_DIR)/cond.h	\
+	\
+	$(C_BACKEND_DIR)/kwd.h		\
+	$(C_BACKEND_DIR)/gen-any.h	\
+	$(C_BACKEND_DIR)/gen-code.h	\
+	$(C_BACKEND_DIR)/gen-dec.h	\
+	$(C_BACKEND_DIR)/gen-enc.h	\
+	$(C_BACKEND_DIR)/gen-free.h	\
+	$(C_BACKEND_DIR)/gen-print.h	\
+	$(C_BACKEND_DIR)/gen-type.h	\
+	$(C_BACKEND_DIR)/gen-vals.h	\
+	$(C_BACKEND_DIR)/rules.h		\
+	$(C_BACKEND_DIR)/type-info.h	\
+	$(C_BACKEND_DIR)/util.h		\
+	\
+	$(C++_BACKEND_DIR)/kwd.h	\
+	$(C++_BACKEND_DIR)/rules.h	\
+	$(C++_BACKEND_DIR)/types.h	\
+	$(C++_BACKEND_DIR)/gen-any.h	\
+	$(C++_BACKEND_DIR)/gen-code.h	\
+	$(C++_BACKEND_DIR)/gen-vals.h	\
+	\
+	$(IDL_BACKEND_DIR)/rules.h	\
+	$(IDL_BACKEND_DIR)/types.h	\
+	$(IDL_BACKEND_DIR)/gen-any.h	\
+	$(IDL_BACKEND_DIR)/gen-code.h	\
+	$(IDL_BACKEND_DIR)/gen-vals.h
+
+HFILES = \
+	$(HFILES.d)		\
+	$(CORE_DIR)/tbl.h
+
+CFILES.d = \
+	$(CORE_DIR)/define.c		\
+	$(CORE_DIR)/dependency.c	\
+	$(CORE_DIR)/do-macros.c		\
+	$(CORE_DIR)/err-chk.c		\
+	$(CORE_DIR)/exports.c		\
+	$(CORE_DIR)/gen-tbls.c		\
+	$(CORE_DIR)/lib-types.c		\
+	$(CORE_DIR)/link-types.c	\
+	$(CORE_DIR)/link-values.c	\
+	$(CORE_DIR)/mem.c		\
+	$(CORE_DIR)/meta.c		\
+	$(CORE_DIR)/normalize.c		\
+	$(CORE_DIR)/oid.c		\
+	$(CORE_DIR)/print.c		\
+	$(CORE_DIR)/recursive.c		\
+	$(CORE_DIR)/snacc.c		\
+	$(CORE_DIR)/snacc-util.c	\
+	$(CORE_DIR)/val-parser.c	\
+	\
+	$(BACKEND_DIR)/str-util.c	\
+	$(BACKEND_DIR)/tag-util.c	\
+	$(BACKEND_DIR)/cond.c		\
+	\
+	$(C_BACKEND_DIR)/type-info.c	\
+	$(C_BACKEND_DIR)/util.c		\
+	$(C_BACKEND_DIR)/rules.c	\
+	$(C_BACKEND_DIR)/gen-code.c	\
+	$(C_BACKEND_DIR)/gen-type.c	\
+	$(C_BACKEND_DIR)/gen-enc.c	\
+	$(C_BACKEND_DIR)/gen-dec.c	\
+	$(C_BACKEND_DIR)/gen-vals.c	\
+	$(C_BACKEND_DIR)/gen-free.c	\
+	$(C_BACKEND_DIR)/gen-print.c	\
+	$(C_BACKEND_DIR)/gen-any.c	\
+	$(C_BACKEND_DIR)/kwd.c		\
+	\
+	$(C++_BACKEND_DIR)/kwd.c	\
+	$(C++_BACKEND_DIR)/types.c	\
+	$(C++_BACKEND_DIR)/rules.c	\
+	$(C++_BACKEND_DIR)/gen-code.c	\
+	$(C++_BACKEND_DIR)/gen-vals.c	\
+	$(C++_BACKEND_DIR)/gen-any.c	\
+	\
+	$(IDL_BACKEND_DIR)/rules.c	\
+	$(IDL_BACKEND_DIR)/types.c	\
+	$(IDL_BACKEND_DIR)/gen-any.c	\
+	$(IDL_BACKEND_DIR)/gen-code.c	\
+	$(IDL_BACKEND_DIR)/gen-vals.c
+
+CFILES = \
+	$(CFILES.d)		\
+	$(CORE_DIR)/tbl.c
+
+OFILES = \
+	$(CORE_DIR)/parse-asn1.o	\
+	$(CORE_DIR)/lex-asn1.o		\
+	\
+	$(CORE_DIR)/link-types.o	\
+	$(CORE_DIR)/exports.o		\
+	$(CORE_DIR)/snacc-util.o	\
+	$(CORE_DIR)/dependency.o	\
+	$(CORE_DIR)/lib-types.o	\
+	$(CORE_DIR)/mem.o		\
+	$(CORE_DIR)/meta.o		\
+	$(CORE_DIR)/print.o		\
+	$(CORE_DIR)/do-macros.o	\
+	$(CORE_DIR)/oid.o		\
+	$(CORE_DIR)/link-values.o	\
+	$(CORE_DIR)/normalize.o	\
+	$(CORE_DIR)/val-parser.o	\
+	$(CORE_DIR)/err-chk.o		\
+	$(CORE_DIR)/define.o		\
+	$(CORE_DIR)/recursive.o	\
+	$(CORE_DIR)/snacc.o		\
+	$(CORE_DIR)/tbl.o		\
+	$(CORE_DIR)/gen-tbls.o		\
+	\
+	$(BACKEND_DIR)/str-util.o	\
+	$(BACKEND_DIR)/tag-util.o	\
+	$(BACKEND_DIR)/cond.o		\
+	\
+	$(C_BACKEND_DIR)/type-info.o	\
+	$(C_BACKEND_DIR)/util.o		\
+	$(C_BACKEND_DIR)/rules.o	\
+	$(C_BACKEND_DIR)/gen-code.o	\
+	$(C_BACKEND_DIR)/gen-type.o	\
+	$(C_BACKEND_DIR)/gen-enc.o	\
+	$(C_BACKEND_DIR)/gen-dec.o	\
+	$(C_BACKEND_DIR)/gen-vals.o	\
+	$(C_BACKEND_DIR)/gen-free.o	\
+	$(C_BACKEND_DIR)/gen-print.o	\
+	$(C_BACKEND_DIR)/gen-any.o	\
+	$(C_BACKEND_DIR)/kwd.o		\
+	\
+	$(C++_BACKEND_DIR)/kwd.o	\
+	$(C++_BACKEND_DIR)/types.o	\
+	$(C++_BACKEND_DIR)/rules.o	\
+	$(C++_BACKEND_DIR)/gen-code.o	\
+	$(C++_BACKEND_DIR)/gen-vals.o	\
+	$(C++_BACKEND_DIR)/gen-any.o	\
+	\
+	$(IDL_BACKEND_DIR)/rules.o	\
+	$(IDL_BACKEND_DIR)/types.o	\
+	$(IDL_BACKEND_DIR)/gen-any.o	\
+	$(IDL_BACKEND_DIR)/gen-code.o	\
+	$(IDL_BACKEND_DIR)/gen-vals.o
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(HFILES.d)	\
+	$(LFILES)	\
+	$(YFILES)	\
+	$(CFILES.d)	\
+	boot/tbl.h	\
+	boot/tbl.c
+
+# end of definitions
+# ----------------------------------------------------------------------
+# rules start here
+
+default::	all
+
+all::		snacc
+
+snacc:		$(OFILES) $(ASN1_LIB)
+		$(REASON)
+		$(CC) $(LDFLAGS) -o snacc $(OFILES) $(ASN1_LIB) $(LEXLIB) $(LIBS)
+
+# compiling with the generated file currently doesn't work!
+# otherwise, one could use the bootstrapping mechanism like for asn-useful.[ch] and tbl.[ch], below
+#	$(CORE_DIR)/asn1module.h:	$(ASN1_SRC_DIR)/asn1module.asn1
+#			./snacc -t -u $(USEFUL_TYPES) $(ASN1_SRC_DIR)/asn1module.asn1
+#	# this file is empty, anyway:
+#			$(RM) asn1module.c
+#			mv asn1module.h $(CORE_DIR)
+
+$(CORE_DIR)/tbl.h	\
+$(CORE_DIR)/tbl.c::
+		$(RM) $(CORE_DIR)/tbl.h $(CORE_DIR)/tbl.c
+		if [ -f snacc ]; then\
+		  $(MAKE) stamp-tbl;\
+		else\
+		  $(RM) tbl.h tbl.c;\
+		  ln boot/tbl.h boot/tbl.c .;\
+		fi
+		ln tbl.h $(CORE_DIR)
+		ln tbl.c $(CORE_DIR)
+
+# `../compiler/snacc' instead of `snacc' or `./snacc' to trick make(1) into believing that both are different files to avoid infinitre recursion:
+stamp-tbl:	../compiler/snacc $(USEFUL_TYPES) $(ASN1_SRC_DIR)/tbl.asn1 makefile
+		$(REASON)
+		-mv tbl.h tbl.h.prev
+		-mv tbl.c tbl.c.prev
+		./snacc -c -t -e -u $(USEFUL_TYPES) $(ASN1_SRC_DIR)/tbl.asn1
+# the dates in the two files will differ, so the files really differ if diff prints more than 4 lines of output:
+		@-if [ -f tbl.h.prev ]; then\
+		  if [ `diff tbl.h.prev tbl.h | wc -l` -gt 4 ]; then\
+		    $(RM) tbl.h.prev;\
+		  else\
+		    echo "tbl.h hasn't changed";\
+		    mv tbl.h.prev tbl.h;\
+		  fi;\
+		fi
+		@-if [ -f tbl.c.prev ]; then\
+		  if [ `diff tbl.c.prev tbl.c | wc -l` -gt 4 ]; then\
+		    $(RM) tbl.c.prev;\
+		  else\
+		    echo "tbl.c hasn't changed";\
+		    mv tbl.c.prev tbl.c;\
+		  fi;\
+		fi
+		date > $@
+
+boot/tbl.h	\
+boot/tbl.c:	stamp-tbl
+		$(RM) boot/tbl.h boot/tbl.c
+		cp -p tbl.h tbl.c boot
+
+# the default rules work for .y.c, but often lack the .h
+$(CORE_DIR)/parse-asn1.h	\
+$(CORE_DIR)/parse-asn1.c:  $(CORE_DIR)/parse-asn1.y
+		$(REASON)
+		@echo "expect 61 shift/reduce and 2 reduce/reduce conflicts"
+		$(YACC) -d $(CORE_DIR)/parse-asn1.y
+		mv y.tab.h $(CORE_DIR)/parse-asn1.h
+		mv y.tab.c $(CORE_DIR)/parse-asn1.c
+
+$(ASN1_LIB)::
+#		cd $(ASN1_LIB_DIR) && $(MAKE) Cebuf-lib compilerFLAGS="$(compilerFLAGS)"
+# since different make versions handle the above line different, we use the more portable passing thru the environment:
+		cd $(ASN1_LIB_DIR) && compilerFLAGS="$(compilerFLAGS)" $(MAKE) Cebuf-lib
+
+install-sh:
+		ln $(TOP)/install-sh $@
+
+install::	snacc install-sh $(bindir)
+
+$(bindir):
+		$(TOP)/mkinstalldirs $@
+
+install::
+		$(INSTALL_PROGRAM) snacc $(bindir)/
+
+clean::
+		$(RM) $(OFILES) $(LCFILES) $(YHFILES) $(YCFILES)
+		$(RM) *.o y.tab.c y.tab.h lex.yy.c y.output .emacs* *~ *.orig *.prev *.bak yacc.tmp yacc.acts yacc.debug
+		$(RM) stamp-tbl tbl.h tbl.h.prev tbl.c tbl.c.prev
+
+clobber::
+		$(RM) snacc
+		$(RM) install-sh
+
+depend::	$(CORE_DIR)/tbl.h $(CORE_DIR)/tbl.c
+
+gen-distfiles::	snacc
+
+include ../maketail
diff --git a/SecuritySNACCRuntime/compiler/stamp-tbl b/SecuritySNACCRuntime/compiler/stamp-tbl
new file mode 100644
index 00000000..27c972b4
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/stamp-tbl
@@ -0,0 +1 @@
+Thu Jun  8 12:35:10 PDT 2000
diff --git a/SecuritySNACCRuntime/compiler/tbl.c b/SecuritySNACCRuntime/compiler/tbl.c
new file mode 100644
index 00000000..f3c49457
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/tbl.c
@@ -0,0 +1,592 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    tbl.c
+ *
+ *    "TBL" ASN.1 module encode/decode/print/free C src.
+ *
+ *    This file was generated by snacc on Thu Jun  8 12:35:09 2000
+ *
+ *    UBC snacc written by Mike Sample
+ *
+ *    NOTE: This is a machine generated file - editing not recommended
+ */
+
+
+
+#include "asn-incl.h"
+#include "tbl.h"
+
+
+AsnLen
+BEncTBLRangeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLRange *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->to));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->from));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLRangeContent */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumber *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->value));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLNamedNumberContent */
+
+
+
+
+AsnLen
+BEncTBLNamedNumberListContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLNamedNumberList *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLNamedNumberListContent */
+
+
+
+
+AsnLen
+BEncTBLTypeRefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeRef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnBoolContent (b, (&v->implicit));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeRefContent */
+
+
+
+
+AsnLen
+BEncTBLTagContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTag *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    itemLen = BEncAsnIntContent (b, (&v->code));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTagClassContent (b, (&v->tclass));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 10);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTagContent */
+
+
+
+
+AsnLen
+BEncTBLTypeSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTagContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContentSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContentSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLTypeContentSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLType *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->values)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLNamedNumberListContent (b, (v->values));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 6);
+
+    totalLen += itemLen;
+    }
+
+    if (NOT_NULL ((v->constraint)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLRangeContent (b, (v->constraint));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 5);
+
+    totalLen += itemLen;
+    }
+
+    if (ASNOCTS_PRESENT ((&v->fieldName)))
+    {
+    itemLen = BEncPrintableStringContent (b, (&v->fieldName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 4);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentContent (b, (v->content));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    if (NOT_NULL ((v->tagList)))
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncAsnBoolContent (b, (&v->optional));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeIdContent (b, (&v->typeId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeContent */
+
+
+
+
+AsnLen
+BEncTBLTypeContentContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeContent *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    switch (v->choiceId)
+    {
+       case TBLTYPECONTENT_PRIMTYPE:
+    itemLen = BEncAsnNullContent (b, (&v->a.primType));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_ELMTS:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 1);
+
+    totalLen += itemLen;
+
+    break;
+
+       case TBLTYPECONTENT_TYPEREF:
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 2);
+
+    totalLen += itemLen;
+
+    break;
+
+    }
+    return totalLen;
+
+}  /* BEncTBLTypeContentContent */
+
+
+
+
+AsnLen
+BEncTBLTypeDefContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLTypeDef *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    if (NOT_NULL ((v->isPdu)))
+    {
+    itemLen = BEncAsnNullContent (b, (v->isPdu));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 5);
+
+    totalLen += itemLen;
+    }
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeContent (b, (v->type));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncPrintableStringContent (b, (&v->typeName));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, PRIM, 19);
+
+    totalLen += itemLen;
+
+    itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLTypeDefContent */
+
+
+
+
+AsnLen
+BEncTBLModuleSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModuleSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLTypeDefContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLModuleSeqOfContent */
+
+
+
+
+AsnLen
+BEncTBLModuleContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLModule *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, CONS, 3);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnBoolContent (b, (&v->isUseful));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, CNTX, PRIM, 2);
+
+    totalLen += itemLen;
+
+    if (ASNOID_PRESENT ((&v->id)))
+    {
+    itemLen = BEncAsnOidContent (b, (&v->id));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 1);
+
+    totalLen += itemLen;
+    }
+
+    itemLen = BEncPrintableStringContent (b, (&v->name));
+    itemLen += BEncDefLen (b, itemLen);
+    itemLen += BEncTag1 (b, CNTX, PRIM, 0);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLModuleContent */
+
+
+
+
+AsnLen
+BEncTBLSeqOfContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBLSeqOf *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+        listLen = 0;
+    FOR_EACH_LIST_ELMT_RVS (component, v)
+    {
+    BEncEocIfNec (b);
+    itemLen = BEncTBLModuleContent (b, component);
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+        listLen += itemLen;
+    }
+    return listLen;
+
+}  /* BEncTBLSeqOfContent */
+
+
+
+
+AsnLen BEncTBL PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen l;
+    BEncEocIfNec (b);
+    l = BEncTBLContent (b, v);
+    l += BEncConsLen (b, l);
+    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
+    return l;
+} /* BEncTBL */
+
+AsnLen
+BEncTBLContent PARAMS ((b, v),
+BUF_TYPE b _AND_
+TBL *v)
+{
+    AsnLen totalLen = 0;
+    AsnLen itemLen;
+    AsnLen listLen;
+    void *component;
+
+    BEncEocIfNec (b);
+    itemLen = BEncTBLSeqOfContent (b, (v->modules));
+    itemLen += BEncConsLen (b, itemLen);
+    itemLen += BEncTag1 (b, UNIV, CONS, 16);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalLenStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumStrings));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTags));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypes));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    itemLen = BEncAsnIntContent (b, (&v->totalNumModules));
+    BEncDefLenTo127 (b, itemLen);
+    itemLen++;
+    itemLen += BEncTag1 (b, UNIV, PRIM, 2);
+
+    totalLen += itemLen;
+
+    return totalLen;
+
+}  /* BEncTBLContent */
+
+
+
+
diff --git a/SecuritySNACCRuntime/compiler/tbl.h b/SecuritySNACCRuntime/compiler/tbl.h
new file mode 100644
index 00000000..ac96eddd
--- /dev/null
+++ b/SecuritySNACCRuntime/compiler/tbl.h
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *    tbl.h
+ *
+ *    "TBL" ASN.1 module C type definitions and prototypes
+ *
+ *    This .h file was generated by snacc on Thu Jun  8 12:35:09 2000
+ *
+ *    UBC snacc written compiler by Mike Sample
+ *
+ *    NOTE: This is a machine generated file--editing not recommended
+ */
+
+
+#ifndef _tbl_h_
+#define _tbl_h_
+
+
+
+
+typedef enum
+    {
+        TBL_BOOLEAN = 0,
+        TBL_INTEGER = 1,
+        TBL_BITSTRING = 2,
+        TBL_OCTETSTRING = 3,
+        TBL_NULL = 4,
+        TBL_OID = 5,
+        TBL_REAL = 6,
+        TBL_ENUMERATED = 7,
+        TBL_SEQUENCE = 8,
+        TBL_SET = 9,
+        TBL_SEQUENCEOF = 10,
+        TBL_SETOF = 11,
+        TBL_CHOICE = 12,
+        TBL_TYPEREF = 13
+    } TBLTypeId; /* ENUMERATED { TBL_BOOLEAN (0), TBL_INTEGER (1), TBL_BITSTRING (2), TBL_OCTETSTRING (3), TBL_NULL (4), TBL_OID (5), TBL_REAL (6), TBL_ENUMERATED (7), TBL_SEQUENCE (8), TBL_SET (9), TBL_SEQUENCEOF (10), TBL_SETOF (11), TBL_CHOICE (12), TBL_TYPEREF (13) }  */
+
+#define BEncTBLTypeIdContent BEncAsnEnumContent
+
+
+
+
+typedef AsnInt TBLTypeDefId; /* INTEGER */
+
+#define BEncTBLTypeDefIdContent BEncAsnIntContent
+
+
+
+
+typedef enum
+    {
+        UNIVERSAL = 0,
+        APPLICATION = 1,
+        CONTEXT = 2,
+        PRIVATE = 3
+    } TBLTagClass; /* ENUMERATED { UNIVERSAL (0), APPLICATION (1), CONTEXT (2), PRIVATE (3) }  */
+
+#define BEncTBLTagClassContent BEncAsnEnumContent
+
+
+
+
+typedef struct TBLRange /* SEQUENCE */
+{
+    AsnInt from; /* [0] IMPLICIT INTEGER */
+    AsnInt to; /* [1] IMPLICIT INTEGER */
+} TBLRange;
+
+AsnLen BEncTBLRangeContent PROTO ((BUF_TYPE b, TBLRange *v));
+
+
+
+
+typedef struct TBLNamedNumber /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnInt value; /* [1] IMPLICIT INTEGER */
+} TBLNamedNumber;
+
+AsnLen BEncTBLNamedNumberContent PROTO ((BUF_TYPE b, TBLNamedNumber *v));
+
+
+
+
+typedef AsnList TBLNamedNumberList; /* SEQUENCE OF TBLNamedNumber */
+
+AsnLen BEncTBLNamedNumberListContent PROTO ((BUF_TYPE b, TBLNamedNumberList *v));
+
+
+
+
+typedef struct TBLTypeRef /* SEQUENCE */
+{
+    TBLTypeDefId typeDef; /* TBLTypeDefId */
+    AsnBool implicit; /* BOOLEAN */
+} TBLTypeRef;
+
+AsnLen BEncTBLTypeRefContent PROTO ((BUF_TYPE b, TBLTypeRef *v));
+
+
+
+
+typedef struct TBLTag /* SEQUENCE */
+{
+    TBLTagClass tclass; /* TBLTagClass */
+    AsnInt code; /* INTEGER (0..MAX) */
+} TBLTag;
+
+AsnLen BEncTBLTagContent PROTO ((BUF_TYPE b, TBLTag *v));
+
+
+
+
+typedef AsnList TBLTypeSeqOf; /* SEQUENCE OF TBLTag */
+
+AsnLen BEncTBLTypeSeqOfContent PROTO ((BUF_TYPE b, TBLTypeSeqOf *v));
+
+
+
+
+typedef AsnList TBLTypeContentSeqOf; /* SEQUENCE OF TBLType */
+
+AsnLen BEncTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, TBLTypeContentSeqOf *v));
+
+
+
+
+typedef struct TBLType /* SEQUENCE */
+{
+    TBLTypeId typeId; /* [0] IMPLICIT TBLTypeId */
+    AsnBool optional; /* [1] IMPLICIT BOOLEAN */
+    TBLTypeSeqOf* tagList; /* [2] IMPLICIT TBLTypeSeqOf OPTIONAL */
+    struct TBLTypeContent* content; /* [3] TBLTypeContent */
+    PrintableString fieldName; /* [4] IMPLICIT PrintableString OPTIONAL */
+    struct TBLRange* constraint; /* [5] IMPLICIT TBLRange OPTIONAL */
+    TBLNamedNumberList* values; /* [6] IMPLICIT TBLNamedNumberList OPTIONAL */
+} TBLType;
+
+AsnLen BEncTBLTypeContent PROTO ((BUF_TYPE b, TBLType *v));
+
+
+
+
+typedef struct TBLTypeContent /* CHOICE */
+{
+    enum TBLTypeContentChoiceId
+    {
+        TBLTYPECONTENT_PRIMTYPE,
+        TBLTYPECONTENT_ELMTS,
+        TBLTYPECONTENT_TYPEREF
+    } choiceId;
+    union TBLTypeContentChoiceUnion
+    {
+    AsnNull primType; /* [0] IMPLICIT NULL */
+    TBLTypeContentSeqOf* elmts; /* [1] IMPLICIT TBLTypeContentSeqOf */
+    struct TBLTypeRef* typeRef; /* [2] IMPLICIT TBLTypeRef */
+    } a;
+} TBLTypeContent;
+
+AsnLen BEncTBLTypeContentContent PROTO ((BUF_TYPE b, TBLTypeContent *v));
+
+
+
+
+typedef struct TBLTypeDef /* SEQUENCE */
+{
+    TBLTypeDefId typeDefId; /* TBLTypeDefId */
+    PrintableString typeName; /* PrintableString */
+    struct TBLType* type; /* TBLType */
+    AsnNull* isPdu; /* NULL OPTIONAL */
+} TBLTypeDef;
+
+AsnLen BEncTBLTypeDefContent PROTO ((BUF_TYPE b, TBLTypeDef *v));
+
+
+
+
+typedef AsnList TBLModuleSeqOf; /* SEQUENCE OF TBLTypeDef */
+
+AsnLen BEncTBLModuleSeqOfContent PROTO ((BUF_TYPE b, TBLModuleSeqOf *v));
+
+
+
+
+typedef struct TBLModule /* SEQUENCE */
+{
+    PrintableString name; /* [0] IMPLICIT PrintableString */
+    AsnOid id; /* [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL */
+    AsnBool isUseful; /* [2] IMPLICIT BOOLEAN */
+    TBLModuleSeqOf* typeDefs; /* [3] IMPLICIT TBLModuleSeqOf */
+} TBLModule;
+
+AsnLen BEncTBLModuleContent PROTO ((BUF_TYPE b, TBLModule *v));
+
+
+
+
+typedef AsnList TBLSeqOf; /* SEQUENCE OF TBLModule */
+
+AsnLen BEncTBLSeqOfContent PROTO ((BUF_TYPE b, TBLSeqOf *v));
+
+
+
+
+typedef struct TBL /* SEQUENCE */
+{
+    AsnInt totalNumModules; /* INTEGER */
+    AsnInt totalNumTypeDefs; /* INTEGER */
+    AsnInt totalNumTypes; /* INTEGER */
+    AsnInt totalNumTags; /* INTEGER */
+    AsnInt totalNumStrings; /* INTEGER */
+    AsnInt totalLenStrings; /* INTEGER */
+    TBLSeqOf* modules; /* TBLSeqOf */
+} TBL;
+
+AsnLen BEncTBL PROTO ((BUF_TYPE b, TBL *v));
+
+AsnLen BEncTBLContent PROTO ((BUF_TYPE b, TBL *v));
+
+
+
+
+
+#endif /* conditional include of tbl.h */
diff --git a/SecuritySNACCRuntime/config.cache b/SecuritySNACCRuntime/config.cache
new file mode 100644
index 00000000..cfe49c35
--- /dev/null
+++ b/SecuritySNACCRuntime/config.cache
@@ -0,0 +1,63 @@
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+ac_cv_c_const=${ac_cv_c_const=yes}
+ac_cv_func_finite=${ac_cv_func_finite=yes}
+ac_cv_func_isinf=${ac_cv_func_isinf=yes}
+ac_cv_func_memcmp=${ac_cv_func_memcmp=yes}
+ac_cv_func_memcpy=${ac_cv_func_memcpy=yes}
+ac_cv_func_memset=${ac_cv_func_memset=yes}
+ac_cv_func_vprintf=${ac_cv_func_vprintf=yes}
+ac_cv_have_x=${ac_cv_have_x='have_x=no'}
+ac_cv_header_dirent_dirent_h=${ac_cv_header_dirent_dirent_h=yes}
+ac_cv_header_fcntl_h=${ac_cv_header_fcntl_h=yes}
+ac_cv_header_malloc_h=${ac_cv_header_malloc_h=no}
+ac_cv_header_memory_h=${ac_cv_header_memory_h=yes}
+ac_cv_header_stdc=${ac_cv_header_stdc=yes}
+ac_cv_header_string_h=${ac_cv_header_string_h=yes}
+ac_cv_header_time=${ac_cv_header_time=yes}
+ac_cv_header_unistd_h=${ac_cv_header_unistd_h=yes}
+ac_cv_lib_dir_opendir=${ac_cv_lib_dir_opendir=no}
+ac_cv_lib_fl_yywrap=${ac_cv_lib_fl_yywrap=no}
+ac_cv_lib_m_sin=${ac_cv_lib_m_sin=no}
+ac_cv_path_install=${ac_cv_path_install='/usr/bin/install -c'}
+ac_cv_prog_AR=${ac_cv_prog_AR=ar}
+ac_cv_prog_CC=${ac_cv_prog_CC=cc}
+ac_cv_prog_CPP=${ac_cv_prog_CPP='cc -E -traditional-cpp'}
+ac_cv_prog_CXX=${ac_cv_prog_CXX=c++}
+ac_cv_prog_LEX=${ac_cv_prog_LEX=flex}
+ac_cv_prog_MKDEP=${ac_cv_prog_MKDEP=mkdep}
+ac_cv_prog_PATCH=${ac_cv_prog_PATCH=patch}
+ac_cv_prog_RANLIB=${ac_cv_prog_RANLIB=ranlib}
+ac_cv_prog_YACC=${ac_cv_prog_YACC='bison -y'}
+ac_cv_prog_cc_cc_c_o=${ac_cv_prog_cc_cc_c_o=yes}
+ac_cv_prog_cc_cross=${ac_cv_prog_cc_cross=no}
+ac_cv_prog_cc_g=${ac_cv_prog_cc_g=yes}
+ac_cv_prog_cc_works=${ac_cv_prog_cc_works=yes}
+ac_cv_prog_cxx_cross=${ac_cv_prog_cxx_cross=no}
+ac_cv_prog_cxx_g=${ac_cv_prog_cxx_g=yes}
+ac_cv_prog_cxx_works=${ac_cv_prog_cxx_works=yes}
+ac_cv_prog_gcc=${ac_cv_prog_gcc=yes}
+ac_cv_prog_gcc_traditional=${ac_cv_prog_gcc_traditional=no}
+ac_cv_prog_gxx=${ac_cv_prog_gxx=yes}
+ac_cv_prog_lex_root=${ac_cv_prog_lex_root=lex.yy}
+ac_cv_prog_lex_yytext_pointer=${ac_cv_prog_lex_yytext_pointer=no}
+ac_cv_prog_make_make_set=${ac_cv_prog_make_make_set=yes}
+ac_cv_sizeof_double=${ac_cv_sizeof_double=8}
+ac_cv_sizeof_int=${ac_cv_sizeof_int=4}
+ac_cv_sizeof_long=${ac_cv_sizeof_long=4}
+ac_cv_sizeof_short=${ac_cv_sizeof_short=2}
+ac_cv_type_size_t=${ac_cv_type_size_t=yes}
+ac_cv_type_uid_t=${ac_cv_type_uid_t=yes}
diff --git a/SecuritySNACCRuntime/config.h b/SecuritySNACCRuntime/config.h
new file mode 100644
index 00000000..33b8a726
--- /dev/null
+++ b/SecuritySNACCRuntime/config.h
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+
+
+/* config.h.  Generated automatically by configure.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef gid_t */
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have the vprintf function.  */
+#define HAVE_VPRINTF 1
+
+/* Define if your C compiler doesn't accept -c and -o together.  */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Define if you need to in order for stat and other things to work.  */
+/* #undef _POSIX_SOURCE */
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef uid_t */
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#define WORDS_BIGENDIAN 1
+
+/* Define if the X Window System is missing or not being used.  */
+#define X_DISPLAY_MISSING 1
+
+/* Define if lex declares yytext as a char * by default, not a char[].  */
+/* #undef YYTEXT_POINTER */
+
+/*
+ * file: acconfig.h
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/config.h,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+ * $Log: config.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:04  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.5  2001/05/05 00:59:16  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.4  2000/12/21 23:56:19  dmitch
+ * Misc. updates for clean build on Cheetah 1D7.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:05:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.7  1997/03/03 11:58:26  wan
+ * Final pre-delivery stuff (I hope).
+ *
+ * Revision 1.6  1997/02/28 13:39:34  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.5  1997/02/15 20:01:37  rj
+ * check whether the compiler supports volatile functions (and whether abort() is volatile).
+ *
+ * Revision 1.4  1995/02/20  11:16:57  rj
+ * cpp switch HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS added.
+ *
+ * Revision 1.3  1995/02/13  14:46:49  rj
+ * settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h.
+ *
+ * Revision 1.2  1994/10/08  04:38:56  rj
+ * slot for autoconf Tcl detection added.
+ *
+ * Revision 1.1  1994/09/01  00:51:19  rj
+ * first check-in (new file).
+ *
+ */
+
+/*
+ * define IEEE_REAL_FMT if your system/compiler uses the native ieee double
+ * this should improve the performance of encoding reals.
+ * If your system has the IEEE library routines (iszero, isinf etc)
+ * then define IEEE_REAL_LIB.  If neither are defined then
+ * frexp is used.  Performance is probaby best for IEEE_REAL_FMT.
+ *
+ *  #define IEEE_REAL_FMT
+ *  #define IEEE_REAL_LIB
+ */
+/* use ANSI or K&R style C? */
+#define __USE_ANSI_C__ 1
+
+/* does the C++ compiler have the bool type built-in? */
+#define BOOL_BUILTIN 1
+
+/* does the C++ compiler allow variable sized automatic arryas? */
+#define HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS 1
+
+/* do we have all the libs we need for the Tcl interface? */
+/* #undef HAVE_TCL */
+
+/* does the compiler support volatile functions (and is abort() volatile?) */
+/* #undef COMPILER_WITHOUT_VOLATILE_FUNCTIONS */
+
+/* The number of bytes in a double.  */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long.  */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a short.  */
+#define SIZEOF_SHORT 2
+
+/* Define if you have the finite function.  */
+#define HAVE_FINITE 1
+
+/* Define if you have the isinf function.  */
+#define HAVE_ISINF 1
+
+/* Define if you have the memcmp function.  */
+#define HAVE_MEMCMP 1
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memset function.  */
+#define HAVE_MEMSET 1
+
+/* Define if you have the <dirent.h> header file.  */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <malloc.h> header file.  */
+/* #undef HAVE_MALLOC_H */
+
+/* Define if you have the <memory.h> header file.  */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <ndir.h> header file.  */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <string.h> header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file.  */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file.  */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the m library (-lm).  */
+/* #undef HAVE_LIBM */
diff --git a/SecuritySNACCRuntime/config.h.in b/SecuritySNACCRuntime/config.h.in
new file mode 100644
index 00000000..5f38ded7
--- /dev/null
+++ b/SecuritySNACCRuntime/config.h.in
@@ -0,0 +1,160 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef gid_t
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define if your C compiler doesn't accept -c and -o together.  */
+#undef NO_MINUS_C_MINUS_O
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef uid_t
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+/* Define if the X Window System is missing or not being used.  */
+#undef X_DISPLAY_MISSING
+
+/* Define if lex declares yytext as a char * by default, not a char[].  */
+#undef YYTEXT_POINTER
+
+/*
+ * file: acconfig.h
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/config.h.in,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+ * $Log: config.h.in,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:04  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.3  2000/12/21 23:56:34  dmitch
+ * Misc. updates for clean build on Cheetah 1D7.
+ *
+ * Revision 1.1.1.1  1999/03/16 18:05:47  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.7  1997/03/03 11:58:26  wan
+ * Final pre-delivery stuff (I hope).
+ *
+ * Revision 1.6  1997/02/28 13:39:34  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.5  1997/02/15 20:01:37  rj
+ * check whether the compiler supports volatile functions (and whether abort() is volatile).
+ *
+ * Revision 1.4  1995/02/20  11:16:57  rj
+ * cpp switch HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS added.
+ *
+ * Revision 1.3  1995/02/13  14:46:49  rj
+ * settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h.
+ *
+ * Revision 1.2  1994/10/08  04:38:56  rj
+ * slot for autoconf Tcl detection added.
+ *
+ * Revision 1.1  1994/09/01  00:51:19  rj
+ * first check-in (new file).
+ *
+ */
+
+/*
+ * define IEEE_REAL_FMT if your system/compiler uses the native ieee double
+ * this should improve the performance of encoding reals.
+ * If your system has the IEEE library routines (iszero, isinf etc)
+ * then define IEEE_REAL_LIB.  If neither are defined then
+ * frexp is used.  Performance is probaby best for IEEE_REAL_FMT.
+ *
+ *  #define IEEE_REAL_FMT
+ *  #define IEEE_REAL_LIB
+ */
+/* use ANSI or K&R style C? */
+#undef __USE_ANSI_C__
+
+/* does the C++ compiler have the bool type built-in? */
+#undef BOOL_BUILTIN
+
+/* does the C++ compiler allow variable sized automatic arryas? */
+#undef HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS
+
+/* do we have all the libs we need for the Tcl interface? */
+#undef HAVE_TCL
+
+/* does the compiler support volatile functions (and is abort() volatile?) */
+#undef COMPILER_WITHOUT_VOLATILE_FUNCTIONS
+
+/* The number of bytes in a double.  */
+#undef SIZEOF_DOUBLE
+
+/* The number of bytes in a int.  */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long.  */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a short.  */
+#undef SIZEOF_SHORT
+
+/* Define if you have the finite function.  */
+#undef HAVE_FINITE
+
+/* Define if you have the isinf function.  */
+#undef HAVE_ISINF
+
+/* Define if you have the memcmp function.  */
+#undef HAVE_MEMCMP
+
+/* Define if you have the memcpy function.  */
+#undef HAVE_MEMCPY
+
+/* Define if you have the memset function.  */
+#undef HAVE_MEMSET
+
+/* Define if you have the <dirent.h> header file.  */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <malloc.h> header file.  */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <memory.h> header file.  */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <ndir.h> header file.  */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <string.h> header file.  */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/dir.h> header file.  */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ndir.h> header file.  */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the m library (-lm).  */
+#undef HAVE_LIBM
diff --git a/SecuritySNACCRuntime/config.log b/SecuritySNACCRuntime/config.log
new file mode 100644
index 00000000..10601e2c
--- /dev/null
+++ b/SecuritySNACCRuntime/config.log
@@ -0,0 +1,76 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+configure:529: checking whether make sets ${MAKE}
+configure:558: checking for gcc
+configure:671: checking whether the C compiler (cc -DMACOS -DYYTEXT_POINTER ) works
+configure:687: cc -o conftest -DMACOS -DYYTEXT_POINTER   conftest.c  1>&5
+configure:713: checking whether the C compiler (cc -DMACOS -DYYTEXT_POINTER ) is a cross-compiler
+configure:718: checking whether we are using GNU C
+configure:746: checking whether cc accepts -g
+configure:778: checking for POSIXized ISC
+configure:802: checking for cc's include path
+configure:811: checking how to run the C preprocessor
+configure:892: checking whether cc needs -traditional
+configure:942: checking whether cc understands -c and -o together
+configure:993: checking whether ANSI or K&R style C
+configure:1002: cc -o conftest -DMACOS -DYYTEXT_POINTER   conftest.c  1>&5
+configure:1022: checking for c++
+configure:1054: checking whether the C++ compiler (c++  ) works
+configure:1070: c++ -o conftest    conftest.C  1>&5
+configure:1096: checking whether the C++ compiler (c++  ) is a cross-compiler
+configure:1101: checking whether we are using GNU C++
+configure:1129: checking whether c++ accepts -g
+configure:1168: checking for bool built-in
+configure:1177: c++ -c -g -O2  conftest.C 1>&5
+configure:1191: checking for variable sized automatic arrays
+configure:1200: c++ -c -g -O2  conftest.C 1>&5
+configure:1214: checking for volatile functions
+configure:1223: c++ -c -g -O2  conftest.C 1>&5
+configure:1246: checking for flex
+configure:1322: checking lex output file root
+configure:1343: checking whether yytext is a pointer
+configure:1398: checking for patch
+configure:1433: checking for bison
+configure:1468: checking for makedepend
+configure:1503: checking for ar
+configure:1536: checking for ranlib
+configure:1594: checking for a BSD compatible install
+configure:1647: checking whether time.h and sys/time.h may both be included
+configure:1686: checking for dirent.h that defines DIR
+configure:1724: checking for opendir in -ldir
+configure:1807: checking for ANSI C header files
+configure:1911: checking for size_t
+configure:1944: checking for uid_t in sys/types.h
+configure:1978: checking for ANSI C header files
+configure:2085: checking for unistd.h
+configure:2085: checking for memory.h
+configure:2085: checking for string.h
+configure:2085: checking for malloc.h
+configure:2085: checking for fcntl.h
+configure:2122: checking for vprintf
+configure:2227: checking for working const
+configure:2302: checking whether byte ordering is bigendian
+configure:2392: checking size of short
+configure:2431: checking size of int
+configure:2470: checking size of long
+configure:2509: checking size of double
+configure:2548: checking for sin in -lm
+configure:2597: checking for isinf
+configure:2597: checking for finite
+configure:2652: checking for memset
+configure:2652: checking for memcpy
+configure:2652: checking for memcmp
+configure:2709: checking for X
+configure:3543: checking for tclsh
+configure:3800: checking for latex
+configure:3835: checking for bibtex
+configure:3870: checking for dvips
+configure:3905: checking for detex2
+configure:3905: checking for detex
+configure:3940: checking for ghostview
+configure:3940: checking for gs
+configure:3975: checking for psbook
+configure:4010: checking for psnup
+configure:4045: checking for ispell
+configure:4045: checking for spell
diff --git a/SecuritySNACCRuntime/config.status b/SecuritySNACCRuntime/config.status
new file mode 100644
index 00000000..20be1ebd
--- /dev/null
+++ b/SecuritySNACCRuntime/config.status
@@ -0,0 +1,350 @@
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host dougsx:
+#
+# ./configure 
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: ./config.status [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running ${CONFIG_SHELL-/bin/sh} ./configure  --no-create --no-recursion"
+    exec ${CONFIG_SHELL-/bin/sh} ./configure  --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "./config.status generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "$ac_cs_usage"; exit 0 ;;
+  *) echo "$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=.
+ac_given_INSTALL="/usr/bin/install -c"
+
+trap 'rm -fr makehead config.h conftest*; exit 1' 1 2 15
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\&%]/\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+/^[ 	]*VPATH[ 	]*=[^:]*$/d
+
+s%@SHELL@%/bin/sh%g
+s%@CFLAGS@%-DMACOS -DYYTEXT_POINTER -DFLEX_IN_USE%g
+s%@CPPFLAGS@%%g
+s%@CXXFLAGS@%-g -O2%g
+s%@FFLAGS@%%g
+s%@DEFS@%-DHAVE_CONFIG_H%g
+s%@LDFLAGS@%%g
+s%@LIBS@%%g
+s%@exec_prefix@%${prefix}%g
+s%@prefix@%/usr/local%g
+s%@program_transform_name@%s,x,x,%g
+s%@bindir@%${exec_prefix}/bin%g
+s%@sbindir@%${exec_prefix}/sbin%g
+s%@libexecdir@%${exec_prefix}/libexec%g
+s%@datadir@%${prefix}/share%g
+s%@sysconfdir@%${prefix}/etc%g
+s%@sharedstatedir@%${prefix}/com%g
+s%@localstatedir@%${prefix}/var%g
+s%@libdir@%${exec_prefix}/lib%g
+s%@includedir@%${prefix}/include%g
+s%@oldincludedir@%/usr/include%g
+s%@infodir@%${prefix}/info%g
+s%@mandir@%${prefix}/man%g
+s%@SET_MAKE@%%g
+s%@CC@%cc%g
+s%@MKDEP_CCINC@%-I/usr/local/include -I/usr/libexec/ppc/2.95.2
+/usr/libexec/ppc/include -F/System/Library/PrivateFrameworks%g
+s%@CPP@%cc -E -traditional-cpp%g
+s%@CXX@%c++%g
+s%@SNACC_NOVOLAT@%%g
+s%@LEX@%flex%g
+s%@LEXLIB@%-ll%g
+s%@LEX_OUTPUT_ROOT@%lex.yy%g
+s%@LFLAGS@%%g
+s%@PATCH@%patch%g
+s%@YACC@%bison -y%g
+s%@MKDEP@%mkdep%g
+s%@AR@%ar%g
+s%@RANLIB@%ranlib%g
+s%@INSTALL_PROGRAM@%${INSTALL}%g
+s%@INSTALL_SCRIPT@%${INSTALL_PROGRAM}%g
+s%@INSTALL_DATA@%${INSTALL} -m 644%g
+s%@X_CFLAGS@%%g
+s%@X_PRE_LIBS@%%g
+s%@X_LIBS@%%g
+s%@X_EXTRA_LIBS@%%g
+s%@TCLSH@%false%g
+s%@TCLLIBS@%%g
+s%@TREELIBS@%%g
+s%@LATEX@%false%g
+s%@BIBTEX@%false%g
+s%@DVIPS@%false%g
+s%@DETEX@%false%g
+s%@PSPREVIEW@%true%g
+s%@PSBOOK@%false%g
+s%@PSNUP@%false%g
+s%@SPELL@%spell%g
+
+CEOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+
+CONFIG_FILES=${CONFIG_FILES-"makehead"}
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+  CONFIG_HEADERS="config.h"
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+  cat > conftest.frag <<CEOF
+${ac_dA}__USE_ANSI_C__${ac_dB}__USE_ANSI_C__${ac_dC}1${ac_dD}
+${ac_uA}__USE_ANSI_C__${ac_uB}__USE_ANSI_C__${ac_uC}1${ac_uD}
+${ac_eA}__USE_ANSI_C__${ac_eB}__USE_ANSI_C__${ac_eC}1${ac_eD}
+${ac_dA}BOOL_BUILTIN${ac_dB}BOOL_BUILTIN${ac_dC}1${ac_dD}
+${ac_uA}BOOL_BUILTIN${ac_uB}BOOL_BUILTIN${ac_uC}1${ac_uD}
+${ac_eA}BOOL_BUILTIN${ac_eB}BOOL_BUILTIN${ac_eC}1${ac_eD}
+${ac_dA}HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS${ac_dB}HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS${ac_dC}1${ac_dD}
+${ac_uA}HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS${ac_uB}HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS${ac_uC}1${ac_uD}
+${ac_eA}HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS${ac_eB}HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS${ac_eC}1${ac_eD}
+${ac_dA}TIME_WITH_SYS_TIME${ac_dB}TIME_WITH_SYS_TIME${ac_dC}1${ac_dD}
+${ac_uA}TIME_WITH_SYS_TIME${ac_uB}TIME_WITH_SYS_TIME${ac_uC}1${ac_uD}
+${ac_eA}TIME_WITH_SYS_TIME${ac_eB}TIME_WITH_SYS_TIME${ac_eC}1${ac_eD}
+CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+
+  cat > conftest.frag <<CEOF
+${ac_dA}HAVE_DIRENT_H${ac_dB}HAVE_DIRENT_H${ac_dC}1${ac_dD}
+${ac_uA}HAVE_DIRENT_H${ac_uB}HAVE_DIRENT_H${ac_uC}1${ac_uD}
+${ac_eA}HAVE_DIRENT_H${ac_eB}HAVE_DIRENT_H${ac_eC}1${ac_eD}
+${ac_dA}STDC_HEADERS${ac_dB}STDC_HEADERS${ac_dC}1${ac_dD}
+${ac_uA}STDC_HEADERS${ac_uB}STDC_HEADERS${ac_uC}1${ac_uD}
+${ac_eA}STDC_HEADERS${ac_eB}STDC_HEADERS${ac_eC}1${ac_eD}
+${ac_dA}STDC_HEADERS${ac_dB}STDC_HEADERS${ac_dC}1${ac_dD}
+${ac_uA}STDC_HEADERS${ac_uB}STDC_HEADERS${ac_uC}1${ac_uD}
+${ac_eA}STDC_HEADERS${ac_eB}STDC_HEADERS${ac_eC}1${ac_eD}
+${ac_dA}HAVE_UNISTD_H${ac_dB}HAVE_UNISTD_H${ac_dC}1${ac_dD}
+${ac_uA}HAVE_UNISTD_H${ac_uB}HAVE_UNISTD_H${ac_uC}1${ac_uD}
+${ac_eA}HAVE_UNISTD_H${ac_eB}HAVE_UNISTD_H${ac_eC}1${ac_eD}
+CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+
+  cat > conftest.frag <<CEOF
+${ac_dA}HAVE_MEMORY_H${ac_dB}HAVE_MEMORY_H${ac_dC}1${ac_dD}
+${ac_uA}HAVE_MEMORY_H${ac_uB}HAVE_MEMORY_H${ac_uC}1${ac_uD}
+${ac_eA}HAVE_MEMORY_H${ac_eB}HAVE_MEMORY_H${ac_eC}1${ac_eD}
+${ac_dA}HAVE_STRING_H${ac_dB}HAVE_STRING_H${ac_dC}1${ac_dD}
+${ac_uA}HAVE_STRING_H${ac_uB}HAVE_STRING_H${ac_uC}1${ac_uD}
+${ac_eA}HAVE_STRING_H${ac_eB}HAVE_STRING_H${ac_eC}1${ac_eD}
+${ac_dA}HAVE_FCNTL_H${ac_dB}HAVE_FCNTL_H${ac_dC}1${ac_dD}
+${ac_uA}HAVE_FCNTL_H${ac_uB}HAVE_FCNTL_H${ac_uC}1${ac_uD}
+${ac_eA}HAVE_FCNTL_H${ac_eB}HAVE_FCNTL_H${ac_eC}1${ac_eD}
+${ac_dA}HAVE_VPRINTF${ac_dB}HAVE_VPRINTF${ac_dC}1${ac_dD}
+${ac_uA}HAVE_VPRINTF${ac_uB}HAVE_VPRINTF${ac_uC}1${ac_uD}
+${ac_eA}HAVE_VPRINTF${ac_eB}HAVE_VPRINTF${ac_eC}1${ac_eD}
+CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+
+  cat > conftest.frag <<CEOF
+${ac_dA}WORDS_BIGENDIAN${ac_dB}WORDS_BIGENDIAN${ac_dC}1${ac_dD}
+${ac_uA}WORDS_BIGENDIAN${ac_uB}WORDS_BIGENDIAN${ac_uC}1${ac_uD}
+${ac_eA}WORDS_BIGENDIAN${ac_eB}WORDS_BIGENDIAN${ac_eC}1${ac_eD}
+${ac_dA}SIZEOF_SHORT${ac_dB}SIZEOF_SHORT${ac_dC}2${ac_dD}
+${ac_uA}SIZEOF_SHORT${ac_uB}SIZEOF_SHORT${ac_uC}2${ac_uD}
+${ac_eA}SIZEOF_SHORT${ac_eB}SIZEOF_SHORT${ac_eC}2${ac_eD}
+${ac_dA}SIZEOF_INT${ac_dB}SIZEOF_INT${ac_dC}4${ac_dD}
+${ac_uA}SIZEOF_INT${ac_uB}SIZEOF_INT${ac_uC}4${ac_uD}
+${ac_eA}SIZEOF_INT${ac_eB}SIZEOF_INT${ac_eC}4${ac_eD}
+${ac_dA}SIZEOF_LONG${ac_dB}SIZEOF_LONG${ac_dC}4${ac_dD}
+${ac_uA}SIZEOF_LONG${ac_uB}SIZEOF_LONG${ac_uC}4${ac_uD}
+${ac_eA}SIZEOF_LONG${ac_eB}SIZEOF_LONG${ac_eC}4${ac_eD}
+CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+
+  cat > conftest.frag <<CEOF
+${ac_dA}SIZEOF_DOUBLE${ac_dB}SIZEOF_DOUBLE${ac_dC}8${ac_dD}
+${ac_uA}SIZEOF_DOUBLE${ac_uB}SIZEOF_DOUBLE${ac_uC}8${ac_uD}
+${ac_eA}SIZEOF_DOUBLE${ac_eB}SIZEOF_DOUBLE${ac_eC}8${ac_eD}
+${ac_dA}HAVE_ISINF${ac_dB}HAVE_ISINF${ac_dC}1${ac_dD}
+${ac_uA}HAVE_ISINF${ac_uB}HAVE_ISINF${ac_uC}1${ac_uD}
+${ac_eA}HAVE_ISINF${ac_eB}HAVE_ISINF${ac_eC}1${ac_eD}
+${ac_dA}HAVE_FINITE${ac_dB}HAVE_FINITE${ac_dC}1${ac_dD}
+${ac_uA}HAVE_FINITE${ac_uB}HAVE_FINITE${ac_uC}1${ac_uD}
+${ac_eA}HAVE_FINITE${ac_eB}HAVE_FINITE${ac_eC}1${ac_eD}
+${ac_dA}HAVE_MEMSET${ac_dB}HAVE_MEMSET${ac_dC}1${ac_dD}
+${ac_uA}HAVE_MEMSET${ac_uB}HAVE_MEMSET${ac_uC}1${ac_uD}
+${ac_eA}HAVE_MEMSET${ac_eB}HAVE_MEMSET${ac_eC}1${ac_eD}
+CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+
+  cat > conftest.frag <<CEOF
+${ac_dA}HAVE_MEMCPY${ac_dB}HAVE_MEMCPY${ac_dC}1${ac_dD}
+${ac_uA}HAVE_MEMCPY${ac_uB}HAVE_MEMCPY${ac_uC}1${ac_uD}
+${ac_eA}HAVE_MEMCPY${ac_eB}HAVE_MEMCPY${ac_eC}1${ac_eD}
+${ac_dA}HAVE_MEMCMP${ac_dB}HAVE_MEMCMP${ac_dC}1${ac_dD}
+${ac_uA}HAVE_MEMCMP${ac_uB}HAVE_MEMCMP${ac_uC}1${ac_uD}
+${ac_eA}HAVE_MEMCMP${ac_eB}HAVE_MEMCMP${ac_eC}1${ac_eD}
+${ac_dA}X_DISPLAY_MISSING${ac_dB}X_DISPLAY_MISSING${ac_dC}1${ac_dD}
+${ac_uA}X_DISPLAY_MISSING${ac_uB}X_DISPLAY_MISSING${ac_uC}1${ac_uD}
+${ac_eA}X_DISPLAY_MISSING${ac_eB}X_DISPLAY_MISSING${ac_eC}1${ac_eD}
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+
+date > stamp-h
+exit 0
diff --git a/SecuritySNACCRuntime/configure b/SecuritySNACCRuntime/configure
new file mode 100644
index 00000000..ee4c4af5
--- /dev/null
+++ b/SecuritySNACCRuntime/configure
@@ -0,0 +1,4458 @@
+#! /bin/sh
+
+# From configure.in Revision: 1.2 # Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --with-x                use the X Window System"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=compiler/core/snacc.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:529: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+	@echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:558: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:588: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:639: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:671: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 682 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:687: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:713: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:718: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:727: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:746: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:778: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+  grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+  echo "$ac_t""yes" 1>&6
+  ISC=yes # If later tests want to check for ISC.
+  cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+  if test "$GCC" = yes; then
+    CC="$CC -posix"
+  else
+    CC="$CC -Xp"
+  fi
+else
+  echo "$ac_t""no" 1>&6
+  ISC=
+fi
+
+if test -n "$GCC"; then
+
+  # hack to let X11 makedepend find .h file a little more the way gcc does:
+  echo $ac_n "checking for $CC's include path""... $ac_c" 1>&6
+echo "configure:802: checking for $CC's include path" >&5
+  gcclibdir=`$CC -v 2>&1 | sed -n -e 's:Reading specs from \(.*\)/specs:\1:p'`
+  gxxincdir=`which gcc | sed "s/bin\/gcc//"`
+  #MKDEP_CCINC="-I$gxxincdir/lib/g++-include -I/usr/local/include -I$gcclibdir/include"
+  MKDEP_CCINC="-I/usr/local/include -I$gcclibdir/include -F/System/Library/PrivateFrameworks"
+  echo "$ac_t""$MKDEP_CCINC" 1>&6
+  
+fi
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:811: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 826 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:832: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 843 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:849: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 860 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:866: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+    echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:892: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat > conftest.$ac_ext <<EOF
+#line 898 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=yes
+else
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat > conftest.$ac_ext <<EOF
+#line 916 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+if test "x$CC" != xcc; then
+  echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6
+echo "configure:939: checking whether $CC and cc understand -c and -o together" >&5
+else
+  echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6
+echo "configure:942: checking whether cc understands -c and -o together" >&5
+fi
+set dummy $CC; ac_cc="`echo $2 |
+		       sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`"
+if eval "test \"`echo '$''{'ac_cv_prog_cc_${ac_cc}_c_o'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'foo(){}' > conftest.c
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5'
+if { (eval echo configure:954: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+   test -f conftest.o && { (eval echo configure:955: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+then
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:960: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+      ac_try='cc -c conftest.c -o conftest.o 1>&5'
+      if { (eval echo configure:962: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+	 test -f conftest.o && { (eval echo configure:963: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+      then
+        # cc works too.
+        :
+      else
+        # cc exists but doesn't like -o.
+        eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  cat >> confdefs.h <<\EOF
+#define NO_MINUS_C_MINUS_O 1
+EOF
+
+fi
+
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
+  echo "configure: warning: since -c and -o don't seem to work together" 1>&2
+fi
+echo $ac_n "checking whether ANSI or K&R style C""... $ac_c" 1>&6
+echo "configure:993: checking whether ANSI or K&R style C" >&5
+if test "$cross_compiling" = yes; then
+  echo "$ac_t""K&R" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 998 "configure"
+#include "confdefs.h"
+main (int argc, char **argv) { void *p; return 0; }
+EOF
+if { (eval echo configure:1002: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  echo "$ac_t""ANSI" 1>&6; cat >> confdefs.h <<\EOF
+#define __USE_ANSI_C__ 1
+EOF
+
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  echo "$ac_t""K&R" 1>&6
+fi
+rm -fr conftest*
+fi
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1022: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1054: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1065 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:1070: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1096: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:1101: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1110: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:1129: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking for bool built-in""... $ac_c" 1>&6
+echo "configure:1168: checking for bool built-in" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1170 "configure"
+#include "confdefs.h"
+
+int main() {
+bool b = false;
+; return 0; }
+EOF
+if { (eval echo configure:1177: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cat >> confdefs.h <<\EOF
+#define BOOL_BUILTIN 1
+EOF
+ echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+echo $ac_n "checking for variable sized automatic arrays""... $ac_c" 1>&6
+echo "configure:1191: checking for variable sized automatic arrays" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1193 "configure"
+#include "confdefs.h"
+
+int main() {
+int i = 42; char a[++i]; *a = i;
+; return 0; }
+EOF
+if { (eval echo configure:1200: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cat >> confdefs.h <<\EOF
+#define HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS 1
+EOF
+ echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+echo $ac_n "checking for volatile functions""... $ac_c" 1>&6
+echo "configure:1214: checking for volatile functions" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1216 "configure"
+#include "confdefs.h"
+
+int main() {
+abort();
+; return 0; }
+EOF
+if { (eval echo configure:1223: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cat >> confdefs.h <<\EOF
+#define COMPILER_WITHOUT_VOLATILE_FUNCTIONS 1
+EOF
+ SNACC_NOVOLAT=-novolat;  echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1246: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$LEX"; then
+  ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_LEX="flex"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+  echo "$ac_t""$LEX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+  case "$LEX" in
+  flex*) ac_lib=fl ;;
+  *) ac_lib=l ;;
+  esac
+  echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:1280: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1288 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:1299: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LEXLIB="-l$ac_lib"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking lex output file root""... $ac_c" 1>&6
+echo "configure:1322: checking lex output file root" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # The minimal lex program is just a single line: %%.  But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+echo '%%
+%%' | $LEX
+if test -f lex.yy.c; then
+  ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+  ac_cv_prog_lex_root=lexyy
+else
+  { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_root" 1>&6
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6
+echo "configure:1343: checking whether yytext is a pointer" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS="$LIBS"
+LIBS="$LIBS $LEXLIB"
+cat > conftest.$ac_ext <<EOF
+#line 1355 "configure"
+#include "confdefs.h"
+`cat $LEX_OUTPUT_ROOT.c`
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_prog_lex_yytext_pointer=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+  cat >> confdefs.h <<\EOF
+#define YYTEXT_POINTER 1
+EOF
+
+fi
+
+case "$LEX" in
+  lex)
+    LFLAGS="-Nc10000"
+  ;;
+  flex)
+    CFLAGS="$CFLAGS -DFLEX_IN_USE"
+esac
+
+
+# the boot strapping code in .../c-lib/ needs patch:
+for ac_prog in patch
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1398: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_PATCH'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$PATCH"; then
+  ac_cv_prog_PATCH="$PATCH" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_PATCH="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+PATCH="$ac_cv_prog_PATCH"
+if test -n "$PATCH"; then
+  echo "$ac_t""$PATCH" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PATCH" && break
+done
+test -n "$PATCH" || PATCH="false"
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1433: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_YACC="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+  echo "$ac_t""$YACC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+for ac_prog in makedepend mkdep mkdep.sh
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1468: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_MKDEP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$MKDEP"; then
+  ac_cv_prog_MKDEP="$MKDEP" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_MKDEP="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+MKDEP="$ac_cv_prog_MKDEP"
+if test -n "$MKDEP"; then
+  echo "$ac_t""$MKDEP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$MKDEP" && break
+done
+test -n "$MKDEP" || MKDEP="$CC"
+
+for ac_prog in ar
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1503: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AR="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+  echo "$ac_t""$AR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AR" && break
+done
+test -n "$AR" || AR="ar"
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1536: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1594: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+	  if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  else
+	    ac_cv_path_install="$ac_dir/$ac_prog -c"
+	    break 2
+	  fi
+	fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1647: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1652 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1661: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_time=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+  cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:1686: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1691 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:1699: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:1724: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldir  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1732 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="$LIBS -ldir"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:1765: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lx  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1773 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1784: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="$LIBS -lx"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1807: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1812 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1820: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1837 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1855 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1876 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1911: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1916 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_size_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+  cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:1944: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1949 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uid_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_uid_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+  cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1978: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1983 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1991: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2008 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2026 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2047 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in unistd.h memory.h string.h malloc.h fcntl.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2085: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2090 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2095: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&6
+echo "configure:2122: checking for vprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2127 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char vprintf(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char vprintf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_vprintf=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
+echo "configure:2174: checking for _doprnt" >&5
+if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2179 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char _doprnt();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2202: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func__doprnt=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2227: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2232 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2281: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:2302: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 2309 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:2320: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 2324 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:2335: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_bigendian=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2355 "configure"
+#include "confdefs.h"
+main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:2368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_bigendian=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+  cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:2392: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2400 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(short));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_short=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:2431: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2439 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2450: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:2470: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2478 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2489: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+echo $ac_n "checking size of double""... $ac_c" 1>&6
+echo "configure:2509: checking size of double" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2517 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(double));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_double=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_double=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_double" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+EOF
+
+
+echo $ac_n "checking for sin in -lm""... $ac_c" 1>&6
+echo "configure:2548: checking for sin in -lm" >&5
+ac_lib_var=`echo m'_'sin | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lm  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2556 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char sin();
+
+int main() {
+sin()
+; return 0; }
+EOF
+if { (eval echo configure:2567: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lm $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+for ac_func in isinf finite
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2597: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2602 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2625: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in memset memcpy memcmp
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2652: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2657 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:2709: checking for X" >&5
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+  withval="$with_x"
+  :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+    # Both variables are already set.
+    have_x=yes
+  else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+  cd conftestdir
+  # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+  cat > Imakefile <<'EOF'
+acfindx:
+	@echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+  if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl; do
+      if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+        test -f $ac_im_libdir/libX11.$ac_extension; then
+        ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case "$ac_im_incroot" in
+	/usr/include) ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+    esac
+    case "$ac_im_usrlibdir" in
+	/usr/lib | /lib) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+    esac
+  fi
+  cd ..
+  rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+  # Guess where to find include files, by looking for this one X11 .h file.
+  test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+  # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 2771 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2776: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+  for ac_dir in               \
+    /usr/X11/include          \
+    /usr/X11R6/include        \
+    /usr/X11R5/include        \
+    /usr/X11R4/include        \
+                              \
+    /usr/include/X11          \
+    /usr/include/X11R6        \
+    /usr/include/X11R5        \
+    /usr/include/X11R4        \
+                              \
+    /usr/local/X11/include    \
+    /usr/local/X11R6/include  \
+    /usr/local/X11R5/include  \
+    /usr/local/X11R4/include  \
+                              \
+    /usr/local/include/X11    \
+    /usr/local/include/X11R6  \
+    /usr/local/include/X11R5  \
+    /usr/local/include/X11R4  \
+                              \
+    /usr/X386/include         \
+    /usr/x386/include         \
+    /usr/XFree86/include/X11  \
+                              \
+    /usr/include              \
+    /usr/local/include        \
+    /usr/unsupported/include  \
+    /usr/athena/include       \
+    /usr/local/x11r5/include  \
+    /usr/lpp/Xamples/include  \
+                              \
+    /usr/openwin/include      \
+    /usr/openwin/share/include \
+    ; \
+  do
+    if test -r "$ac_dir/$x_direct_test_include"; then
+      ac_x_includes=$ac_dir
+      break
+    fi
+  done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+  # Check for the libraries.
+
+  test -z "$x_direct_test_library" && x_direct_test_library=Xt
+  test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS="$LIBS"
+  LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2845 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:2852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+    /usr/X11/lib          \
+    /usr/X11R6/lib        \
+    /usr/X11R5/lib        \
+    /usr/X11R4/lib        \
+                          \
+    /usr/lib/X11          \
+    /usr/lib/X11R6        \
+    /usr/lib/X11R5        \
+    /usr/lib/X11R4        \
+                          \
+    /usr/local/X11/lib    \
+    /usr/local/X11R6/lib  \
+    /usr/local/X11R5/lib  \
+    /usr/local/X11R4/lib  \
+                          \
+    /usr/local/lib/X11    \
+    /usr/local/lib/X11R6  \
+    /usr/local/lib/X11R5  \
+    /usr/local/lib/X11R4  \
+                          \
+    /usr/X386/lib         \
+    /usr/x386/lib         \
+    /usr/XFree86/lib/X11  \
+                          \
+    /usr/lib              \
+    /usr/local/lib        \
+    /usr/unsupported/lib  \
+    /usr/athena/lib       \
+    /usr/local/x11r5/lib  \
+    /usr/lpp/Xamples/lib  \
+    /lib/usr/lib/X11	  \
+                          \
+    /usr/openwin/lib      \
+    /usr/openwin/share/lib \
+    ; \
+do
+  for ac_extension in a so sl; do
+    if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+  # Didn't find X anywhere.  Cache the known absence of X.
+  ac_cv_have_x="have_x=no"
+else
+  # Record where we found X for the cache.
+  ac_cv_have_x="have_x=yes \
+	        ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+  fi
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  echo "$ac_t""$have_x" 1>&6
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes \
+		ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+  echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+if test "$no_x" = yes; then
+  # Not all programs may use this symbol, but it does not hurt to define it.
+  cat >> confdefs.h <<\EOF
+#define X_DISPLAY_MISSING 1
+EOF
+
+  X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+  if test -n "$x_includes"; then
+    X_CFLAGS="$X_CFLAGS -I$x_includes"
+  fi
+
+  # It would also be nice to do this for all -L options, not just this one.
+  if test -n "$x_libraries"; then
+    X_LIBS="$X_LIBS -L$x_libraries"
+    # For Solaris; some versions of Sun CC require a space after -R and
+    # others require no space.  Words are not sufficient . . . .
+    case "`(uname -sr) 2>/dev/null`" in
+    "SunOS 5"*)
+      echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
+echo "configure:2958: checking whether -R must be followed by a space" >&5
+      ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
+      cat > conftest.$ac_ext <<EOF
+#line 2961 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2968: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_R_nospace=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_R_nospace=no
+fi
+rm -f conftest*
+      if test $ac_R_nospace = yes; then
+	echo "$ac_t""no" 1>&6
+	X_LIBS="$X_LIBS -R$x_libraries"
+      else
+	LIBS="$ac_xsave_LIBS -R $x_libraries"
+	cat > conftest.$ac_ext <<EOF
+#line 2984 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_R_space=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_R_space=no
+fi
+rm -f conftest*
+	if test $ac_R_space = yes; then
+	  echo "$ac_t""yes" 1>&6
+	  X_LIBS="$X_LIBS -R $x_libraries"
+	else
+	  echo "$ac_t""neither works" 1>&6
+	fi
+      fi
+      LIBS="$ac_xsave_LIBS"
+    esac
+  fi
+
+  # Check for system-dependent libraries X programs must link with.
+  # Do this before checking for the system-independent R6 libraries
+  # (-lICE), since we may need -lsocket or whatever for X linking.
+
+  if test "$ISC" = yes; then
+    X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+  else
+    # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+    # libraries were built with DECnet support.  And karl@cs.umb.edu says
+    # the Alpha needs dnet_stub (dnet does not exist).
+    echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
+echo "configure:3023: checking for dnet_ntoa in -ldnet" >&5
+ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldnet  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3031 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:3042: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+      echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
+echo "configure:3064: checking for dnet_ntoa in -ldnet_stub" >&5
+ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldnet_stub  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3072 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:3083: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+    # to get the SysV transport functions.
+    # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4)
+    # needs -lnsl.
+    # The nsl library prevents programs from opening the X display
+    # on Irix 5.2, according to dickey@clark.net.
+    echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:3112: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3117 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3140: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_gethostbyname=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_gethostbyname = no; then
+      echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:3161: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3169 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:3180: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # lieder@skyler.mavd.honeywell.com says without -lsocket,
+    # socket/setsockopt and other routines are undefined under SCO ODT
+    # 2.0.  But -lsocket is broken on IRIX 5.2 (and is not necessary
+    # on later versions), says simon@lia.di.epfl.ch: it contains
+    # gethostby* variants that don't use the nameserver (or something).
+    # -lsocket must be given before -lnsl if both are needed.
+    # We assume that if connect needs -lnsl, so does gethostbyname.
+    echo $ac_n "checking for connect""... $ac_c" 1>&6
+echo "configure:3210: checking for connect" >&5
+if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3215 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+connect();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_connect=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_connect=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_connect = no; then
+      echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:3259: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3267 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+connect()
+; return 0; }
+EOF
+if { (eval echo configure:3278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
+    echo $ac_n "checking for remove""... $ac_c" 1>&6
+echo "configure:3302: checking for remove" >&5
+if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3307 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char remove(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char remove();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+remove();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_remove=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_remove=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_remove = no; then
+      echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
+echo "configure:3351: checking for remove in -lposix" >&5
+ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lposix  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3359 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char remove();
+
+int main() {
+remove()
+; return 0; }
+EOF
+if { (eval echo configure:3370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+    echo $ac_n "checking for shmat""... $ac_c" 1>&6
+echo "configure:3394: checking for shmat" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3399 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shmat(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shmat();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+shmat();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3422: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shmat=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shmat=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_shmat = no; then
+      echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
+echo "configure:3443: checking for shmat in -lipc" >&5
+ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lipc  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3451 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shmat();
+
+int main() {
+shmat()
+; return 0; }
+EOF
+if { (eval echo configure:3462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+  fi
+
+  # Check for libraries that X11R6 Xt/Xaw programs need.
+  ac_save_LDFLAGS="$LDFLAGS"
+  test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+  # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+  # check for ICE first), but we must link in the order -lSM -lICE or
+  # we get undefined symbols.  So assume we have SM if we have ICE.
+  # These have to be linked with before -lX11, unlike the other
+  # libraries we check for below, so use a different variable.
+  #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+  echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
+echo "configure:3495: checking for IceConnectionNumber in -lICE" >&5
+ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3503 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char IceConnectionNumber();
+
+int main() {
+IceConnectionNumber()
+; return 0; }
+EOF
+if { (eval echo configure:3514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  LDFLAGS="$ac_save_LDFLAGS"
+
+fi
+
+for ac_prog in tclsh
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3543: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_TCLSH'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$TCLSH"; then
+  ac_cv_prog_TCLSH="$TCLSH" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_TCLSH="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+TCLSH="$ac_cv_prog_TCLSH"
+if test -n "$TCLSH"; then
+  echo "$ac_t""$TCLSH" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$TCLSH" && break
+done
+test -n "$TCLSH" || TCLSH="false"
+
+if test "$TCLSH" != false; then
+  ac_safe=`echo "tcl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for tcl.h""... $ac_c" 1>&6
+echo "configure:3576: checking for tcl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3581 "configure"
+#include "confdefs.h"
+#include <tcl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3586: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  echo $ac_n "checking for ldopen in -lld""... $ac_c" 1>&6
+echo "configure:3603: checking for ldopen in -lld" >&5
+ac_lib_var=`echo ld'_'ldopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3611 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char ldopen();
+
+int main() {
+ldopen()
+; return 0; }
+EOF
+if { (eval echo configure:3622: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  TCLOTHERLIBS=-lld
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    echo $ac_n "checking for Tcl_CreateInterp in -ltcl""... $ac_c" 1>&6
+echo "configure:3643: checking for Tcl_CreateInterp in -ltcl" >&5
+ac_lib_var=`echo tcl'_'Tcl_CreateInterp | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ltcl $TCLOTHERLIBS -lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3651 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char Tcl_CreateInterp();
+
+int main() {
+Tcl_CreateInterp()
+; return 0; }
+EOF
+if { (eval echo configure:3662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  saveCFLAGS="$CFLAGS"
+      CFLAGS="$CFLAGS $X_CFLAGS"
+      echo $ac_n "checking for Tk_CreateWindow in -ltk""... $ac_c" 1>&6
+echo "configure:3680: checking for Tk_CreateWindow in -ltk" >&5
+ac_lib_var=`echo tk'_'Tk_CreateWindow | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ltk -ltcl $TCLOTHERLIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3688 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char Tk_CreateWindow();
+
+int main() {
+Tk_CreateWindow()
+; return 0; }
+EOF
+if { (eval echo configure:3699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_TCL 1
+EOF
+
+	TCLLIBS="-ltk -ltcl $TCLOTHERLIBS"
+	ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+	echo $ac_n "checking for Tree_Init in -lTkTree""... $ac_c" 1>&6
+echo "configure:3727: checking for Tree_Init in -lTkTree" >&5
+ac_lib_var=`echo TkTree'_'Tree_Init | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lTkTree -lTkTree -ltk -ltcl $TCLOTHERLIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3735 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char Tree_Init();
+
+int main() {
+Tree_Init()
+; return 0; }
+EOF
+if { (eval echo configure:3749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  TREELIBS="-lTkTree"
+else
+  echo "$ac_t""no" 1>&6
+echo "$ac_t""tcl/tk libs found, but tree widget is missing" 1>&6
+fi
+
+	ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+else
+  echo "$ac_t""no" 1>&6
+echo "$ac_t""tcl lib found, but tk lib is missing" 1>&6
+fi
+
+      CFLAGS="$saveCFLAGS"
+else
+  echo "$ac_t""no" 1>&6
+echo "$ac_t""tcl library not found" 1>&6
+fi
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+for ac_prog in latex
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3800: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LATEX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$LATEX"; then
+  ac_cv_prog_LATEX="$LATEX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_LATEX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+LATEX="$ac_cv_prog_LATEX"
+if test -n "$LATEX"; then
+  echo "$ac_t""$LATEX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LATEX" && break
+done
+test -n "$LATEX" || LATEX="false"
+
+for ac_prog in bibtex
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3835: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_BIBTEX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$BIBTEX"; then
+  ac_cv_prog_BIBTEX="$BIBTEX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_BIBTEX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+BIBTEX="$ac_cv_prog_BIBTEX"
+if test -n "$BIBTEX"; then
+  echo "$ac_t""$BIBTEX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$BIBTEX" && break
+done
+test -n "$BIBTEX" || BIBTEX="false"
+
+for ac_prog in dvips
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3870: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DVIPS'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$DVIPS"; then
+  ac_cv_prog_DVIPS="$DVIPS" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_DVIPS="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+DVIPS="$ac_cv_prog_DVIPS"
+if test -n "$DVIPS"; then
+  echo "$ac_t""$DVIPS" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$DVIPS" && break
+done
+test -n "$DVIPS" || DVIPS="false"
+
+for ac_prog in detex2 detex
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3905: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DETEX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$DETEX"; then
+  ac_cv_prog_DETEX="$DETEX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_DETEX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+DETEX="$ac_cv_prog_DETEX"
+if test -n "$DETEX"; then
+  echo "$ac_t""$DETEX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$DETEX" && break
+done
+test -n "$DETEX" || DETEX="false"
+
+for ac_prog in ghostview gs
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3940: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_PSPREVIEW'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$PSPREVIEW"; then
+  ac_cv_prog_PSPREVIEW="$PSPREVIEW" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_PSPREVIEW="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+PSPREVIEW="$ac_cv_prog_PSPREVIEW"
+if test -n "$PSPREVIEW"; then
+  echo "$ac_t""$PSPREVIEW" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PSPREVIEW" && break
+done
+test -n "$PSPREVIEW" || PSPREVIEW="true"
+
+for ac_prog in psbook
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3975: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_PSBOOK'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$PSBOOK"; then
+  ac_cv_prog_PSBOOK="$PSBOOK" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_PSBOOK="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+PSBOOK="$ac_cv_prog_PSBOOK"
+if test -n "$PSBOOK"; then
+  echo "$ac_t""$PSBOOK" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PSBOOK" && break
+done
+test -n "$PSBOOK" || PSBOOK="false"
+
+for ac_prog in psnup
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4010: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_PSNUP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$PSNUP"; then
+  ac_cv_prog_PSNUP="$PSNUP" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_PSNUP="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+PSNUP="$ac_cv_prog_PSNUP"
+if test -n "$PSNUP"; then
+  echo "$ac_t""$PSNUP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PSNUP" && break
+done
+test -n "$PSNUP" || PSNUP="false"
+
+for ac_prog in ispell spell
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4045: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_SPELL'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$SPELL"; then
+  ac_cv_prog_SPELL="$SPELL" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_SPELL="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+SPELL="$ac_cv_prog_SPELL"
+if test -n "$SPELL"; then
+  echo "$ac_t""$SPELL" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$SPELL" && break
+done
+test -n "$SPELL" || SPELL="spell"
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "makehead config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@MKDEP_CCINC@%$MKDEP_CCINC%g
+s%@CPP@%$CPP%g
+s%@CXX@%$CXX%g
+s%@SNACC_NOVOLAT@%$SNACC_NOVOLAT%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@LFLAGS@%$LFLAGS%g
+s%@PATCH@%$PATCH%g
+s%@YACC@%$YACC%g
+s%@MKDEP@%$MKDEP%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@X_CFLAGS@%$X_CFLAGS%g
+s%@X_PRE_LIBS@%$X_PRE_LIBS%g
+s%@X_LIBS@%$X_LIBS%g
+s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g
+s%@TCLSH@%$TCLSH%g
+s%@TCLLIBS@%$TCLLIBS%g
+s%@TREELIBS@%$TREELIBS%g
+s%@LATEX@%$LATEX%g
+s%@BIBTEX@%$BIBTEX%g
+s%@DVIPS@%$DVIPS%g
+s%@DETEX@%$DETEX%g
+s%@PSPREVIEW@%$PSPREVIEW%g
+s%@PSBOOK@%$PSBOOK%g
+s%@PSNUP@%$PSNUP%g
+s%@SPELL@%$SPELL%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"makehead"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+date > stamp-h
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/SecuritySNACCRuntime/configure.in b/SecuritySNACCRuntime/configure.in
new file mode 100644
index 00000000..51f27769
--- /dev/null
+++ b/SecuritySNACCRuntime/configure.in
@@ -0,0 +1,189 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl ---
+AC_REVISION($Revision: 1.1.1.1 $)dnl
+dnl	$Log: configure.in,v $
+dnl	Revision 1.1.1.1  2001/05/18 23:14:04  mb
+dnl	Move from private repository to open source repository
+dnl	
+dnl	Revision 1.3  2000/12/21 23:58:39  dmitch
+dnl	Misc. updates for clean build on Cheetah 1D7.
+dnl	
+dnl	Revision 1.2  2000/06/08 19:57:33  dmitch
+dnl	Mods for X port.
+dnl	
+dnl	Revision 1.1.1.1  1999/03/16 18:05:49  aram
+dnl	Originals from SMIME Free Library.
+dnl	
+dnl	Revision 1.13  1997/09/04 13:54:04  wan
+dnl	A little more portability
+dnl
+dnl	Revision 1.12  1997/02/28 13:39:35  wan
+dnl	Modifications collected for new version 1.3: Bug fixes, tk4.2.
+dnl
+dnl	Revision 1.11  1997/02/16 16:50:27  rj
+dnl	made return *this after calling abort()'' a compile time option.
+dnl
+dnl	Revision 1.10  1997/02/15 20:06:27  rj
+dnl	adjust to changed AC_TRY_COMPILE macro
+dnl
+dnl	Revision 1.9  1997/02/15 20:01:38  rj
+dnl	check whether the compiler supports volatile functions (and whether abort() is volatile).
+dnl
+dnl	Revision 1.8  1997/01/01 19:57:01  rj
+dnl	changes for autoconf version 2.12
+dnl
+dnl	Revision 1.7  1995/09/07  18:36:47  rj
+dnl	psbook and psnup are looked for (used by .../doc/makefile)
+dnl
+dnl	Revision 1.6  1995/07/24  14:44:47  rj
+dnl	don't use gcc/g++ with -pipe, compiling some files may exceed virtual memory.
+dnl
+dnl	look for tclsh(1). tcl-lib uses it to construct the tclIndex file. don't look for Tcl/Tk if the tclsh is absent.
+dnl
+dnl	look for patch(1). the c-lib uses it to patch tbl.h.
+dnl
+dnl	search for tree-3.6's libtktree.a and set TREELIBS in .../makehead accordingly.
+dnl
+dnl	check for memset(3), memcpy(3) and memcmp(3). .../snacc.h reverts to bzero(3), bcopy(3) and bcmp(3) if necessary.
+dnl
+dnl	Revision 1.5  1995/02/20  11:18:41  rj
+dnl	cpp switch HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS added.
+dnl	check for isinf(3) and finite(3) added.
+dnl
+dnl	Revision 1.4  1995/02/17  15:15:44  rj
+dnl	hack to let makedepend find .h files the way gcc does.
+dnl
+dnl	Revision 1.3  1995/02/17  14:26:40  rj
+dnl	adjustments for autoconf 2.x
+dnl
+dnl	Revision 1.2  1994/10/08  04:29:37  rj
+dnl	search for Tcl/Tk
+dnl
+dnl	Revision 1.1  1994/09/01  00:51:22  rj
+dnl	first check-in (new file).
+dnl
+AC_INIT( compiler/core/snacc.c)
+AC_CONFIG_HEADER( config.h)
+dnl --- alternative programs:
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_ISC_POSIX
+if test -n "$GCC"; then
+dnl   saveCC="$CC"
+dnl   CC="$CC -pipe"
+dnl   AC_MSG_CHECKING( whether $saveCC takes -pipe)
+dnl   AC_TRY_LINK( , , [AC_MSG_RESULT( yes)], [AC_MSG_RESULT( no); CC="$saveCC"])
+
+  # hack to let X11 makedepend find .h file a little more the way gcc does:
+  AC_MSG_CHECKING( for $CC's include path)
+  gcclibdir=`$CC -v 2>&1 | sed -n -e 's:Reading specs from \(.*\)/specs:\1:p'`
+  gxxincdir=`which gcc | sed "s/bin\/gcc//"`
+  #MKDEP_CCINC="-I$gxxincdir/lib/g++-include -I/usr/local/include -I$gcclibdir/include"
+  MKDEP_CCINC="-I/usr/local/include -I$gcclibdir/include -F/System/Library/PrivateFrameworks"
+  AC_MSG_RESULT( $MKDEP_CCINC)
+  AC_SUBST( MKDEP_CCINC)
+fi
+AC_PROG_GCC_TRADITIONAL
+AC_PROG_CC_C_O
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
+  AC_MSG_WARN( since -c and -o don't seem to work together, the makefiles probably won't work!)
+fi
+AC_MSG_CHECKING( whether ANSI or K&R style C)
+AC_TRY_RUN( [main (int argc, char **argv) { void *p; return 0; }], [AC_MSG_RESULT( ANSI); AC_DEFINE( __USE_ANSI_C__)], AC_MSG_RESULT( K&R), AC_MSG_RESULT( K&R))
+AC_PROG_CXX
+AC_LANG_CPLUSPLUS
+dnl if test -n "$GCC"; then
+dnl   saveCXX="$CXX"
+dnl   CXX="$CXX -pipe"
+dnl   AC_MSG_CHECKING( whether $saveCXX takes -pipe)
+dnl   AC_TRY_LINK( , , [AC_MSG_RESULT( yes)], [AC_MSG_RESULT( no);CC="$saveCC"])
+dnl fi
+AC_MSG_CHECKING( for bool built-in)
+AC_TRY_COMPILE( , bool b = false;, [AC_DEFINE( BOOL_BUILTIN) AC_MSG_RESULT( yes)], AC_MSG_RESULT( no))
+AC_MSG_CHECKING( for variable sized automatic arrays)
+AC_TRY_COMPILE( , changequote(<,>)int i = 42; char a[++i]; *a = i;changequote([,]), [AC_DEFINE( HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS) AC_MSG_RESULT( yes)], AC_MSG_RESULT( no))
+AC_MSG_CHECKING( for volatile functions)
+AC_TRY_COMPILE( , changequote(<,>)abort();changequote([,]), [AC_MSG_RESULT( yes)], [AC_DEFINE( COMPILER_WITHOUT_VOLATILE_FUNCTIONS) SNACC_NOVOLAT=-novolat; AC_SUBST( SNACC_NOVOLAT) AC_MSG_RESULT( no)])
+AC_LANG_C
+AC_PROG_LEX
+AC_DECL_YYTEXT
+case "$LEX" in
+  lex)
+    LFLAGS="-Nc10000"
+  ;;
+  flex)
+    CFLAGS="$CFLAGS -DFLEX_IN_USE"
+esac
+AC_SUBST( LFLAGS)
+AC_SUBST( CFLAGS)
+# the boot strapping code in .../c-lib/ needs patch:
+AC_CHECK_PROGS( PATCH, patch, false)
+AC_PROG_YACC
+AC_CHECK_PROGS( MKDEP, makedepend mkdep mkdep.sh, $CC)
+AC_CHECK_PROGS( AR, ar, ar)
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+dnl --- header files:
+AC_HEADER_TIME
+AC_HEADER_DIRENT
+AC_TYPE_SIZE_T
+AC_TYPE_UID_T
+AC_HEADER_STDC
+AC_CHECK_HEADERS( unistd.h memory.h string.h malloc.h fcntl.h)
+AC_FUNC_VPRINTF
+dnl --- system and compiler characteristics:
+AC_C_CONST
+AC_C_BIGENDIAN
+AC_CHECK_SIZEOF( short)
+AC_CHECK_SIZEOF( int)
+AC_CHECK_SIZEOF( long)
+AC_CHECK_SIZEOF( double)
+AC_CHECK_LIB( m, sin)
+AC_CHECK_FUNCS( isinf finite)
+AC_CHECK_FUNCS( memset memcpy memcmp)
+dnl ---
+AC_PATH_X
+AC_PATH_XTRA
+AC_CHECK_PROGS( TCLSH, tclsh, false)
+if test "$TCLSH" != false; then
+  AC_CHECK_HEADER(
+    tcl.h,
+    [AC_CHECK_LIB( ld, ldopen, TCLOTHERLIBS=-lld)
+    AC_CHECK_LIB(
+      tcl,
+      Tcl_CreateInterp,
+      [saveCFLAGS="$CFLAGS"
+      CFLAGS="$CFLAGS $X_CFLAGS"
+      AC_CHECK_LIB(
+	tk,
+	Tk_CreateWindow,
+	[AC_DEFINE( HAVE_TCL)
+	TCLLIBS="-ltk -ltcl $TCLOTHERLIBS"
+	AC_LANG_CPLUSPLUS
+	AC_CHECK_LIB(
+	  TkTree,
+	  Tree_Init,
+	  [TREELIBS="-lTkTree"],
+	  [AC_MSG_RESULT( [tcl/tk libs found, but tree widget is missing])],
+	  -lTkTree -ltk -ltcl $TCLOTHERLIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS)
+	AC_LANG_C],
+	[AC_MSG_RESULT( [tcl lib found, but tk lib is missing])],
+	-ltcl $TCLOTHERLIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS)
+      CFLAGS="$saveCFLAGS"],
+      [AC_MSG_RESULT( [tcl library not found])],
+      $TCLOTHERLIBS -lm)])
+fi
+AC_SUBST( TCLLIBS)
+AC_SUBST( TREELIBS)
+dnl ---
+AC_CHECK_PROGS( LATEX, latex, false)
+AC_CHECK_PROGS( BIBTEX, bibtex, false)
+AC_CHECK_PROGS( DVIPS, dvips, false)
+AC_CHECK_PROGS( DETEX, detex2 detex, false)
+AC_CHECK_PROGS( PSPREVIEW, ghostview gs, true)
+AC_CHECK_PROGS( PSBOOK, psbook, false)
+AC_CHECK_PROGS( PSNUP, psnup, false)
+AC_CHECK_PROGS( SPELL, ispell spell, spell)
+dnl ---
+AC_OUTPUT( makehead, date > stamp-h)
+dnl --- finis
diff --git a/SecuritySNACCRuntime/doc/asn1-defs.tex b/SecuritySNACCRuntime/doc/asn1-defs.tex
new file mode 100644
index 00000000..76bf343e
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/asn1-defs.tex
@@ -0,0 +1,910 @@
+% file: .../doc/asn1-defs.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/asn1-defs.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: asn1-defs.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:51  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:47  rj
+% first check-in
+%
+
+\chapter{The Module Data Structure ASN.1 Definition}
+
+The ASN.1 modules are parsed into an internal data structure.  The
+data structure was initially defined in ASN.1 with the idea that if
+we needed to write a parsed module to disk, the ASN.1 encoding
+routines could be used.  No file format was needed so the ASN.1 was
+merely an exercise.
+
+This procedure highlighted the problem with circular links and index
+like links in ASN.1 data structures.  BER does not support this type
+of linking; to handle it, the offending links can be made optional
+and not encoded.  After decoding, these links need to be
+re-established.  See the type table data structure for a format
+suitable for writing to files.
+
+The following is the ASN.1 definition of the Module data structure.
+The C translation (as generated by an early version of Snacc) can be
+found in {\ufn \dots/compiler/core/asn1module.h}\footnote{
+  The {\ufn asn1module.h} that is produced by a current version of Snacc cannot be compiled because its type definitions are in the wrong order.
+  This may be caused by the {\ASN --\,--snacc cTypeName} compiler directives, since one of the affected types is BasicTypeChoiceId, but i'm not really sure.
+  ---rj
+}.
+\begin{small}
+\begin{verbatim}
+-- .../asn1specs/asn1module.asn1
+--
+-- This module describes the data structure used to represent the
+-- compiled ASN.1.
+-- Using ASN.1 for the internal data structure allows writing
+-- (encoding) to disk for storage (not done yet due to recursive
+--  refs back to the module)
+--
+-- Mike Sample 91/08/29
+-- Modifed 92/05  MS
+--
+
+Asn1Module DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+-- exports everything
+-- imports nothing
+
+Modules ::= [APPLICATION 0] IMPLICIT SEQUENCE
+{
+    creationTime INTEGER,
+    modules ModuleList
+}
+
+ModuleList ::= SEQUENCE OF Module
+
+
+Module ::= SEQUENCE
+{
+    status ENUMERATED { mod-ok(0), mod-not-linked(1), mod-error(2) },
+    modId      ModuleId,
+    tagDefault ENUMERATED { explicit-tags(0), implicit-tags(1) },
+    exportStatus  ENUMERATED { exports-all(0), exports-nothing(1),
+                               exports-some(2) },
+    imports    ImportModuleList,
+    typeDefs   TypeDefList,
+    valueDefs  ValueDefList,
+    hasAnys    BOOLEAN,
+
+    asn1SrcFileName MyString,
+    cHdrFileName    MyString,
+    cSrcFileName    MyString,
+    cxxHdrFileName  MyString,
+    cxxSrcFileName  MyString
+
+    cxxname		MyString, -- META
+
+    idlFileName		MyString, -- IDL
+    idlname		MyString -- IDL
+}
+
+
+ModuleId ::= SEQUENCE
+{
+    name MyString,
+    oid  OBJECT IDENTIFIER OPTIONAL --snacc cTypeName:"OID" isPtr:"TRUE"
+}
+
+
+ImportModuleList ::= SEQUENCE OF ImportModule
+
+
+ImportModule ::= SEQUENCE
+{
+    modId       ModuleId,
+    importElmts ImportElmtList,
+    moduleRef   Module, --snacc isEncDec:"FALSE"
+    lineNo INTEGER
+}
+
+
+ImportElmtList ::= SEQUENCE OF ImportElmt
+
+
+ImportElmt ::= SEQUENCE
+{
+    resolvedRef CHOICE
+    {
+        type  [0] TypeDef,  -- not encoded
+        value [1] ValueDef  -- not encoded
+     } OPTIONAL,
+    name MyString,
+    privateScope BOOLEAN, -- true if from MODNAME.TYPE ref
+    lineNo INTEGER
+}
+
+TypeDefList ::= SEQUENCE OF TypeDef
+
+OidOrInt ::= CHOICE
+{
+    oid OBJECT IDENTIFIER,
+    intId INTEGER
+}
+
+AnyRef ::= SEQUENCE
+{
+    anyIdName MyString,
+    id OidOrInt
+}
+
+AnyRefList ::= SEQUENCE OF AnyRef
+
+TypeDef ::= SEQUENCE
+{
+    exported     BOOLEAN,
+    recursive    BOOLEAN,
+    isPdu    BOOLEAN,
+    localRefCount     INTEGER,
+    importRefCount     INTEGER,
+    tmpRefCount    INTEGER,
+    visited      BOOLEAN,
+    definedName  MyString,
+    type         Type,
+    cTypeDefInfo CTDI,
+    cxxTypeDefInfo CxxTDI,
+    attrList     AttributeList,
+    refList      TypeDefList,
+    anyRefs      AnyRefList
+}
+
+
+Tag ::= SEQUENCE
+{
+    tclass INTEGER, -- swap this for the BER_CLASS enum from basetypes.h
+    form  INTEGER,  -- swap this for the BER_FORM enum
+    code  INTEGER,
+    explicit BOOLEAN,
+    valueRef Value
+}
+
+Type ::= SEQUENCE
+{
+    optional   BOOLEAN,
+    implicit   BOOLEAN,
+    tags       TagList,
+    defaultVal [0] IMPLICIT NamedValue OPTIONAL,
+    subtypes   [1] Subtype OPTIONAL,
+    basicType  [2] BasicType,
+    lineNo     INTEGER,
+    cTypeRefInfo CTRI,
+    cxxTypeRefInfo CxxTRI,
+    attrList   AttributeList
+}
+
+TagList ::= SEQUENCE OF Tag
+
+AttributeList ::= SEQUENCE OF MyString
+
+NamedNumberList ::= ValueDefList
+
+
+-- BasicTypes with NULL need no more info that which type it is
+-- (this is known from the choice id)
+
+BasicType ::= CHOICE
+{
+    unknown         [0]  IMPLICIT NULL,
+    boolean         [1]  IMPLICIT NULL,
+    integer         [2]  IMPLICIT NamedNumberList,
+    bitString       [3]  IMPLICIT NamedNumberList,
+    octetString     [4]  IMPLICIT NULL,
+    null            [5]  IMPLICIT NULL,
+    oid             [6]  IMPLICIT NULL,
+    real            [7]  IMPLICIT NULL,
+    enumerated      [8]  IMPLICIT NamedNumberList,
+    sequence        [9]  IMPLICIT NamedTypeList,
+    sequenceOf      [10] IMPLICIT Type,
+    set             [11] IMPLICIT NamedTypeList,
+    setOf           [12] IMPLICIT Type,
+    choice          [13] IMPLICIT NamedTypeList,
+    selection       [14] IMPLICIT SelectionType,
+    componentsOf    [15] IMPLICIT Type, --  [Resolved](local/import) type ref
+    any             [16] IMPLICIT NULL,
+    anyDefinedBy    [17] IMPLICIT AnyDefinedByType,
+    localTypeRef    [19] IMPLICIT TypeRef,
+    importTypeRef   [20] IMPLICIT TypeRef,
+    macroType       [21] MacroType,
+    macroDef        [22] IMPLICIT MacroDef --snacc isPtr:"FALSE"
+}
+
+MacroDef ::= MyString -- just keep the text for now
+
+MacroType ::= CHOICE
+{
+    rosOperation    [0] IMPLICIT RosOperationMacroType,
+    rosError        [1] IMPLICIT RosErrorMacroType,
+    rosBind         [2] IMPLICIT RosBindMacroType,
+    rosUnbind       [3] IMPLICIT RosBindMacroType,
+    rosAse          [4] IMPLICIT RosAseMacroType,
+    rosAc           [5] IMPLICIT RosAcMacroType,
+    mtsasExtension  [6] IMPLICIT MtsasExtensionMacroType,
+    mtsasExtensions [7] IMPLICIT MtsasExtensionsMacroType,
+    mtsasExtensionAttribute [8] IMPLICIT MtsasExtensionAttributeMacroType,
+    mtsasToken      [9] IMPLICIT MtsasTokenMacroType,
+    mtsasTokenData [10] IMPLICIT MtsasTokenDataMacroType,
+    mtsasSecurityCategory [11] IMPLICIT MtsasSecurityCategoryMacroType,
+    asnObject       [12] IMPLICIT AsnObjectMacroType,
+    asnPort         [13] IMPLICIT AsnPortMacroType,
+    asnRefine       [14] IMPLICIT AsnRefineMacroType,
+    asnAbstractBind      [15] IMPLICIT AsnAbstractBindMacroType,
+    asnAbstractUnbind    [16] IMPLICIT AsnAbstractBindMacroType,
+    asnAbstractOperation [17] IMPLICIT RosOperationMacroType,
+    asnAbstractError     [18] IMPLICIT RosErrorMacroType,
+    afAlgorithm     [19] IMPLICIT Type,
+    afEncrypted     [20] IMPLICIT Type,
+    afProtected     [21] IMPLICIT Type,
+    afSignature     [22] IMPLICIT Type,
+    afSigned        [23] IMPLICIT Type,
+    snmpObjectType  [24] IMPLICIT SnmpObjectTypeMacroType
+}
+
+
+AnyDefinedByType ::= SEQUENCE
+{
+    fieldName MyString,   -- name of field that its defined by
+    link NamedType OPTIONAL  -- REFERENCE not encoded
+}
+
+
+SelectionType ::= SEQUENCE
+{
+    fieldName MyString,   -- name of field in choice
+    typeRef   Type,      -- [Resolved](local/import) type ref
+    link NamedType OPTIONAL -- REFERENCE not encoded
+}
+
+NamedTypeList ::= SEQUENCE OF NamedType
+
+NamedType ::= SEQUENCE
+{
+    fieldName  MyString, -- may be empty or NULL str
+    type       Type
+}
+
+
+TypeRef ::= SEQUENCE
+{
+    typeName    MyString,
+    moduleName  MyString, -- used for "modname.type" refs (may be null)
+    module      Module,   --snacc isEncDec:"FALSE"
+    link        TypeDef   --snacc isEncDec:"FALSE"
+}
+
+
+
+RosOperationMacroType ::= SEQUENCE
+{
+    arguments NamedType,
+    result    NamedType,
+    errors    [0] IMPLICIT TypeOrValueList OPTIONAL,
+    linkedOps [1] IMPLICIT TypeOrValueList OPTIONAL
+}
+
+ValueList ::= SEQUENCE OF Value
+
+TypeOrValueList ::= SEQUENCE OF TypeOrValue
+
+TypeOrValue ::= CHOICE
+{
+    type  [0] IMPLICIT Type,
+    value [1] IMPLICIT Value
+}
+
+OidList ::= SEQUENCE OF OBJECT IDENTIFIER
+
+
+RosErrorMacroType ::= SEQUENCE
+{
+    parameter NamedType
+}
+
+RosBindMacroType ::= SEQUENCE
+{
+    argument NamedType,
+    result   NamedType,
+    error    NamedType
+}
+
+
+RosAseMacroType  ::= SEQUENCE
+{
+    operations       ValueList,
+    consumerInvokes  ValueList,
+    supplierInvokes  ValueList
+}
+
+RosAcMacroType ::= SEQUENCE
+{
+    nonRoElements       ValueList,
+    bindMacroType       Type,
+    unbindMacroType     Type,
+    remoteOperations    Value,
+    operationsOf        ValueList,
+    initiatorConsumerOf ValueList,
+    responderConsumerOf ValueList,
+    abstractSyntaxes    OidList
+}
+
+
+MtsasExtensionMacroType ::=  SEQUENCE
+{
+    elmtType              [0] IMPLICIT NamedType OPTIONAL,
+    defaultValue          [1] IMPLICIT Value    OPTIONAL,
+    criticalForSubmission [2] IMPLICIT BOOLEAN  OPTIONAL,
+    criticalForTransfer   [3] IMPLICIT BOOLEAN  OPTIONAL,
+    criticalForDelivery   [4] IMPLICIT BOOLEAN  OPTIONAL
+}
+
+
+MtsasExtensionsMacroType ::= SEQUENCE
+{
+    extensions ValueList
+}
+
+MtsasExtensionAttributeMacroType ::= SEQUENCE
+{
+    type Type OPTIONAL
+}
+
+MtsasTokenMacroType ::= SEQUENCE
+{
+    type Type OPTIONAL
+}
+
+MtsasTokenDataMacroType ::= SEQUENCE
+{
+    type Type OPTIONAL
+}
+
+MtsasSecurityCategoryMacroType ::= SEQUENCE
+{
+    type Type OPTIONAL
+}
+
+AsnObjectMacroType ::= SEQUENCE
+{
+   ports  AsnPortList OPTIONAL
+}
+
+AsnPortList ::= SEQUENCE OF AsnPort
+
+AsnPort ::= SEQUENCE
+{
+    portValue Value,
+    portType  ENUMERATED
+    {
+         consumer-port (0),
+         supplier-port (1),
+         symmetric-port (2)
+    }
+}
+
+
+AsnPortMacroType ::= SEQUENCE
+{
+    abstractOps     [0] IMPLICIT TypeOrValueList OPTIONAL,
+    consumerInvokes [1] IMPLICIT TypeOrValueList OPTIONAL,
+    supplierInvokes [2] IMPLICIT TypeOrValueList OPTIONAL
+}
+
+
+AsnRefineMacroType ::= INTEGER
+
+AsnAbstractBindMacroType ::= SEQUENCE
+{
+    ports [0] IMPLICIT AsnPortList OPTIONAL,
+    type  [1] IMPLICIT Type OPTIONAL
+}
+
+
+SnmpObjectTypeMacroType ::= SEQUENCE
+{
+   syntax Type,
+   access ENUMERATED
+       { snmp-read-only (0), snmp-read-write (1),
+         snmp-write-only (2), snmp-not-accessible (3)},
+   status ENUMERATED
+       { snmp-mandatory (0), snmp-optional (1),
+         snmp-obsolete (2), snmp-deprecated (3)},
+   description [0] IMPLICIT Value OPTIONAL,
+   reference   [1] IMPLICIT Value OPTIONAL,
+   index       [2] IMPLICIT TypeOrValueList OPTIONAL,
+   defVal      [3] IMPLICIT Value OPTIONAL
+}
+
+
+Subtype ::= CHOICE
+{
+    single [0] SubtypeValue,
+    and    [1] IMPLICIT SubtypeList,
+    or     [2] IMPLICIT SubtypeList,
+    not    [3] Subtype
+}
+
+SubtypeList ::= SEQUENCE OF Subtype
+
+SubtypeValue ::= CHOICE
+{
+    singleValue       [0] IMPLICIT Value,
+    contained         [1] IMPLICIT Type,
+    valueRange        [2] IMPLICIT ValueRangeSubtype,
+    permittedAlphabet [3] Subtype, -- only valuerange or singleval
+    sizeConstraint    [4] Subtype, -- only single value ints or val range
+    innerSubtype      [5] IMPLICIT InnerSubtype
+}
+
+
+ValueRangeSubtype ::= SEQUENCE
+{
+    lowerEndInclusive BOOLEAN,
+    upperEndInclusive BOOLEAN,
+    lowerEndValue Value,
+    upperEndValue Value
+}
+
+
+InnerSubtype ::= SEQUENCE
+{
+    constraintType ENUMERATED { full-ct (0), partial-ct (1), single-ct (2) },
+    constraints ConstraintList
+}
+
+ConstraintList ::= SEQUENCE OF Constraint
+
+Constraint ::= SEQUENCE
+{
+    fieldRef MyString,  -- not used if in single-ct, may be null
+    presenceConstraint ENUMERATED
+    {
+        present-ct (0),
+        absent-ct (1),
+        empty-ct (2),
+        optional-ct (3)
+    },
+    valueConstraints Subtype
+}
+
+
+ValueDefList ::= SEQUENCE OF ValueDef
+
+
+ValueDef ::= SEQUENCE
+{
+   exported    BOOLEAN,
+   definedName MyString,
+   value       Value
+}
+
+Value ::= SEQUENCE
+{
+    type    Type OPTIONAL,
+    valueType  INTEGER,  -- holds one of choiceId's def'd for BasicType
+    basicValue BasicValue,
+    lineNo     INTEGER
+}
+
+BasicValue ::= CHOICE
+{
+    unknown          [0]  IMPLICIT NULL,
+    empty            [1]  IMPLICIT NULL,
+    integer          [2]  IMPLICIT INTEGER,
+    specialInteger   [3]  IMPLICIT SpecialIntegerValue,
+    longInteger      [4]  IMPLICIT INTEGER,  -- put LONG before INTGEGER
+    boolean          [5]  IMPLICIT BOOLEAN,
+    real             [6]  IMPLICIT REAL,
+    specialReal      [7]  IMPLICIT SpecialRealValue,
+    asciiText        [8]  IMPLICIT OCTET STRING,
+    asciiHex         [9]  IMPLICIT OCTET STRING,
+    asciiBitString   [10] IMPLICIT OCTET STRING,
+    oid              [11] IMPLICIT OBJECT IDENTIFIER,
+    linkedOid        [12] IMPLICIT OBJECT IDENTIFIER, --snacc cTypeName:"OID"
+    berValue         [13] IMPLICIT OCTET STRING,
+    perValue         [14] IMPLICIT OCTET STRING,
+    namedValue       [15] IMPLICIT NamedValue,
+    null             [16] IMPLICIT NULL,
+    localValueRef    [17] IMPLICIT ValueRef,
+    importValueRef   [18] IMPLICIT ValueRef,
+    valueNotation    [19] IMPLICIT OCTET STRING
+}
+
+
+
+SpecialIntegerValue ::= ENUMERATED { min-int (0), max-int (1) }
+SpecialRealValue ::= ENUMERATED { minus-infinity-real (0), plus-infinity-real (1) }
+
+
+ValueRef ::= SEQUENCE
+{
+    valueName  MyString,
+    moduleName MyString, -- used for "modname.value" refs (may be null)
+    link       ValueDef, --snacc isEncDec:"FALSE"
+    module     Module    --snacc isEncDec:"FALSE"
+}
+
+NamedValue ::= SEQUENCE
+{
+   fieldName MyString, -- may be null
+   value     Value
+}
+
+NamedValueList ::= SEQUENCE OF NamedValue
+
+CTypeId  ::= ENUMERATED { c-choice (0), c-list (1), c-any (2), c-anydefinedby (3),
+                          c-lib (4), c-struct (5), c-typeref (6), c-no-type (7),
+                         c-typedef (8) }
+
+-- C Type Def Info - info used for routine naming
+-- and referencing from other types
+CTDI ::= SEQUENCE
+{
+    asn1TypeId         INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId"
+    cTypeId            CTypeId,
+    cTypeName          MyString,
+    isPdu              BOOLEAN,
+    isEncDec           BOOLEAN, -- if false, no routines are gen
+                                -- and not included in encodings
+    isPtrForTypeDef    BOOLEAN,
+    isPtrForTypeRef    BOOLEAN,
+    isPtrInChoice      BOOLEAN,
+    isPtrForOpt        BOOLEAN,
+
+               -- defines these names, used by references
+    optTestRoutineName MyString, -- routine/macro to check whether
+                                 -- opt type is present
+    defaultFieldName   MyString, -- base for generating field names
+
+    printRoutineName   MyString,
+    encodeRoutineName  MyString,
+    decodeRoutineName  MyString,
+    freeRoutineName    MyString,
+
+    genPrintRoutine    BOOLEAN,
+    genEncodeRoutine   BOOLEAN,
+    genDecodeRoutine   BOOLEAN,
+    genFreeRoutine     BOOLEAN,
+    genTypeDef         BOOLEAN
+}
+
+
+--
+-- CTRI (C Type Ref Info) is used for generating C typedefinitions
+-- from the ASN.1 types info
+CTRI ::= SEQUENCE
+{
+    cTypeId CTypeId,
+    cFieldName MyString,
+    cTypeName  MyString,
+    isPtr BOOLEAN,
+--    isEndCType BOOLEAN,        -- false for struct/union def
+    cNamedElmts CNamedElmts OPTIONAL,      -- for C_LIB bits/int/enums
+    choiceIdValue INTEGER,     -- enum value of this c field
+    choiceIdSymbol MyString,   -- this fields sym in choiceId enum
+    choiceIdEnumName MyString,
+    choiceIdEnumFieldName MyString,
+    optTestRoutineName MyString, -- these names are gained from refd type def
+    printRoutineName   MyString,   -- or are over-ridden snacc attribute comment
+    encodeRoutineName  MyString,
+    decodeRoutineName  MyString,
+    freeRoutineName    MyString,
+    isEncDec           BOOLEAN -- whether part of enc value
+}
+
+CNamedElmts ::= SEQUENCE OF CNamedElmt
+
+CNamedElmt ::= SEQUENCE
+{
+    name MyString,
+    value INTEGER
+}
+
+
+CxxTDI ::= SEQUENCE
+{
+    asn1TypeId         INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId"
+    className          MyString,
+    isPdu              BOOLEAN,
+    isEnc              BOOLEAN,
+    isPtrForTypeDef    BOOLEAN,
+    isPtrForOpt        BOOLEAN,
+    isPtrInChoice      BOOLEAN,
+    isPtrInSetAndSeq   BOOLEAN,
+    isPtrInList        BOOLEAN,
+    optTestRoutineName MyString,
+    defaultFieldName   MyString -- base for generating field names
+}
+
+
+
+CxxTRI ::= SEQUENCE
+{
+    isEnc BOOLEAN,
+    className MyString,
+    fieldName MyString,
+    isPtr BOOLEAN,
+    namedElmts CNamedElmts,
+    choiceIdSymbol MyString,
+    choiceIdValue INTEGER,
+    optTestRoutineName MyString
+}
+
+IDLTDI ::= SEQUENCE
+{
+    asn1TypeId         INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId"
+    typeName           MyString,
+    isPdu              BOOLEAN,
+    isEnc              BOOLEAN,
+    isPtrForTypeDef    BOOLEAN,
+    isPtrForOpt        BOOLEAN,
+    isPtrInChoice      BOOLEAN,
+    isPtrInSetAndSeq   BOOLEAN,
+    isPtrInList        BOOLEAN,
+    optTestRoutineName MyString,
+    defaultFieldName   MyString -- base for generating field names
+}
+
+IDLTRI ::= SEQUENCE
+{
+    isEnc BOOLEAN,
+    typeName MyString,
+    fieldName MyString,
+    isPtr BOOLEAN,
+    namedElmts CNamedElmts,
+    choiceIdSymbol MyString,
+    choiceIdValue INTEGER,
+    optTestRoutineName MyString
+}
+
+-- use snacc compiler directives to overide the builtin types.
+--
+-- All strings used in module data struct are null terminated so
+-- can just use a char *
+-- Note the snacc comments before the PrintableString
+-- bind with the MyString TypeDef and the ones after PrintableString
+-- bind with the PrintableString Type ref.
+
+
+MyString ::= --snacc isPtrForTypeDef:"FALSE"
+             --snacc isPtrForTypeRef:"FALSE"
+             --snacc isPtrInChoice:"FALSE"
+             --snacc isPtrForOpt:"FALSE"
+             --snacc optTestRoutineName:"MYSTRING_NON_NULL"
+             --snacc genPrintRoutine:"FALSE"
+             --snacc genEncodeRoutine:"FALSE"
+             --snacc genDecodeRoutine:"FALSE"
+             --snacc genFreeRoutine:"FALSE"
+             --snacc printRoutineName:"printMyString"
+             --snacc encodeRoutineName:"EncMyString"
+             --snacc decodeRoutineName:"DecMyString"
+             --snacc freeRoutineName:"FreeMyString"
+             PrintableString --snacc cTypeName:"char *"
+
+END
+\end{verbatim}
+\end{small}
+
+
+\chapter{The Type Table (TBL) Data Structure ASN.1 Definition}
+
+The following is the type table data structure that Snacc uses for
+type table values.  Using ASN.1 gives a representation suitable for
+saving tables to files or sending them over a network to reconfigure a
+device (e.g. SNMP mib).
+
+This file is actually compiled by Snacc to compile itself.
+For bootstrapping purposes, an initial version is included in the distribution.
+
+\begin{small}
+\begin{verbatim}
+-- .../asn1specs/tbl.asn1
+--
+--  TBL types describe ASN.1 data structures.
+--  These can be used in generic, interpretive encoders/decoders.
+--  Interpretive decoders are typically slower, but don't eat memory
+--  with type-specific encoding and decoding code.
+--  The tbl types can also be sent over the network
+--  and allow dynamic re-configuration of encoders/decoders.
+--
+--  This definition is fairly small so it should be reasonable easy
+--  to understand.  To learn more about semantics of this data
+--  struct, look in snacc/tbl-tools/print-tbl/pasn1.c.
+--
+--  Copyright Mike Sample and UBC, 1992, 1993
+--
+
+TBL DEFINITIONS ::=
+BEGIN
+
+
+-- imports nothing
+-- exports nothing
+
+TBL ::= --snacc isPdu:"TRUE" -- SEQUENCE
+{
+   totalNumModules  INTEGER,  -- these totals can help allocation
+   totalNumTypeDefs INTEGER,  -- when decoding (ie use arrays)
+   totalNumTypes    INTEGER,
+   totalNumTags     INTEGER,
+   totalNumStrings  INTEGER,
+   totalLenStrings  INTEGER,
+   modules SEQUENCE OF TBLModule
+}
+
+TBLModule ::= SEQUENCE
+{
+    name     [0] IMPLICIT PrintableString,
+    id       [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
+    isUseful [2] IMPLICIT BOOLEAN, -- true if useful types module
+    typeDefs [3] IMPLICIT SEQUENCE OF TBLTypeDef
+}
+
+TBLTypeDef ::= SEQUENCE
+{
+   typeDefId TBLTypeDefId,
+   typeName  PrintableString OPTIONAL, -- I have forgotten why this is opt!
+   type      TBLType
+}
+
+TBLType ::= SEQUENCE
+{
+   typeId    [0] IMPLICIT TBLTypeId,
+   optional  [1] IMPLICIT BOOLEAN,
+   tagList   [2] IMPLICIT SEQUENCE OF TBLTag OPTIONAL,
+   content   [3] TBLTypeContent,
+   fieldName [4] IMPLICIT PrintableString OPTIONAL
+}
+
+TBLTypeContent ::= CHOICE
+{
+   primType [0] IMPLICIT NULL,
+   elmts    [1] IMPLICIT SEQUENCE OF TBLType,
+   typeRef  [2] IMPLICIT TBLTypeRef
+}
+
+TBLTypeRef ::= SEQUENCE
+{
+    typeDef TBLTypeDefId,
+    implicit BOOLEAN
+}
+
+TBLTypeId ::= ENUMERATED
+{
+    tbl-boolean (0),
+    tbl-integer (1),
+    tbl-bitstring (2),
+    tbl-octetstring (3),
+    tbl-null (4),
+    tbl-oid (5),
+    tbl-real (6),
+    tbl-enumerated (7),
+    tbl-sequence (8),
+    tbl-set (9),
+    tbl-sequenceof (10),
+    tbl-setof (11),
+    tbl-choice (12),
+    tbl-typeref (13)
+}
+
+TBLTypeDefId ::= INTEGER
+
+TBLTag ::= SEQUENCE
+{
+    tclass TBLTagClass,
+    code INTEGER (0..MAX)
+}
+
+TBLTagClass ::=  ENUMERATED { universal (0), application (1),
+                             context (2), private (3)}
+
+END
+
+\end{verbatim}
+\end{small}
+
+\chapter{\label{edex-files}ASN.1 Files for the Editor Example}
+
+The files can be found in {\ufn \dots/tcl-example/}.
+
+\begin{ASNcode}
+\label{edex0.asn1}%
+--\,-- file: edex0.asn1\\
+--\,--\\
+--\,-- SnaccEd example, simple types module\\
+\\
+EdEx-Simple DEFINITIONS ::=\\
+BEGIN\\
+\\
+RainbowColor ::= INTEGER\\
+\{\\
+  \>red(0), orange(1), yellow(2), green(3), blue(4), indigo(5), violet(6)\\
+\}\\
+\\
+DayOfTheWeek ::= ENUMERATED\\
+\{\\
+  \>sunday(0), monday(1), tuesday(2), wednesday(3), thursday(4), friday(5), saturday(6)\\
+\}\\
+\\
+Hand ::= BIT STRING\\
+\{\\
+  \>thumb(0), forefinger(1), middle-finger(2), ring-finger(3), little-finger(4)\\
+\}\\
+\\
+victory Hand ::= \{ forefinger, middle-finger \}\\
+\\
+END
+\end{ASNcode}
+
+\begin{ASNcode}
+\label{edex1.asn1}%
+--\,-- file: edex1.asn1\\
+--\,--\\
+--\,-- SnaccEd example, structured types module\\
+\\
+EdEx-Structured DEFINITIONS ::=\\
+BEGIN\\
+\\
+IMPORTS RainbowColor, DayOfTheWeek, Hand FROM EdEx-Simple;\\
+\\
+RGBColor ::= SEQUENCE\\
+\{\+\\
+  red INTEGER,\\
+  green INTEGER,\\
+  blue INTEGER\-\\
+\}\\
+\\
+Coordinate ::= CHOICE\\
+\{\+\\
+  cartesian [0] SEQUENCE \{ x REAL, y REAL \},\\
+  polar [1] SEQUENCE \{ angle REAL, distance REAL \}\-\\
+\}\\
+\\
+File ::= SET\\
+\{\+\\
+  name [0] PrintableString,\\
+  contents [1] OCTET STRING,\\
+  checksum [2] INTEGER OPTIONAL,\\
+  read-only [3] BOOLEAN DEFAULT FALSE\-\\
+\}\\
+\\
+Directory ::= SET\\
+\{\+\\
+  name PrintableString,\\
+  files SET OF File\-\\
+\}\\
+\\
+Simple ::= SET\\
+\{\+\\
+  null   [0] NULL,\\
+  bool   [1] BOOLEAN,\\
+  day    [2] DayOfTheWeek,\\
+  int    [3] INTEGER,\\
+  color  [4] RainbowColor,\\
+  real   [5] REAL,\\
+  bits   [6] Hand,\\
+  str    [7] OCTET STRING,\\
+  optstr [8] OCTET STRING OPTIONAL\-\\
+\}\\
+\\
+Structured ::= SET\\
+\{\+\\
+  coord [0] Coordinate,\\
+  color [1] CHOICE \{ rainbow RainbowColor, rgb RGBColor \}\-\\
+\}\\
+\\
+Various ::= SET\\
+\{\+\\
+  simple [0] Simple,\\
+  struct [1] Structured,\\
+  recursion [2] Various OPTIONAL\-\\
+\}\\
+\\
+END
+\end{ASNcode}
diff --git a/SecuritySNACCRuntime/doc/c++-gen.tex b/SecuritySNACCRuntime/doc/c++-gen.tex
new file mode 100644
index 00000000..47629b5d
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/c++-gen.tex
@@ -0,0 +1,720 @@
+% file: .../doc/c++-gen.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c++-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: c++-gen.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:51  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:35  rj
+% first check-in
+%
+
+\chapter{\label{c++-code-gen-chapter}C++ Code Generation}
+
+\section{\label{intro-C++-section}Introduction}
+
+The C++ backend of snacc was designed after the C backend had been
+written.  The basic model that the generated C++ uses is similar to
+that of the generated C, but benefits from the object oriented features of
+C++.  This was my first real foray into C++ which may be evident from
+some of the design.
+
+As with C, two files are generated for each ASN.1 module, a {\ufn .C}
+and a {\ufn .h} file.
+
+Some cleaner designs were rejected either due to their poor
+performance or the inability of the available C++ compiler to handle
+those features.
+
+Tags and lengths would fit nicely into their own classes but
+performance was considerably worse than the technique used in the C
+environment.  The C design was retained in the C++ model for its
+superior performance.
+
+For error management C++'s {\C try} and {\C throw} are obvious
+replacements for the {\C setjmp} and {\C longjmp} used by the C
+decoders. Unfortunately this is a newer C++ feature and is not yet
+supported by gcc.
+
+C++ templates are very attractive for type safe lists (for SET OF and
+SEQUENCE OF) without duplicating code.  Template support was shaky in
+gcc at the time the generated code was being tested so they were
+rejected. Instead, each list generates its own new class with all of
+the standard list routines.
+
+As with the C code generation chapter, we will use the EX1 module to
+help illustrate some of the code generation.  The following is the
+same EX1 module used in the C section.
+
+\begin{ASNcode}
+EX1 DEFINITIONS ::=\\
+BEGIN\\
+\\
+anOidVal      OBJECT IDENTIFIER ::= \{ joint-iso-ccitt 40 foobar(29) \}\\
+theSameOidVal OBJECT IDENTIFIER ::= \{ 2 40 29 \}\\
+anIntVal      INTEGER ::= 1\\
+aBoolVal      BOOLEAN ::= TRUE\\
+\\
+T1 ::= SEQUENCE\\
+\{\+\\
+  INTEGER OPTIONAL,\\
+  OCTET STRING OPTIONAL,\\
+  ENUMERATED \{ a(0), b(1), c(2) \},\\
+  SEQUENCE OF INTEGER,\\
+  SEQUENCE \{ id OBJECT IDENTIFIER, value OCTET STRING \},\\
+  CHOICE \{ INTEGER, OBJECT IDENTIFIER \}\-\\
+\}\\
+\\
+END
+\end{ASNcode}
+
+The C++ backend to snacc is in the {\ufn \dots/compiler/back-ends/c++-gen/} directory if you want to alter it.
+
+\section{\label{naming-C++-section}ASN.1 to C++ Naming Conventions}
+
+The C++ name for a type or value is the same as its ASN.1 name with
+any hyphens converted to underscores.
+
+When an ASN.1 type or value name (after converting any hyphens to
+underscores) conflicts with a C++ keyword or the name of a type in
+another ASN.1 module (name clashes within the same ASN.1 scope are
+considered errors and are detected earlier), the resulting C++ class
+name will be the conflicting name with digits appended to it.
+
+Empty field names in SETs, SEQUENCEs, and CHOICEs will be filled.  The
+field name is derived from the type name for that field. The library
+types such as INTEGER etc. have default field names defined by the
+compiler (see {\ufn \dots/compiler/back-ends/c-gen/rules.c} and
+{\ufn \dots/compiler/back-ends/c++-gen/rules.c}).
+The first letter of the field name is in lower case.
+Empty field names should be fixed properly by adding them to the ASN.1 source.
+
+New type definitions will be generated for SETs, SEQUENCEs, CHOICEs,
+ENUMERATED, INTEGERs with named numbers and BIT STRINGs with named bits
+whose definitions are embedded in other SET, SEQUENCE, SET OF,
+SEQUENCE OF, or CHOICE definitions.  The name of the new type
+is derived from the name of the type in which it was embedded and will
+be made unique by appending digits if necessary.
+
+\section{\label{type-gen-C++-section}ASN.1 to C++ Class Translation}
+
+This section describes how C++ classes are used to represent each
+ASN.1 type.  First, the general characteristics of each ASN.1 type's
+C++ class will be discussed followed by how the aggregate types (SETs,
+SEQUENCEs, CHOICEs, SET OFs, and SEQUENCE OFs) are represented.  The
+representations of non-aggregate types (INTEGER, BOOLEAN, OCTET
+STRING, BIT STRING, OBJECT IDENTIFIER) and ANY and ANY DEFINED BY
+types are presented in the next chapter since they form part of the
+C++ ASN.1 runtime library.
+
+Every ASN.1 type is represented by a C++ class with the following
+characteristics:
+\newcounter{saveenumi}
+\begin{enumerate}
+  \item it inherits from the {\C AsnType} base class
+  \item it has a parameterless constructor
+  \item it has a copy constructor
+  \item it has a destructor
+  \item it has a clone method, {\C Clone}
+  \item it has an assignment operator
+  \item it has a content encode and decode method, {\C BEncContent} and {\C BDecContent}
+  \item it has a PDU encode and decode method, {\C BEnc} and {\C BDec}
+  \item it has a top level interfaces to the PDU encode and decode methods (handles the {\C setjmp} etc.) for the user, {\C BEncPdu} and {\C BDecPdu}
+  \item it has a print method, {\C Print}, a virtual function that gets called from a global <\/<-operator
+  \setcounter{saveenumi}{\value{enumi}}
+\end{enumerate}
+If the metacode has been enabled:
+\begin{enumerate}
+  \setcounter{enumi}{\value{saveenumi}}
+  \item it has a virtual function {\C \_getdesc} that returns the classes meta description% (only if metacode is enabled)
+  \item if it is a structured type, it has a virtual function {\C \_getref} that returns a pointer to one of its components/members, specified through its name% (only if metacode is enabled)
+  \setcounter{saveenumi}{\value{enumi}}
+\end{enumerate}
+If the Tcl code has been enabled:
+\begin{enumerate}
+  \setcounter{enumi}{\value{saveenumi}}
+  \item it has a virtual function {\C TclGetDesc} to access the metacode's {\C \_getdesc} routine from Tcl% (only if Tcl code is enabled)
+  \item it has a virtual function {\C TclGetVal} to retrieve an instance's value% (only if Tcl code is enabled)
+  \item it has a virtual function {\C TclSetVal} to change an instance's value% (only if Tcl code is enabled)
+  \item for SET, SEQUENCE, SET OF and SEQUENCE of: it has a virtual function {\C TclUnsetVal} to clear OPTIONAL members or to delete list elements, respectively% (only if Tcl code is enabled)
+\end{enumerate}
+
+The following C++ fragment shows the class features listed above in greater
+detail.
+\begin{Ccode}
+class Foo: public AsnType\\
+\{\+\\
+  \dots // data members\\
+\\
+\<public:\\
+          \>\>Foo();\\
+          \>\>Foo (const Foo \&);\\
+          \>\>\~{}Foo();\\
+  AsnType \>\>*Clone() const;\\
+  Foo     \>\>\&operator = (const Foo \&);\\
+\\
+  // content encode and decode routines\\
+  AsnLen  \>\>BEncContent (BUF\_TYPE b);\\
+  void    \>\>BDecContent (BUF\_TYPE b, AsnTag tag, AsnLen elmtLen,\\
+                     \`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  // PDU (tags/lengths/content) encode and decode routines\\
+  AsnLen  \>\>BEnc (BUF\_TYPE b);\\
+  void    \>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  // methods most likely to be used by your code.\\
+  // Returns non-zero for success\\
+  int     \>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int     \>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void    \>\>Print (ostream \&os) const;\\
+\\
+\<\#if META\\
+  const AsnTypeDesc  \>\>*\_getdesc() const;\\
+  AsnType            \>\>*\_getref (const char *membername, bool create = false);\\
+\<\#if TCL\\
+  int                \>\>TclGetDesc (Tcl\_DString *) const;\\
+  int                \>\>TclGetVal (Tcl\_Interp *) const;\\
+  int                \>\>TclSetVal (Tcl\_Interp *, const char *valstr);\\
+  int                \>\>TclUnsetVal (Tcl\_Interp *, const char *membername);\\
+\<\#endif\\
+\<\#endif\\
+\<\};
+\end{Ccode}
+
+{\C BEnc} and {\C BDec} are PDU encode and decode methods.
+{\C BEnc} encodes the tag and length pairs for the object's type as
+well as the content (the object's value) to the given buffer,
+{\C b}, and returns the number of bytes written to the buffer for
+the encoding.
+
+{\C BDec} decodes the expected tag and length pairs as well as the
+content of the object it is invoked upon from the given buffer,
+{\C b}, and increments {\C bytesDecoded}  by the byte length of
+the tag(s), length(s) and value decoded.  The {\C env} parameter
+will be used with {\C longjmp} if any decoding error occurs.
+Decoding errors can be reported via {\C longjmp} from any of the
+routines that {\C BDec} calls, such as {\C BDecContent};
+{\C BDec} will call {\C longjmp} directly if the value does not
+have the correct tag(s).
+
+{\C BEncContent} and {\C BDecContent} only deal with the content
+of the type their object represents.  {\C BEncContent} encodes the
+object's value to the given buffer, {\C b}.
+
+{\C BDecContent} decodes the object's value from the given buffer,
+{\C b}.  The last tag and length pair on the content must be passed in
+via the {\C tag} and {\C elmtLen} parameters.  The {\C tag},
+although always present, will only be used when decoding OCTET STRING and
+BIT STRING related types, to determine whether the encoding is
+constructed.  The {\C elmtLen} is the length of the content and may
+be the indefinite length form.  {\C bytesDecoded} is incremented by
+the actual number of bytes in the content; this is normally the same
+as {\C elmtLen} unless the indefinite length form was decoded.  The
+{\C env} parameter will be used with {\C longjmp} if any decoding
+error occurs.  The possible decoding errors depend on the type that is
+being decoded.
+
+{\C BEncPdu} and {\C BDecPdu} are top-level interfaces to the PDU
+encode and decode routines.  They present the simplest interface;
+they return TRUE if the operation succeeded and FALSE if an error
+occurred.   Note that the {\C BDecPdu} routine sets up the
+{\C env} parameter using {\C setjmp} for any {\C longjmp} calls
+that may occur.  If you call {\C BDec} or {\C BDecContent}
+directly from your code, you must use {\C setjmp} to setup the
+{\C env} parameter.  {\C BEncPdu} checks for any buffer writing
+errors and {\C BDecPdu} checks for any buffer reading errors.
+
+The {\C Print} method prints the object's value in ASN.1 value
+notation.  When printing SETs and SEQUENCEs, a global variable
+is used for the current indent.
+
+The {\C AsnType} base class, parameterless constructor and
+{\C Clone} method are required by the ANY and ANY DEFINED BY type
+handling mechanism explained in Sections \ref{asntype-C++-section} and
+\ref{any-C++-section}.  In brief, the {\C AsnType} provides a base type
+that has virtual {\C BEnc}, {\C BDec} and {\C Clone} routines.
+The {\C Clone} routine is used to generate a new instance (not a
+copy) of the object that it is invoked on.  This allows the ANY
+DEFINED BY type decoder to create a new object of the correct type
+from one stored in a hash table, when decoding (the {\C Clone}
+routine calls the parameterless constructor).  The virtual {\C BEnc}
+and {\C BDec} are called from {\C AsnAny} {\C BEnc} and
+{\C BDec} methods.
+
+The meta routines and the Tcl interface will be described in chapters \ref{meta-chapter} and \ref{tcl-if-chapter}, respectively.
+
+\subsection{\label{C++-set-seq-section}SET and SEQUENCE}
+
+SET and SEQUENCE types generate classes that have their components as
+public data members.  This makes accessing the components similar to
+referencing the fields of a C struct.  For example the {\C T1} type in
+module EX1 will produce the following C++ class:
+
+\begin{Ccode}
+class T1: public AsnType\\
+\{\\
+public:\+\\
+  AsnInt    \>\>*integer;\\
+  AsnOcts   \>\>*octs;\\
+  T1Enum    \>\>t1Enum;\\
+  T1SeqOf   \>\>t1SeqOf;\\
+  T1Seq     \>\>*t1Seq;\\
+  T1Choice  \>\>*t1Choice;\\
+\\
+            \>\>T1();\\
+%  {\\
+%    /* init optional/default elements to NULL */\\
+%    integer = NULL;\\
+%    octs = NULL;\\
+%  }\\
+	    \>\>T1 (const T1 \&);\\
+	    \>\>\~{}T1();\\
+%  AsnType *Clone() { return new T1; }\\
+  AsnType   \>\>*Clone() const;\\
+\\
+  T1        \>\>\&operator = (const T1 \&);\\
+\\
+  AsnLen    \>\>BEnc (BUF\_TYPE b);\\
+  void      \>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen    \>\>BEncContent (BUF\_TYPE b);\\
+  void      \>\>BDecContent (BUF\_TYPE b, AsnTag tag, AsnLen elmtLen,\\
+                         \`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int       \>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int       \>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void      \>\>Print (ostream \&os) const;\\
+\\
+\<\#if META\\
+  static const AsnSequenceTypeDesc     \\
+				\>\>\_desc;\\
+  static const AsnSequenceMemberDesc   \\
+				\>\>mdescs[];\\
+  const AsnTypeDesc             \>\>*\_getdesc() const;\\
+  AsnType                       \>\>*\_getref (const char *membername, bool create = false);\\
+\\
+\<\#if TCL\\
+  int                   \>\>TclGetDesc (Tcl\_DString *) const;\\
+  int                   \>\>TclGetVal (Tcl\_Interp *) const;\\
+  int                   \>\>TclSetVal (Tcl\_Interp *, const char *valstr);\\
+  int                   \>\>TclUnsetVal (Tcl\_Interp *, const char *membname);\\
+\<\#endif // TCL\\
+\<\#endif // META\\
+\<\};
+\end{Ccode}
+
+All OPTIONAL components in a SET or SEQUENCE are referenced by pointer.
+The constructor will automatically set OPTIONAL fields to {\C NULL}\@.  The
+other methods are as described at the beginning of this section.
+
+SETs and SEQUENCEs must contain all non-OPTIONAL components and
+SEQUENCEs must be ordered, otherwise an error is reported.  Tagging
+errors are also reported.  All detected errors abort the decoding
+process via {\C longjmp}.
+
+\subsection{\label{C++-choice-section}CHOICE}
+
+Each CHOICE type generates a class that has an anonymous union to hold the
+components of the CHOICE and a {\C choiceId} field to indicate which
+component is present.
+
+Anonymous (un-named) unions allow you to reference the choice components
+with just the field name of the component; this makes referencing the
+contents of a CHOICE the same a referencing the contents of a SET or
+SEQUENCE\@.
+
+The {\C choiceId} field contains a value in the {\C ChoiceIdEnum}
+that indicates the CHOICE field that is present.  The names in the
+enumeration are derived from the field names of the CHOICE components.
+
+When building a local value to be encoded, you must be sure to set the
+{\C choiceId} such that it corresponds to the value in the union.  The
+decoder will set the {\C choiceId} when decoding incoming values.
+
+Tagging errors are reported and abort the decoding process via
+{\C longjmp}.
+
+The following C++ class is produced for the CHOICE in the EX1 module.
+
+\begin{Ccode}
+class T1Choice: public AsnType\\
+\{\\
+public:\+\\
+  enum ChoiceIdEnum\\
+  \{\+\\
+    integerCid = 0,\\
+    oidCid = 1\-\\
+  \};\\
+\\
+  enum ChoiceIdEnum \>\>choiceId;\\
+  union\\
+  \{\+\\
+    AsnInt   \>*integer;\\
+    AsnOid   \>*oid;\-\\
+  \};\\
+\\
+             \>\>T1Choice();\\
+	     \>\>T1Choice (const T1Choice \&);\\
+	     \>\>\~{}T1Choice();\\
+  AsnType    \>\>*Clone() const;\\
+\\
+  T1Choice   \>\>\&operator = (const T1Choice \&);\\
+\\
+  AsnLen     \>\>BEncContent (BUF\_TYPE b);\\
+  void       \>\>BDecContent (BUF\_TYPE b, AsnTag tag, AsnLen elmtLen,\\
+                          \`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen     \>\>BEnc (BUF\_TYPE b);\\
+  void       \>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int        \>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int        \>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void       \>\>Print (ostream \&os) const;\\
+\\
+\<\#if META\\
+  static const AsnChoiceTypeDesc        \>\>\_desc;\\
+  static const AsnChoiceMemberDesc      \\
+					\>\>\_mdescs[];\\
+\\
+  const AsnTypeDesc             \>\>*\_getdesc() const;\\
+  AsnType                       \>\>*\_getref (const char *membername, bool create = false);\\
+\\
+\<\#if TCL\\
+  int                   \>\>TclGetDesc (Tcl\_DString *) const;\\
+  int                   \>\>TclGetVal (Tcl\_Interp *) const;\\
+  int                   \>\>TclSetVal (Tcl\_Interp *, const char *valstr);\\
+\<\#endif // TCL\\
+\<\#endif // META\\
+\<\};
+\end{Ccode}
+
+
+
+\subsection{\label{C++-set-of-section}SET OF and SEQUENCE OF}
+
+Each SET OF and SEQUENCE OF type produces its own list class, unlike
+the C backend which uses a single generic list type for all lists.
+This makes the C++ list routines type safe which allows the C++
+compiler to detect more programmer errors.
+
+C++ templates should be used to reduce the code duplication when they
+become widespread and reliably implemented.  The duplicated list
+handling methods may bloat the size of the generated code.
+
+Any tagging errors are reported and abort the decoding process via
+{\C longjmp}.
+
+From the EX1 ASN.1 module the following list is produced:
+\begin{Ccode}
+class T1SeqOf: public AsnType\\
+\{\\
+protected:\+\\
+    unsigned long int\>\>count;\\
+    struct AsnListElmt\\
+    \{\+\\
+        struct AsnListElmt \>*next;\\
+        struct AsnListElmt \>*prev;\\
+        AsnInt             \>*elmt;\-\\
+    \}                   \>\>*first, *curr, *last;\\
+\\
+\<public:\\
+                         \>\>T1SeqOf() \{ count = 0; first = curr = last = NULL; \}\\
+                         \>\>\~{}T1SeqOf();\\
+    AsnType              \>\>*Clone() const;\\
+\\
+    void                 \>\>SetCurrElmt (unsigned long int index);\\
+    unsigned long int    \>\>GetCurrElmtIndex();\\
+    void                 \>\>SetCurrToFirst();\\
+    void                 \>\>SetCurrToLast();\\
+\\
+    // reading member fcns\\
+    int                  \>\>Count() const;\\
+    AsnInt               \>\>*First() const;\\
+    AsnInt               \>\>*Last() const;\\
+    AsnInt               \>\>*Curr() const;\\
+    AsnInt               \>\>*Next() const;\\
+    AsnInt               \>\>*Prev() const;\\
+\\
+    // routines that move the curr elmt\\
+    AsnInt               \>\>*GoNext();\\
+    AsnInt               \>\>*GoPrev();\\
+\\
+    // write \& alloc fcns--returns new elmt\\
+    AsnInt               \>\>*Append();  // add elmt to end of list\\
+    AsnInt               \>\>*Prepend(); // add elmt to beginning of list\\
+    AsnInt               \>\>*InsertBefore(); // insert elmt before current elmt\\
+    AsnInt               \>\>*InsertAfter();  // insert elmt after current elmt\\
+\\
+    // write \& alloc \& copy--returns list after copying elmt\\
+    T1SeqOf              \>\>\&AppendCopy (AsnInt \&elmt);  // add elmt to end of list\\
+    T1SeqOf              \>\>\&PrependCopy (AsnInt \&elmt); // add elmt to beginning of list\\
+    T1SeqOf              \>\>\&InsertBeforeAndCopy (AsnInt \&elmt); // insert elmt before current elmt\\
+    T1SeqOf              \>\>\&InsertAfterAndCopy (AsnInt \&elmt); // insert elmt after current elmt\\
+\\
+    // removing the current elmt from the list\\
+    void                 \>\>RemoveCurrFromList();\\
+\\
+    // encode and decode routines\\
+    AsnLen               \>\>BEncContent (BUF\_TYPE b);\\
+    void                 \>\>BDecContent (BUF\_TYPE b, AsnTag tag, AsnLen elmtLen,\\
+                         \` AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+    AsnLen               \>\>BEnc (BUF\_TYPE b);\\
+    void                 \>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+    int                  \>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+    int                  \>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+    void                 \>\>Print (ostream \&os);\\
+\\
+\<\#if META\\
+  static const AsnListTypeDesc  \>\>\_desc;\\
+  const AsnTypeDesc             \>\>*\_getdesc() const;\\
+  AsnType                       \>\>*\_getref (const char *index, bool create = false);\\
+\\
+\<\#if TCL\\
+  int                   \>\>TclGetDesc (Tcl\_DString *) const;\\
+  int                   \>\>TclGetVal (Tcl\_Interp *) const;\\
+  int                   \>\>TclSetVal (Tcl\_Interp *, const char *valstr);\\
+  int                   \>\>TclUnsetVal (Tcl\_Interp *, const char *valstr);\\
+\<\#endif // TCL\\
+\<\#endif // META\\
+\<\};
+\end{Ccode}
+
+Each list is doubly linked to allow simple reverse traversal for
+backwards encoding.  The {\C prev} pointer will be {\C NULL} for the
+first element of the list and the {\C next} pointer will be {\C NULL} for
+the last element of the list.
+
+Each list maintains a pointer to the current element of the list.
+Several routines are provided to manipulate the current item.  Since
+there is only one current pointer, you may have to save and restore
+the current pointer with the {\C GetCurrElmtIndex} and
+{\C SetCurrElmt} methods if you call routines that deal with the
+list while iterating through it.
+
+In addition to the standard encode, decode and print methods, some
+list utility routines are included in each list class.  They are
+fairly simple and are described briefly here.
+
+\begin{Ccode}
+void \>\>\>SetCurrElmt (unsigned long int index);
+\end{Ccode}
+This sets the current pointer to the element with the given index.
+Indexes start at zero, that is, the first element in the list has an
+index of zero.  If the given index is greater than or equal to the
+number of elements in the list, the current pointer is set to the last
+element of the list.
+
+\begin{Ccode}
+unsigned long int \>\>\>GetCurrElmtIndex();
+\end{Ccode}
+This returns the index of the current element.  If the current pointer
+is {\C NULL} (or does not reference an element of the list, which is an
+error condition), the index returned will be greater than or equal to
+the number of elements in the list (indexes start at zero so this is
+an invalid index).
+
+
+\begin{Ccode}
+void \>\>\>SetCurrToFirst();
+\end{Ccode}
+This sets the current pointer to the first element of the list. If the
+list is empty, it is set to {\C NULL}\@.
+\begin{Ccode}
+void \>\>\>SetCurrToLast();
+\end{Ccode}
+This sets the current pointer to the last element of the list. If the
+list is empty, it is set to {\C NULL}\@.
+
+
+\begin{Ccode}
+int \>\>\>Count() const;
+\end{Ccode}
+This returns the number of elements in the list.
+
+\begin{Ccode}
+AsnInt \>\>\>*First() const;\\
+AsnInt \>\>\>*Last() const;\\
+AsnInt \>\>\>*Curr() const;\\
+AsnInt \>\>\>*Next() const;\\
+AsnInt \>\>\>*Prev() const;
+\end{Ccode}
+The above routines return a pointer to the list element that the
+routine name indicates.  They return {\C NULL} if the requested element is
+not present.  For example {\C First} will return a pointer to the
+first element in the list or {\C NULL} if the list is empty.  These
+routines do not affect the state of the list; the current pointer and
+the count remain the same.
+
+\begin{Ccode}
+AsnInt \>\>\>*GoNext();\\
+AsnInt \>\>\>*GoPrev();
+\end{Ccode}
+These routines change the current pointer to the next/previous element
+and return a pointer to that element.  If the current element is {\C NULL} or
+points to the last element, {\C GetNext} returns {\C NULL}\@. Similarly, if
+the current element is {\C NULL} or points to the first element, {\C GetPrev}
+returns {\C NULL}\@.
+
+
+\begin{Ccode}
+AsnInt \>\>\>*Append();
+\end{Ccode}
+This allocates a new list element, appends it to the end of the list
+and returns a pointer to the new list element.  Notice that you must
+set the value of the returned list element.
+
+\begin{Ccode}
+AsnInt \>\>\>*Prepend();
+\end{Ccode}
+This allocates a new list element, prepends it to the beginning of the
+list and returns a pointer to the new list element. You must set the
+value of the returned list element.
+
+\begin{Ccode}
+AsnInt \>\>\>*InsertBefore();
+\end{Ccode}
+This allocates a new list element, inserts it before the current list
+element and returns a pointer to the new list element.  You must set
+the value of the returned list element.  If the current pointer is
+{\C NULL}, the new element is placed at the beginning of the list.
+
+\begin{Ccode}
+AsnInt \>\>\>*InsertAfter();
+\end{Ccode}
+This allocates a new list element, inserts it after the current list
+element and returns a pointer to the new list element.  You must set
+the value of the returned list element.  If the current pointer is
+{\C NULL}, the new element is placed at the end of the list.
+
+\begin{Ccode}
+T1SeqOf \>\>\>\&AppendCopy (AsnInt \&elmt);\\
+T1SeqOf \>\>\>\&PrependCopy (AsnInt \&elmt);\\
+T1SeqOf \>\>\>\&InsertBeforeAndCopy (AsnInt \&elmt);\\
+T1SeqOf \>\>\>\&InsertAfterAndCopy (AsnInt \&elmt);
+\end{Ccode}
+These are similar to the {\C Append}, {\C Prepend},
+{\C InsertBefore} and {\C InsertAfter} routines except that a
+copy of the given element's value is placed in the list and the list
+itself is returned.
+
+\subsection{\label{C++-enumerated-section}ENUMERATED, Named Numbers and Named Bits}
+
+The C++ type generator encapsulates each ENUMERATED type, INTEGER
+with named numbers and BIT STRING with named bits in a new class that
+inherits from the proper base class and defines the named elements.
+This provides a separate scope for these identifiers so their symbol
+will be exactly the same as their ASN.1 counterpart.  Currently these
+identifiers are not checked for conflicts with C++ keywords, so you
+may have to modify some of them in the ASN.1 modules.
+
+Inheritance is used for attaching ENUMERATED, named number and named
+bit information.  ENUMERATED types inherit from the {\C AsnEnum} class,
+INTEGERs with named number types inherit from the {\C AsnInt} class and BIT
+STRINGs with named bits inherit from the {\C AsnBits} class.
+
+If the tagging on the type is different from the type it inherits
+from, the PDU encode and decode methods are re-defined with the
+correct tags to override the PDU encode and decode methods of the base
+class.
+
+As with the other types, any tagging errors are reported and abort the
+decoding process via {\C longjmp}.  No range checking is done on the
+decoded values although it would be easy to provide a new
+{\C BDecContent} method in the new class that calls the base class's
+and then checks the range of the result.
+
+\begin{Ccode}
+/* ENUMERATED { a(0), b(1), c(2) } */\\
+class T1Enum: public AsnEnum\\
+\{\\
+public:\\
+\#if TCL\\
+         \>               \>\>T1Enum(): AsnEnum (\_nmdescs[0].value) \{\}\\
+\#else\\
+         \>               \>\>T1Enum(): AsnEnum () \{\}\\
+\#endif\+\\
+                          \>\>T1Enum (int i): AsnEnum (i) \{\}\\
+  enum\\
+  \{\+\\
+    a = 0,\\
+    b = 1,\\
+    c = 2\-\\
+  \};\\
+\\
+\<\#if META\\
+  static const AsnNameDesc      \>\>\_nmdescs[];\\
+  static const AsnEnumTypeDesc  \>\>\_desc;\\
+  const AsnTypeDesc             \>\>*\_getdesc() const;\\
+\<\#endif // META\\
+\<\};
+\end{Ccode}
+
+\section{\label{val-gen-C++-section}ASN.1 to C++ Value Translation}
+
+C++ {\C const} values are used to hold ASN.1 defined values.  C++
+values will be produced for INTEGER, BOOLEAN and OBJECT IDENTIFIER
+ASN.1 values.  An {\C extern} declaration for each {\C const} value is
+written at the end of the header file of the value's module.  The
+{\C const} values are defined at the beginning of the {\ufn .C} file
+of the value's module.  The {\C extern} declarations are at the end
+of the header file so that any required class definitions are
+available.
+
+The following is from the end of the header file generated for the EX1
+module:
+\begin{Ccode}
+extern const AsnOid  \>\>\>anOidVal;\\
+extern const AsnOid  \>\>\>theSameOidVal;\\
+extern const AsnInt  \>\>\>anIntVal;\\
+extern const AsnBool \>\>\>aBoolVal;
+% \\ extern const AsnInt  \>\>\>foobar;
+\end{Ccode}
+
+The following is from the beginning of the {\ufn .C} file generated
+for the EX1 module:
+\begin{Ccode}
+const AsnOid  \>\>\>anOidVal (2, 40, 29);\\
+const AsnOid  \>\>\>theSameOidVal (2, 40, 29);\\
+const AsnInt  \>\>\>anIntVal (1);\\
+const AsnBool \>\>\>aBoolVal (true);
+% \\ const AsnInt  \>\>\>foobar (29);
+\end{Ccode}
+
+The C++ constructor mechanism is used to generate these values.  This
+mechanism is superior to C static initialization because it allows C++
+code to be run to initialize the values.
+
+\section{\label{compiler-dir-C++-section}Compiler Directives}
+Compiler directives are ignored by the C++ backend of snacc.  If you want
+to implement them, look at the {\C FillCxxTypeDefInfo} routine in
+file {\ufn \dots/compiler/back-ends/c++-gen/types.c}.  Then look at the
+way it is done for the C backend (file
+{\ufn \dots/compiler/back-ends/c-gen/type-info.c})
+
+\section{\label{compiling-gen-C++-section}Compiling the Generated C++ Code}
+
+When compiling the generated C++ code you will need:
+\begin{enumerate}
+\item
+  The include directory where the files from {\ufn \dots/c++-lib/inc/} have been installed in your include path so that the C++ sources can include these library header files.
+  The header files should be included with statements like {\C \#include <snacc/c++/asn-incl.h>} and your C++ compiler should be supplied with {\ufn -I/usr/local/include} in case snacc got installed under {\ufn /usr/local/}.
+\item
+  to link with the C++ ASN.1 runtime library, {\ufn \dots/c++-lib/libasn1c++.a}.
+  In case snacc got installed under {\ufn /usr/local/}, your linker may need to be supplied with {\ufn -L/usr/local/lib} and {\ufn -lasn1c++} as arguments.
+\item
+  to link with the math library ({\ufn -lm}), since the ASN.1 REAL type's encode and decode routine use some math routines.
+\end{enumerate}
+
+See the example in {\ufn \dots/c++-examples/simple/} for a complete
+example. The makefile and main routines are probably the most
+important.  There are several other examples in the
+{\ufn \dots/c++-examples/} directory.
diff --git a/SecuritySNACCRuntime/doc/c++-lib.tex b/SecuritySNACCRuntime/doc/c++-lib.tex
new file mode 100644
index 00000000..6790dc9f
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/c++-lib.tex
@@ -0,0 +1,973 @@
+% file: .../doc/c++-lib.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c++-lib.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: c++-lib.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:51  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:37  rj
+% first check-in
+%
+
+\chapter{\label{lib-C++-chapter}C++ ASN.1 Library}
+\section{\label{libover-C++-section}Overview}
+
+The following sections describe the C++ representation of the
+non-aggregate ASN.1 types, ANY and ANY DEFINED BY types and
+the buffer and memory management.  These classes and routines make
+up the C++ ASN.1 runtime library. Every aggregate ASN.1 type will be
+composed of these library types. The source files for this library
+are in {\ufn \dots/c++-lib/inc/} and {\ufn \dots/c++-lib/src/}.
+
+As mentioned in the last chapter, each ASN.1 type is represented by a
+C++ class which inherits from the {\C AsnType} base class.  In
+addition to the standard encode, decode, print and clone methods
+described in the last chapter, each ASN.1 type class in the library
+may also have special constructors and other routines that simplify
+their use.
+
+Unlike the classes generated for some of the aggregate types such as
+SETs and SEQUENCEs, the library types' data members are typically
+protected and accessed via methods.
+
+All of the library classes' {\C BDec} routines will report tagging errors
+via {\C longjmp()} as described in section~\ref{type-gen-C++-section}.
+
+The top level PDU encode and decode methods are the same for all
+library types so they are defined as macros in
+{\ufn \dots/c++-lib/inc/asn-config.h}. For clarity's sake, the macro
+that is used to define these methods in the library type class
+definitions will be replaced with the actual prototypes.
+
+Run the {\ufn test-lib} program in {\ufn \dots/c++-examples/test-lib/}
+to make sure the library routines are working properly for your
+architecture.  The testing is not exhaustive but should point out
+obvious problems.
+
+
+\section{\label{tag-C++-section}Tags}
+
+The C++ tags are identical to those used in snacc's C ASN.1
+environment.  While it would have been nice to define a tag class, the
+performance cost would likely have been noticeable.  Also, the snacc
+users usually do not have to muck around with tags directly, so the
+lack of a class interface will probably not be missed.  The C ASN.1
+tags are described in Section~\ref{tag-C-section}.
+
+Initially I defined a C++ class for tags, but close examination of the
+produced assembly code led me to reject it.  The C++ class for tags
+used the C tag representation internally and had constructor, encode
+and decode methods.  The constructor could not be used as
+{\C switch} statement case labels like {\C MAKE\_TAG\_ID} because it
+did not reduce to an integer constant; this caused problems in the
+generated decoders.
+
+As with the C representation of tags, 4 byte long integers limit the
+maximum representable tag code to $2^{21}$.  Again, this should not be
+a problem.
+
+
+\section{\label{len-C++-section}Lengths}
+
+The C++ representation of lengths is the same at the C representation
+described in Section~\ref{len-C-section}.  The length type was not given
+its own C++ class for reasons similar to those of tags.
+
+
+\section{\label{asntype-C++-section}The AsnType Base Class}
+
+Every ASN.1 type's C++ class uses the {\C AsnType} as its base class.
+The {\C AsnType} base class provides the following virtual functions:
+\begin{itemize}
+  \item the destructor
+  \item {\C Clone()}
+  \item {\C BDec()}
+  \item {\C BEnc()}
+  \item {\C Print()}
+  \item {\C \_getdesc()} (metacode)
+  \item {\C \_getref()} (metacode)
+  \item {\C TclGetDesc()} (Tcl interface)
+  \item {\C TclGetVal()} (Tcl interface)
+  \item {\C TclSetVal()} (Tcl interface)
+  \item {\C TclUnsetVal()} (Tcl interface)
+\end{itemize}
+
+The {\C AsnType} class is defined as follows:
+\begin{Ccode}
+class AsnType\\
+\{\\
+public:\+\\
+  virtual			\>\>\~{}AsnType();\\
+\\
+\<\#ifdef SUPPORT\_ANY\_TYPE\\
+  virtual AsnType		\>\>*Clone() const;\\
+  virtual void			\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+  virtual AsnLen		\>\>BEnc (BUF\_TYPE b);\\
+\<\#else\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env) \{\}\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b) \{ return 0; \}\\
+\<\#endif\\
+  virtual void			\>\>Print (ostream \&os) const;\\
+\\
+\<\#if META\\
+  static const AsnTypeDesc	\>\>\_desc;\\
+\\
+  virtual const AsnTypeDesc	\>\>*\_getdesc() const;\\
+  virtual AsnType		\>\>*\_getref (const char *membername, bool create=false);\\
+\\
+\<private:\\
+  const char			\>\>*\_typename() const;\\
+\-\\
+\#if TCL\\
+public:\+\\
+  virtual int			\>\>TclGetDesc (Tcl\_DString *) const;\\
+  virtual int			\>\>TclGetVal (Tcl\_Interp *) const;\\
+  virtual int			\>\>TclSetVal (Tcl\_Interp *, const char *val);\\
+  virtual int			\>\>TclUnsetVal (Tcl\_Interp *, const char *membernames);\-\\
+\#endif // TCL\\
+\#endif // META\\
+\};
+\end{Ccode}
+
+The {\C AsnType} class and its virtual functions were added to
+support the ANY DEFINED BY type handling mechanism.  This mechanism is
+described in Section~\ref{any-C++-section}.
+
+Even if you do not use the ANY or ANY DEFINED BY types, the
+{\C AsnType} base class may be useful for adding features that are
+common to all of the types, such as changing the {\C new} and
+{\C delete} functions to improve performance.
+
+Virtual functions provide the simplest method of handling ANY DEFINED
+BY and ANY types. Unfortunately, calls to virtual functions are slower
+than calls to normal functions due to their indirect nature.  If you
+do not need support for the ANY DEFINED BY or ANY types you can remove
+most of the virtual functions to improve performance by undefining the
+{\C SUPPORT\_ANY\_TYPE} symbol (see the
+{\ufn asn-type.h} file).
+
+Note that a virtual destructor is included in the {\C AsnType} base
+class as well.  This is done to make sure the {\C delete} routine
+always gets the correct size.  See pages 215--217 of Stroustrup
+\cite{stroustrup} for a discussion of this.
+
+\section{\label{bool-C++-section}BOOLEAN}
+
+The BOOLEAN type is represented by the {\C AsnBool} class. The
+following is the class definition of {\C AsnBool} from the
+{\ufn \dots/c++-lib/inc/asn-bool.h} file.
+
+\begin{Ccode}
+class AsnBool: public AsnType\\
+\{\\
+protected:\+\\
+  bool				\>\>value;\\
+\\
+\<public:\\
+				\>\>AsnBool (const bool val): value (val) \{\};\\
+				\>\>AsnBool() \{\};\\
+  AsnType			\>\>*Clone() const;\\
+				\>\>operator bool() const \{ return value; \}\\
+  AsnBool			\>\>\&operator = (bool newvalue) \{ value = newvalue; return *this; \}\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen			\>\>BEncContent (BUF\_TYPE b);\\
+  void				\>\>BDecContent (BUF\_TYPE b, AsnTag tagId, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void				\>\>Print (ostream \&os) const;\\
+\\
+\<\#if META\\
+  static const AsnBoolTypeDesc	\>\>\_desc;\\
+\\
+  const AsnTypeDesc		\>\>*\_getdesc() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetVal (Tcl\_Interp *) const;\\
+  int				\>\>TclSetVal (Tcl\_Interp *, const char *val);\-\\
+\#endif // TCL\\
+\#endif // META\\
+\};
+\end{Ccode}
+
+The upcoming C++ standard \cite{c++-draft} defines a type {\C bool} accompanied by {\C false} and {\C true} to denote the boolean values.
+The Snacc configuration script checks whether the C++ compiler already supplies this new type and defines a look-alike if it does not.
+
+For backwards compatibility, {\C AsnBool::true} and {\C AsnBool::false} are still valid.
+
+The {\C operator bool()} is defined such that when an {\C AsnBool}
+value is cast to a boolean, it returns the C++ style boolean
+value of the {\C AsnBool}s value.  There is also a constructor for {\C AsnBool}
+that builds an {\C AsnBool} value from the given C++ style boolean
+value. These two methods allow you to manipulate and access
+{\C AsnBool} values in a straight forward way as the following code
+illustrates.
+\begin{Ccode}
+Message::Send()\\
+\{\+\\
+  AsnBool	\>\>okToSend;\\
+  bool		\>\>connectionOpen;\\
+  bool		\>\>pduOk;\\
+  \dots\\
+  okToSend = connectionOpen \&\& pduOk; // assign AsnBool from bool\\
+  if (okToSend) // cast AsnBool to bool\\
+    \>\dots\\
+\<\}
+\end{Ccode}
+
+The {\C AsnBool} class contains the standard encode and decode
+methods that were described in Chapter~\ref{c++-code-gen-chapter}.
+
+{\C BDecContent} will report an error via {\C longjmp} if the
+length of an encoded BOOLEAN value's content is not exactly 1 octet.
+
+Note that the {\C Clone} method returns an {\C AsnType~*} value
+instead of an {\C AsnBool~*}.  It might be more obvious to return an
+{\C AsnBool~*} since due to single inheritance an {\C AsnBool} is also
+an {\C AsnType}.  However, it must return an {\C AsnType~*} for it
+to override the virtual function {\C Clone} defined in the
+{\C AsnType}.
+
+The {\C Print} method will print either ``TRUE'' or ``FALSE''
+depending on the {\C AsnBool} value.  No newline or other formatting
+characters are printed.  The global indent information does not affect
+the output from this method.
+
+
+\section{\label{int-C++-section}INTEGER}
+
+The INTEGER type is represented by the {\C AsnInt} class. The
+following is the class definition of {\C AsnInt} from the
+{\ufn \dots/c++-lib/inc/asn-int.h} file.
+\begin{Ccode}
+class AsnInt: public AsnType\\
+\{\\
+protected:\+\\
+  AsnIntType			\>\>value;\\
+\\
+\<public:\\
+				\>\>AsnInt() \{\}\\
+				\>\>AsnInt (AsnIntType val): value (val) \{\}\\
+\\
+  AsnType			\>\>*Clone() const;\\
+\\
+				\>\>operator AsnIntType() \{ return value; \}\\
+  AsnInt			\>\>\&operator = (AsnIntType newvalue) \{ value = newvalue; return *this; \}
+\\
+  void				\>\>Set (AsnIntType i) \{ value = i; \}\\
+  void				\>\>ReSet (AsnIntType i) \{ value = i; \}\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen			\>\>BEncContent (BUF\_TYPE b);\\
+  void				\>\>BDecContent (BUF\_TYPE b, AsnTag tagId, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void				\>\>Print (ostream \&os) const \{ os <\/< value; \}\\
+\\
+\<\#if META\\
+  static const AsnIntTypeDesc	\>\>\_desc;\\
+\\
+  const AsnTypeDesc		\>\>*\_getdesc() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetVal (Tcl\_Interp *) const;\\
+  int				\>\>TclSetVal (Tcl\_Interp *, const char *val);\-\\
+\#endif /* TCL */\\
+\#endif /* META */\\
+\};
+\end{Ccode}
+
+The internal representation of an ASN.1 INTEGER value is a {\C AsnIntType}.
+This is a {\C typedef}, the real type may be {\C int}, {\C long} or {\C short}, whatever is found to be 32 bits in size.
+The types' sizes depend on the machine and compiler and are determined at configuration time.
+The {\C BDecContent} routine will signal an error if the integer
+value being decoded will not fit into the {\C AsnIntType}
+representation.
+
+Unlike the C ASN.1 library, the non-negative
+%{\C unsigned long int}
+version of
+INTEGER is not provided.  If you need it, it should be relatively
+trivial to combine the C unsigned version with the existing C++ class.
+The unsigned version of an integer is useful if your ASN.1 source uses
+subtyping similar to:
+\begin{ASNcode}
+Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..4294967295)
+\end{ASNcode}
+
+\section{\label{enum-C++-section}ENUMERATED}
+
+The ENUMERATED type is represented by the {\C AsnEnum} class. The
+following is the class definition of {\C AsnEnum} from the
+{\ufn \dots/c++-lib/inc/asn-enum.h} file.
+\begin{Ccode}
+class AsnEnum: public AsnInt\\
+\{\\
+public:\+\\
+\<\#if !TCL\\
+				\>\>AsnEnum(): AsnInt() \{\}\\
+\<\#endif\\
+				\>\>AsnEnum (int i): AsnInt (i) \{\}\\
+\\
+  AsnType			\>\>*Clone() const;\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen			\>\>BEncContent (BUF\_TYPE b);\\
+  void				\>\>BDecContent (BUF\_TYPE b, AsnTag tagId, AsnLen elmtLen,\\
+           		                \`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+\<\#if META\\
+  static const AsnEnumTypeDesc	\>\>\_desc;\\
+\\
+  const AsnTypeDesc		\>\>*\_getdesc() const;\-\\
+\#endif /* META */\\
+\};
+\end{Ccode}
+
+Note that it is not derived from {\C class AsnType} directly but from {\C class AsnInt} instead.
+
+\section{\label{null-C++-section}NULL}
+
+The NULL type is provided by the {\C AsnNull} class.  This class has
+no data members and includes only the standard methods.
+\begin{Ccode}
+class AsnNull: public AsnType\\
+\{\\
+public:\+\\
+				\>\>AsnNull() \{\}\\
+  AsnType			\>\>*Clone() const;\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen			\>\>BEncContent (BUF\_TYPE b);\\
+  void				\>\>BDecContent (BUF\_TYPE b, AsnTag tagId, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void				\>\>Print (ostream \&os) const \{ os <\/< "NULL"; \}\\
+\\
+\<\#if META\\
+  static const AsnNullTypeDesc	\>\>\_desc;\\
+\\
+  const AsnTypeDesc		\>\>*\_getdesc() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetVal (Tcl\_Interp *) const;\\
+  int				\>\>TclSetVal (Tcl\_Interp *, const char *val);\-\\
+\#endif /* TCL */\\
+\#endif /* META */\\
+\};
+\end{Ccode}
+
+\section{\label{real-C++-section}REAL}
+
+REAL types are represented by the {\C AsnReal} class.  Internally, a
+{\C double} is used to hold the real value.  The following is from
+{\ufn \dots/c++-lib/inc/asn-real.h}:
+\begin{Ccode}
+class AsnReal: public AsnType\\
+\{\\
+protected:\\
+  \>double			\>\>value;\\
+\\
+public:\+\\
+				\>\>AsnReal(): value (0.0) \{\}\\
+				\>\>AsnReal (double val): value (val) \{\}\\
+  AsnType			\>\>*Clone() const;\\
+				\>\>operator double() const  \{ return value; \}\\
+  AsnReal			\>\>\&operator = (double newvalue) \{ value = newvalue; return *this; \}\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen			\>\>BEncContent (BUF\_TYPE b);\\
+  void				\>\>BDecContent (BUF\_TYPE b, AsnTag tagId, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void				\>\>Print (ostream \&os) const \{ os <\/< value; \}\\
+\\
+\<\#if META\\
+  static const AsnRealTypeDesc	\>\>\_desc;\\
+\\
+  const AsnTypeDesc		\>\>*\_getdesc() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetVal (Tcl\_Interp *) const;\\
+  int				\>\>TclSetVal (Tcl\_Interp *, const char *val);\-\\
+\#endif /* TCL */\\
+\#endif /* META */\\
+\};\\
+\\
+extern const AsnReal		\>\>\>PLUS\_INFINITY;\\
+extern const AsnReal		\>\>\>MINUS\_INFINITY;
+\end{Ccode}
+
+The {\C double} representation and support routines can depend on
+the compiler or system you are using so several different encoding
+routines are provided.  Even so, you may need to modify the code.
+
+There are three content encoding routines included and they can be selected by defining one of {\C IEEE\_REAL\_FMT}, {\C IEEE\_REAL\_LIB} or nothing.
+Defining {\C IEEE\_REAL\_FMT} uses the encode routine that assumes the double representation is the standard IEEE double \cite{68881}.
+Defining {\C IEEE\_REAL\_LIB} uses the encode routine that assumes the IEEE functions library (isinf, scalbn, signbit etc.) is available.
+If neither are defined, the default encode routine uses {\C frexp}.
+%The {\ufn \dots/configure} script tries to find the {\C isinf} and {\C finite} functions 
+%Look at the related comments in {\ufn \dots/c++-lib/inc/asn-config.h}.
+Currently, the {\ufn \dots/configure} script has not got any checks for the IEEE format or library and therefore does not define any of the symbols. (This should be fixed.)
+
+{\C AsnReal} constants are used to hold {\C PLUS\_INFINITY} and
+{\C MINUS\_INFINITY} values.  These values are initialized using the
+{\C AsnReal} constructor mechanism with the {\C AsnPlusInfinity}
+and {\C AsnMinusInfinity} routines.  If you do not define
+{\C IEEE\_REAL\_FMT} or {\C IEEE\_REAL\_LIB}, you should rewrite the
+{\C AsnPlusInfinity} routine such that it is correct for your system.
+
+There is only one content decoding routine and it builds the value
+through multiplication and the {\C pow} routine (requires the math
+library). The content decoding routine only supports the binary
+encoding of a REAL, not the decimal encoding.
+
+\section{\label{bits-C++-section}BIT STRING}
+
+The BIT STRING type is represented by the {\C AsnBits} class.  From\linebreak
+{\ufn \dots/c++-lib/inc/asn-bits.h}:
+\begin{Ccode}
+class AsnBits: public AsnType\\
+\{\\
+private:\+\\
+  int				\>\>BitsEquiv (AsnBits \&ab);\\
+  void				\>\>BDecConsBits (BUF\_TYPE b, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+  void				\>\>FillBitStringStk (BUF\_TYPE b, AsnLen elmtLen0,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\<protected:\\
+  size\_t			\>\>bitLen;\\
+  char				\>\>*bits;\\
+\\
+\<public:\\
+				\>\>AsnBits() \{ bits = NULL; bitLen = 0; \}\\
+				\>\>AsnBits (const size\_t numBits) \{ Set (numBits); \}\\
+				\>\>AsnBits (const char *bitOcts, const size\_t numBits) \\
+					\`\{ Set (bitOcts, numBits); \}\\
+				\>\>AsnBits (const AsnBits \&b) \{ Set (b); \}\\
+				\>\>\~{}AsnBits() \{ delete bits; \}\\
+\\
+  AsnType			\>\>*Clone() const;\\
+\\
+  AsnBits			\>\>\&operator = (const AsnBits \&b) \{ ReSet (b); return *this; \}\\
+\\
+  size\_t			\>\>BitLen() \{ return bitLen; \}\\
+\\
+  bool				\>\>operator == (AsnBits \&ab) const \{ return BitsEquiv (ab); \}\\
+  bool				\>\>operator != (AsnBits \&ab) const \{ return !BitsEquiv (ab); \}\\
+\\
+  // overwrite existing bits and bitLen values\\
+  void				\>\>Set (size\_t numBits);\\
+  void				\>\>Set (const char *bitOcts, size\_t numBits);\\
+  void				\>\>Set (const AsnBits \&b);\\
+\\
+  // free old bits value, the reset bits and bitLen values\\
+  void				\>\>ReSet (const size\_t numBits);\\
+  void				\>\>ReSet (const char *bitOcts, size\_t numBits);\\
+  void				\>\>ReSet (const AsnBits \&b);\\
+\\
+  void				\>\>SetBit (size\_t);\\
+  void				\>\>ClrBit (size\_t);\\
+  int				\>\>GetBit (size\_t) const;\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen			\>\>BEncContent (BUF\_TYPE b);\\
+  void				\>\>BDecContent (BUF\_TYPE b, AsnTag tagId, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void				\>\>Print (ostream \&os) const;\\
+\\
+\<\#if META\\
+  static const AsnBitsTypeDesc	\>\>\_desc;\\
+\\
+  const AsnTypeDesc		\>\>*\_getdesc() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetVal (Tcl\_Interp *) const;\\
+  int				\>\>TclSetVal (Tcl\_Interp *, const char *val);\-\\
+\#endif /* TCL */\\
+\#endif /* META */\\
+\};
+\end{Ccode}
+
+The {\C AsnBits} class contains a pointer to the bits and an
+integer that holds the length in bits of the BIT STRING\@.
+
+In addition to the standard methods, the {\C AsnBits} class has
+methods for initializing and comparing bit string values and methods
+for setting and getting individual bits in a value.
+
+An {\C AsnBits} value can be created three ways: from the number of
+bits, from a {\C char~*} and its bit length or from another
+{\C AsnBits} value.  Look at the constructors and the {\C Set} and
+{\C ReSet} methods.
+
+{\C SetBit} and {\C ClrBit} can be used for setting the values of
+individual bits in the BIT STRING value.  Given the bit's index,
+{\C SetBits} sets that bit to one.  {\C ClrBit} sets the bit
+of the given index to zero.  The bit indexes start at zero, with zero
+being the first (most signficant) bit in the BIT STRING\@. {\C GetBit}
+will return {\C true} if the specified bit is one and {\C false} if the bit is
+zero.  If the given bit index is too large, {\C SetBit} and
+{\C ClrBit} do nothing and {\C GetBit} returns {\C false}\@.
+
+The {\C ==} and {\C !=} operators have been overloaded such that
+given two {\C AsnBits} values, they will behave as expected.
+
+Each {\C AsnBits} value stores its bit string in a single contiguous
+block of memory.  Received BIT STRING values that were encoded in the
+constructed form are converted to the simple, flat form (see Section
+\ref{bits-C-section}).  Snacc provides no facility for encoding or
+internally representing constructed BIT STRING values.
+
+\section{\label{octets-C++-section}OCTET STRING}
+OCTET STRING values are represented with the {\C AsnOcts} class.
+From\linebreak {\ufn \dots/c++-lib/inc/asn-octs.h}:
+\begin{Ccode}
+class AsnOcts: public AsnType\\
+\{\\
+private:\+\\
+  int				\>\>OctsEquiv (const AsnOcts \&o);\\
+  void				\>\>FillBitStringStk (BUF\_TYPE b, AsnLen elmtLen0,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+  void				\>\>BDecConsOcts (BUF\_TYPE b, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+\<protected:\\
+  size\_t			\>\>octetLen;\\
+  char				\>\>*octs;\\
+\\
+\<public:\\
+  // constructor and Set alway copy strings so destructor can always delete\\
+				\>\>AsnOcts(): octs (NULL), octetLen (0) \{\}\\
+				\>\>AsnOcts (const char *str)  \{ Set (str); \}\\
+				\>\>AsnOcts (const char *str, const size\_t len) \{ Set (str, len); \}\\
+				\>\>AsnOcts (const AsnOcts \&o) \{ Set (o); \}\\
+				\>\>\~{}AsnOcts() \{ delete octs; \}\\
+  AsnType			\>\>*Clone() const;\\
+\\
+  AsnOcts			\>\>\&operator = (const AsnOcts \&o) \{ ReSet (o); return *this; \}\\
+  AsnOcts			\>\>\&operator = (const char *str) \{ ReSet (str); return *this; \}\\
+\\
+  size\_t			\>\>Len() const \{ return octetLen; \}\\
+				\>\>operator const char *() const \{ return octs; \}\\
+				\>\>operator char *() \{ return octs; \}\\
+\\
+  bool				\>\>operator == (const AsnOcts \&o) const \{ return OctsEquiv (o); \}\\
+  bool				\>\>operator != (const AsnOcts \&o) const \{ return !OctsEquiv (o); \}\\
+\\
+  // these set the octs and octetLen values\\
+  void				\>\>Set (const char *str, size\_t len);\\
+  void				\>\>Set (const AsnOcts \&o);\\
+  void				\>\>Set (const char *str);\\
+\\
+  // these free the old octs value and then reset the octs and octetLen values\\
+  void				\>\>ReSet (const char *str, size\_t len);\\
+  void				\>\>ReSet (const AsnOcts \&o);\\
+  void				\>\>ReSet (const char *str);\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen			\>\>BEncContent (BUF\_TYPE b);\\
+  void				\>\>BDecContent (BUF\_TYPE b, AsnTag tagId, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void				\>\>Print (ostream \&os) const;\\
+\\
+\<\#if META\\
+  static const AsnOctsTypeDesc	\>\>\_desc;\\
+\\
+  const AsnTypeDesc		\>\>*\_getdesc() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetVal (Tcl\_Interp *) const;\\
+  int				\>\>TclSetVal (Tcl\_Interp *, const char *val);\-\\
+\#endif /* TCL */\\
+\#endif /* META */\\
+\};
+\end{Ccode}
+
+The {\C AsnOcts} class contains a pointer to the octets and an
+integer that holds the length in octets of the OCTET STRING\@.
+
+There are four constructors for {\C AsnOcts}.  The parameterless
+constructor will initialize the octet string to zero length with a
+{\C NULL} octets pointer.  The constructor that takes a single {\C char~*}
+assumes that the given string is NUL terminated and initializes the octet
+pointer with a pointer to a copy of the given string and sets the
+{\C octetLen} to the {\C strlen} of the string (this does not usually
+include the NUL terminator).  The constructor that takes
+{\C char~*} and a length, {\C len}, initializes the octets pointer
+to point to a copy of {\C len} characters from the given string and
+sets the {\C octetLen} to {\C len}.  The last constructor will initialize
+an {\C AsnOcts} value by copying the given {\C AsnOcts} value.
+
+As with the BIT STRING content decoder, OCTET STRING content decoder
+can handle constructed values.  These are handled in the same way as
+the constructed BIT STRING values; they are converted to the simple
+contiguous representation.  Every OCTET STRING value will
+automatically have a NUL terminator appended to it; this extra
+character will not be included in the string's length and will make
+some strings easier to deal with for printing etc.
+
+The {\C operator char~*()} is defined for the {\C AsnOcts} class to
+return a pointer to the octets.  The {\C Len}
+method returns the length in bytes of the string value.
+These may be useful for passing the
+octets to other functions such as {\C memcpy} etc.  
+
+The {\C ==} and {\C !=} operators have been overloaded such that
+given two {\C AsnOcts} values, they will behave as expected.
+
+
+
+\section{\label{oid-C++-section}OBJECT IDENTIFIER}
+OBJECT IDENTIFIER values are represented with the {\C AsnOid} class.
+From\linebreak {\ufn \dots/c++-lib/inc/asn-oid.h}:
+\begin{Ccode}
+class AsnOid: public AsnType\\
+\{\\
+private:\\
+  \>int				\>\>OidEquiv (AsnOid o);\\
+\\
+protected:\+\\
+  size\_t			\>\>octetLen;\\
+  char				\>\>*oid;\\
+\\
+\<public:\\
+				\>\>AsnOid(): oid (NULL), octetLen (0) \{\}\\
+				\>\>AsnOid (const char *encOid, size\_t len) \{ Set (encOid, len); \}\\
+				\>\>AsnOid (const AsnOid \&o) \{ Set (o); \}\\
+				\>\>AsnOid (unsigned long int a1, unsigned long int a2, long int a3 = -1,\\
+					\`long int a4 = -1, long int a5 = -1, long int a6 = -1, long int a7 = -1,\\
+					\`long int a8 = -1, long int a9 = -1, long int a10 = -1, long int a11 = -1);\\
+				\>\>\~{}AsnOid() \{ delete oid; \}\\
+  AsnType			\>\>*Clone() const;\\
+\\
+  AsnOid			\>\>\&operator = (const AsnOid \&o) \{ ReSet (o); return *this; \}\\
+\\
+  size\_t			\>\>Len() \{ return octetLen; \}\\
+  const char			\>\>*Str() const \{ return oid; \}\\
+				\>\>operator const char * () const \{ return oid; \}\\
+				\>\>operator char * () \{ return oid; \}\\
+  unsigned long int		\>\>NumArcs() const;\\
+\\
+  bool				\>\>operator == (AsnOid \&o) const \{ return OidEquiv (o); \}\\
+  bool				\>\>operator != (AsnOid \&o) const \{ return !OidEquiv (o); \}\\
+\\
+  // Set methods overwrite oid and octetLen values\\
+  void				\>\>Set (const char *encOid, const size\_t len);\\
+  void				\>\>Set (const AsnOid \&o);\\
+\\
+  // first two arc numbers are mandatory.  rest are optional since negative arc nums are not allowed in the\\
+  // encodings, use them to indicate the 'end of arc numbers' in the optional parameters\\
+  void				\>\>Set (unsigned long int a1, unsigned long int a2, long int a3 = -1,\\
+					\`long int a4 = -1, long int a5 = -1, long int a6 = -1, long int a7 = -1,\\
+					\`long int a8 = -1, long int a9 = -1, long int a10 = -1, long int a11 = -1);\\
+\\
+  // ReSet routines are like Set except the old oid value is freed\\
+  void				\>\>ReSet (const char *encOid, const size\_t len);\\
+  void				\>\>ReSet (const AsnOid \&o);\\
+  void				\>\>ReSet (unsigned long int a1, unsigned long int a2, long int a3 = -1,\\
+					\`long int a4 = -1, long int a5 = -1, long int a6 = -1, long int a7 = -1,\\
+					\`long int a8 = -1, long int a9 = -1, long int a10 = -1, long int a11 = -1);\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  AsnLen			\>\>BEncContent (BUF\_TYPE b);\\
+  void				\>\>BDecContent (BUF\_TYPE b, AsnTag tagId, AsnLen elmtLen,\\
+					\`AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void				\>\>Print (ostream \&os) const;\\
+\\
+\<\#if META\\
+  static const AsnOidTypeDesc	\>\>\_desc;\\
+\\
+  const AsnTypeDesc		\>\>*\_getdesc() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetVal (Tcl\_Interp *) const;\\
+  int				\>\>TclSetVal (Tcl\_Interp *, const char *val);\-\\
+\#endif /* TCL */\\
+\#endif /* META */\\
+\};
+\end{Ccode}
+
+The {\C AsnOid} stores OBJECT IDENTIFIER values in their encoded form
+to improve performance.  It seems that the most common operation with
+OBJECT IDENTIFIERs is to compare for equality, for which the encoded
+representation (which is canonical) works well.
+
+The {\C AsnOid} is very similar to the {\C AsnOcts} class in all
+respects, except that its content decoding routine does not need to
+handle constructed encodings.
+
+The {\C AsnOid} class has four constructors which are similiar to
+those of the {\C AsnOcts} class.  A special constructor that takes
+arc numbers as parameters and uses default parameters is provided.  An
+OBJECT IDENTIFIER value must have at least two arc numbers so the
+first two parameters do not have default values.  All of the other
+parameters are optional; since their default value of {\C --1} is an
+invalid arc number (they must be positive) they will not be used in the
+value. For example to build the value {\C \{1 2 3\}} you simply use
+{\C AsnOid (1, 2, 3)}.  This constructor is convenient but is more
+expensive in terms of CPU time than the others.
+
+The {\C operator char~*()} is defined for the {\C AsnOid} class to
+return a pointer to the encoded OBJECT IDENTIFIER value.  The {\C Len}
+method returns the length in bytes of the encode OBJECT IDENTIFIER
+value (NOT the number arcs in the value).  These may be useful for
+passing the octets to other functions such as {\C memcpy} etc.
+{\C NumArcs} returns the number of arcs that the value is comprised of.
+
+The {\C ==} and {\C !=} operators have been overloaded such that
+given two {\C AsnOcts} values, they will behave as expected.
+
+
+
+\section{\label{list-C++-section}SET OF and SEQUENCE OF}
+
+In the C ASN.1 library, the list type was in the library because it
+was generic and every SET OF and SEQUENCE OF was defined as an
+{\C AsnList}.  In C++, a new class is defined every list, providing
+a type safe list mechanism.  This was described in the previous chapter.
+
+
+\section{\label{any-C++-section}ANY and ANY DEFINED BY}
+
+The ANY DEFINED BY type can be handled automatically by snacc
+provided you use the SNMP OBJECT-TYPE macro to specify the identifier
+to type mappings.  The identifier can be an INTEGER or OBJECT
+IDENTIFIER\@.  Handling ANY types properly will require modifications to
+the generated code since there is no identifier associated with the
+type.
+
+Look at the C and C++ ANY examples and the {\ufn any.asn1} file
+included with this release for information on using the OBJECT-TYPE
+macro.  Note that the OBJECT-TYPE macro has been modified slightly to
+allow INTEGER values (identifiers).
+
+An ANY DEFINED BY type is represented by the {\C AsnAny} class.
+The following is from {\ufn \dots/c++-lib/inc/asn-any.h}.
+\begin{Ccode}
+/* AnyInfo is a hash table entry */\\
+class AnyInfo\\
+\{\\
+public:\+\\
+  int				\>\>anyId;  // will be a value from the AnyId enum\\
+  AsnOid			\>\>oid;    // will be zero len/null if intId is valid\\
+  AsnInt			\>\>intId;\\
+  AsnType			\>\>*typeToClone;\-\\
+\};\\
+\\
+class AsnAny: public AsnType\\
+\{\\
+public:\+\\
+  static Table			\>\>*oidHashTbl;  // all AsnAny class instances\\
+  static Table			\>\>*intHashTbl;  // share these tables\\
+  AnyInfo			\>\>*ai; // points to entry in hash tbl for this type\\
+  AsnType			\>\>*value;\\
+\\
+				\>\>AsnAny() \{ ai = NULL; value = NULL; \}\\
+\\
+  // class level methods\\
+  static void			\>\>InstallAnyByInt (AsnInt intId, int anyId, AsnType *type);\\
+  static void			\>\>InstallAnyByOid (AsnOid \&oid, int anyId, AsnType *type);\\
+\\
+  int				\>\>GetId() \{ return ai ? ai-->anyId : -1; \}\\
+  void				\>\>SetTypeByInt (AsnInt id);\\
+  void				\>\>SetTypeByOid (AsnOid \&id);\\
+\\
+  AsnLen			\>\>BEnc (BUF\_TYPE b);\\
+  void				\>\>BDec (BUF\_TYPE b, AsnLen \&bytesDecoded, ENV\_TYPE env);\\
+\\
+  int				\>\>BEncPdu (BUF\_TYPE b, AsnLen \&bytesEncoded);\\
+  int				\>\>BDecPdu (BUF\_TYPE b, AsnLen \&bytesDecoded);\\
+\\
+  void				\>\>Print (ostream \&os) const \{ value-->Print (os); \}\\
+\<\};
+\end{Ccode}
+
+The C++ mechanism is similar to the C mechanism which uses hash tables
+to hold the identifier to type mappings.  In this section we will
+discuss the main differences of the C++ ANY DEFINED BY handling
+mechanism.  You should read Section~\ref{any-C-section} for caveats and
+other important information.
+
+In C, the hash table entry held the size of the type and pointers to
+its encode, decode, free etc. routines to describe the type.  In C++
+these have been replaced with a pointer to an instance of the type. A
+hash table entry contains:
+\begin{itemize}
+\item {the {\C anyId}}
+\item {the INTEGER or OBJECT IDENTIFIER that maps to it}
+\item {a pointer to an instance of the identified type}
+\end{itemize}
+
+All C++ ASN.1 types use the {\C AsnType} base class which designates the following functions as virtual:
+\begin{itemize}
+  \item the destructor
+  \item {\C Clone()}
+  \item {\C BDec()}
+  \item {\C BEnc()}
+  \item {\C Print()}
+  \item {\C \_getdesc()} (metacode)
+  \item {\C \_getref()} (metacode)
+  \item {\C TclGetDesc()} (Tcl interface)
+  \item {\C TclGetVal()} (Tcl interface)
+  \item {\C TclSetVal()} (Tcl interface)
+  \item {\C TclUnsetVal()} (Tcl interface)
+\end{itemize}
+
+This allows the ANY DEFINED BY handling routines to treat a value of
+any ASN.1 type as an {\C AsnType}.  So, for each type the ANY
+DEFINED BY handling code has access to the virtual methods.  Note
+that the {\C value} field in the {\C AsnAny} class and the
+{\C typeToClone} field in the {\C AnyInfo} class are both
+{\C AsnType~*}.
+
+To build an ANY DEFINED BY value, simply set the value field in the
+{\C AsnAny} object to point to the object you want to encode.  Then
+set the identifier field for that ANY DEFINED BY value to the correct
+identifier (as generated for its OBJECT-TYPE macro value).  It is very
+important to do this correctly because the encoder will simply call
+the virtual {\C BEnc} routine for the object pointed to by the
+{\C AsnAny}'s value field.  There is no attempt to make sure that
+the identifier field's value matches the object that was encoded.
+
+A potential solution to the last identifier problem is to add a type
+id field to the {\C AsnType} base class.  Snacc could generate a
+unique identifier (that would be stored in the base class) for each
+type.  The encoder could then check identifiers between the value
+being encoded and the value stored in the hash table.  The identifier
+in the base class could easily be automatically set (correctly) from
+the constructors for each type (constructors are snacc generated).  It
+would be difficult to ensure unique identifiers for each type between
+modules if the ASN.1 modules were compiled separately.
+
+Before an ANY DEFINED BY value can be decoded, the field that contains
+its identifier must have been decoded and used with the {\C AsnAny}
+value's {\C SetTypeByInt} or {\C SetTypeByOid} methods.  Then the
+ANY DEFINED BY value can be decoded by calling its ({\C AsnAny})
+{\C BDec} routine.  This in turn calls the {\C Clone} routine on
+the type in the hash table entry to generate the correct object.  Then
+the {\C BDec} method of the newly created object is called.
+
+When the C ANY DEFINED BY decoder allocates a value, it uses the size
+information for the identified type.  This is not safe for C++ so the
+virtual {\C Clone} routine was added to the {\C AsnType} base
+class.  This allows the proper constructor mechanism to be used when
+allocating the value.
+
+The virtual {\C Clone} routine simply calls its type's parameterless
+constructor via {\C new} (hence every ASN.1 type's class must have a
+parameterless constructor).  {\C Clone} is a poor name since
+the routine only produces a new instance of the given type without
+copying the original's data.
+
+The hash tables are automatically initialized using the C++ constructor
+mechanism.  You do not need to call any initialization routines as
+described in the C chapter.
+
+
+\section{\label{buffer-C++-section}Buffer Management}
+
+The C++ buffer management provided with snacc is similar to that of
+the C {\C SBuf}s.  The following is from
+{\ufn \dots/c++-lib/inc/asn-buf.h}:
+\begin{Ccode}
+class AsnBuf\\
+\{\\
+protected:\+\\
+  char			\>\>*dataStart;\\
+  char			\>\>*dataEnd;\\
+  char			\>\>*blkStart;\\
+  char			\>\>*blkEnd;\\
+  char			\>\>*readLoc;\\
+  bool			\>\>writeError;\\
+  bool			\>\>readError;\\
+\\
+\<public:\\
+  void			\>\>Init (char *data, size\_t dataLen);\\
+  void			\>\>ResetInReadMode();\\
+  void			\>\>ResetInWriteRvsMode();\\
+  void			\>\>InstallData (char *data, size\_t dataLen);\\
+  size\_t		\>\>DataLen();\\
+  char			\>\>*DataPtr();\\
+  size\_t		\>\>BlkLen();\\
+  char			\>\>*BlkPtr();\\
+  bool			\>\>Eod();\\
+\\
+  /* the following 9 methods are required */\\
+  bool			\>\>ReadError();\\
+  bool			\>\>WriteError();\\
+  void			\>\>Skip (size\_t skipLen);\\
+  size\_t		\>\>CopyOut (char *dst, size\_t copyLen);\\
+  unsigned char		\>\>PeekByte();\\
+  char			\>\>*GetSeg (size\_t *lenPtr);\\
+  void			\>\>PutSegRvs (char *seg, size\_t segLen);\\
+  unsigned char		\>\>GetByte();\\
+  void			\>\>PutByteRvs (unsigned char byte);\\
+\<\};
+\end{Ccode}
+
+This is the only buffer type provided with the C++ library.
+
+\section{\label{mem-C++-section}Dynamic Memory Management}
+
+The built-in C++ memory management system is used by snacc ({\C new}
+and {\C delete}).  Better performance might be gained by using a
+different management scheme.
+
+To change {\C new} and {\C delete} to use your own memory
+management scheme the best way to start is by defining them as virtual
+in the {\C AsnType} base class.  More information on providing your
+own memory management can be found in Stroustrup \cite{stroustrup}.
+
+\section{\label{error-C++-section}Error Management}
+
+The C++ ASN.1 error management is identical to that of the C ASN.1
+model.  C++ exception handling ({\C try} and {\C throw}) were not
+used to replace {\C setjmp()} and {\C longjmp()} because they were not
+implemented by the C++ compiler we used.
diff --git a/SecuritySNACCRuntime/doc/c-gen.tex b/SecuritySNACCRuntime/doc/c-gen.tex
new file mode 100644
index 00000000..f77a9a0b
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/c-gen.tex
@@ -0,0 +1,772 @@
+% file: .../doc/c-gen.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: c-gen.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:51  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:33  rj
+% first check-in
+%
+
+\chapter{\label{c-code-gen-chapter}C Code Generation}
+\section{\label{intro-C-section}Introduction}
+Snacc was designed primarily to provide high-performance encoders and
+decoders.  Key areas to optimize are buffer and memory management.
+Buffers are used to hold encoded values and the memory management is
+used when building the internal representation of a value when decoding.
+
+C macros are used where possible to eliminate function call overhead
+for small, commonly used routines.  Using macros with constant
+expressions as parameters allows smarter C compilers to do some of the
+calculations at compile time.  In general, short-cuts that can be taken
+without sacrificing the robustness of code are used.
+
+The generated code can be quite large; large reductions of the size of
+the binaries can be achieved by using the optimizing options of your C
+compiler.
+
+We will use an example ASN.1 module, EX1, to help explain snacc's code
+generation.  The EX1 module uses some of the common built-in types and
+contains some simple values.  The field names have been left out
+to show snacc naming conventions.  The C generation code is in
+{\ufn \dots/compiler/back-ends/c-gen/} if you want to alter it.
+
+\begin{small}
+\begin{verbatim}
+EX1 DEFINITIONS ::=
+BEGIN
+
+anOidVal      OBJECT IDENTIFIER ::= { joint-iso-ccitt 40 foobar(29) }
+theSameOidVal OBJECT IDENTIFIER ::= { 2 40 29 }
+anIntVal      INTEGER ::= 1
+aBoolVal      BOOLEAN ::= TRUE
+
+T1 ::= SEQUENCE
+{
+   INTEGER OPTIONAL,
+   OCTET STRING OPTIONAL,
+   ENUMERATED { a(0), b(1), c(2) },
+   SEQUENCE OF INTEGER,
+   SEQUENCE { id OBJECT IDENTIFIER, value OCTET STRING },
+   CHOICE { INTEGER, OBJECT IDENTIFIER }
+}
+
+END
+\end{verbatim}
+\end{small}
+
+\noindent
+Use the following command to compile the EX1 ASN.1 module:
+
+\noindent
+{\ufn \%1 snacc -u \dots/asn1specs/asn-useful.asn1 \dots/asn1specs/ex1.asn1}
+\noindent
+
+This produces the files {\ufn ex1.h} and {\ufn ex1.c}.
+
+For each ASN.1 type an equivalent C data type, a BER encoding routine,
+a BER decoding routine, a printing routine and a freeing routine will
+be generated.  C values will also be generated from simple ASN.1
+values.  Each aspect of the C code generation will be discussed in the
+next sections.
+
+\section{\label{naming-C-section}ASN.1 to C Naming Conventions}
+
+For any given module, snacc may produce C type definitions, functions
+and {\C \#define}s.  We assume that all C {\C typedef},
+{\C struct}, {\C enum} and {\C union} tag, {\C enum} value,
+variable, {\C \#define} and function names share a single name space.
+
+The C type name for a type is the same as its ASN.1 type name (with
+any hyphens converted to underscores) unless there is a conflict.
+Since, unlike ASN.1, the C types for each ASN.1 module share the same
+name space, snacc makes sure the C typenames are unique amoung all the
+modules and that they do not conflict with C keywords.  The conflicts
+are resolved by appending digits to the conflicting name.  To avoid
+confusing numbered type names etc., you should edit the ASN.1 source
+and name them properly.
+
+Named numbers, ENUMERATED values and named bits are put in entirely in
+upper case to match the common C convention for {\C \#define} and
+{\C enum} values.
+
+Empty field names in SETs, SEQUENCEs, and CHOICEs will be filled.  The
+field name is derived from the type name for that field. The library
+types such as INTEGER have default field names defined by the compiler
+(see {\ufn \dots/compiler/back-ends/c-gen/rules.c} and
+{\ufn \dots/compiler/back-ends/c++-gen/rules.c}).  The first letter of the field
+name is in lower case.  Again, empty field names should be fixed
+properly by adding them to the ASN.1 source.
+
+New type definitions will be generated for SETs, SEQUENCEs, CHOICEs,
+ENUMERATED, INTEGERs with named numbers and BIT STRING with named bits
+whose definitions are embedded in other SET, SEQUENCE, SET OF,
+SEQUENCE OF, or CHOICE definitions.  The name of the new type is
+derived from the name of the type in which it was embedded.  Perhaps a
+better way would use the field name as well, if present.
+
+\section{\label{type-gen-C-section}ASN.1 to C Data Structure Translation}
+
+To handle the different scoping rules between ASN.1 and C, the names
+of some ASN.1 data structure elements such as ENUMERATED type symbols
+may be altered to avoid conflicts.  The T1 type in example ASN.1
+module EX1 has no field names so snacc will generate them.  It is
+recommended to provide field names in the ASN.1 source instead of
+relying on compiler generated names.  The following is the generated C
+data structure for the EX1 module from the {\ufn ex1.h} file (function
+prototypes have been removed):
+
+\begin{small}
+\begin{verbatim}
+
+typedef enum
+{
+    A = 0,
+    B = 1,
+    C = 2
+} T1Enum; /* ENUMERATED { A(0), B(1), C(2) }  */
+
+typedef struct T1Choice /* CHOICE */
+{
+    enum T1ChoiceChoiceId
+    {
+        T1CHOICE_INT1,
+        T1CHOICE_OID
+    } choiceId;
+    union T1ChoiceChoiceUnion
+    {
+        AsnInt int1; /* INTEGER */
+        AsnOid *oid; /* OBJECT IDENTIFIER */
+    } a;
+} T1Choice;
+
+typedef struct T1Seq /* SEQUENCE */
+{
+    AsnOid id; /* OBJECT IDENTIFIER */
+    AsnOcts value; /* OCTET STRING */
+} T1Seq;
+
+typedef AsnList T1SeqOf; /* SEQUENCE OF INTEGER */
+
+typedef struct T1 /* SEQUENCE */
+{
+    AsnInt *int1; /* INTEGER OPTIONAL */
+    AsnOcts octs; /* OCTET STRING OPTIONAL */
+    T1Enum t1Enum; /* T1Enum */
+    T1SeqOf *t1SeqOf; /* T1SeqOf */
+    struct T1Seq *t1Seq; /* T1Seq */
+    struct T1Choice *t1Choice; /* T1Choice */
+} T1;
+\end{verbatim}
+\end{small}
+
+Every ASN.1 type definition maps into a C {\C typedef}.  SETs and
+SEQUENCEs map into C structures and other simple types map into their
+obvious C counterpart.  SET OF and SEQUENCE OF types map into a
+generic list type which is doubly linked and NULL terminated.  The
+reverse link on the lists allows for simpler backwards encoding.  More
+information on the library types can be found in Chapter~\ref{lib-C-chapter}.
+
+Comments that contain a fragment of each type's ASN.1 definition are
+inserted in the header file to clarify cases where elements have been
+re-named.
+
+Aggregate types that are defined in other type definitions are moved
+to their own type definitions.  For example, notice how the SEQUENCE
+and CHOICE that are in type {\C T1} have been moved to the types
+{\C T1Seq} and {\C T1Choice} in the C code.  This simplifies code
+generation at the cost of introducing new types.
+
+Identifiers for named numbers from INTEGER and ENUMERATED types and
+named bits from the BIT STRING type are capitalized in the C
+representation.  The ENUMERATED type maps to a C {\C enum} and the INTEGER
+and BIT STRING named numbers/bits are handled with {\C \#define}
+statements.
+
+Most OPTIONAL elements of SEQUENCEs and SETs are referenced by
+pointer.  An element is considered present if its pointer is non-NULL\@.
+OCTET STRINGs, BIT STRINGs and OBJECT IDENTIFIERs are the exceptions,
+and are included by value even when they are OPTIONAL because they are
+small and contain an internal pointer that can be used to determine
+their presence.  For an example of this, look at the first two
+elements of type {\C T1}.  The INTEGER type is referenced by pointer
+because it is OPTIONAL, but the OCTET STRING type is included
+(non-pointer) in the {\C T1} type even though it is OPTIONAL\@.
+
+
+\section{\label{encode-gen-C-section}Encode Routines}
+
+Snacc generates two kinds of encoding routines. One is PDU oriented
+and encodes the type's tag, length and content and the other
+only encodes the type's content.  The generated encoders only call the
+content encoders, except in the case of ANY and ANY DEFINED BY types.
+Typically, you will only call the PDU oriented routines from your
+code.
+
+The content and PDU encoding routine interfaces are similar for all
+ASN.1 types.  They both take two parameters, one is a buffer pointer
+and the other is a pointer to the value to be encoded.  For example
+the {\C T1} type from module EX1 has the following prototypes for
+its encoding routines.
+
+\begin{verbatim}
+AsnLen BEncT1Content (BUF_TYPE b, T1 *v);
+AsnLen BEncT1 (BUF_TYPE b, T1 *v);
+\end{verbatim}
+
+{\C BEnc} is short for ``BER Encode''. The {\C BUF\_TYPE}
+parameter is the buffer to encode the value into and the {\C T1~*}
+parameter is a pointer to the instance of the {\C T1} type that is to be
+encoded.
+
+The {\C BEncT1Content} routine only encodes the content of a {\C T1}
+type and returns its encoded length; it does not encode its tag
+(UNIVERSAL (CONSTRUCTED) 16 for SEQUENCE) or length.  The job of
+encoding the tag and length is up to any type that encapsulates {\C T1}.
+This design allows decisions about implicit tagging to be made at code
+generation time instead of runtime, improving performance.  Also,
+different encoding rules may fit into this model more easily.
+
+The {\C BEncT1} routine encodes the tag (UNIVERSAL (CONSTRUCTED) 16
+for SEQUENCE), length and content of a {\C T1} type and returns its encoded
+length.  This is the PDU oriented routine and will only be generated
+if the user designates the type as a PDU type via a compiler directive
+or the type is used as
+the content of an ANY or ANY DEFINED BY type (as indicated by an
+OBJECT-TYPE macro).  A PDU type is a type that defines an entire PDU;
+the user will typically be calling the encode and decode routine for
+PDU types directly.  See Section~\ref{compiler-dir-C-section} for how to
+designate PDU types with compiler directives.
+
+The snacc encoders are somewhat strange; they encode a value starting
+from the end of its BER representation and work back to its beginning.
+This ``backwards'' encoding technique simplifies the use of definite
+lengths on constructed values.  Other encoders that encode forwards,
+such as those of CASN1, use an intermediate buffer format so that a
+buffer containing the encoded length of a constructed value can be
+inserted before its encoded content, after the content has been
+encoded.  Use of intermediate buffers hurts performance.  Other
+compilers' approaches have been to only encode indefinite lengths for
+constructed values, however, this will not support some encoding rules
+such as DER\@.  The drawback of encoding backwards is that BER values
+cannot be written to stream-oriented connections as they are encoded.
+
+Both definite and indefinite length encodings for constructed values'
+lengths are supported.  Currently the choice is made when compiling
+the generated code, via the {\C USE\_INDEF\_LEN} flag.  If both length
+forms, definite and indefinite, are required, it easy to modify the
+length encoding macros to check a global variable for the length
+form to use.  For most types, using definite lengths produces smaller
+encodings with little performance difference.
+
+After calling an encode routine you should always check the buffer
+you encoded into for a write error.  This is the only error reporting
+mechanism used for the encoders.  See the C buffer section (Section
+\ref{lib-buf-section}) for how to check a buffer for a write error.
+
+
+\section{\label{decode-gen-C-section}Decode Routines}
+
+Decoding routines are like the encoding routines in that there are two
+kinds, one that decodes the type's tag, length and content and one
+that only decodes the type's content.  As mentioned in the encoder
+section, the content style interface allows implicit tagging decisions
+to be made at compile time.
+
+Unlike the encoding routines, the PDU and content decoding routines
+take different arguments.  For the {\C T1} type the following would be
+produced:
+\begin{verbatim}
+void BDecT1Content (BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, T1 *v, AsnLen *bytesDecoded, ENV_TYPE env);
+void BDecT1 (BUF_TYPE b, T1 *v, AsnLen *bytesDecoded, ENV_TYPE env);
+\end{verbatim}
+
+Notice that the content decoder, {\C BDecT1Content}, has tag and
+length parameters that the PDU decoder, {\C BDecT1}, does not have.
+Since the content decoder does not decode the tag and length on the
+value, it is necessary to pass them in as parameters. Only OCTET
+STRING and BIT STRING decoders will actually use the information
+in the tag parameter.
+
+The {\C BUF\_TYPE} parameter is the buffer that holds the BER value
+being decoded.
+
+The {\C tagId0} parameter is the last tag that was decoded on the
+content of the type that is about to be decoded.  In the case of type
+{\C T1}, {\C BDecT1Content} gets a tagId0 of UNIVERSAL (CONSTRUCTED) 16,
+unless it is implicitly tagged by another type.  Most content decoding
+routines ignore the tag information. OCTET STRING and BIT STRING
+decoders use the tag information to determine whether the contents are
+constructed or primitive.  CHOICE decoders use the tag information to
+determine which CHOICE element is present.  CHOICE values are treated
+differently, as will be explained shortly.
+
+The {\C elmtLen0} parameter is the length of the content of the type
+being decoded.  This is simply the length decoded from the buffer by
+the containing type's decoder just before calling this decode routine.
+
+The {\C v} parameter is a pointer to space allocated for the type
+being decoded.  This memory is not allocated by the decoding routine
+itself; this supports the cases where the type is enclosed in the
+struct of the parent (i.\,e.\  no extra allocation is necessary).  If
+the type to be decoded is referenced by pointer from its parent type,
+the parent type's decoding routine must allocate the type.
+
+The {\C bytesDecoded} parameter maintains the running total of the
+number of octets that have been decoded.  For example, if I call
+{\C BDecT1Content} with a {\C bytesDecoded} parameter that points
+to 20 and the encoded length of the {\C T1} value is 30 octets,
+{\C bytesDecoded} will point to 50 when {\C BDecT1Content}
+returns.  Maintaining the length is vital to determining the presence
+or absence of OPTIONAL elements in a SET or at the end of SEQUENCE\@.
+Local variables are used to hold the lengths; there is no global stack
+of lengths as with CASN1.
+
+The {\C env} parameter is used in conjunction with {\C longjmp}
+calls.  When an decoder encounters a fatal error such as a missing
+tag, it uses the {\C env} with a {\C longjmp} call to pop back to the
+initial decode call. Section~\ref{lib-err-C-section} has more error
+management details.
+
+CHOICEs are decoded a little differently from other types.  For all
+types except CHOICEs, all of the tag and length pairs on the content
+are decoded by the parent type, and the last pair a passed into to
+content decoding routine via the {\C tagId0} and {\C elmtLen0}
+parameters.  For CHOICEs, all of the tag and length pairs on the
+content are decoded and then the first tag and length pair in the
+CHOICE content is decoded by the parent and passed into the CHOICE
+content decoding routine.  The first tag in a CHOICE's content is the
+important tag by which the CHOICE determines which element is present.
+This technique simplifies the code for dealing with untagged CHOICEs
+embedded in other CHOICEs.  CHOICEs nested in this way mean that a
+single tag determines which element is present in more than one
+CHOICE\@.
+
+The decoding routines allocate memory to hold the decoded value.  By
+default snacc decoders use nibble memory (see Section
+\ref{lib-mem-C-section}) which is very efficient in allocation and
+virtually cost free for freeing.
+
+To save memory, decoders generated by some other tools build values
+that reference the data in the encoded PDU for types like OCTET
+STRING\@.  Snacc decoded values do not reference the BER data in any way
+for several reasons.  One, the encoded value may be held in some
+bizarre buffer making access to the value difficult.  Two, with more
+encoding rules being formalized, this technique may not always work
+since the encoded format may be different from the desired internal
+format.  Three, snacc decoders concatenate any constructed BIT and
+OCTET STRINGs values when decoding, to simplify processing in the
+application.
+
+Snacc decoders can detect a variety of errors which will be reported
+by {\C longjmp}.  Any tagging errors are reported. SETs must contain
+all non-OPTIONAL components and SEQUENCEs must be in order and contain
+all non-OPTIONAL components. Extra components in SETs and SEQUENCEs
+are considered an error.  Errors will also be reported if you attempt
+to decode values that exceed the limitations of the internal
+representation (e.\,g.\ an integer that is larger than a
+{\C long int} allows).
+
+\section{\label{print-gen-C-section}Print Routines}
+All of the generated print routines take similar parameters. For
+example the {\C T1} type's print routine prototype is:
+\begin{verbatim}
+void PrintT1 (FILE *f, T1 *v, unsigned short int indent);
+\end{verbatim}
+
+The print routine writes the given value, {\C v}, to the given {\C FILE~*},
+{\C f}.  The printed value is indented by {\C indent} spaces.  The
+values are printed in an ASN.1 value notation style.  {\C PrintT1}
+prints in the following style:
+\begin{small}
+\begin{verbatim}
+{ -- SEQUENCE --
+    17,
+    '436c696d6220617420537175616d697368'H  -- "Climb at Squamish" --,
+    0,
+    { -- SEQUENCE OF --
+        18,
+        19
+    },
+    { -- SEQUENCE --
+        id {2 40 29},
+        value '736f6d6520737472696e67'H  -- "some string" --
+    },
+    20
+}
+\end{verbatim}
+\end{small}
+
+OCTET STRINGs are printed in a hexadecimal notation, and any printable
+characters are included after the string in an ASN.1 comment.  Note
+that the enumerated type value, 0, did not print its symbol, ``A''
+from the ENUMERATED type.  It would be fairly easy to modify the C and
+C++ back ends to generate print routines that printed the ENUMERATED
+types' symbols instead of their values.
+
+\section{\label{free-gen-C-section}Free Routines}
+
+Snacc generates free routines of the form:
+\begin{verbatim}
+void FreeT1 (T1 *v);
+\end{verbatim}
+
+These routines will free all the components named type.
+For example the above {\C FreeT1} routine will free all the
+components of the given {\C T1} value, but not the {\C T1} value itself.  The
+passed in pointer is not freed because it may be embedded in another
+type which will be freed by another call to {\C Asn1Free}.  All the pieces
+of memory are freed using the {\C Asn1Free} macro defined in
+{\ufn asn-config.h}.  Each library type has its own free routine that
+may call {\C Asn1Free}. The values are typically allocated during
+decoding, using the {\C Asn1Alloc} macro.
+
+The memory management can be changed by editing the {\ufn asn-config.h}
+file to use you own memory management routines.  By default the memory
+manager uses the nibble memory system described in Section
+\ref{lib-mem-C-section}.  The nibble memory system does not need explicit
+frees of each component so the generated free routines are not needed.
+However, if you change the memory management to use something like
+{\C malloc} and {\C free}, you should use the generated free routines.
+
+
+\section{\label{val-gen-C-section}ASN.1 to C Value Translation}
+
+C values will be produced for INTEGER, BOOLEAN and OBJECT IDENTIFIER
+values.  C {\C extern} declarations for the value are put at the end
+of the header file (after all of the type definitions).  The value
+definitions are put at the beginning of the source file. For example,
+the following will be produced for the EX1 module (at the end of
+file ex1.h):
+
+\begin{small}
+\begin{verbatim}
+extern AsnOid anOidVal;
+extern AsnOid theSameOidVal;
+extern AsnInt anIntVal;
+extern AsnBool aBoolVal;
+extern AsnInt foobar;
+\end{verbatim}
+\end{small}
+
+(at the beginning of file ex1.c):
+
+\begin{small}
+\begin{verbatim}
+AsnOid anOidVal = { 2, "\170\35" };
+AsnOid theSameOidVal = { 2, "\170\35" };
+AsnInt anIntVal = 1;
+AsnBool aBoolVal = TRUE;
+AsnInt foobar = 29;
+\end{verbatim}
+\end{small}
+
+\section{\label{compiler-dir-C-section}Compiler Directives}
+
+Snacc allows the user to control some aspects of the generated code by
+inserting special comments in the ASN.1 source.  Warning! only the
+{\ASN isPdu} directive has been tested to any extent. Use the others
+very carefully and only if you really need to.  The compiler
+directives have the form:
+
+\begin{verbatim}
+--snacc <attribute>:"<value>"  <attribute>:"<value>" ...
+\end{verbatim}
+
+The {\ASN attribute} is the name of one of the accepted attributes and
+the {\ASN value} is what the {\ASN attribute}'s new value will be.
+The attribute value pairs can be listed in a single {\ASN --snacc}
+comment or spread out in a list of consecutive comments.
+
+Compiler directives are only accepted in certain places in the ASN.1
+code.  Depending on their location in the ASN.1 source, the compiler
+directives affect type definitions or type references.  The directives
+for type definitions and references are different.  Module level
+compiler directives to specify output file names and other information
+would be useful, but are not implemented.
+
+Here is an example to present some of the compiler directives and
+their uses.  Let's say your data structure always deals with
+{\C PrintableStrings} that are null terminated (internally, not in
+the encoding).  The default snacc string type is a structure that
+includes a length and {\C char~*} for the string octets.  To change
+the default type to a simple {\C char~*} the best way would be define
+your own string type, let's say {\ASN MyString} as follows:
+
+\begin{small}
+\begin{verbatim}
+Foo ::= SET
+{
+    s1 [0] MyString OPTIONAL,
+    s2 [1] MyString,
+    i1 [2] INTEGER
+}
+
+Bar ::= CHOICE
+{
+    s1 MyString,
+    i1 INTEGER
+}
+
+Bell ::= MyString
+
+MyString ::= --snacc isPtrForTypeDef:"FALSE"
+             --snacc isPtrForTypeRef:"FALSE"
+             --snacc isPtrInChoice:"FALSE"
+             --snacc isPtrForOpt:"FALSE"
+             --snacc optTestRoutineName:"MYSTRING_NON_NULL"
+             --snacc genPrintRoutine:"FALSE"
+             --snacc genEncodeRoutine:"FALSE"
+             --snacc genDecodeRoutine:"FALSE"
+             --snacc genFreeRoutine:"FALSE"
+             --snacc printRoutineName:"printMyString"
+             --snacc encodeRoutineName:"EncMyString"
+             --snacc decodeRoutineName:"DecMyString"
+             --snacc freeRoutineName:"FreeMyString"
+             PrintableString --snacc cTypeName:"char *"
+\end{verbatim}
+\end{small}
+
+All but the last {\ASN --snacc} comment bind with the {\ASN MyString} type
+definition. The last directive comment binds with the {\ASN PrintableString}
+type.  The C data structure resulting from the above ASN.1 and compiler
+directives is the following:
+\begin{small}
+\begin{verbatim}
+typedef char *MyString; /* PrintableString */
+
+typedef struct Foo /* SET */
+{
+    MyString s1; /* [0] MyString OPTIONAL */
+    MyString s2; /* [1] MyString */
+    AsnInt i1; /* [2] INTEGER */
+} Foo;
+
+typedef struct Bar /* CHOICE */
+{
+    enum BarChoiceId
+    {
+        BAR_S1,
+        BAR_I1
+    } choiceId;
+    union BarChoiceUnion
+    {
+        MyString s1; /* MyString */
+        AsnInt i1; /* INTEGER */
+    } a;
+} Bar;
+
+typedef MyString Bell; /* MyString */
+\end{verbatim}
+\end{small}
+
+The compiler directives used on the {\ASN MyString} type have some
+interesting effects.  Notice that {\ASN MyString} is not referenced by
+pointer in the CHOICE, SET, or type definition, {\ASN Bell}.
+
+The generated code for encoding field {\C s1} of {\C Foo} type
+will use the code\linebreak``{\C MYSTRING\_NON\_NULL (\&fooVal-->s1)}'' to check
+for the presence of the OPTIONAL {\C s1} field.  The code associated
+with MYSTRING\_NON\_NULL should return TRUE if the {\C s1} field
+value is present and might look like:
+\begin{verbatim}
+#define MYSTRING_NON_NULL(s) (*s != NULL)
+\end{verbatim}
+
+The argument to {\C optTestRoutine} routine will be a pointer to the
+field type's defining type.  Note that in the above example,
+{\ASN MyString} is a {\C char~*}, therefore the {\C MYSTRING\_NON\_NULL}
+macro's argument will be a {\C char~**}.
+
+Setting the {\ASN genPrintRoutine} etc. attributes to false makes
+snacc not define or generate any encode, decode, print, or free
+routines for the {\ASN MyString} type.  You must provide these
+yourself; the best approach is to take the normal {\ASN PrintableString}
+routines and modify them to handle your special string type.
+
+The names of the encode, decode, print and free routines used for the
+{\ASN MyString} type will be based on the ones given with the
+{\ASN printRoutineName} etc.\  attributes.  Snacc will prepend a
+``B'' (for BER) and append a ``Content'' to the encode and decode
+routines names, so you must provide the {\C BEncMyStringContent} and
+{\C BDecMyStringContent} routines.  You may also need the
+{\C BEncMyString} and {\C BDecMyString} routines if {\ASN MyString} is a
+PDU type or used in an ANY or ANY DEFINED type.
+
+The {\ASN PrintableString} type has its C type name changed to
+{\C char~*} by the last compiler directive.  Thus {\ASN MyString} is defined
+as a {\C char~*}.  This directive applies to the {\ASN PrintableString}
+type reference.  Note that these directives do not affect the tags or
+the encoded representation of the {\ASN MyString} type
+
+The location of the {\ASN --snacc} comment(s) is important.
+{\ASN --snacc} comment(s) between the {\ASN ::=} sign and the
+following type are associated with the type being defined. Any
+compiler directives after the type and before the next type or value
+definition are associated with the type.  Fields in SETs, SEQUENCEs
+and CHOICEs can be modified by putting the compiler directive after
+the comma that follows the field type that you wish to modify.  In the
+case of the last element of one of these types, where there is no
+comma, just place it after the field and before the closing bracket of
+the parent type.
+
+Attributes shadow the type attributes filled in during the target
+language type information generation pass of the compiler.  The type
+definition attributes are:
+
+\begin{description}
+\item[cTypeName] { this is the type name that the generated type will
+have. Its value can be any string that is valid as a C type name.}
+
+\item[isPdu]     { whether this is a PDU type.  A PDU type will have
+extra interfaces to the encode and decode routines generated. Its
+value can be ``TRUE'' or ``FALSE''}
+
+\item[isPtrForTypeDef] { TRUE if other types defined solely by this type
+definition are defined as a pointer to this type. Its
+value can be ``TRUE'' or ``FALSE''.}
+
+\item[isPtrForTypeRef]{ TRUE if type references to this type
+definition from a SET or SEQUENCE are by pointer. Its
+value can be ``TRUE'' or ``FALSE''.}
+
+\item[isPtrInChoice] {TRUE if type references to this type definition
+from a CHOICE are by pointer. Its value can be ``TRUE'' or ``FALSE''.}
+
+
+\item[isPtrForOpt]  { TRUE if OPTIONAL type references to this type
+definition from a SET or SEQUENCE are by pointer. Its value can be
+``TRUE'' or ``FALSE''.}
+
+\item[optTestRoutineName] {name of the routine to test whether an
+OPTIONAL element of this type in a SET or SEQUENCE is present. The
+routine should return TRUE if the element is present.  The value of
+this field is usually just the name of a C macro that tests for NON-NULL\@.
+The argument to the routine will be a pointer to the type definition's
+type.  The optTestRoutineName value can be any string value.}
+
+\item[defaultFieldName] { if this type is used in a SET, SEQUENCE or
+CHOICE without a field name then this value is used with a digit
+appended to it.  Its value can be any string that is a valid C field
+name in a struct or union.}
+\item[printRoutineName] { name of this type definition's printing
+routine.  Its value can be any string that is a C function or
+macro name.}
+\item[encodeRoutineName]{ name of this type definition's encoding
+routine. Its value can be any string that is a C function or
+macro name.}
+\item[decodeRoutineName]{ name of this type definition's decoding
+routine. Its value can be any string that is a C function or
+macro name.}
+\item[freeRoutineName]  { name of this type definition's freeing
+routine. Its value can be any string that is a C function or
+macro name.}
+
+\item[isEncDec] {If this type is used in a SET or SEQUENCE then it is not
+encoded or decoded.  Its value can be ``TRUE'' or ``FALSE''.  This is
+handy for adding your own types to a standard that are only for local
+use, and are not included in encoded values.}
+
+\item[genTypeDef] { TRUE if you want a C type to be generated for this
+type definition. Its values can be ``TRUE'' or ``FALSE''.}
+
+\item[genPrintRoutine] { TRUE if you want a printing routine to be
+generated for this type definition. Its values can be ``TRUE'' or
+``FALSE''.}
+\item[genEncodeRoutine] { TRUE if you want an encoding routine to be
+generated for this type definition. Its values can be ``TRUE'' or
+``FALSE''.}
+\item[genDecodeRoutine] { TRUE if you want a decoding routine to be
+generated for this type definition. Its values can be ``TRUE'' or
+``FALSE''.}
+\item[genFreeRoutine] { TRUE if you want a free routine to be
+generated for this type definition. Its values can be ``TRUE'' or
+``FALSE''.}
+\end{description}
+
+
+The type reference attributes are slightly different from the type
+definition attributes due to the semantic differences between a type
+definition and a type reference.  Type references will inherit some of
+their attributes from the referenced type definition.  The following
+are the valid type reference attributes:
+\begin{description}
+\item[cTypeName] { this is the type name that the generated type will
+have. Its value can be any string that is valid as a C type name.}
+
+\item[cFieldName] { if this is a field in a CHOICE, SET or SEQUENCE
+then this holds the C field name for this reference. Its value can be
+any string that is valid as a C field name.}
+
+\item[isPtr] { TRUE if this is a pointer to the type named by
+cTypeName.  This is usually determined from the referenced type
+definitions attributes. Its value can be ``TRUE'' or ``FALSE''.}
+
+\item[optTestRoutineName] {if this field is an OPTIONAL component then
+this is the name of the routine to test whether it is present.  The
+routine should return TRUE if the element is present.  The value of
+this is usually just the name of a C macro that tests for NULL\@. The
+argument to the routine will be a pointer to the type definition's
+type.  The optTestRoutineName value can be any string value.}
+
+\item[printRoutineName] { name of this type reference's printing
+routine.  This and the other routine name attributes are useful for
+special instances of the referenced type.  It is easier to modify the
+referenced type definition if you want every instance of this type to
+use a certain print etc.\  routine.  Its value can be any string that is
+a value C function or macro name.}
+
+\item[encodeRoutineName]{ name of this type reference's encoding
+routine. Its value can be any string that is a function or
+macro name.}
+
+\item[decodeRoutineName]{ name of this type reference's decoding
+routine. Its value can be any string that is a C function or
+macro name.}
+
+\item[freeRoutineName]  { name of this type reference's freeing
+routine. Its value can be any string that is a C function or
+macro name.}
+
+\item[isEncDec] { If this type is used in a SET or SEQUENCE then the
+field is not encoded or decoded.  Its value can be ``TRUE'' or
+``FALSE''.  This is handy for adding your own types to a standard that
+are only for local use, and are not included in encoded values.}
+
+\item[choiceIdSymbol] {if this is a component of a CHOICE, this string
+attribute will be the defined/enum symbol whose value in the choiceId
+field indicates the presence of this field.}
+\item[choiceIdValue]  {if this is a component of a CHOICE, this integer
+attribute will be the value associated with the symbol in choiceIdSymbol.}
+
+\end{description}
+
+
+
+
+\section{\label{compiling-gen-C-section}Compiling the Generated C Code}
+
+The generated C code (and libraries) can be compiled by both ANSI and K\&R C compilers.
+C function prototypes use the {\C PROTO} macro and C function declarations use the {\C PARAMS} macro.
+These macros are defined in {\ufn \dots/snacc.h} and their definitions depend on whether the {\C \_\_USE\_ANSI\_C\_\_} flag has been defined in {\ufn \dots/config.h}.
+
+When compiling the generated C code you will need:
+\begin{enumerate}
+\item
+  The include directory where the files from {\ufn \dots/c-lib/inc/} have been installed into in your include path so the C sources can include the library header files.
+  The header files should be included with statements like {\C \#include <snacc/c/asn-incl.h>} and your C compiler should be supplied with {\ufn -I/usr/local/include} in case snacc got installed under {\ufn /usr/local/}.
+\item
+  to link with the correct C ASN.1 runtime library, depending on the buffer type you choose.
+  In case snacc got installed under {\ufn /usr/local/}, your linker may need to be supplied with {\ufn -L/usr/local/lib} and one of {\ufn -lasn1cebuf}, {\ufn -lasn1cmbuf} or {\ufn -lasn1csbuf} as arguments.
+\item
+  to link with the math library ({\ufn -lm}), since the ASN.1 REAL type's encode and decode routine use some math routines.
+\end{enumerate}
+
+See the example in {\ufn \dots/c-examples/simple/} for a complete
+example. The makefile and main routines are probably the most
+important.  There are several other examples in the
+{\ufn \dots/c-examples/} directory.
diff --git a/SecuritySNACCRuntime/doc/c-lib.tex b/SecuritySNACCRuntime/doc/c-lib.tex
new file mode 100644
index 00000000..48cd5265
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/c-lib.tex
@@ -0,0 +1,1384 @@
+% file: .../doc/c-lib.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c-lib.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: c-lib.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:52  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:34  rj
+% first check-in
+%
+
+\chapter{\label{lib-C-chapter}C ASN.1 Library}
+\section{\label{libover-C-section}Overview}
+
+Each library type has a file in the {\ufn \dots/c-lib/src/} and
+{\ufn \dots/c-lib/inc/} directories.  Each source file contains the encode,
+decode, free and print routines for the given type. This chapter
+contains a description of each library type and its routines.
+This library is also referred to as the runtime library.
+
+After installing Snacc, you should test the library types to make sure
+that they are encoding and decoding properly.  Use the
+{\ufn \dots/c-examples/test-lib/} example to check them.
+
+In addition to other errors, most decoding routines will report an
+error if they attempt to read past the end of the data.  Be aware that
+some buffer types do not support this type of checking.  This is
+explained more in the buffer management section.
+
+\section{\label{tag-C-section}Tags}
+
+Snacc's tag representation was motivated by several things.
+\begin{enumerate}
+\item the tags must be easy to compare for equality in {\C if} and {\C switch} statements to make tag-based decisions cheap.
+\item a tag must be cheap to decode.
+\item a tag must be cheap to encode.
+\end{enumerate}
+
+The first requirement meant that tags had to be integer types (for the
+{\C switch} statement).  The representation of the tag within the integer
+was set by the second requirement.
+
+The best way to decode cheaply is minimize the transformation between
+the encoded and decoded (internal) format.  So the four (can be set-up
+for two) bytes of the long integer are used to hold the encoded tag,
+starting with the first octet of the tag in the most significant byte
+of the integer and the rest (if any) following.  Any unused (always
+trailing) bytes in the integer are zero.  This limits the
+representable tag code to less than $2^{21}$ but for reasonable ASN.1
+specifications this should not be a problem.
+
+To meet the third requirement the decoded tag representation was
+bypassed entirely by using macros ({\C BEncTag1()} etc.) that
+write the encoded tag octet(s) to the buffer. The writing of an
+encoded tag octet involves bit shifting, bitwise ands and bitwise ors
+with constant values; most optimizing C compilers can compute these at
+compile time.  This simplifies encoding a tag to writing some constant
+byte value(s) to the buffer.
+
+The following excerpt from {\ufn \dots/c-lib/inc/asn-tag.h} shows some
+of the tag routines.
+\begin{small}
+\begin{verbatim}
+typedef unsigned long int AsnTag;
+
+#define MAKE_TAG_ID( class, form, code) ...
+#define TAG_IS_CONS( tag) ...
+
+#define BEncTag1( b, class, form, code) ...
+#define BEncTag2( b, class, form, code) ...
+#define BEncTag3( b, class, form, code) ...
+#define BEncTag4( b, class, form, code) ...
+#define BEncTag5( b, class, form, code) ...
+
+AsnTag BDecTag (BUF_TYPE b, AsnLen *bytesDecoded, ENV_TYPE env);
+\end{verbatim}
+\end{small}
+
+The generated decode routines use the {\C BDecTag} to decode a tag
+from the buffer.  The returned tag value is either used in an
+{\C if} expression or as the argument to {\C switch} statements.
+The {\C MAKE\_TAG\_ID} macro is used to make a tag for comparison to
+the one returned by {\C BDecTag}. The {\C MAKE\_TAG\_ID} is used is
+{\C switch} statement case labels and in {\C if} statements.
+
+Most of the time tags are only compared for equality, however, the
+OCTET STRING and BIT STRING decoders check the constructed bit in the
+tag using the {\C TAG\_IS\_CONS} macro.
+
+The {\C BEncTag} macros are quite fragile because they return the
+encoded length of the tag; they cannot be treated as a single
+statement.  This requires careful use of braces when using them in
+your own code in places such as the sole statement in an {\C if}
+statement.  This ugliness is caused by the difficulty in returning
+values from multi-line macros (macros are used for performance here
+since encoding tags can be a significant part of BER encoding).
+
+The {\C BDecTag} routine will report an error via {\C longjmp} if
+the encoded tag is longer than can be held in the {\C AsnTag} type
+or if it read past the end of the data when decoding the tag.
+
+\section{\label{len-C-section}Lengths}
+
+Decoded lengths are represented by unsigned long integers, with the
+maximum value indicating indefinite length.
+
+Snacc users can choose between using only indefinite or only definite
+lengths when encoding constructed values' lengths when compiling the
+generated code.  Of course, the generated decoders can handle both
+forms.  Define the {\C USE\_INDEF\_LEN} symbol when compiling the
+generated code if you want to use indefinite lengths when encoding
+constructed values.  Primitive values are always encoded with definite
+lengths as required by the standard; this is necessary to avoid
+confusion between a value's content and the End-Of-Contents marker.
+
+There is no loss of performance when using definite lengths with snacc
+encoders.  This is due the ``backwards'' encoding as described in
+Section~\ref{encode-gen-C-section}.  The schemes used by other compilers'
+encoders to handle definite lengths may hurt performance.
+
+Most of the routines in the following code are obvious except for
+{\C BEncDefLenTo127()}.  This is used instead of {\C BEncDefLen}
+in the generated code when the compiler knows the value being encoded
+will not be over 127 octets long.  Values such as BOOLEANs,
+INTEGERs, and REALs are assumed to be shorter than 127 octets
+(constraints on the decoded representation of INTEGERs and REALs make
+this valid).
+\begin{small}
+\begin{verbatim}
+typedef unsigned long int AsnLen;
+
+/* max unsigned value - used for internal rep of indef len */
+#define INDEFINITE_LEN          ~0L
+
+#ifdef USE_INDEF_LEN
+#define BEncEocIfNec( b)        BEncEoc (b)
+#define BEncConsLen(b, len)     2 + BEncIndefLen (b)
+#else
+#define BEncEocIfNec( b)
+#define BEncConsLen( b, len)    BEncDefLen (b, len)
+#endif
+
+#define BEncIndefLen( b) ...
+#define BEncDefLenTo127( b, len) ...
+AsnLen  BEncDefLen (BUF_TYPE b, AsnLen len);
+AsnLen  BDecLen (BUF_TYPE b, AsnLen *bytesDecoded, ENV_TYPE env);
+
+#define BEncEoc( b) ...
+#define BDEC_2ND_EOC_OCTET( b, bytesDecoded, env) ...
+void    BDecEoc (BUF_TYPE b, AsnLen *bytesDecoded, ENV_TYPE env);
+\end{verbatim}
+\end{small}
+
+The {\C BDecLen} routine will report an error via {\C longjmp} if
+it attempts to read past the end of the data or the decoded length is
+too large to be held in the {\C AsnLen} representation.
+{\C BDecEoc} will report an error if it attempts to read past the
+end of the data or one of the EOC (End-Of-Contents) octets is
+non-zero.
+
+\section{\label{bool-C-section}BOOLEAN}
+
+The BOOLEAN type is represented by an {\C unsigned char}.  It has
+the following routines for manipulating it.
+\begin{small}
+\begin{verbatim}
+typedef unsigned char AsnBool;
+
+AsnLen BEncAsnBool (BUF_TYPE b, AsnBool *data);
+void   BDecAsnBool (BUF_TYPE b, AsnBool *result, AsnLen *bytesDecoded,
+                   ENV_TYPE env);
+
+AsnLen BEncAsnBoolContent (BUF_TYPE b, AsnBool *data);
+void   BDecAsnBoolContent (BUF_TYPE b, AsnTag tag, AsnLen len,
+                          AsnBool *result, AsnLen *bytesDecoded,
+                          ENV_TYPE env);
+
+#define FreeAsnBool( v)
+void PrintAsnBool (FILE *f, AsnBool *b, unsigned short int indent);
+\end{verbatim}
+\end{small}
+
+As discussed in Sections \ref{encode-gen-C-section} and \ref{decode-gen-C-section},
+{\C BEncAsnBool} and {\C BDecAsnBool} encode/decode the UNIVERSAL
+tag, length and content of the given BOOLEAN value.  The\linebreak {\C BEncAsnBoolContent} and {\C BDecAsnBoolContent} routine only
+encode/decode the content of the given BOOLEAN value.
+
+The {\C FreeAsnBool} routine does nothing since the BOOLEAN type
+does not contain pointers to data; the free routine generator does not
+have to check which types need freeing and simply calls the type's
+free routine.  It also allows the user to modify the types and their
+free routines without changing the free routine generator.  However,
+the ANY and ANY DEFINED BY type hash table initialization routine
+generator does need to know which types have empty free routines
+because the hash entries contain pointers to the free functions (NULL
+is used for the empty free functions like {\C FreeAsnBool}).  The
+INTEGER, NULL, REAL and ENUMERATED types have empty free routines for
+the same reason.
+
+{\C BDecAsnBool} will report an error if the tag is not
+UNIVERSAL-PRIM-1.  {\C BDecAsnBoolContent} will report an error if it
+decodes past the end of the data or the length of the encoded value
+(given by the {\C len} parameter) is not exactly one octet.
+
+\section{\label{int-C-section}INTEGER}
+
+The INTEGER type is represented by a 32 bit integer type, {\C AsnInt}.
+The C integer type chosen depends on the machine and compiler and may be {\C int}, {\C long} or {\C short}, whatever is 32 bits in size.
+If you are using INTEGER types that are only positive (via subtyping or
+protocol definition) you may want to use the {\C UAsnInt} and
+associated routines that use the unsigned int for a larger positive value range.
+\begin{small}
+\begin{verbatim}
+typedef int AsnInt;
+typedef unsigned int UAsnInt;
+
+AsnLen BEncAsnInt (BUF_TYPE b, AsnInt *data);
+void BDecAsnInt (BUF_TYPE b, AsnInt *result, AsnLen *bytesDecoded,
+                ENV_TYPE env);
+
+AsnLen BEncAsnIntContent (BUF_TYPE b, AsnInt *data);
+void BDecAsnIntContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen,
+                       AsnInt  *result, AsnLen *bytesDecoded,
+                       ENV_TYPE env);
+
+#define FreeAsnInt( v)
+void PrintAsnInt (FILE *f, AsnInt *v, unsigned short int indent);
+
+AsnLen BEncUAsnInt (BUF_TYPE b, UAsnInt *data);
+void BDecUAsnInt (BUF_TYPE b, UAsnInt *result, AsnLen *bytesDecoded,
+                 ENV_TYPE env);
+
+AsnLen BEncUAsnIntContent (BUF_TYPE b, UAsnInt *data);
+void BDecUAsnIntContent (BUF_TYPE b, AsnTag tagId, AsnLen len,
+                        UAsnInt *result, AsnLen *bytesDecoded,
+                        ENV_TYPE env);
+
+#define FreeUAsnInt( v)
+void PrintUAsnInt (FILE *f, UAsnInt *v, unsigned short int indent);
+\end{verbatim}
+\end{small}
+
+{\C BDecAsnInt} will report an error if the tag is not
+UNIVERSAL-PRIM-2.  {\C BDecAsnIntContent} will report an error if it
+decodes past the end of the data or the integer value is too large for
+an {\C AsnInt}.
+
+\section{\label{null-C-section}NULL}
+
+The NULL type is represented by the {\C AsnNull} type.  Its content
+is always empty and hence its encoded length always is zero.
+\begin{small}
+\begin{verbatim}
+typedef char AsnNull;
+
+AsnLen BEncAsnNull (BUF_TYPE b, AsnNull *data);
+void BDecAsnNull (BUF_TYPE b, AsnNull *result, AsnLen *bytesDecoded,
+                 ENV_TYPE env);
+
+/* 'return' length of encoded NULL value, 0 */
+#define BEncAsnNullContent(b, data) 0
+void BDecAsnNullContent (BUF_TYPE b, AsnTag tag, AsnLen len,
+                        AsnNull *result, AsnLen *bytesDecoded,
+                        ENV_TYPE env);
+
+#define FreeAsnNull( v)
+void PrintAsnNull (FILE *f, AsnNull * b, unsigned short int indent);
+\end{verbatim}
+\end{small}
+
+\section{\label{real-C-section}REAL}
+
+The REAL type is represented by {\C AsnReal}, a double.  This type's
+representation can depend on the compiler or system you are using so
+several different encoding routines are provided.
+Even so, you may need to modify the code.
+
+If you are using the REAL type in your ASN.1 modules, you should call the
+{\C InitAsnInfinity()} routine to setup the {\C PLUS\_INFINITY}
+and {\C MINUS\_INFINITY} values.
+
+There are three encode routines included and they can be selected by
+defining one of {\C IEEE\_REAL\_FMT}, {\C IEEE\_REAL\_LIB} or nothing.
+Defining {\C IEEE\_REAL\_FMT} uses the encode routine that assumes the
+double representation is the standard IEEE double \cite{68881}.
+Defining {\C IEEE\_REAL\_LIB} uses the encode routine that assumes the
+IEEE functions library (isinf, scalbn, signbit etc.\ ) is available.
+If neither are defined, the default encode routine uses {\C frexp}.
+
+There is only one content decoding routine and it builds the value
+through multiplication and the {\C pow} routine (requires the math
+library).  The content decoding routine only supports the binary
+encoding of a REAL, not the decimal encoding.
+
+\begin{small}
+\begin{verbatim}
+typedef double AsnReal;
+
+extern AsnReal PLUS_INFINITY;
+extern AsnReal MINUS_INFINITY;
+
+void InitAsnInfinity();
+AsnLen BEncAsnReal (BUF_TYPE b, AsnReal *data);
+void BDecAsnReal (BUF_TYPE b, AsnReal *result, AsnLen *bytesDecoded,
+                       ENV_TYPE env);
+
+AsnLen BEncAsnRealContent (BUF_TYPE b, AsnReal *data);
+void BDecAsnRealContent (BUF_TYPE b, AsnTag tag, AsnLen len,
+                               AsnReal *result, AsnLen *bytesDecoded,
+                               ENV_TYPE env);
+
+/* do nothing */
+#define FreeAsnReal( v)
+void PrintAsnReal (FILE *f, AsnReal *b, unsigned short int indent);
+\end{verbatim}
+\end{small}
+
+{\C BDecAsnReal} will report an error if the value's tag is not UNIVERSAL-PRIM-9.
+{\C BDecAsnRealContent} will report an error if the base is not supported or the decimal type REAL encoding is received.
+
+
+\section{\label{bits-C-section}BIT STRING}
+
+The BIT STRING type is represented by the {\C AsnBits} structure.  It
+contains a pointer to the bits and integer that holds the length
+in bits of the BIT STRING\@.
+
+In addition to the standard encode, decode, print and free routines,
+there are some other utility routines.  {\C AsnBitsEquiv} returns
+TRUE if the given BIT STRINGs are identical.  The {\C SetAsnBit},
+{\C ClrAsnBit} and {\C GetAsnBit} are routines for writing and
+reading a BIT STRING value.
+
+You may notice that the AsnBits type does not have any means of
+handling linked pieces of BIT STRINGs. Some ASN.1 tools use lists of
+structures like {\C AsnBits} to represent BIT STRINGs.  This is done
+because, as you should be aware, BIT STRINGs can be encoded in a
+nested, constructed fashion.  The snacc BIT STRING decoder attempts to
+save you the hassle of dealing with fragments of BIT STRINGs by
+concatenating them in the decoding step.  Every BIT STRING value
+returned by the decoder will have contiguous bits.
+
+Some people contend that fragmented BIT STRINGs are necessary to
+support systems that lack enough memory to hold the entire value.
+Snacc encodes value ``backwards'' so the entire value must be encoded
+before it can be sent, thus you must have enough memory to hold the
+whole encoded value.  If the fragmented representation is useful to
+your protocol implementation for other reasons, it should be fairly
+simple to modify the BIT STRING routines.  Remember, no significance
+should be placed on where constructed BIT STRING values are fragmented.
+
+Snacc uses a table to hold pointers to the BIT STRING fragments in the
+buffer while it is decoding them. Once the whole BIT STRING value has
+been decoded, a block of memory that is large enough to hold the
+entire BIT STRING is allocated and the fragments are copied into it.
+The table initially can hold pointers to 128 fragments.  If more table
+entries are needed the stack will grow via {\C realloc} (with
+associated performance loss) and will not shrink after growing.  If
+you wish to modify this behaviour, change the
+{\ufn \dots/c-lib/inc/str-stk.h} file.
+
+The {\C FreeAsnBits} routine will free memory referenced by the
+{\C bits} pointer.
+
+\begin{small}
+\begin{verbatim}
+typedef struct AsnBits
+{
+  int   bitLen;
+  char  *bits;
+} AsnBits;
+
+extern char numToHexCharTblG[];
+#define TO_HEX( fourBits)        (numToHexCharTblG[(fourBits) & 0x0f])
+#define ASNBITS_PRESENT( abits)  ((abits)->bits != NULL)
+
+AsnLen BEncAsnBits (BUF_TYPE b, AsnBits *data);
+void BDecAsnBits (BUF_TYPE b, AsnBits *result, AsnLen *bytesDecoded,
+                 ENV_TYPE env);
+
+AsnLen BEncAsnBitsContent (BUF_TYPE b, AsnBits *bits);
+void BDecAsnBitsContent (BUF_TYPE b, AsnLen len, AsnTag tagId,
+                        AsnBits *result, AsnLen *bytesDecoded,
+                        ENV_TYPE env);
+
+void FreeAsnBits (AsnBits *v);
+void PrintAsnBits (FILE *f, AsnBits *b, unsigned short int indent);
+
+int AsnBitsEquiv (AsnBits *b1, AsnBits *b2);
+void SetAsnBit (AsnBits *b1, unsigned long int bit);
+void ClrAsnBit (AsnBits *b1, unsigned long int bit);
+int GetAsnBit (AsnBits *b1, unsigned long int bit);
+\end{verbatim}
+\end{small}
+
+{\C BDecAsnBits} will report an error if the tag is not UNIVERSAL-CONS-3 or UNIVERSAL-PRIM-3.
+When decoding constructed BIT STRING BER values, an error will be reported if a component other than the last one has non-zero unused bits in its last octet or an internal component does not have the UNIVERSAL-3 tag.
+If the decoder attempts to read past the end of the data an error will be reported.
+
+
+\section{\label{octets-C-section}OCTET STRING}
+The OCTET STRING type is represented by the {\C AsnOcts} structure.
+It contains a pointer to the octets and an integer that holds the length in octets of the OCTET STRING\@.
+
+As with BIT STRINGs, OCTET STRINGs can have constructed values.  These
+are handled in the same way as the constructed BIT STRING values. The
+decoded representation of an OCTET STRING is always contiguous.
+
+The {\C FreeAsnOcts} routine will free the memory referenced by the
+{\C octs} pointer.  The {\C AsnOctsEquiv} routine will return TRUE
+if the given OCTET STRINGs are identical.
+
+\begin{small}
+\begin{verbatim}
+typedef struct AsnOcts
+{
+  unsigned long int  octetLen;
+  char               *octs;
+} AsnOcts;
+
+#define ASNOCTS_PRESENT( aocts)  ((aocts)->octs != NULL)
+
+AsnLen BEncAsnOcts (BUF_TYPE b, AsnOcts *data);
+
+void BDecAsnOcts (BUF_TYPE b, AsnOcts *result, AsnLen *bytesDecoded,
+                 ENV_TYPE env);
+
+AsnLen BEncAsnOctsContent (BUF_TYPE b, AsnOcts *octs);
+void BDecAsnOctsContent (BUF_TYPE b, AsnLen len, AsnTag tagId,
+                         AsnOcts *result, AsnLen *bytesDecoded,
+                         ENV_TYPE env);
+
+void FreeAsnOcts (AsnOcts *o);
+void PrintAsnOcts (FILE *f, AsnOcts *o, unsigned short int indent);
+
+int AsnOctsEquiv (AsnOcts *o1, AsnOcts *o2);
+\end{verbatim}
+\end{small}
+
+{\C BDecAsnOcts} will report an error if the tag is not
+UNIVERSAL-CONS-4 or UNIVERSAL-PRIM-4.  When decoding constructed OCTET
+STRING BER values, an error will be reported if an internal component
+does not have the UNIVERSAL-4 tag. If the decoder attempts to read
+past the end of the data an error will be reported.
+
+
+\section{\label{oid-C-section}OBJECT IDENTIFIER}
+
+In snacc, OBJECT IDENTIFIERs are kept in their encoded form to improve
+performance.  The {\C AsnOid} type is defined as {\C AsnOcts}, as
+it holds the octets of the encoded OBJECT IDENTIFIER\@.  It seems that
+the most common operation with OBJECT IDENTIFIERs is to compare for
+equality, for which the encoded representation (which is canonical)
+works well.
+
+There is a linked OBJECT IDENTIFIER representation called {\C OID}
+and routines to convert it to and from the {\C AsnOid} format, but it
+should not be used if performance is an issue.
+
+Since the OBJECT IDENTIFIERs are represented {\C AsnOcts}, the
+{\C AsnOcts} content encoding routine can be used for the
+{\C AsnOid} content encoding routine.  The other {\C AsnOcts}
+encoding and decoding routines cannot be used because the OBJECT
+IDENTIFIER has a different tag and cannot be encoded in a constructed
+fashion.
+
+An OBJECT IDENTIFIER must have a minimum of two arc numbers but the
+decoding routines do not check this.
+
+\begin{small}
+\begin{verbatim}
+typedef AsnOcts AsnOid;
+
+#define ASNOID_PRESENT( aoid)  ASNOCTS_PRESENT (aoid)
+
+AsnLen BEncAsnOid (BUF_TYPE b, AsnOid *data);
+void BDecAsnOid (BUF_TYPE b, AsnOid *result, AsnLen *bytesDecoded,
+                ENV_TYPE env);
+
+#define BEncAsnOidContent(b, oid)  BEncAsnOctsContent(b, oid)
+void BDecAsnOidContent (BUF_TYPE b, AsnTag tag, AsnLen len,
+                       AsnOid  *result, AsnLen *bytesDecoded,
+                       ENV_TYPE env);
+
+#define FreeAsnOid  FreeAsnOcts
+void PrintAsnOid (FILE *f, AsnOid *b, unsigned short int indent);
+
+#define AsnOidsEquiv( o1, o2)   AsnOctsEquiv (o1, o2)
+\end{verbatim}
+\end{small}
+
+
+\section{\label{list-C-section}SET OF and SEQUENCE OF}
+
+The SET OF and SEQUENCE OF type are represented by the {\C AsnList}
+structure.  An {\C AsnList} consists of a head object that has
+pointers to the first, current and last nodes and the current number
+of nodes in the list.  Each list node has a pointer to its next and
+previous list member and the node's data.  The first list node's
+previous pointer is always NULL and the last list node's next pointer
+is always NULL\@.
+
+Each SET OF or SEQUENCE OF type is defined as an {\C AsnList}, so the
+element type information (kept via a {\C void~*}) is not kept,
+therefore, the {\C AsnList} type is not type safe.
+
+The {\C AsnList} is a doubly linked list to simplify ``backwards''
+encoding.  The reverse link allows the list to be traversed in reverse
+so the components can be encoded from last to first.
+
+Initially, the lists were designed to allow the list element itself to
+be contained in the list node (hence the {\C elmtSize} parameter to
+the AsnListNew() routine).  The design eventually changed such that
+every list element was reference by pointer from the list node.
+
+A small problem with the {\C AsnListNew} routine is the memory
+allocation.  Since it is used by the decoding routines to allocate new
+lists, it uses whatever memory management you have setup with the
+{\C Asn1Alloc} macro (see Section~\ref{lib-mem-C-section}).  This may not be
+desirable when building values to be transmitted.  You may need to
+provide another AsnListNew routine that uses a different allocation
+scheme to solve this.
+
+\begin{small}
+\begin{verbatim}
+typedef struct AsnListNode
+{
+    struct AsnListNode *prev;
+    struct AsnListNode *next;
+    void            *data; /* this must be the last field of this structure  */
+} AsnListNode;
+
+typedef struct AsnList
+{
+    AsnListNode *first;
+    AsnListNode *last;
+    AsnListNode *curr;
+    int        count;    /* number of elements in list               */
+    int        dataSize; /* space required in each node for the data */
+} AsnList;
+
+#define FOR_EACH_LIST_ELMT( elmt, list) ...
+#define FOR_EACH_LIST_ELMT_RVS( elmt, list) ...
+#define FOR_REST_LIST_ELMT( elmt, al) ...
+
+#define CURR_LIST_ELMT( al)    (al)->curr->data
+#define NEXT_LIST_ELMT( al)    (al)->curr->next->data
+#define PREV_LIST_ELMT( al)    (al)->curr->prev->data
+#define LAST_LIST_ELMT( al)    (al)->last->data
+#define FIRST_LIST_ELMT( al)   (al)->first->data
+#define LIST_EMPTY(al) (( al)->count == 0)
+
+#define CURR_LIST_NODE( al) ((al)->curr)
+#define FIRST_LIST_NODE( al) ((al)->first)
+#define LAST_LIST_NODE( al) ((al)->last)
+#define PREV_LIST_NODE( al) ((al)->curr->prev)
+#define NEXT_LIST_NODE( al) ((al)->curr->next)
+#define SET_CURR_LIST_NODE( al, listNode)  ((al)->curr = (listNode))
+
+void  AsnListRemove (AsnList *l);
+void *AsnListAdd (AsnList *l);
+void *AsnListInsert (AsnList *list);
+void  AsnListInit (AsnList *list, int dataSize);
+AsnList *AsnListNew (int elmtSize);
+void *AsnListPrev (AsnList *);
+void *AsnListNext (AsnList *);
+void *AsnListLast (AsnList *);
+void *AsnListFirst (AsnList *);
+void *AsnListPrepend (AsnList *);
+void *AsnListAppend (AsnList *);
+void *AsnListCurr (AsnList *);
+int   AsnListCount (AsnList *);
+AsnList *AsnListConcat (AsnList *, AsnList *);
+\end{verbatim}
+\end{small}
+
+There are a number of macros for dealing with the list type, the
+most important being the list traversal macros.  The
+{\C FOR\_EACH\_LIST\_ELMT} macro acts like a ``for'' statment that
+traverses forward through the list.  The first parameter should be a
+pointer to the list element type that will be used to hold the current list
+element for each iteration of the ``for'' loop.  The second parameter is
+the list of elements that you wish to traverse.
+
+The {\C FOR\_EACH\_LIST\_ELMT\_RVS} macro is identical to the
+{\C FOR\_EACH\_LIST\_ELMT} macro except that is moves from the back of
+the list to the front.   The {\C FOR\_REST\_LIST\_ELMT} macro is
+similar to the other two but it does not reset the {\C curr} pointer
+in the {\C AsnList} type.  This has the effect of iterating from the
+current element to the end of the list.   Look in the generated code
+for a better indication of how to use these macros.  The other macros
+are straight forward.
+
+
+\section{\label{any-C-section}ANY and ANY DEFINED BY}
+
+
+The ANY and ANY DEFINED BY type are classically the most irritating
+ASN.1 types for compiler writers.  They rely on mechanisms outside of
+ASN.1 to specify what types they contain.  The 1992 ASN.1 standard has
+rectified this by adding much stronger typing semantics and eliminating
+macros.
+
+The ANY DEFINED BY type can be handled automatically by {\em snacc} if
+the SNMP OBJECT-TYPE \cite{snmp} macro is used to specify the
+identifier value to type mappings.  The identifier can be an INTEGER
+or OBJECT IDENTIFIER\@.  Handling ANY types properly will require
+modifications to the generated code since there is no identifier
+associated with the type.
+
+The general approach used by {\em snacc} to handle ANY DEFINED BY
+types is to lookup the identifier value in a hash table for the
+identified type.  The hash table entry contains information about the
+type such as the routines to use for encoding and decoding.
+
+Two hash tables are used, one for INTEGER to type mappings and the
+other for OBJECT IDENTIFIER to type mappings.  {\em Snacc} generates
+an {\tt InitAny} routine for each module that uses the OBJECT-TYPE
+macro.  This routine adds entries to the hash table(s).  The {\tt
+InitAny} routine(s) is called once before any encoding or decoding is
+done.
+
+
+The hash tables are constructed such that an INTEGER or OBJECT
+IDENTIFIER value will hash to an entry that contains:
+\begin{itemize}
+\item {the {\tt anyId}}
+\item {the INTEGER or OBJECT IDENTIFIER that maps to it}
+\item {the size in bytes of the identified data type}
+\item {a pointer to the type's PDU encode routine}
+\item {a pointer to the type's PDU decode routine}
+\item {a pointer to the type's print routine}
+\item {a pointer to the type's free routine}
+\end{itemize}
+The referenced encode and decode routines are PDU oriented in that
+they encode the type's tag(s) and length(s) as well as the type's
+content.
+
+{\em Snacc} builds an {\tt enum} called {\tt AnyId} that enumerates
+each mapping defined by the OBJECT-TYPE macros.  The name of the value
+associated with each macro is used as part of the enumerated
+identifier.  The {\tt anyId} in the hash table holds the identified
+type's {\tt AnyId enum} value.  The {\tt anyId} is handy for making
+decisions based on the received identifier, without comparing OBJECT
+IDENTIFIERs.  If the identifiers are INTEGERs then the {\tt anyId} is
+less useful.
+
+With ANY DEFINED BY types, it is important to have the identifier
+decoded before the ANY DEFINED BY type is decoded.  Hence, an ANY
+DEFINED BY type should not be declared before its identifier in a SET
+since SETs are un-ordered. An ANY DEFINED BY type should not be
+declared after its identifier in a SEQUENCE\@. {\em Snacc} will print a
+warning if either of these situations occur.
+
+The hash tables may be useful to plain ANY types which do not have an
+identifier field like the ANY DEFINED BY types; the OBJECT-TYPE macro
+can be used to define the mappings and the {\tt SetAnyTypeByInt} or
+{\tt SetAnyTypeByOid} routine can be called with the appropriate
+identifier value before encoding or decoding an ANY value.  The
+compiler will insert calls to these routines where necessary with some
+of the arguments left as ``???''.  There will usually be a ``{\tt /*
+ANY -- Fix me! */}'' comment before code that needs to be modified to
+correctly handle the ANY type.  The code generated from an ASN.1
+module that uses the ANY type will not compile without modifications.
+
+OPTIONAL ANYs and ANY DEFINED BY types that have not been tagged are a
+special problem for {\em snacc}.  Unless they are the last element of a SET
+or SEQUENCE, the generated code will need to be modified.  {\em Snacc} will
+print a warning message when it encounters one of these cases.
+
+To illustrate how ANY DEFINED BY values are handled, we present
+typical encoding and decoding scenarios. Each ANY or ANY DEFINED BY
+type is represented in C by the {\tt AsnAny} type which contains only
+a {\tt void *} named {\tt value} to hold a pointer to the value and a
+{\tt AnyInfo *} named {\tt ai} which points to a hash table entry.
+
+When encoding, before the ANY DEFINED BY value is encoded, {\tt
+SetAnyTypeByOid} or {\tt SetAnyTypeByInt} (depending on the type of
+the identifier) is called with the current identifier value to set the
+{\tt AsnAny} value's {\tt ai} pointer to the proper hash table entry.
+Then to encode the ANY DEFINED BY value, the encode routine pointed to
+from the hash table entry is called with the {\tt value} {\tt void *}
+from the {\tt AsnAny} value.  The {\tt value} {\tt void *} in the {\tt
+AsnAny} should point to a value of the correct type for the given
+identifier, if the user set it up correctly.  Note that setting the
+{\tt void *} value is not type safe; one must make sure that the
+value's type is the same as indicated by the identifier.
+
+For decoding, the identifier must be decoded prior to the ANY DEFINED
+BY value otherwise the identifier will contain an uninitialized value.
+Before the ANY or ANY DEFINED BY value is decoded, {\tt
+SetAnyTypeByOid} or {\tt SetAnyTypeByInt} (depending on the type of
+the identifier) is called to set the {\tt AsnAny} value's {\tt ai}
+pointer to the proper hash table entry.  Then a block of memory of the
+size indicated in the hash table entry is allocated, and its pointer
+stored in the {\tt AsnAny} value's {\tt void *} entry.  Then the decode
+routine pointed to from the hash table entry is called with the newly
+allocated block as its value pointer parameter.  The decode routine
+fills in the value assuming it is of the correct type. Simple!
+
+There is a problem with {\em snacc}'s method for handling ANY DEFINED
+BY types for specifications that have two or more ANY DEFINED BY types
+that share some identifier values.  Since only two hash tables are
+used and they are referenced using the identifier value as a key,
+duplicate identifiers will cause unresolvable hash collisions.
+
+Here is some of the {\C AsnAny} related code from the header file.  It
+should help you understand the way things are done a bit better.  Look
+in the {\ufn hash.c} and {\ufn hash.h} files as well.
+\begin{small}
+\begin{verbatim}
+/*
+ * 1 hash table for integer keys
+ * 1 hash table for oid keys
+ */
+extern Table *anyOidHashTblG;
+extern Table *anyIntHashTblG;
+
+typedef (*EncodeFcn) (BUF_TYPE b, void *value);
+typedef void (*DecodeFcn) (BUF_TYPE b, void *value,
+                           AsnLen *bytesDecoded, ENV_TYPE env);
+typedef void (*FreeFcn) (void *v);
+typedef void (*PrintFcn) (FILE *f, void *v);
+
+/*
+ * this is put into the hash table with the
+ * int or oid as the key
+ */
+typedef struct AnyInfo
+{
+  int          anyId;  /* will be a value from the AnyId enum */
+  AsnOid       oid;    /* will be zero len/null if intId is valid */
+  AsnInt       intId;
+  unsigned int size;  /* size of the C data type (ie as ret'd by sizeof) */
+  EncodeFcn    Encode;
+  DecodeFcn    Decode;
+  FreeFcn      Free;
+  PrintFcn     Print;
+} AnyInfo;
+
+typedef struct AsnAny
+{
+    AnyInfo   *ai; /* point to entry in hash tbl that has routine ptrs */
+    void      *value; /* points to the value */
+} AsnAny;
+
+/*
+ * Returns anyId value for the given ANY type.
+ * Use this to determine to the type of an ANY after decoding
+ * it. Returns -1 if the ANY info is not available
+ */
+#define GetAsnAnyId( a)  (((a)->ai)? (a)->ai->anyId: -1)
+
+/*
+ * used before encoding or decoding a type so the proper
+ * encode or decode routine is used.
+ */
+void SetAnyTypeByInt (AsnAny *v, AsnInt id);
+void SetAnyTypeByOid (AsnAny *v, AsnOid *id);
+
+
+/*
+ * used to initialize the hash table(s)
+ */
+void InstallAnyByInt (int anyId,  AsnInt intId,
+                     unsigned int size, EncodeFcn encode,
+                     DecodeFcn decode, FreeFcn free, PrintFcn print);
+
+void InstallAnyByOid (int anyId, AsnOid *oid, unsigned int size,
+                     EncodeFcn encode, DecodeFcn decode, FreeFcn free,
+                     PrintFcn print);
+
+/*
+ * Standard enc, dec, free, & print routines.
+ * for the AsnAny type.
+ * These call the routines referenced from the
+ * given value's hash table entry.
+ */
+void FreeAsnAny (AsnAny *v);
+AsnLen BEncAsnAny (BUF_TYPE b, AsnAny *v);
+void BerDecAsnAny (BUF_TYPE b, AsnAny  *result, AsnLen *bytesDecoded,
+                  ENV_TYPE env);
+void PrintAsnAny (FILE *f, AsnAny *v, unsigned short indent);
+
+
+/* AnyDefinedBy is the same as AsnAny */
+typedef AsnAny                 AsnAnyDefinedBy;
+#define FreeAsnAnyDefinedBy    FreeAsnAny
+#define BEncAsnAnyDefinedBy    BEncAsnAny
+#define BDecAsnAnyDefinedBy    BDecAsnAny
+#define PrintAsnAnyDefinedBy   PrintAsnAny
+\end{verbatim}
+\end{small}
+
+
+\section{\label{lib-buf-section}Buffer Management}
+
+Encoding and decoding performance is heavily affected by the cost of
+writing to and reading from buffers, thus, efficient buffer management
+is necessary.  Flexibility is also important to allow integration of
+the generated encoders and decoders into existing environments.  To
+provide both of these features, the calls to the buffer routines are
+actually macros that can be configured as you want (see
+{\ufn \dots/c-lib/inc/asn-config.h}). Virtually all buffer calls will
+be made from the encode/decode library routines.  So macros used in
+the generated code will make buffer calls.
+
+If your environment uses a single, simple buffer type, the buffer
+routine macros can be defined as the macros for your simple buffer type.
+This results in the buffer type being bound at compile time, with no
+function call overhead from the encode or decode routines.  This also
+means that the runtime library only works for that buffer type.
+
+If multiple buffer formats must be supported at runtime, the buffer
+macros can be defined like the ISODE buffer calls, where a buffer type
+contains pointers to the buffer routines and data of the current
+buffer type.  This approach will hurt performance since each buffer
+operation will be an indirect function call.  I have implemented
+buffers like this for the table tools (performace is already hosed so
+slower buffer routines are a drop in the bucket).  See the type tables
+section for their description.
+
+The backwards encoding technique requires special buffer primitives
+that write from the end of the buffer towards the front.  This
+requirement will make it impossible to define buffer primitives that
+write directly to stream oriented objects such as TCP connections.  In
+cases such as this, you must encode the entire PDU before sending it.
+(Or else extend the back-end of the compiler to produce ``forwards''
+encoders as well).
+
+Nine buffer primitives are required by the runtime library's encode
+and decode routines:
+\begin{itemize}
+\item {\C unsigned char BufGetByte (BUF\_TYPE b);}
+\item {\C unsigned char BufPeekByte (BUF\_TYPE b);}
+\item {\C char *BufGetSeg (BUF\_TYPE b, unsigned long int *lenPtr);}
+\item {\C void BufCopy (char *dst, BUF\_TYPE b, unsigned long int *lenPtr);}
+\item {\C void BufSkip (BUF\_TYPE b, unsigned long int len);}
+\item {\C void BufPutByteRv (BUF\_TYPE b,  unsigned char byte);}
+\item {\C void BufPutSegRv (BUF\_TYPE b, char *data, unsigned long int len);}
+\item {\C int BufReadError (BUF\_TYPE b);}
+\item {\C int BufWriteError (BUF\_TYPE b);}
+\end{itemize}
+
+These buffer operations are described in the next subsections.  The
+{\C ExpBuf}, {\C SBuf} and {\C MinBuf} buffer formats that come
+with the Snacc distribution and how to configure the buffer operations
+are discussed following that.
+
+\subsection{\label{buf-read-c-section}Buffer Reading Routine Semantics}
+
+The buffer reading routines are called by the decoder routines.  The
+following is the list of necessary buffer reading routines and their
+semantics.   Be sure to setup the buffer in reading mode before
+calling any of these routines.  The means of putting a buffer in
+reading mode depends on the buffer type.
+
+\begin{verbatim}
+unsigned char BufGetByte (BUF_TYPE b);
+\end{verbatim}
+Returns the next byte from the buffer and advances the current pointer
+such that a subsequent buffer read returns the following byte(s).
+This will set the read error flag if an attempt to read past the end
+of the data is made.
+
+\begin{verbatim}
+unsigned char BufPeekByte (BUF_TYPE b);
+\end{verbatim}
+Returns the next byte from the buffer without advancing the current
+pointer.
+
+\begin{verbatim}
+char *BufGetSeg (BUF_TYPE b, unsigned long int *lenPtr);
+\end{verbatim}
+Returns a pointer to the next bytes from the buffer and advances the
+current pointer. {\C *lenPtr} should contain the number of bytes to
+read.  If the buffer has a least {\C *lenPtr} contiguous bytes
+remaining to be read before calling {\C BufGetSeg}, a pointer to
+them will be returned and {\C *lenPtr} will be unchanged.  If there
+are less than {\C *lenPtr} contiguous bytes remaining in the buffer
+before the call to {\C BufGetSeg}, a pointer to them is returned and
+{\C *lenPtr} is set to the actual number of bytes that are
+referenced by the returned pointer.  The current pointer will be
+advanced by the value returned in {\C *lenPtr} (this may advance to the
+next buffer segment if any).  Note that the read error flag is not set
+if  {\C *lenPtr} is greater than the remaining number of unread
+bytes.
+
+\begin{verbatim}
+unsigned long int BufCopy (char *dst, BUF_TYPE b, unsigned long int len)
+\end{verbatim}
+Copies the next {\C len} bytes from the buffer into the {\C dst char~*}
+and advances the current pointer appropriately.  Returns the
+number of bytes actually copied.  The number of bytes copied will be
+less than requested only if the end of data is reached, in which case
+the read error flag is set.
+
+
+\begin{verbatim}
+void BufSkip (BUF_TYPE b, unsigned long int len);
+\end{verbatim}
+Advances the buffer's current pointer by {\C len} bytes.  This will set the
+read error flag if less than {\C len} unread bytes remain in the
+buffer before the call to {\C BufSkip}.
+
+\begin{verbatim}
+int BufReadError (BUF_TYPE b);
+\end{verbatim}
+Returns non-zero if a read error occurred for the given buffer.
+Read errors occur if one of the buffer reading routines attempted to
+read past the end of the buffer's data.
+
+\subsection{\label{buf-write-c-section}Buffer Writing Routine Semantics}
+
+Encoding routines call the buffer writing routines.  Here is a list of
+the buffer writing routine and their semantics.  Before calling the
+writing routines, you should make sure the buffer is setup for
+writing in reverse mode.  The means of doing this depends on the
+buffer type.
+
+\begin{verbatim}
+void BufPutByteRvs (BUF_TYPE b, unsigned char byte);
+\end{verbatim}
+Writes the given byte to the beginning of the data in the given
+buffer.  The newly written byte becomes part of the buffer's data such
+that subsequent writes place bytes before the newly written byte.  If
+a buffer write error occurs, subsequent writes do nothing.
+
+\begin{verbatim}
+void BufPutSegRvs (BUF_TYPE b, char *data, unsigned long int len);
+\end{verbatim}
+Prepends the given bytes, {\C data}, of length {\C len} to the
+beginning of the data in the given buffer {\C b}.  The {\C data}
+bytes are written such that the first byte in {\C data} becomes the
+first byte of the buffer's data, followed by the rest. (This means the
+bytes in {\C data} are not reversed, they are simply prepended as a
+unit to the buffer's original data). If a buffer write error occurs,
+subsequent writes do nothing.
+
+\begin{verbatim}
+int BufWriteError (BUF_TYPE b);
+\end{verbatim}
+Returns non-zero if a write error occurred for the given buffer.
+Write errors occur if the buffer runs out of space for data or cannot
+allocate another data block (depends on the buffer type).
+
+\subsection{Buffer Configuration}
+
+The runtime library's encode and decode routines as well as the
+generated code access the buffers via the nine buffer macros
+described in the last two sections.  These macros can be defined to
+call simple macros for speed or to call functions.  Note that the
+buffer configuration is bound at the time the library and generated
+code are compiled.
+
+The following is from {\ufn \dots/include/asn-config.h} and shows how to
+configure the buffer routines.  This setup will make all calls to
+{\C BufGetByte} in the library and  generated code call your
+{\C ExpBufGetByte} routine; the other buffer routines are mapped to
+their {\C ExpBuf} equivalents in a similar way.
+
+\begin{verbatim}
+#include "exp-buf.h"
+#define BUF_TYPE			ExpBuf **
+#define BufGetByte( b)			ExpBufGetByte (b)
+#define BufGetSeg( b, lenPtr)		ExpBufGetSeg (b, lenPtr)
+#define BufCopy( dst, b, lenPtr)	ExpBufCopy (dst, b, lenPtr)
+#define BufSkip( b, len)		ExpBufSkip (b, len)
+#define BufPeekByte( b)			ExpBufPeekByte (b)
+#define BufPutByteRv( b,  byte)		ExpBufPutByteRv (b, byte)
+#define BufPutSegRv( b, data, len)	ExpBufPutSegRv (b, data, len)
+#define BufReadError( b)		ExpBufReadError (b)
+#define BufWriteError( b)		ExpBufWriteError (b)
+\end{verbatim}
+
+If you want to use your own buffer type, simply edit the
+{\ufn asn-config.h} file such that it includes your buffer's header
+file, sets the {\C BUF\_TYPE} type, and defines the nine buffer
+routines ({\C BufGetByte} etc.) to call your buffer routines.  Your
+buffer routines should have the semantics and prototypes described in
+the last two sections (Sections \ref{buf-read-c-section} and~\ref{buf-write-c-section}).
+
+\subsection{ExpBuf Buffers}
+
+The {\C ExpBuf} buffers are a doubly linked series of buffers that
+can be expanded when encoding by adding new buffers as necessary.
+Each {\C ExpBuf} consists of two blocks of memory, one for the
+control and linking information and the other for the data; when
+refering to an {\C ExpBuf} both parts are included. {\C ExpBuf} is
+short for ``Expanding Buffer''.  Look in {\ufn \dots/c-lib/exp-buf.c}
+for an ASCII drawing of the {\C ExpBuf} buffers. Take a look a the
+{\ufn \dots/c-examples/simple/expbuf-ex.c} file for a quick
+introduction on how to use {\C ExpBufs}.
+
+{\C ExpBufs} are fairly general and useful when a reasonable upper
+bound can not be put on the size of the encoded values that will be
+encountered by the protocol.  The flexibility of these buffer routines
+will hurt the performance as many of the {\C ExpBuf} calls are not
+macros and new buffers may need to be allocated during encoding.
+
+For encoding you need to write into the {\C ExpBufs}. Start with a
+single ExpBuf (or the last one in a list of ExpBufs from a previous
+encoding).  Make sure this ExpBuf has been reset is ``Write Reverse''
+mode (use {\C ExpBufResetInWriteRvsMode}).  This clears the write
+error flag (and sets the read error flag in case you try a read) and
+resets the data start and data end pointers such that the buffer is
+empty and ready for writing from the end towards the front.
+
+During encoding, if an {\C ExpBuf}'s data part fills up, a new
+{\C ExpBuf} before (since writing is reversed) the current buffer is
+needed.  If the {\C prev} pointer in the current buffer is non-NULL,
+the previous buffer is reset for writing and becomes the current
+buffer.  If the {\C prev} pointer in the current buffer si NULL, a new
+buffer is allocated, its pointer is placed in {\C prev} and it
+becomes the current buffer.  The notion of current buffer is handled
+by the parameter to the encoding and decoding routines.  The buffer
+parameter is an {\C ExpBuf~**} and it always holds the current
+{\C ExpBuf~*} (current buffer).
+
+When encoding is finished and the encoded value has been transmitted,
+you have two options.   You can free the entire buffer list or you can
+keep them around and re-use them for the next encoding.  Freeing the
+buffers after each encoding may be quite slow.  If you re-use the
+buffers, the buffer list will grow to the size of the largest encoding
+and stay there.  You can easily implement other management schemes.
+By default the {\C ExpBuf}s (both parts) are allocated and freed with
+{\C malloc} and {\C free}; you may want to change this to fit your
+environment better. If buffer allocation fails during a write, the
+writeError flag will be set and subsequent writes will do nothing.
+
+For decoding you will want to put the encoded data into the
+{\C ExpBuf} format.   For example, if your encoded value is
+contiguous in a single block of memory, you could use
+{\C ExpBufInstallDataInBuf} to attach your data to a single ExpBuf.
+Once your data is in the ExpBuf format, you should call
+{\C ExpBufResetInReadMode} on the first buffer in the list (if more
+than one).  Then you can pass it to the desired decode routine.
+
+If a decode routine attempts to read past the end of a buffer (usually
+due to an erroneous encoding), the readError flag will be set for the
+current {\C ExpBuf} in the list.  This error will typically cause
+the decoding routine that called the buffer read routine to call
+{\C longjmp}.
+
+The {\C BUF\_TYPE} is defined as {\C ExpBuf~**} so that the buffer
+parameter {\C b} can be set to the next active {\C ExpBuf} by the
+buffer routines.  This saves having a head of the list type structure
+that keeps track of the first, last and current buffers (the
+indirectness of this approach would hurt performance).
+
+There are many routines for administrating the {\C ExpBufs} if you
+want to treat them like an abstract data type.  Sometimes it may be
+easier to skip the utility routines and modify the fields directly.
+
+The following routines are the required nine buffer routines.  Compile
+the library and the generated code with the {\C USE\_EXP\_BUF} symbol
+defined to map buffer routines that the generated and library code
+calls to the {\C ExpBuf} routines (see
+{\ufn \dots/c-lib/inc/asn-config.h}). These {\C ExpBuf} routines
+adhere to the buffer routine prototypes and semantics defined in
+Sections \ref{buf-read-c-section} and~\ref{buf-write-c-section}.
+
+\begin{verbatim}
+void          ExpBufSkip (ExpBuf **, unsigned long len);
+int           ExpBufCopy (char *dst, ExpBuf **b, unsigned long len);
+unsigned char ExpBufPeekByte (ExpBuf **b);
+char         *ExpBufGetSeg (ExpBuf **b, unsigned long *len);
+void          ExpBufPutSegRvs (ExpBuf **b, char *data, unsigned long len);
+unsigned char ExpBufGetByte (ExpBuf **b);
+void          ExpBufPutByteRvs (ExpBuf **b, unsigned char byte);
+
+#define ExpBufReadError( b)   ((*b)->readError)
+#define ExpBufWriteError( b)  ((*b)->writeError)
+\end{verbatim}
+
+
+The following {\C ExpBuf} routines are also provided.  Their
+descriptions can be found in the code.
+\begin{verbatim}
+void ExpBufInit (unsigned long dataBlkSize);
+void ExpBufInstallDataInBuf (ExpBuf *b, char *data, unsigned long int len);
+
+void ExpBufResetInReadMode (ExpBuf *b);
+void ExpBufResetInWriteRvsMode (ExpBuf *b);
+
+ExpBuf *ExpBufAllocBufAndData();
+void ExpBufFreeBufAndData (ExpBuf *b);
+void ExpBufFreeBufAndDataList (ExpBuf *b);
+
+ExpBuf *ExpBufNext (ExpBuf *b);
+ExpBuf *ExpBufPrev (ExpBuf *b);
+ExpBuf *ExpBufListLastBuf (ExpBuf *b);
+ExpBuf *ExpBufListFirstBuf (ExpBuf *b);
+
+int ExpBufAtEod (ExpBuf *b);
+int ExpBufFull (ExpBuf *b);
+int ExpBufHasNoData (ExpBuf *b);
+
+char *ExpBufDataPtr (ExpBuf *b);
+unsigned long ExpBufDataSize (ExpBuf *b);
+unsigned long ExpBufDataBlkSize (ExpBuf *b);
+\end{verbatim}
+
+\subsection{SBuf Buffers}
+
+The {\C SBuf}s are simple buffers of a fixed size, much like an
+{\C ExpBuf} that cannot expand.  If you attempt to write
+past the end of the buffer, the writeError flag will be set and the
+encoding will fail.  If you attempt to read past the end of a buffer
+the readError flag will be set and the decoding will fail.
+
+The {\C SBuf}s are useful if you can put a reasonable upper bound on
+the size of the encodings you will be dealing with.  The buffer
+operations are much simpler because the data is contiguous.  In fact,
+all of the {\C SBuf} buffer operations are implemented by macros.
+
+Look in {\ufn \dots/c-examples/simple/sbuf-ex.c} for a quick
+introduction to using {\C SBuf}s in your code. The following
+operations are defined for the {\C SBuf} buffers.
+\begin{verbatim}
+/* The nine required buffer operations */
+#define SBufSkip(b, skipLen) ...
+#define SBufCopy(dst, b, copyLen) ...
+#define SBufPeekByte(b) ...
+#define SBufGetSeg( b, lenPtr) ...
+#define SBufPutSegRvs(b, seg, segLen) ...
+#define SBufGetByte(b) ...
+#define SBufPutByteRvs(b, byte) ...
+#define SBufReadError(b) ...
+#define SBufWriteError(b) ...
+
+/* other useful buffer operations */
+#define SBufInit(b, data, dataLen) ...
+#define SBufResetInReadMode(b) ...
+#define SBufResetInWriteRvsMode(b) ...
+#define SBufInstallData(b, data, dataLen) ...
+#define SBufDataLen(b) ...
+#define SBufDataPtr(b) ...
+#define SBufBlkLen(b) ...
+#define SBufBlkPtr(b) ...
+#define SBufEod(b) ...
+\end{verbatim}
+
+Snacc is configured to use {\C SBuf}s by default.  The symbols that
+will affect the buffer configuration during compilation of the
+libraries and generated code are {\C USE\_EXP\_BUF} and
+{\C USE\_MIN\_BUF}.
+
+\subsection{MinBuf Buffers}
+
+The {\C MinBuf}s provide maximum performance but should only be used under
+restricted conditions (to avoid segmentation faults etc.).  No checks are
+made to determine whether a decoder is reading past the end of the
+buffer or if an encoder is writing ``past'' the beginning of the data
+block (remember, snacc encoders write backwards).
+
+A {\C MinBuf} is just a {\C char~**}; the referenced {\C char~*} points
+to the next byte to be read or the last byte that was written. The
+read routine advances the {\C char~*} and the write reverse routines
+move the {\C char~*} backwards.
+
+When you start encoding, the {\C MinBuf} {\C char~**} should be a
+pointer to a pointer to the byte AFTER the last valid byte in your
+buffer. For example the following C fragment would work:
+\begin{verbatim}
+PersonnelRecord pr;
+char blk[128];
+char *minBuf;
+
+minBuf = blk + 128; /* start writing a end of block */
+BEncPersonnelRecord (&minBuf, pr);
+\end{verbatim}
+
+The {\C MinBuf}s should only be used during encoding if the size of
+the {\C MinBuf}'s buffer is guaranteed to be large enough to hold
+the encoded value. Otherwise, the encoder will blindly continue
+writing into whatever lies after the {\C MinBuf}'s buffer.
+
+When you start decoding, the {\C MinBuf} value should be a pointer
+to a pointer to the first byte of the BER value to be decoded.  Look
+in {\ufn \dots/c-examples/simple/minbuf-ex.c} for a real example.
+
+The {\C MinBuf}s should only be used for decoding when the value
+being decoded is certain to contain no encoding errors. Otherwise, for
+encodings that are incomplete or contain length errors, the decoder may
+attempt to read the memory that follows the {\C MinBuf}s. If you are
+lucky, the decoder will return an error with the {\C longjmp}
+mechanism. If your system has memory protection and you are unlucky
+this may abort your program.  If you are really unlucky, the data
+following the {\C MinBuf} may fool the decoder into thinking that it
+is valid and you receive a wrong PDU with no error indication.  This
+risky technique has been used successfully in some systems where the
+encodings are not guaranteed to be correct.
+
+To configure the generated code to use the {\C MinBuf}s, compile it
+with the {\C USE\_MIN\_BUF} symbol defined.
+
+\subsection{Hybrid Buffer Solutions}
+
+The decoding routines only call the buffer reading routines and the
+encoding routines only call the buffer writing routines.  You may wish
+to choose a different buffer format for the encoding and decoding to
+gain performance.  For instance, if you can be sure that the size of
+outgoing encodings is less than a certain upper bound, but don't want
+to risk segmentation faults when decoding incoming values, you could
+use {\C MinBuf}s for the the buffer writing (encoding) operations
+and {\C SBuf}s or {\C ExpBuf}s for the buffer reading (decoding)
+operations.
+
+In this case you will need to massage the generated code to achieve
+the desired results.
+
+\section{\label{lib-mem-C-section}Dynamic Memory Management}
+
+Like buffer management, efficient memory management is very important
+for efficient decoders.  As a decoder decodes a value, it allocates
+memory to hold the internal representation of the value.
+
+The runtime librarys and the generated decode routines allocate memory
+using the\linebreak {\C Asn1Alloc} routine. The runtime librarys
+and the generated free routines free memory using the {\C Asn1Free}
+routine.  The decoding routines also use {\C CheckAsn1Alloc} to make
+sure that each allocation succeeded.  These memory routines are defined
+in the
+{\ufn asn-config.h} and have the prototypes:
+\begin{verbatim}
+void *Asn1Alloc (unsigned long int size);
+void  Asn1Free (void *ptr);
+int   CheckAsn1Alloc (void *ptr, ENV_TYPE env);
+\end{verbatim}
+
+The decoders assume that {\C Asn1Alloc} returns a \emph{zeroed} block
+of memory.  This saves explicit initialization of OPTIONAL elements with
+NULL in the generated decoders.  It wouldn't be too hard to modify the
+compiler to produce decoders that initialized OPTIONAL elements
+explicitly.
+
+The generated free routines hierarchically free all a value's
+memory using a depth first algorithm.  If you use the Nibble Memory
+scheme, you will not need the generated free routines.
+
+By default, snacc uses a ``Nibble Memory'' scheme to provide efficient
+memory management.  Nibble Memory works by allocating a large block of
+memory for allocating from.  When the decoded value has been
+processed, you can free the entire value by calling a routine that
+simply resets a few pointers.  There is no need to traverse the entire
+value freeing a piece at a time.  The following is from
+{\ufn nibble-alloc.h}.
+\begin{verbatim}
+void InitNibbleMem (unsigned long int initialSize,
+                   unsigned long int incrementSize);
+void *NibbleAlloc (unsigned long int size);
+void ResetNibbleMem();
+void ShutdownNibbleMem();
+\end{verbatim}
+
+You must explicitly initialize the Nibble Memory with the
+{\C InitNibbleMem} routine before using a decoder.  You must specify
+the initial size of the nibble block and the size that it should grow
+by.  If you attempt to allocate a block that is larger that the
+initial nibble block or its grow size, a new block of the correct size
+will be allocated.  Note that the ``growth'' occurs by linking
+separate blocks, not by the potentially slow alternative,
+{\C realloc}.
+
+When you have processed the decoded value you can free it by calling
+{\C ResetNibbleMem}.  This resets a couple pointers and frees any
+extra blocks that were allocated to handle values larger than the
+initial block size.  The original memory block is zeroed
+using {\C memset} so that all allocations will return zeroed values.
+This is necessary to support the implicit initialization of OPTIONAL
+elements to NULL\@.  The zeroing is done in this routine instead of
+{\C NibbleAlloc} under the assumption that zeroing one large block
+is more efficient than zeroing pieces of it as they are allocated.
+
+When you no longer need the Nibble Memory, you can release it by
+using\linebreak {\C ShutDownNibbleMem}.  This frees all of the
+memory associated with Nibble Memory, both the control data and the
+block(s) used for allocation.
+
+There are some problems with this memory management scheme.  Currently
+the Nibble Memory control information is kept track of via a global
+variable that holds a pointer to the control information.  This can
+present a problem if separate Nibble Memory contexts are needed, for
+example, one to hold one value that will be kept after decoding and
+another to hold a decoded value that will soon be discarded.
+
+The problem of separate contexts could be solved by adding another
+layer that would use identifiers for different memory contexts.  This
+would require you to set the context using its identifier before
+calling a decoding routine and to pass the context identifier to the
+{\C ResetNibbleMem} routine.
+
+Another problem has to do with building the values to be encoded.
+There is no restriction on what allocator you use to build internal
+values.  However, it is convenient to use the {\C AsnListNew}
+routine to allocate and initialize a list type.  Unfortunately,
+{\C AsnListNew} is used by the decoding routines so it uses the
+{\C Asn1Alloc} routine to allocate the new list.  You should be
+aware of this if {\C Asn1Alloc} is not what you are using to
+allocate the rest of the value. This could be fixed with a different
+interface to the {\C AsnListNew} routine.
+
+It is possible to change the memory management system without too much
+difficulty.  For example if you are not too worried about performance
+and want to use {\C malloc} and {\C free}, you could change the
+{\ufn asn-config.h} file as follows:
+\begin{verbatim}
+#include "malloc.h"
+#define Asn1Alloc( size)  calloc (1, size)
+#define Asn1Free( ptr)    free (ptr)
+#define CheckAsn1Alloc( ptr, env)\
+   if ((ptr) == NULL)\
+      longjmp (env, -27);
+\end{verbatim}
+If you use {\C malloc} based allocators such as {\C calloc}, you
+must use the generated free routines to free your values.  Note that
+this example used {\C calloc} instead of {\C malloc} because
+{\C calloc} {\em zeroes} each allocated block of memory, as required
+by the decoders.
+
+
+\section{\label{lib-err-C-section}Error Management}
+
+The decoding routines use {\C longjmp} to handle any errors they
+encounter in the value being decoded.  {\C longjmp} works by rolling
+back the stack to where the {\C setjmp} call was made.  Every decode
+routine takes a {\C jmp\_buf env} parameter (initialized by the
+{\C setjmp} call) that tells the {\C longjmp} routine how to
+restore the processor to the correct state.  {\C longjmp} makes the
+error management much simpler since the decoding routines do not have
+to pass back error codes or check ones from other decoding routines.
+
+Before a PDU can be decoded, the {\C jmp\_buf env} parameter to the
+decoding routine must be initialized using the {\C setjmp} routine.
+This should be done immediately and only once before calling the
+decoding routine.  This parameter will be passed down to any other
+decoding routines called within a decoding routine. The following code
+fragment from {\ufn \dots/c-examples/simple/exbuf-ex.c} shows how to
+use {\C setjmp} before decoding.
+
+\begin{small}
+\begin{verbatim}
+if ((val = setjmp (env)) == 0)
+   BDecPersonnelRecord (&buf, &pr, &decodedLen, env);
+else
+{
+    decodeErr = TRUE;
+    fprintf (stderr, "ERROR - Decode routines returned %d\n", val);
+}
+\end{verbatim}
+\end{small}
+
+The code that will signal an error typically looks like:
+\begin{small}
+\begin{verbatim}
+if (mandatoryElmtCount1 != 2)
+{
+    Asn1Error ("BDecChildInformationContent: ERROR - non-optional elmt missing from SET.\n");
+    longjmp (env, -108);
+}
+\end{verbatim}
+\end{small}
+
+
+Most {\C longjmp} calls are preceded by a call to {\C Asn1Error}
+which takes a single {\C char~*} string as a parameter.  The library
+routines and the generated code try to use meaningful messages as the
+parameter. {\C Asn1Error} is defined in {\ufn \dots/c-lib/inc/asn-config.h} and
+currently just prints the given string to {\C stderr}.  You may wish
+to make it do nothing, which may shrink the size of your binary
+because all of the error strings will be gone.  {\C Asn1Warning} is
+similar but is not used by the library or generated code anymore.
+
+The encoding routines do no error checking except for buffer
+overflows.  Hence, they do not use the {\C longjmp} mechanism and
+instead require you to check the status of the buffer after encoding
+(use {\C BufWriteError()}).  If you are not building your values
+properly, for example having random pointers for uninitialized
+OPTIONAL elements, the encode routines will fail, possibly
+catastrophically.
diff --git a/SecuritySNACCRuntime/doc/coding.tex b/SecuritySNACCRuntime/doc/coding.tex
new file mode 100644
index 00000000..c7df41c1
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/coding.tex
@@ -0,0 +1,105 @@
+% file: .../doc/coding.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/coding.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: coding.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:52  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:48  rj
+% first check-in
+%
+
+\chapter{\label{coding-tricks}Coding Tricks For Readability}
+
+\index{ANSI C}
+\index{K&R C}
+\index{PROTO}
+\index{PARAM}
+\index{COMMA}
+
+One of our project partners needed some additional function arguments and so they duplicated the function declarator and put a preprocessor switch around it.
+The metacode and the Tcl interface added some additional compilation conditions.
+Since the Tcl interface is only useful on top of the metacode, there are six different combinations instead of eight.
+Even these six combinations would have made the code very ugly.
+Please decide for yourself, here is an example with an example function with only up to four arguments, {\C PrintCxxCode()} has up to 17 arguments.
+
+\begin{Ccode}
+static void\\
+\#if A\\
+FunctionName PARAMS ((a, b),\\
+  \>TypeA a \_AND\_\\
+  \>TypeB b)\\
+\#if B\\
+FunctionName PARAMS ((a, b, c),\\
+  \>TypeA a \_AND\_\\
+  \>TypeB b \_AND\_\\
+  \>TypeC c)\\
+\#if C\\
+FunctionName PARAMS ((a, b, c, d),\\
+  \>TypeA a \_AND\_\\
+  \>TypeB b \_AND\_\\
+  \>TypeC c \_AND\_\\
+  \>TypeD d)\\
+\#endif\\
+\#endif\\
+\#else\\
+FunctionName PARAMS ((b),\\
+  \>TypeB b)\\
+\#if B\\
+FunctionName PARAMS ((b, c),\\
+  \>TypeB b \_AND\_\\
+  \>TypeC c)\\
+\#if C\\
+FunctionName PARAMS ((b, c, d),\\
+  \>TypeB b \_AND\_\\
+  \>TypeC c \_AND\_\\
+  \>TypeD d)\\
+\#endif\\
+\#endif\\
+\#endif
+\end{Ccode}
+
+Here is the code after introduction of my shorthand:
+
+\begin{Ccode}
+static void\\
+FunctionName PARAMS ((if\_A (a COMMA) b if\_C (COMMA c) if\_D (COMMA d)),\\
+  \>if\_A (TypeA a \_AND\_)\\
+  \>TypeB b\\
+  \>if\_C (\_AND\_ TypeC c)\\
+  \>if\_D (\_AND\_ TypeD d))
+\end{Ccode}
+
+The tricks are very simple.
+One is the {\C if\_\dots} macro
+
+\begin{Ccode}
+\#if A\\
+\#define if\_A( code)			\>\>\>code\\
+\#else\\
+\#define if\_A( code)
+\#endif
+\end{Ccode}
+
+that lets us get rid of at least four lines of code for every invocation, and the other trick is the {\C COMMA} macro
+
+\begin{Ccode}
+\#define COMMA \>\>\>,
+\end{Ccode}
+
+that makes the arguments to the {\C if\_\dots{}} macros look like a single argument.
+Without this trick, 
+
+The other trick, of course is the {\C if\_\dots{}} macro itself.
+The {\C if\_\dots{}} macros have to expand into code without brackets, for example {\C if\_A (a COMMA b)} exands into {\C a, b}.
+The {\C COMMA} is not my invention, snacc's {\C \_AND\_} macro is exactly the same.
+Both {\C \_AND\_} and {\C COMMA} serve the purpose of being a comma (``,'') as the final result (well, only for ANSI C, for K\&R C, the {\C \_AND\_} becomes a semicolon), but without being an argument separator to the C preprocessor.
+The {\C PROTO} macro that was already present in snacc 1.1 gets a single argument as well, but by means of additional parenthesis, inside which commas can savely be used.
+It expands into code with brackets around it: {\C PROTO ((int a, char~*b))} expands into {\C (int a, char~*b)}.
+The first argument to the {\C PARAM} macro is bracketed list as well, and for the arguments purpose, to be a function argument list, this is fine.
+
+To have both an ANSI C and a K\&R C version, without {\C PROTO}, {\C PARAMS} and supporting macros, twelve conditional code compilations would have to be written out instead of one!
+And what a tedious job to maintain all twelve versions!
diff --git a/SecuritySNACCRuntime/doc/corba.bib b/SecuritySNACCRuntime/doc/corba.bib
new file mode 100644
index 00000000..42d2105a
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/corba.bib
@@ -0,0 +1,35 @@
+% file: .../doc/corba.bib
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/corba.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: corba.bib,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:52  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:51  rj
+% first check-in
+%
+
+@techreport{corba,
+  institution = "OMG",
+  author = "OMG",
+  title = "The Common Object Request Broker: Architecture and Specification",
+  year = "1993",
+  version = "1.2",
+}
+
+@techreport{idl-c++,
+  institution = "OMG",
+  author = "OMG",
+  title = "OMG RFP Submission--IDL C++ Language Mapping Specification",
+  year = "1994",
+}
+
+@techreport{gdmo-idl,
+  institution = "X/Open",
+  author = "X/Open",
+  title = "GDMO to OMG IDL Specification Translation Algorithm",
+  year = "1994",
+}
diff --git a/SecuritySNACCRuntime/doc/design.tex b/SecuritySNACCRuntime/doc/design.tex
new file mode 100644
index 00000000..d99bf92a
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/design.tex
@@ -0,0 +1,761 @@
+% file: .../doc/design.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/design.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: design.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:52  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:31  rj
+% first check-in
+%
+
+\chapter{\label{comp-des-chapter}Compiler Design}
+
+\section{\label{comp-overview-section}Overview}
+The Snacc compiler is implemented with {\ufn yacc}, {\ufn lex}
+(actually GNU's equivalents, {\ufn bison} and {\ufn flex}) and
+\verb$C$.  Despite the shortcomings of {\ufn lex} and {\ufn yacc},
+they provide reasonable performance without too much programming
+effort.  Since {\ufn yacc} parsers are extremely difficult to modify
+during runtime, any macro that you want the compiler to handle must
+be hand coded into the ASN.1 {\ufn yacc} grammar
+({\ufn \dots/compiler/core/parse-asn1.y}) followed by recompilation of snacc.
+Macro definitions do not need special consideration since they are
+skipped by the compiler.  Macro definitions and complex value notation
+are kept as text in the data structure resulting from a parse if you
+want to try to parse and process them.
+
+To handle the anti-compiler nature of ASN.1's syntax, snacc makes
+several passes on parse tree data structure when compiling.  None of
+these passes creates temporary files; this allows snacc to process
+large ASN.1 specifications quite quickly.  Each compiler pass is
+explained in the next sections.  The main passes of the compiler are
+executed in the following order:
+
+\begin{enumerate}
+\item parse useful types ASN.1 module
+\item parse all user specified ASN.1 modules
+\item link local and imported type references in all modules
+\item parse values in all modules
+\item link local and imported value references in all modules
+\item process any macro types
+\item normalize types
+\item mark recursive types and signal any recursion related errors
+\item check for semantic errors in all modules
+\item generate C/C++ type information for each ASN.1 type
+\item Sort the types from least dependent to most dependent
+\item generate the C, C++, IDL or type table
+\end{enumerate}
+
+The source code for the compiler resides in {\ufn \dots/compiler/} and the
+back ends are in {\ufn \dots/compiler/back-ends/c-gen/}, {\ufn \dots/compiler/back-ends/c++-gen/} and {\ufn \dots/compiler/back-ends/idl-gen/}.
+
+\section{\label{comp-pass1-section}Pass 1: Parsing the Useful Types Module}
+The ASN.1 useful types are not hardwired into snacc.  Instead they
+have been placed in a separate ASN.1 module.  This allows the user to
+define his own useful types or re-define the existing ones without
+modifying snacc.  This also has the benefit that names of useful types
+are not keywords in the lexical analyzer.  This step is not really a
+compiler pass on the module data, however it is described as one for
+simplicity.
+
+The useful types module should be passed to snacc with the {\ufn -u}
+flag in front of it.  The {\ufn -u} flag tells snacc to treat the
+module in a special way.  Instead of parsing the module and generating
+code for it, snacc parses the module and makes the types in it
+accessible to all of the other modules being parsed.  Note that the
+other modules do not need to explicitly import from the useful types
+module.  See Section~\ref{comp-pass3-section} for more information on how
+useful types affect linking.
+
+The encode, decode, and other routines for the useful types are in the
+runtime library.  Currently, the useful types library routines are the
+same as the ones the compiler would normally generate given the useful
+types module.  However, since they are in the library, you can modify
+them to check character sets (string types), or convert local time
+formats into their BER equivalent (UTCTime, GeneralizedTime).
+
+The following types are in the useful types module:
+\begin{small}
+\begin{verbatim}
+ASN-USEFUL DEFINITIONS ::=
+BEGIN
+ObjectDescriptor ::= [UNIVERSAL 7]  IMPLICIT OCTET STRING
+NumericString    ::= [UNIVERSAL 18] IMPLICIT OCTET STRING
+PrintableString  ::= [UNIVERSAL 19] IMPLICIT OCTET STRING
+TeletexString    ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
+T61String        ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
+VideotexString   ::= [UNIVERSAL 21] IMPLICIT OCTET STRING
+IA5String        ::= [UNIVERSAL 22] IMPLICIT OCTET STRING
+GraphicString    ::= [UNIVERSAL 25] IMPLICIT OCTET STRING
+VisibleString    ::= [UNIVERSAL 26] IMPLICIT OCTET STRING
+ISO646String     ::= [UNIVERSAL 26] IMPLICIT OCTET STRING
+GeneralString    ::= [UNIVERSAL 27] IMPLICIT OCTET STRING
+UTCTime          ::= [UNIVERSAL 23] IMPLICIT OCTET STRING
+GeneralizedTime  ::= [UNIVERSAL 24] IMPLICIT OCTET STRING
+
+EXTERNAL         ::= [UNIVERSAL 8] IMPLICIT SEQUENCE
+{
+  direct-reference      OBJECT IDENTIFIER OPTIONAL,
+  indirect-reference    INTEGER OPTIONAL,
+  data-value-descriptor ObjectDescriptor OPTIONAL,
+  encoding CHOICE
+  {
+    single-ASN1-type [0] OCTET STRING,  -- should be ANY
+    octet-aligned    [1] IMPLICIT OCTET STRING,
+    arbitrary        [2] IMPLICIT BIT STRING
+  }
+}
+END
+\end{verbatim}
+\end{small}
+
+If you use the EXTERNAL type, you must provide the mechanism to encode
+and decode the value in the embedded CHOICE, \verb$encoding$.  The
+type and transfer syntax of the value in an EXTERNAL type is not known
+when the ASN.1 code is compiled by snacc.  Snacc cannot generate
+encoders and decoders without complete type information and only
+supports a single set of encoding rules, BER\@.
+
+\section{\label{comp-pass2-section}Pass 2: Parsing ASN.1 Modules}
+During this pass, all of the specified modules are parsed into the {\em
+Module} data structure.  The ASN.1 source files are not consulted
+again, after they are parsed.  {\ufn Yacc} and {\ufn lex} are doing the work in
+this step. (see files {\ufn snacc.c}, {\ufn lex-asn1.l}, {\ufn parse-asn1.y}
+and {\ufn asn1module.h}).
+
+A lexical tie-in is where the yacc parser puts the lexical analyzer
+into a different mode (and is usually considered a hack).  The
+different modes tokenize symbols differently, which is useful for
+skipping well delimited sections that cannot be parsed easily by a
+{\ufn yacc} parser on the first pass.  Lexical tie-ins are used in two
+places to simplify the ASN.1 grammar sufficiently for {\ufn yacc} and
+{\ufn lex}.  There are two special modes in the lexical analyzer, one
+for ASN.1 macro definitions and the other for ASN.1 values enclosed in
+\{\}'s.
+
+The lexical tie-in for eating macro definition bodies works with macro
+definitions of the following form:
+
+\begin{verbatim}
+<upper case identifier> MACRO ::= BEGIN ... END
+\end{verbatim}
+
+Everything between the {\ASN BEGIN} and {\ASN END} is stuffed into a
+string by {\ufn lex} and passed back as single token to the
+{\ufn yacc} parser.
+
+Values within \{\}'s are grabbed in a similar way.  Value parsing
+cannot really be done at this stage since complete type information is
+needed and the types are not fully parsed or linked yet.
+
+Most syntax errors are reported during this pass.  If syntax errors
+are encountered, snacc will report as many as it can from the
+offending module before the parser is hopelessly lost and then exit.
+If the types and values are separated with semi-colons, the parser can
+recover after a syntax error and attempt to find more errors in that
+module before exiting.
+
+
+\section{\label{comp-pass3-section}Pass 3: Linking Types}
+The third pass links all type references.  Snacc attempts to resolve
+any currently visible (i.\ e.\  not in macro definitions or constructed
+values) type reference.  This includes type references in simple value
+definitions and subtyping information.  The useful types module (if
+given) is linked first.
+
+Snacc will exit after this pass if any type references could not be
+resolved.  Error messages with file and line number information will
+be printed to {\C stderr}.
+
+This pass also counts and stores the number of times a type definition is
+referenced locally and from other modules.  This information is used
+during the type sorting pass.
+
+First, each module identifier is checked for conflicts with the
+others.  If the module identifier includes an OBJECT IDENTIFIER, snacc
+only checks for conflicts with the other module identifier OBJECT
+IDENTIFIERs.  When only a module name is provided, snacc checks for
+conflicts with the the other module names, even if the other module
+identifiers include OBJECT IDENTIFIERs.  If the OBJECT IDENTIFIER of
+a module identifier contains any value references, it will be ignored
+for module look-up purposes.  Note that value references within the
+module identifier OBJECT IDENTIFIERs are not allowed in the 1992
+version of ASN.1 due to the difficulty in module name resolution they
+present.
+
+Two modules with the same name but different OBJECT IDENTIFIERs are
+not considered an error within ASN.1.  However, because the generated
+files use the module name as part of their name, the code generation
+pass will gripe about and fail for modules with the same name.
+
+Next, each module's import {\em lists} are resolved by finding the
+named module and then verifying that the named module contains all of
+the imported types.
+
+Then for each module, each type reference (except those of the form
+{\em modulename.typename}) is assumed to be a local type reference and
+the linker attempts to find a local type definition of the same name
+to resolve it with.  If a matching local definition is found, the type
+reference is resolved and the linker continues with the next type
+reference.
+
+For each type reference of the form {\em modulename.typename}, the
+linker looks in the module with name {\em modulename} for the type
+{\em typename}.  If the type is found the reference is resolved,
+otherwise a linking error is reported.  Note that this form of type
+reference provides a special scope that does not conflict with other
+local or imported types in that module.
+
+For type references that failed to resolve locally and are not of the
+form {\em modulename.typename}, the linker looks in the import lists
+of the current type reference's module for a type to resolve with.  If
+the type is found in the import lists, the reference is resolved.
+
+For the remaining unresolved type references (failed local and legal
+import resolution and are not of the form {\em modulename.typename}),
+the linker looks in the useful types module, if one was specified with
+the {\ufn -u} option.  If the type is found in the useful types module
+then the reference is resolved, otherwise a linking error is reported.
+
+Note that when a useful types module is specified, it is globally
+available to all modules, but it has the lowest linking priority.
+That is, if a type reference can be resolved legally without the
+useful types module, it will be.
+
+Some type checking must be done in this pass to link certain types
+properly.  These include:
+\begin{itemize}
+\item {a SELECTION type must reference a field of a CHOICE type.}
+\item {a COMPONENTS OF type in a SET must reference a SET.}
+\item {a COMPONENTS OF type in a SEQUENCE must reference a SEQUENCE.}
+\end{itemize}
+
+
+
+\section{\label{comp-pass4-section}Pass 4: Parsing Values}
+The fourth pass attempts to parse any value that is enclosed in \{\}'s in
+the given modules.  INTEGERS, REALs and BOOLEANS that are not enclosed in
+braces are parsed in the first pass.
+
+The value parser is implemented without {\ufn yacc} and {\ufn lex} and
+uses each value's type information to help parse the value.  Values
+within \{\}'s hidden within types such as default values and parts of
+subtypes are not parsed.  Since subtypes and default values do not
+affect the generated code, upgrading the value parser in this respect
+is not very useful.
+
+The only type of value in \{\}'s that is parsed is the OBJECT
+IDENTIFIER\@.  All of the OBJECT IDENTIFIER value forms are supported
+but snacc loosens the restrictions on using arc names defined in the
+OBJECT IDENTIFIER tree.
+
+ASN.1 allows OBJECT IDENTIFIER values to reference special built-in
+arc names from the OBJECT IDENTIFIER tree defined in Annexes B, C and
+D of X.208.  For example the first arc in an OBJECT IDENTIFIER value
+can be either {\ASN ccitt} {\ASN iso} or {\ASN joint-iso-ccitt}.  The
+acceptable arc names are context dependent; for example the second arc
+can be one of {\ASN standard}, {\ASN registration-authority},
+{\ASN member-body} or {\ASN identified-organization} only if the first
+arc was {\ASN iso} or 1.
+
+Snacc uses a simplified algorithm to handle references to the arc
+names defined in the OBJECT IDENTIFIER tree.  Any arc value that is
+represented by a single identifier is checked to see if it is one of
+the arc names defined in the OBJECT IDENTIFIER tree; context is
+ignored.  If the identifier matches one of the arc names then its
+value is set accordingly.  The lack of context sensitivity in snacc's
+algorithm may cause the arc name to link with an arc name from the
+OBJECT IDENTIFIER tree when a local or imported INTEGER was desired.
+The following is the list special arc names that snacc understands and
+their values (see {\ufn \dots/compiler/core/oid.c}):
+
+\begin{itemize}
+\setlength{\itemsep}{0pt}
+\setlength{\parsep}{0pt}
+\nspace{0}
+\item {ccitt = 0}
+\item {iso = 1}
+\item {joint-iso-ccitt = 2}
+\item {standard = 0}
+\item {registration-authority = 1}
+\item {member-body = 2}
+\item {identified-organization = 3}
+\item {recommendation = 0}
+\item {question = 1}
+\item {administration = 2}
+\item {network-operator = 3}
+\end{itemize}
+
+\section{\label{comp-pass5-section}Pass 5: Linking Values}
+The fifth pass links value references. The value linker looks for
+value references to resolve in value definitions and type definitions,
+including default values and subtyping information.  The value linking
+algorithm is virtually identical to the type linking pass (see Section
+\ref{comp-pass3-section}).
+
+Currently the value parsing is limited to OBJECT IDENTIFIER values.
+Simple values that are not between \{\}'s are parsed in the first
+pass.  Here is an example that illustrates the OBJECT IDENTIFIER
+parsing and linking.  The following values:
+
+\begin{small}
+\begin{verbatim}
+foo OBJECT IDENTIFIER ::= { joint-iso-ccitt 2 88 28 }
+bar OBJECT IDENTIFIER ::= { foo 1 }
+bell INTEGER ::= 2
+gumby OBJECT IDENTIFIER ::= { foo bell }
+pokie OBJECT IDENTIFIER ::= { foo stimpy(3) }
+\end{verbatim}
+\end{small}
+
+\noindent
+are equivalent to this:
+
+\begin{small}
+\begin{verbatim}
+foo OBJECT IDENTIFIER ::= { 2 2 88 28 }
+bar OBJECT IDENTIFIER ::= { 2 2 88 28  1 }
+bell INTEGER ::= 2
+gumby OBJECT IDENTIFIER ::= { 2 2 88 28 2 }
+pokie OBJECT IDENTIFIER ::= { 2 2 88 28 3 }
+\end{verbatim}
+\end{small}
+
+Note that in version 1.0, named arcs (e.g. {\ASN stimpy(3)}) were
+promoted to full integer values.  This was wrong---many standards
+re-used them (e.g. X.500 and {\ASN ds(5)}) leading to multiply defined
+integer values.  If you want to improve the value parsing, look in
+{\ufn \dots/compiler/core/val-parser.c}
+
+\section{\label{comp-pass6-section}Pass 6: Processing Macros}
+
+The fifth pass processes macros.  For all macros currently handled,
+snacc converts type definitions inside the macro to type references
+and puts the type definition in the normal scope.  This way, the code
+generator does not have to know about macros to generate code for the
+types defined within them.
+
+The only macro that receives any special processing is the SNMP
+OBJECT-TYPE macro.  This macro's information defines an OBJECT
+IDENTIFIER or INTEGER to type mapping for use with any ANY DEFINED BY
+type.  Note that the OBJECT-TYPE macro has been extended beyond its
+SNMP definition to allow integer values for INTEGER to type mappings.
+
+ASN.1 allows you to define new macros within an ASN.1 module;  this
+can change the grammar of the ASN.1 language.  Since snacc is
+implemented with {\ufn yacc} and yacc grammars cannot be modified
+easily during runtime, snacc cannot change its parser in response to
+macro definitions it parses.
+
+Any macro that snacc can parse has been explicitly added to the yacc
+grammar before compiling snacc.  When a macro that snacc can parse is
+parsed, a data structure that holds the relevant information from the
+macro is added to the parse tree.  The type and value linking passes
+as well as the macro processing and possibly the normalization pass
+need to be modified to handle any new macros that you add.
+
+The following macros are parsed:
+
+\begin{itemize}
+%\begin{linespacing}{0.5}
+\setlength{\itemsep}{0pt}
+\setlength{\parsep}{0pt}
+\nspace{0}
+\item{ OPERATION (ROS) }
+\item{ ERROR (ROS) }
+\item{ BIND (ROS) }
+\item{ UNBIND (ROS) }
+\item{ APPLICATION-SERVICE-ELEMENT (ROS) }
+\item{ APPLICATION-CONTEXT }
+\item{ EXTENSION (MTSAS)}
+\item{ EXTENSIONS (MTSAS) }
+\item{ EXTENSION-ATTRIBUTE (MTSAS) }
+\item{ TOKEN (MTSAS) }
+\item{ TOKEN-DATA (MTSAS)}
+\item{ SECURITY-CATEGORY (MTSAS) }
+\item{ OBJECT (X.407) }
+\item{ PORT   (X.407) }
+\item{ REFINE (X.407)}
+\item{ ABSTRACT-BIND (X.407) }
+\item{ ABSTRACT-UNBIND (X.407) }
+\item{ ABSTRACT-OPERATION (X.407) }
+\item{ ABSTRACT-ERROR (X.407) }
+\item{ ALGORITHM (X.509)}
+\item{ ENCRYPTED (X.509)}
+\item{ PROTECTED (X.509)}
+\item{ SIGNATURE (X.509)}
+\item{ SIGNED    (X.509)}
+\item{ OBJECT-TYPE (SNMP) }
+%\end{linespacing}
+\end{itemize}
+
+However, no code is generated for these macros.  As stated above, only
+the OBJECT-TYPE macro affects the encoders and decoders.
+
+\section{\label{comp-pass7-section}Pass 7: Normalizing Types}
+The sixth pass normalizes the types to make code generation simpler.
+The following is done during normalization:
+\begin{itemize}
+
+\item[1.] { COMPONENTS OF types are replaced with the contents of the SET
+or SEQUENCE components that they reference.}
+
+\item[2.] { SELECTION types are replaced with the type they reference.}
+
+\item[3.] { SEQUENCE, SET, CHOICE, SET OF and SEQUENCE OF {\em definitions}
+embedded in other types are made into separate type definitions. }
+
+\item[4.] { For modules in which ``IMPLICIT TAGS'' is specified, tagged
+type references such as {\ASN [APPLICATION 2] Foo} are marked IMPLICIT
+if the referenced type ({\ASN FOO} in this case) is not an untagged
+CHOICE or untagged ANY type.}
+
+\item[5.] { INTEGERs with named numbers, BIT STRINGs with named bits and
+ENUMERATED types embedded in other types are made into separate type
+definitions.}
+\end{itemize}
+
+The COMPONENTS OF and SELECTION type simplifications are obvious but
+the motivation for the others may not be so obvious.  The third type of
+simplification makes type definitions only one level deep.  This
+simplifies the decoding routines since snacc uses local variables for
+expected lengths, running length totals and tags instead of stacks.
+
+The implicit references caused by ``IMPLICIT TAGS'' are marked
+directly on type references that need it.  This saves the code
+generators from worrying about whether implicit tagging is in effect
+and which types can be referenced implicitly.
+
+The types with named numbers or bits are made into a separate type to
+allow the C++ back end to simply make a class that inherits from the
+INTEGER or BIT STRING class and defines the named numbers or bits
+inside an enum in the new class.  This is described further in the C++
+code generation chapter.
+
+\section{\label{comp-pass8-section}Pass 8: Marking Recursive Types}
+
+
+This pass marks recursive types and checks for recursion related
+errors.  To determine whether a type definition is recursive, each
+type definition is traced to its leaves, checking for references to
+itself.  Both local and imported type references within a type are
+followed to reach the leaves of the type.  A leaf type is a simple
+(non-aggregate) built-in type such as an INTEGER or BOOLEAN\@. At the
+moment, recursion information is only used during the type dependency
+sorting pass.
+
+{\em Snacc} attempts to detect two types of recursion related errors.  The
+first type of error results from a recursive type that is composed
+solely of type references.  Types of this form contain no real type
+information and would result in zero-sized values.  For example the
+following recursive types will generate this type of warning:
+\begin{small}
+\begin{verbatim}
+A ::= B
+B ::= C
+C ::= A
+\end{verbatim}
+\end{small}
+
+The other recursion related error results from a type whose value will
+always be infinite in size.  This is caused by recursion with no
+optional component that can terminate the recursion.  If the recursion
+includes an OPTIONAL member of a SET or SEQUENCE, a CHOICE member, or
+a SET OF or SEQUENCE OF, the recursion can terminate.
+
+Both of the recursion errors generate warnings from snacc but will
+not stop code generation.
+
+
+\section{\label{comp-pass9-section}Pass 9: Semantic Error Checking}
+The ninth pass checks for semantic errors in the ASN.1 specification
+that have not been checked already. Both the type linking pass and the
+recursive type marking pass do some error checking as well. Snacc attempts
+to detect the following errors in this pass:
+
+\begin{itemize}
+\item { elements of CHOICE and SET types must have distinct tags.}
+
+\item { CHOICE, ANY, and ANY DEFINED BY types cannot be implicitly tagged. }
+
+\item { type and value names within the same scope must be unique. }
+
+\item { field names in a SET, SEQUENCE or CHOICE must be distinct.  If
+a CHOICE is a member of a SET, SEQUENCE or CHOICE and has no field name,
+then the embedded CHOICE's field names must be distinct from its
+parents to avoid ambiguity in value notation.}
+
+\item { an APPLICATION tag code can only be used once per module. }
+
+\item { each value in a named bit list (BIT STRINGs) or named number
+list (INTEGERs and ENUMERATED) must be unique within its list.}
+
+\item { each identifier in a named bit list or named number list must
+be unique within its list.}
+
+\item { the tags on a series of one or more consecutive OPTIONAL or DEFAULT
+SEQUENCE elements and the following element must be distinct. }
+
+\item { gives a warning if an ANY DEFINED BY type appears in a
+SEQUENCE before its identifier or in a SET\@.  These would allow encodings
+where the ANY DEFINED BY value was prior to its identifier in the
+encoded value; ANY DEFINED BY values are difficult to decode without
+knowing their identifier.}
+
+\end{itemize}
+
+Snacc does not attempt to detect the following errors due the
+limitations of the value parser.
+\begin{itemize}
+\item { SET and SEQUENCE values can be empty (\{\}) only if the SET or
+SEQUENCE type was defined as empty or all of its elements are marked
+as OPTIONAL or DEFAULT.}
+
+\item { each identifier in a BIT STRING value must from that BIT
+STRING's named bit list (this could be done in an improved value
+linker instead of this pass).}
+\end{itemize}
+
+
+\section{\label{comp-pass10-section}Pass 10: Generating C/C++ Type Information}
+
+This pass fills in the target language type information.  The process
+is different for the C and C++ back ends since the C++ ASN.1 model is
+different and it was developed later (more design flaws had been
+corrected for the C++ backend).
+
+For C and C++ there is an array that contains the type {\em definition}
+information for each built-in type.  For each built-in ASN.1 type, the
+C array holds:
+
+\begin{description}
+\item[typename] {the C {\C typedef} name for this type definition.}
+
+\item[isPdu]    {TRUE if this type definition is a PDU\@. This is set
+for types used in ANY and ANY DEFINED BY types and those indicated by
+the user via compiler directives.  Additional interfaces to the encode
+and decode routines are generated for PDU types.  The SNMP OBJECT-TYPE
+macro is the current means of indicating whether a type is used within
+an ANY or ANY DEFINED BY type.}
+
+\item[isPtrForTypeDef] { TRUE if other types defined solely by this type
+definition are defined as a pointer to this type.}
+
+\item[isPtrForTypeRef] { TRUE if type references to this type
+definition from a SET or SEQUENCE are by pointer.}
+
+\item[isPtrForOpt] { TRUE if OPTIONAL type references to this type
+definition from a SET or SEQUENCE are by pointer.}
+
+\item[isPtrInChoice] { TRUE if type references to this type
+definition from a CHOICE are by pointer.}
+
+\item[optTestRoutineName] { name of the routine to test whether an
+OPTIONAL element of this type in a SET or SEQUENCE is present.
+Usually just the name of a C macro that tests for NULL.}
+
+\item[printRoutineName] { name of this type definition's printing routine.}
+\item[encodeRoutineName]{ name of this type definition's encoding routine.}
+\item[decodeRoutineName]{ name of this type definition's decoding routine.}
+\item[freeRoutineName]  { name of this type definition's freeing routine.}
+\end{description}
+
+The C++ type definition array is similar to C's. It contains:
+
+\begin{description}
+\item[classname] { holds the C++ {\C class} name for this type definition.}
+\item[isPdu] { same as C isPdu except that is does not affect the code
+generation since the C++ back end includes the extra PDU encode and
+decode routines by default.}
+\item[isPtrForTypeDef] { same as C isPtrForTypeDef. }
+\item[isPtrForOpt] { same as C isPtrForOpt.}
+\item[isPtrInChoice] { same as C isPtrInChoice}
+\item[isPtrInSetAndSeq] { whether type references to this class
+from a SET or SEQUENCE are by pointer.}
+\item[isPtrInList] {whether type references to this class
+from a SET OF or SEQUENCE OF are by pointer.}
+\item[optTestRoutineName] { name of the routine to test whether an
+OPTIONAL element of this type in a SET or SEQUENCE is present.
+Usually is just name of a C macro that tests for NULL.}
+\end{description}
+
+The first step of this pass uses the type arrays to fill in the C or
+C++ type {\em definition} information for each module's ASN.1 type
+definitions.  This is done for the useful types module as well.
+
+The next step goes through each constructed type and fills in the type
+{\em reference} information for each reference to a built-in, user defined
+or useful type.  Much of the type reference information is taken from
+the referenced type's definition information.  The type reference
+information contains the following (for both C and C++):
+
+\begin{description}
+\item[fieldName] { field name for this type if it is referenced from
+a CHOICE, SET or SEQUENCE.}
+\item[typeName] { type name of the referenced type.}
+\item[isPtr] { whether this reference is by pointer.}
+\item[namedElmts] { named elements for INTEGER, ENUMERATED or BIT
+STRING types with their C names and values.}
+\item[choiceIdValue] { if this type reference is in a CHOICE, this
+holds the value of the CHOICE's choiceId that indicates the presence
+of this field.}
+\item[choiceIdSymbol] { if this type reference is in a CHOICE, this
+holds the C enum value symbol that has the choiceIdValue value.}
+\item[optTestRoutineName] { name of the routine or macro to test for
+the presence of this element if it is an OPTIONAL element of a SET or SEQUENCE.}
+\end{description}
+
+\section{\label{comp-pass11-section}Pass 11: Sorting Types}
+
+This pass sorts the type definitions within each module in order of
+dependence.  ASN.1 does not require the types to be defined before
+they are referenced but both C and C++ do.  Without this pass, the
+generated types/classes would probably not compile due to type
+dependency problems.  There is no attempt to order the modules;
+command line order is used for the module dependence.  If you have
+problems with mutually dependent modules, the simplest approach is to
+combine the dependent modules into a single ASN.1 module.
+
+Some compilers such as CASN1 \cite{CASN1} require the user to order
+the types within the ASN.1 modules.  This can be tedious and since
+snacc may generate new type definitions from nested aggregate type
+definitions in the normalization pass, the user does not have complete
+control over the order of every type definition.  (The user could use
+the {\ufn -P} option to get the normalized ASN.1 and then order it but
+that is painful as well.)
+
+Snacc attempts to sort the types from least dependent to most
+dependent using the following convoluted algorithm:
+
+First, separate the type definitions within a module into the groups:
+\begin{itemize}
+\item[1.] { type definitions that are defined directly from simple built-in
+types such as INTEGER.}
+
+\item[2.] { types such as SET, SEQUENCE, SET OF, SEQUENCE OF and CHOICE
+that contain no references to types defined in this module.  That, is
+they are defined from only simple built-in types, imported types or
+useful types.}
+
+\item[3.] { type definitions that reference locally defined types.}
+
+\item[4.] { type definitions that are not referenced by any local types.}
+\end{itemize}
+
+Only the 3rd group of type definitions needs more sorting.  After it
+has been sorted, the groups are merged in the order 1, 2, 3, 4 to
+yield a sorted type definition list.
+
+Now we describe how the 3rd group of type definitions is sorted.
+\begin{itemize}
+
+\item[1.] {for each type definition in the third group, a list of its local type
+references is built and attached to it.  This type reference list only
+goes one level deep; it does not follow type references to find more
+type references.}
+
+\item[2.] { all of the linearly-dependent types are removed and sorted.
+This is done by repeatedly removing type definitions that do not
+directly depend on any other type definitions that remain in the 3rd
+group.  The process of removing the type definitions sorts them.}
+
+\item[3.] { the type definitions that were not removed in step 2 are
+divided into two groups: recursive and non-recursive.  The
+non-recursive types depend on the recursive ones since they are still
+in the list after step 2.}
+
+\item[4.] { the non-recursive types from step 3 are sorted as in step
+2.  All of them should sort linearly since none are recursive. }
+
+\item[5.] { if the target language is C, any SET OF or SEQUENCE OF
+types are separated from the recursive type definitions built in step 3.
+This is done because the C representation of a list type is generic
+(uses a {\C void~*} to reference the list element) and therefore does
+not really depend on the list's element type.}
+
+\item[6] { the list of local type references for the recursive types
+from step 3 is re-generated as in step 1 using a relaxation:  types
+referenced as pointers are not added to a type's reference list.}
+
+\item[7] { the recursive types from step two are re-sorted as in step
+2 using their new local type reference lists. Two lists are formed,
+those that sorted linearly and those that did not. Hopefully the
+latter list will be empty.}
+\end{itemize}
+
+To form a sorted third group, the lists are merged in the following order:
+\begin{itemize}
+\item {linearly sorted types from step 2}
+\item {separated list types (C only) from step 5}
+\item {sorted recursive types from step 7}
+\item {unsorted recursive types from step 7 (hopefully empty)}
+\item {sorted non-recursive types from step 4}
+\end{itemize}
+
+
+In C, the code generator defines both {\C typedef} names and
+{\C struct} tags (names).  For example,
+\begin{verbatim}
+Foo ::= SET { a INTEGER, b BOOLEAN }
+
+Bar ::= SEQUENCE { a OBJECT IDENTIFIER, b Foo }
+\end{verbatim}
+translates to the following C data types:
+\begin{verbatim}
+typedef struct Foo /* SET */
+{
+    AsnInt a; /* INTEGER */
+    AsnBool b; /* BOOLEAN */
+} Foo;
+
+typedef struct Bar /* SEQUENCE */
+{
+    AsnOid a; /* OBJECT IDENTIFIER */
+    struct Foo *b; /* Foo */
+} Bar;
+\end{verbatim}
+
+Note that both the {\C struct} and the {\C typedef} have the name
+{\C Foo}.  Also note that the Bar type references the {\C Foo} via
+{\C struct Foo~*}.
+
+For types such as {\C Bar} that contain the {\C Foo} type,
+{\C Foo} is referenced as {\C struct Foo~*} instead of just
+{\C Foo~*} because C allows you to use the type {\C struct Foo~*}
+(incomplete type) in defining types even prior to the actual
+declaration of the the {\C struct Foo}. The {\C Foo~*} type can
+{\em only} be used after the {\C Foo typedef} declaration.  The use
+of incomplete types can often overcome recursion related type ordering
+problems (not relevant in this example since they are not recursive).
+
+\section{\label{comp-pass12-section}Pass 12: Generating Code}
+
+This pass creates and fills the source files with C or C++ code or
+produces a type table containing the type descriptions from all of the
+parsed modules, including the useful types module (if given).  The
+purpose of the normalization, sorting and error detection passes is to
+simplify this pass.
+
+The normalization pass simplified the ASN.1 types in various ways to
+make C/C++ type and code generation simpler.
+
+The type sorting pass hopefully eliminates type dependency problems in the
+generated code.  The C/C++ type generator simply proceeds through the
+ordered type list writing the C/C++ type definitions to a header file.
+
+The error detection and linking passes will make snacc exit if errors
+are found, so the code generation pass can assume the ASN.1 types are
+virtually error free.  This usually allows snacc to exit gracefully
+instead of crashing due to an undetected error.
+
+The type table data structure is similar to snacc's parse tree for the
+ASN.1 modules but it is much simpler.  This is because all of the type
+linking and error checking has been done.  The type definitions in the
+type tables are in defined by the type sorting pass (dependency).
+
+The next chapters describe the code that is generated by snacc and the
+libraries the generated code uses.
diff --git a/SecuritySNACCRuntime/doc/editor.tex b/SecuritySNACCRuntime/doc/editor.tex
new file mode 100644
index 00000000..f4514611
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/editor.tex
@@ -0,0 +1,462 @@
+% file: .../doc/editor.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/editor.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: editor.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:52  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:41  rj
+% first check-in
+%
+
+\chapter{\label{snacced-chapter}SnaccEd, the Snacc Editor}
+
+SnaccEd is a simple graphical editor for BER encoded files.
+A set of ASN.1 files describes one or more hierarchical datastructures that can be displayed as an n-ary non-circular graph, in other words: a tree.
+
+\begin{figure}[ht!]
+\begin{center}
+\includegraphics[scale=0.7]{example}
+\caption[SnaccEd: an example screen shot]{An example screen shot}
+\label{snacced-example}
+\end{center}
+\end{figure}
+
+SnaccEd is combined from
+\begin{itemize}
+  \item the usual Snacc BER encode and decode functions
+  \item the metacode (described in chapter~\ref{meta-chapter} starting on page~\pageref{meta-chapter})
+  \item the Tcl library
+  \item the Snacc Tcl interface (described in chapter~\ref{tcl-if-chapter} starting on page~\pageref{tcl-if-chapter})
+  \item the Tk widget set
+  \item a freeware tree widget (another Tcl extension, implemented in C++)
+  \item a Tcl script that glues all those parts together
+\end{itemize}
+
+All items except for the Tcl script are compiled into an executable, the \emph{snaccwish}.
+The Tk interpreter has the name {\ufn wish}, for ``windowing shell'', and consequently, I name the program that results from linking Snacc with Tk {\ufn snaccwish}.
+For every individual set of ASN.1 files, a different snaccwish has to be made, because every snaccwish contains the specialized encode and decode routines for the ASN.1 files' types.
+
+This {\ufn snaccwish} is a Tcl interpreter that has the additional commands of the Tk widget set, the tree widget and the Snacc interface built in.
+This interpreter reads the {\ufn snacced} script that implements the graphical Snacc editor.
+I will henceforth refer to the script as {\ufn snacced} and to the interpreter as {\ufn snaccwish}.
+You may name your script and the shell binary differently, just make sure that the script calls the correct binary!.
+
+Snacced can be called with various arguments, see the manual page for details.
+
+The {\ufn snacced} script is only the most visible entry point, other scripts will be read using Tcl's autoloading mechanism.
+
+The Tcl script is (or can be) always the same.
+It uses the {\Tcl snacc} command to learn about the ASN.1 modules, types and PDUs.
+
+Since the BER format has not got any magic number or similar concept, the Snacc routines in general cannot identify the ASN.1 type contained in a BER encoded string of octets.
+As a consequence, one has to choose not only the file name but the ASN.1 type as well when one opens or creates a file (see figure~\ref{selbox-pic} \sthisnextafter{selbox-pic} for an example).
+
+\begin{figure}[ht]
+\begin{center}
+\includegraphics[scale=0.7]{selbox}
+\caption{The file and content type selection box}
+\label{selbox-pic}
+\end{center}
+\end{figure}
+
+One can then examine and manipulate the file's structure and contents.
+
+\section{Manipulating the Display}
+
+This section describes the pointer\footnote{
+  My pointer device is a mouse, but yours may be a trackball, a tablet, a joystick or something else.
+} operations that change the amount of information to be shown.
+(To change the file's contents, the node's content window has got be opened.)
+
+The file is displayed by means of a tree widget.
+Only a part of the full hierarchy is shown.
+The subtree's root is at the left side.
+The function of the pointer buttons\footnote{
+  I will refer to the buttons but their number, not their position.
+  I could refer to button~1 as the right button, but this might confuse you as your button~1 may in fact be on the left hand side.
+} when clicking on \emph{node names} is as follows:
+\begin{description}
+  \item[button~1]
+    adds or deletes the node's subnodes to or from the display, respectively.
+    (Except for SET OF and SEQUENCE OF types, where with button 2 you have got to open the node content editor, a list widget, and have to toggle the display of individual elements by clicking on their index numbers. This is explained at the end of section~\ref{cont-ed-list-sect} \sthisnextafter{cont-ed-list-sect}.)
+    \begin{itemize}
+      \item For nodes that have subnodes being shown, the subtree gets hidden.
+      \item Otherwise, the node's immediate descendents are added to the display.
+    \end{itemize}
+  \item[button~2]
+    opens or closes the node, where ``closed'' means that only the nodes name is being shown, and ``open'' means that an additional window showing the node's contents it put under the node's name.
+    This content window is explained in the next section.
+  \item[button~3]
+    adds or deletes the node's parent to or from the display, respectively.
+    \begin{itemize}
+      \item For nodes where the parent is displayed, all parents and all siblings with their subtrees will get hidden.
+      \item Otherwise, the parent is added to the display.
+    \end{itemize}
+\end{description}
+
+Pressing and holding button 2 on a free space, the display can be dragged by moving the pointer.
+
+\section{The Content Window}
+
+\begin{figure}
+\begin{center}
+\includegraphics[scale=0.65]{simple}
+\caption{Content editors for ASN.1 simple types}
+\label{simple-content}
+\end{center}
+\end{figure}
+
+\begin{figure}
+\begin{center}
+\includegraphics[scale=0.7]{struct}
+\caption{Content editors for ASN.1 structured types}
+\label{struct-content}
+\end{center}
+\end{figure}
+
+\def\exref{ (based on the example displayed as figure~\ref{snacced-example} on page~\pageref{snacced-example})}
+
+\begin{figure}
+\begin{center}
+\includegraphics[scale=0.7]{str-popup}
+\caption[Popup for import/export of OCTET STRING contents]{Popup for import/export of OCTET STRING contents\exref}
+\label{str-popup}
+\end{center}
+\end{figure}
+
+\begin{figure}
+\begin{center}
+\includegraphics[scale=0.7]{list-popup}
+\caption[Popup for action selection for SET OF and SEQUENCE OF types]{Popup for action selection for SET OF and SEQUENCE OF types\exref}
+\label{list-popup}
+\end{center}
+\end{figure}
+
+The content window that may be opened beneath the node's name looks and behaves different for every content type.
+An example for every ASN.1 simple type is shown in figure~\ref{simple-content} \sthisnextafter{simple-content}.
+The ASN.1 input for the example can be found in appendix~\ref{edex0.asn1} on page~\pageref{edex0.asn1}.
+\begin{itemize}
+  \item
+    The NULL type has only one value that cannot be changed.
+  \item
+    Values of BOOLEAN type are displayed as a toggle button.
+  \item
+    For the ENUMERATED type, SnaccEd displays a list of radio buttons listing the values' names.
+    (The numerical values are not shown.)
+  \item
+    INTEGER values are displayed using an entry widget where the numeric value can be seen and changed.
+    The entry widget's binding have been changed to allow the input of ``--'' and decimal digits only in addition to the usual control functions (procedure {\Tcl int\_entry\_bindings}).
+    Similar to the ENUMERATED type, values can be given a name; the list is displayed as above.
+  \item
+    Individial names in a BIT STRING may be named.
+    SnaccEd displays a list of buttons identifying those bits along with their name.
+    Clicking on one of those buttons toggles the bit's value.
+    \newline
+    The bit string is displayed and can be edited in its binary representation in an entry widget below the names.
+    The entry widget's binding have been changed to allow the input of ``0'' and ``1'' only in addition to the usual control functions (procedure {\Tcl bit\_string\_entry\_bindings}).
+  \item
+    OCTET STRINGs and derived types are displayed in a text widget.
+    Since Tcl cannot handle strings containing NUL bytes, NUL bytes are displayed as the two character combination ``\char`\\0'' and backslashes are duplicated, ``\char`\\\char`\\''.
+    Button 3 pops up a small menu that allows you to load or save the octet string from or to an external file, respectively (figure~\ref{str-popup} \sthisnextafter{str-popup}).
+    The X text selection to copy text between the text widget and e.g. an xterm can be used as well.
+  \item
+    CHOICE types allow exactly one of their subtypes to be valid and therefore are displayed as a list of radio buttons.
+    Clicking on a button deletes the old choice and allocates the new one.
+    See the ``{\C color}'' in figure~\ref{struct-content} on page~\ref{struct-content}.
+  \item
+    The SET and SEQUENCE types' elements are displayed in a list of buttons, and optional elements may be added and deleted by clicking on their buttons.
+    Mandatory members do not respond to button clicks and are greyed out.
+    Examples: the list element \#1 right in the middle of figure~\ref{snacced-example} on page~\pageref{snacced-example} or the ``{\C rgb}'' in figure~\ref{struct-content} on page~\pageref{struct-content}.
+  \item \label{cont-ed-list-sect}
+    SnaccEd visualizes the types SET OF and SEQUENCE OF in a list widget.
+    The widget shows the elements' ordinal numbers, the elements themselves are shown in individual widgets to the right.
+    Button~3 in the list widget brings up a small menu where you can choose the action to perform when (with button 1) you click on a list element (figure~\ref{list-popup} \sthisnextafter{list-popup}):
+    \begin{itemize}
+      \item toggle the display of an element
+      \item insert a new element
+      \item append a new element
+      \item delete an element
+    \end{itemize}
+    The cursor shape changes and reminds you of your chosen action.
+    An example of a list widget is ``{\C files}'' in figure~\ref{snacced-example} on page~\pageref{snacced-example}.
+\end{itemize}
+Some content editors can be resized: move the pointer to the content editor's frame.
+Where the cursor shape changes to a ``bottom\_right\_corner'', press button~1 and drag the frame.
+
+\section{\label{editor-building}Building Your Own Editor}
+
+There isn't much to be done to get an editor that understands your BER encoded files.
+This chapter's example can be found in {\ufn \dots/tcl-example/}.
+
+\begin{itemize}
+  \item
+    Make sure your Snacc compiler has be configured to support the Tcl code.
+    This can be verified by calling {\ufn `snacc -h | grep tcl`}; if the output is empty, the configuration script was unable to find Tcl/Tk.
+  \item
+    The Tcl/Tk libraries must have been compiled with with gcc in order to use its {\C main()} function.
+    Otherwise, the constructors and destructors of static variables may not be called.
+    I have added some code at the end of {\ufn \dots/.../c++-lib/src/tcl-if.C} that checks for this condition.
+    \newline
+    Tcl's default is not to use gcc but cc where present, but you can compile Tcl/Tk by calling {\ufn env CC='gcc -traditional' ./configure} instead of {\ufn ./configure}.
+  \item
+    Install the tree widget.
+    SnaccEd works with tree-3.6.
+    (tree-3.6.2 requires another Tcl extension, itcl, but to avoid complicating matters any further, SnaccEd sticks to the simpler version.)
+    When {\ufn \dots/configure} found the tree widget libraries, the macro definition for {\Make TREELIBS} in {\ufn \dots/makehead} will have been set to {\ufn -ltktree -lOS}.
+  \item
+    In your makefile, extend {\ufn snacc}'s list of arguments with the {\ufn -tcl} option followed by the list of PDUs (that is an additional \emph{two} arguments).
+  \item
+    Put {\ufn modules.C} into the list of files to be compiled.
+  \item
+    Compile with {\ufn -DTCL}.
+  \item
+    To link, replace {\ufn -lasn1c++} against {\ufn -lasn1tcl} and add {\ufn \$(TREELIBS)} to the list of libraries.
+    (You may have to add a {\ufn -L} option as well.)
+  \item
+    Call {\ufn \$(TCL\_LIB)/make-snacced \$(SNACCED) \$(WISH) \$(TCL\_LIB)}, where {\ufn \$(TCL\_LIB)} is either {\ufn \$\{prefix\}/lib/snacc/tcl/} (the place where the Tcl library files got installed by {\ufn make install}) or {\ufn \dots/tcl-lib/} (in case you haven't called {\ufn make install} yet), and {\ufn \$(WISH)} is the name of the wish executable you just compiled.
+    The {\ufn make-snacced} script generates a small Tcl script, {\ufn \$(SNACCED)}, that executes your wish executable, extends the Tcl variable {\Tcl auto\_path} to include your {\ufn \$(TCL\_LIB)} und through the auto loading mechanism calls the Tcl library routine {\Tcl snacced} to start the Snacc editor.
+\end{itemize}
+
+Make sure you get the {\ufn \dots/tcl-example/} working before you despair of your own set of files.
+Take {\ufn \dots/tcl-example/makefile} as a guide.
+
+Your can use the {\ufn .h} and {\ufn .C} file resulting from calling {\ufn snacc -tcl \dots} for both the editor and your other uses.
+Just remember: if you compile with {\ufn -DTCL}, link against {\ufn libasn1tcl.a}; if you want to disable the metacode and tcl interface, compile with {\ufn -DMETA=0} and link against {\ufn libasn1c++.a}.
+
+Make sure that you don't link with your old {\C main()}\footnote{Or make sure your {\C main()} behaves similar to the Tk libraries'}.
+The generated file {\ufn modules.C} contains the line\\
+{\C static int (*dummy)(Tcl\_Interp~*) = Tcl\_AppInit;}\\
+that forces {\ufn libasn1tcl.a(tkAppInit.o)} to be linked.
+{\ufn \dots/c++-lib/src/tkAppInit.c} in turn contains the lines\\
+{\C extern int main();\\
+int *tclDummyMainPtr = (int *)main;}\\
+that force the {\C main} function in the Tk library to be linked.
+
+{\C Tcl\_AppInit()} calls {\C Snacc\_Init()} that is defined in {\ufn \dots/c++-lib/src/tcl-if.C}.
+{\C Snacc\_Init()} installs the {\Tcl snacc} command.
+
+\section{\label{snacced-impl}Implementation}
+
+The Tcl scripts that implement the editor can be found in {\ufn \dots/tcl-lib/} and, after installation, in {\ufn \$\{prefix\}/lib/snacc/tcl/}.
+
+You are free to change the Tcl script(s), for example to display some data types in a more appropiate manner.
+Octet strings may be user readable but often are not, pictures and audio data come to mind.
+
+If add procedures or {\ufn .tcl} files, you have got to rebuild Tcl's autoloading index.
+This best done by adding the files to the {\Make TCLFILES.dist} list in {\ufn \dots/tcl-lib/makefile} and running {\ufn make} again.
+
+%!!! nicht in doc/:
+The first SnaccEd was able to handle only one file at a time.
+To enable the editor to handle several files simultaneously required the following steps:
+\begin{itemize}
+  \item instead of using the default toplevel widget {\Tcl .} (dot), open a toplevel widget for every file.
+    The toplevel widgets get names {\Tcl .file0}, {\Tcl .file1}, \dots
+    The same name without the leading dot is used as a global array variable to hold miscellaneous pieces of information about the file.
+    You can see how the names are generated in the code example on page~\pageref{tcl-name-space-example-code}.
+    The name of this variable is given to many procedures in the {\Tcl fileref} parameter.
+  \item identify global variables. Those were
+    \begin{itemize}
+      \item the name of the file handle
+      \item the names of some widgets, namely the toplevel, the menubar, the canvas and the tree widget.
+    \end{itemize}
+    Other global variables can be left untouched: the help text, the list of PDU types.
+    This information is the same for all the files a snaccwish can handle.
+\end{itemize}
+
+Since the file and type selection box, the help text and the dialog boxes are modal, only one instance is needed and they can have the same names for every file opened by the editor.
+
+The editor displays only a portion of the ASN.1 file.
+The Snacc editor keeps the displayed portions of the ASN.1 file in two similar data structures.
+
+The contents of an ASN.1 file is accessed by calling the {\Tcl snacc} command with a {\Tcl \emph{path}} that identifies the requested data portion.
+
+Every ASN.1 file is displayed using one toplevel widget.
+This toplevel widget is a frame for a number of subwidgets:
+\begin{itemize}
+  \item a menubar
+  \item a canvas
+  \item two scrollbars, one vertical, one horizontal, to select the visible part of a canvas that has grown too large for the frame.
+\end{itemize}
+
+The menubar contains two buttons, one for the usual file related commands, and a help button.
+
+The canvas is the main arena.
+Its subwidgets are the tree widget and all the canvas items that make up the nodes and edges.
+The tree widget computes the positions of the canvas items and moves them in place.
+
+The contents of an ASN.1 file can be seen as a tree (the data structure may by recursive using CHOICE types or OPTIONAL components, and a PDU may contain instances of a type that contain other instances of the same type (see figure~\ref{recursion} on page~\pageref{recursion} for an example), but as ASN.1 has no pointers, cycles are impossible).
+To display this tree, it is mirrored in a number of Tcl data structures:
+\begin{itemize}
+  \item
+    The \emph{snaccpath} is the 1:1 representation of the PDU's structure.
+    This is what in chapter~\ref{tcl-if-chapter} is always referred to as ``\emph{path}'' argument to most {\Tcl snacc} subcommands.
+    The snaccpath is a proper Tcl list.
+  \item
+    The \emph{treepath} is very similar to the snaccpath.
+    Its structure is the same as the snaccpath's, but its syntax and a few elements are different:
+    \begin{itemize}
+      \item
+	The components in a snaccpath are separated by ``~'' (space), in a treepath they are separated by ``/'' (slash).
+	This difference is not strictly necessary, but it helps to detect errors in argument passing as the {\Tcl snacc} commands will never accept any treepath for their path arguments.
+      \item
+	In a snaccpath, the elements of SET OF and SEQUENCE OF types are identified by their index.
+	In a treepath, another numeric id is used instead.
+	The reason for this becomes clear when we have a look at where the treepath is used and what would have to be done if the elements' list indices were used in the treepaths.
+
+	The treepath is used in a number of places, for widget and variable names and for canvas item tags, all detailed in the below bulleted items.
+
+	When an element of a SET OF or SEQUENCE OF type is deleted, the snaccpath's indices for the deleted element's successors have to be decremented to point to the same item; when an element is inserted, those indices need to be incremented.
+	As a consequence, the widget and variable names and the canvas item tags of all elements that follow the one element that has been deleted or inserted would have to be adjusted and all the names and tags of their descendants.
+	Even if these names and tags could easily be changed (they cannot), it would still be an enormous amount of work and the slow Tcl interpreter could need some seconds to complete this task.
+	This enormous labour can be avoided by introducing a table lookup:
+
+	Every node of a SET OF or SEQUENCE OF type gets an idlist (identifier list).
+	This idlist is a Tcl list, its length is the same as there are elements in the ASN.1 data object.
+	Every idlist element corresponds to an element of the data object.
+	Whenever an element is deleted from the data object, the corresponding id from the idlist is removed as well; insertions are likewise performed in both the data object and the idlist.
+	The idlist contains numbers, zero for data objects that are not visually displayed on the canvas and locally unique non-zero numbers otherwise.
+
+	When a data object is identified through its treepath, the id is extracted and the id's position is sought in the idlist.
+	The id's position in the idlist is the element's index for the snaccpath.
+    \end{itemize}
+
+    The treepath is used to build the names of widgets that display a PDU's structure and content portions.
+  \item
+    The node labels and lines for the edges are canvas items, no full fledged widgets.
+    Canvas items can be given tags for identification purposes; the tags of an item are an ordered Tcl list.
+    Canvas items have a locally unique id, but as different items can have the same tag, item groups can be identified.
+
+    Since all tags form an ordered Tcl list, individual items can be addressed:\\
+    {\Tcl [lindex [\$canvas gettags \$id] \$index]}\\
+    SnaccEd uses this mechanism to translate button clicks into paths: when a canvas item is clicked at, the canvas makes this item ``current'' and\\
+    {\Tcl [\$canvas find withtag current]}\\
+    returns the item's id.
+    The id is then used as described above to retrieve the tag list.
+
+    The canvas line items that are used as edges get no tags.
+
+    The canvas text items that make up the node labels and the canvas window items that contain the content editors get three tags.
+    The three tags are ordered from most general to most specific:
+    \begin{enumerate}\setcounter{enumi}{-1}%
+      \item
+	For node labels this tag has the form \emph{validity}-label.
+	The validity is either ``valid'' or ``void''.
+	Absent OPTIONAL components are ``void''.
+	Active node labels get the tag ``valid-label''.
+	In the procedure {\Tcl new\_file} this tag is used to bind the three pointer button events to the callback procedures {\Tcl prune\_or\_add\_children}, {\Tcl toggle\_editor} and {\Tcl set\_or\_add\_root}, respectively.
+
+	For content editors this tag is simply ``edit'', because content editors can only be opened for valid nodes and therefore the validity would be redundant.
+      \item
+	This tag is the treepath.
+	It is the same for all canvas items for this node: the label and possibly the content editor.
+	This is the tag that is given to the tree widget.
+	The tree widget handles all canvas items with the same tag as a group: it uses their bounding box to calculate the tree layout and it keeps the relative distances of the group's items so that their internal layout persists any change in the tree's layout.
+      \item
+	This tag is a combination of the other two tags: it is the treepath, a colon and either ``label'' or ``edit''.
+	This tag is the most specific and it is used to address the individual canvas item, for example to check for a content editors existence.
+	No two items have the same value of this tag.
+    \end{enumerate}
+  \item
+    Content editors are not simple canvas items.
+    They are build from one or more widgets and this widget tree is put into a canvas window item.
+    The widgets have names of the form {\Tcl \$canvas.edit\$treepath}.
+    The leading \$canvas is the name of the canvas widget.
+    Widget names starting with that name are descendants of the canvas, here they are children.
+    The trailing \$treepath does not contain any dots and therefore Tk understands edit\$treepath as a single node in the widget tree.
+  \item
+    Most of the content editors modify a global variable, for example the entry widgets for INTEGER types or the radiobuttons for ENUMERATED types.
+    The variable's name is the simple composition {\Tcl var:\$treepath} that guarantees its uniqueness.
+
+    SET and SEQUENCE types need a variable for each of their components: the component's name gets tacked to the end which yields {\Tcl var:\$treepath:\$name}.
+
+    Named bits of BIT STRING types get similar variables, the bit value is put after the second colon.
+    The bits' toggle buttons operate on these variables.
+\end{itemize}
+
+\begin{figure}
+\begin{center}
+\includegraphics[scale=.6]{recur}
+\caption{`Recursive' data structures}
+\label{recursion}
+\end{center}
+\end{figure}
+
+When button~2 is clicked on a node label, the procedure {\Tcl toggle\_editor} gets called:
+\begin{itemize}
+  \item
+    checks whether the editor for the current node already exists.
+
+    If it does, the editor is deleted.
+
+    Otherwise, the editor is opened by creating a frame widget that is filled with an appropiate set of subwidgets.
+    The editor is supplied with the corresponding content portion from the ASN.1 file and a number of event bindings is installed that let the user modify the contents.
+    The frame is placed at the right place below the node name and the tree widget is called to adjust the layout.
+    Most of the changes to nodes containing simple ASN.1 types are detected using Tcl's trace mechanism.
+    For example, the entry widget for an INTEGER modifies a global variable.
+    The trace procedure that gets called upon every modification computes the snaccpath from the variable's name and modifies the ASN.1 file accordingly.
+    The only ASN.1 simple type that makes an exception to the rule is OCTET STRING.
+    Text widgets do not modify global variables and even if they did, copying the string back to the Snacc object for every key stroke is a waste of CPU time.
+    The text widget's contents is written back to the octet string when the widget receives a leave window event or, since Tk uses explicit focus (click-to-focus instead of focus-follows-pointer) and thus the widget's contents may be changed even after the pointer has left the window, it receives a focus out event.
+
+    The structured ASN.1 types are modified explicitly, i.e. through button clicks.
+    The components are modified using their natural GUI counterparts.
+    \begin{itemize}
+      \item OPTIONAL members of SET and SEQUENCE types are allocated and deallcated by clicking on a checkbutton.
+      \item CHOICE members are selected by clicking on a radiobutton.
+      \item SET OF and SEQUENCE OF types are implemented as list and SnaccEd displays them using a list widget.
+	(This is not actually true.
+	Since the listbox widget allows only single selection or selection of multiple but contiguous entries, I replaced it with a text widget and with some event bindings and a tag for the selected items made it behave like a listbox widget with multiple selection.
+	A patch to the Tk~3.6 code that implements non-contiguous selections exists, but I didn't want to enforce the trouble of getting, patching and installing the Tk library again on anyone.)
+    \end{itemize}
+\end{itemize}
+
+set\_or\_add\_root:
+
+When button~3 has been clicked on a node label, the callback procedure {\Tcl set\_or\_add\_root} will be called.
+
+\begin{itemize}
+  \item
+    The procedure checks whether the node that has been clicked at is the file's toplevel node.
+    In this case nothing can be done because there is no parent that could be shown or hidden.
+  \item
+    Otherwise, the routine checks whether the clicked node is currently displayed as the subtree's root.
+    In this case both the node's parent and grand parent are calculated.
+    The grand parent is not displayed, it merely corresponds to the tree widgets invisible root.
+    The parent is displayed by adding the node to the invisible grand parent.
+    The old root node and its siblings are aded by calling the {\Tcl ed\_expand} procedure.
+    {\Tcl ed\_expand} in turn calls {\Tcl ed\_addnode} for all the parent's children.
+    {\Tcl ed\_addnode} checks whether the node is already present on the canvas.
+    For the old root node this check yields true and the routine simply moves the node and all its descendants to below the new root node.
+    All other nodes are created as usually done when clicking on button~1.
+  \item
+    Otherwise, the node that has been clicked is to be shown as root.
+    This is simple: just tell the tree widget to display the node as root.
+    The tree widget removes everything else that does not belong to the subtree and calls the remove callback procedures for all these items.
+    The remove callback procedure is installed when a content editor is opened and is used to destroy the content editor frame widget and its subwidgets.
+\end{itemize}
+
+selbox:
+
+The file-and-content-type-selection-box (short: selbox) serves different purposes.
+The selbox contains three parts: a file name selection, a content type selection and a button row.
+One of the two selection parts can be disabled (it will not even been shown).
+In figure~\ref{selbox-pic} on page~\pageref{selbox-pic} both parts are visible.
+
+Both selections are necessary if a user wants to open a file.
+The user is the only one to know which of the PDU types is contained in the file.
+
+Only the file selection is necessary to implement the usual ``Save As\dots'' functionality where the content type is already known.
+
+Only the content type selection is needed when the program wants the user to create a new file without giving it an external file name.
+SnaccEd currently has no such function.
+Instead, if a user upon opening a file does not select a file name, an internal file without an external file name gets created.
+
+The selection box is implemented in the file {\ufn \dots/tcl-lib/selbox.tcl}.
+In this file, every procedure name starts with the prefix {\Tcl selbox\_} (except for the main entry point, {\Tcl selbox}).
+
+If the selbox was made non-modal, it would not break, because each individual selbox widget gets its own widget tree and all its status variables are put into a uniquely named array variable.
+The code that generates the names is similar to the example on page~\pageref{tcl-name-space-example-code}.
diff --git a/SecuritySNACCRuntime/doc/future-work.tex b/SecuritySNACCRuntime/doc/future-work.tex
new file mode 100644
index 00000000..e9cc707b
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/future-work.tex
@@ -0,0 +1,80 @@
+% file: .../doc/future-work.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/future-work.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: future-work.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:52  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:45  rj
+% first check-in
+%
+
+\chapter{\label{concl-chapter}Future Work}
+
+There are still many interesting and useful things that can be done to
+Snacc.  To name a few, Snacc could be improved to:
+\begin{itemize}
+  \item{support the new features of 1993 ASN.1}
+  \item{generate forward encoders that use only the indefinite length form for constructed BER values}
+  \item{support new encoding rules such as the variants of Packed Encoding Rules (PER),
+    Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER).}
+  \item{parse complex values.}
+\end{itemize}
+
+1993 ASN.1 has many improvements such as eliminating macros and adding
+stronger mechanisms for adding type semantics.  With stronger
+semantics, the compiler can do more for the user.
+
+New encoding rules such as PER offer improved compression and
+possibly better performance in certain cases.  They can be added to
+the compiler by adding a new backend to the compiler and providing a
+runtime library.
+
+The ability to parse complex ASN.1 value notation values is useful for
+protocol testing.  It allows PDUs to be defined in a human readable
+form and converted into their encoded representation.  The combination
+of an interpreted encoder and decoder with complex value parsing and
+support for newer encoding rules would very useful for protocol
+testing.
+
+
+Here is a list of the things that I didn't get time to do:
+
+\begin{enumerate}
+
+  \item {Add contexts to nibble memory.  It's a pain if you decode
+    a table and then a value---you can't free the value without freeing
+    the table.  This one should be relatively easy and only requires
+    modifications to the libraries and the example/user code.}
+
+  \item Spiff up the table stuff.
+    \begin{enumerate}
+      \item {add subtype info (available in big parse tree) to tbl data struct}
+      \item {add enumerated types name/value info to tbl data struct}
+      \item {Add ANY DEFINED BY id to type mappings to tbl data struct (available in parse tree if using OBJECT-TYPE macro)}
+      \item {Support for C++ table drivers.}
+      \item {I'm sure there's more}
+    \end{enumerate}
+
+  \item {existing bugs!}
+    \begin{enumerate}
+      \item {The hash stuff for ANY DEFINED BY mappings will bomb if you go more than 4 levels deep (unlikely, but\dots). Add linear chaining at the bottom level.}
+      \item {add the ability to handle CMIP style ANY DEFINED BY ids.  Currently snacc gripes about this and stops.}
+	\begin{verbatim}
+	   Eg ::= SEQUENCE { id Foo, ANY DEFINED BY id }
+	   Foo::= CHOICE { a OBJECT IDENTIFIER, b INTEGER }
+	\end{verbatim}
+    \end{enumerate}
+
+  \item {Bigger changes}
+    \begin{enumerate}
+      \item {punt yacc and lex and use PCCTS (Purdue Compiler Construction\dots) (better error reporting, easier to deal with (top down), etc.)}
+      \item {make an ASN.1 '93 version (no more macros!!!)}
+      \item {add PER.}
+      \item {make forwards encoders (use only indefinite lengths, though) for C, C++ and tables.  Allows simpler buffer writing.}
+    \end{enumerate}
+
+\end{enumerate}
diff --git a/SecuritySNACCRuntime/doc/idl-gen.tex b/SecuritySNACCRuntime/doc/idl-gen.tex
new file mode 100644
index 00000000..24713939
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/idl-gen.tex
@@ -0,0 +1,19 @@
+% file: .../doc/idl-gen.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/idl-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: idl-gen.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:52  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:42  rj
+% first check-in
+%
+
+\chapter{\label{idl-code-gen-chapter}IDL Code Generation}
+
+\section{\label{intro-IDL-section}Introduction}
+
+\emph{Under construction}
diff --git a/SecuritySNACCRuntime/doc/install-sh b/SecuritySNACCRuntime/doc/install-sh
new file mode 100644
index 00000000..ab74c882
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/SecuritySNACCRuntime/doc/intro-1.1.tex b/SecuritySNACCRuntime/doc/intro-1.1.tex
new file mode 100644
index 00000000..239ae41b
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/intro-1.1.tex
@@ -0,0 +1,407 @@
+% file: .../doc/intro-1.1.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/intro-1.1.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: intro-1.1.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:53  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:28  rj
+% first check-in
+%
+
+\chapter{\label{intro-1.1}Introduction to Snacc Release~1.1}
+
+Snacc compiles ASN.1 \cite{X.208} (Abstract Syntax Notation One)
+modules into C, C++ or type tables.  The generated C or C++ code
+contains equivalent data structures and routines to convert values
+between the internal (C or C++) representation and the corresponding
+BER \cite{X.209} (Basic Encoding Rules) format.  The name ``snacc'' is
+an acronym for ``Sample Neufeld ASN.1 to C/C++ Compiler''.
+
+This compiler was written so I could do some encoding performance
+research for my M.Sc.  See \cite{Sample93-1}, or \cite{Sample93-2} for
+the results of that research.  A techreport will soo be available
+via ftp from UBC, in the same directory as snacc.
+
+The ASN.1 data structure language can specify complex types such as
+lists and recursively defined types. BER data values are defined
+independently of any computer architecture, providing a universal data
+value representation that is useful for sharing data in heterogeneous
+networks.
+
+The process of converting an ASN.1 value from its C or C++
+representation into an equivalent BER data value is called encoding
+and the reverse process is called decoding.  This document was written
+assuming that the reader is familiar ASN.1 and BER.  Further
+information on ASN.1 and BER can be found in \cite{ASN.1Book},
+\cite{ASN.1Overview}, \cite{X.208} and \cite{X.209}.
+
+Compiling ASN.1 into C is not a new idea but many other tools such as
+UBC's CASN1 \cite{CASN1}, ISODE's PEPY/POSY \cite{ISODE}, and
+commercial tools either do not parse ASN.1 '90, produce slow encoders
+and decoders or are outrageously expensive. The aim of this tool is to
+provide an ASN.1 compiler that parses ASN.1 '90, produces efficient
+encoding and decoding routines and is freely available.  Effort has
+been made to make the generated encoders and decoders relatively easy
+to fit into different software environments.
+
+The table driven encoders are useful for certain applications such as
+protocol testing.  They are also useful if you need to dynamically
+load new ASN.1 definitions.  It is also fairly simple to write your
+own special ASN.1 tools based on tables (e.g. a protocol tester that
+verifies that values conform to a given ASN.1 type definition).  The
+price of the flexibility is speed; they are slower (~4 times) than the
+compiled C and C++ versions.
+
+Some of snacc's features include:
+\begin {itemize}
+\item {parses CCITT ASN.1 '90 including  subtype notation}
+\item {can compile and link inter-dependent ASN.1 modules (IMPORTS/EXPORTS)}
+\item {some X.400 and SNMP macros are parsed}
+
+\item {macro {\em definitions} do not generate syntax errors but are
+are not processed. The macro definitions are retained as a string
+internally (if you want to modify the compiler to process them).}
+
+\item {value notation is parsed. OBJECT IDENTIFIERs, INTEGERs
+and BOOLEANs are translated to C/C++ values. Any other value in \{\}'s
+is kept as a string internally (if you want to modify the compiler to
+process them).}
+
+\item {optionally supports ``;'' separated type or value definitions
+      in the ASN.1 source. This is useful for dealing with some macros and
+      other language ambiguities that introduce parsing problems.}
+\item {ANY DEFINED BY types are supported via the SNMP OBJECT-TYPE macro}
+\end{itemize}
+
+\section{\label{old-install-section}Installing snacc}
+
+First of all, if you haven't already done so, un-archive snacc to
+produce the directory {\em snacc} and its contents.  The following tools
+are required to compile snacc:
+\begin{itemize}
+\item {\verb$lex$ or GNU's \verb$flex$ (\verb$flex$ is recommended)}
+\item {\verb$yacc$ or GNU's \verb$bison$ (\verb$bison$ is recommended)}
+\item {a C compiler and \verb$make$}
+\end{itemize}
+
+Some versions of \verb$yacc$ will choke due to the large size of the
+\verb$asn1.yacc$ file, however, I have had no problems with \verb$bison$.
+Our \verb$yacc$ grammar for ASN.1 has 61 shift/reduce errors and 2
+reduce/reduce errors.  Most of these errors were introduced when
+certain macros were added to the compiler.  Some of the shift/reduce
+errors will require you to follow the offending macro in the ASN.1
+module with a semi-colon.  The reduce/reduce errors were introduced by
+macros that have ``Type or Value Lists'' because the NULL Type and
+NULL values use the same symbol, ``NULL''.  This is not a problem
+since no real processing is done with the macros in question at the
+present.
+
+\verb$Lex$ will work for the \verb$asn1.lex$ file but \verb$flex$ will typically
+produce a smaller executable.  Most versions of \verb$lex$ have a small
+maximum token size that will cause problems for long tokens in the
+ASN.1 source files, such as quoted strings.  To avoid this problem,
+increase the \verb$YYLMAX$ value in the generated {\em lex.yy.c} file to at least
+2048.  \verb$Flex$ does not seem to have this problem.
+
+The compiler and library C code has been written to support ANSI or
+non-ANSI C\@.  ANSI C is used by default; this can be configured in
+\verb$snacc/c_include/asn_config.h$.
+
+By default, the compiler's makefiles use \verb$flex$, \verb$bison$ and
+\verb$gcc$.  If you wish to change these, edit the following files:
+
+\begin{verbatim}
+snacc/src/makefile
+snacc/src/c_lib/makefile
+snacc/src/back_ends/c_gen/makefile
+snacc/src/back_ends/c++_gen/makefile
+\end{verbatim}
+
+The C runtime library uses \verb$gcc$, and its makefile is
+\verb$snacc/c_lib/makefile$.  The C++ runtime library uses \verb$g++$
+(\verb$gcc-2.2.3$) and its makefile is \verb$snacc/c++_lib/makefile$.
+The type table library makefile uses \verb$gcc$ and is
+\verb$snacc/tbl_lib/makefile$.
+
+Finally, to compile \verb$snacc$ and the C and C++ runtime libraries,
+type the following at the shell prompt:
+
+\begin{verbatim}
+%1 cd snacc
+%2 make all
+\end{verbatim}
+
+If you wish to install only the C (including type tables) or only the
+C++ versions of the library, type \verb$make c$ or \verb$make c++$,
+respectively, instead of \verb$make all$.  If the make succeeds, the
+snacc binary, {\em snacc}, should be in the \verb$snacc/bin/$
+directory, the C runtime libraries, {\em libasn1csbuf.a}, {\em
+libasn1cebuf.a}, and {\em libasn1cmbuf.a}, should be in the
+\verb$snacc/c_lib$ and the C++ runtime library, {\em libasn1c++.a}
+should be in the \verb$snacc/c++_lib$.  The type table library, {\em
+libasn1tbl.a} will be in \verb$snacc/tbl_lib$.  The type table tools,
+{\em ptbl}, {\em pval} and {\em mkchdr} will be in \verb$snacc/bin$.
+The \verb$.o$ and other junk files will have been removed.
+
+After compiling the libraries, you can test the library routines with
+\linebreak \verb$snacc/c_examples/test_lib/test_lib$ or \linebreak
+\verb$snacc/c++_examples/test_lib/test_lib$.  These programs run
+simple encoding and decoding tests on all of the library types.  You
+can test the snacc compiler with the other examples.
+
+A manual page that contains information on running snacc can be found in
+\verb$snacc/doc/snacc.1$.  This should be installed in section~1 of
+the manual.  You can use \verb$nroff -man snacc.1$ to view it if you
+don't want to install it.
+
+
+\section{\label{old-run-section}Running snacc}
+
+Snacc is typically invoked from the shell command line and has the synopsis:
+\begin{verbatim}
+snacc [-h] [-P] [-t] [-e] [-d] [-p] [-f]
+      [ -c | -C | -T <table output file>]
+      [-u <useful types ASN.1 file>]
+      [-mf <max file name len>]
+      [-l <neg number>]
+      <ASN.1 file list>
+\end{verbatim}
+
+Snacc generates C or C++ source code for BER encode and decode
+routines as well as print and free routines for each type in the given
+ASN.1 modules.  Alternatively, snacc can produce type tables that can
+be used for table based/interpreted encoding and decoding.  The type
+table based methods tend to be slower than their C or C++ counterparts
+but they tend use less memory (table size vs. C/C++ object code).
+
+Most of the 1990~ASN.1 features are parsed although some do not affect
+the generated code.  Fairly rigourous error checking is performed on
+the ASN.1 source; any errors detected will be reported (printed to
+\verb$stderr$).
+
+Each file in the ASN.1 file list should contain a complete ASN.1
+module.  ASN.1 modules that use the IMPORTS feature must be compiled
+together (specify all necessary modules in the ASN.1 file list).  The
+generated source files will include each module's header file in the
+command line order.  This makes it important to order the modules from
+least dependent to most dependent on the command line to avoid type
+ordering problems. Currently, snacc assumes that each ASN.1 file
+given on the command line depends on all of the others on the command
+line.  No attempt is made to only include the header files from
+modules referenced in the import list for that module.
+
+If the target language is C, snacc will generate a \verb$.h$ and
+\verb$.c$ file for each specified ASN.1 module.  If the target
+language is C++, snacc will generate a \verb$.h$ and \verb$.C$ file
+for each module.  The generated file names will be derived from the
+module names.
+
+The command line options are:
+% zap bullet for items
+%\def\labelitemi{}
+
+\begin{description}
+\item[-h    ] {short for ``help'', prints a synopsis of snacc
+and exits.}
+
+\item[-c    ] {causes snacc to generate C source code.
+This is the default behaviour of snacc if neither of the \verb$-c$ or
+\verb$-C$ options are given.  Only one of the \verb$-c$, \verb$-C$ or
+\verb$-T$ options should be specified.}
+
+\item[-C    ] {causes snacc to generate C++ source code.}
+
+\item[-T {\em file}] {causes snacc to generate type tables and
+write them to the given file {\em file}.}
+
+\item[-P    ] {causes snacc to print the parsed ASN.1
+modules to \verb$stdout$ after the types have been linked, sorted, and
+processed.  This option is useful for debugging snacc and observing
+the modifications snacc performs on the types to make code generation
+simpler.}
+\end{description}
+
+The options, \verb$-t, -v, -e, -d, -p,$ and \verb$-f$ affect
+what types and routines go into the generated source code.
+These options do not affect type table generation. If none of
+them are given on the command line, snacc assumes that all of them are
+in effect.  For example, if you do not need the Free or Print
+routines, you should give the \verb$-t -v -e -d$ options to snacc.
+This lets you trim the size of the generated code by removing
+unnecessary routines; the code generated from large ASN.1
+specifications can produce very large binaries.
+
+\begin{description}
+\item[-t    ] {causes snacc to generate type definitions in the
+target language for each ASN.1 type.}
+
+\item[-v    ] {causes snacc to generate value definitions in the
+target language for each ASN.1 value.  Currently value definitions are
+limited to INTEGERs, BOOLEANs and OBJECT IDENTIFIERs.}
+
+\item[-e    ] {causes snacc to generate encode routines in the
+target language for each ASN.1 type.}
+
+\item[-d    ] {causes snacc to generate decode routines in the
+target language for each ASN.1 type.}
+
+\item[-p    ] {causes snacc to generate print routines in the
+target language for each ASN.1 type.}
+
+\item[-f    ] {causes snacc to generate free routines in the
+target language for each ASN.1 type.  This option only works when the
+target language is C\@.  The free routines hierarchically free C values.
+A more efficient approach is to use the provided nibble-memory system.
+The nibble memory permits freeing an entire decoded value without
+traversing the decoded value.  This is the default memory allocator
+used by snacc generated decoders.  See file
+\verb$snacc/c_include/asn_config.h$ to change the default memory
+system.  For more information on the memory management see Section~\ref{lib-mem-C-section}.}
+
+\item[-u {\em file}] {causes snacc to read the useful types
+definitions from the ASN.1 module in file {\em file}
+for linking purposes.  For some ASN.1 specifications, such as SNMP,
+the useful types are not needed.  The types in the given useful types
+file are globally available to all modules; a useful type definition
+is overridden by a local or explicitly imported type with the same
+name. The useful type module can be found in
+\verb$snacc/asn1specs/asn-useful.asn1$ and contains:
+
+
+\begin{itemize}
+\setlength{\itemsep}{0pt}
+\setlength{\parsep}{0pt}
+\nspace{0}
+\item ObjectDesccriptor
+\item NumericString
+\item PrintableString
+\item TeletexString
+\item T61String
+\item VideoTexString
+\item IA5String
+\item GraphicString
+\item ISO646String
+\item GeneralString
+\item UTCTime
+\item GeneralizedTime
+\item EXTERNAL
+\end{itemize}}
+
+
+\item[-mf {\em number}] {causes the names of the generated source
+files to have a maximum length of {\em number} characters, including
+their suffix.  The {\em number} argument must be at least~3.  This option
+is useful for supporting operating systems that only support short
+file names.  A better solution is to shorten the module name of each
+ASN.1 module.}
+
+\item[-l {\em number}] {this is fairly obscure but may be useful.  Each
+error that the decoders can report is given an id number.  The number
+{\em number} is where the error ids start decreasing from as they are
+assigned to errors.  The default is -100 if this option is not given.
+Avoid using a number in the range -100 to 0 since they may conflict
+with the library routines' error ids.  If you are re-compiling the
+useful types for the library use -50.  Another use of this option is
+to integrate newly generated code with older code; if done correctly,
+the error ids will not conflict.}
+
+\end{description}
+
+Since ASN.1 has different scoping rules than C and C++, some name munging
+is done for types, named-numbers etc. to eliminate conflicts.
+Some capitalization schemes were chosen to fit common C programming
+style.  For all names, dashes in the ASN.1 source are converted to
+underscores.  See Sections \ref{naming-C-section} and \ref{naming-C++-section}
+for more naming information.
+
+The module name is used as a base name for the generated source file
+names.  It will be put into lowercase and dashes will be replaced with
+underscores.  Module names that result in file names longer than
+specified with the \verb$-mf$ option will be truncated.  If the
+\verb$-mf$ option was not given, file names will be truncated if they
+are too long for the target file system. You may want to shorten long
+module names to meaningful abbreviations. This will avoid file name
+conflicts for module names that are truncated to the same substring.
+Any module name and file name conflicts will be reported.
+
+If your ASN.1 modules have syntactic or semantic errors, each error
+will be printed to \verb$stderr$ along with the file name and line number of
+where it occurred. These errors are usable by GNU emacs compiling
+tools.  See the next chapter for more information on the types of
+errors snacc can detect.
+
+More errors can be detected and reported in a single compile if type
+and value definitions are separated by semi-colons.  Separating type
+and value definitions with semi-colons is not required, and if used,
+need not be used to separate all type and value definitions.
+Semi-colons are necessary after some macros that introduce ambiguity.
+In general, if you get a parse error you can't figure out, try
+separating the surrounding type/value definitions with semicolons.
+
+
+\subsection{Known Bugs}
+
+Snacc has problems with the following case:
+
+\begin{verbatim}
+Foo ::= SEQUENCE
+{
+    id IdType,
+    val ANY DEFINED BY id
+}
+
+IdType ::= CHOICE
+{
+    a INTEGER,
+    b OBJECT IDENTIFIER
+}
+\end{verbatim}
+
+The error checking pass will print an error to the effect that the id
+type must be INTEGER or OBJECT IDENTIFER\@.  To fix this you must modify
+the error checking pass as well as the code generation pass.  To be
+cheap about it, disable/fix the error checking and hand modify the
+generated code.
+
+The hashing code used for handling ANY DEFINED BY id to type mappings
+will encounter problems if the hash table goes more than four levels
+deep (I think this is unlikely).  To fix this just add linear chaining
+at fourth level.
+
+On the deficiency side of things, the C++ classes really need to have
+free methods defined for them. (Unless you have replaced new with
+something like nibble memory)
+
+\section{\label{old-bug-section}Reporting Bugs and Your Own Improvements}
+
+This (1.1) is the final release of snacc (I have finished my M.Sc).
+Gerald Neufeld \verb$<neufeld@cs.ubc.ca>$ was my supervisor but he
+does not have time to deal with support (it is all my code anyway).
+Luckily, a colleague has kindly offered to receive the bug reports and
+to coordinate work done by others (i.e.  you).  His name is Barry
+Brachman \verb$<brachman@cs.ubc.ca>$.  He did not write the code
+(35,000+ lines of C) but he has used snacc for X.500 work.  He may be
+able to point you to someone who has fixed or encountered the same
+bug.  Anyway, be nice to him, it's not his job.
+
+Even though this is the second release of snacc, bugs are still
+likely.  In fact, this release was quite rushed so there are probably
+lots of stupid installation bugs etc.  If you find some bugs or have
+other comments, please send email to \verb$snacc-bugs@cs.ubc.ca$
+(these will get to Barry and Gerald).  Please include the offending
+ASN.1 source, the command line options you were using and the hardware
+and operating system configuration.
+
+If you are really keen and hack in new goodies, please share.  Send
+them to Barry or \verb$snacc-bugs@cs.ubc.ca$. Look in
+\verb$snacc/README.future$ for things you could work on.
+
+As I mentioned, I have entered the real world. I am now working with
+Open Systems Solutions (based in New Jersey).  If your application
+needs a commercially developed and supported ASN.1 compiler, try
+calling 1-609-987-9073 (Yeah, I know this is a plug, but it's a good
+company).
diff --git a/SecuritySNACCRuntime/doc/intro-1.2.tex b/SecuritySNACCRuntime/doc/intro-1.2.tex
new file mode 100644
index 00000000..4a822231
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/intro-1.2.tex
@@ -0,0 +1,422 @@
+% file: .../doc/intro-1.2.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/intro-1.2.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: intro-1.2.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:53  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.2  1997/02/16 16:49:30  rj
+% made return *this after calling abort()'' a compile time option.
+%
+% Revision 1.1  1997/01/01 22:47:30  rj
+% first check-in
+%
+
+\chapter{\label{intro-1.2}Introduction}
+
+Snacc compiles ASN.1 \cite{X.208} (Abstract Syntax Notation One) modules into C, C++, CORBA IDL \cite{corba} or type tables.
+The generated C or C++ code contains equivalent data structures and
+routines to convert values between the internal (C or C++)
+representation and the corresponding BER \cite{X.209} (Basic Encoding Rules) format.
+The name ``snacc'' is an acronym for ``Sample Neufeld ASN.1 to C/C++ Compiler''.
+
+This is release 1.2rj\footnote{\emph{1.2} since it is the successor of 1.1 and \emph{rj} as i don't think that I'm the only one who worked on Snacc.} of Snacc.
+This chapter lists only the differences to the original author's last release, Snacc~1.1.
+The list in this chapter is incomplete---for a more thorough enumeration, see the file {\ufn .../ChangeLog}.
+
+New features include:
+\begin{itemize}
+\item
+  The output files generated get names derived from their input file's name, with only the suffix replaced.
+  This eases makefile writing, as now you can use simple suffix rules or other forms of filename pattern matching.
+  The old behaviour, where the output files got their name from the ASN.1 module name, can be retained by using the {\ufn -mm} command line switch to {\ufn snacc}.
+\item
+  The C++ backend generates code with a much more complete set of constructors, destructors and assignment operators.
+\item
+  The C++ backend can supply the generated C++ classes with \emph{meta} information about their own structure.
+  This information can be used to build interpreted interfaces; the Snacc 1.2rj distribution contains a Tcl interface that uses this meta information as well as a Tcl script (that uses the Tcl interface) for a simple editor.
+\item
+  Snacc has successfully been ported to Linux and Alpha OSF/1, and should be both byte order and 64 bit clean.
+\item
+  A new backend that generates CORBA IDL (work-in-progress, not even alpha)
+\end{itemize}
+
+The makefiles have been rewritten.
+The old ones removed the {\ufn .o} files after successful compilation, and thus, for every tiny code change, a full recompilation took place!
+With the new set of makefiles, only those files that need to be remade are.
+Following usual conventions, the phony targets depend, check, install, clean and clobber have been added.
+\newline
+NOTE: the makefiles still are not safe for parallel making.
+\\
+See Appendix~\ref{makefile-sect} for some explanations of some the makefile tricks.
+\\
+If you've got problems with the makefiles, please refer to the appendix!
+
+The 1.1 release used five config.h files, and three almost identical copies of the ASN.1 C library.
+They have all been merged in the file {\ufn \dots/snacc.h}.
+A very small number (currently three) of compilation switches has been put into {\ufn \dots/policy.h}.
+
+The previous release produced huge virtual inline functions.
+Due to their size, these inlines wouldn't get inlined anyway.
+Virtual functions don't get inlined (they get referenced via pointer in the virtual function table).
+Due to their size they wouldn't offer any speed advantage (the function call overhead diminishes).
+Instead, the compiler generated static functions in every {\ufn .C} file were the {\ufn .h} file is included!
+This inflates the {\ufn .o} files and executables real quick (I'm speaking of MBytes per executable).
+These functions have been turned into normal functions.
+
+\section{\label{install-section}Configuring and Installing Snacc}
+
+First of all, if you haven't already done so, un-archive Snacc to
+produce the directory {\ufn snacc-1.2rj.\textit{patchlevel}} and its contents.
+The directory {\ufn snacc-1.2rj.\textit{patchlevel}} will henceforth be referred to as ``{\ufn \dots}''.
+The following tools are required to compile Snacc:
+\begin{itemize}
+  \item {\ufn make} (GNU {\ufn make} is recommended)
+  \item {\ufn patch} (for a tiny patch in {\ufn \dots/c-lib/})
+  \item {\ufn makedepend} or a look-alike (all of them have their advantages and disadvantages, it is hard to recommend any of them, see below)
+  \item {\ufn lex} or GNU's {\ufn flex} ({\ufn flex} is recommended)
+  \item {\ufn yacc} or GNU's {\ufn bison} ({\ufn bison} is recommended)
+  \item a C compiler (it doesn't have to support ANSI, K\&R will do)
+\end{itemize}
+
+Some versions of {\ufn yacc} may choke due to the large size of the
+{\ufn parse-asn1.y} file, however, we have had no problems with {\ufn bison}.
+Our {\ufn yacc} grammar for ASN.1 has 61 shift/reduce errors and 2
+reduce/reduce errors.  Most of these errors were introduced when
+certain macros were added to the compiler.  Some of the shift/reduce
+errors will require you to follow the offending macro in the ASN.1
+module with a semi-colon.  The reduce/reduce errors were introduced by
+macros that have ``Type or Value Lists'' because the NULL Type and
+NULL values use the same symbol, ``NULL''.  This is not a problem
+since no real processing is done with the macros in question at the
+present.
+
+{\ufn Lex} will work for the {\ufn lex-asn1.l} file but {\ufn flex} will typically
+produce a smaller executable.  Most versions of {\ufn lex} have a small
+maximum token size that will cause problems for long tokens in the
+ASN.1 source files, such as quoted strings.  To avoid this problem,
+increase the {\C YYLMAX} value in the generated {\ufn lex-asn1.c} file to at least
+2048.  {\ufn Flex} does not seem to have this problem.
+
+The configuration process has been simplified (at least for the installer of Snacc ;-) by the use of GNU autoconf.
+
+The only file has may have to be edited is {\ufn \dots/policy.h}.
+It contains a few compilation switches you may want to toggle.
+
+The behaviour of makedepend has been changed from X11R5 to R6.
+The new version keeps the source files' dirname and replaces the suffix only, the old version removed the dirname.
+The makefiles expect the new behaviour.
+If you've still got the R5 makedepend, the compiler's dependencies will be useless.
+(If you only install the code and don't make any source code changes, this won't hurt you.)
+If you haven't got {\ufn makedepend}, you can use any of the look-alikes, which often are {\ufn sh}-scripts calling the compiler with the {\ufn -M}-switch.
+If you don't plan to make any source code changes, you can replace {\ufn makedepend} with {\ufn /bin/true}.
+\newline
+Warning: MIT X11's makedepend is broken, in both R5 and R6.
+It silently does not produce any output for many of Snacc's C++ files (in {\ufn \dots/c++-lib/}).
+\newline
+The C compiler called with the {\ufn -M}-switch gives much better results, but is \emph{much} slower.
+
+The Snacc compiler and library C code has been written to support ANSI or non-ANSI C\@.
+The configuration script tries to find out whether your C compiler understands ANSI C\@.
+
+The configuration script generates two files:
+\begin{description}
+  \item[{\ufn \dots/makehead}] gets included by all makefiles.
+    It contains a lot of definitions used by make.
+  \item[{\ufn \dots/config.h}] contains all the machine, operating system, compiler and environment dependent settings.
+    It is included by {\ufn \dots/snacc.h}.
+\end{description}
+
+The C++ runtime library is known to compile with both {\ufn gcc 2.5.8} and {\ufn gcc 2.6.3}.
+The latter has the {\C bool} type built-in (which the configuration script automatically detects).
+
+Finally, to compile {\ufn snacc} and the C and C++ runtime libraries,
+type the following at the shell prompt:
+
+\begin{verbatim}
+%1 cd snacc-1.2rj.*
+%2 ./configure
+%3 make
+\end{verbatim}
+
+If you wish to install only the C (including type tables) or only the
+C++ versions of the library, type {\ufn make c} or {\ufn make c++},
+respectively, instead of {\ufn make}.  If the make succeeds, the
+{\ufn snacc} binary should be present as {\ufn \dots/compiler/snacc},
+the C runtime libraries, {\ufn libasn1csbuf.a},
+{\ufn libasn1cebuf.a}, {\ufn libasn1cmbuf.a} and {\ufn libasn1ctbl.a}, should be in
+{\ufn \dots/c-lib/} and the C++ runtime library, {\ufn libasn1c++.a}
+(and, if you compiled with the Tcl option enabled,
+another runtime library, {\ufn libasn1tcl.a}),
+should be in {\ufn \dots/c++-lib/}.
+The type table tools,
+{\ufn ptbl}, {\ufn pval} and {\ufn mkchdr}, will be in their respective directories under {\ufn \dots/tbl-tools/}.
+
+After compiling the libraries, you can test the library routines by calling {\ufn make check}
+(or by calling {\ufn make c-check} or {\ufn make c++-check} to test the C or C++ library routines only, respectively).
+
+Manual pages that contain information on running {\ufn snacc} and the type table tools can be found in {\ufn \dots/doc/}.  
+
+To install Snacc, you can call {\ufn make install} (or {\ufn make c-install} or {\ufn make c++-install}, respectively).
+This installs the snacc compiler binary, the libraries, the {\ufn .h} and {\ufn .asn1} files, the type table tools, as well as the manual pages into the usual directories.
+
+To remove the {\ufn .o} and other intermediate files, you can call {\ufn make clean}.
+To remove the binaries, libraries and all other generated files as well, call {\ufn make clobber}.
+
+\section{\label{run-section}Running Snacc}
+
+Snacc is typically invoked from the shell command line and has the synopsis:
+\begin{verbatim}
+snacc [-h] [-P] [-t] [-e] [-d] [-p] [-f]
+      [ -c | -C | -idl | -T <table output file>]
+      [-meta <module>.<type>[,...]] [-mA | -mC]
+      [-tcl <module>.<type>[,...]]
+      [-u <useful types ASN.1 file>]
+      [-mm] [-mf <max file name len>]
+      [-l <neg number>]
+      [-novolat]
+      <ASN.1 file list>
+\end{verbatim}
+
+Snacc generates C or C++ source code for BER encode and decode
+routines as well as print and free routines for each type in the given
+ASN.1 modules.  Alternatively, snacc can produce type tables that can
+be used for table based/interpreted encoding and decoding.  The type
+table based methods tend to be slower than their C or C++ counterparts
+but they tend use less memory (table size vs. C/C++ object code).
+
+Snacc may also be used to generate CORBA IDL\@.
+This part of Snacc is very new and I would rate it as pre-alpha.
+
+The {\ufn -meta}, {\ufn -mA}, {\ufn -mC} and {\ufn -tcl} options are only present when the Tcl and Tk libraries where found at configuration time.
+
+Most of the 1990 ASN.1 features are parsed although some do not affect
+the generated code.  Fairly rigourous error checking is performed on
+the ASN.1 source; any errors detected will be reported (printed to
+{\C stderr}).
+
+Each file in the ASN.1 file list should contain a complete ASN.1
+module.  ASN.1 modules that use the IMPORTS feature must be compiled
+together (specify all necessary modules in the ASN.1 file list).  The
+generated source files will include each module's header file in the
+command line order.  This makes it important to order the modules from
+least dependent to most dependent on the command line to avoid type
+ordering problems. Currently, snacc assumes that each ASN.1 file
+given on the command line depends on all of the others on the command
+line.  No attempt is made to only include the header files from
+modules referenced in the import list for that module.
+
+If the target language is C, snacc will generate a {\ufn .h} and {\ufn .c} file for each specified ASN.1 module.
+If the target language is C++, snacc will generate a {\ufn .h} and {\ufn .C} file for each module.
+If the target language is CORBA IDL, snacc will generate an {\ufn .idl} file for each module.
+The generated file names will be derived from the module's filenames, or from the
+module names if the {\ufn -mm} command line switch has been given.
+
+The command line options are:
+
+\begin{description}
+  \item[--h    ] {short for ``help'', prints a synopsis of snacc and exits.}
+
+  \item[--c    ] {causes snacc to generate C source code.
+  This is the default behaviour of snacc if neither of the {\ufn -c} or {\ufn -C} options are given.
+  Only one of the {\ufn -c}, {\ufn -C}, {\ufn -idl} or {\ufn -T} options should be specified.}
+
+  \item[--C    ] {causes snacc to generate C++ source code.}
+
+  \item[--novolat] {causes snacc to generate C++ ``{\C return *this}''
+  after calling {\C abort()}. (Some broken compilers don't know about
+  volatile functions, or their abort() isn't correctly typed.)}
+
+  \item[--idl  ] {causes snacc to generate CORBA IDL source code.}
+
+  \item[--T \emph{file}] {causes snacc to generate type tables and write them to the given file \emph{file}.}
+
+  \item[--meta \emph{types}]
+    causes snacc to generate C++ classes with type meta information.
+    Requires C++ functionality and therefore implies {\ufn -C} (C++ code generation).
+
+  The \emph{types} denote the PDUs and have the following syntax: a comma-separated list of pairs of: module name, a dot, and a type name from that module. (Example: {\ufn snacc -tcl M1.T-a,M-2.Tb mod1.asn1 m2.asn1})
+
+  \item[--mA \textnormal{and} --mC]
+    causes the metacode to use identifiers as defined in the ASN.1 source files or as used in the generated C++ code, respectively.
+    (It defaults to {\ufn -mC}.)
+
+  \item[--tcl \emph{types}]
+    causes snacc to generate functions for a Tcl interface.
+    Needs the type meta information and thus implies {\ufn -meta} (see above).
+    The {\ufn -meta} option can and should be omitted, the \emph{types} are as for the {\ufn -meta} option (the \emph{types} arguments are additive, in case you specify both options).
+
+  \item[--P    ] {causes snacc to print the parsed ASN.1 modules to {\C stdout} after the types have been linked, sorted, and processed.
+  This option is useful for debugging snacc and observing the modifications snacc performs on the types to make code generation simpler.}
+\end{description}
+
+The options, {\ufn -t, -v, -e, -d, -p,} and {\ufn -f} affect
+what types and routines go into the generated source code.
+These options do not affect type table generation. If none of
+them are given on the command line, snacc assumes that all of them are
+in effect.  For example, if you do not need the Free or Print
+routines, you should give the {\ufn -t -v -e -d} options to snacc.
+This lets you trim the size of the generated code by removing
+unnecessary routines; the code generated from large ASN.1
+specifications can produce very large binaries.
+
+\begin{description}
+\item[--t    ]
+  causes snacc to generate type definitions in the target language for each ASN.1 type.
+
+\item[--v    ]
+  causes snacc to generate value definitions in the target language for each ASN.1 value.
+  Currently value definitions are limited to INTEGERs, BOOLEANs and OBJECT IDENTIFIERs.
+
+\item[--e    ]
+  causes snacc to generate encode routines in the target language for each ASN.1 type.
+
+\item[--d    ]
+  causes snacc to generate decode routines in the target language for each ASN.1 type.
+
+\item[--p    ]
+  causes snacc to generate print routines in the target language for each ASN.1 type.
+
+\item[--f    ]
+  causes snacc to generate free routines in the target language for each ASN.1 type.
+  This option only works when the target language is C\@.
+  The free routines hierarchically free C values.
+  A more efficient approach is to use the provided nibble-memory system.
+  The nibble memory permits freeing an entire decoded value without traversing the decoded value.
+  This is the default memory allocator used by snacc generated decoders.
+  See file {\ufn \dots/c-lib/inc/asn-config.h} to change the default memory system.
+  For more information on the memory management see Section~\ref{lib-mem-C-section}.
+
+\item[--u \emph{file}]
+  causes snacc to read the useful types definitions from the ASN.1 module in file \emph{file} for linking purposes.
+  For some ASN.1 specifications, such as SNMP, the useful types are not needed.
+  The types in the given useful types file are globally available to all modules; a useful type definition is overridden by a local or explicitly imported type with the same name.
+  The useful type module can be found in {\ufn \dots/asn1specs/asn-useful.asn1} and contains:
+  \begin{itemize}
+    \setlength{\itemsep}{0pt}
+    \setlength{\parsep}{0pt}
+    \nspace{0}
+    \item ObjectDesccriptor
+    \item NumericString
+    \item PrintableString
+    \item TeletexString
+    \item T61String
+    \item VideoTexString
+    \item IA5String
+    \item GraphicString
+    \item ISO646String
+    \item GeneralString
+    \item UTCTime
+    \item GeneralizedTime
+    \item EXTERNAL
+  \end{itemize}
+
+\item[--mm]
+  This switch is supplied for backwards compatibility.
+  Snacc versions 1.0 and 1.1 produced files with names generated from the ASN.1 module name contained in the input file.
+  Snacc 1.2rj by default retains the input file name and replaces the suffix only.
+  The new behaviour makes {\ufn makefile} writing easier, as with modern {\ufn make}s, pattern matching can be used.
+
+\item[--mf \emph{number}]
+  causes the names of the generated source files to have a maximum length of \emph{number} characters, including their suffix.
+  The \emph{number} argument must be at least 3.
+  This option is useful for supporting operating systems that only support short file names.
+  A better solution is to shorten the module name of each ASN.1 module.
+
+\item[--l \emph{number}]
+  this is fairly obscure but may be useful.
+  Each error that the decoders can report is given an id number.
+  The number \emph{number} is where the error ids start decreasing from as they are assigned to errors.
+  The default is -100 if this option is not given.
+  Avoid using a number in the range -100 to 0 since they may conflict with the library routines' error ids.
+  If you are re-compiling the useful types for the library use -50.
+  Another use of this option is to integrate newly generated code with older code; if done correctly, the error ids will not conflict.
+
+\end{description}
+
+Since ASN.1 has different scoping rules than C and C++, some name munging
+is done for types, named-numbers etc. to eliminate conflicts.
+Some capitalization schemes were chosen to fit common C programming
+style.  For all names, dashes in the ASN.1 source are converted to
+underscores.  See Sections \ref{naming-C-section} and \ref{naming-C++-section}
+for more naming information.
+
+If the {\ufn -mm} switch has been given, the module name is used as a base name for the generated source file
+names.  It will be put into lowercase and dashes will be replaced with
+underscores.  Module names that result in file names longer than
+specified with the {\ufn -mf} option will be truncated.  If the
+{\ufn -mf} option was not given, file names will be truncated if they
+are too long for the target file system. You may want to shorten long
+module names to meaningful abbreviations. This will avoid file name
+conflicts for module names that are truncated to the same substring.
+Any module name and file name conflicts will be reported.
+
+If your ASN.1 modules have syntactic or semantic errors, each error
+will be printed to {\C stderr} along with the file name and line number of
+where it occurred. These errors are usable by GNU emacs compiling
+tools.  See the next chapter for more information on the types of
+errors snacc can detect.
+
+More errors can be detected and reported in a single compile if type
+and value definitions are separated by semi-colons.  Separating type
+and value definitions with semi-colons is not required, and if used,
+need not be used to separate all type and value definitions.
+Semi-colons are necessary after some macros that introduce ambiguity.
+In general, if you get a parse error you can't figure out, try
+separating the surrounding type/value definitions with semicolons.
+
+
+\subsection{Known Bugs}
+
+\begin{itemize}
+  \item
+    Snacc has problems with the following case:
+    \begin{ASNcode}
+      Foo ::= SEQUENCE\\
+      \{\+\\
+	id IdType,\\
+	val ANY DEFINED BY id\-\\
+      \}\\
+      \\
+      IdType ::= CHOICE\\
+      \{\+\\
+	a INTEGER,\\
+	b OBJECT IDENTIFIER\-\\
+      \}
+    \end{ASNcode}
+
+    The error checking pass will print an error to the effect that the id
+    type must be INTEGER or OBJECT IDENTIFER\@.  To fix this you must modify
+    the error checking pass as well as the code generation pass.  To be
+    cheap about it, disable/fix the error checking and hand modify the
+    generated code.
+
+  \item
+    The hashing code used for handling ANY DEFINED BY id to type mappings
+    will encounter problems if the hash table goes more than four levels
+    deep (I think this is unlikely).  To fix this just add linear chaining
+    at fourth level.
+
+  \item 
+    The {\ufn \dots/configure} script should check whether the machine's floating point format is IEEE or whether the IEEE library exists.
+
+  \item
+    The C++ library severly lacks a convenient buffer management class that automatically expands like the C libraries' ExpBuf.
+    What use is an efficient buffer management when you have got to build a loop a round snacc's encoding routine that reallocates larger buffers until the result fits?
+
+  \item
+    Where this document describes personal experiences, it is usually unclear to which author `I' refers.
+    (One way to find out is to look at snacc~1.1's documentation.)
+
+\end{itemize}
+
+\section{\label{bug-section}Reporting Bugs and Your Own Improvements}
+
+Snacc 1.1 was Michael Sample's final release.
+While he is watching Snacc's development, he isn't actively developing it himself.
+
+Since there are quite a number of changes from release 1.1 to 1.2rj, bug reports and new features are best sent to me.
+I can be reached as \texttt{Robert Joop <rj@rainbow.in-berlin.de>} or \texttt{<rj@fokus.gmd.de>}.
diff --git a/SecuritySNACCRuntime/doc/makefile b/SecuritySNACCRuntime/doc/makefile
new file mode 100644
index 00000000..89d5acb5
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/makefile
@@ -0,0 +1,237 @@
+# file: .../doc/makefile
+#
+# - build the user documentation, snacc-*.ps
+# - install the various manual pages
+#
+#  MS 92
+#  use nroff -man snacc.1  to see what the man page, snacc.1, looks like
+#
+#  if latex bombs unexplainably, try 'make clean' followed by 'make'
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:53  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.4  1997/06/19 09:28:30  wan
+# Disabled making new doc due to new version string.
+#
+# Revision 1.3  1997/02/16 19:23:13  rj
+# typo fixed
+#
+# Revision 1.2  1997/01/02 08:51:51  rj
+# order of two files reversed to reflect the order in snacc.tex
+#
+# Revision 1.1  1997/01/01 22:28:25  rj
+# first check-in
+#
+
+include ../makehead
+
+TOP		= ..
+
+MANUALS.1 = \
+	snacc.1		\
+	mkchdr.1	\
+	ptbl.1		\
+	pval.1		\
+	snacced.1
+
+MANUALS.n = \
+	snacc.n
+
+TEX_ROOT	= snacc.tex
+
+TEX_SRC		= \
+	$(TEX_ROOT)	\
+	misc-hyph.tex	\
+	version.tex	\
+	intro-1.2.tex	\
+	intro-1.1.tex	\
+	design.tex	\
+	c-gen.tex	\
+	c-lib.tex	\
+	c++-gen.tex	\
+	c++-lib.tex	\
+	meta.tex	\
+	tcl.tex		\
+	editor.tex	\
+	idl-gen.tex	\
+	ttab.tex	\
+	modifying.tex	\
+	future-work.tex	\
+	asn1-defs.tex	\
+	coding.tex	\
+	makefile.tex
+
+AUX		= \
+	snacc.aux	\
+	version.aux	\
+	intro-1.1.aux	\
+	intro-1.2.aux	\
+	design.aux	\
+	c-gen.aux	\
+	c-lib.aux	\
+	c++-gen.aux	\
+	c++-lib.aux	\
+	meta.aux	\
+	tcl.aux		\
+	editor.aux	\
+	idl-gen.aux	\
+	ttab.aux	\
+	modifying.aux	\
+	future-work.aux	\
+	asn1-defs.aux	\
+	coding.aux	\
+	makefile.aux
+
+side		= \
+	$(AUX)	\
+	snacc.toc
+
+side.cmp	= \
+	snacc.aux~	\
+	version.aux~	\
+	intro-1.1.aux~	\
+	intro-1.2.aux~	\
+	design.aux~	\
+	c-gen.aux~	\
+	c-lib.aux~	\
+	c++-gen.aux~	\
+	c++-lib.aux~	\
+	meta.aux~	\
+	tcl.aux~	\
+	editor.aux~	\
+	idl-gen.aux~	\
+	ttab.aux~	\
+	modifying.aux~	\
+	future-work.aux~\
+	asn1-defs.aux~	\
+	coding.aux~	\
+	makefile.aux~	\
+	snacc.toc~
+
+BIB_SRC		= snacc.bib corba.bib tcl.bib
+BIB_BBL		= snacc.bbl
+
+EPS	= \
+	example.eps	\
+	recur.eps	\
+	selbox.eps	\
+	simple.eps	\
+	struct.eps	\
+	str-popup.eps	\
+	list-popup.eps	\
+
+DVI		= snacc.dvi
+A4.PS		= snacc-a4.ps
+A5.PS		= snacc-a5.ps
+A6.PS		= snacc-a6.ps
+BOOK.PS		= snacc-book.ps
+
+DISTFILES	= \
+	makefile	\
+	tumble.sed	\
+	$(MANUALS.1)	\
+	$(MANUALS.n)	\
+	$(TEX_SRC)	\
+	$(BIB_SRC)	\
+	$(A5.PS)
+
+#-------------------------------------------------------------------------------
+
+default::	a4
+#default::	$(A5.PS) $(BOOK.PS)
+all::		a4 a5 a6 book
+
+book::		$(BOOK.PS)
+$(BOOK.PS):	$(A4.PS) tumble.sed
+		$(REASON)
+		< $< $(PSBOOK) | $(PSNUP) -2 | sed -f tumble.sed > $@~
+		mv $@~ $@
+
+a5::		$(A5.PS)
+$(A5.PS):	$(A4.PS)
+		$(REASON)
+		< $< $(PSNUP) -2 > $@~
+		mv $@~ $@
+
+a6::		$(A6.PS)
+$(A6.PS):	$(A4.PS)
+		$(REASON)
+		< $< $(PSNUP) -4 > $@~
+		mv $@~ $@
+
+a4::		$(A4.PS)
+$(A4.PS):	$(DVI)
+		$(REASON)
+#		$(DVIPS) -f $< > $@~
+#		mv $@~ $@
+# dvips doesn't return a useful return code:
+		$(DVIPS) -f $< > $@
+#		$(PSPREVIEW) $@
+
+dvi::		$(DVI)
+$(DVI):		$(TEX_SRC) $(BIB_BBL) $(side.cmp) $(EPS)
+		$(REASON)
+		trap "$(RM) $@ `basename $(TEX_ROOT) .tex`.aux" 2; $(LATEX) $(TEX_ROOT) || { e=$$?; $(RM) $@ `basename $(TEX_ROOT) .tex`.aux; exit $$e; }
+		for f in $(side); do\
+		  if cmp $$f $$f~; then\
+		    :;\
+		  else\
+		    cp $$f $$f~;\
+		  fi;\
+		done
+		$(MAKE) $(BIB_BBL) $@
+
+$(BIB_BBL):	$(BIB_SRC) $(side.cmp)
+		$(REASON)
+		if [ -s snacc.aux ]; then $(BIBTEX) `basename $(TEX_ROOT) .tex`; fi
+
+$(side.cmp) redo:
+		touch $@
+
+version.tex:	#$(TOP)/version.h
+		echo '\def\snaccversion{'`sed -e '/VERSION/!d' -e 's/.*"\(.*\)".*/\1/' -e q $?`'}' > $@
+
+spell::		sp_errs
+sp_errs:	$(TEX_SRC)
+		$(REASON)
+		$(DETEX) $(TEX_ROOT) | $(SPELL) > $@~
+		mv $@~ $@
+
+install-sh:
+		ln $(TOP)/install-sh $@
+
+$(man1dir):
+		$(TOP)/mkinstalldirs $@
+
+install::	$(MANUALS) install-sh $(man1dir)
+
+install::
+		for man in $(MANUALS.1); do\
+		  $(INSTALL_DATA) $$man $(man1dir)/`basename $$man .1`.$(man1ext);\
+		done
+		for man in $(MANUALS.n); do\
+		  $(INSTALL_DATA) $$man $(man1dir)/`basename $$man .n`.$(mannext);\
+		done
+
+clean::
+		$(RM) *~ *.dvi *.log *.aux *.toc *.lof *.lot *.bbl *.blg sp_errs .emacs*
+
+clobber::	clean
+
+clobber::
+		$(RM) *.ps
+
+gen-distfiles::	$(DISTFILES)
+
+distfiles::
+		echo $(DISTFILES)
+
+# dummy:
+depend::
+		@true
diff --git a/SecuritySNACCRuntime/doc/makefile.tex b/SecuritySNACCRuntime/doc/makefile.tex
new file mode 100644
index 00000000..08c5eb9f
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/makefile.tex
@@ -0,0 +1,121 @@
+% file: .../doc/makefile.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/makefile.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: makefile.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:53  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:49  rj
+% first check-in
+%
+
+\chapter{\label{makefile-sect}Makefiles}
+
+Some of Snacc's makefiles look rather sophisticated.
+This section explains some of the tricks.
+
+\section{CVS, Dependencies and Make's Include Statement}
+
+The makefiles take advantage of the file inclusion feature.
+Since this has already been supported by UNIX System III\footnote{yes, System III, not System V R3} make (somewhen around 1980), I consider it to be pretty portable.
+If your make is crippled, either use a newer one (e.g. GNU make), or as a last resort, remove (better: comment out) the include statements and call make with the additional arguments {\ufn -f .../makehead -f makefile -f dependencies -f .../maketail}.
+
+Snacc's configuration script generates the file {\ufn makehead} which gets included by all makefiles.
+It contains a lot of definitions used by make.
+
+The dependencies have been moved out of each makefile into a separate file called {\ufn dependencies} that is not under cvs control---otherwise, the makefiles would inflate the repository unnecessarily.
+The makefiles have an include statement for their dependencies file.
+GNU make automatically makes the dependencies if the file does not exist, but other versions of {\ufn make} simply give up.
+In that case, an initial (empty) file has to be generated.
+Snacc's top level makefile does this for you if you call {\ufn make depend}.
+
+A third file that is included by almost every makefile is {\ufn \dots/maketail}.
+It holds the rules that are common to all makefiles where C/C++ code is compiled.
+
+\section{Circular Dependencies}
+
+In a normal makefile rule, a file depends upon other files.
+If any of a file's dependencies is newer, the file is remade.
+This goes well as long as the dependency graph is non-circular, but snacc is compiled from some files it has generated itself.
+This recursion can lead to one of two results: in the worse case, {\ufn make} builds the compiler because its source files are newer, builds the source files because the compiler is newer, builds the compiler because some source files are newer, and so on ad infinitum\dots{}
+Even if this endless recursion does not happen, one or two of the above steps will be made every time {\ufn make} is called.
+To avoid this waste of time, one lets the compiler generate a new source file, but when the new and the old version are identical, the old file is kept and {\ufn make} sees that the compiler is up-to-date, and the recursion is terminated.
+Of course, if the source file's contents did change, it is replaced with the new version.
+
+This is a simplified example of a normal makefile:
+
+\begin{Makefile}
+snacc:		\>tbl.h\\
+		\>\emph{compile} snacc\\
+\\
+tbl.h:		\>snacc tbl.asn1\\
+		\>./snacc \dots{} tbl.asn1\\
+\end{Makefile}
+
+Most {\ufn make} versions will complain and print a warning about this `infinite loop' or `circular dependency'.
+The first approach towards a solution could be:
+
+\begin{Makefile}
+snacc:		\>tbl.h\\
+		\>\emph{compile} snacc\\
+\\
+tbl.h:		\>snacc tbl.asn1\\
+		\>mv tbl.h tbl.h.prev\\
+		\>./snacc \dots{} tbl.asn1\\
+		\>if cmp tbl.h.prev tbl.h; then\char`\\\\
+		\>\>  echo "tbl.h hasn't changed";\char`\\\\
+		\>\>  mv tbl.h.prev tbl.h;\char`\\\\
+		\>else\char`\\\\
+		\>\>  \$(RM) tbl.h.prev;\char`\\\\
+		\>fi\\
+\end{Makefile}
+
+The effect is that you keep snacc from being remade if the contents of tbl.h did not change, but the two steps to create tbl.h and to test whether it is different from tbl.h.prev will be made every time snacc or tbl.asn1 are newer than tbl.h, which they most often will be since few of the changes to snacc will affect tbl.h's contents.
+And {\ufn make} will still complain about the recursion.
+To solve all this, another file, a stamp file is introduced.
+It separates the file's contents from its modification time:
+
+\begin{Makefile}
+snacc:		\>tbl.h\\
+		\>\emph{compile} snacc\\
+\\
+stamp-tbl:	\>snacc tbl.asn1\\
+		\>mv tbl.h tbl.h.prev\\
+		\>./snacc \dots{} tbl.asn1\\
+		\>if cmp tbl.h.prev tbl.h; then\char`\\\\
+		\>\>  echo "tbl.h hasn't changed";\char`\\\\
+		\>\>  mv tbl.h.prev tbl.h;\char`\\\\
+		\>else\char`\\\\
+		\>\>  \$(RM) tbl.h.prev;\char`\\\\
+		\>fi\\
+		\>date > \$@\\
+\\
+tbl.h:		\>stamp-tbl\\
+		\>@true\\
+\end{Makefile}
+
+The dummy command in the rule for tbl.h is necessary, since otherwise, despite stamp-tbl commands having modified tbl.h, many versions of make think that tbl.h has not been modified.
+
+If you want {\ufn tbl.h} to be remade (e.g. you have changed an option to snacc), you must delete {\ufn stamp-tbl}---{\ufn tbl.h} may (and should) be left in place.
+
+The rules in {\ufn \dots/compiler/makefile}, {\ufn \dots/c-lib/makefile} and {\ufn \dots/c++-lib/makefile} are further complicated by the fact that
+\begin{enumerate}
+  \item snacc prints the current time into the file which the comparison must take into account
+  \item if snacc has not been built it cannot be used to generate its source files---a bootstrapping version of snacc's source files has got to be supplied.
+\end{enumerate}
+
+\section{Compiling Different Libraries From One Set Of Source Files}
+
+The different libraries in {\ufn \dots/c-lib/} and {\ufn \dots/c++-lib/} get made by means of recursive calls to make with different macro settings.
+This keeps the makefiles short as it avoids a lot of duplication of file lists and rules which would be a hassle to maintain.
+The different libraries get compiled from the same set of source files, the code to be compiled is determined through {\ufn cpp} (C preprocessor) macro switches.
+
+\section{Configuration, Optional Code and Makefiles}
+
+The {\ufn \dots/configure} script looks for Tcl/Tk.
+If they are absent, there is no use in trying to compile Snacc's Tcl interface.
+For makefiles to detect whether the Tcl interface should be compiled or not, there is a file {\ufn \dots/tcl-p.c} that, after being compiled into {\ufn tcl-p}, exits with 0 (the shells' `true' value) if Tcl/Tk is present and the user has not disabled this option by setting {\C NO\_TCL} in {\ufn \dots/policy.h} to {\C 1}.
+{\ufn tcl-p} gets made automatically.
diff --git a/SecuritySNACCRuntime/doc/meta.tex b/SecuritySNACCRuntime/doc/meta.tex
new file mode 100644
index 00000000..e5930473
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/meta.tex
@@ -0,0 +1,670 @@
+% file: .../doc/meta.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/meta.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: meta.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:53  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:38  rj
+% first check-in
+%
+
+\chapter{\label{meta-chapter}The Metacode}
+
+%-----------------------------------------------------------------------------------------------------------------------------------
+\section{\label{intro-meta-section}Introduction}
+
+When you call snacc, during its compilation, the text in the {\ufn .asn1} files gets turned into e.g. C++ classes.
+Names become identifiers, and after the C++ compilation, the user program has no more access to the original module and type names, only to pointers and the bits and bytes of the classes' contents.
+
+The metacode remedies this.
+Using it, a program can access the modules, their types, their subtypes and the named values via strings.
+Generic programs do not have to know any of the modules' or types' names---all the information can be traversed starting at a single well-known place.
+
+The metacode has to map strings (``component {\C "name"} in type {\C "Person"} in ASN.1 module {\C "Mail"}'') into the in-core address of the indicated object.
+Moreover, using the metacode, a generic program has to be able to traverse all modules, types and their components to learn about their names and types.
+Given the name of a type, the metacode must be able to return a newly allocated object instance.
+
+The metacode is an extension to the Snacc compiler's C++ backend and the C++ runtime library.
+
+Since the metacode relies heavyly on the virtual function call mechanism, it is only implemented for the C++ backend.
+
+A number of functions has been added to the C++ runtime library.
+All code extensions have been wrapped into preprocessor conditionals.
+Currently, only one or two libraries are made in {\ufn \dots/c++-lib/}, one with neither metacode nor Tcl interface, and an optional additional one with both extensions.
+If you cannot or do not want to (as stated in {\ufn \dots/policy.h}) use the metacode or the Tcl interface, Snacc will be compiled without it, and only the normal library will get made.
+
+If you want to use the metacode but not the Tcl interface, you have got to change the makefile to compile another set of {\ufn .o} files in a directory you may want to name {\ufn \dots/c++-lib/meta/} and archive the resulting files in {\ufn libasn1meta.a}.
+Compile with {\ufn -DMETA=1 -DTCL=0}.
+
+%-----------------------------------------------------------------------------------------------------------------------------------
+\section{Implementation}
+
+%leftover:----------------
+With the metacode, the strings and the ASN.1 type components' type information are stored in arrays, one per structured ASN.1 type.
+The type descriptions are listed in another array, one per ASN.1 module.
+
+In the C++ code generated by snacc, every ASN.1 type is represented by a C++ class.
+These C++ classes for ASN.1 simple types are implemented in the runtime library, and for structured types they are generated by the backend.
+The metacode is an extension to all of those C++ classes.
+The metacode put into every C++ class is very similar:
+\begin{itemize}
+  \item a static {\C \_desc} member is always present.
+  \item simple types with names (ENUMERATED, INTEGER, BIT STRING) get an additional static {\C \_nmdescs[]} member.
+    The array is exclusively referenced from {\C \_desc}.
+    The array provides the bidirectional mapping of symbolic and numeric values.
+  \item structured types with members (SET, SEQUENCE, CHOICE) get an additional static {\C \_mdescs[]} member.
+    The array is exclusively referenced from {\C \_desc}.
+    The array references the components' type descriptions (their {\C \_desc} data members).
+  \item every class gets a virtual {\C \_getref()} function.
+    Its only purpose is to return the address of {\C \_desc}\footnote{
+      This sounds as if virtual data members were a nice idea, and in fact they are.
+      The C++ standards committees are currently discussing this.
+    %  Of course, there are not a lot of compilers already implementing this feature.
+    }.
+  \item structured types with members (SET, SEQUENCE, CHOICE) get an additional virtual {\C \_getref()} function.
+    This function provides the member name to member address mapping.
+\end{itemize}
+The data members are {\C static}, and therefore get instantiated exactly once per executable, not once per class object instance.
+
+To get an impression, let us have a look at an example:
+The two ASN.1 types
+\begin{ASNcode}
+File ::= SET\\
+\{\+\\
+  name [0] PrintableString,\\
+  contents [1] OCTET STRING,\\
+  checksum [2] INTEGER OPTIONAL,\\
+  read-only [3] BOOLEAN DEFAULT FALSE\-\\
+\}\\
+\\
+Directory ::= SET\\
+\{\+\\
+  name PrintableString,\\
+  files SET OF File\-\\
+\}
+\end{ASNcode}
+
+get turned into two individual C++ classes:
+
+\begin{Ccode}
+class File: public AsnType\\
+\{\\
+public:\+\\
+  PrintableString               \>\>name;\\
+  AsnOcts               \>\>contents;\\
+  AsnInt                \>\>*checksum;\\
+  AsnBool               \>\>*read\_only;\\
+\\
+\<\#if META\\
+  static const AsnSetTypeDesc   \>\>\_desc;\\
+  static const AsnSetMemberDesc \>\>\_mdescs[];\\
+  const AsnTypeDesc             \>\>*\_getdesc() const;\\
+  AsnType                       \>\>*\_getref (const char *membername, bool create = false);\\
+\<\#endif // META\\
+\\
+  // \dots other functions omitted\dots\-\\
+\};\\
+\\
+class Directory: public AsnType\\
+\{\\
+public:\+\\
+  PrintableString               \>\>name;\\
+  DirectorySetOf                \>\>files;\\
+\\
+\<\#if META\\
+  static const AsnSetTypeDesc   \>\>\_desc;\\
+  static const AsnSetMemberDesc \>\>\_mdescs[];\\
+  const AsnTypeDesc             \>\>*\_getdesc() const;\\
+  AsnType                       \>\>*\_getref (const char *membername, bool create = false);\\
+\<\#endif // META\\
+\\
+  // \dots other functions omitted\dots\\
+\<\};
+\end{Ccode}
+
+The above definitions stem from the {\ufn .h} file, the following code is taken from the {\ufn .C} file.
+Only the code for the {\ASN Directory} type is shown, because the code for the {\ASN File} type looks very similar.
+
+\begin{Ccode}
+\#if META\\
+\\
+static AsnType *createDirectory()\\
+\{\\
+  \>return new Directory;\\
+\}\\
+\\
+const AsnSetMemberDesc Directory::\_mdescs[] =\\
+\{\+\\
+  AsnSetMemberDesc ("name", \&PrintableString::\_desc, false), // `name'\\
+  AsnSetMemberDesc ("files", \&DirectorySetOf::\_desc, false), // `files'\\
+  AsnSetMemberDesc()\-\\
+\};\\
+\\
+const AsnSetTypeDesc Directory::\_desc\\
+(\+\\
+  \&EdEx\_StructuredModuleDesc,\\
+  "Directory", // `Directory'\\
+  true,\\
+  AsnTypeDesc::SET,\\
+  createDirectory,\\
+  \_mdescs\-\\
+);\\
+\\
+const AsnTypeDesc *Directory::\_getdesc() const\\
+\{\\
+  \>return \&\_desc;\\
+\}\\
+\\
+AsnType *Directory::\_getref (const char *membername, bool create)\\
+\{\+\\
+  if (!strcmp (membername, "name"))\\
+    \>return \&name;\\
+  if (!strcmp (membername, "files"))\\
+    \>return \&files;\\
+  return NULL;\-\\
+\}\\
+\\
+\#endif // META
+\end{Ccode}
+
+The two ASN.1 types get turned into two individual C++ classes, but their {\C \_desc} members point to two different instances of the same type.
+The C++ backend generates an individual C++ class for every structured ASN.1 type.
+The metacode is different: 
+The types of the descriptions data members ({\C \_desc}, {\C \_nmdesc} and {\C \_mdesc}) despend on the \emph{general} ASN.1 type (i.e. e.g. {\ASN SET}, not {\ASN File}).
+
+
+
+
+
+
+
+%leftover:----------------
+Every {\ufn .asn1} file contains an ASN.1 module and gets translated into a {\ufn .C} file that contains an array that lists all the module's type descriptions.
+
+Snacc generates an additional file {\ufn modules.C} that contains an array that lists all the module descriptions.
+This single top level array provides the well known entry point for the whole module and type hierarchy.
+%leftover:----------------
+
+
+
+
+
+The type of the {\C \_desc} member differs depending on the ASN.1 type it describes.
+The different {\C \_desc} types mirror the {\C AsnType} class hierarchy.
+For example, the ASN.1 BOOLEAN type is mapped into a C++ class called {\C AsnBool} and is described by a C++ class {\C AsnBoolTypeDesc}.
+The root of the {\C \_desc} class hierarchy is called {\C AsnTypeDesc} and looks as follows
+(taken from {\ufn \dots/c++-lib/inc/meta.h}):
+\begin{Ccode}
+struct AsnTypeDesc\\
+\{\+\\
+  const AsnModuleDesc		\>\>*module;\\
+  const char			\>\>*const name;	// NULL for basic types\\
+  const bool			\>\>pdu;\\
+  const enum Type \qquad // NOTE: keep this enum in sync with the typenames[]\\
+  \{\+\\
+    VOID,\\
+    ALIAS,\\
+\\
+    INTEGER,\\
+    REAL,\\
+    NUL\_, // sic! (can't fight the ubiquitous NULL \#define)\\
+    BOOLEAN,\\
+    ENUMERATED,\\
+    BIT\_STRING,\\
+    OCTET\_STRING,\\
+    OBJECT\_IDENTIFIER,\\
+\\
+    SET,\\
+    SEQUENCE,\\
+    SET\_OF,\\
+    SEQUENCE\_OF,\\
+    CHOICE,\\
+    ANY,\-\\
+  \}				\>\>type;\\
+\\
+  static const char		\>\>*const typenames[];\\
+\\
+				\>\>AsnTypeDesc (const AsnModuleDesc *, const char *,\\
+					\`bool ispdu, AsnType *(*create)(), Type);\\
+\\
+  AsnType			\>\>*(*create)();\\
+\\
+  virtual const AsnModuleDesc	\>\>*getmodule() const;\\
+  virtual const char		\>\>*getname() const;\\
+  virtual bool			\>\>ispdu() const;\\
+  virtual Type			\>\>gettype() const;\\
+  virtual const AsnNameDesc	\>\>*getnames() const;\\
+  %//virtual const AsnMemberDesc	\>\>*getmembers() const;\\
+\\
+\<\#if TCL\\
+  virtual int			\>\>TclGetDesc (Tcl\_DString *) const;\\
+  virtual int			\>\>TclGetDesc2 (Tcl\_DString *) const;\-\\
+\#endif\\
+\};\\
+\\
+typedef AsnTypeDesc		\>\>\>AsnRealTypeDesc;\\
+typedef AsnTypeDesc		\>\>\>AsnNullTypeDesc;\\
+typedef AsnTypeDesc		\>\>\>AsnBoolTypeDesc;\\
+\\
+typedef AsnTypeDesc		\>\>\>AsnOctsTypeDesc;\\
+typedef AsnTypeDesc		\>\>\>AsnOidTypeDesc;
+\end{Ccode}
+
+{\C AsnTypeDesc}'s data members provide the following information:
+\begin{description}
+  \item[\textnormal{The} {\C module}] data member points to the module description described at the end of this chapter in section~\ref{meta-modules-sect}.
+
+  \item[\textnormal{The} {\C name}] is either the type's name as used by the backend code (default, or if snacc was called with the {\ufn -mC} switch) or the type's given names as defined in the {\ufn .asn1} file (if snacc has been called with the {\ufn -mA} command line option).
+    Section~\ref{naming-C++-section} on page~\pageref{naming-C++-section} explains the differences.
+    (For example, the backend code sometimes has an additional number tacked to the name---you can see the effect in figure~\ref{snacced-example} on page~\pageref{snacced-example}.)
+    The generated source code contains the respective counterpart printed in a comment.
+
+  \item[\textnormal{The} {\C pdu}] flag is set to {\C true} iff the type was listed after snacc's {\ufn -meta} or {\ufn -tcl} switch.
+
+  \item[\textnormal{The} {\C type}] member is used as an index into the {\C typenames} array---the virtual function call mechanism obliviates the use for any {\C switch} statements.
+
+  \item[\textnormal{The} {\C create}] data member points to a global function that returns a pointer to a newly allocated object of the description type's mirror type, that is, gives you an instance for the generic description.
+    It is the counterpart to the {\C AsnType}'s {\C \_getdesc} function which goes in the opposite direction, from the object instance to its generic description.
+    The {\C AsnType}'s {\C Clone} function serves a similar purpose as the {\C AsnTypeDesc}'s {\C create} function.
+\end{description}
+
+The {\C AsnTypeDesc} class is the only class in the hierarchy that has got the {\C module}, {\C name}, {\C pdu} and {\C type} data members, and {\C AsnNamesTypeDesc} the only class to implement a {\C names} data member.
+Therefore, unlike {\C \_getdesc()} mentioned above, the five virtual functions {\C getmodule}, {\C getname}, {\C ispdu}, {\C gettype} and {\C getnames} are not meant to implement some kind of virtual data members, but help to implement the alias type description functionality described in section~\ref{meta-aliases}.
+
+As you can see looking at the last five code lines with the {\C typedef}s, the five ASN.1 simple types REAL, NULL, BOOLEAN, OCTET STRING and OBJECT IDENTIFIER are directly described by instances of this class.
+The other types, having either named values or components, are more demanding and have their own classes derived from {\C AsnTypeDesc}.
+
+%-----------------------------------------------------------------------------------------------------------------------------------
+\subsection{Named Values}
+
+Some basic ASN.1 types allow values to be named, namely INTEGER, ENUMERATED and BIT STRING.
+The accompanying description types contain arrays listing the names and values.
+The virtual function {\C getnames()} returns this array.
+The respective C++ classes in the runtime library contain an {\C AsnNameDesc \_nmdescs[]} array, the address of which is given to the type descriptions constructor as last argument.
+
+\begin{Ccode}
+struct AsnNameDesc\\
+\{\+\\
+  const char			\>\>*const name;\\
+  const long int		\>\>value;\-\\
+\};\\
+\\
+struct AsnNamesTypeDesc: AsnTypeDesc\\
+\{\+\\
+  const AsnNameDesc		\>\>*const names;\\
+\\
+				\>\>AsnNamesTypeDesc (const AsnModuleDesc *, const char *,\\
+					\`bool ispdu, AsnType *(*create)(), Type, const AsnNameDesc *);\\
+\\
+  const AsnNameDesc		\>\>*getnames() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetDesc (Tcl\_DString *) const;\\
+  // for BIT STRING and INTEGER, ENUMERATED has its own:\\
+  int				\>\>TclGetDesc2 (Tcl\_DString *) const;\-\\
+\#endif\\
+\};\\
+\\
+struct AsnEnumTypeDesc: AsnNamesTypeDesc\\
+\{\\
+  \>				\>\>AsnEnumTypeDesc (const AsnModuleDesc *, const char *,\\
+					\`bool ispdu, Type, AsnType *(*create)(), const AsnNameDesc *);\\
+\\
+\#if TCL\\
+  \>int				\>\>TclGetDesc2 (Tcl\_DString *) const;\\
+\#endif\\
+\};\\
+\\
+typedef AsnNamesTypeDesc	\>\>\>AsnIntTypeDesc;\\
+typedef AsnNamesTypeDesc	\>\>\>AsnBitsTypeDesc;
+\end{Ccode}
+
+The ENUMERATED type gets its own description class because the Tcl interface for ENUMERATED types behaves differently than for the INTEGER and BIT STRING types.
+
+As for {\C AsnTypeDesc::name} above, the content of {\C AsnNameDesc::name} is either the value's name as used by the backend code (default, or if snacc was called with the {\ufn -mC} switch) or the value's name as given in the {\ufn .asn1} file (if snacc has been called with the {\ufn -mA} command line option).
+The generated source code contains the respective counterpart printed in a comment.
+
+\subsection{Types with Members}
+
+The ASN.1 types CHOICE, SET and SEQUENCE are defined in terms of other types, their so-called components.
+The ASN.1 components map into C++ data members.
+
+The three ASN.1 structured types get mapped into C++ classes that contain an {\C Asn\dots{}MemberDesc \_mdescs[]} array (with the `{\C \dots}' replaced by `{\C Choice}' `{\C Set}' or `{\C Sequence}').
+The address of this array is given to the description type's constructor as last argument.
+The elements of this array point to the descriptions of the data classes data members.
+This is similar to the named values above, only the integral value has been replaced by a pointer to a type description.
+
+\begin{Ccode}
+struct AsnMemberDesc // description of CHOICE member; base class for AsnSe\_MemberDesc\\
+\{\+\\
+  const char			\>\>*const name;\\
+  const AsnTypeDesc		\>\>*const desc;\\
+\\
+				\>\>AsnMemberDesc (const char *, const AsnTypeDesc *);\\
+				\>\>AsnMemberDesc();\\
+\\
+\<\#if TCL\\
+  virtual int			\>\>TclGetDesc (Tcl\_DString *) const;\\
+  virtual int			\>\>TclGetDesc2 (Tcl\_DString *) const;\-\\
+\#endif\\
+\};\\
+\\
+struct AsnSe\_MemberDesc: AsnMemberDesc\qquad// \_ == t/quence; description of SET or SEQUENCE member\\
+\{\+\\
+  bool				\>\>optional;\\
+\\
+				\>\>AsnSe\_MemberDesc (const char *, const AsnTypeDesc *, bool);\\
+				\>\>AsnSe\_MemberDesc();\\
+\-\\
+\#if TCL\\
+  \>int				\>\>TclGetDesc2 (Tcl\_DString *) const;\\
+\#endif\\
+\};\\
+\\
+typedef AsnMemberDesc		\>\>\>AsnChoiceMemberDesc;\\
+typedef AsnSe\_MemberDesc	\>\>\>AsnSetMemberDesc;\\
+typedef AsnSe\_MemberDesc	\>\>\>AsnSequenceMemberDesc;\\
+\\
+struct AsnMembersTypeDesc: AsnTypeDesc\\
+\{\+\\
+				\>\>AsnMembersTypeDesc (const AsnModuleDesc *, const char *,\\
+					\`bool ispdu, AsnType *(*create)(), Type);\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetDesc (Tcl\_DString *) const;\-\\
+\#endif\\
+\};\\
+\\
+struct AsnChoiceTypeDesc: AsnMembersTypeDesc\\
+\{\+\\
+  const AsnChoiceMemberDesc	\>\>*const members;\\
+\\
+				\>\>AsnChoiceTypeDesc (const AsnModuleDesc *, const char *,\\
+					\`bool ispdu, AsnType *(*create)(), Type, const AsnChoiceMemberDesc *);\\
+\\
+  int				\>\>choicebyname (const char *name) const;\\
+  const char			\>\>*choicebyvalue (int value) const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetDesc2 (Tcl\_DString *) const;\-\\
+\#endif\\
+\};\\
+\\
+struct AsnSe\_TypeDesc: AsnMembersTypeDesc\qquad// \_ == t/quence\\
+\{\+\\
+  const AsnSe\_MemberDesc	\>\>*const members;\\
+\\
+				\>\>AsnSe\_TypeDesc (const AsnModuleDesc *, const char *,\\
+					\`bool ispdu, AsnType *(*create)(), Type, const AsnSe\_MemberDesc *);\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetDesc2 (Tcl\_DString *) const;\-\\
+\#endif\\
+\};\\
+\\
+typedef AsnSe\_TypeDesc		\>\>\>AsnSetTypeDesc;\\
+typedef AsnSe\_TypeDesc		\>\>\>AsnSequenceTypeDesc;
+\end{Ccode}
+
+As for {\C AsnTypeDesc::name} above, the content of {\C AsnMemberDesc::name} is either the member's name as used by the backend code (default, or if snacc was called with the {\ufn -mC} switch) or the component's name as defined in the {\ufn .asn1} file (if snacc has been called with the {\ufn -mA} command line option).
+The generated source code contains the respective counterpart printed in a comment.
+In case the ASN.1 component was not given a name, the backend's member name is used instead.
+
+The data classes have a member function called {\C \_getref}, that allows the C++ class members to be accessed by their name.
+{\C \_getref()} is the second metacode function and it is present in all C++ classes representing composed ASN.1 types.
+
+A class for a SET contains the following code fragment:
+\begin{Ccode}
+class FooSet: public AsnType\+\\
+  AsnInt	\>\>bar; // an example data member\\
+  \dots // lots of member functions\\
+\<\#if META\\
+  static const AsnSetTypeDesc   \>\>\_desc;\\
+  static const AsnSetMemberDesc \>\>mdescs[];\\
+  const AsnTypeDesc             \>\>*\_getdesc() const;\\
+  AsnType                       \>\>*\_getref (const char *membername, bool create = false);\\
+\<\#if TCL\\
+  int                \>\>TclGetDesc (Tcl\_DString *) const;\\
+  int                \>\>TclGetVal (Tcl\_Interp *) const;\\
+  int                \>\>TclSetVal (Tcl\_Interp *, const char *valstr);\\
+  int                \>\>TclUnsetVal (Tcl\_Interp *, const char *membername);\-\\
+\#endif // TCL \\
+\#endif // META\\
+\};
+\end{Ccode}
+
+{\C \_getref()}'s {\C bool} parameter {\C create} determines whether a non-existing member should be returned as a {\C NULL} pointer or whether it should instead be allocated and its address be returned.
+This parameter is used by value reading and writing routines to implement their different member access semantics.
+
+The following four assignments are equivalent:
+\begin{Ccode}
+FooSet foo;\\
+foo.bar = 1;\\
+*(AsnInt *)foo.\_getref ("bar") = 1;\\
+foo.bar.TclSetVal (interp, "1");\\
+foo.\_getref ("bar")-->TclSetVal (interp, "1");
+\end{Ccode}
+{\C TclSetVal()} is a virtual member function and therefore no cast from {\C AsnType~*} to {\C AsnInt~*} is required.
+The Tcl interface will be described in chapter~\ref{tcl-if-chapter}.
+
+The C++ classes that represent CHOICE types contain an {\C enum ChoiceIdEnum} that allows {\C \_getref()} to be written using a {\C switch} statement.
+The functions {\C choicebyname()} and {\C choicebyvalue()} turn the component's name into its enumeration value and vice versa.
+(The enum has not been introduced with the metacode, it is used by Snacc's encoding and printing functions as well.)
+
+\subsection{\label{meta-list}SET OF and SEQUENCE OF}
+
+The list description behaves like an ASN.1 simple type's---the description type is derived directly from the type descriptions' base class and does not redefine any of the metacode functions:
+
+\begin{Ccode}
+struct AsnListTypeDesc: AsnTypeDesc\\
+\{\+\\
+  const AsnTypeDesc		\>\>*const base;\\
+\\
+  				\>\>AsnListTypeDesc (const AsnModuleDesc *, const char *,\\
+					\`bool ispdu, Type, AsnType *(*create)(), const AsnTypeDesc *);\-\\
+\\
+\#if TCL\\
+  \>int				\>\>TclGetDesc (Tcl\_DString *) const;\\
+\#endif\\
+\};
+\end{Ccode}
+
+The {\C TclGetDesc} function merely adds the base type's standard type description (module and type name, pdu flag and type) after its own, so that a programmer may take the base type's name and ask the metacode once again for the base type's full description.
+
+A list type's data class on the other hand has got a {\C \_getref()} function that gives access to the list's elements and it can be used to insert new elements at any desired position.
+
+\subsection{\label{meta-aliases}Aliases}
+
+For ASN.1 types being defined as a direct copy of another type, snacc in normal operation uses a C++ {\C typedef} to define the C++ type.
+Since this {\C typedef} makes the two types totally equivalent, the metacode has no chance to preserve the two types' different names and thus, this contruct cannot be used.
+A new C++ class has got to be defined instead.
+
+Example: the following ASN.1 code snippet\dots
+\begin{ASNcode}
+Int1 ::= INTEGER \{ foo(42) \}\\
+Int2 ::= Int1
+\end{ASNcode}
+\dots maps into the following C++ definitions:
+\begin{Ccode}
+class Int1: public AsnInt\\
+\{\\
+public:\+\\
+                        \>\>Int1(): AsnInt() \{\}\\
+                        \>\>Int1 (int i): AsnInt (i) \{\}\\
+  enum\\
+  \{\\
+    \>foo = 42\\
+  \};\\
+\\
+\<\#if META\\
+  static const AsnNameDesc      \>\>\_nmdescs[];\\
+  static const AsnIntTypeDesc   \>\>\_desc;\\
+  const AsnTypeDesc     \>\>*\_getdesc() const;\-\\
+\#endif // META\\
+\};\\
+\\
+\#if META\\
+struct Int2: public Int1\\
+\{\+\\
+                        \>\>Int2(): Int1() \{\}\\
+                        \>\>Int2 (int i): Int1 (i) \{\}\\
+  AsnType               \>\>*Clone() const;\\
+\\
+  static const AsnAliasTypeDesc \>\>\_desc;\\
+  const AsnTypeDesc     \>\>*\_getdesc() const;\-\\
+\};\\
+\\
+\#else // META\\
+\\
+typedef Int1 \>\>\>Int2;\\
+\\
+\#endif // META
+\end{Ccode}
+
+The descriptor type's definition points to the reference type:
+
+\begin{Ccode}
+struct AsnAliasTypeDesc: AsnTypeDesc\\
+\{\+\\
+  const AsnTypeDesc		\>\>*const alias;\\
+\\
+				\>\>AsnAliasTypeDesc (const AsnModuleDesc *, const char *,\\
+					\`bool ispdu, AsnType *(*create)(), Type, const AsnTypeDesc *);\\
+\\
+  const AsnModuleDesc		\>\>*getmodule() const;\\
+  const char			\>\>*getname() const;\\
+  bool				\>\>ispdu() const;\\
+  Type				\>\>gettype() const;\\
+  const AsnNameDesc		\>\>*getnames() const;\\
+  %//const AsnMemberDesc		\>\>*getmembers() const;\\
+\\
+\<\#if TCL\\
+  int				\>\>TclGetDesc (Tcl\_DString *) const;\-\\
+\#endif\\
+\};
+\end{Ccode}
+
+The {\C AsnAliasTypeDesc} is the reason for the five virtual functions from {\C getmodule} to {\C getnames} defined in both {\C AsnTypeDesc} and {\C AsnNamesTypeDesc} on the one hand and {\C AsnAliasTypeDesc} on the other hand.
+While the alias type belongs to a different module or has another type name, and it may have another {\C pdu} flag value, its type and names array values are those of its reference type.
+Therefore, {\C AsnAliasTypeDesc}'s first three functions of return the description's own values, and the latter two call their reference type's functions.
+
+The {\C getnames} function has to be defined in the hierarchy's base class because the aliases may be defined for any type of type, not only for types with named values.
+
+\subsection{\label{meta-any}ANY (DEFINED BY)}
+
+ANY DEFINED BY is quite problematic.
+The ASN.1 Book \cite{ASN.1Book} calls it ``a rather half-baked attempt at solution''.
+Since snacc has problems with it---the user has to modify the snacc generated code---and none of our applications requires this construct, no effort has been made to implement it.
+
+ANY itself on the other hand would be quite simple to implement---the virtual function call mechanism that is used to implement the ANY type is the basis for the metacode as well.
+But again, since we have no need for the ANY type, it is as far unimplemented.
+Besides that, according to the ASN.1 book, the ``use of ANY without the DEFINED BY construct is ``deprecated'' (frowned upon) by the standard''.
+The next ASN.1 standard will probably not have the ANY type any more.
+In the 1993 draft standard \cite{asn1:1993}, ANY and ANY DEFINED BY can be found in ``Annex I: Superseded features'', Section 3: ``The any type''.
+% Macros can be found in this annex as well.
+
+\subsection{\label{meta-modules-sect}Modules}
+
+Every {\ufn .C} file (that corresponds to an {\ufn .asn1} file, or, an ASN.1 module), gets an array that lists all the module's types.
+This array contains pointers to all the {\C \_desc} members of all classes of a module.
+
+\begin{Ccode}
+struct AsnModuleDesc\\
+\{\+\\
+  const char			\>\>*const name;\\
+  const AsnTypeDesc		\>\>**const types;\-\\
+\};\\
+\\
+extern const AsnModuleDesc	\>\>\>*asnModuleDescs[];
+\end{Ccode}
+
+The modules themselves are listed in yet another array, the declaration of which is shown in the preceeding line.
+This array has got its own source file named {\ufn modules.C}.
+This array allows all modules to be found, and every type that is defined for these modules.
+
+%-----------------------------------------------------------------------------------------------------------------------------------
+\section{Efficiency}
+
+The metacode is designed with efficiency in mind.
+The metacode is intended for interpreted interfaces and therefore does not need to be highly optimized.
+On the other hand, the same object code should be useable for normal (non-metacode) tasks without loss of performance.
+
+\subsection{Normal Operation}
+
+The metacode does not significantly affect the normal mode of operation.
+The static data members {\C \_mdescs} and {\C \_desc} do not increase the class instances' size.
+The virtual function tables, which have already been present (they are used for the ANY type), get a little longer, but since these tables exist only once for every class, this difference is neglible.
+The class instances reference their virtual function table with a pointer, and so the metacode does not introduce any change here.
+Except for alias types, the C++ classes generated are exactly the same.
+The metacode introduces a new class for alias types, but since no new data members are introduced their size stays the same; only the virtual function table pointer is different.
+
+All normal member functions (constructor, destructor, assignment operator, encode, decode and print functions) are identical---with only one exception: if the metacode is compiled to be usable by the Tcl interface, the constructors initialize their mandatory members.
+
+To sum it up, both code and data grow, but except for a longer loading time from disk and an increased probability for cache misses, the code will run as fast as it does without the metacode.
+
+\subsection{Metacode}
+
+The metacode routines are kept quite simple.
+Intended to be used in conjunction with a Tcl interface, speed was not the most important concern.
+Consequently, the code is optimized more towards memory usage than run time efficiency.
+As an example, name to member resolution uses a linear lookup strategy instead of more elaborated algorithms like binary search or hash tables.
+I think for data types that typically have up to a dozen components, more sophisticated algorithms would have been overkill.
+
+A typical object file gets almost 20\% larger due to the metacode (the Tcl interface adds another 25\%).
+
+%-----------------------------------------------------------------------------------------------------------------------------------
+\section{\label{meta-ttab-comparison}Metacode Vs. Type Tables}
+
+Here's a list of both the type tables' (see chapter~\ref{ttab-chapter}) and the metacode's (dis)advantages:
+\begin{itemize}
+
+  \item source code language:
+  \begin{itemize}
+    \item[$-$] The type tables are implemented for C only.
+    \item[$-$] The metacode works only for C++.
+  \end{itemize}
+
+  \item speed:
+  \begin{itemize}
+    \item[$-$] Encoding and decoding using the type tables is said to be about 4 times slower than using the C routines.
+    \item[$+$] The metacode does not (significantly) harm performance.
+  \end{itemize}
+
+  \item code size:
+  \begin{itemize}
+    \item[$+$] The tables are a lot smaller than the compiled routines.
+    \item[$-$] The metacode makes the compiled code even larger.
+  \end{itemize}
+
+  \item value constants:
+  \begin{itemize}
+    \item[$-$] The type tables lack the values defined in the {\ufn .asn1} files.
+    \item[$+$] The metacode interacts fine with these values.
+  \end{itemize}
+
+  \item named values:
+  \begin{itemize}
+    \item[$-$] The type tables lack the named values defined ENUMERATED, INTEGER and BIT STRING types.
+    \item[$+$] The metacode interacts fine with these names.
+  \end{itemize}
+
+  \item compatibility to normal snacc code:
+  \begin{itemize}
+    \item[$-$] The C structures defined by mkchdr and used by the type table encoding and decoding routines and the C structures defined by snacc's C backend are quite different.
+    \item[$\pm$] Where the backend's structures generated for SEQUENCE contain madatory members by value, the type table's structures contain only pointer members!
+  \end{itemize}
+
+\end{itemize}
+
+%-----------------------------------------------------------------------------------------------------------------------------------
+\section{\label{metacode-setup}Setup for the Metacode Generator}
+
+To compile Snacc with the metacode generator, the following condition must be met:
+\begin{itemize}
+  \item either the configure script must be able to find {\ufn tclsh} and the Tcl/Tk libraries or you have to insert a {\C \#define META 1} into {\ufn \dots/policy.h}
+  \item the {\C NO\_META} preprocessor macro in {\ufn \dots/policy.h} must not be set
+\end{itemize}
diff --git a/SecuritySNACCRuntime/doc/misc-hyph.tex b/SecuritySNACCRuntime/doc/misc-hyph.tex
new file mode 100644
index 00000000..cac4b328
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/misc-hyph.tex
@@ -0,0 +1,23 @@
+% file: .../doc/misc-hyph.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/misc-hyph.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: misc-hyph.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:53  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:27  rj
+% first check-in
+%
+
+\hyphenation{
+  snacc-path
+  Asn-Type
+  Asn-Type-Desc
+  ostream
+  nmdescs
+  mdescs
+  desc
+}
diff --git a/SecuritySNACCRuntime/doc/mkchdr.1 b/SecuritySNACCRuntime/doc/mkchdr.1
new file mode 100644
index 00000000..1752b476
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/mkchdr.1
@@ -0,0 +1,60 @@
+.\" Copyright (c) 1993 by Mike Sample and UBC
+.\" See section COPYING for conditions for redistribution
+.\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/mkchdr.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+.\" $Log: mkchdr.1,v $
+.\" Revision 1.1.1.1  2001/05/18 23:14:10  mb
+.\" Move from private repository to open source repository
+.\"
+.\" Revision 1.1.1.1  1999/03/16 18:05:53  aram
+.\" Originals from SMIME Free Library.
+.\"
+.\" Revision 1.2  1997/01/01 22:47:18  rj
+.\" first check-in
+.\"
+.TH MKCHDR 1 "11 July 1993"
+.SH NAME
+mkchdr \- creates a C header file from a type table
+.SH SYNOPSIS
+.nf
+mkchdr <tbl-file> [output-file]
+.SH DESCRIPTION
+mkchdr will generate a C header file from the given type table.  The C
+data structures will be written to the given output file.  If an
+output file is not given, the C header is written to stdout.
+
+The generated C data structure is the value representation that table
+driven encoder expects (and decoder returns) for the type definitions
+in the given type table.  The table driven encoder and decoder, etc.
+routines do not use the generated header - they treat the data in a
+generic way.  The generated header file simply saves you the hassle of
+dealing with ASN.1 values in the same generic way.  Instead you get
+properly named structs and field names.  You do not need to use mkchdr
+to use the table driven encoders etc. but it is recommended.
+.PP
+.\" there is a tab between the file name and the description
+.SH FILES
+.PD 0
+.TP 28
+.B snacc/tbl-tools/mkchdr/
+Source code for the mkchdr program
+.PD
+.SH BUGS
+There is no means of customizing the generated data structure.
+.SH COPYING
+Copyright (c) 1993 Mike Sample and the University of British Columbia
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+.SH AUTHOR
+Mike Sample <msample@cs.ubc.ca>, University of British Columbia
+.SH ACKNOWLEDGEMENTS
+This work was made possible by grants from the Canadian Institute for
+Telecommunications Research (CITR) and Natural Sciences and
+Engineering Research Council of Canada (NSERC).
diff --git a/SecuritySNACCRuntime/doc/modifying.tex b/SecuritySNACCRuntime/doc/modifying.tex
new file mode 100644
index 00000000..6f47c76c
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/modifying.tex
@@ -0,0 +1,49 @@
+% file: .../doc/modifying.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/modifying.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: modifying.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:54  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:44  rj
+% first check-in
+%
+
+\chapter{\label{modifying-chapter}Modifying the Compiler}
+
+The compiler consists of about 30,000 lines of yacc, lex and C code
+(another 7,000+ for the runtime library routines).  The best way to
+understand the compiler internals is to understand the module data
+structure ({\ufn \dots/compiler/core/asn1module.h}) and to read the compiler
+chapter in this document to gain a conceptual understanding of each
+pass of the compiler.
+
+The most common form of modification will likely be for macro
+handling.  To understand this, look at the way the OBJECT-TYPE macro is
+treated in:
+\begin{description}
+\item[lex-asn1.l] {add any new keywords}
+\item[parse-asn1.y] { parse the macro into the desired data structure.
+Use the existing productions as much as possible.}
+\item[link-type.c] { link any type defined or referenced in the
+macro}
+\item[link-values.c] { link any value defined or referenced in the
+macro}
+\item[do-macros.c] { perform any semantic action for the macro }
+
+\item[normalize.c] { move any type and value definitions in the macro
+to the top level so the code generator can generate code for them
+(without looking in the macro).}
+
+\item[code generators] { to convert any special semantics into useful
+C or C++.  This phase is likely to be dependent on the generated
+code's target environment.}
+\end{description}
+
+In general I have tried to put comments where funky things happen and
+to use function and variable names that are meaningful.  However,
+things may get ugly in certain places.  Thesis writing is harmful to
+your coding style!
diff --git a/SecuritySNACCRuntime/doc/ptbl.1 b/SecuritySNACCRuntime/doc/ptbl.1
new file mode 100644
index 00000000..8f38827f
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/ptbl.1
@@ -0,0 +1,64 @@
+.\" Copyright (c) 1993 by Mike Sample and UBC
+.\" See section COPYING for conditions for redistribution
+.\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/ptbl.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+.\" $Log: ptbl.1,v $
+.\" Revision 1.1.1.1  2001/05/18 23:14:10  mb
+.\" Move from private repository to open source repository
+.\"
+.\" Revision 1.1.1.1  1999/03/16 18:05:54  aram
+.\" Originals from SMIME Free Library.
+.\"
+.\" Revision 1.2  1997/01/01 22:47:19  rj
+.\" first check-in
+.\"
+.TH PTBL 1 "11 July 1993"
+.SH NAME
+ptbl \- print a type table
+.SH SYNOPSIS
+.nf
+ptbl [\-a] <tbl-file>
+.SH DESCRIPTION
+
+ptbl prints the give type table to stdout.  It will print it in one of
+two formats: internal style and ASN.1 stlye.  The internal style shows
+the contents of the type table data structure in ASN.1 value notation.
+You will need to look at the tbl.asn1 file to understand the internal
+form.  The ASN.1 form attempts to re-create the ASN.1 that generated
+the given type table.
+
+.SH OPTIONS
+
+.TP
+.B \-a
+Print the table in ASN.1 style (recommended)
+.PP
+.\" there is a tab between the file name and the description
+.SH FILES
+.PD 0
+.TP 28
+.B snacc/tbl-tools/ptbl/
+Source code for the ptbl program
+.B snacc/asn1specs/tbl.asn1
+ASN.1 definition for the type table data structure
+.PD
+.SH BUGS
+ptbl does not attempt to print the IMPORTs information even though it
+is possible with a bit of work.
+.SH COPYING
+Copyright (c) 1993 Mike Sample and the University of British Columbia
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+.SH AUTHOR
+Mike Sample <msample@cs.ubc.ca>, University of British Columbia
+.SH ACKNOWLEDGEMENTS
+This work was made possible by grants from the Canadian Institute for
+Telecommunications Research (CITR) and Natural Sciences and
+Engineering Research Council of Canada (NSERC).
diff --git a/SecuritySNACCRuntime/doc/pval.1 b/SecuritySNACCRuntime/doc/pval.1
new file mode 100644
index 00000000..403e6e78
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/pval.1
@@ -0,0 +1,63 @@
+.\" Copyright (c) 1993 by Mike Sample and UBC
+.\" See section COPYING for conditions for redistribution
+.\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/pval.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+.\" $Log: pval.1,v $
+.\" Revision 1.1.1.1  2001/05/18 23:14:10  mb
+.\" Move from private repository to open source repository
+.\"
+.\" Revision 1.1.1.1  1999/03/16 18:05:54  aram
+.\" Originals from SMIME Free Library.
+.\"
+.\" Revision 1.2  1997/01/01 22:47:20  rj
+.\" first check-in
+.\"
+.TH PVAL 1 "11 July 1993"
+.SH NAME
+pval \- print BER values in ASN.1 value notation
+.SH SYNOPSIS
+.nf
+pval \-T <tt file name> [\-m <module name>] \-n <type name>
+             <BER value file list>
+.SH DESCRIPTION
+pval prints the given BER values in their value notation.  You must
+specify the type name and optionally the module name of the type in
+the given BER files.
+.SH OPTIONS
+.TP
+.BI "\-T " file\c
+Use the type table in the file to look for the named types definition.
+.TP
+.BI "\-m " modulename\c
+Specifies the module in which the named type is defined.  If the
+module name is not specified with this option, pval looks for the
+first occurence of the named type in the modules in the given type
+table.
+.TP
+.BI "\-n " typename\c
+Specifies the type of the values in the given BER files.  If you
+give the wrong type name, decoding errors will occur.
+.PP
+.\" there is a tab between the file name and the description
+.SH FILES
+.PD 0
+.TP 28
+.B snacc/tbl-tools/pval/
+Source code for the pval program
+.SH COPYING
+Copyright (c) 1993 Mike Sample and the University of British Columbia
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+.SH AUTHOR
+Mike Sample <msample@cs.ubc.ca>, University of British Columbia
+.SH ACKNOWLEDGEMENTS
+This work was made possible by grants from the Canadian Institute for
+Telecommunications Research (CITR) and Natural Sciences and
+Engineering Research Council of Canada (NSERC).
diff --git a/SecuritySNACCRuntime/doc/snacc.1 b/SecuritySNACCRuntime/doc/snacc.1
new file mode 100644
index 00000000..a6b50235
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/snacc.1
@@ -0,0 +1,305 @@
+.\" Copyright (c) 1993 by Mike Sample and UBC
+.\" See section COPYING for conditions for redistribution
+.\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacc.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+.\" $Log: snacc.1,v $
+.\" Revision 1.1.1.1  2001/05/18 23:14:10  mb
+.\" Move from private repository to open source repository
+.\"
+.\" Revision 1.1.1.1  1999/03/16 18:05:54  aram
+.\" Originals from SMIME Free Library.
+.\"
+.\" Revision 1.3  1997/02/16 15:26:26  rj
+.\" made return *this after calling abort()'' a compile time option.
+.\"
+.\" Revision 1.2  1997/01/01 22:47:16  rj
+.\" first check-in
+.\"
+.TH SNACC 1 "11 July 1993"
+.SH NAME
+snacc \- ASN.1 to C, C++ or type table Compiler
+.SH SYNOPSIS
+.nf
+snacc [\-h] [\-P] [\-t] [\-e] [\-d] [\-p] [\-f]\p
+      [\-c | \-C | \-idl | \-T <table output file>]\p
+      [\-u <useful types ASN.1 file>]\p
+      [\-mf <max file name len>]\p
+      [\-l <neg number>]\p
+      [\-meta] [\-tcl <module.type>]\p
+      [\-novolat]\p
+      <ASN.1 file list>
+.SH
+For complete and current documentation, refer to the snacc manual.
+.I
+.SH DESCRIPTION
+Snacc (Sample Neufeld Asn.1 to C/C++ Compiler) generates C or C++
+source code for BER encode and decode routines as well as print and
+free routines for each type in the given ASN.1 modules.
+Alternatively, snacc can produce type tables that can be used for
+table based/interpreted encoding and decoding.  The type table based
+methods tend to be slower than their C or C++ counterparts but they
+usually use less memory (table size vs. C/C++ object code).
+
+Most of the 1990 ASN.1 features are parsed although some do not affect
+the generated code.  Fairly rigourous error checking is performed on
+the ASN.1 source; any errors detected will be reported (printed to
+stderr).
+
+Each file in the ASN.1 file list should contain a complete ASN.1
+module.  ASN.1 modules that use the IMPORTS feature must be compiled
+together (specify all necessary modules in the ASN.1 file list).  The
+generated source files will include each module's header file in the
+command line order.  This makes it important to order the modules from
+least dependent to most dependent on the command line to avoid type
+ordering problems. Currently, snacc assumes that each ASN.1 file
+given on the command line depends on all of the others on the command
+line.  No attempt is made to only include the header files from
+modules referenced in the import list for that module.
+
+If the target language is C, snacc will generate a \c
+.B .h
+and
+.B .c
+file for each specified ASN.1 module.  If the target language is C++,
+snacc will generate a
+.B .h
+and
+.B .C
+file for each module.  The generated file names will be derived from the
+module names.
+
+.SH OPTIONS
+
+.TP
+.B \-h
+Help. Prints a synopsis of snacc and exits.
+.TP
+.B \-c
+Generate C source code.  This is the default behaviour of snacc.
+Only one of \c
+.B \-c
+,
+.B \-C
+or
+.B \-T
+should be specified.
+.TP
+.B \-C
+Generate C++ source code.
+.TP
+.B \-novolat
+Generate ``return *this'' after calling ``abort()''.
+(Some broken compilers don't know about volatile functions, or their abort() isn't correctly typed.)
+.TP
+.B -meta
+Generate meta code that describes the generated types.
+Implies -C.
+.TP
+.B -tcl
+.IR module.type [, module.type ]
+Generate code for a Tcl interpreter where \fImodule.type\fP are the top level PDUs.
+Implies -meta.
+.TP
+.BI "\-T " file\c
+This causes snacc to generate type tables and write them to the given
+file.
+.TP
+.B \-P
+This causes snacc to print the parsed ASN.1 modules to stdout after
+the types have been linked, sorted, and processed.  This option is
+useful for debugging snacc and observing the modifications snacc
+performs on the types to make code generation simpler.
+.TP
+.B \-t
+Generate type definitions in the target language for each ASN.1 type.
+.TP
+.B \-v
+Generate value definitions in the target language for each ASN.1 value.
+Currently value definitions are limited to INTEGERs, BOOLEANs and
+OBJECT IDENTIFIERs.
+.TP
+.B \-e
+Generate encode routines in the target language for each ASN.1 type.
+.TP
+.B \-d
+Generate decode routines in the target language for each ASN.1 type.
+.TP
+.B \-p
+Generate print routines in the target language for each ASN.1 type.
+.TP
+.B \-f
+Generate free routines in the target language for each ASN.1 type.
+This option only works when the target language is C.
+
+If none of the
+.B \-t, \-v, \-e, \-d, \-p, or \-f
+options are given on
+the command line, snacc assumes that all of them are in effect.
+They do not affect type table generation.
+.TP
+.BI "\-u " file\c
+\&Read the useful types definitions from the ASN.1 module in file \c
+.I file\c
+\& for linking purposes.  For some ASN.1 specifications, such as SNMP,
+the useful types are not needed. The types in the given useful types
+file are globally available to all modules; a useful type definition
+is overridden by a local or explicitly imported type with the same
+name.  The current list of useful types is:
+.RS 9
+ObjectDecscriptor
+.br
+NumericString
+.br
+PrintableString
+.br
+TeletexString
+.br
+T61String
+.br
+VideoTexString
+.br
+IA5String
+.br
+GraphicString
+.br
+ISO646String
+.br
+GeneralString
+.br
+UTCTime
+.br
+GeneralizedTime
+.br
+EXTERNAL
+.RE
+.TP
+.BI "\-mf " number\c
+\&This causes the generated source files to have a
+maximum length of \c
+.I number\c
+ characters, including their suffix.  The \c
+.I number\c
+ must be at least 3.  This option is useful for supporting operating
+systems that only support short file names.  A better solution is to
+shorten the module name of each ASN.1 module.
+
+.TP
+.BI "\-l " number\c
+\&This is fairly obscure but may be useful.  Each error that the
+decoders can report is given an id number.  The number \c
+.I number\c
+ is where the error ids start decreasing from as they are assigned to
+errors .  The default is -100 if this option is not given.  Avoid
+using a number in the range -100 to 0 since they may conflict with the
+library routines' error ids.  If you are re-compiling the useful types
+for the library use -50.  Another use of this option is to integrate
+newly generated code with older code; if done correctly, the error ids
+will not conflict.
+
+.PP
+.\" there is a tab between the file name and the description
+.SH FILES
+.PD 0
+.TP 28
+.B snacc/asn1specs/asn-useful.asn1
+ASN.1 useful types module (use with \-u option)
+.TP
+.B snacc/c-lib/inc/
+C runtime library include files
+.TP
+.B snacc/c-lib/libasn1csbuf.a
+C SBuf runtime library
+.TP
+.B snacc/c-lib/libasn1cmbuf.a
+C MinBuf runtime library
+.TP
+.B snacc/c-lib/libasn1cebuf.a
+C ExpBuf runtime library
+.TP
+.B snacc/c++-lib/inc/
+C++ runtime library include files
+.TP
+.B snacc/c++-lib/libasn1c++.a
+C++ runtime library
+.TP
+.B snacc/c-lib/inc/tbl*/
+Type table runtime library include files
+.TP
+.B snacc/c-lib/libasn1ctbl.a
+Type table runtime library
+.TP
+.B snacc/tbl-tools/
+Source code for table based tools (mkchdr, ptbl, pval)
+.TP
+.B snacc/c-examples/
+directory with ASN.1 to C examples
+.TP
+.B snacc/c++-examples/
+directory with ASN.1 to C++ examples
+.TP
+.B snacc/tbl-example
+directory with an ASN.1 to type table example
+.TP
+.B snacc/doc
+directory with snacc documentation and this man page
+.PD
+.SH BUGS
+Snacc has problems with the following case:
+.RS
+.nf
+
+Foo ::= SEQUENCE
+{
+    id IdType,
+    val ANY DEFINED BY id
+}
+
+IdType ::= CHOICE
+{
+    a INTEGER,
+    b OBJECT IDENTIFIER
+}
+
+.fi
+.RE
+The error checking pass will print an error to the effect that the id
+type must be INTEGER or OBJECT IDENTIFER.  To fix this you must modify
+the error checking pass as well as the code generation pass.  To be
+cheap about it, disable/fix the error checking and hand modify the
+generated code.
+
+The hashing code used for handling ANY DEFINED BY id to type mappings
+will encounter problems if the hash table goes more than four levels
+deep (I think this is unlikely).  To fix this just add linear chaining
+at fourth level.
+
+Please send bug reports or comments to
+.\".BR snacc-bugs@cs.ubc.ca .
+.BR "Robert Joop <rj@rainbow.in-berlin.de>" .
+See the documentation about reporting bugs and (lack of) support.
+.SH COPYING
+Copyright (c) 1993 Mike Sample and the University of British Columbia
+.br
+Copyright (c) 1994 1995 Robert Joop and GMD Fokus.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+The snacc compiler is released under the GNU General Public License.
+The runtime libraries are no longer under the GNU Library General
+Public License.  The generated code is yours.
+.SH AUTHOR
+Snacc was written by Mike Sample at the University of British Columbia
+(UBC).  He used it as a tool to do encoding/decoding performance
+research.
+.PP
+It was augmented by Robert Joop at GMD Fokus with the help of some of its project partners.
+.SH ACKNOWLEDGEMENTS
+This work was made possible by grants from the Canadian Institute for
+Telecommunications Research (CITR) and Natural Sciences and
+Engineering Research Council of Canada (NSERC).
diff --git a/SecuritySNACCRuntime/doc/snacc.bib b/SecuritySNACCRuntime/doc/snacc.bib
new file mode 100644
index 00000000..8112ac66
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/snacc.bib
@@ -0,0 +1,269 @@
+% file: .../doc/snacc.bib
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacc.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: snacc.bib,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:54  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:50  rj
+% first check-in
+%
+
+@article{CASN1,
+   author = "Gerald Neufeld and Yeuli Yang",
+   title = "An ASN.1 to C Compiler",
+   journal = "IEEE Transactions on Software Engineering",
+   year = "1990",
+   month = "Oct",
+   volume = "16",
+   number = "10",
+   pages = "1209-1220",
+   key = "CASN1",
+   keywords = "ASN.1 Compiler"
+}
+
+
+@inbook{X.208,
+   author = "CCITT",
+   title = "Data Communications Networks Open systems Interconnection (OSI) Model and Notation, Service Defintion",
+   chapter = "Recommendation X.208, Specification of Abstract Syntax
+Notation One (ASN.1)",
+   pages = "57-130",
+   publisher = "Omnicom",
+   year = "1989",
+   month = "November",
+   address = "115 Park St., S.E., Vienna, VA 22180 USA",
+   series = "Blue Book",
+   number = "Fascicle VIII.4",
+   keywords = "ASN.1"
+}
+
+@inbook{X.209,
+   author = "CCITT",
+   title = "Data Communications Networks Open systems Interconnection (OSI) Model and Notation, Service Defintion",
+   chapter = "Recommendation X.209, Specification of Basic Encoding
+Rules for Abstract Syntax Notation One (ASN.1)",
+   pages = "130-151",
+   publisher = "Omnicom",
+   year = "1989",
+   month = "November",
+   address = "115 Park St., S.E., Vienna, VA 22180 USA",
+   series = "Blue Book",
+   number = "Fascicle VIII.4",
+   keywords = "BER"
+}
+
+
+
+@manual{ISODE,
+   title = "ISODE, The ISO Development Environment: User Manual",
+   author = "Marshall T. Rose",
+   organization = "Wollongong Group",
+   address = "1129 San Antonio Rd. Palo Alto, California, USA",
+   year = "1990",
+   month = "February"
+}
+
+
+
+
+@book{68881,
+   author = "Motorola Inc.",
+   title = "MC68881 Floating-Point Coprocessor User's Manual",
+   publisher = "Motorola Inc.",
+   year = "1985",
+   pages = "2-9 to 2-15",
+   key = "68881"
+}
+
+
+
+@book{ASN.1Book,
+   author = "Douglas Steedman",
+   title = "ASN.1, The Tutorial and Reference",
+   publisher = "Technology Appraisals Ltd.",
+   year = "1990",
+   note = "ISBN 1 871802 06 7"
+}
+
+@article{ASN.1Overview,
+   author = "Gerald Neufeld and Son Vuong",
+   title = "An Overview of ASN.1",
+   journal = "IEEE Networks and ISDN Systems",
+   year = "1992",
+   month = "Feb",
+   volume = "23",
+   number = "5",
+   pages = "393-415"
+}
+
+
+
+@article{Sample93-1,
+   author = "Michael Sample and Gerald Neufeld",
+   title = "Implementing Efficient Encoders and Decoders for Network Data Representations",
+   journal = "IEEE INFOCOM '93 Proceedings",
+   year = "1993",
+   month = "Mar",
+   volume = "3",
+   pages = "1144-1153",
+   key = "Sample93-2",
+   ms-label = "Sample93-2"
+}
+
+
+
+@mastersthesis{Sample93-2,
+   author = "Michael Sample",
+   title = "How Fast Can ASN.1 Encoding Rules Go?",
+   school = "University of British Columbia",
+   year = "1993",
+   month = "April",
+   address = "Vancouver, B.C. Canada V6T 1Z2"
+}
+
+
+@article{TCPOverhead,
+   author = "David D. Clark and Van Jacobson and John Romkey and Howard Salwen",
+   title = "An Analysis of TCP Processing Overhead",
+   journal = "IEEE Communications Magazine",
+   year = "1989",
+   month = "June",
+   pages = "23-29"
+}
+
+@article{NewProts,
+   author = "David D. Clark and David L. Tennenhouse",
+   title = "Architectural Considerations for a New Generation of Protocols",
+   journal = "SIGCOMM '90",
+   year = "1990",
+   month = "Sept",
+   volume = "20",
+   number = "4",
+   pages = "200-208"
+}
+
+
+
+
+@inbook{X.500,
+   author = "CCITT",
+   title = "",
+   chapter = "Recommendation X.500, OSI:Specification of the
+Distributed Directory System",
+   pages = "131-151",
+   publisher = "Omnicom",
+   year = "1989",
+   month = "November",
+   address = "115 Park St., S.E., Vienna, VA 22180 USA",
+   series = "Blue Book",
+   number = "Fascicle VIII.8",
+   keywords = "X.500, Distributed, Directory"
+}
+
+
+
+
+@article{lwer,
+   author = "Christian Huitema and Assem Doghri",
+   title = "Defining Faster Transfer Syntaxes for the OSI Presentation Layer",
+   journal = "Sigcomm Computer Communication Review",
+   year = "1989",
+   month = "Oct",
+   volume = "19",
+   number = "5"
+}
+
+
+@article{ASN1Perf,
+   author = "Christian Huitema and Ghislain Chave",
+   title = "Measuring the Performances fo an ASN.1 Compiler",
+   journal = "Upper Layer Protocols, Architechtures and Applications",
+   year = "1992",
+   month = "May",
+   pages = "99-112"
+}
+
+@inbook{X.400,
+   author = "CCITT",
+   title = "Data Communicatio Networks Message Handling Systems",
+   chapter = "Recommendation X.400-X.420, Message Handling Systems",
+   pages = "57-130",
+   publisher = "Omnicom",
+   year = "1989",
+   month = "November",
+   address = "115 Park St., S.E., Vienna, VA 22180 USA",
+   series = "Blue Book",
+   number = "Fascicle VIII.7",
+   keywords = "ASN.1"
+}
+
+
+
+@book{X.400,
+   author = "CCITT",
+   title = "Data Communication Networks Message Handling Systems,
+Recommendations X.400-X.420",
+   publisher = "Omnicom",
+   year = "1989",
+   month = "Nov",
+   address = "115 Park St., S.E., Vienna, VA 22180 USA",
+   series = "Blue Book",
+   number = "Fascicle VIII.7"
+}
+
+
+@book{stroustrup,
+   author = "Bjarne Stroustrup",
+   title = "The C++ Programming Language, 2nd Edition",
+   publisher = "Addison-Wesley Publishing Co.",
+   year = "1991",
+   note = "ISBN 0201539926"
+}
+
+@misc{snmp,
+   author = "M. Rose and K. McCloghrie",
+   title = "Structure and Identification of Management Information for TCP/IP-based Internets (RFC 1155)",
+   howpublished = "Network Information Center, SRI International",
+   month = "May",
+   year = "1990",
+}
+
+@book{tnhd,
+  title = "The New Hacker's Dictionary",
+  editor = "Eric Raymond",
+  publisher = "The MIT Press, Cambridge, Mass, London, England",
+  year = 1991,
+  note = "ISBN 0-262-68069-6"
+}
+
+@misc{asn1:1987,
+  author = "ISO",
+  number = "ISO 8824:1987(E)",
+  title = "Information processing systems---Open Systems Interconnection---Specification of Abstract Syntax Notation One (ASN.1)"
+}
+
+@misc{asn1:1993,
+  author = "ISO",
+  number = "ISO/IEC DIS 8824-1",
+  title = "Information technology---Open Systems Interconnection---Abstract Syntax Notation One (ASN.1)"
+}
+
+@misc{ber:1987,
+  author = "ISO",
+  number = "ISO 8825:1987(E)",
+  title = "Information processing systems---Open Systems Interconnection---Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1)"
+}
+
+%project:
+%  Programming Language C++
+@misc{c++-draft,
+  author = "ISO",
+  title = "Working Paper for Draft Proposed International Standard for Information Systems---Programming Language C++",
+  number = "X3J16/95-0087",
+  date = "28 April 1995",
+  month = "28~" # apr, year = 1995,
+}
diff --git a/SecuritySNACCRuntime/doc/snacc.n b/SecuritySNACCRuntime/doc/snacc.n
new file mode 100644
index 00000000..8ced4938
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/snacc.n
@@ -0,0 +1,242 @@
+'\" This manual page, except for the introductory troff macros, is
+'\" Copyright (c) 1995 by Robert Joop.
+'\" 
+'\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacc.n,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+'\" $Log: snacc.n,v $
+'\" Revision 1.1.1.1  2001/05/18 23:14:10  mb
+'\" Move from private repository to open source repository
+'\"
+'\" Revision 1.1.1.1  1999/03/16 18:05:54  aram
+'\" Originals from SMIME Free Library.
+'\"
+'\" Revision 1.1  1997/01/01 22:47:24  rj
+'\" first check-in
+'\"
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" All rights reserved.
+'\"
+'\" Permission is hereby granted, without written agreement and without
+'\" license or royalty fees, to use, copy, modify, and distribute this
+'\" documentation for any purpose, provided that the above copyright
+'\" notice and the following two paragraphs appear in all copies.
+'\"
+'\" IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
+'\" FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+'\" ARISING OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+'\" CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+'\"
+'\" THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+'\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+'\" AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+'\" ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+'\" PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+'\" 
+.\" The definitions below are for supplemental macros used in Tcl/Tk
+.\" manual entries.
+.\"
+.\" .HS name section [date [version]]
+.\"	Replacement for .TH in other man pages.  See below for valid
+.\"	section names.
+.\"
+.\" .AP type name in/out [indent]
+.\"	Start paragraph describing an argument to a library procedure.
+.\"	type is type of argument (int, etc.), in/out is either "in", "out",
+.\"	or "in/out" to describe whether procedure reads or modifies arg,
+.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
+.\"	needed;  use .AS below instead)
+.\"
+.\" .AS [type [name]]
+.\"	Give maximum sizes of arguments for setting tab stops.  Type and
+.\"	name are examples of largest possible arguments that will be passed
+.\"	to .AP later.  If args are omitted, default tab stops are used.
+.\"
+.\" .BS
+.\"	Start box enclosure.  From here until next .BE, everything will be
+.\"	enclosed in one large box.
+.\"
+.\" .BE
+.\"	End of box enclosure.
+.\"
+.\" .VS
+.\"	Begin vertical sidebar, for use in marking newly-changed parts
+.\"	of man pages.
+.\"
+.\" .VE
+.\"	End of vertical sidebar.
+.\"
+.\" .DS
+.\"	Begin an indented unfilled display.
+.\"
+.\" .DE
+.\"	End of indented unfilled display.
+.\"
+'\"	# Heading for Tcl/Tk man pages
+.de HS
+.ds ^3 \\0
+.if !"\\$3"" .ds ^3 \\$3
+.if '\\$2'cmds'       .TH \\$1 1 \\*(^3 \\$4
+.if '\\$2'lib'        .TH \\$1 3 \\*(^3 \\$4
+.if '\\$2'tcl'        .TH \\$1 n \\*(^3 Tcl "Tcl Built-In Commands"
+.if '\\$2'tk'         .TH \\$1 n \\*(^3 Tk "Tk Commands"
+.if '\\$2'tclc'        .TH \\$1 3 \\*(^3 Tcl "Tcl Library Procedures"
+.if '\\$2'tkc'         .TH \\$1 3 \\*(^3 Tk "Tk Library Procedures"
+.if '\\$2'tclcmds'         .TH \\$1 1 \\*(^3 Tk "Tcl Applications"
+.if '\\$2'tkcmds'         .TH \\$1 1 \\*(^3 Tk "Tk Applications"
+.if t .wh -1.3i ^B
+.nr ^l \\n(.l
+.ad b
+..
+'\"	# Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ie !"\\$3"" \{\
+.ta \\n()Au \\n()Bu
+\&\\$1	\\fI\\$2\\fP	(\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1	\\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"	# define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+'\"	# BS - start boxed text
+'\"	# ^y = starting y location
+'\"	# ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"	# BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"	Draw four-sided box normally, but don't draw top of
+.\"	box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"	# VS - start vertical sidebar
+'\"	# ^Y = starting y location
+'\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"	# VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"	# Special macro to handle page bottom:  finish off current
+'\"	# box/sidebar if in box/sidebar mode, then invoked standard
+'\"	# page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"	Draw three-sided box if this is the box's first page,
+.\"	draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"	# DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"	# DE - end display
+.de DE
+.fi
+.RE
+.sp .5
+..
+.\" stupid HS macros hasn't got the right ability!
+.TH snacc n "August 1995" Tcl "Tcl Extensions"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+snacc \- Manipulate BER encoded files
+.SH SYNOPSIS
+\fBsnacc \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command provides several operations on BER encoded files.
+Those files can be created, opened, read, its contents examined and
+manipulated and written to disk, as indicated by the \fIoption\fR.
+The valid options are:
+.TP
+\fBsnacc create \fItype\fR
+.TP
+\fBsnacc open \fItype filename ?flags? ?mode?\fR
+\fBfile \fBdirname \fIname\fR
+
+.SH SEE ALSO
+.IR snacced (1)
+.SH KEYWORDS
+ASN.1, BER, file
diff --git a/SecuritySNACCRuntime/doc/snacc.tex b/SecuritySNACCRuntime/doc/snacc.tex
new file mode 100644
index 00000000..21bd960a
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/snacc.tex
@@ -0,0 +1,172 @@
+% file: .../doc/snacc.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacc.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: snacc.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:54  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:25  rj
+% first check-in
+%
+
+\input{misc-hyph}
+
+% different methods get a backslash:
+%   \verb_\_ -> Courier
+%   \char`\\ -> Times-Roman
+%   $\backslash$ -> math font
+
+% for 2up (2x A5 on A4):
+%\def\fmtsize{12pt}
+%% for A4:
+\def\fmtsize{10pt}
+
+\documentclass[\fmtsize,a4paper,twoside]{report}
+\usepackage{t1enc}
+\usepackage{isolatin1}
+\usepackage{times}
+%\usepackage{latexsym}
+\usepackage{amssymb}
+\usepackage[dvips]{graphicx}
+
+\sloppypar
+
+\newlength{\spacing}
+\setlength{\spacing}{\baselineskip}
+\newcommand{\nspace}[1]{\setlength{\baselineskip}{#1\spacing}}
+\newenvironment{linespacing}[1]{\nspace{#1}}{}
+
+%% myitemize environment---less space between items
+%\newenvironment{myitemize}[0]{\begin{itemize}\nspace{0.5}} {\end{itemize}}
+
+%\setlength{\topmargin}{-.50in}
+%\setlength{\textwidth}{6.0in}
+%\setlength{\textheight}{8.5in}
+%\setlength{\oddsidemargin}{.25in}
+\def\myparindent{0in}
+\setlength{\parindent}{\myparindent}
+\def\myparskip{8pt}
+\setlength{\parskip}{\myparskip}
+%\def\myparsep{\parsep}
+%\def\myitemsep{\itemsep}
+
+\input{misc-defs}
+
+\include{version}
+
+\begin{document}
+\thispagestyle{empty}
+\title{Snacc 1.2rj: A High Performance ASN.1 to C/C++/IDL Compiler}
+\author{Michael Sample\\
+        msample@cs.ubc.ca\\\\
+        Department of Computer Science\\
+        University of British Columbia\\
+        6356 Agricultural Rd.\\
+        Vancouver, British Columbia\\
+        Canada, V6T 1Z2\\\\
+	\\
+	augmented by:\\
+	Robert Joop\\
+	$<$rj@rainbow.in-berlin.de$>$}
+%\date{February 1993, updated July 1993,
+%augmented by Robert Joop $<$rj@rainbow.in-berlin.de$>$ 1994/1995}
+\date{msample: February 1993, updated July 1993\\
+rj: 1994/1995\\
+\quad\\
+\emph{Preliminary documentation as of \today\\for Snacc \snaccversion}
+}
+\maketitle
+
+% copyright notice on software and documentation
+
+This work was made possible by grants from the Canadian Institute for
+Telecommunications Research (CITR) and Natural Sciences and
+Engineering Research Council of Canada (NSERC).
+
+Copyright (C) 1990, 1991, 1992, 1993 Michael Sample
+          and the University of British Columbia
+
+Copyright \copyright 1994, 1995 Robert Joop
+	and GMD FOKUS
+
+This program, Snacc, is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The runtime libraries are copyright to the University of British
+Columbia and Michael Sample.  They are free software; you can
+redistribute them and/or modify them as long as the original,
+unmodified copyright information with/in them.  The GNU Library
+Public License has been removed as of version 1.1.
+
+What we're trying to say is: you can't sell the compiler but you can
+sell products that use the code generated by the compiler and the
+runtime libraries.
+
+This program and the associated libraries are distributed in the hope
+that they will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE\@.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License and
+the GNU Library General Public License along with this program; if
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA\@.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+% table of contents
+%\setlength{\parskip}{0pt}
+\tableofcontents
+%\setlength{\parskip}{\myparskip}
+
+% list of figures
+\listoffigures
+
+% list of tables
+%listoftables
+
+\include{intro-1.2}
+\include{intro-1.1}
+
+\include{design}
+
+\include{c-gen}
+\include{c-lib}
+\include{c++-gen}
+\include{c++-lib}
+
+\include{meta}
+\include{tcl}
+\include{editor}
+
+\include{idl-gen}
+
+\include{ttab}
+
+\include{modifying}
+
+\include{future-work}
+
+\appendix
+
+\include{asn1-defs}
+
+\include{coding}
+\include{makefile}
+
+\bibliography{snacc,corba,tcl}
+\bibliographystyle{plain}
+
+\end{document}
diff --git a/SecuritySNACCRuntime/doc/snacced.1 b/SecuritySNACCRuntime/doc/snacced.1
new file mode 100644
index 00000000..eb9220be
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/snacced.1
@@ -0,0 +1,248 @@
+'\" This manual page, except for the introductory troff macros, is
+'\" Copyright (c) 1995 by Robert Joop.
+'\" 
+'\" $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/snacced.1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+'\" $Log: snacced.1,v $
+'\" Revision 1.1.1.1  2001/05/18 23:14:10  mb
+'\" Move from private repository to open source repository
+'\"
+'\" Revision 1.1.1.1  1999/03/16 18:05:54  aram
+'\" Originals from SMIME Free Library.
+'\"
+'\" Revision 1.1  1997/01/01 22:47:21  rj
+'\" first check-in
+'\"
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" All rights reserved.
+'\"
+'\" Permission is hereby granted, without written agreement and without
+'\" license or royalty fees, to use, copy, modify, and distribute this
+'\" documentation for any purpose, provided that the above copyright
+'\" notice and the following two paragraphs appear in all copies.
+'\"
+'\" IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
+'\" FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+'\" ARISING OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+'\" CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+'\"
+'\" THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+'\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+'\" AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+'\" ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+'\" PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+'\" 
+.\" The definitions below are for supplemental macros used in Tcl/Tk
+.\" manual entries.
+.\"
+.\" .HS name section [date [version]]
+.\"	Replacement for .TH in other man pages.  See below for valid
+.\"	section names.
+.\"
+.\" .AP type name in/out [indent]
+.\"	Start paragraph describing an argument to a library procedure.
+.\"	type is type of argument (int, etc.), in/out is either "in", "out",
+.\"	or "in/out" to describe whether procedure reads or modifies arg,
+.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
+.\"	needed;  use .AS below instead)
+.\"
+.\" .AS [type [name]]
+.\"	Give maximum sizes of arguments for setting tab stops.  Type and
+.\"	name are examples of largest possible arguments that will be passed
+.\"	to .AP later.  If args are omitted, default tab stops are used.
+.\"
+.\" .BS
+.\"	Start box enclosure.  From here until next .BE, everything will be
+.\"	enclosed in one large box.
+.\"
+.\" .BE
+.\"	End of box enclosure.
+.\"
+.\" .VS
+.\"	Begin vertical sidebar, for use in marking newly-changed parts
+.\"	of man pages.
+.\"
+.\" .VE
+.\"	End of vertical sidebar.
+.\"
+.\" .DS
+.\"	Begin an indented unfilled display.
+.\"
+.\" .DE
+.\"	End of indented unfilled display.
+.\"
+'\"	# Heading for Tcl/Tk man pages
+.de HS
+.ds ^3 \\0
+.if !"\\$3"" .ds ^3 \\$3
+.if '\\$2'cmds'       .TH \\$1 1 \\*(^3 \\$4
+.if '\\$2'lib'        .TH \\$1 3 \\*(^3 \\$4
+.if '\\$2'tcl'        .TH \\$1 n \\*(^3 Tcl "Tcl Built-In Commands"
+.if '\\$2'tk'         .TH \\$1 n \\*(^3 Tk "Tk Commands"
+.if '\\$2'tclc'        .TH \\$1 3 \\*(^3 Tcl "Tcl Library Procedures"
+.if '\\$2'tkc'         .TH \\$1 3 \\*(^3 Tk "Tk Library Procedures"
+.if '\\$2'tclcmds'         .TH \\$1 1 \\*(^3 Tk "Tcl Applications"
+.if '\\$2'tkcmds'         .TH \\$1 1 \\*(^3 Tk "Tk Applications"
+.if t .wh -1.3i ^B
+.nr ^l \\n(.l
+.ad b
+..
+'\"	# Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ie !"\\$3"" \{\
+.ta \\n()Au \\n()Bu
+\&\\$1	\\fI\\$2\\fP	(\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1	\\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"	# define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+'\"	# BS - start boxed text
+'\"	# ^y = starting y location
+'\"	# ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"	# BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"	Draw four-sided box normally, but don't draw top of
+.\"	box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"	# VS - start vertical sidebar
+'\"	# ^Y = starting y location
+'\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"	# VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"	# Special macro to handle page bottom:  finish off current
+'\"	# box/sidebar if in box/sidebar mode, then invoked standard
+'\"	# page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"	Draw three-sided box if this is the box's first page,
+.\"	draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"	# DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"	# DE - end display
+.de DE
+.fi
+.RE
+.sp .5
+..
+.TH snacced 1 "August 1995" Tk "Tk Applications"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+snacced \- Graphical editor for BER encoded ASN.1 files
+.SH SYNOPSIS
+\fBsnacced \fIoption\fR ?\fImodule type file\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command allowes to browse and edit BER encoded files.
+
+The snacced script needs to be executed by a snaccwish, a Tk shell (see \fIwish\fP(1))
+with additional snacc functionality (see \fIsnacc\fP(n)).
+
+For directions on how to build the snaccwish, please refer to the
+snacc documentation.
+.SH ARGUMENTS
+.TP
+\fBsnacced \fImodule type file\fR
+Open \fIfile\fP that has to be an instance of type \fItype\fP in the ASN.1 module \fImodule\fP.
+.TP
+\fBsnacced \fImodule type\fR
+Create an instance of the given type.
+.TP
+\fBsnacced\fR
+Called without arguments, pops up a file and type selection box.
+.SH SEE ALSO
+.IR wish (1), snacc (n)
+.SH KEYWORDS
+ASN.1, BER, snaccwish, snacc, editor, file
diff --git a/SecuritySNACCRuntime/doc/tcl.bib b/SecuritySNACCRuntime/doc/tcl.bib
new file mode 100644
index 00000000..2edc0f71
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/tcl.bib
@@ -0,0 +1,21 @@
+% file: .../doc/tcl.bib
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/tcl.bib,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: tcl.bib,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:54  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:53  rj
+% first check-in
+%
+
+@book{tcl-book,
+  title = "Tcl and the TK Toolkit",
+  author = "John K. Ousterhout",
+  publisher = "Addison-Wesley Publishing Company",
+  year = 1994,
+  note = "ISBN 0-201-63337-X",
+}
diff --git a/SecuritySNACCRuntime/doc/tcl.tex b/SecuritySNACCRuntime/doc/tcl.tex
new file mode 100644
index 00000000..b5e0ea2d
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/tcl.tex
@@ -0,0 +1,456 @@
+% file: .../doc/tcl.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/tcl.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: tcl.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:54  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:40  rj
+% first check-in
+%
+
+\chapter{\label{tcl-if-chapter}Tcl Interface}
+
+\section{\label{intro-tcl-section}Introduction}
+
+This chapter describes the Snacc's Tcl interface, or: the metacode's link to the outside world.
+
+Tcl is a simple scripting language which the author, John K. Ousterhout, describes in his book titled ``Tcl and the TK Toolkit'' \cite{tcl-book}.
+Tcl's purpose is to be embedded into other applications, to provide a user interface by extending the language.
+Tk, an implementation of the Motif look and feel, is the first and best known extension to Tcl and is described in the same book.
+
+Tcl has got only one data type, the NUL terminated character string.
+Tcl supports other data types like integers and lists, but they are represented as strings.
+A function operating on an integer first converts the string into an integer, performs its operation, converts the resulting value back into another string and returns it to the Tcl interpreter.
+Since lists and even the Tcl procedures are kept as strings, Tcl is rather slow.
+Computations in Tcl should best be kept at a minimum, and all intensive work should be wrapped into C or C++ functions and be made available as Tcl commands.
+
+Since procedures and bodies of loops are kept in string form and parsed for every invocation, comments should be put outside code that is executed \emph{very} often.
+
+From Tcl's point of view, Snacc's Tcl interface is nothing but yet another Tcl extension.
+The Snacc Tcl interface extends the Tcl language by only one command, {\Tcl snacc}.
+The first argument to this command specifies the action to be taken.
+This method is very practical for combining Tcl extensions since it avoids collisions with new command names from other extensions.
+For example, the Tcl core defines an {\Tcl open} command.
+Snacc's Tcl interface wants to offer one as well and has to choose another name.
+This could have been done by naming it {\Tcl snacc\_open}, but I think it is better to stick to Tcl's well established convention and so the Tcl interface's open command became {\Tcl snacc open}.
+To simplify the wording, I will refer to the `snacc subcommands' simply as `commands'.
+
+The usual (non-metacode) snacc generated functions operate on memory buffers containing BER encoded data; they convert them into hierarchical C++ data structures and vice versa.
+
+The Tcl interface is designed to allow controlled fine grained access to this hierarchical C++ data structure, to read and modify its contents.
+While both the C++ code and the Tcl look very similar, for example\dots\\[1ex]
+{\C
+// this is C++ code\\
+x-->foo-->bar = 42;\\[1ex]
+}
+\dots\ and\dots\\[1ex]
+{\Tcl
+\# this is Tcl code\\
+snacc set \{x foo bar\} 42
+}
+
+\dots\ the C++ code gets compiled and the identifiers get turned into pointers and numeric offsets, and the Tcl code gets interpreted and has to mimic the C++ compiler at run time.
+This is what the metacode from chapter~\ref{meta-chapter} is for.
+
+To enable snacc's Tcl code generator, you have to give an additional {\ufn -tcl} option, followed by the list of PDU types.
+The {\ufn -meta} option can (and should) be omitted.
+
+\section{The {\Tcl snacc} Tcl command}
+
+This section explains the Tcl (sub)commands provided by the Snacc extension.
+The commands are grouped in three catagories, commands operating on files (both their external and internal representation), commands accessing the meta information and commands operating on the content itself.
+
+The file commands check the return value from system calls and behave like for example the Tcl {\Tcl open} command, that is, they set the {\Tcl errorCode} variable to {\Tcl POSIX \emph{errno}}, e.g. {\Tcl POSIX ENOENT \{No such file or directory\}}.
+
+The code should be fairly robust, not just against user and programmer errors from `outside' (using the {\Tcl snacc} Tcl command), but against errors from the `inside' as well such as illegal numeric values for enumeration types or illegal choice settings as well.
+
+There are two types of errors:
+\begin{enumerate}
+  \item programmer errors, where the program has no other choice as to print a regret to the user and exit
+  \item user errors, such as trying to write to a read-only file, where the program should tell the user about their mistake and let them try something else.
+\end{enumerate}
+The Tcl interface code helps the programmer for the second type of error by setting Tcl's {\Tcl errorCode} variable.
+The program can {\Tcl catch} any error, and, based on the {\Tcl errorCode}, choose to deal with the mistake or rethrow the error that it is not prepared to handle.
+
+\subsection{File commands}
+
+Most snacc Tcl commands operate on so-called files.
+A file is an internal data structure that
+\begin{itemize}
+  \item references the C++ representation of an ASN.1 data structure as a pointer to {\C AsnType}
+  \item may be associated with an external file in the file system
+\end{itemize}
+
+The commands operating on these files are as follows:
+
+\begin{description}%{
+  \item[{\Tcl snacc create \emph{type}}]
+    The command creates a file consisting only of an instance of type \emph{type}.
+    \emph{type} has to be denoted as one argument, a Tcl list with two elements, module and type.
+    No external filename is associated with this file.
+%    The command returns a file handle that consists of letters and digits only and may therefore be used to construct a component in the Tk widget tree.
+
+  \item[{\Tcl snacc open \emph{type filename} ?\emph{flags}? ?\emph{mode}?}]
+    Open a file and read and decode its contents.
+    \emph{type} has to be denoted as one argument, a list with two elements, module and type.
+    The optional \emph{flags} may consist of:
+    \begin{description}
+      \item[{\Tcl create}] If the file does not exist, create it.
+	If this flag is not given and the file does not already exist, an error occurs.
+      \item[{\Tcl truncate}] If the file exists, drop its contents.
+      \item[{\Tcl \emph{access}}] which may be either {\Tcl ro} or {\Tcl rw}, denoting read only and read/write access.
+	If no access mode is specified, the file will be opened read/write if it is writable, and read only otherwise.
+    \end{description}
+    If the file is created, its mode is set to \emph{mode}, minus umask, of course.
+    \emph{mode} may be any value accepted by {\C Tcl\_GetInt(3)} (the function accepts octal values).
+    At last, if the file could be opened, its contents is read and BER decoded.
+    As for {\Tcl snacc create} above, a file handle is returned.
+
+    If the file cannot be opened, an error is returned identical to Tcl's {\Tcl open} command.
+
+    More errors can be returned, as described under {\Tcl snacc read} below.
+
+  \item[{\Tcl snacc close \emph{file}}]
+    closes the file \emph{file} and invalidates the file handle.
+
+  \item[{\Tcl snacc read \emph{file} ?\emph{type filename}?}]
+    without the \emph{filename}, rereads the file from its old place; otherwise opens \emph{filename}, reads its contents into \emph{file} and closes it.
+    The file's contents gets BER decoded.
+
+    In case no \emph{filename} has been given but the \emph{file} is not associated with a filename, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC MUSTOPEN}.
+
+    If Snacc's decoding routines detect an error, a Tcl error is returned and {\Tcl errorCode} is set to {\Tcl SNACC DECODE \emph{errval}} where \emph{errval} is the value returned by {\C setjmp()} (see sections~\ref{error-C++-section} and~\ref{lib-err-C-section} on pages~\pageref{error-C++-section} and~\pageref{lib-err-C-section}, respectively).
+
+    If the input file is too short, the buffer will signal a read error and a Tcl error will be returned, with {\Tcl errorCode} set to {\Tcl SNACC DECODE EOBUF}.
+
+  \item[{\Tcl snacc write \emph{file} ?\emph{filename}?}]
+    BER encodes the file, then writes the file to its old place in case no \emph{filename} has been given, or opens \emph{filename}, writes \emph{file} into it and closes it.
+
+    In case no \emph{filename} has been given but the \emph{file} is not associated with a filename, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC MUSTOPEN}.
+    If you try to write to a read-only file, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC WRITE READONLY}.
+
+  \item[{\Tcl snacc finfo \emph{file}}]
+    returns a list with two elements, the file name associated with it (the empty string if no external file name is associated with it) and an identifier which may be
+    \begin{description}%{
+      \item[{\Tcl bad}] the file is not associated with an external file.
+      \item[{\Tcl rw}] the external file has been opened read/write.
+      \item[{\Tcl ro}] the external file has been opened read only.
+    \end{description}%}
+\end{description}%}
+
+Since Tcl cannot operate on binary strings (that is, strings containing NUL bytes), but ASN.1 octet strings may contain arbitrary binary data, the binary data has to be converted into a replacement notation that Tcl can work with and that can be converted back to binary without loss of information.
+The conversion I chose is fairly simple: NUL is converted into a backslash followed by a zero digit, and every backslash is doubled.
+
+These conversions for the most part take place automatically.
+In fact, there is only one point where the binary representation is necessary, when you want to read or write data from or into a file on disk.
+Two functions have been written to offer this: the export function converts and writes an octet string to an external file, and the import function reads binary data from a file and converts it to the Tcl compatible representation.
+Unlike the functions described above, these two do not operate on ASN.1 files, that is, the contents is not BER decoded/encoded, but may be used for any file in the file system.
+
+\begin{description}%{
+  \item[{\Tcl snacc import \emph{filename}}] opens the file named, reads its contents, closes it, performs the above described conversion and returns the resulting Tcl string.
+  \item[{\Tcl snacc export \emph{string filename}}] converts the Tcl string into its binary counterpart, opens the file named, writes the binary buffer into it and closes it.
+    The file is created and truncated as necessary.
+    The command returns the empty string.
+\end{description}%}
+
+\subsection{Generic Information Retrieval}
+
+The following functions return information about the modules and their types.
+(This information is independent of any file instance, it is the information from the type descriptions in the {\ufn .asn1} files.)
+
+\begin{description}%{
+  \item[{\Tcl snacc modules}]
+    returns a list of module identifiers.
+  \item[{\Tcl snacc types ?\emph{module}?}]
+    if a \emph{module} is specified, returns a list of all type names of that module.
+    otherwise, a list of all types is returned as a list of pairs, where each pair consists of the module name and the type name.
+  \item[{\Tcl snacc type \emph{type}}]
+    where \emph{type} is a list with two elements, module and type.
+    This command returns a list with the following four elements:
+    \begin{enumerate}%{
+    \setcounter{enumi}{-1}
+      \item the content type as a list consisting of module name and type name
+      \item an identifier that is either {\Tcl pdu} or {\Tcl sub} depending on the list of PDUs that had been given after snacc's {\ufn -tcl} option.
+      \item the ASN.1 type (e.g. INTEGER or CHOICE)
+      \item a list of items that depends on the ASN.1 type:
+      \begin{description}%{
+	\item[INTEGER] a (possibly empty) list of pairs of name and value for each named value.
+	\item[ENUMERATED] a (non-empty) list of names.
+	\item[SET, SEQUENCE \textnormal{and} CHOICE] a list of lists of four elements similar to that being described here.
+	  Element~0 is the subtypes name, then follow content type (a pair consisting of module name and type name), \emph{pdu} vs. \emph{sub} and finally the ASN.1 type.
+	  (The fourth element of the outer list is omitted for obvious reasons: it would explode the type's description.)
+      \end{description}%}
+    \end{enumerate}%}
+\end{description}%}
+
+\subsection{Operations on Content and Structure}
+
+Finally, the last last four functions operate on the file instances itself.
+All four commands get a \emph{path} argument that is constructed as follows:
+\begin{itemize}
+  \item Every \emph{path} starts with a file handle as returned by {\Tcl snacc create} or {\Tcl snacc open}.
+  \item All subsequent path elements, except for the last, must indicate elements of composed types.
+    For CHOICE, SET and SEQUENCE, these are member names, for SET OF and SEQUENCE OF, these are numeric indices.
+  \item The last path element may reference a simple type.
+  \item For SET OF and SEQUENCE OF, instead of a numeric index, a pair consisting of the word {\Tcl insert} followed by a numeric index may be specified.
+    In this case, a new list element is inserted before that addressed by the index.
+    The index must be in the range $0\ldots{}n-1$ to address existing elements and it must be in the range $0\ldots{}n$ for insertion, where in both cases $n$ is the number of elements in the list.
+  \item For {\Tcl snacc unset}, the path must point to an optional member of a SET or SEQUENCE or to an element of a SET OF or SEQUENCE OF.
+\end{itemize}
+
+The commands are:
+\begin{description}%{
+  \item[{\Tcl snacc info \emph{path}}] returns information about the value pointed to by \emph{path}.
+    The information returned is quite similar to that of {\Tcl snacc type} above, with the following exceptions:
+    \begin{itemize}%{
+      \item element~0, the content type, contains empty names for types that have not been given a name (e.g. a SET member of type OCTET STRING
+	Example: the {\ASN contents} member in type {\ASN File} in file {\ufn edex1.asn1} (page~\pageref{edex1.asn1}) {\Tcl snacc info} returns {\Tcl \{\{\} \{\}\} sub \{OCTET STRING\}}).
+      \item the number of elements depends on the ASN.1 type:
+	\begin{description}%{
+	  \item simple types (\textbf{NULL}, \textbf{BOOLEAN}, \textbf{INTEGER}, \textbf{ENUMERATED}, \textbf{REAL}, \textbf{BIT STRING} and \textbf{OCTET STRING}):
+	    no additional elements are returned.
+	    For the list of named values for INTEGER, ENUMERATED and BIT STRING, you have to call {\Tcl snacc type [lindex [snacc info \emph{path}]~0]}, unless the content type equals {\Tcl \{\{\}~\{\}\}}.
+	  \item[CHOICE]
+	    a total of five elements is returned, number~3 is the name of the choice member currently chosen, and the final element number~4 is an identifier that is either {\Tcl void} or {\Tcl valid} depending on whether the pointer representing the choice member is {\C NULL} or pointing to some data.
+	  \item[SET \textnormal{and} SEQUENCE]
+	    a fourth element, a list of pairs, is returned, where the pairs are built from the member name and an identifier that is either {\Tcl valid} or {\Tcl void}
+	  \item[SET OF \textnormal{and} SEQUENCE OF]
+	    the number of items is returned as element number~3.
+	\end{description}%}
+    \end{itemize}%}
+  \item[{\Tcl snacc get \emph{path}}]
+    returns the value of the subtree pointed to by \emph{path}.
+    The value returned is a simple string for simple types, and a hierarchical structure (in Tcl that is a list of lists) otherwise.
+    \begin{description}%{
+      \item[NULL]
+	the empty string is returned.
+      \item[BOOLEAN]
+	the value is returned as {\Tcl TRUE} or {\Tcl FALSE}.
+      \item[INTEGER]
+	the numeric value is returned, even if it has been assigned a name.
+      \item[ENUMERATED]
+	the symbolic value is returned.
+	The numeric values are inaccessible through the Tcl interface.
+	If the object happens to contain an illegal numeric value, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLENUM}.
+      \item[REAL]
+	the value is returned as formatted by {\C sprintf (\dots, "\%g", \dots)}, except for the special values {\ASN PLUS-INFINITY} and {\ASN MINUS-INFINITY} which are returned as {\Tcl +inf} and {\Tcl -inf}, respectively.
+      \item[BIT STRING]
+	a string, consisting solely of `0' and `1', is returned.
+      \item[OCTET STRING]
+	the binary string is returned as is, except for the unavoidable NUL-escape described above.
+      \item[OBJECT IDENTIFIER]
+	the value is returned as a list of numbers.
+      \item[CHOICE]
+	is returned as a pair, the choice member chosen and its value.
+      \item[SET \textnormal{and} SEQUENCE]
+	are returned as a list of pairs of member name and value.
+	Absent OPTIONAL members are left out from the list.
+      \item[SET OF \textnormal{and} SEQUENCE OF]
+	are returned as a list of values.
+    \end{description}%}
+  \item[{\Tcl snacc set \emph{path value}}] sets the subtree identified by \emph{path} to \emph{value}.
+    The value must be of the form 
+    \begin{description}%{
+      \item[NULL]
+	the only legal value is the empty string.
+	otherwise, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLNULL}.
+      \item[BOOLEAN]
+	any value that is accepted by {\C Tcl\_GetBoolean}(3) is fine.
+      \item[INTEGER]
+	both the numeric (as accepted by {\C Tcl\_GetInt(3)}) and the symbolic values are allowed.
+      \item[ENUMERATED]
+	any value must be specified by its name.
+	If an illegal name is given, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLENUM}.
+      \item[REAL]
+	the special values {\ASN PLUS-INFINITY} and {\ASN MINUS-INFINITY} have to be given as {\Tcl +inf} and {\Tcl -inf}, respectively.
+	All other values may be specified in any format accepted by {\C Tcl\_GetDouble}(3).
+      \item[BIT STRING]
+	a string that must consist of `0' and `1' only has to be given.
+	otherwise, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLBIT}.
+      \item[OCTET STRING]
+	due to the NUL-escapes necessary, any string where a backslash is followed by either another backslash or a `0' digit is legal.
+	Improper use of the escape character leads to an error and {\Tcl errorCode} will be set to {\Tcl SNACC ILLESC}.
+      \item[OBJECT IDENTIFIER]
+	the value has to be specified as a list of numbers.
+	if the arc has less than 2 or more than 10 elements, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLARC <2} or {\Tcl SNACC ILLARC >10}, respectively.
+      \item[CHOICE]
+	the value expected is a pair, the choice member chosen and its value.
+	if an illegal member is specified, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLCHOICE}.
+      \item[SET \textnormal{and} SEQUENCE]
+	the value has got to be a list of pairs of member name and value.
+	Any member may be specified at most once.
+	All mandatory members must be present.
+	Failure to do so will result in an error and {\Tcl errorCode} to be set to {\Tcl SNACC DUPMEMB} or {\Tcl SNACC MISSMAND}, respectively.
+	All optional members not listed in the value will be deallocated.
+      \item[SET OF \textnormal{and} SEQUENCE OF]
+	the whole list is replaced with the specified value that has to be a proper Tcl list.
+    \end{description}%}
+  \item[{\Tcl snacc unset \emph{path}}]
+    unsets the subtree pointed to by \emph{path}.
+    Only OPTIONAL members of SET and SEQUENCE types and list elements of SEQ OF and SEQUENCE OF may be unset.
+    If you try to unset a mandatory SET or SEQUENCE member, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC MANDMEMB}.
+\end{description}%}
+
+I did not follow Tk's example where one has to set widget commands to {\Tcl \{\}} to delete them.
+This method would have the drawback that one could not distinguish between an empty and a non-existing octet string (in C that would be {\C ""} vs. {\C NULL}).
+
+The value returned by {\Tcl snacc get} may be very long, {\Tcl snacc get file0} returns the contents of the whole file!
+
+\section{\label{snacc-examples}Examples}
+
+The following example session shall illustrate the {\Tcl snacc} commands usage.
+It assumes that the editor example files {\ufn edex0.asn1} and {\ufn edex1.asn1} (see appendix~\ref{edex-files} on page~\pageref{edex-files}) have been compiled into a binary that has been linked with the necessary libraries.
+
+The notation used is as in the Tcl book \cite{tcl-book}, i.e. `$\Rightarrow$' indicates a normal return value and `$\varnothing$' indicates an error with the error message set in {\Tcl \emph{oblique typeface}}.
+
+A look at the types available:
+
+\begin{Tclex}
+   & snacc types\\
+\R & \{EdEx-Simple Hand\} \{EdEx-Structured StructuredChoice\} \{EdEx-Structured Coordinate\} \{EdEx-Structured CoordinateSeq\} \{EdEx-Structured RGBColor\} \{EdEx-Structured Simple\} \{EdEx-Simple File\} \{EdEx-Simple RainbowColor\} \{EdEx-Structured DirectorySetOf\} \{EdEx-Structured Various\} \{EdEx-Structured File1\} \{EdEx-Structured CoordinateSeq1\} \{EdEx-Structured Directory\} \{EdEx-Structured Structured\} \{EdEx-Simple DayOfTheWeek\}
+\end{Tclex}
+
+Create a file (without filename):
+
+\begin{Tclex}
+   & set file [snacc create \{EdEx-Structured Structured\}]\\
+\R & file0
+\end{Tclex}
+
+The string returned is the file handle. It is used as the first snaccpath component in successive calls.
+
+Look at the file's type:
+
+\begin{Tclex}
+   & snacc info \$file\\
+\R & \{EdEx-Structured Structured\} sub SET \{\{coord valid\} \{color valid\}\}
+\end{Tclex}
+
+The file's type is a SET with the name `Structured' in module `EdEx-Structured' (it is defined in file {\ufn edex1.asn1} (see page~\pageref{edex1.asn1})).
+The `sub' tells us that the type has not been marked as a PDU.
+The SET has the components `coord' and `color', both are present (they are not OPTIONAL, i.e. mandatory).
+
+Look at a component's type:
+
+\begin{Tclex}
+   & snacc info "\$file color"\\
+\R & \{EdEx-Structured StructuredChoice\} sub CHOICE rainbow valid
+\end{Tclex}
+
+Snacc has generated the type name `StructuredChoice' for this type, this name was not defined in the {\ufn .asn1} file.
+The CHOICE object currently is set to `rainbow'.
+A CHOICE component is always present (CHOICE components may not be OPTIONAL), the `valid' is just for completeness.
+
+Ask for the CHOICE's generic type information:
+
+\begin{Tclex}
+   & snacc type \{EdEx-Structured StructuredChoice\}\\
+\R & \{EdEx-Structured StructuredChoice\} sub CHOICE \{\{rainbow \{EdEx-Simple RainbowColor\} sub INTEGER\} \{rgb \{EdEx-Structured RGBColor\} sub SEQUENCE\}\}
+\end{Tclex}
+
+The CHOICE type has two possible components, `rainbow', an INTEGER and `rgb', a SEQUENCE.
+
+Look at the INTEGER's type information:
+
+\begin{Tclex}
+   & snacc type \{EdEx-Simple RainbowColor\}\\
+\R & \{EdEx-Simple RainbowColor\} sub INTEGER \{\{red~0\} \{orange~1\} \{yellow~2\} \{green~3\} \{blue~4\} \{indigo~5\} \{violet~6\}\}
+\end{Tclex}
+
+The type has got named values.
+
+Access the file contents:
+
+\begin{Tclex}
+   & snacc get \$file\\
+\R & \{coord \{cartesian \{\{x 0\} \{y 0\}\}\}\} \{color \{rainbow 977768\}\}
+\end{Tclex}
+
+The color component contains garbage.
+Change that:
+
+\begin{Tclex}
+   & snacc set "\$file color rainbow" green\\
+\R &\\
+   & snacc get "\$file color"\\
+\R & rainbow 3
+\end{Tclex}
+
+Change it again, select the CHOICE's other component type, `rgb', and set its `red' component:
+
+\begin{Tclex}
+   & snacc set "\$file color rgb red" 256\\
+\R &
+\end{Tclex}
+
+Changing a CHOICE component selection work only for write access, on read access this is not possible:
+
+\begin{Tclex}
+   & snacc get "\$file color rainbow"\\
+\E & \emph{snacc get: illegal component "rainbow" in path}\\
+   & snacc get "\$file color rgb"\\
+\R & \{red 256\} \{green 544501616\} \{blue 1814045815\}
+\end{Tclex}
+
+Upon setting a SET or SEQUENCE type, all mandatory members have to be specified:
+
+\begin{Tclex}
+   & snacc set "\$file color rgb" \{\{green 0\} \{blue 0\}\}\\
+\E & \emph{mandatory member "red" is missing in list}\\
+   & snacc set "\$file color rgb" \{\{red 0\} \{green 256\} \{blue 0\}\}\\
+\R &\\
+   & snacc get "\$file color"\\
+\R & rgb \{\{red 0\} \{green 256\} \{blue 0\}\}
+\end{Tclex}
+
+Finish up:
+
+\begin{Tclex}
+   & snacc close \$file\\
+\R &\\
+   & snacc get \$file\\
+\E & \emph{snacc get: no file named "file0"}
+\end{Tclex}
+
+\section{\label{tcl-if-impl}Implementation}
+
+The Tcl interface is implemented in {\ufn \dots/c++-lib/inc/tcl-if.h} and {\ufn \dots/c++-lib/src/tcl-if.C}.
+It gets initialized with the help of {\ufn \dots/c++-lib/inc/init.h} and {\ufn \dots/c++-lib/src/tkAppInit.c}.
+
+The {\Tcl snacc} commands implementation is pretty straight forward: check the arguments, call a metacode function to perform an action and return the result, which may indicate success or an error.
+
+Care has been taken to check the return codes of all system calls and to set Tcl's {\Tcl errorCode} variable in case any system call returns an error.
+
+The file {\ufn tkAppInit.c} contains the function that introduces the {\Tcl snacc} Tcl command to the Tcl interpreter.
+The path that leads to the function's invocation is a little tricky and is described in section~\ref{editor-building}, ``Building Your Own Editor''.
+
+\section{Setup for the Tcl Code Generator}
+
+To compile Snacc with the Tcl interface code generator, you have got to fulfill the following conditions:
+\begin{itemize}
+  \item the configure script must be able to find {\ufn tclsh} and the Tcl/Tk libraries
+  \item the preprocessor switches {\C NO\_META} and {\C NO\_TCL} in {\ufn \dots/policy.h} must not be set
+\end{itemize}
+
+\section{\label{tcl-if-deficiencies}Deficiencies}
+
+\begin{itemize}
+  \item
+    Values defined in the ASN.1 files currently are inaccessible.
+    Adding access functions to the metacode and Tcl interface is rather trivial: build an array of elements that hold a variable's name as a character string and an {\C AsnType~*} that points to the C++ variable.
+    {\C a[i].val-->\_getdesc()} would return a pointer to the variable's type description.
+
+    (First you should fix snacc's value parser as currently it lets some values silently vanish, for example the {\ASN victory} in {\ufn edex0.asn1} that you can find in appendix~\ref{edex0.asn1} on page~\pageref{edex0.asn1}.)
+  \item
+    The Tcl interface does not provide symbolic object identifiers.
+    Mapping numeric to symbolic oids is a task that is difficult to get right since snacc translates\\
+    {\ASN anOidVal OBJECT IDENTIFIER ::= \{ 1 2 foo(3) \}}\\
+    and\\
+    {\ASN anOidVal OBJECT IDENTIFIER ::= \{ 1 2 3 \}\\
+    foo INTEGER ::= 3}\\
+    into identical C++ code, but translating the second {\ASN anOidVal} into {\ASN \{ 1 2 foo \}} may in fact violate {\ASN foo}'s semantics.
+\end{itemize}
diff --git a/SecuritySNACCRuntime/doc/ttab.tex b/SecuritySNACCRuntime/doc/ttab.tex
new file mode 100644
index 00000000..aa9de52c
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/ttab.tex
@@ -0,0 +1,532 @@
+% file: .../doc/ttab.tex
+
+% $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/ttab.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+% $Log: ttab.tex,v $
+% Revision 1.1.1.1  2001/05/18 23:14:10  mb
+% Move from private repository to open source repository
+%
+% Revision 1.1.1.1  1999/03/16 18:05:55  aram
+% Originals from SMIME Free Library.
+%
+% Revision 1.1  1997/01/01 22:47:43  rj
+% first check-in
+%
+
+\chapter{\label{ttab-chapter}Type Tables}
+
+Type tables are a flexible and compact way of dealing with ASN.1.
+The type table data structure is included in the appendix.  It was
+defined in ASN.1 to provide a good storage format for the tables.
+
+When snacc produces a type table it includes the useful types module
+as well, if one was specified.  If you are really trying to limit the
+size of your type tables, put the only useful types that you need in
+your ASN.1 module and compile it without using the useful types
+module.
+
+A generic buffer type (à la ISODE and XDR) was defined to allow type
+table driven routines to read from a wide variety of buffer formats.
+Currently slightly modified versions of the {\C ExpBuf} and the
+{\C SBuf} are provided.  It shouldn't be too hard for you to add
+support for your own buffer formats.  The generic buffers,
+{\C GenBuf}s are described in more detail in a following section.
+
+The general procedure for using type tables is to:
+\begin{enumerate}
+  \item Use snacc to compile your ASN.1 modules into a type table.
+  \item Use {\ufn mkchdr} (make C header, not make cheddar) with the
+    type table to produce a friendly C type description of the types in
+    the type table.
+  \item Load the type table during runtime and use it to configure the table
+    encode, decode and other routines.
+\end{enumerate}
+
+Step two, making the C header file is not necessary but will make
+dealing with the value easier and more type safe.  Internally the
+table driven encoders and decoders know nothing of these header file
+and treat the types in a uniform, generic manner.  This requires the
+encoders and decoders to make assumptions about the way C represents
+strucutures and values.  Look in the {\ufn \dots/c-lib/src/tbl-enc.c} and
+{\ufn \dots/c-lib/src/tbl-dec.c} files to see how this generic data
+structure is manipulated.
+
+On the down side, the compiler directives do not affect the data
+structures generated by mkchdr and the generated C type definitions
+will generally be different from those generated by the C backend.
+This can be fixed, but time was lacking. Type tables also do not
+support ANY DEFINED BY types.  Someone could fix this without too much
+difficulty.  Only a C type table library is provided.  I didn't have
+time to deal with the complexities of creating C++ objects in a
+generic way.
+
+Currently the type tables are lacking subtyping information.  It is
+available in snacc's main parse tree but I didn't have time to add it
+to the tables.  If you want to add it, take the subtype related data
+structures (in ASN.1) from asn1module.asn1 (quite a few), remove all
+the cruft pertaining to linking and error checking etc, and add it to
+the type table type definitions.  Then change the
+{\ufn \dots/compiler/core/gen-tbls.c} file to take the subtype information from
+the parse tree and put it into the type table.  See the appendix or
+{\ufn \dots/asn1specs/} for the ASN.1 definitions of the parse tree
+and type tables.
+
+The parse tree itself was defined in ASN.1 so it could be the table
+format.  The extra complexity required for linking and error checking
+made this very difficult.  Cycles in the data structure and the many
+links between the data elements made encoding in BER difficult.
+[Maybe ASN.1 needs a type refernce type (i.e. pointer)].
+
+
+\section{How Type Table See Values}
+
+As mentioned in the last section, table driven encoding, decoding,
+printing etc. routines see your values in a generic way.  They do not
+have abstract syntax specific header files like those created by
+{\ufn mkchdr}.
+
+The basic idea is that all of the standard primitive and list
+(SEQUENCE OF and SET OF) types are used and some regular rules are
+used for allocating and laying out structs for SEQUENCE, SET and
+CHOICE types.
+
+\begin{small}
+\begin{verbatim}
+/* values from table driver routines' point of view */
+typedef void AVal;
+
+/* SEQUENCE and SET type use AStructVal */
+typedef AVal *AStructVal;  /* an array of AVal ptrs */
+\end{verbatim}
+\end{small}
+
+For SETs and SEQUENCEs, the {\C AStructVal} type is used. Its is
+basically an array of pointers, one for each component of the
+SET/SEQUENCE\@.  Every component is referenced by pointer to simplify
+allocations.  OPTIONAL or DEFAULT components may be NULL\@.  For
+example, the type:
+
+\begin{small}
+\begin{verbatim}
+Foo ::= SEQUENCE { a INTEGER, b BOOLEAN, c OCTET STRING }
+\end{verbatim}
+\end{small}
+
+would be represented as an array of three pointers.  The first pointer
+would point to an {\C AsnInt} value, the second would point to an
+{\C AsnBool} value, and the third would point to an {\C AsnOcts}
+value. {\ufn mkchdr} would give you the following C typedef for Foo:
+
+\begin{small}
+\begin{verbatim}
+typedef struct Foo
+{
+    AsnInt *a;
+    AsnBool *b;
+    AsnOcts *c;
+} Foo;
+\end{verbatim}
+\end{small}
+
+\begin{small}
+\begin{verbatim}
+/* Internal representation for a CHOICE type */
+typedef struct AChoiceVal
+{
+   enum { achoiceval_notused } choiceId;
+   AVal *val;
+} AChoiceVal;
+\end{verbatim}
+\end{small}
+
+
+A CHOICE type is represented in a way similar to the C backend's
+output.  That is, an enum to hold the id of the CHOICE component
+that is present and a pointer to the component itself.  For example,
+the type:
+
+\begin{small}
+\begin{verbatim}
+Bar ::= CHOICE { a INTEGER, b BOOLEAN, c OCTET STRING }
+\end{verbatim}
+\end{small}
+
+would internally be represented as AChoiceVal type.  However,
+{\ufn mkchdr} would give you the following:
+
+\begin{small}
+\begin{verbatim}
+typedef struct Bar
+{
+    enum
+    {
+        a_ID = 0,
+        b_ID = 1,
+        c_ID = 2
+    } choiceId;
+    union
+    {
+        AsnInt *a;
+        AsnBool *b;
+        AsnOcts *c;
+    } a;
+} Bar;
+\end{verbatim}
+\end{small}
+
+
+\section{Type Table Utilities}
+
+There are a bunch of useful routines in {\ufn \dots/c-lib/src/tbl*.c}.  Look
+at the source code in {\ufn \dots/tbl-tools/*/} and
+{\ufn \dots/tbl-example/} to see how to use some of them.
+
+The {\C LoadTblFile} will decode a type table from a given file.
+Notice that its definition of the {\C TBL} data structure has been
+augmented to simplify encoding and decoding operations. (Look at the
+patch in {\ufn \dots/c-lib/tbl.h.patch} that is applied through the makefile automatically.)
+% The additional fields do not screw up the compiled encoder/decoder (in {\ufn \dots/c-lib/src/tbl.c}) provided they are recompiled.
+The compiler uses unmodified {\ufn tbl.h} and {\ufn tbl.c} files.
+
+I don't have time to document these routines.  Look through the table
+tools, examples and library code.  Their usage should be fairly
+obvious.
+
+
+\section{Type Table Tools}
+
+The {\ufn \dots/tbl-tools/} directory contains three tools, {\ufn mkchdr},
+{\ufn pval} and {\ufn ptbl}.  These are described in the following
+sections.
+
+\subsection{Making C Header Files with mkchdr}
+
+{\ufn mkchdr} produces a C header file from a type table.  This header
+file shows the representation of the types that the table tools will
+expect or return for the types in the given type table.
+
+The main use is to provide you with an easy to use definition of the
+ASN.1 types C representation.  You do not need to use {\ufn mkchdr}
+but it is definately recommended.  Note that the table routines could
+have used an even more generic data structure to represent values
+(e.g. ISODE's Presentation Elements).  If you have worked with these,
+you know that they are cumbersome.
+
+Its synopsis is:
+\begin{small}
+\begin{verbatim}
+mkchdr <tbl-file> [output-file]
+\end{verbatim}
+\end{small}
+
+If the output file is omitted, the header file is printed to {\C stdout}.
+
+Here is an example of the output.  Given the table that has the
+following ASN.1 module in it:
+
+\begin{small}
+\begin{verbatim}
+P-REC DEFINITIONS ::=
+BEGIN
+PersonnelRecord ::=  [APPLICATION 0] IMPLICIT SET
+{
+                     Name,
+    title        [0] IA5String,
+                     EmployeeNumber,
+    dateOfHire   [1] Date,
+    nameOfSpouse [2] Name,
+    children     [3] IMPLICIT SEQUENCE OF ChildInformation DEFAULT {}
+}
+
+ChildInformation ::= SET
+{
+                    Name,
+    dateOfBirth [0] Date
+}
+
+Name ::= [APPLICATION 1] IMPLICIT SEQUENCE
+{
+    givenName  IA5String,
+    initial    IA5String,
+    familyName IA5String
+}
+
+EmployeeNumber ::= [APPLICATION 2] IMPLICIT INTEGER
+
+Date ::= [APPLICATION 3] IMPLICIT IA5String -- YYYYMMDD
+
+END
+\end{verbatim}
+\end{small}
+
+{\ufn mkchdr} will produce:
+\begin{small}
+\begin{verbatim}
+typedef AsnInt EmployeeNumber;
+
+typedef struct Name
+{
+    IA5String *givenName;
+    IA5String *initial;
+    IA5String *familyName;
+} Name;
+
+typedef IA5String Date;
+
+typedef struct ChildInformation
+{
+    Name *field0;
+    Date *dateOfBirth;
+} ChildInformation;
+
+typedef AsnList PersonnelRecordSeqOf;
+
+typedef struct PersonnelRecord
+{
+    Name *field0;
+    IA5String *title;
+    EmployeeNumber *field1;
+    Date *dateOfHire;
+    Name *nameOfSpouse;
+    PersonnelRecordSeqOf *children;
+} PersonnelRecord;
+
+\end{verbatim}
+\end{small}
+
+
+\subsection{Printing Tables with ptbl}
+
+{\ufn ptbl} is a program that will show you the contents of a type
+table.  It can print a table in two modes:
+\begin{itemize}
+  \item The value notation for the TBL ASN.1 data structure (see the appendix).
+  \item The ASN.1 text version
+\end{itemize}
+
+Its synopsis is:
+
+\begin{small}
+\begin{verbatim}
+ptbl [-a] <tbl-file>
+\end{verbatim}
+\end{small}
+
+For example, using {\ufn ptbl -a p-rec.tt} to print the
+PersonnelRecord module used in the last section would yield:
+
+\begin{small}
+\begin{verbatim}
+P-REC  DEFINITIONS ::=
+BEGIN
+EmployeeNumber ::= [APPLICATION 2] IMPLICIT INTEGER
+Name ::= [APPLICATION 1] IMPLICIT SEQUENCE
+{
+    givenName IA5String,
+    initial IA5String,
+    familyName IA5String
+}
+Date ::= [APPLICATION 3] IMPLICIT IA5String
+ChildInformation ::= SET
+{
+    Name,
+    dateOfBirth [0] Date
+}
+PersonnelRecordSeqOf ::= SEQUENCE OF ChildInformation
+PersonnelRecord ::= [APPLICATION 0] IMPLICIT SET
+{
+    Name,
+    title [0] IA5String,
+    EmployeeNumber,
+    dateOfHire [1] Date,
+    nameOfSpouse [2] Name,
+    children [3] IMPLICIT PersonnelRecordSeqOf
+}
+END
+--  Definitions for  ASN-USEFUL
+ASN-USEFUL  DEFINITIONS ::=
+BEGIN
+ObjectDescriptor ::= [UNIVERSAL 7] IMPLICIT OCTET STRING
+NumericString ::= [UNIVERSAL 18] IMPLICIT OCTET STRING
+PrintableString ::= [UNIVERSAL 19] IMPLICIT OCTET STRING
+TeletexString ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
+T61String ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
+VideotexString ::= [UNIVERSAL 21] IMPLICIT OCTET STRING
+IA5String ::= [UNIVERSAL 22] IMPLICIT OCTET STRING
+GraphicString ::= [UNIVERSAL 25] IMPLICIT OCTET STRING
+VisibleString ::= [UNIVERSAL 26] IMPLICIT OCTET STRING
+ISO646String ::= [UNIVERSAL 26] IMPLICIT OCTET STRING
+GeneralString ::= [UNIVERSAL 27] IMPLICIT OCTET STRING
+UTCTime ::= [UNIVERSAL 23] IMPLICIT OCTET STRING
+GeneralizedTime ::= [UNIVERSAL 24] IMPLICIT OCTET STRING
+EXTERNAL ::= [UNIVERSAL 8] IMPLICIT SEQUENCE
+{
+    direct-reference OBJECT IDENTIFIER,
+    indirect-reference INTEGER,
+    data-value-descriptor ObjectDescriptor,
+    encoding CHOICE
+    {
+        single-ASN1-type [0] OCTET STRING,
+        octet-aligned [1] IMPLICIT OCTET STRING,
+        arbitrary [2] IMPLICIT BIT STRING
+    }
+}
+END
+\end{verbatim}
+\end{small}
+
+Note that the useful type module is included in the table.  As
+mentioned before, to minimize the size of your tables, put the
+definitions of the useful types (from {\ufn \dots/asn1specs/asn-useful.asn1})
+into your ASN.1 module and do not compile with useful types module
+(i.e. don't use the -u option).  If your module doesn't use any
+useful types, just don't use the -u option.
+
+The other mode of {\ufn ptbl}, value notation for the TBL data
+structure, produces a lot of output.  It may be useful if you are
+debugging one of the table drivers.
+
+
+\subsection{Printing Values with pval}
+
+The {\ufn pval} program will convert BER values into their value
+notation.  Its arguments are a type table file, a module and type name
+and a list of BER files of that type.
+
+Its synopsis is:
+
+\begin{small}
+\begin{verbatim}
+pval -T <tt file name> [-m <module name>] -n <type name> <ber value file list>
+\end{verbatim}
+\end{small}
+
+Running {\ufn pval} on a PersonnelRecord value produced the following:
+
+\begin{small}
+\begin{verbatim}
+-- Contents of file "demo-tbls/p-rec.ber"--
+-- module = ???, type = PersonnelRecord --
+
+value P-REC.PersonnelRecord ::=
+{
+  {
+    givenName '4a6f686e'H  -- "John" --,
+    initial '45'H  -- "E" --,
+    familyName '536d697468'H  -- "Smith" --
+  },
+  title '5468652042696720436865657365'H  -- "The Big Cheese" --,
+  99999,
+  dateOfHire '3139383230313034'H  -- "19820104" --,
+  nameOfSpouse {
+    givenName '4d617279'H  -- "Mary" --,
+    initial '4c'H  -- "L" --,
+    familyName '536d697468'H  -- "Smith" --
+  },
+  children {
+    {
+      {
+        givenName '4a616d6573'H  -- "James" --,
+        initial '52'H  -- "R" --,
+        familyName '536d697468'H  -- "Smith" --
+      },
+      dateOfBirth '3139353730333130'H  -- "19570310" --
+    },
+    {
+      {
+        givenName '4c697361'H  -- "Lisa" --,
+        initial '4d'H  -- "M" --,
+        familyName '536d697468'H  -- "Smith" --
+      },
+      dateOfBirth '3139363130363231'H  -- "19610621" --
+    }
+  }
+}
+
+ -- decoded 143 bytes for the above value --
+\end{verbatim}
+\end{small}
+
+
+\section{Using Tables in Your Own Applications}
+
+The best way to get a handle on using tables is to look at the example
+in {\ufn \dots/tbl-example/}.  The general idea is to compile your
+ASN.1 into a type table (use the snacc {\ufn -T} option).  If you desire a
+livable definition of the C data structures for the types in the type
+table, run {\ufn mkchdr} and compile the generated header file with
+your C code.  During runtime, simply load your table file with
+{\C LoadTblFile} (I use the {\ufn .tt} suffix naming convention for type table
+files but it doesn't matter) and then use the {\C TblEncode},
+{\C TblDecode}, {\C TblPrint} and {\C TblFree} routines with
+your table.  Quite simple.  Seriously.
+
+\section{Using GenBufs}
+
+The {\C GenBuf} generic buffers are really a way of encapsulating
+other buffer formats.  A {\C GenBuf} contains a table of pointers to
+the buffer functions (the standardized ones (see the buffer section)
+plus ``Peek'' routines that the table drivers needed).  They are
+defined in {\ufn \dots/c-lib/inc/gen-buf.h}.
+
+{\C GenBuf}s require functions for the standard buffer routines,
+macros will not do since you cannot have a pointer to macro.
+
+The benefit of the {\C GenBuf}s is that since they can support other
+buffer types, only one set of library routines is needed.  (Note that
+there are 3 libraries in {\ufn \dots/c-lib/} for the backend model and only one for the type table model.
+
+Here is most of {\ufn gen-buf.h} to give you an idea of how things work:
+
+\begin{small}
+\begin{verbatim}
+typedef unsigned char (*BufGetByteFcn) PROTO ((void *b));
+typedef unsigned char *(*BufGetSegFcn) PROTO ((void *b,
+                                               unsigned long int *lenPtr));
+typedef long int (*BufCopyFcn) PROTO ((char *dst, void *b,
+                                   unsigned long int len));
+typedef void (*BufSkipFcn) PROTO ((void *b, unsigned long int len));
+typedef unsigned char (*BufPeekByteFcn) PROTO ((void *b));
+typedef unsigned char *(*BufPeekSegFcn) PROTO ((void *b,
+                                               unsigned long int lenPtr));
+typedef long int (*BufPeekCopyFcn) PROTO ((char *dst, void *b,
+                                   unsigned long int len));
+typedef void (*BufPutByteRvsFcn) PROTO ((void *b, unsigned char byte));
+typedef void (*BufPutSegRvsFcn) PROTO ((void *b, char *data,
+                                    unsigned long int len));
+typedef int (*BufReadErrorFcn) PROTO ((void *b));
+typedef int (*BufWriteErrorFcn) PROTO ((void *b));
+
+typedef struct GenBuf
+{
+    BufGetByteFcn    getByte;
+    BufGetSegFcn     getSeg;
+    BufCopyFcn       copy;
+    BufSkipFcn       skip;
+    BufPeekByteFcn   peekByte;
+    BufPeekSegFcn    peekSeg;
+    BufPeekCopyFcn   peekCopy;
+    BufPutByteRvsFcn putByteRvs;
+    BufPutSegRvsFcn  putSegRvs;
+    BufReadErrorFcn  readError;
+    BufWriteErrorFcn writeError;
+    void             *bufInfo;
+    void             *spare; /* hack to save space for ExpBuf ** type */
+} GenBuf;
+
+#define GenBufGetByte( b)              ((b)->getByte (b->bufInfo))
+#define GenBufGetSeg( b, lenPtr)       ((b)->getSeg (b->bufInfo, lenPtr))
+#define GenBufCopy( dst, b, len)       ((b)->copy (dst, b->bufInfo, len))
+#define GenBufSkip( b, len)            ((b)->skip (b->bufInfo,len))
+#define GenBufPeekByte( b)             ((b)->peekByte (b->bufInfo))
+#define GenBufPeekSeg( b, lenPtr)      ((b)->peekSeg (b->bufInfo, lenPtr))
+#define GenBufPeekCopy( dst, b, len)   ((b)->peekCopy (dst, b->bufInfo, len))
+#define GenBufPutByteRvs( b, byte)     ((b)->putByteRvs (b->bufInfo, byte))
+#define GenBufPutSegRvs( b, data, len) ((b)->putSegRvs (b->bufInfo, data, len))
+#define GenBufReadError( b)            ((b)->readError (b->bufInfo))
+#define GenBufWriteError( b)           ((b)->writeError (b->bufInfo))
+\end{verbatim}
+\end{small}
+
+\section{Type Tables Vs. Metacode}
+
+Please refer to section~\ref{meta-ttab-comparison} on page~\pageref{meta-ttab-comparison}.
diff --git a/SecuritySNACCRuntime/doc/tumble.sed b/SecuritySNACCRuntime/doc/tumble.sed
new file mode 100644
index 00000000..9cfaba85
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/tumble.sed
@@ -0,0 +1,4 @@
+/^%%EndSetup$/i\
+statusdict begin\
+\  true settumble\
+end
diff --git a/SecuritySNACCRuntime/doc/version.tex b/SecuritySNACCRuntime/doc/version.tex
new file mode 100644
index 00000000..654e81de
--- /dev/null
+++ b/SecuritySNACCRuntime/doc/version.tex
@@ -0,0 +1 @@
+\def\snaccversion{1.3b3}
diff --git a/SecuritySNACCRuntime/install-sh b/SecuritySNACCRuntime/install-sh
new file mode 100644
index 00000000..ab74c882
--- /dev/null
+++ b/SecuritySNACCRuntime/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/SecuritySNACCRuntime/makefile b/SecuritySNACCRuntime/makefile
new file mode 100644
index 00000000..16368041
--- /dev/null
+++ b/SecuritySNACCRuntime/makefile
@@ -0,0 +1,225 @@
+# makefile (top level)
+#
+#  Builds and installs the snacc ASN.1 compiler and libraries.
+#
+#  MS 92
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/makefile,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:04  mb
+# Move from private repository to open source repository
+#
+# Revision 1.3  2000/12/22 00:00:40  dmitch
+# Add  include makehead.static due to apparently broken autoconf, which now generates empty makehead file.
+#
+# Revision 1.2  2000/06/15 18:49:46  dmitch
+# Trimmed EXAMPLESDIR to comply with reality.
+#
+# Revision 1.1.1.1  1999/03/16 18:05:49  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.15  1997/08/27 15:53:11  wan
+# Added generic table decoding, debug routines, berdecode, and asnwish.
+#
+# Revision 1.14  1997/03/03 11:58:26  wan
+# Final pre-delivery stuff (I hope).
+#
+# Revision 1.13  1997/02/16 19:55:22  rj
+# remove tcl-p when making clobber
+#
+# Revision 1.12  1997/02/16 18:30:33  rj
+# correct path to configure script
+#
+# Revision 1.11  1997/02/16 16:52:05  rj
+# generate tcl-p before it is needed...
+#
+# Revision 1.10  1997/02/15 20:33:33  rj
+# trick to make making clean/clobber working with gmake: set MAKE_CLEAN_HACK (in makefile), and don't include the dependencies files (in maketail) if it is set.
+#
+# Revision 1.9  1995/07/26 21:16:56  rj
+# distribute tcl-p.c
+#
+# Revision 1.8  1995/07/24  14:54:22  rj
+# type table tools integrated.
+#
+# tiny .../tcl-p utility program that returns 0 if snacc's tcl interface is to be made.
+#
+# dummy action added to config.h.in and config.h rules to trick many makes' overoptimization.
+#
+# Revision 1.7  1995/02/22  09:49:07  rj
+# turned the phony target `pack-tar' into a true target: $(VDIR).tar.gz.
+#
+# Revision 1.6  1995/02/20  11:21:27  rj
+# use install-sh instead of install.sh.
+# phony target distclean: don't remove the distributed file configure and stamp-h.in (they cannot be remade everywhere).
+#
+# Revision 1.5  1995/02/17  14:26:39  rj
+# adjustments for autoconf 2.x
+#
+# Revision 1.4  1994/10/08  04:42:56  rj
+# config.h.bot removed.
+# snacc.h and policy.h added.
+#
+# Revision 1.3  1994/09/01  01:34:34  rj
+# gen-distfiles phony target to generate up-to-date versions of the distfiles.
+#
+# Revision 1.2  1994/08/31  23:19:22  rj
+# a lot of enhancements:
+# - examples integrated, with some phony targets.
+# - autoconf stuff gets automatically remade.
+# - dependency boot strapping (some makes need it).
+# - distributions via file list, therefore no need to clean the tree and to remove private files.
+#
+# Revision 1.1  1994/08/28  09:20:17  rj
+# first check-in. for a list of changes to 1.1 please refer to the ChangeLog.
+
+TOP		= .
+
+include makehead
+include makehead.static
+
+SUBDIRS		= compiler c-lib c++-lib tbl-tools asn1specs doc
+XDIRS		= tcl-lib tcl-asn
+
+# Apple change: the tbl-example doesn't run properly; tcl-example doesn't build Skip them.
+EXAMPLESDIRS	= c-examples c++-examples
+#EXAMPLESDIRS	= c-examples c++-examples tbl-example tcl-example
+
+DISTFILES = \
+	COPYING						\
+	README NEWS INSTALL				\
+	ChangeLog version.h				\
+	configure.in configure				\
+	acconfig.h config.h.in stamp-h.in		\
+	policy.h snacc.h				\
+	tcl-p.c						\
+	makefile makehead.in maketail			\
+	mkinstalldirs install-sh
+
+#-------------------------------------------------------------------------------
+
+.PHONY:	default all subdirs $(SUBDIRS) examples $(EXAMPLESDIRS) $(XDIRS) depend c c++ check c-check c++-check install c-install c++-install clean clobber tar
+
+default::	compiler c-lib c++-lib tbl-tools tcl-asn
+
+tcl-p:		$(TCL-P)
+$(TCL-P):	tcl-p.c snacc.h config.h policy.h
+		$(REASON)
+		$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+depend $(SUBDIRS) $(EXAMPLESDIRS) $(XDIRS)::	config.h version.h
+
+# the following hack is needed for older make versions
+# (gmake doesn't need it):
+depend::
+		@for dir in $(SUBDIRS) tbl-example; do\
+		  test -f $$dir/dependencies || touch $$dir/dependencies;\
+		done
+		@for dir in c-examples c++-examples; do\
+		  (cd $$dir && $(MAKE) init-depend);\
+		done
+
+depend install gen-distfiles::
+		$(MAKE) subdirs examples xdirs subtarget=$@
+
+clean clobber::
+		$(MAKE) subdirs examples xdirs subtarget=$@ MAKE_CLEAN_HACK=xyzzy
+
+subdirs::	$(SUBDIRS)
+examples::	$(EXAMPLESDIRS)
+xdirs::		$(XDIRS)
+$(SUBDIRS)	\
+$(EXAMPLESDIRS)::
+		cd $@ && $(MAKE) $(subtarget)
+tcl-lib::
+		$(MAKE) $(TCL-P)
+		if $(TCL-P); then cd $@ && $(MAKE) $(subtarget); fi
+
+tcl-asn::
+		$(MAKE) $(TCL-P)
+		if $(TCL-P); then cd $@ && $(MAKE) $(subtarget); fi
+
+# compiler, C runtime libraries and type table tools:
+c::		compiler c-lib tbl-tools tcl-asn
+c-check::	c c-lib-check tbl-check
+c-lib-check::
+		$(MAKE) c-examples subtarget=check
+tbl-check::
+		$(MAKE) tbl-example subtarget=check
+c-install::
+		$(MAKE) c asn1specs subtarget=install
+
+# build compiler and C++ runtime library:
+c++::		compiler c++-lib tcl-lib
+c++-check::	c++
+c++-check::
+		$(MAKE) c++-examples subtarget=check
+c++-install::
+		$(MAKE) c++ asn1specs subtarget=install
+
+# create compiler, build C and C++ runtime lib archive, type table tools, run a few checks:
+all::		compiler c-lib c++-lib tbl-tools tcl-asn check
+
+check::		c-check c++-check
+
+$(srcdir)/configure:	configure.in
+		$(REASON)
+		cd $(srcdir) && autoconf
+
+# autoheader might not change config.h.in, so touch a stamp file
+$(srcdir)/config.h.in:	stamp-h.in
+		@true
+$(srcdir)/stamp-h.in:	configure.in acconfig.h
+		$(REASON)
+		cd ${srcdir} && autoheader
+		date > $@
+
+# config.status might not change config.h
+config.h:	stamp-h
+		@true
+stamp-h:	config.h.in config.status
+		$(REASON)
+		CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
+
+makehead:	makehead.in config.status
+		$(REASON)
+		CONFIG_FILES=makehead CONFIG_HEADERS= ./config.status
+
+config.status:	$(srcdir)/configure
+		$(REASON)
+		./config.status --recheck
+
+clobber distclean::
+		$(RM) config.log config.cache config.status config.h stamp-h
+		$(RM) $(TCL-P)
+
+gen-distfiles::	$(DISTFILES)
+
+distfiles::
+		echo "$(DISTFILES)";\
+		for dir in $(SUBDIRS) $(EXAMPLESDIRS) $(XDIRS); do\
+		  subfiles=`cd $$dir && $(MAKE) -s $@`;\
+		  for file in $$subfiles; do\
+		    echo "$$dir/$$file";\
+		  done;\
+		done
+
+tar::		gen-distfiles
+
+tar::
+		vdir=snacc-`sed -e '/VERSION/!d' -e 's/.*"\(.*\)".*/\1/' -e q version.h`;\
+		distfiles=`$(MAKE) -s distfiles ECHO=:`;\
+		for file in $$distfiles; do\
+		  files="$$files $$vdir/$$file";\
+		done;\
+		[ -d $$vdir ] || ln -s . $$vdir;\
+		$(RM) $$vdir.tar.gz;\
+		gtar zcvvhf $$vdir.tar.gz $$files;\
+		$(RM) $$vdir;\
+		ls -l $$vdir.tar.gz
+
+# this one is for internal use only:
+$(VDIR).tar.gz:	$(FILES)
+		$(REASON)
+		$(RM) $@
+		gtar zcvvhf $@ $(FILES)
diff --git a/SecuritySNACCRuntime/makehead b/SecuritySNACCRuntime/makehead
new file mode 100644
index 00000000..017a79fe
--- /dev/null
+++ b/SecuritySNACCRuntime/makehead
@@ -0,0 +1,116 @@
+# file: makehead.in
+# (unless it is the file Generated automatically from makehead.in by configure.)
+#
+# INSERT_VDA_COMMENTS
+# 
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/makehead,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Log: makehead,v $
+# Revision 1.1.1.1  2001/05/18 23:14:04  mb
+# Move from private repository to open source repository
+#
+# Revision 1.4  2000/06/15 18:50:16  dmitch
+# Doc change only.
+#
+# Revision 1.1.1.1  1999/03/16 18:05:49  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.7  1997/02/16 16:44:50  rj
+# made return *this after calling abort()'' a compile time option.
+#
+# Revision 1.6  1995/09/07  18:38:39  rj
+# PSBOOK and PSNUP added. (they get used in .../doc/makefile)
+#
+# manext and mandir split into two pairs, for sections 1 and n.
+#
+# Revision 1.5  1995/07/24  14:59:35  rj
+# new macros added:
+#  libexecdir for architecture-specific stuff
+#  tcldir under libdir (architecture independent)
+#  TCLSH
+#  DEPENDENCIES for c*-lib's multiple dependencies via recursive make calls
+#  TREELIBS for tree-3.6 widget libs
+#  PATCH for c-lib to patch tbl.h
+#  TCL-P utility prog that returns whether the tcl interface should be made as exit code
+#
+# Revision 1.4  1995/02/18  11:53:46  rj
+# added a small hack to find gcc's hidden include directory to pass it to makedepend. this shall enable X11's makedepend to find .h files a little more the way gcc does.
+#
+# Revision 1.3  1995/02/13  14:53:58  rj
+# CFLAGS, CXXFLAGS and LDFLAGS moved from the various makefiles to here.
+#
+# Revision 1.2  1994/10/08  04:30:32  rj
+# Tcl and X11 libs added
+#
+# Revision 1.1  1994/09/01  00:51:23  rj
+# first check-in (new file).
+#
+
+srcdir		= .
+top_srcdir	= .
+prefix		= /usr/local
+exec_prefix	= ${prefix}
+
+bindir		= $(exec_prefix)/bin
+libexecdir	= $(exec_prefix)/lib
+libdir		= $(prefix)/lib
+incdir		= $(prefix)/include
+tcldir		= $(libdir)/snacc/tcl
+# beware setting both extensions to the same value, otherwise snacc.1 and snacc.n will collide!
+man1ext		= 1
+mannext		= n
+man1dir		= $(prefix)/man/man$(man1ext)
+manndir		= $(prefix)/man/man$(mannext)
+
+SHELL		= /bin/sh
+ECHO		= echo
+
+
+TCLSH		= false
+SNACC_NOVOLAT	= 
+
+MKDEP		= mkdep
+MKDEP_CCINC	= -I/usr/local/include -I/usr/libexec/ppc/2.95.2/include
+
+DEPENDENCIES	= dependencies
+
+LEX		= flex
+LFLAGS		= 
+LEXLIB		= -ll
+YACC		= bison -y
+
+CC		= cc
+CFLAGS		= -DMACOS -DYYTEXT_POINTER -DFLEX_IN_USE -DVDADER_RULES
+CXX		= c++
+CXXFLAGS	= -g -O2 -DVDADER_RULES
+
+LDFLAGS		= 
+LIBS		= 
+CPPFLAGS.TCL	=
+TCLLIBS		= 
+TREELIBS	= 
+
+CPPFLAGS.X11	= 
+LDFLAGS.X11	= 
+LDLIBS.X11pre	= 
+LDLIBS.X11extra	= 
+
+PATCH		= patch
+AR		= ar
+RANLIB		= ranlib
+
+INSTALL		= /usr/bin/install -c
+INSTALL_PROGRAM	= ${INSTALL}
+INSTALL_DATA	= ${INSTALL} -m 644
+
+LATEX		= false
+BIBTEX		= false
+DVIPS		= false
+DETEX		= false
+PSPREVIEW	= true
+PSBOOK		= false
+PSNUP		= false
+SPELL		= spell
+
+TCL-P		= $(TOP)/tcl-p
+
+REASON		= @if [ -f $@ ]; then $(ECHO) "====== making $@ because of $? ======"; else $(ECHO) "====== making (creating) $@ ======"; fi
diff --git a/SecuritySNACCRuntime/makehead.in b/SecuritySNACCRuntime/makehead.in
new file mode 100644
index 00000000..a325481e
--- /dev/null
+++ b/SecuritySNACCRuntime/makehead.in
@@ -0,0 +1,113 @@
+# file: makehead.in
+# (unless it is the file @configure_input@)
+#
+# INSERT_VDA_COMMENTS
+# 
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/makehead.in,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Log: makehead.in,v $
+# Revision 1.1.1.1  2001/05/18 23:14:04  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:49  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.7  1997/02/16 16:44:50  rj
+# made return *this after calling abort()'' a compile time option.
+#
+# Revision 1.6  1995/09/07  18:38:39  rj
+# PSBOOK and PSNUP added. (they get used in .../doc/makefile)
+#
+# manext and mandir split into two pairs, for sections 1 and n.
+#
+# Revision 1.5  1995/07/24  14:59:35  rj
+# new macros added:
+#  libexecdir for architecture-specific stuff
+#  tcldir under libdir (architecture independent)
+#  TCLSH
+#  DEPENDENCIES for c*-lib's multiple dependencies via recursive make calls
+#  TREELIBS for tree-3.6 widget libs
+#  PATCH for c-lib to patch tbl.h
+#  TCL-P utility prog that returns whether the tcl interface should be made as exit code
+#
+# Revision 1.4  1995/02/18  11:53:46  rj
+# added a small hack to find gcc's hidden include directory to pass it to makedepend. this shall enable X11's makedepend to find .h files a little more the way gcc does.
+#
+# Revision 1.3  1995/02/13  14:53:58  rj
+# CFLAGS, CXXFLAGS and LDFLAGS moved from the various makefiles to here.
+#
+# Revision 1.2  1994/10/08  04:30:32  rj
+# Tcl and X11 libs added
+#
+# Revision 1.1  1994/09/01  00:51:23  rj
+# first check-in (new file).
+#
+
+srcdir		= @srcdir@
+top_srcdir	= @top_srcdir@
+prefix		= @prefix@
+exec_prefix	= @exec_prefix@
+
+bindir		= $(exec_prefix)/bin
+libexecdir	= $(exec_prefix)/lib
+libdir		= $(prefix)/lib
+incdir		= $(prefix)/include
+tcldir		= $(libdir)/snacc/tcl
+# beware setting both extensions to the same value, otherwise snacc.1 and snacc.n will collide!
+man1ext		= 1
+mannext		= n
+man1dir		= $(prefix)/man/man$(man1ext)
+manndir		= $(prefix)/man/man$(mannext)
+
+SHELL		= /bin/sh
+ECHO		= echo
+@SET_MAKE@
+
+TCLSH		= @TCLSH@
+SNACC_NOVOLAT	= @SNACC_NOVOLAT@
+
+MKDEP		= @MKDEP@
+MKDEP_CCINC	= @MKDEP_CCINC@
+
+DEPENDENCIES	= dependencies
+
+LEX		= @LEX@
+LFLAGS		= @LFLAGS@
+LEXLIB		= @LEXLIB@
+YACC		= @YACC@
+
+CC		= @CC@
+CFLAGS		= @CFLAGS@ -DVDADER_RULES
+CXX		= @CXX@
+CXXFLAGS	= @CXXFLAGS@ -DVDADER_RULES
+
+LDFLAGS		= @LDFLAGS@
+LIBS		= @LIBS@
+CPPFLAGS.TCL	=
+TCLLIBS		= @TCLLIBS@
+TREELIBS	= @TREELIBS@
+
+CPPFLAGS.X11	= @X_CFLAGS@
+LDFLAGS.X11	= @X_LIBS@
+LDLIBS.X11pre	= @X_PRE_LIBS@
+LDLIBS.X11extra	= @X_EXTRA_LIBS@
+
+PATCH		= @PATCH@
+AR		= @AR@
+RANLIB		= @RANLIB@
+
+INSTALL		= @INSTALL@
+INSTALL_PROGRAM	= @INSTALL_PROGRAM@
+INSTALL_DATA	= @INSTALL_DATA@
+
+LATEX		= @LATEX@
+BIBTEX		= @BIBTEX@
+DVIPS		= @DVIPS@
+DETEX		= @DETEX@
+PSPREVIEW	= @PSPREVIEW@
+PSBOOK		= @PSBOOK@
+PSNUP		= @PSNUP@
+SPELL		= @SPELL@
+
+TCL-P		= $(TOP)/tcl-p
+
+REASON		= @if [ -f $@ ]; then $(ECHO) "====== making $@ because of $? ======"; else $(ECHO) "====== making (creating) $@ ======"; fi
diff --git a/SecuritySNACCRuntime/makehead.static b/SecuritySNACCRuntime/makehead.static
new file mode 100644
index 00000000..6e20da1b
--- /dev/null
+++ b/SecuritySNACCRuntime/makehead.static
@@ -0,0 +1,134 @@
+#
+# Hack to work around (apparently) broken autoconf - it always generates this error
+# when tying to create makehead
+#
+# ...snip...
+# creating makehead
+# sed: 28: conftest.s1: unescaped newline inside substitute pattern
+# creating config.h
+#...snip...
+#
+# So, this is a copy of a previously known good makehead, and all the makefiles
+# which need it include this one. 
+#
+#
+# 
+# file: makehead.in
+# (unless it is the file Generated automatically from makehead.in by configure.)
+#
+# INSERT_VDA_COMMENTS
+# 
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/makehead.static,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Log: makehead.static,v $
+# Revision 1.1.1.1  2001/05/18 23:14:04  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1  2000/12/22 00:01:14  dmitch
+# New file, included by most makefiles here and below, due to apparently broken autoconf, which now generates empty makehead file. This one is a copy of the last makehead which worked.
+#
+# Revision 1.4  2000/06/15 18:50:16  dmitch
+# Doc change only.
+#
+# Revision 1.1.1.1  1999/03/16 18:05:49  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.7  1997/02/16 16:44:50  rj
+# made return *this after calling abort()'' a compile time option.
+#
+# Revision 1.6  1995/09/07  18:38:39  rj
+# PSBOOK and PSNUP added. (they get used in .../doc/makefile)
+#
+# manext and mandir split into two pairs, for sections 1 and n.
+#
+# Revision 1.5  1995/07/24  14:59:35  rj
+# new macros added:
+#  libexecdir for architecture-specific stuff
+#  tcldir under libdir (architecture independent)
+#  TCLSH
+#  DEPENDENCIES for c*-lib's multiple dependencies via recursive make calls
+#  TREELIBS for tree-3.6 widget libs
+#  PATCH for c-lib to patch tbl.h
+#  TCL-P utility prog that returns whether the tcl interface should be made as exit code
+#
+# Revision 1.4  1995/02/18  11:53:46  rj
+# added a small hack to find gcc's hidden include directory to pass it to makedepend. this shall enable X11's makedepend to find .h files a little more the way gcc does.
+#
+# Revision 1.3  1995/02/13  14:53:58  rj
+# CFLAGS, CXXFLAGS and LDFLAGS moved from the various makefiles to here.
+#
+# Revision 1.2  1994/10/08  04:30:32  rj
+# Tcl and X11 libs added
+#
+# Revision 1.1  1994/09/01  00:51:23  rj
+# first check-in (new file).
+#
+
+srcdir		= .
+top_srcdir	= .
+prefix		= /usr/local
+exec_prefix	= ${prefix}
+
+bindir		= $(exec_prefix)/bin
+libexecdir	= $(exec_prefix)/lib
+libdir		= $(prefix)/lib
+incdir		= $(prefix)/include
+tcldir		= $(libdir)/snacc/tcl
+# beware setting both extensions to the same value, otherwise snacc.1 and snacc.n will collide!
+man1ext		= 1
+mannext		= n
+man1dir		= $(prefix)/man/man$(man1ext)
+manndir		= $(prefix)/man/man$(mannext)
+
+SHELL		= /bin/sh
+ECHO		= echo
+
+
+TCLSH		= false
+SNACC_NOVOLAT	= 
+
+MKDEP		= mkdep
+MKDEP_CCINC	= -I/usr/local/include -I/usr/libexec/ppc/2.95.2/include -F/System/Library/PrivateFrameworks
+
+DEPENDENCIES	= dependencies
+
+LEX		= flex
+LFLAGS		= 
+LEXLIB		= -ll
+YACC		= bison -y
+
+CC		= cc
+CFLAGS		= -DMACOS -DYYTEXT_POINTER -DFLEX_IN_USE -DVDADER_RULES
+CXX		= c++
+CXXFLAGS	= -g -O2 -DVDADER_RULES
+
+LDFLAGS		= 
+LIBS		= 
+CPPFLAGS.TCL	=
+TCLLIBS		= 
+TREELIBS	= 
+
+CPPFLAGS.X11	= 
+LDFLAGS.X11	= 
+LDLIBS.X11pre	= 
+LDLIBS.X11extra	= 
+
+PATCH		= patch
+AR		= ar
+RANLIB		= ranlib
+
+INSTALL		= /usr/bin/install -c
+INSTALL_PROGRAM	= ${INSTALL}
+INSTALL_DATA	= ${INSTALL} -m 644
+
+LATEX		= false
+BIBTEX		= false
+DVIPS		= false
+DETEX		= false
+PSPREVIEW	= true
+PSBOOK		= false
+PSNUP		= false
+SPELL		= spell
+
+TCL-P		= $(TOP)/tcl-p
+
+REASON		= @if [ -f $@ ]; then $(ECHO) "====== making $@ because of $? ======"; else $(ECHO) "====== making (creating) $@ ======"; fi
diff --git a/SecuritySNACCRuntime/maketail b/SecuritySNACCRuntime/maketail
new file mode 100644
index 00000000..40d8d31c
--- /dev/null
+++ b/SecuritySNACCRuntime/maketail
@@ -0,0 +1,78 @@
+# file: maketail
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/maketail,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+# $Log: maketail,v $
+# Revision 1.1.1.1  2001/05/18 23:14:04  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:05:50  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.7  1997/02/16 16:46:26  rj
+# rule to generate $(TCL-P) added
+#
+# Revision 1.6  1997/02/15 20:33:59  rj
+# trick to make making clean/clobber working with gmake: set MAKE_CLEAN_HACK (in makefile), and don't include the dependencies files (in maketail) if it is set.
+#
+# Revision 1.5  1995/07/24  15:02:34  rj
+# .C.o default rule uses CXXFLAGS instead of CFLAGS for compilation.
+#
+# dependencies modified to allow c*-lib's recursive dependency-making.
+#
+# Revision 1.4  1995/02/18  11:53:48  rj
+# added a small hack to find gcc's hidden include directory to pass it to makedepend. this shall enable X11's makedepend to find .h files a little more the way gcc does.
+#
+# Revision 1.3  1994/09/01  01:34:49  rj
+# gen-distfiles phony target to generate up-to-date versions of the distfiles.
+#
+# Revision 1.2  1994/08/31  23:23:24  rj
+# use a make macro MKDEP (set via autoconf) instead of a fixed name.
+# generate dependencies for .c files derived from .asn1 files.
+#
+
+# different make versions have different default rules, so we need our own to get a consistent behaviour...
+.l.c:
+		$(REASON)
+		$(RM) $@
+		$(LEX) $(LFLAGS) -t $< > $@~
+		mv $@~ $@
+.c.o:
+		$(REASON)
+		$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
+.C.o:
+		$(REASON)
+		$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
+
+.PHONY:		depend distfiles
+
+depend::	$(ASN1HFILES) $(ASN1CFILES) $(LCFILES) $(YHFILES) $(YCFILES)
+
+depend::
+		if [ x"$(DEPENDENCIES)" != x ]; then\
+		  touch newdep;\
+		  $(MKDEP) -f newdep $(CPPFLAGS) -DMAKEDEPEND $(MKDEP_CCINC) $(ASN1CFILES) $(LCFILES) $(YCFILES) $(CFILES);\
+		  mv newdep $(DEPENDENCIES);\
+		  $(RM) newdep.bak;\
+		fi
+
+ifeq "$(MAKE_CLEAN_HACK)" "" # avoid any recompilation when we just want to `make clean'
+include dependencies
+endif
+
+dependencies:
+		touch $@
+		$(MAKE) depend
+
+$(TCL-P):
+		cd $(TOP) && $(MAKE) tcl-p
+clean::
+		$(RM) dependencies
+
+gen-distfiles::	$(DISTFILES)
+
+distfiles::
+		echo "$(DISTFILES)"
+
+.PHONY:	clean clobber
+
+clobber::	clean
diff --git a/SecuritySNACCRuntime/mkinstalldirs b/SecuritySNACCRuntime/mkinstalldirs
new file mode 100644
index 00000000..91f6d04e
--- /dev/null
+++ b/SecuritySNACCRuntime/mkinstalldirs
@@ -0,0 +1,32 @@
+#!/bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do 
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" || errstatus=$?
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/SecuritySNACCRuntime/policy.h b/SecuritySNACCRuntime/policy.h
new file mode 100644
index 00000000..d69d0b20
--- /dev/null
+++ b/SecuritySNACCRuntime/policy.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * file: policy.h
+ *
+ */
+
+/*
+ * enable the snacc compiler's Tcl interface generating code?
+ * set it to 0 or 1.
+ */
+#ifndef NO_TCL
+#define NO_TCL		0
+#endif
+
+/*
+ * enable code for meta code generation?
+ * the Tcl code needs it.
+ */
+#ifndef NO_META
+#define NO_META		NO_TCL
+#endif
+
+/*
+ * enable code for CORBA IDL generation?
+ */
+#ifndef IDL
+#define IDL		1
+#endif
diff --git a/SecuritySNACCRuntime/snacc.h b/SecuritySNACCRuntime/snacc.h
new file mode 100644
index 00000000..be4affc1
--- /dev/null
+++ b/SecuritySNACCRuntime/snacc.h
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * file: snacc.h
+ *
+ * INSERT_VDA_COMMENTS
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/snacc.h,v 1.1.1.1 2001/05/18 23:14:04 mb Exp $
+ * $Log: snacc.h,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:04  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:16  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:05:50  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.7  1997/04/07 13:13:18  wan
+ * Made more C++ readable (credits to Steve Walker)
+ *
+ * Revision 1.6  1997/02/28 13:39:35  wan
+ * Modifications collected for new version 1.3: Bug fixes, tk4.2.
+ *
+ * Revision 1.5  1997/02/15 20:38:48  rj
+ * In member functions, return *this after calling abort() for stupid compilers that don't seem to know about volatile abort() (they would otherwise abort with an error).
+ *
+ * Revision 1.4  1995/07/24  15:06:52  rj
+ * configure checks for mem* functions. define replacements using b* functions, if necessary.
+ *
+ */
+
+#ifndef _SNACC_H_
+#define _SNACC_H_
+
+#define GLASS	1
+#define KHO	1
+
+#include "config.h"
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL	0
+#endif
+
+#if HAVE_MEMCMP /* memcmp(3) returns <0, 0 and 0, bcmp(3) returns only 0 and !0 */
+#define memcmpeq( a, b, len)	memcmp (a, b, len)
+#else
+#define memcmpeq( a, b, len)	bcmp (a, b, len)
+#endif
+#if HAVE_MEMSET
+#define memzero( p, len)	memset (p, 0, len)
+#else
+#define memzero( p, len)	bzero (p, len)
+#endif
+#if !HAVE_MEMCPY
+#define memcpy( dst, src, len)	bcopy (src, dst, len)
+#endif
+
+#ifdef __cplusplus
+
+#ifdef VOLATILE_RETRUN
+#  define RETURN_THIS_FOR_COMPILERS_WITHOUT_VOLATILE_FUNCTIONS	return *this;
+#else
+#  define RETURN_THIS_FOR_COMPILERS_WITHOUT_VOLATILE_FUNCTIONS
+#endif
+
+#if !BOOL_BUILTIN
+#ifndef true
+// enum bool { false, true };
+// the above looks elegant, but leads to anachronisms (<, ==, !=, ... return value of type int, not enum bool), therefore:
+typedef int bool;
+enum { false, true };
+#endif
+#endif
+
+#else /* !__cplusplus */
+
+#ifndef FALSE
+#define FALSE	0
+#endif
+#ifndef TRUE
+#define TRUE	1
+#endif
+
+#endif /* __cplusplus */
+
+/*
+ *  Inspired by gdb 4.0, for better or worse...
+ *  (grabbed from Barry Brachman - MS)
+ *
+ *  These macros munge C routine declarations such
+ *  that they work for ANSI or non-ANSI C compilers
+ */
+#ifdef __USE_ANSI_C__
+
+#define PROTO( X)			X
+#define PARAMS( arglist, args)  	(args)
+#define NOPARAMS()	        	(void)
+#define _AND_				,
+#define DOTS				, ...
+
+#else /* !__USE_ANSI_C__ */
+
+#define PROTO( X)			()
+#define PARAMS( arglist, args)	 	arglist args;
+#define NOPARAMS()	        	()
+#define _AND_				;
+#define DOTS
+#define void                            char
+
+#endif /* __USE_ANSI_C__ */
+
+#include "policy.h"
+
+#if COMPILER
+#define TCL	(HAVE_TCL && !NO_TCL)
+#define META	(TCL && !NO_META)
+#endif
+
+#if MAKEDEPEND
+#if !NO_META
+#ifdef META
+#undef META
+#endif
+#define META	1
+#endif
+#if !NO_TCL
+#ifdef TCL
+#undef TCL
+#endif
+#define TCL	1
+#endif
+#endif
+
+#if TCL
+#ifdef META
+#undef META
+#endif
+#define META	1
+#endif
+
+#define COMMA			,
+
+#ifdef _IBM_ENC_
+#define if_IBM_ENC( code)	code
+#else
+#define if_IBM_ENC( code)
+#endif
+
+#if META
+#define if_META( code)		code
+#else
+#define if_META( code)
+#endif
+
+#if TCL && META
+#define if_TCL( code)		code
+#else
+#define if_TCL( code)
+#endif
+
+#ifndef _gVDADER_RULES
+extern int gVDADER_RULES;
+#endif
+
+#endif /* _SNACC_H_ */
diff --git a/SecuritySNACCRuntime/snacc.pbproj/project.pbxproj b/SecuritySNACCRuntime/snacc.pbproj/project.pbxproj
new file mode 100644
index 00000000..76fac8f3
--- /dev/null
+++ b/SecuritySNACCRuntime/snacc.pbproj/project.pbxproj
@@ -0,0 +1,1372 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 31;
+	objects = {
+		00FA20B2FFD8762011CD2A97 = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		00FA20B3FFD8762011CD2A97 = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		0509B1B6FF15460611CD283A = {
+			isa = PBXFrameworkReference;
+			path = SecuritySNACCRuntime.framework;
+			refType = 3;
+		};
+		15CACFCEFF6579E2D0A17CE7 = {
+			isa = PBXFileReference;
+			name = cdsaUtils.cpp;
+			path = "c++-lib/src/cdsaUtils.cpp";
+			refType = 4;
+		};
+		15CACFCFFF6579E2D0A17CE7 = {
+			fileRef = 15CACFCEFF6579E2D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		15CACFD0FF657A5BD0A17CE7 = {
+			isa = PBXFileReference;
+			name = cdsaUtils.h;
+			path = "c++-lib/inc/cdsaUtils.h";
+			refType = 4;
+		};
+		15CACFD1FF657A5BD0A17CE7 = {
+			fileRef = 15CACFD0FF657A5BD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		15CACFD2FF657BF5D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			name = cdsa_utilities.framework;
+			path = /System/Library/PrivateFrameworks/cdsa_utilities.framework;
+			refType = 0;
+		};
+		15CACFD3FF657BF5D0A17CE7 = {
+			fileRef = 15CACFD2FF657BF5D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		3D3E9FE5FEF01C90D0A17CE7 = {
+			buildStyles = (
+				00FA20B2FFD8762011CD2A97,
+				00FA20B3FFD8762011CD2A97,
+			);
+			isa = PBXProject;
+			mainGroup = 3D3E9FE6FEF01C90D0A17CE7;
+			productRefGroup = 5D41A7C1FEF026FFD0A17CE7;
+			projectDirPath = .;
+			targets = (
+				6B215E98FEF02818D0A17CE7,
+				5D41A7C3FEF026FFD0A17CE7,
+				3D3E9FE8FEF01D16D0A17CE7,
+			);
+		};
+		3D3E9FE6FEF01C90D0A17CE7 = {
+			children = (
+				3D3E9FE7FEF01D16D0A17CE7,
+				5D41A7C1FEF026FFD0A17CE7,
+				6B215E9BFEF02ACDD0A17CE7,
+				6B215E9CFEF02ACDD0A17CE7,
+				15CACFCEFF6579E2D0A17CE7,
+				15CACFD2FF657BF5D0A17CE7,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		3D3E9FE7FEF01D16D0A17CE7 = {
+			children = (
+				5D41A792FEF026FFD0A17CE7,
+				5D41A793FEF026FFD0A17CE7,
+				5D41A794FEF026FFD0A17CE7,
+				5D41A795FEF026FFD0A17CE7,
+				5D41A796FEF026FFD0A17CE7,
+				5D41A797FEF026FFD0A17CE7,
+				5D41A798FEF026FFD0A17CE7,
+				5D41A799FEF026FFD0A17CE7,
+				5D41A79AFEF026FFD0A17CE7,
+				5D41A79BFEF026FFD0A17CE7,
+				5D41A79CFEF026FFD0A17CE7,
+				5D41A79DFEF026FFD0A17CE7,
+				5D41A79EFEF026FFD0A17CE7,
+				5D41A79FFEF026FFD0A17CE7,
+				5D41A7A0FEF026FFD0A17CE7,
+				5D41A7A1FEF026FFD0A17CE7,
+				5D41A7A2FEF026FFD0A17CE7,
+				5D41A7A3FEF026FFD0A17CE7,
+				5D41A7A4FEF026FFD0A17CE7,
+				5D41A7A5FEF026FFD0A17CE7,
+				5D41A7A6FEF026FFD0A17CE7,
+				5D41A7A7FEF026FFD0A17CE7,
+				5D41A7A8FEF026FFD0A17CE7,
+				5D41A7A9FEF026FFD0A17CE7,
+				5D41A7AAFEF026FFD0A17CE7,
+				5D41A7ABFEF026FFD0A17CE7,
+				5D41A7ACFEF026FFD0A17CE7,
+				5D41A7ADFEF026FFD0A17CE7,
+				5D41A7AEFEF026FFD0A17CE7,
+				5D41A7AFFEF026FFD0A17CE7,
+				5D41A7B0FEF026FFD0A17CE7,
+				5D41A7B1FEF026FFD0A17CE7,
+				5D41A7B2FEF026FFD0A17CE7,
+				5D41A7B3FEF026FFD0A17CE7,
+				5D41A7B4FEF026FFD0A17CE7,
+				5D41A7B5FEF026FFD0A17CE7,
+				5D41A7B6FEF026FFD0A17CE7,
+				5D41A7B7FEF026FFD0A17CE7,
+				5D41A7B8FEF026FFD0A17CE7,
+				5D41A7B9FEF026FFD0A17CE7,
+				5D41A7BAFEF026FFD0A17CE7,
+				5D41A7BBFEF026FFD0A17CE7,
+				5D41A7BCFEF026FFD0A17CE7,
+				5D41A7BDFEF026FFD0A17CE7,
+				5D41A7BEFEF026FFD0A17CE7,
+				5D41A7BFFEF026FFD0A17CE7,
+				5D41A7C0FEF026FFD0A17CE7,
+				15CACFD0FF657A5BD0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "c++-lib";
+			refType = 4;
+		};
+		3D3E9FE8FEF01D16D0A17CE7 = {
+			buildArgumentsString = "-f $(SRCROOT)/MacOSX-make SRCROOT=$(SRCROOT) $ACTION";
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = UnixBuild;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			buildToolPath = /usr/bin/make;
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = UnixBuild;
+			productName = UnixBuild;
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 287;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		5D41A792FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-any.cpp";
+			path = "c++-lib/c++/asn-any.cpp";
+			refType = 4;
+		};
+		5D41A793FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-bits.cpp";
+			path = "c++-lib/c++/asn-bits.cpp";
+			refType = 4;
+		};
+		5D41A794FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-bool.cpp";
+			path = "c++-lib/c++/asn-bool.cpp";
+			refType = 4;
+		};
+		5D41A795FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-enum.cpp";
+			path = "c++-lib/c++/asn-enum.cpp";
+			refType = 4;
+		};
+		5D41A796FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-int.cpp";
+			path = "c++-lib/c++/asn-int.cpp";
+			refType = 4;
+		};
+		5D41A797FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-len.cpp";
+			path = "c++-lib/c++/asn-len.cpp";
+			refType = 4;
+		};
+		5D41A798FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-list.cpp";
+			path = "c++-lib/c++/asn-list.cpp";
+			refType = 4;
+		};
+		5D41A799FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-null.cpp";
+			path = "c++-lib/c++/asn-null.cpp";
+			refType = 4;
+		};
+		5D41A79AFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-octs.cpp";
+			path = "c++-lib/c++/asn-octs.cpp";
+			refType = 4;
+		};
+		5D41A79BFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-oid.cpp";
+			path = "c++-lib/c++/asn-oid.cpp";
+			refType = 4;
+		};
+		5D41A79CFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-real.cpp";
+			path = "c++-lib/c++/asn-real.cpp";
+			refType = 4;
+		};
+		5D41A79DFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-tag.cpp";
+			path = "c++-lib/c++/asn-tag.cpp";
+			refType = 4;
+		};
+		5D41A79EFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-type.cpp";
+			path = "c++-lib/c++/asn-type.cpp";
+			refType = 4;
+		};
+		5D41A79FFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-useful.cpp";
+			path = "c++-lib/c++/asn-useful.cpp";
+			refType = 4;
+		};
+		5D41A7A0FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = hash.cpp;
+			path = "c++-lib/c++/hash.cpp";
+			refType = 4;
+		};
+		5D41A7A1FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = meta.cpp;
+			path = "c++-lib/c++/meta.cpp";
+			refType = 4;
+		};
+		5D41A7A2FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = print.cpp;
+			path = "c++-lib/c++/print.cpp";
+			refType = 4;
+		};
+		5D41A7A3FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "str-stk.cpp";
+			path = "c++-lib/c++/str-stk.cpp";
+			refType = 4;
+		};
+		5D41A7A4FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "tcl-if.cpp";
+			path = "c++-lib/c++/tcl-if.cpp";
+			refType = 4;
+		};
+		5D41A7A5FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-any.h";
+			path = "c++-lib/inc/asn-any.h";
+			refType = 4;
+		};
+		5D41A7A6FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-bits.h";
+			path = "c++-lib/inc/asn-bits.h";
+			refType = 4;
+		};
+		5D41A7A7FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-bool.h";
+			path = "c++-lib/inc/asn-bool.h";
+			refType = 4;
+		};
+		5D41A7A8FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-buf.h";
+			path = "c++-lib/inc/asn-buf.h";
+			refType = 4;
+		};
+		5D41A7A9FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-config.h";
+			path = "c++-lib/inc/asn-config.h";
+			refType = 4;
+		};
+		5D41A7AAFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-enum.h";
+			path = "c++-lib/inc/asn-enum.h";
+			refType = 4;
+		};
+		5D41A7ABFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-incl.h";
+			path = "c++-lib/inc/asn-incl.h";
+			refType = 4;
+		};
+		5D41A7ACFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-int.h";
+			path = "c++-lib/inc/asn-int.h";
+			refType = 4;
+		};
+		5D41A7ADFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-len.h";
+			path = "c++-lib/inc/asn-len.h";
+			refType = 4;
+		};
+		5D41A7AEFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-list.h";
+			path = "c++-lib/inc/asn-list.h";
+			refType = 4;
+		};
+		5D41A7AFFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-null.h";
+			path = "c++-lib/inc/asn-null.h";
+			refType = 4;
+		};
+		5D41A7B0FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-octs.h";
+			path = "c++-lib/inc/asn-octs.h";
+			refType = 4;
+		};
+		5D41A7B1FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-oid.h";
+			path = "c++-lib/inc/asn-oid.h";
+			refType = 4;
+		};
+		5D41A7B2FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-real.h";
+			path = "c++-lib/inc/asn-real.h";
+			refType = 4;
+		};
+		5D41A7B3FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-tag.h";
+			path = "c++-lib/inc/asn-tag.h";
+			refType = 4;
+		};
+		5D41A7B4FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-type.h";
+			path = "c++-lib/inc/asn-type.h";
+			refType = 4;
+		};
+		5D41A7B5FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "asn-useful.h";
+			path = "c++-lib/inc/asn-useful.h";
+			refType = 4;
+		};
+		5D41A7B6FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = config.h;
+			path = "c++-lib/inc/config.h";
+			refType = 4;
+		};
+		5D41A7B7FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = hash.h;
+			path = "c++-lib/inc/hash.h";
+			refType = 4;
+		};
+		5D41A7B8FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = init.h;
+			path = "c++-lib/inc/init.h";
+			refType = 4;
+		};
+		5D41A7B9FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = meta.h;
+			path = "c++-lib/inc/meta.h";
+			refType = 4;
+		};
+		5D41A7BAFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = policy.h;
+			path = "c++-lib/inc/policy.h";
+			refType = 4;
+		};
+		5D41A7BBFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = print.h;
+			path = "c++-lib/inc/print.h";
+			refType = 4;
+		};
+		5D41A7BCFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_vdasnacc.h;
+			path = "c++-lib/inc/sm_vdasnacc.h";
+			refType = 4;
+		};
+		5D41A7BDFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_vdatypes.h;
+			path = "c++-lib/inc/sm_vdatypes.h";
+			refType = 4;
+		};
+		5D41A7BEFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = snacc.h;
+			path = "c++-lib/inc/snacc.h";
+			refType = 4;
+		};
+		5D41A7BFFEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "str-stk.h";
+			path = "c++-lib/inc/str-stk.h";
+			refType = 4;
+		};
+		5D41A7C0FEF026FFD0A17CE7 = {
+			isa = PBXFileReference;
+			name = "tcl-if.h";
+			path = "c++-lib/inc/tcl-if.h";
+			refType = 4;
+		};
+		5D41A7C1FEF026FFD0A17CE7 = {
+			children = (
+				0509B1B6FF15460611CD283A,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		5D41A7C3FEF026FFD0A17CE7 = {
+			buildPhases = (
+				5D41A7C4FEF026FFD0A17CE7,
+				5D41A7E1FEF026FFD0A17CE7,
+				5D41A7E2FEF026FFD0A17CE7,
+				5D41A7F6FEF026FFD0A17CE7,
+				5D41A7F7FEF026FFD0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYMROOT)\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-DVDADER_RULES";
+				OTHER_LDFLAGS = "-lstdc++ -sectorder __TEXT __text $(APPLE_INTERNAL_DIR)/OrderFiles/SecuritySNACCRuntime.order";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = SecuritySNACCRuntime;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXFrameworkTarget;
+			name = snaccRuntime;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = SecuritySNACCRuntime;
+			productReference = 0509B1B6FF15460611CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>SecuritySNACCRuntime</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		5D41A7C4FEF026FFD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				5D41A7C5FEF026FFD0A17CE7,
+				5D41A7C6FEF026FFD0A17CE7,
+				5D41A7C7FEF026FFD0A17CE7,
+				5D41A7C8FEF026FFD0A17CE7,
+				5D41A7C9FEF026FFD0A17CE7,
+				5D41A7CAFEF026FFD0A17CE7,
+				5D41A7CBFEF026FFD0A17CE7,
+				5D41A7CCFEF026FFD0A17CE7,
+				5D41A7CDFEF026FFD0A17CE7,
+				5D41A7CEFEF026FFD0A17CE7,
+				5D41A7CFFEF026FFD0A17CE7,
+				5D41A7D0FEF026FFD0A17CE7,
+				5D41A7D1FEF026FFD0A17CE7,
+				5D41A7D2FEF026FFD0A17CE7,
+				5D41A7D3FEF026FFD0A17CE7,
+				5D41A7D4FEF026FFD0A17CE7,
+				5D41A7D5FEF026FFD0A17CE7,
+				5D41A7D6FEF026FFD0A17CE7,
+				5D41A7D7FEF026FFD0A17CE7,
+				5D41A7D8FEF026FFD0A17CE7,
+				5D41A7D9FEF026FFD0A17CE7,
+				5D41A7DAFEF026FFD0A17CE7,
+				5D41A7DBFEF026FFD0A17CE7,
+				5D41A7DCFEF026FFD0A17CE7,
+				5D41A7DDFEF026FFD0A17CE7,
+				5D41A7DEFEF026FFD0A17CE7,
+				5D41A7DFFEF026FFD0A17CE7,
+				5D41A7E0FEF026FFD0A17CE7,
+				15CACFD1FF657A5BD0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		5D41A7C5FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A5FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7C6FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A6FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7C7FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A7FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7C8FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A8FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7C9FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A9FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7CAFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7AAFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7CBFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7ABFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7CCFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7ACFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7CDFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7ADFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7CEFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7AEFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7CFFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7AFFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D0FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B0FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D1FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B1FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D2FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B2FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D3FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B3FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D4FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B4FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D5FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B5FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D6FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B6FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D7FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B7FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D8FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B8FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7D9FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7B9FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7DAFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7BAFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7DBFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7BBFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7DCFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7BCFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7DDFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7BDFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7DEFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7BEFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7DFFEF026FFD0A17CE7 = {
+			fileRef = 5D41A7BFFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7E0FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7C0FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7E1FEF026FFD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		5D41A7E2FEF026FFD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				5D41A7E3FEF026FFD0A17CE7,
+				5D41A7E4FEF026FFD0A17CE7,
+				5D41A7E5FEF026FFD0A17CE7,
+				5D41A7E6FEF026FFD0A17CE7,
+				5D41A7E7FEF026FFD0A17CE7,
+				5D41A7E8FEF026FFD0A17CE7,
+				5D41A7E9FEF026FFD0A17CE7,
+				5D41A7EAFEF026FFD0A17CE7,
+				5D41A7EBFEF026FFD0A17CE7,
+				5D41A7ECFEF026FFD0A17CE7,
+				5D41A7EDFEF026FFD0A17CE7,
+				5D41A7EEFEF026FFD0A17CE7,
+				5D41A7EFFEF026FFD0A17CE7,
+				5D41A7F0FEF026FFD0A17CE7,
+				5D41A7F1FEF026FFD0A17CE7,
+				5D41A7F2FEF026FFD0A17CE7,
+				5D41A7F3FEF026FFD0A17CE7,
+				5D41A7F4FEF026FFD0A17CE7,
+				5D41A7F5FEF026FFD0A17CE7,
+				6B215E9DFEF02ACDD0A17CE7,
+				6B215E9EFEF02ACDD0A17CE7,
+				15CACFCFFF6579E2D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		5D41A7E3FEF026FFD0A17CE7 = {
+			fileRef = 5D41A792FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7E4FEF026FFD0A17CE7 = {
+			fileRef = 5D41A793FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7E5FEF026FFD0A17CE7 = {
+			fileRef = 5D41A794FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7E6FEF026FFD0A17CE7 = {
+			fileRef = 5D41A795FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7E7FEF026FFD0A17CE7 = {
+			fileRef = 5D41A796FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7E8FEF026FFD0A17CE7 = {
+			fileRef = 5D41A797FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7E9FEF026FFD0A17CE7 = {
+			fileRef = 5D41A798FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7EAFEF026FFD0A17CE7 = {
+			fileRef = 5D41A799FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7EBFEF026FFD0A17CE7 = {
+			fileRef = 5D41A79AFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7ECFEF026FFD0A17CE7 = {
+			fileRef = 5D41A79BFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7EDFEF026FFD0A17CE7 = {
+			fileRef = 5D41A79CFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7EEFEF026FFD0A17CE7 = {
+			fileRef = 5D41A79DFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7EFFEF026FFD0A17CE7 = {
+			fileRef = 5D41A79EFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7F0FEF026FFD0A17CE7 = {
+			fileRef = 5D41A79FFEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7F1FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A0FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7F2FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A1FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7F3FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A2FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7F4FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A3FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7F5FEF026FFD0A17CE7 = {
+			fileRef = 5D41A7A4FEF026FFD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5D41A7F6FEF026FFD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				15CACFD3FF657BF5D0A17CE7,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		5D41A7F7FEF026FFD0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		6B215E98FEF02818D0A17CE7 = {
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = World;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				6B215E9AFEF02818D0A17CE7,
+			);
+			isa = PBXAggregateTarget;
+			name = World;
+			productName = World;
+			shouldUseHeadermap = 0;
+		};
+		6B215E9AFEF02818D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 5D41A7C3FEF026FFD0A17CE7;
+		};
+		6B215E9BFEF02ACDD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_buffer.cpp;
+			path = "c++-lib/src/sm_buffer.cpp";
+			refType = 4;
+		};
+		6B215E9CFEF02ACDD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sm_vdasnacc.cpp;
+			path = "c++-lib/src/sm_vdasnacc.cpp";
+			refType = 4;
+		};
+		6B215E9DFEF02ACDD0A17CE7 = {
+			fileRef = 6B215E9BFEF02ACDD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6B215E9EFEF02ACDD0A17CE7 = {
+			fileRef = 6B215E9CFEF02ACDD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+	};
+	rootObject = 3D3E9FE5FEF01C90D0A17CE7;
+}
diff --git a/SecuritySNACCRuntime/stamp-h b/SecuritySNACCRuntime/stamp-h
new file mode 100644
index 00000000..371c8388
--- /dev/null
+++ b/SecuritySNACCRuntime/stamp-h
@@ -0,0 +1 @@
+Thu Dec 21 15:42:05 PST 2000
diff --git a/SecuritySNACCRuntime/stamp-h.in b/SecuritySNACCRuntime/stamp-h.in
new file mode 100644
index 00000000..925eace8
--- /dev/null
+++ b/SecuritySNACCRuntime/stamp-h.in
@@ -0,0 +1 @@
+Thu Dec 21 14:13:51 PST 2000
diff --git a/SecuritySNACCRuntime/tbl-example/README b/SecuritySNACCRuntime/tbl-example/README
new file mode 100644
index 00000000..8da983ae
--- /dev/null
+++ b/SecuritySNACCRuntime/tbl-example/README
@@ -0,0 +1,89 @@
+(RCS control information is at the end of this file.)
+
+
+Table encoder/decoder example README - MS 93
+------------------------------------
+
+This directory contains an example that shows:
+
+   1. the process of creating and using tables.
+   2. examples of decoding, printing, and encoding.
+
+
+To dive right in just type "make" in this directory.  That will
+create the "example" executable (you should have previously installed
+the snacc and mkchdr progs and the table library).
+
+Then type:
+
+ make check
+
+and see what happens. Look in example.c and makefile to see how things
+work.
+
+
+
+Questions and Answers
+---------------------
+
+Q. What is a table? (also refered to a type table or type tree)
+
+A. A table is simply a data structure that holds a description of
+   the types from an ASN.1 module.  This table can then be used
+   by a number of "generic" routines to do ASN.1 related (BER
+   encoding/decoding) or other useful things such as printing
+   values, freeing values and whatever else you can dream up.
+
+
+Q. How do I create a table from my ASN.1 source files?
+
+A. Run snacc with the -T option, e.g.:
+
+     snacc -T mytbls.tt myMod1.asn1 myMod2.asn1
+
+   the above command will create the "mytbls.tt" file that
+   holds the descriptions of the ASN.1 types in the "myMod1.asn1"
+   and "myMod2.asn1" files. (look in the makefile in this directory)
+
+
+Q. Why is there only a C interface to tables?
+
+A. Time. Tables drivers create/read/free these types
+   without having seen a typedef for them.  The C implementation
+   uses some assumptions about how structures etc. are allocated
+   and accessed.  With C++ this is much more difficult.  It can
+   be done but required more time than I had.
+
+
+Q. Ok, tables sound great, what's the catch?
+
+A. Well,
+
+   1. table driven encoding and decoding is something like
+      4 times slower than the C or C++ version.
+      (but tables are *way* smaller than the .o's for the compiled approach)
+   2. the ANY DEFINED BY stuff is not supported at all.
+   3. subtype information is not included in the tables (time crunch again)
+      (PER encoders/decoders will need the subtype info)
+   4. Values from the ASN.1 source are not included in the table.
+
+   If you have the time and skills, you can fix 2, 3 and 4.  1 is harder.
+
+
+
+Q.  Tell me more.
+
+A.  Look at the manual. (in .../doc/)
+
+#-------------------------------------------------------------------------------
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tbl-example/README,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: README,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:54  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.1  1997/02/15 19:33:24  rj
+# first check-in
+#
diff --git a/SecuritySNACCRuntime/tbl-example/dependencies b/SecuritySNACCRuntime/tbl-example/dependencies
new file mode 100644
index 00000000..e69de29b
diff --git a/SecuritySNACCRuntime/tbl-example/example.c b/SecuritySNACCRuntime/tbl-example/example.c
new file mode 100644
index 00000000..0650ec15
--- /dev/null
+++ b/SecuritySNACCRuntime/tbl-example/example.c
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * file: .../tbl-example/example.c - decodes and prints a given BER
+ * PersonnelRecord value and re-encodes it to the file
+ * "p-rec.out.ber".  This example would be similar to your user code in
+ * that you run "mkchdr" to build a nicely named description of data
+ * structure (PersonnelRecord in this case).  The table tools deal with
+ * the same data structure in a generic way and don't use/need mkchdr.
+ * You must not change the output of mkchdr otherwise the table encoder
+ * decoder, etc will not understand it.
+ *
+ * Mike Sample
+ *
+ * Copyright (C) 1993 Michael Sample
+ *            and the University of British Columbia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program and the associated libraries are distributed in the hope
+ * that they will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License and GNU Library General
+ * Public License for more details.
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tbl-example/example.c,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+ * $Log: example.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:10  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:30  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:06:53  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1997/02/15 19:33:26  rj
+ * first check-in
+ *
+ */
+
+#include "tbl-incl.h"
+#include "exp-buf.h"
+#include "sbuf.h"
+
+#include "p-rec.h"  /* include the file we made with mkchdr */
+
+
+char *outputFileNameG = "p-rec.out.ber";
+
+void Usage PARAMS ((prg),
+    char *prg)
+{
+    fprintf (stderr, "Usage: %s <tt file name> <p-rec ber file> \n\n", prg);
+    fprintf (stderr, "E.g.  %s p-rec.tt  p-rec.ber\n\n", prg);
+    fprintf (stderr, "The BER values in the file list will be decoded, printed to stdout and then re-encoded to the file \"%s\"\n", outputFileNameG);
+}
+
+
+int
+main PARAMS ((argc, argv),
+    int argc _AND_
+    char **argv)
+{
+    char *tblFileName;
+    char *berFileName;
+    TBL *tbl;
+    int i;
+    char *fileData;
+    unsigned long int fsize;
+    PersonnelRecord *val;
+    unsigned long int bytesDecoded;
+    unsigned long int bytesEncoded;
+    SBuf sb;  /* use simple buffers for reading in (know sizes) */
+    ExpBuf *ebPtr; /* use expanding bufs for enc (usually don't know sizes)*/
+    GenBuf gb;
+    FILE *outputFile;
+
+
+
+    if (argc != 3)
+    {
+        Usage (argv[0]);
+        return 1;
+    }
+
+    tblFileName = argv[1];
+    berFileName = argv[2];
+
+    /* init mem pool to hold  decoded val */
+    InitNibbleMem (1024, 1024);
+
+    /* read in and decode the type table */
+    tbl = LoadTblFile (tblFileName);
+    if (tbl == NULL)
+        return 1;
+
+    fileData = LoadFile (berFileName, &fsize);
+    if (fileData == NULL)
+        return 1;
+
+    SBufInstallData (&sb, fileData, fsize);
+    PutSBufInGenBuf (&sb, &gb);
+
+    fprintf (stdout, "\n\n-- decoded contents of BER PersonnelRecord file: \"%s\"--\n", berFileName);
+
+    val = TblDecode (tbl, NULL, "PersonnelRecord", &gb, &bytesDecoded);
+
+    if (val == NULL)
+        fprintf (stdout, "-- Decoding error occured somewhere -- \n");
+    else
+        TblPrintValue (tbl, NULL, "PersonnelRecord", stdout, val);
+
+    fprintf (stdout, "\n\n -- decoded %d bytes for the above value --\n\n", bytesDecoded, berFileName);
+
+    free (fileData); /* was malloc'd in LoadFile */
+
+    /*
+     * process value here
+     * (This is where the header file generated by mkchdr is
+     * useful - you can access the decoded value in a standard
+     * /easier way).
+     *
+     * Ok, well, the names "field0" etc aren't that nice
+     * but what did you expect - they aren't named in the ASN.1
+     * spec so mkchdr just makes them up.  To fix this, just
+     * add field names to you ASN.1 spec - it will not change the
+     * way the values are encoded - so you're not making it
+     * incompatible with the original. (not including value notation)
+     */
+    printf ("The following printout is an example of using the\n");
+    printf ("hdr file generated by mkchdr to access the data\n");
+    printf ("returned from the table decoder.  Look in \"example.c\"\n\n");
+
+
+    printf ("***** JQ GUMBY & CO Database *****************************************\n");
+    printf ("Employee Name:      %s %s %s\n", val->field0->givenName->octs, val->field0->initial->octs, val->field0->familyName->octs);
+    printf ("Title:              %s\n", val->title->octs);
+    printf ("Employee Number:    %d\n", *val->field1);
+    printf ("Date of Hire:       %s\n", val->dateOfHire->octs);
+    printf ("Name of Spouse:     %s %s %s\n", val->nameOfSpouse->givenName->octs, val->nameOfSpouse->initial->octs, val->nameOfSpouse->familyName->octs);
+    printf ("Number of Children: %d\n", AsnListCount (val->children));
+    printf ("**********************************************************************\n\n");
+
+    /*
+     * finished playing with the decoded value.
+     * now re-encode the value.  Using an expbuf to hold the encoded val
+     * because they can grow and in general you can predict a values
+     * encoded size (although we could assume that is would be close to
+     * the same size as the one we read in at the beginning of this prg).
+     * (note: the size of PersonnelRecord BER value we decoded may be
+     * different from the size of the re-encoded version depending on
+     * the use of indefinite or definite lengths.  Both are valid BER.)
+     */
+    fprintf (stdout, "now re-encoding the PersonnelRecord value to \"%s\"\n", outputFileNameG);
+
+    ebPtr = ExpBufAllocBufAndData();
+    ExpBufResetInWriteRvsMode (ebPtr); /* set up to hold encoding (= writing) */
+
+    PutExpBufInGenBuf (ebPtr, &gb);
+
+    if (TblEncode (tbl, NULL, "PersonnelRecord", &gb, val, &bytesEncoded) < 0)
+        fprintf (stderr, "main: error encoding the PersonnelRecord\n");
+
+    /* copy ExpBuf data to file */
+    outputFile = fopen (outputFileNameG, "w");
+    if (outputFile == NULL)
+    {
+        fprintf (stderr, "error - could not open file \"%s\"\n", outputFileNameG);
+        perror ("main: fopen:");
+    }
+
+    ExpBufCopyToFile (ebPtr, outputFile);
+
+    fclose (outputFile);
+
+    /* free the encoded version */
+    ExpBufFreeBufAndDataList (ebPtr);
+
+
+    return 0;
+} /* main */
diff --git a/SecuritySNACCRuntime/tbl-example/makefile b/SecuritySNACCRuntime/tbl-example/makefile
new file mode 100644
index 00000000..d18d51c1
--- /dev/null
+++ b/SecuritySNACCRuntime/tbl-example/makefile
@@ -0,0 +1,88 @@
+# file: .../tbl-example/makefile
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tbl-example/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:53  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.1  1997/02/15 19:33:26  rj
+# first check-in
+#
+
+include ../makehead
+
+TOP		= ..
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+
+ASN1_C_LIB_DIR	= $(TOP)/c-lib
+ASN1_C_INC_DIR	= $(ASN1_C_LIB_DIR)/inc
+TTBL_ASN1_LIB	= $(ASN1_C_LIB_DIR)/libasn1ctbl.a
+
+COMPILERDIR	= $(TOP)/compiler
+SNACC		= $(COMPILERDIR)/snacc
+USEFUL_TYPES	= $(ASN1_SRC_DIR)/asn-useful.asn1
+SNACCFLAGS	= -u $(USEFUL_TYPES)
+
+TBLTOOLSDIR	= $(TOP)/tbl-tools
+MKHDR		= $(TBLTOOLSDIR)/mkchdr/mkchdr
+
+ASN1FILES	= $(ASN1_SRC_DIR)/p-rec.asn1
+ASN1TTFILE	= p-rec.tt
+ASN1TTHFILE	= p-rec.h
+
+CFILES	= example.c
+OFILES	= example.o
+
+DISTFILES = \
+	README		\
+	makefile	\
+	$(CFILES)	\
+	p-rec.ber
+
+CPPFLAGS	+= -I$(TOP) -I$(ASN1_C_INC_DIR) -DUSE_GEN_BUF
+
+#-------------------------------------------------------------------------------
+
+all::		example
+
+example:	$(OFILES) $(TTBL_ASN1_LIB)
+		$(REASON)
+		$(CC) $(CFLAGS) -o example $(OFILES) $(TTBL_ASN1_LIB) $(LIBS)
+
+$(ASN1TTFILE):	$(ASN1FILES)
+		$(REASON)
+		$(SNACC) $(SNACCFLAGS) -T $@ $(ASN1FILES)
+
+$(SNACC) $(MKHDR):
+		cd $(@D) && $(MAKE) $(@F)
+
+$(TTBL_ASN1_LIB):
+		cd $(@D) && $(MAKE) tbl-lib
+
+$(ASN1TTHFILE):	$(ASN1TTFILE)
+		$(REASON)
+		$(MKHDR) $? $@
+
+check::		example $(ASN1TTFILE)
+
+check::
+		./example p-rec.tt p-rec.ber
+		cmp p-rec.ber p-rec.out.ber
+		@echo "+++ the test was successful"
+
+# dummy:
+install::
+
+clean::
+		$(RM) example *.o *~ core .emacs* $(ASN1TTFILE) $(ASN1TTHFILE) p-rec.out.ber
+
+depend::
+		$(MAKE) $(MKHDR)
+
+depend::	$(ASN1TTHFILE)
+
+include ../maketail
diff --git a/SecuritySNACCRuntime/tbl-example/p-rec.ber b/SecuritySNACCRuntime/tbl-example/p-rec.ber
new file mode 100644
index 0000000000000000000000000000000000000000..f8cc9410ed7be7741ca4c0e0805cce1fbee7df6a
GIT binary patch
literal 145
zcmYdj>`N37WAVz*$P;696=My~%`C}SARxvUl98(5l$oyJoROMZoEqQAz|7b-e<7DM
zhoPl~k%6Is$s!?;M&HDuN-;(ssK&*PhVqGmVys??xv9lsj6pE-z}igB4U7#94CO%D
Td@_p@#Tb22<jo8X%!~{HLggjQ

literal 0
HcmV?d00001

diff --git a/SecuritySNACCRuntime/tbl-example/p-rec.h b/SecuritySNACCRuntime/tbl-example/p-rec.h
new file mode 100644
index 00000000..ce691616
--- /dev/null
+++ b/SecuritySNACCRuntime/tbl-example/p-rec.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  type definitions for the values that the snacc table
+ *  decoder will return and snacc table encoder expects
+ *  for the type table that contains the following modules:
+ *  
+ *      P-REC
+ *
+ *  UBC snacc written by Mike Sample
+ *  NOTE: This is a machine generated file 
+ *  NOTE2: Table routines don't use this so feel free to make changes
+ *       that do not affect the structure. Changing field 
+ *       and type names is fine.
+ */
+
+
+/* start of module P-REC's definitions */
+
+typedef AsnInt EmployeeNumber;
+
+typedef struct Name
+{
+    IA5String* givenName;
+    IA5String* initial;
+    IA5String* familyName;
+} Name;
+
+typedef IA5String Date;
+
+typedef struct ChildInformation
+{
+    Name* field0;
+    Date* dateOfBirth;
+} ChildInformation;
+
+typedef AsnList PersonnelRecordSeqOf;
+
+typedef struct PersonnelRecord
+{
+    Name* field0;
+    IA5String* title;
+    EmployeeNumber* field1;
+    Date* dateOfHire;
+    Name* nameOfSpouse;
+    PersonnelRecordSeqOf* children;
+} PersonnelRecord;
+
diff --git a/SecuritySNACCRuntime/tbl-example/p-rec.tt b/SecuritySNACCRuntime/tbl-example/p-rec.tt
new file mode 100644
index 0000000000000000000000000000000000000000..308e9e3045c7485341b18ac0270a08ac806484da
GIT binary patch
literal 1612
zcmaKs%Wl&^6o!2!mpUP7Lnq}f?ociYno7_OVo^$fO3+kITCsKGNjsHehsm^RSvgi#
zyhZ9~V2#9vC*U=Bg>XDhLfT?hx%l&cuK!^{_B{bY;1Yqy1nv-6#2-IdkX>Q{QGRBl
zvRPdXzz74<VowMdbhg^=INmYm>j&)}F4=+)&;#Qn$7b??QidNA-(Uv>fTq{2HfQ@j
zm=R&JY(xNrp9b6Px(`MCH#ASO1PTB~KesCmxvO8fdhX$jaD@_<!)}~=ly6yW;T-E1
zA7C{!{l-$9U5mj<*wiG{khKV;XlZp%IQE*`@?_gm!gE>8hukDngTTe`)!-#7O-BUG
zlr2t6W5Y&OU};AGf{npzt=B@TJ+?w1P0Jfxc0JeS&L(eq(ysH*wHABmLw-6|DJ&1>
zPsd6{v3kD=Wa!)(4c7ZLohx?L2zx&Uz3-<LbhdZ?ovrS9MhWHc(=QoOSWGV(Pux8$
z5#sLY67zA1?}g;-(HV}!TokxpaB=*#R=wjLbUC}P$>BtCG><gEux~b_QAqA)3>Kum
z`T3RldS$C#eY^D`fMFP<PS{fdSz4;??DM92!@Er>I?9u*>_cjjCys1JZ{H*QLW{Ve
zT#9C0N#X9EBj+`VJ8fcjkx<r-!xLCKR?X33gF9UDqXe?7$@>KIG}l;O`Y(l!yFh2R
zh0VQW!G*D4f#%j$UL*)!8Yft!#dp%`>?M|cbxh9E;<o6D<f5->a*@CsEv(gR%g>h+
zg2y2CyoABI%cbQckk_^3U33<m*=npd1fGYp6TGY$oXb3&8>xve-2NwfWz14Kx8>sb
zkln=CH#CcrDbw8Rj~fXY-qch8O9U3ES^d<gZmzF<U;*5ozGAp&W*9(W5P%t3CDVh^
zV&ju+B+)O~Xpg3<NZ#VO*iCH}yp(@AqPcnDo+IP?GK{U1jjXhQma{5{mUF->_TTOA
zef6P$>mMEs4%xGj6-v>ajjmGkiTR}Ce7a}?hgZ;9OBHq8;q2bDb+pB!yo+8_aaFM#
fvFmc1-SUA<{Dn}Qbk34HLP<*=_f4$Lvr+pGi<xYK

literal 0
HcmV?d00001

diff --git a/SecuritySNACCRuntime/tbl-tools/makefile b/SecuritySNACCRuntime/tbl-tools/makefile
new file mode 100644
index 00000000..6fcdbe6d
--- /dev/null
+++ b/SecuritySNACCRuntime/tbl-tools/makefile
@@ -0,0 +1,55 @@
+#
+# Makes all of the type table tools
+# (currently mkchdr, pval and ptbl)
+#
+# The library in snacc/tbl-lib must be made prior to making these tools
+#
+# MS 93
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tbl-tools/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.2  2000/05/10 21:40:50  rmurphy
+# removing makefile ref to unavailable subdirectories
+#
+# Revision 1.1.1.1  1999/03/16 18:06:54  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1997/08/27 15:55:44  wan
+# Added generic table decoding, debug routines, berdecode, and asnwish.
+#
+# Revision 1.1  1997/01/02 09:25:24  rj
+# first check-in
+#
+
+SUBDIRS		= # mkchdr pval ptbl berdecode
+
+#-------------------------------------------------------------------------------
+
+.PHONY:	implicit_default subdirs
+
+implicit_default::	subdirs
+
+subdirs::	$(SUBDIRS)
+$(SUBDIRS)::
+		cd $@ && $(MAKE) $(subtarget)
+
+# the following hack is needed for older make versions (gmake doesn't need it):
+init-depend::
+		@for dir in $(SUBDIRS); do\
+		  test -f $$dir/dependencies || touch $$dir/dependencies;\
+		done
+
+.DEFAULT::
+		$(MAKE) subdirs subtarget=$@
+
+distfiles::
+		echo makefile
+		for dir in $(SUBDIRS); do\
+		  subfiles=`cd $$dir && $(MAKE) -s $@`;\
+		  for file in $$subfiles; do\
+		    echo "$$dir/$$file";\
+		  done;\
+		done
diff --git a/SecuritySNACCRuntime/tcl-asn/README b/SecuritySNACCRuntime/tcl-asn/README
new file mode 100644
index 00000000..266378ba
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-asn/README
@@ -0,0 +1,75 @@
+asnwish - An ASN.1 Tcl/Tk interpreter based on snacc table files
+
+The only extension to standard Tcl/Tk is a command called 
+
+"asn",
+	which reads a binary ASN.1 grammar file (as generated 
+	by "snacc -T") into an internal data structure
+	and returns a new command "asn<n>".
+
+"asn<n>" offers the following possibilities:
+
+"asn<n> modules"
+	Returns a list of all modules of the grammar.
+
+"asn<n> types ?module?"
+	Returns a list of all type definitions of the
+	grammar respectively of the module given.
+	Each type definition is returned as a list
+	consisting of the module name and the type name.
+
+"asn<n> type ?-followref? {?module? typedef ?subtype? ...}
+	Returns a description of the given type. 
+	The description format is 
+	"<typeid> <type> <range> <namedvalues> ?<subtypelist>?".
+
+	In case of a type definition, "<typeid>" is a three-
+	element list "{<module> <typename> "pdu"|"sub"}".
+	In case of a subtype, <typeid> is the fieldname,
+	if any, or an empty list "{}".
+
+	"<type>" is one out of "BOOLEAN", "INTEGER", "BIT STRING",
+	"OCTET STRING", "NULL", "OBJECT IDENTIFIER", "REAL",
+	"ENUMERATED", "SEQUENCE", "SET", "SEQUENCE OF", "SET OF",
+	"CHOICE" or "TYPEREF".
+
+	"<range>" is either empty, or a single numeric value,
+	or a list of two numeric vaules. It can be available
+	for types "SEQUENCE OF" (giving the lower and, optionally,
+	the upper bounds of the index), "INTEGER" (giving the lowest
+	and the highest possible value) and "OCTET STRING" (giving
+	the minimum and, optionally, the maximum length).
+
+	"<namedvalues>" is either empty, or a list of two-element
+	lists, each consisting of an integer value and a name.
+	It can be available for types "BIT STRING" and "ENUMERATED".
+
+	"?<subtypelist>?" is available for types "TYPEREF" (where it
+	is a two-element list "{<module> <typename>}" and "SEQUENCE",
+	"SET", "SEQUENCE OF", "SET OF", "CHOICE" (where it is a list
+	of subtype descriptions, each of the format given here).
+
+"asn<n> decode channel {?module? typedef ?subtype? ...} valcmd ?typecmd?"
+	Reads from the channel the given type, BER encoded, and decodes it.
+	During decoding, whenever a compound type is entered or left,
+	the Tcl/Tk "typecmd" (if any) is executed, with the type path
+	as first parameter, and a "1" resp. "-1" as second, and
+	whenever a value is decoded, the Tcl/Tk "valcmd" is executed,
+	with the type path as the first and the value as the second
+	parameter. BOOLEAN values are represented as "TRUE" resp. 
+	"FALSE". INTEGER and ENUMERATED values are represented by
+	their decimal representation. BIT STRINGs are represented by
+	a string of "0" and "1" characters. OCTET STRINGs and OIDs
+	are represented as following: printable characters (except the
+	character "\") are copied unchanged; non-printable characters
+	and the character "\" are represented by \OOO (e.g., their ASCII
+	value encoded by three octal digits with leading 0). The NULL
+	type is encoded as "NULL". REAL numbers representation follows
+	sprintf %G.
+
+	Returns the number of bytes decoded.
+
+"asn<n> encode channel {?module? typedef ?subtype? ...} valcmd ?typecmd?"
+
+"asn<n> close"
+	Closes the grammar and deletes the internal data structure.
diff --git a/SecuritySNACCRuntime/tcl-asn/asnwish.c b/SecuritySNACCRuntime/tcl-asn/asnwish.c
new file mode 100644
index 00000000..aec6f29e
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-asn/asnwish.c
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+
+#include "tk.h"
+
+extern int Tbl_AppInit ();
+
+int main(argc, argv)
+    int argc;			/* Number of command-line arguments. */
+    char **argv;		/* Values of command-line arguments. */
+{
+    Tk_Main(argc, argv, Tbl_AppInit);
+    return 0;			/* Needed only to prevent compiler warning. */
+}
diff --git a/SecuritySNACCRuntime/tcl-asn/beredit b/SecuritySNACCRuntime/tcl-asn/beredit
new file mode 100644
index 00000000..807a5462
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-asn/beredit
@@ -0,0 +1,372 @@
+#!/bin/sh
+# the next line restarts using wish \
+exec asnwish "$0" "$@"
+
+proc err {msg} {
+    tk_dialog .err Error $msg {} 0 Damn
+}
+
+proc ref {desc} {
+    set res [lindex $desc 0]
+    if {$res==""} {
+    	set res [lindex $desc 1]
+    	if {$res=="TYPEREF"} {
+    	    set res [lindex [lindex $desc 4] 1]
+    	}
+    }
+    return $res
+}
+
+proc complete {ntp} {
+    global pdu
+    upvar $ntp tp
+    set tp [string trimright "$pdu $tp"]
+}
+
+proc newenc {tp r toggle} {
+    global asnenc
+    set idx $tp
+    if {$toggle} {
+    	set cur [lindex [array get asnenc $idx] 1]
+	set pr [lsearch -exact $cur $r]
+	if {$pr==-1} {
+    	    lappend cur $r
+	} else {
+    	    set cur [lreplace $cur $pr $pr]
+	}
+	set asnenc($idx) $cur
+    } else {
+    	set asnenc($idx) $r
+    }
+    fillcomposer
+}
+
+proc selpress {y} {
+    global tag
+    set i [.selector.l nearest $y]
+    if {$i==0} return
+    set tpval [.selector.l get $i]
+    if {$tag(selector)=="CHOICE"} {
+    	newenc [lindex $tpval 0] [lindex $tpval 1] 0
+    } else {
+    	newenc [lindex $tpval 0] [lindex $tpval 1] 1
+    }
+}
+
+proc comppress {y} {
+    global table tag
+    set i [.composer.l nearest $y]
+    set tpval [.composer.l get $i]
+    set tp [lindex $tpval 0]
+    set val [lindex $tpval 1]
+    set typetoask $tp
+    set td [$table type -followref $typetoask]
+    set t [lindex $td 1]
+    switch $t {
+    	CHOICE {
+    	    set tag(selector) $t
+   	    .selector.l delete 0 end
+    	    .selector.l insert end "$tp is a CHOICE of:"
+    	    foreach {subtypedesc req} [lindex $td 4] {
+    	    	set r [ref $subtypedesc]
+    	    	.selector.l insert end [list $tp $r] 
+    	    }
+    	    wm withdraw .insertor
+    	    wm deiconify .selector 
+    	    raise .selector
+    	}
+    	SEQUENCE {
+    	    set tag(selector) $t
+    	    .selector.l delete 0 end
+    	    .selector.l insert end "In SEQUENCE $tp, the following are OPTIONAL:"
+    	    foreach {subtypedesc req} [lindex $td 4] {
+    	    	if {!$req} {
+   	    	    set r [ref $subtypedesc]
+    	    	    .selector.l insert end [list $tp $r]
+    	    	}
+    	    }
+    	    wm withdraw .insertor
+   	    wm deiconify .selector 
+    	    raise .selector
+    	}
+    	default {
+    	    if {$t=="SEQUENCE OF"} {
+    	    	set text "Size of SEQUENCE OF $tp:"
+    	    } else {
+    	    	set text "New value of $tp:"
+    	    }
+    	    set tag(insertor) $tp
+    	    .insertor.l configure -text $text
+    	    .insertor.e delete 0 end
+    	    .insertor.e insert 0 $val
+    	    wm withdraw .selector
+    	    wm deiconify .insertor
+    	    raise .insertor
+    	}
+    }
+}
+
+proc inspress {} {
+    global tag
+    newenc $tag(insertor) [.insertor.e get] 0
+}
+
+proc fillcomposer {} {
+    global table pdu
+    set fraction 0.0
+    if [winfo exists .composer.l] {
+    	set fraction [lindex [.composer.l yview] 0]
+	.composer.l delete 0 end
+    } else {
+	frame .composer
+	pack .composer -fill both -expand 1
+	listbox .composer.l -yscrollcommand ".composer.v set"
+	scrollbar .composer.v -orient vertical -command ".composer.l yview"
+	pack .composer.v -fill y -side right
+	pack .composer.l -expand yes -fill both
+	bind .composer.l <ButtonPress-1> {comppress %y}
+	toplevel .selector
+	listbox .selector.l -yscrollcommand ".selector.v set"
+	scrollbar .selector.v -orient vertical -command ".selector.l yview"
+	pack .selector.v -fill y -side right
+	pack .selector.l -expand yes -fill both
+	bind .selector.l <ButtonPress-1> {selpress %y}
+	wm protocol .selector WM_DELETE_WINDOW {wm withdraw .selector}
+	wm title .selector "Snacc ASN.1 data item selection"
+	toplevel .insertor
+	label .insertor.l
+	entry .insertor.e
+	pack .insertor.l -fill x -expand yes -side top
+	pack .insertor.e -fill x -expand yes -side bottom
+	bind .insertor.e <KeyPress-Return> {inspress}
+	wm protocol .insertor WM_DELETE_WINDOW {wm withdraw .insertor}
+	wm title .insertor "Snacc ASN.1 data item modification"
+    }
+    wm withdraw .selector
+    wm withdraw .insertor
+    set null [open "/dev/null" w]
+    $table encode $null $pdu "encodevalcompose $null"
+    close $null
+    .composer.l yview moveto $fraction
+    wm deiconify .
+    raise .
+}
+
+proc decodetype {tp val} {
+    complete tp
+    if {$val==-1} {
+	set l [expr [llength $tp]-1]
+	set final [lindex $tp $l]
+	set addto [lrange $tp 0 [expr $l-1]]
+	global table asnenc
+    	set td [$table type -followref $addto]
+	if {[lindex $td 1]=="SEQUENCE"} {
+	    if [catch {set asnenc($addto)}] {
+    		set asnenc($addto) ""
+	    }
+	    foreach {elem req} [lindex $td 4] {
+    		if {[lindex $elem 0]==$final} {
+    		    if {!$req} {
+    			lappend asnenc($addto) $final
+   		    }
+   		    break
+    		}
+	    }
+	} else {
+    	    set asnenc($addto) $final
+	}
+    }
+}
+
+proc decodeval {chan tp val} {
+    decodetype $tp -1
+    global asnenc table
+    complete tp
+    set typ [$table type -followref $tp]
+    if {[lindex $typ 1]=="BIT STRING"} {
+	set namespecs [lindex $typ 3]
+	set bitno 0
+	foreach bit [split $val ""] {
+	    set idx [lsearch $namespecs "$bitno *"]
+	    if {$idx>=0 && $bit} {
+	    	lappend val "[lindex {! {}} $bit][lindex [lindex $namespecs $idx] 1]($bitno)"
+	    }
+	    incr bitno
+	}
+    } elseif {[lindex $typ 1]=="ENUMERATED"} {
+	set namespecs [lindex $typ 3]
+	set idx [lsearch $namespecs "$val *"]
+	if {$idx>=0} {
+	    lappend val "[lindex [lindex $namespecs $idx] 1]"
+	}
+    }
+    set asnenc($tp) $val
+}
+
+proc encodevalcompose {chan tp} {
+    global asnenc
+    complete tp
+    if [catch {set val $asnenc($tp)}] {
+	set val {}
+    }
+    .composer.l insert end [list $tp $val]
+    return $val
+}
+
+proc encodeval {chan tp val} {
+    global table
+    set prefix -
+    set val [subst -nobackslashes $val]
+    set typ [$table type -followref $tp]
+    if {[lindex $typ 1]=="OCTET STRING"} {
+	set fromto [lindex $typ 2]
+	set from [lindex $fromto 0]
+	set to [lindex $fromto 1]
+	if {$to==""} {
+	    set to $from
+	}
+	regsub -all {[^\\]} $val {} slashes
+	set len [expr [string length $val] - [string length $slashes] * 3]
+	if {$from!={} && $from>$len} {
+	    set val [format "%$prefix[expr $from]s" $val] 
+	} elseif {$to!={} && $to<$len} {
+	    err [list encodeval: value $val for $tp >$to]
+	    while {$to<$len} {
+	    	set last [string last \\ $val]
+	    	if {$last==-1 || $last<[string length $val]-4} {
+	    	    set val [string range $val 0 [expr [string length $val] - 2]]
+	    	} else {
+	    	    set val [string range $val 0 [expr $last - 1]]
+	    	}
+		regsub -all {[^\\]} $val {} slashes
+		set len [expr [string length $val] - [string length $slashes] * 3]
+	    }
+	}
+    } elseif {[lindex $typ 1]=="BIT STRING"} {
+	set namespecs [lindex $typ 3]
+	if {[regexp {^[01]+$} [lindex $val 0]]} {
+	    set val [split [lindex $val 0] ""]
+	} else {
+	    set names $val
+	    set val {}
+	    foreach name $names {
+	    	if {[regsub {([a-zA-Z_][a-zA-Z0-9_]*)?\(([0-9]+)\)} $name {\2} bitno]!=1} {
+	    	    set idx [lsearch -regexp $namespecs "^\[0-9\]+ $name$"]
+	    	    if {$idx<0} {
+	    	    	err "Bit $name of $tp not in $namespecs"
+	    	    	continue 
+	    	    }
+	    	    set bitno [lindex [lindex $namespecs $idx] 0]
+	    	}
+	    	while {[llength $val]<=$bitno} {
+	    	    lappend val 0
+	    	}
+	    	set val [lreplace $val $bitno $bitno 1]
+	    }
+	}
+	proc namespeccmp {a b} {return [expr [lindex $a 0] - [lindex $b 0]]}
+	set sorted [lsort -command namespeccmp -decreasing $namespecs]
+	set bitno [lindex [lindex $sorted 0] 0]
+	while {[llength $val]<=$bitno} {
+	    lappend val 0
+	}
+	set val [join $val ""]
+    } elseif {[lindex $typ 1]=="ENUMERATED"} {
+	set namespecs [lindex $typ 3]
+	if {![regexp {^[0-9]*$} [lindex $val 0]]} {
+	    set idx [lsearch -regexp $namespecs "^\[0-9\]+ $val$"]
+	    if {$idx<0} {
+	    	err "Named value $val of $tp not in $namespecs"
+	    } else {
+	    	set val [lindex [lindex $namespecs $idx] 0]
+	    }
+	}
+    }
+    return $val
+}
+
+proc encodeasnenc {chan tp} {
+    global asnenc pdu
+    complete tp
+    if [catch {set val $asnenc($tp)}] {
+	set val {}
+    }
+    return [encodeval $chan $tp $val]
+}
+
+wm title . "Snacc ASN.1 message editor"
+wm geometry . 400x300
+frame .mbar -relief raised
+pack .mbar -side top -fill x
+
+menubutton .mbar.file -text Message -menu .mbar.file.menu
+pack .mbar.file -side left
+
+menu .mbar.file.menu
+.mbar.file.menu add command -label "Open ..." -command {openfile}
+.mbar.file.menu add command -label "Save As ..." -command {savefile}
+.mbar.file.menu add command -label "Quit" -command {quit}
+wm protocol . WM_DELETE_WINDOW {quit}
+
+proc readfile {fn} {
+    if {$fn==""} return
+    global table pdu asnenc
+    catch {unset asnenc}
+    set chan [open $fn r]
+    fconfigure $chan -translation binary
+    set bytes [$table decode $chan $pdu "decodeval $chan" decodetype]
+    close $chan
+    fillcomposer
+}
+
+proc openfile {} {
+    readfile [tk_getOpenFile -defaultextension .ber -filetypes {{{ASN.1 data} {.ber .bin .out .tt}} {{All files} {.*}}}]
+}
+
+proc savefile {} {
+    set fn [tk_getSaveFile -defaultextension .ber -filetypes {{{ASN.1 data} {.ber .bin .out .tt}} {{All files} {.*}}}]
+    if {$fn==""} return
+    global table pdu
+    set chan [open $fn w]
+    $table encode $chan $pdu "encodeasnenc $chan"
+    close $chan
+}
+
+proc quit {} {
+    global done
+    set done 1
+}
+
+set asnfile [lindex $argv 0]
+if {$asnfile==""} {
+    puts stderr "Usage: $argv0 <table-file> ?<ber-file>?"
+    puts stderr ""
+    puts stderr "This program is a simple editor for ASN.1 messages"
+    puts stderr "encoded using the Basic Encoding Rules (BER). It requires"
+    puts stderr "the grammar specification, in binary format as generated"
+    puts stderr "by \"snacc -T\", as the initial argument on the command line."
+    puts stderr ""
+    puts stderr "The purpose of this program is to demonstrate the usage of"
+    puts stderr "the new Tcl/Tk command \"asn\". Have a look at the Tcl/Tk"
+    puts stderr "script \"$argv0\"!"
+    exit 0
+}
+
+set table [asn $asnfile]
+
+foreach type [$table types] {
+    if {[lindex [$table type $type] 0]=="$type pdu"} {
+	set pdu $type
+	break
+    }
+}
+
+readfile [lindex $argv 1]
+fillcomposer
+
+update idletasks
+vwait done
+
+$table close
+exit
+
diff --git a/SecuritySNACCRuntime/tcl-asn/makefile b/SecuritySNACCRuntime/tcl-asn/makefile
new file mode 100644
index 00000000..3c6d796c
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-asn/makefile
@@ -0,0 +1,90 @@
+#
+# Makefile for the asnwish
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-asn/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:54  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.3  1997/10/10 13:43:18  wan
+# Corrected bug in generic table decoder wrt. indefinite length elements
+# Corrected compiler access to freed memory (bug reported by Markku Savela)
+# Broke asnwish.c into two pieces so that one can build ones on wish
+# Added beredit tool (based on asnwish, allowes to edit BER messages)
+#
+# Revision 1.2  1997/09/03 12:13:13  wan
+# Reworked asnwish to neither strip nor encapsulate; instead,
+# buffer reads during decoding incrementally Tcl_Read the channel.
+#
+# Revision 1.1  1997/08/27 15:55:51  wan
+# Added generic table decoding, debug routines, berdecode, and asnwish.
+#
+#
+
+include ../makehead
+
+TOP		= ..
+
+SNACC		= $(TOP)/compiler/snacc
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+C_LIB		= $(TOP)/c-lib
+ASN1INC		= $(C_LIB)/inc
+ASN1LIB		= $(C_LIB)/libasn1ctbl.a
+
+CPPFLAGS	+= -I$(TOP) -I$(ASN1INC) $(CPPFLAGS.TCL) $(CPPFLAGS.X11)
+
+OFILES	= 	tclasn.o asnwish.o
+
+DISTFILES = 	makefile tclasn.c asnwish.c README beredit
+
+LDFLAGS		+= $(LDFLAGS.X11)
+LDLIBS		+= $(ASN1LIB) $(TCLLIBS) $(LDLIBS.X11pre) -lX11 $(LDLIBS.X11extra) $(LIBS)
+
+WISH		= asnwish
+
+#-------------------------------------------------------------------------------
+
+all::		$(WISH)
+
+$(WISH):	$(OFILES) $(ASN1LIB)
+		$(REASON)
+		$(CC) $(LDFLAGS) -o $(WISH) $(OFILES) $(LDLIBS)
+
+$(ASN1LIB)::
+		cd $(@D) && $(MAKE) tbl-lib
+
+# if $(ASN1INC)/asn_useful.h doesn't exist, someone probably called `make clean` in $(C++_LIB).
+$(ASN1INC)/asn-useful.h:
+		$(MAKE) $(ASN1LIB)
+
+$(SNACC)::
+		cd $(@D) && $(MAKE) $(@F)
+
+clean::
+		$(RM) $(ASN1HFILES) $(ASN1CFILES)
+		$(RM) $(OFILES)
+
+clobber::
+		$(RM) $(WISH)
+
+install-sh:
+		ln $(TOP)/install-sh $@
+
+$(bindir):
+		$(TOP)/mkinstalldirs $@
+
+install::       $(WISH) install-sh $(bindir)
+
+init-depend::
+		test -f dependencies || touch dependencies
+
+install::
+		$(INSTALL_PROGRAM) $(WISH) $(bindir)/
+		$(INSTALL_PROGRAM) beredit $(bindir)/
+		$(INSTALL_PROGRAM) tclasn.o $(libdir)/
+
+include ../maketail
diff --git a/SecuritySNACCRuntime/tcl-asn/tclasn.c b/SecuritySNACCRuntime/tcl-asn/tclasn.c
new file mode 100644
index 00000000..86ffa762
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-asn/tclasn.c
@@ -0,0 +1,1185 @@
+/*
+ * 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.
+ */
+
+
+/* 
+ * Wishes:
+ * Allow spec of PDU to decode in asn<n> decode
+ * (Prefixing tp during decoding with PDU is not necessary)
+ * 
+ * 
+ */
+
+#include "tk.h"
+#include "tbl-gen.h"
+#include "tbl-dbg.h"
+#include "sbuf.h"
+#include "exp-buf.h"
+#include <netinet/in.h>
+
+typedef struct ChannelBuf {
+    Tcl_Channel chan;
+    int readError;
+} ChannelBuf;
+
+static void PutChannelBufInGenBuf _ANSI_ARGS_((Tcl_Channel chan, GenBuf* gb));
+
+static unsigned char
+ChanGetByte (cb)
+    ChannelBuf* cb;
+{
+    unsigned char result = 0;
+    if (!cb->readError)
+    	if (Tcl_Read(cb->chan,&result,1)!=1)
+    	    cb->readError = TRUE;
+    return result;
+}
+
+static char*
+ChanGetSeg (cb, len)
+    ChannelBuf* cb;
+    unsigned long* len;
+{
+    static char result[100];
+    if (cb->readError) {
+    	*len = 0;
+    	return NULL;
+    }
+    if (*len>sizeof(result))
+    	*len = sizeof(result);
+    *len = Tcl_Read(cb->chan,result,*len);
+    if (*len<0) {
+    	cb->readError = TRUE;
+    	*len = 0;
+    	return NULL;
+    }
+    return result;
+}
+
+static unsigned long
+ChanCopy (dst, cb, len)
+    char* dst;
+    ChannelBuf* cb;
+    unsigned long len;
+{
+    unsigned long result;
+    if (cb->readError) {
+    	return 0;
+    }
+    result = Tcl_Read(cb->chan,dst,len);
+    if (result!=len) {
+    	cb->readError = TRUE;
+    	if (result<0)
+    	    result = 0;
+    }
+    return result;
+}
+
+static unsigned long
+ChanPeekCopy (dst, cb, len)
+    char* dst;
+    ChannelBuf* cb;
+    unsigned long len;
+{
+    unsigned long result, result2;
+    if (cb->readError) {
+    	return 0;
+    }
+    result = ChanCopy(dst,cb,len);
+    result2 = Tcl_Ungets(cb->chan,dst,result,0);
+    if (result2!=result) {
+    	cb->readError = TRUE;
+    }
+    return result;
+}
+
+static unsigned char
+ChanPeekByte (cb)
+    ChannelBuf* cb;
+{
+    unsigned char result = 0;
+    ChanPeekCopy(&result,cb,1);
+    return result;
+}
+
+static int
+ChanReadError (cb)
+    ChannelBuf* cb;
+{
+    return cb->readError;
+}
+
+static void 
+PutChannelBufInGenBuf (cb, gb)
+    ChannelBuf* cb;
+    GenBuf* gb;
+{
+    gb->bufInfo = cb;
+    cb->readError = FALSE;
+    gb->getByte = (BufGetByteFcn) ChanGetByte;
+    gb->getSeg = (BufGetSegFcn) ChanGetSeg;
+    gb->copy = (BufCopyFcn) ChanCopy;
+    gb->peekByte = (BufPeekByteFcn) ChanPeekByte;
+    gb->peekCopy = (BufPeekCopyFcn) ChanPeekCopy;
+    gb->readError = (BufReadErrorFcn) ChanReadError;
+}
+
+#if TCL_MAJORVERSION<8
+#define Tcl_GetStringResult(interp) (interp->result)
+#endif
+
+#define max(a,b) ((a)>(b)?(a):(b))
+#define min(a,b) ((a)<(b)?(a):(b))
+
+extern int matherr();
+int *tclDummyMathPtr = (int *) matherr;
+
+Tcl_Interp* interpG;
+int interpResultG;
+char* tblvalcmdG;
+char* tbltypecmdG;
+
+void myAsn1ErrorHandler (str, severity)
+    char* str;
+    int severity;
+{
+    Tcl_AppendResult(interpG,"ASN.1 error: ",str,NULL);
+    interpResultG = TCL_ERROR;
+}
+
+int equal (char* s1, char* s2)
+{
+    return s1==s2 || (s1 && s2 && !strcmp(s1,s2));
+}
+
+int contained (char* in, char* el)
+{
+    int argc;
+    char** argv;
+    if (Tcl_SplitList(interpG,in,&argc,&argv)!=TCL_OK)
+    	return FALSE;
+    while (argc--)
+    	if (equal(*argv++,el))
+    	    return TRUE;
+    return FALSE;
+}
+
+static struct TypePath
+    {
+    char* typename;
+    char* fieldname;
+    int index;
+    } tp[20];
+static int ntp;
+
+int TblDbgCallProc (cmdstart, value)
+    char* cmdstart;
+    char* value;
+{
+    int i;
+    Tcl_DString cmd, type;
+    if (ntp<=1 || !cmdstart)
+    	return TCL_OK;
+    Tcl_DStringInit(&cmd);
+    Tcl_DStringAppend(&cmd,cmdstart,-1);
+    Tcl_DStringInit(&type);
+    for (i=1; i<ntp; i++)
+    {
+    	Tcl_DStringAppendElement(&type,tp[i].fieldname?tp[i].fieldname:tp[i].typename);
+    	if (tp[i].index)
+    	{
+    	    char fmt[20];
+    	    sprintf(fmt,"%d",tp[i].index);
+    	    Tcl_DStringAppendElement(&type,fmt);
+    	    i++; /* BAD HACK */
+    	}
+    }
+    Tcl_DStringAppendElement(&cmd,Tcl_DStringValue(&type));
+    Tcl_DStringFree(&type);
+    Tcl_DStringAppendElement(&cmd,value);
+    interpResultG = Tcl_Eval(interpG,Tcl_DStringValue(&cmd));
+    Tcl_DStringFree(&cmd);
+    return interpResultG;
+    
+}
+
+static char* TIN [] = { "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
+    "NULL", "OBJECT IDENTIFIER", "REAL", "ENUMERATED", "SEQUENCE", "SET", 
+    "SEQUENCE OF", "SET OF", "CHOICE", "TYPEREF" };
+
+#define SPECIALID_STR -1
+
+int
+TblEncAsk (tid, v, precmd)
+    int tid;
+    AVal* v;
+    char* precmd;
+{
+    int i;
+    int result;
+    Tcl_DString cmd, type;
+    char fmt[20];
+    char* iresult;
+    Tcl_DStringInit(&cmd);
+    Tcl_DStringAppend(&cmd,precmd,-1);
+    Tcl_DStringInit(&type);
+    for (i=1; i<ntp; i++)
+    {
+    	Tcl_DStringAppendElement(&type,tp[i].fieldname?tp[i].fieldname:tp[i].typename);
+    	if (tp[i].index)
+    	{
+    	    sprintf(fmt,"%d",tp[i].index);
+    	    Tcl_DStringAppendElement(&type,fmt);
+    	    i++; /* BAD HACK */
+    	}
+    }
+    Tcl_DStringAppendElement(&cmd,Tcl_DStringValue(&type));
+    Tcl_DStringFree(&type);
+    result = Tcl_Eval(interpG,Tcl_DStringValue(&cmd));
+    Tcl_DStringFree(&cmd);
+    if (result!=TCL_OK)
+    	return result;
+    iresult = Tcl_GetStringResult(interpG);
+    switch (tid)
+    {
+    	case TBL_BOOLEAN:
+    	    *(AsnBool*)v = !(!strcmp(iresult,"0") || toupper(*iresult)=='F' || !*iresult);
+    	    break;
+    	case TBL_INTEGER:
+    	case TBL_ENUMERATED:
+    	    *(AsnInt*)v = atoi(iresult);
+    	    break;
+    	case TBL_REAL:
+    	    sscanf(iresult,"%lf",(AsnReal*)v);
+    	    break;
+    	case TBL_BITSTRING:
+    	    ((AsnBits*)v)->bitLen = strlen(iresult);
+    	    ((AsnBits*)v)->bits = Asn1Alloc(((AsnBits*)v)->bitLen?(((AsnBits*)v)->bitLen-1)/8+1:0);
+    	    for (i=0; iresult[i]; i++)
+    	    	if (iresult[i]!='0')
+    	    	    SetAsnBit((AsnBits*)v,i);
+    	    break;
+    	case TBL_OCTETSTRING:
+    	case TBL_OID:
+    	    ((AsnOcts*)v)->octs = Asn1Alloc(strlen(iresult)); /* Might be too much, but don't care */
+    	    for (i=((AsnOcts*)v)->octetLen=0; iresult[i]; i++,((AsnOcts*)v)->octetLen++)
+    	    	if (iresult[i]=='\\')
+    	    	    {
+    	    	    char* skipto;
+    	    	    strncpy(fmt,iresult+i+1,3);
+    	    	    fmt[3] = '\0';
+    	    	    ((AsnOcts*)v)->octs[((AsnOcts*)v)->octetLen] = strtol(fmt,&skipto,8);
+    	    	    i += skipto-fmt;
+    	    	    } 
+    	    	 else 
+    	    	    ((AsnOcts*)v)->octs[((AsnOcts*)v)->octetLen] = iresult[i];
+    	    break;
+    	case SPECIALID_STR:
+    	    *(char**)v = Asn1Alloc(strlen(iresult)+1);
+    	    strcpy(*(char**)v,iresult);
+    	    break;
+    	default:
+    	    break;
+    }
+    Tcl_ResetResult(interpG);
+    return TCL_OK;
+}
+
+int
+TblEncType PARAMS ((type, b, implicit, bytesEncoded),
+    TBLType *type _AND_
+    BUF_TYPE b _AND_
+    int implicit _AND_
+    unsigned long int *bytesEncoded)
+{
+    int result = TCL_OK;
+    unsigned long int tmpBytesEncoded = 0;
+    unsigned int currElmt;
+    TBLType *elmt;
+    TBLType* choice;
+    int implicitRef;
+    void *tmp;
+    AsnBits optavail;
+    char* elmtname;
+    union {
+    	AsnBool bo;
+    	AsnInt in;
+    	AsnBits bi;
+    	AsnOcts oc;
+    	AsnReal re;
+    	} unival;
+
+    if (type->typeId==TBL_TYPEREF && !tp[ntp-1].typename)
+	tp[ntp-1].typename = type->content->a.typeRef->typeDefPtr->typeName.octs;
+    if (type->typeId!=TBL_TYPEREF && !tp[ntp-1].typename)
+    	tp[ntp-1].typename = TIN[type->typeId];
+    if (!tp[ntp-1].fieldname)
+	tp[ntp-1].fieldname = type->fieldName.octs;
+
+    switch (type->typeId)
+    {
+      case TBL_TYPEREF:
+
+          /*
+           * carry over implicit ref if goes
+           * through typeref with no tags
+           */
+          implicitRef = type->content->a.typeRef->implicit ||
+              (implicit &&
+               ((type->tagList == NULL) || LIST_EMPTY (type->tagList)));
+
+          result = TblEncType (type->content->a.typeRef->typeDefPtr->type, b, implicitRef,
+            	&tmpBytesEncoded);
+      	  if (result!=TCL_OK)
+      	      return result;
+          break;
+
+      case TBL_SEQUENCE:
+      case TBL_SET:
+          /* rvs though list value and list type def */
+          currElmt = LIST_COUNT (type->content->a.elmts);
+          tmp = CURR_LIST_NODE (type->content->a.elmts);
+          result = TblEncAsk(SPECIALID_STR,&elmtname,tbltypecmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+           FOR_EACH_LIST_ELMT_RVS (elmt, type->content->a.elmts)
+          {
+              if (!elmt->optional 
+              	    || contained(elmtname,elmt->fieldName.octs)
+              	    || !elmt->fieldName.octetLen && 
+              	    (elmt->typeId==TBL_TYPEREF && contained(elmtname,
+              	    elmt->content->a.typeRef->typeDefPtr->typeName.octs)
+              	    || elmt->typeId!=TBL_TYPEREF && contained(elmtname,
+              	    TIN[elmt->typeId])))
+              {
+    		 tp[ntp].typename = tp[ntp].fieldname = NULL;
+    		 tp[ntp].index = 0;
+    		 ntp++;
+                   result = TblEncType (elmt, b, FALSE, &tmpBytesEncoded);
+                  if (result!=TCL_OK)
+    	              {
+    	              Asn1Free(optavail.bits);
+                      return result;
+                      }
+        	 ntp--;
+              }
+          }
+          Asn1Free(elmtname);
+          /* restore list curr in case recursive type */
+          SET_CURR_LIST_NODE (type->content->a.elmts, tmp);
+          break;
+
+      case TBL_SEQUENCEOF:
+      case TBL_SETOF:
+      	  result = TblEncAsk(TBL_INTEGER,&tp[ntp-1].index,tbltypecmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+           elmt = FIRST_LIST_ELMT (type->content->a.elmts);
+          for (;tp[ntp-1].index>=1;tp[ntp-1].index--)
+          {
+    	     tp[ntp].typename = tp[ntp].fieldname = NULL;
+    	     tp[ntp].index = 0;
+    	     ntp++;
+             result = TblEncType (elmt, b, FALSE, &tmpBytesEncoded);
+             if (result!=TCL_OK)
+                 return result;
+             ntp--;
+          }
+        break;
+
+      case TBL_CHOICE:
+      	  result = TblEncAsk(SPECIALID_STR,&elmtname,tbltypecmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+          tmp = CURR_LIST_NODE (type->content->a.elmts);
+      	  choice = NULL;
+          FOR_EACH_LIST_ELMT(elmt, type->content->a.elmts)
+            if (equal(elmtname,elmt->fieldName.octs))
+            	{
+            	choice = elmt;
+            	break;
+            	}
+          if (!choice)
+            FOR_EACH_LIST_ELMT(elmt, type->content->a.elmts)
+              if (!elmt->fieldName.octetLen)
+              	{
+              	if (elmt->typeId==TBL_TYPEREF)
+              	    {
+              	    if (equal(elmtname,elmt->content->a.typeRef->typeDefPtr->typeName.octs))
+            		{
+            		choice = elmt;
+            		break;
+            		}
+            	    }
+    	    	else if (equal(elmtname,TIN[elmt->typeId]))
+            		{
+            		choice = elmt;
+            		break;
+            		}
+            	}
+            Asn1Free(elmtname);
+            SET_CURR_LIST_NODE (type->content->a.elmts, tmp);
+            if (choice)
+              {
+    		 tp[ntp].typename = tp[ntp].fieldname = NULL;
+    		 tp[ntp].index = 0;
+    		 ntp++;
+            	result = TblEncType(choice,b,FALSE,&tmpBytesEncoded);
+      		  if (result!=TCL_OK)
+      		      return result;
+         	 ntp--;
+              }
+        break;
+
+      case TBL_BOOLEAN:
+      	  result = TblEncAsk(type->typeId,&unival,tblvalcmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+          tmpBytesEncoded += BEncAsnBoolContent (b, &unival.bo);
+          if (interpResultG!=TCL_OK)
+            return interpResultG;
+        break;
+
+      case TBL_INTEGER:
+      case TBL_ENUMERATED:
+      	  result = TblEncAsk(type->typeId,&unival,tblvalcmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+          tmpBytesEncoded += BEncAsnIntContent (b, &unival.in);
+          if (interpResultG!=TCL_OK)
+            return interpResultG;
+        break;
+
+      case TBL_BITSTRING:
+      	  result = TblEncAsk(type->typeId,&unival,tblvalcmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+          tmpBytesEncoded += BEncAsnBitsContent (b, &unival.bi);
+          Asn1Free(unival.bi.bits);
+          if (interpResultG!=TCL_OK)
+            return interpResultG;
+        break;
+
+      case TBL_OCTETSTRING:
+      	  result = TblEncAsk(type->typeId,&unival,tblvalcmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+          tmpBytesEncoded += BEncAsnOctsContent (b, &unival.oc);
+          Asn1Free(unival.oc.octs);
+          if (interpResultG!=TCL_OK)
+            return interpResultG;
+        break;
+
+      case TBL_NULL:
+          tmpBytesEncoded += BEncAsnNullContent (b, NULL);
+          if (interpResultG!=TCL_OK)
+            return interpResultG;
+        break;
+
+      case TBL_OID:
+      	  result = TblEncAsk(type->typeId,&unival,tblvalcmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+          tmpBytesEncoded += BEncAsnOidContent (b, &unival.oc);
+          Asn1Free(unival.oc.octs);
+          if (interpResultG!=TCL_OK)
+            return interpResultG;
+        break;
+
+      case TBL_REAL:
+      	  result = TblEncAsk(type->typeId,&unival,tblvalcmdG);
+      	  if (result!=TCL_OK)
+      	      return result;
+          tmpBytesEncoded += BEncAsnRealContent (b, &unival.re);
+          if (interpResultG!=TCL_OK)
+            return interpResultG;
+        break;
+
+      default:
+         Tcl_AppendResult(interpG,"strange type",NULL);
+         return TCL_ERROR;
+         
+    }
+
+    TblEncodeTagsAndLens (type, b, implicit, &tmpBytesEncoded);
+    (*bytesEncoded) += tmpBytesEncoded;
+
+    return TCL_OK;
+
+}
+
+int
+TblEnc PARAMS (( type, b),
+    TBLType *type _AND_
+    BUF_TYPE b)
+{
+    unsigned long int bytesEncoded = 0;
+    int result;
+    ntp = 1;
+    result = TblEncType (type, b, FALSE, &bytesEncoded);
+    if (result==TCL_OK && BufWriteError (b))
+    	{
+    	Tcl_AppendResult(interpG,"error writing buffer",NULL);
+    	result = TCL_ERROR;
+    	}
+    interpResultG = result;
+    if (result==TCL_OK)
+    	return bytesEncoded;
+    else
+    	return -1;
+}
+
+
+void
+TblDbgValue (type, val, pvalue)
+    TBLType* type;
+    AVal* val;
+    Tcl_DString* pvalue;
+{
+    char fmt[20];
+    switch (type->typeId)
+    {
+	case TBL_BOOLEAN:
+	    Tcl_DStringAppend(pvalue,*(AsnBool*)val? "TRUE" :"FALSE", -1);
+	    break;
+	case TBL_INTEGER:
+	case TBL_ENUMERATED:
+	    sprintf(fmt,"%d",*(AsnInt*)val);
+	    Tcl_DStringAppend(pvalue,fmt, -1);
+	    break;
+	case TBL_BITSTRING:
+	    {
+	    AsnBits* v = (AsnBits*)val;
+	    unsigned long i;
+	    for (i=0; i<v->bitLen; i++)
+    		Tcl_DStringAppend(pvalue,GetAsnBit(v,i)?"1":"0", -1);
+	    }
+	    break;
+	case TBL_OCTETSTRING:
+	case TBL_OID:
+	    {
+	    AsnOcts* v = (AsnOcts*)val;
+	    unsigned long i;
+	    for (i=0; i<v->octetLen; i++)
+		if (v->octs[i]=='\\' || !isprint(v->octs[i]))
+		    {
+		    sprintf(fmt,"\\%03o",v->octs[i]);
+		    Tcl_DStringAppend(pvalue,fmt,-1);
+		    }
+		else
+		    Tcl_DStringAppend(pvalue,v->octs+i,1);
+	    }
+	    break;
+	case TBL_NULL:
+    	    Tcl_DStringAppend(pvalue,"NULL", -1);
+	    break;
+	case TBL_REAL:
+	    sprintf(fmt,"%G",*(AsnReal*)val);
+    	    Tcl_DStringAppend(pvalue,fmt, -1);
+	    break;
+	default:
+	    break;
+    }
+}
+
+
+int
+TblDbgType PARAMS ((type, val, begin),
+    TBLType* type _AND_
+    AVal* val _AND_
+    int begin)
+{
+    int result = TCL_OK;
+    if (begin)
+    {
+	if (type->typeId==TBL_TYPEREF && !tp[ntp-1].typename)
+	    tp[ntp-1].typename = type->content->a.typeRef->typeDefPtr->typeName.octs;
+    	if (type->typeId!=TBL_TYPEREF && !tp[ntp-1].typename)
+    	    tp[ntp-1].typename = TIN[type->typeId];
+	if (!tp[ntp-1].fieldname)
+	    tp[ntp-1].fieldname = type->fieldName.octs;
+	if (type->typeId >= TBL_SEQUENCE && type->typeId <= TBL_CHOICE)
+    	{
+    	    result = TblDbgCallProc(tbltypecmdG,"1");
+	    if (type->typeId == TBL_SEQUENCEOF || type->typeId == TBL_SETOF)
+		tp[ntp-1].index = 1;
+    	    tp[ntp].typename = tp[ntp].fieldname = NULL;
+    	    tp[ntp].index = 0;
+    	    ntp++;
+    	}
+    }
+    else if (type->typeId!=TBL_TYPEREF)
+    {
+	if (type->typeId < TBL_SEQUENCE)
+	{
+	    Tcl_DString value;
+	    Tcl_DStringInit(&value);
+	    TblDbgValue(type,val,&value);
+	    result = TblDbgCallProc(tblvalcmdG,Tcl_DStringValue(&value));
+    	    Tcl_DStringFree(&value);
+    	} else {
+	    ntp--;
+	    if (type->typeId == TBL_SEQUENCEOF || type->typeId == TBL_SETOF)
+		tp[ntp-1].index = 0;
+    	    result = TblDbgCallProc(tbltypecmdG,"-1");
+    	}
+    	tp[ntp-1].typename = tp[ntp-1].fieldname = NULL;
+    	if (ntp>=2)
+    	    if (tp[ntp-2].index)
+    	    	tp[ntp-2].index++;
+    }
+    return result;
+}
+
+TBLType* TblFindType (type, argv, followref, ptr, ptnnl)
+    TBLType* type;
+    char** argv;
+    int followref;
+    TBLRange** ptr;
+    TBLNamedNumberList** ptnnl;
+{
+    TBLType* elmt;
+    TBLType* result;
+    void *tmp;
+    if (!*argv)
+    	{
+	if (ptr && !*ptr && type->constraint)
+    	    *ptr = type->constraint;
+	if (ptnnl && !*ptnnl && type->values)
+    	    *ptnnl = type->values;
+    	if (!followref || type->typeId!=TBL_TYPEREF)
+    	    return type;
+    	}
+    switch (type->typeId)
+    	{
+    	case TBL_TYPEREF:
+    	    return TblFindType(type->content->a.typeRef->typeDefPtr->type,argv,followref,ptr,ptnnl);
+    	case TBL_CHOICE:
+    	case TBL_SET:
+    	case TBL_SEQUENCE:
+            tmp = CURR_LIST_NODE (type->content->a.elmts);
+	    result = NULL;
+    	    FOR_EACH_LIST_ELMT(elmt,type->content->a.elmts)
+    	    	if (equal(*argv,elmt->fieldName.octs)) 
+		    {
+    	    	    result = TblFindType(elmt,argv+1,followref,ptr,ptnnl);
+		    break;
+		    }
+	    if (!result) {
+    	    FOR_EACH_LIST_ELMT(elmt,type->content->a.elmts)
+    	    	if (!elmt->fieldName.octetLen)
+    	    	    {
+    	    	    if (elmt->typeId==TBL_TYPEREF)
+    	    	    	{
+    	    	    	if (equal(*argv,elmt->content->a.typeRef->typeDefPtr->typeName.octs)) {
+    	    	    	    result = TblFindType(elmt->content->a.typeRef->typeDefPtr->type,argv+1,followref,ptr,ptnnl);
+			    break;
+			    }
+    	    	    	}
+    	    	    else if (equal(*argv,TIN[elmt->typeId])) {
+    	    	    	result = TblFindType(elmt,argv+1,followref,ptr,ptnnl);
+			break;
+			}
+    	    	    }
+	    }
+	    SET_CURR_LIST_NODE (type->content->a.elmts, tmp);
+    	    return result;
+    	case TBL_SETOF:
+    	case TBL_SEQUENCEOF:
+    	    if (**argv>='0'&&**argv<='9')
+    	    	argv++;
+    	    return TblFindType(FIRST_LIST_ELMT(type->content->a.elmts),argv,followref,ptr,ptnnl);
+    	default:
+    	    return NULL;
+    	}
+}
+
+
+TBLType* TblTypeOfPath (interp, tbl, path, followref, ptd, ptr, ptnnl)
+    TBL* tbl;
+    char* path;
+    int followref;
+    TBLTypeDef** ptd;
+    TBLRange** ptr;
+    TBLNamedNumberList** ptnnl;
+{
+    TBLModule* tm = NULL;
+    TBLTypeDef* td;
+    TBLType* type = NULL;
+    int argc;
+    char** argv;
+    if (Tcl_SplitList(interp,path,&argc,&argv)!=TCL_OK)
+    	return NULL;
+    if (argc>=2 && (tm = TblFindModule(tbl,argv[0])))
+    	{
+    	argv++;
+    	argc--;
+    	}
+    if (argc<1 || !(td=TblFindTypeDef(tbl,tm?tm->name.octs:NULL,argv[0],&tm))
+    	    || !(type=TblFindType(td->type,argv+1,followref,ptr,ptnnl)))
+    	Tcl_AppendResult(interp,"wrong typepath \"",path,
+    	    	"\", should be ?module? typedef ?subtype? ...", NULL);
+    else if (ptd)
+    	*ptd = td;
+    Tcl_Free((char*)argv);
+    return type;
+}      
+
+int dowrite (Tcl_Channel chan, char* buffer, int n)
+    {
+    int written = 0;
+    int onewrite;
+    while (written<n)
+        {
+        onewrite = Tcl_Write(chan,buffer+written,n-written);
+        if (onewrite<0)
+            return onewrite;
+        written += onewrite;
+        }
+    return written;
+    }
+
+
+int TblCmdEncode (interp, tbl, chan, path, valcmd, typecmd)
+    Tcl_Interp* interp;
+    TBL* tbl;
+    Tcl_Channel chan;
+    char* path;
+    char* valcmd;
+    char* typecmd;
+{
+    int write;
+    ExpBuf *ep;
+    ExpBuf* b;
+    GenBuf gb;
+
+    TBLType* type = TblTypeOfPath (interp, tbl, path, FALSE, NULL, NULL, NULL);
+    if (!type)
+    	{
+    	Tcl_AppendResult(interp,"wrong typepath \"",path,"\"",NULL);
+    	return TCL_ERROR;
+    	}
+
+    interpG = interp;
+    interpResultG = TCL_OK;
+    tblvalcmdG = valcmd;
+    tbltypecmdG = typecmd?typecmd:valcmd;
+
+    ep = ExpBufAllocBufAndData();
+    ExpBufResetInWriteRvsMode (ep); /* set up to hold encoding (= writing) */
+    PutExpBufInGenBuf (ep, &gb);
+    write = TblEnc(type,&gb);
+    ep = ExpBufListFirstBuf(ep);
+    
+    for (b=ep;interpResultG==TCL_OK && b;b=ExpBufNext(b))
+    {
+        if (dowrite(chan,ExpBufDataPtr(b),ExpBufDataSize(b))!=ExpBufDataSize(b))
+            {
+            Asn1Error("Error during writing");
+            break;
+            }
+    }
+    ExpBufFreeBufAndDataList (ep);
+    return interpResultG;
+}
+
+int doread (Tcl_Channel chan, char* buffer, int n, int checkeof)
+    {
+    int oneread = 0;
+    int haveread = 0;
+    while (haveread<n)
+        {
+        oneread = Tcl_Read(chan,buffer+haveread,n-haveread);
+        if (oneread<0)
+            {
+            haveread = oneread;
+            break;
+            }
+        if (checkeof && oneread==0 && haveread==0)
+            /* Nothing there although select sais readable -> EOF */
+            break;
+        haveread += oneread;
+        }
+    return haveread;
+    }
+
+
+int TblCmdDecode (interp, tbl, chan, path, valcmd, typecmd)
+    Tcl_Interp* interp;
+    TBL* tbl;
+    Tcl_Channel chan;
+    char* path;
+    char* valcmd;
+    char* typecmd;
+{
+    int result;
+    ChannelBuf cb;
+    GenBuf gb;
+    unsigned long bytesDecoded;
+    char test;
+
+    TBLType* type = TblTypeOfPath (interp, tbl, path, FALSE, NULL, NULL, NULL);
+    if (!type)
+    	{
+    	Tcl_AppendResult(interp,"wrong typepath \"",path,"\"",NULL);
+    	return TCL_ERROR;
+    	}
+
+    result = Tcl_Read(chan,&test,1);
+    if (result<0) {
+    	Tcl_AppendResult(interp,"read failed",NULL);
+    	return TCL_ERROR;
+    }
+    if (result==0) {
+    	Tcl_AppendResult(interp,"0",NULL);
+    	return TCL_OK;
+    }
+    result = Tcl_Ungets(chan,&test,1,0);
+    if (result!=1) {
+    	Tcl_AppendResult(interp,"ungets failed",NULL);
+    	return TCL_ERROR;
+    }
+
+    cb.chan = chan;
+    PutChannelBufInGenBuf(&cb,&gb);
+    
+    interpG = interp;
+    interpResultG = TCL_OK;
+    tblvalcmdG = valcmd;
+    tbltypecmdG = typecmd;
+    ntp = 1;
+    
+    result = TdeDecodeSpecific(tbl,&gb,type,&bytesDecoded,TblDbgType,NULL,NULL);
+    if (interpResultG==TCL_OK)
+    	{
+    	if (!result)
+    	    Asn1Error("TdeDecodeSpecific failed");
+    	}
+    if (interpResultG==TCL_OK)
+    	{
+    	char buffer[11];
+    	sprintf(buffer,"%u",(int)bytesDecoded);
+    	Tcl_SetResult(interp,buffer,TCL_VOLATILE);
+    	}
+    return interpResultG;
+}
+
+int TblRealType (type)
+    TBLType* type;
+{
+    if (type->typeId==TBL_TYPEREF)
+	return TblRealType(type->content->a.typeRef->typeDefPtr->type);
+    else
+	return type->typeId;
+}
+
+TBLModule* TblModuleOfTypeDef (tbl, td)
+    TBL* tbl;
+    TBLTypeDef* td;
+{
+    TBLModule* tm;
+    TBLTypeDef* td2;
+    void *tmp1;
+    void *tmp2;
+
+     /* look in all modules and return typedef with given id */
+    tmp1 = CURR_LIST_NODE (tbl->modules);
+    FOR_EACH_LIST_ELMT (tm, tbl->modules)
+    {
+        tmp2 = CURR_LIST_NODE (tm->typeDefs);
+        FOR_EACH_LIST_ELMT (td2, tm->typeDefs)
+            if (td2==td)
+            {
+                SET_CURR_LIST_NODE (tm->typeDefs, tmp2);
+                SET_CURR_LIST_NODE (tbl->modules, tmp1);
+                return tm;
+            }
+        SET_CURR_LIST_NODE (tm->typeDefs, tmp2);
+    }
+    SET_CURR_LIST_NODE (tbl->modules, tmp1);
+    return NULL;
+}
+
+void TblDescType (ps, tbl, tm, td, type, tr, tnnl)
+    Tcl_DString* ps;
+    TBL* tbl;
+    TBLModule* tm;
+    TBLTypeDef* td;
+    TBLType* type;
+    TBLRange* tr;
+    TBLNamedNumberList* tnnl;
+{
+    if (td) {
+    	Tcl_DStringStartSublist(ps);
+    	Tcl_DStringAppendElement(ps,tm->name.octs);
+    	Tcl_DStringAppendElement(ps,td->typeName.octs);
+    	Tcl_DStringAppendElement(ps,td->isPdu?"pdu":"sub");
+    	Tcl_DStringEndSublist(ps);
+    } else {
+    	Tcl_DStringAppendElement(ps,type->fieldName.octs);
+    }
+    Tcl_DStringAppendElement(ps,TIN[type->typeId]);
+    Tcl_DStringStartSublist(ps);
+    if (!tr)
+    	tr = type->constraint;
+    if (tr) {
+    	char fmt[20];
+    	sprintf(fmt,"%d",tr->from);
+    	Tcl_DStringAppendElement(ps,fmt);
+    	if (tr->to!=tr->from) {
+    	    sprintf(fmt,"%d",tr->to);
+    	    Tcl_DStringAppendElement(ps,fmt);
+    	}
+    }
+    Tcl_DStringEndSublist(ps);
+    Tcl_DStringStartSublist(ps);
+    if (!tnnl)
+    	tnnl = type->values;
+    if (tnnl) {
+        TBLNamedNumber* tnn;
+        FOR_EACH_LIST_ELMT(tnn,tnnl)
+            {
+            char fmt[20];
+    	    Tcl_DStringStartSublist(ps);
+    	    sprintf(fmt,"%d",tnn->value);
+    	    Tcl_DStringAppendElement(ps,fmt);
+    	    if (tnn->name.octetLen)
+    	    	Tcl_DStringAppendElement(ps,tnn->name.octs);
+    	    Tcl_DStringEndSublist(ps);
+            }
+    }
+    Tcl_DStringEndSublist(ps);
+    if (type->content)
+    	switch (type->content->choiceId) {
+    	case TBLTYPECONTENT_ELMTS:
+    	    {
+    	    TBLType* elmt;
+	    void* tmp = CURR_LIST_NODE (type->content->a.elmts);
+    	    Tcl_DStringStartSublist(ps);
+    	    FOR_EACH_LIST_ELMT(elmt,type->content->a.elmts)
+    	    	{
+    	    	Tcl_DStringStartSublist(ps);
+    	    	TblDescType(ps,tbl,tm,NULL,elmt,NULL,NULL);
+    	    	Tcl_DStringEndSublist(ps);
+    	    	Tcl_DStringAppendElement(ps,elmt->optional?"0":"1");
+    	    	}
+    	    Tcl_DStringEndSublist(ps);
+	    SET_CURR_LIST_NODE (type->content->a.elmts, tmp);
+    	    }
+    	    break;
+    	case TBLTYPECONTENT_TYPEREF:
+    	    {
+    	    TBLTypeDef* td = type->content->a.typeRef->typeDefPtr;
+	    Tcl_DStringStartSublist(ps);
+	    Tcl_DStringAppendElement(ps,TblModuleOfTypeDef(tbl,td)->name.octs);
+	    Tcl_DStringAppendElement(ps,td->typeName.octs);
+	    Tcl_DStringEndSublist(ps);
+	    }
+    	    break;
+    	default:
+    	    break;
+    	}
+}
+
+typedef struct TblCmdData {
+    char name[20];
+    TBL* tbl;
+    } TblCmdData;
+
+int TblCmd (tcd, interp, argc, argv)
+    TblCmdData* tcd;
+    Tcl_Interp* interp;
+    int argc;
+    char* argv[];
+{
+    int c;
+    size_t l;
+    if (argc>=2) {
+	c = *argv[1];
+	l = strlen(argv[1]);
+
+	if (argc==2 && !strncmp(argv[1],"close",l)) {
+	    Tcl_DeleteCommand(interp,tcd->name);
+	    return TCL_OK;
+	} else if (!strncmp(argv[1],"decode",l) && (argc>=5 && argc<=6)) {
+	    int mode;
+	    Tcl_Channel chan = Tcl_GetChannel(interp,argv[2],&mode);
+	    if (!chan)
+		return TCL_ERROR;
+	    if (!(mode & TCL_READABLE)) {
+		Tcl_AppendResult(interp, "channel \"", argv[2],
+			"\" wasn't opened for reading", NULL);
+		return TCL_ERROR;
+	    }
+	    return TblCmdDecode(interp,tcd->tbl,chan,argv[3],argv[4],argv[5]);
+	} else if (!strncmp(argv[1],"encode",l) && (argc>=5 && argc<=6)) {
+	    int mode;
+	    Tcl_Channel chan = Tcl_GetChannel(interp,argv[2],&mode);
+	    if (!chan)
+		return TCL_ERROR;
+	    if (!(mode & TCL_WRITABLE)) {
+		Tcl_AppendResult(interp, "channel \"", argv[2],
+			"\" wasn't opened for writing", NULL);
+		return TCL_ERROR;
+	    }
+	    return TblCmdEncode(interp,tcd->tbl,chan,argv[3],argv[4],argv[5]);
+	} else if (argc==2 && !strncmp(argv[1],"modules",l)) {
+            TBLModule *tm;
+	    FOR_EACH_LIST_ELMT (tm, tcd->tbl->modules)
+		Tcl_AppendElement(interp,tm->name.octs);
+	    return TCL_OK;
+	} else if (!strncmp(argv[1],"type",l) && (argc==3 
+    		|| argc==4 && !strncmp(argv[2],"-followref",max(strlen(argv[2]),2)))) {
+    	    TBLTypeDef* td;
+    	    TBLRange* tr = NULL;
+    	    TBLNamedNumberList* tnnl = NULL;
+    	    TBLType* type = TblTypeOfPath(interp,tcd->tbl,argv[argc-1],argc==4,
+    	    	    &td,&tr,&tnnl);
+    	    if (!type)
+    		return TCL_ERROR;
+    	    else
+    		{
+		Tcl_DString ds;
+		Tcl_DStringInit(&ds);
+    		TblDescType(&ds,tcd->tbl,TblModuleOfTypeDef(tcd->tbl,td),
+    	    		type==td->type?td:NULL,type,tr,tnnl);
+		Tcl_DStringResult(interp,&ds);
+		Tcl_DStringFree(&ds);
+		return TCL_OK;
+    		}
+
+	} else if (argc>=2 && argc<=3 && !strncmp(argv[1],"types",l)) {
+            TBLModule *tm;
+            TBLTypeDef* td;
+            int moduleFound = 0;
+	    Tcl_DString ds;
+	    Tcl_DStringInit(&ds);
+	    FOR_EACH_LIST_ELMT (tm, tcd->tbl->modules)
+		if (argc==2 || equal(tm->name.octs,argv[2])) {
+		    moduleFound = 1;
+		FOR_EACH_LIST_ELMT (td, tm->typeDefs) {
+	    	    Tcl_DStringStartSublist(&ds);
+	    	    Tcl_DStringAppendElement(&ds,tm->name.octs);
+	    	    Tcl_DStringAppendElement(&ds,td->typeName.octs);
+	    	    Tcl_DStringEndSublist(&ds);
+	    	    }
+		}
+	    Tcl_DStringResult(interp,&ds);
+	    Tcl_DStringFree(&ds);
+	    if (argc==3 && !moduleFound) {
+		Tcl_AppendResult(interp,argv[0]," ",argv[1],": module \"",argv[2],
+	    		"\" unknown",NULL);
+		return TCL_ERROR;
+	    	}
+	    return TCL_OK;
+	}
+    }
+    Tcl_AppendResult(interp, "wrong # args:  should be \"",
+	    argv[0], 
+	    " modules", 
+	    " | types ?module?",
+	    " | type ?-followref? {?module? typedef ?subtype? ...}",
+	    " | decode channel {?module? typedef ?subtype? ...} valcmd ?typecmd?",
+	    " | encode channel {?module? typedef ?subtype? ...} valcmd ?typecmd?",
+	    " | close\"",
+	    NULL);
+    return TCL_ERROR;
+}
+
+void TblCmdFree (tcd)
+    TblCmdData* tcd;
+{
+    FreeTBL(tcd->tbl);
+    ckfree(tcd);
+}
+
+int TableCmd (clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp* interp;
+    int argc;
+    char* argv[];
+{
+    static int ntbl = 0;
+    TBL* tbl;
+    TblCmdData* tcd;
+    
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # args:  should be \"",
+		argv[0], " path\"", NULL);
+	return TCL_ERROR;
+    }
+
+    interpG = interp;
+    interpResultG = TCL_OK;
+    tbl = LoadTblFile(argv[1]);
+    if (!tbl && interpResultG==TCL_OK) {
+    	Asn1Error("Can't load grammar table");
+    }
+    
+    if (interpResultG!=TCL_OK)
+    	return interpResultG;
+    
+    tcd = (TblCmdData*) ckalloc(sizeof(*tcd));
+    sprintf(tcd->name,"asn%d",++ntbl);
+    tcd->tbl = tbl;
+    Tcl_CreateCommand(interp,tcd->name,TblCmd,tcd,TblCmdFree);
+    Tcl_AppendResult(interp,tcd->name,NULL);
+    return TCL_OK;
+    }
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppInit --
+ *
+ *	This procedure performs application-specific initialization.
+ *	Most applications, especially those that incorporate additional
+ *	packages, will have their own version of this procedure.
+ *
+ * Results:
+ *	Returns a standard Tcl completion code, and leaves an error
+ *	message in interp->result if an error occurs.
+ *
+ * Side effects:
+ *	Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+
+int
+Tbl_AppInit(interp)
+    Tcl_Interp *interp;		/* Interpreter for application. */
+{
+    if (Tcl_Init(interp) == TCL_ERROR) {
+	return TCL_ERROR;
+    }
+    if (Tk_Init(interp) == TCL_ERROR) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Call Tcl_CreateCommand for application-specific commands, if
+     * they weren't already created by the init procedures called above.
+     */
+
+    Asn1InstallErrorHandler(myAsn1ErrorHandler);
+    InitNibbleMem(1024,1024);
+    Tcl_CreateCommand(interp, "asn", TableCmd, NULL, NULL);
+
+    return TCL_OK;
+}
diff --git a/SecuritySNACCRuntime/tcl-example/dependencies b/SecuritySNACCRuntime/tcl-example/dependencies
new file mode 100644
index 00000000..e69de29b
diff --git a/SecuritySNACCRuntime/tcl-example/edex0.asn1 b/SecuritySNACCRuntime/tcl-example/edex0.asn1
new file mode 100644
index 00000000..0c3c332b
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-example/edex0.asn1
@@ -0,0 +1,39 @@
+-- file: edex0.asn1
+--
+-- snacced example, simple types module
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-example/edex0.asn1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+-- $Log: edex0.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:10  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:06:55  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.1  1997/01/01 22:57:11  rj
+-- first check-in
+--
+
+EdEx-Simple DEFINITIONS ::=
+BEGIN
+
+RainbowColor ::= INTEGER
+{
+  red(0), orange(1), yellow(2), green(3), blue(4), indigo(5), violet(6)
+}
+
+DayOfTheWeek ::= ENUMERATED
+{
+  sunday(0), monday(1), tuesday(2), wednesday(3), thursday(4), friday(5), saturday(6)
+}
+
+Hand ::= BIT STRING
+{
+  thumb(0), forefinger(1), middle-finger(2), ring-finger(3), little-finger(4)
+}
+
+victory Hand ::= { forefinger, middle-finger }
+
+File ::= OCTET STRING
+
+END
diff --git a/SecuritySNACCRuntime/tcl-example/edex1.asn1 b/SecuritySNACCRuntime/tcl-example/edex1.asn1
new file mode 100644
index 00000000..8f059521
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-example/edex1.asn1
@@ -0,0 +1,78 @@
+-- file: edex1.asn1
+--
+-- snacced example, structured types module
+--
+-- $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-example/edex1.asn1,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+-- $Log: edex1.asn1,v $
+-- Revision 1.1.1.1  2001/05/18 23:14:10  mb
+-- Move from private repository to open source repository
+--
+-- Revision 1.1.1.1  1999/03/16 18:06:55  aram
+-- Originals from SMIME Free Library.
+--
+-- Revision 1.2  1997/02/28 13:39:56  wan
+-- Modifications collected for new version 1.3: Bug fixes, tk4.2.
+--
+-- Revision 1.1  1997/01/01 22:57:13  rj
+-- first check-in
+--
+
+EdEx-Structured DEFINITIONS ::=
+BEGIN
+
+IMPORTS RainbowColor, DayOfTheWeek, Hand FROM EdEx-Simple;
+
+RGBColor ::= SEQUENCE
+{
+  red INTEGER,
+  green INTEGER,
+  blue INTEGER
+}
+
+Coordinate ::= CHOICE
+{
+  cartesian [0] SEQUENCE { x REAL, y REAL },
+  polar [1] SEQUENCE { angle REAL, distance REAL }
+}
+
+File ::= SET
+{
+  name [0] PrintableString,
+  contents [1] OCTET STRING,
+  checksum [2] INTEGER OPTIONAL,
+  read-only [3] BOOLEAN DEFAULT FALSE
+}
+
+Directory ::= SET
+{
+  name PrintableString,
+  files SET OF File
+}
+
+Simple ::= SET
+{
+  null   [0] NULL,
+  boolv  [1] BOOLEAN,
+  day    [2] DayOfTheWeek,
+  intv   [3] INTEGER,
+  color  [4] RainbowColor,
+  real   [5] REAL,
+  bits   [6] Hand,
+  str    [7] OCTET STRING,
+  optstr [8] OCTET STRING OPTIONAL
+}
+
+Structured ::= SET
+{
+  coord [0] Coordinate,
+  color [1] CHOICE { rainbow RainbowColor, rgb RGBColor }
+}
+
+Various ::= SET
+{
+  simple [0] Simple,
+  struct [1] Structured,
+  recursion [2] Various OPTIONAL
+}
+
+END
diff --git a/SecuritySNACCRuntime/tcl-example/makefile b/SecuritySNACCRuntime/tcl-example/makefile
new file mode 100644
index 00000000..cd095b3c
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-example/makefile
@@ -0,0 +1,102 @@
+#
+# Makefile for the snaccwish
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-example/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:55  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1997/02/16 12:53:24  rj
+# remove more generated files
+#
+# Revision 1.1  1997/01/01 22:57:14  rj
+# first check-in
+#
+
+include ../makehead
+
+TOP		= ..
+
+SNACC		= $(TOP)/compiler/snacc
+
+ASN1_SRC_DIR	= $(TOP)/asn1specs
+C++_LIB		= $(TOP)/c++-lib
+ASN1INC		= $(C++_LIB)/inc
+ASN1LIB		= $(C++_LIB)/libasn1tcl.a
+TCL_LIB		= $(TOP)/tcl-lib
+
+CPPFLAGS	+= -I$(TOP) -I$(ASN1INC) $(CPPFLAGS.TCL) $(CPPFLAGS.X11) -DTCL -DSNACC_DEEP_COPY
+
+PDUS		= X.T1,X.T4
+PDUS		= EdEx-Structured.File,EdEx-Structured.Directory,EdEx-Structured.Various
+
+ASN1FILES	= \
+	edex0.asn1	\
+	edex1.asn1
+
+ASN1HFILES	= \
+	edex0.h		\
+	edex1.h
+
+ASN1CFILES	= \
+	edex0.C		\
+	edex1.C		\
+	modules.C
+
+ASN1OFILES	= \
+	edex0.o		\
+	edex1.o		\
+	modules.o
+
+OFILES	= \
+	$(ASN1OFILES)
+
+DISTFILES = \
+	makefile	\
+	$(ASN1FILES)
+
+LDFLAGS		+= $(LDFLAGS.X11)
+LDLIBS		+= $(ASN1LIB) $(TREELIBS) $(TCLLIBS) $(LDLIBS.X11pre) -lX11 $(LDLIBS.X11extra) $(LIBS)
+
+WISH		= snaccwish
+SCRIPT		= snacced
+
+#-------------------------------------------------------------------------------
+
+all::		$(WISH) $(SCRIPT)
+
+$(WISH):	$(OFILES) $(ASN1LIB)
+		$(REASON)
+		$(CXX) $(LDFLAGS) -o $(WISH) $(OFILES) $(LDLIBS)
+
+$(SCRIPT)::
+		$(TCL_LIB)/make-snacced $@ ./$(WISH) $(TCL_LIB)
+
+$(ASN1LIB)::
+		cd $(@D) && $(MAKE) tcl-lib
+
+# if $(ASN1INC)/asn_useful.h doesn't exist, someone probably called `make clean` in $(C++_LIB).
+$(ASN1INC)/asn-useful.h:
+		$(MAKE) $(ASN1LIB)
+
+$(ASN1HFILES) $(ASN1CFILES):	$(SNACC) $(ASN1FILES) makefile
+		$(REASON)
+		$(SNACC) -u $(ASN1_SRC_DIR)/asn-useful.asn1 -tcl $(PDUS) $(ASN1FILES)
+
+$(SNACC)::
+		cd $(@D) && $(MAKE) $(@F)
+
+clean::
+		$(RM) $(ASN1HFILES) $(ASN1CFILES)
+		$(RM) $(OFILES)
+
+clobber::
+		$(RM) $(WISH)
+
+# dummy:
+install::
+
+include ../maketail
diff --git a/SecuritySNACCRuntime/tcl-lib/bindings.tcl b/SecuritySNACCRuntime/tcl-lib/bindings.tcl
new file mode 100644
index 00000000..fc510818
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-lib/bindings.tcl
@@ -0,0 +1,30 @@
+# file: bindings.tcl
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc bit_string_entry_bindings {entry} \
+{
+  bind $entry <Any-Key> { }
+#  bind $entry <Key-Return> {puts return}
+  bind $entry <Key-0> {%W insert insert %A}
+  bind $entry <Key-1> {%W insert insert %A}
+  bind $entry <Control-u> [bind Entry <Control-u>]
+  bind $entry <Control-v> [bind Entry <Control-v>]
+  bind $entry <Control-d> [bind Entry <Control-d>]
+  bind $entry <Delete> [bind Entry <Delete>]
+  bind $entry <Backspace> [bind Entry <Backspace>]
+  bind $entry <Left> {%W icursor [expr [%W index insert] -1]}
+  bind $entry <Right> {%W icursor [expr [%W index insert] +1]}
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc int_entry_bindings {entry} \
+{
+  bit_string_entry_bindings $entry
+  for {set i 2} {$i < 10} {incr i} \
+  {
+    bind $entry <Key-$i> {%W insert insert %A}
+    bind $entry <Key-KP_$i> {%W insert insert %A}
+  }
+  bind $entry <Key-minus> {%W insert insert %A}
+  bind $entry <Key-KP_Subtract> {%W insert insert %A}
+}
diff --git a/SecuritySNACCRuntime/tcl-lib/help.tcl b/SecuritySNACCRuntime/tcl-lib/help.tcl
new file mode 100644
index 00000000..068e0204
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-lib/help.tcl
@@ -0,0 +1,48 @@
+# file: help.tcl
+# toplevel widget to display a help text (modal)
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/help.tcl,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: help.tcl,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:55  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.1  1997/01/01 23:11:54  rj
+# first check-in
+#
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc help {w helptext} \
+{
+  set help .help
+  set text $help.text
+  set sb $help.sb
+  set dismiss $help.dismiss
+
+  getpos $w x y
+  incr x -100
+  toplevel $help -class Dialog
+  wm title $help {Help}
+  wm transient $help .
+  wm geometry $help +$x+$y
+  wm minsize $help 0 0
+
+  text $text -borderwidth 2 -relief sunken -yscrollcommand [list $sb set] -width 32 -height 8
+  scrollbar $sb -relief sunken -command [list $text yview] -width 10 -cursor arrow
+  button $dismiss -text Dismiss -command [list destroy $help]
+
+  pack $dismiss -side bottom -pady 2
+  pack $sb -side right -fill y
+  pack $text -expand true -fill both
+
+  bind $text <Any-Key> [list destroy $help]
+
+  $text insert end $helptext
+
+  set oldfocus [focus]
+  focus $text
+  tkwait window $help
+  focus $oldfocus
+}
diff --git a/SecuritySNACCRuntime/tcl-lib/make-snacced b/SecuritySNACCRuntime/tcl-lib/make-snacced
new file mode 100644
index 00000000..893ae803
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-lib/make-snacced
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+if [ $# -ne 3 ]; then
+  echo "usage: $0 script wish tcldir" 1>&2
+  exit 1
+fi
+
+set -e
+
+exec 1> "$1"
+
+echo "#!$2 -f"
+echo "set auto_path [linsert \$auto_path 0 $3]"
+echo "snacced"
+
+chmod +x "$1"
diff --git a/SecuritySNACCRuntime/tcl-lib/makefile b/SecuritySNACCRuntime/tcl-lib/makefile
new file mode 100644
index 00000000..68aca740
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-lib/makefile
@@ -0,0 +1,69 @@
+# file: .../tcl-lib/makefile
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/makefile,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: makefile,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:55  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.1  1997/01/01 23:11:57  rj
+# first check-in
+#
+
+include ../makehead
+
+TOP		= ..
+
+TCLFILES.dist	= \
+	bindings.tcl	\
+	help.tcl	\
+	selbox.tcl	\
+	snacced.tcl	\
+	tkuti.tcl	\
+	uti.tcl
+
+TCLFILES	= \
+	$(TCLFILES.dist)	\
+	tclIndex
+
+DISTFILES	= \
+	$(TCLFILES.dist)	\
+	make-snacced	\
+	makefile
+
+default:	tclIndex
+
+tclIndex:	$(TCLFILES.dist) makefile
+		echo 'auto_mkindex . $(TCLFILES.dist)' | $(TCLSH)
+
+install-sh:
+		ln $(TOP)/install-sh $@
+
+install::	$(TCLFILES) install-sh $(tcldir)
+
+$(tcldir):
+		$(TOP)/mkinstalldirs $@
+
+install::
+		$(INSTALL_PROGRAM) make-snacced	$(bindir)/
+		for tcl in $(TCLFILES); do\
+		  $(INSTALL_DATA) $$tcl $(tcldir)/;\
+		done
+
+clean::
+		$(RM) *~ *.dvi *.log *.aux *.toc *.lof *.lot *.bbl *.blg sp_errs .emacs*
+
+clobber::
+		$(RM) tclIndex
+		$(RM) install-sh
+
+gen-distfiles::	$(DISTFILES)
+
+distfiles::
+		echo $(DISTFILES)
+
+# dummy:
+depend::
+		@true
diff --git a/SecuritySNACCRuntime/tcl-lib/selbox.tcl b/SecuritySNACCRuntime/tcl-lib/selbox.tcl
new file mode 100644
index 00000000..69c6ba86
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-lib/selbox.tcl
@@ -0,0 +1,362 @@
+# file: selbox.tcl
+# file and content type selection box (ASN.1)
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/selbox.tcl,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
+# $Log: selbox.tcl,v $
+# Revision 1.1.1.1  2001/05/18 23:14:10  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:56  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1997/02/28 13:39:56  wan
+# Modifications collected for new version 1.3: Bug fixes, tk4.2.
+#
+# Revision 1.1  1997/01/01 23:11:59  rj
+# first check-in
+#
+
+proc selbox_newfn {sbref} \
+{
+  upvar #0 $sbref sb
+
+  set fn $sb(toplevel).f.fn.name
+
+  set name [$fn get]
+
+  debug $name
+}
+
+proc selbox_newbase {sbref} \
+{
+  global $sbref
+  upvar #0 $sbref sb
+
+  set fb_list $sb(toplevel).f.lists.basename
+  set bs [$fb_list curselection]
+  if {[llength $bs] == 1} \
+  {
+    set base [$fb_list get $bs]
+
+debug base=$base
+    set path [split $sb(fn) /]
+    set len [llength $path]
+    set last [expr $len-1]
+debug len=$len
+    if {$base == {..}} \
+    {
+      if {$len == 0} \
+      {
+	set $sbref\(fn) ..
+      } \
+      else \
+      {
+#	set sb [join [lrange $path 0 $last] /]
+	if {[lindex $path $last] == {..}} \
+	{
+	  append $sbref\(fn) /..
+	} \
+	else \
+	{
+	  set $sbref\(fn) [join [lrange $path 0 $last] /]
+	}
+      }
+    } \
+    else \
+    {
+      if {$len == 0} \
+      {
+	set $sbref\(fn) $base
+      } \
+      else \
+      {
+incr last -1
+#	set sb [join [concat [lrange $path 0 $last] $base] /]
+debug [list set $sbref\(fn) [join [concat [lrange $path 0 $last] $base] /]]
+	set $sbref\(fn) [join [concat [lrange $path 0 $last] $base] /]
+      }
+    }
+debug "sb(fn)=$sb(fn)"
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc selbox_update {name elem op} \
+{
+debug ">selbox_update $name $elem $op"
+  upvar #0 $name sb
+
+#debug "$name=$sb"
+  set fb_list $sb(toplevel).f.lists.basename
+  $fb_list delete 0 end
+  $fb_list insert 0 ..
+  set dir [file dirname $sb(fn)]
+  set base [file tail $sb(fn)]
+  set names [lsort [glob $dir/{.*,*}]]
+  foreach name $names \
+  {
+    set name [file tail $name]
+#    debug $name
+    if {$name != {.} && $name != {..}} \
+    {
+      $fb_list insert end $name
+      if {$name == $base} \
+      {
+	$fb_list select from end
+	$fb_list yview end
+      }
+    }
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc selbox_tm_click {sbref} \
+{
+  upvar #0 $sbref sb
+
+  global pdus
+
+  set t $sb(toplevel).t.lists
+  set tm $t.modules
+  set tt $t.types
+
+  set ms [$tm curselection]
+  if {[llength $ms] == 1} \
+  {
+    $tt delete 0 end
+    eval $tt insert 0 $pdus([$tm get $ms])
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc selbox_ok {sbref} \
+{
+  upvar #0 $sbref sb
+
+  set fn $sb(toplevel).f.fn.name
+  set t $sb(toplevel).t.lists
+  set m $t.modules
+  set t $t.types
+
+  if {$sb(want_fn) && $sb(fn) == {} && $sb(force_fn)} \
+  {
+    tk_dialog .d {select filename} "You need to enter a file name" warning 0 Ok
+    return
+  }
+
+  if {$sb(want_ct)} \
+  {
+    set ms [$m curselection]
+    set ts [$t curselection]
+
+    if {[llength $ms] == 1 && [llength $ts] == 1} \
+    {
+      set sb(ct) "[$m get $ms] [$t get $ts]"
+    } \
+    else \
+    {
+      tk_dialog .d {select content type} "You need to select a content type" warning 0 Ok
+      return
+    }
+  }
+
+  set sb(rc) 1
+  destroy $sb(toplevel)
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc selbox_cancel {sbref} \
+{
+  upvar #0 $sbref sb
+
+  set sb(rc) 0
+  destroy $sb(toplevel)
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+# the selbox (short for `file and content type selection box')
+# selbox has to be called with two arguments, which may be either empty or be the name of a global variable.
+# the selbox can display two sections: one for selecting a file name, a second for selecting a content type.
+# the selbox arguments denote the variable names for the the two sections.
+# if a variable name is empty, its corresponding section will not be displayed.
+# if filename_ref is non-empty, a filename will forced to be entered unless `nullfn' is given in args.
+
+# the 1x1 geometry for the listboxes below allows them to shrink when the selbox is resized.
+# (otherwise, the buttons and the second listbox will disappear!)
+
+set #sb 0
+
+proc selbox {filename_ref conttype_ref args} \
+{
+  # change this if you get widget or variable name collisions:
+  set prefix selbox
+
+  # choose a unique variable and widget name:
+  global #sb
+  while {[winfo exists [set toplevel .[set sbref $prefix${#sb}]]]} \
+  {
+    incr #sb
+  }
+
+  global $sbref
+  upvar #0 $sbref sb
+
+  if {$filename_ref != {}} \
+  {
+    set sb(want_fn) 1
+    set sb(force_fn) 1
+    upvar $filename_ref filename
+  } \
+  else \
+  {
+    set sb(want_fn) 0
+  }
+
+  if {$conttype_ref != {}} \
+  {
+    set sb(want_ct) 1
+    upvar $conttype_ref conttype
+  } \
+  else \
+  {
+    set sb(want_ct) 0
+  }
+
+  foreach arg $args \
+  {
+    switch $arg \
+    {
+      nullfn \
+      {
+	set sb(force_fn) 0
+      }
+      default \
+      {
+	error "selbox: illegal argument $arg"
+      }
+    }
+  }
+
+  set sb(toplevel) [toplevel $toplevel]
+  wm minsize $toplevel 1 1
+  wm geometry $toplevel 300x300
+
+  #--- up to three frames, for the file name, for the content type, and for a row of buttons:
+  set borderwidth 5
+  set relief ridge
+  if {$sb(want_fn)} \
+  {
+    set f [frame $toplevel.f -relief $relief -bd $borderwidth]
+  }
+  if {$sb(want_ct)} \
+  {
+    set t [frame $toplevel.t -relief $relief -bd $borderwidth]
+  }
+  set btns [frame $toplevel.btns -relief $relief -bd $borderwidth]
+
+  #--- fill the upper file frame:
+
+  if {$sb(want_fn)} \
+  {
+  #  set c [canvas $f.c -bg blue]
+    set flabel [label $f.label -text {File name:}]
+    set flists [frame $f.lists]
+    set fnf [frame $f.fn]
+  #$c create window 0 0 -window $flists -anchor nw
+  #set hsb [scrollbar $f.sb -orient horizontal -command "$c xview"]
+  #  set fd_list [listbox $flists.dirname -relief sunken]
+    set fb_list [listbox $flists.basename -relief sunken -width 1 -height 1 -selectmode single]
+
+  #  set fd_sb [scrollbar $flists.dir_sb]
+    set fb_sb [scrollbar $flists.base_sb]
+
+    $fb_list configure -yscrollcommand "$fb_sb set"
+    $fb_sb configure -command "$fb_list yview"
+
+  #  tk_listboxSingleSelect $fd_list $fb_list
+  #  tk_listboxSingleSelect $fb_list
+  #  bind $fd_list <Double-Button-1> "sb_newdir $sb"
+    bind $fb_list <Double-Button-1> "selbox_newbase $sbref"
+
+    set fn [entry $fnf.name -relief sunken -textvariable $sbref\(fn)]
+
+    #bind $fn <Return> "sb_newfn $sb"
+
+  #  pack $fd_list $fd_sb $fb_list $fb_sb -side left -expand 1 -fill y
+    pack $fb_list -side left -expand 1 -fill both
+    pack $fb_sb -side left -fill y
+    pack $fn
+
+    pack $flabel -fill x
+    pack $fnf -fill x
+    pack $flists -expand 1 -fill both
+  #  pack $c $hsb -expand 1 -fill both
+
+    trace variable $sbref\(fn) w selbox_update
+    # ``set sb(fn) {}'' doesn't work! (selbox_update will be called with the alias, not the global name!)
+    if {[info exists filename]} \
+    {
+      set $sbref\(fn) $filename
+    } \
+    else \
+    {
+      set $sbref\(fn) {}
+    }
+
+    pack $f -expand 1 -fill both
+  }
+
+  #--- fill the middle type frame:
+
+  if {$sb(want_ct)} \
+  {
+    set tlabel [label $t.label -text {Content type:}]
+    set tlists [frame $t.lists]
+
+    set tm [listbox $tlists.modules -exportselection 0 -relief sunken -width 1 -height 1 -selectmode single]
+    set tt [listbox $tlists.types -exportselection 0 -relief sunken -width 1 -height 1 -selectmode single]
+
+    set tm_sb [scrollbar $tlists.mod_sb]
+    set tt_sb [scrollbar $tlists.type_sb]
+
+    # tk_listboxSingleSelect $tm $tt
+    $tm configure -yscrollcommand "$tm_sb set"
+    $tm_sb configure -command "$tm yview"
+
+    global pdus
+    eval $tm insert 0 [array names pdus]
+    bind $tm <1> "[bind Listbox <1>]; selbox_tm_click $sbref"
+
+    pack $tm $tm_sb $tt $tt_sb -side left
+      pack configure $tm $tt -expand 1 -fill both
+      pack configure $tm_sb $tt_sb -fill y
+    pack $tlabel -fill x
+    pack $tlists -expand 1 -fill both
+
+    pack $t -expand 1 -fill both
+  }
+
+  #--- fill the lower button frame:
+
+  button $btns.ok -text Ok -command "selbox_ok $sbref"
+  button $btns.cancel -text Cancel -command "selbox_cancel $sbref"
+
+  pack $btns.ok $btns.cancel -side left -padx 3m
+
+  pack $btns -fill x
+
+  #--- now we're set up, let's go to work:
+
+  set of [focus]
+  focus $fn
+
+  tkwait window $toplevel
+  # if we got an affirmative response, export the selection:
+  if $sb(rc) \
+  {
+    if {$sb(want_fn)} { set filename $sb(fn) }
+    if {$sb(want_ct)} { set conttype $sb(ct) }
+  }
+  focus $of
+  return $sb(rc)
+}
diff --git a/SecuritySNACCRuntime/tcl-lib/snacced.tcl b/SecuritySNACCRuntime/tcl-lib/snacced.tcl
new file mode 100644
index 00000000..dc07cb60
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-lib/snacced.tcl
@@ -0,0 +1,1604 @@
+# file: .../tcl-lib/snacced.tcl
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/snacced.tcl,v 1.1.1.1 2001/05/18 23:14:11 mb Exp $
+# $Log: snacced.tcl,v $
+# Revision 1.1.1.1  2001/05/18 23:14:11  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:56  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.2  1997/02/28 13:39:57  wan
+# Modifications collected for new version 1.3: Bug fixes, tk4.2.
+#
+# Revision 1.1  1997/01/01 23:12:00  rj
+# first check-in
+#
+
+# todo:
+#	int, enum and bit string editors with scrollbar
+
+#\[banner "initialization"]---------------------------------------------------------------------------------------------------------
+
+set version 1.0
+
+#tk colormodel . monochrome
+
+# check all types whether they were marked as PDU.
+# collect them in an associative array (indexed by module name)
+foreach t [snacc types] \
+{ 
+  if {[lindex [snacc type $t] 1] == {pdu}} \
+  { 
+    set module [lindex $t 0]
+    set type [lindex $t 1]
+    lappend pdus($module) $type
+  }
+}
+
+#foreach n [array names pdus] \
+#{
+#  debug "module $n: $pdus($n)"
+#}
+
+#\[banner "debugging aid"]----------------------------------------------------------------------------------------------------------
+
+set debug 0
+
+proc debug {text} \
+{
+  global debug
+  if $debug {puts $text}
+}
+
+#\[banner "help texts"]-------------------------------------------------------------------------------------------------------------
+
+set helptext(about) "SnaccEd $version"
+
+set helptext(manoeuv) \
+"Button 1
+  on label
+    show/hide subnodes (except for lists)
+  on list
+    perform action (selected with button 3's popup)
+
+Button 2
+  on label
+    open/close value editor
+  on canvas, list or text
+    drag view
+
+Button 3
+  on label
+    show/hide parent
+  on list
+    select action mode (for button 1)
+  on text
+    pops up menu for text import/export
+"
+
+#\[banner "File loading and saving"]------------------------------------------------------------------------------------------------
+
+# called from file_reload and file_load_from
+# clears the display so that only the file's root gets shown
+proc file_prune {fileref} \
+{
+  upvar #0 $fileref file
+
+  set tree $file(tree)
+  set handle $file(handle)
+
+  list_cleanup /$handle $handle
+  $tree prune {}
+
+  ed_addnode $tree {} {} {} $handle $handle valid
+  $tree draw
+}
+
+# this function is called from the "File" menu.
+# it reloads the file contents from its old origin:
+proc file_reload {fileref} \
+{
+  set rc 1
+  upvar #0 $fileref file
+  # file_prune must be called before the snacc object is modified:
+  file_prune $fileref
+  $file(toplevel) config -cursor watch
+  update idletasks
+  if {[catch {snacc read $file(handle)} msg]} \
+  {
+    tk_dialog .d load "Couldn't reload: $msg" warning 0 Dismiss
+  } \
+  else \
+  {
+    set file(modified) 0
+    set rc 0
+  }
+  $file(toplevel) config -cursor arrow
+  return $rc
+}
+
+# this function is called from the "File" menu.
+# it lets the user select a file and loads its contents
+proc file_load_from {fileref} \
+{
+  set rc 1
+  upvar #0 $fileref file
+  if {[selbox fn ct]} \
+  {
+    # file_prune must be called before the snacc object is modified:
+    file_prune $fileref
+    $file(toplevel) config -cursor watch
+    update idletasks
+    if {[catch {snacc read $file(handle) $ct $fn} msg]} \
+    {
+      tk_dialog .d load "Couldn't load $fn: $msg" warning 0 Dismiss
+    } \
+    else \
+    {
+      set file(modified) 0
+      set rc 0
+    }
+    $file(toplevel) config -cursor arrow
+  }
+  return $rc
+}
+
+# this function is called from the "File" menu.
+# it saves the file contents to its old origin:
+proc file_save {fileref} \
+{
+  set rc 1
+  upvar #0 $fileref file
+  $file(toplevel) config -cursor watch
+  update idletasks
+  if {[catch {snacc write $file(handle)} msg]} \
+  {
+    tk_dialog .d save "Couldn't save: $msg" warning 0 Dismiss
+  } \
+  else \
+  {
+    set file(modified) 0
+    set rc 0
+  }
+  $file(toplevel) config -cursor arrow
+  return $rc
+}
+
+# this function is called from the "File" menu.
+# it lets the user select a file and saves the file's contents
+proc file_save_as {fileref} \
+{
+  set rc 1
+  upvar #0 $fileref file
+  if {[selbox fn {}]} \
+  {
+    $file(toplevel) config -cursor watch
+    update idletasks
+    if {[catch {snacc write $file(handle) $fn} msg]} \
+    {
+      tk_dialog .d save "Couldn't save $fn: $msg" warning 0 Dismiss
+    } \
+    else \
+    {
+      set file(modified) 0
+      set rc 0
+    }
+    $file(toplevel) config -cursor arrow
+  }
+  return $rc
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+# this function is called from prune_or_add_children, list_click, new_choice, toggle_se* and set_or_add_root
+# it adds the node's children to the display
+# some of the children may already be displayed (this is usually the case when the function gets called from list_click or set_or_add_root).
+# ed_addnode will be called for every child.
+
+proc ed_expand {tree treepath snaccpath} \
+{
+  set canvas [$tree canvas]
+
+  set info [snacc info $snaccpath]
+  set type [lindex $info 2]
+
+  switch $type \
+  {
+    SEQUENCE -
+    SET \
+    {
+      debug "$type:"
+      foreach elem [lindex $info 3] \
+      {
+	set name [lindex $elem 0]
+	set validity [lindex $elem 1]
+	debug "  $validity $name"
+	ed_addnode $tree $treepath $treepath $snaccpath $name $name $validity
+      }
+    }
+    SEQUENCE\ OF -
+    SET\ OF \
+    {
+      set len [lindex $info 3]
+      set varname var:$treepath
+      upvar #0 $varname var
+debug [list treepath=$treepath]
+debug [list varname=$varname]
+debug [list idlist=$var(idlist)]
+debug [list expand list ($type) len=$len]
+      for {set i 0} {$i < $len} {incr i} \
+      {
+	set id [lindex $var(idlist) $i]
+debug [list index $i id $id]
+	if {$id} \
+	{
+	  ed_addnode $tree $treepath $treepath $snaccpath $id $i valid
+	}
+      }
+    }
+    CHOICE \
+    {
+      set name [lindex $info 3]
+      set validity [lindex $info 4]
+      debug "  $validity $name"
+      ed_addnode $tree $treepath $treepath $snaccpath $name $name $validity
+    }
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+
+# ed_addnode is called from set_or_add_root, new_file, file_prune and ed_expand.
+# the node may already be displayed (this is usually the case when the function ed_expand gets called from list_click or set_or_add_root). in this case the node gets moved to the right position.
+# otherwise the node is created at the right place.
+
+# the arguments are:
+#   tree		name of the tree widget
+#   treeparent		tag of the displayed parent node. this is usually the same as the treeparentpath, except when the display gets extended into the parent direction where the root tag is {}
+#   treeparentpath	tag of the logical parent node.
+#   snaccparentpath	names of the 
+#   treenode		node's name, gets appended to the treeparentpath
+#   snaccnode		node's name, gets appended to the snaccparentpath
+#   validity
+
+proc ed_addnode {tree treeparent treeparentpath snaccparentpath treenode snaccnode validity} \
+{
+  set canvas [$tree canvas]
+
+  set treepath "$treeparentpath/$treenode"
+  set snaccpath "$snaccparentpath $snaccnode"
+
+  if [llength [$canvas find withtag $treepath]] \
+  {
+debug [list movelink $treepath $treeparent]
+    $tree movelink $treepath $treeparent
+  } \
+  else \
+  {
+#debug [list addnode $snaccpath]
+    if {[llength $snaccparentpath] > 0} \
+    {
+      set nodelabeltext $snaccnode
+    } \
+    else \
+    {
+      set finfo [snacc finfo [string range $snaccpath 1 end]]
+      if {[lindex $finfo 0] == {}} \
+      {
+	set nodelabeltext {(unnamed)}
+      } \
+      else \
+      {
+	set nodelabeltext [lindex $finfo 0]
+      }
+    }
+    $canvas create text 0 0 -text $nodelabeltext -tags [list $validity-label $treepath $treepath:label]
+
+    set line [$canvas create line 0 0 0 0]
+
+    # fix for canvas bug: for reverse video, the canvas displays black items on a black background
+    if {[tk colormodel .] == {monochrome} && [lindex [$canvas config -background] 4] == {black}} \
+    {
+      $canvas itemconfigure $treepath -fill white
+      $canvas itemconfigure $line -fill white
+    }
+
+    if {$validity == {void}} \
+    {
+      if {[tk colormodel .] == {color}} \
+      {
+	# #b0b0b0 is the light grey of disabled checkbuttons:
+	$canvas itemconfigure $treepath -fill #b0b0b0
+	$canvas itemconfigure $line -fill #b0b0b0
+      } \
+      else \
+      {
+	$canvas itemconfigure $treepath -stipple gray50
+	$canvas itemconfigure $line -stipple gray50
+      }
+    }
+
+debug [list addlink $treeparent $treepath $line]
+    $tree addlink $treeparent $treepath $line
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+# open/drop subtree
+proc prune_or_add_children {canvas} \
+{
+  set tree $canvas.t
+#  debug $canvas
+  set id [$canvas find withtag current]
+  if {$id == {}} \
+  {
+    debug "no item"
+  } \
+  else \
+  {
+    set treepath [lindex [$canvas gettags $id] 1]
+    set snaccpath [tree2snacc $treepath]
+    set type [lindex [snacc info $snaccpath] 2]
+    switch $type \
+    {
+      SEQUENCE\ OF - SET\ OF
+      {}
+      default
+      {
+#    debug $treepath
+	if {[$tree isleaf $treepath]} \
+	{
+	  debug [list expanding $treepath $snaccpath]
+	  ed_expand $tree $treepath $snaccpath
+	} \
+	else \
+	{
+	  debug [list cutting $treepath]
+	  # !!! list_cleanup usually has to be called with the node that gets removed!
+	  # in this case calling it with the node that stays around doesn't hurt because it is guaranteed not to be a SEQUENCE OF or SET OF type (they are handled a few lines above)
+	  list_cleanup $treepath $snaccpath
+	  $tree prune $treepath
+	}
+      }
+    }
+  }
+  $tree draw
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+# this function has to be called whenever a subtree that may contain SET OF or SEQUENCE of types gets removed from the display
+# it must be called *before* the snacc object gets destroyed, the function examines it!
+proc list_cleanup {treepath snaccpath} \
+{
+  set info [snacc info $snaccpath]
+  set type [lindex $info 2]
+  switch $type \
+  {
+    SET - SEQUENCE - CHOICE
+    {
+      foreach elem [lindex $info 3] \
+      {
+	set name [lindex $elem 0]
+	set validity [lindex $elem 1]
+	if {$validity == {valid}} \
+	{
+	  set subtreepath "$treepath/$name"
+	  set subsnaccpath "$snaccpath $name"
+	  list_cleanup $subtreepath $subsnaccpath
+	}
+      }
+    }
+    SET\ OF - SEQUENCE\ OF
+    {
+      set varname var:$treepath
+      global $varname
+debug [list varname=$varname]
+      if {[info exists $varname]} \
+      {
+	set idlist [set $varname\(idlist)]
+debug [list idlist=$idlist]
+	set i 0
+	foreach id $idlist \
+	{
+	  if {$id != 0} \
+	  {
+	    set subtreepath "$treepath/$id"
+	    set subsnaccpath "$snaccpath $i"
+	    list_cleanup $subtreepath $subsnaccpath
+	  }
+	  incr i
+	}
+	unset $varname
+      }
+    }
+  }
+}
+
+# this function must be called when calling "$tree root $treepath".
+# it calls list_cleanup for all nodes that are neither parent nor in the subtree pointed to by $treepath.
+proc list_cleanup_not_me {treepath snaccpath} \
+{
+  if {[set i [llength $snaccpath]] > 1} \
+  {
+    incr i -1
+    set parenttreepath [join [lrange [split $treepath /] 0 $i] /]
+    incr i -1
+    set parentsnaccpath [lrange $snaccpath 0 $i]
+
+    set info [snacc info $parentsnaccpath]
+    set type [lindex $info 2]
+    switch $type \
+    {
+      SET - SEQUENCE - CHOICE
+      {
+	foreach elem [lindex $info 3] \
+	{
+	  set name [lindex $elem 0]
+	  set validity [lindex $elem 1]
+	  if {$validity == {valid}} \
+	  {
+	    set subparenttreepath "$parenttreepath/$name"
+	    set subparentsnaccpath "$parentsnaccpath $name"
+	    if {$subparenttreepath != $treepath} \
+	    {
+	      list_cleanup $subparenttreepath $subparentsnaccpath
+	    }
+	  }
+	}
+      }
+      SET\ OF - SEQUENCE\ OF
+      {
+	set varname var:$parenttreepath
+	global $varname
+  debug [list varname=$varname]
+	set idlist [set $varname\(idlist)]
+debug [list idlist=$idlist]
+	set i 0
+	foreach id $idlist \
+	{
+	  if {$id != 0} \
+	  {
+	    set subparenttreepath "$parenttreepath/$id"
+	    set subparentsnaccpath "$parentsnaccpath $i"
+	    if {$subparenttreepath != $treepath} \
+	    {
+	      list_cleanup $subparenttreepath $subparentsnaccpath
+	      set $varname\(idlist) [lreplace [set $varname\(idlist)] $i $i 0]
+	    }
+	  }
+	  incr i
+	}
+      }
+    }
+    # recursion:
+    list_cleanup_not_me $parenttreepath $parentsnaccpath
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+# /file0/files/1/name \(-> { file0 files 0 name}
+
+proc tree2snacc {treepath} \
+{
+  set subtreepath {}
+  foreach elem [lrange [split $treepath /] 1 end] \
+  {
+    set treeelem $elem
+    if {[regexp {^[0-9]} $elem]} \
+    {
+      set varname var:$subtreepath
+      global $varname
+      set idlist [set $varname\(idlist)]
+      set id $elem
+      set index 0
+      foreach lid $idlist \
+      {
+	if {$lid == $id} break
+	incr index
+      }
+      if {$index == [llength $idlist]} \
+      {
+	error "tree2snacc: id $id not found in idlist [list $idlist]"
+      }
+      set snaccelem $index
+    } \
+    else \
+    {
+      set snaccelem $elem
+    }
+    append subtreepath /$treeelem
+    append subsnaccpath " $snaccelem"
+  debug [list >>$subtreepath--$subsnaccpath<<]
+  }
+  debug [list >>$subtreepath--$subsnaccpath<<]
+  return $subsnaccpath
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc import_text {text_w treepath} \
+{
+  if {[selbox fn {}]} \
+  {
+    if {[catch {set text [snacc import $fn]} msg]} \
+    {
+      tk_dialog .d import "Couldn't import $fn: $msg" warning 0 Dismiss
+    } \
+    else \
+    {
+      $text_w delete 0.0 end
+      $text_w insert end $text
+      snacc set [tree2snacc $treepath] $text
+    }
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc export_text {text_w} \
+{
+  if {[selbox fn {}]} \
+  {
+    if {[catch {snacc export [$text_w get 0.0 end] $fn} msg]} \
+    {
+      tk_dialog .d import "Couldn't export $fn: $msg" warning 0 Dismiss
+    }
+  }
+}
+
+proc frame_resize_bindings {fileref treepath} \
+{
+  upvar #0 $fileref file
+
+  set frame $file(canvas).edit$treepath
+
+  bind $frame <ButtonPress-1> [list frame_resize_start $fileref %x %y]
+  bind $frame <Button1-Motion> [list frame_resize_cont $fileref $treepath %x %y]
+  bind $frame <ButtonRelease-1> [list frame_resize_end $fileref $treepath]
+
+  $frame config -cursor bottom_right_corner
+}
+
+proc frame_resize_start {fileref x y} \
+{
+#debug [list frame_resize_start $fileref $x $y]
+
+  upvar #0 $fileref file
+
+  set file(resize_x) $x
+  set file(resize_y) $y
+}
+
+proc frame_resize_cont {fileref treepath x y} \
+{
+#debug [list frame_resize_cont $fileref $treepath $x $y]
+
+  upvar #0 $fileref file
+
+  set frame $file(canvas).edit$treepath
+  set frametag $treepath:edit
+
+  set oldw [lindex [$file(canvas) itemconfig $frametag -width] 4]
+  set oldh [lindex [$file(canvas) itemconfig $frametag -height] 4]
+debug "old: $oldw x $oldh"
+  set neww [max 1 [expr $oldw+$x-$file(resize_x)]]
+  set newh [max 1 [expr $oldh+$y-$file(resize_y)]]
+debug "new: $neww x $newh"
+  $file(canvas) itemconfig $frametag -width $neww -height $newh
+  set file(resize_x) $x
+  set file(resize_y) $y
+}
+
+proc frame_resize_end {fileref treepath} \
+{
+#debug [list frame_resize_end $fileref $treepath]
+
+  upvar #0 $fileref file
+
+  $file(tree) nodeconfig $treepath
+  $file(tree) draw
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+# toggle content editor
+proc toggle_editor {canvas} \
+{
+  set tree $canvas.t
+  set id [$canvas find withtag current]
+  if {$id == {}} \
+  {
+    debug "no item"
+  } \
+  else \
+  {
+    set treepath [lindex [$canvas gettags $id] 1]
+    set snaccpath [tree2snacc $treepath]
+    set frame $canvas.edit$treepath
+    if [llength [$canvas find withtag $treepath:edit]] \
+    {
+debug "removing editor for [list $treepath]"
+      $canvas delete $treepath:edit
+      destroy $frame
+      $tree nodeconfig $treepath -remove {}
+    } \
+    else \
+    {
+debug "opening editor for [list $treepath]"
+
+      set fileref [lindex [split $treepath /] 1]
+
+      frame $frame -borderwidth 3 -bg #cdb79e
+      set cleanup [list [list destroy $frame]]
+
+      set info [snacc info $snaccpath]
+      set type [lindex $info 2]
+
+      switch $type \
+      {
+	NULL \
+	{
+	  set label $frame.label
+	  label $label -text NULL
+	  pack $label
+	}
+	BOOLEAN \
+	{
+	  set value [snacc get $snaccpath]
+
+	  set var var:$treepath
+	  global $var
+	  set $var $value
+
+	  set button $frame.button
+	  #checkbutton $button -variable $var
+	  checkbutton $button -onvalue TRUE -offvalue FALSE -variable $var -textvariable $var -command [list debug [list $canvas $treepath]]
+	  pack $button
+
+	  trace variable $var w change_simple
+	}
+	INTEGER \
+	{
+	  set value [snacc get $snaccpath]
+
+	  set var var:$treepath
+	  global $var
+	  set $var $value
+
+	  if {[lindex $info 0] != {{} {}}} \
+	  {
+	    set typeinfo [snacc type [lindex $info 0]]
+
+	    foreach elem [lindex $typeinfo 3] \
+	    {
+	      set en [lindex $elem 0]
+	      set ev [lindex $elem 1]
+	      set button $frame.button$en
+	      radiobutton $button -text $en -variable $var -value $ev -anchor w
+	      pack $button -fill x
+	    }
+	  }
+
+	  set entry $frame.entry
+	  entry $entry -textvariable $var -width 9 -relief sunken
+
+	  int_entry_bindings $entry
+
+	  pack $entry -anchor w -fill x
+
+	  focus $entry
+
+	  trace variable $var w change_simple
+	}
+	ENUMERATED \
+	{
+	  set typeinfo [snacc type [lindex $info 0]]
+
+	  if {[catch {set value [snacc get $snaccpath]} msg] == 1} \
+	  {
+	    global errorInfo errorCode
+	    if {$errorCode == {SNACC ILLENUM}} \
+	    {
+	      set value [lindex [lindex $typeinfo 3] 0]
+	      snacc set $snaccpath $value
+	      append msg "--setting to first legal symbolic value \"$value\""
+	      tk_dialog .d illenum "$msg" warning 0 Dismiss
+	    } \
+	    else \
+	    {
+	      error $msg $errorInfo $errorCode
+	    }
+	  }
+
+	  set var var:$treepath
+	  global $var
+	  set $var $value
+
+	  foreach ev [lindex $typeinfo 3] \
+	  {
+	    set button $frame.button$ev
+	    radiobutton $button -text $ev -variable $var -value $ev -anchor w
+	    pack $button -fill x
+	  }
+
+	  trace variable $var w change_simple
+	}
+	REAL \
+	{
+	  set value [snacc get $snaccpath]
+
+	  set var var:$treepath
+	  global $var
+	  set $var $value
+
+	  set entry $frame.entry
+	  entry $entry -textvariable $var -relief sunken
+	  pack $entry
+
+	  frame_resize_bindings $fileref $treepath
+
+	  focus $entry
+
+	  trace variable $var w change_simple
+	}
+	BIT\ STRING \
+	{
+	  set value [snacc get $snaccpath]
+
+	  set var var:$treepath
+	  global $var
+	  set $var $value
+
+	  set max_ev 0
+	  if {[lindex $info 0] != {{} {}}} \
+	  {
+	    set typeinfo [snacc type [lindex $info 0]]
+
+	    foreach elem [lindex $typeinfo 3] \
+	    {
+	      set en [lindex $elem 0]
+	      set ev [lindex $elem 1]
+	      set max_ev [max $ev $max_ev]
+	      set button $frame.button$en
+	      checkbutton $button -text $en -variable $var:$ev -command [list toggle_bit $var $ev] -anchor w
+	      pack $button -fill x
+	    }
+	  }
+
+	  set entry $frame.entry
+	  entry $entry -textvariable $var -relief sunken
+	  set len [max 8 [string length $value] [expr $max_ev + 1]]
+	  if {$len > 0} \
+	  {
+debug [list length of entry is $len]
+	    $entry config -width $len
+	  }
+	  pack $entry -anchor w -fill x
+
+	  bit_string_entry_bindings $entry
+
+	  focus $entry
+
+	  trace variable $var w change_bits
+	  set $var $value; # trigger the trace
+	}
+	OBJECT\ IDENTIFIER \
+	{
+	  set value [snacc get $snaccpath]
+
+	  set var var:$treepath
+	  global $var
+	  set $var $value
+
+	  set entry $frame.entry
+	  entry $entry -textvariable $var -relief sunken
+	  pack $entry -fill both
+
+	  frame_resize_bindings $fileref $treepath
+
+	  focus $entry
+
+	  trace variable $var w change_simple
+	}
+	OCTET\ STRING \
+	{
+	  set value [snacc get $snaccpath]
+
+	  set text $frame.text
+	  set sb $frame.sb
+
+	  text $text -borderwidth 2 -relief sunken -yscrollcommand [list $sb set] -width 32 -height 8
+	  scrollbar $sb -relief sunken -command [list $text yview] -width 10 -cursor arrow
+
+	  pack $sb -side right -fill y
+	  pack $text -side left -expand true -fill both
+
+	  bind $text <ButtonPress-2> [list $text scan mark %y]
+	  bind $text <Button2-Motion> [list $text scan dragto %y]
+
+	  bind $text <Leave> "snacc set \[tree2snacc $treepath\] \[$text get 0.0 end\]"
+	  bind $text <FocusOut> "snacc set \[tree2snacc $treepath\] \[$text get 0.0 end\]"
+
+	  set m $frame.menu
+	  menu $m
+	  $m add command -label Load... -command "[list import_text $text $treepath]; [list $m unpost]"
+	  $m add command -label Save... -command "[list export_text $text]; [list $m unpost]"
+
+	  bind $text <ButtonPress-3> "[list $m] post \[expr %X -16\] \[expr %Y -8\]"
+	  bind $m <ButtonPress-3> [list $m unpost]
+	  bind $m <Any-Leave> [list $m unpost]
+
+	  $text insert end $value
+	  focus $text
+
+	  frame_resize_bindings $fileref $treepath
+	}
+	SEQUENCE -
+	SET \
+	{
+	  set typeinfo [snacc type [lindex $info 0]]
+
+	  debug "$type:"
+
+	  set varelems [lindex $info 3]
+	  set typeelems [lindex $typeinfo 3]
+
+	  for {set i 0; set len [llength $varelems]} {$i < $len} {incr i} \
+	  {
+	    set varelem [lindex $varelems $i]
+	    set typeelem [lindex $typeelems $i]
+
+	    set name [lindex $varelem 0]
+	    set validity [lindex $varelem 1]
+	    debug "  $validity $name"
+
+	    set var var:$treepath:$name
+	    global $var
+	    set $var $validity
+
+	    set button $frame.$name
+	    checkbutton $button -text $name -onvalue valid -offvalue void -variable $var -command [list toggle_se* $canvas $treepath $name] -anchor w
+	    if {[lindex $typeelem 4] == {mandatory}} \
+	    {
+	      #$button configure -disabledforeground [lindex [$button configure -fg] 4] -state disabled
+	      $button configure -state disabled
+	    }
+	    pack $button -fill x
+	  }
+	}
+	SEQUENCE\ OF -
+	SET\ OF \
+	{
+	  set len [lindex $info 3]
+
+	  set varname var:$treepath
+	  upvar #0 $varname var
+	  if {![info exists var(idlist)]} \
+	  {
+	    set var(idlist) {}
+	    set var(lastid) 0
+	  }
+	  # no! needs a longer lifetime!
+	  #lappend cleanup [list global $varname] [list unset $varname]
+
+#	  set mbar $frame.mbar
+	  set list $frame.list
+	  set sb $frame.sb
+
+	  scrollbar $sb -command [list $list yview] -width 10 -relief sunken -cursor arrow
+#	  listbox $list -yscroll [list $sb set] -relief sunken -width 4 -height 5
+	  text $list -borderwidth 2 -relief sunken -yscrollcommand [list $sb set] -width 4 -height 8 -exportselection 0
+	  pack $sb -side right -fill y
+	  pack $list -side left -expand true -fill both
+
+#	  frame $mbar -relief raised -bd 2
+#	  pack $mbar -side top -fill x
+
+#	  set mode $mbar.mode
+#	  set mode $frame.mode
+#	  set m $mode.m
+#	  menubutton $mode -text Mode -menu $m
+	  set m $frame.mode
+	  menu $m
+	  set lm "[list list_mode $canvas $treepath]; [list $m unpost]"
+	  $m add radiobutton -label Display -variable ${varname}(mode) -value display -command $lm
+	  $m invoke last
+	  $m add radiobutton -label Insert -variable ${varname}(mode) -value insert -command $lm
+	  $m add radiobutton -label Append -variable ${varname}(mode) -value append -command $lm
+	  $m add radiobutton -label Delete -variable ${varname}(mode) -value delete -command $lm
+#	  pack $mode -side left
+
+#	  pack $mode -side top -fill x
+
+	  $list tag config display -background #b2dfee -relief raised
+	  bind $list <Button-1> [list list_click $canvas $treepath]
+	  bind $list <Double-Button-1> { }
+	  bind $list <Triple-Button-1> { }
+	  bind $list <Button1-Motion> { }
+
+	  bind $list <ButtonPress-3> "[list $m] post \[expr %X-16\] \[expr %Y-8\]"
+	  bind $m <ButtonPress-3> [list $m unpost]
+	  bind $m <Any-Leave> [list $m unpost]
+	  debug $m
+
+	  for {set i 0} {$i < $len} {incr i} \
+	  {
+	    $list insert end [format "%4d\n" $i]
+
+	    if {[llength $var(idlist)] > $i} \
+	    {
+	      if {[set id [lindex $var(idlist) $i]]} \
+	      {
+		set line [expr $i + 1]
+		$list tag add display $line.0 $line.end
+	      }
+	    } \
+	    else \
+	    {
+	      set var(idlist) [linsert $var(idlist) $i 0]
+	    }
+	  }
+
+	  frame_resize_bindings $fileref $treepath
+	}
+	CHOICE \
+	{
+	  set name [lindex $info 3]
+	  set validity [lindex $info 4]
+	  set typeinfo [snacc type [lindex $info 0]]
+
+	  set var var:$treepath
+	  set oldvar oldvar:$treepath
+	  global $var $oldvar
+	  set $var $name
+	  set $oldvar $name
+
+	  foreach elem [lindex $typeinfo 3] \
+	  {
+	    set en [lindex $elem 0]
+	    set button $frame.button$en
+	    radiobutton $button -text $en -variable $var -value $en -command [list new_choice $canvas $treepath] -anchor w
+	    pack $button -fill x
+	  }
+	  debug "  $validity $name"
+	}
+	default \
+	{
+	  error "unexpected type $type"
+	}
+      }
+
+      scan [$canvas bbox $treepath:label] "%d%d%d%d" lx uy rx ly
+      $canvas create window $lx $ly -anchor nw -tags [list edit $treepath $treepath:edit] -window $frame
+
+      update idletasks;		# calculate frame's size (needed by tree widget)
+
+      # explicitly set the frame's width&height to avoid nasty effects when resizing:
+      scan [$canvas bbox $treepath:edit] "%d%d%d%d" lx uy rx ly
+      $canvas itemconfig $treepath:edit -width [expr $rx - $lx] -height [expr $ly - $uy]
+
+#debug [list cleanup = [join $cleanup \;]]
+      $tree nodeconfig $treepath -remove [join $cleanup \;]
+    }
+  }
+  $tree draw
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc list_click {canvas treepath} \
+{
+  set tree $canvas.t
+  set snaccpath [tree2snacc $treepath]
+
+debug [list treepath=$treepath]
+debug [list snaccpath=$snaccpath]
+debug [list tree2snacc: [tree2snacc $treepath]]
+  set varname var:$treepath
+  upvar #0 $varname var
+  set frame $canvas.edit$treepath
+  set list $frame.list
+
+  debug [list list_click: $list]
+debug [list varname=$varname]
+debug [list idlist=$var(idlist)]
+#  debug [$list tag ranges display]
+  set text_index [$list index current]
+#debug [list index: $index]
+  if {$text_index != ""} \
+  {
+    # strip the column number:
+    set line [lindex [split $text_index .] 0]
+    # lines numbers start at 1, indices at 0:
+    set index [expr $line - 1]
+    set len [llength $var(idlist)]
+    set tags [$list tag names $text_index]
+    switch $var(mode) \
+    {
+      display \
+      {
+debug [list tags: $tags]
+debug [list line: $line]
+	if {$index < $len} \
+	{
+	  set id [lindex $var(idlist) $index]
+debug [list index $index id $id]
+	  if {$id} \
+	  {
+	    $list tag remove display $line.0 $line.end
+	    list_cleanup $treepath/$id "$snaccpath $index"
+debug [list $tree rmlink $treepath/$id]
+	    $tree rmlink $treepath/$id
+	    set var(idlist) [lreplace $var(idlist) $index $index 0]
+	  } \
+	  else \
+	  {
+	    $list tag add display $line.0 $line.end
+	    set var(idlist) [lreplace $var(idlist) $index $index [incr var(lastid)]]
+	    ed_expand $tree $treepath $snaccpath
+	  }
+	}
+      }
+      insert -
+      append \
+      {
+	if {$var(mode) == {append}} {incr index}
+debug [list insert $index 0]
+	set var(idlist) [linsert $var(idlist) $index 0]
+debug [list $var(idlist)]
+debug [list catch [list snacc set "$snaccpath {insert $index}" {}]]
+	catch [list snacc set "$snaccpath {insert $index}" {}]
+	set file(modified) 1
+debug [list [snacc get $snaccpath]]
+
+	$list insert end [format "%4d\n" [expr [lindex [split [$list index end] .] 0] - 1]]
+
+	for {set i $len} {$i > $index} {incr i -1} \
+	{
+	  set line [expr $i + 1]
+	  if {[set id [lindex $var(idlist) $i]]} \
+	  {
+debug [list $canvas itemconfigure $treepath/$id:label -text $i]
+	    $canvas itemconfigure $treepath/$id:label -text $i
+	    if {![lindex $var(idlist) [expr $i - 1]]} \
+	    {
+debug [list $list tag add display $line.0 $line.end]
+	      $list tag add display $line.0 $line.end
+	    }
+	  } \
+	  else \
+	  {
+	    if {![lindex $var(idlist) [expr $i - 1]]} \
+	    {
+debug [list $list tag remove display $line.0 $line.end]
+	      $list tag remove display $line.0 $line.end
+	    }
+	  }
+	}
+	set line [expr $index + 1]
+debug [list $list tag remove display $line.0 $line.end]
+	$list tag remove display $line.0 $line.end
+      }
+      delete \
+      {
+	if {$index < $len} \
+	{
+debug [list delete $index]
+
+	  if {[set id [lindex $var(idlist) $index]]} \
+	  {
+	    # list_cleanup must be called before the snacc object is modified:
+	    list_cleanup $treepath/$id "$snaccpath $index"
+	    $tree rmlink $treepath/$id
+	  }
+	  incr len -1
+	  for {set i $index} {$i < $len} {incr i} \
+	  {
+	    set line [expr $i + 1]
+	    if {[set id [lindex $var(idlist) [expr $i + 1]]]} \
+	    {
+debug [list $canvas itemconfigure $treepath/$id:label -text $i]
+	      $canvas itemconfigure $treepath/$id:label -text $i
+	      if {![lindex $var(idlist) $i]} \
+	      {
+debug [list $list tag add display $line.0 $line.end]
+		$list tag add display $line.0 $line.end
+	      }
+	    } \
+	    else \
+	    {
+	      if {[lindex $var(idlist) $i]} \
+	      {
+debug [list $list tag remove display $line.0 $line.end]
+		$list tag remove display $line.0 $line.end
+	      }
+	    }
+	  }
+
+	  set var(idlist) [lreplace $var(idlist) $index $index]
+debug [list $var(idlist)]
+debug [list snacc unset "$snaccpath $index"]
+	  snacc unset "$snaccpath $index"
+	  set file(modified) 1
+debug [list [snacc get $snaccpath]]
+	  $list delete [$list index {end - 1 line}] [$list index end]
+	}
+      }
+    }
+    $tree draw
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc list_mode {canvas treepath} \
+{
+  set var var:$treepath
+  global $var
+  set mode [set ${var}(mode)]
+  set frame $canvas.edit$treepath
+  set list $frame.list
+
+  switch $mode \
+  {
+    display {set cursor arrow}
+    insert {set cursor based_arrow_up}
+    append {set cursor based_arrow_down}
+    delete {set cursor pirate}
+  }
+  $list config -cursor $cursor
+
+  debug [list list_mode: ${var}(mode) set to $mode]
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc toggle_bit {var i} \
+{
+  global $var:$i $var
+  set bit [set $var:$i]
+  set val [set $var]
+
+debug [list toggle_bit $val $i to $bit]
+
+  set pre [string range $val 0 [expr $i - 1]]
+
+  set fill {}
+  for {set l [string length $val]} {$l < $i} {incr l} \
+  {
+    append fill 0
+debug [list appending: $val]
+  }
+
+  set post [string range $val [expr $i + 1] end]
+
+debug [list toggle_bit combining $pre $fill $bit $post]
+  set $var $pre$fill$bit$post
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc change_bits {var element op} \
+{
+  global $var
+  set val [set $var]
+debug [list change_bits $var set to $val]
+
+debug [list set l [string length $val]]
+  set l [string length $val]
+  for {set i 0} {$i < $l} {incr i} \
+  {
+    global $var:$i
+    if {[info exists $var:$i]} \
+    {
+debug [list set $var:$i [string index $val $i]]
+      set $var:$i [string index $val $i]
+    } \
+    else \
+    {
+debug [list non-exist: $var:$i]
+    }
+  }
+
+  foreach bitvar [info globals $var:*] \
+  {
+    set i [lindex [split $bitvar :] 2]
+    if {$i >= $l} \
+    {
+      global $bitvar
+      set $bitvar 0
+    }
+  }
+
+  change_simple $var $element $op
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc change_simple {var element op} \
+{
+  global $var
+  set val [set $var]
+debug [list change_simple $var set to $val]
+
+  set treepath [lindex [split $var :] 1]
+debug [list treepath= $treepath]
+  set fileref [lindex [split $treepath /] 1]
+  upvar #0 $fileref file
+  set canvas $file(canvas)
+debug [list canvas= $canvas]
+  set snaccpath [tree2snacc $treepath]
+debug [list snaccpath= $snaccpath]
+  snacc set $snaccpath $val
+  set file(modified) 1
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc new_choice {canvas treepath} \
+{
+  set tree $canvas.t
+  set snaccpath [tree2snacc $treepath]
+
+  set var var:$treepath
+  set oldvar oldvar:$treepath
+  global $var $oldvar
+  set val [set $var]
+  set oldval [set $oldvar]
+
+  set fileref [lindex [split $treepath /] 1]
+  upvar #0 $fileref file
+
+debug "$file(modified)"
+  debug [list new choice: $snaccpath = $val]
+
+  # list_cleanup must be called before the snacc object is modified:
+  list_cleanup $treepath/$oldval "$snaccpath $oldval"
+
+  catch {snacc set $snaccpath [list $val {}]}
+  set file(modified) 1
+debug "$file(modified)"
+
+  if {[llength [$canvas find withtag "$treepath/$oldval"]]} \
+  {
+    $tree rmlink "$treepath/$oldval"
+    ed_expand $tree $treepath $snaccpath
+    $tree draw
+  }
+
+  set $oldvar $val
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc toggle_se* {canvas treepath name} \
+{
+  set tree $canvas.t
+  set snaccpath [tree2snacc $treepath]
+
+  set var var:$treepath:$name
+  global $var
+  set val [set $var]
+
+  set fileref [lindex [split $treepath /] 1]
+  upvar #0 $fileref file
+
+  debug "$snaccpath $name = $val"
+
+  # this procedure is called after the button value has changed, so adjust the display to the current (new) setting:
+  if {$val == {void}} \
+  {
+    # (change valid \(-> void)
+    # list_cleanup must be called before the snacc object is modified:
+    list_cleanup $treepath/$name "$snaccpath $name"
+    snacc unset "$snaccpath $name"
+  } \
+  else \
+  {
+    # (change void \(-> valid)
+    catch {snacc set "$snaccpath $name" {}}
+  }
+  set file(modified) 1
+
+  if {[llength [$canvas find withtag "$treepath/$name"]]} \
+  {
+debug [list rmlink "$treepath/$name"]
+    $tree rmlink "$treepath/$name"
+    # a bug in the tree widget requires us to redraw here:
+      $tree draw
+    ed_expand $tree $treepath $snaccpath
+    $tree draw
+  }
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+# add/drop parent and siblings
+proc set_or_add_root {canvas} \
+{
+  set tree $canvas.t
+  set id [$canvas find withtag current]
+  if {$id == {}} \
+  {
+    debug "no item"
+  } \
+  else \
+  {
+    set treepath [lindex [$canvas gettags $id] 1]
+    set snaccpath [tree2snacc $treepath]
+#    debug $path
+    if {[llength $snaccpath] == 1} \
+    {
+      debug "at root already"
+    } \
+    else \
+    {
+      if {[$tree isroot $treepath]} \
+      {
+	# show the parent:
+debug [list expanding [list $treepath $snaccpath]]
+	set i [llength $snaccpath]
+
+	incr i -1
+
+	set treeparentpath [join [lrange [split $treepath /] 0 $i] /]
+	set treeparentnode [lindex [split $treepath /] $i]
+	incr i -1
+	set snaccparentpath [lrange $snaccpath 0 $i]
+	set snaccparentnode [lindex $snaccpath $i]
+
+	set treeparentparentpath [join [lrange [split $treepath /] 0 $i] /]
+	incr i -1
+	set snaccparentparentpath [lrange $snaccpath 0 $i]
+
+#debug [list ed_addnode $tree {} $parentparentpath $parentnode valid]
+	ed_addnode $tree {} $treeparentparentpath $snaccparentparentpath $treeparentnode $snaccparentnode valid
+#debug [list ed_expand $tree $parentpath]
+	ed_expand $tree $treeparentpath $snaccparentpath
+      } \
+      else \
+      {
+	# hide everything above this subtree:
+#	debug "cutting $path"
+	list_cleanup_not_me $treepath $snaccpath
+	$tree root $treepath
+      }
+#      debug [snacc info $path]
+    }
+  }
+  $tree draw
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc file_open {} \
+{
+  if {[selbox fn ct nullfn]} \
+  {
+debug "fn=$fn ct=$ct"
+    if {$fn != {}} \
+    {
+      if {[catch {set f [snacc open $ct $fn create]} msg]} \
+      {
+	tk_dialog .d load "Couldn't open $fn {$ct}: $msg" warning 0 Dismiss
+	return -1
+      }
+    } \
+    else \
+    {
+      if {[catch {set f [snacc create $ct]} msg]} \
+      {
+	tk_dialog .d create "Couldn't create {$ct}: $msg" warning 0 Dismiss
+	return -1
+      }
+    }
+    new_file $f
+    return 0
+  }
+  return -1
+}
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+
+set #file 0
+set #files 0
+
+# returns 1 on `cancel', otherwise exits or returns 0
+proc close_file {fileref} \
+{
+  upvar #0 $fileref file
+
+  if {$file(modified)} \
+  {
+    set fi [snacc finfo $file(handle)]
+    set fn [lindex $fi 0]
+    set hasfn [expr {$fn != {}}]
+    set isrw [expr {[lindex $fi 1] == {rw}}]
+    set msg {There are unsaved changes}
+    if {$hasfn} \
+    {
+      append msg " in `$fn'"
+    }
+    append msg {. Save them?}
+    switch [lindex {save discard cancel} [tk_dialog .d modified $msg questhead 0 Yes No Cancel]] \
+    {
+      cancel \
+      {
+        return 1
+      }
+      save \
+      {
+	if {$hasfn && $isrw} \
+	{
+	  if {[file_save $fileref]} \
+	  {
+	    return 1
+	  }
+	} \
+	else \
+	{
+	  if {[file_save_as $fileref]} \
+	  {
+	    return 1
+	  }
+	}
+      }
+    }
+  }
+
+  destroy $file(toplevel)
+  global #files
+  if {![incr #files -1]} \
+  {
+    exit
+  }
+  return 0
+}
+
+proc file_quit {} \
+{
+  global #files
+  for {set i 0} {${#files}} {incr i} \
+  {
+    if {[winfo exists .[set fileref file$i]]} \
+    {
+      if {[close_file $fileref]} \
+      {
+	return
+      }
+    }
+  }
+}
+
+proc new_file {handle} \
+{
+  global #file
+
+  while {[winfo exists [set toplevel .[set fileref file${#file}]]]} \
+  {
+    incr #file
+  }
+
+  #global $fileref
+  upvar #0 $fileref file
+
+  set file(handle) $handle
+
+  set file(toplevel) [toplevel $toplevel]
+  wm title $toplevel snaccEd
+  wm minsize $toplevel 150 100
+  wm geometry $toplevel 500x500
+
+  global #files
+  incr #files
+
+  set file(modified) 0
+
+  $toplevel config -cursor arrow
+
+  set menubar $toplevel.menu
+  frame $menubar -relief raised -bd 2
+  pack $menubar -side top -fill x
+
+  set filem $menubar.file
+  set m $filem.m
+  menubutton $filem -text File -menu $m
+  menu $m
+  $m add command -label Reload -command [list file_reload $fileref]
+  $m add command -label Load... -command [list file_load_from $fileref]
+  $m add command -label Save -command [list file_save $fileref]
+  $m add command -label {Save As...} -command [list file_save_as $fileref]
+  $m add command -label Close -command [list close_file $fileref]
+  $m add separator
+  $m add command -label Open... -command file_open
+  $m add separator
+  $m add command -label Quit -command file_quit
+  set fi [snacc finfo $handle]
+  set hasnofn [expr {[lindex $fi 0] == {}}]
+  set isro [expr {[lindex $fi 1] == {ro}}]
+  if {$hasnofn} \
+  {
+    $m entryconfigure Reload -state disabled
+  }
+  if {$hasnofn || $isro} \
+  {
+    $m entryconfigure Save -state disabled
+  }
+  pack $filem -side left
+
+  set help $menubar.help
+  set m $help.m
+  menubutton $help -text Help -menu $help.m
+  menu $m
+  $m add command -label About -command "help [list $m] \$helptext(about)"
+  $m add command -label Manoeuvering -command "help [list $m] \$helptext(manoeuv)"
+  pack $help -side right
+
+  tk_menuBar $menubar $filem $help
+
+  frame $toplevel.f0
+  frame $toplevel.f1
+
+  pack $toplevel.f0 -expand true -fill both
+  pack $toplevel.f1 -fill x
+
+  set file(canvas) [set canvas [canvas $toplevel.c -width 0 -height 0]]
+
+  set hsb [scrollbar $toplevel.hsb -orient horiz -relief sunken -command [list $canvas xview]]
+  set vsb [scrollbar $toplevel.vsb -relief sunken -command [list $canvas yview]]
+
+  $canvas config -xscroll [list $hsb set] -yscroll [list $vsb set]
+
+  set blind [frame $toplevel.blind -width [lindex [$vsb config -width] 4]]
+
+  pack $vsb -in $toplevel.f0 -side right -fill y
+  pack $canvas -in $toplevel.f0 -side left -expand true -fill both
+
+  pack $blind -in $toplevel.f1 -side right
+  pack $hsb -in $toplevel.f1 -side left -expand true -fill x
+
+  bind $canvas <ButtonPress-2> [list $canvas scan mark %x %y]
+  bind $canvas <Button2-Motion> [list $canvas scan dragto %x %y]
+
+  $canvas bind valid-label <Button-1> {prune_or_add_children %W}
+  $canvas bind valid-label <Button-2> {toggle_editor %W}
+  $canvas bind valid-label <Button-3> {set_or_add_root %W}
+
+  set file(tree) [set tree [tree $canvas.t]]
+
+  ed_addnode $tree {} {} {} $handle $handle valid
+
+  $tree draw
+
+  tkwait visibility $toplevel
+}
+
+proc snacced {} \
+{
+  wm withdraw .
+
+  global argc argv
+
+  if {$argc == 0} \
+  {
+    if {[file_open]} \
+    {
+      exit 1
+    }
+  } \
+  else \
+  {
+    if {$argc == 3} \
+    {
+      set ct [lrange $argv 0 1]
+      set fn [lindex $argv 2]
+      if {[catch {set f [snacc open $ct $fn create]} msg]} \
+      {
+	tk_dialog .d load "Couldn't open $fn {$ct}: $msg" warning 0 Dismiss
+	exit 1
+      }
+    } \
+    elseif {$argc == 2} \
+    {
+      set ct [lrange $argv 0 1]
+      if {[catch {set f [snacc create $ct]} msg]} \
+      {
+	tk_dialog .d create "Couldn't create {$ct}: $msg" warning 0 Dismiss
+	exit 1
+      }
+    } \
+    else \
+    {
+      exit 1
+    }
+    new_file $f
+  }
+}
diff --git a/SecuritySNACCRuntime/tcl-lib/tkuti.tcl b/SecuritySNACCRuntime/tcl-lib/tkuti.tcl
new file mode 100644
index 00000000..952273f4
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-lib/tkuti.tcl
@@ -0,0 +1,21 @@
+# file: tkuti.tcl
+# miscellaneous Tk utilities.
+#
+# $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-lib/tkuti.tcl,v 1.1.1.1 2001/05/18 23:14:11 mb Exp $
+# $Log: tkuti.tcl,v $
+# Revision 1.1.1.1  2001/05/18 23:14:11  mb
+# Move from private repository to open source repository
+#
+# Revision 1.1.1.1  1999/03/16 18:06:56  aram
+# Originals from SMIME Free Library.
+#
+# Revision 1.1  1997/01/01 23:12:03  rj
+# first check-in
+#
+
+proc getpos {w xn yn} \
+{
+  upvar $xn x $yn y
+  set geom [wm geometry $w]
+  scan $geom {%dx%d+%d+%d} w h x y
+}
diff --git a/SecuritySNACCRuntime/tcl-lib/uti.tcl b/SecuritySNACCRuntime/tcl-lib/uti.tcl
new file mode 100644
index 00000000..8f7c3fff
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-lib/uti.tcl
@@ -0,0 +1,15 @@
+# file: uti.tcl
+
+#\[sep]-----------------------------------------------------------------------------------------------------------------------------
+proc max {a0 args} \
+{
+  set max $a0
+  foreach a $args \
+  {
+    if {$a > $max} \
+    {
+      set max $a
+    }
+  }
+  return $max
+}
diff --git a/SecuritySNACCRuntime/tcl-p.c b/SecuritySNACCRuntime/tcl-p.c
new file mode 100644
index 00000000..3376bf4f
--- /dev/null
+++ b/SecuritySNACCRuntime/tcl-p.c
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * file: tcl-p.c
+ * purpose: check and return via exit code whether the tcl interface needs to be made
+ *
+ * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/tcl-p.c,v 1.1.1.1 2001/05/18 23:14:05 mb Exp $
+ * $Log: tcl-p.c,v $
+ * Revision 1.1.1.1  2001/05/18 23:14:05  mb
+ * Move from private repository to open source repository
+ *
+ * Revision 1.2  2001/05/05 00:59:16  rmurphy
+ * Adding darwin license headers
+ *
+ * Revision 1.1.1.1  1999/03/16 18:05:50  aram
+ * Originals from SMIME Free Library.
+ *
+ * Revision 1.1  1995/07/25 22:24:48  rj
+ * new file
+ *
+ */
+
+#define COMPILER	1
+
+#include "snacc.h"
+
+main()
+{
+#if TCL
+  return 0;
+#else
+  return 1;
+#endif
+}
diff --git a/SecuritySNACCRuntime/version.h b/SecuritySNACCRuntime/version.h
new file mode 100644
index 00000000..bd268d26
--- /dev/null
+++ b/SecuritySNACCRuntime/version.h
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+
+#define VERSION		"1.3"
+#define RELDATE		"1997-10-20"
+#define BUGREPADDR	"snacc@cs.ubc.ca"
diff --git a/SecurityServer/AZNTest.cpp b/SecurityServer/AZNTest.cpp
new file mode 100644
index 00000000..a9c263bb
--- /dev/null
+++ b/SecurityServer/AZNTest.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  AZNTest.cpp
+ *  SecurityServer
+ *
+ *  Created by michael on Fri Oct 20 2000.
+ *  Copyright (c) 2000 Apple Computer Inc. All rights reserved.
+ *
+ */
+
+#include <Security/Authorization.h>
+
+#include <Security/AuthorizationEngine.h>
+
+using namespace Authorization;
+
+static const AuthorizationItem gItems[] =
+{
+	{"login", 0, NULL, NULL},
+	{"reboot", 0, NULL, NULL},
+	{"shutdown", 0, NULL, NULL},
+	{"mount", 0, NULL, NULL},
+	{"login.reboot", 0, NULL, NULL},
+	{"login.shutdown", 0, NULL, NULL},
+	{"unmount", 0, NULL, NULL}
+};
+
+static const AuthorizationRights gRights =
+{
+	7,
+	const_cast<AuthorizationItem *>(gItems)
+};
+
+void
+printRights(const RightSet &rightSet)
+{
+	for(RightSet::const_iterator it = rightSet.begin(); it != rightSet.end(); ++it)
+	{
+		printf("right: \"%s\"\n", it->rightName());
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	Engine engine("/tmp/config.plist");
+
+	const RightSet inputRights(&gRights);
+	MutableRightSet outputRights;
+	printf("InputRights:\n");
+	printRights(inputRights);
+	printf("Authorizing:\n");
+	OSStatus result = engine.authorize(inputRights, NULL,
+		kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights | kAuthorizationFlagPartialRights,
+		NULL, NULL, &outputRights);
+	printf("Result: %ld\n", result);
+	printf("OutputRights:\n");
+	printRights(outputRights);
+	return 0;
+}
diff --git a/SecurityServer/Authorization/AuthSession.h b/SecurityServer/Authorization/AuthSession.h
new file mode 100644
index 00000000..38f74a52
--- /dev/null
+++ b/SecurityServer/Authorization/AuthSession.h
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  AuthSession.h
+ *  AuthSession - APIs for managing login, authorization, and security Sessions.
+ */
+#if !defined(__AuthSession__)
+#define __AuthSession__ 1
+
+#include <Security/Authorization.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/*!
+	@header AuthSession
+
+	The Session API provides specialized applications access to Session management and inquiry
+    functions. This is a specialized API that should not be of interest to most people.
+    
+    If you do not know what "Session" means in the context of MacOS Authorization and security,
+    please check with your documentation and come back when you have figured it out - we won't
+    explain it here.
+    
+    This API is tentative, preliminary, incomplete, internal, and subject to change.
+    You have been warned.
+*/
+
+
+/*!
+	@typedef SecuritySessionId
+	These are externally visible identifiers for authorization sessions.
+        Different sessions have different identifiers; beyond that, you can't
+        tell anything from these values.
+    SessionIds can be compared for equality as you'd expect, but you should be careful
+        to use attribute bits wherever appropriate. For example, don't rely on there being
+        "the" graphical login session - some day, we may have more than one...
+*/
+typedef UInt32 SecuritySessionId;
+
+
+/*!
+    @enum SecuritySessionId
+    Here are some special values for SecuritySessionId. You may specify those
+        on input to SessionAPI functions. They will never be returned from such
+        functions.
+*/
+enum {
+    noSecuritySession                      = 0,     /* definitely not a valid SecuritySessionId */
+    callerSecuritySession                  = -1     /* the Session I (the caller) am in */
+};
+
+
+/*!
+    @enum SessionAttributeBits
+    Each Session has a set of attribute bits. You can get those from the
+        SessionGetInfo API function.
+ */
+typedef UInt32 SessionAttributeBits;
+ 
+enum {
+    sessionIsRoot                          = 0x0001, /* is the root session (startup/system programs) */
+    sessionHasGraphicAccess                = 0x0010, /* graphic subsystem (CoreGraphics et al) available */
+    sessionHasTTY                          = 0x0020, /* /dev/tty is available */
+    sessionIsRemote                        = 0x1000, /* session was established over the network */
+
+    sessionWasInitialized                  = 0x8000  /* session has been set up by its leader */
+};
+
+
+/*!
+    @enum SessionCreationFlags
+    These flags control how a new session is created by SessionCreate.
+        They have no permanent meaning beyond that.
+ */
+typedef UInt32 SessionCreationFlags;
+ 
+enum {
+    sessionKeepCurrentBootstrap             = 0x8000 /* caller has allocated sub-bootstrap (expert use only) */
+};
+ 
+ 
+/*!
+	@enum SessionStatus
+	Error codes returned by AuthSession API.
+    Note that the AuthSession APIs can also return Authorization API error codes.
+*/
+enum {
+    errSessionSuccess                       = 0,      /* all is well */
+    errSessionInvalidId                     = -60500, /* invalid session id specified */
+    errSessionInvalidAttributes             = -60501, /* invalid set of requested attribute bits */
+    errSessionAuthorizationDenied           = -60502, /* you are not allowed to do this */
+
+    errSessionInternal                      = errAuthorizationInternal,	/* internal error */
+	errSessionInvalidFlags                  = errAuthorizationInvalidFlags /* invalid flags/options */
+};
+
+
+/*!
+    @function SessionGetInfo
+    Obtain information about a session.
+
+    @param session (input) The Session you are asking about. Can be one of the
+        special constants defined above.
+	
+	@param sessionId (output/optional) The actual SecuritySessionId for the session you asked about.
+        Will never be one of those constants.
+        
+    @param attributes (output/optional) Receives the attribute bits for the session.
+
+    @result An OSStatus indicating success (noErr) or an error cause.
+    
+    errSessionInvalidId -60500 Invalid session id specified
+
+*/
+OSStatus SessionGetInfo(SecuritySessionId session,
+    SecuritySessionId *sessionId,
+    SessionAttributeBits *attributes);
+    
+
+/*!
+    @function SessionCreate
+    This (very specialized) function creates and/or initializes a security session.
+        It always sets up the session that the calling process belongs to - you cannot
+        create a session for someone else.
+    By default, a new bootstrap subset port is created for the calling process. The process
+        acquires this new port as its bootstrap port, which all its children will inherit.
+        If you happen to have created the subset port on your own, you can pass the
+        sessionKeepCurrentBootstrap flag, and SessionCreate will use it. Note however that
+        you cannot supersede a prior SessionCreate call that way; only a single SessionCreate
+        call is allowed for each Session (however made).
+    
+    @param flags Flags controlling how the session is created.
+    
+    @param attributes The set of attribute bits to set for the new session.
+        Not all bits can be set this way.
+    
+    @result An OSStatus indicating success (noErr) or an error cause.
+    
+    errSessionInvalidAttributes -60501 Attempt to set invalid attribute bits	
+    errSessionAuthorizationDenied -60502 Attempt to re-initialize a session
+    errSessionInvalidFlags -60011 Attempt to specify unsupported flag bits
+    
+*/
+OSStatus SessionCreate(SessionCreationFlags flags,
+    SessionAttributeBits attributes);
+    
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* ! __AuthSession__ */
diff --git a/SecurityServer/Authorization/Authorization.cpp b/SecurityServer/Authorization/Authorization.cpp
new file mode 100644
index 00000000..d20612c4
--- /dev/null
+++ b/SecurityServer/Authorization/Authorization.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+
+//
+// Authorization.cpp
+//
+// This file is the unified implementation of the Authorization and AuthSession APIs.
+//
+#include <Security/Authorization.h>
+#include <Security/AuthSession.h>
+#include "AuthorizationWalkers.h"
+#include <Security/mach++.h>
+#include <Security/globalizer.h>
+#include <Security/cssmalloc.h>
+#include <Security/ssclient.h>
+
+using namespace SecurityServer;
+using namespace MachPlusPlus;
+
+
+//
+// Shared cached client object
+//
+class AuthClient : public SecurityServer::ClientSession {
+public:
+	AuthClient()
+	: SecurityServer::ClientSession(CssmAllocator::standard(), CssmAllocator::standard())
+	{ }
+};
+
+static ModuleNexus<AuthClient> server;
+
+
+//
+// Create an Authorization
+//
+OSStatus AuthorizationCreate(const AuthorizationRights *rights,
+	const AuthorizationEnvironment *environment,
+	AuthorizationFlags flags,
+	AuthorizationRef *authorization)
+{
+	BEGIN_API
+	AuthorizationBlob result;
+	server().authCreate(rights, environment, flags, result);
+	if (authorization)
+	{
+		*authorization = 
+			(AuthorizationRef) new(server().returnAllocator) AuthorizationBlob(result);
+	}
+	else
+	{
+		// If no authorizationRef is desired free the one we just created.
+		server().authRelease(result, flags);
+	}
+	END_API(CSSM)
+}
+
+
+//
+// Free an authorization reference
+//
+OSStatus AuthorizationFree(AuthorizationRef authorization, AuthorizationFlags flags)
+{
+	BEGIN_API
+	AuthorizationBlob *auth = (AuthorizationBlob *)authorization;
+	server().authRelease(Required(auth), flags);
+	server().returnAllocator.free(auth);
+	END_API(CSSM)
+}
+
+
+//
+// Augment and/or interrogate an authorization
+//
+OSStatus AuthorizationCopyRights(AuthorizationRef authorization,
+	const AuthorizationRights *rights,
+	const AuthorizationEnvironment *environment,
+	AuthorizationFlags flags,
+	AuthorizationRights **authorizedRights)
+{
+	BEGIN_API
+	AuthorizationBlob *auth = (AuthorizationBlob *)authorization;
+	server().authCopyRights(Required(auth), rights, environment, flags, authorizedRights);
+	END_API(CSSM)
+}
+
+
+//
+// Retrieve side-band information from an authorization
+//
+OSStatus AuthorizationCopyInfo(AuthorizationRef authorization, 
+	AuthorizationString tag,
+	AuthorizationItemSet **info)
+{
+	BEGIN_API
+	AuthorizationBlob *auth = (AuthorizationBlob *)authorization;
+	server().authCopyInfo(Required(auth), tag, Required(info));
+	END_API(CSSM)
+}
+
+
+//
+// Externalize and internalize authorizations
+//
+OSStatus AuthorizationMakeExternalForm(AuthorizationRef authorization,
+	AuthorizationExternalForm *extForm)
+{
+	BEGIN_API
+	AuthorizationBlob *auth = (AuthorizationBlob *)authorization;
+	server().authExternalize(Required(auth), *extForm);
+	END_API(CSSM)
+}
+
+OSStatus AuthorizationCreateFromExternalForm(const AuthorizationExternalForm *extForm,
+	AuthorizationRef *authorization)
+{
+	BEGIN_API
+	AuthorizationBlob result;
+	server().authInternalize(*extForm, result);
+	Required(authorization) = 
+		(AuthorizationRef) new(server().returnAllocator) AuthorizationBlob(result);
+	END_API(CSSM)
+}
+
+
+//
+// Free an ItemSet structure returned from an API call. This is a local operation.
+// Since we allocate returned ItemSets as compact blobs, this is just a simple
+// free() call.
+//
+OSStatus AuthorizationFreeItemSet(AuthorizationItemSet *set)
+{
+	BEGIN_API
+	server().returnAllocator.free(set);
+	return errAuthorizationSuccess;
+	END_API(CSSM)
+}
+
+
+//
+// Get session information
+//
+OSStatus SessionGetInfo(SecuritySessionId session,
+    SecuritySessionId *sessionId,
+    SessionAttributeBits *attributes)
+{
+    BEGIN_API
+    SecuritySessionId sid = session;
+    server().getSessionInfo(sid, *attributes);
+    if (sessionId)
+        *sessionId = sid;
+    END_API(CSSM)
+}
+
+
+//
+// Create a new session
+//
+OSStatus SessionCreate(SessionCreationFlags flags,
+    SessionAttributeBits attributes)
+{
+    BEGIN_API
+
+    // just to be on the safe side, drop any cached connection to the SecurityServer
+    server.reset();
+    
+    // unless the (expert) caller has already done so, create a sub-bootstrap and set it
+    // note that this is inherently thread-unfriendly; we can't do anything about that
+    // (caller's responsibility)
+    Bootstrap bootstrap;
+    if (!(flags & sessionKeepCurrentBootstrap)) {
+        TaskPort self;
+        bootstrap = bootstrap.subset(self);
+        self.bootstrap(bootstrap);
+    }
+    
+    // now call the SecurityServer and tell it to initialize the (new) session
+    server().setupSession(flags, attributes);
+
+    END_API(CSSM)
+}
diff --git a/SecurityServer/Authorization/Authorization.h b/SecurityServer/Authorization/Authorization.h
new file mode 100644
index 00000000..c8e23abc
--- /dev/null
+++ b/SecurityServer/Authorization/Authorization.h
@@ -0,0 +1,408 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  Authorization.h
+ *  Authorization -- APIs for implementing access control in applications and daemons.
+ *
+ *    Copyright (C) 2000, 2001 by Apple Computer, Inc., all rights reserved
+ *
+ */
+
+#if !defined(__Authorization__)
+#define __Authorization__ 1
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#include <stdio.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/*!
+	@header Authorization
+	Version 1.0 10/16/2000
+
+	The Authorization API contains all the APIs that a application or tool that need pre-authorization or need an authorization desision made.
+	
+	A typical use cases are a preference panel that would start off calling AuthorizationCreate() (without UI) to get an authorization object.  Then call AuthorizationCopyRights() to figure out what is currently allowed.
+	
+	If any of the operations that the preference panel wishes to perform are currently not allowed the lock icon in the window would show up in the locked state.  Otherwise it would show up unlocked.
+	
+	When the user locks the lock AuthorizationFree() is called with the kAuthorizationFreeFlagDestroy to destroy any authorization rights that have been aquired.
+	
+	When the user unlocks the lock AuthorizationCreate() is called with the kAuthorizationFlagInteractionAllowed and kAuthorizationFlagExtendRights flags to obtain all required rights.  The old authorization object can be freed by calling AuthorizationFree() with no flags.
+
+*/
+
+
+
+/*!
+	@define kAuthorizationEmptyEnvironment
+	Parameter to specify to AuthorizationCreate when no environment is being provided.
+*/
+#define kAuthorizationEmptyEnvironment	NULL
+
+
+/*!
+	@enum AuthorizationStatus
+	Error codes returned by Authorization API.
+*/
+enum {
+	errAuthorizationSuccess					= 0,      /* The operation completed successfully. */
+    errAuthorizationInvalidSet				= -60001, /* The set parameter is invalid. */
+    errAuthorizationInvalidRef				= -60002, /* The authorization parameter is invalid. */
+    errAuthorizationInvalidTag				= -60003, /* The tag parameter is invalid. */
+    errAuthorizationInvalidPointer			= -60004, /* The authorizedRights parameter is invalid. */
+	errAuthorizationDenied					= -60005, /* The authorization was denied. */
+	errAuthorizationCanceled				= -60006, /* The authorization was cancled by the user. */
+	errAuthorizationInteractionNotAllowed	= -60007, /* The authorization was denied since no user interaction was possible. */
+	errAuthorizationInternal                = -60008, /* something else went wrong */
+	errAuthorizationExternalizeNotAllowed	= -60009, /* authorization externalization denied */
+	errAuthorizationInternalizeNotAllowed	= -60010, /* authorization internalization denied */
+	errAuthorizationInvalidFlags            = -60011, /* invalid option flag(s) */
+	errAuthorizationToolExecuteFailure      = -60031, /* cannot execute privileged tool */
+	errAuthorizationToolEnvironmentError    = -60032  /* privileged tool environment error */
+};
+
+
+/*!
+	@enum AuthorizationFlags
+	Optional flags passed in to serveral Authorization APIs. See the description of AuthorizationCreate, AuthorizationCopyRights and AuthorizationFree for a description of how they affect those calls.
+*/
+enum {
+	kAuthorizationFlagDefaults              = 0,
+	kAuthorizationFlagInteractionAllowed	= (1 << 0),
+	kAuthorizationFlagExtendRights			= (1 << 1),
+	kAuthorizationFlagPartialRights			= (1 << 2),
+	kAuthorizationFlagDestroyRights			= (1 << 3),
+	kAuthorizationFlagPreAuthorize			= (1 << 4),
+	
+	// private bits (do not use)
+	kAuthorizationFlagNoData                = (1 << 20)
+};
+
+
+/*!
+	@typedef AuthorizationFlags
+	Optional flags passed in to AuthorizationCreate.
+*/
+typedef UInt32 AuthorizationFlags;
+
+
+/*!
+	@enum AuthorizationRightFlags
+	Flags returned in the flags field of ItemSet Items when calling AuthorizationCopyRights().
+*/
+enum {
+	kAuthorizationFlagCanNotPreAuthorize	= (1 << 0)
+};
+
+
+/*!
+	@typedef AuthorizationRef
+	Opaque reference to an authorization object.
+*/
+typedef const struct AuthorizationOpaqueRef			*AuthorizationRef;
+
+
+/*!
+	@typedef AuthorizationString
+	A zero terminated string in UTF-8 encoding.
+*/
+typedef const char *AuthorizationString;
+
+
+/*!
+	@typedef AuthorizationItem
+	Each AuthorizationItem describes a single string-named item with optional
+	parameter value. The value must be contiguous memory of valueLength bytes;
+	internal structure is defined separately for each name.
+
+	@param name name of the item, as an AuthorizationString. Mandatory.
+	@param value Pointer to the optional parameter value associated with name.
+	Must be NULL if no parameter value.
+	@param valueLength Number of bytes in parameter value. Must be zero if no parameter.
+	@param reserved Reserved field. Must be set to NULL on creation. Do not modify after that.
+*/
+typedef struct {
+	AuthorizationString name;
+	UInt32 valueLength;
+	void *value;
+	UInt32 flags;
+} AuthorizationItem;
+
+
+/*!
+	@typedef AuthorizationItemSet
+	An AuthorizationItemSet structure represents a set of zero or more AuthorizationItems.  Since it is a set it should not contain any identical AuthorizationItems.
+
+	@param count Number of items identified by items.
+	@param items Pointer to an array of items.
+*/
+typedef struct {
+	UInt32 count;
+	AuthorizationItem *items;
+} AuthorizationItemSet;
+
+
+
+/*!
+	@typedef AuthorizationExternalForm
+	An AuthorizationExternalForm structure can hold the externalized form of
+	an AuthorizationRef. As such, it can be transmitted across IPC channels
+	to other processes, which can re-internalize it to recover a valid AuthorizationRef
+	handle.
+	The data contained in an AuthorizationExternalForm should be considered opaque.
+
+	SECURITY NOTE: Applications should take care to not disclose the AuthorizationExternalForm to
+	potential attackers since it would authorize rights to them.
+*/
+enum {
+	kAuthorizationExternalFormLength = 32
+};
+
+typedef struct {
+	char bytes[kAuthorizationExternalFormLength];
+} AuthorizationExternalForm;
+
+
+
+/*!
+	@typedef AuthorizationRights
+	An AuthorizationItemSet representing a set of rights each with an associated argument (value).
+	Each argument value is as defined for the specific right they belong to.  Argument values may not contain pointers as the should be copyable to different address spaces.
+*/
+typedef AuthorizationItemSet AuthorizationRights;
+
+
+/*!
+	@typedef AuthorizationEnvironment
+	An AuthorizationItemSet representing environmental information of potential use
+	to authorization decisions.
+*/
+typedef AuthorizationItemSet AuthorizationEnvironment;
+
+
+/*!
+    @function AuthorizationCreate
+    Create a new autorization object which can be used in other authorization calls.  When the authorization is no longer needed AuthorizationFree should be called.
+
+	When the kAuthorizationFlagInteractionAllowed flag is set, user interaction will happen when required.  Failing to set this flag will result in this call failing with a errAuthorizationInteractionNotAllowed status when interaction is required.
+
+	Setting the kAuthorizationFlagExtendRights flag will extend the currently available rights. If this flag is set the returned AuthorizationRef will grant all the rights requested when errAuthorizationSuccess is returned. If this flag is not set the operation will almost certainly succeed, but no attempt will be made to make the requested rights availible.
+		Call AuthorizationCopyRights to figure out which of the requested rights are granted by the returned AuthorizationRef.
+
+	Setting the kAuthorizationFlagPartialRights flag will cause this call to succeed if only some of the requested rights are being granted by the returned AuthorizationRef. Unless this flag is set this API will fail if not all the requested rights could be obtained.
+
+	Setting the kAuthorizationFlagDestroyRights flag will prevent any rights obtained during this call from being preserved after returning from this API (This is most useful when the authorization parameter is NULL and the caller doesn't want to affect the session state in any way).
+
+	Setting the kAuthorizationFlagPreAuthorize flag will pre authorize the requested rights so that at a later time -- by calling AuthorizationMakeExternalForm() follow by AuthorizationCreateFromExternalForm() -- the obtained rights can be used in a different process.  Rights that can't be preauthorized will be treated as if they were authorized for the sake of returning an error (in other words if all rights are either authorized or could not be preauthorized this call will still succeed).
+		The rights which could not be preauthorized are not currently authorized and may fail to authorize when a later call to AuthorizationCopyRights() is made, unless the kAuthorizationFlagExtendRights and kAuthorizationFlagInteractionAllowed flags are set.  Even then they might still fail if the user does not supply the correct credentials.
+		The reason for passing in this flag is to provide correct audit trail information and to avoid unnecessary user interaction.
+
+    @param rights (input/optional) An AuthorizationItemSet containing rights for which authorization is being requested.  If none are specified the resulting AuthorizationRef will authorize nothing at all.
+    @param environment (input/optional) An AuthorizationItemSet containing enviroment state used when making the autorization decision.  See the AuthorizationEnvironment type for details.
+    @param flags (input) options specified by the AuthorizationFlags enum.  set all unused bits to zero to allow for future expansion.
+    @param authorization (output optional) A pointer to an AuthorizationRef to be returned.  When the returned AuthorizationRef is no longer needed AuthorizationFree should be called to prevent anyone from using the aquired rights.  If NULL is specified no new rights are returned, but the system will attempt to authorize all the requested rights and return the appropriate status.
+
+    @result errAuthorizationSuccess 0 authorization or all requested rights succeeded.
+
+	errAuthorizationDenied -60005 The authorization for one or more of the requested rights was denied.
+
+	errAuthorizationCanceled -60006 The authorization was cancled by the user.
+
+	errAuthorizationInteractionNotAllowed -60007 The authorization was denied since no interaction with the user was allowed.
+*/
+OSStatus AuthorizationCreate(const AuthorizationRights *rights,
+	const AuthorizationEnvironment *environment,
+	AuthorizationFlags flags,
+	AuthorizationRef *authorization);
+
+
+/*!
+    @function AuthorizationFree
+    Destroy an AutorizationRef object. If the kAuthorizationFreeFlagDestroy flag is passed,
+	any rights associated with the authorization are lost. Otherwise, only local resources
+	are released, and the rights may still be available to other clients.
+
+	Setting the kAuthorizationFlagDestroyRights flag will prevent any rights that were obtained by the specified authorization object to be preserved after returning from this API.  This effectivaly locks down all potentially shared authorizations.
+
+    @param authorization (input) The authorization object on which this operation is performed.
+	
+	@param flags (input) Bit mask of option flags to this call.
+
+    @result errAuthorizationSuccess 0 No error.
+
+    errAuthorizationInvalidRef -60002 The authorization parameter is invalid.
+*/
+OSStatus AuthorizationFree(AuthorizationRef authorization, AuthorizationFlags flags);
+
+
+/*!
+	@function AuthorizationCopyRights
+    Given a set of rights, return the subset that is currently authorized
+    by the AuthorizationRef given.
+
+	When the kAuthorizationFlagInteractionAllowed flag is set, user interaction will happen when required.  Failing to set this flag will result in this call failing with a errAuthorizationInteractionNotAllowed status when interaction is required.
+
+	Setting the kAuthorizationFlagExtendRights flag will extend the currently available rights.
+
+	Setting the kAuthorizationFlagPartialRights flag will cause this call to succeed if only some of the requested rights are being granted by the returned AuthorizationRef.  Unless this flag is set this API will fail if not all the requested rights could be obtained.
+
+	Setting the kAuthorizationFlagDestroyRights flag will prevent any additional rights obtained during this call from being preserved after returning from this API.
+
+	Setting the kAuthorizationFlagPreAuthorize flag will pre authorize the requested rights so that at a later time -- by calling AuthorizationMakeExternalForm() follow by AuthorizationCreateFromExternalForm() -- the obtained rights can be used in a different process.  Rights that can't be preauthorized will be treated as if they were authorized for the sake of returning an error (in other words if all rights are either authorized or could not be preauthorized this call will still succeed), and they will be returned in authorizedRights with their kAuthorizationFlagCanNotPreAuthorize bit in the flags field set to 1.
+		The rights which could not be preauthorized are not currently authorized and may fail to authorize when a later call to AuthorizationCopyRights() is made, unless the kAuthorizationFlagExtendRights and kAuthorizationFlagInteractionAllowed flags are set.  Even then they might still fail if the user does not supply the correct credentials.
+		The reason for passing in this flag is to provide correct audit trail information and to avoid unnecessary user interaction.
+
+	Setting the kAuthorizationFlagPreAuthorize flag will pre authorize the requested rights so that at a later time -- by calling AuthorizationMakeExternalForm() follow by AuthorizationCreateFromExternalForm() -- the obtained rights can be used in a different process.  When this flags is specified rights that can't be preauthorized will be returned as if they were authorized with their kAuthorizationFlagCanNotPreAuthorize bit in the flags field set to 1.  These rights are not currently authorized and may fail to authorize later unless kAuthorizationFlagExtendRights and kAuthorizationFlagInteractionAllowed flags are set when the actual authorization is done.  And even then they might still fail if the user does not supply the correct credentials.
+
+    @param authorization (input) The authorization object on which this operation is performed.
+    @param rights (input) A rights set (see AuthorizationCreate).
+    @param environment (input/optional) An AuthorizationItemSet containing enviroment state used when making the autorization decision.  See the AuthorizationEnvironment type for details.
+    @param flags (input) options specified by the AuthorizationFlags enum.  set all unused bits to zero to allow for future expansion.
+    @param authorizedRights (output/optional) A pointer to a newly allocated AuthorizationInfoSet in which the authorized subset of rights are returned (authorizedRights should be deallocated by calling AuthorizationFreeInfoSet() when it is no longer needed).  If NULL the only information returned is the status.  Note that if the kAuthorizationFlagPreAuthorize flag was specified rights that could not be preauthorized are returned in authorizedRights, but their flags contains the kAuthorizationFlagCanNotPreAuthorize bit.
+
+    @result errAuthorizationSuccess 0 No error.
+
+	errAuthorizationInvalidRef -60002 The authorization parameter is invalid.
+
+    errAuthorizationInvalidSet -60001 The rights parameter is invalid.
+
+    errAuthorizationInvalidPointer -60004 The authorizedRights parameter is invalid.
+*/
+OSStatus AuthorizationCopyRights(AuthorizationRef authorization, 
+	const AuthorizationRights *rights,
+	const AuthorizationEnvironment *environment,
+	AuthorizationFlags flags,
+	AuthorizationRights **authorizedRights);
+
+
+/*!
+	@function AuthorizationCopyInfo
+	Returns sideband information (e.g. access credentials) obtained from a call to AuthorizationCreate.  The format of this data depends of the tag specified.
+	
+    @param authorization (input) The authorization object on which this operation is performed.
+    @param tag (input/optional) An optional string tag specifing which sideband information should be returned.  When NULL is specified all available information is returned.
+    @param flags (input) options specified by the AuthorizationFlags enum.  set all unused bits to zero to allow for future expansion.
+    @param info (output) A pointer to a newly allocated AuthorizationInfoSet in which the requested sideband infomation is returned (info should be deallocated by calling AuthorizationFreeInfoSet() when it is no longer needed).
+
+    @result errAuthorizationSuccess 0 No error.
+
+    errAuthorizationInvalidRef -60002 The authorization parameter is invalid.
+
+    errAuthorizationInvalidTag -60003 The tag parameter is invalid.
+
+    errAuthorizationInvalidPointer -60004 The info parameter is invalid.
+*/
+OSStatus AuthorizationCopyInfo(AuthorizationRef authorization, 
+	AuthorizationString tag,
+	AuthorizationItemSet **info);
+
+
+/*!
+	@function AuthorizationMakeExternalForm
+	Turn an Authorization into an external "byte blob" form so it can be
+	transmitted to another process.
+	Note that *storing* the external form somewhere will probably not do what
+	you want, since authorizations are bounded by sessions, processes, and possibly
+	time limits. This is for online transmission of authorizations.
+	
+	@param authorization The (valid) authorization reference to externalize
+	@param extForm Pointer to an AuthorizationExternalForm variable to fill.
+	
+	@result TBD
+*/
+OSStatus AuthorizationMakeExternalForm(AuthorizationRef authorization,
+	AuthorizationExternalForm *extForm);
+
+
+/*!
+	@function AuthorizationCreateFromExternalForm
+	Turn an Authorization into an external "byte blob" form so it can be
+	transmitted to another process.
+	Note that *storing* the external form somewhere will probably not do what
+	you want, since authorizations are bounded by sessions, processes, and possibly
+	time limits. This is for online transmission of authorizations.
+	
+	@param extForm Pointer to an AuthorizationExternalForm value.
+	@param authorization Will be filled with a valid AuthorizationRef on success.
+	
+	@result TBD
+*/
+OSStatus AuthorizationCreateFromExternalForm(const AuthorizationExternalForm *extForm,
+	AuthorizationRef *authorization);
+
+
+/*!
+	@function AuthorizationFreeItemSet
+	Release the memory allocated for an AuthorizationItemSet that was allocated
+	by an API call.
+	
+    @param set The AuthorizationItemSet to deallocate.
+
+    @result errAuthorizationSuccess 0 No error.
+
+    errAuthorizationInvalidSet -60001 The set parameter is invalid.
+*/
+OSStatus AuthorizationFreeItemSet(AuthorizationItemSet *set);
+
+
+/*!
+	@function AuthorizationExecuteWithPrivileges
+	Run an executable tool with enhanced privileges after passing
+	suitable authorization procedures.
+	
+	@param authorization An authorization reference that is used to authorize
+	access to the enhanced privileges. It is also passed to the tool for
+	further access control.
+	@param pathToTool Full pathname to the tool that should be executed
+	with enhanced privileges.
+	@param options Option bits (reserved). Must be zero.
+	@param arguments An argv-style vector of strings to be passed to the tool.
+	@param communicationsPipe Assigned a UNIX stdio FILE pointer for
+	a bidirectional pipe to communicate with the tool. The tool will have
+	this pipe as its standard I/O channels (stdin/stdout). If NULL, do not
+	establish a communications pipe.
+ */
+OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
+	const char *pathToTool,
+	AuthorizationFlags options,
+	char * const *arguments,
+	FILE **communicationsPipe);
+
+
+/*!
+	@function AuthorizationCopyPrivilegedReference
+	From within a tool launched via the AuthorizationExecuteWithPrivileges function
+	ONLY, retrieve the AuthorizationRef originally passed to that function.
+	While AuthorizationExecuteWithPrivileges already verified the authorization to
+	launch your tool, the tool may want to avail itself of any additional pre-authorizations
+	the caller may have obtained through that reference.
+ */
+OSStatus AuthorizationCopyPrivilegedReference(AuthorizationRef *authorization,
+	AuthorizationFlags flags);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* ! __Authorization__ */
diff --git a/SecurityServer/Authorization/AuthorizationEngine.cpp b/SecurityServer/Authorization/AuthorizationEngine.cpp
new file mode 100644
index 00000000..ad158fff
--- /dev/null
+++ b/SecurityServer/Authorization/AuthorizationEngine.cpp
@@ -0,0 +1,1076 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  AuthorizationEngine.cpp
+ *  Authorization
+ *
+ *  Created by Michael Brouwer on Thu Oct 12 2000.
+ *  Copyright (c) 2000 Apple Computer Inc. All rights reserved.
+ *
+ */
+
+#include "AuthorizationEngine.h"
+
+#include "server.h"
+#include "authority.h"
+
+#include <Security/AuthorizationTags.h>
+#include <Security/logging.h>
+#include <Security/debugging.h>
+
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFPropertyList.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <float.h>
+#include <unistd.h>
+#include <grp.h>
+#include <pwd.h>
+
+// for longname lookup
+#include <netinfo/ni.h>
+// private header (lu_utils.h from lookup project)
+extern "C" {
+int lookupd_query(ni_proplist *l, ni_proplist ***out);
+ni_proplist *lookupd_make_query(char *cat, char *fmt, ...);
+int _lu_running(void);
+}
+
+using namespace Authorization;
+
+//
+// Errors to be thrown
+//
+Error::Error(int err) : error(err)
+{
+}
+
+const char *Error::what() const
+{ return "Authorization error"; }
+
+CSSM_RETURN Error::cssmError() const
+{ return error; }	// @@@ eventually...
+
+OSStatus Error::osStatus() const
+{ return error; }
+
+void Error::throwMe(int err) { throw Error(err); }
+
+
+//
+// CredentialImpl class
+//
+
+// only for testing whether this credential is usable
+CredentialImpl::CredentialImpl(const string &username, const uid_t uid, const gid_t gid, bool shared) :
+mUsername(username), mShared(shared), mUid(uid), mGid(gid), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true)
+{
+}
+
+// credential with validity based on username/password combination.
+CredentialImpl::CredentialImpl(const string &username, const string &password, bool shared) :
+mShared(shared), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false)
+{
+	// try short name first
+	const char *user = username.c_str();
+	struct passwd *pw = getpwnam(user);
+
+	do
+	{
+		if ( !pw && _lu_running() ) {
+			// try lookup query to find passed username as a long name (realname in NI-speak)
+			ni_proplist **out = NULL;
+			// query "user" records.  "k" specifies position of keys in varargs
+			ni_proplist *in = lookupd_make_query("user", "kv", "realname", user);
+			if (!in) break;
+
+			int results = lookupd_query(in, &out);
+			ni_proplist_free(in);
+			if (!out) break;
+
+			// Find the first, if any, name value in returned records, getpwnam, and dispose of them
+			for (int i=0; i<results; ++i) {
+				ni_proplist *nipl = out[i];
+				for (unsigned int j=0; !pw && j< nipl->ni_proplist_len; j++) {
+					if ( !strcmp(nipl->ni_proplist_val[j].nip_name, "name") &&
+						(nipl->ni_proplist_val[j].nip_val.ni_namelist_len > 0) )
+							pw = getpwnam( *(nipl->ni_proplist_val[j].nip_val.ni_namelist_val) );
+				}
+				ni_proplist_free(nipl);
+			}
+			free(out);
+		}
+
+		if (!pw)
+		{
+			debug("autheval", "user %s not found, creating invalid credential", user);
+			break;
+		}
+
+		if (pw->pw_passwd != NULL && pw->pw_passwd[0])
+		{
+			const char *passwd = password.c_str();
+			if (strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd))
+			{
+				debug("autheval", "password for user %s is invalid, creating invalid credential", user);
+				break;
+			}
+		}
+
+		debug("autheval", "password for user %s is ok, creating%s credential",
+			user, mShared ? " shared" : "");
+
+		mUsername = string ( pw->pw_name );
+		mUid = pw->pw_uid;
+		mGid = pw->pw_gid;
+		mValid = true;
+	}
+	while (0);
+	
+	if (pw)
+		endpwent();
+}
+
+
+CredentialImpl::~CredentialImpl()
+{
+}
+
+bool
+CredentialImpl::operator < (const CredentialImpl &other) const
+{
+	if (!mShared && other.mShared)
+		return true;
+	if (!other.mShared && mShared)
+		return false;
+
+	return mUsername < other.mUsername;
+}
+
+// Returns true if this CredentialImpl should be shared.
+bool
+CredentialImpl::isShared() const
+{
+	return mShared;
+}
+
+// Merge with other
+void
+CredentialImpl::merge(const CredentialImpl &other)
+{
+	assert(mUsername == other.mUsername);
+
+	if (other.mValid && (!mValid || mCreationTime < other.mCreationTime))
+	{
+		mCreationTime = other.mCreationTime;
+		mUid = other.mUid;
+		mGid = other.mGid;
+		mValid = true;
+	}
+}
+
+// The time at which this credential was obtained.
+CFAbsoluteTime
+CredentialImpl::creationTime() const
+{
+	return mCreationTime;
+}
+
+// Return true iff this credential is valid.
+bool
+CredentialImpl::isValid() const
+{
+	return mValid;
+}
+
+void
+CredentialImpl::invalidate()
+{
+	mValid = false;
+}
+
+//
+// Credential class
+//
+Credential::Credential() :
+RefPointer<CredentialImpl>(NULL)
+{
+}
+
+Credential::Credential(CredentialImpl *impl) :
+RefPointer<CredentialImpl>(impl)
+{
+}
+
+Credential::Credential(const string &username, const uid_t uid, const gid_t gid, bool shared) :
+RefPointer<CredentialImpl>(new CredentialImpl(username, uid, gid, shared))
+{
+}
+
+Credential::Credential(const string &username, const string &password, bool shared) :
+RefPointer<CredentialImpl>(new CredentialImpl(username, password, shared))
+{
+}
+
+Credential::~Credential()
+{
+}
+
+bool
+Credential::operator < (const Credential &other) const
+{
+	if (!*this)
+		return other;
+
+	if (!other)
+		return false;
+
+	return (**this) < (*other);
+}
+
+
+//
+// Right class
+//
+Right &
+Right::overlay(AuthorizationItem &item)
+{
+	return static_cast<Right &>(item);
+}
+
+Right *
+Right::overlay(AuthorizationItem *item)
+{
+	return static_cast<Right *>(item);
+}
+
+Right::Right()
+{
+	name = "";
+	valueLength = 0;
+	value = NULL;
+	flags = 0;
+}
+
+Right::Right(AuthorizationString inName, size_t inValueLength, const void *inValue)
+{
+	name = inName;
+	valueLength = inValueLength;
+	value = const_cast<void *>(inValue);
+}
+
+Right::~Right()
+{
+}
+
+bool
+Right::operator < (const Right &other) const
+{
+	return strcmp(name, other.name) < 0;
+}
+
+
+//
+// RightSet class
+//
+const AuthorizationRights RightSet::gEmptyRights = { 0, NULL };
+
+RightSet::RightSet(const AuthorizationRights *rights) :
+mRights(const_cast<AuthorizationRights *>(rights ? rights : &gEmptyRights))
+{
+}
+
+RightSet::RightSet(const RightSet &other)
+{
+	mRights = other.mRights;
+}
+
+RightSet::~RightSet()
+{
+}
+
+RightSet::const_reference
+RightSet::back() const
+{
+	// @@@ Should this if empty::throwMe()?
+	return static_cast<const_reference>(mRights->items[size() - 1]);
+}
+
+
+//
+// MutableRightSet class
+//
+MutableRightSet::MutableRightSet(size_t count, const Right &element) :
+mCapacity(count)
+{
+	mRights = new AuthorizationRights();
+	mRights->items = reinterpret_cast<pointer>(malloc(sizeof(Right) * mCapacity));
+	if (!mRights->items)
+	{
+		delete mRights;
+		throw std::bad_alloc();
+	}
+
+	mRights->count = count;
+	for (size_type ix = 0; ix < count; ++ix)
+		mRights->items[ix] = element;
+}
+
+MutableRightSet::MutableRightSet(const RightSet &other)
+{
+	size_type count = other.size();
+	mCapacity = count;
+	mRights = new AuthorizationRights();
+
+	mRights->items = reinterpret_cast<pointer>(malloc(sizeof(Right) * mCapacity));
+	if (!mRights->items)
+	{
+		delete mRights;
+		throw std::bad_alloc();
+	}
+
+	mRights->count = count;
+	for (size_type ix = 0; ix < count; ++ix)
+		mRights->items[ix] = other.mRights->items[ix];
+}
+
+MutableRightSet::~MutableRightSet()
+{
+	free(mRights->items);
+	delete mRights;
+}
+
+MutableRightSet &
+MutableRightSet::operator = (const RightSet &other)
+{
+	size_type count = other.size();
+	if (capacity() < count)
+		grow(count);
+
+	mRights->count = count;
+	for (size_type ix = 0; ix < count; ++ix)
+		mRights->items[ix] = other.mRights->items[ix];
+
+	return *this;
+}
+
+void
+MutableRightSet::swap(MutableRightSet &other)
+{
+	AuthorizationRights *rights = mRights;
+	size_t capacity = mCapacity;
+	mRights = other.mRights;
+	mCapacity = other.mCapacity;
+	other.mRights = rights;
+	other.mCapacity = capacity;
+}
+
+MutableRightSet::reference
+MutableRightSet::back()
+{
+	// @@@ Should this if empty::throwMe()?
+	return static_cast<reference>(mRights->items[size() - 1]);
+}
+
+void
+MutableRightSet::push_back(const_reference right)
+{
+	if (size() >= capacity())
+		grow(capacity() + 1);
+
+	mRights->items[mRights->count] = right;
+	mRights->count++;
+}
+
+void
+MutableRightSet::pop_back()
+{
+	// @@@ Should this if empty::throwMe()?
+	if (!empty())
+		mRights->count--;
+}
+
+void
+MutableRightSet::grow(size_type min_capacity)
+{
+	size_type newCapacity = mCapacity * mCapacity;
+	if (newCapacity < min_capacity)
+		newCapacity = min_capacity;
+
+	void *newItems = realloc(mRights->items, sizeof(*mRights->items) * newCapacity);
+	if (!newItems)
+		throw std::bad_alloc();
+
+	mRights->items = reinterpret_cast<pointer>(newItems);
+	mCapacity = newCapacity;
+}
+
+
+//
+// Rule class
+//
+CFStringRef Rule::kUserInGroupID = CFSTR("group");
+CFStringRef Rule::kTimeoutID = CFSTR("timeout");
+CFStringRef Rule::kSharedID = CFSTR("shared");
+CFStringRef Rule::kAllowRootID = CFSTR("allow-root");
+CFStringRef Rule::kDenyID = CFSTR("deny");
+CFStringRef Rule::kAllowID = CFSTR("allow");
+
+
+Rule::Rule() :
+mType(kUserInGroup), mGroupName("admin"), mMaxCredentialAge(300.0), mShared(true), mAllowRoot(false)
+{
+	// @@@ Default rule is shared admin group with 5 minute timeout
+}
+
+Rule::Rule(CFTypeRef cfRule)
+{
+	// @@@ This code is ugly.  Serves me right for using CF.
+	if (CFGetTypeID(cfRule) == CFStringGetTypeID())
+	{
+		CFStringRef tag = reinterpret_cast<CFStringRef>(cfRule);
+		if (CFEqual(kAllowID, tag))
+		{
+			debug("authrule", "rule always allow");
+			mType = kAllow;
+		}
+		else if (CFEqual(kDenyID, tag))
+		{
+			debug("authrule", "rule always deny");
+			mType = kDeny;
+		}
+		else
+			Error::throwMe();
+	}
+	else if (CFGetTypeID(cfRule) == CFDictionaryGetTypeID())
+	{
+		mType = kUserInGroup;
+		CFDictionaryRef dict = reinterpret_cast<CFDictionaryRef>(cfRule);
+		CFTypeRef groupTag = CFDictionaryGetValue(dict, kUserInGroupID);
+		if (!groupTag || CFGetTypeID(groupTag) != CFStringGetTypeID())
+			Error::throwMe();
+
+		CFStringRef group = reinterpret_cast<CFStringRef>(groupTag);
+		char buffer[512];
+		const char *ptr = CFStringGetCStringPtr(group, kCFStringEncodingUTF8);
+		if (ptr == NULL)
+		{
+			if (CFStringGetCString(group, buffer, 512, kCFStringEncodingUTF8))
+				ptr = buffer;
+			else
+				Error::throwMe();
+		}
+
+		mGroupName = string(ptr);
+
+		mMaxCredentialAge = DBL_MAX;
+		CFTypeRef timeoutTag = CFDictionaryGetValue(dict, kTimeoutID);
+		if (timeoutTag)
+		{
+			if (CFGetTypeID(timeoutTag) != CFNumberGetTypeID())
+				Error::throwMe();
+			CFNumberGetValue(reinterpret_cast<CFNumberRef>(timeoutTag), kCFNumberDoubleType, &mMaxCredentialAge);
+		}
+
+		CFTypeRef sharedTag = CFDictionaryGetValue(dict, kSharedID);
+		mShared = false;
+		if (sharedTag)
+		{
+			if (CFGetTypeID(sharedTag) != CFBooleanGetTypeID())
+				Error::throwMe();
+			mShared = CFBooleanGetValue(reinterpret_cast<CFBooleanRef>(sharedTag));
+		}
+
+		CFTypeRef allowRootTag = CFDictionaryGetValue(dict, kAllowRootID);
+		mAllowRoot = false;
+		if (allowRootTag)
+		{
+			if (CFGetTypeID(allowRootTag) != CFBooleanGetTypeID())
+				Error::throwMe();
+			mAllowRoot = CFBooleanGetValue(reinterpret_cast<CFBooleanRef>(allowRootTag));
+		}
+		debug("authrule", "rule user in group \"%s\" timeout %g%s%s",
+			mGroupName.c_str(), mMaxCredentialAge, mShared ? " shared" : "",
+			mAllowRoot ? " allow-root" : "");
+	}
+}
+
+Rule::Rule(const Rule &other) :
+mType(other.mType),
+mGroupName(other.mGroupName),
+mMaxCredentialAge(other.mMaxCredentialAge),
+mShared(other.mShared),
+mAllowRoot(other.mAllowRoot)
+{
+}
+
+Rule &
+Rule::operator = (const Rule &other)
+{
+	mType = other.mType;
+	mGroupName = other.mGroupName;
+	mMaxCredentialAge = other.mMaxCredentialAge;
+	mShared = other.mShared;
+	mAllowRoot = other.mAllowRoot;
+	return *this;
+}
+
+Rule::~Rule()
+{
+}
+
+OSStatus
+Rule::evaluate(const Right &inRight,
+    const AuthorizationEnvironment *environment, AuthorizationFlags flags,
+	CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials,
+	const AuthorizationToken &auth)
+{
+	switch (mType)
+	{
+	case kAllow:
+		debug("autheval", "rule is always allow");
+		return errAuthorizationSuccess;
+	case kDeny:
+		debug("autheval", "rule is always deny");
+		return errAuthorizationDenied;
+	case kUserInGroup:
+		debug("autheval", "rule is user in group");
+		break;
+	default:
+		Error::throwMe();
+	}
+
+	// If we got here, this is a kUserInGroup type rule, let's start looking for a
+	// credential that is satisfactory
+
+	// Zeroth -- Here is an extra special saucy ugly hack to allow authorizations
+	// created by a proccess running as root to automatically get a right.
+	if (mAllowRoot && auth.creatorUid() == 0)
+	{
+		debug("autheval", "creator of authorization has uid == 0 granting right %s",
+			inRight.rightName());
+		return errAuthorizationSuccess;
+	}
+
+	// First -- go though the credentials we either already used or obtained during this authorize operation.
+	for (CredentialSet::const_iterator it = credentials.begin(); it != credentials.end(); ++it)
+	{
+		OSStatus status = evaluate(inRight, environment, now, *it, true);
+		if (status != errAuthorizationDenied)
+			return status;
+	}
+
+	// Second -- go though the credentials passed in to this authorize operation by the state management layer.
+	if (inCredentials)
+	{
+		for (CredentialSet::const_iterator it = inCredentials->begin(); it != inCredentials->end(); ++it)
+		{
+			OSStatus status = evaluate(inRight, environment, now, *it, false);
+			if (status == errAuthorizationSuccess)
+			{
+				// Add the credential we used to the output set.
+				// @@@ Deal with potential credential merges.
+				credentials.insert(*it);
+				return status;
+			}
+			else if (status != errAuthorizationDenied)
+				return status;
+		}
+	}
+
+	// Finally -- We didn't find the credential in our passed in credential lists.  Obtain a new credential if
+	// our flags let us do so.
+	if (!(flags & kAuthorizationFlagExtendRights))
+		return errAuthorizationDenied;
+
+	if (!(flags & kAuthorizationFlagInteractionAllowed))
+		return errAuthorizationInteractionNotAllowed;
+
+	QueryAuthorizeByGroup query;
+
+	string usernamehint;
+	// @@@ This should really be the loginname of the proccess that originally created the AuthorizationRef.
+	// For now we get the pw_name of the user with the uid of the calling process.
+	uid_t uid = query.uid();
+	if (uid)
+	{
+		struct passwd *pw = getpwuid(uid);
+		if (pw != NULL)
+		{
+			// avoid hinting a locked account (ie. root)
+			if ( (pw->pw_passwd == NULL) ||
+				 strcmp(pw->pw_passwd, "*") ) {
+				// Check if username will authorize the request and set username to
+				// be used as a hint to the user if so
+				if (evaluate(inRight, environment, now, Credential(pw->pw_name, pw->pw_uid, pw->pw_gid, mShared), true) == errAuthorizationSuccess) {
+						// user long name as hint
+						usernamehint = string( pw->pw_gecos );
+						// minus other gecos crud
+						size_t comma = usernamehint.find(',');
+						if (comma)
+							usernamehint = usernamehint.substr(0, comma);
+						// or fallback to short username
+						if (usernamehint.size() == 0)
+							usernamehint = string( pw->pw_name );
+				} //fi
+			} //fi
+			endpwent();
+		}
+	}
+
+	Credential newCredential;
+	// @@@ Keep the default reason the same, so the agent only gets userNotInGroup or invalidPassphrase
+	SecurityAgent::Reason reason = SecurityAgent::userNotInGroup;
+	// @@@ Hardcoded 3 tries to avoid infinite loops.
+	for (int tryCount = 0; tryCount < 3; ++tryCount)
+	{
+		// Obtain a new credential.  Anything but success is considered an error.
+		OSStatus status = obtainCredential(query, inRight, environment, usernamehint.c_str(), newCredential, reason);
+		if (status)
+            return status;
+
+		// Now we have successfully obtained a credential we need to make sure it authorizes the requested right
+		if (!newCredential->isValid())
+			reason = SecurityAgent::invalidPassphrase;
+		else {
+			status = evaluate(inRight, environment, now, newCredential, true);
+			if (status == errAuthorizationSuccess)
+			{
+				// Add the new credential we obtained to the output set.
+				// @@@ Deal with potential credential merges.
+				credentials.insert(newCredential);
+				query.done();
+				return errAuthorizationSuccess;
+			}
+			else if (status != errAuthorizationDenied)
+				return status;
+			reason = SecurityAgent::userNotInGroup;
+		}
+	}
+
+	query.cancel(SecurityAgent::tooManyTries);
+	return errAuthorizationDenied;
+}
+
+// Return errAuthorizationSuccess if this rule allows access based on the specified credential,
+// return errAuthorizationDenied otherwise.
+OSStatus
+Rule::evaluate(const Right &inRight, const AuthorizationEnvironment *environment, CFAbsoluteTime now,
+	const Credential &credential, bool ignoreShared)
+{
+	assert(mType == kUserInGroup);
+
+	// Get the username from the credential
+	const char *user = credential->username().c_str();
+
+	// If the credential is not valid or it's age is more than the allowed maximum age
+	// for a credential, deny.
+	if (!credential->isValid())
+	{
+		debug("autheval", "credential for user %s is invalid, denying right %s", user, inRight.rightName());
+		return errAuthorizationDenied;
+	}
+
+	if (now - credential->creationTime() > mMaxCredentialAge)
+	{
+		debug("autheval", "credential for user %s has expired, denying right %s", user, inRight.rightName());
+		return errAuthorizationDenied;
+	}
+
+	if (!ignoreShared && !mShared && credential->isShared())
+	{
+		debug("autheval", "shared credential for user %s cannot be used, denying right %s", user, inRight.rightName());
+		return errAuthorizationDenied;
+	}
+
+	// A root (uid == 0) user can do anything
+	if (credential->uid() == 0)
+	{
+		debug("autheval", "user %s has uid 0, granting right %s", user, inRight.rightName());
+		return errAuthorizationSuccess;
+	}
+
+	const char *groupname = mGroupName.c_str();
+	struct group *gr = getgrnam(groupname);
+	if (!gr)
+		return errAuthorizationDenied;
+
+	// Is this the default group of this user?
+	// <grp.h> declares gr_gid int, as opposed to advertised (getgrent(3)) gid_t
+	if (credential->gid() == gr->gr_gid)
+	{
+		debug("autheval", "user %s has group %s(%d) as default group, granting right %s",
+			user, groupname, gr->gr_gid, inRight.rightName());
+		endgrent();
+		return errAuthorizationSuccess;
+	}
+
+	for (char **group = gr->gr_mem; *group; ++group)
+	{
+		if (!strcmp(*group, user))
+		{
+			debug("autheval", "user %s is a member of group %s, granting right %s",
+				user, groupname, inRight.rightName());
+			endgrent();
+			return errAuthorizationSuccess;
+		}
+	}
+
+	debug("autheval", "user %s is not a member of group %s, denying right %s",
+		user, groupname, inRight.rightName());
+	endgrent();
+	return errAuthorizationDenied;
+}
+
+OSStatus
+Rule::obtainCredential(QueryAuthorizeByGroup &query, const Right &inRight, 
+    const AuthorizationEnvironment *environment, const char *usernameHint, Credential &outCredential, SecurityAgent::Reason reason)
+{
+	char nameBuffer[SecurityAgent::maxUsernameLength];
+	char passphraseBuffer[SecurityAgent::maxPassphraseLength];
+	OSStatus status = errAuthorizationDenied;
+
+	try {
+        if (query(mGroupName.c_str(), usernameHint, nameBuffer, passphraseBuffer, reason))
+            status = noErr;
+	} catch (const CssmCommonError &err) {
+		status = err.osStatus();
+	} catch (...) {
+		status = errAuthorizationInternal;
+	}
+	if (status == CSSM_ERRCODE_USER_CANCELED)
+	{
+		debug("auth", "canceled obtaining credential for user in group %s", mGroupName.c_str());
+		return errAuthorizationCanceled;
+	}
+	if (status == CSSM_ERRCODE_NO_USER_INTERACTION)
+	{
+		debug("auth", "user interaction not possible obtaining credential for user in group %s", mGroupName.c_str());
+		return errAuthorizationInteractionNotAllowed;
+	}
+
+	if (status != noErr)
+	{
+		debug("auth", "failed obtaining credential for user in group %s", mGroupName.c_str());
+		return status;
+	}
+
+	debug("auth", "obtained credential for user %s", nameBuffer);
+
+	string username(nameBuffer);
+	string password(passphraseBuffer);
+	outCredential = Credential(username, password, mShared);
+	return errAuthorizationSuccess;
+}
+
+
+//
+// Engine class
+//
+Engine::Engine(const char *configFile) :
+mLastChecked(DBL_MIN)
+{
+	mRulesFileName = new char[strlen(configFile) + 1];
+	strcpy(mRulesFileName, configFile);
+	memset(&mRulesFileMtimespec, 0, sizeof(mRulesFileMtimespec));
+}
+
+Engine::~Engine()
+{
+	delete[] mRulesFileName;
+}
+
+void
+Engine::updateRules(CFAbsoluteTime now)
+{
+	if (mRules.empty())
+		readRules();
+	else
+	{
+		// Don't do anything if we checked the timestamp less than 5 seconds ago
+		if (mLastChecked > now - 5.0)
+			return;
+	
+		struct stat st;
+		if (stat(mRulesFileName, &st))
+		{
+			Syslog::error("Stating rules file \"%s\": %s", mRulesFileName, strerror(errno));
+			/* @@@ No rules file found, use defaults: admin group for everything. */
+			//UnixError::throwMe(errno);
+		}
+		else
+		{
+			// @@@ Make sure this is the right way to compare 2 struct timespec thingies
+			// Technically we should check st_dev and st_ino as well since if either of those change
+			// we are looking at a different file too.
+			if (memcmp(&st.st_mtimespec, &mRulesFileMtimespec, sizeof(mRulesFileMtimespec)))
+				readRules();
+		}
+	}
+
+	mLastChecked = now;
+}
+
+void
+Engine::readRules()
+{
+	// Make an entry in the mRules map that matches every right to the default Rule.
+	mRules.clear();
+	mRules.insert(RuleMap::value_type(string(), Rule()));
+
+	int fd = open(mRulesFileName, O_RDONLY, 0);
+	if (fd == -1)
+	{
+		Syslog::error("Opening rules file \"%s\": %s", mRulesFileName, strerror(errno));
+		return;
+	}
+
+	try
+	{
+		struct stat st;
+		if (fstat(fd, &st))
+			UnixError::throwMe(errno);
+
+		mRulesFileMtimespec = st.st_mtimespec;
+
+		off_t fileSize = st.st_size;
+
+        CFRef<CFMutableDataRef> xmlData(CFDataCreateMutable(NULL, fileSize));
+        CFDataSetLength(xmlData, fileSize);
+		void *buffer = CFDataGetMutableBytePtr(xmlData);
+		size_t bytesRead = read(fd, buffer, fileSize);
+		if (bytesRead != fileSize)
+		{
+			if (bytesRead == static_cast<size_t>(-1))
+			{
+				Syslog::error("Reading rules file \"%s\": %s", mRulesFileName, strerror(errno));
+				return;
+			}
+
+			Syslog::error("Could only read %ul out of %ul bytes from rules file \"%s\"",
+						  bytesRead, fileSize, mRulesFileName);
+			return;
+		}
+
+		CFStringRef errorString;
+        CFRef<CFDictionaryRef> newRoot(reinterpret_cast<CFDictionaryRef>
+			(CFPropertyListCreateFromXMLData(NULL, xmlData, kCFPropertyListImmutable, &errorString)));
+		if (!newRoot)
+		{
+			char buffer[512];
+			const char *error = CFStringGetCStringPtr(errorString, kCFStringEncodingUTF8);
+			if (error == NULL)
+			{
+				if (CFStringGetCString(errorString, buffer, 512, kCFStringEncodingUTF8))
+					error = buffer;
+			}
+
+			Syslog::error("Parsing rules file \"%s\": %s", mRulesFileName, error);
+			return;
+		}
+
+		if (CFGetTypeID(newRoot) != CFDictionaryGetTypeID())
+		{
+			Syslog::error("Rules file \"%s\": is not a dictionary", mRulesFileName);
+			return;
+		}
+
+		parseRules(newRoot);
+	}
+	catch(...)
+	{
+		close(fd);
+	}
+
+	close(fd);
+}
+
+void
+Engine::parseRules(CFDictionaryRef rules)
+{
+	CFDictionaryApplyFunction(rules, parseRuleCallback, this);
+}
+
+void
+Engine::parseRuleCallback(const void *key, const void *value, void *context)
+{
+	Engine *engine = reinterpret_cast<Engine *>(context);
+	if (CFGetTypeID(key) != CFStringGetTypeID())
+		return;
+
+	CFStringRef right = reinterpret_cast<CFStringRef>(key);
+	engine->parseRule(right, reinterpret_cast<CFTypeRef>(value));
+}
+
+void
+Engine::parseRule(CFStringRef cfRight, CFTypeRef cfRule)
+{
+	char buffer[512];
+	const char *ptr = CFStringGetCStringPtr(cfRight, kCFStringEncodingUTF8);
+	if (ptr == NULL)
+	{
+		if (CFStringGetCString(cfRight, buffer, 512, kCFStringEncodingUTF8))
+			ptr = buffer;
+	}
+
+	string right(ptr);
+	try
+	{
+		mRules[right] = Rule(cfRule);
+		debug("authrule", "added rule for right \"%s\"", right.c_str());
+	}
+	catch (...)
+	{
+		Syslog::error("Rules file \"%s\" right \"%s\": rule is invalid", mRulesFileName, ptr);
+	}
+}
+
+
+/*!
+	@function AuthorizationEngine::getRule
+
+	Look up the Rule for a given right.
+
+	@param inRight (input) the right for which we want a rule.
+
+	@results The Rule for right
+*/
+Rule
+Engine::getRule(const Right &inRight) const
+{
+	string key(inRight.rightName());
+	for (;;)
+	{
+		RuleMap::const_iterator it = mRules.find(key);
+		if (it != mRules.end())
+		{
+			debug("authrule", "right \"%s\" using right expression \"%s\"", inRight.rightName(), key.c_str());
+			return it->second;
+		}
+
+		// no default rule
+		assert (key.size());
+
+		// any reduction of a combination of two chars is futile
+		if (key.size() > 2) {
+			// find last dot with exception of possible dot at end
+			string::size_type index = key.rfind('.', key.size() - 2);
+			// cut right after found dot, or make it match default rule
+			key = key.substr(0, index == string::npos ? 0 : index + 1);
+		} else
+			key.erase();
+	}
+}
+
+/*!
+	@function AuthorizationEngine::authorize
+
+	@@@.
+
+	@param inRights (input) List of rights being requested for authorization.
+	@param environment (optional/input) Environment containing information to be used during evaluation.
+	@param flags (input) Optional flags @@@ see AuthorizationCreate for a description.
+	@param inCredentials (input) Credentials already held by the caller.
+	@param outCredentials (output/optional) Credentials obtained, used or refreshed during this call to authorize the requested rights.
+	@param outRights (output/optional) Subset of inRights which were actually authorized.
+
+	@results Returns errAuthorizationSuccess if all rights requested are authorized, or if the kAuthorizationFlagPartialRights flag was specified.  Might return other status values like errAuthorizationDenied, errAuthorizationCanceled or errAuthorizationInteractionNotAllowed 
+*/
+OSStatus
+Engine::authorize(const RightSet &inRights, const AuthorizationEnvironment *environment,
+	AuthorizationFlags flags, const CredentialSet *inCredentials, CredentialSet *outCredentials,
+	MutableRightSet *outRights, const AuthorizationToken &auth)
+{
+	CredentialSet credentials;
+	MutableRightSet rights;
+	OSStatus status = errAuthorizationSuccess;
+
+	// Get current time of day.
+	CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+
+	// Update rules from database if needed
+	updateRules(now);
+
+	// Check if a credential was passed into the environment and we were asked to extend the rights
+	if (environment && (flags & kAuthorizationFlagExtendRights))
+	{
+		const AuthorizationItem *username = NULL, *password = NULL;
+		bool shared = false;
+		for (UInt32 ix = 0; ix < environment->count; ++ix)
+		{
+			const AuthorizationItem &item = environment->items[ix];
+			if (!strcmp(item.name, kAuthorizationEnvironmentUsername))
+				username = &item;
+			if (!strcmp(item.name, kAuthorizationEnvironmentPassword))
+				password = &item;
+			if (!strcmp(item.name, kAuthorizationEnvironmentShared))
+				shared = true;
+		}
+
+		if (username && password)
+		{
+			// Let's create a credential from the passed in username and password.
+			Credential newCredential(string(reinterpret_cast<const char *>(username->value), username->valueLength),
+				string(reinterpret_cast<const char *>(password->value), password->valueLength), shared);
+			// If it's valid insert it into the credentials list.  Normally this is
+			// only done if it actually authorizes a requested right, but for this
+			// special case (environment) we do it even when no rights are being requested.
+			if (newCredential->isValid())
+				credentials.insert(newCredential);
+		}
+	}
+
+	RightSet::const_iterator end = inRights.end();
+	for (RightSet::const_iterator it = inRights.begin(); it != end; ++it)
+	{
+		// Get the rule for each right we are trying to obtain.
+		OSStatus result = getRule(*it).evaluate(*it, environment, flags, now, 
+            inCredentials, credentials, auth);
+		if (result == errAuthorizationSuccess)
+			rights.push_back(*it);
+		else if (result == errAuthorizationDenied || result == errAuthorizationInteractionNotAllowed)
+		{
+			if (!(flags & kAuthorizationFlagPartialRights))
+			{
+				status = result;
+				break;
+			}
+		}
+        else if (result == errAuthorizationCanceled)
+        {
+            status = result;
+            break;
+        }
+		else
+		{
+			Syslog::error("Engine::authorize: Rule::evaluate returned %ld returning errAuthorizationInternal", result);
+			status = errAuthorizationInternal;
+			break;
+		}
+	}
+
+	if (outCredentials)
+		outCredentials->swap(credentials);
+	if (outRights)
+		outRights->swap(rights);
+
+	return status;
+}
diff --git a/SecurityServer/Authorization/AuthorizationEngine.h b/SecurityServer/Authorization/AuthorizationEngine.h
new file mode 100644
index 00000000..c0748e86
--- /dev/null
+++ b/SecurityServer/Authorization/AuthorizationEngine.h
@@ -0,0 +1,312 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  AuthorizationEngine.h
+ *  Authorization
+ *
+ *    Copyright:  (c) 2000 by Apple Computer, Inc., all rights reserved
+ *
+ */
+
+#if !defined(__AuthorizationEngine__)
+#define __AuthorizationEngine__ 1
+
+#include <Security/Authorization.h>
+#include <Security/refcount.h>
+#include <Security/osxsigning.h>
+#include "agentquery.h"
+
+#include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFDictionary.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <map>
+#include <set>
+#include <string>
+
+class AuthorizationToken;
+
+namespace Authorization
+{
+
+class Error : public CssmCommonError {
+protected:
+    Error(int err);
+public:
+    const int error;
+    virtual CSSM_RETURN cssmError() const;
+    virtual OSStatus osStatus() const;
+    virtual const char *what () const;
+	// @@@ Default value should be internal error.
+    static void throwMe(int err = -1) __attribute((noreturn));
+};
+
+
+/* Credentials are less than comparable so they can be put in sets or maps. */
+class CredentialImpl : public RefCount
+{
+public:
+	CredentialImpl(const string &username, const uid_t uid, gid_t gid, bool shared);
+	CredentialImpl(const string &username, const string &password, bool shared);
+	~CredentialImpl();
+
+	bool operator < (const CredentialImpl &other) const;
+
+	// Returns true if this credential should be shared.
+	bool isShared() const;
+
+	// Merge with other
+	void merge(const CredentialImpl &other);
+
+	// The time at which this credential was obtained.
+	CFAbsoluteTime creationTime() const;
+
+	// Return true iff this credential is valid.
+	bool isValid() const;
+
+	// Make this credential invalid.
+	void invalidate();
+
+	// We could make Rule a friend but instead we just expose this for now
+	inline const string& username() const { return mUsername; }
+	inline const uid_t uid() const { return mUid; }
+	inline const gid_t gid() const { return mGid; }
+
+
+private:
+	// The username of the user that provided his password.
+	// This and mShared are what make this credential unique.
+	// @@@ We do not deal with the domain as of yet.
+	string mUsername;
+
+	// True iff this credential is shared.
+	bool mShared;
+
+	// Fields below are not used by less than operator
+
+	// cached pw-data as returned by getpwnam(mUsername)
+	uid_t mUid;
+	gid_t mGid;
+
+	CFAbsoluteTime mCreationTime;
+	bool mValid;
+};
+
+
+/* Credentials are less than comparable so they can be put in sets or maps. */
+class Credential : public RefPointer<CredentialImpl>
+{
+public:
+	Credential();
+	Credential(CredentialImpl *impl);
+	Credential(const string &username, const uid_t uid, gid_t gid, bool shared);
+	Credential(const string &username, const string &password, bool shared);
+	~Credential();
+
+	bool operator < (const Credential &other) const;
+};
+
+
+class MutableRightSet;
+class RightSet;
+
+class Right : protected AuthorizationItem
+{
+	friend MutableRightSet;
+	friend RightSet;
+public:
+	static Right &overlay(AuthorizationItem &item);
+	static Right *overlay(AuthorizationItem *item);
+	Right();
+	Right(AuthorizationString name, size_t valueLength, const void *value);
+	~Right();
+
+	bool operator < (const Right &other) const;
+	AuthorizationString rightName() const { return name; }
+	size_t argumentLength() const { return valueLength; }
+	const void *argument() const { return value; }
+};
+
+
+/* A RightSet is a Container and a Back Insertion Sequence, but it is not a Sequence.  Also it only
+   implements the const members of Container and Back Insertion Sequence. */
+class RightSet
+{
+	friend class MutableRightSet;
+public:
+	// Container required memebers
+	typedef Right value_type;
+	typedef const Right &const_reference;
+	typedef const Right *const_pointer;
+	typedef const_pointer const_iterator;
+	typedef ptrdiff_t difference_type;
+	typedef size_t size_type;
+
+	RightSet(const AuthorizationRights *rights = NULL);
+	RightSet(const RightSet &other);
+	~RightSet();
+
+	size_type size() const { return mRights->count; }
+	size_type max_size() const { return INT_MAX; }
+	const_iterator begin() const { return static_cast<const_pointer>(mRights->items); }
+	const_iterator end() const { return static_cast<const_pointer>(&mRights->items[mRights->count]); }
+	bool empty() const { return size() == 0; }
+
+	// Back Insertion Sequence required memebers
+	const_reference back() const;
+
+	// Other convenience members
+	operator const AuthorizationRights *() const { return mRights; }
+private:
+	RightSet &operator = (const RightSet &other);
+
+protected:
+	static const AuthorizationRights gEmptyRights;
+	AuthorizationRights *mRights;
+};
+
+
+/* A MutableRightSet is a Container and a Back Insertion Sequence, but it is not a Sequence. */
+class MutableRightSet : public RightSet
+{
+public:
+	// Container required memebers
+	typedef Right &reference;
+	typedef Right *pointer;
+	typedef pointer iterator;
+
+	MutableRightSet(size_t count = 0, const Right &element = Right());
+	MutableRightSet(const RightSet &other);
+	~MutableRightSet();
+
+	MutableRightSet &operator = (const RightSet &other);
+
+	iterator begin() { return static_cast<pointer>(mRights->items); }
+	iterator end() { return static_cast<pointer>(&mRights->items[mRights->count]); }
+	void swap(MutableRightSet &other);
+
+	// Back Insertion Sequence required memebers
+	reference back();
+	void push_back(const_reference right);
+	void pop_back();
+
+	// Other convenience members
+	size_type capacity() const { return mCapacity; }
+private:
+	void grow(size_type min_capacity);
+
+	size_type mCapacity;
+};
+
+
+typedef set<Credential> CredentialSet;
+
+
+class Rule
+{
+public:
+	Rule();
+	Rule(CFTypeRef cfRule);
+	Rule(const Rule &other);
+	Rule &operator = (const Rule &other);
+	~Rule();
+
+	OSStatus evaluate(const Right &inRight, const AuthorizationEnvironment *environment,
+		AuthorizationFlags flags, CFAbsoluteTime now,
+		const CredentialSet *inCredentials, CredentialSet &credentials,
+		const AuthorizationToken &auth);
+
+private:
+	OSStatus evaluate(const Right &inRight, const AuthorizationEnvironment *environment,
+		CFAbsoluteTime now, const Credential &credential, bool ignoreShared);
+	OSStatus obtainCredential(QueryAuthorizeByGroup &client, const Right &inRight,
+		const AuthorizationEnvironment *environment, const char *usernameHint,
+		Credential &outCredential, SecurityAgent::Reason reason);
+
+	enum Type
+	{
+		kDeny,
+		kAllow,
+		kUserInGroup
+	} mType;
+
+	string mGroupName;
+	CFTimeInterval mMaxCredentialAge;
+	bool mShared;
+	bool mAllowRoot;
+
+	static CFStringRef kUserInGroupID;
+	static CFStringRef kTimeoutID;
+	static CFStringRef kSharedID;
+	static CFStringRef kAllowRootID;
+	static CFStringRef kDenyID;
+	static CFStringRef kAllowID;
+};
+
+
+/* The engine which performs the actual authentication and authorization computations.
+
+	The implementation of a typical call to AuthorizationCreate would look like:
+	
+	Get the current shared CredentialSet for this session.
+	Call authorizedRights() with inRights and the shared CredentialSet.
+	Compute the difference set between the rights requested and the rights returned from authorizedRights().  
+	Call credentialIds() with the rights computed above (for which we have no credentials yet).
+	Call aquireCredentials() for the credentialIds returned from credentialIds()
+	For each credential returned place it in the session (replacing when needed) if shared() returns true.
+	The authorization returned to the user should now refer to the credentials in the session and the non shared ones returned by aquireCredentials().
+
+	When a call to AuthorizationCopyRights() is made, just call authorizedRights() using the union of the session credentials and the credentials tied to the authorization specified.
+
+	When a call to AuthorizationCopyInfo() is made, ask the Credential specified by tag for it info and return it.
+
+	When a call to AuthorizationFree() is made, delete all the non-shared credentials ascociated with the authorization specified.  If the kAuthorizationFreeFlagDestroy is set.  Also delete the shared credentials ascociated with the authorization specified.
+ */
+class Engine
+{
+public:
+	Engine(const char *configFile);
+	~Engine();
+
+	OSStatus authorize(const RightSet &inRights, const AuthorizationEnvironment *environment,
+		AuthorizationFlags flags, const CredentialSet *inCredentials, CredentialSet *outCredentials,
+		MutableRightSet *outRights, const AuthorizationToken &auth);
+private:
+	void updateRules(CFAbsoluteTime now);
+	void readRules();
+	void parseRules(CFDictionaryRef rules);
+	static void parseRuleCallback(const void *key, const void *value, void *context);
+	void parseRule(CFStringRef right, CFTypeRef rule);
+
+	Rule getRule(const Right &inRight) const;
+
+	char *mRulesFileName;
+	CFAbsoluteTime mLastChecked;
+	struct timespec mRulesFileMtimespec;
+
+	typedef map<Right, Rule> RightMap;
+	typedef map<string, Rule> RuleMap;
+
+	RuleMap mRules;
+};
+
+}; // namespace Authorization
+
+#endif /* ! __AuthorizationEngine__ */
diff --git a/SecurityServer/Authorization/AuthorizationPlugin.h b/SecurityServer/Authorization/AuthorizationPlugin.h
new file mode 100644
index 00000000..af0c5a1f
--- /dev/null
+++ b/SecurityServer/Authorization/AuthorizationPlugin.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+/*
+ *  AuthorizationPlugin.h
+ *  AuthorizationPlugin -- APIs for implementing authorization plugins.
+ */
+
+#if !defined(__AuthorizationPlugin__)
+#define __AuthorizationPlugin__ 1
+
+#include <Security/Authorization.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/*!
+	@header AuthorizationPlugin
+	Version 0.3 05/09/2001
+
+	Foo bar @@@.
+
+*/
+
+
+/*!
+	@typedef AuthorizationValue
+	@@@
+*/
+typedef struct AuthorizationValue
+{
+    UInt32 length;
+    void *data;
+} AuthorizationValue;
+
+typedef struct AuthorizationValueVector
+{
+	UInt32 count;
+	AuthorizationValue *values;
+} AuthorizationValueVector;
+
+typedef UInt32 AuthorizationContextFlags;
+enum
+{
+    /* If set, it will be possible to obtain the value of this attribute usingAuthorizationCopyInfo(). */
+    kAuthorizationContextFlagExtractable = (1 << 0),
+
+    /* If set, this value will not be remembered in a "credential".  @@@ Do we need this? */
+    kAuthorizationContextFlagVolatile = (1 << 1)
+};
+
+
+/*!
+	@typedef AuthorizationMechanismId
+	@@@
+*/
+typedef const AuthorizationString AuthorizationMechanismId;
+
+/*!
+	@typedef AuthorizationPluginRef
+	An instance of a plugin (even though there will probably only be one).
+*/
+typedef void *AuthorizationPluginRef;
+
+/*!
+	@typedef AuthorizationMechanismRef
+	An instance of a mechanism in a plugin.
+*/
+typedef void *AuthorizationMechanismRef;
+
+/*!
+	@typedef AuthorizationEngineRef
+	The engines handle for an instance of a mechanism in a plugin (corresponds to a particular AuthorizationMechanismRef).
+*/
+typedef struct __OpaqueAuthorizationEngine *AuthorizationEngineRef;
+
+
+/*!
+	@typedef AuthorizationSessionId
+	A unique value for an AuthorizationSession being evaluated, provided by the authorization engine.
+    A session is represented by a top level call to an Authorization API.
+    @@@ Should this be changed to tie a session to the lifetime of an AuthorizationRef?  -- Michael
+*/
+typedef void *AuthorizationSessionId;
+
+/*!
+	@typedef AuthorizationResult
+	Possible values that SetResult may use.
+
+    @param kAuthorizationResultAllow the operation succeeded and should be allowed as far as this mechanism is concerned.
+    @param kAuthorizationResultDeny the operation succeeded and should be denied as far as this mechanism is concerned.
+    @param kAuthorizationResultUndefined the operation failed for some reason and should not be retried for this session.
+    @param kAuthorizationResultUserCanceled the user has requested that the evaluation be terminated.
+*/
+typedef UInt32 AuthorizationResult;
+enum
+{
+    kAuthorizationResultAllow,
+    kAuthorizationResultDeny,
+    kAuthorizationResultUndefined,
+    kAuthorizationResultUserCanceled,
+};
+
+enum {
+    kAuthorizationPluginInterfaceVersion = 0,
+};
+
+enum {
+    kAuthorizationCallbacksVersion = 0,
+};
+
+
+/* Callback API of the AuthorizationEngine. */
+typedef struct AuthorizationCallbacks {
+    /* Will be set to kAuthorizationCallbacksVersion. */
+    UInt32 version;
+
+    /* Flow control */
+
+    /* Set a result after a call to AuthorizationSessionInvoke. */
+    OSStatus (*SetResult)(AuthorizationEngineRef inEngine, AuthorizationResult inResult);
+
+    /* Request authorization engine to interrupt all mechamisms invoked after this mechamism has called SessionSetResult and then call AuthorizationSessionInvoke again. */
+    OSStatus (*RequestInterrupt)(AuthorizationEngineRef inEngine);
+
+    OSStatus (*DidDeactivate)(AuthorizationEngineRef inEngine);
+
+
+    /* Getters and setters */
+    OSStatus (*GetContextValue)(AuthorizationEngineRef inEngine,
+        AuthorizationString inKey,
+        AuthorizationContextFlags *outContextFlags,
+        const AuthorizationValue **outValue);
+
+    OSStatus (*SetContextValue)(AuthorizationEngineRef inEngine,
+        AuthorizationString inKey,
+        AuthorizationContextFlags inContextFlags,
+        const AuthorizationValue *inValue);
+
+    OSStatus (*GetHintValue)(AuthorizationEngineRef inEngine,
+        AuthorizationString inKey,
+        const AuthorizationValue **outValue);
+
+    OSStatus (*SetHintValue)(AuthorizationEngineRef inEngine,
+        AuthorizationString inKey,
+        const AuthorizationValue *inValue);
+
+    OSStatus (*GetArguments)(AuthorizationEngineRef inEngine,
+        const AuthorizationValueVector **outArguments);
+
+    OSStatus (*GetSessionId)(AuthorizationEngineRef inEngine,
+        AuthorizationSessionId *outSessionId);
+
+
+} AuthorizationCallbacks;
+
+
+/* Functions that must be implemented by each plugin. */
+
+typedef struct AuthorizationPluginInterface
+{
+    /* Must be set to kAuthorizationPluginInterfaceVersion. */
+    UInt32 version;
+
+    /* Notify a plugin that it is about to be unloaded so it get a chance to clean up and release any resources it is holding.  */
+    OSStatus (*PluginDestroy)(AuthorizationPluginRef inPlugin);
+
+    /* The plugin should create an AuthorizationMechanismRef and remeber inEngine, mechanismId and callbacks for future reference.  It is guaranteed that MechanismDestroy will be called on the returned AuthorizationMechanismRef sometime after this function.  */
+    OSStatus (*MechanismCreate)(AuthorizationPluginRef inPlugin,
+        AuthorizationEngineRef inEngine,
+        AuthorizationMechanismId mechanismId,
+        AuthorizationMechanismRef *outMechanism);
+
+    /* Invoke (or evaluate) an instance of a mechanism (created with MechanismCreate).  It should call SetResult during or after returning from this function.  */
+    OSStatus (*MechanismInvoke)(AuthorizationMechanismRef inMechanism);
+
+    /* Plugin should respond with a SessionDidDeactivate asap. */
+    OSStatus (*MechanismDeactivate)(AuthorizationMechanismRef inMechanism);
+
+    OSStatus (*MechanismDestroy)(AuthorizationMechanismRef inMechanism);
+
+} AuthorizationPluginInterface;
+
+
+/* @function AuthorizationPluginCreate
+
+    Initialize a plugin after it gets loaded.  This is the main entry point to a plugin.  This function will only be called once and after all Mechanism instances have been destroyed outPluginInterface->PluginDestroy will be called.
+
+    @param callbacks (input) A pointer to an AuthorizationCallbacks which contains the callbacks implemented by the AuthorizationEngine.
+    @param outPlugin (output) On successful completion should contain a valid AuthorizationPluginRef.  This will be passed in to any subsequent calls the engine makes to  outPluginInterface->MechanismCreate and outPluginInterface->PluginDestroy.
+    @param outPluginInterface (output) On successful completion should contain a pointer to a AuthorizationPluginInterface that will stay valid until outPluginInterface->PluginDestroy is called. */
+OSStatus AuthorizationPluginCreate(const AuthorizationCallbacks *callbacks,
+    AuthorizationPluginRef *outPlugin,
+    const AuthorizationPluginInterface **outPluginInterface);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* ! __AuthorizationPlugin__ */
diff --git a/SecurityServer/Authorization/AuthorizationTags.h b/SecurityServer/Authorization/AuthorizationTags.h
new file mode 100644
index 00000000..2b6537af
--- /dev/null
+++ b/SecurityServer/Authorization/AuthorizationTags.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  AuthorizationTags.h
+ *  Authorization -- Right tags for implementing access control in applications and daemons
+ *
+ *    Copyright:  (c) 2000, 2001 by Apple Computer, Inc., all rights reserved
+ *
+ */
+
+#if !defined(__AuthorizationTags__)
+#define __AuthorizationTags__ 1
+
+
+/*!
+	@header AuthorizationTags
+	Draft version 2 01/23/2001
+
+	This header defines some of the supported rights tags to be used in the Authorization API.
+*/
+
+
+/*!
+	@define kAuthorizationEnvironmentUsername
+	The name of the AuthorizationItem that should be passed into the environment when specifying a username.  The value and valueLength should contain the username itself.
+*/
+#define kAuthorizationEnvironmentUsername  "username"
+
+/*!
+	@define kAuthorizationEnvironmentPassword
+	The name of the AuthorizationItem that should be passed into the environment when specifying a password for a given username.  The value and valueLength should contain the actual password data.
+*/
+#define kAuthorizationEnvironmentPassword  "password"
+
+/*!
+	@define kAuthorizationEnvironmentShared
+	The name of the AuthorizationItem that should be passed into the environment when specifying a username and password.  Adding this entry to the environment will cause the username/password to be added to the shared credential pool of the calling applications session.  This means that further calls by other applications in this session will automatically have this credential availible to them.  The value is ignored.
+*/
+#define kAuthorizationEnvironmentShared  "shared"
+
+/*!
+	@define kAuthorizationRightExecute
+	The name of the AuthorizationItem that should be passed into the rights when preauthorizing for a call to AuthorizationExecuteWithPrivileges().
+	
+	You need to aquire this right to be able to perform a AuthorizationExecuteWithPrivileges() operation.  In addtion to this right you should obtain whatever rights the tool you are executing with privileges need to perform it's operation on your behalf.  Currently no options are supported but you should pass in the full path of the tool you wish to execute in the value and valueLength fields.  In the future we will limit the right to only execute the requested path, and we will display this information to the user.
+*/
+#define kAuthorizationRightExecute "system.privilege.admin"
+
+#endif /* ! __AuthorizationTags__ */
diff --git a/SecurityServer/Authorization/AuthorizationTrampoline.cpp b/SecurityServer/Authorization/AuthorizationTrampoline.cpp
new file mode 100644
index 00000000..d0a12d7b
--- /dev/null
+++ b/SecurityServer/Authorization/AuthorizationTrampoline.cpp
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+
+//
+// AuthorizationTrampoline - simple suid-root execution trampoline
+// for the authorization API.
+//
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <Security/Authorization.h>
+#include <Security/debugging.h>
+#include <Security/logging.h>
+
+
+#define EXECUTERIGHT "system.privilege.admin"
+
+
+static void fail(OSStatus cause) __attribute__ ((noreturn));
+
+
+//
+// Main program entry point.
+//
+// Arguments:
+//	argv[0] = my name
+//	argv[1] = path to user tool
+//	argv[2] = "auth n", n=file descriptor of mailbox temp file
+//	argv[3..n] = arguments to pass on
+//
+// File descriptors (set by fork/exec code in client):
+//	0 -> communications pipe (perhaps /dev/null)
+//	1 -> notify pipe write end
+//	2 and above -> unchanged from original client
+//
+int main(int argc, const char *argv[])
+{
+	// initial setup
+	Syslog::open("authexec", LOG_AUTH);
+
+	// validate basic integrity
+	if (!argv[0] || !argv[1] || !argv[2]) {
+		Syslog::alert("invalid argument vector");
+		exit(1);
+	}
+	
+	// pick up arguments
+	const char *pathToTool = argv[1];
+	const char *mboxFdText = argv[2];
+	const char **restOfArguments = argv + 3;
+	debug("authtramp", "trampoline(%s,%s)", pathToTool, mboxFdText);
+
+    // read the external form
+    AuthorizationExternalForm extForm;
+    int fd;
+    if (sscanf(mboxFdText, "auth %d", &fd) != 1)
+        return errAuthorizationInternal;
+    if (lseek(fd, 0, SEEK_SET) ||
+            read(fd, &extForm, sizeof(extForm)) != sizeof(extForm)) {
+        close(fd);
+        return errAuthorizationInternal;
+    }
+
+	// internalize the authorization
+	AuthorizationRef auth;
+	if (OSStatus error = AuthorizationCreateFromExternalForm(&extForm, &auth))
+		fail(error);
+	debug("authtramp", "authorization recovered");
+	
+	// are we allowed to do this?
+	AuthorizationItem right = { EXECUTERIGHT, 0, NULL, 0 };
+	AuthorizationRights inRights = { 1, &right };
+	AuthorizationRights *outRights;
+	if (OSStatus error = AuthorizationCopyRights(auth, &inRights, NULL /*env*/,
+			kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, &outRights))
+		fail(error);
+	if (outRights->count != 1 || strcmp(outRights->items[0].name, EXECUTERIGHT))
+		fail(errAuthorizationDenied);
+		
+	// ----- AT THIS POINT WE COMMIT TO PERMITTING THE EXECUTION -----
+	
+	// let go of our authorization - the client tool will re-internalize it
+	AuthorizationFree(auth, kAuthorizationFlagDefaults);
+	
+	// put the external authorization form into the environment
+	setenv("__AUTHORIZATION", mboxFdText, true);
+
+	// shuffle file descriptors
+	int notify = dup(1);		// save notify port
+	fcntl(notify, F_SETFD, 1);	// close notify port on (successful) exec
+	dup2(0, 1);					// make stdin, stdout point to the comms pipe
+	
+	// prepare the argv for the tool (prepend the "myself" element)
+	// note how this overwrites a known-existing argv element (that we copied earlier)
+	*(--restOfArguments) = pathToTool;
+	
+	debug("authtramp", "trampoline executes %s", pathToTool);
+	Syslog::notice("executing %s", pathToTool);
+	execv(pathToTool, (char *const *)restOfArguments);
+	debug("authexec", "exec(%s) failed (errno=%d)", pathToTool, errno);
+	
+	// report failure
+	OSStatus error = errAuthorizationToolExecuteFailure;
+	write(notify, &error, sizeof(error));
+	exit(1);
+}
+
+
+void fail(OSStatus cause)
+{
+	write(1, &cause, sizeof(cause));	// ignore error - can't do anything if error
+	debug("authtramp", "trampoline aborting with status %ld", cause);
+	exit(1);
+}
diff --git a/SecurityServer/Authorization/AuthorizationWalkers.h b/SecurityServer/Authorization/AuthorizationWalkers.h
new file mode 100644
index 00000000..cef82848
--- /dev/null
+++ b/SecurityServer/Authorization/AuthorizationWalkers.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  AuthorizationWalkers.h
+ *  SecurityCore
+ *
+ *    Copyright:  (c) 2000 by Apple Computer, Inc., all rights reserved
+ *
+ */
+
+#if !defined(__AuthorizationWalkers__)
+#define __AuthorizationWalkers__ 1
+
+#include <Security/Authorization.h>
+#include <Security/walkers.h>
+
+namespace Security
+{
+
+namespace DataWalkers
+{
+
+template <class Action>
+void walk(Action &operate, AuthorizationItem &item)
+{
+	walk(operate, item.name);
+	operate(item.value, item.valueLength);
+	// Ignore reserved
+}
+
+template <class Action>
+AuthorizationItemSet *walk(Action &operate, AuthorizationItemSet * &itemSet)
+{
+	operate(itemSet);
+	operate(itemSet->items, itemSet->count * sizeof(AuthorizationItem));
+	for (uint32 n = 0; n < itemSet->count; n++)
+		walk(operate, itemSet->items[n]);
+	return itemSet;
+}
+
+} // end namespace DataWalkers
+
+} // end namespace Security
+
+#endif /* ! __AuthorizationWalkers__ */
diff --git a/SecurityServer/Authorization/authorization.plist b/SecurityServer/Authorization/authorization.plist
new file mode 100644
index 00000000..3359602a
--- /dev/null
+++ b/SecurityServer/Authorization/authorization.plist
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+<!-- NOTICE: this file will be replaced by a system facility in
+             forthcoming releases.  It is provided purely for your
+             convenience using this release.
+
+     The name of the requested right is matched against the keys.
+     An exact match has priority, otherwise the longest match from
+     the start is used.  Note that the right will only match wildcard
+     rules (ending in a ".") during this reduction.
+
+     Rules are specified as a string or a dict.  The latter being a
+     user-in-group rule.
+
+     allow rule: this is always allowed
+     <key>com.apple.TestApp.benign</key>
+	 <string>allow</string>
+
+     deny rule: this is always denied
+     <key>com.apple.TestApp.dangerous</key>
+	 <string>deny</string>
+
+     user-in-group rule: successful authentication as a user in the
+     specified group(5) allows the associated right.
+
+     The shared property specifies whether a credential generated on
+     success is shared with other apps (same "session"). This property
+     defaults to false if not specified.
+
+     The timeout property specifies the maximum age of a (cached/shared)
+     credential accepted for this rule.
+
+     The allow-root property specifies whether a right should be allowed
+     automatically if the requesting process is running with uid == 0.
+     This defaults to false if not specified.
+
+          See remaining rules for examples.
+
+     Successful login produces a credential.
+  -->
+
+<!-- Used by AuthorizationExecuteWithPrivileges(...)
+     AuthorizationExecuteWithPrivileges is used by programs requesting
+     to run a tool as root (ie. some installers).
+     Credentials remain valid 5 minutes after they've been obtained.
+     An acquired credential isn't shared with other clients.
+     Clients running as root will be granted this right automatically.
+  -->
+	<key>system.privilege.admin</key>
+	<dict>
+		<key>group</key>
+		<string>admin</string>
+		<key>shared</key>
+		<false/>
+		<key>allow-root</key>
+		<true/>
+		<key>timeout</key>
+		<integer>300</integer>
+	</dict>
+
+<!-- Used by the dvd player to set the regioncode the first time
+     Note that changed the region code after it has been set requires a
+	 different right (system.device.dvd.setregion.change)
+     Credentials remain valid indefinitely after they've been obtained.
+     An acquired credential is shared amongst all clients.
+  -->
+	<key>system.device.dvd.setregion.initial</key>
+	<dict>
+		<key>group</key>
+		<string>admin</string>
+		<key>shared</key>
+		<true/>
+	</dict>
+
+<!-- All other rights will be matched by this rule.
+     Credentials remain valid 5 minutes after they've been obtained.
+     An acquired credential is shared amongst all clients.
+  -->
+	<key/>
+	<dict>
+		<key>group</key>
+		<string>admin</string>
+		<key>shared</key>
+		<true/>
+		<key>timeout</key>
+		<integer>300</integer>
+	</dict>
+</dict>
+</plist>
diff --git a/SecurityServer/Authorization/trampolineClient.cpp b/SecurityServer/Authorization/trampolineClient.cpp
new file mode 100644
index 00000000..73af87d6
--- /dev/null
+++ b/SecurityServer/Authorization/trampolineClient.cpp
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+
+
+//
+// trampolineClient - Authorization trampoline client-side implementation
+//
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <Security/Authorization.h>
+#include <Security/debugging.h>
+
+//
+// Where is the trampoline itself?
+//
+#if !defined(TRAMPOLINE)
+# define TRAMPOLINE "/System/Library/CoreServices/AuthorizationTrampoline" /* fallback */
+#endif
+
+
+//
+// A few names for clarity's sake
+//
+enum {
+	READ = 0,		// read end of standard UNIX pipe
+	WRITE = 1		// write end of standard UNIX pipe
+};
+
+
+//
+// Local (static) functions
+//
+static const char **argVector(const char *trampoline,
+	const char *tool, const char *commFd,
+	char *const *arguments);
+
+
+//
+// The public client API function.
+//
+OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
+	const char *pathToTool,
+	unsigned long flags,
+	char *const *arguments,
+	FILE **communicationsPipe)
+{
+	// flags are currently reserved
+	if (flags != 0)
+		return errAuthorizationInvalidFlags;
+
+	// externalize the authorization
+	AuthorizationExternalForm extForm;
+	if (OSStatus err = AuthorizationMakeExternalForm(authorization, &extForm))
+		return err;
+
+    // create the mailbox file
+    FILE *mbox = tmpfile();
+    if (!mbox)
+        return errAuthorizationInternal;
+    if (fwrite(&extForm, sizeof(extForm), 1, mbox) != 1) {
+        fclose(mbox);
+        return errAuthorizationInternal;
+    }
+    
+    // make text representation of the temp-file descriptor
+    char mboxFdText[20];
+    snprintf(mboxFdText, sizeof(mboxFdText), "auth %d", fileno(mbox));
+    
+	// make a notifier pipe
+	int notify[2];
+	if (pipe(notify)) {
+        fclose(mbox);
+		return errAuthorizationToolExecuteFailure;
+    }
+
+	// make the communications pipe if requested
+	int comm[2];
+	if (communicationsPipe && socketpair(AF_UNIX, SOCK_STREAM, 0, comm)) {
+		close(notify[READ]); close(notify[WRITE]);
+        fclose(mbox);
+		return errAuthorizationToolExecuteFailure;
+	}
+
+	// do the standard forking tango...
+	int delay = 1;
+	for (int n = 5;; n--, delay *= 2) {
+		switch (pid_t pid = fork()) {
+		case -1:	// error
+			if (errno == EAGAIN) {
+				// potentially recoverable resource shortage
+				if (n > 0) {
+					debug("authexec", "resource shortage (EAGAIN), delaying %d seconds", delay);
+					sleep(delay);
+					continue;
+				}
+			}
+			debug("authexec", "fork failed (errno=%d)", errno);
+			close(notify[READ]); close(notify[WRITE]);
+			return errAuthorizationToolExecuteFailure;
+
+		default:	// parent
+			// close foreign side of pipes
+			close(notify[WRITE]);
+			if (communicationsPipe)
+				close(comm[WRITE]);
+                
+            // close mailbox file (child has it open now)
+            fclose(mbox);
+			
+			// get status notification from child
+			OSStatus status;
+			debug("authexec", "parent waiting for status");
+			switch (ssize_t rc = read(notify[READ], &status, sizeof(status))) {
+			default:				// weird result of read: post error
+				debug("authexec", "unexpected read return value %ld", long(rc));
+				status = errAuthorizationToolEnvironmentError;
+				// fall through
+			case sizeof(status):	// read succeeded: child reported an error
+				debug("authexec", "parent received status=%ld", status);
+				close(notify[READ]);
+				if (communicationsPipe) { close(comm[READ]); close(comm[WRITE]); }
+				return status;
+			case 0:					// end of file: exec succeeded
+				close(notify[READ]);
+				if (communicationsPipe)
+					*communicationsPipe = fdopen(comm[READ], "r+");
+				debug("authexec", "parent resumes (no error)");
+				return noErr;
+			}
+
+		case 0:		// child
+			// close foreign side of pipes
+			close(notify[READ]);
+			if (communicationsPipe)
+				close(comm[READ]);
+			
+			// fd 1 (stdout) holds the notify write end
+			dup2(notify[WRITE], 1);
+			close(notify[WRITE]);
+			
+			// fd 0 (stdin) holds either the comm-link write-end or /dev/null
+			if (communicationsPipe) {
+				dup2(comm[WRITE], 0);
+				close(comm[WRITE]);
+			} else {
+				close(0);
+				open("/dev/null", O_RDWR);
+			}
+			
+			// where is the trampoline?
+#if defined(NDEBUG)
+			const char *trampoline = TRAMPOLINE;
+#else //!NDEBUG
+			const char *trampoline = getenv("AUTHORIZATIONTRAMPOLINE");
+			if (!trampoline)
+				trampoline = TRAMPOLINE;
+#endif //NDEBUG
+
+			// okay, execute the trampoline
+			debug("authexec", "child exec(%s:%s)",
+				trampoline, pathToTool);
+			if (const char **argv = argVector(trampoline, pathToTool, mboxFdText, arguments))
+				execv(trampoline, (char *const[])argv);
+			debug("authexec", "trampoline exec failed (errno=%d)", errno);
+			
+			// execute failed - tell the parent
+			{
+				OSStatus error = errAuthorizationToolExecuteFailure;
+				write(1, &error, sizeof(error));
+				_exit(1);
+			}
+		}
+	}
+}
+
+
+//
+// Build an argv vector
+//
+static const char **argVector(const char *trampoline, const char *pathToTool,
+	const char *mboxFdText, char *const *arguments)
+{
+	int length = 0;
+	if (arguments) {
+		for (char *const *p = arguments; *p; p++)
+			length++;
+	}
+	if (const char **args = (const char **)malloc(sizeof(const char *) * (length + 4))) {
+		args[0] = trampoline;
+		args[1] = pathToTool;
+		args[2] = mboxFdText;
+		if (arguments)
+			for (int n = 0; arguments[n]; n++)
+				args[n + 3] = arguments[n];
+		args[length + 3] = NULL;
+		return args;
+	}
+	return NULL;
+}
diff --git a/SecurityServer/Authorization/trampolineServer.cpp b/SecurityServer/Authorization/trampolineServer.cpp
new file mode 100644
index 00000000..cf2c5bb4
--- /dev/null
+++ b/SecurityServer/Authorization/trampolineServer.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+//
+// trampolineServer.cpp - tool-side trampoline support functions
+//
+#include <cstdlib>
+#include <unistd.h>
+#include <Security/Authorization.h>
+
+
+//
+// In a tool launched via AuthorizationCopyPrivilegedReference, retrieve a copy
+// of the AuthorizationRef that started it all.
+//
+OSStatus AuthorizationCopyPrivilegedReference(AuthorizationRef *authorization,
+	AuthorizationFlags flags)
+{
+	// flags are currently reserved
+	if (flags != 0)
+		return errAuthorizationInvalidFlags;
+
+	// retrieve hex form of external form from environment
+	const char *mboxFdText = getenv("__AUTHORIZATION");
+	if (!mboxFdText)
+		return errAuthorizationInvalidRef;
+
+    // retrieve mailbox file and read external form
+    AuthorizationExternalForm extForm;
+    int fd;
+    if (sscanf(mboxFdText, "auth %d", &fd) != 1)
+        return errAuthorizationInvalidRef;
+    if (lseek(fd, 0, SEEK_SET) ||
+            read(fd, &extForm, sizeof(extForm)) != sizeof(extForm)) {
+        close(fd);
+        return errAuthorizationInvalidRef;
+    }
+
+	// internalize the authorization
+	AuthorizationRef auth;
+	if (OSStatus error = AuthorizationCreateFromExternalForm(&extForm, &auth))
+		return error;
+
+	// well, here you go
+	*authorization = auth;
+	return noErr;
+}
diff --git a/SecurityServer/BLOBFORMAT b/SecurityServer/BLOBFORMAT
new file mode 100644
index 00000000..22528f70
--- /dev/null
+++ b/SecurityServer/BLOBFORMAT
@@ -0,0 +1,64 @@
+Description of SecurityServer blob format.
+
+
+Database blob:
+
+
+Creation (input PASSWORD, PRIVATE_DBB_BYTES, PUBLIC_DBB_BYTES)
+Update -- change password (same as creation except use passed in DSK and DEK).
+
+1. Generate a 20 byte (160 bit) random string called SALT.
+2. Derive a 24 byte (192 bit -- 168 bit effective because of odd parity in each octet) 3DES key called MK and 8 bytes IV from PASSWORD and SALT using PBKDF2 with PRF = HMACSHA1 and iteration count = 1000.
+3. Generate a 24 byte (192 bit -- 168 bit effective because of parity) 3DES key called DEK.
+4. Generate a 20 byte (160 bit SHA1HMAC key called DSK.
+5. Let TEMP1 = DSK || DEK || PRIVATE_DBB_BYTES
+6. Let TEMP2 = ciphertext of TEMP1 encrypted with MK and IV using 3DES in CBC_IV mode.
+7. Let TEMP3 = SALT || LEN(PUBLIC_DBB_BYTES) || PUBLIC_DBB_BYTES || TEMP2
+8. Let SIG = SHA1HMAC(DSK, TEMP3)
+9. Let DBB = SIG || TEMP3
+10. Outputs DBB, DSK (for signing) and DEK (for encryption)
+
+
+Decode (input DBB and PASSWORD)
+
+1. Let SIG = First 20 octets of DBB.
+2. Let TEMP3 = Octets 20 though end of DBB.
+3. Let SALT = Octets 0 though 20 of TEMP3.
+4. Derive a 192 bit (168 bit effective because of parity) 3DES key called MK and 8 bytes IV from PASSWORD and SALT using PKDF2 with PRF = HMACSHA1 and iteration count = 1000.
+5. Let LEN_PUBLIC_DBB_BYTES = Octets 20 though 24 of TEMP3.
+6. Let PUBLIC_DBB_BYTES = Octets 24 though 24 + LEN_PUBLIC_DBB_BYTES of TEMP3.
+7. Let TEMP2 = Octets 24 + LEN_PUBLIC_DBB_BYTES though end of TEMP3.
+8. Let TEMP1 = plaintext of TEMP2 decrypted with MK and IV using 3DES in CBC_IV mode with PKCS1 padding.
+9. Let DSK = First 20 octets of TEMP1
+10. Verify that SHA1HMAC(DSK, TEMP3) == SIG (using VerifyMac) if fail then password is wrong. 
+11. Let DEK = Octets 20 though 44 of TEMP1
+12. If DEK does not have odd parity in all octets then DBB is corrupt.
+13. Let PRIVATE_DBB_BYTES = Octets 44 though end of TEMP1
+14. Outputs PUBLIC_DBB_BYTES, PRIVATE_DBB_BYTES, DSK, DEK
+
+
+
+Key blob:
+
+Creation (input DSK, DEK, PRIVATE_KEY_BYTES, PUBLIC_KEY_BYTES output KB)
+(NOTE PRIVATE_KEY_BYTES contains both the key bits (24 bytes) and the private ACL parts)
+
+1. Generate a 8 byte random string called IV
+2. Encrypt PRIVATE_KEY_BYTES using DEK (3DES) and IV in CBC mode with PKCS1 padding.  Call the ciphertext TEMP1
+3. Let TEMP2 = IV || TEMP1.
+4. Reverse the order of the octects in TEMP2 call the result TEMP3.
+5. Encrypt TEMP3 using DEK with an IV of 0x4adda22c79e82105 in CBC mode with PKCS1 padding call the result TEMP4.
+6. Concatenate LEN(PUBLIC_KEY_BYTES) | PUBLIC_KEY_BYTES | TEMP4 and call it TEMP5
+7. Compute the 20 byte SHA1HMAC of TEMP5 using DSK and call it SIG.
+8. Concatinate TEMP5 | SIG and call the result KB.
+
+Decode (input DSK, DEK, KB output PRIVATE_KEY_BYTES, PUBLIC_KEY_BYTES)
+
+1. Split KB in TEMP5 and SIG (SIG is last 20 bytes) TEMP5 is the rest.
+2. Verify the 20 byte SHA1HMAC of TEMP5 using DSK against SIG if if fails the blob is invalid.
+3. Split TEMP5 in LEN(PUBLIC_KEY_BYTES) , PUBLIC_KEY_BYTES and TEMP4.
+4. Decrypt TEMP4 using DEK with an IV of 0x4adda22c79e82105 in CBC mode with PKCS1 padding call the result TEMP3.
+5. Reverse the order of the octects in TEMP3 and call the result TEMP2.
+6. Split TEMP2 in IV (first 8 bytes) and TEMP1 (rest).
+7. Decrypt TEMP1 using DEK (3DES) and IV in CBC mode with PKCS1 padding.  Call the plaintext PRIVATE_KEY_BYTES.
+
diff --git a/SecurityServer/CVSVersionInfo.txt b/SecurityServer/CVSVersionInfo.txt
new file mode 100644
index 00000000..7ca8c83e
--- /dev/null
+++ b/SecurityServer/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:14:00 mb Exp $
+# $Name: Security-28 $
+ProjectName: SecurityServer
+ProjectVersion: 17.1
diff --git a/SecurityServer/MacYarrow/MacYarrow.pbproj/project.pbxproj b/SecurityServer/MacYarrow/MacYarrow.pbproj/project.pbxproj
new file mode 100644
index 00000000..9b7fa49c
--- /dev/null
+++ b/SecurityServer/MacYarrow/MacYarrow.pbproj/project.pbxproj
@@ -0,0 +1,1680 @@
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 26;
+	objects = {
+		04E694E6FED2FFD1D0A17CE7 = {
+			isa = PBXProject;
+			knownPlatforms = (
+			);
+			mainGroup = 04E694E7FED2FFD1D0A17CE7;
+			productRefGroup = 04E694E8FED30093D0A17CE7;
+			projectDirPath = .;
+			targets = (
+				04E694EDFED30093D0A17CE7,
+				04E694EFFED30093D0A17CE7,
+				04E694F6FED30093D0A17CE7,
+				04E694FBFED30093D0A17CE7,
+				04E69500FED30093D0A17CE7,
+				6106C772FEDC677AD0A17CE7,
+				6106C789FEDC6E50D0A17CE7,
+				6106C78FFEDC6E50D0A17CE7,
+			);
+		};
+		04E694E7FED2FFD1D0A17CE7 = {
+			children = (
+				6106C76EFEDC677AD0A17CE7,
+				04E69508FED301E6D0A17CE7,
+				04E69509FED301E6D0A17CE7,
+				04E6950AFED301E6D0A17CE7,
+				04E6950BFED301E6D0A17CE7,
+				6106C784FEDC6E50D0A17CE7,
+				04E694E8FED30093D0A17CE7,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		04E694E8FED30093D0A17CE7 = {
+			children = (
+				04E694E9FED30093D0A17CE7,
+				04E694EAFED30093D0A17CE7,
+				04E694EBFED30093D0A17CE7,
+				04E694ECFED30093D0A17CE7,
+				6106C787FEDC6E50D0A17CE7,
+				6106C788FEDC6E50D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		04E694E9FED30093D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			path = YarrowClient.framework;
+			refType = 3;
+		};
+		04E694EAFED30093D0A17CE7 = {
+			isa = PBXLibraryReference;
+			path = libYarrowServer.a;
+			refType = 3;
+		};
+		04E694EBFED30093D0A17CE7 = {
+			isa = PBXLibraryReference;
+			path = libYarrowCore.a;
+			refType = 3;
+		};
+		04E694ECFED30093D0A17CE7 = {
+			isa = PBXLibraryReference;
+			path = libzlibcomp.a;
+			refType = 3;
+		};
+		04E694EDFED30093D0A17CE7 = {
+			buildPhases = (
+			);
+			buildSettings = {
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				04E694F5FED30093D0A17CE7,
+				04E69507FED30108D0A17CE7,
+				43DC8711FEDDB331D0A17CE7,
+				43DC8712FEDDB331D0A17CE7,
+			);
+			isa = PBXAggregateTarget;
+			name = World;
+			productName = World;
+			shouldUseHeadermap = 0;
+		};
+		04E694EFFED30093D0A17CE7 = {
+			buildPhases = (
+				04E694F0FED30093D0A17CE7,
+				04E694F1FED30093D0A17CE7,
+				04E694F2FED30093D0A17CE7,
+				04E694F3FED30093D0A17CE7,
+				04E694F4FED30093D0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_VERSION = A;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-I$(SRCROOT)  -I$(SYMROOT) ";
+				OTHER_LDFLAGS = "-L$(SYMROOT)";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				6106C779FEDC6816D0A17CE7,
+			);
+			isa = PBXFrameworkTarget;
+			name = YarrowClient;
+			productInstallPath = /Local/Library/Frameworks;
+			productName = YarrowClient;
+			productReference = 04E694E9FED30093D0A17CE7;
+			productSettings = {
+				CFBundleDevelopmentRegion = English;
+				CFBundleExecutable = "";
+				CFBundleGetInfoString = "";
+				CFBundleIconFile = "";
+				CFBundleIdentifier = "";
+				CFBundleInfoDictionaryVersion = 6.0;
+				CFBundleName = "";
+				CFBundlePackageType = FMWK;
+				CFBundleShortVersionString = "";
+				CFBundleSignature = "????";
+				CFBundleVersion = 0.0.1d1;
+			};
+			shouldUseHeadermap = 0;
+		};
+		04E694F0FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				04E69552FED30608D0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		04E694F1FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		04E694F2FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				6106C77AFEDC6816D0A17CE7,
+				6106C781FEDC68F3D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		04E694F3FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				0C1E98FCFED45995D0A17CE7,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		04E694F4FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		04E694F5FED30093D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 04E694F6FED30093D0A17CE7;
+		};
+		04E694F6FED30093D0A17CE7 = {
+			buildPhases = (
+				04E694F7FED30093D0A17CE7,
+				04E694F8FED30093D0A17CE7,
+				04E694F9FED30093D0A17CE7,
+				04E694FAFED30093D0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-DDEBUG -I$(SRCROOT) -I$(SYMROOT)/include  -I$(SYMROOT) ";
+				OTHER_LDFLAGS = "-L$(SYMROOT) -lYarrowCore";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-format -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				04E69505FED30108D0A17CE7,
+				6106C776FEDC6816D0A17CE7,
+			);
+			isa = PBXLibraryTarget;
+			name = YarrowServer;
+			productName = libYarrowServer.a;
+			productReference = 04E694EAFED30093D0A17CE7;
+			shouldUseHeadermap = 0;
+		};
+		04E694F7FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				04E69547FED30594D0A17CE7,
+				04E69548FED30594D0A17CE7,
+				04E69559FED31996D0A17CE7,
+				04E69564FED355A1D0A17CE7,
+				0C1E98F6FED35C9BD0A17CE7,
+				0C1E98FEFED464D0D0A17CE7,
+				6106C777FEDC6816D0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		04E694F8FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				04E6954FFED30608D0A17CE7,
+				04E6955AFED31996D0A17CE7,
+				04E6955DFED35405D0A17CE7,
+				0C1E9900FED46617D0A17CE7,
+				162B3B2AFED9E757D0A17CE7,
+				6106C778FEDC6816D0A17CE7,
+				6106C77FFEDC68F3D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		04E694F9FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		04E694FAFED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		04E694FBFED30093D0A17CE7 = {
+			buildPhases = (
+				04E694FCFED30093D0A17CE7,
+				04E694FDFED30093D0A17CE7,
+				04E694FEFED30093D0A17CE7,
+				04E694FFFED30093D0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-I$(SRCROOT)";
+				OTHER_LDFLAGS = "-L$(SYMROOT) -lzlibcomp";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				04E69506FED30108D0A17CE7,
+			);
+			isa = PBXLibraryTarget;
+			name = YarrowCore;
+			productInstallPath = /usr/local/lib;
+			productName = libYarrowCore.a;
+			productReference = 04E694EBFED30093D0A17CE7;
+			shouldUseHeadermap = 0;
+		};
+		04E694FCFED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				04E69531FED302B0D0A17CE7,
+				04E69532FED302B0D0A17CE7,
+				04E69533FED302B0D0A17CE7,
+				04E69534FED302B0D0A17CE7,
+				04E69535FED302B0D0A17CE7,
+				04E69536FED302B0D0A17CE7,
+				04E69537FED302B0D0A17CE7,
+				04E69538FED302B0D0A17CE7,
+				04E69539FED302B0D0A17CE7,
+				04E6953AFED302B0D0A17CE7,
+				04E6953BFED302B0D0A17CE7,
+				04E6953CFED302B0D0A17CE7,
+				04E6953DFED302B0D0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		04E694FDFED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				04E6953EFED302B0D0A17CE7,
+				04E6953FFED302B0D0A17CE7,
+				04E69540FED302B0D0A17CE7,
+				04E69541FED302B0D0A17CE7,
+				04E69543FED302B0D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		04E694FEFED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		04E694FFFED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		04E69500FED30093D0A17CE7 = {
+			buildPhases = (
+				04E69501FED30093D0A17CE7,
+				04E69502FED30093D0A17CE7,
+				04E69503FED30093D0A17CE7,
+				04E69504FED30093D0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLibraryTarget;
+			name = "zlib compress";
+			productName = libzlibcomp.a;
+			productReference = 04E694ECFED30093D0A17CE7;
+			shouldUseHeadermap = 0;
+		};
+		04E69501FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				04E69515FED301E6D0A17CE7,
+				04E69516FED301E6D0A17CE7,
+				04E69517FED301E6D0A17CE7,
+				04E69518FED301E6D0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		04E69502FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				04E69519FED301E6D0A17CE7,
+				04E6951AFED301E6D0A17CE7,
+				04E6951BFED301E6D0A17CE7,
+				04E6951CFED301E6D0A17CE7,
+				04E6951DFED301E6D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		04E69503FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		04E69504FED30093D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		04E69505FED30108D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 04E694FBFED30093D0A17CE7;
+		};
+		04E69506FED30108D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 04E69500FED30093D0A17CE7;
+		};
+		04E69507FED30108D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 04E694EFFED30093D0A17CE7;
+		};
+		04E69508FED301E6D0A17CE7 = {
+			children = (
+				04E6954AFED30608D0A17CE7,
+				6106C773FEDC6816D0A17CE7,
+				0C1E98FBFED45995D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = YarrowClient;
+			refType = 4;
+		};
+		04E69509FED301E6D0A17CE7 = {
+			children = (
+				04E69544FED30594D0A17CE7,
+				04E6954CFED30608D0A17CE7,
+				04E69545FED30594D0A17CE7,
+				162B3B29FED9E757D0A17CE7,
+				04E69557FED31996D0A17CE7,
+				04E69558FED31996D0A17CE7,
+				04E69563FED355A1D0A17CE7,
+				04E6955CFED35405D0A17CE7,
+				0C1E98FDFED464D0D0A17CE7,
+				0C1E98FFFED46617D0A17CE7,
+				6106C775FEDC6816D0A17CE7,
+				6106C774FEDC6816D0A17CE7,
+				0C1E98F5FED35C9BD0A17CE7,
+				07DD2236FEED91E4D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = YarrowServer;
+			path = "";
+			refType = 4;
+		};
+		04E6950AFED301E6D0A17CE7 = {
+			children = (
+				04E69521FED302B0D0A17CE7,
+				04E69523FED302B0D0A17CE7,
+				04E69522FED302B0D0A17CE7,
+				04E69524FED302B0D0A17CE7,
+				04E69525FED302B0D0A17CE7,
+				04E69527FED302B0D0A17CE7,
+				04E69526FED302B0D0A17CE7,
+				04E69528FED302B0D0A17CE7,
+				04E6952AFED302B0D0A17CE7,
+				04E69529FED302B0D0A17CE7,
+				04E6952CFED302B0D0A17CE7,
+				04E6952BFED302B0D0A17CE7,
+				04E6952EFED302B0D0A17CE7,
+				04E6952FFED302B0D0A17CE7,
+				04E6951EFED302B0D0A17CE7,
+				04E6951FFED302B0D0A17CE7,
+				04E69520FED302B0D0A17CE7,
+				04E69530FED302B0D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = YarrowCoreLib;
+			path = "";
+			refType = 4;
+		};
+		04E6950BFED301E6D0A17CE7 = {
+			children = (
+				04E6950CFED301E6D0A17CE7,
+				04E6950DFED301E6D0A17CE7,
+				04E69511FED301E6D0A17CE7,
+				04E6950EFED301E6D0A17CE7,
+				04E69512FED301E6D0A17CE7,
+				04E6950FFED301E6D0A17CE7,
+				04E69514FED301E6D0A17CE7,
+				04E69510FED301E6D0A17CE7,
+				04E69513FED301E6D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = zlib;
+			path = "";
+			refType = 4;
+		};
+		04E6950CFED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = adler32.c;
+			path = zlib/adler32.c;
+			refType = 4;
+		};
+		04E6950DFED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = compress.c;
+			path = zlib/compress.c;
+			refType = 4;
+		};
+		04E6950EFED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = deflate.c;
+			path = zlib/deflate.c;
+			refType = 4;
+		};
+		04E6950FFED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = trees.c;
+			path = zlib/trees.c;
+			refType = 4;
+		};
+		04E69510FED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = zutil.c;
+			path = zlib/zutil.c;
+			refType = 4;
+		};
+		04E69511FED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = deflate.h;
+			path = zlib/deflate.h;
+			refType = 4;
+		};
+		04E69512FED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = trees.h;
+			path = zlib/trees.h;
+			refType = 4;
+		};
+		04E69513FED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = zlib.h;
+			path = zlib/zlib.h;
+			refType = 4;
+		};
+		04E69514FED301E6D0A17CE7 = {
+			isa = PBXFileReference;
+			name = zutil.h;
+			path = zlib/zutil.h;
+			refType = 4;
+		};
+		04E69515FED301E6D0A17CE7 = {
+			fileRef = 04E69511FED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69516FED301E6D0A17CE7 = {
+			fileRef = 04E69512FED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69517FED301E6D0A17CE7 = {
+			fileRef = 04E69513FED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69518FED301E6D0A17CE7 = {
+			fileRef = 04E69514FED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69519FED301E6D0A17CE7 = {
+			fileRef = 04E6950CFED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6951AFED301E6D0A17CE7 = {
+			fileRef = 04E6950DFED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6951BFED301E6D0A17CE7 = {
+			fileRef = 04E6950EFED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6951CFED301E6D0A17CE7 = {
+			fileRef = 04E6950FFED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6951DFED301E6D0A17CE7 = {
+			fileRef = 04E69510FED301E6D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6951EFED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = WindowsTypesForMac.h;
+			path = YarrowCoreLib/include/WindowsTypesForMac.h;
+			refType = 4;
+		};
+		04E6951FFED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrow.h;
+			path = YarrowCoreLib/include/yarrow.h;
+			refType = 4;
+		};
+		04E69520FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrowUtils.h;
+			path = YarrowCoreLib/include/yarrowUtils.h;
+			refType = 4;
+		};
+		04E69521FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = assertverify.h;
+			path = YarrowCoreLib/src/assertverify.h;
+			refType = 4;
+		};
+		04E69522FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = comp.c;
+			path = YarrowCoreLib/src/comp.c;
+			refType = 4;
+		};
+		04E69523FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = comp.h;
+			path = YarrowCoreLib/src/comp.h;
+			refType = 4;
+		};
+		04E69524FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = entropysources.h;
+			path = YarrowCoreLib/src/entropysources.h;
+			refType = 4;
+		};
+		04E69525FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = macOnly.h;
+			path = YarrowCoreLib/src/macOnly.h;
+			refType = 4;
+		};
+		04E69526FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = prng.c;
+			path = YarrowCoreLib/src/prng.c;
+			refType = 4;
+		};
+		04E69527FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = prng.h;
+			path = YarrowCoreLib/src/prng.h;
+			refType = 4;
+		};
+		04E69528FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = prngpriv.h;
+			path = YarrowCoreLib/src/prngpriv.h;
+			refType = 4;
+		};
+		04E69529FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = sha1mod.c;
+			path = YarrowCoreLib/src/sha1mod.c;
+			refType = 4;
+		};
+		04E6952AFED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = sha1mod.h;
+			path = YarrowCoreLib/src/sha1mod.h;
+			refType = 4;
+		};
+		04E6952BFED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = smf.cpp;
+			path = YarrowCoreLib/src/smf.cpp;
+			refType = 4;
+		};
+		04E6952CFED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = smf.h;
+			path = YarrowCoreLib/src/smf.h;
+			refType = 4;
+		};
+		04E6952EFED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = userdefines.h;
+			path = YarrowCoreLib/src/userdefines.h;
+			refType = 4;
+		};
+		04E6952FFED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = usersources.h;
+			path = YarrowCoreLib/src/usersources.h;
+			refType = 4;
+		};
+		04E69530FED302B0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrowUtils.c;
+			path = YarrowCoreLib/src/yarrowUtils.c;
+			refType = 4;
+		};
+		04E69531FED302B0D0A17CE7 = {
+			fileRef = 04E6951EFED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69532FED302B0D0A17CE7 = {
+			fileRef = 04E6951FFED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69533FED302B0D0A17CE7 = {
+			fileRef = 04E69520FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69534FED302B0D0A17CE7 = {
+			fileRef = 04E69521FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69535FED302B0D0A17CE7 = {
+			fileRef = 04E69523FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69536FED302B0D0A17CE7 = {
+			fileRef = 04E69524FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69537FED302B0D0A17CE7 = {
+			fileRef = 04E69525FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69538FED302B0D0A17CE7 = {
+			fileRef = 04E69527FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69539FED302B0D0A17CE7 = {
+			fileRef = 04E69528FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6953AFED302B0D0A17CE7 = {
+			fileRef = 04E6952AFED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6953BFED302B0D0A17CE7 = {
+			fileRef = 04E6952CFED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6953CFED302B0D0A17CE7 = {
+			fileRef = 04E6952EFED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6953DFED302B0D0A17CE7 = {
+			fileRef = 04E6952FFED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6953EFED302B0D0A17CE7 = {
+			fileRef = 04E69522FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6953FFED302B0D0A17CE7 = {
+			fileRef = 04E69526FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69540FED302B0D0A17CE7 = {
+			fileRef = 04E69529FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69541FED302B0D0A17CE7 = {
+			fileRef = 04E6952BFED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69543FED302B0D0A17CE7 = {
+			fileRef = 04E69530FED302B0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69544FED30594D0A17CE7 = {
+			isa = PBXFileReference;
+			name = debug.h;
+			path = YarrowServer/debug.h;
+			refType = 4;
+		};
+		04E69545FED30594D0A17CE7 = {
+			isa = PBXFileReference;
+			name = entropyFile.h;
+			path = YarrowServer/entropyFile.h;
+			refType = 4;
+		};
+		04E69547FED30594D0A17CE7 = {
+			fileRef = 04E69544FED30594D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69548FED30594D0A17CE7 = {
+			fileRef = 04E69545FED30594D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6954AFED30608D0A17CE7 = {
+			isa = PBXFileReference;
+			name = YarrowClient.h;
+			path = YarrowClient/YarrowClient.h;
+			refType = 4;
+		};
+		04E6954CFED30608D0A17CE7 = {
+			isa = PBXFileReference;
+			name = debug.c;
+			path = YarrowServer/debug.c;
+			refType = 4;
+		};
+		04E6954FFED30608D0A17CE7 = {
+			fileRef = 04E6954CFED30608D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69552FED30608D0A17CE7 = {
+			fileRef = 04E6954AFED30608D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69557FED31996D0A17CE7 = {
+			isa = PBXFileReference;
+			name = MacYarrow_OSX.h;
+			path = YarrowServer/MacYarrow_OSX.h;
+			refType = 4;
+		};
+		04E69558FED31996D0A17CE7 = {
+			isa = PBXFileReference;
+			name = MacYarrow_OSX.cpp;
+			path = YarrowServer/MacYarrow_OSX.cpp;
+			refType = 4;
+		};
+		04E69559FED31996D0A17CE7 = {
+			fileRef = 04E69557FED31996D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6955AFED31996D0A17CE7 = {
+			fileRef = 04E69558FED31996D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E6955CFED35405D0A17CE7 = {
+			isa = PBXFileReference;
+			name = systemEntropy.c;
+			path = YarrowServer/systemEntropy.c;
+			refType = 4;
+		};
+		04E6955DFED35405D0A17CE7 = {
+			fileRef = 04E6955CFED35405D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E69563FED355A1D0A17CE7 = {
+			isa = PBXFileReference;
+			name = systemEntropy.h;
+			path = YarrowServer/systemEntropy.h;
+			refType = 4;
+		};
+		04E69564FED355A1D0A17CE7 = {
+			fileRef = 04E69563FED355A1D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		07DD2236FEED91E4D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			name = CarbonCore.framework;
+			path = /System/Library/Frameworks/CarbonCore.framework;
+			refType = 0;
+		};
+		07DD2238FEED926BD0A17CE7 = {
+			isa = PBXFrameworkReference;
+			name = CarbonCore.framework;
+			path = /System/Library/Frameworks/CarbonCore.framework;
+			refType = 0;
+		};
+		07DD2239FEED926BD0A17CE7 = {
+			fileRef = 07DD2238FEED926BD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0C1E98F5FED35C9BD0A17CE7 = {
+			isa = PBXFileReference;
+			name = kdebug_private.h;
+			path = YarrowServer/kdebug_private.h;
+			refType = 4;
+		};
+		0C1E98F6FED35C9BD0A17CE7 = {
+			fileRef = 0C1E98F5FED35C9BD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0C1E98FBFED45995D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			path = cdsa_utilities.framework;
+			refType = 3;
+		};
+		0C1E98FCFED45995D0A17CE7 = {
+			fileRef = 0C1E98FBFED45995D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0C1E98FDFED464D0D0A17CE7 = {
+			isa = PBXFileReference;
+			name = waitingThread.h;
+			path = YarrowServer/waitingThread.h;
+			refType = 4;
+		};
+		0C1E98FEFED464D0D0A17CE7 = {
+			fileRef = 0C1E98FDFED464D0D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0C1E98FFFED46617D0A17CE7 = {
+			isa = PBXFileReference;
+			name = waitingThread.cpp;
+			path = YarrowServer/waitingThread.cpp;
+			refType = 4;
+		};
+		0C1E9900FED46617D0A17CE7 = {
+			fileRef = 0C1E98FFFED46617D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		162B3B29FED9E757D0A17CE7 = {
+			isa = PBXFileReference;
+			name = entropyFileUnix.c;
+			path = YarrowServer/entropyFileUnix.c;
+			refType = 4;
+		};
+		162B3B2AFED9E757D0A17CE7 = {
+			fileRef = 162B3B29FED9E757D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		43DC8711FEDDB331D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 6106C789FEDC6E50D0A17CE7;
+		};
+		43DC8712FEDDB331D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 6106C78FFEDC6E50D0A17CE7;
+		};
+		6106C76EFEDC677AD0A17CE7 = {
+			children = (
+				6106C76FFEDC677AD0A17CE7,
+				6106C770FEDC677AD0A17CE7,
+				6106C771FEDC677AD0A17CE7,
+				6106C77BFEDC685ED0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "MIG RPC";
+			refType = 4;
+		};
+		6106C76FFEDC677AD0A17CE7 = {
+			isa = PBXFileReference;
+			path = Makefile;
+			refType = 4;
+		};
+		6106C770FEDC677AD0A17CE7 = {
+			isa = PBXFileReference;
+			path = yarrowMigTypes.h;
+			refType = 4;
+		};
+		6106C771FEDC677AD0A17CE7 = {
+			isa = PBXFileReference;
+			path = yarrowServer.defs;
+			refType = 4;
+		};
+		6106C772FEDC677AD0A17CE7 = {
+			buildArgumentsString = "\"$ACTION\" \"SYMROOT=$(SYMROOT)\" \"SRCROOT=$(SRCROOT)\"";
+			buildPhases = (
+			);
+			buildSettings = {
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = "MIG RPC";
+			productName = "MIG RPC";
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 287;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		6106C773FEDC6816D0A17CE7 = {
+			isa = PBXFileReference;
+			name = YarrowClient_OSX.cpp;
+			path = YarrowClient/YarrowClient_OSX.cpp;
+			refType = 4;
+		};
+		6106C774FEDC6816D0A17CE7 = {
+			isa = PBXFileReference;
+			name = YarrowServer_OSX.cpp;
+			path = YarrowServer/YarrowServer_OSX.cpp;
+			refType = 4;
+		};
+		6106C775FEDC6816D0A17CE7 = {
+			isa = PBXFileReference;
+			name = YarrowServer_OSX.h;
+			path = YarrowServer/YarrowServer_OSX.h;
+			refType = 4;
+		};
+		6106C776FEDC6816D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 6106C772FEDC677AD0A17CE7;
+		};
+		6106C777FEDC6816D0A17CE7 = {
+			fileRef = 6106C775FEDC6816D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C778FEDC6816D0A17CE7 = {
+			fileRef = 6106C774FEDC6816D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C779FEDC6816D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 6106C772FEDC677AD0A17CE7;
+		};
+		6106C77AFEDC6816D0A17CE7 = {
+			fileRef = 6106C773FEDC6816D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C77BFEDC685ED0A17CE7 = {
+			children = (
+				6106C77CFEDC68F3D0A17CE7,
+				6106C77DFEDC68F3D0A17CE7,
+				6106C77EFEDC68F3D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = Generated;
+			refType = 4;
+		};
+		6106C77CFEDC68F3D0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrowMigServer.cpp;
+			path = derived_src/yarrowMigServer.cpp;
+			refType = 3;
+		};
+		6106C77DFEDC68F3D0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrowMigUser.cpp;
+			path = derived_src/yarrowMigUser.cpp;
+			refType = 3;
+		};
+		6106C77EFEDC68F3D0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrowMig.h;
+			path = include/yarrowMig.h;
+			refType = 3;
+		};
+		6106C77FFEDC68F3D0A17CE7 = {
+			fileRef = 6106C77CFEDC68F3D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C781FEDC68F3D0A17CE7 = {
+			fileRef = 6106C77DFEDC68F3D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C784FEDC6E50D0A17CE7 = {
+			children = (
+				6106C785FEDC6E50D0A17CE7,
+				6106C786FEDC6E50D0A17CE7,
+				6106C799FEDC6F00D0A17CE7,
+				6106C79DFEDC6F4DD0A17CE7,
+				07DD2238FEED926BD0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "test harness";
+			path = "";
+			refType = 4;
+		};
+		6106C785FEDC6E50D0A17CE7 = {
+			isa = PBXFileReference;
+			name = clientTest.cpp;
+			path = testHarness/clientTest.cpp;
+			refType = 4;
+		};
+		6106C786FEDC6E50D0A17CE7 = {
+			isa = PBXFileReference;
+			name = serverDaemon.cpp;
+			path = testHarness/serverDaemon.cpp;
+			refType = 4;
+		};
+		6106C787FEDC6E50D0A17CE7 = {
+			isa = PBXFileReference;
+			path = testServer;
+			refType = 3;
+		};
+		6106C788FEDC6E50D0A17CE7 = {
+			isa = PBXFileReference;
+			path = testClient;
+			refType = 3;
+		};
+		6106C789FEDC6E50D0A17CE7 = {
+			buildPhases = (
+				6106C78AFEDC6E50D0A17CE7,
+				6106C78BFEDC6E50D0A17CE7,
+				6106C78DFEDC6E50D0A17CE7,
+				6106C78EFEDC6E50D0A17CE7,
+			);
+			buildSettings = {
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-I$(SRCROOT)";
+				OTHER_LDFLAGS = "-lYarrowServer -L$(SYMROOT)";
+				OTHER_REZFLAGS = "";
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				6106C79EFEDC6F4DD0A17CE7,
+			);
+			isa = PBXToolTarget;
+			name = testServer;
+			productInstallPath = /usr/local/bin;
+			productName = testServer;
+			productReference = 6106C787FEDC6E50D0A17CE7;
+			shouldUseHeadermap = 0;
+		};
+		6106C78AFEDC6E50D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		6106C78BFEDC6E50D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				6106C78CFEDC6E50D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		6106C78CFEDC6E50D0A17CE7 = {
+			fileRef = 6106C786FEDC6E50D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C78DFEDC6E50D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				6106C79BFEDC6F00D0A17CE7,
+				07DD2239FEED926BD0A17CE7,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		6106C78EFEDC6E50D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		6106C78FFEDC6E50D0A17CE7 = {
+			buildPhases = (
+				6106C790FEDC6E50D0A17CE7,
+				6106C791FEDC6E50D0A17CE7,
+				6106C793FEDC6E50D0A17CE7,
+				6106C794FEDC6E50D0A17CE7,
+			);
+			buildSettings = {
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				6106C79FFEDC6F4DD0A17CE7,
+			);
+			isa = PBXToolTarget;
+			name = testClient;
+			productInstallPath = /usr/local/bin;
+			productName = testClient;
+			productReference = 6106C788FEDC6E50D0A17CE7;
+			shouldUseHeadermap = 0;
+		};
+		6106C790FEDC6E50D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		6106C791FEDC6E50D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				6106C792FEDC6E50D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		6106C792FEDC6E50D0A17CE7 = {
+			fileRef = 6106C785FEDC6E50D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C793FEDC6E50D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				6106C7A0FEDC6F4DD0A17CE7,
+				6106C7A1FEDC6F4DD0A17CE7,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		6106C794FEDC6E50D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		6106C799FEDC6F00D0A17CE7 = {
+			isa = PBXFrameworkReference;
+			path = cdsa_utilities.framework;
+			refType = 3;
+		};
+		6106C79BFEDC6F00D0A17CE7 = {
+			fileRef = 6106C799FEDC6F00D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C79DFEDC6F4DD0A17CE7 = {
+			isa = PBXFrameworkReference;
+			path = YarrowClient.framework;
+			refType = 3;
+		};
+		6106C79EFEDC6F4DD0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 04E694F6FED30093D0A17CE7;
+		};
+		6106C79FFEDC6F4DD0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 04E694EFFED30093D0A17CE7;
+		};
+		6106C7A0FEDC6F4DD0A17CE7 = {
+			fileRef = 6106C799FEDC6F00D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6106C7A1FEDC6F4DD0A17CE7 = {
+			fileRef = 6106C79DFEDC6F4DD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+	};
+	rootObject = 04E694E6FED2FFD1D0A17CE7;
+}
diff --git a/SecurityServer/MacYarrow/YarrowServer/MacYarrow_OSX.cpp b/SecurityServer/MacYarrow/YarrowServer/MacYarrow_OSX.cpp
new file mode 100644
index 00000000..b2e3d9c9
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/MacYarrow_OSX.cpp
@@ -0,0 +1,294 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		MacYarrow_OSX.cpp
+
+	Contains:	Yarrow RNG, OS X version.
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		02/29/00	dpm		Created.
+ 
+*/
+
+#include "MacYarrow_OSX.h"
+#include "entropyFile.h"
+#include "systemEntropy.h"
+#include <debug.h>
+#include <Security/debugging.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+/* moved to Carbon.framework, FIXME */
+// #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/Power.h>	/* HardDiskPowered() */
+
+static int HardDiskPowered() { return 1; }
+/* end fixme */
+
+
+#define QUICK_TEST		0
+
+#if		QUICK_TEST
+
+/*
+ * We collect system entropy every SYSTEM_ENTROPY_COLLECT_INTERVAL milliseconds.
+ */
+#define SYSTEM_ENTROPY_COLLECT_INTERVAL		(10 * 1000)
+
+/*
+ * Update system entropy file every UPDATE_SYSTEM_ENTROPY_FILE seconds.
+ */
+#define UPDATE_SYSTEM_ENTROPY_FILE			(30)
+
+#else	/* QUICK_TEST */
+
+/* normal values */
+
+#define SYSTEM_ENTROPY_COLLECT_INTERVAL		(10 * 60 * 1000)
+#define UPDATE_SYSTEM_ENTROPY_FILE			(60 * 60)
+
+#endif	/* QUICK_TEST */
+
+/*
+ * State of pending timer. 
+ */
+typedef enum {
+	kYTSUninitialized = 0,
+	kYTSCollecting,			// while gathering entropy
+	kYTSCollectingInit,		// while gathering entropy the first time
+	kYTSSleeping			// idle
+} yarrowTimerState;
+
+/* 
+ * When collecting system entropy, try for this many bytes. 
+ */
+#define SYSTEM_ENTROPY_SIZE			20
+
+/*
+ * Maintain an entropy file of this size.
+ */
+#define ENTROPY_FILE_SIZE			20
+
+/*
+ * Microseconds to crunch in prngAllowReseed() 
+ */
+#define RESEED_TICKS				1000
+
+/* 
+ * The single process-wide yarrow PRNG object and associated timer state.
+ * All of the code in this module runs in a single thread, owned by 
+ * the YarrowServer object, so no locking is needed.  
+ * 
+ */
+static yarrowTimerState timerState = kYTSUninitialized;
+static struct timeval	lastFileUpdate;
+
+static int gDevRandomRef = -1;
+
+/*
+ * Reusable init. Currently called from the YarrowServer constructor. 
+ */
+OSStatus yarrowServerInit(
+	const char *entropyFilePath,
+	unsigned *firstTimeout)			// RETURNED, first timeout in milliseconds
+{
+    UInt8               entropyFileData[ENTROPY_FILE_SIZE];
+    UInt32              actLen;
+    OSErr               ortn;
+
+    /* set up prng */
+    gDevRandomRef = open ("/dev/random", O_RDWR);
+    if (gDevRandomRef == -1) {
+        return ioErr;
+    }
+
+    /*
+     * read entropy file, add contents to system entropy pool.
+     * It's not an error if there is no entropy file; this
+     * should only happen the first time this server runs on a given
+     * system.
+     */
+    gettimeofday(&lastFileUpdate, NULL);
+    setEntropyFilePath(entropyFilePath);
+    ortn = readEntropyFile(entropyFileData,
+        ENTROPY_FILE_SIZE,
+        &actLen);
+    if((ortn == noErr) && (actLen > 0))
+        write(gDevRandomRef, entropyFileData, actLen);
+    memset(entropyFileData, 0, actLen);
+
+    /*
+     * Start collecting system entropy; schedule a timer event to gather
+     * it and add it to the pool.
+     */
+    systemEntropyBegin(SYSTEM_ENTROPY_SIZE);
+    *firstTimeout = SYSTEM_ENTROPY_COLLECT_TIME;
+    timerState = kYTSCollectingInit;
+    
+    return noErr;
+}
+
+
+void yarrowServerFini()
+{
+}
+
+/* 
+ * Add some entropy to the pool. The only "known" failure here is a 
+ * result of a failure of this library'e early init.
+ */
+OSStatus yarrowAddEntropy(
+	UInt8	*bytes,
+	UInt32	numBytes,
+	UInt32	bitsOfEntropy,
+	unsigned *nextTimeout)		// RETURNED, next timeout in ms,  0 means none (leave
+								//   timer alone)
+{
+    OSStatus rCode = noErr;
+    
+    if (gDevRandomRef == -1) { // did the system not open properly?
+        return ioErr;
+    }
+    
+    int result = write (gDevRandomRef, bytes, numBytes);
+    if (result == -1) {
+        rCode = ioErr;
+    }
+    
+    debug("yarrow", "adding %ld bytes of entropy", numBytes);
+    
+	/* 
+	 * Asynchronously - because this can be time-consuming - 
+	 * add some system entropy too. This prevents clients from 
+	 * overwhelming the entropy pool with its own (untrusted) data.
+	 * Skip this step if we happen to be collecting entropy at the 
+	 * moment.
+	 */
+	if(timerState == kYTSSleeping) {
+		systemEntropyBegin(SYSTEM_ENTROPY_SIZE);
+		timerState = kYTSCollecting;
+		*nextTimeout = SYSTEM_ENTROPY_COLLECT_TIME;
+	}
+    
+	return noErr;
+}
+
+
+/* 
+ * Get some random data. Caller mallocs the memory.
+ */
+OSStatus yarrowGetRandomBytes(
+	UInt8	*bytes,	
+	UInt32	numBytes)
+{
+    if (gDevRandomRef == -1) {
+        return ioErr;
+    }
+    
+    int result = read (gDevRandomRef, bytes, numBytes);
+    if (result == -1) {
+        return ioErr;
+    } else {
+        return noErr;
+    }
+}
+
+
+/* 
+ * Handle timer event. Returns next timeout in milliseconds.
+ */
+unsigned yarrowTimerEvent()
+{
+	UInt8				sysEntropyData[SYSTEM_ENTROPY_SIZE];
+	UInt32 				numSysBytes;
+	UInt32 				numSysEntropyBits;
+	int 				rtn;
+	unsigned			nextTimeout;
+	
+	switch(timerState) {
+		case kYTSCollecting:
+		case kYTSCollectingInit:
+			/* 
+			 * Entropy collection in progress; finish the operation,
+			 * gather result, add to entropy pool.
+			 */
+			debug("yarrowtimer", "collecting system entropy");
+            nextTimeout = SYSTEM_ENTROPY_COLLECT_INTERVAL;
+			if(rtn = systemEntropyCollect(sysEntropyData, SYSTEM_ENTROPY_SIZE, 
+					&numSysBytes, &numSysEntropyBits)) {
+				errorLog1("systemEntropyCollect() returned %d; aborting\n",
+					rtn);
+				timerState = kYTSSleeping;
+				break;
+			}
+
+            unsigned dummy;
+            yarrowAddEntropy (sysEntropyData, numSysBytes, 0, &dummy);
+
+			timerState = kYTSSleeping;
+			
+			/* 
+			 * Is it time to update the system entropy file? 
+			 */
+			struct timeval 	now;
+			
+			gettimeofday(&now, NULL);
+			if( ( (now.tv_sec - lastFileUpdate.tv_sec) > UPDATE_SYSTEM_ENTROPY_FILE) &&
+				HardDiskPowered() ) {
+				
+				UInt8 entropyFileData[ENTROPY_FILE_SIZE];
+				OSErr ortn;
+	
+				debug("yarrow", "writing new entropy file");
+                
+                yarrowGetRandomBytes (entropyFileData, ENTROPY_FILE_SIZE);
+
+				ortn = writeEntropyFile(entropyFileData, ENTROPY_FILE_SIZE);
+				if(ortn) {
+					errorLog1("....writeEntropyFile returned %d\n", ortn);
+				}
+				lastFileUpdate = now;
+			}
+			break;
+			
+		case kYTSSleeping:
+			/* start to gather entropy */
+			debug("yarrowtimer", "start gathering entropy");
+			systemEntropyBegin(SYSTEM_ENTROPY_SIZE);
+			timerState = kYTSCollecting;
+			nextTimeout = SYSTEM_ENTROPY_COLLECT_TIME;
+			break;
+			
+		default:
+			errorLog1("yarrowTimerEvent with timerState %d\n", timerState);
+			nextTimeout = SYSTEM_ENTROPY_COLLECT_INTERVAL;
+			break;
+	}
+	debug("yarrowtimer", "timer rescheduling for %d msecs", nextTimeout);
+	return nextTimeout;
+}
+
diff --git a/SecurityServer/MacYarrow/YarrowServer/MacYarrow_OSX.h b/SecurityServer/MacYarrow/YarrowServer/MacYarrow_OSX.h
new file mode 100644
index 00000000..91e7c8de
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/MacYarrow_OSX.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		MacYarrow_OSX.h
+
+	Contains:	Yarrow RNG, OS X version
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		02/29/00	dpm		Created. 
+ 
+*/
+
+#ifndef	_MAC_YARROW_OSX_H_
+#define _MAC_YARROW_OSX_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Resusable init. entropyFilePath is optional; if NULL, we'll use our
+ * own hard-coded default.
+ */
+OSStatus yarrowServerInit(
+	const char *entropyFilePath,
+	unsigned *firstTimeout);			// RETURNED, first timeout in milliseconds
+
+void yarrowServerFini();
+
+/* 
+ * Add some entropy to the pool. The only "known" failure here is a 
+ * result of a failure of this library's early init.
+ */
+OSStatus yarrowAddEntropy(
+	UInt8	*bytes,
+	UInt32	numBytes,
+	UInt32	bitsOfEntropy,
+	unsigned *nextTimeout);		// RETURNED, next timeout in ms,  0 means none (leave
+								//   timer alone)
+					
+/* 
+ * Get some random data. Caller mallocs the memory.
+ */
+OSStatus yarrowGetRandomBytes(
+	UInt8	*bytes,	
+	UInt32	numBytes);
+
+/* 
+ * Handle timer event. Returns next timeout in milliseconds.
+ */
+unsigned yarrowTimerEvent();
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _MAC_YARROW_OSX_H_*/
+
diff --git a/SecurityServer/MacYarrow/YarrowServer/YarrowLib_OS9.mcp.exp b/SecurityServer/MacYarrow/YarrowServer/YarrowLib_OS9.mcp.exp
new file mode 100644
index 00000000..26ebd352
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/YarrowLib_OS9.mcp.exp
@@ -0,0 +1 @@
+# only export YarrowClient
getRandomBytes__12YarrowClientFPUcUl		# YarrowClient::getRandomBytes(unsigned char*,unsigned long)
addEntropy__12YarrowClientFPUcUlUl		# YarrowClient::addEntropy(unsigned char*,unsigned long,unsigned long)
__dt__12YarrowClientFv		# YarrowClient::~YarrowClient()
__ct__12YarrowClientFv		# YarrowClient::YarrowClient()

\ No newline at end of file
diff --git a/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OS9.c b/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OS9.c
new file mode 100644
index 00000000..37364669
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OS9.c
@@ -0,0 +1,328 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		YarrowServer_OS9.c
+
+	Contains:	Yarrow Server, OS 9 version.
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		02/29/00	dpm		Created.
+ 
+*/
+
+#include <yarrowUtils.h>
+#include "YarrowServer_OS9.h"
+#include "entropyFile.h"
+#include <debug.h>
+#include <yarrow.h>
+#include <Errors.h>
+#include <Timer.h>		/* Microseconds() */
+#include <LowMem.h>		/* LMGetTicks() */
+
+/* the single system-wide yarrow PRNG object */
+static PrngRef	prng = NULL;
+
+/*
+ * We collect system entropy every ENTROPY_COLLECT_INTERVAL seconds.
+ */
+#define ENTROPY_COLLECT_INTERVAL	(10 * 60)
+
+/* 
+ * When collecting system entropy, try for this many bytes. 
+ */
+#define SYSTEM_ENTROPY_SIZE			20
+
+/*
+ * Maintain an entropy file of this size.
+ */
+#define ENTROPY_FILE_SIZE			20
+
+/*
+ * Microseconds to crunch in prngAllowReseed() 
+ */
+#define RESEED_TICKS				100
+
+
+#pragma mark -
+#pragma mark * * * Private Functions * * * 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+OSErr _init(void *initBlk);
+void _fini(void);
+int main();
+#ifdef __cplusplus
+}
+#endif
+
+static void
+systemEntropy(
+	UInt8 *buf,
+	UInt32 bufSize,
+	UInt32 *numBytes,		// RETURNED - number of bytes obtained
+	UInt32 *bitsOfEntropy);	// RETURNED - est. amount of entropy
+
+
+/*
+ * Called once on initial library load. 
+ */
+OSErr 
+_init(void *initBlk)
+{
+	prng_error_status	prtn;
+	UInt8				entropyFileData[ENTROPY_FILE_SIZE];
+	UInt8				sysEntropyData[SYSTEM_ENTROPY_SIZE];
+	UInt32				actLen;
+	OSErr				ortn;
+	UInt32				entropyBits;
+	
+	/* set up prng and its lock */
+	prtn = prngInitialize(&prng);
+	if(prtn) {
+		errorLog1("_init: prngInitialize returned %s\n", perrorString(prtn));
+		return perrorToOSErr(prtn);
+	}
+
+	/* TBD - the mutex */
+	
+	/*
+	 * read entropy file, add contents to system entropy pool.
+	 * It's not an error if there is no entropy file; this
+	 * should only happen the first time this server runs on a given
+	 * system.
+	 */
+	ortn = readEntropyFile(entropyFileData, 
+		ENTROPY_FILE_SIZE,
+		&actLen);
+	if((ortn == noErr) && (actLen > 0)) {
+		prtn = prngInput(prng, 
+			entropyFileData,
+			actLen,
+			ENTROPY_FILE_SOURCE,
+			actLen * 8);		// assume total entropy here 
+		if(prtn) {
+			errorLog1("_init: prngInput returned %s\n", 
+				perrorString(prtn));
+			return perrorToOSErr(prtn);
+		}
+	}
+	trashMemory(entropyFileData, actLen);
+	
+	/*
+	 * collect system entropy, add to system entropy pool
+	 */
+	systemEntropy(sysEntropyData,
+		SYSTEM_ENTROPY_SIZE,
+		&actLen,
+		&entropyBits);
+	if(actLen > 0) {
+		prtn = prngInput(prng, 
+			entropyFileData,
+			actLen,
+			SYSTEM_SOURCE,
+			entropyBits);	
+		if(prtn) {
+			errorLog1("_init: prngInput returned %s\n", 
+				perrorString(prtn));
+			return perrorToOSErr(prtn);
+		}
+	}
+	trashMemory(sysEntropyData, actLen);
+	
+	/*
+	 * force reseed
+	 */
+	prtn = prngForceReseed(prng, RESEED_TICKS);
+	if(prtn) {
+		errorLog1("_init: prngForceReseed returned %s\n", 
+			perrorString(prtn));
+		return perrorToOSErr(prtn);
+	}
+	
+	/*
+	 * get 20 bytes of random data, write to entropy file
+	 */
+	prtn = prngOutput(prng, entropyFileData, ENTROPY_FILE_SIZE);
+	if(prtn) {
+		errorLog1("_init: prngOutput returned %s\n", 
+			perrorString(prtn));
+		return perrorToOSErr(prtn);
+	}
+	ortn = writeEntropyFile(entropyFileData, ENTROPY_FILE_SIZE, false);
+	if(ortn) {
+		return ortn;
+	}
+	/* FIXME -  schedule an entropyCollector() call; */
+	
+	return noErr;
+}
+
+void 
+_fini(void)
+{
+	/* free prng and lock */
+	if(prng != NULL) {
+		prngDestroy(prng);
+		prng = NULL;
+	}
+}
+
+/* 
+ * FIXME - RuntimePPC.dll is referring to this somehow...
+ *
+int main()
+{
+	errorLog0("YarrowServer main() called\n");
+}
+*/
+
+/* 
+ * Lock/unlock prngMutex - I guess these are not technically necessary 
+ * on OS 9
+ */
+static void
+prngLock()
+{
+
+}
+
+static void
+prngUnlock()
+{
+
+}
+
+/*
+ * Get some system entropy. On OS 9 this is pretty lame. 
+ */
+static void
+systemEntropy(
+	UInt8 *buf,
+	UInt32 bufSize,
+	UInt32 *numBytes,		// RETURNED - number of bytes obtained
+	UInt32 *bitsOfEntropy)	// RETURNED - est. amount of entropy
+{
+	UnsignedWide curTime;		/* low 16 bits are pretty good, use 32 */
+	unsigned ticks = 0;				/* low 8 bits are OK, use 16 bits */
+	UInt8 pool[6];
+	UInt8 *pp = pool;
+	
+	Microseconds(&curTime);		/* low 16 bits are pretty good */
+	//ticks = LMGetTicks();
+	*pp++ = curTime.lo & 0xff;
+	*pp++ = curTime.lo >> 8;
+	*pp++ = curTime.lo >> 16;
+	*pp++ = curTime.lo >> 24;
+	*pp++ = ticks & 0xff;
+	*pp   = ticks >> 8;
+	if(bufSize > 6) {
+		bufSize = 6;
+	}
+	BlockMove(pool, buf, bufSize);
+	*numBytes = bufSize;
+	*bitsOfEntropy = 3 * 8;		/* three bytes worth */
+}
+
+/*
+ * Entropy collector - called every ENTROPY_COLLECT_INTERVAL seconds. 
+ */
+static void 
+entropyCollector()
+{
+	/* grab some system entropy
+	 * add to pool
+	 * allow reseed
+	 * if enough time has elapsed {
+	 *		update seed file
+	 * }
+	 * schedule another call
+	 */
+}
+
+#pragma mark -
+#pragma mark * * * Public Functions * * * 
+
+/* 
+ * Add some entropy to the pool. The only "known" failure here is a 
+ * result of a failure of this library'e early init.
+ */
+OSErr yarrowAddEntropy(
+	UInt8	*bytes,
+	UInt32	numBytes,
+	UInt32	bitsOfEntropy)
+{
+	UInt8 				sysEntropy[SYSTEM_ENTROPY_SIZE];
+	UInt32 				numSysBytes;
+	UInt32 				numSysEntropyBits;
+	prng_error_status 	prtn;
+	OSErr 				ortn = noErr;
+	
+	if(prng == NULL) {
+		return notOpenErr;
+	}
+	prngLock();
+	
+	/* add client entropy */
+	prtn = prngInput(prng, bytes, numBytes, CLIENT_SOURCE, bitsOfEntropy);
+	if(prtn) {
+		errorLog1("prngInput returned %s\n", perrorString(prtn));
+		ortn = ioErr;
+		goto done;
+	}
+	
+	/* and some system entropy too - this prevents client from overwhelming
+	 * the entropy pool with its own (untrusted) data */
+	systemEntropy(sysEntropy, SYSTEM_ENTROPY_SIZE, &numSysBytes, 
+		&numSysEntropyBits);
+	prtn = prngInput(prng, sysEntropy, numSysBytes, SYSTEM_SOURCE, 
+		numSysEntropyBits);
+	if(prtn) {
+		errorLog1("prngInput returned %s\n", perrorString(prtn));
+		ortn = ioErr;
+		goto done;
+	}
+	prngAllowReseed(prng, RESEED_TICKS);
+	
+done:
+	prngUnlock();
+	return ortn;
+}
+
+/* 
+ * Get some random data. Caller mallocs the memory.
+ */
+OSErr yarrowGetRandomBytes(
+	UInt8	*bytes,	
+	UInt32	numBytes)
+{
+	if(prng == NULL) {
+		return notOpenErr;
+	}
+	prngLock();
+	prngOutput(prng, bytes, numBytes);
+	prngUnlock();
+	return noErr;
+}
+
diff --git a/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OS9.h b/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OS9.h
new file mode 100644
index 00000000..68711fa5
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OS9.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		YarrowServer_OS9.h
+
+	Contains:	Yarrow Server interface, OS 9 version.
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		02/29/00	dpm		Created. 
+ 
+*/
+
+/*
+ * This interface is only used by the YarrowClient class. It's basically
+ * just a 1-to-1 map of YarrowClient's own public member functions. The
+ * functions declared here are the only exported symbols from this shared
+ * library. 
+ */
+#ifndef	_YARROW_SERVER_OS9_H_
+#define _YARROW_SERVER_OS9_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* 
+ * Add some entropy to the pool. The only "known" failure here is a 
+ * result of a failure of this library'e early init.
+ */
+OSErr yarrowAddEntropy(
+	UInt8	*bytes,
+	UInt32	numBytes,
+	UInt32	bitsOfEntropy);
+					
+/* 
+ * Get some random data. Caller mallocs the memory.
+ */
+OSErr yarrowGetRandomBytes(
+	UInt8	*bytes,	
+	UInt32	numBytes);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _YARROW_SERVER_OS9_H_*/
+
diff --git a/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.cpp b/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.cpp
new file mode 100644
index 00000000..236e94de
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * YarrowServer - Yarrow RNG server object, OSX version
+ */
+#include "YarrowServer_OSX.h"
+#include <mach/mach_error.h>
+#include <sys/errno.h>
+#include <stdio.h>				// debug
+#include <yarrowMigTypes.h>
+#include "MacYarrow_OSX.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <Security/cssmalloc.h>
+
+#define YS_DEBUG		0 
+#if		YS_DEBUG
+#define ysprintf(x)		printf x
+#else
+#define ysprintf(x)
+#endif
+
+using MachPlusPlus::MachServer;
+
+/*
+ * A timer for this module. Just one, and it's always active subsequent to startup.
+ */
+class YarrowTimer : public MachServer::Timer {
+public:
+	YarrowTimer(MachPlusPlus::MachServer &server) :
+		MachServer::Timer(),
+		mServer(server) {}
+		
+	void action();
+	void scheduleTimer(unsigned msFromNow);
+private:
+	MachPlusPlus::MachServer	&mServer;		// to which we do setTimer()
+};
+
+/* 
+ * Timeout event, the sole purpose of this class. Pass on to MacYarrow module.
+ */
+void YarrowTimer::action()
+{
+	unsigned nextTimeout = yarrowTimerEvent();
+	scheduleTimer(nextTimeout);
+}
+
+void YarrowTimer::scheduleTimer(unsigned msFromNow)
+{
+    mServer.setTimer(this, Time::Interval(msFromNow / 1000.0));
+}
+
+/* global, one per process, therefore one per system */
+static YarrowTimer 		*yarrowTimer;
+static CssmAllocator	*cssmAlloc;		// for temp alloc in 
+										//   yarrow_server_getRandomBytes()
+
+YarrowServer::YarrowServer(MachPlusPlus::MachServer &globalServer, const char *entropyFilePath) : 
+	MachServer(YARROW_SERVER_NAME)
+{
+#ifdef TEMPORARY_SEMANTICS
+        MutexLocker ml (gYarrowMutex);
+#endif
+	unsigned firstTimeout;
+	yarrowTimer = new YarrowTimer(globalServer);
+	cssmAlloc = &CssmAllocator::standard();
+	yarrowServerInit(entropyFilePath, &firstTimeout);
+	yarrowTimer->scheduleTimer(firstTimeout);
+}
+
+
+/*
+ * Clean up the server object
+ */
+YarrowServer::~YarrowServer()
+{
+	delete yarrowTimer;		// FIXME - is this safe? Does MachServer do this?
+}
+
+/*
+ * Thread::run() specific to this class, needed because both MachServer
+ * and Thread have a run() method. Called from main(). 
+ */
+void YarrowServer::runYarrow()
+{
+	Thread::run();
+}
+ 
+/*
+ * Run the server. This will not return until the server is forced to exit.
+ */
+void YarrowServer::action() 
+{
+	ysprintf(("YarrowServer: running MachServer\n"));
+	MachServer::run();
+}
+
+
+//
+// The server run-loop function, called out from MachServer
+//
+boolean_t yarrow_server(mach_msg_header_t *, mach_msg_header_t *);
+
+boolean_t YarrowServer::handle(mach_msg_header_t *in, mach_msg_header_t *out)
+{
+	return yarrow_server(in, out);
+}
+
+
+//
+// Handling dead-port notifications
+// FIXME - how is this used?
+//
+void YarrowServer::notifyDeadName(MachPlusPlus::Port port)
+{
+	// forcibly end the Connection
+	// FIXME....endConnection(port, true);
+}
+
+/*
+ * Functions called from server side of MIG interface. 
+ * As far as I can tell, MIG doesn't generate
+ * prototypes for the server side...FIXME....
+ */
+ 
+/* Bracket Macros */
+#define UCSP_ARGS	mach_port_t sport, mach_port_t rport, OSStatus *rcode
+
+kern_return_t 
+yarrow_server_addEntropy(
+	UCSP_ARGS,
+	Data bytes,
+	mach_msg_type_number_t bytesCnt, 
+	UInt32 entBits)
+{
+	unsigned nextTimeout;
+	ysprintf(("yarrow server addEntropy(%02X %02X %02X %02X...) called\n",
+		((UInt8 *)bytes)[0], ((UInt8 *)bytes)[1], ((UInt8 *)bytes)[2],
+		((UInt8 *)bytes)[3]));
+	*rcode = yarrowAddEntropy(static_cast<UInt8 *>(bytes), bytesCnt, entBits,
+		&nextTimeout);
+	if(nextTimeout != 0) {
+		yarrowTimer->scheduleTimer(nextTimeout);
+	}
+	return KERN_SUCCESS;
+}
+
+
+kern_return_t 
+yarrow_server_getRandomBytes(
+	UCSP_ARGS,
+	UInt32 numBytes,					// in
+	Data *bytes,						// out
+	mach_msg_type_number_t *bytesCnt)	// out
+{
+	/*
+	 * We have to allocate here; MIG does a virtual copy back to 
+	 * client. MachServer releases later. 
+	 */
+	void *tempPtr;
+	try {
+		tempPtr = cssmAlloc->malloc(numBytes);
+	}
+	catch(...) {
+		return unix_err(ENOMEM);
+	}
+	MachPlusPlus::MachServer::active().releaseWhenDone(*cssmAlloc, tempPtr);
+	*rcode = yarrowGetRandomBytes(reinterpret_cast<UInt8 *>(tempPtr), numBytes);
+	if(*rcode == noErr) {
+		*bytes = reinterpret_cast<Data>(tempPtr);
+		*bytesCnt = numBytes; 
+	}
+	else {
+		*bytesCnt = 0;
+	}
+	ysprintf(("yarrow server getRandomBytes called; data %02X %02X %02X %02X...\n",
+		((UInt8 *)*bytes)[0], ((UInt8 *)*bytes)[1], ((UInt8 *)*bytes)[2],
+		((UInt8 *)*bytes)[3]));
+	return KERN_SUCCESS;
+}
diff --git a/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.h b/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.h
new file mode 100644
index 00000000..bace99b0
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/YarrowServer_OSX.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * YarrowServer - Yarrow RNG server object
+ */
+#ifndef _YARROW_SERVER_H_
+#define _YARROW_SERVER_H_
+
+#include <Security/machserver.h>
+
+class YarrowServer : public MachPlusPlus::MachServer, public Thread {
+public:
+	YarrowServer(MachPlusPlus::MachServer &globalServer, const char *entropyFilePath = NULL);
+	~YarrowServer();
+	
+	void runYarrow();	
+	
+private:
+	void action();		// Thread action - start up server, etc.
+	
+protected:
+	boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out);
+	void notifyDeadName(MachPlusPlus::Port port);
+	
+};
+
+
+#endif /* _YARROW_SERVER_H_ */
diff --git a/SecurityServer/MacYarrow/YarrowServer/debug.c b/SecurityServer/MacYarrow/YarrowServer/debug.c
new file mode 100644
index 00000000..18017dff
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/debug.c
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		debug.c
+
+	Contains:	Debugging support.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1999 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		12/07/99	dpm		Created.
+ 
+*/
+
+
+#include "debug.h"
+
+#if		DEBUG && !LOG_VIA_PRINTF
+
+#include <string.h>
+#include <Types.h>
+#include <TextUtils.h>
+
+/* common log macros */
+
+/* this one needs a writable string */
+static void logCom(unsigned char *str) {
+	c2pstr((char *)str);
+	DebugStr(str);
+}
+
+/* remaining ones can take constant strings */
+void dblog0(char *str)	{		
+	Str255	outStr;				
+	strcpy((char *)outStr, str);	
+	logCom(outStr);					
+}
+
+void dblog1(char *str, void *arg1)	{				
+	Str255	outStr;						
+	sprintf((char *)outStr, str, arg1);	
+	logCom(outStr);						
+}
+
+void dblog2(char *str, void * arg1, void * arg2)	{				
+	Str255	outStr;								
+	sprintf((char *)outStr, str, arg1, arg2);	
+	logCom(outStr);								
+}
+
+void dblog3(char *str, void * arg1, void * arg2, void * arg3)	{				
+	Str255	outStr;									
+	sprintf((char *)outStr, str, arg1, arg2, arg3);	
+	logCom(outStr);									
+}
+
+void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4)	{				
+	Str255	outStr;											
+	sprintf((char *)outStr, str, arg1, arg2, arg3, arg4);	
+	logCom(outStr);											
+}
+
+#endif	/* DEBUG */
+
+#include <stdlib.h>
+
+void yarrowPanic(const char *errStr)
+{
+	errorLog0((char *)errStr);
+	exit(1);
+}
+
diff --git a/SecurityServer/MacYarrow/YarrowServer/debug.h b/SecurityServer/MacYarrow/YarrowServer/debug.h
new file mode 100644
index 00000000..71e23679
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/debug.h
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		debug.h
+
+	Contains:	Debugging macros.
+
+	Written by:	Doug Mitchell
+
+	Copyright:	(c) 1999 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		12/07/99	dpm		Created.
+ 
+*/
+
+#ifndef	_DEBUG_H_
+#define _DEBUG_H_
+
+extern void yarrowPanic(const char *errStr);
+
+#define ERROR_LOG_ENABLE	0
+
+#define LOG_VIA_PRINTF		1
+
+#if		DEBUG || ERROR_LOG_ENABLE
+
+#include <stdio.h>
+
+#if		!LOG_VIA_PRINTF
+
+#include <string.h>
+#include <Types.h>
+#include <TextUtils.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* common log macros */
+
+extern void dblog0(char *str);
+extern void dblog1(char *str, void * arg1);
+extern void dblog2(char *str, void * arg1, void * arg2);
+extern void dblog3(char *str, void * arg1, void * arg2, void * arg3);
+extern void dblog4(char *str, void * arg1, void * arg2, void * arg3, void * arg4);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#else	/* LOG_VIA_PRINTF */
+
+#define dblog0(str)								printf(str)
+#define dblog1(str, arg1)						printf(str, arg1)
+#define dblog2(str, arg1, arg2)					printf(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)			printf(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)		printf(str, arg1, arg2, arg3, arg4)
+
+#endif	/* LOG_VIA_PRINTF */
+
+#else	/* log macros disabled */
+
+#define dblog0(str)
+#define dblog1(str, arg1)
+#define dblog2(str, arg1, arg2)
+#define dblog3(str, arg1, arg2, arg3)
+#define dblog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* log macros */
+
+#if	DEBUG
+
+#define dprintf0(str)								dblog0(str)
+#define dprintf1(str, arg1)							dblog1(str, (void *)arg1)
+#define dprintf2(str, arg1, arg2)					dblog2(str, (void *)arg1, (void *)arg2)
+#define dprintf3(str, arg1, arg2, arg3)				dblog3(str, (void *)arg1, (void *)arg2, (void *)arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)		dblog4(str, (void *)arg1, (void *)arg2, (void *)arg3, (void *) arg4)
+
+#define CASSERT(expression) 							\
+  ((expression) ? (void)0 : 							\
+   (dprintf1 ("Assertion failed: " #expression 			\
+      ", file " __FILE__ ", line %d.\n", __LINE__), 	\
+    yarrowPanic("Assertion Failure")))
+
+#else	/* DEBUG */
+
+#define dprintf0(str)
+#define dprintf1(str, arg1)
+#define dprintf2(str, arg1, arg2)
+#define dprintf3(str, arg1, arg2, arg3)
+#define dprintf4(str, arg1, arg2, arg3, arg4)
+
+#define CASSERT(expression)
+
+#endif	/* DEBUG */
+
+/*
+ * Error logging. This may well be platform dependent.
+ */
+#if		ERROR_LOG_ENABLE
+#define errorLog0(str)								dblog0(str);
+#define errorLog1(str, arg1)						dblog1(str, (void *)arg1)
+#define errorLog2(str, arg1, arg2)					dblog2(str, (void *)arg1, (void *)arg2)
+#define errorLog3(str, arg1, arg2, arg3)			dblog3(str, (void *)arg1, (void *)arg2, (void *)arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)		dblog4(str, (void *)arg1, (void *)arg2, (void *)arg3, (void *)arg4)
+
+#else	/* ERROR_LOG_ENABLE */
+
+#define errorLog0(str)
+#define errorLog1(str, arg1)
+#define errorLog2(str, arg1, arg2)
+#define errorLog3(str, arg1, arg2, arg3)
+#define errorLog4(str, arg1, arg2, arg3, arg4)
+
+#endif	/* ERROR_LOG_ENABLE */
+
+#endif	/* _DEBUG_H_ */
diff --git a/SecurityServer/MacYarrow/YarrowServer/entropyFile.h b/SecurityServer/MacYarrow/YarrowServer/entropyFile.h
new file mode 100644
index 00000000..23723004
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/entropyFile.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		entropyFile.h
+
+	Contains:	Module to maintain MacYarrow's entropy file.
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		02/29/00	dpm		Created.
+ 
+*/
+
+#ifndef	_ENTROPY_FILE_H_
+#define _ENTROPY_FILE_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Specify optional entropy file path. If this is never called,
+ * this module will use its own default path. 
+ */
+OSErr setEntropyFilePath(
+	const char *path);
+	
+/*
+ * Write specified data to entropy file. A new file will be created
+ * if none exists. Existing file's data is replaced with caller's data.
+ */
+OSErr writeEntropyFile(
+	UInt8		*bytes,
+	UInt32		numBytes);
+	
+/*
+ * Read data from entropy file.
+ */
+OSErr readEntropyFile(
+	UInt8		*bytes,
+	UInt32		numBytes,		// max # of bytes to read
+	UInt32		*actualBytes);	// RETURNED - number of bytes actually read
+	
+#if defined(__cplusplus)
+}
+#endif
+
+#endif	/* _ENTROPY_FILE_H_*/
diff --git a/SecurityServer/MacYarrow/YarrowServer/entropyFileOS9.c b/SecurityServer/MacYarrow/YarrowServer/entropyFileOS9.c
new file mode 100644
index 00000000..eb37e729
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/entropyFileOS9.c
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		entropyFile.c
+
+	Contains:	Module to maintain MacYarrow's entropy file.
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		02/29/00	dpm		Created.
+ 
+*/
+
+#include "entropyFile.h"
+#include "debug.h"
+#include <Files.h>
+#include <Folders.h>
+#include <Errors.h>
+#include <Script.h>		// for smSystemScript
+
+/*
+ * FIXME - for debugging, we put the entropy file the current user's 
+ * preferences folder.  For the real thing, we should either put it in
+ * System preferences or use UNIX I/O to specify some other path. 
+ */
+#ifdef	DEBUG
+#define ENTROPY_FOLDER			kPreferencesFolderType
+#else
+#define ENTROPY_FOLDER			kSystemPreferencesFolderType
+#endif
+#define ENTROPY_FILE_NAME		"\pSystem Entropy"
+#define ENTROPY_FILE_CREATOR	'yarw'
+#define ENTROPY_FILE_TYPE		'ENTR'
+
+/*
+ * Open/create entropy file. fnfErr returned if doCreate is false and
+ * the file doesn't exist.  
+ */
+static OSErr openEntropyFile(
+	Boolean doCreate,
+	Boolean writeAccess,		// required if doCreate true
+	short	*refNum)			// RETURNED
+{
+	FSSpec		fsp;
+	OSErr 		ortn;
+	short 		vRefNum;
+	long 		dirID;
+	SInt8 		perm;
+	
+	if(doCreate && !writeAccess) {
+		return paramErr;
+	}
+	*refNum = 0;
+	ortn = FindFolder(kOnSystemDisk, 
+		ENTROPY_FOLDER, 
+		kDontCreateFolder, 
+		&vRefNum, 
+		&dirID);
+	if(ortn) {
+		errorLog1("openEntropyFile: FindFolder returned %d\n", (int)ortn);
+		return ioErr;
+	}
+	ortn = FSMakeFSSpec(vRefNum, dirID, ENTROPY_FILE_NAME, &fsp);
+	switch(ortn) {
+		case noErr:
+			break;
+		case fnfErr:
+			if(!doCreate) {
+				return fnfErr;
+			}
+			else {
+				break;
+			}
+		default:
+			errorLog1("openEntropyFile: FSMakeFSSpec returned %d\n", (int)ortn);
+			return ioErr;
+	}
+
+	if(doCreate && (ortn == fnfErr)) {
+		/* create it */
+		ortn = FSpCreate(&fsp, 
+			ENTROPY_FILE_CREATOR, 
+			ENTROPY_FILE_TYPE, 
+			smSystemScript);
+		if(ortn) {
+			errorLog1("openEntropyFile: FSpCreate returned %d\n", (int)ortn);
+			return ortn;
+		}
+		
+		/* fixme - set FInfo.fdFlags.kIsInvisible? */
+	}
+
+	/* open it in any case */
+	perm = (writeAccess ? fsRdWrPerm : fsRdPerm);
+	ortn = FSpOpenDF(&fsp, perm, refNum);
+	if(ortn) {
+		errorLog1("openEntropyFile: FSpOpenDF returned %d\n", (int)ortn);
+	}
+	return ortn;
+}
+
+/*
+ * Write specified data to entropy file. A new file will be created
+ * if none exists. Data will be appended to possible existing data
+ * if append is true, otherwise the file's data is replaced with 
+ * caller's data.
+ */
+OSErr writeEntropyFile(
+	UInt8		*bytes,
+	UInt32		numBytes,
+	Boolean		append)
+{
+	OSErr ortn;
+	short refNum;
+	long  eof;
+	long  actLength = numBytes;
+	
+	ortn = openEntropyFile(true, true, &refNum);
+	if(ortn) {
+		return ortn;
+	}
+	if(append) {
+		ortn = GetEOF(refNum, &eof);
+		if(ortn) {
+			goto done;
+		}
+	}
+	else {
+		/* truncate to 0 */
+		ortn = SetEOF(refNum, 0);
+		if(ortn) {
+			goto done;
+		}
+		eof = 0;
+	}
+	ortn = SetFPos(refNum, fsFromStart, eof);
+	if(ortn) {
+		goto done;
+	}
+	ortn = FSWrite(refNum, &actLength, bytes);
+	if((ortn == noErr) && (actLength != numBytes)) {
+		errorLog0("writeEntropyFile: short write\n");
+	}
+done:
+	FSClose(refNum);
+	return ortn;
+}
+	
+/*
+ * Read data from entropy file.
+ */
+OSErr readEntropyFile(
+	UInt8		*bytes,
+	UInt32		numBytes,		// max # of bytes to read
+	UInt32		*actualBytes)	// RETURNED - number of bytes actually read
+{
+	OSErr ortn;
+	short refNum;
+	long  actLength = numBytes;
+	
+	ortn = openEntropyFile(false, false, &refNum);
+	if(ortn) {
+		return ortn;
+	}
+	ortn = FSRead(refNum, &actLength, bytes);
+	*actualBytes = actLength;
+	FSClose(refNum);
+	return ortn;
+}
diff --git a/SecurityServer/MacYarrow/YarrowServer/entropyFileUnix.c b/SecurityServer/MacYarrow/YarrowServer/entropyFileUnix.c
new file mode 100644
index 00000000..89ab1f71
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/entropyFileUnix.c
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		entropyFileUnix.c
+
+	Contains:	Module to maintain MacYarrow's entropy file, UNIX version.
+
+	Written by:	Doug Mitchell
+
+	Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved.
+
+	Change History (most recent first):
+
+		05/22/00	dpm		Created.
+ 
+*/
+
+#include "entropyFile.h"
+#include "debug.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+/*
+ * For now we use the same file location for all builds. Generally for
+ * debugging - when this code is not running as root - you need to do
+ * the following once per system before using this code:
+ *
+ * > su to root
+ * # touch /var/db/SystemEntropyCache
+ * # chmod 666 /var/db/SystemEntropyCache
+ */
+#define DEFAULT_ENTROPY_FILE_PATH		"/var/db/SystemEntropyCache"
+
+/* NULL ==> use default, else use caller-specified path */
+static char *entropyFilePath = NULL;
+
+static OSErr errNoToOSErr(int err)
+{
+	switch(err) {
+		case ENOENT:
+			return fnfErr;
+		case EPERM:
+			return permErr;
+		/* anything else interesting? */
+		default:
+			return ioErr;
+	}
+}
+
+static char *getEntropyFilePath()
+{
+	if(entropyFilePath) {
+		return entropyFilePath;
+	}
+	else {
+		return DEFAULT_ENTROPY_FILE_PATH;
+	}
+}
+
+/*
+ * Specify optional entropy file path. If this is never called,
+ * this module will use its own default path. 
+ */
+OSErr setEntropyFilePath(
+	const char *path)
+{
+	unsigned len;
+	
+	if(entropyFilePath) {
+		free(entropyFilePath);
+		entropyFilePath = NULL;
+	}
+	if(path == NULL) {
+		return noErr;
+	}
+	len = strlen(path);
+	if(len > 255) {
+		/* no can do */
+		return bdNamErr;
+	}
+	entropyFilePath = malloc(len + 1);
+	if(entropyFilePath == NULL) {
+		return memFullErr;
+	}
+	memmove(entropyFilePath, path, len + 1);
+	return noErr;
+}
+
+/*
+ * Write specified data to entropy file. A new file will be created
+ * if none exists. Existing file's data is replaced with caller's data.
+ */
+OSErr writeEntropyFile(
+	UInt8		*bytes,
+	UInt32		numBytes)
+{
+	int		rtn;
+	int 	fd;
+	OSErr	ortn;
+	
+	fd = open(getEntropyFilePath(), O_RDWR | O_CREAT | O_TRUNC, 0600);
+	if(fd <= 0) {
+		rtn = errno;
+		errorLog1("writeEntropyFile: open returned %d\n", rtn);
+		return errNoToOSErr(rtn);
+	}
+	rtn = lseek(fd, 0, SEEK_SET);
+	if(rtn < 0) {
+		rtn = errno;
+		errorLog1("writeEntropyFile: lseek returned %d\n", rtn);
+		return errNoToOSErr(rtn);
+	}
+	rtn = write(fd, bytes, (size_t)numBytes);
+	if(rtn != (int)numBytes) {
+		if(rtn < 0) {
+			errorLog1("writeEntropyFile: write() returned %d\n", rtn);
+			ortn = errNoToOSErr(errno);
+		}
+		else {
+			errorLog0("writeEntropyFile(): short write\n");
+			ortn = ioErr;
+		}
+	}
+	else {
+		ortn = noErr;
+	}
+	close(fd);
+	return ortn;
+}
+	
+/*
+ * Read data from entropy file.
+ */
+OSErr readEntropyFile(
+	UInt8		*bytes,
+	UInt32		numBytes,		// max # of bytes to read
+	UInt32		*actualBytes)	// RETURNED - number of bytes actually read
+{
+	int rtn;
+	int fd;
+	OSErr ortn;
+	
+	*actualBytes = 0;
+	fd = open(getEntropyFilePath(), O_RDONLY, 0);
+	if(fd <= 0) {
+		rtn = errno;
+		errorLog1("readEntropyFile: open returned %d\n", rtn);
+		return errNoToOSErr(rtn);
+	}
+	rtn = lseek(fd, 0, SEEK_SET);
+	if(rtn < 0) {
+		rtn = errno;
+		errorLog1("readEntropyFile: lseek returned %d\n", rtn);
+		return errNoToOSErr(rtn);
+	}
+	rtn = read(fd, bytes, (size_t)numBytes);
+	if(rtn < 0) {
+		errorLog1("readEntropyFile: read() returned %d\n", rtn);
+		ortn = errNoToOSErr(errno);
+	}
+	else {
+		*actualBytes = (UInt32)rtn;
+		ortn = noErr;
+	}
+	close(fd);
+	return ortn;
+}
diff --git a/SecurityServer/MacYarrow/YarrowServer/kdebug_private.h b/SecurityServer/MacYarrow/YarrowServer/kdebug_private.h
new file mode 100644
index 00000000..0946ebf3
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/kdebug_private.h
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+
+/*  Copyright (c) 1997 Apple Computer, Inc.  All rights reserved.
+ *
+ * kdebugprivate.h -   private kernel_debug definitions
+ *
+ */
+
+
+/**********************************************************************/
+#ifndef _BSD_KERN_KDEBUG_PRIVATE_H_
+#define _BSD_KERN_KDEBUG_PRIVATE_H_
+
+typedef struct {
+mach_timespec_t timestamp;
+unsigned int arg1;
+unsigned int arg2;
+unsigned int arg3;
+unsigned int arg4;
+unsigned int arg5;       /* will hold current thread */
+unsigned int debugid;
+} kd_buf;
+
+/* Debug Flags */
+#define KDBG_INIT 0x1
+#define KDBG_NOWRAP 0x2
+#define KDBG_FREERUN 0x4
+#define KDBG_WRAPPED 0x8
+#define KDBG_USERFLAGS (KDBG_FREERUN|KDBG_NOWRAP|KDBG_INIT)
+#define KDBG_PIDCHECK   0x10
+#define KDBG_MAPINIT    0x20
+
+
+typedef struct {
+ unsigned int type;
+ unsigned int value1;
+ unsigned int value2;
+ unsigned int value3;
+ unsigned int value4;
+
+} kd_regtype;
+
+typedef struct
+{
+    int nkdbufs;
+    int nolog;
+    int flags;
+    int nkdthreads;
+} kbufinfo_t;
+
+typedef struct
+{
+  unsigned int thread;
+  int          valid;
+  char         command[20];
+} kd_threadmap;
+
+
+#define KDBG_CLASSTYPE  0x10000
+#define KDBG_SUBCLSTYPE  0x20000
+#define KDBG_RANGETYPE  0x40000
+#define KDBG_TYPENONE  0x80000
+#define KDBG_CKTYPES  0xF0000
+
+#define KDBG_RANGECHECK 0x100000
+#define KDBG_VALCHECK 0x200000        /* Check up to 4 individual values
+*/
+
+#define KDBG_BUFINIT 0x80000000
+/* Maximum number of buffer entries is 64k */
+
+#define KDBG_MAXBUFSIZE (64*1024)
+
+/* Control operations */
+#define KDBG_EFLAGS 1
+#define KDBG_DFLAGS 2
+#define KDBG_ENABLE 3
+#define KDBG_SETNUMBUF 4
+#define KDBG_GETNUMBUF 5
+#define KDBG_SETUP 6
+#define KDBG_REMOVE 7
+#define KDBG_SETREGCODE 8
+#define KDBG_GETREGCODE 9
+#define KDBG_READTRACE 10
+
+#define KDBGREGCALSS 1
+#define KDBGREGSUBCALSS 2
+#define KDBGREGRANGE 3
+#define KDBGREGNONE 4
+/**********************************************************************/
+
+#endif /* _BSD_KERN_KDEBUG_PRIVATE_H_ */
\ No newline at end of file
diff --git a/SecurityServer/MacYarrow/YarrowServer/prefixDebug.h b/SecurityServer/MacYarrow/YarrowServer/prefixDebug.h
new file mode 100644
index 00000000..94ee21be
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/prefixDebug.h
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+
+#define DEBUG	1
diff --git a/SecurityServer/MacYarrow/YarrowServer/prefixRelease.h b/SecurityServer/MacYarrow/YarrowServer/prefixRelease.h
new file mode 100644
index 00000000..7c5ee212
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/prefixRelease.h
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+
+#define DEBUG	0
diff --git a/SecurityServer/MacYarrow/YarrowServer/systemEntropy.c b/SecurityServer/MacYarrow/YarrowServer/systemEntropy.c
new file mode 100644
index 00000000..a33d582e
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/systemEntropy.c
@@ -0,0 +1,270 @@
+/*
+ * 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.
+ */
+
+
+/*
+ 	File:		systemEntropy.c
+	
+ 	Contains:	System entropy collector, using 
+				sysctl(CTL_KERN:KERN_KDEBUG) trace info
+
+ 	Copyright:	(C) 2000 by Apple Computer, Inc., all rights reserved
+
+ 	Written by:	Doug Mitchell <dmitch@apple.com>	
+*/
+
+#include "systemEntropy.h"
+#include "debug.h"
+
+/* support for sysctl */
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+//#include <libc.h>
+#include <sys/kdebug.h>
+#include <sys/sysctl.h>
+#include <sys/errno.h>
+#include <unistd.h>
+
+/* this should eventually come from private system headers */
+#include "kdebug_private.h"
+
+/* time to gather trace info */
+#define MS_TO_SLEEP		100
+
+static int set_remove();
+static int set_init();
+static int set_enable(int val);
+static int set_numbufs(int nbufs);
+
+/* start collecting system entropy */
+int systemEntropyBegin(UInt32 bufSize)
+{
+	int rtn;
+	
+	/* start from clean slate  */
+	set_remove();
+	
+	/* 
+	 * This will result in a ENOENT error if we're not root.
+	 * That's OK, the kernel will use its default of an 8K 
+	 * buffer in that case. 
+	 */
+	set_numbufs(bufSize);	
+	if(rtn = set_init()) {
+		return rtn;
+	}
+	if(rtn = set_enable(1)) {
+		return rtn;
+	}
+	return 0;
+}
+
+
+int systemEntropyCollect(
+	UInt8 *buf,
+	UInt32 bufSize,
+	UInt32 *numBytes,		// RETURNED - number of bytes obtained
+	UInt32 *bitsOfEntropy)	// RETURNED - est. amount of entropy
+{
+	int 		rtn = 0;
+	size_t 		mallocdSize;
+	UInt8		*cp = buf;
+	kd_buf 		*kd = NULL;
+	int			i;
+	int 		mib[6];
+	size_t		numEntries;
+	
+	*numBytes = 0;
+	*bitsOfEntropy = 0;
+	
+
+	/*
+	 * We use one byte from each entry, which is a kd_buf.
+	 * Thus, malloc bufSize kd_bufs. 
+	 * FIXME : this should use a secure nonswapping malloc. 
+	 */
+	mallocdSize = bufSize * sizeof(kd_buf);
+	kd = (kd_buf *)malloc(mallocdSize);
+	if(kd == NULL) {
+		rtn = ENOMEM;
+		goto errOut;
+	}
+	
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_KDEBUG;
+	mib[2] = KERN_KDREADTR;
+	mib[3] = 0;
+	mib[4] = 0;
+	mib[5] = 0;  /* no flags */
+	
+	/*
+	 * Snag the trace buffer, up to caller's limit. 
+	 * On call to sysctl, numEntries is byte count, on return,
+	 * it's buffer count. 
+	 */ 
+	numEntries = mallocdSize;
+	if (sysctl(mib, 3, kd, &numEntries, NULL, 0) < 0) {
+		/* ENOMEM means we didn't have room for everything in
+		 * the kernel trace buffer, which is fine */
+		int err = errno;
+		if(err != ENOMEM) {
+			errorLog1("sysctl-KERN_KDREADTR: %d\n", err);
+			rtn = err;
+			goto errOut;
+		}
+	}
+	if(numEntries == 0) {
+		rtn = ENOENT;
+		goto errOut;
+	}
+	
+	/* 
+	 * First entropy byte is the low byte of the first entry's
+	 * timestamp. Subsequent bytes are the deltas between successive
+	 * entries' timestamps.
+	 */	
+	*cp++ = (UInt8)kd[0].timestamp.tv_nsec;
+	for (i=1; i<numEntries; i++) {
+		*cp++ = kd[i].timestamp.tv_nsec - kd[i-1].timestamp.tv_nsec;
+	}
+	
+	*numBytes = numEntries;
+	*bitsOfEntropy = numEntries * 4;		// half random?
+	
+	/* and finally, turn off tracing */
+errOut:
+	set_enable(0);
+	set_remove();		// ignore errors 
+	return rtn;
+}
+
+/*
+ * The remainder of this file is based on code provided by Joe Sokol.
+ * All functions return a UNIX errno, zero on success. 
+ */
+
+static int set_remove()
+{
+	int mib[6];
+	size_t needed;
+	
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_KDEBUG;
+	mib[2] = KERN_KDREMOVE;  /* protocol */
+	mib[3] = 0;
+	mib[4] = 0;
+	mib[5] = 0;  /* no flags */
+	
+	if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0) {
+		int err = errno;
+		errorLog1("sysctl-KERN_KDREMOVE: %d\n", err);
+		return err;
+	}
+	return 0;
+}
+
+static int set_init()
+{       
+	kd_regtype kr;
+	int mib[6];
+	size_t needed;
+	
+	kr.type = KDBG_RANGETYPE;
+	kr.value1 = 0;
+	kr.value2 = -1;
+	needed = sizeof(kd_regtype);
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_KDEBUG;
+	mib[2] = KERN_KDSETREG;
+	mib[3] = 0;
+	mib[4] = 0;
+	mib[5] = 0;  /* no flags */
+	
+	if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
+		int err = errno;
+		errorLog1("sysctl-KERN_KDSETREG: %d\n", err);
+		return err;
+	}
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_KDEBUG;
+	mib[2] = KERN_KDSETUP;
+	mib[3] = 0;
+	mib[4] = 0;
+	mib[5] = 0;  /* no flags */
+	
+	if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0) {
+		int err = errno;
+		errorLog1("sysctl-KERN_KDSETUP: %d\n", err);
+		return err;
+	}
+	return 0;
+}
+
+static int set_enable(int val)
+{
+	int mib[6];
+	size_t needed;
+	
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_KDEBUG;
+	mib[2] = KERN_KDENABLE;  /* protocol */
+	mib[3] = val;
+	mib[4] = 0;
+	mib[5] = 0;          /* no flags */
+	if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0) {
+		int err = errno;
+		errorLog1("sysctl-KERN_KDENABLE: %d\n", err);
+		return err;
+	}
+	return 0;
+}
+
+static int set_numbufs(int nbufs) 
+{
+	int mib[6];
+	size_t needed;
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_KDEBUG;
+	mib[2] = KERN_KDSETBUF;
+	mib[3] = nbufs;
+	mib[4] = 0;
+	mib[5] = 0;		        /* no flags */
+	if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0) {
+		int err = errno;
+		errorLog2("ERROR: sysctl-KERN_KDSETBUF(%d): %s\n", 
+			nbufs, strerror(err));
+		return err;
+	}
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_KDEBUG;
+	mib[2] = KERN_KDSETUP;		
+	mib[3] = 0;
+	mib[4] = 0;
+	mib[5] = 0;		        /* no flags */
+	if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0) {
+		int err = errno;
+		errorLog1("ERROR: sysctl-KERN_KDSETUP: %s\n", 
+			strerror(err));
+		return err;
+	}
+	return 0;
+}
diff --git a/SecurityServer/MacYarrow/YarrowServer/systemEntropy.h b/SecurityServer/MacYarrow/YarrowServer/systemEntropy.h
new file mode 100644
index 00000000..023b1c10
--- /dev/null
+++ b/SecurityServer/MacYarrow/YarrowServer/systemEntropy.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+/*
+ 	File:		systemEntropy.h
+	
+ 	Contains:	System entropy collector, using 
+				sysctl(CTL_KERN:KERN_KDEBUG) trace info
+
+ 	Copyright:	(C) 2000 by Apple Computer, Inc., all rights reserved
+
+ 	Written by:	Doug Mitchell <dmitch@apple.com>	
+*/
+
+#ifndef	_YARROW_SYSTEM_ENTROPY_H_
+#define _YARROW_SYSTEM_ENTROPY_H_
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* start collecting system entropy */
+int systemEntropyBegin(
+	UInt32 bufSize);		// desired number of bytes to collect
+
+
+/* gather system entropy in caller-supplied buffer */
+int systemEntropyCollect(
+	UInt8 *buf,
+	UInt32 bufSize,
+	UInt32 *numBytes,		// RETURNED - number of bytes obtained
+	UInt32 *bitsOfEntropy);	// RETURNED - est. amount of entropy
+
+/* minimum number of milliseconds between calling systemEntropyBegin() and
+ * systemEntropyCollect() */
+#define SYSTEM_ENTROPY_COLLECT_TIME		100
+//#define SYSTEM_ENTROPY_COLLECT_TIME		5000
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _YARROW_SYSTEM_ENTROPY_H_*/
diff --git a/SecurityServer/MacYarrow/testHarness/clientTest.cpp b/SecurityServer/MacYarrow/testHarness/clientTest.cpp
new file mode 100644
index 00000000..8509047d
--- /dev/null
+++ b/SecurityServer/MacYarrow/testHarness/clientTest.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * Simple YarrowClient test.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <Security/SecurityYarrowClient.h>
+
+#define BUFSIZE		32
+
+static void dumpBuf(UInt8 *buf,
+	unsigned len)
+{
+	unsigned i;
+	
+	printf("   ");
+	for(i=0; i<len; i++) {
+		printf("%02X  ", buf[i]);
+		if((i % 8) == 7) {
+			printf("\n   ");
+		}
+	}
+	printf("\n");
+}
+
+int main()
+{
+	try {
+		YarrowClient client;		// take default constructor
+		UInt8	buf[BUFSIZE];
+		char	resp = 'm';			// initial op = get random data
+
+		while(1) {
+			switch(resp) {
+				case 'm':
+					client.getRandomBytes(buf, BUFSIZE);
+					dumpBuf(buf, BUFSIZE);
+					break;
+				case 'a':
+					/* claim it's half random */
+					client.addEntropy(buf, BUFSIZE, BUFSIZE * 4);
+					break;
+				case '\n':
+					goto nextChar;
+				default:
+					printf("Huh?\n");
+			}
+			printf(" a   Add this as entropy\n");
+			printf(" m   Get more random data\n");
+			printf(" q   quit\n");
+			printf("\ncommand me: ");
+		nextChar:
+			resp = getchar();
+			if(resp == 'q') {
+				break;
+			}
+		}
+	}
+	catch (OSErr ortn) {
+		printf("YarrowClient threw OSErr %d\n", ortn);
+	}
+	catch (...) {
+		printf("Whoops! YarrowClient threw an exception!\n");
+	}
+	/* and YarrowClient cleans up on the way out */
+	return 0;
+}
diff --git a/SecurityServer/MacYarrow/testHarness/serverDaemon.cpp b/SecurityServer/MacYarrow/testHarness/serverDaemon.cpp
new file mode 100644
index 00000000..63072f11
--- /dev/null
+++ b/SecurityServer/MacYarrow/testHarness/serverDaemon.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+//
+// simple daemon to run yarrow server
+//
+
+#include <YarrowServer/YarrowServer_OSX.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+	char *entropyFilePath = NULL;
+	int arg;
+	
+	for(arg=1; arg<argc; arg++) {
+		switch(argv[arg][0]) {
+			case 'e':
+				entropyFilePath = &argv[arg][2];
+				break;
+			default:
+				printf("Usage: %s [e=entropyFilePath]\n", argv[0]);
+				exit(1);
+		}
+	}
+	printf("starting up server...\n");
+	
+	YarrowServer *server = new YarrowServer(entropyFilePath);
+	server->runYarrow();		// forks off thread
+	printf("server running; hit q exit: ");
+	while(1) {
+		char c = getchar();
+		if(c == 'q') {
+			break;
+		}
+		printf("...still running\n");
+	}
+	return 0;
+}
\ No newline at end of file
diff --git a/SecurityServer/MacYarrow/yarrowseed.cpp b/SecurityServer/MacYarrow/yarrowseed.cpp
new file mode 100644
index 00000000..de10a000
--- /dev/null
+++ b/SecurityServer/MacYarrow/yarrowseed.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+//
+// yarrowseed - periodical to collect and seed entropy into /dev/random
+//
+#include "yarrowseed.h"
+#include "MacYarrow_OSX.h"
+
+
+//
+// Constructor initializes the entropy generator and schedules itself
+//
+YarrowTimer::YarrowTimer(MachPlusPlus::MachServer &srv, const char *entropyFile)
+    : MachServer::Timer(), server(srv)
+{
+    unsigned firstTimeout;
+#if correct
+    if (OSStatus err = yarrowServerInit(entropyFile, &firstTimeout))
+        MacOSError::throwMe(err);
+#else
+    yarrowServerInit(entropyFile, &firstTimeout);
+#endif
+    server.setTimer(this, Time::Interval(firstTimeout / 1000.0));
+}
+
+
+/* 
+ * Timeout event, the sole purpose of this class. Pass on to MacYarrow module.
+ */
+void YarrowTimer::action()
+{
+	unsigned nextTimeout = yarrowTimerEvent();
+	scheduleTimer(nextTimeout);
+}
+
+void YarrowTimer::scheduleTimer(unsigned msFromNow)
+{
+    server.setTimer(this, Time::Interval(msFromNow / 1000.0));
+}
diff --git a/SecurityServer/MacYarrow/yarrowseed.h b/SecurityServer/MacYarrow/yarrowseed.h
new file mode 100644
index 00000000..d6b27451
--- /dev/null
+++ b/SecurityServer/MacYarrow/yarrowseed.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+
+//
+// yarrowseed - periodical to collect and seed entropy into /dev/random
+//
+#ifndef _H_YARROWSEED
+#define _H_YARROWSEED
+
+#include <Security/machserver.h>
+#include <mach/mach_error.h>
+
+
+using MachPlusPlus::MachServer;
+
+
+/*
+ * A timer for this module. Just one, and it's always active subsequent to startup.
+ */
+class YarrowTimer : public MachServer::Timer {
+public:
+	YarrowTimer(MachPlusPlus::MachServer &srv, const char *entropyFile = NULL);
+		
+	void action();
+	void scheduleTimer(unsigned msFromNow);
+    
+	MachPlusPlus::MachServer	&server;		// to which we do setTimer()
+};
+
+#endif //_H_YARROWSEED
diff --git a/SecurityServer/MacYarrow/zlib/ChangeLog b/SecurityServer/MacYarrow/zlib/ChangeLog
new file mode 100644
index 00000000..a54907ac
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/ChangeLog
@@ -0,0 +1 @@
+
		ChangeLog file for zlib

Changes in 1.1.3 (9 July 1998)
- fix "an inflate input buffer bug that shows up on rare but persistent
  occasions" (Mark)
- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
- fix gzseek(..., SEEK_SET) in write mode
- fix crc check after a gzeek (Frank Faubert)
- fix miniunzip when the last entry in a zip file is itself a zip file
  (J Lillge)
- add contrib/asm586 and contrib/asm686 (Brian Raiter)
  See http://www.muppetlabs.com/~breadbox/software/assembly.html
- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
- added a FAQ file

- Support gzdopen on Mac with Metrowerks (Jason Linhart)
- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
- avoid some warnings with Borland C (Tom Tanner)
- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant)
- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
- use libdir and includedir in Makefile.in (Tim Mooney)
- support shared libraries on OSF1 V4 (Tim Mooney)
- remove so_locations in "make clean"  (Tim Mooney)
- fix maketree.c compilation error (Glenn, Mark)
- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
- new Makefile.riscos (Rich Walker)
- initialize static descriptors in trees.c for embedded targets (Nick Smith)
- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
- fix maketree.c to allow clean compilation of inffixed.h (Mark)
- fix parameter check in deflateCopy (Gunther Nikl)
- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
- Many portability patches by Christian Spieler:
  . zutil.c, zutil.h: added "const" for zmem*
  . Make_vms.com: fixed some typos
  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
  . msdos/Makefile.msc: remove "default rtl link library" info from obj files
  . msdos/Makefile.*: use model-dependent name for the built zlib library
  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
- replace __far with _far for better portability (Christian Spieler, Tom Lane)
- fix test for errno.h in configure (Tim Newsham)

Changes in 1.1.2 (19 March 98)
- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
  See http://www.winimage.com/zLibDll/unzip.html
- preinitialize the inflate tables for fixed codes, to make the code
  completely thread safe (Mark)
- some simplifications and slight speed-up to the inflate code (Mark)
- fix gzeof on non-compressed files (Allan Schrum)
- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
- do not wrap extern "C" around system includes (Tom Lane)
- mention zlib binding for TCL in README (Andreas Kupries)
- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
- allow "configure --prefix $HOME" (Tim Mooney)
- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
- move Makefile.sas to amiga/Makefile.sas

Changes in 1.1.1 (27 Feb 98)
- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)
- remove block truncation heuristic which had very marginal effect for zlib
  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
  compression ratio on some files. This also allows inlining _tr_tally for
  matches in deflate_slow.
- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)

Changes in 1.1.0 (24 Feb 98)
- do not return STREAM_END prematurely in inflate (John Bowler)
- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
- compile with -DFASTEST to get compression code optimized for speed only
- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
  on Sun but significant on HP)

- add a pointer to experimental unzip library in README (Gilles Vollant)
- initialize variable gcc in configure (Chris Herborth)

Changes in 1.0.9 (17 Feb 1998)
- added gzputs and gzgets functions
- do not clear eof flag in gzseek (Mark Diekhans)
- fix gzseek for files in transparent mode (Mark Diekhans)
- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
- replace EXPORT with ZEXPORT to avoid conflict with other programs
- added compress2 in zconf.h, zlib.def, zlib.dnt
- new asm code from Gilles Vollant in contrib/asm386
- simplify the inflate code (Mark):
 . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
 . ZALLOC the length list in inflate_trees_fixed() instead of using stack
 . ZALLOC the value area for huft_build() instead of using stack
 . Simplify Z_FINISH check in inflate()

- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
  the declaration of FAR (Gilles VOllant)
- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
- read_buf buf parameter of type Bytef* instead of charf*
- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
- fix check for presence of directories in "make install" (Ian Willis)

Changes in 1.0.8 (27 Jan 1998)
- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
- added compress2() to allow setting the compression level
- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
- use constant arrays for the static trees in trees.c instead of computing
  them at run time (thanks to Ken Raeburn for this suggestion). To create
  trees.h, compile with GEN_TREES_H and run "make test".
- check return code of example in "make test" and display result
- pass minigzip command line options to file_compress
- simplifying code of inflateSync to avoid gcc 2.8 bug

- support CC="gcc -Wall" in configure -s (QingLong)
- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
- fix test for shared library support to avoid compiler warnings
- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
- do not use fdopen for Metrowerks on Mac (Brad Pettit))
- add checks for gzputc and gzputc in example.c
- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
- use const for the CRC table (Ken Raeburn)
- fixed "make uninstall" for shared libraries
- use Tracev instead of Trace in infblock.c
- in example.c use correct compressed length for test_sync
- suppress +vnocompatwarnings in configure for HPUX (not always supported)

Changes in 1.0.7 (20 Jan 1998)
- fix gzseek which was broken in write mode
- return error for gzseek to negative absolute position
- fix configure for Linux (Chun-Chung Chen)
- increase stack space for MSC (Tim Wegner)
- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
- define EXPORTVA for gzprintf (Gilles Vollant)
- added man page zlib.3 (Rick Rodgers)
- for contrib/untgz, fix makedir() and improve Makefile

- check gzseek in write mode in example.c
- allocate extra buffer for seeks only if gzseek is actually called
- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
- add inflateSyncPoint in zconf.h
- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def

Changes in 1.0.6 (19 Jan 1998)
- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
- Fix a deflate bug occuring only with compression level 0 (thanks to
  Andy Buckler for finding this one).
- In minigzip, pass transparently also the first byte for .Z files.
- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
- check Z_FINISH in inflate (thanks to Marc Schluper)
- Implement deflateCopy (thanks to Adam Costello)
- make static libraries by default in configure, add --shared option.
- move MSDOS or Windows specific files to directory msdos
- suppress the notion of partial flush to simplify the interface
  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
- suppress history buffer provided by application to simplify the interface
  (this feature was not implemented anyway in 1.0.4)
- next_in and avail_in must be initialized before calling inflateInit or
  inflateInit2
- add EXPORT in all exported functions (for Windows DLL)
- added Makefile.nt (thanks to Stephen Williams)
- added the unsupported "contrib" directory:
   contrib/asm386/ by Gilles Vollant <info@winimage.com>
	386 asm code replacing longest_match().
   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
        A C++ I/O streams interface to the zlib gz* functions
   contrib/iostream2/  by Tyge Løvset <Tyge.Lovset@cmr.no>
	Another C++ I/O streams interface
   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
	A very simple tar.gz file extractor using zlib
   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
        How to use compress(), uncompress() and the gz* functions from VB.
- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
  level) in minigzip (thanks to Tom Lane)

- use const for rommable constants in deflate
- added test for gzseek and gztell in example.c
- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
- add undocumented function zError to convert error code to string
  (for Tim Smithers)
- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
- Use default memcpy for Symantec MSDOS compiler.
- Add EXPORT keyword for check_func (needed for Windows DLL)
- add current directory to LD_LIBRARY_PATH for "make test"
- create also a link for libz.so.1
- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
- added -soname for Linux in configure (Chun-Chung Chen,
- assign numbers to the exported functions in zlib.def (for Windows DLL)
- add advice in zlib.h for best usage of deflateSetDictionary
- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
- allow compilation with ANSI keywords only enabled for TurboC in large model
- avoid "versionString"[0] (Borland bug)
- add NEED_DUMMY_RETURN for Borland
- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
- allow compilation with CC
- defined STDC for OS/2 (David Charlap)	
- limit external names to 8 chars for MVS (Thomas Lund)
- in minigzip.c, use static buffers only for 16-bit systems
- fix suffix check for "minigzip -d foo.gz"
- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
- added makelcc.bat for lcc-win32 (Tom St Denis)
- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
- Avoid expanded $Id: ChangeLog,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
- check for unistd.h in configure (for off_t)
- remove useless check parameter in inflate_blocks_free
- avoid useless assignment of s->check to itself in inflate_blocks_new
- do not flush twice in gzclose (thanks to Ken Raeburn)
- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
- work around buggy fclose on pipes for HP/UX
- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
- fix configure if CC is already equal to gcc

Changes in 1.0.5 (3 Jan 98)
- Fix inflate to terminate gracefully when fed corrupted or invalid data
- Use const for rommable constants in inflate
- Eliminate memory leaks on error conditions in inflate
- Removed some vestigial code in inflate
- Update web address in README
  
Changes in 1.0.4 (24 Jul 96)
- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
  bit, so the decompressor could decompress all the correct data but went
  on to attempt decompressing extra garbage data. This affected minigzip too.
- zlibVersion and gzerror return const char* (needed for DLL)
- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
- use z_error only for DEBUG (avoid problem with DLLs)

Changes in 1.0.3 (2 Jul 96)
- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
  small and medium models; this makes the library incompatible with previous
  versions for these models. (No effect in large model or on other systems.)
- return OK instead of BUF_ERROR if previous deflate call returned with
  avail_out as zero but there is nothing to do
- added memcmp for non STDC compilers
- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
- better check for 16-bit mode MSC (avoids problem with Symantec)

Changes in 1.0.2 (23 May 96)
- added Windows DLL support
- added a function zlibVersion (for the DLL support)
- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
- Bytef is define's instead of typedef'd only for Borland C
- avoid reading uninitialized memory in example.c
- mention in README that the zlib format is now RFC1950
- updated Makefile.dj2
- added algorithm.doc

Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
- fix array overlay in deflate.c which sometimes caused bad compressed data
- fix inflate bug with empty stored block
- fix MSDOS medium model which was broken in 0.99
- fix deflateParams() which could generated bad compressed data.
- Bytef is define'd instead of typedef'ed (work around Borland bug)
- added an INDEX file
- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
- speed up adler32 for modern machines without auto-increment
- added -ansi for IRIX in configure
- static_init_done in trees.c is an int
- define unlink as delete for VMS
- fix configure for QNX
- add configure branch for SCO and HPUX
- avoid many warnings (unused variables, dead assignments, etc...)
- no fdopen for BeOS
- fix the Watcom fix for 32 bit mode (define FAR as empty)
- removed redefinition of Byte for MKWERKS
- work around an MWKERKS bug (incorrect merge of all .h files)

Changes in 0.99 (27 Jan 96)
- allow preset dictionary shared between compressor and decompressor
- allow compression level 0 (no compression)
- add deflateParams in zlib.h: allow dynamic change of compression level
  and compression strategy.
- test large buffers and deflateParams in example.c
- add optional "configure" to build zlib as a shared library
- suppress Makefile.qnx, use configure instead
- fixed deflate for 64-bit systems (detected on Cray)
- fixed inflate_blocks for 64-bit systems (detected on Alpha)
- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
- always return Z_BUF_ERROR when deflate() has nothing to do
- deflateInit and inflateInit are now macros to allow version checking
- prefix all global functions and types with z_ with -DZ_PREFIX
- make falloc completely reentrant (inftrees.c)
- fixed very unlikely race condition in ct_static_init
- free in reverse order of allocation to help memory manager
- use zlib-1.0/* instead of zlib/* inside the tar.gz
- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
- allow gzread on concatenated .gz files
- deflateEnd now returns Z_DATA_ERROR if it was premature
- deflate is finally (?) fully deterministic (no matches beyond end of input)
- Document Z_SYNC_FLUSH
- add uninstall in Makefile
- Check for __cpluplus in zlib.h
- Better test in ct_align for partial flush
- avoid harmless warnings for Borland C++
- initialize hash_head in deflate.c
- avoid warning on fdopen (gzio.c) for HP cc -Aa
- include stdlib.h for STDC compilers
- include errno.h for Cray
- ignore error if ranlib doesn't exist
- call ranlib twice for NeXTSTEP
- use exec_prefix instead of prefix for libz.a
- renamed ct_* as _tr_* to avoid conflict with applications
- clear z->msg in inflateInit2 before any error return
- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
- fixed typo in zconf.h (_GNUC__ => __GNUC__)
- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
- in fcalloc, normalize pointer if size > 65520 bytes
- don't use special fcalloc for 32 bit Borland C++
- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
- use Z_BINARY instead of BINARY
- document that gzclose after gzdopen will close the file
- allow "a" as mode in gzopen.
- fix error checking in gzread
- allow skipping .gz extra-field on pipes
- added reference to Perl interface in README
- put the crc table in FAR data (I dislike more and more the medium model :)
- added get_crc_table
- added a dimension to all arrays (Borland C can't count).
- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
- guard against multiple inclusion of *.h (for precompiled header on Mac)
- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
- don't use unsized arrays to avoid silly warnings by Visual C++:
     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
     (what's wrong with far data in far model?).
- define enum out of inflate_blocks_state to allow compilation with C++

Changes in 0.95 (16 Aug 95)
- fix MSDOS small and medium model (now easier to adapt to any compiler)
- inlined send_bits
- fix the final (:-) bug for deflate with flush (output was correct but
  not completely flushed in rare occasions).
- default window size is same for compression and decompression
  (it's now sufficient to set MAX_WBITS in zconf.h).
- voidp -> voidpf and voidnp -> voidp (for consistency with other
  typedefs and because voidnp was not near in large model).

Changes in 0.94 (13 Aug 95)
- support MSDOS medium model
- fix deflate with flush (could sometimes generate bad output)
- fix deflateReset (zlib header was incorrectly suppressed)
- added support for VMS
- allow a compression level in gzopen()
- gzflush now calls fflush
- For deflate with flush, flush even if no more input is provided.
- rename libgz.a as libz.a
- avoid complex expression in infcodes.c triggering Turbo C bug
- work around a problem with gcc on Alpha (in INSERT_STRING)
- don't use inline functions (problem with some gcc versions)
- allow renaming of Byte, uInt, etc... with #define.
- avoid warning about (unused) pointer before start of array in deflate.c
- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
- avoid reserved word 'new' in trees.c

Changes in 0.93 (25 June 95)
- temporarily disable inline functions
- make deflate deterministic
- give enough lookahead for PARTIAL_FLUSH
- Set binary mode for stdin/stdout in minigzip.c for OS/2
- don't even use signed char in inflate (not portable enough)
- fix inflate memory leak for segmented architectures

Changes in 0.92 (3 May 95)
- don't assume that char is signed (problem on SGI)
- Clear bit buffer when starting a stored block
- no memcpy on Pyramid
- suppressed inftest.c
- optimized fill_window, put longest_match inline for gcc
- optimized inflate on stored blocks.
- untabify all sources to simplify patches

Changes in 0.91 (2 May 95)
- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
- Document the memory requirements in zconf.h
- added "make install"
- fix sync search logic in inflateSync
- deflate(Z_FULL_FLUSH) now works even if output buffer too short
- after inflateSync, don't scare people with just "lo world"
- added support for DJGPP

Changes in 0.9 (1 May 95)
- don't assume that zalloc clears the allocated memory (the TurboC bug
  was Mark's bug after all :)
- let again gzread copy uncompressed data unchanged (was working in 0.71)
- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
- added a test of inflateSync in example.c
- moved MAX_WBITS to zconf.h because users might want to change that.
- document explicitly that zalloc(64K) on MSDOS must return a normalized
  pointer (zero offset)
- added Makefiles for Microsoft C, Turbo C, Borland C++
- faster crc32()

Changes in 0.8 (29 April 95)
- added fast inflate (inffast.c)
- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
  is incompatible with previous versions of zlib which returned Z_OK.
- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
  (actually that was not a compiler bug, see 0.81 above)
- gzread no longer reads one extra byte in certain cases
- In gzio destroy(), don't reference a freed structure
- avoid many warnings for MSDOS
- avoid the ERROR symbol which is used by MS Windows

Changes in 0.71 (14 April 95)
- Fixed more MSDOS compilation problems :( There is still a bug with
  TurboC large model.

Changes in 0.7 (14 April 95)
- Added full inflate support.
- Simplified the crc32() interface. The pre- and post-conditioning
  (one's complement) is now done inside crc32(). WARNING: this is
  incompatible with previous versions; see zlib.h for the new usage.

Changes in 0.61 (12 April 95)
- workaround for a bug in TurboC. example and minigzip now work on MSDOS.

Changes in 0.6 (11 April 95)
- added minigzip.c
- added gzdopen to reopen a file descriptor as gzFile
- added transparent reading of non-gziped files in gzread.
- fixed bug in gzread (don't read crc as data)
- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
- don't allocate big arrays in the stack (for MSDOS)
- fix some MSDOS compilation problems

Changes in 0.5:
- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
  not yet Z_FULL_FLUSH.
- support decompression but only in a single step (forced Z_FINISH)
- added opaque object for zalloc and zfree.
- added deflateReset and inflateReset
- added a variable zlib_version for consistency checking.
- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.

Changes in 0.4:
- avoid "zip" everywhere, use zlib instead of ziplib.
- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
  if compression method == 8.
- added adler32 and crc32
- renamed deflateOptions as deflateInit2, call one or the other but not both
- added the method parameter for deflateInit2.
- added inflateInit2
- simplied considerably deflateInit and inflateInit by not supporting
  user-provided history buffer. This is supported only in deflateInit2
  and inflateInit2.

Changes in 0.3:
- prefix all macro names with Z_
- use Z_FINISH instead of deflateEnd to finish compression.
- added Z_HUFFMAN_ONLY
- added gzerror()
\ No newline at end of file
diff --git a/SecurityServer/MacYarrow/zlib/README b/SecurityServer/MacYarrow/zlib/README
new file mode 100644
index 00000000..473ce501
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/README
@@ -0,0 +1 @@
+zlib 1.1.3 is a general purpose data compression library.  All the code
is thread safe.  The data format used by the zlib library
is described by RFCs (Request for Comments) 1950 to 1952 in the files 
ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
format) and rfc1952.txt (gzip format). These documents are also available in
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html

All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
example of the library is given in the file example.c which also tests that
the library is working correctly. Another example is given in the file
minigzip.c. The compression library itself is composed of all source files
except example.c and minigzip.c.

To compile all files and run the test program, follow the instructions
given at the top of Makefile. In short "make test; make install"
should work for most machines. For Unix: "configure; make test; make install"
For MSDOS, use one of the special makefiles such as Makefile.msc.
For VMS, use Make_vms.com or descrip.mms.

Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov>, or to
Gilles Vollant <info@winimage.com> for the Windows DLL version.
The zlib home page is http://www.cdrom.com/pub/infozip/zlib/
The official zlib ftp site is ftp://ftp.cdrom.com/pub/infozip/zlib/
Before reporting a problem, please check those sites to verify that
you have the latest version of zlib; otherwise get the latest version and
check whether the problem still exists or not.

Mark Nelson <markn@tiny.com> wrote an article about zlib for the Jan. 1997
issue of  Dr. Dobb's Journal; a copy of the article is available in
http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm

The changes made in version 1.1.3 are documented in the file ChangeLog.
The main changes since 1.1.2 are:

- fix "an inflate input buffer bug that shows up on rare but persistent
  occasions" (Mark)
- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
- fix gzseek(..., SEEK_SET) in write mode
- fix crc check after a gzeek (Frank Faubert)
- fix miniunzip when the last entry in a zip file is itself a zip file
  (J Lillge)
- add contrib/asm586 and contrib/asm686 (Brian Raiter)
  See http://www.muppetlabs.com/~breadbox/software/assembly.html
- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
- added a FAQ file

plus many changes for portability.

Unsupported third party contributions are provided in directory "contrib".

A Java implementation of zlib is available in the Java Development Kit 1.1
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
See the zlib home page http://www.cdrom.com/pub/infozip/zlib/ for details.

A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
is in the CPAN (Comprehensive Perl Archive Network) sites, such as:
ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*

A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
is available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html

A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html

An experimental package to read and write files in .zip format,
written on top of zlib by Gilles Vollant <info@winimage.com>, is
available at http://www.winimage.com/zLibDll/unzip.html
and also in the contrib/minizip directory of zlib.


Notes for some targets:

- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
  and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
  The zlib DLL support was initially done by Alessandro Iacopetti and is
  now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
  home page at http://www.winimage.com/zLibDll

  From Visual Basic, you can call the DLL functions which do not take
  a structure as argument: compress, uncompress and all gz* functions.
  See contrib/visual-basic.txt for more information, or get
  http://www.tcfb.com/dowseware/cmp-z-it.zip

- For 64-bit Irix, deflate.c must be compiled without any optimization.
  With -O, one libpng test fails. The test works in 32 bit mode (with
  the -n32 compiler flag). The compiler bug has been reported to SGI.

- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1   
  it works when compiled with cc.

- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
  is necessary to get gzprintf working correctly. This is done by configure.

- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
  with other compilers. Use "make test" to check your compiler.

- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.

- For Turbo C the small model is supported only with reduced performance to
  avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3

- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
  Per Harald Myrvang <perm@stud.cs.uit.no>


Acknowledgments:

  The deflate format used by zlib was defined by Phil Katz. The deflate
  and zlib specifications were written by L. Peter Deutsch. Thanks to all the
  people who reported problems and suggested various improvements in zlib;
  they are too numerous to cite here.

Copyright notice:

 (C) 1995-1998 Jean-loup Gailly and Mark Adler

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

  Jean-loup Gailly        Mark Adler
  jloup@gzip.org          madler@alumni.caltech.edu

If you use the zlib library in a product, we would appreciate *not*
receiving lengthy legal documents to sign. The sources are provided
for free but without warranty of any kind.  The library has been
entirely written by Jean-loup Gailly and Mark Adler; it does not
include third-party code.

If you redistribute modified sources, we would appreciate that you include
in the file ChangeLog history information documenting your changes.
\ No newline at end of file
diff --git a/SecurityServer/MacYarrow/zlib/adler32.c b/SecurityServer/MacYarrow/zlib/adler32.c
new file mode 100644
index 00000000..2b1f5161
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/adler32.c
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: adler32.c,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#include "zlib.h"
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long s1 = adler & 0xffff;
+    unsigned long s2 = (adler >> 16) & 0xffff;
+    int k;
+
+    if (buf == Z_NULL) return 1L;
+
+    while (len > 0) {
+        k = len < NMAX ? len : NMAX;
+        len -= k;
+        while (k >= 16) {
+            DO16(buf);
+	    buf += 16;
+            k -= 16;
+        }
+        if (k != 0) do {
+            s1 += *buf++;
+	    s2 += s1;
+        } while (--k);
+        s1 %= BASE;
+        s2 %= BASE;
+    }
+    return (s2 << 16) | s1;
+}
diff --git a/SecurityServer/MacYarrow/zlib/algorithm.txt b/SecurityServer/MacYarrow/zlib/algorithm.txt
new file mode 100644
index 00000000..0f681bda
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/algorithm.txt
@@ -0,0 +1 @@
+1. Compression algorithm (deflate)

The deflation algorithm used by gzip (also zip and zlib) is a variation of
LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
the input data.  The second occurrence of a string is replaced by a
pointer to the previous string, in the form of a pair (distance,
length).  Distances are limited to 32K bytes, and lengths are limited
to 258 bytes. When a string does not occur anywhere in the previous
32K bytes, it is emitted as a sequence of literal bytes.  (In this
description, `string' must be taken as an arbitrary sequence of bytes,
and is not restricted to printable characters.)

Literals or match lengths are compressed with one Huffman tree, and
match distances are compressed with another tree. The trees are stored
in a compact form at the start of each block. The blocks can have any
size (except that the compressed data for one block must fit in
available memory). A block is terminated when deflate() determines that
it would be useful to start another block with fresh trees. (This is
somewhat similar to the behavior of LZW-based _compress_.)

Duplicated strings are found using a hash table. All input strings of
length 3 are inserted in the hash table. A hash index is computed for
the next 3 bytes. If the hash chain for this index is not empty, all
strings in the chain are compared with the current input string, and
the longest match is selected.

The hash chains are searched starting with the most recent strings, to
favor small distances and thus take advantage of the Huffman encoding.
The hash chains are singly linked. There are no deletions from the
hash chains, the algorithm simply discards matches that are too old.

To avoid a worst-case situation, very long hash chains are arbitrarily
truncated at a certain length, determined by a runtime option (level
parameter of deflateInit). So deflate() does not always find the longest
possible match but generally finds a match which is long enough.

deflate() also defers the selection of matches with a lazy evaluation
mechanism. After a match of length N has been found, deflate() searches for
a longer match at the next input byte. If a longer match is found, the
previous match is truncated to a length of one (thus producing a single
literal byte) and the process of lazy evaluation begins again. Otherwise,
the original match is kept, and the next match search is attempted only N
steps later.

The lazy match evaluation is also subject to a runtime parameter. If
the current match is long enough, deflate() reduces the search for a longer
match, thus speeding up the whole process. If compression ratio is more
important than speed, deflate() attempts a complete second search even if
the first match is already long enough.

The lazy match evaluation is not performed for the fastest compression
modes (level parameter 1 to 3). For these fast modes, new strings
are inserted in the hash table only when no match was found, or
when the match is not too long. This degrades the compression ratio
but saves time since there are both fewer insertions and fewer searches.


2. Decompression algorithm (inflate)

2.1 Introduction

The real question is, given a Huffman tree, how to decode fast.  The most
important realization is that shorter codes are much more common than
longer codes, so pay attention to decoding the short codes fast, and let
the long codes take longer to decode.

inflate() sets up a first level table that covers some number of bits of
input less than the length of longest code.  It gets that many bits from the
stream, and looks it up in the table.  The table will tell if the next
code is that many bits or less and how many, and if it is, it will tell
the value, else it will point to the next level table for which inflate()
grabs more bits and tries to decode a longer code.

How many bits to make the first lookup is a tradeoff between the time it
takes to decode and the time it takes to build the table.  If building the
table took no time (and if you had infinite memory), then there would only
be a first level table to cover all the way to the longest code.  However,
building the table ends up taking a lot longer for more bits since short
codes are replicated many times in such a table.  What inflate() does is
simply to make the number of bits in the first table a variable, and set it
for the maximum speed.

inflate() sends new trees relatively often, so it is possibly set for a
smaller first level table than an application that has only one tree for
all the data.  For inflate, which has 286 possible codes for the
literal/length tree, the size of the first table is nine bits.  Also the
distance trees have 30 possible values, and the size of the first table is
six bits.  Note that for each of those cases, the table ended up one bit
longer than the ``average'' code length, i.e. the code length of an
approximately flat code which would be a little more than eight bits for
286 symbols and a little less than five bits for 30 symbols.  It would be
interesting to see if optimizing the first level table for other
applications gave values within a bit or two of the flat code size.


2.2 More details on the inflate table lookup

Ok, you want to know what this cleverly obfuscated inflate tree actually  
looks like.  You are correct that it's not a Huffman tree.  It is simply a  
lookup table for the first, let's say, nine bits of a Huffman symbol.  The  
symbol could be as short as one bit or as long as 15 bits.  If a particular  
symbol is shorter than nine bits, then that symbol's translation is duplicated
in all those entries that start with that symbol's bits.  For example, if the  
symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a  
symbol is nine bits long, it appears in the table once.

If the symbol is longer than nine bits, then that entry in the table points  
to another similar table for the remaining bits.  Again, there are duplicated  
entries as needed.  The idea is that most of the time the symbol will be short
and there will only be one table look up.  (That's whole idea behind data  
compression in the first place.)  For the less frequent long symbols, there  
will be two lookups.  If you had a compression method with really long  
symbols, you could have as many levels of lookups as is efficient.  For  
inflate, two is enough.

So a table entry either points to another table (in which case nine bits in  
the above example are gobbled), or it contains the translation for the symbol  
and the number of bits to gobble.  Then you start again with the next  
ungobbled bit.

You may wonder: why not just have one lookup table for how ever many bits the  
longest symbol is?  The reason is that if you do that, you end up spending  
more time filling in duplicate symbol entries than you do actually decoding.   
At least for deflate's output that generates new trees every several 10's of  
kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code  
would take too long if you're only decoding several thousand symbols.  At the  
other extreme, you could make a new table for every bit in the code.  In fact,
that's essentially a Huffman tree.  But then you spend two much time  
traversing the tree while decoding, even for short symbols.

So the number of bits for the first lookup table is a trade of the time to  
fill out the table vs. the time spent looking at the second level and above of
the table.

Here is an example, scaled down:

The code being decoded, with 10 symbols, from 1 to 6 bits long:

A: 0
B: 10
C: 1100
D: 11010
E: 11011
F: 11100
G: 11101
H: 11110
I: 111110
J: 111111

Let's make the first table three bits long (eight entries):

000: A,1
001: A,1
010: A,1
011: A,1
100: B,2
101: B,2
110: -> table X (gobble 3 bits)
111: -> table Y (gobble 3 bits)

Each entry is what the bits decode to and how many bits that is, i.e. how  
many bits to gobble.  Or the entry points to another table, with the number of
bits to gobble implicit in the size of the table.

Table X is two bits long since the longest code starting with 110 is five bits
long:

00: C,1
01: C,1
10: D,2
11: E,2

Table Y is three bits long since the longest code starting with 111 is six  
bits long:

000: F,2
001: F,2
010: G,2
011: G,2
100: H,2
101: H,2
110: I,3
111: J,3

So what we have here are three tables with a total of 20 entries that had to  
be constructed.  That's compared to 64 entries for a single table.  Or  
compared to 16 entries for a Huffman tree (six two entry tables and one four  
entry table).  Assuming that the code ideally represents the probability of  
the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
to one lookup for the single table, or 1.66 lookups per symbol for the  
Huffman tree.

There, I think that gives you a picture of what's going on.  For inflate, the  
meaning of a particular symbol is often more than just a letter.  It can be a  
byte (a "literal"), or it can be either a length or a distance which  
indicates a base value and a number of bits to fetch after the code that is  
added to the base value.  Or it might be the special end-of-block code.  The  
data structures created in inftrees.c try to encode all that information  
compactly in the tables.


Jean-loup Gailly        Mark Adler
jloup@gzip.org          madler@alumni.caltech.edu


References:

[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
pp. 337-343.

``DEFLATE Compressed Data Format Specification'' available in
ftp://ds.internic.net/rfc/rfc1951.txt
\ No newline at end of file
diff --git a/SecurityServer/MacYarrow/zlib/compress.c b/SecurityServer/MacYarrow/zlib/compress.c
new file mode 100644
index 00000000..4c65bdb8
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/compress.c
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: compress.c,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
diff --git a/SecurityServer/MacYarrow/zlib/crc32.c b/SecurityServer/MacYarrow/zlib/crc32.c
new file mode 100644
index 00000000..8382b7ca
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/crc32.c
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+
+
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: crc32.c,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#include "zlib.h"
+
+#define local static
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local int crc_table_empty = 1;
+local uLongf crc_table[256];
+local void make_crc_table OF((void));
+
+/*
+  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The table is simply the CRC of all possible eight bit values.  This is all
+  the information needed to generate CRC's on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.
+*/
+local void make_crc_table()
+{
+  uLong c;
+  int n, k;
+  uLong poly;            /* polynomial exclusive-or pattern */
+  /* terms of polynomial defining this crc (except x^32): */
+  static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  /* make exclusive-or pattern from polynomial (0xedb88320L) */
+  poly = 0L;
+  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
+    poly |= 1L << (31 - p[n]);
+ 
+  for (n = 0; n < 256; n++)
+  {
+    c = (uLong)n;
+    for (k = 0; k < 8; k++)
+      c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+    crc_table[n] = c;
+  }
+  crc_table_empty = 0;
+}
+#else
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+local const uLongf crc_table[256] = {
+  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+  0x2d02ef8dL
+};
+#endif
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const uLongf * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+  if (crc_table_empty) make_crc_table();
+#endif
+  return (const uLongf *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong ZEXPORT crc32(crc, buf, len)
+    uLong crc;
+    const Bytef *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0L;
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+      make_crc_table();
+#endif
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}
diff --git a/SecurityServer/MacYarrow/zlib/deflate.c b/SecurityServer/MacYarrow/zlib/deflate.c
new file mode 100644
index 00000000..1f18268a
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/deflate.c
@@ -0,0 +1,1368 @@
+/*
+ * 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.
+ */
+
+
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id: deflate.c,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+			 Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+		  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int noheader = 0;
+    static const char* my_version = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+	return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == Z_NULL) {
+	strm->zalloc = zcalloc;
+	strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == Z_NULL) strm->zfree = zcfree;
+
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#ifdef FASTEST
+    level = 1;
+#endif
+
+    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+        noheader = 1;
+        windowBits = -windowBits;
+    }
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+        return Z_STREAM_ERROR;
+    }
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->noheader = noheader;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+        strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
+
+    s = strm->state;
+    strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > MAX_DIST(s)) {
+	length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+	dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+    }
+    zmemcpy(s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+	INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+    
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->noheader < 0) {
+        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
+    }
+    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+    strm->adler = 1;
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+    if (level == Z_DEFAULT_COMPRESSION) {
+	level = 6;
+    }
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+	return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if (func != configuration_table[level].func && strm->total_in != 0) {
+	/* Flush the last buffer: */
+	err = deflate(strm, Z_PARTIAL_FLUSH);
+    }
+    if (s->level != level) {
+	s->level = level;
+	s->max_lazy_match   = configuration_table[level].max_lazy;
+	s->good_match       = configuration_table[level].good_length;
+	s->nice_match       = configuration_table[level].nice_length;
+	s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}   
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len = strm->state->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, strm->state->pending_out, len);
+    strm->next_out  += len;
+    strm->state->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    strm->state->pending -= len;
+    if (strm->state->pending == 0) {
+        strm->state->pending_out = strm->state->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+	flush > Z_FINISH || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+	(s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the zlib header */
+    if (s->status == INIT_STATE) {
+
+        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+        uInt level_flags = (s->level-1) >> 1;
+
+        if (level_flags > 3) level_flags = 3;
+        header |= (level_flags << 6);
+	if (s->strstart != 0) header |= PRESET_DICT;
+        header += 31 - (header % 31);
+
+        s->status = BUSY_STATE;
+        putShortMSB(s, header);
+
+	/* Save the adler32 of the preset dictionary: */
+	if (s->strstart != 0) {
+	    putShortMSB(s, (uInt)(strm->adler >> 16));
+	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+	}
+	strm->adler = 1L;
+    }
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+	    /* Since avail_out is 0, deflate will be called again with
+	     * more output space, but possibly with both pending and
+	     * avail_in equal to zero. There won't be anything to do,
+	     * but this is not an error situation so make sure we
+	     * return OK instead of BUF_ERROR at next call of deflate:
+             */
+	    s->last_flush = -1;
+	    return Z_OK;
+	}
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+	       flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+	bstate = (*(configuration_table[s->level].func))(s, flush);
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+	    if (strm->avail_out == 0) {
+	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+	    }
+	    return Z_OK;
+	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+	     * of deflate should use the same flush parameter to make sure
+	     * that the flush is complete. So we don't have to output an
+	     * empty block here, this will be done at next call. This also
+	     * ensures that for a very small output buffer, we emit at most
+	     * one empty block.
+	     */
+	}
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                }
+            }
+            flush_pending(strm);
+	    if (strm->avail_out == 0) {
+	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+	      return Z_OK;
+	    }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->noheader) return Z_STREAM_END;
+
+    /* Write the zlib trailer (adler32) */
+    putShortMSB(s, (uInt)(strm->adler >> 16));
+    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    s->noheader = -1; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE && status != BUSY_STATE &&
+	status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    *dest = *source;
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    *ds = *ss;
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (!strm->state->noheader) {
+        strm->adler = adler32(strm->adler, strm->next_in, len);
+    }
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+}
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+#ifndef FASTEST
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2:
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+
+#else /* FASTEST */
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return len <= s->lookahead ? len : s->lookahead;
+}
+#endif /* FASTEST */
+#endif /* ASMV */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+		start, match, length);
+        do {
+	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+	} while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+            more = wsize;
+
+        } else if (more == (unsigned)(-1)) {
+            /* Very unlikely, but possible on 16 bit machine if strstart == 0
+             * and lookahead == 1 (input done one byte at time)
+             */
+            more--;
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+	    n = s->hash_size;
+	    p = &s->head[n];
+	    do {
+		m = *--p;
+		*p = (Pos)(m >= wsize ? m-wsize : NIL);
+	    } while (--n);
+
+	    n = wsize;
+#ifndef FASTEST
+	    p = &s->prev[n];
+	    do {
+		m = *--p;
+		*p = (Pos)(m >= wsize ? m-wsize : NIL);
+		/* If n is not on any hash chain, prev[n] is garbage but
+		 * its value will never be used.
+		 */
+	    } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+		(ulg)((long)s->strstart - s->block_start), \
+		(eof)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+   FLUSH_BLOCK_ONLY(s, eof); \
+   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+		   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+	Assert(s->block_start >= 0L, "block gone");
+
+	s->strstart += s->lookahead;
+	s->lookahead = 0;
+
+	/* Emit a stored block if pending_buf will be full: */
+ 	max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+	    /* strstart == 0 is possible when wraparound on 16-bit machine */
+	    s->lookahead = (uInt)(s->strstart - max_start);
+	    s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+	}
+	/* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+	}
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL; /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in hash table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++; 
+            } else
+#endif
+	    {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++; 
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL;    /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+                 (s->match_length == MIN_MATCH &&
+                  s->strstart - s->match_start > TOO_FAR))) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+			   s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+	    _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+	    if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
diff --git a/SecurityServer/MacYarrow/zlib/deflate.h b/SecurityServer/MacYarrow/zlib/deflate.h
new file mode 100644
index 00000000..4e5913d9
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/deflate.h
@@ -0,0 +1,336 @@
+/*
+ * 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.
+ */
+
+
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-1998 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: deflate.h,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#ifndef _DEFLATE_H
+#define _DEFLATE_H
+
+#include "zutil.h"
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    int   pending;       /* nb of bytes in the pending buffer */
+    int   noheader;      /* suppress zlib header and adler32 */
+    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+        /* in trees.c */
+void _tr_init         OF((deflate_state *s));
+int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
+			  int eof));
+void _tr_align        OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch _length_code[];
+  extern uch _dist_code[];
+#else
+  extern const uch _length_code[];
+  extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length) 
+#endif
+
+#endif
diff --git a/SecurityServer/MacYarrow/zlib/infblock.c b/SecurityServer/MacYarrow/zlib/infblock.c
new file mode 100644
index 00000000..90b6d0c9
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/infblock.c
@@ -0,0 +1,416 @@
+/*
+ * 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.
+ */
+
+
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local const uInt border[] = { /* Order of the bit length code lengths */
+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+   Notes beyond the 1.93a appnote.txt:
+
+   1. Distance pointers never point before the beginning of the output
+      stream.
+   2. Distance pointers can point back across blocks, up to 32k away.
+   3. There is an implied maximum of 7 bits for the bit length table and
+      15 bits for the actual data.
+   4. If only one code exists, then it is encoded using one bit.  (Zero
+      would be more efficient, but perhaps a little confusing.)  If two
+      codes exist, they are coded using one bit each (0 and 1).
+   5. There is no way of sending zero distance codes--a dummy must be
+      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+      store blocks with no distance codes, but this was discovered to be
+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+      zero distance codes, which is sent as one code of zero bits in
+      length.
+   6. There are up to 286 literal/length codes.  Code 256 represents the
+      end-of-block.  Note however that the static length tree defines
+      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+      cannot be used though, since there is no length base or extra bits
+      defined for them.  Similarily, there are up to 30 distance codes.
+      However, static trees define 32 codes (all 5 bits) to fill out the
+      Huffman codes, but the last two had better not show up in the data.
+   7. Unzip can check dynamic Huffman blocks for complete code sets.
+      The exception is that a single code would not be complete (see #4).
+   8. The five bits following the block type is really the number of
+      literal codes sent minus 257.
+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+      (1+6+6).  Therefore, to output three times the length, you output
+      three codes (1+1+1), whereas to output four times the same length,
+      you only need two codes (1+3).  Hmm.
+  10. In the tree reconstruction algorithm, Code = Code + Increment
+      only if BitLength(i) is not zero.  (Pretty obvious.)
+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+  12. Note: length code 284 can represent 227-258, but length code 285
+      really is 258.  The last length deserves its own, short code
+      since it gets used a lot in very redundant files.  The length
+      258 is special since 258 - 3 (the min match length) is 255.
+  13. The literal/length and distance code bit lengths are read as a
+      single stream of lengths.  It is possible (and advantageous) for
+      a repeat code (16, 17, or 18) to go across the boundary between
+      the two sets of lengths.
+ */
+
+
+void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_streamp z;
+uLongf *c;
+{
+  if (c != Z_NULL)
+    *c = s->check;
+  if (s->mode == BTREE || s->mode == DTREE)
+    ZFREE(z, s->sub.trees.blens);
+  if (s->mode == CODES)
+    inflate_codes_free(s->sub.decode.codes, z);
+  s->mode = TYPE;
+  s->bitk = 0;
+  s->bitb = 0;
+  s->read = s->write = s->window;
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
+  Tracev((stderr, "inflate:   blocks reset\n"));
+}
+
+
+inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_streamp z;
+check_func c;
+uInt w;
+{
+  inflate_blocks_statef *s;
+
+  if ((s = (inflate_blocks_statef *)ZALLOC
+       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+    return s;
+  if ((s->hufts =
+       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
+  {
+    ZFREE(z, s);
+    return Z_NULL;
+  }
+  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+  {
+    ZFREE(z, s->hufts);
+    ZFREE(z, s);
+    return Z_NULL;
+  }
+  s->end = s->window + w;
+  s->checkfn = c;
+  s->mode = TYPE;
+  Tracev((stderr, "inflate:   blocks allocated\n"));
+  inflate_blocks_reset(s, z, Z_NULL);
+  return s;
+}
+
+
+int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt t;               /* temporary storage */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input based on current state */
+  while (1) switch (s->mode)
+  {
+    case TYPE:
+      NEEDBITS(3)
+      t = (uInt)b & 7;
+      s->last = t & 1;
+      switch (t >> 1)
+      {
+        case 0:                         /* stored */
+          Tracev((stderr, "inflate:     stored block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          t = k & 7;                    /* go to byte boundary */
+          DUMPBITS(t)
+          s->mode = LENS;               /* get length of stored block */
+          break;
+        case 1:                         /* fixed */
+          Tracev((stderr, "inflate:     fixed codes block%s\n",
+                 s->last ? " (last)" : ""));
+          {
+            uInt bl, bd;
+            inflate_huft *tl, *td;
+
+            inflate_trees_fixed(&bl, &bd, &tl, &td, z);
+            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+            if (s->sub.decode.codes == Z_NULL)
+            {
+              r = Z_MEM_ERROR;
+              LEAVE
+            }
+          }
+          DUMPBITS(3)
+          s->mode = CODES;
+          break;
+        case 2:                         /* dynamic */
+          Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          s->mode = TABLE;
+          break;
+        case 3:                         /* illegal */
+          DUMPBITS(3)
+          s->mode = BAD;
+          z->msg = (char*)"invalid block type";
+          r = Z_DATA_ERROR;
+          LEAVE
+      }
+      break;
+    case LENS:
+      NEEDBITS(32)
+      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
+      {
+        s->mode = BAD;
+        z->msg = (char*)"invalid stored block lengths";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+      s->sub.left = (uInt)b & 0xffff;
+      b = k = 0;                      /* dump bits */
+      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
+      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
+      break;
+    case STORED:
+      if (n == 0)
+        LEAVE
+      NEEDOUT
+      t = s->sub.left;
+      if (t > n) t = n;
+      if (t > m) t = m;
+      zmemcpy(q, p, t);
+      p += t;  n -= t;
+      q += t;  m -= t;
+      if ((s->sub.left -= t) != 0)
+        break;
+      Tracev((stderr, "inflate:       stored end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      s->mode = s->last ? DRY : TYPE;
+      break;
+    case TABLE:
+      NEEDBITS(14)
+      s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+      {
+        s->mode = BAD;
+        z->msg = (char*)"too many length or distance symbols";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+#endif
+      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+      {
+        r = Z_MEM_ERROR;
+        LEAVE
+      }
+      DUMPBITS(14)
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       table sizes ok\n"));
+      s->mode = BTREE;
+    case BTREE:
+      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+      {
+        NEEDBITS(3)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+        DUMPBITS(3)
+      }
+      while (s->sub.trees.index < 19)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+      s->sub.trees.bb = 7;
+      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+                             &s->sub.trees.tb, s->hufts, z);
+      if (t != Z_OK)
+      {
+        ZFREE(z, s->sub.trees.blens);
+        r = t;
+        if (r == Z_DATA_ERROR)
+          s->mode = BAD;
+        LEAVE
+      }
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       bits tree ok\n"));
+      s->mode = DTREE;
+    case DTREE:
+      while (t = s->sub.trees.table,
+             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+      {
+        inflate_huft *h;
+        uInt i, j, c;
+
+        t = s->sub.trees.bb;
+        NEEDBITS(t)
+        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+        t = h->bits;
+        c = h->base;
+        if (c < 16)
+        {
+          DUMPBITS(t)
+          s->sub.trees.blens[s->sub.trees.index++] = c;
+        }
+        else /* c == 16..18 */
+        {
+          i = c == 18 ? 7 : c - 14;
+          j = c == 18 ? 11 : 3;
+          NEEDBITS(t + i)
+          DUMPBITS(t)
+          j += (uInt)b & inflate_mask[i];
+          DUMPBITS(i)
+          i = s->sub.trees.index;
+          t = s->sub.trees.table;
+          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+              (c == 16 && i < 1))
+          {
+            ZFREE(z, s->sub.trees.blens);
+            s->mode = BAD;
+            z->msg = (char*)"invalid bit length repeat";
+            r = Z_DATA_ERROR;
+            LEAVE
+          }
+          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+          do {
+            s->sub.trees.blens[i++] = c;
+          } while (--j);
+          s->sub.trees.index = i;
+        }
+      }
+      s->sub.trees.tb = Z_NULL;
+      {
+        uInt bl, bd;
+        inflate_huft *tl, *td;
+        inflate_codes_statef *c;
+
+        bl = 9;         /* must be <= 9 for lookahead assumptions */
+        bd = 6;         /* must be <= 9 for lookahead assumptions */
+        t = s->sub.trees.table;
+        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
+                                  s->hufts, z);
+        ZFREE(z, s->sub.trees.blens);
+        if (t != Z_OK)
+        {
+          if (t == (uInt)Z_DATA_ERROR)
+            s->mode = BAD;
+          r = t;
+          LEAVE
+        }
+        Tracev((stderr, "inflate:       trees ok\n"));
+        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+        {
+          r = Z_MEM_ERROR;
+          LEAVE
+        }
+        s->sub.decode.codes = c;
+      }
+      s->mode = CODES;
+    case CODES:
+      UPDATE
+      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+        return inflate_flush(s, z, r);
+      r = Z_OK;
+      inflate_codes_free(s->sub.decode.codes, z);
+      LOAD
+      Tracev((stderr, "inflate:       codes end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      if (!s->last)
+      {
+        s->mode = TYPE;
+        break;
+      }
+      s->mode = DRY;
+    case DRY:
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      s->mode = DONE;
+    case DONE:
+      r = Z_STREAM_END;
+      LEAVE
+    case BAD:
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+int inflate_blocks_free(s, z)
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  inflate_blocks_reset(s, z, Z_NULL);
+  ZFREE(z, s->window);
+  ZFREE(z, s->hufts);
+  ZFREE(z, s);
+  Tracev((stderr, "inflate:   blocks freed\n"));
+  return Z_OK;
+}
+
+
+void inflate_set_dictionary(s, d, n)
+inflate_blocks_statef *s;
+const Bytef *d;
+uInt  n;
+{
+  zmemcpy(s->window, d, n);
+  s->read = s->write = s->window + n;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
+ * IN assertion: s != Z_NULL
+ */
+int inflate_blocks_sync_point(s)
+inflate_blocks_statef *s;
+{
+  return s->mode == LENS;
+}
diff --git a/SecurityServer/MacYarrow/zlib/infblock.h b/SecurityServer/MacYarrow/zlib/infblock.h
new file mode 100644
index 00000000..dfd11411
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/infblock.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+extern inflate_blocks_statef * inflate_blocks_new OF((
+    z_streamp z,
+    check_func c,               /* check function */
+    uInt w));                   /* window size */
+
+extern int inflate_blocks OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));                      /* initial return code */
+
+extern void inflate_blocks_reset OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    uLongf *));                  /* check value on output */
+
+extern int inflate_blocks_free OF((
+    inflate_blocks_statef *,
+    z_streamp));
+
+extern void inflate_set_dictionary OF((
+    inflate_blocks_statef *s,
+    const Bytef *d,  /* dictionary */
+    uInt  n));       /* dictionary length */
+
+extern int inflate_blocks_sync_point OF((
+    inflate_blocks_statef *s));
diff --git a/SecurityServer/MacYarrow/zlib/infcodes.c b/SecurityServer/MacYarrow/zlib/infcodes.c
new file mode 100644
index 00000000..9351354c
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/infcodes.c
@@ -0,0 +1,275 @@
+/*
+ * 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.
+ */
+
+
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+      START,    /* x: set up for LEN */
+      LEN,      /* i: get length/literal/eob next */
+      LENEXT,   /* i: getting length extra (have base) */
+      DIST,     /* i: get distance next */
+      DISTEXT,  /* i: getting distance extra */
+      COPY,     /* o: copying bytes in window, waiting for space */
+      LIT,      /* o: got literal, waiting for output space */
+      WASH,     /* o: got eob, possibly still output waiting */
+      END,      /* x: got eob and all data flushed */
+      BADCODE}  /* x: got error */
+inflate_codes_mode;
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+  /* mode */
+  inflate_codes_mode mode;      /* current inflate_codes mode */
+
+  /* mode dependent information */
+  uInt len;
+  union {
+    struct {
+      inflate_huft *tree;       /* pointer into tree */
+      uInt need;                /* bits needed */
+    } code;             /* if LEN or DIST, where in tree */
+    uInt lit;           /* if LIT, literal */
+    struct {
+      uInt get;                 /* bits to get for extra */
+      uInt dist;                /* distance back to copy from */
+    } copy;             /* if EXT or COPY, where and how much */
+  } sub;                /* submode */
+
+  /* mode independent information */
+  Byte lbits;           /* ltree bits decoded per branch */
+  Byte dbits;           /* dtree bits decoder per branch */
+  inflate_huft *ltree;          /* literal/length/eob tree */
+  inflate_huft *dtree;          /* distance tree */
+
+};
+
+
+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+z_streamp z;
+{
+  inflate_codes_statef *c;
+
+  if ((c = (inflate_codes_statef *)
+       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+  {
+    c->mode = START;
+    c->lbits = (Byte)bl;
+    c->dbits = (Byte)bd;
+    c->ltree = tl;
+    c->dtree = td;
+    Tracev((stderr, "inflate:       codes new\n"));
+  }
+  return c;
+}
+
+
+int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt j;               /* temporary storage */
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  Bytef *f;             /* pointer to copy strings from */
+  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input and output based on current state */
+  while (1) switch (c->mode)
+  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+    case START:         /* x: set up for LEN */
+#ifndef SLOW
+      if (m >= 258 && n >= 10)
+      {
+        UPDATE
+        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+        LOAD
+        if (r != Z_OK)
+        {
+          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+          break;
+        }
+      }
+#endif /* !SLOW */
+      c->sub.code.need = c->lbits;
+      c->sub.code.tree = c->ltree;
+      c->mode = LEN;
+    case LEN:           /* i: get length/literal/eob next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e == 0)               /* literal */
+      {
+        c->sub.lit = t->base;
+        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                 "inflate:         literal '%c'\n" :
+                 "inflate:         literal 0x%02x\n", t->base));
+        c->mode = LIT;
+        break;
+      }
+      if (e & 16)               /* length */
+      {
+        c->sub.copy.get = e & 15;
+        c->len = t->base;
+        c->mode = LENEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t + t->base;
+        break;
+      }
+      if (e & 32)               /* end of block */
+      {
+        Tracevv((stderr, "inflate:         end of block\n"));
+        c->mode = WASH;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid literal/length code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case LENEXT:        /* i: getting length extra (have base) */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->len += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      c->sub.code.need = c->dbits;
+      c->sub.code.tree = c->dtree;
+      Tracevv((stderr, "inflate:         length %u\n", c->len));
+      c->mode = DIST;
+    case DIST:          /* i: get distance next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e & 16)               /* distance */
+      {
+        c->sub.copy.get = e & 15;
+        c->sub.copy.dist = t->base;
+        c->mode = DISTEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t + t->base;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid distance code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case DISTEXT:       /* i: getting distance extra */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->sub.copy.dist += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
+      c->mode = COPY;
+    case COPY:          /* o: copying bytes in window, waiting for space */
+#ifndef __TURBOC__ /* Turbo C bug for following expression */
+      f = (uInt)(q - s->window) < c->sub.copy.dist ?
+          s->end - (c->sub.copy.dist - (q - s->window)) :
+          q - c->sub.copy.dist;
+#else
+      f = q - c->sub.copy.dist;
+      if ((uInt)(q - s->window) < c->sub.copy.dist)
+        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
+#endif
+      while (c->len)
+      {
+        NEEDOUT
+        OUTBYTE(*f++)
+        if (f == s->end)
+          f = s->window;
+        c->len--;
+      }
+      c->mode = START;
+      break;
+    case LIT:           /* o: got literal, waiting for output space */
+      NEEDOUT
+      OUTBYTE(c->sub.lit)
+      c->mode = START;
+      break;
+    case WASH:          /* o: got eob, possibly more output */
+      if (k > 7)        /* return unused byte, if any */
+      {
+        Assert(k < 16, "inflate_codes grabbed too many bytes")
+        k -= 8;
+        n++;
+        p--;            /* can always return one */
+      }
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      c->mode = END;
+    case END:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADCODE:       /* x: got error */
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+#ifdef NEED_DUMMY_RETURN
+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
+#endif
+}
+
+
+void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_streamp z;
+{
+  ZFREE(z, c);
+  Tracev((stderr, "inflate:       codes free\n"));
+}
diff --git a/SecurityServer/MacYarrow/zlib/infcodes.h b/SecurityServer/MacYarrow/zlib/infcodes.h
new file mode 100644
index 00000000..cb79604e
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/infcodes.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+extern inflate_codes_statef *inflate_codes_new OF((
+    uInt, uInt,
+    inflate_huft *, inflate_huft *,
+    z_streamp ));
+
+extern int inflate_codes OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+extern void inflate_codes_free OF((
+    inflate_codes_statef *,
+    z_streamp ));
+
diff --git a/SecurityServer/MacYarrow/zlib/inffast.c b/SecurityServer/MacYarrow/zlib/inffast.c
new file mode 100644
index 00000000..413da202
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/inffast.c
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
+
+/* Called with number of bytes left to write in window at least 258
+   (the maximum string length) and number of input bytes available
+   at least ten.  The ten bytes are six bytes for the longest length/
+   distance pair plus four bytes for overloading the bit buffer. */
+
+int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  uInt ml;              /* mask for literal/length tree */
+  uInt md;              /* mask for distance tree */
+  uInt c;               /* bytes to copy */
+  uInt d;               /* distance back to copy from */
+  Bytef *r;             /* copy source pointer */
+
+  /* load input, output, bit values */
+  LOAD
+
+  /* initialize masks */
+  ml = inflate_mask[bl];
+  md = inflate_mask[bd];
+
+  /* do until not enough input or output space for fast loop */
+  do {                          /* assume called with m >= 258 && n >= 10 */
+    /* get literal/length code */
+    GRABBITS(20)                /* max bits for literal/length code */
+    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+    {
+      DUMPBITS(t->bits)
+      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                "inflate:         * literal '%c'\n" :
+                "inflate:         * literal 0x%02x\n", t->base));
+      *q++ = (Byte)t->base;
+      m--;
+      continue;
+    }
+    do {
+      DUMPBITS(t->bits)
+      if (e & 16)
+      {
+        /* get extra bits for length */
+        e &= 15;
+        c = t->base + ((uInt)b & inflate_mask[e]);
+        DUMPBITS(e)
+        Tracevv((stderr, "inflate:         * length %u\n", c));
+
+        /* decode distance base of block to copy */
+        GRABBITS(15);           /* max bits for distance code */
+        e = (t = td + ((uInt)b & md))->exop;
+        do {
+          DUMPBITS(t->bits)
+          if (e & 16)
+          {
+            /* get extra bits to add to distance base */
+            e &= 15;
+            GRABBITS(e)         /* get extra bits (up to 13) */
+            d = t->base + ((uInt)b & inflate_mask[e]);
+            DUMPBITS(e)
+            Tracevv((stderr, "inflate:         * distance %u\n", d));
+
+            /* do the copy */
+            m -= c;
+            if ((uInt)(q - s->window) >= d)     /* offset before dest */
+            {                                   /*  just copy */
+              r = q - d;
+              *q++ = *r++;  c--;        /* minimum count is three, */
+              *q++ = *r++;  c--;        /*  so unroll loop a little */
+            }
+            else                        /* else offset after destination */
+            {
+              e = d - (uInt)(q - s->window); /* bytes from offset to end */
+              r = s->end - e;           /* pointer to offset */
+              if (c > e)                /* if source crosses, */
+              {
+                c -= e;                 /* copy to end of window */
+                do {
+                  *q++ = *r++;
+                } while (--e);
+                r = s->window;          /* copy rest from start of window */
+              }
+            }
+            do {                        /* copy all or what's left */
+              *q++ = *r++;
+            } while (--c);
+            break;
+          }
+          else if ((e & 64) == 0)
+          {
+            t += t->base;
+            e = (t += ((uInt)b & inflate_mask[e]))->exop;
+          }
+          else
+          {
+            z->msg = (char*)"invalid distance code";
+            UNGRAB
+            UPDATE
+            return Z_DATA_ERROR;
+          }
+        } while (1);
+        break;
+      }
+      if ((e & 64) == 0)
+      {
+        t += t->base;
+        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
+        {
+          DUMPBITS(t->bits)
+          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                    "inflate:         * literal '%c'\n" :
+                    "inflate:         * literal 0x%02x\n", t->base));
+          *q++ = (Byte)t->base;
+          m--;
+          break;
+        }
+      }
+      else if (e & 32)
+      {
+        Tracevv((stderr, "inflate:         * end of block\n"));
+        UNGRAB
+        UPDATE
+        return Z_STREAM_END;
+      }
+      else
+      {
+        z->msg = (char*)"invalid literal/length code";
+        UNGRAB
+        UPDATE
+        return Z_DATA_ERROR;
+      }
+    } while (1);
+  } while (m >= 258 && n >= 10);
+
+  /* not enough input or output--restore pointers and return */
+  UNGRAB
+  UPDATE
+  return Z_OK;
+}
diff --git a/SecurityServer/MacYarrow/zlib/inffast.h b/SecurityServer/MacYarrow/zlib/inffast.h
new file mode 100644
index 00000000..cd8b0d73
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/inffast.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+extern int inflate_fast OF((
+    uInt,
+    uInt,
+    inflate_huft *,
+    inflate_huft *,
+    inflate_blocks_statef *,
+    z_streamp ));
diff --git a/SecurityServer/MacYarrow/zlib/inffixed.h b/SecurityServer/MacYarrow/zlib/inffixed.h
new file mode 100644
index 00000000..bcc921d7
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/inffixed.h
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+
+/* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by the maketree.c program
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+local uInt fixed_bl = 9;
+local uInt fixed_bd = 5;
+local inflate_huft fixed_tl[] = {
+    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
+    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
+    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
+    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
+    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
+    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
+    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
+    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
+    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
+    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
+    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
+    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
+    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
+    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
+    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
+    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
+    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
+    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
+    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
+    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
+    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
+    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
+    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
+    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
+    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
+    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
+    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
+    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
+    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
+    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
+    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
+    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
+    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
+    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
+    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
+    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
+    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
+    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
+    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
+    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
+    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
+    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
+    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
+    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
+    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
+    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
+    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
+    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
+    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
+    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
+    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
+    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
+    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
+    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
+    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
+    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
+    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
+    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
+    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
+    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
+    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
+    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
+    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
+    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
+    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
+    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
+    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
+    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
+    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
+    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
+    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
+    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
+    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
+    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
+    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
+    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
+    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
+    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
+    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
+    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
+    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
+    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
+    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
+    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
+    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
+    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
+    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
+    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
+    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
+    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
+    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
+    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
+    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
+    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
+    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
+    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
+    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
+    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
+    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
+    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
+    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
+    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
+    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
+    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
+    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
+    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
+    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
+    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
+    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
+    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
+    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
+    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
+  };
+local inflate_huft fixed_td[] = {
+    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
+    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
+    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
+    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
+    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
+    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
+    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
+    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
+  };
diff --git a/SecurityServer/MacYarrow/zlib/inflate.c b/SecurityServer/MacYarrow/zlib/inflate.c
new file mode 100644
index 00000000..b85be900
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/inflate.c
@@ -0,0 +1,384 @@
+/*
+ * 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.
+ */
+
+
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+
+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
+
+typedef enum {
+      METHOD,   /* waiting for method byte */
+      FLAG,     /* waiting for flag byte */
+      DICT4,    /* four dictionary check bytes to go */
+      DICT3,    /* three dictionary check bytes to go */
+      DICT2,    /* two dictionary check bytes to go */
+      DICT1,    /* one dictionary check byte to go */
+      DICT0,    /* waiting for inflateSetDictionary */
+      BLOCKS,   /* decompressing blocks */
+      CHECK4,   /* four check bytes to go */
+      CHECK3,   /* three check bytes to go */
+      CHECK2,   /* two check bytes to go */
+      CHECK1,   /* one check byte to go */
+      DONE,     /* finished check, done */
+      BAD}      /* got an error--stay here */
+inflate_mode;
+
+/* inflate private state */
+struct internal_state {
+
+  /* mode */
+  inflate_mode  mode;   /* current inflate mode */
+
+  /* mode dependent information */
+  union {
+    uInt method;        /* if FLAGS, method byte */
+    struct {
+      uLong was;                /* computed check value */
+      uLong need;               /* stream check value */
+    } check;            /* if CHECK, check values to compare */
+    uInt marker;        /* if BAD, inflateSync's marker bytes count */
+  } sub;        /* submode */
+
+  /* mode independent information */
+  int  nowrap;          /* flag for no wrapper */
+  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
+  inflate_blocks_statef 
+    *blocks;            /* current inflate_blocks state */
+
+};
+
+
+int ZEXPORT inflateReset(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->total_in = z->total_out = 0;
+  z->msg = Z_NULL;
+  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
+  Tracev((stderr, "inflate: reset\n"));
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateEnd(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->blocks != Z_NULL)
+    inflate_blocks_free(z->state->blocks, z);
+  ZFREE(z, z->state);
+  z->state = Z_NULL;
+  Tracev((stderr, "inflate: end\n"));
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateInit2_(z, w, version, stream_size)
+z_streamp z;
+int w;
+const char *version;
+int stream_size;
+{
+  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+      stream_size != sizeof(z_stream))
+      return Z_VERSION_ERROR;
+
+  /* initialize state */
+  if (z == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->msg = Z_NULL;
+  if (z->zalloc == Z_NULL)
+  {
+    z->zalloc = zcalloc;
+    z->opaque = (voidpf)0;
+  }
+  if (z->zfree == Z_NULL) z->zfree = zcfree;
+  if ((z->state = (struct internal_state FAR *)
+       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+    return Z_MEM_ERROR;
+  z->state->blocks = Z_NULL;
+
+  /* handle undocumented nowrap option (no zlib header or check) */
+  z->state->nowrap = 0;
+  if (w < 0)
+  {
+    w = - w;
+    z->state->nowrap = 1;
+  }
+
+  /* set window size */
+  if (w < 8 || w > 15)
+  {
+    inflateEnd(z);
+    return Z_STREAM_ERROR;
+  }
+  z->state->wbits = (uInt)w;
+
+  /* create inflate_blocks state */
+  if ((z->state->blocks =
+      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
+      == Z_NULL)
+  {
+    inflateEnd(z);
+    return Z_MEM_ERROR;
+  }
+  Tracev((stderr, "inflate: allocated\n"));
+
+  /* reset state */
+  inflateReset(z);
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateInit_(z, version, stream_size)
+z_streamp z;
+const char *version;
+int stream_size;
+{
+  return inflateInit2_(z, DEF_WBITS, version, stream_size);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int ZEXPORT inflate(z, f)
+z_streamp z;
+int f;
+{
+  int r;
+  uInt b;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
+    return Z_STREAM_ERROR;
+  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+  r = Z_BUF_ERROR;
+  while (1) switch (z->state->mode)
+  {
+    case METHOD:
+      NEEDBYTE
+      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"unknown compression method";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"invalid window size";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      z->state->mode = FLAG;
+    case FLAG:
+      NEEDBYTE
+      b = NEXTBYTE;
+      if (((z->state->sub.method << 8) + b) % 31)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"incorrect header check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Tracev((stderr, "inflate: zlib header ok\n"));
+      if (!(b & PRESET_DICT))
+      {
+        z->state->mode = BLOCKS;
+        break;
+      }
+      z->state->mode = DICT4;
+    case DICT4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = DICT3;
+    case DICT3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = DICT2;
+    case DICT2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = DICT1;
+    case DICT1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+      z->adler = z->state->sub.check.need;
+      z->state->mode = DICT0;
+      return Z_NEED_DICT;
+    case DICT0:
+      z->state->mode = BAD;
+      z->msg = (char*)"need dictionary";
+      z->state->sub.marker = 0;       /* can try inflateSync */
+      return Z_STREAM_ERROR;
+    case BLOCKS:
+      r = inflate_blocks(z->state->blocks, z, r);
+      if (r == Z_DATA_ERROR)
+      {
+        z->state->mode = BAD;
+        z->state->sub.marker = 0;       /* can try inflateSync */
+        break;
+      }
+      if (r == Z_OK)
+        r = f;
+      if (r != Z_STREAM_END)
+        return r;
+      r = f;
+      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+      if (z->state->nowrap)
+      {
+        z->state->mode = DONE;
+        break;
+      }
+      z->state->mode = CHECK4;
+    case CHECK4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = CHECK3;
+    case CHECK3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = CHECK2;
+    case CHECK2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = CHECK1;
+    case CHECK1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+
+      if (z->state->sub.check.was != z->state->sub.check.need)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"incorrect data check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Tracev((stderr, "inflate: zlib check ok\n"));
+      z->state->mode = DONE;
+    case DONE:
+      return Z_STREAM_END;
+    case BAD:
+      return Z_DATA_ERROR;
+    default:
+      return Z_STREAM_ERROR;
+  }
+#ifdef NEED_DUMMY_RETURN
+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
+#endif
+}
+
+
+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
+z_streamp z;
+const Bytef *dictionary;
+uInt  dictLength;
+{
+  uInt length = dictLength;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
+    return Z_STREAM_ERROR;
+
+  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
+  z->adler = 1L;
+
+  if (length >= ((uInt)1<<z->state->wbits))
+  {
+    length = (1<<z->state->wbits)-1;
+    dictionary += dictLength - length;
+  }
+  inflate_set_dictionary(z->state->blocks, dictionary, length);
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateSync(z)
+z_streamp z;
+{
+  uInt n;       /* number of bytes to look at */
+  Bytef *p;     /* pointer to bytes */
+  uInt m;       /* number of marker bytes found in a row */
+  uLong r, w;   /* temporaries to save total_in and total_out */
+
+  /* set up */
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->mode != BAD)
+  {
+    z->state->mode = BAD;
+    z->state->sub.marker = 0;
+  }
+  if ((n = z->avail_in) == 0)
+    return Z_BUF_ERROR;
+  p = z->next_in;
+  m = z->state->sub.marker;
+
+  /* search */
+  while (n && m < 4)
+  {
+    static const Byte mark[4] = {0, 0, 0xff, 0xff};
+    if (*p == mark[m])
+      m++;
+    else if (*p)
+      m = 0;
+    else
+      m = 4 - m;
+    p++, n--;
+  }
+
+  /* restore */
+  z->total_in += p - z->next_in;
+  z->next_in = p;
+  z->avail_in = n;
+  z->state->sub.marker = m;
+
+  /* return no joy or set up to restart on a new block */
+  if (m != 4)
+    return Z_DATA_ERROR;
+  r = z->total_in;  w = z->total_out;
+  inflateReset(z);
+  z->total_in = r;  z->total_out = w;
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ * but removes the length bytes of the resulting empty stored block. When
+ * decompressing, PPP checks that at the end of input packet, inflate is
+ * waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
+    return Z_STREAM_ERROR;
+  return inflate_blocks_sync_point(z->state->blocks);
+}
diff --git a/SecurityServer/MacYarrow/zlib/inftrees.c b/SecurityServer/MacYarrow/zlib/inftrees.c
new file mode 100644
index 00000000..b8c9c4ca
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/inftrees.c
@@ -0,0 +1,473 @@
+/*
+ * 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.
+ */
+
+
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#if !defined(BUILDFIXED) && !defined(STDC)
+#  define BUILDFIXED   /* non ANSI compilers may not accept inffixed.h */
+#endif
+
+const char inflate_copyright[] =
+   " inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+struct internal_state  {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+    uIntf *,            /* code lengths in bits */
+    uInt,               /* number of codes */
+    uInt,               /* number of "simple" codes */
+    const uIntf *,      /* list of base values for non-simple codes */
+    const uIntf *,      /* list of extra bits for non-simple codes */
+    inflate_huft * FAR*,/* result: starting table */
+    uIntf *,            /* maximum lookup bits (returns actual) */
+    inflate_huft *,     /* space for trees */
+    uInt *,             /* hufts used in space */
+    uIntf * ));         /* space for values */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+        /* see note #13 above about 258 */
+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+local const uInt cpdext[30] = { /* Extra bits for distance codes */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15         /* maximum bit length of any code */
+
+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
+uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
+uInt n;                 /* number of codes (assumed <= 288) */
+uInt s;                 /* number of simple-valued codes (0..s-1) */
+const uIntf *d;         /* list of base values for non-simple codes */
+const uIntf *e;         /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t;  /* result: starting table */
+uIntf *m;               /* maximum lookup bits, returns actual */
+inflate_huft *hp;       /* space for trees */
+uInt *hn;               /* hufts used in space */
+uIntf *v;               /* working area: values in order of bit length */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
+   if the given code set is incomplete (the tables are still built in this
+   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
+   lengths), or Z_MEM_ERROR if not enough memory. */
+{
+
+  uInt a;                       /* counter for codes of length k */
+  uInt c[BMAX+1];               /* bit length count table */
+  uInt f;                       /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register uInt i;              /* counter, current code */
+  register uInt j;              /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
+  register uIntf *p;            /* pointer into c[], b[], or v[] */
+  inflate_huft *q;              /* points to current table */
+  struct inflate_huft_s r;      /* table entry for structure assignment */
+  inflate_huft *u[BMAX];        /* table stack */
+  register int w;               /* bits before this table == (l * h) */
+  uInt x[BMAX+1];               /* bit offsets, then code stack */
+  uIntf *xp;                    /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  uInt z;                       /* number of entries in current table */
+
+
+  /* Generate counts for each bit length */
+  p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+  C4                            /* clear c[]--assume BMAX+1 is 16 */
+  p = b;  i = n;
+  do {
+    c[*p++]++;                  /* assume all entries <= BMAX */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (inflate_huft *)Z_NULL;
+    *m = 0;
+    return Z_OK;
+  }
+
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                        /* minimum code length */
+  if ((uInt)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((uInt)l > i)
+    l = i;
+  *m = l;
+
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return Z_DATA_ERROR;
+  if ((y -= c[i]) < 0)
+    return Z_DATA_ERROR;
+  c[i] += y;
+
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;  xp = x + 2;
+  while (--i) {                 /* note that i == g from above */
+    *xp++ = (j += *p++);
+  }
+
+
+  /* Make a table of values in order of bit lengths */
+  p = b;  i = 0;
+  do {
+    if ((j = *p++) != 0)
+      v[x[j]++] = i;
+  } while (++i < n);
+  n = x[g];                     /* set n to length of v */
+
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                 /* first Huffman code is zero */
+  p = v;                        /* grab values in bit order */
+  h = -1;                       /* no tables yet--level -1 */
+  w = -l;                       /* bits decoded == (l * h) */
+  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
+  q = (inflate_huft *)Z_NULL;   /* ditto */
+  z = 0;                        /* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+    a = c[k];
+    while (a--)
+    {
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = g - w;
+        z = z > (uInt)l ? l : z;        /* table size upper limit */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          if (j < z)
+            while (++j < z)     /* try smaller tables up to z bits */
+            {
+              if ((f <<= 1) <= *++xp)
+                break;          /* enough codes to use up j bits */
+              f -= *xp;         /* else deduct codes from patterns */
+            }
+        }
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate new table */
+        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
+          return Z_MEM_ERROR;   /* not enough memory */
+        u[h] = q = hp + *hn;
+        *hn += z;
+
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.bits = (Byte)l;     /* bits to dump before this table */
+          r.exop = (Byte)j;     /* bits in this table */
+          j = i >> (w - l);
+          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+        else
+          *t = q;               /* first table is returned result */
+      }
+
+      /* set up table entry in r */
+      r.bits = (Byte)(k - w);
+      if (p >= v + n)
+        r.exop = 128 + 64;      /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
+        r.base = *p++;          /* simple code is just the value */
+      }
+      else
+      {
+        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
+        r.base = d[*p++ - s];
+      }
+
+      /* fill code-like entries with r */
+      f = 1 << (k - w);
+      for (j = i >> w; j < z; j += f)
+        q[j] = r;
+
+      /* backwards increment the k-bit code i */
+      for (j = 1 << (k - 1); i & j; j >>= 1)
+        i ^= j;
+      i ^= j;
+
+      /* backup over finished tables */
+      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
+      while ((i & mask) != x[h])
+      {
+        h--;                    /* don't need to update q */
+        w -= l;
+        mask = (1 << w) - 1;
+      }
+    }
+  }
+
+
+  /* Return Z_BUF_ERROR if we were given an incomplete table */
+  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+int inflate_trees_bits(c, bb, tb, hp, z)
+uIntf *c;               /* 19 code lengths */
+uIntf *bb;              /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+inflate_huft *hp;       /* space for trees */
+z_streamp z;            /* for messages */
+{
+  int r;
+  uInt hn = 0;          /* hufts used in space */
+  uIntf *v;             /* work area for huft_build */
+
+  if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
+    return Z_MEM_ERROR;
+  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
+                 tb, bb, hp, &hn, v);
+  if (r == Z_DATA_ERROR)
+    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
+  else if (r == Z_BUF_ERROR || *bb == 0)
+  {
+    z->msg = (char*)"incomplete dynamic bit lengths tree";
+    r = Z_DATA_ERROR;
+  }
+  ZFREE(z, v);
+  return r;
+}
+
+
+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
+uInt nl;                /* number of literal/length codes */
+uInt nd;                /* number of distance codes */
+uIntf *c;               /* that many (total) code lengths */
+uIntf *bl;              /* literal desired/actual bit depth */
+uIntf *bd;              /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+inflate_huft *hp;       /* space for trees */
+z_streamp z;            /* for messages */
+{
+  int r;
+  uInt hn = 0;          /* hufts used in space */
+  uIntf *v;             /* work area for huft_build */
+
+  /* allocate work area */
+  if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+    return Z_MEM_ERROR;
+
+  /* build literal/length tree */
+  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
+  if (r != Z_OK || *bl == 0)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed literal/length tree";
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    ZFREE(z, v);
+    return r;
+  }
+
+  /* build distance tree */
+  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
+  if (r != Z_OK || (*bd == 0 && nl > 257))
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed distance tree";
+    else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+      r = Z_OK;
+    }
+#else
+      z->msg = (char*)"incomplete distance tree";
+      r = Z_DATA_ERROR;
+    }
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"empty distance tree with lengths";
+      r = Z_DATA_ERROR;
+    }
+    ZFREE(z, v);
+    return r;
+#endif
+  }
+
+  /* done */
+  ZFREE(z, v);
+  return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+#ifdef BUILDFIXED
+local int fixed_built = 0;
+#define FIXEDH 544      /* number of hufts used by fixed tables */
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+#else
+#include "inffixed.h"
+#endif
+
+
+int inflate_trees_fixed(bl, bd, tl, td, z)
+uIntf *bl;               /* literal desired/actual bit depth */
+uIntf *bd;               /* distance desired/actual bit depth */
+inflate_huft * FAR *tl;  /* literal/length tree result */
+inflate_huft * FAR *td;  /* distance tree result */
+z_streamp z;             /* for memory allocation */
+{
+#ifdef BUILDFIXED
+  /* build fixed tables if not already */
+  if (!fixed_built)
+  {
+    int k;              /* temporary variable */
+    uInt f = 0;         /* number of hufts used in fixed_mem */
+    uIntf *c;           /* length list for huft_build */
+    uIntf *v;           /* work area for huft_build */
+
+    /* allocate memory */
+    if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+      return Z_MEM_ERROR;
+    if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+    {
+      ZFREE(z, c);
+      return Z_MEM_ERROR;
+    }
+
+    /* literal table */
+    for (k = 0; k < 144; k++)
+      c[k] = 8;
+    for (; k < 256; k++)
+      c[k] = 9;
+    for (; k < 280; k++)
+      c[k] = 7;
+    for (; k < 288; k++)
+      c[k] = 8;
+    fixed_bl = 9;
+    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
+               fixed_mem, &f, v);
+
+    /* distance table */
+    for (k = 0; k < 30; k++)
+      c[k] = 5;
+    fixed_bd = 5;
+    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
+               fixed_mem, &f, v);
+
+    /* done */
+    ZFREE(z, v);
+    ZFREE(z, c);
+    fixed_built = 1;
+  }
+#endif
+  *bl = fixed_bl;
+  *bd = fixed_bd;
+  *tl = fixed_tl;
+  *td = fixed_td;
+  return Z_OK;
+}
diff --git a/SecurityServer/MacYarrow/zlib/inftrees.h b/SecurityServer/MacYarrow/zlib/inftrees.h
new file mode 100644
index 00000000..f3d7465b
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/inftrees.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+  union {
+    struct {
+      Byte Exop;        /* number of extra bits or operation */
+      Byte Bits;        /* number of bits in this code or subcode */
+    } what;
+    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
+  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
+  uInt base;            /* literal, length base, distance base,
+                           or table offset */
+};
+
+/* Maximum size of dynamic tree.  The maximum found in a long but non-
+   exhaustive search was 1004 huft structures (850 for length/literals
+   and 154 for distances, the latter actually the result of an
+   exhaustive search).  The actual maximum is not known, but the
+   value below is more than safe. */
+#define MANY 1440
+
+extern int inflate_trees_bits OF((
+    uIntf *,                    /* 19 code lengths */
+    uIntf *,                    /* bits tree desired/actual depth */
+    inflate_huft * FAR *,       /* bits tree result */
+    inflate_huft *,             /* space for trees */
+    z_streamp));                /* for messages */
+
+extern int inflate_trees_dynamic OF((
+    uInt,                       /* number of literal/length codes */
+    uInt,                       /* number of distance codes */
+    uIntf *,                    /* that many (total) code lengths */
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    inflate_huft *,             /* space for trees */
+    z_streamp));                /* for messages */
+
+extern int inflate_trees_fixed OF((
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    z_streamp));                /* for memory allocation */
diff --git a/SecurityServer/MacYarrow/zlib/infutil.c b/SecurityServer/MacYarrow/zlib/infutil.c
new file mode 100644
index 00000000..248916aa
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/infutil.c
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* And'ing with mask[n] masks the lower n bits */
+uInt inflate_mask[17] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+
+/* copy as much as possible from the sliding window to the output area */
+int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt n;
+  Bytef *p;
+  Bytef *q;
+
+  /* local copies of source and destination pointers */
+  p = z->next_out;
+  q = s->read;
+
+  /* compute number of bytes to copy as far as end of window */
+  n = (uInt)((q <= s->write ? s->write : s->end) - q);
+  if (n > z->avail_out) n = z->avail_out;
+  if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+  /* update counters */
+  z->avail_out -= n;
+  z->total_out += n;
+
+  /* update check information */
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+  /* copy as far as end of window */
+  zmemcpy(p, q, n);
+  p += n;
+  q += n;
+
+  /* see if more to copy at beginning of window */
+  if (q == s->end)
+  {
+    /* wrap pointers */
+    q = s->window;
+    if (s->write == s->end)
+      s->write = s->window;
+
+    /* compute bytes to copy */
+    n = (uInt)(s->write - q);
+    if (n > z->avail_out) n = z->avail_out;
+    if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+    /* update counters */
+    z->avail_out -= n;
+    z->total_out += n;
+
+    /* update check information */
+    if (s->checkfn != Z_NULL)
+      z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+    /* copy */
+    zmemcpy(p, q, n);
+    p += n;
+    q += n;
+  }
+
+  /* update pointers */
+  z->next_out = p;
+  s->read = q;
+
+  /* done */
+  return r;
+}
diff --git a/SecurityServer/MacYarrow/zlib/infutil.h b/SecurityServer/MacYarrow/zlib/infutil.h
new file mode 100644
index 00000000..89e95252
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/infutil.h
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFUTIL_H
+#define _INFUTIL_H
+
+typedef enum {
+      TYPE,     /* get type bits (3, including end bit) */
+      LENS,     /* get lengths for stored */
+      STORED,   /* processing stored block */
+      TABLE,    /* get table lengths */
+      BTREE,    /* get bit lengths tree for a dynamic block */
+      DTREE,    /* get length, distance trees for a dynamic block */
+      CODES,    /* processing fixed or dynamic block */
+      DRY,      /* output remaining window bytes */
+      DONE,     /* finished last block, done */
+      BAD}      /* got a data error--stuck here */
+inflate_block_mode;
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+  /* mode */
+  inflate_block_mode  mode;     /* current inflate_block mode */
+
+  /* mode dependent information */
+  union {
+    uInt left;          /* if STORED, bytes left to copy */
+    struct {
+      uInt table;               /* table lengths (14 bits) */
+      uInt index;               /* index into blens (or border) */
+      uIntf *blens;             /* bit lengths of codes */
+      uInt bb;                  /* bit length tree depth */
+      inflate_huft *tb;         /* bit length decoding tree */
+    } trees;            /* if DTREE, decoding info for trees */
+    struct {
+      inflate_codes_statef 
+         *codes;
+    } decode;           /* if CODES, current state */
+  } sub;                /* submode */
+  uInt last;            /* true if this block is the last block */
+
+  /* mode independent information */
+  uInt bitk;            /* bits in bit buffer */
+  uLong bitb;           /* bit buffer */
+  inflate_huft *hufts;  /* single malloc for tree space */
+  Bytef *window;        /* sliding window */
+  Bytef *end;           /* one byte after sliding window */
+  Bytef *read;          /* window read pointer */
+  Bytef *write;         /* window write pointer */
+  check_func checkfn;   /* check function */
+  uLong check;          /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/*   update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/*   get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/*   output bytes */
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/*   load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
+extern uInt inflate_mask[17];
+
+/* copy as much as possible from the sliding window to the output area */
+extern int inflate_flush OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+struct internal_state      {int dummy;}; /* for buggy compilers */
+
+#endif
diff --git a/SecurityServer/MacYarrow/zlib/trees.c b/SecurityServer/MacYarrow/zlib/trees.c
new file mode 100644
index 00000000..2878e93e
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/trees.c
@@ -0,0 +1,1232 @@
+/*
+ * 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.
+ */
+
+
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-1998 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id: trees.c,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local void set_data_type  OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (value << s->bi_valid);
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (val << s->bi_valid);\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+	    "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+	fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+		static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+	fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+		static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+	fprintf(header, "%2u%s", _dist_code[i],
+		SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+	fprintf(header, "%2u%s", _length_code[i],
+		SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+	fprintf(header, "%1u%s", base_length[i],
+		SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+	fprintf(header, "%5u%s", base_dist[i],
+		SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if (tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
+#ifdef DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+        s->compressed_len += 10L;
+#endif
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+	 /* Check if the file is ascii or binary */
+	if (s->data_type == Z_UNKNOWN) set_data_type(s);
+
+	/* Construct the literal and distance trees */
+	build_tree(s, (tree_desc *)(&(s->l_desc)));
+	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+
+	build_tree(s, (tree_desc *)(&(s->d_desc)));
+	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+	/* At this point, opt_len and static_len are the total bit lengths of
+	 * the compressed block data, excluding the tree representations.
+	 */
+
+	/* Build the bit length tree for the above two trees, and get the index
+	 * in bl_order of the last bit length code to send.
+	 */
+	max_blindex = build_bl_tree(s);
+
+	/* Determine the best encoding. Compute first the block length in bytes*/
+	opt_lenb = (s->opt_len+3+7)>>3;
+	static_lenb = (s->static_len+3+7)>>3;
+
+	Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+		opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+		s->last_lit));
+
+	if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+eof, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+eof, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (eof) {
+        bi_windup(s);
+#ifdef DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+    deflate_state *s;
+{
+    int n = 0;
+    unsigned ascii_freq = 0;
+    unsigned bin_freq = 0;
+    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
+    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
+    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);   
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
diff --git a/SecurityServer/MacYarrow/zlib/trees.h b/SecurityServer/MacYarrow/zlib/trees.h
new file mode 100644
index 00000000..4b87f54b
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/trees.h
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
diff --git a/SecurityServer/MacYarrow/zlib/uncompr.c b/SecurityServer/MacYarrow/zlib/uncompr.c
new file mode 100644
index 00000000..5ef67042
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/uncompr.c
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: uncompr.c,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
diff --git a/SecurityServer/MacYarrow/zlib/zconf.h b/SecurityServer/MacYarrow/zlib/zconf.h
new file mode 100644
index 00000000..2f2ceba0
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/zconf.h
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ */
+
+
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: zconf.h,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_	z_deflateInit_
+#  define deflate	z_deflate
+#  define deflateEnd	z_deflateEnd
+#  define inflateInit_ 	z_inflateInit_
+#  define inflate	z_inflate
+#  define inflateEnd	z_inflateEnd
+#  define deflateInit2_	z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy	z_deflateCopy
+#  define deflateReset	z_deflateReset
+#  define deflateParams	z_deflateParams
+#  define inflateInit2_	z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync	z_inflateSync
+#  define inflateSyncPoint z_inflateSyncPoint
+#  define inflateReset	z_inflateReset
+#  define compress	z_compress
+#  define compress2	z_compress2
+#  define uncompress	z_uncompress
+#  define adler32	z_adler32
+#  define crc32		z_crc32
+#  define get_crc_table z_get_crc_table
+
+#  define Byte		z_Byte
+#  define uInt		z_uInt
+#  define uLong		z_uLong
+#  define Bytef	        z_Bytef
+#  define charf		z_charf
+#  define intf		z_intf
+#  define uIntf		z_uIntf
+#  define uLongf	z_uLongf
+#  define voidpf	z_voidpf
+#  define voidp		z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+#  ifndef __32BIT__
+#    define __32BIT__
+#  endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
+#  define STDC
+#endif
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+#  ifndef STDC
+#    define STDC
+#  endif
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Old Borland C incorrectly complains about missing returns: */
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+#  define NEED_DUMMY_RETURN
+#endif
+
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+   /* MSC small or medium model */
+#  define SMALL_MEDIUM
+#  ifdef _MSC_VER
+#    define FAR _far
+#  else
+#    define FAR far
+#  endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+#  ifndef __32BIT__
+#    define SMALL_MEDIUM
+#    define FAR _far
+#  endif
+#endif
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if defined(ZLIB_DLL)
+#  if defined(_WINDOWS) || defined(WINDOWS)
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+#    define ZEXPORT  WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA  WINAPIV
+#    else
+#      define ZEXPORTVA  FAR _cdecl _export
+#    endif
+#  endif
+#  if defined (__BORLANDC__)
+#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)
+#      include <windows.h>
+#      define ZEXPORT __declspec(dllexport) WINAPI
+#      define ZEXPORTRVA __declspec(dllexport) WINAPIV
+#    else
+#      if defined (_Windows) && defined (__DLL__)
+#        define ZEXPORT _export
+#        define ZEXPORTVA _export
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  if defined (ZLIB_DLL)
+#    define ZEXTERN extern __declspec(dllexport)
+#  else
+#    define ZEXTERN extern __declspec(dllimport)
+#  endif
+#endif
+
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+
+#ifndef FAR
+#   define FAR
+#endif
+
+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void FAR *voidpf;
+   typedef void     *voidp;
+#else
+   typedef Byte FAR *voidpf;
+   typedef Byte     *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  define z_off_t  off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define  z_off_t long
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(inflate_blocks,"INBL")
+#   pragma map(inflate_blocks_new,"INBLNE")
+#   pragma map(inflate_blocks_free,"INBLFR")
+#   pragma map(inflate_blocks_reset,"INBLRE")
+#   pragma map(inflate_codes_free,"INCOFR")
+#   pragma map(inflate_codes,"INCO")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_flush,"INFLU")
+#   pragma map(inflate_mask,"INMA")
+#   pragma map(inflate_set_dictionary,"INSEDI2")
+#   pragma map(inflate_copyright,"INCOPY")
+#   pragma map(inflate_trees_bits,"INTRBI")
+#   pragma map(inflate_trees_dynamic,"INTRDY")
+#   pragma map(inflate_trees_fixed,"INTRFI")
+#   pragma map(inflate_trees_free,"INTRFR")
+#endif
+
+#endif /* _ZCONF_H */
diff --git a/SecurityServer/MacYarrow/zlib/zlib.h b/SecurityServer/MacYarrow/zlib/zlib.h
new file mode 100644
index 00000000..ea7597b0
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/zlib.h
@@ -0,0 +1,911 @@
+/*
+ * 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.
+ */
+
+
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.1.3, July 9th, 1998
+
+  Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.1.3"
+
+/* 
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms will be added later and will have the same
+  stream interface.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio.
+
+     The library does not install any signal handler. The decoder checks
+  the consistency of the compressed data, so the library should never
+  crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: ascii or binary */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+/* 
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce some
+  output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows. deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far. (In particular
+  avail_in is zero after the call if enough output space has been provided
+  before the call.)  Flushing may degrade compression for some compression
+  algorithms and so it should be used only when necessary.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+  the compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+  
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update data_type if it can make a good guess about
+  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero).
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/* 
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+   value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller.  msg is set to null if there is no error
+   message. inflateInit does not perform any decompression apart from reading
+   the zlib header if present: this will be done by inflate().  (So next_in and
+   avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may some
+  introduce some output latency (reading input without producing any output)
+  except when forced to flush.
+
+  The detailed semantics are as follows. inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
+  output as possible to the output buffer. The flushing behavior of inflate is
+  not specified for values of the flush parameter other than Z_SYNC_FLUSH
+  and Z_FINISH, but the current implementation actually flushes as much output
+  as possible anyway.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster routine
+  may be used for the single inflate() call.
+
+     If a preset dictionary is needed at this point (see inflateSetDictionary
+  below), inflate sets strm-adler to the adler32 checksum of the
+  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
+  it sets strm->adler to the adler32 checksum of all output produced
+  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
+  an error code as described below. At the end of the stream, inflate()
+  checks that its computed adler32 checksum is equal to that saved by the
+  compressor and returns Z_STREAM_END only if the checksum is correct.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect
+  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
+  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
+  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
+  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
+  case, the application may then call inflateSync to look for a good
+  compression block.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*   
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library. Larger values of this parameter result in better
+   compression at the expense of memory usage. The default value is 15 if
+   deflateInit is used instead.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match).  Filtered data consists mostly of small values with a
+   somewhat random distribution. In this case, the compression algorithm is
+   tuned to compress them better. The effect of Z_FILTERED is to force more
+   Huffman coding and less string matching; it is somewhat intermediate
+   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+   the compression ratio but not the correctness of the compressed output even
+   if it is not set appropriately.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+   method). msg is set to null if there is no error message.  deflateInit2 does
+   not perform any compression: this will be done by deflate().
+*/
+                            
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output. This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any
+   call of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size in
+   deflate or deflate2. Thus the strings most likely to be useful should be
+   put at the end of the dictionary, not at the front.
+
+     Upon return of this function, strm->adler is set to the Adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The Adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.)
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort). deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+				      int level,
+				      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different
+   strategy. If the compression level is changed, the input available so far
+   is compressed with the old level (and may be flushed); the new level will
+   take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+/*   
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter. The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library. The default value is 15 if inflateInit is used
+   instead. If a compressed stream with a larger window size is given as
+   input, inflate() will return with the error code Z_DATA_ERROR instead of
+   trying to allocate a larger window.
+
+      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+   memLevel). msg is set to null if there is no error message.  inflateInit2
+   does not perform any decompression apart from reading the zlib header if
+   present: this will be done by inflate(). (So next_in and avail_in may be
+   modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence. This function must be called immediately after a call of inflate
+   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the Adler32 value returned by this call of
+   inflate. The compressor and decompressor must use exactly the same
+   dictionary (see deflateSetDictionary).
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect Adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/* 
+    Skips invalid compressed data until a full flush point (see above the
+  description of deflate with Z_FULL_FLUSH) can be found, or until all
+  available input is skipped. No output is provided.
+
+    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level and memory usage,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least 0.1% larger than
+   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb") but can also include a compression level
+   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+   Huffman only compression as in "wb1h". (See the description
+   of deflateInit2 for more information about the strategy parameter.)
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).  */
+
+ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, pipe or
+   fileno (in the file has been previously opened with fopen).
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy. See the description
+   of deflateInit2 for the meaning of these parameters.
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT    gzwrite OF((gzFile file, 
+				   const voidp buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+      Reads bytes from the compressed file until len-1 characters are read, or
+   a newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  The string is then terminated with a null
+   character.
+      gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
+/*
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
+/*
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
+				      z_off_t offset, int whence));
+/* 
+      Sets the starting position for the next gzread or gzwrite on the
+   given compressed file. The offset represents a number of bytes in the
+   uncompressed data stream. The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow. If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+/*
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+
+   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running crc with the bytes buf[0..len-1] and return the updated
+   crc. If buf is NULL, this function returns the required initial value
+   for the crc. Pre- and post-conditioning (one's complement) is performed
+   within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char   * ZEXPORT zError           OF((int err));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
diff --git a/SecurityServer/MacYarrow/zlib/zlib.mcp b/SecurityServer/MacYarrow/zlib/zlib.mcp
new file mode 100644
index 0000000000000000000000000000000000000000..07bd98085e99edf5a0f7c66cb151a74cfea845f8
GIT binary patch
literal 38665
zcmeHQYiu0V6~4Q+<2>xxH~~Tm$tI8oNpRj_ZIa-`PC~%OTgQ+{ZG_kBjk9FeyX>xM
z2(225T2Y>rTA{Wolu9)1k3Q5Ap-Qwgv{H*`D<Sw((IT}pQnBc}7446L`+fJ`nVo&i
zV;$FV*g46abLQMTXU;wM+{ez`IgX{%Ng+g?5P`KqJpPgpPfQ5W7y_?15DWk*=uVHs
z4@a}vL^>OaWYc%YV|gR1Ch)0bVz{$=JeN<WLbt{5`&c?Vk`t1-Cl-t6a-m2xe_V40
zquJ4TK6EIa&nL!4HFJL=84vYEGnoQw?|33P654k%pN;B5J@Mi3(b0G|q(rD2n9PCk
zv3w#GSKJ-p+d^!V1M#r}qbHGz=5q1Wa5A1Pa1SKY!_j1@KZC0ir>r@>iLn#bbE9Qd
zZ8vtWUypmFGEiNM>y|t?!dRgi-TV8XjJjQ4G}eD8)E9>VV3DzSQn4e^Tnri%%hJqZ
zVUb98aka=OuNJwLtHm5^wRj%cw_oeQ6YagSj>z4UOIcMNh@UFxsmq3B<Mk$Tc_rph
zdORD8hX%9pxN5ji3|7k04bo%D`#Rn7EBR50h%&D#$*<&NB}K|TuB1Sj|CQudbUeE<
z7LP3{QtGJ{vdbE{LYa!qU7?(%@hjw7TfZb*`F4?yRxDBEu%#smeW4_$a?dC!L}#^j
z>I&IzrlJThreZmJQ!&@*H5HU_up+K3?olO|7xk~2m^%DQesC;cEQl^gm4dojYk;wS
zlCTrUdQJBOH)uKvJV(>_0yk><QQ*0nehPS=rk?|zujyX_FVOUxz)hO|3vjcd1Jq@q
zrmp~Q(ez5-R!w&RU#98Xf!j14174(QF6tI*`e9(!6A*Y72g(Hm&f;*TBt-!0MX^NF
zuK{1B>GQx#HT^E|hZG%TU9Z+O^RLl#C-5>&9|c~n=}!QMH2n<l3QhCAtQ#QsdmOHn
zq^P64uhTTvvtpH|4*;*$^a)_L8KCa-IItX`?t3^~FG*4ND)2f@{{wivqU&j!4VrET
zzCqK6fO!t6&*HFAlA``e;7yu-5qPtve+#@t)BgtEs^|vVc$=no0B=|HEI7ilpPZx~
zWk<AWz*I1xNFpR2%`A92IP$+_Hy7nuig_X%<elU#P#$-gr&gW)<9Sclmle7huqP7f
zrHZ1yr}w~-*onjlXS&0OBHbt+#9g%SmR(E+{h7W;pQEqQ$LL%1>lH}!E&3FFiGEN2
zrQe2-=u`A1`Vf7GK0{xjkI*;h6TCP31;-B9T#gkSBRDodWjXF}Y~Yx%5Q)Gshkc?B
ziDLrC0*(P~NQ;o@&+Oy$JN9YzW%gnASB@#w0Cl0BypFP2f8Lw24Y{-rZNmGrZoDV$
zMIBfNtBtHSq5iBVb+1Qay;xV;g7u~CsWZn<){(ZNjcI$@EQGWIiFTpgX+PSYHl_^>
zo6|-F+FXwp^4!aTeYFeK|B+IWeYftt8#gtK%-=NmKFoUb&65oyD5J|Y+^L6to?oM9
zie=IYN@r<*8bw>x$@^rnf&TtM7B`@I|H0mUkg`zYR*hRUZX?E(4I0nUxKZP|8qd>s
zzQzlPA@?$U-prO#?GU0ONX@c!RPU_oQhg`DLEZ=70`!qd08kMBe82ErLR!G^i!Kf!
zm`&7AX3Gy%-%h>-YRCe7LRmxAEw3up51pOzDJ53*nen{8fGD?7EpdXP{`T}(+_B1m
zzP?D-v4n@rE|gKT4<BCZ$E2m#EtkI*OSx5^525^?OeR_7Wo5-Fr?0PfZ&^kOqc<@e
zI+)6&v-uET+Ej$TNbmlN85X7|IfuJ@ESF4)9Ku!odv6W7UECKr>{_o#Z~B7AQ|dEt
zXrS9oAGdtU8QgbduzmQrW6{0QWHOx|3*8b=X6y<|IWfCj#qT>DQtvlxTV3lDTfg2(
zl6N`I3VD}fTWzUk6>=N}d6pAD=_tp^c1E6TFXv_#Zu+!Bn3Ut94dm$eto9AB<lr5&
z19+DcbF7(Ly-u6;iXC_IMDKDk;||rLogM9C>f<t};I)?1ZDgLbb1pvWTF|AyNIK?N
zCzs1*_7INQT-LdhdJsf8x#LOKaTPBUUB~BKetcTwQ0;aYiFm3I(HFL-oh5jgcPODf
zlewVDXGp8jeu0ffIhI$^T51VuoNX(cSvliQ!-#N!jVYUL2uCkHu%wMEp1MA9SvK1|
zqslce9wt?+xTtc?YcFS-*1WUQ<6TBnb56FkPL*p+S2@lKdDq8z5mkj8M?s$D%=8-5
z#?GziD%GtqZ3LNeysk0b<ak_T+K4%A>f>>Z=_<$T8ndz>Q=e&=QPdg}6?6b-fh}4N
z1(0>5yWjO00Lz%Gy2@1(m-t%MrdF77t6Qtu%3&+a)LPX`dr5s}(OOk-p9fzI)i_`y
zg|-8?RQTXqpkRSuf%GZg0=@-m+yV_85I9>{=FI?iHOi?p!2NR?Sdd$AyaMN*kh(~;
z0WU;qL25<142isErzAI5su_JbHseVJsTp=V-w`?3j&Ep=B~Dh>MpcHD!VL<59e)kc
z_ViSDeNvFQ^HT&)A30YLJynYG%xmumd@e9Ac)xiriNNXN^9w$+w5gJ%taZV1Yg)iv
zcjfZYZ2n@}ARroL&$V{tsp)g^E5kjvK2)-R8U}R^PdLKWA+cL?%;k3HO547<1$z1b
zcPiW5uQ`RAw1M2Bhu}qe*YaZhP0Ho^o0Thc{*^j^t3F?%&#%(ott{2&<-4EN@D<YE
z$*hq3wYhVf#^BCvH3eKpjG~-D_^omsQaw@w(j25lBz$uq<{`~TT7cAq#2w=VkWv!O
zOmokisnHjBa|LPwv@oRBoF!RC>RTvmT;v^>d?`Vplx-0}x(&6jo69X{?e^QwII|Hf
z*Uk(Xu-r8$BG6v_o0+@M+Pf@X)7{^*Z%t@T&z`|OK#_ypgZ%8GR)DUIx~|fJ3UrS#
zYj65E2#y%5J(S}(u*O3<ju~q`l;fCky@zrf;@5d7$7x`_hjN^4H+U$=FJ^A=P>x^s
zw0kJWuXHwgD95R5lZSE~t2euqLm3}@3)Gwi<PP!uiENJ1Mn+TdvApP1KZZ;8XO?VJ
zDcV(NzLw+;F`QWTLvdGA$<CeP4cX>;!E!&o>o8^N6D^ZxNPPQL_A<h9A9<0CBm&CV
zep?zeqbNc~X*i7H*cU~CF3hMFI$}jh*oTq`Ct7hcDug~aV?a<rBVq&TqVNo4l*MAO
zREZ>`EJ&=wl7KG6PbdnOV8j?{kBO1^v1BwK2X$&ZpGX2nM-ZcB>lRS4Y)s<B*s<Yc
zI(7mqkTHac$tm(!G?!PDmVxX%LzyV17HDwB$K-vHR}|I6w4yaAO>w9PQSK@<Bg3RP
zEHP`Y4_{D)v9S3+fA?JJVPZjL_4})E?o+-6d<*y%sBH@vzdQNcPd%wp5fS*?lE7#M
z#uIx+JWx-ygb0J???A#nB>vVT3?La#PlrJBHydFDiNDJT+`Z4=UWA8{j7NiC0&P6+
zIs@8>3~?5;5$)gw(A?}r_$3mfED(N!#OHm4KOr%y1L40&jG6!lP?yUkDFTcf!DtVF
z03SmbQDU}%W&{X8pa%ydO3We9v;`nAi~}P$00P_xr6X+wJ_VYQ8~}mGabQFTK;Wx5
zESIE;NE6cZkAYWc`sctaHT^p9wVM7N@O7I0Gw>=+{|9)rqJwNV)&UTtjn_(21X*vk
z86Zd<*GW<YSyq2J6WjuNgXZr9zCqLbf!j6xVPHm`00cjR!zM|JU<{a1DFDF~4wMB5
z^7DeNk`%#5fN4`e@M#<vL1MN5eVo20@!9ihUxTaD2aABl^`Yi1KsS(&qfJZH%jbCu
z&c5~F(B$OTbU!n5eWG?Ouno>(%%hwwNpC;<)}wDsPQJr=z=s;N0DOY$7uV<gD95#p
z>+^n;<GRQ7c|Xc=P2~E#8s*wh&h@<j%5hER`dr&DR~Q0duc8y2``}xkwk&`F!S4jM
z)#QF{eGB*&u(1H2G^o8ybzOKELb}tYsL!q~3vizFqfFLTn|rCP;TK&TIq+oHHRgdA
zp?(?P0+*--xP_-=<HjXglPRjrHG>~za*D?L0AA)tnY3-xA>>pUamP07T$K@b?Bz^T
z#2r7%q#tF{&hgFdthQcgL^jG~>|~JdS<XyH0J5nUUyf840mw#>DaUIBAU8Q4BLLZm
zIc@6WF#?dQ9Ip|8Dho38$wDy)@S{vR7zbIFJ>-=QjWSh6?y;3aO=c=`Ps#Ru-nt_A
zQ6?*z#RGE)WoBi}y=fQ`{3w$i9Kf~+J)_DsFTUZZEUwBmuf3dUTJz3IkLM0Z2Qb%A
zw$?G$Vovd+Eo(7XInD}s*T->bSXdjn>f>>Z=_Y5U*O)f?RKLcw5d@!6YgMmnOgA|m
z*O)e9PMi98Tw}V*@w&#WEXdSn8fFwf$|M@s28O`*5|7!kR;}D%l;cO4w6U@fv@>Bk
zBBJ|ICY3F*y~qdO0=@-&3rGv#!!)(K#{5LhH;iuqWdVHn=LcRiKjSpL!rz{2nqtbt
z#gA3UVbAzN7uE2CFiyEGFOdro{H~QdVH_fq$jEmWKlmNDxq4lv`=Rno_p9|#d05He
z6ZW|xmCKhr0GbDW9r;PqSdwVIg{wdC$BOy;UgY<fN>1I|g}naT3v#Udg%&whei!64
zh*Vzw@l(sRc@sZxKMj5k*urmyo+6aW=cuQJ-wOGn73CAf{GC6+`L<L($v@#{Dc?jn
zOBrf9FtH_4$ZI`<dUZ+u+YjCkzV2m<zlf*|ixq$D58&4!0hWFX5fT2S_~S2up(l*?
zXK=elC4bK(_&U79#&1C6)r!C5Jos~v0Goe`OIwwkGb_Pplx)$o7g*nS@IKIUHUCcF
z`AW_$l!28Pp=pQ*CFhOjK{IRtpo#WcsQB@-pcjxU#Ex^&bB^NQ!;k|_<N`6&z;4BV
z{wdJ>R1whh101xRJ81)ciV3*!XOQ!TEI-jnK0mz#G=VRM6@TSFLGwv3U<Yj*R`SnN
zH-1_P*zp_=&5HlZmqE9Yi?4oP$3ffS+;>1PA{YEW;-KvCc9dZ!7@7gF{qHy^J52Oa
zA03{e;~CJeDETix0a}Nu=)4>HFH!slJ`TPPTd|w=`=;W5l%XM(AOW_&hl31N9++6c
zFcdnR#qRH;eYO41TnqkEBtQ%Ob1nJ{{L||H1L!Zo4XI47gg*%T*TZi|VH<1tmP|no
z<r=V?emXaWKNM?l6yDhm{DoAs^p6X-uw70^dUN@}!~$NU!*1NV8?Gw-P^?=1D)<a<
z0ce5$i-oB)^|wOH8JrpYQTG+*A3+<L{o2Cc`7Sbzer@6JSP#C@f35tRz+bHUuZ4e<
z@|B+9^9-$_!-MRkU(0?i!tYSmWk`Twj#si@i}1_e21ADpIrhHMuSLggY^x9wAO*iu
z{aSSFWnWw&+2VmYM!y!}(T(7(RQyk&f2jT|!oU6scx-#XXP}qr?;`x^r@_!6M|Rx{
zTKcmHpZf)99e!j-8npCh=(!X0Y9zp}hjEa8CBoFf2urf-Nzk%CijDz}F&x(b4|N#*
zT7;7?gK@oNi(StG%YH37ws(PEr}=LID>>nN*vHu(fY07+^lK5mdl-xjk}VFxo~mDq
z@DKkAnr#5MHH3q%*Fz70rvCwU{S60Qub~$}({_MI*l$$5IyO&$-b60=w1@1cB7C$L
zG{+{uBe<99ry~4yjtyHRTRg@#lKoVKCwf3{)%@=Q%YF)fU|-iEQyzQM=%*r_%7ZV%
Gr~D5!6;vAl

literal 0
HcmV?d00001

diff --git a/SecurityServer/MacYarrow/zlib/zutil.c b/SecurityServer/MacYarrow/zlib/zutil.c
new file mode 100644
index 00000000..a887ecf9
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/zutil.c
@@ -0,0 +1,243 @@
+/*
+ * 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.
+ */
+
+
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: zutil.c,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#include "zutil.h"
+
+struct internal_state      {int dummy;}; /* for buggy compilers */
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char *z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int z_verbose = verbose;
+
+void z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#ifdef __TURBOC__
+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
+/* Small and medium model in Turbo C are for now limited to near allocation
+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
+ */
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+#endif
+#endif /* __TURBOC__ */
+
+
+#if defined(M_I86) && !defined(__32BIT__)
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* MSC */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return (voidpf)calloc(items, size);
+}
+
+void  zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/SecurityServer/MacYarrow/zlib/zutil.h b/SecurityServer/MacYarrow/zlib/zutil.h
new file mode 100644
index 00000000..c6bb31fd
--- /dev/null
+++ b/SecurityServer/MacYarrow/zlib/zutil.h
@@ -0,0 +1,238 @@
+/*
+ * 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.
+ */
+
+
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: zutil.h,v 1.1.1.1 2001/05/18 23:14:03 mb Exp $ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#ifdef MSDOS
+#  define OS_CODE  0x00
+#  if defined(__TURBOC__) || defined(__BORLANDC__)
+#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+       /* Allow compilation with ANSI keywords only enabled */
+       void _Cdecl farfree( void *block );
+       void *_Cdecl farmalloc( unsigned long nbytes );
+#    else
+#     include <alloc.h>
+#    endif
+#  else /* MSC or DJGPP */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#endif
+
+#ifdef WIN32 /* Window 95 & Windows NT */
+#  define OS_CODE  0x0b
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#    include <unix.h> /* for fdopen */
+#  else
+#    ifndef fdopen
+#      define fdopen(fd,mode) NULL /* No fdopen() */
+#    endif
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0F
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+#  define fdopen(fd,type)  _fdopen(fd,type)
+#endif
+
+
+        /* Common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#ifdef HAVE_STRERROR
+   extern char *strerror OF((int));
+#  define zstrerror(errnum) strerror(errnum)
+#else
+#  define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
+   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
+   extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int z_verbose;
+   extern void z_error    OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
+				       uInt len));
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void   zcfree  OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* _Z_UTIL_H */
diff --git a/SecurityServer/Makefile b/SecurityServer/Makefile
new file mode 100644
index 00000000..18e9b8ba
--- /dev/null
+++ b/SecurityServer/Makefile
@@ -0,0 +1,35 @@
+#
+#	Makefile to build MIG-generated sources and headers
+#
+SRC = $(SYMROOT)/derived_src
+HDR = $(SYMROOT)/include
+
+build:	$(SRC)/.mig.ucsp $(SRC)/.mig.secagent
+
+debug: build
+
+profile: build
+
+install: build
+
+installhdrs: build
+
+installsrc:
+
+clean:
+	rm -f $(SRC)/.mig.ucsp $(SRC)/.mig.secagent \
+		$(SRC)/ucsp*.cpp $(SRC)/secagent*.cpp $(HDR)/ucsp.h $(HDR)/secagent.h
+
+$(SRC)/.mig.ucsp: SecurityServer/ucsp.defs SecurityServer/ucsp_types.h
+	mkdir -p $(SRC)
+	mkdir -p $(HDR)
+	cd /tmp; mig -server $(SRC)/ucspServer.cpp -user $(SRC)/ucspUser.cpp \
+		-header $(HDR)/ucsp.h $(SRCROOT)/SecurityServer/ucsp.defs
+	touch $(SRC)/.mig.ucsp
+
+$(SRC)/.mig.secagent: SecurityServer/secagent.defs SecurityServer/secagent_types.h
+	mkdir -p $(SRC)
+	mkdir -p $(HDR)
+	cd /tmp; mig -server $(SRC)/secagentServer.cpp -user $(SRC)/secagentUser.cpp \
+		-header $(HDR)/secagent.h $(SRCROOT)/SecurityServer/secagent.defs
+	touch $(SRC)/.mig.secagent
diff --git a/SecurityServer/Makefile.startup b/SecurityServer/Makefile.startup
new file mode 100644
index 00000000..bda8b415
--- /dev/null
+++ b/SecurityServer/Makefile.startup
@@ -0,0 +1,53 @@
+#
+#	Makefile to install the system-startup code for SecurityServer
+#
+
+# wouldn't it be nice if PBX actually $#@?@! defined those?
+# Note: CORE_SERVICES_DIR should be absolute path in target environment (don't prefix with DSTROOT)
+SYSTEM_LIBRARY_DIR=$(DSTROOT)/System/Library
+SYSTEM_CORE_SERVICES_DIR=/System/Library/CoreServices
+AUTHORIZATION_LOCATION=$(DSTROOT)/private/etc
+AUTHORIZATION_PLIST=$(AUTHORIZATION_LOCATION)/authorization
+
+DST=$(SYSTEM_LIBRARY_DIR)/StartupItems/SecurityServer
+SRC=$(SRCROOT)/SecurityServer
+
+
+#
+# The other phases do nothing
+#
+build:	
+	@echo null build.
+
+debug:
+	@echo null debug.
+
+profile:
+	@echo null profile.
+
+#
+# Install
+#
+install:
+	mkdir -p $(DST)/Resources/English.lproj
+	cp $(SRC)/StartupItems/StartupParameters.plist $(DST)
+	sed -e "s:@@@:$(SYSTEM_CORE_SERVICES_DIR):g" $(SRC)/StartupItems/SecurityServer >$(DST)/SecurityServer
+	cp $(SRC)/StartupItems/Localizable.strings $(DST)/Resources/English.lproj/Localizable.strings
+	chown -R root.wheel $(DST)
+	chmod 755 $(DST)/SecurityServer
+	chmod 644 $(DST)/StartupParameters.plist
+	chmod 644 $(DST)/Resources/English.lproj/Localizable.strings
+	chmod 4711 $(DSTROOT)/$(SYSTEM_CORE_SERVICES_DIR)/AuthorizationTrampoline
+	mkdir -p $(AUTHORIZATION_LOCATION)
+	cp $(SRC)/Authorization/authorization.plist $(AUTHORIZATION_PLIST)
+	chown root.admin $(AUTHORIZATION_PLIST)
+	chmod 640 $(AUTHORIZATION_PLIST)
+
+installhdrs:
+	@echo null installhdrs.
+
+installsrc:
+	@echo null installsrc.
+
+clean:
+	@echo null clean.
diff --git a/SecurityServer/SecurityAgentClient.cpp b/SecurityServer/SecurityAgentClient.cpp
new file mode 100644
index 00000000..7528ee7d
--- /dev/null
+++ b/SecurityServer/SecurityAgentClient.cpp
@@ -0,0 +1,685 @@
+/*
+ * 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.
+ */
+
+
+//
+// SecurityAgentClient - client interface to SecurityAgent
+//
+// This file changes behavior depending on two environment variables.
+// AGENTNAME/AGENTPATH: if defined, is the name and path to
+// the SecurityAgent binary to autolaunch. If undefined, SecurityAgent must be running.
+// NOSA: If set, check for NOSA environment variable and if set, simulate the Agent
+//  using stdio in the client.
+//
+// A note on message flow: the combined send/receive operation at the heart of each
+// secagent_client_* call can receive three types of message:
+// (o) SecurityAgent reply -- ok, process
+// (o) Dead port notification -- agent died, translated to NO_USER_INTERACTION error thrown
+// (o) Cancel message -- will come out as INVALID_ID error and throw
+//
+// @@@ SA keepalive option.
+//
+#include "SecurityAgentClient.h"
+#include "secagent.h"
+#include <Security/utilities.h>
+#include <Security/Authorization.h>
+#include <cstdio>
+#include <unistd.h>
+#include <mach/mach_error.h>
+#include <mach/ndr.h>
+#include <Security/debugging.h>
+#include <sys/wait.h>
+#include <sys/syslimits.h>
+#include <time.h>
+
+// @@@ Should be in <time.h> but it isn't as of Puma5F22
+extern "C" int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
+
+namespace Security {
+namespace SecurityAgent {
+
+
+using namespace Security;
+using namespace MachPlusPlus;
+
+
+//
+// Encode a requestor
+//
+class Requestor {
+public:
+	Requestor(const OSXCode *code)	{ if (code) extForm = code->encode(); }
+	operator const char * () const	{ return extForm.c_str(); }
+
+private:
+	string extForm;
+};
+
+
+//
+// Check a return from a MIG client call
+//
+void Client::check(kern_return_t error)
+{
+	// first check the Mach IPC return code
+	switch (error) {
+	case KERN_SUCCESS:				// peachy
+		break;
+	case MIG_SERVER_DIED:			// explicit can't-send-it's-dead
+		stage = mainStage;
+		CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+	default:						// some random Mach error
+		stage = mainStage;
+		MachPlusPlus::Error::throwMe(error);
+	}
+	
+	// now check the OSStatus return from the server side
+	switch (status) {
+	case noErr:
+	case errAuthorizationDenied:
+		break;
+	case userCanceledErr:
+		unstage();
+		CssmError::throwMe(CSSM_ERRCODE_USER_CANCELED);
+	default:
+		unstage();
+		MacOSError::throwMe(status);
+	}
+}
+
+void Client::unstage()
+{
+	if (stage != mainStage) {
+		mStagePort.deallocate();
+		stage = mainStage;
+	}
+}
+
+
+//
+// NOSA support functions. This is a test mode where the SecurityAgent
+// is simulated via stdio in the client. Good for running automated tests
+// of client programs. Only available if -DNOSA when compiling.
+//
+#if defined(NOSA)
+
+#include <cstdarg>
+
+static void getNoSA(char *buffer, size_t bufferSize, const char *fmt, ...)
+{
+	// write prompt
+	va_list args;
+	va_start(args, fmt);
+	vfprintf(stdout, fmt, args);
+	va_end(args);
+
+	// read reply
+	memset(buffer, 0, bufferSize);
+	const char *nosa = getenv("NOSA");
+	if (!strcmp(nosa, "-")) {
+		if (fgets(buffer, bufferSize-1, stdin) == NULL)
+			CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+		buffer[strlen(buffer)-1] = '\0';	// remove trailing newline
+		if (!isatty(fileno(stdin)))
+			printf("%s\n", buffer);			// echo to output if input not terminal
+	} else {
+		strncpy(buffer, nosa, bufferSize-1);
+		printf("%s\n", buffer);
+	}
+	if (buffer[0] == '\0')				// empty input -> cancellation
+		CssmError::throwMe(CSSM_ERRCODE_USER_CANCELED);
+}
+
+#endif //NOSA
+
+
+//
+// Initialize our CSSM interface
+//
+Client::Client() : mActive(false), mKeepAlive(false), stage(mainStage)
+{
+}
+
+Client::~Client()
+{
+	terminate();
+}
+
+
+//
+// Activate a session
+//
+void Client::activate(const char *name)
+{
+	if (!mActive) {
+        establishServer(name ? name : "SecurityAgent");
+		
+		// create reply port
+		mClientPort.allocate(MACH_PORT_RIGHT_RECEIVE);
+		mClientPort.insertRight(MACH_MSG_TYPE_MAKE_SEND);
+		
+		// get notified if the server dies (shouldn't happen, but...)
+		mServerPort.requestNotify(mClientPort, MACH_NOTIFY_DEAD_NAME, true);
+		
+		// ready
+		mActive = true;
+	}
+}
+
+void Client::terminate()
+{
+	if (mActive) {
+		mServerPort.deallocate();
+		mClientPort.destroy();
+		mActive = false;
+	}
+}
+
+
+//
+// Cancel a client call.
+// This actually sends a reply message to the thread waiting for a reply,
+// thereby unblocking it.
+// @@@ Theoretically we should thread-lock this so only one cancel message
+// ever gets sent. But right now, this is only used to completely tear down
+// a client session, so duplicate replies don't bother us.
+//
+void Client::cancel()
+{
+	// this is the common prefix of SecurityAgent client call replies
+	struct {
+			mach_msg_header_t Head;
+			NDR_record_t NDR;
+			kern_return_t result;
+			OSStatus status;
+	} request;
+
+	request.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
+	request.Head.msgh_remote_port = mClientPort;
+	request.Head.msgh_local_port = MACH_PORT_NULL;
+	request.Head.msgh_id = cancelMessagePseudoID;
+	request.NDR = NDR_record;
+	
+	// set call succeeded, no error status
+	request.result = KERN_SUCCESS;
+	request.status = noErr;
+
+	// send it (do not receive a reply). Use zero timeout to avoid hangs
+	MachPlusPlus::check(mach_msg_overwrite(&request.Head, MACH_SEND_MSG|MACH_SEND_TIMEOUT, 
+		sizeof(request), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, 
+		MACH_PORT_NULL, (mach_msg_header_t *) NULL, 0));
+}
+
+
+//
+// Get the port for the SecurityAgent.
+// Start it if necessary (and possible). Throw an exception if we can't get to it.
+// Sets mServerPort on success.
+//
+void Client::establishServer(const char *name)
+{
+    locateDesktop();
+
+    // If the userids don't match, that means you can't do user interaction
+    // @@@ Expose this to caller so it can implement its own idea of getuid()!
+    if (desktopUid != getuid() && getuid() != 0)
+        CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+        
+    // if the server is already running, we're done
+    Bootstrap bootstrap(pbsBootstrap);
+    if (mServerPort = bootstrap.lookupOptional(name))
+        return;
+
+#if defined(AGENTNAME) && defined(AGENTPATH)
+    // switch the bootstrap port to that of the logged-in user
+    StBootstrap bootSaver(pbsBootstrap);
+
+    // try to start the agent
+    switch (pid_t pid = fork()) {
+    case 0:		// child
+	{
+		// Setup the environment for the SecurityAgent
+		unsetenv("USER");
+		unsetenv("LOGNAME");
+		unsetenv("HOME");
+
+        debug("SAclnt", "setgid(%d)", desktopGid);
+        setgid(desktopGid);	// switch to login-user gid
+        debug("SAclnt", "setuid(%d)", desktopUid);
+		// Must be setuid and not seteuid since we do not want the agent to be able
+		// to call seteuid(0) successfully.
+        setuid(desktopUid);	// switch to login-user uid
+
+        // construct path to SecurityAgent
+        char agentExecutable[PATH_MAX + 1];
+        const char *path = getenv("SECURITYAGENT");
+        if (!path)
+            path = AGENTPATH;
+        snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/MacOS/" AGENTNAME, path);
+        debug("SAclnt", "execl(%s)", agentExecutable);
+        execl(agentExecutable, agentExecutable, NULL);
+		debug("SAclnt", "execl of SecurityAgent failed, errno=%d", errno);
+
+        // Unconditional suicide follows.
+		// See comments below on why we can't use abort()
+#if 1
+		_exit(1);
+#else
+        // NOTE: OS X abort() is implemented as kill(getuid()), which fails
+        // for a setuid-root process that has setuid'd. Go back to root to die...
+        setuid(0);
+        abort();
+#endif
+	}
+    case -1:	// error (in parent)
+        UnixError::throwMe();
+    default:	// parent
+        {
+			static const int timeout = 300;
+
+            debug("SAclnt", "Starting security agent (%d seconds timeout)", timeout);
+			struct timespec rqtp;
+			memset(&rqtp, 0, sizeof(rqtp));
+			rqtp.tv_nsec = 100000000; /* 10^8 nanaseconds = 1/10th of a second */
+            for (int n = timeout; n > 0; nanosleep(&rqtp, NULL), n--) {
+                if (mServerPort = bootstrap.lookupOptional(name))
+                    break;
+                int status;
+                switch (pid_t rc = waitpid(pid, &status, WNOHANG)) {
+                case 0:	// child still running
+                    continue;
+                case -1:	// error
+                    switch (errno) {
+                    case EINTR:
+                    case EAGAIN:	// transient
+                        continue;
+                    case ECHILD:	// no such child (dead; already reaped elsewhere)
+                        debug("SAclnt", "child is dead (reaped elsewhere)");
+                        CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+                    default:
+                        debug("SAclnt", "waitpid failed: errno=%d", errno);
+                        UnixError::throwMe();
+                    }
+                default:
+                    assert(rc == pid);
+                    debug("SAclnt", "child died without claiming the SecurityAgent port");
+                    CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+                }
+            }
+
+            if (mServerPort == 0) {		// couldn't contact Security Agent
+				debug("SAclnt", "Autolaunch failed");
+                CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+			}
+            debug("SAclnt", "SecurityAgent located");
+            return;
+        }
+    }
+#endif
+
+    // well, this didn't work. Too bad
+	debug("SAclnt", "Cannot contact SecurityAgent");
+    CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);	//@@@ or INTERNAL_ERROR?
+}
+
+
+//
+// Staged query maintainance
+//
+void Client::finishStagedQuery()
+{
+	if (stage == mainStage)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); //@@@ invent a "state mismatch error"?
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		printf(" [query done]\n");
+		stage = mainStage;
+		return;
+	}
+#endif		
+	check(secagent_client_finishStagedQuery(mStagePort, mClientPort, &status));
+	unstage();
+    terminate();
+}
+
+void Client::cancelStagedQuery(Reason reason)
+{
+	if (stage == mainStage)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); //@@@ invent a "state mismatch error"?
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		printf(" [query canceled; reason=%d]\n", reason);
+		stage = mainStage;
+		return;
+	}
+#endif
+	check(secagent_client_cancelStagedQuery(mStagePort, mClientPort, &status, reason));
+	unstage();
+    terminate();
+}
+
+
+//
+// Query the user to unlock a keychain. This is a staged protocol with a private side-port.
+//
+void Client::queryUnlockDatabase(const OSXCode *requestor, pid_t requestPid,
+    const char *database, char passphrase[maxPassphraseLength])
+{
+	Requestor req(requestor);
+	
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(passphrase, maxPassphraseLength, "Unlock %s [<CR> to cancel]: ", database);
+		stage = unlockStage;
+		return;
+	}
+#endif
+	activate();
+	check(secagent_client_unlockDatabase(mServerPort, mClientPort,
+		&status, req, requestPid, database, &mStagePort.port(), passphrase));
+	stage = unlockStage;
+}
+
+void Client::retryUnlockDatabase(Reason reason, char passphrase[maxPassphraseLength])
+{
+	if (stage != unlockStage)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	//@@@ invent a "state mismatch error"?
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(passphrase, maxPassphraseLength, "Retry unlock [<CR> to cancel]: ");
+		return;
+	}
+#endif
+	check(secagent_client_retryUnlockDatabase(mStagePort, mClientPort,
+		&status, reason, passphrase));
+}
+
+
+//
+// Ask for a (new) password for something.
+//
+void Client::queryNewPassphrase(const OSXCode *requestor, pid_t requestPid,
+    const char *database, Reason reason, char passphrase[maxPassphraseLength])
+{
+	Requestor req(requestor);
+	
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(passphrase, maxPassphraseLength,
+			"New passphrase for %s (reason %d) [<CR> to cancel]: ",
+			(database ? database : "[NULL database]"), reason);
+		stage = newPassphraseStage;
+		return;
+	}
+#endif
+	activate();
+	check(secagent_client_queryNewPassphrase(mServerPort, mClientPort,
+		&status, req, requestPid, database, reason,
+        &mStagePort.port(), passphrase));
+	stage = newPassphraseStage;
+}
+
+void Client::retryNewPassphrase(Reason reason, char passphrase[maxPassphraseLength])
+{
+	if (stage != newPassphraseStage)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	//@@@ invent a "state mismatch error"?
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(passphrase, maxPassphraseLength,
+			"retry new passphrase (reason %d) [<CR> to cancel]: ", reason);
+		return;
+	}
+#endif
+	check(secagent_client_retryNewPassphrase(mStagePort, mClientPort,
+		&status, reason, passphrase));
+}
+
+
+//
+// Ask the user permission to use an item.
+// This is used by the keychain-style ACL subject type (only).
+//
+void Client::queryKeychainAccess(const OSXCode *requestor, pid_t requestPid,
+    const char *database, const char *itemName, AclAuthorization action,
+    Client::KeychainChoice &choice)
+{
+	Requestor req(requestor);
+
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		char answer[10];
+		getNoSA(answer, sizeof(answer), "Allow [someone] to do %d on %s in %s? ",
+			int(action), (itemName ? itemName : "[NULL item]"),
+			(database ? database : "[NULL database]"));
+		choice.allowAccess = answer[0] == 'y';
+		choice.continueGrantingToCaller = answer[1] == 'g';
+		return;
+	}
+#endif
+	activate();
+	check(secagent_client_queryKeychainAccess(mServerPort, mClientPort,
+		&status, req, requestPid, (database ? database : ""), itemName, action, &choice));
+    terminate();
+}
+
+
+//
+// Query the user for a generic existing passphrase, with selectable prompt.
+//
+void Client::queryOldGenericPassphrase(const OSXCode *requestor, pid_t requestPid,
+    const char *prompt,
+    KeychainBox &addToKeychain, char passphrase[maxPassphraseLength])
+{
+	Requestor req(requestor);
+	
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(passphrase, maxPassphraseLength,
+            "Old passphrase (\"%s\") [<CR> to cancel]: ", prompt);
+        // @@@ addToKeychain not hooked up; stays unchanged
+		stage = oldGenericPassphraseStage;
+		return;
+	}
+#endif
+	activate();
+    MigBoolean addBox = addToKeychain.setting;
+	check(secagent_client_queryOldGenericPassphrase(mServerPort, mClientPort,
+		&status, req, requestPid, prompt, &mStagePort.port(),
+        addToKeychain.show, &addBox, passphrase));
+    addToKeychain.setting = addBox;
+	stage = oldGenericPassphraseStage;
+}
+
+void Client::retryOldGenericPassphrase(Reason reason, 
+    bool &addToKeychain, char passphrase[maxPassphraseLength])
+{
+	if (stage != oldGenericPassphraseStage)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); //@@@ invent a "state mismatch error"?
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(passphrase, maxPassphraseLength,
+            "Retry old passphrase [<CR> to cancel]: ");
+		return;
+	}
+#endif
+    MigBoolean addBox;
+	check(secagent_client_retryOldGenericPassphrase(mStagePort, mClientPort,
+		&status, reason, &addBox, passphrase));
+    addToKeychain = addBox;
+}
+
+
+//
+// Ask for a new passphrase for something (with selectable prompt).
+//
+void Client::queryNewGenericPassphrase(const OSXCode *requestor, pid_t requestPid,
+    const char *prompt, Reason reason,
+    KeychainBox &addToKeychain, char passphrase[maxPassphraseLength])
+{
+	Requestor req(requestor);
+	
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(passphrase, maxPassphraseLength,
+			"New passphrase (\"%s\") (reason %d) [<CR> to cancel]: ",
+			prompt, reason);
+        // @@@ addToKeychain not hooked up; stays unchanged
+		stage = newGenericPassphraseStage;
+		return;
+	}
+#endif
+	activate();
+    MigBoolean addBox = addToKeychain.setting;
+	check(secagent_client_queryNewGenericPassphrase(mServerPort, mClientPort,
+		&status, req, requestPid, prompt, reason,
+        &mStagePort.port(), addToKeychain.show, &addBox, passphrase));
+    addToKeychain.setting = addBox;
+	stage = newGenericPassphraseStage;
+}
+
+void Client::retryNewGenericPassphrase(Reason reason,
+    bool &addToKeychain, char passphrase[maxPassphraseLength])
+{
+	if (stage != newGenericPassphraseStage)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); //@@@ invent a "state mismatch error"?
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(passphrase, maxPassphraseLength,
+			"retry new passphrase (reason %d) [<CR> to cancel]: ", reason);
+		return;
+	}
+#endif
+    MigBoolean addBox;
+	check(secagent_client_retryNewGenericPassphrase(mStagePort, mClientPort,
+		&status, reason, &addBox, passphrase));
+    addToKeychain = addBox;
+}
+
+
+//
+// Authorization by authentication
+//
+bool Client::authorizationAuthenticate(const OSXCode *requestor, pid_t requestPid,
+	const char *neededGroup, const char *candidateUser,
+	char user[maxUsernameLength], char passphrase[maxPassphraseLength])
+{
+	Requestor req(requestor);
+
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(user, maxUsernameLength,
+			"User to authenticate for group %s (try \"%s\" [\"-\" to deny]): ",
+			neededGroup, (candidateUser ? candidateUser : "[NULL]"));
+		if (strcmp(user, "-"))
+                    getNoSA(passphrase, maxPassphraseLength,
+                            "Passphrase for user %s: ", user);
+		stage = authorizeStage;
+		return strcmp(user, "-");
+	}
+#endif
+	activate();
+	check(secagent_client_authorizationAuthenticate(mServerPort, mClientPort,
+			&status, req, requestPid, neededGroup, candidateUser, &mStagePort.port(), user, passphrase));
+    stage = authorizeStage;
+	return status == noErr;
+}
+
+bool Client::retryAuthorizationAuthenticate(Reason reason, char user[maxUsernameLength],
+        char passphrase[maxPassphraseLength])
+{
+	if (stage != authorizeStage)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	//@@@ invent a "state mismatch error"?
+#if defined(NOSA)
+	if (getenv("NOSA")) {
+		getNoSA(user, maxUsernameLength,
+			"Retry authenticate (reason=%d) ([\"-\" to deny again]): ", reason);
+		if (strcmp(user, "-"))
+                    getNoSA(passphrase, maxPassphraseLength,
+                            "Passphrase for user %s: ", user);
+		return strcmp(user, "-");
+	}
+#endif
+	check(secagent_client_retryAuthorizationAuthenticate(mStagePort, mClientPort,
+			&status, reason, user, passphrase));
+	return status == noErr;
+}
+
+
+//
+// Locate and identify the current desktop.
+// This is moderately atrocious code. There really ought to be a way to identify
+// the logged-in (graphics console) user (and whether there is one). As it stands,
+// we locate the "pbs" (pasteboard server) process and obtain its uid. No pbs, no
+// user interaction. (By all accounts, a dead pbs is a death sentence anyway.)
+//
+#include <sys/sysctl.h>
+#include <mach/mach_error.h>
+
+void Client::locateDesktop()
+{
+    int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL};
+    size_t bufSize;
+    struct kinfo_proc *procBuf;
+
+    if (sysctl(mib, 3, NULL, &bufSize, NULL, 0) < 0) {
+        perror("sysctl");
+        abort();
+    }
+
+    procBuf = (struct kinfo_proc *)malloc(bufSize);		//@@@ which allocator?
+    if (sysctl(mib, 3, procBuf, &bufSize, NULL, 0))
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+    int count = bufSize / sizeof(struct kinfo_proc);
+    struct kinfo_proc *pbsProc = NULL;
+    for (struct kinfo_proc *proc = procBuf; proc < procBuf + count; proc++) {
+        if (!strncmp(proc->kp_proc.p_comm, "pbs", MAXCOMLEN)) {
+            pbsProc = proc;
+            break;
+        }
+    }
+    
+    if (!pbsProc) {		// no pasteboard server -- user not logged in
+		debug("SAclnt", "No pasteboard server - no user logged in");
+        CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+	}
+
+    desktopUid = pbsProc->kp_eproc.e_ucred.cr_uid;
+    desktopGid = pbsProc->kp_eproc.e_ucred.cr_gid;
+	pid_t pbsPid = pbsProc->kp_proc.p_pid;
+
+    debug("SAclnt", "Desktop has uid %d", desktopUid);
+    free(procBuf);
+
+	kern_return_t result;
+	mach_port_t pbsTaskPort;
+	result = task_for_pid(mach_task_self(), pbsPid, &pbsTaskPort);
+	if (result)
+	{
+		mach_error("task_for_pid(pbs)", result);
+		CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+	}
+
+	result = task_get_bootstrap_port(pbsTaskPort, &pbsBootstrap);
+	if (result)
+	{
+		mach_error("task_get_bootstrap_port(pbs)", result);
+		CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+	}
+}
+
+} // end namespace SecurityAgent
+} // end namespace Security
diff --git a/SecurityServer/SecurityAgentClient.h b/SecurityServer/SecurityAgentClient.h
new file mode 100644
index 00000000..bc0c3ed2
--- /dev/null
+++ b/SecurityServer/SecurityAgentClient.h
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+
+//
+// SecurityAgentClient - client interface to SecurityAgent
+//
+#ifndef _H_SECURITYAGENTCLIENT
+#define _H_SECURITYAGENTCLIENT
+
+#if defined(__cplusplus)
+#include <string>
+#include <Security/mach++.h>
+#include <Security/osxsigning.h>
+#include <Security/cssmacl.h>
+#include <Security/cssm.h>
+
+namespace Security {
+
+using MachPlusPlus::Port;
+using CodeSigning::OSXCode;
+
+
+namespace SecurityAgent {
+
+#endif //C++ only
+
+// Note: Following section also available to C code for inclusion
+
+static const unsigned int maxPassphraseLength = 1024;
+static const unsigned int maxUsernameLength = 80;
+
+
+//
+// Unified reason codes transmitted to SecurityAgent (and internationalized there)
+//
+enum Reason {
+	noReason = 0,			// no reason (not used, used as a NULL)
+	unknownReason,			// something else (catch-all internal error)
+	
+	// reasons for asking for a new passphrase
+	newDatabase = 11,		// need passphrase for a new database
+	changePassphrase,		// changing passphrase for existing database
+	
+	// reasons for retrying an unlock query
+	invalidPassphrase = 21,	// passphrase was wrong
+	
+	// reasons for retrying a new passphrase query
+	passphraseIsNull = 31,	// empty passphrase
+	passphraseTooSimple,	// passphrase is not complex enough
+	passphraseRepeated,		// passphrase was used before (must use new one)
+	passphraseUnacceptable, // passphrase unacceptable for some other reason
+	
+	// reasons for retrying an authorization query
+	userNotInGroup = 41,	// authenticated user not in needed group
+	unacceptableUser,		// authenticated user unacceptable for some other reason
+	
+	// reasons for canceling a staged query
+	tooManyTries = 61,		// too many failed attempts to get it right
+	noLongerNeeded,			// the queried item is no longer needed
+	keychainAddFailed,		// the requested itemed couldn't be added to the keychain
+	generalErrorCancel		// something went wrong so we have to give up now
+};
+
+#if defined(__cplusplus)
+
+
+//
+// The client interface to the SecurityAgent.
+//
+class Client {
+public:
+	Client();
+	virtual ~Client();
+	
+	void activate(const char *bootstrapName = NULL);
+	void terminate();
+	
+	bool keepAlive() const		{ return mKeepAlive; }
+	void keepAlive(bool ka)		{ mKeepAlive = ka; }
+	
+	// common stage termination calls
+	void finishStagedQuery();
+	void cancelStagedQuery(Reason reason);
+    
+public:
+    struct KeychainBox {
+        bool show;				// show the "save in keychain" checkbox (in)
+        bool setting;			// value of the checkbox (in/out)
+    };
+	
+public:
+	// ask to unlock an existing database. Staged protocol
+	void queryUnlockDatabase(const OSXCode *requestor, pid_t requestPid,
+        const char *database, char passphrase[maxPassphraseLength]);
+	void retryUnlockDatabase(Reason reason, char passphrase[maxPassphraseLength]);
+	
+	// ask for a new passphrase for a database. Not yet staged
+	void queryNewPassphrase(const OSXCode *requestor, pid_t requestPid,
+        const char *database, Reason reason, char passphrase[maxPassphraseLength]);
+	void retryNewPassphrase(Reason reason, char passphrase[maxPassphraseLength]);
+	
+	// ask permission to use an item in a database
+    struct KeychainChoice {
+        bool allowAccess;
+        bool continueGrantingToCaller;
+    };
+    void queryKeychainAccess(const OSXCode *requestor, pid_t requestPid,
+        const char *database, const char *itemName, AclAuthorization action,
+		KeychainChoice &choice);
+        
+    // generic old passphrase query
+    void queryOldGenericPassphrase(const OSXCode *requestor, pid_t requestPid,
+        const char *prompt,
+        KeychainBox &addToKeychain, char passphrase[maxPassphraseLength]);
+    void retryOldGenericPassphrase(Reason reason,
+        bool &addToKeychain, char passphrase[maxPassphraseLength]);
+        
+    // generic new passphrase query
+    void queryNewGenericPassphrase(const OSXCode *requestor, pid_t requestPid,
+        const char *prompt, Reason reason,
+        KeychainBox &addToKeychain, char passphrase[maxPassphraseLength]);
+    void retryNewGenericPassphrase(Reason reason,
+        bool &addToKeychain, char passphrase[maxPassphraseLength]);
+	
+	// authenticate a user for the purpose of authorization
+	bool authorizationAuthenticate(const OSXCode *requestor, pid_t requestPid,
+		const char *neededGroup, const char *candidateUser,
+                char username[maxUsernameLength], char passphrase[maxPassphraseLength]);
+	bool retryAuthorizationAuthenticate(Reason reason,
+                char username[maxUsernameLength], char passphrase[maxPassphraseLength]);
+	
+	// Cancel a pending client call in another thread by sending a cancel message.
+	// This call (only) may be made from another thread.
+	void cancel();
+		
+private:
+	// used by client call wrappers to receive IPC return-status
+	OSStatus status;
+
+private:
+    Port mServerPort;
+    Port mClientPort;
+	bool mActive;
+    uid_t desktopUid;
+    gid_t desktopGid;
+    mach_port_t pbsBootstrap;
+	bool mKeepAlive;
+
+	enum Stage {
+		mainStage,				// in between requests
+		unlockStage,			// in unlock sub-protocol
+		newPassphraseStage,		// in get-new-passphrase sub-protocol
+        newGenericPassphraseStage, // in get-new-generic-passphrase sub-protocol
+        oldGenericPassphraseStage, // in get-old-generic-passphrase sub-protocol
+		authorizeStage			// in authorize-by-group-membership sub-protocol
+	} stage;
+	Port mStagePort;
+
+    void locateDesktop();
+    void establishServer(const char *name);
+	void check(kern_return_t error);
+	void unstage();
+	
+private:
+	static const int cancelMessagePseudoID = 1200;
+};
+
+}; // end namespace SecurityAgent
+
+} // end namespace Security
+
+#endif //C++ only
+
+#endif //_H_SECURITYAGENTCLIENT
diff --git a/SecurityServer/SecurityServer.order b/SecurityServer/SecurityServer.order
new file mode 100644
index 00000000..96e116f6
--- /dev/null
+++ b/SecurityServer/SecurityServer.order
@@ -0,0 +1,103 @@
+_ucsp_server__FP17mach_msg_header_tn1
+__Xsetup__FP17mach_msg_header_tn1
+save_world
+_ucsp_server_setup__FUiUiG16security_token_tPlUiPCc
+___get_eh_context
+_eh_context_via_pthreads
+_dcast__C14__si_type_infoRC9type_infoiPvPCB1Pv
+___eq__C9type_infoRCB0
+_setupConnection__6ServerGQ212MachPlusPlus4Portn1RC16security_token_tPCc
+_check__5Mutexi
+rest_world
+_debug__5MutexPCc
+___builtin_new
+___7ProcessGQ212MachPlusPlus4PortPCcUiUi
+_sessionForPort__7ProcessGQ212MachPlusPlus4Port
+_make__7Session
+_check__5Mutexi
+___10ConnectionR7ProcessGQ212MachPlusPlus4Port
+_check__5Mutexi
+_self__Q212MachPlusPlus4Port
+__XdecodeDb__FP17mach_msg_header_tn1
+_ucsp_server_decodeDb__FUiUiG16security_token_tPlPUlPQ211DataWalkers18DLDbFlatIdentifierUiPB1P17AccessCredentialsUiPB2PvUi
+_connection__6ServerUi
+_beginWork__10Connection
+_beginConnection__7ProcessR10Connection
+_debug__5MutexPCc
+_check__5Mutexi
+_debug__5MutexPCc
+___9XDatabaseRC14DLDbIdentifierPCQ214SecurityServer6DbBlobR7SessionPC17AccessCredentials
+_check__5Mutexi
+_debug__5MutexPCc
+_dumpState__9XDatabasePCc
+___builtin_delete
+_endWork__10Connection
+_checkWork__10Connection
+_debug__5MutexPCc
+_endConnection__7ProcessR10Connection
+_handle__6ServerP17mach_msg_header_tn1
+__XisLocked__FP17mach_msg_header_tn1
+_ucsp_server_isLocked__FUiUiG16security_token_tPlUlPi
+___dynamic_cast
+_dcast__C17__class_type_infoRC9type_infoiPvPCB1Pv
+__XunlockDb__FP17mach_msg_header_tn1
+_ucsp_server_unlockDb__FUiUiG16security_token_tPlUl
+_generateNewSecrets__18DatabaseCryptoCore
+_encodeKeyCore__C18DatabaseCryptoCoreR7CssmKeyRC8CssmDatan1
+___18SecurityAgentQuery
+___cl__11QueryUnlockPC17AccessCredentials
+_query__15QueryPassphrasePC17AccessCredentialsl
+_getBatchPassphrase__15QueryPassphrasePC17AccessCredentialslR13CssmOwnedData
+_queryInteractive__11QueryUnlockR13CssmOwnedData
+_connection__6Server
+_decodeKeyCore__C18DatabaseCryptoCorePQ214SecurityServer7KeyBlobR7CssmKeyRPvn1
+_encodeCore__C18DatabaseCryptoCoreRCQ214SecurityServer6DbBlobRC8CssmDatan2
+_decodeCore__18DatabaseCryptoCorePQ214SecurityServer6DbBlobRC8CssmDataPPv
+_makeRawKey__18DatabaseCryptoCorePvUlUl
+__._18DatabaseCryptoCore
+__._12CssmAutoData
+__._11QueryUnlock
+___eh_rtime_match
+___get_eh_info
+___start_cp_handler
+___cp_pop_exception
+___is_pointer__FPv
+___eh_free
+_unlock__9XDatabase
+_reset__12CssmAutoData
+_decode__9XDatabaseRC8CssmData
+_unlock__Q29XDatabase6CommonPQ214SecurityServer6DbBlobRC8CssmDataPPv
+_deriveDbCryptoKey__C18DatabaseCryptoCoreRC8CssmDatan1
+_getCsp__6Server
+_check__5Mutexi
+_unwrapKey__10ConnectionP9XDatabaseRC7ContextP3KeyPC17AccessCredentialsPC17AclEntryPrototypeUlUlG7CssmKeyPB3P8CssmData
+_ucsp_server_unwrapKey__FUiUiG16security_token_tPlUlG7ContextPvPQ27Context4AttrUiUlP17AccessCredentialsUiPB3P17AclEntryPrototypeUiPB4UlG7CssmKeyPvUiUlUlPPvPUiPUlPQ27CssmKey6Header
+_ucsp_server_lockDb__FUiUiG16security_token_tPlUl
+_ucsp_server_getOwner__FUiUiG16security_token_tPlQ214SecurityServer7AclKindUlPP17AclOwnerPrototypePUiPPB2
+__XgenerateKey__FP17mach_msg_header_tn1
+_ucsp_server_changePassphrase__FUiUiG16security_token_tPlUlP17AccessCredentialsUiPB1
+_debug__5MutexPCc
+_reset__12CssmAutoData
+_activity__Q29XDatabase6Common
+_makeDictionary__FRC14DLDbIdentifier
+_lockNotify__16KeychainNotifierRC14DLDbIdentifierb
+start
+__start
+__call_mod_init_funcs
+__dyld_init_check
+dyld_stub_binding_helper
+___18DatabaseCryptoCore
+__dyld_func_lookup
+__._Q210CssmClient3Key
+_notifyDeadName__6ServerGQ212MachPlusPlus4Port
+_abort__10Connection
+__._10Connection
+__._Q210CssmClient7WrapKey
+_generateMac__10ConnectionRC7ContextR3KeyRC8CssmDataRB3
+_active__6Server
+_encrypt__10ConnectionRC7ContextR3KeyRC8CssmDataRB3
+_key__6ServerUl
+_verifyMac__10ConnectionRC7ContextR3KeyRC8CssmDatan1
+_kill__7Process
+__._7Process
+_self__Q212MachPlusPlus4Port
diff --git a/SecurityServer/SecurityServer.pbxproj/.cvsignore b/SecurityServer/SecurityServer.pbxproj/.cvsignore
new file mode 100644
index 00000000..0857ac37
--- /dev/null
+++ b/SecurityServer/SecurityServer.pbxproj/.cvsignore
@@ -0,0 +1 @@
+*.pbxuser
diff --git a/SecurityServer/SecurityServer.pbxproj/project.pbxproj b/SecurityServer/SecurityServer.pbxproj/project.pbxproj
new file mode 100644
index 00000000..b5eee1d6
--- /dev/null
+++ b/SecurityServer/SecurityServer.pbxproj/project.pbxproj
@@ -0,0 +1,4284 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 31;
+	objects = {
+		00C958F7FF092883D0A17CE7 = {
+			children = (
+				6CC434E1FF09B18B11CD283A,
+				00C958F9FF092883D0A17CE7,
+				00C958FDFF092883D0A17CE7,
+				00C958F8FF092883D0A17CE7,
+				00C958FAFF092883D0A17CE7,
+				00C958FBFF092883D0A17CE7,
+				00C958FCFF092883D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = MacYarrow;
+			path = "";
+			refType = 4;
+		};
+		00C958F8FF092883D0A17CE7 = {
+			children = (
+				01005F97FF092E82D0A17CE7,
+				01005F98FF092E82D0A17CE7,
+				01005F99FF092E82D0A17CE7,
+				01005F9AFF092E82D0A17CE7,
+				01005F9BFF092E82D0A17CE7,
+				01005F9CFF092E82D0A17CE7,
+				01005F9DFF092E82D0A17CE7,
+				01005F9EFF092E82D0A17CE7,
+				01005F9FFF092E82D0A17CE7,
+				01005FA2FF092E82D0A17CE7,
+				01005FA3FF092E82D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = YarrowServer;
+			refType = 4;
+		};
+		00C958F9FF092883D0A17CE7 = {
+			children = (
+				01005F91FF092DE1D0A17CE7,
+				01005F92FF092DE1D0A17CE7,
+				01005F93FF092DE1D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "MIG RPC";
+			refType = 4;
+		};
+		00C958FAFF092883D0A17CE7 = {
+			children = (
+				01005FB4FF092EFBD0A17CE7,
+				01005FB5FF092EFBD0A17CE7,
+				01005FB6FF092EFBD0A17CE7,
+				01005FB7FF092EFBD0A17CE7,
+				01005FB8FF092EFBD0A17CE7,
+				01005FB9FF092EFBD0A17CE7,
+				01005FBAFF092EFBD0A17CE7,
+				01005FBBFF092EFBD0A17CE7,
+				01005FBCFF092EFBD0A17CE7,
+				01005FBDFF092EFBD0A17CE7,
+				01005FBEFF092EFBD0A17CE7,
+				01005FBFFF092EFBD0A17CE7,
+				01005FC0FF092EFBD0A17CE7,
+				01005FC1FF092EFBD0A17CE7,
+				01005FC2FF092EFBD0A17CE7,
+				01005FC4FF092EFBD0A17CE7,
+				01005FC5FF092EFBD0A17CE7,
+				01005FC6FF092EFBD0A17CE7,
+				01005FC7FF092EFBD0A17CE7,
+			);
+			isa = PBXGroup;
+			name = YarrowCoreLib;
+			path = "";
+			refType = 4;
+		};
+		00C958FBFF092883D0A17CE7 = {
+			children = (
+				01005FDCFF092F71D0A17CE7,
+				01005FDDFF092F71D0A17CE7,
+				01005FDEFF092F71D0A17CE7,
+				01005FDFFF092F71D0A17CE7,
+				01005FE0FF092F71D0A17CE7,
+				01005FE1FF092F71D0A17CE7,
+				01005FE2FF092F71D0A17CE7,
+				01005FE3FF092F71D0A17CE7,
+				01005FE4FF092F71D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = zlib;
+			path = "";
+			refType = 4;
+		};
+		00C958FCFF092883D0A17CE7 = {
+			children = (
+				01005FEEFF092FB8D0A17CE7,
+				01005FEFFF092FB8D0A17CE7,
+				01005FF3FF0930C3D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "Test Harness";
+			path = "";
+			refType = 4;
+		};
+		00C958FDFF092883D0A17CE7 = {
+			children = (
+				03D6E7BAFF16DF7511CD283A,
+				01005F94FF092E82D0A17CE7,
+				01005F95FF092E82D0A17CE7,
+			);
+			isa = PBXGroup;
+			name = YarrowClient;
+			path = "";
+			refType = 4;
+		};
+		00C95903FF092949D0A17CE7 = {
+			buildPhases = (
+				00C95904FF092949D0A17CE7,
+				00C95905FF092949D0A17CE7,
+				00C95906FF092949D0A17CE7,
+				00C95907FF092949D0A17CE7,
+				00C95908FF092949D0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/include\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-lstdc++ -prebind -seg_addr_table $(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = SecurityYarrowClient;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				01005FF2FF093014D0A17CE7,
+			);
+			isa = PBXFrameworkTarget;
+			name = YarrowClient;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = SecurityYarrowClient;
+			productReference = 011B80E0FF140C9311CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict/>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		00C95904FF092949D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FA4FF092E82D0A17CE7,
+				03D6E7BBFF16DF7511CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		00C95905FF092949D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		00C95906FF092949D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FA5FF092E82D0A17CE7,
+				01005FF4FF0930C3D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		00C95907FF092949D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				0140AD53FFA8EB2311CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		00C95908FF092949D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		00C9590CFF0929F1D0A17CE7 = {
+			buildPhases = (
+				00C9590DFF0929F1D0A17CE7,
+				00C9590EFF0929F1D0A17CE7,
+				00C9590FFF0929F1D0A17CE7,
+				00C95910FF0929F1D0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/CIncludes\" \"$(SRCROOT)/MacYarrow\" \"$(SRCROOT)/MacYarrow/YarrowCoreLib/include\" \"$(SYMROOT)\" \"$(SYMROOT)/include\"";
+				LIBRARY_SEARCH_PATHS = "";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-L$(SYMROOT) -lYarrowCore";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libYarrowServer.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				01621B24FF09323DD0A17CE7,
+				01621B25FF09323DD0A17CE7,
+			);
+			isa = PBXLibraryTarget;
+			name = YarrowServer;
+			productName = libYarrowServer.a;
+			productReference = 011B80E1FF140C9311CD283A;
+			shouldUseHeadermap = 0;
+		};
+		00C9590DFF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FA7FF092E82D0A17CE7,
+				01005FA8FF092E82D0A17CE7,
+				01005FA9FF092E82D0A17CE7,
+				01005FAAFF092E82D0A17CE7,
+				01005FABFF092E82D0A17CE7,
+				01005FADFF092E82D0A17CE7,
+				6CC434E2FF09B18C11CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		00C9590EFF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FAEFF092E82D0A17CE7,
+				01005FAFFF092E82D0A17CE7,
+				01005FB0FF092E82D0A17CE7,
+				01005FB1FF092E82D0A17CE7,
+				01005FB3FF092E82D0A17CE7,
+				01621B2BFF09328ED0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		00C9590FFF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		00C95910FF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		00C95911FF0929F1D0A17CE7 = {
+			buildPhases = (
+				00C95912FF0929F1D0A17CE7,
+				00C95913FF0929F1D0A17CE7,
+				00C95914FF0929F1D0A17CE7,
+				00C95915FF0929F1D0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\" \"$(SRCROOT)/MacYarrow\"";
+				INSTALL_PATH = /usr/local/lib;
+				LIBRARY_SEARCH_PATHS = "\"$(SYMROOT)\"";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-lzlibcomp";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libYarrowCore.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				01621B23FF093182D0A17CE7,
+			);
+			isa = PBXLibraryTarget;
+			name = YarrowCore;
+			productInstallPath = /usr/local/lib;
+			productName = libYarrowCore.a;
+			productReference = 011B80E3FF140C9311CD283A;
+			shouldUseHeadermap = 0;
+		};
+		00C95912FF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FC8FF092EFBD0A17CE7,
+				01005FC9FF092EFBD0A17CE7,
+				01005FCAFF092EFBD0A17CE7,
+				01005FCBFF092EFBD0A17CE7,
+				01005FCCFF092EFBD0A17CE7,
+				01005FCDFF092EFBD0A17CE7,
+				01005FCEFF092EFBD0A17CE7,
+				01005FCFFF092EFBD0A17CE7,
+				01005FD0FF092EFBD0A17CE7,
+				01005FD1FF092EFBD0A17CE7,
+				01005FD2FF092EFBD0A17CE7,
+				01005FD3FF092EFBD0A17CE7,
+				01005FD4FF092EFBD0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		00C95913FF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FD5FF092EFBD0A17CE7,
+				01005FD6FF092EFBD0A17CE7,
+				01005FD7FF092EFBD0A17CE7,
+				01005FD8FF092EFBD0A17CE7,
+				01005FDAFF092EFBD0A17CE7,
+				01005FDBFF092EFBD0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		00C95914FF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		00C95915FF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		00C95916FF0929F1D0A17CE7 = {
+			buildPhases = (
+				00C95917FF0929F1D0A17CE7,
+				00C95918FF0929F1D0A17CE7,
+				00C95919FF0929F1D0A17CE7,
+				00C9591AFF0929F1D0A17CE7,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "";
+				LIBRARY_SEARCH_PATHS = "";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libzlibcomp.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLibraryTarget;
+			name = "zlib compress";
+			productName = libzlibcomp.a;
+			productReference = 011B80E2FF140C9311CD283A;
+			shouldUseHeadermap = 0;
+		};
+		00C95917FF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FE5FF092F71D0A17CE7,
+				01005FE6FF092F71D0A17CE7,
+				01005FE7FF092F71D0A17CE7,
+				01005FE8FF092F71D0A17CE7,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		00C95918FF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FE9FF092F71D0A17CE7,
+				01005FEAFF092F71D0A17CE7,
+				01005FEBFF092F71D0A17CE7,
+				01005FECFF092F71D0A17CE7,
+				01005FEDFF092F71D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		00C95919FF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		00C9591AFF0929F1D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		00C9591DFF092AA8D0A17CE7 = {
+			buildArgumentsString = "-f MakefileYarrow $ACTION \"SYMROOT=$(SYMROOT)\" \"SRCROOT=$(SRCROOT)\" ";
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = "Yarrow MIG RPC";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = "Yarrow MIG RPC";
+			productName = "Yarrow MIG RPC";
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 1;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		00C9591EFF092AA8D0A17CE7 = {
+			buildPhases = (
+				00C9591FFF092AA8D0A17CE7,
+				00C95920FF092AA8D0A17CE7,
+				00C95921FF092AA8D0A17CE7,
+				00C95922FF092AA8D0A17CE7,
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)/MacYarrow\"";
+				INSTALL_PATH = /usr/local/bin;
+				LIBRARY_SEARCH_PATHS = "\"$(SYMROOT)\"";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-lYarrowServer";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = yarrowTestServer;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				01621B2FFF0933F4D0A17CE7,
+			);
+			isa = PBXToolTarget;
+			name = yarrowTestServer;
+			productInstallPath = /usr/local/bin;
+			productName = yarrowTestServer;
+			productReference = 011B80DCFF140C9311CD283A;
+			shouldUseHeadermap = 0;
+		};
+		00C9591FFF092AA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		00C95920FF092AA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FF0FF092FB8D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		00C95921FF092AA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				0140AD55FFA8EB2311CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		00C95922FF092AA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		00C95923FF092AA8D0A17CE7 = {
+			buildPhases = (
+				00C95924FF092AA8D0A17CE7,
+				00C95925FF092AA8D0A17CE7,
+				00C95926FF092AA8D0A17CE7,
+				00C95927FF092AA8D0A17CE7,
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
+				HEADER_SEARCH_PATHS = "";
+				INSTALL_PATH = /usr/local/bin;
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = yarrowTestClient;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				01621B33FF09351FD0A17CE7,
+			);
+			isa = PBXToolTarget;
+			name = yarrowTestClient;
+			productInstallPath = /usr/local/bin;
+			productName = yarrowTestClient;
+			productReference = 011B80DEFF140C9311CD283A;
+			shouldUseHeadermap = 0;
+		};
+		00C95924FF092AA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		00C95925FF092AA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01005FF1FF092FB8D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		00C95926FF092AA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+				01C17CFCFF16DA6211CD283A,
+				0140AD56FFA8EB2311CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		00C95927FF092AA8D0A17CE7 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		00DFB0D2FEB79FB211CD296C = {
+			isa = PBXFileReference;
+			path = acls.h;
+			refType = 4;
+		};
+		00DFB0D3FEB79FB211CD296C = {
+			isa = PBXFileReference;
+			path = acls.cpp;
+			refType = 4;
+		};
+		00DFB0D4FEB79FB211CD296C = {
+			fileRef = 00DFB0D2FEB79FB211CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00DFB0D5FEB79FB211CD296C = {
+			fileRef = 00DFB0D3FEB79FB211CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00EFF5BBFE93EA0D11CD296C = {
+			isa = PBXFileReference;
+			path = transition.cpp;
+			refType = 4;
+		};
+		00EFF5BCFE93EA0D11CD296C = {
+			fileRef = 00EFF5BBFE93EA0D11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00EFF5EBFE95419011CD296C = {
+			fileRef = 348D2E5AFE81B60B11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00EFF5ECFE95419011CD296C = {
+			fileRef = 0F409627FE746BD111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00F9D6B9FEA504D511CD296C = {
+			buildPhases = (
+				00F9D6BAFEA504D511CD296C,
+				00F9D6BDFEA504D511CD296C,
+				00F9D6BEFEA504D511CD296C,
+				00F9D6C1FEA504D511CD296C,
+				00F9D6C4FEA504D511CD296C,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/include\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-Wno-unused -DSAFER";
+				OTHER_LDFLAGS = "-lstdc++ -prebind -seg_addr_table $(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = SecurityServerClient;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-unused -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				00F9D6CBFEA5060511CD296C,
+			);
+			isa = PBXFrameworkTarget;
+			name = "SecurityServer Client";
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = SecurityServerClient;
+			productReference = 011B80E4FF140C9311CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict/>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		00F9D6BAFEA504D511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				03D6E7B9FF16DE8A11CD283A,
+				00F9D6BBFEA504D511CD296C,
+				00F9D6BCFEA504D511CD296C,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		00F9D6BBFEA504D511CD296C = {
+			fileRef = 111A0B82FE75AA7411CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00F9D6BCFEA504D511CD296C = {
+			fileRef = 4D433F0DFE9CF5B811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00F9D6BDFEA504D511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		00F9D6BEFEA504D511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				00F9D6BFFEA504D511CD296C,
+				00F9D6C0FEA504D511CD296C,
+				00F9D6C8FEA5056A11CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		00F9D6BFFEA504D511CD296C = {
+			fileRef = 111A0B84FE75AAD211CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00F9D6C0FEA504D511CD296C = {
+			fileRef = 4D433F0EFE9CF5B811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00F9D6C1FEA504D511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				00F9D6C3FEA504D511CD296C,
+				0140AD52FFA8EB2311CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		00F9D6C3FEA504D511CD296C = {
+			fileRef = 0F409627FE746BD111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00F9D6C4FEA504D511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		00F9D6C8FEA5056A11CD296C = {
+			fileRef = 111A0B73FE75A89D11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00F9D6CBFEA5060511CD296C = {
+			isa = PBXTargetDependency;
+			target = 5DF1AE65FE88150D11CD296C;
+		};
+		00F9D6CDFEA5065511CD296C = {
+			children = (
+				011B80DFFF140C9311CD283A,
+				014A688AFFE94D9411CD296C,
+				011B80E0FF140C9311CD283A,
+				011B80E1FF140C9311CD283A,
+				011B80E2FF140C9311CD283A,
+				011B80E3FF140C9311CD283A,
+				011B80E4FF140C9311CD283A,
+				1379BD96FF9BA26811CD283A,
+				0140AD5AFFA8EBF911CD296C,
+				0140AD72FFA9002E11CD296C,
+				011B80DDFF140C9311CD283A,
+				011B80DEFF140C9311CD283A,
+				011B80DCFF140C9311CD283A,
+				037D0ECFFFA115C911CD283A,
+				2BC07DF1FFE9A3DE11CD296C,
+			);
+			isa = PBXGroup;
+			name = Products;
+			path = "";
+			refType = 3;
+		};
+		00FDF003FEDF19F511CD296C = {
+			isa = PBXFileReference;
+			path = session.cpp;
+			refType = 4;
+		};
+		00FDF004FEDF19F511CD296C = {
+			isa = PBXFileReference;
+			path = session.h;
+			refType = 4;
+		};
+		00FDF005FEDF19F511CD296C = {
+			fileRef = 00FDF004FEDF19F511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		00FDF006FEDF19F511CD296C = {
+			fileRef = 00FDF003FEDF19F511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005F91FF092DE1D0A17CE7 = {
+			isa = PBXFileReference;
+			path = yarrowMigTypes.h;
+			refType = 4;
+		};
+		01005F92FF092DE1D0A17CE7 = {
+			isa = PBXFileReference;
+			path = yarrowServer.defs;
+			refType = 4;
+		};
+		01005F93FF092DE1D0A17CE7 = {
+			isa = PBXFileReference;
+			path = MakefileYarrow;
+			refType = 4;
+		};
+		01005F94FF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = YarrowClient.h;
+			path = MacYarrow/YarrowClient/YarrowClient.h;
+			refType = 4;
+		};
+		01005F95FF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = YarrowClient_OSX.cpp;
+			path = MacYarrow/YarrowClient/YarrowClient_OSX.cpp;
+			refType = 4;
+		};
+		01005F97FF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = debug.c;
+			path = MacYarrow/YarrowServer/debug.c;
+			refType = 4;
+		};
+		01005F98FF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = debug.h;
+			path = MacYarrow/YarrowServer/debug.h;
+			refType = 4;
+		};
+		01005F99FF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = entropyFile.h;
+			path = MacYarrow/YarrowServer/entropyFile.h;
+			refType = 4;
+		};
+		01005F9AFF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = entropyFileUnix.c;
+			path = MacYarrow/YarrowServer/entropyFileUnix.c;
+			refType = 4;
+		};
+		01005F9BFF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = kdebug_private.h;
+			path = MacYarrow/YarrowServer/kdebug_private.h;
+			refType = 4;
+		};
+		01005F9CFF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = MacYarrow_OSX.cpp;
+			path = MacYarrow/YarrowServer/MacYarrow_OSX.cpp;
+			refType = 4;
+		};
+		01005F9DFF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = MacYarrow_OSX.h;
+			path = MacYarrow/YarrowServer/MacYarrow_OSX.h;
+			refType = 4;
+		};
+		01005F9EFF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = systemEntropy.c;
+			path = MacYarrow/YarrowServer/systemEntropy.c;
+			refType = 4;
+		};
+		01005F9FFF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = systemEntropy.h;
+			path = MacYarrow/YarrowServer/systemEntropy.h;
+			refType = 4;
+		};
+		01005FA2FF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = YarrowServer_OSX.cpp;
+			path = MacYarrow/YarrowServer/YarrowServer_OSX.cpp;
+			refType = 4;
+		};
+		01005FA3FF092E82D0A17CE7 = {
+			isa = PBXFileReference;
+			name = YarrowServer_OSX.h;
+			path = MacYarrow/YarrowServer/YarrowServer_OSX.h;
+			refType = 4;
+		};
+		01005FA4FF092E82D0A17CE7 = {
+			fileRef = 01005F94FF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FA5FF092E82D0A17CE7 = {
+			fileRef = 01005F95FF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FA7FF092E82D0A17CE7 = {
+			fileRef = 01005F98FF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FA8FF092E82D0A17CE7 = {
+			fileRef = 01005F99FF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FA9FF092E82D0A17CE7 = {
+			fileRef = 01005F9BFF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FAAFF092E82D0A17CE7 = {
+			fileRef = 01005F9DFF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FABFF092E82D0A17CE7 = {
+			fileRef = 01005F9FFF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FADFF092E82D0A17CE7 = {
+			fileRef = 01005FA3FF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FAEFF092E82D0A17CE7 = {
+			fileRef = 01005F97FF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FAFFF092E82D0A17CE7 = {
+			fileRef = 01005F9AFF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FB0FF092E82D0A17CE7 = {
+			fileRef = 01005F9CFF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FB1FF092E82D0A17CE7 = {
+			fileRef = 01005F9EFF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FB3FF092E82D0A17CE7 = {
+			fileRef = 01005FA2FF092E82D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FB4FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = WindowsTypesForMac.h;
+			path = MacYarrow/YarrowCoreLib/include/WindowsTypesForMac.h;
+			refType = 4;
+		};
+		01005FB5FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrow.h;
+			path = MacYarrow/YarrowCoreLib/include/yarrow.h;
+			refType = 4;
+		};
+		01005FB6FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrowUtils.h;
+			path = MacYarrow/YarrowCoreLib/include/yarrowUtils.h;
+			refType = 4;
+		};
+		01005FB7FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = assertverify.h;
+			path = MacYarrow/YarrowCoreLib/src/assertverify.h;
+			refType = 4;
+		};
+		01005FB8FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = comp.c;
+			path = MacYarrow/YarrowCoreLib/src/comp.c;
+			refType = 4;
+		};
+		01005FB9FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = comp.h;
+			path = MacYarrow/YarrowCoreLib/src/comp.h;
+			refType = 4;
+		};
+		01005FBAFF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = entropysources.h;
+			path = MacYarrow/YarrowCoreLib/src/entropysources.h;
+			refType = 4;
+		};
+		01005FBBFF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = macOnly.h;
+			path = MacYarrow/YarrowCoreLib/src/macOnly.h;
+			refType = 4;
+		};
+		01005FBCFF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = prng.c;
+			path = MacYarrow/YarrowCoreLib/src/prng.c;
+			refType = 4;
+		};
+		01005FBDFF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = prng.h;
+			path = MacYarrow/YarrowCoreLib/src/prng.h;
+			refType = 4;
+		};
+		01005FBEFF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = prngpriv.h;
+			path = MacYarrow/YarrowCoreLib/src/prngpriv.h;
+			refType = 4;
+		};
+		01005FBFFF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sha1mod.c;
+			path = MacYarrow/YarrowCoreLib/src/sha1mod.c;
+			refType = 4;
+		};
+		01005FC0FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = sha1mod.h;
+			path = MacYarrow/YarrowCoreLib/src/sha1mod.h;
+			refType = 4;
+		};
+		01005FC1FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = smf.cpp;
+			path = MacYarrow/YarrowCoreLib/src/smf.cpp;
+			refType = 4;
+		};
+		01005FC2FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = smf.h;
+			path = MacYarrow/YarrowCoreLib/src/smf.h;
+			refType = 4;
+		};
+		01005FC4FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = TBD.c;
+			path = MacYarrow/YarrowCoreLib/src/TBD.c;
+			refType = 4;
+		};
+		01005FC5FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = userdefines.h;
+			path = MacYarrow/YarrowCoreLib/src/userdefines.h;
+			refType = 4;
+		};
+		01005FC6FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = usersources.h;
+			path = MacYarrow/YarrowCoreLib/src/usersources.h;
+			refType = 4;
+		};
+		01005FC7FF092EFBD0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrowUtils.c;
+			path = MacYarrow/YarrowCoreLib/src/yarrowUtils.c;
+			refType = 4;
+		};
+		01005FC8FF092EFBD0A17CE7 = {
+			fileRef = 01005FB4FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FC9FF092EFBD0A17CE7 = {
+			fileRef = 01005FB5FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FCAFF092EFBD0A17CE7 = {
+			fileRef = 01005FB6FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FCBFF092EFBD0A17CE7 = {
+			fileRef = 01005FB7FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FCCFF092EFBD0A17CE7 = {
+			fileRef = 01005FB9FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FCDFF092EFBD0A17CE7 = {
+			fileRef = 01005FBAFF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FCEFF092EFBD0A17CE7 = {
+			fileRef = 01005FBBFF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FCFFF092EFBD0A17CE7 = {
+			fileRef = 01005FBDFF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD0FF092EFBD0A17CE7 = {
+			fileRef = 01005FBEFF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD1FF092EFBD0A17CE7 = {
+			fileRef = 01005FC0FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD2FF092EFBD0A17CE7 = {
+			fileRef = 01005FC2FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD3FF092EFBD0A17CE7 = {
+			fileRef = 01005FC5FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD4FF092EFBD0A17CE7 = {
+			fileRef = 01005FC6FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD5FF092EFBD0A17CE7 = {
+			fileRef = 01005FB8FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD6FF092EFBD0A17CE7 = {
+			fileRef = 01005FBCFF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD7FF092EFBD0A17CE7 = {
+			fileRef = 01005FBFFF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FD8FF092EFBD0A17CE7 = {
+			fileRef = 01005FC1FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FDAFF092EFBD0A17CE7 = {
+			fileRef = 01005FC4FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FDBFF092EFBD0A17CE7 = {
+			fileRef = 01005FC7FF092EFBD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FDCFF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = adler32.c;
+			path = MacYarrow/zlib/adler32.c;
+			refType = 4;
+		};
+		01005FDDFF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = compress.c;
+			path = MacYarrow/zlib/compress.c;
+			refType = 4;
+		};
+		01005FDEFF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = deflate.c;
+			path = MacYarrow/zlib/deflate.c;
+			refType = 4;
+		};
+		01005FDFFF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = deflate.h;
+			path = MacYarrow/zlib/deflate.h;
+			refType = 4;
+		};
+		01005FE0FF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = trees.c;
+			path = MacYarrow/zlib/trees.c;
+			refType = 4;
+		};
+		01005FE1FF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = trees.h;
+			path = MacYarrow/zlib/trees.h;
+			refType = 4;
+		};
+		01005FE2FF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = zlib.h;
+			path = MacYarrow/zlib/zlib.h;
+			refType = 4;
+		};
+		01005FE3FF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = zutil.c;
+			path = MacYarrow/zlib/zutil.c;
+			refType = 4;
+		};
+		01005FE4FF092F71D0A17CE7 = {
+			isa = PBXFileReference;
+			name = zutil.h;
+			path = MacYarrow/zlib/zutil.h;
+			refType = 4;
+		};
+		01005FE5FF092F71D0A17CE7 = {
+			fileRef = 01005FDFFF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FE6FF092F71D0A17CE7 = {
+			fileRef = 01005FE1FF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FE7FF092F71D0A17CE7 = {
+			fileRef = 01005FE2FF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FE8FF092F71D0A17CE7 = {
+			fileRef = 01005FE4FF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FE9FF092F71D0A17CE7 = {
+			fileRef = 01005FDCFF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FEAFF092F71D0A17CE7 = {
+			fileRef = 01005FDDFF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FEBFF092F71D0A17CE7 = {
+			fileRef = 01005FDEFF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FECFF092F71D0A17CE7 = {
+			fileRef = 01005FE0FF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FEDFF092F71D0A17CE7 = {
+			fileRef = 01005FE3FF092F71D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FEEFF092FB8D0A17CE7 = {
+			isa = PBXFileReference;
+			name = clientTest.cpp;
+			path = MacYarrow/testHarness/clientTest.cpp;
+			refType = 4;
+		};
+		01005FEFFF092FB8D0A17CE7 = {
+			isa = PBXFileReference;
+			name = serverDaemon.cpp;
+			path = MacYarrow/testHarness/serverDaemon.cpp;
+			refType = 4;
+		};
+		01005FF0FF092FB8D0A17CE7 = {
+			fileRef = 01005FEFFF092FB8D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FF1FF092FB8D0A17CE7 = {
+			fileRef = 01005FEEFF092FB8D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01005FF2FF093014D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 00C9591DFF092AA8D0A17CE7;
+		};
+		01005FF3FF0930C3D0A17CE7 = {
+			isa = PBXFileReference;
+			name = yarrowMigUser.cpp;
+			path = derived_src/yarrowMigUser.cpp;
+			refType = 3;
+		};
+		01005FF4FF0930C3D0A17CE7 = {
+			fileRef = 01005FF3FF0930C3D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01101223FF0D0DE311CD296C = {
+			children = (
+				01101224FF0D0DE311CD296C,
+				16732091FF32431411CD296C,
+			);
+			isa = PBXGroup;
+			name = "Installation Files";
+			path = "";
+			refType = 4;
+		};
+		01101224FF0D0DE311CD296C = {
+			isa = PBXFileReference;
+			path = Makefile.startup;
+			refType = 4;
+		};
+		01157F48FE7700BF11CD296C = {
+			isa = PBXFileReference;
+			path = ucsp.defs;
+			refType = 4;
+		};
+		011B80DCFF140C9311CD283A = {
+			isa = PBXExecutableFileReference;
+			path = yarrowTestServer;
+			refType = 3;
+		};
+		011B80DDFF140C9311CD283A = {
+			isa = PBXExecutableFileReference;
+			path = SSTester;
+			refType = 3;
+		};
+		011B80DEFF140C9311CD283A = {
+			isa = PBXExecutableFileReference;
+			path = yarrowTestClient;
+			refType = 3;
+		};
+		011B80DFFF140C9311CD283A = {
+			isa = PBXExecutableFileReference;
+			path = SecurityServer;
+			refType = 3;
+		};
+		011B80E0FF140C9311CD283A = {
+			isa = PBXFrameworkReference;
+			path = SecurityYarrowClient.framework;
+			refType = 3;
+		};
+		011B80E1FF140C9311CD283A = {
+			isa = PBXLibraryReference;
+			path = libYarrowServer.a;
+			refType = 3;
+		};
+		011B80E2FF140C9311CD283A = {
+			isa = PBXLibraryReference;
+			path = libzlibcomp.a;
+			refType = 3;
+		};
+		011B80E3FF140C9311CD283A = {
+			isa = PBXLibraryReference;
+			path = libYarrowCore.a;
+			refType = 3;
+		};
+		011B80E4FF140C9311CD283A = {
+			isa = PBXFrameworkReference;
+			path = SecurityServerClient.framework;
+			refType = 3;
+		};
+		0140AD51FFA8EA2311CD296C = {
+			children = (
+				0140AD58FFA8EBF911CD296C,
+				0140AD59FFA8EBF911CD296C,
+			);
+			isa = PBXGroup;
+			name = "SecurityAgent Client";
+			refType = 4;
+		};
+		0140AD52FFA8EB2311CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD53FFA8EB2311CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD54FFA8EB2311CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD55FFA8EB2311CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD56FFA8EB2311CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD57FFA8EB2311CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD58FFA8EBF911CD296C = {
+			isa = PBXFileReference;
+			path = SecurityAgentClient.cpp;
+			refType = 4;
+		};
+		0140AD59FFA8EBF911CD296C = {
+			isa = PBXFileReference;
+			path = SecurityAgentClient.h;
+			refType = 4;
+		};
+		0140AD5AFFA8EBF911CD296C = {
+			isa = PBXFrameworkReference;
+			path = SecurityAgentClient.framework;
+			refType = 3;
+		};
+		0140AD5BFFA8EBF911CD296C = {
+			isa = PBXTargetDependency;
+			target = 0140AD5CFFA8EBF911CD296C;
+		};
+		0140AD5CFFA8EBF911CD296C = {
+			buildPhases = (
+				0140AD5DFFA8EBF911CD296C,
+				0140AD5FFFA8EBF911CD296C,
+				0140AD60FFA8EBF911CD296C,
+				0140AD62FFA8EBF911CD296C,
+				0140AD63FFA8EBF911CD296C,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/include\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-DNOSA -DAGENTBUNDLE=\\\\\\\"/System/Library/CoreServices/SecurityAgent.app\\\\\\\"";
+				OTHER_LDFLAGS = "-lstdc++";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = SecurityAgentClient;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				1E3C053DFFA90CBA11CD283A,
+			);
+			isa = PBXFrameworkTarget;
+			name = "SecurityAgent Client";
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = SecurityAgentClient;
+			productReference = 0140AD5AFFA8EBF911CD296C;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string></string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		0140AD5DFFA8EBF911CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				0140AD5EFFA8EBF911CD296C,
+				0140AD6BFFA8EFFB11CD296C,
+				0140AD6CFFA8F8A411CD296C,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0140AD5EFFA8EBF911CD296C = {
+			fileRef = 0140AD59FFA8EBF911CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD5FFFA8EBF911CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		0140AD60FFA8EBF911CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				0140AD61FFA8EBF911CD296C,
+				0140AD6AFFA8EFBF11CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0140AD61FFA8EBF911CD296C = {
+			fileRef = 0140AD58FFA8EBF911CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD62FFA8EBF911CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				0140AD69FFA8EFAC11CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0140AD63FFA8EBF911CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0140AD64FFA8ECBF11CD296C = {
+			isa = PBXFileReference;
+			path = secagent.defs;
+			refType = 4;
+		};
+		0140AD65FFA8EE5711CD296C = {
+			isa = PBXFileReference;
+			path = secagent_types.h;
+			refType = 4;
+		};
+		0140AD66FFA8EEA811CD296C = {
+			isa = PBXFileReference;
+			path = secagentServer.cpp;
+			refType = 4;
+		};
+		0140AD67FFA8EEA811CD296C = {
+			isa = PBXFileReference;
+			path = secagentUser.cpp;
+			refType = 4;
+		};
+		0140AD68FFA8EEA811CD296C = {
+			isa = PBXFileReference;
+			path = secagent.h;
+			refType = 4;
+		};
+		0140AD69FFA8EFAC11CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD6AFFA8EFBF11CD296C = {
+			fileRef = 0140AD67FFA8EEA811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD6BFFA8EFFB11CD296C = {
+			fileRef = 0140AD68FFA8EEA811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD6CFFA8F8A411CD296C = {
+			fileRef = 0140AD65FFA8EE5711CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD6FFFA8FC4611CD296C = {
+			isa = PBXTargetDependency;
+			target = 0140AD5CFFA8EBF911CD296C;
+		};
+		0140AD72FFA9002E11CD296C = {
+			isa = PBXLibraryReference;
+			path = libSecurityAgentServer.a;
+			refType = 3;
+		};
+		0140AD73FFA9002E11CD296C = {
+			isa = PBXTargetDependency;
+			target = 0140AD74FFA9002E11CD296C;
+		};
+		0140AD74FFA9002E11CD296C = {
+			buildPhases = (
+				0140AD76FFA9002E11CD296C,
+				0140AD77FFA9002E11CD296C,
+				0140AD79FFA9002E11CD296C,
+				0140AD7AFFA9002E11CD296C,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/include\"";
+				INSTALL_PATH = /usr/local/lib;
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libSecurityAgentServer.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				0140AD75FFA9002E11CD296C,
+			);
+			isa = PBXLibraryTarget;
+			name = "SecurityAgent Server";
+			productInstallPath = /usr/local/lib;
+			productName = libSecurityAgentServer.a;
+			productReference = 0140AD72FFA9002E11CD296C;
+			shouldUseHeadermap = 0;
+		};
+		0140AD75FFA9002E11CD296C = {
+			isa = PBXTargetDependency;
+			target = 5DF1AE65FE88150D11CD296C;
+		};
+		0140AD76FFA9002E11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0140AD77FFA9002E11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				0140AD78FFA9002E11CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0140AD78FFA9002E11CD296C = {
+			fileRef = 0140AD66FFA8EEA811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0140AD79FFA9002E11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0140AD7AFFA9002E11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		014A6888FFE94D9411CD296C = {
+			children = (
+				014A6889FFE94D9411CD296C,
+				014A6894FFE9508C11CD296C,
+				014A6898FFE9535811CD296C,
+			);
+			isa = PBXGroup;
+			name = Trampoline;
+			refType = 4;
+		};
+		014A6889FFE94D9411CD296C = {
+			isa = PBXFileReference;
+			path = AuthorizationTrampoline.cpp;
+			refType = 4;
+		};
+		014A688AFFE94D9411CD296C = {
+			isa = PBXExecutableFileReference;
+			path = AuthorizationTrampoline;
+			refType = 3;
+		};
+		014A688BFFE94D9411CD296C = {
+			buildPhases = (
+				014A688CFFE94D9411CD296C,
+				014A688DFFE94D9411CD296C,
+				014A688FFFE94D9411CD296C,
+				014A6890FFE94D9411CD296C,
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"";
+				INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-Wno-unused -DSAFER";
+				OTHER_LDFLAGS = "-lstdc++";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AuthorizationTrampoline;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				014A689BFFE981FA11CD296C,
+			);
+			isa = PBXToolTarget;
+			name = AuthorizationTrampoline;
+			productInstallPath = "$(SYSTEM_CORE_SERVICES_DIR)";
+			productName = AuthorizationTrampoline;
+			productReference = 014A688AFFE94D9411CD296C;
+			shouldUseHeadermap = 0;
+		};
+		014A688CFFE94D9411CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		014A688DFFE94D9411CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				014A688EFFE94D9411CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		014A688EFFE94D9411CD296C = {
+			fileRef = 014A6889FFE94D9411CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		014A688FFFE94D9411CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				014A6892FFE94E8511CD296C,
+				014A6893FFE94E8511CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		014A6890FFE94D9411CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		014A6892FFE94E8511CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		014A6893FFE94E8511CD296C = {
+			fileRef = 1379BD96FF9BA26811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		014A6894FFE9508C11CD296C = {
+			isa = PBXFileReference;
+			path = trampolineClient.cpp;
+			refType = 4;
+		};
+		014A6896FFE9508C11CD296C = {
+			fileRef = 014A6894FFE9508C11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		014A6898FFE9535811CD296C = {
+			isa = PBXFileReference;
+			path = trampolineServer.cpp;
+			refType = 4;
+		};
+		014A6899FFE9535811CD296C = {
+			fileRef = 014A6898FFE9535811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		014A689AFFE981FA11CD296C = {
+			isa = PBXTargetDependency;
+			target = 014A688BFFE94D9411CD296C;
+		};
+		014A689BFFE981FA11CD296C = {
+			isa = PBXTargetDependency;
+			target = 1379BD97FF9BA26811CD283A;
+		};
+		0159DF1CFFBB405111CD296C = {
+			children = (
+				5DF1AEB3FE88242A11CD296C,
+				5DF1AEB4FE88242A11CD296C,
+				0159DF1DFFBB405111CD296C,
+				0159DF1EFFBB405111CD296C,
+				00FDF004FEDF19F511CD296C,
+				00FDF003FEDF19F511CD296C,
+			);
+			isa = PBXGroup;
+			name = "Client State";
+			refType = 4;
+		};
+		0159DF1DFFBB405111CD296C = {
+			isa = PBXFileReference;
+			path = process.h;
+			refType = 4;
+		};
+		0159DF1EFFBB405111CD296C = {
+			isa = PBXFileReference;
+			path = process.cpp;
+			refType = 4;
+		};
+		0159DF1FFFBB405111CD296C = {
+			fileRef = 0159DF1DFFBB405111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0159DF20FFBB405111CD296C = {
+			fileRef = 0159DF1EFFBB405111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01621B23FF093182D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 00C95916FF0929F1D0A17CE7;
+		};
+		01621B24FF09323DD0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 00C9591DFF092AA8D0A17CE7;
+		};
+		01621B25FF09323DD0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 00C95911FF0929F1D0A17CE7;
+		};
+		01621B2AFF09328ED0A17CE7 = {
+			isa = PBXFileReference;
+			path = yarrowMigServer.cpp;
+			refType = 4;
+		};
+		01621B2BFF09328ED0A17CE7 = {
+			fileRef = 01621B2AFF09328ED0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01621B2FFF0933F4D0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 00C9590CFF0929F1D0A17CE7;
+		};
+		01621B33FF09351FD0A17CE7 = {
+			isa = PBXTargetDependency;
+			target = 00C95903FF092949D0A17CE7;
+		};
+		01621B35FF09357FD0A17CE7 = {
+			isa = PBXFrameworkReference;
+			path = cdsa_utilities.framework;
+			refType = 3;
+		};
+		01692084FF9CE78611CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01692085FF9CE78611CD296C = {
+			fileRef = 011B80E4FF140C9311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01692086FF9CE7A811CD296C = {
+			isa = PBXTargetDependency;
+			target = 00F9D6B9FEA504D511CD296C;
+		};
+		01692087FF9CF5BB11CD296C = {
+			isa = PBXTargetDependency;
+			target = 1379BD97FF9BA26811CD283A;
+		};
+		01C17CFBFF16D9FF11CD283A = {
+			fileRef = 011B80E4FF140C9311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01C17CFCFF16DA6211CD283A = {
+			fileRef = 011B80E0FF140C9311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		01CAFEA1FF0BDAF611CD296C = {
+			isa = PBXTargetDependency;
+			target = 01CAFEA2FF0BDAF611CD296C;
+		};
+		01CAFEA2FF0BDAF611CD296C = {
+			buildArgumentsString = "-f Makefile.startup $ALL_SETTINGS $ACTION";
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = "Install Startup Arrangements";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				3382A64DFFEAABFA11CD296C,
+			);
+			isa = PBXLegacyTarget;
+			name = "Install Startup Arrangements";
+			productName = "Install Startup Arrangements";
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 1;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		01CAFEA3FF0BDDF111CD296C = {
+			isa = PBXFrameworkReference;
+			path = SecurityAgentClient.framework;
+			refType = 4;
+		};
+		01CAFEA4FF0BDDF111CD296C = {
+			fileRef = 01CAFEA3FF0BDDF111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0259BC03FFA694BE11CD283A = {
+			children = (
+				03904DA9FF9E3F6B11CD283A,
+				03904DAAFF9E3F6B11CD283A,
+			);
+			isa = PBXGroup;
+			name = Support;
+			refType = 4;
+		};
+		0259BC04FFA694BE11CD283A = {
+			fileRef = 03904DAAFF9E3F6B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0259BC05FFA694BE11CD283A = {
+			fileRef = 03904DA9FF9E3F6B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0259BC06FFA694D511CD283A = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0259BC07FFA694E211CD283A = {
+			fileRef = 03904DAAFF9E3F6B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0259BC08FFA694E211CD283A = {
+			fileRef = 03904DA9FF9E3F6B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		034B3474FFAF7F4A11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		034B3475FFAF7F4A11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		037D0ECDFFA115C911CD283A = {
+			children = (
+				037D0ECEFFA115C911CD283A,
+				2BC07DF8FFE9A42411CD296C,
+			);
+			isa = PBXGroup;
+			name = Test;
+			path = "";
+			refType = 2;
+		};
+		037D0ECEFFA115C911CD283A = {
+			isa = PBXFileReference;
+			name = AZNTest.cpp;
+			path = tests/AZNTest.cpp;
+			refType = 4;
+		};
+		037D0ECFFFA115C911CD283A = {
+			isa = PBXExecutableFileReference;
+			path = AZNTest;
+			refType = 3;
+		};
+		037D0ED2FFA115C911CD283A = {
+			buildPhases = (
+				037D0ED3FFA115C911CD283A,
+				037D0ED4FFA115C911CD283A,
+				037D0ED5FFA115C911CD283A,
+				037D0ED6FFA115C911CD283A,
+			);
+			buildSettings = {
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "-lstdc++";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = AZNTest;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXToolTarget;
+			name = AZNTest;
+			productName = AZNTest;
+			productReference = 037D0ECFFFA115C911CD283A;
+			shouldUseHeadermap = 0;
+		};
+		037D0ED3FFA115C911CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0259BC04FFA694BE11CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		037D0ED4FFA115C911CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				037D0ED9FFA1166911CD283A,
+				0259BC05FFA694BE11CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		037D0ED5FFA115C911CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0259BC06FFA694D511CD283A,
+				18FB4D97FFA7B7D311CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		037D0ED6FFA115C911CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		037D0ED9FFA1166911CD283A = {
+			fileRef = 037D0ECEFFA115C911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		03904DA9FF9E3F6B11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationEngine.cpp;
+			refType = 4;
+		};
+		03904DAAFF9E3F6B11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationEngine.h;
+			refType = 4;
+		};
+		03A49624FEC1F50311CD283A = {
+			isa = PBXFileReference;
+			path = Makefile;
+			refType = 4;
+		};
+		03A49625FEC1F5B611CD283A = {
+			isa = PBXTargetDependency;
+			target = 00F9D6B9FEA504D511CD296C;
+		};
+		03D6E7B8FF16DE8A11CD283A = {
+			isa = PBXFileReference;
+			path = SecurityServerClient.h;
+			refType = 4;
+		};
+		03D6E7B9FF16DE8A11CD283A = {
+			fileRef = 03D6E7B8FF16DE8A11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		03D6E7BAFF16DF7511CD283A = {
+			isa = PBXFileReference;
+			name = SecurityYarrowClient.h;
+			path = MacYarrow/YarrowClient/SecurityYarrowClient.h;
+			refType = 4;
+		};
+		03D6E7BBFF16DF7511CD283A = {
+			fileRef = 03D6E7BAFF16DF7511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		03F9A9EFFF0D135811CD296C = {
+			isa = PBXTargetDependency;
+			target = 111A0B05FE757C9E11CD296C;
+		};
+		03F9B681FF3B345D11CD296C = {
+			isa = PBXFrameworkReference;
+			name = AppKit.framework;
+			path = /System/Library/Frameworks/AppKit.framework;
+			refType = 0;
+		};
+		03F9B682FF3B345D11CD296C = {
+			isa = PBXFrameworkReference;
+			name = Foundation.framework;
+			path = /System/Library/Frameworks/Foundation.framework;
+			refType = 0;
+		};
+		04E61BF8FFC0C70811CD296C = {
+			isa = PBXFileReference;
+			path = testclient.h;
+			refType = 4;
+		};
+		04E61BF9FFC0C70811CD296C = {
+			isa = PBXFileReference;
+			path = testclient.cpp;
+			refType = 4;
+		};
+		04E61BFAFFC0C70811CD296C = {
+			isa = PBXFileReference;
+			path = testacls.cpp;
+			refType = 4;
+		};
+		04E61BFBFFC0C70811CD296C = {
+			isa = PBXFileReference;
+			path = testauth.cpp;
+			refType = 4;
+		};
+		04E61BFCFFC0C70811CD296C = {
+			isa = PBXFileReference;
+			path = testblobs.cpp;
+			refType = 4;
+		};
+		04E61BFDFFC0C70811CD296C = {
+			isa = PBXFileReference;
+			path = testcrypto.cpp;
+			refType = 4;
+		};
+		04E61BFEFFC0C70811CD296C = {
+			isa = PBXFileReference;
+			path = testutils.h;
+			refType = 4;
+		};
+		04E61BFFFFC0C70811CD296C = {
+			isa = PBXFileReference;
+			path = testutils.cpp;
+			refType = 4;
+		};
+		04E61C00FFC0C70811CD296C = {
+			fileRef = 04E61BF8FFC0C70811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E61C01FFC0C70811CD296C = {
+			fileRef = 04E61BFEFFC0C70811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E61C02FFC0C70811CD296C = {
+			fileRef = 04E61BFAFFC0C70811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E61C03FFC0C70811CD296C = {
+			fileRef = 04E61BFBFFC0C70811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E61C04FFC0C70811CD296C = {
+			fileRef = 04E61BFCFFC0C70811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E61C05FFC0C70811CD296C = {
+			fileRef = 04E61BF9FFC0C70811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E61C06FFC0C70811CD296C = {
+			fileRef = 04E61BFDFFC0C70811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		04E61C07FFC0C70811CD296C = {
+			fileRef = 04E61BFFFFC0C70811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0658E17AFE796F8C11CD296C = {
+			isa = PBXFileReference;
+			path = server.h;
+			refType = 4;
+		};
+		0658E17BFE796F8C11CD296C = {
+			fileRef = 0658E17AFE796F8C11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0658E17CFE796FE311CD296C = {
+			isa = PBXFileReference;
+			path = server.cpp;
+			refType = 4;
+		};
+		0658E17DFE796FE311CD296C = {
+			fileRef = 0658E17CFE796FE311CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		074E9B2AFF25311211CD296C = {
+			children = (
+				074E9B2BFF2531C011CD296C,
+				074E9B2CFF2531C011CD296C,
+			);
+			isa = PBXGroup;
+			name = "Temporary Crap";
+			refType = 4;
+		};
+		074E9B2BFF2531C011CD296C = {
+			isa = PBXFileReference;
+			path = cfnotifier.h;
+			refType = 4;
+		};
+		074E9B2CFF2531C011CD296C = {
+			isa = PBXFileReference;
+			path = cfnotifier.cpp;
+			refType = 4;
+		};
+		074E9B2DFF2531C011CD296C = {
+			fileRef = 074E9B2BFF2531C011CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		074E9B2EFF2531C011CD296C = {
+			fileRef = 074E9B2CFF2531C011CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0B5432CFFFB3A6347F000001 = {
+			isa = PBXFileReference;
+			path = agentquery.cpp;
+			refType = 4;
+		};
+		0B5432D0FFB3A6347F000001 = {
+			isa = PBXFileReference;
+			path = agentquery.h;
+			refType = 4;
+		};
+		0B5432D1FFB3A6347F000001 = {
+			fileRef = 0B5432D0FFB3A6347F000001;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0B5432D2FFB3A6347F000001 = {
+			fileRef = 0B5432CFFFB3A6347F000001;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0F409611FE746BD111CD296C = {
+			buildStyles = (
+				034B3474FFAF7F4A11CD296C,
+				034B3475FFAF7F4A11CD296C,
+			);
+			isa = PBXProject;
+			mainGroup = 0F409612FE746BD111CD296C;
+			projectDirPath = .;
+			targets = (
+				111A0B05FE757C9E11CD296C,
+				0F409629FE746BD111CD296C,
+				00F9D6B9FEA504D511CD296C,
+				1379BD97FF9BA26811CD283A,
+				014A688BFFE94D9411CD296C,
+				0140AD5CFFA8EBF911CD296C,
+				0140AD74FFA9002E11CD296C,
+				5DF1AE65FE88150D11CD296C,
+				00C95903FF092949D0A17CE7,
+				00C9590CFF0929F1D0A17CE7,
+				00C95911FF0929F1D0A17CE7,
+				00C9591DFF092AA8D0A17CE7,
+				00C9591EFF092AA8D0A17CE7,
+				00C95923FF092AA8D0A17CE7,
+				01CAFEA2FF0BDAF611CD296C,
+				00C95916FF0929F1D0A17CE7,
+				111A0B65FE75A7A511CD296C,
+				037D0ED2FFA115C911CD283A,
+				2BC07DF2FFE9A3DE11CD296C,
+			);
+		};
+		0F409612FE746BD111CD296C = {
+			children = (
+				111A0B70FE75A89D11CD296C,
+				111A0B71FE75A89D11CD296C,
+				1379BD9DFF9BA29E11CD283A,
+				0140AD51FFA8EA2311CD296C,
+				111A0AE4FE75767411CD296C,
+				00C958F7FF092883D0A17CE7,
+				111A0B72FE75A89D11CD296C,
+				01101223FF0D0DE311CD296C,
+				0F409625FE746BD111CD296C,
+				00F9D6CDFEA5065511CD296C,
+			);
+			isa = PBXGroup;
+			name = SecurityServer;
+			refType = 4;
+		};
+		0F409625FE746BD111CD296C = {
+			children = (
+				01621B35FF09357FD0A17CE7,
+				0F409627FE746BD111CD296C,
+				348D2E5AFE81B60B11CD296C,
+				01CAFEA3FF0BDDF111CD296C,
+				03F9B681FF3B345D11CD296C,
+				03F9B682FF3B345D11CD296C,
+			);
+			isa = PBXGroup;
+			name = Frameworks;
+			path = "";
+			refType = 3;
+		};
+		0F409627FE746BD111CD296C = {
+			isa = PBXFrameworkReference;
+			path = cdsa.framework;
+			refType = 4;
+		};
+		0F409629FE746BD111CD296C = {
+			buildPhases = (
+				0F40962AFE746BD111CD296C,
+				0F409633FE746BD111CD296C,
+				0F40963CFE746BD111CD296C,
+				0F409640FE746BD111CD296C,
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"";
+				INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
+				LIBRARY_SEARCH_PATHS = "\"$(SYMROOT)\"";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-Wno-unused -DSAFER -DDEBUGDUMP -DDatabase=XDatabase";
+				OTHER_LDFLAGS = "-lstdc++ -lYarrowServer";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = SecurityServer;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-unused -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				03A49625FEC1F5B611CD283A,
+				0140AD5BFFA8EBF911CD296C,
+				51C703C7FF1E685211CD283A,
+				6CC434E0FF09B06111CD283A,
+			);
+			isa = PBXToolTarget;
+			name = SecurityServer;
+			productInstallPath = "$(SYSTEM_CORE_SERVICES_DIR)";
+			productName = SecurityServer;
+			productReference = 011B80DFFF140C9311CD283A;
+			shouldUseHeadermap = 0;
+		};
+		0F40962AFE746BD111CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				5DF1AEBBFE88284211CD296C,
+				0F409646FE746C5811CD296C,
+				111A0B28FE758EB611CD296C,
+				0658E17BFE796F8C11CD296C,
+				5DF1AEB5FE88242A11CD296C,
+				5DF1AECBFE8853E711CD296C,
+				1FBB80EEFE90442611CD296C,
+				271A278DFEAE7AB511CD296C,
+				00DFB0D4FEB79FB211CD296C,
+				00FDF005FEDF19F511CD296C,
+				1EA3AEBEFEEEFDE011CD296C,
+				074E9B2DFF2531C011CD296C,
+				128BEC68FF26113211CD296C,
+				0259BC07FFA694E211CD283A,
+				1F41CF42FFA695FC11CD296C,
+				0B5432D1FFB3A6347F000001,
+				0159DF1FFFBB405111CD296C,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0F409633FE746BD111CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				128BEC69FF26113211CD296C,
+				111A0B3FFE75909811CD296C,
+				0658E17DFE796FE311CD296C,
+				348D2F39FE87F27111CD296C,
+				5DF1AEB6FE88242A11CD296C,
+				5DF1AEBDFE88284211CD296C,
+				5DF1AECCFE8853E711CD296C,
+				00EFF5BCFE93EA0D11CD296C,
+				271A278EFEAE7AB511CD296C,
+				00DFB0D5FEB79FB211CD296C,
+				00FDF006FEDF19F511CD296C,
+				1EA3AEBFFEEEFDE011CD296C,
+				074E9B2EFF2531C011CD296C,
+				0259BC08FFA694E211CD283A,
+				1F41CF43FFA695FC11CD296C,
+				0B5432D2FFB3A6347F000001,
+				0159DF20FFBB405111CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0F40963CFE746BD111CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				348D2E5BFE81B60B11CD296C,
+				0F40963EFE746BD111CD296C,
+				01CAFEA4FF0BDDF111CD296C,
+				3054CB26FF1D38CA11CD296C,
+				0140AD54FFA8EB2311CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0F40963EFE746BD111CD296C = {
+			fileRef = 0F409627FE746BD111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		0F409640FE746BD111CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0F409645FE746C5811CD296C = {
+			isa = PBXFileReference;
+			path = securityserver.h;
+			refType = 4;
+		};
+		0F409646FE746C5811CD296C = {
+			fileRef = 0F409645FE746C5811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		111A0AE4FE75767411CD296C = {
+			children = (
+				01157F48FE7700BF11CD296C,
+				1FBB80EDFE90442611CD296C,
+				0140AD64FFA8ECBF11CD296C,
+				0140AD65FFA8EE5711CD296C,
+				5DF1AE7AFE881A5C11CD296C,
+				1C12ABCCFEC8E61B11CD296C,
+				03A49624FEC1F50311CD283A,
+			);
+			isa = PBXGroup;
+			name = MIG;
+			path = "";
+			refType = 4;
+		};
+		111A0B05FE757C9E11CD296C = {
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = All;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				01692087FF9CF5BB11CD296C,
+				014A689AFFE981FA11CD296C,
+				0140AD6FFFA8FC4611CD296C,
+				0140AD73FFA9002E11CD296C,
+				111A0BDDFE75C06B11CD296C,
+				01CAFEA1FF0BDAF611CD296C,
+			);
+			isa = PBXAggregateTarget;
+			name = All;
+			productInstallPath = /;
+			productName = All;
+			shouldUseHeadermap = 0;
+		};
+		111A0B25FE758EB611CD296C = {
+			isa = PBXFileReference;
+			path = ucsp.h;
+			refType = 4;
+		};
+		111A0B28FE758EB611CD296C = {
+			fileRef = 111A0B25FE758EB611CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		111A0B3EFE75909811CD296C = {
+			isa = PBXFileReference;
+			path = ucspServer.cpp;
+			refType = 4;
+		};
+		111A0B3FFE75909811CD296C = {
+			fileRef = 111A0B3EFE75909811CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		111A0B65FE75A7A511CD296C = {
+			buildPhases = (
+				111A0B67FE75A7A511CD296C,
+				111A0B68FE75A7A511CD296C,
+				111A0B6AFE75A7A511CD296C,
+				111A0B6BFE75A7A511CD296C,
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"";
+				LIBRARY_SEARCH_PATHS = "\"$(SYMROOT)\"";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-UTARGET_CARBON -DSAFER";
+				OTHER_LDFLAGS = "-lstdc++";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = SSTester;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-unused -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				03F9A9EFFF0D135811CD296C,
+			);
+			isa = PBXToolTarget;
+			name = SSTester;
+			productName = SSTester;
+			productReference = 011B80DDFF140C9311CD283A;
+			shouldUseHeadermap = 0;
+		};
+		111A0B67FE75A7A511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				04E61C00FFC0C70811CD296C,
+				04E61C01FFC0C70811CD296C,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		111A0B68FE75A7A511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				04E61C02FFC0C70811CD296C,
+				04E61C03FFC0C70811CD296C,
+				04E61C04FFC0C70811CD296C,
+				04E61C05FFC0C70811CD296C,
+				04E61C06FFC0C70811CD296C,
+				04E61C07FFC0C70811CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		111A0B6AFE75A7A511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				00EFF5EBFE95419011CD296C,
+				00EFF5ECFE95419011CD296C,
+				01C17CFBFF16D9FF11CD283A,
+				0140AD57FFA8EB2311CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		111A0B6BFE75A7A511CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		111A0B70FE75A89D11CD296C = {
+			children = (
+				348D2F38FE87F27111CD296C,
+				0F409645FE746C5811CD296C,
+				00EFF5BBFE93EA0D11CD296C,
+				0159DF1CFFBB405111CD296C,
+				0658E17AFE796F8C11CD296C,
+				0658E17CFE796FE311CD296C,
+				5DF1AEB7FE88284211CD296C,
+				5DF1AEB8FE88284211CD296C,
+				5DF1AEC9FE8853E711CD296C,
+				5DF1AECAFE8853E711CD296C,
+				00DFB0D2FEB79FB211CD296C,
+				00DFB0D3FEB79FB211CD296C,
+				1F41CF3FFFA695FC11CD296C,
+				1F41CF3EFFA695FC11CD296C,
+				271A278CFEAE7AB511CD296C,
+				271A278BFEAE7AB511CD296C,
+				0B5432D0FFB3A6347F000001,
+				0B5432CFFFB3A6347F000001,
+				128BEC67FF26113211CD296C,
+				128BEC66FF26113211CD296C,
+				1EA3AEBBFEEEFDE011CD296C,
+				074E9B2AFF25311211CD296C,
+			);
+			isa = PBXGroup;
+			name = SecurityServer;
+			path = "";
+			refType = 4;
+		};
+		111A0B71FE75A89D11CD296C = {
+			children = (
+				03D6E7B8FF16DE8A11CD283A,
+				111A0B82FE75AA7411CD296C,
+				111A0B84FE75AAD211CD296C,
+				4D433F0DFE9CF5B811CD296C,
+				4D433F0EFE9CF5B811CD296C,
+			);
+			isa = PBXGroup;
+			name = "SecurityServer Client";
+			path = "";
+			refType = 4;
+		};
+		111A0B72FE75A89D11CD296C = {
+			children = (
+				04E61BF8FFC0C70811CD296C,
+				04E61BF9FFC0C70811CD296C,
+				04E61BFAFFC0C70811CD296C,
+				04E61BFBFFC0C70811CD296C,
+				04E61BFCFFC0C70811CD296C,
+				04E61BFDFFC0C70811CD296C,
+				04E61BFEFFC0C70811CD296C,
+				04E61BFFFFC0C70811CD296C,
+			);
+			isa = PBXGroup;
+			name = SSTester;
+			path = tests;
+			refType = 2;
+		};
+		111A0B73FE75A89D11CD296C = {
+			isa = PBXFileReference;
+			path = ucspUser.cpp;
+			refType = 4;
+		};
+		111A0B82FE75AA7411CD296C = {
+			isa = PBXFileReference;
+			path = ssclient.h;
+			refType = 4;
+		};
+		111A0B84FE75AAD211CD296C = {
+			isa = PBXFileReference;
+			path = ssclient.cpp;
+			refType = 4;
+		};
+		111A0BDDFE75C06B11CD296C = {
+			isa = PBXTargetDependency;
+			target = 0F409629FE746BD111CD296C;
+		};
+		128BEC66FF26113211CD296C = {
+			isa = PBXFileReference;
+			path = dbcrypto.cpp;
+			refType = 4;
+		};
+		128BEC67FF26113211CD296C = {
+			isa = PBXFileReference;
+			path = dbcrypto.h;
+			refType = 4;
+		};
+		128BEC68FF26113211CD296C = {
+			fileRef = 128BEC67FF26113211CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		128BEC69FF26113211CD296C = {
+			fileRef = 128BEC66FF26113211CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1379BD96FF9BA26811CD283A = {
+			isa = PBXFrameworkReference;
+			path = Authorization.framework;
+			refType = 3;
+		};
+		1379BD97FF9BA26811CD283A = {
+			buildPhases = (
+				1379BD98FF9BA26811CD283A,
+				1379BD99FF9BA26811CD283A,
+				1379BD9AFF9BA26811CD283A,
+				1379BD9BFF9BA26811CD283A,
+				1379BD9CFF9BA26811CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SYMROOT)/include\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "-DTRAMPOLINE=\\\\\\\"$(SYSTEM_CORE_SERVICES_DIR)/AuthorizationTrampoline\\\\\\\"";
+				OTHER_LDFLAGS = "-lstdc++";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = Authorization;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				1E3C053CFFA90CBA11CD283A,
+				01692086FF9CE7A811CD296C,
+			);
+			isa = PBXFrameworkTarget;
+			name = Authorization;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = Authorization;
+			productReference = 1379BD96FF9BA26811CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string></string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string></string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 0;
+		};
+		1379BD98FF9BA26811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				1379BDA0FF9BA29E11CD283A,
+				1379BDA3FF9BA30D11CD283A,
+				144210EDFF9BD62E11CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		1379BD99FF9BA26811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		1379BD9AFF9BA26811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				1379BDA1FF9BA29E11CD283A,
+				014A6896FFE9508C11CD296C,
+				014A6899FFE9535811CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		1379BD9BFF9BA26811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01692084FF9CE78611CD296C,
+				01692085FF9CE78611CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		1379BD9CFF9BA26811CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		1379BD9DFF9BA29E11CD283A = {
+			children = (
+				1379BD9EFF9BA29E11CD283A,
+				1379BD9FFF9BA29E11CD283A,
+				144210ECFF9BD62E11CD283A,
+				1379BDA2FF9BA30D11CD283A,
+				014A6888FFE94D9411CD296C,
+				0259BC03FFA694BE11CD283A,
+				037D0ECDFFA115C911CD283A,
+			);
+			isa = PBXGroup;
+			path = Authorization;
+			refType = 4;
+		};
+		1379BD9EFF9BA29E11CD283A = {
+			isa = PBXFileReference;
+			path = Authorization.cpp;
+			refType = 4;
+		};
+		1379BD9FFF9BA29E11CD283A = {
+			isa = PBXFileReference;
+			path = Authorization.h;
+			refType = 4;
+		};
+		1379BDA0FF9BA29E11CD283A = {
+			fileRef = 1379BD9FFF9BA29E11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1379BDA1FF9BA29E11CD283A = {
+			fileRef = 1379BD9EFF9BA29E11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1379BDA2FF9BA30D11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationWalkers.h;
+			refType = 4;
+		};
+		1379BDA3FF9BA30D11CD283A = {
+			fileRef = 1379BDA2FF9BA30D11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		144210ECFF9BD62E11CD283A = {
+			isa = PBXFileReference;
+			path = AuthorizationTags.h;
+			refType = 4;
+		};
+		144210EDFF9BD62E11CD283A = {
+			fileRef = 144210ECFF9BD62E11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		16732091FF32431411CD296C = {
+			children = (
+				16732092FF32431411CD296C,
+				16732093FF32431411CD296C,
+			);
+			isa = PBXGroup;
+			name = "Startup Files";
+			path = StartupItems;
+			refType = 2;
+		};
+		16732092FF32431411CD296C = {
+			isa = PBXFileReference;
+			path = SecurityServer;
+			refType = 4;
+		};
+		16732093FF32431411CD296C = {
+			isa = PBXFileReference;
+			path = StartupParameters.plist;
+			refType = 4;
+		};
+		18FB4D97FFA7B7D311CD283A = {
+			fileRef = 01CAFEA3FF0BDDF111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1C12ABCCFEC8E61B11CD296C = {
+			children = (
+				111A0B25FE758EB611CD296C,
+				0140AD68FFA8EEA811CD296C,
+			);
+			isa = PBXGroup;
+			name = "Generated Includes";
+			path = include;
+			refType = 3;
+		};
+		1E3C053CFFA90CBA11CD283A = {
+			isa = PBXTargetDependency;
+			target = 0140AD5CFFA8EBF911CD296C;
+		};
+		1E3C053DFFA90CBA11CD283A = {
+			isa = PBXTargetDependency;
+			target = 5DF1AE65FE88150D11CD296C;
+		};
+		1EA3AEBBFEEEFDE011CD296C = {
+			children = (
+				1EA3AEBDFEEEFDE011CD296C,
+				1EA3AEBCFEEEFDE011CD296C,
+			);
+			isa = PBXGroup;
+			name = "Acl Subjects";
+			refType = 4;
+		};
+		1EA3AEBCFEEEFDE011CD296C = {
+			isa = PBXFileReference;
+			path = acl_keychain.cpp;
+			refType = 4;
+		};
+		1EA3AEBDFEEEFDE011CD296C = {
+			isa = PBXFileReference;
+			path = acl_keychain.h;
+			refType = 4;
+		};
+		1EA3AEBEFEEEFDE011CD296C = {
+			fileRef = 1EA3AEBDFEEEFDE011CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1EA3AEBFFEEEFDE011CD296C = {
+			fileRef = 1EA3AEBCFEEEFDE011CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1F41CF3EFFA695FC11CD296C = {
+			isa = PBXFileReference;
+			path = authority.cpp;
+			refType = 4;
+		};
+		1F41CF3FFFA695FC11CD296C = {
+			isa = PBXFileReference;
+			path = authority.h;
+			refType = 4;
+		};
+		1F41CF42FFA695FC11CD296C = {
+			fileRef = 1F41CF3FFFA695FC11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1F41CF43FFA695FC11CD296C = {
+			fileRef = 1F41CF3EFFA695FC11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1FBB80EDFE90442611CD296C = {
+			isa = PBXFileReference;
+			path = ucsp_types.h;
+			refType = 4;
+		};
+		1FBB80EEFE90442611CD296C = {
+			fileRef = 1FBB80EDFE90442611CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		271A278BFEAE7AB511CD296C = {
+			isa = PBXFileReference;
+			path = ssblob.cpp;
+			refType = 4;
+		};
+		271A278CFEAE7AB511CD296C = {
+			isa = PBXFileReference;
+			path = ssblob.h;
+			refType = 4;
+		};
+		271A278DFEAE7AB511CD296C = {
+			fileRef = 271A278CFEAE7AB511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		271A278EFEAE7AB511CD296C = {
+			fileRef = 271A278BFEAE7AB511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		2BC07DF1FFE9A3DE11CD296C = {
+			isa = PBXExecutableFileReference;
+			path = ExecTest;
+			refType = 3;
+		};
+		2BC07DF2FFE9A3DE11CD296C = {
+			buildPhases = (
+				2BC07DF3FFE9A3DE11CD296C,
+				2BC07DF4FFE9A3DE11CD296C,
+				2BC07DF5FFE9A3DE11CD296C,
+				2BC07DF6FFE9A3DE11CD296C,
+			);
+			buildSettings = {
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = ExecTest;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				2BC07DFCFFE9A4AE11CD296C,
+				2BC07DFAFFE9A48411CD296C,
+				2BC07DFBFFE9A48411CD296C,
+			);
+			isa = PBXToolTarget;
+			name = ExecTest;
+			productInstallPath = /usr/local/bin;
+			productName = ExecTest;
+			productReference = 2BC07DF1FFE9A3DE11CD296C;
+			shouldUseHeadermap = 0;
+		};
+		2BC07DF3FFE9A3DE11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		2BC07DF4FFE9A3DE11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				2BC07DF9FFE9A42411CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		2BC07DF5FFE9A3DE11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				2BC07DFDFFE9A4AE11CD296C,
+				2BC07DFEFFE9A4AE11CD296C,
+				2BC07DFFFFE9A4AE11CD296C,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		2BC07DF6FFE9A3DE11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		2BC07DF8FFE9A42411CD296C = {
+			isa = PBXFileReference;
+			name = exectest.cpp;
+			path = tests/exectest.cpp;
+			refType = 4;
+		};
+		2BC07DF9FFE9A42411CD296C = {
+			fileRef = 2BC07DF8FFE9A42411CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		2BC07DFAFFE9A48411CD296C = {
+			isa = PBXTargetDependency;
+			target = 1379BD97FF9BA26811CD283A;
+		};
+		2BC07DFBFFE9A48411CD296C = {
+			isa = PBXTargetDependency;
+			target = 014A688BFFE94D9411CD296C;
+		};
+		2BC07DFCFFE9A4AE11CD296C = {
+			isa = PBXTargetDependency;
+			target = 0F409629FE746BD111CD296C;
+		};
+		2BC07DFDFFE9A4AE11CD296C = {
+			fileRef = 1379BD96FF9BA26811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		2BC07DFEFFE9A4AE11CD296C = {
+			fileRef = 01621B35FF09357FD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		2BC07DFFFFE9A4AE11CD296C = {
+			fileRef = 011B80E4FF140C9311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		3054CB26FF1D38CA11CD296C = {
+			fileRef = 011B80E0FF140C9311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		3382A64DFFEAABFA11CD296C = {
+			isa = PBXTargetDependency;
+			target = 014A688BFFE94D9411CD296C;
+		};
+		348D2E5AFE81B60B11CD296C = {
+			isa = PBXFrameworkReference;
+			path = cdsa_client.framework;
+			refType = 4;
+		};
+		348D2E5BFE81B60B11CD296C = {
+			fileRef = 348D2E5AFE81B60B11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		348D2F38FE87F27111CD296C = {
+			isa = PBXFileReference;
+			path = main.cpp;
+			refType = 4;
+		};
+		348D2F39FE87F27111CD296C = {
+			fileRef = 348D2F38FE87F27111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		4D433F0DFE9CF5B811CD296C = {
+			isa = PBXFileReference;
+			path = sstransit.h;
+			refType = 4;
+		};
+		4D433F0EFE9CF5B811CD296C = {
+			isa = PBXFileReference;
+			path = sstransit.cpp;
+			refType = 4;
+		};
+		51C703C7FF1E685211CD283A = {
+			isa = PBXTargetDependency;
+			target = 00C95903FF092949D0A17CE7;
+		};
+		5DF1AE65FE88150D11CD296C = {
+			buildArgumentsString = "-f Makefile $ACTION \"SYMROOT=$(SYMROOT)\" \"SRCROOT=$(SRCROOT)\"";
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "";
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = "MIG RPC";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = "MIG RPC";
+			productInstallPath = /;
+			productName = "MIG RPC";
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 1;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		5DF1AE7AFE881A5C11CD296C = {
+			children = (
+				111A0B3EFE75909811CD296C,
+				111A0B73FE75A89D11CD296C,
+				0140AD66FFA8EEA811CD296C,
+				0140AD67FFA8EEA811CD296C,
+				01621B2AFF09328ED0A17CE7,
+			);
+			isa = PBXGroup;
+			name = "Generated Sources";
+			path = derived_src;
+			refType = 3;
+		};
+		5DF1AEB3FE88242A11CD296C = {
+			isa = PBXFileReference;
+			path = connection.h;
+			refType = 4;
+		};
+		5DF1AEB4FE88242A11CD296C = {
+			isa = PBXFileReference;
+			path = connection.cpp;
+			refType = 4;
+		};
+		5DF1AEB5FE88242A11CD296C = {
+			fileRef = 5DF1AEB3FE88242A11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5DF1AEB6FE88242A11CD296C = {
+			fileRef = 5DF1AEB4FE88242A11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5DF1AEB7FE88284211CD296C = {
+			isa = PBXFileReference;
+			path = database.h;
+			refType = 4;
+		};
+		5DF1AEB8FE88284211CD296C = {
+			isa = PBXFileReference;
+			path = database.cpp;
+			refType = 4;
+		};
+		5DF1AEBBFE88284211CD296C = {
+			fileRef = 5DF1AEB7FE88284211CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5DF1AEBDFE88284211CD296C = {
+			fileRef = 5DF1AEB8FE88284211CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5DF1AEC9FE8853E711CD296C = {
+			isa = PBXFileReference;
+			path = key.h;
+			refType = 4;
+		};
+		5DF1AECAFE8853E711CD296C = {
+			isa = PBXFileReference;
+			path = key.cpp;
+			refType = 4;
+		};
+		5DF1AECBFE8853E711CD296C = {
+			fileRef = 5DF1AEC9FE8853E711CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		5DF1AECCFE8853E711CD296C = {
+			fileRef = 5DF1AECAFE8853E711CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		6CC434E0FF09B06111CD283A = {
+			isa = PBXTargetDependency;
+			target = 00C9590CFF0929F1D0A17CE7;
+		};
+		6CC434E1FF09B18B11CD283A = {
+			isa = PBXFileReference;
+			path = yarrowMigTypes.h;
+			refType = 4;
+		};
+		6CC434E2FF09B18C11CD283A = {
+			fileRef = 6CC434E1FF09B18B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+	};
+	rootObject = 0F409611FE746BD111CD296C;
+}
diff --git a/SecurityServer/SecurityServerClient.h b/SecurityServer/SecurityServerClient.h
new file mode 100644
index 00000000..7558af7b
--- /dev/null
+++ b/SecurityServer/SecurityServerClient.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+
+#ifndef __SECURITYSERVERCLIENT_SECURITYSERVERCLIENT_H__
+#define __SECURITYSERVERCLIENT_SECURITYSERVERCLIENT_H__     1
+
+#include <Security/ssclient.h>
+
+#endif  /* __SECURITYSERVERCLIENT_SECURITYSERVERCLIENT_H__ */
diff --git a/SecurityServer/SettingsDialog/English.lproj/InfoPlist.strings b/SecurityServer/SettingsDialog/English.lproj/InfoPlist.strings
new file mode 100755
index 00000000..89c3cf81
--- /dev/null
+++ b/SecurityServer/SettingsDialog/English.lproj/InfoPlist.strings
@@ -0,0 +1,6 @@
+/* Localized versions of Info.plist keys */
+
+CFBundleName = "Security Settings";
+CFBundleShortVersionString = "Security Settings version 0.0.1d1";
+CFBundleGetInfoString = "Security Settings version 0.0.1d1, Copyright 2000, Apple Computer, Inc.";
+NSHumanReadableCopyright = "Copyright 2000,  Apple Computer, Inc.";
diff --git a/SecurityServer/SettingsDialog/English.lproj/MainMenu.nib/classes.nib b/SecurityServer/SettingsDialog/English.lproj/MainMenu.nib/classes.nib
new file mode 100755
index 0000000000000000000000000000000000000000..dae612c5aca2d0152968f8204e260723d2b406ca
GIT binary patch
literal 316
zcmb2|=3oE;Cg!)79P^tDMA$#f`zvCbcXCrhVu69RLgBe1CzLkK-DsDtuHBZ@V_5TD
z)OGVriOq-0Zv5NNT&r3CV6Vu;rBRdjg%%yE>&lH>_qgEL&c~H`d!@oQOU=7#CVsn6
z_k5Xe!|mMNwa0fHtvl#7J@cTYu&@xf*12cbiWl|#wY(ix%ha5=;XnTm+x=Ox=TfWJ
zWYr1q9|}wnincv}y?=_XukLc$xY8ffQw+W=w)(EX9oy%rUu?Sck&4L|_rFKpfA`Uw
zvxil^eDRZ&=5~A1MP{;eehOZ;>*4g<A}fWanEF2JUUoqxtX0Q+Ay@ilZef>@X+e8m
ziLYGt^H;QRi>J+-qr2_yng4!%zUIxNHM?K!x+z&Qf8_<EaJ8J-d%GCHfrCUGu>Z>V
MQ|Ph>g9ZZw0P|Om!vFvP

literal 0
HcmV?d00001

diff --git a/SecurityServer/SettingsDialog/English.lproj/MainMenu.nib/objects.nib b/SecurityServer/SettingsDialog/English.lproj/MainMenu.nib/objects.nib
new file mode 100755
index 0000000000000000000000000000000000000000..bfdd2b0cb8682bf196f43bcb1133b4282f197b0d
GIT binary patch
literal 2226
zcmV;j2u=4NiwFP!000021MOFRY#c`wpFMxYj=z#Pv_%v)qEVF+B0Ei-a4O9?E~cl}
zcH4_6pNiIdbMZEJyJl}Mw!=re*V&Z-3Cdv)@s;Wnj7XFmiI7_rq^hnWSqcLR{}rUf
zQUnMkQuB|cNFkAYyqVd%ixXV>4+x=sws&`C-n{qbz2AFpY>mBybtk*aG{(?>iu!tc
z`}gcok*e<5x38bSfqH|ts_yIEw-=s$d-{9#_4NaT+PAxJ@8d}AMgIlLWgX2{Riuw$
z{V2BA<(nMGIF0`AsBxn+J%N*1$HrR5ZMa617$Kx{BoRM2DxmR{=4dXuO2~$hgq%TM
zL9z^j@2rfR+%ZEUF}}5HBr%+Gw6Qc!IJRLPQN+&Rdxj{V=@>~2OiZK=U2_b}^gW*_
z#-}Lk+&Gdrgr}S#1E-S@5z-0@EYq>A^bSIrM-pE$@Z=7`^#aaLSY{G}HB%sO6ucrL
z?J=NKK+?LviUHf!rV$}6pjLd&6q~vIVAR2!<5(v8S)o)!B@f6&r1Q`=gbr;hlnNgI
zA&rKv$B+U7NPBh1AWo+bi1C2V&%no<gpK?w2A(jCe5108@*BXzq><Z3=H{9QHB-lF
zp9t0=INR2l;v=N#YmfKq-)IKTkHg<;1wD&$NJj=rA`N{J+3+;s8-pYz)j<>;m6b9o
zH~XFkilT_yIZs-%S;OFpVlKM)kdpWFu?px!J~;sokDM)j0yOR3FE#Z@O;3Z=G&%-P
z2lVMkJKIr~(qW757sxN}a?PLbam_sU$}dmlN%f$oL0@F_sDH-uekH6rf39vz85Wfe
z-#aJdzFw2N$we1jrDGRD{JBQ9z)}qn+_j%SbxQgb#iY7tU$k=Rq&jWo)U<IFtB$2&
zlSf^B22bnbnqjH~x{kA1RWp;SGmh0^O;<+~>X+3l)^oPuOsgrZIXN3=57Z4`APssf
z#w}>!AWU0;v~n|P2;!KS&N?{b!)LoL5h{3m@|$u4iKJ4m9(e4`S;gn$=7rw^TX(?5
z4^wA-69JD87*nF2&mq|a0JEkZdqX&foGdCF-HU;vA`w?<+sob5wzse--Q)uXyv@g5
zr8CYKI^#9iwxm+An6B#pn$yx}!e5&b)l&}zr{;(DFEm6@LD~RmF|0wdPCZ#qi)}9Q
zquUXRZofM|9@+e911K7e@}!gCJB3h0fi2O^NXb8S8q}XGMhaD!1Q0Rno?a3ViR6Fx
z!~j4<LY0s$)l7?Lv?DlS<!l`{K(5ctLGgG&OB$A3hV%PEc<q1<qp6gTuG}Y`dA|pT
zy)8ViDE^r>`<jH*x?SEmS9$Fjl#lO!zT%bnPI2&yexb;HuC%(!ZWmR!*ZEs|1zcD~
z^^>l$WhY<VvU3fl-vXW6R+Son2jiIu%XT!=iK^;X0LB@psVc+;nvzooE8tp#Qgcjm
zut2eiCjr2Y12r|f%ZKEC<jhAYAZIrQ>D}sA4_f>+dixzX+*_VsqOvj#V>9QXKg>Yw
zi}5TtF}ERs?PCVykq_ZS9Qa*_p{56uoZshFtxfKYLvpyvKOkOzdWY|BjGHNo?}WO0
zrLasoKx{lN@DepZ{@mOH17lXsQET8#1V{7BDF1S$Qb8OP-PMKz<zFCT#|(wNkf8!4
z!YXON;5fAMjAkDNe2~A=zwr!|E5pVVP9_|1BP_{4`@*Pq^Y4N0%H=%jMpd1E@%~=p
zxh%Q3v5ij~Nuf;{_t#_pC?e|upU)YN5ctjY1d3X7ST;^9{VlfE19Pt$(wWVTWq?z*
zDA^|7_h}H5<`)e!X-)E|G;&K;gt)F@!!$C+ajaIC!KloKol@@G_*KiwRQHrWlszB&
zcTSNayLq!Vk6;x__>c|db6vUI$WHK$R9{8o6^TA@(J*uYF$rgF;0h}5t~H<zk(zrY
zqI}Tup3t)F7gmF<0s%NZai2Ysvx<4aB5U}SLW|h;vHS3?N-l8nfpsGfzno*^VP2Sn
zlgQvVuj6oO$cj%R6?$`pE=TC~Wm=h~O%-})h2CDFOC`D}lD)g?wL>^Fk%p{rm0L5A
zpGLi)>k9OppS#Mdve4z9n?h(!BdO&ouM<^ye9*`*Y<|g8NFx`A_PdR*xD5}Ml{dL4
zWoyAJM}kj(mR?+<=Sy^<M6WH=TPw7!g%ZlsyR#}k5bObOsf%7%q%BSK#xnh2nXXpo
zr6qcGna-E!<>g`zy~wlW?#r4_E8M!8|L80X+lP!ael)9&PMX;E>54~tcnYl5*XPso
zFxy&{2ICgktL*ma4R}ZTVB!{^fOnhdUv!bT6Vb_idVz;YUR{0K6!0zZaNc#Z@#*bP
z(o3?r)oljGB@W+eKlbUo90skAcKr+Q(4stgO?IDX>h1MAId+h^Xz&lXjmHr%oGi9;
zuB{`95o2tydZRH-xYk>?i~cCC({f49ZJJrQ>A`8XOkg`@*%@9o_;ms*N0eXhKD%&-
zFL!A&hvTNm;9#kZFSTaJtx1mlVDc89Y!AfoY7)#}<&k>Wvf;8XWI*jUlbW3r4dXe@
z#OZ+X`Yd<*IF#mK;s%%4=3qNxn1JkH_B@YqgLO0*F7aV!^(r`O!tEhgnfGAjp6!J6
z2tSPGoHTas_Ry|{9v+Sjndu-9z&*Gy%cXBf;xs-YIu5ki;!gNC$!I#l`oGO?f1S;{
z=zHwu18i1daBn}szTl!Fd;h!apo`|%f{T8@o^a7D>wT2nfd5U{)hMex%(}L+<<GG@
zO{~pgEibW^2icP@`YBs<(GOWE!mho{R=2QAE-J9=E^^riE_#LS`4)@1$YV<`dX4Se
z&UPPXx2D(y7yXD`bkUDlkBes5c^7@36<zcbcKJIjvY+jDQ67e`7f}Ix*&RPPXz7+V
zWNR5bY4PrgLJBFQkU|P6q>w@iDWs4>3Mr(JLJBFQkU|P6r2j?wCvXo~l>jIJ0JCga
ABLDyZ

literal 0
HcmV?d00001

diff --git a/SecurityServer/SettingsDialog/SecuritySettings.icns b/SecurityServer/SettingsDialog/SecuritySettings.icns
new file mode 100755
index 0000000000000000000000000000000000000000..51efe9bb460736b422e27bd36a35671e08ea510a
GIT binary patch
literal 38637
zcmeHQ2Ut@{*Pfd~0-=Kx!HOb?y;o3F6bp(XiXsZ4fGDB@DkvoM-ivf;RumMGj-a9l
z%Gy8_D_Gavb=8eX%l*$y2pw0!?|Z)Ie;i11@04@S%$zwh^WKw*#a63*2!;P?v2~vk
zLTCxz8d~DNiv1n`cl^g8O)Kkn*MGq4aVH`PV?r(nwCA+H#khYWe+&ODcSNpQya*K`
z1axK~gwc6qnwpxLIlN2ay{QGqTbkSMIjO{DhYUm#r#&5S(r2;0e&yyOayF^e*Eck%
z=@ZuwQrQTpHR|g(@^0~_FKTSHCVl;;*89}2^<P<PYF}Bc_ngKCyt%&dYeVaOOG7Ho
zX=rIu1F49Rst=+zHgnWk3p5gh;H{Cz@SjE^Ujsz83dF4#i_eXq0D;q5U5kB_Cm}?d
z?To0RI(oXRB-{~=ymSOY!<SLq5GJm{LfBksH$)elLq{aJxq_G*5?B^uVj6d162$72
z<rjFf?go)vkl^f>jhx#y5ut8yLpOL@{;pul(TJt4NN~cbOD7IqDY>{4gIqHEy#}bC
zcS&|9ZWR4zASo{;{i0!Tv%pUnp#zI#uUR-F5_z`)6H)C}A-h-#3o%5jheK~2UXMh_
zU?34i0^ZEm`yfnS+68rzU3+9F+2?@lG@k70G<Og^2t+?Q5ky~GR`|aox+Kx;+TEMI
zRrI-ngy_NCR)+?~^!^uQ-#25IB{77EVTMGkT%2vCxtGKnW??`ft+b)=Bc$yxxU?P2
zzn8HSKuGeyApSk_$YLeGd85I<U;XeSp{2PbUc}ti!FGqo4DBWoA%qZAA<V4D|NIR1
zM_cnN*8jdB2LHY3O6&bBjw_nf=zY3Lg_qyIVGP0^98$+w+<RJW76oBfLrD2|sYHa_
z9|kZcN{%7rZ6GE>jAat=9(5Ax#bwCjsyu~ALr8mp4wxh`CCwT*{`murf2b#9gV1Hn
zy}yp*FNWdx4S2D{aU2!l9OMSCGw|{On}y*xNdm{M<Z=AjIUJ9lf#a95aa<$c33no1
zg-#r&I1LUS?*xfJpZ|hO2#8#Skmv*uUk)L07)ukN`G>Z?h-<k+2o2#NqyaA{93dzI
z9O1>`z7Tv8ai{@4Kf>pW4+wky24O{Sm{?IAlU!6+L}nVp>p7E*wm{AKuc2^FnADwM
zQYoz_l_wLJ#)by{rVh5XHJ<muX=q60w6rufw3@a~iD0A%D@KH7!sK-iO?;DzcQtRk
zyj)Ajz2xwXX(u9$ZB#k!mmPAj+Dtm9jZ=qYyqU$jYiVif($%fG8dy-jW|$kkvf5a6
zAi&Z8^5siogMOo0{g)nU$kAtW8c^d`{l*5!(2YaW7dE^8%a`T`{f5SduWDUu*vw{s
z`GVMA)L4xT4PP7TyQb@ZQTqZpzI<W9{G-oO>q@^~4Z@c%YHH0up4C|2wTtxCzCwn2
zwT4uE$kSasRy`5a*i8*;UmL!Dfk~`$NY($U|MhD_a|6@?>d0<w%eG9-4NZ+-h?!4c
zA2kB8uH{=;ta_M}TN)en8&jcyy7mx<rO&N$YD0Y!-cn!xwM!2)H9|ZQ8tYj&N57sw
zo$>`>HMEvs5u}^d>iP3IFGDJ@<z2yC4a<eE^=h3YY;NRB+@wZiWPRa&@TucX4Sag3
z^$mn*U)dddh{I}?4y*_-y`|G2;WV}>chgt>u6+aKTH31H@>Rc+WNjj}UT}IW-yv7i
zH;Z@3$h)-INh~P@OuZ0IY)zP-Pk@0`C=wjZw4bJ+Fu~eeH5ic<oL7=yl3(aA8-%d+
zyI}&yNXTq07Jw+EU0|A7h)P0(?CF?4qEM~nFcL&yn2>`o$sduhouk|kS<0R!5P&dk
z6K5nq8a{H>3PkopVi=-1?Qx$iGks@t@<|IRDnyZyaNNDhG8?}zk1Hj2110>CsJ!<-
z3a$;z#E`xI<waG7en@=tZT745+Gk7MqdXlv&zG|>A0(mq;_ZufEx*6GYIexo|AcF?
z6XuO1ND;5@J$d%*P0byv)8|uSO-naHPTJ`kWp^s8UX+&UIJtTo+g=>$gTw`rO0ut%
zRpj0EoRd&ou=dUdUnGHT&Ce^ikbkSr!0AekXUfCCDG)g;F)=FrEK84h`Bk;;@wi%3
zU@pGM-q^l!7Lq?48QsL%Rd{i-FA`VUW}UWJ6b(OMcjVwCzbgd?d=Yt|c~}q=2~nrG
zoi{`(8F^`gyb*=G`ap&b3klNp=2;@eh@xxjAyQzY>nRx)62eT1tq^5#$)zJyFGL=*
zFMdC)y;c<1kkHVS;*zNlx703kGQ_PdI3$SZoA2Lr^h6ZF_3jaLh@6${Du&R2lOJ3>
z5m{{Oxh*b;g6ZY>$}$mYwAXNml(n-T1d*hrX~Dywx2UR;&|4}eV<$yIrzQI;!w0r{
z4*4YdhJFle)sFyq(2upP`mtTVRX;F7KPY_tpjgY1NG^yZ<iPL;(x_ECs3bq)PTQEP
zAER_vAcznpAsW-#iK`z;CoLrXkr;(gk7}-ZTrIg9B;BKWZ21xOsOe2T%6_RwztzL5
zgZWq#r~vAr&sPt^e2~C=xPb8>4YC&?jE4Xy2ca#5@nArD&$dH{&<!yRqd8eS&*Iw-
z3PcGYM%=xsf3Y3El;gi|J9cvS9+cMY0C)L`C?;oblwaH@%De0KE}K#Atf#xb;KtZ)
zNkjzo><Lv^><bL@xe3eX?qO}oDDJYKtZ>S$dn!V)Od8^50J|yDJ%eDzy4FZ+(&Z7|
z(?!xY@*~GyR^?x|e~N@e@ot0^Y|hHJ$Mdg5S6p{JI96~j>)v0Dg~Rx<?VqGs_i_C7
zZ@h)VdBOIC)+>ov{7f}5e}5%5UTw1Q^DT$8r~eS?9D+n5Kfd*IGIzH|B=f>Wa_0;Q
z{Djueq}F{|Yc7G`I;V3ix}@LkoPKF!7y7%ucFJ%^w=;XB@d?sDmRIrDL`S-$FCms*
zK2tWeuIM<XUD8KD{Z7vloeJ6BT>b;ck9SEQ{U`oTTNF`Un(*68J#hSY#ZDQpGf-R>
z>LmRNzc+j(Y-TMwr<dZ*CdAH@oQXe@5|6|2!cG-j-GJXy<0_Xc{#pTB2k=ho-jhcr
z8pr*3Y9Ee&P(pIKIPTqn0sSWa_Y&CuLD+=Xk3;17ukiC7(q;d`vlMvufq3IAnCw?v
zv+f|ki24sELcDZaoU<6liqsSp?#7rGDY|Qq3XeRRi{on{Qb0naLk|j$P~#8E0iW>M
zyh0t`N%VGN2V7-3r1WsffQ@Z?u&^Q4nwk|vOePX@FfleZ*=BBOX<=eyuvS;+J(AwI
z)qM9srdM!KNN7l)pYs7L6N43-UL(16##V=Y!(tN?QxfCi5{@4`ksK4q+-bC0w-zbr
zZr|e^6qA$~73}NEJYai}=^A(>;pE9^kKG$qJx7DL?Q{x>IU4EjxXWan?(!vzm#kQA
zu+7#rA|*A}W&7&sPmu6#JD($Q5$@I-mrs$SyCM<BaE+D52g6RD4cWVP#iWNwXzq50
z(3l91J^Gq5K8QgXx@ZeC?n0dXIt`U-M7KB`7U_Rz(;|sLBsg^0&d|)1!+Pq%Rfx9d
za73iX-c_SQV8J)dIPk)8hc%OB$J|4-^$yXIZrin_eG!`Gj_4yc_~s<rX^#}Ti)fB}
zk3_rg&=d+pXp$?U4_p^<Dbj2<nQ|M^BCLHA{P!#rWC42NhcGb_!0m=?O}^x@W;9jt
zHzc6zkQ8aJGaw8$^^l@wbMfpx4TK5aLIUQSLz7$$m0`_?A(=o#5+){DI%Q$-^}w|X
zWX3JT5VJiQwO0eQ0>c==Ff9uc8N|0|XIM`|6!~%_pgP&-jOPY<f`kAy7$JFAM4KL3
z?zsd*SQ!#l6kVH;Vm}|W5F?R7;T<Gk?79|jsE8;cH;@30z9T)_Oo=N22I&l_+v4-N
zR%#fDY;+xo2nisEoB(}c7&RDqC{#g+So$KR@N&l)Ad|p#BuvH_o;e<i2o^{z9AR=G
zq9Dd_s&LT+rh?Z1k;5?QkWA;POvn-mqtgY^EJ}Qq16G7xLn43$4UEiUjwi|^!3e-s
zVA;F=YMcRs2?Vb~TSL5TWG-u*Go-~K`ig5uH;Q5yN#H6%BqpLr1m?Spg)~txM-<ot
z>0F7@6U44_69p-(V&BO?8WRG}Le7Y?>1xOdDhq?ML{sj%9Igp1h0!7bd4dRv-DU52
zh=n26Whf78UfseZ13JRu5Hx{QaE{{ykP^d0d8zb?r!LwIfe13pDj4h^=BAyp90ci5
z@e*hRSmFC#4xWdwXoN;F5ktT_KU9waSs@)LV9rR8Y*KJ+yBtKwL?Ti6m>QkoGLvWt
z3_%uHc@uQ$Q<94V7Qr<s645XuYJDNzVhEE+#UySZLGissr}q%;H#iuHgoOC|G7oNF
zxil!*Z84n%!eHfy0eh#I&59tX;zCnjG{7OuKPW0X_DFPqldXrN8Nhi!irXeI%EZlc
zvI5sB%r|#BWWIW$C!!hdbPR}$NjS<(6irEvKjOCEbSj-Ip+8hY#tn&%b-Q%V)513?
z`{FVGeVZMeVd$^hX1Qm-PpDsL)X~Jm<dkD4Q%@Z`6TEo@u(^fCQ5QuNosG!4SNrC9
zRkqJo6J%;;zJ135mWO9xh-*MtXhd{!Tw+}Esnk;!P9M_1O5g#6I~qUAF`@86QqI*U
z?_RyU;cck5-R7{1yN9Qzhj*;IXIT7+^vv{(WAVu+Q%|4I^3X%nn`nZv>*eDKSF)1b
zyzahyR-1F!U_Z;<%ge{x%gghKzk7Vf#q7L-!ou8(r;}69WaN5nCY7U!O1_mfRrzt*
zS5E8=seAgg^2Gj~4lV>2A1^Qen4NoL&t1&Q&do2nTy*~E*|WLX&bzLFy>LO3q@1c=
z)ZWQU2t1t^?fLleqsK+DTXx#BcAM;V_w(_Nu`_dt&$w_gJ2$VO_-fASbLp2;?VzNh
zGnzs+y;fWICOt6Pa9e16^5aL<kBXv<x4MKl@3dk0`1*u~Y+<p^oWFQ62g+V5xp?MW
zR(Zr`Xnc7nJL~w<+S<C*Xo~@gi+AKatE#NN<zwj>dGd5he1MOiuW#bkRSS=tJ%8b1
zR!(mIrQ)27^pY&c>xfKY-hIY=PLBy$gpin7SvB*%Qh|?C@Ue`XoO205e*V7EE{i7k
zpEz^weCEZRoV<e4-1FJjLrsd2fFN36#dOVN)lGPl;i`&+_0HbAfA3CJh2K8ckhqv&
ze^1{)fB(P;ciX6hl+$O@Gl=FYzI6UV@rm8VXtug{a(3BoPiyOHU%b2>tEFvsuIlll
z+Z7L=`0JWjyE!?zdj<yu!e2;e%+aJ{Cr+OQ{#kk185eUeI2IwnfFoH|FY4-QU%g`0
z4XDbye5dB&!|LkFTbUl}Yt0;7yaR#*nZW}>LL<UM0)1S3l1`q2x@YB`$-a>7bqNVF
zlP^E6t$SHl`;1jH;rY`iPoF=1TK%A^>Ry)9!p%GEz5GK%!@`b4g!;K2ve|RM(IY%2
z`gm%3MpjaGW=7Dk0;IuADSuX5_x!=b>PIzCpMxMTp4ZeodGe^L@_uC@)7WI6Pw<h*
zFn@Oko4xxTT|M2M_S*#o#vMDIe(_{>&WVVL`Dh+9=6cQZr<FJF);zC$`RdKvx9{G*
zt$Y6X$&-io@7}8{cHL?3@9S|0%0pYYIqu(Q>*yX><{Wr5<@EW4tlWf%3HeAcJpa-2
zn$n5~PoFdED6ihUe*1>`R_#^Y^M_T{cPeh*KJK~8+S>N8o2NSy${+R&jEaqoyS2+T
zD&hFqsEhfLA*1t<a6nq+!<sv{9zr9$c)_g0UcO?zR(t#U<r8R+ikmmf@~rnbyE`8M
z{vJV5@kfuw$Hqn%TRDWrCY?yVloJrBoQuR)M3-0B+`RSRVa?;G&z`@i1v&~ZU%rCB
zy2tnL|5jF3aoOF}%GSvXruu}0_;_ZV7|^+Va9?1=(WDbs&U*XG<sxan^t%u5m))s)
zP+bFbo<0Y8YHMBUB%fE8-@Z|L{q$keLw?Z-i6BBe>!^5QLPFv-x7|LWv2iD^CwSV^
za*;&%^~yUXH}Bl5d{F(6=#OX5SkGB6Mm>LCbF-|xr2M?Ig@aE-9287QOagm!{A5bP
zg#+6?10tg@lzaG_<swasqqpvsl-#VieeZtNg9i^Efh13!Jbn6%`(IO0Tz<7A&DUg~
zd)U#WWFT<jWJ*$uAIp)o*~r~DA}Ig5wVzflV%VOos3<HcyIJwu?Yqn>N_F+aM~_%F
z=n3<&@{^j1!fQnpnckbNoI?}9N*#|s;^pM%<mwm2G~Vmt8xVH=yrq*;E|T4seXF>j
zr1VDlt%}=s?%uBgd4SNvN6s}PtIM*l=D*0_yJ?qmXk6?Oufq<`?!gg}(ZT-ayAHYd
zx}L4@I=F?Ni=^xe%QEvWmz0#2->l$LsjRAGKESFUu&PJgE51;i`~2eGb=!8^+S<E$
z2ge)<_H}V#?cKJ+?vT5uOYxOm2dCyCS*J@k3iAq!uasQB!J~5L?!Ei>D=S%5Bkz}G
zXXlkY@iWsgFgxHK9_jDy?&2L1li+D?x$gke>)^4Q3Hvq*=OHQQqHDz$^DY%%zFKmP
zOXauUZnN&7d(68dZWdn1%YK(>WMpW%``{s#r+-xJ(P%GES98m~c8(s0gRWh1w;G?1
zB%KRO^3$^O3X6)bfGDM9<>j}S71(bT%-=?q7iZ+;<vuv1r*B}m<B)$`Y>2<Jt5@)e
z1A2Sy4!JSi3T~XYU&6>o()Q<yFQ=zx=j8(x5Cv)kWSBQc-73Fcn3<KERRYG}&}91_
z2PZc-zo?Y+IR&L5tLz+HSOJ-(*8*0{7a%d4r2OK7v*%#S$iD<ct}si+TrVxXaijD~
zUPe~Vg{vj$P6q2X7+N}poysaKDk>~2xDsQu-_a#B?|NSBb|rEF65kblCco(7ne+?9
zByj0caWV7C=&L1HuM}pbW#pVIsf%>ow9&-!pnppCrJ|xsg@u=ju16a0cZn{zTAJ#<
zfm(>f41$lR<`ib9pFNie9gtVxd`Y!1Kl}W-jI50OKc58c+O=oz0k??LxkZ;RU%3jE
zyme%)V`65}<?H$3R$@?I$?M$lQy24dGtZn&&$y6vk(oU%D>LK#`Hal0^BFatZhKqV
z?6Y<9gCeEnw{DbVo=uE!Gzm}3F1mKDG$Ul=ltJ?OX#SqK)MF{>S$R1b8R_X~)6Sne
zn~|Q8nVoeZJ^#07wXu8c_8&Ox8FRk4wCF-gu$Pmqxzz#Bqi1poj^~wK%SrdMT)z;k
z;PwOli7Clx7jkoQb1o2tv$L|ZE@q?_yvVzH%;w;s!z?$jTH$^y&%l_oS*(2?fl(>x
zg_+Fw8>MAs*G?QZEkKN6wh2io$;VEBiO*(UoS2!JaW3s-O5wAFy}r!Dj{Emm?X)`R
z5qUEE`tAD<Z!y8<B%H}ADscA5yj6OmqAbE?LmrwhW9Skd6&;t5l9ZSjmq5H7J8>c-
z|K_nBmNvW1w;65S#fr`-t%Nz|-rcHl51a6Ww2ZuxQV-X-n`O7|R2^|P0pl^voD~*&
z`e=}cZ(>r6Yjjd#{P~;bkHnvfx6xc-uxjH0C-3O9#kcNNR#jJ3Rz9row~arM!t^Qo
zE!Hix_;yillD_)vTr}UpJH{tDE6&r=H97f^U3_Bvsau)hCaa8emFP+n)He78#im`p
z0~61qikgSjk1GSLgZ=jF=;htZV}_l5km$Tfk&%bwtb!u~Bi-$H8athgG2NMv7<)0(
zS9hSGAlVrWUl$mcd?G0zx9)Y`##^<IpFQ^5YJbRJ)yj}NxBY^m?wt!Urovb;+H2)v
zZ?Vl#o0aOYWmjT+?1hp;1KrVZ{g?>7r7ITOy!q%oGVPD2wNHY#*jR1YV(wI2dD1Ps
z=(h;>Aq7ZERnN}a!bERHOu{zPL&s0W9WM_W1BDGv?N`>=U~K-BZKD?avF^?D$gLI@
zI}UjVpS*wFCH#0zT*UH1B)R+0PGbY@U8h+l+x;r?B2E{Ds=Fhl%~?BU8SmO@a-VIh
z=JL;9f4z#{W_8dzC@L<xyfVxu>TW@}t!O@yGCW|vWAo}I{wK}0?@E4uaO>d!$H`E7
z+tuCktoK+Mma-jGJU<qkjdioObBOYbj0wwrnB@#_LBX@2^m<F%orcTTr-W=VbH03g
z{Wz7mGsK|up1Zbl_U+xVER7wnW>dXqi@wdK1q)n!!=l4e?%#0>N_=|qh-E$!o3U=U
z<vJ~g(>B{Ij=YInHozN=*in91eV?_N);acBwQUdV7AejiB_+N&AoNIN_>G!akBEx0
zK<|lpNKAF1v6-$;OuUKN!L&D)v#3yXeb_E7o4poGGTCRwn%6NG3Nq*<G{x3GJUk@x
z@nxs5%;%Be7Wqg-YK_sdU8mf(ng!g+)mMV&9W&NwF59=yV(Dpiy6X0ST$YNnkhsvq
z?ZKfT302kJL2*xV!kIF8NMyoF{pEhgEzGP_-a9Q6^+jSrW3_kfvs~uIzBO*s->y26
zE=Y8idth+L^`~cCj@+pB4_uv#M3uBQtlp3e4di~QYV$;RP$W8N#>U+{m%FoTr)ob6
zSS1Ce2JZ6@2uy!+%Q5`atE33q93(n-;hK#)4yX5TH;;Q2vr-`diHOeJyhF#6{bK5}
znvhkpE&vd3@%0Ugxc@A|JLci_AkX<(NK8w6?UoHIqZ3Wc4yFCETb&+=gyq)l(D7zJ
zo3iw6?CRlAim~0tJ20@gHpeNVur4CRGz*C?S#P>s&-Apb@%D&{%LXbz+(N6Z+3#j7
zc$=_B1qvw~^z-xyOnzGB8g%US`3NQyT5Yy%>oWI~JIt()y?0+M0fpq(?_9r`&0aCH
z<fOi;3lbl&$KS&%IP6~CQMV)aszd!2TtuQPH=D23OA6a;=3V%B>ohWyl3l%XqbZxM
zJ3TMmK+P42t#Ng8_Ycf}S?Um)^ET;-)kP#ScaxR&zErzy=0{&7t{xJC7z@p|n6ud{
zXJ0K`KhYJ557XV@>=l^w?3tHO?91!XE;5-&WZ`CG?eL_n+YhJxxo18D%1kjdHDj|^
zPrp{GKiLh52~OGV<{wh=CfzBbqAohrAQK5MHd<wT+|6WLX!%V;wNS)RGuWYD$KIos
zTxJL(LR8Se+0W;~n|t=5X@6wJ@4tXVrmo(i<#OE8Y+v&4zRRScgzCB-`p?;pssT5*
zPWC{e8us3PF;8BFc*H!fjPsnIfkbqT*RGBY-(u#KU28T|AQT!}+sLq%?VuL+aO(`%
zt%(lZ;qL2u<9+_Yh^v2`j<h(BMCNTY)83t8x7|Fp=8XREaKw;bx%CCxUhT;5TW1SH
z2}LuOr&rqB$4-GK-<KX|odeZbwsVuVf1Js7hZBE0EE0ht<JTLMvI9rEzp<RnaEIw^
zhm*TkSk3zcR#f%N(;>R)NMyy9-8vhOI-6_@zIJcxgb2jYGF^LteNN5d=>c_dC?d1@
zu(Ov($zSCMLks@8bZj3KS-aP4(cyS=3+tFyM^?&&BjJgwcj;#lW!@Z|FXw^87Vma+
z_e_5G*26pTef2rdF=<G|V9(m+p#fXW+|It<HCF)2j5XN3E{~ly+LG<KP!Y<=EZWBM
z@O||0oPGHH_xW)~X-IgznfA758#D9ZyIC7YMId1%eXEV<*}1AF|F|t0<cUND=G(b>
z<b15z?|<QQ#ks?0k;p^?<3+Av#%2d&-!rwvjv$7%sZkL7$>ilv!j~#~!6R4`mRscS
ze}%fly?tHit8@m5Xc!sjg*lm+dgj(_pF)Nb^Ve_nhw-`eam)%OZzQtZp5;^Z`HF35
z**`^I)6O8_MJCJkgqd4f1-wYmSBOGF%Z!8B&nIiYJ+7ky*(Vs=yJmcPdDtiIpB$(0
zsi48y8<%-`ZZ<m<|JG(99rDjJ3}?TXxa4ixDpkl&n_=V_@%D4d;h0xvtff<t@YJO`
zn}c?nZTGldWIQGs2`%5sV*fLLPDz2mXkR2WVUtfO``-TW;;0QE%J{|F_C8z8tpeV7
zu9S*GjCmV&?1aHFGw<4_@qS29+2q*op8~^T_s)d8(-!IZ*cux<o_Vrk7QinI9dnCa
zkayOVdxlf|5q+p-<=^Rhw#|?`13IH+>9fszn_E??(a<O)tZiUzzK6|TKKbgiEz<&!
zz=*K)En^gg&LYNG9Ve!dsa;rY;zkB!T(EKX4l6cWe_Ybb-BSY*S#7o?IUNa2-t4}^
z!q6q~QrfC$B;v5z(#oioZ8ysQjomEzH6*05+j)!SM*Ce%tKl(7c$v{I!^dm~)zD9N
z^F<+5*WP-Yk-qU}ond51ox8?z^Aq+#<#4wB0;y}@2WSf`^1~*Y1LF~6`8Lz1Y{!vK
z|M+N00*E$2$LN5&+j5zsh_Tqj<SP5<$gLlum&#v9RFUB`wdP7DfNmHWrLj|$%|6Ah
z8uk%7euHs3`}9b2cA~xt+-j{e$zUHJY4T@={j^U=Xr<{X&^(=r^S+bePTSCreP`nG
zq|-JcpOD}pJ<rc~#%no8ul|e#S1<SdyJGC}Am?HKAeyG<AGc?2iZo#(+Dwa>aBV}|
z@o+h0-l`Q-W=x}fK_rDCqB!FHo%vsZlBfL(l&mx5TTrr0Z&32!UZ7;g*509HN_Qw(
zo(CmUWdTY)&>2b=6>Wo(RmsBbP%;bfIsl^E;bcr?*ew{zJUE$)<qZHhnL;>xw86<T
zx4@C46;5ViNC@C$sxXCxXsvKEb`uGY;GxMt9;1ms1_}u<&{jMdqXV8SBGQg06L@hO
zo;-+z(E(2u>3}E0q<}4e3=}S)4B)Rm0Ll_PKv{$kk~A3rWr9L0oJ?k1M?$S|G68u5
zo=YR}YA%!v*<lm_mdu5codNCzs2Cg;IzY)ZYAcissgjTi-mQRDbD?B_i-iG72ArJ-
zB{K=gogRY(FvNwEnFPj21y@-vn2eZ^UzG<ZQ@C(4G#H71jG3qdq8yLtTr`=$dwF;=
z4e;azkPVCK0w>Gxz&d&>oQ#p<kPr_}CK`eQsQ?C3d2n(9qHu9!LPm_nOQP|BWCVo8
zR+Hh$P&<-L=H+Nbl7Z037)0a2$b`IT;0->0j3Hqz$jrl!Atwk*?uZ``4MtL(@nc@5
zb^w_uGviwT@_=sx$bxMEGPE(#W<QJ`Lm`SA8vla`GQkVBFh2+(W28Pn$W!|YArI{{
zgsj&O2wAeP5HhG8mDL{@ncOcJd2at;<naHOF!Gx|!N}KnF!E$Bj0|veUtr|h-C*Rp
zCl4O<2Sz3VjLdvFpzcZK_rl1MJ;2D!TIc^Nj4aa&jLdpA>gm&dp~%b{>~Y^=<l9|f
z<nn&O$fK(XK)U+g<-Xy_0BX14$mM;(k;`u0s_1|tU+OE4e6zne^0j{B$XEK0BNz1>
zN6zmbj+~j5^$SP-g(G*tk!5?tkzvi}@(W7-1ttH2l7B(Tzo6t_Q1UM*`4^P@{|HJR
z{w*k3xi=_Tyk{tR65Y3VC|Rxxlnmc0!&<Rqu3K_UE0!D#F3DUR*_3ceR>fr6ab$pB
zi9-f>F3DUBSztL2LuLUqNI=L8!Xug1>XD39baO~1cW_9?NRr@?JiOf@nMMYOWGTKw
zGVmfClKB8KK#zn&GL-;$xem#Ibpn7)7i@D##;Bp-@r(g5%5zBuoOJ$mM59x9F3Hh|
zB*^vQ9l>)(CXpdgpw$@}5OTs7c{)hn?u$&hh8TldeUSkO#*TIZk0FNZha3ygG6=<k
zjRD5JiiE&%mIoUnKrPW|0EP*nxWF-7(g0f|ckn|V%uDC_Awz*u_?8{l3z^0Beuk1f
z)EJr=N`i!3FJ!pF=-`D+g9s|u3z^_$Rf=eQ%s94#4>G{819-SEg$o+TLGd>KV*;cV
z;HA>}xG{JR3y)|AjxnBGT<>FW9!CRW5QFb}3~)Auj~Rndq6B7)wPD6U8{=cf@FjUn
zw42W{6KHotjOA3O_lg+b<hvUy{+qioNJY3ClYbB}<|6Y0`vw@pX%asO7$Zs_0Aq4r
z0b`>+1I9!90T_deecybJq4yN~1sDtT3o!1d-*NE&OThT`4+6&XxPHf6z__-q?&ko;
zq?fN=F<+~_c@2nhzZ{QU04@H0r{kZ97T@oy)A9c>T3p%D>G(U*Vws+tj)9H~xEy~U
zR4mig<rtviyWn!ntQu8Wb-&M8F?eIM?x@@YS~q_XD=u#HIsSze|0JK|Us&-kpX07R
z$G@=RUv9_0+>U>_9shDW{^fT3%kB7=+i}0#j%~Q7+RW>8stx*qKoT3Z*wn?>557F@
zV5BjOLHdER{mx1f9&ZwP`NiK~8;MZ=*P~otJ!M+I$$l>ZiN(G*{_J#yA*bO@zV*2F
zqeZ@#QeW~3O!j+BoFRj^G<^P0_u|#Z&)fqgIiIfX9`ax41&OVt#0fY}f8I$8urXhw
zt8aB6s_4llII4&9_sIpVXSejFUf)%Qq~Q4$PS$C7e9BTweV*pxWh<5~($tu*<B;<T
zj=E{C+#v!G^?xpq#>KFq;h#n>pQ*WgwXV)GtwmbPb#!#J=FT-f_a_MU_8@T*$A2uS
zo`Yk9*x74mELf?tVCtBWgXLuvhp9}MqqTJLT=o68An{Y6^nXqOx!5M0^WJxk`tqf-
zRpcdv=u`@oDj*~-Gkk)E*8CYOPQq!lA8p`tv;Ry3FdW%9=gIy_^OwvTCC#9c$?)I<
z0+}KpEIn+Z`uyqh<Nn6+SB7x>$A2P_SH6OCt;{DaSU6cxm<DeD?SV=YmRFmpF=JN5
z7o2lz8gV4aPY;+v76<?AK2>x6SXl-fJ4Xa={fP@QRajPe+T0nM$KgQlD9QhX0OTEP
zyy?Vj&3S4vf>d%FcR~c>hAJehJax|W#U&j4jgG+27XTY_1;_6$*VG&<FC;*)=hmJ7
z1}z{UCZ{@m&deR}@Rk%=>QC<h^5%c=dgu9ClNCe=_FTrTeN0@FNEDj5!kC$J)RUU<
zmy6&l8b4P7FsW1y{@W_8IU^;B)(4KA=)*mkDkwF4;_Nva>hLCa34xzF6<{RF#HV;;
z;Npej<wbbxiAr~<KOumCsJzNF_4%nSc#)D2^=Arzk?02h;O|Tq&sLJ8Q#v(1PX<C7
z5=BsQ$oM(x)}Qd#3&jM8@3H)(0Hj6XytSLUizX^U?-R_rQsxREz>rs&uAx_hf3cLN
zlYd?VU}U;%LJQ~2GL6v#gt*o3${y~a0myX8VN>R6<>Sr%0~wT`$Dc$I9+{6f1}&MP
zBte{1)vfkiaX<i?sKVIU3y!sLl7>SE^dMxPqJXaCgd6x*7p*CSM5(~P7b?(ALb9W#
z%@1qB^T$dF{<IDtk%eTZ5&SjB%L_yE_re~!fJB!XHhCWFD}H^l{LkwEXnw_+*MPtJ
zXjuk~{crFW5F0dJ!|5x2ZJL7UPwN1ZfcVfE=Qv;8<|q#k{04jYt{GK$;23rH2F`_P
zLnVJ2e=<#S#EiJ+=9sz4lH9MS_1XZ00;tSA+T0vFRS6WJ_m=9FLJtWf5`BR3Y?pe@
zC5;hMbnp-8JzxZX&C7Vb%gm87KaD?3ttxXY|G=NEQIev4dsLC>(#nRf@!u_GsmKcb
zqya#pGGtZMH&(**H&P1DSolW3$TVqHzefD#x;eoACrtq)3h<w!bEbt;G+A1R^36^q
z2@X)Nz?+g*68wLX1>|<>oMp_9_(w~5#<y1%RJy!VJ^pV0^4X)H|G(K*-)P3pNf?D8
zGiuf{!x9dsc!~(v-_FUccT{PWX-kZjsjsWVTXKw+&l)*E@SCdIBat2>q5je%rY~9J
z^%?)_H&C#r`G+Jqdw1fM%4dH*uX@yi|K+T|Y{qaHsy&kX;Yf@kC_Q|t)+(do7X0m2
zNwBcfRR&Nykf9G;9De^Z?EhNBr?a-prwjr6({oF8DEVENF#Sjjo~XG>-@X>-RN4h*
z-F|Q-X@?T8c4UdMtDMqmT2FIr6`-LqKvO~FC#gRiNGKqtFh+g3o<aBrob!Quf`9YJ
zGxMk<#!z*un9^6>elG#G;&J1Je;R*GKtxV;=CU<wci!PQG3>Q(>L|HoKm61Q2Wd~P
zk5eZ7r2a=3l_8@vWs$B~2KQKCU_$gY=O*hj|B&5wzHL|a!Ne)JKP6yPLCL`r=5Ng4
z!Y;s}1wa6Jf6>MaE}Hm>{K!u>#Nn1dA;8L7P<+ss`B7iEq=_G6fd8(6dsuR($j9?~
zF%>^36Tx3>;ApEiT<Yx1iq0n>xAEj~HM8v&Z%LNyb*c6vB5?UD%r4+|Hs`9jO=@kA
z{r)nO_+6e3;jL!xYsDWB03%TaC5G(h>0W){y7eZfdQ|#*K7c-S49y`zKf?rJB*wUH
zK2Ld+|Jb!^jmxth>tFw%-30P7-%<M3YV~`YfTHa8h|T}e8n(mk$d?@}+2OjIR3Egd
z{cix8(cKQ#mGk~X*IIUvpvz_BembSUDk#Q!*R5V%*z|hKi4p5(17N~FTwBvCi*G07
z%G3L012EdIF2}8Zn_t(|;vvL#^?MbqTRx1u>UCF=KXiXZ31-25@E=y%=f3C4Su#qj
zxAj`L%JvXJb?ed4e18+<t4Q=i0kBa|zMoZ3Ia`uON(p{@!QMly+oG_&{j7eY$4J0S
z`f33%T5kV(AOEmzluX|T047)4Q=|SsT;=jnG5|yLZ2(}{4Bmp{2N-tF+I&o1x$pJI
zNUQqU{qOh897${#`&fUH@%PU(oh#0}Ysp(ZeR$vXA0sjQr+$ApE}lHJ@8cgM_m6+m
z#f_Td6h-^`C;(P{CLQMeo*MX@ahz%!ojIy<eYXF=Uzfk#_$H%X65si6STa=!)UVIO
zk36FvlON}@$?Eyz2K9aV0W?=8tCzZcM>OZU@zNQ}GJS4-0!*cu^<(kzDSo?_ic~+=
ze}E<{1pd+YA^7>>r2v(FU=RT33k<QU`Hr^kEeq$fMSu7M?jR@=*Y^g1Eqa<%AB``p
z0YCw%jG0$^tX#`q-)EX%OzPw4Bi11B!yHR<yYqn`;QZ@yXyxa(U3Qz@1#NkEOtr7W
zpW6UxH@a{1KNO!m<*`9$kLLk+9Q@7Da@lIEIPtiKs7zl1Hl?~-_5Y68vPKu&9u{h9
zCU+OElRQlk6NbQJ`o8x7CbIT4{KjpkP`yQG`O?J;7tGVpNctE4_zf-9fqgfCga!&s
zyw!<2ICxmC(ALsapFL~V?1X>g|CiPHA$^~J3I1g5_g(mZVJ=xPcjnYd6DLkS@^Ac`
zj{^z{>;Jwg0DRdpu#*D(Ui<l(mBx%oV^ow!jv9Ta3*yyX9Um?pB;KF>2T8Qk4Ahw9
z<ZridirR?53i9%bLwA6;Nr&+9&S$*&O(zKE%U<GPeP62&20)~fj=$NjucJ9dWw5NI
zxR|(<oN4FfarI&N%>kd>j-A3u9}Evc`oUj7tE|0-oJ(8QESaS?SXxwwP8SrBT>GXY
zFT8rUjnj@zE>Ao5*o(OYT;G?mPn3ZfP$aUwSK0pSbTlU`$%ug44@E#wWYpdc!hvVZ
z{;gY#Hf(aZ(m|?*!+qX<@c1j{x7WYYOn31twL#)gCBoZ6NL>Cf@mp*B@c!Ty!wu{7
zRx>-=<-)=JYJZwxyZvcCwsy&!@xulPa~%N4RJw@dB)3QH&GY-d^?IvU>8#jP$(IN|
z|6J9N{Xa(60B;(8cz<x|obgI>Vm$u`5=B5rOj^mf9fSVEdifG?N7GuC(Ow2`juh*=
z0?-W0+WV4ob=|y)z+RAOP{P-MN@Ix2s<zM1|Lj+vIc@sPxr?$p@W(61^t}Tn-s?cA
zK5*&uQS!i^YtOg>(1j&O6!V)0|9WuZ=us+TCN1vt3x8~jzCVUF?Py?XOy`duO!(e#
z%_;DQ9-xa3E^Oz&PkE5M!cdi&o#tgunoM6C09)3se0X!3&TJJquI_P%GdN+u`cP=V
zv9>1qx^Kt;2??1YYBqnh#er~j^ZIH5F~ys0mBT+A)|xU*vV%1t1fbAFx3-P8CND(^
z218s<X^!X34mPNf$><vbgkgi)Ctpt4#(85EL}?w28CL-M=(a~vEm4YMf^=c&A*$1i
zp0o>&Um4c74!}rD|7s)iH9}{mvP|d23<y9LkZn_dmS{yWx`2>`;;8Yn&a{sk{DW?v
zOaL4w&|!kF-KoXf%Xcv5+y;<L=XW;e=uqG<C?-E*?4-RN3}YWn07g=8w=FF>Yc<pc
zf=5XQ_Qd)GBMWVQ$Zw>~5#n?zO+;p>>Nu^AHt^xZzH|VlkkGD0pWT<u=nmy^J3u;$
z-_|9n5_GBnLsCIWb#6x+P;b>2Z#;3|4%7P`<AoCk6KiSi*lT}-Ey}<=e*LehNzf@&
zy6AvGN*WLNk?_gMkn2MOEO^&WqA^}~?r3@8F3r!IA=P=0<sftESQwvVD!Ahg8gqfK
z6$FvDnm=v=Fxw8`%ga4WrV&V1=k6z(0i)Wt<$E}j$U+uiNXQMde8uk-;NRr&<0b&x
z(?%EP6zI<%rzqBO@bkL>W1Jvr$PF(w3H~GsT|`Pj&FWeQ0ZNDeXa``}y7um8`!1g~
zitxGZ+Wk;}ntz*?zFNQq8^J1z%MDiE(qZNPaea5y;n$$&PmF5QzPhe5<qrOy%qT|E
zsN>iF^&&2RXaLax3d1IL0IyqOM0@DFo;h=4F>FW?pDf;#qN_1RzGom0!^GNVpuhCE
zU_1B#2}{Wj9^ug8F>#)3cisI4dpO0$q#b*EXQw@V#DJa`(ile7`?FQjFXmvN38P31
z0fnKO*V=jp&mZ_>+YpSN*fxMTB^xv+4DMwg0~S#EZY%$KOIZT$f@u+!hH{EZs|)xl
z%sC<7v-rKW0VbN=*8KIs+?l^8?StYNWevan^_KEH{-A+k(jdT!)Yb(|le?VAk8}W>
zYgE$4|B+djnZJ|JnAB;0OEo&d`h@V!g>?Z#Oj>^M$ax7o0PnN;j{%VwX+#_D)qEPX
z4`%*uwwEUcS(jgZyd`WPx0Zwk(1pbZ3>>Pg?hnh8mQO{Ce+&nQgYBR5>;K`9HcUM|
z4t_!cp>{=SIl|*l?AxiZKa(A#G<sfQ-S3wJHccJ&BhLY#{5byH%PBKlFkwh9+6Vj@
zXZV8REs?DYBxnFo0Z}RWA<E;ltQ-uN&YQ^P-`#xi+OX?8bl?L1(x*P0K+${G9@4h9
zfyzl4+={les=xq+;iD(dUZAyT?)afFHGMC8*mqL-*0;HIyVjK9Qr|$)2et123Py;v
z4s&9ALTA84IC9){_4yjpN5kyVivo46Jh7}H3+&=q-{xEUbv4E+_NskQm}1*z=dO(6
zFA<0y03DQ&9ilQ}`poGQM#%mE4gvgW+qrA_hSCG;v;jr$Rr`QHHofgB!Ik!>y{!UB
z$_*VgcKq0pijv=G!LBU;-7l!@Q2hJnSLu5;tkRqS7}huX4pV;0*T7q2+H<xEFnGAq
zFa@dhjZ0T<-R}tlE;VBDes4#U^?KT~h+R()GcUg!rqK3_?ayXOv};+b0OHcJvI8WD
zuj_oj`jG{MWrj~w*VbLDw_^Upp*=2q`0U}}xLkhyU#fT1a$<D~D21?ysIZ^_u>TSM
zBC;bUYiO_3U9oVQG7P?NsxIv)-vHNX!2Yzoo?J^z6`;`sxZl`lllb2*K>b8zM@*Wl
zrM*NGMh>)TJIx--lFj(r<hxU)I!$wg03<R5;_EU!l<YZ*7=9u$!^TdZt1)Ma>R>6M
zZ}mQqz{a=Q%I4@1(w+DdL%B8d%&Ny&;7=8jR2VU4!bBK2|E{^1_(h%q{JvpmSN=Q+
zdSugkBr$)ANDUk^eE48F2?l)G=-X|Fkq>a!8JxT+J@D_HO|L1?YZRD2r3Oe#h;YAa
z)N4*|0)}aFCkysL)xq8C|Lw9prxF4P(1jR6FmApBy~YNYH-7o>$2pCWgF5S9&(yyo
zmarZ0%|<GP_@dRn=Evwp{>+``^F}Et{M%UhS6ZzZxFd)69k+ik0?(<$C8ZRG4j&>X
zM*D`P{&z|pa`47Yhlt)UiTMile1irLloI~_S+;k2Kbk@q3?cCW^71k~aPmjX_cuRi
j3jqd8ON%pT|2A0r%d4mIyw#qBq_{8v4fmAe8*%>!!Kmtz

literal 0
HcmV?d00001

diff --git a/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore b/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore
new file mode 100644
index 00000000..0857ac37
--- /dev/null
+++ b/SecurityServer/SettingsDialog/SecuritySettings.pbproj/.cvsignore
@@ -0,0 +1 @@
+*.pbxuser
diff --git a/SecurityServer/SettingsDialog/SecuritySettings.pbproj/project.pbxproj b/SecurityServer/SettingsDialog/SecuritySettings.pbproj/project.pbxproj
new file mode 100755
index 00000000..8a2098fe
--- /dev/null
+++ b/SecurityServer/SettingsDialog/SecuritySettings.pbproj/project.pbxproj
@@ -0,0 +1,336 @@
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 30;
+	objects = {
+		027CEFC5FF37673611CD287F = {
+			isa = PBXApplicationReference;
+			path = SecuritySettings.app;
+			refType = 3;
+		};
+		027CEFC7FF376BA311CD287F = {
+			isa = PBXFileReference;
+			path = main.m;
+			refType = 4;
+		};
+		027CEFC8FF376BA311CD287F = {
+			fileRef = 027CEFC7FF376BA311CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		027CEFCAFF3770A311CD287F = {
+			children = (
+				027CEFD0FF37724411CD287F,
+			);
+			isa = PBXGroup;
+			name = Headers;
+			path = "";
+			refType = 4;
+		};
+		027CEFCFFF37724411CD287F = {
+			isa = PBXFileReference;
+			path = SettingsWindow.m;
+			refType = 4;
+		};
+		027CEFD0FF37724411CD287F = {
+			isa = PBXFileReference;
+			path = SettingsWindow.h;
+			refType = 4;
+		};
+		027CEFD1FF37724411CD287F = {
+			fileRef = 027CEFD0FF37724411CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		027CEFD2FF37724411CD287F = {
+			fileRef = 027CEFCFFF37724411CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		043355C9FE30361CC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		080E96DCFE201CFB7F000001 = {
+			fileRef = 29B97318FDCFA39411CA2CEA;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		080E96DDFE201D6D7F000001 = {
+			children = (
+				027CEFCFFF37724411CD287F,
+			);
+			isa = PBXGroup;
+			name = Classes;
+			refType = 4;
+		};
+		089C165CFE840E0CC02AAC07 = {
+			children = (
+				089C165DFE840E0CC02AAC07,
+			);
+			isa = PBXVariantGroup;
+			name = InfoPlist.strings;
+			refType = 4;
+		};
+		089C165DFE840E0CC02AAC07 = {
+			isa = PBXFileReference;
+			name = English;
+			path = English.lproj/InfoPlist.strings;
+			refType = 4;
+		};
+		089C165EFE840E0CC02AAC07 = {
+			fileRef = 089C165CFE840E0CC02AAC07;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		1058C7A0FEA54F0111CA2CBB = {
+			children = (
+				1058C7A1FEA54F0111CA2CBB,
+			);
+			isa = PBXGroup;
+			name = "Linked Frameworks";
+			refType = 4;
+		};
+		1058C7A1FEA54F0111CA2CBB = {
+			isa = PBXFrameworkReference;
+			name = Cocoa.framework;
+			path = /System/Library/Frameworks/Cocoa.framework;
+			refType = 0;
+		};
+		1058C7A2FEA54F0111CA2CBB = {
+			children = (
+				29B97325FDCFA39411CA2CEA,
+				29B97324FDCFA39411CA2CEA,
+			);
+			isa = PBXGroup;
+			name = "Other Frameworks";
+			refType = 4;
+		};
+		1058C7A3FEA54F0111CA2CBB = {
+			fileRef = 1058C7A1FEA54F0111CA2CBB;
+			isa = PBXBuildFile;
+			settings = {
+				INCLUDED_OSS = (
+					MACOS,
+					WINDOWS,
+					PDOUNIX,
+				);
+			};
+		};
+		19C28FACFE9D520D11CA2CBB = {
+			children = (
+				027CEFC5FF37673611CD287F,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		29B97313FDCFA39411CA2CEA = {
+			isa = PBXProject;
+			mainGroup = 29B97314FDCFA39411CA2CEA;
+			targets = (
+				29B97326FDCFA39411CA2CEA,
+			);
+		};
+		29B97314FDCFA39411CA2CEA = {
+			children = (
+				080E96DDFE201D6D7F000001,
+				027CEFCAFF3770A311CD287F,
+				29B97315FDCFA39411CA2CEA,
+				29B97317FDCFA39411CA2CEA,
+				29B97323FDCFA39411CA2CEA,
+				19C28FACFE9D520D11CA2CBB,
+			);
+			isa = PBXGroup;
+			name = CocoaApp;
+			path = "";
+			refType = 4;
+		};
+		29B97315FDCFA39411CA2CEA = {
+			children = (
+				027CEFC7FF376BA311CD287F,
+			);
+			isa = PBXGroup;
+			name = "Other Sources";
+			path = "";
+			refType = 4;
+		};
+		29B97317FDCFA39411CA2CEA = {
+			children = (
+				29B97318FDCFA39411CA2CEA,
+				089C165CFE840E0CC02AAC07,
+			);
+			isa = PBXGroup;
+			name = Resources;
+			path = "";
+			refType = 4;
+		};
+		29B97318FDCFA39411CA2CEA = {
+			children = (
+				29B97319FDCFA39411CA2CEA,
+			);
+			isa = PBXVariantGroup;
+			name = MainMenu.nib;
+			path = "";
+			refType = 4;
+		};
+		29B97319FDCFA39411CA2CEA = {
+			isa = PBXFileReference;
+			name = English;
+			path = English.lproj/MainMenu.nib;
+			refType = 4;
+		};
+		29B97323FDCFA39411CA2CEA = {
+			children = (
+				1058C7A0FEA54F0111CA2CBB,
+				1058C7A2FEA54F0111CA2CBB,
+			);
+			isa = PBXGroup;
+			name = Frameworks;
+			path = "";
+			refType = 4;
+		};
+		29B97324FDCFA39411CA2CEA = {
+			isa = PBXFrameworkReference;
+			name = AppKit.framework;
+			path = /System/Library/Frameworks/AppKit.framework;
+			refType = 0;
+		};
+		29B97325FDCFA39411CA2CEA = {
+			isa = PBXFrameworkReference;
+			name = Foundation.framework;
+			path = /System/Library/Frameworks/Foundation.framework;
+			refType = 0;
+		};
+		29B97326FDCFA39411CA2CEA = {
+			buildPhases = (
+				29B97327FDCFA39411CA2CEA,
+				29B97328FDCFA39411CA2CEA,
+				29B9732BFDCFA39411CA2CEA,
+				29B9732DFDCFA39411CA2CEA,
+				043355C9FE30361CC02AAC07,
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = app;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXApplicationTarget;
+			name = SecuritySettings;
+			productInstallPath = "$(HOME)/Applications";
+			productName = SecuritySettings;
+			productReference = 027CEFC5FF37673611CD287F;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>SecuritySettings</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		29B97327FDCFA39411CA2CEA = {
+			buildActionMask = 2147483647;
+			files = (
+				027CEFD1FF37724411CD287F,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		29B97328FDCFA39411CA2CEA = {
+			buildActionMask = 2147483647;
+			files = (
+				080E96DCFE201CFB7F000001,
+				089C165EFE840E0CC02AAC07,
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		29B9732BFDCFA39411CA2CEA = {
+			buildActionMask = 2147483647;
+			files = (
+				027CEFC8FF376BA311CD287F,
+				027CEFD2FF37724411CD287F,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		29B9732DFDCFA39411CA2CEA = {
+			buildActionMask = 2147483647;
+			files = (
+				1058C7A3FEA54F0111CA2CBB,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+	};
+	rootObject = 29B97313FDCFA39411CA2CEA;
+}
diff --git a/SecurityServer/SettingsDialog/SettingsWindow.h b/SecurityServer/SettingsDialog/SettingsWindow.h
new file mode 100755
index 00000000..377c3667
--- /dev/null
+++ b/SecurityServer/SettingsDialog/SettingsWindow.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+
+#import <AppKit/AppKit.h>
+
+@interface SettingsWindow : NSObject
+{
+	NSWindow *myWindow;
+	BOOL securityOnOffSetting;
+}
+- (void)cancel:(id)sender;
+- (void)ok:(id)sender;
+- (void)securityOnOff:(id)sender;
+@end
diff --git a/SecurityServer/SettingsDialog/SettingsWindow.m b/SecurityServer/SettingsDialog/SettingsWindow.m
new file mode 100644
index 00000000..12aa56f2
--- /dev/null
+++ b/SecurityServer/SettingsDialog/SettingsWindow.m
@@ -0,0 +1,53 @@
+#import "SettingsWindow.h"
+
+// @@@ need to add code to remember the radio button settings as a pref
+
+@implementation SettingsWindow
+
+- (void)applicationDidFinishLaunching:(NSNotification *)val
+{
+	[myWindow makeKeyAndOrderFront:self];
+	[NSApp activateIgnoringOtherApps:YES];
+}
+
+// @@@ don't need this right now as the nib is connected to terminate
+- (void)cancel:(id)sender
+{
+
+}
+
+- (void)ok:(id)sender
+{
+	int status;
+	char commandLine[256];
+	
+	strcpy(commandLine, "/System/Library/StartupItems/SecurityServer/enable ");
+	strcat(commandLine, (securityOnOffSetting ? "no" : "yes"));
+	
+	status=system(commandLine);
+    if ( status ) 
+	{
+        NSRunAlertPanel(@"Alert", @"Error executing the enable component.\nSecurity settings not changed.", @"OK", nil, nil, nil);
+    }
+			
+			
+	[[NSApplication sharedApplication] terminate:self];
+		
+}
+
+- (void)securityOnOff:(id)sender
+{
+    switch ([sender selectedRow]) 
+	{
+		case 0: securityOnOffSetting = 0;			
+			break;
+		case 1: securityOnOffSetting = 1;			
+			break;
+	}
+}
+
+
+
+
+
+@end
diff --git a/SecurityServer/SettingsDialog/main.m b/SecurityServer/SettingsDialog/main.m
new file mode 100755
index 00000000..2bc3a7b6
--- /dev/null
+++ b/SecurityServer/SettingsDialog/main.m
@@ -0,0 +1,5 @@
+#import <AppKit/AppKit.h>
+
+int main(int argc, const char *argv[]) {
+    return NSApplicationMain(argc, argv);
+}
diff --git a/SecurityServer/StartupItems/Localizable.strings b/SecurityServer/StartupItems/Localizable.strings
new file mode 100644
index 00000000..2d6f3c5c
--- /dev/null
+++ b/SecurityServer/StartupItems/Localizable.strings
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+	<key>Starting SecurityServer</key>
+	<string>Starting SecurityServer</string>
+	<key>Stopping SecurityServer</key>
+	<string>Stopping SecurityServer</string>
+</dict>
+</plist>
+
diff --git a/SecurityServer/StartupItems/SecurityServer b/SecurityServer/StartupItems/SecurityServer
new file mode 100755
index 00000000..e93fbe85
--- /dev/null
+++ b/SecurityServer/StartupItems/SecurityServer
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+. /etc/rc.common
+
+SECURITYSERVER=-YES-	# needs to be put into /etc/hostconfig
+
+if [ "$SECURITYSERVER" != "-NO-" ]; then
+  ConsoleMessage "Starting SecurityServer"
+  export DEBUGDEST=LOG_AUTHPRIV
+  /System/Library/CoreServices/SecurityServer
+else
+  ConsoleMessage "SecurityServer disabled"
+fi
diff --git a/SecurityServer/StartupItems/StartupParameters.plist b/SecurityServer/StartupItems/StartupParameters.plist
new file mode 100644
index 00000000..8f4fd0e3
--- /dev/null
+++ b/SecurityServer/StartupItems/StartupParameters.plist
@@ -0,0 +1,10 @@
+{
+  Description     = "Apple Security Server";
+  Provides        = ("SecurityServer");
+  OrderPreference = "None";
+  Messages =
+  {
+    start = "Starting SecurityServer";
+    stop  = "Stopping SecurityServer";
+  };
+}
diff --git a/SecurityServer/TODO b/SecurityServer/TODO
new file mode 100644
index 00000000..4fb0efdc
--- /dev/null
+++ b/SecurityServer/TODO
@@ -0,0 +1,18 @@
+SecurityServer is a work in progress.
+
+Important items that we know need to be cleaned up for Cheetah:
+Sort out which memory allocations should be sensitive, and make them so.
+Use CssmAutoData & friends copiously
+Replace MIG server loop with a custom version and integrate deferred
+  allocation release and timed events.
+
+Questionable for Cheetah (not important enough/too big?):
+Multi-threading the SecurityServer main request loop. This would require
+  thread-safing the entire server core, which right now it probably isn't.
+
+Major missing features (for future consideration):
+ACL-related callbacks (+ possibly other callbacks)
+  This would require IPC support that makes the IPC path asynchronous
+  (or else requires interesting step dancing on the client side).
+  It's not trivial, but eventually we'll have to do it. At least the
+  data structure transports are already pretty much in place.
diff --git a/SecurityServer/acl_keychain.cpp b/SecurityServer/acl_keychain.cpp
new file mode 100644
index 00000000..9de5f7d9
--- /dev/null
+++ b/SecurityServer/acl_keychain.cpp
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_keychain - a subject type for the protected-path
+//				  keychain prompt interaction model.
+//
+// Arguments in list form:
+//	list[1] = CssmData: Descriptive String (presented to user in protected dialogs)
+//
+// Some notes on Acl Update Triggers:
+// When the user checks the "don't ask me again" checkbox in the access confirmation
+// dialog, we respond by returning the informational error code
+// CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT, and setting a count-down trigger
+// in the connection. The caller is entitled to bypass our dialog (it succeeds
+// automatically) within the next few (Connection::aclUpdateTriggerLimit == 2)
+// requests, in order to update the object's ACL as requested. It must then retry
+// the original access operation (which will presumably pass because of that edit).
+// These are the rules: for the trigger to apply, the access must be to the same
+// object, from the same connection, and within the next two accesses.
+// (Currently, these are for a "get acl" and the "change acl" calls.)
+// Damage Control Department: The worst this mechanism could do, if subverted, is
+// to bypass our confirmation dialog (making it appear to succeed to the ACL validation).
+// But that is exactly what the "don't ask me again" checkbox is meant to do, so any
+// subversion would be based on a (perhaps intentional) miscommunication between user 
+// and client process as to what the user consents not to be asked about (any more).
+// The user can always examine the resulting ACL (in Keychain Access or elsewhere), and
+// edit it to suit her needs.
+//
+#ifdef __MWERKS__
+#define _CPP_ACL_KEYCHAIN
+#endif
+
+#include "acl_keychain.h"
+#include "agentquery.h"
+#include "acls.h"
+#include "connection.h"
+#include "xdatabase.h"
+#include "server.h"
+#include <Security/debugging.h>
+#include <algorithm>
+
+
+//
+// Validate a credential set against this subject.
+//
+bool KeychainPromptAclSubject::validate(const AclValidationContext &context,
+    const TypedList &sample) const
+{
+    SecurityServerEnvironment *env = context.environment<SecurityServerEnvironment>();
+    if (env) {
+		// check for special ACL-update override
+		if (context.authorization() == CSSM_ACL_AUTHORIZATION_CHANGE_ACL
+				&& Server::connection().aclWasSetForUpdateTrigger(env->acl)) {
+			debug("kcacl", "honoring acl update trigger for %p(%s)", 
+                &env->acl, description.c_str());
+			return true;
+		}
+
+        // ask the user
+		QueryKeychainUse query;
+		const Database *db = env->database();
+		query((db ? db->dbName() : NULL), description.c_str(), context.authorization());
+		if (query.continueGrantingToCaller) {
+			// mark for special ACL-update override (really soon) later
+			Server::connection().setAclUpdateTrigger(env->acl);
+			debug("kcacl", "setting acl update trigger for %p(%s)", 
+                &env->acl, description.c_str());
+			// fail with prejudice (caller will retry)
+			CssmError::throwMe(CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT);
+		}
+		return query.allowAccess;
+    }
+	return false;        // default to deny without prejudice
+}
+
+
+//
+// Make a copy of this subject in CSSM_LIST form
+//
+CssmList KeychainPromptAclSubject::toList(CssmAllocator &alloc) const
+{
+	return TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT,
+        new(alloc) ListElement(alloc, description));
+}
+
+
+//
+// Create a PasswordAclSubject
+//
+KeychainPromptAclSubject *KeychainPromptAclSubject::Maker::make(const TypedList &list) const
+{
+    ListElement *params[1];
+	crack(list, 1, params, CSSM_LIST_ELEMENT_DATUM);
+	return new KeychainPromptAclSubject(*params[0]);
+}
+
+KeychainPromptAclSubject *KeychainPromptAclSubject::Maker::make(Reader &pub, Reader &) const
+{
+    const char *description; pub(description);
+	return new KeychainPromptAclSubject(description);
+}
+
+KeychainPromptAclSubject::KeychainPromptAclSubject(string descr)
+: SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT),
+  description(descr)
+{
+}
+
+
+//
+// Export the subject to a memory blob
+//
+void KeychainPromptAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
+{
+    pub.insert(description.size() + 1);
+}
+
+void KeychainPromptAclSubject::exportBlob(Writer &pub, Writer &priv)
+{
+    pub(description.c_str());
+}
+
+
+#ifdef DEBUGDUMP
+
+void KeychainPromptAclSubject::debugDump() const
+{
+	Debug::dump("KeychainPrompt:%s", description.c_str());
+}
+
+#endif //DEBUGDUMP
diff --git a/SecurityServer/acl_keychain.h b/SecurityServer/acl_keychain.h
new file mode 100644
index 00000000..98770085
--- /dev/null
+++ b/SecurityServer/acl_keychain.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_keychain - a subject type for the protected-path
+//				  keychain prompt interaction model.
+//
+#ifndef _ACL_KEYCHAIN
+#define _ACL_KEYCHAIN
+
+#include <Security/cssmacl.h>
+#include "SecurityAgentClient.h"
+#include <string>
+
+#ifdef _CPP_ACL_KEYCHAIN
+#pragma export on
+#endif
+
+
+//
+// This is the actual subject implementation class
+//
+class KeychainPromptAclSubject : public SimpleAclSubject {
+public:
+    bool validate(const AclValidationContext &baseCtx, const TypedList &sample) const;
+    CssmList toList(CssmAllocator &alloc) const;
+    
+    KeychainPromptAclSubject(string description);
+    
+    void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
+    void exportBlob(Writer &pub, Writer &priv);
+	
+	IFDUMP(void debugDump() const);
+
+    class Maker : public AclSubject::Maker {
+    public:
+    	Maker() : AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT) { }
+    	KeychainPromptAclSubject *make(const TypedList &list) const;
+    	KeychainPromptAclSubject *make(Reader &pub, Reader &priv) const;
+    };
+    
+private:
+    string description;
+};
+
+
+#ifdef _CPP_ACL_KEYCHAIN
+#pragma export off
+#endif
+
+
+#endif //_ACL_KEYCHAIN
diff --git a/SecurityServer/acls.cpp b/SecurityServer/acls.cpp
new file mode 100644
index 00000000..39b29f36
--- /dev/null
+++ b/SecurityServer/acls.cpp
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+
+
+//
+// acls - SecurityServer ACL implementation
+//
+#include "acls.h"
+#include "connection.h"
+#include "server.h"
+#include "SecurityAgentClient.h"
+#include <Security/acl_any.h>
+#include <Security/acl_password.h>
+#include <Security/acl_threshold.h>
+
+
+//
+// SecurityServerAcl is virtual
+//
+SecurityServerAcl::~SecurityServerAcl()
+{ }
+
+
+//
+// Each SecurityServerAcl type must provide some indication of a database
+// it is associated with. The default, naturally, is "none".
+//
+const Database *SecurityServerAcl::relatedDatabase() const
+{ return NULL; }
+
+
+//
+// Provide environmental information to get/change-ACL calls.
+// Also make them virtual so our children can override them.
+//
+void SecurityServerAcl::cssmGetAcl(const char *tag, uint32 &count, AclEntryInfo * &acls)
+{
+	instantiateAcl();
+	return ObjectAcl::cssmGetAcl(tag, count, acls);
+}
+
+void SecurityServerAcl::cssmGetOwner(AclOwnerPrototype &owner)
+{
+	instantiateAcl();
+	return ObjectAcl::cssmGetOwner(owner);
+}
+
+void SecurityServerAcl::cssmChangeAcl(const AclEdit &edit, const AccessCredentials *cred)
+{
+	instantiateAcl();
+	SecurityServerEnvironment env(*this);
+	ObjectAcl::cssmChangeAcl(edit, cred, &env);
+	noticeAclChange();
+}
+
+void SecurityServerAcl::cssmChangeOwner(const AclOwnerPrototype &newOwner,
+	const AccessCredentials *cred)
+{
+	instantiateAcl();
+	SecurityServerEnvironment env(*this);
+	ObjectAcl::cssmChangeOwner(newOwner, cred, &env);
+	noticeAclChange();
+}
+
+
+//
+// Modified validate() methods to connect all the conduits...
+//
+void SecurityServerAcl::validate(AclAuthorization auth, const AccessCredentials *cred) const
+{
+    SecurityServerEnvironment env(*this);
+    ObjectAcl::validate(auth, cred, &env);
+}
+
+void SecurityServerAcl::validate(AclAuthorization auth, const Context &context) const
+{
+	validate(auth,
+		context.get<AccessCredentials>(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS));
+}
+
+
+//
+// This function decodes the "special passphrase samples" that provide passphrases
+// to the SecurityServer through ACL sample blocks. Essentially, it trolls a credentials
+// structure's samples for the special markers, resolves anything that contains
+// passphrases outright (and returns true), or returns false if the normal interactive
+// procedures are to be followed.
+// (This doesn't strongly belong to the SecurityServerAcl class, but doesn't really have
+// a better home elsewhere.)
+//
+bool SecurityServerAcl::getBatchPassphrase(const AccessCredentials *cred,
+	CSSM_SAMPLE_TYPE neededSampleType, CssmOwnedData &passphrase)
+{
+    if (cred) {
+		// check all top-level samples
+        const SampleGroup &samples = cred->samples();
+        for (uint32 n = 0; n < samples.length(); n++) {
+            TypedList sample = samples[n];
+            if (!sample.isProper())
+                CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+            if (sample.type() == neededSampleType) {
+                sample.snip();
+                if (!sample.isProper())
+                    CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+                switch (sample.type()) {
+                case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT:
+                    return false;
+                case CSSM_SAMPLE_TYPE_PASSWORD:
+					if (sample.length() != 2)
+						CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+					passphrase = sample[1];
+                    return true;
+                default:
+                    CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+                }
+            }
+        }
+    }
+	return false;
+}
+
+
+//
+// Implement our environment object
+//
+uid_t SecurityServerEnvironment::getuid() const
+{
+    return Server::connection().process.uid();
+}
+
+gid_t SecurityServerEnvironment::getgid() const
+{
+    return Server::connection().process.gid();
+}
+
+pid_t SecurityServerEnvironment::getpid() const
+{
+    return Server::connection().process.pid();
+}
+
+bool SecurityServerEnvironment::verifyCodeSignature(const CodeSigning::Signature *signature)
+{
+	return Server::connection().process.verifyCodeSignature(signature);
+}
diff --git a/SecurityServer/acls.h b/SecurityServer/acls.h
new file mode 100644
index 00000000..0bbd998c
--- /dev/null
+++ b/SecurityServer/acls.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+
+//
+// acls - SecurityServer ACL implementation
+//
+#ifndef _H_ACLS
+#define _H_ACLS
+
+#include "securityserver.h"
+#include <Security/cssmacl.h>
+#include <Security/acl_process.h>
+#include <Security/acl_codesigning.h>
+
+
+class Connection;
+class Database;
+
+
+//
+// ACL implementation as used by the SecurityServer
+//
+class SecurityServerAcl : public ObjectAcl {
+public:
+	SecurityServerAcl(AclKind k, CssmAllocator &alloc) :ObjectAcl(alloc), mKind(k) { }
+	virtual ~SecurityServerAcl();
+	
+	AclKind kind() const { return mKind; }
+
+    // validation calls restated
+	void validate(AclAuthorization auth, const AccessCredentials *cred) const;
+	void validate(AclAuthorization auth, const Context &context) const;
+
+	void cssmGetAcl(const char *tag, uint32 &count, AclEntryInfo * &acls);
+    void cssmGetOwner(AclOwnerPrototype &owner);
+    void cssmChangeAcl(const AclEdit &edit, const AccessCredentials *cred);
+    void cssmChangeOwner(const AclOwnerPrototype &newOwner, const AccessCredentials *cred);
+	
+	virtual void instantiateAcl() = 0;
+	virtual void noticeAclChange() = 0;
+	virtual const Database *relatedDatabase() const;
+	
+public:
+	static bool getBatchPassphrase(const AccessCredentials *cred,
+		CSSM_SAMPLE_TYPE neededSampleType, CssmOwnedData &passphrase);
+
+private:
+	AclKind mKind;
+};
+
+
+//
+// Our implementation of an ACL validation environment uses information
+// derived from a Connection object. It implements context for
+// -- ProcessAclSubjects (getuid/getgid)
+// -- KeychainPromptAclSubjects (connection link)
+//
+class SecurityServerEnvironment : public virtual AclValidationEnvironment,
+    public virtual ProcessAclSubject::Environment,
+	public virtual CodeSignatureAclSubject::Environment {
+public:
+    SecurityServerEnvironment(const SecurityServerAcl &baseAcl)
+    : acl(baseAcl) { }
+	
+	const SecurityServerAcl &acl;
+    
+	const Database *database() const		{ return acl.relatedDatabase(); }
+    uid_t getuid() const;
+    gid_t getgid() const;
+	pid_t getpid() const;
+	bool verifyCodeSignature(const CodeSigning::Signature *signature);
+};
+
+
+#endif //_H_ACLS
diff --git a/SecurityServer/agentquery.cpp b/SecurityServer/agentquery.cpp
new file mode 100644
index 00000000..0e251297
--- /dev/null
+++ b/SecurityServer/agentquery.cpp
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ */
+
+
+//
+// passphrases - canonical code to obtain passphrases
+//
+#include "agentquery.h"
+#include "server.h"
+
+using namespace SecurityAgent;
+
+
+//
+// Construct a query object
+//
+SecurityAgentQuery::SecurityAgentQuery()
+{
+	// this may take a while
+	Server::active().longTermActivity();
+	Server::connection().useAgent(this);
+}
+
+SecurityAgentQuery::~SecurityAgentQuery()
+{
+	Server::connection(true).useAgent(NULL);
+}
+
+
+//
+// Perform the "rogue app" access query dialog
+//
+void QueryKeychainUse::operator () (const char *database, const char *description,
+	AclAuthorization action)
+{
+	queryKeychainAccess(Server::connection().process.clientCode(),
+        Server::connection().process.pid(),
+		database, description, action, *this);
+}
+
+
+//
+// Obtain passphrases and submit them to the accept() method until it is accepted
+// or we can't get another passphrase. Accept() should consume the passphrase
+// if it is accepted. If no passphrase is acceptable, throw out of here.
+//
+void QueryPassphrase::query(const AccessCredentials *cred, CSSM_SAMPLE_TYPE sampleType)
+{
+	CssmAutoData passphrase(CssmAllocator::standard(CssmAllocator::sensitive));
+	if (SecurityServerAcl::getBatchPassphrase(cred, sampleType, passphrase)) {
+		// batch use - try the one and only, fail if unacceptable
+		if (accept(passphrase, false) == noReason)
+			return;
+		else
+			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PASSPHRASE);	//@@@ not ideal
+	} else {
+		// interactive use - run a try/retry loop
+		unsigned int retryCount = 0;
+		queryInteractive(passphrase);
+		while (Reason reason = accept(passphrase, true)) {
+			if (++retryCount > maxRetries) {
+				cancelStagedQuery(tooManyTries);
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PASSPHRASE);	//@@@ not ideal
+			} else {
+				retryInteractive(passphrase, reason);
+			}
+		}
+		// accepted
+		finishStagedQuery();
+	}
+}
+
+
+//
+// Get existing passphrase (unlock) Query
+//
+void QueryUnlock::operator () (const AccessCredentials *cred)
+{
+	query(cred, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK);
+}
+
+Reason QueryUnlock::accept(CssmManagedData &passphrase, bool)
+{
+	return database.decode(passphrase) ? noReason : invalidPassphrase;
+}
+
+void QueryUnlock::queryInteractive(CssmOwnedData &passphrase)
+{
+    char passString[maxPassphraseLength];
+	queryUnlockDatabase(Server::connection().process.clientCode(),
+        Server::connection().process.pid(),
+        database.dbName(), passString);
+	passphrase.copy(passString, strlen(passString));
+}
+
+void QueryUnlock::retryInteractive(CssmOwnedData &passphrase, Reason reason)
+{
+    char passString[maxPassphraseLength];
+	retryUnlockDatabase(reason, passString);
+	passphrase.copy(passString, strlen(passString));
+}
+
+
+//
+// Get new passphrase Query
+//
+void QueryNewPassphrase::operator () (const AccessCredentials *cred, CssmOwnedData &passphrase)
+{
+	query(cred, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK);
+	passphrase = mPassphrase;
+}
+
+Reason QueryNewPassphrase::accept(CssmManagedData &passphrase, bool canRetry)
+{
+	//@@@ acceptance criteria are currently hardwired here
+	//@@@ This validation presumes ASCII - UTF8 might be more lenient
+	
+	// if we can't retry (i.e. batch environment), accept it rather than fail terminally
+	if (!canRetry) {
+		mPassphrase = passphrase;
+		return noReason;
+	}
+	
+	// if the user insists (re-enters the same passphrase), allow it
+	if (mPassphraseValid && passphrase.get() == mPassphrase)
+		return noReason;
+
+	// check simple criteria
+	mPassphrase = passphrase;
+    mPassphraseValid = true;
+	if (mPassphrase.length() == 0)
+		return passphraseIsNull;
+	const char *passString = mPassphrase;
+	if (strlen(passString) < 6)
+		return passphraseTooSimple;
+	
+	// accept this
+	return noReason;
+}
+
+void QueryNewPassphrase::queryInteractive(CssmOwnedData &passphrase)
+{
+    char passString[maxPassphraseLength];
+	queryNewPassphrase(Server::connection().process.clientCode(),
+        Server::connection().process.pid(),
+		dbCommon.dbName(), initialReason, passString);
+	passphrase.copy(passString, strlen(passString));
+}
+
+void QueryNewPassphrase::retryInteractive(CssmOwnedData &passphrase, Reason reason)
+{
+    char passString[maxPassphraseLength];
+	retryNewPassphrase(reason, passString);
+	passphrase.copy(passString, strlen(passString));
+}
+
+
+//
+// Authorize by group membership
+//
+void QueryAuthorizeByGroup::cancel(Reason reason)
+{
+    if (mActive) {
+        cancelStagedQuery(reason);
+        mActive = false;
+    }
+}
+
+void QueryAuthorizeByGroup::done()
+{
+    if (mActive) {
+        finishStagedQuery();
+        mActive = false;
+    }
+}
+
+uid_t QueryAuthorizeByGroup::uid()
+{
+    return Server::connection().process.uid();
+}
+
+bool QueryAuthorizeByGroup::operator () (const char *group, const char *candidateUser,
+    char username[maxUsernameLength], char passphrase[maxPassphraseLength], Reason reason)
+{
+    if (mActive) {
+        return retryAuthorizationAuthenticate(reason, username, passphrase);
+    } else {
+        bool result = authorizationAuthenticate(Server::connection().process.clientCode(),
+            Server::connection().process.pid(), group, candidateUser, username, passphrase);
+        mActive = true;
+        return result;
+    }
+}
diff --git a/SecurityServer/agentquery.h b/SecurityServer/agentquery.h
new file mode 100644
index 00000000..e12c6a08
--- /dev/null
+++ b/SecurityServer/agentquery.h
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+
+//
+// passphrases - canonical code to obtain passphrases
+//
+#ifndef _H_PASSPHRASES
+#define _H_PASSPHRASES
+
+#include "securityserver.h"
+#include "xdatabase.h"
+#include <Security/utilities.h>
+#include "SecurityAgentClient.h"
+
+
+//
+// The common machinery of retryable SecurityAgent queries
+//
+class SecurityAgentQuery : protected SecurityAgent::Client {
+	typedef SecurityAgent::Reason Reason;
+public:	
+	SecurityAgentQuery();
+	virtual ~SecurityAgentQuery();
+};
+
+
+//
+// Specialized for "rogue app" alert queries
+//
+class QueryKeychainUse : public SecurityAgent::Client::KeychainChoice, public SecurityAgentQuery {
+public:
+	void operator () (const char *database, const char *description, AclAuthorization action);
+};
+
+
+//
+// Specialized for passphrase-yielding queries based on Credential markers
+//
+class QueryPassphrase : public SecurityAgentQuery {
+protected:
+	QueryPassphrase(unsigned int maxTries) : maxRetries(maxTries) { }
+	void query(const AccessCredentials *cred, CSSM_SAMPLE_TYPE relevantSampleType);
+	
+	virtual void queryInteractive(CssmOwnedData &passphrase) = 0;
+	virtual void retryInteractive(CssmOwnedData &passphrase, Reason reason) = 0;
+
+protected:
+	virtual Reason accept(CssmManagedData &passphrase, bool canRetry) = 0;
+	
+private:
+	const unsigned int maxRetries;
+};
+
+
+//
+// A query for an existing passphrase
+//
+class QueryUnlock : public QueryPassphrase {
+	static const int maxTries = 3;
+public:
+	QueryUnlock(Database &db) : QueryPassphrase(maxTries), database(db) { }
+	
+	Database &database;
+	
+	void operator () (const AccessCredentials *cred);
+	
+protected:
+	void queryInteractive(CssmOwnedData &passphrase);
+	void retryInteractive(CssmOwnedData &passphrase, Reason reason);
+	Reason accept(CssmManagedData &passphrase, bool canRetry);
+};
+
+
+//
+// A query for a new passphrase
+//
+class QueryNewPassphrase : public QueryPassphrase {
+	static const int maxTries = 7;
+public:
+	QueryNewPassphrase(Database::Common &common, Reason reason)
+	: QueryPassphrase(maxTries), dbCommon(common), initialReason(reason),
+		mPassphrase(CssmAllocator::standard(CssmAllocator::sensitive)),
+        mPassphraseValid(false) { }
+		
+	Database::Common &dbCommon;
+	
+	void operator () (const AccessCredentials *cred, CssmOwnedData &passphrase);
+	
+protected:
+	void queryInteractive(CssmOwnedData &passphrase);
+	void retryInteractive(CssmOwnedData &passphrase, Reason reason);
+	Reason accept(CssmManagedData &passphrase, bool canRetry);
+	
+private:
+	Reason initialReason;
+	CssmAutoData mPassphrase;
+    bool mPassphraseValid;
+};
+
+
+//
+// The "give user/passphrase in group" authorization dialog.
+// This class is not self-contained, since the AuthorizationEngine wants
+// to micro-manage the retry process.
+//
+class QueryAuthorizeByGroup : public SecurityAgentQuery {
+public:
+    QueryAuthorizeByGroup() : mActive(false) { }
+	bool operator () (const char *group, const char *candidateUser,
+        char username[SecurityAgent::maxUsernameLength],
+        char passphrase[SecurityAgent::maxPassphraseLength], 
+        Reason reason = SecurityAgent::userNotInGroup);
+    void cancel(Reason reason);
+    void done();
+    
+    uid_t uid();
+
+private:
+    bool mActive;
+};
+
+
+#endif //_H_PASSPHRASES
diff --git a/SecurityServer/authority.cpp b/SecurityServer/authority.cpp
new file mode 100644
index 00000000..1a236c0e
--- /dev/null
+++ b/SecurityServer/authority.cpp
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ */
+
+
+//
+// authority - authorization manager
+//
+#include "authority.h"
+#include "server.h"
+#include "connection.h"
+#include "session.h"
+#include "process.h"
+
+
+//
+// The global dictionary of extant AuthorizationTokens
+//
+AuthorizationToken::AuthMap AuthorizationToken::authMap; // set of extant authorizations
+Mutex AuthorizationToken::authMapLock; // lock for mAuthorizations (only)
+
+
+//
+// Construct an Authority
+//
+Authority::Authority(const char *configFile)
+: Authorization::Engine(configFile)
+{
+}
+
+Authority::~Authority()
+{
+}
+
+
+//
+// Create an authorization token.
+//
+AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base)
+	: session(ssn), mBaseCreds(base), mTransferCount(INT_MAX),
+	mCreatorUid(Server::connection().process.uid())
+{
+    // generate our (random) handle
+    Server::active().random(mHandle);
+    
+    // register handle in the global map
+    StLock<Mutex> _(authMapLock);
+    authMap[mHandle] = this;
+    
+	// register with parent session
+	session.addAuthorization(this);
+	
+    // all ready
+	debug("SSauth", "Authorization %p created using %d credentials",
+		this, int(mBaseCreds.size()));
+}
+
+AuthorizationToken::~AuthorizationToken()
+{
+	// we better be clean
+	assert(mUsingProcesses.empty());
+    
+    // deregister from parent session
+    if (session.removeAuthorization(this))
+        delete &session;
+    
+	debug("SSauth", "Authorization %p destroyed", this);
+}
+
+
+//
+// Locate an authorization given its blob.
+//
+AuthorizationToken &AuthorizationToken::find(const AuthorizationBlob &blob)
+{
+    StLock<Mutex> _(authMapLock);
+	AuthMap::iterator it = authMap.find(blob);
+	if (it == authMap.end())
+		Authorization::Error::throwMe(errAuthorizationInvalidRef);
+	return *it->second;
+}
+
+
+//
+// Handle atomic deletion of AuthorizationToken objects
+//
+AuthorizationToken::Deleter::Deleter(const AuthorizationBlob &blob)
+    : lock(authMapLock)
+{
+    AuthMap::iterator it = authMap.find(blob);
+    if (it == authMap.end())
+        Authorization::Error::throwMe(errAuthorizationInvalidRef);
+    mAuth = it->second;
+}
+
+void AuthorizationToken::Deleter::remove()
+{
+    if (mAuth) {
+        authMap.erase(mAuth->handle());
+        delete mAuth;
+        mAuth = NULL;
+    }
+}
+
+
+//
+// Given a set of credentials, add it to our private credentials and return the result
+//
+CredentialSet AuthorizationToken::effectiveCreds() const
+{
+	CredentialSet result = session.authCredentials();
+	for (CredentialSet::const_iterator it = mBaseCreds.begin(); it != mBaseCreds.end(); it++)
+		if (!(*it)->isShared())
+			result.insert(*it);
+	return result;
+}
+
+
+//
+// Add more credential dependencies to an authorization
+//
+void AuthorizationToken::mergeCredentials(const CredentialSet &add)
+{
+	for (CredentialSet::const_iterator it = add.begin(); it != add.end(); it++) {
+        mBaseCreds.erase(*it);
+        mBaseCreds.insert(*it);
+    }
+    debug("SSauth", "Authorization %p merged %d new credentials for %d total",
+		this, int(add.size()), int(mBaseCreds.size()));
+}
+
+
+//
+// Register a new process that uses this authorization token.
+// This is an idempotent operation.
+//
+void AuthorizationToken::addProcess(Process &proc)
+{
+	StLock<Mutex> _(mLock);
+	mUsingProcesses.insert(&proc);
+	debug("SSauth", "Authorization %p added process %p(%d)", this, &proc, proc.pid());
+}
+
+
+//
+// Completely unregister client process.
+// It does not matter how often it was registered with addProcess before.
+// This returns true if no more processes use this token. Presumably you
+// would then want to clean up, though that's up to you.
+//
+bool AuthorizationToken::endProcess(Process &proc)
+{
+	StLock<Mutex> _(mLock);
+	assert(mUsingProcesses.find(&proc) != mUsingProcesses.end());
+	mUsingProcesses.erase(&proc);
+	IFDEBUG(debug("SSauth", "Authorization %p removed process %p(%d)%s",
+		this, &proc, proc.pid(), mUsingProcesses.empty() ? " FINAL" : ""));
+	return mUsingProcesses.empty();
+}
+
+
+//
+// Check whether internalization/externalization is allowed
+//
+bool AuthorizationToken::mayExternalize(Process &) const
+{
+	return mTransferCount > 0;
+}
+
+bool AuthorizationToken::mayInternalize(Process &, bool countIt)
+{
+	StLock<Mutex> _(mLock);
+	if (mTransferCount > 0) {
+		if (countIt) {
+			mTransferCount--;
+			debug("SSauth", "Authorization %p decrement intcount to %d", this, mTransferCount);
+		}
+		return true;
+	}
+	return false;
+}
+
+uid_t
+AuthorizationToken::creatorUid() const
+{
+	return mCreatorUid;
+}
+
+//
+// Call the underlying authorize() in a critical region.
+// The engine code is not thread safe.
+//
+
+OSStatus Authority::authorize(const RightSet &inRights, 
+    const AuthorizationEnvironment *environment,
+	AuthorizationFlags flags, const CredentialSet *inCredentials, CredentialSet *outCredentials,
+	MutableRightSet *outRights, const AuthorizationToken &auth)
+{
+	StLock<Mutex> _(mLock);
+	return Authorization::Engine::authorize(inRights, environment,
+		flags, inCredentials, outCredentials, outRights, auth);
+}
+
diff --git a/SecurityServer/authority.h b/SecurityServer/authority.h
new file mode 100644
index 00000000..34979516
--- /dev/null
+++ b/SecurityServer/authority.h
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+//
+// authority - authorization manager
+//
+#ifndef _H_AUTHORITY
+#define _H_AUTHORITY
+
+#include "securityserver.h"
+#include "AuthorizationEngine.h"
+
+
+using Authorization::CredentialSet;
+using Authorization::RightSet;
+using Authorization::MutableRightSet;
+
+
+class Process;
+class Session;
+
+
+class AuthorizationToken {
+public:
+	AuthorizationToken(Session &ssn, const CredentialSet &base);
+	~AuthorizationToken();
+
+    Session &session;
+	
+	const AuthorizationBlob &handle() const		{ return mHandle; }
+	const CredentialSet &baseCreds() const		{ return mBaseCreds; }
+	CredentialSet effectiveCreds() const;
+	
+	typedef CredentialSet::iterator iterator;
+	iterator begin()		{ return mBaseCreds.begin(); }
+	iterator end()			{ return mBaseCreds.end(); }
+	
+	// add more credential dependencies
+	void mergeCredentials(const CredentialSet &more);
+	
+	// maintain process-owning links
+	void addProcess(Process &proc);
+	bool endProcess(Process &proc);
+	
+	// access control for external representations
+	bool mayExternalize(Process &proc) const;
+	bool mayInternalize(Process &proc, bool countIt = true);
+
+	uid_t creatorUid() const;
+public:
+	static AuthorizationToken &find(const AuthorizationBlob &blob);
+    
+    class Deleter {
+    public:
+        Deleter(const AuthorizationBlob &blob);
+        
+        void remove();
+        operator AuthorizationToken &() const	{ return *mAuth; }
+        
+    private:
+        AuthorizationToken *mAuth;
+        StLock<Mutex> lock;
+    };
+
+private:
+	Mutex mLock;					// object lock
+	AuthorizationBlob mHandle;		// official randomized blob marker
+	CredentialSet mBaseCreds;		// credentials we're based on
+	
+	unsigned int mTransferCount;	// number of internalizations remaining
+	
+	typedef set<Process *> ProcessSet;
+	ProcessSet mUsingProcesses;		// set of process objects using this token
+
+	uid_t mCreatorUid;				// Uid of proccess that created this authorization
+
+private:
+	typedef map<AuthorizationBlob, AuthorizationToken *> AuthMap;
+	static AuthMap authMap;			// set of extant authorizations
+    static Mutex authMapLock;		// lock for mAuthorizations (only)
+};
+
+
+//
+// The authority itself. You will usually only have one of these.
+//
+class Authority : public Authorization::Engine {
+public:
+	Authority(const char *configFile);
+	virtual ~Authority();
+
+	OSStatus authorize(const RightSet &inRights, const AuthorizationEnvironment *environment,
+		AuthorizationFlags flags, const CredentialSet *inCredentials, CredentialSet *outCredentials,
+		MutableRightSet *outRights, const AuthorizationToken &auth);
+
+private:
+	Mutex mLock;			// force-single-thread lock for authorize()
+};
+
+
+#endif //_H_AUTHORITY
diff --git a/SecurityServer/cfnotifier.cpp b/SecurityServer/cfnotifier.cpp
new file mode 100644
index 00000000..f473c84b
--- /dev/null
+++ b/SecurityServer/cfnotifier.cpp
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+
+//
+// cfnotifier - quick & dirty code to send keychain lock notification
+//
+#include "cfnotifier.h"
+#include <Security/debugging.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "session.h"
+
+using namespace Security;
+using namespace Security::MachPlusPlus;
+
+
+#define notificationName	CFSTR("com.apple.securitycore.kcevent")
+#define eventTypeKey		CFSTR("type")
+#define keychainKey		CFSTR("keychain")
+#define itekey			CFSTR("item")
+#define keyGUID			CFSTR("GUID")
+#define keySubserviceId	CFSTR("SubserviceId")
+#define keySubserviceType	CFSTR("SubserviceType")
+#define keyDbName		CFSTR("DbName")
+#define keyDbLocation		CFSTR("DbLocation")
+#define keyActive			CFSTR("Active")
+#define keyMajorVersion	CFSTR("MajorVersion")
+#define keyMinorVersion	CFSTR("MinorVersion")
+#define defaultDLDbListKey	 CFSTR("DLDBSearchList")
+#define defaultDomain		CFSTR("com.apple.securitycore")
+
+
+//
+// Event codes
+//
+enum {
+    lockedEvent                = 1,	/* a keychain was locked */
+    unlockedEvent              = 2,	/* a keychain was unlocked */
+	passphraseChangedEvent	   = 6	/* a keychain password was (possibly) changed */
+};
+
+
+//
+// Local functions
+//
+static CFDictionaryRef makeDictionary(const DLDbIdentifier &db);
+
+
+//
+// Main methods
+//
+void KeychainNotifier::lock(const DLDbIdentifier &db)
+{ notify(db, lockedEvent); }
+
+void KeychainNotifier::unlock(const DLDbIdentifier &db)
+{ notify(db, unlockedEvent); }
+
+void KeychainNotifier::passphraseChanged(const DLDbIdentifier &db)
+{ notify(db, passphraseChangedEvent); }
+
+
+//
+// Lock and unlock notifications
+//
+void KeychainNotifier::notify(const DLDbIdentifier &db, int event)
+{
+    CFRef<CFMutableDictionaryRef> mutableDict(::CFDictionaryCreateMutable(
+        kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
+        &kCFTypeDictionaryValueCallBacks));
+    if (!mutableDict)
+        throw std::bad_alloc();
+    
+    SInt32 theEvent = event;
+    CFRef<CFNumberRef> theEventData(::CFNumberCreate( kCFAllocatorDefault,
+        kCFNumberSInt32Type, &theEvent));
+    if (!theEventData)
+        throw std::bad_alloc();
+    ::CFDictionarySetValue( mutableDict, eventTypeKey, theEventData );
+    
+    CFRef<CFDictionaryRef> dict = makeDictionary(db);
+    if (!dict)
+        throw std::bad_alloc();
+    ::CFDictionarySetValue(mutableDict, keychainKey, dict);
+    
+    for (Session::Iterator it = Session::begin(); it != Session::end(); it++) {
+        StBootstrap bootSwitch(it->second->bootstrapPort());
+        IFDEBUG(debug("cfnotify", "send event %d for database %s to session %p",
+            event, db.dbName(), it->second));
+        ::CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(),
+            notificationName, NULL, mutableDict, false);
+    }
+}
+
+static CFDictionaryRef makeDictionary(const DLDbIdentifier &db)
+{
+	CFRef<CFMutableDictionaryRef> aDict(CFDictionaryCreateMutable(kCFAllocatorDefault,0,
+		&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks));
+    if (!aDict)
+        throw std::bad_alloc();
+
+    // Put SUBSERVICE_UID in dictionary
+    char buffer[Guid::stringRepLength+1];
+    const CssmSubserviceUid& ssuid=db.ssuid();
+    const Guid &theGuid = Guid::overlay(ssuid.Guid);
+    CFRef<CFStringRef> stringGuid(::CFStringCreateWithCString(kCFAllocatorDefault,
+            theGuid.toString(buffer),kCFStringEncodingMacRoman));
+    if (stringGuid)
+        ::CFDictionarySetValue(aDict,keyGUID,stringGuid);
+        
+    if (ssuid.SubserviceId!=0)
+    {
+        CFRef<CFNumberRef> subserviceId(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.SubserviceId));
+        if (subserviceId)
+            ::CFDictionarySetValue(aDict,keySubserviceId,subserviceId);
+    }
+    if (ssuid.SubserviceType!=0)
+    {
+        CFRef<CFNumberRef> subserviceType(CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.SubserviceType));
+        if (subserviceType)
+            ::CFDictionarySetValue(aDict,keySubserviceType,subserviceType);
+    }
+    if (ssuid.Version.Major!=0 && ssuid.Version.Minor!=0)
+    {
+        CFRef<CFNumberRef> majorVersion(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.Version.Major));
+        if (majorVersion)
+            ::CFDictionarySetValue(aDict,keyMajorVersion,majorVersion);
+        CFRef<CFNumberRef> minorVersion(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.Version.Minor));
+        if (minorVersion)
+            ::CFDictionarySetValue(aDict,keyMinorVersion,minorVersion);
+    }
+    
+    // Put DbName in dictionary
+	const char *dbName=db.dbName();
+    if (dbName)
+    {
+        CFRef<CFStringRef> theDbName(::CFStringCreateWithCString(kCFAllocatorDefault,dbName,kCFStringEncodingMacRoman));
+        ::CFDictionarySetValue(aDict,keyDbName,theDbName);
+    }
+    // Put DbLocation in dictionary
+	const CSSM_NET_ADDRESS *dbLocation=db.dbLocation();
+    if (dbLocation!=NULL && dbLocation->AddressType!=CSSM_ADDR_NONE)
+    {
+        CFRef<CFDataRef> theData(::CFDataCreate(kCFAllocatorDefault,dbLocation->Address.Data,dbLocation->Address.Length));
+        if (theData)
+            ::CFDictionarySetValue(aDict,keyDbLocation,theData);
+    }
+
+    ::CFRetain(aDict);
+	return aDict;
+}
+
diff --git a/SecurityServer/cfnotifier.h b/SecurityServer/cfnotifier.h
new file mode 100644
index 00000000..4f35bbcd
--- /dev/null
+++ b/SecurityServer/cfnotifier.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+
+//
+// cfnotifier - quick & dirty code to send keychain lock notification
+//
+#ifndef _H_CFNOTIFIER
+#define _H_CFNOTIFIER
+
+#include "securityserver.h"
+
+
+//
+// A KeychainNotifier object can send keychain-related lock state broadcasts.
+//
+class KeychainNotifier {
+public:
+    static void lock(const DLDbIdentifier &db);
+    static void unlock(const DLDbIdentifier &db);
+	static void passphraseChanged(const DLDbIdentifier &db);
+    
+private:
+    static void notify(const DLDbIdentifier &db, int event);
+};
+
+
+#endif //_H_CFNOTIFIER
diff --git a/SecurityServer/connection.cpp b/SecurityServer/connection.cpp
new file mode 100644
index 00000000..610056cc
--- /dev/null
+++ b/SecurityServer/connection.cpp
@@ -0,0 +1,341 @@
+/*
+ * 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.
+ */
+
+
+//
+// connection - manage connections to clients.
+//
+// Note that Connection objects are single-threaded; only one request can be outstanding
+// per connection. The various operational calls (e.g. generateMac) can be called by
+// multiple threads, but each call will be for a different connection (the one the request
+// came in on). Thus, locking happens elsewhere as needed.
+//
+#include "connection.h"
+#include "key.h"
+#include "server.h"
+#include "session.h"
+#include <Security/keyclient.h>
+#include <Security/genkey.h>
+#include <Security/wrapkey.h>
+#include <Security/signclient.h>
+#include <Security/macclient.h>
+#include <Security/cryptoclient.h>
+
+
+//
+// Construct a Connection object.
+//
+Connection::Connection(Process &proc, Port rPort)
+ : process(proc), mClientPort(rPort), state(idle), agentWait(NULL),
+   aclUpdateTrigger(NULL)
+{
+	// bump the send-rights count on the reply port so we keep the right after replying
+	mClientPort.modRefs(MACH_PORT_RIGHT_SEND, +1);
+	
+	debug("SS", "New connection %p for process %d clientport=%d",
+		this, process.pid(), int(rPort));
+}
+
+
+//
+// When a Connection's destructor executes, the connection must already have been
+// terminated. All we have to do here is clean up a bit.
+//
+Connection::~Connection()
+{
+	debug("SS", "Connection %p destroyed", this);
+	assert(!agentWait);
+}
+
+
+//
+// Terminate a Connection normally.
+// This is assumed to be properly sequenced, so no thread races are possible.
+//
+void Connection::terminate()
+{
+	// cleanly discard port rights
+	assert(state == idle);
+	mClientPort.modRefs(MACH_PORT_RIGHT_SEND, -1);	// discard surplus send right
+	assert(mClientPort.getRefs(MACH_PORT_RIGHT_SEND) == 1);	// one left for final reply
+	debug("SS", "Connection %p terminated", this);
+}
+
+
+//
+// Abort a Connection.
+// This may be called from thread A while thread B is working a request for the Connection,
+// so we must be careful.
+//
+bool Connection::abort(bool keepReplyPort)
+{
+	StLock<Mutex> _(lock);
+    if (!keepReplyPort)
+        mClientPort.destroy();		// dead as a doornail already
+	switch (state) {
+	case idle:
+		debug("SS", "Connection %p aborted", this);
+		return true;				// just shoot me
+	case busy:
+		state = dying;				// shoot me soon, please
+		if (agentWait)
+			agentWait->cancel();
+		debug("SS", "Connection %p abort deferred (busy)", this);
+		return false;				// but not quite yet
+	default:
+		assert(false);				// impossible (we hope)
+	}
+}
+
+
+//
+// Service request framing.
+// These are here so "hanging" connection service threads don't fall
+// into the Big Bad Void as Connections and processes drop out from
+// under them.
+//
+void Connection::beginWork()
+{
+	switch (state) {
+	case idle:
+		state = busy;
+		process.beginConnection(*this);
+		break;
+	case busy:
+		debug("SS", "Attempt to re-enter connection %p(port %d)", this, mClientPort.port());
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	//@@@ some state-error code instead?
+	default:
+		assert(false);
+	}
+}
+
+void Connection::checkWork()
+{
+	StLock<Mutex> _(lock);
+	switch (state) {
+	case busy:
+		return;
+	case dying:
+		agentWait = NULL;	// obviously we're not waiting on this
+		throw this;
+	default:
+		assert(false);
+	}
+}
+
+bool Connection::endWork()
+{
+	switch (state) {
+	case busy:
+		// process the n-step aclUpdateTrigger
+		if (aclUpdateTrigger) {
+            if (--aclUpdateTriggerCount == 0) {
+                aclUpdateTrigger = NULL;
+                debug("kcacl", "acl update trigger expires");
+            } else
+                debug("kcacl", "acl update trigger armed for %d calls",
+                    aclUpdateTriggerCount);
+        }
+		// end involvement
+		state = idle;
+		process.endConnection(*this);
+		return false;
+	case dying:
+		debug("SS", "Connection %p abort resuming", this);
+		if (process.endConnection(*this))
+			delete &process;
+		return true;
+	default:
+		assert(false);
+	}
+}
+
+
+//
+// Key creation and release
+//
+void Connection::releaseKey(Key::Handle key)
+{
+	delete &Server::key(key);
+}
+
+
+//
+// Signatures and MACs
+//
+void Connection::generateSignature(const Context &context, Key &key,
+	const CssmData &data, CssmData &signature)
+{
+	context.replace(CSSM_ATTRIBUTE_KEY, (CSSM_KEY &)key);
+	key.validate(CSSM_ACL_AUTHORIZATION_SIGN, context);
+	CssmClient::Sign signer(Server::csp(), context.algorithm());
+	signer.override(context);
+	signer.sign(data, signature);
+}
+
+void Connection::verifySignature(const Context &context, Key &key,
+	const CssmData &data, const CssmData &signature)
+{
+	context.replace(CSSM_ATTRIBUTE_KEY, (CSSM_KEY &)key);
+	CssmClient::Verify verifier(Server::csp(), context.algorithm());
+	verifier.override(context);
+	verifier.verify(data, signature);
+}
+
+void Connection::generateMac(const Context &context, Key &key,
+	const CssmData &data, CssmData &mac)
+{
+	context.replace(CSSM_ATTRIBUTE_KEY, (CSSM_KEY &)key);
+	key.validate(CSSM_ACL_AUTHORIZATION_MAC, context);
+	CssmClient::GenerateMac signer(Server::csp(), context.algorithm());
+	signer.override(context);
+	signer.sign(data, mac);
+}
+
+void Connection::verifyMac(const Context &context, Key &key,
+	const CssmData &data, const CssmData &mac)
+{
+	context.replace(CSSM_ATTRIBUTE_KEY, (CSSM_KEY &)key);
+	key.validate(CSSM_ACL_AUTHORIZATION_MAC, context);
+	CssmClient::VerifyMac verifier(Server::csp(), context.algorithm());
+	verifier.override(context);
+	verifier.verify(data, mac);
+}
+
+
+//
+// Encryption/decryption
+//
+void Connection::encrypt(const Context &context, Key &key,
+	const CssmData &clear, CssmData &cipher)
+{
+	context.replace(CSSM_ATTRIBUTE_KEY, (CSSM_KEY &)key);
+	key.validate(CSSM_ACL_AUTHORIZATION_ENCRYPT, context);
+	CssmClient::Encrypt cryptor(Server::csp(), context.algorithm());
+	cryptor.override(context);
+	CssmData remData;
+	size_t totalLength = cryptor.encrypt(clear, cipher, remData);
+	// shouldn't need remData - if an algorithm REQUIRES this, we'd have to ship it
+	if (remData)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+	cipher.length(totalLength);
+}
+
+void Connection::decrypt(const Context &context, Key &key,
+	const CssmData &cipher, CssmData &clear)
+{
+	context.replace(CSSM_ATTRIBUTE_KEY, (CSSM_KEY &)key);
+	key.validate(CSSM_ACL_AUTHORIZATION_DECRYPT, context);
+	CssmClient::Decrypt cryptor(Server::csp(), context.algorithm());
+	cryptor.override(context);
+	CssmData remData;
+	size_t totalLength = cryptor.decrypt(cipher, clear, remData);
+	// shouldn't need remData - if an algorithm REQUIRES this, we'd have to ship it
+	if (remData)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+	clear.length(totalLength);
+}
+
+
+//
+// Key generation.
+// Currently, we consider symmetric key generation to be fast, but
+// asymmetric key generation to be (potentially) slow.
+//
+void Connection::generateKey(Database *db, const Context &context,
+		const AccessCredentials *cred, const AclEntryPrototype *owner,
+		uint32 usage, uint32 attrs, Key * &newKey)
+{
+	// prepare a context
+	CssmClient::GenerateKey generate(Server::csp(), context.algorithm());
+	generate.override(context);
+	
+	// generate key
+	// @@@ turn "none" return into reference if permanent (only)
+	CssmKey key;
+	generate(key, CssmClient::KeySpec(usage, attrs & ~Key::managedAttributes));
+		
+	// register and return the generated key
+    newKey = new Key(db, key, attrs & Key::managedAttributes, owner);
+}
+
+void Connection::generateKey(Database *db, const Context &context,
+	const AccessCredentials *cred, const AclEntryPrototype *owner,
+	uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs,
+    Key * &publicKey, Key * &privateKey)
+{
+	// prepare a context
+	CssmClient::GenerateKey generate(Server::csp(), context.algorithm());
+	generate.override(context);
+	
+	// this may take a while; let our server object know
+	Server::active().longTermActivity();
+	
+	// generate keys
+	// @@@ turn "none" return into reference if permanent (only)
+	CssmKey pubKey, privKey;
+	generate(pubKey, CssmClient::KeySpec(pubUsage, pubAttrs & ~Key::managedAttributes),
+		privKey, CssmClient::KeySpec(privUsage, privAttrs & ~Key::managedAttributes));
+		
+	// register and return the generated keys
+	publicKey = new Key(db, pubKey, pubAttrs & Key::managedAttributes, owner);
+	privateKey = new Key(db, privKey, privAttrs & Key::managedAttributes, owner);
+}
+
+
+//
+// Key wrapping and unwrapping.
+// Note that the key argument (the key in the context) is optional because of the special
+// case of "cleartext" (null algorithm) wrapping for import/export.
+//
+void Connection::wrapKey(const Context &context, Key *key,
+    Key &keyToBeWrapped, const AccessCredentials *cred,
+    const CssmData &descriptiveData, CssmKey &wrappedKey)
+{
+    keyToBeWrapped.validate(context.algorithm() == CSSM_ALGID_NONE ?
+            CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR : CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED,
+        cred);
+    if (key)
+        context.replace(CSSM_ATTRIBUTE_KEY, (CSSM_KEY &)*key);
+    CssmClient::WrapKey wrap(Server::csp(), context.algorithm());
+    wrap.override(context);
+    wrap.cred(const_cast<AccessCredentials *>(cred));	//@@@ const madness - fix in client/pod
+    wrap(keyToBeWrapped, wrappedKey, &descriptiveData);
+}
+
+Key &Connection::unwrapKey(Database *db, const Context &context, Key *key,
+	const AccessCredentials *cred, const AclEntryPrototype *owner,
+	uint32 usage, uint32 attrs, const CssmKey wrappedKey,
+    Key *publicKey, CssmData *descriptiveData)
+{
+    if (key)
+        context.replace(CSSM_ATTRIBUTE_KEY, (CSSM_KEY &)*key);
+    CssmClient::UnwrapKey unwrap(Server::csp(), context.algorithm());
+    unwrap.override(context);
+    CssmKey unwrappedKey;
+    unwrap.cred(const_cast<AccessCredentials *>(cred));	//@@@ const madness - fix in client/pod
+    if (owner) {
+        AclEntryInput ownerInput(*owner);	//@@@ const trouble - fix in client/pod
+        unwrap.aclEntry(ownerInput);
+    }
+
+    // @@@ Invoking conversion operator to CssmKey & on *publicKey and take the address of the result.
+    unwrap(wrappedKey, CssmClient::KeySpec(usage, attrs), unwrappedKey,
+        descriptiveData, publicKey ? &static_cast<CssmKey &>(*publicKey) : NULL);
+
+    return *new Key(db, unwrappedKey, attrs & Key::managedAttributes, owner);
+}
diff --git a/SecurityServer/connection.h b/SecurityServer/connection.h
new file mode 100644
index 00000000..5265213e
--- /dev/null
+++ b/SecurityServer/connection.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+
+//
+// connection - manage connections to clients
+//
+#ifndef _H_CONNECTION
+#define _H_CONNECTION
+
+#include "securityserver.h"
+#include "SecurityAgentClient.h"
+#include <Security/osxsigning.h>
+#include "process.h"
+#include "key.h"
+#include <string>
+
+using MachPlusPlus::Port;
+using MachPlusPlus::TaskPort;
+
+class Session;
+
+
+//
+// A Connection object represents an established connection between a client
+// and the SecurityServer. Note that in principle, a client process can have
+// multiple Connections (each represented by an IPC channel), though there will
+// usually be only one.
+//
+class Connection {
+	typedef Key::Handle KeyHandle;
+public:
+	Connection(Process &proc, Port rPort);
+	virtual ~Connection();
+	void terminate();		// normal termination
+	bool abort(bool keepReplyPort = false); // abnormal termination
+	
+    Port clientPort() const	{ return mClientPort; }
+
+	// work framing - called as work threads pick up connection work
+	void beginWork();		// I've got it
+	void checkWork();		// everything still okay?
+	bool endWork();			// Done with this
+	
+	// notify that a SecurityAgent call may hang the active worker thread for a while
+	void useAgent(SecurityAgent::Client *client)
+	{ StLock<Mutex> _(lock); agentWait = client; }
+	
+	// special UI convenience - set a don't-ask-again trigger for Keychain-style ACLs
+	void setAclUpdateTrigger(const SecurityServerAcl &object)
+	{ aclUpdateTrigger = &object; aclUpdateTriggerCount = aclUpdateTriggerLimit + 1; }
+	bool aclWasSetForUpdateTrigger(const SecurityServerAcl &object) const
+	{ return aclUpdateTriggerCount > 0 && aclUpdateTrigger == &object; }
+
+	Process &process;
+	
+public:
+	void releaseKey(KeyHandle key);
+	
+	// service calls
+	void generateSignature(const Context &context, Key &key,
+		const CssmData &data, CssmData &signature);
+	void verifySignature(const Context &context, Key &key,
+		const CssmData &data, const CssmData &signature);
+	void generateMac(const Context &context, Key &key,
+		const CssmData &data, CssmData &mac);
+	void verifyMac(const Context &context, Key &key,
+		const CssmData &data, const CssmData &mac);
+	
+	void encrypt(const Context &context, Key &key, const CssmData &clear, CssmData &cipher);
+	void decrypt(const Context &context, Key &key, const CssmData &cipher, CssmData &clear);
+	
+	void generateKey(Database *db, const Context &context,
+		const AccessCredentials *cred, const AclEntryPrototype *owner,
+		uint32 usage, uint32 attrs, Key * &newKey);
+	void generateKey(Database *db, const Context &context,
+		const AccessCredentials *cred, const AclEntryPrototype *owner,
+		uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs,
+		Key * &publicKey, Key * &privateKey);
+
+    void wrapKey(const Context &context, Key *key,
+        Key &keyToBeWrapped, const AccessCredentials *cred,
+        const CssmData &descriptiveData, CssmKey &wrappedKey);
+	Key &unwrapKey(Database *db, const Context &context, Key *key,
+		const AccessCredentials *cred, const AclEntryPrototype *owner,
+		uint32 usage, uint32 attrs, const CssmKey wrappedKey,
+        Key *publicKey, CssmData *descriptiveData);
+
+private:
+	// peer state: established during connection startup; fixed thereafter
+	Port mClientPort;
+	
+	// transient state (altered as we go)
+	Mutex lock;
+	enum State {
+		idle,					// no thread services us
+		busy,					// a thread is busy servicing us
+		dying					// busy and scheduled to die as soon as possible
+	} state;
+	SecurityAgent::Client *agentWait;	// SA client session we may be waiting on
+	
+	// see KeychainPromptAclSubject in acl_keychain.cpp for more information on this
+	const SecurityServerAcl *aclUpdateTrigger; // update trigger set for this (NULL if none)
+    uint8 aclUpdateTriggerCount; // number of back-to-back requests honored
+    static const uint8 aclUpdateTriggerLimit = 2;	// two subsequent calls (getAcl + changeAcl)
+};
+
+
+#endif //_H_CONNECTION
diff --git a/SecurityServer/dbcrypto.cpp b/SecurityServer/dbcrypto.cpp
new file mode 100644
index 00000000..09c99a7f
--- /dev/null
+++ b/SecurityServer/dbcrypto.cpp
@@ -0,0 +1,375 @@
+/*
+ * 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.
+ */
+
+
+//
+// dbcrypto - cryptographic core for database and key blob cryptography
+//
+#include "dbcrypto.h"
+#include "ssblob.h"
+#include "server.h"		// just for Server::csp()
+#include <Security/genkey.h>
+#include <Security/cryptoclient.h>
+#include <Security/keyclient.h>
+#include <Security/macclient.h>
+#include <Security/wrapkey.h>
+
+
+using namespace CssmClient;
+
+
+DatabaseCryptoCore::DatabaseCryptoCore() : mIsValid(false)
+{
+}
+
+
+DatabaseCryptoCore::~DatabaseCryptoCore()
+{
+    // key objects take care of themselves
+}
+
+
+//
+// Generate new secrets for this crypto core.
+//
+void DatabaseCryptoCore::generateNewSecrets()
+{
+    // create a random DES3 key
+    GenerateKey desGenerator(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE, 24 * 8);
+    encryptionKey = desGenerator(KeySpec(CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP,
+        CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE));
+    
+    // create a random 20 byte HMAC1/SHA1 signing "key"
+    GenerateKey signGenerator(Server::csp(), CSSM_ALGID_SHA1HMAC,
+        sizeof(DbBlob::PrivateBlob::signingKey) * 8);
+    signingKey = signGenerator(KeySpec(CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY,
+        CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE));
+    
+    // secrets established
+    mIsValid = true;
+}
+
+
+//
+// Encode a database blob from the core.
+//
+DbBlob *DatabaseCryptoCore::encodeCore(const DbBlob &blobTemplate,
+    const CssmData &passphrase,
+    const CssmData &publicAcl, const CssmData &privateAcl) const
+{
+    assert(isValid());		// must have secrets to work from
+
+    // make a new salt and IV
+    uint8 salt[20];
+    Server::active().random(salt);
+    uint8 iv[8];
+    Server::active().random(iv);
+    
+    // derive blob encryption key
+    CssmClient::Key blobCryptKey = deriveDbCryptoKey(passphrase,
+        CssmData(salt, sizeof(salt)));
+    
+    // build the encrypted section blob
+    CssmData &encryptionBits = *encryptionKey;
+    CssmData &signingBits = *signingKey;
+    CssmData incrypt[3];
+    incrypt[0] = encryptionBits;
+    incrypt[1] = signingBits;
+    incrypt[2] = privateAcl;
+    CssmData cryptoBlob, remData;
+    Encrypt cryptor(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE);
+    cryptor.mode(CSSM_ALGMODE_CBCPadIV8);
+    cryptor.padding(CSSM_PADDING_PKCS1);
+    cryptor.key(blobCryptKey);
+    CssmData ivd(iv, sizeof(iv)); cryptor.initVector(ivd);
+    cryptor.encrypt(incrypt, 3, &cryptoBlob, 1, remData);
+    
+    // allocate the final DbBlob, uh, blob
+    size_t length = sizeof(DbBlob) + publicAcl.length() + cryptoBlob.length();
+    DbBlob *blob = CssmAllocator::standard().malloc<DbBlob>(length);
+    
+    // assemble the DbBlob
+    memset(blob, 0x7d, sizeof(DbBlob));	// deterministically fill any alignment gaps
+    blob->initialize();
+    blob->randomSignature = blobTemplate.randomSignature;
+    blob->sequence = blobTemplate.sequence;
+    blob->params = blobTemplate.params;
+    memcpy(blob->salt, salt, sizeof(salt));
+    memcpy(blob->iv, iv, sizeof(iv));
+    memcpy(blob->publicAclBlob(), publicAcl, publicAcl.length());
+    blob->startCryptoBlob = sizeof(DbBlob) + publicAcl.length();
+    memcpy(blob->cryptoBlob(), cryptoBlob, cryptoBlob.length());
+    blob->totalLength = blob->startCryptoBlob + cryptoBlob.length();
+    
+    // sign the blob
+    CssmData signChunk[] = {
+		CssmData(blob->data(), offsetof(DbBlob, blobSignature)),
+		CssmData(blob->publicAclBlob(), publicAcl.length() + cryptoBlob.length())
+	};
+    CssmData signature(blob->blobSignature, sizeof(blob->blobSignature));
+    GenerateMac signer(Server::csp(), CSSM_ALGID_SHA1HMAC_LEGACY);	//@@@!!! CRUD
+    signer.key(signingKey);
+    signer.sign(signChunk, 2, signature);
+    assert(signature.length() == sizeof(blob->blobSignature));
+    
+    // all done. Clean up
+    Server::csp()->allocator().free(cryptoBlob);
+    return blob;
+}
+
+
+//
+// Decode a database blob into the core.
+// Returns false if the decoding fails.
+//
+void DatabaseCryptoCore::decodeCore(DbBlob *blob, const CssmData &passphrase,
+    void **privateAclBlob)
+{
+    // derive blob encryption key
+    CssmClient::Key blobCryptKey = deriveDbCryptoKey(passphrase,
+        CssmData(blob->salt, sizeof(blob->salt)));
+    
+    // try to decrypt the cryptoblob section
+    Decrypt decryptor(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE);
+    decryptor.mode(CSSM_ALGMODE_CBCPadIV8);
+    decryptor.padding(CSSM_PADDING_PKCS1);
+    decryptor.key(blobCryptKey);
+    CssmData ivd(blob->iv, sizeof(blob->iv)); decryptor.initVector(ivd);
+    CssmData cryptoBlob(blob->cryptoBlob(), blob->cryptoBlobLength());
+    CssmData decryptedBlob, remData;
+    decryptor.decrypt(cryptoBlob, decryptedBlob, remData);
+    DbBlob::PrivateBlob *privateBlob = decryptedBlob.interpretedAs<DbBlob::PrivateBlob>();
+    
+    // tentatively establish keys
+    CssmClient::Key encryptionKey = makeRawKey(privateBlob->encryptionKey,
+        sizeof(privateBlob->encryptionKey), CSSM_ALGID_3DES_3KEY_EDE,
+        CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP);
+    CssmClient::Key signingKey = makeRawKey(privateBlob->signingKey,
+        sizeof(privateBlob->signingKey), CSSM_ALGID_SHA1HMAC,
+        CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY);
+    
+    // verify signature on the whole blob
+    CssmData signChunk[] = {
+		CssmData(blob->data(), offsetof(DbBlob, blobSignature)),
+    	CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
+	};
+    CSSM_ALGORITHMS verifyAlgorithm = CSSM_ALGID_SHA1HMAC;
+#if defined(COMPAT_OSX_10_0)
+    if (blob->version == blob->version_MacOS_10_0)
+        verifyAlgorithm = CSSM_ALGID_SHA1HMAC_LEGACY;	// BSafe bug compatibility
+#endif
+    VerifyMac verifier(Server::csp(), verifyAlgorithm);
+    verifier.key(signingKey);
+    verifier.verify(signChunk, 2, CssmData(blob->blobSignature, sizeof(blob->blobSignature)));
+    
+    // all checks out; start extracting fields
+    this->encryptionKey = encryptionKey;
+    this->signingKey = signingKey;
+    if (privateAclBlob) {
+        // extract private ACL blob as a separately allocated area
+        uint32 blobLength = decryptedBlob.length() - sizeof(DbBlob::PrivateBlob);
+        *privateAclBlob = CssmAllocator::standard().malloc(blobLength);
+        memcpy(*privateAclBlob, privateBlob->privateAclBlob(), blobLength);
+    }
+        
+    // secrets have been established
+    mIsValid = true;
+    CssmAllocator::standard().free(privateBlob);
+}
+
+
+//
+// Encode a key blob
+//
+KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey,
+    const CssmData &publicAcl, const CssmData &privateAcl) const
+{
+    assert(isValid());		// need our database secrets
+    
+    // create new IV
+    uint8 iv[8];
+    Server::active().random(iv);
+    
+    // extract and hold some header bits the CSP does not want to see
+    CssmKey key = inKey;
+    uint32 heldAttributes = key.attributes() & managedAttributes;
+    key.clearAttribute(managedAttributes);
+    
+    // use a CMS wrap to encrypt the key
+    WrapKey wrap(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE);
+    wrap.key(encryptionKey);
+    wrap.mode(CSSM_ALGMODE_CBCPadIV8);
+    wrap.padding(CSSM_PADDING_PKCS1);
+    CssmData ivd(iv, sizeof(iv)); wrap.initVector(ivd);
+    wrap.add(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT,
+        uint32(CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM));
+    CssmKey wrappedKey;
+    wrap(key, wrappedKey, &privateAcl);
+    
+    // stick the held attribute bits back in
+    key.setAttribute(heldAttributes);
+    
+    // allocate the final KeyBlob, uh, blob
+    size_t length = sizeof(KeyBlob) + publicAcl.length() + wrappedKey.length();
+    KeyBlob *blob = CssmAllocator::standard().malloc<KeyBlob>(length);
+    
+    // assemble the KeyBlob
+    memset(blob, 0, sizeof(KeyBlob));	// fill alignment gaps
+    blob->initialize();
+    memcpy(blob->iv, iv, sizeof(iv));
+    blob->header = key.header();
+    blob->wrappedHeader.blobType = wrappedKey.blobType();
+    blob->wrappedHeader.blobFormat = wrappedKey.blobFormat();
+    blob->wrappedHeader.wrapAlgorithm = wrappedKey.wrapAlgorithm();
+    blob->wrappedHeader.wrapMode = wrappedKey.wrapMode();
+    memcpy(blob->publicAclBlob(), publicAcl, publicAcl.length());
+    blob->startCryptoBlob = sizeof(KeyBlob) + publicAcl.length();
+    memcpy(blob->cryptoBlob(), wrappedKey.data(), wrappedKey.length());
+    blob->totalLength = blob->startCryptoBlob + wrappedKey.length();
+    
+    // sign the blob
+    CssmData signChunk[] = {
+		CssmData(blob->data(), offsetof(KeyBlob, blobSignature)),
+    	CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
+	};
+    CssmData signature(blob->blobSignature, sizeof(blob->blobSignature));
+    GenerateMac signer(Server::csp(), CSSM_ALGID_SHA1HMAC_LEGACY);	//@@@!!! CRUD
+    signer.key(signingKey);
+    signer.sign(signChunk, 2, signature);
+    assert(signature.length() == sizeof(blob->blobSignature));
+    
+    // all done. Clean up
+    Server::csp()->allocator().free(wrappedKey);
+    return blob;
+}
+
+
+//
+// Decode a key blob
+//
+void DatabaseCryptoCore::decodeKeyCore(KeyBlob *blob,
+    CssmKey &key, void * &pubAcl, void * &privAcl) const
+{
+    assert(isValid());		// need our database secrets
+    
+    // Assemble the encrypted blob as a CSSM "wrapped key"
+    CssmKey wrappedKey;
+    wrappedKey.KeyHeader = blob->header;
+    wrappedKey.blobType(blob->wrappedHeader.blobType);
+    wrappedKey.blobFormat(blob->wrappedHeader.blobFormat);
+    wrappedKey.wrapAlgorithm(blob->wrappedHeader.wrapAlgorithm);
+    wrappedKey.wrapMode(blob->wrappedHeader.wrapMode);
+    wrappedKey.KeyData = CssmData(blob->cryptoBlob(), blob->cryptoBlobLength());
+
+    // verify signature (check against corruption)
+    CssmData signChunk[] = {
+    	CssmData::wrap(blob, offsetof(KeyBlob, blobSignature)),
+    	CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
+	};
+    CSSM_ALGORITHMS verifyAlgorithm = CSSM_ALGID_SHA1HMAC;
+#if defined(COMPAT_OSX_10_0)
+    if (blob->version == blob->version_MacOS_10_0)
+        verifyAlgorithm = CSSM_ALGID_SHA1HMAC_LEGACY;	// BSafe bug compatibility
+#endif
+    VerifyMac verifier(Server::csp(), verifyAlgorithm);
+    verifier.key(signingKey);
+    CssmData signature(blob->blobSignature, sizeof(blob->blobSignature));
+    verifier.verify(signChunk, 2, signature);
+    
+    // extract and hold some header bits the CSP does not want to see
+    uint32 heldAttributes = blob->header.attributes() & managedAttributes;
+   
+    // decrypt the key using an unwrapping operation
+    UnwrapKey unwrap(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE);
+    unwrap.key(encryptionKey);
+    unwrap.mode(CSSM_ALGMODE_CBCPadIV8);
+    unwrap.padding(CSSM_PADDING_PKCS1);
+    CssmData ivd(blob->iv, sizeof(blob->iv)); unwrap.initVector(ivd);
+    unwrap.add(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT,
+        uint32(CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM));
+    CssmData privAclData;
+    wrappedKey.clearAttribute(managedAttributes);    //@@@ shouldn't be needed(?)
+    unwrap(wrappedKey,
+        KeySpec(blob->header.usage(), blob->header.attributes() & ~managedAttributes),
+        key, &privAclData);
+    
+    // compare retrieved key headers with blob headers (sanity check)
+    // @@@ this should probably be checked over carefully
+    CssmKey::Header &real = key.header();
+    CssmKey::Header &incoming = blob->header;
+    if (real.HeaderVersion != incoming.HeaderVersion ||
+        real.cspGuid() != incoming.cspGuid() ||
+        real.blobFormat() != incoming.blobFormat())
+        CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+    if (real.algorithm() != incoming.algorithm())
+        CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
+        
+    // re-insert held bits
+    key.header().KeyAttr |= heldAttributes;
+    
+    // got a valid key: return the pieces
+    pubAcl = blob->publicAclBlob();		// points into blob (shared)
+    privAcl = privAclData;				// was allocated by CSP decrypt
+    // key was set by unwrap operation
+}
+
+
+//
+// Derive the blob-specific database blob encryption key from the passphrase and the salt.
+//
+CssmClient::Key DatabaseCryptoCore::deriveDbCryptoKey(const CssmData &passphrase,
+    const CssmData &salt) const
+{
+    // derive an encryption key and IV from passphrase and salt
+    CssmClient::DeriveKey makeKey(Server::csp(),
+        CSSM_ALGID_PKCS5_PBKDF2, CSSM_ALGID_3DES_3KEY_EDE, 24 * 8);
+    makeKey.iterationCount(1000);
+    makeKey.salt(salt);
+    CSSM_PKCS5_PBKDF2_PARAMS params;
+    params.Passphrase = passphrase;
+    params.PseudoRandomFunction = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
+	CssmData paramData = CssmData::wrap(params);
+    return makeKey(&paramData, KeySpec(CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+        CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE));
+}
+
+
+//
+// Turn raw keybits into a symmetric key in the CSP
+//
+CssmClient::Key DatabaseCryptoCore::makeRawKey(void *data, size_t length,
+    CSSM_ALGORITHMS algid, CSSM_KEYUSE usage)
+{
+    // build a fake key
+    CssmKey key;
+    key.header().BlobType = CSSM_KEYBLOB_RAW;
+    key.header().Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
+    key.header().AlgorithmId = algid;
+    key.header().KeyClass = CSSM_KEYCLASS_SESSION_KEY;
+    key.header().KeyUsage = usage;
+    key.header().KeyAttr = 0;
+    key.KeyData = CssmData(data, length);
+    
+    // unwrap it into the CSP (but keep it raw)
+    UnwrapKey unwrap(Server::csp(), CSSM_ALGID_NONE);
+    CssmKey unwrappedKey;
+    CssmData descriptiveData;
+    unwrap(key,
+        KeySpec(CSSM_KEYUSE_ANY, CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE),
+        unwrappedKey, &descriptiveData, NULL);
+    return CssmClient::Key(Server::csp(), unwrappedKey);
+}
diff --git a/SecurityServer/dbcrypto.h b/SecurityServer/dbcrypto.h
new file mode 100644
index 00000000..64867115
--- /dev/null
+++ b/SecurityServer/dbcrypto.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+
+//
+// dbcrypto - cryptographic core for database and key blob cryptography
+//
+#ifndef _H_DBCRYPTO
+#define _H_DBCRYPTO
+
+#include "securityserver.h"
+#include <Security/cspclient.h>
+#include <Security/keyclient.h>
+
+
+//
+// A DatabaseCryptoCore object encapsulates the secret state of a database.
+// It provides for encoding and decoding of database blobs and key blobs,
+// and holds all state related to the database secrets.
+//
+class DatabaseCryptoCore {
+public:
+    DatabaseCryptoCore();
+	virtual ~DatabaseCryptoCore();
+    
+    bool isValid() const	{ return mIsValid; }
+    
+    void generateNewSecrets();
+
+    DbBlob *encodeCore(const DbBlob &blobTemplate, const CssmData &passphrase,
+        const CssmData &publicAcl, const CssmData &privateAcl) const;
+    void decodeCore(DbBlob *blob, const CssmData &passphrase,
+        void **privateAclBlob = NULL);
+        
+    KeyBlob *encodeKeyCore(const CssmKey &key,
+        const CssmData &publicAcl, const CssmData &privateAcl) const;
+    void decodeKeyCore(KeyBlob *blob,
+        CssmKey &key, void * &pubAcl, void * &privAcl) const;
+    
+    static const uint32 managedAttributes = KeyBlob::managedAttributes;
+	
+private:
+    bool mIsValid;					// master secrets are valid
+    
+    CssmClient::Key encryptionKey;	// master encryption key
+    CssmClient::Key signingKey;		// master signing key
+
+    CssmClient::Key deriveDbCryptoKey(const CssmData &passphrase, const CssmData &salt) const;
+    CssmClient::Key makeRawKey(void *data, size_t length,
+        CSSM_ALGORITHMS algid, CSSM_KEYUSE usage);
+};
+
+
+#endif //_H_DBCRYPTO
diff --git a/SecurityServer/key.cpp b/SecurityServer/key.cpp
new file mode 100644
index 00000000..f5656263
--- /dev/null
+++ b/SecurityServer/key.cpp
@@ -0,0 +1,257 @@
+/*
+ * 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.
+ */
+
+
+//
+// key - representation of SecurityServer key objects
+//
+#include "key.h"
+#include "server.h"
+#include "xdatabase.h"
+#include <Security/acl_any.h>
+
+
+//
+// Create a Key object from a database-encoded blob.
+// Note that this doesn't decode the blob (yet).
+//
+Key::Key(Database &db, const KeyBlob *blob)
+: SecurityServerAcl(keyAcl, CssmAllocator::standard())
+{
+    // perform basic validation on the incoming blob
+	assert(blob);
+    blob->validate(CSSMERR_APPLEDL_INVALID_KEY_BLOB);
+    switch (blob->version) {
+#if defined(COMPAT_OSX_10_0)
+    case blob->version_MacOS_10_0:
+        break;
+#endif
+    case blob->version_MacOS_10_1:
+        break;
+    default:
+        CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB);
+    }
+
+    // set it up
+	mDatabase = &db;
+    mBlob = blob->copy(CssmAllocator::standard());
+    mAttributes = 0;
+	mValidBlob = true;
+	mValidKey = false;
+    mValidUID = false;
+    debug("SSkey", "%p created from blob version %lx", this, blob->version);
+}
+
+
+//
+// Create a Key from an explicit CssmKey.
+//
+Key::Key(Database *db, const CssmKey &newKey, uint32 moreAttributes,
+	const AclEntryPrototype *owner)
+: SecurityServerAcl(keyAcl, CssmAllocator::standard())
+{
+	if (moreAttributes & CSSM_KEYATTR_PERMANENT) {
+		// better have a database to make it permanent in...
+		if (!db)
+			CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE);
+	} else {
+		// non-permanent; ignore database
+		db = NULL;
+	}
+
+	mDatabase = db;
+	mValidKey = true;
+    mBlob = NULL;
+	mValidBlob = false;
+    mValidUID = false;
+	setup(newKey, moreAttributes);
+	
+	// establish initial ACL
+	if (owner)
+		cssmSetInitial(*owner);
+	else
+		cssmSetInitial(new AnyAclSubject());
+    debug("SSkey", "%p created from key alg=%ld use=0x%lx attr=0x%lx",
+        this, mKey.algorithm(), mKey.usage(), mAttributes);
+}
+
+
+//
+// Set up the CssmKey part of this Key according to instructions.
+//
+void Key::setup(const CssmKey &newKey, uint32 moreAttributes)
+{
+    CssmKey::Header &header = mKey.header();
+    
+	// copy key header
+	header = newKey.header();
+    mAttributes = header.attributes() | moreAttributes;
+	
+	// apply initial values of derived attributes (these are all in managedAttributes)
+    if (!(mAttributes & CSSM_KEYATTR_EXTRACTABLE))
+        mAttributes |= CSSM_KEYATTR_NEVER_EXTRACTABLE;
+    if (mAttributes & CSSM_KEYATTR_SENSITIVE)
+        mAttributes |= CSSM_KEYATTR_ALWAYS_SENSITIVE;
+
+    // verify internal/external attribute separation
+    assert(!(header.attributes() & managedAttributes));
+
+	// copy key data field @@@ crud - replace after MM reorg
+	mKey.KeyData = CssmData(memcpy(malloc(newKey.length()), newKey.data(), newKey.length()), newKey.length());
+}
+
+
+Key::~Key()
+{
+    CssmAllocator::standard().free(mBlob);
+    if (mValidKey)
+        Server::csp()->freeKey(mKey);
+    debug("SSkey", "%p destroyed", this);
+}
+
+
+//
+// Retrieve the actual CssmKey value for the key object.
+// This will decode its blob if needed (and appropriate).
+//
+CssmKey &Key::keyValue()
+{
+    decode();
+    return mKey;
+}
+
+
+//
+// Ensure that a key is fully decoded.
+// This makes the mKey key value available for use, as well as its ACL.
+//
+void Key::decode()
+{
+	if (!mValidKey) {
+		assert(mDatabase);	// have to have a database (to decode the blob)
+		assert(mValidBlob);	// must have a blob to decode
+        
+        // decode the key
+        void *publicAcl, *privateAcl;
+        database()->decodeKey(mBlob, mKey, publicAcl, privateAcl);
+        importBlob(publicAcl, privateAcl);
+        // publicAcl points into the blob; privateAcl was allocated for us
+        CssmAllocator::standard().free(privateAcl);
+        
+        // extract managed attribute bits
+        mAttributes = mKey.attributes() & managedAttributes;
+        mKey.clearAttribute(managedAttributes);
+
+        // key is valid now
+		mValidKey = true;
+	}
+}
+
+
+//
+// Retrieve the header (only) of a key.
+// This is taking the clear header from the blob *without* verifying it.
+//
+CssmKey::Header &Key::keyHeader()
+{
+    if (mValidKey) {
+        return mKey.header();
+    } else {
+        assert(mValidBlob);
+        return mBlob->header;
+    }
+}
+
+
+//
+// Return a key's handle and header in external form
+//
+void Key::returnKey(Handle &h, CssmKey::Header &hdr)
+{
+    // return handle
+    h = handle();
+    
+    // return header with external attributes merged
+    hdr = keyHeader();
+    hdr.setAttribute(mAttributes);
+}
+
+
+//
+// Encode a key into a blob.
+// We'll have to ask our Database to do this - we don't have its keys.
+// Note that this returns memory we own and keep.
+//
+KeyBlob *Key::blob()
+{
+	if (mDatabase == NULL)	// can't encode independent keys
+		CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE);
+	if (!mValidBlob) {
+        assert(mValidKey);		// must have valid key to encode
+		//@@@ release mBlob memory here
+
+        // export Key ACL to blob form
+        CssmData pubAcl, privAcl;
+        exportBlob(pubAcl, privAcl);
+        
+        // assemble external key form
+        CssmKey externalKey = mKey;
+        externalKey.setAttribute(mAttributes);
+
+        // encode the key and replace blob
+        KeyBlob *newBlob = database()->encodeKey(externalKey, pubAcl, privAcl);
+        CssmAllocator::standard().free(mBlob);
+        mBlob = newBlob;
+        mValidBlob = true;
+    
+        // clean up and go
+        database()->allocator.free(pubAcl);
+        database()->allocator.free(privAcl);
+	}
+	return mBlob;
+}
+
+
+//
+// Return the UID of a key (the hash of its bits)
+//
+KeyUID &Key::uid()
+{
+    if (!mValidUID) {
+        //@@@ calculate UID here
+        memset(&mUID, 0, sizeof(mUID));
+        mValidUID = true;
+    }
+    return mUID;
+}
+
+
+//
+// Intercept ACL change requests and reset blob validity
+//
+void Key::instantiateAcl()
+{
+	decode();
+}
+
+void Key::noticeAclChange()
+{
+	mValidBlob = false;
+}
+
+const Database *Key::relatedDatabase() const
+{ return database(); }
diff --git a/SecurityServer/key.h b/SecurityServer/key.h
new file mode 100644
index 00000000..edc7557b
--- /dev/null
+++ b/SecurityServer/key.h
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+
+//
+// key - representation of SecurityServer key objects
+//
+#ifndef _H_KEY
+#define _H_KEY
+
+#include "securityserver.h"
+#include "acls.h"
+#include <Security/utilities.h>
+#include <Security/handleobject.h>
+
+
+class Database;
+
+
+//
+// A Key object represents a CSSM_KEY known to the SecurityServer.
+// We give each Key a handle that allows our clients to access it, while we use
+// the Key's ACL to control such accesses.
+// A Key can be used by multiple Connections. Whether more than one Key can represent
+// the same actual key object is up to the CSP we use, so let's be tolerant about that.
+//
+// A note on key attributes: We keep two sets of attribute bits. The internal bits are used
+// when talking to our CSP; the external bits are used when negotiating with our client(s).
+// The difference is the bits in managedAttributes, which relate to persistent key storage
+// and are not digestible by our CSP. The internal attributes are kept in mKey. The external
+// ones are kept in mAttributes, and are a superset of the internal ones.
+//
+class Key : public HandleObject, public SecurityServerAcl {
+public:
+	//Key(Database *db, const CssmKey &newKey, uint32 usage, uint32 attrs,
+	//	const AclEntryPrototype *owner = NULL);
+	//Key(Database *db, const CssmKey &newKey, const AclEntryPrototype *owner = NULL);
+	Key(Database &db, const KeyBlob *blob);
+	Key(Database *db, const CssmKey &newKey, uint32 moreAttributes,
+		const AclEntryPrototype *owner = NULL);
+	virtual ~Key();
+    
+    Database *database() const { return mDatabase; }
+    bool hasDatabase() const { return mDatabase != NULL; }
+	
+    // yield the decoded internal key -- internal attributes
+	operator CssmKey &()		{ return keyValue(); }
+	size_t length()				{ return keyValue().length(); }
+	void *data()				{ return keyValue().data(); }
+    
+    // yield the approximate external key header -- external attributes
+    void returnKey(Handle &h, CssmKey::Header &hdr);
+    
+    // we can also yield an encoded KeyBlob *if* we belong to a database	
+	KeyBlob *blob();
+    
+    // calculate the UID value for this key (if possible)
+    KeyUID &uid();
+    
+    // ACL state management hooks
+	void instantiateAcl();
+	void noticeAclChange();
+    const Database *relatedDatabase() const;
+    
+    // key attributes that should not be passed on to the CSP
+    static const uint32 managedAttributes = KeyBlob::managedAttributes;
+
+private:
+	void setup(const CssmKey &newKey, uint32 attrs);
+    void decode();
+    CssmKey::Header &keyHeader();
+	CssmKey &keyValue();
+
+private:
+	CssmKey mKey;			// clear form CssmKey (attributes modified)
+    CSSM_KEYATTR_FLAGS mAttributes; // full attributes (external form)
+	bool mValidKey;			// CssmKey form is valid
+
+	Database *mDatabase;	// the database we belong to, NULL if independent
+
+	KeyBlob *mBlob;			// key blob encoded by mDatabase
+	bool mValidBlob;		// mBlob is valid key encoding
+    
+    KeyUID mUID;			// cached UID
+    bool mValidUID;			// UID has been calculated
+};
+
+
+#endif //_H_KEY
diff --git a/SecurityServer/main.cpp b/SecurityServer/main.cpp
new file mode 100644
index 00000000..30a7341c
--- /dev/null
+++ b/SecurityServer/main.cpp
@@ -0,0 +1,232 @@
+/*
+ * 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.
+ */
+
+
+//
+// SecurityServer - Apple security services daemon.
+//
+#include "securityserver.h"
+#include "server.h"
+#include <MacYarrow/yarrowseed.h>
+
+#include <Security/daemon.h>
+#include <Security/osxsigner.h>
+#include "authority.h"
+#include "session.h"
+
+#include <unistd.h>
+#include <Security/machserver.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+// ACL subject types (their makers are instantiated here)
+#include <Security/acl_any.h>
+#include <Security/acl_password.h>
+#include <Security/acl_threshold.h>
+#include <Security/acl_codesigning.h>
+#include <Security/acl_comment.h>
+#include "acl_keychain.h"
+
+
+namespace Security
+{
+
+//
+// Program options (set by argument scan and environment)
+//
+uint32 debugMode = 0;
+
+} // end namespace Security
+
+
+//
+// Local functions of the main program driver
+//
+static void usage(const char *me);
+static void handleSIGCHLD(int);
+static void handleSIGOther(int);
+
+
+//
+// Main driver
+//
+int main(int argc, char *argv[])
+{
+	// program arguments (preset to defaults)
+	bool forceCssmInit = false;
+	int workerTimeout = 0;
+	int maxThreads = 0;
+	const char *authorizationConfig = "/etc/authorization";
+	const char *bootstrapName = "SecurityServer";
+
+	// parse command line arguments
+	extern char *optarg;
+	extern int optind;
+	int arg;
+	while ((arg = getopt(argc, argv, "a:dfN:t:T:")) != -1) {
+		switch (arg) {
+		case 'a':
+			authorizationConfig = optarg;
+			break;
+		case 'd':
+			debugMode++;
+			break;
+        case 'f':
+            forceCssmInit = true;
+            break;
+		case 'N':
+			bootstrapName = optarg;
+			break;
+		case 't':
+			if ((maxThreads = atoi(optarg)) < 0)
+				maxThreads = 0;
+			break;
+		case 'T':
+			if ((workerTimeout = atoi(optarg)) < 0)
+				workerTimeout = 0;
+			break;
+		default:
+			usage(argv[0]);
+		}
+	}
+	
+	// take no non-option arguments
+	if (optind < argc)
+		usage(argv[0]);
+		
+	// configure logging
+	if (debugMode) {
+		Syslog::open(argv[0], LOG_AUTHPRIV, LOG_PERROR);
+		Syslog::notice("SecurityServer started in debug mode");
+	} else {
+		Syslog::open(argv[0], LOG_AUTHPRIV, LOG_CONS);
+	}
+    
+    // if we're not running as root in production mode, fail
+    // in debug mode, issue a warning
+    if (uid_t uid = getuid()) {
+#if defined(NDEBUG)
+        Syslog::alert("Unprivileged SecurityServer aborted (uid=%d)", uid);
+        fprintf(stderr, "You are not allowed to run SecurityServer\n");
+        exit(1);
+#else
+        debug("SS", "Running unprivileged (uid=%d); some features may not work", uid);
+#endif //NDEBUG
+    }
+    
+    // turn into a properly diabolical daemon unless debugMode is on
+    if (!debugMode && !Daemon::incarnate())
+        exit(1);
+	
+	// create a code signing engine
+	CodeSigning::OSXSigner signer;
+	
+	// create an Authorization engine
+	Authority authority(authorizationConfig);
+	
+	// establish the ACL machinery
+	new AnyAclSubject::Maker();
+	new PasswordAclSubject::Maker();
+	new ThresholdAclSubject::Maker();
+    new KeychainPromptAclSubject::Maker();
+    new CommentAclSubject::Maker();
+    new CodeSignatureAclSubject::Maker(signer);
+    
+    // create the RootSession object
+    RootSession rootSession;
+	
+    // create the main server object and register it
+ 	Server server(authority, bootstrapName);
+
+    // set server configuration from arguments, if specified
+	if (workerTimeout)
+		server.timeout(workerTimeout);
+	if (maxThreads)
+		server.maxThreads(maxThreads);
+    
+	// add the RNG seed timer to it
+    YarrowTimer yarrow(server);
+        
+    // set up signal handlers
+    if (signal(SIGCHLD, handleSIGCHLD) == SIG_ERR)
+        debug("SS", "Cannot ignore SIGCHLD: errno=%d", errno);
+    if (signal(SIGINT, handleSIGOther) == SIG_ERR)
+        debug("SS", "Cannot handle SIGINT: errno=%d", errno);
+    if (signal(SIGTERM, handleSIGOther) == SIG_ERR)
+        debug("SS", "Cannot handle SIGTERM: errno=%d", errno);
+    
+    // initialize CSSM now if requested
+    if (forceCssmInit)
+        server.loadCssm();
+    
+	Syslog::notice("Entering service");
+	debug("SS", "Entering service run loop");
+	server.run();
+	
+	// fell out of runloop (should not happen)
+	Syslog::alert("Aborting");
+    return 1;
+}
+
+
+//
+// Issue usage message and die
+//
+static void usage(const char *me)
+{
+	fprintf(stderr, "Usage: %s [-df] [-t maxthreads] [-T threadTimeout]"
+		"\t[-N bootstrapName] [-a authConfigFile]\n", me);
+	exit(2);
+}
+
+
+//
+// Handle SIGCHLD signals to reap our children (zombie cleanup)
+//
+static void handleSIGCHLD(int)
+{
+    int status;
+    switch (pid_t pid = waitpid(-1, &status, WNOHANG)) {
+    case 0:
+        debug("SS", "Spurious SIGCHLD ignored");
+        return;
+    case -1:
+        debug("SS", "waitpid after SIGCHLD failed: errno=%d", errno);
+        return;
+    default:
+        debug("SS", "Reaping child pid=%d", pid);
+        return;
+    }
+}
+
+
+//
+// Handle some other signals to shut down cleanly (and with logging)
+//
+static void handleSIGOther(int sig)
+{
+    switch (sig) {
+    case SIGINT:
+        debug("SS", "Interrupt signal; terminating");
+        exit(0);
+    case SIGTERM:
+        debug("SS", "Termination signal; terminating");
+        exit(0);
+    }
+}
diff --git a/SecurityServer/process.cpp b/SecurityServer/process.cpp
new file mode 100644
index 00000000..2f0cba11
--- /dev/null
+++ b/SecurityServer/process.cpp
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+
+//
+// process - track a single client process and its belongings
+//
+#include "process.h"
+#include "server.h"
+#include "session.h"
+#include "authority.h"
+
+
+//
+// Construct a Process object.
+//
+Process::Process(TaskPort taskPort, const char *identity, uid_t uid, gid_t gid)
+ :  session(Session::find(taskPort.bootstrap())), mBusyCount(0), mDying(false),
+	mTaskPort(taskPort), mUid(uid), mGid(gid)
+{
+    // let's take a look at our wannabe client...
+    mPid = mTaskPort.pid();
+    
+    // register with the session
+    session.addProcess(this);
+	
+	// identify the client-on-disk
+	// @@@ do this lazily on first use?
+	// @@@ note that the paradigm will shift here when kernel-supported id happens
+	mClientCode = CodeSigning::OSXCode::decode(identity);
+	
+	debug("SS", "New process %p(%d) uid=%d gid=%d session=%p TP=%d for %s",
+		this, mPid, mUid, mGid, &session,
+        mTaskPort.port(), identity ? identity : "(unknown)");
+}
+
+Process::Process(Process &prior)
+ :	session(Session::find(prior.mTaskPort.bootstrap())), mBusyCount(0), mDying(false),
+    mTaskPort(prior.mTaskPort), mUid(prior.mUid), mGid(prior.mGid)
+{
+    // copy more
+    mPid = prior.mPid;
+
+    // register with the session
+    session.addProcess(this);
+    
+    // copy the client-code id (and clear it in the prior so it doesn't get destroyed there)
+    mClientCode = prior.mClientCode;
+    prior.mClientCode = NULL;
+    prior.mTaskPort = Port();
+
+    debug("SS", "Process %p(%d) recloned uid=%d gid=%d session=%p",
+        this, mPid, mUid, mGid, &session);
+}
+
+
+Process::~Process()
+{
+	assert(mBusyCount == 0);	// mustn't die with Connections referencing us
+
+	// tell all our authorizations that we're gone
+	IFDEBUG(if (!mAuthorizations.empty()) 
+		debug("SS", "Process %p(%d) clearing %d authorizations", 
+			this, mPid, int(mAuthorizations.size())));
+	for (AuthorizationSet::iterator it = mAuthorizations.begin();
+			it != mAuthorizations.end(); it++) {
+        AuthorizationToken *auth = *it;
+        if (removeAuthorization(auth))
+            delete auth;
+    }
+        
+    // remove all database handles that belong to this process
+    IFDEBUG(if (!mDatabases.empty())
+        debug("SS", "Process %p(%d) clearing %d database handles",
+            this, mPid, int(mDatabases.size())));
+    for (DatabaseSet::iterator it = mDatabases.begin();
+            it != mDatabases.end(); it++)
+        delete *it;
+
+	// no need to lock here; the client process has no more active threads
+	debug("SS", "Process %p(%d) has died", this, mPid);
+	
+	if (mTaskPort)
+        mTaskPort.destroy();	// either dead or taken by reclone
+	delete mClientCode;
+    
+    // deregister from session
+    if (session.removeProcess(this))
+        delete &session;
+}
+
+bool Process::kill()
+{
+	if (mBusyCount == 0) {
+		return true;	// destroy me now
+	} else {
+		debug("SS", "Process %p(%d) destruction deferred for %d busy connections",
+			this, mPid, int(mBusyCount));
+		mDying = true;
+		return false;	// destroy me later
+	}
+}
+
+
+//
+// Given a task port, determine which session it belongs to.
+// @@@ Very preliminary, pending true session implementation.
+//
+Session &Process::sessionForPort(TaskPort taskPort)
+{
+    return Session::find(taskPort.bootstrap());
+}
+
+
+//
+// Connection management
+//
+void Process::beginConnection(Connection &)
+{
+	StLock<Mutex> _(mLock);
+	mBusyCount++;
+}
+
+bool Process::endConnection(Connection &)
+{
+	StLock<Mutex> _(mLock);
+	return --mBusyCount == 0 && mDying;
+}
+
+
+//
+// Database management
+//
+void Process::addDatabase(Database *database)
+{
+    StLock<Mutex> _(mLock);
+    mDatabases.insert(database);
+}
+
+void Process::removeDatabase(Database *database)
+{
+    StLock<Mutex> _(mLock);
+    assert(mDatabases.find(database) != mDatabases.end());
+    mDatabases.erase(database);
+}
+
+
+//
+// Verify the code signature of the a process's on-disk source.
+// @@@ In a truly secure solution, we would ask the OS to verify this.
+// @@@ Only the OS knows for sure what disk file (if any) originated a process.
+// @@@ In the meantime, we fake it.
+//
+bool Process::verifyCodeSignature(const CodeSigning::Signature *signature)
+{
+	if (mClientCode)
+		return Server::signer().verify(*mClientCode, signature);
+	else
+		return false;	// identity not known; can't verify
+}
+
+
+//
+// Authorization set maintainance
+//
+void Process::addAuthorization(AuthorizationToken *auth)
+{
+	assert(auth);
+	StLock<Mutex> _(mLock);
+	mAuthorizations.insert(auth);
+	auth->addProcess(*this);
+}
+
+bool Process::removeAuthorization(AuthorizationToken *auth)
+{
+	assert(auth);
+	StLock<Mutex> _(mLock);
+	// we do everything with a single set lookup call...
+	typedef AuthorizationSet::iterator Iter;
+	pair<Iter, Iter> range = mAuthorizations.equal_range(auth);
+	assert(range.first != mAuthorizations.end());
+	Iter next = range.first; next++;	// next element after first hit
+	mAuthorizations.erase(range.first);	// erase first hit
+	if (next == range.second) {			// if no more hits...
+		if (auth->endProcess(*this))	// ... tell it to remove us,
+			return true;				// ... and tell the caller
+	}
+	return false;						// keep the auth; it's still in use
+}
diff --git a/SecurityServer/process.h b/SecurityServer/process.h
new file mode 100644
index 00000000..dc8c2934
--- /dev/null
+++ b/SecurityServer/process.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+
+//
+// process - track a single client process and its belongings
+//
+#ifndef _H_PROCESS
+#define _H_PROCESS
+
+#include "securityserver.h"
+#include "SecurityAgentClient.h"
+#include <Security/osxsigning.h>
+#include "key.h"
+#include <string>
+
+using MachPlusPlus::Port;
+using MachPlusPlus::TaskPort;
+
+class Session;
+class AuthorizationToken;
+
+
+//
+// A Process object represents a UNIX process (and associated Mach Task) that has
+// had contact with us and may have some state associated with it.
+//
+class Process {
+public:
+	Process(TaskPort tPort, const char *identity, uid_t uid, gid_t gid);
+    Process(Process &prior);	// specialized reclone facility
+	virtual ~Process();
+    
+    uid_t uid() const			{ return mUid; }
+    gid_t gid() const			{ return mGid; }
+    pid_t pid() const			{ return mPid; }
+    TaskPort taskPort() const	{ return mTaskPort; }
+	
+	const CodeSigning::OSXCode *clientCode() const	{ return mClientCode; }
+	bool verifyCodeSignature(const CodeSigning::Signature *signature);
+	
+	void addAuthorization(AuthorizationToken *auth);
+	bool removeAuthorization(AuthorizationToken *auth);
+	
+	void beginConnection(Connection &);
+	bool endConnection(Connection &);
+	bool kill();
+    
+    void addDatabase(Database *database);
+    void removeDatabase(Database *database);
+    
+    Session &session;
+	
+protected:
+	static Session &sessionForPort(TaskPort taskPort);
+	
+private:
+	Mutex mLock;						// object lock
+	uint32 mBusyCount;					// number of Connection references
+	bool mDying;						// process is dead; waiting for Connections to drain
+
+	// peer state: established during connection startup; fixed thereafter
+    TaskPort mTaskPort;					// task port
+    pid_t mPid;							// process id
+    uid_t mUid;							// UNIX uid credential
+    gid_t mGid;							// primary UNIX gid credential
+	
+	CodeSigning::OSXCode *mClientCode;	// code object for client
+	
+	// authorization dictionary
+	typedef multiset<AuthorizationToken *> AuthorizationSet;
+	AuthorizationSet mAuthorizations;	// set of valid authorizations for process
+    
+    // database dictionary
+    typedef set<Database *> DatabaseSet;
+    DatabaseSet mDatabases;				// set of valid database handles
+};
+
+
+#endif //_H_PROCESS
diff --git a/SecurityServer/secagent.defs b/SecurityServer/secagent.defs
new file mode 100644
index 00000000..af0697e3
--- /dev/null
+++ b/SecurityServer/secagent.defs
@@ -0,0 +1,98 @@
+//
+// secagent.defs - Client-side Mach RPC interface to SecurityAgent.
+//
+// Note: one additional message ID code (Client::cancelMessagePseudoID) is used
+// explicitly without showing up in this file.
+//
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+
+subsystem secagent 1000;
+serverprefix secagent_server_;
+userprefix secagent_client_;
+
+import <Security/secagent_types.h>;
+
+
+//
+// Data types
+//
+type OSStatus = int32;
+type pid_t = int32;
+type AclAuthorization = unsigned32;
+type Reason = unsigned32;
+type String = c_string[*:2048];
+type ConstString = c_string[*:2048];
+type Username = c_string[*:80];
+type Choice = struct[2] of unsigned32;
+type MigBoolean = unsigned32;
+
+
+//
+// Common argument profiles
+//
+#define UCSP_PORTS	requestport sport: mach_port_t; \
+					replyport rport: mach_port_t; \
+					out status: OSStatus
+#define IN_BLOB(name)	in name: name##Blob; in name##Base: name##Ptr
+
+
+//
+// Staged query maintainance (common to all staged queries)
+//
+routine finishStagedQuery(UCSP_PORTS);
+routine cancelStagedQuery(UCSP_PORTS; in reason: Reason);
+
+
+//
+// Unlocking keychains by user input
+//
+routine unlockDatabase(UCSP_PORTS;
+	in requestor: ConstString; in requestPid: pid_t; in database: ConstString;
+	out stagePort: mach_port_copy_send_t; out passphrase: String);
+routine retryUnlockDatabase(UCSP_PORTS; in reason: Reason; out passphrase: String);
+
+//
+// Get a new passphrase for a database
+//
+routine queryNewPassphrase(UCSP_PORTS;
+	in requestor: ConstString; in requestPid: pid_t; in database: ConstString;
+    in reason: Reason;
+    out stagePort: mach_port_copy_send_t; out passphrase: String);
+routine retryNewPassphrase(UCSP_PORTS; in reason: Reason; out passphrase: String);
+
+//
+// "Rogue App" alert/confirm function
+//
+routine queryKeychainAccess(UCSP_PORTS; 
+	in requestor: ConstString; in requestPid: pid_t; in database: ConstString;
+	in item: ConstString; in operation: AclAuthorization;
+    out choice: Choice);
+    
+//
+// Generic new/old password prompt interface
+//
+routine queryNewGenericPassphrase(UCSP_PORTS;
+    in requestor: ConstString; in requestPid: pid_t; in prompt: ConstString;
+    in reason: Reason; out stagePort: mach_port_copy_send_t;
+    in showBox: MigBoolean; inout addBox: MigBoolean; out passphrase: String);
+routine retryNewGenericPassphrase(UCSP_PORTS; in reason: Reason;
+    out addBox: MigBoolean; out passphrase: String);
+
+routine queryOldGenericPassphrase(UCSP_PORTS;
+    in requestor: ConstString; in requestPid: pid_t; in prompt: ConstString;
+    out stagePort: mach_port_copy_send_t;
+    in showBox: MigBoolean; inout addBox: MigBoolean; out passphrase: String);
+routine retryOldGenericPassphrase(UCSP_PORTS; in reason: Reason;
+    out addBox: MigBoolean; out passphrase: String);
+
+//
+// Authorization subsystem authentication option
+//
+routine authorizationAuthenticate(UCSP_PORTS;
+	in requestor: ConstString; in requestPid: pid_t;
+	in neededGroup: ConstString; in candidateUser: ConstString;
+	out stagePort: mach_port_copy_send_t; 
+        out authenticatedUser: Username; out authenticatedPassword: String);
+routine retryAuthorizationAuthenticate(UCSP_PORTS; in reason: Reason;
+	out authenticatedUser: Username; out authenticatedPassword: String);
diff --git a/SecurityServer/secagent_types.h b/SecurityServer/secagent_types.h
new file mode 100644
index 00000000..0cda0252
--- /dev/null
+++ b/SecurityServer/secagent_types.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+
+//
+// secagent_types - type equivalence declarations for SecurityAgent MIG
+//
+#include "SecurityAgentClient.h"
+
+// @@@ who forgot that one?
+extern "C" kern_return_t mig_deallocate(vm_address_t addr, vm_size_t size);
+
+namespace Security
+{
+
+using namespace SecurityAgent;
+
+
+typedef char *String;
+typedef const char *ConstString;
+typedef Client::KeychainChoice Choice;
+typedef char *Username;
+typedef uint32 MigBoolean;
+
+
+// fix const-blindless in MIG's internals
+inline int mig_strncpy(char *dest, const char *src, int length)
+{ return ::mig_strncpy(dest, const_cast<char *>(src), length); }
+
+
+//
+// Customization macros for MIG code
+//
+#define __AfterSendRpc(id, name) \
+	if (msg_result == MACH_MSG_SUCCESS && Out0P->Head.msgh_id == MACH_NOTIFY_DEAD_NAME) \
+		return MIG_SERVER_DIED;
+
+#define UseStaticTemplates 0
+
+} // end namespace Security
diff --git a/SecurityServer/securityserver.h b/SecurityServer/securityserver.h
new file mode 100644
index 00000000..ccf344b5
--- /dev/null
+++ b/SecurityServer/securityserver.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+
+//
+// securityserver.h - master header file for the SecurityServer.
+//
+#ifndef _H_SECURITYSERVER
+#define _H_SECURITYSERVER
+
+#include "ssblob.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <Security/cssm.h>
+#include <Security/utilities.h>
+#include <Security/context.h>
+#include <Security/SecurityServerClient.h>
+#include <Security/mach++.h>
+#include <Security/unix++.h>
+#include <Security/debugging.h>
+#include <Security/logging.h>
+
+namespace Security {
+
+using namespace SecurityServer;
+using namespace UnixPlusPlus;
+
+
+//
+// Logging and verbosity levels
+//
+extern uint32 debugMode;
+
+} // end namespace Security
+
+#endif //_H_SECURITYSERVER
diff --git a/SecurityServer/server.cpp b/SecurityServer/server.cpp
new file mode 100644
index 00000000..5462a3e8
--- /dev/null
+++ b/SecurityServer/server.cpp
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ */
+
+
+//
+// server - the actual SecurityServer server object
+//
+#include "server.h"
+#include "session.h"
+#include "acls.h"
+#include <mach/mach_error.h>
+
+using namespace MachPlusPlus;
+
+
+//
+// Construct the server object
+//
+Server::Server(Authority &myAuthority, const char *bootstrapName)
+  : MachServer(bootstrapName),
+    mCurrentConnection(false),
+    mCSPModule(gGuidAppleCSP, mCssm), mCSP(mCSPModule),
+    mAuthority(myAuthority)
+{
+    // engage the subsidiary port handler for sleep notifications
+    add(sleepWatcher);
+}
+
+
+//
+// Clean up the server object
+//
+Server::~Server()
+{
+    //@@@ more later
+}
+
+
+//
+// Locate a connection by reply port and make it the current connection
+// of this thread. The connection will be marked busy, and can be accessed
+// by calling Server::connection() [no argument] until it is released by
+// calling Connection::endWork().
+//
+Connection &Server::connection(mach_port_t port)
+{
+	Server &server = active();
+	StLock<Mutex> _(server.lock);
+	if (Connection *conn = server.connections[port]) {
+		active().mCurrentConnection = conn;
+		conn->beginWork();
+		return *conn;
+	}
+	// unknown client port -- could be a hack attempt
+	CssmError::throwMe(CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+}
+
+Connection &Server::connection(bool tolerant)
+{
+	Connection *conn = active().mCurrentConnection;
+	assert(conn);	// have to have one
+	if (!tolerant)
+		conn->checkWork();
+	return *conn;
+}
+
+void Server::requestComplete()
+{
+	// note: there may not be an active connection if connection setup failed
+	if (Connection *conn = active().mCurrentConnection) {
+		if (conn->endWork())
+			delete conn;
+		active().mCurrentConnection = NULL;
+	}
+}
+
+
+//
+// Locate an ACL bearer (database or key) by handle
+//
+SecurityServerAcl &Server::aclBearer(AclKind kind, CSSM_HANDLE handle)
+{
+	SecurityServerAcl &bearer = findHandle<SecurityServerAcl>(handle);
+	if (kind != bearer.kind())
+		CssmError::throwMe(CSSMERR_CSSM_INVALID_HANDLE_USAGE);
+	return bearer;
+}
+
+
+//
+// Run the server. This will not return until the server is forced to exit.
+//
+void Server::run()
+{
+	MachServer::run(0x10000,
+        MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) |
+        MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER));
+}
+
+
+//
+// The server run-loop function
+//
+boolean_t ucsp_server(mach_msg_header_t *, mach_msg_header_t *);
+
+boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out)
+{
+	return ucsp_server(in, out);
+}
+
+
+//
+// Set up a new Connection. This establishes the environment (process et al) as needed
+// and registers a properly initialized Connection object to run with.
+//
+void Server::setupConnection(Port replyPort, Port taskPort,
+    const security_token_t &securityToken, const char *identity)
+{
+	// first, make or find the process based on task port
+	StLock<Mutex> _(lock);
+	Process * &proc = processes[taskPort];
+	if (proc == NULL) {
+		proc = new Process(taskPort, identity, securityToken.val[0], securityToken.val[1]);
+		notifyIfDead(taskPort);
+	}
+
+	// now, establish a connection and register it in the server
+	Connection *connection = new Connection(*proc, replyPort);
+	if (connections[replyPort])	// malicious re-entry attempt?
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	//@@@ error code? (client error)
+	connections[replyPort] = connection;
+	notifyIfDead(replyPort);
+}
+
+
+//
+// Synchronously end a Connection.
+// This is due to a request from the client, so no thread races are possible.
+//
+void Server::endConnection(Port replyPort)
+{
+	StLock<Mutex> _(lock);
+	Connection *connection = connections[replyPort];
+	assert(connection);
+	connections.erase(replyPort);
+	connection->terminate();
+	delete connection;
+}
+
+
+//
+// Take an existing Connection/Process combo. Tear them down even though
+// the client-side thread/process is still alive and construct new ones in their place.
+// This is a high-wire act with a frayed net. We use it ONLY to deal with clients
+// who change their Session (by changing their bootstrap subset port) in mid-stream.
+// In other words, this is a hack that the client would be well advised to avoid.
+// (Avoid it by calling SessionCreate before calling any other Security interfaces in
+// the process's life.)
+//
+Process *Server::resetConnection()
+{
+    Connection *oldConnection = mCurrentConnection;
+    Process *oldProcess = &oldConnection->process;
+    debug("SS", "reset process %p connection %p for session switch",
+        oldProcess, oldConnection);
+
+    Port replyPort = oldConnection->clientPort();
+    
+    oldConnection->endWork();
+    oldConnection->abort(true);
+    delete oldConnection;
+    
+    oldProcess->kill();
+    
+    Process * &proc = processes[oldProcess->taskPort()];
+    proc = new Process(*oldProcess);
+    delete oldProcess;
+    
+    Connection *connection = new Connection(*proc, replyPort);
+    connections[replyPort] = connection;
+    mCurrentConnection = connection;
+    connection->beginWork();
+    
+    return proc;
+}
+
+
+//
+// Handling dead-port notifications.
+// This receives DPNs for all kinds of ports we're interested in.
+//
+void Server::notifyDeadName(Port port)
+{
+	StLock<Mutex> _(lock);
+    
+    // is it a connection?
+    ConnectionMap::iterator conIt = connections.find(port);
+    if (conIt != connections.end()) {
+        Connection *connection = conIt->second;
+		if (connection->abort())
+			delete connection;
+		connections.erase(conIt);
+        return;
+    }
+    
+    // is it a process?
+    ProcessMap::iterator procIt = processes.find(port);
+    if (procIt != processes.end()) {
+        Process *process = procIt->second;
+		if (process->kill())
+			delete process;
+		processes.erase(procIt);
+        return;
+    }
+    
+    // well, it better be a session
+    Session::eliminate(Bootstrap(port));
+}
+
+
+//
+// Notifier for system sleep events
+//
+void Server::SleepWatcher::systemWillSleep()
+{
+    debug("SS", "sleep notification received");
+    Database::lockAllDatabases(true);
+}
+
+
+//
+// Return the primary Cryptographic Service Provider.
+// This will be lazily loaded when it is first requested.
+//
+CssmClient::CSP &Server::getCsp()
+{
+	//@@@ not officially pthread-kosher. Use a ModuleNexus here?
+    if (!mCssm->isActive()) {
+        // first time load
+        //@@@ should we abort the server if this fails? What point continuing?
+		StLock<Mutex> _(lock);
+        debug("SS", "CSSM initializing");
+        mCssm->init();
+        mCSP->attach();
+        char guids[Guid::stringRepLength+1];
+        IFDEBUG(debug("SS", "CSSM ready with CSP %s", mCSP->guid().toString(guids)));
+    }
+    return mCSP;
+}
diff --git a/SecurityServer/server.h b/SecurityServer/server.h
new file mode 100644
index 00000000..2f1bb96b
--- /dev/null
+++ b/SecurityServer/server.h
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+
+//
+// server - the actual Server object
+//
+#ifndef _H_SERVER
+#define _H_SERVER
+
+#include "securityserver.h"
+#include <Security/machserver.h>
+#include <Security/powerwatch.h>
+#include <Security/cssmclient.h>
+#include <Security/cspclient.h>
+#include <Security/osxsigner.h>
+#include <Security/devrandom.h>
+#include <Security/uniformrandom.h>
+#include "connection.h"
+#include "key.h"
+#include "xdatabase.h"
+#include "authority.h"
+#include <map>
+
+
+class Server : public MachPlusPlus::MachServer,
+               public UniformRandomBlobs<DevRandomGenerator> {
+public:
+	Server(Authority &myAuthority, const char *bootstrapName);
+	~Server();
+	
+    // run the server until it shuts down
+	void run();
+	
+    //
+    // Retrieve pieces of the Server's object web.
+    // These are all static methods that use the active() Server of this thread.
+    //
+	static Server &active() { return safer_cast<Server &>(MachServer::active()); }
+	
+	static Connection &connection(mach_port_t replyPort);
+	static Connection &connection(bool tolerant = false);
+	static void requestComplete();
+	
+	static Key &key(KeyHandle key)
+	{ return findHandle<Key>(key, CSSMERR_CSP_INVALID_KEY); }
+    static Key *optionalKey(KeyHandle k) { return (k == noKey) ? NULL : &key(k); }
+	static Database &database(DbHandle db)
+	{ return findHandle<Database>(db, CSSMERR_DL_INVALID_DB_HANDLE); }
+	static Database *optionalDatabase(DbHandle db) { return db ? &database(db) : NULL; }
+    static Authority &authority() { return active().mAuthority; }
+	static CodeSigning::OSXSigner &signer() { return active().mSigner; }
+	static SecurityServerAcl &aclBearer(AclKind kind, CSSM_HANDLE handle);
+	static CssmClient::CSP &csp() { return active().getCsp(); }
+
+    void loadCssm()	{ getCsp(); }
+	
+public:
+	void setupConnection(Port replyPort, Port taskPort,
+        const security_token_t &securityToken, const char *executablePath);
+    Process *resetConnection();
+	void endConnection(Port replyPort);
+	
+	static void releaseWhenDone(CssmAllocator &alloc, void *memory)
+	{ MachServer::active().releaseWhenDone(alloc, memory); }
+	static void releaseWhenDone(void *memory)
+	{ releaseWhenDone(CssmAllocator::standard(), memory); }
+    
+protected:
+    // implementation methods of MachServer
+	boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out);
+	void notifyDeadName(Port port);
+    
+private:
+    class SleepWatcher : public MachPlusPlus::PortPowerWatcher {
+    public:
+        void systemWillSleep();
+    };
+    SleepWatcher sleepWatcher;
+	
+private:
+	Mutex lock;					// master lock
+
+	// map of connections (by client reply port)
+	typedef map<mach_port_t, Connection *> ConnectionMap;
+	ConnectionMap connections;
+	
+	// map of processes (by process task port)
+	typedef map<mach_port_t, Process *> ProcessMap;
+	ProcessMap processes;
+	
+	// Current connection, if any (per thread).
+	// Set as a side effect of calling the connection() method.
+	PerThreadPointer<Connection> mCurrentConnection;
+	
+    // CSSM components
+    CssmClient::Cssm mCssm;
+    CssmClient::Module mCSPModule;
+	CssmClient::CSP mCSP;
+    CssmClient::CSP &getCsp();
+    
+	Authority &mAuthority;
+	CodeSigning::OSXSigner mSigner;
+};
+
+#endif //_H_SERVER
diff --git a/SecurityServer/session.cpp b/SecurityServer/session.cpp
new file mode 100644
index 00000000..5dad8d10
--- /dev/null
+++ b/SecurityServer/session.cpp
@@ -0,0 +1,360 @@
+/*
+ * 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.
+ */
+
+
+//
+// session - authentication session domains
+//
+// A Session is defined by a mach_init bootstrap dictionary. These dictionaries are
+// hierarchical and inherited, so they work well for characterization of processes
+// that "belong" together. (Of course, if your mach_init is broken, you're in bad shape.)
+//
+// Sessions are multi-threaded objects.
+//
+#include "session.h"
+#include "connection.h"
+#include "server.h"
+
+
+//
+// The static session map
+//
+Session::SessionMap Session::sessionMap;
+Mutex Session::sessionMapLock;
+
+
+//
+// Create a Session object from initial parameters (create)
+//
+Session::Session(Bootstrap bootstrap, SessionAttributeBits attrs) 
+    : mBootstrap(bootstrap), mAttributes(attrs), mProcessCount(0), mAuthCount(0), mDying(false)
+{
+    debug("SSsession", "%p CREATED: handle=0x%lx bootstrap=%d attrs=0x%lx",
+        this, handle(), mBootstrap.port(), mAttributes);
+}
+
+RootSession::RootSession()
+    : Session(Bootstrap(), sessionIsRoot | sessionWasInitialized)
+{
+    // self-install
+    sessionMap[mBootstrap] = this;
+}
+
+DynamicSession::DynamicSession(Bootstrap bootstrap) : Session(bootstrap)
+{
+    Server::active().notifyIfDead(bootstrapPort());
+}
+
+
+//
+// Destroy a Session
+//
+Session::~Session()
+{
+    assert(mProcessCount == 0);	// can't die with processes still alive
+    Database::lockAllDatabases();
+    debug("SSsession", "%p DESTROYED: handle=0x%lx bootstrap=%d",
+        this, handle(), mBootstrap.port());
+}
+
+
+//
+// Retrieve or create a session object
+//
+Session &Session::find(Bootstrap bootstrap, bool makeNew)
+{
+    StLock<Mutex> _(sessionMapLock);
+    Session * &slot = sessionMap[bootstrap];
+    if (slot == NULL)
+        if (makeNew)
+            slot = new DynamicSession(bootstrap);
+        else
+            Authorization::Error::throwMe(errAuthorizationInvalidRef);
+    return *slot;
+}
+
+Session &Session::find(SecuritySessionId id)
+{
+    switch (id) {
+    case callerSecuritySession:
+        return Server::connection().process.session;
+    default:
+        return findHandle<Session>(id);
+    }
+}
+
+
+//
+// Act on a death notification for a session's (sub)bootstrap port.
+// We may not destroy the Session outright here (due to processes that use it),
+// but we do clear out its accumulated wealth.
+//
+void Session::eliminate(Bootstrap bootstrap)
+{
+    // remove session from session map
+    StLock<Mutex> _(sessionMapLock);
+    SessionMap::iterator it = sessionMap.find(bootstrap);
+    assert(it != sessionMap.end());
+    Session *session = it->second;
+    sessionMap.erase(it);
+
+    // clear resources
+    if (session->clearResources())
+        delete session;
+    else
+        debug("SSsession", "session %p zombified for %d processes and %d auths",
+            session, int(session->mProcessCount), int(session->mAuthCount));
+}
+
+bool Session::clearResources()
+{
+    StLock<Mutex> _(mLock);
+    
+    // this session is now officially dying
+    mDying = true;
+    
+    // invalidate shared credentials
+    IFDEBUG(if (!mSessionCreds.empty()) 
+        debug("SSauth", "session %p clearing %d shared credentials", 
+            this, int(mSessionCreds.size())));
+    for (CredentialSet::iterator it = mSessionCreds.begin(); it != mSessionCreds.end(); it++)
+        (*it)->invalidate();
+    
+    // let the caller know if we are ready to die NOW
+    return mProcessCount == 0 && mAuthCount == 0;
+}
+
+
+//
+// Process management
+//
+void Session::addProcess(Process *)
+{
+    StLock<Mutex> _(mLock);
+    mProcessCount++;
+}
+
+bool Session::removeProcess(Process *)
+{
+    StLock<Mutex> _(mLock);
+    assert(mProcessCount > 0);
+    return --mProcessCount == 0 && mDying && mAuthCount == 0;
+}
+
+
+//
+// Authorization retention management.
+//
+void Session::addAuthorization(AuthorizationToken *)
+{
+    StLock<Mutex> _(mLock);
+    mAuthCount++;
+}
+
+bool Session::removeAuthorization(AuthorizationToken *)
+{
+    StLock<Mutex> _(mLock);
+    assert(mAuthCount > 0);
+    return --mAuthCount == 0 && mDying && mProcessCount == 0;
+}
+
+
+//
+// Authorization operations
+//
+OSStatus Session::authCreate(const RightSet &rights,
+	const AuthorizationEnvironment *environment,
+	AuthorizationFlags flags,
+	AuthorizationBlob &newHandle)
+{
+	// invoke the authorization computation engine
+	CredentialSet resultCreds;
+	
+	// this will acquire mLock, so we delay acquiring it
+	auto_ptr<AuthorizationToken> auth(new AuthorizationToken(*this, resultCreds));
+	
+	OSStatus result = Server::authority().authorize(rights, environment, flags,
+        &mSessionCreds, &resultCreds, NULL, *auth);
+	newHandle = auth->handle();
+
+	{
+		StLock<Mutex> _(mLock);
+
+		// merge resulting creds into shared pool
+		if ((flags & kAuthorizationFlagExtendRights) && 
+			!(flags & kAuthorizationFlagDestroyRights)) {
+			mergeCredentials(resultCreds);
+			auth->mergeCredentials(resultCreds);
+		}
+	}
+
+	// Make sure that this isn't done until the auth(AuthorizationToken) is guaranteed to 
+	// not be destroyed anymore since it's destructor asserts it has no processes
+	Server::connection().process.addAuthorization(auth.get());
+	auth.release();
+	return result;
+}
+
+void Session::authFree(const AuthorizationBlob &authBlob, AuthorizationFlags flags)
+{
+    AuthorizationToken::Deleter deleter(authBlob);
+    AuthorizationToken &auth = deleter;
+
+	if (flags & kAuthorizationFlagDestroyRights) {
+		// explicitly invalidate all shared credentials and remove them from the session
+		for (CredentialSet::const_iterator it = auth.begin(); it != auth.end(); it++)
+			if ((*it)->isShared())
+				(*it)->invalidate();
+	}
+
+	// now get rid of the authorization itself
+	if (Server::connection().process.removeAuthorization(&auth))
+        deleter.remove();
+}
+
+OSStatus Session::authGetRights(const AuthorizationBlob &authBlob,
+	const RightSet &rights, const AuthorizationEnvironment *environment,
+	AuthorizationFlags flags,
+	MutableRightSet &grantedRights)
+{
+	StLock<Mutex> _(mLock);
+	CredentialSet resultCreds;
+	AuthorizationToken &auth = authorization(authBlob);
+	CredentialSet effective = auth.effectiveCreds();
+	OSStatus result = Server::authority().authorize(rights, environment, flags, 
+        &effective, &resultCreds, &grantedRights, auth);
+
+	// merge resulting creds into shared pool
+	if ((flags & kAuthorizationFlagExtendRights) && !(flags & kAuthorizationFlagDestroyRights)) {
+		mergeCredentials(resultCreds);
+		auth.mergeCredentials(resultCreds);
+	}
+
+	IFDEBUG(debug("SSauth", "Authorization %p copyRights asked for %d got %d",
+		&authorization(authBlob), int(rights.size()), int(grantedRights.size())));
+	return result;
+}
+
+OSStatus Session::authGetInfo(const AuthorizationBlob &authBlob,
+	const char *tag,
+	MutableRightSet &grantedRights)
+{
+	StLock<Mutex> _(mLock);
+	AuthorizationToken &auth = authorization(authBlob);
+	debug("SSauth", "Authorization %p get-info not implemented", &auth);
+    if (tag) {	// no such tag (no info support)
+        return errAuthorizationInvalidTag;
+    } else {	// return no tags (no info support)
+        grantedRights = RightSet();	// return no entries
+        return noErr;
+    }
+}
+
+OSStatus Session::authExternalize(const AuthorizationBlob &authBlob, 
+	AuthorizationExternalForm &extForm)
+{
+	StLock<Mutex> _(mLock);
+	const AuthorizationToken &auth = authorization(authBlob);
+	if (auth.mayExternalize(Server::connection().process)) {
+		memset(&extForm, 0, sizeof(extForm));
+        AuthorizationExternalBlob &extBlob =
+            reinterpret_cast<AuthorizationExternalBlob &>(extForm);
+        extBlob.blob = auth.handle();
+        extBlob.session = bootstrapPort();
+		debug("SSauth", "Authorization %p externalized", &auth);
+		return noErr;
+	} else
+		return errAuthorizationExternalizeNotAllowed;
+}
+
+OSStatus Session::authInternalize(const AuthorizationExternalForm &extForm, 
+	AuthorizationBlob &authBlob)
+{
+	StLock<Mutex> _(mLock);
+	
+	// interpret the external form
+    const AuthorizationExternalBlob &extBlob = 
+        reinterpret_cast<const AuthorizationExternalBlob &>(extForm);
+	
+    // locate source authorization
+    AuthorizationToken &sourceAuth = AuthorizationToken::find(extBlob.blob);
+    
+	// check for permission and do it
+	if (sourceAuth.mayInternalize(Server::connection().process, true)) {
+		authBlob = extBlob.blob;
+        Server::connection().process.addAuthorization(&sourceAuth);
+        mAuthCount++;
+        debug("SSauth", "Authorization %p internalized", &sourceAuth);
+		return noErr;
+	} else
+		return errAuthorizationInternalizeNotAllowed;
+}
+
+
+//
+// Set up a (new-ish) Session.
+// This call must be made from a process within the session, and it must be the first
+// such process to make the call.
+//
+void Session::setup(SessionCreationFlags flags, SessionAttributeBits attrs)
+{
+    // check current process object - it may have been cached before the client's bootstrap switch
+    Process *process = &Server::connection().process;
+    if (process->taskPort().bootstrap() != process->session.bootstrapPort())
+        process = Server::active().resetConnection();
+    process->session.setupAttributes(attrs);
+}
+
+
+void Session::setupAttributes(SessionAttributeBits attrs)
+{
+    debug("SSsession", "%p setup attrs=0x%lx", this, attrs);
+    if (attrs & ~settableAttributes)
+        MacOSError::throwMe(errSessionInvalidAttributes);
+    if (attribute(sessionWasInitialized))
+        MacOSError::throwMe(errSessionAuthorizationDenied);
+    setAttributes(attrs | sessionWasInitialized);
+}
+
+
+//
+// Merge a set of credentials into the shared-session credential pool
+//
+void Session::mergeCredentials(CredentialSet &creds)
+{
+	for (CredentialSet::const_iterator it = creds.begin(); it != creds.end(); it++)
+		if (((*it)->isShared() && (*it)->isValid())) {
+			CredentialSet::iterator old = mSessionCreds.find(*it);
+			if (old == mSessionCreds.end()) {
+				mSessionCreds.insert(*it);
+            } else {
+                // replace "new" with "old" in input set to retain synchronization
+				(*old)->merge(**it);
+                creds.erase(it);
+                creds.insert(*old);
+            }
+		}
+}
+
+
+//
+// Locate an AuthorizationToken given a blob
+//
+AuthorizationToken &Session::authorization(const AuthorizationBlob &blob)
+{
+    return AuthorizationToken::find(blob);
+}
diff --git a/SecurityServer/session.h b/SecurityServer/session.h
new file mode 100644
index 00000000..b08a2469
--- /dev/null
+++ b/SecurityServer/session.h
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+
+//
+// session - authentication session domains
+//
+#ifndef _H_SESSION
+#define _H_SESSION
+
+#include "securityserver.h"
+#include "acls.h"
+#include "authority.h"
+#include <Security/AuthSession.h>
+#include <Security/utilities.h>
+#include <Security/handleobject.h>
+#include <Security/cssmdb.h>
+#include <hash_map>
+
+
+class Key;
+class Connection;
+
+
+//
+// A Session object represents one or more Connections that are known to
+// belong to the same authentication domain. Informally this means just
+// about "the same user", for the right definition of "user." The upshot
+// is that global credentials can be shared by Connections of one Session
+// with a modicum of security, and so Sessions are the natural nexus of
+// single-sign-on functionality.
+//
+class Session : public HandleObject {
+    typedef MachPlusPlus::Bootstrap Bootstrap;
+public:
+    Session(Bootstrap bootstrap, SessionAttributeBits attrs = 0);
+	virtual ~Session();
+    
+    Bootstrap bootstrapPort() const		{ return mBootstrap; }
+    
+    void addProcess(Process *proc);
+    bool removeProcess(Process *proc);
+    
+    void addAuthorization(AuthorizationToken *auth);
+    bool removeAuthorization(AuthorizationToken *auth);
+    
+public:
+    static const SessionAttributeBits settableAttributes =
+        sessionHasGraphicAccess | sessionHasTTY | sessionIsRemote;
+
+    SessionAttributeBits attributes() const			{ return mAttributes; }
+    bool attribute(SessionAttributeBits bits) const	{ return mAttributes & bits; }
+    
+    static void setup(SessionCreationFlags flags, SessionAttributeBits attrs);
+    void setupAttributes(SessionAttributeBits attrs);
+    
+protected:
+    void setAttributes(SessionAttributeBits attrs)	{ mAttributes |= attrs; }
+    
+public:
+	const CredentialSet &authCredentials() const	{ return mSessionCreds; }
+
+	OSStatus authCreate(const RightSet &rights, const AuthorizationEnvironment *environment,
+		AuthorizationFlags flags, AuthorizationBlob &newHandle);
+	void authFree(const AuthorizationBlob &auth, AuthorizationFlags flags);
+	OSStatus authGetRights(const AuthorizationBlob &auth,
+		const RightSet &requestedRights, const AuthorizationEnvironment *environment,
+		AuthorizationFlags flags, MutableRightSet &grantedRights);
+	OSStatus authGetInfo(const AuthorizationBlob &auth, const char *tag, MutableRightSet &info);
+	OSStatus authExternalize(const AuthorizationBlob &auth, AuthorizationExternalForm &extForm);
+	OSStatus authInternalize(const AuthorizationExternalForm &extForm, AuthorizationBlob &auth);
+
+private:
+    struct AuthorizationExternalBlob {
+        AuthorizationBlob blob;
+        mach_port_t session;
+    };
+	
+protected:
+    AuthorizationToken &authorization(const AuthorizationBlob &blob);
+	void mergeCredentials(CredentialSet &creds);
+
+    bool clearResources();
+
+public:
+    static Session &find(Bootstrap bootstrap, bool makeNew = true);
+    static Session &find(SecuritySessionId id);
+    static void eliminate(Bootstrap bootstrap);
+    
+protected:
+	mutable Mutex mLock;			// object lock
+    
+    Bootstrap mBootstrap;			// session bootstrap port
+    SessionAttributeBits mAttributes; // attribute bits (see AuthSession.h)
+    unsigned int mProcessCount;		// number of active processes in session
+    unsigned int mAuthCount;		// number of AuthorizationTokens belonging to us
+    bool mDying;					// session is dying
+
+	CredentialSet mSessionCreds;	// shared session authorization credentials
+
+private:	
+    typedef map<mach_port_t, Session *> SessionMap;
+    static SessionMap sessionMap;
+    static Mutex sessionMapLock;
+    
+public:
+    typedef SessionMap::iterator Iterator;
+    static Iterator begin()		{ return sessionMap.begin(); }
+    static Iterator end() 		{ return sessionMap.end(); }
+};
+
+
+//
+// The RootSession is the session (i.e. bootstrap dictionary) of system daemons that are
+// started early and don't belong to anything more restrictive. The RootSession is considered
+// immortal.
+// Currently, telnet sessions et al also default into this session, but this will change
+// (we hope).
+//
+class RootSession : public Session {
+public:
+    RootSession();
+};
+
+
+//
+// A DynamicSession is the default type of session object. We create one when a new
+// Connection initializes whose bootstrap port we haven't seen before. These Sessions
+// are torn down when their bootstrap object disappears (which happens when mach_init
+// destroys it due to its requestor referent vanishing).
+//
+class DynamicSession : public Session {
+public:
+    DynamicSession(Bootstrap bootstrap);
+};
+
+
+#endif //_H_SESSION
diff --git a/SecurityServer/ssblob.cpp b/SecurityServer/ssblob.cpp
new file mode 100644
index 00000000..517b2122
--- /dev/null
+++ b/SecurityServer/ssblob.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+
+//
+// ssclient - SecurityServer client interface library
+//
+#include "ssblob.h"
+
+
+namespace Security {
+namespace SecurityServer {
+
+
+//
+// Initialize the blob header for a given version
+//
+void CommonBlob::initialize(uint32 version)
+{
+    magic = magicNumber;
+    this->version = version;
+}
+
+
+//
+// Verify the blob header for basic sane-ness.
+// Version is checked (for equality) if non-zero.
+void CommonBlob::validate(CSSM_RETURN failureCode) const
+{
+    if (magic != magicNumber)
+        CssmError::throwMe(failureCode);
+}
+
+
+
+} // end namespace SecurityServer
+
+} // end namespace Security
diff --git a/SecurityServer/ssblob.h b/SecurityServer/ssblob.h
new file mode 100644
index 00000000..4013e3fb
--- /dev/null
+++ b/SecurityServer/ssblob.h
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+
+//
+// ssblob - objects to represent key and database blobs to SecurityServer
+//
+#ifndef _H_SSBLOB
+#define _H_SSBLOB
+
+#include <Security/SecurityServerClient.h>
+#include <Security/cssm.h>
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <Security/cssmacl.h>
+#include <Security/memutils.h>
+
+
+namespace Security
+{
+
+using LowLevelMemoryUtilities::increment;
+
+namespace SecurityServer
+{
+
+//
+// A generic blob
+//
+class Blob {
+protected:
+    template <class T>
+    T *at(off_t offset)		{ return LowLevelMemoryUtilities::increment<T>(this, offset); }
+    void *at(off_t offset)	{ return LowLevelMemoryUtilities::increment(this, offset); }
+};
+
+
+//
+// The common features of our blobs
+//
+class CommonBlob : public Blob {
+public:
+    // initial fixed fields for versioning
+    uint32 magic;		// magic number
+    uint32 version;		// version code
+    
+    static const uint32 magicNumber = 0xfade0711;
+
+    static const uint32 version_MacOS_10_0 = 0x00000100;	// MacOS 10.0.x
+    static const uint32 version_MacOS_10_1 = 0x00000101;	// MacOS 10.1.x and on
+    static const uint32 currentVersion = version_MacOS_10_0;
+    
+public:
+    void initialize(uint32 version = currentVersion);
+    void validate(CSSM_RETURN failureCode) const;
+	
+	void *data()		{ return at(0); }
+};
+
+
+//
+// A Database blob
+//
+class DbBlob : public CommonBlob {
+public:    
+    struct Signature {
+        uint8 bytes[16];
+        
+        bool operator < (const Signature &sig) const
+        { return memcmp(bytes, sig.bytes, sizeof(bytes)) < 0; }
+        bool operator == (const Signature &sig) const
+        { return memcmp(bytes, sig.bytes, sizeof(bytes)) == 0; }
+    };
+    
+    struct PrivateBlob : public Blob {
+        uint8 encryptionKey[24];	// master encryption key
+        uint8 signingKey[20];		// master signing key
+
+        // private ACL blob follows, to the end
+        void *privateAclBlob()	{ return at(sizeof(PrivateBlob)); }
+    };
+
+public:    
+    // position separators between variable-length fields (see below)
+    uint32 startCryptoBlob;		// end of public ACL; start of crypto blob
+    uint32 totalLength;			// end of crypto blob; end of entire blob
+
+    Signature randomSignature;	// randomizing database signature
+    uint32 sequence;			// database sequence number
+    DBParameters params;		// database settable parameters
+
+    uint8 salt[20];				// derivation salt
+    uint8 iv[8];				// encryption iv
+
+    uint8 blobSignature[20];	// HMAC/SHA1 of entire blob except itself
+    
+    // variable length fields:
+    void *publicAclBlob()	{ return at(sizeof(DbBlob)); }
+    size_t publicAclBlobLength() const
+    { return startCryptoBlob - sizeof(DbBlob); }
+    
+    void *cryptoBlob()		{ return at(startCryptoBlob); }
+    size_t cryptoBlobLength() const { return totalLength - startCryptoBlob; }
+    
+    uint32 length() const	{ return totalLength; }
+
+    DbBlob *copy(CssmAllocator &alloc = CssmAllocator::standard()) const
+    {
+        DbBlob *blob = alloc.malloc<DbBlob>(length());
+        memcpy(blob, this, length());
+        return blob;
+    }
+};
+
+
+//
+// A key blob
+//
+class KeyBlob : public CommonBlob {
+public:
+    uint32 startCryptoBlob;		// end of public ACL; start of crypto blob
+    uint32 totalLength;			// end of crypto blob; end of entire blob
+
+    uint8 iv[8];				// encryption iv
+
+    CssmKey::Header header;		// key header as-is
+    struct WrappedFields {
+        CSSM_KEYBLOB_TYPE blobType;
+        CSSM_KEYBLOB_FORMAT blobFormat;
+        CSSM_ALGORITHMS wrapAlgorithm;
+        CSSM_ENCRYPT_MODE wrapMode;
+    } wrappedHeader;
+
+    uint8 blobSignature[20];	// HMAC/SHA1 of entire blob except itself
+    
+    // variable length fields:
+    void *publicAclBlob()	{ return at(sizeof(KeyBlob)); }
+    size_t publicAclBlobLength() const
+    { return startCryptoBlob - sizeof(KeyBlob); }
+    
+    void *cryptoBlob()		{ return at(startCryptoBlob); }
+    size_t cryptoBlobLength() const { return totalLength - startCryptoBlob; }
+    
+    uint32 length() const	{ return totalLength; }
+
+    // these bits are managed internally by the SecurityServer (and not passed to the CSPs)
+    static const uint32 managedAttributes =
+        CSSM_KEYATTR_ALWAYS_SENSITIVE |
+        CSSM_KEYATTR_NEVER_EXTRACTABLE |
+        CSSM_KEYATTR_PERMANENT;
+
+public:
+    KeyBlob *copy(CssmAllocator &alloc) const
+    {
+        KeyBlob *blob = alloc.malloc<KeyBlob>(length());
+        memcpy(blob, this, length());
+        return blob;
+    }
+};
+
+
+} // end namespace SecurityServer
+
+} // end namespace Security
+
+
+#endif //_H_SSBLOB
diff --git a/SecurityServer/ssclient.cpp b/SecurityServer/ssclient.cpp
new file mode 100644
index 00000000..2a876200
--- /dev/null
+++ b/SecurityServer/ssclient.cpp
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+//
+// ssclient - SecurityServer client interface library
+//
+#include "sstransit.h"
+#include <servers/netname.h>
+#include <Security/debugging.h>
+
+using MachPlusPlus::check;
+using MachPlusPlus::Bootstrap;
+using CodeSigning::OSXCode;
+
+
+namespace Security
+{
+
+namespace SecurityServer
+{
+
+//
+// The process-global object
+//
+ModuleNexus<ClientSession::Global> ClientSession::mGlobal;
+
+
+//
+// Construct a client session
+//
+ClientSession::ClientSession(CssmAllocator &std, CssmAllocator &rtn)
+: internalAllocator(std), returnAllocator(rtn)
+{ }
+
+
+//
+// Destroy a session
+//
+ClientSession::~ClientSession()
+{ }
+
+
+//
+// Activate a session: This connects to the SecurityServer and executes
+// application authentication
+//
+void ClientSession::activate()
+{
+	Global &global = mGlobal();
+    Thread &thread = global.thread();
+    if (!thread) {
+		// first time for this thread - use abbreviated registration
+		IPCN(ucsp_client_setup(UCSP_ARGS, mach_task_self(), ""));
+        thread.registered = true;
+        global.serverPort.requestNotify(thread.replyPort, MACH_NOTIFY_DEAD_NAME, true);
+        debug("SSclnt", "Thread registered with SecurityServer");
+	}
+}
+
+// Caution: you can't use mGlobal() inside Global::Global (deadlock)
+ClientSession::Global::Global()
+{
+    debug("SSclnt", "Initial process setup");
+
+    // find server port
+    serverPort = Bootstrap().lookup("SecurityServer");
+    
+    // send identification/setup message
+    string extForm;
+    try {
+        myself = OSXCode::main();
+        extForm = myself->encode();
+        debug("SSclnt", "my OSXCode extForm=%s", extForm.c_str());
+    } catch (...) {
+        myself = NULL;
+        // leave extForm empty
+        debug("SSclnt", "failed to obtain my own OSXCode");
+    }
+    // cannot use UCSP_ARGS here because it uses mGlobal()
+    IPCN(ucsp_client_setup(serverPort, mig_get_reply_port(), &rcode,
+        mach_task_self(), extForm.c_str()));
+    Thread &thread = this->thread();
+    thread.registered = true;	// as a side-effect of setup call above
+	serverPort.requestNotify(thread.replyPort, MACH_NOTIFY_DEAD_NAME, true);
+    debug("SSclnt", "Process registered with SecurityServer");
+}
+
+
+//
+// Terminate a session. This is called by the session destructor, or explicitly.
+//
+void ClientSession::terminate()
+{
+	// currently defunct
+	debug("SSclnt", "ClientSession::terminate() call ignored");
+}
+
+
+} // end namespace SecurityServer
+
+} // end namespace Security
diff --git a/SecurityServer/ssclient.h b/SecurityServer/ssclient.h
new file mode 100644
index 00000000..7edb4cc8
--- /dev/null
+++ b/SecurityServer/ssclient.h
@@ -0,0 +1,277 @@
+/*
+ * 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.
+ */
+
+
+//
+// ssclient - SecurityServer client interface library
+//
+#ifndef _H_SSCLIENT
+#define _H_SSCLIENT
+
+
+#include <Security/cssm.h>
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <Security/cssmacl.h>
+#include <Security/context.h>
+#include <Security/globalizer.h>
+#include <Security/mach++.h>
+#include <Security/cssmdb.h>
+#include <Security/osxsigning.h>
+#include <Security/Authorization.h>
+#include <Security/AuthSession.h>
+
+
+namespace Security
+{
+
+using MachPlusPlus::Port;
+using MachPlusPlus::ReceivePort;
+
+
+namespace SecurityServer
+{
+
+//
+// Common data types
+//
+typedef CSSM_HANDLE KeyHandle;
+typedef CSSM_HANDLE DbHandle;
+	
+static const CSSM_HANDLE noDb = 0;
+static const CSSM_HANDLE noKey = 0;
+
+struct KeyUID {
+    uint8 signature[20];
+};
+
+struct AuthorizationBlob {
+    uint32 data[2];
+	
+	bool operator < (const AuthorizationBlob &other) const
+	{ return memcmp(data, other.data, sizeof(data)) < 0; }
+	
+	bool operator == (const AuthorizationBlob &other) const
+	{ return memcmp(data, other.data, sizeof(data)) == 0; }
+    
+    size_t hash() const {	//@@@ revisit this hash
+        return data[0] ^ data[1] << 3;
+    }
+};
+
+enum AclKind { dbAcl, keyAcl, loginAcl };
+
+
+//
+// Database parameter structure
+//
+class DBParameters {
+public:
+	uint32 idleTimeout;				// seconds idle timout lock
+	uint8 lockOnSleep;				// lock keychain when system sleeps
+};
+
+
+//
+// A client connection (session)
+//
+class ClientSession {
+	NOCOPY(ClientSession)
+public:
+	ClientSession(CssmAllocator &standard, CssmAllocator &returning);
+	virtual ~ClientSession();
+	
+	CssmAllocator &internalAllocator;
+	CssmAllocator &returnAllocator;
+	
+public:
+	typedef CSSM_DB_ACCESS_TYPE DBAccessType;
+	
+public:
+	void activate();
+	void terminate();
+
+public:
+	// database sessions
+	DbHandle createDb(const DLDbIdentifier &dbId,
+        const AccessCredentials *cred, const AclEntryInput *owner,
+        const DBParameters &params);
+	DbHandle decodeDb(const DLDbIdentifier &dbId,
+        const AccessCredentials *cred, const CssmData &blob);
+	void encodeDb(DbHandle db, CssmData &blob, CssmAllocator &alloc);
+    void encodeDb(DbHandle db, CssmData &blob) { return encodeDb(db, blob, returnAllocator); }
+	void releaseDb(DbHandle db);
+	void authenticateDb(DbHandle db, DBAccessType type, const AccessCredentials *cred);
+	void setDbParameters(DbHandle db, const DBParameters &params);
+	void getDbParameters(DbHandle db, DBParameters &params);
+    void changePassphrase(DbHandle db, const AccessCredentials *cred);
+    void lock(DbHandle db);
+    void unlock(DbHandle db);
+    void unlock(DbHandle db, const CssmData &passPhrase);
+    bool isLocked(DbHandle db);
+	
+	// key objects
+	void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid, CssmAllocator &alloc);
+	void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid = NULL)
+    { return encodeKey(key, blob, uid, returnAllocator); }
+	KeyHandle decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header);
+	void releaseKey(KeyHandle key);
+
+public:
+    // key wrapping and unwrapping
+	void wrapKey(const Context &context, KeyHandle key, KeyHandle keyToBeWrapped,
+		const AccessCredentials *cred,
+		const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, CssmAllocator &alloc);
+	void wrapKey(const Context &context, KeyHandle key, KeyHandle keyToBeWrapped,
+		const AccessCredentials *cred,
+		const CssmData *descriptiveData, CssmWrappedKey &wrappedKey)
+    { return wrapKey(context, key, keyToBeWrapped, cred,
+        descriptiveData, wrappedKey, returnAllocator); }
+    
+	void unwrapKey(DbHandle db, const Context &context, KeyHandle key, KeyHandle publicKey,
+		const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr,
+		const AccessCredentials *cred, const AclEntryInput *owner,
+		CssmData &data, KeyHandle &newKey, CssmKey::Header &newKeyHeader, CssmAllocator &alloc);
+	void unwrapKey(DbHandle db, const Context &context, KeyHandle key, KeyHandle publicKey,
+		const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr,
+		const AccessCredentials *cred, const AclEntryInput *owner, CssmData &data,
+        KeyHandle &newKey, CssmKey::Header &newKeyHeader)
+    { return unwrapKey(db, context, key, publicKey, wrappedKey, keyUsage, keyAttr,
+      cred, owner, data, newKey, newKeyHeader, returnAllocator); }
+
+    // key generation and derivation
+	void generateKey(DbHandle db, const Context &context, uint32 keyUsage, uint32 keyAttr,
+		const AccessCredentials *cred, const AclEntryInput *owner,
+        KeyHandle &newKey, CssmKey::Header &newHeader);
+	void generateKey(DbHandle db, const Context &context,
+		uint32 pubKeyUsage, uint32 pubKeyAttr,
+		uint32 privKeyUsage, uint32 privKeyAttr,
+		const AccessCredentials *cred, const AclEntryInput *owner,
+		KeyHandle &pubKey, CssmKey::Header &pubHeader,
+        KeyHandle &privKey, CssmKey::Header &privHeader);
+	void deriveKey(DbHandle db, KeyHandle &newKey, CssmKey::Header &newHeader);
+	//void generateAlgorithmParameters();	// not implemented
+
+	void generateRandom(CssmData &data);
+	
+    // encrypt/decrypt
+	void encrypt(const Context &context, KeyHandle key,
+        const CssmData &in, CssmData &out, CssmAllocator &alloc);
+	void encrypt(const Context &context, KeyHandle key, const CssmData &in, CssmData &out)
+    { return encrypt(context, key, in, out, returnAllocator); }
+	void decrypt(const Context &context, KeyHandle key,
+        const CssmData &in, CssmData &out, CssmAllocator &alloc);
+	void decrypt(const Context &context, KeyHandle key, const CssmData &in, CssmData &out)
+    { return decrypt(context, key, in, out, returnAllocator); }
+
+    // signatures
+	void generateSignature(const Context &context, KeyHandle key,
+		const CssmData &data, CssmData &signature, CssmAllocator &alloc);
+	void generateSignature(const Context &context, KeyHandle key,
+		const CssmData &data, CssmData &signature)
+    { return generateSignature(context, key, data, signature, returnAllocator); }
+	void verifySignature(const Context &context, KeyHandle key,
+		const CssmData &data, const CssmData &signature);
+		
+    // MACs
+	void generateMac(const Context &context, KeyHandle key,
+		const CssmData &data, CssmData &mac, CssmAllocator &alloc);
+	void generateMac(const Context &context, KeyHandle key,
+		const CssmData &data, CssmData &mac)
+    { return generateMac(context, key, data, mac, returnAllocator); }
+	void verifyMac(const Context &context, KeyHandle key,
+		const CssmData &data, const CssmData &mac);
+	uint32 queryKeySizeInBits(KeyHandle key);
+	
+    // key ACL management
+	void getKeyAcl(KeyHandle key, const char *tag,
+        uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc);
+	void getKeyAcl(KeyHandle key, const char *tag,
+        uint32 &count, AclEntryInfo * &info)
+    { return getKeyAcl(key, tag, count, info, returnAllocator); }
+	void changeKeyAcl(KeyHandle key, const AccessCredentials &cred, const AclEdit &edit);
+	void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner, CssmAllocator &alloc);
+	void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner)
+    { return getKeyOwner(key, owner, returnAllocator); }
+	void changeKeyOwner(KeyHandle key, const AccessCredentials &cred,
+		const AclOwnerPrototype &edit);
+	
+    // database ACL management
+	void getDbAcl(DbHandle db, const char *tag,
+        uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc);
+	void getDbAcl(DbHandle db, const char *tag,
+        uint32 &count, AclEntryInfo * &info)
+    { return getDbAcl(db, tag, count, info, returnAllocator); }
+	void changeDbAcl(DbHandle db, const AccessCredentials &cred, const AclEdit &edit);
+	void getDbOwner(DbHandle db, AclOwnerPrototype &owner, CssmAllocator &alloc);
+	void getDbOwner(DbHandle db, AclOwnerPrototype &owner)
+    { return getDbOwner(db, owner, returnAllocator); }
+    void changeDbOwner(DbHandle db, const AccessCredentials &cred,
+		const AclOwnerPrototype &edit);
+		
+public:
+	// Authorization API support
+	void authCreate(const AuthorizationItemSet *rights,	const AuthorizationItemSet *environment, 
+		AuthorizationFlags flags,AuthorizationBlob &result);
+	void authRelease(const AuthorizationBlob &auth, AuthorizationFlags flags);
+	void authCopyRights(const AuthorizationBlob &auth,
+		const AuthorizationItemSet *rights, const AuthorizationItemSet *environment,
+		AuthorizationFlags flags, AuthorizationItemSet **result);
+	void authCopyInfo(const AuthorizationBlob &auth, const char *tag, AuthorizationItemSet * &info);
+	void authExternalize(const AuthorizationBlob &auth, AuthorizationExternalForm &extForm);
+	void authInternalize(const AuthorizationExternalForm &extForm, AuthorizationBlob &auth);
+    
+public:
+    // Session API support
+    void getSessionInfo(SecuritySessionId &sessionId, SessionAttributeBits &attrs);
+    void setupSession(SessionCreationFlags flags, SessionAttributeBits attrs);
+	
+private:
+	void getAcl(AclKind kind, KeyHandle key, const char *tag,
+		uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc);
+	void changeAcl(AclKind kind, KeyHandle key,
+		const AccessCredentials &cred, const AclEdit &edit);
+	void getOwner(AclKind kind, KeyHandle key, AclOwnerPrototype &owner, CssmAllocator &alloc);
+	void changeOwner(AclKind kind, KeyHandle key, const AccessCredentials &cred,
+		const AclOwnerPrototype &edit);
+
+private:
+	struct Thread {
+		Thread() : replyPort(mig_get_reply_port()), registered(false) { }
+		operator bool() const { return registered; }
+		
+		Port replyPort;			// cached mig_get_reply_port
+        bool registered;		// has been registered with SecurityServer
+	};
+
+	struct Global {
+        Global();
+		Port serverPort;
+		CodeSigning::OSXCode *myself;
+		ThreadNexus<Thread> thread;
+	};
+
+	static ModuleNexus<Global> mGlobal;
+};
+
+
+} // end namespace SecurityServer
+
+} // end namespace Security
+
+
+#endif //_H_SSCLIENT
diff --git a/SecurityServer/sstransit.cpp b/SecurityServer/sstransit.cpp
new file mode 100644
index 00000000..02c0dcd7
--- /dev/null
+++ b/SecurityServer/sstransit.cpp
@@ -0,0 +1,533 @@
+/*
+ * 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.
+ */
+
+
+//
+// sstransit - SecurityServer client library transition code.
+//
+// These are the functions that implement CssmClient methods in terms of
+// MIG IPC client calls, plus their supporting machinery.
+//
+#include "sstransit.h"
+
+namespace Security
+{
+
+using MachPlusPlus::check;
+
+
+//
+// Utility classes
+//
+DataOutput::~DataOutput()
+{
+	if (mData) {	// was assigned to; IPC returned OK
+		if (argument) {	// buffer was provided
+			if (argument.length() < mLength)
+				CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+			argument.length(mLength);
+		} else {	// allocate buffer
+			argument = CssmData(allocator.malloc(mLength), mLength);
+		}
+		memcpy(argument.data(), mData, mLength);
+	}
+}
+
+
+CssmList chunkCopy(CssmList &list, CssmAllocator &alloc)
+{
+	CssmList copy = list;
+	ChunkCopyWalker w(alloc);
+	walk(w, copy);
+	return copy;
+}
+
+
+//
+// Create a packaged-up Context for IPC transmission.
+// In addition to collecting the context into a contiguous blob for transmission,
+// we also evaluate CssmCryptoData callbacks at this time.
+//
+SendContext::SendContext(const Context &ctx) : context(ctx)
+{
+	CssmCryptoData cryptoDataValue;	// holding area for CssmCryptoData element
+	IFDEBUG(uint32 cryptoDataUsed = 0);
+	Context::Builder builder(CssmAllocator::standard());
+	for (unsigned n = 0; n < ctx.attributesInUse(); n++) {
+		switch (ctx[n].baseType()) {
+		case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA: {
+			CssmCryptoData &data = ctx[n];	// extract CssmCryptoData value
+			cryptoDataValue = data();		// evaluate callback (if any)
+			builder.setup(&cryptoDataValue); // use evaluted value
+			IFDEBUG(cryptoDataUsed++);
+			break;
+		}
+		default:
+			builder.setup(ctx[n]);
+			break;
+		}
+	}
+	attributeSize = builder.make();
+	for (unsigned n = 0; n < ctx.attributesInUse(); n++) {
+		const Context::Attr &attr = ctx[n];
+		switch (attr.baseType()) {
+		case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA:
+			builder.put(attr.type(), &cryptoDataValue);
+			break;
+		default:
+			builder.put(attr);
+			break;
+		}
+	}
+	uint32 count;	// not needed
+	builder.done(attributes, count);
+	assert(cryptoDataUsed <= 1);	// no more than one slot converted
+}
+
+
+namespace SecurityServer
+{
+
+//
+// Database control
+//
+DbHandle ClientSession::createDb(const DLDbIdentifier &dbId,
+    const AccessCredentials *cred, const AclEntryInput *owner,
+    const DBParameters &params)
+{
+	Copier<AccessCredentials> creds(cred, internalAllocator);
+	Copier<AclEntryPrototype> proto(&owner->proto(), internalAllocator);
+    DataWalkers::DLDbFlatIdentifier ident(dbId);
+    Copier<DataWalkers::DLDbFlatIdentifier> id(&ident, internalAllocator);
+	DbHandle db;
+	IPC(ucsp_client_createDb(UCSP_ARGS, &db, COPY(id), COPY(creds), COPY(proto), params));
+	return db;
+}
+
+DbHandle ClientSession::decodeDb(const DLDbIdentifier &dbId,
+    const AccessCredentials *cred, const CssmData &blob)
+{
+	Copier<AccessCredentials> creds(cred, internalAllocator);
+    DataWalkers::DLDbFlatIdentifier ident(dbId);
+    Copier<DataWalkers::DLDbFlatIdentifier> id(&ident, internalAllocator);
+	DbHandle db;
+	IPC(ucsp_client_decodeDb(UCSP_ARGS, &db, COPY(id), COPY(creds), DATA(blob)));
+	return db;
+}
+
+void ClientSession::encodeDb(DbHandle db, CssmData &blob, CssmAllocator &alloc)
+{
+	DataOutput outBlob(blob, alloc);
+	IPC(ucsp_client_encodeDb(UCSP_ARGS, db, DATA(outBlob)));
+}
+
+void ClientSession::releaseDb(DbHandle db)
+{
+	IPC(ucsp_client_releaseDb(UCSP_ARGS, db));
+}
+
+void ClientSession::authenticateDb(DbHandle db, DBAccessType type,
+	const AccessCredentials *cred)
+{
+    Copier<AccessCredentials> creds(cred, internalAllocator);
+	IPC(ucsp_client_authenticateDb(UCSP_ARGS, db, COPY(creds)));
+}
+
+void ClientSession::setDbParameters(DbHandle db, const DBParameters &params)
+{
+	IPC(ucsp_client_setDbParameters(UCSP_ARGS, db, params));
+}
+
+void ClientSession::getDbParameters(DbHandle db, DBParameters &params)
+{
+	IPC(ucsp_client_getDbParameters(UCSP_ARGS, db, &params));
+}
+
+void ClientSession::changePassphrase(DbHandle db, const AccessCredentials *cred)
+{
+    Copier<AccessCredentials> creds(cred, internalAllocator);
+    IPC(ucsp_client_changePassphrase(UCSP_ARGS, db, COPY(creds)));
+}
+
+
+void ClientSession::lock(DbHandle db)
+{
+	IPC(ucsp_client_lockDb(UCSP_ARGS, db));
+}
+
+void ClientSession::unlock(DbHandle db)
+{
+	IPC(ucsp_client_unlockDb(UCSP_ARGS, db));
+}
+
+void ClientSession::unlock(DbHandle db, const CssmData &passphrase)
+{
+	IPC(ucsp_client_unlockDbWithPassphrase(UCSP_ARGS, db, DATA(passphrase)));
+}
+
+bool ClientSession::isLocked(DbHandle db)
+{
+    boolean_t locked;
+	IPC(ucsp_client_isLocked(UCSP_ARGS, db, &locked));
+    return locked;
+}
+
+
+//
+// Key control
+//
+void ClientSession::encodeKey(KeyHandle key, CssmData &blob,
+    KeyUID *uid, CssmAllocator &alloc)
+{
+	DataOutput oBlob(blob, alloc);
+    void *uidp;
+    mach_msg_type_number_t uidLength;
+	IPC(ucsp_client_encodeKey(UCSP_ARGS, key, oBlob.data(), oBlob.length(),
+        (uid != NULL), &uidp, &uidLength));
+    // return key uid if requested
+    if (uid) {
+        assert(uidLength == sizeof(KeyUID));
+        memcpy(uid, uidp, sizeof(KeyUID));
+    }
+}
+
+
+KeyHandle ClientSession::decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header)
+{
+	KeyHandle key;
+	IPC(ucsp_client_decodeKey(UCSP_ARGS, &key, &header, db, blob.data(), blob.length()));
+	return key;
+}
+
+void ClientSession::releaseKey(KeyHandle key)
+{
+	IPC(ucsp_client_releaseKey(UCSP_ARGS, key));
+}
+
+
+//
+// Random number generation.
+// This interfaces to the secure RNG inside the SecurityServer; it does not access
+// a PRNG in its CSP. If you need a reproducible PRNG, attach a local CSP and use it.
+// Note that this function does not allocate a buffer; it always fills the buffer provided.
+//
+void ClientSession::generateRandom(CssmData &data)
+{
+	void *result;
+	mach_msg_type_number_t resultLength;
+	IPC(ucsp_client_generateRandom(UCSP_ARGS, data.length(), &result, &resultLength));
+	assert(resultLength == data.length());
+	memcpy(data.data(), result, data.length());
+}
+
+
+//
+// Signatures and MACs
+//
+void ClientSession::generateSignature(const Context &context, KeyHandle key,
+	const CssmData &data, CssmData &signature, CssmAllocator &alloc)
+{
+	SendContext ctx(context);
+	DataOutput sig(signature, alloc);
+	IPC(ucsp_client_generateSignature(UCSP_ARGS, CONTEXT(ctx), key,
+		DATA(data), DATA(sig)));
+}
+
+void ClientSession::verifySignature(const Context &context, KeyHandle key,
+	const CssmData &data, const CssmData &signature)
+{
+	SendContext ctx(context);
+	IPC(ucsp_client_verifySignature(UCSP_ARGS, CONTEXT(ctx), key,
+		DATA(data), DATA(signature)));
+}
+
+
+void ClientSession::generateMac(const Context &context, KeyHandle key,
+	const CssmData &data, CssmData &signature, CssmAllocator &alloc)
+{
+	SendContext ctx(context);
+	DataOutput sig(signature, alloc);
+	IPC(ucsp_client_generateMac(UCSP_ARGS, CONTEXT(ctx), key,
+		DATA(data), DATA(sig)));
+}
+
+void ClientSession::verifyMac(const Context &context, KeyHandle key,
+	const CssmData &data, const CssmData &signature)
+{
+	SendContext ctx(context);
+	IPC(ucsp_client_verifyMac(UCSP_ARGS, CONTEXT(ctx), key,
+		DATA(data), DATA(signature)));
+}
+
+
+//
+// Encryption/Decryption
+//
+	
+void ClientSession::encrypt(const Context &context, KeyHandle key,
+	const CssmData &clear, CssmData &cipher, CssmAllocator &alloc)
+{
+	SendContext ctx(context);
+	DataOutput cipherOut(cipher, alloc);
+	IPC(ucsp_client_encrypt(UCSP_ARGS, CONTEXT(ctx), key, DATA(clear), DATA(cipherOut)));
+}
+
+void ClientSession::decrypt(const Context &context, KeyHandle key,
+	const CssmData &cipher, CssmData &clear, CssmAllocator &alloc)
+{
+	SendContext ctx(context);
+	DataOutput clearOut(clear, alloc);
+	IPC(ucsp_client_decrypt(UCSP_ARGS, CONTEXT(ctx), key, DATA(cipher), DATA(clearOut)));
+}
+
+
+//
+// Key generation
+//
+void ClientSession::generateKey(DbHandle db, const Context &context, uint32 keyUsage, uint32 keyAttr,
+    const AccessCredentials *cred, const AclEntryInput *owner,
+    KeyHandle &newKey, CssmKey::Header &newHeader)
+{
+	SendContext ctx(context);
+	Copier<AccessCredentials> creds(cred, internalAllocator);
+	Copier<AclEntryPrototype> proto(&owner->proto(), internalAllocator);
+	IPC(ucsp_client_generateKey(UCSP_ARGS, db, CONTEXT(ctx),
+		COPY(creds), COPY(proto), keyUsage, keyAttr, &newKey, &newHeader));
+}
+
+void ClientSession::generateKey(DbHandle db, const Context &context,
+    uint32 pubKeyUsage, uint32 pubKeyAttr,
+    uint32 privKeyUsage, uint32 privKeyAttr,
+    const AccessCredentials *cred, const AclEntryInput *owner,
+    KeyHandle &pubKey, CssmKey::Header &pubHeader,
+    KeyHandle &privKey, CssmKey::Header &privHeader)
+{
+	SendContext ctx(context);
+	Copier<AccessCredentials> creds(cred, internalAllocator);
+	Copier<AclEntryPrototype> proto(&owner->proto(), internalAllocator);
+	IPC(ucsp_client_generateKeyPair(UCSP_ARGS, db, CONTEXT(ctx),
+		COPY(creds), COPY(proto),
+		pubKeyUsage, pubKeyAttr, privKeyUsage, privKeyAttr,
+		&pubKey, &pubHeader, &privKey, &privHeader));
+}
+
+
+//
+// Key wrapping and unwrapping
+//
+void ClientSession::wrapKey(const Context &context, KeyHandle wrappingKey,
+    KeyHandle keyToBeWrapped, const AccessCredentials *cred,
+	const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, CssmAllocator &alloc)
+{
+	SendContext ctx(context);
+	Copier<AccessCredentials> creds(cred, internalAllocator);
+	DataOutput keyData(wrappedKey, alloc);
+	IPC(ucsp_client_wrapKey(UCSP_ARGS, CONTEXT(ctx), wrappingKey, COPY(creds),
+		keyToBeWrapped, OPTIONALDATA(descriptiveData),
+		&wrappedKey, DATA(keyData)));
+	wrappedKey = CssmData();	// null out data section (force allocation for key data)
+}
+
+void ClientSession::unwrapKey(DbHandle db, const Context &context, KeyHandle key,
+    KeyHandle publicKey, const CssmWrappedKey &wrappedKey,
+	uint32 usage, uint32 attr,
+	const AccessCredentials *cred, const AclEntryInput *acl,
+	CssmData &descriptiveData,
+    KeyHandle &newKey, CssmKey::Header &newHeader, CssmAllocator &alloc)
+{
+	SendContext ctx(context);
+	DataOutput descriptor(descriptiveData, alloc);
+	Copier<AccessCredentials> creds(cred, internalAllocator);
+	Copier<AclEntryPrototype> proto(&acl->proto(), internalAllocator);
+	IPC(ucsp_client_unwrapKey(UCSP_ARGS, db, CONTEXT(ctx), key,
+		COPY(creds), COPY(proto),
+		publicKey, wrappedKey, DATA(wrappedKey), usage, attr, DATA(descriptor),
+        &newKey, &newHeader));
+}
+
+
+//
+// ACL management
+//
+void ClientSession::getAcl(AclKind kind, KeyHandle key, const char *tag,
+	uint32 &infoCount, AclEntryInfo * &infoArray, CssmAllocator &alloc)
+{
+	uint32 count;
+	AclEntryInfo *info, *infoBase;
+	mach_msg_type_number_t infoLength;
+	IPC(ucsp_client_getAcl(UCSP_ARGS, kind, key,
+		(tag != NULL), tag ? tag : "",
+		&count, COPY_OUT(info)));
+	infoCount = count;
+
+	// relocate incoming AclEntryInfo array
+	ReconstituteWalker relocator(info, infoBase);
+	for (uint32 n = 0; n < count; n++)
+		walk(relocator, info[n]);
+	
+	// copy AclEntryInfo array into discrete memory nodes
+	infoArray = alloc.alloc<AclEntryInfo>(count);
+	ChunkCopyWalker chunker(alloc);
+	for (uint32 n = 0; n < count; n++) {
+		infoArray[n] = info[n];
+		walk(chunker, infoArray[n]);
+	}
+}
+
+void ClientSession::changeAcl(AclKind kind, KeyHandle key, const AccessCredentials &cred,
+	const AclEdit &edit)
+{
+	Copier<AccessCredentials> creds(&cred, internalAllocator);
+	//@@@ ignoring callback
+	Copier<AclEntryPrototype> aclEntry(&edit.newEntry()->proto(), internalAllocator);
+	IPC(ucsp_client_changeAcl(UCSP_ARGS, kind, key, COPY(creds),
+		edit.mode(), edit.handle(), COPY(aclEntry)));
+}
+
+void ClientSession::getOwner(AclKind kind, KeyHandle key, AclOwnerPrototype &owner,
+    CssmAllocator &alloc)
+{
+	AclOwnerPrototype *proto, *protoBase;
+	mach_msg_type_number_t protoLength;
+	IPC(ucsp_client_getOwner(UCSP_ARGS, kind, key, COPY_OUT(proto)));
+	// turn the returned AclOwnerPrototype into its proper output form
+	relocate(proto, protoBase);
+	owner.TypedSubject = chunkCopy(proto->subject(), alloc);
+	owner.Delegate = proto->delegate();
+}
+
+void ClientSession::changeOwner(AclKind kind, KeyHandle key,
+	const AccessCredentials &cred, const AclOwnerPrototype &proto)
+{
+	Copier<AccessCredentials> creds(&cred, internalAllocator);
+	Copier<AclOwnerPrototype> protos(&proto, internalAllocator);
+	IPC(ucsp_client_setOwner(UCSP_ARGS, kind, key, COPY(creds), COPY(protos)));
+}
+
+
+void ClientSession::getKeyAcl(DbHandle db, const char *tag,
+	uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc)
+{ getAcl(keyAcl, db, tag, count, info, alloc); }
+
+void ClientSession::changeKeyAcl(DbHandle db, const AccessCredentials &cred,
+	const AclEdit &edit)
+{ changeAcl(keyAcl, db, cred, edit); }
+
+void ClientSession::getKeyOwner(DbHandle db, AclOwnerPrototype &owner, CssmAllocator &alloc)
+{ getOwner(keyAcl, db, owner, alloc); }
+
+void ClientSession::changeKeyOwner(DbHandle db, const AccessCredentials &cred,
+	const AclOwnerPrototype &edit)
+{ changeOwner(keyAcl, db, cred, edit); }
+
+void ClientSession::getDbAcl(DbHandle db, const char *tag,
+	uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc)
+{ getAcl(dbAcl, db, tag, count, info, alloc); }
+
+void ClientSession::changeDbAcl(DbHandle db, const AccessCredentials &cred,
+	const AclEdit &edit)
+{ changeAcl(dbAcl, db, cred, edit); }
+
+void ClientSession::getDbOwner(DbHandle db, AclOwnerPrototype &owner, CssmAllocator &alloc)
+{ getOwner(dbAcl, db, owner, alloc); }
+
+void ClientSession::changeDbOwner(DbHandle db, const AccessCredentials &cred,
+	const AclOwnerPrototype &edit)
+{ changeOwner(dbAcl, db, cred, edit); }
+
+
+//
+// Authorization subsystem entry
+//
+void ClientSession::authCreate(const AuthorizationItemSet *rights,
+	const AuthorizationItemSet *environment, AuthorizationFlags flags,
+	AuthorizationBlob &result)
+{
+	Copier<AuthorizationItemSet> rightSet(rights, internalAllocator);
+	Copier<AuthorizationItemSet> environ(environment, internalAllocator);
+	IPC(ucsp_client_authorizationCreate(UCSP_ARGS,
+		COPY(rightSet), flags, COPY(environ), &result));
+}
+
+void ClientSession::authRelease(const AuthorizationBlob &auth, 
+	AuthorizationFlags flags)
+{
+	IPC(ucsp_client_authorizationRelease(UCSP_ARGS, auth, flags));
+}
+
+void ClientSession::authCopyRights(const AuthorizationBlob &auth,
+	const AuthorizationItemSet *rights, const AuthorizationItemSet *environment,
+	AuthorizationFlags flags,
+	AuthorizationItemSet **grantedRights)
+{
+	Copier<AuthorizationItemSet> rightSet(rights, internalAllocator);
+	Copier<AuthorizationItemSet> environ(environment, internalAllocator);
+	COPY_OUT_DECL(AuthorizationItemSet, result);
+	IPC(ucsp_client_authorizationCopyRights(UCSP_ARGS, auth, COPY(rightSet),
+		flags | (grantedRights ? 0 : kAuthorizationFlagNoData),
+		COPY(environ), COPY_OUT(result)));
+	// return rights vector (only) if requested
+	if (grantedRights) {
+		relocate(result, resultBase);
+		*grantedRights = copy(result, returnAllocator);
+	}
+}
+
+void ClientSession::authCopyInfo(const AuthorizationBlob &auth,
+	const char *tag,
+	AuthorizationItemSet * &info)
+{
+	COPY_OUT_DECL(AuthorizationItemSet, result);
+    if (tag == NULL)
+        tag = "";
+    else if (tag[0] == '\0')
+        MacOSError::throwMe(errAuthorizationInvalidTag);
+	IPC(ucsp_client_authorizationCopyInfo(UCSP_ARGS, auth, tag, COPY_OUT(result)));
+	relocate(result, resultBase);
+	info = copy(result, returnAllocator);
+}
+
+void ClientSession::authExternalize(const AuthorizationBlob &auth,
+	AuthorizationExternalForm &extForm)
+{
+	IPC(ucsp_client_authorizationExternalize(UCSP_ARGS, auth, &extForm));
+}
+
+void ClientSession::authInternalize(const AuthorizationExternalForm &extForm,
+	AuthorizationBlob &auth)
+{
+	IPC(ucsp_client_authorizationInternalize(UCSP_ARGS, extForm, &auth));
+}
+
+
+//
+// Session management API
+//
+void ClientSession::getSessionInfo(SecuritySessionId &sessionId, SessionAttributeBits &attrs)
+{
+    IPC(ucsp_client_getSessionInfo(UCSP_ARGS, &sessionId, &attrs));
+}
+
+void ClientSession::setupSession(SessionCreationFlags flags, SessionAttributeBits attrs)
+{
+    IPC(ucsp_client_setupSession(UCSP_ARGS, flags, attrs));
+}
+
+
+} // end namespace SecurityServer
+
+} // end namespace Security
diff --git a/SecurityServer/sstransit.h b/SecurityServer/sstransit.h
new file mode 100644
index 00000000..8a51eda5
--- /dev/null
+++ b/SecurityServer/sstransit.h
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+
+//
+// sstransit - SecurityServer client library transition code.
+//
+// These are the functions that implement CssmClient methods in terms of
+// MIG IPC client calls, plus their supporting machinery.
+//
+// WARNING! HERE BE DRAGONS!
+// This code involves moderately arcane magic including (but not limited to)
+// dancing macros paired off with self-maintaining stack objects. Don't take
+// anything for granted! Be very afraid of ALL-CAPS names. Your best bet is
+// probably to stick with the existing patterns.
+//
+#ifndef _H_SSTRANSIT
+#define _H_SSTRANSIT
+
+#include "ssclient.h"
+#include <Security/mach++.h>
+#include <Security/cssmwalkers.h>
+#include <Security/AuthorizationWalkers.h>
+#include "ucsp.h"
+
+namespace Security
+{
+
+// stock leading argument profile used by all calls
+#define UCSP_ARGS	mGlobal().serverPort, mig_get_reply_port(), &rcode
+
+// IPC/IPCN wrap the actual Mach IPC call. IPC also activates the connection first
+#define IPCN(statement) \
+	{ CSSM_RETURN rcode; check(statement); if (rcode != CSSM_OK) CssmError::throwMe(rcode); }
+#define IPC(statement)	{ activate(); IPCN(statement); }
+
+// pass mandatory or optional CssmData arguments into an IPC call
+#define DATA(arg)			arg.data(), arg.length()
+#define OPTIONALDATA(arg)	(arg ? arg->data() : NULL), (arg ? arg->length() : 0)
+
+// pass structured arguments in/out of IPC calls. See "data walkers" for details
+#define COPY(copy)			copy, copy.length(), copy
+#define COPY_OUT(copy)		&copy, &copy##Length, &copy##Base
+#define COPY_OUT_DECL(type,name) type *name, *name##Base; mach_msg_type_number_t name##Length
+
+
+//
+// DataOutput manages an output CssmData argument.
+//
+class DataOutput {
+public:
+	DataOutput(CssmData &arg, CssmAllocator &alloc)
+		: argument(arg), allocator(alloc) { mData = NULL; }
+	~DataOutput();
+	
+	void **data() { return &mData; }
+	mach_msg_type_number_t *length() { return &mLength; }
+	
+	CssmData &argument;
+	CssmAllocator &allocator;
+
+private:
+	void *mData;
+	mach_msg_type_number_t mLength;
+};
+
+
+//
+// Bundle up a Context for IPC transmission
+//
+class SendContext {
+public:
+	SendContext(const Context &ctx);
+	~SendContext() { CssmAllocator::standard().free(attributes); }
+	
+	const Context &context;
+	CSSM_CONTEXT_ATTRIBUTE *attributes;
+	size_t attributeSize;
+};
+
+#define CONTEXT(ctx)	ctx.context, ctx.attributes, ctx.attributes, ctx.attributeSize
+
+} // end namespace Security
+
+#endif //_H_SSTRANSIT
diff --git a/SecurityServer/tests/AZNTest.cpp b/SecurityServer/tests/AZNTest.cpp
new file mode 100644
index 00000000..a9c263bb
--- /dev/null
+++ b/SecurityServer/tests/AZNTest.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+
+/*
+ *  AZNTest.cpp
+ *  SecurityServer
+ *
+ *  Created by michael on Fri Oct 20 2000.
+ *  Copyright (c) 2000 Apple Computer Inc. All rights reserved.
+ *
+ */
+
+#include <Security/Authorization.h>
+
+#include <Security/AuthorizationEngine.h>
+
+using namespace Authorization;
+
+static const AuthorizationItem gItems[] =
+{
+	{"login", 0, NULL, NULL},
+	{"reboot", 0, NULL, NULL},
+	{"shutdown", 0, NULL, NULL},
+	{"mount", 0, NULL, NULL},
+	{"login.reboot", 0, NULL, NULL},
+	{"login.shutdown", 0, NULL, NULL},
+	{"unmount", 0, NULL, NULL}
+};
+
+static const AuthorizationRights gRights =
+{
+	7,
+	const_cast<AuthorizationItem *>(gItems)
+};
+
+void
+printRights(const RightSet &rightSet)
+{
+	for(RightSet::const_iterator it = rightSet.begin(); it != rightSet.end(); ++it)
+	{
+		printf("right: \"%s\"\n", it->rightName());
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	Engine engine("/tmp/config.plist");
+
+	const RightSet inputRights(&gRights);
+	MutableRightSet outputRights;
+	printf("InputRights:\n");
+	printRights(inputRights);
+	printf("Authorizing:\n");
+	OSStatus result = engine.authorize(inputRights, NULL,
+		kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights | kAuthorizationFlagPartialRights,
+		NULL, NULL, &outputRights);
+	printf("Result: %ld\n", result);
+	printf("OutputRights:\n");
+	printRights(outputRights);
+	return 0;
+}
diff --git a/SecurityServer/tests/auth.plist b/SecurityServer/tests/auth.plist
new file mode 100644
index 00000000..b9732dc9
--- /dev/null
+++ b/SecurityServer/tests/auth.plist
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+	<key>debug.</key>
+	<dict>
+		<key>group</key>
+		<string>yes</string>
+		<key>shared</key>
+		<true/>
+		<key>timeout</key>
+		<integer>300</integer>
+	</dict>
+	<key>debug.allow</key>
+	<string>allow</string>
+	<key>debug.deny</key>
+	<string>deny</string>
+</dict>
+</plist>
diff --git a/SecurityServer/tests/exectest.cpp b/SecurityServer/tests/exectest.cpp
new file mode 100644
index 00000000..4449f37a
--- /dev/null
+++ b/SecurityServer/tests/exectest.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+
+//
+// Exectest - privileged-execution test driver
+//
+#include <Security/Authorization.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+
+void doLoopback(int argc, char *argv[]);
+
+
+int main(int argc, char **argv)
+{
+	const char *path = "/usr/bin/id";
+	bool writeToPipe = false;
+	bool loopback = false;
+	
+	int arg;
+	extern char *optarg;
+	extern int optind;
+	while ((arg = getopt(argc, argv, "f:lLw")) != -1) {
+		switch (arg) {
+		case 'f':
+			path = optarg;
+			break;
+		case 'l':
+			loopback = true;
+			break;
+		case 'L':
+			doLoopback(argc, argv);
+			exit(0);
+		case 'w':
+			writeToPipe = true;
+			break;
+		case '?':
+			exit(2);
+		}
+	}
+	
+	AuthorizationItem right = { "system.privilege.admin", 0, NULL, 0 };
+	AuthorizationRights rights = { 1, &right };
+
+	AuthorizationRef auth;
+	if (OSStatus error = AuthorizationCreate(&rights, NULL /*env*/,
+		kAuthorizationFlagInteractionAllowed |
+		kAuthorizationFlagExtendRights |
+		kAuthorizationFlagPreAuthorize,
+		&auth)) {
+		printf("create error %ld\n", error);
+		exit(1);
+	}
+	
+	if (loopback) {
+		path = argv[0];
+		argv[--optind] = "-L";	// backing over existing array element
+	}
+	
+	FILE *f;
+	if (OSStatus error = AuthorizationExecuteWithPrivileges(auth,
+		path, 0, argv + optind, &f)) {
+		printf("exec error %ld\n", error);
+		exit(1);
+	}
+	printf("--- execute successful ---\n");
+	if (writeToPipe) {
+		char buffer[1024];
+		while (fgets(buffer, sizeof(buffer), stdin))
+			fprintf(f, "%s", buffer);
+	} else {
+		char buffer[1024];
+		while (fgets(buffer, sizeof(buffer), f))
+			printf("%s", buffer);
+	}
+	printf("--- end of output ---\n");
+	exit(0);
+}
+
+
+void doLoopback(int argc, char *argv[])
+{
+	// general status
+	printf("Authorization Execution Loopback Test\n");
+	printf("Invoked as");
+	for (int n = 0; argv[n]; n++)
+		printf(" %s", argv[n]);
+	printf("\n");
+	
+	// recover the authorization handle
+	AuthorizationRef auth;
+	if (OSStatus err = AuthorizationCopyPrivilegedReference(&auth, 0)) {
+		printf("Cannot recover AuthorizationRef: error=%ld\n", err);
+		exit(1);
+	}
+	
+	printf("AuthorizationRef recovered.\n");
+}
diff --git a/SecurityServer/tests/testacls.cpp b/SecurityServer/tests/testacls.cpp
new file mode 100644
index 00000000..b5cb946e
--- /dev/null
+++ b/SecurityServer/tests/testacls.cpp
@@ -0,0 +1,403 @@
+/*
+ * 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.
+ */
+
+
+//
+// testacls - ACL-related test cases.
+// 
+#include "testclient.h"
+#include "testutils.h"
+#include <Security/osxsigner.h>
+
+using namespace CodeSigning;
+
+
+//
+// ACL get/set tests
+//
+void acls()
+{
+    printf("* Basic ACL tests\n");
+	CssmAllocator &alloc = CssmAllocator::standard();
+	ClientSession ss(alloc, alloc);
+	
+	// create key with initial ACL
+	StringData initialAclPassphrase("very secret");
+	AclEntryPrototype initialAcl;
+	initialAcl.TypedSubject = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD,
+		new(alloc) ListElement(initialAclPassphrase));
+	AclEntryInput initialAclInput(initialAcl);
+	AclTester tester(ss, &initialAclInput);
+	
+	// get the owner and verify
+	AclOwnerPrototype owner;
+	ss.getKeyOwner(tester.keyRef, owner);
+	assert(owner.subject().type() == CSSM_ACL_SUBJECT_TYPE_PASSWORD);
+	assert(owner.subject().length() == 1);
+	
+	// get the acl entry and verify
+	{
+		uint32 count;
+		AclEntryInfo *acls;
+		ss.getKeyAcl(tester.keyRef, NULL/*tag*/, count, acls);
+		assert(count == 1);
+		const AclEntryInfo &acl1 = acls[0];
+		const TypedList &subject1 = acl1.proto().subject();
+		assert(subject1.type() == CSSM_ACL_SUBJECT_TYPE_PASSWORD);
+		assert(subject1.length() == 1);
+	}
+	
+	// try to use the key and see...
+	tester.testWrap(&nullCred, "ACCEPTING NULL CREDENTIAL");
+	AutoCredentials cred(alloc);
+	cred += TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+		new(alloc) ListElement(StringData("wrongo")));
+	tester.testWrap(&cred, "ACCEPTING WRONG PASSWORD CREDENTIAL");
+	cred += TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+		new(alloc) ListElement(StringData("very secret")));
+	tester.testWrap(&cred);
+    
+    // now *replace* the ACL entry with a new one...
+    {
+        detail("Changing ACL");
+        uint32 count;
+        AclEntryInfo *infos;
+        ss.getKeyAcl(tester.keyRef, NULL, count, infos);
+        assert(count == 1);	// one entry
+        
+        AclEntryPrototype newAcl;
+        TypedList subject = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_THRESHOLD,
+            new(alloc) ListElement(2), new(alloc) ListElement(3));
+        subject += new(alloc) ListElement(TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "check me!")));
+        subject += new(alloc) ListElement(TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "once again!")));
+        subject += new(alloc) ListElement(TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "hug me!")));
+        newAcl.TypedSubject = subject;
+        AclEntryInput input(newAcl);
+        AclEdit edit(infos[0].handle(), input);
+        
+        try {
+            AutoCredentials nullCred(alloc);
+            ss.changeKeyAcl(tester.keyRef, nullCred, edit);
+            error("ALLOWED ACL EDIT WITHOUT CREDENTIALS");
+        } catch (CssmCommonError &err) {
+            detail(err, "Acl Edit rejected properly");
+        }
+        ss.changeKeyAcl(tester.keyRef, cred, edit);
+        detail("ACL changed OK");
+    }
+    
+    // ... and see how the new one reacts
+    tester.testWrap(&nullCred, "ACCEPTING NULL CREDENTIALS NOW");
+    tester.testWrap(&cred, "ACCEPTING OLD CREDENTIALS FOR NEW ACL");
+    {
+        AutoCredentials cred(alloc);
+        cred += TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+            new(alloc) ListElement(alloc, "check me!"));
+        tester.testWrap(&cred, "ACCEPTING LEAF SAMPLE WITHOUT THRESHOLD FRAMEWORK");
+    }
+    
+    // Threshold subjects
+    {
+        detail("Testing threshold ACLs");
+        AutoCredentials cred(alloc);
+        TypedList &threshold = cred += TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD,
+            new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "wrongo!")))
+        );
+        tester.testWrap(&cred, "ACCEPTING ALL WRONG SAMPLES IN THRESHOLD");
+        threshold += new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "hug me!")));
+        tester.testWrap(&cred, "ACCEPTING TOO FEW THRESHOLD SAMPLES");
+        threshold += new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "check me!")));
+        tester.testWrap(&cred);
+        // stuff the ballot box
+        threshold += new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "and this!")));
+        threshold += new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "and that!")));
+        threshold += new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+                new(alloc) ListElement(alloc, "and more!")));
+#ifdef STRICT_THRESHOLD_SUBJECTS
+        tester.testWrap(&cred, "ACCEPTING OVER-STUFFED THRESHOLD");
+#else
+		tester.testWrap(&cred);
+#endif //STRICT_THRESHOLD_SUBJECTS
+    }
+	
+	// comment ACLs and tags
+	{
+        detail("Adding Comment entry");
+		
+        AclEntryPrototype newAcl;
+        TypedList subject = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_COMMENT,
+			new(alloc) ListElement(TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_THRESHOLD,
+				new(alloc) ListElement(alloc, "Robby Ray!"))),
+			new(alloc) ListElement(666));
+        newAcl.TypedSubject = subject;
+		strcpy(newAcl.EntryTag, "vamos");
+        AclEntryInput input(newAcl);
+        AclEdit edit(input);
+        ss.changeKeyAcl(tester.keyRef, cred, edit);
+        detail("Entry added");
+		
+        uint32 count;
+        AclEntryInfo *infos;
+        ss.getKeyAcl(tester.keyRef, "vamos", count, infos);
+        assert(count == 1);	// one entry (with this tag)
+		const AclEntryInfo &acl = infos[0];
+		const TypedList &read = acl.proto().subject();
+		assert(read.type() == CSSM_ACL_SUBJECT_TYPE_COMMENT);
+		assert(read.length() == 3);
+		assert(read[2] == 666);
+		CssmList &sublist = read[1];
+		assert(sublist[0] == CSSM_ACL_SUBJECT_TYPE_THRESHOLD);
+		assert(string(sublist[1]) == "Robby Ray!");
+		
+		detail("Comment entry retrieved okay");
+	}
+}
+
+
+//
+// ACL authorization tests
+//
+void authAcls()
+{
+    printf("* ACL authorizations test\n");
+	CssmAllocator &alloc = CssmAllocator::standard();
+	ClientSession ss(alloc, alloc);
+	
+	// create key with initial ACL
+    CSSM_ACL_AUTHORIZATION_TAG wrapTag = CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR;
+    CSSM_ACL_AUTHORIZATION_TAG encryptTag = CSSM_ACL_AUTHORIZATION_ENCRYPT;
+	StringData initialAclPassphrase("very secret");
+    StringData the2ndAclPassword("most secret");
+	AclEntryPrototype initialAcl;
+	initialAcl.TypedSubject = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD,
+		new(alloc) ListElement(initialAclPassphrase));
+    initialAcl.authorization().NumberOfAuthTags = 1;
+    initialAcl.authorization().AuthTags = &wrapTag;
+	AclEntryInput initialAclInput(initialAcl);
+	AclTester tester(ss, &initialAclInput);
+	
+	// get the owner and verify
+	AclOwnerPrototype owner;
+	ss.getKeyOwner(tester.keyRef, owner);
+	assert(owner.subject().type() == CSSM_ACL_SUBJECT_TYPE_PASSWORD);
+	assert(owner.subject().length() == 1);
+	
+	// get the acl entry and verify
+	{
+		uint32 count;
+		AclEntryInfo *acls;
+		ss.getKeyAcl(tester.keyRef, NULL/*tag*/, count, acls);
+		assert(count == 1);
+		const AclEntryInfo &acl1 = acls[0];
+		const TypedList &subject1 = acl1.proto().subject();
+		assert(subject1.type() == CSSM_ACL_SUBJECT_TYPE_PASSWORD);
+		assert(subject1.length() == 1);
+        const AuthorizationGroup &auths = acl1.proto().authorization();
+        assert(auths.count() == 1);
+        assert(auths[0] == CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR);
+	}
+	
+	// try to use the key and see...
+	tester.testWrap(&nullCred, "ACCEPTING NULL CREDENTIAL");
+	AutoCredentials cred(alloc);
+	cred += TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+		new(alloc) ListElement(StringData("wrongo")));
+	tester.testWrap(&cred, "ACCEPTING WRONG PASSWORD CREDENTIAL");
+	cred += TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+		new(alloc) ListElement(initialAclPassphrase));
+	tester.testWrap(&cred);
+
+    tester.testEncrypt(&nullCred, "ACCEPTING NULL CREDENTIAL FOR UNAUTHORIZED OPERATION");
+    tester.testEncrypt(&cred, "ACCEPTING GOOD CREDENTIAL FOR UNAUTHORIZED OPERATION");
+    
+    // now *add* a new ACL entry for encryption
+    {
+        detail("Adding new ACL entry");
+        
+        AclEntryPrototype newAcl;
+        newAcl.TypedSubject = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD,
+            new(alloc) ListElement(the2ndAclPassword));
+        newAcl.authorization().NumberOfAuthTags = 1;
+        newAcl.authorization().AuthTags = &encryptTag;
+        AclEntryInput newInput(newAcl);
+        AclEdit edit(newInput);
+        
+        try {
+            AutoCredentials nullCred(alloc);
+            ss.changeKeyAcl(tester.keyRef, nullCred, edit);
+            error("ALLOWED ACL EDIT WITHOUT CREDENTIALS");
+        } catch (CssmCommonError &err) {
+            detail(err, "Acl Edit rejected properly");
+        }
+        ss.changeKeyAcl(tester.keyRef, cred, edit);
+        detail("ACL changed OK");
+
+        // read it back and check
+        {
+            uint32 count;
+            AclEntryInfo *acls;
+            ss.getKeyAcl(tester.keyRef, NULL/*tag*/, count, acls);
+            assert(count == 2);
+            const AclEntryInfo &acl1 = acls[0];
+            const TypedList &subject1 = acl1.proto().subject();
+            assert(subject1.type() == CSSM_ACL_SUBJECT_TYPE_PASSWORD);
+            assert(subject1.length() == 1);
+            const AuthorizationGroup &auths1 = acl1.proto().authorization();
+            assert(auths1.count() == 1);
+            assert(auths1[0] == CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR);
+            const AclEntryInfo &acl2 = acls[1];
+            const TypedList &subject2 = acl2.proto().subject();
+            assert(subject2.type() == CSSM_ACL_SUBJECT_TYPE_PASSWORD);
+            assert(subject2.length() == 1);
+            const AuthorizationGroup &auths2 = acl2.proto().authorization();
+            assert(auths2.count() == 1);
+            assert(auths2[0] == CSSM_ACL_AUTHORIZATION_ENCRYPT);
+        }
+    }
+    
+    // ... and see how the new composite ACL behaves
+	AutoCredentials cred2(alloc);
+	cred2 += TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+		new(alloc) ListElement(the2ndAclPassword));
+    tester.testWrap(&nullCred, "ACCEPTING NULL CREDENTIALS FOR WRAPPING");	
+    tester.testEncrypt(&nullCred, "ACCEPTING NULL CREDENTIALS FOR ENCRYPTION");
+    tester.testWrap(&cred);	// "very secret" allows wrapping
+    tester.testEncrypt(&cred2); // "most secret" allows encrypting
+    tester.testWrap(&cred2, "ACCEPTING ENCRYPT CRED FOR WRAPPING");
+    tester.testEncrypt(&cred, "ACCEPTING WRAP CRED FOR ENCRYPTING");
+}
+
+
+//
+// Keychain ACL subjects
+//
+void keychainAcls()
+{
+    printf("* Keychain (interactive) ACL test\n");
+	CssmAllocator &alloc = CssmAllocator::standard();
+	ClientSession ss(alloc, alloc);
+	
+	// create key with initial ACL
+	AclEntryPrototype initialAcl;
+	initialAcl.TypedSubject = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT,
+        new(alloc) ListElement(alloc, "Test Key"));
+	AclEntryInput initialAclInput(initialAcl);
+	AclTester tester(ss, &initialAclInput);
+	
+	// get the owner and verify
+	AclOwnerPrototype owner;
+	ss.getKeyOwner(tester.keyRef, owner);
+	assert(owner.subject().type() == CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT);
+	assert(owner.subject().length() == 2);
+	
+	// get the acl entry and verify
+	{
+		uint32 count;
+		AclEntryInfo *acls;
+		ss.getKeyAcl(tester.keyRef, NULL/*tag*/, count, acls);
+		assert(count == 1);
+		const AclEntryInfo &acl1 = acls[0];
+		const TypedList &subject1 = acl1.proto().subject();
+		assert(subject1.type() == CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT);
+		assert(subject1.length() == 2);
+		assert(static_cast<string>(subject1[1]) == "Test Key");
+	}
+	
+	// try to use the key and see...
+	tester.testWrap(NULL, "ACCEPTING NULL CREDENTIAL");
+	AutoCredentials cred(alloc);
+	cred += TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+		new(alloc) ListElement(StringData("Test Key")));
+	tester.testWrap(&cred, "ACCEPTING PASSWORD CREDENTIAL");
+	cred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT);
+	tester.testWrap(&cred);
+	// once again, for allow-this-pid feature testing
+	tester.testWrap(&cred);
+}
+
+
+//
+// Code-signing ACL subjects
+//
+void codeSigning()
+{
+    printf("* Code Signing ACL test\n");
+	CssmAllocator &alloc = CssmAllocator::standard();
+	ClientSession ss(alloc, alloc);
+	
+	// sign ourselves
+	OSXSigner signer;
+	OSXCode *main = OSXCode::main();
+	Signature *mySignature = signer.sign(*main);
+	detail("Code signature for testclient obtained");
+	
+	// make a variant signature that isn't right
+	Signature *badSignature;
+	{
+		char buffer[512];
+		assert(mySignature->length() <= sizeof(buffer));
+		memcpy(buffer, mySignature->data(), mySignature->length());
+		memcpy(buffer, "xyz!", 4);	// 1 in 2^32 this is right...
+		badSignature = signer.restore(mySignature->type(), buffer, mySignature->length());
+	}
+	
+	// create key with good code signature ACL
+	AclEntryPrototype initialAcl;
+	initialAcl.subject() = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE,
+		new(alloc) ListElement(mySignature->type()),
+		new(alloc) ListElement(alloc.alloc(*mySignature)));
+	AclEntryInput initialAclInput(initialAcl);
+	AclTester tester(ss, &initialAclInput);
+	
+	// get the owner and verify
+	AclOwnerPrototype owner;
+	ss.getKeyOwner(tester.keyRef, owner);
+	assert(owner.subject().type() == CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE);
+	assert(owner.subject().length() == 3);
+	
+	// we are us, so the SecurityServer should accept us
+	tester.testWrap(&nullCred);
+	
+	// now try this again with a *bad* signature...
+	AclEntryPrototype badAcl;
+	badAcl.TypedSubject = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE,
+		new(alloc) ListElement(badSignature->type()),
+		new(alloc) ListElement(alloc.alloc(*badSignature)));
+	AclEntryInput badAclInput(badAcl);
+	AclTester badTester(ss, &badAclInput);
+	badTester.testWrap(&nullCred, "BAD CODE SIGNATURE ACCEPTED");
+	
+	// make sure the optional comment field makes it back out intact
+	// (reusing original initialAcl structures)
+	StringData comment("Walla Walla Washington!\nAbra cadabra.\n\n");
+	initialAcl.subject() += new(alloc) ListElement(alloc, comment);
+	AclEntryInput initialAclInputWithComment(initialAcl);
+	AclTester commentTester(ss, &initialAclInputWithComment);
+	ss.getKeyOwner(commentTester.keyRef, owner);
+	assert(owner.subject().type() == CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE);
+	assert(owner.subject().length() == 4);
+	assert(owner.subject()[3] == comment);
+	detail("Verified comment field intact");
+}
diff --git a/SecurityServer/tests/testauth.cpp b/SecurityServer/tests/testauth.cpp
new file mode 100644
index 00000000..5e96d314
--- /dev/null
+++ b/SecurityServer/tests/testauth.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+
+//
+// testacls - ACL-related test cases.
+// 
+#include "testclient.h"
+#include "testutils.h"
+#include <Security/osxsigner.h>
+
+using namespace CodeSigning;
+
+
+//
+// Authorization test.
+// This tests the authorization API support.
+// @@@ Incomplete and not satisfactory.
+//
+void authorizations()
+{
+	printf("* authorization test\n");
+	ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard());
+	
+	// make a simple authorization query
+	AuthorizationBlob auth;
+	AuthorizationItem testingItem = { "debug.testing", 0, NULL, NULL };
+	AuthorizationItem testingMoreItem = { "debug.testing.more", 0, NULL, NULL };
+	AuthorizationItem denyItem = { "debug.deny", 0, NULL, NULL };
+	AuthorizationItemSet request = { 1, &testingItem };
+	ss.authCreate(&request, NULL/*environment*/,
+		kAuthorizationFlagInteractionAllowed |
+		kAuthorizationFlagExtendRights |
+		kAuthorizationFlagPartialRights,
+		auth);
+	detail("Initial authorization obtained");
+	
+	// ask for rights from this authorization
+	{
+		AuthorizationItem moreItems[3] = { testingItem, denyItem, testingMoreItem };
+		AuthorizationItemSet moreRequests = { 3, moreItems };
+		AuthorizationItemSet *rightsVector;
+		ss.authCopyRights(auth, &moreRequests, NULL/*environment*/,
+			kAuthorizationFlagInteractionAllowed |
+			kAuthorizationFlagExtendRights |
+			kAuthorizationFlagPartialRights,
+			&rightsVector);
+		if (rightsVector->count != 2)
+			error("COPYRIGHTS RETURNED %d RIGHTS (EXPECTED 2)", int(rightsVector->count));
+		// the output rights could be in either order -- be flexible
+		set<string> rights;
+		rights.insert(rightsVector->items[0].name);
+		rights.insert(rightsVector->items[1].name);
+		assert(rights.find("debug.testing") != rights.end() &&
+			rights.find("debug.testing.more") != rights.end());
+		free(rightsVector);
+		detail("CopyRights okay");
+	}
+		
+	// ask for the impossible
+	try {
+		AuthorizationBlob badAuth;
+		AuthorizationItem badItem = { "debug.deny", 0, NULL, NULL };
+		AuthorizationItemSet badRequest = { 1, &badItem };
+		ss.authCreate(&badRequest, NULL/*environment*/,
+			kAuthorizationFlagInteractionAllowed |
+			kAuthorizationFlagExtendRights,
+			auth);
+		error("AUTHORIZED debug.deny OPERATION");
+	} catch (CssmCommonError &err) {
+		detail(err, "debug.deny authorization denied properly");
+	}
+	
+	// externalize
+	AuthorizationExternalForm extForm;
+	ss.authExternalize(auth, extForm);
+	
+	// re-internalize
+	AuthorizationBlob auth2;
+	ss.authInternalize(extForm, auth2);
+	
+	// make sure it still works
+	{
+		AuthorizationItem moreItems[2] = { testingItem, denyItem };
+		AuthorizationItemSet moreRequests = { 2, moreItems };
+		AuthorizationItemSet *rightsVector;
+		ss.authCopyRights(auth2, &moreRequests, NULL/*environment*/,
+			kAuthorizationFlagInteractionAllowed |
+			kAuthorizationFlagExtendRights |
+			kAuthorizationFlagPartialRights,
+			&rightsVector);
+		if (rightsVector->count != 1)
+			error("COPYRIGHTS RETURNED %d RIGHTS (EXPECTED 1)", int(rightsVector->count));
+		assert(!strcmp(rightsVector->items[0].name, "debug.testing"));
+		free(rightsVector);
+		detail("Re-internalized authorization checks out okay");
+
+		// try it with no rights output (it's optional)
+		ss.authCopyRights(auth2, &moreRequests, NULL/*environment*/,
+			kAuthorizationFlagPartialRights, NULL);
+		detail("authCopyRights partial success OK (with no output)");
+		
+		// but this will fail if we want ALL rights...
+		try {
+			ss.authCopyRights(auth2, &moreRequests, NULL/*environment*/,
+			kAuthorizationFlagDefaults, NULL);
+			error("authCopyRights succeeded with (only) partial success");
+		} catch (CssmError &err) {
+			detail("authCopyRight failed for (only) partial success");
+		}
+	}
+}
diff --git a/SecurityServer/tests/testblobs.cpp b/SecurityServer/tests/testblobs.cpp
new file mode 100644
index 00000000..4aca73cd
--- /dev/null
+++ b/SecurityServer/tests/testblobs.cpp
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+
+//
+// testacls - ACL-related test cases.
+// 
+#include "testclient.h"
+#include "testutils.h"
+
+
+//
+// Blob tests.
+// Encodes and decodes Db and Key blobs and all that jazz.
+//
+void blobs()
+{
+	printf("* Database blob encryption test\n");
+	ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard());
+	
+	DbTester db1(ss, "/tmp/one", NULL, 60, true);
+	DbTester db2(ss, "/tmp/two", NULL, 30, false);
+	
+	// encode db1, purge it, decode it again
+	CssmData dbBlob;
+	ss.encodeDb(db1, dbBlob);
+	DbHandle db1a = ss.decodeDb(db1.dbId, &nullCred, dbBlob);
+	ss.releaseDb(db1);
+	if (db1 == db1a)
+		detail("REUSED DB HANDLE ON DECODEDB (probably wrong)");
+	DBParameters savedParams;
+	ss.getDbParameters(db1a, savedParams);
+	assert(savedParams.idleTimeout == db1.params.idleTimeout);
+	assert(savedParams.lockOnSleep == db1.params.lockOnSleep);
+	detail("Database encode/decode passed");
+	
+	// make sure the old handle isn't valid anymore
+	try {
+		ss.getDbParameters(db1, savedParams);
+		printf("OLD DATABASE HANDLE NOT PURGED (possibly wrong)\n");
+	} catch (const CssmCommonError &err) {
+		detail(err, "old DB handle rejected");
+	}
+    
+    // open db1 a second time (so now there's two db handles for db1)
+    DbHandle db1b = ss.decodeDb(db1.dbId, &nullCred, dbBlob);
+    
+    // release both db1 handles and db2
+    ss.releaseDb(db1a);
+    ss.releaseDb(db1b);
+    ss.releaseDb(db2);
+}
+
+
+//
+// Database tests.
+// Database locks/unlocks etc.
+//
+void databases()
+{
+	printf("* Database manipulation test\n");
+    CssmAllocator &alloc = CssmAllocator::standard();
+	ClientSession ss(alloc, alloc);
+    
+    AutoCredentials pwCred(alloc);
+    StringData passphrase("two");
+    StringData badPassphrase("three");
+    pwCred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
+        new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+        new(alloc) ListElement(passphrase));
+    pwCred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
+        new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+        new(alloc) ListElement(badPassphrase));
+	// pwCred = (NEW: two, OLD: three)
+	
+	DbTester db1(ss, "/tmp/one", NULL, 30, true);
+	DbTester db2(ss, "/tmp/two", &pwCred, 60, false);
+	// db2.passphrase = two
+	
+	// encode db1 and re-open it
+	CssmData dbBlob;
+	ss.encodeDb(db1, dbBlob);
+	DbHandle db1b = ss.decodeDb(db1.dbId, &nullCred, dbBlob);
+	if (db1b == db1.dbRef)
+		detail("REUSED DB HANDLE ON DECODEDB (probably wrong)");
+	
+    // open db1 a third time (so now there's three db handles for db1)
+    DbHandle db1c = ss.decodeDb(db1.dbId, &nullCred, dbBlob);
+    
+    // lock them to get started
+    ss.lock(db1);
+    ss.lock(db2);
+    
+    // unlock it through user
+    prompt("unlock");
+    ss.unlock(db1);
+	prompt();
+    ss.unlock(db1b);		// 2nd unlock should not prompt
+    ss.lock(db1c);			// lock it again
+    prompt("unlock");
+    ss.unlock(db1);		// and that should prompt again
+	prompt();
+    
+    // db2 has a passphrase lock credentials - it'll work without U/I
+	db2.unlock("wrong passphrase");		// pw=two, cred=three
+    AutoCredentials pwCred2(alloc);
+    pwCred2 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
+        new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+        new(alloc) ListElement(passphrase));
+	// pwCred2 = (OLD: two)
+    ss.authenticateDb(db2, CSSM_DB_ACCESS_WRITE, &pwCred2); // set it
+	db2.unlock();
+    ss.lock(db2);
+    
+    // now change db2's passphrase
+    ss.lock(db2);
+    pwCred2 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
+        new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+        new(alloc) ListElement(badPassphrase));
+	// pwCred2 = (OLD: two, NEW: three)
+	db2.changePassphrase(&pwCred2);
+	// passphrase = three, cred = (OLD: two)
+	
+    // encode and re-decode to make sure new data is there
+    CssmData blob2;
+    ss.encodeDb(db2, blob2);
+    DbHandle db2a = ss.decodeDb(db2.dbId, &pwCred, blob2);
+	// db2a cred = (OLD: two, NEW: three)
+    
+    // now, the *old* cred won't work anymore
+	db2.unlock("old passphrase accepted");
+
+    // back to the old credentials, which *do* have the (old bad, now good) passphrase
+    ss.lock(db2a);
+    ss.unlock(db2a);
+    detail("New passphrase accepted");
+	
+	// clear the credentials (this will prompt; cancel it)
+	ss.authenticateDb(db2, CSSM_DB_ACCESS_WRITE, NULL);
+	prompt("cancel");
+	db2.unlock("null credential accepted");
+	prompt();
+	
+	// fell-swoop from-to change password operation
+	StringData newPassphrase("hollerith");
+	AutoCredentials pwCred3(alloc);
+	pwCred3 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
+		new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+		new(alloc) ListElement(newPassphrase));
+	pwCred3 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
+		new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+		new(alloc) ListElement(passphrase));
+	db2.changePassphrase(&pwCred3, "accepting original (unchanged) passphrase");
+	
+	AutoCredentials pwCred4(alloc);
+	pwCred4 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
+		new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+		new(alloc) ListElement(newPassphrase));
+	pwCred4 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
+		new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+		new(alloc) ListElement(badPassphrase));
+	db2.changePassphrase(&pwCred4);
+	
+	// final status check
+	AutoCredentials pwCred5(alloc);
+	pwCred5 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
+		new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+		new(alloc) ListElement(newPassphrase));	
+	ss.authenticateDb(db2, CSSM_DB_ACCESS_WRITE, &pwCred5);
+	db2.unlock();
+	detail("Final passphrase change verified");
+}
+
+
+//
+// Key encryption tests.
+//
+void keyBlobs()
+{
+	printf("* Keyblob encryption test\n");
+    CssmAllocator &alloc = CssmAllocator::standard();
+	ClientSession ss(alloc, alloc);
+    
+    DLDbIdentifier dbId1(ssuid, "/tmp/one", NULL);
+	DBParameters initialParams1 = { 3600, false };
+    
+    // create a new database
+	DbHandle db = ss.createDb(dbId1, NULL, NULL, initialParams1);
+	detail("Database created");
+	
+	// establish an ACL for the key
+	StringData theAclPassword("Strenge Geheimsache");
+	AclEntryPrototype initialAcl;
+	initialAcl.TypedSubject = TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD,
+		new(alloc) ListElement(theAclPassword));
+	AclEntryInput initialAclInput(initialAcl);
+    
+    AutoCredentials cred(alloc);
+    cred += TypedList(alloc, CSSM_SAMPLE_TYPE_PASSWORD,
+        new(alloc) ListElement(theAclPassword));
+    
+    // generate a key
+	const CssmCryptoData seed(StringData("Farmers' day"));
+	FakeContext genContext(CSSM_ALGCLASS_KEYGEN, CSSM_ALGID_DES,
+		&::Context::Attr(CSSM_ATTRIBUTE_KEY_LENGTH, 64),
+		&::Context::Attr(CSSM_ATTRIBUTE_SEED, seed),
+		NULL);
+    KeyHandle key;
+    CssmKey::Header header;
+    ss.generateKey(db, genContext, CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+        CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT,
+        /*cred*/NULL, &initialAclInput, key, header);
+	detail("Key generated");
+    
+    // encrypt with the key
+    StringData clearText("Yet another boring cleartext sample string text sequence.");
+    StringData iv("Aardvark");
+    CssmKey nullKey; memset(&nullKey, 0, sizeof(nullKey));
+	FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
+		&::Context::Attr(CSSM_ATTRIBUTE_KEY, nullKey),
+		&::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
+		&::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
+		&::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
+        &::Context::Attr(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, cred),
+		NULL);
+	CssmData cipherText;
+	ss.encrypt(cryptoContext, key, clearText, cipherText);
+	detail("Plaintext encrypted with original key");
+    
+    // encode the key and release it
+    CssmData blob;
+    ss.encodeKey(key, blob);
+    ss.releaseKey(key);
+    detail("Key encoded and released");
+    
+    // decode it again, re-introducing it
+    CssmKey::Header decodedHeader;
+    KeyHandle key2 = ss.decodeKey(db, blob, decodedHeader);
+    detail("Key decoded");
+    
+    // decrypt with decoded key
+    CssmData recovered;
+    ss.decrypt(cryptoContext, key2, cipherText, recovered);
+    assert(recovered == clearText);
+    detail("Decoded key correctly decrypts ciphertext");
+    
+    // check a few header fields
+    if (!memcmp(&header, &decodedHeader, sizeof(header))) {
+        detail("All header fields match");
+    } else {
+        assert(header.algorithm() == decodedHeader.algorithm());
+        assert(header.blobType() == decodedHeader.blobType());
+        assert(header.blobFormat() == decodedHeader.blobFormat());
+        assert(header.keyClass() == decodedHeader.keyClass());
+        assert(header.attributes() == decodedHeader.attributes());
+        assert(header.usage() == decodedHeader.usage());
+        printf("Some header fields differ (probably okay)\n");
+    }
+    
+    // make sure we need the credentials (destructive)
+    memset(&cred, 0, sizeof(cred));
+    try {
+        ss.decrypt(cryptoContext, key2, cipherText, recovered);
+        error("RESTORED ACL FAILS TO RESTRICT");
+    } catch (CssmError &err) {
+        detail(err, "Restored key restricts access properly");
+    }
+}
diff --git a/SecurityServer/tests/testclient.cpp b/SecurityServer/tests/testclient.cpp
new file mode 100644
index 00000000..4f000be1
--- /dev/null
+++ b/SecurityServer/tests/testclient.cpp
@@ -0,0 +1,281 @@
+/*
+ * 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.
+ */
+
+
+//
+// Tester - test driver for securityserver client side.
+//
+#include "testclient.h"
+#include "testutils.h"
+#include <unistd.h>		// getopt(3)
+#include <set>
+
+
+//
+// Global constants
+//
+const CssmData null;		// zero pointer, zero length constant data
+const AccessCredentials nullCred;	// null credentials
+
+CSSM_GUID ssguid = { 1,2,3 };
+CssmSubserviceUid ssuid(ssguid);
+
+
+//
+// Local functions
+//
+static void usage();
+static void runtest(char type);
+
+
+//
+// Default test set
+//
+static char testCodes[] = ".cesaAbdkKt";
+
+
+//
+// Main program
+//
+int main(int argc, char *argv[])
+{
+	setbuf(stdout, NULL);
+
+	long ranseq = 0;	// random stress test count
+	long ranseed = 1;	// random seed for it
+
+	int arg;
+	while ((arg = getopt(argc, argv, "r:v")) != -1) {
+		switch (arg) {
+		case 'r': {
+			ranseq = atoi(optarg);
+			if (const char *colon = strchr(optarg, ':'))
+				ranseed = atoi(colon + 1);
+			else
+				ranseed = getpid() ^ time(NULL);
+			break;
+			}
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			usage();
+		}
+	}
+	if (optind < argc - 1)
+		usage();
+	const char *sequence = argv[optind];
+	if (sequence && !strcmp(sequence, "+"))
+		sequence = testCodes;
+		
+	if (ranseq) {	// repeated random (stress test) sequence
+		if (!sequence)
+			sequence = testCodes;
+		printf("*** Random stress test: %ld iterations from <%s> with seed=%ld\n",
+			ranseq, sequence, ranseed);
+		srandom(ranseed);
+		int setSize = strlen(sequence);
+		for (long n = 0; n < ranseq; n++) {
+			char type = sequence[random() % setSize];
+			printf("\n[%ld:%c]", n, type);
+			runtest(type);
+		}
+		printf("*** Random test sequence complete.\n");
+		exit(0);
+	} else {		// single-pass selected tests sequence
+		if (!sequence)
+			sequence = ".";	// default to ping test
+		for (const char *s = sequence; *s; s++)
+			runtest(*s);
+		printf("*** Test sequence complete.\n");
+		exit(0);
+	}
+}
+
+void usage()
+{
+	fprintf(stderr, "Usage: SSTester [-r count[:seed]] [-v] [%s|.|+]\n",
+		testCodes);
+	exit(2);
+}
+
+
+//
+// Run a single type test
+//
+void runtest(char type)
+{	
+	try {
+		debug("SStest", "Start test <%c>", type);
+		switch (type) {
+		case '.':	// default
+			integrity();
+			break;
+		case '-':
+			adhoc();
+			break;
+		case 'a':
+			acls();
+			break;
+		case 'A':
+			authAcls();
+			break;
+		case 'b':
+			blobs();
+			break;
+		case 'c':
+			codeSigning();
+			break;
+		case 'd':
+			databases();
+			break;
+		case 'e':
+			desEncryption();
+			break;
+		case 'k':
+			keychainAcls();
+			break;
+		case 'K':
+			keyBlobs();
+			break;
+		case 's':
+			signWithRSA();
+			break;
+		case 't':
+			authorizations();
+			break;
+		case 'T':
+			timeouts();
+			break;
+		default:
+			error("Invalid test selection (%c)", type);
+		}
+		printf("** Test step complete.\n");
+		debug("SStest", "End test <%c>", type);
+	} catch (CssmCommonError &err) {
+		error(err, "Unexpected exception");
+	} catch (...) {
+		error("Unexpected system exception");
+	}
+}
+
+
+//
+// Basic integrity test.
+//
+void integrity()
+{
+	ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard());
+	
+	printf("* Generating random sample: ");
+	DataBuffer<11> sample;
+	ss.generateRandom(sample);
+	for (uint32 n = 0; n < sample.length(); n++)
+		printf("%.2x", ((unsigned char *)sample)[n]);
+	printf("\n");
+}
+
+
+//
+// Database timeouts
+// @@@ Incomplete and not satisfactory
+//
+void timeouts()
+{
+	printf("* Database timeout locks test\n");
+    CssmAllocator &alloc = CssmAllocator::standard();
+	ClientSession ss(alloc, alloc);
+    
+    DLDbIdentifier dbId1(ssuid, "/tmp/one", NULL);
+    DLDbIdentifier dbId2(ssuid, "/tmp/two", NULL);
+	DBParameters initialParams1 = { 4, false };	// 4 seconds timeout
+	DBParameters initialParams2 = { 8, false };	// 8 seconds timeout
+    
+	// credential to set keychain passphrase
+    AutoCredentials pwCred(alloc);
+    StringData password("mumbojumbo");
+    pwCred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
+        new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+        new(alloc) ListElement(password));
+    
+	DbHandle db1 = ss.createDb(dbId1, &pwCred, NULL, initialParams1);
+	DbHandle db2 = ss.createDb(dbId2, &pwCred, NULL, initialParams2);
+	detail("Databases created");
+    
+    // generate a key
+	const CssmCryptoData seed(StringData("rain tonight"));
+	FakeContext genContext(CSSM_ALGCLASS_KEYGEN, CSSM_ALGID_DES,
+		&::Context::Attr(CSSM_ATTRIBUTE_KEY_LENGTH, 64),
+		&::Context::Attr(CSSM_ATTRIBUTE_SEED, seed),
+		NULL);
+    KeyHandle key;
+    CssmKey::Header header;
+    ss.generateKey(db1, genContext, CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+        CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT,
+        /*cred*/NULL, NULL, key, header);
+    ss.generateKey(db2, genContext, CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+        CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT,
+        /*cred*/NULL, NULL, key, header);
+	detail("Keys generated and stored");
+	
+	// credential to provide keychain passphrase
+    AutoCredentials pwCred2(alloc);
+    pwCred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
+        new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+        new(alloc) ListElement(password));
+
+	//@@@ incomplete
+	ss.releaseDb(db1);
+	ss.releaseDb(db2);
+}
+
+
+//
+// Ad-hoc test area.
+// Used for whatever is needed at the moment...
+//
+void adhoc()
+{
+	printf("* Ad-hoc test sequence (now what does it do *this* time?)\n");
+	
+	Cssm cssm1;
+	Cssm cssm2;
+	cssm1->init();
+	cssm2->init();
+	
+	{
+		Module m1(gGuidAppleCSP, cssm1);
+		Module m2(gGuidAppleCSP, cssm2);
+		CSP r1(m1);
+		CSP r2(m2);
+		
+		Digest d1(r1, CSSM_ALGID_SHA1);
+		Digest d2(r2, CSSM_ALGID_SHA1);
+		
+		StringData foo("foo de doo da blech");
+		DataBuffer<30> digest1, digest2;
+		d1.digest(foo, digest1);
+		d2.digest(foo, digest2);
+		if (digest1 == digest2)
+			detail("Digests verify");
+		else
+			error("Digests mismatch");
+	}
+	
+	cssm1->terminate();
+	cssm2->terminate();
+}
diff --git a/SecurityServer/tests/testclient.h b/SecurityServer/tests/testclient.h
new file mode 100644
index 00000000..9346a41c
--- /dev/null
+++ b/SecurityServer/tests/testclient.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+
+//
+// Tester - test driver for securityserver client side.
+//
+#ifndef _H_TESTCLIENT
+#define _H_TESTCLIENT
+
+#include "ssclient.h"
+#include <Security/cssmerrno.h>
+#include <Security/debugging.h>
+#include <Security/cssmclient.h>
+#include <Security/signclient.h>
+#include <Security/cryptoclient.h>
+#include <stdarg.h>
+
+
+//
+// Names from the SecurityServerSession class
+//
+using namespace SecurityServer;
+using namespace CssmClient;
+
+
+//
+// Test drivers
+//
+void integrity();
+void signWithRSA();
+void desEncryption();
+void blobs();
+void keyBlobs();
+void databases();
+void timeouts();
+void acls();
+void authAcls();
+void codeSigning();
+void keychainAcls();
+void authorizations();
+void adhoc();
+
+
+//
+// Global constants
+//
+extern const CssmData null;					// zero pointer, zero length constant data
+extern const AccessCredentials nullCred;	// null credentials
+
+extern CSSM_GUID ssguid;					// a fixed guid
+extern CssmSubserviceUid ssuid;				// a subservice-uid using this guid
+
+
+#endif //_H_TESTCLIENT
diff --git a/SecurityServer/tests/testcrypto.cpp b/SecurityServer/tests/testcrypto.cpp
new file mode 100644
index 00000000..bf8e6ac7
--- /dev/null
+++ b/SecurityServer/tests/testcrypto.cpp
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+
+
+//
+// Tester - test driver for securityserver client side.
+//
+#include "testclient.h"
+#include "testutils.h"
+
+
+//
+// Simple run-through.
+// This generates an RSA key, tests cleartext retrieval, signs a message,
+// and veries it both ways.
+// This is a basic integrity regression for the SecurityServer.
+//
+void signWithRSA()
+{
+	printf("* RSA key signing test\n");
+	CSP csp(gGuidAppleCSP);
+	ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard());
+	StringData data("To sign or not to sign, is that the question?");
+	
+	// set up dummy credentials
+	CssmKey dummyKey; memset(&dummyKey, 0, sizeof(dummyKey));
+	CssmData nullData;
+	
+	// generate a key
+	detail("Asking for RSA key generation");
+	KeyHandle publicKey, privateKey;
+	const CssmCryptoData seed(StringData("Seed ye well, my friend, and ye shall reap..."));
+	FakeContext genContext(CSSM_ALGCLASS_KEYGEN, CSSM_ALGID_RSA,
+		&::Context::Attr(CSSM_ATTRIBUTE_KEY_LENGTH, 512),
+		&::Context::Attr(CSSM_ATTRIBUTE_SEED, seed),
+		NULL);
+    CssmKey::Header pubHeader, privHeader;
+	ss.generateKey(noDb, genContext,
+		CSSM_KEYUSE_VERIFY, CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA,
+		CSSM_KEYUSE_SIGN, CSSM_KEYATTR_SENSITIVE,
+		NULL/*cred*/, NULL/*owner*/, publicKey, pubHeader, privateKey, privHeader);
+	detail("Key pair generated");
+	
+	// retrieve the public key
+	CssmKey cpk;
+	FakeContext wrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
+	ss.wrapKey(wrapContext, noKey, publicKey, &nullCred, NULL, cpk);
+    Key clearPublicKey(csp, cpk);
+	detail("Retrieved public key");
+	
+	// make sure we can't retrieve the private key
+	CssmKey clearPrivateKey;
+	try {
+		ss.wrapKey(wrapContext, noKey, privateKey, NULL/*cred*/, NULL, clearPrivateKey);
+		error("SecurityServer ACTUALLY gave us the PRIVATE key bits!");
+	} catch (CssmError &err) {
+		detail(err, "Private key retrieval properly rejected");
+	}
+	
+	// sign a message
+	CssmData signature;
+	FakeContext signContext(CSSM_ALGCLASS_SIGNATURE, CSSM_ALGID_SHA1WithRSA,
+		&::Context::Attr(CSSM_ATTRIBUTE_KEY, dummyKey),
+		NULL);
+	ss.generateSignature(signContext, privateKey, data, signature);
+	detail("Signature generated by SecurityServer");
+	
+	// verify the signature (local)
+	{
+		Verify verifier(csp, CSSM_ALGID_SHA1WithRSA);
+		verifier.key(clearPublicKey);
+		verifier.verify(data, signature);
+		detail("Signature verified locally");
+	}
+	
+	// verify the signature (SS)
+	ss.verifySignature(signContext, publicKey, data, signature);
+	detail("Signature verified by SecurityServer");
+	
+	// falsify the signature (SS)
+	DataBuffer<200> falseData;
+	memcpy(falseData.data(), data.data(), data.length());
+	falseData.length(data.length());
+	((char *)falseData)[3] = '?';	// alter message
+	try {
+		ss.verifySignature(signContext, publicKey, falseData, signature);
+		error("Altered message incorrectly verifies");
+	} catch (CssmError &err) {		
+		if (err.cssmError() == CSSMERR_CSP_VERIFY_FAILED)
+			detail("Verify of altered message successfully failed");
+		else
+			error(err, "Unexpected exception on verify failure test");
+	}
+}
+
+
+//
+// Encrypt with DES
+//
+void desEncryption()
+{
+	printf("* DES encryption test\n");
+	ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard());
+	CSP csp(gGuidAppleCSP);
+	
+	StringData clearText("Insert witty quotation here.");
+	StringData iv("abcdefgh");
+	
+	// make up a DES key
+	StringData keyBits(strdup("Wallaby!"));
+	CssmKey keyForm(keyBits);
+	keyForm.header().KeyClass = CSSM_KEYCLASS_SESSION_KEY;
+	keyForm.header().BlobType = CSSM_KEYBLOB_RAW;
+	keyForm.header().AlgorithmId = CSSM_ALGID_DES;
+	keyForm.header().Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
+    Key key(csp, keyForm);
+	
+	// encrypt locally
+	DataBuffer<200> localCipher;
+	Encrypt localCrypt(csp, CSSM_ALGID_DES);
+	localCrypt.mode(CSSM_ALGMODE_CBC_IV8);
+	localCrypt.padding(CSSM_PADDING_PKCS1);
+	localCrypt.initVector(iv);
+	localCrypt.key(key);
+	CssmData remData;
+	size_t localLen = localCrypt.encrypt(clearText, localCipher, remData);
+	if (remData)
+		error("LOCAL ENCRYPTION OVERFLOWED");
+	localCipher.length(localLen);
+	detail("Locally encrypted %ld bytes", localLen);
+	
+	// wrap in the key
+	CssmData unwrappedData;
+	ResourceControlContext owner;
+	FakeContext unwrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
+	KeyHandle keyRef;
+    CssmKey::Header keyHeader;
+    ss.unwrapKey(noDb, unwrapContext, noKey, noKey,
+		key,
+		CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+		CSSM_KEYATTR_RETURN_DEFAULT,
+		NULL/*cred*/, NULL/*owner*/, unwrappedData, keyRef, keyHeader);
+	detail("Placed key into SecurityServer; handle=%lx", keyRef);
+	
+	// encrypt remotely and compare
+	const CssmKey &tKey = key;
+	FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
+		&::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm),
+		&::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
+		&::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
+		&::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
+		NULL);
+	CssmData remoteCipher;
+	ss.encrypt(cryptoContext, keyRef, clearText, remoteCipher);
+	detail("Plaintext encrypted on SecurityServer");
+	if (remoteCipher == localCipher)
+		detail("Ciphertexts verified");
+	else
+		error("CIPHERTEXTS DIFFER");
+	
+	// decrypt in SecurityServer
+	DataBuffer<200> clearRecovered;
+	ss.decrypt(cryptoContext, keyRef, localCipher, clearRecovered);
+	detail("Decrypted ciphertext in SecurityServer");
+	if (clearRecovered == clearText)
+		detail("Plaintext recovered");
+	else
+		error("PLAINTEXT MISMATCH");
+}
+
diff --git a/SecurityServer/tests/testutils.cpp b/SecurityServer/tests/testutils.cpp
new file mode 100644
index 00000000..0f741214
--- /dev/null
+++ b/SecurityServer/tests/testutils.cpp
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+
+
+//
+// testutils - utilities for unit test drivers
+//
+#include "testutils.h"
+
+using namespace CssmClient;
+
+bool verbose = false;
+
+
+//
+// Error and diagnostic drivers
+//
+void error(const char *msg = NULL, ...)
+{
+	if (msg) {
+		va_list args;
+		va_start(args, msg);
+		vfprintf(stderr, msg, args);
+		va_end(args);
+		putc('\n', stderr);
+	}
+	abort();
+}
+
+void error(const CssmCommonError &err, const char *msg = NULL, ...)
+{
+	if (msg) {
+		va_list args;
+		va_start(args, msg);
+		vfprintf(stderr, msg, args);
+		va_end(args);
+		fprintf(stderr, ": %s", cssmErrorString(err.cssmError()).c_str());
+		putc('\n', stderr);
+	}
+	abort();
+}
+
+void detail(const char *msg = NULL, ...)
+{
+	if (verbose) {
+		va_list args;
+		va_start(args, msg);
+		vfprintf(stdout, msg, args);
+		va_end(args);
+		putc('\n', stdout);
+	}
+}
+
+void detail(const CssmCommonError &err, const char *msg)
+{
+	if (verbose)
+		printf("%s (ok): %s\n", msg, cssmErrorString(err).c_str());
+}
+
+void prompt(const char *msg)
+{
+	if (isatty(fileno(stdin)))
+		printf("[%s]", msg);
+}
+
+void prompt()
+{
+	if (isatty(fileno(stdin)))
+		printf(" OK\n");
+}
+
+
+//
+// FakeContext management
+//
+FakeContext::FakeContext(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS alg, uint32 count)
+: Context(type, alg)
+{
+	NumberOfAttributes = count;
+	ContextAttributes = new Attr[count];
+}
+
+
+FakeContext::FakeContext(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS alg, ...) 
+: Context(type, alg)
+{
+	// count arguments
+	va_list args;
+	va_start(args, alg);
+	uint32 count = 0;
+	while (va_arg(args, Attr *))
+		count++;
+	va_end(args);
+	
+	// make vector
+	NumberOfAttributes = count;
+	ContextAttributes = new Attr[count];
+	
+	// stuff vector
+	va_start(args, alg);
+	for (uint32 n = 0; n < count; n++)
+		(*this)[n] = *va_arg(args, Attr *);
+	va_end(args);
+}
+
+
+//
+// ACL test driver class
+//
+AclTester::AclTester(ClientSession &ss, const AclEntryInput *acl) : session(ss)
+{
+	// make up a DES key
+	StringData keyBits("Tweedle!");
+	CssmKey key(keyBits);
+	key.header().KeyClass = CSSM_KEYCLASS_SESSION_KEY;
+	
+	// wrap in the key
+	CssmData unwrappedData;
+	FakeContext unwrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
+    CssmKey::Header keyHeader;
+    ss.unwrapKey(noDb, unwrapContext, noKey, noKey,
+		key,
+		CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+		CSSM_KEYATTR_EXTRACTABLE,
+		NULL /*cred*/, acl,
+		unwrappedData, keyRef, keyHeader);
+	detail("Key seeded with ACL");
+}
+
+
+void AclTester::testWrap(const AccessCredentials *cred, const char *howWrong)
+{
+	FakeContext wrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
+	CssmWrappedKey wrappedKey;
+	try {
+		session.wrapKey(wrapContext, noKey, keyRef,
+			cred, NULL /*descriptive*/, wrappedKey);
+		if (howWrong) {
+			error("WRAP MISTAKENLY SUCCEEDED: %s", howWrong);
+		}
+		detail("extract OK");
+	} catch (const CssmCommonError &err) {
+		if (!howWrong)
+			error(err, "FAILED TO EXTRACT KEY");
+		detail(err, "extract failed OK");
+	}
+}
+
+void AclTester::testEncrypt(const AccessCredentials *cred, const char *howWrong)
+{
+    CssmKey keyForm; memset(&keyForm, 0, sizeof(keyForm));
+    StringData iv("Aardvark");
+    StringData clearText("blah");
+	CssmData remoteCipher;
+    try {
+        if (cred) {
+            FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
+                &::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm),
+                &::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
+                &::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
+                &::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
+                &::Context::Attr(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, *cred),
+                NULL);
+            session.encrypt(cryptoContext, keyRef, clearText, remoteCipher);
+        } else {
+            FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
+                &::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm),
+                &::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
+                &::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
+                &::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
+                NULL);
+            session.encrypt(cryptoContext, keyRef, clearText, remoteCipher);
+        }
+		if (howWrong) {
+			error("ENCRYPT MISTAKENLY SUCCEEDED: %s", howWrong);
+		}
+		detail("encrypt OK");
+	} catch (CssmCommonError &err) {
+		if (!howWrong)
+			error(err, "FAILED TO ENCRYPT");
+		detail(err, "encrypt failed");
+	}
+}
+
+
+//
+// Database test driver class
+//
+DbTester::DbTester(ClientSession &ss, const char *path,
+	const AccessCredentials *cred, int timeout, bool sleepLock) 
+: session(ss), dbId(ssuid, path, NULL)
+{
+	params.idleTimeout = timeout;
+	params.lockOnSleep = sleepLock;
+	dbRef = ss.createDb(dbId, cred, NULL, params);
+	detail("Database %s created", path);
+}
+
+
+void DbTester::unlock(const char *howWrong)
+{
+	session.lock(dbRef);
+	try {
+		session.unlock(dbRef);
+		if (howWrong)
+			error("DATABASE MISTAKENLY UNLOCKED: %s", howWrong);
+	} catch (CssmError &err) {
+		if (!howWrong)
+			error(err, howWrong);
+		detail(err, howWrong);
+	}
+}
+
+void DbTester::changePassphrase(const AccessCredentials *cred, const char *howWrong)
+{
+	session.lock(dbRef);
+	try {
+		session.changePassphrase(dbRef, cred);
+		if (howWrong)
+			error("PASSPHRASE CHANGE MISTAKENLY SUCCEEDED: %s", howWrong);
+	} catch (CssmError &err) {
+		if (!howWrong)
+			error(err, howWrong);
+		detail(err, howWrong);
+	}
+}
diff --git a/SecurityServer/tests/testutils.h b/SecurityServer/tests/testutils.h
new file mode 100644
index 00000000..7f35ae7e
--- /dev/null
+++ b/SecurityServer/tests/testutils.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+
+//
+// testutils - utilities for unit test drivers
+//
+#ifndef _H_TESTUTILS
+#define _H_TESTUTILS
+
+#include "testclient.h"
+
+
+//
+// Global test state
+//
+extern bool verbose;
+
+
+//
+// Error and diagnostic drivers
+//
+void error(const char *fmt, ...) __attribute__((format(printf,1,2)));
+void error(const CssmCommonError &error, const char *fmt, ...) __attribute__((format(printf,2,3)));
+void detail(const char *fmt, ...) __attribute__((format(printf,1,2)));
+void detail(const CssmCommonError &error, const char *msg);
+void prompt(const char *msg);
+void prompt();
+
+
+//
+// A self-building "fake" context.
+// (Fake in that it was hand-made without involvement of CSSM.)
+//
+class FakeContext : public ::Context {
+public:
+	FakeContext(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS alg, uint32 count);
+	FakeContext(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS alg, ...);
+};
+
+
+//
+// A test driver class for ACL tests
+//
+class AclTester {
+public:
+	AclTester(ClientSession &ss, const AclEntryInput *acl);
+	
+	void testWrap(const AccessCredentials *cred, const char *howWrong = NULL);
+	void testEncrypt(const AccessCredentials *cred, const char *howWrong = NULL);
+	
+	ClientSession &session;
+	KeyHandle keyRef;
+};
+
+
+//
+// A test driver class for database tests
+//
+class DbTester {
+public:
+	DbTester(ClientSession &ss, const char *path, 
+		const AccessCredentials *cred, int timeout = 30, bool sleepLock = true);
+	
+	operator DbHandle () const { return dbRef; }
+	void unlock(const char *howWrong = NULL);
+	void changePassphrase(const AccessCredentials *cred, const char *howWrong = NULL);
+	
+	ClientSession &session;
+	DBParameters params;
+	DLDbIdentifier dbId;
+	DbHandle dbRef;
+};
+
+
+#endif //_H_TESTUTILS
diff --git a/SecurityServer/transition.cpp b/SecurityServer/transition.cpp
new file mode 100644
index 00000000..1a5c7d9b
--- /dev/null
+++ b/SecurityServer/transition.cpp
@@ -0,0 +1,610 @@
+/*
+ * 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.
+ */
+
+
+//
+// transition - SecurityServer IPC-to-class-methods transition layer
+//
+#include <Security/AuthorizationWalkers.h>
+#include "server.h"
+#include "ucsp.h"
+#include "session.h"
+#include "xdatabase.h"
+#include <mach/mach_error.h>
+
+
+//
+// Bracket Macros
+//
+#define UCSP_ARGS	mach_port_t sport, mach_port_t rport, security_token_t securityToken, \
+                    CSSM_RETURN *rcode
+#define CONTEXT_ARGS Context context, Pointer contextBase, Context::Attr *attributes, mach_msg_type_number_t attrCount
+
+#define BEGIN_IPCN	*rcode = CSSM_OK; try {
+#define BEGIN_IPC	BEGIN_IPCN Connection &connection = Server::connection(rport);
+#define END_IPC(base)	END_IPCN(base) Server::requestComplete(); return KERN_SUCCESS;
+#define END_IPCN(base) 	} \
+	catch (const CssmCommonError &err) { *rcode = err.cssmError(CSSM_ ## base ## _BASE_ERROR); } \
+	catch (std::bad_alloc) { *rcode = CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
+	catch (Connection *conn) { *rcode = 0; } \
+	catch (...) { *rcode = CssmError::merge(CSSM_ERRCODE_INTERNAL_ERROR, CSSM_ ## base ## _BASE_ERROR); }
+
+#define DATA_IN(base)	void *base, mach_msg_type_number_t base##Length
+#define DATA_OUT(base)	void **base, mach_msg_type_number_t *base##Length
+#define DATA(base)		CssmData(base, base##Length)
+
+#define COPY_IN(type,name)	type *name, mach_msg_type_number_t name##Length, type *name##Base
+#define COPY_OUT(type,name)	\
+	type **name, mach_msg_type_number_t *name##Length, type **name##Base
+	
+
+using LowLevelMemoryUtilities::increment;
+using LowLevelMemoryUtilities::difference;
+
+
+//
+// An OutputData object will take memory allocated within the SecurityServer,
+// hand it to the MIG return-output parameters, and schedule it to be released
+// after the MIG reply has been sent. It will also get rid of it in case of
+// error.
+//
+class OutputData : public CssmData {
+public:
+	OutputData(void **outP, mach_msg_type_number_t *outLength)
+		: mData(*outP), mLength(*outLength) { }
+	~OutputData()
+	{ mData = data(); mLength = length(); Server::releaseWhenDone(mData); }
+	
+private:
+	void * &mData;
+	mach_msg_type_number_t &mLength;
+};
+
+
+//
+// A CheckingReconstituteWalker is a variant of an ordinary ReconstituteWalker
+// that checks object pointers and sizes against the incoming block limits.
+// It throws an exception if incoming data has pointers outside the incoming block.
+// This avoids trouble inside of the SecurityServer caused (by bug or malice)
+// from someone spoofing the client access side.
+//
+class CheckingReconstituteWalker {
+public:
+    CheckingReconstituteWalker(void *ptr, void *base, size_t size)
+    : mBase(base), mLimit(increment(base, size)), mOffset(difference(ptr, base)) { }
+
+    template <class T>
+    void operator () (T * &addr, size_t size = sizeof(T))
+    {
+        if (addr) {
+			if (addr < mBase || increment(addr, size) > mLimit)
+				CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
+            addr = increment<T>(addr, mOffset);
+		}
+    }
+    
+    static const bool needsRelinking = true;
+    static const bool needsSize = false;
+    
+private:
+	void *mBase;			// old base address
+	void *mLimit;			// old last byte address + 1
+    off_t mOffset;			// relocation offset
+};
+
+template <class T>
+void relocate(T *obj, T *base, size_t size)
+{
+    if (obj) {
+        CheckingReconstituteWalker w(obj, base, size);
+        walk(w, base);
+    }
+}
+
+
+
+//
+// Setup/Teardown functions.
+//
+kern_return_t ucsp_server_setup(UCSP_ARGS, mach_port_t taskPort, const char *identity)
+{
+	BEGIN_IPCN
+	Server::active().setupConnection(rport, taskPort, securityToken, identity);
+	END_IPCN(CSSM)
+	return KERN_SUCCESS;
+}
+
+kern_return_t ucsp_server_teardown(UCSP_ARGS)
+{
+	BEGIN_IPCN
+	Server::active().endConnection(rport);
+	END_IPCN(CSSM)
+	return KERN_SUCCESS;
+}
+
+
+//
+// Database management
+//
+kern_return_t ucsp_server_createDb(UCSP_ARGS, DbHandle *db,
+	COPY_IN(DLDbFlatIdentifier, ident),
+    COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
+    DBParameters params)
+{
+	BEGIN_IPC
+	relocate(cred, credBase, credLength);
+	relocate(owner, ownerBase, ownerLength);
+    relocate(ident, identBase, identLength);
+	*db = (new Database(*ident, params, connection.process, cred, owner))->handle();
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_decodeDb(UCSP_ARGS, DbHandle *db,
+    COPY_IN(DLDbFlatIdentifier, ident), COPY_IN(AccessCredentials, cred), DATA_IN(blob))
+{
+	BEGIN_IPC
+	relocate(cred, credBase, credLength);
+    relocate(ident, identBase, identLength);
+	*db = (new Database(*ident, DATA(blob).interpretedAs<DbBlob>(),
+        connection.process, cred))->handle();
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_encodeDb(UCSP_ARGS, DbHandle db, DATA_OUT(blob))
+{
+	BEGIN_IPC
+    DbBlob *dbBlob = Server::database(db).encode();	// memory owned by database
+    *blob = dbBlob;
+    *blobLength = dbBlob->length();
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_releaseDb(UCSP_ARGS, DbHandle db)
+{
+	BEGIN_IPC
+	delete &Server::database(db);
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_authenticateDb(UCSP_ARGS, DbHandle db,
+    COPY_IN(AccessCredentials, cred))
+{
+	BEGIN_IPC
+    relocate(cred, credBase, credLength);
+    Server::database(db).authenticate(cred);
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_setDbParameters(UCSP_ARGS, DbHandle db, DBParameters params)
+{
+	BEGIN_IPC
+	Server::database(db).setParameters(params);
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_getDbParameters(UCSP_ARGS, DbHandle db, DBParameters *params)
+{
+	BEGIN_IPC
+	Server::database(db).getParameters(*params);
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_changePassphrase(UCSP_ARGS, DbHandle db,
+    COPY_IN(AccessCredentials, cred))
+{
+	BEGIN_IPC
+    relocate(cred, credBase, credLength);
+	Server::database(db).changePassphrase(cred);
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_lockDb(UCSP_ARGS, DbHandle db)
+{
+	BEGIN_IPC
+	Server::database(db).lock();
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_unlockDb(UCSP_ARGS, DbHandle db)
+{
+	BEGIN_IPC
+	Server::database(db).unlock();
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_unlockDbWithPassphrase(UCSP_ARGS, DbHandle db, DATA_IN(passphrase))
+{
+	BEGIN_IPC
+	Server::database(db).unlock(DATA(passphrase));
+	END_IPC(DL)
+}
+
+kern_return_t ucsp_server_isLocked(UCSP_ARGS, DbHandle db, boolean_t *locked)
+{
+    BEGIN_IPC
+    *locked = Server::database(db).isLocked();
+    END_IPC(DL)
+}
+
+
+//
+// Key management
+//
+kern_return_t ucsp_server_encodeKey(UCSP_ARGS, KeyHandle keyh, DATA_OUT(blob),
+    boolean_t wantUid, DATA_OUT(uid))
+{
+	BEGIN_IPC
+    Key &key = Server::key(keyh);
+    KeyBlob *keyBlob = key.blob();	// still owned by key
+    *blob = keyBlob;
+    *blobLength = keyBlob->length();
+    if (wantUid) {
+        *uid = &key.uid();
+        *uidLength = sizeof(KeyUID);
+    } else {
+        *uidLength = 0;	// do not return this
+    }
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_decodeKey(UCSP_ARGS, KeyHandle *keyh, CssmKey::Header *header,
+	DbHandle db, DATA_IN(blob))
+{
+	BEGIN_IPC
+    Key &key = *new Key(Server::database(db), DATA(blob).interpretedAs<KeyBlob>());
+    key.returnKey(*keyh, *header);
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_releaseKey(UCSP_ARGS, KeyHandle key)
+{
+	BEGIN_IPC
+	connection.releaseKey(key);
+	END_IPC(CSP)
+}
+
+
+//
+// RNG interface
+//
+kern_return_t ucsp_server_generateRandom(UCSP_ARGS, uint32 bytes, DATA_OUT(data))
+{
+	BEGIN_IPC
+	CssmAllocator &allocator = CssmAllocator::standard(CssmAllocator::sensitive);
+	void *buffer = allocator.malloc(bytes);
+    Server::active().random(buffer, bytes);
+	*data = buffer;
+	*dataLength = bytes;
+	Server::releaseWhenDone(allocator, buffer);
+	END_IPC(CSP)
+}
+
+
+//
+// Signatures and MACs
+//
+kern_return_t ucsp_server_generateSignature(UCSP_ARGS, CONTEXT_ARGS, KeyHandle key,
+		DATA_IN(data), DATA_OUT(signature))
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+	OutputData sigData(signature, signatureLength);
+	connection.generateSignature(context, findHandle<Key>(key),
+		DATA(data), sigData);
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_verifySignature(UCSP_ARGS, CONTEXT_ARGS, KeyHandle key,
+		DATA_IN(data), DATA_IN(signature))
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+	connection.verifySignature(context, findHandle<Key>(key),
+		DATA(data), DATA(signature));
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_generateMac(UCSP_ARGS, CONTEXT_ARGS, KeyHandle key,
+		DATA_IN(data), DATA_OUT(mac))
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+	OutputData macData(mac, macLength);
+	connection.generateMac(context, findHandle<Key>(key),
+		DATA(data), macData);
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_verifyMac(UCSP_ARGS, CONTEXT_ARGS, KeyHandle key,
+		DATA_IN(data), DATA_IN(mac))
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+	connection.verifyMac(context, findHandle<Key>(key),
+		DATA(data), DATA(mac));
+	END_IPC(CSP)
+}
+
+
+//
+// Encryption/Decryption
+//
+kern_return_t ucsp_server_encrypt(UCSP_ARGS, CONTEXT_ARGS, KeyHandle key,
+	DATA_IN(clear), DATA_OUT(cipher))
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+	OutputData cipherOut(cipher, cipherLength);
+	connection.encrypt(context, findHandle<Key>(key),
+		DATA(clear), cipherOut);
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_decrypt(UCSP_ARGS, CONTEXT_ARGS, KeyHandle key,
+	DATA_IN(cipher), DATA_OUT(clear))
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+	OutputData clearOut(clear, clearLength);
+	connection.decrypt(context, findHandle<Key>(key),
+		DATA(cipher), clearOut);
+	END_IPC(CSP)
+}
+
+
+//
+// Key generation
+//
+kern_return_t ucsp_server_generateKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
+	COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
+	uint32 usage, uint32 attrs, KeyHandle *newKey, CssmKey::Header *newHeader)
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+    relocate(cred, credBase, credLength);
+	relocate(owner, ownerBase, ownerLength);
+    Key *key;
+	connection.generateKey(Server::optionalDatabase(db),
+		context, cred, owner, usage, attrs, key);
+    key->returnKey(*newKey, *newHeader);
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_generateKeyPair(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
+	COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
+	uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs,
+	KeyHandle *pubKey, CssmKey::Header *pubHeader, KeyHandle *privKey, CssmKey::Header *privHeader)
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+    relocate(cred, credBase, credLength);
+	relocate(owner, ownerBase, ownerLength);
+    Key *pub, *priv;
+	connection.generateKey(Server::optionalDatabase(db),
+		context, cred, owner,
+		pubUsage, pubAttrs, privUsage, privAttrs, pub, priv);
+    pub->returnKey(*pubKey, *pubHeader);
+    priv->returnKey(*privKey, *privHeader);
+	END_IPC(CSP)
+}
+
+
+//
+// Key wrapping and unwrapping
+//
+kern_return_t ucsp_server_wrapKey(UCSP_ARGS, CONTEXT_ARGS, KeyHandle key,
+	COPY_IN(AccessCredentials, cred), KeyHandle keyToBeWrapped,
+	DATA_IN(descriptiveData), CssmKey *wrappedKey, DATA_OUT(keyData))
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+    relocate(cred, credBase, credLength);
+    connection.wrapKey(context, Server::optionalKey(key),
+        Server::key(keyToBeWrapped), cred, DATA(descriptiveData), *wrappedKey);
+    // transmit key data back as a separate blob
+	*keyData = wrappedKey->data();
+	*keyDataLength = wrappedKey->length();
+	Server::releaseWhenDone(*keyData);
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_unwrapKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS, KeyHandle key,
+	COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
+	KeyHandle publicKey, CssmKey wrappedKey, DATA_IN(wrappedKeyData),
+	uint32 usage, uint32 attr, DATA_OUT(descriptiveData),
+    KeyHandle *newKey, CssmKey::Header *newHeader)
+{
+	BEGIN_IPC
+	context.postIPC(contextBase, attributes);
+	wrappedKey.KeyData = DATA(wrappedKeyData);
+    relocate(cred, credBase, credLength);
+	relocate(owner, ownerBase, ownerLength);
+	CssmData descriptiveDatas;
+    Key &theKey = connection.unwrapKey(Server::optionalDatabase(db),
+		context, Server::optionalKey(key), cred, owner, usage, attr, wrappedKey,
+        Server::optionalKey(publicKey), &descriptiveDatas);
+    theKey.returnKey(*newKey, *newHeader);
+	*descriptiveData = descriptiveDatas.data();
+	*descriptiveDataLength = descriptiveDatas.length();
+	Server::releaseWhenDone(*descriptiveData);
+	END_IPC(CSP)
+}
+
+
+//
+// ACL management.
+// Watch out for the memory-management tap-dance.
+//
+kern_return_t ucsp_server_getOwner(UCSP_ARGS, AclKind kind, KeyHandle key,
+	COPY_OUT(AclOwnerPrototype, ownerOut))
+{
+	BEGIN_IPC
+	AclOwnerPrototype owner;
+	Server::aclBearer(kind, key).cssmGetOwner(owner);	// allocates memory in owner
+	Copier<AclOwnerPrototype> owners(&owner, CssmAllocator::standard()); // make flat copy
+	{ ChunkFreeWalker free; walk(free, owner); } // release chunked original
+	*ownerOut = *ownerOutBase = owners;
+	*ownerOutLength = owners.length();
+	Server::releaseWhenDone(owners.keep()); // throw flat copy out when done
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_setOwner(UCSP_ARGS, AclKind kind, KeyHandle key,
+	COPY_IN(AccessCredentials, cred), COPY_IN(AclOwnerPrototype, owner))
+{
+	BEGIN_IPC
+    relocate(cred, credBase, credLength);
+	relocate(owner, ownerBase, ownerLength);
+	Server::aclBearer(kind, key).cssmChangeOwner(*owner, cred);
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_getAcl(UCSP_ARGS, AclKind kind, KeyHandle key,
+	boolean_t haveTag, const char *tag,
+	uint32 *countp, COPY_OUT(AclEntryInfo, acls))
+{
+	BEGIN_IPC
+	uint32 count;
+	AclEntryInfo *aclList;
+	Server::aclBearer(kind, key).cssmGetAcl(haveTag ? tag : NULL, count, aclList);
+	*countp = count;
+	Copier<AclEntryInfo> aclsOut(AclEntryInfo::overlay(aclList), count); // make flat copy
+
+	{	// release the chunked memory originals
+		ChunkFreeWalker free;
+		for (uint32 n = 0; n < count; n++)
+			walk(free, aclList[n]);
+	}
+	
+	// set result
+	*acls = *aclsBase = aclsOut;
+	*aclsLength = aclsOut.length();
+	Server::releaseWhenDone(aclsOut.keep());
+	END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_changeAcl(UCSP_ARGS, AclKind kind, KeyHandle key,
+	COPY_IN(AccessCredentials, cred), CSSM_ACL_EDIT_MODE mode, CSSM_ACL_HANDLE handle,
+	COPY_IN(AclEntryPrototype, acl))
+{
+	BEGIN_IPC
+    relocate(cred, credBase, credLength);
+	relocate(acl, aclBase, aclLength);
+	AclEntryInput input(*acl);
+	Server::aclBearer(kind, key).cssmChangeAcl(AclEdit(mode, handle, &input), cred);
+	END_IPC(CSP)
+}
+
+
+//
+// Authorization subsystem support
+//
+kern_return_t ucsp_server_authorizationCreate(UCSP_ARGS,
+	COPY_IN(AuthorizationItemSet, rights),
+	uint32 flags,
+	COPY_IN(AuthorizationItemSet, environment),
+	AuthorizationBlob *authorization)
+{
+	BEGIN_IPC
+	relocate(rights, rightsBase, rightsLength);
+	relocate(environment, environmentBase, environmentLength);
+	*rcode = connection.process.session.authCreate(rights, environment, 
+		flags, *authorization);
+	END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_authorizationRelease(UCSP_ARGS,
+	AuthorizationBlob authorization, uint32 flags)
+{
+	BEGIN_IPC
+	connection.process.session.authFree(authorization, flags);
+	END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_authorizationCopyRights(UCSP_ARGS,
+	AuthorizationBlob authorization,
+	COPY_IN(AuthorizationItemSet, rights),
+	uint32 flags,
+	COPY_IN(AuthorizationItemSet, environment),
+	COPY_OUT(AuthorizationItemSet, result))
+{
+	BEGIN_IPC
+	relocate(rights, rightsBase, rightsLength);
+	relocate(environment, environmentBase, environmentLength);
+	Authorization::MutableRightSet grantedRights;
+	*rcode = connection.process.session.authGetRights(authorization,
+		rights, environment, flags, grantedRights);
+	Copier<AuthorizationRights> returnedRights(grantedRights, CssmAllocator::standard());
+	*result = *resultBase = returnedRights;
+	*resultLength = returnedRights.length();
+	Server::releaseWhenDone(returnedRights.keep());
+	END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_authorizationCopyInfo(UCSP_ARGS,
+	AuthorizationBlob authorization,
+	AuthorizationString tag,
+	COPY_OUT(AuthorizationItemSet, info))
+{
+	BEGIN_IPC
+	Authorization::MutableRightSet result;
+	*rcode = connection.process.session.authGetInfo(authorization,
+        tag[0] ? tag : NULL, result);
+	Copier<AuthorizationItemSet> returnedInfo(result, CssmAllocator::standard());
+	*info = *infoBase = returnedInfo;
+	*infoLength = returnedInfo.length();
+	Server::releaseWhenDone(returnedInfo.keep());
+	END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_authorizationExternalize(UCSP_ARGS,
+	AuthorizationBlob authorization, AuthorizationExternalForm *extForm)
+{
+	BEGIN_IPC
+	*rcode = connection.process.session.authExternalize(authorization, *extForm);
+	END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_authorizationInternalize(UCSP_ARGS,
+	AuthorizationExternalForm extForm, AuthorizationBlob *authorization)
+{
+	BEGIN_IPC
+	*rcode = connection.process.session.authInternalize(extForm, *authorization);
+	END_IPC(CSSM)
+}
+
+
+//
+// Session management subsystem
+//
+kern_return_t ucsp_server_getSessionInfo(UCSP_ARGS,
+    SecuritySessionId *sessionId, SessionAttributeBits *attrs)
+{
+	BEGIN_IPC
+    Session &session = Session::find(*sessionId);
+    *sessionId = session.handle();
+    *attrs = session.attributes();
+	END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_setupSession(UCSP_ARGS,
+    SessionCreationFlags flags, SessionAttributeBits attrs)
+{
+	BEGIN_IPC
+    Session::setup(flags, attrs);
+	END_IPC(CSSM)
+}
diff --git a/SecurityServer/ucsp.defs b/SecurityServer/ucsp.defs
new file mode 100644
index 00000000..db2cf63a
--- /dev/null
+++ b/SecurityServer/ucsp.defs
@@ -0,0 +1,226 @@
+//
+// ucsp.defs - Mach RPC interface between SecurityServer and its clients
+//
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+
+subsystem ucsp 1000;
+serverprefix ucsp_server_;
+userprefix ucsp_client_;
+
+import "securityserver.h";
+import "ucsp_types.h";
+
+
+//
+// Data types
+//
+type Data = array [] of char;
+
+type KeyHandle = unsigned32;
+type KeyBlob = Data
+	ctype: Pointer;
+
+type DbHandle = unsigned32;
+type DbBlob = Data
+	ctype: Pointer;
+
+type AclEntryPrototypeBlob = Data
+	ctype: AclEntryPrototypePtr;
+type AclEntryPrototypePtr = unsigned32;
+
+type AclEntryInfoBlob = Data
+	ctype: AclEntryInfoPtr;
+type AclEntryInfoPtr = unsigned32;
+
+type AclOwnerPrototypeBlob = Data
+	ctype: AclOwnerPrototypePtr;
+type AclOwnerPrototypePtr = unsigned32;
+
+type AccessCredentialsBlob = Data
+	ctype: AccessCredentialsPtr;
+type AccessCredentialsPtr = unsigned32;
+
+type DLDbIdentBlob = Data
+    ctype: DLDbIdentPtr;
+type DLDbIdentPtr = unsigned32;
+
+type Context = struct [9] of unsigned32
+	ctype: CSSM_CONTEXT
+	intran: Context inTrans(CSSM_CONTEXT);
+type ContextAttributes = array [] of char
+	cservertype: ContextAttributesPointer;
+	
+type CssmKeyHeader = struct [23] of unsigned32;
+
+type CssmKey = struct [23+2] of unsigned32
+	ctype: CSSM_KEY
+	intran: CssmKey inTrans(CSSM_KEY)
+	outtran: CSSM_KEY outTrans(CssmKey);
+
+type DBParameters = struct [1] of unsigned32;
+
+type AuthorizationItemSetBlob = Data
+	ctype: AuthorizationItemSetPtr;
+type AuthorizationItemSetPtr = unsigned32;
+
+type AuthorizationBlob = struct [2] of unsigned32;				// 8 opaque bytes
+type AuthorizationExternalForm = struct [8] of unsigned32;		// 32 opaque bytes
+
+type CssmString = c_string[*:64+4];
+type AuthorizationString = c_string[*:1024];
+type CSSM_RETURN = int32;
+type CSSM_ALGORITHMS = unsigned32;
+type CSSM_ACL_EDIT_MODE = unsigned32;
+type CSSM_ACL_HANDLE = unsigned32;
+type AclKind = unsigned32;
+type uint32 = unsigned32;
+type SecuritySessionId = unsigned32;
+type SessionAttributeBits = unsigned32;
+type SessionCreationFlags = unsigned32;
+
+type Pointer = unsigned32;
+
+type ExecutablePath = c_string[*:2048];
+
+
+//
+// Common argument profiles
+//
+#define UCSP_PORTS	requestport sport: mach_port_t; \
+					replyport rport: mach_port_make_send_t; \
+                    serversectoken sourceSecurity: security_token_t; \
+					out rcode: CSSM_RETURN
+#define IN_CONTEXT	in context: Context; in contextBase: Pointer; in attrs: ContextAttributes
+#define IN_BLOB(name,type)	in name: type##Blob; in name##Base: type##Ptr
+#define OUT_BLOB(name,type)	out name: type##Blob; out name##Base: type##Ptr
+
+
+//
+// Management and administrative functions
+//
+routine setup(UCSP_PORTS; in tport: mach_port_t; in executablePath: ExecutablePath);
+routine teardown(UCSP_PORTS);
+
+
+//
+// Database management
+//
+routine createDb(UCSP_PORTS; out db: DbHandle; IN_BLOB(ident,DLDbIdent);
+    IN_BLOB(accessCredentials,AccessCredentials); IN_BLOB(aclEntryPrototype,AclEntryPrototype);
+    in params: DBParameters);
+routine decodeDb(UCSP_PORTS; out db: DbHandle; IN_BLOB(ident,DLDbIdent);
+    IN_BLOB(accessCredentials,AccessCredentials); in blob: DbBlob);
+routine encodeDb(UCSP_PORTS; in db: DbHandle; out blob: DbBlob);
+routine releaseDb(UCSP_PORTS; in db: DbHandle);
+routine authenticateDb(UCSP_PORTS; in db: DbHandle; IN_BLOB(accessCredentials,AccessCredentials));
+routine setDbParameters(UCSP_PORTS; in db: DbHandle; in params: DBParameters);
+routine getDbParameters(UCSP_PORTS; in db: DbHandle; out params: DBParameters);
+routine changePassphrase(UCSP_PORTS; in db: DbHandle; 
+	IN_BLOB(accessCredentials,AccessCredentials));
+routine lockDb(UCSP_PORTS; in db: DbHandle);
+routine unlockDb(UCSP_PORTS; in db: DbHandle);
+routine unlockDbWithPassphrase(UCSP_PORTS; in db: DbHandle; in passPhrase: Data);
+routine isLocked(UCSP_PORTS; in db: DbHandle; out locked: boolean_t);
+
+
+//
+// Key management
+//
+routine encodeKey(UCSP_PORTS; in key: KeyHandle; out blob: KeyBlob;
+    in wantUid: boolean_t; out uid: Data);
+routine decodeKey(UCSP_PORTS; out key: KeyHandle; out header: CssmKeyHeader;
+    in db: DbHandle; in blob: KeyBlob);
+routine releaseKey(UCSP_PORTS; in key: KeyHandle);
+
+
+//
+// Random numbers
+//
+routine generateRandom(UCSP_PORTS; in bytes: uint32; out data: Data);
+
+
+//
+// Cryptographic operations
+//
+routine generateSignature(UCSP_PORTS; IN_CONTEXT; in key: KeyHandle;
+	in data: Data; out signature: Data);
+routine verifySignature(UCSP_PORTS; IN_CONTEXT; in key: KeyHandle;
+	in data: Data; in signature: Data);
+routine generateMac(UCSP_PORTS; IN_CONTEXT; in key: KeyHandle;
+	in data: Data; out signature: Data);
+routine verifyMac(UCSP_PORTS; IN_CONTEXT; in key: KeyHandle;
+	in data: Data; in signature: Data);
+
+routine encrypt(UCSP_PORTS; IN_CONTEXT; in key: KeyHandle; in clear: Data; out cipher: Data);
+routine decrypt(UCSP_PORTS; IN_CONTEXT; in key: KeyHandle; in cipher: Data; out clear: Data);
+
+routine generateKey(UCSP_PORTS; in db: DbHandle; IN_CONTEXT;
+	IN_BLOB(accessCredentials,AccessCredentials); IN_BLOB(aclEntryPrototype,AclEntryPrototype);
+	in keyUsage: uint32; in keyAttrs: uint32; out key: KeyHandle; out header: CssmKeyHeader);
+routine generateKeyPair(UCSP_PORTS; in db: DbHandle; IN_CONTEXT;
+	IN_BLOB(accessCredentials,AccessCredentials); IN_BLOB(aclEntryPrototype,AclEntryPrototype);
+	in pubUsage: uint32; in pubAttrs: uint32; in privUsage: uint32; in privAttrs: uint32;
+	out pubKey: KeyHandle; out pubHeader: CssmKeyHeader;
+    out privKey: KeyHandle; out privHeader: CssmKeyHeader);
+
+routine wrapKey(UCSP_PORTS; IN_CONTEXT; in key: KeyHandle;
+    IN_BLOB(accessCredentials,AccessCredentials); in keyToBeWrapped: KeyHandle;
+	in data: Data; out wrappedKey: CssmKey; out wrappedKeyData: Data);
+routine unwrapKey(UCSP_PORTS; in db: DbHandle; IN_CONTEXT; in key: KeyHandle;
+	IN_BLOB(accessCredentials,AccessCredentials); IN_BLOB(aclEntryPrototype,AclEntryPrototype);
+	in publicKey: KeyHandle; in wrappedKey: CssmKey; in wrappedKeyData: Data;
+	in usage: uint32; in attributes: uint32; out data: Data; 
+    out resultKey: KeyHandle; out header: CssmKeyHeader);
+
+
+//
+// ACL management
+//
+routine getOwner(UCSP_PORTS; in kind: AclKind; in key: KeyHandle;
+	out proto: AclOwnerPrototypeBlob; out protoBase: AclOwnerPrototypePtr);
+routine setOwner(UCSP_PORTS; in kind: AclKind; in key: KeyHandle;
+	IN_BLOB(accessCredentials,AccessCredentials); IN_BLOB(aclOwnerPrototype,AclOwnerPrototype));
+routine getAcl(UCSP_PORTS; in kind: AclKind; in key: KeyHandle;
+	in haveTag: boolean_t; in tag: CssmString;
+	out count: uint32; out acls: AclEntryInfoBlob; out aclsBase: AclEntryInfoPtr);
+routine changeAcl(UCSP_PORTS; in kind: AclKind; in key: KeyHandle;
+	IN_BLOB(accessCredentials,AccessCredentials);
+	in mode: CSSM_ACL_EDIT_MODE; in handle: CSSM_ACL_HANDLE;
+	IN_BLOB(aclEntryPrototype,AclEntryPrototype));
+
+
+//
+// Authorization subsystem
+//
+routine authorizationCreate(UCSP_PORTS; IN_BLOB(rights,AuthorizationItemSet);
+	in flags: uint32;
+	IN_BLOB(environment,AuthorizationItemSet);
+	out authorization: AuthorizationBlob);
+
+routine authorizationRelease(UCSP_PORTS; in authorization: AuthorizationBlob;
+	in flags: uint32);
+
+routine authorizationCopyRights(UCSP_PORTS; in authorization: AuthorizationBlob;
+	IN_BLOB(rights,AuthorizationItemSet); in flags: uint32;
+	IN_BLOB(environment,AuthorizationItemSet);
+	OUT_BLOB(result,AuthorizationItemSet));
+
+routine authorizationCopyInfo(UCSP_PORTS; in authorization: AuthorizationBlob;
+	in tag: AuthorizationString;
+	OUT_BLOB(info,AuthorizationItemSet));
+
+routine authorizationExternalize(UCSP_PORTS; in authorization: AuthorizationBlob;
+	out form: AuthorizationExternalForm);
+
+routine authorizationInternalize(UCSP_PORTS; in form: AuthorizationExternalForm;
+	out authorization: AuthorizationBlob);
+
+
+//
+// Session management subsystem
+//
+routine getSessionInfo(UCSP_PORTS; inout sessionId: SecuritySessionId;
+    out attrs: SessionAttributeBits);
+
+routine setupSession(UCSP_PORTS; in flags: SessionCreationFlags; in attrs: SessionAttributeBits);
diff --git a/SecurityServer/ucsp_types.h b/SecurityServer/ucsp_types.h
new file mode 100644
index 00000000..ddba23f1
--- /dev/null
+++ b/SecurityServer/ucsp_types.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+
+//
+// ucsp_types - type equivalence declarations for SecurityServer MIG
+//
+#include "ssclient.h"
+#include <Security/Authorization.h>
+
+// who forgot that one?
+extern "C" kern_return_t mig_deallocate(vm_address_t addr, vm_size_t size);
+
+namespace Security {
+
+using namespace SecurityServer;
+
+
+typedef void *Data;
+typedef void *Pointer;
+
+typedef const char *CssmString;
+
+typedef void *ContextAttributes;
+typedef Context::Attr *ContextAttributesPointer;
+
+typedef AclEntryPrototype *AclEntryPrototypePtr;
+typedef AclEntryInfo *AclEntryInfoPtr;
+typedef AclOwnerPrototype *AclOwnerPrototypePtr;
+typedef AccessCredentials *AccessCredentialsPtr;
+
+typedef DataWalkers::DLDbFlatIdentifier DLDbIdentBlob;
+typedef DataWalkers::DLDbFlatIdentifier *DLDbIdentPtr;
+
+typedef AuthorizationItemSet AuthorizationItemSetBlob;
+typedef AuthorizationItemSet *AuthorizationItemSetPtr;
+typedef void *AuthorizationHandle;
+
+typedef CssmKey::Header CssmKeyHeader;
+
+typedef const char *ExecutablePath;
+
+inline Context &inTrans(CSSM_CONTEXT &arg) { return Context::overlay(arg); }
+inline CssmKey &inTrans(CSSM_KEY &arg) { return CssmKey::overlay(arg); }
+inline CSSM_KEY &outTrans(CssmKey &key) { return key; }
+
+// fix const-blindless in MIG's internals
+inline int mig_strncpy(char *dest, const char *src, int length)
+{ return ::mig_strncpy(dest, const_cast<char *>(src), length); }
+
+
+//
+// Customization macros for MIG code
+//
+#define __AfterSendRpc(id, name) \
+	if (msg_result == MACH_MSG_SUCCESS && Out0P->Head.msgh_id == MACH_NOTIFY_DEAD_NAME) \
+		return MIG_SERVER_DIED;
+
+#define UseStaticTemplates 0
+
+} // end namespace Security
diff --git a/SecurityServer/xdatabase.cpp b/SecurityServer/xdatabase.cpp
new file mode 100644
index 00000000..a897dc64
--- /dev/null
+++ b/SecurityServer/xdatabase.cpp
@@ -0,0 +1,584 @@
+/*
+ * 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.
+ */
+
+
+//
+// database - database session management
+//
+#include "xdatabase.h"
+#include "agentquery.h"
+#include "key.h"
+#include "server.h"
+#include "cfnotifier.h"
+#include "SecurityAgentClient.h"
+#include <Security/acl_any.h>	// for default owner ACLs
+
+
+//
+// The map of database common segments
+//
+Mutex Database::commonLock;
+Database::CommonMap Database::commons;
+
+
+//
+// Create a Database object from initial parameters (create operation)
+//
+Database::Database(const DLDbIdentifier &id, const DBParameters &params, Process &proc,
+            const AccessCredentials *cred, const AclEntryPrototype *owner)
+	: SecurityServerAcl(dbAcl, CssmAllocator::standard()), process(proc),
+    mValidData(false), version(0), mBlob(NULL)
+{
+    // save a copy of the credentials for later access control
+    mCred = DataWalkers::copy(cred, CssmAllocator::standard());
+
+    // create a new random signature to complete the DLDbIdentifier
+    Signature newSig;
+    Server::active().random(newSig.bytes);
+    DbIdentifier ident(id, newSig);
+    
+    // create common block and initialize
+	common = new Common(ident);
+	StLock<Mutex> _(*common);
+	{	StLock<Mutex> _(commonLock);
+		assert(commons.find(ident) == commons.end());	// better be new!
+		commons[ident] = common = new Common(ident);
+		common->useCount++;
+	}
+	// new common is now visible but we hold its lock
+	
+	// obtain initial passphrase and generate keys
+	common->mParams = params;
+	common->setupKeys(cred);
+
+	// establish initial ACL
+	if (owner)
+		cssmSetInitial(*owner);
+	else
+		cssmSetInitial(new AnyAclSubject());
+    mValidData = true;
+    
+    // for now, create the blob immediately
+    //@@@ this could be deferred, at the cost of some additional
+    //@@@ state monitoring. What happens if it locks before we have a blob?
+    encode();
+    
+    // register with process
+    process.addDatabase(this);
+    
+	IFDEBUG(debug("SSdb", "database %s(%p) created, common at %p",
+		common->dbName(), this, common));
+	IFDUMPING("SSdb", debugDump("creation complete"));
+}
+
+
+//
+// Create a Database object from a database blob (decoding)
+//
+Database::Database(const DLDbIdentifier &id, const DbBlob *blob, Process &proc,
+    const AccessCredentials *cred)
+	: SecurityServerAcl(dbAcl, CssmAllocator::standard()), process(proc),
+    mValidData(false), version(0)
+{
+    // perform basic validation on the incoming blob
+	assert(blob);
+    blob->validate(CSSMERR_APPLEDL_INVALID_DATABASE_BLOB);
+    switch (blob->version) {
+#if defined(COMPAT_OSX_10_0)
+    case blob->version_MacOS_10_0:
+        break;
+#endif
+    case blob->version_MacOS_10_1:
+        break;
+    default:
+        CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_DATABASE_BLOB);
+    }
+
+    // save a copy of the credentials for later access control
+    mCred = DataWalkers::copy(cred, CssmAllocator::standard());
+    
+    // check to see if we already know about this database
+    DbIdentifier ident(id, blob->randomSignature);
+	StLock<Mutex> mapLock(commonLock);
+    CommonMap::iterator it = commons.find(ident);
+    if (it != commons.end()) {
+        // already there
+        common = it->second;				// reuse common component
+        //@@@ arbitrate sequence number here, perhaps update common->mParams
+		StLock<Mutex> _(*common);			// lock common against other users
+		common->useCount++;
+		IFDEBUG(debug("SSdb",
+            "open database %s(%p) version %lx at known common %p(%d)",
+			common->dbName(), this, blob->version, common, int(common->useCount)));
+    } else {
+        // newly introduced
+        commons[ident] = common = new Common(ident);
+		common->mParams = blob->params;
+		common->useCount++;
+		IFDEBUG(debug("SSdb", "open database %s(%p) version %lx with new common %p",
+			common->dbName(), this, blob->version, common));
+    }
+    
+    // register with process
+    process.addDatabase(this);
+
+    mBlob = blob->copy();
+    IFDUMPING("SSdb", debugDump("end of decode"));
+}
+
+
+//
+// Destroy a Database
+//
+Database::~Database()
+{
+    IFDEBUG(debug("SSdb", "deleting database %s(%p) common %p (%d refs)",
+        common->dbName(), this, common, int(common->useCount)));
+    IFDUMPING("SSdb", debugDump("deleting database instance"));
+    process.removeDatabase(this);
+    CssmAllocator::standard().free(mCred);
+
+    // take the commonLock to avoid races against re-use of the common
+    StLock<Mutex> __(commonLock);
+    if (--common->useCount == 0 && common->isLocked()) {
+        // last use of this database, and it's locked - discard
+		IFDUMPING("SSdb", debugDump("discarding common"));
+        discard(common);
+    } else if (common->useCount == 0)
+		IFDUMPING("SSdb", debugDump("retained because it's unlocked"));
+}
+
+
+//
+// (Re-)Authenticate the database. This changes the stored credentials.
+//
+void Database::authenticate(const AccessCredentials *cred)
+{
+	StLock<Mutex> _(*common);
+    CssmAllocator::standard().free(mCred);
+    mCred = DataWalkers::copy(cred, CssmAllocator::standard());
+}
+
+
+//
+// Encode the current database as a blob.
+// Note that this returns memory we own and keep.
+//
+DbBlob *Database::encode()
+{
+	StLock<Mutex> _(*common);
+    if (!validBlob()) {
+        // unlock the database
+        makeUnlocked();
+
+        // create new up-to-date blob
+        DbBlob *blob = common->encode(*this);
+        CssmAllocator::standard().free(mBlob);
+        mBlob = blob;
+        version = common->version;
+		debug("SSdb", "encoded database %p(%s) version %ld", this, dbName(), version);
+    }
+    activity();
+	assert(mBlob);
+    return mBlob;
+}
+
+
+//
+// Change the passphrase on a database
+//
+void Database::changePassphrase(const AccessCredentials *cred)
+{
+	StLock<Mutex> _(*common);
+	if (isLocked()) {
+		CssmAutoData passphrase(CssmAllocator::standard(CssmAllocator::sensitive));
+		if (getBatchPassphrase(cred, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, passphrase)) {
+			// incoming sample contained data for unlock
+			makeUnlocked(passphrase);
+		} else {
+			// perform standard unlock
+			makeUnlocked();
+		}
+    } else if (!mValidData)     // need to decode to get our ACLs, passphrase available
+        decode(common->passphrase);
+
+    // get the new passphrase
+	// @@@ unstaged version -- revise to filter passphrases
+	QueryNewPassphrase query(*common, SecurityAgent::changePassphrase);
+	query(cred, common->passphrase);
+	common->version++;	// blob state changed
+	IFDEBUG(debug("SSdb", "Database %s(%p) passphrase changed", common->dbName(), this));
+	
+	// send out a notification
+	KeychainNotifier::passphraseChanged(identifier());
+
+    // I guess this counts as an activity
+    activity();
+}
+
+
+//
+// Unlock this database (if needed) by obtaining the passphrase in some
+// suitable way and then proceeding to unlock with it. Performs retries
+// where appropriate. Does absolutely nothing if the database is already unlocked.
+//
+void Database::unlock()
+{
+	StLock<Mutex> _(*common);
+	makeUnlocked();
+}
+	
+void Database::makeUnlocked()
+{
+    IFDUMPING("SSdb", debugDump("default procedures unlock"));
+    if (isLocked()) {
+        assert(mBlob || (mValidData && common->passphrase));
+		
+		QueryUnlock query(*this);
+		query(mCred);
+		if (isLocked())		// still locked, unlock failed
+			CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
+			
+		// successfully unlocked
+		activity();				// set timeout timer
+	} else if (!mValidData)		// need to decode to get our ACLs, passphrase available
+		decode(common->passphrase);
+}
+
+
+//
+// Perform programmatic unlock of a database, given a passphrase.
+//
+void Database::unlock(const CssmData &passphrase)
+{
+	StLock<Mutex> _(*common);
+	makeUnlocked(passphrase);
+}
+
+void Database::makeUnlocked(const CssmData &passphrase)
+{
+	if (isLocked()) {
+		if (decode(passphrase))
+			return;
+		else
+			CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
+	} else if (!mValidData)
+		decode(common->passphrase);
+}
+
+
+//
+// Perform an actual unlock operation given a passphrase.
+// Caller must hold common lock.
+//
+bool Database::decode(const CssmData &passphrase)
+{
+	if (mValidData && common->passphrase) {	// just check
+		return common->unlock(passphrase);
+	} else {	// decode our blob
+		assert(mBlob);
+		void *privateAclBlob;
+		if (common->unlock(mBlob, passphrase, &privateAclBlob)) {
+			if (!mValidData) {
+				importBlob(mBlob->publicAclBlob(), privateAclBlob);
+				mValidData = true;
+			}
+			CssmAllocator::standard().free(privateAclBlob);
+			return true;
+		}
+	}
+	return false;
+}
+
+
+//
+// Lock this database
+//
+void Database::lock()
+{
+    common->lock();
+}
+
+
+//
+// Lock all databases we know of.
+// This is an interim stop-gap measure, until we can work out how database
+// state should interact with true multi-session operation.
+//
+void Database::lockAllDatabases(bool forSleep)
+{
+    StLock<Mutex> _(commonLock);	// hold all changes to Common map
+    debug("SSdb", "locking all %d known databases", int(commons.size()));
+    for (CommonMap::iterator it = commons.begin(); it != commons.end(); it++)
+        it->second->lock(true, forSleep);	// lock, already holding commonLock
+}
+
+
+//
+// Given a Key for this database, encode it into a blob and return it.
+//
+KeyBlob *Database::encodeKey(const CssmKey &key, const CssmData &pubAcl, const CssmData &privAcl)
+{
+    makeUnlocked();
+    
+    // tell the cryptocore to form the key blob
+    return common->encodeKeyCore(key, pubAcl, privAcl);
+}
+
+
+//
+// Given a "blobbed" key for this database, decode it into its real
+// key object and (re)populate its ACL.
+//
+void Database::decodeKey(KeyBlob *blob, CssmKey &key,
+    void * &pubAcl, void * &privAcl)
+{
+    makeUnlocked();							// we need our keys
+
+    common->decodeKeyCore(blob, key, pubAcl, privAcl);
+    // memory protocol: pubAcl points into blob; privAcl was allocated
+	
+    activity();
+}
+
+
+//
+// Modify database parameters
+//
+void Database::setParameters(const DBParameters &params)
+{
+	StLock<Mutex> _(*common);
+    makeUnlocked();
+	common->mParams = params;
+    common->version++;		// invalidate old blobs
+    activity();
+}
+
+
+//
+// Retrieve database parameters
+//
+void Database::getParameters(DBParameters &params)
+{
+	StLock<Mutex> _(*common);
+    makeUnlocked();
+	params = common->mParams;
+    //activity();		// getting parameters does not reset the idle timer
+}
+
+
+//
+// Intercept ACL change requests and reset blob validity
+//
+void Database::instantiateAcl()
+{
+	StLock<Mutex> _(*common);
+	makeUnlocked();
+}
+
+void Database::noticeAclChange()
+{
+	StLock<Mutex> _(*common);
+	version = 0;
+}
+
+const Database *Database::relatedDatabase() const
+{ return this; }
+
+
+//
+// Debugging support
+//
+#if defined(DEBUGDUMP)
+
+void Database::debugDump(const char *msg)
+{
+    assert(common);
+	const Signature &sig = common->identifier();
+	uint32 sig4; memcpy(&sig4, sig.bytes, sizeof(sig4));
+	Debug::dump("** %s(%8.8lx) common=%p(%ld) %s\n",
+		common->dbName(), sig4, common, common->useCount, msg);
+	if (isLocked())
+		Debug::dump("  locked");
+	else {
+		Time::Absolute when = common->when();
+		time_t whenTime = time_t(when);
+		Debug::dump("  UNLOCKED(%24.24s/%.2g)", ctime(&whenTime),
+            (when - Time::now()).seconds());
+	}
+	Debug::dump(" %s blobversion=%ld/%ld %svalidData",
+		(common->isValid() ? "validkeys" : "!validkeys"),
+		version, common->version,
+		(mValidData ? "" : "!"));
+	Debug::dump(" Params=(%ld %d)\n",
+		common->mParams.idleTimeout, common->mParams.lockOnSleep);
+}
+
+#endif //DEBUGDUMP
+
+
+//
+// Database::Common basic features
+//
+Database::Common::Common(const DbIdentifier &id)
+: mIdentifier(id), sequence(0), passphrase(CssmAllocator::standard(CssmAllocator::sensitive)),
+	useCount(0), version(1),
+    mIsLocked(true)
+{ }
+
+Database::Common::~Common()
+{
+	// explicitly unschedule ourselves
+	Server::active().clearTimer(this);
+}
+
+
+void Database::discard(Common *common)
+{
+    // LOCKING: commonLock held, *common NOT held
+    debug("SSdb", "discarding dbcommon %p (no users, locked)", common);
+	commons.erase(common->identifier());
+    delete common;
+}
+
+bool Database::Common::unlock(DbBlob *blob, const CssmData &passphrase,
+    void **privateAclBlob)
+{
+	try {
+		// Tell the cryptocore to (try to) decode itself. This will fail
+		// in an astonishing variety of ways if the passphrase is wrong.
+		decodeCore(blob, passphrase, privateAclBlob);
+	} catch (...) {
+		//@@@ which errors should we let through? Any?
+		return false;
+	}
+
+	// save the passphrase (we'll need it for database encoding)
+	this->passphrase = passphrase;
+	
+	// retrieve some public arguments
+	mParams = blob->params;
+	
+	// now successfully unlocked
+	mIsLocked = false;
+	
+	// set timeout
+	activity();
+	
+	// broadcast unlock notification
+	KeychainNotifier::unlock(identifier());
+    return true;
+}
+
+
+//
+// Fast-path unlock: secrets already valid; just check passphrase and approve.
+//
+bool Database::Common::unlock(const CssmData &passphrase)
+{
+    assert(isValid());
+    if (isLocked()) {
+        if (passphrase == this->passphrase) {
+            mIsLocked = false;
+			KeychainNotifier::unlock(identifier());
+            return true;	// okay
+        } else
+            return false;	// failed
+    } else
+        return true;		// was unlocked; no problem
+}
+
+void Database::Common::lock(bool holdingCommonLock, bool forSleep)
+{
+    StLock<Mutex> locker(*this);
+    if (!isLocked()) {
+        if (forSleep && !mParams.lockOnSleep)
+            return;	// it doesn't want to
+
+        //@@@ discard secrets here? That would make fast-path impossible.
+        mIsLocked = true;
+        KeychainNotifier::lock(identifier());
+		
+		// if no database refers to us now, we're history
+        StLock<Mutex> _(commonLock, false);
+        if (!holdingCommonLock)
+            _.lock();
+		if (useCount == 0) {
+            locker.unlock();	// release object lock
+			discard(this);
+        }
+    }
+}
+
+DbBlob *Database::Common::encode(Database &db)
+{
+    assert(!isLocked());	// must have been unlocked by caller
+    
+    // export database ACL to blob form
+    CssmData pubAcl, privAcl;
+    db.exportBlob(pubAcl, privAcl);
+    
+    // tell the cryptocore to form the blob
+    DbBlob form;
+    form.randomSignature = identifier();
+    form.sequence = sequence;
+    form.params = mParams;
+    DbBlob *blob = encodeCore(form, passphrase, pubAcl, privAcl);
+    
+    // clean up and go
+    db.allocator.free(pubAcl);
+    db.allocator.free(privAcl);
+	return blob;
+}
+
+
+//
+// Initialize a (new) database's key information.
+// This acquires the passphrase in the appropriate way.
+// When (successfully) done, the database is in the unlocked state.
+//
+void Database::Common::setupKeys(const AccessCredentials *cred)
+{
+	// get the new passphrase
+	// @@@ Un-staged version of the API - revise with acceptability tests
+	QueryNewPassphrase query(*this, SecurityAgent::newDatabase);
+	query(cred, passphrase);
+		
+	// we have the passphrase now
+    generateNewSecrets();
+	
+	// we're unlocked now
+	mIsLocked = false;
+    activity();
+}
+
+
+//
+// Perform deferred lock processing for a database.
+//
+void Database::Common::action()
+{
+	IFDEBUG(debug("SSdb", "common %s(%p) locked by timer (%d refs)",
+		dbName(), this, int(useCount)));
+	lock();
+}
+
+void Database::Common::activity()
+{
+    if (!isLocked())
+		Server::active().setTimer(this, int(mParams.idleTimeout));
+}
diff --git a/SecurityServer/xdatabase.h b/SecurityServer/xdatabase.h
new file mode 100644
index 00000000..eb28258b
--- /dev/null
+++ b/SecurityServer/xdatabase.h
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+
+
+//
+// database - database session management
+//
+#ifndef _H_DATABASE
+#define _H_DATABASE
+
+#include "securityserver.h"
+#include "acls.h"
+#include "dbcrypto.h"
+#include <Security/utilities.h>
+#include <Security/handleobject.h>
+#include <Security/cssmdb.h>
+#include <Security/machserver.h>
+#include <time.h>
+#include <string>
+#include <map>
+
+
+class Key;
+class Connection;
+class Process;
+using MachPlusPlus::MachServer;
+
+
+//
+// A Database object represents an Apple CSP/DL open database (DL/DB) object.
+// It maintains its protected semantic state (including keys) and provides controlled
+// access.
+//
+class Database : public HandleObject, public SecurityServerAcl {
+	class Common; friend class Common;
+public:
+	Database(const DLDbIdentifier &id, const DBParameters &params, Process &proc,
+        const AccessCredentials *cred, const AclEntryPrototype *owner);
+	virtual ~Database();
+    
+    Process &process;
+	
+	static const int maxUnlockTryCount = 3;
+
+public:
+    typedef DbBlob::Signature Signature;
+
+    class DbIdentifier {
+    public:
+        DbIdentifier(const DLDbIdentifier &id, Signature sig)
+        : mIdent(id), mSig(sig) { }
+        
+        operator const DLDbIdentifier &() const { return mIdent; }
+        operator const Signature &() const { return mSig; }
+        
+        bool operator < (const DbIdentifier &id) const	// simple lexicographic
+        {
+            if (mIdent < id.mIdent) return true;
+            if (id.mIdent < mIdent) return false;
+            return mSig < id.mSig;
+        }
+        
+    private:
+        DLDbIdentifier mIdent;
+        Signature mSig;
+    };
+
+public:
+	//
+	// A Database::Common is the "common core" of all Database objects that
+	// represent the same client database (on disk, presumably).
+	// NOTE: Common obeys exterior locking protocol: the caller (always Database)
+	// must lock it before operating on its non-const members. In practice,
+	// most Database methods lock down their Common first thing.
+	//
+    class Common : public DatabaseCryptoCore, public MachServer::Timer, public Mutex {
+    public:
+        Common(const DbIdentifier &id);
+        ~Common();
+        
+        bool unlock(DbBlob *blob, const CssmData &passphrase,
+            void **privateAclBlob = NULL);
+        bool unlock(const CssmData &passphrase);
+        void lock(bool holdingCommonLock = false, bool forSleep = false); // versatile lock primitive
+        bool isLocked() const { return mIsLocked; } // lock status
+        void activity();			// reset lock timeout
+        
+        const DbIdentifier &identifier() const {return mIdentifier; }
+        const DLDbIdentifier &dlDbIdent() const { return identifier(); }
+        const char *dbName() const { return dlDbIdent().dbName(); }
+        
+        DbBlob *encode(Database &db);
+        void setupKeys(const AccessCredentials *cred);
+		
+	protected:
+		void action();				// timer queue action to lock keychain
+
+    public:
+        DbIdentifier mIdentifier;	// database external identifier [const]
+		// all following data locked with object lock
+        uint32 sequence;			// change sequence number
+        DBParameters mParams;		// database parameters (arbitrated copy)
+
+        CssmAutoData passphrase;	// passphrase if available, or NULL data
+        
+        uint32 useCount;			// database sessions we belong to
+        uint32 version;				// version stamp for change tracking
+        
+    private:
+        bool mIsLocked;				// database is LOGICALLY locked
+    };
+    
+    const DbIdentifier &identifier() const { return common->identifier(); }
+    const char *dbName() const { return common->dbName(); }
+	
+public:
+	// encoding/decoding databases
+	DbBlob *encode();
+	Database(const DLDbIdentifier &id, const DbBlob *blob, Process &proc,
+        const AccessCredentials *cred);
+    void authenticate(const AccessCredentials *cred);
+    void changePassphrase(const AccessCredentials *cred);
+	
+	// lock/unlock processing
+	void lock();											// unconditional lock
+	void unlock();											// full-feature unlock
+	void unlock(const CssmData &passphrase);				// unlock with passphrase
+	bool decode(const CssmData &passphrase);				// try unlock/don't fail
+	bool isLocked() const { return common->isLocked(); }	// lock status
+    
+    void activity() const { common->activity(); }			// reset timeout clock
+    static void lockAllDatabases(bool forSleep = false);	// lock them all
+	
+	// encoding/decoding keys
+    void decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl);
+	KeyBlob *encodeKey(const CssmKey &key, const CssmData &pubAcl, const CssmData &privAcl);
+
+    bool validBlob() const	{ return mBlob && version == common->version; }
+
+	// manage database parameters
+	void setParameters(const DBParameters &params);
+	void getParameters(DBParameters &params);
+    
+    // ACL state management hooks
+	void instantiateAcl();
+	void noticeAclChange();
+	const Database *relatedDatabase() const; // "self", for SecurityServerAcl's sake
+
+    // debugging
+    IFDUMP(void debugDump(const char *msg));
+
+protected:
+	void makeUnlocked();							// interior version of unlock()
+	void makeUnlocked(const CssmData &passphrase);	// interior version of unlock(CssmData)
+    static void discard(Common *common);
+		
+private:
+    Common *common;					// shared features of all instances of this database [const]
+
+	// all following data is locked by the common lock
+    bool mValidData;				// valid ACL and params (blob decoded)
+        
+    uint32 version;					// version stamp for blob validity
+    DbBlob *mBlob;					// database blob (encoded)
+    
+    AccessCredentials *mCred;		// local access credentials (always valid)
+    
+private:
+    // @@@ Arguably, this should be a member of the Server or Session.
+    // @@@ If we do this, encapsulate it as a DatabaseMap object of sorts.
+	static Mutex commonLock;		// lock for commons map (only)
+    typedef map<DbIdentifier, Common *> CommonMap;
+    static CommonMap commons;		// map of extant database objects
+};
+
+
+#endif //_H_DATABASE
diff --git a/SecurityServer/yarrowMigTypes.h b/SecurityServer/yarrowMigTypes.h
new file mode 100644
index 00000000..6a744753
--- /dev/null
+++ b/SecurityServer/yarrowMigTypes.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+
+//
+// yarrowMigTypes.h - type equivalence declarations for Yarrow's MIG 
+// interface
+//
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+
+// @@@ who forgot that one?
+extern "C" kern_return_t mig_deallocate(vm_address_t addr, vm_size_t size);
+
+namespace Security
+{
+
+typedef void 	*Data;
+
+//
+// The server's bootstrap name 
+//
+#define YARROW_SERVER_NAME	"YarrowServer"
+
+} // end namespace Security
+
+using namespace Security;
diff --git a/cdsa/CVSVersionInfo.txt b/cdsa/CVSVersionInfo.txt
new file mode 100644
index 00000000..b0ee3400
--- /dev/null
+++ b/cdsa/CVSVersionInfo.txt
@@ -0,0 +1,5 @@
+# Created and modified by checkpoint; do not edit
+# $Id: CVSVersionInfo.txt,v 1.1.1.1 2001/05/18 23:13:53 mb Exp $
+# $Name: Security-28 $
+ProjectName: cdsa
+ProjectVersion: 21
diff --git a/cdsa/TODO b/cdsa/TODO
new file mode 100644
index 00000000..16d52c39
--- /dev/null
+++ b/cdsa/TODO
@@ -0,0 +1 @@
+Things TODO in cdsa
diff --git a/cdsa/cdsa.cpp b/cdsa/cdsa.cpp
new file mode 100644
index 00000000..ddf69730
--- /dev/null
+++ b/cdsa/cdsa.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+
+/* Headers. */
+#include <cdsa/cssmconfig.h>
+#include <cdsa/cssmerr.h>
+#include <cdsa/cssmtype.h>
+#include <cdsa/cssmapple.h>
+#include <cdsa/cssmapi.h>
+#include <cdsa/cssmspi.h>
+#include <cdsa/cssm.h>
+#include <cdsa/cssmaci.h>
+#include <cdsa/cssmcli.h>
+#include <cdsa/cssmcspi.h>
+#include <cdsa/cssmdli.h>
+#include <cdsa/cssmkrapi.h>
+#include <cdsa/cssmkrspi.h>
+#include <cdsa/cssmtpi.h>
+#include <cdsa/eisl.h>
+#include <cdsa/emmspi.h>
+#include <cdsa/emmtype.h>
+#include <cdsa/mds.h>
+#include <cdsa/mds_schema.h>
+#include <cdsa/oidsbase.h>
+#include <cdsa/oidscert.h>
+#include <cdsa/oidscrl.h>
+#include <cdsa/x509defs.h>
+#include <cdsa/certextensions.h>
+#include <cdsa/oidsattr.h>
+#include <cdsa/oidsalg.h>
+
+#include <cssm/attachfactory.h>
+#include <cssm/attachment.h>
+#include <cssm/cspattachment.h>
+#include <cssm/cssmcontext.h>
+#include <cssm/cssmint.h>
+#include <cssm/cssmmds.h>
+#include <cssm/manager.h>
+#include <cssm/module.h>
+
+/* Source files. */
+#include <cssm/attachfactory.cpp>
+#include <cssm/attachment.cpp>
+#include <cssm/cspattachment.cpp>
+#include <cssm/cssm.cpp>
+#include <cssm/cssmcontext.cpp>
+#include <cssm/cssmmds.cpp>
+#include <cssm/manager.cpp>
+#include <cssm/module.cpp>
+#include <cssm/oidscert.cpp>
+#include <cssm/oidscrl.cpp>
+#include <cssm/transition.cpp>
+#include <cssm/oidsattr.c>
+#include <cssm/oidsalg.c>
diff --git a/cdsa/cdsa.pbxproj/.cvsignore b/cdsa/cdsa.pbxproj/.cvsignore
new file mode 100644
index 00000000..0857ac37
--- /dev/null
+++ b/cdsa/cdsa.pbxproj/.cvsignore
@@ -0,0 +1 @@
+*.pbxuser
diff --git a/cdsa/cdsa.pbxproj/project.pbxproj b/cdsa/cdsa.pbxproj/project.pbxproj
new file mode 100644
index 00000000..e2b8ea37
--- /dev/null
+++ b/cdsa/cdsa.pbxproj/project.pbxproj
@@ -0,0 +1,4774 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 31;
+	objects = {
+		00DAE77BFEB4BE5E11CD2984 = {
+			isa = PBXFileReference;
+			path = DLDBList.cpp;
+			refType = 4;
+		};
+		00DAE77CFEB4BE5E11CD2984 = {
+			isa = PBXFileReference;
+			path = DLDBList.h;
+			refType = 4;
+		};
+		00DAE77DFEB4BE5E11CD2984 = {
+			fileRef = 00DAE77CFEB4BE5E11CD2984;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		00DAE77EFEB4BE5E11CD2984 = {
+			fileRef = 00DAE77BFEB4BE5E11CD2984;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		00DE4CA2FEBE2E3B11CD296C = {
+			isa = PBXFileReference;
+			path = walkers.cpp;
+			refType = 4;
+		};
+		00DE4CA3FEBE2E3B11CD296C = {
+			isa = PBXFileReference;
+			path = walkers.h;
+			refType = 4;
+		};
+		00DE4CA4FEBE2E3B11CD296C = {
+			fileRef = 00DE4CA3FEBE2E3B11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		00DE4CA5FEBE2E3B11CD296C = {
+			fileRef = 00DE4CA2FEBE2E3B11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		00DE4CA6FEC3407011CD296C = {
+			isa = PBXFileReference;
+			path = cssmwalkers.cpp;
+			refType = 4;
+		};
+		00DE4CA7FEC3407011CD296C = {
+			isa = PBXFileReference;
+			path = cssmwalkers.h;
+			refType = 4;
+		};
+		00DE4CA8FEC3407011CD296C = {
+			fileRef = 00DE4CA7FEC3407011CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		00DE4CA9FEC3407011CD296C = {
+			fileRef = 00DE4CA6FEC3407011CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		00DE4CAAFEC34AB411CD296C = {
+			children = (
+				00DE4CABFEC34AB411CD296C,
+				00DE4CACFEC34AB411CD296C,
+				0C2D421CFE89F09B11CD283A,
+				0C2D421DFE89F09B11CD283A,
+				012E3793FEDC6CAE11CD296C,
+				012E3794FEDC6CAE11CD296C,
+				013A8788FEDD94C911CD296C,
+				013A8789FEDD94C911CD296C,
+				01692099FF9E3C0511CD296C,
+				0169209AFF9E3C0511CD296C,
+				00FD121BFFCB76E511CD296C,
+				00FD121CFFCB76E511CD296C,
+			);
+			isa = PBXGroup;
+			name = "ACL Subjects";
+			refType = 4;
+		};
+		00DE4CABFEC34AB411CD296C = {
+			isa = PBXFileReference;
+			path = acl_any.cpp;
+			refType = 4;
+		};
+		00DE4CACFEC34AB411CD296C = {
+			isa = PBXFileReference;
+			path = acl_any.h;
+			refType = 4;
+		};
+		00DE4CADFEC34AB411CD296C = {
+			fileRef = 00DE4CACFEC34AB411CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		00DE4CAEFEC34AB411CD296C = {
+			fileRef = 00DE4CABFEC34AB411CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		00DE4CAFFEC35F0311CD296C = {
+			isa = PBXFileReference;
+			path = cssmaclpod.cpp;
+			refType = 4;
+		};
+		00DE4CB0FEC35F0311CD296C = {
+			isa = PBXFileReference;
+			path = cssmaclpod.h;
+			refType = 4;
+		};
+		00DE4CB1FEC35F0311CD296C = {
+			fileRef = 00DE4CB0FEC35F0311CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		00DE4CB2FEC35F0311CD296C = {
+			fileRef = 00DE4CAFFEC35F0311CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		00FD121BFFCB76E511CD296C = {
+			isa = PBXFileReference;
+			path = acl_comment.cpp;
+			refType = 4;
+		};
+		00FD121CFFCB76E511CD296C = {
+			isa = PBXFileReference;
+			path = acl_comment.h;
+			refType = 4;
+		};
+		00FD121DFFCB76E511CD296C = {
+			fileRef = 00FD121CFFCB76E511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		00FD121EFFCB76E511CD296C = {
+			fileRef = 00FD121BFFCB76E511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01022B31FF5326C811CD28CA = {
+			isa = PBXFileReference;
+			path = NOTES;
+			refType = 4;
+		};
+		01022B32FF5326C811CD28CA = {
+			fileRef = 01022B31FF5326C811CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		01022B33FF54464F11CD28CA = {
+			children = (
+				0C2D4234FE89F09B11CD283A,
+				0C2D4235FE89F09B11CD283A,
+				0C2D4236FE89F09B11CD283A,
+				0C2D4237FE89F09B11CD283A,
+				0C2D4238FE89F09B11CD283A,
+				0C2D4239FE89F09B11CD283A,
+				0C2D423AFE89F09B11CD283A,
+				0C2D423BFE89F09B11CD283A,
+				0C2D423CFE89F09B11CD283A,
+				0C2D423DFE89F09B11CD283A,
+				01022B34FF54464F11CD28CA,
+				01022B35FF54464F11CD28CA,
+				01022B36FF54464F11CD28CA,
+				01022B37FF54464F11CD28CA,
+				01022B38FF54464F11CD28CA,
+				01022B39FF54464F11CD28CA,
+				01022B3AFF54464F11CD28CA,
+				01022B3BFF54464F11CD28CA,
+				01022B3CFF54464F11CD28CA,
+				01022B3DFF54464F11CD28CA,
+				01022B3EFF54464F11CD28CA,
+				01022B3FFF54464F11CD28CA,
+				01022B40FF54464F11CD28CA,
+			);
+			isa = PBXGroup;
+			name = AppleDatabase;
+			refType = 4;
+		};
+		01022B34FF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = AppleDatabase.cpp;
+			refType = 4;
+		};
+		01022B35FF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = AppleDatabase.h;
+			refType = 4;
+		};
+		01022B36FF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = DbIndex.cpp;
+			refType = 4;
+		};
+		01022B37FF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = DbIndex.h;
+			refType = 4;
+		};
+		01022B38FF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = DbValue.cpp;
+			refType = 4;
+		};
+		01022B39FF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = DbValue.h;
+			refType = 4;
+		};
+		01022B3AFF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = MetaAttribute.cpp;
+			refType = 4;
+		};
+		01022B3BFF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = MetaAttribute.h;
+			refType = 4;
+		};
+		01022B3CFF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = MetaRecord.cpp;
+			refType = 4;
+		};
+		01022B3DFF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = MetaRecord.h;
+			refType = 4;
+		};
+		01022B3EFF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = ReadWriteSection.h;
+			refType = 4;
+		};
+		01022B3FFF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = SelectionPredicate.cpp;
+			refType = 4;
+		};
+		01022B40FF54464F11CD28CA = {
+			isa = PBXFileReference;
+			path = SelectionPredicate.h;
+			refType = 4;
+		};
+		01022B41FF54464F11CD28CA = {
+			fileRef = 01022B35FF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01022B42FF54464F11CD28CA = {
+			fileRef = 01022B37FF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01022B43FF54464F11CD28CA = {
+			fileRef = 01022B39FF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01022B44FF54464F11CD28CA = {
+			fileRef = 01022B3BFF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01022B45FF54464F11CD28CA = {
+			fileRef = 01022B3DFF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01022B46FF54464F11CD28CA = {
+			fileRef = 01022B3EFF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01022B47FF54464F11CD28CA = {
+			fileRef = 01022B40FF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01022B48FF54464F11CD28CA = {
+			fileRef = 01022B34FF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01022B49FF54464F11CD28CA = {
+			fileRef = 01022B36FF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01022B4AFF54464F11CD28CA = {
+			fileRef = 01022B38FF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01022B4BFF54464F11CD28CA = {
+			fileRef = 01022B3AFF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01022B4CFF54464F11CD28CA = {
+			fileRef = 01022B3CFF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01022B4DFF54464F11CD28CA = {
+			fileRef = 01022B3FFF54464F11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01128942FECB751C11CD296C = {
+			children = (
+				01128943FECB751C11CD296C,
+				01128944FECB751C11CD296C,
+				01128947FECB77DB11CD296C,
+				01128948FECB77DB11CD296C,
+				12DB1A67FF094C9E11CD296C,
+				12DB1A68FF094C9E11CD296C,
+				0112894BFECB79BA11CD296C,
+				0112894CFECB79BA11CD296C,
+			);
+			isa = PBXGroup;
+			name = Mach;
+			path = "";
+			refType = 4;
+		};
+		01128943FECB751C11CD296C = {
+			isa = PBXFileReference;
+			path = "mach++.cpp";
+			refType = 4;
+		};
+		01128944FECB751C11CD296C = {
+			isa = PBXFileReference;
+			path = "mach++.h";
+			refType = 4;
+		};
+		01128945FECB751C11CD296C = {
+			fileRef = 01128944FECB751C11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01128946FECB751C11CD296C = {
+			fileRef = 01128943FECB751C11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01128947FECB77DB11CD296C = {
+			isa = PBXFileReference;
+			path = machserver.cpp;
+			refType = 4;
+		};
+		01128948FECB77DB11CD296C = {
+			isa = PBXFileReference;
+			path = machserver.h;
+			refType = 4;
+		};
+		01128949FECB77DB11CD296C = {
+			fileRef = 01128948FECB77DB11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0112894AFECB77DB11CD296C = {
+			fileRef = 01128947FECB77DB11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0112894BFECB79BA11CD296C = {
+			isa = PBXFileReference;
+			path = mach_notify.c;
+			refType = 4;
+		};
+		0112894CFECB79BA11CD296C = {
+			isa = PBXFileReference;
+			path = mach_notify.h;
+			refType = 4;
+		};
+		0112894DFECB79BA11CD296C = {
+			fileRef = 0112894CFECB79BA11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0112894EFECB79BA11CD296C = {
+			fileRef = 0112894BFECB79BA11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0112894FFECB7F4711CD296C = {
+			isa = PBXFileReference;
+			path = cssmcred.cpp;
+			refType = 4;
+		};
+		01128950FECB7F4711CD296C = {
+			isa = PBXFileReference;
+			path = cssmcred.h;
+			refType = 4;
+		};
+		01128951FECB7F4711CD296C = {
+			fileRef = 01128950FECB7F4711CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01128952FECB7F4711CD296C = {
+			fileRef = 0112894FFECB7F4711CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0115DA1BFF13D7E811CD283A = {
+			children = (
+				0115DA1CFF13D7E811CD283A,
+				0115DA1DFF13D7E811CD283A,
+				0115DA1EFF13D7E811CD283A,
+				0115DA1FFF13D7E811CD283A,
+				0115DA20FF13D7E811CD283A,
+				01815976FFEAFFA511CD283A,
+				01815985FFEE820F11CD283A,
+				0181598FFFEE88CD11CD283A,
+				42462E68FFF0254211CD283A,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+		0115DA1CFF13D7E811CD283A = {
+			isa = PBXFrameworkReference;
+			path = cdsa.framework;
+			refType = 3;
+		};
+		0115DA1DFF13D7E811CD283A = {
+			isa = PBXFrameworkReference;
+			path = cdsa_utilities.framework;
+			refType = 3;
+		};
+		0115DA1EFF13D7E811CD283A = {
+			isa = PBXFrameworkReference;
+			path = mds.framework;
+			refType = 3;
+		};
+		0115DA1FFF13D7E811CD283A = {
+			isa = PBXFrameworkReference;
+			path = cdsa_pluginlib.framework;
+			refType = 3;
+		};
+		0115DA20FF13D7E811CD283A = {
+			isa = PBXFrameworkReference;
+			path = cdsa_client.framework;
+			refType = 3;
+		};
+		0115DA21FF13D7E811CD283A = {
+			fileRef = 0115DA1DFF13D7E811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0115DA22FF13D7E811CD283A = {
+			fileRef = 0115DA1DFF13D7E811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0115DA23FF13D7E811CD283A = {
+			fileRef = 0115DA1DFF13D7E811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0115DA24FF13D7E811CD283A = {
+			fileRef = 0115DA1CFF13D7E811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0115DA25FF13D7E811CD283A = {
+			fileRef = 0115DA1DFF13D7E811CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		012E3793FEDC6CAE11CD296C = {
+			isa = PBXFileReference;
+			path = acl_threshold.cpp;
+			refType = 4;
+		};
+		012E3794FEDC6CAE11CD296C = {
+			isa = PBXFileReference;
+			path = acl_threshold.h;
+			refType = 4;
+		};
+		012E3795FEDC6CAE11CD296C = {
+			fileRef = 012E3794FEDC6CAE11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		012E3796FEDC6CAE11CD296C = {
+			fileRef = 012E3793FEDC6CAE11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		013867ADFEAB8F4011CD283A = {
+			fileRef = 41463C2AFE8C141C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		013867AEFEAB8F4011CD283A = {
+			fileRef = 41463C2BFE8C141C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		013867AFFEAB8F4011CD283A = {
+			fileRef = 41463C2CFE8C141C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		013867B0FEAB8F4011CD283A = {
+			fileRef = 41463C2DFE8C141C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		013867B1FEAB8F4011CD283A = {
+			fileRef = 41463C2EFE8C141C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		013867B2FEAB8F4011CD283A = {
+			fileRef = 0DD48EDDFE89FA0911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		013867B3FEAB8F4011CD283A = {
+			fileRef = 0DD48EDEFE89FA0911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		013867B4FEAB8F4011CD283A = {
+			fileRef = 0DD48EDFFE89FA0911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		013867B5FEAB8F4011CD283A = {
+			fileRef = 0DD48EE0FE89FA0911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		013867B6FEAB8F4011CD283A = {
+			fileRef = 0DD48EE1FE89FA0911CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		013A8788FEDD94C911CD296C = {
+			isa = PBXFileReference;
+			path = acl_process.cpp;
+			refType = 4;
+		};
+		013A8789FEDD94C911CD296C = {
+			isa = PBXFileReference;
+			path = acl_process.h;
+			refType = 4;
+		};
+		013A878AFEDD94C911CD296C = {
+			fileRef = 013A8789FEDD94C911CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		013A878BFEDD94C911CD296C = {
+			fileRef = 013A8788FEDD94C911CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		015BB43CFFB749EA11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		015BB43DFFB749EA11CD296C = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+		01692075FF9B76B311CD296C = {
+			isa = PBXFileReference;
+			path = codesigning.cpp;
+			refType = 4;
+		};
+		01692076FF9B76B311CD296C = {
+			isa = PBXFileReference;
+			path = codesigning.h;
+			refType = 4;
+		};
+		01692077FF9B76B311CD296C = {
+			fileRef = 01692076FF9B76B311CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01692078FF9B76B311CD296C = {
+			fileRef = 01692075FF9B76B311CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0169207DFF9BA84C11CD296C = {
+			children = (
+				01692088FF9D296311CD296C,
+				01692089FF9D296311CD296C,
+			);
+			isa = PBXGroup;
+			name = "OSX Code Signing";
+			refType = 4;
+		};
+		01692088FF9D296311CD296C = {
+			isa = PBXFileReference;
+			path = osxsigner.cpp;
+			refType = 4;
+		};
+		01692089FF9D296311CD296C = {
+			isa = PBXFileReference;
+			path = osxsigner.h;
+			refType = 4;
+		};
+		0169208AFF9D296311CD296C = {
+			fileRef = 01692089FF9D296311CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0169208BFF9D296311CD296C = {
+			fileRef = 01692088FF9D296311CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01692099FF9E3C0511CD296C = {
+			isa = PBXFileReference;
+			path = acl_codesigning.cpp;
+			refType = 4;
+		};
+		0169209AFF9E3C0511CD296C = {
+			isa = PBXFileReference;
+			path = acl_codesigning.h;
+			refType = 4;
+		};
+		0169209BFF9E3C0511CD296C = {
+			fileRef = 0169209AFF9E3C0511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0169209CFF9E3C0511CD296C = {
+			fileRef = 01692099FF9E3C0511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		016920A2FF9E86DF11CD296C = {
+			children = (
+				01692075FF9B76B311CD296C,
+				01692076FF9B76B311CD296C,
+				016920A3FF9E872A11CD296C,
+				016920A4FF9E872A11CD296C,
+			);
+			isa = PBXGroup;
+			name = "Code Signing";
+			path = "";
+			refType = 4;
+		};
+		016920A3FF9E872A11CD296C = {
+			isa = PBXFileReference;
+			path = osxsigning.cpp;
+			refType = 4;
+		};
+		016920A4FF9E872A11CD296C = {
+			isa = PBXFileReference;
+			path = osxsigning.h;
+			refType = 4;
+		};
+		016920A5FF9E872A11CD296C = {
+			fileRef = 016920A4FF9E872A11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		016920A6FF9E872A11CD296C = {
+			fileRef = 016920A3FF9E872A11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01815975FFEAFFA511CD283A = {
+			children = (
+				0181597DFFEAFFC711CD283A,
+				0181597FFFEE802311CD283A,
+				01815980FFEE802311CD283A,
+				0181598DFFEE86AE11CD283A,
+			);
+			isa = PBXGroup;
+			name = master;
+			refType = 4;
+		};
+		01815976FFEAFFA511CD283A = {
+			isa = PBXLibraryReference;
+			path = libcdsa_utilities.a;
+			refType = 3;
+		};
+		01815977FFEAFFA511CD283A = {
+			buildPhases = (
+				01815979FFEAFFA511CD283A,
+				0181597AFFEAFFA511CD283A,
+				0181597BFFEAFFA511CD283A,
+				0181597CFFEAFFA511CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/derived_src\"";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O1";
+				OTHER_CFLAGS = "-DSAFER -DLIMITED_SIGNING -DDEBUGDUMP";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libcdsa_utilities.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				01815978FFEAFFA511CD283A,
+			);
+			isa = PBXLibraryTarget;
+			name = libcdsa_utilities.a;
+			productInstallPath = /usr/local/lib;
+			productName = libcdsa_utilities.a;
+			productReference = 01815976FFEAFFA511CD283A;
+			shouldUseHeadermap = 0;
+		};
+		01815978FFEAFFA511CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2D4320FE89F10511CD283A;
+		};
+		01815979FFEAFFA511CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0181597AFFEAFFA511CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0181597EFFEAFFC711CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0181597BFFEAFFA511CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0181597CFFEAFFA511CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0181597DFFEAFFC711CD283A = {
+			isa = PBXFileReference;
+			path = cdsa_utilities.cpp;
+			refType = 4;
+		};
+		0181597EFFEAFFC711CD283A = {
+			fileRef = 0181597DFFEAFFC711CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0181597FFFEE802311CD283A = {
+			isa = PBXFileReference;
+			path = cdsa_client.cpp;
+			refType = 4;
+		};
+		01815980FFEE802311CD283A = {
+			isa = PBXFileReference;
+			path = cdsa_pluginlib.cpp;
+			refType = 4;
+		};
+		01815985FFEE820F11CD283A = {
+			isa = PBXLibraryReference;
+			path = libcdsa.a;
+			refType = 3;
+		};
+		01815986FFEE820F11CD283A = {
+			buildPhases = (
+				01815988FFEE820F11CD283A,
+				01815989FFEE820F11CD283A,
+				0181598AFFEE820F11CD283A,
+				0181598BFFEE820F11CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				EXPORTED_SYMBOLS_FILE = "\"$(SYMROOT)/derived_src/cssmexports.gen\"";
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/derived_src\"";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O1";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libcdsa.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLibraryTarget;
+			name = libcdsa.a;
+			productInstallPath = /usr/local/lib;
+			productName = libcdsa.a;
+			productReference = 01815985FFEE820F11CD283A;
+			shouldUseHeadermap = 0;
+		};
+		01815988FFEE820F11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		01815989FFEE820F11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0181598EFFEE86AE11CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0181598AFFEE820F11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0181598BFFEE820F11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0181598DFFEE86AE11CD283A = {
+			isa = PBXFileReference;
+			path = cdsa.cpp;
+			refType = 4;
+		};
+		0181598EFFEE86AE11CD283A = {
+			fileRef = 0181598DFFEE86AE11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0181598FFFEE88CD11CD283A = {
+			isa = PBXLibraryReference;
+			path = libcdsa_pluginlib.a;
+			refType = 3;
+		};
+		01815990FFEE88CD11CD283A = {
+			buildPhases = (
+				01815991FFEE88CD11CD283A,
+				01815992FFEE88CD11CD283A,
+				01815993FFEE88CD11CD283A,
+				01815994FFEE88CD11CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/include\" \"$(SYMROOT)/derived_src\"";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "-O1";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libcdsa_pluginlib.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLibraryTarget;
+			name = libcdsa_pluginlib.a;
+			productInstallPath = /usr/local/lib;
+			productName = libcdsa_pluginlib.a;
+			productReference = 0181598FFFEE88CD11CD283A;
+			shouldUseHeadermap = 0;
+		};
+		01815991FFEE88CD11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		01815992FFEE88CD11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01815995FFEE898511CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		01815993FFEE88CD11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		01815994FFEE88CD11CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		01815995FFEE898511CD283A = {
+			fileRef = 01815980FFEE802311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01B9A47EFF51D86CD0A17CE7 = {
+			isa = PBXFileReference;
+			path = oidsattr.h;
+			refType = 4;
+		};
+		01B9A47FFF51D86CD0A17CE7 = {
+			fileRef = 01B9A47EFF51D86CD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01B9A480FF51D994D0A17CE7 = {
+			isa = PBXFileReference;
+			path = oidsattr.c;
+			refType = 4;
+		};
+		01B9A481FF51D994D0A17CE7 = {
+			fileRef = 01B9A480FF51D994D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01EEBCFBFEED9C1111CD287F = {
+			isa = PBXFileReference;
+			path = genkey.cpp;
+			refType = 4;
+		};
+		01EEBCFCFEED9C1111CD287F = {
+			isa = PBXFileReference;
+			path = wrapkey.cpp;
+			refType = 4;
+		};
+		01EEBCFDFEED9C1111CD287F = {
+			fileRef = 01EEBCFBFEED9C1111CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01EEBCFEFEED9C1111CD287F = {
+			fileRef = 01EEBCFCFEED9C1111CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		01EEBCFFFEED9C5C11CD287F = {
+			isa = PBXFileReference;
+			path = wrapkey.h;
+			refType = 4;
+		};
+		01EEBD00FEED9C5C11CD287F = {
+			isa = PBXFileReference;
+			path = genkey.h;
+			refType = 4;
+		};
+		01EEBD01FEED9C5C11CD287F = {
+			fileRef = 01EEBCFFFEED9C5C11CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		01EEBD02FEED9C5C11CD287F = {
+			fileRef = 01EEBD00FEED9C5C11CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		020587C0FF4AFF9BD0A17CE7 = {
+			isa = PBXFileReference;
+			path = certextensions.h;
+			refType = 4;
+		};
+		020587C1FF4AFF9BD0A17CE7 = {
+			fileRef = 020587C0FF4AFF9BD0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		02FD68C9FEA50F7511CD283A = {
+			isa = PBXFileReference;
+			path = guids.cpp;
+			refType = 4;
+		};
+		02FD68CAFEA50F7511CD283A = {
+			fileRef = 02FD68C9FEA50F7511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		03FB9036FEC7773411CD296C = {
+			isa = PBXFileReference;
+			path = DLsession.cpp;
+			refType = 4;
+		};
+		03FB9037FEC7773411CD296C = {
+			fileRef = 03FB9036FEC7773411CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		062BE057FEAFD57811CD287F = {
+			isa = PBXFileReference;
+			path = macclient.cpp;
+			refType = 4;
+		};
+		062BE058FEAFD57811CD287F = {
+			isa = PBXFileReference;
+			path = macclient.h;
+			refType = 4;
+		};
+		062BE059FEAFD57811CD287F = {
+			fileRef = 062BE058FEAFD57811CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		062BE05AFEAFD57811CD287F = {
+			fileRef = 062BE057FEAFD57811CD287F;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		088B6D7DFF8E7B2111CD296C = {
+			isa = PBXFileReference;
+			path = tqueue.cpp;
+			refType = 4;
+		};
+		088B6D7EFF8E7B2111CD296C = {
+			isa = PBXFileReference;
+			path = tqueue.h;
+			refType = 4;
+		};
+		088B6D7FFF8E7B2111CD296C = {
+			fileRef = 088B6D7EFF8E7B2111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		088B6D80FF8E7B2111CD296C = {
+			fileRef = 088B6D7DFF8E7B2111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C1F5822FE89EE6611CD283A = {
+			buildStyles = (
+				015BB43CFFB749EA11CD296C,
+				015BB43DFFB749EA11CD296C,
+			);
+			isa = PBXProject;
+			mainGroup = 0C1F5823FE89EE6611CD283A;
+			productRefGroup = 0115DA1BFF13D7E811CD283A;
+			projectDirPath = .;
+			targets = (
+				0C2A94F3FE89EF8611CD283A,
+				0C2D4320FE89F10511CD283A,
+				0C2A94F6FE89EF8611CD283A,
+				0C2A94FEFE89EF8611CD283A,
+				0C2A9506FE89EF8611CD283A,
+				1F54E424FE99514A11CD296C,
+				0C2A950EFE89EF8611CD283A,
+				01815977FFEAFFA511CD283A,
+				01815986FFEE820F11CD283A,
+				42462E69FFF0254211CD283A,
+				01815990FFEE88CD11CD283A,
+			);
+		};
+		0C1F5823FE89EE6611CD283A = {
+			children = (
+				0C2D4324FE89F18F11CD283A,
+				0C2D426FFE89F09B11CD283A,
+				0C2D421AFE89F09B11CD283A,
+				0C2D4287FE89F09B11CD283A,
+				0C2D425EFE89F09B11CD283A,
+				0C2D4254FE89F09B11CD283A,
+				1F54E423FE99511211CD296C,
+				01815975FFEAFFA511CD283A,
+				0DD48EDBFE89F98211CD283A,
+				41463C29FE8C139711CD283A,
+				0CE0F7C5FE89F77411CD283A,
+				0115DA1BFF13D7E811CD283A,
+			);
+			isa = PBXGroup;
+			refType = 4;
+		};
+		0C2A94F3FE89EF8611CD283A = {
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Libraries/CIncludes\"";
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = world;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				0C2D431FFE89F10511CD283A,
+				0C2D4214FE89EFEE11CD283A,
+				0C2D4215FE89EFEE11CD283A,
+				0C2D4217FE89EFEE11CD283A,
+				15B6EA0AFE9AA4C511CD283A,
+			);
+			isa = PBXAggregateTarget;
+			name = world;
+			productInstallPath = /;
+			productName = world;
+			shouldUseHeadermap = 0;
+		};
+		0C2A94F6FE89EF8611CD283A = {
+			buildPhases = (
+				0C2A94F7FE89EF8611CD283A,
+				0C2A94F8FE89EF8611CD283A,
+				0C2A94F9FE89EF8611CD283A,
+				0C2A94FAFE89EF8611CD283A,
+				0C2A94FBFE89EF8611CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(SYMROOT)/derived_src\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "-O1";
+				OTHER_CFLAGS = "-DSAFER -DLIMITED_SIGNING -DDEBUGDUMP";
+				OTHER_LDFLAGS = "\"-lstdc++\" -prebind -seg_addr_table \"$(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table\"";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = cdsa_utilities;
+				SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/cdsa_utilities.order\"";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				0C2D4323FE89F10511CD283A,
+			);
+			isa = PBXFrameworkTarget;
+			name = cdsa_utilities;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = cdsa_utilities;
+			productReference = 0115DA1DFF13D7E811CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>cdsa_utilities</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.cdsa_utilities</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		0C2A94F7FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0C2D429FFE89F09B11CD283A,
+				00DE4CADFEC34AB411CD296C,
+				012E3795FEDC6CAE11CD296C,
+				013A878AFEDD94C911CD296C,
+				0C2D42A0FE89F09B11CD283A,
+				0C2D42A2FE89F09B11CD283A,
+				0C2D42A3FE89F09B11CD283A,
+				0C2D42A5FE89F09B11CD283A,
+				0C2D42A6FE89F09B11CD283A,
+				0C2D42A7FE89F09B11CD283A,
+				688302CEFE940F2A11CD283A,
+				0C2D42A8FE89F09B11CD283A,
+				0C2D42A9FE89F09B11CD283A,
+				0C2D42AAFE89F09B11CD283A,
+				0C2D42ABFE89F09B11CD283A,
+				0C2D42ACFE89F09B11CD283A,
+				0C2D42ADFE89F09B11CD283A,
+				0C2D42AEFE89F09B11CD283A,
+				0C2D42AFFE89F09B11CD283A,
+				0C2D42B0FE89F09B11CD283A,
+				0C2D42B2FE89F09B11CD283A,
+				0C2D42B3FE89F09B11CD283A,
+				0C2D42B4FE89F09B11CD283A,
+				0C2D42B5FE89F09B11CD283A,
+				0C2D42B6FE89F09B11CD283A,
+				0C2D42B7FE89F09B11CD283A,
+				0C2D42B9FE89F09B11CD283A,
+				0C2D42BAFE89F09B11CD283A,
+				0C2D42BBFE89F09B11CD283A,
+				00DE4CA4FEBE2E3B11CD296C,
+				00DE4CA8FEC3407011CD296C,
+				00DE4CB1FEC35F0311CD296C,
+				01128945FECB751C11CD296C,
+				01128949FECB77DB11CD296C,
+				01128951FECB7F4711CD296C,
+				0112894DFECB79BA11CD296C,
+				12DB1A69FF094C9E11CD296C,
+				01022B41FF54464F11CD28CA,
+				01022B42FF54464F11CD28CA,
+				01022B43FF54464F11CD28CA,
+				01022B44FF54464F11CD28CA,
+				01022B45FF54464F11CD28CA,
+				01022B46FF54464F11CD28CA,
+				01022B47FF54464F11CD28CA,
+				17AD015BFF6EA90F11CD296C,
+				17AD015CFF6EA90F11CD296C,
+				17AD015DFF6EA90F11CD296C,
+				088B6D7FFF8E7B2111CD296C,
+				01692077FF9B76B311CD296C,
+				0169209BFF9E3C0511CD296C,
+				016920A5FF9E872A11CD296C,
+				168D1485FFC4593211CD296C,
+				00FD121DFFCB76E511CD296C,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0C2A94F8FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		0C2A94F9FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0C2D42C0FE89F09B11CD283A,
+				0C2D42C1FE89F09B11CD283A,
+				0C2D42C2FE89F09B11CD283A,
+				0C2D42C3FE89F09B11CD283A,
+				0C2D42C4FE89F09B11CD283A,
+				0C2D42C5FE89F09B11CD283A,
+				0C2D42C6FE89F09B11CD283A,
+				634531E8FF097FD011CD283A,
+				0C2D42C7FE89F09B11CD283A,
+				0C2D42C8FE89F09B11CD283A,
+				0C2D42C9FE89F09B11CD283A,
+				0C2D42CAFE89F09B11CD283A,
+				0C2D42CBFE89F09B11CD283A,
+				0C2D42CCFE89F09B11CD283A,
+				0C2D42CDFE89F09B11CD283A,
+				0C2D42CEFE89F09B11CD283A,
+				0C2D42CFFE89F09B11CD283A,
+				0C2D42D0FE89F09B11CD283A,
+				02FD68CAFEA50F7511CD283A,
+				0C2D42D1FE89F09B11CD283A,
+				0C2D42D2FE89F09B11CD283A,
+				0C2D42D3FE89F09B11CD283A,
+				0C2D42D4FE89F09B11CD283A,
+				0C2D42D6FE89F09B11CD283A,
+				0C2D42D7FE89F09B11CD283A,
+				00DE4CA5FEBE2E3B11CD296C,
+				00DE4CA9FEC3407011CD296C,
+				00DE4CAEFEC34AB411CD296C,
+				00DE4CB2FEC35F0311CD296C,
+				01128946FECB751C11CD296C,
+				0112894AFECB77DB11CD296C,
+				0112894EFECB79BA11CD296C,
+				01128952FECB7F4711CD296C,
+				012E3796FEDC6CAE11CD296C,
+				013A878BFEDD94C911CD296C,
+				12DB1A6AFF094C9E11CD296C,
+				01022B48FF54464F11CD28CA,
+				01022B49FF54464F11CD28CA,
+				01022B4AFF54464F11CD28CA,
+				01022B4BFF54464F11CD28CA,
+				01022B4CFF54464F11CD28CA,
+				01022B4DFF54464F11CD28CA,
+				17AD015EFF6EA90F11CD296C,
+				17AD015FFF6EA90F11CD296C,
+				088B6D80FF8E7B2111CD296C,
+				01692078FF9B76B311CD296C,
+				0169209CFF9E3C0511CD296C,
+				016920A6FF9E872A11CD296C,
+				168D1486FFC4593211CD296C,
+				00FD121EFFCB76E511CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0C2A94FAFE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0CE0F7C7FE89F77411CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0C2A94FBFE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0C2A94FEFE89EF8611CD283A = {
+			buildPhases = (
+				0C2A94FFFE89EF8611CD283A,
+				0C2A9500FE89EF8611CD283A,
+				0C2A9501FE89EF8611CD283A,
+				0C2A9502FE89EF8611CD283A,
+				0C2A9503FE89EF8611CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "\"-lstdc++\" -prebind -seg_addr_table \"$(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table\"";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = mds;
+				SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/mds.order\"";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				0C2D4219FE89EFEE11CD283A,
+			);
+			isa = PBXFrameworkTarget;
+			name = mds;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = mds;
+			productReference = 0115DA1EFF13D7E811CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>mds</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.mds</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		0C2A94FFFE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0C2D4316FE89F09B11CD283A,
+				0C2D4317FE89F09B11CD283A,
+				0C2D4318FE89F09B11CD283A,
+				454AF0B6FFAB6EDE11CD28CA,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0C2A9500FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				01022B32FF5326C811CD28CA,
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		0C2A9501FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0C2D431BFE89F09B11CD283A,
+				0C2D431CFE89F09B11CD283A,
+				0C2D431DFE89F09B11CD283A,
+				0C2D431EFE89F09B11CD283A,
+				454AF0B4FFAB6E8311CD28CA,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0C2A9502FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0115DA21FF13D7E811CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0C2A9503FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0C2A9506FE89EF8611CD283A = {
+			buildPhases = (
+				0C2A9507FE89EF8611CD283A,
+				0C2A9508FE89EF8611CD283A,
+				0C2A9509FE89EF8611CD283A,
+				0C2A950AFE89EF8611CD283A,
+				0C2A950BFE89EF8611CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				EXPORTED_SYMBOLS_FILE = "\"$(SYMROOT)/derived_src/cssmexports.gen\"";
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SYMROOT)/derived_src\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "\"-lstdc++\" -prebind -seg_addr_table \"$(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table\"";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = cdsa;
+				SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/cdsa.order\"";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				0C2D4216FE89EFEE11CD283A,
+			);
+			isa = PBXFrameworkTarget;
+			name = cdsa;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = cdsa;
+			productReference = 0115DA1CFF13D7E811CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>cdsa</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.cdsa</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		0C2A9507FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0C2D42D8FE89F09B11CD283A,
+				0C2D42D9FE89F09B11CD283A,
+				0C2D42DAFE89F09B11CD283A,
+				0C2D42DBFE89F09B11CD283A,
+				0C2D42DCFE89F09B11CD283A,
+				0C2D42DDFE89F09B11CD283A,
+				0C2D42DEFE89F09B11CD283A,
+				0C2D42DFFE89F09B11CD283A,
+				0C2D42E0FE89F09B11CD283A,
+				0C2D42E1FE89F09B11CD283A,
+				0C2D42E2FE89F09B11CD283A,
+				0C2D42E3FE89F09B11CD283A,
+				0C2D42E4FE89F09B11CD283A,
+				0C2D42E5FE89F09B11CD283A,
+				0C2D42E6FE89F09B11CD283A,
+				0C2D42E7FE89F09B11CD283A,
+				0C2D42E8FE89F09B11CD283A,
+				0C2D42E9FE89F09B11CD283A,
+				0C2D42EAFE89F09B11CD283A,
+				0C2D42EBFE89F09B11CD283A,
+				0C2D42ECFE89F09B11CD283A,
+				0C2D42EDFE89F09B11CD283A,
+				0C2D42EEFE89F09B11CD283A,
+				020587C1FF4AFF9BD0A17CE7,
+				01B9A47FFF51D86CD0A17CE7,
+				163F7758FF543E27D0A17CE7,
+				0C2D42EFFE89F09B11CD283A,
+				0C2D42F0FE89F09B11CD283A,
+				0C2D42F1FE89F09B11CD283A,
+				0C2D42F2FE89F09B11CD283A,
+				0C2D42F3FE89F09B11CD283A,
+				0C2D42F4FE89F09B11CD283A,
+				0C2D42F5FE89F09B11CD283A,
+				0C2D42F6FE89F09B11CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0C2A9508FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				4EABFBABFE9016E511CD283A,
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		0C2A9509FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0C2D42FBFE89F09B11CD283A,
+				0C2D42FCFE89F09B11CD283A,
+				0C2D42FDFE89F09B11CD283A,
+				0C2D42FEFE89F09B11CD283A,
+				0C2D42FFFE89F09B11CD283A,
+				0C2D4300FE89F09B11CD283A,
+				0C2D4301FE89F09B11CD283A,
+				0C2D4302FE89F09B11CD283A,
+				0C2D4303FE89F09B11CD283A,
+				0C2D4304FE89F09B11CD283A,
+				0C2D4305FE89F09B11CD283A,
+				01B9A481FF51D994D0A17CE7,
+				163F7759FF543E27D0A17CE7,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0C2A950AFE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0115DA22FF13D7E811CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0C2A950BFE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0C2A950EFE89EF8611CD283A = {
+			buildPhases = (
+				0C2A950FFE89EF8611CD283A,
+				0C2A9510FE89EF8611CD283A,
+				0C2A9511FE89EF8611CD283A,
+				0C2A9512FE89EF8611CD283A,
+				0C2A9513FE89EF8611CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "\"$(SYMROOT)/derived_src\"";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "\"-lstdc++\" -prebind -seg_addr_table \"$(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table\"";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = cdsa_pluginlib;
+				SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/cdsa_pluginlib.order\"";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				0C2D4218FE89EFEE11CD283A,
+			);
+			isa = PBXFrameworkTarget;
+			name = cdsa_pluginlib;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = cdsa_pluginlib;
+			productReference = 0115DA1FFF13D7E811CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>cdsa_pluginlib</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.cdsa_pluginlib</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		0C2A950FFE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0C2D4306FE89F09B11CD283A,
+				0C2D4307FE89F09B11CD283A,
+				0C2D4308FE89F09B11CD283A,
+				0C2D4309FE89F09B11CD283A,
+				0C2D430AFE89F09B11CD283A,
+				0DD48EE7FE89FB7511CD283A,
+				0C2D430BFE89F09B11CD283A,
+				0C2D430CFE89F09B11CD283A,
+				0C2D430DFE89F09B11CD283A,
+				013867ADFEAB8F4011CD283A,
+				013867AEFEAB8F4011CD283A,
+				013867AFFEAB8F4011CD283A,
+				013867B0FEAB8F4011CD283A,
+				013867B1FEAB8F4011CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		0C2A9510FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		0C2A9511FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0C2D4312FE89F09B11CD283A,
+				0C2D4313FE89F09B11CD283A,
+				0C2D4314FE89F09B11CD283A,
+				0C2D4315FE89F09B11CD283A,
+				013867B2FEAB8F4011CD283A,
+				013867B3FEAB8F4011CD283A,
+				013867B4FEAB8F4011CD283A,
+				013867B5FEAB8F4011CD283A,
+				013867B6FEAB8F4011CD283A,
+				03FB9037FEC7773411CD296C,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		0C2A9512FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				0115DA23FF13D7E811CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		0C2A9513FE89EF8611CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		0C2D4214FE89EFEE11CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2A94F6FE89EF8611CD283A;
+		};
+		0C2D4215FE89EFEE11CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2A9506FE89EF8611CD283A;
+		};
+		0C2D4216FE89EFEE11CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2A94F6FE89EF8611CD283A;
+		};
+		0C2D4217FE89EFEE11CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2A950EFE89EF8611CD283A;
+		};
+		0C2D4218FE89EFEE11CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2A94F6FE89EF8611CD283A;
+		};
+		0C2D4219FE89EFEE11CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2A94F6FE89EF8611CD283A;
+		};
+		0C2D421AFE89F09B11CD283A = {
+			children = (
+				01022B33FF54464F11CD28CA,
+				0C2D421BFE89F09B11CD283A,
+				0C2D421EFE89F09B11CD283A,
+				0C2D421FFE89F09B11CD283A,
+				0C2D4221FE89F09B11CD283A,
+				0C2D4222FE89F09B11CD283A,
+				0C2D4223FE89F09B11CD283A,
+				0C2D4224FE89F09B11CD283A,
+				00DE4CAFFEC35F0311CD296C,
+				00DE4CB0FEC35F0311CD296C,
+				0C2D4228FE89F09B11CD283A,
+				0C2D4229FE89F09B11CD283A,
+				0C2D4226FE89F09B11CD283A,
+				0C2D4227FE89F09B11CD283A,
+				0C2D422AFE89F09B11CD283A,
+				0C2D422BFE89F09B11CD283A,
+				0112894FFECB7F4711CD296C,
+				01128950FECB7F4711CD296C,
+				634531E7FF097FD011CD283A,
+				688302CDFE940F2A11CD283A,
+				0C2D422CFE89F09B11CD283A,
+				0C2D422DFE89F09B11CD283A,
+				0C2D422EFE89F09B11CD283A,
+				0C2D422FFE89F09B11CD283A,
+				0C2D4230FE89F09B11CD283A,
+				0C2D4231FE89F09B11CD283A,
+				0C2D4232FE89F09B11CD283A,
+				0C2D4233FE89F09B11CD283A,
+				00DE4CA6FEC3407011CD296C,
+				00DE4CA7FEC3407011CD296C,
+				168D1483FFC4593111CD296C,
+				168D1484FFC4593111CD296C,
+				17AD0156FF6EA90F11CD296C,
+				17AD0157FF6EA90F11CD296C,
+				17AD0158FF6EA90F11CD296C,
+				0C2D423FFE89F09B11CD283A,
+				0C2D4240FE89F09B11CD283A,
+				0C2D4241FE89F09B11CD283A,
+				0C2D4242FE89F09B11CD283A,
+				02FD68C9FEA50F7511CD283A,
+				0C2D4243FE89F09B11CD283A,
+				0C2D4244FE89F09B11CD283A,
+				17AD0159FF6EA90F11CD296C,
+				17AD015AFF6EA90F11CD296C,
+				0C2D4245FE89F09B11CD283A,
+				0C2D4246FE89F09B11CD283A,
+				0C2D4247FE89F09B11CD283A,
+				0C2D4248FE89F09B11CD283A,
+				0C2D4249FE89F09B11CD283A,
+				0C2D424AFE89F09B11CD283A,
+				0C2D424BFE89F09B11CD283A,
+				0C2D424CFE89F09B11CD283A,
+				0C2D424DFE89F09B11CD283A,
+				0C2D424EFE89F09B11CD283A,
+				0C2D424FFE89F09B11CD283A,
+				0C2D4250FE89F09B11CD283A,
+				088B6D7DFF8E7B2111CD296C,
+				088B6D7EFF8E7B2111CD296C,
+				0C2D4251FE89F09B11CD283A,
+				0C2D4252FE89F09B11CD283A,
+				0C2D4253FE89F09B11CD283A,
+				00DE4CA2FEBE2E3B11CD296C,
+				00DE4CA3FEBE2E3B11CD296C,
+				016920A2FF9E86DF11CD296C,
+				00DE4CAAFEC34AB411CD296C,
+				01128942FECB751C11CD296C,
+			);
+			isa = PBXGroup;
+			path = cdsa_utilities;
+			refType = 4;
+		};
+		0C2D421BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = .cvsignore;
+			refType = 4;
+		};
+		0C2D421CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = acl_password.cpp;
+			refType = 4;
+		};
+		0C2D421DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = acl_password.h;
+			refType = 4;
+		};
+		0C2D421EFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = AtomicFile.cpp;
+			refType = 4;
+		};
+		0C2D421FFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = AtomicFile.h;
+			refType = 4;
+		};
+		0C2D4221FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = callback.cpp;
+			refType = 4;
+		};
+		0C2D4222FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = callback.h;
+			refType = 4;
+		};
+		0C2D4223FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = context.cpp;
+			refType = 4;
+		};
+		0C2D4224FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = context.h;
+			refType = 4;
+		};
+		0C2D4226FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssm_adt_utils.cpp;
+			refType = 4;
+		};
+		0C2D4227FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssm_adt_utils.h;
+			refType = 4;
+		};
+		0C2D4228FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmacl.cpp;
+			refType = 4;
+		};
+		0C2D4229FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmacl.h;
+			refType = 4;
+		};
+		0C2D422AFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmalloc.cpp;
+			refType = 4;
+		};
+		0C2D422BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmalloc.h;
+			refType = 4;
+		};
+		0C2D422CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdates.cpp;
+			refType = 4;
+		};
+		0C2D422DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdates.h;
+			refType = 4;
+		};
+		0C2D422EFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdb.cpp;
+			refType = 4;
+		};
+		0C2D422FFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdb.h;
+			refType = 4;
+		};
+		0C2D4230FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmerrno.cpp;
+			refType = 4;
+		};
+		0C2D4231FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmerrno.h;
+			refType = 4;
+		};
+		0C2D4232FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmlist.cpp;
+			refType = 4;
+		};
+		0C2D4233FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmlist.h;
+			refType = 4;
+		};
+		0C2D4234FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = Database.cpp;
+			refType = 4;
+		};
+		0C2D4235FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = Database.h;
+			refType = 4;
+		};
+		0C2D4236FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DatabaseSession.cpp;
+			refType = 4;
+		};
+		0C2D4237FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DatabaseSession.h;
+			refType = 4;
+		};
+		0C2D4238FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DbContext.cpp;
+			refType = 4;
+		};
+		0C2D4239FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DbContext.h;
+			refType = 4;
+		};
+		0C2D423AFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DbName.cpp;
+			refType = 4;
+		};
+		0C2D423BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DbName.h;
+			refType = 4;
+		};
+		0C2D423CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DbQuery.cpp;
+			refType = 4;
+		};
+		0C2D423DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DbQuery.h;
+			refType = 4;
+		};
+		0C2D423EFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = DLsession.h;
+			refType = 4;
+		};
+		0C2D423FFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = generator.mk;
+			refType = 4;
+		};
+		0C2D4240FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = generator.pl;
+			refType = 4;
+		};
+		0C2D4241FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = globalizer.cpp;
+			refType = 4;
+		};
+		0C2D4242FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = globalizer.h;
+			refType = 4;
+		};
+		0C2D4243FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = handleobject.cpp;
+			refType = 4;
+		};
+		0C2D4244FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = handleobject.h;
+			refType = 4;
+		};
+		0C2D4245FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = memutils.h;
+			refType = 4;
+		};
+		0C2D4246FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = modloader.cpp;
+			refType = 4;
+		};
+		0C2D4247FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = modloader.h;
+			refType = 4;
+		};
+		0C2D4248FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = modloader9.cpp;
+			refType = 4;
+		};
+		0C2D4249FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = NOTES;
+			refType = 4;
+		};
+		0C2D424AFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = os9utils.cpp;
+			refType = 4;
+		};
+		0C2D424BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = os9utils.h;
+			refType = 4;
+		};
+		0C2D424CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = refcount.h;
+			refType = 4;
+		};
+		0C2D424DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = SampleGroup.cpp;
+			refType = 4;
+		};
+		0C2D424EFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = SampleGroup.h;
+			refType = 4;
+		};
+		0C2D424FFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = threading.cpp;
+			refType = 4;
+		};
+		0C2D4250FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = threading.h;
+			refType = 4;
+		};
+		0C2D4251FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = utilities.cpp;
+			refType = 4;
+		};
+		0C2D4252FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = utilities.h;
+			refType = 4;
+		};
+		0C2D4253FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = utility_config.h;
+			refType = 4;
+		};
+		0C2D4254FE89F09B11CD283A = {
+			children = (
+				0C2D4255FE89F09B11CD283A,
+				0C2D4256FE89F09B11CD283A,
+				0C2D4257FE89F09B11CD283A,
+				0C2D4258FE89F09B11CD283A,
+				0C2D4259FE89F09B11CD283A,
+				0C2D425AFE89F09B11CD283A,
+				0C2D425BFE89F09B11CD283A,
+				0C2D425CFE89F09B11CD283A,
+				0C2D425DFE89F09B11CD283A,
+				01022B31FF5326C811CD28CA,
+				454AF0B3FFAB6E8311CD28CA,
+				454AF0B5FFAB6EDE11CD28CA,
+			);
+			isa = PBXGroup;
+			path = mds;
+			refType = 2;
+		};
+		0C2D4255FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = .cvsignore;
+			refType = 4;
+		};
+		0C2D4256FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = mds.mcp;
+			refType = 4;
+		};
+		0C2D4257FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = mdsapi.cpp;
+			refType = 4;
+		};
+		0C2D4258FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = MDSDatabase.cpp;
+			refType = 4;
+		};
+		0C2D4259FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = MDSDatabase.h;
+			refType = 4;
+		};
+		0C2D425AFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = MDSModule.cpp;
+			refType = 4;
+		};
+		0C2D425BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = MDSModule.h;
+			refType = 4;
+		};
+		0C2D425CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = MDSSession.cpp;
+			refType = 4;
+		};
+		0C2D425DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = MDSSession.h;
+			refType = 4;
+		};
+		0C2D425EFE89F09B11CD283A = {
+			children = (
+				0C2D425FFE89F09B11CD283A,
+				0C2D4260FE89F09B11CD283A,
+				0C2D4261FE89F09B11CD283A,
+				0C2D4262FE89F09B11CD283A,
+				0C2D4263FE89F09B11CD283A,
+				0C2D4264FE89F09B11CD283A,
+				0C2D4265FE89F09B11CD283A,
+				0C2D4266FE89F09B11CD283A,
+				0C2D4267FE89F09B11CD283A,
+				03FB9036FEC7773411CD296C,
+				0C2D423EFE89F09B11CD283A,
+				0C2D4268FE89F09B11CD283A,
+				0C2D4269FE89F09B11CD283A,
+				0C2D426AFE89F09B11CD283A,
+				0C2D426BFE89F09B11CD283A,
+				0C2D426CFE89F09B11CD283A,
+				0C2D426DFE89F09B11CD283A,
+				0C2D426EFE89F09B11CD283A,
+			);
+			isa = PBXGroup;
+			path = cdsa_pluginlib;
+			refType = 2;
+		};
+		0C2D425FFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = .cvsignore;
+			refType = 4;
+		};
+		0C2D4260FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = ACsession.h;
+			refType = 4;
+		};
+		0C2D4261FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = "c++plugin.h";
+			refType = 4;
+		};
+		0C2D4262FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = CLsession.h;
+			refType = 4;
+		};
+		0C2D4263FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = CSPsession.cpp;
+			refType = 4;
+		};
+		0C2D4264FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = CSPsession.h;
+			refType = 4;
+		};
+		0C2D4265FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = csputilities.cpp;
+			refType = 4;
+		};
+		0C2D4266FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmplugin.cpp;
+			refType = 4;
+		};
+		0C2D4267FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmplugin.h;
+			refType = 4;
+		};
+		0C2D4268FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = generator.cfg;
+			refType = 4;
+		};
+		0C2D4269FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = generator.mk;
+			refType = 4;
+		};
+		0C2D426AFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = generator.pl;
+			refType = 4;
+		};
+		0C2D426BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = pluginsession.cpp;
+			refType = 4;
+		};
+		0C2D426CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = pluginsession.h;
+			refType = 4;
+		};
+		0C2D426DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = pluginspi.h;
+			refType = 4;
+		};
+		0C2D426EFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = TPsession.h;
+			refType = 4;
+		};
+		0C2D426FFE89F09B11CD283A = {
+			children = (
+				020587C0FF4AFF9BD0A17CE7,
+				0C2D4270FE89F09B11CD283A,
+				0C2D4271FE89F09B11CD283A,
+				0C2D4272FE89F09B11CD283A,
+				0C2D4273FE89F09B11CD283A,
+				0C2D4274FE89F09B11CD283A,
+				0C2D4275FE89F09B11CD283A,
+				0C2D4276FE89F09B11CD283A,
+				0C2D4277FE89F09B11CD283A,
+				0C2D4278FE89F09B11CD283A,
+				0C2D4279FE89F09B11CD283A,
+				0C2D427AFE89F09B11CD283A,
+				0C2D427BFE89F09B11CD283A,
+				0C2D427CFE89F09B11CD283A,
+				0C2D427DFE89F09B11CD283A,
+				0C2D427EFE89F09B11CD283A,
+				0C2D427FFE89F09B11CD283A,
+				0C2D4280FE89F09B11CD283A,
+				0C2D4281FE89F09B11CD283A,
+				0C2D4282FE89F09B11CD283A,
+				163F7756FF543E27D0A17CE7,
+				01B9A47EFF51D86CD0A17CE7,
+				0C2D4283FE89F09B11CD283A,
+				0C2D4284FE89F09B11CD283A,
+				0C2D4285FE89F09B11CD283A,
+				0C2D4286FE89F09B11CD283A,
+			);
+			isa = PBXGroup;
+			path = cdsa;
+			refType = 2;
+		};
+		0C2D4270FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssm.h;
+			refType = 4;
+		};
+		0C2D4271FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmaci.h;
+			refType = 4;
+		};
+		0C2D4272FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmapi.h;
+			refType = 4;
+		};
+		0C2D4273FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmapple.h;
+			refType = 4;
+		};
+		0C2D4274FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcli.h;
+			refType = 4;
+		};
+		0C2D4275FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmconfig.h;
+			refType = 4;
+		};
+		0C2D4276FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcspi.h;
+			refType = 4;
+		};
+		0C2D4277FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdli.h;
+			refType = 4;
+		};
+		0C2D4278FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmerr.h;
+			refType = 4;
+		};
+		0C2D4279FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmkrapi.h;
+			refType = 4;
+		};
+		0C2D427AFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmkrspi.h;
+			refType = 4;
+		};
+		0C2D427BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmspi.h;
+			refType = 4;
+		};
+		0C2D427CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmtpi.h;
+			refType = 4;
+		};
+		0C2D427DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmtype.h;
+			refType = 4;
+		};
+		0C2D427EFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = eisl.h;
+			refType = 4;
+		};
+		0C2D427FFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = emmspi.h;
+			refType = 4;
+		};
+		0C2D4280FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = emmtype.h;
+			refType = 4;
+		};
+		0C2D4281FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = mds.h;
+			refType = 4;
+		};
+		0C2D4282FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = mds_schema.h;
+			refType = 4;
+		};
+		0C2D4283FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = oidsbase.h;
+			refType = 4;
+		};
+		0C2D4284FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = oidscert.h;
+			refType = 4;
+		};
+		0C2D4285FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = oidscrl.h;
+			refType = 4;
+		};
+		0C2D4286FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = x509defs.h;
+			refType = 4;
+		};
+		0C2D4287FE89F09B11CD283A = {
+			children = (
+				4EABFBAAFE9016E511CD283A,
+				0C2D4288FE89F09B11CD283A,
+				0C2D4289FE89F09B11CD283A,
+				0C2D428AFE89F09B11CD283A,
+				0C2D428BFE89F09B11CD283A,
+				0C2D428CFE89F09B11CD283A,
+				0C2D428DFE89F09B11CD283A,
+				0C2D428EFE89F09B11CD283A,
+				0C2D428FFE89F09B11CD283A,
+				0C2D4290FE89F09B11CD283A,
+				0C2D4291FE89F09B11CD283A,
+				0C2D4292FE89F09B11CD283A,
+				0C2D4293FE89F09B11CD283A,
+				0C2D4294FE89F09B11CD283A,
+				0C2D4295FE89F09B11CD283A,
+				0C2D4296FE89F09B11CD283A,
+				0C2D4297FE89F09B11CD283A,
+				0C2D4298FE89F09B11CD283A,
+				0C2D4299FE89F09B11CD283A,
+				0C2D429AFE89F09B11CD283A,
+				0C2D429BFE89F09B11CD283A,
+				163F7757FF543E27D0A17CE7,
+				01B9A480FF51D994D0A17CE7,
+				0C2D429CFE89F09B11CD283A,
+				0C2D429DFE89F09B11CD283A,
+				0C2D429EFE89F09B11CD283A,
+			);
+			isa = PBXGroup;
+			path = cssm;
+			refType = 4;
+		};
+		0C2D4288FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = .cvsignore;
+			refType = 4;
+		};
+		0C2D4289FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = attachfactory.cpp;
+			refType = 4;
+		};
+		0C2D428AFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = attachfactory.h;
+			refType = 4;
+		};
+		0C2D428BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = attachment.cpp;
+			refType = 4;
+		};
+		0C2D428CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = attachment.h;
+			refType = 4;
+		};
+		0C2D428DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cspattachment.cpp;
+			refType = 4;
+		};
+		0C2D428EFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cspattachment.h;
+			refType = 4;
+		};
+		0C2D428FFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssm.cpp;
+			refType = 4;
+		};
+		0C2D4290FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcontext.cpp;
+			refType = 4;
+		};
+		0C2D4291FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmcontext.h;
+			refType = 4;
+		};
+		0C2D4292FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmint.h;
+			refType = 4;
+		};
+		0C2D4293FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmmds.cpp;
+			refType = 4;
+		};
+		0C2D4294FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = cssmmds.h;
+			refType = 4;
+		};
+		0C2D4295FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = generator.cfg;
+			refType = 4;
+		};
+		0C2D4296FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = generator.mk;
+			refType = 4;
+		};
+		0C2D4297FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = generator.pl;
+			refType = 4;
+		};
+		0C2D4298FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = manager.cpp;
+			refType = 4;
+		};
+		0C2D4299FE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = manager.h;
+			refType = 4;
+		};
+		0C2D429AFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = module.cpp;
+			refType = 4;
+		};
+		0C2D429BFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = module.h;
+			refType = 4;
+		};
+		0C2D429CFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = oidscert.cpp;
+			refType = 4;
+		};
+		0C2D429DFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = oidscrl.cpp;
+			refType = 4;
+		};
+		0C2D429EFE89F09B11CD283A = {
+			isa = PBXFileReference;
+			path = transition.cpp;
+			refType = 4;
+		};
+		0C2D429FFE89F09B11CD283A = {
+			fileRef = 0C2D421DFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42A0FE89F09B11CD283A = {
+			fileRef = 0C2D421FFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42A2FE89F09B11CD283A = {
+			fileRef = 0C2D4222FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42A3FE89F09B11CD283A = {
+			fileRef = 0C2D4224FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42A5FE89F09B11CD283A = {
+			fileRef = 0C2D4227FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42A6FE89F09B11CD283A = {
+			fileRef = 0C2D4229FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42A7FE89F09B11CD283A = {
+			fileRef = 0C2D422BFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42A8FE89F09B11CD283A = {
+			fileRef = 0C2D422DFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42A9FE89F09B11CD283A = {
+			fileRef = 0C2D422FFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42AAFE89F09B11CD283A = {
+			fileRef = 0C2D4231FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42ABFE89F09B11CD283A = {
+			fileRef = 0C2D4233FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42ACFE89F09B11CD283A = {
+			fileRef = 0C2D4235FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42ADFE89F09B11CD283A = {
+			fileRef = 0C2D4237FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42AEFE89F09B11CD283A = {
+			fileRef = 0C2D4239FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42AFFE89F09B11CD283A = {
+			fileRef = 0C2D423BFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42B0FE89F09B11CD283A = {
+			fileRef = 0C2D423DFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42B2FE89F09B11CD283A = {
+			fileRef = 0C2D4242FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42B3FE89F09B11CD283A = {
+			fileRef = 0C2D4244FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42B4FE89F09B11CD283A = {
+			fileRef = 0C2D4245FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42B5FE89F09B11CD283A = {
+			fileRef = 0C2D4247FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42B6FE89F09B11CD283A = {
+			fileRef = 0C2D424BFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42B7FE89F09B11CD283A = {
+			fileRef = 0C2D424CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42B9FE89F09B11CD283A = {
+			fileRef = 0C2D4250FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42BAFE89F09B11CD283A = {
+			fileRef = 0C2D4252FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42BBFE89F09B11CD283A = {
+			fileRef = 0C2D4253FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42C0FE89F09B11CD283A = {
+			fileRef = 0C2D421CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C1FE89F09B11CD283A = {
+			fileRef = 0C2D421EFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C2FE89F09B11CD283A = {
+			fileRef = 0C2D4221FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C3FE89F09B11CD283A = {
+			fileRef = 0C2D4223FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C4FE89F09B11CD283A = {
+			fileRef = 0C2D4226FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C5FE89F09B11CD283A = {
+			fileRef = 0C2D4228FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C6FE89F09B11CD283A = {
+			fileRef = 0C2D422AFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C7FE89F09B11CD283A = {
+			fileRef = 0C2D422CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C8FE89F09B11CD283A = {
+			fileRef = 0C2D422EFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42C9FE89F09B11CD283A = {
+			fileRef = 0C2D4230FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42CAFE89F09B11CD283A = {
+			fileRef = 0C2D4232FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42CBFE89F09B11CD283A = {
+			fileRef = 0C2D4234FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42CCFE89F09B11CD283A = {
+			fileRef = 0C2D4236FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42CDFE89F09B11CD283A = {
+			fileRef = 0C2D4238FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42CEFE89F09B11CD283A = {
+			fileRef = 0C2D423AFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42CFFE89F09B11CD283A = {
+			fileRef = 0C2D423CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42D0FE89F09B11CD283A = {
+			fileRef = 0C2D4241FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42D1FE89F09B11CD283A = {
+			fileRef = 0C2D4243FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42D2FE89F09B11CD283A = {
+			fileRef = 0C2D4246FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42D3FE89F09B11CD283A = {
+			fileRef = 0C2D4248FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42D4FE89F09B11CD283A = {
+			fileRef = 0C2D424AFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42D6FE89F09B11CD283A = {
+			fileRef = 0C2D424FFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42D7FE89F09B11CD283A = {
+			fileRef = 0C2D4251FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42D8FE89F09B11CD283A = {
+			fileRef = 0C2D4270FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42D9FE89F09B11CD283A = {
+			fileRef = 0C2D4271FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42DAFE89F09B11CD283A = {
+			fileRef = 0C2D4272FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42DBFE89F09B11CD283A = {
+			fileRef = 0C2D4273FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42DCFE89F09B11CD283A = {
+			fileRef = 0C2D4274FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42DDFE89F09B11CD283A = {
+			fileRef = 0C2D4275FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42DEFE89F09B11CD283A = {
+			fileRef = 0C2D4276FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42DFFE89F09B11CD283A = {
+			fileRef = 0C2D4277FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E0FE89F09B11CD283A = {
+			fileRef = 0C2D4278FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E1FE89F09B11CD283A = {
+			fileRef = 0C2D4279FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E2FE89F09B11CD283A = {
+			fileRef = 0C2D427AFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E3FE89F09B11CD283A = {
+			fileRef = 0C2D427BFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E4FE89F09B11CD283A = {
+			fileRef = 0C2D427CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E5FE89F09B11CD283A = {
+			fileRef = 0C2D427DFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E6FE89F09B11CD283A = {
+			fileRef = 0C2D427EFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E7FE89F09B11CD283A = {
+			fileRef = 0C2D427FFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E8FE89F09B11CD283A = {
+			fileRef = 0C2D4280FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42E9FE89F09B11CD283A = {
+			fileRef = 0C2D4281FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42EAFE89F09B11CD283A = {
+			fileRef = 0C2D4282FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42EBFE89F09B11CD283A = {
+			fileRef = 0C2D4283FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42ECFE89F09B11CD283A = {
+			fileRef = 0C2D4284FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42EDFE89F09B11CD283A = {
+			fileRef = 0C2D4285FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42EEFE89F09B11CD283A = {
+			fileRef = 0C2D4286FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D42EFFE89F09B11CD283A = {
+			fileRef = 0C2D428AFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0C2D42F0FE89F09B11CD283A = {
+			fileRef = 0C2D428CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0C2D42F1FE89F09B11CD283A = {
+			fileRef = 0C2D428EFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0C2D42F2FE89F09B11CD283A = {
+			fileRef = 0C2D4291FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0C2D42F3FE89F09B11CD283A = {
+			fileRef = 0C2D4292FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0C2D42F4FE89F09B11CD283A = {
+			fileRef = 0C2D4294FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0C2D42F5FE89F09B11CD283A = {
+			fileRef = 0C2D4299FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0C2D42F6FE89F09B11CD283A = {
+			fileRef = 0C2D429BFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		0C2D42FBFE89F09B11CD283A = {
+			fileRef = 0C2D4289FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42FCFE89F09B11CD283A = {
+			fileRef = 0C2D428BFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42FDFE89F09B11CD283A = {
+			fileRef = 0C2D428DFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42FEFE89F09B11CD283A = {
+			fileRef = 0C2D428FFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D42FFFE89F09B11CD283A = {
+			fileRef = 0C2D4290FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4300FE89F09B11CD283A = {
+			fileRef = 0C2D4293FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4301FE89F09B11CD283A = {
+			fileRef = 0C2D4298FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4302FE89F09B11CD283A = {
+			fileRef = 0C2D429AFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4303FE89F09B11CD283A = {
+			fileRef = 0C2D429CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4304FE89F09B11CD283A = {
+			fileRef = 0C2D429DFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4305FE89F09B11CD283A = {
+			fileRef = 0C2D429EFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4306FE89F09B11CD283A = {
+			fileRef = 0C2D4260FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D4307FE89F09B11CD283A = {
+			fileRef = 0C2D4261FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D4308FE89F09B11CD283A = {
+			fileRef = 0C2D4262FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D4309FE89F09B11CD283A = {
+			fileRef = 0C2D4264FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D430AFE89F09B11CD283A = {
+			fileRef = 0C2D4267FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D430BFE89F09B11CD283A = {
+			fileRef = 0C2D426CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D430CFE89F09B11CD283A = {
+			fileRef = 0C2D426DFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D430DFE89F09B11CD283A = {
+			fileRef = 0C2D426EFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0C2D4312FE89F09B11CD283A = {
+			fileRef = 0C2D4263FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4313FE89F09B11CD283A = {
+			fileRef = 0C2D4265FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4314FE89F09B11CD283A = {
+			fileRef = 0C2D4266FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4315FE89F09B11CD283A = {
+			fileRef = 0C2D426BFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D4316FE89F09B11CD283A = {
+			fileRef = 0C2D4259FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0C2D4317FE89F09B11CD283A = {
+			fileRef = 0C2D425BFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0C2D4318FE89F09B11CD283A = {
+			fileRef = 0C2D425DFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0C2D431BFE89F09B11CD283A = {
+			fileRef = 0C2D4257FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D431CFE89F09B11CD283A = {
+			fileRef = 0C2D4258FE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D431DFE89F09B11CD283A = {
+			fileRef = 0C2D425AFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D431EFE89F09B11CD283A = {
+			fileRef = 0C2D425CFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0C2D431FFE89F10511CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2D4320FE89F10511CD283A;
+		};
+		0C2D4320FE89F10511CD283A = {
+			buildArgumentsString = "-f generator.mk $ACTION \"SRCROOT=$SRCROOT\" \"SYMROOT=$SYMROOT\"";
+			buildPhases = (
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "";
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = generate;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "";
+			};
+			buildToolPath = /usr/bin/gnumake;
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLegacyTarget;
+			name = generate;
+			productInstallPath = /;
+			productName = generate;
+			settingsToExpand = 6;
+			settingsToPassInEnvironment = 1;
+			settingsToPassOnCommandLine = 280;
+			shouldUseHeadermap = 0;
+		};
+		0C2D4323FE89F10511CD283A = {
+			isa = PBXTargetDependency;
+			target = 0C2D4320FE89F10511CD283A;
+		};
+		0C2D4324FE89F18F11CD283A = {
+			isa = PBXFileReference;
+			path = generator.mk;
+			refType = 2;
+		};
+		0CE0F7C5FE89F77411CD283A = {
+			children = (
+				0CE0F7C6FE89F77411CD283A,
+			);
+			isa = PBXGroup;
+			name = Frameworks;
+			refType = 4;
+		};
+		0CE0F7C6FE89F77411CD283A = {
+			isa = PBXFrameworkReference;
+			name = CoreFoundation.framework;
+			path = /System/Library/Frameworks/CoreFoundation.framework;
+			refType = 0;
+		};
+		0CE0F7C7FE89F77411CD283A = {
+			fileRef = 0CE0F7C6FE89F77411CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		0D80A0A1FEA5508C11CD283A = {
+			isa = PBXFileReference;
+			path = cryptoclient.cpp;
+			refType = 4;
+		};
+		0D80A0A2FEA5508C11CD283A = {
+			isa = PBXFileReference;
+			path = cryptoclient.h;
+			refType = 4;
+		};
+		0D80A0A3FEA5508C11CD283A = {
+			isa = PBXFileReference;
+			path = keyclient.cpp;
+			refType = 4;
+		};
+		0D80A0A4FEA5508C11CD283A = {
+			isa = PBXFileReference;
+			path = keyclient.h;
+			refType = 4;
+		};
+		0D80A0A5FEA5508C11CD283A = {
+			fileRef = 0D80A0A2FEA5508C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0D80A0A6FEA5508C11CD283A = {
+			fileRef = 0D80A0A4FEA5508C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0D80A0A7FEA5508C11CD283A = {
+			fileRef = 0D80A0A1FEA5508C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0D80A0A8FEA5508C11CD283A = {
+			fileRef = 0D80A0A3FEA5508C11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0DD48EDBFE89F98211CD283A = {
+			children = (
+				0DD48EDDFE89FA0911CD283A,
+				0DD48EDEFE89FA0911CD283A,
+				0DD48EDFFE89FA0911CD283A,
+				0DD48EE0FE89FA0911CD283A,
+				0DD48EE1FE89FA0911CD283A,
+				0DD48EEAFE89FD5111CD283A,
+				0DD48EEBFE89FD5111CD283A,
+				0DD48EECFE89FD5111CD283A,
+				0DD48EEDFE89FD5111CD283A,
+			);
+			isa = PBXGroup;
+			path = derived_src;
+			refType = 3;
+		};
+		0DD48EDDFE89FA0911CD283A = {
+			isa = PBXFileReference;
+			path = ACabstractsession.cpp;
+			refType = 4;
+		};
+		0DD48EDEFE89FA0911CD283A = {
+			isa = PBXFileReference;
+			path = CLabstractsession.cpp;
+			refType = 4;
+		};
+		0DD48EDFFE89FA0911CD283A = {
+			isa = PBXFileReference;
+			path = CSPabstractsession.cpp;
+			refType = 4;
+		};
+		0DD48EE0FE89FA0911CD283A = {
+			isa = PBXFileReference;
+			path = DLabstractsession.cpp;
+			refType = 4;
+		};
+		0DD48EE1FE89FA0911CD283A = {
+			isa = PBXFileReference;
+			path = TPabstractsession.cpp;
+			refType = 4;
+		};
+		0DD48EE7FE89FB7511CD283A = {
+			fileRef = 0C2D423EFE89F09B11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0DD48EEAFE89FD5111CD283A = {
+			isa = PBXFileReference;
+			path = errorcodes.gen;
+			refType = 4;
+		};
+		0DD48EEBFE89FD5111CD283A = {
+			isa = PBXFileReference;
+			path = funcnames.gen;
+			refType = 4;
+		};
+		0DD48EECFE89FD5111CD283A = {
+			isa = PBXFileReference;
+			path = generator.rpt;
+			refType = 4;
+		};
+		0DD48EEDFE89FD5111CD283A = {
+			isa = PBXFileReference;
+			path = transition.gen;
+			refType = 4;
+		};
+		0ECA317BFEB7611311CD283A = {
+			isa = PBXFileReference;
+			path = securestorage.cpp;
+			refType = 4;
+		};
+		0ECA317CFEB7611311CD283A = {
+			isa = PBXFileReference;
+			path = securestorage.h;
+			refType = 4;
+		};
+		0ECA317DFEB7611311CD283A = {
+			fileRef = 0ECA317CFEB7611311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0ECA317EFEB7611311CD283A = {
+			fileRef = 0ECA317BFEB7611311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		0ECA317FFEB793E111CD283A = {
+			isa = PBXFileReference;
+			path = multidldb.cpp;
+			refType = 4;
+		};
+		0ECA3180FEB793E111CD283A = {
+			isa = PBXFileReference;
+			path = multidldb.h;
+			refType = 4;
+		};
+		0ECA3181FEB793E111CD283A = {
+			fileRef = 0ECA3180FEB793E111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		0ECA3182FEB793E111CD283A = {
+			fileRef = 0ECA317FFEB793E111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		12DB1A67FF094C9E11CD296C = {
+			isa = PBXFileReference;
+			path = machrunloopserver.cpp;
+			refType = 4;
+		};
+		12DB1A68FF094C9E11CD296C = {
+			isa = PBXFileReference;
+			path = machrunloopserver.h;
+			refType = 4;
+		};
+		12DB1A69FF094C9E11CD296C = {
+			fileRef = 12DB1A68FF094C9E11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		12DB1A6AFF094C9E11CD296C = {
+			fileRef = 12DB1A67FF094C9E11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		15B6EA05FE9A545311CD283A = {
+			children = (
+				15B6EA06FE9A545311CD283A,
+				15B6EA07FE9A545311CD283A,
+			);
+			isa = PBXGroup;
+			name = Datastore;
+			path = "";
+			refType = 4;
+		};
+		15B6EA06FE9A545311CD283A = {
+			isa = PBXFileReference;
+			path = dlclient.cpp;
+			refType = 4;
+		};
+		15B6EA07FE9A545311CD283A = {
+			isa = PBXFileReference;
+			path = dlclient.h;
+			refType = 4;
+		};
+		15B6EA08FE9A545311CD283A = {
+			fileRef = 15B6EA07FE9A545311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		15B6EA09FE9A545311CD283A = {
+			fileRef = 15B6EA06FE9A545311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		15B6EA0AFE9AA4C511CD283A = {
+			isa = PBXTargetDependency;
+			target = 1F54E424FE99514A11CD296C;
+		};
+		163F7756FF543E27D0A17CE7 = {
+			isa = PBXFileReference;
+			path = oidsalg.h;
+			refType = 4;
+		};
+		163F7757FF543E27D0A17CE7 = {
+			isa = PBXFileReference;
+			name = oidsalg.c;
+			path = cssm/oidsalg.c;
+			refType = 2;
+		};
+		163F7758FF543E27D0A17CE7 = {
+			fileRef = 163F7756FF543E27D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		163F7759FF543E27D0A17CE7 = {
+			fileRef = 163F7757FF543E27D0A17CE7;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		168D1483FFC4593111CD296C = {
+			isa = PBXFileReference;
+			path = daemon.cpp;
+			refType = 4;
+		};
+		168D1484FFC4593111CD296C = {
+			isa = PBXFileReference;
+			path = daemon.h;
+			refType = 4;
+		};
+		168D1485FFC4593211CD296C = {
+			fileRef = 168D1484FFC4593111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		168D1486FFC4593211CD296C = {
+			fileRef = 168D1483FFC4593111CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		17AD0156FF6EA90F11CD296C = {
+			isa = PBXFileReference;
+			path = debugging.cpp;
+			refType = 4;
+		};
+		17AD0157FF6EA90F11CD296C = {
+			isa = PBXFileReference;
+			path = debugging.h;
+			refType = 4;
+		};
+		17AD0158FF6EA90F11CD296C = {
+			isa = PBXFileReference;
+			path = debugsupport.h;
+			refType = 4;
+		};
+		17AD0159FF6EA90F11CD296C = {
+			isa = PBXFileReference;
+			path = logging.cpp;
+			refType = 4;
+		};
+		17AD015AFF6EA90F11CD296C = {
+			isa = PBXFileReference;
+			path = logging.h;
+			refType = 4;
+		};
+		17AD015BFF6EA90F11CD296C = {
+			fileRef = 17AD0157FF6EA90F11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		17AD015CFF6EA90F11CD296C = {
+			fileRef = 17AD0158FF6EA90F11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		17AD015DFF6EA90F11CD296C = {
+			fileRef = 17AD015AFF6EA90F11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		17AD015EFF6EA90F11CD296C = {
+			fileRef = 17AD0156FF6EA90F11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		17AD015FFF6EA90F11CD296C = {
+			fileRef = 17AD0159FF6EA90F11CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		1F382786FF238CB211CD283A = {
+			isa = PBXFileReference;
+			path = aclclient.h;
+			refType = 4;
+		};
+		1F382788FF238E7911CD283A = {
+			fileRef = 1F382786FF238CB211CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		1F54E423FE99511211CD296C = {
+			children = (
+				1F54E42FFE99523511CD296C,
+				1F54E430FE99523511CD296C,
+				1F382786FF238CB211CD283A,
+				1F54E43BFE99528E11CD296C,
+				15B6EA05FE9A545311CD283A,
+				00DAE77BFEB4BE5E11CD2984,
+				00DAE77CFEB4BE5E11CD2984,
+				0ECA317FFEB793E111CD283A,
+				0ECA3180FEB793E111CD283A,
+				0ECA317BFEB7611311CD283A,
+				0ECA317CFEB7611311CD283A,
+				28455460FFF000A111CD283A,
+				0169207DFF9BA84C11CD296C,
+			);
+			isa = PBXGroup;
+			path = cdsa_client;
+			refType = 4;
+		};
+		1F54E424FE99514A11CD296C = {
+			buildPhases = (
+				1F54E426FE99514A11CD296C,
+				1F54E427FE99514A11CD296C,
+				1F54E428FE99514A11CD296C,
+				1F54E429FE99514A11CD296C,
+				1F54E42AFE99514A11CD296C,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				HEADER_SEARCH_PATHS = "";
+				INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "\"-lstdc++\" -prebind -seg_addr_table \"$(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table\"";
+				OTHER_REZFLAGS = "";
+				PRINCIPAL_CLASS = "";
+				PRODUCT_NAME = cdsa_client;
+				SECTORDER_FLAGS = "-sectorder __TEXT __text \"$(APPLE_INTERNAL_DIR)/OrderFiles/cdsa_client.order\"";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+				WRAPPER_EXTENSION = framework;
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+				1F54E425FE99514A11CD296C,
+			);
+			isa = PBXFrameworkTarget;
+			name = cdsa_client;
+			productInstallPath = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+			productName = cdsa_client;
+			productReference = 0115DA20FF13D7E811CD283A;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>cdsa_client</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.cdsa_client</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.1d1</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		1F54E425FE99514A11CD296C = {
+			isa = PBXTargetDependency;
+			target = 0C2A9506FE89EF8611CD283A;
+		};
+		1F54E426FE99514A11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				1F382788FF238E7911CD283A,
+				0D80A0A5FEA5508C11CD283A,
+				1F54E434FE99523511CD296C,
+				1F54E435FE99523511CD296C,
+				15B6EA08FE9A545311CD283A,
+				00DAE77DFEB4BE5E11CD2984,
+				0D80A0A6FEA5508C11CD283A,
+				062BE059FEAFD57811CD287F,
+				0ECA3181FEB793E111CD283A,
+				0ECA317DFEB7611311CD283A,
+				1F54E436FE99523511CD296C,
+				01EEBD01FEED9C5C11CD287F,
+				01EEBD02FEED9C5C11CD287F,
+				0169208AFF9D296311CD296C,
+				28455463FFF000A111CD283A,
+				28455467FFF00DA211CD283A,
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		1F54E427FE99514A11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXResourcesBuildPhase;
+			name = "Bundle Resources";
+		};
+		1F54E428FE99514A11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				0D80A0A7FEA5508C11CD283A,
+				1F54E437FE99523511CD296C,
+				1F54E438FE99523511CD296C,
+				15B6EA09FE9A545311CD283A,
+				00DAE77EFEB4BE5E11CD2984,
+				0D80A0A8FEA5508C11CD283A,
+				062BE05AFEAFD57811CD287F,
+				0ECA3182FEB793E111CD283A,
+				0ECA317EFEB7611311CD283A,
+				1F54E439FE99523511CD296C,
+				01EEBCFDFEED9C1111CD287F,
+				01EEBCFEFEED9C1111CD287F,
+				0169208BFF9D296311CD296C,
+				28455464FFF000A111CD283A,
+				28455468FFF00DA211CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		1F54E429FE99514A11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+				0115DA24FF13D7E811CD283A,
+				0115DA25FF13D7E811CD283A,
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		1F54E42AFE99514A11CD296C = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		1F54E42DFE99523511CD296C = {
+			isa = PBXFileReference;
+			path = cspclient.cpp;
+			refType = 4;
+		};
+		1F54E42EFE99523511CD296C = {
+			isa = PBXFileReference;
+			path = cspclient.h;
+			refType = 4;
+		};
+		1F54E42FFE99523511CD296C = {
+			isa = PBXFileReference;
+			path = cssmclient.cpp;
+			refType = 4;
+		};
+		1F54E430FE99523511CD296C = {
+			isa = PBXFileReference;
+			path = cssmclient.h;
+			refType = 4;
+		};
+		1F54E431FE99523511CD296C = {
+			isa = PBXFileReference;
+			path = signclient.cpp;
+			refType = 4;
+		};
+		1F54E432FE99523511CD296C = {
+			isa = PBXFileReference;
+			path = signclient.h;
+			refType = 4;
+		};
+		1F54E434FE99523511CD296C = {
+			fileRef = 1F54E42EFE99523511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		1F54E435FE99523511CD296C = {
+			fileRef = 1F54E430FE99523511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		1F54E436FE99523511CD296C = {
+			fileRef = 1F54E432FE99523511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		1F54E437FE99523511CD296C = {
+			fileRef = 1F54E42DFE99523511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		1F54E438FE99523511CD296C = {
+			fileRef = 1F54E42FFE99523511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		1F54E439FE99523511CD296C = {
+			fileRef = 1F54E431FE99523511CD296C;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		1F54E43BFE99528E11CD296C = {
+			children = (
+				0D80A0A1FEA5508C11CD283A,
+				0D80A0A2FEA5508C11CD283A,
+				1F54E42DFE99523511CD296C,
+				1F54E42EFE99523511CD296C,
+				01EEBCFBFEED9C1111CD287F,
+				01EEBD00FEED9C5C11CD287F,
+				0D80A0A3FEA5508C11CD283A,
+				0D80A0A4FEA5508C11CD283A,
+				062BE057FEAFD57811CD287F,
+				062BE058FEAFD57811CD287F,
+				1F54E431FE99523511CD296C,
+				1F54E432FE99523511CD296C,
+				01EEBCFCFEED9C1111CD287F,
+				01EEBCFFFEED9C5C11CD287F,
+			);
+			isa = PBXGroup;
+			name = Crypto;
+			refType = 4;
+		};
+		28455460FFF000A111CD283A = {
+			children = (
+				28455461FFF000A111CD283A,
+				28455462FFF000A111CD283A,
+				28455465FFF00DA211CD283A,
+				28455466FFF00DA211CD283A,
+			);
+			isa = PBXGroup;
+			name = "ACL Support";
+			refType = 4;
+		};
+		28455461FFF000A111CD283A = {
+			isa = PBXFileReference;
+			path = aclsupport.cpp;
+			refType = 4;
+		};
+		28455462FFF000A111CD283A = {
+			isa = PBXFileReference;
+			path = aclsupport.h;
+			refType = 4;
+		};
+		28455463FFF000A111CD283A = {
+			fileRef = 28455462FFF000A111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		28455464FFF000A111CD283A = {
+			fileRef = 28455461FFF000A111CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		28455465FFF00DA211CD283A = {
+			isa = PBXFileReference;
+			path = keychainacl.cpp;
+			refType = 4;
+		};
+		28455466FFF00DA211CD283A = {
+			isa = PBXFileReference;
+			path = keychainacl.h;
+			refType = 4;
+		};
+		28455467FFF00DA211CD283A = {
+			fileRef = 28455466FFF00DA211CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		28455468FFF00DA211CD283A = {
+			fileRef = 28455465FFF00DA211CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		41463C29FE8C139711CD283A = {
+			children = (
+				41463C2AFE8C141C11CD283A,
+				41463C2BFE8C141C11CD283A,
+				41463C2CFE8C141C11CD283A,
+				41463C2DFE8C141C11CD283A,
+				41463C2EFE8C141C11CD283A,
+			);
+			isa = PBXGroup;
+			name = derived_headers;
+			path = include/cdsa_pluginlib;
+			refType = 3;
+		};
+		41463C2AFE8C141C11CD283A = {
+			isa = PBXFileReference;
+			path = ACabstractsession.h;
+			refType = 4;
+		};
+		41463C2BFE8C141C11CD283A = {
+			isa = PBXFileReference;
+			path = CLabstractsession.h;
+			refType = 4;
+		};
+		41463C2CFE8C141C11CD283A = {
+			isa = PBXFileReference;
+			path = CSPabstractsession.h;
+			refType = 4;
+		};
+		41463C2DFE8C141C11CD283A = {
+			isa = PBXFileReference;
+			path = DLabstractsession.h;
+			refType = 4;
+		};
+		41463C2EFE8C141C11CD283A = {
+			isa = PBXFileReference;
+			path = TPabstractsession.h;
+			refType = 4;
+		};
+		42462E68FFF0254211CD283A = {
+			isa = PBXLibraryReference;
+			path = libcdsa_client.a;
+			refType = 3;
+		};
+		42462E69FFF0254211CD283A = {
+			buildPhases = (
+				42462E6AFFF0254211CD283A,
+				42462E6BFFF0254211CD283A,
+				42462E6DFFF0254211CD283A,
+				42462E6EFFF0254211CD283A,
+			);
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks\"";
+				HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"";
+				LIBRARY_STYLE = STATIC;
+				OPTIMIZATION_CFLAGS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOL_FLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = libcdsa_client.a;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			conditionalBuildSettings = {
+			};
+			dependencies = (
+			);
+			isa = PBXLibraryTarget;
+			name = libcdsa_client.a;
+			productInstallPath = /usr/local/lib;
+			productName = libcdsa_client.a;
+			productReference = 42462E68FFF0254211CD283A;
+			shouldUseHeadermap = 0;
+		};
+		42462E6AFFF0254211CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			name = Headers;
+		};
+		42462E6BFFF0254211CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+				42462E6CFFF0254211CD283A,
+			);
+			isa = PBXSourcesBuildPhase;
+			name = Sources;
+		};
+		42462E6CFFF0254211CD283A = {
+			fileRef = 0181597FFFEE802311CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		42462E6DFFF0254211CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXFrameworksBuildPhase;
+			name = "Frameworks & Libraries";
+		};
+		42462E6EFFF0254211CD283A = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			name = "ResourceManager Resources";
+		};
+		454AF0B3FFAB6E8311CD28CA = {
+			isa = PBXFileReference;
+			path = MDSSchema.cpp;
+			refType = 4;
+		};
+		454AF0B4FFAB6E8311CD28CA = {
+			fileRef = 454AF0B3FFAB6E8311CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		454AF0B5FFAB6EDE11CD28CA = {
+			isa = PBXFileReference;
+			path = MDSSchema.h;
+			refType = 4;
+		};
+		454AF0B6FFAB6EDE11CD28CA = {
+			fileRef = 454AF0B5FFAB6EDE11CD28CA;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		4EABFBAAFE9016E511CD283A = {
+			isa = PBXFileReference;
+			path = MDS;
+			refType = 4;
+		};
+		4EABFBABFE9016E511CD283A = {
+			fileRef = 4EABFBAAFE9016E511CD283A;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		634531E7FF097FD011CD283A = {
+			isa = PBXFileReference;
+			path = cssmdata.cpp;
+			refType = 4;
+		};
+		634531E8FF097FD011CD283A = {
+			fileRef = 634531E7FF097FD011CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Debug,
+				);
+			};
+		};
+		688302CDFE940F2A11CD283A = {
+			isa = PBXFileReference;
+			path = cssmdata.h;
+			refType = 4;
+		};
+		688302CEFE940F2A11CD283A = {
+			fileRef = 688302CDFE940F2A11CD283A;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+	};
+	rootObject = 0C1F5822FE89EE6611CD283A;
+}
diff --git a/cdsa/cdsa/certextensions.h b/cdsa/cdsa/certextensions.h
new file mode 100644
index 00000000..a3f3235d
--- /dev/null
+++ b/cdsa/cdsa/certextensions.h
@@ -0,0 +1,298 @@
+/*
+ * 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.
+ */
+
+
+/*
+	File:		CertExtensions.h
+
+	Contains:	X.509 Cert Extensions as C structs
+
+	Copyright:	(c) 2000 by Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef	_CERT_EXTENSIONS_H_
+#define _CERT_EXTENSIONS_H_
+
+#include <Security/cssmtype.h>
+
+/***
+ *** Structs for declaring extension-specific data. 
+ ***/
+
+/*
+ * GeneralName, used in AuthorityKeyID and SubjectAltName.
+ *
+ * For now, we just provide explicit support for the types which are
+ * represented as IA5Strings, OIDs, and octet strings. Constructed types
+ * such as EDIPartyName and x400Address are not explicitly handled
+ * right now and must be encoded and decoded by the caller. In those
+ * cases the CE_GeneralName.name.Data field represents the BER contents
+ * octets; CE_GeneralName.name,Length is the length of the contents; the 
+ * tag of the field is not needed - the BER encoding uses context-specific
+ * implicit tagging. The berEncoded field is set to CSSM_TRUE in these
+ * case. Simple types have berEncoded = CSSM_FALS. 
+ *
+ *      GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ *
+ *      GeneralName ::= CHOICE {
+ *           otherName                       [0]     OtherName (i.e., OID),
+ *           rfc822Name                      [1]     IA5String,
+ *           dNSName                         [2]     IA5String,
+ *           x400Address                     [3]     ORAddress,
+ *           directoryName                   [4]     Name,
+ *           ediPartyName                    [5]     EDIPartyName,
+ *           uniformResourceIdentifier       [6]     IA5String,
+ *           iPAddress                       [7]     OCTET STRING,
+ *           registeredID                    [8]     OBJECT IDENTIFIER}
+ *
+ *      OtherName ::= SEQUENCE {
+ *           type-id    OBJECT IDENTIFIER,
+ *           value      [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ *      EDIPartyName ::= SEQUENCE {
+ *           nameAssigner            [0]     DirectoryString OPTIONAL,
+ *           partyName               [1]     DirectoryString }
+ */
+typedef enum {
+	GNT_OtherName = 0,
+	GNT_RFC822Name,
+	GNT_DNSName,
+	GNT_X400Address,
+	GNT_DirectoryName,
+	GNT_EdiPartyName,
+	GNT_URI,
+	GNT_IPAddress,
+	GNT_RegisteredID
+} CE_GeneralNameType;
+
+typedef struct {
+	CE_GeneralNameType		nameType;	// GNT_RFC822Name, etc.
+	CSSM_BOOL				berEncoded;
+	CSSM_DATA				name; 
+} CE_GeneralName;
+
+typedef struct {
+	uint32					numNames;
+	CE_GeneralName			*generalName;		
+} CE_GeneralNames;	
+
+/*
+ * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
+ *
+ *   AuthorityKeyIdentifier ::= SEQUENCE {
+ *     keyIdentifier             [0] KeyIdentifier           OPTIONAL,
+ *     authorityCertIssuer       [1] GeneralNames            OPTIONAL,
+ *     authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
+ *
+ *   KeyIdentifier ::= OCTET STRING
+ *
+ * CSSM OID = CSSMOID_AuthorityKeyIdentifier
+ */
+typedef struct {
+	CSSM_BOOL			keyIdentifierPresent;
+	CSSM_DATA			keyIdentifier;
+	CSSM_BOOL			generalNamesPresent;
+	CE_GeneralNames		*generalNames;
+	CSSM_BOOL			serialNumberPresent;
+	CSSM_DATA			serialNumber;
+} CE_AuthorityKeyID;
+
+/*
+ * id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }
+ *   SubjectKeyIdentifier ::= KeyIdentifier
+ *
+ * CSSM OID = CSSMOID_SubjectKeyIdentifier
+ */
+typedef CSSM_DATA CE_SubjectKeyID;
+
+/*
+ * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
+ *
+ *     KeyUsage ::= BIT STRING {
+ *          digitalSignature        (0),
+ *          nonRepudiation          (1),
+ *          keyEncipherment         (2),
+ *          dataEncipherment        (3),
+ *          keyAgreement            (4),
+ *          keyCertSign             (5),
+ *          cRLSign                 (6),
+ *          encipherOnly            (7),
+ *          decipherOnly            (8) }
+ *
+ * CSSM OID = CSSMOID_KeyUsage
+ *
+ */
+typedef uint16 CE_KeyUsage;
+
+#define CE_KU_DigitalSignature	0x8000
+#define CE_KU_NonRepudiation	0x4000
+#define CE_KU_KeyEncipherment	0x2000
+#define CE_KU_DataEncipherment	0x1000
+#define CE_KU_KeyAgreement		0x0800
+#define CE_KU_KeyCertSign	 	0x0400
+#define CE_KU_CRLSign			0x0200
+#define CE_KU_EncipherOnly	 	0x0100
+#define CE_KU_DecipherOnly	 	0x0080
+
+/*
+ * id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }
+ *
+ *      SubjectAltName ::= GeneralNames
+ *
+ * CSSM OID = CSSMOID_SubjectAltName
+ *
+ * GeneralNames defined above.
+ */
+
+/*
+ *  id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
+ *
+ *   ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId*
+ *
+ *  KeyPurposeId ::= OBJECT IDENTIFIER
+ *
+ * CSSM OID = CSSMOID_ExtendedKeyUsage
+ */
+typedef struct {
+	uint32			numPurposes;
+	CSSM_OID_PTR	purposes;		// in Intel pre-encoded format
+} CE_ExtendedKeyUsage;
+
+/*
+ * id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
+ *
+ * BasicConstraints ::= SEQUENCE {
+ *       cA                      BOOLEAN DEFAULT FALSE,
+ *       pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
+ *
+ * CSSM OID = CSSMOID_BasicConstraints
+ */
+typedef struct {
+	CSSM_BOOL			cA;
+	CSSM_BOOL			pathLenConstraintPresent;
+	uint32				pathLenConstraint;
+} CE_BasicConstraints;	
+
+/*
+ * id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }
+ *
+ *   certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+ *
+ *   PolicyInformation ::= SEQUENCE {
+ *        policyIdentifier   CertPolicyId,
+ *        policyQualifiers   SEQUENCE SIZE (1..MAX) OF
+ *                                PolicyQualifierInfo OPTIONAL }
+ *
+ *   CertPolicyId ::= OBJECT IDENTIFIER
+ *
+ *   PolicyQualifierInfo ::= SEQUENCE {
+ *        policyQualifierId  PolicyQualifierId,
+ *        qualifier          ANY DEFINED BY policyQualifierId } 
+ *
+ *   -- policyQualifierIds for Internet policy qualifiers
+ *
+ *   id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
+ *   id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
+ *   id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
+ *
+ *   PolicyQualifierId ::=
+ *        OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+ *
+ *   Qualifier ::= CHOICE {
+ *        cPSuri           CPSuri,
+ *        userNotice       UserNotice }
+ *
+ *   CPSuri ::= IA5String
+ *
+ *   UserNotice ::= SEQUENCE {
+ *        noticeRef        NoticeReference OPTIONAL,
+ *        explicitText     DisplayText OPTIONAL}
+ *
+ *   NoticeReference ::= SEQUENCE {
+ *        organization     DisplayText,
+ *        noticeNumbers    SEQUENCE OF INTEGER }
+ *
+ *   DisplayText ::= CHOICE {
+ *        visibleString    VisibleString  (SIZE (1..200)),
+ *        bmpString        BMPString      (SIZE (1..200)),
+ *        utf8String       UTF8String     (SIZE (1..200)) }
+ *
+ *  CSSM OID = CSSMOID_CertificatePolicies
+ *
+ * We only support down to the level of Qualifier, and then only the CPSuri
+ * choice. UserNotice is transmitted to and from this library as a raw
+ * CSSM_DATA representing the Contents octets of the BER-encoded UserNotice sequence. 
+ */
+
+typedef struct {
+	CSSM_OID	policyQualifierId;			// CSSMOID_QT_CPS, CSSMOID_QT_UNOTICE
+	CSSM_DATA	qualifier;					// CSSMOID_QT_CPS: IA5String contents
+											// CSSMOID_QT_UNOTICE : Sequence contents
+} CE_PolicyQualifierInfo;
+
+typedef struct {
+	CSSM_OID				certPolicyId;
+	uint32					numPolicyQualifiers;	// size of *policyQualifiers;
+	CE_PolicyQualifierInfo	*policyQualifiers;
+} CE_PolicyInformation;
+
+typedef struct {
+	uint32					numPolicies;			// size of *policies;
+	CE_PolicyInformation	*policies;
+} CE_CertPolicies;
+
+/*
+ * netscape-cert-type, a bit string.
+ *
+ * CSSM OID = CSSMOID_NetscapeCertType
+ *
+ * Bit fields defined in oidsattr.h: CE_NCT_SSL_Client, etc.
+ */
+typedef uint16 CE_NetscapeCertType;
+
+/*
+ * An enumerated list identifying one of the above per-extension
+ * structs.
+ */
+typedef enum {
+	DT_AuthorityKeyID,			// CE_AuthorityKeyID
+	DT_SubjectKeyID,			// CE_SubjectKeyID
+	DT_KeyUsage,				// CE_KeyUsage
+	DT_SubjectAltName,			// implies CE_GeneralName
+	DT_ExtendedKeyUsage,		// CE_ExtendedKeyUsage
+	DT_BasicConstraints,		// CE_BasicConstraints
+	DT_CertPolicies,			// CE_CertPolicies
+	DT_NetscapeCertType,		// CE_NetscapeCertType
+	DT_Other					// unknown, raw data as a CSSM_DATA
+} CE_DataType;
+
+/*
+ * One unified representation of all the cert extensions we know about.
+ */
+typedef union {
+	CE_AuthorityKeyID		authorityKeyID;
+	CE_SubjectKeyID			subjectKeyID;
+	CE_KeyUsage				keyUsage;
+	CE_GeneralNames			subjectAltName;
+	CE_ExtendedKeyUsage		extendedKeyUsage;
+	CE_BasicConstraints		basicConstraints;
+	CE_CertPolicies			certPolicies;
+	CE_NetscapeCertType		netscapeCertType;
+	CSSM_DATA				rawData;			// unknown, not decoded
+} CE_Data;
+
+#endif	/* _CERT_EXTENSIONS_H_ */
diff --git a/cdsa/cdsa/cssm.h b/cdsa/cdsa/cssm.h
new file mode 100644
index 00000000..f0c5d900
--- /dev/null
+++ b/cdsa/cdsa/cssm.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssm.h
+
+   Contains:  Common Security Services Manager Interface
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+
+*/
+
+#ifndef _CSSM_H_
+#define _CSSM_H_  1
+
+#include <Security/cssmtype.h>
+#include <Security/emmtype.h>
+#include <Security/cssmapi.h>
+#include <Security/cssmerr.h>
+#include <Security/cssmapple.h>
+
+#endif /* _CSSM_H_ */
diff --git a/cdsa/cdsa/cssmaci.h b/cdsa/cdsa/cssmaci.h
new file mode 100644
index 00000000..2f1ca2e2
--- /dev/null
+++ b/cdsa/cdsa/cssmaci.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmaci.h
+
+   Contains:  Sevice Provider Interface for Access Control Module
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+ */
+
+#ifndef _CSSMACI_H_
+#define _CSSMACI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct cssm_spi_ac_funcs {
+    CSSM_RETURN (CSSMACI *AuthCompute)
+        (CSSM_AC_HANDLE ACHandle,
+         const CSSM_TUPLEGROUP *BaseAuthorizations,
+         const CSSM_TUPLEGROUP *Credentials,
+         uint32 NumberOfRequestors,
+         const CSSM_LIST *Requestors,
+         const CSSM_LIST *RequestedAuthorizationPeriod,
+         const CSSM_LIST *RequestedAuthorization,
+         CSSM_TUPLEGROUP_PTR AuthorizationResult);
+    CSSM_RETURN (CSSMACI *PassThrough)
+        (CSSM_AC_HANDLE ACHandle,
+         CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DL_DB_LIST *DBList,
+         uint32 PassThroughId,
+         const void *InputParams,
+         void **OutputParams);
+} CSSM_SPI_AC_FUNCS, *CSSM_SPI_AC_FUNCS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMACI_H_ */
diff --git a/cdsa/cdsa/cssmapi.h b/cdsa/cdsa/cssmapi.h
new file mode 100644
index 00000000..6feaf51d
--- /dev/null
+++ b/cdsa/cdsa/cssmapi.h
@@ -0,0 +1,1181 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmapi.h
+
+   Contains:  Application Programmers Interfaces for CSSM
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMAPI_H_
+#define _CSSMAPI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Core Functions */
+
+CSSM_RETURN CSSMAPI
+CSSM_Init (const CSSM_VERSION *Version,
+           CSSM_PRIVILEGE_SCOPE Scope,
+           const CSSM_GUID *CallerGuid,
+           CSSM_KEY_HIERARCHY KeyHierarchy,
+           CSSM_PVC_MODE *PvcPolicy,
+           const void *Reserved);
+
+CSSM_RETURN CSSMAPI
+CSSM_Terminate (void);
+
+CSSM_RETURN CSSMAPI
+CSSM_ModuleLoad (const CSSM_GUID *ModuleGuid,
+                 CSSM_KEY_HIERARCHY KeyHierarchy,
+                 CSSM_API_ModuleEventHandler AppNotifyCallback,
+                 void *AppNotifyCallbackCtx);
+
+CSSM_RETURN CSSMAPI
+CSSM_ModuleUnload (const CSSM_GUID *ModuleGuid,
+                   CSSM_API_ModuleEventHandler AppNotifyCallback,
+                   void *AppNotifyCallbackCtx);
+
+CSSM_RETURN CSSMAPI
+CSSM_Introduce (const CSSM_GUID *ModuleID,
+                CSSM_KEY_HIERARCHY KeyHierarchy);
+
+CSSM_RETURN CSSMAPI
+CSSM_Unintroduce (const CSSM_GUID *ModuleID);
+
+CSSM_RETURN CSSMAPI
+CSSM_ModuleAttach (const CSSM_GUID *ModuleGuid,
+                   const CSSM_VERSION *Version,
+                   const CSSM_API_MEMORY_FUNCS *MemoryFuncs,
+                   uint32 SubserviceID,
+                   CSSM_SERVICE_TYPE SubServiceType,
+                   CSSM_ATTACH_FLAGS AttachFlags,
+                   CSSM_KEY_HIERARCHY KeyHierarchy,
+                   CSSM_FUNC_NAME_ADDR *FunctionTable,
+                   uint32 NumFunctionTable,
+                   const void *Reserved,
+                   CSSM_MODULE_HANDLE_PTR NewModuleHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_ModuleDetach (CSSM_MODULE_HANDLE ModuleHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_SetPrivilege (CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetPrivilege (CSSM_PRIVILEGE *Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetModuleGUIDFromHandle (CSSM_MODULE_HANDLE ModuleHandle,
+                              CSSM_GUID_PTR ModuleGUID);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetSubserviceUIDFromHandle (CSSM_MODULE_HANDLE ModuleHandle,
+                                 CSSM_SUBSERVICE_UID_PTR SubserviceUID);
+
+CSSM_RETURN CSSMAPI
+CSSM_ListAttachedModuleManagers (uint32 *NumberOfModuleManagers,
+                                 CSSM_GUID_PTR ModuleManagerGuids);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetAPIMemoryFunctions (CSSM_MODULE_HANDLE AddInHandle,
+                            CSSM_API_MEMORY_FUNCS_PTR AppMemoryFuncs);
+
+
+/* Cryptographic Context Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateSignatureContext (CSSM_CSP_HANDLE CSPHandle,
+                                 CSSM_ALGORITHMS AlgorithmID,
+                                 const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                                 const CSSM_KEY *Key,
+                                 CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateSymmetricContext (CSSM_CSP_HANDLE CSPHandle,
+                                 CSSM_ALGORITHMS AlgorithmID,
+                                 CSSM_ENCRYPT_MODE Mode,
+                                 const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                                 const CSSM_KEY *Key,
+                                 const CSSM_DATA *InitVector,
+                                 CSSM_PADDING Padding,
+                                 void *Reserved,
+                                 CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateDigestContext (CSSM_CSP_HANDLE CSPHandle,
+                              CSSM_ALGORITHMS AlgorithmID,
+                              CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateMacContext (CSSM_CSP_HANDLE CSPHandle,
+                           CSSM_ALGORITHMS AlgorithmID,
+                           const CSSM_KEY *Key,
+                           CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateRandomGenContext (CSSM_CSP_HANDLE CSPHandle,
+                                 CSSM_ALGORITHMS AlgorithmID,
+                                 const CSSM_CRYPTO_DATA *Seed,
+                                 uint32 Length,
+                                 CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateAsymmetricContext (CSSM_CSP_HANDLE CSPHandle,
+                                  CSSM_ALGORITHMS AlgorithmID,
+                                  const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                                  const CSSM_KEY *Key,
+                                  CSSM_PADDING Padding,
+                                  CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateDeriveKeyContext (CSSM_CSP_HANDLE CSPHandle,
+                                 CSSM_ALGORITHMS AlgorithmID,
+                                 CSSM_KEY_TYPE DeriveKeyType,
+                                 uint32 DeriveKeyLengthInBits,
+                                 const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                                 const CSSM_KEY *BaseKey,
+                                 uint32 IterationCount,
+                                 const CSSM_DATA *Salt,
+                                 const CSSM_CRYPTO_DATA *Seed,
+                                 CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateKeyGenContext (CSSM_CSP_HANDLE CSPHandle,
+                              CSSM_ALGORITHMS AlgorithmID,
+                              uint32 KeySizeInBits,
+                              const CSSM_CRYPTO_DATA *Seed,
+                              const CSSM_DATA *Salt,
+                              const CSSM_DATE *StartDate,
+                              const CSSM_DATE *EndDate,
+                              const CSSM_DATA *Params,
+                              CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreatePassThroughContext (CSSM_CSP_HANDLE CSPHandle,
+                                   const CSSM_KEY *Key,
+                                   CSSM_CC_HANDLE *NewContextHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetContext (CSSM_CC_HANDLE CCHandle,
+                 CSSM_CONTEXT_PTR *Context);
+
+CSSM_RETURN CSSMAPI
+CSSM_FreeContext (CSSM_CONTEXT_PTR Context);
+
+CSSM_RETURN CSSMAPI
+CSSM_SetContext (CSSM_CC_HANDLE CCHandle,
+                 const CSSM_CONTEXT *Context);
+
+CSSM_RETURN CSSMAPI
+CSSM_DeleteContext (CSSM_CC_HANDLE CCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetContextAttribute (const CSSM_CONTEXT *Context,
+                          uint32 AttributeType,
+                          CSSM_CONTEXT_ATTRIBUTE_PTR *ContextAttribute);
+
+CSSM_RETURN CSSMAPI
+CSSM_UpdateContextAttributes (CSSM_CC_HANDLE CCHandle,
+                              uint32 NumberOfAttributes,
+                              const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes);
+
+CSSM_RETURN CSSMAPI
+CSSM_DeleteContextAttributes (CSSM_CC_HANDLE CCHandle,
+                              uint32 NumberOfAttributes,
+                              const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes);
+
+
+/* Cryptographic Sessions and Controlled Access to Keys */
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_Login (CSSM_CSP_HANDLE CSPHandle,
+                const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                const CSSM_DATA *LoginName,
+                const void *Reserved);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_Logout (CSSM_CSP_HANDLE CSPHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_GetLoginAcl (CSSM_CSP_HANDLE CSPHandle,
+                      const CSSM_STRING *SelectionTag,
+                      uint32 *NumberOfAclInfos,
+                      CSSM_ACL_ENTRY_INFO_PTR *AclInfos);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_ChangeLoginAcl (CSSM_CSP_HANDLE CSPHandle,
+                         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                         const CSSM_ACL_EDIT *AclEdit);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetKeyAcl (CSSM_CSP_HANDLE CSPHandle,
+                const CSSM_KEY *Key,
+                const CSSM_STRING *SelectionTag,
+                uint32 *NumberOfAclInfos,
+                CSSM_ACL_ENTRY_INFO_PTR *AclInfos);
+
+CSSM_RETURN CSSMAPI
+CSSM_ChangeKeyAcl (CSSM_CSP_HANDLE CSPHandle,
+                   const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                   const CSSM_ACL_EDIT *AclEdit,
+                   const CSSM_KEY *Key);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetKeyOwner (CSSM_CSP_HANDLE CSPHandle,
+                  const CSSM_KEY *Key,
+                  CSSM_ACL_OWNER_PROTOTYPE_PTR Owner);
+
+CSSM_RETURN CSSMAPI
+CSSM_ChangeKeyOwner (CSSM_CSP_HANDLE CSPHandle,
+                     const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                     const CSSM_KEY *Key,
+                     const CSSM_ACL_OWNER_PROTOTYPE *NewOwner);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_GetLoginOwner (CSSM_CSP_HANDLE CSPHandle,
+                        CSSM_ACL_OWNER_PROTOTYPE_PTR Owner);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_ChangeLoginOwner (CSSM_CSP_HANDLE CSPHandle,
+                           const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                           const CSSM_ACL_OWNER_PROTOTYPE *NewOwner);
+
+CSSM_RETURN CSSMAPI
+CSSM_SignData (CSSM_CC_HANDLE CCHandle,
+               const CSSM_DATA *DataBufs,
+               uint32 DataBufCount,
+               CSSM_ALGORITHMS DigestAlgorithm,
+               CSSM_DATA_PTR Signature);
+
+CSSM_RETURN CSSMAPI
+CSSM_SignDataInit (CSSM_CC_HANDLE CCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_SignDataUpdate (CSSM_CC_HANDLE CCHandle,
+                     const CSSM_DATA *DataBufs,
+                     uint32 DataBufCount);
+
+CSSM_RETURN CSSMAPI
+CSSM_SignDataFinal (CSSM_CC_HANDLE CCHandle,
+                    CSSM_DATA_PTR Signature);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyData (CSSM_CC_HANDLE CCHandle,
+                 const CSSM_DATA *DataBufs,
+                 uint32 DataBufCount,
+                 CSSM_ALGORITHMS DigestAlgorithm,
+                 const CSSM_DATA *Signature);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyDataInit (CSSM_CC_HANDLE CCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyDataUpdate (CSSM_CC_HANDLE CCHandle,
+                       const CSSM_DATA *DataBufs,
+                       uint32 DataBufCount);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyDataFinal (CSSM_CC_HANDLE CCHandle,
+                      const CSSM_DATA *Signature);
+
+CSSM_RETURN CSSMAPI
+CSSM_DigestData (CSSM_CC_HANDLE CCHandle,
+                 const CSSM_DATA *DataBufs,
+                 uint32 DataBufCount,
+                 CSSM_DATA_PTR Digest);
+
+CSSM_RETURN CSSMAPI
+CSSM_DigestDataInit (CSSM_CC_HANDLE CCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_DigestDataUpdate (CSSM_CC_HANDLE CCHandle,
+                       const CSSM_DATA *DataBufs,
+                       uint32 DataBufCount);
+
+CSSM_RETURN CSSMAPI
+CSSM_DigestDataClone (CSSM_CC_HANDLE CCHandle,
+                      CSSM_CC_HANDLE *ClonednewCCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_DigestDataFinal (CSSM_CC_HANDLE CCHandle,
+                      CSSM_DATA_PTR Digest);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateMac (CSSM_CC_HANDLE CCHandle,
+                  const CSSM_DATA *DataBufs,
+                  uint32 DataBufCount,
+                  CSSM_DATA_PTR Mac);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateMacInit (CSSM_CC_HANDLE CCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateMacUpdate (CSSM_CC_HANDLE CCHandle,
+                        const CSSM_DATA *DataBufs,
+                        uint32 DataBufCount);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateMacFinal (CSSM_CC_HANDLE CCHandle,
+                       CSSM_DATA_PTR Mac);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyMac (CSSM_CC_HANDLE CCHandle,
+                const CSSM_DATA *DataBufs,
+                uint32 DataBufCount,
+                const CSSM_DATA *Mac);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyMacInit (CSSM_CC_HANDLE CCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyMacUpdate (CSSM_CC_HANDLE CCHandle,
+                      const CSSM_DATA *DataBufs,
+                      uint32 DataBufCount);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyMacFinal (CSSM_CC_HANDLE CCHandle,
+                     const CSSM_DATA *Mac);
+
+CSSM_RETURN CSSMAPI
+CSSM_QuerySize (CSSM_CC_HANDLE CCHandle,
+                CSSM_BOOL Encrypt,
+                uint32 QuerySizeCount,
+                CSSM_QUERY_SIZE_DATA_PTR DataBlockSizes);
+
+CSSM_RETURN CSSMAPI
+CSSM_EncryptData (CSSM_CC_HANDLE CCHandle,
+                  const CSSM_DATA *ClearBufs,
+                  uint32 ClearBufCount,
+                  CSSM_DATA_PTR CipherBufs,
+                  uint32 CipherBufCount,
+                  uint32 *bytesEncrypted,
+                  CSSM_DATA_PTR RemData);
+
+CSSM_RETURN CSSMAPI
+CSSM_EncryptDataP (CSSM_CC_HANDLE CCHandle,
+                   const CSSM_DATA *ClearBufs,
+                   uint32 ClearBufCount,
+                   CSSM_DATA_PTR CipherBufs,
+                   uint32 CipherBufCount,
+                   uint32 *bytesEncrypted,
+                   CSSM_DATA_PTR RemData,
+                   CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_EncryptDataInit (CSSM_CC_HANDLE CCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_EncryptDataInitP (CSSM_CC_HANDLE CCHandle,
+                       CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_EncryptDataUpdate (CSSM_CC_HANDLE CCHandle,
+                        const CSSM_DATA *ClearBufs,
+                        uint32 ClearBufCount,
+                        CSSM_DATA_PTR CipherBufs,
+                        uint32 CipherBufCount,
+                        uint32 *bytesEncrypted);
+
+CSSM_RETURN CSSMAPI
+CSSM_EncryptDataFinal (CSSM_CC_HANDLE CCHandle,
+                       CSSM_DATA_PTR RemData);
+
+CSSM_RETURN CSSMAPI
+CSSM_DecryptData (CSSM_CC_HANDLE CCHandle,
+                  const CSSM_DATA *CipherBufs,
+                  uint32 CipherBufCount,
+                  CSSM_DATA_PTR ClearBufs,
+                  uint32 ClearBufCount,
+                  uint32 *bytesDecrypted,
+                  CSSM_DATA_PTR RemData);
+
+CSSM_RETURN CSSMAPI
+CSSM_DecryptDataP (CSSM_CC_HANDLE CCHandle,
+                   const CSSM_DATA *CipherBufs,
+                   uint32 CipherBufCount,
+                   CSSM_DATA_PTR ClearBufs,
+                   uint32 ClearBufCount,
+                   uint32 *bytesDecrypted,
+                   CSSM_DATA_PTR RemData,
+                   CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_DecryptDataInit (CSSM_CC_HANDLE CCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_DecryptDataInitP (CSSM_CC_HANDLE CCHandle,
+                       CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_DecryptDataUpdate (CSSM_CC_HANDLE CCHandle,
+                        const CSSM_DATA *CipherBufs,
+                        uint32 CipherBufCount,
+                        CSSM_DATA_PTR ClearBufs,
+                        uint32 ClearBufCount,
+                        uint32 *bytesDecrypted);
+
+CSSM_RETURN CSSMAPI
+CSSM_DecryptDataFinal (CSSM_CC_HANDLE CCHandle,
+                       CSSM_DATA_PTR RemData);
+
+CSSM_RETURN CSSMAPI
+CSSM_QueryKeySizeInBits (CSSM_CSP_HANDLE CSPHandle,
+                         CSSM_CC_HANDLE CCHandle,
+                         const CSSM_KEY *Key,
+                         CSSM_KEY_SIZE_PTR KeySize);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateKey (CSSM_CC_HANDLE CCHandle,
+                  uint32 KeyUsage,
+                  uint32 KeyAttr,
+                  const CSSM_DATA *KeyLabel,
+                  const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                  CSSM_KEY_PTR Key);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateKeyP (CSSM_CC_HANDLE CCHandle,
+                   uint32 KeyUsage,
+                   uint32 KeyAttr,
+                   const CSSM_DATA *KeyLabel,
+                   const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                   CSSM_KEY_PTR Key,
+                   CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateKeyPair (CSSM_CC_HANDLE CCHandle,
+                      uint32 PublicKeyUsage,
+                      uint32 PublicKeyAttr,
+                      const CSSM_DATA *PublicKeyLabel,
+                      CSSM_KEY_PTR PublicKey,
+                      uint32 PrivateKeyUsage,
+                      uint32 PrivateKeyAttr,
+                      const CSSM_DATA *PrivateKeyLabel,
+                      const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                      CSSM_KEY_PTR PrivateKey);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateKeyPairP (CSSM_CC_HANDLE CCHandle,
+                       uint32 PublicKeyUsage,
+                       uint32 PublicKeyAttr,
+                       const CSSM_DATA *PublicKeyLabel,
+                       CSSM_KEY_PTR PublicKey,
+                       uint32 PrivateKeyUsage,
+                       uint32 PrivateKeyAttr,
+                       const CSSM_DATA *PrivateKeyLabel,
+                       const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                       CSSM_KEY_PTR PrivateKey,
+                       CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateRandom (CSSM_CC_HANDLE CCHandle,
+                     CSSM_DATA_PTR RandomNumber);
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_ObtainPrivateKeyFromPublicKey (CSSM_CSP_HANDLE CSPHandle,
+                                        const CSSM_KEY *PublicKey,
+                                        CSSM_KEY_PTR PrivateKey);
+
+CSSM_RETURN CSSMAPI
+CSSM_WrapKey (CSSM_CC_HANDLE CCHandle,
+              const CSSM_ACCESS_CREDENTIALS *AccessCred,
+              const CSSM_KEY *Key,
+              const CSSM_DATA *DescriptiveData,
+              CSSM_WRAP_KEY_PTR WrappedKey);
+
+CSSM_RETURN CSSMAPI
+CSSM_UnwrapKey (CSSM_CC_HANDLE CCHandle,
+                const CSSM_KEY *PublicKey,
+                const CSSM_WRAP_KEY *WrappedKey,
+                uint32 KeyUsage,
+                uint32 KeyAttr,
+                const CSSM_DATA *KeyLabel,
+                const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                CSSM_KEY_PTR UnwrappedKey,
+                CSSM_DATA_PTR DescriptiveData);
+
+CSSM_RETURN CSSMAPI
+CSSM_WrapKeyP (CSSM_CC_HANDLE CCHandle,
+               const CSSM_ACCESS_CREDENTIALS *AccessCred,
+               const CSSM_KEY *Key,
+               const CSSM_DATA *DescriptiveData,
+               CSSM_WRAP_KEY_PTR WrappedKey,
+               CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_UnwrapKeyP (CSSM_CC_HANDLE CCHandle,
+                 const CSSM_KEY *PublicKey,
+                 const CSSM_WRAP_KEY *WrappedKey,
+                 uint32 KeyUsage,
+                 uint32 KeyAttr,
+                 const CSSM_DATA *KeyLabel,
+                 const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                 CSSM_KEY_PTR UnwrappedKey,
+                 CSSM_DATA_PTR DescriptiveData,
+                 CSSM_PRIVILEGE Privilege);
+
+CSSM_RETURN CSSMAPI
+CSSM_DeriveKey (CSSM_CC_HANDLE CCHandle,
+                CSSM_DATA_PTR Param,
+                uint32 KeyUsage,
+                uint32 KeyAttr,
+                const CSSM_DATA *KeyLabel,
+                const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                CSSM_KEY_PTR DerivedKey);
+
+CSSM_RETURN CSSMAPI
+CSSM_FreeKey (CSSM_CSP_HANDLE CSPHandle,
+              const CSSM_ACCESS_CREDENTIALS *AccessCred,
+              CSSM_KEY_PTR KeyPtr,
+              CSSM_BOOL Delete);
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateAlgorithmParams (CSSM_CC_HANDLE CCHandle,
+                              uint32 ParamBits,
+                              CSSM_DATA_PTR Param);
+
+
+/* Miscellaneous Functions for Cryptographic Services */
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_GetOperationalStatistics (CSSM_CSP_HANDLE CSPHandle,
+                                   CSSM_CSP_OPERATIONAL_STATISTICS *Statistics);
+
+CSSM_RETURN CSSMAPI
+CSSM_GetTimeValue (CSSM_CSP_HANDLE CSPHandle,
+                   CSSM_ALGORITHMS TimeAlgorithm,
+                   CSSM_DATA *TimeData);
+
+CSSM_RETURN CSSMAPI
+CSSM_RetrieveUniqueId (CSSM_CSP_HANDLE CSPHandle,
+                       CSSM_DATA_PTR UniqueID);
+
+CSSM_RETURN CSSMAPI
+CSSM_RetrieveCounter (CSSM_CSP_HANDLE CSPHandle,
+                      CSSM_DATA_PTR Counter);
+
+CSSM_RETURN CSSMAPI
+CSSM_VerifyDevice (CSSM_CSP_HANDLE CSPHandle,
+                   const CSSM_DATA *DeviceCert);
+
+
+/* Extensibility Functions for Cryptographic Services */
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_PassThrough (CSSM_CC_HANDLE CCHandle,
+                      uint32 PassThroughId,
+                      const void *InData,
+                      void **OutData);
+
+
+/* Trust Policy Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_SubmitCredRequest (CSSM_TP_HANDLE TPHandle,
+                           const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
+                           CSSM_TP_AUTHORITY_REQUEST_TYPE RequestType,
+                           const CSSM_TP_REQUEST_SET *RequestInput,
+                           const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthContext,
+                           sint32 *EstimatedTime,
+                           CSSM_DATA_PTR ReferenceIdentifier);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_RetrieveCredResult (CSSM_TP_HANDLE TPHandle,
+                            const CSSM_DATA *ReferenceIdentifier,
+                            const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
+                            sint32 *EstimatedTime,
+                            CSSM_BOOL *ConfirmationRequired,
+                            CSSM_TP_RESULT_SET_PTR *RetrieveOutput);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_ConfirmCredResult (CSSM_TP_HANDLE TPHandle,
+                           const CSSM_DATA *ReferenceIdentifier,
+                           const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
+                           const CSSM_TP_CONFIRM_RESPONSE *Responses,
+                           const CSSM_TP_AUTHORITY_ID *PreferredAuthority);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_ReceiveConfirmation (CSSM_TP_HANDLE TPHandle,
+                             const CSSM_DATA *ReferenceIdentifier,
+                             CSSM_TP_CONFIRM_RESPONSE_PTR *Responses,
+                             sint32 *ElapsedTime);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertReclaimKey (CSSM_TP_HANDLE TPHandle,
+                        const CSSM_CERTGROUP *CertGroup,
+                        uint32 CertIndex,
+                        CSSM_LONG_HANDLE KeyCacheHandle,
+                        CSSM_CSP_HANDLE CSPHandle,
+                        const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertReclaimAbort (CSSM_TP_HANDLE TPHandle,
+                          CSSM_LONG_HANDLE KeyCacheHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_FormRequest (CSSM_TP_HANDLE TPHandle,
+                     const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
+                     CSSM_TP_FORM_TYPE FormType,
+                     CSSM_DATA_PTR BlankForm);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_FormSubmit (CSSM_TP_HANDLE TPHandle,
+                    CSSM_TP_FORM_TYPE FormType,
+                    const CSSM_DATA *Form,
+                    const CSSM_TP_AUTHORITY_ID *ClearanceAuthority,
+                    const CSSM_TP_AUTHORITY_ID *RepresentedAuthority,
+                    CSSM_ACCESS_CREDENTIALS_PTR Credentials);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertGroupVerify (CSSM_TP_HANDLE TPHandle,
+                         CSSM_CL_HANDLE CLHandle,
+                         CSSM_CSP_HANDLE CSPHandle,
+                         const CSSM_CERTGROUP *CertGroupToBeVerified,
+                         const CSSM_TP_VERIFY_CONTEXT *VerifyContext,
+                         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR VerifyContextResult);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertCreateTemplate (CSSM_TP_HANDLE TPHandle,
+                            CSSM_CL_HANDLE CLHandle,
+                            uint32 NumberOfFields,
+                            const CSSM_FIELD *CertFields,
+                            CSSM_DATA_PTR CertTemplate);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertGetAllTemplateFields (CSSM_TP_HANDLE TPHandle,
+                                  CSSM_CL_HANDLE CLHandle,
+                                  const CSSM_DATA *CertTemplate,
+                                  uint32 *NumberOfFields,
+                                  CSSM_FIELD_PTR *CertFields);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertSign (CSSM_TP_HANDLE TPHandle,
+                  CSSM_CL_HANDLE CLHandle,
+                  CSSM_CC_HANDLE CCHandle,
+                  const CSSM_DATA *CertTemplateToBeSigned,
+                  const CSSM_CERTGROUP *SignerCertGroup,
+                  const CSSM_TP_VERIFY_CONTEXT *SignerVerifyContext,
+                  CSSM_TP_VERIFY_CONTEXT_RESULT_PTR SignerVerifyResult,
+                  CSSM_DATA_PTR SignedCert);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CrlVerify (CSSM_TP_HANDLE TPHandle,
+                   CSSM_CL_HANDLE CLHandle,
+                   CSSM_CSP_HANDLE CSPHandle,
+                   const CSSM_ENCODED_CRL *CrlToBeVerified,
+                   const CSSM_CERTGROUP *SignerCertGroup,
+                   const CSSM_TP_VERIFY_CONTEXT *VerifyContext,
+                   CSSM_TP_VERIFY_CONTEXT_RESULT_PTR RevokerVerifyResult);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CrlCreateTemplate (CSSM_TP_HANDLE TPHandle,
+                           CSSM_CL_HANDLE CLHandle,
+                           uint32 NumberOfFields,
+                           const CSSM_FIELD *CrlFields,
+                           CSSM_DATA_PTR NewCrlTemplate);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertRevoke (CSSM_TP_HANDLE TPHandle,
+                    CSSM_CL_HANDLE CLHandle,
+                    CSSM_CSP_HANDLE CSPHandle,
+                    const CSSM_DATA *OldCrlTemplate,
+                    const CSSM_CERTGROUP *CertGroupToBeRevoked,
+                    const CSSM_CERTGROUP *RevokerCertGroup,
+                    const CSSM_TP_VERIFY_CONTEXT *RevokerVerifyContext,
+                    CSSM_TP_VERIFY_CONTEXT_RESULT_PTR RevokerVerifyResult,
+                    CSSM_TP_CERTCHANGE_REASON Reason,
+                    CSSM_DATA_PTR NewCrlTemplate);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertRemoveFromCrlTemplate (CSSM_TP_HANDLE TPHandle,
+                                   CSSM_CL_HANDLE CLHandle,
+                                   CSSM_CSP_HANDLE CSPHandle,
+                                   const CSSM_DATA *OldCrlTemplate,
+                                   const CSSM_CERTGROUP *CertGroupToBeRemoved,
+                                   const CSSM_CERTGROUP *RevokerCertGroup,
+                                   const CSSM_TP_VERIFY_CONTEXT *RevokerVerifyContext,
+                                   CSSM_TP_VERIFY_CONTEXT_RESULT_PTR RevokerVerifyResult,
+                                   CSSM_DATA_PTR NewCrlTemplate);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CrlSign (CSSM_TP_HANDLE TPHandle,
+                 CSSM_CL_HANDLE CLHandle,
+                 CSSM_CC_HANDLE CCHandle,
+                 const CSSM_ENCODED_CRL *CrlToBeSigned,
+                 const CSSM_CERTGROUP *SignerCertGroup,
+                 const CSSM_TP_VERIFY_CONTEXT *SignerVerifyContext,
+                 CSSM_TP_VERIFY_CONTEXT_RESULT_PTR SignerVerifyResult,
+                 CSSM_DATA_PTR SignedCrl);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_ApplyCrlToDb (CSSM_TP_HANDLE TPHandle,
+                      CSSM_CL_HANDLE CLHandle,
+                      CSSM_CSP_HANDLE CSPHandle,
+                      const CSSM_ENCODED_CRL *CrlToBeApplied,
+                      const CSSM_CERTGROUP *SignerCertGroup,
+                      const CSSM_TP_VERIFY_CONTEXT *ApplyCrlVerifyContext,
+                      CSSM_TP_VERIFY_CONTEXT_RESULT_PTR ApplyCrlVerifyResult);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertGroupConstruct (CSSM_TP_HANDLE TPHandle,
+                            CSSM_CL_HANDLE CLHandle,
+                            CSSM_CSP_HANDLE CSPHandle,
+                            const CSSM_DL_DB_LIST *DBList,
+                            const void *ConstructParams,
+                            const CSSM_CERTGROUP *CertGroupFrag,
+                            CSSM_CERTGROUP_PTR *CertGroup);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertGroupPrune (CSSM_TP_HANDLE TPHandle,
+                        CSSM_CL_HANDLE CLHandle,
+                        const CSSM_DL_DB_LIST *DBList,
+                        const CSSM_CERTGROUP *OrderedCertGroup,
+                        CSSM_CERTGROUP_PTR *PrunedCertGroup);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_CertGroupToTupleGroup (CSSM_TP_HANDLE TPHandle,
+                               CSSM_CL_HANDLE CLHandle,
+                               const CSSM_CERTGROUP *CertGroup,
+                               CSSM_TUPLEGROUP_PTR *TupleGroup);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_TupleGroupToCertGroup (CSSM_TP_HANDLE TPHandle,
+                               CSSM_CL_HANDLE CLHandle,
+                               const CSSM_TUPLEGROUP *TupleGroup,
+                               CSSM_CERTGROUP_PTR *CertTemplates);
+
+CSSM_RETURN CSSMAPI
+CSSM_TP_PassThrough (CSSM_TP_HANDLE TPHandle,
+                     CSSM_CL_HANDLE CLHandle,
+                     CSSM_CC_HANDLE CCHandle,
+                     const CSSM_DL_DB_LIST *DBList,
+                     uint32 PassThroughId,
+                     const void *InputParams,
+                     void **OutputParams);
+
+
+/* Authorization Computation Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_AC_AuthCompute (CSSM_AC_HANDLE ACHandle,
+                     const CSSM_TUPLEGROUP *BaseAuthorizations,
+                     const CSSM_TUPLEGROUP *Credentials,
+                     uint32 NumberOfRequestors,
+                     const CSSM_LIST *Requestors,
+                     const CSSM_LIST *RequestedAuthorizationPeriod,
+                     const CSSM_LIST *RequestedAuthorization,
+                     CSSM_TUPLEGROUP_PTR AuthorizationResult);
+
+CSSM_RETURN CSSMAPI
+CSSM_AC_PassThrough (CSSM_AC_HANDLE ACHandle,
+                     CSSM_TP_HANDLE TPHandle,
+                     CSSM_CL_HANDLE CLHandle,
+                     CSSM_CC_HANDLE CCHandle,
+                     const CSSM_DL_DB_LIST *DBList,
+                     uint32 PassThroughId,
+                     const void *InputParams,
+                     void **OutputParams);
+
+
+/* Certificate Library Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertCreateTemplate (CSSM_CL_HANDLE CLHandle,
+                            uint32 NumberOfFields,
+                            const CSSM_FIELD *CertFields,
+                            CSSM_DATA_PTR CertTemplate);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGetAllTemplateFields (CSSM_CL_HANDLE CLHandle,
+                                  const CSSM_DATA *CertTemplate,
+                                  uint32 *NumberOfFields,
+                                  CSSM_FIELD_PTR *CertFields);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertSign (CSSM_CL_HANDLE CLHandle,
+                  CSSM_CC_HANDLE CCHandle,
+                  const CSSM_DATA *CertTemplate,
+                  const CSSM_FIELD *SignScope,
+                  uint32 ScopeSize,
+                  CSSM_DATA_PTR SignedCert);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertVerify (CSSM_CL_HANDLE CLHandle,
+                    CSSM_CC_HANDLE CCHandle,
+                    const CSSM_DATA *CertToBeVerified,
+                    const CSSM_DATA *SignerCert,
+                    const CSSM_FIELD *VerifyScope,
+                    uint32 ScopeSize);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertVerifyWithKey (CSSM_CL_HANDLE CLHandle,
+                           CSSM_CC_HANDLE CCHandle,
+                           const CSSM_DATA *CertToBeVerified);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGetFirstFieldValue (CSSM_CL_HANDLE CLHandle,
+                                const CSSM_DATA *Cert,
+                                const CSSM_OID *CertField,
+                                CSSM_HANDLE_PTR ResultsHandle,
+                                uint32 *NumberOfMatchedFields,
+                                CSSM_DATA_PTR *Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGetNextFieldValue (CSSM_CL_HANDLE CLHandle,
+                               CSSM_HANDLE ResultsHandle,
+                               CSSM_DATA_PTR *Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertAbortQuery (CSSM_CL_HANDLE CLHandle,
+                        CSSM_HANDLE ResultsHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGetKeyInfo (CSSM_CL_HANDLE CLHandle,
+                        const CSSM_DATA *Cert,
+                        CSSM_KEY_PTR *Key);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGetAllFields (CSSM_CL_HANDLE CLHandle,
+                          const CSSM_DATA *Cert,
+                          uint32 *NumberOfFields,
+                          CSSM_FIELD_PTR *CertFields);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_FreeFields (CSSM_CL_HANDLE CLHandle,
+                    uint32 NumberOfFields,
+                    CSSM_FIELD_PTR *Fields);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_FreeFieldValue (CSSM_CL_HANDLE CLHandle,
+                        const CSSM_OID *CertOrCrlOid,
+                        CSSM_DATA_PTR Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertCache (CSSM_CL_HANDLE CLHandle,
+                   const CSSM_DATA *Cert,
+                   CSSM_HANDLE_PTR CertHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGetFirstCachedFieldValue (CSSM_CL_HANDLE CLHandle,
+                                      CSSM_HANDLE CertHandle,
+                                      const CSSM_OID *CertField,
+                                      CSSM_HANDLE_PTR ResultsHandle,
+                                      uint32 *NumberOfMatchedFields,
+                                      CSSM_DATA_PTR *Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGetNextCachedFieldValue (CSSM_CL_HANDLE CLHandle,
+                                     CSSM_HANDLE ResultsHandle,
+                                     CSSM_DATA_PTR *Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertAbortCache (CSSM_CL_HANDLE CLHandle,
+                        CSSM_HANDLE CertHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGroupToSignedBundle (CSSM_CL_HANDLE CLHandle,
+                                 CSSM_CC_HANDLE CCHandle,
+                                 const CSSM_CERTGROUP *CertGroupToBundle,
+                                 const CSSM_CERT_BUNDLE_HEADER *BundleInfo,
+                                 CSSM_DATA_PTR SignedBundle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertGroupFromVerifiedBundle (CSSM_CL_HANDLE CLHandle,
+                                     CSSM_CC_HANDLE CCHandle,
+                                     const CSSM_CERT_BUNDLE *CertBundle,
+                                     const CSSM_DATA *SignerCert,
+                                     CSSM_CERTGROUP_PTR *CertGroup);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CertDescribeFormat (CSSM_CL_HANDLE CLHandle,
+                            uint32 *NumberOfFields,
+                            CSSM_OID_PTR *OidList);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlCreateTemplate (CSSM_CL_HANDLE CLHandle,
+                           uint32 NumberOfFields,
+                           const CSSM_FIELD *CrlTemplate,
+                           CSSM_DATA_PTR NewCrl);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlSetFields (CSSM_CL_HANDLE CLHandle,
+                      uint32 NumberOfFields,
+                      const CSSM_FIELD *CrlTemplate,
+                      const CSSM_DATA *OldCrl,
+                      CSSM_DATA_PTR ModifiedCrl);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlAddCert (CSSM_CL_HANDLE CLHandle,
+                    CSSM_CC_HANDLE CCHandle,
+                    const CSSM_DATA *Cert,
+                    uint32 NumberOfFields,
+                    const CSSM_FIELD *CrlEntryFields,
+                    const CSSM_DATA *OldCrl,
+                    CSSM_DATA_PTR NewCrl);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlRemoveCert (CSSM_CL_HANDLE CLHandle,
+                       const CSSM_DATA *Cert,
+                       const CSSM_DATA *OldCrl,
+                       CSSM_DATA_PTR NewCrl);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlSign (CSSM_CL_HANDLE CLHandle,
+                 CSSM_CC_HANDLE CCHandle,
+                 const CSSM_DATA *UnsignedCrl,
+                 const CSSM_FIELD *SignScope,
+                 uint32 ScopeSize,
+                 CSSM_DATA_PTR SignedCrl);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlVerify (CSSM_CL_HANDLE CLHandle,
+                   CSSM_CC_HANDLE CCHandle,
+                   const CSSM_DATA *CrlToBeVerified,
+                   const CSSM_DATA *SignerCert,
+                   const CSSM_FIELD *VerifyScope,
+                   uint32 ScopeSize);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlVerifyWithKey (CSSM_CL_HANDLE CLHandle,
+                          CSSM_CC_HANDLE CCHandle,
+                          const CSSM_DATA *CrlToBeVerified);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_IsCertInCrl (CSSM_CL_HANDLE CLHandle,
+                     const CSSM_DATA *Cert,
+                     const CSSM_DATA *Crl,
+                     CSSM_BOOL *CertFound);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlGetFirstFieldValue (CSSM_CL_HANDLE CLHandle,
+                               const CSSM_DATA *Crl,
+                               const CSSM_OID *CrlField,
+                               CSSM_HANDLE_PTR ResultsHandle,
+                               uint32 *NumberOfMatchedFields,
+                               CSSM_DATA_PTR *Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlGetNextFieldValue (CSSM_CL_HANDLE CLHandle,
+                              CSSM_HANDLE ResultsHandle,
+                              CSSM_DATA_PTR *Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlAbortQuery (CSSM_CL_HANDLE CLHandle,
+                       CSSM_HANDLE ResultsHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlGetAllFields (CSSM_CL_HANDLE CLHandle,
+                         const CSSM_DATA *Crl,
+                         uint32 *NumberOfCrlFields,
+                         CSSM_FIELD_PTR *CrlFields);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlCache (CSSM_CL_HANDLE CLHandle,
+                  const CSSM_DATA *Crl,
+                  CSSM_HANDLE_PTR CrlHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_IsCertInCachedCrl (CSSM_CL_HANDLE CLHandle,
+                           const CSSM_DATA *Cert,
+                           CSSM_HANDLE CrlHandle,
+                           CSSM_BOOL *CertFound,
+                           CSSM_DATA_PTR CrlRecordIndex);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlGetFirstCachedFieldValue (CSSM_CL_HANDLE CLHandle,
+                                     CSSM_HANDLE CrlHandle,
+                                     const CSSM_DATA *CrlRecordIndex,
+                                     const CSSM_OID *CrlField,
+                                     CSSM_HANDLE_PTR ResultsHandle,
+                                     uint32 *NumberOfMatchedFields,
+                                     CSSM_DATA_PTR *Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlGetNextCachedFieldValue (CSSM_CL_HANDLE CLHandle,
+                                    CSSM_HANDLE ResultsHandle,
+                                    CSSM_DATA_PTR *Value);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlGetAllCachedRecordFields (CSSM_CL_HANDLE CLHandle,
+                                     CSSM_HANDLE CrlHandle,
+                                     const CSSM_DATA *CrlRecordIndex,
+                                     uint32 *NumberOfFields,
+                                     CSSM_FIELD_PTR *CrlFields);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlAbortCache (CSSM_CL_HANDLE CLHandle,
+                       CSSM_HANDLE CrlHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_CrlDescribeFormat (CSSM_CL_HANDLE CLHandle,
+                           uint32 *NumberOfFields,
+                           CSSM_OID_PTR *OidList);
+
+CSSM_RETURN CSSMAPI
+CSSM_CL_PassThrough (CSSM_CL_HANDLE CLHandle,
+                     CSSM_CC_HANDLE CCHandle,
+                     uint32 PassThroughId,
+                     const void *InputParams,
+                     void **OutputParams);
+
+
+/* Data Storage Library Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DbOpen (CSSM_DL_HANDLE DLHandle,
+                const char *DbName,
+                const CSSM_NET_ADDRESS *DbLocation,
+                CSSM_DB_ACCESS_TYPE AccessRequest,
+                const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                const void *OpenParameters,
+                CSSM_DB_HANDLE *DbHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DbClose (CSSM_DL_DB_HANDLE DLDBHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DbCreate (CSSM_DL_HANDLE DLHandle,
+                  const char *DbName,
+                  const CSSM_NET_ADDRESS *DbLocation,
+                  const CSSM_DBINFO *DBInfo,
+                  CSSM_DB_ACCESS_TYPE AccessRequest,
+                  const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                  const void *OpenParameters,
+                  CSSM_DB_HANDLE *DbHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DbDelete (CSSM_DL_HANDLE DLHandle,
+                  const char *DbName,
+                  const CSSM_NET_ADDRESS *DbLocation,
+                  const CSSM_ACCESS_CREDENTIALS *AccessCred);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_CreateRelation (CSSM_DL_DB_HANDLE DLDBHandle,
+                        CSSM_DB_RECORDTYPE RelationID,
+                        const char *RelationName,
+                        uint32 NumberOfAttributes,
+                        const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
+                        uint32 NumberOfIndexes,
+                        const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DestroyRelation (CSSM_DL_DB_HANDLE DLDBHandle,
+                         CSSM_DB_RECORDTYPE RelationID);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_Authenticate (CSSM_DL_DB_HANDLE DLDBHandle,
+                      CSSM_DB_ACCESS_TYPE AccessRequest,
+                      const CSSM_ACCESS_CREDENTIALS *AccessCred);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_GetDbAcl (CSSM_DL_DB_HANDLE DLDBHandle,
+                  const CSSM_STRING *SelectionTag,
+                  uint32 *NumberOfAclInfos,
+                  CSSM_ACL_ENTRY_INFO_PTR *AclInfos);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_ChangeDbAcl (CSSM_DL_DB_HANDLE DLDBHandle,
+                     const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                     const CSSM_ACL_EDIT *AclEdit);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_GetDbOwner (CSSM_DL_DB_HANDLE DLDBHandle,
+                    CSSM_ACL_OWNER_PROTOTYPE_PTR Owner);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_ChangeDbOwner (CSSM_DL_DB_HANDLE DLDBHandle,
+                       const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                       const CSSM_ACL_OWNER_PROTOTYPE *NewOwner);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_GetDbNames (CSSM_DL_HANDLE DLHandle,
+                    CSSM_NAME_LIST_PTR *NameList);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_GetDbNameFromHandle (CSSM_DL_DB_HANDLE DLDBHandle,
+                             char **DbName);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_FreeNameList (CSSM_DL_HANDLE DLHandle,
+                      CSSM_NAME_LIST_PTR NameList);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DataInsert (CSSM_DL_DB_HANDLE DLDBHandle,
+                    CSSM_DB_RECORDTYPE RecordType,
+                    const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes,
+                    const CSSM_DATA *Data,
+                    CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DataDelete (CSSM_DL_DB_HANDLE DLDBHandle,
+                    const CSSM_DB_UNIQUE_RECORD *UniqueRecordIdentifier);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DataModify (CSSM_DL_DB_HANDLE DLDBHandle,
+                    CSSM_DB_RECORDTYPE RecordType,
+                    CSSM_DB_UNIQUE_RECORD_PTR UniqueRecordIdentifier,
+                    const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified,
+                    const CSSM_DATA *DataToBeModified,
+                    CSSM_DB_MODIFY_MODE ModifyMode);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DataGetFirst (CSSM_DL_DB_HANDLE DLDBHandle,
+                      const CSSM_QUERY *Query,
+                      CSSM_HANDLE_PTR ResultsHandle,
+                      CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                      CSSM_DATA_PTR Data,
+                      CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DataGetNext (CSSM_DL_DB_HANDLE DLDBHandle,
+                     CSSM_HANDLE ResultsHandle,
+                     CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                     CSSM_DATA_PTR Data,
+                     CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DataAbortQuery (CSSM_DL_DB_HANDLE DLDBHandle,
+                        CSSM_HANDLE ResultsHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_DataGetFromUniqueRecordId (CSSM_DL_DB_HANDLE DLDBHandle,
+                              const CSSM_DB_UNIQUE_RECORD *UniqueRecord,
+                              CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                              CSSM_DATA_PTR Data);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_FreeUniqueRecord (CSSM_DL_DB_HANDLE DLDBHandle,
+                          CSSM_DB_UNIQUE_RECORD_PTR UniqueRecord);
+
+CSSM_RETURN CSSMAPI
+CSSM_DL_PassThrough (CSSM_DL_DB_HANDLE DLDBHandle,
+                uint32 PassThroughId,
+                const void *InputParams,
+                void **OutputParams);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMAPI_H_ */
diff --git a/cdsa/cdsa/cssmapple.h b/cdsa/cdsa/cssmapple.h
new file mode 100644
index 00000000..aadec454
--- /dev/null
+++ b/cdsa/cdsa/cssmapple.h
@@ -0,0 +1,413 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmapple.h
+
+   Contains:  CSSM features specific to Apple's Implementation
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMAPPLE_H_
+#define _CSSMAPPLE_H_  1
+
+#include <Security/cssmerr.h>
+#include <Security/cssmtype.h>
+#include <sys/types.h>	/* for the BSD *_t types */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Guids for standard Apple addin modules. */
+
+/* {87191ca0-0fc9-11d4-849a-000502b52122} */
+extern const CSSM_GUID gGuidCssm;
+
+/* {87191ca1-0fc9-11d4-849a-000502b52122} */
+extern const CSSM_GUID gGuidAppleFileDL;
+
+/* {87191ca2-0fc9-11d4-849a-000502b52122} */
+extern const CSSM_GUID gGuidAppleCSP;
+
+/* {87191ca3-0fc9-11d4-849a-000502b52122} */
+extern const CSSM_GUID gGuidAppleCSPDL;
+
+/* {87191ca4-0fc9-11d4-849a-000502b52122} */
+extern const CSSM_GUID gGuidAppleX509CL;
+
+/* {87191ca5-0fc9-11d4-849a-000502b52122} */
+extern const CSSM_GUID gGuidAppleX509TP;
+
+
+/* Apple defined WORDID values */
+enum
+{
+	CSSM_WORDID_KEYCHAIN_PROMPT = CSSM_WORDID_VENDOR_START,
+    CSSM_WORDID_KEYCHAIN_LOCK,
+    CSSM_WORDID_KEYCHAIN_CHANGE_LOCK,
+	CSSM_WORDID_PROCESS,
+	CSSM_WORDID__FIRST_UNUSED
+};
+
+/* Apple defined ACL subject and credential types */
+enum
+{
+	CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT = CSSM_WORDID_KEYCHAIN_PROMPT,
+	CSSM_ACL_SUBJECT_TYPE_PROCESS = CSSM_WORDID_PROCESS,
+	CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE = CSSM_WORDID_SIGNATURE,
+	CSSM_ACL_SUBJECT_TYPE_COMMENT = CSSM_WORDID_COMMENT
+};
+
+enum
+{
+	CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT = CSSM_WORDID_KEYCHAIN_PROMPT,
+    CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK = CSSM_WORDID_KEYCHAIN_LOCK,
+    CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK = CSSM_WORDID_KEYCHAIN_CHANGE_LOCK,
+	CSSM_SAMPLE_TYPE_PROCESS = CSSM_WORDID_PROCESS,
+	CSSM_SAMPLE_TYPE_COMMENT = CSSM_WORDID_COMMENT,
+	CSSM_SAMPLE_TYPE_RETRY_ID = CSSM_WORDID_PROPAGATE
+};
+
+
+/* Apple-defined ACL authorization tags */
+enum {
+	CSSM_ACL_AUTHORIZATION_CHANGE_ACL = CSSM_ACL_AUTHORIZATION_TAG_VENDOR_DEFINED_START,
+	CSSM_ACL_AUTHORIZATION_CHANGE_OWNER
+};
+
+
+/* Parameters and structures for Apple-defined ACL subjects and samples */
+
+enum {	/* types of code signatures - item 1 of CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE subjects */
+    CSSM_ACL_CODE_SIGNATURE_INVALID = 0, /* standard OS X code signature */
+    CSSM_ACL_CODE_SIGNATURE_OSX = 1		/* standard OS X code signature */
+};
+
+
+enum {	/* PROCESS_SUBJECT mask fields */
+    CSSM_ACL_MATCH_UID = 0x01,			/* match userid against uid field */
+    CSSM_ACL_MATCH_GID = 0x02,			/* match groupid against gid field */
+    CSSM_ACL_MATCH_HONOR_ROOT = 0x100,	/* let root (uid 0) match any userid */
+    CSSM_ACL_MATCH_BITS = CSSM_ACL_MATCH_UID | CSSM_ACL_MATCH_GID
+};
+
+enum {	/* PROCESS_SUBJECT structure version field */
+    CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION = 0x101
+};
+
+typedef struct cssm_acl_process_subject_selector {	/* PROCESS_SUBJECT selector */
+    uint16 version;			/* version of this selector */
+    uint16 mask;			/* active fields mask */
+    uid_t uid;				/* effective user id match */
+    gid_t gid;				/* effective group id match */
+} CSSM_ACL_PROCESS_SUBJECT_SELECTOR;
+
+
+/* Apple defined algorithm IDs */
+enum
+{
+    CSSM_ALGID_APPLE_YARROW = CSSM_ALGID_VENDOR_DEFINED,
+	CSSM_ALGID_AES,				/* RijnDael */
+	CSSM_ALGID_FEE,				/* FEE Key Generation */ 
+	CSSM_ALGID_FEE_MD5,			/* FEE/ElGamal signature w/ MD5 hash */
+	CSSM_ALGID_FEE_SHA1,		/* FEE/ElGamal signature w/ SHA1 hash */
+	CSSM_ALGID_FEED,			/* 1:1 FEE asymmetric encryption */
+	CSSM_ALGID_FEEDEXP,			/* 2:1 FEE asymmetric encryption */
+	CSSM_ALGID_ASC,				/* Apple Secure Compression */
+	CSSM_ALGID_SHA1HMAC_LEGACY,	/* HMAC/SHA1, legacy compatible */
+    CSSM_ALGID__FIRST_UNUSED
+};
+
+
+/* Apple adds some "common" error codes. CDSA does not define an official start value for this. */
+enum
+{
+    CSSM_CUSTOM_COMMON_ERROR_EXTENT = 0x00e0,
+    
+    CSSM_ERRCODE_NO_USER_INTERACTION =				0x00e0,
+    CSSM_ERRCODE_USER_CANCELED =					0x00e1,
+	CSSM_ERRCODE_SERVICE_NOT_AVAILABLE =			0x00e2
+};
+
+enum {
+	CSSMERR_CSSM_NO_USER_INTERACTION = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION,
+	CSSMERR_AC_NO_USER_INTERACTION = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION,
+	CSSMERR_CSP_NO_USER_INTERACTION = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION,
+	CSSMERR_CL_NO_USER_INTERACTION = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION,
+	CSSMERR_DL_NO_USER_INTERACTION = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION,
+	CSSMERR_TP_NO_USER_INTERACTION = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION,
+	
+	CSSMERR_CSSM_USER_CANCELED = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED,
+	CSSMERR_AC_USER_CANCELED = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED,
+	CSSMERR_CSP_USER_CANCELED = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED,
+	CSSMERR_CL_USER_CANCELED = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED,
+	CSSMERR_DL_USER_CANCELED = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED,
+	CSSMERR_TP_USER_CANCELED = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED,
+
+	CSSMERR_CSSM_SERVICE_NOT_AVAILABLE = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE,
+	CSSMERR_AC_SERVICE_NOT_AVAILABLE = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE,
+	CSSMERR_CSP_SERVICE_NOT_AVAILABLE = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE,
+	CSSMERR_CL_SERVICE_NOT_AVAILABLE = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE,
+	CSSMERR_DL_SERVICE_NOT_AVAILABLE = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE,
+	CSSMERR_TP_SERVICE_NOT_AVAILABLE = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE
+};
+
+/* AppleCSPDL private error codes. */
+enum {
+	CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT = CSSM_CSP_PRIVATE_ERROR + 0
+};
+
+
+/* AppleFileDL record types. */
+enum
+{
+    CSSM_DL_DB_RECORD_GENERIC_PASSWORD = CSSM_DB_RECORDTYPE_APP_DEFINED_START + 0,
+    CSSM_DL_DB_RECORD_INTERNET_PASSWORD = CSSM_DB_RECORDTYPE_APP_DEFINED_START + 1,
+    CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD = CSSM_DB_RECORDTYPE_APP_DEFINED_START + 2
+};
+
+/* AppleFileDL extentions: passthrough ids */
+enum {
+	// Toggle whether or not to autocommit after modifying the database.
+	// The input parameter is a CSSM_BOOL, where TRUE turns autocommit on
+	// and FALSE turns it off.
+	CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT,
+	
+	// Commit any pending changes to the database.
+	CSSM_APPLEFILEDL_COMMIT,
+	
+	// Rollback and discard any pending changes to the database.
+	CSSM_APPLEFILEDL_ROLLBACK
+};
+
+/* Apple DL private error codes. */
+enum
+{
+	/* The OpenParameters argument passed to CSSM_DL_DbCreate or CSSM_DL_DbOpen
+	   was neither NULL nor a pointer to a valid CSSM_APPLEDL_OPEN_PARAMETERS
+	   structure. */
+	CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS =		CSSM_DL_PRIVATE_ERROR + 0,
+	
+	/* an operation failed because the disk was full */
+	CSSMERR_APPLEDL_DISK_FULL = 					CSSM_DL_PRIVATE_ERROR + 1,
+	
+	/* an operation failed because a disk quote was exceeded */
+	CSSMERR_APPLEDL_QUOTA_EXCEEDED =				CSSM_DL_PRIVATE_ERROR + 2,
+	
+	/* an operation failed because a file was too large */
+	CSSMERR_APPLEDL_FILE_TOO_BIG = 					CSSM_DL_PRIVATE_ERROR + 3,
+    
+    /* a keychain database's internal information ("blob") is invalid */
+    CSSMERR_APPLEDL_INVALID_DATABASE_BLOB =			CSSM_DL_PRIVATE_ERROR + 4,
+    CSSMERR_APPLEDL_INVALID_KEY_BLOB =				CSSM_DL_PRIVATE_ERROR + 5,
+    
+    /* the internal data format version for a database's internal information ("blob") is invalid */
+    CSSMERR_APPLEDL_INCOMPATIBLE_DATABASE_BLOB =	CSSM_DL_PRIVATE_ERROR + 6,
+    CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB =			CSSM_DL_PRIVATE_ERROR + 7,    
+};
+
+enum
+{
+	CSSM_APPLEDL_OPEN_PARAMETERS_VERSION =			0
+};
+
+/* Pass a CSSM_APPLEDL_OPEN_PARAMETERS_PTR as the OpenParameters argument to
+   CSSM_DL_DbCreate or CSSM_DL_DbOpen. */
+typedef struct cssm_appledl_open_parameters
+{
+	uint32 length;	/* Should be sizeof(CSSM_APPLEDL_OPEN_PARAMETERS). */
+	uint32 version;	/* Should be CSSM_APPLEDL_OPEN_PARAMETERS_VERSION. */
+
+	/* If no OpenParameters are specified autoCommit is on (!CSSM_FALSE) by default.
+	   When autoCommit is on (!CSSM_FALSE) changes made to the Db are written to disk
+	   before returning from each function.
+	   When autoCommit is off (CSSM_FALSE) changes made to the database are not guaranteed
+	   to be written to disk until the Db is closed.  This is useful for bulk writes.
+	   Beware that if autoCommit is off changes made in previous calls to the DL might
+	   get rolled back if a new modification operation fails. */
+	CSSM_BOOL autoCommit;
+} CSSM_APPLEDL_OPEN_PARAMETERS, *CSSM_APPLEDL_OPEN_PARAMETERS_PTR;
+
+
+/* AppleCSPDL passthough ids */
+enum
+{
+	/* Tell the SecurityServer to lock the database specified by the DLDBHandle argument.
+	   The InputParams and OutputParams arguments are ignored. */
+	CSSM_APPLECSPDL_DB_LOCK =			0,
+
+	/* Tell the SecurityServer to unlock the database specified by the DLDBHandle argument.
+	   The InputParameters argument is a CSSM_DATA_PTR containing the password. Or NULL if
+	   the SecurityServer should prompt for the password.
+	   The OutputParams argument is ignored.
+	   The SecurityServer will put up UI (though the SecurityAgent) when this function is called
+	   iff InputParameters is NULL.  */
+	CSSM_APPLECSPDL_DB_UNLOCK =			1,
+
+	/* Ask the SecurityServer to get the db settings specified for the database
+	   specified by the DLDBHandle argument.  The settings are returned in the OutputParameters argument.
+	   The OutputParameters argument is a pointer to a CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR.
+	   Upon successful completion the AppleCSPDL will have allocated a
+	   CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS structure using the application specified
+	   allocators for the DL attachment specified by the DLDBHandle argument.  The structure will contain
+	   the current database settings for the specified database.  The client should free the
+	   CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR after it has finished using it.
+	   The InputParameters argument is ignored.
+	   The SecurityServer might put up UI (though the SecurityAgent) when this function is called.  */
+	CSSM_APPLECSPDL_DB_GET_SETTINGS =	2,
+
+	/* Tell the SecurityServer to set the db settings specified in InputParameters on the database
+	   specified by the DLDBHandle argument.
+	   The InputParameters argument is a const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS * containing
+	   the new settings for the specified database.
+	   The OutputParams argument is ignored.
+	   The SecurityServer might put up UI (though the SecurityAgent) when this function is called.  */
+	CSSM_APPLECSPDL_DB_SET_SETTINGS =	3,
+
+	/* Ask the SecurityServer whether the database specified by the DLDBHandle argument is locked.
+	   The InputParameters argument is ignored.
+	   The OutputParameters argument is a pointer to a CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR.
+	   Upon successful completion the AppleCSPDL will have allocated a
+	   CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS structure using the application specified
+	   allocators for the DL attachment specified by the DLDBHandle argument.  The structure will contain
+	   the current lock status for the specified database.  The client should free the
+	   CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR after it has finished using it.
+	   The SecurityServer will put up UI (though the SecurityAgent) when this function is called. */
+	CSSM_APPLECSPDL_DB_IS_LOCKED =		4,
+
+	/* Tell the SecurityServer to change the password for the database specified by
+	   the DLDBHandle.
+
+	   The InputParameters argument is a const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS * containing
+	   a CSSM_ACCESS_CREDENTIALS * which determines how the password will be changed.  If the
+	   accessCredentials are NULL the SecurityAgent will prompt for the old and the new password for the
+	   specified database.  If credentials are specified there should be 2 entries.  First a 3 element
+	   list containing:
+	   CSSM_WORDID_KEYCHAIN_LOCK, CSSM_SAMPLE_TYPE_PASSWORD, and the old password.
+	   Second a 3 element list containing:
+	   CSSM_WORDID_KEYCHAIN_CHANGE_LOCK, CSSM_SAMPLE_TYPE_PASSWORD, and the new password.
+
+	   The OutputParams argument is ignored.
+	   The SecurityServer might put up UI (though the SecurityAgent) when this function is called.  */
+	CSSM_APPLECSPDL_DB_CHANGE_PASSWORD =5,
+
+	
+	/* Given a CSSM_KEY_PTR in any format, obtain the SSHA-1 hash of the 
+	 * associated key blob. 
+	 * Key is specified in CSSM_CSP_CreatePassThroughContext.
+	 * Hash is allocated bythe CSP, in the App's memory, and returned
+	 * in *outData. */
+	CSSM_APPLECSP_KEYDIGEST = 			0x100	
+};
+
+/* AppleCSPDL passthough parameters */
+typedef struct cssm_applecspdl_db_settings_parameters
+{
+	uint32 idleTimeout;				// seconds idle timeout lock
+	uint8 lockOnSleep;				// lock database when system sleeps
+} CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS, *CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR;
+
+/* AppleCSPDL passthough parameters */
+typedef struct cssm_applecspdl_db_is_locked_parameters
+{
+	uint8 isLocked;				// True iff the database is locked
+} CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS, *CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR;
+
+/* AppleCSPDL passthough parameters */
+typedef struct cssm_applecspdl_db_change_password_parameters
+{
+	CSSM_ACCESS_CREDENTIALS *accessCredentials;
+} CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS, *CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS_PTR;
+
+/* Custom wrapped key format */
+enum {
+	CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM = 100
+};
+
+/* 
+ * Optional argument for X509TP's CertGroupVerify. Instructs TP to
+ * ignore "certificate expired" error conditions. Expressed in 
+ * CSSM_TP_CALLERAUTH_CONTEXT.Policy.PolicyControl. 
+ */
+#define CSSM_TP_ALLOW_EXPIRE	((void *)0x55)
+
+/*
+ * Structure containing parameters for the MDS DbOpen() function.
+ */
+ 
+#define MDS_APPLE_OPEN_LOCAL_DB    ((uint32) (1 << 0))
+#define MDS_APPLE_CREATE_LOCAL_DB  ((uint32) (1 << 1))
+
+typedef struct mds_apple_open_parameters
+{
+	uint32 version;
+	uint32 openFlags;
+} MDS_APPLE_OPEN_PARAMETERS, *MDS_APPLE_OPEN_PARAMETERS_PTR;
+
+/*
+ * Custom context attributes for AppleCSP.
+ */
+enum {
+	CSSM_ATTRIBUTE_VENDOR_DEFINED	= 0x800000
+};
+
+enum {
+	/* 
+	 * Public Key attribute for use with CSSM_ALGID_FEED.
+	 */
+    CSSM_ATTRIBUTE_PUBLIC_KEY =		
+			(CSSM_ATTRIBUTE_DATA_KEY | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 0)),
+			
+	/*
+	 * FEE key attributes.
+	 * See CSSM_FEE_PRIME_TYPE_xxx, CSSM_FEE_CURVE_TYPE_xxx enumsm below.
+	 */
+	CSSM_ATTRIBUTE_FEE_PRIME_TYPE = 
+			(CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 1)),
+	CSSM_ATTRIBUTE_FEE_CURVE_TYPE = 
+			(CSSM_ATTRIBUTE_DATA_UINT32 | (CSSM_ATTRIBUTE_VENDOR_DEFINED + 2)),
+};
+
+/*
+ * FEE key pair prime modulus types.
+ */
+enum {
+	CSSM_FEE_PRIME_TYPE_DEFAULT,		/* default per key size */
+	CSSM_FEE_PRIME_TYPE_MERSENNE,		/* (2 ** q) - 1Ê*/
+	CSSM_FEE_PRIME_TYPE_FEE,			/* (2 ** q) - k */
+	CSSM_FEE_PRIME_TYPE_GENERAL			/* random prime */
+};
+
+/*
+ * FEE curve types. Comments refer to equation
+ *
+ *    y**2 = x**3 + c(x**2) + ax + b
+ */
+enum {
+	CSSM_FEE_CURVE_TYPE_DEFAULT,		/* default per key size */
+	CSSM_FEE_CURVE_TYPE_MONTGOMERY,		/* a==1, b==0 */
+	CSSM_FEE_CURVE_TYPE_WEIERSTRASS		/* c==0. IEEE P1363 compliant. */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMAPPLE_H_ */
diff --git a/cdsa/cdsa/cssmcli.h b/cdsa/cdsa/cssmcli.h
new file mode 100644
index 00000000..d420715e
--- /dev/null
+++ b/cdsa/cdsa/cssmcli.h
@@ -0,0 +1,243 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmcli.h
+
+   Contains:  Service Provider Interface for Certificate Library Modules
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMCLI_H_
+#define _CSSMCLI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct cssm_spi_cl_funcs {
+    CSSM_RETURN (CSSMCLI *CertCreateTemplate)
+        (CSSM_CL_HANDLE CLHandle,
+         uint32 NumberOfFields,
+         const CSSM_FIELD *CertFields,
+         CSSM_DATA_PTR CertTemplate);
+    CSSM_RETURN (CSSMCLI *CertGetAllTemplateFields)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *CertTemplate,
+         uint32 *NumberOfFields,
+         CSSM_FIELD_PTR *CertFields);
+    CSSM_RETURN (CSSMCLI *CertSign)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *CertTemplate,
+         const CSSM_FIELD *SignScope,
+         uint32 ScopeSize,
+         CSSM_DATA_PTR SignedCert);
+    CSSM_RETURN (CSSMCLI *CertVerify)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *CertToBeVerified,
+         const CSSM_DATA *SignerCert,
+         const CSSM_FIELD *VerifyScope,
+         uint32 ScopeSize);
+    CSSM_RETURN (CSSMCLI *CertVerifyWithKey)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *CertToBeVerified);
+    CSSM_RETURN (CSSMCLI *CertGetFirstFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Cert,
+         const CSSM_OID *CertField,
+         CSSM_HANDLE_PTR ResultsHandle,
+         uint32 *NumberOfMatchedFields,
+         CSSM_DATA_PTR *Value);
+    CSSM_RETURN (CSSMCLI *CertGetNextFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE ResultsHandle,
+         CSSM_DATA_PTR *Value);
+    CSSM_RETURN (CSSMCLI *CertAbortQuery)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE ResultsHandle);
+    CSSM_RETURN (CSSMCLI *CertGetKeyInfo)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Cert,
+         CSSM_KEY_PTR *Key);
+    CSSM_RETURN (CSSMCLI *CertGetAllFields)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Cert,
+         uint32 *NumberOfFields,
+         CSSM_FIELD_PTR *CertFields);
+	CSSM_RETURN (CSSMCLI *FreeFields)
+		(CSSM_CL_HANDLE CLHandle,
+		 uint32 NumberOfFields,
+		 CSSM_FIELD_PTR *FieldArray);
+    CSSM_RETURN (CSSMCLI *FreeFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_OID *CertOrCrlOid,
+         CSSM_DATA_PTR Value);
+    CSSM_RETURN (CSSMCLI *CertCache)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Cert,
+         CSSM_HANDLE_PTR CertHandle);
+    CSSM_RETURN (CSSMCLI *CertGetFirstCachedFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE CertHandle,
+         const CSSM_OID *CertField,
+         CSSM_HANDLE_PTR ResultsHandle,
+         uint32 *NumberOfMatchedFields,
+         CSSM_DATA_PTR *Value);
+    CSSM_RETURN (CSSMCLI *CertGetNextCachedFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE ResultsHandle,
+         CSSM_DATA_PTR *Value);
+    CSSM_RETURN (CSSMCLI *CertAbortCache)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE CertHandle);
+    CSSM_RETURN (CSSMCLI *CertGroupToSignedBundle)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CERTGROUP *CertGroupToBundle,
+         const CSSM_CERT_BUNDLE_HEADER *BundleInfo,
+         CSSM_DATA_PTR SignedBundle);
+    CSSM_RETURN (CSSMCLI *CertGroupFromVerifiedBundle)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CERT_BUNDLE *CertBundle,
+         const CSSM_DATA *SignerCert,
+         CSSM_CERTGROUP_PTR *CertGroup);
+    CSSM_RETURN (CSSMCLI *CertDescribeFormat)
+        (CSSM_CL_HANDLE CLHandle,
+         uint32 *NumberOfFields,
+         CSSM_OID_PTR *OidList);
+    CSSM_RETURN (CSSMCLI *CrlCreateTemplate)
+        (CSSM_CL_HANDLE CLHandle,
+         uint32 NumberOfFields,
+         const CSSM_FIELD *CrlTemplate,
+         CSSM_DATA_PTR NewCrl);
+    CSSM_RETURN (CSSMCLI *CrlSetFields)
+        (CSSM_CL_HANDLE CLHandle,
+         uint32 NumberOfFields,
+         const CSSM_FIELD *CrlTemplate,
+         const CSSM_DATA *OldCrl,
+         CSSM_DATA_PTR ModifiedCrl);
+    CSSM_RETURN (CSSMCLI *CrlAddCert)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *Cert,
+         uint32 NumberOfFields,
+         const CSSM_FIELD *CrlEntryFields,
+         const CSSM_DATA *OldCrl,
+         CSSM_DATA_PTR NewCrl);
+    CSSM_RETURN (CSSMCLI *CrlRemoveCert)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Cert,
+         const CSSM_DATA *OldCrl,
+         CSSM_DATA_PTR NewCrl);
+    CSSM_RETURN (CSSMCLI *CrlSign)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *UnsignedCrl,
+         const CSSM_FIELD *SignScope,
+         uint32 ScopeSize,
+         CSSM_DATA_PTR SignedCrl);
+    CSSM_RETURN (CSSMCLI *CrlVerify)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *CrlToBeVerified,
+         const CSSM_DATA *SignerCert,
+         const CSSM_FIELD *VerifyScope,
+         uint32 ScopeSize);
+    CSSM_RETURN (CSSMCLI *CrlVerifyWithKey)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *CrlToBeVerified);
+    CSSM_RETURN (CSSMCLI *IsCertInCrl)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Cert,
+         const CSSM_DATA *Crl,
+         CSSM_BOOL *CertFound);
+    CSSM_RETURN (CSSMCLI *CrlGetFirstFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Crl,
+         const CSSM_OID *CrlField,
+         CSSM_HANDLE_PTR ResultsHandle,
+         uint32 *NumberOfMatchedFields,
+         CSSM_DATA_PTR *Value);
+    CSSM_RETURN (CSSMCLI *CrlGetNextFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE ResultsHandle,
+         CSSM_DATA_PTR *Value);
+    CSSM_RETURN (CSSMCLI *CrlAbortQuery)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE ResultsHandle);
+    CSSM_RETURN (CSSMCLI *CrlGetAllFields)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Crl,
+         uint32 *NumberOfCrlFields,
+         CSSM_FIELD_PTR *CrlFields);
+    CSSM_RETURN (CSSMCLI *CrlCache)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Crl,
+         CSSM_HANDLE_PTR CrlHandle);
+    CSSM_RETURN (CSSMCLI *IsCertInCachedCrl)
+        (CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *Cert,
+         CSSM_HANDLE CrlHandle,
+         CSSM_BOOL *CertFound,
+         CSSM_DATA_PTR CrlRecordIndex);
+    CSSM_RETURN (CSSMCLI *CrlGetFirstCachedFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE CrlHandle,
+         const CSSM_DATA *CrlRecordIndex,
+         const CSSM_OID *CrlField,
+         CSSM_HANDLE_PTR ResultsHandle,
+         uint32 *NumberOfMatchedFields,
+         CSSM_DATA_PTR *Value);
+    CSSM_RETURN (CSSMCLI *CrlGetNextCachedFieldValue)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE ResultsHandle,
+         CSSM_DATA_PTR *Value);
+    CSSM_RETURN (CSSMCLI *CrlGetAllCachedRecordFields)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE CrlHandle,
+         const CSSM_DATA *CrlRecordIndex,
+         uint32 *NumberOfFields,
+         CSSM_FIELD_PTR *CrlFields);
+    CSSM_RETURN (CSSMCLI *CrlAbortCache)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_HANDLE CrlHandle);
+    CSSM_RETURN (CSSMCLI *CrlDescribeFormat)
+        (CSSM_CL_HANDLE CLHandle,
+         uint32 *NumberOfFields,
+         CSSM_OID_PTR *OidList);
+    CSSM_RETURN (CSSMCLI *PassThrough)
+        (CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         uint32 PassThroughId,
+         const void *InputParams,
+         void **OutputParams);
+} CSSM_SPI_CL_FUNCS, *CSSM_SPI_CL_FUNCS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMCLI_H_ */
diff --git a/cdsa/cdsa/cssmconfig.h b/cdsa/cdsa/cssmconfig.h
new file mode 100644
index 00000000..e0293978
--- /dev/null
+++ b/cdsa/cdsa/cssmconfig.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmconfig.h
+
+   Contains:  Platform specific defines and typedefs for cdsa.
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMCONFIG_H_
+#define _CSSMCONFIG_H_  1
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h>
+
+/* #if defined(TARGET_API_MAC_OS8) || defined(TARGET_API_MAC_CARBON) || defined(TARGET_API_MAC_OSX) */
+#if defined(TARGET_OS_MAC)
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#else
+#error Unknown API architecture.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef SInt64 sint64;
+typedef UInt64 uint64;
+typedef SInt32 sint32;
+typedef SInt16 sint16;
+typedef SInt8 sint8;
+typedef UInt32 uint32;
+typedef UInt16 uint16;
+typedef UInt8 uint8;
+
+#if 0
+#define CSSM_EXTERN(_type) EXTERN_API_C(_type)
+#define CSSM_DEFINE(_type) DEFINE_API_C(_type)
+#define CSSM_CALLBACK(_type, _name) CALLBACK_API_C(_type, _name)
+#else
+#define CSSMACI
+#define CSSMAPI
+#define CSSMCLI
+#define CSSMCSPI
+#define CSSMDLI
+#define CSSMKRI
+#define CSSMSPI
+#define CSSMTPI
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMCONFIG_H_ */
diff --git a/cdsa/cdsa/cssmcspi.h b/cdsa/cdsa/cssmcspi.h
new file mode 100644
index 00000000..52b7a505
--- /dev/null
+++ b/cdsa/cdsa/cssmcspi.h
@@ -0,0 +1,368 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmcspi.h
+
+   Contains:  Service Provider Interface for
+              Cryptographic Service Provider Modules
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMCSPI_H_
+#define _CSSMCSPI_H_  1
+
+#include <Security/cssmspi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct cssm_spi_csp_funcs {
+    CSSM_RETURN (CSSMCSPI *EventNotify)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CONTEXT_EVENT Event,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context);
+    CSSM_RETURN (CSSMCSPI *QuerySize)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         CSSM_BOOL Encrypt,
+         uint32 QuerySizeCount,
+         CSSM_QUERY_SIZE_DATA_PTR DataBlock);
+    CSSM_RETURN (CSSMCSPI *SignData)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount,
+         CSSM_ALGORITHMS DigestAlgorithm,
+         CSSM_DATA_PTR Signature);
+    CSSM_RETURN (CSSMCSPI *SignDataInit)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context);
+    CSSM_RETURN (CSSMCSPI *SignDataUpdate)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount);
+    CSSM_RETURN (CSSMCSPI *SignDataFinal)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         CSSM_DATA_PTR Signature);
+    CSSM_RETURN (CSSMCSPI *VerifyData)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount,
+         CSSM_ALGORITHMS DigestAlgorithm,
+         const CSSM_DATA *Signature);
+    CSSM_RETURN (CSSMCSPI *VerifyDataInit)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context);
+    CSSM_RETURN (CSSMCSPI *VerifyDataUpdate)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount);
+    CSSM_RETURN (CSSMCSPI *VerifyDataFinal)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *Signature);
+    CSSM_RETURN (CSSMCSPI *DigestData)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount,
+         CSSM_DATA_PTR Digest);
+    CSSM_RETURN (CSSMCSPI *DigestDataInit)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context);
+    CSSM_RETURN (CSSMCSPI *DigestDataUpdate)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount);
+    CSSM_RETURN (CSSMCSPI *DigestDataClone)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         CSSM_CC_HANDLE ClonedCCHandle);
+    CSSM_RETURN (CSSMCSPI *DigestDataFinal)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         CSSM_DATA_PTR Digest);
+    CSSM_RETURN (CSSMCSPI *GenerateMac)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount,
+         CSSM_DATA_PTR Mac);
+    CSSM_RETURN (CSSMCSPI *GenerateMacInit)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context);
+    CSSM_RETURN (CSSMCSPI *GenerateMacUpdate)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount);
+    CSSM_RETURN (CSSMCSPI *GenerateMacFinal)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         CSSM_DATA_PTR Mac);
+    CSSM_RETURN (CSSMCSPI *VerifyMac)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount,
+         const CSSM_DATA *Mac);
+    CSSM_RETURN (CSSMCSPI *VerifyMacInit)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context);
+    CSSM_RETURN (CSSMCSPI *VerifyMacUpdate)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *DataBufs,
+         uint32 DataBufCount);
+    CSSM_RETURN (CSSMCSPI *VerifyMacFinal)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *Mac);
+    CSSM_RETURN (CSSMCSPI *EncryptData)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_DATA *ClearBufs,
+         uint32 ClearBufCount,
+         CSSM_DATA_PTR CipherBufs,
+         uint32 CipherBufCount,
+         uint32 *bytesEncrypted,
+         CSSM_DATA_PTR RemData,
+         CSSM_PRIVILEGE Privilege);
+    CSSM_RETURN (CSSMCSPI *EncryptDataInit)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         CSSM_PRIVILEGE Privilege);
+    CSSM_RETURN (CSSMCSPI *EncryptDataUpdate)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *ClearBufs,
+         uint32 ClearBufCount,
+         CSSM_DATA_PTR CipherBufs,
+         uint32 CipherBufCount,
+         uint32 *bytesEncrypted);
+    CSSM_RETURN (CSSMCSPI *EncryptDataFinal)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         CSSM_DATA_PTR RemData);
+    CSSM_RETURN (CSSMCSPI *DecryptData)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_DATA *CipherBufs,
+         uint32 CipherBufCount,
+         CSSM_DATA_PTR ClearBufs,
+         uint32 ClearBufCount,
+         uint32 *bytesDecrypted,
+         CSSM_DATA_PTR RemData,
+         CSSM_PRIVILEGE Privilege);
+    CSSM_RETURN (CSSMCSPI *DecryptDataInit)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         CSSM_PRIVILEGE Privilege);
+    CSSM_RETURN (CSSMCSPI *DecryptDataUpdate)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *CipherBufs,
+         uint32 CipherBufCount,
+         CSSM_DATA_PTR ClearBufs,
+         uint32 ClearBufCount,
+         uint32 *bytesDecrypted);
+    CSSM_RETURN (CSSMCSPI *DecryptDataFinal)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         CSSM_DATA_PTR RemData);
+    CSSM_RETURN (CSSMCSPI *QueryKeySizeInBits)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_KEY *Key,
+         CSSM_KEY_SIZE_PTR KeySize);
+    CSSM_RETURN (CSSMCSPI *GenerateKey)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         uint32 KeyUsage,
+         uint32 KeyAttr,
+         const CSSM_DATA *KeyLabel,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+         CSSM_KEY_PTR Key,
+         CSSM_PRIVILEGE Privilege);
+    CSSM_RETURN (CSSMCSPI *GenerateKeyPair)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         uint32 PublicKeyUsage,
+         uint32 PublicKeyAttr,
+         const CSSM_DATA *PublicKeyLabel,
+         CSSM_KEY_PTR PublicKey,
+         uint32 PrivateKeyUsage,
+         uint32 PrivateKeyAttr,
+         const CSSM_DATA *PrivateKeyLabel,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+         CSSM_KEY_PTR PrivateKey,
+         CSSM_PRIVILEGE Privilege);
+   CSSM_RETURN (CSSMCSPI *GenerateRandom)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         CSSM_DATA_PTR RandomNumber);
+    CSSM_RETURN (CSSMCSPI *GenerateAlgorithmParams)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         uint32 ParamBits,
+         CSSM_DATA_PTR Param,
+         uint32 *NumberOfUpdatedAttibutes,
+         CSSM_CONTEXT_ATTRIBUTE_PTR *UpdatedAttributes);
+    CSSM_RETURN (CSSMCSPI *WrapKey)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_KEY *Key,
+         const CSSM_DATA *DescriptiveData,
+         CSSM_WRAP_KEY_PTR WrappedKey,
+         CSSM_PRIVILEGE Privilege);
+    CSSM_RETURN (CSSMCSPI *UnwrapKey)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         const CSSM_KEY *PublicKey,
+         const CSSM_WRAP_KEY *WrappedKey,
+         uint32 KeyUsage,
+         uint32 KeyAttr,
+         const CSSM_DATA *KeyLabel,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+         CSSM_KEY_PTR UnwrappedKey,
+         CSSM_DATA_PTR DescriptiveData,
+         CSSM_PRIVILEGE Privilege);
+    CSSM_RETURN (CSSMCSPI *DeriveKey)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         CSSM_DATA_PTR Param,
+         uint32 KeyUsage,
+         uint32 KeyAttr,
+         const CSSM_DATA *KeyLabel,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+         CSSM_KEY_PTR DerivedKey);
+    CSSM_RETURN (CSSMCSPI *FreeKey)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         CSSM_KEY_PTR KeyPtr,
+         CSSM_BOOL Delete);
+    CSSM_RETURN (CSSMCSPI *PassThrough)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_CONTEXT *Context,
+         uint32 PassThroughId,
+         const void *InData,
+         void **OutData);
+    CSSM_RETURN (CSSMCSPI *Login)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_DATA *LoginName,
+         const void *Reserved);
+    CSSM_RETURN (CSSMCSPI *Logout)
+        (CSSM_CSP_HANDLE CSPHandle);
+    CSSM_RETURN (CSSMCSPI *ChangeLoginAcl)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_ACL_EDIT *AclEdit);
+    CSSM_RETURN (CSSMCSPI *ObtainPrivateKeyFromPublicKey)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_KEY *PublicKey,
+         CSSM_KEY_PTR PrivateKey);
+    CSSM_RETURN (CSSMCSPI *RetrieveUniqueId)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_DATA_PTR UniqueID);
+    CSSM_RETURN (CSSMCSPI *RetrieveCounter)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_DATA_PTR Counter);
+    CSSM_RETURN (CSSMCSPI *VerifyDevice)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_DATA *DeviceCert);
+    CSSM_RETURN (CSSMCSPI *GetTimeValue)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_ALGORITHMS TimeAlgorithm,
+         CSSM_DATA *TimeData);
+    CSSM_RETURN (CSSMCSPI *GetOperationalStatistics)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_CSP_OPERATIONAL_STATISTICS *Statistics);
+    CSSM_RETURN (CSSMCSPI *GetLoginAcl)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_STRING *SelectionTag,
+         uint32 *NumberOfAclInfos,
+         CSSM_ACL_ENTRY_INFO_PTR *AclInfos);
+    CSSM_RETURN (CSSMCSPI *GetKeyAcl)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_KEY *Key,
+         const CSSM_STRING *SelectionTag,
+         uint32 *NumberOfAclInfos,
+         CSSM_ACL_ENTRY_INFO_PTR *AclInfos);
+    CSSM_RETURN (CSSMCSPI *ChangeKeyAcl)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_ACL_EDIT *AclEdit,
+         const CSSM_KEY *Key);
+    CSSM_RETURN (CSSMCSPI *GetKeyOwner)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_KEY *Key,
+         CSSM_ACL_OWNER_PROTOTYPE_PTR Owner);
+    CSSM_RETURN (CSSMCSPI *ChangeKeyOwner)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_KEY *Key,
+         const CSSM_ACL_OWNER_PROTOTYPE *NewOwner);
+    CSSM_RETURN (CSSMCSPI *GetLoginOwner)
+        (CSSM_CSP_HANDLE CSPHandle,
+         CSSM_ACL_OWNER_PROTOTYPE_PTR Owner);
+    CSSM_RETURN (CSSMCSPI *ChangeLoginOwner)
+        (CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_ACL_OWNER_PROTOTYPE *NewOwner);
+} CSSM_SPI_CSP_FUNCS, *CSSM_SPI_CSP_FUNCS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMCSPI_H_ */
diff --git a/cdsa/cdsa/cssmdli.h b/cdsa/cdsa/cssmdli.h
new file mode 100644
index 00000000..6e2d67f9
--- /dev/null
+++ b/cdsa/cdsa/cssmdli.h
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmdli.h
+
+   Contains:  Service Provider Interface for Data Store Modules
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMDLI_H_
+#define _CSSMDLI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct cssm_spi_dl_funcs {
+    CSSM_RETURN (CSSMDLI *DbOpen)
+        (CSSM_DL_HANDLE DLHandle,
+         const char *DbName,
+         const CSSM_NET_ADDRESS *DbLocation,
+         CSSM_DB_ACCESS_TYPE AccessRequest,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const void *OpenParameters,
+         CSSM_DB_HANDLE *DbHandle);
+    CSSM_RETURN (CSSMDLI *DbClose)
+        (CSSM_DL_DB_HANDLE DLDBHandle);
+    CSSM_RETURN (CSSMDLI *DbCreate)
+        (CSSM_DL_HANDLE DLHandle,
+         const char *DbName,
+         const CSSM_NET_ADDRESS *DbLocation,
+         const CSSM_DBINFO *DBInfo,
+         CSSM_DB_ACCESS_TYPE AccessRequest,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+         const void *OpenParameters,
+         CSSM_DB_HANDLE *DbHandle);
+    CSSM_RETURN (CSSMDLI *DbDelete)
+        (CSSM_DL_HANDLE DLHandle,
+         const char *DbName,
+         const CSSM_NET_ADDRESS *DbLocation,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred);
+    CSSM_RETURN (CSSMDLI *CreateRelation)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_RECORDTYPE RelationID,
+         const char *RelationName,
+         uint32 NumberOfAttributes,
+         const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
+         uint32 NumberOfIndexes,
+         const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo);
+    CSSM_RETURN (CSSMDLI *DestroyRelation)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_RECORDTYPE RelationID);
+    CSSM_RETURN (CSSMDLI *Authenticate)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_ACCESS_TYPE AccessRequest,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred);
+    CSSM_RETURN (CSSMDLI *GetDbAcl)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_STRING *SelectionTag,
+         uint32 *NumberOfAclInfos,
+         CSSM_ACL_ENTRY_INFO_PTR *AclInfos);
+    CSSM_RETURN (CSSMDLI *ChangeDbAcl)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_ACL_EDIT *AclEdit);
+    CSSM_RETURN (CSSMDLI *GetDbOwner)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_ACL_OWNER_PROTOTYPE_PTR Owner);
+    CSSM_RETURN (CSSMDLI *ChangeDbOwner)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_ACL_OWNER_PROTOTYPE *NewOwner);
+    CSSM_RETURN (CSSMDLI *GetDbNames)
+        (CSSM_DL_HANDLE DLHandle,
+         CSSM_NAME_LIST_PTR *NameList);
+    CSSM_RETURN (CSSMDLI *GetDbNameFromHandle)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         char **DbName);
+    CSSM_RETURN (CSSMDLI *FreeNameList)
+        (CSSM_DL_HANDLE DLHandle,
+         CSSM_NAME_LIST_PTR NameList);
+    CSSM_RETURN (CSSMDLI *DataInsert)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_RECORDTYPE RecordType,
+         const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes,
+         const CSSM_DATA *Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+    CSSM_RETURN (CSSMDLI *DataDelete)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_DB_UNIQUE_RECORD *UniqueRecordIdentifier);
+    CSSM_RETURN (CSSMDLI *DataModify)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_RECORDTYPE RecordType,
+         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecordIdentifier,
+         const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified,
+         const CSSM_DATA *DataToBeModified,
+         CSSM_DB_MODIFY_MODE ModifyMode);
+    CSSM_RETURN (CSSMDLI *DataGetFirst)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_QUERY *Query,
+         CSSM_HANDLE_PTR ResultsHandle,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+    CSSM_RETURN (CSSMDLI *DataGetNext)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_HANDLE ResultsHandle,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+    CSSM_RETURN (CSSMDLI *DataAbortQuery)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_HANDLE ResultsHandle);
+    CSSM_RETURN (CSSMDLI *DataGetFromUniqueRecordId)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_DB_UNIQUE_RECORD *UniqueRecord,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data);
+    CSSM_RETURN (CSSMDLI *FreeUniqueRecord)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecord);
+    CSSM_RETURN (CSSMDLI *PassThrough)
+        (CSSM_DL_DB_HANDLE DLDBHandle,
+         uint32 PassThroughId,
+         const void *InputParams,
+         void **OutputParams);
+} CSSM_SPI_DL_FUNCS, *CSSM_SPI_DL_FUNCS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMDLI_H_ */
diff --git a/cdsa/cdsa/cssmerr.h b/cdsa/cdsa/cssmerr.h
new file mode 100644
index 00000000..d5452ba9
--- /dev/null
+++ b/cdsa/cdsa/cssmerr.h
@@ -0,0 +1,809 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmerr.h
+
+   Contains:  Error Code Definitions for CSSM
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMERR_H_
+#define _CSSMERR_H_  1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Common error codes. */
+enum {
+	CSSM_BASE_ERROR =				-0x7FFF0000 /* 0x80010000 */
+};
+
+enum {
+	CSSM_ERRORCODE_MODULE_EXTENT =	0x00000800,
+	CSSM_ERRORCODE_CUSTOM_OFFSET =	0x00000400,
+	CSSM_ERRORCODE_COMMON_EXTENT =	0x100
+};
+
+/* Macros for convertible error code manipulation. */
+#define CSSM_ERRCODE(CODE) \
+	(((CODE) - CSSM_BASE_ERROR) & (CSSM_ERRORCODE_MODULE_EXTENT - 1)) 
+
+#define CSSM_ERRBASE(CODE) \
+	((((CODE) - CSSM_BASE_ERROR) & ~(CSSM_ERRORCODE_MODULE_EXTENT - 1)) + CSSM_BASE_ERROR) 
+
+#define CSSM_ERR_IS_CONVERTIBLE(CODE) \
+	(CSSM_ERRCODE(CODE) < CSSM_ERRORCODE_COMMON_EXTENT)
+
+#define CSSM_ERR_TAG(CODE, BASE) \
+	(CSSM_ERRCODE(CODE) + (BASE))
+
+/* Error Bases for different module types. */
+enum {
+	CSSM_CSSM_BASE_ERROR =				CSSM_BASE_ERROR,
+	CSSM_CSSM_PRIVATE_ERROR =			CSSM_BASE_ERROR + CSSM_ERRORCODE_CUSTOM_OFFSET,
+	CSSM_CSP_BASE_ERROR =				CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_MODULE_EXTENT,
+	CSSM_CSP_PRIVATE_ERROR =			CSSM_CSP_BASE_ERROR + CSSM_ERRORCODE_CUSTOM_OFFSET,
+	CSSM_DL_BASE_ERROR =				CSSM_CSP_BASE_ERROR + CSSM_ERRORCODE_MODULE_EXTENT,
+	CSSM_DL_PRIVATE_ERROR =				CSSM_DL_BASE_ERROR + CSSM_ERRORCODE_CUSTOM_OFFSET,
+	CSSM_CL_BASE_ERROR =				CSSM_DL_BASE_ERROR + CSSM_ERRORCODE_MODULE_EXTENT,
+	CSSM_CL_PRIVATE_ERROR =				CSSM_CL_BASE_ERROR + CSSM_ERRORCODE_CUSTOM_OFFSET,
+	CSSM_TP_BASE_ERROR =				CSSM_CL_BASE_ERROR + CSSM_ERRORCODE_MODULE_EXTENT,
+	CSSM_TP_PRIVATE_ERROR =				CSSM_TP_BASE_ERROR + CSSM_ERRORCODE_CUSTOM_OFFSET ,
+	CSSM_KR_BASE_ERROR =				CSSM_TP_BASE_ERROR + CSSM_ERRORCODE_MODULE_EXTENT,
+	CSSM_KR_PRIVATE_ERROR =				CSSM_KR_BASE_ERROR + CSSM_ERRORCODE_CUSTOM_OFFSET,
+	CSSM_AC_BASE_ERROR =				CSSM_KR_BASE_ERROR + CSSM_ERRORCODE_MODULE_EXTENT,
+	CSSM_AC_PRIVATE_ERROR =				CSSM_AC_BASE_ERROR + CSSM_ERRORCODE_CUSTOM_OFFSET
+};
+
+/* XXX @@@ MDS Error Bases same as DL for now. */
+enum {
+	CSSM_MDS_BASE_ERROR =				CSSM_CSP_BASE_ERROR + CSSM_ERRORCODE_MODULE_EXTENT,
+	CSSM_MDS_PRIVATE_ERROR =			CSSM_MDS_BASE_ERROR + CSSM_ERRORCODE_CUSTOM_OFFSET
+};
+
+/* General Error Values. */
+enum {
+	CSSMERR_CSSM_INVALID_ADDIN_HANDLE =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 1,
+	CSSMERR_CSSM_NOT_INITIALIZED =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 2,
+	CSSMERR_CSSM_INVALID_HANDLE_USAGE =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 3,
+	CSSMERR_CSSM_PVC_REFERENT_NOT_FOUND =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 4,
+	CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 5
+};
+
+/* Common Error Codes For All Module Types. */
+enum {
+	CSSM_ERRCODE_INTERNAL_ERROR =					0x0001,
+	CSSM_ERRCODE_MEMORY_ERROR =						0x0002,
+	CSSM_ERRCODE_MDS_ERROR =						0x0003,
+	CSSM_ERRCODE_INVALID_POINTER =					0x0004,
+	CSSM_ERRCODE_INVALID_INPUT_POINTER =			0x0005,
+	CSSM_ERRCODE_INVALID_OUTPUT_POINTER =			0x0006,
+	CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED =			0x0007,
+	CSSM_ERRCODE_SELF_CHECK_FAILED =				0x0008,
+	CSSM_ERRCODE_OS_ACCESS_DENIED =					0x0009,
+	CSSM_ERRCODE_FUNCTION_FAILED =					0x000A,
+	CSSM_ERRCODE_MODULE_MANIFEST_VERIFY_FAILED =	0x000B,
+	CSSM_ERRCODE_INVALID_GUID =						0x000C
+};
+
+/* Common Error Codes for ACLs */
+enum {
+	CSSM_ERRCODE_OPERATION_AUTH_DENIED =			0x0020,
+	CSSM_ERRCODE_OBJECT_USE_AUTH_DENIED =			0x0021,
+	CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED =			0x0022,
+	CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED =			0x0023,
+	CSSM_ERRCODE_OBJECT_ACL_REQUIRED =				0x0024,
+	CSSM_ERRCODE_INVALID_ACCESS_CREDENTIALS =		0x0025,
+	CSSM_ERRCODE_INVALID_ACL_BASE_CERTS =			0x0026,
+	CSSM_ERRCODE_ACL_BASE_CERTS_NOT_SUPPORTED =		0x0027,
+	CSSM_ERRCODE_INVALID_SAMPLE_VALUE =				0x0028,
+	CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED =		0x0029,
+	CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE =		0x002A,
+	CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED =	0x002B,
+	CSSM_ERRCODE_INVALID_ACL_CHALLENGE_CALLBACK =	0x002C,
+	CSSM_ERRCODE_ACL_CHALLENGE_CALLBACK_FAILED =	0x002D,
+	CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG =			0x002E,
+	CSSM_ERRCODE_ACL_ENTRY_TAG_NOT_FOUND =			0x002F,
+	CSSM_ERRCODE_INVALID_ACL_EDIT_MODE =			0x0030,
+	CSSM_ERRCODE_ACL_CHANGE_FAILED =				0x0031,
+	CSSM_ERRCODE_INVALID_NEW_ACL_ENTRY =			0x0032,
+	CSSM_ERRCODE_INVALID_NEW_ACL_OWNER =			0x0033,
+	CSSM_ERRCODE_ACL_DELETE_FAILED =				0x0034,
+	CSSM_ERRCODE_ACL_REPLACE_FAILED =				0x0035,
+	CSSM_ERRCODE_ACL_ADD_FAILED =					0x0036
+};
+
+/* Common Error Codes for Specific Data Types */
+enum {
+	CSSM_ERRCODE_INVALID_CONTEXT_HANDLE =			0x0040,
+	CSSM_ERRCODE_INCOMPATIBLE_VERSION =				0x0041,
+	CSSM_ERRCODE_INVALID_CERTGROUP_POINTER =		0x0042,
+	CSSM_ERRCODE_INVALID_CERT_POINTER =				0x0043,
+	CSSM_ERRCODE_INVALID_CRL_POINTER =				0x0044,
+	CSSM_ERRCODE_INVALID_FIELD_POINTER =			0x0045,
+	CSSM_ERRCODE_INVALID_DATA =						0x0046,
+	CSSM_ERRCODE_CRL_ALREADY_SIGNED =				0x0047,
+	CSSM_ERRCODE_INVALID_NUMBER_OF_FIELDS =			0x0048,
+	CSSM_ERRCODE_VERIFICATION_FAILURE =				0x0049,
+	CSSM_ERRCODE_INVALID_DB_HANDLE =				0x004A,
+	CSSM_ERRCODE_PRIVILEGE_NOT_GRANTED =			0x004B,
+	CSSM_ERRCODE_INVALID_DB_LIST =					0x004C,
+	CSSM_ERRCODE_INVALID_DB_LIST_POINTER =			0x004D,
+	CSSM_ERRCODE_UNKNOWN_FORMAT =					0x004E,
+	CSSM_ERRCODE_UNKNOWN_TAG =						0x004F,
+	CSSM_ERRCODE_INVALID_CSP_HANDLE =				0x0050,
+	CSSM_ERRCODE_INVALID_DL_HANDLE =				0x0051,
+	CSSM_ERRCODE_INVALID_CL_HANDLE =				0x0052,
+	CSSM_ERRCODE_INVALID_TP_HANDLE =				0x0053,
+	CSSM_ERRCODE_INVALID_KR_HANDLE =				0x0054,
+	CSSM_ERRCODE_INVALID_AC_HANDLE =				0x0055,
+	CSSM_ERRCODE_INVALID_PASSTHROUGH_ID =			0x0056,
+	CSSM_ERRCODE_INVALID_NETWORK_ADDR =				0x0057,
+	CSSM_ERRCODE_INVALID_CRYPTO_DATA =				0x0058
+};
+
+/* CSSM Error Values Derived from Common Error Codes For All Module Types. */
+enum {
+	CSSMERR_CSSM_INTERNAL_ERROR =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR,
+	CSSMERR_CSSM_MEMORY_ERROR =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR,
+	CSSMERR_CSSM_MDS_ERROR =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR,
+	CSSMERR_CSSM_INVALID_POINTER =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER,
+	CSSMERR_CSSM_INVALID_INPUT_POINTER =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER,
+	CSSMERR_CSSM_INVALID_OUTPUT_POINTER =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER,
+	CSSMERR_CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED,
+	CSSMERR_CSSM_SELF_CHECK_FAILED =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED,
+	CSSMERR_CSSM_OS_ACCESS_DENIED =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED,
+	CSSMERR_CSSM_FUNCTION_FAILED =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED,
+	CSSMERR_CSSM_MODULE_MANIFEST_VERIFY_FAILED =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_MODULE_MANIFEST_VERIFY_FAILED,
+	CSSMERR_CSSM_INVALID_GUID =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_GUID
+};
+
+/* CSSM Error Values for Specific Data Types. */
+enum {
+	CSSMERR_CSSM_INVALID_CONTEXT_HANDLE =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE,
+	CSSMERR_CSSM_INCOMPATIBLE_VERSION =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INCOMPATIBLE_VERSION,
+	CSSMERR_CSSM_PRIVILEGE_NOT_GRANTED =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_PRIVILEGE_NOT_GRANTED
+};
+
+/* CSSM Module-Specific Error Values */
+enum {
+	CSSM_CSSM_BASE_CSSM_ERROR =
+		CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 0x10,
+	CSSMERR_CSSM_SCOPE_NOT_SUPPORTED =				CSSM_CSSM_BASE_CSSM_ERROR + 1,
+	CSSMERR_CSSM_PVC_ALREADY_CONFIGURED =			CSSM_CSSM_BASE_CSSM_ERROR + 2,
+	CSSMERR_CSSM_INVALID_PVC =						CSSM_CSSM_BASE_CSSM_ERROR + 3,
+	CSSMERR_CSSM_EMM_LOAD_FAILED =					CSSM_CSSM_BASE_CSSM_ERROR + 4,
+	CSSMERR_CSSM_EMM_UNLOAD_FAILED =				CSSM_CSSM_BASE_CSSM_ERROR + 5,
+	CSSMERR_CSSM_ADDIN_LOAD_FAILED =				CSSM_CSSM_BASE_CSSM_ERROR + 6,
+	CSSMERR_CSSM_INVALID_KEY_HIERARCHY =			CSSM_CSSM_BASE_CSSM_ERROR + 7,
+	CSSMERR_CSSM_ADDIN_UNLOAD_FAILED =				CSSM_CSSM_BASE_CSSM_ERROR + 8,
+	CSSMERR_CSSM_LIB_REF_NOT_FOUND =				CSSM_CSSM_BASE_CSSM_ERROR + 9,
+	CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE =		CSSM_CSSM_BASE_CSSM_ERROR + 10,
+	CSSMERR_CSSM_EMM_AUTHENTICATE_FAILED =			CSSM_CSSM_BASE_CSSM_ERROR + 11,
+	CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED =		CSSM_CSSM_BASE_CSSM_ERROR + 12,
+	CSSMERR_CSSM_INVALID_SERVICE_MASK =				CSSM_CSSM_BASE_CSSM_ERROR + 13,
+	CSSMERR_CSSM_MODULE_NOT_LOADED =				CSSM_CSSM_BASE_CSSM_ERROR + 14,
+	CSSMERR_CSSM_INVALID_SUBSERVICEID =				CSSM_CSSM_BASE_CSSM_ERROR + 15,
+	CSSMERR_CSSM_BUFFER_TOO_SMALL =					CSSM_CSSM_BASE_CSSM_ERROR + 16,
+	CSSMERR_CSSM_INVALID_ATTRIBUTE =				CSSM_CSSM_BASE_CSSM_ERROR + 17,
+	CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT =			CSSM_CSSM_BASE_CSSM_ERROR + 18,
+	CSSMERR_CSSM_MODULE_MANAGER_INITIALIZE_FAIL =	CSSM_CSSM_BASE_CSSM_ERROR + 19,
+	CSSMERR_CSSM_MODULE_MANAGER_NOT_FOUND =			CSSM_CSSM_BASE_CSSM_ERROR + 20,
+	CSSMERR_CSSM_EVENT_NOTIFICATION_CALLBACK_NOT_FOUND = CSSM_CSSM_BASE_CSSM_ERROR + 21
+};
+
+/* CSP Error Values Derived from Common Error Codes For All Module Types. */
+enum {
+	CSSMERR_CSP_INTERNAL_ERROR =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR,
+	CSSMERR_CSP_MEMORY_ERROR =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR,
+	CSSMERR_CSP_MDS_ERROR =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR,
+	CSSMERR_CSP_INVALID_POINTER =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER,
+	CSSMERR_CSP_INVALID_INPUT_POINTER =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER,
+	CSSMERR_CSP_INVALID_OUTPUT_POINTER =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER,
+	CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED,
+	CSSMERR_CSP_SELF_CHECK_FAILED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED,
+	CSSMERR_CSP_OS_ACCESS_DENIED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED,
+	CSSMERR_CSP_FUNCTION_FAILED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED
+};
+
+/* CSP Error Values Derived from ACL-based Error Codes. */
+enum {
+	CSSMERR_CSP_OPERATION_AUTH_DENIED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OPERATION_AUTH_DENIED,
+	CSSMERR_CSP_OBJECT_USE_AUTH_DENIED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OBJECT_USE_AUTH_DENIED,
+	CSSMERR_CSP_OBJECT_MANIP_AUTH_DENIED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED,
+	CSSMERR_CSP_OBJECT_ACL_NOT_SUPPORTED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED,
+	CSSMERR_CSP_OBJECT_ACL_REQUIRED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OBJECT_ACL_REQUIRED,
+	CSSMERR_CSP_INVALID_ACCESS_CREDENTIALS =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACCESS_CREDENTIALS,
+	CSSMERR_CSP_INVALID_ACL_BASE_CERTS =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_BASE_CERTS,
+	CSSMERR_CSP_ACL_BASE_CERTS_NOT_SUPPORTED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_BASE_CERTS_NOT_SUPPORTED,
+	CSSMERR_CSP_INVALID_SAMPLE_VALUE =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_SAMPLE_VALUE,
+	CSSMERR_CSP_SAMPLE_VALUE_NOT_SUPPORTED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED,
+	CSSMERR_CSP_INVALID_ACL_SUBJECT_VALUE =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE,
+	CSSMERR_CSP_ACL_SUBJECT_TYPE_NOT_SUPPORTED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED,
+	CSSMERR_CSP_INVALID_ACL_CHALLENGE_CALLBACK =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_CHALLENGE_CALLBACK,
+	CSSMERR_CSP_ACL_CHALLENGE_CALLBACK_FAILED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_CHALLENGE_CALLBACK_FAILED,
+	CSSMERR_CSP_INVALID_ACL_ENTRY_TAG =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG,
+	CSSMERR_CSP_ACL_ENTRY_TAG_NOT_FOUND =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_ENTRY_TAG_NOT_FOUND,
+	CSSMERR_CSP_INVALID_ACL_EDIT_MODE =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_EDIT_MODE,
+	CSSMERR_CSP_ACL_CHANGE_FAILED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_CHANGE_FAILED,
+	CSSMERR_CSP_INVALID_NEW_ACL_ENTRY =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_NEW_ACL_ENTRY,
+	CSSMERR_CSP_INVALID_NEW_ACL_OWNER =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_NEW_ACL_OWNER,
+	CSSMERR_CSP_ACL_DELETE_FAILED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_DELETE_FAILED,
+	CSSMERR_CSP_ACL_REPLACE_FAILED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_REPLACE_FAILED,
+	CSSMERR_CSP_ACL_ADD_FAILED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_ADD_FAILED
+};
+
+/* CSP Error Values for Specific Data Types. */
+enum {
+	CSSMERR_CSP_INVALID_CONTEXT_HANDLE =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE,
+	CSSMERR_CSP_PRIVILEGE_NOT_GRANTED =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_PRIVILEGE_NOT_GRANTED,
+	CSSMERR_CSP_INVALID_DATA =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_DATA,
+	CSSMERR_CSP_INVALID_PASSTHROUGH_ID =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID,
+	CSSMERR_CSP_INVALID_CRYPTO_DATA =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_CRYPTO_DATA
+};
+
+/* CSP Module-Specific Error Values */
+enum {
+	/* General CSP Error Values */
+	CSSM_CSP_BASE_CSP_ERROR =
+		CSSM_CSP_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT,
+	CSSMERR_CSP_INPUT_LENGTH_ERROR =				CSSM_CSP_BASE_CSP_ERROR + 1,
+	CSSMERR_CSP_OUTPUT_LENGTH_ERROR =				CSSM_CSP_BASE_CSP_ERROR + 2,
+	CSSMERR_CSP_PRIVILEGE_NOT_SUPPORTED =			CSSM_CSP_BASE_CSP_ERROR + 3,
+	CSSMERR_CSP_DEVICE_ERROR =						CSSM_CSP_BASE_CSP_ERROR + 4,
+	CSSMERR_CSP_DEVICE_MEMORY_ERROR =				CSSM_CSP_BASE_CSP_ERROR + 5,
+	CSSMERR_CSP_ATTACH_HANDLE_BUSY =				CSSM_CSP_BASE_CSP_ERROR + 6,
+	CSSMERR_CSP_NOT_LOGGED_IN =						CSSM_CSP_BASE_CSP_ERROR + 7,
+	CSSMERR_CSP_INVALID_KEY =						CSSM_CSP_BASE_CSP_ERROR + 16,
+	CSSMERR_CSP_INVALID_KEY_REFERENCE =				CSSM_CSP_BASE_CSP_ERROR + 17,
+	CSSMERR_CSP_INVALID_KEY_CLASS =					CSSM_CSP_BASE_CSP_ERROR + 18,
+	CSSMERR_CSP_ALGID_MISMATCH =					CSSM_CSP_BASE_CSP_ERROR + 19,
+	CSSMERR_CSP_KEY_USAGE_INCORRECT =				CSSM_CSP_BASE_CSP_ERROR + 20,
+	CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT =			CSSM_CSP_BASE_CSP_ERROR + 21,
+	CSSMERR_CSP_KEY_HEADER_INCONSISTENT =			CSSM_CSP_BASE_CSP_ERROR + 22,
+	CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT =			CSSM_CSP_BASE_CSP_ERROR + 23,
+	CSSMERR_CSP_UNSUPPORTED_KEY_SIZE =				CSSM_CSP_BASE_CSP_ERROR + 24,
+	CSSMERR_CSP_INVALID_KEY_POINTER =				CSSM_CSP_BASE_CSP_ERROR + 25,
+	CSSMERR_CSP_INVALID_KEYUSAGE_MASK =				CSSM_CSP_BASE_CSP_ERROR + 26,
+	CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK =			CSSM_CSP_BASE_CSP_ERROR + 27,
+	CSSMERR_CSP_INVALID_KEYATTR_MASK =				CSSM_CSP_BASE_CSP_ERROR + 28,
+	CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK =			CSSM_CSP_BASE_CSP_ERROR + 29,
+	CSSMERR_CSP_INVALID_KEY_LABEL =					CSSM_CSP_BASE_CSP_ERROR + 30,
+	CSSMERR_CSP_UNSUPPORTED_KEY_LABEL =				CSSM_CSP_BASE_CSP_ERROR + 31,
+	CSSMERR_CSP_INVALID_KEY_FORMAT =				CSSM_CSP_BASE_CSP_ERROR + 32,
+
+	/* CSP Vector of Buffers Error Values. */
+	CSSMERR_CSP_INVALID_DATA_COUNT =				CSSM_CSP_BASE_CSP_ERROR + 40,
+	CSSMERR_CSP_VECTOR_OF_BUFS_UNSUPPORTED =		CSSM_CSP_BASE_CSP_ERROR + 41,
+	CSSMERR_CSP_INVALID_INPUT_VECTOR =				CSSM_CSP_BASE_CSP_ERROR + 42,
+	CSSMERR_CSP_INVALID_OUTPUT_VECTOR =				CSSM_CSP_BASE_CSP_ERROR + 43,
+
+	/* CSP Cryptographic Context Error Values. */
+	CSSMERR_CSP_INVALID_CONTEXT =					CSSM_CSP_BASE_CSP_ERROR + 48,
+	CSSMERR_CSP_INVALID_ALGORITHM =					CSSM_CSP_BASE_CSP_ERROR + 49,
+	CSSMERR_CSP_INVALID_ATTR_KEY = 					CSSM_CSP_BASE_CSP_ERROR + 54,
+	CSSMERR_CSP_MISSING_ATTR_KEY = 					CSSM_CSP_BASE_CSP_ERROR + 55,
+	CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR = 			CSSM_CSP_BASE_CSP_ERROR + 56,
+	CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR = 			CSSM_CSP_BASE_CSP_ERROR + 57,
+	CSSMERR_CSP_INVALID_ATTR_SALT = 				CSSM_CSP_BASE_CSP_ERROR + 58,
+	CSSMERR_CSP_MISSING_ATTR_SALT = 				CSSM_CSP_BASE_CSP_ERROR + 59,
+	CSSMERR_CSP_INVALID_ATTR_PADDING = 				CSSM_CSP_BASE_CSP_ERROR + 60,
+	CSSMERR_CSP_MISSING_ATTR_PADDING = 				CSSM_CSP_BASE_CSP_ERROR + 61,
+	CSSMERR_CSP_INVALID_ATTR_RANDOM = 				CSSM_CSP_BASE_CSP_ERROR + 62,
+	CSSMERR_CSP_MISSING_ATTR_RANDOM = 				CSSM_CSP_BASE_CSP_ERROR + 63,
+	CSSMERR_CSP_INVALID_ATTR_SEED = 				CSSM_CSP_BASE_CSP_ERROR + 64,
+	CSSMERR_CSP_MISSING_ATTR_SEED = 				CSSM_CSP_BASE_CSP_ERROR + 65,
+	CSSMERR_CSP_INVALID_ATTR_PASSPHRASE = 			CSSM_CSP_BASE_CSP_ERROR + 66,
+	CSSMERR_CSP_MISSING_ATTR_PASSPHRASE = 			CSSM_CSP_BASE_CSP_ERROR + 67,
+	CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH = 			CSSM_CSP_BASE_CSP_ERROR + 68,
+	CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH = 			CSSM_CSP_BASE_CSP_ERROR + 69,
+	CSSMERR_CSP_INVALID_ATTR_BLOCK_SIZE = 			CSSM_CSP_BASE_CSP_ERROR + 70,
+	CSSMERR_CSP_MISSING_ATTR_BLOCK_SIZE = 			CSSM_CSP_BASE_CSP_ERROR + 71,
+	CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE = 			CSSM_CSP_BASE_CSP_ERROR + 100,
+	CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE = 			CSSM_CSP_BASE_CSP_ERROR + 101,
+	CSSMERR_CSP_INVALID_ATTR_ROUNDS = 				CSSM_CSP_BASE_CSP_ERROR + 102,
+	CSSMERR_CSP_MISSING_ATTR_ROUNDS = 				CSSM_CSP_BASE_CSP_ERROR + 103,
+	CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS = 			CSSM_CSP_BASE_CSP_ERROR + 104,
+	CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS = 			CSSM_CSP_BASE_CSP_ERROR + 105,
+	CSSMERR_CSP_INVALID_ATTR_LABEL = 				CSSM_CSP_BASE_CSP_ERROR + 106,
+	CSSMERR_CSP_MISSING_ATTR_LABEL = 				CSSM_CSP_BASE_CSP_ERROR + 107,
+	CSSMERR_CSP_INVALID_ATTR_KEY_TYPE = 			CSSM_CSP_BASE_CSP_ERROR + 108,
+	CSSMERR_CSP_MISSING_ATTR_KEY_TYPE = 			CSSM_CSP_BASE_CSP_ERROR + 109,
+	CSSMERR_CSP_INVALID_ATTR_MODE = 				CSSM_CSP_BASE_CSP_ERROR + 110,
+	CSSMERR_CSP_MISSING_ATTR_MODE = 				CSSM_CSP_BASE_CSP_ERROR + 111,
+	CSSMERR_CSP_INVALID_ATTR_EFFECTIVE_BITS = 		CSSM_CSP_BASE_CSP_ERROR + 112,
+	CSSMERR_CSP_MISSING_ATTR_EFFECTIVE_BITS = 		CSSM_CSP_BASE_CSP_ERROR + 113,
+	CSSMERR_CSP_INVALID_ATTR_START_DATE = 			CSSM_CSP_BASE_CSP_ERROR + 114,
+	CSSMERR_CSP_MISSING_ATTR_START_DATE = 			CSSM_CSP_BASE_CSP_ERROR + 115,
+	CSSMERR_CSP_INVALID_ATTR_END_DATE = 			CSSM_CSP_BASE_CSP_ERROR + 116,
+	CSSMERR_CSP_MISSING_ATTR_END_DATE = 			CSSM_CSP_BASE_CSP_ERROR + 117,
+	CSSMERR_CSP_INVALID_ATTR_VERSION = 				CSSM_CSP_BASE_CSP_ERROR + 118,
+	CSSMERR_CSP_MISSING_ATTR_VERSION = 				CSSM_CSP_BASE_CSP_ERROR + 119,
+	CSSMERR_CSP_INVALID_ATTR_PRIME = 				CSSM_CSP_BASE_CSP_ERROR + 120,
+	CSSMERR_CSP_MISSING_ATTR_PRIME = 				CSSM_CSP_BASE_CSP_ERROR + 121,
+	CSSMERR_CSP_INVALID_ATTR_BASE = 				CSSM_CSP_BASE_CSP_ERROR + 122,
+	CSSMERR_CSP_MISSING_ATTR_BASE = 				CSSM_CSP_BASE_CSP_ERROR + 123,
+	CSSMERR_CSP_INVALID_ATTR_SUBPRIME = 			CSSM_CSP_BASE_CSP_ERROR + 124,
+	CSSMERR_CSP_MISSING_ATTR_SUBPRIME = 			CSSM_CSP_BASE_CSP_ERROR + 125,
+	CSSMERR_CSP_INVALID_ATTR_ITERATION_COUNT = 		CSSM_CSP_BASE_CSP_ERROR + 126,
+	CSSMERR_CSP_MISSING_ATTR_ITERATION_COUNT = 		CSSM_CSP_BASE_CSP_ERROR + 127,
+	CSSMERR_CSP_INVALID_ATTR_DL_DB_HANDLE = 		CSSM_CSP_BASE_CSP_ERROR + 128,
+	CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE = 		CSSM_CSP_BASE_CSP_ERROR + 129,
+	CSSMERR_CSP_INVALID_ATTR_ACCESS_CREDENTIALS = 	CSSM_CSP_BASE_CSP_ERROR + 130,
+	CSSMERR_CSP_MISSING_ATTR_ACCESS_CREDENTIALS = 	CSSM_CSP_BASE_CSP_ERROR + 131,
+	CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT = 	CSSM_CSP_BASE_CSP_ERROR + 132,
+	CSSMERR_CSP_MISSING_ATTR_PUBLIC_KEY_FORMAT = 	CSSM_CSP_BASE_CSP_ERROR + 133,
+	CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT = 	CSSM_CSP_BASE_CSP_ERROR + 134,
+	CSSMERR_CSP_MISSING_ATTR_PRIVATE_KEY_FORMAT = 	CSSM_CSP_BASE_CSP_ERROR + 135,
+	CSSMERR_CSP_INVALID_ATTR_SYMMETRIC_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 136,
+	CSSMERR_CSP_MISSING_ATTR_SYMMETRIC_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 137,
+	CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT = 	CSSM_CSP_BASE_CSP_ERROR + 138,
+	CSSMERR_CSP_MISSING_ATTR_WRAPPED_KEY_FORMAT = 	CSSM_CSP_BASE_CSP_ERROR + 139,
+
+	/* CSP Staged Cryptographic API Error Values. */
+	CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS =		CSSM_CSP_BASE_CSP_ERROR + 72,
+	CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED =		CSSM_CSP_BASE_CSP_ERROR + 73,
+	CSSMERR_CSP_VERIFY_FAILED =						CSSM_CSP_BASE_CSP_ERROR + 74,
+	CSSMERR_CSP_INVALID_SIGNATURE =					CSSM_CSP_BASE_CSP_ERROR + 75,
+	CSSMERR_CSP_QUERY_SIZE_UNKNOWN =				CSSM_CSP_BASE_CSP_ERROR + 76,
+	CSSMERR_CSP_BLOCK_SIZE_MISMATCH =				CSSM_CSP_BASE_CSP_ERROR + 77,
+	CSSMERR_CSP_PRIVATE_KEY_NOT_FOUND =				CSSM_CSP_BASE_CSP_ERROR + 78,
+	CSSMERR_CSP_PUBLIC_KEY_INCONSISTENT =			CSSM_CSP_BASE_CSP_ERROR + 79,
+	CSSMERR_CSP_DEVICE_VERIFY_FAILED =				CSSM_CSP_BASE_CSP_ERROR + 80,
+	CSSMERR_CSP_INVALID_LOGIN_NAME =				CSSM_CSP_BASE_CSP_ERROR + 81,
+	CSSMERR_CSP_ALREADY_LOGGED_IN =					CSSM_CSP_BASE_CSP_ERROR + 82,
+	CSSMERR_CSP_PRIVATE_KEY_ALREADY_EXISTS =		CSSM_CSP_BASE_CSP_ERROR + 83,
+	CSSMERR_CSP_KEY_LABEL_ALREADY_EXISTS =			CSSM_CSP_BASE_CSP_ERROR + 84,
+	CSSMERR_CSP_INVALID_DIGEST_ALGORITHM =			CSSM_CSP_BASE_CSP_ERROR + 85,
+	CSSMERR_CSP_CRYPTO_DATA_CALLBACK_FAILED =		CSSM_CSP_BASE_CSP_ERROR + 86
+};
+
+
+/* TP Error Values Derived from Common Error Codes For All Module Types. */
+enum {
+	CSSMERR_TP_INTERNAL_ERROR =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR,
+	CSSMERR_TP_MEMORY_ERROR =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR,
+	CSSMERR_TP_MDS_ERROR =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR,
+	CSSMERR_TP_INVALID_POINTER =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER,
+	CSSMERR_TP_INVALID_INPUT_POINTER =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER,
+	CSSMERR_TP_INVALID_OUTPUT_POINTER =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER,
+	CSSMERR_TP_FUNCTION_NOT_IMPLEMENTED =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED,
+	CSSMERR_TP_SELF_CHECK_FAILED =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED,
+	CSSMERR_TP_OS_ACCESS_DENIED =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED,
+	CSSMERR_TP_FUNCTION_FAILED =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED,
+	CSSMERR_TP_INVALID_CONTEXT_HANDLE =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE,
+	CSSMERR_TP_INVALID_DATA =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DATA,
+	CSSMERR_TP_INVALID_DB_LIST =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST,
+	CSSMERR_TP_INVALID_CERTGROUP_POINTER =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CERTGROUP_POINTER,
+	CSSMERR_TP_INVALID_CERT_POINTER =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CERT_POINTER,
+	CSSMERR_TP_INVALID_CRL_POINTER =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CRL_POINTER,
+	CSSMERR_TP_INVALID_FIELD_POINTER =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_FIELD_POINTER,
+	CSSMERR_TP_INVALID_NETWORK_ADDR =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_NETWORK_ADDR,
+	CSSMERR_TP_CRL_ALREADY_SIGNED =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_CRL_ALREADY_SIGNED,
+	CSSMERR_TP_INVALID_NUMBER_OF_FIELDS =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_NUMBER_OF_FIELDS,
+	CSSMERR_TP_VERIFICATION_FAILURE =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_VERIFICATION_FAILURE,
+	CSSMERR_TP_INVALID_DB_HANDLE =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_HANDLE,
+	CSSMERR_TP_UNKNOWN_FORMAT =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_UNKNOWN_FORMAT,
+	CSSMERR_TP_UNKNOWN_TAG =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_UNKNOWN_TAG,
+	CSSMERR_TP_INVALID_PASSTHROUGH_ID =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID,
+	CSSMERR_TP_INVALID_CSP_HANDLE =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CSP_HANDLE,
+	CSSMERR_TP_INVALID_DL_HANDLE =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DL_HANDLE,
+	CSSMERR_TP_INVALID_CL_HANDLE =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CL_HANDLE,
+	CSSMERR_TP_INVALID_DB_LIST_POINTER =
+		CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST_POINTER
+};
+
+/* TP Module-Specific Error Values */
+enum {
+	CSSM_TP_BASE_TP_ERROR =
+		CSSM_TP_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT,
+	CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER =	CSSM_TP_BASE_TP_ERROR + 1,
+	CSSMERR_TP_INVALID_IDENTIFIER_POINTER =			CSSM_TP_BASE_TP_ERROR + 2,
+	CSSMERR_TP_INVALID_KEYCACHE_HANDLE =			CSSM_TP_BASE_TP_ERROR + 3,
+	CSSMERR_TP_INVALID_CERTGROUP =					CSSM_TP_BASE_TP_ERROR + 4,
+	CSSMERR_TP_INVALID_CRLGROUP =					CSSM_TP_BASE_TP_ERROR + 5,
+	CSSMERR_TP_INVALID_CRLGROUP_POINTER =			CSSM_TP_BASE_TP_ERROR + 6,
+	CSSMERR_TP_AUTHENTICATION_FAILED =				CSSM_TP_BASE_TP_ERROR + 7,
+	CSSMERR_TP_CERTGROUP_INCOMPLETE =				CSSM_TP_BASE_TP_ERROR + 8,
+	CSSMERR_TP_CERTIFICATE_CANT_OPERATE =			CSSM_TP_BASE_TP_ERROR + 9,
+	CSSMERR_TP_CERT_EXPIRED =						CSSM_TP_BASE_TP_ERROR + 10,
+	CSSMERR_TP_CERT_NOT_VALID_YET =					CSSM_TP_BASE_TP_ERROR + 11,
+	CSSMERR_TP_CERT_REVOKED =						CSSM_TP_BASE_TP_ERROR + 12,
+	CSSMERR_TP_CERT_SUSPENDED =						CSSM_TP_BASE_TP_ERROR + 13,
+	CSSMERR_TP_INSUFFICIENT_CREDENTIALS =			CSSM_TP_BASE_TP_ERROR + 14,
+	CSSMERR_TP_INVALID_ACTION =						CSSM_TP_BASE_TP_ERROR + 15,
+	CSSMERR_TP_INVALID_ACTION_DATA =				CSSM_TP_BASE_TP_ERROR + 16,
+/*	CSSMERR_TP_INVALID_NETWORK_ADDR =				CSSM_TP_BASE_TP_ERROR + 17, */
+	CSSMERR_TP_INVALID_ANCHOR_CERT =				CSSM_TP_BASE_TP_ERROR + 18,
+	CSSMERR_TP_INVALID_AUTHORITY =					CSSM_TP_BASE_TP_ERROR + 19,
+	CSSMERR_TP_VERIFY_ACTION_FAILED =				CSSM_TP_BASE_TP_ERROR + 20,
+	CSSMERR_TP_INVALID_CERTIFICATE =				CSSM_TP_BASE_TP_ERROR + 21,
+	CSSMERR_TP_INVALID_CERT_AUTHORITY =				CSSM_TP_BASE_TP_ERROR + 22,
+	CSSMERR_TP_INVALID_CRL_AUTHORITY =				CSSM_TP_BASE_TP_ERROR + 23,
+	CSSMERR_TP_INVALID_CRL_ENCODING =				CSSM_TP_BASE_TP_ERROR + 24,
+	CSSMERR_TP_INVALID_CRL_TYPE =					CSSM_TP_BASE_TP_ERROR + 25,
+	CSSMERR_TP_INVALID_CRL =						CSSM_TP_BASE_TP_ERROR + 26,
+	CSSMERR_TP_INVALID_FORM_TYPE =					CSSM_TP_BASE_TP_ERROR + 27,
+	CSSMERR_TP_INVALID_ID =							CSSM_TP_BASE_TP_ERROR + 28,
+	CSSMERR_TP_INVALID_IDENTIFIER =					CSSM_TP_BASE_TP_ERROR + 29,
+	CSSMERR_TP_INVALID_INDEX =						CSSM_TP_BASE_TP_ERROR + 30,
+	CSSMERR_TP_INVALID_NAME =						CSSM_TP_BASE_TP_ERROR + 31,
+	CSSMERR_TP_INVALID_POLICY_IDENTIFIERS =			CSSM_TP_BASE_TP_ERROR + 32,
+	CSSMERR_TP_INVALID_TIMESTRING =					CSSM_TP_BASE_TP_ERROR + 33,
+	CSSMERR_TP_INVALID_REASON =						CSSM_TP_BASE_TP_ERROR + 34,
+	CSSMERR_TP_INVALID_REQUEST_INPUTS =				CSSM_TP_BASE_TP_ERROR + 35,
+	CSSMERR_TP_INVALID_RESPONSE_VECTOR =			CSSM_TP_BASE_TP_ERROR + 36,
+	CSSMERR_TP_INVALID_SIGNATURE =					CSSM_TP_BASE_TP_ERROR + 37,
+	CSSMERR_TP_INVALID_STOP_ON_POLICY =				CSSM_TP_BASE_TP_ERROR + 38,
+	CSSMERR_TP_INVALID_CALLBACK =					CSSM_TP_BASE_TP_ERROR + 39,
+	CSSMERR_TP_INVALID_TUPLE =						CSSM_TP_BASE_TP_ERROR + 40,
+	CSSMERR_TP_NOT_SIGNER =							CSSM_TP_BASE_TP_ERROR + 41,
+	CSSMERR_TP_NOT_TRUSTED =						CSSM_TP_BASE_TP_ERROR + 42,
+	CSSMERR_TP_NO_DEFAULT_AUTHORITY =				CSSM_TP_BASE_TP_ERROR + 43,
+	CSSMERR_TP_REJECTED_FORM =						CSSM_TP_BASE_TP_ERROR + 44,
+	CSSMERR_TP_REQUEST_LOST =						CSSM_TP_BASE_TP_ERROR + 45,
+	CSSMERR_TP_REQUEST_REJECTED =					CSSM_TP_BASE_TP_ERROR + 46,
+	CSSMERR_TP_UNSUPPORTED_ADDR_TYPE =				CSSM_TP_BASE_TP_ERROR + 47,
+	CSSMERR_TP_UNSUPPORTED_SERVICE =				CSSM_TP_BASE_TP_ERROR + 48,
+	CSSMERR_TP_INVALID_TUPLEGROUP_POINTER =			CSSM_TP_BASE_TP_ERROR + 49,
+	CSSMERR_TP_INVALID_TUPLEGROUP =					CSSM_TP_BASE_TP_ERROR + 50
+};
+
+/* AC Error Values Derived from Common Error Codes For All Module Types. */
+enum {
+	CSSMERR_AC_INTERNAL_ERROR =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR,
+	CSSMERR_AC_MEMORY_ERROR =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR,
+	CSSMERR_AC_MDS_ERROR =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR,
+	CSSMERR_AC_INVALID_POINTER =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER,
+	CSSMERR_AC_INVALID_INPUT_POINTER =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER,
+	CSSMERR_AC_INVALID_OUTPUT_POINTER =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER,
+	CSSMERR_AC_FUNCTION_NOT_IMPLEMENTED =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED,
+	CSSMERR_AC_SELF_CHECK_FAILED =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED,
+	CSSMERR_AC_OS_ACCESS_DENIED =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED,
+	CSSMERR_AC_FUNCTION_FAILED =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED,
+	CSSMERR_AC_INVALID_CONTEXT_HANDLE =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE,
+	CSSMERR_AC_INVALID_DATA =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DATA,
+	CSSMERR_AC_INVALID_DB_LIST =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST,
+	CSSMERR_AC_INVALID_PASSTHROUGH_ID =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID,
+	CSSMERR_AC_INVALID_DL_HANDLE =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DL_HANDLE,
+	CSSMERR_AC_INVALID_CL_HANDLE =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_CL_HANDLE,
+	CSSMERR_AC_INVALID_TP_HANDLE =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_TP_HANDLE,
+	CSSMERR_AC_INVALID_DB_HANDLE =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_HANDLE,
+	CSSMERR_AC_INVALID_DB_LIST_POINTER =
+		CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST_POINTER
+};
+
+/* AC Module-Specific Error Values */
+enum {
+	CSSM_AC_BASE_AC_ERROR =
+		CSSM_AC_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT,
+	CSSMERR_AC_INVALID_BASE_ACLS =					CSSM_AC_BASE_AC_ERROR + 1,
+	CSSMERR_AC_INVALID_TUPLE_CREDENTIALS =			CSSM_AC_BASE_AC_ERROR + 2,
+	CSSMERR_AC_INVALID_ENCODING =					CSSM_AC_BASE_AC_ERROR + 3,
+	CSSMERR_AC_INVALID_VALIDITY_PERIOD =			CSSM_AC_BASE_AC_ERROR + 4,
+	CSSMERR_AC_INVALID_REQUESTOR =					CSSM_AC_BASE_AC_ERROR + 5,
+	CSSMERR_AC_INVALID_REQUEST_DESCRIPTOR =			CSSM_AC_BASE_AC_ERROR + 6
+};
+
+/* CL Error Values Derived from Common Error Codes For All Module Types. */
+enum {
+	CSSMERR_CL_INTERNAL_ERROR =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR,
+	CSSMERR_CL_MEMORY_ERROR =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR,
+	CSSMERR_CL_MDS_ERROR =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR,
+	CSSMERR_CL_INVALID_POINTER =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER,
+	CSSMERR_CL_INVALID_INPUT_POINTER =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER,
+	CSSMERR_CL_INVALID_OUTPUT_POINTER =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER,
+	CSSMERR_CL_FUNCTION_NOT_IMPLEMENTED =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED,
+	CSSMERR_CL_SELF_CHECK_FAILED =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED,
+	CSSMERR_CL_OS_ACCESS_DENIED =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED,
+	CSSMERR_CL_FUNCTION_FAILED =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED,
+	CSSMERR_CL_INVALID_CONTEXT_HANDLE =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE,
+	CSSMERR_CL_INVALID_CERTGROUP_POINTER =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_CERTGROUP_POINTER,
+	CSSMERR_CL_INVALID_CERT_POINTER =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_CERT_POINTER,
+	CSSMERR_CL_INVALID_CRL_POINTER =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_CRL_POINTER,
+	CSSMERR_CL_INVALID_FIELD_POINTER =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_FIELD_POINTER,
+	CSSMERR_CL_INVALID_DATA =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_DATA,
+	CSSMERR_CL_CRL_ALREADY_SIGNED =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_CRL_ALREADY_SIGNED,
+	CSSMERR_CL_INVALID_NUMBER_OF_FIELDS =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_NUMBER_OF_FIELDS,
+	CSSMERR_CL_VERIFICATION_FAILURE =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_VERIFICATION_FAILURE,
+	CSSMERR_CL_UNKNOWN_FORMAT =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_UNKNOWN_FORMAT,
+	CSSMERR_CL_UNKNOWN_TAG =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_UNKNOWN_TAG,
+	CSSMERR_CL_INVALID_PASSTHROUGH_ID =
+		CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID
+};
+
+/* CL Module-Specific Error Values */
+enum {
+	CSSM_CL_BASE_CL_ERROR =
+		CSSM_CL_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT,
+	CSSMERR_CL_INVALID_BUNDLE_POINTER =				CSSM_CL_BASE_CL_ERROR + 1,
+	CSSMERR_CL_INVALID_CACHE_HANDLE =				CSSM_CL_BASE_CL_ERROR + 2,
+	CSSMERR_CL_INVALID_RESULTS_HANDLE =				CSSM_CL_BASE_CL_ERROR + 3,
+	CSSMERR_CL_INVALID_BUNDLE_INFO =				CSSM_CL_BASE_CL_ERROR + 4,
+	CSSMERR_CL_INVALID_CRL_INDEX =					CSSM_CL_BASE_CL_ERROR + 5,
+	CSSMERR_CL_INVALID_SCOPE =						CSSM_CL_BASE_CL_ERROR + 6,
+	CSSMERR_CL_NO_FIELD_VALUES =					CSSM_CL_BASE_CL_ERROR + 7,
+	CSSMERR_CL_SCOPE_NOT_SUPPORTED =				CSSM_CL_BASE_CL_ERROR + 8
+};
+
+/* DL Error Values Derived from Common Error Codes For All Module Types. */
+enum {
+	CSSMERR_DL_INTERNAL_ERROR =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR,
+	CSSMERR_DL_MEMORY_ERROR =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR,
+	CSSMERR_DL_MDS_ERROR =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR,
+	CSSMERR_DL_INVALID_POINTER =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER,
+	CSSMERR_DL_INVALID_INPUT_POINTER =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER,
+	CSSMERR_DL_INVALID_OUTPUT_POINTER =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER,
+	CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED,
+	CSSMERR_DL_SELF_CHECK_FAILED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED,
+	CSSMERR_DL_OS_ACCESS_DENIED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED,
+	CSSMERR_DL_FUNCTION_FAILED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED
+};
+
+/* DL Error Values Derived from ACL-based Error Codes. */
+enum {
+	CSSMERR_DL_OPERATION_AUTH_DENIED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OPERATION_AUTH_DENIED,
+	CSSMERR_DL_OBJECT_USE_AUTH_DENIED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OBJECT_USE_AUTH_DENIED,
+	CSSMERR_DL_OBJECT_MANIP_AUTH_DENIED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED,
+	CSSMERR_DL_OBJECT_ACL_NOT_SUPPORTED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED,
+	CSSMERR_DL_OBJECT_ACL_REQUIRED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OBJECT_ACL_REQUIRED,
+	CSSMERR_DL_INVALID_ACCESS_CREDENTIALS =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACCESS_CREDENTIALS,
+	CSSMERR_DL_INVALID_ACL_BASE_CERTS =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_BASE_CERTS,
+	CSSMERR_DL_ACL_BASE_CERTS_NOT_SUPPORTED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_BASE_CERTS_NOT_SUPPORTED,
+	CSSMERR_DL_INVALID_SAMPLE_VALUE =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_SAMPLE_VALUE,
+	CSSMERR_DL_SAMPLE_VALUE_NOT_SUPPORTED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED,
+	CSSMERR_DL_INVALID_ACL_SUBJECT_VALUE =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE,
+	CSSMERR_DL_ACL_SUBJECT_TYPE_NOT_SUPPORTED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED,
+	CSSMERR_DL_INVALID_ACL_CHALLENGE_CALLBACK =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_CHALLENGE_CALLBACK,
+	CSSMERR_DL_ACL_CHALLENGE_CALLBACK_FAILED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_CHALLENGE_CALLBACK_FAILED,
+	CSSMERR_DL_INVALID_ACL_ENTRY_TAG =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG,
+	CSSMERR_DL_ACL_ENTRY_TAG_NOT_FOUND =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_ENTRY_TAG_NOT_FOUND,
+	CSSMERR_DL_INVALID_ACL_EDIT_MODE =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_EDIT_MODE,
+	CSSMERR_DL_ACL_CHANGE_FAILED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_CHANGE_FAILED,
+	CSSMERR_DL_INVALID_NEW_ACL_ENTRY =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_NEW_ACL_ENTRY,
+	CSSMERR_DL_INVALID_NEW_ACL_OWNER =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_NEW_ACL_OWNER,
+	CSSMERR_DL_ACL_DELETE_FAILED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_DELETE_FAILED,
+	CSSMERR_DL_ACL_REPLACE_FAILED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_REPLACE_FAILED,
+	CSSMERR_DL_ACL_ADD_FAILED =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_ADD_FAILED
+};
+
+/* DL Error Values for Specific Data Types. */
+enum {
+	CSSMERR_DL_INVALID_DB_HANDLE =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_HANDLE,
+	CSSMERR_DL_INVALID_PASSTHROUGH_ID =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID,
+	CSSMERR_DL_INVALID_NETWORK_ADDR =
+		CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_NETWORK_ADDR
+};
+
+/* DL Module-Specific Error Values */
+enum {
+	CSSM_DL_BASE_DL_ERROR =
+		CSSM_DL_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT,
+	CSSMERR_DL_DATABASE_CORRUPT =					CSSM_DL_BASE_DL_ERROR + 1,
+	CSSMERR_DL_INVALID_RECORD_INDEX =				CSSM_DL_BASE_DL_ERROR + 8,
+	CSSMERR_DL_INVALID_RECORDTYPE =					CSSM_DL_BASE_DL_ERROR + 9,
+	CSSMERR_DL_INVALID_FIELD_NAME =					CSSM_DL_BASE_DL_ERROR + 10,
+	CSSMERR_DL_UNSUPPORTED_FIELD_FORMAT =			CSSM_DL_BASE_DL_ERROR + 11,
+	CSSMERR_DL_UNSUPPORTED_INDEX_INFO =				CSSM_DL_BASE_DL_ERROR + 12,
+	CSSMERR_DL_UNSUPPORTED_LOCALITY =				CSSM_DL_BASE_DL_ERROR + 13,
+	CSSMERR_DL_UNSUPPORTED_NUM_ATTRIBUTES =			CSSM_DL_BASE_DL_ERROR + 14,
+	CSSMERR_DL_UNSUPPORTED_NUM_INDEXES =			CSSM_DL_BASE_DL_ERROR + 15,
+	CSSMERR_DL_UNSUPPORTED_NUM_RECORDTYPES =		CSSM_DL_BASE_DL_ERROR + 16,
+	CSSMERR_DL_UNSUPPORTED_RECORDTYPE =				CSSM_DL_BASE_DL_ERROR + 17,
+	CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE =			CSSM_DL_BASE_DL_ERROR + 18,
+	CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT =			CSSM_DL_BASE_DL_ERROR + 19,
+	CSSMERR_DL_INVALID_PARSING_MODULE =				CSSM_DL_BASE_DL_ERROR + 20,
+	CSSMERR_DL_INVALID_DB_NAME =					CSSM_DL_BASE_DL_ERROR + 22,
+	CSSMERR_DL_DATASTORE_DOESNOT_EXIST =			CSSM_DL_BASE_DL_ERROR + 23,
+	CSSMERR_DL_DATASTORE_ALREADY_EXISTS =			CSSM_DL_BASE_DL_ERROR + 24,
+	CSSMERR_DL_DB_LOCKED =							CSSM_DL_BASE_DL_ERROR + 25,
+	CSSMERR_DL_DATASTORE_IS_OPEN =					CSSM_DL_BASE_DL_ERROR + 26,
+	CSSMERR_DL_RECORD_NOT_FOUND =					CSSM_DL_BASE_DL_ERROR + 27,
+	CSSMERR_DL_MISSING_VALUE =						CSSM_DL_BASE_DL_ERROR + 28,
+	CSSMERR_DL_UNSUPPORTED_QUERY =					CSSM_DL_BASE_DL_ERROR + 29,
+	CSSMERR_DL_UNSUPPORTED_QUERY_LIMITS =			CSSM_DL_BASE_DL_ERROR + 30,
+	CSSMERR_DL_UNSUPPORTED_NUM_SELECTION_PREDS =	CSSM_DL_BASE_DL_ERROR + 31,
+	CSSMERR_DL_UNSUPPORTED_OPERATOR =				CSSM_DL_BASE_DL_ERROR + 33,
+	CSSMERR_DL_INVALID_RESULTS_HANDLE =				CSSM_DL_BASE_DL_ERROR + 34,
+	CSSMERR_DL_INVALID_DB_LOCATION =				CSSM_DL_BASE_DL_ERROR + 35,
+	CSSMERR_DL_INVALID_ACCESS_REQUEST =				CSSM_DL_BASE_DL_ERROR + 36,
+	CSSMERR_DL_INVALID_INDEX_INFO =					CSSM_DL_BASE_DL_ERROR + 37,
+	CSSMERR_DL_INVALID_SELECTION_TAG =				CSSM_DL_BASE_DL_ERROR + 38,
+	CSSMERR_DL_INVALID_NEW_OWNER =					CSSM_DL_BASE_DL_ERROR + 39,
+	CSSMERR_DL_INVALID_RECORD_UID =					CSSM_DL_BASE_DL_ERROR + 40,
+	CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA =			CSSM_DL_BASE_DL_ERROR + 41,
+	CSSMERR_DL_INVALID_MODIFY_MODE =				CSSM_DL_BASE_DL_ERROR + 42,
+	CSSMERR_DL_INVALID_OPEN_PARAMETERS =			CSSM_DL_BASE_DL_ERROR + 43,
+	CSSMERR_DL_RECORD_MODIFIED =					CSSM_DL_BASE_DL_ERROR + 44,
+	CSSMERR_DL_ENDOFDATA =							CSSM_DL_BASE_DL_ERROR + 45,
+	CSSMERR_DL_INVALID_QUERY =						CSSM_DL_BASE_DL_ERROR + 46,
+	CSSMERR_DL_INVALID_VALUE =						CSSM_DL_BASE_DL_ERROR + 47,
+	CSSMERR_DL_MULTIPLE_VALUES_UNSUPPORTED =		CSSM_DL_BASE_DL_ERROR + 48,
+	CSSMERR_DL_STALE_UNIQUE_RECORD =				CSSM_DL_BASE_DL_ERROR + 49
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMERR_H_ */
diff --git a/cdsa/cdsa/cssmkrapi.h b/cdsa/cdsa/cssmkrapi.h
new file mode 100644
index 00000000..b73be5be
--- /dev/null
+++ b/cdsa/cdsa/cssmkrapi.h
@@ -0,0 +1,229 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmkrapi.h
+
+   Contains:  Application Programmers Interface for Key Recovery Modules
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMKRAPI_H_
+#define _CSSMKRAPI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint32 CSSM_KRSP_HANDLE; /* Key Recovery Service Provider Handle */
+
+typedef struct cssm_kr_name {
+    uint8 Type; /* namespace type */
+    uint8 Length; /* name string length */
+    char *Name; /* name string */
+} CSSM_KR_NAME;
+
+typedef struct cssm_kr_profile {
+    CSSM_KR_NAME UserName; /* name of the user */
+    CSSM_CERTGROUP_PTR UserCertificate; /* public key certificate of the user */
+    CSSM_CERTGROUP_PTR KRSCertChain; /* cert chain for the KRSP coordinator */
+    uint8 LE_KRANum; /* number of KRA cert chains in the following list */
+    CSSM_CERTGROUP_PTR LE_KRACertChainList; /* list of Law enforcement KRA certificate chains */
+    uint8 ENT_KRANum; /* number of KRA cert chains in the following list */
+    CSSM_CERTGROUP_PTR ENT_KRACertChainList; /* list of Enterprise KRA certificate chains */
+    uint8 INDIV_KRANum; /* number of KRA cert chains in the following list */
+    CSSM_CERTGROUP_PTR INDIV_KRACertChainList; /* list of Individual KRA certificate chains */
+    CSSM_DATA_PTR INDIV_AuthenticationInfo; /* authentication information for individual key recovery */
+    uint32 KRSPFlags; /* flag values to be interpreted by KRSP */
+    CSSM_DATA_PTR KRSPExtensions; /* reserved for extensions specific to KRSPs */
+} CSSM_KR_PROFILE, *CSSM_KR_PROFILE_PTR;
+
+typedef struct cssm_kr_wrappedproductinfo {
+    CSSM_VERSION StandardVersion;
+    CSSM_STRING StandardDescription;
+    CSSM_VERSION ProductVersion;
+    CSSM_STRING ProductDescription;
+    CSSM_STRING ProductVendor;
+    uint32 ProductFlags;
+} CSSM_KR_WRAPPEDPRODUCT_INFO, *CSSM_KR_WRAPPEDPRODUCT_INFO_PTR;
+
+typedef struct cssm_krsubservice {
+    uint32 SubServiceId;
+    char *Description; /* Description of this sub service */
+    CSSM_KR_WRAPPEDPRODUCT_INFO WrappedProduct;
+} CSSM_KRSUBSERVICE, *CSSM_KRSUBSERVICE_PTR;
+
+typedef uint32 CSSM_KR_POLICY_TYPE;
+#define CSSM_KR_INDIV_POLICY			(0x00000001)
+#define CSSM_KR_ENT_POLICY				(0x00000002)
+#define CSSM_KR_LE_MAN_POLICY			(0x00000003)
+#define CSSM_KR_LE_USE_POLICY			(0x00000004)
+
+typedef uint32 CSSM_KR_POLICY_FLAGS;
+
+#define CSSM_KR_INDIV					(0x00000001)
+#define CSSM_KR_ENT						(0x00000002)
+#define CSSM_KR_LE_MAN					(0x00000004)
+#define CSSM_KR_LE_USE					(0x00000008)
+#define CSSM_KR_LE						(CSSM_KR_LE_MAN | CSSM_KR_LE_USE)
+#define CSSM_KR_OPTIMIZE				(0x00000010)
+#define CSSM_KR_DROP_WORKFACTOR			(0x00000020)
+
+typedef struct cssm_kr_policy_list_item {
+    struct kr_policy_list_item *next;
+    CSSM_ALGORITHMS AlgorithmId;
+    CSSM_ENCRYPT_MODE Mode;
+    uint32 MaxKeyLength;
+    uint32 MaxRounds;
+    uint8 WorkFactor;
+    CSSM_KR_POLICY_FLAGS PolicyFlags;
+    CSSM_CONTEXT_TYPE AlgClass;
+} CSSM_KR_POLICY_LIST_ITEM, *CSSM_KR_POLICY_LIST_ITEM_PTR;
+
+typedef struct cssm_kr_policy_info {
+    CSSM_BOOL krbNotAllowed;
+    uint32 numberOfEntries;
+    CSSM_KR_POLICY_LIST_ITEM *policyEntry;
+} CSSM_KR_POLICY_INFO, *CSSM_KR_POLICY_INFO_PTR;
+
+
+/* Key Recovery Module Mangement Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_SetEnterpriseRecoveryPolicy (const CSSM_DATA *RecoveryPolicyFileName,
+                                     const CSSM_ACCESS_CREDENTIALS *OldPassPhrase,
+                                     const CSSM_ACCESS_CREDENTIALS *NewPassPhrase);
+
+
+/* Key Recovery Context Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_CreateRecoveryRegistrationContext (CSSM_KRSP_HANDLE KRSPHandle,
+                                           CSSM_CC_HANDLE *NewContext);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_CreateRecoveryEnablementContext (CSSM_KRSP_HANDLE KRSPHandle,
+                                         const CSSM_KR_PROFILE *LocalProfile,
+                                         const CSSM_KR_PROFILE *RemoteProfile,
+                                         CSSM_CC_HANDLE *NewContext);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_CreateRecoveryRequestContext (CSSM_KRSP_HANDLE KRSPHandle,
+                                      const CSSM_KR_PROFILE *LocalProfile,
+                                      CSSM_CC_HANDLE *NewContext);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_GetPolicyInfo (CSSM_CC_HANDLE CCHandle,
+                       CSSM_KR_POLICY_FLAGS *EncryptionProhibited,
+                       uint32 *WorkFactor);
+
+
+/* Key Recovery Registration Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_RegistrationRequest (CSSM_CC_HANDLE RecoveryRegistrationContext,
+                             const CSSM_DATA *KRInData,
+                             const CSSM_ACCESS_CREDENTIALS *AccessCredentials,
+                             CSSM_KR_POLICY_FLAGS KRFlags,
+                             sint32 *EstimatedTime,
+                             CSSM_HANDLE_PTR ReferenceHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_RegistrationRetrieve (CSSM_KRSP_HANDLE KRSPHandle,
+                              CSSM_HANDLE ReferenceHandle,
+                              const CSSM_ACCESS_CREDENTIALS *AccessCredentials,
+                              sint32 *EstimatedTime,
+                              CSSM_KR_PROFILE_PTR KRProfile);
+
+
+/* Key Recovery Enablement Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_GenerateRecoveryFields (CSSM_CC_HANDLE KeyRecoveryContext,
+                                CSSM_CC_HANDLE CCHandle,
+                                const CSSM_DATA *KRSPOptions,
+                                CSSM_KR_POLICY_FLAGS KRFlags,
+                                CSSM_DATA_PTR KRFields,
+                                CSSM_CC_HANDLE *NewCCHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_ProcessRecoveryFields (CSSM_CC_HANDLE KeyRecoveryContext,
+                               CSSM_CC_HANDLE CryptoContext,
+                               const CSSM_DATA *KRSPOptions,
+                               CSSM_KR_POLICY_FLAGS KRFlags,
+                               const CSSM_DATA *KRFields,
+                               CSSM_CC_HANDLE *NewCryptoContext);
+
+
+/* Key Recovery Request Operations */
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_RecoveryRequest (CSSM_CC_HANDLE RecoveryRequestContext,
+                         const CSSM_DATA *KRInData,
+                         const CSSM_ACCESS_CREDENTIALS *AccessCredentials,
+                         sint32 *EstimatedTime,
+                         CSSM_HANDLE_PTR ReferenceHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_RecoveryRetrieve (CSSM_KRSP_HANDLE KRSPHandle,
+                          CSSM_HANDLE ReferenceHandle,
+                          const CSSM_ACCESS_CREDENTIALS *AccessCredentials,
+                          sint32 *EstimatedTime,
+                          CSSM_HANDLE_PTR CacheHandle,
+                          uint32 *NumberOfRecoveredKeys);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_GetRecoveredObject (CSSM_KRSP_HANDLE KRSPHandle,
+                            CSSM_HANDLE CacheHandle,
+                            uint32 IndexInResults,
+                            CSSM_CSP_HANDLE CSPHandle,
+                            const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                            uint32 Flags,
+                            CSSM_KEY_PTR RecoveredKey,
+                            CSSM_DATA_PTR OtherInfo);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_RecoveryRequestAbort (CSSM_KRSP_HANDLE KRSPHandle,
+                              CSSM_HANDLE CacheHandle);
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_QueryPolicyInfo (CSSM_KRSP_HANDLE KRSPHandle,
+                         CSSM_ALGORITHMS AlgorithmID,
+                         CSSM_ENCRYPT_MODE Mode,
+                         CSSM_CONTEXT_TYPE Class,
+                         CSSM_KR_POLICY_INFO_PTR *PolicyInfoData);
+
+
+/* Extensibility Functions */
+
+CSSM_RETURN CSSMAPI
+CSSM_KR_PassThrough (CSSM_KRSP_HANDLE KRSPHandle,
+                     CSSM_CC_HANDLE KeyRecoveryContext,
+                     CSSM_CC_HANDLE CryptoContext,
+                     uint32 PassThroughId,
+                     const void *InputParams,
+                     void **OutputParams);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMKRAPI_H_ */
diff --git a/cdsa/cdsa/cssmkrspi.h b/cdsa/cdsa/cssmkrspi.h
new file mode 100644
index 00000000..ba86477c
--- /dev/null
+++ b/cdsa/cdsa/cssmkrspi.h
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmkrspi.h
+
+   Contains:  Service Provider Interface for Key Recovery Modules
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMKRSPI_H_
+#define _CSSMKRSPI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Data types for Key Recovery SPI */
+
+typedef struct cssm_spi_kr_funcs {
+    CSSM_RETURN (CSSMKRI *RegistrationRequest)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_CC_HANDLE KRRegistrationContextHandle,
+         const CSSM_CONTEXT *KRRegistrationContext,
+         const CSSM_DATA *KRInData,
+         const CSSM_ACCESS_CREDENTIALS *AccessCredentials,
+         CSSM_KR_POLICY_FLAGS KRFlags,
+         sint32 *EstimatedTime,
+         CSSM_HANDLE_PTR ReferenceHandle);
+    CSSM_RETURN (CSSMKRI *RegistrationRetrieve)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_HANDLE ReferenceHandle,
+         sint32 *EstimatedTime,
+         CSSM_KR_PROFILE_PTR KRProfile);
+    CSSM_RETURN (CSSMKRI *GenerateRecoveryFields)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_CC_HANDLE KREnablementContextHandle,
+         const CSSM_CONTEXT *KREnablementContext,
+         CSSM_CC_HANDLE CryptoContextHandle,
+         const CSSM_CONTEXT *CryptoContext,
+         const CSSM_DATA *KRSPOptions,
+         CSSM_KR_POLICY_FLAGS KRFlags,
+         CSSM_DATA_PTR KRFields);
+    CSSM_RETURN (CSSMKRI *ProcessRecoveryFields)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_CC_HANDLE KREnablementContextHandle,
+         const CSSM_CONTEXT *KREnablementContext,
+         CSSM_CC_HANDLE CryptoContextHandle,
+         const CSSM_CONTEXT *CryptoContext,
+         const CSSM_DATA *KRSPOptions,
+         CSSM_KR_POLICY_FLAGS KRFlags,
+         const CSSM_DATA *KRFields);
+    CSSM_RETURN (CSSMKRI *RecoveryRequest)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_CC_HANDLE KRRequestContextHandle,
+         const CSSM_CONTEXT *KRRequestContext,
+         const CSSM_DATA *KRInData,
+         const CSSM_ACCESS_CREDENTIALS *AccessCredentials,
+         sint32 *EstimatedTime,
+         CSSM_HANDLE_PTR ReferenceHandle);
+    CSSM_RETURN (CSSMKRI *RecoveryRetrieve)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_HANDLE ReferenceHandle,
+         sint32 *EstimatedTime,
+         CSSM_HANDLE_PTR CacheHandle,
+         uint32 *NumberOfRecoveredKeys);
+    CSSM_RETURN (CSSMKRI *GetRecoveredObject)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_HANDLE CacheHandle,
+         uint32 IndexInResults,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+         uint32 Flags,
+         CSSM_KEY_PTR RecoveredKey,
+         CSSM_DATA_PTR OtherInfo);
+    CSSM_RETURN (CSSMKRI *RecoveryRequestAbort)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_HANDLE ResultsHandle);
+    CSSM_RETURN (CSSMKRI *PassThrough)
+        (CSSM_KRSP_HANDLE KRSPHandle,
+         CSSM_CC_HANDLE KeyRecoveryContextHandle,
+         const CSSM_CONTEXT *KeyRecoveryContext,
+         CSSM_CC_HANDLE CryptoContextHandle,
+         const CSSM_CONTEXT *CryptoContext,
+         uint32 PassThroughId,
+         const void *InputParams,
+         void **OutputParams);
+} CSSM_SPI_KR_FUNCS, *CSSM_SPI_KR_FUNCS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMKRSPI_H_ */
diff --git a/cdsa/cdsa/cssmspi.h b/cdsa/cdsa/cssmspi.h
new file mode 100644
index 00000000..a2f4725a
--- /dev/null
+++ b/cdsa/cdsa/cssmspi.h
@@ -0,0 +1,151 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmspi.h
+
+   Contains:  Service Provider Interface for CSSM Modules
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMSPI_H_
+#define _CSSMSPI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef CSSM_RETURN (CSSMAPI *CSSM_SPI_ModuleEventHandler)
+    (const CSSM_GUID *ModuleGuid,
+     void *CssmNotifyCallbackCtx,
+     uint32 SubserviceId,
+     CSSM_SERVICE_TYPE ServiceType,
+     CSSM_MODULE_EVENT EventType);
+
+typedef uint32 CSSM_CONTEXT_EVENT;
+enum {
+    CSSM_CONTEXT_EVENT_CREATE = 1,
+    CSSM_CONTEXT_EVENT_DELETE = 2,
+    CSSM_CONTEXT_EVENT_UPDATE = 3
+};
+
+typedef struct cssm_module_funcs {
+    CSSM_SERVICE_TYPE ServiceType;
+    uint32 NumberOfServiceFuncs;
+    const CSSM_PROC_ADDR *ServiceFuncs;
+} CSSM_MODULE_FUNCS, *CSSM_MODULE_FUNCS_PTR;
+
+typedef void *(CSSMAPI *CSSM_UPCALLS_MALLOC)
+    (CSSM_HANDLE AddInHandle,
+     uint32 size);
+
+typedef void (CSSMAPI *CSSM_UPCALLS_FREE)
+    (CSSM_HANDLE AddInHandle,
+     void *memblock);
+
+typedef void *(CSSMAPI *CSSM_UPCALLS_REALLOC)
+    (CSSM_HANDLE AddInHandle,
+     void *memblock,
+     uint32 size);
+
+typedef void *(CSSMAPI *CSSM_UPCALLS_CALLOC)
+    (CSSM_HANDLE AddInHandle,
+     uint32 num,
+     uint32 size);
+
+typedef struct cssm_upcalls {
+    CSSM_UPCALLS_MALLOC malloc_func;
+    CSSM_UPCALLS_FREE free_func;
+    CSSM_UPCALLS_REALLOC realloc_func;
+    CSSM_UPCALLS_CALLOC calloc_func;
+    CSSM_RETURN (CSSMAPI *CcToHandle_func)
+        (CSSM_CC_HANDLE Cc,
+         CSSM_MODULE_HANDLE_PTR ModuleHandle);
+    CSSM_RETURN (CSSMAPI *GetModuleInfo_func)
+        (CSSM_MODULE_HANDLE Module,
+         CSSM_GUID_PTR Guid,
+         CSSM_VERSION_PTR Version,
+         uint32 *SubServiceId,
+         CSSM_SERVICE_TYPE *SubServiceType,
+         CSSM_ATTACH_FLAGS *AttachFlags,
+         CSSM_KEY_HIERARCHY *KeyHierarchy,
+         CSSM_API_MEMORY_FUNCS_PTR AttachedMemFuncs,
+         CSSM_FUNC_NAME_ADDR_PTR FunctionTable,
+         uint32 NumFunctions);
+} CSSM_UPCALLS, *CSSM_UPCALLS_PTR;
+
+CSSM_RETURN CSSMSPI
+CSSM_SPI_ModuleLoad (const CSSM_GUID *CssmGuid,
+                     const CSSM_GUID *ModuleGuid,
+                     CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+                     void *CssmNotifyCallbackCtx);
+
+CSSM_RETURN CSSMSPI
+CSSM_SPI_ModuleUnload (const CSSM_GUID *CssmGuid,
+                       const CSSM_GUID *ModuleGuid,
+                       CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+                       void *CssmNotifyCallbackCtx);
+
+CSSM_RETURN CSSMSPI
+CSSM_SPI_ModuleAttach (const CSSM_GUID *ModuleGuid,
+                       const CSSM_VERSION *Version,
+                       uint32 SubserviceID,
+                       CSSM_SERVICE_TYPE SubServiceType,
+                       CSSM_ATTACH_FLAGS AttachFlags,
+                       CSSM_MODULE_HANDLE ModuleHandle,
+                       CSSM_KEY_HIERARCHY KeyHierarchy,
+                       const CSSM_GUID *CssmGuid,
+                       const CSSM_GUID *ModuleManagerGuid,
+                       const CSSM_GUID *CallerGuid,
+                       const CSSM_UPCALLS *Upcalls,
+                       CSSM_MODULE_FUNCS_PTR *FuncTbl);
+
+CSSM_RETURN CSSMSPI
+CSSM_SPI_ModuleDetach (CSSM_MODULE_HANDLE ModuleHandle);
+
+#if 0
+/* XXX You should call these though the Upcalls structure passed into
+   moduleattach, --Michael. */
+
+/* CSSM Upcalls for Service Provider Modules */
+
+CSSM_RETURN CSSMAPI
+cssm_CcToHandle (CSSM_CC_HANDLE Cc,
+                 CSSM_MODULE_HANDLE *ModuleHandle);
+
+CSSM_RETURN CSSMAPI
+cssm_GetModuleInfo (CSSM_MODULE_HANDLE Module,
+                    CSSM_GUID_PTR Guid,
+                    CSSM_VERSION_PTR Version,
+                    uint32 *SubServiceId,
+                    CSSM_SERVICE_TYPE *SubServiceType,
+                    CSSM_ATTACH_FLAGS *AttachFlags,
+                    CSSM_KEY_HIERARCHY *KeyHierarchy,
+                    CSSM_API_MEMORY_FUNCS_PTR AttachedMemFuncs,
+                    CSSM_FUNC_NAME_ADDR_PTR FunctionTable,
+                    uint32 NumFunctions);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMSPI_H_ */
diff --git a/cdsa/cdsa/cssmtpi.h b/cdsa/cdsa/cssmtpi.h
new file mode 100644
index 00000000..6065c5a3
--- /dev/null
+++ b/cdsa/cdsa/cssmtpi.h
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmtpi.h
+
+   Contains:  Service Provider Interface for Trust Policy Modules
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMTPI_H_
+#define _CSSMTPI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct cssm_spi_tp_funcs {
+    CSSM_RETURN (CSSMTPI *SubmitCredRequest)
+        (CSSM_TP_HANDLE TPHandle,
+         const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
+         CSSM_TP_AUTHORITY_REQUEST_TYPE RequestType,
+         const CSSM_TP_REQUEST_SET *RequestInput,
+         const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthContext,
+         sint32 *EstimatedTime,
+         CSSM_DATA_PTR ReferenceIdentifier);
+    CSSM_RETURN (CSSMTPI *RetrieveCredResult)
+        (CSSM_TP_HANDLE TPHandle,
+         const CSSM_DATA *ReferenceIdentifier,
+         const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
+         sint32 *EstimatedTime,
+         CSSM_BOOL *ConfirmationRequired,
+         CSSM_TP_RESULT_SET_PTR *RetrieveOutput);
+    CSSM_RETURN (CSSMTPI *ConfirmCredResult)
+        (CSSM_TP_HANDLE TPHandle,
+         const CSSM_DATA *ReferenceIdentifier,
+         const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
+         const CSSM_TP_CONFIRM_RESPONSE *Responses,
+         const CSSM_TP_AUTHORITY_ID *PreferredAuthority);
+    CSSM_RETURN (CSSMTPI *ReceiveConfirmation)
+        (CSSM_TP_HANDLE TPHandle,
+         const CSSM_DATA *ReferenceIdentifier,
+         CSSM_TP_CONFIRM_RESPONSE_PTR *Responses,
+         sint32 *ElapsedTime);
+    CSSM_RETURN (CSSMTPI *CertReclaimKey)
+        (CSSM_TP_HANDLE TPHandle,
+         const CSSM_CERTGROUP *CertGroup,
+         uint32 CertIndex,
+         CSSM_LONG_HANDLE KeyCacheHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry);
+    CSSM_RETURN (CSSMTPI *CertReclaimAbort)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_LONG_HANDLE KeyCacheHandle);
+    CSSM_RETURN (CSSMTPI *FormRequest)
+        (CSSM_TP_HANDLE TPHandle,
+         const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
+         CSSM_TP_FORM_TYPE FormType,
+         CSSM_DATA_PTR BlankForm);
+    CSSM_RETURN (CSSMTPI *FormSubmit)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_TP_FORM_TYPE FormType,
+         const CSSM_DATA *Form,
+         const CSSM_TP_AUTHORITY_ID *ClearanceAuthority,
+         const CSSM_TP_AUTHORITY_ID *RepresentedAuthority,
+         CSSM_ACCESS_CREDENTIALS_PTR Credentials);
+    CSSM_RETURN (CSSMTPI *CertGroupVerify)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_CERTGROUP *CertGroupToBeVerified,
+         const CSSM_TP_VERIFY_CONTEXT *VerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR VerifyContextResult);
+    CSSM_RETURN (CSSMTPI *CertCreateTemplate)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         uint32 NumberOfFields,
+         const CSSM_FIELD *CertFields,
+         CSSM_DATA_PTR CertTemplate);
+    CSSM_RETURN (CSSMTPI *CertGetAllTemplateFields)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         const CSSM_DATA *CertTemplate,
+         uint32 *NumberOfFields,
+         CSSM_FIELD_PTR *CertFields);
+    CSSM_RETURN (CSSMTPI *CertSign)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DATA *CertTemplateToBeSigned,
+         const CSSM_CERTGROUP *SignerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT *SignerVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR SignerVerifyResult,
+         CSSM_DATA_PTR SignedCert);
+    CSSM_RETURN (CSSMTPI *CrlVerify)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ENCODED_CRL *CrlToBeVerified,
+         const CSSM_CERTGROUP *SignerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT *VerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR RevokerVerifyResult);
+    CSSM_RETURN (CSSMTPI *CrlCreateTemplate)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         uint32 NumberOfFields,
+         const CSSM_FIELD *CrlFields,
+         CSSM_DATA_PTR NewCrlTemplate);
+    CSSM_RETURN (CSSMTPI *CertRevoke)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_DATA *OldCrlTemplate,
+         const CSSM_CERTGROUP *CertGroupToBeRevoked,
+         const CSSM_CERTGROUP *RevokerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT *RevokerVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR RevokerVerifyResult,
+         CSSM_TP_CERTCHANGE_REASON Reason,
+         CSSM_DATA_PTR NewCrlTemplate);
+    CSSM_RETURN (CSSMTPI *CertRemoveFromCrlTemplate)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_DATA *OldCrlTemplate,
+         const CSSM_CERTGROUP *CertGroupToBeRemoved,
+         const CSSM_CERTGROUP *RevokerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT *RevokerVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR RevokerVerifyResult,
+         CSSM_DATA_PTR NewCrlTemplate);
+    CSSM_RETURN (CSSMTPI *CrlSign)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_ENCODED_CRL *CrlToBeSigned,
+         const CSSM_CERTGROUP *SignerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT *SignerVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR SignerVerifyResult,
+         CSSM_DATA_PTR SignedCrl);
+    CSSM_RETURN (CSSMTPI *ApplyCrlToDb)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_ENCODED_CRL *CrlToBeApplied,
+         const CSSM_CERTGROUP *SignerCertGroup,
+         const CSSM_TP_VERIFY_CONTEXT *ApplyCrlVerifyContext,
+         CSSM_TP_VERIFY_CONTEXT_RESULT_PTR ApplyCrlVerifyResult);
+    CSSM_RETURN (CSSMTPI *CertGroupConstruct)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CSP_HANDLE CSPHandle,
+         const CSSM_DL_DB_LIST *DBList,
+         const void *ConstructParams,
+         const CSSM_CERTGROUP *CertGroupFrag,
+         CSSM_CERTGROUP_PTR *CertGroup);
+    CSSM_RETURN (CSSMTPI *CertGroupPrune)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         const CSSM_DL_DB_LIST *DBList,
+         const CSSM_CERTGROUP *OrderedCertGroup,
+         CSSM_CERTGROUP_PTR *PrunedCertGroup);
+    CSSM_RETURN (CSSMTPI *CertGroupToTupleGroup)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         const CSSM_CERTGROUP *CertGroup,
+         CSSM_TUPLEGROUP_PTR *TupleGroup);
+    CSSM_RETURN (CSSMTPI *TupleGroupToCertGroup)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         const CSSM_TUPLEGROUP *TupleGroup,
+         CSSM_CERTGROUP_PTR *CertTemplates);
+    CSSM_RETURN (CSSMTPI *PassThrough)
+        (CSSM_TP_HANDLE TPHandle,
+         CSSM_CL_HANDLE CLHandle,
+         CSSM_CC_HANDLE CCHandle,
+         const CSSM_DL_DB_LIST *DBList,
+         uint32 PassThroughId,
+         const void *InputParams,
+         void **OutputParams);
+} CSSM_SPI_TP_FUNCS, *CSSM_SPI_TP_FUNCS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMTPI_H_ */
diff --git a/cdsa/cdsa/cssmtype.h b/cdsa/cdsa/cssmtype.h
new file mode 100644
index 00000000..59a47f2b
--- /dev/null
+++ b/cdsa/cdsa/cssmtype.h
@@ -0,0 +1,2074 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      cssmtype.h
+
+   Contains:  Common Security Services Manager Common Data Types
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _CSSMTYPE_H_
+#define _CSSMTYPE_H_  1
+
+#include <Security/cssmconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Handle types. */
+
+typedef uint32 CSSM_HANDLE, *CSSM_HANDLE_PTR;
+
+typedef uint64 CSSM_LONG_HANDLE, *CSSM_LONG_HANDLE_PTR;
+
+typedef CSSM_HANDLE CSSM_MODULE_HANDLE, *CSSM_MODULE_HANDLE_PTR;
+
+typedef CSSM_LONG_HANDLE CSSM_CC_HANDLE; /* Cryptographic Context Handle */
+
+typedef CSSM_MODULE_HANDLE CSSM_CSP_HANDLE; /* Cryptographic Service Provider Handle */
+
+typedef CSSM_MODULE_HANDLE CSSM_TP_HANDLE; /* Trust Policy Handle */
+
+typedef CSSM_MODULE_HANDLE CSSM_AC_HANDLE; /* Authorization Computation Handle */
+
+typedef CSSM_MODULE_HANDLE CSSM_CL_HANDLE; /* Certificate Library Handle */
+
+typedef CSSM_MODULE_HANDLE CSSM_DL_HANDLE; /* Data Storage Library Handle */
+
+typedef CSSM_MODULE_HANDLE CSSM_DB_HANDLE; /* Data Storage Database Handle */
+
+
+/* invalid or NULL value for any CSSM_HANDLE type */
+enum {
+    CSSM_INVALID_HANDLE =				0
+};
+
+
+/* Data Types for Core Services */
+
+typedef sint32 CSSM_BOOL;
+enum {
+	CSSM_FALSE =						0,
+	CSSM_TRUE =							!CSSM_FALSE
+};
+
+/* The standard declares this as uint32 but we changed it to sint32 to match OSStatus. */
+typedef sint32 CSSM_RETURN;
+enum {
+	CSSM_OK =							0
+};
+
+enum {
+	CSSM_MODULE_STRING_SIZE =			64
+};
+typedef char CSSM_STRING [CSSM_MODULE_STRING_SIZE + 4];
+
+typedef struct cssm_data {
+    uint32 Length; /* in bytes */
+    uint8 *Data;
+} CSSM_DATA, *CSSM_DATA_PTR;
+
+typedef struct cssm_guid {
+    uint32 Data1;
+    uint16 Data2;
+    uint16 Data3;
+    uint8 Data4[8];
+} CSSM_GUID, *CSSM_GUID_PTR;
+
+typedef uint32 CSSM_BITMASK;
+typedef CSSM_BITMASK CSSM_KEY_HIERARCHY;
+enum {
+	CSSM_KEY_HIERARCHY_NONE =			0,
+	CSSM_KEY_HIERARCHY_INTEG =			1,
+	CSSM_KEY_HIERARCHY_EXPORT =			2
+};
+
+typedef CSSM_BITMASK CSSM_PVC_MODE;
+enum {
+	CSSM_PVC_NONE =						0,
+	CSSM_PVC_APP =						1,
+	CSSM_PVC_SP =						2
+};
+
+typedef uint32 CSSM_PRIVILEGE_SCOPE;
+enum {
+	CSSM_PRIVILEGE_SCOPE_NONE =			0,
+	CSSM_PRIVILEGE_SCOPE_PROCESS =		1,
+	CSSM_PRIVILEGE_SCOPE_THREAD =		2
+};
+
+typedef struct cssm_version {
+    uint32 Major;
+    uint32 Minor;
+} CSSM_VERSION, *CSSM_VERSION_PTR;
+
+typedef uint32 CSSM_SERVICE_MASK;
+enum {
+	CSSM_SERVICE_CSSM =				0x1,
+	CSSM_SERVICE_CSP =				0x2,
+	CSSM_SERVICE_DL =				0x4,
+	CSSM_SERVICE_CL =				0x8,
+	CSSM_SERVICE_TP =				0x10,
+	CSSM_SERVICE_AC =				0x20,
+	CSSM_SERVICE_KR =				0x40
+};
+
+typedef CSSM_SERVICE_MASK CSSM_SERVICE_TYPE;
+
+typedef struct cssm_subservice_uid {
+    CSSM_GUID Guid;
+    CSSM_VERSION Version;
+    uint32 SubserviceId;
+    CSSM_SERVICE_TYPE SubserviceType;
+} CSSM_SUBSERVICE_UID, *CSSM_SUBSERVICE_UID_PTR;
+
+typedef uint32 CSSM_MODULE_EVENT, *CSSM_MODULE_EVENT_PTR;
+enum {
+    CSSM_NOTIFY_INSERT =				1,
+    CSSM_NOTIFY_REMOVE =				2,
+    CSSM_NOTIFY_FAULT =					3
+};
+
+typedef CSSM_RETURN (CSSMAPI *CSSM_API_ModuleEventHandler)
+    (const CSSM_GUID *ModuleGuid,
+     void* AppNotifyCallbackCtx,
+     uint32 SubserviceId,
+     CSSM_SERVICE_TYPE ServiceType,
+     CSSM_MODULE_EVENT EventType);
+
+typedef uint32 CSSM_ATTACH_FLAGS;
+enum {
+	CSSM_ATTACH_READ_ONLY =			0x00000001
+};
+
+/* Non-export privilege range: (0x00000000 - 0x7FFFFFFF) */
+/* Vendor specific range: (0x80000000 - 0xFFFFFFFF) */
+typedef uint64 CSSM_PRIVILEGE;
+typedef CSSM_PRIVILEGE CSSM_USEE_TAG;
+enum {
+	CSSM_USEE_LAST =					0xFF,
+	CSSM_USEE_NONE =					0,
+	CSSM_USEE_DOMESTIC =				1,
+	CSSM_USEE_FINANCIAL =				2,
+	CSSM_USEE_KRLE =					3,
+	CSSM_USEE_KRENT =					4,
+	CSSM_USEE_SSL =						5,
+	CSSM_USEE_AUTHENTICATION =			6,
+	CSSM_USEE_KEYEXCH =					7,
+	CSSM_USEE_MEDICAL =					8,
+	CSSM_USEE_INSURANCE =				9,
+	CSSM_USEE_WEAK =					10
+};
+
+typedef uint32 CSSM_NET_ADDRESS_TYPE;
+enum {
+    CSSM_ADDR_NONE =					0,
+    CSSM_ADDR_CUSTOM =					1,
+    CSSM_ADDR_URL =						2, /* char* */
+    CSSM_ADDR_SOCKADDR =				3,
+    CSSM_ADDR_NAME =					4 /* char* - qualified by access method */
+};
+
+typedef struct cssm_net_address {
+    CSSM_NET_ADDRESS_TYPE AddressType;
+    CSSM_DATA Address;
+} CSSM_NET_ADDRESS, *CSSM_NET_ADDRESS_PTR;
+
+typedef uint32 CSSM_NET_PROTOCOL;
+enum {
+	CSSM_NET_PROTO_NONE =				0,	/* local */
+	CSSM_NET_PROTO_CUSTOM =				1,	/* proprietary implementation */
+	CSSM_NET_PROTO_UNSPECIFIED =		2,	/* implementation default */
+	CSSM_NET_PROTO_LDAP =				3,	/* light weight directory access protocol */
+	CSSM_NET_PROTO_LDAPS =				4,	/* ldap/ssl where SSL initiates the connection */
+	CSSM_NET_PROTO_LDAPNS =				5,	/* ldap where ldap negotiates an SSL session */
+	CSSM_NET_PROTO_X500DAP =			6,	/* x.500 Directory access protocol */
+	CSSM_NET_PROTO_FTP =				7,	/* ftp for cert/crl fetch */
+	CSSM_NET_PROTO_FTPS =				8,	/* ftp/ssl/tls where SSL/TLS initiates the connection */
+	CSSM_NET_PROTO_OCSP =				9,	/* online certificate status protocol */
+	CSSM_NET_PROTO_CMP =				10,	/* the cert request protocol in PKIX3 */
+	CSSM_NET_PROTO_CMPS =				11	/* The ssl/tls derivative of CMP */
+};
+
+typedef CSSM_RETURN (CSSMAPI *CSSM_CALLBACK)
+    (CSSM_DATA_PTR OutData, void *CallerCtx);
+
+typedef struct cssm_crypto_data {
+    CSSM_DATA Param;
+    CSSM_CALLBACK Callback;
+    void *CallerCtx;
+} CSSM_CRYPTO_DATA, *CSSM_CRYPTO_DATA_PTR;
+
+typedef sint32 CSSM_WORDID_TYPE;
+enum {
+	CSSM_WORDID__UNK_ =					-1, /* not in dictionary */
+	CSSM_WORDID__NLU_ =					0, /* not yet looked up */
+	CSSM_WORDID__STAR_ =				1,
+	CSSM_WORDID_A =						2,
+	CSSM_WORDID_ACL =					3,
+	CSSM_WORDID_ALPHA =					4,
+	CSSM_WORDID_B =						5,
+	CSSM_WORDID_BER =					6,
+	CSSM_WORDID_BINARY =				7,
+	CSSM_WORDID_BIOMETRIC =				8,
+	CSSM_WORDID_C =						9,
+	CSSM_WORDID_CANCELED =				10,
+	CSSM_WORDID_CERT =					11,
+	CSSM_WORDID_COMMENT =				12,
+	CSSM_WORDID_CRL =					13,
+	CSSM_WORDID_CUSTOM =				14,
+	CSSM_WORDID_D =						15,
+	CSSM_WORDID_DATE =					16,
+	CSSM_WORDID_DB_DELETE =				17,
+	CSSM_WORDID_DB_EXEC_STORED_QUERY =	18,
+	CSSM_WORDID_DB_INSERT =				19,
+	CSSM_WORDID_DB_MODIFY =				20,
+	CSSM_WORDID_DB_READ =				21,
+	CSSM_WORDID_DBS_CREATE =			22,
+	CSSM_WORDID_DBS_DELETE =			23,
+	CSSM_WORDID_DECRYPT =				24,
+	CSSM_WORDID_DELETE =				25,
+	CSSM_WORDID_DELTA_CRL =				26,
+	CSSM_WORDID_DER =					27,
+	CSSM_WORDID_DERIVE =				28,
+	CSSM_WORDID_DISPLAY =				29,
+	CSSM_WORDID_DO =					30,
+	CSSM_WORDID_DSA =					31,
+	CSSM_WORDID_DSA_SHA1 =				32,
+	CSSM_WORDID_E =						33,
+	CSSM_WORDID_ELGAMAL =				34,
+	CSSM_WORDID_ENCRYPT =				35,
+	CSSM_WORDID_ENTRY =					36,
+	CSSM_WORDID_EXPORT_CLEAR =			37,
+	CSSM_WORDID_EXPORT_WRAPPED =		38,
+	CSSM_WORDID_G =						39,
+	CSSM_WORDID_GE =					40,
+	CSSM_WORDID_GENKEY =				41,
+	CSSM_WORDID_HASH =					42,
+	CSSM_WORDID_HASHED_PASSWORD =		43,
+	CSSM_WORDID_HASHED_SUBJECT =		44,
+	CSSM_WORDID_HAVAL =					45,
+	CSSM_WORDID_IBCHASH =				46,
+	CSSM_WORDID_IMPORT_CLEAR =			47,
+	CSSM_WORDID_IMPORT_WRAPPED =		48,
+	CSSM_WORDID_INTEL =					49,
+	CSSM_WORDID_ISSUER =				50,
+	CSSM_WORDID_ISSUER_INFO =			51,
+	CSSM_WORDID_K_OF_N =				52,
+	CSSM_WORDID_KEA =					53,
+	CSSM_WORDID_KEYHOLDER =				54,
+	CSSM_WORDID_L =						55,
+	CSSM_WORDID_LE =					56,
+	CSSM_WORDID_LOGIN =					57,
+	CSSM_WORDID_LOGIN_NAME =			58,
+	CSSM_WORDID_MAC =					59,
+	CSSM_WORDID_MD2 =					60,
+	CSSM_WORDID_MD2WITHRSA =			61,
+	CSSM_WORDID_MD4 =					62,
+	CSSM_WORDID_MD5 =					63,
+	CSSM_WORDID_MD5WITHRSA =			64,
+	CSSM_WORDID_N =						65,
+	CSSM_WORDID_NAME =					66,
+	CSSM_WORDID_NDR =					67,
+	CSSM_WORDID_NHASH =					68,
+	CSSM_WORDID_NOT_AFTER =				69,
+	CSSM_WORDID_NOT_BEFORE =			70,
+	CSSM_WORDID_NULL =					71,
+	CSSM_WORDID_NUMERIC =				72,
+	CSSM_WORDID_OBJECT_HASH =			73,
+	CSSM_WORDID_ONE_TIME =				74,
+	CSSM_WORDID_ONLINE =				75,
+	CSSM_WORDID_OWNER =					76,
+	CSSM_WORDID_P =						77,
+	CSSM_WORDID_PAM_NAME =				78,
+	CSSM_WORDID_PASSWORD =				79,
+	CSSM_WORDID_PGP =					80,
+	CSSM_WORDID_PREFIX =				81,
+	CSSM_WORDID_PRIVATE_KEY =			82,
+	CSSM_WORDID_PROMPTED_BIOMETRIC =	83,
+	CSSM_WORDID_PROMPTED_PASSWORD =		84,
+	CSSM_WORDID_PROPAGATE =				85,
+	CSSM_WORDID_PROTECTED_BIOMETRIC =	86,
+	CSSM_WORDID_PROTECTED_PASSWORD =	87,
+	CSSM_WORDID_PROTECTED_PIN =			88,
+	CSSM_WORDID_PUBLIC_KEY =			89,
+	CSSM_WORDID_PUBLIC_KEY_FROM_CERT =	90,
+	CSSM_WORDID_Q =						91,
+	CSSM_WORDID_RANGE =					92,
+	CSSM_WORDID_REVAL =					93,
+	CSSM_WORDID_RIPEMAC =				94,
+	CSSM_WORDID_RIPEMD =				95,
+	CSSM_WORDID_RIPEMD160 =				96,
+	CSSM_WORDID_RSA =					97,
+	CSSM_WORDID_RSA_ISO9796 =			98,
+	CSSM_WORDID_RSA_PKCS =				99,
+	CSSM_WORDID_RSA_PKCS_MD5 =			100,
+	CSSM_WORDID_RSA_PKCS_SHA1 =			101,
+	CSSM_WORDID_RSA_PKCS1 =				102,
+	CSSM_WORDID_RSA_PKCS1_MD5 =			103,
+	CSSM_WORDID_RSA_PKCS1_SHA1 =		104,
+	CSSM_WORDID_RSA_PKCS1_SIG =			105,
+	CSSM_WORDID_RSA_RAW =				106,
+	CSSM_WORDID_SDSIV1 =				107,
+	CSSM_WORDID_SEQUENCE =				108,
+	CSSM_WORDID_SET =					109,
+	CSSM_WORDID_SEXPR =					110,
+	CSSM_WORDID_SHA1 =					111,
+	CSSM_WORDID_SHA1WITHDSA =			112,
+	CSSM_WORDID_SHA1WITHECDSA =			113,
+	CSSM_WORDID_SHA1WITHRSA =			114,
+	CSSM_WORDID_SIGN =					115,
+	CSSM_WORDID_SIGNATURE =				116,
+	CSSM_WORDID_SIGNED_NONCE =			117,
+	CSSM_WORDID_SIGNED_SECRET =			118,
+	CSSM_WORDID_SPKI =					119,
+	CSSM_WORDID_SUBJECT =				120,
+	CSSM_WORDID_SUBJECT_INFO =			121,
+	CSSM_WORDID_TAG =					122,
+	CSSM_WORDID_THRESHOLD =				123,
+	CSSM_WORDID_TIME =					124,
+	CSSM_WORDID_URI =					125,
+	CSSM_WORDID_VERSION =				126,
+	CSSM_WORDID_X509_ATTRIBUTE =		127,
+	CSSM_WORDID_X509V1 =				128,
+	CSSM_WORDID_X509V2 =				129,
+	CSSM_WORDID_X509V3 =				130,
+	CSSM_WORDID_X9_ATTRIBUTE =			131,
+	CSSM_WORDID_VENDOR_START =			0x00010000,
+	CSSM_WORDID_VENDOR_END =			0x7FFF0000
+};
+
+typedef uint32 CSSM_LIST_ELEMENT_TYPE, *CSSM_LIST_ELEMENT_TYPE_PTR;
+enum {
+	CSSM_LIST_ELEMENT_DATUM =			0x00,
+	CSSM_LIST_ELEMENT_SUBLIST =			0x01,
+	CSSM_LIST_ELEMENT_WORDID =			0x02
+};
+
+typedef uint32 CSSM_LIST_TYPE, *CSSM_LIST_TYPE_PTR;
+enum {
+	CSSM_LIST_TYPE_UNKNOWN =			0,
+	CSSM_LIST_TYPE_CUSTOM =				1,
+	CSSM_LIST_TYPE_SEXPR =				2
+};
+
+typedef struct cssm_list_element *CSSM_LIST_ELEMENT_PTR;
+
+typedef struct cssm_list {
+    CSSM_LIST_TYPE ListType;	/* type of this list */
+    CSSM_LIST_ELEMENT_PTR Head;	/* head of the list */
+    CSSM_LIST_ELEMENT_PTR Tail;	/* tail of the list */
+} CSSM_LIST, *CSSM_LIST_PTR;
+
+typedef struct cssm_list_element {
+    struct cssm_list_element *NextElement;	/* next list element */
+	CSSM_WORDID_TYPE WordID;	/* integer identifier associated */
+								/* with a Word value */
+    CSSM_LIST_ELEMENT_TYPE ElementType;
+    union {
+        CSSM_LIST Sublist;		/* sublist */
+        CSSM_DATA Word;		/* a byte-string */
+    } Element;
+} CSSM_LIST_ELEMENT;
+
+typedef struct {				/* 5-tuple definition */
+	CSSM_LIST Issuer;			/* issuer, or empty if ACL */
+	CSSM_LIST Subject;			/* subject */
+	CSSM_BOOL Delegate;			/* permission to delegate */
+	CSSM_LIST AuthorizationTag;	/* authorization field */
+	CSSM_LIST ValidityPeriod;	/* validity information (dates) */
+} CSSM_TUPLE, *CSSM_TUPLE_PTR;
+
+typedef struct cssm_tuplegroup {
+    uint32 NumberOfTuples;
+    CSSM_TUPLE_PTR Tuples;
+} CSSM_TUPLEGROUP, *CSSM_TUPLEGROUP_PTR;
+
+typedef CSSM_WORDID_TYPE CSSM_SAMPLE_TYPE;
+enum {
+	CSSM_SAMPLE_TYPE_PASSWORD =				CSSM_WORDID_PASSWORD,
+	CSSM_SAMPLE_TYPE_HASHED_PASSWORD =		CSSM_WORDID_HASHED_PASSWORD,
+	CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD =	CSSM_WORDID_PROTECTED_PASSWORD,
+	CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD =	CSSM_WORDID_PROMPTED_PASSWORD,
+	CSSM_SAMPLE_TYPE_SIGNED_NONCE =			CSSM_WORDID_SIGNED_NONCE,
+	CSSM_SAMPLE_TYPE_SIGNED_SECRET =		CSSM_WORDID_SIGNED_SECRET,
+	CSSM_SAMPLE_TYPE_BIOMETRIC =			CSSM_WORDID_BIOMETRIC,
+	CSSM_SAMPLE_TYPE_PROTECTED_BIOMETRIC =	CSSM_WORDID_PROTECTED_BIOMETRIC,
+	CSSM_SAMPLE_TYPE_PROMPTED_BIOMETRIC =	CSSM_WORDID_PROMPTED_BIOMETRIC,
+	CSSM_SAMPLE_TYPE_THRESHOLD =			CSSM_WORDID_THRESHOLD
+};
+
+typedef struct cssm_sample {
+    CSSM_LIST TypedSample;
+    const CSSM_SUBSERVICE_UID *Verifier;
+} CSSM_SAMPLE, *CSSM_SAMPLE_PTR;
+
+typedef struct cssm_samplegroup {
+    uint32 NumberOfSamples;
+    const CSSM_SAMPLE *Samples;
+} CSSM_SAMPLEGROUP, *CSSM_SAMPLEGROUP_PTR;
+
+typedef void *(CSSMAPI *CSSM_MALLOC)
+    (uint32 size,
+     void *allocref);
+
+typedef void (CSSMAPI *CSSM_FREE)
+    (void *memblock,
+     void *allocref);
+
+typedef void *(CSSMAPI *CSSM_REALLOC)
+    (void *memblock,
+     uint32 size,
+     void *allocref);
+
+typedef void *(CSSMAPI *CSSM_CALLOC)
+    (uint32 num,
+     uint32 size,
+     void *allocref);
+
+typedef struct cssm_memory_funcs {
+    CSSM_MALLOC malloc_func;
+    CSSM_FREE free_func;
+    CSSM_REALLOC realloc_func;
+    CSSM_CALLOC calloc_func;
+    void *AllocRef;
+} CSSM_MEMORY_FUNCS, *CSSM_MEMORY_FUNCS_PTR;
+
+typedef CSSM_MEMORY_FUNCS CSSM_API_MEMORY_FUNCS;
+typedef CSSM_API_MEMORY_FUNCS *CSSM_API_MEMORY_FUNCS_PTR;
+
+typedef CSSM_RETURN (CSSMAPI * CSSM_CHALLENGE_CALLBACK)
+    (const CSSM_LIST *Challenge,
+     CSSM_SAMPLEGROUP_PTR Response,
+     void *CallerCtx,
+     const CSSM_MEMORY_FUNCS *MemFuncs);
+
+typedef uint32 CSSM_CERT_TYPE, *CSSM_CERT_TYPE_PTR;
+enum {
+    CSSM_CERT_UNKNOWN =					0x00,
+    CSSM_CERT_X_509v1 =					0x01,
+    CSSM_CERT_X_509v2 =					0x02,
+    CSSM_CERT_X_509v3 =					0x03,
+    CSSM_CERT_PGP =						0x04,
+    CSSM_CERT_SPKI =					0x05,
+    CSSM_CERT_SDSIv1 =					0x06,
+    CSSM_CERT_Intel =					0x08,
+    CSSM_CERT_X_509_ATTRIBUTE =			0x09, /* X.509 attribute cert */
+    CSSM_CERT_X9_ATTRIBUTE =			0x0A, /* X9 attribute cert */
+    CSSM_CERT_TUPLE =					0x0B,
+    CSSM_CERT_ACL_ENTRY =				0x0C,
+    CSSM_CERT_MULTIPLE =				0x7FFE,
+    CSSM_CERT_LAST =					0x7FFF,
+	/* Applications wishing to define their own custom certificate
+	   type should define and publicly document a uint32 value greater
+	   than the CSSM_CL_CUSTOM_CERT_TYPE */
+	CSSM_CL_CUSTOM_CERT_TYPE =			0x08000
+};
+
+typedef uint32 CSSM_CERT_ENCODING, *CSSM_CERT_ENCODING_PTR;
+enum {
+    CSSM_CERT_ENCODING_UNKNOWN =		0x00,
+    CSSM_CERT_ENCODING_CUSTOM =			0x01,
+    CSSM_CERT_ENCODING_BER =			0x02,
+    CSSM_CERT_ENCODING_DER =			0x03,
+    CSSM_CERT_ENCODING_NDR =			0x04,
+    CSSM_CERT_ENCODING_SEXPR =			0x05,
+    CSSM_CERT_ENCODING_PGP =			0x06,
+    CSSM_CERT_ENCODING_MULTIPLE =		0x7FFE,
+    CSSM_CERT_ENCODING_LAST =			0x7FFF,
+	/* Applications wishing to define their own custom certificate
+	   encoding should create a uint32 value greater than the
+	   CSSM_CL_CUSTOM_CERT_ENCODING */
+	CSSM_CL_CUSTOM_CERT_ENCODING =		0x8000
+};
+
+typedef struct cssm_encoded_cert {
+    CSSM_CERT_TYPE CertType;			/* type of certificate */
+    CSSM_CERT_ENCODING CertEncoding;	/* encoding for this packed cert */
+    CSSM_DATA CertBlob;					/* packed cert */
+} CSSM_ENCODED_CERT, *CSSM_ENCODED_CERT_PTR;
+
+typedef uint32 CSSM_CERT_PARSE_FORMAT, *CSSM_CERT_PARSE_FORMAT_PTR;
+enum {
+	CSSM_CERT_PARSE_FORMAT_NONE =			0x00,
+	CSSM_CERT_PARSE_FORMAT_CUSTOM =			0x01, /* void* */
+	CSSM_CERT_PARSE_FORMAT_SEXPR =			0x02, /* CSSM_LIST */
+	CSSM_CERT_PARSE_FORMAT_COMPLEX =		0x03, /* void* */
+	CSSM_CERT_PARSE_FORMAT_OID_NAMED =		0x04, /* CSSM_FIELDGROUP */
+	CSSM_CERT_PARSE_FORMAT_TUPLE =			0x05, /* CSSM_TUPLE */
+	CSSM_CERT_PARSE_FORMAT_MULTIPLE =		0x7FFE,
+/* multiple forms, each cert carries a
+   parse format indicator */
+	CSSM_CERT_PARSE_FORMAT_LAST =			0x7FFF,
+/* Applications wishing to define their
+   own custom parse format should create
+   a * uint32 value greater than the
+   CSSM_CL_CUSTOM_CERT_PARSE_FORMAT */
+	CSSM_CL_CUSTOM_CERT_PARSE_FORMAT =		0x8000
+};
+
+typedef struct cssm_parsed_cert {
+    CSSM_CERT_TYPE CertType; /* certificate type */
+    CSSM_CERT_PARSE_FORMAT ParsedCertFormat;
+    /* struct of ParsedCert */
+    void *ParsedCert; /* parsed cert (to be typecast) */
+} CSSM_PARSED_CERT, *CSSM_PARSED_CERT_PTR;
+
+typedef struct cssm_cert_pair {
+    CSSM_ENCODED_CERT EncodedCert; /* an encoded certificate blob */
+    CSSM_PARSED_CERT ParsedCert; /* equivalent parsed certificate */
+} CSSM_CERT_PAIR, *CSSM_CERT_PAIR_PTR;
+
+typedef uint32 CSSM_CERTGROUP_TYPE, *CSSM_CERTGROUP_TYPE_PTR;
+enum {
+	CSSM_CERTGROUP_DATA =				0x00,
+	CSSM_CERTGROUP_ENCODED_CERT =		0x01,
+	CSSM_CERTGROUP_PARSED_CERT =		0x02,
+	CSSM_CERTGROUP_CERT_PAIR =			0x03
+};
+
+typedef struct cssm_certgroup {
+    CSSM_CERT_TYPE CertType;
+    CSSM_CERT_ENCODING CertEncoding;
+    uint32 NumCerts; /* # of certificates in this list */
+    union {
+        CSSM_DATA_PTR CertList; /* legacy list of single type certificate blobs */
+        CSSM_ENCODED_CERT_PTR EncodedCertList;
+        /* list of multi-type certificate blobs */
+        CSSM_PARSED_CERT_PTR ParsedCertList;
+        /* list of multi-type parsed certs */
+        CSSM_CERT_PAIR_PTR PairCertList;
+        /*list of single or multi-type certs with two representations: blob and parsed */
+    } GroupList;
+    CSSM_CERTGROUP_TYPE CertGroupType;
+    /* type of structure in the GroupList */
+    void *Reserved; /* reserved for implementation dependent use */
+} CSSM_CERTGROUP, *CSSM_CERTGROUP_PTR;
+
+typedef struct cssm_base_certs {
+    CSSM_TP_HANDLE TPHandle;
+    CSSM_CL_HANDLE CLHandle;
+    CSSM_CERTGROUP Certs;
+} CSSM_BASE_CERTS, *CSSM_BASE_CERTS_PTR;
+
+typedef struct cssm_access_credentials {
+    CSSM_STRING EntryTag;
+    CSSM_BASE_CERTS BaseCerts;
+    CSSM_SAMPLEGROUP Samples;
+    CSSM_CHALLENGE_CALLBACK Callback;
+    void *CallerCtx;
+} CSSM_ACCESS_CREDENTIALS, *CSSM_ACCESS_CREDENTIALS_PTR;
+
+typedef sint32 CSSM_ACL_SUBJECT_TYPE;
+enum {
+	CSSM_ACL_SUBJECT_TYPE_ANY =					CSSM_WORDID__STAR_,
+	CSSM_ACL_SUBJECT_TYPE_THRESHOLD =			CSSM_WORDID_THRESHOLD,
+	CSSM_ACL_SUBJECT_TYPE_PASSWORD =			CSSM_WORDID_PASSWORD,
+	CSSM_ACL_SUBJECT_TYPE_PROTECTED_PASSWORD =	CSSM_WORDID_PROTECTED_PASSWORD,
+	CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD =	CSSM_WORDID_PROMPTED_PASSWORD,
+	CSSM_ACL_SUBJECT_TYPE_PUBLIC_KEY =			CSSM_WORDID_PUBLIC_KEY,
+	CSSM_ACL_SUBJECT_TYPE_HASHED_SUBJECT =		CSSM_WORDID_HASHED_SUBJECT,
+	CSSM_ACL_SUBJECT_TYPE_BIOMETRIC =			CSSM_WORDID_BIOMETRIC,
+	CSSM_ACL_SUBJECT_TYPE_PROTECTED_BIOMETRIC =	CSSM_WORDID_PROTECTED_BIOMETRIC,
+	CSSM_ACL_SUBJECT_TYPE_PROMPTED_BIOMETRIC =	CSSM_WORDID_PROMPTED_BIOMETRIC,
+	CSSM_ACL_SUBJECT_TYPE_LOGIN_NAME =			CSSM_WORDID_LOGIN_NAME,
+	CSSM_ACL_SUBJECT_TYPE_EXT_PAM_NAME =		CSSM_WORDID_PAM_NAME
+};
+
+/* Authorization tag type */
+typedef sint32 CSSM_ACL_AUTHORIZATION_TAG;
+enum {
+	/* All vendor specific constants must be in the number range
+	   starting at CSSM_ACL_AUTHORIZATION_TAG_VENDOR_DEFINED_START */
+	CSSM_ACL_AUTHORIZATION_TAG_VENDOR_DEFINED_START =	0x00010000,
+	/* No restrictions. Permission to perform all operations on
+	   the resource or available to an ACL owner.  */
+	CSSM_ACL_AUTHORIZATION_ANY =						CSSM_WORDID__STAR_,
+	/* Defined authorization tag values for CSPs */
+	CSSM_ACL_AUTHORIZATION_LOGIN =						CSSM_WORDID_LOGIN,
+	CSSM_ACL_AUTHORIZATION_GENKEY =						CSSM_WORDID_GENKEY,
+	CSSM_ACL_AUTHORIZATION_DELETE =						CSSM_WORDID_DELETE,
+	CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED =				CSSM_WORDID_EXPORT_WRAPPED,
+	CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR =				CSSM_WORDID_EXPORT_CLEAR,
+	CSSM_ACL_AUTHORIZATION_IMPORT_WRAPPED =				CSSM_WORDID_IMPORT_WRAPPED,
+	CSSM_ACL_AUTHORIZATION_IMPORT_CLEAR =				CSSM_WORDID_IMPORT_CLEAR,
+	CSSM_ACL_AUTHORIZATION_SIGN =						CSSM_WORDID_SIGN,
+	CSSM_ACL_AUTHORIZATION_ENCRYPT =					CSSM_WORDID_ENCRYPT,
+	CSSM_ACL_AUTHORIZATION_DECRYPT =					CSSM_WORDID_DECRYPT,
+	CSSM_ACL_AUTHORIZATION_MAC =						CSSM_WORDID_MAC,
+	CSSM_ACL_AUTHORIZATION_DERIVE =						CSSM_WORDID_DERIVE,
+	/* Defined authorization tag values for DLs */
+	CSSM_ACL_AUTHORIZATION_DBS_CREATE =					CSSM_WORDID_DBS_CREATE,
+	CSSM_ACL_AUTHORIZATION_DBS_DELETE =					CSSM_WORDID_DBS_DELETE,
+	CSSM_ACL_AUTHORIZATION_DB_READ =					CSSM_WORDID_DB_READ,
+	CSSM_ACL_AUTHORIZATION_DB_INSERT =					CSSM_WORDID_DB_INSERT,
+	CSSM_ACL_AUTHORIZATION_DB_MODIFY =					CSSM_WORDID_DB_MODIFY,
+	CSSM_ACL_AUTHORIZATION_DB_DELETE =					CSSM_WORDID_DB_DELETE
+};
+
+typedef struct cssm_authorizationgroup {
+    uint32 NumberOfAuthTags;
+    CSSM_ACL_AUTHORIZATION_TAG *AuthTags;
+} CSSM_AUTHORIZATIONGROUP, *CSSM_AUTHORIZATIONGROUP_PTR;
+
+typedef struct cssm_acl_validity_period {
+    CSSM_DATA StartDate;
+    CSSM_DATA EndDate;
+} CSSM_ACL_VALIDITY_PERIOD, *CSSM_ACL_VALIDITY_PERIOD_PTR;
+
+typedef struct cssm_acl_entry_prototype {
+    CSSM_LIST TypedSubject;
+    CSSM_BOOL Delegate;
+    CSSM_AUTHORIZATIONGROUP Authorization;
+    CSSM_ACL_VALIDITY_PERIOD TimeRange;
+    CSSM_STRING EntryTag;
+} CSSM_ACL_ENTRY_PROTOTYPE, *CSSM_ACL_ENTRY_PROTOTYPE_PTR;
+
+typedef struct cssm_acl_owner_prototype {
+    CSSM_LIST TypedSubject;
+    CSSM_BOOL Delegate;
+} CSSM_ACL_OWNER_PROTOTYPE, *CSSM_ACL_OWNER_PROTOTYPE_PTR;
+
+typedef CSSM_RETURN (CSSMAPI * CSSM_ACL_SUBJECT_CALLBACK)
+    (const CSSM_LIST *SubjectRequest,
+     CSSM_LIST_PTR SubjectResponse,
+     void *CallerContext,
+     const CSSM_MEMORY_FUNCS *MemFuncs);
+
+typedef struct cssm_acl_entry_input {
+    CSSM_ACL_ENTRY_PROTOTYPE Prototype;
+    CSSM_ACL_SUBJECT_CALLBACK Callback;
+    void *CallerContext;
+} CSSM_ACL_ENTRY_INPUT, *CSSM_ACL_ENTRY_INPUT_PTR;
+
+typedef struct cssm_resource_control_context {
+    CSSM_ACCESS_CREDENTIALS_PTR AccessCred;
+    CSSM_ACL_ENTRY_INPUT InitialAclEntry;
+} CSSM_RESOURCE_CONTROL_CONTEXT, *CSSM_RESOURCE_CONTROL_CONTEXT_PTR;
+
+typedef CSSM_HANDLE CSSM_ACL_HANDLE;
+
+typedef struct cssm_acl_entry_info {
+    CSSM_ACL_ENTRY_PROTOTYPE EntryPublicInfo;
+    CSSM_ACL_HANDLE EntryHandle;
+} CSSM_ACL_ENTRY_INFO, *CSSM_ACL_ENTRY_INFO_PTR;
+
+typedef uint32 CSSM_ACL_EDIT_MODE;
+enum {
+	CSSM_ACL_EDIT_MODE_ADD =			1,
+	CSSM_ACL_EDIT_MODE_DELETE =			2,
+	CSSM_ACL_EDIT_MODE_REPLACE =		3
+};
+
+typedef struct cssm_acl_edit {
+    CSSM_ACL_EDIT_MODE EditMode;
+    CSSM_ACL_HANDLE OldEntryHandle;
+    const CSSM_ACL_ENTRY_INPUT *NewEntry;
+} CSSM_ACL_EDIT, *CSSM_ACL_EDIT_PTR;
+
+#if defined(WIN32)
+typedef FARPROC CSSM_PROC_ADDR;
+#else
+typedef void (CSSMAPI *CSSM_PROC_ADDR) ();
+#endif
+typedef CSSM_PROC_ADDR *CSSM_PROC_ADDR_PTR;
+
+typedef struct cssm_func_name_addr {
+    CSSM_STRING Name;
+    CSSM_PROC_ADDR Address;
+} CSSM_FUNC_NAME_ADDR, *CSSM_FUNC_NAME_ADDR_PTR;
+
+
+/* Data Types for Cryptographic Services  */
+
+typedef struct cssm_date {
+    uint8 Year[4];
+    uint8 Month[2];
+    uint8 Day[2];
+} CSSM_DATE, *CSSM_DATE_PTR;
+
+typedef struct cssm_range {
+    uint32 Min; /* inclusive minimum value */
+    uint32 Max; /* inclusive maximum value */
+} CSSM_RANGE, *CSSM_RANGE_PTR;
+
+typedef struct cssm_query_size_data {
+    uint32 SizeInputBlock; /* size of input data block */
+    uint32 SizeOutputBlock; /* size of resulting output data block */
+} CSSM_QUERY_SIZE_DATA, *CSSM_QUERY_SIZE_DATA_PTR;
+
+typedef uint32 CSSM_HEADERVERSION;
+enum {
+	CSSM_KEYHEADER_VERSION =		2
+};
+
+typedef struct cssm_key_size {
+    uint32 LogicalKeySizeInBits; /* Logical key size in bits */
+    uint32 EffectiveKeySizeInBits; /* Effective key size in bits */
+} CSSM_KEY_SIZE, *CSSM_KEY_SIZE_PTR;
+
+typedef uint32 CSSM_KEYBLOB_TYPE;
+enum {
+	CSSM_KEYBLOB_RAW =				0, /* The blob is a clear, raw key */
+	CSSM_KEYBLOB_REFERENCE =		2, /* The blob is a reference to a key */
+	CSSM_KEYBLOB_WRAPPED =			3, /* The blob is a wrapped RAW key */
+	CSSM_KEYBLOB_OTHER =			0xFFFFFFFF
+};
+
+typedef uint32 CSSM_KEYBLOB_FORMAT;
+enum {
+	/* Raw Format */
+	CSSM_KEYBLOB_RAW_FORMAT_NONE =			0,
+	/* No further conversion need to be done */
+	CSSM_KEYBLOB_RAW_FORMAT_PKCS1 =			1, /* RSA PKCS1 V1.5 */
+	CSSM_KEYBLOB_RAW_FORMAT_PKCS3 =			2, /* RSA PKCS3 V1.5 */
+	CSSM_KEYBLOB_RAW_FORMAT_MSCAPI =		3, /* Microsoft CAPI V2.0 */
+	CSSM_KEYBLOB_RAW_FORMAT_PGP =			4, /* PGP V */
+	CSSM_KEYBLOB_RAW_FORMAT_FIPS186 =		5, /* US Gov. FIPS 186 - DSS V */
+	CSSM_KEYBLOB_RAW_FORMAT_BSAFE =			6, /* RSA Bsafe V3.0 */
+	CSSM_KEYBLOB_RAW_FORMAT_CCA =			9, /* CCA clear public key blob */
+	CSSM_KEYBLOB_RAW_FORMAT_PKCS8 =			10, /* RSA PKCS8 V1.2 */
+	CSSM_KEYBLOB_RAW_FORMAT_SPKI =			11, /* SPKI Specification */
+	CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING =	12,
+	CSSM_KEYBLOB_RAW_FORMAT_OTHER =			0xFFFFFFFF /* Other, CSP defined */
+};
+enum {
+	/* Wrapped Format */
+	CSSM_KEYBLOB_WRAPPED_FORMAT_NONE =		0,
+	/* No further conversion need to be done */
+	CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8 =		1, /* RSA PKCS8 V1.2 */
+	CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7 =		2,
+	CSSM_KEYBLOB_WRAPPED_FORMAT_MSCAPI =	3,
+	CSSM_KEYBLOB_WRAPPED_FORMAT_OTHER =		0xFFFFFFFF /* Other, CSP defined */
+};
+enum {
+	/* Reference Format */
+	CSSM_KEYBLOB_REF_FORMAT_INTEGER =		0,	/* Reference is a number or handle */
+	CSSM_KEYBLOB_REF_FORMAT_STRING =		1,	/* Reference is a string or label */
+	CSSM_KEYBLOB_REF_FORMAT_SPKI =			2,	/* Reference is an SPKI S-expression */
+												/* to be evaluated to locate the key */
+	CSSM_KEYBLOB_REF_FORMAT_OTHER =			0xFFFFFFFF	/* Other, CSP defined */
+};
+
+typedef uint32 CSSM_KEYCLASS;
+enum {
+	CSSM_KEYCLASS_PUBLIC_KEY =		0, /* Key is public key */
+	CSSM_KEYCLASS_PRIVATE_KEY =		1, /* Key is private key */
+	CSSM_KEYCLASS_SESSION_KEY =		2, /* Key is session or symmetric key */
+	CSSM_KEYCLASS_SECRET_PART =		3, /* Key is part of secret key */
+	CSSM_KEYCLASS_OTHER =			0xFFFFFFFF /* Other */
+};
+
+typedef uint32 CSSM_KEYATTR_FLAGS;
+enum {
+	/* Valid only during call to an API. Will never be valid when set in a key header */
+	CSSM_KEYATTR_RETURN_DEFAULT =		0x00000000,
+	CSSM_KEYATTR_RETURN_DATA =			0x10000000,
+	CSSM_KEYATTR_RETURN_REF =			0x20000000,
+	CSSM_KEYATTR_RETURN_NONE =			0x40000000,
+	/* Valid during an API call and in a key header */
+	CSSM_KEYATTR_PERMANENT =			0x00000001,
+	CSSM_KEYATTR_PRIVATE =				0x00000002,
+	CSSM_KEYATTR_MODIFIABLE =			0x00000004,
+	CSSM_KEYATTR_SENSITIVE =			0x00000008,
+	CSSM_KEYATTR_EXTRACTABLE =			0x00000020,
+	/* Valid only in a key header generated by a CSP, not valid during an API call */
+	CSSM_KEYATTR_ALWAYS_SENSITIVE =		0x00000010,
+	CSSM_KEYATTR_NEVER_EXTRACTABLE =	0x00000040
+};
+
+typedef uint32 CSSM_KEYUSE;
+enum {
+	CSSM_KEYUSE_ANY =					0x80000000,
+	CSSM_KEYUSE_ENCRYPT =				0x00000001,
+	CSSM_KEYUSE_DECRYPT =				0x00000002,
+	CSSM_KEYUSE_SIGN =					0x00000004,
+	CSSM_KEYUSE_VERIFY =				0x00000008,
+	CSSM_KEYUSE_SIGN_RECOVER =			0x00000010,
+	CSSM_KEYUSE_VERIFY_RECOVER =		0x00000020,
+	CSSM_KEYUSE_WRAP =					0x00000040,
+	CSSM_KEYUSE_UNWRAP =				0x00000080,
+	CSSM_KEYUSE_DERIVE =				0x00000100
+};
+
+typedef uint32 CSSM_ALGORITHMS;
+enum {
+	CSSM_ALGID_NONE =					0,
+	CSSM_ALGID_CUSTOM =					CSSM_ALGID_NONE + 1,
+	CSSM_ALGID_DH =						CSSM_ALGID_NONE + 2,
+	CSSM_ALGID_PH =						CSSM_ALGID_NONE + 3,
+	CSSM_ALGID_KEA =					CSSM_ALGID_NONE + 4,
+	CSSM_ALGID_MD2 =					CSSM_ALGID_NONE + 5,
+	CSSM_ALGID_MD4 =					CSSM_ALGID_NONE + 6,
+	CSSM_ALGID_MD5 =					CSSM_ALGID_NONE + 7,
+	CSSM_ALGID_SHA1 =					CSSM_ALGID_NONE + 8,
+	CSSM_ALGID_NHASH =					CSSM_ALGID_NONE + 9,
+	CSSM_ALGID_HAVAL =					CSSM_ALGID_NONE + 10,
+	CSSM_ALGID_RIPEMD =					CSSM_ALGID_NONE + 11,
+	CSSM_ALGID_IBCHASH =				CSSM_ALGID_NONE + 12,
+	CSSM_ALGID_RIPEMAC =				CSSM_ALGID_NONE + 13,
+	CSSM_ALGID_DES =					CSSM_ALGID_NONE + 14,
+	CSSM_ALGID_DESX =					CSSM_ALGID_NONE + 15,
+	CSSM_ALGID_RDES =					CSSM_ALGID_NONE + 16,
+	CSSM_ALGID_3DES_3KEY_EDE =			CSSM_ALGID_NONE + 17,
+	CSSM_ALGID_3DES_2KEY_EDE =			CSSM_ALGID_NONE + 18,
+	CSSM_ALGID_3DES_1KEY_EEE =			CSSM_ALGID_NONE + 19,
+	CSSM_ALGID_3DES_3KEY =           	CSSM_ALGID_3DES_3KEY_EDE,
+	CSSM_ALGID_3DES_3KEY_EEE =       	CSSM_ALGID_NONE + 20,
+	CSSM_ALGID_3DES_2KEY =           	CSSM_ALGID_3DES_2KEY_EDE,
+	CSSM_ALGID_3DES_2KEY_EEE =       	CSSM_ALGID_NONE + 21,
+	CSSM_ALGID_3DES_1KEY =				CSSM_ALGID_3DES_3KEY_EEE,
+	CSSM_ALGID_IDEA =					CSSM_ALGID_NONE + 22,
+	CSSM_ALGID_RC2 =					CSSM_ALGID_NONE + 23,
+	CSSM_ALGID_RC5 =					CSSM_ALGID_NONE + 24,
+	CSSM_ALGID_RC4 =					CSSM_ALGID_NONE + 25,
+	CSSM_ALGID_SEAL =					CSSM_ALGID_NONE + 26,
+	CSSM_ALGID_CAST =					CSSM_ALGID_NONE + 27,
+	CSSM_ALGID_BLOWFISH =				CSSM_ALGID_NONE + 28,
+	CSSM_ALGID_SKIPJACK =				CSSM_ALGID_NONE + 29,
+	CSSM_ALGID_LUCIFER =				CSSM_ALGID_NONE + 30,
+	CSSM_ALGID_MADRYGA =				CSSM_ALGID_NONE + 31,
+	CSSM_ALGID_FEAL =					CSSM_ALGID_NONE + 32,
+	CSSM_ALGID_REDOC =					CSSM_ALGID_NONE + 33,
+	CSSM_ALGID_REDOC3 =					CSSM_ALGID_NONE + 34,
+	CSSM_ALGID_LOKI =					CSSM_ALGID_NONE + 35,
+	CSSM_ALGID_KHUFU =					CSSM_ALGID_NONE + 36,
+	CSSM_ALGID_KHAFRE =					CSSM_ALGID_NONE + 37,
+	CSSM_ALGID_MMB =					CSSM_ALGID_NONE + 38,
+	CSSM_ALGID_GOST =					CSSM_ALGID_NONE + 39,
+	CSSM_ALGID_SAFER =					CSSM_ALGID_NONE + 40,
+	CSSM_ALGID_CRAB =					CSSM_ALGID_NONE + 41,
+	CSSM_ALGID_RSA =					CSSM_ALGID_NONE + 42,
+	CSSM_ALGID_DSA =					CSSM_ALGID_NONE + 43,
+	CSSM_ALGID_MD5WithRSA =				CSSM_ALGID_NONE + 44,
+	CSSM_ALGID_MD2WithRSA =				CSSM_ALGID_NONE + 45,
+	CSSM_ALGID_ElGamal =				CSSM_ALGID_NONE + 46,
+	CSSM_ALGID_MD2Random =				CSSM_ALGID_NONE + 47,
+	CSSM_ALGID_MD5Random =				CSSM_ALGID_NONE + 48,
+	CSSM_ALGID_SHARandom =				CSSM_ALGID_NONE + 49,
+	CSSM_ALGID_DESRandom =				CSSM_ALGID_NONE + 50,
+	CSSM_ALGID_SHA1WithRSA =			CSSM_ALGID_NONE + 51,
+	CSSM_ALGID_CDMF =					CSSM_ALGID_NONE + 52,
+	CSSM_ALGID_CAST3 =					CSSM_ALGID_NONE + 53,
+	CSSM_ALGID_CAST5 =					CSSM_ALGID_NONE + 54,
+	CSSM_ALGID_GenericSecret =			CSSM_ALGID_NONE + 55,
+	CSSM_ALGID_ConcatBaseAndKey =		CSSM_ALGID_NONE + 56,
+	CSSM_ALGID_ConcatKeyAndBase =		CSSM_ALGID_NONE + 57,
+	CSSM_ALGID_ConcatBaseAndData =		CSSM_ALGID_NONE + 58,
+	CSSM_ALGID_ConcatDataAndBase =		CSSM_ALGID_NONE + 59,
+	CSSM_ALGID_XORBaseAndData =			CSSM_ALGID_NONE + 60,
+	CSSM_ALGID_ExtractFromKey =			CSSM_ALGID_NONE + 61,
+	CSSM_ALGID_SSL3PreMasterGen =		CSSM_ALGID_NONE + 62,
+	CSSM_ALGID_SSL3MasterDerive =		CSSM_ALGID_NONE + 63,
+	CSSM_ALGID_SSL3KeyAndMacDerive =	CSSM_ALGID_NONE + 64,
+	CSSM_ALGID_SSL3MD5_MAC =			CSSM_ALGID_NONE + 65,
+	CSSM_ALGID_SSL3SHA1_MAC =			CSSM_ALGID_NONE + 66,
+	CSSM_ALGID_PKCS5_PBKDF1_MD5 =		CSSM_ALGID_NONE + 67,
+	CSSM_ALGID_PKCS5_PBKDF1_MD2 =		CSSM_ALGID_NONE + 68,
+	CSSM_ALGID_PKCS5_PBKDF1_SHA1 =		CSSM_ALGID_NONE + 69,
+	CSSM_ALGID_WrapLynks =				CSSM_ALGID_NONE + 70,
+	CSSM_ALGID_WrapSET_OAEP =			CSSM_ALGID_NONE + 71,
+	CSSM_ALGID_BATON =					CSSM_ALGID_NONE + 72,
+	CSSM_ALGID_ECDSA =					CSSM_ALGID_NONE + 73,
+	CSSM_ALGID_MAYFLY =					CSSM_ALGID_NONE + 74,
+	CSSM_ALGID_JUNIPER =				CSSM_ALGID_NONE + 75,
+	CSSM_ALGID_FASTHASH =				CSSM_ALGID_NONE + 76,
+	CSSM_ALGID_3DES =					CSSM_ALGID_NONE + 77,
+	CSSM_ALGID_SSL3MD5 =				CSSM_ALGID_NONE + 78,
+	CSSM_ALGID_SSL3SHA1 =				CSSM_ALGID_NONE + 79,
+	CSSM_ALGID_FortezzaTimestamp =		CSSM_ALGID_NONE + 80,
+	CSSM_ALGID_SHA1WithDSA =			CSSM_ALGID_NONE + 81,
+	CSSM_ALGID_SHA1WithECDSA =			CSSM_ALGID_NONE + 82,
+	CSSM_ALGID_DSA_BSAFE =				CSSM_ALGID_NONE + 83,
+	CSSM_ALGID_ECDH =					CSSM_ALGID_NONE + 84,
+	CSSM_ALGID_ECMQV =					CSSM_ALGID_NONE + 85,
+	CSSM_ALGID_PKCS12_SHA1_PBE =		CSSM_ALGID_NONE + 86,
+	CSSM_ALGID_ECNRA =					CSSM_ALGID_NONE + 87,
+	CSSM_ALGID_SHA1WithECNRA =			CSSM_ALGID_NONE + 88,
+	CSSM_ALGID_ECES =					CSSM_ALGID_NONE + 89,
+	CSSM_ALGID_ECAES =					CSSM_ALGID_NONE + 90,
+	CSSM_ALGID_SHA1HMAC =				CSSM_ALGID_NONE + 91,
+	CSSM_ALGID_FIPS186Random =			CSSM_ALGID_NONE + 92,
+	CSSM_ALGID_ECC =					CSSM_ALGID_NONE + 93,
+	CSSM_ALGID_MQV =					CSSM_ALGID_NONE + 94,
+	CSSM_ALGID_NRA =					CSSM_ALGID_NONE + 95,
+	CSSM_ALGID_IntelPlatformRandom =	CSSM_ALGID_NONE + 96,
+	CSSM_ALGID_UTC =					CSSM_ALGID_NONE + 97,
+	CSSM_ALGID_HAVAL3 =					CSSM_ALGID_NONE + 98,
+	CSSM_ALGID_HAVAL4 =					CSSM_ALGID_NONE + 99,
+	CSSM_ALGID_HAVAL5 =					CSSM_ALGID_NONE + 100,
+	CSSM_ALGID_TIGER =					CSSM_ALGID_NONE + 101,
+	CSSM_ALGID_MD5HMAC =				CSSM_ALGID_NONE + 102,
+	CSSM_ALGID_PKCS5_PBKDF2 = 			CSSM_ALGID_NONE + 103,
+	CSSM_ALGID_RUNNING_COUNTER =		CSSM_ALGID_NONE + 104,
+	CSSM_ALGID_LAST =					CSSM_ALGID_NONE + 0x7FFFFFFF,
+/* All algorithms IDs that are vendor specific, and not
+   part of the CSSM specification should be defined relative
+   to CSSM_ALGID_VENDOR_DEFINED. */
+	CSSM_ALGID_VENDOR_DEFINED =			CSSM_ALGID_NONE + 0x80000000
+};
+
+typedef uint32 CSSM_ENCRYPT_MODE;
+enum {
+	CSSM_ALGMODE_NONE =					0,
+	CSSM_ALGMODE_CUSTOM =				CSSM_ALGMODE_NONE + 1,
+	CSSM_ALGMODE_ECB =					CSSM_ALGMODE_NONE + 2,
+	CSSM_ALGMODE_ECBPad =				CSSM_ALGMODE_NONE + 3,
+	CSSM_ALGMODE_CBC =					CSSM_ALGMODE_NONE + 4,
+	CSSM_ALGMODE_CBC_IV8 =				CSSM_ALGMODE_NONE + 5,
+	CSSM_ALGMODE_CBCPadIV8 =			CSSM_ALGMODE_NONE + 6,
+	CSSM_ALGMODE_CFB =					CSSM_ALGMODE_NONE + 7,
+	CSSM_ALGMODE_CFB_IV8 =				CSSM_ALGMODE_NONE + 8,
+	CSSM_ALGMODE_CFBPadIV8 =			CSSM_ALGMODE_NONE + 9,
+	CSSM_ALGMODE_OFB =					CSSM_ALGMODE_NONE + 10,
+	CSSM_ALGMODE_OFB_IV8 =				CSSM_ALGMODE_NONE + 11,
+	CSSM_ALGMODE_OFBPadIV8 =			CSSM_ALGMODE_NONE + 12,
+	CSSM_ALGMODE_COUNTER =				CSSM_ALGMODE_NONE + 13,
+	CSSM_ALGMODE_BC =					CSSM_ALGMODE_NONE + 14,
+	CSSM_ALGMODE_PCBC =					CSSM_ALGMODE_NONE + 15,
+	CSSM_ALGMODE_CBCC =					CSSM_ALGMODE_NONE + 16,
+	CSSM_ALGMODE_OFBNLF =				CSSM_ALGMODE_NONE + 17,
+	CSSM_ALGMODE_PBC =					CSSM_ALGMODE_NONE + 18,
+	CSSM_ALGMODE_PFB =					CSSM_ALGMODE_NONE + 19,
+	CSSM_ALGMODE_CBCPD =				CSSM_ALGMODE_NONE + 20,
+	CSSM_ALGMODE_PUBLIC_KEY =			CSSM_ALGMODE_NONE + 21,
+	CSSM_ALGMODE_PRIVATE_KEY =			CSSM_ALGMODE_NONE + 22,
+	CSSM_ALGMODE_SHUFFLE =				CSSM_ALGMODE_NONE + 23,
+	CSSM_ALGMODE_ECB64 =				CSSM_ALGMODE_NONE + 24,
+	CSSM_ALGMODE_CBC64 =				CSSM_ALGMODE_NONE + 25,
+	CSSM_ALGMODE_OFB64 =				CSSM_ALGMODE_NONE + 26,
+	CSSM_ALGMODE_CFB32 =				CSSM_ALGMODE_NONE + 28,
+	CSSM_ALGMODE_CFB16 =				CSSM_ALGMODE_NONE + 29,
+	CSSM_ALGMODE_CFB8 =					CSSM_ALGMODE_NONE + 30,
+	CSSM_ALGMODE_WRAP =					CSSM_ALGMODE_NONE + 31,
+	CSSM_ALGMODE_PRIVATE_WRAP =			CSSM_ALGMODE_NONE + 32,
+	CSSM_ALGMODE_RELAYX =				CSSM_ALGMODE_NONE + 33,
+	CSSM_ALGMODE_ECB128 =				CSSM_ALGMODE_NONE + 34,
+	CSSM_ALGMODE_ECB96 =				CSSM_ALGMODE_NONE + 35,
+	CSSM_ALGMODE_CBC128 =				CSSM_ALGMODE_NONE + 36,
+	CSSM_ALGMODE_OAEP_HASH =			CSSM_ALGMODE_NONE + 37,
+	CSSM_ALGMODE_PKCS1_EME_V15 =  		CSSM_ALGMODE_NONE + 38,
+	CSSM_ALGMODE_PKCS1_EME_OAEP = 		CSSM_ALGMODE_NONE + 39,
+	CSSM_ALGMODE_PKCS1_EMSA_V15 = 		CSSM_ALGMODE_NONE + 40,
+	CSSM_ALGMODE_ISO_9796 =       		CSSM_ALGMODE_NONE + 41,
+	CSSM_ALGMODE_X9_31 =           		CSSM_ALGMODE_NONE + 42,
+	CSSM_ALGMODE_LAST =            		CSSM_ALGMODE_NONE + 0x7FFFFFFF,
+/* All algorithms modes that are vendor specific, and
+   not part of the CSSM specification should be defined
+   relative to CSSM_ALGMODE_VENDOR_DEFINED. */
+	CSSM_ALGMODE_VENDOR_DEFINED =		CSSM_ALGMODE_NONE + 0x80000000
+};
+
+typedef struct cssm_keyheader {
+    CSSM_HEADERVERSION HeaderVersion; /* Key header version */
+    CSSM_GUID CspId; /* GUID of CSP generating the key */
+    CSSM_KEYBLOB_TYPE BlobType; /* See BlobType enum */
+    CSSM_KEYBLOB_FORMAT Format; /* Raw or Reference format */
+    CSSM_ALGORITHMS AlgorithmId; /* Algorithm ID of key */
+    CSSM_KEYCLASS KeyClass; /* Public/Private/Secret, etc. */
+    uint32 LogicalKeySizeInBits; /* Logical key size in bits */
+    CSSM_KEYATTR_FLAGS KeyAttr; /* Attribute flags */
+    CSSM_KEYUSE KeyUsage; /* Key use flags */
+    CSSM_DATE StartDate; /* Effective date of key */
+    CSSM_DATE EndDate; /* Expiration date of key */
+    CSSM_ALGORITHMS WrapAlgorithmId; /* == CSSM_ALGID_NONE if clear key */
+    CSSM_ENCRYPT_MODE WrapMode; /* if alg supports multiple wrapping modes */
+    uint32 Reserved;
+} CSSM_KEYHEADER, *CSSM_KEYHEADER_PTR;
+
+typedef struct cssm_key {
+    CSSM_KEYHEADER KeyHeader; /* Fixed length key header */
+    CSSM_DATA KeyData; /* Variable length key data */
+} CSSM_KEY, *CSSM_KEY_PTR;
+
+typedef CSSM_KEY CSSM_WRAP_KEY, *CSSM_WRAP_KEY_PTR;
+
+typedef uint32 CSSM_CSPTYPE;
+enum {
+    CSSM_CSP_SOFTWARE =					1,
+    CSSM_CSP_HARDWARE =					CSSM_CSP_SOFTWARE + 1,
+    CSSM_CSP_HYBRID =					CSSM_CSP_SOFTWARE + 2
+};
+
+/* From DL. */
+typedef struct cssm_dl_db_handle {
+    CSSM_DL_HANDLE DLHandle;
+    CSSM_DB_HANDLE DBHandle;
+} CSSM_DL_DB_HANDLE, *CSSM_DL_DB_HANDLE_PTR;
+
+typedef uint32 CSSM_CONTEXT_TYPE;
+enum {
+	CSSM_ALGCLASS_NONE =				0,
+	CSSM_ALGCLASS_CUSTOM =				CSSM_ALGCLASS_NONE + 1,
+	CSSM_ALGCLASS_SIGNATURE =			CSSM_ALGCLASS_NONE + 2,
+	CSSM_ALGCLASS_SYMMETRIC =			CSSM_ALGCLASS_NONE + 3,
+	CSSM_ALGCLASS_DIGEST =				CSSM_ALGCLASS_NONE + 4,
+	CSSM_ALGCLASS_RANDOMGEN =			CSSM_ALGCLASS_NONE + 5,
+	CSSM_ALGCLASS_UNIQUEGEN =			CSSM_ALGCLASS_NONE + 6,
+	CSSM_ALGCLASS_MAC =					CSSM_ALGCLASS_NONE + 7,
+	CSSM_ALGCLASS_ASYMMETRIC =			CSSM_ALGCLASS_NONE + 8,
+	CSSM_ALGCLASS_KEYGEN =				CSSM_ALGCLASS_NONE + 9,
+	CSSM_ALGCLASS_DERIVEKEY =			CSSM_ALGCLASS_NONE + 10
+};
+
+/* Attribute data type tags */
+enum {
+	CSSM_ATTRIBUTE_DATA_NONE =					0x00000000,
+	CSSM_ATTRIBUTE_DATA_UINT32 =				0x10000000,
+	CSSM_ATTRIBUTE_DATA_CSSM_DATA =				0x20000000,
+	CSSM_ATTRIBUTE_DATA_CRYPTO_DATA =			0x30000000,
+	CSSM_ATTRIBUTE_DATA_KEY =					0x40000000,
+	CSSM_ATTRIBUTE_DATA_STRING =				0x50000000,
+	CSSM_ATTRIBUTE_DATA_DATE =					0x60000000,
+	CSSM_ATTRIBUTE_DATA_RANGE =					0x70000000,
+	CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS =	0x80000000,
+	CSSM_ATTRIBUTE_DATA_VERSION =				0x01000000,
+	CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE =			0x02000000,
+	CSSM_ATTRIBUTE_DATA_KR_PROFILE =			0x03000000,
+	CSSM_ATTRIBUTE_TYPE_MASK =					0xFF000000
+};
+
+typedef uint32 CSSM_ATTRIBUTE_TYPE;
+enum {
+    CSSM_ATTRIBUTE_NONE =				0,
+    CSSM_ATTRIBUTE_CUSTOM =				CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 1,
+    CSSM_ATTRIBUTE_DESCRIPTION =		CSSM_ATTRIBUTE_DATA_STRING				| 2,
+    CSSM_ATTRIBUTE_KEY =				CSSM_ATTRIBUTE_DATA_KEY					| 3,
+    CSSM_ATTRIBUTE_INIT_VECTOR =		CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 4,
+    CSSM_ATTRIBUTE_SALT =				CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 5,
+    CSSM_ATTRIBUTE_PADDING =			CSSM_ATTRIBUTE_DATA_UINT32				| 6,
+    CSSM_ATTRIBUTE_RANDOM =				CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 7,
+    CSSM_ATTRIBUTE_SEED =				CSSM_ATTRIBUTE_DATA_CRYPTO_DATA			| 8,
+    CSSM_ATTRIBUTE_PASSPHRASE =			CSSM_ATTRIBUTE_DATA_CRYPTO_DATA			| 9,
+    CSSM_ATTRIBUTE_KEY_LENGTH =			CSSM_ATTRIBUTE_DATA_UINT32				| 10,
+    CSSM_ATTRIBUTE_KEY_LENGTH_RANGE =	CSSM_ATTRIBUTE_DATA_RANGE				| 11,
+    CSSM_ATTRIBUTE_BLOCK_SIZE =			CSSM_ATTRIBUTE_DATA_UINT32				| 12,
+    CSSM_ATTRIBUTE_OUTPUT_SIZE =		CSSM_ATTRIBUTE_DATA_UINT32				| 13,
+    CSSM_ATTRIBUTE_ROUNDS =				CSSM_ATTRIBUTE_DATA_UINT32				| 14,
+    CSSM_ATTRIBUTE_IV_SIZE =			CSSM_ATTRIBUTE_DATA_UINT32				| 15,
+    CSSM_ATTRIBUTE_ALG_PARAMS =			CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 16,
+    CSSM_ATTRIBUTE_LABEL =				CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 17,
+    CSSM_ATTRIBUTE_KEY_TYPE =			CSSM_ATTRIBUTE_DATA_UINT32				| 18,
+    CSSM_ATTRIBUTE_MODE =				CSSM_ATTRIBUTE_DATA_UINT32				| 19,
+    CSSM_ATTRIBUTE_EFFECTIVE_BITS =		CSSM_ATTRIBUTE_DATA_UINT32				| 20,
+    CSSM_ATTRIBUTE_START_DATE =			CSSM_ATTRIBUTE_DATA_DATE				| 21,
+    CSSM_ATTRIBUTE_END_DATE =			CSSM_ATTRIBUTE_DATA_DATE				| 22,
+    CSSM_ATTRIBUTE_KEYUSAGE =			CSSM_ATTRIBUTE_DATA_UINT32				| 23,
+    CSSM_ATTRIBUTE_KEYATTR =			CSSM_ATTRIBUTE_DATA_UINT32				| 24,
+    CSSM_ATTRIBUTE_VERSION =			CSSM_ATTRIBUTE_DATA_VERSION				| 25,
+    CSSM_ATTRIBUTE_PRIME =				CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 26,
+    CSSM_ATTRIBUTE_BASE =				CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 27,
+    CSSM_ATTRIBUTE_SUBPRIME =			CSSM_ATTRIBUTE_DATA_CSSM_DATA			| 28,
+    CSSM_ATTRIBUTE_ALG_ID =				CSSM_ATTRIBUTE_DATA_UINT32				| 29,
+    CSSM_ATTRIBUTE_ITERATION_COUNT =	CSSM_ATTRIBUTE_DATA_UINT32				| 30,
+    CSSM_ATTRIBUTE_ROUNDS_RANGE =		CSSM_ATTRIBUTE_DATA_RANGE				| 31,
+	CSSM_ATTRIBUTE_KRPROFILE_LOCAL  =	CSSM_ATTRIBUTE_DATA_KR_PROFILE			| 32,
+	CSSM_ATTRIBUTE_KRPROFILE_REMOTE =	CSSM_ATTRIBUTE_DATA_KR_PROFILE			| 33,
+    CSSM_ATTRIBUTE_CSP_HANDLE =			CSSM_ATTRIBUTE_DATA_UINT32				| 34,
+    CSSM_ATTRIBUTE_DL_DB_HANDLE =		CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE		| 35,
+    CSSM_ATTRIBUTE_ACCESS_CREDENTIALS =	CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS	| 36,
+    CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT =	CSSM_ATTRIBUTE_DATA_UINT32				| 37,
+    CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT =	CSSM_ATTRIBUTE_DATA_UINT32				| 38,
+    CSSM_ATTRIBUTE_SYMMETRIC_KEY_FORMAT=CSSM_ATTRIBUTE_DATA_UINT32				| 39,
+    CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT =	CSSM_ATTRIBUTE_DATA_UINT32				| 40
+};
+
+typedef uint32 CSSM_PADDING;
+enum {
+	CSSM_PADDING_NONE =					0,
+	CSSM_PADDING_CUSTOM =				CSSM_PADDING_NONE + 1,
+	CSSM_PADDING_ZERO =					CSSM_PADDING_NONE + 2,
+	CSSM_PADDING_ONE =					CSSM_PADDING_NONE + 3,
+	CSSM_PADDING_ALTERNATE =			CSSM_PADDING_NONE + 4,
+	CSSM_PADDING_FF =					CSSM_PADDING_NONE + 5,
+	CSSM_PADDING_PKCS5 =				CSSM_PADDING_NONE + 6,
+	CSSM_PADDING_PKCS7 =				CSSM_PADDING_NONE + 7,
+	CSSM_PADDING_CIPHERSTEALING =		CSSM_PADDING_NONE + 8,
+	CSSM_PADDING_RANDOM =				CSSM_PADDING_NONE + 9,
+	CSSM_PADDING_PKCS1 =				CSSM_PADDING_NONE + 10,
+/* All padding types that are vendor specific, and not
+   part of the CSSM specification should be defined
+   relative to CSSM_PADDING_VENDOR_DEFINED. */
+	CSSM_PADDING_VENDOR_DEFINED =		CSSM_PADDING_NONE + 0x80000000
+};
+
+typedef CSSM_ALGORITHMS CSSM_KEY_TYPE;
+
+typedef struct cssm_context_attribute {
+    CSSM_ATTRIBUTE_TYPE AttributeType;
+    uint32 AttributeLength;
+    union cssm_context_attribute_value {
+        char *String;
+        uint32 Uint32;
+        CSSM_ACCESS_CREDENTIALS_PTR AccessCredentials;
+        CSSM_KEY_PTR Key;
+        CSSM_DATA_PTR Data;
+        CSSM_PADDING Padding;
+        CSSM_DATE_PTR Date;
+        CSSM_RANGE_PTR Range;
+        CSSM_CRYPTO_DATA_PTR CryptoData;
+        CSSM_VERSION_PTR Version;
+        CSSM_DL_DB_HANDLE_PTR DLDbHandle;
+        struct cssm_kr_profile *KRProfile;
+    } Attribute;
+} CSSM_CONTEXT_ATTRIBUTE, *CSSM_CONTEXT_ATTRIBUTE_PTR;
+
+typedef struct cssm_context {
+    CSSM_CONTEXT_TYPE ContextType;
+    CSSM_ALGORITHMS AlgorithmType;
+    uint32 NumberOfAttributes;
+    CSSM_CONTEXT_ATTRIBUTE_PTR ContextAttributes;
+    CSSM_CSP_HANDLE CSPHandle;
+    uint32 Reserved; /* reserved for future use */
+    CSSM_BOOL Reserved1; /* reserved for future use */
+    uint32 Reserved2; /* reserved for future use */
+    uint32 Reserved3; /* reserved for future use */
+} CSSM_CONTEXT, *CSSM_CONTEXT_PTR;
+
+typedef uint32 CSSM_SC_FLAGS;
+enum {
+	CSSM_CSP_TOK_RNG =				0x00000001,
+	CSSM_CSP_TOK_CLOCK_EXISTS =		0x00000040
+};
+
+typedef uint32 CSSM_CSP_READER_FLAGS;
+enum {
+	CSSM_CSP_RDR_TOKENPRESENT =			0x00000001,
+	/* Token is present in reader/slot */
+	CSSM_CSP_RDR_EXISTS =				0x00000002,
+	/* Device is a reader with a
+	   removable token */
+	CSSM_CSP_RDR_HW =					0x00000004
+	/* Slot is a hardware slot */
+};
+
+typedef uint32 CSSM_CSP_FLAGS;
+enum {
+	CSSM_CSP_TOK_WRITE_PROTECTED =			0x00000002,
+	CSSM_CSP_TOK_LOGIN_REQUIRED =			0x00000004,
+	CSSM_CSP_TOK_USER_PIN_INITIALIZED =		0x00000008,
+	CSSM_CSP_TOK_PROT_AUTHENTICATION =		0x00000100,
+	CSSM_CSP_TOK_USER_PIN_EXPIRED =			0x00100000,
+	CSSM_CSP_TOK_SESSION_KEY_PASSWORD =		0x00200000,
+	CSSM_CSP_TOK_PRIVATE_KEY_PASSWORD =		0x00400000,
+	CSSM_CSP_STORES_PRIVATE_KEYS =			0x01000000,
+	CSSM_CSP_STORES_PUBLIC_KEYS =			0x02000000,
+	CSSM_CSP_STORES_SESSION_KEYS =			0x04000000,
+	CSSM_CSP_STORES_CERTIFICATES =			0x08000000,
+	CSSM_CSP_STORES_GENERIC =				0x10000000
+};
+
+typedef uint32 CSSM_PKCS_OAEP_MGF;
+enum {
+	CSSM_PKCS_OAEP_MGF_NONE =				0,
+	CSSM_PKCS_OAEP_MGF1_SHA1 =				CSSM_PKCS_OAEP_MGF_NONE + 1,
+	CSSM_PKCS_OAEP_MGF1_MD5 =				CSSM_PKCS_OAEP_MGF_NONE + 2
+};
+
+typedef uint32 CSSM_PKCS_OAEP_PSOURCE;
+enum {
+	CSSM_PKCS_OAEP_PSOURCE_NONE =			0,
+	CSSM_PKCS_OAEP_PSOURCE_Pspecified =		CSSM_PKCS_OAEP_PSOURCE_NONE + 1
+};
+
+typedef struct cssm_pkcs1_oaep_params {
+    uint32 HashAlgorithm;
+    CSSM_DATA HashParams;
+    CSSM_PKCS_OAEP_MGF MGF;
+    CSSM_DATA MGFParams;
+    CSSM_PKCS_OAEP_PSOURCE PSource;
+    CSSM_DATA PSourceParams;
+} CSSM_PKCS1_OAEP_PARAMS, *CSSM_PKCS1_OAEP_PARAMS_PTR;
+
+typedef struct cssm_csp_operational_statistics {
+    CSSM_BOOL UserAuthenticated;
+    /* CSSM_TRUE if the user is logged in to the token, CSSM_FALSE otherwise. */
+    CSSM_CSP_FLAGS DeviceFlags;
+    uint32 TokenMaxSessionCount; /* Exported by Cryptoki modules. */
+    uint32 TokenOpenedSessionCount;
+    uint32 TokenMaxRWSessionCount;
+    uint32 TokenOpenedRWSessionCount;
+    uint32 TokenTotalPublicMem; /* Storage space statistics. */
+    uint32 TokenFreePublicMem;
+    uint32 TokenTotalPrivateMem;
+    uint32 TokenFreePrivateMem;
+} CSSM_CSP_OPERATIONAL_STATISTICS, *CSSM_CSP_OPERATIONAL_STATISTICS_PTR;
+
+/* Indicates that the statistical value can not be revealed or is not
+   relevant for a CSP */
+enum {
+	CSSM_VALUE_NOT_AVAILABLE =		(uint32)(~0)
+};
+
+typedef struct cssm_pkcs5_pbkdf1_params {
+    CSSM_DATA Passphrase;
+    CSSM_DATA InitVector;
+} CSSM_PKCS5_PBKDF1_PARAMS, *CSSM_PKCS5_PBKDF1_PARAMS_PTR;
+
+typedef uint32 CSSM_PKCS5_PBKDF2_PRF;
+enum {
+	CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1 =	0
+};
+
+typedef struct cssm_pkcs5_pbkdf2_params {
+	CSSM_DATA Passphrase;
+	CSSM_PKCS5_PBKDF2_PRF PseudoRandomFunction;
+} CSSM_PKCS5_PBKDF2_PARAMS, *CSSM_PKCS5_PBKDF2_PARAMS_PTR;
+
+typedef struct cssm_kea_derive_params {
+    CSSM_DATA Rb;
+    CSSM_DATA Yb;
+} CSSM_KEA_DERIVE_PARAMS, *CSSM_KEA_DERIVE_PARAMS_PTR;
+
+
+/* Data Types for Trust Policy Services  */
+
+typedef struct cssm_tp_authority_id {
+    CSSM_DATA *AuthorityCert;
+    CSSM_NET_ADDRESS_PTR AuthorityLocation;
+} CSSM_TP_AUTHORITY_ID, *CSSM_TP_AUTHORITY_ID_PTR;
+
+typedef uint32 CSSM_TP_AUTHORITY_REQUEST_TYPE, *CSSM_TP_AUTHORITY_REQUEST_TYPE_PTR;
+enum {
+	CSSM_TP_AUTHORITY_REQUEST_CERTISSUE =		0x01,
+	CSSM_TP_AUTHORITY_REQUEST_CERTREVOKE =		0x02,
+	CSSM_TP_AUTHORITY_REQUEST_CERTSUSPEND =		0x03,
+	CSSM_TP_AUTHORITY_REQUEST_CERTRESUME =		0x04,
+	CSSM_TP_AUTHORITY_REQUEST_CERTVERIFY =		0x05,
+	CSSM_TP_AUTHORITY_REQUEST_CERTNOTARIZE =	0x06,
+	CSSM_TP_AUTHORITY_REQUEST_CERTUSERECOVER =	0x07,
+	CSSM_TP_AUTHORITY_REQUEST_CRLISSUE =		0x100
+};
+
+typedef CSSM_RETURN (CSSMAPI * CSSM_TP_VERIFICATION_RESULTS_CALLBACK)
+	(CSSM_MODULE_HANDLE ModuleHandle,
+	 void *CallerCtx,
+	 CSSM_DATA_PTR VerifiedCert);
+
+/* From CL */
+typedef CSSM_DATA CSSM_OID, *CSSM_OID_PTR;
+
+typedef struct cssm_field {
+    CSSM_OID FieldOid;
+    CSSM_DATA FieldValue;
+} CSSM_FIELD, *CSSM_FIELD_PTR;
+
+/* TP Again. */
+typedef struct cssm_tp_policyinfo {
+    uint32 NumberOfPolicyIds;
+    CSSM_FIELD_PTR PolicyIds;
+    void *PolicyControl;
+} CSSM_TP_POLICYINFO, *CSSM_TP_POLICYINFO_PTR;
+
+typedef uint32 CSSM_TP_SERVICES;
+enum {
+	/* bit masks for additional Authority services available through TP */
+	CSSM_TP_KEY_ARCHIVE =				0x0001, /* archive cert & keys */
+	CSSM_TP_CERT_PUBLISH =				0x0002, /* register cert in directory */
+	CSSM_TP_CERT_NOTIFY_RENEW =			0x0004, /* notify at renewal time */
+	CSSM_TP_CERT_DIR_UPDATE =			0x0008, /* update cert registry entry */
+	CSSM_TP_CRL_DISTRIBUTE =			0x0010 /* push CRL to everyone */
+};
+
+typedef uint32 CSSM_TP_ACTION;
+enum {
+	CSSM_TP_ACTION_DEFAULT =			0
+};
+
+typedef uint32 CSSM_TP_STOP_ON;
+enum {
+    CSSM_TP_STOP_ON_POLICY =			0, /* use the pre-defined stopping criteria */
+    CSSM_TP_STOP_ON_NONE =				1, /* evaluate all condition whether TRUE or FALSE */
+    CSSM_TP_STOP_ON_FIRST_PASS =		2, /* stop evaluation at first TRUE */
+    CSSM_TP_STOP_ON_FIRST_FAIL =		3 /* stop evaluation at first FALSE */
+};
+
+typedef char *CSSM_TIMESTRING;
+
+/* From DL. */
+typedef struct cssm_dl_db_list {
+    uint32 NumHandles;
+    CSSM_DL_DB_HANDLE_PTR DLDBHandle;
+} CSSM_DL_DB_LIST, *CSSM_DL_DB_LIST_PTR;
+
+/* TP Again. */
+typedef struct cssm_tp_callerauth_context {
+    CSSM_TP_POLICYINFO Policy;
+    CSSM_TIMESTRING VerifyTime;
+    CSSM_TP_STOP_ON VerificationAbortOn;
+    CSSM_TP_VERIFICATION_RESULTS_CALLBACK CallbackWithVerifiedCert;
+    uint32 NumberOfAnchorCerts;
+    CSSM_DATA_PTR AnchorCerts;
+    CSSM_DL_DB_LIST_PTR DBList;
+    CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials;
+} CSSM_TP_CALLERAUTH_CONTEXT, *CSSM_TP_CALLERAUTH_CONTEXT_PTR;
+
+typedef uint32 CSSM_CRL_PARSE_FORMAT, * CSSM_CRL_PARSE_FORMAT_PTR;
+enum {
+	CSSM_CRL_PARSE_FORMAT_NONE =		0x00,
+	CSSM_CRL_PARSE_FORMAT_CUSTOM =		0x01,
+	CSSM_CRL_PARSE_FORMAT_SEXPR =		0x02,
+	CSSM_CRL_PARSE_FORMAT_COMPLEX =		0x03,
+	CSSM_CRL_PARSE_FORMAT_OID_NAMED =	0x04,
+	CSSM_CRL_PARSE_FORMAT_TUPLE =		0x05,
+	CSSM_CRL_PARSE_FORMAT_MULTIPLE =	0x7FFE,
+	CSSM_CRL_PARSE_FORMAT_LAST =		0x7FFF,
+	/* Applications wishing to define their own custom parse
+	   format should create a uint32 value greater than the
+	   CSSM_CL_CUSTOM_CRL_PARSE_FORMAT */
+	CSSM_CL_CUSTOM_CRL_PARSE_FORMAT =	0x8000
+};
+
+/* From CL. */
+typedef uint32 CSSM_CRL_TYPE, *CSSM_CRL_TYPE_PTR;
+enum {
+    CSSM_CRL_TYPE_UNKNOWN =				0x00,
+    CSSM_CRL_TYPE_X_509v1 =				0x01,
+    CSSM_CRL_TYPE_X_509v2 =				0x02,
+    CSSM_CRL_TYPE_SPKI =				0x03,
+    CSSM_CRL_TYPE_MULTIPLE =			0x7FFE
+};
+
+typedef uint32 CSSM_CRL_ENCODING, *CSSM_CRL_ENCODING_PTR;
+enum {
+    CSSM_CRL_ENCODING_UNKNOWN =			0x00,
+    CSSM_CRL_ENCODING_CUSTOM =			0x01,
+    CSSM_CRL_ENCODING_BER =				0x02,
+    CSSM_CRL_ENCODING_DER =				0x03,
+    CSSM_CRL_ENCODING_BLOOM =			0x04,
+    CSSM_CRL_ENCODING_SEXPR =			0x05,
+    CSSM_CRL_ENCODING_MULTIPLE =		0x7FFE
+};
+
+typedef struct cssm_encoded_crl {
+    CSSM_CRL_TYPE CrlType; /* type of CRL */
+    CSSM_CRL_ENCODING CrlEncoding; /* encoding for this packed CRL */
+    CSSM_DATA CrlBlob; /* packed CRL */
+} CSSM_ENCODED_CRL, *CSSM_ENCODED_CRL_PTR;
+
+/* TP Again. */
+typedef struct cssm_parsed_crl {
+    CSSM_CRL_TYPE CrlType; /* CRL type */
+    CSSM_CRL_PARSE_FORMAT ParsedCrlFormat;
+    /* struct of ParsedCrl */
+    void *ParsedCrl; /* parsed CRL (to be typecast) */
+} CSSM_PARSED_CRL, *CSSM_PARSED_CRL_PTR;
+
+typedef struct cssm_crl_pair {
+    CSSM_ENCODED_CRL EncodedCrl; /* an encoded CRL blob */
+    CSSM_PARSED_CRL ParsedCrl; /* equivalent parsed CRL */
+} CSSM_CRL_PAIR, *CSSM_CRL_PAIR_PTR;
+
+typedef uint32 CSSM_CRLGROUP_TYPE, * CSSM_CRLGROUP_TYPE_PTR;
+enum {
+	CSSM_CRLGROUP_DATA =			0x00,
+	CSSM_CRLGROUP_ENCODED_CRL =		0x01,
+	CSSM_CRLGROUP_PARSED_CRL =		0x02,
+	CSSM_CRLGROUP_CRL_PAIR =		0x03
+};
+
+typedef struct cssm_crlgroup {
+    CSSM_CRL_TYPE CrlType;
+    CSSM_CRL_ENCODING CrlEncoding;
+    uint32 NumberOfCrls;
+    union {
+        CSSM_DATA_PTR CrlList;					/* CRL blob */
+        CSSM_ENCODED_CRL_PTR EncodedCrlList;	/* CRL blob w/ separate type */
+        CSSM_PARSED_CRL_PTR ParsedCrlList;		/* bushy, parsed CRL */
+        CSSM_CRL_PAIR_PTR PairCrlList;
+    } GroupCrlList;
+    CSSM_CRLGROUP_TYPE CrlGroupType;
+} CSSM_CRLGROUP, *CSSM_CRLGROUP_PTR;
+
+typedef struct cssm_fieldgroup {
+    int NumberOfFields;		/* number of fields in the array */
+    CSSM_FIELD_PTR Fields;	/* array of fields */
+} CSSM_FIELDGROUP, *CSSM_FIELDGROUP_PTR;
+
+typedef uint32 CSSM_EVIDENCE_FORM;
+enum {
+	CSSM_EVIDENCE_FORM_UNSPECIFIC =		0x0,
+	CSSM_EVIDENCE_FORM_CERT =			0x1,
+	CSSM_EVIDENCE_FORM_CRL =			0x2,
+	CSSM_EVIDENCE_FORM_CERT_ID =		0x3,
+	CSSM_EVIDENCE_FORM_CRL_ID =			0x4,
+	CSSM_EVIDENCE_FORM_VERIFIER_TIME =	0x5,
+	CSSM_EVIDENCE_FORM_CRL_THISTIME =	0x6,
+	CSSM_EVIDENCE_FORM_CRL_NEXTTIME =	0x7,
+	CSSM_EVIDENCE_FORM_POLICYINFO =		0x8,
+	CSSM_EVIDENCE_FORM_TUPLEGROUP =		0x9
+};
+
+typedef struct cssm_evidence {
+    CSSM_EVIDENCE_FORM EvidenceForm;
+    void *Evidence; /* Evidence content */
+} CSSM_EVIDENCE, *CSSM_EVIDENCE_PTR;
+
+typedef struct cssm_tp_verify_context {
+    CSSM_TP_ACTION Action;
+    CSSM_DATA ActionData;
+    CSSM_CRLGROUP Crls;
+    CSSM_TP_CALLERAUTH_CONTEXT_PTR Cred;
+} CSSM_TP_VERIFY_CONTEXT, *CSSM_TP_VERIFY_CONTEXT_PTR;
+
+typedef struct cssm_tp_verify_context_result {
+    uint32 NumberOfEvidences;
+    CSSM_EVIDENCE_PTR Evidence;
+} CSSM_TP_VERIFY_CONTEXT_RESULT, *CSSM_TP_VERIFY_CONTEXT_RESULT_PTR;
+
+typedef struct cssm_tp_request_set {
+    uint32 NumberOfRequests;
+    void *Requests;
+} CSSM_TP_REQUEST_SET, *CSSM_TP_REQUEST_SET_PTR;
+
+typedef struct cssm_tp_result_set {
+    uint32 NumberOfResults;
+    void *Results;
+} CSSM_TP_RESULT_SET, *CSSM_TP_RESULT_SET_PTR;
+
+typedef uint32 CSSM_TP_CONFIRM_STATUS, *CSSM_TP_CONFIRM_STATUS_PTR;
+enum {
+	CSSM_TP_CONFIRM_STATUS_UNKNOWN =	0x0,
+	/* indeterminate */
+	CSSM_TP_CONFIRM_ACCEPT =			0x1,
+	/* accept results of executing a
+	   submit-retrieve function pair */
+	CSSM_TP_CONFIRM_REJECT =			0x2
+	/* reject results of executing a
+	   submit-retrieve function pair */
+};
+
+typedef struct cssm_tp_confirm_response {
+    uint32 NumberOfResponses;
+    CSSM_TP_CONFIRM_STATUS_PTR Responses;
+} CSSM_TP_CONFIRM_RESPONSE, *CSSM_TP_CONFIRM_RESPONSE_PTR;
+
+enum {
+	CSSM_ESTIMATED_TIME_UNKNOWN =		-1
+};
+
+enum {
+	CSSM_ELAPSED_TIME_UNKNOWN =			-1,
+	CSSM_ELAPSED_TIME_COMPLETE =		-2
+};
+
+typedef struct cssm_tp_certissue_input {
+    CSSM_SUBSERVICE_UID CSPSubserviceUid;
+    CSSM_CL_HANDLE CLHandle;
+    uint32 NumberOfTemplateFields;
+    CSSM_FIELD_PTR SubjectCertFields;
+    CSSM_TP_SERVICES MoreServiceRequests;
+    uint32 NumberOfServiceControls;
+    CSSM_FIELD_PTR ServiceControls;
+    CSSM_ACCESS_CREDENTIALS_PTR UserCredentials;
+} CSSM_TP_CERTISSUE_INPUT, *CSSM_TP_CERTISSUE_INPUT_PTR;
+
+typedef uint32 CSSM_TP_CERTISSUE_STATUS;
+enum {
+	CSSM_TP_CERTISSUE_STATUS_UNKNOWN =		0x0,
+	/* indeterminate */
+	CSSM_TP_CERTISSUE_OK =					0x1,
+	/* cert issued as requested */
+	CSSM_TP_CERTISSUE_OKWITHCERTMODS =		0x2,
+	/* cert issued but cert contents were
+	   updated by the issuing authority */
+	CSSM_TP_CERTISSUE_OKWITHSERVICEMODS =	0x3,
+	/* cert issued but some requested backend
+	   services were not performed by the
+	   issuing authority */
+	CSSM_TP_CERTISSUE_REJECTED =			0x4,
+	/* cert was not issued due to some error
+	   condition */
+	CSSM_TP_CERTISSUE_NOT_AUTHORIZED =		0x5,
+	/* cert was not issued, the request was
+	   not authorized */
+	CSSM_TP_CERTISSUE_WILL_BE_REVOKED =		0x6
+	/* cert was issued, but TP has initiated
+	   a revocation of the certificate */
+};
+
+typedef struct cssm_tp_certissue_output {
+    CSSM_TP_CERTISSUE_STATUS IssueStatus;
+    CSSM_CERTGROUP_PTR CertGroup;
+    CSSM_TP_SERVICES PerformedServiceRequests;
+} CSSM_TP_CERTISSUE_OUTPUT, *CSSM_TP_CERTISSUE_OUTPUT_PTR;
+
+typedef uint32 CSSM_TP_CERTCHANGE_ACTION;
+enum {
+	CSSM_TP_CERTCHANGE_NONE =			0x0, /* no change */
+	CSSM_TP_CERTCHANGE_REVOKE =			0x1, /* Revoke the certificate */
+/* This action type indicates a request to revoke a single
+   certificate. Notice of the revocation operation remains
+   in affect until the certificate itself expires. Revocation
+   should be used to permanently remove a certificate from use. */
+	CSSM_TP_CERTCHANGE_HOLD =			0x2, /* Hold/suspend the certificate */
+/* This action type indicates a request to suspend a
+   single certificate. A suspension operation implies
+   that the requester intends, at some time in the future,
+   to request that the certificate be released from hold,
+   making it available for use again. Placing a hold on
+   a certificate does not obligate the requester to
+   request a release. In practice, a certificate may
+   remain on hold until the certificate itself expires.
+   Revocation should be used to permanently remove a
+   certificate from use. */
+	CSSM_TP_CERTCHANGE_RELEASE =		0x3 /* Release the held certificate */
+/* This action type indicates a request to release a
+   single certificate currently on hold. A release
+   operation makes a certificate available for use again.
+   Revocation should be used to permanently remove a
+   certificate from use. */
+};
+
+typedef uint32 CSSM_TP_CERTCHANGE_REASON;
+enum {
+	CSSM_TP_CERTCHANGE_REASON_UNKNOWN =					0x0,
+	/* unspecified */
+	CSSM_TP_CERTCHANGE_REASON_KEYCOMPROMISE =			0x1,
+	/* Subject key believed to be compromised */
+	CSSM_TP_CERTCHANGE_REASON_CACOMPROMISE =			0x2,
+	/* CAs key believed to be compromised */
+	CSSM_TP_CERTCHANGE_REASON_CEASEOPERATION =			0x3,
+	/* certificate holder ceases operation under
+	   the jurisdiction of this certificate */
+	CSSM_TP_CERTCHANGE_REASON_AFFILIATIONCHANGE =		0x4,
+	/* certificate holder has moved from this
+	   jurisdiction */
+	CSSM_TP_CERTCHANGE_REASON_SUPERCEDED =				0x5,
+	/* certificate holder as issued a new, superceding
+	   certificate */
+	CSSM_TP_CERTCHANGE_REASON_SUSPECTEDCOMPROMISE =		0x6,
+	/* certificate could be compromised */
+	CSSM_TP_CERTCHANGE_REASON_HOLDRELEASE =				0x7
+	/* certificate holder resumes operation under the
+	   jurisdiction of this certificate */
+};
+
+typedef struct cssm_tp_certchange_input {
+    CSSM_TP_CERTCHANGE_ACTION Action;
+    CSSM_TP_CERTCHANGE_REASON Reason;
+    CSSM_CL_HANDLE CLHandle;
+    CSSM_DATA_PTR Cert;
+    CSSM_FIELD_PTR ChangeInfo;
+    CSSM_TIMESTRING StartTime;
+    CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials;
+} CSSM_TP_CERTCHANGE_INPUT, *CSSM_TP_CERTCHANGE_INPUT_PTR;
+
+typedef uint32 CSSM_TP_CERTCHANGE_STATUS;
+enum {
+	CSSM_TP_CERTCHANGE_STATUS_UNKNOWN =		0x0,
+	/* indeterminate */
+	CSSM_TP_CERTCHANGE_OK =					0x1,
+	/* cert state was successfully changed
+	   beginning at the specified time */
+	CSSM_TP_CERTCHANGE_OKWITHNEWTIME =		0x2,
+	/* cert state was successfully changed,
+	   at a modified effective time */
+	CSSM_TP_CERTCHANGE_WRONGCA =			0x3,
+	/* cert state was not changed, the
+	   selected CA is not authorized to
+	   change the cert state */
+	CSSM_TP_CERTCHANGE_REJECTED =			0x4,
+	/* cert state was not changed due to some
+	   error condition */
+	CSSM_TP_CERTCHANGE_NOT_AUTHORIZED =		0x5
+	/* cert state was not changed, the
+	   requester is not authorized to change
+	   the cert state */
+};
+
+typedef struct cssm_tp_certchange_output {
+    CSSM_TP_CERTCHANGE_STATUS ActionStatus;
+    CSSM_FIELD RevokeInfo;
+} CSSM_TP_CERTCHANGE_OUTPUT, *CSSM_TP_CERTCHANGE_OUTPUT_PTR;
+
+typedef struct cssm_tp_certverify_input {
+    CSSM_CL_HANDLE CLHandle;
+    CSSM_DATA_PTR Cert;
+    CSSM_TP_VERIFY_CONTEXT_PTR VerifyContext;
+} CSSM_TP_CERTVERIFY_INPUT, *CSSM_TP_CERTVERIFY_INPUT_PTR;
+
+typedef uint32 CSSM_TP_CERTVERIFY_STATUS;
+enum {
+	CSSM_TP_CERTVERIFY_UNKNOWN =					0x0,
+	CSSM_TP_CERTVERIFY_VALID =						0x1,
+	CSSM_TP_CERTVERIFY_INVALID =					0x2,
+	CSSM_TP_CERTVERIFY_REVOKED =					0x3,
+	CSSM_TP_CERTVERIFY_SUSPENDED =					0x4,
+	CSSM_TP_CERTVERIFY_EXPIRED =					0x5,
+	CSSM_TP_CERTVERIFY_NOT_VALID_YET =				0x6,
+	CSSM_TP_CERTVERIFY_INVALID_AUTHORITY =			0x7,
+	CSSM_TP_CERTVERIFY_INVALID_SIGNATURE =			0x8,
+	CSSM_TP_CERTVERIFY_INVALID_CERT_VALUE =			0x9,
+	CSSM_TP_CERTVERIFY_INVALID_CERTGROUP =			0xA,
+	CSSM_TP_CERTVERIFY_INVALID_POLICY =				0xB,
+	CSSM_TP_CERTVERIFY_INVALID_POLICY_IDS =			0xC,
+	CSSM_TP_CERTVERIFY_INVALID_BASIC_CONSTRAINTS =	0xD,
+	CSSM_TP_CERTVERIFY_INVALID_CRL_DIST_PT =		0xE,
+	CSSM_TP_CERTVERIFY_INVALID_NAME_TREE =			0xF,
+	CSSM_TP_CERTVERIFY_UNKNOWN_CRITICAL_EXT =		0x10
+};
+
+typedef struct cssm_tp_certverify_output {
+    CSSM_TP_CERTVERIFY_STATUS VerifyStatus;
+    uint32 NumberOfEvidence;
+    CSSM_EVIDENCE_PTR Evidence;
+} CSSM_TP_CERTVERIFY_OUTPUT, *CSSM_TP_CERTVERIFY_OUTPUT_PTR;
+
+typedef struct cssm_tp_certnotarize_input {
+    CSSM_CL_HANDLE CLHandle;
+    uint32 NumberOfFields;
+    CSSM_FIELD_PTR MoreFields;
+    CSSM_FIELD_PTR SignScope;
+    uint32 ScopeSize;
+    CSSM_TP_SERVICES MoreServiceRequests;
+    uint32 NumberOfServiceControls;
+    CSSM_FIELD_PTR ServiceControls;
+    CSSM_ACCESS_CREDENTIALS_PTR UserCredentials;
+} CSSM_TP_CERTNOTARIZE_INPUT, *CSSM_TP_CERTNOTARIZE_INPUT_PTR;
+
+typedef uint32 CSSM_TP_CERTNOTARIZE_STATUS;
+enum {
+	CSSM_TP_CERTNOTARIZE_STATUS_UNKNOWN =		0x0,
+	/* indeterminate */
+	CSSM_TP_CERTNOTARIZE_OK =					0x1,
+	/* cert fields were added and the result was
+	   notarized as requested */
+	CSSM_TP_CERTNOTARIZE_OKWITHOUTFIELDS = 		0x2,
+	/* non-conflicting cert fields were added,
+	   conflicting cert fields were ignored,
+	   and the result was notarized as requested */
+	CSSM_TP_CERTNOTARIZE_OKWITHSERVICEMODS =	0x3,
+	/* cert fields were added and the result was
+	   notarized as requested, but some requested
+	   backend services were not performed by the
+	   notary */
+	CSSM_TP_CERTNOTARIZE_REJECTED = 			0x4,
+	/* cert was not notarized due to some error
+	   condition */
+	CSSM_TP_CERTNOTARIZE_NOT_AUTHORIZED =		0x5
+	/* cert was not notarized, the request was
+	   not authorized */
+};
+
+typedef struct cssm_tp_certnotarize_output {
+    CSSM_TP_CERTNOTARIZE_STATUS NotarizeStatus;
+    CSSM_CERTGROUP_PTR NotarizedCertGroup;
+    CSSM_TP_SERVICES PerformedServiceRequests;
+} CSSM_TP_CERTNOTARIZE_OUTPUT, *CSSM_TP_CERTNOTARIZE_OUTPUT_PTR;
+
+typedef struct cssm_tp_certreclaim_input {
+    CSSM_CL_HANDLE CLHandle;
+    uint32 NumberOfSelectionFields;
+    CSSM_FIELD_PTR SelectionFields;
+    CSSM_ACCESS_CREDENTIALS_PTR UserCredentials;
+} CSSM_TP_CERTRECLAIM_INPUT, *CSSM_TP_CERTRECLAIM_INPUT_PTR;
+
+typedef uint32 CSSM_TP_CERTRECLAIM_STATUS;
+enum {
+	CSSM_TP_CERTRECLAIM_STATUS_UNKNOWN = 	0x0,
+	/* indeterminate */
+	CSSM_TP_CERTRECLAIM_OK =				0x1,
+	/* a set of one or more certificates were
+	   returned by the CA for local recovery
+	   of the associated private key */
+	CSSM_TP_CERTRECLAIM_NOMATCH =			0x2,
+	/* no certificates owned by the requester
+	   were found matching the specified
+	   selection fields */
+	CSSM_TP_CERTRECLAIM_REJECTED =			0x3,
+	/* certificate reclamation failed due
+	   to some error condition */
+	CSSM_TP_CERTRECLAIM_NOT_AUTHORIZED =	0x4
+	/* certificate reclamation was not
+	   performed, the request was not
+	   authorized */
+};
+
+typedef struct cssm_tp_certreclaim_output {
+    CSSM_TP_CERTRECLAIM_STATUS ReclaimStatus;
+    CSSM_CERTGROUP_PTR ReclaimedCertGroup;
+    CSSM_LONG_HANDLE KeyCacheHandle;
+} CSSM_TP_CERTRECLAIM_OUTPUT, *CSSM_TP_CERTRECLAIM_OUTPUT_PTR;
+
+typedef struct cssm_tp_crlissue_input {
+    CSSM_CL_HANDLE CLHandle;
+    uint32 CrlIdentifier;
+    CSSM_TIMESTRING CrlThisTime;
+    CSSM_FIELD_PTR PolicyIdentifier;
+    CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials;
+} CSSM_TP_CRLISSUE_INPUT, *CSSM_TP_CRLISSUE_INPUT_PTR;
+
+typedef uint32 CSSM_TP_CRLISSUE_STATUS;
+enum {
+	CSSM_TP_CRLISSUE_STATUS_UNKNOWN =		0x0,
+	/* indeterminate */
+	CSSM_TP_CRLISSUE_OK =					0x1,
+	/* a copy of the most current CRL was
+	   issued as requested and the time for
+	   issuing the next CRL is also returned */
+	CSSM_TP_CRLISSUE_NOT_CURRENT =			0x2,
+	/* either no CRL has been issued since
+	   the CRL identified in the request, or
+	   it is not time to issue an updated CRL.
+	   no CRL has been returned, but the time
+	   for issuing the next CRL is included
+	   in the results */
+	CSSM_TP_CRLISSUE_INVALID_DOMAIN =		0x3,
+	/* CRL domain was not recognized or was
+	   outside the CA jurisdiction, no CRL or
+	   time for the next CRL has been
+	   returned. */
+	CSSM_TP_CRLISSUE_UNKNOWN_IDENTIFIER =	0x4,
+	/* unrecognized CRL identifier, no CRL or
+	   time for the next CRL has been
+	   returned. */
+	CSSM_TP_CRLISSUE_REJECTED =				0x5,
+	/* CRL was not issued due to some error
+	   condition, no CRL or time for the next
+	   CRL has been returned. */
+	CSSM_TP_CRLISSUE_NOT_AUTHORIZED =		0x6
+	/* CRL was not issued, the request was
+	   not authorized, no CRL or time for the
+	   next CRL has been returned. */
+};
+
+typedef struct cssm_tp_crlissue_output {
+    CSSM_TP_CRLISSUE_STATUS IssueStatus;
+    CSSM_ENCODED_CRL_PTR Crl;
+    CSSM_TIMESTRING CrlNextTime;
+} CSSM_TP_CRLISSUE_OUTPUT, *CSSM_TP_CRLISSUE_OUTPUT_PTR;
+
+typedef uint32 CSSM_TP_FORM_TYPE;
+enum {
+	CSSM_TP_FORM_TYPE_GENERIC =				0x0,
+	CSSM_TP_FORM_TYPE_REGISTRATION =		0x1
+};
+
+/* Data Types for Certificate Library Services  */
+
+typedef uint32 CSSM_CL_TEMPLATE_TYPE;
+enum {
+	CSSM_CL_TEMPLATE_INTERMEDIATE_CERT =	1,
+	/* for X509 certificates, a fully-formed
+	   encoded certificate with empty signature field */
+	CSSM_CL_TEMPLATE_PKIX_CERTTEMPLATE =	2
+	/* as defined in RFC2511, section 5 CertTemplate */
+};
+
+typedef uint32 CSSM_CERT_BUNDLE_TYPE;
+enum {
+    CSSM_CERT_BUNDLE_UNKNOWN =						0x00,
+    CSSM_CERT_BUNDLE_CUSTOM =						0x01,
+    CSSM_CERT_BUNDLE_PKCS7_SIGNED_DATA =			0x02,
+    CSSM_CERT_BUNDLE_PKCS7_SIGNED_ENVELOPED_DATA =	0x03,
+    CSSM_CERT_BUNDLE_PKCS12 =						0x04,
+    CSSM_CERT_BUNDLE_PFX =							0x05,
+    CSSM_CERT_BUNDLE_SPKI_SEQUENCE =				0x06,
+    CSSM_CERT_BUNDLE_PGP_KEYRING =					0x07,
+    CSSM_CERT_BUNDLE_LAST =							0x7FFF,
+	/* Applications wishing to define their own custom certificate
+	   bundle type should define and publicly document a uint32
+	   value greater than CSSM_CL_CUSTOM_CERT_BUNDLE_TYPE */
+	CSSM_CL_CUSTOM_CERT_BUNDLE_TYPE =				0x8000
+};
+
+typedef uint32 CSSM_CERT_BUNDLE_ENCODING;
+enum {
+    CSSM_CERT_BUNDLE_ENCODING_UNKNOWN =			0x00,
+    CSSM_CERT_BUNDLE_ENCODING_CUSTOM =			0x01,
+    CSSM_CERT_BUNDLE_ENCODING_BER =				0x02,
+    CSSM_CERT_BUNDLE_ENCODING_DER =				0x03,
+    CSSM_CERT_BUNDLE_ENCODING_SEXPR =			0x04,
+    CSSM_CERT_BUNDLE_ENCODING_PGP =				0x05
+};
+
+typedef struct cssm_cert_bundle_header {
+    CSSM_CERT_BUNDLE_TYPE BundleType;
+    CSSM_CERT_BUNDLE_ENCODING BundleEncoding;
+} CSSM_CERT_BUNDLE_HEADER, *CSSM_CERT_BUNDLE_HEADER_PTR;
+
+typedef struct cssm_cert_bundle {
+    CSSM_CERT_BUNDLE_HEADER BundleHeader;
+    CSSM_DATA Bundle;
+} CSSM_CERT_BUNDLE, *CSSM_CERT_BUNDLE_PTR;
+
+enum {
+	CSSM_FIELDVALUE_COMPLEX_DATA_TYPE =			0xFFFFFFFF
+};
+
+/* Data Types for Data Storage Library Services  */
+
+typedef uint32 CSSM_DB_ATTRIBUTE_NAME_FORMAT, *CSSM_DB_ATTRIBUTE_NAME_FORMAT_PTR;
+enum {
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING =			0,
+    CSSM_DB_ATTRIBUTE_NAME_AS_OID =				1,
+	CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER =			2
+};
+
+typedef uint32 CSSM_DB_ATTRIBUTE_FORMAT, *CSSM_DB_ATTRIBUTE_FORMAT_PTR;
+enum {
+    CSSM_DB_ATTRIBUTE_FORMAT_STRING =			0,
+    CSSM_DB_ATTRIBUTE_FORMAT_SINT32 =			1,
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32 =			2,
+    CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM =			3,
+    CSSM_DB_ATTRIBUTE_FORMAT_REAL =				4,
+    CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE =		5,
+    CSSM_DB_ATTRIBUTE_FORMAT_BLOB =				6,
+    CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32 =		7,
+    CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX =			8
+};
+
+typedef struct cssm_db_attribute_info {
+    CSSM_DB_ATTRIBUTE_NAME_FORMAT AttributeNameFormat;
+    union cssm_db_attribute_label {
+        char *AttributeName;		/* e.g., "record label" */
+        CSSM_OID AttributeOID;		/* e.g., CSSMOID_RECORDLABEL */
+        uint32 AttributeID;			/* e.g., FOUR_CHAR_CODE('recl') */
+    } Label;
+    CSSM_DB_ATTRIBUTE_FORMAT AttributeFormat;
+} CSSM_DB_ATTRIBUTE_INFO, *CSSM_DB_ATTRIBUTE_INFO_PTR;
+
+typedef struct cssm_db_attribute_data {
+    CSSM_DB_ATTRIBUTE_INFO Info;
+    uint32 NumberOfValues;
+    CSSM_DATA_PTR Value;
+} CSSM_DB_ATTRIBUTE_DATA, *CSSM_DB_ATTRIBUTE_DATA_PTR;
+
+typedef uint32 CSSM_DB_RECORDTYPE;
+enum {
+	/* Schema Management Name Space Range Definition*/
+	CSSM_DB_RECORDTYPE_SCHEMA_START =			0x00000000,
+	CSSM_DB_RECORDTYPE_SCHEMA_END =				CSSM_DB_RECORDTYPE_SCHEMA_START + 4,
+	/* Open Group Application Name Space Range Definition*/
+	CSSM_DB_RECORDTYPE_OPEN_GROUP_START =		0x0000000A,
+	CSSM_DB_RECORDTYPE_OPEN_GROUP_END =			CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 8,
+	/* Industry At Large Application Name Space Range Definition */
+	CSSM_DB_RECORDTYPE_APP_DEFINED_START =		0x80000000,
+	CSSM_DB_RECORDTYPE_APP_DEFINED_END =		0xffffffff,
+	/* Record Types defined in the Schema Management Name Space */
+	CSSM_DL_DB_SCHEMA_INFO =					CSSM_DB_RECORDTYPE_SCHEMA_START + 0,
+	CSSM_DL_DB_SCHEMA_INDEXES =					CSSM_DB_RECORDTYPE_SCHEMA_START + 1,
+	CSSM_DL_DB_SCHEMA_ATTRIBUTES =				CSSM_DB_RECORDTYPE_SCHEMA_START + 2,
+	CSSM_DL_DB_SCHEMA_PARSING_MODULE =			CSSM_DB_RECORDTYPE_SCHEMA_START + 3,
+	/* Record Types defined in the Open Group Application Name Space */
+	CSSM_DL_DB_RECORD_ANY =						CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 0,
+	CSSM_DL_DB_RECORD_CERT =					CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 1,
+	CSSM_DL_DB_RECORD_CRL =						CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 2,
+	CSSM_DL_DB_RECORD_POLICY =					CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 3,
+	CSSM_DL_DB_RECORD_GENERIC =					CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 4,
+	CSSM_DL_DB_RECORD_PUBLIC_KEY =				CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 5,
+	CSSM_DL_DB_RECORD_PRIVATE_KEY =				CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 6,
+	CSSM_DL_DB_RECORD_SYMMETRIC_KEY =			CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 7,
+	CSSM_DL_DB_RECORD_ALL_KEYS =				CSSM_DB_RECORDTYPE_OPEN_GROUP_START + 8
+};
+
+enum {
+	CSSM_DB_CERT_USE_TRUSTED =			0x00000001,	/* application-defined as trusted */
+	CSSM_DB_CERT_USE_SYSTEM =			0x00000002,	/* the CSSM system cert */
+	CSSM_DB_CERT_USE_OWNER =			0x00000004,	/* private key owned by system user*/
+	CSSM_DB_CERT_USE_REVOKED =			0x00000008,	/* revoked cert -15913 used w CRL APIs */
+	CSSM_DB_CERT_USE_SIGNING =			0x00000010,	/* use cert for signing only */
+	CSSM_DB_CERT_USE_PRIVACY =			0x00000020	/* use cert for confidentiality only */
+};
+
+typedef struct cssm_db_record_attribute_info {
+    CSSM_DB_RECORDTYPE DataRecordType;
+    uint32 NumberOfAttributes;
+    CSSM_DB_ATTRIBUTE_INFO_PTR AttributeInfo;
+} CSSM_DB_RECORD_ATTRIBUTE_INFO, *CSSM_DB_RECORD_ATTRIBUTE_INFO_PTR;
+
+typedef struct cssm_db_record_attribute_data {
+    CSSM_DB_RECORDTYPE DataRecordType;
+    uint32 SemanticInformation;
+    uint32 NumberOfAttributes;
+    CSSM_DB_ATTRIBUTE_DATA_PTR AttributeData;
+} CSSM_DB_RECORD_ATTRIBUTE_DATA, *CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR;
+
+typedef struct cssm_db_parsing_module_info {
+    CSSM_DB_RECORDTYPE RecordType;
+    CSSM_SUBSERVICE_UID ModuleSubserviceUid;
+} CSSM_DB_PARSING_MODULE_INFO, *CSSM_DB_PARSING_MODULE_INFO_PTR;
+
+typedef uint32 CSSM_DB_INDEX_TYPE;
+enum {
+    CSSM_DB_INDEX_UNIQUE =				0,
+    CSSM_DB_INDEX_NONUNIQUE =			1
+};
+
+typedef uint32 CSSM_DB_INDEXED_DATA_LOCATION;
+enum {
+    CSSM_DB_INDEX_ON_UNKNOWN =			0,
+    CSSM_DB_INDEX_ON_ATTRIBUTE =		1,
+    CSSM_DB_INDEX_ON_RECORD =			2
+};
+
+typedef struct cssm_db_index_info {
+    CSSM_DB_INDEX_TYPE IndexType;
+    CSSM_DB_INDEXED_DATA_LOCATION IndexedDataLocation;
+    CSSM_DB_ATTRIBUTE_INFO Info;
+} CSSM_DB_INDEX_INFO, *CSSM_DB_INDEX_INFO_PTR;
+
+typedef struct cssm_db_unique_record {
+    CSSM_DB_INDEX_INFO RecordLocator;
+    CSSM_DATA RecordIdentifier;
+} CSSM_DB_UNIQUE_RECORD, *CSSM_DB_UNIQUE_RECORD_PTR;
+
+typedef struct cssm_db_record_index_info {
+    CSSM_DB_RECORDTYPE DataRecordType;
+    uint32 NumberOfIndexes;
+    CSSM_DB_INDEX_INFO_PTR IndexInfo;
+} CSSM_DB_RECORD_INDEX_INFO, *CSSM_DB_RECORD_INDEX_INFO_PTR;
+
+typedef uint32 CSSM_DB_ACCESS_TYPE, *CSSM_DB_ACCESS_TYPE_PTR;
+enum {
+	CSSM_DB_ACCESS_READ =				0x00001,
+	CSSM_DB_ACCESS_WRITE =				0x00002,
+	CSSM_DB_ACCESS_PRIVILEGED =			0x00004 /* versus user mode */
+};
+
+typedef uint32 CSSM_DB_MODIFY_MODE;
+enum {
+	CSSM_DB_MODIFY_ATTRIBUTE_NONE =		0,
+	CSSM_DB_MODIFY_ATTRIBUTE_ADD =		CSSM_DB_MODIFY_ATTRIBUTE_NONE + 1,
+	CSSM_DB_MODIFY_ATTRIBUTE_DELETE =	CSSM_DB_MODIFY_ATTRIBUTE_NONE + 2,
+	CSSM_DB_MODIFY_ATTRIBUTE_REPLACE =	CSSM_DB_MODIFY_ATTRIBUTE_NONE + 3
+};
+
+typedef struct cssm_dbinfo {
+    /* meta information about each record type stored in this
+    data store including meta information about record
+    attributes and indexes */
+    uint32 NumberOfRecordTypes;
+    CSSM_DB_PARSING_MODULE_INFO_PTR DefaultParsingModules;
+    CSSM_DB_RECORD_ATTRIBUTE_INFO_PTR RecordAttributeNames;
+    CSSM_DB_RECORD_INDEX_INFO_PTR RecordIndexes;
+    /* access restrictions for opening this data store */
+    CSSM_BOOL IsLocal;
+    char *AccessPath; /* URL, dir path, etc. */
+    void *Reserved;
+} CSSM_DBINFO, *CSSM_DBINFO_PTR;
+
+typedef uint32 CSSM_DB_OPERATOR, *CSSM_DB_OPERATOR_PTR;
+enum {
+    CSSM_DB_EQUAL =							0,
+    CSSM_DB_NOT_EQUAL =						1,
+    CSSM_DB_LESS_THAN =						2,
+    CSSM_DB_GREATER_THAN =					3,
+    CSSM_DB_CONTAINS =						4,
+    CSSM_DB_CONTAINS_INITIAL_SUBSTRING =	5,
+    CSSM_DB_CONTAINS_FINAL_SUBSTRING =		6
+};
+
+typedef uint32 CSSM_DB_CONJUNCTIVE, *CSSM_DB_CONJUNCTIVE_PTR;
+enum {
+    CSSM_DB_NONE =						0,
+    CSSM_DB_AND =						1,
+    CSSM_DB_OR =						2
+};
+
+typedef struct cssm_selection_predicate {
+    CSSM_DB_OPERATOR DbOperator;
+    CSSM_DB_ATTRIBUTE_DATA Attribute;
+} CSSM_SELECTION_PREDICATE, *CSSM_SELECTION_PREDICATE_PTR;
+
+enum {
+	CSSM_QUERY_TIMELIMIT_NONE =			0
+};
+
+enum {
+	CSSM_QUERY_SIZELIMIT_NONE =			0
+};
+
+typedef struct cssm_query_limits {
+    uint32 TimeLimit; /* in seconds */
+    uint32 SizeLimit; /* max. number of records to return */
+} CSSM_QUERY_LIMITS, *CSSM_QUERY_LIMITS_PTR;
+
+typedef uint32 CSSM_QUERY_FLAGS;
+enum {
+	CSSM_QUERY_RETURN_DATA =			0x01
+};
+
+typedef struct cssm_query {
+    CSSM_DB_RECORDTYPE RecordType;
+    CSSM_DB_CONJUNCTIVE Conjunctive;
+    uint32 NumSelectionPredicates;
+    CSSM_SELECTION_PREDICATE_PTR SelectionPredicate;
+    CSSM_QUERY_LIMITS QueryLimits;
+    CSSM_QUERY_FLAGS QueryFlags;
+} CSSM_QUERY, *CSSM_QUERY_PTR;
+
+typedef uint32 CSSM_DLTYPE, *CSSM_DLTYPE_PTR;
+enum {
+    CSSM_DL_UNKNOWN =					0,
+    CSSM_DL_CUSTOM =					1,
+    CSSM_DL_LDAP =						2,
+    CSSM_DL_ODBC =						3,
+    CSSM_DL_PKCS11 =					4,
+    CSSM_DL_FFS =						5, /* flat file system */
+    CSSM_DL_MEMORY =					6,
+    CSSM_DL_REMOTEDIR =					7
+};
+
+typedef void *CSSM_DL_CUSTOM_ATTRIBUTES;
+typedef void *CSSM_DL_LDAP_ATTRIBUTES;
+typedef void *CSSM_DL_ODBC_ATTRIBUTES;
+typedef void *CSSM_DL_FFS_ATTRIBUTES;
+
+typedef struct cssm_dl_pkcs11_attributes {
+    uint32 DeviceAccessFlags;
+} *CSSM_DL_PKCS11_ATTRIBUTE, *CSSM_DL_PKCS11_ATTRIBUTE_PTR;
+
+enum {
+	CSSM_DB_DATASTORES_UNKNOWN =		0xFFFFFFFF
+};
+
+typedef struct cssm_name_list {
+    uint32 NumStrings;
+    char **String;
+} CSSM_NAME_LIST, *CSSM_NAME_LIST_PTR;
+
+typedef uint32 CSSM_DB_RETRIEVAL_MODES;
+enum {
+	CSSM_DB_TRANSACTIONAL_MODE =		0,
+	CSSM_DB_FILESYSTEMSCAN_MODE =		1
+};
+
+typedef struct cssm_db_schema_attribute_info {
+    uint32 AttributeId;
+    char *AttributeName;
+    CSSM_OID AttributeNameID;
+    CSSM_DB_ATTRIBUTE_FORMAT DataType;
+} CSSM_DB_SCHEMA_ATTRIBUTE_INFO, *CSSM_DB_SCHEMA_ATTRIBUTE_INFO_PTR;
+
+typedef struct cssm_db_schema_index_info {
+    uint32 AttributeId;
+    uint32 IndexId;
+    CSSM_DB_INDEX_TYPE IndexType;
+    CSSM_DB_INDEXED_DATA_LOCATION IndexedDataLocation;
+} CSSM_DB_SCHEMA_INDEX_INFO, *CSSM_DB_SCHEMA_INDEX_INFO_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSSMTYPE_H_ */
diff --git a/cdsa/cdsa/eisl.h b/cdsa/cdsa/eisl.h
new file mode 100644
index 00000000..698b4d29
--- /dev/null
+++ b/cdsa/cdsa/eisl.h
@@ -0,0 +1,328 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      eisl.h
+
+   Contains:  Embedded Integrity Services Library Interface
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _EISL_H_
+#define _EISL_H_  1
+
+#include <Security/cssmconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Data Types for Embedded Integrity Services Library */
+
+typedef const void *ISL_ITERATOR_PTR;
+
+typedef const void *ISL_VERIFIED_SIGNATURE_ROOT_PTR;
+
+typedef const void *ISL_VERIFIED_CERTIFICATE_CHAIN_PTR;
+
+typedef const void *ISL_VERIFIED_CERTIFICATE_PTR;
+
+typedef const void *ISL_MANIFEST_SECTION_PTR;
+
+typedef const void *ISL_VERIFIED_MODULE_PTR;
+
+typedef void (*ISL_FUNCTION_PTR)(void);
+
+typedef struct isl_data {
+    uint32 Length; /* in bytes */
+    uint8 *Data;
+} ISL_DATA, *ISL_DATA_PTR;
+
+typedef struct isl_const_data {
+    uint32 Length; /* in bytes */
+    const uint8 *Data;
+} ISL_CONST_DATA, *ISL_CONST_DATA_PTR;
+
+typedef enum isl_status {
+	ISL_OK = 0,
+	ISL_FAIL = -1
+} ISL_STATUS;
+
+typedef void (*ISL_FUNCTION_PTR)(void);
+
+/* Embedded Integrity Services Library Functions */
+
+ISL_VERIFIED_MODULE_PTR
+EISL_SelfCheck ();
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyAndLoadModuleAndCredentialData (const ISL_CONST_DATA CredentialsImage,
+                                           const ISL_CONST_DATA ModuleSearchPath,
+                                           const ISL_CONST_DATA Name,
+                                           const ISL_CONST_DATA Signer,
+                                           const ISL_CONST_DATA PublicKey);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyAndLoadModuleAndCredentialDataWithCertificate (const ISL_CONST_DATA CredentialsImage,
+                                                          const ISL_CONST_DATA ModuleSearchPath,
+                                                          const ISL_CONST_DATA Name,
+                                                          const ISL_CONST_DATA Signer,
+                                                          const ISL_CONST_DATA Certificate);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyAndLoadModuleAndCredentials (ISL_CONST_DATA Credentials,
+                                        ISL_CONST_DATA Name,
+                                        ISL_CONST_DATA Signer,
+                                        ISL_CONST_DATA PublicKey);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyAndLoadModuleAndCredentialsWithCertificate (const ISL_CONST_DATA Credentials,
+                                                       const ISL_CONST_DATA Name,
+                                                       const ISL_CONST_DATA Signer,
+                                                       const ISL_CONST_DATA Certificate);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyLoadedModuleAndCredentialData (const ISL_CONST_DATA CredentialsImage,
+                                          const ISL_CONST_DATA ModuleSearchPath,
+                                          const ISL_CONST_DATA Name,
+                                          const ISL_CONST_DATA Signer,
+                                          const ISL_CONST_DATA PublicKey);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyLoadedModuleAndCredentialDataWithCertificate (const ISL_CONST_DATA CredentialsImage,
+                                                         const ISL_CONST_DATA ModuleSearchPath,
+                                                         const ISL_CONST_DATA Name,
+                                                         const ISL_CONST_DATA Signer,
+                                                         const ISL_CONST_DATA Certificate);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyLoadedModuleAndCredentials (ISL_CONST_DATA Credentials,
+                                       ISL_CONST_DATA Name,
+                                       ISL_CONST_DATA Signer,
+                                       ISL_CONST_DATA PublicKey);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyLoadedModuleAndCredentialsWithCertificate (const ISL_CONST_DATA Credentials,
+                                                      const ISL_CONST_DATA Name,
+                                                      const ISL_CONST_DATA Signer,
+                                                      const ISL_CONST_DATA Certificate);
+
+ISL_VERIFIED_CERTIFICATE_CHAIN_PTR
+EISL_GetCertificateChain (ISL_VERIFIED_MODULE_PTR Module);
+
+uint32
+EISL_ContinueVerification (ISL_VERIFIED_MODULE_PTR Module,
+                           uint32 WorkFactor);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_DuplicateVerifiedModulePtr (ISL_VERIFIED_MODULE_PTR Module);
+
+ISL_STATUS
+EISL_RecycleVerifiedModuleCredentials (ISL_VERIFIED_MODULE_PTR Verification);
+
+
+/* Signature Root Methods */
+
+ISL_VERIFIED_SIGNATURE_ROOT_PTR
+EISL_CreateVerifiedSignatureRootWithCredentialData (const ISL_CONST_DATA CredentialsImage,
+                                                    const ISL_CONST_DATA ModuleSearchPath,
+                                                    const ISL_CONST_DATA Signer,
+                                                    const ISL_CONST_DATA PublicKey);
+
+ISL_VERIFIED_SIGNATURE_ROOT_PTR
+EISL_CreateVerifiedSignatureRootWithCredentialDataAndCertificate (const ISL_CONST_DATA CredentialsImage,
+                                                                  const ISL_CONST_DATA ModuleSearchPath,
+                                                                  ISL_VERIFIED_CERTIFICATE_PTR Cert);
+
+ISL_VERIFIED_SIGNATURE_ROOT_PTR
+EISL_CreateVerfiedSignatureRoot (ISL_CONST_DATA Credentials,
+                                 ISL_CONST_DATA Signer,
+                                 ISL_CONST_DATA PublicKey);
+
+ISL_VERIFIED_SIGNATURE_ROOT_PTR
+EISL_CreateVerfiedSignatureRootWithCertificate (ISL_CONST_DATA Credentials,
+                                                ISL_VERIFIED_CERTIFICATE_PTR Cert);
+
+ISL_MANIFEST_SECTION_PTR
+EISL_FindManifestSection (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root,
+                          ISL_CONST_DATA Name);
+
+ISL_ITERATOR_PTR
+EISL_CreateManifestSectionEnumerator (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root);
+
+ISL_MANIFEST_SECTION_PTR
+EISL_GetNextManifestSection (ISL_ITERATOR_PTR Iterator);
+
+ISL_STATUS
+EISL_RecycleManifestSectionEnumerator (ISL_ITERATOR_PTR Iterator);
+
+ISL_STATUS
+EISL_FindManifestAttribute (ISL_VERIFIED_SIGNATURE_ROOT_PTR Context,
+                            ISL_CONST_DATA Name,
+                            ISL_CONST_DATA_PTR Value);
+
+ISL_ITERATOR_PTR
+EISL_CreateManifestAttributeEnumerator (ISL_VERIFIED_SIGNATURE_ROOT_PTR Context);
+
+ISL_STATUS
+EISL_FindSignerInfoAttribute (ISL_VERIFIED_SIGNATURE_ROOT_PTR Context,
+                              ISL_CONST_DATA Name,
+                              ISL_CONST_DATA_PTR Value);
+
+ISL_ITERATOR_PTR
+EISL_CreateSignerInfoAttributeEnumerator (ISL_VERIFIED_SIGNATURE_ROOT_PTR Context);
+
+ISL_STATUS
+EISL_GetNextAttribute (ISL_ITERATOR_PTR Iterator,
+                       ISL_CONST_DATA_PTR Name,
+                       ISL_CONST_DATA_PTR Value);
+
+ISL_STATUS
+EISL_RecycleAttributeEnumerator (ISL_ITERATOR_PTR Iterator);
+
+ISL_STATUS
+EISL_FindSignatureAttribute (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root,
+                             ISL_CONST_DATA Name,
+                             ISL_CONST_DATA_PTR Value);
+
+ISL_ITERATOR_PTR
+EISL_CreateSignatureAttributeEnumerator (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root);
+
+ISL_STATUS
+EISL_GetNextSignatureAttribute (ISL_ITERATOR_PTR Iterator,
+                                ISL_CONST_DATA_PTR Name,
+                                ISL_CONST_DATA_PTR Value);
+
+ISL_STATUS
+EISL_RecycleSignatureAttributeEnumerator (ISL_ITERATOR_PTR Iterator);
+
+ISL_STATUS
+EISL_RecycleVerifiedSignatureRoot (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root);
+
+
+/* Certificate Chain Methods */
+
+const ISL_VERIFIED_CERTIFICATE_CHAIN_PTR
+EISL_CreateCertificateChainWithCredentialData (const ISL_CONST_DATA RootIssuer,
+                                               const ISL_CONST_DATA PublicKey,
+                                               const ISL_CONST_DATA CredentialsImage,
+                                               const ISL_CONST_DATA ModuleSearchPath);
+
+ISL_VERIFIED_CERTIFICATE_CHAIN_PTR
+EISL_CreateCertificateChainWithCredentialDataAndCertificate (const ISL_CONST_DATA Certificate,
+                                                             const ISL_CONST_DATA CredentialsImage,
+                                                             const ISL_CONST_DATA ModuleSearchPath);
+
+ISL_VERIFIED_CERTIFICATE_CHAIN_PTR
+EISL_CreateCertificateChain (ISL_CONST_DATA RootIssuer,
+                             ISL_CONST_DATA PublicKey,
+                             ISL_CONST_DATA Credential);
+
+ISL_VERIFIED_CERTIFICATE_CHAIN_PTR
+EISL_CreateCertificateChainWithCertificate (const ISL_CONST_DATA Certificate,
+                                            const ISL_CONST_DATA Credential);
+
+uint32
+EISL_CopyCertificateChain (ISL_VERIFIED_CERTIFICATE_CHAIN_PTR Verification,
+                           ISL_VERIFIED_CERTIFICATE_PTR Certs[],
+                           uint32 MaxCertificates);
+
+ISL_STATUS
+EISL_RecycleVerifiedCertificateChain (ISL_VERIFIED_CERTIFICATE_CHAIN_PTR Chain);
+
+
+/* Certificate Attribute Methods */
+
+ISL_STATUS
+EISL_FindCertificateAttribute (ISL_VERIFIED_CERTIFICATE_PTR Cert,
+                               ISL_CONST_DATA Name,
+                               ISL_CONST_DATA_PTR Value);
+
+ISL_ITERATOR_PTR
+EISL_CreateCertificateAttributeEnumerator (ISL_VERIFIED_CERTIFICATE_PTR Cert);
+
+ISL_STATUS
+EISL_GetNextCertificateAttribute (ISL_ITERATOR_PTR CertIterator,
+                                  ISL_CONST_DATA_PTR Name,
+                                  ISL_CONST_DATA_PTR Value);
+
+ISL_STATUS
+EISL_RecycleCertificateAttributeEnumerator (ISL_ITERATOR_PTR CertIterator);
+
+
+/* Manifest Section Object Methods */
+
+ISL_VERIFIED_SIGNATURE_ROOT_PTR
+EISL_GetManifestSignatureRoot (ISL_MANIFEST_SECTION_PTR Section);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyAndLoadModule (ISL_MANIFEST_SECTION_PTR Section);
+
+ISL_VERIFIED_MODULE_PTR
+EISL_VerifyLoadedModule (ISL_MANIFEST_SECTION_PTR Section);
+
+ISL_STATUS
+EISL_FindManifestSectionAttribute (ISL_MANIFEST_SECTION_PTR Section,
+                                   ISL_CONST_DATA Name,
+                                   ISL_CONST_DATA_PTR Value);
+
+ISL_ITERATOR_PTR
+EISL_CreateManifestSectionAttributeEnumerator (ISL_MANIFEST_SECTION_PTR Section);
+
+ISL_STATUS
+EISL_GetNextManifestSectionAttribute (ISL_ITERATOR_PTR Iterator,
+                                      ISL_CONST_DATA_PTR Name,
+                                      ISL_CONST_DATA_PTR Value);
+
+ISL_STATUS
+EISL_RecycleManifestSectionAttributeEnumerator (ISL_ITERATOR_PTR Iterator);
+
+ISL_MANIFEST_SECTION_PTR
+EISL_GetModuleManifestSection (ISL_VERIFIED_MODULE_PTR Module);
+
+
+/* Secure Linkage Services */
+
+ISL_FUNCTION_PTR
+EISL_LocateProcedureAddress (ISL_VERIFIED_MODULE_PTR Module,
+                             ISL_CONST_DATA Name);
+
+#ifdef MACOSX
+#define EISL_GetReturnAddress(Address) \
+{\
+    /* Platform specific code in here */
+}
+#endif
+
+ISL_STATUS
+EISL_CheckAddressWithinModule (ISL_VERIFIED_MODULE_PTR Verification,
+                               ISL_FUNCTION_PTR Address);
+
+ISL_STATUS
+EISL_CheckDataAddressWithinModule (ISL_VERIFIED_MODULE_PTR Verification,
+                                   const void *Address);
+
+void *
+EISL_GetLibHandle (ISL_VERIFIED_MODULE_PTR Verification);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EISL_H_ */
diff --git a/cdsa/cdsa/emmspi.h b/cdsa/cdsa/emmspi.h
new file mode 100644
index 00000000..60bc25a6
--- /dev/null
+++ b/cdsa/cdsa/emmspi.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      emmspi.h
+
+   Contains:  Service Provider Interface for Elective Module Managers
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _EMMSPI_H_
+#define _EMMSPI_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct cssm_state_funcs {
+    CSSM_RETURN (CSSMAPI *cssm_GetAttachFunctions)
+        (CSSM_MODULE_HANDLE hAddIn,
+         CSSM_SERVICE_MASK AddinType,
+         void **SPFunctions,
+         CSSM_GUID_PTR Guid,
+	 CSSM_BOOL *Serialized);
+    CSSM_RETURN (CSSMAPI *cssm_ReleaseAttachFunctions)
+        (CSSM_MODULE_HANDLE hAddIn);
+    CSSM_RETURN (CSSMAPI *cssm_GetAppMemoryFunctions)
+        (CSSM_MODULE_HANDLE hAddIn,
+         CSSM_UPCALLS_PTR UpcallTable);
+    CSSM_RETURN (CSSMAPI *cssm_IsFuncCallValid)
+        (CSSM_MODULE_HANDLE hAddin,
+         CSSM_PROC_ADDR SrcAddress,
+         CSSM_PROC_ADDR DestAddress,
+         CSSM_PRIVILEGE InPriv,
+         CSSM_PRIVILEGE *OutPriv,
+         CSSM_BITMASK Hints,
+         CSSM_BOOL *IsOK);
+    CSSM_RETURN (CSSMAPI *cssm_DeregisterManagerServices)
+        (const CSSM_GUID *GUID);
+    CSSM_RETURN (CSSMAPI *cssm_DeliverModuleManagerEvent)
+        (const CSSM_MANAGER_EVENT_NOTIFICATION *EventDescription);
+} CSSM_STATE_FUNCS, *CSSM_STATE_FUNCS_PTR;
+
+typedef struct cssm_manager_registration_info {
+    /* loading, unloading, dispatch table, and event notification */
+    CSSM_RETURN (CSSMAPI *Initialize)
+        (uint32 VerMajor,
+         uint32 VerMinor);
+    CSSM_RETURN (CSSMAPI *Terminate) (void);
+    CSSM_RETURN (CSSMAPI *RegisterDispatchTable)
+        (CSSM_STATE_FUNCS_PTR CssmStateCallTable);
+    CSSM_RETURN (CSSMAPI *DeregisterDispatchTable) (void);
+    CSSM_RETURN (CSSMAPI *EventNotifyManager)
+        (const CSSM_MANAGER_EVENT_NOTIFICATION *EventDescription);
+    CSSM_RETURN (CSSMAPI *RefreshFunctionTable)
+        (CSSM_FUNC_NAME_ADDR_PTR FuncNameAddrPtr,
+         uint32 NumOfFuncNameAddr);
+} CSSM_MANAGER_REGISTRATION_INFO, *CSSM_MANAGER_REGISTRATION_INFO_PTR;
+
+enum {
+	CSSM_HINT_NONE =			0,
+	CSSM_HINT_ADDRESS_APP = 	1 << 0,
+	CSSM_HINT_ADDRESS_SP =		1 << 1
+};
+
+CSSM_RETURN CSSMAPI
+ModuleManagerAuthenticate (CSSM_KEY_HIERARCHY KeyHierarchy,
+                           const CSSM_GUID *CssmGuid,
+                           const CSSM_GUID *AppGuid,
+                           CSSM_MANAGER_REGISTRATION_INFO_PTR FunctionTable);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EMMSPI_H_ */
diff --git a/cdsa/cdsa/emmtype.h b/cdsa/cdsa/emmtype.h
new file mode 100644
index 00000000..3c4271f4
--- /dev/null
+++ b/cdsa/cdsa/emmtype.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      emmtype.h
+
+   Contains:  Data Structures for Elective Module Managers
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _EMMTYPE_H_
+#define _EMMTYPE_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CSSM_HINT_CALLBACK (1)
+
+typedef uint32 CSSM_MANAGER_EVENT_TYPES;
+#define CSSM_MANAGER_SERVICE_REQUEST 1
+#define CSSM_MANAGER_REPLY 2
+
+typedef struct cssm_manager_event_notification {
+    CSSM_SERVICE_MASK DestinationModuleManagerType;
+    CSSM_SERVICE_MASK SourceModuleManagerType;
+    CSSM_MANAGER_EVENT_TYPES Event;
+    uint32 EventId;
+    CSSM_DATA EventData;
+} CSSM_MANAGER_EVENT_NOTIFICATION, *CSSM_MANAGER_EVENT_NOTIFICATION_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EMMTYPE_H_ */
diff --git a/cdsa/cdsa/mds.h b/cdsa/cdsa/mds.h
new file mode 100644
index 00000000..d9215c9d
--- /dev/null
+++ b/cdsa/cdsa/mds.h
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      mds.h
+
+   Contains:  Module Directory Services Data Types and API.
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _MDS_H_
+#define _MDS_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef CSSM_DL_HANDLE MDS_HANDLE;
+
+typedef CSSM_DL_DB_HANDLE MDS_DB_HANDLE;
+
+typedef struct mds_funcs {
+    CSSM_RETURN (CSSMAPI *DbOpen)
+        (MDS_HANDLE MdsHandle,
+         const char *DbName,
+         const CSSM_NET_ADDRESS *DbLocation,
+         CSSM_DB_ACCESS_TYPE AccessRequest,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const void *OpenParameters,
+         CSSM_DB_HANDLE *hMds);
+
+    CSSM_RETURN (CSSMAPI *DbClose)
+        (MDS_DB_HANDLE MdsDbHandle);
+
+    CSSM_RETURN (CSSMAPI *GetDbNames)
+        (MDS_HANDLE MdsHandle,
+         CSSM_NAME_LIST_PTR *NameList);
+
+    CSSM_RETURN (CSSMAPI *GetDbNameFromHandle)
+        (MDS_DB_HANDLE MdsDbHandle,
+         char **DbName);
+
+    CSSM_RETURN (CSSMAPI *FreeNameList)
+        (MDS_HANDLE MdsHandle,
+         CSSM_NAME_LIST_PTR NameList);
+
+    CSSM_RETURN (CSSMAPI *DataInsert)
+        (MDS_DB_HANDLE MdsDbHandle,
+         CSSM_DB_RECORDTYPE RecordType,
+         const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes,
+         const CSSM_DATA *Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+
+    CSSM_RETURN (CSSMAPI *DataDelete)
+        (MDS_DB_HANDLE MdsDbHandle,
+         const CSSM_DB_UNIQUE_RECORD *UniqueRecordIdentifier);
+
+    CSSM_RETURN (CSSMAPI *DataModify)
+        (MDS_DB_HANDLE MdsDbHandle,
+         CSSM_DB_RECORDTYPE RecordType,
+         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecordIdentifier,
+         const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified,
+         const CSSM_DATA *DataToBeModified,
+         CSSM_DB_MODIFY_MODE ModifyMode);
+
+    CSSM_RETURN (CSSMAPI *DataGetFirst)
+        (MDS_DB_HANDLE MdsDbHandle,
+         const CSSM_QUERY *Query,
+         CSSM_HANDLE_PTR ResultsHandle,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+
+    CSSM_RETURN (CSSMAPI *DataGetNext)
+        (MDS_DB_HANDLE MdsDbHandle,
+         CSSM_HANDLE ResultsHandle,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId);
+
+    CSSM_RETURN (CSSMAPI *DataAbortQuery)
+        (MDS_DB_HANDLE MdsDbHandle,
+         CSSM_HANDLE ResultsHandle);
+
+    CSSM_RETURN (CSSMAPI *DataGetFromUniqueRecordId)
+        (MDS_DB_HANDLE MdsDbHandle,
+         const CSSM_DB_UNIQUE_RECORD *UniqueRecord,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data);
+
+    CSSM_RETURN (CSSMAPI *FreeUniqueRecord)
+        (MDS_DB_HANDLE MdsDbHandle,
+         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecord);
+
+    CSSM_RETURN (CSSMAPI *CreateRelation)
+        (MDS_DB_HANDLE MdsDbHandle,
+         CSSM_DB_RECORDTYPE RelationID,
+         const char *RelationName,
+         uint32 NumberOfAttributes,
+         const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
+         uint32 NumberOfIndexes,
+         const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo);
+
+    CSSM_RETURN (CSSMAPI *DestroyRelation)
+        (MDS_DB_HANDLE MdsDbHandle,
+         CSSM_DB_RECORDTYPE RelationID);
+} MDS_FUNCS, *MDS_FUNCS_PTR;
+
+
+/* MDS Context APIs */
+
+CSSM_RETURN CSSMAPI
+MDS_Initialize (const CSSM_GUID *pCallerGuid,
+                const CSSM_MEMORY_FUNCS *pMemoryFunctions,
+                MDS_FUNCS_PTR pDlFunctions,
+                MDS_HANDLE *hMds);
+
+CSSM_RETURN CSSMAPI
+MDS_Terminate (MDS_HANDLE MdsHandle);
+
+CSSM_RETURN CSSMAPI
+MDS_Install (MDS_HANDLE MdsHandle);
+
+CSSM_RETURN CSSMAPI
+MDS_Uninstall (MDS_HANDLE MdsHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MDS_H_ */
diff --git a/cdsa/cdsa/mds_schema.h b/cdsa/cdsa/mds_schema.h
new file mode 100644
index 00000000..2c151180
--- /dev/null
+++ b/cdsa/cdsa/mds_schema.h
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      mds_schema.h
+
+   Contains:  Module Directory Services Schema for CSSM.
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _MDS_SCHEMA_H_
+#define _MDS_SCHEMA_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Names of the databases supported by MDS. */
+#define MDS_OBJECT_DIRECTORY_NAME						"MDS Object Directory"
+#define MDS_CDSA_DIRECTORY_NAME							"MDS CDSA Directory"
+
+/* MDS predefined values for a 16K name space */
+#define CSSM_DB_RELATIONID_MDS_START					(0x40000000)
+#define CSSM_DB_RELATIONID_MDS_END						(0x40004000)
+
+#define MDS_OBJECT_RECORDTYPE							(CSSM_DB_RELATIONID_MDS_START)
+
+#define MDS_CDSA_SCHEMA_START							(MDS_OBJECT_RECORDTYPE)
+#define MDS_CDSADIR_CSSM_RECORDTYPE						(MDS_CDSA_SCHEMA_START + 1)
+#define MDS_CDSADIR_KRMM_RECORDTYPE						(MDS_CDSA_SCHEMA_START + 2)
+#define MDS_CDSADIR_EMM_RECORDTYPE						(MDS_CDSA_SCHEMA_START + 3)
+#define MDS_CDSADIR_COMMON_RECORDTYPE					(MDS_CDSA_SCHEMA_START + 4)
+#define MDS_CDSADIR_CSP_PRIMARY_RECORDTYPE				(MDS_CDSA_SCHEMA_START + 5)
+#define MDS_CDSADIR_CSP_CAPABILITY_RECORDTYPE			(MDS_CDSA_SCHEMA_START + 6)
+#define MDS_CDSADIR_CSP_ENCAPSULATED_PRODUCT_RECORDTYPE	(MDS_CDSA_SCHEMA_START + 7)
+#define MDS_CDSADIR_CSP_SC_INFO_RECORDTYPE				(MDS_CDSA_SCHEMA_START + 8)
+#define MDS_CDSADIR_DL_PRIMARY_RECORDTYPE				(MDS_CDSA_SCHEMA_START + 9)
+#define MDS_CDSADIR_DL_ENCAPSULATED_PRODUCT_RECORDTYPE	(MDS_CDSA_SCHEMA_START + 10)
+#define MDS_CDSADIR_CL_PRIMARY_RECORDTYPE				(MDS_CDSA_SCHEMA_START + 11)
+#define MDS_CDSADIR_CL_ENCAPSULATED_PRODUCT_RECORDTYPE	(MDS_CDSA_SCHEMA_START + 12)
+#define MDS_CDSADIR_TP_PRIMARY_RECORDTYPE				(MDS_CDSA_SCHEMA_START + 13)
+#define MDS_CDSADIR_TP_OIDS_RECORDTYPE					(MDS_CDSA_SCHEMA_START + 14)
+#define MDS_CDSADIR_TP_ENCAPSULATED_PRODUCT_RECORDTYPE	(MDS_CDSA_SCHEMA_START + 15)
+#define MDS_CDSADIR_EMM_PRIMARY_RECORDTYPE				(MDS_CDSA_SCHEMA_START + 16)
+#define MDS_CDSADIR_AC_PRIMARY_RECORDTYPE				(MDS_CDSA_SCHEMA_START + 17)
+#define MDS_CDSADIR_KR_PRIMARY_RECORDTYPE				(MDS_CDSA_SCHEMA_START + 18)
+#define MDS_CDSADIR_MDS_SCHEMA_RELATIONS				(MDS_CDSA_SCHEMA_START + 19)
+#define MDS_CDSADIR_MDS_SCHEMA_ATTRIBUTES				(MDS_CDSA_SCHEMA_START + 20)
+#define MDS_CDSADIR_MDS_SCHEMA_INDEXES					(MDS_CDSA_SCHEMA_START + 21)
+
+/* MDS predefined values for a 16K name space */
+#define CSSM_DB_ATTRIBUTE_MDS_START				(0x40000000)
+#define CSSM_DB_ATTRIBUTE_MDS_END				(0x40004000)
+#define MDS_CDSAATTR_MODULE_ID					(CSSM_DB_ATTRIBUTE_MDS_START + 1)
+#define MDS_CDSAATTR_MANIFEST					(CSSM_DB_ATTRIBUTE_MDS_START + 2)
+#define MDS_CDSAATTR_MODULE_NAME				(CSSM_DB_ATTRIBUTE_MDS_START + 3)
+#define MDS_CDSAATTR_PATH						(CSSM_DB_ATTRIBUTE_MDS_START + 4)
+#define MDS_CDSAATTR_CDSAVERSION				(CSSM_DB_ATTRIBUTE_MDS_START + 5)
+#define MDS_CDSAATTR_VENDOR						(CSSM_DB_ATTRIBUTE_MDS_START + 6)
+#define MDS_CDSAATTR_DESC						(CSSM_DB_ATTRIBUTE_MDS_START + 8)
+#define MDS_CDSAATTR_INTERFACE_GUID				(CSSM_DB_ATTRIBUTE_MDS_START + 9)
+#define MDS_CDSAATTR_POLICY_STMT				(CSSM_DB_ATTRIBUTE_MDS_START + 10)
+#define MDS_CDSAATTR_EMMSPECVERSION				(CSSM_DB_ATTRIBUTE_MDS_START + 11)
+#define MDS_CDSAATTR_EMM_VERSION				(CSSM_DB_ATTRIBUTE_MDS_START + 12)
+#define MDS_CDSAATTR_EMM_VENDOR					(CSSM_DB_ATTRIBUTE_MDS_START + 13)
+#define MDS_CDSAATTR_EMM_TYPE					(CSSM_DB_ATTRIBUTE_MDS_START + 14)
+#define MDS_CDSAATTR_SSID						(CSSM_DB_ATTRIBUTE_MDS_START + 15)
+#define MDS_CDSAATTR_SERVICE_TYPE				(CSSM_DB_ATTRIBUTE_MDS_START + 16)
+#define MDS_CDSAATTR_NATIVE_SERVICES			(CSSM_DB_ATTRIBUTE_MDS_START + 17)
+#define MDS_CDSAATTR_DYNAMIC_FLAG				(CSSM_DB_ATTRIBUTE_MDS_START + 18)
+#define MDS_CDSAATTR_MULTITHREAD_FLAG			(CSSM_DB_ATTRIBUTE_MDS_START + 19)
+#define MDS_CDSAATTR_SERVICE_MASK				(CSSM_DB_ATTRIBUTE_MDS_START + 20)
+#define MDS_CDSAATTR_CSP_TYPE					(CSSM_DB_ATTRIBUTE_MDS_START + 21)
+#define MDS_CDSAATTR_CSP_FLAGS					(CSSM_DB_ATTRIBUTE_MDS_START + 22)
+#define MDS_CDSAATTR_CSP_CUSTOMFLAGS			(CSSM_DB_ATTRIBUTE_MDS_START + 23)
+#define MDS_CDSAATTR_USEE_TAGS					(CSSM_DB_ATTRIBUTE_MDS_START + 24)
+#define MDS_CDSAATTR_CONTEXT_TYPE				(CSSM_DB_ATTRIBUTE_MDS_START + 25)
+#define MDS_CDSAATTR_ALG_TYPE					(CSSM_DB_ATTRIBUTE_MDS_START + 26)
+#define MDS_CDSAATTR_GROUP_ID					(CSSM_DB_ATTRIBUTE_MDS_START + 27)
+#define MDS_CDSAATTR_ATTRIBUTE_TYPE				(CSSM_DB_ATTRIBUTE_MDS_START + 28)
+#define MDS_CDSAATTR_ATTRIBUTE_VALUE			(CSSM_DB_ATTRIBUTE_MDS_START + 29)
+#define MDS_CDSAATTR_PRODUCT_DESC				(CSSM_DB_ATTRIBUTE_MDS_START + 30)
+#define MDS_CDSAATTR_PRODUCT_VENDOR				(CSSM_DB_ATTRIBUTE_MDS_START + 31)
+#define MDS_CDSAATTR_PRODUCT_VERSION			(CSSM_DB_ATTRIBUTE_MDS_START + 32)
+#define MDS_CDSAATTR_PRODUCT_FLAGS				(CSSM_DB_ATTRIBUTE_MDS_START + 33)
+#define MDS_CDSAATTR_PRODUCT_CUSTOMFLAGS		(CSSM_DB_ATTRIBUTE_MDS_START + 34)
+#define MDS_CDSAATTR_STANDARD_DESC				(CSSM_DB_ATTRIBUTE_MDS_START + 35)
+#define MDS_CDSAATTR_STANDARD_VERSION			(CSSM_DB_ATTRIBUTE_MDS_START + 36)
+#define MDS_CDSAATTR_READER_DESC				(CSSM_DB_ATTRIBUTE_MDS_START + 37)
+#define MDS_CDSAATTR_READER_VENDOR				(CSSM_DB_ATTRIBUTE_MDS_START + 38)
+#define MDS_CDSAATTR_READER_VERSION				(CSSM_DB_ATTRIBUTE_MDS_START + 39)
+#define MDS_CDSAATTR_READER_FWVERSION			(CSSM_DB_ATTRIBUTE_MDS_START + 40)
+#define MDS_CDSAATTR_READER_FLAGS				(CSSM_DB_ATTRIBUTE_MDS_START + 41)
+#define MDS_CDSAATTR_READER_CUSTOMFLAGS			(CSSM_DB_ATTRIBUTE_MDS_START + 42)
+#define MDS_CDSAATTR_READER_SERIALNUMBER		(CSSM_DB_ATTRIBUTE_MDS_START + 43)
+#define MDS_CDSAATTR_SC_DESC					(CSSM_DB_ATTRIBUTE_MDS_START + 44)
+#define MDS_CDSAATTR_SC_VENDOR					(CSSM_DB_ATTRIBUTE_MDS_START + 45)
+#define MDS_CDSAATTR_SC_VERSION					(CSSM_DB_ATTRIBUTE_MDS_START + 46)
+#define MDS_CDSAATTR_SC_FWVERSION				(CSSM_DB_ATTRIBUTE_MDS_START + 47)
+#define MDS_CDSAATTR_SC_FLAGS					(CSSM_DB_ATTRIBUTE_MDS_START + 48)
+#define MDS_CDSAATTR_SC_CUSTOMFLAGS				(CSSM_DB_ATTRIBUTE_MDS_START + 49)
+#define MDS_CDSAATTR_SC_SERIALNUMBER			(CSSM_DB_ATTRIBUTE_MDS_START + 50)
+#define MDS_CDSAATTR_DL_TYPE					(CSSM_DB_ATTRIBUTE_MDS_START + 51)
+#define MDS_CDSAATTR_QUERY_LIMITS				(CSSM_DB_ATTRIBUTE_MDS_START + 52)
+#define MDS_CDSAATTR_CONJUNCTIVE_OPS			(CSSM_DB_ATTRIBUTE_MDS_START + 53)
+#define MDS_CDSAATTR_RELATIONAL_OPS				(CSSM_DB_ATTRIBUTE_MDS_START + 54)
+#define MDS_CDSAATTR_PROTOCOL					(CSSM_DB_ATTRIBUTE_MDS_START + 55)
+#define MDS_CDSAATTR_CERT_TYPEFORMAT			(CSSM_DB_ATTRIBUTE_MDS_START + 56)
+#define MDS_CDSAATTR_CRL_TYPEFORMAT				(CSSM_DB_ATTRIBUTE_MDS_START + 57)
+#define MDS_CDSAATTR_CERT_FIELDNAMES			(CSSM_DB_ATTRIBUTE_MDS_START + 58)
+#define MDS_CDSAATTR_BUNDLE_TYPEFORMAT			(CSSM_DB_ATTRIBUTE_MDS_START + 59)
+#define MDS_CDSAATTR_CERT_CLASSNAME				(CSSM_DB_ATTRIBUTE_MDS_START + 60)
+#define MDS_CDSAATTR_ROOTCERT					(CSSM_DB_ATTRIBUTE_MDS_START + 61)
+#define MDS_CDSAATTR_ROOTCERT_TYPEFORMAT		(CSSM_DB_ATTRIBUTE_MDS_START + 62)
+#define MDS_CDSAATTR_VALUE						(CSSM_DB_ATTRIBUTE_MDS_START + 63)
+#define MDS_CDSAATTR_REQCREDENTIALS				(CSSM_DB_ATTRIBUTE_MDS_START + 64)
+#define MDS_CDSAATTR_SAMPLETYPES				(CSSM_DB_ATTRIBUTE_MDS_START + 65)
+#define MDS_CDSAATTR_ACLSUBJECTTYPES			(CSSM_DB_ATTRIBUTE_MDS_START + 66)
+#define MDS_CDSAATTR_AUTHTAGS					(CSSM_DB_ATTRIBUTE_MDS_START + 67)
+#define MDS_CDSAATTR_USEETAG					(CSSM_DB_ATTRIBUTE_MDS_START + 68)
+#define MDS_CDSAATTR_RETRIEVALMODE				(CSSM_DB_ATTRIBUTE_MDS_START + 69)
+#define MDS_CDSAATTR_OID						(CSSM_DB_ATTRIBUTE_MDS_START + 70)
+#define MDS_CDSAATTR_XLATIONTYPEFORMAT			(CSSM_DB_ATTRIBUTE_MDS_START + 71)
+#define MDS_CDSAATTR_DEFAULT_TEMPLATE_TYPE		(CSSM_DB_ATTRIBUTE_MDS_START + 72)
+#define MDS_CDSAATTR_TEMPLATE_FIELD_NAMES		(CSSM_DB_ATTRIBUTE_MDS_START + 73)
+#define MDS_CDSAATTR_AUTHORITY_REQUEST_TYPE		(CSSM_DB_ATTRIBUTE_MDS_START + 74)
+
+/* Meta-data names for the MDS Object directory relation */
+#define MDS_OBJECT_NUM_RELATIONS							(1)
+#define MDS_OBJECT_NUM_ATTRIBUTES							(4)
+/* Defined constant for # of relations in the CDSA directory */
+#define MDS_CDSADIR_NUM_RELATIONS							(19)
+/* Meta-data names for the MDS CSSM relation */
+#define MDS_CDSADIR_CSSM_NUM_ATTRIBUTES						(4)
+/* Meta-data names for the MDS EMM relation */
+#define MDS_CDSADIR_EMM_NUM_ATTRIBUTES						(11)
+/* Meta-data names for the MDS Common relation */
+#define MDS_CDSADIR_COMMON_NUM_ATTRIBUTES					(9)
+/* Meta-data names for the MDS CSP Primary relation */
+#define MDS_CDSADIR_CSP_PRIMARY_NUM_ATTRIBUTES				(13)
+/* Meta-data names for the MDS CSP Capabilities relation */
+#define MDS_CDSADIR_CSP_CAPABILITY_NUM_ATTRIBUTES			(9)
+/* Meta-data names for the MDS CSP Encapsulated Product relation */
+#define MDS_CDSADIR_CSP_ENCAPSULATED_PRODUCT_NUM_ATTRIBUTES	(16)
+/* Meta-data names for the MDS CSP SmartcardInfo relation */
+#define MDS_CDSADIR_CSP_SC_INFO_NUM_ATTRIBUTES				(9)
+/* Meta-data names for the MDS DL Primary relation */
+#define MDS_CDSADIR_DL_PRIMARY_NUM_ATTRIBUTES				(13)
+/* Meta-data names for the MDS DL Encapsulated Product relation */
+#define MDS_CDSADIR_DL_ENCAPSULATED_PRODUCT_NUM_ATTRIBUTES	(10)
+/* Meta-data names for the MDS CL Primary relation */
+#define MDS_CDSADIR_CL_PRIMARY_NUM_ATTRIBUTES				(13)
+/* Meta-data names for the MDS CL Encapsulated Product relation */
+#define MDS_CDSADIR_CL_ENCAPSULATED_PRODUCT_NUM_ATTRIBUTES	(8)
+/* Meta-data names for the MDS TP Primary relation */
+#define MDS_CDSADIR_TP_PRIMARY_NUM_ATTRIBUTES				(10)
+/* Meta-data names for the MDS TP Policy-OIDS relation */
+#define MDS_CDSADIR_TP_OIDS_NUM_ATTRIBUTES					(4)
+/* Meta-data names for the MDS TP Encapsulated Product relation */
+#define MDS_CDSADIR_TP_ENCAPSULATED_PRODUCT_NUM_ATTRIBUTES	(14)
+/* Meta-data names for MDS EMM Service Provider Primary relation */
+#define MDS_CDSADIR_EMM_PRIMARY_NUM_ATTRIBUTES				(9)
+/* Meta-data names for MDS AC Primary relation */
+#define MDS_CDSADIR_AC_PRIMARY_NUM_ATTRIBUTES				(6)
+/* Meta-data names for MDS Schema relation */
+#define MDS_CDSADIR_SCHEMA_RELATONS_NUM_ATTRIBUTES			(2)
+#define MDS_CDSADIR_SCHEMA_ATTRIBUTES_NUM_ATTRIBUTES		(6)
+#define MDS_CDSADIR_SCHEMA_INDEXES_NUM_ATTRIBUTES			(5)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MDS_SCHEMA_H_ */
diff --git a/cdsa/cdsa/oidsalg.h b/cdsa/cdsa/oidsalg.h
new file mode 100644
index 00000000..48f72741
--- /dev/null
+++ b/cdsa/cdsa/oidsalg.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      oidsalg.h
+
+   Contains:  OIDs defining crypto algorithms
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef	_OIDS_ALG_H_
+#define _OIDS_ALG_H_
+
+#include <Security/cssmtype.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern const CSSM_OID
+	CSSMOID_MD2,
+	CSSMOID_MD4,
+	CSSMOID_MD5,
+	CSSMOID_RSA,
+	CSSMOID_MD2WithRSA,
+	CSSMOID_MD4WithRSA,
+	CSSMOID_MD5WithRSA,
+	CSSMOID_SHA1WithRSA,
+	CSSMOID_DH,
+	CSSMOID_DSA,
+	CSSMOID_SHA1WithDSA,
+	CSSMOID_APPLE_ISIGN,
+	CSSMOID_APPLE_X509_BASIC,
+	CSSMOID_APPLE_TP_SSL,
+	CSSMOID_APPLE_FEE,
+	CSSMOID_APPLE_ASC,
+	CSSMOID_APPLE_FEE_MD5,
+	CSSMOID_APPLE_FEE_SHA1,
+	CSSMOID_APPLE_FEED,
+	CSSMOID_APPLE_FEEDEXP,
+	CSSMOID_APPLE_ECDSA;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _OIDS_ALG_H_ */
diff --git a/cdsa/cdsa/oidsattr.h b/cdsa/cdsa/oidsattr.h
new file mode 100644
index 00000000..db04cb35
--- /dev/null
+++ b/cdsa/cdsa/oidsattr.h
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      oidsattr.h
+
+   Contains:  Cert/CRL related OIDs.
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef	_CDSA_OIDSATTR_H_
+#define _CDSA_OIDSATTR_H_
+
+#include <Security/cssmtype.h>
+#include <Security/oidsbase.h>
+
+/* 
+ * Directory name component identifiers.
+ */
+extern const CSSM_OID
+	CSSMOID_ObjectClass,
+	CSSMOID_AliasedEntryName,
+	CSSMOID_KnowledgeInformation,
+	CSSMOID_CommonName,
+	CSSMOID_Surname,
+	CSSMOID_SerialNumber,
+	CSSMOID_CountryName,
+	CSSMOID_LocalityName,
+	CSSMOID_StateProvinceName,
+	CSSMOID_CollectiveStateProvinceName,
+	CSSMOID_StreetAddress,
+	CSSMOID_CollectiveStreetAddress,
+	CSSMOID_OrganizationName,
+	CSSMOID_CollectiveOrganizationName,
+	CSSMOID_OrganizationalUnitName,
+	CSSMOID_CollectiveOrganizationalUnitName,
+	CSSMOID_Title,
+	CSSMOID_Description,
+	CSSMOID_SearchGuide,
+	CSSMOID_BusinessCategory,
+	CSSMOID_PostalAddress,
+	CSSMOID_CollectivePostalAddress,
+	CSSMOID_PostalCode,
+	CSSMOID_CollectivePostalCode,
+	CSSMOID_PostOfficeBox,
+	CSSMOID_CollectivePostOfficeBox,
+	CSSMOID_PhysicalDeliveryOfficeName, 
+	CSSMOID_CollectivePhysicalDeliveryOfficeName,
+	CSSMOID_TelephoneNumber,
+	CSSMOID_CollectiveTelephoneNumber,  
+	CSSMOID_TelexNumber,
+	CSSMOID_CollectiveTelexNumber,
+	CSSMOID_TelexTerminalIdentifier,
+	CSSMOID_CollectiveTelexTerminalIdentifier,
+	CSSMOID_FacsimileTelephoneNumber,
+	CSSMOID_CollectiveFacsimileTelephoneNumber,
+	CSSMOID_X_121Address,
+	CSSMOID_InternationalISDNNumber,
+	CSSMOID_CollectiveInternationalISDNNumber,
+	CSSMOID_RegisteredAddress,
+	CSSMOID_DestinationIndicator,
+	CSSMOID_PreferredDeliveryMethod,
+	CSSMOID_PresentationAddress,
+	CSSMOID_SupportedApplicationContext,
+	CSSMOID_Member,
+	CSSMOID_Owner,
+	CSSMOID_RoleOccupant,
+	CSSMOID_SeeAlso,
+	CSSMOID_UserPassword,
+	CSSMOID_UserCertificate,
+	CSSMOID_CACertificate,
+	CSSMOID_AuthorityRevocationList,
+	CSSMOID_CertificateRevocationList,
+	CSSMOID_CrossCertificatePair,
+	CSSMOID_Name,
+	CSSMOID_GivenName,
+	CSSMOID_Initials,
+	CSSMOID_GenerationQualifier,
+	CSSMOID_UniqueIdentifier,
+	CSSMOID_DNQualifier,
+	CSSMOID_EnhancedSearchGuide,
+	CSSMOID_ProtocolInformation,
+	CSSMOID_DistinguishedName,
+	CSSMOID_UniqueMember,
+	CSSMOID_HouseIdentifier;
+	
+/* PKCS 9 */
+extern const CSSM_OID
+	CSSMOID_EmailAddress,
+	CSSMOID_UnstructuredName,
+	CSSMOID_ContentType,
+	CSSMOID_MessageDigest,
+	CSSMOID_SigningTime,
+	CSSMOID_CounterSignature,
+	CSSMOID_ChallengePassword,
+	CSSMOID_UnstructuredAddress,
+	CSSMOID_ExtendedCertificateAttributes;
+
+/* PKIX */
+extern const CSSM_OID
+	CSSMOID_QT_CPS,
+	CSSMOID_QT_UNOTICE;
+
+#endif	/* _CDSA_OIDSATTR_H_*/
diff --git a/cdsa/cdsa/oidsbase.h b/cdsa/cdsa/oidsbase.h
new file mode 100644
index 00000000..fc52dfa1
--- /dev/null
+++ b/cdsa/cdsa/oidsbase.h
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      oidsbase.h
+
+   Contains:  Basic Object Identifier Macros and Data Types.
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _OIDSBASE_H_
+#define _OIDSBASE_H_  1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Intel CSSM */
+
+#define INTEL 96, 134, 72, 1, 134, 248, 77
+#define INTEL_LENGTH 7
+
+#define INTEL_CDSASECURITY INTEL, 2
+#define INTEL_CDSASECURITY_LENGTH (INTEL_LENGTH + 1)
+
+#define INTEL_SEC_FORMATS INTEL_CDSASECURITY, 1
+#define INTEL_SEC_FORMATS_LENGTH (INTEL_CDSASECURITY_LENGTH + 1)
+
+#define INTEL_SEC_ALGS INTEL_CDSASECURITY, 2, 5
+#define INTEL_SEC_ALGS_LENGTH (INTEL_CDSASECURITY_LENGTH + 2)
+
+#define INTEL_SEC_OBJECT_BUNDLE INTEL_SEC_FORMATS, 4
+#define INTEL_SEC_OBJECT_BUNDLE_LENGTH (INTEL_SEC_FORMATS_LENGTH + 1)
+
+#define INTEL_CERT_AND_PRIVATE_KEY_2_0 INTEL_SEC_OBJECT_BUNDLE, 1
+#define INTEL_CERT_AND_PRIVATE_KEY_2_0_LENGTH (INTEL_SEC_OBJECT_BUNDLE_LENGTH + 1)
+
+/* Suffix specifying format or representation of a field value */
+/* Note that if a format suffix is not specified, a flat data
+representation is implied */
+#define INTEL_X509_C_DATATYPE 1
+#define INTEL_X509_LDAPSTRING_DATATYPE 2
+
+#define OID_ISO_CCITT_DIR_SERVICE 			85
+#define OID_DS              				OID_ISO_CCITT_DIR_SERVICE 
+#define OID_DS_LENGTH       				1
+#define OID_ATTR_TYPE        				OID_DS, 4                
+#define OID_ATTR_TYPE_LENGTH 				OID_DS_LENGTH + 1
+#define OID_EXTENSION        				OID_DS, 29          
+#define OID_EXTENSION_LENGTH 				OID_DS_LENGTH + 1
+#define OID_ISO_STANDARD      	 			40
+#define OID_ISO_MEMBER         				42                     
+#define OID_US                 				OID_ISO_MEMBER, 134, 72
+
+#define OID_ISO_IDENTIFIED_ORG 				43
+#define OID_OSINET             				OID_ISO_IDENTIFIED_ORG, 4
+#define OID_GOSIP              				OID_ISO_IDENTIFIED_ORG, 5
+#define OID_DOD                				OID_ISO_IDENTIFIED_ORG, 6
+#define OID_OIW                				OID_ISO_IDENTIFIED_ORG, 14 
+
+/* From the PKCS Standards */
+#define OID_ISO_MEMBER_LENGTH 				1
+#define OID_US_LENGTH         				OID_ISO_MEMBER_LENGTH + 2
+#define OID_RSA               				OID_US, 134, 247, 13
+#define OID_RSA_LENGTH        				OID_US_LENGTH + 3
+#define OID_RSA_HASH          				OID_RSA, 2
+#define OID_RSA_HASH_LENGTH   				OID_RSA_LENGTH + 1
+#define OID_RSA_ENCRYPT       				OID_RSA, 3
+#define OID_RSA_ENCRYPT_LENGTH	 			OID_RSA_LENGTH + 1
+#define OID_PKCS             				OID_RSA, 1
+#define OID_PKCS_LENGTH       				OID_RSA_LENGTH +1
+#define OID_PKCS_1          				OID_PKCS, 1
+#define OID_PKCS_1_LENGTH   				OID_PKCS_LENGTH +1
+#define OID_PKCS_2          				OID_PKCS, 2
+#define OID_PKCS_3          				OID_PKCS, 3
+#define OID_PKCS_3_LENGTH   				OID_PKCS_LENGTH +1
+#define OID_PKCS_4          				OID_PKCS, 4
+#define OID_PKCS_5          				OID_PKCS, 5
+#define OID_PKCS_5_LENGTH   				OID_PKCS_LENGTH +1
+#define OID_PKCS_6          				OID_PKCS, 6
+#define OID_PKCS_7          				OID_PKCS, 7
+#define OID_PKCS_7_LENGTH   				OID_PKCS_LENGTH +1
+#define OID_PKCS_8          				OID_PKCS, 8
+#define OID_PKCS_9          				OID_PKCS, 9
+#define OID_PKCS_9_LENGTH   				OID_PKCS_LENGTH +1
+#define OID_PKCS_10         				OID_PKCS, 10
+
+#define OID_PKIX							OID_DOD, 1, 5, 5, 7
+#define OID_PKIX_LENGTH						6
+#define OID_QT								OID_PKIX, 2
+#define OID_QT_LENGTH						OID_PKIX_LENGTH + 1
+
+#define OID_OIW_SECSIG        				OID_OIW, 3
+#define OID_OIW_LENGTH       				2
+#define OID_OIW_SECSIG_LENGTH 				OID_OIW_LENGTH +1
+
+#define OID_OIW_ALGORITHM    				OID_OIW_SECSIG, 2
+#define OID_OIW_ALGORITHM_LENGTH   			OID_OIW_SECSIG_LENGTH +1
+
+/*
+ * Apple-specific OID bases
+ */
+ 
+/* 
+ * apple OBJECT IDENTIFIER ::=
+ * 	{ iso(1) member-body(2) US(840) 113635 }
+ * 
+ * BER = 06 06 2A 86 48 86 F7 63
+ */
+#define APPLE_OID				OID_US, 0x86, 0xf7, 0x63
+#define APPLE_OID_LENGTH		OID_US_LENGTH + 3
+
+/* appleDataSecurity OBJECT IDENTIFIER ::=
+ *		{ apple 100 }
+ *      { 1 2 840 113635 100 }
+ *
+ * BER = 06 07 2A 86 48 86 F7 63 64
+ */
+#define APPLE_ADS_OID			APPLE_OID, 0x64
+#define APPLE_ADS_OID_LENGTH	APPLE_OID_LENGTH + 1
+
+/*
+ * appleTrustPolicy OBJECT IDENTIFIER ::=
+ *		{ appleDataSecurity 1 }
+ *      { 1 2 840 113635 100 1 }
+ *
+ * BER = 06 08 2A 86 48 86 F7 63 64 01 
+ */ 
+#define APPLE_TP_OID			APPLE_ADS_OID, 1
+#define APPLE_TP_OID_LENGTH		APPLE_ADS_OID_LENGTH + 1
+
+/*
+ *	appleSecurityAlgorithm OBJECT IDENTIFIER ::=
+ *		{ appleDataSecurity 2 }
+ *      { 1 2 840 113635 100 2 }
+ *
+ * BER = 06 08 2A 86 48 86 F7 63 64 02
+ */
+#define APPLE_ALG_OID			APPLE_ADS_OID, 2
+#define APPLE_ALG_OID_LENGTH	APPLE_ADS_OID_LENGTH + 1
+
+/*
+ * Netscape extensions. 
+ */
+/*
+ *  netscape-cert-extension OBJECT IDENTIFIER ::=
+ * 		{ 2 16 840 1 113730 1 }
+ *
+ *	BER = 06 08 60 86 48 01 86 F8 42 01
+ */
+#define NETSCAPE_CERT_EXTEN		0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01
+#define NETSCAPE_CERT_EXTEN_LENGTH	8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OIDSBASE_H_ */
diff --git a/cdsa/cdsa/oidscert.h b/cdsa/cdsa/oidscert.h
new file mode 100644
index 00000000..b9bd47a6
--- /dev/null
+++ b/cdsa/cdsa/oidscert.h
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+
+/*
+ File:      oidscert.h
+
+ Contains:  Object Identifiers for X509 Certificate Library
+
+ Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _OIDSCERT_H_
+#define _OIDSCERT_H_  1
+
+#include <Security/cssmconfig.h>
+#include <Security/cssmtype.h>
+#include <Security/oidsbase.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define INTEL_X509V3_CERT_R08 INTEL_SEC_FORMATS, 1, 1
+#define INTEL_X509V3_CERT_R08_LENGTH INTEL_SEC_FORMATS_LENGTH + 2
+
+/* Prefix for defining Certificate Extension field OIDs */
+#define INTEL_X509V3_CERT_PRIVATE_EXTENSIONS INTEL_X509V3_CERT_R08, 50
+#define INTEL_X509V3_CERT_PRIVATE_EXTENSIONS_LENGTH INTEL_X509V3_CERT_R08_LENGTH + 1
+
+/* Prefix for defining signature field OIDs */
+#define INTEL_X509V3_SIGN_R08 INTEL_SEC_FORMATS, 3, 2
+#define INTEL_X509V3_SIGN_R08_LENGTH INTEL_SEC_FORMATS_LENGTH + 2
+
+/* Suffix specifying format or representation of a field value                                      */
+/* Note that if a format suffix is not specified, a flat data representation is implied. */
+
+#define INTEL_X509_C_DATATYPE					1
+#define INTEL_X509_LDAPSTRING_DATATYPE		2
+
+/* Certificate OIDS */
+extern const CSSM_OID
+
+	CSSMOID_X509V3SignedCertificate,
+	CSSMOID_X509V3SignedCertificateCStruct,
+	CSSMOID_X509V3Certificate,
+	CSSMOID_X509V3CertificateCStruct,
+	CSSMOID_X509V1Version,
+	CSSMOID_X509V1SerialNumber,
+	CSSMOID_X509V1IssuerName,
+	CSSMOID_X509V1IssuerNameCStruct,
+	CSSMOID_X509V1IssuerNameLDAP,
+	CSSMOID_X509V1ValidityNotBefore,
+	CSSMOID_X509V1ValidityNotAfter,
+	CSSMOID_X509V1SubjectName,
+	CSSMOID_X509V1SubjectNameCStruct,
+	CSSMOID_X509V1SubjectNameLDAP,
+	CSSMOID_CSSMKeyStruct,
+	CSSMOID_X509V1SubjectPublicKeyCStruct,
+	CSSMOID_X509V1SubjectPublicKeyAlgorithm,
+	CSSMOID_X509V1SubjectPublicKeyAlgorithmParameters,
+	CSSMOID_X509V1SubjectPublicKey,
+	CSSMOID_X509V1CertificateIssuerUniqueId,
+	CSSMOID_X509V1CertificateSubjectUniqueId,
+	CSSMOID_X509V3CertificateExtensionsStruct,
+	CSSMOID_X509V3CertificateExtensionsCStruct,
+	CSSMOID_X509V3CertificateNumberOfExtensions,
+	CSSMOID_X509V3CertificateExtensionStruct,
+	CSSMOID_X509V3CertificateExtensionCStruct,
+	CSSMOID_X509V3CertificateExtensionId,
+	CSSMOID_X509V3CertificateExtensionCritical,
+	CSSMOID_X509V3CertificateExtensionType,
+	CSSMOID_X509V3CertificateExtensionValue,
+	
+	/* Signature OID Fields */
+	CSSMOID_X509V1SignatureStruct,
+	CSSMOID_X509V1SignatureCStruct,
+	CSSMOID_X509V1SignatureAlgorithm,
+	CSSMOID_X509V1SignatureAlgorithmTBS,
+	CSSMOID_X509V1SignatureAlgorithmParameters,
+	CSSMOID_X509V1Signature,
+	
+	/* Extension OID Fields */
+	CSSMOID_SubjectSignatureBitmap,
+	CSSMOID_SubjectPicture,
+	CSSMOID_SubjectEmailAddress,
+	CSSMOID_UseExemptions;
+
+/*** 
+ *** Apple addenda
+ ***/
+ 
+/* 
+ * Standard Cert extensions.
+ */
+extern const CSSM_OID
+	CSSMOID_SubjectDirectoryAttributes,
+	CSSMOID_SubjectKeyIdentifier,
+	CSSMOID_KeyUsage,
+	CSSMOID_PrivateKeyUsagePeriod ,
+	CSSMOID_SubjectAltName,
+	CSSMOID_IssuerAltName,
+	CSSMOID_BasicConstraints,
+	CSSMOID_CrlNumber,
+	CSSMOID_CrlReason,
+	CSSMOID_HoldInstructionCode,
+	CSSMOID_InvalidityDate,
+	CSSMOID_DeltaCrlIndicator,
+	CSSMOID_IssuingDistributionPoints,
+	CSSMOID_NameConstraints,
+	CSSMOID_CrlDistributionPoints,
+	CSSMOID_CertificatePolicies,
+	CSSMOID_PolicyMappings,
+	CSSMOID_PolicyConstraints,
+	CSSMOID_AuthorityKeyIdentifier,
+	CSSMOID_ExtendedKeyUsage,
+	CSSMOID_ExtendedUseCodeSigning;
+
+/*
+ * Netscape extensions.
+ */
+extern const CSSM_OID	CSSMOID_NetscapeCertType;
+
+/*
+ * Field values for CSSMOID_NetscapeCertType, a bit string.
+ * Assumes a 16 bit field, even though currently only 8 bits
+ * are defined. 
+ */
+#define CE_NCT_SSL_Client	0x8000
+#define CE_NCT_SSL_Server	0x4000
+#define CE_NCT_SMIME		0x2000
+#define CE_NCT_ObjSign		0x1000
+#define CE_NCT_Reserved		0x0800
+#define CE_NCT_SSL_CA		0x0400
+#define CE_NCT_SMIME_CA		0x0200
+#define CE_NCT_ObjSignCA	0x0100
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OIDSCERT_H_ */
diff --git a/cdsa/cdsa/oidscrl.h b/cdsa/cdsa/oidscrl.h
new file mode 100644
index 00000000..74d57e29
--- /dev/null
+++ b/cdsa/cdsa/oidscrl.h
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      oidscrl.h
+
+   Contains:  Object Identifiers for X509 CRLS
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _OIDSCRL_H_
+#define _OIDSCRL_H_  1
+
+#include <Security/cssmconfig.h>
+#include <Security/cssmtype.h>
+#include <Security/oidsbase.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define INTEL_X509V2_CRL_R08 INTEL_SEC_FORMATS, 2, 1
+#define INTEL_X509V2_CRL_R08_LENGTH INTEL_SEC_FORMATS_LENGTH+2
+
+	
+extern const CSSM_OID
+    /* CRL OIDs */
+	CSSMOID_X509V2CRLSignedCrlStruct,
+	CSSMOID_X509V2CRLSignedCrlCStruct,
+	CSSMOID_X509V2CRLTbsCertListStruct,
+	CSSMOID_X509V2CRLTbsCertListCStruct,
+	CSSMOID_X509V2CRLVersion,
+	CSSMOID_X509V1CRLIssuerStruct,
+	CSSMOID_X509V1CRLIssuerNameCStruct,
+	CSSMOID_X509V1CRLIssuerNameLDAP,
+	CSSMOID_X509V1CRLThisUpdate,
+	CSSMOID_X509V1CRLNextUpdate,
+
+	/* CRL Entry (CRL CertList) OIDS */
+	CSSMOID_X509V1CRLRevokedCertificatesStruct,
+	CSSMOID_X509V1CRLRevokedCertificatesCStruct,
+	CSSMOID_X509V1CRLNumberOfRevokedCertEntries,
+	CSSMOID_X509V1CRLRevokedEntryStruct,
+	CSSMOID_X509V1CRLRevokedEntryCStruct,
+	CSSMOID_X509V1CRLRevokedEntrySerialNumber,
+	CSSMOID_X509V1CRLRevokedEntryRevocationDate,
+
+	/* CRL Entry (CRL CertList) Extension OIDs */
+	CSSMOID_X509V2CRLRevokedEntryAllExtensionsStruct,
+	CSSMOID_X509V2CRLRevokedEntryAllExtensionsCStruct,
+	CSSMOID_X509V2CRLRevokedEntryNumberOfExtensions,
+	CSSMOID_X509V2CRLRevokedEntrySingleExtensionStruct,
+	CSSMOID_X509V2CRLRevokedEntrySingleExtensionCStruct,
+	CSSMOID_X509V2CRLRevokedEntryExtensionId,
+	CSSMOID_X509V2CRLRevokedEntryExtensionCritical,
+	CSSMOID_X509V2CRLRevokedEntryExtensionType,
+	CSSMOID_X509V2CRLRevokedEntryExtensionValue,
+
+	/* CRL Extension OIDs */
+	CSSMOID_X509V2CRLAllExtensionsStruct,
+	CSSMOID_X509V2CRLAllExtensionsCStruct,
+	CSSMOID_X509V2CRLNumberOfExtensions,
+	CSSMOID_X509V2CRLSingleExtensionStruct,
+	CSSMOID_X509V2CRLSingleExtensionCStruct,
+	CSSMOID_X509V2CRLExtensionId,
+	CSSMOID_X509V2CRLExtensionCritical,
+	CSSMOID_X509V2CRLExtensionType;
+	
+
+	
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OIDSCRL_H_ */
diff --git a/cdsa/cdsa/x509defs.h b/cdsa/cdsa/x509defs.h
new file mode 100644
index 00000000..618db42b
--- /dev/null
+++ b/cdsa/cdsa/x509defs.h
@@ -0,0 +1,231 @@
+/*
+ * 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.
+ */
+
+
+/*
+   File:      x509defs.h
+
+   Contains:  Data structures for X509 Certificate Library field values
+
+   Copyright: (c) 1999-2000 Apple Computer, Inc., all rights reserved.
+*/
+
+#ifndef _X509DEFS_H_
+#define _X509DEFS_H_  1
+
+#include <Security/cssmtype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint8 CSSM_BER_TAG;
+#define BER_TAG_UNKNOWN 0
+#define BER_TAG_BOOLEAN 1
+#define BER_TAG_INTEGER 2
+#define BER_TAG_BIT_STRING 3
+#define BER_TAG_OCTET_STRING 4
+#define BER_TAG_NULL 5
+#define BER_TAG_OID 6
+#define BER_TAG_OBJECT_DESCRIPTOR 7
+#define BER_TAG_EXTERNAL 8
+#define BER_TAG_REAL 9
+#define BER_TAG_ENUMERATED 10
+/* 12 to 15 are reserved for future versions of the recommendation */
+#define BER_TAG_PKIX_UTF8_STRING 12
+#define BER_TAG_SEQUENCE 16
+#define BER_TAG_SET 17
+#define BER_TAG_NUMERIC_STRING 18
+#define BER_TAG_PRINTABLE_STRING 19
+#define BER_TAG_T61_STRING 20
+#define BER_TAG_TELETEX_STRING BER_TAG_T61_STRING
+#define BER_TAG_VIDEOTEX_STRING 21
+#define BER_TAG_IA5_STRING 22
+#define BER_TAG_UTC_TIME 23
+#define BER_TAG_GENERALIZED_TIME 24
+#define BER_TAG_GRAPHIC_STRING 25
+#define BER_TAG_ISO646_STRING 26
+#define BER_TAG_GENERAL_STRING 27
+#define BER_TAG_VISIBLE_STRING BER_TAG_ISO646_STRING
+/* 28 - are reserved for future versions of the recommendation */
+#define BER_TAG_PKIX_UNIVERSAL_STRING 28
+#define BER_TAG_PKIX_BMP_STRING 30
+
+
+/* Data Structures for X.509 Certificates */
+
+typedef struct cssm_x509_algorithm_identifier {
+    CSSM_OID algorithm;
+    CSSM_DATA parameters;
+} CSSM_X509_ALGORITHM_IDENTIFIER, *CSSM_X509_ALGORITHM_IDENTIFIER_PTR;
+
+/* X509 Distinguished name structure */
+typedef struct cssm_x509_type_value_pair {
+    CSSM_OID type;
+    CSSM_BER_TAG valueType; /* The Tag to be used when */
+    /*this value is BER encoded */
+    CSSM_DATA value;
+} CSSM_X509_TYPE_VALUE_PAIR, *CSSM_X509_TYPE_VALUE_PAIR_PTR;
+
+typedef struct cssm_x509_rdn {
+    uint32 numberOfPairs;
+    CSSM_X509_TYPE_VALUE_PAIR_PTR AttributeTypeAndValue;
+} CSSM_X509_RDN, *CSSM_X509_RDN_PTR;
+
+typedef struct cssm_x509_name {
+    uint32 numberOfRDNs;
+    CSSM_X509_RDN_PTR RelativeDistinguishedName;
+} CSSM_X509_NAME, *CSSM_X509_NAME_PTR;
+
+/* Public key info struct */
+typedef struct cssm_x509_subject_public_key_info {
+    CSSM_X509_ALGORITHM_IDENTIFIER algorithm;
+    CSSM_DATA subjectPublicKey;
+} CSSM_X509_SUBJECT_PUBLIC_KEY_INFO, *CSSM_X509_SUBJECT_PUBLIC_KEY_INFO_PTR;
+
+typedef struct cssm_x509_time {
+    CSSM_BER_TAG timeType;
+    CSSM_DATA time;
+} CSSM_X509_TIME, *CSSM_X509_TIME_PTR;
+
+/* Validity struct */
+typedef struct x509_validity {
+    CSSM_X509_TIME notBefore;
+    CSSM_X509_TIME notAfter;
+} CSSM_X509_VALIDITY, *CSSM_X509_VALIDITY_PTR;
+
+#define CSSM_X509_OPTION_PRESENT CSSM_TRUE
+#define CSSM_X509_OPTION_NOT_PRESENT CSSM_FALSE
+typedef CSSM_BOOL CSSM_X509_OPTION;
+
+typedef struct cssm_x509ext_basicConstraints {
+    CSSM_BOOL cA;
+    CSSM_X509_OPTION pathLenConstraintPresent;
+    uint32 pathLenConstraint;
+} CSSM_X509EXT_BASICCONSTRAINTS, *CSSM_X509EXT_BASICCONSTRAINTS_PTR;
+
+typedef enum extension_data_format {
+    CSSM_X509_DATAFORMAT_ENCODED = 0,
+    CSSM_X509_DATAFORMAT_PARSED,
+    CSSM_X509_DATAFORMAT_PAIR,
+} CSSM_X509EXT_DATA_FORMAT;
+
+typedef struct cssm_x509_extensionTagAndValue {
+    CSSM_BER_TAG type;
+    CSSM_DATA value;
+} CSSM_X509EXT_TAGandVALUE, *CSSM_X509EXT_TAGandVALUE_PTR;
+
+typedef struct cssm_x509ext_pair {
+    CSSM_X509EXT_TAGandVALUE tagAndValue;
+    void *parsedValue;
+} CSSM_X509EXT_PAIR, *CSSM_X509EXT_PAIR_PTR;
+
+/* Extension structure */
+typedef struct cssm_x509_extension {
+    CSSM_OID extnId;
+    CSSM_BOOL critical;
+    CSSM_X509EXT_DATA_FORMAT format;
+    union cssm_x509ext_value {
+        CSSM_X509EXT_TAGandVALUE *tagAndValue;
+        void *parsedValue;
+        CSSM_X509EXT_PAIR *valuePair;
+    } value;
+    CSSM_DATA BERvalue;
+} CSSM_X509_EXTENSION, *CSSM_X509_EXTENSION_PTR;
+
+typedef struct cssm_x509_extensions {
+    uint32 numberOfExtensions;
+    CSSM_X509_EXTENSION_PTR extensions;
+} CSSM_X509_EXTENSIONS, *CSSM_X509_EXTENSIONS_PTR;
+
+/* X509V3 certificate structure */
+typedef struct cssm_x509_tbs_certificate {
+    CSSM_DATA version;
+    CSSM_DATA serialNumber;
+    CSSM_X509_ALGORITHM_IDENTIFIER signature;
+    CSSM_X509_NAME issuer;
+    CSSM_X509_VALIDITY validity;
+    CSSM_X509_NAME subject;
+    CSSM_X509_SUBJECT_PUBLIC_KEY_INFO subjectPublicKeyInfo;
+    CSSM_DATA issuerUniqueIdentifier;
+    CSSM_DATA subjectUniqueIdentifier;
+    CSSM_X509_EXTENSIONS extensions;
+} CSSM_X509_TBS_CERTIFICATE, *CSSM_X509_TBS_CERTIFICATE_PTR;
+
+/* Signature structure */
+typedef struct cssm_x509_signature {
+    CSSM_X509_ALGORITHM_IDENTIFIER algorithmIdentifier;
+    CSSM_DATA encrypted;
+} CSSM_X509_SIGNATURE, *CSSM_X509_SIGNATURE_PTR;
+
+/* Signed certificate structure */
+typedef struct cssm_x509_signed_certificate {
+    CSSM_X509_TBS_CERTIFICATE certificate;
+    CSSM_X509_SIGNATURE signature;
+} CSSM_X509_SIGNED_CERTIFICATE, *CSSM_X509_SIGNED_CERTIFICATE_PTR;
+
+typedef struct cssm_x509ext_policyQualifierInfo {
+    CSSM_OID policyQualifierId;
+    CSSM_DATA value;
+} CSSM_X509EXT_POLICYQUALIFIERINFO, *CSSM_X509EXT_POLICYQUALIFIERINFO_PTR;
+
+typedef struct cssm_x509ext_policyQualifiers {
+    uint32 numberOfPolicyQualifiers;
+    CSSM_X509EXT_POLICYQUALIFIERINFO *policyQualifier;
+} CSSM_X509EXT_POLICYQUALIFIERS, *CSSM_X509EXT_POLICYQUALIFIERS_PTR;
+
+typedef struct cssm_x509ext_policyInfo {
+    CSSM_OID policyIdentifier;
+    CSSM_X509EXT_POLICYQUALIFIERS policyQualifiers;
+} CSSM_X509EXT_POLICYINFO, *CSSM_X509EXT_POLICYINFO_PTR;
+
+
+/* Data Structures for X.509 Certificate Revocations Lists */
+
+/* x509V2 entry in the CRL revokedCertificates sequence */
+typedef struct cssm_x509_revoked_cert_entry {
+    CSSM_DATA certificateSerialNumber;
+    CSSM_X509_TIME revocationDate;
+    CSSM_X509_EXTENSIONS extensions;
+} CSSM_X509_REVOKED_CERT_ENTRY, *CSSM_X509_REVOKED_CERT_ENTRY_PTR;
+
+typedef struct cssm_x509_revoked_cert_list {
+    uint32 numberOfRevokedCertEntries;
+    CSSM_X509_REVOKED_CERT_ENTRY_PTR revokedCertEntry;
+} CSSM_X509_REVOKED_CERT_LIST, *CSSM_X509_REVOKED_CERT_LIST_PTR;
+
+/* x509v2 Certificate Revocation List (CRL) (unsigned) structure */
+typedef struct cssm_x509_tbs_certlist {
+    CSSM_DATA version;
+    CSSM_X509_ALGORITHM_IDENTIFIER signature;
+    CSSM_X509_NAME issuer;
+    CSSM_X509_TIME thisUpdate;
+    CSSM_X509_TIME nextUpdate;
+    CSSM_X509_REVOKED_CERT_LIST_PTR revokedCertificates;
+    CSSM_X509_EXTENSIONS extensions;
+} CSSM_X509_TBS_CERTLIST, *CSSM_X509_TBS_CERTLIST_PTR;
+
+typedef struct cssm_x509_signed_crl {
+    CSSM_X509_TBS_CERTLIST tbsCertList;
+    CSSM_X509_SIGNATURE signature;
+} CSSM_X509_SIGNED_CRL, *CSSM_X509_SIGNED_CRL_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _X509DEFS_H_ */
diff --git a/cdsa/cdsa_client.cpp b/cdsa/cdsa_client.cpp
new file mode 100644
index 00000000..94eb8c74
--- /dev/null
+++ b/cdsa/cdsa_client.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+
+/* Headers. */
+#include <cdsa_client/aclclient.h>
+#include <cdsa_client/cryptoclient.h>
+#include <cdsa_client/cspclient.h>
+#include <cdsa_client/cssmclient.h>
+#include <cdsa_client/dlclient.h>
+#include <cdsa_client/DLDBList.h>
+#include <cdsa_client/keyclient.h>
+#include <cdsa_client/macclient.h>
+#include <cdsa_client/multidldb.h>
+#include <cdsa_client/securestorage.h>
+#include <cdsa_client/signclient.h>
+#include <cdsa_client/wrapkey.h>
+#include <cdsa_client/genkey.h>
+#include <cdsa_client/osxsigner.h>
+#include <cdsa_client/aclsupport.h>
+#include <cdsa_client/keychainacl.h>
+
+/* Source files. */
+#include <cdsa_client/cryptoclient.cpp>
+#include <cdsa_client/cspclient.cpp>
+#include <cdsa_client/cssmclient.cpp>
+#include <cdsa_client/dlclient.cpp>
+#include <cdsa_client/DLDBList.cpp>
+#include <cdsa_client/keyclient.cpp>
+#include <cdsa_client/macclient.cpp>
+#include <cdsa_client/multidldb.cpp>
+#include <cdsa_client/securestorage.cpp>
+#include <cdsa_client/signclient.cpp>
+#include <cdsa_client/wrapkey.cpp>
+#include <cdsa_client/genkey.cpp>
+#include <cdsa_client/osxsigner.cpp>
+#include <cdsa_client/aclsupport.cpp>
+#include <cdsa_client/keychainacl.cpp>
diff --git a/cdsa/cdsa_client/DLDBList.cpp b/cdsa/cdsa_client/DLDBList.cpp
new file mode 100644
index 00000000..1deb70d9
--- /dev/null
+++ b/cdsa/cdsa_client/DLDBList.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+/*
+    DLDbList.cpp
+*/
+
+#include "DLDBList.h"
+
+using namespace CssmClient;
+
+//----------------------------------------------------------------------
+//			DLDbList implementation
+//----------------------------------------------------------------------
+
+void DLDbList::add(const DLDbIdentifier& dldbIdentifier)	// Adds at end if not in list
+{
+    for (DLDbList::const_iterator ix=begin();ix!=end();ix++)
+        if (*ix==dldbIdentifier)		// already in list
+            return;
+    push_back(dldbIdentifier);
+    changed(true);
+}
+
+void DLDbList::remove(const DLDbIdentifier& dldbIdentifier)	// Removes from list
+{
+    for (DLDbList::iterator ix=begin();ix!=end();ix++)
+	if (*ix==dldbIdentifier)		// found in list
+	{
+		erase(ix);
+		changed(true);
+		break;
+	}
+}
+
+void DLDbList::save()
+{
+}
diff --git a/cdsa/cdsa_client/DLDBList.h b/cdsa/cdsa_client/DLDBList.h
new file mode 100644
index 00000000..6affdb91
--- /dev/null
+++ b/cdsa/cdsa_client/DLDBList.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+/*
+    DLDbList.h
+    
+    This implements a vector of DLDbIdentifiers. A DLDbIdentifier contains all of the
+    information needed to find a particular DB within a particular DL. This file
+    does not depend on CoreFoundation but does depend on CDSA headers.
+*/
+
+#ifndef _H_CDSA_CLIENT_DLDBLIST
+#define _H_CDSA_CLIENT_DLDBLIST  1
+
+#include <Security/utilities.h>
+#include <Security/cssmdb.h>
+#include <Security/DbName.h>
+#include <Security/refcount.h>
+#include <vector>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+//-------------------------------------------------------------------------------------
+//
+//			Lists of DL/DBs
+//
+//-------------------------------------------------------------------------------------
+
+
+//
+// DLDbList
+//
+class DLDbList : public vector<DLDbIdentifier>
+{
+public:
+    DLDbList() : mChanged(false) {}
+    virtual ~DLDbList() {}
+    
+    // API
+    virtual void add(const DLDbIdentifier& dldbIdentifier);		// Adds at end if not in list
+    virtual void remove(const DLDbIdentifier& dldbIdentifier);	// Removes from list
+    virtual void save();
+
+    bool hasChanged() const { return mChanged; }
+
+protected:
+    void changed(bool hasChanged) { mChanged=hasChanged; }
+    
+private:
+    bool mChanged;
+};
+
+}; // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_DLDBLIST
diff --git a/cdsa/cdsa_client/aclclient.h b/cdsa/cdsa_client/aclclient.h
new file mode 100644
index 00000000..bbd1f92d
--- /dev/null
+++ b/cdsa/cdsa_client/aclclient.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+
+//
+// keyclient 
+//
+#ifndef _H_CDSA_CLIENT_ACLCLIENT
+#define _H_CDSA_CLIENT_ACLCLIENT  1
+
+#include <Security/cssmaclpod.h>
+#include <Security/cssmcred.h>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+class CSP;
+
+//
+// AclClient -- abstract interface implemented by objects that can manipulate their acls
+//
+class AclClient
+{
+public:	
+	// Acl manipulation
+	virtual void getAcl(const char *selectionTag, AutoAclEntryInfoList &aclInfos) const = 0;
+	virtual void changeAcl(const CSSM_ACCESS_CREDENTIALS *accessCred,
+						   const CSSM_ACL_EDIT &aclEdit) = 0;
+
+	// Acl owner manipulation
+	virtual void getOwner(AutoAclOwnerPrototype &owner) const = 0;
+	virtual void changeOwner(const CSSM_ACCESS_CREDENTIALS *accessCred,
+							 const CSSM_ACL_OWNER_PROTOTYPE &newOwner) = 0;
+
+#if 0
+	// Create a random owner
+	static void makeRandomOwner(CSP &csp, AutoAclOwnerPrototype &owner, AutoCredentials &cred);
+	void setOwnerAndAcl(const AutoCredentials &cred, const AutoAclOwnerPrototype &newOwner,
+						uint32 numEntries, const CSSM_ACL_ENTRY_INFO *entries);
+#endif
+};
+
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_ACLCLIENT
diff --git a/cdsa/cdsa_client/aclsupport.cpp b/cdsa/cdsa_client/aclsupport.cpp
new file mode 100644
index 00000000..98cb2b6d
--- /dev/null
+++ b/cdsa/cdsa_client/aclsupport.cpp
@@ -0,0 +1,331 @@
+/*
+ * 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.
+ */
+
+
+//
+// aclsupport.h - support for special Keychain style acls
+//
+
+#include <Security/osxsigning.h>
+#include <Security/osxsigner.h>
+#include "aclsupport.h"
+#include "keychainacl.h"
+#include <memory>
+
+using namespace CssmClient;
+
+
+// ---------------------------------------------------------------------------
+//	TrustedApplicationImpl
+// ---------------------------------------------------------------------------
+
+TrustedApplicationImpl::TrustedApplicationImpl(const CssmData &signature, const CssmData &comment, bool enabled) :
+	mSignature(CssmAllocator::standard(), signature),
+	mComment(CssmAllocator::standard(), comment),
+	mEnabled(enabled)
+{
+}
+
+TrustedApplicationImpl::TrustedApplicationImpl(const char *path, const CssmData &comment, bool enabled) :	mSignature(CssmAllocator::standard(), calcSignature(path)),
+	mComment(CssmAllocator::standard(), comment),
+	mEnabled(enabled)
+{
+}
+
+
+const CssmData & TrustedApplicationImpl::signature() const
+{
+
+	return mSignature;
+}
+
+const CssmData & TrustedApplicationImpl::comment() const
+{
+	return mComment;
+}
+
+bool TrustedApplicationImpl::enabled() const
+{
+	return mEnabled;
+}
+
+void TrustedApplicationImpl::enabled(bool enabled)
+{
+	mEnabled = enabled;
+}
+
+bool TrustedApplicationImpl::sameSignature(const char *path)
+{
+	// return true if object at given path has same signature
+	return (mSignature.get() == calcSignature(path).get());
+}
+
+CssmAutoData TrustedApplicationImpl::calcSignature(const char *path)
+{
+	// generate a signature for the given object
+	auto_ptr<CodeSigning::OSXCode> objToVerify(CodeSigning::OSXCode::at(path));
+	CodeSigning::OSXSigner signer;
+	auto_ptr<CodeSigning::OSXSigner::OSXSignature> signature(signer.sign(*objToVerify));
+
+	return CssmAutoData(CssmAllocator::standard(), signature->data(), signature->length());
+}
+
+// ---------------------------------------------------------------------------
+//	TrustedApplication
+// ---------------------------------------------------------------------------
+
+TrustedApplication::TrustedApplication()
+{
+}
+
+TrustedApplication::TrustedApplication(
+	const char *path, const CssmData &comment, bool enabled) :
+RefPointer<TrustedApplicationImpl>(new TrustedApplicationImpl(path, comment, enabled))
+{
+}
+
+TrustedApplication::TrustedApplication(
+	const CssmData &signature, const CssmData &comment, bool enabled) :
+RefPointer<TrustedApplicationImpl>(new TrustedApplicationImpl(signature, comment, enabled))
+{
+}
+
+// ---------------------------------------------------------------------------
+//	KeychainACL
+// ---------------------------------------------------------------------------
+
+KeychainACL::KeychainACL(const Key &key) :
+    mLabel(CssmAllocator::standard())
+{
+    mKey = key;
+	initialize();
+}
+
+void KeychainACL::initialize()
+{
+	mAnyAllow=false;
+	mAlwaysAskUser=false;
+
+	AutoAclEntryInfoList aclInfos;
+	mKey->getAcl(NULL, aclInfos);
+	mHandle = CSSM_INVALID_HANDLE;
+	const AclEntryInfo *theInfo = NULL;
+	for(uint32 entry=0; entry<aclInfos.size(); entry++)
+	{
+		const AclEntryInfo &info = aclInfos[entry];
+		const AuthorizationGroup &authorizationGroup=info.proto().authorization();
+		for(uint32 auth=0; auth<authorizationGroup.count(); auth++)
+		{
+			if(authorizationGroup[auth]==CSSM_ACL_AUTHORIZATION_DECRYPT || authorizationGroup[auth]==CSSM_ACL_AUTHORIZATION_ANY)
+			{
+				if (mHandle != CSSM_INVALID_HANDLE && mHandle != info.handle())
+				{
+					mIsCustomACL=true;
+					return;
+				}
+
+				mHandle = info.handle();
+				theInfo = &info;
+			}
+		}
+	}
+	if (!theInfo)
+	{
+		mIsCustomACL=true;
+		return;
+	}
+
+	TypedList subject=theInfo->proto().subject();
+	assert(subject.isProper());
+	const ListElement *element = subject.first();
+
+	switch(*element)
+	{
+		case CSSM_ACL_SUBJECT_TYPE_ANY:
+			assert(element->next() == NULL);
+			mAnyAllow=true;
+			return;
+
+		case CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT:
+			mAlwaysAskUser=true;
+			element = element->next();
+			assert(element && element->type() == CSSM_LIST_ELEMENT_DATUM && element->next() == NULL);
+			mLabel = element->data();
+			return;
+		
+		case CSSM_ACL_SUBJECT_TYPE_THRESHOLD:
+			break;
+
+		default:
+			mIsCustomACL = true;
+			return;
+	}
+
+	// OK, it's a threshold acl
+	element = element->next();
+	assert(element && element->type() == CSSM_LIST_ELEMENT_WORDID);
+	if (*element != 1) {
+		mIsCustomACL = true;
+		return;
+	}
+	element = element->next();
+	assert(element && element->type() == CSSM_LIST_ELEMENT_WORDID);
+	uint32 n = *element;
+	assert(n > 0);
+
+	int isEnabled=1;
+	for (uint32 ix = 0; ix < n; ++ix)
+	{
+		element = element->next();
+		assert(element && element->type() == CSSM_LIST_ELEMENT_SUBLIST);
+		const TypedList &subList = *element;
+		assert(subList.isProper());
+		const ListElement *subElement = subList.first();
+
+		switch(*subElement)
+		{
+		case CSSM_ACL_SUBJECT_TYPE_ANY:
+			// Must be first subList in list.
+			assert(ix == 0 && subElement->next() == NULL);
+			mAnyAllow=true;
+			break;
+
+		case CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT:
+			// Must be last subList in list.
+			assert(ix == n - 1);
+			mAlwaysAskUser=true;
+			subElement = subElement->next();
+			assert(subElement && subElement->type() == CSSM_LIST_ELEMENT_DATUM && subElement->next() == NULL);
+			mLabel = subElement->data();
+			break;
+
+
+		case CSSM_ACL_SUBJECT_TYPE_COMMENT:
+		case CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE:
+		{
+			// when the app is disabled it is commented out.
+			if(*subElement==CSSM_ACL_SUBJECT_TYPE_COMMENT)
+			{
+				isEnabled=0;
+				subElement = subElement->next();
+			}
+			subElement = subElement->next();
+     		assert(subElement && subElement->type() == CSSM_LIST_ELEMENT_WORDID);
+			uint32 sigType = *subElement;
+    		subElement = subElement->next();
+			assert(subElement && subElement->type() == CSSM_LIST_ELEMENT_DATUM);
+			const CssmData &sig = subElement->data();
+			subElement = subElement->next();
+			assert(subElement && subElement->type() == CSSM_LIST_ELEMENT_DATUM && subElement->next() == NULL);
+			const CssmData &comment = subElement->data();
+			// Only if sigType is CSSM_ACL_CODE_SIGNATURE_OSX this element is enabled.
+			// @@@ Otherwsie it should be CSSM_ACL_CODE_SIGNATURE_NONE (which is not defined yet).
+			// additionally the enabled flag must be respected.
+			push_back(TrustedApplication(sig, comment, (sigType == CSSM_ACL_CODE_SIGNATURE_OSX) && isEnabled));
+			break;
+		}
+
+		default:
+			mIsCustomACL = true;
+		return;
+		}
+	}
+
+	// Since we looked at N values we should be done.
+	assert(element->next() == NULL);
+}
+
+void KeychainACL::commit()
+{
+	TrackingAllocator allocator(CssmAllocator::standard());
+
+	KeychainAclFactory aclFactory(allocator);
+
+	CssmList &list = *new(allocator) CssmList();
+
+	list.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_THRESHOLD));   
+	list.append(new(allocator) ListElement(1));
+	list.append(new(allocator) ListElement(size()+mAnyAllow+mAlwaysAskUser));
+	
+	if(mAnyAllow)
+	{
+		CssmList &sublist = *new(allocator) CssmList();
+		sublist.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_ANY));
+		list.append(new(allocator) ListElement(sublist));
+	}
+
+		
+	for (uint32 ix = 0; ix < size(); ++ix)
+	{
+		TrustedApplication app = at(ix);
+		CssmList &sublist = *new(allocator) CssmList();
+		if(!app->enabled()) sublist.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_COMMENT));
+		sublist.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE));
+		sublist.append(new(allocator) ListElement(CSSM_ACL_CODE_SIGNATURE_OSX));
+		sublist.append(new(allocator) ListElement(app->signature()));
+		sublist.append(new(allocator) ListElement(app->comment()));
+		list.append(new(allocator) ListElement(sublist));
+	}
+
+	if(mAlwaysAskUser)
+	{
+		CssmList &sublist = *new(allocator) CssmList();
+		sublist.append(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT));
+		sublist.append(new(allocator) ListElement(mLabel.get()));
+		list.append(new(allocator) ListElement(sublist));	
+	}
+
+	AclEntryPrototype aclEntry(list);
+	// @@@ @@@ Force "decrypt" authorization for now -- should take this from input!! @@@
+	AuthorizationGroup &anyDecryptAuthGroup = aclEntry.authorization();
+	CSSM_ACL_AUTHORIZATION_TAG decryptTag = CSSM_ACL_AUTHORIZATION_DECRYPT;
+	anyDecryptAuthGroup.NumberOfAuthTags = 1;
+	anyDecryptAuthGroup.AuthTags = &decryptTag;
+	const AccessCredentials *promptCred = aclFactory.keychainPromptCredentials();
+	AclEdit edit(mHandle, aclEntry);
+	mKey->changeAcl(promptCred, edit);
+}
+
+void KeychainACL::anyAllow(bool allow)
+{
+	mAnyAllow=allow;
+}
+
+bool KeychainACL::anyAllow() const
+{
+	return mAnyAllow;
+}
+
+void KeychainACL::alwaysAskUser(bool ask)
+{
+	mAlwaysAskUser=ask;
+}
+
+bool KeychainACL::alwaysAskUser() const
+{
+	return mAlwaysAskUser;
+}
+
+bool KeychainACL::isCustomACL() const
+{
+	return mIsCustomACL;
+}
+
+void KeychainACL::label(const CssmData &label)
+{
+    mLabel = label;
+}
diff --git a/cdsa/cdsa_client/aclsupport.h b/cdsa/cdsa_client/aclsupport.h
new file mode 100644
index 00000000..d0d1c6b9
--- /dev/null
+++ b/cdsa/cdsa_client/aclsupport.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+
+//
+// aclsupport.h - support for special Keychain style acls
+//
+
+#ifndef _ACLSUPPORT_H_
+#define _ACLSUPPORT_H_
+
+#include <Security/cssmdata.h>
+#include <Security/threading.h>
+#include <Security/cssmalloc.h>
+#include <Security/refcount.h>
+#include <Security/keyclient.h>
+#include <vector>
+
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+class TrustedApplicationImpl : public RefCount
+{
+public:
+	TrustedApplicationImpl(const CssmData &signature, const CssmData &comment, bool enabled);
+	TrustedApplicationImpl(const char *path, const CssmData &comment, bool enabled);
+
+	const CssmData &signature() const;
+	const CssmData &comment() const;
+	bool enabled() const;
+	void enabled(bool enabled);
+
+	bool sameSignature(const char *path); // return true if object at path has same signature
+	CssmAutoData calcSignature(const char *path); // generate a signature
+
+private:
+	CssmAutoData mSignature;
+	CssmAutoData mComment;
+	bool mEnabled;
+};
+
+class TrustedApplication : public RefPointer<TrustedApplicationImpl>
+{
+public:
+	TrustedApplication();
+	TrustedApplication(const CssmData &signature, const CssmData &comment, bool enabled = true);
+	TrustedApplication(const char *path, const CssmData &comment, bool enabled = true);
+};
+
+class KeychainACL : public vector<TrustedApplication>
+{
+public:
+	KeychainACL(const Key &key);
+	void commit();
+
+	void anyAllow(bool allow);
+	bool anyAllow() const;
+
+	void alwaysAskUser(bool allow);
+	bool alwaysAskUser() const;
+	bool isCustomACL() const;
+    void label(const CssmData &label);
+
+private:
+	void initialize();
+	Key mKey;
+	bool mAnyAllow;
+	bool mAlwaysAskUser;
+	bool mIsCustomACL;
+	CssmAutoData mLabel;
+
+	CSSM_ACL_HANDLE mHandle;
+};
+
+}; // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _ACLSUPPORT_H_
diff --git a/cdsa/cdsa_client/cryptoclient.cpp b/cdsa/cdsa_client/cryptoclient.cpp
new file mode 100644
index 00000000..b6ad3ab9
--- /dev/null
+++ b/cdsa/cdsa_client/cryptoclient.cpp
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+
+//
+// cryptoclient - client interface to CSSM CSP encryption/decryption operations
+//
+#include <Security/cryptoclient.h>
+
+using namespace CssmClient;
+
+
+Crypt::Crypt(const CSP &csp, CSSM_ALGORITHMS alg) : Context(csp, alg)
+{
+	// set defaults
+	mMode = CSSM_ALGMODE_NONE;
+	mCred = NULL;
+	mInitVector = NULL;
+	mPadding = CSSM_PADDING_NONE;
+}
+
+void
+Crypt::activate()
+{
+	if (!mActive)
+	{
+        // Some crypto operations require a credential.
+        // Use a null credential if none was specified.
+        if (!mCred)
+            mCred = &AccessCredentials::null;
+    
+        // Key is required unless we have a NULL algorithm (cleartext wrap/unwrap),
+        // in which case we'll make a symmetric context (it shouldn't matter then).
+		if (!mKey && mAlgorithm != CSSM_ALGID_NONE)
+			CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_KEY);
+		if (!mKey || mKey->keyClass() == CSSM_KEYCLASS_SESSION_KEY)
+		{	// symmetric key
+			check(CSSM_CSP_CreateSymmetricContext(attachment()->handle(), mAlgorithm,
+				mMode, mCred, mKey, mInitVector, mPadding, NULL,
+				&mHandle));
+		}
+		else
+		{
+			check(CSSM_CSP_CreateAsymmetricContext(attachment()->handle(), mAlgorithm,
+				mCred, mKey, mPadding, &mHandle));
+			//@@@ stick mode and initVector explicitly into the context?
+		}		
+		mActive = true;
+	}
+}
+void Crypt::cred(const AccessCredentials *c)
+{
+    if (!(mCred = c))
+        mCred = &AccessCredentials::null;
+    set(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, *mCred);
+}
+
+
+//
+// Manage encryption contexts
+//
+
+uint32
+Encrypt::encrypt(const CssmData *in, uint32 inCount,
+						CssmData *out, uint32 outCount, CssmData &remData)
+{
+	unstaged();
+	uint32 total;
+	check(CSSM_EncryptData(handle(), in, inCount, out, outCount, &total, &remData));
+	return total;
+}
+
+void
+Encrypt::init()
+{
+	check(CSSM_EncryptDataInit(handle()));
+	mStaged = true;
+}
+
+uint32
+Encrypt::encrypt(const CssmData *in, uint32 inCount,
+	CssmData *out, uint32 outCount)
+{
+	staged();
+	uint32 total;
+	check(CSSM_EncryptDataUpdate(handle(), in, inCount, out, outCount, &total));
+	return total;
+}
+
+void
+Encrypt::final(CssmData &remData)
+{
+	staged();
+	check(CSSM_EncryptDataFinal(handle(), &remData));
+	mStaged = false;
+}
+
+
+//
+// Manage Decryption contexts
+//
+
+uint32
+Decrypt::decrypt(const CssmData *in, uint32 inCount,
+	CssmData *out, uint32 outCount, CssmData &remData)
+{
+	unstaged();
+	uint32 total;
+	check(CSSM_DecryptData(handle(), in, inCount, out, outCount, &total, &remData));
+	return total;
+}
+
+void
+Decrypt::init()
+{
+	check(CSSM_DecryptDataInit(handle()));
+	mStaged = true;
+}
+
+uint32
+Decrypt::decrypt(const CssmData *in, uint32 inCount,
+	CssmData *out, uint32 outCount)
+{
+	staged();
+	uint32 total;
+	check(CSSM_DecryptDataUpdate(handle(), in, inCount, out, outCount, &total));
+	return total;
+}
+
+void
+Decrypt::final(CssmData &remData)
+{
+	staged();
+	check(CSSM_DecryptDataFinal(handle(), &remData));
+	mStaged = false;
+}
diff --git a/cdsa/cdsa_client/cryptoclient.h b/cdsa/cdsa_client/cryptoclient.h
new file mode 100644
index 00000000..247b6a30
--- /dev/null
+++ b/cdsa/cdsa_client/cryptoclient.h
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+
+//
+// cryptoclient - client interface to CSSM CSP encryption/decryption operations
+//
+#ifndef _H_CDSA_CLIENT_CRYPTOCLIENT
+#define _H_CDSA_CLIENT_CRYPTOCLIENT  1
+
+#include <Security/cspclient.h>
+#include <Security/keyclient.h>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+class Crypt : public Context
+{
+public:
+	Crypt(const CSP &csp, CSSM_ALGORITHMS alg);
+	
+public:
+    // Context attributes
+	CSSM_ENCRYPT_MODE mode() const			{ return mMode; }
+	void mode(CSSM_ENCRYPT_MODE m)			{ mMode = m; set(CSSM_ATTRIBUTE_MODE, m); }
+	const AccessCredentials *cred() const	{ return mCred; }
+	void cred(const AccessCredentials *c);
+	Key key() const							{ return mKey; }
+	void key(const Key &k)				   	{ mKey = k; set(CSSM_ATTRIBUTE_KEY, k); }
+	const CssmData &initVector() const		{ return *mInitVector; }
+	void initVector(const CssmData &v)		{ mInitVector = &v; set(CSSM_ATTRIBUTE_INIT_VECTOR, v); }
+	CSSM_PADDING padding() const			{ return mPadding; }
+	void padding(CSSM_PADDING p)			{ mPadding = p; set(CSSM_ATTRIBUTE_PADDING, p); }
+
+    // Other attributes
+	AclEntryInput aclEntry() const			{ return mAclEntry; }
+	void aclEntry(AclEntryInput &aclEntry)	{ mAclEntry = aclEntry; }
+
+protected:
+	void activate();
+	
+protected:
+	CSSM_ENCRYPT_MODE mMode;
+	Key mKey;
+	const CssmData *mInitVector;
+	CSSM_PADDING mPadding;
+	
+protected:
+	const AccessCredentials *mCred;
+	AclEntryInput mAclEntry;
+};
+
+
+
+//
+// An encryption context
+//
+class Encrypt : public Crypt
+{
+public:
+	Encrypt(const CSP &csp, CSSM_ALGORITHMS alg) : Crypt(csp, alg) {};
+	
+
+public:
+	// integrated
+	uint32 encrypt(const CssmData *in, uint32 inCount, CssmData *out, uint32 outCount,
+		CssmData &remData);
+	uint32 encrypt(const CssmData &in, CssmData &out, CssmData &remData)
+	{ return encrypt(&in, 1, &out, 1, remData); }
+	
+	// staged update
+	void init(); // Optional
+	uint32 encrypt(const CssmData *in, uint32 inCount, CssmData *out, uint32 outCount);
+	uint32 encrypt(const CssmData &in, CssmData &out)
+	{ return encrypt(&in, 1, &out, 1); }
+	// staged final
+	void final(CssmData &remData);
+
+};
+
+//
+// An Decryption context
+//
+class Decrypt : public Crypt
+{
+public:
+	Decrypt(const CSP &csp, CSSM_ALGORITHMS alg) : Crypt(csp, alg) {};
+	
+public:
+	// integrated
+	uint32 decrypt(const CssmData *in, uint32 inCount, CssmData *out, uint32 outCount,
+		CssmData &remData);
+	uint32 decrypt(const CssmData &in, CssmData &out, CssmData &remData)
+	{ return decrypt(&in, 1, &out, 1, remData); }
+
+	// staged update
+	void init(); // Optional
+	uint32 decrypt(const CssmData *in, uint32 inCount, CssmData *out, uint32 outCount);
+	uint32 decrypt(const CssmData &in, CssmData &out)
+	{ return decrypt(&in, 1, &out, 1); }
+	// staged final
+	void final(CssmData &remData);
+};
+
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_CRYPTOCLIENT
diff --git a/cdsa/cdsa_client/cspclient.cpp b/cdsa/cdsa_client/cspclient.cpp
new file mode 100644
index 00000000..4031e01f
--- /dev/null
+++ b/cdsa/cdsa_client/cspclient.cpp
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+
+//
+// cspclient - client interface to CSSM CSPs and their operations
+//
+#include <Security/cspclient.h>
+
+using namespace CssmClient;
+
+
+//
+// Manage CSP attachments
+//
+CSPImpl::CSPImpl(const Guid &guid) : AttachmentImpl(guid, CSSM_SERVICE_CSP)
+{
+}
+
+CSPImpl::CSPImpl(const Module &module) : AttachmentImpl(module, CSSM_SERVICE_CSP)
+{
+}
+
+CSPImpl::~CSPImpl()
+{
+}
+
+
+//
+// Delete a key explicitly
+//
+void CSPImpl::freeKey(CssmKey &key, const AccessCredentials *cred, bool permanent)
+{
+    check(CSSM_FreeKey(handle(), cred, &key, permanent));
+}
+
+
+//
+// Manage generic context objects
+//
+CssmClient::Context::Context(const CSP &csp, CSSM_ALGORITHMS alg) 
+: ObjectImpl(csp), mAlgorithm(alg), mStaged(false)
+{
+}
+
+CssmClient::Context::~Context()
+{
+	try
+	{
+		deactivate();
+	} catch(...) {}
+}
+
+void CssmClient::Context::init()
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void CssmClient::Context::deactivate()
+{
+	if (mActive)
+	{
+		mActive = false;
+		check(CSSM_DeleteContext(mHandle));
+	}
+}
+
+
+void CssmClient::Context::algorithm(CSSM_ALGORITHMS alg)
+{
+	if (isActive())
+		abort();	//@@@ can't (currently?) change algorithm with active context
+	mAlgorithm = alg;
+}
+
+
+//
+// The override() method of Context is an expert feature. It replaces the entire
+// context with a context object provided. It is up to the caller to keep this context
+// consistent with the purpose of the Context subclass he is (mis)using.
+// This feature is currently used by the SecurityServer.
+//
+void CssmClient::Context::override(const Security::Context &ctx)
+{
+	if (!isActive()) {
+		// make a valid context object (it doesn't matter what kind - keep it cheap)
+		check(CSSM_CSP_CreateDigestContext(attachment()->handle(), CSSM_ALGID_NONE, &mHandle));
+	}
+	// now replace everything with the context data provided
+	check(CSSM_SetContext(mHandle, &ctx));
+	mActive = true;		// now active
+}
+
+
+//
+// Manage Digest contexts
+//
+void Digest::activate()
+{
+	if (!mActive) {
+		check(CSSM_CSP_CreateDigestContext(attachment()->handle(), mAlgorithm, &mHandle));
+		mActive = true;
+	}
+}
+
+
+void Digest::digest(const CssmData *data, uint32 count, CssmData &digest)
+{
+	activate();
+	if (mStaged)
+		Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS);
+	check(CSSM_DigestData(handle(), data, count, &digest));
+}
+
+void Digest::digest(const CssmData *data, uint32 count)
+{
+	activate();
+	if (!mStaged) {
+		check(CSSM_DigestDataInit(handle()));
+		mStaged = true;
+	}
+	check(CSSM_DigestDataUpdate(handle(), data, count));
+}
+
+void Digest::operator () (CssmData &digest)
+{
+	if (!mStaged)
+		Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED);
+	check(CSSM_DigestDataFinal(handle(), &digest));
+	mStaged = false;
+}
+
+
+//
+// Random number generation
+//
+void Random::seed(const CssmCryptoData &seedData)
+{
+	mSeed = &seedData;
+	set(CSSM_ATTRIBUTE_SEED, seedData);
+}
+
+void Random::size(uint32 sz)
+{
+	mSize = sz;
+	set(CSSM_ATTRIBUTE_OUTPUT_SIZE, sz);
+}
+
+
+void Random::activate()
+{
+	if (!mActive) {
+		check(CSSM_CSP_CreateRandomGenContext(attachment()->handle(), mAlgorithm,
+			mSeed, mSize, &mHandle));
+		mActive = true;
+	}
+}
+
+
+void Random::generate(CssmData &data, uint32 newSize)
+{
+	if (newSize)
+		size(newSize);
+	activate();
+	assert(!mStaged);	// not a stage-able operation
+	check(CSSM_GenerateRandom(handle(), &data));
+}
diff --git a/cdsa/cdsa_client/cspclient.h b/cdsa/cdsa_client/cspclient.h
new file mode 100644
index 00000000..e17c5d73
--- /dev/null
+++ b/cdsa/cdsa_client/cspclient.h
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+
+
+//
+// cspclient - client interface to CSSM CSPs and their operations
+//
+#ifndef _H_CDSA_CLIENT_CSPCLIENT
+#define _H_CDSA_CLIENT_CSPCLIENT  1
+
+#include <Security/cssmclient.h>
+#include <Security/context.h>
+#include <Security/cssmacl.h>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+//
+// A CSP attachment
+//
+class CSPImpl : public AttachmentImpl
+{
+public:
+	CSPImpl(const Guid &guid);
+	CSPImpl(const Module &module);
+	virtual ~CSPImpl();
+    
+    // the least inappropriate place for this one
+    void freeKey(CssmKey &key, const AccessCredentials *cred = NULL, bool permanent = false);
+};
+
+class CSP : public Attachment
+{
+public:
+	typedef CSPImpl Impl;
+
+	explicit CSP(Impl *impl) : Attachment(impl) {}
+	CSP(const Guid &guid) : Attachment(new Impl(guid)) {}
+	CSP(const Module &module) : Attachment(new Impl(module)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+};
+
+//
+// A cryptographic context.
+// Contexts always belong to CSPs (CSP attachments).
+//
+class Context : public ObjectImpl
+{
+public:
+	Context(const CSP &csp, CSSM_ALGORITHMS alg = CSSM_ALGID_NONE);
+	~Context();
+
+	CSP Context::attachment() const { return parent<CSP>(); }
+	Module Context::module() const { return attachment()->module(); }
+	
+	CSSM_ALGORITHMS algorithm() const { return mAlgorithm; }
+	void algorithm(CSSM_ALGORITHMS alg);
+
+public:
+	CSSM_CC_HANDLE handle() { activate(); return mHandle; }
+	
+public:
+	// don't use this section unless you know what you're doing!
+	void override(const ::Context &ctx);
+
+	template <class T>
+	void set(CSSM_ATTRIBUTE_TYPE type, const T &value)
+	{
+		if (isActive()) {
+			::Context::Attr attr(type, value);
+			check(CSSM_UpdateContextAttributes(handle(), 1, &attr));
+		}
+	}
+
+	void set(CSSM_ATTRIBUTE_TYPE type, uint32 value)
+	{
+		if (isActive()) {
+			::Context::Attr attr(type, value);
+			check(CSSM_UpdateContextAttributes(handle(), 1, &attr));
+		}
+	}
+    
+    template <class T>
+    void add(CSSM_ATTRIBUTE_TYPE type, const T &value)
+    { activate(); set(type, value); }
+    
+    void add(CSSM_ATTRIBUTE_TYPE type, uint32 value)
+    { activate(); set(type, value); }
+	
+protected:
+	CSSM_ALGORITHMS mAlgorithm;		// intended algorithm
+	CSSM_CC_HANDLE mHandle;			// CSSM CC handle
+	bool mStaged;					// staged in progress
+
+	void deactivate();
+
+	virtual void init(); // Subclasses must implement if they support staged operations.
+
+	void unstaged()
+	{ activate(); if (mStaged) CssmError::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS); }
+	
+	void staged()
+	{ if (!mStaged) init(); }
+};
+
+
+//
+// A Digest context
+//
+class Digest : public Context
+{
+public:
+	Digest(const CSP &csp, CSSM_ALGORITHMS alg) : Context(csp, alg) { }
+	
+public:
+	// integrated
+	void digest(const CssmData &data, CssmData &digest) { this->digest(&data, 1, digest); }
+	void digest(const CssmData *data, uint32 count, CssmData &digest);
+	
+	// staged
+	void digest(const CssmData &data) { digest(&data, 1); }
+	void digest(const CssmData *data, uint32 count);
+	void operator () (CssmData &digest);
+	CssmData operator () () { CssmData digest; (*this)(digest); return digest; }
+	
+protected:
+	void activate();
+};
+
+
+//
+// A [P]RNG context
+//
+class Random : public Context
+{
+public:
+	Random(const CSP &csp, CSSM_ALGORITHMS alg) : Context(csp, alg), mSeed(NULL), mSize(1) { }
+	Random(const CSP &csp, CSSM_ALGORITHMS alg, const CssmCryptoData &seed)
+		: Context(csp, alg), mSeed(&seed), mSize(1) { }
+	Random(const CSP &csp, CSSM_ALGORITHMS alg, uint32 size)
+		: Context(csp, alg), mSeed(NULL), mSize(size) { }
+	Random(const CSP &csp, CSSM_ALGORITHMS alg, const CssmCryptoData &seed, uint32 size)
+		: Context(csp, alg), mSeed(&seed), mSize(size) { }
+	
+	void seed(const CssmCryptoData &data);
+	void size(uint32 size);
+	
+public:
+	void generate(CssmData &data, uint32 size = 0);
+
+	// alternate function-call form
+	CssmData operator () (uint32 size = 0)
+	{ CssmData output; generate(output, size); return output; }
+	
+protected:
+	void activate();
+	
+private:
+	const CssmCryptoData *mSeed;
+	uint32 mSize;
+};
+
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_CSPCLIENT
diff --git a/cdsa/cdsa_client/cssmclient.cpp b/cdsa/cdsa_client/cssmclient.cpp
new file mode 100644
index 00000000..587aa44d
--- /dev/null
+++ b/cdsa/cdsa_client/cssmclient.cpp
@@ -0,0 +1,444 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmclient - common client interface to CSSM and MDS.
+//
+// Locking Strategy (preliminary):
+// XXX This is obsolete update this --mb
+// A CssmObject is a CountingMutex. Its count represents the number of children that have registered
+// themselves (using addChild/removeChild). The lock controls the internal management fields of the
+// various subclasses to protect them against corruption. It does NOT control attribute and argument
+// fields and operations, not does it control object-constant fields.
+// This means that if you use an object from multiple threads, you (the caller) must lock the object
+// during set/get calls of attributes. Note that the CSSM operations themselves are safely multithreaded
+// and thus don't need to be interlocked explicitly.
+//
+#include <Security/cssmclient.h>
+#include <Security/cssmerrno.h>
+
+
+using namespace CssmClient;
+
+//
+// Exception model
+//
+CSSM_RETURN
+Error::cssmError() const
+{
+	//@@@ munge in client-side error codes here?
+	return CssmError::cssmError();
+}
+
+const char *
+Error::what () const
+{
+	return "CSSM client library error";
+}
+
+
+//
+// General utilities
+//
+void
+ObjectImpl::check(CSSM_RETURN status)
+{
+	if (status != CSSM_OK)
+	{
+		CssmError::throwMe(status);
+	}
+}
+
+
+//
+// Common features of Objects
+//
+ObjectImpl::ObjectImpl() : mParent(), mChildCount(0)
+{
+	mActive = false;		// not activated
+	mAllocator = NULL;		// allocator to be determined
+}
+
+ObjectImpl::ObjectImpl(const Object &mommy) : mParent(mommy.mImpl), mChildCount(0)
+{
+	mActive = false;		// not activated
+	mAllocator = NULL;		// allocator to be determined
+	if (mParent)
+		mParent->addChild();
+}
+
+ObjectImpl::~ObjectImpl()
+{
+	assert(!mActive);	// subclass must have deactivated us
+	if (!isIdle())
+		Error::throwMe(Error::objectBusy);
+		
+	// release parent from her obligations (if we still have one)
+	if (mParent)
+		mParent->removeChild();
+}
+
+void
+ObjectImpl::addChild()
+{
+	mChildCount++;		// atomic
+}
+
+void
+ObjectImpl::removeChild()
+{
+	mChildCount--;		// atomic
+}
+
+
+//
+// Manage allocators in the Object tree
+//
+CssmAllocator &
+ObjectImpl::allocator() const
+{
+	if (mAllocator == NULL)
+	{
+		// fix allocator now
+		if (mParent)
+			mAllocator = &mParent->allocator();
+		else
+			mAllocator = &CssmAllocator::standard();
+	}
+
+	return *mAllocator;
+}
+
+void
+ObjectImpl::allocator(CssmAllocator &alloc)
+{
+	assert(mAllocator == NULL);	// cannot redefine allocator once set
+	mAllocator = &alloc;
+}
+
+// Comparison operators use pointer comparison by default.  Subclasses may override.
+bool
+ObjectImpl::operator <(const ObjectImpl &other) const
+{
+	return this < &other;
+}
+
+bool
+ObjectImpl::operator ==(const ObjectImpl &other) const
+{
+	return this == &other;
+}
+
+
+//
+// CSSMSession objects.
+// parent ::= NULL (none)
+// active ::= CSSM initialized
+//
+ModuleNexus<CssmImpl::StandardCssm> CssmImpl::mStandard;
+
+CssmImpl::CssmImpl() : ObjectImpl()
+{
+	setup();
+	mStandard().setCssm(this);
+}
+
+CssmImpl::CssmImpl(bool) : ObjectImpl()
+{
+	setup();
+	// implicitly constructed - caller responsible for standard session management
+}
+
+CssmImpl::~CssmImpl()
+{
+    try
+    {
+		deactivate();
+    }
+	catch(...) {}
+
+	// this may be the standard session...
+    mStandard().unsetCssm(this);
+}
+
+
+void
+CssmImpl::setup()
+{
+	// set default configuration
+	mVersion.Major = 2;
+	mVersion.Minor = 0;
+	mScope = CSSM_PRIVILEGE_SCOPE_PROCESS;
+}
+
+
+Cssm
+CssmImpl::standard()
+{
+    return Cssm(mStandard().get());
+}
+
+
+void
+CssmImpl::activate()
+{
+	if (!mActive)
+	{
+		// currently, no choices on PVC mode and key hierarchy
+		CSSM_PVC_MODE pvc = CSSM_PVC_NONE;
+		//@@@ should handle PVC_ALREADY... non-error
+		check(CSSM_Init(&mVersion, mScope, &mCallerGuid,
+			CSSM_KEY_HIERARCHY_NONE, &pvc, NULL));
+		mActive = true;
+	}
+}
+
+void
+CssmImpl::deactivate()
+{
+	if (mActive)
+	{
+		mActive = false;
+
+		// clear module map (all gone now)
+		moduleMap.erase(moduleMap.begin(), moduleMap.end());
+	
+		// now terminate CSSM
+		check(CSSM_Terminate());
+	}
+}
+
+void
+CssmImpl::atExitHandler()
+{
+    try {
+        mStandard.reset();
+    } catch (...) {
+    }
+}
+
+void
+CssmImpl::catchExit()
+{
+	// @@@ Even though this is the "right thing" to do.  This only causes
+	// exceptions during exit and doesn't really help cleanup correctly.
+#if 0
+	if (::atexit(atExitHandler))
+		UnixError::throwMe();
+#endif
+}
+
+
+//
+// Manage the automatic Cssm object.
+// This is a program global.
+//
+void CssmImpl::StandardCssm::setCssm(CssmImpl *cssm)
+{
+    StLock<Mutex> _(*this);
+    if (mCssm == NULL)
+        mCssm = cssm;
+}
+
+void CssmImpl::StandardCssm::unsetCssm(CssmImpl *cssm)
+{
+    StLock<Mutex> _(*this);
+    if (mCssm == cssm)
+        mCssm = NULL;
+}
+
+CssmImpl *CssmImpl::StandardCssm::get()
+{
+    StLock<Mutex> _(*this);
+    if (mCssm == NULL) {	// make the default instance
+        mCssm = new CssmImpl(true);
+    }
+    return mCssm;
+}
+
+CssmImpl::StandardCssm::~StandardCssm()
+{
+    if (mCssm) {
+        mCssm->deactivate();
+        delete mCssm;
+    }
+}
+
+
+//
+// Auto-module management
+//
+Module
+CssmImpl::autoModule(const Guid &guid)
+{
+	StLock<Mutex> _(mapLock);
+	ModuleMap::iterator it = moduleMap.find(guid);
+	if (it == moduleMap.end())
+	{
+		// no automodule for this guid yet, create one
+		Module module(guid, Cssm(this));
+		moduleMap.insert(ModuleMap::value_type(guid, module));
+		return module;
+	}
+	else
+	{
+		// existing automodule - use it
+		return it->second;
+	}
+}
+
+
+//
+// Module objects.
+// parent ::= the session object (usually Cssm::standard)
+// active ::= module is loaded.
+//
+ModuleImpl::ModuleImpl(const Guid &guid) : ObjectImpl(Cssm::standard())
+{
+	setGuid(guid);
+}
+
+ModuleImpl::ModuleImpl(const Guid &guid, const Cssm &session) : ObjectImpl(session)
+{
+	setGuid(guid);
+}
+
+ModuleImpl::~ModuleImpl()
+{
+	unload();
+}
+
+
+void
+ModuleImpl::activate()
+{
+	if (!mActive)
+	{
+		session()->init();
+		// @@@ install handler here (use central dispatch with override)
+		check(CSSM_ModuleLoad(&guid(), CSSM_KEY_HIERARCHY_NONE, NULL, NULL));
+		mActive = true;
+		session()->catchExit();
+	}
+}
+
+void
+ModuleImpl::deactivate()
+{
+	if (!isIdle())
+		Error::throwMe(Error::objectBusy);
+	if (mActive)
+	{
+		mActive = false;
+		check(CSSM_ModuleUnload(&guid(), NULL, NULL));
+	}
+}
+
+Cssm
+ModuleImpl::session() const
+{
+	return parent<Cssm>();
+}
+
+
+//
+// CssmAttachment objects.
+// parent ::= the loaded module object.
+// active ::= attached.
+//
+AttachmentImpl::AttachmentImpl(const Guid &guid, CSSM_SERVICE_TYPE subserviceType)
+: ObjectImpl(CssmImpl::standard()->autoModule(guid))
+{
+	make(subserviceType);
+}
+
+AttachmentImpl::AttachmentImpl(const Module &module, CSSM_SERVICE_TYPE subserviceType)
+: ObjectImpl(module)
+{
+	make(subserviceType);
+}
+
+AttachmentImpl::~AttachmentImpl()
+{
+	detach();
+}
+
+void
+AttachmentImpl::make(CSSM_SERVICE_TYPE subserviceType)
+{
+	// default configuration
+	mVersion.Major = 2;
+	mVersion.Minor = 0;
+	mSubserviceType = subserviceType;
+	mSubserviceId = 0;
+	mAttachFlags = 0;
+}
+
+void
+AttachmentImpl::activate()
+{
+	if (!mActive)
+	{
+		module()->load();
+		mMemoryFunctions = CssmAllocatorMemoryFunctions(allocator());
+		check(CSSM_ModuleAttach(&guid(), &mVersion,
+			  &mMemoryFunctions,
+			  mSubserviceId,
+			  mSubserviceType,
+			  mAttachFlags,
+			  CSSM_KEY_HIERARCHY_NONE,
+			  NULL, 0,	// no function pointer table return
+			  NULL,		// reserved
+			  &mHandle));
+		mActive = true;
+	}
+}
+
+void
+AttachmentImpl::deactivate()
+{
+	if (mActive)
+	{
+		mActive = false;
+		check(CSSM_ModuleDetach(mHandle));
+	}
+}
+
+CSSM_SERVICE_MASK
+AttachmentImpl::subserviceMask() const
+{
+	return mSubserviceType;
+}
+
+void
+AttachmentImpl::subserviceId(uint32 id)
+{
+	mSubserviceId = id;
+}
+
+CssmSubserviceUid
+AttachmentImpl::subserviceUid() const
+{
+	return CssmSubserviceUid(guid(), &mVersion, mSubserviceId, subserviceMask());
+}
+
+Module
+AttachmentImpl::module() const
+{
+	return parent<Module>();
+}
diff --git a/cdsa/cdsa_client/cssmclient.h b/cdsa/cdsa_client/cssmclient.h
new file mode 100644
index 00000000..725fcbf8
--- /dev/null
+++ b/cdsa/cdsa_client/cssmclient.h
@@ -0,0 +1,364 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmclient - common client interface to CSSM and MDS
+//
+#ifndef _H_CDSA_CLIENT_CSSMCLIENT
+#define _H_CDSA_CLIENT_CSSMCLIENT  1
+
+#include <Security/utilities.h>
+#include <Security/threading.h>
+#include <Security/globalizer.h>
+#include <Security/cssmalloc.h>
+#include <Security/refcount.h>
+#include <map>
+#include <stdio.h>	// debug
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+//
+// Forward declarations
+//
+class Cssm;
+class Module;
+class Attachment;
+
+
+//
+// An mixin for objects that have (store) GUIDs.
+// The GUID value is meant to be set-once constant, and can be locked handled accordingly.
+//
+class HasGuid {
+public:
+	HasGuid(const Guid &guid) { mGuid = guid; }
+	HasGuid() { }
+	
+	const Guid &guid() const { return mGuid; }
+
+protected:
+	void setGuid(const Guid &guid) { mGuid = guid; }
+	
+private:
+	Guid mGuid;
+};
+
+
+//
+// A CssmData initialized from a string constant.
+// Note that the trailing null terminator is not part of the Data.
+//
+// @@@ This is obsoleted by CssmPolyData in <cdsa_utilities/cssmdata.h>
+class StringData : public CssmData {
+public:
+	StringData(const char *s) : CssmData(const_cast<char *>(s), strlen(s)) { }
+	operator char * () const { return CssmData::operator char * (); }
+};
+
+
+//
+// Exceptions are based on the CssmError utility class. We add our own class of client-side exceptions.
+//
+class Error : public CssmError {
+public:
+	Error(int err) : CssmError(err) { }
+	CSSM_RETURN cssmError() const;
+	virtual const char *what () const;
+	
+	enum {
+		objectBusy = -1,
+	};
+};
+
+
+//
+// A CssmData bundled up with a data buffer it refers to
+//
+template <size_t size>
+struct DataBuffer : public CssmData {
+	unsigned char buffer[size];
+	DataBuffer() : CssmData(buffer, size) { }
+};
+
+
+//
+// The CssmObject abstract class models features common to different Cssm objects.
+// It handles a tree hierarchy of objects (parent/children) safely.
+//
+class Object;
+
+class ObjectImpl : virtual public RefCount
+{
+public:
+	explicit ObjectImpl(); // Constructor for Impl objects without a parent.
+	explicit ObjectImpl(const Object &parent);
+	virtual ~ObjectImpl();
+
+	bool isActive() const { return mActive; }
+
+	virtual CssmAllocator &allocator() const;
+	virtual void allocator(CssmAllocator &alloc);
+
+	// Pointer comparison by default.  Subclasses may override.
+	virtual bool operator <(const ObjectImpl &other) const;
+	virtual bool operator ==(const ObjectImpl &other) const;
+
+	static void check(CSSM_RETURN status);
+
+protected:
+	bool mActive;					// loaded, attached, etc.
+	mutable CssmAllocator *mAllocator; // allocator hierarchy (NULL => TBD)
+	
+	template <class Obj> Obj parent() const
+	{ assert(mParent); return Obj(static_cast<typename Obj::Impl *>(&(*mParent))); }
+
+	void addChild();
+	void removeChild();
+	bool isIdle() const { return mChildCount == 0; }
+
+	// {de,}allocate() assume you have locked *this
+	virtual void activate() = 0;
+	virtual void deactivate() = 0;
+
+private:
+	RefPointer<ObjectImpl> mParent;		// parent object
+	AtomicCounter<uint32> mChildCount;
+};
+
+
+
+
+class Object
+{
+	friend class ObjectImpl;
+public:
+	typedef ObjectImpl Impl;
+	explicit Object(Impl *impl) : mImpl(impl) {}
+
+protected:
+	// @@@ CSPDL subclass breaks if the is a static_cast
+	template <class _Impl> _Impl &impl() const
+	{ return dynamic_cast<_Impl &>(*mImpl); }
+
+public:
+	Impl *operator ->() const { return &(*mImpl); }
+	Impl &operator *() const { return *mImpl; }
+
+	// @@@ Why is this needed.  DbCursor which inheirits from Object wants to call this.
+	template <class _Impl> _Impl &checkedImpl() const
+	{ return dynamic_cast<_Impl &>(*mImpl); }
+
+	bool operator !() const { return !mImpl; }
+	operator bool() const { return mImpl; }
+
+	bool operator <(const Object &other) const
+	{ return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl < other.mImpl; }
+	bool operator ==(const Object &other) const
+	{ return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl == other.mImpl; }
+
+private:
+	RefPointer<Impl> mImpl;
+};
+
+
+//
+// A CSSM loadable module.
+// You rarely directly interact with these objects, but if you need to,
+// here they are.
+//
+class ModuleImpl : public ObjectImpl, public HasGuid
+{
+public:
+	ModuleImpl(const Guid &guid);
+	ModuleImpl(const Guid &guid, const Cssm &session);
+	virtual ~ModuleImpl();
+	
+	void load() { activate(); }
+	void unload() { deactivate(); }
+	bool isLoaded() const { return isActive(); }
+	
+	Cssm session() const;
+
+protected:
+	void activate();
+	void deactivate();
+};
+
+class Module : public Object
+{
+public:
+	typedef ModuleImpl Impl;
+	explicit Module(Impl *impl) : Object(impl) {}
+	Module() : Object(NULL) {} // XXX This might break operator <
+	Module(const Guid &guid) : Object(new Impl(guid)) {}
+	Module(const Guid &guid, const Cssm &session) : Object(new Impl(guid, session)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+};
+
+
+//
+// An Attachment object. This is the parent of all typed attachment classes.
+//
+class AttachmentImpl : public ObjectImpl
+{
+public:
+	AttachmentImpl(const Guid &guid, CSSM_SERVICE_TYPE subserviceType);
+	AttachmentImpl(const Module &module, CSSM_SERVICE_TYPE subserviceType);
+	//AttachmentImpl(... mds reference ...);
+	virtual ~AttachmentImpl();
+
+	// Virtual so that subclasses can return there true mask.
+	virtual CSSM_SERVICE_MASK subserviceMask() const;
+
+	CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; }
+	CSSM_VERSION version() const { return mVersion; }
+	void version(const CSSM_VERSION &v) { mVersion = v; }
+	uint32 subserviceId() const { return mSubserviceId; }
+	virtual void subserviceId(uint32 id);
+	CSSM_ATTACH_FLAGS flags() const { return mAttachFlags; }
+	void flags(CSSM_ATTACH_FLAGS f) { mAttachFlags = f; }
+
+	void attach() { activate(); }
+	void detach() { deactivate(); }
+	bool attached() const { return isActive(); }
+
+	Module module() const;
+	const Guid &guid() const { return module()->guid(); }
+	CSSM_MODULE_HANDLE handle() { attach(); return mHandle; }
+
+	CssmSubserviceUid subserviceUid() const;
+
+protected:
+	void activate();
+	void deactivate();
+
+private:
+	void make(CSSM_SERVICE_TYPE subserviceType);	// common constructor
+
+	CSSM_MODULE_HANDLE mHandle;
+
+	CSSM_SERVICE_TYPE mSubserviceType;				// set by constructor
+	CSSM_VERSION mVersion;
+	uint32 mSubserviceId;
+	CSSM_ATTACH_FLAGS mAttachFlags;
+
+	CssmAllocatorMemoryFunctions mMemoryFunctions;	// set on attach()
+};
+
+class Attachment : public Object
+{
+public:
+	typedef AttachmentImpl Impl;
+	explicit Attachment(Impl *impl) : Object(impl) {}
+	Attachment(const Guid &guid, CSSM_SERVICE_TYPE subserviceType)
+	: Object(new Impl(guid, subserviceType)) {}
+	Attachment(const Module &module, CSSM_SERVICE_TYPE subserviceType)
+	: Object(new Impl(module, subserviceType)) {}
+	//Attachment(... mds reference ...);
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+};
+
+
+//
+// A CSSM session object.
+// You usually only have one per program, or library, or what-not.
+//
+class Cssm;
+
+class CssmImpl : public ObjectImpl {
+    class StandardCssm; friend class StandardCssm;
+public:
+	CssmImpl();
+	virtual ~CssmImpl();
+
+	void init() { activate(); }
+	void terminate() { deactivate(); }
+
+	CSSM_PRIVILEGE_SCOPE scope() const { return mScope; }
+	void scope(CSSM_PRIVILEGE_SCOPE sc) { mScope = sc; }
+	const Guid &callerGuid() const { return mCallerGuid; }
+	void callerGuid(const CSSM_GUID &guid) { mCallerGuid = Guid::overlay(guid); }
+
+	Module autoModule(const Guid &guid);
+    
+protected:
+	explicit CssmImpl(bool);				// internal constructor
+
+	void setup();							// constructor setup
+
+	void activate();
+	void deactivate();
+
+private:
+	// CSSM global configuration -- picked up on each Init
+	CSSM_VERSION mVersion;
+	CSSM_PRIVILEGE_SCOPE mScope;
+	Guid mCallerGuid;
+
+	// module repository: modules by guid (protected by self)
+	typedef map<Guid, Module> ModuleMap;
+	ModuleMap moduleMap;
+	Mutex mapLock;
+
+public:
+	static Cssm standard();
+	static void catchExit();
+
+private:
+	static void atExitHandler();
+    
+    class StandardCssm : public Mutex {
+    public:
+        StandardCssm() : mCssm(NULL) { }
+        ~StandardCssm();
+        void setCssm(CssmImpl *cssm);
+        void unsetCssm(CssmImpl *cssm);
+        CssmImpl *get();
+        
+    private:
+        CssmImpl *mCssm;
+    };
+    static ModuleNexus<StandardCssm> mStandard;
+};
+
+class Cssm : public Object
+{
+public:
+	typedef CssmImpl Impl;
+	explicit Cssm(Impl *impl) : Object(impl) {}
+	explicit Cssm() : Object(new Impl()) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+
+	static Cssm standard() { return CssmImpl::standard(); }
+};
+
+} // end namespace CssmClient 
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_CSSMCLIENT
diff --git a/cdsa/cdsa_client/dlclient.cpp b/cdsa/cdsa_client/dlclient.cpp
new file mode 100644
index 00000000..3ebdf52f
--- /dev/null
+++ b/cdsa/cdsa_client/dlclient.cpp
@@ -0,0 +1,510 @@
+/*
+ * 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.
+ */
+
+
+//
+// dlclient - client interface to CSSM DLs and their operations
+//
+#include <Security/dlclient.h>
+
+using namespace CssmClient;
+
+
+//
+// Manage DL attachments
+//
+DLImpl::DLImpl(const Guid &guid) : AttachmentImpl(guid, CSSM_SERVICE_DL)
+{
+}
+
+DLImpl::DLImpl(const Module &module) : AttachmentImpl(module, CSSM_SERVICE_DL)
+{
+}
+
+DLImpl::~DLImpl()
+{
+}
+
+void
+DLImpl::getDbNames(char **)
+{
+	CssmError::throwMe(CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+DLImpl::freeNameList(char **)
+{
+	CssmError::throwMe(CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED);
+}
+
+DbImpl *
+DLImpl::newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
+{
+	return new DbImpl(DL(this), inDbName, inDbLocation);
+}
+
+
+//
+// Db (database)
+//
+DbImpl::DbImpl(const DL &dl, const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
+: ObjectImpl(dl), mDbName(inDbName, inDbLocation),
+mAccessRequest(CSSM_DB_ACCESS_READ), mAccessCredentials(NULL),
+mOpenParameters(NULL), mDbInfo(NULL), mResourceControlContext(NULL)
+{
+}
+
+DbImpl::~DbImpl()
+{
+	try
+	{
+		deactivate();
+	}
+	catch(...) {}
+}
+
+void
+DbImpl::open()
+{
+	if (!mActive)
+	{
+		assert(mDbInfo == nil);
+		mHandle.DLHandle = dl()->handle();
+		check(CSSM_DL_DbOpen(mHandle.DLHandle, name(), dbLocation(),
+								mAccessRequest, mAccessCredentials,
+								mOpenParameters, &mHandle.DBHandle));
+		mActive = true;
+	}
+}
+
+void
+DbImpl::create()
+{
+	if (mActive)
+		CssmError::throwMe(CSSMERR_DL_DATASTORE_ALREADY_EXISTS);
+
+	assert(mDbInfo != nil);
+	mHandle.DLHandle = dl()->handle();
+	check(CSSM_DL_DbCreate(mHandle.DLHandle, name(), dbLocation(), mDbInfo,
+							mAccessRequest, mResourceControlContext,
+							mOpenParameters, &mHandle.DBHandle));
+	mActive = true;
+}
+
+void
+DbImpl::close()
+{
+	check(CSSM_DL_DbClose(mHandle));
+}
+
+void
+DbImpl::activate()
+{
+	if (!mActive)
+	{
+		if (mDbInfo)
+			create();
+		else
+			open();
+	}
+}
+
+void
+DbImpl::deactivate()
+{
+	if (mActive)
+	{
+		mActive = false;
+		close();
+	}
+}
+
+void
+DbImpl::deleteDb()
+{
+	// This call does not require the receiver to be active.
+	check(CSSM_DL_DbDelete(dl()->handle(), name(), dbLocation(),
+						   mAccessCredentials));
+}
+
+void
+DbImpl::authenticate(CSSM_DB_ACCESS_TYPE inAccessRequest,
+					 const CSSM_ACCESS_CREDENTIALS *inAccessCredentials)
+{
+	if (!mActive)
+	{
+		// XXX Could do the same for create but this would require sticking
+		// inAccessCredentials into mResourceControlContext.
+		if (!mDbInfo)
+		{
+			// We were not yet active.  Just do an open.
+			accessRequest(inAccessRequest);
+			accessCredentials(inAccessCredentials);
+			activate();
+			return;
+		}
+	}
+
+	check(CSSM_DL_Authenticate(handle(), inAccessRequest, inAccessCredentials));
+}
+
+void
+DbImpl::name(char *&outDbName)
+{
+	check(CSSM_DL_GetDbNameFromHandle(handle(), &outDbName));
+}
+
+void
+DbImpl::createRelation(CSSM_DB_RECORDTYPE inRelationID,
+							 const char *inRelationName,
+							 uint32 inNumberOfAttributes,
+							 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
+							 uint32 inNumberOfIndexes,
+							 const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo)
+{
+	check(CSSM_DL_CreateRelation(handle(), inRelationID, inRelationName,
+								 inNumberOfAttributes, pAttributeInfo,
+								 inNumberOfIndexes, pIndexInfo));
+}
+
+void
+DbImpl::destroyRelation(CSSM_DB_RECORDTYPE inRelationID)
+{
+	check(CSSM_DL_DestroyRelation(handle(), inRelationID));
+}
+
+DbUniqueRecord
+DbImpl::insert(CSSM_DB_RECORDTYPE recordType, const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+				 const CSSM_DATA *data)
+{
+	DbUniqueRecord uniqueId(Db(this));
+	check(CSSM_DL_DataInsert(handle(), recordType,
+							 attributes,
+							 data, uniqueId));
+	// Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope.
+	uniqueId->activate();
+	return uniqueId;
+}
+
+#if 0
+// @@@ These methods have been moved to DbUniqueRecord.
+void
+DbImpl::deleteRecord(const DbUniqueRecord &uniqueId)
+{
+	check(CSSM_DL_DataDelete(handle(), uniqueId));
+}
+
+void
+DbImpl::modify(CSSM_DB_RECORDTYPE recordType, DbUniqueRecord &uniqueId,
+				 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+				 const CSSM_DATA *data,
+				 CSSM_DB_MODIFY_MODE modifyMode)
+{
+	check(CSSM_DL_DataModify(handle(), recordType, uniqueId,
+							 attributes,
+							 data, modifyMode));
+}
+
+void
+DbImpl::get(const DbUniqueRecord &uniqueId, DbAttributes *attributes,
+			  ::CssmDataContainer *data)
+{
+	if (attributes)
+		attributes->deleteValues();
+
+	if (data)
+		data->clear();
+
+	// @@@ Fix the const_cast here.
+	check(CSSM_DL_DataGetFromUniqueRecordId(handle(), uniqueId,
+											attributes,
+											data));
+}
+#endif
+
+//
+// Passthrough functions (only implemented by AppleCSPDL).
+//
+void
+DbImpl::lock()
+{
+	check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_LOCK, NULL, NULL));
+}
+
+void
+DbImpl::unlock()
+{
+	check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_UNLOCK, NULL, NULL));
+}
+
+void
+DbImpl::unlock(const CSSM_DATA &password)
+{
+	check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_UNLOCK, &password, NULL));
+}
+
+void
+DbImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
+{
+	CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR settings;
+	check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_GET_SETTINGS,
+							  NULL, reinterpret_cast<void **>(&settings)));
+	outIdleTimeout = settings->idleTimeout;
+	outLockOnSleep = settings->lockOnSleep;
+	allocator().free(settings);
+}
+
+void
+DbImpl::setSettings(uint32 inIdleTimeout, bool inLockOnSleep)
+{
+	CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS settings;
+	settings.idleTimeout = inIdleTimeout;
+	settings.lockOnSleep = inLockOnSleep;
+	check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_SET_SETTINGS, &settings, NULL));
+}
+
+bool
+DbImpl::isLocked()
+{
+	CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR params;
+	check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_IS_LOCKED,
+							  NULL, reinterpret_cast<void **>(&params)));
+	bool isLocked = params->isLocked;
+	allocator().free(params);
+	return isLocked;
+}
+
+void
+DbImpl::changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS params;
+	params.accessCredentials = const_cast<CSSM_ACCESS_CREDENTIALS *>(cred);
+	check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_CHANGE_PASSWORD, &params, NULL));
+}
+
+
+//
+// DbCursorMaker
+//
+DbCursorImpl *
+DbImpl::newDbCursor(const CSSM_QUERY &query, CssmAllocator &allocator)
+{
+	return new DbDbCursorImpl(Db(this), query, allocator);
+}
+
+DbCursorImpl *
+DbImpl::newDbCursor(uint32 capacity, CssmAllocator &allocator)
+{
+	return new DbDbCursorImpl(Db(this), capacity, allocator);
+}
+
+//
+// DbUniqueRecordMaker
+//
+DbUniqueRecordImpl *
+DbImpl::newDbUniqueRecord()
+{
+	return new DbUniqueRecordImpl(Db(this));
+}
+
+
+//
+// Utility methods
+//
+DLDbIdentifier
+DbImpl::dlDbIdentifier() const
+{
+	return DLDbIdentifier(dl()->subserviceUid(), name(), dbLocation());
+}
+
+
+//
+// DbDbCursorImpl
+//
+DbDbCursorImpl::DbDbCursorImpl(const Db &db, const CSSM_QUERY &query, CssmAllocator &allocator)
+: DbCursorImpl(db, query, allocator), mResultsHandle(CSSM_INVALID_HANDLE)
+{
+}
+
+DbDbCursorImpl::DbDbCursorImpl(const Db &db, uint32 capacity, CssmAllocator &allocator)
+: DbCursorImpl(db, capacity, allocator), mResultsHandle(CSSM_INVALID_HANDLE)
+{
+}
+
+DbDbCursorImpl::~DbDbCursorImpl()
+{
+	try
+	{
+		deactivate();
+	}
+	catch(...) {}
+}
+
+bool
+DbDbCursorImpl::next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId)
+{
+	if (attributes)
+		attributes->deleteValues();
+
+	if (data)
+		data->clear();
+
+	CSSM_RETURN result;
+	Db db(database());
+	DbUniqueRecord unique(db);
+	if (!mActive)
+	{
+		result = CSSM_DL_DataGetFirst(db->handle(),
+									  this,
+									  &mResultsHandle,
+									  attributes,
+									  data,
+									  unique);
+		if (result == CSSM_OK)
+			mActive = true;
+	}
+	else
+	{
+		result = CSSM_DL_DataGetNext(db->handle(),
+									 mResultsHandle,
+									 attributes,
+									 data,
+									 unique);
+	}
+
+	if (result == CSSMERR_DL_ENDOFDATA)
+	{
+		mActive = false;
+		return false;
+	}
+
+	check(result);
+
+	// Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope.
+	unique->activate();
+	uniqueId = unique;
+	return true;
+}
+
+void
+DbDbCursorImpl::activate()
+{
+}
+
+void
+DbDbCursorImpl::deactivate()
+{
+	if (mActive)
+	{
+		mActive = false;
+		check(CSSM_DL_DataAbortQuery(database()->handle(), mResultsHandle));
+	}
+}
+
+
+//
+// DbCursorImpl
+//
+DbCursorImpl::DbCursorImpl(const Object &parent, const CSSM_QUERY &query, CssmAllocator &allocator) :
+ObjectImpl(parent), CssmAutoQuery(query, allocator)
+{
+}
+
+DbCursorImpl::DbCursorImpl(const Object &parent, uint32 capacity, CssmAllocator &allocator) :
+ObjectImpl(parent), CssmAutoQuery(capacity, allocator)
+{
+}
+
+
+//
+// DbUniqueRecord
+//
+DbUniqueRecordImpl::DbUniqueRecordImpl(const Db &db) : ObjectImpl(db)
+{
+}
+
+DbUniqueRecordImpl::~DbUniqueRecordImpl()
+{
+	try
+	{
+		deactivate();
+	}
+	catch(...) {}
+}
+
+void
+DbUniqueRecordImpl::deleteRecord()
+{
+	check(CSSM_DL_DataDelete(database()->handle(), mUniqueId));
+}
+
+void
+DbUniqueRecordImpl::modify(CSSM_DB_RECORDTYPE recordType,
+						   const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+						   const CSSM_DATA *data,
+						   CSSM_DB_MODIFY_MODE modifyMode)
+{
+	check(CSSM_DL_DataModify(database()->handle(), recordType, mUniqueId,
+							 attributes,
+							 data, modifyMode));
+}
+
+void
+DbUniqueRecordImpl::get(DbAttributes *attributes,
+						::CssmDataContainer *data)
+{
+	if (attributes)
+		attributes->deleteValues();
+
+	if (data)
+		data->clear();
+
+	// @@@ Fix the allocators for attributes and data.
+	check(CSSM_DL_DataGetFromUniqueRecordId(database()->handle(), mUniqueId,
+											attributes,
+											data));
+}
+
+void
+DbUniqueRecordImpl::activate()
+{
+	mActive = true;
+}
+
+void
+DbUniqueRecordImpl::deactivate()
+{
+	if (mActive)
+	{
+		mActive = false;
+		check(CSSM_DL_FreeUniqueRecord(database()->handle(), mUniqueId));
+	}
+}
+
+
+//
+// DbAttributes
+//
+DbAttributes::DbAttributes()
+:  CssmAutoDbRecordAttributeData(0, CssmAllocator::standard(), CssmAllocator::standard())
+{
+}
+
+DbAttributes::DbAttributes(const Db &db, uint32 capacity, CssmAllocator &allocator)
+:  CssmAutoDbRecordAttributeData(capacity, db->allocator(), allocator)
+{
+}
diff --git a/cdsa/cdsa_client/dlclient.h b/cdsa/cdsa_client/dlclient.h
new file mode 100644
index 00000000..e0dfe1df
--- /dev/null
+++ b/cdsa/cdsa_client/dlclient.h
@@ -0,0 +1,484 @@
+/*
+ * 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.
+ */
+
+
+//
+// dlclient - client interface to CSSM DLs and their operations
+//
+
+#ifndef _H_CDSA_CLIENT_DLCLIENT
+#define _H_CDSA_CLIENT_DLCLIENT  1
+
+#include <Security/cssmclient.h>
+#include <Security/DLDBList.h>
+#include <Security/cssmacl.h>
+#include <Security/cssmdb.h>
+#include <Security/cssmdata.h>
+
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+#define CSSM_DB_ATTR(ATTR) ATTR
+#define CSSM_DB_ATTR_SCHEMA(ATTR) ATTR ## Schema
+
+#define CSSM_DB_INDEX(ATTR) ATTR ## Index
+#define CSSM_DB_UNIQUE(ATTR) ATTR ## Unique
+
+//
+// Helper macro for declaring and defining a Db index unique and non-unique attributes
+//
+#define CSSM_DB_INDEX_DECL(ATTR)  static const CSSM_DB_INDEX_INFO CSSM_DB_INDEX(ATTR)
+#define CSSM_DB_UNIQUE_DECL(ATTR)  static const CSSM_DB_INDEX_INFO CSSM_DB_UNIQUE(ATTR)
+
+
+//
+// Use this macro for defining a non-unique attribute
+//
+#define CSSM_DB_INDEX_DEF(ATTR) \
+const CSSM_DB_INDEX_INFO CSSM_DB_INDEX(ATTR) = \
+{ \
+	CSSM_DB_INDEX_NONUNIQUE, \
+	CSSM_DB_INDEX_ON_ATTRIBUTE, \
+	CSSM_DB_ATTR(ATTR) \
+}
+
+//
+//  Use this macro for defining a unique attribute
+
+//
+#define CSSM_DB_UNIQUE_DEF(ATTR) \
+const CSSM_DB_INDEX_INFO CSSM_DB_UNIQUE(ATTR) = \
+{ \
+	CSSM_DB_INDEX_UNIQUE, \
+	CSSM_DB_INDEX_ON_ATTRIBUTE, \
+	CSSM_DB_ATTR(ATTR) \
+}
+
+
+
+//
+// Helper macro for declaring and defining a Db schema attributes
+// Use this macro in your header to declare each attribute you require.
+//
+#define CSSM_DB_ATTR_DECL(ATTR) \
+static const CSSM_DB_ATTRIBUTE_INFO CSSM_DB_ATTR(ATTR); \
+static const CSSM_DB_SCHEMA_ATTRIBUTE_INFO CSSM_DB_ATTR_SCHEMA(ATTR)
+
+//
+// Don't directly use this macro use one of the below instead.
+//
+#define CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE) \
+const CSSM_DB_SCHEMA_ATTRIBUTE_INFO CSSM_DB_ATTR_SCHEMA(ATTR) = \
+{ \
+	INTEGER, \
+	NAME, \
+	{ OID_LEN, OID_DATA }, \
+	CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
+}
+
+
+//
+// Use one of the following macros to defined each declared attribute required by your application.
+//
+//
+// Use this macro to define attributes which are looked up by integer AttributeID.
+//
+#define CSSM_DB_INTEGER_ATTR(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE) \
+const CSSM_DB_ATTRIBUTE_INFO ATTR = \
+{ \
+    CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, \
+    {(char *)INTEGER}, \
+    CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
+};\
+\
+CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE)
+
+//
+// Use this macro to define attributes which are looked up by string AttributeName.
+//
+#define CSSM_DB_NAME_ATTR(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE) \
+const CSSM_DB_ATTRIBUTE_INFO ATTR = \
+{ \
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING, \
+    {NAME}, \
+    CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
+};\
+\
+CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE)
+
+//
+// Use this macro to define attributes which are looked up by OID AttributeNameID.
+// XXX This does not work yet.
+//
+#define CSSM_DB_OID_ATTR(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE) \
+const CSSM_DB_ATTRIBUTE_INFO ATTR = \
+{ \
+    CSSM_DB_ATTRIBUTE_NAME_AS_OID, \
+    {{OID_LEN, OID_DATA}}, \
+    CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
+};\
+\
+CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE)
+
+
+//
+// Use this macro to define attributes which are part of the primary key.
+//
+#define CSSM_DB_PRIMARKEY_ATTR(ATTR, NAME) \
+const CSSM_DB_ATTRIBUTE_INFO ATTR = \
+{ \
+    CSSM_DB_INDEX_UNIQUE, \
+    CSSM_DB_INDEX_ON_ATTRIBUTE, \
+    CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
+};\
+\
+CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE)
+
+
+
+//
+// Maker interfaces used by various Impl objects
+//
+
+// DbMaker -- someone who can create a new DbImpl.
+class DbImpl;
+class DbMaker
+{
+public:
+	virtual DbImpl *newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation) = 0;
+};
+
+// DbCursorMaker -- someone who can create a new DbCursorImpl.
+class DbCursorImpl;
+class DbCursorMaker
+{
+public:
+	virtual DbCursorImpl *newDbCursor(const CSSM_QUERY &query, CssmAllocator &allocator) = 0;
+	virtual DbCursorImpl *newDbCursor(uint32 capacity, CssmAllocator &allocator) = 0;
+};
+
+// DbUniqueRecordMaker -- someone who can create a new DbUniqueRecordImpl.
+class DbUniqueRecordImpl;
+class DbUniqueRecordMaker
+{
+public:
+	virtual DbUniqueRecordImpl *newDbUniqueRecord() = 0;
+};
+
+
+//
+// A DL attachment
+//
+class DLImpl : public AttachmentImpl, public DbMaker
+{
+public:
+	DLImpl(const Guid &guid);
+	DLImpl(const Module &module);
+	virtual ~DLImpl();
+
+	virtual void getDbNames(char **);
+	virtual void freeNameList(char **);
+
+	// DbMaker
+	virtual DbImpl *newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
+private:
+};
+
+class DL : public Attachment
+{
+public:
+	typedef DLImpl Impl;
+
+	explicit DL(Impl *impl) : Attachment(impl) {}
+	DL() : Attachment(NULL) {}
+	DL(const Guid &guid) : Attachment(new Impl(guid)) {}
+	DL(const Module &module) : Attachment(new Impl(module)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+
+	// Conversion to DbMaker.
+	operator DbMaker &() const { return impl<Impl>(); }
+};
+
+
+class DbAttributes;
+class DbUniqueRecord;
+
+
+//
+// A CSSM_DLDB handle.
+// Dbs always belong to DLs (DL attachments)
+//
+class DbImpl : public ObjectImpl, public DbCursorMaker, public DbUniqueRecordMaker
+{
+public:
+	DbImpl(const DL &dl, const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
+	virtual ~DbImpl();
+
+	DL dl() const { return parent<DL>(); }
+	Module module() const { return dl()->module(); }
+
+	virtual void open();
+	virtual void create();
+	virtual void close();
+	virtual void deleteDb();
+	virtual void authenticate(CSSM_DB_ACCESS_TYPE inAccessRequest,
+								const CSSM_ACCESS_CREDENTIALS *inAccessCredentials);
+	virtual void name(char *&outName);	// CSSM_DL_GetDbNameFromHandle()
+
+	virtual void createRelation(CSSM_DB_RECORDTYPE inRelationID,
+								const char *inRelationName,
+								uint32 inNumberOfAttributes,
+								const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
+								uint32 inNumberOfIndexes,
+								const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo);
+	virtual void destroyRelation(CSSM_DB_RECORDTYPE inRelationID);
+
+	virtual DbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
+									const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+									const CSSM_DATA *data);
+
+#if 0
+	// @@@ These methods have been moved to DbUniqueRecord.
+	virtual void deleteRecord(const DbUniqueRecord &uniqueId);
+	virtual void modify(CSSM_DB_RECORDTYPE recordType, DbUniqueRecord &uniqueId,
+						const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+						const CSSM_DATA *data,
+						CSSM_DB_MODIFY_MODE modifyMode);
+	virtual void get(const DbUniqueRecord &uniqueId, DbAttributes *attributes,
+						::CssmDataContainer *data);
+#endif
+
+	const CSSM_DL_DB_HANDLE &handle() { activate(); return mHandle; }
+
+	const DbName &dbName() { return mDbName; }
+	void dbName(const DbName &dbName) { mDbName = dbName; }
+
+	const char *name() const { return mDbName.dbName().c_str(); }
+	const CSSM_NET_ADDRESS *dbLocation() const { return mDbName.dbLocation(); }
+
+	CSSM_DB_ACCESS_TYPE accessRequest() const { return mAccessRequest; }
+	void accessRequest(CSSM_DB_ACCESS_TYPE inAccessRequest)
+	{ mAccessRequest = inAccessRequest; }
+
+	const CSSM_ACCESS_CREDENTIALS *accessCredentials() const
+	{ return mAccessCredentials; }
+	void accessCredentials(const CSSM_ACCESS_CREDENTIALS *inAccessCredentials)
+	{ mAccessCredentials = inAccessCredentials; }
+
+	const void *openParameters() const { return mOpenParameters; }
+	void openParameters(const void *inOpenParameters)
+	{ mOpenParameters = inOpenParameters; }
+
+	const CSSM_DBINFO *dbInfo() const { return mDbInfo; }
+	void dbInfo(const CSSM_DBINFO *inDbInfo) { mDbInfo = inDbInfo; }
+
+	const CSSM_RESOURCE_CONTROL_CONTEXT *resourceControlContext() const
+	{ return mResourceControlContext; }
+	void resourceControlContext(const CSSM_RESOURCE_CONTROL_CONTEXT *inResourceControlContext)
+	{ mResourceControlContext = inResourceControlContext; }
+
+	// Passthrough functions (only implemented by AppleCSPDL).
+	virtual void lock();
+	virtual void unlock();
+	virtual void unlock(const CSSM_DATA &password);
+	virtual void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
+	virtual void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
+	virtual bool isLocked();
+	virtual void changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred);
+
+	// Utility methods
+	virtual DLDbIdentifier dlDbIdentifier() const;
+
+	// DbCursorMaker
+	virtual DbCursorImpl *newDbCursor(const CSSM_QUERY &query, CssmAllocator &allocator);
+	virtual DbCursorImpl *newDbCursor(uint32 capacity, CssmAllocator &allocator);
+
+	// DbUniqueRecordMaker
+	virtual DbUniqueRecordImpl *newDbUniqueRecord();
+
+protected:
+	virtual void activate();
+	virtual void deactivate();
+
+private:
+	CSSM_DL_DB_HANDLE mHandle;			// CSSM DLDB handle
+
+	DbName mDbName;
+	CSSM_DB_ACCESS_TYPE mAccessRequest;
+	const CSSM_ACCESS_CREDENTIALS *mAccessCredentials;
+	const void *mOpenParameters;
+
+	// Arguments to create
+	const CSSM_DBINFO *mDbInfo;
+	const CSSM_RESOURCE_CONTROL_CONTEXT *mResourceControlContext;
+};
+
+
+class Db : public Object
+{
+public:
+	typedef DbImpl Impl;
+
+	explicit Db(Impl *impl) : Object(impl) {}
+	Db() : Object(NULL) {}
+	Db(DbMaker &maker, const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation = NULL)
+	: Object(maker.newDb(inDbName, inDbLocation)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+
+	// Conversion to DbCursorMaker.
+	operator DbCursorMaker &() const { return impl<Impl>(); }
+	// Conversion to DbUniqueRecordMaker.
+	operator DbUniqueRecordMaker &() const { return impl<Impl>(); }
+};
+
+//
+// DbCursor
+//
+
+// This class is still abstract.  You must subclass it in order to be able to instantiate an instance.
+class DbCursorImpl : public ObjectImpl, public CssmAutoQuery
+{
+public:
+	DbCursorImpl(const Object &parent, const CSSM_QUERY &query, CssmAllocator &allocator);
+	DbCursorImpl(const Object &parent, uint32 capacity, CssmAllocator &allocator);
+
+	virtual bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId) = 0;
+	void abort() { deactivate(); }
+};
+
+class DbCursor : public Object
+{
+public:
+	typedef DbCursorImpl Impl;
+
+	explicit DbCursor(Impl *impl) : Object(impl) {}
+	DbCursor() : Object(NULL) {}
+	DbCursor(DbCursorMaker &maker, const CSSM_QUERY &query,
+			 CssmAllocator &allocator = CssmAllocator::standard())
+	: Object(maker.newDbCursor(query, allocator)) {}
+	DbCursor(DbCursorMaker &maker, uint32 capacity = 0,
+			 CssmAllocator &allocator = CssmAllocator::standard())
+	: Object(maker.newDbCursor(capacity, allocator)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+};
+
+
+//
+// DbUniqueRecord
+//
+class DbUniqueRecordImpl : public ObjectImpl
+{
+public:
+	DbUniqueRecordImpl(const Db &db);
+	virtual ~DbUniqueRecordImpl();
+
+	virtual void deleteRecord();
+	virtual void modify(CSSM_DB_RECORDTYPE recordType,
+						const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+						const CSSM_DATA *data,
+						CSSM_DB_MODIFY_MODE modifyMode);
+	virtual void get(DbAttributes *attributes, ::CssmDataContainer *data);
+
+	Db database() const { return parent<Db>(); }
+
+	// Client must call activate() after calling this function if mUniqueId is successfully set.
+	operator CSSM_DB_UNIQUE_RECORD_PTR *() { if (mActive) free(); return &mUniqueId; }
+
+	operator CSSM_DB_UNIQUE_RECORD *() { return mUniqueId; }
+	operator const CSSM_DB_UNIQUE_RECORD *() const { return mUniqueId; }
+
+	void free() { deactivate(); }
+
+	void activate();
+
+protected:
+	void deactivate();
+
+	CSSM_DB_UNIQUE_RECORD_PTR mUniqueId;
+};
+
+class DbUniqueRecord : public Object
+{
+public:
+	typedef DbUniqueRecordImpl Impl;
+
+	explicit DbUniqueRecord(Impl *impl) : Object(impl) {}
+	DbUniqueRecord() : Object(NULL) {}
+	DbUniqueRecord(DbUniqueRecordMaker &maker) : Object(maker.newDbUniqueRecord()) {}
+
+	Impl *operator ->() { return &impl<Impl>(); }
+	Impl &operator *() { return impl<Impl>(); }
+	const Impl &operator *() const { return impl<Impl>(); }
+
+	// Conversion operators must be here.
+
+	// Client must activate after calling this function if mUniqueId is successfully set.
+	operator CSSM_DB_UNIQUE_RECORD_PTR *() { return **this; }
+
+	operator CSSM_DB_UNIQUE_RECORD *() { return **this; }
+	operator const CSSM_DB_UNIQUE_RECORD *() const { return **this; }
+};
+
+
+//
+// DbAttributes
+//
+class DbAttributes : public CssmAutoDbRecordAttributeData
+{
+public:
+	DbAttributes();
+	DbAttributes(const Db &db, uint32 capacity = 0, CssmAllocator &allocator = CssmAllocator::standard());
+};
+
+
+//
+// DbDbCursor -- concrete subclass of DbCursorImpl for querying Db's
+//
+class DbDbCursorImpl : public DbCursorImpl
+{
+public:
+	DbDbCursorImpl(const Db &db, const CSSM_QUERY &query, CssmAllocator &allocator);
+	DbDbCursorImpl(const Db &db, uint32 capacity, CssmAllocator &allocator);
+	virtual ~DbDbCursorImpl();
+
+	bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId);
+
+protected:
+	Db database() { return parent<Db>(); }
+
+	void activate();
+	void deactivate();
+
+private:
+	CSSM_HANDLE mResultsHandle;
+};
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_DLCLIENT
diff --git a/cdsa/cdsa_client/genkey.cpp b/cdsa/cdsa_client/genkey.cpp
new file mode 100644
index 00000000..9f99270b
--- /dev/null
+++ b/cdsa/cdsa_client/genkey.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+
+//
+// genkey - client interface to CSSM sign/verify contexts
+//
+#include <Security/genkey.h>
+
+using namespace CssmClient;
+
+
+GenerateKey::GenerateKey(const CSP &csp, CSSM_ALGORITHMS alg, uint32 size)
+: Context(csp, alg), mKeySize(size), mSeed(NULL), mSalt(NULL), mParams(NULL), mInitialAcl(NULL)
+{
+}
+
+void
+GenerateKey::database(const Db &inDb)
+{
+	mDb = inDb;
+	if (mDb && isActive())
+		set(CSSM_ATTRIBUTE_DL_DB_HANDLE, mDb->handle());
+}
+
+void GenerateKey::activate()
+{
+	if (!mActive)
+	{
+		check(CSSM_CSP_CreateKeyGenContext(attachment()->handle(), mAlgorithm,
+			mKeySize, mSeed, mSalt, NULL, NULL, mParams, &mHandle));
+		// Must be done before calling set() since is does nothing unless we are active.
+		// Also we are technically active even if set() throws since we already created a context.
+		mActive = true;
+		if (mDb)
+			set(CSSM_ATTRIBUTE_DL_DB_HANDLE, mDb->handle());
+	}
+}
+
+Key GenerateKey::operator () (const KeySpec &spec)
+{
+	Key key;
+	
+	check(CSSM_GenerateKey(handle(), spec.usage, spec.attributes, spec.label,
+		   mInitialAcl, key.makeNewKey(attachment())));
+		   
+	key->activate();
+	
+	return key;
+}
+
+void GenerateKey::operator () (CssmKey &key, const KeySpec &spec)
+{
+	check(CSSM_GenerateKey(handle(), spec.usage, spec.attributes, spec.label, mInitialAcl, &key));
+
+}
+
+void GenerateKey::operator () (Key &publicKey, const KeySpec &pubSpec,
+		Key &privateKey, const KeySpec &privSpec)
+{
+	check(CSSM_GenerateKeyPair(handle(),
+		pubSpec.usage, pubSpec.attributes,
+		pubSpec.label, publicKey.makeNewKey(attachment()),
+		privSpec.usage, privSpec.attributes,
+		privSpec.label, mInitialAcl, privateKey.makeNewKey(attachment())));
+
+	publicKey->activate();
+	privateKey->activate();
+
+}
+
+void GenerateKey::operator () (CssmKey &publicKey, const KeySpec &pubSpec,
+		CssmKey &privateKey, const KeySpec &privSpec)
+{
+	check(CSSM_GenerateKeyPair(handle(),
+		pubSpec.usage, pubSpec.attributes, pubSpec.label, &publicKey,
+		privSpec.usage, privSpec.attributes, privSpec.label, mInitialAcl, &privateKey));
+}
+
diff --git a/cdsa/cdsa_client/genkey.h b/cdsa/cdsa_client/genkey.h
new file mode 100644
index 00000000..dccbf532
--- /dev/null
+++ b/cdsa/cdsa_client/genkey.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+
+//
+// genkey - client interface to CSSM sign/verify contexts
+//
+#ifndef _H_CDSA_CLIENT_GENKEY
+#define _H_CDSA_CLIENT_GENKEY  1
+
+#include <Security/cspclient.h>
+#include <Security/cryptoclient.h>
+#include <Security/dlclient.h>
+#include <Security/keyclient.h>
+
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+class GenerateKey : public Context {
+public:
+	GenerateKey(const CSP &csp, CSSM_ALGORITHMS alg, uint32 size = 0);
+
+public:
+	
+	// context parameters
+	void size(uint32 s) { mKeySize = s; set(CSSM_ATTRIBUTE_KEY_LENGTH, s); }
+	void seed(const CssmCryptoData &s) { mSeed = &s; set(CSSM_ATTRIBUTE_SEED, s); }
+	void salt(const CssmData &s) { mSalt = &s;set(CSSM_ATTRIBUTE_SALT, s);  }
+	void params(const CssmData &p) { mParams = &p; set(CSSM_ATTRIBUTE_ALG_PARAMS, p); }
+	void database(const Db &inDb);
+
+	// Generation parameters
+	void initialAcl(const ResourceControlContext *rc) { mInitialAcl = rc; }
+
+	// symmetric key generation
+	Key operator () (const KeySpec &spec);
+	void operator () (CssmKey &key, const KeySpec &spec);
+	
+	// asymmetric key generation
+	void operator () (Key &publicKey, const KeySpec &publicSpec,
+		Key &privateKey, const KeySpec &privateSpec);
+	void operator () (CssmKey &publicKey, const KeySpec &publicSpec,
+		CssmKey &privateKey, const KeySpec &privateSpec);
+
+	
+protected:
+	void activate();
+	
+private:
+	// context parameters
+	uint32 mKeySize;
+	const CssmCryptoData *mSeed;
+	const CssmData *mSalt;
+	const CssmData *mParams;
+	Db mDb;
+
+	// generation parameters(?)
+	const ResourceControlContext *mInitialAcl;
+};
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_GENKEY
diff --git a/cdsa/cdsa_client/keychainacl.cpp b/cdsa/cdsa_client/keychainacl.cpp
new file mode 100644
index 00000000..e30db088
--- /dev/null
+++ b/cdsa/cdsa_client/keychainacl.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+
+//
+// keychainacl - Keychain-related ACL and credential forms
+//
+#ifdef __MWERKS__
+#define _CPP_KEYCHAINACL
+#endif
+
+#include "keychainacl.h"
+#include <Security/cssmwalkers.h>
+
+using namespace CssmClient;
+
+
+//
+// Construct the factory.
+// @@@ Leaks.
+//
+KeychainAclFactory::KeychainAclFactory(CssmAllocator &alloc)
+: allocator(alloc), nullCred(alloc, 1), kcCred(alloc, 2), kcUnlockCred(alloc, 1)
+{
+	// the credential objects self-initialize to empty
+	nullCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD);
+	
+	kcCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT);
+	kcCred.sample(1) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD,
+		new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT)));
+
+	// @@@ This leaks a ListElement(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT)
+	kcUnlockCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
+									  new(alloc) ListElement(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT));
+}
+
+KeychainAclFactory::~KeychainAclFactory()
+{
+}
+
+
+//
+// Produce credentials.
+// These are constants that don't need to be allocated per use.
+//
+const AccessCredentials *KeychainAclFactory::nullCredentials()
+{
+	return &nullCred;
+}
+
+const AccessCredentials *KeychainAclFactory::keychainPromptCredentials()
+{
+	return &kcCred;
+}
+
+const AccessCredentials *KeychainAclFactory::keychainPromptUnlockCredentials()
+{
+	return &kcUnlockCred;
+}
+
+const AutoCredentials *KeychainAclFactory::passwordChangeCredentials(const CssmData &password)
+{
+	AutoCredentials *cred = new AutoCredentials(allocator, 1);
+	// @@@ This leaks a ListElement(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT) and ListElement(password)
+	cred->sample(0) = TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
+								new(allocator) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+								new(allocator) ListElement(password));
+	return cred;
+}
+
+const AutoCredentials *KeychainAclFactory::passwordUnlockCredentials(const CssmData &password)
+{
+	AutoCredentials *cred = new AutoCredentials(allocator, 1);
+	// @@@ This leaks a ListElement(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT) and ListElement(password)
+	cred->sample(0) = TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
+								new(allocator) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
+								new(allocator) ListElement(password));
+	return cred;
+}
+
+
+//
+// 
+AclEntryInput *KeychainAclFactory::keychainPromptOwner(const CssmData &description)
+{
+	// @@@ Make sure this works for a NULL description
+	AclEntryPrototype proto(TypedList(allocator, CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT,
+		new(allocator) ListElement(allocator, description)));
+	return new(allocator) AclEntryInput(proto);
+}
+
+AclEntryInput *KeychainAclFactory::anyOwner()
+{
+	AclEntryPrototype proto(TypedList(allocator, CSSM_ACL_SUBJECT_TYPE_ANY));
+	return new(allocator) AclEntryInput(proto);
+}
+
+void KeychainAclFactory::release(AclEntryInput *input)
+{
+	DataWalkers::chunkFree(input, allocator);
+}
+
+
+//
+// ACL editing
+//
+void KeychainAclFactory::comment(TypedList &subject)
+{
+	subject.insert(new(allocator) ListElement(CSSM_ACL_SUBJECT_TYPE_COMMENT),
+		subject.first());
+}
+
+void KeychainAclFactory::uncomment(TypedList &subject)
+{
+	ListElement *first = subject.first();
+	assert(*first == CSSM_ACL_SUBJECT_TYPE_COMMENT);
+	subject -= first;
+	destroy(first, allocator);
+}
diff --git a/cdsa/cdsa_client/keychainacl.h b/cdsa/cdsa_client/keychainacl.h
new file mode 100644
index 00000000..d4650ffc
--- /dev/null
+++ b/cdsa/cdsa_client/keychainacl.h
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+
+//
+// keychainacl - Keychain-related ACL and credential forms
+//
+#ifndef _KEYCHAINACL
+#define _KEYCHAINACL
+
+#include <Security/cssm.h>
+#include <Security/cssmaclpod.h>
+#include <Security/cssmcred.h>
+#include <Security/cssmalloc.h>
+
+#ifdef _CPP_KEYCHAINACL
+# pragma export on
+#endif
+
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+class KeychainAclFactory
+{
+public:
+	KeychainAclFactory(CssmAllocator &alloc);
+	~KeychainAclFactory();
+	
+	CssmAllocator &allocator;
+	
+public:
+	//
+	// Create credentials. These functions return AccessCredentials pointers.
+	//
+	const AccessCredentials *nullCredentials();
+	const AccessCredentials *keychainPromptCredentials();
+	const AccessCredentials *keychainPromptUnlockCredentials();
+	const AutoCredentials *passwordChangeCredentials(const CssmData &password);
+	const AutoCredentials *passwordUnlockCredentials(const CssmData &password);
+
+public:
+	//
+	// Create initial ACLs. Pass those to resource creation functions.
+	//
+	AclEntryInput *keychainPromptOwner(const CssmData &description);
+	AclEntryInput *anyOwner();
+	void release(AclEntryInput *input);
+	
+public:
+	//
+	// Edit ACLs (in external form, as TypedLists)
+	//
+	void comment(TypedList &subject);
+	void uncomment(TypedList &subject);
+	
+private:
+	AutoCredentials nullCred;
+	AutoCredentials kcCred;
+	AutoCredentials kcUnlockCred;
+};
+
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#ifdef _CPP_KEYCHAINACL
+# pragma export off
+#endif
+
+#endif //_KEYCHAINACL
diff --git a/cdsa/cdsa_client/keyclient.cpp b/cdsa/cdsa_client/keyclient.cpp
new file mode 100644
index 00000000..92e3b0a5
--- /dev/null
+++ b/cdsa/cdsa_client/keyclient.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+
+//
+// keyclient
+//
+#include <Security/keyclient.h>
+
+using namespace CssmClient;
+
+
+KeyImpl::KeyImpl(const CSP &csp) : ObjectImpl(csp), CssmKey() 
+{
+	mActive=false;
+}
+
+KeyImpl::KeyImpl(const CSP &csp, CSSM_KEY &key) : ObjectImpl(csp), CssmKey(key) 
+{
+	mActive=true;
+}
+
+KeyImpl::KeyImpl(const CSP &csp, const CSSM_DATA &keyData) : ObjectImpl(csp),
+CssmKey(keyData.Length, csp->allocator().alloc<uint8>(keyData.Length)) 
+{
+	memcpy(KeyData.Data, keyData.Data, keyData.Length);
+	mActive=true;
+}
+
+KeyImpl::~KeyImpl()
+{
+	try
+	{
+		deactivate();
+	}
+	catch(...) {}
+}
+
+void
+KeyImpl::deleteKey(const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	if (mActive)
+	{
+		mActive=false;
+		check(CSSM_FreeKey(csp()->handle(), cred, this, CSSM_TRUE));
+	}
+}
+
+void
+KeyImpl::getAcl(const char *selectionTag, AutoAclEntryInfoList &aclInfos) const
+{
+	aclInfos.allocator(allocator());
+	check(CSSM_GetKeyAcl(csp()->handle(), this, reinterpret_cast<const CSSM_STRING *>(selectionTag), aclInfos, aclInfos));
+}
+
+void
+KeyImpl::changeAcl(const CSSM_ACCESS_CREDENTIALS *accessCred,
+				   const CSSM_ACL_EDIT &aclEdit)
+{
+	check(CSSM_ChangeKeyAcl(csp()->handle(), accessCred, &aclEdit, this));
+}
+
+void
+KeyImpl::getOwner(AutoAclOwnerPrototype &owner) const
+{
+	owner.allocator(allocator());
+	check(CSSM_GetKeyOwner(csp()->handle(), this, owner));
+}
+
+void
+KeyImpl::changeOwner(const CSSM_ACCESS_CREDENTIALS *accessCred,
+					 const CSSM_ACL_OWNER_PROTOTYPE &newOwner)
+{
+	check(CSSM_ChangeKeyOwner(csp()->handle(), accessCred, this, &newOwner));
+}
+
+void KeyImpl::activate()
+{
+	mActive=true;
+}
+
+void KeyImpl::deactivate()
+{
+	if (mActive)
+	{
+		mActive=false;
+		check(CSSM_FreeKey(csp()->handle(), NULL, this, CSSM_FALSE));
+	}
+}
diff --git a/cdsa/cdsa_client/keyclient.h b/cdsa/cdsa_client/keyclient.h
new file mode 100644
index 00000000..b2264f2d
--- /dev/null
+++ b/cdsa/cdsa_client/keyclient.h
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+
+//
+// keyclient 
+//
+#ifndef _H_CDSA_CLIENT_KEYCLIENT
+#define _H_CDSA_CLIENT_KEYCLIENT  1
+
+#include <Security/aclclient.h>
+#include <Security/cspclient.h>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+//
+// Key
+//
+class KeyImpl : public ObjectImpl, public AclClient, public CssmKey
+{
+public:
+	KeyImpl(const CSP &csp);
+	KeyImpl(const CSP &csp, CSSM_KEY &key);
+	KeyImpl(const CSP &csp, const CSSM_DATA &keyData);
+	virtual ~KeyImpl();
+	
+	CSP csp() const { return parent<CSP>(); }
+	void deleteKey(const CSSM_ACCESS_CREDENTIALS *cred);
+
+	// Acl manipulation
+	void getAcl(const char *selectionTag, AutoAclEntryInfoList &aclInfos) const;
+	void changeAcl(const CSSM_ACCESS_CREDENTIALS *accessCred,
+				   const CSSM_ACL_EDIT &aclEdit);
+
+	// Acl owner manipulation
+	void getOwner(AutoAclOwnerPrototype &owner) const;
+	void changeOwner(const CSSM_ACCESS_CREDENTIALS *accessCred,
+					 const CSSM_ACL_OWNER_PROTOTYPE &newOwner);
+
+	// Call this after completing the CSSM API call after having called Key::makeNewKey()
+	void activate();
+
+protected:
+	void deactivate(); 
+};
+
+class Key : public Object
+{
+public:
+	typedef KeyImpl Impl;
+	explicit Key(Impl *impl) : Object(impl) {}
+	
+	Key() : Object(NULL) {}
+	Key(const CSP &csp, CSSM_KEY &key)	: Object(new Impl(csp, key)) {}
+	Key(const CSP &csp, CSSM_DATA &keyData)	: Object(new Impl(csp, keyData)) {}
+
+	// Creates an inactive key, client must call activate() after this.
+	Key(const CSP &csp) : Object(new Impl(csp)) {}
+
+	Impl *operator ->() const { return (*this) ? &impl<Impl>() : NULL; }
+	Impl &operator *() const { return impl<Impl>(); }
+
+	// Conversion operators to CssmKey baseclass.
+	operator const CssmKey * () const { return (*this) ? &(**this) : NULL; }
+	operator const CssmKey & () const { return **this; }
+
+	// Creates an inactive key, client must call activate() after this.
+	CssmKey *makeNewKey(const CSP &csp) { (*this) = Key(csp); return &(**this); }
+};
+
+
+struct KeySpec 
+{
+	uint32 usage;
+	uint32 attributes;
+	const CssmData *label;
+	//add rc context
+	
+	KeySpec(uint32 u, uint32 a) : usage(u), attributes(a), label(NULL) { }
+	KeySpec(uint32 u, uint32 a, const CssmData &l) : usage(u), attributes(a), label(&l) { }
+};
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+
+#endif // _H_CDSA_CLIENT_KEYCLIENT
diff --git a/cdsa/cdsa_client/macclient.cpp b/cdsa/cdsa_client/macclient.cpp
new file mode 100644
index 00000000..065ae0ec
--- /dev/null
+++ b/cdsa/cdsa_client/macclient.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+
+//
+// macclient - client interface to CSSM sign/verify mac contexts
+//
+#include <Security/macclient.h>
+
+using namespace CssmClient;
+
+
+//
+// Common features of signing and verify mac contexts
+//
+void MacContext::activate()
+{
+	if (!mActive) 
+	{
+		check(CSSM_CSP_CreateMacContext(attachment()->handle(), mAlgorithm,
+			  mKey, &mHandle));
+		mActive = true;
+	}
+}
+
+//
+// Signing
+//
+void GenerateMac::sign(const CssmData *data, uint32 count, CssmData &mac)
+{
+	unstaged();
+	check(CSSM_GenerateMac(handle(), data, count, &mac));
+}
+
+void GenerateMac::init()
+{
+	check(CSSM_GenerateMacInit(handle()));
+	mStaged = true;
+}
+
+void GenerateMac::sign(const CssmData *data, uint32 count)
+{
+	staged();
+	check(CSSM_GenerateMacUpdate(handle(), data, count));
+}
+
+void GenerateMac::operator () (CssmData &mac)
+{
+	staged();
+	check(CSSM_GenerateMacFinal(handle(), &mac));
+	mStaged = false;
+}
+
+
+//
+// Verifying
+//
+void VerifyMac::verify(const CssmData *data, uint32 count, const CssmData &mac)
+{
+	unstaged();
+	check(CSSM_VerifyMac(handle(), data, count, &mac));
+}
+
+void VerifyMac::init()
+{
+	check(CSSM_VerifyMacInit(handle()));
+	mStaged = true;
+}
+
+void VerifyMac::verify(const CssmData *data, uint32 count)
+{
+	staged();
+	check(CSSM_VerifyMacUpdate(handle(), data, count));
+}
+
+void VerifyMac::operator () (const CssmData &mac)
+{
+	staged();
+	check(CSSM_VerifyMacFinal(handle(), &mac));
+	mStaged = false;
+}
diff --git a/cdsa/cdsa_client/macclient.h b/cdsa/cdsa_client/macclient.h
new file mode 100644
index 00000000..a37d8789
--- /dev/null
+++ b/cdsa/cdsa_client/macclient.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+
+//
+// macclient - client interface to CSSM sign/verify mac contexts
+//
+#ifndef _H_CDSA_CLIENT_MACCLIENT
+#define _H_CDSA_CLIENT_MACCLIENT  1
+
+#include <Security/cspclient.h>
+#include <Security/keyclient.h>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+//
+// A signing/verifying mac context
+//
+class MacContext : public Context
+{
+public:
+	MacContext(const CSP &csp, CSSM_ALGORITHMS alg)
+		: Context(csp, alg) { }
+
+	// preliminary interface
+	Key key() const { assert(mKey); return mKey; }
+	void key(const Key &k) { mKey = k; set(CSSM_ATTRIBUTE_KEY, mKey); }
+
+protected:
+	void activate();
+	Key mKey;
+};
+
+
+class GenerateMac : public MacContext
+{
+public:
+	GenerateMac(const CSP &csp, CSSM_ALGORITHMS alg) : MacContext(csp, alg) { }
+	
+	// integrated
+	void sign(const CssmData &data, CssmData &mac) { sign(&data, 1, mac); }
+	void sign(const CssmData *data, uint32 count, CssmData &mac);
+	
+	// staged
+	void init(); // Optional
+	void sign(const CssmData &data) { sign(&data, 1); }
+	void sign(const CssmData *data, uint32 count);
+	void operator () (CssmData &mac);
+	CssmData operator () () { CssmData mac; (*this)(mac); return mac; }
+};
+
+class VerifyMac : public MacContext
+{
+public:
+	VerifyMac(const CSP &csp, CSSM_ALGORITHMS alg) : MacContext(csp, alg) { }
+	
+	// integrated
+	void verify(const CssmData &data, const CssmData &mac) { verify(&data, 1, mac); }
+	void verify(const CssmData *data, uint32 count, const CssmData &mac);
+	
+	// staged
+	void init(); // Optional
+	void verify(const CssmData &data) { verify(&data, 1); }
+	void verify(const CssmData *data, uint32 count);
+	void operator () (const CssmData &mac);
+};
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_MACCLIENT
diff --git a/cdsa/cdsa_client/multidldb.cpp b/cdsa/cdsa_client/multidldb.cpp
new file mode 100644
index 00000000..5e410440
--- /dev/null
+++ b/cdsa/cdsa_client/multidldb.cpp
@@ -0,0 +1,234 @@
+/*
+ * 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.
+ */
+
+
+//
+// MultiDLDb implementation.
+//
+
+#include <Security/multidldb.h>
+#include <Security/securestorage.h>
+#include <Security/cssmerrno.h>
+
+
+
+namespace Security
+{
+
+using namespace CssmClient;
+
+namespace CssmClient
+{
+
+//
+// MultiDLDbDbCursorImpl declaration
+//
+class MultiDLDbDbCursorImpl : public DbCursorImpl
+{
+public:
+	MultiDLDbDbCursorImpl(const MultiDLDb &parent, const CSSM_QUERY &query, CssmAllocator &allocator);
+	MultiDLDbDbCursorImpl(const MultiDLDb &parent, uint32 capacity, CssmAllocator &allocator);
+	virtual ~MultiDLDbDbCursorImpl();
+
+	bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId);
+private:
+	MultiDLDb multiDLDb() { return parent<MultiDLDb>(); }
+	void activate();
+	void deactivate();
+
+	MultiDLDbImpl::ListRef mListRef;
+	MultiDLDbImpl::List::const_iterator mNext;
+	MultiDLDbImpl::List::const_iterator mEnd;
+	DbCursor mCursor;
+};
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+//
+// MultiDLDbImpl
+//
+MultiDLDbImpl::MultiDLDbImpl(const vector<DLDbIdentifier> &list, bool useSecureStorage, const Cssm &cssm)
+: ObjectImpl(cssm), mListRef(list), mUseSecureStorage(useSecureStorage)
+{
+}
+
+MultiDLDbImpl::MultiDLDbImpl(const vector<DLDbIdentifier> &list, bool useSecureStorage)
+: ObjectImpl(Cssm::standard()), mListRef(list), mUseSecureStorage(useSecureStorage)
+{
+}
+
+MultiDLDbImpl::~MultiDLDbImpl()
+{
+	deactivate();
+}
+
+Db
+MultiDLDbImpl::database(const DLDbIdentifier &dlDbIdentifier)
+{
+	StLock<Mutex> _(mLock);
+	DbMap::const_iterator it = mDbMap.find(dlDbIdentifier);
+	if (it != mDbMap.end())
+		return it->second;
+
+	Module module(dlDbIdentifier.ssuid().guid(), cssm());
+	DL dl;
+	if (dlDbIdentifier.ssuid().subserviceType() & CSSM_SERVICE_CSP)
+	{
+		if (mUseSecureStorage)
+			dl = SSCSPDL(module);
+		else
+			dl = CSPDL(module);
+	}
+	else
+		dl = DL(module);
+
+	dl->subserviceId(dlDbIdentifier.ssuid().subserviceId());
+	dl->version(dlDbIdentifier.ssuid().version());
+	Db db(dl, dlDbIdentifier.dbName());
+	if (find(mListRef->begin(), mListRef->end(), dlDbIdentifier) != mListRef->end())
+		mDbMap.insert(DbMap::value_type(dlDbIdentifier, db));
+
+	return db;
+}
+
+void
+MultiDLDbImpl::list(const vector<DLDbIdentifier> &list)
+{
+	StLock<Mutex> _(mLock);
+	set<DLDbIdentifier> oldList(mListRef->begin(), mListRef->end());
+	mListRef = ListRef(list);
+	set<DLDbIdentifier> newList(mListRef->begin(), mListRef->end());
+	vector<DLDbIdentifier> obsolete;
+	back_insert_iterator<vector<DLDbIdentifier> > ii(obsolete);
+	// Remove all db's from the map that were in oldList but are not in mListRef.
+	set_difference(oldList.begin(), oldList.end(), newList.begin(), newList.end(), ii);
+	for (vector<DLDbIdentifier>::const_iterator it = obsolete.begin(); it != obsolete.end(); ++it)
+		mDbMap.erase(*it);
+}
+
+DbCursorImpl *
+MultiDLDbImpl::newDbCursor(const CSSM_QUERY &query, CssmAllocator &allocator)
+{
+	return new MultiDLDbDbCursorImpl(MultiDLDb(this), query, allocator);
+}
+
+DbCursorImpl *
+MultiDLDbImpl::newDbCursor(uint32 capacity, CssmAllocator &allocator)
+{
+	return new MultiDLDbDbCursorImpl(MultiDLDb(this), capacity, allocator);
+}
+
+void
+MultiDLDbImpl::activate()
+{
+}
+
+void
+MultiDLDbImpl::deactivate()
+{
+	StLock<Mutex> _(mLock);
+	mDbMap.erase(mDbMap.begin(), mDbMap.end());
+}
+
+
+//
+// MultiDLDbDbCursorImpl
+//
+MultiDLDbDbCursorImpl::MultiDLDbDbCursorImpl(const MultiDLDb &parent,
+											 const CSSM_QUERY &query, CssmAllocator &allocator)
+: DbCursorImpl(parent, query, allocator)
+{
+}
+
+MultiDLDbDbCursorImpl::MultiDLDbDbCursorImpl(const MultiDLDb &parent,
+											 uint32 capacity, CssmAllocator &allocator)
+: DbCursorImpl(parent, capacity, allocator)
+{
+}
+
+MultiDLDbDbCursorImpl::~MultiDLDbDbCursorImpl()
+{
+	try
+	{
+		deactivate();
+	}
+	catch(...) {}
+}
+
+bool
+MultiDLDbDbCursorImpl::next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId)
+{
+	activate();
+	for (;;)
+	{
+		if (!mCursor)
+		{
+			if (mNext == mEnd)
+			{
+				// This is how it ends.
+				deactivate();
+				return false;
+			}
+
+			mCursor = DbCursor(multiDLDb()->database(*mNext++), *this);
+		}
+
+		try
+		{
+			if (mCursor->next(attributes, data, uniqueId))
+				return true;
+		}
+
+		catch(const CssmCommonError &err)
+		{
+			OSStatus status = err.osStatus();
+			if(status != CSSMERR_DL_DATASTORE_DOESNOT_EXIST)
+				throw;
+		}
+
+
+
+		mCursor = DbCursor();
+	}
+}
+
+void
+MultiDLDbDbCursorImpl::activate()
+{
+	if (!mActive)
+	{
+		mListRef = multiDLDb()->listRef();
+		mNext = mListRef->begin();
+		mEnd = mListRef->end();
+		mActive = true;
+	}
+}
+
+void
+MultiDLDbDbCursorImpl::deactivate()
+{
+	if (mActive)
+	{
+		mActive = false;
+		mListRef = MultiDLDbImpl::ListRef();
+		mNext = mEnd;
+		mCursor = DbCursor();
+	}
+}
+
diff --git a/cdsa/cdsa_client/multidldb.h b/cdsa/cdsa_client/multidldb.h
new file mode 100644
index 00000000..d2a64b41
--- /dev/null
+++ b/cdsa/cdsa_client/multidldb.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+
+//
+// multidldb interfaces for searching multiple dls or db with a single cursor.
+//
+#ifndef _H_CDSA_CLIENT_MULTIDLDB
+#define _H_CDSA_CLIENT_MULTIDLDB  1
+
+#include <Security/dlclient.h>
+#include <Security/DLDBList.h>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+//
+// The MultiDLDb class.
+//
+class MultiDLDbImpl : public ObjectImpl, public DbCursorMaker
+{
+public:
+	struct List : public vector<DLDbIdentifier>, public RefCount
+	{
+		List(const vector<DLDbIdentifier> &list) : vector<DLDbIdentifier>(list) {}
+	};
+
+	struct ListRef : public RefPointer<List>
+	{
+		ListRef() {}
+		ListRef(const vector<DLDbIdentifier> &list) : RefPointer<List>(new List(list)) {}
+	};
+
+	MultiDLDbImpl(const vector<DLDbIdentifier> &list, bool useSecureStorage, const Cssm &cssm);
+	MultiDLDbImpl(const vector<DLDbIdentifier> &list, bool useSecureStorage);
+	virtual ~MultiDLDbImpl();
+
+	Cssm cssm() const { return parent<Cssm>(); }
+	Db database(const DLDbIdentifier &dlDbIdentifier);
+	ListRef listRef() { return mListRef; }
+	void list(const vector<DLDbIdentifier> &list);
+    const vector<DLDbIdentifier> &list() { return *mListRef; }
+
+	// DbCursorMaker
+	virtual DbCursorImpl *newDbCursor(const CSSM_QUERY &query, CssmAllocator &allocator);
+	virtual DbCursorImpl *newDbCursor(uint32 capacity, CssmAllocator &allocator);
+
+protected:
+	void activate();
+	void deactivate();
+
+private:
+	typedef map<DLDbIdentifier, Db> DbMap;
+
+	// Lock protecting this object during changes.
+	Mutex mLock;
+	ListRef mListRef;
+	DbMap mDbMap;
+	bool mUseSecureStorage;
+};
+
+class MultiDLDb : public Object
+{
+public:
+	typedef MultiDLDbImpl Impl;
+
+	explicit MultiDLDb(Impl *impl) : Object(impl) {}
+	MultiDLDb(const vector<DLDbIdentifier> &list, bool useSecureStorage, const Cssm &cssm)
+	: Object(new Impl(list, useSecureStorage, cssm)) {}
+	MultiDLDb(const vector<DLDbIdentifier> &list, bool useSecureStorage)
+	: Object(new Impl(list, useSecureStorage)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+	
+	// Conversion to DbCursorMaker
+	operator DbCursorMaker &() { return impl<Impl>(); }
+};
+
+}; // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_MULTIDLDB
diff --git a/cdsa/cdsa_client/osxsigner.cpp b/cdsa/cdsa_client/osxsigner.cpp
new file mode 100644
index 00000000..832ea0ab
--- /dev/null
+++ b/cdsa/cdsa_client/osxsigner.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+
+//
+// osxsigner - MacOS X's standard code signing algorithm.
+//
+#ifdef __MWERKS__
+#define _CPP_OSXSIGNER
+#endif
+
+#include <Security/osxsigner.h>
+#include <Security/debugging.h>
+
+
+namespace Security
+{
+
+namespace CodeSigning
+{
+
+//
+// Construct an OSXSigner
+//
+OSXSigner::OSXSigner() : csp(gGuidAppleCSP)
+{
+}
+
+
+//
+// Signing/verification implementation
+//
+OSXSigner::OSXSignature *OSXSigner::sign(const Signable &target)
+{
+	Digester digester(*this);
+	scanContents(digester, target);
+	CssmClient::DataBuffer<OSXSignature::hashLength> hash;
+	digester(hash);
+	IFDUMPING("codesign", Debug::dumpData("sign", hash));
+	return new OSXSignature(hash);
+}
+
+bool OSXSigner::verify(const Signable &target, const Signature *signature)
+{
+	if (const OSXSignature *sig = dynamic_cast<const OSXSignature *>(signature)) {
+		Digester digester(*this);
+		scanContents(digester, target);
+		CssmClient::DataBuffer<OSXSignature::hashLength> hash;
+		digester(hash);
+		IFDUMPING("codesign", Debug::dumpData("verify", hash));
+		return (*sig) == hash;
+	}
+	return false;
+}
+
+void OSXSigner::Digester::enumerateContents(const void *data, size_t length)
+{
+	digest(CssmData(const_cast<void *>(data), length));
+}
+
+
+//
+// Re-create a Signature object from its external representation
+//
+OSXSigner::OSXSignature *OSXSigner::restore(uint32 type, const void *data, size_t length)
+{
+	switch (type) {
+	case CSSM_ACL_CODE_SIGNATURE_OSX:
+		if (length != OSXSignature::hashLength)
+			CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
+		return new OSXSignature(data);
+	default:
+		CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT);
+	}
+}
+
+
+}; // end namespace CodeSigning
+
+} // end namespace Security
diff --git a/cdsa/cdsa_client/osxsigner.h b/cdsa/cdsa_client/osxsigner.h
new file mode 100644
index 00000000..cfe409cd
--- /dev/null
+++ b/cdsa/cdsa_client/osxsigner.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+
+//
+// osxsigner - MacOS X's standard code signing algorithm.
+//
+#ifndef _H_OSXSIGNER
+#define _H_OSXSIGNER
+
+#include <Security/osxsigning.h>
+#include <Security/cspclient.h>
+#include <string>
+
+#ifdef _CPP_OSXSIGNER
+#pragma export on
+#endif
+
+namespace Security
+{
+
+namespace CodeSigning
+{
+
+//
+// The OSX standard signer object
+//
+class OSXSigner : public Signer {
+	class OSXSignature;
+	class Digester; friend class Digester;
+public:
+	OSXSigner();
+	OSXSignature *sign(const Signable &target);
+	bool verify(const Signable &target, const Signature *signature);
+	
+	OSXSignature *restore(uint32 type, const void *data, size_t length);
+
+public:
+	class OSXSignature : public Signature {
+	public:
+		static const size_t hashLength = 20;	// length of signature data
+		typedef uint8 Hash[hashLength];
+		
+		OSXSignature(const void *src)	{ memcpy(mData, src, hashLength); }
+		
+		bool operator == (const Signature &other) const
+		{
+			if (const OSXSignature *sig = dynamic_cast<const OSXSignature *>(&other))
+				return !memcmp(mData, sig->mData, hashLength);
+			else
+				return false;
+		}
+		
+		bool operator == (void *bytes) const
+		{ return !memcmp(mData, bytes, hashLength); }
+		
+		uint32 type() const		{ return standardOSXSignature; }
+		const void *data() const { return mData; }
+		size_t length() const	{ return hashLength; }
+	
+	private:
+		uint8 mData[hashLength];
+	};
+	
+private:
+	class Digester : public State, public CssmClient::Digest {
+	public:
+		Digester(OSXSigner &sgn) : State(sgn), CssmClient::Digest(sgn.csp, CSSM_ALGID_SHA1) { }
+		
+		void enumerateContents(const void *addr, size_t length);
+	};
+
+private:
+	// CDSA resources
+	CssmClient::CSP csp;
+};
+
+} // end namespace CodeSigning
+
+} // end namespace Security
+
+#ifdef _CPP_OSXSIGNER
+#pragma export off
+#endif
+
+
+#endif //_H_OSXSIGNER
diff --git a/cdsa/cdsa_client/securestorage.cpp b/cdsa/cdsa_client/securestorage.cpp
new file mode 100644
index 00000000..24f9a5ae
--- /dev/null
+++ b/cdsa/cdsa_client/securestorage.cpp
@@ -0,0 +1,596 @@
+/*
+ * 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.
+ */
+
+
+#include "securestorage.h"
+#include "genkey.h"
+#include "aclsupport.h"
+#include <Security/osxsigning.h>
+#include <memory>
+
+using namespace CssmClient;
+
+//
+// Manage CSPDL attachments
+//
+CSPDLImpl::CSPDLImpl(const Guid &guid)
+: CSPImpl(Cssm::standard()->autoModule(guid)),
+DLImpl(CSPImpl::module())
+{
+}
+
+CSPDLImpl::CSPDLImpl(const Module &module)
+: CSPImpl(module),
+DLImpl(module)
+{
+}
+
+CSPDLImpl::~CSPDLImpl()
+{
+}
+
+CssmAllocator &CSPDLImpl::allocator() const
+{
+	DLImpl::allocator(); return CSPImpl::allocator();
+}
+
+void CSPDLImpl::allocator(CssmAllocator &alloc)
+{
+	CSPImpl::allocator(alloc); DLImpl::allocator(alloc);
+}
+
+bool CSPDLImpl::operator <(const CSPDLImpl &other) const
+{
+	return (static_cast<const CSPImpl &>(*this) < static_cast<const CSPImpl &>(other) ||
+			(!(static_cast<const CSPImpl &>(other) < static_cast<const CSPImpl &>(*this))
+			   && static_cast<const DLImpl &>(*this) < static_cast<const DLImpl &>(other)));
+}
+
+bool CSPDLImpl::operator ==(const CSPDLImpl &other) const
+{
+	return (static_cast<const CSPImpl &>(*this) == static_cast<const CSPImpl &>(other)
+			&& static_cast<const DLImpl &>(*this) == static_cast<const DLImpl &>(other));
+}
+
+CSSM_SERVICE_MASK CSPDLImpl::subserviceMask() const
+{
+	return CSPImpl::subserviceType() | DLImpl::subserviceType();
+}
+
+void CSPDLImpl::subserviceId(uint32 id)
+{
+	CSPImpl::subserviceId(id); DLImpl::subserviceId(id);
+}
+
+
+//
+// Secure storage
+//
+SSCSPDLImpl::SSCSPDLImpl(const Guid &guid) : CSPDLImpl::CSPDLImpl(guid)
+{
+}
+
+SSCSPDLImpl::SSCSPDLImpl(const Module &module) : CSPDLImpl::CSPDLImpl(module)
+{
+}
+
+SSCSPDLImpl::~SSCSPDLImpl()
+{
+}
+
+DbImpl *
+SSCSPDLImpl::newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
+{
+	return new SSDbImpl(SSCSPDL(this), inDbName, inDbLocation);
+}
+
+
+//
+// SSDbImpl -- Secure Storage Database Implementation
+//
+SSDbImpl::SSDbImpl(const SSCSPDL &cspdl, const char *inDbName,
+				   const CSSM_NET_ADDRESS *inDbLocation)
+: DbImpl(cspdl, inDbName, inDbLocation)
+{
+}
+
+SSDbImpl::~SSDbImpl()
+{
+}
+
+void
+SSDbImpl::create()
+{
+	DbImpl::create();
+}
+
+void
+SSDbImpl::open()
+{
+	DbImpl::open();
+}
+
+SSDbUniqueRecord
+SSDbImpl::insert(CSSM_DB_RECORDTYPE recordType,
+				 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+				 const CSSM_DATA *data,
+				 const CSSM_RESOURCE_CONTROL_CONTEXT *rc)
+{
+	SSGroup group(SSDb(this), rc);
+	const CSSM_ACCESS_CREDENTIALS *cred = rc ? rc->AccessCred : NULL;
+	try
+	{
+		return insert(recordType, attributes, data, group, cred);
+	}
+	catch(...)
+	{
+		// @@@ Look at rc for credentials
+		group->deleteKey(cred);
+		throw;
+	}
+}
+
+SSDbUniqueRecord
+SSDbImpl::insert(CSSM_DB_RECORDTYPE recordType,
+				 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+				 const CSSM_DATA *data, const SSGroup &group,
+				 const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	// Create an encoded dataBlob for this item.
+	CssmDataContainer dataBlob;
+	group->encodeDataBlob(data, cred, dataBlob);
+
+	// Insert the record with the new juicy dataBlob.
+	return SSDbUniqueRecord(safe_cast<SSDbUniqueRecordImpl *>
+            (&(*DbImpl::insert(recordType, attributes, &dataBlob))));
+}
+
+
+// DbCursorMaker
+DbCursorImpl *
+SSDbImpl::newDbCursor(const CSSM_QUERY &query, CssmAllocator &allocator)
+{
+	return new SSDbCursorImpl(Db(this), query, allocator);
+}
+
+DbCursorImpl *
+SSDbImpl::newDbCursor(uint32 capacity, CssmAllocator &allocator)
+{
+	return new SSDbCursorImpl(Db(this), capacity, allocator);
+}
+
+
+// SSDbUniqueRecordMaker
+DbUniqueRecordImpl *
+SSDbImpl::newDbUniqueRecord()
+{
+	return new SSDbUniqueRecordImpl(Db(this));
+}
+
+
+//
+// SSGroup -- Group key with acl, used to protect a group of items.
+//
+// @@@ Get this from a shared spot.
+CSSM_DB_NAME_ATTR(SSGroupImpl::kLabel, 6, "Label", 0, NULL, BLOB);
+
+// Create a new group.
+SSGroupImpl::SSGroupImpl(const SSDb &ssDb,
+						 const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry)
+: KeyImpl(ssDb->csp()), mLabel(ssDb->allocator())
+{
+	mLabel.Length = kLabelSize;
+	mLabel.Data = reinterpret_cast<uint8 *>
+		(mLabel.mAllocator.malloc(mLabel.Length));
+
+	// Get our csp and set up a random number generation context.
+	CSP csp(csp());
+	Random random(csp, CSSM_ALGID_APPLE_YARROW);
+
+	// Generate a kLabelSize byte random number that will be the label of
+	// the key which we store in the dataBlob.
+	random.generate(mLabel, mLabel.Length);
+
+	// Overwrite the first 4 bytes with the magic cookie for a group.
+	reinterpret_cast<uint32 *>(mLabel.Data)[0] = kGroupMagic;
+
+	// @@@ Ensure that the label is unique (Chance of collision is 2^80 --
+	// birthday paradox).
+
+	// Generate a permanent 3DES key that we will use to encrypt the data.
+	GenerateKey genKey(csp, CSSM_ALGID_3DES_3KEY, 192);
+	genKey.database(ssDb);
+
+	// Set the acl of the key correctly here
+	genKey.initialAcl(ResourceControlContext::overlay(credAndAclEntry));
+
+	// Generate the key
+	genKey(*this, KeySpec(CSSM_KEYUSE_ENCRYPT|CSSM_KEYUSE_DECRYPT,
+						  CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_SENSITIVE,
+						  mLabel));
+
+	// Activate ourself so CSSM_FreeKey will get called when we go out of
+	// scope.
+	activate();
+}
+
+// Lookup an existing group based on a dataBlob.
+SSGroupImpl::SSGroupImpl(const SSDb &ssDb, const CSSM_DATA &dataBlob)
+: KeyImpl(ssDb->csp()), mLabel(ssDb->allocator())
+{
+	if (dataBlob.Length < kLabelSize + kIVSize)
+		CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND); // @@@ Not a SS record
+
+	mLabel = CssmData(dataBlob.Data, kLabelSize);
+	if (*reinterpret_cast<const uint32 *>(mLabel.Data) != kGroupMagic)
+		CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND); // @@@ Not a SS record
+
+	// Look up the symmetric key with that label.
+	DbCursor cursor(new DbDbCursorImpl(ssDb, 0, CssmAllocator::standard()));
+	cursor->recordType(CSSM_DL_DB_RECORD_SYMMETRIC_KEY);
+	cursor->add(CSSM_DB_EQUAL, kLabel, mLabel);
+
+	DbUniqueRecord keyId;
+	CssmDataContainer keyData(ssDb->allocator());
+	if (!cursor->next(NULL, &keyData, keyId))
+		CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND); // @@@ The key is gone
+
+	// Set the key part of ourself.
+	static_cast<CSSM_KEY &>(*this) =
+		*reinterpret_cast<const CSSM_KEY *>(keyData.Data);
+
+	// Activate ourself so CSSM_FreeKey will get called when we go out of
+	// scope.
+	activate();
+}
+
+const CssmData
+SSGroupImpl::label() const
+{
+	return mLabel;
+}
+
+void
+SSGroupImpl::decodeDataBlob(const CSSM_DATA &dataBlob,
+							const CSSM_ACCESS_CREDENTIALS *cred,
+							CssmAllocator &allocator, CSSM_DATA &data)
+{
+	// First get the IV and the cipherText from the blob.
+	CssmData iv(&dataBlob.Data[kLabelSize], kIVSize);
+	CssmData cipherText(&dataBlob.Data[kLabelSize + kIVSize],
+						dataBlob.Length - (kLabelSize + kIVSize));
+
+	CssmDataContainer plainText1(allocator);
+	CssmDataContainer plainText2(allocator);
+	try
+	{
+		// Decrypt the data
+		// @@@ Don't use staged decrypt once the AppleCSPDL can do combo
+		// encryption.
+		// Setup decryption context
+		Decrypt decrypt(csp(), algorithm());
+		decrypt.mode(CSSM_ALGMODE_CBCPadIV8);
+		decrypt.padding(CSSM_PADDING_PKCS1);
+		decrypt.initVector(iv);
+		decrypt.key(Key(this));
+		decrypt.cred(AccessCredentials::overlay(cred));
+		decrypt.decrypt(&cipherText, 1, &plainText1, 1);
+		decrypt.final(plainText2);
+	}
+	catch (const CssmError &e)
+	{
+		if (e.cssmError() != CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT)
+			throw;
+
+		// The user checked to don't ask again checkbox in the rogue app alert.  Let's edit the ACL for this key and add the calling application to it.
+		KeychainACL acl(Key(this));
+		acl.anyAllow(false);
+		acl.alwaysAskUser(true);
+
+		auto_ptr<CodeSigning::OSXCode> code(CodeSigning::OSXCode::main());
+		const char *path = code->canonicalPath().c_str();
+		CssmData comment(const_cast<char *>(path), strlen(path) + 1);
+		acl.push_back(TrustedApplication(path, comment));
+
+		// Change the acl.
+		acl.commit();
+
+		// Retry the decrypt operation.
+		Decrypt decrypt(csp(), algorithm());
+		decrypt.mode(CSSM_ALGMODE_CBCPadIV8);
+		decrypt.padding(CSSM_PADDING_PKCS1);
+		decrypt.initVector(iv);
+		decrypt.key(Key(this));
+		decrypt.cred(AccessCredentials::overlay(cred));
+		decrypt.decrypt(&cipherText, 1, &plainText1, 1);
+		decrypt.final(plainText2);
+	}
+
+	// Use DL allocator for allocating memory for data.
+	uint32 length = plainText1.Length + plainText2.Length;
+	data.Data = allocator.alloc<uint8>(length);
+	data.Length = length;
+	memcpy(data.Data, plainText1.Data, plainText1.Length);
+	memcpy(&data.Data[plainText1.Length], plainText2.Data, plainText2.Length);
+}
+
+void
+SSGroupImpl::encodeDataBlob(const CSSM_DATA *data,
+							const CSSM_ACCESS_CREDENTIALS *cred,
+							CssmDataContainer &dataBlob)
+{
+	// Get our csp and set up a random number generation context.
+	CSP csp(csp());
+	Random random(csp, CSSM_ALGID_APPLE_YARROW);
+
+	// Encrypt data using key and encode it in a dataBlob.
+
+	// First calculate a random IV.
+	uint8 ivBuf[kIVSize];
+	CssmData iv(ivBuf, kIVSize);
+	random.generate(iv, kIVSize);
+
+	// Setup encryption context
+	Encrypt encrypt(csp, algorithm());
+	encrypt.mode(CSSM_ALGMODE_CBCPadIV8);
+	encrypt.padding(CSSM_PADDING_PKCS1);
+	encrypt.initVector(iv);
+	encrypt.key(Key(this));
+	encrypt.cred(AccessCredentials::overlay(cred));
+
+	// Encrypt the data
+	const CssmData nothing;
+	const CssmData *plainText = data ? CssmData::overlay(data) : &nothing;
+	// @@@ Don't use staged encrypt once the AppleCSPDL can do combo
+	// encryption.
+	CssmDataContainer cipherText1, cipherText2;
+	encrypt.encrypt(plainText, 1, &cipherText1, 1);
+	encrypt.final(cipherText2);
+
+	// Create a dataBlob containing the label followed by the IV followed
+	// by the cipherText.
+	uint32 length = (kLabelSize + kIVSize
+					 + cipherText1.Length + cipherText2.Length);
+	dataBlob.Data = dataBlob.mAllocator.alloc<uint8>(length);
+	dataBlob.Length = length;
+	memcpy(dataBlob.Data, mLabel.Data, kLabelSize);
+	memcpy(&dataBlob.Data[kLabelSize], iv.Data, kIVSize);
+	memcpy(&dataBlob.Data[kLabelSize + kIVSize],
+		   cipherText1.Data, cipherText1.Length);
+	memcpy(&dataBlob.Data[kLabelSize + kIVSize + cipherText1.Length],
+		   cipherText2.Data, cipherText2.Length);
+}
+
+
+//
+// SSDbCursorImpl -- Secure Storage Database Cursor Implementation.
+//
+SSDbCursorImpl::SSDbCursorImpl(const Db &db, const CSSM_QUERY &query,
+							   CssmAllocator &allocator)
+: DbDbCursorImpl(db, query, allocator)
+{
+}
+
+SSDbCursorImpl::SSDbCursorImpl(const Db &db, uint32 capacity,
+							   CssmAllocator &allocator)
+: DbDbCursorImpl(db, capacity, allocator)
+{
+}
+
+bool
+SSDbCursorImpl::next(DbAttributes *attributes, ::CssmDataContainer *data,
+					 DbUniqueRecord &uniqueId)
+{
+	return next(attributes, data, uniqueId, NULL);
+}
+
+bool
+SSDbCursorImpl::next(DbAttributes *attributes, ::CssmDataContainer *data,
+					 DbUniqueRecord &uniqueId,
+					 const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	if (!data)
+		return DbDbCursorImpl::next(attributes, data, uniqueId);
+
+	DbAttributes noAttrs, *attrs;
+	attrs = attributes ? attributes : &noAttrs;
+
+	// Get the datablob for this record
+	CssmDataContainer dataBlob;
+	for (;;)
+	{
+		if (!DbDbCursorImpl::next(attrs, &dataBlob, uniqueId))
+			return false;
+
+		// Keep going until we find a non key type record.
+		CSSM_DB_RECORDTYPE rt = attrs->recordType();
+		if (rt != CSSM_DL_DB_RECORD_SYMMETRIC_KEY
+			&& rt != CSSM_DL_DB_RECORD_PRIVATE_KEY
+			&& rt != CSSM_DL_DB_RECORD_PUBLIC_KEY)
+		{
+			// @@@ Check the label and if it doesn't start with the magic for a SSKey return the key.
+			break;
+		}
+		else
+		{
+			// Free the key we just retrieved
+			database()->csp()->freeKey(*reinterpret_cast<CssmKey *>(dataBlob.Data));
+		}
+	}
+
+	// Get the group for dataBlob
+	// @@@ This might fail in which case we should probably not decrypt the
+	// data.
+	SSGroup group(database(), dataBlob);
+
+	// Decode the dataBlob, pass in the DL allocator.
+	group->decodeDataBlob(dataBlob, cred, database()->allocator(), *data);
+	return true;
+}
+
+bool
+SSDbCursorImpl::nextKey(DbAttributes *attributes, Key &key,
+						DbUniqueRecord &uniqueId)
+{
+	DbAttributes noAttrs, *attrs;
+	attrs = attributes ? attributes : &noAttrs;
+	CssmDataContainer keyData(database()->allocator());
+	for (;;)
+	{
+		if (!DbDbCursorImpl::next(attrs, &keyData, uniqueId))
+			return false;
+		// Keep going until we find a key type record.
+		CSSM_DB_RECORDTYPE rt = attrs->recordType();
+		if (rt == CSSM_DL_DB_RECORD_SYMMETRIC_KEY
+			|| rt == CSSM_DL_DB_RECORD_PRIVATE_KEY
+			|| rt == CSSM_DL_DB_RECORD_PUBLIC_KEY)
+			break;
+	}
+
+	key = Key(database()->csp(), *reinterpret_cast<CSSM_KEY *>(keyData.Data));
+	return true;
+}
+
+void
+SSDbCursorImpl::activate()
+{
+	return DbDbCursorImpl::activate();
+}
+
+void
+SSDbCursorImpl::deactivate()
+{
+	return DbDbCursorImpl::deactivate();
+}
+
+
+//
+// SSDbUniqueRecordImpl -- Secure Storage UniqueRecord Implementation.
+//
+SSDbUniqueRecordImpl::SSDbUniqueRecordImpl(const Db &db)
+: DbUniqueRecordImpl(db)
+{
+}
+
+SSDbUniqueRecordImpl::~SSDbUniqueRecordImpl()
+{
+}
+
+void
+SSDbUniqueRecordImpl::deleteRecord()
+{
+	deleteRecord(NULL);
+}
+
+void
+SSDbUniqueRecordImpl::deleteRecord(const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	// Get the datablob for this record
+	// @@@ Fixme so we don't need to call DbUniqueRecordImpl::get
+	CssmDataContainer dataBlob;
+	DbUniqueRecordImpl::get(NULL, &dataBlob);
+
+	// Get the group for dataBlob
+	// @@@ This might fail in which case we should probably not decrypt the
+	// data.
+	SSGroup group(database(), dataBlob);
+
+	// @@@ Use transactions.
+	// Delete the record.
+	DbUniqueRecordImpl::deleteRecord();
+	// Delete the group
+	// @@@ What if the group is shared?
+	group->deleteKey(cred);
+}
+
+void
+SSDbUniqueRecordImpl::modify(CSSM_DB_RECORDTYPE recordType,
+							 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+							 const CSSM_DATA *data,
+							 CSSM_DB_MODIFY_MODE modifyMode)
+{
+	modify(recordType, attributes, data, modifyMode, NULL);
+}
+
+void
+SSDbUniqueRecordImpl::modify(CSSM_DB_RECORDTYPE recordType,
+							 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+							 const CSSM_DATA *data,
+							 CSSM_DB_MODIFY_MODE modifyMode,
+							 const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	if (!data)
+	{
+		DbUniqueRecordImpl::modify(recordType, attributes, NULL, modifyMode);
+		return;
+	}
+
+	// Get the datablob for this record @@@ Fixme so we don't need to call
+	// DbUniqueRecordImpl::get
+	CssmDataContainer oldDataBlob;
+	DbUniqueRecordImpl::get(NULL, &oldDataBlob);
+
+	// Get the group for oldDataBlob
+	// @@@ This might fail in which case we should probably not decrypt the
+	// data.
+	SSGroup group(database(), oldDataBlob);
+
+	// Create a new dataBlob.
+	CssmDataContainer dataBlob;
+	group->encodeDataBlob(data, cred, dataBlob);
+	DbUniqueRecordImpl::modify(recordType, attributes, &dataBlob, modifyMode);
+}
+
+void
+SSDbUniqueRecordImpl::get(DbAttributes *attributes, ::CssmDataContainer *data)
+{
+	get(attributes, data, NULL);
+}
+
+void
+SSDbUniqueRecordImpl::get(DbAttributes *attributes, ::CssmDataContainer *data,
+						  const CSSM_ACCESS_CREDENTIALS *cred)
+{
+	if (!data)
+	{
+		DbUniqueRecordImpl::get(attributes, NULL);
+		return;
+	}
+
+	// Get the datablob for this record @@@ Fixme so we don't need to call
+	// DbUniqueRecordImpl::get
+	CssmDataContainer dataBlob;
+	DbUniqueRecordImpl::get(attributes, &dataBlob);
+
+	// Get the group for dataBlob
+	// @@@ This might fail in which case we should probably not decrypt the
+	// data.
+	SSGroup group(database(), dataBlob);
+
+	// Decode the dataBlob, pass in the DL allocator.
+	group->decodeDataBlob(dataBlob, cred, allocator(), *data);
+}
+
+SSGroup
+SSDbUniqueRecordImpl::group()
+{
+	// Get the datablob for this record
+	// @@@ Fixme so we don't need to call DbUniqueRecordImpl::get
+	CssmDataContainer dataBlob;
+	DbUniqueRecordImpl::get(NULL, &dataBlob);
+	return SSGroup(database(), dataBlob);
+}
diff --git a/cdsa/cdsa_client/securestorage.h b/cdsa/cdsa_client/securestorage.h
new file mode 100644
index 00000000..1e177122
--- /dev/null
+++ b/cdsa/cdsa_client/securestorage.h
@@ -0,0 +1,347 @@
+/*
+ * 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.
+ */
+
+
+//
+// securestorage - client interface to CSP DLs and their operations
+//
+#ifndef _H_CDSA_CLIENT_SECURESTORAGE
+#define _H_CDSA_CLIENT_SECURESTORAGE  1
+
+#include <Security/cspclient.h>
+#include <Security/dlclient.h>
+#include <Security/keyclient.h>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+//
+// A CSP and a DL attachment of the same subservice
+//
+// This gives us 2 Object instances, but we make sure that have the same
+// mImpl.  Currently this class has no behaviour, but it will get some in
+// the future.
+//
+class CSPDLImpl : public CSPImpl, public DLImpl
+{
+public:
+	CSPDLImpl(const Guid &guid);
+	CSPDLImpl(const Module &module);
+	virtual ~CSPDLImpl();
+
+	// Object methods.
+	bool isActive() const { return CSPImpl::isActive() || DLImpl::isActive(); }
+
+	virtual CssmAllocator &allocator() const;
+	virtual void allocator(CssmAllocator &alloc);
+
+	virtual bool operator <(const CSPDLImpl &other) const;
+	virtual bool operator ==(const CSPDLImpl &other) const;
+
+	// Attachment methods.
+	virtual CSSM_SERVICE_MASK subserviceMask() const;
+	virtual void subserviceId(uint32 id);
+
+	uint32 subserviceId() const { return CSPImpl::subserviceId(); }
+	CSSM_ATTACH_FLAGS cspFlags() const { return CSPImpl::flags(); }
+	void cspFlags(CSSM_ATTACH_FLAGS f) { CSPImpl::flags(f); }
+	CSSM_ATTACH_FLAGS dlFlags() const { return DLImpl::flags(); }
+	void dlFlags(CSSM_ATTACH_FLAGS f) { DLImpl::flags(f); }
+
+	void attach() { CSPImpl::attach(); DLImpl::attach(); }
+	void detach() { CSPImpl::detach(); DLImpl::detach(); }
+	bool attached() const { return CSPImpl::attached() || DLImpl::attached(); }
+
+	Module module() const { return CSPImpl::module(); }
+	const Guid &guid() const { return CSPImpl::guid(); }
+	CSSM_MODULE_HANDLE cspHandle() { return CSPImpl::handle(); }
+	CSSM_MODULE_HANDLE dlHandle() { return DLImpl::handle(); }
+
+	CssmSubserviceUid subserviceUid() const
+	{ return CSPImpl::subserviceUid(); }
+
+private:
+};
+
+
+class CSPDL : public CSP, public DL
+{
+public:
+	typedef CSPDLImpl Impl;
+
+	explicit CSPDL(Impl *impl) : CSP(impl), DL(impl) {}
+	CSPDL(const Guid &guid) : CSP(new Impl(guid)), DL(&CSP::impl<Impl>()) {}
+	CSPDL(const Module &module)
+		: CSP(new Impl(module)), DL(&CSP::impl<Impl>()) {}
+
+	//template <class _Impl> _Impl &impl() const
+	//{ return CSP::impl<_Impl>(); }
+
+	Impl *operator ->() const { return &CSP::impl<Impl>(); }
+	Impl &operator *() const { return CSP::impl<Impl>(); }
+
+	// Conversion operators must be here
+	bool operator !() const { return !&**this; }
+	operator bool() const { return &**this; }
+
+	bool operator <(const CSPDL &other) const
+	{ return *this && other ? **this < *other : &**this < &*other; }
+	bool operator ==(const CSPDL &other) const
+	{ return *this && other ? **this == *other : &**this == &*other; }
+};
+
+
+//
+// SSCSPDL -- Secure storage class
+//
+class SSCSPDLImpl : public CSPDLImpl
+{
+public:
+	SSCSPDLImpl(const Guid &guid);
+	SSCSPDLImpl(const Module &module);
+	virtual ~SSCSPDLImpl();
+
+	// DbMaker
+	DbImpl *newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
+private:
+};
+
+class SSCSPDL : public CSPDL 
+{
+public:
+	typedef SSCSPDLImpl Impl;
+
+	explicit SSCSPDL(Impl *impl) : CSPDL(impl) {}
+	SSCSPDL(const Guid &guid) : CSPDL(new Impl(guid)) {}
+	SSCSPDL(const Module &module) : CSPDL(new Impl(module)) {}
+
+	Impl *operator ->() const { return &CSP::impl<Impl>(); }
+	Impl &operator *() const { return CSP::impl<Impl>(); }
+};
+
+
+//
+// SSDbImpl --  A Security Storage Db object.
+//
+class SSGroup;
+class SSDbUniqueRecord;
+
+class SSDbImpl : public DbImpl
+{
+public:
+	SSDbImpl(const SSCSPDL &cspdl,
+			 const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
+	virtual ~SSDbImpl();
+
+	void create();
+	void open();
+
+	SSDbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
+							const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+							const CSSM_DATA *data,
+							const CSSM_RESOURCE_CONTROL_CONTEXT *rc = NULL);
+
+#if 0
+	SSDbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
+							const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+							const CSSM_DATA *data,
+							const AutoAclEntryInfoList &keyAcl);
+#endif
+
+	SSDbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
+							const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+							const CSSM_DATA *data, const SSGroup &group,
+							const CSSM_ACCESS_CREDENTIALS *cred);
+
+	// DbCursorMaker
+	DbCursorImpl *newDbCursor(const CSSM_QUERY &query,
+							  CssmAllocator &allocator);
+	DbCursorImpl *newDbCursor(uint32 capacity, CssmAllocator &allocator);
+
+	// SSDbUniqueRecordMaker
+	DbUniqueRecordImpl *newDbUniqueRecord();
+
+	CSP csp() { return parent<CSP>(); }
+};
+
+class SSDb : public Db
+{
+public:
+	typedef SSDbImpl Impl;
+
+	explicit SSDb(Impl *impl) : Db(impl) {}
+	SSDb(const SSCSPDL &cspdl, const char *inDbName,
+		 const CSSM_NET_ADDRESS *inDbLocation)
+		: Db(cspdl->newDb(inDbName, inDbLocation)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+};
+
+
+//
+// SSGroup -- Group key with acl, used to protect a group of items.
+//
+class SSGroupImpl : public KeyImpl
+{
+public:
+	SSGroupImpl(const SSDb &ssDb, const CSSM_DATA &dataBlob);
+	SSGroupImpl(const SSDb &ssDb,
+				const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry);
+
+	const CssmData label() const;
+	void decodeDataBlob(const CSSM_DATA &dataBlob,
+						const CSSM_ACCESS_CREDENTIALS *cred,
+						CssmAllocator &allocator, CSSM_DATA &data);
+	void encodeDataBlob(const CSSM_DATA *data,
+						const CSSM_ACCESS_CREDENTIALS *cred,
+						CssmDataContainer &dataBlob);
+
+private:
+	// Constants
+	enum
+	{
+		// Label prefix for a secure storage group
+		kGroupMagic = FOUR_CHAR_CODE('ssgp'),
+
+		// Size of label (including prefix)
+		kLabelSize = 20,
+
+		// Size of IV
+		kIVSize = 8
+	};
+
+	CSSM_DB_ATTR_DECL(kLabel);
+
+	CssmDataContainer mLabel;
+};
+
+class SSGroup : public Key
+{
+public:
+	typedef SSGroupImpl Impl;
+	explicit SSGroup(Impl *impl) : Key(impl) {}
+
+	SSGroup() : Key(NULL) {}
+
+	// Create a new group.
+	SSGroup(const SSDb &ssDb,
+			const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry)
+	: Key(new Impl(ssDb, credAndAclEntry)) {}
+
+	// Lookup an existing group based on a dataBlob.
+	SSGroup(const SSDb &ssDb, const CSSM_DATA &dataBlob)
+	: Key(new Impl(ssDb, dataBlob)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+};
+
+
+//
+// SSDbCursor -- Cursor for iterating over Securely Stored records (or keys)
+//
+class SSDbCursorImpl : public DbDbCursorImpl
+{
+public:
+	SSDbCursorImpl(const Db &db, const CSSM_QUERY &query,
+				   CssmAllocator &allocator);
+	SSDbCursorImpl(const Db &db, uint32 capacity,
+				   CssmAllocator &allocator);
+
+	bool next(DbAttributes *attributes, ::CssmDataContainer *data,
+			  DbUniqueRecord &uniqueId);
+	bool next(DbAttributes *attributes, ::CssmDataContainer *data,
+			  DbUniqueRecord &uniqueId, const CSSM_ACCESS_CREDENTIALS *cred);
+	bool nextKey(DbAttributes *attributes, Key &key, DbUniqueRecord &uniqueId);
+	//bool nextGroup(DbAttributes *attributes, SSGroup &group, DbUniqueRecord &uniqueId);
+
+	SSDb database() { return parent<SSDb>(); }
+protected:
+	void activate();
+	void deactivate();
+};
+
+class SSDbCursor : public DbCursor
+{
+public:
+	typedef SSDbCursorImpl Impl;
+
+	explicit SSDbCursor(Impl *impl) : DbCursor(impl) {}
+	SSDbCursor(const SSDb &ssDb, const CSSM_QUERY &query,
+			   CssmAllocator &allocator = CssmAllocator::standard())
+		: DbCursor(ssDb->newDbCursor(query, allocator)) {}
+	SSDbCursor(const SSDb &ssDb, const uint32 capacity = 0,
+			   CssmAllocator &allocator = CssmAllocator::standard())
+		: DbCursor(ssDb->newDbCursor(capacity, allocator)) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+};
+
+
+//
+// SSDbUniqueRecord
+//
+class SSDbUniqueRecordImpl : public DbUniqueRecordImpl
+{
+public:
+	SSDbUniqueRecordImpl(const Db &db);
+	virtual ~SSDbUniqueRecordImpl();
+
+	void deleteRecord();
+	void deleteRecord(const CSSM_ACCESS_CREDENTIALS *cred);
+	void modify(CSSM_DB_RECORDTYPE recordType,
+				const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+				const CSSM_DATA *data,
+				CSSM_DB_MODIFY_MODE modifyMode);
+	void modify(CSSM_DB_RECORDTYPE recordType,
+				const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
+				const CSSM_DATA *data,
+				CSSM_DB_MODIFY_MODE modifyMode,
+				const CSSM_ACCESS_CREDENTIALS *cred);
+	void get(DbAttributes *attributes, ::CssmDataContainer *data);
+	void get(DbAttributes *attributes, ::CssmDataContainer *data,
+			 const CSSM_ACCESS_CREDENTIALS *cred);
+
+	SSDb database() { return parent<SSDb>(); }
+
+	// Return the group that this record is in.
+	SSGroup group();
+};
+
+class SSDbUniqueRecord : public DbUniqueRecord
+{
+public:
+	typedef SSDbUniqueRecordImpl Impl;
+
+	explicit SSDbUniqueRecord(Impl *impl) : DbUniqueRecord(impl) {}
+	SSDbUniqueRecord(const SSDb &ssDb)
+		: DbUniqueRecord(ssDb->newDbUniqueRecord()) {}
+
+	Impl *operator ->() const { return &impl<Impl>(); }
+	Impl &operator *() const { return impl<Impl>(); }
+};
+
+}; // end namespace CssmClient
+
+} // end namespace Security
+
+#endif //_H_CDSA_CLIENT_SECURESTORAGE
diff --git a/cdsa/cdsa_client/signclient.cpp b/cdsa/cdsa_client/signclient.cpp
new file mode 100644
index 00000000..91b4718e
--- /dev/null
+++ b/cdsa/cdsa_client/signclient.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+
+//
+// signclient - client interface to CSSM sign/verify contexts
+//
+#include <Security/signclient.h>
+
+using namespace CssmClient;
+
+//
+// Common features of signing and verify contexts
+//
+void SigningContext::activate()
+{
+	if (!mActive)
+	{
+		check(CSSM_CSP_CreateSignatureContext(attachment()->handle(), mAlgorithm,
+			  NULL/*cred*/, mKey, &mHandle));
+		mActive = true;
+	}
+}
+
+
+//
+// Signing
+//
+void Sign::sign(const CssmData *data, uint32 count, CssmData &signature)
+{
+	unstaged();
+	check(CSSM_SignData(handle(), data, count, mSignOnly, &signature));
+}
+
+void Sign::init()
+{
+	check(CSSM_SignDataInit(handle()));
+	mStaged = true;
+}
+
+void Sign::sign(const CssmData *data, uint32 count)
+{
+	staged();
+	check(CSSM_SignDataUpdate(handle(), data, count));
+}
+
+void Sign::operator () (CssmData &signature)
+{
+	staged();
+	check(CSSM_SignDataFinal(handle(), &signature));
+	mStaged = false;
+}
+
+
+//
+// Verifying
+//
+void Verify::verify(const CssmData *data, uint32 count, const CssmData &signature)
+{
+	unstaged();
+	check(CSSM_VerifyData(handle(), data, count, mSignOnly, &signature));
+}
+
+void Verify::init()
+{
+	check(CSSM_VerifyDataInit(handle()));
+	mStaged = true;
+}
+
+void Verify::verify(const CssmData *data, uint32 count)
+{
+	staged();
+	check(CSSM_VerifyDataUpdate(handle(), data, count));
+}
+
+void Verify::operator () (const CssmData &signature)
+{
+	staged();
+	check(CSSM_VerifyDataFinal(handle(), &signature));
+	mStaged = false;
+}
diff --git a/cdsa/cdsa_client/signclient.h b/cdsa/cdsa_client/signclient.h
new file mode 100644
index 00000000..1c625d6b
--- /dev/null
+++ b/cdsa/cdsa_client/signclient.h
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+
+//
+// signclient - client interface to CSSM sign/verify contexts
+//
+#ifndef _H_CDSA_CLIENT_SIGNCLIENT
+#define _H_CDSA_CLIENT_SIGNCLIENT  1
+
+#include <Security/cspclient.h>
+#include <Security/keyclient.h>
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+//
+// A signing/verifying context
+//
+class SigningContext : public Context
+{
+public:
+	SigningContext(const CSP &csp, CSSM_ALGORITHMS alg, CSSM_ALGORITHMS signOnly = CSSM_ALGID_NONE)
+	: Context(csp, alg), mSignOnly(signOnly) { }
+
+	// preliminary interface
+	Key key() const { assert(mKey); return mKey; }
+	void key(const Key &k) { mKey = k; set(CSSM_ATTRIBUTE_KEY, mKey); }
+
+protected:
+	void activate();
+	CSSM_ALGORITHMS mSignOnly;
+	Key mKey;
+};
+
+
+class Sign : public SigningContext
+{
+public:
+	Sign(const CSP &csp, CSSM_ALGORITHMS alg) : SigningContext(csp, alg) { }
+	
+	// integrated
+	void sign(const CssmData &data, CssmData &signature) { sign(&data, 1, signature); }
+	void sign(const CssmData *data, uint32 count, CssmData &signature);
+
+	// staged
+	void init(); // Optional
+	void sign(const CssmData &data) { sign(&data, 1); }
+	void sign(const CssmData *data, uint32 count);
+	void operator () (CssmData &signature);
+	CssmData operator () () { CssmData signature; (*this)(signature); return signature; }
+};
+
+class Verify : public SigningContext
+{
+public:
+	Verify(const CSP &csp, CSSM_ALGORITHMS alg) : SigningContext(csp, alg) { }
+	
+	// integrated
+	void verify(const CssmData &data, const CssmData &signature) { verify(&data, 1, signature); }
+	void verify(const CssmData *data, uint32 count, const CssmData &signature);
+
+	// staged
+	void init(); // Optional
+	void verify(const CssmData &data) { verify(&data, 1); }
+	void verify(const CssmData *data, uint32 count);
+	void operator () (const CssmData &signature);
+};
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_SIGNCLIENT
diff --git a/cdsa/cdsa_client/wrapkey.cpp b/cdsa/cdsa_client/wrapkey.cpp
new file mode 100644
index 00000000..981df26d
--- /dev/null
+++ b/cdsa/cdsa_client/wrapkey.cpp
@@ -0,0 +1,223 @@
+/*
+ * 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.
+ */
+
+
+//
+// wrapkey - client interface for wrapping and unwrapping keys
+//
+#include <Security/wrapkey.h>
+
+using namespace CssmClient;
+
+
+Key
+WrapKey::operator () (Key &keyToBeWrapped, const CssmData *descriptiveData)
+{
+	Key wrappedKey;
+
+	check(CSSM_WrapKey(handle(), mCred, keyToBeWrapped, descriptiveData,
+					   wrappedKey.makeNewKey(attachment())));
+	wrappedKey->activate();
+
+	return wrappedKey;
+}
+
+void
+WrapKey::operator () (const CssmKey &keyToBeWrapped, CssmKey &wrappedKey,
+					  const CssmData *descriptiveData)
+{
+	check(CSSM_WrapKey(handle(), mCred, &keyToBeWrapped, descriptiveData, &wrappedKey));
+}
+
+void
+WrapKey::activate()
+{
+	if (!mActive)
+	{
+		Crypt::activate();
+		if (mWrappedKeyFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE);
+			set(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT, mWrappedKeyFormat);
+	}
+}
+
+Key
+UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec)
+{
+	Key unwrappedKey;
+
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+	CssmData data(reinterpret_cast<uint8 *>(1), 0);
+
+	check(CSSM_UnwrapKey(handle(), NULL,
+						 &keyToBeUnwrapped, spec.usage, spec.attributes,
+						 spec.label, &resourceControlContext,
+						 unwrappedKey.makeNewKey(attachment()), &data));
+	unwrappedKey->activate();
+
+	return unwrappedKey;
+}
+
+void
+UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+						CssmKey &unwrappedKey)
+{
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+	CssmData data(reinterpret_cast<uint8 *>(1), 0);
+
+	check(CSSM_UnwrapKey(handle(), NULL, &keyToBeUnwrapped, spec.usage,
+						 spec.attributes, spec.label, &resourceControlContext,
+						 &unwrappedKey, &data));
+}
+
+Key
+UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+						Key &optionalPublicKey)
+{
+	Key unwrappedKey;
+
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+	CssmData data(reinterpret_cast<uint8 *>(1), 0);
+
+	check(CSSM_UnwrapKey(handle(), optionalPublicKey,
+						 &keyToBeUnwrapped, spec.usage, spec.attributes,
+						 spec.label, &resourceControlContext,
+						 unwrappedKey.makeNewKey(attachment()), &data));
+
+	unwrappedKey->activate();
+
+	return unwrappedKey;
+}
+
+void
+UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+						CssmKey &unwrappedKey,
+						const CssmKey *optionalPublicKey)
+{
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+	CssmData data(reinterpret_cast<uint8 *>(1), 0);
+
+	check(CSSM_UnwrapKey(handle(), optionalPublicKey, &keyToBeUnwrapped,
+						 spec.usage, spec.attributes, spec.label,
+						 &resourceControlContext, &unwrappedKey, &data));
+}
+
+
+Key
+UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+						CssmData *descriptiveData)
+{
+	Key unwrappedKey;
+
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+
+	check(CSSM_UnwrapKey(handle(), NULL, &keyToBeUnwrapped, spec.usage,
+						 spec.attributes, spec.label, &resourceControlContext,
+						 unwrappedKey.makeNewKey(attachment()),
+						 descriptiveData));
+	unwrappedKey->activate();
+
+	return unwrappedKey;
+}
+
+void
+UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+						CssmKey &unwrappedKey, CssmData *descriptiveData)
+{
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+
+	check(CSSM_UnwrapKey(handle(), NULL, &keyToBeUnwrapped, spec.usage,
+						 spec.attributes, spec.label, &resourceControlContext,
+						 &unwrappedKey, descriptiveData));
+}
+
+Key
+UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+						Key &optionalPublicKey, CssmData *descriptiveData)
+{
+	Key unwrappedKey;
+
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+
+	check(CSSM_UnwrapKey(handle(), optionalPublicKey, &keyToBeUnwrapped,
+						 spec.usage, spec.attributes, spec.label,
+						 &resourceControlContext,
+						 unwrappedKey.makeNewKey(attachment()),
+						 descriptiveData));
+	unwrappedKey->activate();
+
+	return unwrappedKey;
+}
+
+void
+UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+						CssmKey &unwrappedKey, CssmData *descriptiveData,
+						const CssmKey *optionalPublicKey)
+{
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+
+	check(CSSM_UnwrapKey(handle(), optionalPublicKey, &keyToBeUnwrapped,
+						 spec.usage, spec.attributes, spec.label,
+						 &resourceControlContext, &unwrappedKey,
+						 descriptiveData));
+}
+
+
+void DeriveKey::activate()
+{
+	if (!mActive)
+	{
+        check(CSSM_CSP_CreateDeriveKeyContext(attachment()->handle(), mAlgorithm,
+            mTargetType, mKeySize, mCred, mKey, mIterationCount, mSalt, mSeed, &mHandle));
+		mActive = true;
+    }
+}
+
+
+Key
+DeriveKey::operator () (CssmData *param, const KeySpec &spec)
+{
+	Key derivedKey;
+
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+
+	check(CSSM_DeriveKey(handle(), param, spec.usage, spec.attributes,
+						 spec.label, &resourceControlContext,
+						 derivedKey.makeNewKey(attachment())));
+	derivedKey->activate();
+
+	return derivedKey;
+}
+
+void
+DeriveKey::operator () (CssmData *param, const KeySpec &spec,
+						CssmKey &derivedKey)
+{
+	const ResourceControlContext resourceControlContext
+		(mAclEntry, const_cast<AccessCredentials *>(mCred));
+
+	check(CSSM_DeriveKey(handle(), param, spec.usage, spec.attributes,
+						 spec.label, &resourceControlContext, &derivedKey));
+}
diff --git a/cdsa/cdsa_client/wrapkey.h b/cdsa/cdsa_client/wrapkey.h
new file mode 100644
index 00000000..e38fefae
--- /dev/null
+++ b/cdsa/cdsa_client/wrapkey.h
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+
+//
+// wrapkey - client interface for wrapping and unwrapping keys
+//
+#ifndef _H_CDSA_CLIENT_WRAPKEY
+#define _H_CDSA_CLIENT_WRAPKEY  1
+
+#include <Security/cspclient.h>
+#include <Security/cryptoclient.h>
+#include <Security/keyclient.h>
+
+
+namespace Security
+{
+
+namespace CssmClient
+{
+
+class WrapKey : public Crypt
+{
+public:
+	WrapKey(const CSP &csp, CSSM_ALGORITHMS alg) :
+		Crypt(csp, alg), mWrappedKeyFormat(CSSM_KEYBLOB_WRAPPED_FORMAT_NONE) {}
+
+public:
+	CSSM_KEYBLOB_FORMAT wrappedKeyFormat() const { return mWrappedKeyFormat; }
+	void wrappedKeyFormat(CSSM_KEYBLOB_FORMAT wrappedKeyFormat)
+	{ mWrappedKeyFormat = wrappedKeyFormat; set(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT, wrappedKeyFormat); }
+
+	// wrap the key
+	Key operator () (Key &keyToBeWrapped, const CssmData *descriptiveData = NULL);
+	void operator () (const CssmKey &keyToBeWrapped, CssmKey &wrappedKey,
+					  const CssmData *descriptiveData = NULL);
+
+protected:
+	void activate();
+
+private:
+	CSSM_KEYBLOB_FORMAT mWrappedKeyFormat;
+};
+
+class UnwrapKey : public Crypt
+{
+public:
+	UnwrapKey(const CSP &csp, CSSM_ALGORITHMS alg) : Crypt(csp, alg) {}
+
+public:
+	// wrap the key
+	Key operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec);
+	void operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+					  CssmKey &unwrappedKey);
+
+	Key operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+					 Key &optionalPublicKey);
+	void operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+					  CssmKey &unwrappedKey, const CssmKey *optionalPublicKey);
+
+	Key operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+					 CssmData *descriptiveData);
+	void operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+					  CssmKey &unwrappedKey, CssmData *descriptiveData);
+
+	Key operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+					 Key &optionalPublicKey, CssmData *descriptiveData);
+	void operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec,
+					  CssmKey &unwrappedKey, CssmData *descriptiveData,
+					  const CssmKey *optionalPublicKey);
+};
+
+class DeriveKey : public Crypt
+{
+public:
+	DeriveKey(const CSP &csp, CSSM_ALGORITHMS alg, CSSM_ALGORITHMS target, uint32 size = 0)
+    : Crypt(csp, alg), mKeySize(size), mTargetType(target), mIterationCount(0),
+      mSeed(NULL), mSalt(NULL) { }
+
+public:
+    CSSM_ALGORITHMS targetType() const { return mTargetType; }
+    void targetType(CSSM_ALGORITHMS alg) { mTargetType = alg; }
+    uint32 iterationCount() const		{ return mIterationCount; }
+    void iterationCount(uint32 c)		{ mIterationCount = c; }
+    const CssmCryptoData seed() const	{ return *mSeed; }
+    void seed(const CssmCryptoData &data) { mSeed = &data; }
+    const CssmData salt() const			{ return *mSalt; }
+    void salt(const CssmData &data)		{ mSalt = &data; }
+
+	Key operator () (CssmData *param, const KeySpec &spec);
+	void operator () (CssmData *param, const KeySpec &spec,
+					  CssmKey &derivedKey);
+                      
+    void activate();
+    
+private:
+	uint32 mKeySize;
+    CSSM_ALGORITHMS mTargetType;
+    uint32 mIterationCount;
+    const CssmCryptoData *mSeed;
+    const CssmData *mSalt;
+};
+
+} // end namespace CssmClient
+
+} // end namespace Security
+
+#endif // _H_CDSA_CLIENT_WRAPKEY
diff --git a/cdsa/cdsa_pluginlib.cpp b/cdsa/cdsa_pluginlib.cpp
new file mode 100644
index 00000000..aa40724c
--- /dev/null
+++ b/cdsa/cdsa_pluginlib.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+
+/* Headers. */
+#include <cdsa_pluginlib/c++plugin.h>
+#include <cdsa_pluginlib/cssmplugin.h>
+#include <cdsa_pluginlib/pluginsession.h>
+#include <cdsa_pluginlib/ACsession.h>
+#include <cdsa_pluginlib/CLsession.h>
+#include <cdsa_pluginlib/CSPsession.h>
+#include <cdsa_pluginlib/DLsession.h>
+#include <cdsa_pluginlib/TPsession.h>
+#include <cdsa_pluginlib/ACabstractsession.h>
+#include <cdsa_pluginlib/CLabstractsession.h>
+#include <cdsa_pluginlib/CSPabstractsession.h>
+#include <cdsa_pluginlib/DLabstractsession.h>
+#include <cdsa_pluginlib/TPabstractsession.h>
+
+/* Source files. */
+#include <cdsa_pluginlib/CSPsession.cpp>
+#include <cdsa_pluginlib/DLsession.cpp>
+#include <cdsa_pluginlib/csputilities.cpp>
+#include <cdsa_pluginlib/cssmplugin.cpp>
+#include <cdsa_pluginlib/pluginsession.cpp>
+#include <ACabstractsession.cpp>
+#include <CLabstractsession.cpp>
+#include <CSPabstractsession.cpp>
+#include <DLabstractsession.cpp>
+#include <TPabstractsession.cpp>
diff --git a/cdsa/cdsa_pluginlib/.cvsignore b/cdsa/cdsa_pluginlib/.cvsignore
new file mode 100644
index 00000000..d2615714
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/.cvsignore
@@ -0,0 +1 @@
+cdsa_pluginlib?Data
diff --git a/cdsa/cdsa_pluginlib/ACsession.h b/cdsa/cdsa_pluginlib/ACsession.h
new file mode 100644
index 00000000..085af035
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/ACsession.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+//
+// ACsession.h - Framework for AC plugin modules
+//
+#ifndef _H_ACSESSION
+#define _H_ACSESSION
+
+#include <Security/ACabstractsession.h>
+
+#if defined(_CPP_ACSESSION)
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// The abstract ACPluginSession class is the common ancestor of your implementation
+// object for an AC type plugin attachment session. Inherit from this and implement
+// the abstract methods to define a plugin session.
+//
+class ACPluginSession : public PluginSession, public ACAbstractPluginSession {
+public:
+    ACPluginSession(CSSM_MODULE_HANDLE theHandle,
+                    CssmPlugin &plug,
+                    const CSSM_VERSION &version,
+                    uint32 subserviceId,
+                    CSSM_SERVICE_TYPE subserviceType,
+                    CSSM_ATTACH_FLAGS attachFlags,
+                    const CSSM_UPCALLS &upcalls)
+      : PluginSession(theHandle, plug, version, subserviceId, subserviceType, attachFlags, upcalls) { }
+
+protected:
+    CSSM_MODULE_FUNCS_PTR construct();
+};
+
+} // end namespace Security
+
+#if defined(_CPP_ACSESSION)
+# pragma export off
+#endif
+
+#endif //_H_ACSESSION
diff --git a/cdsa/cdsa_pluginlib/CLsession.h b/cdsa/cdsa_pluginlib/CLsession.h
new file mode 100644
index 00000000..a006173a
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/CLsession.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+//
+// CLsession.h - Framework for CL plugin modules
+//
+#ifndef _H_CLSESSION
+#define _H_CLSESSION
+
+#include <Security/CLabstractsession.h>
+
+#if defined(_CPP_CLSESSION)
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// The abstract CLPluginSession class is the common ancestor of your implementation
+// object for an CL type plugin attachment session. Inherit from this and implement
+// the abstract methods to define a plugin session.
+//
+class CLPluginSession : public PluginSession, public CLAbstractPluginSession {
+public:
+    CLPluginSession(CSSM_MODULE_HANDLE theHandle,
+                    CssmPlugin &plug,
+                    const CSSM_VERSION &version,
+                    uint32 subserviceId,
+                    CSSM_SERVICE_TYPE subserviceType,
+                    CSSM_ATTACH_FLAGS attachFlags,
+                    const CSSM_UPCALLS &upcalls)
+      : PluginSession(theHandle, plug, version, subserviceId, subserviceType, attachFlags, upcalls) { }
+
+protected:
+    CSSM_MODULE_FUNCS_PTR construct();
+};
+
+} // end namespace Security
+
+#if defined(_CPP_CLSESSION)
+# pragma export off
+#endif
+
+#endif //_H_CLSESSION
diff --git a/cdsa/cdsa_pluginlib/CSPsession.cpp b/cdsa/cdsa_pluginlib/CSPsession.cpp
new file mode 100644
index 00000000..d18fd08e
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/CSPsession.cpp
@@ -0,0 +1,1026 @@
+/*
+ * 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.
+ */
+
+
+//
+// CSPsession - Plugin framework for CSP plugin modules
+//
+#ifdef __MWERKS__
+#define _CPP_CSPSESSION
+#endif
+
+#include <Security/CSPsession.h>
+#include <Security/cssmplugin.h>
+
+
+typedef CSPFullPluginSession::CSPContext CSPContext;
+
+
+//
+// PluginContext construction
+//
+CSPPluginSession::PluginContext::~PluginContext()
+{ }
+
+
+//
+// Internal utilities
+//
+inline CssmData CSPFullPluginSession::makeBuffer(size_t size, CssmAllocator &alloc)
+{
+	return CssmData(alloc.malloc(size), size);
+}
+
+inline size_t CSPFullPluginSession::totalBufferSize(const CssmData *data, uint32 count)
+{
+	size_t size = 0;
+	for (uint32 n = 0; n < count; n++)
+		size += data[n].length();
+	return size;
+}
+
+
+//
+// Notify a context that its underlying CSSM context has (well, may have) changed.
+// The default reaction is to ask the frame to delete the context and start over.
+//
+bool CSPPluginSession::PluginContext::changed(const Context &context)
+{
+    return false;	// delete me, please
+}
+
+
+//
+// The Session's init() function calls your setupContext() method to prepare
+// it for action, then calls the context's init() method.
+//
+CSPContext *CSPFullPluginSession::init(CSSM_CC_HANDLE ccHandle,
+									CSSM_CONTEXT_TYPE type,
+									const Context &context, bool encoding)
+{
+    CSPContext *ctx = getContext<CSPContext>(ccHandle);
+    checkOperation(context.type(), type);
+
+    // ask the implementation to set up an internal context
+    setupContext(ctx, context, encoding);
+    assert(ctx != NULL);	// must have context now (@@@ throw INTERNAL_ERROR instead?)
+    ctx->mType = context.type();
+    ctx->mDirection = encoding;
+    setContext(ccHandle, ctx);
+
+    // initialize the context and return it
+    ctx->init(context, encoding);
+    return ctx;
+}
+
+
+//
+// Retrieve a context for a staged operation in progress.
+//
+CSPContext *CSPFullPluginSession::getStagedContext(CSSM_CC_HANDLE ccHandle,
+	CSSM_CONTEXT_TYPE type, bool encoding)
+{
+	CSPContext *ctx = getContext<CSPContext>(ccHandle);
+	if (ctx == NULL)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);	//@@@ better diagnostic?
+	checkOperation(ctx->type(), type);
+	if (ctx->encoding() != encoding)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
+	return ctx;
+}
+
+
+//
+// The Session's checkState() function is called for subsequent staged operations
+// (update/final) to verify that the user didn't screw up the sequencing.
+//
+void CSPFullPluginSession::checkOperation(CSSM_CONTEXT_TYPE ctxType, CSSM_CONTEXT_TYPE opType)
+{
+    switch (opType) {
+        case CSSM_ALGCLASS_NONE:	// no check
+            return;
+        case CSSM_ALGCLASS_CRYPT:	// symmetric or asymmetric encryption
+            if (ctxType == CSSM_ALGCLASS_SYMMETRIC ||
+                ctxType == CSSM_ALGCLASS_ASYMMETRIC)
+                return;
+        default:					// plain match
+            if (ctxType == opType)
+                return;
+    }
+    CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
+}
+
+
+//
+// The default implementations of the primary context operations throw internal
+// errors. You must implement any of these that are actually called by the
+// operations involved. The others, of course, can be left alone.
+//
+void CSPContext::init(const Context &context, bool encoding)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+void CSPContext::update(const CssmData &data)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+void CSPContext::update(void *inp, size_t &inSize, void *outp, size_t &outSize)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+void CSPContext::final(CssmData &out)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+void CSPContext::final(const CssmData &in)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+void CSPContext::generate(const Context &, CssmKey &pubKey, CssmKey &privKey)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+void CSPContext::generate(const Context &, uint32, CssmData &params,
+                                                uint32 &attrCount, Context::Attr * &attrs)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+size_t CSPContext::inputSize(size_t outSize)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+size_t CSPContext::outputSize(bool final, size_t inSize)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+void CSPContext::minimumProgress(size_t &in, size_t &out)
+{ CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); }
+
+CSPFullPluginSession::CSPContext *CSPContext::clone(CssmAllocator &)
+{ CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED); }
+
+void CSPContext::setDigestAlgorithm(CSSM_ALGORITHMS digestAlg)
+{ CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); }
+
+void CSPContext::update(const CssmData *in,
+						uint32 inCount, Writer &writer)
+{
+    const CssmData *lastIn = in + inCount;
+    CssmData current;
+    for (;;) {
+        if (current.length() == 0) {
+            if (in == lastIn)
+                return;		// all done
+            current = *in++;
+			continue; // Just in case next block is zero length too.
+        }
+        // match up current input and output buffers
+        void *outP; size_t outSize;
+        writer.nextBlock(outP, outSize);
+        size_t inSize = inputSize(outSize);
+        if (inSize > current.length())
+            inSize = current.length();	// cap to remaining input buffer
+        if (inSize > 0) {
+            // we can stuff into the current output buffer - do it
+            update(current.data(), inSize, outP, outSize);
+            current.use(inSize);
+            writer.use(outSize);
+        } else {
+            // We have remaining output buffer space, but not enough
+            // for the algorithm to make progress with it. We must proceed with
+            // a bounce buffer and split it manually into this and the next buffer(s).
+            size_t minOutput;
+            minimumProgress(inSize, minOutput);
+            assert(minOutput > outSize);		// PluginContext consistency (not fatal)
+            char splitBuffer[128];
+            assert(minOutput <= sizeof(splitBuffer)); // @@@ static buffer for now
+            outSize = sizeof(splitBuffer);
+            if (current.length() < inSize)
+                inSize = current.length();	// cap to data remaining in input buffer
+            update(current.data(), inSize, splitBuffer, outSize);
+            assert(inSize > 0);				// progress made
+            writer.put(splitBuffer, outSize);	// stuff into buffer, the hard way
+            current.use(inSize);
+        }
+    }
+}
+
+void CSPContext::final(CssmData &out, CssmAllocator &alloc)
+{
+    size_t needed = outputSize(true, 0);
+    if (out) {
+        if (out.length() < needed)
+            CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+    } else {
+        out = makeBuffer(needed, alloc);
+    }
+    final(out);
+}
+
+void CSPContext::final(Writer &writer, CssmAllocator &alloc)
+{
+    if (size_t needed = outputSize(true, 0)) {
+        // need to generate additional output
+        writer.allocate(needed, alloc);		// belt + suspender
+    
+        void *addr; size_t size;
+        writer.nextBlock(addr, size);		// next single block available
+        if (needed <= size) {				// rest fits into one block
+            CssmData chunk(addr, size);
+            final(chunk);
+            writer.use(chunk.length());
+        } else {							// need to split it up
+            char splitBuffer[128];
+            assert(needed <= sizeof(splitBuffer));
+            CssmData chunk(splitBuffer, sizeof(splitBuffer));
+            final(chunk);
+            writer.put(chunk.data(), chunk.length());
+        }
+    }
+}
+
+
+//
+// Default context response functions
+//
+CSPPluginSession::PluginContext *
+CSPPluginSession::contextCreate(CSSM_CC_HANDLE, const Context &)
+{
+	return NULL;	// request no local context
+}
+
+void CSPPluginSession::contextUpdate(CSSM_CC_HANDLE ccHandle,
+                                     const Context &context, PluginContext * &ctx)
+{
+    // call update notifier in context object
+    if (ctx && !ctx->changed(context)) {
+        // context requested that it be removed
+        delete ctx;
+        ctx = NULL;
+    }
+}
+
+void CSPPluginSession::contextDelete(CSSM_CC_HANDLE, const Context &, PluginContext *)
+{
+    // do nothing (you can't prohibit deletion here)
+}
+
+
+//
+// Default event notification handler.
+// This default handler calls the virtual context* methods to dispose of context actions.
+//
+void CSPPluginSession::EventNotify(CSSM_CONTEXT_EVENT event,
+                                   CSSM_CC_HANDLE ccHandle, const Context &context)
+{
+    switch (event) {
+        case CSSM_CONTEXT_EVENT_CREATE:
+            if (PluginContext *ctx = contextCreate(ccHandle, context)) {
+				StLock<Mutex> _(contextMapLock);
+                assert(contextMap[ccHandle] == NULL);	// check context re-creation
+                contextMap[ccHandle] = ctx;
+            }
+            break;
+        case CSSM_CONTEXT_EVENT_UPDATE:
+            // note that the handler can change the map entry (even to NULL, if desired)
+			{
+				StLock<Mutex> _(contextMapLock);
+				contextUpdate(ccHandle, context, contextMap[ccHandle]);
+			}
+            break;
+        case CSSM_CONTEXT_EVENT_DELETE:
+			{
+				StLock<Mutex> _(contextMapLock);
+				if (PluginContext *ctx = contextMap[ccHandle]) {
+					contextDelete(ccHandle, context, ctx);
+					delete ctx;
+				}
+				contextMap.erase(ccHandle);
+			}
+			break;
+        default:
+            CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	// unexpected event code
+    }
+}
+
+
+//
+// Defaults for methods you *should* implement.
+// If you don't, they'll throw UNIMPLEMENTED.
+//
+void CSPFullPluginSession::getKeySize(const CssmKey &key, CSSM_KEY_SIZE &size)
+{ unimplemented(); }
+ 
+
+//
+// Encryption and decryption
+//
+void CSPFullPluginSession::EncryptData(CSSM_CC_HANDLE ccHandle,
+                                       const Context &context,
+                                       const CssmData clearBufs[],
+                                       uint32 clearBufCount,
+                                       CssmData cipherBufs[],
+                                       uint32 cipherBufCount,
+                                       uint32 &bytesEncrypted,
+                                       CssmData &remData,
+                                       CSSM_PRIVILEGE privilege)
+{
+    Writer writer(cipherBufs, cipherBufCount, &remData);
+    CSPContext *ctx = init(ccHandle, CSSM_ALGCLASS_CRYPT, context, true);
+    size_t outNeeded = ctx->outputSize(true, totalBufferSize(clearBufs, clearBufCount));
+    writer.allocate(outNeeded, *this);
+    ctx->update(clearBufs, clearBufCount, writer);
+    ctx->final(writer, *this);
+    bytesEncrypted = writer.close();
+}
+
+void CSPFullPluginSession::EncryptDataInit(CSSM_CC_HANDLE ccHandle,
+                             const Context &context,
+                             CSSM_PRIVILEGE Privilege)
+{
+    init(ccHandle, CSSM_ALGCLASS_CRYPT, context, true);
+}
+
+void CSPFullPluginSession::EncryptDataUpdate(CSSM_CC_HANDLE ccHandle,
+                                         const CssmData clearBufs[],
+                                         uint32 clearBufCount,
+                                         CssmData cipherBufs[],
+                                         uint32 cipherBufCount,
+                                         uint32 &bytesEncrypted)
+{
+    CSPContext *alg = getStagedContext(ccHandle, CSSM_ALGCLASS_CRYPT, true);
+    Writer writer(cipherBufs, cipherBufCount);
+    size_t outNeeded = alg->outputSize(false, totalBufferSize(clearBufs, clearBufCount));
+    writer.allocate(outNeeded, *this);
+    alg->update(clearBufs, clearBufCount, writer);
+    bytesEncrypted = writer.close();
+}
+
+void CSPFullPluginSession::EncryptDataFinal(CSSM_CC_HANDLE ccHandle,
+                              CssmData &remData)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_CRYPT, true)->final(remData, *this);
+}
+
+
+void CSPFullPluginSession::DecryptData(CSSM_CC_HANDLE ccHandle,
+                                   const Context &context,
+                                   const CssmData cipherBufs[],
+                                   uint32 cipherBufCount,
+                                   CssmData clearBufs[],
+                                   uint32 clearBufCount,
+                                   uint32 &bytesDecrypted,
+                                   CssmData &remData,
+                                   CSSM_PRIVILEGE privilege)
+{
+    Writer writer(clearBufs, clearBufCount, &remData);
+    CSPContext *ctx = init(ccHandle, CSSM_ALGCLASS_CRYPT, context, false);
+    size_t outNeeded = ctx->outputSize(true, totalBufferSize(cipherBufs, cipherBufCount));
+    writer.allocate(outNeeded, *this);
+    ctx->update(cipherBufs, cipherBufCount, writer);
+    ctx->final(writer, *this);
+    bytesDecrypted = writer.close();
+}
+
+void CSPFullPluginSession::DecryptDataInit(CSSM_CC_HANDLE ccHandle,
+                             const Context &context,
+                             CSSM_PRIVILEGE Privilege)
+{
+    init(ccHandle, CSSM_ALGCLASS_CRYPT, context, false);
+}
+
+void CSPFullPluginSession::DecryptDataUpdate(CSSM_CC_HANDLE ccHandle,
+                               const CssmData cipherBufs[],
+                               uint32 cipherBufCount,
+                               CssmData clearBufs[],
+                               uint32 clearBufCount,
+                               uint32 &bytesDecrypted)
+{
+    CSPContext *ctx = getStagedContext(ccHandle, CSSM_ALGCLASS_CRYPT, false);
+    Writer writer(clearBufs, clearBufCount);
+    size_t outNeeded = ctx->outputSize(false, totalBufferSize(cipherBufs, cipherBufCount));
+    writer.allocate(outNeeded, *this);
+    ctx->update(cipherBufs, cipherBufCount, writer);
+    bytesDecrypted = writer.close();
+}
+
+void CSPFullPluginSession::DecryptDataFinal(CSSM_CC_HANDLE ccHandle,
+                                      CssmData &remData)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_CRYPT, false)->final(remData, *this);
+}
+               
+void CSPFullPluginSession::QuerySize(CSSM_CC_HANDLE ccHandle,
+									 const Context &context,
+									 CSSM_BOOL encrypt,
+									 uint32 querySizeCount,
+									 QuerySizeData *dataBlock)
+{
+	if (querySizeCount == 0)
+		return;	// nothing ventured, nothing gained
+	CSPContext *ctx = getContext<CSPContext>(ccHandle);	// existing context?
+	if (ctx == NULL)	// force internal context creation (as best we can)
+		ctx = init(ccHandle, context.type(), context, encrypt);
+	// If QuerySizeCount > 1, we assume this inquires about a staged
+	// operation, and the LAST item gets the 'final' treatment.
+	//@@@ Intel revised algspec says "use the staged flag" -- TBD
+	for (uint32 n = 0; n < querySizeCount; n++) {
+		// the outputSize() call might throw CSSMERR_CSP_QUERY_SIZE_UNKNOWN
+		dataBlock[n].SizeOutputBlock =
+			ctx->outputSize(n == querySizeCount-1, dataBlock[n].inputSize());
+	}
+	//@@@ if we forced a context creation, should we discard it now?
+}
+
+
+//
+// Key wrapping and unwrapping.
+//
+void CSPFullPluginSession::WrapKey(CSSM_CC_HANDLE CCHandle,
+								const Context &Context,
+								const AccessCredentials &AccessCred,
+								const CssmKey &Key,
+								const CssmData *DescriptiveData,
+								CssmKey &WrappedKey,
+								CSSM_PRIVILEGE Privilege)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::UnwrapKey(CSSM_CC_HANDLE CCHandle,
+								const Context &Context,
+								const CssmKey *PublicKey,
+								const CssmKey &WrappedKey,
+								uint32 KeyUsage,
+								uint32 KeyAttr,
+								const CssmData *KeyLabel,
+								const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+								CssmKey &UnwrappedKey,
+								CssmData &DescriptiveData,
+								CSSM_PRIVILEGE Privilege)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::DeriveKey(CSSM_CC_HANDLE CCHandle,
+							const Context &Context,
+							CssmData &Param,
+							uint32 KeyUsage,
+							uint32 KeyAttr,
+							const CssmData *KeyLabel,
+							const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+							CssmKey &DerivedKey)
+{
+	unimplemented();
+}
+
+
+//
+// Message Authentication Codes.
+// Almost like signatures (signatures with symmetric keys), though the
+// underlying implementation may be somewhat different.
+//
+void CSPFullPluginSession::GenerateMac(CSSM_CC_HANDLE ccHandle,
+                                   const Context &context,
+                                   const CssmData dataBufs[],
+                                   uint32 dataBufCount,
+                                   CssmData &mac)
+{
+    GenerateMacInit(ccHandle, context);
+    GenerateMacUpdate(ccHandle, dataBufs, dataBufCount);
+    GenerateMacFinal(ccHandle, mac);
+}
+
+void CSPFullPluginSession::GenerateMacInit(CSSM_CC_HANDLE ccHandle,
+                                           const Context &context)
+{
+    init(ccHandle, CSSM_ALGCLASS_MAC, context, true);
+}
+
+void CSPFullPluginSession::GenerateMacUpdate(CSSM_CC_HANDLE ccHandle,
+                                             const CssmData dataBufs[],
+                                             uint32 dataBufCount)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_MAC, true)->update(dataBufs, dataBufCount);
+}
+
+void CSPFullPluginSession::GenerateMacFinal(CSSM_CC_HANDLE ccHandle,
+                                            CssmData &mac)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_MAC, true)->final(mac, *this);
+}
+
+void CSPFullPluginSession::VerifyMac(CSSM_CC_HANDLE ccHandle,
+                                     const Context &context,
+                                     const CssmData dataBufs[],
+                                     uint32 dataBufCount,
+                                     const CssmData &mac)
+{
+    VerifyMacInit(ccHandle, context);
+    VerifyMacUpdate(ccHandle, dataBufs, dataBufCount);
+    VerifyMacFinal(ccHandle, mac);
+}
+
+void CSPFullPluginSession::VerifyMacInit(CSSM_CC_HANDLE ccHandle,
+                                         const Context &context)
+{
+    init(ccHandle, CSSM_ALGCLASS_MAC, context, false);
+}
+
+void CSPFullPluginSession::VerifyMacUpdate(CSSM_CC_HANDLE ccHandle,
+                                           const CssmData dataBufs[],
+                                           uint32 dataBufCount)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_MAC, false)->update(dataBufs, dataBufCount);
+}
+
+void CSPFullPluginSession::VerifyMacFinal(CSSM_CC_HANDLE ccHandle,
+                                          const CssmData &mac)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_MAC, false)->final(mac);
+}
+
+
+//
+// Signatures
+//
+void CSPFullPluginSession::SignData(CSSM_CC_HANDLE ccHandle,
+                                const Context &context,
+                                const CssmData dataBufs[],
+                                uint32 dataBufCount,
+                                CSSM_ALGORITHMS digestAlgorithm,
+                                CssmData &Signature)
+{
+	SignDataInit(ccHandle, context);
+	if(digestAlgorithm != CSSM_ALGID_NONE) {
+		getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, 
+			true)->setDigestAlgorithm(digestAlgorithm);
+	}
+	SignDataUpdate(ccHandle, dataBufs, dataBufCount);
+	SignDataFinal(ccHandle, Signature);
+}
+
+void CSPFullPluginSession::SignDataInit(CSSM_CC_HANDLE ccHandle,
+                                    const Context &context)
+{
+    init(ccHandle, CSSM_ALGCLASS_SIGNATURE, context, true);
+}
+
+void CSPFullPluginSession::SignDataUpdate(CSSM_CC_HANDLE ccHandle,
+                    const CssmData dataBufs[],
+                    uint32 dataBufCount)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, true)->update(dataBufs, dataBufCount);
+}
+
+void CSPFullPluginSession::SignDataFinal(CSSM_CC_HANDLE ccHandle,
+                           CssmData &signature)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, true)->final(signature, *this);
+}
+
+
+void CSPFullPluginSession::VerifyData(CSSM_CC_HANDLE ccHandle,
+                                  const Context &context,
+                                  const CssmData dataBufs[],
+                                  uint32 dataBufCount,
+                                  CSSM_ALGORITHMS digestAlgorithm,
+                                  const CssmData &Signature)
+{
+	VerifyDataInit(ccHandle, context);
+	if(digestAlgorithm != CSSM_ALGID_NONE) {
+		getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, 
+			false)->setDigestAlgorithm(digestAlgorithm);
+	}
+	VerifyDataUpdate(ccHandle, dataBufs, dataBufCount);
+	VerifyDataFinal(ccHandle, Signature);
+}
+
+void CSPFullPluginSession::VerifyDataInit(CSSM_CC_HANDLE ccHandle, const Context &context)
+{
+    init(ccHandle, CSSM_ALGCLASS_SIGNATURE, context, false);
+}
+
+void CSPFullPluginSession::VerifyDataUpdate(CSSM_CC_HANDLE ccHandle,
+                                        const CssmData dataBufs[],
+                                        uint32 dataBufCount)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, false)->update(dataBufs, dataBufCount);
+}
+
+void CSPFullPluginSession::VerifyDataFinal(CSSM_CC_HANDLE ccHandle,
+                     const CssmData &signature)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_SIGNATURE, false)->final(signature);
+}
+
+
+//
+// Digesting
+//
+void CSPFullPluginSession::DigestData(CSSM_CC_HANDLE ccHandle,
+               const Context &context,
+               const CssmData dataBufs[],
+               uint32 DataBufCount,
+               CssmData &Digest)
+{
+    DigestDataInit(ccHandle, context);
+    DigestDataUpdate(ccHandle, dataBufs, DataBufCount);
+    DigestDataFinal(ccHandle, Digest);
+}
+
+void CSPFullPluginSession::DigestDataInit(CSSM_CC_HANDLE ccHandle, const Context &context)
+{
+    init(ccHandle, CSSM_ALGCLASS_DIGEST, context);
+}
+
+void CSPFullPluginSession::DigestDataUpdate(CSSM_CC_HANDLE ccHandle,
+                              const CssmData dataBufs[],
+                              uint32 dataBufCount)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_DIGEST)->update(dataBufs, dataBufCount);
+}
+
+void CSPFullPluginSession::DigestDataFinal(CSSM_CC_HANDLE ccHandle,
+                                           CssmData &digest)
+{
+    getStagedContext(ccHandle, CSSM_ALGCLASS_DIGEST)->final(digest, *this);
+}
+
+void CSPFullPluginSession::DigestDataClone(CSSM_CC_HANDLE ccHandle,
+                                           CSSM_CC_HANDLE clonedCCHandle)
+{
+	setContext(clonedCCHandle, getStagedContext(ccHandle, CSSM_ALGCLASS_DIGEST)->clone(*this));
+}
+
+
+//
+// Key generation, Derivation, and inquiry
+//
+void CSPFullPluginSession::GenerateKey(CSSM_CC_HANDLE ccHandle,
+                         const Context &context,
+                         uint32 keyUsage,
+                         uint32 keyAttr,
+                         const CssmData *keyLabel,
+                         const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry,
+                         CssmKey &key,
+                         CSSM_PRIVILEGE privilege)
+{
+    CSPContext *alg = init(ccHandle, CSSM_ALGCLASS_KEYGEN, context);
+    setKey(key, context, CSSM_KEYCLASS_SESSION_KEY, keyAttr, keyUsage);
+    CssmKey blank;		// dummy 2nd key (not used)
+    alg->generate(context, key, blank);
+}
+
+void CSPFullPluginSession::GenerateKeyPair(CSSM_CC_HANDLE ccHandle,
+                             const Context &context,
+                             uint32 publicKeyUsage,
+                             uint32 publicKeyAttr,
+                             const CssmData *publicKeyLabel,
+                             CssmKey &publicKey,
+                             uint32 privateKeyUsage,
+                             uint32 privateKeyAttr,
+                             const CssmData *privateKeyLabel,
+                             const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry,
+                             CssmKey &privateKey,
+                             CSSM_PRIVILEGE privilege)
+{
+    CSPContext *alg = init(ccHandle, CSSM_ALGCLASS_KEYGEN, context);
+    
+    setKey(publicKey, context, CSSM_KEYCLASS_PUBLIC_KEY, publicKeyAttr, publicKeyUsage);
+    setKey(privateKey, context, CSSM_KEYCLASS_PRIVATE_KEY, privateKeyAttr, privateKeyUsage);
+    alg->generate(context, publicKey, privateKey);
+    //@@@ handle labels
+    //@@@ handle reference keys
+}
+
+void CSPFullPluginSession::ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
+														 CssmKey &PrivateKey)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::QueryKeySizeInBits(CSSM_CC_HANDLE ccHandle,
+						const Context *context,
+						const CssmKey *key,
+						CSSM_KEY_SIZE &keySize)
+{
+	if (context) {
+		getKeySize(context->get<CSSM_KEY>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY),
+			keySize);
+	} else {
+		getKeySize(CssmKey::required(key), keySize);
+	}
+}
+
+
+//
+// Free a key object.
+//
+void CSPFullPluginSession::FreeKey(const AccessCredentials *AccessCred,
+								   CssmKey &key,
+								   CSSM_BOOL Delete)
+{
+	free(key.data());
+}
+
+
+//
+// Random number and parameter generation
+//
+void CSPFullPluginSession::GenerateRandom(CSSM_CC_HANDLE ccHandle,
+                                          const Context &context,
+                                          CssmData &randomNumber)
+{
+    init(ccHandle, CSSM_ALGCLASS_RANDOMGEN, context)->final(randomNumber, *this);
+}
+
+void CSPFullPluginSession::GenerateAlgorithmParams(CSSM_CC_HANDLE ccHandle,
+                                    const Context &context,
+                                    uint32 paramBits,
+                                    CssmData &param,
+                                    uint32 &attrCount,
+                                    CSSM_CONTEXT_ATTRIBUTE_PTR &attrs)
+{
+    Context::Attr *attrList;
+    init(ccHandle, CSSM_ALGCLASS_NONE, context)->generate(context, paramBits,
+                                                          param, attrCount, attrList);
+    attrs = attrList;
+}
+
+
+//
+// Login/Logout and token operational maintainance.
+// These mean little without support by the actual implementation, but we can help...
+// @@@ Should this be in CSP[non-Full]PluginSession?
+//
+void CSPFullPluginSession::Login(const AccessCredentials &AccessCred,
+			const CssmData *LoginName,
+			const void *Reserved)
+{
+	if (Reserved != NULL)
+		CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
+		
+	// default implementation refuses to log in
+	//@@@ should hand it to implementation virtual defaulting to this
+	CssmError::throwMe(CSSMERR_CSP_INVALID_LOGIN_NAME);
+}
+
+void CSPFullPluginSession::Logout()
+{
+	if (!loggedIn(false))
+		CssmError::throwMe(CSSMERR_CSP_NOT_LOGGED_IN);
+}
+
+void CSPFullPluginSession::VerifyDevice(const CssmData &DeviceCert)
+{
+	CssmError::throwMe(CSSMERR_CSP_DEVICE_VERIFY_FAILED);
+}
+
+void CSPFullPluginSession::GetOperationalStatistics(CSPOperationalStatistics &statistics)
+{
+	memset(&statistics, 0, sizeof(statistics));
+	statistics.UserAuthenticated = loggedIn();
+	//@@@ collect device flags - capability matrix setup?
+	//@@@ collect token limitation parameters (static) - capability matrix setup?
+	//@@@ collect token statistics (dynamic) - dynamic accounting call-downs?
+}
+
+
+//
+// Utterly miscellaneous, rarely used, strange functions
+//
+void CSPFullPluginSession::RetrieveCounter(CssmData &Counter)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::RetrieveUniqueId(CssmData &UniqueID)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm, CssmData &TimeData)
+{
+	unimplemented();
+}
+
+
+//
+// ACL retrieval and change operations
+//
+void CSPFullPluginSession::GetKeyOwner(const CssmKey &Key,
+		CSSM_ACL_OWNER_PROTOTYPE &Owner)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::ChangeKeyOwner(const AccessCredentials &AccessCred,
+		const CssmKey &Key,
+		const CSSM_ACL_OWNER_PROTOTYPE &NewOwner)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::GetKeyAcl(const CssmKey &Key,
+		const CSSM_STRING *SelectionTag,
+		uint32 &NumberOfAclInfos,
+		CSSM_ACL_ENTRY_INFO_PTR &AclInfos)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::ChangeKeyAcl(const AccessCredentials &AccessCred,
+		const CSSM_ACL_EDIT &AclEdit,
+		const CssmKey &Key)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::GetLoginOwner(CSSM_ACL_OWNER_PROTOTYPE &Owner)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::ChangeLoginOwner(const AccessCredentials &AccessCred,
+		const CSSM_ACL_OWNER_PROTOTYPE &NewOwner)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::GetLoginAcl(const CSSM_STRING *SelectionTag,
+		uint32 &NumberOfAclInfos,
+		CSSM_ACL_ENTRY_INFO_PTR &AclInfos)
+{
+	unimplemented();
+}
+
+void CSPFullPluginSession::ChangeLoginAcl(const AccessCredentials &AccessCred,
+		const CSSM_ACL_EDIT &AclEdit)
+{
+	unimplemented();
+}
+
+
+
+//
+// Passthroughs (by default, unimplemented)
+//
+void CSPFullPluginSession::PassThrough(CSSM_CC_HANDLE CCHandle,
+										const Context &Context,
+										uint32 PassThroughId,
+										const void *InData,
+										void **OutData)
+{
+	unimplemented();
+}
+
+
+//
+// KeyPool -- ReferencedKey management functionality
+//
+KeyPool::KeyPool()
+{
+}
+
+KeyPool::~KeyPool()
+{
+	StLock<Mutex> _(mKeyMapLock);
+	// Delete every ReferencedKey in the pool, but be careful to deactivate them first
+	// to keep them from calling erase (which would cause deadlock since we already hold mKeyMapLock).
+	KeyMap::iterator end = mKeyMap.end();
+	for (KeyMap::iterator it = mKeyMap.begin(); it != end; ++it)
+	{
+		try
+		{
+			it->second->deactivate();
+		}
+		catch(...) {}
+		delete it->second;
+	}
+	mKeyMap.clear();
+}
+
+void
+KeyPool::add(ReferencedKey &referencedKey)
+{
+	StLock<Mutex> _(mKeyMapLock);
+	bool inserted = mKeyMap.insert(KeyMap::value_type(referencedKey.keyReference(), &referencedKey)).second;
+	// Since add is only called from the constructor of ReferencedKey we should
+	// never add a key that is already in mKeyMap
+	assert(inserted);
+}
+
+ReferencedKey &
+KeyPool::findKey(const CSSM_KEY &key) const
+{
+	return findKeyReference(ReferencedKey::keyReference(key));
+}
+
+ReferencedKey &
+KeyPool::findKeyReference(ReferencedKey::KeyReference keyReference) const
+{
+	StLock<Mutex> _(mKeyMapLock);
+	KeyMap::const_iterator it = mKeyMap.find(keyReference);
+	if (it == mKeyMap.end())
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
+
+	return *it->second;
+}
+
+void
+KeyPool::erase(ReferencedKey &referencedKey)
+{
+	erase(referencedKey.keyReference());
+}
+
+ReferencedKey &
+KeyPool::erase(ReferencedKey::KeyReference keyReference)
+{
+	StLock<Mutex> _(mKeyMapLock);
+	KeyMap::iterator it = mKeyMap.find(keyReference);
+	if (it == mKeyMap.end())
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
+
+	mKeyMap.erase(it);
+	ReferencedKey &referencedKey = *it->second;
+	return referencedKey;
+}
+
+// Erase keyReference from mKeyMap, free the ioKey, and delete the ReferencedKey
+void
+KeyPool::freeKey(CssmAllocator &allocator, CSSM_KEY &ioKey)
+{
+	delete &erase(ReferencedKey::freeReferenceKey(allocator, ioKey));
+}
+
+//
+// ReferencedKey class
+//
+ReferencedKey::ReferencedKey(KeyPool &keyPool) : mKeyPool(&keyPool)
+{
+	mKeyPool->add(*this);
+}
+
+ReferencedKey::~ReferencedKey()
+{
+	if (isActive())
+		mKeyPool->erase(*this);
+}
+
+ReferencedKey::KeyReference
+ReferencedKey::keyReference()
+{
+	// @@@ Possibly check isActive() and return an invalid reference if it is not set.
+	return reinterpret_cast<ReferencedKey::KeyReference>(this);
+}
+
+//
+// Making, retrieving and freeing Key references of CssmKeys
+//
+void
+ReferencedKey::makeReferenceKey(CssmAllocator &allocator, KeyReference keyReference, CSSM_KEY &key)
+{
+	key.KeyHeader.BlobType = CSSM_KEYBLOB_REFERENCE;
+	key.KeyHeader.Format = CSSM_KEYBLOB_REF_FORMAT_INTEGER;
+	key.KeyData.Length = sizeof(KeyReference);
+	key.KeyData.Data = allocator.alloc<uint8>(sizeof(KeyReference));
+	uint8 *cp = key.KeyData.Data;
+	for (int i = sizeof(KeyReference); --i >= 0;)
+	{
+		cp[i] = keyReference & 0xff;
+		keyReference = keyReference >> 8;
+	}
+}
+
+ReferencedKey::KeyReference
+ReferencedKey::keyReference(const CSSM_KEY &key)
+{
+	if (key.KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE
+		|| key.KeyHeader.Format != CSSM_KEYBLOB_REF_FORMAT_INTEGER
+		|| key.KeyData.Length != sizeof(KeyReference)
+		|| key.KeyData.Data == NULL)
+		CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
+
+	const uint8 *cp = key.KeyData.Data;
+	KeyReference keyReference = 0;
+	for (uint32 i = 0; i < sizeof(KeyReference); ++i)
+		keyReference = (keyReference << 8) + cp[i];
+
+	return keyReference;
+}
+
+ReferencedKey::KeyReference
+ReferencedKey::freeReferenceKey(CssmAllocator &allocator, CSSM_KEY &key)
+{
+	KeyReference aKeyReference = keyReference(key);
+	allocator.free(key.KeyData.Data);
+	key.KeyData.Data = NULL;
+	key.KeyData.Length = 0;
+	return aKeyReference;
+}
diff --git a/cdsa/cdsa_pluginlib/CSPsession.h b/cdsa/cdsa_pluginlib/CSPsession.h
new file mode 100644
index 00000000..1872d70a
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/CSPsession.h
@@ -0,0 +1,552 @@
+/*
+ * 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.
+ */
+
+
+//
+// CSPsession.h - Framework for CSP plugin modules
+//
+#ifndef _H_CSPSESSION
+#define _H_CSPSESSION
+
+#include <Security/CSPabstractsession.h>
+#include <map>
+
+#if defined(_CPP_CSPSESSION)
+# pragma export on
+#endif
+
+
+namespace Security
+{
+
+//
+// The CSPPluginSession provides a general bed for CSP plugin session objects.
+// Derive from this if you want to write your CSP, effectively, from scratch.
+// We still provide a framework for managing local cryptographic contexts and
+// (module) logins.
+//
+class CSPPluginSession : public PluginSession, public CSPAbstractPluginSession {
+public:
+    CSPPluginSession(CSSM_MODULE_HANDLE theHandle,
+                    CssmPlugin &plug,
+                    const CSSM_VERSION &version,
+                    uint32 subserviceId,
+                    CSSM_SERVICE_TYPE subserviceType,
+                    CSSM_ATTACH_FLAGS attachFlags,
+                    const CSSM_UPCALLS &upcalls)
+      : PluginSession(theHandle, plug, version, subserviceId, subserviceType, attachFlags, upcalls) { }
+
+    // methods implemented here that you should not override in a subclass
+    void EventNotify(CSSM_CONTEXT_EVENT e,
+                     CSSM_CC_HANDLE ccHandle, const Context &context);
+    CSSM_MODULE_FUNCS_PTR construct();
+
+public:
+    class PluginContext {
+    public:
+        virtual bool changed(const Context &context);
+        virtual ~PluginContext();
+    };
+
+public:
+    bool loggedIn() const { return mLoggedIn; }
+    bool loggedIn(bool li) { bool old = mLoggedIn; mLoggedIn = li; return old; }
+
+    template <class Ctx> Ctx *getContext(CSSM_CC_HANDLE handle)
+    { StLock<Mutex> _(contextMapLock); return safe_cast<Ctx *>(contextMap[handle]); }
+
+    void setContext(CSSM_CC_HANDLE handle, PluginContext *ctx)
+    { StLock<Mutex> _(contextMapLock); contextMap[handle] = ctx; }
+
+public:
+    // context management methods - override as needed
+    virtual PluginContext *contextCreate(CSSM_CC_HANDLE handle, const Context &context);
+    virtual void contextUpdate(CSSM_CC_HANDLE handle,
+                               const Context &context, PluginContext * &ctx);
+    virtual void contextDelete(CSSM_CC_HANDLE handle, const Context &context, PluginContext *ctx);
+
+private:
+    bool mLoggedIn;
+	
+    map<CSSM_CC_HANDLE, PluginContext *> contextMap;
+	Mutex contextMapLock;
+};
+
+
+//
+// On the other hand, for most CSP modules, this subclass of CSPPluginSession provides
+// much more convenient embedding facilities. The theory of operation is too complicated
+// to explain here; refer to the accompanying documentation.
+//
+class CSPFullPluginSession : public CSPPluginSession {
+    class CSPContext;
+    class AlgorithmFactory;
+public:
+    CSPFullPluginSession(CSSM_MODULE_HANDLE theHandle,
+                    CssmPlugin &plug,
+                    const CSSM_VERSION &version,
+                    uint32 subserviceId,
+                    CSSM_SERVICE_TYPE subserviceType,
+                    CSSM_ATTACH_FLAGS attachFlags,
+                    const CSSM_UPCALLS &upcalls)
+    : CSPPluginSession(theHandle, plug, version,
+                             subserviceId, subserviceType, attachFlags, upcalls) { }
+
+    // final context preparation (called by secondary transition layer)
+    CSPContext *init(CSSM_CC_HANDLE ccHandle, CSSM_CONTEXT_TYPE type,
+                     const Context &context, bool encoding = true);
+
+    // verify proper state on continuation (update/final) calls
+    CSPContext *getStagedContext(CSSM_CC_HANDLE ccHandle,
+                                 CSSM_CONTEXT_TYPE type, bool encoding = true);
+
+    static const uint32 CSSM_ALGCLASS_CRYPT = 1001;	// internally added to CONTEXT_TYPE
+
+protected:
+	// validate operation type against context class
+    void checkOperation(CSSM_CONTEXT_TYPE ctxType, CSSM_CONTEXT_TYPE opType);
+	
+protected:
+	//
+	// The Writer class encapsulates staged-output destinations with optional overflow
+	//
+	class Writer {
+	public:
+		Writer(CssmData *v, uint32 n, CssmData *rem = NULL);
+	
+		// can this buffer be extended?
+		bool isExtensible() const
+		{ return !*vec || remData && !*remData; }
+	
+		// increase size if necessary (and possible)
+		void allocate(size_t needed, CssmAllocator &alloc);
+	
+		// straight-forward buffer writing
+		void put(void *addr, size_t size);
+	
+		// locate-mode output (deliver buffer mode)
+		void nextBlock(void * &p, size_t &sz);
+		void use(size_t sz);
+	
+		// wrap up and return total number of bytes written
+		size_t close();
+	
+	private:
+		CssmData *vec;						// current buffer descriptor (the one in use)
+        CssmData *firstVec;					// first buffer descriptor
+		CssmData *lastVec;					// last buffer descriptor (NOT one past it)
+		CssmData *remData;					// overflow buffer, if any
+	
+		void *currentBuffer;				// next free byte in vec
+		size_t currentSize;					// free bytes in vec
+	
+		size_t written;						// bytes written
+		
+		void useData(CssmData *data)
+		{ currentBuffer = data->data(); currentSize = data->length(); }
+	};
+	
+public:
+	// internal utilities (used by our own subclasses)
+	static CssmData makeBuffer(size_t size, CssmAllocator &alloc);
+	static size_t totalBufferSize(const CssmData *data, uint32 count);
+    void setKey(CssmKey &key,
+                const Context &context, CSSM_KEYCLASS keyClass,
+                CSSM_KEYATTR_FLAGS attrs, CSSM_KEYUSE use);
+
+public:
+	//
+	// All contexts from CSPFullPluginSession's subclasses must derive from CSPContext.
+	// CSPFullPluginSession reformulates CSSM operations in terms of virtual methods of
+	// the context class.
+	//
+    class CSPContext : public PluginContext {
+        friend class CSPFullPluginSession;
+    public:
+        CSSM_CONTEXT_TYPE type() const { return mType; }
+        bool encoding() const { return mDirection; }
+        
+        // init() is called for all algorithms
+        virtual void init(const Context &context, bool encoding = true);
+
+        // the following methods will be called for some but not all algorithms
+        virtual void update(const CssmData &data);	// all block-input algorithms
+        virtual void update(void *inp, size_t &inSize, void *outp, size_t &outSize); // cryption algs
+        virtual void final(CssmData &out);		// output-data producing algorithms
+        virtual void final(const CssmData &in);	// verifying algorithms
+        virtual void generate(const Context &context, CssmKey &pubKey, CssmKey &privKey);
+        virtual void generate(const Context &context, uint32,
+                              CssmData &params, uint32 &attrCount, Context::Attr * &attrs);
+		virtual CSPContext *clone(CssmAllocator &);	// clone internal state
+		virtual void setDigestAlgorithm(CSSM_ALGORITHMS digestAlg);
+		
+        virtual size_t inputSize(size_t outSize);	// input for given output size
+        virtual size_t outputSize(bool final = false, size_t inSize = 0); // output for given input size
+        virtual void minimumProgress(size_t &in, size_t &out); // minimum progress chunks
+
+    protected:
+        // convenience forms of the above
+        void update(const CssmData *in, uint32 inCount, Writer &writer);
+        void final(CssmData &out, CssmAllocator &alloc);
+        void final(Writer &writer, CssmAllocator &alloc);
+
+        void update(const CssmData *in, uint32 inCount)
+        { for (uint32 n = 0; n < inCount; n++) update(in[n]); }
+
+        void checkOperation(CSSM_CONTEXT_TYPE type);
+        void checkOperation(CSSM_CONTEXT_TYPE type, bool encode);
+
+        CSSM_CONTEXT_TYPE mType;		// CSSM context type
+        bool mDirection;			// operation direction (true if irrelevant)
+    };
+
+protected:
+    virtual void setupContext(CSPContext * &ctx, const Context &context, bool encoding) = 0;
+	
+	virtual void getKeySize(const CssmKey &key, CSSM_KEY_SIZE &size);
+    
+public:
+    // an algorithm factory. This is an optional feature
+    class AlgorithmFactory {
+    public:
+        // set ctx and return true if you can handle this
+        virtual bool setup(CSPContext * &ctx, const Context &context) = 0;
+    };
+
+public:
+    void EncryptData(CSSM_CC_HANDLE CCHandle,
+                     const Context &Context,
+                     const CssmData ClearBufs[],
+                     uint32 ClearBufCount,
+                     CssmData CipherBufs[],
+                     uint32 CipherBufCount,
+                     uint32 &bytesEncrypted,
+                     CssmData &RemData,
+                     CSSM_PRIVILEGE Privilege);
+    void EncryptDataInit(CSSM_CC_HANDLE CCHandle,
+                         const Context &Context,
+                         CSSM_PRIVILEGE Privilege);
+    void EncryptDataUpdate(CSSM_CC_HANDLE CCHandle,
+                           const CssmData ClearBufs[],
+                           uint32 ClearBufCount,
+                           CssmData CipherBufs[],
+                           uint32 CipherBufCount,
+                           uint32 &bytesEncrypted);
+    void EncryptDataFinal(CSSM_CC_HANDLE CCHandle,
+                          CssmData &RemData);
+
+    void DecryptData(CSSM_CC_HANDLE CCHandle,
+                     const Context &Context,
+                     const CssmData CipherBufs[],
+                     uint32 CipherBufCount,
+                     CssmData ClearBufs[],
+                     uint32 ClearBufCount,
+                     uint32 &bytesDecrypted,
+                     CssmData &RemData,
+                     CSSM_PRIVILEGE Privilege);
+    void DecryptDataInit(CSSM_CC_HANDLE CCHandle,
+                         const Context &Context,
+                         CSSM_PRIVILEGE Privilege);
+    void DecryptDataUpdate(CSSM_CC_HANDLE CCHandle,
+                           const CssmData CipherBufs[],
+                           uint32 CipherBufCount,
+                           CssmData ClearBufs[],
+                           uint32 ClearBufCount,
+                           uint32 &bytesDecrypted);
+    void DecryptDataFinal(CSSM_CC_HANDLE CCHandle,
+                          CssmData &RemData);
+               
+	void QuerySize(CSSM_CC_HANDLE CCHandle,
+				  const Context &Context,
+				  CSSM_BOOL Encrypt,
+				  uint32 QuerySizeCount,
+				  QuerySizeData *DataBlock);
+
+	void WrapKey(CSSM_CC_HANDLE CCHandle,
+				const Context &Context,
+				const AccessCredentials &AccessCred,
+				const CssmKey &Key,
+				const CssmData *DescriptiveData,
+				CssmKey &WrappedKey,
+				CSSM_PRIVILEGE Privilege);
+	void UnwrapKey(CSSM_CC_HANDLE CCHandle,
+				const Context &Context,
+				const CssmKey *PublicKey,
+				const CssmKey &WrappedKey,
+				uint32 KeyUsage,
+				uint32 KeyAttr,
+				const CssmData *KeyLabel,
+				const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+				CssmKey &UnwrappedKey,
+				CssmData &DescriptiveData,
+				CSSM_PRIVILEGE Privilege);
+	void DeriveKey(CSSM_CC_HANDLE CCHandle,
+				const Context &Context,
+				CssmData &Param,
+				uint32 KeyUsage,
+				uint32 KeyAttr,
+				const CssmData *KeyLabel,
+				const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+				CssmKey &DerivedKey);
+
+    void GenerateMac(CSSM_CC_HANDLE CCHandle,
+                     const Context &Context,
+                     const CssmData DataBufs[],
+                     uint32 DataBufCount,
+                     CssmData &Mac);
+    void GenerateMacInit(CSSM_CC_HANDLE CCHandle,
+                                 const Context &Context);
+    void GenerateMacUpdate(CSSM_CC_HANDLE CCHandle,
+                                   const CssmData DataBufs[],
+                                   uint32 DataBufCount);
+    void GenerateMacFinal(CSSM_CC_HANDLE CCHandle,
+                                  CssmData &Mac);
+    
+    void VerifyMac(CSSM_CC_HANDLE CCHandle,
+                   const Context &Context,
+                   const CssmData DataBufs[],
+                   uint32 DataBufCount,
+                   const CssmData &Mac);
+    virtual void VerifyMacInit(CSSM_CC_HANDLE CCHandle,
+                               const Context &Context);
+    virtual void VerifyMacUpdate(CSSM_CC_HANDLE CCHandle,
+                                 const CssmData DataBufs[],
+                                 uint32 DataBufCount);
+    virtual void VerifyMacFinal(CSSM_CC_HANDLE CCHandle,
+                                const CssmData &Mac);
+
+    void SignData(CSSM_CC_HANDLE CCHandle,
+                  const Context &Context,
+                  const CssmData DataBufs[],
+                  uint32 DataBufCount,
+                  CSSM_ALGORITHMS DigestAlgorithm,
+                  CssmData &Signature);
+    void SignDataInit(CSSM_CC_HANDLE CCHandle,
+                              const Context &Context);
+    void SignDataUpdate(CSSM_CC_HANDLE CCHandle,
+                                const CssmData DataBufs[],
+                                uint32 DataBufCount);
+    void SignDataFinal(CSSM_CC_HANDLE CCHandle,
+                               CssmData &Signature);
+
+    void VerifyData(CSSM_CC_HANDLE CCHandle,
+                    const Context &Context,
+                    const CssmData DataBufs[],
+                    uint32 DataBufCount,
+                    CSSM_ALGORITHMS DigestAlgorithm,
+                    const CssmData &Signature);
+    virtual void VerifyDataInit(CSSM_CC_HANDLE CCHandle,
+                                const Context &Context);
+    virtual void VerifyDataUpdate(CSSM_CC_HANDLE CCHandle,
+                                  const CssmData DataBufs[],
+                                  uint32 DataBufCount);
+    virtual void VerifyDataFinal(CSSM_CC_HANDLE CCHandle,
+                                 const CssmData &Signature);
+
+    void DigestData(CSSM_CC_HANDLE CCHandle,
+                    const Context &Context,
+                    const CssmData DataBufs[],
+                    uint32 DataBufCount,
+                    CssmData &Digest);
+    void DigestDataInit(CSSM_CC_HANDLE CCHandle,
+                                const Context &Context);
+    void DigestDataUpdate(CSSM_CC_HANDLE CCHandle,
+                                  const CssmData DataBufs[],
+                                  uint32 DataBufCount);
+    void DigestDataFinal(CSSM_CC_HANDLE CCHandle,
+                                 CssmData &Digest);
+    void DigestDataClone(CSSM_CC_HANDLE CCHandle,
+						CSSM_CC_HANDLE ClonedCCHandle);
+
+    void GenerateKey(CSSM_CC_HANDLE CCHandle,
+                             const Context &Context,
+                             uint32 KeyUsage,
+                             uint32 KeyAttr,
+                             const CssmData *KeyLabel,
+                             const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                             CssmKey &Key,
+                             CSSM_PRIVILEGE Privilege);
+    void GenerateKeyPair(CSSM_CC_HANDLE CCHandle,
+                                 const Context &Context,
+                                 uint32 PublicKeyUsage,
+                                 uint32 PublicKeyAttr,
+                                 const CssmData *PublicKeyLabel,
+                                 CssmKey &PublicKey,
+                                 uint32 PrivateKeyUsage,
+                                 uint32 PrivateKeyAttr,
+                                 const CssmData *PrivateKeyLabel,
+                                 const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                                 CssmKey &PrivateKey,
+                                 CSSM_PRIVILEGE Privilege);
+        
+	void ObtainPrivateKeyFromPublicKey(const CssmKey &PublicKey,
+									   CssmKey &PrivateKey);
+	void QueryKeySizeInBits(CSSM_CC_HANDLE CCHandle,
+							const Context *Context,
+							const CssmKey *Key,
+							CSSM_KEY_SIZE &KeySize);
+                              
+	void FreeKey(const AccessCredentials *AccessCred,
+				 CssmKey &KeyPtr,
+				 CSSM_BOOL Delete);
+
+    void GenerateRandom(CSSM_CC_HANDLE CCHandle,
+                                const Context &Context,
+                                CssmData &RandomNumber);
+    void GenerateAlgorithmParams(CSSM_CC_HANDLE CCHandle,
+                                         const Context &Context,
+                                         uint32 ParamBits,
+                                         CssmData &Param,
+                                         uint32 &NumberOfUpdatedAttibutes,
+                                         CSSM_CONTEXT_ATTRIBUTE_PTR &UpdatedAttributes);
+										 
+	void Login(const AccessCredentials &AccessCred,
+			   const CssmData *LoginName,
+			   const void *Reserved);
+	void Logout();
+	void VerifyDevice(const CssmData &DeviceCert);
+	void GetOperationalStatistics(CSPOperationalStatistics &Statistics);
+	
+	void RetrieveCounter(CssmData &Counter);
+	void RetrieveUniqueId(CssmData &UniqueID);
+	void GetTimeValue(CSSM_ALGORITHMS TimeAlgorithm, CssmData &TimeData);
+	
+	void GetKeyOwner(const CssmKey &Key,
+			CSSM_ACL_OWNER_PROTOTYPE &Owner);
+	void ChangeKeyOwner(const AccessCredentials &AccessCred,
+			const CssmKey &Key,
+			const CSSM_ACL_OWNER_PROTOTYPE &NewOwner);
+	void GetKeyAcl(const CssmKey &Key,
+			const CSSM_STRING *SelectionTag,
+			uint32 &NumberOfAclInfos,
+			CSSM_ACL_ENTRY_INFO_PTR &AclInfos);
+	void ChangeKeyAcl(const AccessCredentials &AccessCred,
+			const CSSM_ACL_EDIT &AclEdit,
+			const CssmKey &Key);
+			
+	void GetLoginOwner(CSSM_ACL_OWNER_PROTOTYPE &Owner);
+	void ChangeLoginOwner(const AccessCredentials &AccessCred,
+			const CSSM_ACL_OWNER_PROTOTYPE &NewOwner);
+	void GetLoginAcl(const CSSM_STRING *SelectionTag,
+			uint32 &NumberOfAclInfos,
+			CSSM_ACL_ENTRY_INFO_PTR &AclInfos);
+	void ChangeLoginAcl(const AccessCredentials &AccessCred,
+			const CSSM_ACL_EDIT &AclEdit);
+       
+	void PassThrough(CSSM_CC_HANDLE CCHandle,
+               const Context &Context,
+               uint32 PassThroughId,
+               const void *InData,
+               void **OutData);
+};
+
+
+//
+// Classes for dealing with reference keys.
+//
+
+// Forward declaration.
+class KeyPool;
+
+//
+// A ReferencedKey -- The private (to the CSP) part of a Reference Key.
+//
+class ReferencedKey
+{
+	friend class KeyPool; // So it can call deactivate()
+public:
+	// What we use to reference a ReferencedKey.
+	typedef uint32 KeyReference;
+
+	ReferencedKey(KeyPool &session); // Calls KeyPool::add()
+	virtual ~ReferencedKey(); // Calls KeyPool::erase()
+
+	KeyReference keyReference();
+	bool isActive() { return mKeyPool != NULL; }
+
+	template <class SubPool>
+	SubPool &keyPool() { assert(mKeyPool); return safer_cast<SubPool &>(*mKeyPool); }
+public:
+	// Making, retrieving and freeing CSSM_KEYBLOB_REF_FORMAT_INTEGER CSSM_KEY type reference keys
+	// NOTE: that none of these functions affect mKeyMap.
+	static void makeReferenceKey(CssmAllocator &allocator, KeyReference keyReference, CSSM_KEY &ioKey);
+	static KeyReference keyReference(const CSSM_KEY &key);
+	static KeyReference freeReferenceKey(CssmAllocator &allocator, CSSM_KEY &ioKey);
+
+private:
+	void deactivate() { mKeyPool = NULL; }
+
+	// Will be NULL iff this key is not active
+	KeyPool *mKeyPool;
+};
+
+
+//
+// KeyPool -- a mixin class to manage a pool of ReferencedKeys
+//
+class KeyPool
+{
+public:
+	friend class ReferencedKey; // So it can call add() and erase()
+public:
+	KeyPool();
+	virtual ~KeyPool();
+
+	// Type safe ReferencedKey subclass lookup
+	template <class Subclass>
+	Subclass &find(const CSSM_KEY &key) const;
+
+	// Free the ioKey, erase keyReference from mKeyMap, and delete the ReferencedKey
+	void freeKey(CssmAllocator &allocator, CSSM_KEY &key);
+
+private:
+	// Called by the constructor of ReferencedKey -- add referencedKey to mKeyMap
+ 	void add(ReferencedKey &referencedKey);
+
+	ReferencedKey &findKey(const CSSM_KEY &key) const;
+	ReferencedKey &findKeyReference(ReferencedKey::KeyReference keyReference) const;
+
+	// Called by the destructor of ReferencedKey -- erase keyReference from mKeyMap
+ 	void erase(ReferencedKey &referencedKey);
+
+	// Erase keyReference from mKeyMap, and return it (for deletion)
+ 	ReferencedKey &erase(ReferencedKey::KeyReference keyReference);
+
+private:
+	typedef map<ReferencedKey::KeyReference, ReferencedKey *> KeyMap;
+	KeyMap mKeyMap;
+	mutable Mutex mKeyMapLock;
+};
+
+// Implementation of type safe ReferencedKey subclass lookup.
+template <class Subclass>
+Subclass &
+KeyPool::find(const CSSM_KEY &key) const
+{
+    Subclass *sub;
+    if (!(sub = dynamic_cast<Subclass *>(&findKey(key))))
+        CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
+    return *sub;
+}
+
+} // end namespace Security
+
+#if defined(_CPP_CSPSESSION)
+# pragma export off
+#endif
+
+#endif //_H_CSPSESSION
diff --git a/cdsa/cdsa_pluginlib/DLsession.cpp b/cdsa/cdsa_pluginlib/DLsession.cpp
new file mode 100644
index 00000000..44ae56e6
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/DLsession.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+//
+// DLsession - Plugin framework for CSP plugin modules
+//
+#ifdef __MWERKS__
+#define _CPP_DLSESSION
+#endif
+
+#include <Security/DLsession.h>
+#include <Security/cssmplugin.h>
+
+
+//
+// Construct a DLPluginSession
+//
+DLPluginSession::DLPluginSession(CSSM_MODULE_HANDLE theHandle,
+                                 CssmPlugin &plug,
+                                 const CSSM_VERSION &version,
+                                 uint32 subserviceId,
+                                 CSSM_SERVICE_TYPE subserviceType,
+                                 CSSM_ATTACH_FLAGS attachFlags,
+                                 const CSSM_UPCALLS &upcalls,
+                                 DatabaseManager &databaseManager)
+  : PluginSession(theHandle, plug, version, subserviceId, subserviceType, attachFlags, upcalls),
+    DatabaseSession (databaseManager)
+{
+}
+
+
+//
+// Implement CssmAllocator methods from the PluginSession side
+//
+void *DLPluginSession::malloc(size_t size)
+{ return PluginSession::malloc(size); }
+
+void DLPluginSession::free(void *addr)
+{ return PluginSession::free(addr); }
+
+void *DLPluginSession::realloc(void *addr, size_t size)
+{ return PluginSession::realloc(addr, size); }
diff --git a/cdsa/cdsa_pluginlib/DLsession.h b/cdsa/cdsa_pluginlib/DLsession.h
new file mode 100644
index 00000000..5295a39a
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/DLsession.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+
+//
+// DLsession.h - Framework for DL plugin modules
+//
+#ifndef _H_DLSESSION
+#define _H_DLSESSION
+
+#include <Security/pluginsession.h>
+#include <Security/DatabaseSession.h>
+
+#if defined(_CPP_DLSESSION)
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// The abstract DLPluginSession class is the common ancestor of your implementation
+// object for an DL type plugin attachment session. Inherit from this and implement
+// the abstract methods to define a plugin session.
+//
+class DLPluginSession : public PluginSession, public DatabaseSession {
+    NOCOPY(DLPluginSession)
+public:
+    DLPluginSession(CSSM_MODULE_HANDLE theHandle,
+                    CssmPlugin &plug,
+                    const CSSM_VERSION &version,
+                    uint32 subserviceId,
+                    CSSM_SERVICE_TYPE subserviceType,
+                    CSSM_ATTACH_FLAGS attachFlags,
+                    const CSSM_UPCALLS &upcalls,
+                    DatabaseManager &databaseManager);
+	
+	void *malloc(size_t size);
+	void free(void *addr);
+	void *realloc(void *addr, size_t size);
+
+protected:
+    CSSM_MODULE_FUNCS_PTR construct();
+};
+
+} // end namespace Security
+
+#if defined(_CPP_DLSESSION)
+# pragma export off
+#endif
+
+#endif //_H_DLSESSION
diff --git a/cdsa/cdsa_pluginlib/TPsession.h b/cdsa/cdsa_pluginlib/TPsession.h
new file mode 100644
index 00000000..5cf394c7
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/TPsession.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+//
+// TPsession.h - Framework for TP plugin modules
+//
+#ifndef _H_TPSESSION
+#define _H_TPSESSION
+
+#include <Security/TPabstractsession.h>
+
+#if defined(_CPP_TPSESSION)
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// The abstract TPPluginSession class is the common ancestor of your implementation
+// object for an TP type plugin attachment session. Inherit from this and implement
+// the abstract methods to define a plugin session.
+//
+class TPPluginSession : public PluginSession, public TPAbstractPluginSession {
+public:
+    TPPluginSession(CSSM_MODULE_HANDLE theHandle,
+                    CssmPlugin &plug,
+                    const CSSM_VERSION &version,
+                    uint32 subserviceId,
+                    CSSM_SERVICE_TYPE subserviceType,
+                    CSSM_ATTACH_FLAGS attachFlags,
+                    const CSSM_UPCALLS &upcalls)
+      : PluginSession(theHandle, plug, version, subserviceId, subserviceType, attachFlags, upcalls) { }
+
+protected:
+    CSSM_MODULE_FUNCS_PTR construct();
+};
+
+} // end namespace Security
+
+#if defined(_CPP_TPSESSION)
+# pragma export off
+#endif
+
+#endif //_H_TPSESSION
diff --git a/cdsa/cdsa_pluginlib/c++plugin.h b/cdsa/cdsa_pluginlib/c++plugin.h
new file mode 100644
index 00000000..516e427c
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/c++plugin.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+
+//
+// spilayer - "roof" interface layer for CDSA SPI plugins
+//
+#ifndef _H_SPILAYER
+#define _H_SPILAYER
+
+#include <Security/cssm.h>
+#include <Security/cssmspi.h>
+#include <Security/utilities.h>
+#include <Security/globalizer.h>
+
+
+namespace Security
+{
+
+//
+// Forward/common - separate file (which?) @@@
+//
+class CssmPlugin;
+class PluginSession;
+
+} // end namespace Security
+
+#endif //_H_SPILAYER
diff --git a/cdsa/cdsa_pluginlib/csputilities.cpp b/cdsa/cdsa_pluginlib/csputilities.cpp
new file mode 100644
index 00000000..e5629ee7
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/csputilities.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+
+//
+// csputilities - utility classes for CSP implementation
+//
+#include <Security/CSPsession.h>
+#include <Security/cssmplugin.h>
+#include <Security/memutils.h>
+#include <stdio.h>	//@@@ debug
+
+using LowLevelMemoryUtilities::increment;
+
+
+//
+// Writer objects
+//
+CSPFullPluginSession::Writer::Writer(CssmData *v, uint32 n, CssmData *rem)
+: vec(v), firstVec(v), lastVec(v + n - 1), remData(rem)
+{
+    if (vec == NULL || n == 0)
+        CssmError::throwMe(CSSMERR_CSP_INVALID_OUTPUT_VECTOR);	// CDSA p.253, amended
+	useData(vec);
+    written = 0;
+}
+
+void CSPFullPluginSession::Writer::allocate(size_t needed, CssmAllocator &alloc)
+{
+    if (vec == firstVec && !*vec) {	// initial null vector element, wants allocation there
+        *vec = makeBuffer(needed, alloc);
+        lastVec = vec;		// ignore all subsequent buffers in vector
+		useData(vec);
+    } else {
+        // how much output space do we have left?
+        size_t size = currentSize;
+        for (CssmData *v = vec + 1; v <= lastVec; v++)
+            size += v->length();
+        if (size >= needed)
+            return;	// we're fine
+        if (remData) {
+            if (!*remData) {	        // have overflow, can allocate
+                *remData = makeBuffer(needed - size, alloc);
+                return;	// got it
+            }
+            if (size + remData->length() >= needed)
+                return;	// will fit into overflow
+        }
+        // not enough buffer space, and can't allocate
+        CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
+    }
+}
+
+void CSPFullPluginSession::Writer::nextBlock(void * &ptr, size_t &size)
+{
+    ptr = currentBuffer;
+    size = currentSize;
+}
+
+void CSPFullPluginSession::Writer::use(size_t used)
+{
+    assert(used <= currentSize);
+    written += used;
+    if (used < currentSize) {
+        currentBuffer = increment(currentBuffer, used);
+        currentSize -= used;
+    } else {
+        if (vec < lastVec) {
+            useData(vec++);				// use next vector buffer
+        } else if (vec == lastVec && remData) {
+            useData(remData);			// use remainder buffer
+            vec++;						// mark used
+#if !defined(NDEBUG) && 0
+        } else if (vec == lastVec) {
+            vec++;
+        } else if (vec > lastVec) {
+            assert(false);				// 2nd try to overflow end
+#endif !NDEBUG
+        } else {
+            currentBuffer = NULL;		// no more output buffer
+            currentSize = 0;
+        }
+    }
+}
+
+void CSPFullPluginSession::Writer::put(void *addr, size_t size)
+{
+    while (size > 0) {
+        void *p; size_t sz;
+        nextBlock(p, sz);
+        if (size < sz)
+            sz = size;	// cap transfer
+        memcpy(p, addr, sz);
+        use(sz);
+        addr = increment(addr, sz);
+        size -= sz;
+    }
+}
+
+size_t CSPFullPluginSession::Writer::close()
+{
+    return written;
+}
+
+
+//
+// Common algorithm utilities
+//
+void CSPFullPluginSession::setKey(CssmKey &key,
+								  const Context &context, CSSM_KEYCLASS keyClass,
+								  CSSM_KEYATTR_FLAGS attrs, CSSM_KEYUSE use)
+{
+    // general setup
+    memset(&key.KeyHeader, 0, sizeof(key.KeyHeader));
+    key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
+    key.KeyHeader.CspId = plugin.myGuid();
+    key.KeyHeader.AlgorithmId = context.algorithm();
+    key.KeyHeader.KeyClass = keyClass;
+    key.KeyHeader.KeyUsage = use;
+    key.KeyHeader.KeyAttr = attrs;
+
+    // defaults (change as needed)
+    key.KeyHeader.WrapAlgorithmId = CSSM_ALGID_NONE;
+    
+    // clear key data (standard says, "Always allocate this, ignore prior contents.")
+    key = CssmData();
+}
diff --git a/cdsa/cdsa_pluginlib/cssmplugin.cpp b/cdsa/cdsa_pluginlib/cssmplugin.cpp
new file mode 100644
index 00000000..089cee95
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/cssmplugin.cpp
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmplugin - adapter framework for C++-based CDSA plugin modules
+//
+// A note on locking: Attachments are effectively reference counted in CSSM.
+// CSSM will not let a client detach an attachment that has a(nother) thread
+// active in its code. Thus, our locks merely protect global maps; they do not
+// need (or try) to close the classic use-and-delete window.
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMPLUGIN
+#endif
+#include <Security/cssmplugin.h>
+#include <Security/pluginsession.h>
+
+
+ModuleNexus<CssmPlugin::SessionMap> CssmPlugin::sessionMap;
+
+
+CssmPlugin::CssmPlugin()
+{
+    haveCallback = false;
+}
+
+CssmPlugin::~CssmPlugin()
+{
+	// Note: if haveCallback, we're being unloaded forcibly.
+	// (CSSM wouldn't do this to us in normal operation.)
+}
+
+
+void CssmPlugin::moduleLoad(const Guid &cssmGuid,
+                const Guid &moduleGuid,
+                const ModuleCallback &newCallback)
+{
+    // add the callback vector
+    if (haveCallback)	// re-entering moduleLoad - not currently supported
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+        
+	mMyGuid = moduleGuid;
+
+    // let the implementation know that we're loading
+    load();
+
+    // commit
+    callback = newCallback;
+    haveCallback = true;
+}
+
+
+void CssmPlugin::moduleUnload(const Guid &cssmGuid,
+                  const Guid &moduleGuid,
+                      const ModuleCallback &oldCallback)
+{
+    // check the callback vector
+    if (!haveCallback || oldCallback != callback)
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+    // tell our subclass that we're closing down
+    unload();
+
+    // commit closure
+    haveCallback = false;
+}
+
+
+void CssmPlugin::moduleAttach(CSSM_MODULE_HANDLE theHandle,
+                              const Guid &newCssmGuid,
+                              const Guid &moduleGuid,
+                              const Guid &moduleManagerGuid,
+                              const Guid &callerGuid,
+                              const CSSM_VERSION &version,
+                              uint32 subserviceId,
+                              CSSM_SERVICE_TYPE subserviceType,
+                              CSSM_ATTACH_FLAGS attachFlags,
+                              CSSM_KEY_HIERARCHY keyHierarchy,
+                              const CSSM_UPCALLS &upcalls,
+                              CSSM_MODULE_FUNCS_PTR &funcTbl)
+{
+    // insanity checks
+    // @@@ later
+    
+    // make the new session object, hanging in thin air
+    PluginSession *session = makeSession(theHandle,
+                                         version,
+                                         subserviceId, subserviceType,
+                                         attachFlags,
+                                         upcalls);
+
+    try {
+        // haggle with the implementor
+        funcTbl = session->construct();
+
+        // commit this session creation
+        StLock<Mutex> _(sessionMap());
+		sessionMap()[theHandle] = session;
+    } catch (...) {
+        delete session;
+        throw;
+    }
+}
+
+void CssmPlugin::moduleDetach(CSSM_MODULE_HANDLE handle)
+{
+	// locate the plugin and hold the sessionMapLock
+	PluginSession *session;
+	{
+		StLock<Mutex> _(sessionMap());
+		SessionMap::iterator it = sessionMap().find(handle);
+		if (it == sessionMap().end())
+			CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
+		session = it->second;
+		sessionMap().erase(it);
+	}
+		
+	// let the session know it is going away
+	try {
+		session->detach();
+	} catch (...) {
+		// session detach failed - put the plugin back and fail
+		StLock<Mutex> _(sessionMap());
+		sessionMap()[handle] = session;
+		throw;
+	}
+	
+	// everything's fine, delete the session
+	delete session;
+}
+
+void CssmPlugin::sendCallback(CSSM_MODULE_EVENT event, uint32 subId,
+                     		  CSSM_SERVICE_TYPE serviceType) const
+{
+	assert(haveCallback);
+	callback(event, mMyGuid, subId, serviceType);
+}
+
+
+//
+// Default subclass hooks.
+// The default implementations succeed without doing anything
+//
+void CssmPlugin::load() { }
+
+void CssmPlugin::unload() { }
diff --git a/cdsa/cdsa_pluginlib/cssmplugin.h b/cdsa/cdsa_pluginlib/cssmplugin.h
new file mode 100644
index 00000000..fbf008f2
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/cssmplugin.h
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmplugin - common header for CSSM plugin modules
+//
+#ifndef _H_CSSMPLUGIN
+#define _H_CSSMPLUGIN
+
+#include <Security/c++plugin.h>
+#include <Security/globalizer.h>
+#include <Security/callback.h>
+#include <hash_map>
+#include <set>
+
+namespace Security
+{
+
+//
+// Inherit from this (abstract) class to implement your plugin
+//
+class CssmPlugin {
+    NOCOPY(CssmPlugin)
+public:
+    CssmPlugin();
+    virtual ~CssmPlugin();
+
+    void moduleLoad(const Guid &cssmGuid,
+                    const Guid &moduleGuid,
+                    const ModuleCallback &callback);
+    void moduleUnload(const Guid &cssmGuid,
+                      const Guid &moduleGuid,
+                      const ModuleCallback &callback);
+
+    void moduleAttach(CSSM_MODULE_HANDLE theHandle,
+                      const Guid &cssmGuid,
+                      const Guid &moduleGuid,
+                      const Guid &moduleManagerGuid,
+                      const Guid &callerGuid,
+                      const CSSM_VERSION &Version,
+                      uint32 SubserviceID,
+                      CSSM_SERVICE_TYPE SubServiceType,
+                      CSSM_ATTACH_FLAGS AttachFlags,
+                      CSSM_KEY_HIERARCHY KeyHierarchy,
+                      const CSSM_UPCALLS &Upcalls,
+                      CSSM_MODULE_FUNCS_PTR &FuncTbl);
+    void moduleDetach(CSSM_MODULE_HANDLE handle);
+    
+    const Guid &myGuid() const { return mMyGuid; }
+    
+    void sendCallback(CSSM_MODULE_EVENT event,
+                      uint32 subId,
+                      CSSM_SERVICE_TYPE serviceType) const;
+                      
+    void sendInsertion(uint32 subId, CSSM_SERVICE_TYPE serviceType) const
+    { sendCallback(CSSM_NOTIFY_INSERT, subId, serviceType); }
+                      
+    void sendRemoval(uint32 subId, CSSM_SERVICE_TYPE serviceType) const
+    { sendCallback(CSSM_NOTIFY_REMOVE, subId, serviceType); }
+                      
+    void sendFault(uint32 subId, CSSM_SERVICE_TYPE serviceType) const
+    { sendCallback(CSSM_NOTIFY_FAULT, subId, serviceType); }
+
+protected:
+    // subclass-defined methods
+    virtual void load();
+    virtual void unload();
+
+    // make a session object for your plugin
+    virtual PluginSession *makeSession(CSSM_MODULE_HANDLE handle,
+                                       const CSSM_VERSION &version,
+                                       uint32 subserviceId,
+                                       CSSM_SERVICE_TYPE subserviceType,
+                                       CSSM_ATTACH_FLAGS attachFlags,
+                                       const CSSM_UPCALLS &upcalls) = 0;
+
+private:
+    // map of (CSSM) handles to attachment objects
+    struct SessionMap :
+            public hash_map<CSSM_MODULE_HANDLE, PluginSession *>,
+            public Mutex { };
+            
+    static ModuleNexus<SessionMap> sessionMap;
+    
+    Guid mMyGuid;
+
+    // the registered callback. We currently allow only one
+    ModuleCallback callback;
+    bool haveCallback;
+
+public:
+    static PluginSession *find(CSSM_MODULE_HANDLE h)
+    {
+        StLock<Mutex> _(sessionMap());
+        SessionMap::iterator it = sessionMap().find(h);
+        if (it == sessionMap().end())
+            CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
+        return it->second;
+    }
+};
+
+template <class SessionClass>
+inline SessionClass &findSession(CSSM_MODULE_HANDLE h)
+{
+    SessionClass *session = dynamic_cast<SessionClass *>(CssmPlugin::find(h));
+    if (session == NULL)
+        CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
+    assert(session->handle() == h);
+    return *session;
+}
+
+} // end namespace Security
+
+#endif //_H_CSSMPLUGIN
diff --git a/cdsa/cdsa_pluginlib/generator.cfg b/cdsa/cdsa_pluginlib/generator.cfg
new file mode 100644
index 00000000..f596500f
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/generator.cfg
@@ -0,0 +1,59 @@
+#
+# transition.cfg
+#
+# Configuration file for generating the CSSM plugin framework transition layer.
+#
+
+
+#
+# Specify optional arguments
+#
+
+# CSP
+optional Login LoginName
+optional GetLoginAcl SelectionTag
+optional GetKeyAcl SelectionTag
+optional GetDbAcl SelectionTag
+optional GenerateKey KeyLabel CredAndAclEntry
+optional GenerateKeyPair PrivateKeyLabel PublicKeyLabel CredAndAclEntry
+optional WrapKey DescriptiveData
+optional UnwrapKey PublicKey KeyLabel CredAndAclEntry
+optional DeriveKey KeyLabel CredAndAclEntry
+optional FreeKey AccessCred
+optional QuerySize DataBlock
+optional QueryKeySizeInBits Context Key
+
+# CL/TP
+optional SubmitCredRequest PreferredAuthority CallerAuthContext
+optional RetrieveCredResult CallerAuthCredentials
+optional ConfirmCredResult CallerAuthCredentials PreferredAuthority
+optional CertReclaimKey CredAndAclEntry
+optional FormRequest PreferredAuthority
+optional FormSubmit ClearanceAuthority RepresentedAuthority Credentials
+optional CertGroupVerify VerifyContext VerifyContextResult
+optional CertSign SignScope SignerVerifyContext
+optional CrlVerify VerifyContext
+optional CertRevoke OldCrlTemplate
+optional CertRemoveFromCrlTemplate OldCrlTemplate
+optional CrlSign SignerVerifyContext
+optional ApplyCrlToDb ApplyCrlVerifyContext
+optional PassThrough DBList
+optional AuthCompute Credentials RequestedAuthorizationPeriod
+optional CertSign SignScope
+optional CertVerify SignerCert VerifyScope
+optional CertGroupToSignedBundle SignerCert BundleInfo
+optional CertGroupFromVerifiedBundle SignerCert
+optional CrlSign SignScope
+optional CrlVerify VerifyScope
+optional CrlGetFirstCachedFieldValue CrlRecordIndex
+optional FreeFieldValue Value
+
+# DL
+optional DbOpen DbLocation AccessCred
+optional DbCreate DbLocation CredAndAclEntry
+optional DbDelete DbLocation AccessCred
+optional DataInsert Attributes Data
+optional DataModify AttributesToBeModified DataToBeModified
+optional DataGetFirst Query Attributes Data
+optional DataGetNext Query Attributes Data
+optional DataGetFromUniqueRecordId Attributes Data
diff --git a/cdsa/cdsa_pluginlib/generator.mk b/cdsa/cdsa_pluginlib/generator.mk
new file mode 100644
index 00000000..81ea93e0
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/generator.mk
@@ -0,0 +1,28 @@
+# Makefile for generated files.
+
+PERL=/usr/bin/perl
+
+CDSA_HEADERS_DIR = Headers/cdsa
+SECURITY_HEADERS_DIR = Headers/Security
+CDSA_PLUGINLIB_DIR = Sources/cdsa_pluginlib
+
+GEN_SPIGLUE = $(CDSA_PLUGINLIB_DIR)/generator.pl
+SPIGLUE_GEN = $(patsubst %,$(SECURITY_HEADERS_DIR)/%,ACabstractsession.h CLabstractsession.h CSPabstractsession.h DLabstractsession.h TPabstractsession.h)\
+			  $(patsubst %,$(CDSA_PLUGINLIB_DIR)/%,ACabstractsession.cpp CLabstractsession.cpp CSPabstractsession.cpp DLabstractsession.cpp TPabstractsession.cpp)
+SPIGLUE_DEPENDS = $(patsubst %,$(CDSA_PLUGINLIB_DIR)/%,generator.pl generator.cfg)\
+				  $(patsubst %,$(CDSA_HEADERS_DIR)/%,cssmapi.h cssmtype.h cssmconfig.h cssmaci.h cssmcli.h cssmcspi.h cssmdli.h cssmspi.h)
+
+build: $(SPIGLUE_GEN)
+
+clean:
+	rm -f $(SPIGLUE_GEN)
+
+debug: build
+
+profile: build
+
+.PHONY: build clean debug profile
+
+$(SPIGLUE_GEN): $(SPIGLUE_DEPENDS)
+	(cd $(CDSA_PLUGINLIB_DIR);\
+	  $(PERL) ./generator.pl ../../$(CDSA_HEADERS_DIR) ../../$(SECURITY_HEADERS_DIR) .)
diff --git a/cdsa/cdsa_pluginlib/generator.pl b/cdsa/cdsa_pluginlib/generator.pl
new file mode 100644
index 00000000..afc03b0a
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/generator.pl
@@ -0,0 +1,258 @@
+#!/usr/bin/perl
+#
+# generator.pl - auto-generate code for the CSSM plugin interfaces
+#
+# Usage:
+#	perl generator.pl input-directory h-output-dir c-output-dir
+#
+# Perry The Cynic, Fall 1999.
+#
+@API_H=("cssmapi.h");
+%SPI_H=("AC" => "cssmaci.h", "CSP" => "cssmcspi.h", "DL" => "cssmdli.h",
+        "CL" => "cssmcli.h", "TP"  => "cssmtpi.h");
+        
+$SOURCEDIR=$ARGV[0];			# where all the input files are
+$HTARGETDIR=$ARGV[1];			# where the generated headers go
+$CTARGETDIR=$ARGV[2];			# where the generated sources go
+
+(${D}) = $HTARGETDIR =~ m@([/:])@;		# guess directory delimiter
+sub macintosh() { return ${D} eq ':'; }
+
+# XXX The configuration file should be passed in as a command line argument
+if( macintosh() ) {
+$APICFG=":::cdsa:cdsa_pluginlib:generator.cfg";		# configuration file
+}
+ else{
+	$APICFG="generator.cfg";		# configuration file 
+ }
+
+$tabs = "\t\t\t";	# argument indentation (noncritical)
+$warning = "This file was automatically generated. Do not edit on penalty of futility!";
+
+
+#
+# Open and read the configuration file
+#
+$/=undef;	# gulp file
+open(APICFG, $APICFG) or die "Cannot open $APICFG: $^E";
+$_=<APICFG>;
+close(APICFG);
+tr/\012/\015/ if macintosh;
+%optionals = /^\s*optional\s+(\w+)\s+(.*)$/gm;
+
+
+#
+# Pre-arranged arrays for processing below
+#
+%noDataReturnError = ( CL => "CSSMERR_CL_NO_FIELD_VALUES",
+					   DL => "CSSMERR_DL_ENDOFDATA" );
+
+
+#
+# process one SPI at a time
+#
+while (($type, $header) = each %SPI_H) {
+  my(%functions, %methods, %actuals);
+  ($typelower = $type) =~ tr/A-Z/a-z/;	# lowercase version of type
+
+  # start in on the $type header file
+  open(SPI, "$SOURCEDIR${D}$header") or die "cannot open $SOURCEDIR${D}$header: $^E";
+  $/=undef;		# big gulp mode
+  $_ = <SPI>;	# aaaaah...
+  close(SPI);	# done
+  tr/\012/\015/ if macintosh;
+  # throw away leading and trailing crud (only interested in SPI structure)
+  s/^.*struct cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s
+    or die "bad format in $SPI_H{$name}";
+
+  # break up into functions (you'd do that HOW in YOUR language? :-)
+  @functions = /CSSM_RETURN \(CSSM${type}I \*([A-Za-z_]+)\)\s+\(([^)]+)\);/g;
+  %functions = @functions;
+
+  $MOREHEADERS="";
+  $MOREHEADERS .= "#include <Security/context.h>\n" if /CSSM_CONTEXT/;
+  $MOREHEADERS .= "#include <Security/cssmacl.h>\n" if /CSSM_(ACL|ACCESS)/;
+
+  # break function arguments into many forms:
+  #  functions => formal SPI arguments
+  #  methods => formal C++ method arguments
+  #  actuals => actual expression forms for transition layer use
+  # and (by the way) massage them into a more palatable form...
+  $nFunctions = 0;
+  while (($function, $_) = each %functions) {
+    #
+    # Turn CSSM SPI formal into method formal
+	#
+	$returntype{$function} = "void";
+    $prefix{$function} = "";
+	$postfix{$function} = ";";
+    # reshape initial argument (the module handle, more or less)
+    s/^CSSM_${type}_HANDLE ${type}Handle(,\s*\n\s*|$)//s; # remove own handle (-> this)
+    s/^CSSM_DL_DB_HANDLE DLDBHandle/CSSM_DB_HANDLE DBHandle/s; # DL_DB handle -> DB handle
+    s/CSSM_HANDLE_PTR ResultsHandle(,?)\n//m	   	# turn ptr-to-resultshandle into fn result
+      and do {
+		$returntype{$function} = "CSSM_HANDLE";
+		$prefix{$function} = "if ((Required(ResultsHandle) = ";
+		$postfix{$function} = ") == CSSM_INVALID_HANDLE)\n    return $noDataReturnError{$type};";
+	  };
+	if ($function =~ /GetNext/) {					# *GetNext* returns a bool
+	  $returntype{$function} = "bool";
+	  $prefix{$function} = "if (!";
+	  $postfix{$function} = ")\n    return $noDataReturnError{$type};";
+	}
+    # reshape subsequent arguments
+	s/([su]int32) \*(\w+,?)/$1 \&$2/gm;				# int * -> int & (output integer)
+    s/(CSSM_\w+_PTR) \*(\w+,?)/$1 \&$2/gm;			# _PTR * -> _PTR &
+	s/(CSSM_\w+)_PTR (\w+)/$1 \*$2/gm;				# XYZ_PTR -> XYZ * (explicit)
+	s/(const )?CSSM_DATA \*(\w+)Bufs/$1CssmData $2Bufs\[\]/gm; # c DATA *Bufs (plural)
+    s/(const )?CSSM_(DATA|OID) \*/$1CssmData \&/gm;	# c DATA * -> c Data &
+	s/(const )?CSSM_FIELD \*(\w+)Fields/$1CSSM_FIELD $2Fields\[\]/gm; # c FIELD *Fields (plural)
+	s/(const )?CSSM_FIELD \*CrlTemplate/$1CSSM_FIELD CrlTemplate\[\]/gm; # c FIELD *CrlTemplate
+	s/const CSSM_CONTEXT \*/const Context \&/gm;	# c CSSM_CONTEXT * -> c Context &
+	s/(const )?CSSM_ACCESS_CREDENTIALS \*/$1AccessCredentials \&/gm; # ditto
+	s/(const )?CSSM_QUERY_SIZE_DATA \*/$1QuerySizeData \&/gm; # ditto
+	s/(const )?CSSM_CSP_OPERATIONAL_STATISTICS \*/$1CSPOperationalStatistics \&/gm; # ditto
+    s/(const )?CSSM_(WRAP_)?KEY \*/$1CssmKey \&/gm;	# CSSM[WRAP]KEY * -> CssmKey &
+    s/const CSSM_QUERY \*/const DLQuery \&/gm;		# c QUERY * -> c Query &
+	s/(const )?(CSSM_[A-Z_]+) \*/$1$2 \&/gm;		# c CSSM_ANY * -> c CSSM_ANY &
+    $methods{$function} = $_;
+
+	#
+    # Now turn the method formal into the transition invocation actuals
+	#
+    s/^CSSM_DB_HANDLE \w+(,?)/DLDBHandle.DBHandle$1/s;		# matching change to DL_DB handles
+	s/(const )?([A-Z][a-z]\w+) &(\w+)(,?)/$2::required($3)$4/gm; # BIG_ * -> Small_ &
+	s/(const )?CssmData (\w+)Bufs\[\](,?)/\&\&CssmData::required($2Bufs)$3/gm; # c DATA *DataBufs
+	s/(const )?CSSM_FIELD (\w+)Fields\[\](,?)/$2Fields$3/gm; # c CSSM_FIELD *Fields
+	s/(const )?CSSM_FIELD CrlTemplate\[\](,?)/CrlTemplate$2/gm; # c CSSM_FIELD *CrlTemplate
+    # now remove formal arguments and clean up
+	s/^.* \&\&(\w+,?)/$tabs\&$1/gm;					# && escape (to keep real &)
+	s/^.* \&(\w+)(,?)/${tabs}Required($1)$2/gm;		# dereference for ref transition
+    s/^.* \**(\w+,?)/$tabs$1/gm;					# otherwise, plain actual argument
+    s/^$tabs//;
+    $actuals{$function} = $_;
+
+	#
+	# Fix optional arguments
+	#
+	foreach $opt (split " ", $optionals{$function}) {
+	  $methods{$function} =~ s/\&$opt\b/\*$opt/;	# turn refs back into pointers
+	  $actuals{$function} =~ s/::required\($opt\)/::optional($opt)/; # optional specific
+	  $actuals{$function} =~ s/Required\($opt\)/$opt/; # optional generic
+	};
+    $nFunctions++;
+  };
+
+  #
+  # Prepare to write header and source files
+  #
+  open(H, ">$HTARGETDIR${D}${type}abstractsession.h") or die "cannot write ${type}abstractsession.h: $^E";
+  open(C, ">$CTARGETDIR${D}${type}abstractsession.cpp") or die "cannot write ${type}abstractsession.cpp: $^E";
+
+  #
+  # Create header file
+  #
+  print H <<HDRHEAD;
+//
+// $type plugin transition layer.
+// $warning
+//
+#ifndef _H_${type}ABSTRACTSESSION
+#define _H_${type}ABSTRACTSESSION
+
+#include <Security/pluginsession.h>
+$MOREHEADERS
+#if defined(_CPP_${type}ABSTRACTSESSION)
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// A pure abstract class to define the ${type} module interface
+//
+class ${type}AbstractPluginSession {
+public:
+HDRHEAD
+
+  $functionCount = 0;
+  while (($function, $arglist) = each %methods) {
+    # generate method declaration
+    print H "  virtual $returntype{$function} $function($arglist) = 0;\n";
+    $functionCount++;
+  };
+  print H <<HDREND;
+};
+
+} // end namespace Security
+
+#if defined(_CPP_${type}ABSTRACTSESSION)
+# pragma export off
+#endif
+
+#endif //_H_${type}ABSTRACTSESSION
+HDREND
+
+  #
+  # Create source file
+  #
+  print C <<BODY;
+//
+// $type plugin transition layer.
+// $warning
+//
+#if defined(__MWERKS__)
+# define _CPP_${type}ABSTRACTSESSION
+# define _CPP_${type}SESSION
+#endif
+#include <Security/${type}session.h>
+#include <Security/cssmplugin.h>
+#include <Security/cssm${typelower}i.h>
+
+BODY
+
+  # write transition layer functions
+  while (($function, $arglist) = each %functions) {
+    $lookupHandle = "${type}Handle";
+	$lookupHandle = "DLDBHandle.DLHandle" if $arglist =~ /DL_DB_HANDLE/;
+    print C <<SHIM;
+static CSSM_RETURN CSSM${type}I cssm_$function($arglist)
+{
+  BEGIN_API
+  ${prefix{$function}}findSession<${type}PluginSession>($lookupHandle).$function($actuals{$function})${postfix{$function}}
+  END_API($type)
+}
+
+SHIM
+  };
+
+  # generate dispatch table - in the right order, please
+  print C "\nstatic const CSSM_SPI_${type}_FUNCS ${type}FunctionStruct = {\n";
+  while ($function = shift @functions) {
+    print C "  cssm_$function,\n";
+    shift @functions;	# skip over arglist part
+  };
+  print C "};\n\n";
+
+  print C <<END;
+static CSSM_MODULE_FUNCS ${type}FunctionTable = {
+  CSSM_SERVICE_$type,	// service type
+  $functionCount,	// number of functions
+  (const CSSM_PROC_ADDR *)&${type}FunctionStruct
+};
+
+CSSM_MODULE_FUNCS_PTR ${type}PluginSession::construct()
+{
+   return &${type}FunctionTable;
+}
+END
+
+  #
+  # Done with this type
+  #
+  close(H);
+  close(C);
+  
+  print "$nFunctions functions generated for $type SPI transition layer.\n";
+};
diff --git a/cdsa/cdsa_pluginlib/pluginsession.cpp b/cdsa/cdsa_pluginlib/pluginsession.cpp
new file mode 100644
index 00000000..f98aeb28
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/pluginsession.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+
+//
+// pluginsession - an attachment session for a CSSM plugin
+//
+#ifdef __MWERKS__
+#define _CPP_PLUGINSESSION
+#endif
+#include <Security/pluginsession.h>
+#include <Security/cssmplugin.h>
+#include <Security/DLsession.h>
+
+
+//
+// Construct the PluginSession base object.
+//
+PluginSession::PluginSession(CSSM_MODULE_HANDLE theHandle,
+                             CssmPlugin &plug,
+                             const CSSM_VERSION &version,
+                             uint32 subserviceId,
+                             CSSM_SERVICE_TYPE subserviceType,
+                             CSSM_ATTACH_FLAGS attachFlags,
+                             const CSSM_UPCALLS &inUpcalls)
+: HandledObject(theHandle), plugin(plug), upcalls(inUpcalls)
+{
+    // fill in passed flags
+    mVersion = version;
+    mSubserviceId = subserviceId;
+    mSubserviceType = subserviceType;
+    mAttachFlags = attachFlags;
+}
+
+PluginSession::~PluginSession()
+{
+}
+
+void PluginSession::detach()
+{
+}
+
+
+//
+// Allocation management
+//
+void *PluginSession::malloc(size_t size)
+{
+    if (void *addr = upcalls.malloc_func(handle(), size))
+        return addr;
+    CssmError::throwMe(CSSM_ERRCODE_MEMORY_ERROR);
+}
+
+void *PluginSession::realloc(void *oldAddr, size_t size)
+{
+    if (void *addr = upcalls.realloc_func(handle(), oldAddr, size))
+        return addr;
+    CssmError::throwMe(CSSM_ERRCODE_MEMORY_ERROR);
+}
+
+
+//
+// Dispatch events through the plugin module object.
+// Subsystem ID and subservice type default to our own.
+//
+
+void PluginSession::sendCallback(CSSM_MODULE_EVENT event,
+                                 uint32 subId,
+                                 CSSM_SERVICE_TYPE serviceType) const
+{
+    plugin.sendCallback(event,
+                        (subId == uint32(-1)) ? mSubserviceId : subId,
+                        serviceType ? serviceType : mSubserviceType);
+}
diff --git a/cdsa/cdsa_pluginlib/pluginsession.h b/cdsa/cdsa_pluginlib/pluginsession.h
new file mode 100644
index 00000000..f9f4b135
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/pluginsession.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+
+//
+// pluginsession - an attachment session for a CSSM plugin
+//
+#ifndef _H_PLUGINSESSION
+#define _H_PLUGINSESSION
+
+#include <Security/c++plugin.h>
+#include <Security/handleobject.h>
+#include <Security/cssmalloc.h>
+
+
+#ifdef _CPP_PLUGINSESSION
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// A PluginSession object describes an ongoing connection between a particular
+// CSSM client and our plugin. Every time CSSM_SPI_ModuleAttach is called
+// (due to the client calling CSSM_ModuleAttach), a new PluginSession object
+// is created as a result. Sessions and CSSM_MODULE_HANDLES correspond one-to-one.
+//
+// PluginSession is meant to be the parent class of your session object.
+// This is where you store per-session information.
+//
+class PluginSession : public CssmAllocator, public HandledObject {
+    NOCOPY(PluginSession)
+    friend class CssmPlugin;
+public:
+    PluginSession(CSSM_MODULE_HANDLE theHandle,
+                  CssmPlugin &plug,
+                  const CSSM_VERSION &Version,
+                  uint32 SubserviceID,
+                  CSSM_SERVICE_TYPE SubServiceType,
+                  CSSM_ATTACH_FLAGS AttachFlags,
+                  const CSSM_UPCALLS &upcalls);
+    virtual ~PluginSession();
+    virtual void detach();
+
+    CssmPlugin &plugin;
+    
+    void sendCallback(CSSM_MODULE_EVENT event,
+    				  uint32 subId = uint32(-1),
+                      CSSM_SERVICE_TYPE serviceType = 0) const;
+
+    static void unimplemented() { CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED); }
+
+protected:
+    virtual CSSM_MODULE_FUNCS_PTR construct() = 0;
+
+public:
+    // implement CssmHeap::Allocator
+    void *malloc(size_t size);
+    void *realloc(void *addr, size_t size);
+    void free(void *addr) { upcalls.free_func(handle(), addr); }
+
+	const CSSM_VERSION &version() const { return mVersion; }
+    uint32 subserviceId() const { return mSubserviceId; }
+    CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; }
+    CSSM_ATTACH_FLAGS attachFlags() const { return mAttachFlags; }
+
+private:
+    CSSM_VERSION mVersion;
+    uint32 mSubserviceId;
+    CSSM_SERVICE_TYPE mSubserviceType;
+    CSSM_ATTACH_FLAGS mAttachFlags;
+    const CSSM_UPCALLS &upcalls;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_PLUGINSESSION
+# pragma export off
+#endif
+
+#endif //_H_PLUGINSESSION
diff --git a/cdsa/cdsa_pluginlib/pluginspi.h b/cdsa/cdsa_pluginlib/pluginspi.h
new file mode 100644
index 00000000..de869010
--- /dev/null
+++ b/cdsa/cdsa_pluginlib/pluginspi.h
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+
+//
+// pluginspi - "roof" level entry points into a CSSM plugin.
+//
+// This file is meant to be included into the top-level source file
+// for a CSSM plugin written to the C++ alternate interface.
+// It contains actual code that defines the four required entry points.
+//
+
+//
+// Provide some flexibility for the includer
+//
+#if !defined(SPIPREFIX)
+# define SPIPREFIX	extern "C" CSSMSPI
+#endif
+
+
+SPIPREFIX CSSM_RETURN CSSM_SPI_ModuleLoad (const CSSM_GUID *CssmGuid,
+    const CSSM_GUID *ModuleGuid,
+    CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+    void *CssmNotifyCallbackCtx)
+{
+    BEGIN_API
+    plugin().moduleLoad(Guid::required(CssmGuid),
+        Guid::required(ModuleGuid),
+        ModuleCallback(CssmNotifyCallback, CssmNotifyCallbackCtx));
+    END_API(CSSM)
+}
+
+SPIPREFIX CSSM_RETURN CSSM_SPI_ModuleUnload (const CSSM_GUID *CssmGuid,
+    const CSSM_GUID *ModuleGuid,
+    CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+    void *CssmNotifyCallbackCtx)
+{
+    BEGIN_API
+    plugin().moduleUnload(Guid::required(CssmGuid),
+        Guid::required(ModuleGuid),
+        ModuleCallback(CssmNotifyCallback, CssmNotifyCallbackCtx));
+    END_API(CSSM)
+}
+
+SPIPREFIX CSSM_RETURN CSSM_SPI_ModuleAttach (const CSSM_GUID *ModuleGuid,
+    const CSSM_VERSION *Version,
+    uint32 SubserviceID,
+    CSSM_SERVICE_TYPE SubServiceType,
+    CSSM_ATTACH_FLAGS AttachFlags,
+    CSSM_MODULE_HANDLE ModuleHandle,
+    CSSM_KEY_HIERARCHY KeyHierarchy,
+    const CSSM_GUID *CssmGuid,
+    const CSSM_GUID *ModuleManagerGuid,
+    const CSSM_GUID *CallerGuid,
+    const CSSM_UPCALLS *Upcalls,
+    CSSM_MODULE_FUNCS_PTR *FuncTbl)
+{
+    BEGIN_API
+    plugin().moduleAttach(ModuleHandle,
+        Guid::required(CssmGuid),
+        Guid::required(ModuleGuid),
+        Guid::required(ModuleManagerGuid),
+        Guid::required(CallerGuid),
+        *Version,
+        SubserviceID,
+        SubServiceType,
+        AttachFlags,
+        KeyHierarchy,
+        Required(Upcalls),
+        Required(FuncTbl));
+    END_API(CSSM)
+}
+
+SPIPREFIX CSSM_RETURN CSSM_SPI_ModuleDetach (CSSM_MODULE_HANDLE ModuleHandle)
+{
+    BEGIN_API
+    plugin().moduleDetach(ModuleHandle);
+    END_API(CSSM)
+}
diff --git a/cdsa/cdsa_utilities.cpp b/cdsa/cdsa_utilities.cpp
new file mode 100644
index 00000000..d46034d0
--- /dev/null
+++ b/cdsa/cdsa_utilities.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+
+#define SYSLOG_NAMES	// compile syslog name tables
+
+/* Headers. */
+#include <cdsa_utilities/acl_password.h>
+#include <cdsa_utilities/acl_any.h>
+#include <cdsa_utilities/acl_threshold.h>
+#include <cdsa_utilities/acl_process.h>
+#include <cdsa_utilities/AtomicFile.h>
+#include <cdsa_utilities/callback.h>
+#include <cdsa_utilities/context.h>
+#include <cdsa_utilities/cssm_adt_utils.h>
+#include <cdsa_utilities/cssmacl.h>
+#include <cdsa_utilities/cssmalloc.h>
+#include <cdsa_utilities/cssmdata.h>
+#include <cdsa_utilities/cssmdates.h>
+#include <cdsa_utilities/cssmdb.h>
+#include <cdsa_utilities/cssmerrno.h>
+#include <cdsa_utilities/cssmlist.h>
+#include <cdsa_utilities/Database.h>
+#include <cdsa_utilities/DatabaseSession.h>
+#include <cdsa_utilities/DbContext.h>
+#include <cdsa_utilities/DbName.h>
+#include <cdsa_utilities/DbQuery.h>
+#include <cdsa_utilities/globalizer.h>
+#include <cdsa_utilities/handleobject.h>
+#include <cdsa_utilities/memutils.h>
+#include <cdsa_utilities/modloader.h>
+#include <cdsa_utilities/os9utils.h>
+#include <cdsa_utilities/refcount.h>
+#include <cdsa_utilities/threading.h>
+#include <cdsa_utilities/utilities.h>
+#include <cdsa_utilities/utility_config.h>
+#include <cdsa_utilities/walkers.h>
+#include <cdsa_utilities/cssmwalkers.h>
+#include <cdsa_utilities/cssmaclpod.h>
+#include <cdsa_utilities/mach++.h>
+#include <cdsa_utilities/machserver.h>
+#include <cdsa_utilities/cssmcred.h>
+#include <cdsa_utilities/mach_notify.h>
+#include <cdsa_utilities/machrunloopserver.h>
+#include <cdsa_utilities/AppleDatabase.h>
+#include <cdsa_utilities/DbIndex.h>
+#include <cdsa_utilities/DbValue.h>
+#include <cdsa_utilities/MetaAttribute.h>
+#include <cdsa_utilities/MetaRecord.h>
+#include <cdsa_utilities/ReadWriteSection.h>
+#include <cdsa_utilities/SelectionPredicate.h>
+#include <cdsa_utilities/debugging.h>
+#include <cdsa_utilities/debugsupport.h>
+#include <cdsa_utilities/logging.h>
+#include <cdsa_utilities/tqueue.h>
+#include <cdsa_utilities/codesigning.h>
+#include <cdsa_utilities/acl_codesigning.h>
+#include <cdsa_utilities/osxsigning.h>
+#include <cdsa_utilities/daemon.h>
+#include <cdsa_utilities/acl_comment.h>
+
+/* Source files. */
+#include <cdsa_utilities/acl_password.cpp>
+#include <cdsa_utilities/AtomicFile.cpp>
+#include <cdsa_utilities/callback.cpp>
+#include <cdsa_utilities/context.cpp>
+#include <cdsa_utilities/cssm_adt_utils.cpp>
+#include <cdsa_utilities/cssmacl.cpp>
+#include <cdsa_utilities/cssmalloc.cpp>
+#include <cdsa_utilities/cssmdata.cpp>
+#include <cdsa_utilities/cssmdates.cpp>
+#include <cdsa_utilities/cssmdb.cpp>
+#include <cdsa_utilities/cssmerrno.cpp>
+#include <cdsa_utilities/cssmlist.cpp>
+#include <cdsa_utilities/Database.cpp>
+#include <cdsa_utilities/DatabaseSession.cpp>
+#include <cdsa_utilities/DbContext.cpp>
+#include <cdsa_utilities/DbName.cpp>
+#include <cdsa_utilities/DbQuery.cpp>
+#include <cdsa_utilities/globalizer.cpp>
+#include <cdsa_utilities/guids.cpp>
+#include <cdsa_utilities/handleobject.cpp>
+#include <cdsa_utilities/modloader.cpp>
+#include <cdsa_utilities/modloader9.cpp>
+#include <cdsa_utilities/os9utils.cpp>
+#include <cdsa_utilities/threading.cpp>
+#include <cdsa_utilities/utilities.cpp>
+#include <cdsa_utilities/walkers.cpp>
+#include <cdsa_utilities/cssmwalkers.cpp>
+#include <cdsa_utilities/acl_any.cpp>
+#include <cdsa_utilities/cssmaclpod.cpp>
+#include <cdsa_utilities/mach++.cpp>
+#include <cdsa_utilities/machserver.cpp>
+#include <cdsa_utilities/mach_notify.c>
+#include <cdsa_utilities/cssmcred.cpp>
+#include <cdsa_utilities/acl_threshold.cpp>
+#include <cdsa_utilities/acl_process.cpp>
+#include <cdsa_utilities/machrunloopserver.cpp>
+#include <cdsa_utilities/AppleDatabase.cpp>
+#include <cdsa_utilities/DbIndex.cpp>
+#include <cdsa_utilities/DbValue.cpp>
+#include <cdsa_utilities/MetaAttribute.cpp>
+#include <cdsa_utilities/MetaRecord.cpp>
+#include <cdsa_utilities/SelectionPredicate.cpp>
+#include <cdsa_utilities/debugging.cpp>
+#include <cdsa_utilities/logging.cpp>
+#include <cdsa_utilities/tqueue.cpp>
+#include <cdsa_utilities/codesigning.cpp>
+#include <cdsa_utilities/acl_codesigning.cpp>
+#include <cdsa_utilities/osxsigning.cpp>
+#include <cdsa_utilities/daemon.cpp>
+#include <cdsa_utilities/acl_comment.cpp>
diff --git a/cdsa/cdsa_utilities/.cvsignore b/cdsa/cdsa_utilities/.cvsignore
new file mode 100644
index 00000000..2a8f2f8b
--- /dev/null
+++ b/cdsa/cdsa_utilities/.cvsignore
@@ -0,0 +1 @@
+cdsa_utilities?Data
diff --git a/cdsa/cdsa_utilities/AppleDatabase.cpp b/cdsa/cdsa_utilities/AppleDatabase.cpp
new file mode 100644
index 00000000..dfb752b5
--- /dev/null
+++ b/cdsa/cdsa_utilities/AppleDatabase.cpp
@@ -0,0 +1,2225 @@
+/*
+ * 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.
+ */
+
+
+//
+//  AppleDatabase.cpp - Description t.b.d.
+//
+#include "AppleDatabase.h"
+#include <Security/DatabaseSession.h>
+#include <Security/DbContext.h>
+#include <Security/cssmdb.h>
+#include <Security/cssmapple.h>
+#include <fcntl.h>
+#include <memory>
+
+//
+// Table
+//
+Table::Table(const ReadSection &inTableSection) :
+	mMetaRecord(inTableSection[OffsetId]),
+	mTableSection(inTableSection),
+	mRecordsCount(inTableSection[OffsetRecordsCount]),
+	mFreeListHead(inTableSection[OffsetFreeListHead]),
+	mRecordNumbersCount(inTableSection[OffsetRecordNumbersCount])
+{
+	// can't easily initialize indexes here, since meta record is incomplete
+	// until much later... see DbVersion::open()
+}
+
+Table::~Table() 
+{
+	for_each_map_delete(mIndexMap.begin(), mIndexMap.end());
+}
+
+void
+Table::readIndexSection()
+{
+	uint32 indexSectionOffset = mTableSection.at(OffsetIndexesOffset);
+
+	uint32 numIndexes = mTableSection.at(indexSectionOffset + AtomSize);
+
+	for (uint32 i = 0; i < numIndexes; i++) {
+		uint32 indexOffset = mTableSection.at(indexSectionOffset + (i + 2) * AtomSize);
+		ReadSection indexSection(mTableSection.subsection(indexOffset));
+	
+		auto_ptr<DbConstIndex> index(new DbConstIndex(*this, indexSection));
+		mIndexMap.insert(ConstIndexMap::value_type(index->indexId(), index.get()));
+		index.release();
+	}
+}
+
+Cursor *
+Table::createCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion) const
+{
+	// if an index matches the query, return a cursor which uses the index
+
+	ConstIndexMap::const_iterator it;
+	DbQueryKey *queryKey;
+	
+	for (it = mIndexMap.begin(); it != mIndexMap.end(); it++)
+		if (it->second->matchesQuery(*inQuery, queryKey)) {
+			IndexCursor *cursor = new IndexCursor(queryKey, inDbVersion, *this, it->second);
+			return cursor;
+		}
+
+	// otherwise, return a cursor that iterates over all table records
+
+	return new LinearCursor(inQuery, inDbVersion, *this);
+}
+
+const ReadSection
+Table::getRecordSection(uint32 inRecordNumber) const
+{
+	if (inRecordNumber >= mRecordNumbersCount)
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
+
+	uint32 aRecordOffset = mTableSection[OffsetRecordNumbers + AtomSize
+										 * inRecordNumber];
+
+	// Check if this RecordNumber has been deleted.
+	if (aRecordOffset & 1 || aRecordOffset == 0)
+		CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND);
+
+	return MetaRecord::readSection(mTableSection, aRecordOffset);
+}
+
+const RecordId
+Table::getRecord(const RecordId &inRecordId,
+				 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+				 CssmData *inoutData,
+				 CssmAllocator &inAllocator) const
+{
+	const ReadSection aRecordSection = getRecordSection(inRecordId.mRecordNumber);
+	const RecordId aRecordId = MetaRecord::unpackRecordId(aRecordSection);
+
+	// Make sure the RecordNumber matches that in the RecordId we just retrived.
+	if (aRecordId.mRecordNumber != inRecordId.mRecordNumber)
+		CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+	if (aRecordId.mCreateVersion != inRecordId.mCreateVersion)
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
+
+	// XXX Figure out which value to pass for inQueryFlags (5th) argument
+	mMetaRecord.unpackRecord(aRecordSection, inAllocator, inoutAttributes,
+							 inoutData, 0);
+	return aRecordId;
+}
+
+uint32
+Table::popFreeList(uint32 &aFreeListHead) const
+{
+	assert(aFreeListHead | 1);
+	uint32 anOffset = aFreeListHead ^ 1;
+	uint32 aRecordNumber = (anOffset - OffsetRecordNumbers) / AtomSize;
+	aFreeListHead = mTableSection[anOffset];
+	return aRecordNumber;
+}
+
+const ReadSection
+Table::getRecordsSection() const
+{
+	return mTableSection.subsection(mTableSection[OffsetRecords]);
+}
+
+bool
+Table::matchesTableId(Id inTableId) const
+{
+	Id anId = mMetaRecord.dataRecordType();
+	if (inTableId == CSSM_DL_DB_RECORD_ANY) // All non schema tables.
+		return !(CSSM_DB_RECORDTYPE_SCHEMA_START <= anId
+				 && anId < CSSM_DB_RECORDTYPE_SCHEMA_END);
+
+	if (inTableId == CSSM_DL_DB_RECORD_ALL_KEYS) // All key tables.
+		return (anId == CSSM_DL_DB_RECORD_PUBLIC_KEY
+				|| anId == CSSM_DL_DB_RECORD_PRIVATE_KEY
+				|| anId == CSSM_DL_DB_RECORD_SYMMETRIC_KEY);
+
+	return inTableId == anId; // Only if exact match.
+}
+
+
+//
+// ModifiedTable
+//
+ModifiedTable::ModifiedTable(const Table *inTable) :
+	mTable(inTable),
+	mNewMetaRecord(nil),
+	mRecordNumberCount(inTable->recordNumberCount()),
+	mFreeListHead(inTable->freeListHead()),
+	mIsModified(false)
+{
+}
+
+ModifiedTable::ModifiedTable(MetaRecord *inMetaRecord) :
+	mTable(nil),
+	mNewMetaRecord(inMetaRecord),
+	mRecordNumberCount(0),
+	mFreeListHead(0),
+	mIsModified(true)
+{
+}
+
+ModifiedTable::~ModifiedTable()
+{
+	for_each_map_delete(mIndexMap.begin(), mIndexMap.end());
+	for_each_map_delete(mInsertedMap.begin(), mInsertedMap.end());
+
+	delete mNewMetaRecord;
+}
+
+void
+ModifiedTable::deleteRecord(const RecordId &inRecordId)
+{
+	modifyTable();
+
+    uint32 aRecordNumber = inRecordId.mRecordNumber;
+	
+	// remove the record from all the indexes
+	MutableIndexMap::iterator it;
+	for (it = mIndexMap.begin(); it != mIndexMap.end(); it++)
+		it->second->removeRecord(aRecordNumber);
+
+	InsertedMap::iterator anIt = mInsertedMap.find(inRecordId.mRecordNumber);
+	if (anIt == mInsertedMap.end())
+	{
+		// If we have no old table than this record can not exist yet.
+		if (!mTable)
+			CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND);
+
+		const RecordId aRecordId = MetaRecord::unpackRecordId(mTable->getRecordSection(aRecordNumber));
+		if (aRecordId.mRecordVersion != inRecordId.mRecordVersion)
+			CssmError::throwMe(CSSMERR_DL_RECORD_MODIFIED);
+
+		// Schedule the record for deletion
+		if (!mDeletedSet.insert(aRecordNumber).second)
+			CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND); // It was already deleted
+	}
+	else
+	{
+		const RecordId aRecordId = MetaRecord::unpackRecordId(*anIt->second);
+		if (aRecordId.mCreateVersion != inRecordId.mCreateVersion)
+			CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND);
+
+		if (aRecordId.mRecordVersion != inRecordId.mRecordVersion)
+			CssmError::throwMe(CSSMERR_DL_RECORD_MODIFIED);
+
+		// Remove the inserted (but uncommited) record.  It should already be in mDeletedSet
+		// if it existed previously in mTable.
+		mInsertedMap.erase(anIt);
+        delete anIt->second;		
+	}
+}
+
+const RecordId
+ModifiedTable::insertRecord(AtomicFile::VersionId inVersionId,
+							const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+							const CssmData *inData)
+{
+	modifyTable();
+	
+	auto_ptr<WriteSection> aWriteSection(new WriteSection());
+	getMetaRecord().packRecord(*aWriteSection, inAttributes, inData);
+    uint32 aRecordNumber = nextRecordNumber();
+	
+	// add the record to all the indexes; this will throw if the new record
+	// violates a unique index
+	MutableIndexMap::iterator it;
+	for (it = mIndexMap.begin(); it != mIndexMap.end(); it++)
+		it->second->insertRecord(aRecordNumber, *(aWriteSection.get()));
+
+	// schedule the record for insertion
+	RecordId aRecordId(aRecordNumber, inVersionId);
+	MetaRecord::packRecordId(aRecordId, *aWriteSection);
+    mInsertedMap.insert(InsertedMap::value_type(aRecordNumber, aWriteSection.get()));
+
+    aWriteSection.release();
+	
+    return aRecordId;
+}
+
+const RecordId
+ModifiedTable::updateRecord(const RecordId &inRecordId,
+							const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+							const CssmData *inData,
+							CSSM_DB_MODIFY_MODE inModifyMode)
+{
+	modifyTable();
+
+    uint32 aRecordNumber = inRecordId.mRecordNumber;
+	InsertedMap::iterator anIt = mInsertedMap.find(inRecordId.mRecordNumber);
+
+	// aReUpdate is true iff we are updating an already updated record.
+	bool aReUpdate = anIt != mInsertedMap.end();
+
+	// If we are not re-updating and there is no old table than this record does not exist yet.
+	if (!aReUpdate && !mTable)
+		CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND);
+
+	const ReadSection &anOldDbRecord = aReUpdate ? *anIt->second : mTable->getRecordSection(aRecordNumber);
+	const RecordId aRecordId = MetaRecord::unpackRecordId(anOldDbRecord);
+
+	// Did someone else delete the record we are trying to update.
+	if (aRecordId.mCreateVersion != inRecordId.mCreateVersion)
+		CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND);
+
+	// Is the record we that our update is based on current?
+	if (aRecordId.mRecordVersion != inRecordId.mRecordVersion)
+		CssmError::throwMe(CSSMERR_DL_STALE_UNIQUE_RECORD);
+
+	// Update the actual packed record.
+    auto_ptr<WriteSection> aDbRecord(new WriteSection());
+	getMetaRecord().updateRecord(anOldDbRecord, *aDbRecord,
+		CssmDbRecordAttributeData::overlay(inAttributes), inData, inModifyMode);
+
+
+	// Bump the RecordVersion of this record.
+	RecordId aNewRecordId(aRecordNumber, inRecordId.mCreateVersion, inRecordId.mRecordVersion + 1);
+	// Store the RecordVersion in the packed aDbRecord.
+	MetaRecord::packRecordId(aNewRecordId, *aDbRecord);
+
+	if (!aReUpdate && !mDeletedSet.insert(aRecordNumber).second)
+		CssmError::throwMe(CSSMERR_DL_RECORD_NOT_FOUND); // Record was already in mDeletedSet
+
+	try
+	{
+		// remove the original record from all the indexes
+		MutableIndexMap::iterator it;
+		for (it = mIndexMap.begin(); it != mIndexMap.end(); it++)
+			it->second->removeRecord(aRecordNumber);
+
+		// add the updated record to all the indexes; this will throw if the new record
+		// violates a unique index
+		for (it = mIndexMap.begin(); it != mIndexMap.end(); it++)
+			it->second->insertRecord(aRecordNumber, *(aDbRecord.get()));
+
+		mInsertedMap.insert(InsertedMap::value_type(aRecordNumber, aDbRecord.get()));
+		aDbRecord.release();
+	}
+	catch(...)
+	{
+		if (!aReUpdate)
+			mDeletedSet.erase(aRecordNumber);
+		throw;
+	}
+
+	return aNewRecordId;
+}
+
+uint32
+ModifiedTable::nextRecordNumber()
+{
+	// If we still have unused free records in mTable get the next one.
+	if (mFreeListHead)
+		return mTable->popFreeList(mFreeListHead);
+
+	// Bump up the mRecordNumberCount so we don't reuse the same one.
+	return mRecordNumberCount++;
+}
+
+uint32
+ModifiedTable::recordNumberCount() const
+{
+	uint32 anOldMax = !mTable ? 0 : mTable->recordNumberCount() - 1;
+	uint32 anInsertedMax = mInsertedMap.empty() ? 0 : mInsertedMap.rbegin()->first;
+
+	DeletedSet::reverse_iterator anIt = mDeletedSet.rbegin();
+	DeletedSet::reverse_iterator anEnd = mDeletedSet.rend();
+	for (; anIt != anEnd; anIt++)
+	{
+		if (*anIt != anOldMax || anOldMax <= anInsertedMax)
+			break;
+		anOldMax--;
+ 	}
+
+	return max(anOldMax,anInsertedMax) + 1;
+}
+
+const MetaRecord &
+ModifiedTable::getMetaRecord() const
+{
+	return mNewMetaRecord ? *mNewMetaRecord : mTable->getMetaRecord();
+}
+
+// prepare to modify the table
+
+void
+ModifiedTable::modifyTable()
+{
+	if (!mIsModified) {
+		createMutableIndexes();
+		mIsModified = true;
+	}
+}
+
+// create mutable indexes from the read-only indexes in the underlying table
+
+void
+ModifiedTable::createMutableIndexes()
+{
+	if (mTable == NULL)
+		return;
+	
+	Table::ConstIndexMap::const_iterator it;
+	for (it = mTable->mIndexMap.begin(); it != mTable->mIndexMap.end(); it++) {
+		auto_ptr<DbMutableIndex> mutableIndex(new DbMutableIndex(*it->second));
+		mIndexMap.insert(MutableIndexMap::value_type(it->first, mutableIndex.get()));
+		mutableIndex.release();
+	}
+}
+
+// find, and create if needed, an index with the given id
+
+DbMutableIndex &
+ModifiedTable::findIndex(uint32 indexId, const MetaRecord &metaRecord, bool isUniqueIndex)
+{
+	MutableIndexMap::iterator it = mIndexMap.find(indexId);
+
+	if (it == mIndexMap.end()) {
+		// create the new index
+		auto_ptr<DbMutableIndex> index(new DbMutableIndex(metaRecord, indexId, isUniqueIndex));
+		it = mIndexMap.insert(MutableIndexMap::value_type(indexId, index.get())).first;
+		index.release();
+	}
+
+	return *it->second;
+}
+
+uint32
+ModifiedTable::writeIndexSection(WriteSection &tableSection, uint32 offset)
+{
+	MutableIndexMap::iterator it;
+	
+	tableSection.put(Table::OffsetIndexesOffset, offset);
+	
+	// leave room for the size, to be written later
+	uint32 indexSectionOffset = offset;
+	offset += AtomSize;
+	
+	offset = tableSection.put(offset, mIndexMap.size());
+	
+	// leave room for the array of offsets to the indexes
+	uint32 indexOffsetOffset = offset;
+	offset += mIndexMap.size() * AtomSize;
+	
+	// write the indexes
+	for (it = mIndexMap.begin(); it != mIndexMap.end(); it++) {
+		indexOffsetOffset = tableSection.put(indexOffsetOffset, offset);
+		offset = it->second->writeIndex(tableSection, offset);
+	}
+	
+	// write the total index section size
+	tableSection.put(indexSectionOffset, offset - indexSectionOffset);
+
+	return offset;
+}
+
+uint32
+ModifiedTable::writeTable(AtomicFile &inAtomicFile, uint32 inSectionOffset)
+{
+	if (mTable && !mIsModified) {
+		// the table has not been modified, so we can just dump the old table
+		// section into the new database
+
+		const ReadSection &tableSection = mTable->getTableSection();
+		uint32 tableSize = tableSection.at(Table::OffsetSize);
+		
+		inAtomicFile.write(AtomicFile::FromStart, inSectionOffset,
+			tableSection.range(Range(0, tableSize)), tableSize);
+
+		return inSectionOffset + tableSize;
+	}
+
+	// We should have an old mTable or a mNewMetaRecord but not both.
+	assert(mTable != nil ^ mNewMetaRecord != nil);
+	const MetaRecord &aNewMetaRecord = getMetaRecord();
+	
+	uint32 aRecordsCount = 0;
+	uint32 aRecordNumbersCount = recordNumberCount();
+	uint32 aRecordsOffset = Table::OffsetRecordNumbers + AtomSize * aRecordNumbersCount;
+	WriteSection aTableSection(CssmAllocator::standard(), aRecordsOffset);
+	aTableSection.size(aRecordsOffset);
+	aTableSection.put(Table::OffsetId, aNewMetaRecord.dataRecordType());
+	aTableSection.put(Table::OffsetRecords, aRecordsOffset);
+	aTableSection.put(Table::OffsetRecordNumbersCount, aRecordNumbersCount);
+	
+	uint32 anOffset = inSectionOffset + aRecordsOffset;
+
+	if (mTable)
+	{
+		// XXX Handle schema changes in the future.
+		assert(mNewMetaRecord == nil);
+		
+		// We have a modified old table so copy all non deleted records
+		// The code below is rather elaborate, but this is because it attempts
+		// to copy large ranges of non deleted records with single calls
+		// to AtomicFile::write()
+		uint32 anOldRecordsCount = mTable->getRecordsCount();
+		ReadSection aRecordsSection = mTable->getRecordsSection();
+		uint32 aReadOffset = 0;					// Offset of current record
+		uint32 aWriteOffset = aRecordsOffset;	// Offset for current write record
+		uint32 aBlockStart = aReadOffset;		// Starting point for read 
+		uint32 aBlockSize = 0;					// Size of block to read
+		for (uint32 aRecord = 0; aRecord < anOldRecordsCount; aRecord++)
+		{
+			ReadSection aRecordSection = MetaRecord::readSection(aRecordsSection, aReadOffset);
+			uint32 aRecordNumber = MetaRecord::unpackRecordNumber(aRecordSection);
+			uint32 aRecordSize = aRecordSection.size();
+			aReadOffset += aRecordSize;
+			if (mDeletedSet.find(aRecordNumber) == mDeletedSet.end())
+			{
+				// This record has not been deleted.  Register the offset
+				// at which it will be in the new file in aTableSection.
+				aTableSection.put(Table::OffsetRecordNumbers
+								  + AtomSize * aRecordNumber,
+								  aWriteOffset);
+				aWriteOffset += aRecordSize;
+				aBlockSize += aRecordSize;
+				aRecordsCount++;
+				// XXX update all indexes being created.
+			}
+			else
+			{
+				// The current record has been deleted.  Copy all records up
+				// to but not including the current one to the new file.
+				if (aBlockSize > 0)
+				{
+					inAtomicFile.write(AtomicFile::FromStart, anOffset,
+									   aRecordsSection.range(Range(aBlockStart,
+																   aBlockSize)),
+									   aBlockSize);
+					anOffset += aBlockSize;
+				}
+
+				// Set the start of the next block to the start of the next
+				// record, and the size of the block to 0.
+				aBlockStart = aReadOffset;
+				aBlockSize = 0;
+			} // if (mDeletedSet..)
+		} // for (aRecord...)
+
+		// Copy all records that have not yet been copied to the new file.
+		if (aBlockSize > 0)
+		{
+			inAtomicFile.write(AtomicFile::FromStart, anOffset,
+							   aRecordsSection.range(Range(aBlockStart,
+														   aBlockSize)),
+							   aBlockSize);
+			anOffset += aBlockSize;
+		}
+	} // if (mTable)
+
+	// Now add all inserted records to the table.
+	InsertedMap::const_iterator anIt = mInsertedMap.begin();
+	InsertedMap::const_iterator anEnd = mInsertedMap.end();
+	// Iterate over all inserted objects.
+	for (; anIt != anEnd; anIt++)
+	{
+		// Write out each inserted/modified record
+		const WriteSection &aRecord = *anIt->second;
+		uint32 aRecordNumber = anIt->first;
+		// Put offset relative to start of this table in recordNumber array.
+		aTableSection.put(Table::OffsetRecordNumbers + AtomSize * aRecordNumber,
+						  anOffset - inSectionOffset);
+		inAtomicFile.write(AtomicFile::FromStart, anOffset,
+						   aRecord.address(), aRecord.size());
+		anOffset += aRecord.size();
+		aRecordsCount++;
+		// XXX update all indexes being created.
+	}
+
+	// Reconstruct the freelist (this is O(N) where N is the number of recordNumbers)
+	// We could implement it faster by using the old freelist and skipping the records
+	// that have been inserted.  However building the freelist for the newly used
+	// recordNumbers (not in mTable) would look like the code below anyway (starting
+	// from mTable->recordNumberCount()).
+	// The first part of this would be O(M Log(N))  (where M is the old number of
+	// free records, and N is the number of newly inserted records)
+	// The second part would be O(N) where N is the currently max RecordNumber
+	// in use - the old max RecordNumber in use.
+	uint32 aFreeListHead = 0;	// Link to previous free record
+	for (uint32 aRecordNumber = 0; aRecordNumber < aRecordNumbersCount; aRecordNumber++)
+	{
+		// Make the freelist a list of all records with 0 offset (non existing).
+		if (!aTableSection.at(Table::OffsetRecordNumbers + AtomSize * aRecordNumber))
+		{
+			aTableSection.put(Table::OffsetRecordNumbers
+								+ AtomSize * aRecordNumber,
+								aFreeListHead);
+			// Make aFreeListHead point to the previous free recordNumber slot in the table.
+			aFreeListHead = (Table::OffsetRecordNumbers + AtomSize * aRecordNumber) | 1;
+		}
+	}
+	aTableSection.put(Table::OffsetFreeListHead, aFreeListHead);
+
+	anOffset -= inSectionOffset;
+	
+	// Write out indexes, which are part of the table section
+
+	{	
+		uint32 indexOffset = anOffset;
+		anOffset = writeIndexSection(aTableSection, anOffset);
+		inAtomicFile.write(AtomicFile::FromStart, inSectionOffset + indexOffset,
+			aTableSection.address() + indexOffset, anOffset - indexOffset);
+	}
+
+	// Set the section size and recordCount.
+	aTableSection.put(Table::OffsetSize, anOffset);
+	aTableSection.put(Table::OffsetRecordsCount, aRecordsCount);
+
+	// Write out aTableSection header.
+	inAtomicFile.write(AtomicFile::FromStart, inSectionOffset,
+					   aTableSection.address(), aTableSection.size());
+
+    return anOffset + inSectionOffset;
+}
+
+
+
+//
+// Metadata
+//
+
+// Attribute definitions
+
+static const CSSM_DB_ATTRIBUTE_INFO RelationID =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"RelationID"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+static const CSSM_DB_ATTRIBUTE_INFO RelationName =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"RelationName"},
+    CSSM_DB_ATTRIBUTE_FORMAT_STRING
+};
+static const CSSM_DB_ATTRIBUTE_INFO AttributeID =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"AttributeID"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+static const CSSM_DB_ATTRIBUTE_INFO AttributeNameFormat =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"AttributeNameFormat"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+static const CSSM_DB_ATTRIBUTE_INFO AttributeName =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"AttributeName"},
+    CSSM_DB_ATTRIBUTE_FORMAT_STRING
+};
+static const CSSM_DB_ATTRIBUTE_INFO AttributeNameID =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"AttributeNameID"},
+    CSSM_DB_ATTRIBUTE_FORMAT_BLOB
+};
+static const CSSM_DB_ATTRIBUTE_INFO AttributeFormat =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"AttributeFormat"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+static const CSSM_DB_ATTRIBUTE_INFO IndexID =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"IndexID"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+static const CSSM_DB_ATTRIBUTE_INFO IndexType =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"IndexType"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+static const CSSM_DB_ATTRIBUTE_INFO IndexedDataLocation =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"IndexedDataLocation"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+static const CSSM_DB_ATTRIBUTE_INFO ModuleID =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"ModuleID"},
+    CSSM_DB_ATTRIBUTE_FORMAT_BLOB
+};
+static const CSSM_DB_ATTRIBUTE_INFO AddinVersion =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"AddinVersion"},
+    CSSM_DB_ATTRIBUTE_FORMAT_STRING
+};
+static const CSSM_DB_ATTRIBUTE_INFO SSID =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"SSID"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+static const CSSM_DB_ATTRIBUTE_INFO SubserviceType =
+{
+    CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
+    {"SubserviceType"},
+    CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+};
+
+#define ATTRIBUTE(type, name) \
+	{ CSSM_DB_ATTRIBUTE_NAME_AS_STRING, { #name }, CSSM_DB_ATTRIBUTE_FORMAT_ ## type }
+	
+static const CSSM_DB_ATTRIBUTE_INFO AttrSchemaRelations[] =
+{
+	//RelationID, RelationName
+	ATTRIBUTE(UINT32, RelationID),
+	ATTRIBUTE(STRING, RelationName)
+};
+
+static const CSSM_DB_ATTRIBUTE_INFO AttrSchemaAttributes[] =
+{
+	//RelationID, AttributeID,
+    //AttributeNameFormat, AttributeName, AttributeNameID,
+    //AttributeFormat
+	ATTRIBUTE(UINT32, RelationID),
+	ATTRIBUTE(UINT32, AttributeID),
+	ATTRIBUTE(UINT32, AttributeNameFormat),
+	ATTRIBUTE(STRING, AttributeName),
+	ATTRIBUTE(BLOB, AttributeNameID),
+	ATTRIBUTE(UINT32, AttributeFormat)
+};
+
+static const CSSM_DB_ATTRIBUTE_INFO AttrSchemaIndexes[] =
+{
+	ATTRIBUTE(UINT32, RelationID),
+	ATTRIBUTE(UINT32, IndexID),
+	ATTRIBUTE(UINT32, AttributeID),
+	ATTRIBUTE(UINT32, IndexType),
+	ATTRIBUTE(UINT32, IndexedDataLocation)
+    //RelationID, IndexID, AttributeID,
+    //IndexType, IndexedDataLocation
+};
+
+static const CSSM_DB_ATTRIBUTE_INFO AttrSchemaParsingModule[] =
+{
+	ATTRIBUTE(UINT32, RelationID),
+	ATTRIBUTE(UINT32, AttributeID),
+	ATTRIBUTE(BLOB, ModuleID),
+	ATTRIBUTE(STRING, AddinVersion),
+	ATTRIBUTE(UINT32, SSID),
+	ATTRIBUTE(UINT32, SubserviceType)
+    //RelationID, AttributeID,
+    //ModuleID, AddinVersion, SSID, SubserviceType
+};
+
+#undef ATTRIBUTE
+
+//
+// DbVersion
+//
+DbVersion::DbVersion(AtomicFile &inDatabaseFile,
+	const AppleDatabase &db) :
+	mDatabase(reinterpret_cast<const uint8 *>(NULL), 0), mDatabaseFile(&inDatabaseFile),
+	mDb(db)
+{
+	const uint8 *aFileAddress;
+	size_t aLength;
+	mVersionId = mDatabaseFile->enterRead(aFileAddress, aLength);
+	mDatabase = ReadSection(aFileAddress, aLength);
+	open();
+}
+
+DbVersion::~DbVersion()
+{
+	try
+	{
+		for_each_map_delete(mTableMap.begin(), mTableMap.end());
+		if (mDatabaseFile)
+			mDatabaseFile->exitRead(mVersionId);
+	}
+	catch(...) {}
+}
+
+bool
+DbVersion::isDirty() const
+{
+	if (mDatabaseFile)
+		return mDatabaseFile->isDirty(mVersionId);
+
+	return true;
+}
+
+void
+DbVersion::open()
+{
+	try
+	{
+		// This is the oposite of DbModifier::commit()
+		const ReadSection aHeaderSection = mDatabase.subsection(HeaderOffset,
+																HeaderSize);
+		if (aHeaderSection.at(OffsetMagic) != HeaderMagic)
+			CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+	
+		// We currently only support one version.  If we support additional
+		// file format versions in the future fix this.
+		uint32 aVersion = aHeaderSection.at(OffsetVersion);
+		if (aVersion != HeaderVersion)
+			CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+	
+		//const ReadSection anAuthSection =
+		//	mDatabase.subsection(HeaderOffset + aHeaderSection.at(OffsetAuthOffset));
+		// XXX Do something with anAuthSection.
+	
+		uint32 aSchemaOffset = aHeaderSection.at(OffsetSchemaOffset);
+		const ReadSection aSchemaSection =
+			mDatabase.subsection(HeaderOffset + aSchemaOffset);
+	
+		uint32 aSchemaSize = aSchemaSection[OffsetSchemaSize];
+		// Make sure that the given range exists.
+		aSchemaSection.subsection(0, aSchemaSize);
+		uint32 aTableCount = aSchemaSection[OffsetTablesCount];
+	
+		// Assert that the size of this section is big enough.
+		if (aSchemaSize < OffsetTables + AtomSize * aTableCount)
+			CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+	
+		for (uint32 aTableNumber = 0; aTableNumber < aTableCount;
+			 aTableNumber++)
+		{
+			uint32 aTableOffset = aSchemaSection.at(OffsetTables + AtomSize
+													* aTableNumber);
+			// XXX Set the size boundary on aTableSection.
+			const ReadSection aTableSection =
+				aSchemaSection.subsection(aTableOffset);
+			auto_ptr<Table> aTable(new Table(aTableSection));
+			Table::Id aTableId = aTable->getMetaRecord().dataRecordType();
+			mTableMap.insert(TableMap::value_type(aTableId, aTable.get()));
+			aTable.release();
+		}
+
+		// Fill in the schema for the meta tables.
+		
+		findTable(mDb.schemaRelations.DataRecordType).getMetaRecord().
+			setRecordAttributeInfo(mDb.schemaRelations);
+		findTable(mDb.schemaIndexes.DataRecordType).getMetaRecord().
+			setRecordAttributeInfo(mDb.schemaIndexes);
+		findTable(mDb.schemaParsingModule.DataRecordType).getMetaRecord().
+			setRecordAttributeInfo(mDb.schemaParsingModule);
+
+		// OK, we have created all the tables in the tableMap.  Now
+		// lets read the schema and proccess it accordingly.
+		// Iterate over all schema records.
+		Table &aTable = findTable(mDb.schemaAttributes.DataRecordType);
+		aTable.getMetaRecord().setRecordAttributeInfo(mDb.schemaAttributes);
+		uint32 aRecordsCount = aTable.getRecordsCount();
+		ReadSection aRecordsSection = aTable.getRecordsSection();
+		uint32 aReadOffset = 0;
+		const MetaRecord &aMetaRecord = aTable.getMetaRecord();
+
+		CSSM_DB_ATTRIBUTE_DATA aRelationIDData =
+		{
+			RelationID,
+			0,
+			NULL
+		};
+		CSSM_DB_ATTRIBUTE_DATA aAttributeIDData =
+		{
+			AttributeID,
+			0,
+			NULL
+		};
+		CSSM_DB_ATTRIBUTE_DATA aAttributeNameFormatData =
+		{
+			AttributeNameFormat,
+			0,
+			NULL
+		};
+		CSSM_DB_ATTRIBUTE_DATA aAttributeNameData =
+		{
+			AttributeName,
+			0,
+			NULL
+		};
+		CSSM_DB_ATTRIBUTE_DATA aAttributeNameIDData =
+		{
+			AttributeNameID,
+			0,
+			NULL
+		};
+		CSSM_DB_ATTRIBUTE_DATA aAttributeFormatData =
+		{
+			AttributeFormat,
+			0,
+			NULL
+		};
+		CSSM_DB_ATTRIBUTE_DATA aRecordAttributes[] =
+		{
+			aRelationIDData,
+			aAttributeIDData,
+			aAttributeNameFormatData,
+			aAttributeNameData,
+			aAttributeNameIDData,
+			aAttributeFormatData
+		};
+		CSSM_DB_RECORD_ATTRIBUTE_DATA aRecordAttributeData =
+		{
+			aMetaRecord.dataRecordType(),
+			0,
+			sizeof(aRecordAttributes) / sizeof(CSSM_DB_ATTRIBUTE_DATA),
+			aRecordAttributes
+		};
+		CssmDbRecordAttributeData &aRecordData = CssmDbRecordAttributeData::overlay(aRecordAttributeData);
+
+		TrackingAllocator recordAllocator(CssmAllocator::standard());
+		for (uint32 aRecord = 0; aRecord != aRecordsCount; aRecord++)
+		{
+			ReadSection aRecordSection = MetaRecord::readSection(aRecordsSection, aReadOffset);
+			uint32 aRecordSize = aRecordSection.size();
+			aReadOffset += aRecordSize;
+#if 0
+			try
+			{
+#endif
+				aMetaRecord.unpackRecord(aRecordSection, recordAllocator,
+										 &aRecordAttributeData, NULL, 0);
+				// Create the attribute coresponding to this entry
+				if (aRecordData[0].size() != 1 || aRecordData[0].format() != CSSM_DB_ATTRIBUTE_FORMAT_UINT32)
+					CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+				uint32 aRelationId = aRecordData[0];
+
+				// Skip the schema relations for the meta tables themselves.
+				if (CSSM_DB_RECORDTYPE_SCHEMA_START <= aRelationId && aRelationId < CSSM_DB_RECORDTYPE_SCHEMA_END)
+					continue;
+
+				// Get the MetaRecord corresponding to the specified RelationId
+				MetaRecord &aMetaRecord = findTable(aRelationId).getMetaRecord();
+
+				if (aRecordData[1].size() != 1
+					|| aRecordData[1].format() != CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+					|| aRecordData[2].size() != 1
+					|| aRecordData[2].format() != CSSM_DB_ATTRIBUTE_FORMAT_UINT32
+					|| aRecordData[5].size() != 1
+					|| aRecordData[5].format() != CSSM_DB_ATTRIBUTE_FORMAT_UINT32)
+					CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+				uint32 anAttributeId = aRecordData[1];
+				uint32 anAttributeNameFormat = aRecordData[2];
+				uint32 anAttributeFormat = aRecordData[5];
+				auto_ptr<string> aName;
+				const CssmData *aNameID = NULL;
+
+				if (aRecordData[3].size() == 1)
+				{
+					if (aRecordData[3].format() != CSSM_DB_ATTRIBUTE_FORMAT_STRING)
+						CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+					auto_ptr<string> aName2(new string(static_cast<string>(aRecordData[3])));
+					aName = aName2;
+				}
+
+				if (aRecordData[4].size() == 1)
+				{
+					if (aRecordData[4].format() != CSSM_DB_ATTRIBUTE_FORMAT_BLOB)
+						CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+                                        // @@@ Invoking conversion operator to CssmData & on aRecordData[4]
+                                        // And taking address of result.
+					aNameID = &static_cast<CssmData &>(aRecordData[4]);
+				}
+
+				// Make sure that the attribute specified by anAttributeNameFormat is present. 
+				switch (anAttributeNameFormat)
+				{
+				case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
+					if (aRecordData[3].size() != 1)
+						CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+					break;
+				case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
+					if (aRecordData[4].size() != 1)
+						CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+					break;
+				case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
+					break;
+				default:
+					CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+				}
+
+				// Create the attribute
+				aMetaRecord.createAttribute(aName.get(), aNameID, anAttributeId, anAttributeFormat);
+
+#if 0
+				// Free the data.
+				aRecordData.deleteValues(CssmAllocator::standard());
+			}
+			catch(...)
+			{
+				aRecordData.deleteValues(CssmAllocator::standard());
+				throw;
+			}
+#endif
+        }
+		
+		// initialize the indexes associated with each table
+		{
+			TableMap::iterator it;
+			for (it = mTableMap.begin(); it != mTableMap.end(); it++)
+				it->second->readIndexSection();
+		}
+	}
+	catch(...)
+	{
+		for_each_map_delete(mTableMap.begin(), mTableMap.end());
+		mTableMap.clear();
+		throw;
+	}
+}
+
+const RecordId
+DbVersion::getRecord(Table::Id inTableId, const RecordId &inRecordId,
+							CSSM_DB_RECORD_ATTRIBUTE_DATA *inoutAttributes,
+							CssmData *inoutData,
+							CssmAllocator &inAllocator) const
+{
+	return findTable(inTableId).getRecord(inRecordId, inoutAttributes,
+										  inoutData, inAllocator);
+}
+
+Cursor *
+DbVersion::createCursor(const CSSM_QUERY *inQuery) const
+{
+	// XXX We should add support for these special query types
+	// By Creating a Cursor that iterates over multiple tables
+	if (!inQuery || inQuery->RecordType == CSSM_DL_DB_RECORD_ANY
+		|| inQuery->RecordType == CSSM_DL_DB_RECORD_ALL_KEYS)
+	{
+		return new MultiCursor(inQuery, *this);
+	}
+
+	return findTable(inQuery->RecordType).createCursor(inQuery, *this);
+}
+
+const Table &
+DbVersion::findTable(Table::Id inTableId) const
+{
+    TableMap::const_iterator it = mTableMap.find(inTableId);
+    if (it == mTableMap.end())
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
+	return *it->second;
+}
+
+Table &
+DbVersion::findTable(Table::Id inTableId)
+{
+    TableMap::iterator it = mTableMap.find(inTableId);
+    if (it == mTableMap.end())
+		CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+	return *it->second;
+}
+
+//
+// Cursor implemetation
+//
+Cursor::~Cursor()
+{
+}
+
+
+//
+// LinearCursor implemetation
+//
+LinearCursor::LinearCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion,
+						   const Table &inTable) :
+    mDbVersion(&inDbVersion),
+    mRecordsCount(inTable.getRecordsCount()),
+    mRecord(0),
+    mRecordsSection(inTable.getRecordsSection()),
+    mReadOffset(0),
+    mMetaRecord(inTable.getMetaRecord())
+{
+	if (inQuery)
+	{
+	    mConjunctive = inQuery->Conjunctive;
+	    mQueryFlags = inQuery->QueryFlags;
+	    // XXX Do something with inQuery->QueryLimits?
+	    uint32 aPredicatesCount = inQuery->NumSelectionPredicates;
+	    mPredicates.resize(aPredicatesCount);
+		try
+		{
+			for (uint32 anIndex = 0; anIndex < aPredicatesCount; anIndex++)
+			{
+				CSSM_SELECTION_PREDICATE &aPredicate = inQuery->SelectionPredicate[anIndex];
+				mPredicates[anIndex] = new SelectionPredicate(mMetaRecord, aPredicate);
+			}
+		}
+		catch(...)
+		{
+			for_each_delete(mPredicates.begin(), mPredicates.end());
+			throw;
+		}
+	}
+}
+
+LinearCursor::~LinearCursor()
+{
+	for_each_delete(mPredicates.begin(), mPredicates.end());
+}
+
+bool
+LinearCursor::next(Table::Id &outTableId,
+				   CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+				   CssmData *inoutData, CssmAllocator &inAllocator, RecordId &recordId)
+{
+	while (mRecord++ < mRecordsCount)
+	{
+		ReadSection aRecordSection = MetaRecord::readSection(mRecordsSection, mReadOffset);
+		uint32 aRecordSize = aRecordSection.size();
+		mReadOffset += aRecordSize;
+
+        PredicateVector::const_iterator anIt = mPredicates.begin();
+        PredicateVector::const_iterator anEnd = mPredicates.end();
+		bool aMatch;
+		if (anIt == anEnd)
+		{
+			// If there are no predicates we have a match.
+			aMatch = true;
+		}
+		else if (mConjunctive == CSSM_DB_OR)
+		{
+			// If mConjunctive is OR, the first predicate that returns
+			// true indicates a match. Dropthough means no match
+			aMatch = false;
+			for (; anIt != anEnd; anIt++)
+			{
+				if ((*anIt)->evaluate(aRecordSection))
+				{
+					aMatch = true;
+                    break;
+				}
+			}
+		}
+		else if (mConjunctive == CSSM_DB_AND || mConjunctive == CSSM_DB_NONE)
+		{
+			// If mConjunctive is AND (or NONE), the first predicate that returns
+			// false indicates a mismatch. Dropthough means a match
+			aMatch = true;
+			for (; anIt != anEnd; anIt++)
+			{
+				if (!(*anIt)->evaluate(aRecordSection))
+				{
+					aMatch = false;
+                    break;
+				}
+			}
+		}
+		else
+		{
+			// XXX Should be CSSMERR_DL_INVALID_QUERY (or CSSMERR_DL_INVALID_CONJUNTIVE).
+			CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
+		}
+
+        if (aMatch)
+        {
+            // Get the actual record.
+            mMetaRecord.unpackRecord(aRecordSection, inAllocator,
+									 inoutAttributes, inoutData,
+									 mQueryFlags);
+			outTableId = mMetaRecord.dataRecordType();
+			recordId = MetaRecord::unpackRecordId(aRecordSection);
+			return true;
+        }
+    }
+
+	return false;
+}
+
+//
+// IndexCursor
+// 
+
+IndexCursor::IndexCursor(DbQueryKey *queryKey, const DbVersion &inDbVersion,
+	const Table &table, const DbConstIndex *index)
+:	mQueryKey(queryKey), mDbVersion(inDbVersion), mTable(table), mIndex(index)
+{
+	index->performQuery(*queryKey, mBegin, mEnd);
+}
+
+IndexCursor::~IndexCursor()
+{
+	// the query key will be deleted automatically, since it's an auto_ptr
+}
+
+bool
+IndexCursor::next(Table::Id &outTableId,
+	CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes,
+	CssmData *outData,
+	CssmAllocator &inAllocator, RecordId &recordId)
+{
+	if (mBegin == mEnd)
+		return false;
+		
+	ReadSection rs = mIndex->getRecordSection(mBegin++);
+	const MetaRecord &metaRecord = mTable.getMetaRecord();
+
+	outTableId = metaRecord.dataRecordType();
+	metaRecord.unpackRecord(rs, inAllocator, outAttributes, outData, 0);
+	
+	recordId = MetaRecord::unpackRecordId(rs);
+	return true;
+}
+
+//
+// MultiCursor
+//
+MultiCursor::MultiCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion) :
+    mDbVersion(&inDbVersion), mTableIterator(inDbVersion.begin())
+{
+	if (inQuery)
+		mQuery.reset(new CssmAutoQuery(*inQuery));
+	else
+	{
+		mQuery.reset(new CssmAutoQuery());
+		mQuery->recordType(CSSM_DL_DB_RECORD_ANY);
+	}
+}
+
+MultiCursor::~MultiCursor()
+{
+}
+
+bool
+MultiCursor::next(Table::Id &outTableId,
+				  CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+				  CssmData *inoutData, CssmAllocator &inAllocator, RecordId &recordId)
+{
+	for (;;)
+	{
+		if (!mCursor.get())
+		{
+			if (mTableIterator == mDbVersion->end())
+				return false;
+
+			const Table &aTable = *mTableIterator++;
+			if (!aTable.matchesTableId(mQuery->recordType()))
+				continue;
+
+			mCursor.reset(aTable.createCursor(mQuery.get(), *mDbVersion));
+		}
+
+		if (mCursor->next(outTableId, inoutAttributes, inoutData, inAllocator, recordId))
+			return true;
+			
+		mCursor.reset(NULL);
+	}
+}
+
+
+//
+// DbModifier
+//
+DbModifier::DbModifier(AtomicFile &inAtomicFile, const AppleDatabase &db) :
+	Metadata(),
+	mDbVersion(),
+    mAtomicFile(inAtomicFile),
+    mWriting(false),
+	mDb(db)
+{
+}
+
+DbModifier::~DbModifier()
+{
+    try
+    {
+		for_each_map_delete(mModifiedTableMap.begin(), mModifiedTableMap.end());
+
+        if (mWriting)
+            rollback();
+    }
+    catch(...) {}
+}
+
+const RefPointer<const DbVersion>
+DbModifier::getDbVersion()
+{
+    StLock<Mutex> _(mDbVersionLock);
+	if (mDbVersion && mDbVersion->isDirty())
+		mDbVersion = NULL;
+
+	if (mDbVersion == NULL)
+		mDbVersion = new DbVersion(mAtomicFile, mDb);
+
+    return mDbVersion;
+}
+
+void
+DbModifier::createDatabase(const CSSM_DBINFO &inDbInfo,
+						   const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry)
+{
+	// XXX This needs better locking.  There is a possible race condition between
+	// two concurrent creators.  Or a writer/creator or a close/create etc.
+	if (mWriting || !mModifiedTableMap.empty())
+		CssmError::throwMe(CSSMERR_DL_DATASTORE_ALREADY_EXISTS);
+
+    mVersionId = mAtomicFile.enterCreate(mFileRef);
+    mWriting = true;
+
+	// we need to create the meta tables first, because inserting tables
+	// (including the meta tables themselves) relies on them being there
+    createTable(new MetaRecord(mDb.schemaRelations));
+    createTable(new MetaRecord(mDb.schemaAttributes));
+    createTable(new MetaRecord(mDb.schemaIndexes));
+    createTable(new MetaRecord(mDb.schemaParsingModule));
+	
+	// now add the meta-tables' schema to the meta tables themselves
+	insertTableSchema(mDb.schemaRelations);
+	insertTableSchema(mDb.schemaAttributes);
+	insertTableSchema(mDb.schemaIndexes);
+	insertTableSchema(mDb.schemaParsingModule);
+
+    if (inInitialAclEntry != NULL)
+    {
+        //createACL(*inInitialAclEntry);
+    }
+
+    if (inDbInfo.NumberOfRecordTypes == 0)
+        return;
+    if (inDbInfo.RecordAttributeNames == NULL)
+        CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
+    if (inDbInfo.RecordIndexes == NULL)
+        CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_INDEX);
+    if (inDbInfo.DefaultParsingModules == NULL)
+        CssmError::throwMe(CSSMERR_DL_INVALID_PARSING_MODULE);
+
+    for (uint32 anIndex = 0; anIndex < inDbInfo.NumberOfRecordTypes; anIndex++)
+    {
+        insertTable(CssmDbRecordAttributeInfo::overlay(inDbInfo.RecordAttributeNames[anIndex]),
+					&inDbInfo.RecordIndexes[anIndex],
+					&inDbInfo.DefaultParsingModules[anIndex]);
+    }
+}
+
+void DbModifier::openDatabase()
+{
+	commit(); // XXX Requires write lock.
+	getDbVersion();
+}
+
+void DbModifier::closeDatabase()
+{
+	commit(); // XXX Requires write lock.
+	StLock<Mutex> _(mDbVersionLock);
+	mDbVersion = NULL;
+}
+
+void DbModifier::deleteDatabase()
+{
+	rollback(); // XXX Requires write lock.  Also if autoCommit was disabled
+	// this will incorrectly cause the performDelete to throw CSSMERR_DB_DOES_NOT_EXIST.
+	StLock<Mutex> _(mDbVersionLock);
+	mDbVersion = NULL;
+    mAtomicFile.performDelete();
+}
+
+void
+DbModifier::modifyDatabase()
+{
+	if (mWriting)
+		return;
+
+	try
+	{
+		const uint8 *aFileAddress;
+		size_t aLength;
+		mVersionId = mAtomicFile.enterWrite(aFileAddress, aLength, mFileRef);
+		mWriting = true;
+		{
+			// Aquire the mutex protecting mDbVersion 
+			StLock<Mutex> _l(mDbVersionLock);
+			if (mDbVersion == nil || mDbVersion->getVersionId() != mVersionId)
+			{
+				// This will call enterRead().  Now that we hold the write
+				// lock on the file this ensures we get the same verison
+				// enterWrite just returned.
+				mDbVersion = new DbVersion(mAtomicFile, mDb);
+			}
+		}
+
+		// Remove all old modified tables
+		for_each_map_delete(mModifiedTableMap.begin(), mModifiedTableMap.end());
+		mModifiedTableMap.clear();
+
+		// Setup the new tables
+		DbVersion::TableMap::const_iterator anIt =
+			mDbVersion->mTableMap.begin();
+		DbVersion::TableMap::const_iterator anEnd =
+			mDbVersion->mTableMap.end();
+		for (; anIt != anEnd; ++anIt)
+		{
+			auto_ptr<ModifiedTable> aTable(new ModifiedTable(anIt->second));
+			mModifiedTableMap.insert(ModifiedTableMap::value_type(anIt->first,
+																  aTable.get()));
+			aTable.release();
+		}
+	}
+	catch(...)
+	{
+		for_each_map_delete(mModifiedTableMap.begin(), mModifiedTableMap.end());
+		mModifiedTableMap.clear();
+		rollback();
+		throw;
+	}
+}
+
+void
+DbModifier::deleteRecord(Table::Id inTableId, const RecordId &inRecordId)
+{
+	modifyDatabase();
+	findTable(inTableId).deleteRecord(inRecordId);
+}
+
+const RecordId
+DbModifier::insertRecord(Table::Id inTableId,
+						 const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+						 const CssmData *inData)
+{
+	modifyDatabase();
+	return findTable(inTableId).insertRecord(mVersionId, inAttributes, inData);
+}
+
+const RecordId
+DbModifier::updateRecord(Table::Id inTableId, const RecordId &inRecordId,
+						 const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+						 const CssmData *inData,
+						 CSSM_DB_MODIFY_MODE inModifyMode)
+{
+	commit(); // XXX this is not thread safe, but what is?
+	modifyDatabase();
+	return findTable(inTableId).updateRecord(inRecordId, inAttributes, inData, inModifyMode);
+}
+
+// Create a table associated with a given metarecord, and add the table
+// to the database.
+
+ModifiedTable *
+DbModifier::createTable(MetaRecord *inMetaRecord)
+{
+	auto_ptr<MetaRecord> aMetaRecord(inMetaRecord);
+	auto_ptr<ModifiedTable> aModifiedTable(new ModifiedTable(inMetaRecord));
+	// Now that aModifiedTable is fully constructed it owns inMetaRecord
+	aMetaRecord.release();
+
+	if (!mModifiedTableMap.insert
+		(ModifiedTableMap::value_type(inMetaRecord->dataRecordType(),
+									  aModifiedTable.get())).second)
+	{
+		// XXX Should be CSSMERR_DL_DUPLICATE_RECORDTYPE.  Since that
+		// doesn't exist we report that the metatable's unique index would
+		// no longer be valid
+        CssmError::throwMe(CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA);
+	}
+
+	return aModifiedTable.release();
+}
+
+void
+DbModifier::deleteTable(Table::Id inTableId)
+{
+	modifyDatabase();
+    // Can't delete schema tables.
+    if (CSSM_DB_RECORDTYPE_SCHEMA_START <= inTableId
+		&& inTableId < CSSM_DB_RECORDTYPE_SCHEMA_END)
+        CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
+
+	// Find the ModifiedTable and delete it
+    ModifiedTableMap::iterator it = mModifiedTableMap.find(inTableId);
+    if (it == mModifiedTableMap.end())
+        CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
+
+    delete it->second;
+    mModifiedTableMap.erase(it);
+}
+
+uint32
+DbModifier::writeAuthSection(uint32 inSectionOffset)
+{
+	WriteSection anAuthSection;
+
+    // XXX Put real data into the authsection.
+	uint32 anOffset = anAuthSection.put(0, 0);
+	anAuthSection.size(anOffset);
+
+	mAtomicFile.write(AtomicFile::FromStart, inSectionOffset,
+					  anAuthSection.address(), anAuthSection.size());
+    return inSectionOffset + anOffset;
+}
+
+uint32
+DbModifier::writeSchemaSection(uint32 inSectionOffset)
+{
+	uint32 aTableCount = mModifiedTableMap.size();
+	WriteSection aTableSection(CssmAllocator::standard(),
+							   OffsetTables + AtomSize * aTableCount);
+	// Set aTableSection to the correct size.
+	aTableSection.size(OffsetTables + AtomSize * aTableCount);
+	aTableSection.put(OffsetTablesCount, aTableCount);
+
+	uint32 anOffset = inSectionOffset + OffsetTables + AtomSize * aTableCount;
+	ModifiedTableMap::const_iterator anIt = mModifiedTableMap.begin();
+	ModifiedTableMap::const_iterator anEnd = mModifiedTableMap.end();
+	for (uint32 aTableNumber = 0; anIt != anEnd; anIt++, aTableNumber++)
+	{
+		// Put the offset to the current table relative to the start of
+		// this section into the tables array
+		aTableSection.put(OffsetTables + AtomSize * aTableNumber,
+						  anOffset - inSectionOffset);
+		anOffset = anIt->second->writeTable(mAtomicFile, anOffset);
+	}
+
+	aTableSection.put(OffsetSchemaSize, anOffset - inSectionOffset);
+	mAtomicFile.write(AtomicFile::FromStart, inSectionOffset,
+					  aTableSection.address(), aTableSection.size());
+
+	return anOffset;
+}
+
+void
+DbModifier::commit()
+{
+    if (!mWriting)
+        return;
+    try
+    {
+		WriteSection aHeaderSection(CssmAllocator::standard(), HeaderSize);
+		// Set aHeaderSection to the correct size.
+		aHeaderSection.size(HeaderSize);
+
+        // Start writing sections after the header
+        uint32 anOffset = HeaderOffset + HeaderSize;
+
+        // Write auth section
+		aHeaderSection.put(OffsetAuthOffset, anOffset);
+        anOffset = writeAuthSection(anOffset);
+        // Write schema section
+		aHeaderSection.put(OffsetSchemaOffset, anOffset);
+        anOffset = writeSchemaSection(anOffset);
+
+		// Write out the file header.
+		aHeaderSection.put(OffsetMagic, HeaderMagic);
+		aHeaderSection.put(OffsetVersion, HeaderVersion);
+        mAtomicFile.write(AtomicFile::FromStart, HeaderOffset,
+						  aHeaderSection.address(), aHeaderSection.size());
+    }
+    catch(...)
+    {
+        try
+        {
+            rollback(); // Sets mWriting to false;
+        }
+        catch(...) {}
+		throw;
+    }
+
+    mWriting = false;
+    mAtomicFile.commit();
+}
+
+void
+DbModifier::rollback()
+{
+    if (mWriting)
+    {
+        mWriting = false;
+        mAtomicFile.rollback();
+    }
+}
+
+const RecordId
+DbModifier::getRecord(Table::Id inTableId, const RecordId &inRecordId,
+					  CSSM_DB_RECORD_ATTRIBUTE_DATA *inoutAttributes,
+					  CssmData *inoutData, CssmAllocator &inAllocator)
+{
+	// XXX never call commit(), rather search our own record tables.
+	commit(); // XXX Requires write lock.
+	return getDbVersion()->getRecord(inTableId, inRecordId,
+									 inoutAttributes, inoutData, inAllocator);
+}
+
+Cursor *
+DbModifier::createCursor(const CSSM_QUERY *inQuery)
+{
+	// XXX Be smarter as to when we must call commit (i.e. don't
+	// force commit if the table being queried has not been modified).
+	commit(); // XXX Requires write lock.
+	return getDbVersion()->createCursor(inQuery);
+}
+
+// Insert schema records for a new table into the metatables of the database. This gets
+// called while a database is being created.
+
+void
+DbModifier::insertTableSchema(const CssmDbRecordAttributeInfo &inInfo,
+	const CSSM_DB_RECORD_INDEX_INFO *inIndexInfo /* = NULL */)
+{
+	ModifiedTable &aTable = findTable(inInfo.DataRecordType);
+	const MetaRecord &aMetaRecord = aTable.getMetaRecord();
+
+	CssmAutoDbRecordAttributeData aRecordBuilder(5); // Set capacity to 5 so we don't need to grow
+
+	// Create the entry for the SchemaRelations table.
+	aRecordBuilder.add(RelationID, inInfo.recordType());
+	aRecordBuilder.add(RelationName, mDb.recordName(inInfo.recordType()));
+
+	// Insert the record into the SchemaRelations ModifiedTable
+    findTable(mDb.schemaRelations.DataRecordType).insertRecord(mVersionId,
+		&aRecordBuilder, NULL);
+	
+	ModifiedTable &anAttributeTable = findTable(mDb.schemaAttributes.DataRecordType);
+    for (uint32 anIndex = 0; anIndex < inInfo.size(); anIndex++)
+    {
+		// Create an entry for the SchemaAttributes table.
+		aRecordBuilder.clear();
+		aRecordBuilder.add(RelationID, inInfo.recordType());
+		aRecordBuilder.add(AttributeNameFormat, inInfo.at(anIndex).nameFormat());
+
+		uint32 attributeId = aMetaRecord.metaAttribute(inInfo.at(anIndex)).attributeId();
+		
+        switch (inInfo.at(anIndex).nameFormat())
+        {
+            case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
+				aRecordBuilder.add(AttributeName, inInfo.at(anIndex).Label.AttributeName);
+				break;
+            case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
+				aRecordBuilder.add(AttributeNameID, inInfo.at(anIndex).Label.AttributeOID);
+				break;
+            case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
+                break;
+            default:
+                CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
+		}
+
+		aRecordBuilder.add(AttributeID, attributeId);
+		aRecordBuilder.add(AttributeFormat, inInfo.at(anIndex).format());
+
+		// Insert the record into the SchemaAttributes ModifiedTable
+		anAttributeTable.insertRecord(mVersionId, &aRecordBuilder, NULL);
+    }
+
+	if (inIndexInfo != NULL) {
+	
+		if (inIndexInfo->DataRecordType != inInfo.DataRecordType &&
+			inIndexInfo->NumberOfIndexes > 0)
+			CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
+	
+		ModifiedTable &indexMetaTable = findTable(mDb.schemaIndexes.DataRecordType);
+		uint32 aNumberOfIndexes = inIndexInfo->NumberOfIndexes;
+		
+		for (uint32 anIndex = 0; anIndex < aNumberOfIndexes; anIndex++)
+		{
+			const CssmDbIndexInfo &thisIndex = CssmDbIndexInfo::overlay(inIndexInfo->IndexInfo[anIndex]);
+			
+			// make sure the index is supported
+			if (thisIndex.dataLocation() != CSSM_DB_INDEX_ON_ATTRIBUTE)
+				CssmError::throwMe(CSSMERR_DL_INVALID_INDEX_INFO);
+			
+			// assign an index ID: the unique index is ID 0, all others are ID > 0
+			uint32 indexId;
+			if (thisIndex.IndexType == CSSM_DB_INDEX_UNIQUE)
+				indexId = 0;
+			else
+				indexId = anIndex + 1;
+				
+			// figure out the attribute ID
+			uint32 attributeId =
+				aMetaRecord.metaAttribute(thisIndex.Info).attributeId();
+			
+			// Create an entry for the SchemaIndexes table.
+			aRecordBuilder.clear();
+			aRecordBuilder.add(RelationID, inInfo.DataRecordType);
+			aRecordBuilder.add(IndexID, indexId);
+			aRecordBuilder.add(AttributeID, attributeId);
+			aRecordBuilder.add(IndexType, thisIndex.IndexType);
+			aRecordBuilder.add(IndexedDataLocation, thisIndex.IndexedDataLocation);
+
+			// Insert the record into the SchemaIndexes ModifiedTable
+			indexMetaTable.insertRecord(mVersionId, &aRecordBuilder, NULL);
+			
+			// update the table's index objects
+			DbMutableIndex &index = aTable.findIndex(indexId, aMetaRecord, indexId == 0);
+			index.appendAttribute(attributeId);
+		}
+	}
+}
+
+// Insert a new table. The attribute info is required; the index and parsing module
+// descriptions are optional. This version gets called during the creation of a
+// database.
+
+void
+DbModifier::insertTable(const CssmDbRecordAttributeInfo &inInfo,
+						const CSSM_DB_RECORD_INDEX_INFO *inIndexInfo /* = NULL */,
+						const CSSM_DB_PARSING_MODULE_INFO *inParsingModule /* = NULL */)
+{
+	modifyDatabase();
+	createTable(new MetaRecord(inInfo));
+	insertTableSchema(inInfo, inIndexInfo);
+}
+
+// Insert a new table. This is the version that gets called when a table is added
+// after a database has been created.
+
+void
+DbModifier::insertTable(Table::Id inTableId, const string &inTableName,
+						uint32 inNumberOfAttributes,
+						const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo,
+						uint32 inNumberOfIndexes,
+						const CSSM_DB_SCHEMA_INDEX_INFO *inIndexInfo)
+{
+	modifyDatabase();
+	ModifiedTable *aTable = createTable(new MetaRecord(inTableId, inNumberOfAttributes, inAttributeInfo));
+
+	CssmAutoDbRecordAttributeData aRecordBuilder(6); // Set capacity to 6 so we don't need to grow
+
+	// Create the entry for the SchemaRelations table.
+	aRecordBuilder.add(RelationID, inTableId);
+	aRecordBuilder.add(RelationName, inTableName);
+
+	// Insert the record into the SchemaRelations ModifiedTable
+    findTable(mDb.schemaRelations.DataRecordType).insertRecord(mVersionId,
+		&aRecordBuilder, NULL);
+
+	ModifiedTable &anAttributeTable = findTable(mDb.schemaAttributes.DataRecordType);
+    for (uint32 anIndex = 0; anIndex < inNumberOfAttributes; anIndex++)
+    {
+		// Create an entry for the SchemaAttributes table.
+		aRecordBuilder.clear();
+		aRecordBuilder.add(RelationID, inTableId);
+		// XXX What should this be?  We set it to CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER for now
+		// since the AttributeID is always valid.
+		aRecordBuilder.add(AttributeNameFormat, uint32(CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER));
+		aRecordBuilder.add(AttributeID, inAttributeInfo[anIndex].AttributeId);
+		if (inAttributeInfo[anIndex].AttributeName)
+			aRecordBuilder.add(AttributeName, inAttributeInfo[anIndex].AttributeName);
+		if (inAttributeInfo[anIndex].AttributeNameID.Length > 0)
+			aRecordBuilder.add(AttributeNameID, inAttributeInfo[anIndex].AttributeNameID);
+		aRecordBuilder.add(AttributeFormat, inAttributeInfo[anIndex].DataType);
+
+		// Insert the record into the SchemaAttributes ModifiedTable
+		anAttributeTable.insertRecord(mVersionId, &aRecordBuilder, NULL);
+    }
+
+	ModifiedTable &anIndexTable = findTable(mDb.schemaIndexes.DataRecordType);
+    for (uint32 anIndex = 0; anIndex < inNumberOfIndexes; anIndex++)
+    {
+		// Create an entry for the SchemaIndexes table.
+		aRecordBuilder.clear();
+		aRecordBuilder.add(RelationID, inTableId);
+		aRecordBuilder.add(IndexID, inIndexInfo[anIndex].IndexId);
+		aRecordBuilder.add(AttributeID, inIndexInfo[anIndex].AttributeId);
+		aRecordBuilder.add(IndexType, inIndexInfo[anIndex].IndexType);
+		aRecordBuilder.add(IndexedDataLocation, inIndexInfo[anIndex].IndexedDataLocation);
+
+		// Insert the record into the SchemaIndexes ModifiedTable
+		anIndexTable.insertRecord(mVersionId, &aRecordBuilder, NULL);
+		
+		// update the table's index objects
+		DbMutableIndex &index = aTable->findIndex(inIndexInfo[anIndex].IndexId,
+			aTable->getMetaRecord(), inIndexInfo[anIndex].IndexType == CSSM_DB_INDEX_UNIQUE);
+		index.appendAttribute(inIndexInfo[anIndex].AttributeId);
+    }
+}
+
+ModifiedTable &
+DbModifier::findTable(Table::Id inTableId)
+{
+    ModifiedTableMap::iterator it = mModifiedTableMap.find(inTableId);
+    if (it == mModifiedTableMap.end())
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
+	return *it->second;
+}
+
+
+//
+// AppleDatabaseManager implementation
+//
+
+AppleDatabaseManager::AppleDatabaseManager(const AppleDatabaseTableName *tableNames)
+	:	DatabaseManager(),
+		mTableNames(tableNames)
+{
+	// make sure that a proper set of table ids and names has been provided
+	
+	if (!mTableNames)
+		CssmError::throwMe(CSSMERR_DL_INTERNAL_ERROR);
+	else {
+		uint32 i;
+		for (i = 0; mTableNames[i].mTableName; i++) {}
+		if (i < AppleDatabaseTableName::kNumRequiredTableNames)
+			CssmError::throwMe(CSSMERR_DL_INTERNAL_ERROR);
+	}
+}
+
+Database *
+AppleDatabaseManager::make(const DbName &inDbName)
+{
+    return new AppleDatabase(inDbName, mTableNames);
+}
+
+//
+// AppleDbContext implementation
+//
+AppleDbContext::AppleDbContext(Database &inDatabase,
+							   DatabaseSession &inDatabaseSession,
+							   CSSM_DB_ACCESS_TYPE inAccessRequest,
+							   const AccessCredentials *inAccessCred,
+							   const void *inOpenParameters) :
+	DbContext(inDatabase, inDatabaseSession, inAccessRequest, inAccessCred)
+{
+	const CSSM_APPLEDL_OPEN_PARAMETERS *anOpenParameters =
+		reinterpret_cast<const CSSM_APPLEDL_OPEN_PARAMETERS *>(inOpenParameters);
+	if (anOpenParameters)
+	{
+		if (anOpenParameters->length < sizeof(CSSM_APPLEDL_OPEN_PARAMETERS)
+			|| anOpenParameters->version != 0)
+			CssmError::throwMe(CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS);
+
+		mAutoCommit = anOpenParameters->autoCommit == CSSM_FALSE ? false : true;
+	}
+	else
+		mAutoCommit = true;
+}
+
+AppleDbContext::~AppleDbContext()
+{
+}
+
+//
+// AppleDatabase implementation
+//
+AppleDatabase::AppleDatabase(const DbName &inDbName, const AppleDatabaseTableName *tableNames) :
+    Database(inDbName),
+	schemaRelations(tableNames[AppleDatabaseTableName::kSchemaInfo].mTableId,
+		sizeof(AttrSchemaRelations) / sizeof(CSSM_DB_ATTRIBUTE_INFO),
+		const_cast<CSSM_DB_ATTRIBUTE_INFO_PTR>(AttrSchemaRelations)),
+	schemaAttributes(tableNames[AppleDatabaseTableName::kSchemaAttributes].mTableId,
+		sizeof(AttrSchemaAttributes) / sizeof(CSSM_DB_ATTRIBUTE_INFO),
+		const_cast<CSSM_DB_ATTRIBUTE_INFO_PTR>(AttrSchemaAttributes)),
+	schemaIndexes(tableNames[AppleDatabaseTableName::kSchemaIndexes].mTableId,
+		sizeof(AttrSchemaIndexes) / sizeof(CSSM_DB_ATTRIBUTE_INFO),
+		const_cast<CSSM_DB_ATTRIBUTE_INFO_PTR>(AttrSchemaIndexes)),
+	schemaParsingModule(tableNames[AppleDatabaseTableName::kSchemaParsingModule].mTableId,
+		sizeof(AttrSchemaParsingModule) / sizeof(CSSM_DB_ATTRIBUTE_INFO),
+		const_cast<CSSM_DB_ATTRIBUTE_INFO_PTR>(AttrSchemaParsingModule)),
+    mAtomicFile(mDbName),
+	mDbModifier(mAtomicFile, *this),
+	mTableNames(tableNames)
+{
+}
+
+AppleDatabase::~AppleDatabase()
+{
+}
+
+// Return the name of a record type. This uses a table that maps record types
+// to record names. The table is provided when the database is created.
+
+const char *AppleDatabase::recordName(CSSM_DB_RECORDTYPE inRecordType) const
+{
+	if (inRecordType == CSSM_DL_DB_RECORD_ANY || inRecordType == CSSM_DL_DB_RECORD_ALL_KEYS)
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
+		
+	for (uint32 i = 0; mTableNames[i].mTableName; i++)
+		if (mTableNames[i].mTableId == inRecordType)
+			return mTableNames[i].mTableName;
+			
+	return "";
+}
+
+DbContext *
+AppleDatabase::makeDbContext(DatabaseSession &inDatabaseSession,
+                             CSSM_DB_ACCESS_TYPE inAccessRequest,
+                             const AccessCredentials *inAccessCred,
+                             const void *inOpenParameters)
+{
+    return new AppleDbContext(*this, inDatabaseSession, inAccessRequest,
+							  inAccessCred, inOpenParameters);
+}
+
+void
+AppleDatabase::dbCreate(DbContext &inDbContext, const CSSM_DBINFO &inDBInfo,
+                        const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry)
+{
+    try
+    {
+		StLock<Mutex> _(mWriteLock);
+        mDbModifier.createDatabase(inDBInfo, inInitialAclEntry);
+    }
+    catch(...)
+    {
+        mDbModifier.rollback();
+        throw;
+    }
+	if (safer_cast<AppleDbContext &>(inDbContext).autoCommit())
+		mDbModifier.commit();
+}
+
+void
+AppleDatabase::dbOpen(DbContext &inDbContext)
+{
+	mDbModifier.openDatabase();
+}
+
+void
+AppleDatabase::dbClose()
+{
+	StLock<Mutex> _(mWriteLock);
+	mDbModifier.closeDatabase();
+}
+
+void
+AppleDatabase::dbDelete(DatabaseSession &inDatabaseSession,
+                        const AccessCredentials *inAccessCred)
+{
+	StLock<Mutex> _(mWriteLock);
+    // XXX Check callers credentials.
+	mDbModifier.deleteDatabase();
+}
+
+void
+AppleDatabase::createRelation(DbContext &inDbContext,
+                              CSSM_DB_RECORDTYPE inRelationID,
+                              const char *inRelationName,
+                              uint32 inNumberOfAttributes,
+                              const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
+                              uint32 inNumberOfIndexes,
+                              const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo)
+{
+	try
+	{
+		StLock<Mutex> _(mWriteLock);
+		// XXX Fix the refs here.
+		mDbModifier.insertTable(inRelationID, inRelationName,
+								inNumberOfAttributes, &inAttributeInfo,
+								inNumberOfIndexes, &inIndexInfo);
+	}
+	catch(...)
+	{
+		mDbModifier.rollback();
+		throw;
+	}
+	if (safer_cast<AppleDbContext &>(inDbContext).autoCommit())
+		mDbModifier.commit();
+}
+
+void
+AppleDatabase::destroyRelation(DbContext &inDbContext,
+                               CSSM_DB_RECORDTYPE inRelationID)
+{
+	try
+	{
+		StLock<Mutex> _(mWriteLock);
+		mDbModifier.deleteTable(inRelationID);
+	}
+	catch(...)
+	{
+		mDbModifier.rollback();
+		throw;
+	}
+	if (safer_cast<AppleDbContext &>(inDbContext).autoCommit())
+		mDbModifier.commit();
+}
+
+void
+AppleDatabase::authenticate(DbContext &inDbContext,
+                            CSSM_DB_ACCESS_TYPE inAccessRequest,
+                            const AccessCredentials &inAccessCred)
+{
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+AppleDatabase::getDbAcl(DbContext &inDbContext,
+                        const CSSM_STRING *inSelectionTag,
+                        uint32 &outNumberOfAclInfos,
+                        CSSM_ACL_ENTRY_INFO_PTR &outAclInfos)
+{
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+AppleDatabase::changeDbAcl(DbContext &inDbContext,
+                           const AccessCredentials &inAccessCred,
+                           const CSSM_ACL_EDIT &inAclEdit)
+{
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+AppleDatabase::getDbOwner(DbContext &inDbContext,
+						  CSSM_ACL_OWNER_PROTOTYPE &outOwner)
+{
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+AppleDatabase::changeDbOwner(DbContext &inDbContext,
+                             const AccessCredentials &inAccessCred,
+                             const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner)
+{
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+char *
+AppleDatabase::getDbNameFromHandle(const DbContext &inDbContext) const
+{
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+CSSM_DB_UNIQUE_RECORD_PTR
+AppleDatabase::dataInsert(DbContext &inDbContext,
+                          CSSM_DB_RECORDTYPE inRecordType,
+                          const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+                          const CssmData *inData)
+{
+	CSSM_DB_UNIQUE_RECORD_PTR anUniqueRecordPtr = NULL;
+	try
+	{
+		StLock<Mutex> _(mWriteLock);
+		const RecordId aRecordId =
+			mDbModifier.insertRecord(inRecordType, inAttributes, inData);
+
+		anUniqueRecordPtr = createUniqueRecord(inDbContext, inRecordType,
+											   aRecordId);
+		if (safer_cast<AppleDbContext &>(inDbContext).autoCommit())
+			mDbModifier.commit();
+	}
+	catch(...)
+	{
+		if (anUniqueRecordPtr != NULL)
+			freeUniqueRecord(inDbContext, *anUniqueRecordPtr);
+
+		mDbModifier.rollback();
+		throw;
+	}
+
+	return anUniqueRecordPtr;
+}
+
+void
+AppleDatabase::dataDelete(DbContext &inDbContext,
+                          const CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
+{
+    try
+    {
+		StLock<Mutex> _(mWriteLock);
+		Table::Id aTableId;
+		const RecordId aRecordId(parseUniqueRecord(inUniqueRecord, aTableId));
+		mDbModifier.deleteRecord(aTableId, aRecordId);
+	}
+    catch(...)
+    {
+        mDbModifier.rollback();
+        throw;
+    }
+
+	if (safer_cast<AppleDbContext &>(inDbContext).autoCommit())
+		mDbModifier.commit();
+}
+
+void
+AppleDatabase::dataModify(DbContext &inDbContext,
+                          CSSM_DB_RECORDTYPE inRecordType,
+                          CSSM_DB_UNIQUE_RECORD &inoutUniqueRecord,
+                          const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
+                          const CssmData *inDataToBeModified,
+                          CSSM_DB_MODIFY_MODE inModifyMode)
+{
+    try
+    {
+		StLock<Mutex> _(mWriteLock);
+		Table::Id aTableId;
+		const RecordId aRecordId =
+			mDbModifier.updateRecord(aTableId,
+									 parseUniqueRecord(inoutUniqueRecord, aTableId),
+									 inAttributesToBeModified,
+									 inDataToBeModified,
+									 inModifyMode);
+		updateUniqueRecord(inDbContext, inRecordType, aRecordId, inoutUniqueRecord);
+	}
+    catch(...)
+    {
+        mDbModifier.rollback();
+        throw;
+    }
+
+	if (safer_cast<AppleDbContext &>(inDbContext).autoCommit())
+		mDbModifier.commit();
+}
+
+CSSM_HANDLE
+AppleDatabase::dataGetFirst(DbContext &inDbContext,
+                            const DLQuery *inQuery,
+                            CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                            CssmData *inoutData,
+                            CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
+{
+	// XXX: register Cursor with DbContext and have DbContext call
+	// dataAbortQuery for all outstanding Query objects on close.
+	auto_ptr<Cursor> aCursor(mDbModifier.createCursor(inQuery));
+	Table::Id aTableId;
+	RecordId aRecordId;
+	
+	if (!aCursor->next(aTableId, inoutAttributes, inoutData,
+					   inDbContext.mDatabaseSession, aRecordId))
+		// return a NULL handle, and implicitly delete the cursor
+		return NULL;
+
+	outUniqueRecord = createUniqueRecord(inDbContext, aTableId, aRecordId);
+	return aCursor.release()->handle(); // We didn't throw so keep the Cursor around.
+}
+
+bool
+AppleDatabase::dataGetNext(DbContext &inDbContext,
+                           CSSM_HANDLE inResultsHandle,
+                           CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                           CssmData *inoutData,
+                           CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
+{
+	auto_ptr<Cursor> aCursor(&findHandle<Cursor>(inResultsHandle, CSSMERR_DL_INVALID_RESULTS_HANDLE));
+	Table::Id aTableId;
+	RecordId aRecordId;
+	
+	if (!aCursor->next(aTableId, inoutAttributes, inoutData, inDbContext.mDatabaseSession, aRecordId))
+		return false;
+
+	outUniqueRecord = createUniqueRecord(inDbContext, aTableId, aRecordId);
+
+	aCursor.release();
+	return true;
+}
+
+void
+AppleDatabase::dataAbortQuery(DbContext &inDbContext,
+                              CSSM_HANDLE inResultsHandle)
+{
+	delete &findHandle<Cursor>(inResultsHandle, CSSMERR_DL_INVALID_RESULTS_HANDLE);
+}
+
+void
+AppleDatabase::dataGetFromUniqueRecordId(DbContext &inDbContext,
+                                         const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
+                                         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                                         CssmData *inoutData)
+{
+	Table::Id aTableId;
+	const RecordId aRecordId(parseUniqueRecord(inUniqueRecord, aTableId));
+	// XXX Change CDSA spec to use new RecordId returned by this function
+	mDbModifier.getRecord(aTableId, aRecordId, inoutAttributes, inoutData,
+						  inDbContext.mDatabaseSession);
+}
+
+void
+AppleDatabase::freeUniqueRecord(DbContext &inDbContext,
+                                CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
+{
+	if (inUniqueRecord.RecordIdentifier.Length != 0
+		&& inUniqueRecord.RecordIdentifier.Data != NULL)
+	{
+		inUniqueRecord.RecordIdentifier.Length = 0;
+		inDbContext.mDatabaseSession.free(inUniqueRecord.RecordIdentifier.Data);
+	}
+	inDbContext.mDatabaseSession.free(&inUniqueRecord);
+}
+
+void
+AppleDatabase::updateUniqueRecord(DbContext &inDbContext,
+								  CSSM_DB_RECORDTYPE inTableId,
+								  const RecordId &inRecordId,
+								  CSSM_DB_UNIQUE_RECORD &inoutUniqueRecord)
+{
+	uint32 *aBuffer = reinterpret_cast<uint32 *>(inoutUniqueRecord.RecordIdentifier.Data);
+	aBuffer[0] = inTableId;
+	aBuffer[1] = inRecordId.mRecordNumber;
+	aBuffer[2] = inRecordId.mCreateVersion;
+	aBuffer[3] = inRecordId.mRecordVersion;
+}
+
+CSSM_DB_UNIQUE_RECORD_PTR
+AppleDatabase::createUniqueRecord(DbContext &inDbContext,
+								  CSSM_DB_RECORDTYPE inTableId,
+								  const RecordId &inRecordId)
+{
+	CSSM_DB_UNIQUE_RECORD_PTR aUniqueRecord =
+		inDbContext.mDatabaseSession.alloc<CSSM_DB_UNIQUE_RECORD>();
+	memset(aUniqueRecord, 0, sizeof(*aUniqueRecord));
+	aUniqueRecord->RecordIdentifier.Length = sizeof(uint32) * 4;
+	try
+	{
+		aUniqueRecord->RecordIdentifier.Data =
+			inDbContext.mDatabaseSession.alloc<uint8>(sizeof(uint32) * 4);
+		updateUniqueRecord(inDbContext, inTableId, inRecordId, *aUniqueRecord);
+	}
+	catch(...)
+	{
+		inDbContext.mDatabaseSession.free(aUniqueRecord);
+		throw;
+	}
+
+	return aUniqueRecord;
+}
+
+const RecordId
+AppleDatabase::parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
+								 CSSM_DB_RECORDTYPE &outTableId)
+{
+	if (inUniqueRecord.RecordIdentifier.Length != sizeof(uint32) * 4)
+		CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
+
+	uint32 *aBuffer = reinterpret_cast<uint32 *>(inUniqueRecord.RecordIdentifier.Data);
+	outTableId = aBuffer[0];
+	return RecordId(aBuffer[1], aBuffer[2], aBuffer[3]);
+}
+
+void
+AppleDatabase::passThrough(DbContext &dbContext,
+						   uint32 passThroughId,
+						   const void *inputParams,
+						   void **outputParams)
+{
+	switch (passThroughId)
+	{
+	case CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT:
+		{
+			CSSM_BOOL on = reinterpret_cast<CSSM_BOOL>(inputParams);
+			safer_cast<AppleDbContext &>(dbContext).autoCommit(on);
+		}
+		break;
+		
+	case CSSM_APPLEFILEDL_COMMIT:
+		mDbModifier.commit();
+		break;
+		
+	case CSSM_APPLEFILEDL_ROLLBACK:
+		mDbModifier.rollback();
+		break;
+	
+	default:
+		CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+		break;
+	}
+}
+
+
diff --git a/cdsa/cdsa_utilities/AppleDatabase.h b/cdsa/cdsa_utilities/AppleDatabase.h
new file mode 100644
index 00000000..5151ecb7
--- /dev/null
+++ b/cdsa/cdsa_utilities/AppleDatabase.h
@@ -0,0 +1,662 @@
+/*
+ * 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.
+ */
+
+
+//
+//  AppleDatabase.h - Description t.b.d.
+//
+#ifndef _H_APPLEDATABASE
+#define _H_APPLEDATABASE
+
+#include "MetaRecord.h"
+#include "SelectionPredicate.h"
+#include "DbIndex.h"
+
+#include <Security/AtomicFile.h>
+#include <Security/Database.h>
+#include <Security/DbContext.h>
+#include <Security/handleobject.h>
+#include <Security/refcount.h>
+#include <memory>
+#include <vector>
+
+namespace Security
+{
+
+// Abstract database Cursor class.
+class Cursor;
+class DbVersion;
+class CssmAutoQuery;
+
+struct AppleDatabaseTableName
+{
+	uint32 mTableId;
+	const char *mTableName;
+	
+	// indices of meta-table entries in an array of table names
+
+	enum {
+		kSchemaInfo = 0,
+		kSchemaAttributes,
+		kSchemaIndexes,
+		kSchemaParsingModule,
+		kNumRequiredTableNames
+	};
+};
+
+//
+// This is what the CDSA standard refers to as a Relation.  We use
+// the more conventional term Table.
+//
+class Table
+{
+	NOCOPY(Table)
+public:
+	// Type used to refer to a table.
+	typedef CSSM_DB_RECORDTYPE Id;
+
+    Table(const ReadSection &inTableSection);
+	~Table();
+#if 0
+    Table(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo) :
+		mMetaRecord (inInfo) {}
+    Table(Id inTableId, const string &inTableName,
+		  uint32 inNumberOfAttributes,
+		  const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo,
+		  uint32 inNumberOfIndexes, 
+		  const CSSM_DB_SCHEMA_INDEX_INFO *inIndexInfo) :
+		mMetaRecord(inTableId, inTableName,
+				    inNumberOfAttributes, inAttributeInfo)
+		{ /* XXX Use inIndexInfo */ }
+#endif
+
+	// Return a newly created cursor satisfying inQuery on the receiving table
+	// The returned Cursor may or may not use indexes depending on their availability.
+	Cursor *createCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion) const;
+
+	const ReadSection getRecordSection(uint32 inRecordNumber) const;
+
+	const RecordId getRecord(const RecordId &inRecordId,
+							 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+							 CssmData *inoutData,
+							 CssmAllocator &inAllocator) const;
+
+	// Return the number of recordNumbers in use by this table including empty slots.
+    uint32 recordNumberCount() const { return mRecordNumbersCount; }
+    uint32 freeListHead() const { return mFreeListHead; }
+
+	// Return the record number corresponding to aFreeListHead and update
+	// aFreeListHead to point to the next availble recordNumber slot.
+	uint32 popFreeList(uint32 &aFreeListHead) const;
+
+	MetaRecord &getMetaRecord() { return mMetaRecord; }
+	const MetaRecord &getMetaRecord() const { return mMetaRecord; }
+
+	uint32 getRecordsCount() const { return mRecordsCount; }
+	const ReadSection getRecordsSection() const;
+	
+	const ReadSection &getTableSection() const { return mTableSection; }
+
+	bool matchesTableId(Id inTableId) const;
+
+	void readIndexSection();
+	
+	enum
+	{
+		OffsetSize					= AtomSize * 0,
+		OffsetId					= AtomSize * 1,
+		OffsetRecordsCount			= AtomSize * 2,
+		OffsetRecords				= AtomSize * 3,
+		OffsetIndexesOffset			= AtomSize * 4,
+		OffsetFreeListHead			= AtomSize * 5,
+		OffsetRecordNumbersCount	= AtomSize * 6,
+		OffsetRecordNumbers			= AtomSize * 7
+	};
+protected:
+	friend class ModifiedTable;
+	
+	MetaRecord mMetaRecord;
+	const ReadSection mTableSection;
+
+	uint32 mRecordsCount;
+	uint32 mFreeListHead;
+	// Number of record numbers (including freelist slots) in this table.
+	uint32 mRecordNumbersCount;
+
+	// all the table's indexes, mapped by index id
+	typedef map<uint32, DbConstIndex *> ConstIndexMap;
+	ConstIndexMap mIndexMap;
+};
+
+class ModifiedTable
+{
+	NOCOPY(ModifiedTable)
+public:
+	ModifiedTable(const Table *inTable);
+	ModifiedTable(MetaRecord *inMetaRecord); // Take over ownership of inMetaRecord
+	~ModifiedTable();
+
+	// Mark the record with inRecordId as deleted.
+    void deleteRecord(const RecordId &inRecordId);
+    const RecordId insertRecord(AtomicFile::VersionId inVersionId,
+								const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+								const CssmData *inData);
+    const RecordId updateRecord(const RecordId &inRecordId,
+								const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+								const CssmData *inData,
+								CSSM_DB_MODIFY_MODE inModifyMode);
+
+	// Return the MetaRecord this table should use for writes.
+	const MetaRecord &getMetaRecord() const;
+
+	// find, and create if needed, an index with the given id
+	DbMutableIndex &findIndex(uint32 indexId, const MetaRecord &metaRecord, bool isUniqueIndex);
+
+	// Write this table to inOutputFile at inSectionOffset and return the new offset.
+    uint32 writeTable(AtomicFile &inOutputFile, uint32 inSectionOffset);
+
+private:
+	// Return the next available record number for this table.
+    uint32 nextRecordNumber();
+
+	// Return the number of recordNumbers in use by this table including empty slots.
+    uint32 recordNumberCount() const;
+
+	void modifyTable();
+	void createMutableIndexes();
+	uint32 writeIndexSection(WriteSection &tableSection, uint32 offset);
+
+	// Optional, this is merly a reference, we do not own this object.
+	const Table *mTable;
+	
+	// Optional, New MetaRecord.  This is only present if it is different from the
+	// MetaRecord of mTable or mTable is nil.
+	const MetaRecord *mNewMetaRecord;
+
+	// Set of Records that have been deleted or modified.
+    typedef set<uint32> DeletedSet;
+    DeletedSet mDeletedSet;
+
+	// Set of Records that have been inserted or modified.
+    typedef map<uint32, WriteSection *> InsertedMap;
+    InsertedMap mInsertedMap;
+
+	// Next lowest available RecordNumber
+    uint32 mRecordNumberCount;
+	// Head of the free list (if there is one) or 0 if either we have no
+	// mTable of the free list has been exhausted.
+    uint32 mFreeListHead;
+	
+	// has this table actually been modified?
+	bool mIsModified;
+
+	typedef map<uint32, DbMutableIndex *> MutableIndexMap;
+	MutableIndexMap mIndexMap;
+};
+
+//
+// Read only snapshot of a database.
+//
+class Metadata
+{
+	NOCOPY(Metadata)
+protected:
+	Metadata() {}
+    enum
+    {
+		HeaderOffset		= 0,	// Absolute offset of header.
+		OffsetMagic			= AtomSize * 0,
+		OffsetVersion		= AtomSize * 1,
+		OffsetAuthOffset	= AtomSize * 2,
+		OffsetSchemaOffset	= AtomSize * 3,
+        HeaderSize			= AtomSize * 4,
+
+        HeaderMagic			= FOUR_CHAR_CODE('kych'),
+        HeaderVersion		= 0x00010000
+    };
+
+	enum
+	{
+		OffsetSchemaSize	= AtomSize * 0,
+		OffsetTablesCount	= AtomSize * 1,
+		OffsetTables		= AtomSize * 2
+	};
+};
+
+//
+// Read only representation of a database
+//
+class DbVersion : public Metadata, public RefCount
+{
+	NOCOPY(DbVersion)
+public:
+    DbVersion(AtomicFile &inDatabaseFile, const class AppleDatabase &db);
+    ~DbVersion();
+
+    // Return true if the file on which this DbVersion is based
+	// has been modified.
+    bool isDirty() const;
+
+	AtomicFile::VersionId getVersionId() const { return mVersionId; }
+	const RecordId getRecord(Table::Id inTableId, const RecordId &inRecordId,
+							 CSSM_DB_RECORD_ATTRIBUTE_DATA *inoutAttributes,
+							 CssmData *inoutData, CssmAllocator &inAllocator) const;
+	Cursor *createCursor(const CSSM_QUERY *inQuery) const;
+protected:
+	const Table &findTable(Table::Id inTableId) const;
+	Table &findTable(Table::Id inTableId);
+
+private:
+    void open(); // Part of constructor contract.
+
+	ReadSection mDatabase;
+	AtomicFile *mDatabaseFile;
+    AtomicFile::VersionId mVersionId;
+
+	friend class DbModifier; // XXX Fixme
+    typedef map<Table::Id, Table *> TableMap;
+    TableMap mTableMap;
+	const class AppleDatabase &mDb;
+
+public:
+	typedef Table value_type;
+	typedef const Table &const_reference;
+	typedef const Table *const_pointer;
+
+	// A const forward iterator.
+	class const_iterator
+	{
+	public:
+		const_iterator(const TableMap::const_iterator &it) : mIterator(it) {}
+
+		// Use default copy consturctor and assignment operator.
+		//const_iterator(const const_iterator &it) : mIterator(it.mIterator) {}
+		//const_iterator &operator=(const const_iterator &it) { mIterator = it.mIterator; return *this; }
+		const_reference operator*() const { return *mIterator->second; }
+		const_iterator &operator++() { mIterator.operator++(); return *this; }
+		const_iterator operator++(int i) { return const_iterator(mIterator.operator++(i)); }
+		bool operator!=(const const_iterator &other) const { return mIterator != other.mIterator; }
+		bool operator==(const const_iterator &other) const { return mIterator == other.mIterator; }
+
+		const_pointer operator->() const { return mIterator->second; } // Not really needed.
+
+	private:
+		TableMap::const_iterator mIterator;
+	};
+
+	const_iterator begin() const { return const_iterator(mTableMap.begin()); }
+	const_iterator end() const { return const_iterator(mTableMap.end()); }
+};
+
+//
+// Cursor
+//
+class Cursor : public HandleObject
+{
+public:
+    virtual ~Cursor();
+    virtual bool next(Table::Id &outTableId,
+					CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes,
+					CssmData *outData,
+					CssmAllocator &inAllocator,
+					RecordId &recordId) = 0;
+};
+
+//
+// LinearCursor
+//
+class LinearCursor : public Cursor
+{
+    NOCOPY(LinearCursor)
+public:
+    LinearCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion,
+		   const Table &inTable);
+    virtual ~LinearCursor();
+    virtual bool next(Table::Id &outTableId,
+					CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes,
+					CssmData *outData,
+					CssmAllocator &inAllocator,
+					RecordId &recordId);
+					
+private:
+	const RefPointer<const DbVersion> mDbVersion;
+	uint32 mRecordsCount;
+    uint32 mRecord;
+	const ReadSection mRecordsSection;
+	uint32 mReadOffset;
+    const MetaRecord &mMetaRecord;
+
+    CSSM_DB_CONJUNCTIVE mConjunctive;
+    CSSM_QUERY_FLAGS mQueryFlags; // If CSSM_QUERY_RETURN_DATA is set return the raw key bits;
+    typedef vector<SelectionPredicate *> PredicateVector;
+
+    PredicateVector mPredicates;
+};
+
+//
+// A cursor that uses an index.
+//
+
+class IndexCursor : public Cursor
+{
+	NOCOPY(IndexCursor)
+public:
+	IndexCursor(DbQueryKey *queryKey, const DbVersion &inDbVersion,
+		const Table &table, const DbConstIndex *index);
+	virtual ~IndexCursor();
+
+    virtual bool next(Table::Id &outTableId,
+					CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes,
+					CssmData *outData,
+					CssmAllocator &inAllocator,
+					RecordId &recordId);
+
+private:
+	auto_ptr<DbQueryKey> mQueryKey;
+	const DbVersion &mDbVersion;
+	const Table &mTable;
+	const DbConstIndex *mIndex;
+	
+	DbIndexIterator mBegin, mEnd;
+};
+
+//
+// MultiCursor
+//
+class MultiCursor : public Cursor
+{
+    NOCOPY(MultiCursor)
+public:
+    MultiCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion);
+    virtual ~MultiCursor();
+    virtual bool next(Table::Id &outTableId,
+					CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes,
+					CssmData *outData,
+					CssmAllocator &inAllocator,
+					RecordId &recordId);
+private:
+	const RefPointer<const DbVersion> mDbVersion;
+	auto_ptr<CssmAutoQuery> mQuery;
+
+	DbVersion::const_iterator mTableIterator;
+	auto_ptr<Cursor> mCursor;
+};
+
+//
+// A DbModifier contains all pending changes to be made to a DB.
+// It also contains a DbVersion representing the state of the Database before any such changes
+// No read-style operations are supported by DbModifier.  If a DbModifier exists for a
+// particular Database and a client wishes to perform a query commit() must be called and
+// the client should perform the new query on the current database version after the commit.
+// Otherwise a client will not see changes made since the DbModifier was instanciated.
+//
+class DbModifier : public Metadata
+{
+	NOCOPY(DbModifier)
+public:
+    DbModifier(AtomicFile &inAtomicFile, const class AppleDatabase &db);
+    ~DbModifier();
+
+	// Whole database affecting members.
+    void createDatabase(const CSSM_DBINFO &inDbInfo,
+						const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry);
+	void openDatabase(); // This is optional right now.
+	void closeDatabase();
+	void deleteDatabase();
+
+    void commit();
+    void rollback();
+
+	// Record changing members
+	void deleteRecord(Table::Id inTableId, const RecordId &inRecordId);
+	const RecordId insertRecord(Table::Id inTableId,
+								const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+								const CssmData *inData);
+	const RecordId updateRecord(Table::Id inTableId, const RecordId &inRecordId,
+								const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+								const CssmData *inData,
+								CSSM_DB_MODIFY_MODE inModifyMode);
+
+	// Schema changing members
+    void insertTable(Table::Id inTableId, const string &inTableName,
+					 uint32 inNumberOfAttributes,
+					 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo,
+					 uint32 inNumberOfIndexes,
+					 const CSSM_DB_SCHEMA_INDEX_INFO *inIndexInfo);
+	void deleteTable(Table::Id inTableId);
+
+	// Record reading members
+	const RecordId getRecord(Table::Id inTableId, const RecordId &inRecordId,
+							 CSSM_DB_RECORD_ATTRIBUTE_DATA *inoutAttributes,
+							 CssmData *inoutData, CssmAllocator &inAllocator);
+	Cursor *createCursor(const CSSM_QUERY *inQuery);
+protected:
+    void modifyDatabase();
+    const RefPointer<const DbVersion> getDbVersion();
+
+    ModifiedTable *createTable(MetaRecord *inMetaRecord); // Takes over ownership of inMetaRecord
+	
+	void insertTableSchema(const CssmDbRecordAttributeInfo &inInfo,
+		const CSSM_DB_RECORD_INDEX_INFO *inIndexInfo = NULL);
+		
+	void insertTable(const CssmDbRecordAttributeInfo &inInfo,
+		const CSSM_DB_RECORD_INDEX_INFO * inIndexInfo = NULL,
+		const CSSM_DB_PARSING_MODULE_INFO * inParsingModule = NULL);
+
+    ModifiedTable &findTable(Table::Id inTableId);
+
+    uint32 writeAuthSection(uint32 inSectionOffset);
+    uint32 writeSchemaSection(uint32 inSectionOffset);
+
+private:
+	
+	// Current DbVersion of this database before any changes we are going to make.
+	RefPointer<const DbVersion> mDbVersion;
+	Mutex mDbVersionLock;
+
+    AtomicFile &mAtomicFile;
+    AtomicFile::VersionId mVersionId;
+    AtomicFile::FileRef mFileRef;
+    bool mWriting;
+
+    typedef map<Table::Id, ModifiedTable *> ModifiedTableMap;
+    ModifiedTableMap mModifiedTableMap;
+	
+	const class AppleDatabase &mDb;
+};
+
+//
+// AppleDatabaseManager
+//
+class AppleDatabaseManager : public DatabaseManager
+{
+public:
+	AppleDatabaseManager(const AppleDatabaseTableName *tableNames);
+    Database *make(const DbName &inDbName);
+	
+protected:
+	const AppleDatabaseTableName *mTableNames;
+};
+
+//
+// AppleDbContext
+//
+class AppleDbContext : public DbContext
+{
+public:
+	AppleDbContext(Database &inDatabase,
+				   DatabaseSession &inDatabaseSession,
+				   CSSM_DB_ACCESS_TYPE inAccessRequest,
+				   const AccessCredentials *inAccessCred,
+				   const void *inOpenParameters);
+	virtual ~AppleDbContext();
+	bool autoCommit() const { return mAutoCommit; }
+	void autoCommit(bool on) { mAutoCommit = on; }
+	
+private:
+	bool mAutoCommit;
+};
+
+//
+// AppleDatabase
+//
+class AppleDatabase : public Database
+{
+public:
+    AppleDatabase(const DbName &inDbName, const AppleDatabaseTableName *tableNames);
+    virtual ~AppleDatabase();
+
+    virtual void
+        dbCreate(DbContext &inDbContext, const CSSM_DBINFO &inDBInfo,
+                 const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry);
+
+    virtual void
+        dbOpen(DbContext &inDbContext);
+
+    virtual void
+        dbClose();
+
+    virtual void
+        dbDelete(DatabaseSession &inDatabaseSession,
+                 const AccessCredentials *inAccessCred);
+
+    virtual void
+        createRelation(DbContext &inDbContext,
+                       CSSM_DB_RECORDTYPE inRelationID,
+                       const char *inRelationName,
+                       uint32 inNumberOfAttributes,
+                       const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
+                       uint32 inNumberOfIndexes,
+                       const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo);
+
+    virtual void
+        destroyRelation(DbContext &inDbContext,
+                        CSSM_DB_RECORDTYPE inRelationID);
+
+    virtual void
+        authenticate(DbContext &inDbContext,
+                     CSSM_DB_ACCESS_TYPE inAccessRequest,
+                     const AccessCredentials &inAccessCred);
+
+    virtual void
+        getDbAcl(DbContext &inDbContext,
+                 const CSSM_STRING *inSelectionTag,
+                 uint32 &outNumberOfAclInfos,
+                 CSSM_ACL_ENTRY_INFO_PTR &outAclInfos);
+
+    virtual void
+        changeDbAcl(DbContext &inDbContext,
+                    const AccessCredentials &inAccessCred,
+                    const CSSM_ACL_EDIT &inAclEdit);
+
+    virtual void
+        getDbOwner(DbContext &inDbContext, CSSM_ACL_OWNER_PROTOTYPE &outOwner);
+
+    virtual void
+        changeDbOwner(DbContext &inDbContext,
+                      const AccessCredentials &inAccessCred,
+                      const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner);
+
+    virtual char *
+        getDbNameFromHandle(const DbContext &inDbContext) const;
+
+    virtual CSSM_DB_UNIQUE_RECORD_PTR
+        dataInsert(DbContext &inDbContext,
+                   CSSM_DB_RECORDTYPE RecordType,
+                   const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+                   const CssmData *inData);
+
+    virtual void
+        dataDelete(DbContext &inDbContext,
+                   const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier);
+
+    virtual void
+        dataModify(DbContext &inDbContext,
+                   CSSM_DB_RECORDTYPE inRecordType,
+                   CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier,
+                   const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
+                   const CssmData *inDataToBeModified,
+                   CSSM_DB_MODIFY_MODE inModifyMode);
+
+    virtual CSSM_HANDLE
+        dataGetFirst(DbContext &inDbContext,
+                     const DLQuery *inQuery,
+                     CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                     CssmData *inoutData,
+                     CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord);
+
+    virtual bool
+        dataGetNext(DbContext &inDbContext,
+                    CSSM_HANDLE inResultsHandle,
+                    CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                    CssmData *inoutData,
+                    CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord);
+
+    virtual void
+        dataAbortQuery(DbContext &inDbContext,
+                       CSSM_HANDLE inResultsHandle);
+
+    virtual void
+        dataGetFromUniqueRecordId(DbContext &inDbContext,
+                                  const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
+                                  CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                                  CssmData *inoutData);
+
+    virtual void
+        freeUniqueRecord(DbContext &inDbContext,
+                         CSSM_DB_UNIQUE_RECORD &inUniqueRecord);
+						 
+	virtual void passThrough(DbContext &dbContext,
+							 uint32 passThroughId,
+							 const void *inputParams,
+							 void **outputParams);
+
+    // Subclasses must implement this method.
+    virtual DbContext *makeDbContext(DatabaseSession &inDatabaseSession,
+                                     CSSM_DB_ACCESS_TYPE inAccessRequest,
+                                     const AccessCredentials *inAccessCred,
+                                     const void *inOpenParameters);
+									 
+	const CssmDbRecordAttributeInfo schemaRelations;
+	const CssmDbRecordAttributeInfo schemaAttributes;
+	const CssmDbRecordAttributeInfo schemaIndexes;
+	const CssmDbRecordAttributeInfo schemaParsingModule;
+
+	const char *recordName(CSSM_DB_RECORDTYPE inRecordType) const;
+
+private:
+	static void
+	AppleDatabase::updateUniqueRecord(DbContext &inDbContext,
+									CSSM_DB_RECORDTYPE inTableId,
+									const RecordId &inRecordId,
+									CSSM_DB_UNIQUE_RECORD &inoutUniqueRecord);
+
+	CSSM_DB_UNIQUE_RECORD_PTR
+	createUniqueRecord(DbContext &inDbContext, CSSM_DB_RECORDTYPE inTableId,
+					   const RecordId &inRecordId);
+	const RecordId parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
+									 CSSM_DB_RECORDTYPE &outTableId);
+
+    Mutex mWriteLock;
+    AtomicFile mAtomicFile;
+	DbModifier mDbModifier;
+	const AppleDatabaseTableName *mTableNames;
+};
+
+} // end namespace Security
+
+#endif //_H_APPLEDATABASE
diff --git a/cdsa/cdsa_utilities/AtomicFile.cpp b/cdsa/cdsa_utilities/AtomicFile.cpp
new file mode 100644
index 00000000..710c70e8
--- /dev/null
+++ b/cdsa/cdsa_utilities/AtomicFile.cpp
@@ -0,0 +1,1017 @@
+/*
+ * 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.
+ */
+
+
+//
+//  AtomicFile.cpp - Description t.b.d.
+//
+#ifdef __MWERKS__
+#define _CPP_ATOMICFILE
+#endif
+
+#include <Security/AtomicFile.h>
+#include <Security/DbName.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <memory>
+#include <stack>
+
+#if _USE_IO == _USE_IO_POSIX
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <sys/stat.h>
+//#include <err.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#elif _USE_IO == _USE_IO_MACOS
+typedef SInt32 ssize_t;
+#endif
+
+using namespace std;
+
+AtomicFile::AtomicFile(const DbName &inDbName) :
+    mReadFile(nil),
+    mReadFilename(inDbName.dbName()),
+    mWriteFile(nil),
+    mWriteFilename(mReadFilename + ",") // XXX Do some more work here like resolving symlinks/aliases etc.
+{
+    // We only support databases with string names of non-zero length.
+    if (inDbName.dbLocation() != nil || inDbName.dbName().length() == 0)
+        CssmError::throwMe(CSSMERR_DL_INVALID_DB_LOCATION);
+}
+
+AtomicFile::~AtomicFile()
+{
+    // Assume there are no more running theads in this object.
+
+    // Try hard to clean up as much as possible.
+    try
+    {
+        // Rollback any pending write.
+        if (mWriteFile)
+            rollback();
+    }
+    catch(...) {}
+
+    // Close and delete all files in mOpenFileMap
+    for (OpenFileMap::iterator it = mOpenFileMap.begin(); it != mOpenFileMap.end(); it++)
+    {
+        try
+        {
+            it->second->close();
+        }
+        catch(...) {}
+        try
+        {
+            delete it->second;
+        }
+        catch(...) {}
+    }
+}
+
+void
+AtomicFile::close()
+{
+    StLock<Mutex> _(mReadLock);
+
+    // If we have no read file we have nothing to close.
+    if (mReadFile == nil)
+        return;
+
+    // Remember mReadFile and set it to nil, so that it will be closed after any pending write completes
+    OpenFile *aOpenFile = mReadFile;
+    mReadFile = nil;
+
+    // If aOpenFile has a zero use count no other thread is currently using it,
+    // so we can safely remove it from the map.
+    if (aOpenFile->mUseCount == 0)
+    {
+        // Do not close any files (nor remove them from the map) while some thread is writing
+        // since doing so might release the lock we are holding.
+        if (mWriteLock.tryLock())
+        {
+            // Release the write lock immediately since tryLock just aquired it and we don't want to write.
+            mWriteLock.unlock();
+
+            // Remove aOpenFile from the map of open files.
+            mOpenFileMap.erase(aOpenFile->versionId());
+            try
+            {
+                aOpenFile->close();
+            }
+            catch(...)
+            {
+                delete aOpenFile;
+                throw;
+            }
+            delete aOpenFile;
+        }
+    }
+}
+
+AtomicFile::VersionId
+AtomicFile::enterRead(const uint8 *&outFileAddress, size_t &outLength)
+{
+    StLock<Mutex> _(mReadLock);
+
+    // If we already have a read file check if it is still current.
+    if (mReadFile != nil)
+    {
+        if (mReadFile->isDirty())
+        {
+            // Remember mReadFile and set it to nil in case an exception is thrown
+            OpenFile *aOpenFile = mReadFile;
+            mReadFile = nil;
+
+            // If aOpenFile has a zero use count no other thread is currently using it,
+            // so we can safely remove it from the map.
+            if (aOpenFile->mUseCount == 0)
+            {
+                // Do not close any files (nor remove them from the map) while some thread is writing
+                // since doing so might release the lock we are holding.
+                if (mWriteLock.tryLock())
+                {
+                    // Release the write lock immediately since tryLock just aquired it and we don't want to write.
+                    mWriteLock.unlock();
+
+                    // Remove aOpenFile from the map of open files.
+                    mOpenFileMap.erase(aOpenFile->versionId());
+                    try
+                    {
+                        aOpenFile->close();
+                    }
+                    catch(...)
+                    {
+                        delete aOpenFile;
+                        throw;
+                    }
+                    delete aOpenFile;
+                }
+            }
+        }
+    }
+
+    // If we never had or no longer have an open read file.  Open it now.
+    if (mReadFile == nil)
+    {
+        mReadFile = new OpenFile(mReadFilename, false, false, 0);
+        mOpenFileMap.insert(OpenFileMap::value_type(mReadFile->versionId(), mReadFile));
+    }
+    // Note that mReadFile->isDirty() might actually return true here, but all that mean is
+    // that we are looking at data that was commited after we opened the file which might
+    // happen in a few miliseconds anyway.
+
+    // Bump up the use count of our OpenFile.
+    mReadFile->mUseCount++;
+
+    // Return the length of the file and the mapped address.
+    outLength = mReadFile->length();
+    outFileAddress = mReadFile->address();
+    return mReadFile->versionId();
+}
+
+void
+AtomicFile::exitRead(VersionId inVersionId)
+{
+    StLock<Mutex> _(mReadLock);
+    OpenFileMap::iterator it = mOpenFileMap.find(inVersionId);
+    // If the inVersionId is not in the map anymore something really bad happned.
+    if (it == mOpenFileMap.end())
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+    OpenFile *aOpenFile = it->second;
+    aOpenFile->mUseCount--;
+
+    // Don't close the current active file even if its mUseCount hits 0 since someone
+    // else will probably request it soon.
+    if (aOpenFile->mUseCount == 0 && aOpenFile != mReadFile)
+    {
+        // Do not close any files (nor remove them from the map) while some thread is writing
+        // since doing so might release the lock we are holding.
+        if (mWriteLock.tryLock())
+        {
+            // Release the write lock immidiatly since tryLock just aquired it and we don't want to write.
+            mWriteLock.unlock();
+
+            // Remove from the map, close and delete aOpenFile.
+            mOpenFileMap.erase(it);
+            try
+            {
+                aOpenFile->close();
+            }
+            catch(...)
+            {
+                delete aOpenFile;
+                throw;
+            }
+            delete aOpenFile;
+        }
+    }
+}
+
+bool AtomicFile::isDirty(VersionId inVersionId)
+{
+    StLock<Mutex> _(mReadLock);
+    OpenFileMap::iterator it = mOpenFileMap.find(inVersionId);
+    // If the inVersionId is not in the map anymore something really bad happned.
+    if (it == mOpenFileMap.end())
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+    return it->second->isDirty();
+}
+
+void
+AtomicFile::performDelete()
+{
+    // Prevent any other threads in this process from writing.
+    mWriteLock.lock();
+
+    OpenFile *aReadFile = nil;
+    try
+    {
+        // Keep reopening mReadFilename until the lock has been aquired on a non-dirty file.
+        // XXX This is a potential infinite loop.
+        for (;;)
+        {
+            aReadFile = new OpenFile(mReadFilename, true, true, 0);
+            if (!aReadFile->isDirty())
+                break;
+
+            aReadFile->close();
+            delete aReadFile;
+            aReadFile = nil;
+        }
+
+        // Aquire the read lock so no other thread will open the file
+        StLock<Mutex> _(mReadLock);
+
+        // Delete the file.
+        unlink(mReadFilename);
+
+        // Clear our current mReadFile since it refers to the deleted file.
+        mReadFile = nil;
+
+        // Mark the old file as modified
+        aReadFile->setDirty();
+
+        // Close any open files.
+        endWrite();
+    }
+    catch(...)
+    {
+        if (aReadFile)
+        {
+            try
+            {
+                VersionId aVersionId = aReadFile->versionId();
+                aReadFile->close();
+                mOpenFileMap.erase(aVersionId);
+            } catch(...) {}
+            delete aReadFile;
+        }
+        endWrite();
+        throw;
+    }
+    endWrite();
+}
+
+AtomicFile::VersionId
+AtomicFile::enterCreate(FileRef &outWriteRef)
+{
+    // Prevent any other threads in this process from writing.
+    mWriteLock.lock();
+    OpenFile *aReadFile = nil;
+    try
+    {
+        // No threads can read during creation
+        StLock<Mutex> _(mReadLock);
+
+        // Create mReadFilename until the lock has been aquired on a non-dirty file.
+        aReadFile = new OpenFile(mReadFilename, false, true, 1);
+
+        // Open mWriteFile for writing.
+        mWriteFile = new OpenFile(mWriteFilename, true, false, aReadFile->versionId() + 1);
+
+        // Insert aReadFile into the map (do this after opening mWriteFile just in case that throws).
+        mOpenFileMap.insert(OpenFileMap::value_type(-1, aReadFile));
+
+        outWriteRef = mWriteFile->fileRef();
+        mCreating = true; // So rollback() will delete mReadFileName.
+        return aReadFile->versionId();
+    }
+    catch(...)
+    {
+        // Make sure we don't thow during cleanup since that would clobber the original
+        // error and prevent us from releasing mWriteLock
+        try
+        {
+            if (aReadFile)
+            {
+                try
+                {
+                    aReadFile->close();
+                    // XXX We should only unlink if we know that no one else is currently creating the file.
+                    //unlink(mReadFilename);
+                    mOpenFileMap.erase(-1);
+                } catch(...) {}
+                delete aReadFile;
+            }
+
+            if (mWriteFile)
+            {
+                try
+                {
+                    mWriteFile->close();
+                    unlink(mWriteFilename);
+                } catch(...) {}
+                delete mWriteFile;
+                mWriteFile = nil;
+            }
+        }
+        catch(...) {} // Do not throw since we already have an error.
+
+        // Release the write lock and remove any unused files from the map
+        endWrite();
+        throw;
+    }
+}
+
+AtomicFile::VersionId
+AtomicFile::enterWrite(const uint8 *&outFileAddress, size_t &outLength, FileRef &outWriteRef)
+{
+    // Wait for all other threads in this process to finish writing.
+    mWriteLock.lock();
+    mCreating = false; // So rollback() will not delete mReadFileName.
+    OpenFile *aReadFile = nil;
+    try
+    {
+        // Keep reopening mReadFilename until the lock has been aquired on a non-dirty file.
+        // XXX This is a potential infinite loop.
+        for (;;)
+        {
+            aReadFile = new OpenFile(mReadFilename, true, true, 0);
+            if (!aReadFile->isDirty())
+                break;
+
+            aReadFile->close();
+            delete aReadFile;
+            aReadFile = nil;
+        }
+
+        // We have the write lock on the file now we start modifying our shared data
+        // stuctures so aquire the read lock.
+        StLock<Mutex> _(mReadLock);
+
+        // Open mWriteFile for writing.
+        mWriteFile = new OpenFile(mWriteFilename, true, false, aReadFile->versionId() + 1);
+
+        // Insert aReadFile into the map (do this after opening mWriteFile just in case that throws).
+        mOpenFileMap.insert(OpenFileMap::value_type(-1, aReadFile));
+
+        outWriteRef = mWriteFile->fileRef();
+        outLength = aReadFile->length();
+        outFileAddress = aReadFile->address();
+        return aReadFile->versionId();
+    }
+    catch(...)
+    {
+        // Make sure we don't thow during cleanup since that would clobber the original
+        // error and prevent us from releasing mWriteLock
+        try
+        {
+            if (aReadFile)
+            {
+                try
+                {
+                    aReadFile->close();
+                    mOpenFileMap.erase(-1);
+                } catch(...) {}
+                delete aReadFile;
+            }
+
+            if (mWriteFile)
+            {
+                try
+                {
+                    mWriteFile->close();
+                    unlink(mWriteFilename);
+                } catch(...) {}
+                delete mWriteFile;
+                mWriteFile = nil;
+            }
+        }
+        catch(...) {} // Do not throw since we already have an error.
+
+        // Release the write lock and remove any unused files from the map
+        endWrite();
+        throw;
+    }
+}
+
+AtomicFile::VersionId
+AtomicFile::commit()
+{
+    StLock<Mutex> _(mReadLock);
+    if (mWriteFile == nil)
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+    try
+    {
+        VersionId aVersionId = mWriteFile->versionId();
+        mWriteFile->close();
+        delete mWriteFile;
+        mWriteFile = nil;
+
+        OpenFileMap::iterator it = mOpenFileMap.find(-1);
+        if (it == mOpenFileMap.end())
+            CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+        // First rename the file and them mark the old one as modified
+        rename(mWriteFilename, mReadFilename);
+        OpenFile *aOpenFile = it->second;
+
+        // Clear our current mReadFile since it refers to the old file.
+        mReadFile = nil;
+
+        // Mark the old file as modified
+        aOpenFile->setDirty();
+
+        // Close all unused files (in particular aOpenFile) and remove them from mOpenFileMap
+        endWrite();
+        return aVersionId;
+    }
+    catch (...)
+    {
+        // Unlink the new file to rollback the transaction and close any open files.
+        try
+        {
+            unlink(mWriteFilename);
+        }catch(...) {}
+        endWrite();
+        throw;
+    }
+}
+
+void
+AtomicFile::rollback()
+{
+    StLock<Mutex> _(mReadLock);
+    if (mWriteFile == nil)
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+    try
+    {
+        mWriteFile->close();
+        delete mWriteFile;
+        mWriteFile = nil;
+
+        // First rename the file and them mark the old one as modified
+        unlink(mWriteFilename);
+        if (mCreating)
+            unlink(mReadFilename);
+        endWrite();
+    }
+    catch(...)
+    {
+        // Unlink the new file to rollback the transaction and close any open files.
+        try
+        {
+            unlink(mWriteFilename);
+        }catch(...) {}
+        endWrite();
+        throw;
+    }
+}
+
+// This private function is called by a successfull commit(), rollback() or performDelete() as well
+// as by a failed enterWrite() or enterCreate().
+void
+AtomicFile::endWrite()
+{
+    try
+    {
+        // We need to go in and close and delete all unused files from the queue
+        stack<VersionId> aDeleteList;
+        OpenFileMap::iterator it;
+        for (it = mOpenFileMap.begin();
+             it != mOpenFileMap.end();
+             it++)
+        {
+            OpenFile *aOpenFile = it->second;
+            // If aOpenFile is unused and it is not the mReadFile schedule it for close and removal.
+            // Note that if this is being called after a commit mReadFile will have been set to nil.
+            if (aOpenFile != mReadFile && aOpenFile->mUseCount == 0)
+                aDeleteList.push(it->first);
+        }
+
+        // Remove everything that was scheduled for removal
+        while (!aDeleteList.empty())
+        {
+            it = mOpenFileMap.find(aDeleteList.top());
+            aDeleteList.pop();
+            try
+            {
+                it->second->close();
+            }
+            catch(...) {}
+            delete it->second;
+            mOpenFileMap.erase(it);
+        }
+
+        if (mWriteFile)
+        {
+            mWriteFile->close();
+        }
+    }
+    catch(...)
+    {
+        delete mWriteFile;
+        mWriteFile = nil;
+        mWriteLock.unlock();
+        throw;
+    }
+
+    delete mWriteFile;
+    mWriteFile = nil;
+    mWriteLock.unlock();
+}
+
+void
+AtomicFile::rename(const string &inSrcFilename, const string &inDestFilename)
+{
+    if (::rename(inSrcFilename.c_str(), inDestFilename.c_str()))
+        UnixError::throwMe(errno);
+}
+
+void
+AtomicFile::unlink(const string &inFilename)
+{
+    if (::unlink(inFilename.c_str()))
+        UnixError::throwMe(errno);
+}
+
+void
+AtomicFile::write(OffsetType inOffsetType, uint32 inOffset, const uint32 inData)
+{
+    uint32 aData = htonl(inData);
+    write(inOffsetType, inOffset, reinterpret_cast<uint8 *>(&aData), sizeof(aData));
+}
+
+void
+AtomicFile::write(OffsetType inOffsetType, uint32 inOffset,
+				  const uint32 *inData, uint32 inCount)
+{
+#ifdef HOST_LONG_IS_NETWORK_LONG
+    // XXX Optimize this for the case where hl == nl
+    const uint32 *aBuffer = inData;
+#else
+    auto_array<uint32> aBuffer(inCount);
+    for (uint32 i = 0; i < inCount; i++)
+        aBuffer.get()[i] = htonl(inData[i]);
+#endif
+
+    write(inOffsetType, inOffset, reinterpret_cast<const uint8 *>(aBuffer.get()),
+    	  inCount * sizeof(*inData));
+}
+
+void
+AtomicFile::write(OffsetType inOffsetType, uint32 inOffset, const uint8 *inData, uint32 inLength)
+{
+    // Seriously paranoid check.
+    if (mWriteFile == nil)
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+    if (inOffsetType != None)
+    {
+        if (::lseek(mWriteFile->mFileRef, inOffset, inOffsetType == FromStart ? SEEK_SET : SEEK_CUR) == -1)
+            UnixError::throwMe(errno);
+    }
+
+    if (::write(mWriteFile->mFileRef, reinterpret_cast<const char *>(inData),
+    			inLength) != static_cast<ssize_t>(inLength))
+        UnixError::throwMe(errno);
+}
+
+// AtomicFile::OpenFile implementation
+
+AtomicFile::OpenFile::OpenFile(const string &inFilename, bool write, bool lock, VersionId inVersionId) :
+    mUseCount(0),
+    mVersionId(inVersionId),
+    mAddress(NULL),
+    mLength(0)
+{
+    int flags, mode = 0;
+    if (write && lock)
+    {
+        flags = O_RDWR;
+        mState = ReadWrite;
+    }
+    else if (write && !lock)
+    {
+        flags = O_WRONLY|O_CREAT|O_TRUNC;
+        mode = 0666;
+        mState = Write;
+    }
+    else if (!write && lock)
+    {
+        flags = O_WRONLY|O_CREAT|O_TRUNC|O_EXCL;
+        mode = 0666;
+        mState = Create;
+    }
+    else
+    {
+        flags = O_RDONLY;
+        mState = Read;
+    }
+
+    mFileRef = ::open(inFilename.c_str(), flags, mode);
+    if (mFileRef == -1)
+    {
+        int error = errno;
+
+#if _USE_IO == _USE_IO_POSIX
+        // Do the obvious error code translations here.
+        if (error == ENOENT)
+		{
+			// Throw CSSMERR_DL_DATASTORE_DOESNOT_EXIST even in Write state since it means someone threw away our parent directory.
+			if (mState == ReadWrite || mState == Read || mState == Write)
+				CssmError::throwMe(CSSMERR_DL_DATASTORE_DOESNOT_EXIST);
+			if (mState == Create)
+			{
+				// Attempt to create the path to inFilename since one or more of the directories
+				// in the path do not yet exist.
+				mkpath(inFilename);
+
+				// Now try the open again.
+				mFileRef = ::open(inFilename.c_str(), flags, mode);
+				error = mFileRef == -1 ? errno : 0;
+				if (error == ENOENT)
+					CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED);
+			}
+		}
+
+		if (error == EACCES)
+			CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED);
+
+        if (error == EEXIST)
+            CssmError::throwMe(CSSMERR_DL_DATASTORE_ALREADY_EXISTS);
+#endif
+
+		// Check if we are still in an error state.
+		if (error)
+			UnixError::throwMe(errno);
+    }
+
+    // If this is a new file write out the versionId
+    if (mState == Create)
+        writeVersionId(mVersionId);
+
+    // If this is a temp output file we are done.
+    if (mState == Write)
+        return;
+
+    try
+    {
+        mLength = ::lseek(mFileRef, 0, SEEK_END);
+        if (mLength == static_cast<size_t>(-1))
+            UnixError::throwMe(errno);
+        if (mLength == 0)
+        {
+            // XXX What to set versionId to?
+            mVersionId = 0;
+            return; // No point in mapping a zero length file.
+        }
+
+#if _USE_IO == _USE_IO_POSIX
+        // Lock the file if required.
+        if (lock)
+        {
+            struct flock mLock;
+            mLock.l_start = 0;
+            mLock.l_len = 1;
+            mLock.l_pid = getpid();
+            mLock.l_type = F_WRLCK;
+            mLock.l_whence = SEEK_SET;
+
+            // Keep trying to obtain the lock if we get interupted.
+            for (;;)
+            {
+                if (::fcntl(mFileRef, F_SETLKW, reinterpret_cast<int>(&mLock)) == -1)
+                {
+                    int error = errno;
+                    if (error == EINTR)
+                        continue;
+
+					if (error != ENOTSUP)
+						UnixError::throwMe(error);
+
+					// XXX Filesystem does not support locking with fcntl use an alternative.
+					mFcntlLock = false;
+                }
+				else
+					mFcntlLock = true;
+
+                break;
+            }
+        }
+
+        if (mState != Create)
+        {
+            mAddress = reinterpret_cast<const uint8 *>
+				(::mmap(0, mLength, PROT_READ, MAP_FILE|MAP_SHARED,
+						mFileRef, 0));
+            if (mAddress == reinterpret_cast<const uint8 *>(-1))
+            {
+                 mAddress = NULL;
+                UnixError::throwMe(errno);
+            }
+
+            mVersionId = readVersionId();
+        }
+#else
+        if (mState != Create)
+        {
+			mAddress = reinterpret_cast<const uint8 *>(-1);
+        	auto_array<char> aBuffer(mLength);
+ 			if (::read(mFileRef, aBuffer.get(), mLength) != mLength)
+ 				UnixError::throwMe(errno);
+
+            mAddress = reinterpret_cast<const uint8 *>(aBuffer.release());
+            mVersionId = readVersionId();
+        }
+#endif
+    }
+    catch(...)
+    {
+        if (mState != Closed)
+            ::close(mFileRef);
+        throw;
+    }
+}
+
+AtomicFile::OpenFile::~OpenFile()
+{
+    close();
+}
+
+void
+AtomicFile::OpenFile::close()
+{
+    int error = 0;
+    if (mAddress != NULL)
+    {
+#if _USE_IO == _USE_IO_POSIX
+        if (::munmap(const_cast<uint8 *>(mAddress), mLength) == -1)
+            error = errno;
+#else
+		delete[] mAddress;
+#endif
+
+        mAddress = NULL;
+    }
+
+    if (mState == Write)
+        writeVersionId(mVersionId);
+
+    if (mState != Closed)
+    {
+        mState = Closed;
+        if (::close(mFileRef) == -1)
+            error = errno;
+    }
+
+    if (error != 0)
+        UnixError::throwMe(error);
+}
+
+bool
+AtomicFile::OpenFile::isDirty()
+{
+    if (mAddress == NULL)
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+    return (mVersionId != readVersionId()) || mVersionId == 0;
+}
+
+// Set the files dirty bit (requires the file to be writeable and locked).
+void
+AtomicFile::OpenFile::setDirty()
+{
+    if (mState != ReadWrite && mState != Create)
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+
+    writeVersionId(0);
+}
+
+void
+AtomicFile::OpenFile::unlock()
+{
+// XXX This should be called.
+#if 0
+	if (mFcntlLock)
+	{
+		struct flock mLock;
+		mLock.l_start = 0;
+		mLock.l_len = 1;
+		mLock.l_pid = getpid();
+		mLock.l_type = F_UNLCK;
+		mLock.l_whence = SEEK_SET;
+		if (::fcntl(mFileRef, F_SETLK, reinterpret_cast<int>(&mLock)) == -1)
+			UnixError::throwMe(errno);
+	}
+#endif
+}
+
+AtomicFile::VersionId
+AtomicFile::OpenFile::readVersionId()
+{
+    const uint8 *ptr;
+    char buf[4];
+
+    // Read the VersionId
+    if (mAddress == NULL)
+    {
+        // Seek to the end of the file minus 4
+		if (mLength < 4)
+			CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+        if (::lseek(mFileRef, mLength - 4, SEEK_SET) == -1)
+            UnixError::throwMe(errno);
+
+        ptr = reinterpret_cast<uint8 *>(buf);
+        if (::read(mFileRef, buf, 4) != 4)
+            UnixError::throwMe(errno);
+    }
+    else
+    {
+        ptr = mAddress + mLength - 4;
+        if (mLength < 4)
+            CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+    }
+
+    VersionId aVersionId = 0;
+    for (int i = 0; i < 4; i++)
+    {
+        aVersionId = (aVersionId << 8) + ptr[i];
+    }
+
+    return aVersionId;
+}
+
+void
+AtomicFile::OpenFile::writeVersionId(VersionId inVersionId)
+{
+	if (mState == ReadWrite)
+	{
+        // Seek to the end of the file minus 4
+		if (mLength < 4)
+			CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+        if (::lseek(mFileRef, mLength - 4, SEEK_SET) == -1)
+            UnixError::throwMe(errno);
+	}
+	else /* if (mState == Create || mState == Write) */
+	{
+		// Seek to the end of the file.
+		if (::lseek(mFileRef, 0, SEEK_END) == -1)
+			UnixError::throwMe(errno);
+	}
+
+    uint8 buf[4];
+    // Serialize the VersionId
+    for (int i = 3; i >= 0; i--)
+    {
+        buf[i] = inVersionId & 0xff;
+        inVersionId = inVersionId >> 8;
+    }
+
+    // Write the VersionId
+    if (::write(mFileRef, reinterpret_cast<char *>(buf), 4) != 4)
+        UnixError::throwMe(errno);
+}
+
+void
+AtomicFile::OpenFile::mkpath(const std::string &inFilename)
+{
+	char *path = const_cast<char *>(inFilename.c_str()); // @@@ Const_cast is a lie!!!
+	struct stat sb;
+	char *slash;
+    mode_t dir_mode = (0777 & ~umask(0)) | S_IWUSR | S_IXUSR;
+
+	slash = path;
+
+	for (;;)
+	{
+		slash += strspn(slash, "/");
+		slash += strcspn(slash, "/");
+
+		if (*slash == '\0')
+			break;
+
+		*slash = '\0';
+
+		if (stat(path, &sb))
+		{
+			if (errno != ENOENT || mkdir(path, dir_mode))
+				UnixError::throwMe(errno);
+			/* The mkdir() and umask() calls both honor only the low
+			   nine bits, so if you try to set a mode including the
+			   sticky, setuid, setgid bits you lose them. So chmod().  */
+			if (chmod(path, dir_mode) == -1)
+				UnixError::throwMe(errno);
+		}
+		else if (!S_ISDIR(sb.st_mode))
+			CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED);  // @@@ Should be is a directory
+
+		*slash = '/';
+	}
+}
+
+
+
+// Constructor uglyness to work around C++ language limitations.
+struct AtomicFileRef::InitArg
+{
+    AtomicFile::VersionId versionId;
+    const uint8 *address;
+    size_t length;
+};
+
+AtomicFileRef::~AtomicFileRef()
+{
+}
+
+AtomicFileRef::AtomicFileRef(AtomicFile &inAtomicFile, const InitArg &inInitArg) :
+    mVersionId(inInitArg.versionId),
+    mAtomicFile(inAtomicFile),
+    mAddress(inInitArg.address),
+    mLength(inInitArg.length)
+{
+}
+
+AtomicFileReadRef::~AtomicFileReadRef()
+{
+	try {
+		mAtomicFile.exitRead(mVersionId);
+	}
+	catch(...) {
+	}
+}
+
+AtomicFileRef::InitArg
+AtomicFileReadRef::enterRead(AtomicFile &inAtomicFile)
+{
+    InitArg anInitArg;
+    anInitArg.versionId = inAtomicFile.enterRead(anInitArg.address, anInitArg.length);
+    return anInitArg;
+}
+
+AtomicFileReadRef::AtomicFileReadRef(AtomicFile &inAtomicFile) :
+    AtomicFileRef(inAtomicFile, enterRead(inAtomicFile))
+{
+}
+
+AtomicFileWriteRef::~AtomicFileWriteRef()
+{
+	if (mOpen) {
+		try {
+			mAtomicFile.rollback();
+		}
+		catch (...) 
+		{
+		}
+	}
+}
+
+AtomicFileRef::InitArg
+AtomicFileWriteRef::enterWrite(AtomicFile &inAtomicFile, AtomicFile::FileRef &outWriteFileRef)
+{
+    InitArg anInitArg;
+    anInitArg.versionId = inAtomicFile.enterWrite(anInitArg.address, anInitArg.length, outWriteFileRef);
+    return anInitArg;
+}
+
+AtomicFileWriteRef::AtomicFileWriteRef(AtomicFile &inAtomicFile) :
+    AtomicFileRef(inAtomicFile, enterWrite(inAtomicFile, mFileRef))
+{
+}
diff --git a/cdsa/cdsa_utilities/AtomicFile.h b/cdsa/cdsa_utilities/AtomicFile.h
new file mode 100644
index 00000000..2ec22274
--- /dev/null
+++ b/cdsa/cdsa_utilities/AtomicFile.h
@@ -0,0 +1,224 @@
+/*
+ * 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.
+ */
+
+
+//
+//  AtomicFile.h - Description t.b.d.
+//
+#ifndef _H_ATOMICFILE
+#define _H_ATOMICFILE
+
+#include <Security/threading.h>
+
+#include <map>
+#include <string>
+
+#if _USE_IO == _USE_IO_POSIX
+#include <sys/types.h>
+#include <machine/endian.h>
+#elif _USE_IO == _USE_IO_MACOS
+#define htonl(X) (X)
+#define ntohl(X) (X)
+#endif
+
+#ifdef _CPP_ATOMICFILE
+#pragma export on
+#endif
+
+namespace Security
+{
+
+class DbName;
+
+class AtomicFile
+{
+public:
+    typedef int FileRef;
+    typedef int VersionId;
+
+    AtomicFile(const DbName &inDbName);
+	~AtomicFile();
+
+    // Close the currently open AtomicFile.  (If there are transactions outstanding this call
+    // has no effect until after they have completed.
+    void close();
+
+    // Start a read operation. Returns a mmaped region with the file in it.  Return the size of the
+    // file in length.  Each call to enterRead() *must* be paired with a call to exitRead.
+    VersionId enterRead(const uint8 *&outFileAddress, size_t &outLength);
+
+    // End a read operation.
+    void exitRead(VersionId inVersionId);
+
+	// Return true if inVersionId is not the most recent version of this file.
+	bool isDirty(VersionId inVersionId);
+
+    // Aquire the write lock and remove the file.
+    void performDelete();
+
+    // Create and lock the database file for writing, and set outWriteRef to a newly created
+    // file open for writing.
+    // Return the new VersionId this file will have after a succesful commit.
+    VersionId enterCreate(FileRef &outWriteRef);
+
+    // Lock the database file for writing, map the database file for reading and
+    // set outWriteRef to a newly created file open for writing.
+    // Return the VersionId or the file being modified.
+    VersionId enterWrite(const uint8 *&outFileAddress, size_t &outLength, FileRef &outWriteRef);
+
+    // Commit the current create or write and close the write file.  Return the VersionId of the new file.
+    VersionId commit();
+
+    // Rollback the current create or write.
+    void rollback();
+
+    enum OffsetType {
+        None,
+        FromStart,
+        FromCurrent
+    };
+
+    void write(OffsetType inOffsetType, uint32 inOffset, const uint32 *inData, uint32 inCount);
+    void write(OffsetType inOffsetType, uint32 inOffset, const uint8 *inData, uint32 inLength);
+    void write(OffsetType inOffsetType, uint32 inOffset, const uint32 inData);
+    const string filename() const { return mReadFilename; }
+private:
+    void endWrite();
+    void rename(const string &inSrcFilename, const string &inDestFilename);
+    void unlink(const string &inFilename);
+
+    class OpenFile
+    {
+    public:
+        OpenFile(const std::string &inFilename, bool write, bool lock, VersionId inVersionId);
+        ~OpenFile();
+
+        void close();
+        VersionId versionId() const { return mVersionId; }
+        FileRef fileRef() const { return mFileRef; }
+        const uint8 *address() const { return mAddress; }
+        size_t length() const { return mLength; }
+
+        // Check if the file has its dirty bit set.
+        bool isDirty();
+        // Set the files dirty bit (requires the file to be writeable and locked).
+        void setDirty();
+
+        void lock();
+        void unlock();
+
+        int mUseCount;
+        FileRef mFileRef;
+    private:
+        VersionId readVersionId();
+        void writeVersionId(VersionId inVersionId);
+		static void mkpath(const std::string &inFilename);
+
+        VersionId mVersionId;
+        const uint8 *mAddress;
+        size_t mLength;
+		bool mFcntlLock;
+        enum
+        {
+            Closed,
+            Read,
+            Write,
+            ReadWrite,
+            Create
+        } mState;
+    };
+
+    Mutex mReadLock;
+    OpenFile *mReadFile;
+    string mReadFilename;
+
+    Mutex mWriteLock;
+    OpenFile *mWriteFile;
+    string mWriteFilename;
+
+    typedef std::map<VersionId, OpenFile *> OpenFileMap;
+    OpenFileMap mOpenFileMap;
+
+    bool mCreating;
+};
+
+
+class AtomicFileRef
+{
+public:
+    virtual ~AtomicFileRef();
+
+    uint32 at(uint32 inOffset)
+    {
+        return ntohl(*reinterpret_cast<const uint32 *>(mAddress + inOffset));
+    }
+
+    uint32 operator[](uint32 inOffset)
+    {
+        if (inOffset + sizeof(uint32) > mLength)
+            CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+        return at(inOffset);
+    }
+
+    const uint8 *range(uint32 inOffset, uint32 inLength)
+    {
+        if (inOffset + inLength > mLength)
+            CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+        return mAddress + inOffset;
+    }
+
+    const AtomicFile::VersionId mVersionId;
+protected:
+    struct InitArg;
+    AtomicFileRef(AtomicFile &inAtomicFile, const InitArg &inInitArg);
+
+    AtomicFile &mAtomicFile;
+    const uint8 *mAddress;
+    const size_t mLength;
+};
+
+// Use this class to open an AtomicFile for reading.
+class AtomicFileReadRef : public AtomicFileRef
+{
+public:
+    AtomicFileReadRef(AtomicFile &inAtomicFile);
+    virtual ~AtomicFileReadRef();
+private:
+    static InitArg enterRead(AtomicFile &inAtomicFile);
+};
+
+// Use this class to open an AtomicFile for writing.
+class AtomicFileWriteRef : public AtomicFileRef
+{
+public:
+    AtomicFileWriteRef(AtomicFile &inAtomicFile);
+    virtual ~AtomicFileWriteRef();
+    AtomicFile::VersionId commit() { mOpen = false; return mAtomicFile.commit(); }
+
+private:
+    static InitArg enterWrite(AtomicFile &inAtomicFile, AtomicFile::FileRef &outWriteFileRef);
+    AtomicFile::FileRef mFileRef;
+    bool mOpen;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_ATOMICFILE
+#pragma export off
+#endif
+
+#endif //_H_ATOMICFILE
diff --git a/cdsa/cdsa_utilities/Database.cpp b/cdsa/cdsa_utilities/Database.cpp
new file mode 100644
index 00000000..7821bc15
--- /dev/null
+++ b/cdsa/cdsa_utilities/Database.cpp
@@ -0,0 +1,231 @@
+/*
+ * 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.
+ */
+
+
+#ifdef __MWERKS__
+#define _CPP_DATABASE
+#endif
+#include <Security/Database.h>
+
+#include <Security/cssmerr.h>
+#include <Security/DbContext.h>
+#include <memory>
+
+DatabaseManager::DatabaseManager ()
+{
+}
+
+DatabaseManager::~DatabaseManager ()
+{
+}
+
+Database *
+DatabaseManager::get (const DbName &inDbName)
+{
+    StLock<Mutex> _(mDatabaseMapLock);
+    DatabaseMap::iterator anIterator = mDatabaseMap.find (inDbName);
+    if (anIterator == mDatabaseMap.end())
+    {
+        auto_ptr<Database> aDatabase(make(inDbName));
+        mDatabaseMap.insert(DatabaseMap::value_type(aDatabase->mDbName, aDatabase.get()));
+        return aDatabase.release();
+    }
+
+    return anIterator->second;
+}
+
+void
+DatabaseManager::removeIfUnused(Database &inDatabase)
+{
+    StLock<Mutex> _(mDatabaseMapLock);
+    if (!inDatabase.hasDbContexts())
+        mDatabaseMap.erase(inDatabase.mDbName);
+}
+
+DbContext &
+DatabaseManager::dbOpen(DatabaseSession &inDatabaseSession,
+                        const DbName &inDbName,
+                        CSSM_DB_ACCESS_TYPE inAccessRequest,
+                        const AccessCredentials *inAccessCred,
+                        const void *inOpenParameters)
+{
+    Database &aDatabase = *get(inDbName);
+    try
+    {
+        return aDatabase._dbOpen(inDatabaseSession, inAccessRequest, inAccessCred, inOpenParameters);
+    }
+    catch (...)
+    {
+        removeIfUnused(aDatabase);
+        throw;
+    }
+}
+
+DbContext &
+DatabaseManager::dbCreate(DatabaseSession &inDatabaseSession,
+                          const DbName &inDbName,
+                          const CSSM_DBINFO &inDBInfo,
+                          CSSM_DB_ACCESS_TYPE inAccessRequest,
+                          const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
+                          const void *inOpenParameters)
+{
+    Database &aDatabase = *get(inDbName);
+    try
+    {
+        return aDatabase._dbCreate(inDatabaseSession, inDBInfo, inAccessRequest,
+                                   inCredAndAclEntry, inOpenParameters);
+    }
+    catch (...)
+    {
+        removeIfUnused(aDatabase);
+        throw;
+    }
+}
+
+// Delete a DbContext instance created by calling dbOpen or dbCreate.
+void
+DatabaseManager::dbClose(DbContext &inDbContext)
+{
+    Database &aDatabase = inDbContext.mDatabase;
+    aDatabase._dbClose(inDbContext);
+    removeIfUnused(aDatabase);
+}
+
+// Delete a database.
+void
+DatabaseManager::dbDelete(DatabaseSession &inDatabaseSession,
+                          const DbName &inDbName,
+                          const AccessCredentials *inAccessCred)
+{
+    Database &aDatabase = *get(inDbName);
+    try
+    {
+        aDatabase.dbDelete(inDatabaseSession, inAccessCred);
+    }
+    catch (...)
+    {
+        removeIfUnused(aDatabase);
+        throw;
+    }
+
+    removeIfUnused(aDatabase);
+}
+
+// List all available databases.
+CSSM_NAME_LIST_PTR
+DatabaseManager::getDbNames(DatabaseSession &inDatabaseSession)
+{
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+DatabaseManager::freeNameList(DatabaseSession &inDatabaseSession,
+                  CSSM_NAME_LIST &inNameList)
+{
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+// Start of Database implementation.
+
+Database::Database (const DbName &inDbName)
+: mDbName(inDbName)
+{
+}
+
+Database::~Database ()
+{
+}
+
+bool
+Database::hasDbContexts()
+{
+    StLock<Mutex> _(mDbContextSetLock);
+    return !mDbContextSet.empty();
+}
+
+DbContext &
+Database::_dbOpen(DatabaseSession &inDatabaseSession,
+                  CSSM_DB_ACCESS_TYPE inAccessRequest,
+                  const AccessCredentials *inAccessCred,
+                  const void *inOpenParameters)
+{
+    auto_ptr<DbContext>aDbContext(makeDbContext(inDatabaseSession,
+                                                inAccessRequest,
+                                                inAccessCred,
+                                                inOpenParameters));
+    {
+        StLock<Mutex> _(mDbContextSetLock);
+        mDbContextSet.insert(aDbContext.get());
+        // Release the mDbContextSetLock
+    }
+
+    try
+    {
+        dbOpen(*aDbContext);
+    }
+    catch (...)
+    {
+        StLock<Mutex> _(mDbContextSetLock);
+        mDbContextSet.erase(aDbContext.get());
+        throw;
+    }
+
+    return *aDbContext.release();
+}
+
+DbContext &
+Database::_dbCreate(DatabaseSession &inDatabaseSession,
+                    const CSSM_DBINFO &inDBInfo,
+                    CSSM_DB_ACCESS_TYPE inAccessRequest,
+                    const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
+                    const void *inOpenParameters)
+{
+    auto_ptr<DbContext>aDbContext(makeDbContext(inDatabaseSession,
+                                                inAccessRequest,
+                                                (inCredAndAclEntry
+												 ? AccessCredentials::optional(inCredAndAclEntry->AccessCred)
+												 : NULL),
+                                                inOpenParameters));
+    {
+        StLock<Mutex> _(mDbContextSetLock);
+        mDbContextSet.insert(aDbContext.get());
+        // Release the mDbContextSetLock
+    }
+
+    try
+    {
+        dbCreate(*aDbContext, inDBInfo,
+                 inCredAndAclEntry ? &inCredAndAclEntry->InitialAclEntry : NULL);
+    }
+    catch (...)
+    {
+        StLock<Mutex> _(mDbContextSetLock);
+        mDbContextSet.erase(aDbContext.get());
+        throw;
+    }
+
+    return *aDbContext.release();
+}
+
+void
+Database::_dbClose(DbContext &dbContext)
+{
+    StLock<Mutex> _(mDbContextSetLock);
+    mDbContextSet.erase(&dbContext);
+    if (mDbContextSet.empty())
+        dbClose();
+}
diff --git a/cdsa/cdsa_utilities/Database.h b/cdsa/cdsa_utilities/Database.h
new file mode 100644
index 00000000..94a14052
--- /dev/null
+++ b/cdsa/cdsa_utilities/Database.h
@@ -0,0 +1,251 @@
+/*
+ * 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.
+ */
+
+
+#ifndef _DATABASE_H_
+#define _DATABASE_H_  1
+
+#include <Security/cssmacl.h>
+#include <Security/threading.h>
+#include <Security/DbName.h>
+#include <list>
+#include <map>
+#include <set>
+
+#ifdef _CPP_DATABASE
+# pragma export on
+#endif
+
+// @@@ Should not use using in headers.
+using namespace std;
+
+namespace Security
+{
+
+class Database;
+class DatabaseFactory;
+class DatabaseSession;
+class DbContext;
+
+/* DatabaseManager class.  */
+class DatabaseManager
+{
+	NOCOPY(DatabaseManager)
+public:
+    DatabaseManager ();
+    virtual ~DatabaseManager ();
+
+    // Create and return a new DbContext instance which is owned by us and must be discared by calling dbClose.
+    virtual DbContext &dbOpen(DatabaseSession &inDatabaseSession,
+                              const DbName &inDbName,
+                              CSSM_DB_ACCESS_TYPE inAccessRequest,
+                              const AccessCredentials *inAccessCred,
+                              const void *inOpenParameters);
+    virtual DbContext &dbCreate(DatabaseSession &inDatabaseSession,
+                                const DbName &inDbName,
+                                const CSSM_DBINFO &inDBInfo,
+                                CSSM_DB_ACCESS_TYPE inAccessRequest,
+                                const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
+                                const void *inOpenParameters);
+
+    // Delete a DbContext instance created by calling dbOpen or dbCreate.
+    virtual void dbClose(DbContext &inDbContext);
+
+    // Delete a database.
+    virtual void dbDelete(DatabaseSession &inDatabaseSession,
+                          const DbName &inDbName,
+                          const AccessCredentials *inAccessCred);
+
+    // List all available databases.
+    virtual CSSM_NAME_LIST_PTR getDbNames(DatabaseSession &inDatabaseSession);
+    virtual void freeNameList(DatabaseSession &inDatabaseSession,
+                              CSSM_NAME_LIST &inNameList);
+protected:
+    virtual void removeIfUnused(Database &inDatabase);
+    virtual Database *get (const DbName &inDbName); // Get existing instance or make a new one.
+    virtual Database *make (const DbName &inDbName) = 0; // Create a new database instance subclass must implement.
+private:
+    typedef map<DbName, Database *> DatabaseMap;
+    DatabaseMap mDatabaseMap;
+    Mutex mDatabaseMapLock;
+};
+
+
+/* Database is an abstract class.  Each Database subclass should implement all the
+   pure virtual methods listed below.  The constructor for a particular Database
+   subclass should create the Database object.  A subsequent call to dBOpen or
+   dBCreate should be is made.  This returns a DbContext.  All other methods take
+   a DbContext as an argument.
+ */
+class Database
+{
+public:
+    virtual void
+    dbCreate (DbContext &inDbContext, const CSSM_DBINFO &inDBInfo,
+              const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry) = 0;
+
+    // Don't override this method in subclasses.
+    virtual DbContext &
+    _dbCreate(DatabaseSession &inDatabaseSession,
+             const CSSM_DBINFO &inDBInfo,
+             CSSM_DB_ACCESS_TYPE inAccessRequest,
+             const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
+             const void *inOpenParameters);
+
+    virtual void
+    dbOpen (DbContext &inDbContext) = 0;
+
+    // Don't override this method in subclasses.
+    virtual DbContext &
+    _dbOpen (DatabaseSession &inDatabaseSession,
+            CSSM_DB_ACCESS_TYPE inAccessRequest,
+            const AccessCredentials *inAccessCred,
+            const void *inOpenParameters);
+
+    virtual void
+    dbClose () = 0;
+
+    // Don't override this method in subclasses.
+    virtual void
+    _dbClose (DbContext &dbContext);
+
+    virtual void
+    dbDelete(DatabaseSession &inDatabaseSession,
+             const AccessCredentials *inAccessCred) = 0;
+
+    virtual void
+    createRelation (DbContext &dbContext,
+                    CSSM_DB_RECORDTYPE inRelationID,
+                    const char *inRelationName,
+                    uint32 inNumberOfAttributes,
+                    const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
+                    uint32 inNumberOfIndexes,
+                    const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo) = 0;
+
+    virtual void
+    destroyRelation (DbContext &dbContext,
+                     CSSM_DB_RECORDTYPE inRelationID) = 0;
+
+    virtual void
+    authenticate(DbContext &dbContext,
+                 CSSM_DB_ACCESS_TYPE inAccessRequest,
+                 const AccessCredentials &inAccessCred) = 0;
+
+    virtual void
+    getDbAcl(DbContext &dbContext,
+             const CSSM_STRING *inSelectionTag,
+             uint32 &outNumberOfAclInfos,
+             CSSM_ACL_ENTRY_INFO_PTR &outAclInfos) = 0;
+
+    virtual void
+    changeDbAcl(DbContext &dbContext,
+                const AccessCredentials &inAccessCred,
+                const CSSM_ACL_EDIT &inAclEdit) = 0;
+
+    virtual void
+    getDbOwner(DbContext &dbContext, CSSM_ACL_OWNER_PROTOTYPE &outOwner) = 0;
+
+    virtual void
+    changeDbOwner(DbContext &dbContext,
+                  const AccessCredentials &inAccessCred,
+                  const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner) = 0;
+
+    virtual char *
+    getDbNameFromHandle (const DbContext &dbContext) const = 0;
+
+    virtual CSSM_DB_UNIQUE_RECORD_PTR
+    dataInsert (DbContext &dbContext,
+                CSSM_DB_RECORDTYPE RecordType,
+                const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+                const CssmData *inData) = 0;
+
+    virtual void
+    dataDelete (DbContext &dbContext,
+                const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier) = 0;
+
+    virtual void
+    dataModify (DbContext &dbContext,
+                CSSM_DB_RECORDTYPE RecordType,
+                CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier,
+                const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
+                const CssmData *inDataToBeModified,
+                CSSM_DB_MODIFY_MODE ModifyMode) = 0;
+
+    virtual CSSM_HANDLE
+    dataGetFirst (DbContext &dbContext,
+                  const DLQuery *inQuery,
+                  CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                  CssmData *inoutData,
+                  CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord) = 0;
+
+    virtual bool
+    dataGetNext (DbContext &dbContext,
+                 CSSM_HANDLE inResultsHandle,
+                 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                 CssmData *inoutData,
+                 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord) = 0;
+
+    virtual void
+    dataAbortQuery (DbContext &dbContext,
+                    CSSM_HANDLE inResultsHandle) = 0;
+
+    virtual void
+    dataGetFromUniqueRecordId (DbContext &dbContext,
+                               const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
+                               CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                               CssmData *inoutData) = 0;
+
+    virtual void
+    freeUniqueRecord (DbContext &dbContext,
+                      CSSM_DB_UNIQUE_RECORD &inUniqueRecord) = 0;
+					  
+	virtual void
+	passThrough(DbContext &dbContext,
+				uint32 passThroughId,
+				const void *inputParams,
+				void **outputParams) = 0;
+
+    Database (const DbName &inDbName);
+    virtual ~Database ();
+
+    virtual bool hasDbContexts();
+
+    // XXX @@@ Think about consequences of race conditions between DbOpen/DbCreate/DbDelete/DbClose
+    // on databases with the same name at the same time. 
+    //virtual DbContext &insertDbContext();
+    //virtual void removeDbContext(DbContext &inDbContext);
+
+    const DbName mDbName;
+protected:
+    // Subclasses must implement this method.
+    virtual DbContext *makeDbContext(DatabaseSession &inDatabaseSession,
+                                     CSSM_DB_ACCESS_TYPE inAccessRequest,
+                                     const AccessCredentials *inAccessCred,
+                                     const void *inOpenParameters) = 0;
+private:
+    typedef set<DbContext *> DbContextSet;
+    DbContextSet mDbContextSet;
+    Mutex mDbContextSetLock;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_DATABASE
+# pragma export off
+#endif
+
+#endif //_DATABASE_H_
diff --git a/cdsa/cdsa_utilities/DatabaseSession.cpp b/cdsa/cdsa_utilities/DatabaseSession.cpp
new file mode 100644
index 00000000..30e96edd
--- /dev/null
+++ b/cdsa/cdsa_utilities/DatabaseSession.cpp
@@ -0,0 +1,347 @@
+/*
+ * 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.
+ */
+
+
+//
+// DatabaseSession.cpp - DL Session.
+//
+#ifdef __MWERKS__
+#define _CPP_DATABASESESSION
+#endif
+#include <Security/DatabaseSession.h>
+
+#include <Security/Database.h>
+#include <Security/DbContext.h>
+#include <memory>
+
+using namespace std;
+
+//
+// Session constructor
+//
+DatabaseSession::DatabaseSession(DatabaseManager &inDatabaseManager)
+: mDatabaseManager(inDatabaseManager)
+{
+}
+
+DatabaseSession::~DatabaseSession()
+{
+}
+
+
+// Utility functions
+void
+DatabaseSession::GetDbNames(CSSM_NAME_LIST_PTR &outNameList)
+{
+	outNameList = mDatabaseManager.getDbNames (*this);
+}
+
+
+void
+DatabaseSession::FreeNameList(CSSM_NAME_LIST &inNameList)
+{
+	mDatabaseManager.freeNameList (*this, inNameList);
+}
+
+
+void
+DatabaseSession::DbDelete(const char *inDbName,
+                          const CSSM_NET_ADDRESS *inDbLocation,
+                          const AccessCredentials *inAccessCred)
+{
+    // The databaseManager will notify all its DbContext instances
+    // that the database is question is being deleted.
+    mDatabaseManager.dbDelete(*this, DbName(inDbName, CssmNetAddress::optional(inDbLocation)), inAccessCred);
+}
+
+// DbContext creation and destruction.
+void
+DatabaseSession::DbCreate(const char *inDbName,
+                          const CSSM_NET_ADDRESS *inDbLocation,
+                          const CSSM_DBINFO &inDBInfo,
+                          CSSM_DB_ACCESS_TYPE inAccessRequest,
+                          const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
+                          const void *inOpenParameters,
+                          CSSM_DB_HANDLE &outDbHandle)
+{
+	outDbHandle = CSSM_INVALID_HANDLE;	// CDSA 2.0 says to set this if we fail 
+    outDbHandle = insertDbContext(mDatabaseManager.dbCreate(*this,
+                                                            DbName(inDbName, CssmNetAddress::optional(inDbLocation)),
+                                                            inDBInfo,
+                                                            inAccessRequest,
+                                                            inCredAndAclEntry,
+                                                            inOpenParameters));
+
+}
+
+void
+DatabaseSession::DbOpen(const char *inDbName,
+                        const CSSM_NET_ADDRESS *inDbLocation,
+                        CSSM_DB_ACCESS_TYPE inAccessRequest,
+                        const AccessCredentials *inAccessCred,
+                        const void *inOpenParameters,
+                        CSSM_DB_HANDLE &outDbHandle)
+{
+	outDbHandle = CSSM_INVALID_HANDLE;	// CDSA 2.0 says to set this if we fail 
+    outDbHandle = insertDbContext(mDatabaseManager.dbOpen(*this,
+                                                          DbName(inDbName, CssmNetAddress::optional(inDbLocation)),
+                                                          inAccessRequest,
+                                                          inAccessCred,
+                                                          inOpenParameters));
+}
+
+CSSM_DB_HANDLE
+DatabaseSession::insertDbContext(DbContext &inDbContext)
+{
+    CSSM_DB_HANDLE aDbHandle;
+    try
+    {
+        aDbHandle = inDbContext.handle ();
+        StLock<Mutex> _(mDbContextMapLock);
+        mDbContextMap.insert(DbContextMap::value_type(aDbHandle, &inDbContext));
+    }
+    catch (...)
+    {
+        // Close the context
+        mDatabaseManager.dbClose(inDbContext);
+        throw;
+    }
+
+    return aDbHandle;
+}
+
+DbContext &
+DatabaseSession::findDbContext(CSSM_DB_HANDLE inDbHandle)
+{
+    StLock<Mutex> _(mDbContextMapLock);
+    DbContextMap::iterator it = mDbContextMap.find(inDbHandle);
+    if (it == mDbContextMap.end())
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_DB_HANDLE);
+    return *it->second;
+}
+
+void
+DatabaseSession::closeAll()
+{
+    StLock<Mutex> _(mDbContextMapLock);
+    for (DbContextMap::iterator it = mDbContextMap.begin();
+         it != mDbContextMap.end();
+         it++)
+    {
+        DbContext *aDbContext = it->second;
+        try
+        {
+            mDatabaseManager.dbClose(*aDbContext);
+            // This is done by the database itself which owns the context.
+            //delete aDbContext;
+        }
+        catch (...)
+        {
+            // Ignore exceptions since we want to close as many DBs as possible.
+            // XXX @@@ log an error or something.
+        }
+    }
+
+    mDbContextMap.clear();
+}
+
+// Operations using DbContext instances.
+void
+DatabaseSession::DbClose(CSSM_DB_HANDLE inDbHandle)
+{
+    StLock<Mutex> _(mDbContextMapLock);
+    DbContextMap::iterator it = mDbContextMap.find(inDbHandle);
+    if (it == mDbContextMap.end())
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_DB_HANDLE);
+    auto_ptr<DbContext> aDbContext(it->second);
+    mDbContextMap.erase(it);
+    mDatabaseManager.dbClose(*aDbContext);
+}
+
+void
+DatabaseSession::CreateRelation(CSSM_DB_HANDLE inDbHandle,
+                                CSSM_DB_RECORDTYPE inRelationID,
+                                const char *inRelationName,
+                                uint32 inNumberOfAttributes,
+                                const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
+                                uint32 inNumberOfIndexes,
+                                const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    return aDbContext.mDatabase.createRelation(aDbContext, inRelationID, inRelationName,
+                                                inNumberOfAttributes, inAttributeInfo,
+                                                inNumberOfIndexes, inIndexInfo);
+}
+
+void
+DatabaseSession::DestroyRelation(CSSM_DB_HANDLE inDbHandle,
+                                 CSSM_DB_RECORDTYPE inRelationID)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    return aDbContext.mDatabase.destroyRelation(aDbContext, inRelationID);
+}
+
+void
+DatabaseSession::Authenticate(CSSM_DB_HANDLE inDbHandle,
+                              CSSM_DB_ACCESS_TYPE inAccessRequest,
+                              const AccessCredentials &inAccessCred)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.authenticate(aDbContext, inAccessRequest, inAccessCred);
+}
+
+
+void
+DatabaseSession::GetDbAcl(CSSM_DB_HANDLE inDbHandle,
+                          const CSSM_STRING *inSelectionTag,
+                          uint32 &outNumberOfAclInfos,
+                          CSSM_ACL_ENTRY_INFO_PTR &outAclInfos)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.getDbAcl(aDbContext, inSelectionTag, outNumberOfAclInfos, outAclInfos);
+}
+
+void
+DatabaseSession::ChangeDbAcl(CSSM_DB_HANDLE inDbHandle,
+                             const AccessCredentials &inAccessCred,
+                             const CSSM_ACL_EDIT &inAclEdit)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.changeDbAcl(aDbContext, inAccessCred, inAclEdit);
+}
+
+void
+DatabaseSession::GetDbOwner(CSSM_DB_HANDLE inDbHandle,
+                            CSSM_ACL_OWNER_PROTOTYPE &outOwner)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.getDbOwner(aDbContext, outOwner);
+}
+
+void
+DatabaseSession::ChangeDbOwner(CSSM_DB_HANDLE inDbHandle,
+                               const AccessCredentials &inAccessCred,
+                               const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.changeDbOwner(aDbContext, inAccessCred, inNewOwner);
+}
+
+void
+DatabaseSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle,
+                                     char **outDbName)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    Required(outDbName) = aDbContext.mDatabase.getDbNameFromHandle(aDbContext);
+}
+
+void
+DatabaseSession::DataInsert(CSSM_DB_HANDLE inDbHandle,
+                            CSSM_DB_RECORDTYPE inRecordType,
+                            const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+                            const CssmData *inData,
+                            CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    outUniqueId = aDbContext.mDatabase.dataInsert(aDbContext, inRecordType, inAttributes, inData);
+}
+
+
+void
+DatabaseSession::DataDelete(CSSM_DB_HANDLE inDbHandle,
+                            const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.dataDelete(aDbContext, inUniqueRecordIdentifier);
+}
+
+
+void
+DatabaseSession::DataModify(CSSM_DB_HANDLE inDbHandle,
+                            CSSM_DB_RECORDTYPE inRecordType,
+                            CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier,
+                            const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
+                            const CssmData *inDataToBeModified,
+                            CSSM_DB_MODIFY_MODE inModifyMode)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.dataModify(aDbContext, inRecordType, inoutUniqueRecordIdentifier,
+                                     inAttributesToBeModified, inDataToBeModified, inModifyMode);
+}
+
+CSSM_HANDLE
+DatabaseSession::DataGetFirst(CSSM_DB_HANDLE inDbHandle,
+                              const DLQuery *inQuery,
+                              CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                              CssmData *inoutData,
+                              CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+	
+	return aDbContext.mDatabase.dataGetFirst(aDbContext, inQuery,
+		inoutAttributes, inoutData, outUniqueId);
+}
+
+bool
+DatabaseSession::DataGetNext(CSSM_DB_HANDLE inDbHandle,
+                             CSSM_HANDLE inResultsHandle,
+                             CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                             CssmData *inoutData,
+                             CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+
+	return aDbContext.mDatabase.dataGetNext(aDbContext, inResultsHandle, inoutAttributes,
+			inoutData, outUniqueRecord);
+}
+
+void
+DatabaseSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle,
+                                CSSM_HANDLE inResultsHandle)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.dataAbortQuery(aDbContext, inResultsHandle);
+}
+
+void
+DatabaseSession::DataGetFromUniqueRecordId(CSSM_DB_HANDLE inDbHandle,
+                                           const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
+                                           CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                                           CssmData *inoutData)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.dataGetFromUniqueRecordId(aDbContext, inUniqueRecord,
+                                                   inoutAttributes, inoutData);
+}
+
+void
+DatabaseSession::FreeUniqueRecord(CSSM_DB_HANDLE inDbHandle,
+                                  CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
+{
+    DbContext &aDbContext = findDbContext(inDbHandle);
+    aDbContext.mDatabase.freeUniqueRecord(aDbContext, inUniqueRecordIdentifier);
+}
+
+void
+DatabaseSession::PassThrough(CSSM_DB_HANDLE inDbHandle,
+                             uint32 passThroughId,
+                             const void *inputParams,
+                             void **outputParams)
+{
+	DbContext &aDbContext = findDbContext(inDbHandle);
+	aDbContext.mDatabase.passThrough(aDbContext, passThroughId, inputParams, outputParams);
+}
diff --git a/cdsa/cdsa_utilities/DatabaseSession.h b/cdsa/cdsa_utilities/DatabaseSession.h
new file mode 100644
index 00000000..31ed5763
--- /dev/null
+++ b/cdsa/cdsa_utilities/DatabaseSession.h
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+
+//
+// DatabaseSession.h - Framework for DL plugin modules
+//
+#ifndef _H_DATABASESESSION
+#define _H_DATABASESESSION
+
+#include <Security/DLabstractsession.h>
+
+#include <Security/cssmalloc.h>
+#include <Security/threading.h>
+#include <Security/cssmtype.h>
+#include <map>
+
+#if defined(_CPP_DATABASESESSION)
+# pragma export on
+#endif
+
+namespace Security
+{
+
+class DatabaseManager;
+class DbContext;
+
+// A class providing some of the base Database (DL and MDS) functionality.
+class DatabaseSession: public DLAbstractPluginSession, public CssmAllocator
+{
+public:
+    DatabaseSession(DatabaseManager &inDatabaseManager);
+    virtual ~DatabaseSession();
+
+    void GetDbNames(CSSM_NAME_LIST_PTR &NameList);
+    void FreeNameList(CSSM_NAME_LIST &NameList);
+    void DbDelete(const char *DbName,
+                  const CSSM_NET_ADDRESS *DbLocation,
+                  const AccessCredentials *AccessCred);
+    void DbCreate(const char *DbName,
+                  const CSSM_NET_ADDRESS *DbLocation,
+                  const CSSM_DBINFO &DBInfo,
+                  CSSM_DB_ACCESS_TYPE AccessRequest,
+                  const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+                  const void *OpenParameters,
+                  CSSM_DB_HANDLE &DbHandle);
+    void DbOpen(const char *DbName,
+                const CSSM_NET_ADDRESS *DbLocation,
+                CSSM_DB_ACCESS_TYPE AccessRequest,
+                const AccessCredentials *AccessCred,
+                const void *OpenParameters,
+                CSSM_DB_HANDLE &DbHandle);
+    void DbClose(CSSM_DB_HANDLE DBHandle);
+    void CreateRelation(CSSM_DB_HANDLE DBHandle,
+                        CSSM_DB_RECORDTYPE RelationID,
+                        const char *RelationName,
+                        uint32 NumberOfAttributes,
+                        const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &pAttributeInfo,
+                        uint32 NumberOfIndexes,
+                        const CSSM_DB_SCHEMA_INDEX_INFO &pIndexInfo);
+    void DestroyRelation(CSSM_DB_HANDLE DBHandle,
+                         CSSM_DB_RECORDTYPE RelationID);
+
+    void Authenticate(CSSM_DB_HANDLE DBHandle,
+                      CSSM_DB_ACCESS_TYPE AccessRequest,
+                      const AccessCredentials &AccessCred);
+    void GetDbAcl(CSSM_DB_HANDLE DBHandle,
+                  const CSSM_STRING *SelectionTag,
+                  uint32 &NumberOfAclInfos,
+                  CSSM_ACL_ENTRY_INFO_PTR &AclInfos);
+    void ChangeDbAcl(CSSM_DB_HANDLE DBHandle,
+                     const AccessCredentials &AccessCred,
+                     const CSSM_ACL_EDIT &AclEdit);
+    void GetDbOwner(CSSM_DB_HANDLE DBHandle,
+                    CSSM_ACL_OWNER_PROTOTYPE &Owner);
+    void ChangeDbOwner(CSSM_DB_HANDLE DBHandle,
+                       const AccessCredentials &AccessCred,
+                       const CSSM_ACL_OWNER_PROTOTYPE &NewOwner);
+    void GetDbNameFromHandle(CSSM_DB_HANDLE DBHandle,
+                             char **DbName);
+    void DataInsert(CSSM_DB_HANDLE DBHandle,
+                    CSSM_DB_RECORDTYPE RecordType,
+                    const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes,
+                    const CssmData *Data,
+                    CSSM_DB_UNIQUE_RECORD_PTR &UniqueId);
+    void DataDelete(CSSM_DB_HANDLE DBHandle,
+                    const CSSM_DB_UNIQUE_RECORD &UniqueRecordIdentifier);
+    void DataModify(CSSM_DB_HANDLE DBHandle,
+                    CSSM_DB_RECORDTYPE RecordType,
+                    CSSM_DB_UNIQUE_RECORD &UniqueRecordIdentifier,
+                    const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified,
+                    const CssmData *DataToBeModified,
+                    CSSM_DB_MODIFY_MODE ModifyMode);
+    CSSM_HANDLE DataGetFirst(CSSM_DB_HANDLE DBHandle,
+                             const DLQuery *Query,
+                             CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                             CssmData *Data,
+                             CSSM_DB_UNIQUE_RECORD_PTR &UniqueId);
+    bool DataGetNext(CSSM_DB_HANDLE DBHandle,
+                     CSSM_HANDLE ResultsHandle,
+                     CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                     CssmData *Data,
+                     CSSM_DB_UNIQUE_RECORD_PTR &UniqueId);
+    void DataAbortQuery(CSSM_DB_HANDLE DBHandle,
+                        CSSM_HANDLE ResultsHandle);
+    void DataGetFromUniqueRecordId(CSSM_DB_HANDLE DBHandle,
+                                   const CSSM_DB_UNIQUE_RECORD &UniqueRecord,
+                                   CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                                   CssmData *Data);
+    void FreeUniqueRecord(CSSM_DB_HANDLE DBHandle,
+                          CSSM_DB_UNIQUE_RECORD &UniqueRecord);
+    void PassThrough(CSSM_DB_HANDLE DBHandle,
+                     uint32 PassThroughId,
+                     const void *InputParams,
+                     void **OutputParams);
+
+    DatabaseManager &mDatabaseManager;
+protected:
+    void closeAll();
+private:
+    CSSM_DB_HANDLE insertDbContext(DbContext &dbContext);
+    DbContext &findDbContext(CSSM_DB_HANDLE inDbHandle);
+
+    typedef std::map<CSSM_DB_HANDLE, DbContext *> DbContextMap;
+    DbContextMap mDbContextMap;
+    Mutex mDbContextMapLock;
+};
+
+} // end namespace Security
+
+#if defined(_CPP_DATABASESESSION)
+# pragma export off
+#endif
+
+#endif //_H_DATABASESESSION
diff --git a/cdsa/cdsa_utilities/DbContext.cpp b/cdsa/cdsa_utilities/DbContext.cpp
new file mode 100644
index 00000000..ebe270bc
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbContext.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+
+#ifdef __MWERKS__
+#define _CPP_DBCONTEXT
+#endif
+#include <Security/DbContext.h>
+
+#include <Security/Database.h>
+
+#include <Security/cssmerr.h>
+#include <Security/utilities.h>
+
+DbContext::DbContext (Database &inDatabase,
+                      DatabaseSession &inDatabaseSession,
+                      CSSM_DB_ACCESS_TYPE inAccessRequest,
+                      const CSSM_ACCESS_CREDENTIALS *inAccessCred) :
+    mDatabase (inDatabase),
+    mDatabaseSession (inDatabaseSession),
+    mAccessRequest (inAccessRequest)
+{
+    // XXX Copy the ACL.
+    //mAccessCred = inAccessCred;
+}
+
+DbContext::~DbContext ()
+{
+    //delete mAccessCred;
+    // XXX How do we delete these?
+}
+
+#if 0
+CSSM_HANDLE
+DbContext::dataGetFirst(const DLQuery *inQuery,
+                        CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                        CssmData *inoutData,
+                        CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
+{
+    auto_ptr<DbQuery> aQuery(mDatabase.makeQuery(const DLQuery *inQuery));
+    try
+    {
+        mDatabase.dataGetNext(*aQuery, inoutAttributes, inoutData, outUniqueRecord);
+
+        StLock<Mutex> _(mDbQuerySet);
+        mDbQuerySet.insert(aQuery.get());
+    }
+    catch(...)
+    {
+        mDatabase.dataAbortQuery(*aQuery);
+        throw;
+    }
+
+    return reinterpret_cast<CSSM_HANDLE>(aQuery.release());
+}
+
+void
+DbContext::dataGetNext(CSSM_HANDLE inResultsHandle,
+                       CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                       CssmData *inoutData,
+                       CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
+{
+    DbQuery *aQuery = reinterpret_cast<DbQuery *>(inResultsHandle);
+    {
+        StLock<Mutex> _(mDbQuerySet);
+        DbQuerySet::iterator it = mDbQuerySet.find(aQuery);
+        if (it == mDbContextMap.end())
+            CssmError::throwMe(CSSMERR_DL_INVALID_RESULTS_HANDLE);
+    }
+
+    try
+    {
+        mDatabase.dataGetNext(*aQuery, inoutAttributes, inoutData, outUniqueRecord);
+    }
+    catch(...)
+    {
+        {
+            StLock<Mutex> _(mDbQuerySet);
+            mDbQuerySet.erase(aQuery);
+        }
+        try
+        {
+            mDatabase.dataAbortQuery(*aQuery);
+        }
+        catch(...) {}
+        delete aQuery;
+        throw;
+    }
+}
+
+void
+DbContext::dataAbortQuery(CSSM_HANDLE inResultsHandle)
+{
+    DbQuery *aQuery = reinterpret_cast<DbQuery *>(inResultsHandle);
+    {
+        StLock<Mutex> _(mDbQuerySet);
+        DbQuerySet::iterator it = mDbQuerySet.find(aQuery);
+        if (it == mDbContextMap.end())
+            CssmError::throwMe(CSSMERR_DL_INVALID_RESULTS_HANDLE);
+        mDbContextMap.erase(it);
+    }
+
+    try
+    {
+        mDatabase.dataAbortQuery(*aQuery);
+    }
+    catch(...)
+    {
+        delete aQuery;
+        throw;
+    }
+    delete aQuery;
+}
+#endif
diff --git a/cdsa/cdsa_utilities/DbContext.h b/cdsa/cdsa_utilities/DbContext.h
new file mode 100644
index 00000000..986ddcab
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbContext.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+#ifndef _DBCONTEXT_H_
+#define _DBCONTEXT_H_  1
+
+#include <Security/Database.h>
+#include <Security/handleobject.h>
+
+#ifdef _CPP_DBCONTEXT
+# pragma export on
+#endif
+
+namespace Security
+{
+
+class DatabaseSession;
+
+class DbContext : public HandleObject
+{
+	NOCOPY(DbContext)
+public:
+    Database &mDatabase;
+    DatabaseSession &mDatabaseSession;
+
+    DbContext(Database &inDatabase,
+              DatabaseSession &inDatabaseSession,
+              CSSM_DB_ACCESS_TYPE inAccessRequest,
+              const CSSM_ACCESS_CREDENTIALS *inAccessCred);
+
+    virtual ~DbContext();
+
+    CSSM_HANDLE
+    dataGetFirst(const DLQuery *inQuery,
+                      CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                      CssmData *inoutData,
+                      CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord);
+
+    void
+    dataGetNext(CSSM_HANDLE inResultsHandle,
+                CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                CssmData *inoutData,
+                CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord);
+
+    void
+    dataAbortQuery(CSSM_HANDLE inResultsHandle);
+private:
+    CSSM_DB_ACCESS_TYPE mAccessRequest;
+    CSSM_ACCESS_CREDENTIALS *mAccessCred;
+    //typedef set<DbQuery *> DbQuerySet;
+    //DbQuerySet mDbQuerySet;
+    //Mutex mDbQuerySetLock;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_DBCONTEXT
+# pragma export off
+#endif
+
+#endif //_DBCONTEXT_H_
diff --git a/cdsa/cdsa_utilities/DbIndex.cpp b/cdsa/cdsa_utilities/DbIndex.cpp
new file mode 100644
index 00000000..0b2a5edc
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbIndex.cpp
@@ -0,0 +1,471 @@
+/*
+ * 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.
+ */
+
+
+//
+// DbIndex.cpp
+//
+
+#include "DbIndex.h"
+#include "AppleDatabase.h"
+#include <stdio.h>
+
+DbQueryKey::DbQueryKey(const DbConstIndex &index)
+:	mIndex(index),
+	mTableSection(index.table().getTableSection())
+{
+}
+
+// Perform a less-than comparison between two keys. An offset of zero
+// means to use the key provided as part of the query; otherwise, the
+// key comes from the database.
+
+int
+DbKeyComparator::operator () (uint32 offset1, uint32 offset2) const
+{
+	ReadSection rs1, rs2;
+	const ReadSection *key1, *key2;
+
+	// get the read sections to compare
+	
+	if (offset1 == 0)
+		key1 = &mKey.mKeyData;
+	else {
+		rs1 = mKey.mTableSection.subsection(offset1);
+		key1 = &rs1;
+	}
+	
+	if (offset2 == 0)
+		key2 = &mKey.mKeyData;
+	else {
+		rs2 = mKey.mTableSection.subsection(offset2);
+		key2 = &rs2;
+	}
+
+	// compare the values of the attributes in the keys
+	
+	uint32 valueOffset1 = sizeof(uint32), valueOffset2 = sizeof(uint32);
+	
+	for (uint32 i = 0; i < mKey.mNumKeyValues; i++) {
+		const MetaAttribute &metaAttribute = *mKey.mIndex.mAttributes[i];
+		auto_ptr<DbValue> value1(metaAttribute.createValue(*key1, valueOffset1));
+		auto_ptr<DbValue> value2(metaAttribute.createValue(*key2, valueOffset2));
+		
+		if (metaAttribute.evaluate(value1.get(), value2.get(), CSSM_DB_LESS_THAN))
+			return true;
+			
+		else if (metaAttribute.evaluate(value2.get(), value1.get(), CSSM_DB_LESS_THAN))
+			return false;
+	}
+
+	// if we are here, the keys are equal
+
+	return false;
+}
+
+// Comparison used when inserting an item into an index, but otherwise
+// similar to the version above.
+
+bool
+DbIndexKey::operator < (const DbIndexKey &other) const
+{
+	// compare the values of the attributes in the keys
+	
+	uint32 numAttributes = mIndex.mAttributes.size();
+	uint32 valueOffset1 = 0, valueOffset2 = 0;
+	
+	for (uint32 i = 0; i < numAttributes; i++) {
+		const MetaAttribute &metaAttribute = *mIndex.mAttributes[i];
+		auto_ptr<DbValue> value1(metaAttribute.createValue(mKeySection.subsection(mKeyRange),
+			valueOffset1));
+		auto_ptr<DbValue> value2(metaAttribute.createValue(other.mKeySection.subsection(other.mKeyRange),
+			valueOffset2));
+		
+		if (metaAttribute.evaluate(value1.get(), value2.get(), CSSM_DB_LESS_THAN))
+			return true;
+			
+		else if (metaAttribute.evaluate(value2.get(), value1.get(), CSSM_DB_LESS_THAN))
+			return false;
+	}
+
+	// if we are here, the keys are equal
+
+	return false;
+}
+
+DbIndex::DbIndex(const MetaRecord &metaRecord, uint32 indexId, bool isUniqueIndex)
+:	mMetaRecord(metaRecord),
+	mIndexId(indexId),
+	mIsUniqueIndex(isUniqueIndex)
+{
+}
+
+// Append an attribute to the vector used to form index keys.
+
+void
+DbIndex::appendAttribute(uint32 attributeId)
+{
+	CSSM_DB_ATTRIBUTE_INFO info;
+	info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
+	info.Label.AttributeID = attributeId;
+
+	mAttributes.push_back(&(mMetaRecord.metaAttribute(info)));
+}
+
+// Construct a new read-only index.
+
+DbConstIndex::DbConstIndex(const Table &table, uint32 indexId, bool isUniqueIndex)
+:	DbIndex(table.getMetaRecord(), indexId, isUniqueIndex),
+	mTable(table)
+{
+}
+
+DbConstIndex::DbConstIndex(const Table &table, const ReadSection &indexSection)
+:	DbIndex(table.getMetaRecord(), indexSection.at(AtomSize), indexSection.at(2 * AtomSize)),
+	mTable(table)
+{
+	uint32 numAttributes = indexSection.at(3 * AtomSize);
+
+	for (uint32 i = 0; i < numAttributes; i++) {
+		uint32 attributeId = indexSection.at((4 + i) * AtomSize);
+		appendAttribute(attributeId);
+	}
+
+	uint32 offset = (4 + numAttributes) * AtomSize;
+	uint32 numRecords = indexSection.at(offset);
+	offset += AtomSize;
+	mKeyOffsetVector.overlay(numRecords,
+		reinterpret_cast<const uint32 *>(indexSection.range(Range(offset, numRecords * AtomSize))));
+
+	offset += numRecords * AtomSize;
+	mRecordNumberVector.overlay(numRecords,
+		reinterpret_cast<const uint32 *>(indexSection.range(Range(offset, numRecords * AtomSize))));
+}
+
+// Check to see if this index can be used to perform a given query, based on
+// the attributes used in the query and their order. They must be a prefix
+// of the index key attributes. If there is more than one attribute, all of the
+// operators must be EQUAL and the conjunctive must be AND; this is needed to
+// ensure that the results are a contiguous segment of the index. On success,
+// the appropriate index key is generated from the query.
+
+bool
+DbConstIndex::matchesQuery(const CSSM_QUERY &query, DbQueryKey *&queryKey) const
+{
+	uint32 numPredicates = query.NumSelectionPredicates;
+
+	if (numPredicates == 0 || numPredicates > mAttributes.size())
+		return false;
+	
+	// determine which index attributes are used in the query
+	
+	auto_array<uint32> attributeUsed(mAttributes.size());
+	for (uint32 i = 0; i < mAttributes.size(); attributeUsed[i++] = ~0UL);
+	
+	for (uint32 i = 0, j; i < numPredicates; i++) {
+		const MetaAttribute &tableAttribute =
+			mMetaRecord.metaAttribute(query.SelectionPredicate[i].Attribute.Info);
+		
+		for (j = 0; j < mAttributes.size(); j++) {
+			if (tableAttribute.attributeId() == mAttributes[j]->attributeId()) {
+				if (attributeUsed[j] != ~0UL)
+					// invalid query: attribute appears twice
+					CssmError::throwMe(CSSMERR_DL_INVALID_QUERY);
+				else {
+					// the jth index component is the ith predicate in the query
+					attributeUsed[j] = i;
+					break;
+				}
+			}
+		}
+		
+		if (j == mAttributes.size()) {
+			// the predicate attribute is not in the index, so return failure
+			return false;
+		}
+	}
+	
+	// check that the query predicates form a prefix of the index key, which means that
+	// the first N index components are the N query predicates in some order
+	
+	uint32 lastIndex;
+	for (lastIndex = mAttributes.size() - 1; (lastIndex >= 0) && (attributeUsed[lastIndex] == ~0UL);
+		lastIndex--);
+		
+	if (lastIndex != numPredicates - 1)
+		return false;
+
+	// if there is more than one predicate, the conjunctive must be AND and all the
+	// operators must be EQUAL for the compound index to be useful
+	
+	CSSM_DB_OPERATOR op;
+	
+	if (numPredicates > 1) {
+		if (query.Conjunctive != CSSM_DB_AND)
+			return false;
+			
+		for (uint32 i = 0; i < numPredicates; i++)
+			if (query.SelectionPredicate[i].DbOperator != CSSM_DB_EQUAL)
+				return false;
+				
+		op = CSSM_DB_EQUAL;
+	}
+		
+	// for a single predicate, check the operator
+	
+	else {
+		op = query.SelectionPredicate[0].DbOperator;
+		if (op != CSSM_DB_EQUAL && op != CSSM_DB_LESS_THAN && op != CSSM_DB_GREATER_THAN)
+			return false;
+	}
+
+	// ok, after all that, we can use this index, so generate an object used as a key
+	// for this query on this index
+	
+	queryKey = new DbQueryKey(*this);
+	queryKey->mNumKeyValues = numPredicates;
+	queryKey->mOp = op;
+	
+	uint32 keyLength = sizeof(uint32);
+	for (uint32 i = 0; i < numPredicates; i++)
+		mAttributes[i]->packValue(queryKey->mKeyData, keyLength,
+			*(query.SelectionPredicate[attributeUsed[i]].Attribute.Value));
+	queryKey->mKeyData.put(0, keyLength - sizeof(uint32));
+	queryKey->mKeyData.size(keyLength);
+	
+	return true;
+}
+
+// Perform a query on an index, returning the iterators that bound the
+// returned results.
+
+void
+DbConstIndex::performQuery(const DbQueryKey &queryKey,
+	DbIndexIterator &begin, DbIndexIterator &end) const
+{
+	DbKeyComparator cmp(queryKey);
+	
+	switch (queryKey.mOp) {
+	
+	case CSSM_DB_EQUAL:
+		{
+			pair<DbIndexIterator, DbIndexIterator> result;
+			result = equal_range(mKeyOffsetVector.begin(), mKeyOffsetVector.end(),
+				DbQueryKey::kQueryValue, cmp);
+			begin = result.first;
+			end = result.second;
+		}
+		break;
+		
+	case CSSM_DB_LESS_THAN:
+		begin = mKeyOffsetVector.begin();
+		end = lower_bound(begin, mKeyOffsetVector.end(), DbQueryKey::kQueryValue, cmp);
+		break;
+		
+	case CSSM_DB_GREATER_THAN:
+		end = mKeyOffsetVector.end();
+		begin = lower_bound(mKeyOffsetVector.begin(), end, DbQueryKey::kQueryValue, cmp);
+		break;
+		
+	default:
+		CssmError::throwMe(CSSMERR_DL_INTERNAL_ERROR);
+		break;
+	}
+}
+
+// Given an iterator as returned by performQuery(), return the read section for the record.
+
+ReadSection
+DbConstIndex::getRecordSection(DbIndexIterator iter) const
+{
+	uint32 recordNumber = mRecordNumberVector[iter - mKeyOffsetVector.begin()];
+	return mTable.getRecordSection(recordNumber);
+}
+
+// Construct a mutable index from a read-only index.
+
+DbMutableIndex::DbMutableIndex(const DbConstIndex &index)
+:	DbIndex(index),
+	mIndexDataSize(0)
+{
+	// go through the const index and copy all the entries into the
+	// mutable index
+	
+	const ReadSection &tableSection = index.mTable.getTableSection();
+	
+	uint32 numRecords = index.mKeyOffsetVector.size();
+	for (uint32 i = 0; i < numRecords; i++) {
+		uint32 recordNumber = index.mRecordNumberVector.at(i);
+		uint32 keyOffset = index.mKeyOffsetVector.at(i);
+		uint32 keySize = tableSection.at(keyOffset);
+		DbIndexKey key(tableSection, Range(keyOffset + AtomSize, keySize), *this);
+		mMap.insert(IndexMap::value_type(key, recordNumber));
+	}
+}
+
+DbMutableIndex::DbMutableIndex(const MetaRecord &metaRecord, uint32 indexId, bool isUniqueIndex)
+:	DbIndex(metaRecord, indexId, isUniqueIndex)
+{
+}
+
+DbMutableIndex::~DbMutableIndex()
+{
+}
+
+// Remove all entries for a record from an index. This is not an ideal implementation,
+// since it walks the entire index. In a perfect world, we'd generate all the record's
+// keys and lookup matching entries, deleting only those with the correct record number.
+// But this is not a perfect world.
+
+void
+DbMutableIndex::removeRecord(uint32 recordNumber)
+{
+	IndexMap::iterator it, temp;
+	for (it = mMap.begin(); it != mMap.end(); ) {
+		temp = it; it++;
+		if (temp->second == recordNumber)
+			mMap.erase(temp);
+	}
+}
+
+// Insert a record into an index.
+
+void
+DbMutableIndex::insertRecord(uint32 recordNumber, const ReadSection &packedRecord)
+{
+	// The common case is that each indexed attribute has a single value in
+	// the record; detect and handle this separately since we can avoid an
+	// expensive recursive technique.
+	
+	uint32 numAttributes = mAttributes.size();
+	bool allSingleValued = true;
+	
+	for (uint32 i = 0; i < numAttributes; i++) {
+		uint32 numValues = mAttributes[i]->getNumberOfValues(packedRecord);
+		if (numValues == 0) {
+			// record does not have value required by index; for a unique index,
+			// this is an error, otherwise just don't index the record
+			if (mIsUniqueIndex)
+				CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
+			else
+				return;
+		}
+		else if (numValues > 1) {
+			allSingleValued = false;
+			break;
+		}
+	}
+	
+	if (allSingleValued)
+		insertRecordSingle(recordNumber, packedRecord);
+		
+	else {
+		// recursively build all appropriate index keys, and add them to the map
+		WriteSection keyData;
+		insertRecordMulti(recordNumber, packedRecord, 0, keyData, 0);
+	}
+}
+
+void
+DbMutableIndex::insertRecordSingle(uint32 recordNumber, const ReadSection &packedRecord)
+{
+	// append the key values to the index data
+	uint32 offset = mIndexDataSize;
+	for (uint32 i = 0; i < mAttributes.size(); i++)
+		mAttributes[i]->copyValueBytes(0, packedRecord, mIndexData, mIndexDataSize);
+	mIndexData.size(mIndexDataSize);
+		
+	// make an index key
+	DbIndexKey key(mIndexData, Range(offset, mIndexDataSize - offset), *this);
+	
+	// if this is a unique index, check for a record with the same key
+	if (mIsUniqueIndex && (mMap.find(key) != mMap.end()))
+		// the key already exists, which is an error
+		CssmError::throwMe(CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA);
+		
+	// insert the item into the map
+	mMap.insert(IndexMap::value_type(key, recordNumber));
+}
+
+void
+DbMutableIndex::insertRecordMulti(uint32 recordNumber, const ReadSection &packedRecord,
+	uint32 attributeIndex, WriteSection &keyData, uint32 keySize)
+{
+	const MetaAttribute &metaAttribute = *(mAttributes[attributeIndex]);
+	uint32 numValues = metaAttribute.getNumberOfValues(packedRecord);
+
+	for (uint32 i = 0; i < numValues; i++) {
+	
+		uint32 newKeySize = keySize;
+		metaAttribute.copyValueBytes(i, packedRecord, keyData, newKeySize);
+		
+		if (attributeIndex == mAttributes.size()) {
+			uint32 offset = mIndexDataSize;
+			mIndexDataSize = mIndexData.put(mIndexDataSize, newKeySize, keyData.address());
+			mIndexData.size(mIndexDataSize);
+
+			DbIndexKey key(mIndexData, Range(offset, mIndexDataSize - offset), *this);
+			if (mIsUniqueIndex && (mMap.find(key) != mMap.end()))
+				CssmError::throwMe(CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA);
+
+			mMap.insert(IndexMap::value_type(key, recordNumber));
+		}
+		else
+			// otherwise, recurse with the rest of the attributes
+			insertRecordMulti(recordNumber, packedRecord, attributeIndex + 1, keyData, newKeySize);
+	}
+}
+
+uint32
+DbMutableIndex::writeIndex(WriteSection &ws, uint32 offset)
+{
+	IndexMap::iterator it;
+	
+	// reserve space for the index size
+	uint32 sizeOffset = offset;
+	offset += AtomSize;
+	
+	offset = ws.put(offset, mIndexId);
+	offset = ws.put(offset, mIsUniqueIndex ? 1 : 0);
+	
+	offset = ws.put(offset, mAttributes.size());
+	for (uint32 i = 0; i < mAttributes.size(); i++)
+		offset = ws.put(offset, mAttributes[i]->attributeId());
+
+	offset = ws.put(offset, mMap.size());
+	
+	// reserve space for the array of offsets to key data
+	uint32 keyPtrOffset = offset;
+	offset += AtomSize * mMap.size();
+	
+	// write the array of record numbers
+	for (it = mMap.begin(); it != mMap.end(); it++) {
+		offset = ws.put(offset, it->second);
+	}
+		
+	// write the key data
+	for (it = mMap.begin(); it != mMap.end(); it++) {
+		keyPtrOffset = ws.put(keyPtrOffset, offset);
+		offset = ws.put(offset, it->first.keySize());
+		offset = ws.put(offset, it->first.keySize(), it->first.keyData());
+	}
+	
+	// write the index size
+	ws.put(sizeOffset, offset - sizeOffset);
+
+	return offset;	
+}
diff --git a/cdsa/cdsa_utilities/DbIndex.h b/cdsa/cdsa_utilities/DbIndex.h
new file mode 100644
index 00000000..cb93855f
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbIndex.h
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+
+//
+// DbIndex.h
+//
+
+#ifndef _H_APPLEDL_DBINDEX
+#define _H_APPLEDL_DBINDEX
+
+#include "MetaRecord.h"
+
+namespace Security
+{
+
+class Table;
+class DbConstIndex;
+class DbIndex;
+
+typedef constVector<uint32> DbOffsetVector;
+
+typedef DbOffsetVector::const_iterator DbIndexIterator;
+
+//
+// An object that represents a key being used as part of a query.
+//
+
+class DbQueryKey
+{
+	friend class DbConstIndex;
+	friend class DbKeyComparator;
+	
+public:
+	DbQueryKey(const DbConstIndex &index);
+	
+	static const uint32 kQueryValue = 0;
+	
+private:
+	WriteSection mKeyData;
+	uint32 mNumKeyValues;
+	const DbConstIndex &mIndex;
+	const ReadSection &mTableSection;
+	CSSM_DB_OPERATOR mOp;
+};
+
+//
+// An object which performs comparison between keys, either stored
+// in a database or provided as part of a query.
+//
+
+class DbKeyComparator
+{
+public:
+	DbKeyComparator(const DbQueryKey &key) : mKey(key) {}
+
+	int operator () (uint32 keyOffset1, uint32 keyOffset2) const;
+	
+private:
+	const DbQueryKey &mKey;
+};
+
+//
+// A key as stored in an index.
+//
+
+class DbIndexKey {
+public:
+	DbIndexKey(const ReadSection &key, const Range &keyRange, const DbIndex &index)
+		: mKeySection(key), mKeyRange(keyRange), mIndex(index) {}
+
+	bool operator < (const DbIndexKey &other) const;
+	
+	uint32 keySize() const { return mKeyRange.mSize; }
+	const uint8 *keyData() const { return mKeySection.range(mKeyRange); }
+	
+private:
+	// the key data, expressed as a subsection of a read section
+	const ReadSection &mKeySection;
+	Range mKeyRange;
+	
+	// the index that knows how to interpret the key data
+	const DbIndex &mIndex;
+};
+
+// Base class containing stuff shared between const and mutable indexes.
+
+class DbIndex
+{
+	friend class DbIndexKey;
+	
+public:
+	uint32 indexId() const { return mIndexId; }
+
+	// append an attribute to the index key
+	void appendAttribute(uint32 attributeId);
+
+protected:
+	DbIndex(const MetaRecord &metaRecord, uint32 indexId, bool isUniqueIndex);
+
+	// meta record for table associated with this index
+	const MetaRecord &mMetaRecord;
+
+	// vector of indexed attributes
+	typedef vector<const MetaAttribute *> AttributeVector;
+	AttributeVector mAttributes;
+	
+	uint32 mIndexId;
+	bool mIsUniqueIndex;
+};
+
+// Read-only index.
+
+class DbConstIndex : public DbIndex
+{
+	friend class DbMutableIndex;
+	friend class DbQueryKey;
+	friend class DbKeyComparator;
+
+public:
+	DbConstIndex(const Table &table, uint32 indexId, bool isUniqueIndex);
+	DbConstIndex(const Table &table, const ReadSection &indexSection);
+	
+	const Table &table() const { return mTable; }
+
+	// check if this index can be used for a given query, and if so, generate
+	// the appropriate index key from the query
+	bool matchesQuery(const CSSM_QUERY &query, DbQueryKey *&queryKey) const;
+
+	// perform a query on the index
+	void performQuery(const DbQueryKey &queryKey,
+		DbIndexIterator &begin, DbIndexIterator &end) const;
+		
+	// given an iterator as returned by performQuery(), return the read section for the record
+	ReadSection getRecordSection(DbIndexIterator iter) const;
+
+private:
+	// sorted vector of offsets to index key data
+	DbOffsetVector mKeyOffsetVector;
+	
+	// vector, in same order as key vector, of corresponding record numbers
+	DbOffsetVector mRecordNumberVector;
+
+	const Table &mTable;
+};
+
+// A memory-resident index that can be modified, but not used for a query.
+
+class DbMutableIndex : public DbIndex
+{
+public:
+	DbMutableIndex(const DbConstIndex &index);
+	DbMutableIndex(const MetaRecord &metaRecord, uint32 indexId, bool isUniqueIndex);
+	~DbMutableIndex();
+	
+	// insert a record into the index
+	void insertRecord(uint32 recordNumber, const ReadSection &packedRecord);
+	
+	// remove a record from the index
+	void removeRecord(uint32 recordNumber);
+	
+	// write the index
+	uint32 writeIndex(WriteSection &ws, uint32 offset);
+	
+private:
+	// helper methods called by insertRecord()
+	void insertRecordSingle(uint32 recordOffset, const ReadSection &packedRecord);
+	void insertRecordMulti(uint32 recordOffset, const ReadSection &packedRecord,
+		uint32 attributeIndex, WriteSection &keyData, uint32 keySize);
+
+	// a single write section which stores generated index key data
+	WriteSection mIndexData;
+	uint32 mIndexDataSize;
+	
+	// a map from index keys to record numbers
+	typedef multimap<DbIndexKey, uint32> IndexMap;
+	IndexMap mMap;
+};
+
+} // end namespace Security
+
+#endif // _H_APPLEDL_DBINDEX
diff --git a/cdsa/cdsa_utilities/DbName.cpp b/cdsa/cdsa_utilities/DbName.cpp
new file mode 100644
index 00000000..166288d2
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbName.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+
+#ifdef __MWERKS__
+#define _CPP_DBNAME
+#endif
+#include <Security/DbName.h>
+
+#include <Security/utilities.h>
+
+CssmNetAddress::CssmNetAddress(CSSM_DB_RECORDTYPE inAddressType, const CssmData &inAddress)
+{
+    AddressType = inAddressType;
+    Address.Length = inAddress.Length;
+    if (Address.Length > 0)
+    {
+        Address.Data = new uint8[Address.Length];
+        memcpy (Address.Data, inAddress.Data, Address.Length);
+    }
+    else
+        Address.Data = NULL;
+}
+
+CssmNetAddress::CssmNetAddress(const CSSM_NET_ADDRESS &other)
+{
+    AddressType = other.AddressType;
+    Address.Length = other.Address.Length;
+    if (Address.Length > 0)
+    {
+        Address.Data = new uint8[Address.Length];
+        memcpy (Address.Data, other.Address.Data, Address.Length);
+    }
+    else
+        Address.Data = NULL;
+}
+
+CssmNetAddress::~CssmNetAddress()
+{
+    if (Address.Length > 0)
+        delete Address.Data;
+}
+
+DbName::DbName(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
+:mDbName(&Required(inDbName)),
+mDbLocation(nil)
+{
+    if (inDbLocation)
+    {
+        mDbLocation = new CssmNetAddress(*inDbLocation);
+    }
+}
+
+DbName::DbName(const DbName &other)
+:mDbName(other.mDbName),
+mDbLocation(nil)
+{
+    if (other.mDbLocation)
+    {
+        mDbLocation = new CssmNetAddress(*other.mDbLocation);
+    }
+}
+
+DbName &
+DbName::operator =(const DbName &other)
+{
+	mDbName = other.mDbName;
+    if (other.mDbLocation)
+    {
+        mDbLocation = new CssmNetAddress(*other.mDbLocation);
+    }
+
+	return *this;
+}
+
+DbName::~DbName()
+{
+    if (mDbLocation)
+    {
+        delete mDbLocation;
+    }
+}
diff --git a/cdsa/cdsa_utilities/DbName.h b/cdsa/cdsa_utilities/DbName.h
new file mode 100644
index 00000000..bf5e18dd
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbName.h
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+#ifndef _DBNAME_H_
+#define _DBNAME_H_  1
+
+#include <Security/utilities.h>
+#include <Security/walkers.h>
+#include <Security/cssmtype.h>
+#include <string>
+
+#ifdef _CPP_DBNAME
+# pragma export on
+#endif
+
+// @@@ Should not use using in headers.
+using namespace std;
+
+namespace Security
+{
+
+//----------------------------------------------------------------
+//typedef struct cssm_net_address {
+//    CSSM_NET_ADDRESS_TYPE AddressType;
+//    CSSM_DATA Address;
+//} CSSM_NET_ADDRESS, *CSSM_NET_ADDRESS_PTR;
+//----------------------------------------------------------------
+
+// XXX TODO: Make CssmNetAddress use a factory to constuct netadrress objects based on CSSM_NET_ADDRESS_TYPE!
+class CssmNetAddress : public PodWrapper<CssmNetAddress, CSSM_NET_ADDRESS>
+{
+public:
+    // Create a CssmNetAddress wrapper.  Copies inAddress.Data
+    CssmNetAddress(CSSM_DB_RECORDTYPE inAddressType, const CssmData &inAddress);
+    CssmNetAddress(const CSSM_NET_ADDRESS &other);
+    ~CssmNetAddress();
+    CSSM_DB_RECORDTYPE addressType() const { return AddressType; }
+    const CssmData &address() const { return CssmData::overlay(Address); }
+    bool operator <(const CssmNetAddress &other) const
+    {
+        return AddressType != other.AddressType ? AddressType < other.AddressType : address() < other.address();
+    }
+};
+
+class DbName
+{
+public:
+    DbName (const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
+    DbName(const DbName &other);
+    DbName &operator =(const DbName &other);
+    ~DbName ();
+    const string &dbName() const { return mDbName; }
+    const CssmNetAddress *dbLocation() const { return mDbLocation; }
+    bool operator <(const DbName &other) const
+    {
+        // If mDbNames are not equal return whether our mDbName is less than others mDbName.
+        if (mDbName != other.mDbName)
+            return mDbName < other.mDbName;
+
+        // DbNames are equal so check for pointer equality of DbLocations
+        if (mDbLocation == other.mDbLocation)
+            return false;
+
+        // If either DbLocations is nil the one that is nil is less than the other.
+        if (mDbLocation == nil || other.mDbLocation == nil)
+            return mDbLocation < other.mDbLocation;
+
+        // Return which mDbLocation is smaller.
+        return *mDbLocation < *other.mDbLocation;
+    }
+	bool operator ==(const DbName &other) const
+	{ return (!(*this < other)) && (!(other < *this)); }
+	bool operator !=(const DbName &other) const
+	{ return *this < other || other < *this; }
+
+private:
+    string mDbName;
+    CssmNetAddress *mDbLocation;
+};
+
+
+namespace DataWalkers
+{
+
+template<class Action>
+CssmNetAddress *walk(Action &operate, CssmNetAddress * &addr)
+{
+    operate(addr);
+    walk(operate, addr->Address);
+    return addr;
+}
+
+} // end namespace DataWalkers
+
+} // end namespace Security
+
+#ifdef _CPP_DBNAME
+# pragma export off
+#endif
+
+#endif //_DBNAME_H_
diff --git a/cdsa/cdsa_utilities/DbQuery.cpp b/cdsa/cdsa_utilities/DbQuery.cpp
new file mode 100644
index 00000000..0a4bc938
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbQuery.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+
+#ifdef __MWERKS__
+#define _CPP_DBQUERY
+#endif
+#include <Security/DbQuery.h>
+
+DbQuery::DbQuery ()
+{
+}
+
+DbQuery::~DbQuery ()
+{
+}
diff --git a/cdsa/cdsa_utilities/DbQuery.h b/cdsa/cdsa_utilities/DbQuery.h
new file mode 100644
index 00000000..77ea5aeb
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbQuery.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+
+#ifndef _DBQUERY_H_
+#define _DBQUERY_H_  1
+
+#include <Security/handleobject.h>
+
+#ifdef _CPP_DBQUERY
+# pragma export on
+#endif
+
+namespace Security
+{
+
+class DbQuery: public HandleObject
+{
+    NOCOPY(DbQuery);
+public:
+    DbQuery ();
+    virtual ~DbQuery ();
+};
+
+} // end namespace Security
+
+#ifdef _CPP_DBQUERY
+# pragma export off
+#endif
+
+#endif // _DBQUERY_H_
diff --git a/cdsa/cdsa_utilities/DbValue.cpp b/cdsa/cdsa_utilities/DbValue.cpp
new file mode 100644
index 00000000..4532c179
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbValue.cpp
@@ -0,0 +1,554 @@
+/*
+ * 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.
+ */
+
+
+//
+// DbValue.cpp
+//
+
+#include "DbValue.h"
+
+//
+// DbValue
+//
+
+DbValue::~DbValue()
+{
+}
+
+//
+// UInt32Value
+//
+
+UInt32Value::UInt32Value(const ReadSection &rs, uint32 &offset)
+:	BasicValue<uint32>(rs.at(offset))
+{
+	offset += size();
+}
+
+UInt32Value::UInt32Value(const CSSM_DATA &data)
+{
+	switch (data.Length)
+	{
+		case 1:
+			mValue = *reinterpret_cast<uint8 *>(data.Data);
+			break;
+		case 2:
+			mValue = *reinterpret_cast<uint16 *>(data.Data);
+			break;
+		case 4:
+			mValue = *reinterpret_cast<uint32 *>(data.Data);
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
+	}
+}
+
+UInt32Value::~UInt32Value()
+{
+}
+
+void
+UInt32Value::pack(WriteSection &ws, uint32 &offset) const
+{
+	offset = ws.put(offset, mValue);
+}
+
+//
+// SInt32Value
+//
+
+SInt32Value::SInt32Value(const ReadSection &rs, uint32 &offset)
+:	BasicValue<sint32>(static_cast<sint32>(rs.at(offset)))
+{
+	offset += size();
+}
+
+SInt32Value::SInt32Value(const CSSM_DATA &data)
+{
+	switch (data.Length)
+	{
+		case 1:
+			mValue = *reinterpret_cast<sint8 *>(data.Data);
+			break;
+		case 2:
+			mValue = *reinterpret_cast<sint16 *>(data.Data);
+			break;
+		case 4:
+			mValue = *reinterpret_cast<sint32 *>(data.Data);
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
+	}
+}
+
+SInt32Value::~SInt32Value()
+{
+}
+
+void
+SInt32Value::pack(WriteSection &ws, uint32 &offset) const
+{
+	offset = ws.put(offset, static_cast<uint32>(mValue));
+}
+
+//
+// DoubleValue
+//
+
+DoubleValue::DoubleValue(const ReadSection &rs, uint32 &offset)
+{
+	Range r(offset, size());
+	mValue = *reinterpret_cast<const double *>(rs.range(r));
+	offset += size();
+}
+
+DoubleValue::DoubleValue(const CSSM_DATA &data)
+{
+	switch (data.Length)
+	{
+		case 4:
+			mValue = *reinterpret_cast<float *>(data.Data);
+			break;
+		case 8:
+			mValue = *reinterpret_cast<double *>(data.Data);
+			break;
+		default:
+			CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
+	}
+}
+
+DoubleValue::~DoubleValue()
+{
+}
+
+void
+DoubleValue::pack(WriteSection &ws, uint32 &offset) const
+{
+	offset = ws.put(offset, size(), bytes());
+}
+
+//
+// BlobValue
+//
+
+BlobValue::BlobValue(const ReadSection &rs, uint32 &offset)
+{
+	Length = rs.at(offset);
+	Data = const_cast<uint8 *>(rs.range(Range(offset + AtomSize, Length)));
+	offset = ReadSection::align(offset + Length + AtomSize);
+}
+
+BlobValue::BlobValue(const CSSM_DATA &data)
+:	CssmData(CssmData::overlay(data))
+{
+}
+
+BlobValue::~BlobValue()
+{
+}
+
+void
+BlobValue::pack(WriteSection &ws, uint32 &offset) const
+{
+	offset = ws.put(offset, Length);
+	offset = ws.put(offset, Length, Data);
+}
+
+BlobValue::Comparator::~Comparator()
+{
+}
+
+int
+BlobValue::Comparator::operator () (const uint8 *ptr1, const uint8 *ptr2, uint32 length)
+{
+	return memcmp(ptr1, ptr2, length);
+}
+
+bool
+BlobValue::evaluate(const BlobValue &other, CSSM_DB_OPERATOR op) const
+{
+	return evaluate(*this, other, op, Comparator());
+}
+
+bool
+BlobValue::evaluate(const CssmData &inData1, const CssmData &inData2, CSSM_DB_OPERATOR op,
+	Comparator compare)
+{
+	uint32 length1 = inData1.Length, length2 = inData2.Length;
+	const uint8 *data1 = inData1.Data;
+	const uint8 *data2 = inData2.Data;
+	
+	switch (op) {
+	
+	case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
+		if (length1 > length2)
+            return false;
+        length2 = length1;
+        goto DB_EQUAL;
+		
+	case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
+        if (length1 > length2)
+            return false;
+		data2 += (length2 - length1);
+		length2 = length1;
+        // dropthrough...
+
+    case CSSM_DB_EQUAL:
+	DB_EQUAL:
+        if (length1 != length2)
+            return false;
+        if (length1 == 0)
+            return true;
+		return compare(data1, data2, length1) == 0;
+
+    case CSSM_DB_NOT_EQUAL:
+		if (length1 != length2)
+			return true;
+		if (length1 == 0)
+			return false;
+        return compare(data1, data2, length1) != 0;
+
+    case CSSM_DB_LESS_THAN:
+    case CSSM_DB_GREATER_THAN:
+    {
+        uint32 length = min(length1, length2);
+		int result = (length == 0) ? 0 : compare(data1, data2, length);
+		
+		if (result < 0 || (result == 0 && length1 < length2))
+			return op == CSSM_DB_LESS_THAN;
+		else if (result > 0 || (result == 0 && length1 > length2))
+			return op == CSSM_DB_GREATER_THAN;
+		break;
+	}
+
+    case CSSM_DB_CONTAINS:
+        if (length1 > length2)
+            return false;
+        if (length1 == 0)
+            return true;
+        // Both buffers are at least 1 byte long.
+        for (const uint8 *data = data2; data + length1 <= data2 + length2; data++)
+			if (compare(data1, data, length1) == 0)
+				return true;
+		break;
+
+    default:
+        CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
+    }
+
+    return false;
+}
+
+//
+// TimeDateValue
+//
+
+TimeDateValue::TimeDateValue(const ReadSection &rs, uint32 &offset)
+{
+	Length = kTimeDateSize;
+	Data = const_cast<uint8 *>(rs.range(Range(offset, Length)));
+	offset = ReadSection::align(offset + Length);
+}
+
+TimeDateValue::TimeDateValue(const CSSM_DATA &data)
+:	BlobValue(data)
+{
+	if (Length != kTimeDateSize || !isValidDate())
+		CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
+}
+
+TimeDateValue::~TimeDateValue()
+{
+}
+
+void
+TimeDateValue::pack(WriteSection &ws, uint32 &offset) const
+{
+	offset = ws.put(offset, Length, Data);
+}
+
+bool
+TimeDateValue::isValidDate() const
+{
+	if (Length != kTimeDateSize || Data[kTimeDateSize - 1] != 0 ||
+		Data[kTimeDateSize - 2] != 'Z')
+		return false;
+		
+	for (uint32 i = 0; i < kTimeDateSize - 2; i++)
+		if (!isdigit(Data[i]))
+			return false;
+			
+	uint32 month = rangeValue(4, 2);
+	if (month < 1 || month > 12)
+		return false;
+		
+	uint32 day = rangeValue(6, 2);
+	if (day < 1 || day > 31)
+		return false;
+		
+	uint32 hour = rangeValue(8, 2);
+	if (hour < 0 || hour > 23)
+		return false;
+		
+	uint32 minute = rangeValue(10, 2);
+	if (minute < 0 || minute > 59)
+		return false;
+
+	uint32 second = rangeValue(12, 2);
+	if (second < 0 || second > 59)
+		return false;		
+
+	return true;
+}
+
+uint32
+TimeDateValue::rangeValue(uint32 start, uint32 length) const
+{
+	uint32 value = 0;
+	for (uint32 i = 0; i < length; i++)
+		value = value * 10 + Data[start + i] - '0';
+	return value;
+}
+
+//
+// StringValue
+//
+
+StringValue::StringValue(const ReadSection &rs, uint32 &offset)
+:	BlobValue(rs, offset)
+{
+}
+
+StringValue::StringValue(const CSSM_DATA &data)
+:	BlobValue(data)
+{
+}
+
+StringValue::~StringValue()
+{
+}
+
+int
+StringValue::Comparator::operator () (const uint8 *ptr1, const uint8 *ptr2, uint32 length)
+{
+	return strncmp(reinterpret_cast<const char *>(ptr1),
+		reinterpret_cast<const char *>(ptr2), length);
+}
+
+bool
+StringValue::evaluate(const StringValue &other, CSSM_DB_OPERATOR op) const
+{
+	return BlobValue::evaluate(*this, other, op, StringValue::Comparator());
+}
+
+//
+// BigNumValue
+//
+
+BigNumValue::BigNumValue(const ReadSection &rs, uint32 &offset)
+:	BlobValue(rs, offset)
+{
+}
+
+BigNumValue::BigNumValue(const CSSM_DATA &data)
+:	BlobValue(data)
+{
+	// remove trailing zero bytes
+	while (Length > 1 && Data[Length - 1] == 0)
+		Length--;
+		
+	// if the number is zero (positive or negative), make the length zero
+	if (Length == 1 && (Data[0] & ~kSignBit) == 0)
+		Length = 0;
+}
+
+BigNumValue::~BigNumValue()
+{
+}
+
+// Walk the contents of two equal-sized bignums, moving backward
+// from the high-order bytes, and return the comparison result
+// ala memcmp.
+
+int
+BigNumValue::compare(const uint8 *a, const uint8 *b, int length)
+{
+	for (int diff, i = length - 1; i >= 1; i--)
+		if (diff = a[i] - b[i])
+			return diff;
+
+	// for the last (i.e. first) byte, mask out the sign bit
+	return (a[0] & ~kSignBit) - (b[0] & ~kSignBit);
+}
+
+// Compare two bignums, assuming they are in canonical form (i.e.,
+// no bytes containing trailing zeros.
+
+bool
+BigNumValue::evaluate(const BigNumValue &other, CSSM_DB_OPERATOR op) const
+{
+	uint32 length1 = Length, length2 = other.Length;
+	uint8 sign1 = length1 ? (Data[0] & kSignBit) : 0;
+	uint8 sign2 = length2 ? (other.Data[0] & kSignBit) : 0;
+	
+	switch (op)
+	{
+	case CSSM_DB_EQUAL:
+	case CSSM_DB_NOT_EQUAL:
+		return BlobValue::evaluate(other, op);
+		
+	case CSSM_DB_LESS_THAN:
+		if (sign1 ^ sign2)
+			// different signs: return true iff left value is the negative one
+			return sign1;
+		else if (length1 != length2)
+			// in canonical form, shorter numbers have smaller absolute value
+			return sign1 ? (length1 > length2) : (length1 < length2);
+		else {
+			// same length, same sign...
+			int c = compare(Data, other.Data, length1);
+			return sign1 ? (c > 0) : (c < 0);
+		}
+		break;
+		
+	case CSSM_DB_GREATER_THAN:
+		if (sign1 ^ sign2)
+			return sign2;
+		else if (length1 != length2)
+			return sign1 ? (length1 < length2) : (length1 > length2);
+		else {
+			int c = compare(Data, other.Data, length1);
+			return sign1 ? (c < 0) : (c > 0);
+		}
+		break;
+		
+	case CSSM_DB_CONTAINS:
+	case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
+	case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
+	default:
+		CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
+	}
+}
+
+//
+// MultiUInt32Value
+//
+
+MultiUInt32Value::MultiUInt32Value(const ReadSection &rs, uint32 &offset)
+{
+	// this is relatively expensive, since it copies the data from the
+	// read section to get the endianness correct
+
+	mNumValues = rs.at(offset);
+	mValues = new uint32[mNumValues];
+	
+	for (uint32 i = 0; i < mNumValues; i++)
+		mValues[i] = rs.at(offset + (i + 1) * AtomSize);
+	
+	offset = ReadSection::align(offset + (mNumValues + 1) * AtomSize);
+	mOwnsValues = true;
+}
+
+MultiUInt32Value::MultiUInt32Value(const CSSM_DATA &data)
+{
+	if (data.Length & (sizeof(uint32) - 1))
+		CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
+		
+	mNumValues = data.Length / sizeof(uint32);
+	mValues = reinterpret_cast<uint32 *>(data.Data);
+	mOwnsValues = false;
+}
+
+MultiUInt32Value::~MultiUInt32Value()
+{
+	if (mOwnsValues)
+		delete [] mValues;
+}
+
+void
+MultiUInt32Value::pack(WriteSection &ws, uint32 &offset) const
+{
+	offset = ws.put(offset, mNumValues);
+	for (uint32 i = 0; i < mNumValues; i++)
+		offset = ws.put(offset, mValues[i]);
+}
+
+static inline int
+uint32cmp(const uint32 *a, const uint32 *b, uint32 length)
+{
+	return memcmp(a, b, length * sizeof(uint32));
+}
+
+bool
+MultiUInt32Value::evaluate(const MultiUInt32Value &other, CSSM_DB_OPERATOR op) const
+{
+	uint32 length1 = mNumValues, length2 = other.mNumValues;
+	const uint32 *values1 = mValues;
+	const uint32 *values2 = other.mValues;
+	
+	switch (op)
+	{
+	case CSSM_DB_EQUAL:					
+		if (length1 == length2)
+			return uint32cmp(values1, values2, length1) == 0;
+		break;
+		
+	case CSSM_DB_NOT_EQUAL:
+		if (length1 != length2 || uint32cmp(values1, values2, length1))
+			return true;
+		break;
+
+	case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
+		if (length1 <= length2)
+			return uint32cmp(values1, values2, length1) == 0;
+		break;
+		
+	case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
+		if (length1 <= length2)
+			return uint32cmp(values1, values2 + (length2 - length1), length1) == 0;
+		break;
+		
+	case CSSM_DB_CONTAINS:
+		if (length1 <= length2) {
+		
+			if (length1 == 0)
+				return true;
+				
+			for (const uint32 *values = values2; values + length1 < values2 + length2; values++)
+				if (uint32cmp(values1, values, length1) == 0)
+					return true;
+		}
+		break;
+		
+	case CSSM_DB_LESS_THAN:
+		// this is not required by the spec, but is required to sort indexes over
+		// multi uint32 keys...
+		if (length1 < length2)
+			return true;
+		else if (length1 == length2)
+			return uint32cmp(values1, values2, length1) < 0;
+		break;
+
+	default:
+		CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
+	}
+	
+	return false;
+}
+
+
diff --git a/cdsa/cdsa_utilities/DbValue.h b/cdsa/cdsa_utilities/DbValue.h
new file mode 100644
index 00000000..78d1de4f
--- /dev/null
+++ b/cdsa/cdsa_utilities/DbValue.h
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ */
+
+
+//
+// DbValue.h
+//
+
+#ifndef _H_APPLEDL_DBVALUE
+#define _H_APPLEDL_DBVALUE
+
+#include "ReadWriteSection.h"
+
+#include <Security/cssmdata.h>
+#include <Security/cssmdb.h>
+#include <Security/cssmerr.h>
+#include <map>
+#include <vector>
+
+namespace Security
+{
+
+//
+// DbValue -- A base class for all types of database values.
+//
+class DbValue
+{
+public:
+	virtual ~DbValue();
+};
+
+// A collection of subclasses of DbValue that work for simple
+// data types, e.g. uint32, sint32, and double, that have
+// the usual C comparison and sizeof operations. Defining this
+// template saves typing below.
+
+template <class T>
+class BasicValue : public DbValue
+{
+public:
+	BasicValue() {}
+	BasicValue(T value) : mValue(value) {}
+
+	bool evaluate(const BasicValue<T> &other, CSSM_DB_OPERATOR op) const
+	{
+		switch (op) {
+
+		case CSSM_DB_EQUAL:
+			return mValue == other.mValue;
+			
+		case CSSM_DB_NOT_EQUAL:
+			return mValue != other.mValue;
+			
+		case CSSM_DB_LESS_THAN:
+			return mValue < other.mValue;
+
+		case CSSM_DB_GREATER_THAN:
+			return mValue > other.mValue;			
+
+		default:
+			CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
+			return false;
+		}
+	}
+
+	size_t size() const { return sizeof(T); }
+	size_t size(const ReadSection &rs, uint32 offset) const { return size(); }
+	const uint8 *bytes() const { return reinterpret_cast<const uint8 *>(&mValue); }
+
+protected:
+	T mValue;
+};
+
+// Actual useful subclasses of DbValue as instances of BasicValue.
+// Note that all of these require a constructor of the form
+// (const ReadSection &, uint32 &offset) that advances the offset
+// to just after the value.
+
+class UInt32Value : public BasicValue<uint32>
+{
+public:
+	UInt32Value(const ReadSection &rs, uint32 &offset);		
+	UInt32Value(const CSSM_DATA &data);
+	virtual ~UInt32Value();
+	void pack(WriteSection &ws, uint32 &offset) const;
+};
+
+class SInt32Value : public BasicValue<sint32>
+{
+public:
+	SInt32Value(const ReadSection &rs, uint32 &offset);		
+	SInt32Value(const CSSM_DATA &data);
+	virtual ~SInt32Value();
+	void pack(WriteSection &ws, uint32 &offset) const;
+};
+
+class DoubleValue : public BasicValue<double>
+{
+public:
+	DoubleValue(const ReadSection &rs, uint32 &offset);		
+	DoubleValue(const CSSM_DATA &data);
+	virtual ~DoubleValue();
+	void pack(WriteSection &ws, uint32 &offset) const;
+};
+
+// Subclasses of Value for more complex types.
+
+class BlobValue : public DbValue, public CssmData
+{
+public:
+	BlobValue() {}
+	BlobValue(const ReadSection &rs, uint32 &offset);		
+	BlobValue(const CSSM_DATA &data);
+	virtual ~BlobValue();
+	void pack(WriteSection &ws, uint32 &offset) const;
+	bool evaluate(const BlobValue &other, CSSM_DB_OPERATOR op) const;
+
+	size_t size() const { return Length; }
+	const uint8 *bytes() const { return Data; }
+	
+protected:
+	class Comparator {
+	public:
+		virtual ~Comparator();
+		virtual int operator () (const uint8 *ptr1, const uint8 *ptr2, uint32 length);
+	};
+
+	static bool evaluate(const CssmData &data1, const CssmData &data2, CSSM_DB_OPERATOR op,
+		Comparator compare);
+};
+
+class TimeDateValue : public BlobValue
+{
+public:
+	enum { kTimeDateSize = 16 };
+
+	TimeDateValue(const ReadSection &rs, uint32 &offset);		
+	TimeDateValue(const CSSM_DATA &data);
+	virtual ~TimeDateValue();
+	void pack(WriteSection &ws, uint32 &offset) const;
+
+	bool isValidDate() const;
+	
+private:
+	uint32 rangeValue(uint32 start, uint32 length) const;
+};
+
+class StringValue : public BlobValue
+{
+public:
+	StringValue(const ReadSection &rs, uint32 &offset);		
+	StringValue(const CSSM_DATA &data);
+	virtual ~StringValue();
+	bool evaluate(const StringValue &other, CSSM_DB_OPERATOR op) const;
+	
+private:
+	class Comparator : public BlobValue::Comparator {
+	public:
+		virtual int operator () (const uint8 *ptr1, const uint8 *ptr2, uint32 length);
+	};
+
+};
+
+class BigNumValue : public BlobValue
+{
+public:
+	static const uint8 kSignBit = 0x80;
+
+	BigNumValue(const ReadSection &rs, uint32 &offset);		
+	BigNumValue(const CSSM_DATA &data);
+	virtual ~BigNumValue();
+	bool evaluate(const BigNumValue &other, CSSM_DB_OPERATOR op) const;
+
+private:
+	static int compare(const uint8 *a, const uint8 *b, int length);
+};
+
+class MultiUInt32Value : public DbValue
+{
+public:
+	MultiUInt32Value(const ReadSection &rs, uint32 &offset);		
+	MultiUInt32Value(const CSSM_DATA &data);
+	virtual ~MultiUInt32Value();
+	void pack(WriteSection &ws, uint32 &offset) const;
+	bool evaluate(const MultiUInt32Value &other, CSSM_DB_OPERATOR op) const;
+
+	size_t size() const { return mNumValues * sizeof(uint32); }
+	const uint8 *bytes() const { return reinterpret_cast<uint8 *>(mValues); }
+	
+private:
+	uint32 mNumValues;
+	uint32 *mValues;
+	bool mOwnsValues;
+};
+
+} // end namespace Security
+
+#endif // _H_APPLEDL_DBVALUE
+
diff --git a/cdsa/cdsa_utilities/MetaAttribute.cpp b/cdsa/cdsa_utilities/MetaAttribute.cpp
new file mode 100644
index 00000000..0f45b0e1
--- /dev/null
+++ b/cdsa/cdsa_utilities/MetaAttribute.cpp
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+
+//
+// MetaAttribute.cpp
+//
+
+#include "MetaAttribute.h"
+#include "MetaRecord.h"
+
+MetaAttribute::~MetaAttribute()
+{
+}
+
+// Construct an instance of an appropriate subclass of MetaAttribute
+// based on the given format.
+
+MetaAttribute *
+MetaAttribute::create(Format format, uint32 attributeIndex,
+	uint32 attributeId)
+{
+	switch (format)
+	{
+		case CSSM_DB_ATTRIBUTE_FORMAT_STRING:
+			return new TypedMetaAttribute<StringValue>(format, attributeIndex, attributeId);
+
+		case CSSM_DB_ATTRIBUTE_FORMAT_SINT32:
+			return new TypedMetaAttribute<SInt32Value>(format, attributeIndex, attributeId);
+			
+		case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
+			return new TypedMetaAttribute<UInt32Value>(format, attributeIndex, attributeId);
+
+		case CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM:
+			return new TypedMetaAttribute<BigNumValue>(format, attributeIndex, attributeId);
+			
+		case CSSM_DB_ATTRIBUTE_FORMAT_REAL:
+			return new TypedMetaAttribute<DoubleValue>(format, attributeIndex, attributeId);
+
+		case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE:
+			return new TypedMetaAttribute<TimeDateValue>(format, attributeIndex, attributeId);
+
+		case CSSM_DB_ATTRIBUTE_FORMAT_BLOB:
+			return new TypedMetaAttribute<BlobValue>(format, attributeIndex, attributeId);
+			
+		case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
+			return new TypedMetaAttribute<MultiUInt32Value>(format, attributeIndex, attributeId);
+														
+	    case CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX:
+		default:
+			CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_FIELD_FORMAT);
+	}
+}
+
+void
+MetaAttribute::packNumberOfValues(WriteSection &ws, uint32 numValues, uint32 &valueOffset) const
+{
+	uint32 offset = MetaRecord::OffsetAttributeOffsets + mAttributeIndex * AtomSize;
+	
+	if (numValues == 0) {
+		// a zero offset means the attribute has no values
+		ws.put(offset, 0);
+	}
+	else if (numValues == 1) {
+		// setting the low bit of the offset means that there is exactly one value
+		 ws.put(offset, valueOffset | 1);
+	}
+	else {
+		// write the offset, then write the number of values at that position
+		ws.put(offset, valueOffset);
+		valueOffset = ws.put(valueOffset, numValues);
+	}
+}
+
+void
+MetaAttribute::unpackNumberOfValues(const ReadSection &rs, uint32 &numValues,
+	uint32 &valueOffset) const
+{
+	uint32 offset = MetaRecord::OffsetAttributeOffsets + mAttributeIndex * AtomSize;
+	valueOffset = rs[offset];
+	
+	if (valueOffset == 0)
+		// a zero offset means no values
+		numValues = 0;
+	else if (valueOffset & 1) {
+		// setting the LSB means exactly one value
+		valueOffset ^= 1;
+		numValues = 1;
+	}
+	else {
+		// otherwise, the number of values is at the offset, and the values follow
+		numValues = rs[valueOffset];
+		valueOffset += AtomSize;
+	}
+}
+
+void
+MetaAttribute::packAttribute(WriteSection &ws, uint32 &valueOffset, uint32 numValues,
+	const CSSM_DATA *values) const
+{
+	packNumberOfValues(ws, numValues, valueOffset);
+	for (uint32 i = 0; i < numValues; i++)
+		packValue(ws, valueOffset, values[i]);
+}
+
+void
+MetaAttribute::unpackAttribute(const ReadSection &rs, CssmAllocator &allocator,
+	uint32 &numValues, CSSM_DATA *&values) const
+{
+	uint32 valueOffset;
+	unpackNumberOfValues(rs, numValues, valueOffset);
+	
+	values = reinterpret_cast<CSSM_DATA *>(allocator.malloc(numValues * sizeof(CSSM_DATA)));
+	
+	for (uint32 i = 0; i < numValues; i++)
+		unpackValue(rs, valueOffset, values[i], allocator);
+}
+
+uint32
+MetaAttribute::getNumberOfValues(const ReadSection &rs) const
+{
+	uint32 numValues, valueOffset;
+	unpackNumberOfValues(rs, numValues, valueOffset);
+	return numValues;
+}
+
+void
+MetaAttribute::copyValueBytes(uint32 valueIndex, const ReadSection &rs, WriteSection &ws,
+	uint32 &writeOffset) const
+{
+	uint32 numValues, valueOffset;
+	unpackNumberOfValues(rs, numValues, valueOffset);
+
+	// skip bytes before the desired value
+	for (uint32 i = 0; i < valueIndex; i++)
+		skipValue(rs, valueOffset);
+		
+	// copy the value bytes into the write section
+	copyValue(rs, valueOffset, ws, writeOffset);
+}
diff --git a/cdsa/cdsa_utilities/MetaAttribute.h b/cdsa/cdsa_utilities/MetaAttribute.h
new file mode 100644
index 00000000..755b0eae
--- /dev/null
+++ b/cdsa/cdsa_utilities/MetaAttribute.h
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+
+//
+// MetaAttribute.h
+//
+
+#ifndef _H_APPLEDL_METAATTRIBUTE
+#define _H_APPLEDL_METAATTRIBUTE
+
+#include "DbValue.h"
+#include <memory>
+
+namespace Security
+{
+
+// A base class for all meta attributes.
+
+class MetaAttribute
+{
+public:
+	typedef CSSM_DB_ATTRIBUTE_FORMAT Format;
+	
+	virtual ~MetaAttribute();
+	
+	// construct an appropriate subclass of MetaAttribute
+	static MetaAttribute *create(Format format, uint32 attributeIndex,
+		uint32 attributeId);
+
+	Format attributeFormat() const { return mFormat; }
+	uint32 attributeIndex() const { return mAttributeIndex; }
+	uint32 attributeId() const { return mAttributeId; }
+
+	void packAttribute(WriteSection &ws, uint32 &valueOffset,
+		uint32 numValues, const CSSM_DATA *values) const;
+	void unpackAttribute(const ReadSection &rs, CssmAllocator &allocator,
+		uint32 &numValues, CSSM_DATA *&values) const;
+		
+	uint32 getNumberOfValues(const ReadSection &rs) const;
+	void copyValueBytes(uint32 valueIndex, const ReadSection &rs, WriteSection &ws,
+		uint32 &writeOffset) const;
+
+	// interface required of all subclasses, implemented with templates below
+	virtual DbValue *createValue(const CSSM_DATA &data) const = 0;
+	virtual DbValue *createValue(const ReadSection &rs, uint32 &offset) const = 0;
+	virtual void packValue(WriteSection &ws, uint32 &offset, const CSSM_DATA &data) const = 0;
+	virtual void unpackValue(const ReadSection &rs, uint32 &offset, CSSM_DATA &data,
+		CssmAllocator &allocator) const = 0;
+	virtual void skipValue(const ReadSection &rs, uint32 &offset) const = 0;
+	virtual void copyValue(const ReadSection &rs, uint32 &readOffset, WriteSection &ws,
+		uint32 &writeOffset) const = 0;
+	virtual bool evaluate(const DbValue *value, const ReadSection &rs, CSSM_DB_OPERATOR op) const = 0;
+	virtual bool evaluate(const DbValue *value1, const DbValue *value2, CSSM_DB_OPERATOR op) const = 0;
+	virtual uint32 parse(const CssmData &inData, CSSM_DATA_PTR &outValues) const = 0;
+
+protected:
+	MetaAttribute(Format format, uint32 attributeIndex, uint32 attributeId)
+	: mFormat(format), mAttributeIndex(attributeIndex), mAttributeId(attributeId) {}
+
+	void packNumberOfValues(WriteSection &ws, uint32 numValues, uint32 &valueOffset) const;
+	void unpackNumberOfValues(const ReadSection &rs, uint32 &numValues, uint32 &valueOffset) const;
+
+	Format mFormat;
+	uint32 mAttributeIndex;
+	uint32 mAttributeId;
+};
+
+// Template used to describe particular subclasses of MetaAttribute
+
+template <class T>
+class TypedMetaAttribute : public MetaAttribute
+{
+public:
+	TypedMetaAttribute(Format format, uint32 attributeIndex, uint32 attributeId)
+	: MetaAttribute(format, attributeIndex, attributeId) {}
+
+	DbValue *createValue(const CSSM_DATA &data) const
+	{
+		return new T(data);
+	}
+
+	DbValue *createValue(const ReadSection &rs, uint32 &offset) const
+	{
+		return new T(rs, offset);
+	}
+
+	void packValue(WriteSection &ws, uint32 &offset, const CSSM_DATA &data) const
+	{
+		T value(data);
+		value.pack(ws, offset);
+	}
+
+	void unpackValue(const ReadSection &rs, uint32 &offset, CSSM_DATA &data, CssmAllocator &allocator) const
+	{
+		T value(rs, offset);
+		data.Length = value.size();
+		data.Data = reinterpret_cast<uint8 *>(allocator.malloc(data.Length));
+		memcpy(data.Data, value.bytes(), data.Length);
+	}
+
+	void skipValue(const ReadSection &rs, uint32 &offset) const
+	{
+		T value(rs, offset);
+	}
+	
+	void copyValue(const ReadSection &rs, uint32 &readOffset, WriteSection &ws, uint32 &writeOffset) const
+	{
+		T value(rs, readOffset);
+		value.pack(ws, writeOffset);
+	}
+
+	bool evaluate(const DbValue *value, const ReadSection &rs, CSSM_DB_OPERATOR op) const
+	{
+		uint32 offset, numValues;
+		unpackNumberOfValues(rs, numValues, offset);		
+		if (numValues == 0)
+			return false;
+
+		return (dynamic_cast<const T *>(value))->evaluate(T(rs, offset), op);
+	}
+
+	bool evaluate(const DbValue *value1, const DbValue *value2, CSSM_DB_OPERATOR op) const
+	{
+		return (dynamic_cast<const T *>(value1))->evaluate(*dynamic_cast<const T *>(value2), op);
+	}
+		
+    uint32 parse(const CssmData &inData, CSSM_DATA_PTR &outValues) const
+	{
+		return 0;
+	}
+};
+
+} // end namespace Security
+
+#endif //  _H_APPLEDL_METAATTRIBUTE
diff --git a/cdsa/cdsa_utilities/MetaRecord.cpp b/cdsa/cdsa_utilities/MetaRecord.cpp
new file mode 100644
index 00000000..cc84191d
--- /dev/null
+++ b/cdsa/cdsa_utilities/MetaRecord.cpp
@@ -0,0 +1,493 @@
+/*
+ * 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.
+ */
+
+
+//
+// MetaRecord.cpp
+//
+
+#include "MetaRecord.h"
+
+MetaRecord::MetaRecord(CSSM_DB_RECORDTYPE inRecordType) :
+    mRecordType(inRecordType)
+{
+}
+
+MetaRecord::MetaRecord(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo)
+:	mRecordType(inInfo.DataRecordType)
+{
+	try
+	{
+		setRecordAttributeInfo(inInfo);
+	}
+	catch (...)
+	{
+		for_each_delete(mAttributeVector.begin(), mAttributeVector.end());
+	}
+}
+
+MetaRecord::MetaRecord(CSSM_DB_RECORDTYPE inRelationID,
+                       uint32 inNumberOfAttributes,
+					   const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo) :
+    mRecordType(inRelationID)
+{
+	// XXX Is there any particular reason not to allow this?
+#if 0
+	if (inNumberOfAttributes == 0 || inAttributeInfo == NULL)
+		CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_NUM_ATTRIBUTES);
+#endif
+
+	try {
+		for (uint32 anIndex = 0; anIndex < inNumberOfAttributes; anIndex++)
+		{
+			string aName;
+			if (inAttributeInfo[anIndex].AttributeName)
+				aName = string(inAttributeInfo[anIndex].AttributeName);
+				
+			const CssmData *aNameID = NULL;
+			if (inAttributeInfo[anIndex].AttributeNameID.Length > 0)
+				aNameID = &CssmData::overlay(inAttributeInfo[anIndex].AttributeNameID);
+
+			uint32 aNumber = inAttributeInfo[anIndex].AttributeId;
+			createAttribute(
+				inAttributeInfo[anIndex].AttributeName ? &aName : NULL,
+				aNameID, aNumber,
+				inAttributeInfo[anIndex].DataType);
+		}
+	}
+	catch (...)
+	{
+		for_each_delete(mAttributeVector.begin(), mAttributeVector.end());
+	}
+}
+
+MetaRecord::~MetaRecord()
+{
+	for_each_delete(mAttributeVector.begin(), mAttributeVector.end());
+}
+
+void
+MetaRecord::setRecordAttributeInfo(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo)
+{
+	// XXX Is there any particular reason not to allow this?
+#if 0
+    if (inInfo.NumberOfAttributes == 0 || inInfo.AttributeInfo == NULL)
+        CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_NUM_ATTRIBUTES);
+#endif
+
+    for (uint32 anIndex = 0; anIndex < inInfo.NumberOfAttributes; anIndex++)
+    {
+        switch (inInfo.AttributeInfo[anIndex].AttributeNameFormat)
+        {
+            case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
+            {
+                string aName(inInfo.AttributeInfo[anIndex].Label.AttributeName);
+                createAttribute(&aName, nil, anIndex,
+								inInfo.AttributeInfo[anIndex].AttributeFormat);
+                break;
+            }
+            case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
+            {
+                const CssmData &aNameID = CssmOid::overlay(inInfo.AttributeInfo[anIndex].Label.AttributeOID);
+                createAttribute(nil, &aNameID, anIndex,
+								inInfo.AttributeInfo[anIndex].AttributeFormat);
+                break;
+            }
+            case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
+            {
+                uint32 aNumber = inInfo.AttributeInfo[anIndex].Label.AttributeID;
+                createAttribute(nil, nil, aNumber,
+								inInfo.AttributeInfo[anIndex].AttributeFormat);
+                break;
+            }
+            default:
+                CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
+                break;
+        }
+    }
+}
+
+void
+MetaRecord::createAttribute(const string *inAttributeName,
+							const CssmOid *inAttributeOID,
+                            uint32 inAttributeID,
+							CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat)
+{
+	// Index of new element is current size of vector
+    uint32 anAttributeIndex = mAttributeVector.size();
+    bool aInsertedAttributeName = false;
+    bool aInsertedAttributeOID = false;
+    bool aInsertedAttributeID = false;
+
+    if (inAttributeName)
+    {
+        if (!mNameStringMap.insert(NameStringMap::value_type(*inAttributeName, anAttributeIndex)).second)
+            CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
+        aInsertedAttributeName = true;
+    }
+    try
+    {
+        if (inAttributeOID)
+        {
+            if (!mNameOIDMap.insert(NameOIDMap::value_type(*inAttributeOID, anAttributeIndex)).second)
+                CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
+            aInsertedAttributeOID = true;
+        }
+
+		if (!mNameIntMap.insert(NameIntMap::value_type(inAttributeID, anAttributeIndex)).second)
+			CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
+		aInsertedAttributeID = true;
+
+		// Note: this no longer throws INVALID_FIELD_NAME since the attribute will always have
+		// an attribute ID by which it is known
+
+		mAttributeVector.push_back(MetaAttribute::create(inAttributeFormat,
+			anAttributeIndex, inAttributeID));
+    }
+    catch(...)
+    {
+        if (aInsertedAttributeName)
+            mNameStringMap.erase(*inAttributeName);
+        if (aInsertedAttributeOID)
+            mNameOIDMap.erase(*inAttributeOID);
+        if (inAttributeID)
+            mNameIntMap.erase(inAttributeID);
+		
+        throw;
+    }
+}
+
+
+// Create a packed record from the given inputs.
+void
+MetaRecord::packRecord(WriteSection &inWriteSection,
+                       const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+                       const CssmData *inData) const
+{
+    uint32 aDataSize;
+    if (inData)
+        aDataSize = inData->Length;
+    else
+        aDataSize = 0;
+
+    inWriteSection.put(OffsetDataSize, aDataSize);
+    uint32 anOffset = OffsetAttributeOffsets + AtomSize * mAttributeVector.size();
+    if (aDataSize)
+        anOffset = inWriteSection.put(anOffset, aDataSize, inData->Data);
+
+    vector<uint32> aNumValues(mAttributeVector.size(), ~0UL);
+    vector<CSSM_DATA_PTR> aValues(mAttributeVector.size());
+    uint32 anIndex;
+
+    if (inAttributes == NULL)
+        inWriteSection.put(OffsetSemanticInformation, 0);
+    else
+    {
+        inWriteSection.put(OffsetSemanticInformation, inAttributes->SemanticInformation);
+
+        // Put the supplied attribute values into the list of attributes
+        // and values.
+        anIndex = inAttributes->NumberOfAttributes;
+        // Make sure that AttributeData is a valid array.
+		if (anIndex > 0)
+			Required(inAttributes->AttributeData);
+
+        while (anIndex-- > 0)
+        {
+            CSSM_DB_ATTRIBUTE_DATA &anAttribute = inAttributes->AttributeData[anIndex];
+            uint32 anAttributeIndex = attributeIndex(anAttribute.Info);
+			// Make sure that the caller specified the attribute values in the correct format.
+			if (anAttribute.Info.AttributeFormat != mAttributeVector[anAttributeIndex]->attributeFormat())
+				CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
+
+            // If this attribute was specified before, throw.
+            if (aNumValues[anAttributeIndex] != ~0UL)
+                CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
+
+            aNumValues[anAttributeIndex] = anAttribute.NumberOfValues;
+            aValues[anAttributeIndex] = anAttribute.Value;
+        }
+    }
+
+    for (anIndex = 0; anIndex < mAttributeVector.size(); ++anIndex)
+    {
+        const MetaAttribute &aMetaAttribute = *mAttributeVector[anIndex];
+        uint32 aNumberOfValues = aNumValues[anIndex];
+        // Now call the parsingmodule for each attribute that
+        // wasn't explicitly specified and that has a parsingmodule.
+        if (aNumberOfValues == ~0UL)
+            aNumberOfValues = aDataSize == 0 ? 0 : aMetaAttribute.parse(*inData, aValues[anIndex]);
+
+        // XXX When do we throw CSSMERR_DL_MISSING_VALUE?  Maybe if an
+		// attribute is part of a unique index.
+
+        // Now we have a valuelist for this attribute.  Let's encode it.
+        aMetaAttribute.packAttribute(inWriteSection, anOffset, aNumberOfValues, aValues[anIndex]);
+    }
+
+	inWriteSection.put(OffsetRecordSize, anOffset);
+    inWriteSection.size(anOffset);
+}
+
+inline void
+MetaRecord::unpackAttribute(const ReadSection &inReadSection,
+							CssmAllocator &inAllocator,
+                            CSSM_DB_ATTRIBUTE_DATA &inoutAttribute) const
+{
+    const MetaAttribute &aMetaAttribute = metaAttribute(inoutAttribute.Info);
+    // XXX: See ISSUES on whether AttributeFormat should be an outputvalue or not.
+	inoutAttribute.Info.AttributeFormat = aMetaAttribute.attributeFormat();
+    aMetaAttribute.unpackAttribute(inReadSection, inAllocator,
+                                   inoutAttribute.NumberOfValues,
+								   inoutAttribute.Value);
+}
+
+void
+MetaRecord::unpackRecord(const ReadSection &inReadSection,
+						 CssmAllocator &inAllocator,
+                         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                         CssmData *inoutData,
+						 CSSM_QUERY_FLAGS inQueryFlags) const
+{
+	// XXX Use POD wrapper for inoutAttributes here.
+	TrackingAllocator anAllocator(inAllocator);
+    if (inoutData)
+    {
+        // XXX Treat KEY records specially.
+
+        // If inQueryFlags & CSSM_QUERY_RETURN_DATA is true return the raw
+        // key bits in the CSSM_KEY structure
+        Range aDataRange = dataRange(inReadSection);
+    	inoutData->Length = aDataRange.mSize;
+        inoutData->Data = inReadSection.allocCopyRange(aDataRange, anAllocator);
+    }
+
+    if (inoutAttributes)
+    {
+        inoutAttributes->DataRecordType = dataRecordType();
+        inoutAttributes->SemanticInformation = semanticInformation(inReadSection);
+        uint32 anIndex = inoutAttributes->NumberOfAttributes;
+
+        // Make sure that AttributeData is a valid array.
+        if (anIndex > 0 && inoutAttributes->AttributeData == NULL)
+            CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
+
+        while (anIndex-- > 0)
+        {
+            unpackAttribute(inReadSection, anAllocator,
+            				inoutAttributes->AttributeData[anIndex]);
+        }
+    }
+
+	// Don't free anything the trackingAllocator allocated when it is destructed.
+	anAllocator.commit();
+}
+
+// Return the index (0 though NumAttributes - 1) of the attribute
+// represented by inAttributeInfo
+uint32
+MetaRecord::attributeIndex(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const
+{
+	uint32 anIndex;
+	switch (inAttributeInfo.AttributeNameFormat)
+	{
+	    case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
+		{
+			string aName(inAttributeInfo.Label.AttributeName);
+			NameStringMap::const_iterator it = mNameStringMap.find(aName);
+			if (it == mNameStringMap.end())
+				CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
+			anIndex = it->second;
+			break;
+		}
+	    case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
+	    {
+			const CssmOid &aName = CssmOid::overlay(inAttributeInfo.Label.AttributeOID);
+			NameOIDMap::const_iterator it = mNameOIDMap.find(aName);
+			if (it == mNameOIDMap.end())
+				CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
+			anIndex = it->second;
+			break;
+		}
+		case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
+		{
+			uint32 aName = inAttributeInfo.Label.AttributeID;
+			NameIntMap::const_iterator it = mNameIntMap.find(aName);
+			if (it == mNameIntMap.end())
+				CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
+			anIndex = it->second;
+			break;
+		}
+		default:
+			CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
+			break;
+	}
+
+	return anIndex;
+}
+
+const MetaAttribute &
+MetaRecord::metaAttribute(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const
+{
+	return *mAttributeVector[attributeIndex(inAttributeInfo)];
+}
+
+// Create a packed record from the given inputs and the old packed record inReadSection.
+void
+MetaRecord::updateRecord(const ReadSection &inReadSection,
+						 WriteSection &inWriteSection,
+						 const CssmDbRecordAttributeData *inAttributes,
+						 const CssmData *inData,
+						 CSSM_DB_MODIFY_MODE inModifyMode) const
+{
+	TrackingAllocator anAllocator(CssmAllocator::standard());
+
+	// modify the opaque data associated with the record
+	
+    uint32 aDataSize;
+	const uint8 *aDataData = NULL;
+    
+	if (inData)
+	{
+		// prepare to write new data
+        aDataSize = inData->Length;
+		aDataData = inData->Data;
+	}
+    else
+	{
+		// prepare to copy old data
+        Range aDataRange = dataRange(inReadSection);
+    	aDataSize = aDataRange.mSize;
+		if (aDataSize)
+			aDataData = inReadSection.range(aDataRange);
+	}
+
+	// compute the data offset; this will keep a running total of the record size
+    uint32 anOffset = OffsetAttributeOffsets + AtomSize * mAttributeVector.size();
+	
+	// write the appropriate data to the new record
+	inWriteSection.put(OffsetDataSize, aDataSize);
+	if (aDataSize)
+		anOffset = inWriteSection.put(anOffset, aDataSize, aDataData);
+
+	// unpack the old attributes since some of them may need to be preserved
+	
+	auto_array<CssmDbAttributeData> attributeData(mAttributeVector.size());
+
+	for (uint32 anAttributeIndex = mAttributeVector.size(); anAttributeIndex-- > 0; )
+	{
+		// unpack the old attribute data for this attribute index
+		const MetaAttribute &attribute = *mAttributeVector[anAttributeIndex];
+		attribute.unpackAttribute(inReadSection, anAllocator,
+								  attributeData[anAttributeIndex].NumberOfValues,
+								  attributeData[anAttributeIndex].Value);
+	}
+	
+	// retrieve the currrent semantic information
+	
+	uint32 oldSemanticInformation = semanticInformation(inReadSection);
+	
+	// process each input attribute as necessary, based on the modification mode
+	
+	if (inAttributes == NULL)
+	{
+		// make sure the modification mode is NONE, otherwise it's an
+		// error accordining to the spec
+		if (inModifyMode != CSSM_DB_MODIFY_ATTRIBUTE_NONE)
+			CssmError::throwMe(CSSMERR_DL_INVALID_MODIFY_MODE);
+	}
+
+	else {
+	
+		// modify the semantic information
+
+		uint32 inSemanticInformation = inAttributes ? inAttributes->SemanticInformation : 0;
+
+		if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_ADD)
+			oldSemanticInformation |= inSemanticInformation;
+
+		else if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_DELETE)
+			oldSemanticInformation &= ~inSemanticInformation;
+		
+		else if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_REPLACE)
+			oldSemanticInformation = inSemanticInformation;
+
+		uint32 anIndex = inAttributes->NumberOfAttributes;
+		if (anIndex > 0)
+			Required(inAttributes->AttributeData);
+
+		// modify the attributes
+
+		while (anIndex-- > 0) {
+	
+			const CssmDbAttributeData &anAttribute = inAttributes->at(anIndex);
+			uint32 anAttributeIndex = attributeIndex(anAttribute.info());
+			if (anAttribute.format() != mAttributeVector[anAttributeIndex]->attributeFormat())
+				CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
+
+			CssmDbAttributeData &oldAttribute = attributeData[anAttributeIndex];
+		
+			// if the modify mode is ADD, merge new values with pre-existing values
+		
+			if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_ADD)
+				oldAttribute.add(anAttribute, anAllocator);
+
+			// if the modify mode is DELETE, remove the indicated values, or remove
+			// all values if none are specified
+
+			else if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_DELETE)
+			{
+				if (anAttribute.size() == 0)
+					oldAttribute.deleteValues(anAllocator);
+				else
+					oldAttribute.deleteValues(anAttribute, anAllocator);
+			}
+		
+			// if the modify mode is REPLACE, then replace the specified values, or
+			// delete all values if no values are specified
+		
+			else if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_REPLACE)
+			{
+				oldAttribute.deleteValues(anAllocator);
+				if (anAttribute.size() > 0)
+					oldAttribute.add(anAttribute, anAllocator);
+				else
+					// The spec says "all values are deleted or the the value is replaced
+					// with the default" but doesn't say which. We could call the parsing
+					// module for the attribute here...if they were implemented! But instead
+					// we choose "all values are deleted" and leave it at that.
+					;
+			}
+		}
+	}
+
+	// write the resulting attributes into the new record
+	
+	inWriteSection.put(OffsetSemanticInformation, oldSemanticInformation);
+
+	for (uint32 anIndex = 0; anIndex < mAttributeVector.size(); ++anIndex)
+	{
+		const MetaAttribute &metaAttribute = *mAttributeVector[anIndex];
+		metaAttribute.packAttribute(inWriteSection, anOffset,
+								    attributeData[anIndex].NumberOfValues,
+									attributeData[anIndex].Value);
+	}
+	
+	inWriteSection.put(OffsetRecordSize, anOffset);
+	inWriteSection.size(anOffset);
+}
+
diff --git a/cdsa/cdsa_utilities/MetaRecord.h b/cdsa/cdsa_utilities/MetaRecord.h
new file mode 100644
index 00000000..e482ecf2
--- /dev/null
+++ b/cdsa/cdsa_utilities/MetaRecord.h
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+
+//
+// MetaRecord.h
+//
+
+#ifndef _H_APPLEDL_METARECORD
+#define _H_APPLEDL_METARECORD
+
+#include "MetaAttribute.h"
+
+namespace Security
+{
+
+//
+// Part of the Unique record identifier needed to identify the actual record.
+//
+class RecordId
+{
+public:
+	RecordId() : mRecordNumber(~0UL), mCreateVersion(~0UL), mRecordVersion(~0UL) {}
+    RecordId(uint32 inRecordNumber, uint32 inCreateVersion, uint32 inRecordVersion = 0)
+	  : mRecordNumber(inRecordNumber),
+        mCreateVersion(inCreateVersion),
+		mRecordVersion(inRecordVersion) {}
+    bool operator <(const RecordId &inRecordId) const
+    {
+        return (mRecordNumber < inRecordId.mRecordNumber
+                || (mRecordNumber == inRecordId.mRecordNumber
+                    && (mCreateVersion < inRecordId.mCreateVersion
+						|| (mCreateVersion == inRecordId.mCreateVersion
+							&& mRecordVersion < inRecordId.mRecordVersion))));
+    }
+    uint32 mRecordNumber;
+    uint32 mCreateVersion;
+	uint32 mRecordVersion;
+};
+
+//
+// Meta (or Schema) representation of an a Record.  Used for packing and unpacking objects.
+//
+
+class MetaRecord
+{
+	NOCOPY(MetaRecord)
+	
+public:
+    MetaRecord(CSSM_DB_RECORDTYPE inRecordType);
+	MetaRecord(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo);
+    MetaRecord(CSSM_DB_RECORDTYPE inRelationID,
+               uint32 inNumberOfAttributes,
+			   const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo);
+	~MetaRecord();
+
+    void setRecordAttributeInfo(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo);
+	
+    void createAttribute(const string *inAttributeName,
+						 const CssmOid *inAttributeOID,
+                         uint32 inAttributeID,
+						 CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat);
+
+    // Create a packed record from the given inputs.
+    void packRecord(WriteSection &inWriteSection,
+                    const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+                    const CssmData *inData) const;
+
+	// Unpack a record from the given inputs and return the RecordId of the record.
+    void unpackRecord(const ReadSection &inReadSection,
+					  CssmAllocator &inAllocator,
+					  CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+					  CssmData *inoutData,
+					  CSSM_QUERY_FLAGS inQueryFlags) const;
+
+	const MetaAttribute &metaAttribute(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const;
+
+	void updateRecord(const ReadSection &inReadSection,
+					  WriteSection &inWriteSection,
+					  const CssmDbRecordAttributeData *inAttributes,
+					  const CssmData *inData,
+					  CSSM_DB_MODIFY_MODE inModifyMode) const;
+
+    CSSM_DB_RECORDTYPE dataRecordType() const { return mRecordType; }
+
+	Range dataRange(const ReadSection &inReadSection) const
+	{
+        return Range(OffsetAttributeOffsets + mAttributeVector.size() * AtomSize,
+					 inReadSection[OffsetDataSize]);
+	}
+
+	// Currently this is not a real attribute.  We should probably fix this.
+	uint32 semanticInformation(const ReadSection &inReadSection) const
+	{
+		return inReadSection[OffsetSemanticInformation];
+	}
+
+    // Return the ReadSection for record at offset
+	static const ReadSection readSection(const ReadSection &inTableSection, uint32 inOffset)
+	{
+		return inTableSection.subsection(inOffset,
+										 inTableSection[inOffset + OffsetRecordSize]);
+	}
+
+	// Set the RecordId of the record in inWriteSection
+	static void packRecordId(const RecordId &inRecordId,
+							 WriteSection &inWriteSection)
+	{
+		inWriteSection.put(OffsetRecordNumber, inRecordId.mRecordNumber);
+		inWriteSection.put(OffsetCreateVersion, inRecordId.mCreateVersion);
+		inWriteSection.put(OffsetRecordVersion, inRecordId.mRecordVersion);
+	}
+
+	// Return the RecordId for the record inRecordSection
+	static const uint32 unpackRecordNumber(const ReadSection &inRecordSection)
+	{
+		return inRecordSection[OffsetRecordNumber];
+	}
+
+	// Return the RecordId for the record inRecordSection
+	static const RecordId unpackRecordId(const ReadSection &inRecordSection)
+	{
+		return RecordId(inRecordSection[OffsetRecordNumber],
+						inRecordSection[OffsetCreateVersion],
+						inRecordSection[OffsetRecordVersion]);
+	}
+
+private:
+    // Return the index (0 though NumAttributes - 1) of the attribute
+    // represented by inAttributeInfo
+    uint32 attributeIndex(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const;
+
+    void unpackAttribute(const ReadSection &inReadSection, CssmAllocator &inAllocator,
+                         CSSM_DB_ATTRIBUTE_DATA &inoutAttribute) const;
+
+    friend class MetaAttribute;
+	enum
+	{
+		OffsetRecordSize			= AtomSize * 0,
+		OffsetRecordNumber			= AtomSize * 1,
+		OffsetCreateVersion			= AtomSize * 2,
+		OffsetRecordVersion			= AtomSize * 3,
+		OffsetDataSize				= AtomSize * 4,
+		OffsetSemanticInformation	= AtomSize * 5,
+		OffsetAttributeOffsets		= AtomSize * 6
+	};
+
+	CSSM_DB_RECORDTYPE mRecordType;
+	typedef std::map<string, uint32> NameStringMap;
+	typedef std::map<CssmBuffer<CssmOidContainer>, uint32> NameOIDMap;
+	typedef std::map<uint32, uint32> NameIntMap;
+	typedef std::vector<MetaAttribute *> AttributeVector;
+	NameStringMap mNameStringMap;
+	NameOIDMap mNameOIDMap;
+	NameIntMap mNameIntMap;
+	AttributeVector mAttributeVector;
+};
+
+} // end namespace Security
+
+#endif // _H_APPLEDL_METARECORD
+
diff --git a/cdsa/cdsa_utilities/NOTES b/cdsa/cdsa_utilities/NOTES
new file mode 100644
index 00000000..e69de29b
diff --git a/cdsa/cdsa_utilities/ReadWriteSection.h b/cdsa/cdsa_utilities/ReadWriteSection.h
new file mode 100644
index 00000000..1982d9b2
--- /dev/null
+++ b/cdsa/cdsa_utilities/ReadWriteSection.h
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+
+//
+// ReadWriteSection.h
+//
+
+#ifndef _H_APPLEDL_READWRITESECTION
+#define _H_APPLEDL_READWRITESECTION
+
+#include <Security/cssmalloc.h>
+#include <Security/AtomicFile.h>
+
+namespace Security
+{
+
+//
+// Atom -- An Atom is a 32-bit unsigned integer value that is always internally
+// represented using network byte order.
+//
+class Atom
+{
+public:
+	typedef constVector<Atom> Vector;
+	
+	Atom() : mValue(0) {}
+	Atom(uint32 value) : mValue(htonl(value)) {}
+	
+	operator uint32 () const { return ntohl(mValue); }
+	Atom &operator = (uint32 value) { mValue = htonl(value); return *this; }
+	
+private:
+	uint32 mValue;
+};
+
+enum {
+	AtomSize = sizeof(uint32) // XXX Why not just use sizeof(Atom)?
+};
+
+//
+// Class representing a range (or subrange of a buffer).
+//
+class Range
+{
+public:
+	Range(uint32 inOffset, uint32 inSize) : mOffset(inOffset), mSize(inSize) {}
+	uint32 mOffset;
+	uint32 mSize;
+};
+
+//
+// Class representing a packed record.  All the accessors on this class are const since the
+// underlying data is read-only 
+//
+// XXX Should be replaced by Atom::Vector
+class ReadSection
+{
+public:
+	ReadSection() : mAddress(NULL), mLength(0) {}
+    ReadSection(const uint8 *inAddress, size_t inLength) :
+	    mAddress(const_cast<uint8 *>(inAddress)), mLength(inLength) {}
+		
+    uint32 size() const { return mLength; }
+
+    uint32 at(uint32 inOffset) const
+    {
+        return ntohl(*reinterpret_cast<const uint32 *>(mAddress + inOffset));
+    }
+
+    uint32 operator[](uint32 inOffset) const
+    {
+        if (inOffset + sizeof(uint32) > mLength)
+            CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+        return at(inOffset);
+    }
+
+	// Return a subsection from inOffset to end of section.
+    ReadSection subsection(uint32 inOffset) const
+    {
+        if (inOffset > mLength)
+            CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+        return ReadSection(mAddress + inOffset, mLength - inOffset);
+    }
+
+	// Return a subsection from inOffset of inLength bytes.
+    ReadSection subsection(uint32 inOffset, uint32 inLength) const
+    {
+        if (inOffset + inLength > mLength)
+            CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+        return ReadSection(mAddress + inOffset, inLength);
+    }
+	
+	ReadSection subsection(const Range &inRange) const
+	{
+		return subsection(inRange.mOffset, inRange.mSize);
+	}
+
+    const uint8 *range(const Range &inRange) const
+    {
+        if (inRange.mOffset + inRange.mSize > mLength)
+            CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+        return mAddress + inRange.mOffset;
+    }
+
+	uint8 *allocCopyRange(const Range &inRange, CssmAllocator &inAllocator) const
+	{
+	    uint8 *aData;
+	    if (inRange.mSize == 0)
+	        aData = NULL;
+	    else
+	    {
+	        if (inRange.mOffset + inRange.mSize > mLength)
+	            CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+	        aData = reinterpret_cast<uint8 *>(inAllocator.malloc(inRange.mSize));
+	        memcpy(aData, mAddress + inRange.mOffset, inRange.mSize);
+	    }
+
+		return aData;
+	}
+
+	static uint32 align(uint32 offset) { return (offset + AtomSize - 1) & ~(AtomSize - 1); }
+
+protected:
+    ReadSection(uint8 *inAddress, size_t inLength) : mAddress(inAddress), mLength(inLength) {}
+    uint8 *mAddress;
+    size_t mLength;
+};
+
+//
+// Class representing a packed record (or buffer) used for writing.
+//
+class WriteSection : public ReadSection
+{
+public:
+	static const size_t DefaultCapacity = 64;
+
+    WriteSection(CssmAllocator &inAllocator, size_t inCapacity) :
+        ReadSection(reinterpret_cast<uint8 *>(inAllocator.malloc(inCapacity)), 0),
+        mAllocator(inAllocator),
+        mCapacity(inCapacity)
+	{
+		if (mCapacity > 0)
+			memset(mAddress, 0, mCapacity);
+	}
+
+    WriteSection(CssmAllocator &inAllocator = CssmAllocator::standard()) :
+        ReadSection(reinterpret_cast<uint8 *>(inAllocator.malloc(DefaultCapacity)), 0),
+        mAllocator(inAllocator),
+        mCapacity(DefaultCapacity)
+	{
+	}
+	
+	WriteSection(const WriteSection &ws, int length) :
+		ReadSection(reinterpret_cast<uint8 *>(ws.mAllocator.malloc(length)), length),
+		mAllocator(ws.mAllocator),
+		mCapacity(length)
+	{
+		memcpy(mAddress, ws.mAddress, length);
+	}
+
+    ~WriteSection() { mAllocator.free(mAddress); }
+
+#if BUG_GCC
+	uint32 size() const { return ReadSection::size(); }
+#else
+	// XXX This should work but egcs-2.95.2 doesn't like it.
+	using ReadSection::size;
+#endif
+
+    void size(uint32 inLength) { mLength = inLength; }
+    uint32 put(uint32 inOffset, uint32 inValue)
+    {
+        uint32 aLength = inOffset + sizeof(inValue);
+        if (aLength > mCapacity)
+            grow(aLength);
+
+        *reinterpret_cast<uint32 *>(mAddress + inOffset) = htonl(inValue);
+        return aLength;
+    }
+
+    uint32 put(uint32 inOffset, uint32 inLength, const uint8 *inData)
+    {
+        uint32 aLength = inOffset + inLength;
+        // Round up to nearest multiple of 4 bytes, to pad with zeros
+        uint32 aNewOffset = align(aLength);
+        if (aNewOffset > mCapacity)
+            grow(aNewOffset);
+
+        memcpy(mAddress + inOffset, inData, inLength);
+
+        for (uint32 anOffset = aLength; anOffset < aNewOffset; anOffset++)
+            mAddress[anOffset] = 0;
+
+        return aNewOffset;
+    }
+
+    const uint8 *address() const { return mAddress; }
+    uint8 *release()
+    {
+        uint8 *anAddress = mAddress;
+        mAddress = NULL;
+        mCapacity = 0;
+        return anAddress;
+    }
+
+private:
+    void grow(size_t inNewCapacity)
+    {
+        size_t aNewCapacity = max(mCapacity * 2, inNewCapacity);
+        mAddress = reinterpret_cast<uint8 *>(mAllocator.realloc(mAddress, aNewCapacity));
+		memset(mAddress + mCapacity, 0, aNewCapacity - mCapacity);
+        mCapacity = aNewCapacity;
+    }
+
+    CssmAllocator &mAllocator;
+    size_t mCapacity;
+};
+
+} // end namespace Security
+
+#endif // _H_APPLEDL_READWRITESECTION
diff --git a/cdsa/cdsa_utilities/SampleGroup.cpp b/cdsa/cdsa_utilities/SampleGroup.cpp
new file mode 100644
index 00000000..1a7951a0
--- /dev/null
+++ b/cdsa/cdsa_utilities/SampleGroup.cpp
@@ -0,0 +1,294 @@
+/*
+ * 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.
+ */
+
+
+//	SampleGroup.cpp
+//
+//		CSSM_SAMPLE POD routines
+
+#ifdef __MWERKS__
+#define _CPP_UTILITIES
+#endif
+
+#include <cdsa_utilities/cssmlist.h>
+#include <cdsa_utilities/SampleGroup.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+	CssmSample::CssmSample()
+	{
+		Verifier = NULL;
+		TypedSample.ListType = CSSM_LIST_TYPE_UNKNOWN;
+		TypedSample.Head = NULL;
+		TypedSample.Tail = NULL;
+	}
+	
+	CssmSample::CssmSample( CSSM_LIST &list, CSSM_SUBSERVICE_UID *verifier)
+	{
+		Verifier = verifier;
+		TypedSample.ListType = list.ListType;
+		TypedSample.Head = list.Head;
+		TypedSample.Tail = list.Tail;
+	}
+	
+	CssmSample::~CssmSample()
+	{
+	}
+
+
+CssmSample* CssmSample::operator = (CssmSample& sample)
+{
+	if( this == &sample )
+		return NULL;
+
+	this->Verifier = sample.Verifier;
+	
+	this->TypedSample = sample.TypedSample;
+
+	return this;
+}
+	
+CSSM_RETURN	CssmSample::AddPasswordImmediate( char* password, CSSM_SUBSERVICE_UID *optionalVerifier )
+{
+ CSSM_RETURN result = CSSM_OK;
+ 
+ CSSM_LIST_ELEMENT*	passwordTypeElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_PASSWORD );	// declares the type to be password
+  (CssmList::overlay(TypedSample)).append( ListElement::overlay(passwordTypeElement) );
+ 
+ char* permanentPasswordData = (char*)malloc( strlen(password) + 1 ); // need error handling. Going to assume these succeed for now
+ strcpy( permanentPasswordData, password );
+ CSSM_LIST_ELEMENT*	passwordElement = MakeDatumElement( (void*)permanentPasswordData, strlen(password) );		// has the password CSSM_DATA in it
+  (CssmList::overlay(TypedSample)).append( ListElement::overlay(passwordElement) );
+  
+ Verifier = optionalVerifier;
+ 
+ return result;
+}
+
+	
+CSSM_RETURN	CssmSample::AddPasswordCallback( )
+{
+CSSM_RETURN result = CSSM_OK;
+ 
+ CSSM_LIST_ELEMENT*	passwordCallbackElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_PASSWORD );	// declares the type to be password
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(passwordCallbackElement) );
+ 
+ Verifier = NULL;
+ 
+ return result;
+	
+}
+
+CSSM_RETURN CssmSample::AddHashedPassword( char* password, CSSM_SUBSERVICE_UID *optionalVerifier )
+{
+ CSSM_RETURN result = CSSM_OK;
+ 
+ CSSM_LIST_ELEMENT*	passwordTypeElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_HASHED_PASSWORD );	// declares the type to be password
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(passwordTypeElement) );
+ 
+ char* permanentPasswordData = (char*)malloc( strlen(password) + 1 ); // need error handling. Going to assume these succeed for now
+ strcpy( permanentPasswordData, password );
+ CSSM_LIST_ELEMENT*	passwordElement = MakeDatumElement( (void*)permanentPasswordData, strlen(password) );		// has the password CSSM_DATA in it
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(passwordElement) );
+ 
+ Verifier = optionalVerifier;
+ 
+ return result;
+
+}
+
+
+
+CSSM_RETURN CssmSample::AddProtectedPasword(CSSM_SUBSERVICE_UID *optionalVerifier)
+{
+CSSM_RETURN	result = CSSM_OK;
+
+ CSSM_LIST_ELEMENT*	passwordCallbackElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD );	// declares the type to be password
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(passwordCallbackElement) );
+ 
+ Verifier = optionalVerifier;
+		
+return result;
+}
+
+
+CSSM_RETURN		CssmSample::AddPromptedPassword( char* promptedPassword, CSSM_SUBSERVICE_UID *optionalVerifier )	
+{
+ CSSM_RETURN result = CSSM_OK;
+ 
+ CSSM_LIST_ELEMENT*	passwordTypeElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD );	// declares the type to be password
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(passwordTypeElement) );
+
+ char* permanentPasswordData = (char*)malloc( strlen(promptedPassword) + 1 ); // need error handling. Going to assume these succeed for now
+ strcpy( permanentPasswordData, promptedPassword );
+ CSSM_LIST_ELEMENT*	passwordPromptElement = MakeDatumElement( (void*)permanentPasswordData, strlen(promptedPassword) );		// has the password CSSM_DATA in it 
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(passwordPromptElement) );
+ 
+ Verifier = optionalVerifier;
+ 
+ return result;
+}
+
+
+CSSM_RETURN		CssmSample::AddSignedNonceForCallback( CSSM_SUBSERVICE_UID *requiredVerifier )
+{
+CSSM_RETURN	result = CSSM_OK;
+
+ CSSM_LIST_ELEMENT*	signedNonceCallbackElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_SIGNED_NONCE );	
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(signedNonceCallbackElement) );
+ 
+ Verifier = requiredVerifier;
+		
+return result;
+}
+
+CSSM_RETURN		CssmSample::AddSignedNonceReply( CSSM_DATA_PTR signedNonce, CSSM_SUBSERVICE_UID *requiredVerifier )
+{
+CSSM_RETURN	result = CSSM_OK;
+
+ CSSM_LIST_ELEMENT*	signedNonceTypeElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_SIGNED_NONCE );
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(signedNonceTypeElement) );
+
+ CSSM_LIST_ELEMENT* 	signedNonceDataElement = MakeDatumElement( (void*)signedNonce->Data, signedNonce->Length ); 
+ (CssmList::overlay(TypedSample)).append( ListElement::overlay(signedNonceDataElement) );
+ 
+ Verifier = requiredVerifier;
+		
+return result;
+}
+
+CSSM_RETURN		CssmSample::AddSignedSecretForCallback( CSSM_SUBSERVICE_UID *requiredVerifier )
+{
+CSSM_RETURN	result = CSSM_OK;
+	CSSM_LIST_ELEMENT*	signedSecretCallbackElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_SIGNED_SECRET );
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(signedSecretCallbackElement) );
+	
+	Verifier = requiredVerifier;	
+	
+return result;
+}
+
+CSSM_RETURN		CssmSample::AddSignedSecretImmediate( CSSM_DATA_PTR signedSecret, CSSM_SUBSERVICE_UID *requiredVerifier )
+{
+CSSM_RETURN	result = CSSM_OK;
+
+	CSSM_LIST_ELEMENT*	signedSecretTypeElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_SIGNED_SECRET );
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(signedSecretTypeElement) );
+
+	CSSM_LIST_ELEMENT*	signedSecretElement = MakeDatumElement( (void*)signedSecret->Data, signedSecret->Length );	
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(signedSecretElement) );
+ 
+	Verifier = requiredVerifier;	
+return result;
+
+}
+
+CSSM_RETURN		CssmSample::AddBiometricCallback( CSSM_SUBSERVICE_UID *requiredVerifier )
+{
+CSSM_RETURN	result = CSSM_OK;
+
+	CSSM_LIST_ELEMENT*	callbackElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_BIOMETRIC );
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(callbackElement) );
+	
+	Verifier = requiredVerifier;	
+	
+return result;
+}
+
+
+CSSM_RETURN CssmSample::AddBiometricImmediate( CSSM_DATA_PTR biometricData, CSSM_SUBSERVICE_UID *requiredVerifier )
+{
+CSSM_RETURN	result = CSSM_OK;
+
+	CSSM_LIST_ELEMENT*	typeElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_BIOMETRIC );
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(typeElement) );
+
+	CSSM_LIST_ELEMENT*	dataElement = MakeDatumElement( (void*)biometricData->Data, biometricData->Length );	
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(dataElement) );
+ 
+	Verifier = requiredVerifier;	
+	
+return result;
+}
+
+
+CSSM_RETURN CssmSample::AddProtectedBiometric( CSSM_SUBSERVICE_UID *requiredVerifier )
+{
+CSSM_RETURN	result = CSSM_OK;
+
+	CSSM_LIST_ELEMENT*	callbackElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_PROTECTED_BIOMETRIC );
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(callbackElement) );
+	
+	Verifier = requiredVerifier;	
+return result;
+}
+
+CSSM_RETURN CssmSample::AddPromptedBiometric( CSSM_DATA_PTR biometricData, CSSM_SUBSERVICE_UID *requiredVerifier )
+{
+CSSM_RETURN	result = CSSM_OK;
+
+	CSSM_LIST_ELEMENT*	callbackElement = MakeWordIDElement( CSSM_SAMPLE_TYPE_PROMPTED_BIOMETRIC );
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(callbackElement) );
+
+
+	CSSM_LIST_ELEMENT*	dataElement = MakeDatumElement( (void*)biometricData->Data, biometricData->Length );	
+	(CssmList::overlay(TypedSample)).append( ListElement::overlay(dataElement) );
+ 	
+	Verifier = requiredVerifier;	
+return result;
+}
+
+// CssmSampleGroup
+
+CssmSampleGroup::CssmSampleGroup()
+{	// creates the nothing sample group
+	NumberOfSamples = 0;
+	Samples = NULL;
+}
+
+CSSM_RETURN	CssmSampleGroup::AddSample(CSSM_SAMPLE*	sample)
+{
+CSSM_RETURN		result = CSSM_OK;
+CSSM_SAMPLE*	sampleBase;
+	if( NumberOfSamples == 0 )
+	{ // malloc to create the first item
+		sampleBase = (CSSM_SAMPLE*)malloc( sizeof(CSSM_SAMPLE) );
+		Samples = sampleBase;
+	}
+		else
+		{ // realloc to add the next item
+			sampleBase = (CSSM_SAMPLE*)realloc( (void*)Samples, sizeof(CSSM_SAMPLE) * (NumberOfSamples + 1) );
+			Samples = sampleBase;
+		}
+		
+	sampleBase[NumberOfSamples].TypedSample.ListType	= sample->TypedSample.ListType;
+	sampleBase[NumberOfSamples].TypedSample.Head		= sample->TypedSample.Head;
+	sampleBase[NumberOfSamples].TypedSample.Tail		= sample->TypedSample.Tail;
+	sampleBase[NumberOfSamples].Verifier 				= sample->Verifier;
+	
+	NumberOfSamples++;
+	
+return result;
+}
+
+CSSM_SAMPLE*	CssmSampleGroup::GetIthSample(uint32 sampleIndex)
+{
+	if( (0 != NumberOfSamples) && (sampleIndex < NumberOfSamples-1) )
+		return (CSSM_SAMPLE*)&Samples[sampleIndex];
+	  else
+	  	return NULL;
+}
diff --git a/cdsa/cdsa_utilities/SampleGroup.h b/cdsa/cdsa_utilities/SampleGroup.h
new file mode 100644
index 00000000..92cfbfc1
--- /dev/null
+++ b/cdsa/cdsa_utilities/SampleGroup.h
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+
+// SampleGroup.h
+//
+//	a class interface to the CSSM_SAMPLEGROUP structure
+//
+//	Here are the relevant structures:
+//
+//	typedef struct cssm_samplegroup {
+//	    uint32 NumberOfSamples;
+//	    const CSSM_SAMPLE *Samples;
+//	} CSSM_SAMPLEGROUP, *CSSM_SAMPLEGROUP_PTR;
+//	
+//		typedef struct cssm_sample {
+//		    CSSM_LIST TypedSample;
+//		    const CSSM_SUBSERVICE_UID *Verifier;
+//		} CSSM_SAMPLE, *CSSM_SAMPLE_PTR;
+//		
+//			typedef struct cssm_list {
+//			    CSSM_LIST_TYPE ListType;	/* type of this list */
+//			    CSSM_LIST_ELEMENT_PTR Head;	/* head of the list */
+//			    CSSM_LIST_ELEMENT_PTR Tail;	/* tail of the list */
+//			} CSSM_LIST, *CSSM_LIST_PTR;
+//			
+//			typedef uint32 CSSM_LIST_TYPE, *CSSM_LIST_TYPE_PTR;
+//			enum {
+//				CSSM_LIST_TYPE_UNKNOWN =			0,
+//				CSSM_LIST_TYPE_CUSTOM =				1,
+//				CSSM_LIST_TYPE_SEXPR =				2
+//			};
+//			
+//			typedef struct cssm_list_element {
+//			    struct cssm_list_element *NextElement;	/* next list element */
+//				CSSM_WORDID_TYPE WordID;	/* integer identifier associated */
+//											/* with a Word value */
+//			    CSSM_LIST_ELEMENT_TYPE ElementType;
+//			    union {
+//			        CSSM_LIST Sublist;		/* sublist */
+//			        CSSM_DATA Word;		/* a byte-string */
+//			    } Element;
+//			} CSSM_LIST_ELEMENT;
+//
+
+
+#ifndef	__SAMPLEGROUP__
+#define __SAMPLEGROUP__
+
+#include <cdsa/cssmtype.h>
+#include <cdsa_utilities/utilities.h>
+#include <cdsa_utilities/cssm_adt_utils.h>
+
+#ifdef _CPP_UTILITIES
+#pragma export on
+#endif
+
+
+class	CssmSample : public PodWrapper<CssmSample, CSSM_SAMPLE> {
+public:
+		CssmSample();
+		CssmSample( CSSM_LIST &list, CSSM_SUBSERVICE_UID *verifier);
+		~CssmSample();
+		
+		CssmSample* operator = (CssmSample& sample);
+		
+		void	SetSubserviceUID( CSSM_SUBSERVICE_UID *verifier ) { Verifier = verifier; }
+		void	SetList( CSSM_LIST *list ) { TypedSample.ListType = list->ListType; TypedSample.Head = list->Head; TypedSample.Tail = list->Tail; }
+		
+//		CSSM_SAMPLE_TYPE_PASSWORD =				CSSM_WORDID_PASSWORD,
+		CSSM_RETURN		AddPasswordImmediate( char* password, CSSM_SUBSERVICE_UID *optionalVerifier );	// provide password without callback or reply to callback
+		CSSM_RETURN		AddPasswordCallback( );				// triggers a callback that will acquire the password
+		
+//		CSSM_SAMPLE_TYPE_HASHED_PASSWORD =		CSSM_WORDID_HASHED_PASSWORD,
+		CSSM_RETURN		AddHashedPassword( char* password, CSSM_SUBSERVICE_UID *optionalVerifier );	// this is always in reply to a callback
+
+//		CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD =	CSSM_WORDID_PROTECTED_PASSWORD,
+		CSSM_RETURN		AddProtectedPasword(CSSM_SUBSERVICE_UID *optionalVerifier);	// this always provokes a callback, Verifier is optional
+		
+//		CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD =	CSSM_WORDID_PROMPTED_PASSWORD,
+		CSSM_RETURN		AddPromptedPassword( char* promptedPassword, CSSM_SUBSERVICE_UID *optionalVerifier );	// this is always in reply to a callback
+		
+//		CSSM_SAMPLE_TYPE_SIGNED_NONCE =			CSSM_WORDID_SIGNED_NONCE,
+		CSSM_RETURN		AddSignedNonceForCallback( CSSM_SUBSERVICE_UID *requiredVerifier );
+		CSSM_RETURN		AddSignedNonceReply( CSSM_DATA_PTR signedNonce, CSSM_SUBSERVICE_UID *requiredVerifier ); // used to reply to the callback for a signed nonce
+		
+//		CSSM_SAMPLE_TYPE_SIGNED_SECRET =		CSSM_WORDID_SIGNED_SECRET,
+		CSSM_RETURN		AddSignedSecretForCallback( CSSM_SUBSERVICE_UID *requiredVerifier ); // will provoke a callback to fill in the actual signed secret
+		CSSM_RETURN		AddSignedSecretImmediate( CSSM_DATA_PTR signedSecret, CSSM_SUBSERVICE_UID *requiredVerifier ); // use as the original request or as a response to a callback   
+		
+//		CSSM_SAMPLE_TYPE_BIOMETRIC =			CSSM_WORDID_BIOMETRIC,
+		CSSM_RETURN		AddBiometricCallback( CSSM_SUBSERVICE_UID *requiredVerifier );
+		CSSM_RETURN		AddBiometricImmediate( CSSM_DATA_PTR biometricData, CSSM_SUBSERVICE_UID *requiredVerifier );	// reply to callback or provide sample without callback
+		
+//		CSSM_SAMPLE_TYPE_PROTECTED_BIOMETRIC =	CSSM_WORDID_PROTECTED_BIOMETRIC,
+		CSSM_RETURN		AddProtectedBiometric( CSSM_SUBSERVICE_UID *requiredVerifier );		// request for a callback for biometric data
+			
+//		CSSM_SAMPLE_TYPE_PROMPTED_BIOMETRIC =	CSSM_WORDID_PROMPTED_BIOMETRIC,
+		CSSM_RETURN		AddPromptedBiometric( CSSM_DATA_PTR biometricData, CSSM_SUBSERVICE_UID *requiredVerifier );	// reply to callback only
+		
+//		CSSM_SAMPLE_TYPE_THRESHOLD =			CSSM_WORDID_THRESHOLD
+ 		CSSM_RETURN		AddThreshold();
+		
+};
+
+class	CssmSampleGroup : public PodWrapper<CssmSampleGroup, CSSM_SAMPLEGROUP>
+{
+public:
+			CssmSampleGroup();
+			CssmSampleGroup( uint32 sampleCount, CSSM_SAMPLE *samples );
+			~CssmSampleGroup();
+			
+	CSSM_RETURN		AddSample(CSSM_SAMPLE*	sample);
+	
+	CSSM_SAMPLE*	GetIthSample(uint32 sampleIndex);
+
+	uint32			GetSampleCount() { return NumberOfSamples; }
+	
+	
+private:
+};
+
+#ifdef _CPP_UTILITIES
+#pragma export off
+#endif
+
+#endif	// __SAMPLEGROUP__
diff --git a/cdsa/cdsa_utilities/SelectionPredicate.cpp b/cdsa/cdsa_utilities/SelectionPredicate.cpp
new file mode 100644
index 00000000..85426ac2
--- /dev/null
+++ b/cdsa/cdsa_utilities/SelectionPredicate.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+
+//
+// SelectionPredicate.cpp
+//
+
+#include "SelectionPredicate.h"
+
+SelectionPredicate::SelectionPredicate(const MetaRecord &inMetaRecord,
+									   const CSSM_SELECTION_PREDICATE &inPredicate)
+:	mMetaAttribute(inMetaRecord.metaAttribute(inPredicate.Attribute.Info)),
+	mDbOperator(inPredicate.DbOperator)
+{
+	// Make sure that the caller specified the attribute values in the correct format.
+	if (inPredicate.Attribute.Info.AttributeFormat != mMetaAttribute.attributeFormat())
+		CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
+
+	// XXX See ISSUES
+	if (inPredicate.Attribute.NumberOfValues != 1)
+		CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
+
+	mData = inPredicate.Attribute.Value[0];
+	mValue = mMetaAttribute.createValue(mData);
+}
+
+SelectionPredicate::~SelectionPredicate()
+{
+	delete mValue;
+}
+
+bool
+SelectionPredicate::evaluate(const ReadSection &rs) const
+{
+    return mMetaAttribute.evaluate(mValue, rs, mDbOperator);
+}
diff --git a/cdsa/cdsa_utilities/SelectionPredicate.h b/cdsa/cdsa_utilities/SelectionPredicate.h
new file mode 100644
index 00000000..d5b93c5d
--- /dev/null
+++ b/cdsa/cdsa_utilities/SelectionPredicate.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+
+//
+// SelectionPredicate.h
+//
+
+#ifndef _H_APPLEDL_SELECTIONPREDICATE
+#define _H_APPLEDL_SELECTIONPREDICATE
+
+#include "MetaRecord.h"
+#include <memory>
+
+namespace Security
+{
+
+class SelectionPredicate
+{
+    NOCOPY(SelectionPredicate)
+	
+public:
+    SelectionPredicate(const MetaRecord &inMetaRecord,
+    				   const CSSM_SELECTION_PREDICATE &inPredicate);
+	~SelectionPredicate();
+	
+    bool evaluate(const ReadSection &inReadSection) const;
+	
+private:
+    const MetaAttribute &mMetaAttribute;
+    CSSM_DB_OPERATOR mDbOperator;
+	CssmDataContainer mData;
+	DbValue *mValue;
+};
+
+} // end namespace Security
+
+#endif // _H_APPLEDL_SELECTIONPREDICATE
diff --git a/cdsa/cdsa_utilities/acl_any.cpp b/cdsa/cdsa_utilities/acl_any.cpp
new file mode 100644
index 00000000..7bb8201c
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_any.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_any - "anyone" ACL subject type.
+//
+#ifdef __MWERKS__
+#define _CPP_ACL_ANY
+#endif
+
+#include <Security/acl_any.h>
+#include <algorithm>
+
+
+//
+// The ANY subject matches all credentials, including none at all.
+//
+bool AnyAclSubject::validate(const AclValidationContext &) const
+{
+	return true;
+}
+
+
+//
+// The CSSM_LIST version is trivial. It has no private part to omit.
+//
+CssmList AnyAclSubject::toList(CssmAllocator &alloc) const
+{
+	return TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_ANY);
+}
+
+
+//
+// The subject form takes no arguments.
+//
+AnyAclSubject *AnyAclSubject::Maker::make(const TypedList &list) const
+{
+	crack(list, 0);	// no arguments in input list
+	return new AnyAclSubject();
+}
+
+AnyAclSubject *AnyAclSubject::Maker::make(Reader &, Reader &) const
+{
+    return new AnyAclSubject();
+}
+
diff --git a/cdsa/cdsa_utilities/acl_any.h b/cdsa/cdsa_utilities/acl_any.h
new file mode 100644
index 00000000..19fc079a
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_any.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_any - "anyone" ACL subject type.
+//
+// This subject will categorically match everything and anything, even no
+// credentials at all (a NULL AccessCredentials pointer).
+//
+#ifndef _ACL_ANY
+#define _ACL_ANY
+
+#include <Security/cssmacl.h>
+#include <string>
+
+#ifdef _CPP_ACL_ANY
+#pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// The ANY subject simply matches everything. No sweat.
+//
+class AnyAclSubject : public AclSubject {
+public:
+    AnyAclSubject() : AclSubject(CSSM_ACL_SUBJECT_TYPE_ANY) { }
+	bool validate(const AclValidationContext &ctx) const;
+	CssmList toList(CssmAllocator &alloc) const;
+
+	class Maker : public AclSubject::Maker {
+	public:
+		Maker() : AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_ANY) { }
+		AnyAclSubject *make(const TypedList &list) const;
+    	AnyAclSubject *make(Reader &pub, Reader &priv) const;
+	};
+};
+
+} // end namespace Security
+
+#ifdef _CPP_ACL_ANY
+#pragma export off
+#endif
+
+
+#endif //_ACL_ANY
diff --git a/cdsa/cdsa_utilities/acl_codesigning.cpp b/cdsa/cdsa_utilities/acl_codesigning.cpp
new file mode 100644
index 00000000..45678e5d
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_codesigning.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_codesigning - ACL subject for signature of calling application
+//
+#ifdef __MWERKS__
+#define _CPP_ACL_CODESIGNING
+#endif
+
+#include <Security/acl_codesigning.h>
+#include <Security/cssmdata.h>
+#include <algorithm>
+
+
+//
+// Construct a password ACL subject.
+// Note that this takes over ownership of the signature object.
+//
+CodeSignatureAclSubject::CodeSignatureAclSubject(CssmAllocator &alloc, 
+	const Signature *signature, const void *comment, size_t commentLength)
+	: AclSubject(CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE),
+    allocator(alloc), mSignature(signature),
+	mHaveComment(true), mComment(alloc, comment, commentLength)
+{ }
+
+CodeSignatureAclSubject::CodeSignatureAclSubject(CssmAllocator &alloc, 
+	const Signature *signature)
+	: AclSubject(CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE),
+    allocator(alloc), mSignature(signature), mHaveComment(false), mComment(alloc)
+{ }
+
+CodeSignatureAclSubject::~CodeSignatureAclSubject()
+{
+	delete mSignature;
+}
+
+//
+// Code signature credentials are validated globally - they are entirely
+// a feature of "the" process (defined by the environment), and take no
+// samples whatsoever.
+//
+bool CodeSignatureAclSubject::validate(const AclValidationContext &context) const
+{
+	// a suitable environment is required for a match
+    if (Environment *env = context.environment<Environment>())
+		return env->verifyCodeSignature(mSignature);
+	else
+		return false;
+}
+
+
+//
+// Make a copy of this subject in CSSM_LIST form.
+// The format is (head), (type code: Wordid), (signature data: datum), (comment: datum)
+//
+CssmList CodeSignatureAclSubject::toList(CssmAllocator &alloc) const
+{
+    // all associated data is public (no secrets)
+	TypedList list(alloc, CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE,
+		new(alloc) ListElement(mSignature->type()),
+		new(alloc) ListElement(alloc.alloc(*mSignature)));
+	if (mHaveComment)
+		list += new(alloc) ListElement(alloc.alloc(mComment));
+	return list;
+}
+
+
+//
+// Create a CodeSignatureAclSubject
+//
+CodeSignatureAclSubject *CodeSignatureAclSubject::Maker::make(const TypedList &list) const
+{
+    CssmAllocator &alloc = CssmAllocator::standard();
+	if (list.length() == 3+1) {
+		// signature type: int, signature data: datum, comment: datum
+		ListElement *elem[3];
+		crack(list, 3, elem, 
+			CSSM_LIST_ELEMENT_WORDID, CSSM_LIST_ELEMENT_DATUM, CSSM_LIST_ELEMENT_DATUM);
+		CssmData &commentData(*elem[2]);
+		return new CodeSignatureAclSubject(alloc, signer.restore(*elem[0], *elem[1]), 
+			commentData.data(), commentData.length());
+	} else {
+		// signature type: int, signature data: datum [no comment]
+		ListElement *elem[2];
+		crack(list, 2, elem, 
+			CSSM_LIST_ELEMENT_WORDID, CSSM_LIST_ELEMENT_DATUM);
+		return new CodeSignatureAclSubject(alloc, signer.restore(*elem[0], *elem[1]));
+	}
+}
+
+CodeSignatureAclSubject *CodeSignatureAclSubject::Maker::make(Reader &pub, Reader &priv) const
+{
+    CssmAllocator &alloc = CssmAllocator::standard();
+	uint32 sigType; pub(sigType);
+	const void *data; uint32 length; pub.countedData(data, length);
+	const void *commentData; uint32 commentLength; pub.countedData(commentData, commentLength);
+	return new CodeSignatureAclSubject(alloc, 
+		signer.restore(sigType, data, length),
+		commentData, commentLength);
+}
+
+
+//
+// Export the subject to a memory blob
+//
+void CodeSignatureAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
+{
+	uint32 sigType = mSignature->type(); pub(sigType);
+	pub.countedData(*mSignature);
+	pub.countedData(mComment);
+}
+
+void CodeSignatureAclSubject::exportBlob(Writer &pub, Writer &priv)
+{
+	uint32 sigType = mSignature->type(); pub(sigType);
+	pub.countedData(*mSignature);
+	pub.countedData(mComment);
+}
+
+
+#ifdef DEBUGDUMP
+
+void CodeSignatureAclSubject::debugDump() const
+{
+	Debug::dump("CodeSigning");
+	if (mHaveComment) {
+		Debug::dump(" comment=");
+		Debug::dumpData(mComment);
+	}
+}
+
+#endif //DEBUGDUMP
diff --git a/cdsa/cdsa_utilities/acl_codesigning.h b/cdsa/cdsa_utilities/acl_codesigning.h
new file mode 100644
index 00000000..20c4ee9f
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_codesigning.h
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_codesigning - ACL subject for signature of calling application
+//
+#ifndef _H_ACL_CODESIGNING
+#define _H_ACL_CODESIGNING
+
+#include <Security/cssmdata.h>
+#include <Security/cssmacl.h>
+#include <Security/codesigning.h>
+
+#ifdef _CPP_ACL_CODESIGNING
+#pragma export on
+#endif
+
+namespace Security
+{
+
+using CodeSigning::Signature;
+using CodeSigning::Signer;
+
+//
+// The CodeSignature subject type matches a code signature applied to the
+// disk image that originated the client process.
+//
+class CodeSignatureAclSubject : public AclSubject {
+public:
+    bool validate(const AclValidationContext &baseCtx) const;
+    CssmList toList(CssmAllocator &alloc) const;
+    
+    CodeSignatureAclSubject(CssmAllocator &alloc, const Signature *signature);
+    CodeSignatureAclSubject(CssmAllocator &alloc, 
+		const Signature *signature, const void *comment, size_t commentLength);
+	~CodeSignatureAclSubject();
+    
+    CssmAllocator &allocator;
+    
+    void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
+    void exportBlob(Writer &pub, Writer &priv);
+	
+	IFDUMP(void debugDump() const);
+    
+public:
+    class Environment : public virtual AclValidationEnvironment {
+    public:
+		virtual bool verifyCodeSignature(const Signature *signature) = 0;
+    };
+
+public:
+    class Maker : public AclSubject::Maker {
+    public:
+    	Maker(Signer &sgn) 
+		: AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE), signer(sgn) { }
+    	CodeSignatureAclSubject *make(const TypedList &list) const;
+    	CodeSignatureAclSubject *make(Reader &pub, Reader &priv) const;
+		
+		Signer &signer;
+    };
+    
+private:
+	const Signature *mSignature;			// signature of object
+	bool mHaveComment;						// mComment present
+	CssmAutoData mComment;					// arbitrary comment blob
+};
+
+} // end namespace Security
+
+
+#ifdef _CPP_ACL_CODESIGNING
+#pragma export off
+#endif
+
+
+#endif //_H_ACL_CODESIGNING
diff --git a/cdsa/cdsa_utilities/acl_comment.cpp b/cdsa/cdsa_utilities/acl_comment.cpp
new file mode 100644
index 00000000..03924d5f
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_comment.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_comment - "ignore" ACL subject type
+//
+#include <Security/acl_comment.h>
+#include <Security/cssmwalkers.h>
+#include <Security/cssmlist.h>
+#include <algorithm>
+
+using namespace DataWalkers;
+
+
+//
+// The COMMENT subject matches nothing, no matter how pretty.
+//
+bool CommentAclSubject::validate(const AclValidationContext &) const
+{
+	return false;
+}
+
+
+//
+// The toList function simply returns a copy of the preserved list.
+// The interface convention requires that we chunkCopy here.
+//
+CssmList CommentAclSubject::toList(CssmAllocator &alloc) const
+{
+	CssmList result = CssmList::overlay(*mComment);
+	ChunkCopyWalker w(alloc);
+	walk(w, result);
+	return result;
+}
+
+
+//
+// Construct-from-list makes a unified copy of the list.
+//
+CommentAclSubject *CommentAclSubject::Maker::make(const TypedList &list) const
+{
+	const CSSM_LIST *baseList = &list;
+	size_t commentSize = size(baseList);
+	CSSM_LIST *comment = copy(baseList, CssmAllocator::standard(), commentSize);
+	return new CommentAclSubject(comment, commentSize);
+}
+
+CommentAclSubject *CommentAclSubject::Maker::make(Reader &pub, Reader &) const
+{
+	CSSM_LIST *base; pub(base);	// get original pointer base
+	const void *data; uint32 length; pub.countedData(data, length);	// data blob
+
+	// copy the input blob into writable memory
+	CSSM_LIST *list = CssmAllocator::standard().malloc<CSSM_LIST>(length);
+	memcpy(list, data, length);
+	
+	// relocate it based on the base pointer we stored
+	relocate(list, base);
+	
+	// good
+    return new CommentAclSubject(list, length);
+}
+
+
+//
+// Export to blob form.
+// Since we store the list in unified form, this isn't very hard. Do try to figure
+// out how walkers work before messing with this code.
+//
+void CommentAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &)
+{
+	pub(mComment);	// yes, the pointer itself
+	pub.countedData(mComment, mSize);
+}
+
+void CommentAclSubject::exportBlob(Writer &pub, Writer &)
+{
+	pub(mComment);
+	pub.countedData(mComment, mSize);
+}
+
diff --git a/cdsa/cdsa_utilities/acl_comment.h b/cdsa/cdsa_utilities/acl_comment.h
new file mode 100644
index 00000000..b273981c
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_comment.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_comment - "ignore" ACL subject type
+//
+// This subject will never match anything - its presence is effectively ignored.
+// Its usefulness lies in the fact that COMMENT type ACL subjects are valid ACL
+// subjects that preserve their contents as uninterpreted data blobs. This allows
+// you to keep information in an ACL that can be retrieved later. In particular,
+// you can "prefix" any external ACL subject representation with an ACL_COMMENT
+// header, which turns it into an inactive comment until you remove the prefix.
+//
+// Notes: 
+// (1) All contents of a comment ACL are public.
+// (2) While there is a COMMENT sample type, it is in no way related to this subject
+//     type. Validation of a COMMENT acl subject never examines any samples.
+//
+#ifndef _ACL_COMMENT
+#define _ACL_COMMENT
+
+#include <Security/cssmacl.h>
+
+
+namespace Security
+{
+
+//
+// The ANY subject simply matches everything. No sweat.
+//
+class CommentAclSubject : public AclSubject {
+public:
+	CommentAclSubject::CommentAclSubject(CSSM_LIST *list, uint32 size)
+	: AclSubject(CSSM_ACL_SUBJECT_TYPE_COMMENT), mComment(list), mSize(size) { }
+	~CommentAclSubject() { CssmAllocator::standard().free(mComment); }
+	
+	bool validate(const AclValidationContext &ctx) const;
+	CssmList toList(CssmAllocator &alloc) const;
+
+    void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
+    void exportBlob(Writer &pub, Writer &priv);
+
+	class Maker : public AclSubject::Maker {
+	public:
+		Maker() : AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_COMMENT) { }
+		CommentAclSubject *make(const TypedList &list) const;
+    	CommentAclSubject *make(Reader &pub, Reader &priv) const;
+	};
+	
+private:
+	CSSM_LIST *mComment;		// list form preserved
+	uint32 mSize;				// size of mComment blob
+};
+
+} // end namespace Security
+
+
+#endif //_ACL_COMMENT
diff --git a/cdsa/cdsa_utilities/acl_keychain.cpp b/cdsa/cdsa_utilities/acl_keychain.cpp
new file mode 100644
index 00000000..0b33216c
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_keychain.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_keychain - a subject type for the protected-path
+//				  keychain prompt interaction model.
+//
+// Arguments in list form:
+//	list[1] = CssmData: Descriptive String
+//
+#ifdef __MWERKS__
+#define _CPP_ACL_KEYCHAIN
+#endif
+
+#include <Security/acl_keychain.h>
+#include <algorithm>
+
+
+//
+// Validate a credential set against this subject
+//
+bool KeychainPromptAclSubject::validate(const AclValidationContext &,
+    const TypedList &sample) const
+{
+    return interface.validate(description);
+}
+
+
+//
+// Make a copy of this subject in CSSM_LIST form
+//
+CssmList KeychainPromptAclSubject::toList(CssmAllocator &alloc) const
+{
+	return TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT,
+        new(alloc) ListElement(alloc, description));
+}
+
+
+//
+// Create a PasswordAclSubject
+//
+KeychainPromptAclSubject *KeychainPromptAclSubject::Maker::make(const TypedList &list) const
+{
+    ListElement *params[1];
+	crack(list, 1, params, CSSM_LIST_ELEMENT_DATUM);
+	return new KeychainPromptAclSubject(interface, *params[0]);
+}
+
+KeychainPromptAclSubject *KeychainPromptAclSubject::Maker::make(Reader &pub, Reader &) const
+{
+    char *description; pub(description);
+	return new KeychainPromptAclSubject(interface, description);
+}
+
+KeychainPromptAclSubject::KeychainPromptAclSubject(KeychainPromptInterface &ifc,
+    string descr)
+: SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT),
+  interface(ifc), description(descr)
+{
+}
+
+
+//
+// Export the subject to a memory blob
+//
+void KeychainPromptAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
+{
+    pub(description.size() + 1);
+}
+
+void KeychainPromptAclSubject::exportBlob(Writer &pub, Writer &priv)
+{
+    pub(description.c_str());
+}
+
diff --git a/cdsa/cdsa_utilities/acl_keychain.h b/cdsa/cdsa_utilities/acl_keychain.h
new file mode 100644
index 00000000..3e76fa9d
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_keychain.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_keychain - a subject type for the protected-path
+//				  keychain prompt interaction model.
+//
+#ifndef _ACL_KEYCHAIN
+#define _ACL_KEYCHAIN
+
+#include <Security/cssmacl.h>
+#include <string>
+
+#ifdef _CPP_ACL_KEYCHAIN
+#pragma export on
+#endif
+
+class KeychainPromptInterface;
+class SecurityAgentClient;
+
+
+//
+// This is the actual subject implementation class
+//
+class KeychainPromptAclSubject : public SimpleAclSubject {
+public:
+    bool validate(const AclValidationContext &baseCtx, const TypedList &sample) const;
+    CssmList toList(CssmAllocator &alloc) const;
+    
+    KeychainPromptAclSubject(KeychainPromptInterface &ifc, string description);
+    
+    void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
+    void exportBlob(Writer &pub, Writer &priv);
+
+    class Maker : public AclSubject::Maker {
+    public:
+    	Maker(KeychainPromptInterface &ifc)
+         : AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT),
+           interface(ifc) { }
+    	KeychainPromptAclSubject *make(const TypedList &list) const;
+    	KeychainPromptAclSubject *make(Reader &pub, Reader &priv) const;
+        
+    private:
+        KeychainPromptInterface &interface;
+    };
+    
+private:
+    KeychainPromptInterface &interface;
+    string description;
+};
+
+
+//
+// A KeychainPromptAcl needs to use some I/O facility to validate a credential.
+// You must thus subclass this interface class (which acts as an AclSubject::Maker)
+// to provide the actual testing interface. The subject type will take care of
+// the formalities.
+//
+class KeychainPromptInterface {
+public:
+    KeychainPromptInterface() : maker(*this) { }
+
+    virtual bool validate(string description) = 0;	// implement this
+    
+private:
+    const KeychainPromptAclSubject::Maker maker;
+};
+
+
+#ifdef _CPP_ACL_KEYCHAIN
+#pragma export off
+#endif
+
+
+#endif //_ACL_KEYCHAIN
diff --git a/cdsa/cdsa_utilities/acl_password.cpp b/cdsa/cdsa_utilities/acl_password.cpp
new file mode 100644
index 00000000..363e0a7f
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_password.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_password - password-based ACL subject types
+//
+#ifdef __MWERKS__
+#define _CPP_ACL_PASSWORD
+#endif
+
+#include <Security/acl_password.h>
+#include <Security/debugging.h>
+#include <algorithm>
+
+
+//
+// Construct a password ACL subject
+//
+PasswordAclSubject::PasswordAclSubject(CssmAllocator &alloc, const CssmData &password)
+    : SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE_PASSWORD, CSSM_SAMPLE_TYPE_PASSWORD),
+    allocator(alloc), mPassword(alloc, password)
+{ }
+
+PasswordAclSubject::PasswordAclSubject(CssmAllocator &alloc, CssmManagedData &password)
+    : SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE_PASSWORD, CSSM_SAMPLE_TYPE_PASSWORD),
+    allocator(alloc), mPassword(alloc, password)
+{ }
+
+
+//
+// Validate a credential set against this subject
+//
+bool PasswordAclSubject::validate(const AclValidationContext &context,
+    const TypedList &sample) const
+{
+	if (sample[1].type() != CSSM_LIST_ELEMENT_DATUM)
+		CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+    const CssmData &password = sample[1];
+    return password == mPassword;
+}
+
+
+//
+// Make a copy of this subject in CSSM_LIST form
+//
+CssmList PasswordAclSubject::toList(CssmAllocator &alloc) const
+{
+    // the password itself is private and not exported to CSSM
+	return TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD);
+}
+
+
+//
+// Create a PasswordAclSubject
+//
+PasswordAclSubject *PasswordAclSubject::Maker::make(const TypedList &list) const
+{
+	ListElement *password;
+	crack(list, 1, &password, CSSM_LIST_ELEMENT_DATUM);
+	return new PasswordAclSubject(CssmAllocator::standard(CssmAllocator::sensitive), *password);
+}
+
+PasswordAclSubject *PasswordAclSubject::Maker::make(Reader &pub, Reader &priv) const
+{
+    CssmAllocator &alloc = CssmAllocator::standard(CssmAllocator::sensitive);
+	const void *data; uint32 length; priv.countedData(data, length);
+	return new PasswordAclSubject(alloc, CssmAutoData(alloc, data, length));
+}
+
+
+//
+// Export the subject to a memory blob
+//
+void PasswordAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
+{
+	priv.countedData(mPassword);
+}
+
+void PasswordAclSubject::exportBlob(Writer &pub, Writer &priv)
+{
+	priv.countedData(mPassword);
+}
+
+
+#ifdef DEBUGDUMP
+
+void PasswordAclSubject::debugDump() const
+{
+	Debug::dump("Password ");
+	Debug::dumpData(mPassword.data(), mPassword.length());
+}
+
+#endif //DEBUGDUMP
diff --git a/cdsa/cdsa_utilities/acl_password.h b/cdsa/cdsa_utilities/acl_password.h
new file mode 100644
index 00000000..3a0e048e
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_password.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_password - password-based ACL subject types.
+//
+// This implements simple password-based subject types as per CSSM standard.
+//
+#ifndef _ACL_PASSWORD
+#define _ACL_PASSWORD
+
+#include <Security/cssmdata.h>
+#include <Security/cssmacl.h>
+#include <string>
+
+#ifdef _CPP_ACL_PASSWORD
+#pragma export on
+#endif
+
+namespace Security
+{
+
+class PasswordAclSubject : public SimpleAclSubject {
+public:
+    bool validate(const AclValidationContext &baseCtx, const TypedList &sample) const;
+    CssmList toList(CssmAllocator &alloc) const;
+    
+    PasswordAclSubject(CssmAllocator &alloc, const CssmData &password);
+    PasswordAclSubject(CssmAllocator &alloc, CssmManagedData &password);
+    
+    CssmAllocator &allocator;
+    
+    void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
+    void exportBlob(Writer &pub, Writer &priv);
+	
+	IFDUMP(void debugDump() const);
+    
+    class Maker : public AclSubject::Maker {
+    public:
+    	Maker() : AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_PASSWORD) { }
+    	PasswordAclSubject *make(const TypedList &list) const;
+    	PasswordAclSubject *make(Reader &pub, Reader &priv) const;
+    };
+    
+private:
+    CssmAutoData mPassword;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_ACL_PASSWORD
+#pragma export off
+#endif
+
+
+#endif //_ACL_PASSWORD
diff --git a/cdsa/cdsa_utilities/acl_process.cpp b/cdsa/cdsa_utilities/acl_process.cpp
new file mode 100644
index 00000000..460b3898
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_process.cpp
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_process - Process-attribute ACL subject type.
+//
+#ifdef __MWERKS__
+#define _CPP_ACL_PROCESS
+#endif
+
+#include <Security/acl_process.h>
+#include <algorithm>
+
+#include <cstdio>	// testing
+
+
+//
+// Validate a credential set against this subject
+//
+bool ProcessAclSubject::validate(const AclValidationContext &context,
+    const TypedList &sample) const
+{
+    if (sample.length() != 1)	// no-argument sample
+		CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+    
+    // reality check (internal structure was validated when created)
+    assert(select.uses(CSSM_ACL_MATCH_BITS));
+    
+    // access the environment
+    Environment *env = context.environment<Environment>();
+    if (env == NULL) {
+        static Environment localEnvironment;
+        env = &localEnvironment;
+    }
+    
+    // match uid
+    if (select.uses(CSSM_ACL_MATCH_UID)) {
+        uid_t uid = env->getuid();
+        if (!(uid == select.uid || (select.uses(CSSM_ACL_MATCH_HONOR_ROOT) && uid == 0)))
+            return false;
+    }
+    
+    // match gid
+    if (select.uses(CSSM_ACL_MATCH_GID) && select.gid != env->getgid())
+        return false;
+        
+    return true;
+}
+
+
+//
+// Make a copy of this subject in CSSM_LIST form
+//
+CssmList ProcessAclSubject::toList(CssmAllocator &alloc) const
+{
+    // all associated data is public (no secrets)
+    //@@@ ownership of selector data is murky; revisit after leak-plugging pass
+    CssmData sData(memcpy(alloc.alloc<CSSM_ACL_PROCESS_SUBJECT_SELECTOR>(),
+        &select, sizeof(select)), sizeof(select));
+	return TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PROCESS,
+        new(alloc) ListElement(sData));
+}
+
+
+//
+// Create a ProcessAclSubject
+//
+ProcessAclSubject *ProcessAclSubject::Maker::make(const TypedList &list) const
+{
+    // crack input apart
+	ListElement *selectorData;
+	crack(list, 1, &selectorData, CSSM_LIST_ELEMENT_DATUM);
+    AclProcessSubjectSelector selector;
+    selectorData->extract(selector);
+    
+    // validate input
+    if (selector.version != CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION)
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+    if (!selector.uses(CSSM_ACL_MATCH_BITS))
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+        
+    // okay
+	return new ProcessAclSubject(selector);
+}
+
+ProcessAclSubject *ProcessAclSubject::Maker::make(Reader &pub, Reader &priv) const
+{
+    AclProcessSubjectSelector selector; pub(selector);
+	return new ProcessAclSubject(selector);
+}
+
+
+//
+// Export the subject to a memory blob
+//
+void ProcessAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
+{
+    pub(select);
+}
+
+void ProcessAclSubject::exportBlob(Writer &pub, Writer &priv)
+{
+    pub(select);
+}
+
+
+//
+// Implement the default methods of a ProcessEnvironment
+//
+uid_t ProcessAclSubject::Environment::getuid() const
+{
+    return ::getuid();
+}
+
+gid_t ProcessAclSubject::Environment::getgid() const
+{
+    return ::getgid();
+}
+
+
+#ifdef DEBUGDUMP
+
+void ProcessAclSubject::debugDump() const
+{
+	Debug::dump("Process ");
+	if (select.uses(CSSM_ACL_MATCH_UID)) {
+		Debug::dump("uid=%d", int(select.uid));
+		if (select.uses(CSSM_ACL_MATCH_HONOR_ROOT))
+			Debug::dump("+root");
+	}
+	if (select.uses(CSSM_ACL_MATCH_GID))
+		Debug::dump("gid=%d", int(select.gid));
+}
+
+#endif //DEBUGDUMP
diff --git a/cdsa/cdsa_utilities/acl_process.h b/cdsa/cdsa_utilities/acl_process.h
new file mode 100644
index 00000000..2ccadafd
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_process.h
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_process - Process-attribute ACL subject type.
+//
+// NOTE:
+// The default Environment provides data about the current process (the one that
+// validate() is run in). If this isn't right for you (e.g. because you want to
+// validate against a process on the other side of some IPC connection), you must
+// make your own version of Environment and pass it to validate().
+//
+#ifndef _ACL_PROCESS
+#define _ACL_PROCESS
+
+#include <Security/cssmacl.h>
+#include <string>
+
+#ifdef _CPP_ACL_PROCESS
+#pragma export on
+#endif
+
+namespace Security
+{
+
+class AclProcessSubjectSelector
+    : public PodWrapper<AclProcessSubjectSelector, CSSM_ACL_PROCESS_SUBJECT_SELECTOR> {
+public:
+    AclProcessSubjectSelector()
+    { version = CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION; mask = 0; }
+    
+    bool uses(uint32 m) const { return mask & m; }
+};
+
+
+//
+// The ProcessAclSubject matches process attributes securely identified
+// by the system across IPC channels.
+//
+class ProcessAclSubject : public SimpleAclSubject {
+public:
+    bool validate(const AclValidationContext &baseCtx, const TypedList &sample) const;
+    CssmList toList(CssmAllocator &alloc) const;
+
+    ProcessAclSubject(const AclProcessSubjectSelector &selector)
+    : SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE_PROCESS, CSSM_SAMPLE_TYPE_PROCESS),
+      select(selector) { }
+
+    void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
+    void exportBlob(Writer &pub, Writer &priv);
+	
+	IFDUMP(void debugDump() const);
+    
+public:
+    class Environment : public virtual AclValidationEnvironment {
+    public:
+        virtual uid_t getuid() const;	// retrieve effective userid to match
+        virtual gid_t getgid() const;	// retrieve effective groupid to match
+    };
+    
+public:
+    class Maker : public AclSubject::Maker {
+    public:
+    	Maker() : AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_PROCESS) { }
+    	ProcessAclSubject *make(const TypedList &list) const;
+    	ProcessAclSubject *make(Reader &pub, Reader &priv) const;
+    };
+
+private:
+    AclProcessSubjectSelector select;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_ACL_PROCESS
+#pragma export off
+#endif
+
+
+#endif //_ACL_PROCESS
diff --git a/cdsa/cdsa_utilities/acl_threshold.cpp b/cdsa/cdsa_utilities/acl_threshold.cpp
new file mode 100644
index 00000000..7bba0cc0
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_threshold.cpp
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_threshold - Threshold-based group ACL subjects
+//
+#ifdef __MWERKS__
+#define _CPP_ACL_THRESHOLD
+#endif
+
+#include <Security/acl_threshold.h>
+#include <algorithm>
+
+
+//
+// Validate a credential set against this subject.
+//
+// With STRICTCOUNTING set, we assume that every match in the threshold ACL
+// "consumes" one sample in the corresponding threshold sample. This will not
+// work as expected for subject types that may succeed without a sample (e.g. ANY)
+// or subject types that may multiply match against a single sample. You have been
+// warned.
+//
+class SublistValidationContext : public AclValidationContext {
+public:
+    SublistValidationContext(const AclValidationContext &ctx, const TypedList &list)
+    : AclValidationContext(ctx), sampleList(list) { }
+    
+    uint32 count() const { return sampleList.length() - 1; }
+    const TypedList &sample(uint32 n) const
+    { return TypedList::overlay(sampleList[n+1].list()); }
+    
+    const TypedList &sampleList;
+};
+
+bool ThresholdAclSubject::validate(const AclValidationContext &baseCtx,
+    const TypedList &sample) const
+{
+#ifdef STRICTCOUNTING
+    // Pre-screen for reasonable number of subsamples.
+    // We could more strictly require subSampleCount == elements.length();
+    // this is more flexible in that it allows the caller to abbreviate.
+    uint32 subSampleCount = sample.length() - 1;	// (drop type header)
+    if (subSampleCount < minimumNeeded)	// can't possibly satisfy
+		CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+    if (subSampleCount > totalSubjects)	// reject attempt at sample stuffing
+		CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+#endif //STRICTCOUNTING
+
+    // evaluate
+    SublistValidationContext ctx(baseCtx, sample);
+    uint32 matched = 0;
+    for (uint32 n = 0; n < totalSubjects; n++) {
+		if ((matched += elements[n]->validate(ctx)) >= minimumNeeded)
+            return true;
+#ifdef STRICTCOUNTING
+        else if (matched + subSampleCount - n <= minimumNeeded)
+            return false;	// can't get there anymore
+#endif //STRICTCOUNTING
+    }
+	return false;
+}
+
+
+//
+// Make a copy of this subject in CSSM_LIST form
+//
+CssmList ThresholdAclSubject::toList(CssmAllocator &alloc) const
+{
+	TypedList result(alloc, CSSM_ACL_SUBJECT_TYPE_THRESHOLD,
+		new(alloc) ListElement(minimumNeeded),
+		new(alloc) ListElement(totalSubjects));
+    for (uint32 n = 0; n < totalSubjects; n++)
+		result += new(alloc) ListElement(elements[n]->toList(alloc));
+	return result;
+}
+
+
+//
+// Create a ThresholdAclSubject
+//
+ThresholdAclSubject *ThresholdAclSubject::Maker::make(const TypedList &list) const
+{
+    // pick apart the input list
+    if (list.length() < 4)	// head + "n" + "k" + at least one subSubject
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+    uint32 minimumNeeded = getWord(list[1], 1);
+    uint32 totalSubjects = getWord(list[2], minimumNeeded);
+    if (list.length() != 3 + totalSubjects)
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+
+    // now compile the subSubjects
+    AclSubjectVector elements(totalSubjects);
+    const ListElement *subSubject = &list[3];
+    for (uint32 n = 0; n < totalSubjects; n++, subSubject = subSubject->next())
+        elements[n] = ObjectAcl::make(*subSubject);
+	return new ThresholdAclSubject(totalSubjects, minimumNeeded, elements);
+}
+
+ThresholdAclSubject *ThresholdAclSubject::Maker::make(Reader &pub, Reader &priv) const
+{
+    uint32 totalSubjects; pub(totalSubjects);
+    uint32 minimumNeeded; pub(minimumNeeded);
+    AclSubjectVector subSubjects(totalSubjects);
+    for (uint32 n = 0; n < totalSubjects; n++) {
+        CSSM_ACL_SUBJECT_TYPE type; pub(type);
+        subSubjects[n] = ObjectAcl::make(type, pub, priv);
+    }
+	return new ThresholdAclSubject(totalSubjects, minimumNeeded, subSubjects);
+}
+
+ThresholdAclSubject::ThresholdAclSubject(uint32 n, uint32 k,
+    const AclSubjectVector &subSubjects)
+: SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE_THRESHOLD, CSSM_SAMPLE_TYPE_THRESHOLD),
+  minimumNeeded(k), totalSubjects(n), elements(subSubjects)
+{
+}
+
+
+//
+// Export the subject to a memory blob
+//
+template <class Action>
+void ThresholdAclSubject::exportBlobForm(Action &pub, Action &priv)
+{
+    pub(totalSubjects);
+    pub(minimumNeeded);
+    for (uint32 n = 0; n < totalSubjects; n++) {
+        AclSubjectPointer &subSubject = elements[n];
+        CSSM_ACL_SUBJECT_TYPE type = subSubject->type();
+        pub(type);
+        subSubject->exportBlob(pub, priv);
+    }
+}
+
+void ThresholdAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
+{ exportBlobForm(pub, priv); }
+
+void ThresholdAclSubject::exportBlob(Writer &pub, Writer &priv)
+{ exportBlobForm(pub, priv); }
+
+
+#ifdef DEBUGDUMP
+
+void ThresholdAclSubject::debugDump() const
+{
+	Debug::dump("Threshold(%ld of %ld)", minimumNeeded, totalSubjects);
+	for (unsigned int n = 0; n < elements.size(); n++) {
+		Debug::dump(" [");
+		elements[n]->debugDump();
+		Debug::dump("]");
+	}
+}
+
+#endif //DEBUGDUMP
diff --git a/cdsa/cdsa_utilities/acl_threshold.h b/cdsa/cdsa_utilities/acl_threshold.h
new file mode 100644
index 00000000..9c55039d
--- /dev/null
+++ b/cdsa/cdsa_utilities/acl_threshold.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+
+//
+// acl_threshold - Threshold-based group ACL subjects.
+//
+// This subject type implements threshold (k of n) subjects as per CSSM standard.
+// Subsubjects are stored and evaluated in the order received. Any subsubject
+// is presented with all subsamples of the corresponding threshold sample, but
+// not any other samples possibly present in the credentials. Subsubject evaluation
+// stops as soon as the threshold is satisfied, or as soon as it becomes numerically
+// impossible to satisfy the threshold with future matches.
+// Note that this subject will reject out of hand any threshold sample that
+// contains more than <n> subsamples. This defeats "sample stuffing" attacks
+// where the attacker provides thousands of samples in the hope that some may
+// match by accident. It will however accept threshold samples with fewer than
+// <n> subsamples, as long as there are at least <k> subsamples.
+//
+#ifndef _ACL_THRESHOLD
+#define _ACL_THRESHOLD
+
+#include <Security/cssmacl.h>
+#include <vector>
+
+#ifdef _CPP_ACL_THRESHOLD
+#pragma export on
+#endif
+
+namespace Security
+{
+
+class ThresholdAclSubject : public SimpleAclSubject {
+    typedef ObjectAcl::AclSubjectPointer AclSubjectPointer;
+    typedef vector<AclSubjectPointer> AclSubjectVector;
+public:
+    bool validate(const AclValidationContext &baseCtx, const TypedList &sample) const;
+    CssmList toList(CssmAllocator &alloc) const;
+    
+    ThresholdAclSubject(uint32 n, uint32 k, const AclSubjectVector &subSubjects);
+    
+    void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
+    void exportBlob(Writer &pub, Writer &priv);
+	
+	IFDUMP(void debugDump() const);
+    
+    class Maker : public AclSubject::Maker {
+    public:
+    	Maker() : AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_THRESHOLD) { }
+    	ThresholdAclSubject *make(const TypedList &list) const;
+    	ThresholdAclSubject *make(Reader &pub, Reader &priv) const;
+    };
+    
+private:
+    uint32 minimumNeeded;				// number of matches needed
+    uint32 totalSubjects;				// number of subSubjects
+    AclSubjectVector elements;			// sub-subject vector
+
+    template <class Action>
+    void ThresholdAclSubject::exportBlobForm(Action &pub, Action &priv);
+};
+
+} // end namespace Security
+
+#ifdef _CPP_ACL_THRESHOLD
+#pragma export off
+#endif
+
+#endif //_ACL_THRESHOLD
diff --git a/cdsa/cdsa_utilities/bufferfifo.cpp b/cdsa/cdsa_utilities/bufferfifo.cpp
new file mode 100644
index 00000000..d5818d9f
--- /dev/null
+++ b/cdsa/cdsa_utilities/bufferfifo.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+
+//
+// bufferfifo - a Sink that queues data in a FIFO of buffers for retrieval
+//
+#include "bufferfifo.h"
+#include <Security/memutils.h>
+
+
+namespace Security {
+
+
+//
+// On destruction, throw away all queued buffers (that haven't been picked up)
+//
+BufferFifo::~BufferFifo()
+{
+    while (!mBuffers.empty()) {
+        delete mBuffers.front();
+        mBuffers.pop();
+    }
+}
+
+
+//
+// This is the put function of a Sink. We store the data in at most two buffers:
+// First we append to the last (partially filled) one; then we allocate a new one
+// (if needed) to hold the rest.
+//
+void BufferFifo::consume(const void *data, size_t size)
+{
+    // step 1: fill the rearmost (partially filled) buffer
+    if (size > 0 && !mBuffers.empty()) {
+        Buffer *current = mBuffers.back();
+        size_t length = current->put(data, size);
+        data = LowLevelMemoryUtilities::increment(data, length);
+        size -= length;
+    }
+    // step 2: if there's anything left, make a new buffer and fill it
+    if (size > 0) {	// not done
+        Buffer *current = new Buffer(max(bufferLength, size));
+        mBuffers.push(current);
+        assert(current->available() >= size);
+        current->put(data, size);
+    }
+}
+
+
+//
+// Pull the first (FI) buffer off the queue and deliver it.
+// We retain no memory of it; it belongs to the caller now.
+//
+Buffer *BufferFifo::pop()
+{
+    assert(!mBuffers.empty());
+    Buffer *top = mBuffers.front();
+    mBuffers.pop();
+    return top;
+}
+
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/bufferfifo.h b/cdsa/cdsa_utilities/bufferfifo.h
new file mode 100644
index 00000000..170c163b
--- /dev/null
+++ b/cdsa/cdsa_utilities/bufferfifo.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+
+//
+// bufferfifo - a Sink that queues data in a FIFO of buffers for retrieval
+//
+#ifndef _H_BUFFERFIFO
+#define _H_BUFFERFIFO
+
+#include "streams.h"
+#include "buffers.h"
+#include <list>
+#include <queue>
+
+
+namespace Security {
+
+
+//
+// A BufferFifo acts as a First-in First-out queue of Buffer objects.
+// This is usually used as a flexible I/O buffer queue mechanism.
+// For convenience, a BufferFifo is a Sink, so you can push data
+// into it directly using the Sink mechanism.
+// Note that there is currently no mechanism for restricting the
+// memory footprint of a BufferFifo.
+//
+class BufferFifo : public Sink {
+public:
+    BufferFifo(size_t es = 4096) : bufferLength(es) { }
+    ~BufferFifo();
+    
+    Buffer *top() const			{ assert(!mBuffers.empty()); return mBuffers.front(); }
+    Buffer *pop();
+    void push(Buffer *b)		{ mBuffers.push(b); }
+    
+    bool isEmpty() const		{ return mBuffers.empty(); }
+    size_t size() const			{ return mBuffers.size(); }
+    size_t topLength() const	{ assert(!isEmpty()); return mBuffers.front()->length(); }
+    
+    // Sink implementation
+    void consume(const void *data, size_t size);
+
+private:
+    typedef queue< Buffer *, list<Buffer *> > BufferQueue;
+    BufferQueue mBuffers;
+    const size_t bufferLength;
+};
+
+
+
+}	// end namespace Security
+
+
+#endif _H_BUFFERFIFO
diff --git a/cdsa/cdsa_utilities/buffers.cpp b/cdsa/cdsa_utilities/buffers.cpp
new file mode 100644
index 00000000..25bda022
--- /dev/null
+++ b/cdsa/cdsa_utilities/buffers.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+
+//
+// buffer - simple data buffers with convenience
+//
+#include "buffers.h"
+#include <Security/debugging.h>
+#include <algorithm>
+
+
+namespace Security {
+
+
+//
+// Construct an empty Buffer from newly allocated memory
+//
+Buffer::Buffer(size_t size)
+    : mBase(new char[size]), mTop(mBase + size), mOwningMemory(true)
+{
+    mStart = mEnd = mBase;
+}
+
+
+//
+// Construct a buffer from given memory, with given fill or ownership
+//
+Buffer::Buffer(void *base, size_t size, bool filled, bool owned) 
+    : mBase(reinterpret_cast<char *>(base)), mTop(mBase + size), mOwningMemory(owned)
+{
+    mStart = mBase;
+    mEnd = filled ? mTop : mBase;
+}
+
+
+//
+// Destroying a buffer deallocates its memory iff it owns it.
+//
+Buffer::~Buffer()
+{
+    if (mOwningMemory)
+        delete[] mBase;
+}
+
+
+//
+// Shuffle buffer contents to make more room.
+// Takes minimum size needed. Returns size available.
+//
+size_t Buffer::shuffle(size_t needed)
+{
+    assert(available() < needed);	// shouldn't be called otherwise
+    size_t length = this->length();
+    memmove(mBase, mStart, length);
+    mStart = mBase;
+    mEnd = mStart + length;
+    return min(needed, available());
+}
+
+
+//
+// Formatted append to buffer
+//
+void Buffer::printf(const char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    vprintf(format, args);
+    va_end(args);
+}
+
+void Buffer::vprintf(const char *format, va_list args)
+{
+    unsigned int written = vsnprintf(mEnd, mTop - mEnd, format, args);
+    if (written < available()) {
+        // overflow on formatting. Reshuffle and try again
+        shuffle();
+        written = vsnprintf(mEnd, available(), format, args);
+        assert(written < available());	//@@@ throw here?
+    }
+    mEnd += written;	// note: zero terminator discarded here
+}
+
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/buffers.h b/cdsa/cdsa_utilities/buffers.h
new file mode 100644
index 00000000..86aca4a5
--- /dev/null
+++ b/cdsa/cdsa_utilities/buffers.h
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+
+//
+// buffer - simple data buffers with convenience
+//
+#ifndef _H_BUFFER
+#define _H_BUFFER
+
+#include <Security/utilities.h>
+#include <cstdarg>
+#include <limits.h>
+
+
+namespace Security {
+
+
+class Buffer {
+public:
+    Buffer(size_t size);			// allocate empty buffer
+    ~Buffer();
+    
+    static Buffer reader(void *base, size_t size, bool owned = false)
+    { return Buffer(base, size, true, owned); }
+    static Buffer writer(void *base, size_t size, bool owned = false)
+    { return Buffer(base, size, false, owned); }
+    
+    size_t available(bool heavy = false) const
+    { return heavy ? ((mTop - mEnd) + (mStart - mBase)): (mTop - mEnd); }
+    bool isFull(bool heavy = false) const
+    { return heavy ? (mEnd == mTop && mStart == mBase) : (mEnd == mTop); }
+    bool isEmpty() const		{ return mStart == mEnd; }
+
+    size_t length() const		{ return mEnd - mStart; }
+    void *data()				{ assert(mStart == mBase); return mStart; }
+    
+    void clear()				{ mStart = mEnd = mBase; }
+    
+protected:
+    // private constructor with full flexibility
+    Buffer(void *base, size_t size, bool filled, bool owned = false);
+    
+    // perform expensive realignment to coalesce freespace
+    size_t shuffle(size_t needed = UINT_MAX);
+    
+    // perform cheap adjustments after data was taken out
+    void adjustGet()
+    {
+        if (isEmpty())	// empty buffer. Reset pointers to base
+            mStart = mEnd = mBase;
+    }
+    
+public:
+    // elementary put: copy mode
+    size_t put(const void *data, size_t length)
+    {
+        if (length > available())
+            length = shuffle(length);
+        memcpy(mEnd, data, length);
+        mEnd += length;
+        return length;
+    }
+
+    // elementary put: locate mode. Remember that each can shuffle memory
+    template <class T> void locatePut(T * &addr, size_t &length)
+    {
+        if (length > available())
+            length = shuffle(length);
+        addr = reinterpret_cast<T *>(mEnd);
+    }
+    
+    void usePut(size_t length)
+    {
+        assert(length <= available());
+        mEnd += length;
+    }
+    
+    // elementary get: locate mode
+    template <class T> void locateGet(T * &addr, size_t &length)
+    {
+        if (length > size_t(mEnd - mStart))
+            length = mEnd - mStart;
+        addr = reinterpret_cast<T *>(mStart);
+    }
+    
+    void useGet(size_t length)
+    {
+        assert(length <= this->length());
+        mStart += length;
+        adjustGet();
+    }
+    
+    //
+    // I/O via FileDescoid objects
+    //
+    template <class IO>
+    size_t read(IO &io, size_t length)
+    {
+        if (length > available())
+            length = shuffle(length);
+        size_t bytesRead = io.read(mEnd, length);
+        mEnd += bytesRead;
+        return bytesRead;
+    }
+    
+    template <class IO>
+    size_t write(IO &io, size_t length)
+    {
+        length = min(this->length(), length);
+        size_t bytesWritten = io.write(mStart, length);
+        mStart += bytesWritten;
+        adjustGet();
+        return bytesWritten;
+    }
+
+    template <class IO> size_t read(IO &io, bool heavy = false)
+    { return read(io, available(heavy)); }
+    
+    template <class IO> size_t write(IO &io)
+    { return write(io, length()); }
+
+    // printf-style output to a buffer
+    void printf(const char *format, ...);
+    void vprintf(const char *format, va_list args);
+
+    // memory ownership
+    void own()		{ mOwningMemory = true; }
+    
+private:
+    char *const mBase;			// base pointer
+    char *const mTop;			// end pointer + 1
+    char *mStart;				// start of used area
+    char *mEnd;					// end of used area + 1
+    bool mOwningMemory;			// true if we own the memory (free on destruction)
+};
+
+
+}	// end namespace Security
+
+
+#endif //_H_BUFFER
diff --git a/cdsa/cdsa_utilities/callback.cpp b/cdsa/cdsa_utilities/callback.cpp
new file mode 100644
index 00000000..17ebb145
--- /dev/null
+++ b/cdsa/cdsa_utilities/callback.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+
+//
+// Encapsulate the callback mechanism of CSSM.
+//
+#ifdef __MWERKS__
+#define _CPP_CALLBACK
+#endif
+#include <Security/callback.h>
+
+
+//
+// Invoke a callback
+//
+void ModuleCallback::operator () (CSSM_MODULE_EVENT event,
+                                  const Guid &guid, uint32 subId,
+                                  CSSM_SERVICE_TYPE serviceType) const
+{
+    if (mCallback)
+        if (CSSM_RETURN err = mCallback(&guid, mContext, subId, serviceType, event))
+            CssmError::throwMe(err);
+}
+
+
+//
+// Manage Callback sets.
+// THREADS: Caller is ensuring single-thread access on these calls.
+//
+void ModuleCallbackSet::insert(const ModuleCallback &newCallback)
+{
+    callbacks.insert(CallbackMap::value_type(newCallback, new CountingMutex));
+}
+
+void ModuleCallbackSet::erase(const ModuleCallback &oldCallback)
+{
+    CallbackMap::iterator it = callbacks.find(oldCallback);
+    if (it == callbacks.end())	// not registered; fail
+        CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
+    CountingMutex *counter = it->second;
+    {
+        StLock<Mutex> _(*counter);
+        if (!counter->isIdle()) // callbacks are scheduled against this
+            CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED);	// @#module is busy
+    }
+    // counter is zero (idle), and we hold the entry lock (via our caller)
+    delete counter;
+    callbacks.erase(it);
+}
+
+
+//
+// Invoke an entire callback set.
+// THREADS: Caller is ensuring  single-thread access on these calls.
+//
+void ModuleCallbackSet::operator () (CSSM_MODULE_EVENT event,
+                                     const Guid &guid, uint32 subId,
+                                     CSSM_SERVICE_TYPE serviceType) const
+{
+    if (callbacks.empty())	// nothing to do; quick exit
+        return;
+
+#if _USE_THREADS == _USE_NO_THREADS || defined(SYNCHRONOUS_CALLBACKS)
+    // no threading model supported - we HAVE to do this right here
+    // note that the user better not re-enter CSSM too much,
+    // or we might deadlock...
+    for (CallbackMap::const_iterator it = callbacks.begin();
+         it != callbacks.end(); it++) {
+        it->first(event, guid, subId, serviceType);
+    }
+#else // real threads available
+    // lock down all callback elements - still protected by global lock (via caller)
+    for (CallbackMap::iterator it = callbacks.begin();
+         it != callbacks.end(); it++)
+        it->second->enter();
+
+    // get out of this thread - now!
+    (new Runner(callbacks, event, guid, subId, serviceType))->run();
+#endif
+}
+
+void ModuleCallbackSet::Runner::action()
+{
+    //
+    // NOTE WELL: Our callbacks map shares (pointed-to) values with the ModuleCallbackSet
+    // we were created from. Some of these values may be dangling pointers since they have
+    // been destroyed by other threads, but only *after* we are done with them, since
+    // we must call exit() on them before they become eligible for destruction.
+    // In all cases, it is the responsibility of other threads to destroy those mutexi.
+    //
+    // @@@ Could also fan out to multiple callback threads in parallel.
+    for (CallbackMap::iterator it = callbacks.begin();
+         it != callbacks.end(); it++) {
+        //@@@ safety vs. convenience - recheck
+        it->first(event, guid, subserviceId, serviceType);
+        it->second->exit();
+    }
+}
diff --git a/cdsa/cdsa_utilities/callback.h b/cdsa/cdsa_utilities/callback.h
new file mode 100644
index 00000000..8b5f9f83
--- /dev/null
+++ b/cdsa/cdsa_utilities/callback.h
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+
+//
+// Encapsulate the callback mechanism of CSSM.
+//
+#ifndef _H_CALLBACK
+#define _H_CALLBACK
+
+#include <Security/utilities.h>
+#include <Security/threading.h>
+#include <map>
+
+#ifdef _CPP_CALLBACK
+#pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// A single module-specific callback as requested by the user.
+//
+class ModuleCallback {
+public:
+	ModuleCallback() : mCallback(0), mContext(0) { }
+    ModuleCallback(CSSM_API_ModuleEventHandler callback, void *context)
+    : mCallback(callback), mContext(context) { }
+
+    void operator () (CSSM_MODULE_EVENT event,
+                      const Guid &guid, uint32 subId,
+                      CSSM_SERVICE_TYPE serviceType) const;
+
+    operator bool () const { return mCallback || mContext; }
+    bool operator ! () const { return !bool(*this); }
+
+    bool operator == (const ModuleCallback &cb) const
+    { return mCallback == cb.mCallback && mContext == cb.mContext; }
+    bool operator < (const ModuleCallback &cb) const
+    { return mCallback < cb.mCallback
+        || mCallback == cb.mCallback && mContext < cb.mContext; }
+
+private:
+    CSSM_API_ModuleEventHandler mCallback;
+    void *mContext;
+};
+
+
+//
+// A set of callbacks that can be invoked automatically in a thread-safe manner.
+// THREADS: The set itself is not interlocked by the ModuleCallbackSet class; you
+// are responsible for ensuring single access to the set object. The class ensures
+// that any threads it spawns to execute the callbacks will not step on each other
+// or on you, and that you will not be able to erase() a callback while it has
+// activity scheduled against it. This also applies to the invocation method
+// (operator ()) - you must lock against multiple accesses to it until it returns.
+//
+class ModuleCallbackSet {
+public:
+    unsigned int size() const { return callbacks.size(); }
+    void insert(const ModuleCallback &newCallback);
+    void erase(const ModuleCallback &oldCallback);
+
+    void operator () (CSSM_MODULE_EVENT event,
+                      const Guid &guid, uint32 subId,
+                      CSSM_SERVICE_TYPE serviceType) const;
+
+private:
+    // note mutex *: we don't want to rely on copy-ability of Mutex objects
+    typedef multimap<ModuleCallback, CountingMutex *> CallbackMap;
+    mutable CallbackMap callbacks;
+
+    struct Runner : public Thread {
+        Runner(CallbackMap &inCallbacks,
+               CSSM_MODULE_EVENT inEvent,
+               const Guid &inGuid,
+               uint32 inSSId,
+               CSSM_SERVICE_TYPE inServiceType)
+        : callbacks(inCallbacks), event(inEvent), guid(inGuid),
+        subserviceId(inSSId), serviceType(inServiceType) { }
+        
+        CallbackMap callbacks;	// note that we share the CountingMutex * values!
+        const CSSM_MODULE_EVENT event;
+        const Guid guid;
+        const uint32 subserviceId;
+        const CSSM_SERVICE_TYPE serviceType;
+
+        void action();
+    };
+};
+
+} // end namespace Security
+
+#ifdef _CPP_CALLBACK
+#pragma export off
+#endif
+
+#endif //_H_CALLBACK
diff --git a/cdsa/cdsa_utilities/codesigning.cpp b/cdsa/cdsa_utilities/codesigning.cpp
new file mode 100644
index 00000000..96bc0716
--- /dev/null
+++ b/cdsa/cdsa_utilities/codesigning.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+
+//
+// codesigning - support for signing and verifying "bags o' bits" on disk.
+//
+#ifdef __MWERKS__
+#define _CPP_CODESIGNING
+#endif
+
+#include <Security/codesigning.h>
+
+
+namespace Security
+{
+
+namespace CodeSigning
+{
+} // end namespace CodeSigning
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/codesigning.h b/cdsa/cdsa_utilities/codesigning.h
new file mode 100644
index 00000000..782a7c34
--- /dev/null
+++ b/cdsa/cdsa_utilities/codesigning.h
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+
+//
+// codesigning - support for signing and verifying "bags o' bits" on disk.
+//
+// This file defines CodeSigner objects that sign, SignableCode objects
+// that can be signed, and CodeSignature objects that represent signatures.
+// Anything that can be "enumerated" into a stream of bits is fair game as
+// a SignableCode, though the primary intent is to sign files or directories
+// of files on disk.
+//
+#ifndef _CODESIGNING
+#define _CODESIGNING
+
+#include <Security/utilities.h>
+#include <string>
+
+#ifdef _CPP_CODESIGNING
+#pragma export on
+#endif
+
+namespace Security
+{
+
+namespace CodeSigning
+{
+
+//
+// Type codes for signatures. Each represents a particular type of signature.
+//
+enum {
+	standardOSXSignature = 1			// standard MacOS X signature (SHA1)
+};
+
+
+//
+// A CodeSignature is an abstract object representing a complete signature.
+// You may think of this as a cryptographic hash of some kind together with
+// type information and enough abstraction to make changing the algorithms
+// easier.
+//
+class Signature {
+public:
+	virtual ~Signature() { }
+	
+	virtual bool operator == (const Signature &other) const = 0;
+	bool operator != (const Signature &other) const		{ return !(*this == other); }
+	
+	virtual uint32 type() const = 0;		// yield type code
+	virtual const void *data() const = 0;	// yield data pointer
+	virtual size_t length() const = 0;		// yield length of data
+};
+
+
+//
+// A Signer is the engine that can sign and verify. It may have configuration,
+// but it should have NO state that carries over between signing/verifying
+// operations. In other words, once a signing/verifyng operation is complete,
+// the signer should forget about what it did.
+//
+class Signer {
+	friend class Signable;
+public:
+	virtual ~Signer() { }
+	
+public:
+	class State {
+	public:
+		virtual void enumerateContents(const void *data, size_t length) = 0;
+		
+		Signer &signer;
+		
+	protected:
+		State(Signer &sgn) : signer(sgn) { }
+	};
+	
+public:
+	virtual Signature *sign(const Signable &target) = 0;
+	virtual bool verify(const Signable &target, const Signature *signature) = 0;
+	
+	virtual Signature *restore(uint32 type, const void *data, size_t length) = 0;
+	Signature *restore(uint32 type, const CssmData &data)
+	{ return restore(type, data.data(), data.length()); }
+
+protected:
+	void scanContents(State &state, const Signable &target);
+};
+
+
+//
+// A Signable object represents something that can be signed
+//
+class Signable {
+	friend class Signer;
+public:
+	virtual ~Signable() { }
+	
+	Signature *sign(Signer &signer) const
+	{ return signer.sign(*this); }
+	bool verify(const Signature *signature, Signer &signer) const
+	{ return signer.verify(*this, signature); }
+
+protected:
+	virtual void scanContents(Signer::State &state) const = 0;
+};
+
+
+//
+// Close mutually recursive calls
+//
+inline void Signer::scanContents(State &state, const Signable &target)
+{
+	target.scanContents(state);
+}
+
+} // end namespace CodeSigning
+
+} // end namespace Security
+
+#ifdef _CPP_CODESIGNING
+#pragma export off
+#endif
+
+
+#endif //_CODESIGNING
diff --git a/cdsa/cdsa_utilities/constdata.cpp b/cdsa/cdsa_utilities/constdata.cpp
new file mode 100644
index 00000000..b1978f54
--- /dev/null
+++ b/cdsa/cdsa_utilities/constdata.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+
+//
+// constdata - shared constant binary data objects
+//
+#include "constdata.h"
+#include <Security/debugging.h>
+
+
+namespace Security {
+
+
+//
+// Construct a Blob from a source
+//
+ConstData::Blob::Blob(const void *base, size_t size, bool takeOwnership) : mSize(size)
+{
+    mData = takeOwnership ? base : memcpy(new char[size], base, size);
+}
+
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/constdata.h b/cdsa/cdsa_utilities/constdata.h
new file mode 100644
index 00000000..da75382e
--- /dev/null
+++ b/cdsa/cdsa_utilities/constdata.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+
+//
+// constdata - shared constant binary data objects
+//
+#ifndef _H_CONSTDATA
+#define _H_CONSTDATA
+
+#include <Security/utilities.h>
+#include <Security/refcount.h>
+
+
+namespace Security {
+
+
+//
+// ConstData represents a contiguous, binary blob of constant data.
+// Assignment is by sharing (thus cheap).
+// ConstData is a (constant) Dataoid type.
+//
+class ConstData {    
+private:
+    class Blob : public RefCount {
+    public:
+        Blob() : mData(NULL), mSize(0) { }
+        Blob(const void *base, size_t size, bool takeOwnership = false);
+        ~Blob()		{ delete[] reinterpret_cast<const char *>(mData); }
+    
+        const void *data() const	{ return mData; }
+        size_t length() const		{ return mSize; }
+    
+    private:
+        const void *mData;
+        size_t mSize;
+    };
+    
+public:
+    ConstData() { }		//@@@ use a nullBlob?
+    ConstData(const void *base, size_t size, bool takeOwnership = false)
+        : mBlob(new Blob(base, size, takeOwnership)) { }
+        
+    template <class T>
+    static ConstData wrap(const T &obj, bool takeOwnership)
+    { return ConstData(&obj, sizeof(obj), takeOwnership); }
+    
+public:
+    const void *data() const	{ return mBlob ? mBlob->data() : NULL; }
+    size_t length() const		{ return mBlob ? mBlob->length() : 0; }
+    
+    operator bool() const		{ return mBlob; }
+    bool operator !() const		{ return !mBlob; }
+
+    template <class T> operator const T *() const
+    { return reinterpret_cast<const T *>(data()); }
+    
+    template <class T> const T &as() const
+    { return *static_cast<const T *>(reinterpret_cast<const T *>(data())); }
+    
+private:
+    RefPointer<Blob> mBlob;
+};
+
+
+}	// end namespace Security
+
+
+#endif //_H_CONSTDATA
diff --git a/cdsa/cdsa_utilities/context.cpp b/cdsa/cdsa_utilities/context.cpp
new file mode 100644
index 00000000..ca2e2e5e
--- /dev/null
+++ b/cdsa/cdsa_utilities/context.cpp
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+
+//
+// context - manage CSSM (cryptographic) contexts every which way.
+//
+// A note on memory management:
+// Context attributes are allocated from application memory in big chunks comprising
+// many attributes as well as the attribute array itself. The CSSM_CONTEXT fields
+// NumberOfAttributes and ContextAttributes are handled as a group. Context::Builder
+// and Context::copyFrom assume these fields are undefined and fill them. Context::clear
+// assumes they are valid and invalides them, freeing memory.
+//
+// You may also want to look at cssmcontext.h in CSSM proper, where CSSM's internal Context
+// objects are built on top of our Context class.
+//
+#include <Security/context.h>
+
+
+//
+// Delete a single attribute from a Context by type.
+// We implement this by simply nulling out the slot - the memory is not released,
+// and will not be reclaimed until the Context is deleted or reconstructed for some reason.
+//
+void Context::deleteAttribute(CSSM_ATTRIBUTE_TYPE type)
+{
+    for (uint32 n = 0; n < attributesInUse(); n++)
+        if (ContextAttributes[n].AttributeType == type) {
+            ContextAttributes[n].AttributeType = CSSM_ATTRIBUTE_NONE; 
+            ContextAttributes[n].AttributeLength = 0;
+            return;
+        }
+    // not found
+    CssmError::throwMe(CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT);
+}
+
+
+//
+// This swiss-army-knife function performs a deep copy of all of a Context's attributes,
+// bundling them up into a single memory node and storing them into a pointer/count pair.
+// It also returns the size of the memory block allocated, in case you care (IPC does).
+//
+size_t Context::copyAttributes(CSSM_CONTEXT_ATTRIBUTE * &attrs, uint32 &count,
+							   CssmAllocator &alloc) const
+{
+    Context::Builder builder(alloc);
+    for (unsigned n = 0; n < attributesInUse(); n++)
+        builder.setup(ContextAttributes[n]);
+    size_t size = builder.make();
+    for (unsigned n = 0; n < attributesInUse(); n++)
+        builder.put(ContextAttributes[n]);
+    builder.done(attrs, count);
+	return size;
+}
+
+
+//
+// Locate attribute values by type.
+// This function deals in attribute vectors, not contexts; hence the explicit count argument.
+// Returns NULL for attribute not found.
+//
+Context::Attr *Context::find(CSSM_ATTRIBUTE_TYPE theType,
+                             const CSSM_CONTEXT_ATTRIBUTE *attrs, unsigned int count)
+{
+    for (unsigned n = 0; n < count; n++)
+        if (attrs[n].AttributeType == theType)
+            return (Attr *)&attrs[n];
+    return NULL;
+}
+
+
+//
+// Post-IPC context fixup.
+// A Context is transmitted via IPC as a two-element blob. The first is the Context
+// structure itself, which is taken as flat. The second is the flattened attribute
+// vector blob as produced by the Context::Builder class. Since IPC will relocate
+// each blob, we need to offset all internal pointers to compensate.
+//
+void Context::postIPC(void *base, CSSM_CONTEXT_ATTRIBUTE *ipcAttributes)
+{
+	ReconstituteWalker relocator(LowLevelMemoryUtilities::difference(ipcAttributes, base));
+	ContextAttributes = ipcAttributes;	// fix context->attr vector link
+	for (uint32 n = 0; n < attributesInUse(); n++)
+		walk(relocator, (*this)[n]);
+}
+
+
+//
+// Context Builders
+//
+size_t Context::Builder::make()
+{
+    size_t vectorSize =
+		LowLevelMemoryUtilities::alignUp(slotCount * sizeof(CSSM_CONTEXT_ATTRIBUTE));
+    size_t totalSize = vectorSize + sizer;
+    attributes = reinterpret_cast<Attr *>(allocator.malloc(totalSize));
+    copier = LowLevelMemoryUtilities::increment(attributes, vectorSize);
+    slot = 0;
+	return totalSize;
+}
+
+void Context::Builder::done(CSSM_CONTEXT_ATTRIBUTE * &attributes, uint32 &count)
+{
+    assert(slot == slotCount);	// match pass profiles
+    attributes = this->attributes;
+    count = slotCount;
+    this->attributes = NULL;	// delivered the goods, no longer our responsibility
+}
+
+
+//
+// Debugging support
+//
+#if defined(DEBUGDUMP)
+
+static void dumpData(CSSM_DATA *data)
+{
+	if (data == NULL)
+		Debug::dump("[NULL]");
+	else
+		Debug::dump("[%p,%ld]@%p", data->Data, data->Length, data);
+}
+
+void Context::Attr::dump() const
+{
+    Debug::dump(" Attr{type=%x, size=%d, value=", int(AttributeType), int(AttributeLength));
+    switch (AttributeType & CSSM_ATTRIBUTE_TYPE_MASK) {
+        case CSSM_ATTRIBUTE_DATA_UINT32:
+            Debug::dump("%ld", long(Attribute.Uint32)); break;
+        case CSSM_ATTRIBUTE_DATA_STRING:
+            Debug::dump("%s@%p", Attribute.String, Attribute.String); break;
+		case CSSM_ATTRIBUTE_DATA_CSSM_DATA:
+			dumpData(Attribute.Data);
+			break;
+		case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA:
+			dumpData(&Attribute.CryptoData->Param);
+			break;
+        default:
+            Debug::dump("%p", Attribute.String); break;	// (slightly unclean)
+    };
+    Debug::dump("}\n");
+}
+
+void Context::dump(const char *title, const CSSM_CONTEXT_ATTRIBUTE *attrs) const
+{
+	if (attrs == NULL)
+		attrs = ContextAttributes;
+    Debug::dump("Context %s{type=%d, alg=%d, CSP=%u, %d attributes@%p:\n",
+		   title ? title : "",
+           int(ContextType), int(AlgorithmType), (unsigned int)CSPHandle,
+           int(NumberOfAttributes), attrs);
+    for (unsigned int n = 0; n < NumberOfAttributes; n++)
+        Attr::overlay(attrs[n]).dump();
+    Debug::dump("} // end Context\n");
+}
+
+#endif //DEBUGDUMP
diff --git a/cdsa/cdsa_utilities/context.h b/cdsa/cdsa_utilities/context.h
new file mode 100644
index 00000000..7b9c34eb
--- /dev/null
+++ b/cdsa/cdsa_utilities/context.h
@@ -0,0 +1,342 @@
+/*
+ * 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.
+ */
+
+
+//
+// context - CSSM cryptographic context objects
+//
+#ifndef _H_CONTEXT
+#define _H_CONTEXT
+
+#include <Security/utilities.h>
+#include <Security/debugging.h>
+#include <Security/cssmalloc.h>
+#include <Security/cssmwalkers.h>
+#include <Security/cssmacl.h>	// to serialize/copy access credentials
+
+#ifdef _CPP_CONTEXT
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// Context is a POD overlay for the CSSM_CONTEXT type. It does
+// add allocation functions and lots of good stuff.
+// Note that if you're outside CSSM proper, you are not supposed to
+// memory-manage Context structures on your own. Be a good boy and
+// call the CSSM API functions.
+// We also provide a POD overlay for CSSM_CONTEXT_ATTRIBUTE, with
+// the obvious semantics.
+//
+class Context : public PodWrapper<Context, CSSM_CONTEXT> {
+public:
+    Context(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS algorithmId)
+    { ContextType = type; AlgorithmType = algorithmId; }
+
+    uint32 attributesInUse() const { return NumberOfAttributes; }
+    CSSM_CONTEXT_TYPE type() const { return ContextType; }
+    CSSM_ALGORITHMS algorithm() const { return AlgorithmType; }
+    CSSM_CSP_HANDLE cspHandle() const { return CSPHandle; }
+
+    void deleteAttribute(CSSM_ATTRIBUTE_TYPE type);
+	size_t copyAttributes(CSSM_CONTEXT_ATTRIBUTE * &attrs, uint32 &count, CssmAllocator &alloc) const;
+	
+    void copyFrom(const Context &source, CssmAllocator &alloc)
+	{ source.copyAttributes(ContextAttributes, NumberOfAttributes, alloc); }
+
+public:
+    class Attr : public PodWrapper<Attr, CSSM_CONTEXT_ATTRIBUTE> {
+    public:
+		Attr() { }
+        Attr(const CSSM_CONTEXT_ATTRIBUTE &attr) { (CSSM_CONTEXT_ATTRIBUTE &)*this = attr; }
+
+        template <class T>
+        Attr(CSSM_ATTRIBUTE_TYPE typ, T &value, size_t size = 0)
+        {
+            AttributeType = typ;
+			// attribute component pointers are stupidly non-const; allow const input
+            Attribute.String = const_cast<char *>(reinterpret_cast<const char *>(&value));
+            AttributeLength = size ? size : sizeof(T);
+        }
+
+        Attr(CSSM_ATTRIBUTE_TYPE typ, uint32 value)
+        {
+            AttributeType = typ;
+            Attribute.Uint32 = value;
+            AttributeLength = 0;
+        }
+        
+        CSSM_ATTRIBUTE_TYPE type() const { return AttributeType; }
+        uint32 baseType() const { return AttributeType & CSSM_ATTRIBUTE_TYPE_MASK; }
+
+        operator char * () const
+        { assert(baseType() == CSSM_ATTRIBUTE_DATA_STRING); return Attribute.String; }
+        operator CssmData & () const
+        { assert(baseType() == CSSM_ATTRIBUTE_DATA_CSSM_DATA);
+		  return CssmData::overlay(*Attribute.Data); }
+        operator CssmCryptoData & () const
+        { assert(baseType() == CSSM_ATTRIBUTE_DATA_CRYPTO_DATA);
+		  return CssmCryptoData::overlay(*Attribute.CryptoData); }
+        operator CssmKey & () const
+        { assert(baseType() == CSSM_ATTRIBUTE_DATA_KEY); return CssmKey::overlay(*Attribute.Key); }
+        operator AccessCredentials & () const
+        { assert(baseType() == CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS);
+		  return AccessCredentials::overlay(*Attribute.AccessCredentials); }
+        operator uint32 () const
+        { assert(baseType() == CSSM_ATTRIBUTE_DATA_UINT32); return Attribute.Uint32; }
+        operator CSSM_DL_DB_HANDLE &() const
+        {
+			assert(baseType() == CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE);
+			if (Attribute.DLDbHandle == NULL)
+				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_DL_DB_HANDLE);
+			return *Attribute.DLDbHandle;
+		}
+        // @@@ etc. etc. - add yours today!
+
+        void operator = (uint32 value) { Attribute.Uint32 = value; }
+        template <class T>
+        void operator = (T *ptr) { Attribute.String = reinterpret_cast<char *>(ptr); }
+
+        IFDUMP(void dump() const;)	// debug dump this Attr to stdout (one line)
+    };
+
+    // Attributes by position
+	Attr *attributes() const { return Attr::overlay(ContextAttributes); }
+    Attr &operator [] (unsigned int ix)
+    { assert(ix < NumberOfAttributes); return static_cast<Attr &>(ContextAttributes[ix]); }
+    const Attr &operator [] (unsigned int ix) const
+    { assert(ix < NumberOfAttributes); return static_cast<Attr &>(ContextAttributes[ix]); }
+
+    // general attribute retrieval by type
+    Attr *find(CSSM_ATTRIBUTE_TYPE theType) const
+    { return find(theType, ContextAttributes, NumberOfAttributes); }
+
+    template <class Elem>
+    Elem &get(CSSM_ATTRIBUTE_TYPE type, CSSM_RETURN err) const
+    {
+        if (Attr *attr = find(type))
+            return static_cast<Elem &>(*attr);
+        else
+            CssmError::throwMe(err);
+    }
+
+    template <class Elem>
+    Elem *get(CSSM_ATTRIBUTE_TYPE type) const
+    {
+        if (Attr *attr = find(type))
+            // @@@ Invoking conversion operator to Elem & on *attr and taking address of result.
+            return &static_cast<Elem &>(*attr);
+        else
+            return NULL;
+    }
+
+    uint32 getInt(CSSM_ATTRIBUTE_TYPE type, CSSM_RETURN err) const
+    {
+        if (Attr *attr = find(type))
+            return static_cast<uint32>(*attr);
+        else
+            CssmError::throwMe(err);
+    }
+
+    uint32 getInt(CSSM_ATTRIBUTE_TYPE type) const
+    {
+        if (Attr *attr = find(type))
+            return static_cast<uint32>(*attr);
+        else
+            return 0;
+    }
+	
+public:
+	template <class T>
+	void replace(CSSM_ATTRIBUTE_TYPE type, const T &newValue) const
+	{
+		if (Attr *attr = find(type))
+			*attr = Attr(type, newValue);
+		else
+			CssmError::throwMe(CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT);
+	}
+
+public:
+    void *operator new (size_t size, CssmAllocator &alloc)
+    { return alloc.malloc(size); }
+    void operator delete (void *addr, size_t, CssmAllocator &alloc)
+    { return alloc.free(addr); }
+    static void destroy(Context *context, CssmAllocator &alloc)
+    { alloc.free(context->ContextAttributes); alloc.free(context); }
+	
+public:
+	// Post-IPC context fixup.
+	// This can only be called on a Built Context after IPC transmission.
+	void postIPC(void *base, CSSM_CONTEXT_ATTRIBUTE *ipcAttributes);
+
+public:
+    class Builder;
+
+	// dump to stdout, multiline format
+    IFDUMP(void dump(const char *title = NULL,
+        const CSSM_CONTEXT_ATTRIBUTE *attrs = NULL) const;)
+
+protected:
+    // find an attribute in a plain array of attribute structures (no context)
+    static Attr *find(CSSM_ATTRIBUTE_TYPE theType,
+    				  const CSSM_CONTEXT_ATTRIBUTE *attrs, unsigned int count);
+};
+
+
+namespace DataWalkers
+{
+
+template <class Action>
+void walk(Action &operate, CSSM_CONTEXT_ATTRIBUTE &attr)
+{
+    switch (attr.AttributeType & CSSM_ATTRIBUTE_TYPE_MASK) {
+        case CSSM_ATTRIBUTE_DATA_CSSM_DATA:
+            walk(operate, attr.Attribute.Data); break;
+		case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA:
+            walk(operate, attr.Attribute.CryptoData); break;
+        case CSSM_ATTRIBUTE_DATA_KEY:
+            walk(operate, attr.Attribute.Key); break;
+        case CSSM_ATTRIBUTE_DATA_STRING:
+            walk(operate, attr.Attribute.String); break;
+        case CSSM_ATTRIBUTE_DATA_DATE:
+            walk(operate, attr.Attribute.Date); break;
+        case CSSM_ATTRIBUTE_DATA_RANGE:
+            walk(operate, attr.Attribute.Range); break;
+        case CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS:
+            walk(operate, attr.Attribute.AccessCredentials); break;
+        case CSSM_ATTRIBUTE_DATA_VERSION:
+            walk(operate, attr.Attribute.Version); break;
+        case CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE:
+            walk(operate, attr.Attribute.DLDbHandle); break;
+        case CSSM_ATTRIBUTE_NONE:
+        case CSSM_ATTRIBUTE_DATA_UINT32:
+            break;
+        default:
+            assert(false);	// unexpected type
+    }
+}
+
+} // end namespace DataWalkers
+
+
+//
+// Context::Builder - make context attributes the fun way.
+//
+// A Context (aka CSSM_CONTEXT) has a pointer to an array of context attributes,
+// most of which contain pointers to other stuff with pointers to God Knows Where.
+// Instead of allocating this all over the heap, a Context::Builder performs
+// a two-pass algorithm that places all that stuff into a single heap node.
+// Specifically, the builder will allocate and create a vector of CSSM_CONTEXT_ATTRIBUTE
+// structures and all their subordinate heap storage.
+// A Builder does not deal in Context objects and does not care what you do with your
+// CSSM_CONTEXT_ATTRIBUTE array once it's delivered. Since it's a single heap node,
+// you can just free() it using the appropriate allocator when you're done with it.
+//
+// Theory of operation:
+// Builder works in two phases, called scan and build. During scan, you call setup()
+// with the desired data to be placed into the attribute vector. When done, call make()
+// to switch to build phase. Then call put() with the SAME sequence of values as in phase 1.
+// Finally, call done() to receive the pointer-and-count values.
+// @@@ Add comment about IPC use.
+//
+using namespace DataWalkers;
+
+class Context::Builder {
+protected:
+public:
+    Builder(CssmAllocator &alloc) : allocator(alloc)
+    { slotCount = 0; attributes = NULL; }
+    ~Builder() { allocator.free(attributes); }
+
+    CssmAllocator &allocator;
+
+    // switch to build phase
+    size_t make();
+    // deliver result
+    void done(CSSM_CONTEXT_ATTRIBUTE * &attributes, uint32 &count);
+
+public:
+    //
+    // Phase 1 (scan) dispatch. Call once for each attribute needed.
+	//
+    template <class T>
+    void setup(T p, CSSM_RETURN invalidError = CSSM_OK)
+    {
+        if (p) {
+            slotCount++;
+			walk(sizer, p);
+        } else if (invalidError)
+            CssmError::throwMe(invalidError);
+    }
+	// dynamic attribute type
+    void setup(const CSSM_CONTEXT_ATTRIBUTE &attr)
+	{ slotCount++; walk(sizer, const_cast<CSSM_CONTEXT_ATTRIBUTE &>(attr)); }
+	void setup(const Context::Attr &attr) { setup(static_cast<const CSSM_CONTEXT_ATTRIBUTE &>(attr)); }
+
+    //
+    // Phase 2 (copy) dispatch. Call once for each attribute, in same order as setup().
+    //
+    template <class T>
+    void put(CSSM_ATTRIBUTE_TYPE type, const T *p)
+    {
+        if (p) {
+            assert(slot < slotCount);			// check overflow
+            Attr &attribute = attributes[slot++];
+            attribute.AttributeType = type;
+            attribute.AttributeLength = size(p); //@@@ needed? how/when/what for?
+			attribute = walk(copier, p);
+        }
+    }
+    void put(CSSM_ATTRIBUTE_TYPE type, uint32 value)
+    {
+        if (value) {
+            assert(slot < slotCount);			// check overflow
+            Attr &attribute = attributes[slot++];
+            attribute.AttributeType = type;
+            attribute.AttributeLength = 0;		//@@@ unclear what that should be
+            attribute = value;					// no heap data (immediate value)
+        }
+    }
+	void put(const CSSM_CONTEXT_ATTRIBUTE &attr)
+	{
+		assert(slot < slotCount);
+		Attr &attribute = attributes[slot++];
+		attribute = attr;	// shallow copy
+		walk(copier, attribute);	// deep copy
+	}
+	void put(const Context::Attr &attr) { put(static_cast<const CSSM_CONTEXT_ATTRIBUTE &>(attr)); }
+	
+private:
+    // pass 1 state: collect sizes and counts
+    unsigned slotCount;					// count of attribute slots in use
+	SizeWalker sizer;					// memory size calculator
+
+    // pass 2 state: build the data set
+    Context::Attr *attributes;			// attribute vector and start of block
+	CopyWalker copier;					// data copy engine
+    uint32 slot;						// writer slot position
+};
+
+} // end namespace Security
+
+#ifdef _CPP_CONTEXT
+# pragma export off
+#endif
+
+#endif //_H_CONTEXT
diff --git a/cdsa/cdsa_utilities/cssmacl.cpp b/cdsa/cdsa_utilities/cssmacl.cpp
new file mode 100644
index 00000000..cc700e22
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmacl.cpp
@@ -0,0 +1,528 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmacl - core ACL management interface
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMACL
+#endif
+
+#include <Security/cssmacl.h>
+#include <Security/debugging.h>
+#include <algorithm>
+#include <cstdarg>
+
+using namespace DataWalkers;
+
+
+//
+// The static map of available ACL subject makers.
+// These are the kinds of ACL subjects we can deal with.
+//
+ModuleNexus<ObjectAcl::MakerMap> ObjectAcl::makers;
+
+
+//
+// Common (basic) features of AclSubjects
+//
+AclSubject::~AclSubject()
+{ }
+
+AclValidationEnvironment::~AclValidationEnvironment()
+{ }
+
+void AclSubject::exportBlob(Writer::Counter &, Writer::Counter &)
+{ }
+
+void AclSubject::exportBlob(Writer &, Writer &)
+{ }
+
+void AclSubject::importBlob(Reader &, Reader &)
+{ }
+
+AclSubject::Maker::~Maker()
+{
+}
+
+//
+// A SimpleAclSubject accepts only a single type of sample, validates
+// samples independently, and makes no use of certificates.
+//
+bool SimpleAclSubject::validate(const AclValidationContext &ctx) const
+{
+    for (uint32 n = 0; n < ctx.count(); n++) {
+        const TypedList &sample = ctx[n];
+        if (!sample.isProper())
+            CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+        if (sample.type() == acceptingSamples && validate(ctx, sample))
+            return true;	// matched this sample; validation successful
+    }
+    return false;
+}
+
+
+//
+// Create an ObjectAcl
+//
+ObjectAcl::ObjectAcl(CssmAllocator &alloc) : allocator(alloc), nextHandle(1)
+{
+}
+
+ObjectAcl::ObjectAcl(const AclEntryPrototype &proto, CssmAllocator &alloc)
+    : allocator(alloc), nextHandle(1)
+{
+    cssmSetInitial(proto);
+}
+
+ObjectAcl::~ObjectAcl()
+{ }
+
+
+//
+// Set an "initial ACL" from a CSSM-style initial ACL argument.
+// This will replace the owner, as well as replace the entire ACL
+// with a single-item slot, as per CSSM specification.
+//
+void ObjectAcl::cssmSetInitial(const AclEntryPrototype &proto)
+{
+    owner = OwnerEntry(proto);
+    entries.insert(EntryMap::value_type("", proto))->second.handle = nextHandle++;
+}
+
+void ObjectAcl::cssmSetInitial(const AclSubjectPointer &subject)
+{
+    owner = OwnerEntry(subject);
+    entries.insert(EntryMap::value_type("", subject))->second.handle = nextHandle++;
+}
+
+ObjectAcl::Entry::~Entry()
+{
+}
+
+AclValidationContext::~AclValidationContext()
+{
+}
+
+//
+// ObjectAcl::validate validates an access authorization claim.
+// Returns normally if 'auth' is granted to the bearer of 'cred'.
+// Otherwise, throws a suitable (ACL-related) CssmError exception.
+// @@@ Should it return a reference to the Entry that granted access?
+//
+class BaseValidationContext : public AclValidationContext {
+public:
+    BaseValidationContext(const AccessCredentials *cred,
+        AclAuthorization auth, AclValidationEnvironment *env)
+        : AclValidationContext(cred, auth, env) { }
+    
+    uint32 count() const { return mCred ? mCred->samples().length() : 0; }
+    const TypedList &sample(uint32 n) const
+    { assert(n < count()); return mCred->samples()[n]; }
+};
+
+void ObjectAcl::validate(AclAuthorization auth, const AccessCredentials *cred,
+    AclValidationEnvironment *env) const
+{
+    //@@@ should pre-screen based on requested auth, maybe?
+    BaseValidationContext ctx(cred, auth, env);
+
+#if defined(ACL_OMNIPOTENT_OWNER)
+    // try owner (owner can do anything)
+    if (owner.validate(ctx))
+        return;
+#endif ACL_OMNIPOTENT_OWNER
+
+    // try applicable ACLs
+    pair<ConstIterator, ConstIterator> range;
+    if (getRange(cred->EntryTag, range) == 0)	// no such tag
+        CssmError::throwMe(CSSM_ERRCODE_ACL_ENTRY_TAG_NOT_FOUND);
+    // try entries in turn
+    for (ConstIterator it = range.first; it != range.second; it++) {
+        const AclEntry &slot = it->second;
+        if (slot.authorizes(ctx.authorization()) && slot.validate(ctx))
+            return;	// passed
+    }
+    CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);	//@@@ imprecise
+}
+
+void ObjectAcl::validateOwner(AclAuthorization authorizationHint,
+	const AccessCredentials *cred, AclValidationEnvironment *env) const
+{
+    BaseValidationContext ctx(cred, authorizationHint, env);
+    if (owner.validate(ctx))
+        return;
+    CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
+}
+
+
+//
+// Export an ObjectAcl to two memory blobs: public and private data separated.
+// This is a standard two-pass size+copy operation.
+//
+void ObjectAcl::exportBlob(CssmData &publicBlob, CssmData &privateBlob)
+{
+    Writer::Counter pubSize, privSize;
+	uint32 entryCount = entries.size();
+    owner.exportBlob(pubSize, privSize);
+	pubSize(entryCount);
+    for (Iterator it = begin(); it != end(); it++)
+        it->second.exportBlob(pubSize, privSize);
+    publicBlob = CssmData(allocator.malloc(pubSize), pubSize);
+    privateBlob = CssmData(allocator.malloc(privSize), privSize);
+    Writer pubWriter(publicBlob), privWriter(privateBlob);
+    owner.exportBlob(pubWriter, privWriter);
+	pubWriter(entryCount);
+    for (Iterator it = begin(); it != end(); it++)
+        it->second.exportBlob(pubWriter, privWriter);
+}
+
+
+//
+// Import an ObjectAcl's contents from two memory blobs representing public and
+// private contents, respectively. These blobs must have been generated by the
+// export method.
+// Prior contents (if any) are deleted and replaced.
+//
+void ObjectAcl::importBlob(const void *publicBlob, const void *privateBlob)
+{
+    Reader pubReader(publicBlob), privReader(privateBlob);
+    owner.importBlob(pubReader, privReader);
+	uint32 entryCount; pubReader(entryCount);
+	entries.erase(begin(), end());
+	for (uint32 n = 0; n < entryCount; n++) {
+		AclEntry newEntry;
+		newEntry.importBlob(pubReader, privReader);
+		entries.insert(EntryMap::value_type(newEntry.tag, newEntry))->second.handle = nextHandle++;
+	}
+	IFDUMPING("acl", debugDump("imported"));
+}
+
+
+//
+// ACL utility methods
+//
+unsigned int ObjectAcl::getRange(const char *tag, pair<ConstIterator, ConstIterator> &range) const
+{
+    if (tag) {
+        range = entries.equal_range(tag);
+        uint32 count = entries.count(tag);
+        if (count == 0)
+            CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
+        return count;
+    } else {
+        range.first = entries.begin();
+        range.second = entries.end();
+        return entries.size();
+    }
+}
+
+ObjectAcl::Iterator ObjectAcl::findEntryHandle(CSSM_ACL_HANDLE handle)
+{
+    for (Iterator it = entries.begin(); it != entries.end(); it++)
+        if (it->second.handle == handle)
+            return it;
+    CssmError::throwMe(CSSMERR_CSSM_INVALID_HANDLE_USAGE);	//%%% imprecise error code
+}
+
+
+//
+// CSSM style ACL access and modification functions.
+//
+void ObjectAcl::cssmGetAcl(const char *tag, uint32 &count, AclEntryInfo * &acls)
+{
+    pair<ConstIterator, ConstIterator> range;
+    count = getRange(tag, range);
+    acls = allocator.alloc<AclEntryInfo>(count);
+    uint32 n = 0;
+    for (ConstIterator it = range.first; it != range.second; it++, n++) {
+        acls[n].EntryHandle = it->second.handle;
+        it->second.toEntryInfo(acls[n].EntryPublicInfo, allocator);
+    }
+    count = n;
+}
+
+void ObjectAcl::cssmChangeAcl(const AclEdit &edit,
+	const AccessCredentials *cred, AclValidationEnvironment *env)
+{
+	IFDUMPING("acl", debugDump("acl-change-from"));
+
+    // validate access credentials
+    validateOwner(CSSM_ACL_AUTHORIZATION_CHANGE_ACL, cred, env);
+    
+    // what is Thy wish, effendi?
+    switch (edit.EditMode) {
+    case CSSM_ACL_EDIT_MODE_ADD: {
+        AclEntry ent(Required(edit.newEntry()).proto());	//@@@ bypassing callback
+        ent.handle = nextHandle++;
+        entries.insert(EntryMap::value_type(edit.NewEntry->Prototype.EntryTag, ent));
+        }
+        break;
+    case CSSM_ACL_EDIT_MODE_REPLACE: {
+		// keep the handle, and try for some modicum of atomicity
+        Iterator it = findEntryHandle(edit.OldEntryHandle);
+		AclEntry ent(Required(edit.newEntry()).proto());
+		ent.handle = edit.OldEntryHandle;
+		entries.insert(EntryMap::value_type(edit.NewEntry->Prototype.EntryTag, ent));
+		entries.erase(it);
+        }
+        break;
+    case CSSM_ACL_EDIT_MODE_DELETE:
+        entries.erase(findEntryHandle(edit.OldEntryHandle));
+        break;
+    default:
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_EDIT_MODE);
+    }
+
+	IFDUMPING("acl", debugDump("owner-change-to"));
+}
+
+void ObjectAcl::cssmGetOwner(AclOwnerPrototype &outOwner)
+{
+    outOwner.TypedSubject = owner.subject->toList(allocator);
+    outOwner.Delegate = owner.delegate;
+}
+
+void ObjectAcl::cssmChangeOwner(const AclOwnerPrototype &newOwner,
+                                const AccessCredentials *cred, AclValidationEnvironment *env)
+{
+	IFDUMPING("acl", debugDump("owner-change-from"));
+
+    // only the owner entry can match
+    validateOwner(CSSM_ACL_AUTHORIZATION_CHANGE_OWNER, cred, env);
+        
+    // okay, replace it
+    owner = newOwner;
+
+	IFDUMPING("acl", debugDump("owner-change-to"));
+}
+
+
+//
+// Common features of ACL entries/owners
+//
+void ObjectAcl::Entry::init(const AclSubjectPointer &subject, bool delegate)
+{
+    this->subject = subject;
+    this->delegate = delegate;
+}
+
+void ObjectAcl::Entry::importBlob(Reader &pub, Reader &priv)
+{
+    // delegate is trivial
+    pub(delegate);
+    
+    // now reconstruct the (polymorphic) subject
+    CSSM_ACL_SUBJECT_TYPE subjectType; pub(subjectType);
+	subject = make(subjectType, pub, priv);
+}
+
+
+//
+// An OwnerEntry is a restricted EntryPrototype for use as the ACL owner.
+//
+bool ObjectAcl::OwnerEntry::authorizes(AclAuthorization) const
+{
+    return true;	// owner can do anything
+}
+
+bool ObjectAcl::OwnerEntry::validate(const AclValidationContext &ctx) const
+{
+    return subject->validate(ctx);		// simple subject match - no strings attached
+}
+
+
+//
+// An AclEntry has some extra goodies
+//
+ObjectAcl::AclEntry::AclEntry(const AclEntryPrototype &proto) : Entry(proto)
+{
+    tag = proto.tag();
+    if (proto.authorization().contains(CSSM_ACL_AUTHORIZATION_ANY))
+        authorizesAnything = true;	// anything else wouldn't add anything
+    else if (proto.authorization().empty())
+        authorizesAnything = true;	// not in standard, but common sense
+    else {
+        authorizesAnything = false;
+        authorizations = proto.authorization();
+    }
+    //@@@ not setting time range
+    // handle = not set here. Set by caller when the AclEntry is created.
+}
+
+ObjectAcl::AclEntry::AclEntry(const AclSubjectPointer &subject) : Entry(subject)
+{
+    authorizesAnything = true;	// by default, everything
+    //@@@ not setting time range
+}
+
+void ObjectAcl::AclEntry::toEntryInfo(CSSM_ACL_ENTRY_PROTOTYPE &info, CssmAllocator &alloc) const
+{
+    info.TypedSubject = subject->toList(alloc);
+    info.Delegate = delegate;
+    info.Authorization = AuthorizationGroup(authorizations, alloc);
+    //@@@ info.TimeRange = 
+    assert(tag.length() <= CSSM_MODULE_STRING_SIZE);
+    memcpy(info.EntryTag, tag.c_str(), tag.length() + 1);
+}
+
+bool ObjectAcl::AclEntry::authorizes(AclAuthorization auth) const
+{
+    return authorizesAnything || authorizations.find(auth) != authorizations.end();
+}
+
+bool ObjectAcl::AclEntry::validate(const AclValidationContext &ctx) const
+{
+    //@@@ not checking time ranges
+    return subject->validate(ctx);
+}
+
+void ObjectAcl::AclEntry::importBlob(Reader &pub, Reader &priv)
+{
+    Entry::importBlob(pub, priv);
+    const char *s; pub(s); tag = s;
+    pub(authorizesAnything);
+    authorizations.erase(authorizations.begin(), authorizations.end());
+    if (!authorizesAnything) {
+        uint32 count; pub(count);
+        for (uint32 n = 0; n < count; n++) {
+            AclAuthorization auth; pub(auth);
+            authorizations.insert(auth);
+        }
+    }
+    //@@@ import time range
+}
+
+
+//
+// Subject factory and makers
+//
+AclSubject::Maker::Maker(CSSM_ACL_SUBJECT_TYPE type) : myType(type)
+{
+    ObjectAcl::makers()[type] = this;
+}
+
+AclSubject *ObjectAcl::make(const TypedList &list)
+{
+    if (!list.isProper())
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+    return makerFor(list.type()).make(list);
+}
+
+AclSubject *ObjectAcl::make(CSSM_ACL_SUBJECT_TYPE type, Reader &pub, Reader &priv)
+{
+    return makerFor(type).make(pub, priv);
+}
+
+AclSubject::Maker &ObjectAcl::makerFor(CSSM_ACL_SUBJECT_TYPE type)
+{
+    AclSubject::Maker *maker = makers()[type];
+    if (maker == NULL)
+        CssmError::throwMe(CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED);
+    return *maker;
+}
+
+
+//
+// Parsing helper for subject makers.
+// Note that count/array exclude the first element of list, which is the subject type wordid.
+//
+void AclSubject::Maker::crack(const CssmList &list, uint32 count, ListElement **array, ...)
+{
+    if (count != list.length() - 1)
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+    if (count > 0) {
+        va_list args;
+        va_start(args, array);
+        ListElement *elem = list.first()->next();
+        for (uint32 n = 0; n < count; n++, elem = elem->next()) {
+            CSSM_LIST_ELEMENT_TYPE expectedType = va_arg(args, CSSM_LIST_ELEMENT_TYPE);
+            if (elem->type() != expectedType)
+                CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+            array[n] = elem;
+        }
+        va_end(args);
+    }
+}
+
+CSSM_WORDID_TYPE AclSubject::Maker::getWord(const ListElement &elem,
+    int min = 0, int max = INT_MAX)
+{
+    if (elem.type() != CSSM_LIST_ELEMENT_WORDID)
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+    CSSM_WORDID_TYPE value = elem;
+    if (value < min || value > max)
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
+    return value;
+}
+
+
+//
+// Debug dumping support
+//
+#if defined(DEBUGDUMP)
+
+void ObjectAcl::debugDump(const char *what) const
+{
+	if (!what)
+		what = "Dump";
+	Debug::dump("%p ACL %s: %d entries\n", this, what, int(entries.size()));
+	Debug::dump(" OWNER ["); owner.debugDump(); Debug::dump("]\n");
+	for (ConstIterator it = begin(); it != end(); it++) {
+		const AclEntry &ent = it->second;
+		Debug::dump(" (%ld:%s) [", ent.handle, ent.tag.c_str());
+		ent.debugDump();
+		Debug::dump("]\n");
+	}
+	Debug::dump("%p ACL END\n", this);
+}
+
+void ObjectAcl::Entry::debugDump() const
+{
+	subject->debugDump();
+	if (delegate)
+		Debug::dump(" DELEGATE");
+}
+
+void ObjectAcl::AclEntry::debugDump() const
+{
+	Entry::debugDump();
+	if (authorizesAnything) {
+		Debug::dump(" auth(ALL)");
+	} else {
+		Debug::dump(" auth(");
+		for (AclAuthorizationSet::iterator it = authorizations.begin();
+				it != authorizations.end(); it++)
+			Debug::dump(" %ld", *it);
+		Debug::dump(")");
+	}
+}
+
+void AclSubject::debugDump() const
+{
+	switch (type()) {
+	case CSSM_ACL_SUBJECT_TYPE_ANY:
+		Debug::dump("ANY");
+		break;
+	default:
+		Debug::dump("subject type=%d", int(type()));
+		break;
+	}
+}
+
+#endif //DEBUGDUMP
diff --git a/cdsa/cdsa_utilities/cssmacl.h b/cdsa/cdsa_utilities/cssmacl.h
new file mode 100644
index 00000000..de4bf859
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmacl.h
@@ -0,0 +1,355 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmacl - core ACL management interface.
+//
+// Statement of strategy:
+// Beyond the enhanced POD Wrappers for the various CSSM types, we find pure C++ classes
+// that implement ACLs in the local address space. ObjectAcl is the abstract interface
+// to an implementation of a CSSM ACL. It supports the CSSM interfaces for ACL manipulation.
+// @@@ TBA @@@
+//
+#ifndef _CSSMACL
+#define _CSSMACL
+
+#include <Security/cssmaclpod.h>
+#include <Security/cssmcred.h>
+#include <Security/refcount.h>
+#include <Security/globalizer.h>
+#include <Security/memutils.h>
+#include <map>
+#include <set>
+#include <string>
+#include <limits.h>
+
+#ifdef _CPP_CSSMACL
+#pragma export on
+#endif
+
+namespace Security
+{
+
+class AclValidationContext;
+
+
+//
+// The AclSubject class models an ACL "subject" object.
+// This is an abstract polymorphic class implementing various ACL subject types.
+// Note that it does contain some common code to make everybody's life easier.
+//
+class AclSubject : public RefCount {
+    typedef LowLevelMemoryUtilities::Writer Writer;
+    typedef LowLevelMemoryUtilities::Reader Reader;
+public:
+    AclSubject(uint32 type) : mType(type) { }
+    virtual ~AclSubject();
+    uint32 type() const { return mType; }
+    
+    virtual bool validate(const AclValidationContext &ctx) const = 0;
+    
+    // export to CSSM interface
+    virtual CssmList toList(CssmAllocator &alloc) const = 0;
+        
+    // export/import for save/restore interface
+    virtual void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
+    virtual void exportBlob(Writer &pub, Writer &priv);
+    virtual void importBlob(Reader &pub, Reader &priv);
+	
+	// debug suupport
+	IFDUMP(virtual void debugDump() const);
+    
+private:
+    CSSM_ACL_SUBJECT_TYPE mType;
+    
+public:
+    class Maker {
+    public:
+        Maker(CSSM_ACL_SUBJECT_TYPE type);
+		virtual ~Maker();
+        
+        uint32 type() const { return myType; }
+        virtual AclSubject *make(const TypedList &list) const = 0;
+        virtual AclSubject *make(Reader &pub, Reader &priv) const = 0;
+            
+    protected:
+        // list parsing helpers
+        static void crack(const CssmList &list, uint32 count,
+            ListElement **array = NULL, ...);
+        static CSSM_WORDID_TYPE getWord(const ListElement &list,
+            int min = 0, int max = INT_MAX);
+        
+    private:
+        CSSM_ACL_SUBJECT_TYPE myType;
+    };
+};
+
+
+//
+// A SimpleAclSubject validates a credential by scanning its samples
+// one at a time, without any interactions between them. Thus its validate()
+// can be a lot simpler.
+//
+class SimpleAclSubject : public AclSubject {
+public:
+    SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE su, CSSM_SAMPLE_TYPE sa)
+    : AclSubject(su), acceptingSamples(sa) { }
+    
+    bool validate(const AclValidationContext &ctx) const;
+    virtual bool validate(const AclValidationContext &baseCtx,
+        const TypedList &sample) const = 0;
+    
+    const CSSM_SAMPLE_TYPE acceptingSamples;
+};
+
+
+//
+// An AclValidationEnvironment can be subclassed to add context access to ACL subject
+// validation. If you use ACL subject classes that need context beyond the credential
+// structure itself, add that context to (a subclass of) CredentialsContext, pass that
+// to ObjectAcl::validate() along with the credentials, and have the Subject implementation
+// access validationContext.environment().
+//
+class AclValidationEnvironment {
+public:
+    virtual ~AclValidationEnvironment();	// ensure virtual methods (need dynamic_cast)
+};
+
+
+//
+// An AclValidationContext holds credential information in a semi-transparent
+// form. It's designed to provide a uniform representation of credentials, plus
+// any (trusted path and/or implicit) context information useful for ACL validation.
+//
+class AclValidationContext {
+public:
+    AclValidationContext(const AccessCredentials *cred,
+        AclAuthorization auth, AclValidationEnvironment *env = NULL)
+    : mCred(cred), mAuth(auth), mEnv(env) { }
+    AclValidationContext(const AclValidationContext &ctx)
+    : mCred(ctx.mCred), mAuth(ctx.mAuth), mEnv(ctx.mEnv) { }
+	virtual ~AclValidationContext();
+
+    // access to (suitably focused) sample set
+    virtual uint32 count() const = 0;	// number of samples
+    virtual const TypedList &sample(uint32 n) const = 0;	// retrieve one sample
+    const TypedList &operator [] (uint32 n) const { return sample(n); }
+    
+    // context access
+    AclAuthorization authorization() const { return mAuth; }
+    template <class Env>
+    Env *environment() const { return dynamic_cast<Env *>(mEnv); }
+
+    //@@@ add certificate access functions
+    //@@@ add callback management
+
+protected:
+    const AccessCredentials *mCred;		// original credentials
+    AclAuthorization mAuth;				// action requested
+    AclValidationEnvironment *mEnv;		// environmental context (if any)
+};
+
+
+//
+// An in-memory ACL object.
+// This class implements an ACL-for-a-protected-object. It is complete in that
+// it provides full ACL management functionality. You still need to (globally)
+// register makers for the ACL subject types you want to use.
+// Note that ObjectAcl does no integrity checking. ObjectAcl objects need to be
+// protected from hostile access (by e.g. address space separation), and exported
+// ACLs need to be protected somehow (by hiding, signing, or whatever works in
+// your situation).
+//
+class ObjectAcl {
+    friend AclSubject::Maker::Maker(CSSM_ACL_SUBJECT_TYPE);
+    
+public:
+    typedef RefPointer<AclSubject> AclSubjectPointer;
+    
+    typedef LowLevelMemoryUtilities::Writer Writer;
+    typedef LowLevelMemoryUtilities::Reader Reader;
+    
+public:
+    ObjectAcl(CssmAllocator &alloc);
+    ObjectAcl(const AclEntryPrototype &proto, CssmAllocator &alloc);
+	virtual ~ObjectAcl();
+    
+    CssmAllocator &allocator;
+
+    // access control validation: succeed or throw exception
+    void validate(AclAuthorization auth, const AccessCredentials *cred,
+        AclValidationEnvironment *env = NULL) const;
+    void validateOwner(AclAuthorization authorizationHint, const AccessCredentials *cred,
+		AclValidationEnvironment *env = NULL) const;
+
+    // CSSM-style ACL access operations
+	// (Gets are not const because underlying implementations usually want them writable) 
+    void cssmGetAcl(const char *tag, uint32 &count, AclEntryInfo * &acls);
+    void cssmChangeAcl(const AclEdit &edit, const AccessCredentials *cred,
+		AclValidationEnvironment *env = NULL);
+    void cssmGetOwner(AclOwnerPrototype &owner);
+    void cssmChangeOwner(const AclOwnerPrototype &newOwner, const AccessCredentials *cred,
+		AclValidationEnvironment *env = NULL);
+    
+    void cssmSetInitial(const AclEntryPrototype &proto);
+    void cssmSetInitial(const AclSubjectPointer &subject);
+        
+    // Acl I/O (to/from memory blobs)
+    void exportBlob(CssmData &publicBlob, CssmData &privateBlob);
+    void importBlob(const void *publicBlob, const void *privateBlob);
+	
+	// debugging support
+	IFDUMP(virtual void debugDump(const char *what = NULL) const);
+
+public:
+    class Entry {
+    public:
+        AclSubjectPointer subject;		// subject representation
+        bool delegate;					// delegation flag
+        
+        Entry() { }						// make invalid Entry
+        
+        void toOwnerInfo(CSSM_ACL_OWNER_PROTOTYPE &info,
+                        CssmAllocator &alloc) const; // encode copy in CSSM format
+
+        virtual bool authorizes(AclAuthorization auth) const = 0;
+        virtual bool validate(const AclValidationContext &ctx) const = 0;
+
+        template <class Action>
+        void exportBlob(Action &pub, Action &priv)
+        {
+            pub(delegate);
+			CSSM_ACL_SUBJECT_TYPE type = subject->type(); pub(type);
+            subject->exportBlob(pub, priv);
+        }
+        void importBlob(Reader &pub, Reader &priv);
+		
+		IFDUMP(virtual void debugDump() const);
+        
+    private:
+        void init(const AclSubjectPointer &subject, bool delegate = false);
+        void init(const TypedList &subject, bool delegate = false) { init(make(subject), delegate); }
+
+    protected:
+        Entry(const AclEntryPrototype &proto) { init(proto.subject(), proto.delegate()); }
+        Entry(const AclOwnerPrototype &proto) { init(proto.subject()); }
+        Entry(const AclSubjectPointer &subject) { init(subject); }
+        virtual ~Entry();
+    };
+    
+    class OwnerEntry : public Entry {
+    public:
+        OwnerEntry() { }	// invalid OwnerEntry
+        template <class Input>
+        OwnerEntry(const Input &owner) : Entry(owner) { }
+        OwnerEntry(const AclSubjectPointer &subject) : Entry(subject) { }
+
+        bool authorizes(AclAuthorization auth) const;
+        bool validate(const AclValidationContext &ctx) const;
+    };
+    
+    class AclEntry : public Entry {
+    public:
+        string tag;						// entry tag
+        AclAuthorizationSet authorizations;	 // set of authorizations
+        bool authorizesAnything;		// has the _ANY authorization tag
+        //@@@ time range not yet implemented
+        uint32 handle;					// entry handle
+        
+		AclEntry() { }					// invalid AclEntry
+        AclEntry(const AclSubjectPointer &subject);
+        AclEntry(const AclEntryPrototype &proto);
+        
+        void toEntryInfo(CSSM_ACL_ENTRY_PROTOTYPE &info,
+                        CssmAllocator &alloc) const; // encode copy in CSSM format
+        
+        bool authorizes(AclAuthorization auth) const;
+        bool validate(const AclValidationContext &ctx) const;
+        
+        template <class Action>
+        void exportBlob(Action &pub, Action &priv)
+        {
+            Entry::exportBlob(pub, priv);
+            const char *s = tag.c_str(); pub(s);
+            pub(authorizesAnything);
+            if (!authorizesAnything) {
+                uint32 count = authorizations.size(); pub(count);
+                for (AclAuthorizationSet::iterator it = authorizations.begin();
+                    it != authorizations.end(); it++) {
+                    AclAuthorization auth = *it; pub(auth);
+                }
+            }
+            //@@@ export time range
+        }
+        void importBlob(Reader &pub, Reader &priv);
+		
+		IFDUMP(void debugDump() const);
+    };
+
+    typedef multimap<string, AclEntry> EntryMap;
+    typedef EntryMap::iterator Iterator;
+    typedef EntryMap::const_iterator ConstIterator;
+    
+    Iterator begin() { return entries.begin(); }
+    Iterator end() { return entries.end(); }
+    ConstIterator begin() const { return entries.begin(); }
+    ConstIterator end() const { return entries.end(); }
+    
+    unsigned int getRange(const char *tag, pair<ConstIterator, ConstIterator> &range) const;	
+    Iterator findEntryHandle(CSSM_ACL_HANDLE handle);
+    
+    // construct an AclSubject through the Maker registry (by subject type)
+    static AclSubject *make(const TypedList &list);	// make from CSSM form
+    static AclSubject *make(CSSM_ACL_SUBJECT_TYPE type,
+                            Reader &pub, Reader &priv); // make from export form
+    
+private:
+    EntryMap entries;				// ACL entries indexed by tag
+    OwnerEntry owner;				// ACL owner entry
+    uint32 nextHandle;				// next unused entry handle value
+
+private:
+    typedef map<CSSM_ACL_SUBJECT_TYPE, AclSubject::Maker *> MakerMap;
+    static ModuleNexus<MakerMap> makers;	// registered subject Makers
+    
+    static AclSubject::Maker &makerFor(CSSM_ACL_SUBJECT_TYPE type);
+};
+
+
+//
+// This bastard child of two different data structure sets has no natural home.
+// We'll take pity on it here.
+//
+class ResourceControlContext : public PodWrapper<ResourceControlContext, CSSM_RESOURCE_CONTROL_CONTEXT> {
+public:
+    ResourceControlContext() { }
+    ResourceControlContext(const AclEntryInput &initial, AccessCredentials *cred = NULL)
+    { InitialAclEntry = initial; AccessCred = cred; }
+    
+    operator AclEntryInput &() { return AclEntryInput::overlay(InitialAclEntry); }
+    AccessCredentials *credentials() { return AccessCredentials::overlay(AccessCred); }
+};
+
+} // end namespace Security
+
+#ifdef _CPP_CSSMACL
+#pragma export off
+#endif
+
+
+#endif //_CSSMACL
diff --git a/cdsa/cdsa_utilities/cssmaclpod.cpp b/cdsa/cdsa_utilities/cssmaclpod.cpp
new file mode 100644
index 00000000..b97b5da1
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmaclpod.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmaclpod - enhanced PodWrappers for ACL-related CSSM data structures
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMACLPOD
+#endif
+
+#include <Security/cssmaclpod.h>
+#include <Security/cssmwalkers.h>
+
+
+AuthorizationGroup::AuthorizationGroup(const AclAuthorizationSet &auths, CssmAllocator &alloc)
+{
+	NumberOfAuthTags = auths.size();
+	AuthTags = alloc.alloc<CSSM_ACL_AUTHORIZATION_TAG>(NumberOfAuthTags);
+	copy(auths.begin(), auths.end(), AuthTags);	// happens to be sorted
+}
+
+bool AuthorizationGroup::contains(CSSM_ACL_AUTHORIZATION_TAG tag) const
+{
+	return find(AuthTags, &AuthTags[NumberOfAuthTags], tag) != &AuthTags[NumberOfAuthTags];
+}
+
+
+AuthorizationGroup::operator AclAuthorizationSet() const
+{
+	return AclAuthorizationSet(AuthTags, &AuthTags[NumberOfAuthTags]);
+}
+
+AclEntryPrototype::AclEntryPrototype(const AclOwnerPrototype &proto)
+{
+	memset(this, 0, sizeof(*this));
+	TypedSubject = proto.subject(); Delegate = proto.delegate();
+	//@@@ set authorization to "is owner" pseudo-auth? See cssmacl.h
+}		
+
+
+AutoAclOwnerPrototype::~AutoAclOwnerPrototype()
+{
+	if (mAllocator)
+		DataWalkers::chunkFree(mAclOwnerPrototype, *mAllocator);
+}
+
+void
+AutoAclOwnerPrototype::allocator(CssmAllocator &allocator)
+{
+	mAllocator = &allocator;
+}
+
+
+AutoAclEntryInfoList::~AutoAclEntryInfoList()
+{
+	if (mAllocator)
+	{
+		DataWalkers::ChunkFreeWalker w(*mAllocator);
+		for (uint32 ix = 0; ix < mNumberOfAclEntries; ix++)
+			walk(w, mAclEntryInfo[ix]);
+		//DataWalkers::chunkFree(mAclEntryInfo[ix], *mAllocator);	
+		mAllocator->free(mAclEntryInfo);
+	}
+}
+
+void
+AutoAclEntryInfoList::allocator(CssmAllocator &allocator)
+{
+	mAllocator = &allocator;
+}
diff --git a/cdsa/cdsa_utilities/cssmaclpod.h b/cdsa/cdsa_utilities/cssmaclpod.h
new file mode 100644
index 00000000..1e9a1906
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmaclpod.h
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmaclpod - enhanced PodWrappers for ACL-related CSSM data structures
+//
+#ifndef _CSSMACLPOD
+#define _CSSMACLPOD
+
+#include <Security/utilities.h>
+#include <Security/cssmlist.h>
+#include <Security/cssmalloc.h>
+
+#ifdef _CPP_CSSMACLPOD
+#pragma export on
+#endif
+
+namespace Security
+{
+
+// a nicer name for an authorization tag
+typedef CSSM_ACL_AUTHORIZATION_TAG AclAuthorization;
+typedef set<AclAuthorization> AclAuthorizationSet;
+
+
+//
+// Enhanced POD Wrappers for the public ACL-related CSSM structures
+//
+class AuthorizationGroup : public PodWrapper<AuthorizationGroup, CSSM_AUTHORIZATIONGROUP> {
+public:
+	AuthorizationGroup() { NumberOfAuthTags = 0; }
+	AuthorizationGroup(AclAuthorization auth);
+	explicit AuthorizationGroup(const AclAuthorizationSet &, CssmAllocator &alloc);
+	
+    bool empty() const			{ return NumberOfAuthTags == 0; }
+	unsigned int count() const	{ return NumberOfAuthTags; }
+	CSSM_ACL_AUTHORIZATION_TAG operator [] (unsigned ix) const
+	{ assert(ix < count()); return AuthTags[ix]; }
+	
+	bool contains(CSSM_ACL_AUTHORIZATION_TAG tag) const;
+	operator AclAuthorizationSet () const;
+};
+
+class AclOwnerPrototype;
+
+class AclEntryPrototype : public PodWrapper<AclEntryPrototype, CSSM_ACL_ENTRY_PROTOTYPE> {
+public:
+	AclEntryPrototype() { memset(this, 0, sizeof(*this)); }
+	AclEntryPrototype(const AclOwnerPrototype &proto);
+	AclEntryPrototype(const CSSM_LIST &subj, bool delegate = false)
+	{ memset(this, 0, sizeof(*this)); TypedSubject = subj; Delegate = delegate; }
+	
+	TypedList &subject() { return TypedList::overlay(TypedSubject); }
+	const TypedList &subject() const { return TypedList::overlay(TypedSubject); }
+	bool delegate() const { return Delegate; }
+	char *tag() { return EntryTag; }
+	const char *tag() const { return EntryTag; }
+	AuthorizationGroup &authorization() { return AuthorizationGroup::overlay(Authorization); }
+	const AuthorizationGroup &authorization() const
+	{ return AuthorizationGroup::overlay(Authorization); }
+};
+
+class AclOwnerPrototype : public PodWrapper<AclOwnerPrototype, CSSM_ACL_OWNER_PROTOTYPE> {
+public:
+	AclOwnerPrototype() { }
+	explicit AclOwnerPrototype(const AclEntryPrototype &proto)
+	{ TypedSubject = proto.subject(); Delegate = proto.delegate(); }
+	
+	TypedList &subject() { return TypedList::overlay(TypedSubject); }
+	const TypedList &subject() const { return TypedList::overlay(TypedSubject); }
+	bool delegate() const { return Delegate; }
+};
+
+class AclEntryInfo : public PodWrapper<AclEntryInfo, CSSM_ACL_ENTRY_INFO> {
+public:
+	AclEntryPrototype &proto() { return AclEntryPrototype::overlay(EntryPublicInfo); }
+	const AclEntryPrototype &proto()
+	const { return AclEntryPrototype::overlay(EntryPublicInfo); }
+	
+	operator AclEntryPrototype &() { return proto(); }
+	operator const AclEntryPrototype &() const { return proto(); }
+
+	CSSM_ACL_HANDLE &handle() { return EntryHandle; }
+	const CSSM_ACL_HANDLE &handle() const { return EntryHandle; }
+};
+
+class AclEntryInput : public PodWrapper<AclEntryInput, CSSM_ACL_ENTRY_INPUT> {
+public:
+	AclEntryInput() { memset(this, 0, sizeof(*this)); }
+	AclEntryInput(const AclEntryPrototype &prot)
+	{ Prototype = prot; Callback = NULL; CallerContext = NULL; }
+
+	AclEntryPrototype &proto() { return AclEntryPrototype::overlay(Prototype); }
+	const AclEntryPrototype &proto() const { return AclEntryPrototype::overlay(Prototype); }
+	//@@@ not supporting callback features (yet)
+};
+
+class AclEdit : public PodWrapper<AclEdit, CSSM_ACL_EDIT> {
+public:
+	AclEdit(CSSM_ACL_EDIT_MODE m, CSSM_ACL_HANDLE h, const AclEntryInput *data)
+	{ EditMode = m; OldEntryHandle = h; NewEntry = data; }
+	AclEdit(const AclEntryInput &add)
+	{ EditMode = CSSM_ACL_EDIT_MODE_ADD; OldEntryHandle = CSSM_INVALID_HANDLE; NewEntry = &add; }
+	AclEdit(CSSM_ACL_HANDLE h, const AclEntryInput &modify)
+	{ EditMode = CSSM_ACL_EDIT_MODE_REPLACE; OldEntryHandle = h; NewEntry = &modify; }
+	AclEdit(CSSM_ACL_HANDLE h)
+	{ EditMode = CSSM_ACL_EDIT_MODE_DELETE; OldEntryHandle = h; NewEntry = NULL; }
+	
+	CSSM_ACL_EDIT_MODE mode() const { return EditMode; }
+	CSSM_ACL_HANDLE handle() const { return OldEntryHandle; }
+	const AclEntryInput *newEntry() const { return AclEntryInput::overlay(NewEntry); }
+};
+
+
+//
+// Allocating versions of Acl structures
+//
+class AutoAclOwnerPrototype {
+	NOCOPY(AutoAclOwnerPrototype)
+public:
+	// allocator can be set after construction
+	AutoAclOwnerPrototype(CssmAllocator *allocator = NULL) : mAllocator(allocator) { }
+	~AutoAclOwnerPrototype();
+	
+	operator CSSM_ACL_OWNER_PROTOTYPE *() { return mAclOwnerPrototype; }
+
+	void allocator(CssmAllocator &allocator);
+
+private:
+	AclOwnerPrototype *mAclOwnerPrototype;
+	CssmAllocator *mAllocator;
+};
+
+
+class AutoAclEntryInfoList {
+	NOCOPY(AutoAclEntryInfoList)
+public:
+	// allocator can be set after construction
+	AutoAclEntryInfoList(CssmAllocator *allocator = NULL)
+    : mAclEntryInfo(NULL), mNumberOfAclEntries(0), mAllocator(allocator) { }
+	~AutoAclEntryInfoList();
+
+	operator CSSM_ACL_ENTRY_INFO_PTR *() { return &CSSM_ACL_ENTRY_INFO_PTR(mAclEntryInfo); }
+	operator uint32 *() { return &mNumberOfAclEntries; }
+
+	void allocator(CssmAllocator &allocator);
+
+	const AclEntryInfo &at(uint32 ix) const { return mAclEntryInfo[ix]; }
+	const AclEntryInfo &operator[](uint32 ix) const
+	{ assert(ix < mNumberOfAclEntries); return mAclEntryInfo[ix]; }
+
+	uint32 size() const { return mNumberOfAclEntries; }
+
+private:
+	AclEntryInfo *mAclEntryInfo;
+	uint32 mNumberOfAclEntries;
+	CssmAllocator *mAllocator;
+};
+
+
+//
+// Walkers for the CSSM API structure types
+//
+namespace DataWalkers {
+
+// AclEntryInput
+template <class Action>
+AclEntryInput *walk(Action &operate, AclEntryInput * &input)
+{
+	operate(input);
+	walk(operate, *input);
+	return input;
+}
+
+template <class Action>
+void walk(Action &operate, AclEntryInput &input)
+{ walk(operate, input.proto()); }
+
+// AclEntryInfo
+template <class Action>
+void walk(Action &operate, AclEntryInfo &info)
+{ walk(operate, info.proto()); }
+
+template <class Action>
+void walk(Action &operate, const AclEntryInfo &info)
+{ walk(operate, const_cast<AclEntryInfo &>(info)); }
+
+// AclEntryPrototype
+template <class Action>
+void walk(Action &operate, AclEntryPrototype &proto)
+{
+	walk(operate, proto.subject());
+	operate(proto.Authorization.AuthTags,
+		sizeof(CSSM_ACL_AUTHORIZATION_TAG) * proto.Authorization.NumberOfAuthTags);
+	//@@@ ignoring validity period
+}
+
+template <class Action>
+AclEntryPrototype *walk(Action &operate, AclEntryPrototype * &proto)
+{
+	operate(proto);
+	walk(operate, *proto);
+	return proto;
+}
+
+// AclOwnerPrototype
+template <class Action>
+void walk(Action &operate, AclOwnerPrototype &proto)
+{
+	walk(operate, proto.subject());
+}
+
+template <class Action>
+AclOwnerPrototype *walk(Action &operate, AclOwnerPrototype * &proto)
+{
+	operate(proto);
+	walk(operate, *proto);
+	return proto;
+}
+
+
+} // end namespace DataWalkers
+
+} // end namespace Security
+
+#ifdef _CPP_CSSMACLPOD
+#pragma export off
+#endif
+
+
+#endif //_CSSMACLPOD
diff --git a/cdsa/cdsa_utilities/cssmalloc.cpp b/cdsa/cdsa_utilities/cssmalloc.cpp
new file mode 100644
index 00000000..7994e803
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmalloc.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmalloc - memory allocation in the CDSA world.
+//
+// Don't eat heavily before inspecting this code.
+//
+#include <Security/cssmalloc.h>
+#include <Security/memutils.h>
+#include <Security/globalizer.h>
+#include <stdlib.h>
+#include <errno.h>
+
+using LowLevelMemoryUtilities::alignof;
+using LowLevelMemoryUtilities::increment;
+using LowLevelMemoryUtilities::alignUp;
+
+
+//
+// Features of the CssmAllocator root class
+//
+bool CssmAllocator::operator == (const CssmAllocator &alloc) const
+{
+	return this == &alloc;
+}
+
+CssmAllocator::~CssmAllocator()
+{
+}
+
+
+//
+// Standard CssmAllocator variants.
+// Note that all calls to CssmAllocator::standard(xxx) with the same xxx argument
+// must produce compatible allocators (i.e. they must be work on a common memory
+// pool). This is trivially achieved here by using singletons.
+//
+struct DefaultCssmAllocator : public CssmAllocator {
+	void *malloc(size_t size);
+	void free(void *addr);
+	void *realloc(void *addr, size_t size);
+};
+
+static ModuleNexus<DefaultCssmAllocator> defaultAllocator;
+
+
+CssmAllocator &CssmAllocator::standard(uint32)
+{
+	return defaultAllocator();
+}
+
+void *DefaultCssmAllocator::malloc(size_t size)
+{
+	if (void *result = ::malloc(size))
+		return result;
+	throw std::bad_alloc();
+}
+
+void DefaultCssmAllocator::free(void *addr)
+{
+	::free(addr);
+}
+
+void *DefaultCssmAllocator::realloc(void *addr, size_t newSize)
+{
+	if (void *result = ::realloc(addr, newSize))
+		return result;
+	throw std::bad_alloc();
+}
+
+TrackingAllocator::~TrackingAllocator()
+{
+	AllocSet::iterator first = mAllocSet.begin(), last = mAllocSet.end();
+	for (; first != last; ++first)
+		mAllocator.free(*first);
+}
+
+//
+// CssmMemoryFunctionsAllocators
+//
+void *CssmMemoryFunctionsAllocator::malloc(size_t size)
+{ return functions.malloc(size); }
+
+void CssmMemoryFunctionsAllocator::free(void *addr)
+{ return functions.free(addr); }
+
+void *CssmMemoryFunctionsAllocator::realloc(void *addr, size_t size)
+{ return functions.realloc(addr, size); }
+
+
+//
+// CssmAllocatorMemoryFunctions
+//
+CssmAllocatorMemoryFunctions::CssmAllocatorMemoryFunctions(CssmAllocator &alloc)
+{
+	AllocRef = &alloc;
+	malloc_func = relayMalloc;
+	free_func = relayFree;
+	realloc_func = relayRealloc;
+	calloc_func = relayCalloc;
+}
+
+void *CssmAllocatorMemoryFunctions::relayMalloc(size_t size, void *ref)
+{ return allocator(ref).malloc(size); }
+
+void CssmAllocatorMemoryFunctions::relayFree(void *mem, void *ref)
+{ allocator(ref).free(mem); }
+
+void *CssmAllocatorMemoryFunctions::relayRealloc(void *mem, size_t size, void *ref)
+{ return allocator(ref).realloc(mem, size); }
+
+void *CssmAllocatorMemoryFunctions::relayCalloc(uint32 count, size_t size, void *ref)
+{
+	// CssmAllocator doesn't have a calloc() method
+	void *mem = allocator(ref).malloc(size * count);
+	memset(mem, 0, size * count);
+	return mem;
+}
+
+
+//
+// Memory allocators for CssmHeap objects.
+// This implementation stores a pointer to the allocator used into memory
+// *after* the object's proper storage block. This allows the usual free()
+// functions to safely free our (hidden) pointer without knowing about it.
+// An allocator argument of NULL is interpreted as the standard allocator.
+//
+void *CssmHeap::operator new (size_t size, CssmAllocator *alloc)
+{
+	if (alloc == NULL)
+		alloc = &CssmAllocator::standard();
+	size = alignUp(size, alignof<CssmAllocator *>());
+	size_t totalSize = size + sizeof(CssmAllocator *);
+	void *addr = alloc->malloc(totalSize);
+	*(CssmAllocator **)increment(addr, size) = alloc;
+	return addr;
+}
+
+void CssmHeap::operator delete (void *addr, size_t size, CssmAllocator *alloc)
+{
+	alloc->free(addr);	// as per C++ std, called (only) if construction fails
+}
+
+void CssmHeap::operator delete (void *addr, size_t size)
+{
+	void *end = increment(addr, alignUp(size, alignof<CssmAllocator *>()));
+	(*(CssmAllocator **)end)->free(addr);
+}
diff --git a/cdsa/cdsa_utilities/cssmalloc.h b/cdsa/cdsa_utilities/cssmalloc.h
new file mode 100644
index 00000000..f09fa171
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmalloc.h
@@ -0,0 +1,368 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmalloc - memory allocation in the CDSA world
+//
+#ifndef _H_CSSMALLOC
+#define _H_CSSMALLOC
+
+#include <Security/utilities.h>
+#include <Security/cssm.h>
+#include <cstring>
+#include <set>
+
+#ifdef _CPP_CSSMALLOC
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// An abstract allocator superclass, based on the simple malloc/realloc/free paradigm
+// that CDSA loves so much. If you have an allocation strategy and want objects
+// to be allocated through it, inherit from this.
+//
+class CssmAllocator {
+public:
+	virtual ~CssmAllocator();
+	virtual void *malloc(size_t) = 0;
+	virtual void free(void *) = 0;
+	virtual void *realloc(void *, size_t) = 0;
+
+	//
+	// Template versions for added expressiveness.
+	// Note that the integers are element counts, not byte sizes.
+	//
+	template <class T> T *alloc()
+	{ return reinterpret_cast<T *>(malloc(sizeof(T))); }
+
+	template <class T> T *alloc(uint32 count)
+	{ return reinterpret_cast<T *>(malloc(sizeof(T) * count)); }
+
+	template <class T> T *alloc(T *old, uint32 count)
+	{ return reinterpret_cast<T *>(realloc(old, sizeof(T) * count)); }
+	
+	template <class Data> CssmData alloc(const Data &source)
+	{
+		size_t length = source.length();
+		return CssmData(memcpy(malloc(length), source.data(), length), length);
+	}
+	
+	//
+	// Happier malloc/realloc for any type. Note that these still have
+	// the original (byte-sized) argument profile.
+	//
+	template <class T> T *malloc(size_t size)
+	{ return reinterpret_cast<T *>(malloc(size)); }
+	
+	template <class T> T *realloc(void *addr, size_t size)
+	{ return reinterpret_cast<T *>(realloc(addr, size)); }
+	
+	// All right, if you *really* have to have calloc...
+	void *calloc(size_t size, unsigned int count)
+	{
+		void *addr = malloc(size * count);
+		memset(addr, 0, size * count);
+		return addr;
+	}
+	
+	// compare CssmAllocators for identity
+	virtual bool operator == (const CssmAllocator &alloc) const;
+
+public:
+	// allocator chooser options
+	enum {
+		normal = 0x0000,
+		sensitive = 0x0001
+	};
+
+	static CssmAllocator &standard(uint32 request = normal);
+};
+
+
+//
+// A POD wrapper for the memory functions structure passed around in CSSM.
+//
+class CssmMemoryFunctions : public PodWrapper<CssmMemoryFunctions, CSSM_MEMORY_FUNCS> {
+public:
+	CssmMemoryFunctions(const CSSM_MEMORY_FUNCS &funcs)
+	{ *(CSSM_MEMORY_FUNCS *)this = funcs; }
+	CssmMemoryFunctions() { }
+
+	void *malloc(size_t size) const;
+	void free(void *mem) const { free_func(mem, AllocRef); }
+	void *realloc(void *mem, size_t size) const;
+	void *calloc(uint32 count, size_t size) const;
+	
+	bool operator == (const CSSM_MEMORY_FUNCS &other) const
+	{ return !memcmp(this, &other, sizeof(*this)); }
+};
+
+inline void *CssmMemoryFunctions::malloc(size_t size) const
+{
+	if (void *addr = malloc_func(size, AllocRef))
+		return addr;
+	throw std::bad_alloc();
+}
+
+inline void *CssmMemoryFunctions::calloc(uint32 count, size_t size) const
+{
+	if (void *addr = calloc_func(count, size, AllocRef))
+		return addr;
+	throw std::bad_alloc();
+}
+
+inline void *CssmMemoryFunctions::realloc(void *mem, size_t size) const
+{
+	if (void *addr = realloc_func(mem, size, AllocRef))
+		return addr;
+	throw std::bad_alloc();
+}
+
+
+//
+// A CssmAllocator based on CssmMemoryFunctions
+//
+class CssmMemoryFunctionsAllocator : public CssmAllocator {
+public:
+	CssmMemoryFunctionsAllocator(const CssmMemoryFunctions &memFuncs) : functions(memFuncs) { }
+	
+	void *malloc(size_t size);
+	void free(void *addr);
+	void *realloc(void *addr, size_t size);
+	
+	operator const CssmMemoryFunctions & () const { return functions; }
+	
+private:
+	const CssmMemoryFunctions functions;
+};
+
+} // end namespace Security
+
+//
+// Global C++ allocation hooks to use CssmAllocators
+//
+inline void *operator new (size_t size, CssmAllocator &allocator)
+{ return allocator.malloc(size); }
+
+//
+// You'd think that this is operator delete(const T *, CssmAllocator &), but you'd
+// be wrong. Specialized operator delete is only called during constructor cleanup.
+// Use this to cleanly destroy things.
+//
+template <class T>
+inline void destroy(T *obj, CssmAllocator &alloc)
+{
+	obj->~T();
+	alloc.free(obj);
+}
+
+// untyped (release memory only, no destructor call)
+inline void destroy(void *obj, CssmAllocator &alloc)
+{
+	alloc.free(obj);
+}
+
+namespace Security
+{
+
+//
+// A MemoryFunctions object based on a CssmAllocator.
+// Note that we don't copy the CssmAllocator object. It needs to live (at least)
+// as long as any CssmAllocatorMemoryFunctions object based on it.
+//
+class CssmAllocatorMemoryFunctions : public CssmMemoryFunctions {
+public:
+	CssmAllocatorMemoryFunctions(CssmAllocator &alloc);
+	CssmAllocatorMemoryFunctions() { /*IFDEBUG(*/ AllocRef = NULL /*)*/ ; }	// later assignment req'd
+	
+private:
+	static void *relayMalloc(size_t size, void *ref);
+	static void relayFree(void *mem, void *ref);
+	static void *relayRealloc(void *mem, size_t size, void *ref);
+	static void *relayCalloc(uint32 count, size_t size, void *ref);
+	
+	static CssmAllocator &allocator(void *ref)
+	{ return *reinterpret_cast<CssmAllocator *>(ref); }
+};
+
+
+//
+// A mixin class to automatically manage your allocator.
+// To allow allocation (of your object) from any instance of CssmAllocator,
+// inherit from CssmHeap. Your users can then create heap instances of your thing by
+//		new (an-allocator) YourClass(...)
+// or (still)
+//		new YourClass(...)
+// for the default allocation source. The beauty is that when someone does a
+//		delete pointer-to-your-instance
+// then the magic fairies will find the allocator that created the object and ask it
+// to free the memory (by calling its free() method).
+// The price of all that glory is memory overhead - typically one pointer per object.
+//
+class CssmHeap {
+public:    
+	void *operator new (size_t size, CssmAllocator *alloc = NULL);
+	void operator delete (void *addr, size_t size);
+	void operator delete (void *addr, size_t size, CssmAllocator *alloc);
+};
+
+
+//
+// Here is a version of auto_ptr that works with CssmAllocators. It is designed
+// to be pretty much a drop-in replacement. It requires an allocator as a constructor
+// argument, of course.
+// Note that CssmAutoPtr<void> is perfectly valid, unlike its auto_ptr look-alike.
+// You can't dereference it, naturally.
+//
+template <class T>
+class CssmAutoPtr {
+public:
+	CssmAllocator &allocator;
+
+	CssmAutoPtr(CssmAllocator &alloc = CssmAllocator::standard())
+	: allocator(alloc), mine(NULL) { }
+	CssmAutoPtr(CssmAllocator &alloc, T *p)
+	: allocator(alloc), mine(p) { }
+	CssmAutoPtr(T *p)
+	: allocator(CssmAllocator::standard()), mine(p) { }
+	template <class T1> CssmAutoPtr(CssmAutoPtr<T1> &src)
+	: allocator(src.allocator), mine(src.release()) { }
+	template <class T1> CssmAutoPtr(CssmAllocator &alloc, CssmAutoPtr<T1> &src)
+	: allocator(alloc), mine(rc.release()) { assert(allocator == src.allocator); }
+	
+	~CssmAutoPtr()				{ destroy(mine); }
+	
+	T *get() const throw()		{ return mine; }
+	T *release()				{ T *result = mine; mine = NULL; return result; }
+	void reset()				{ allocator.free(mine); mine = NULL; }
+	
+	operator T * () const		{ return mine; }
+	T *operator -> () const		{ return mine; }
+	T &operator * () const		{ assert(mine); return *mine; }
+
+private:
+	T *mine;
+};
+
+// specialization for void (i.e. void *), omitting the troublesome dereferencing ops.
+template <>
+class CssmAutoPtr<void> {
+public:
+	CssmAllocator &allocator;
+
+	CssmAutoPtr(CssmAllocator &alloc) : allocator(alloc), mine(NULL) { }
+	CssmAutoPtr(CssmAllocator &alloc, void *p) : allocator(alloc), mine(p) { }
+	template <class T1> CssmAutoPtr(CssmAutoPtr<T1> &src)
+	: allocator(src.allocator), mine(src.release()) { }
+	template <class T1> CssmAutoPtr(CssmAllocator &alloc, CssmAutoPtr<T1> &src)
+	: allocator(alloc), mine(rc.release()) { assert(allocator == src.allocator); }
+	
+	~CssmAutoPtr()				{ destroy(mine, allocator); }
+	
+	void *get() throw()		{ return mine; }
+	void *release()				{ void *result = mine; mine = NULL; return result; }
+	void reset()				{ allocator.free(mine); mine = NULL; }
+
+private:
+	void *mine;
+};
+
+
+//
+// Convenience forms of CssmAutoPtr that automatically make their (initial) object.
+//
+template <class T>
+class CssmNewAutoPtr : public CssmAutoPtr<T> {
+public:
+	CssmNewAutoPtr(CssmAllocator &alloc = CssmAllocator::standard())
+	: CssmAutoPtr<T>(alloc, new(alloc) T) { }
+	
+	template <class A1>
+	CssmNewAutoPtr(CssmAllocator &alloc, A1 &arg1) : CssmAutoPtr<T>(alloc, new(alloc) T(arg1)) { }
+	template <class A1>
+	CssmNewAutoPtr(CssmAllocator &alloc, const A1 &arg1)
+	: CssmAutoPtr<T>(alloc, new(alloc) T(arg1)) { }
+	
+	template <class A1, class A2>
+	CssmNewAutoPtr(CssmAllocator &alloc, A1 &arg1, A2 &arg2)
+	: CssmAutoPtr<T>(alloc, new(alloc) T(arg1, arg2)) { }
+	template <class A1, class A2>
+	CssmNewAutoPtr(CssmAllocator &alloc, const A1 &arg1, A2 &arg2)
+	: CssmAutoPtr<T>(alloc, new(alloc) T(arg1, arg2)) { }
+	template <class A1, class A2>
+	CssmNewAutoPtr(CssmAllocator &alloc, A1 &arg1, const A2 &arg2)
+	: CssmAutoPtr<T>(alloc, new(alloc) T(arg1, arg2)) { }
+	template <class A1, class A2>
+	CssmNewAutoPtr(CssmAllocator &alloc, const A1 &arg1, const A2 &arg2)
+	: CssmAutoPtr<T>(alloc, new(alloc) T(arg1, arg2)) { }
+};
+
+
+//
+// A CssmAllocator that keeps track of allocations and can throw everything
+// away unless explicitly committed.
+//
+class TrackingAllocator : public CssmAllocator
+{
+public:
+	TrackingAllocator(CssmAllocator &inAllocator) : mAllocator(inAllocator) {}
+	virtual ~TrackingAllocator();
+
+	void *malloc(size_t inSize)
+	{
+		void *anAddress = mAllocator.malloc(inSize);
+		mAllocSet.insert(anAddress);
+		return anAddress;
+	}
+
+	void free(void *inAddress)
+	{
+		mAllocator.free(inAddress);
+		mAllocSet.erase(inAddress);
+	}
+
+	void *realloc(void *inAddress, size_t inNewSize)
+	{
+		void *anAddress = mAllocator.realloc(inAddress, inNewSize);
+		if (anAddress != inAddress)
+		{
+			mAllocSet.erase(inAddress);
+			mAllocSet.insert(anAddress);
+		}
+
+		return anAddress;
+	}
+
+	void commit() { mAllocSet.clear(); }
+private:
+	typedef std::set<void *> AllocSet;
+
+	CssmAllocator &mAllocator;
+	AllocSet mAllocSet;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_CSSMALLOC
+# pragma export off
+#endif
+
+#endif //_H_CSSMALLOC
diff --git a/cdsa/cdsa_utilities/cssmcred.cpp b/cdsa/cdsa_utilities/cssmcred.cpp
new file mode 100644
index 00000000..d65d5371
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmcred.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmcred - enhanced PodWrappers and construction aids for ACL credentials
+//
+#include <Security/cssmcred.h>
+
+
+namespace Security {
+
+
+//
+// The null credential constant.
+//
+static const CSSM_ACCESS_CREDENTIALS null_credentials = { "" };	// and more nulls
+#if BUG_GCC
+const AccessCredentials &AccessCredentials::null =
+    *static_cast<const AccessCredentials *>(&null_credentials);
+#else
+const AccessCredentials &AccessCredentials::null =
+    static_cast<const AccessCredentials &>(null_credentials);
+#endif
+
+
+//
+// AutoCredentials self-constructing credentials structure
+//
+AutoCredentials::AutoCredentials(CssmAllocator &alloc) : allocator(alloc)
+{
+	init();
+}
+
+AutoCredentials::AutoCredentials(CssmAllocator &alloc, uint32 nSamples) : allocator(alloc)
+{
+	init();
+}
+
+void AutoCredentials::init()
+{
+	sampleArray = NULL;
+	nSamples = 0;
+}
+
+
+CssmSample &AutoCredentials::getSample(uint32 n)
+{
+	if (n >= nSamples) {
+		sampleArray = allocator.alloc<CssmSample>(sampleArray, nSamples = n + 1);
+		Samples.Samples = sampleArray;
+		Samples.NumberOfSamples = nSamples;
+	}
+	return sampleArray[n];
+}
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/cssmcred.h b/cdsa/cdsa_utilities/cssmcred.h
new file mode 100644
index 00000000..7c8e53fd
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmcred.h
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmcred - enhanced PodWrappers and construction aids for ACL credentials
+//
+#ifndef _CSSMCRED
+#define _CSSMCRED
+
+#include <Security/utilities.h>
+#include <Security/cssmlist.h>
+#include <Security/cssmalloc.h>
+
+#ifdef _CPP_CSSMCRED
+#pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// PodWrappers for samples and sample groups
+//
+class CssmSample : public PodWrapper<CssmSample, CSSM_SAMPLE> {
+public:
+	CssmSample(const TypedList &list)
+	{ TypedSample = list; Verifier = NULL; }
+	CssmSample(TypedList &list, const CssmSubserviceUid &ver)
+	{ TypedSample = list; Verifier = &ver; }
+
+	TypedList &value() { return TypedList::overlay(TypedSample); }
+	const TypedList &value() const { return TypedList::overlay(TypedSample); }
+	operator TypedList & () { return value(); }
+	operator const TypedList & () const { return value(); }
+	
+	const CssmSubserviceUid *verifier() const { return CssmSubserviceUid::overlay(Verifier); }
+	const CssmSubserviceUid * &verifier() { return CssmSubserviceUid::overlayVar(Verifier); }
+};
+
+class SampleGroup : public PodWrapper<SampleGroup, CSSM_SAMPLEGROUP> {
+public:
+	uint32 length() const { return NumberOfSamples; }
+
+	const CssmSample &operator [] (uint32 n) const
+	{ assert(n < length()); return CssmSample::overlay(Samples[n]); }
+};
+
+
+//
+// The PodWrapper for the top-level CSSM credentials structure
+//
+class AccessCredentials : public PodWrapper<AccessCredentials, CSSM_ACCESS_CREDENTIALS> {
+public:
+	AccessCredentials() { memset(this, 0, sizeof(*this)); }
+	
+	const char *tag() const { return EntryTag; }
+
+	SampleGroup &samples() { return SampleGroup::overlay(Samples); }
+	const SampleGroup &samples() const { return SampleGroup::overlay(Samples); }
+    
+public:
+    static const AccessCredentials &null;	// all null credential
+};
+
+
+//
+// An AccessCredentials object with some construction help.
+// Note that this is NOT a PodWrapper.
+//
+class AutoCredentials : public AccessCredentials {
+public:
+	AutoCredentials(CssmAllocator &alloc);
+	AutoCredentials(CssmAllocator &alloc, uint32 nSamples);
+	
+	CssmAllocator &allocator;
+	
+	CssmSample &sample(uint32 n) { return getSample(n); }
+	
+	CssmSample &operator += (const CssmSample &sample)
+	{ return getSample(samples().length()) = sample; }
+	TypedList &operator += (const TypedList &exhibit)
+	{ return (getSample(samples().length()) = exhibit).value(); }
+	
+private:
+	void init();
+	CssmSample &getSample(uint32 n);
+	
+	CssmSample *sampleArray;
+	uint32 nSamples;
+};
+
+
+//
+// Walkers for the CSSM API structure types.
+// Note that there are irrational "const"s strewn about the credential sub-structures.
+// They make it essentially impossible to incrementally construction them without
+// violating them. Since we know what we're doing, we do.
+//
+namespace DataWalkers
+{
+
+// CssmSample (with const override)
+template <class Action>
+void walk(Action &operate, CssmSample &sample)
+{
+	walk(operate, sample.value());
+	if (sample.verifier())
+		walk(operate, sample.verifier());
+}
+
+template <class Action>
+void walk(Action &operate, const CssmSample &sample)
+{ walk(operate, const_cast<CssmSample &>(sample)); }
+
+// SampleGroup
+template <class Action>
+void walk(Action &operate, SampleGroup &samples)
+{
+	operate(samples.Samples, samples.length() * sizeof(CssmSample));
+	for (uint32 n = 0; n < samples.length(); n++)
+		walk(operate, samples[n]);
+}
+
+// AccessCredentials
+template <class Action>
+AccessCredentials *walk(Action &operate, AccessCredentials * &cred)
+{
+	operate(cred);
+	//@@@ ignoring BaseCerts
+	walk(operate, cred->samples());
+	//@@@ ignoring challenge callback
+	return cred;
+}
+
+template <class Action>
+CSSM_ACCESS_CREDENTIALS *walk(Action &operate, CSSM_ACCESS_CREDENTIALS * &cred)
+{ return walk(operate, AccessCredentials::overlayVar(cred)); }
+
+
+} // end namespace DataWalkers
+
+} // end namespace Security
+
+#ifdef _CPP_CSSMCRED
+#pragma export off
+#endif
+
+
+#endif //_CSSMCRED
diff --git a/cdsa/cdsa_utilities/cssmdata.cpp b/cdsa/cdsa_utilities/cssmdata.cpp
new file mode 100644
index 00000000..3cd9548a
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmdata.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmdata.cpp -- Manager different CssmData types
+//
+#ifdef __MWERKS__
+#define _CPP_CDSA_UTILITIES_CSSMDATA
+#endif
+#include <Security/cssmdata.h>
+
+#include <Security/utilities.h>
+
+
+//
+// Managed data objects
+//
+CssmManagedData::~CssmManagedData()
+{ }
+
+
+//
+// CssmOwnedData
+//
+void CssmOwnedData::set(CssmManagedData &source)
+{
+    if (source.length() == 0) {					// source is empty
+        reset();								// so just clear old data
+    } else if (allocator == source.allocator) {	// compatible allocators
+        if (referent.data() == source.data()) {	// same data *and* we own it?!
+            assert(this == &source);			//  this better *be* me!
+        } else {								// different data
+            reset();							// give up our old data
+            referent = source.release();		// take over source's data
+        }
+    } else {									// different allocators
+        copy(source);							// make a copy with our allocator
+        source.reset();							// release source's data
+    }
+}
+
+
+//
+// CssmAutoData
+//
+CssmData CssmAutoData::release()
+{
+    CssmData result = mData;
+    mData.clear();
+    return result;
+}
+
+void CssmAutoData::reset()
+{
+    allocator.free(mData);
+    mData.clear();
+}
+
+
+//
+// CssmRemoteData
+//
+CssmData CssmRemoteData::release()
+{
+    iOwnTheData = false;
+    return referent;
+}
+
+void CssmRemoteData::reset()
+{
+    if (iOwnTheData)
+        allocator.free(referent);
+    referent.clear();
+}
+
+
+//
+// Date stuff
+//
+CssmDateData::CssmDateData(const CSSM_DATE &date)
+: CssmData(buffer, sizeof(buffer))
+{
+	memcpy(buffer, date.Year, 4);
+	memcpy(buffer + 4, date.Month, 2);
+	memcpy(buffer + 6, date.Day, 2);
+}
+
+CssmGuidData::CssmGuidData(const CSSM_GUID &guid) : CssmData(buffer, sizeof(buffer))
+{
+	Guid::overlay(guid).toString(buffer);
+}
+
+CssmDLPolyData::operator CSSM_DATE () const
+{
+	assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_BLOB);
+	if (mData.Length != 8)
+		CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+	CSSM_DATE date;
+	memcpy(date.Year, mData.Data, 4);
+	memcpy(date.Month, mData.Data + 4, 2);
+	memcpy(date.Day, mData.Data + 6, 2);
+	return date;
+}
+
+CssmDLPolyData::operator Guid () const
+{
+	assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_BLOB);
+	if (mData.Length != Guid::stringRepLength + 1)
+		CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
+
+	return Guid(reinterpret_cast<const char *>(mData.Data));
+}
diff --git a/cdsa/cdsa_utilities/cssmdata.h b/cdsa/cdsa_utilities/cssmdata.h
new file mode 100644
index 00000000..0211bace
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmdata.h
@@ -0,0 +1,423 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmdata.h -- Manager different CssmData types
+//
+#ifndef _H_CDSA_UTILITIES_CSSMDATA
+#define _H_CDSA_UTILITIES_CSSMDATA
+
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <Security/refcount.h>
+
+#ifdef _CPP_CDSA_UTILITIES_CSSMDATA
+#pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// The following pseudo-code describes what (at minimum) is required for a class
+// to be a "PseudoData". PseudoData arguments are used in templates.
+//
+// class PseudoData {
+//	void *data() const ...
+//  size_t length() const ...
+//  operator const CssmData &() const ...
+// }
+//
+// All this can be satisfied, of course, by inheriting form CssmData.
+//
+
+
+//
+// A common virtual parent for CssmData-like objects that actively manage the
+// allocation status of their data blob. Note that this is about allocating
+// the data(), not the CssmData structure itself.
+// The ManagedData layer provides for little active memory management, since
+// the underlying strategies are potentially very disparate. It does however
+// have a well defined interface for *yielding up* its data for copying or transfer.
+//
+class CssmManagedData {
+public:
+	CssmManagedData(CssmAllocator &alloc) : allocator(alloc) { }
+	virtual ~CssmManagedData();
+	
+	CssmAllocator &allocator;
+	
+	virtual operator const CssmData & () const { return get(); }
+	template <class T> T *data() const	{ return reinterpret_cast<T *>(data()); }
+	void *data() const					{ return get().data(); }
+	size_t length() const				{ return get().length(); }
+	
+	virtual CssmData &get() const throw() = 0; // get shared copy, no ownership change
+	virtual CssmData release() = 0;		// give up copy, ownership is transferred
+	virtual void reset() = 0;			// give up copy, data is discarded
+};
+
+
+//
+// A CssmOwnedData is a CssmManagedData that unilaterally owns its data storage.
+// It has its CssmData object provided during construction.
+//
+class CssmOwnedData : public CssmManagedData {
+public:
+	CssmOwnedData(CssmAllocator &alloc, CssmData &mine) : CssmManagedData(alloc), referent(mine) { }
+
+	CssmOwnedData(CssmAllocator &alloc, CSSM_DATA &mine)
+	: CssmManagedData(alloc), referent(CssmData::overlay(mine)) { referent.clear(); }
+	
+	//
+	// Basic retrievals (this echoes features of CssmData)
+	//
+	operator void * () const		{ return referent; }
+	operator char * () const		{ return referent; }
+	operator signed char * () const	 { return referent; }
+	operator unsigned char * () const { return referent; }
+	
+	operator bool () const			{ return referent; }
+	bool operator ! () const		{ return !referent; }
+	
+	size_t length() const			{ return referent.length(); }
+
+	
+	//
+	// Basic allocators
+	//
+	void *malloc(size_t len)
+	{
+		// pseudo-atomic reallocation semantics
+		CssmAutoPtr<uint8> alloc(allocator, allocator.malloc<uint8>(len));
+		reset();
+		return referent = CssmData(alloc.release(), len);
+	}
+	
+	void *realloc(size_t newLen)
+	{
+		// CssmAllocator::realloc() should be pseudo-atomic (i.e. throw on error)
+		return referent = CssmData(allocator.realloc<uint8>(referent.data(), newLen), newLen);
+	}
+    
+	void length(size_t len)			{ realloc(len); }
+
+
+	//
+	// Manipulate existing data
+	//
+	void *append(const void *addData, size_t addLength)
+	{
+		size_t oldLength = length();
+		realloc(oldLength + addLength);
+		return memcpy(referent.at(oldLength), addData, addLength);
+	}
+	
+	void *append(const CssmData &data)
+	{ return append(data.data(), data.length()); }
+	
+	//
+	// set() replaces current data with new, taking over ownership to the extent possible.
+	//
+	template <class T>
+	void set(T *data, size_t length)
+	{
+		// assume that data was allocated by our allocator -- we can't be sure
+		reset();
+		referent = CssmData(data, length);
+	}
+	
+	void set(CssmManagedData &source);
+	void set(const CSSM_DATA &source)	{ set(source.Data, source.Length); }
+	// NOTE: General template set() cannot be used because all subclasses of CssmManagedData
+	// need to receive the special handling above. Use set(*.data(), *.length()) instead.
+
+
+	//
+	// copy() replaces current data with new, making a copy and leaving
+	// the source intact.
+	//
+	template <class T>
+	void copy(const T *data, size_t length)
+	{
+		// don't leave any open windows for Mr. Murphy
+		CssmAutoPtr<void> newData(allocator, memcpy(allocator.malloc(length), data, length));
+		reset();
+		referent = CssmData(newData.release(), length);
+	}
+	
+	void copy(const CssmData &source)
+	{ if (&source != &referent) copy(source.data(), source.length()); }
+	void copy(const CSSM_DATA &source)
+	{ if (&source != &referent) copy(source.Data, source.Length); }
+	void copy(CssmManagedData &source)		{ copy(source.get()); }
+	template <class Data>
+	void copy(const Data &source)			{ copy(source.data(), source.length()); }
+
+	
+	//
+	// Assignment conservatively uses copy if allocator unknown, set if known
+	//
+	void operator = (CssmManagedData &source) { set(source); }
+	void operator = (CssmOwnedData &source) { set(source); }
+	void operator = (const CSSM_DATA &source) { copy(source); }
+	
+	CssmData &get() const throw()			{ return referent; }
+	
+protected:
+	CssmData &referent;
+};
+
+
+//
+// A CssmAutoData is a CssmOwnedData that includes its CssmData object.
+// This is the very simple case: The object includes ownership, data object,
+// and data storage.
+//
+class CssmAutoData : public CssmOwnedData {
+public:
+	CssmAutoData(CssmAllocator &alloc) : CssmOwnedData(alloc, mData) { }
+	
+	template <class Data>
+	CssmAutoData(CssmAllocator &alloc, const Data &source) : CssmOwnedData(alloc, mData)
+	{ *this = source; }
+	
+	explicit CssmAutoData(CssmManagedData &source) : CssmOwnedData(source.allocator, mData)
+	{ set(source); }
+	
+	CssmAutoData(CssmAllocator &alloc, const void *data, size_t length)
+	: CssmOwnedData(alloc, mData)	{ copy(data, length); }
+	
+	~CssmAutoData()					{ allocator.free(mData); }
+	
+	CssmData release();
+	void reset();
+	
+	// assignment (not usefully inherited)
+	void operator = (CssmManagedData &source)		{ set(source); }
+	void operator = (CssmOwnedData &source)			{ set(source); }
+	void operator = (CssmAutoData &source)			{ set(source); }
+	template <class Data>
+	void operator = (const Data &source)			{ copy(source); }
+
+private:
+	CssmData mData;
+};
+
+
+//
+// A CssmRemoteData is a CssmOwnedData that uses an external CssmData object.
+// Its release operation clears an internal ownership flag but does not clear
+// the CssmData values so they can be used to return values to an outside scope.
+//
+class CssmRemoteData : public CssmOwnedData {
+public:
+	CssmRemoteData(CssmAllocator &alloc, CssmData &mine)
+	: CssmOwnedData(alloc, mine), iOwnTheData(true) { }
+	
+	CssmRemoteData(CssmAllocator &alloc, CSSM_DATA &mine)
+	: CssmOwnedData(alloc, mine), iOwnTheData(true) { }
+	
+	~CssmRemoteData()
+	{ if (iOwnTheData) allocator.free(referent); }
+	
+	CssmData release();
+	void reset();
+	
+	// assignment (not usefully inherited)
+	void operator = (CssmManagedData &source)		{ set(source); }
+	void operator = (CssmOwnedData &source)			{ set(source); }
+	void operator = (CssmAutoData &source)			{ set(source); }
+	template <class Data>
+	void operator = (const Data &source)			{ copy(source); }
+	
+private:
+	bool iOwnTheData;
+};
+
+
+//
+// CssmPolyData
+//
+// Used by functions that take a CssmData and would like to allow it to be
+// initialized with a static string, int or other basic type.  The function *must*
+// copy the Data of the CssmPolyData when doing so if it is to be used
+// after the function returns.  (For example by creating a CssmDataContainer from it).
+class CssmPolyData : public CssmData {
+	template <class T>
+	uint8 *set(const T &it)
+	{ return const_cast<uint8 *>(reinterpret_cast<const uint8 *>(&it)); }
+public:
+	template <class char_T>
+	CssmPolyData(const char_T *s) : CssmData(const_cast<char_T *>(s), strlen(s)) {}
+	CssmPolyData(const string &s) : CssmData(const_cast<char *>(s.c_str()), s.size()) {}
+	CssmPolyData(const CSSM_DATA &data) : CssmData(data.Data, data.Length) {}
+
+	// Don't use a template constructor (for T &) here - it would eat way too much
+	CssmPolyData(const bool &t) : CssmData(set(t), sizeof(t)) { }
+	CssmPolyData(const uint32 &t) : CssmData(set(t), sizeof(t)) { }
+	CssmPolyData(const sint32 &t) : CssmData(set(t), sizeof(t)) { }
+	CssmPolyData(const sint64 &t) : CssmData(set(t), sizeof(t)) { }
+	CssmPolyData(const double &t) : CssmData(set(t), sizeof(t)) { }
+};
+
+class CssmDateData : public CssmData
+{
+public:
+	CssmDateData(const CSSM_DATE &date);
+private:
+	uint8 buffer[8];
+};
+
+class CssmGuidData : public CssmData
+{
+public:
+	CssmGuidData(const CSSM_GUID &guid);
+private:
+	char buffer[Guid::stringRepLength + 1];
+};
+
+
+//
+// CssmDLPolyData
+//
+class CssmDLPolyData
+{
+public:
+	CssmDLPolyData(const CSSM_DATA &data, CSSM_DB_ATTRIBUTE_FORMAT format)
+	: mData(CssmData::overlay(data)), mFormat(format) {}
+
+	// @@@ Don't use assert, but throw an exception.
+	// @@@ Do a size check on mData as well.
+
+	// @@@ This method is dangerous since the returned string is not guaranteed to be zero terminated.
+	operator const char *() const
+	{
+		assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_STRING
+               || mFormat == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE);
+		return reinterpret_cast<const char *>(mData.Data);
+	}
+	operator bool() const
+	{
+		assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_UINT32 || mFormat == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
+		return *reinterpret_cast<uint32 *>(mData.Data);
+	}
+	operator uint32() const
+	{
+		assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_UINT32);
+		return *reinterpret_cast<uint32 *>(mData.Data);
+	}
+	operator const uint32 *() const
+	{
+		assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32);
+		return reinterpret_cast<const uint32 *>(mData.Data);
+	}
+	operator sint32() const
+	{
+		assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
+		return *reinterpret_cast<sint32 *>(mData.Data);
+	}
+	operator double() const
+	{
+		assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_REAL);
+		return *reinterpret_cast<double *>(mData.Data);
+	}
+	operator CSSM_DATE () const;
+	operator Guid () const;
+	operator const CssmData &() const
+	{
+		return mData;
+	}
+
+private:
+	const CssmData &mData;
+	CSSM_DB_ATTRIBUTE_FORMAT mFormat;
+};
+
+
+//
+// Non POD refcounted CssmData wrapper that own the data it refers to.
+//
+class CssmDataContainer : public CssmData, public RefCount
+{
+public:
+    CssmDataContainer(CssmAllocator &inAllocator = CssmAllocator::standard()) :
+	CssmData(), mAllocator(inAllocator) {}
+	template <class T>
+    CssmDataContainer(const T *data, size_t length, CssmAllocator &inAllocator = CssmAllocator::standard()) :
+	CssmData(inAllocator.malloc(length), length), mAllocator(inAllocator) 
+	{ if (length) ::memcpy(Data, data, length); }
+	void clear() { if (Data) { mAllocator.free(Data); Data = NULL; Length = 0; } }
+	~CssmDataContainer() { if (Data) mAllocator.free(Data); }
+	void append(const CssmPolyData &data)
+	{
+		uint32 newLength = Length + data.Length;
+		Data = reinterpret_cast<uint8 *>(mAllocator.realloc(Data, newLength));
+		memcpy(Data + Length, data.Data, data.Length);
+		Length = newLength;
+	}
+	CssmDataContainer(const CssmDataContainer &other)
+	: mAllocator(other.mAllocator)
+	{
+		Data = reinterpret_cast<uint8 *>(mAllocator.malloc(other.Length));
+		memcpy(Data, other.Data, other.Length);
+		Length = other.Length;
+	}
+	CssmDataContainer & operator = (const CSSM_DATA &other)
+	{
+		clear();
+		Data = reinterpret_cast<uint8 *>(mAllocator.malloc(other.Length));
+		memcpy(Data, other.Data, other.Length);
+		Length = other.Length;
+		return *this;
+	}
+
+public:
+	CssmAllocator &mAllocator;
+
+private:
+	operator CssmDataContainer * () const;  // prohibit conversion-to-my-pointer
+};
+
+//
+// CSSM_OIDs are CSSM_DATAs but will probably have different wrapping characteristics.
+//
+typedef CssmDataContainer CssmOidContainer;
+
+template <class Container>
+class CssmBuffer : public RefPointer<Container>
+{
+public:
+    CssmBuffer() : RefPointer<Container>(new Container()) {} // XXX This should may just set ptr to NULL.
+	template <class T>
+    CssmBuffer(const T *data, size_t length, CssmAllocator &inAllocator = CssmAllocator::standard()) :
+	RefPointer<Container>(new Container(data, length, inAllocator)) {}
+    CssmBuffer(const CSSM_DATA &data, CssmAllocator &inAllocator = CssmAllocator::standard()) :
+	RefPointer<Container>(new Container(data.Data, data.Length, inAllocator)) {}
+	CssmBuffer(const CssmBuffer& other) : RefPointer<Container>(other) {}
+	CssmBuffer(Container *p) : RefPointer<Container>(p) {}
+	bool CssmBuffer::operator < (const CssmBuffer &other) const { return (**this) < (*other); }
+};
+
+} // end namespace Security
+
+#ifdef _CPP_CSSMDATA
+#pragma export off
+#endif
+
+#endif // _H_CDSA_UTILITIES_CSSMDATA
diff --git a/cdsa/cdsa_utilities/cssmdates.cpp b/cdsa/cdsa_utilities/cssmdates.cpp
new file mode 100644
index 00000000..e97933ff
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmdates.cpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+
+//
+// Manage the Tower of Babel of CSSM dates and times
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMDATES
+#endif
+#include <Security/cssmdates.h>
+
+
diff --git a/cdsa/cdsa_utilities/cssmdates.h b/cdsa/cdsa_utilities/cssmdates.h
new file mode 100644
index 00000000..5f2d7500
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmdates.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+//
+// Manage the Tower of Babel of CSSM dates and times.
+//
+#ifndef _H_CSSMDATES
+#define _H_CSSMDATES
+
+#include <Security/utilities.h>
+
+#ifdef _CPP_CSSMDATES
+#pragma export on
+#endif
+
+namespace Security
+{
+
+class CssmDate : public PodWrapper<CssmDate, CSSM_DATE>
+{
+};
+
+
+class CssmStringDate
+{
+public:
+	CssmStringDate(CSSM_TIMESTRING str);
+private:
+	CSSM_TIMESTRING timeString;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_CSSMDATES
+#pragma export off
+#endif
+
+#endif //_H_CSSMDATES
diff --git a/cdsa/cdsa_utilities/cssmdb.cpp b/cdsa/cdsa_utilities/cssmdb.cpp
new file mode 100644
index 00000000..4d276249
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmdb.cpp
@@ -0,0 +1,316 @@
+/*
+ * 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.
+ */
+
+
+// cssmdb.cpp
+//
+//
+
+#ifdef __MWERKS__
+#define _CPP_UTILITIES
+#endif
+
+#include <Security/cssmdb.h>
+
+#if 0
+// XXX Obsolete
+CSSM_RETURN	AddFooToIntelList( void** theIntelListToAddItTo, unsigned long* theNumberOfThingsAlreadyInTheList, const void* theThingToAdd, size_t theSizeOfTheThingToAdd)
+{	// this is to make adding things to Intel LISTs (also called Arrays by the rest of us) easy! We do it everywhere! Join the fun!
+  CSSM_RETURN result = CSSM_OK;
+	void*	theReallocatedBuffer = NULL;
+	if( *theIntelListToAddItTo == NULL )
+	{
+		
+		*theIntelListToAddItTo = malloc(theSizeOfTheThingToAdd);
+		if(!*theIntelListToAddItTo)
+		{
+			result = CSSMERR_CSSM_MEMORY_ERROR;
+		}
+	}
+	 else
+	 {
+			theReallocatedBuffer = realloc((void*)*theIntelListToAddItTo, (*theNumberOfThingsAlreadyInTheList+1) * (theSizeOfTheThingToAdd) );
+			if(!theReallocatedBuffer)
+			{
+				result = CSSMERR_CSSM_MEMORY_ERROR;
+			}	 
+			 else
+			 {
+			 	*theIntelListToAddItTo = theReallocatedBuffer;
+			 }
+	 }
+	 
+	 if(result == CSSM_OK )
+	 {
+	 	memcpy( (void*)((char*)*theIntelListToAddItTo+(theSizeOfTheThingToAdd * (*theNumberOfThingsAlreadyInTheList))), theThingToAdd, theSizeOfTheThingToAdd);
+	 	(*theNumberOfThingsAlreadyInTheList)++;
+	 }
+	 
+   return result;
+}
+#endif
+
+//
+// CssmDbAttributeInfo
+//
+bool
+CssmDbAttributeInfo::operator <(const CssmDbAttributeInfo& other) const
+{
+	if (nameFormat() < other.nameFormat()) return true;
+	if (other.nameFormat() < nameFormat()) return false;
+	// nameFormat's are equal.
+	switch (nameFormat())
+	{
+	case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
+	{
+		int res = strcmp(static_cast<const char *>(*this), static_cast<const char *>(other));
+		if (res < 0) return true;
+		if (res > 0) return false;
+		break;
+	}
+	case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
+		if (static_cast<const CssmOid &>(*this) < static_cast<const CssmOid &>(other)) return true;
+		if (static_cast<const CssmOid &>(other) < static_cast<const CssmOid &>(*this)) return false;
+		break;
+	case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
+		if (static_cast<uint32>(*this) < static_cast<uint32>(other)) return true;
+		if (static_cast<uint32>(other) < static_cast<uint32>(*this)) return false;
+		break;
+	default:
+		CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
+	}
+
+	return format() < other.format();
+}
+
+bool
+CssmDbAttributeInfo::operator ==(const CssmDbAttributeInfo& other) const
+{
+	if (nameFormat() != other.nameFormat()) return false;
+	if (format() != other.format()) return false;
+	switch (nameFormat())
+	{
+	case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
+		return !strcmp(static_cast<const char *>(*this), static_cast<const char *>(other));
+	case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
+		return static_cast<const CssmOid &>(*this) == static_cast<const CssmOid &>(other);
+	case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
+		return static_cast<uint32>(*this) == static_cast<uint32>(other);
+	default:
+		CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
+	}
+}
+
+//
+// CssmDbAttributeData
+//
+void
+CssmDbAttributeData::deleteValues(CssmAllocator &inAllocator)
+{
+	// Loop over all values and delete each one.
+	if (Value)
+	{
+		for (uint32 anIndex = 0; anIndex < NumberOfValues; anIndex++)
+		{
+			if (Value[anIndex].Length)
+			{
+				inAllocator.free(Value[anIndex].Data);
+				Value[anIndex].Length = 0;
+			}
+		}
+
+		inAllocator.free(Value);
+		Value = NULL;
+	}
+
+	NumberOfValues = 0;
+}
+
+bool
+CssmDbAttributeData::operator <(const CssmDbAttributeData &other) const
+{
+	if (info() < other.info()) return true;
+	if (other.info() < info()) return false;
+
+	uint32 minSize = min(size(), other.size());
+	for (uint32 ix = 0; ix < minSize; ++ix)
+	{
+		if (at<const CssmData &>(ix) < other.at<const CssmData &>(ix))
+			return true;
+		if (other.at<const CssmData &>(ix) < at<const CssmData &>(ix))
+			return false;
+	}
+
+	return size() < other.size();
+}
+
+void
+CssmDbAttributeData::add(const CssmDbAttributeData &src, CssmAllocator &inAllocator)
+{
+	// Add all the values from another attribute into this attribute.
+
+	Value = reinterpret_cast<CSSM_DATA *>(inAllocator.realloc(Value,
+		sizeof(*Value) * (NumberOfValues + src.NumberOfValues)));
+		
+	for (uint32 srcIndex = 0; srcIndex < src.NumberOfValues; srcIndex++) {
+		uint32 destIndex = NumberOfValues + srcIndex;
+		
+		Value[destIndex].Length = 0;
+		Value[destIndex].Data = inAllocator.alloc<uint8>(src.Value[srcIndex].Length);
+		Value[destIndex].Length = src.Value[srcIndex].Length;
+		memcpy(Value[destIndex].Data, src.Value[srcIndex].Data, src.Value[srcIndex].Length);
+	}
+	
+	NumberOfValues += src.NumberOfValues;
+}
+
+bool
+CssmDbAttributeData::deleteValue(const CssmData &src, CssmAllocator &inAllocator)
+{
+	// Delete a single value from this attribute, if it is present.
+
+	for (uint32 i = 0; i < NumberOfValues; i++)
+		if (CssmData::overlay(Value[i]) == src)
+		{
+			inAllocator.free(Value[i].Data);
+			Value[i].Length = 0;
+			
+			NumberOfValues--;
+			Value[i].Data = Value[NumberOfValues].Data;
+			Value[i].Length = Value[NumberOfValues].Length;
+		
+			return true;
+		}
+		
+	return false;
+}
+
+// Delete those values found in src from this object, if they are present.
+// Warning: This is O(N^2) worst case; if this becomes a performance bottleneck
+// then it will need to be changed.
+
+void
+CssmDbAttributeData::deleteValues(const CssmDbAttributeData &src, CssmAllocator &inAllocator)
+{
+	for (uint32 i = 0; i < src.NumberOfValues; i++)
+		deleteValue(CssmData::overlay(src.Value[i]), inAllocator);
+}
+
+//
+// CssmDbRecordAttributeData
+//
+CssmDbAttributeData *
+CssmDbRecordAttributeData::find(const CSSM_DB_ATTRIBUTE_INFO &inInfo)
+{
+	const CssmDbAttributeInfo &anInfo = CssmDbAttributeInfo::overlay(inInfo);
+	for (uint32 ix = 0; ix < size(); ++ix)
+	{
+		if (at(ix).info() == anInfo)
+			return &at(ix);
+	}
+
+	return NULL;
+}
+
+bool
+CssmDbRecordAttributeData::operator <(const CssmDbRecordAttributeData &other) const
+{
+	if (recordType() < other.recordType()) return true;
+	if (other.recordType() < recordType()) return false;
+	if (semanticInformation() < other.semanticInformation()) return true;
+	if (other.semanticInformation() < semanticInformation()) return false;
+
+	uint32 minSize = min(size(), other.size());
+	for (uint32 ix = 0; ix < minSize; ++ix)
+	{
+		if (at(ix) < other.at(ix))
+			return true;
+		if (other.at(ix) < at(ix))
+			return false;
+	}
+
+	return size() < other.size();
+}
+
+
+//
+// CssmAutoDbRecordAttributeData
+//
+CssmAutoDbRecordAttributeData::~CssmAutoDbRecordAttributeData()
+{
+	clear();
+}
+
+void
+CssmAutoDbRecordAttributeData::clear()
+{
+	deleteValues();
+	ArrayBuilder<CssmDbAttributeData>::clear();
+}
+
+CssmDbAttributeData &
+CssmAutoDbRecordAttributeData::add(const CSSM_DB_ATTRIBUTE_INFO &info)
+{
+	CssmDbAttributeData &anAttr = add();
+	anAttr.info(info);
+	return anAttr;
+}
+
+CssmDbAttributeData &
+CssmAutoDbRecordAttributeData::add(const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value)
+{
+	CssmDbAttributeData &anAttr = add();
+	anAttr.set(info, value, mValueAllocator);
+	return anAttr;
+}
+
+//
+// CssmAutoQuery
+//
+CssmAutoQuery::CssmAutoQuery(const CSSM_QUERY &query, CssmAllocator &allocator)
+: ArrayBuilder<CssmSelectionPredicate>(static_cast<CssmSelectionPredicate *>(SelectionPredicate),
+									   NumSelectionPredicates,
+									   query.NumSelectionPredicates, allocator)
+{
+	RecordType = query.RecordType;
+	Conjunctive = query.Conjunctive;
+	QueryLimits =  query.QueryLimits;
+	QueryFlags = query.QueryFlags;
+	for (uint32 ix = 0; ix < query.NumSelectionPredicates; ++ix)
+		add().set(query.SelectionPredicate[ix], allocator);
+}
+
+CssmAutoQuery::~CssmAutoQuery()
+{
+	clear();
+}
+
+void
+CssmAutoQuery::clear()
+{
+	deleteValues();
+	ArrayBuilder<CssmSelectionPredicate>::clear();
+}
+
+CssmSelectionPredicate &
+CssmAutoQuery::add(CSSM_DB_OPERATOR dbOperator, const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value)
+{
+	CssmSelectionPredicate &predicate = add();
+	predicate.dbOperator(dbOperator);
+	predicate.set(info, value, allocator());
+	return predicate;
+}
diff --git a/cdsa/cdsa_utilities/cssmdb.h b/cdsa/cdsa_utilities/cssmdb.h
new file mode 100644
index 00000000..6e7d06cb
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmdb.h
@@ -0,0 +1,657 @@
+/*
+ * 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.
+ */
+
+
+// cssmdb.h
+//
+// classes for the DL related data structures
+//
+
+#ifndef _H_CDSA_UTILITIES_CSSMDB
+#define _H_CDSA_UTILITIES_CSSMDB
+
+#include <Security/cssmdata.h>
+#include <Security/cssmalloc.h>
+#include <Security/walkers.h>
+#include <Security/DbName.h>
+
+#ifdef _CPP_UTILITIES
+#pragma export on
+#endif
+
+namespace Security
+{
+
+
+#if 0
+//
+// XXX Obsolete --mb
+//
+// some prototypes for utility functions
+CSSM_RETURN						AddFooToIntelList( void** theIntelListToAddItTo, unsigned long* theNumberOfThingsAlreadyInTheList, const void* theThingToAdd, size_t theSizeOfTheThingToAdd);
+#endif
+
+//
+// Template class to build and maintain external arrays.
+// Feel free to add and vector<> member functions and behaviours as needed.
+//
+// This class differs from vector mainly because it does not construct or
+// destruct any of the elements it contains.  Rather it zero fills the
+// storage and returns references to elements.
+// Also it does not implement insert(), erase() or assign().  It does implement
+// which is equivalent to calling *insert(end()) on a vector.
+//
+template <class _Tp>
+class ArrayBuilder {
+public:
+	typedef _Tp value_type;
+	typedef value_type* pointer;
+	typedef const value_type* const_pointer;
+	typedef value_type* iterator;
+	typedef const value_type* const_iterator;
+	typedef value_type& reference;
+	typedef const value_type& const_reference;
+	typedef uint32 size_type;
+	typedef ptrdiff_t difference_type;
+
+	typedef reverse_iterator<const_iterator> const_reverse_iterator;
+	typedef reverse_iterator<iterator> reverse_iterator;
+
+protected:
+  void insert_aux(iterator __position, const _Tp& __x);
+  void insert_aux(iterator __position);
+
+public:
+	iterator begin() { return mArray; }
+	const_iterator begin() const { return mArray; }
+	iterator end() { return &mArray[mSize]; }
+	const_iterator end() const { return &mArray[mSize]; }
+	
+	reverse_iterator rbegin()
+	{ return reverse_iterator(end()); }
+	const_reverse_iterator rbegin() const
+	{ return const_reverse_iterator(end()); }
+	reverse_iterator rend()
+	{ return reverse_iterator(begin()); }
+	const_reverse_iterator rend() const
+	{ return const_reverse_iterator(begin()); }
+
+	// Must be defined in base class.
+	//size_type size() const
+	//{ return mSize; }
+	size_type max_size() const
+	{ return size_type(-1) / sizeof(_Tp); }
+	size_type capacity() const
+	{ return mCapacity; }
+	bool empty() const
+	{ return begin() == end(); }
+
+	ArrayBuilder(pointer &array, size_type &size, size_type capacity = 0, CssmAllocator &allocator = CssmAllocator::standard()) :
+	mArray(array), mSize(size), mCapacity(capacity), mAllocator(allocator)
+	{
+#if BUG_GCC
+		mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity));
+#else
+		mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity));
+		//mArray = mAllocator.alloc(mCapacity);
+#endif
+		memset(mArray, 0, sizeof(value_type) * mCapacity);
+		mSize = 0;
+	}
+	~ArrayBuilder() { mAllocator.free(mArray); }
+
+	reference front() { return *begin(); }
+	const_reference front() const { return *begin(); }
+	reference back() { return *(end() - 1); }
+	const_reference back() const { return *(end() - 1); }
+
+	void reserve(size_type newCapacity)
+	{
+		if (newCapacity > mCapacity)
+		{
+#if BUG_GCC
+			mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity));
+#else
+			mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity));
+			//mArray = mAllocator.realloc<value_type>(mArray, newCapacity));
+#endif
+			memset(&mArray[mCapacity], 0, sizeof(value_type) * (newCapacity - mCapacity));
+			mCapacity = newCapacity;
+		}
+	}
+
+	// XXX Replace by push_back and insert.
+	reference add()
+	{
+		if (mSize >= mCapacity)
+			reserve(max(mSize + 1, mCapacity ? 2 * mCapacity : 1));
+
+		return mArray[mSize++];
+	}
+
+	const_pointer get() const { return mArray; }
+	pointer release() { const_pointer array = mArray; mArray = NULL; return array; }
+	void clear() { if (mSize) { memset(mArray, 0, sizeof(value_type) * mSize); } mSize = 0; }
+
+	// Must be defined in base class.
+	//reference at(size_type ix) { return mArray[ix]; }
+	//const_reference at(size_type ix) const { return mArray[ix]; }
+	//reference operator[] (size_type ix) { assert(ix < size()); return at(ix); }
+	//const_reference operator[] (size_type ix) const { assert(ix < size()); return at(ix); }
+protected:
+	CssmAllocator &allocator() const { return mAllocator; }
+
+private:
+
+	pointer &mArray;
+	size_type &mSize;
+	size_type mCapacity;
+	CssmAllocator &mAllocator;
+};
+
+
+//
+// CssmDbAttributeInfo pod wrapper for CSSM_DB_ATTRIBUTE_INFO
+//
+class CssmDbAttributeInfo : public PodWrapper<CssmDbAttributeInfo, CSSM_DB_ATTRIBUTE_INFO>
+{
+public:
+	CssmDbAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO &attr)
+	{ (CSSM_DB_ATTRIBUTE_INFO &)*this = attr; }
+
+	CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat() const { return AttributeNameFormat; }
+	void nameFormat(CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat) { AttributeNameFormat = nameFormat; }
+
+	CSSM_DB_ATTRIBUTE_FORMAT format() const { return AttributeFormat; }
+	void format(CSSM_DB_ATTRIBUTE_FORMAT format) { AttributeFormat = format; }
+
+	operator const char *() const
+	{
+		assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_STRING);
+		return Label.AttributeName;
+	}
+	operator const CssmOid &() const
+	{
+		assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_OID);
+		return CssmOid::overlay(Label.AttributeOID);
+	}
+	operator uint32() const
+	{
+		assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER);
+		return Label.AttributeID;
+	}
+
+	bool operator <(const CssmDbAttributeInfo& other) const;
+	bool operator ==(const CssmDbAttributeInfo& other) const;
+	bool operator !=(const CssmDbAttributeInfo& other) const
+	{ return !(*this == other); }
+
+	// XXX Add setting member functions.
+};
+
+//
+// CssmDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO
+//
+class CssmDbRecordAttributeInfo : public PodWrapper<CssmDbRecordAttributeInfo, CSSM_DB_RECORD_ATTRIBUTE_INFO>
+{
+public:
+	CssmDbRecordAttributeInfo()
+	{ DataRecordType = CSSM_DL_DB_RECORD_ANY; }
+	
+	CssmDbRecordAttributeInfo(CSSM_DB_RECORDTYPE recordType, uint32 numberOfAttributes,
+							  CSSM_DB_ATTRIBUTE_INFO_PTR attributeInfo)
+	{
+		DataRecordType = recordType;
+		NumberOfAttributes = numberOfAttributes;
+		AttributeInfo = attributeInfo;
+	}
+
+	CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; }
+	void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; }
+
+	uint32 size() const { return NumberOfAttributes; }
+
+	// Attributes by position
+    CssmDbAttributeInfo &at(uint32 ix)
+	{ return CssmDbAttributeInfo::overlay(AttributeInfo[ix]); }
+    const CssmDbAttributeInfo &at(uint32 ix) const
+	{ return CssmDbAttributeInfo::overlay(AttributeInfo[ix]); }
+
+    CssmDbAttributeInfo &operator [](uint32 ix)
+    { assert(ix < size()); return at(ix); }
+    const CssmDbAttributeInfo &operator [](uint32 ix) const
+    { assert(ix < size()); return at(ix); }
+};
+
+//
+// CssmAutoDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO
+//
+class CssmAutoDbRecordAttributeInfo: public CssmDbRecordAttributeInfo, public ArrayBuilder<CssmDbAttributeInfo>
+{
+public:
+	CssmAutoDbRecordAttributeInfo(uint32 capacity = 0, CssmAllocator &allocator = CssmAllocator::standard()) :
+	CssmDbRecordAttributeInfo(),
+	ArrayBuilder<CssmDbAttributeInfo>(static_cast<CssmDbAttributeInfo *>(AttributeInfo),
+									  NumberOfAttributes, capacity, allocator) {}
+};
+
+
+//
+// CssmDbAttributeData pod wrapper for CSSM_DB_ATTRIBUTE_DATA
+//
+class CssmDbAttributeData : public PodWrapper<CssmDbAttributeData, CSSM_DB_ATTRIBUTE_DATA>
+{
+public:
+	CssmDbAttributeData() { NumberOfValues = 0; Value = NULL; }
+	CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_DATA &attr)
+	{ (CSSM_DB_ATTRIBUTE_DATA &)*this = attr; }
+	CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_INFO &info)
+	{ Info = info; NumberOfValues = 0; Value = NULL; }
+
+	CSSM_DB_ATTRIBUTE_FORMAT format() const { return info().format(); }
+
+	CssmDbAttributeInfo &info() { return CssmDbAttributeInfo::overlay(Info); }
+	const CssmDbAttributeInfo &info() const { return CssmDbAttributeInfo::overlay(Info); }
+	void info (const CSSM_DB_ATTRIBUTE_INFO &inInfo) { Info = inInfo; }
+
+	uint32 size() const { return NumberOfValues; }
+
+	template <class T>
+    T at(unsigned int ix) const { return CssmDLPolyData(Value[ix], format()); }
+
+	template <class T>
+    T operator [](unsigned int ix) const
+	{ if (ix >= size()) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE); return at(ix); }
+
+	// this is intentionally unspecified since it could lead to bugs; the
+	// data is not guaranteed to be NULL-terminated
+	// operator const char *() const;
+
+	// XXX Don't use assert, but throw an exception.
+	operator string() const
+	{
+		if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
+		assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_STRING);
+		return string(reinterpret_cast<const char *>(Value[0].Data), Value[0].Length);
+	}		
+	operator bool() const
+	{
+		if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
+		assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_UINT32 || format() == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
+		return *reinterpret_cast<uint32 *>(Value[0].Data);
+	}
+	operator uint32() const
+	{
+		if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
+		assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_UINT32);
+		return *reinterpret_cast<uint32 *>(Value[0].Data);
+	}
+	operator const uint32 *() const
+	{
+		if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
+		assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32);
+		return reinterpret_cast<const uint32 *>(Value[0].Data);
+	}
+	operator sint32() const
+	{
+		if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
+		assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
+		return *reinterpret_cast<sint32 *>(Value[0].Data);
+	}
+	operator double() const
+	{
+		if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
+		assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_REAL);
+		return *reinterpret_cast<double *>(Value[0].Data);
+	}
+	operator CssmData &() const
+	{
+		if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
+		assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_STRING
+				|| format() == CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM
+				|| format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
+				|| format() == CSSM_DB_ATTRIBUTE_FORMAT_BLOB
+				|| format() == CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32);
+		return CssmData::overlay(Value[0]);
+	}
+
+	// Set the value of this Attr (assuming it was not set before).
+	void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo, const CssmPolyData &inValue,
+			 CssmAllocator &inAllocator)
+	{
+		info(inInfo);
+		NumberOfValues = 0;
+		Value = inAllocator.alloc<CSSM_DATA>();
+		Value[0].Length = 0;
+		Value[0].Data = inAllocator.alloc<uint8>(inValue.Length);
+		Value[0].Length = inValue.Length;
+		memcpy(Value[0].Data, inValue.Data, inValue.Length);
+		NumberOfValues = 1;
+	}
+
+	// Set the value of this Attr (assuming it was not set before).
+	void set(const CSSM_DB_ATTRIBUTE_DATA &other, CssmAllocator &inAllocator)
+	{
+		info(other.Info);
+		Value = inAllocator.alloc<CSSM_DATA>(other.NumberOfValues);
+		NumberOfValues = other.NumberOfValues;
+		for (NumberOfValues = 0; NumberOfValues < other.NumberOfValues; NumberOfValues++)
+		{
+			Value[NumberOfValues].Length = 0;
+			Value[NumberOfValues].Data = inAllocator.alloc<uint8>(other.Value[NumberOfValues].Length);
+			Value[NumberOfValues].Length = other.Value[NumberOfValues].Length;
+			memcpy(Value[NumberOfValues].Data, other.Value[NumberOfValues].Data,
+				   other.Value[NumberOfValues].Length);
+		}
+	}
+
+	// Add a value to this attribute.
+	void add(const CssmPolyData &inValue, CssmAllocator &inAllocator)
+	{
+		Value = reinterpret_cast<CSSM_DATA *>(inAllocator.realloc(Value, sizeof(*Value) * (NumberOfValues + 1)));
+		Value[NumberOfValues].Length = 0;
+		Value[NumberOfValues].Data = inAllocator.alloc<uint8>(inValue.Length);
+		Value[NumberOfValues].Length = inValue.Length;
+		memcpy(Value[NumberOfValues++].Data, inValue.Data, inValue.Length);
+	}
+
+	void add(const CssmDbAttributeData &src, CssmAllocator &inAllocator);
+
+	// delete specific values if they are present in this attribute data
+	bool deleteValue(const CssmData &src, CssmAllocator &inAllocator);
+	void deleteValues(const CssmDbAttributeData &src, CssmAllocator &inAllocator);
+
+	void deleteValues(CssmAllocator &inAllocator);
+
+	bool operator <(const CssmDbAttributeData& other) const;
+};
+
+
+//
+// CssmDbRecordAttributeData pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_DATA
+//
+class CssmDbRecordAttributeData : public PodWrapper<CssmDbRecordAttributeData, CSSM_DB_RECORD_ATTRIBUTE_DATA>
+{
+public:
+	CssmDbRecordAttributeData()
+	{ DataRecordType = CSSM_DL_DB_RECORD_ANY; SemanticInformation = 0; }
+
+	CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; }
+	void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; }
+
+	uint32 semanticInformation() const { return SemanticInformation; }
+	void semanticInformation(uint32 semanticInformation) { SemanticInformation = semanticInformation; }
+
+	uint32 size() const { return NumberOfAttributes; }
+
+	// Attributes by position
+    CssmDbAttributeData &at(unsigned int ix)
+	{ return CssmDbAttributeData::overlay(AttributeData[ix]); }
+    const CssmDbAttributeData &at(unsigned int ix) const
+	{ return CssmDbAttributeData::overlay(AttributeData[ix]); }
+
+    CssmDbAttributeData &operator [](unsigned int ix)
+    { assert(ix < size()); return at(ix); }
+    const CssmDbAttributeData &operator [](unsigned int ix) const
+    { assert(ix < size()); return at(ix); }
+
+    void deleteValues(CssmAllocator &allocator)
+	{ for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); }
+
+	CssmDbAttributeData *find(const CSSM_DB_ATTRIBUTE_INFO &inInfo);
+
+	bool operator <(const CssmDbRecordAttributeData& other) const;
+};
+
+
+//
+// CssmAutoDbRecordAttributeData
+//
+class CssmAutoDbRecordAttributeData : public CssmDbRecordAttributeData, public ArrayBuilder<CssmDbAttributeData>
+{
+public:
+	CssmAutoDbRecordAttributeData(uint32 capacity = 0,
+								  CssmAllocator &valueAllocator = CssmAllocator::standard(),
+								  CssmAllocator &dataAllocator = CssmAllocator::standard()) :
+	CssmDbRecordAttributeData(),
+	ArrayBuilder<CssmDbAttributeData>(static_cast<CssmDbAttributeData *>(AttributeData),
+									  NumberOfAttributes, capacity, dataAllocator),
+	mValueAllocator(valueAllocator) {}
+	~CssmAutoDbRecordAttributeData();
+
+	void clear();
+    void deleteValues() { CssmDbRecordAttributeData::deleteValues(mValueAllocator); }
+
+	CssmDbAttributeData &add() { return ArrayBuilder<CssmDbAttributeData>::add(); } // XXX using doesn't work here.
+	CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info);
+	CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value);
+
+	// So clients can pass this as the allocator argument to add()
+	operator CssmAllocator &() const { return mValueAllocator; }
+private:
+	CssmAllocator &mValueAllocator;
+};
+
+
+//
+// CssmSelectionPredicate a PodWrapper for CSSM_SELECTION_PREDICATE
+//
+class CssmSelectionPredicate : public PodWrapper<CssmSelectionPredicate, CSSM_SELECTION_PREDICATE> {
+public:
+	CssmSelectionPredicate() { /*IFDEBUG(*/ memset(this, 0, sizeof(*this)) /*)*/ ; }
+	CssmSelectionPredicate(CSSM_DB_OPERATOR inDbOperator)
+	{ dbOperator(inDbOperator); Attribute.NumberOfValues = 0; Attribute.Value = NULL; }
+
+	CSSM_DB_OPERATOR dbOperator() const { return DbOperator; }
+	void dbOperator(CSSM_DB_OPERATOR dbOperator) { DbOperator = dbOperator; }
+
+	CssmDbAttributeData &attribute() { return CssmDbAttributeData::overlay(Attribute); }
+	const CssmDbAttributeData &attribute() const { return CssmDbAttributeData::overlay(Attribute); }
+
+	// Set the value of this CssmSelectionPredicate (assuming it was not set before).
+	void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo,
+			 const CssmPolyData &inValue, CssmAllocator &inAllocator)
+	{ attribute().set(inInfo, inValue, inAllocator); }
+
+	// Set the value of this CssmSelectionPredicate using another CssmSelectionPredicate's value.
+	void set(const CSSM_SELECTION_PREDICATE &other, CssmAllocator &inAllocator)
+	{ DbOperator = other.DbOperator; attribute().set(other.Attribute, inAllocator); }
+
+	// Add a value to the list of values for this CssmSelectionPredicate.
+	void add(const CssmPolyData &inValue, CssmAllocator &inAllocator)
+	{ attribute().add(inValue, inAllocator); }
+
+	void deleteValues(CssmAllocator &inAllocator) { attribute().deleteValues(inAllocator); }
+};
+
+class CssmQuery : public PodWrapper<CssmQuery, CSSM_QUERY> {
+public:
+    CssmQuery()
+    { memset(this, 0, sizeof(*this)) ; RecordType = CSSM_DL_DB_RECORD_ANY; }
+    //CssmDLQuery(const CSSM_QUERY &q) { memcpy(this, &q, sizeof(*this)); }
+
+    //CssmDLQuery &operator = (const CSSM_QUERY &q)
+    //{ memcpy(this, &q, sizeof(*this)); return *this; }
+
+	CSSM_DB_RECORDTYPE recordType() const { return RecordType; }
+	void recordType(CSSM_DB_RECORDTYPE recordType)  { RecordType = recordType; }
+
+	CSSM_DB_CONJUNCTIVE conjunctive() const { return Conjunctive; }
+	void conjunctive(CSSM_DB_CONJUNCTIVE conjunctive)  { Conjunctive = conjunctive; }
+
+	CSSM_QUERY_LIMITS queryLimits() const { return QueryLimits; }
+	void queryLimits(CSSM_QUERY_LIMITS queryLimits)  { QueryLimits = queryLimits; }
+
+	CSSM_QUERY_FLAGS queryFlags() const { return QueryFlags; }
+	void queryFlags(CSSM_QUERY_FLAGS queryFlags)  { QueryFlags = queryFlags; }
+
+	uint32 size() const { return NumSelectionPredicates; }
+
+	CssmSelectionPredicate &at(uint32 ix)
+	{ return CssmSelectionPredicate::overlay(SelectionPredicate[ix]); }
+	const CssmSelectionPredicate &at(uint32 ix) const
+	{ return CssmSelectionPredicate::overlay(SelectionPredicate[ix]); }
+
+	CssmSelectionPredicate &operator[] (uint32 ix) { assert(ix < size()); return at(ix); }
+	const CssmSelectionPredicate &operator[] (uint32 ix) const { assert(ix < size()); return at(ix); }
+
+    void deleteValues(CssmAllocator &allocator)
+	{ for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); }
+};
+
+
+class CssmAutoQuery : public CssmQuery, public ArrayBuilder<CssmSelectionPredicate> {
+public:
+	CssmAutoQuery(const CSSM_QUERY &query, CssmAllocator &allocator = CssmAllocator::standard());
+	CssmAutoQuery(uint32 capacity = 0, CssmAllocator &allocator = CssmAllocator::standard()) :
+	ArrayBuilder<CssmSelectionPredicate>(static_cast<CssmSelectionPredicate *>(SelectionPredicate),
+										 NumSelectionPredicates,
+										 capacity, allocator) {}
+	~CssmAutoQuery();
+	void clear();
+    void deleteValues() { CssmQuery::deleteValues(allocator()); }
+
+	CssmSelectionPredicate &add() { return ArrayBuilder<CssmSelectionPredicate>::add(); }
+	CssmSelectionPredicate &add(CSSM_DB_OPERATOR dbOperator, const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value);
+
+	// So clients can pass this as the allocator argument to add()
+	operator CssmAllocator &() const { return allocator(); }
+};
+
+
+//
+// DLDbIdentifier
+//
+class DLDbIdentifier
+{
+protected:
+    class Impl : public RefCount
+    {
+        NOCOPY(Impl)
+    public:
+        Impl(const CSSM_SUBSERVICE_UID &ssuid,const char *DbName,const CSSM_NET_ADDRESS *DbLocation) :
+            mCssmSubserviceUid(ssuid),mDbName(DbName,DbLocation) {}
+
+        ~Impl() {} // Must be public since RefPointer uses it.
+
+        // Accessors
+        const CssmSubserviceUid &ssuid() const { return mCssmSubserviceUid; }
+        const char *dbName() const { return mDbName.dbName().c_str(); }
+        const CssmNetAddress *dbLocation() const { return mDbName.dbLocation(); }
+
+        // operators
+        bool operator < (const Impl &other) const
+		{ return (mCssmSubserviceUid < other.mCssmSubserviceUid ||
+					(!(other.mCssmSubserviceUid < mCssmSubserviceUid) && mDbName < other.mDbName)); }
+
+        bool operator == (const Impl &other) const
+		{ return mCssmSubserviceUid == other.mCssmSubserviceUid && mDbName == other.mDbName; }
+
+    private:
+        // Private member variables
+        CssmSubserviceUid mCssmSubserviceUid;
+        DbName mDbName;
+    };
+
+public:
+    // Constructors
+    DLDbIdentifier() {}
+    DLDbIdentifier(const CSSM_SUBSERVICE_UID &ssuid,const char *DbName,const CSSM_NET_ADDRESS *DbLocation)
+        : mImpl(new Impl(ssuid, DbName, DbLocation)) {}
+
+	// Conversion Operators
+	bool operator !() const { return !mImpl; }
+	operator bool() const { return mImpl; }
+
+    // Operators
+	bool operator <(const DLDbIdentifier &other) const
+	{ return mImpl && other.mImpl ? *mImpl < *other.mImpl : &*mImpl < &*other.mImpl; }
+	bool operator ==(const DLDbIdentifier &other) const
+	{ return mImpl && other.mImpl ? *mImpl == *other.mImpl : &*mImpl == &*other.mImpl; }
+
+    // Accessors
+    const CssmSubserviceUid &ssuid() const { return mImpl->ssuid(); }
+    const char *dbName() const { return mImpl->dbName(); }
+    const CssmNetAddress *dbLocation() const { return mImpl->dbLocation(); }
+
+    RefPointer<Impl> mImpl;
+};
+
+// Wrappers for index-related CSSM objects.
+
+class CssmDbIndexInfo : public PodWrapper<CssmDbIndexInfo, CSSM_DB_INDEX_INFO>
+{
+public:
+	CssmDbIndexInfo(const CSSM_DB_INDEX_INFO &attr)
+	{ (CSSM_DB_INDEX_INFO &)*this = attr; }
+
+	CSSM_DB_INDEX_TYPE indexType() const { return IndexType; }
+	void indexType(CSSM_DB_INDEX_TYPE indexType) { IndexType = indexType; }
+
+	CSSM_DB_INDEXED_DATA_LOCATION dataLocation() const { return IndexedDataLocation; }
+	void dataLocation(CSSM_DB_INDEXED_DATA_LOCATION dataLocation)
+	{
+		IndexedDataLocation = dataLocation;
+	}
+	
+	const CssmDbAttributeInfo &attributeInfo() const
+	{
+		return CssmDbAttributeInfo::overlay(Info);
+	}
+};
+
+
+namespace DataWalkers
+{
+
+//
+// DLDbIdentifiers don't walk directly because they have Impl structure and use strings.
+// Happily, they are easily transcribed into a walkable form.
+//
+struct DLDbFlatIdentifier {
+    const CssmSubserviceUid *uid;		// module reference
+    const char *name;					// string name
+    const CssmNetAddress *address;	// optional network address
+    
+    DLDbFlatIdentifier(const DLDbIdentifier &ident)
+        : uid(&ident.ssuid()), name(ident.dbName()), address(ident.dbLocation()) { }
+        
+    operator DLDbIdentifier ()	{ return DLDbIdentifier(*uid, name, address); }
+};
+
+template<class Action>
+DLDbFlatIdentifier *walk(Action &operate, DLDbFlatIdentifier * &ident)
+{
+    operate(ident);
+    if (ident->uid)
+        walk(operate, ident->uid);
+    walk(operate, ident->name);
+    if (ident->address)
+        walk(operate, ident->address);
+    return ident;
+}
+
+} // end namespace DataWalkers
+
+} // end namespace Security
+
+#ifdef _CPP_UTILITIES
+#pragma export off
+#endif
+
+
+#endif // _H_CDSA_UTILITIES_CSSMDB
diff --git a/cdsa/cdsa_utilities/cssmerrno.cpp b/cdsa/cdsa_utilities/cssmerrno.cpp
new file mode 100644
index 00000000..23029da8
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmerrno.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmerrno - number-to-string translation for CSSM error codes
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMERRNO
+#endif
+#include <Security/cssmerrno.h>
+#include <Security/globalizer.h>
+#include <stdio.h>
+#include <map>
+
+
+namespace Security {
+
+
+//
+// The compiled database of error codes
+//
+struct ErrorMap : public map<CSSM_RETURN, const char *> {
+    ErrorMap();
+};
+static ModuleNexus<ErrorMap> errorMap;
+
+struct Mapping {
+    CSSM_RETURN error;
+    const char *name;
+};
+
+#include "errorcodes.gen"	// include generated error tables
+
+
+//
+// Create the error map (the first time)
+//
+ErrorMap::ErrorMap()
+{
+    for (unsigned n = 0; n < sizeof(errorList) / sizeof(errorList[0]); n++)
+        (*this)[errorList[n].error] = errorList[n].name;
+}
+
+
+//
+// A perror-like form usable from C (and C++)
+//
+extern "C"
+void cssmPerror(const char *how, CSSM_RETURN error)
+{
+    if (how)
+        fprintf(stderr, "%s: %s\n", how, cssmErrorString(error).c_str());
+    else
+        fprintf(stderr, "%s\n", cssmErrorString(error).c_str());
+}
+
+
+//
+// Produce a diagnostic string from a CSSM error number or exception
+//
+string cssmErrorString(CSSM_RETURN error)
+{
+    if (error == CSSM_OK) {
+    	return "[ok]";
+    } else if (error > 0 &&
+               int(error) < int(sizeof(convErrorList) / sizeof(convErrorList[0]))) {
+        return string("COMMON[") + convErrorList[error] + "]";
+    } else {
+        ErrorMap::const_iterator it = errorMap().find(error);
+        if (it == errorMap().end())
+            return "[UNKNOWN]";
+        else
+            return it->second;
+    }
+}
+
+string cssmErrorString(const CssmCommonError &error)
+{ return cssmErrorString(error.cssmError()); }
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/cssmerrno.h b/cdsa/cdsa_utilities/cssmerrno.h
new file mode 100644
index 00000000..de18b160
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmerrno.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmerrno - number-to-string translation for CSSM error codes
+//
+#ifndef _H_CSSMERRNO
+#define _H_CSSMERRNO
+
+#include <Security/utilities.h>
+
+#ifdef _CPP_CSSMERRNO
+#pragma export on
+#endif
+
+#ifdef __cplusplus
+
+#include <string>
+
+namespace Security
+{
+
+extern "C" void cssmPerror(const char *how, CSSM_RETURN error);
+string cssmErrorString(CSSM_RETURN error);
+string cssmErrorString(const CssmCommonError &error);
+
+} // end namespace Security
+
+#else // C, not C++
+
+void cssmPerror(const char *how, CSSM_RETURN error);
+
+#endif
+
+#ifdef _CPP_CSSMERRNO
+#pragma export off
+#endif
+
+#endif //_H_CSSMERRNO
diff --git a/cdsa/cdsa_utilities/cssmlist.cpp b/cdsa/cdsa_utilities/cssmlist.cpp
new file mode 100644
index 00000000..6c01777e
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmlist.cpp
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmlist - CSSM_LIST operational utilities
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMLIST
+#endif
+
+#include <Security/cssmlist.h>
+
+
+//
+// Managing list elements
+//
+ListElement *ListElement::last()
+{
+	for (ListElement *p = this; ; p = p->next())
+		if (p->next() == NULL)
+			return p;
+	// not reached
+}
+
+
+ListElement::ListElement(CSSM_WORDID_TYPE word)
+{
+	ElementType = CSSM_LIST_ELEMENT_WORDID;
+	WordID = word;
+}
+
+ListElement::ListElement(const CssmData &data)
+{
+	ElementType = CSSM_LIST_ELEMENT_DATUM;
+	WordID = 0;
+	Element.Word = data;
+}
+
+ListElement::ListElement(CssmAllocator &alloc, string s)
+{
+    ElementType = CSSM_LIST_ELEMENT_DATUM;
+    WordID = 0;
+    size_t length = s.size();
+    Element.Word = CssmData(memcpy(alloc.alloc<char>(length), s.data(), length), length);
+}
+
+ListElement::ListElement(const CssmList &list)
+{
+	ElementType = CSSM_LIST_ELEMENT_SUBLIST;
+	WordID = 0;
+	Element.Sublist = list;
+}
+
+
+CssmData &ListElement::data()
+{
+	assert(type() == CSSM_LIST_ELEMENT_DATUM);
+	return CssmData::overlay(Element.Word);
+}
+
+const CssmData &ListElement::data() const
+{
+	assert(type() == CSSM_LIST_ELEMENT_DATUM);
+	return CssmData::overlay(Element.Word);
+}
+
+CssmList &ListElement::list()
+{
+	assert(type() == CSSM_LIST_ELEMENT_SUBLIST);
+	return CssmList::overlay(Element.Sublist);
+}
+
+const CssmList &ListElement::list() const
+{
+	assert(type() == CSSM_LIST_ELEMENT_SUBLIST);
+	return CssmList::overlay(Element.Sublist);
+}
+
+CSSM_WORDID_TYPE ListElement::word() const
+{
+	assert(type() == CSSM_LIST_ELEMENT_WORDID);
+	return WordID;
+}
+
+
+//
+// List operations
+//
+ListElement &CssmList::operator [] (unsigned ix) const
+{
+	for (ListElement *elem = first(); elem; elem = elem->next(), ix--) {
+		if (ix == 0)
+			return *elem;
+	}
+	throw 999;	//@@@
+}
+
+unsigned int CssmList::length() const
+{
+	unsigned int len = 0;
+	for (ListElement *elem = first(); elem; elem = elem->next())
+		len++;
+	return len;
+}
+
+CssmList &CssmList::append(ListElement *elem)
+{
+	if (Tail == NULL) {	// first element
+		Head = Tail = elem;
+	} else {
+		Tail->NextElement = elem;
+		Tail = elem;
+	}
+	elem->NextElement = NULL;
+	return *this;
+}
+
+CssmList &CssmList::insert(ListElement *elem, ListElement *before)
+{
+	// null before -> append
+	if (before == NULL)
+		return append(elem);
+	
+	// we have a real position
+	assert(!empty());
+	if (Head == before) { // before first element
+		elem->NextElement = before;
+		Head = elem;
+	} else { // before is not first
+		for (CSSM_LIST_ELEMENT *p = Head; p; p = p->NextElement) {
+			if (p->NextElement == before) {
+				elem->NextElement = before;
+				p->NextElement = elem;
+				return *this;
+			}
+		}
+		// end of list, before not in list
+		throw 999;	//@@@
+	}
+	return *this;
+}
+
+CssmList &CssmList::remove(ListElement *elem)
+{
+	assert(elem);
+	if (elem == Head) {	// remove first element
+		Head = Head->NextElement;
+	} else { // subsequent element
+		for (CSSM_LIST_ELEMENT *p = Head; p; p = p->NextElement)
+			if (p->NextElement == elem) {
+				p->NextElement = elem->NextElement;
+				if (elem->NextElement == NULL) // removing last element
+					Tail = p;
+				return *this;
+			}
+		// end of list, elem not found
+		throw 999;	//@@@
+	}
+	return *this;
+}
+
+void CssmList::snip()
+{
+    assert(Head);	// can't be empty
+    if (Head == Tail) {	// single element, empty when snipped
+        Head = Tail = NULL;
+    } else {		// more than one, bypass first
+        Head = first()->next();
+    }
+}
+
+
+//
+// Deep-destruction of CssmLists and ListElements.
+// The underlying assumption is that all components were allocated from a single
+// CssmAllocator in canonical chunks.
+//
+void ListElement::clear(CssmAllocator &alloc)
+{
+	switch (type()) {
+	case CSSM_LIST_ELEMENT_WORDID:
+		break;	// no substructure
+	case CSSM_LIST_ELEMENT_DATUM:
+		alloc.free(data().data());
+		break;
+	case CSSM_LIST_ELEMENT_SUBLIST:
+		list().clear(alloc);
+		break;
+	default:
+		assert(false);
+	}
+}
+
+void CssmList::clear(CssmAllocator &alloc)
+{
+	ListElement *elem = first();
+	while (elem) {
+		ListElement *next = elem->next();
+		destroy(elem, alloc);
+		elem = next;
+	}
+}
+
+
+//
+// Building TypedLists
+//
+TypedList::TypedList(CssmAllocator &alloc, CSSM_WORDID_TYPE type)
+{
+	append(new(alloc) ListElement(type));
+}
+
+TypedList::TypedList(CssmAllocator &alloc, CSSM_WORDID_TYPE type, ListElement *elem1)
+{
+	append(new(alloc) ListElement(type));
+	append(elem1);
+}
+
+TypedList::TypedList(CssmAllocator &alloc, CSSM_WORDID_TYPE type, ListElement *elem1, ListElement *elem2)
+{
+	append(new(alloc) ListElement(type));
+	append(elem1);
+	append(elem2);
+}
+
+
+//
+// Verify that a TypedList is "proper", i.e. has a first element of WORDID form
+//
+bool TypedList::isProper() const
+{
+	return first() && first()->type() == CSSM_LIST_ELEMENT_WORDID;
+}
diff --git a/cdsa/cdsa_utilities/cssmlist.h b/cdsa/cdsa_utilities/cssmlist.h
new file mode 100644
index 00000000..c9884abd
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmlist.h
@@ -0,0 +1,251 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmlist - CSSM_LIST operational utilities
+//
+#ifndef _H_CSSMLIST
+#define _H_CSSMLIST
+
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <Security/walkers.h>
+
+#ifdef _CPP_CSSMLIST
+#pragma export on
+#endif
+
+namespace Security
+{
+
+class CssmList;
+class TypedList;
+
+
+//
+// A POD Wrapper for CSSM_LIST_ELEMENTs.
+// List elements are pseudo-polymorphic, so we provide ways to get and
+// set their three personalities. It's up to the caller to get this right;
+// you mustn't (for example) call the data() method on a list element that
+// is not of (element) type CSSM_LIST_ELEMENT_DATUM. To violate this rule
+// will get you an assertion (not exception).
+//
+class ListElement : public PodWrapper<ListElement, CSSM_LIST_ELEMENT> {
+public:
+    // list element chaining
+	CSSM_LIST_ELEMENT_TYPE type() const { return ElementType; }
+	ListElement * &next() { return ListElement::overlayVar(NextElement); }
+	ListElement *next() const { return ListElement::overlay(NextElement); }
+	ListElement *last();
+	
+    // CssmData personality
+	ListElement(const CssmData &data);
+    ListElement(CssmAllocator &alloc, string stringData);
+	CssmData &data();
+	const CssmData &data() const;
+	ListElement &operator = (const CssmData &data);
+	operator CssmData &() { return data(); }
+	operator string () const { return data(); }
+	bool operator == (const CssmData &other) const	{ return data() == other; }
+	bool operator != (const CssmData &other) const	{ return data() != other; }
+
+    template <class T>
+    void extract(T &destination, CSSM_RETURN error = CSSM_ERRCODE_INVALID_DATA)
+    { data().extract(destination, error); }
+	
+    // CssmList (sublist) personality
+	ListElement(const CssmList &list);
+	CssmList &list();
+	const CssmList &list() const;
+	ListElement &operator = (const CssmList &list);
+	operator CssmList &() { return list(); }
+	operator const CssmList &() const { return list(); }
+    operator TypedList &();
+    operator const TypedList &() const;
+	
+    // WORDID (number) personality
+	ListElement(CSSM_WORDID_TYPE word);
+	CSSM_WORDID_TYPE word() const;
+	ListElement &operator = (CSSM_WORDID_TYPE word);
+    operator CSSM_WORDID_TYPE () const { return word(); }
+	bool operator == (CSSM_WORDID_TYPE other) const	{ return word() == other; }
+	bool operator != (CSSM_WORDID_TYPE other) const	{ return word() != other; }
+	
+public:
+	void *operator new (size_t size, CssmAllocator &alloc)
+	{ return alloc.malloc(size); }
+	
+	void clear(CssmAllocator &alloc);		// free my contents
+};
+
+} // end namespace Security
+
+// specialize destroy() to call clear() for cleanup
+inline void destroy(ListElement *elem, CssmAllocator &alloc)
+{
+	elem->clear(alloc);
+	alloc.free(elem);
+}
+
+namespace Security
+{
+
+//
+// A POD Wrapper for CSSM_LIST.
+// CssmList does no memory allocations. Retrieval functions return pointers or
+// references into existing content, and modifiers modify in-place without any
+// attempt to release previous dynamic content. May the Leaking God be with You.
+//
+class CssmList : public PodWrapper<CssmList, CSSM_LIST> {
+public:
+	CssmList() { ListType = CSSM_LIST_TYPE_UNKNOWN; Head = Tail = NULL; }
+	CssmList(const CssmList &list)	{ *(CssmList *)this = list; }
+
+public:
+	CSSM_LIST_TYPE kind() const { return ListType; }	// type() reserved for TypedList
+	
+	ListElement &operator [] (unsigned ix) const;
+	unsigned int length() const;
+	ListElement * &first() { return ListElement::overlayVar(Head); }
+	ListElement *first() const { return ListElement::overlay(Head); }
+	ListElement *last() const { return ListElement::overlay(Tail); }
+	bool empty() const { return first() == NULL; }
+
+	CssmList &append(ListElement *elem);
+	CssmList &insert(ListElement *elem, ListElement *before);
+	CssmList &remove(ListElement *elem);
+	CssmList &operator += (ListElement *elem) { return append(elem); }
+	CssmList &operator -= (ListElement *elem) { return remove(elem); }
+    
+    // logically remove the first element (skip it)
+    void snip();
+	
+public:
+	void clear(CssmAllocator &alloc);		// free my contents
+};
+
+} // end namespace Security
+
+inline void destroy(CssmList *list, CssmAllocator &alloc)
+{
+	list->clear(alloc);
+	alloc.free(list);
+}
+
+namespace Security
+{
+
+//
+// Enhanced overlay for CssmLists whose first element is known to be a wordid.
+//
+class TypedList : public CssmList {
+public:
+    TypedList(const CSSM_LIST &list) { *(CSSM_LIST *)this = list; }
+	TypedList(CssmAllocator &alloc, CSSM_WORDID_TYPE type);
+	TypedList(CssmAllocator &alloc, CSSM_WORDID_TYPE type, ListElement *elem1);
+	TypedList(CssmAllocator &alloc, CSSM_WORDID_TYPE type, ListElement *elem1, ListElement *elem2);
+	
+	bool isProper() const;	// format check (does not throw)
+	static TypedList &overlay(CSSM_LIST &list)
+	{ return static_cast<TypedList &>(list); }
+	static const TypedList &overlay(const CSSM_LIST &list)
+	{ return static_cast<const TypedList &>(list); }
+	
+	CSSM_WORDID_TYPE type() const
+	{ assert(isProper()); return first()->word(); }
+};
+
+inline ListElement::operator TypedList &()
+{ return TypedList::overlay(operator CssmList &()); }
+
+inline ListElement::operator const TypedList &() const
+{ return TypedList::overlay(operator const CssmList &()); }
+
+
+//
+// Data walkers to parse list elements and lists.
+// @@@ Walking lists by recursing over next() is stack intensive. Do this in CssmList walker by loop?
+//
+namespace DataWalkers
+{
+
+template <class Action>
+ListElement *walk(Action &operate, ListElement * &elem)
+{
+	operate(elem);
+	switch (elem->type()) {
+	case CSSM_LIST_ELEMENT_DATUM:
+		walk(operate, elem->data());
+		break;
+	case CSSM_LIST_ELEMENT_SUBLIST:
+		walk(operate, elem->list());
+		break;
+	case CSSM_LIST_ELEMENT_WORDID:
+		break;
+	default:
+		assert(false);
+	}
+	if (elem->next())		
+		walk(operate, elem->next());
+	return elem;
+}
+
+template <class Action>
+ListElement *walk(Action &operate, CSSM_LIST_ELEMENT * &elem)
+{ walk(operate, ListElement::overlay(elem)); }
+
+template <class Action>
+void walk(Action &operate, CssmList &list)
+{
+	if (!list.empty()) {
+		walk(operate, list.first());
+		if (operate.needsRelinking)
+			list.Tail = list.first()->last();	// re-establish "tail" link
+	}
+}
+
+template <class Action>
+void walk(Action &operate, CSSM_LIST &list)
+{ walk(operate, CssmList::overlay(list)); }
+
+template <class Action>
+void walk(Action &operate, const CSSM_LIST &list)
+{ walk(operate, const_cast<CSSM_LIST &>(list)); }
+
+template <class Action>
+void walk(Action &operate, const CssmList &list)
+{ walk(operate, const_cast<CssmList &>(list)); }
+
+
+template <class Action>
+CSSM_LIST *walk(Action &operate, CSSM_LIST * &list)
+{
+	operate(list);
+	walk(operate, *list);
+	return list;
+}
+
+} // end namespace DataWalkers
+
+}; 	// end namespace Security
+
+#ifdef _CPP_CSSMLIST
+#pragma export off
+#endif
+
+#endif //_H_CSSMLIST
diff --git a/cdsa/cdsa_utilities/cssmwalkers.cpp b/cdsa/cdsa_utilities/cssmwalkers.cpp
new file mode 100644
index 00000000..7272adcd
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmwalkers.cpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmwalkers - walkers for standard CSSM datatypes and wrappers
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMWALKERS
+#endif
+#include <Security/cssmwalkers.h>
diff --git a/cdsa/cdsa_utilities/cssmwalkers.h b/cdsa/cdsa_utilities/cssmwalkers.h
new file mode 100644
index 00000000..04a09900
--- /dev/null
+++ b/cdsa/cdsa_utilities/cssmwalkers.h
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmwalkers - walkers for standard CSSM datatypes and wrappers
+//
+#ifndef _H_CSSMWALKERS
+#define _H_CSSMWALKERS
+
+#include <Security/walkers.h>
+
+#ifdef _CPP_CSSMWALKERS
+# pragma export on
+#endif
+
+
+namespace Security
+{
+
+namespace DataWalkers
+{
+
+//
+// Walk an INLINE CSSM_DATA by dealing with the data it points to.
+// Note that this is not the walker for an OUT OF LINE CSSM_DATA,
+// which is quite regular and handled below.
+//
+template <class Action>
+void walk(Action &operate, CSSM_DATA &data)
+{
+	void *p = data.Data;
+	operate(p, data.Length);
+	data.Data = reinterpret_cast<unsigned char *>(p);
+}
+
+
+//
+// Walking a C string is almost regular (the size comes from strlen()).
+//
+template <class Action>
+char *walk(Action &operate, char * &s)
+{
+    // A string's length is obtained by reading the string value.
+    // We must honor the operator's preference for not calculating length
+    // (e.g. because s won't be valid until some magic thing was done to it).
+	operate(s, operate.needsSize ? (strlen(s) + 1) : 0);
+	return s;
+}
+
+
+//
+// We "walk" an integer by simply returning it unchanged.
+// This is a degenerate special case that makes some templated
+// uses of walking easier (notably for Context use). Note that
+// the action is never called, so operations don't need to be able
+// to cope with integer (non-ref) arguments. This is strictly for
+// notational convenience.
+//
+template <class Action>
+uint32 walk(Action &, uint32 arg)
+{
+	return arg;
+}
+
+
+//
+// Flattener functions for common CSSM data types that have internal
+// structure. (The flat ones are handled by the default above.)
+//
+template <class Action>
+CssmData *walk(Action &operate, CssmData * &data)
+{
+	operate(data);
+	walk(operate, *data);
+	return data;
+}
+
+template <class Action>
+CSSM_DATA *walk(Action &operate, CSSM_DATA * &data)
+{ return walk(operate, CssmData::overlayVar(data)); }
+
+template <class Action>
+CssmKey *walk(Action &operate, CssmKey * &key)
+{
+	operate(key);
+	walk(operate, static_cast<CssmData &>(*key));
+	return key;
+}
+
+template <class Action>
+CSSM_KEY *walk(Action &operate, CSSM_KEY * &data)
+{ return walk(operate, CssmKey::overlayVar(data)); }
+
+template <class Action>
+CssmCryptoData *walk(Action &operate, CssmCryptoData * &data)
+{
+	operate(data);
+	walk(operate, data->param());
+	return data;
+}
+
+template <class Action>
+CSSM_CRYPTO_DATA *walk(Action &operate, CSSM_CRYPTO_DATA * &data)
+{ return walk(operate, CssmCryptoData::overlayVar(data)); }
+
+
+} // end namespace DataWalkers
+
+} // end namespace Security
+
+#ifdef _CPP_CSSMWALKERS
+# pragma export off
+#endif
+
+#endif //_H_CSSMWALKERS
diff --git a/cdsa/cdsa_utilities/daemon.cpp b/cdsa/cdsa_utilities/daemon.cpp
new file mode 100644
index 00000000..16023c7b
--- /dev/null
+++ b/cdsa/cdsa_utilities/daemon.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+
+//
+// demon - support code for writing UNIXoid demons
+//
+#ifdef __MWERKS__
+# define _CPP_DEMON
+#endif
+
+#include <Security/daemon.h>
+#include <Security/logging.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+namespace Security
+{
+
+namespace Daemon
+{
+
+//
+// Daemonize this process, the UNIX way.
+//
+bool incarnate()
+{
+	// fork with slight resilience
+	for (int forkTries = 1; forkTries <= 5; forkTries++) {
+		switch (fork()) {
+		case 0:			// child
+			// we are the daemon process (Har! Har!)
+			break;
+		case -1:		// parent: fork failed
+			switch (errno) {
+			case EAGAIN:
+			case ENOMEM:
+				Syslog::warning("fork() short on resources (errno=%d); retrying", errno);
+				sleep(forkTries);
+				continue;
+			default:
+				Syslog::error("fork() failed (errno=%d)", errno);
+				return false;
+			}
+		default:		// parent
+			// @@@ we could close an assurance loop here, but we don't (yet?)
+			exit(0);
+		}
+	}
+	
+	// fork succeeded; we are the child; parent is terminating
+
+	// create new session (the magic set-me-apart system call)
+	setsid();
+
+	// redirect standard channels to /dev/null
+	close(0);	// fail silently in case 0 is closed
+	if (open("/dev/null", O_RDWR, 0) == 0) {	// /dev/null could be missing, I suppose...
+		dup2(0, 1);
+		dup2(0, 2);
+	}
+	
+	// ready to roll
+	return true;
+}
+
+
+} // end namespace Daemon
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/daemon.h b/cdsa/cdsa_utilities/daemon.h
new file mode 100644
index 00000000..e418e16a
--- /dev/null
+++ b/cdsa/cdsa_utilities/daemon.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+
+//
+// demon - support code for writing UNIXoid demons
+//
+#ifndef _H_DEMON
+#define _H_DEMON
+
+#include <Security/utilities.h>
+
+#ifdef _CPP_DEMON
+#pragma export on
+#endif
+
+
+namespace Security
+{
+
+namespace Daemon
+{
+
+bool incarnate();
+
+} // end namespace Daemon
+
+} // end namespace Security
+
+#ifdef _CPP_DEMON
+#pragma export off
+#endif
+
+#endif //_H_DEMON
diff --git a/cdsa/cdsa_utilities/debugging.cpp b/cdsa/cdsa_utilities/debugging.cpp
new file mode 100644
index 00000000..a1941e3e
--- /dev/null
+++ b/cdsa/cdsa_utilities/debugging.cpp
@@ -0,0 +1,455 @@
+/*
+ * 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.
+ */
+
+
+//
+// debugging - non-trivial debugging support
+//
+#include <Security/debugsupport.h>
+#include <Security/globalizer.h>
+#include <cstdarg>
+
+#define SYSLOG_NAMES	// compile syslog name tables
+#include <syslog.h>
+
+namespace Security {
+namespace Debug {
+
+
+#if !defined(NDEBUG)
+
+
+//
+// Main debug functions (global and in-scope)
+//
+void debug(const char *scope, const char *format, ...)
+{
+#if !defined(NDEBUG_STUBS)
+	va_list args;
+	va_start(args, format);
+	Target::get().message(scope, format, args);
+	va_end(args);
+#endif
+}
+
+void vdebug(const char *scope, const char *format, va_list args)
+{
+#if !defined(NDEBUG_STUBS)
+    Target::get().message(scope, format, args);
+#endif
+}
+
+void Scope::operator () (const char *format, ...)
+{
+#if !defined(NDEBUG_STUBS)
+	va_list args;
+	va_start(args, format);
+	Target::get().message(mScope, format, args);
+	va_end(args);
+#endif
+}
+
+bool debugging(const char *scope)
+{
+#if !defined(NDEBUG_STUBS)
+	return Target::get().debugging(scope);
+#else
+    return false;
+#endif
+}
+
+
+//
+// Dump facility
+//
+bool dumping(const char *scope)
+{
+#if defined(NDEBUG_STUBS)
+    return false;
+#else
+	return Target::get().dump(scope);
+#endif
+}
+
+void dump(const char *format, ...)
+{
+#if !defined(NDEBUG_STUBS)
+	va_list args;
+	va_start(args, format);
+	Target::get().dump(format, args);
+	va_end(args);
+#endif
+}
+
+void dumpData(const void *ptr, size_t size)
+{
+#if !defined(NDEBUG_STUBS)
+	const char *addr = reinterpret_cast<const char *>(ptr);
+	const char *end = addr + size;
+	bool isText = true;
+	for (const char *p = addr; p < end; p++)
+		if (!isprint(*p)) { isText = false; break; }
+		
+	if (isText) {
+		dump("\"");
+		for (const char *p = addr; p < end; p++)
+			dump("%c", *p);
+		dump("\"");
+	} else {
+		dump("0x");
+		for (const char *p = addr; p < end; p++)
+			dump("%2.2x", *p);
+	}
+#endif //NDEBUG_STUBS
+}
+
+void dumpData(const char *title, const void *ptr, size_t size)
+{
+#if !defined(NDEBUG_STUBS)
+	dump("%s: ", title);
+	dumpData(ptr, size);
+	dump("\n");
+#endif //NDEBUG_STUBS
+}
+
+
+//
+// Target initialization
+//
+#if !defined(NDEBUG_STUBS)
+
+Target::Target() : showScope(false), showThread(false),	showPid(false), sink(NULL)
+{
+	// put into singleton slot if first
+	if (singleton == NULL)
+		singleton = this;
+}
+
+Target::~Target()
+{
+}
+
+
+//
+// The core logging function of a Target
+//
+void Target::message(const char *scope, const char *format, va_list args)
+{
+	if (logSelector(scope)) {
+		// note: messageConstructionSize is big enough for all prefixes constructed
+		char buffer[messageConstructionSize];	// building the message here
+		char *bufp = buffer;
+		if (showScope && scope) {		// add "scope "
+			if (const char *sep = strchr(scope, ',')) {
+				bufp += sprintf(bufp, "%-*s", Name::maxLength, (const char *)Name(scope, sep));
+			} else {	// single scope
+				bufp += sprintf(bufp, "%-*s", Name::maxLength, scope);
+			}
+		}
+		if (showPid) {		// add "[Pid] "
+			bufp += sprintf(bufp, "[%d] ", getpid());
+		}
+		if (showThread) {		// add "#Tthreadid "
+			*bufp++ = '#';
+			Thread::Identity::current().getIdString(bufp);
+			bufp += strlen(bufp);
+			*bufp++ = ' ';
+		}
+		vsnprintf(bufp, buffer + sizeof(buffer) - bufp, format, args);
+        for (char *p = bufp; *p; p++)
+            if (!isprint(*p))
+                *p = '?';
+		sink->put(buffer, bufp - buffer);
+	}
+}
+
+bool Target::debugging(const char *scope)
+{
+	return logSelector(scope);
+}
+
+
+//
+// The core debug-dump function of a target
+//
+void Target::dump(const char *format, va_list args)
+{
+	sink->dump(format, args);
+}
+
+bool Target::dump(const char *scope)
+{
+	return dumpSelector(scope);
+}
+
+//
+// Selector objects.
+//
+Target::Selector::Selector() : useSet(false), negate(false)
+{ }
+
+void Target::Selector::operator = (const char *scope)
+{
+	if (scope) {
+		// initial values
+		if (!strcmp(scope, "all")) {
+			useSet = false;
+			negate = true;
+		} else if (!strcmp(scope, "none")) {
+			useSet = negate = false;
+		} else {
+			useSet = true;
+			enableSet.erase(enableSet.begin(), enableSet.end());
+			if (scope[0] == '-') {
+				negate = true;
+				scope++;
+			} else
+				negate = false;
+			while (const char *sep = strchr(scope, ',')) {
+				enableSet.insert(Name(scope, sep));
+				scope = sep + 1;
+			}
+			enableSet.insert(scope);
+		}
+	} else {
+		useSet = negate = false;
+	}
+}
+
+bool Target::Selector::operator () (const char *scope) const
+{
+	// a scope of NULL is a special override; it always qualifies
+	if (scope == NULL)
+		return true;
+
+	if (useSet) {
+		while (const char *sep = strchr(scope, ',')) {
+			if (enableSet.find(Name(scope, sep)) != enableSet.end())
+				return !negate;
+			scope = sep + 1;
+		}
+		return (enableSet.find(scope) != enableSet.end()) != negate;
+	} else {
+		return negate;
+	}
+}
+
+
+//
+// Establish Target state from the environment
+//
+void Target::setFromEnvironment()
+{
+	// set scopes
+	logSelector = getenv("DEBUGSCOPE");
+	dumpSelector = getenv("DEBUGDUMP");
+	
+	//
+	// Set and configure destination. Currently available:
+	//	/some/where -> that file
+	//	LOG_SOMETHING -> syslog facility
+	//	>&number -> that (already) open file descriptor
+	//	anything else -> try as a filename sight unseen
+	//	DEBUGDEST not set -> stderr
+	//	anything in error -> stderr (with an error message on it)
+	//
+	if (const char *dest = getenv("DEBUGDEST")) {
+		if (dest[0] == '/') {	// full pathname, write to file
+			to(dest);
+		} else if (!strncmp(dest, "LOG_", 4)) {	// syslog
+			int facility = LOG_DAEMON;
+			for (CODE *cp = facilitynames; cp->c_name; cp++)
+				if (!strcmp(dest, cp->c_name))
+					facility = cp->c_val;
+			to(facility | LOG_DEBUG);
+		} else if (!strncmp(dest, ">&", 2)) {	// to file descriptor
+			int fd = atoi(dest+2);
+			if (FILE *f = fdopen(fd, "a")) {
+				to(f);
+			} else {
+				to(stderr);
+				::debug(NULL, "cannot log to fd[%d]: %s", fd, strerror(errno));
+			}
+		} else {	// if everything else fails, write a file
+			to(dest);
+		}
+	} else {		// default destination is stderr
+		to(stderr);
+	}
+	configure();
+}
+
+
+void Target::configure()
+{
+	configure(getenv("DEBUGOPTIONS"));
+}
+
+void Target::configure(const char *config)
+{
+	// configure global options
+	showScope = config && strstr(config, "scope");
+	showThread = config && strstr(config, "thread");
+	showPid = config && strstr(config, "pid");
+
+	// configure sink
+	if (sink)
+		sink->configure(config);
+}
+
+
+//
+// Explicit destination assignments
+//
+void Target::to(Sink *s)
+{		
+	delete sink;	
+	sink = s;
+}
+
+void Target::to(FILE *file)
+{
+	to(new FileSink(file));
+}
+
+void Target::to(const char *filename)
+{
+	if (FILE *f = fopen(filename, "a")) {
+		to(new FileSink(f));
+	} else {
+		to(stderr);
+		::debug(NULL, "cannot debug to \"%s\": %s", filename, strerror(errno));
+	}
+}
+
+void Target::to(int syslogPriority)
+{
+	to(new SyslogSink(syslogPriority));
+}
+
+
+//
+// Making and retrieving the default singleton
+//
+Target *Target::singleton;
+
+Target &Target::get()
+{
+	if (singleton == NULL) {
+		Target *t = new Target;
+		t->setFromEnvironment();
+	}
+	return *singleton;
+}
+
+
+//
+// Standard sink implementations
+//
+Target::Sink::~Sink()
+{ }
+
+void Target::Sink::dump(const char *, va_list)
+{ }
+
+void Target::Sink::configure(const char *)
+{ }
+
+
+//
+// File sinks (write to file via stdio)
+//
+void FileSink::put(const char *buffer, unsigned int)
+{
+	StLock<Mutex> locker(lock, false);
+	if (lockIO)
+		locker.lock();
+	if (addDate) {
+		time_t now = time(NULL);
+		char *date = ctime(&now);
+		date[19] = '\0';
+		fprintf(file, "%s ", date + 4);	// Nov 24 18:22:48
+	}
+	fputs(buffer, file);
+	putc('\n', file);
+}
+
+void FileSink::dump(const char *format, va_list args)
+{
+	StLock<Mutex> locker(lock, false);
+	if (lockIO)
+		locker.lock();
+	vfprintf(file, format, args);
+}
+
+void FileSink::configure(const char *options)
+{
+	if (options == NULL || !strstr(options, "noflush"))
+		setlinebuf(file);
+	if (options) {
+		addDate = strstr(options, "date");
+		lockIO = !strstr(options, "nolock");
+	}
+}
+
+
+//
+// Syslog sinks (write to syslog)
+//
+void SyslogSink::put(const char *buffer, unsigned int)
+{
+	syslog(priority, "%s", buffer);
+}
+
+void SyslogSink::dump(const char *format, va_list args)
+{
+	// add to dump buffer
+	vsnprintf(dumpPtr, dumpBuffer + dumpBufferSize - dumpPtr, format, args);
+	
+	// take off full lines and submit
+	char *p = dumpBase;
+	while (char *q = strchr(p, '\n')) {
+		*q++ = '\0';	// terminate/break
+		syslog(priority, " @@ %s", p);
+		p = q;
+	}
+	
+	if (*p) {	// left-over unterminated line segment in buffer
+		dumpPtr = p + strlen(p);
+		if ((dumpBase = p) > dumpBuffer + dumpBufferSize / 2) {
+			// shift buffer down to make room
+			memmove(dumpBuffer, dumpBase, dumpPtr - dumpBase);
+			dumpPtr -= (dumpBase - dumpBuffer);
+			dumpBase = dumpBuffer;
+		}
+	} else {	// buffer is empty; reset to start
+		dumpBase = dumpPtr = dumpBuffer;
+	}
+}
+
+void SyslogSink::configure(const char *options)
+{
+}
+
+#endif //NDEBUG_STUBS
+
+#endif // NDEBUG
+
+
+} // end namespace Debug
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/debugging.h b/cdsa/cdsa_utilities/debugging.h
new file mode 100644
index 00000000..d6b283a3
--- /dev/null
+++ b/cdsa/cdsa_utilities/debugging.h
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+
+//
+// debugging - non-trivial debug support
+//
+#ifndef _H_DEBUGGING
+#define _H_DEBUGGING
+
+#include <Security/utilities.h>
+#include <cstdarg>
+
+#ifdef _CPP_DEBUGGING
+#pragma export on
+#endif
+
+namespace Security {
+namespace Debug {
+
+
+#if !defined(NDEBUG)
+
+
+// Debug to standard target
+void debug(const char *scope, const char *format, ...) __attribute__((format(printf,2,3)));
+void vdebug(const char *scope, const char *format, va_list args);
+bool debugging(const char *scope);
+
+// Stream dumping to standard target
+bool dumping(const char *scope);
+void dump(const char *format, ...) __attribute((format(printf,1,2)));
+void dumpData(const void *data, size_t length);
+void dumpData(const char *title, const void *data, size_t length);
+template <class Data> inline void dumpData(const Data &obj)
+{ dumpData(obj.data(), obj.length()); }
+template <class Data> inline void dumpData(const char *title, const Data &obj) 
+{ dumpData(title, obj.data(), obj.length()); }
+
+#if defined(DEBUGDUMP)
+# define IFDUMP(code)				code
+# define IFDUMPING(scope,code)		if (Debug::dumping(scope)) code; else /* no */
+#else
+# define IFDUMP(code)				/* no-op */
+# define IFDUMPING(scope,code)		/* no-op */
+#endif
+
+
+//
+// A (prepared) debug scope object.
+//
+class Scope {
+public:
+	Scope(const char *string)	{ mScope = string; }
+	
+	void operator () (const char *format, ...);
+	
+private:
+	const char *mScope;
+};
+
+
+#else // NDEBUG
+
+
+//
+// If NDEBUG is defined, we try to make all debugging functions weightless
+//
+inline void debug(const char *, const char *, ...) { }
+inline void vdebug(const char *, const char *, va_list) { }
+inline bool debugging(const char *) { return false; }
+
+class Scope {
+public:
+	Scope(const char *)		{ }
+	void operator () (const char *, ...)	{ }
+};
+
+inline bool dumping(const char *) { return false; }
+inline void dump(const char *, ...) { }
+inline void dumpData(const void *, size_t) { }
+void dumpData(const char *, const void *, size_t);
+template <class Data> inline void dumpData(const Data &) { }
+template <class Data> inline void dumpData(const char *, const Data &) { }
+
+// debugdumping is forced off
+#if defined(DEBUGDUMP)
+# undef DEBUGDUMP
+#endif
+# define IFDUMP(code)				/* no-op */
+# define IFDUMPING(scope,code)		/* no-op */
+
+#endif // NDEBUG
+
+
+} // end namespace Debug
+
+} // end namespace Security
+
+// We intentionally leak a few functions into the global namespace
+using Security::Debug::debug;
+
+
+#ifdef _CPP_DEBUGGING
+#pragma export off
+#endif
+
+#endif //_H_DEBUGGING
diff --git a/cdsa/cdsa_utilities/debugsupport.h b/cdsa/cdsa_utilities/debugsupport.h
new file mode 100644
index 00000000..94d91789
--- /dev/null
+++ b/cdsa/cdsa_utilities/debugsupport.h
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+
+//
+// debugsupport - support interface for making and managing debugger objects.
+//
+// This header is not needed for logging debug messages.
+//
+#ifndef _H_DEBUGSUPPORT
+#define _H_DEBUGSUPPORT
+
+//
+// Generate stub-code support if NDEBUG (but not CLEAN_NDEBUG) is set, to support
+// client code that may have been generated with debug enabled. You don't actually
+// get *real* debug logging, of course, just cheap dummy stubs to keep the linker happy.
+//
+#if defined(NDEBUG) && !defined(CLEAN_NDEBUG)
+# undef NDEBUG
+# define NDEBUG_STUBS
+#endif
+
+#include <Security/debugging.h>
+#include <Security/threading.h>
+#include <cstdarg>
+#include <set>
+
+namespace Security {
+namespace Debug {
+
+
+#if !defined(NDEBUG)
+
+
+//
+// Debug scope names - short strings with value semantics.
+// We don't use STL strings because of overhead.
+//
+class Name {
+public:
+	static const int maxLength = 12;
+
+	Name(const char *s)
+	{ strncpy(mName, s, maxLength-1); mName[maxLength-1] = '\0'; }
+	
+	Name(const char *start, const char *end)
+	{
+		int length = end - start; if (length >= maxLength) length = maxLength - 1;
+		memcpy(mName, start, length); memset(mName + length, 0, maxLength - length);
+	}
+	
+	operator const char *() const	{ return mName; }
+	
+	bool operator < (const Name &other) const
+	{ return memcmp(mName, other.mName, maxLength) < 0; }
+	
+	bool operator == (const Name &other) const
+	{ return memcmp(mName, other.mName, maxLength) == 0; }
+
+private:
+	char mName[maxLength];		// null terminated for easy printing
+};
+
+
+//
+// A debugging Target. This is an object that receives debugging requests.
+// You can have many, but one default one is always provided.
+//
+class Target {
+public:
+	Target();
+	virtual ~Target();
+	
+	// get default (singleton) Target
+	static Target &get();
+	
+	void setFromEnvironment();
+	
+public:
+	class Sink {
+	public:
+		virtual ~Sink();
+		virtual void put(const char *buffer, unsigned int length) = 0;
+		virtual void dump(const char *format, va_list args);
+		virtual void configure(const char *argument);
+	};
+	
+	void to(Sink *sink);
+	void to(const char *filename);
+	void to(int syslogPriority);
+	void to(FILE *openFile);
+	
+	void configure();						// from DEBUGOPTIONS
+	void configure(const char *options);	// from explicit string
+	
+public:
+	void message(const char *scope, const char *format, va_list args);
+	bool debugging(const char *scope);
+	void dump(const char *format, va_list args);
+	bool dump(const char *scope);
+	
+protected:
+	class Selector {
+	public:
+		Selector();
+		void operator = (const char *config);
+		
+		bool operator () (const char *name) const;
+
+	private:
+		bool useSet;				// use contents of enableSet
+		bool negate;				// negate meaning of enableSet
+		set<Name> enableSet;		// set of names
+	};
+	
+protected:
+	static const size_t messageConstructionSize = 512;	// size of construction buffer
+
+	Selector logSelector;			// selector for logging
+	Selector dumpSelector;			// selector for dumping
+	
+	// output option state (from last configure call)
+	bool showScope;					// include scope in output lines
+	bool showThread;				// include #Threadid in output lines
+	bool showPid;					// include [Pid] in output lines
+	size_t dumpLimit;				// max. # of bytes dumped by dumpData & friends
+
+	// current output support
+	Sink *sink;
+	
+	// the default Target
+	static Target *singleton;
+};
+
+
+//
+// Standard Target::Sinks
+//
+class FileSink : public Target::Sink {
+public:
+	FileSink(FILE *f) : file(f), addDate(false), lockIO(true), lock(false) { }
+	void put(const char *, unsigned int);
+	void dump(const char *format, va_list args);
+	void configure(const char *);
+	
+private:
+	FILE *file;
+	bool addDate;
+	bool lockIO;
+	Mutex lock;
+};
+
+class SyslogSink : public Target::Sink {
+public:
+	SyslogSink(int pri) : priority(pri), dumpBase(dumpBuffer), dumpPtr(dumpBuffer) { }
+	void put(const char *, unsigned int);
+	void dump(const char *format, va_list args);
+	void configure(const char *);
+	
+private:
+	int priority;
+	
+	static const size_t dumpBufferSize = 1024;
+	char dumpBuffer[dumpBufferSize];
+	char *dumpBase, *dumpPtr;
+};
+
+
+#else // NDEBUG
+
+//
+// Note that we don't scaffold up the entire Target hierarchy for NDEBUG.
+// If you directly manipulate debug Targets, Names, or Sinks, you need to
+// conditionalize the code based on NDEBUG.
+//
+
+#endif // NDEBUG
+
+
+} // end namespace Debug
+
+} // end namespace Security
+
+#ifdef _CPP_DEBUGGING
+#pragma export off
+#endif
+
+#endif //_H_DEBUGSUPPORT
diff --git a/cdsa/cdsa_utilities/devrandom.cpp b/cdsa/cdsa_utilities/devrandom.cpp
new file mode 100644
index 00000000..574a7142
--- /dev/null
+++ b/cdsa/cdsa_utilities/devrandom.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+//
+// devrandom - RNG operations based on /dev/random
+//
+#include <Security/devrandom.h>
+
+
+namespace Security {
+
+
+//
+// DevRandomGenerator objects immediately open their file descriptors
+//
+DevRandomGenerator::DevRandomGenerator(bool writable)
+{
+    mDevRandom.open("/dev/random", writable ? O_RDWR : O_RDONLY);
+}
+
+
+//
+// Standard generate (directly from /dev/random)
+//
+void DevRandomGenerator::random(void *data, size_t length)
+{
+    mDevRandom.read(data, length);
+}
+
+
+//
+// If you opened for writing, you add entropy to the global pool here
+//
+void DevRandomGenerator::addEntropy(const void *data, size_t length)
+{
+    mDevRandom.write(data, length);
+}
+
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/devrandom.h b/cdsa/cdsa_utilities/devrandom.h
new file mode 100644
index 00000000..6819a885
--- /dev/null
+++ b/cdsa/cdsa_utilities/devrandom.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+
+//
+// devrandom - RNG operations based on /dev/random
+//
+#ifndef _H_DEVRANDOM
+#define _H_DEVRANDOM
+
+#include <Security/utilities.h>
+#include <Security/unix++.h>
+
+
+namespace Security {
+
+
+//
+// This RNG uses /dev/random.
+// It is not repeatable. AddEntropy() contributes random entropy to a global pool (only).
+//
+class DevRandomGenerator {
+public:
+    DevRandomGenerator(bool writable = false);
+    
+    void random(void *data, size_t length);
+    void addEntropy(const void *data, size_t length);
+
+private:
+    UnixPlusPlus::FileDesc mDevRandom;
+};
+
+
+}; 	// end namespace Security
+
+
+#endif //_H_DEVRANDOM
diff --git a/cdsa/cdsa_utilities/fdsel.cpp b/cdsa/cdsa_utilities/fdsel.cpp
new file mode 100644
index 00000000..f04507d1
--- /dev/null
+++ b/cdsa/cdsa_utilities/fdsel.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+
+//
+// fdsel - select-style file descriptor set management
+//
+#include "fdsel.h"
+
+
+namespace Security {
+namespace UnixPlusPlus {
+
+
+//
+// Throw the bitvectors away on destruction
+// 
+FDSet::~FDSet()
+{
+    delete mBits;
+    delete mUseBits;
+}
+
+
+//
+// Given the old and desired new sizes (in fd_mask words), grow
+// the bitvectors. New storage is zero filled. Note that we preserve
+// the mUseBits vector, so this is safe to do during a post-select scan.
+// This function cannot shrink the bitmaps.
+//
+void FDSet::grow(int oldWords, int newWords)
+{
+    assert(oldWords < newWords);
+    grow(mBits, oldWords, newWords);
+    grow(mUseBits, oldWords, newWords);
+}
+
+void FDSet::grow(fd_mask * &bits, int oldWords, int newWords)
+{
+    fd_mask *newBits = new fd_mask[newWords];
+    memcpy(newBits, bits, oldWords * sizeof(fd_mask));
+    memset(newBits + oldWords, 0, (newWords - oldWords) * sizeof(fd_mask));
+    delete [] bits;
+    bits = newBits;
+}
+
+
+//
+// Set or clear a single bit in the map.
+// No check for overflow is perfomed.
+//
+void FDSet::set(int fd, bool on)
+{
+    if (on) {
+        FD_SET(fd, (fd_set *)mBits);
+    } else {
+        FD_CLR(fd, (fd_set *)mBits);
+        FD_CLR(fd, (fd_set *)mUseBits);
+    }
+}
+
+
+//
+// Copy only the first words fd_mask words from mBits to mUseBits
+// and return that for select(2) use.
+//
+fd_set *FDSet::make(int words)
+{
+    //@@@ if empty -> return NULL (but check caller for [] use)
+    memcpy(mUseBits, mBits, words * sizeof(fd_mask));
+    return (fd_set *)mUseBits;
+}
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/fdsel.h b/cdsa/cdsa_utilities/fdsel.h
new file mode 100644
index 00000000..d9427aee
--- /dev/null
+++ b/cdsa/cdsa_utilities/fdsel.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+
+//
+// fdsel - select-style file descriptor set management
+//
+#ifndef _H_FDSEL
+#define _H_FDSEL
+
+#include <Security/utilities.h>
+#include <sys/types.h>
+#include <Security/debugging.h>
+
+
+namespace Security {
+namespace UnixPlusPlus {
+
+
+//
+// An FDSet object maintains a single select(2) compatible bitmap.
+// Size is implicitly kept by the caller (who needs to call grow() as
+// needed, starting at zero). As long as this is done correctly, we are
+// not bound by the FD_SETSIZE limit.
+// An FDSet can self-copy for select(2) use; after that, the [] operator
+// investigates the copy.
+//
+// Why are we using the FD_* macros even though we know these
+// are fd_mask arrays? Some implementations use optimized assembly
+// for these operations, and we want to pick those up.
+//
+// This whole mess is completely UNIX specific. If your system has
+// the poll(2) system call, ditch this and use it.
+//
+class FDSet {
+public:
+    FDSet() : mBits(NULL), mUseBits(NULL) { }
+    ~FDSet();
+
+    void grow(int oldWords, int newWords);
+    void set(int fd, bool on);
+    
+    fd_set *make(int words);
+    bool operator [] (int fd) const	{ return FD_ISSET(fd, (fd_set *)mUseBits); }
+    
+    inline static int words(int fd)	{ return (fd - 1) / NFDBITS + 1; }
+
+private:
+    fd_mask *mBits;					// base bits
+    fd_mask *mUseBits;				// mutable copy for select(2)
+    
+    void grow(fd_mask * &bits, int oldWords, int newWords);
+};
+
+
+}	// end namespace UnixPlusPlus
+}	// end namespace Security
+
+
+#endif //_H_FDSEL
diff --git a/cdsa/cdsa_utilities/generator.mk b/cdsa/cdsa_utilities/generator.mk
new file mode 100644
index 00000000..2e701383
--- /dev/null
+++ b/cdsa/cdsa_utilities/generator.mk
@@ -0,0 +1,26 @@
+# Makefile for generated files.
+
+PERL=/usr/bin/perl
+
+CDSA_HEADERS_DIR = Headers/cdsa
+CDSA_UTILITIES_DIR = Sources/cdsa_utilities
+
+GEN_ERRORCODES = $(CDSA_UTILITIES_DIR)/generator.pl
+ERRORCODES_GEN = $(patsubst %,$(CDSA_UTILITIES_DIR)/%,errorcodes.gen)
+ERRORCODES_DEPENDS = $(GEN_ERRORCODES)\
+					 $(patsubst %,$(CDSA_HEADERS_DIR)/%,cssmerr.h)
+
+build: $(ERRORCODES_GEN)
+
+clean:
+	rm -f $(ERRORCODES_GEN)
+
+debug: build
+
+profile: build
+
+.PHONY: build clean debug profile
+
+$(ERRORCODES_GEN): $(ERRORCODE_DEPENDS)
+	(cd $(CDSA_UTILITIES_DIR);\
+	  $(PERL) ./generator.pl ../../$(CDSA_HEADERS_DIR) .)
diff --git a/cdsa/cdsa_utilities/generator.pl b/cdsa/cdsa_utilities/generator.pl
new file mode 100644
index 00000000..511c4df3
--- /dev/null
+++ b/cdsa/cdsa_utilities/generator.pl
@@ -0,0 +1,84 @@
+#!/usr/bin/perl
+#
+# generator.pl - derive various and sundry C++ code from the CDSA header files
+#
+# Usage:
+#	perl generator.pl input-directory output-directory
+#
+# Perry The Cynic, Fall 1999.
+#
+$ERR_H="cssmerr.h";
+$APPLE_ERR_H="cssmapple.h";
+
+$SOURCEDIR=$ARGV[0];						# directory with inputs
+
+(${D}) = $SOURCEDIR =~ m@([/:])@;			# guess directory delimiter
+sub macintosh() { return ${D} eq ':'; }
+
+if( macintosh() ){
+$TARGETDIR=$ARGV[2];						# directory for outputs
+}
+ else{
+$TARGETDIR=$ARGV[1];
+}
+
+$TABLES="$TARGETDIR${D}errorcodes.gen";		# error name tables
+
+$tabs = "\t\t\t";	# argument indentation (noncritical)
+$warning = "This file was automatically generated. Do not edit on penalty of futility!";
+
+
+#
+# Parse CSSM error header and build table of all named codes
+#
+open(ERR, "$SOURCEDIR${D}$ERR_H") or die "Cannot open $ERR_H: $^E";
+open(APPLE_ERR, "$SOURCEDIR${D}$APPLE_ERR_H") or die "Cannot open $APPLE_ERR_H: $^E";
+$/=undef;	# big gulp mode
+$errors = <ERR> . <APPLE_ERR>;
+$errors =~ tr/\012/\015/ if macintosh;
+close(ERR); close(APPLE_ERR);
+
+@fullErrors = $errors =~ /^\s+CSSMERR_([A-Z_]+)/gm;
+@convertibles = $errors =~ /^\s+CSSM_ERRCODE_([A-Z_]+)\s*=\s*([0-9xXA-Fa-f]+)/gm;
+
+while ($name = shift @convertibles) {
+  $value = shift @convertibles or die;
+  $convErrors[hex $value] = $name;
+};
+
+#
+# Now we will generate the error name tables.
+#
+open(OUT, ">$TABLES") or die "Cannot write $TABLES: $^E";
+select OUT;
+
+print <<HDR;
+//
+// CSSM error code tables.
+// $warning
+//
+static const Mapping errorList[] = {
+HDR
+foreach $name (@fullErrors) {
+  print "  { CSSMERR_$name, \"$name\" },\n";
+};
+print <<MID;
+};
+
+static const char * const convErrorList [] = {
+MID
+for ($n = 0; $n <= $#convErrors; $n++) {
+  if ($name = $convErrors[$n]) {
+    print "  \"$name\",\n";
+  } else {
+    print "  NULL,\n";
+  };
+};
+print "};\n";
+
+close(OUT);
+select(STDOUT);
+
+$nFull = $#fullErrors + 1;
+$nConv = $#convertibles + 1;
+print "$nFull errors available to error translation functions.\n";
diff --git a/cdsa/cdsa_utilities/globalizer.cpp b/cdsa/cdsa_utilities/globalizer.cpp
new file mode 100644
index 00000000..0f7fa629
--- /dev/null
+++ b/cdsa/cdsa_utilities/globalizer.cpp
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+
+//
+// globalizer - multiscope globalization services.
+//
+// This is a tentative, partial implementation.
+// Status:
+//	module scope: constructs, optional cleanup
+//	thread scope: constructs, optional cleanup
+//	process scope: not implemented (obsolete implementation, unused)
+//	system scope: not implemented (probably never will)
+//
+// @@@ Assumption: {bool,T*} atomic unless PTHREAD_STRICT
+//
+#ifdef __MWERKS__
+#define _CPP_GLOBALIZER
+#endif
+#include <Security/globalizer.h>
+#include <cstdlib>
+
+
+//
+// The Error class thrown if Nexus operations fail
+//
+GlobalNexus::Error::~Error()
+{
+}
+
+
+//
+// The long (and possibly contentious) path of ModuleNexus()
+//
+// Briefly, the trick here is to go through a three-stage sequence
+// to lazily construct a unique singleton object, no matter how many
+// threads all of a sudden decide they need it.
+// State sequence:
+// State 0: pointer == 0, not initialized, idle
+// State 1: pointer == mutexp | 0x1, where mutexp points to a Mutex
+//  used to serialize construction of the singleton object
+// State 2: pointer == &singleton, and we're done
+//
+// TAKE NOTE:
+// This code is optimized with a particular issue in mind: when placed
+// into static storage (as ModuleNexi are wont to), it should not require
+// dynamic initialization. This is important because our code is, in effect,
+// linked into just about every program in the system. The price we pay
+// for this coolness is
+//  (a) This won't work *except* in static storage (not on stack or heap)
+//  (b) We slightly fracture portability (see below)
+// This has been considered Worth It, at least for now. Before you throw
+// up and throw this code out, please try to figure out whether you know
+// the Whole Story. Thank you.
+//
+// WARNING:
+// This code makes the following non-portable assumptions:
+//  (a) NULL == 0 (binary representation of NULL pointer is zero value)
+//	Pointers acquired from new have at least their LSB zero (are at
+//  (b) least two-byte aligned).
+// It seems like it's been a while since anyone made a machine/runtime that
+// violated either of those. But you have been warned.
+//
+#if defined(_HAVE_ATOMIC_OPERATIONS)
+
+AtomicWord ModuleNexusCommon::create(void *(*make)())
+{
+    sync++;		// keep mutex alive if needed
+  retry:
+    AtomicWord initialPointer = pointer;	// latch pointer
+    if (!initialPointer || (initialPointer & 0x1)) {
+        Mutex *mutex;
+        if (initialPointer == 0) {
+            mutex = new Mutex(false);	// don't bother debugging this one
+            mutex->lock();
+            if (atomicStore(pointer, AtomicWord(mutex) | 0x1, 0) != 0) {
+                // somebody beat us to the lead - back off
+                mutex->unlock();
+                delete mutex;
+                goto retry;
+            }
+            // we have the ball
+            try {
+                void *singleton = make();
+                pointer = AtomicWord(singleton);
+                // we need a write barrier here, but the mutex->unlock below provides it for free
+                debug("nexus", "ModuleNexus %p constructed object 0x%x", this, pointer);
+            } catch (...) {
+				debug("nexus", "ModuleNexus %p construction failed", this);
+                mutex->unlock();
+                sync--;
+                //@@@ set up for retry here?
+                throw;
+            }
+        } else {
+            mutex = reinterpret_cast<Mutex *>(pointer & ~0x1);
+            mutex->lock();	// we'll wait here
+        }
+        mutex->unlock();
+        //@@@ retry if not resolved -- or fail here (with "object can't be built")
+        if (--sync == 0)
+            delete mutex;
+    }
+    return pointer;
+}
+
+#endif //_HAVE_ATOMIC_OPERATIONS
+
+
+//
+// Process nexus operation
+//
+ProcessNexusBase::ProcessNexusBase(const char *identifier)
+{
+	const char *env = getenv(identifier);
+	if (env == NULL) {	// perhaps we're first...
+		auto_ptr<Store> store(new Store);
+		char form[2*sizeof(Store *) + 2];
+		sprintf(form, "*%p", &store);
+		setenv(identifier, form, 0);	// do NOT overwrite...
+		env = getenv(identifier);		// ... and refetch to resolve races
+		if (sscanf(env, "*%p", &mStore) != 1)
+			CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR /*"environment communication failed" */);
+		if (mStore == store.get())		// we won the race...
+			store.release();			// ... so keep the store
+	} else
+		if (sscanf(env, "*%p", &mStore) != 1)
+			CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR /*"environment communication failed"*/);
+}
diff --git a/cdsa/cdsa_utilities/globalizer.h b/cdsa/cdsa_utilities/globalizer.h
new file mode 100644
index 00000000..a675d530
--- /dev/null
+++ b/cdsa/cdsa_utilities/globalizer.h
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * globalizer - multiscope globalization services
+ */
+#ifndef _H_GLOBALIZER
+#define _H_GLOBALIZER
+
+#include <Security/threading.h>
+#include <memory>
+
+#ifdef _CPP_GLOBALIZER
+# pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// GlobalNexus is the common superclass of all globality scopes.
+// A Nexus is an *access point* to the *single* object of a given
+// type in the Nexus's particular scope.
+//
+class GlobalNexus {
+public:
+    class Error : public exception {
+    public:
+		virtual ~Error();
+        const char * const message;
+        Error(const char *m) : message(m) { }
+        const char *what() const { return message; }
+    };
+};
+
+
+//
+// A module-scope nexus is tied to the linker Nexus object itself.
+// Its scope is all code accessing that particular Nexus object
+// from within a process. Any number of ModuleNexus objects can
+// exist, and each implements a different scope.
+//
+// IMPORTANT notes on this class can be found in globalizer.cpp.
+// DO NOT change anything here before carefully reading them.
+//
+#if defined(_HAVE_ATOMIC_OPERATIONS)
+
+class ModuleNexusCommon : public GlobalNexus {
+protected:
+    AtomicWord create(void *(*make)());
+    
+protected:
+    // both of these will be statically initialized to zero
+    AtomicWord pointer;
+    StaticAtomicCounter<uint32> sync;
+};
+
+template <class Type>
+class ModuleNexus : public ModuleNexusCommon {
+public:
+    Type &operator () ()
+    {
+        AtomicWord p = pointer;	// latch pointer
+        return *reinterpret_cast<Type *>((p && !(p & 0x1)) ? p : create(make));
+    }
+    
+    void reset()
+    {
+        if (pointer && !(pointer & 0x1)) {
+            delete reinterpret_cast<Type *>(pointer);
+            pointer = 0;
+        }
+    }
+    
+private:
+    static void *make() { return new Type; }
+};
+
+#else	// !_HAVE_ATOMIC_OPERATIONS
+
+template <class Type>
+class ModuleNexus : public GlobalNexus {
+public:
+    Type &operator () ()
+    {
+#if !defined(PTHREAD_STRICT)
+        // not strictly kosher POSIX, but pointers are usually atomic types
+        if (mSingleton)
+            return *mSingleton;
+#endif
+        StLock<Mutex> _(mLock);
+        if (mSingleton == NULL)
+            mSingleton = new Type;
+        return *mSingleton;
+    }
+    
+    void reset()		{ delete mSingleton; mSingleton = NULL; }
+    
+private:
+    Type *mSingleton;		// pointer to singleton static initialized to NULL
+    Mutex mLock;			// construction lock
+};
+
+#endif // _HAVE_ATOMIC_OPERATIONS
+
+template <class Type>
+class CleanModuleNexus : public ModuleNexus<Type> {
+public:
+    ~CleanModuleNexus()
+    {
+        debug("nexus", "ModuleNexus %p destroyed object 0x%x", this, pointer);
+        delete reinterpret_cast<Type *>(pointer);
+    }
+};
+
+
+//
+// A thread-scope nexus is tied to a particular native thread AND
+// a particular nexus object. Its scope is all code in any one thread
+// that access that particular Nexus object. Any number of Nexus objects
+// can exist, and each implements a different scope for each thread.
+// NOTE: ThreadNexus is dynamically constructed. If you want static,
+// zero-initialization ThreadNexi, put them inside a ModuleNexus.
+//
+#if _USE_THREADS == _USE_PTHREADS
+
+template <class Type>
+class ThreadNexus : public GlobalNexus {
+public:
+    ThreadNexus() : mSlot(true) { }
+    Type &operator () ()
+    {
+        // no thread contention here!
+        if (Type *p = mSlot)
+            return *p;
+        mSlot = new Type;
+        return *mSlot;
+    }
+
+private:
+    PerThreadPointer<Type> mSlot;
+};
+
+#endif //_USE_PTHREADS
+
+
+//
+// A ProcessNexus is global within a single process, regardless of
+// load module boundaries. You can have any number of ProcessNexus
+// scopes, each identified by a C string (compared by value, not pointer).
+//
+class ProcessNexusBase : public GlobalNexus {
+protected:
+	ProcessNexusBase(const char *identifier);
+
+	struct Store {
+		void *mObject;
+		Mutex mLock;
+	};
+	Store *mStore;
+};
+
+template <class Type>
+class ProcessNexus : public ProcessNexusBase {
+public:
+	ProcessNexus(const char *identifier) : ProcessNexusBase(identifier) { }
+	Type &operator () ();
+	
+private:
+	Type *mObject;
+};
+
+template <class Type>
+Type &ProcessNexus<Type>::operator () ()
+{
+#if !defined(PTHREAD_STRICT)
+    // not strictly kosher POSIX, but pointers are usually atomic types
+    if (mStore->mObject)
+        return *reinterpret_cast<Type *>(mStore->mObject);
+#endif
+    StLock<Mutex> _(mStore->mLock);
+    if (mStore->mObject == NULL)
+        mStore->mObject = new Type;
+    return *reinterpret_cast<Type *>(mStore->mObject);
+};
+
+
+} // end namespace Security
+
+#endif //_H_GLOBALIZER
diff --git a/cdsa/cdsa_utilities/guids.cpp b/cdsa/cdsa_utilities/guids.cpp
new file mode 100644
index 00000000..d4b1a91f
--- /dev/null
+++ b/cdsa/cdsa_utilities/guids.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+
+#include <Security/cssmapple.h>
+
+// {87191ca0-0fc9-11d4-849a-000502b52122}
+const CSSM_GUID gGuidCssm =
+{ 0x87191ca0, 0x0fc9, 0x11d4, { 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22 } };
+
+// {87191ca1-0fc9-11d4-849a-000502b52122}
+const CSSM_GUID gGuidAppleFileDL =
+{ 0x87191ca1, 0x0fc9, 0x11d4, { 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22 } };
+
+// {87191ca2-0fc9-11d4-849a-000502b52122}
+const CSSM_GUID gGuidAppleCSP =
+{ 0x87191ca2, 0x0fc9, 0x11d4, { 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22 } };
+
+// {87191ca3-0fc9-11d4-849a-000502b52122}
+const CSSM_GUID gGuidAppleCSPDL =
+{ 0x87191ca3, 0x0fc9, 0x11d4, { 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22 } };
+
+// {87191ca4-0fc9-11d4-849a-000502b52122}
+const CSSM_GUID gGuidAppleX509CL =
+{ 0x87191ca4, 0x0fc9, 0x11d4, { 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22 } };
+
+// {87191ca5-0fc9-11d4-849a-000502b52122}
+const CSSM_GUID gGuidAppleX509TP =
+{ 0x87191ca5, 0x0fc9, 0x11d4, { 0x84, 0x9a, 0x00, 0x05, 0x02, 0xb5, 0x21, 0x22 } };
diff --git a/cdsa/cdsa_utilities/handleobject.cpp b/cdsa/cdsa_utilities/handleobject.cpp
new file mode 100644
index 00000000..58b44a8d
--- /dev/null
+++ b/cdsa/cdsa_utilities/handleobject.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+
+//
+// handleobject - give an object a process-global unique handle
+//
+#ifdef __MWERKS__
+#define _CPP_HANDLEOBJECT
+#endif
+#include <Security/handleobject.h>
+
+
+//
+// Static members of HandleObject
+//
+ModuleNexus<HandleObject::State> HandleObject::state;
+
+
+//
+// Bring the State constructor out of line
+//
+HandleObject::State::State()
+{ }
+
+
+//
+// Assign a HandleObject's (new) Handle.
+//
+void HandleObject::State::make(HandleObject *obj)
+{
+    StLock<Mutex> _(mLock);
+	for (;;) {
+		Handle handle = reinterpret_cast<uint32>(obj) ^ (++sequence << 19);
+		if (handleMap[handle] == NULL) {
+			debug("handleobj", "create 0x%lx for %p", handle, obj);
+			obj->setHandle(handle);
+			handleMap[handle] = obj;
+			return;
+		}
+	}
+}
+
+
+//
+// Clean up a HandleObject that dies.
+// Note that an object MAY clear its handle before (in which case we do nothing).
+// In particular, killHandle will do this.
+//
+void HandleObject::State::erase(HandleObject *obj)
+{
+    StLock<Mutex> _(mLock);
+    if (obj->validHandle())
+        handleMap.erase(obj->handle());
+}
+
+
+//
+// This is the main locator driver. It translates an object handle
+// into an object pointer, on the way atomically locking it and/or
+// removing it from the handle map for atomic deletion.
+//
+HandleObject *HandleObject::State::locate(CSSM_HANDLE h, LocateMode mode, CSSM_RETURN error)
+{
+    for (;;) {
+		{
+			StLock<Mutex> _(mLock);
+			HandleMap::iterator it = handleMap.find(h);
+			if (it == handleMap.end())
+				CssmError::throwMe(error);
+			HandleObject *obj = it->second;
+			if (obj == NULL || obj->handle() != h)
+				CssmError::throwMe(error);
+			if (mode == findTarget)
+				return obj;		// that's all, folks
+			// atomic find-and-lock requested (implicit in remove operation)
+			if (obj->tryLock()) {
+				// got object lock - assured of exit path
+				if (mode == removeTarget) {
+					debug("handleobj", "killing %p", obj);
+					handleMap.erase(h);
+					obj->clearHandle();
+				}
+				return obj;
+			}
+			// obj is busy; relinquish maplock and try again later
+			debug("handleobj", "object %p (handle 0x%lx) is busy - backing off",
+				obj, h);
+		}
+#if _USE_THREADS == _USE_NO_THREADS
+		assert(false);		// impossible; tryLock above always succeeds
+#else // real threads
+        Thread::yield();
+#endif // real threads
+    }
+}
+
+
+//
+// The default locking virtual methods do nothing and succeed.
+//
+void HandleObject::lock() { }
+
+bool HandleObject::tryLock() { return true; }
diff --git a/cdsa/cdsa_utilities/handleobject.h b/cdsa/cdsa_utilities/handleobject.h
new file mode 100644
index 00000000..25f1727d
--- /dev/null
+++ b/cdsa/cdsa_utilities/handleobject.h
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+
+//
+// handleobject - give an object a process-global unique handle
+//
+#ifndef _H_HANDLEOBJECT
+#define _H_HANDLEOBJECT
+
+#include <Security/cssm.h>
+#include <Security/utilities.h>
+#include <Security/threading.h>
+#include <Security/globalizer.h>
+#include <hash_map>
+
+
+namespace Security
+{
+
+//
+// A HandledObject is a trivial mixin class whose only feature is that
+// it has a *handle*, in the form of (currently) a CSSM_HANDLE of some kind.
+// Subclasses need to assign such a handle during creation.
+//
+class HandledObject {
+public:
+    typedef CSSM_HANDLE Handle;
+    static const Handle invalidHandle = 0;
+
+    Handle handle() const { return mMyHandle; }
+    bool validHandle() const { return mValid; }
+
+protected:
+    HandledObject(Handle h) : mMyHandle(h), mValid(true) { }
+    HandledObject() { /*IFDEBUG(*/ mMyHandle = invalidHandle/*)*/ ; mValid = false; }
+
+    void setHandle(Handle h)
+    {
+        assert(!mValid);	// guard against redefinition
+        mMyHandle = h;
+        mValid = true;
+    }
+    void clearHandle()
+    { assert(mValid); mValid = false; }
+    
+private:
+    Handle mMyHandle;			// our handle value
+    bool mValid;				// is the handle (still) valid?
+};
+
+
+//
+// Mapping CSSM_HANDLE values to object pointers and back.
+// A HandleObject is a HandledObject (see above) that makes up its own handle
+// based on some mechanism that you know nothing about.
+//
+// Please be very careful about the limits of the object contract here.
+// We promise to invent a suitable, unique Handle for each HandleObject in
+// existence within one address space. We promise that if you hand that handle
+// to the various findHandle<>() variants, we will give you back the HandleObject
+// that created it. This is the entire contract.
+// We *will* make some efforts to diagnose invalid handles and throw exceptions on
+// them, but the find() operation is supposed to be *fast*, so no heroic measures
+// will be taken.
+//
+class HandleObject : public HandledObject {
+    NOCOPY(HandleObject)
+    class State; friend class State;
+    template <class Subtype> friend Subtype &findHandle(CSSM_HANDLE, CSSM_RETURN);
+    template <class Subtype> friend Subtype &findHandleAndLock(CSSM_HANDLE, CSSM_RETURN);
+    template <class Subtype> friend Subtype &killHandle(CSSM_HANDLE, CSSM_RETURN);
+public:
+    HandleObject()				{ state().make(this); }
+    virtual ~HandleObject()		{ state().erase(this); }
+
+protected:
+    virtual void lock();
+    virtual bool tryLock();
+
+private:
+    enum LocateMode { lockTarget, findTarget, removeTarget };
+
+private:
+    typedef hash_map<CSSM_HANDLE, HandleObject *> HandleMap;
+    class State {
+    public:
+        State();
+        void make(HandleObject *obj);
+        HandleObject *locate(Handle h, LocateMode mode, CSSM_RETURN error);
+        void erase(HandleObject *obj);
+
+    private:
+        HandleMap handleMap;
+        uint32 sequence;
+        Mutex mLock;
+    };
+    
+    static ModuleNexus<State> state;
+};
+
+
+//
+// Type-specific ways to access the HandleObject map in various ways
+//
+template <class Subclass>
+Subclass &findHandle(CSSM_HANDLE handle,
+                     CSSM_RETURN error = CSSMERR_CSSM_INVALID_ADDIN_HANDLE)
+{
+    Subclass *sub;
+    if (!(sub = dynamic_cast<Subclass *>(HandleObject::state().locate(handle, HandleObject::findTarget, error))))
+        CssmError::throwMe(error);
+    return *sub;
+}
+
+template <class Subclass>
+Subclass &findHandleAndLock(CSSM_HANDLE handle,
+                            CSSM_RETURN error = CSSMERR_CSSM_INVALID_ADDIN_HANDLE)
+{
+    Subclass *sub;
+    if (!(sub = dynamic_cast<Subclass *>(HandleObject::state().locate(handle, HandleObject::lockTarget, error))))
+        CssmError::throwMe(error);
+    return *sub;
+}
+
+template <class Subclass>
+Subclass &killHandle(CSSM_HANDLE handle,
+                     CSSM_RETURN error = CSSMERR_CSSM_INVALID_ADDIN_HANDLE)
+{
+    Subclass *sub;
+    if (!(sub = dynamic_cast<Subclass *>(HandleObject::state().locate(handle, HandleObject::removeTarget, error))))
+        CssmError::throwMe(error);
+	return *sub;
+}
+
+} // end namespace Security
+
+#endif //_H_HANDLEOBJECT
diff --git a/cdsa/cdsa_utilities/headermap.cpp b/cdsa/cdsa_utilities/headermap.cpp
new file mode 100644
index 00000000..e5215e3d
--- /dev/null
+++ b/cdsa/cdsa_utilities/headermap.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+
+//
+// headermap - represent Internet-standard headers
+//
+#include "headermap.h"
+
+
+namespace Security {
+
+
+//
+// Given a constant text string, extract the leading substring up to 'end' (or \0),
+// canonicalize its case, and store the result for use.
+//
+HeaderMap::CanonicalKey::CanonicalKey(const char *key, char end)
+{
+    assert(key && key[0]);	// non-empty
+    mValue[0] = toupper(key[0]);
+    for (unsigned int n = 1; n < sizeof(mValue) - 1; n++) {
+        if (key[n] == end) {
+            mValue[n] = '\0';
+            return;
+        }
+        mValue[n] = tolower(key[n]);
+    }
+    // overflow -- truncate? throw? dynamic allocation? seppuko? :-)
+    assert(false);
+}
+
+
+//
+// Add an entry
+//
+void HeaderMap::add(const char *key, const char *value)
+{
+    add(CanonicalKey(key), value);
+}
+
+
+//
+// Given a standard form (Key: value), add its value to the headermap
+//
+void HeaderMap::add(const char *form)
+{
+    while (*form && isspace(*form))
+        form++;
+    if (const char *colon = strchr(form, ':')) {
+        CanonicalKey key(form, ':');
+        const char *value = colon + 1;
+        while (*value && isspace(*value))
+            value++;
+        add(key, value);
+    } else {
+        // ignore this
+        //@@@ signal an error? how? how bad?
+    }
+}
+
+
+//
+// Internal add method, given a canonicalized key
+//
+void HeaderMap::add(const CanonicalKey &key, const char *value)
+{
+    Map::iterator it = mMap.find(key);
+    if (it == mMap.end())
+        mMap[key] = value;
+    else
+        merge(key, mMap[key], value);
+}
+
+
+//
+// Locate an entry in a headermap.
+// Find returns NULL if not found; [] creates a new entry if needed and returns
+// a reference to the value, in good STL tradition.
+//
+const char *HeaderMap::find(const char *key, const char *defaultValue) const
+{
+    Map::const_iterator it = mMap.find(CanonicalKey(key));
+    return (it == mMap.end()) ? defaultValue : it->second.c_str();
+}
+
+string &HeaderMap::operator[] (const char *key)
+{
+    return mMap[CanonicalKey(key)];
+}
+
+
+//
+// The default implementation of merge throws out the old contents and replaces
+// them with the new.
+//
+void HeaderMap::merge(string key, string &old, string newValue)
+{
+    old = newValue;
+}
+
+
+//
+// Collect the entire contents into a single string
+// Note that this is NOT exactly what was passed in; certain canonicalizations have
+// been done; fields are reordered; and duplicate-header fields have been coalesced.
+//@@@ size could be pre-calculated (running counter).
+//
+string HeaderMap::collect(const char *lineEnding) const
+{
+    string value;
+    for (Map::const_iterator it = mMap.begin(); it != mMap.end(); it++)
+        value += it->first + ": " + it->second + lineEnding;
+    return value;
+}
+
+size_t HeaderMap::collectLength(const char *lineEnding) const
+{
+    size_t size = 0;
+    size_t sepLength = strlen(lineEnding);
+    for (Map::const_iterator it = mMap.begin(); it != mMap.end(); it++)
+        size += it->first.length() + 2 + it->second.length() + sepLength;
+    return size;
+}
+
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/headermap.h b/cdsa/cdsa_utilities/headermap.h
new file mode 100644
index 00000000..f06ccbf1
--- /dev/null
+++ b/cdsa/cdsa_utilities/headermap.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+
+//
+// headermap - represent Internet-standard headers
+//
+//@@@ Handle duplicate entries.
+//@@@ Be flexible: think HTTP (append with commas) vs. RFC822 (multiple Received: headers etc.)
+//
+#ifndef _H_HEADERMAP
+#define _H_HEADERMAP
+
+#include <string>
+#include <map>
+
+
+namespace Security {
+
+
+//
+// Header-maps
+//
+class HeaderMap {
+    static const int maxKeyLength = 80;
+    typedef map<string, string> Map;
+public:
+    HeaderMap() { }
+    virtual ~HeaderMap() { }
+    
+    virtual void merge(string key, string &old, string newValue);
+    
+    void add(const char *key, const char *value);
+    void add(const char *line);		// Key: value
+    void remove(const char *key);
+
+    const char *find(const char *key, const char *def = NULL) const;
+    string &operator [] (const char *key);
+    
+    typedef Map::const_iterator ConstIterator;
+    ConstIterator begin() const	{ return mMap.begin(); }
+    ConstIterator end() const	{ return mMap.end(); }
+    
+    typedef Map::const_iterator Iterator;
+    Iterator begin()			{ return mMap.begin(); }
+    Iterator end()				{ return mMap.end(); }    
+    
+    string collect(const char *lineEnding = "\r\n") const;
+    size_t collectLength(const char *lineEnding = "\r\n") const;
+    
+private:
+    //
+    // In-place case canonicalization of header keys
+    //
+    struct CanonicalKey {
+        CanonicalKey(const char *key, char end = '\0');
+        operator const char *() const { return mValue; }
+        operator string () const { return mValue; }
+    private:
+        char mValue[maxKeyLength];
+    };
+    
+    void add(const CanonicalKey &key, const char *value);
+
+private:
+    Map mMap;						// map of key: value pairs
+};
+
+
+}	// end namespace Security
+
+
+#endif _H_HEADERMAP
diff --git a/cdsa/cdsa_utilities/hosts.cpp b/cdsa/cdsa_utilities/hosts.cpp
new file mode 100644
index 00000000..4dd47c70
--- /dev/null
+++ b/cdsa/cdsa_utilities/hosts.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+
+//
+// hosts - value-semantics host identifier class
+//
+#include "hosts.h"
+#include <arpa/inet.h>
+#include <netdb.h>
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+class NamedHost : public Host::Spec {
+public:
+    NamedHost(const char *name);
+    
+    string name() const;
+    set<IPAddress> addresses() const;
+    
+    bool operator == (const NamedHost &other) const
+    { return mName == other.mName; }
+    
+private:
+    string mName;
+    set<IPAddress> mAddrs;
+};
+
+
+class IPv4NumberHost : public Host::Spec {
+public:
+    IPv4NumberHost(IPAddress addr) : mAddr(addr) { }
+    
+    string name() const;
+    set<IPAddress> addresses() const;
+    
+    bool operator == (const IPv4NumberHost &other) const
+    { return mAddr == other.mAddr; }
+    
+private:
+    IPAddress mAddr;
+};
+
+
+//
+// Host basics
+//
+Host::Host(const char *form)
+{
+    //@@@ IPv4 only at this time
+    IPAddress addr;
+    if (inet_aton(form, &addr))
+        mSpec = new IPv4NumberHost(addr);
+    else
+        mSpec = new NamedHost(form);
+}
+
+
+//
+// Compare for equality
+//
+bool Host::operator == (const Host &other) const
+{
+    // really silly hack alert: just compare lexicographically by name
+    return mSpec ? (name() == other.name()) : !other.mSpec;
+}
+
+bool Host::operator < (const Host &other) const
+{
+    // really silly hack alert: just compare lexicographically by name
+    return !mSpec || (other.mSpec && name() < other.name());
+}
+
+
+//
+// Compare for subsumption
+//
+bool Host::operator <= (const Host &other) const
+{
+    return false;
+}
+
+
+//
+// IPv4 address host specs (a single IPv4 address)
+//
+string IPv4NumberHost::name() const
+{
+    return mAddr;
+}
+
+set<IPAddress> IPv4NumberHost::addresses() const
+{
+    set<IPAddress> result;
+    result.insert(mAddr);
+    return result;
+}
+
+
+//
+// IPv4 hostname host specs (a set of addresses derived from a name lookup)
+// @@@ If we want to support IPv6, this should ALSO contain IPv6 lookup results.
+//
+NamedHost::NamedHost(const char *name) : mName(name)
+{
+    //@@@ NOT THREAD SAFE - find another way to do name resolution
+    if (hostent *he = gethostbyname(name)) {
+        for (char **p = he->h_addr_list; *p; p++)
+            mAddrs.insert(*reinterpret_cast<in_addr *>(*p));
+        debug("ipname", "host %s resolves to %ld address(es)", mName.c_str(), mAddrs.size());
+        return;
+    }
+    UnixError::throwMe(ENOENT);	//@@@ h_errno translation or other source
+}
+
+string NamedHost::name() const
+{
+    return mName;
+}
+
+set<IPAddress> NamedHost::addresses() const
+{
+    return mAddrs;
+}
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/hosts.h b/cdsa/cdsa_utilities/hosts.h
new file mode 100644
index 00000000..4ddfb5c4
--- /dev/null
+++ b/cdsa/cdsa_utilities/hosts.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+//
+// hosts - value-semantics host identifier class
+//
+// @@@ use vector instead of set to preserve resolver-generated order?
+// @@@ preliminary implementation: at the very least, there'll be more subclasses (deferred, etc.)
+//
+#ifndef _H_HOSTS
+#define _H_HOSTS
+
+#include "ip++.h"
+#include <Security/refcount.h>
+#include <set>
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+//
+// Host identities
+//
+class Host {
+public:
+    Host(const char *form);
+    Host() { }
+
+    // equality is defined strongly: same host specification
+    bool operator == (const Host &other) const;
+    bool operator != (const Host &other) const	{ return !(*this == other); }
+    bool operator < (const Host &other) const;	// for STL sorting
+    
+    // inclusion (<=) is defined semi-weakly: greater subsumes smaller, same access specs
+    bool operator <= (const Host &other) const;
+    bool operator >= (const Host &other) const	{ return other <= *this; }
+    
+    string name() const					{ return mSpec->name(); }
+    set<IPAddress> addresses() const	{ return mSpec->addresses(); }
+
+public:
+    class Spec : public RefCount {
+    public:
+        virtual ~Spec() { }
+        
+        virtual set<IPAddress> addresses() const = 0;
+        virtual string name() const = 0;
+    
+    private:
+    };
+
+private:
+    RefPointer<Spec> mSpec;
+};
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
+
+
+#endif _H_HOSTS
diff --git a/cdsa/cdsa_utilities/inetreply.cpp b/cdsa/cdsa_utilities/inetreply.cpp
new file mode 100644
index 00000000..29bce589
--- /dev/null
+++ b/cdsa/cdsa_utilities/inetreply.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+
+//
+// inetreply - manage Internet-standard reply strings
+//
+#include "inetreply.h"
+#include <Security/debugging.h>
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+//
+// Construct an InetReply object from a WRITABLE buffer.
+// The buffer will be alterered by this constructor, and needs to be left alone
+// until the InetReply object is destroyed.
+//
+InetReply::InetReply(const char *buffer) : mBuffer(buffer)
+{
+    analyze();
+}
+
+void InetReply::analyze()
+{
+    // follow Internet rule #1: be lenient in what you accept
+    /*const*/ char *p;				// (un-const is ANSI bogosity in strtol)
+    mCode = strtol(mBuffer, &p, 10);
+    if (p == mBuffer) {			// conversion failed
+        mCode = -1;				// error indicator
+        mSeparator = ' ';
+        mMessage = "?invalid?";
+        return;
+    }
+    if (!*p) {					// just "nnn" (tolerate)
+        mCode = atoi(p);
+        mSeparator = ' ';
+        mMessage = "";
+        return;
+    }
+    mSeparator = *p++;
+    while (isspace(*p)) p++;
+    mMessage = p;
+}
+
+
+//
+// Continuation handling
+//
+bool InetReply::Continuation::operator () (const char *input)
+{
+    if (mActive && !strncmp(input, mTestString, 4))
+        mActive = false;
+    return mActive;
+}
+
+bool InetReply::Continuation::operator () (const InetReply &reply)
+{
+    if (!mActive && reply.isContinued()) {
+        mActive = true;
+        snprintf(mTestString, 4, "%03d", reply.code());
+        mTestString[3] = ' ';	// no \0 left in this string
+    }
+    return mActive;
+}
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/inetreply.h b/cdsa/cdsa_utilities/inetreply.h
new file mode 100644
index 00000000..65b154d7
--- /dev/null
+++ b/cdsa/cdsa_utilities/inetreply.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+
+//
+// inetreply - manage Internet-standard reply strings
+//
+// The InetReply class represents an Internet-standard reply line of the form
+//	nnn some text
+//
+#ifndef _H_INETREPLY
+#define _H_INETREPLY
+
+#include <Security/utilities.h>
+#include <cstdarg>
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+//
+// An InetReply object represents a broken-up reply line of the form
+//	nnn(sp)text-form
+// Note that this will take a *writable* input line buffer and munge it
+// into shape. This means that
+//  (a) You have to keep the input line buffer alive until the InetReply dies, and
+//  (b) You can't use the input line buffer after the InetReply is constructed.
+//
+class InetReply {
+public:
+    InetReply(const char *buffer);
+    
+    bool valid() const			{ return mCode >= 0; }
+    unsigned int code() const	{ return mCode; }
+    operator unsigned int () const { return code(); }
+    unsigned int type() const	{ return mCode / 100; }
+    const char *message() const	{ return mMessage; }
+    bool isContinued() const	{ return mSeparator == '-'; }
+    
+private:
+    const char *mBuffer;		// base buffer
+    int mCode;					// integer code (usually nnn)
+    char mSeparator;			// character after code (usually space; '-' for continued lines)
+    const char *mMessage;		// rest of message
+    
+    void analyze();
+    
+public:
+    //
+    // Handle FTP-style continuations: nnn- ... nnn<sp>Message
+    // Instructions for use:
+    //	Continuation myCont;	// in some persistent place
+    //	... get a line of reply -> const char *input ...
+    //	if (myCont(input)) /* in (old) continuation */;
+    //	InetReply reply(input);
+    //	if (myCont(reply)) /* in (newly started) continuation */;
+    //	/* not (any more) in continuation; reply has last message line
+    //
+    class Continuation {
+    public:
+        Continuation() : mActive(false) { }
+        
+        bool operator () (const char *input);
+        bool operator () (const InetReply &reply);
+        
+        bool active() const	{ return mActive; }
+        
+    private:
+        bool mActive;
+        char mTestString[4];
+    };
+};
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
+
+
+#endif //_H_INETREPLY
diff --git a/cdsa/cdsa_utilities/ip++.cpp b/cdsa/cdsa_utilities/ip++.cpp
new file mode 100644
index 00000000..0bd8f3cc
--- /dev/null
+++ b/cdsa/cdsa_utilities/ip++.cpp
@@ -0,0 +1,317 @@
+/*
+ * 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.
+ */
+
+
+//
+// ip++ - C++ layer for IP socket and address management
+//
+// [Also see comments in header file.]
+//
+#include "ip++.h"
+#include "hosts.h"
+#include <Security/debugging.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+typedef unsigned char Byte;		// occasionally useful
+
+
+//
+// IPAddress
+//
+static const struct in_addr in_addr_any = { INADDR_ANY };
+#if BUG_GCC
+const IPAddress &IPAddress::any = *static_cast<const IPAddress *>(&in_addr_any);
+#else
+const IPAddress &IPAddress::any = static_cast<const IPAddress &>(in_addr_any);
+#endif
+
+IPAddress::IPAddress(const char *s)
+{
+    if (!inet_aton(s, this))
+        UnixError::throwMe(EINVAL);
+}
+
+IPAddress::operator string() const
+{
+    // This code is esentially equivalent to inet_ntoa, which we can't use for thread safety.
+    // Note: contents in NBO = always high-endian, thus this cast works everywhere.
+    const Byte *p = reinterpret_cast<const Byte *>(this);
+    char buffer[(3+1)*4];	// nnn.nnn.nnn.nnn\0
+    snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+    return buffer;
+}
+
+
+//
+// IPSockAddress
+//
+IPSockAddress::IPSockAddress()
+{
+    sin_family = AF_INET;
+}
+
+IPSockAddress::IPSockAddress(const IPAddress &addr, IPPort port)
+{
+    sin_family = AF_INET;
+    sin_addr = addr;
+    sin_port = htons(port);
+}
+
+IPSockAddress::operator string () const
+{
+    char buffer[4*(3+1)+5+1];	// nnn.nnn.nnn.nnn:ppppp
+    snprintf(buffer, sizeof(buffer), "%s:%d", string(address()).c_str(), port());
+    return buffer;
+}
+
+
+IPSockAddress IPSockAddress::defaults(const IPSockAddress &defaultAddr) const
+{
+    return defaults(defaultAddr.address(), defaultAddr.port());
+}
+
+IPSockAddress IPSockAddress::defaults(const IPAddress &defaultAddr, IPPort defaultPort) const
+{
+    return IPSockAddress(
+        address() ? address() : defaultAddr,
+        port() ? port() : defaultPort
+    );
+}
+
+IPSockAddress IPSockAddress::defaults(IPPort defaultPort) const
+{
+    return IPSockAddress(address(), port() ? port() : defaultPort);
+}
+
+
+//
+// Sockets
+//
+Socket::Socket(int type, int protocol)
+{
+    open(type, protocol);
+}
+
+void Socket::open(int type, int protocol)
+{
+    checkSetFd(::socket(AF_INET, type, protocol));
+    mAtEnd = false;
+    debug("sockio", "socket(%d,%d) -> %d", type, protocol, fd());
+}
+
+void Socket::prepare(int fdFlags, int type, int protocol)
+{
+    // if file descriptor is closed, open it - otherwise take what's there
+    if (!isOpen())
+        open(type, protocol);
+        
+    // if flags were passed in, set them on the file descriptor now
+    if (fdFlags)
+        setFlag(fdFlags);
+}
+
+
+void Socket::bind(const IPAddress &addr, IPPort port)
+{
+    bind(IPSockAddress(addr, port));
+}
+
+void Socket::bind(const IPSockAddress &local)
+{
+    checkError(::bind(fd(), local, sizeof(local)));
+    IFDEBUG(debug("sockio", "%d bind to %s", fd(), string(local).c_str()));
+}
+
+
+void Socket::listen(int backlog)
+{
+    checkError(::listen(fd(), backlog));
+}
+
+
+void Socket::accept(Socket &s)
+{
+    IPSockAddress dummy;	// ignored
+    return accept(s, dummy);
+}
+
+void Socket::accept(Socket &s, IPSockAddress &peer)
+{
+    int length = sizeof(IPSockAddress);
+    s.checkSetFd(::accept(fd(), peer, &length));
+    assert(length == sizeof(IPSockAddress));
+}
+
+
+bool Socket::connect(const IPSockAddress &peer)
+{
+    if (::connect(fd(), peer, sizeof(peer))) {
+        switch (errno) {
+        case EINPROGRESS:
+            IFDEBUG(debug("sockio", "%d connecting to %s", fd(), string(peer).c_str()));
+            return false;
+        case EALREADY:
+            if (int err = error())		// connect failed
+                UnixError::throwMe(err);
+            // just keep trying
+            IFDEBUG(debug("sockio", "%d still trying to connect", fd()));
+            return false;
+        case EISCONN:
+            if (flags() & O_NONBLOCK) {
+                debug("sockio", "%d now connected", fd());
+                return true;
+            } else {
+                UnixError::throwMe();
+            }
+        default:
+            UnixError::throwMe();
+        }
+    } else {
+        IFDEBUG(debug("sockio", "%d connect to %s", fd(), string(peer).c_str()));
+        return true;
+    }
+}
+
+bool Socket::connect(const IPAddress &addr, IPPort port)
+{
+    return connect(IPSockAddress(addr, port));
+}
+
+// void Socket::connect(const Host &host, ...): see below.
+
+
+void Socket::shutdown(int how)
+{
+    assert(how >= 0 && how <= 2);
+    checkError(::shutdown(fd(), how));
+}
+
+
+IPSockAddress Socket::localAddress() const
+{
+    IPSockAddress addr;
+    int length = sizeof(addr);
+    checkError(::getsockname(fd(), addr, &length));
+    assert(length == sizeof(addr));
+    return addr;
+}
+
+IPSockAddress Socket::peerAddress() const
+{
+    IPSockAddress addr;
+    int length = sizeof(addr);
+    checkError(::getpeername(fd(), addr, &length));
+    assert(length == sizeof(addr));
+    return addr;
+}
+
+void Socket::getOption(void *value, int &length, int name, int level = SOL_SOCKET) const
+{
+    UnixError::check(::getsockopt(fd(), level, name, value, &length));
+}
+
+void Socket::setOption(const void *value, int length, int name, int level = SOL_SOCKET) const
+{
+    UnixError::check(::setsockopt(fd(), level, name, value, length));
+}
+
+    
+//
+// Connect to a Host object.
+// This version of connect performs nontrivial work and makes interesting decisions.
+//
+void Socket::connect(const Host &host, IPPort port)
+{
+    //@@@ use two-step stutter algorithm?
+    //@@@ randomize order?
+    //@@@ keep worked-recently information?
+    //@@@ what about nonblocking operation?
+    set<IPAddress> addrs = host.addresses();
+    for (set<IPAddress>::const_iterator it = addrs.begin(); it != addrs.end(); it++) {
+        const IPSockAddress address(*it, port);
+        if (::connect(fd(), address, sizeof(IPSockAddress)) == 0) {
+            IFDEBUG(debug("sockio", "%d connect to %s", fd(), string(address).c_str()));
+            return;
+        }
+    }
+    // no joy on any of the candidate addresses. Throw last error
+    //@@@ clean up errno?
+    UnixError::throwMe();
+}
+
+
+//
+// TCP*Sockets.
+// Note that these will TCP*Socket::open() will *use* its existing file descriptor,
+// on the theory that the caller may have prepared it specially (e.g. to make it nonblocking).
+//
+void TCPClientSocket::open(const IPSockAddress &peer, int fdFlags)
+{
+    prepare(fdFlags, SOCK_STREAM);
+    connect(peer);
+}
+
+void TCPClientSocket::open(const IPAddress &addr, IPPort port, int fdFlags)
+{
+    prepare(fdFlags, SOCK_STREAM);
+    connect(addr, port);
+}
+
+void TCPClientSocket::open(const Host &host, IPPort port, int fdFlags)
+{
+    prepare(fdFlags, SOCK_STREAM);
+    connect(host, port);
+}
+
+TCPClientSocket::~TCPClientSocket()
+{
+    close();
+}
+
+
+void TCPServerSocket::open(const IPSockAddress &addr, int depth)
+{
+    prepare(0, SOCK_STREAM);
+    bind(addr);
+    listen(depth);
+}
+
+void TCPServerSocket::operator () (TCPClientSocket &newClient)
+{
+    accept(newClient);
+}
+
+void TCPServerSocket::receive(TCPClientSocket &newClient)
+{
+    accept(newClient);
+    close();
+}
+
+TCPServerSocket::~TCPServerSocket()
+{
+    close();
+}
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/ip++.h b/cdsa/cdsa_utilities/ip++.h
new file mode 100644
index 00000000..bfc105c6
--- /dev/null
+++ b/cdsa/cdsa_utilities/ip++.h
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ */
+
+
+//
+// ip++ - C++ layer for IP socket and address management
+//
+// Key to comments:
+//	HBO = host byte order, NBO = network byte order
+//
+// Rules for byte ordering: C++ objects store addresses and ports in NBO.
+// Struct in_addr arguments are in NBO. Integer type arguments are in HBO.
+// Stick with the conversion methods and you win. Cast around and you lose.
+//
+// @@@ Which namespace should we be in?
+//
+#ifndef _H_IPPLUSPLUS
+#define _H_IPPLUSPLUS
+
+#include "unix++.h"
+#include "timeflow.h"
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <cstdio>
+#include <cstdarg>
+#include <map>
+
+using namespace UnixPlusPlus;
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+class Host;
+
+
+//
+// For now, ports are simply a short unsigned integer type, in HBO.
+//
+typedef uint16 IPPort;
+
+
+//
+// An IP host address.
+//
+class IPAddress : public in_addr {
+public:
+    IPAddress()						{ s_addr = htonl(INADDR_ANY); }
+    IPAddress(const struct in_addr &addr) { s_addr = addr.s_addr; }
+    explicit IPAddress(uint32 addr)	{ s_addr = htonl(addr); }
+    IPAddress(const char *s);		// ONLY dotted-quad form - use hosts.h for name resolution
+    
+    operator uint32 () const		{ return ntohl(s_addr); }
+    operator string () const;		// "n.n.n.n" (no name resolution)
+    
+public:
+    bool operator == (const IPAddress &other) const	{ return s_addr == other.s_addr; }
+    bool operator != (const IPAddress &other) const	{ return s_addr != other.s_addr; }
+    bool operator < (const IPAddress &other) const	{ return s_addr < other.s_addr; }
+    
+    operator bool () const			{ return s_addr != htonl(INADDR_ANY); }
+    bool operator ! () const		{ return s_addr == htonl(INADDR_ANY); }
+    
+public:
+    static const IPAddress &any;
+};
+
+
+//
+// An IP "socket address", i.e. a combined host address and port.
+//
+class IPSockAddress : public sockaddr_in {
+public:
+    IPSockAddress();
+    IPSockAddress(const struct sockaddr_in &sockaddr)	{ *(sockaddr_in *)this = sockaddr; }
+    IPSockAddress(const IPAddress &addr, IPPort port);
+    
+    IPAddress address() const		{ return sin_addr; }
+    void address(IPAddress addr)	{ sin_addr = addr; }
+    IPPort port() const				{ return ntohs(sin_port); }
+    void port(IPPort p)				{ sin_port = htons(p); }
+    
+    operator string () const;		// "n.n.n.n:p" (no name resolution)
+
+    // automatically convert to struct sockaddr * for use in system calls
+    operator struct sockaddr * ()
+    { return reinterpret_cast<struct sockaddr *>(this); }
+    operator const struct sockaddr * () const
+    { return reinterpret_cast<const struct sockaddr *>(this); }
+    
+    // conveniences
+    IPSockAddress defaults(const IPSockAddress &defaultAddr) const;
+    IPSockAddress defaults(const IPAddress &defaultAddr, IPPort defaultPort = 0) const;
+    IPSockAddress defaults(IPPort defaultPort) const;
+};
+
+
+//
+// An IP socket.
+// This inherits all functionality of a FileDesc, so I/O is fun and easy.
+// Socket is "passive"; it doesn't own any resources and does nothing on destruction.
+// On the upside, you can assign Sockets freely.
+// If you want self-managing sockets that clean up after themselves,
+// use the subclasses below.
+//
+class Socket : public FileDesc {
+public:
+    Socket() { }
+    explicit Socket(int type, int protocol = 0);
+    
+    Socket &operator = (int fd)				{ setFd(fd); return *this; }
+    
+    // basic open (socket system call)
+    void open(int type, int protocol = 0);
+    
+    // standard socket operations
+    void bind(const IPSockAddress &addr);	// to this socket address
+    void bind(const IPAddress &addr = IPAddress::any, IPPort port = 0);
+    void listen(int backlog = 1);
+    void accept(Socket &s);
+    void accept(Socket &s, IPSockAddress &peer);
+    bool connect(const IPSockAddress &peer);
+    bool connect(const IPAddress &addr, IPPort port);
+    void connect(const Host &host, IPPort port);	// any address of this host
+    void shutdown(int type);
+    enum { shutdownRead = 0, shutdownWrite = 1, shutdownBoth = 2 };
+    
+    // get endpoint addresses
+    IPSockAddress localAddress() const;
+    IPSockAddress peerAddress() const;
+    
+    // socket options
+    void setOption(const void *value, int length, int name, int level = SOL_SOCKET) const;
+    void getOption(void *value, int &length, int name, int level = SOL_SOCKET) const;
+    
+    template <class T> void setOption(const T &value, int name, int level = SOL_SOCKET) const
+    { setOption(&value, sizeof(value), name, level); }
+    
+    template <class T> T getOption(int name, int level = SOL_SOCKET) const
+    {
+        T value; int length = sizeof(value);
+        getOption(&value, length, name, level);
+        assert(length == sizeof(value));
+        return value;
+    }
+    
+    // some specific useful options
+    int type() const		{ return getOption<int>(SO_TYPE); }
+    int error() const		{ return getOption<int>(SO_ERROR); }
+    
+public:
+#if defined(SOMAXCONN)
+    static const int listenMaxQueue = SOMAXCONN;
+#else
+    static const int listenMaxQueue = 5;	// the traditional BSD UNIX value
+#endif
+
+protected:
+    void prepare(int fdFlags, int type, int protocol = 0);
+};
+
+
+//
+// A TCPClientSocket is a self-connecting TCP socket that connects (actively) to a server.
+// Since TCP, once established, is symmetric, it can also be used for the server side
+// of a TCP pipe. You can think of it as the least complex embodiment of a TCP connection.
+//
+class TCPClientSocket : public Socket {
+    NOCOPY(TCPClientSocket)
+public:
+    TCPClientSocket() { }
+    ~TCPClientSocket();	// closes connection
+    
+#if BUG_GCC
+    void open(int type, int protocol = 0)	{ Socket::open(type, protocol); }
+#else
+    using Socket::open;
+#endif
+    
+    void open(const IPSockAddress &peer, int fdFlags = 0);
+    void open(const IPAddress &addr, IPPort port, int fdFlags = 0);
+    void open(const Host &host, IPPort port, int fdFlags = 0);
+
+    TCPClientSocket(const IPSockAddress &peer, int fdFlags = 0)
+    { open(peer, fdFlags); }
+    TCPClientSocket(const IPAddress &addr, IPPort port, int fdFlags = 0)
+    { open(addr, port, fdFlags); }
+    TCPClientSocket(const Host &host, IPPort port, int fdFlags = 0)
+    { open(host, port, fdFlags); }
+    
+protected:	// for serverSocket/clientSocket footsy play
+    void setFd(int fd)			{ Socket::setFd(fd); }
+    
+private:
+    TCPClientSocket(int sockfd);
+};
+
+
+//
+// A TCPServerSocket is a self-initializing listener socket for incoming TCP requests
+// (usually to a server). Its function operator yields the next incoming connection request
+// as a TCPClientSocket (see above). For one-shot receivers, the receive() method will
+// create the client and close the listener atomically (which is sometimes faster).
+//
+class TCPServerSocket : public Socket {
+    NOCOPY(TCPServerSocket)
+public:
+    TCPServerSocket() { }
+    ~TCPServerSocket();	// closes listener; existing connections unaffected
+    
+    void open(const IPSockAddress &local, int depth = 1);
+    void open(IPPort port = 0, int depth = 1)
+    { open(IPSockAddress(IPAddress::any, port), depth); }
+
+    TCPServerSocket(const IPSockAddress &local, int depth = 1)	{ open(local, depth); }
+    TCPServerSocket(IPPort port, int depth = 1)					{ open(port, depth); }
+    
+    void operator () (TCPClientSocket &newClient);	// retrieve next connection
+    void receive(TCPClientSocket &client);			// accept once, then close listener
+};
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
+
+
+#endif //_H_IPPLUSPLUS
diff --git a/cdsa/cdsa_utilities/logging.cpp b/cdsa/cdsa_utilities/logging.cpp
new file mode 100644
index 00000000..7628b1bd
--- /dev/null
+++ b/cdsa/cdsa_utilities/logging.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+
+//
+// logging - message log support
+//
+#ifdef __MWERKS__
+# define _CPP_LOGGING
+#endif
+
+#include <Security/logging.h>
+#include <Security/globalizer.h>
+#include <cstdarg>
+
+
+namespace Security
+{
+
+namespace Syslog
+{
+
+//
+// Open and initialize logging
+//
+void open(const char *ident, int facility, int options = 0)
+{
+	::openlog(ident, options, facility);
+}
+
+
+//
+// General output method
+//
+static void output(int priority, const char *format, va_list args)
+{
+	::vsyslog(priority, format, args);
+}
+
+
+//
+// Priority-specific wrappers
+//
+void syslog(int priority, const char *format, ...)
+{ va_list args; va_start(args, format); output(priority, format, args); va_end(args); }
+
+void emergency(const char *format, ...)
+{ va_list args; va_start(args, format); output(LOG_EMERG, format, args); va_end(args); }
+void alert(const char *format, ...)
+{ va_list args; va_start(args, format); output(LOG_ALERT, format, args); va_end(args); }
+void critical(const char *format, ...)
+{ va_list args; va_start(args, format); output(LOG_CRIT, format, args); va_end(args); }
+void error(const char *format, ...)
+{ va_list args; va_start(args, format); output(LOG_ERR, format, args); va_end(args); }
+void warning(const char *format, ...)
+{ va_list args; va_start(args, format); output(LOG_WARNING, format, args); va_end(args); }
+void notice(const char *format, ...)
+{ va_list args; va_start(args, format); output(LOG_NOTICE, format, args); va_end(args); }
+void info(const char *format, ...)
+{ va_list args; va_start(args, format); output(LOG_INFO, format, args); va_end(args); }
+void debug(const char *format, ...)
+{ va_list args; va_start(args, format); output(LOG_DEBUG, format, args); va_end(args); }
+
+
+//
+// Enable mask operation
+//
+int mask()
+{
+	int mask;
+	::setlogmask(mask = ::setlogmask(0));
+	return mask;
+}
+	
+void upto(int priority)
+{
+	::setlogmask(LOG_UPTO(priority));
+}
+
+void enable(int priority)
+{
+	::setlogmask(::setlogmask(0) | LOG_MASK(priority));
+}
+
+void disable(int priority)
+{
+	::setlogmask(::setlogmask(0) & ~LOG_MASK(priority));
+}
+
+} // end namespace Syslog
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/logging.h b/cdsa/cdsa_utilities/logging.h
new file mode 100644
index 00000000..2adb3f77
--- /dev/null
+++ b/cdsa/cdsa_utilities/logging.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+
+//
+// logging - message log support
+//
+#ifndef _H_LOGGING
+#define _H_LOGGING
+
+#include <Security/utilities.h>
+#include <syslog.h>
+
+#ifdef _CPP_LOGGING
+#pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// Log destination object
+//
+namespace Syslog
+{
+
+void syslog(int priority, const char *format, ...);
+
+void emergency(const char *format, ...);
+void alert(const char *format, ...);
+void critical(const char *format, ...);
+void error(const char *format, ...);
+void warning(const char *format, ...);
+void notice(const char *format, ...);
+void info(const char *format, ...);
+void debug(const char *format, ...);
+
+void open(const char *ident, int facility, int options = 0);
+	
+int mask();
+void upto(int priority);
+void enable(int priority);
+void disable(int priority);
+
+} // end namespace Syslog
+
+} // end namespace Security
+
+#ifdef _CPP_LOGGING
+#pragma export off
+#endif
+
+#endif //_H_LOGGING
diff --git a/cdsa/cdsa_utilities/mach++.cpp b/cdsa/cdsa_utilities/mach++.cpp
new file mode 100644
index 00000000..bf673a97
--- /dev/null
+++ b/cdsa/cdsa_utilities/mach++.cpp
@@ -0,0 +1,300 @@
+/*
+ * 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.
+ */
+
+
+//
+// mach++ - C++ bindings for useful Mach primitives
+//
+#include "mach++.h"
+#include <mach/mach_error.h>
+#include <stdio.h>	// debug
+#include <Security/debugging.h>
+#include <servers/bootstrap_defs.h>	// debug
+
+namespace Security {
+namespace MachPlusPlus {
+
+
+Error::Error(kern_return_t err) : error(err)
+{
+}
+
+Error::~Error()
+{
+}
+
+CSSM_RETURN
+Error::cssmError() const
+{
+	switch (error) {
+	case BOOTSTRAP_UNKNOWN_SERVICE:
+	case MIG_SERVER_DIED:
+		return CSSM_ERRCODE_SERVICE_NOT_AVAILABLE;
+	default: 
+		return CSSM_ERRCODE_INTERNAL_ERROR;
+	}
+}
+
+OSStatus
+Error::osStatus() const
+{
+	return cssmError();
+}
+
+void Error::check(kern_return_t status)
+{
+	if (status != KERN_SUCCESS) {
+#if !defined(NDEBUG)
+		// issue a diagnostic log for any discovered mach-level error
+		switch (status) {
+		case BOOTSTRAP_UNKNOWN_SERVICE:
+			debug("error", "mach error: BOOTSTRAP_UNKNOWN_SERVICE"); break;
+		case BOOTSTRAP_NAME_IN_USE:	
+			debug("error", "mach error: BOOTSTRAP_NAME_IN_USE"); break;
+		case BOOTSTRAP_NOT_PRIVILEGED:
+			debug("error", "mach error: BOOTSTRAP_NOT_PRIVILEGED"); break;
+		case BOOTSTRAP_SERVICE_ACTIVE:
+			debug("error", "mach error: BOOTSTRAP_SERVICE_ACTIVE"); break;
+		default:
+			debug("error", "mach error: %s (%d)", mach_error_string(status), status); break;
+		}
+#endif NDEBUG
+		Error::throwMe(status);
+	}
+}
+
+void Error::throwMe(kern_return_t err) { throw Error(err); }
+
+//
+// Port functions
+//
+mach_port_urefs_t Port::getRefs(mach_port_right_t right)
+{
+	mach_port_urefs_t count;
+	check(::mach_port_get_refs(self(), mPort, right, &count));
+	return count;
+}
+
+
+//
+// Task port features
+//
+pid_t TaskPort::pid() const
+{
+    pid_t pid;
+    check(::pid_for_task(mPort, &pid));
+    return pid;
+}
+
+TaskPort TaskPort::forPid(pid_t pid)
+{
+    TaskPort taskPort;
+    check(::task_for_pid(self(), pid, &taskPort.port()));
+    return taskPort;
+}
+
+
+//
+// Bootstrap port management
+//
+mach_port_t Bootstrap::checkIn(const char *name) const
+{
+	mach_port_t port;
+	check(::bootstrap_check_in(mPort, makeName(name), &port));
+	return port;
+}
+
+mach_port_t Bootstrap::checkInOptional(const char *name) const
+{
+	mach_port_t port;
+	kern_return_t err = ::bootstrap_check_in(mPort, makeName(name), &port);
+    if (err == BOOTSTRAP_UNKNOWN_SERVICE || err == BOOTSTRAP_NOT_PRIVILEGED)
+        return 0;
+    check(err);
+	return port;
+}
+
+void Bootstrap::registerAs(mach_port_t port, const char *name) const
+{
+	check(::bootstrap_register(mPort, makeName(name), port));
+}
+
+mach_port_t Bootstrap::lookup(const char *name) const
+{
+	mach_port_t port;
+	check(::bootstrap_look_up(mPort, makeName(name), &port));
+	return port;
+}
+
+mach_port_t Bootstrap::lookupOptional(const char *name) const
+{
+	mach_port_t port;
+	kern_return_t err = ::bootstrap_look_up(mPort, makeName(name), &port);
+    if (err == BOOTSTRAP_UNKNOWN_SERVICE)
+        return 0;
+    check(err);
+	return port;
+}
+
+
+Bootstrap Bootstrap::subset(Port requestor)
+{
+    mach_port_t sub;
+    check(::bootstrap_subset(mPort, requestor, &sub));
+    return sub;
+}
+
+
+//
+// ReceivePorts
+//
+ReceivePort::ReceivePort(const char *name, const Bootstrap &bootstrap)
+{
+	mPort = bootstrap.checkInOptional(name);
+	if (!mPort)
+	{
+		allocate();
+		insertRight(MACH_MSG_TYPE_MAKE_SEND);
+		bootstrap.registerAs(mPort, name);
+	}
+}
+
+
+//
+// Stack-based bootstrap switcher
+//
+ModuleNexus<Mutex> StBootstrap::critical;
+
+StBootstrap::StBootstrap(const Bootstrap &newBoot, const TaskPort &task) 
+    : mTask(task), locker(critical())
+{
+    mOldBoot = Bootstrap();
+    mTask.bootstrap(newBoot);
+    debug("StBoot", "bootstrap for %d switched to %d", mTask.port(), newBoot.port());
+}
+
+StBootstrap::~StBootstrap()
+{
+    mTask.bootstrap(mOldBoot);
+    debug("StBoot", "bootstrap for %d returned to %d", mTask.port(), mOldBoot.port());
+}
+
+
+//
+// Mach message buffers
+//
+Message::Message(void *buffer, size_t size)
+    : mBuffer(reinterpret_cast<mig_reply_error_t *>(buffer)), 
+    mSize(size), mRelease(false)
+{
+    assert(size >= sizeof(mach_msg_header_t));
+}
+
+Message::Message(size_t size)
+{
+    mSize = size + MAX_TRAILER_SIZE;
+    mBuffer = (mig_reply_error_t *)new char[mSize];
+    mRelease = true;
+}
+
+Message::~Message()
+{
+    if (mRelease)
+        delete[] mBuffer;
+}
+
+
+void Message::send(mach_msg_option_t options,
+    mach_msg_timeout_t timeout,
+    mach_port_name_t notify)
+{
+    check(mach_msg_overwrite_trap(*this,
+        options | MACH_SEND_MSG,
+        length(),
+        0, MACH_PORT_NULL,
+        timeout, notify,
+        NULL, 0));
+}
+
+void Message::receive(mach_port_t receivePort,
+    mach_msg_option_t options,
+    mach_msg_timeout_t timeout,
+    mach_port_name_t notify)
+{
+    check(mach_msg_overwrite_trap(*this,
+        options | MACH_RCV_MSG,
+        length(),
+        mSize, receivePort,
+        timeout, notify,
+        NULL, 0));
+}
+
+void Message::sendReceive(mach_port_t receivePort,
+    mach_msg_option_t options,
+    mach_msg_timeout_t timeout,
+    mach_port_name_t notify)
+{
+    check(mach_msg_overwrite_trap(*this,
+        options | MACH_SEND_MSG | MACH_RCV_MSG,
+        length(),
+        mSize, receivePort,
+        timeout, notify,
+        NULL, 0));
+}
+
+
+//
+// Debug dumping of ports etc.
+//
+#if defined(DEBUGDUMP)
+
+void Port::dump(const char *descr)
+{
+	fprintf(stderr, "[%s(%d)", descr ? descr : "port", mPort);
+	mach_port_type_t type;
+	kern_return_t err = mach_port_type(self(), mPort, &type);
+	if (err != KERN_SUCCESS) {
+		fprintf(stderr, " !%s", mach_error_string(err));
+	} else {
+		if (type & MACH_PORT_TYPE_SEND) fprintf(stderr, " send(%d)", getRefs(MACH_PORT_RIGHT_SEND));
+		if (type & MACH_PORT_TYPE_RECEIVE) fprintf(stderr, " rcv");
+		if (type & MACH_PORT_TYPE_SEND_ONCE) fprintf(stderr, " once");
+		if (type & MACH_PORT_TYPE_PORT_SET) fprintf(stderr, " set");
+		if (type & MACH_PORT_TYPE_DEAD_NAME) fprintf(stderr, " dead");
+		if (type & MACH_PORT_TYPE_DNREQUEST) fprintf(stderr, " dnreq");
+	}
+	fprintf(stderr, "]\n");
+}
+
+
+void Bootstrap::dump()
+{
+    name_array_t services, servers;
+    bool_array_t active;
+    mach_msg_type_number_t nServices, nServers, nActive;
+    check(bootstrap_info(mPort, &services, &nServices,
+        &servers, &nServers, &active, &nActive));
+    fprintf(stderr, "[port %d] %d services\n", mPort, nServices);
+    for (mach_msg_type_number_t n = 0; n < nServices; n++)
+        fprintf(stderr, "%s\n", services[n]);
+}
+
+#endif //DEBUGDUMP
+
+
+} // end namespace MachPlusPlus
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/mach++.h b/cdsa/cdsa_utilities/mach++.h
new file mode 100644
index 00000000..dc3c1a8b
--- /dev/null
+++ b/cdsa/cdsa_utilities/mach++.h
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ */
+
+
+//
+// mach++ - C++ bindings for useful Mach primitives
+//
+#ifndef _H_MACHPP
+#define _H_MACHPP
+
+#include <Security/utilities.h>
+#include <Security/threading.h>
+#include <Security/globalizer.h>
+#include <mach/mach.h>
+#include <servers/bootstrap.h>
+
+// yes, we use some UNIX (non-mach) headers...
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace Security {
+namespace MachPlusPlus {
+
+
+//
+// Exceptions thrown by the mach++ interface.
+//
+class Error : public CssmCommonError {
+protected:
+	// actually, kern_return_t can be just about any subsystem type return code
+	Error(kern_return_t err);
+public:
+	virtual ~Error();
+
+    virtual CSSM_RETURN cssmError() const;
+    virtual OSStatus osStatus() const;
+
+	const kern_return_t error;
+	
+	static void check(kern_return_t err);
+    static void throwMe(kern_return_t err) __attribute__((noreturn));
+};
+
+// generic return code checker
+inline void check(kern_return_t status)
+{ Error::check(status); }
+
+
+//
+// An encapsulation of a Mach 3 port
+//
+class Port {
+protected:
+	static mach_port_t self() { return mach_task_self(); }	
+
+public:
+	Port() { mPort = 0; }
+	Port(mach_port_t port) { mPort = port; }
+	
+	// devolve to Mach primitive type
+	operator mach_port_t () const	{ return mPort; }
+
+	// access reference (for primitives storing into &mach_port_t)
+	mach_port_t &port ()			{ return mPort; }
+	const mach_port_t &port () const { return mPort; }
+	
+	// status checks
+	mach_port_type_t type() const
+	{ mach_port_type_t typ; check(mach_port_type(self(), mPort, &typ)); return typ; }
+	
+	bool isType(mach_port_type_t typ) const	{ return type() & typ; }
+	bool isDead() const		{ return isType(MACH_PORT_TYPE_DEAD_NAME); }
+
+	// port allocation and management
+	void allocate(mach_port_right_t right = MACH_PORT_RIGHT_RECEIVE)
+	{ check(mach_port_allocate(self(), right, &mPort)); }
+	void deallocate()	{ check(mach_port_deallocate(self(), mPort)); }
+	void destroy()		{ check(mach_port_destroy(self(), mPort)); }
+	
+	void insertRight(mach_msg_type_name_t type)
+	{ check(mach_port_insert_right(self(), mPort, mPort, type)); }
+	
+	void modRefs(mach_port_right_t right, mach_port_delta_t delta = 1)
+	{ check(mach_port_mod_refs(self(), mPort, right, delta)); }
+	
+	mach_port_urefs_t getRefs(mach_port_right_t right);
+
+	// port notification interface
+	mach_port_t requestNotify(mach_port_t notify, mach_msg_id_t type, mach_port_mscount_t sync = 1)
+	{
+		mach_port_t previous;
+		check(mach_port_request_notification(self(), mPort, type, sync, notify,
+			MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous));
+		return previous;
+	}
+	
+    IFDUMP(void dump(const char *name = NULL));
+	
+protected:
+	mach_port_t mPort;
+};
+
+
+//
+// Ports representing PortSets
+//
+class PortSet : public Port {
+public:
+	PortSet() { allocate(MACH_PORT_RIGHT_PORT_SET); }
+	~PortSet() { destroy(); }
+	
+	void operator += (const Port &port)
+	{ check(mach_port_move_member(self(), port, mPort)); }
+    
+    void operator -= (const Port &port)
+    { check(mach_port_move_member(self(), port, MACH_PORT_NULL)); }
+};
+
+
+//
+// Ports that are bootstrap ports
+//
+class Bootstrap : public Port {
+public:
+    Bootstrap() { check(task_get_bootstrap_port(mach_task_self(), &mPort)); }
+    Bootstrap(mach_port_t bootp) : Port(bootp) { }
+
+	mach_port_t checkIn(const char *name) const;
+	mach_port_t checkInOptional(const char *name) const;
+    
+	void registerAs(mach_port_t port, const char *name) const;
+    
+	mach_port_t lookup(const char *name) const;
+    mach_port_t lookupOptional(const char *name) const;
+    
+    Bootstrap subset(Port requestor);
+
+    IFDUMP(void dump());
+	
+private:
+	// officially, the register/lookup IPCs take an array of 128 characters (not a zero-end string)
+	mutable char nameBuffer[BOOTSTRAP_MAX_NAME_LEN];
+    
+protected:
+	char *Bootstrap::makeName(const char *s) const
+	{ return strncpy(nameBuffer, s, BOOTSTRAP_MAX_NAME_LEN); }
+};
+
+
+//
+// Ports that are Task Ports
+//
+class TaskPort : public Port {
+public:
+    TaskPort() { mPort = self(); }
+    TaskPort(const Port &p) { mPort = p; }
+    
+    Bootstrap bootstrap() const
+    { mach_port_t boot; check(task_get_bootstrap_port(mPort, &boot)); return boot; }
+    void bootstrap(Bootstrap boot)
+    { check(task_set_bootstrap_port(mPort, boot)); }
+
+    pid_t pid() const;
+    static TaskPort forPid(pid_t pid);
+};
+
+
+//
+// Ports that are are self-allocated and have receive rights
+//
+class ReceivePort : public Port {
+public:
+	ReceivePort() { allocate(); }
+	ReceivePort(const char *name, const Bootstrap &bootstrap);
+	~ReceivePort() { destroy(); }
+};
+
+
+//
+// A little stack utility for temporarily switching your bootstrap around.
+// Essentially, it restores your bootstrap port when it dies. Since the
+// "current bootstrap port" is a process-global item, this uses a global
+// zone of exclusion (aka critical region). There's no protection against
+// someone else calling the underlying system service, of course.
+//
+class StBootstrap {
+public:
+    StBootstrap(const Bootstrap &boot, const TaskPort &task = TaskPort());
+    ~StBootstrap();
+    
+private:
+    Bootstrap mOldBoot;
+    TaskPort mTask;
+    StLock<Mutex> locker;
+    static ModuleNexus<Mutex> critical; // critical region guard (of a sort)
+};
+
+
+//
+// Message buffers for Mach messages.
+// This class is for relatively simple uses.
+//
+class Message {
+public:
+    Message(void *buffer, size_t size);
+    Message(size_t size);
+    virtual ~Message();
+
+    operator mig_reply_error_t & () const	{ return *mBuffer; }
+    operator mach_msg_header_t & () const	{ return mBuffer->Head; }
+    operator mig_reply_error_t * () const	{ return mBuffer; }
+    operator mach_msg_header_t * () const	{ return &mBuffer->Head; }
+    operator NDR_record_t & () const		{ return mBuffer->NDR; }
+    
+    void *data() const						{ return mBuffer; }
+    size_t length() const					{ return mBuffer->Head.msgh_size; }
+    Port localPort() const					{ return mBuffer->Head.msgh_local_port; }
+    Port remotePort() const					{ return mBuffer->Head.msgh_remote_port; }
+    mach_msg_id_t msgId() const				{ return mBuffer->Head.msgh_id; }
+    mach_msg_bits_t bits() const			{ return mBuffer->Head.msgh_bits; }
+    kern_return_t returnCode() const		{ return mBuffer->RetCode; }
+    
+    void localPort(mach_port_t p)			{ mBuffer->Head.msgh_local_port = p; }
+    void remotePort(mach_port_t p)			{ mBuffer->Head.msgh_remote_port = p; }
+    
+public:
+    void send(mach_msg_option_t options = 0,
+        mach_msg_timeout_t timeout = MACH_MSG_TIMEOUT_NONE,
+        mach_port_name_t notify = MACH_PORT_NULL);
+    void receive(mach_port_t receivePort,
+        mach_msg_option_t options = 0,
+        mach_msg_timeout_t timeout = MACH_MSG_TIMEOUT_NONE,
+        mach_port_name_t notify = MACH_PORT_NULL);
+    void sendReceive(mach_port_t receivePort,
+        mach_msg_option_t options = 0,
+        mach_msg_timeout_t timeout = MACH_MSG_TIMEOUT_NONE,
+        mach_port_name_t notify = MACH_PORT_NULL);
+    
+    void destroy()		{ mach_msg_destroy(*this); }
+
+private:
+    mig_reply_error_t *mBuffer;
+    size_t mSize;
+    bool mRelease;
+};
+
+
+} // end namespace MachPlusPlus
+} // end namespace Security
+
+#endif //_H_MACHPP
diff --git a/cdsa/cdsa_utilities/mach_notify.c b/cdsa/cdsa_utilities/mach_notify.c
new file mode 100644
index 00000000..2b93adbc
--- /dev/null
+++ b/cdsa/cdsa_utilities/mach_notify.c
@@ -0,0 +1,560 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * IDENTIFICATION:
+ * stub generated Wed Mar 29 13:49:14 2000
+ * with a MiG generated Sat Feb 5 17:40:06 PST 2000 by root@salzburg
+ *
+ * NOTE: This file was originally generated by MIG, but has since been hand-massaged
+ * to the point where re-generating it is not advised.
+ */
+
+/* Module notify */
+
+#include <string.h>
+#include <mach/ndr.h>
+#include <mach/boolean.h>
+#include <mach/kern_return.h>
+#include <mach/notify.h>
+#include <mach/mach_types.h>
+#include <mach/message.h>
+#include <mach/mig_errors.h>
+#include <mach/port.h>
+
+#include <mach/std_types.h>
+
+#ifndef	mig_internal
+#define	mig_internal	static
+#endif	/* mig_internal */
+
+#ifndef	mig_external
+#define mig_external
+#endif	/* mig_external */
+
+#ifndef	TypeCheck
+#define	TypeCheck 0
+#endif	/* TypeCheck */
+
+#ifndef	LimitCheck
+#define	LimitCheck 0
+#endif	/* LimitCheck */
+
+#ifndef	min
+#define	min(a,b)  ( ((a) < (b))? (a): (b) )
+#endif	/* min */
+
+#ifndef	UseStaticTemplates
+#define	UseStaticTemplates	1
+#endif	/* UseStaticTemplates */
+
+#define _WALIGN_(x) (((x) + 3) & ~3)
+#define _WALIGNSZ_(x) _WALIGN_(sizeof(x))
+#ifndef	__DeclareRcvRpc
+#define	__DeclareRcvRpc(_NUM_, _NAME_)
+#endif	/* __DeclareRcvRpc */
+
+#ifndef	__BeforeRcvRpc
+#define	__BeforeRcvRpc(_NUM_, _NAME_)
+#endif	/* __BeforeRcvRpc */
+
+#ifndef	__AfterRcvRpc
+#define	__AfterRcvRpc(_NUM_, _NAME_)
+#endif	/* __AfterRcvRpc */
+
+#ifndef	__DeclareRcvSimple
+#define	__DeclareRcvSimple(_NUM_, _NAME_)
+#endif	/* __DeclareRcvSimple */
+
+#ifndef	__BeforeRcvSimple
+#define	__BeforeRcvSimple(_NUM_, _NAME_)
+#endif	/* __BeforeRcvSimple */
+
+#ifndef	__AfterRcvSimple
+#define	__AfterRcvSimple(_NUM_, _NAME_)
+#endif	/* __AfterRcvSimple */
+
+#define novalue void
+
+#define msgh_request_port	msgh_local_port
+#define MACH_MSGH_BITS_REQUEST(bits)	MACH_MSGH_BITS_LOCAL(bits)
+#define msgh_reply_port		msgh_remote_port
+#define MACH_MSGH_BITS_REPLY(bits)	MACH_MSGH_BITS_REMOTE(bits)
+
+#define MIG_RETURN_ERROR(X, code)	{\
+				((mig_reply_error_t *)X)->RetCode = code;\
+				((mig_reply_error_t *)X)->NDR = NDR_record;\
+				return;\
+				}
+
+/* typedefs for all replies */
+
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		kern_return_t RetCode;
+	} __Reply__mach_notify_port_deleted_t;
+
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		kern_return_t RetCode;
+	} __Reply__mach_notify_port_destroyed_t;
+
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		kern_return_t RetCode;
+	} __Reply__mach_notify_no_senders_t;
+
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		kern_return_t RetCode;
+	} __Reply__mach_notify_send_once_t;
+
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		kern_return_t RetCode;
+	} __Reply__mach_notify_dead_name_t;
+
+
+/* Forward Declarations */
+
+
+mig_internal novalue _Xmach_notify_port_deleted
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
+
+mig_internal novalue _Xmach_notify_port_destroyed
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
+
+mig_internal novalue _Xmach_notify_no_senders
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
+
+mig_internal novalue _Xmach_notify_send_once
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
+
+mig_internal novalue _Xmach_notify_dead_name
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
+
+
+/* SimpleRoutine mach_notify_port_deleted */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t cdsa_mach_notify_port_deleted
+(
+	mach_port_t notify,
+	mach_port_name_t name
+);
+
+/* SimpleRoutine mach_notify_port_deleted */
+mig_internal novalue _Xmach_notify_port_deleted
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
+{
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		mach_port_name_t name;
+		mach_msg_trailer_t trailer;
+	} Request;
+
+	typedef __Reply__mach_notify_port_deleted_t Reply;
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		mach_port_name_t name;
+	} __Request;
+
+	/*
+	 * typedef struct {
+	 * 	mach_msg_header_t Head;
+	 * 	NDR_record_t NDR;
+	 * 	kern_return_t RetCode;
+	 * } mig_reply_error_t;
+	 */
+
+	register Request *In0P = (Request *) InHeadP;
+	register Reply *OutP = (Reply *) OutHeadP;
+	__DeclareRcvSimple(65, "mach_notify_port_deleted")
+	__BeforeRcvSimple(65, "mach_notify_port_deleted")
+#if	TypeCheck
+	if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||
+	    (In0P->Head.msgh_size != sizeof(__Request)))
+		{ MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); }
+#endif	/* TypeCheck */
+
+	OutP->RetCode = cdsa_mach_notify_port_deleted(In0P->Head.msgh_request_port, In0P->name);
+	__AfterRcvSimple(65, "mach_notify_port_deleted")
+}
+
+/* SimpleRoutine mach_notify_port_destroyed */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t cdsa_mach_notify_port_destroyed
+(
+	mach_port_t notify,
+	mach_port_t rights
+);
+
+/* SimpleRoutine mach_notify_port_destroyed */
+mig_internal novalue _Xmach_notify_port_destroyed
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
+{
+	typedef struct {
+		mach_msg_header_t Head;
+		/* start of the kernel processed data */
+		mach_msg_body_t msgh_body;
+		mach_msg_port_descriptor_t rights;
+		/* end of the kernel processed data */
+		mach_msg_trailer_t trailer;
+	} Request;
+
+	typedef __Reply__mach_notify_port_destroyed_t Reply;
+	typedef struct {
+		mach_msg_header_t Head;
+		/* start of the kernel processed data */
+		mach_msg_body_t msgh_body;
+		mach_msg_port_descriptor_t rights;
+		/* end of the kernel processed data */
+	} __Request;
+
+	/*
+	 * typedef struct {
+	 * 	mach_msg_header_t Head;
+	 * 	NDR_record_t NDR;
+	 * 	kern_return_t RetCode;
+	 * } mig_reply_error_t;
+	 */
+
+	register Request *In0P = (Request *) InHeadP;
+	register Reply *OutP = (Reply *) OutHeadP;
+	__DeclareRcvSimple(69, "mach_notify_port_destroyed")
+	__BeforeRcvSimple(69, "mach_notify_port_destroyed")
+#if	TypeCheck
+	if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||
+	    (In0P->msgh_body.msgh_descriptor_count != 1) ||
+	    (In0P->Head.msgh_size != sizeof(__Request)))
+		{ MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); }
+#endif	/* TypeCheck */
+
+#if	TypeCheck
+	if (In0P->rights.type != MACH_MSG_PORT_DESCRIPTOR || 
+	    In0P->rights.disposition != MACH_MSG_TYPE_MOVE_RECEIVE)
+		{ MIG_RETURN_ERROR(OutP, MIG_TYPE_ERROR); }
+#endif	/* TypeCheck */
+
+	OutP->RetCode = cdsa_mach_notify_port_destroyed(In0P->Head.msgh_request_port, In0P->rights.name);
+	__AfterRcvSimple(69, "mach_notify_port_destroyed")
+}
+
+/* SimpleRoutine mach_notify_no_senders */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t cdsa_mach_notify_no_senders
+(
+	mach_port_t notify,
+	mach_port_mscount_t mscount
+);
+
+/* SimpleRoutine mach_notify_no_senders */
+mig_internal novalue _Xmach_notify_no_senders
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
+{
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		mach_port_mscount_t mscount;
+		mach_msg_trailer_t trailer;
+	} Request;
+
+	typedef __Reply__mach_notify_no_senders_t Reply;
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		mach_port_mscount_t mscount;
+	} __Request;
+
+	/*
+	 * typedef struct {
+	 * 	mach_msg_header_t Head;
+	 * 	NDR_record_t NDR;
+	 * 	kern_return_t RetCode;
+	 * } mig_reply_error_t;
+	 */
+
+	register Request *In0P = (Request *) InHeadP;
+	register Reply *OutP = (Reply *) OutHeadP;
+	__DeclareRcvSimple(70, "mach_notify_no_senders")
+	__BeforeRcvSimple(70, "mach_notify_no_senders")
+#if	TypeCheck
+	if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||
+	    (In0P->Head.msgh_size != sizeof(__Request)))
+		{ MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); }
+#endif	/* TypeCheck */
+
+	OutP->RetCode = cdsa_mach_notify_no_senders(In0P->Head.msgh_request_port, In0P->mscount);
+	__AfterRcvSimple(70, "mach_notify_no_senders")
+}
+
+/* SimpleRoutine mach_notify_send_once */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t cdsa_mach_notify_send_once
+(
+	mach_port_t notify
+);
+
+/* SimpleRoutine mach_notify_send_once */
+mig_internal novalue _Xmach_notify_send_once
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
+{
+	typedef struct {
+		mach_msg_header_t Head;
+		mach_msg_trailer_t trailer;
+	} Request;
+
+	typedef __Reply__mach_notify_send_once_t Reply;
+	typedef struct {
+		mach_msg_header_t Head;
+	} __Request;
+
+	/*
+	 * typedef struct {
+	 * 	mach_msg_header_t Head;
+	 * 	NDR_record_t NDR;
+	 * 	kern_return_t RetCode;
+	 * } mig_reply_error_t;
+	 */
+
+	register Request *In0P = (Request *) InHeadP;
+	register Reply *OutP = (Reply *) OutHeadP;
+	__DeclareRcvSimple(71, "mach_notify_send_once")
+	__BeforeRcvSimple(71, "mach_notify_send_once")
+#if	TypeCheck
+	if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||
+	    (In0P->Head.msgh_size != sizeof(__Request)))
+		{ MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); }
+#endif	/* TypeCheck */
+
+	OutP->RetCode = cdsa_mach_notify_send_once(In0P->Head.msgh_request_port);
+	__AfterRcvSimple(71, "mach_notify_send_once")
+}
+
+/* SimpleRoutine mach_notify_dead_name */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t cdsa_mach_notify_dead_name
+(
+	mach_port_t notify,
+	mach_port_name_t name
+);
+
+/* SimpleRoutine mach_notify_dead_name */
+mig_internal novalue _Xmach_notify_dead_name
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
+{
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		mach_port_name_t name;
+		mach_msg_trailer_t trailer;
+	} Request;
+
+	typedef __Reply__mach_notify_dead_name_t Reply;
+	typedef struct {
+		mach_msg_header_t Head;
+		NDR_record_t NDR;
+		mach_port_name_t name;
+	} __Request;
+
+	/*
+	 * typedef struct {
+	 * 	mach_msg_header_t Head;
+	 * 	NDR_record_t NDR;
+	 * 	kern_return_t RetCode;
+	 * } mig_reply_error_t;
+	 */
+
+	register Request *In0P = (Request *) InHeadP;
+	register Reply *OutP = (Reply *) OutHeadP;
+	__DeclareRcvSimple(72, "mach_notify_dead_name")
+	__BeforeRcvSimple(72, "mach_notify_dead_name")
+#if	TypeCheck
+	if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||
+	    (In0P->Head.msgh_size != sizeof(__Request)))
+		{ MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); }
+#endif	/* TypeCheck */
+
+	OutP->RetCode = cdsa_mach_notify_dead_name(In0P->Head.msgh_request_port, In0P->name);
+	__AfterRcvSimple(72, "mach_notify_dead_name")
+}
+
+/* union of all replies */
+
+union __ReplyUnion {
+	__Reply__mach_notify_port_deleted_t Reply_mach_notify_port_deleted;
+	__Reply__mach_notify_port_destroyed_t Reply_mach_notify_port_destroyed;
+	__Reply__mach_notify_no_senders_t Reply_mach_notify_no_senders;
+	__Reply__mach_notify_send_once_t Reply_mach_notify_send_once;
+	__Reply__mach_notify_dead_name_t Reply_mach_notify_dead_name;
+};
+
+
+extern boolean_t notify_server(
+		mach_msg_header_t *InHeadP,
+		mach_msg_header_t *OutHeadP);
+
+extern mig_routine_t notify_server_routine(
+		mach_msg_header_t *InHeadP);
+
+
+/* Description of this subsystem, for use in direct RPC */
+const struct cdsa_notify_subsystem {
+	struct subsystem *	subsystem;	/* Reserved for system use */
+	mach_msg_id_t	start;	/* Min routine number */
+	mach_msg_id_t	end;	/* Max routine number + 1 */
+	unsigned int	maxsize;	/* Max msg size */
+	vm_address_t	base_addr;	/* Base ddress */
+	struct routine_descriptor	/*Array of routine descriptors */
+		routine[9];
+	struct routine_arg_descriptor	/*Array of arg descriptors */
+		arg_descriptor[6];
+} cdsa_notify_subsystem = {
+#define ARGDES(n) \
+    (struct routine_arg_descriptor *)&cdsa_notify_subsystem.arg_descriptor[n]
+	0,
+	64,
+	73,
+	sizeof(union __ReplyUnion),
+	(vm_address_t)&cdsa_notify_subsystem,
+	{
+		{0, 0, 0, 0, 0, 0},
+          { (mig_impl_routine_t) cdsa_mach_notify_port_deleted,
+            (mig_stub_routine_t) _Xmach_notify_port_deleted, 2, 1, ARGDES(0), sizeof(__Reply__mach_notify_port_deleted_t) },
+		{0, 0, 0, 0, 0, 0},
+		{0, 0, 0, 0, 0, 0},
+		{0, 0, 0, 0, 0, 0},
+          { (mig_impl_routine_t) cdsa_mach_notify_port_destroyed,
+            (mig_stub_routine_t) _Xmach_notify_port_destroyed, 2, 2, ARGDES(1), sizeof(__Reply__mach_notify_port_destroyed_t) },
+          { (mig_impl_routine_t) cdsa_mach_notify_no_senders,
+            (mig_stub_routine_t) _Xmach_notify_no_senders, 2, 1, ARGDES(3), sizeof(__Reply__mach_notify_no_senders_t) },
+          { (mig_impl_routine_t) cdsa_mach_notify_send_once,
+            (mig_stub_routine_t) _Xmach_notify_send_once, 1, 1, ARGDES(4), sizeof(__Reply__mach_notify_send_once_t) },
+          { (mig_impl_routine_t) cdsa_mach_notify_dead_name,
+            (mig_stub_routine_t) _Xmach_notify_dead_name, 2, 1, ARGDES(5), sizeof(__Reply__mach_notify_dead_name_t) },
+	},
+
+	{
+            {
+                0 | MACH_RPC_PORT  | MACH_RPC_MOVE_SEND_ONCE,
+                4,
+                1,
+                0,
+            },
+            {
+                0 | MACH_RPC_PORT  | MACH_RPC_MOVE_SEND_ONCE,
+                4,
+                1,
+                0,
+            },
+            {
+                0 | MACH_RPC_PORT  | MACH_RPC_IN ,
+                4,
+                1,
+                4,
+            },
+            {
+                0 | MACH_RPC_PORT  | MACH_RPC_MOVE_SEND_ONCE,
+                4,
+                1,
+                0,
+            },
+            {
+                0 | MACH_RPC_PORT  | MACH_RPC_MOVE_SEND_ONCE,
+                4,
+                1,
+                0,
+            },
+            {
+                0 | MACH_RPC_PORT  | MACH_RPC_MOVE_SEND_ONCE,
+                4,
+                1,
+                0,
+            },
+	},
+
+};
+
+mig_external boolean_t cdsa_notify_server
+	(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
+{
+	/*
+	 * typedef struct {
+	 * 	mach_msg_header_t Head;
+	 * 	NDR_record_t NDR;
+	 * 	kern_return_t RetCode;
+	 * } mig_reply_error_t;
+	 */
+
+	register mig_routine_t routine;
+
+	OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0);
+	OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port;
+	/* Minimal size: routine() will update it if different */
+	OutHeadP->msgh_size = sizeof(mig_reply_error_t);
+	OutHeadP->msgh_local_port = MACH_PORT_NULL;
+	OutHeadP->msgh_id = InHeadP->msgh_id + 100;
+
+	if ((InHeadP->msgh_id > 72) || (InHeadP->msgh_id < 64) ||
+	    ((routine = cdsa_notify_subsystem.routine[InHeadP->msgh_id - 64].stub_routine) == 0)) {
+		((mig_reply_error_t *)OutHeadP)->NDR = NDR_record;
+		((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID;
+		return FALSE;
+	}
+	(*routine) (InHeadP, OutHeadP);
+	return TRUE;
+}
+
+mig_external mig_routine_t cdsa_notify_server_routine
+	(mach_msg_header_t *InHeadP)
+{
+	register int msgh_id;
+
+	msgh_id = InHeadP->msgh_id - 64;
+
+	if ((msgh_id > 8) || (msgh_id < 0))
+		return 0;
+
+	return cdsa_notify_subsystem.routine[msgh_id].stub_routine;
+}
diff --git a/cdsa/cdsa_utilities/mach_notify.h b/cdsa/cdsa_utilities/mach_notify.h
new file mode 100644
index 00000000..344d5bad
--- /dev/null
+++ b/cdsa/cdsa_utilities/mach_notify.h
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+
+#ifndef	_notify_user_
+#define	_notify_user_
+
+/* Module notify */
+
+#include <string.h>
+#include <mach/ndr.h>
+#include <mach/boolean.h>
+#include <mach/kern_return.h>
+#include <mach/notify.h>
+#include <mach/mach_types.h>
+#include <mach/message.h>
+#include <mach/mig_errors.h>
+#include <mach/port.h>
+
+#ifdef AUTOTEST
+#ifndef FUNCTION_PTR_T
+#define FUNCTION_PTR_T
+typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t);
+typedef struct {
+        char            *name;
+        function_ptr_t  function;
+} function_table_entry;
+typedef function_table_entry 	*function_table_t;
+#endif /* FUNCTION_PTR_T */
+#endif /* AUTOTEST */
+
+#ifndef	notify_MSG_COUNT
+#define	notify_MSG_COUNT	9
+#endif	/* notify_MSG_COUNT */
+
+#include <mach/std_types.h>
+
+#ifdef __BeforeMigUserHeader
+__BeforeMigUserHeader
+#endif /* __BeforeMigUserHeader */
+
+
+/* SimpleRoutine mach_notify_port_deleted */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t mach_notify_port_deleted
+(
+	mach_port_t notify,
+	mach_port_name_t name
+);
+
+/* SimpleRoutine mach_notify_port_destroyed */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t mach_notify_port_destroyed
+(
+	mach_port_t notify,
+	mach_port_t rights,
+	mach_msg_type_name_t rightsPoly
+);
+
+/* SimpleRoutine mach_notify_no_senders */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t mach_notify_no_senders
+(
+	mach_port_t notify,
+	mach_port_mscount_t mscount
+);
+
+/* SimpleRoutine mach_notify_send_once */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t mach_notify_send_once
+(
+	mach_port_t notify
+);
+
+/* SimpleRoutine mach_notify_dead_name */
+#ifdef	mig_external
+mig_external
+#else
+extern
+#endif	/* mig_external */
+kern_return_t mach_notify_dead_name
+(
+	mach_port_t notify,
+	mach_port_name_t name
+);
+
+#ifndef subsystem_to_name_map_notify
+#define subsystem_to_name_map_notify \
+    { "mach_notify_port_deleted", 65 },\
+    { "mach_notify_port_destroyed", 69 },\
+    { "mach_notify_no_senders", 70 },\
+    { "mach_notify_send_once", 71 },\
+    { "mach_notify_dead_name", 72 }
+#endif
+
+#ifdef __AfterMigUserHeader
+__AfterMigUserHeader
+#endif /* __AfterMigUserHeader */
+
+#endif	 /* _notify_user_ */
diff --git a/cdsa/cdsa_utilities/machrunloopserver.cpp b/cdsa/cdsa_utilities/machrunloopserver.cpp
new file mode 100644
index 00000000..93fc8f29
--- /dev/null
+++ b/cdsa/cdsa_utilities/machrunloopserver.cpp
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+
+
+//
+// machrunloopserver - C++ shell for writing Mach 3 servers called by CFRunLoop
+//
+#include "machrunloopserver.h"
+#include <mach/mach_error.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/debugging.h>
+
+
+namespace Security {
+namespace MachPlusPlus {
+
+
+//
+// Generic Mach server
+//
+MachRunLoopServer::MachRunLoopServer(const char *name) : MachServer(name)
+{
+}
+
+MachRunLoopServer::MachRunLoopServer(const char *name, const Bootstrap &boot)
+: MachServer(name, boot)
+{
+}
+
+void MachRunLoopServer::run(size_t bufferSize, mach_msg_options_t options)
+{
+	// allocate reply buffer (well, try)
+	replyBuffer = CssmAllocator::standard().malloc<mach_msg_header_t>(bufferSize);
+
+	// Now do the CFRunLoop tango...
+	runLoop = CFRunLoopGetCurrent();
+	CFRef<CFMachPortRef> cfPort = CFMachPortCreateWithPort(NULL, mServerPort, cfCallback,
+        NULL, NULL);
+	runLoopSource =
+		CFMachPortCreateRunLoopSource(NULL, cfPort, 10);	//@@@ no idea what order is good
+	if (!runLoop || !runLoopSource || !cfPort)
+		CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	//@@@ $#!!& CF non-diagnostics!
+	CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
+	
+	// we are it!
+	perThread().server = this;
+}
+
+MachRunLoopServer::~MachRunLoopServer()
+{
+	// remove our runloop source
+	CFRunLoopRemoveSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
+	CFRelease(runLoopSource);
+	
+	// delete the reply buffer
+	CssmAllocator::standard().free(replyBuffer);
+    
+    // no longer tagged
+    perThread().server = NULL;
+	
+	// our MachServer parent class will clean up the ports and deregister from our bootstrap
+}
+
+
+//
+// Block/unblock new request reception to serialize the request queue
+//
+void MachRunLoopServer::blockNewRequests(bool block)
+{
+	if (block) {
+		CFRunLoopRemoveSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
+		debug("machsrv", "disabled request reception");
+	} else {
+		CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
+		debug("machsrv", "enabled request reception");
+	}
+}
+
+
+//
+// Add secondary ports to receive on
+//
+void MachRunLoopServer::alsoListenOn(Port port)
+{
+	CFRef<CFMachPortRef> cfPort = CFMachPortCreateWithPort(NULL, port, cfCallback,
+        NULL, NULL);
+	CFRef<CFRunLoopSourceRef> source =
+		CFMachPortCreateRunLoopSource(NULL, cfPort, 10);	//@@@ no idea what order is good
+	CFRunLoopAddSource(runLoop, source, kCFRunLoopDefaultMode);
+	debug("machsrv", "also receiving from port %d", port.port());
+}
+
+void MachRunLoopServer::stopListenOn(Port port)
+{
+	CFRef<CFMachPortRef> cfPort = CFMachPortCreateWithPort(NULL, port, cfCallback,
+        NULL, NULL);
+	CFRef<CFRunLoopSourceRef> source =
+		CFMachPortCreateRunLoopSource(NULL, cfPort, 10);	//@@@ no idea what order is good
+	CFRunLoopRemoveSource(runLoop, source, kCFRunLoopDefaultMode);
+	debug("machsrv", "no longer receiving from port %d", port.port());
+}
+
+
+//
+// Handle dead-port notifications.
+// Since we don't actually run our own runloop here, we can't well use standard
+// notifications to our own server port. So we use a CFMachPort facility instead.
+//
+void MachRunLoopServer::notifyIfDead(Port port) const
+{
+	//@@@ not clear how to deal with CFRetainCount of cfPort here
+	//    will CF clean up the cfPort when it dies? Or do we have to keep a set?
+	CFMachPortRef cfPort = CFMachPortCreateWithPort(NULL, port, NULL, NULL, NULL);
+	CFMachPortSetInvalidationCallBack(cfPort, cfInvalidateCallback);
+}
+
+void MachRunLoopServer::cfInvalidateCallback(CFMachPortRef cfPort, void *)
+{
+	active().notifyDeadName(CFMachPortGetPort(cfPort));
+}
+
+
+//
+// The callback triggered from CFRunLoop
+//
+void MachRunLoopServer::cfCallback(CFMachPortRef port, void *msg, CFIndex, void *)
+{
+	active().oneRequest(reinterpret_cast<mach_msg_header_t *>(msg));
+}
+
+void MachRunLoopServer::oneRequest(mach_msg_header_t *request)
+{
+	if (!handle(request, replyBuffer)) {
+		// MIG dispatch did not recognize the request. Ignore/Retry/Fail? :-)
+		//@@@ Should send an error reply back here, I suppose. Later...
+		debug("machrls", "MachRunLoopServer dispatch failed");
+		return;
+	}
+	
+	// MIG dispatch handled the call. Send reply back to caller.
+	// This boilerplate stolen from mach_msg_server, since MIG can't seem to
+	// generate send-only code for replies (without explicit simpleroutines).
+	if (kern_return_t err =	mach_msg_overwrite_trap(replyBuffer,
+		(MACH_MSGH_BITS_REMOTE(replyBuffer->msgh_bits) == MACH_MSG_TYPE_MOVE_SEND_ONCE) ?
+		MACH_SEND_MSG :	MACH_SEND_MSG|MACH_SEND_TIMEOUT,
+		replyBuffer->msgh_size, 0, MACH_PORT_NULL,
+		0, MACH_PORT_NULL, (mach_msg_header_t *) 0, 0)) {
+		//@@@ should at least clean up resources here, I suppose.
+		debug("machsrv", "RunloopServer cannot post reply: %s", mach_error_string(err));
+		active().releaseDeferredAllocations();
+		return;
+	}
+	active().releaseDeferredAllocations();
+	return;
+}
+
+
+} // end namespace MachPlusPlus
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/machrunloopserver.h b/cdsa/cdsa_utilities/machrunloopserver.h
new file mode 100644
index 00000000..d0ba5fd9
--- /dev/null
+++ b/cdsa/cdsa_utilities/machrunloopserver.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+
+//
+// machrunloopserver - C++ shell for writing Mach 3 servers called by CFRunLoop.
+//
+// Note that this is a subclass of MachServer and tries to preserve its interface,
+// so you can switch back-and-forth between them with a minimum of fuss.
+// Timers are not currently implemented; they're not that hard to add if you need them.
+//
+#ifndef _H_MACHRUNLOOPSERVER
+#define _H_MACHRUNLOOPSERVER
+
+#include <Security/machserver.h>
+#include <CoreFoundation/CFRunLoop.h>
+#include <CoreFoundation/CFMachPort.h>
+
+
+namespace Security
+{
+
+namespace MachPlusPlus
+{
+
+//
+// Mach server object
+//
+class MachRunLoopServer : public MachServer {
+public:
+	MachRunLoopServer(const char *name);
+	MachRunLoopServer(const char *name, const Bootstrap &boot);
+	virtual ~MachRunLoopServer();
+
+	void run(size_t maxSize = 4096, mach_msg_options_t options = 0);
+
+	static MachRunLoopServer &active()
+	{ return safer_cast<MachRunLoopServer &>(MachServer::active()); }
+	
+	void notifyIfDead(Port port) const;
+	
+	void blockNewRequests(bool block = true);
+
+	void alsoListenOn(Port port);
+	void stopListenOn(Port port);
+
+protected:
+    void setup(const char *name, size_t bufferSize);
+	static void cfCallback(CFMachPortRef port, void *msg, CFIndex size, void *info);
+	static void cfInvalidateCallback(CFMachPortRef port, void *info);
+	void oneRequest(mach_msg_header_t *request);
+	
+private:
+	CFRunLoopRef runLoop;
+	CFRunLoopSourceRef runLoopSource;
+	
+	mach_msg_header_t *replyBuffer;
+};
+
+
+} // end namespace MachPlusPlus
+
+} // end namespace Security
+
+#endif //_H_MACHRUNLOOPSERVER
diff --git a/cdsa/cdsa_utilities/machserver.cpp b/cdsa/cdsa_utilities/machserver.cpp
new file mode 100644
index 00000000..408ac91b
--- /dev/null
+++ b/cdsa/cdsa_utilities/machserver.cpp
@@ -0,0 +1,472 @@
+/*
+ * 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.
+ */
+
+
+//
+// machserver - C++ shell for writing Mach 3 servers
+//
+#include "machserver.h"
+#include <servers/bootstrap.h>
+#include <mach/kern_return.h>
+#include <mach/message.h>
+#include <mach/mig_errors.h>
+#include "mach_notify.h"
+#include <Security/debugging.h>
+
+#if defined(USECFCURRENTTIME)
+# include <CoreFoundation/CFDate.h>
+#else
+# include <sys/time.h>
+#endif
+
+namespace Security {
+namespace MachPlusPlus {
+
+
+//
+// Global per-thread information
+//
+ModuleNexus< ThreadNexus<MachServer::PerThread> > MachServer::thread;
+
+
+//
+// Create a server object.
+// The resulting object is not "active", and any number of server objects
+// can be in this "prepared" state at the same time.
+//
+MachServer::MachServer(const char *name)
+: mServerPort(name, bootstrap)
+{ setup(name); }
+
+MachServer::MachServer(const char *name, const Bootstrap &boot)
+: bootstrap(boot), mServerPort(name, bootstrap)
+{ setup(name); }
+
+void MachServer::setup(const char *name)
+{
+	debug("machsrv", "%p preparing service for \"%s\"", this, name);
+	workerTimeout = 60 * 2;	// 2 minutes default timeout
+	maxWorkerCount = 100;	// sanity check limit
+    
+    mPortSet += mServerPort;
+}
+
+MachServer::~MachServer()
+{
+	// The ReceivePort members will clean themselves up.
+	// The bootstrap server will clear us from its map when our receive port dies.
+	debug("machsrv", "%p destroyed", this);
+}
+
+
+//
+// Utility access
+//
+void MachServer::notifyIfDead(Port port) const
+{
+	port.requestNotify(mServerPort, MACH_NOTIFY_DEAD_NAME, true);
+}
+
+
+//
+// Initiate service.
+// This call will take control of the current thread and use it to service
+// incoming requests. The thread will not be released until an error happens.
+// We may also be creating additional threads to service concurrent requests
+// as appropriate.
+// @@@ Additional threads are not being reaped at this point.
+// @@@ Msg-errors in additional threads are not acted upon.
+//
+void MachServer::run(size_t maxSize, mach_msg_options_t options)
+{
+	// establish server-global (thread-shared) parameters
+	mMaxSize = maxSize;
+	mMsgOptions = options;
+	
+	// establish the thread pool state
+	// (don't need managerLock since we're the only thread as of yet)
+	idleCount = workerCount = 1;
+	nextCheckTime = Time::now() + workerTimeout;
+	leastIdleWorkers = 1;
+	highestWorkerCount = 1;
+	
+	// run server loop in initial (immortal) thread
+	runServerThread(false);
+	
+	// primary server thread exited somehow (not currently possible)
+	assert(false);
+}
+
+
+//
+// This is the core of a server thread at work. It takes over the thread until
+// something makes it exit normally. Then it returns. Errors cause exceptions.
+// This code is loosely based on mach_msg_server.c, but is drifting away for
+// various reasons of flexibility and resilience.
+//
+extern "C" boolean_t cdsa_notify_server(mach_msg_header_t *in, mach_msg_header_t *out);
+
+void MachServer::runServerThread(bool doTimeout)
+{
+	// allocate request/reply buffers
+    Message bufRequest(mMaxSize);
+    Message bufReply(mMaxSize);
+	
+	// all exits from runServerThread are through exceptions or "goto exit"
+	try {
+		// register as a worker thread
+		debug("machsrv", "%p starting service on port %d", this, int(mServerPort));
+		perThread().server = this;
+
+		for (;;) {
+			// process all pending timers
+			while (processTimer()) ;
+		
+			// check for worker idle timeout
+			{	StLock<Mutex> _(managerLock);
+				// record idle thread low-water mark in scan interval
+				if (idleCount < leastIdleWorkers)
+					leastIdleWorkers = idleCount;
+				
+				// perform self-timeout processing
+				if (doTimeout) {
+					if (workerCount > maxWorkerCount) {
+						debug("machsrv", "%p too many threads; reaping immediately", this);
+						break;
+					}
+					Time::Absolute rightNow = Time::now();
+					if (rightNow >= nextCheckTime) {	// reaping period complete; process
+						uint32 idlers = leastIdleWorkers;
+						debug("machsrv", "%p end of reaping period: %ld (min) idle of %ld total",
+							this, idlers, workerCount);
+						nextCheckTime = rightNow + workerTimeout;
+						leastIdleWorkers = INT_MAX;
+						if (idlers > 1)
+							break;
+					}
+				}
+			}
+            
+            // release deferred-release memory
+            releaseDeferredAllocations();
+			
+			// determine next timeout, or zero for infinity
+            bool indefinite = false;
+			Time::Interval timeout;
+			{	StLock<Mutex> _(managerLock);
+				if (timers.empty()) {
+                    if (doTimeout)
+                        timeout = workerTimeout;
+                    else
+                        indefinite = true;
+				} else {
+					timeout = doTimeout 
+						? min(workerTimeout, timers.next() - Time::now()) 
+						: timers.next() - Time::now();
+                }
+			}
+			
+			// receive next IPC request (or wait for timeout)
+			switch (mach_msg_return_t mr = indefinite ?
+				mach_msg_overwrite_trap(bufRequest,
+					MACH_RCV_MSG | mMsgOptions,
+					0, mMaxSize, mPortSet,
+					MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL,
+					(mach_msg_header_t *) 0, 0)
+                    :
+				mach_msg_overwrite_trap(bufRequest,
+					MACH_RCV_MSG | MACH_RCV_TIMEOUT | mMsgOptions,
+					0, mMaxSize, mPortSet,
+					mach_msg_timeout_t(timeout.mSeconds()), MACH_PORT_NULL,
+					(mach_msg_header_t *) 0, 0)) {
+			case MACH_MSG_SUCCESS:
+				// process received request message below
+				break;
+			case MACH_RCV_TIMED_OUT:
+				// back to top for time-related processing
+				continue;
+			case MACH_RCV_TOO_LARGE:
+				// the kernel destroyed the request
+				continue;
+            case MACH_RCV_INTERRUPTED:
+                // receive interrupted, try again
+                continue;
+			default:
+				Error::throwMe(mr);
+			}
+			
+			// process received message
+			if (bufRequest.msgId() >= MACH_NOTIFY_FIRST &&
+				bufRequest.msgId() <= MACH_NOTIFY_LAST) {
+				// mach kernel notification message
+				// we assume this is quick, so no thread arbitration here
+				cdsa_notify_server(bufRequest, bufReply);
+			} else {
+				// normal request message
+				{ StLock<Mutex> _(managerLock); idleCount--; }
+				debug("machsrvreq",
+                    "servicing port %d request id=%d",
+                    bufRequest.localPort().port(), bufRequest.msgId());
+                if (bufRequest.localPort() == mServerPort) {	// primary
+                    handle(bufRequest, bufReply);
+                } else {
+                    for (HandlerSet::const_iterator it = mHandlers.begin();
+                            it != mHandlers.end(); it++)
+                        if (bufRequest.localPort() == (*it)->port())
+                            (*it)->handle(bufRequest, bufReply);
+                }
+				debug("machsrvreq", "request complete");
+				{ StLock<Mutex> _(managerLock); idleCount++; }
+			}
+
+			// process reply generated by handler
+            if (!(bufReply.bits() & MACH_MSGH_BITS_COMPLEX) &&
+                bufReply.returnCode() != KERN_SUCCESS) {
+                    if (bufReply.returnCode() == MIG_NO_REPLY)
+						continue;
+                    // don't destroy the reply port right, so we can send an error message
+                    bufRequest.remotePort(MACH_PORT_NULL);
+                    mach_msg_destroy(bufRequest);
+            }
+
+            if (bufReply.remotePort() == MACH_PORT_NULL) {
+                // no reply port, so destroy the reply
+                if (bufReply.bits() & MACH_MSGH_BITS_COMPLEX)
+                    bufReply.destroy();
+                continue;
+            }
+
+            /*
+             *  We don't want to block indefinitely because the client
+             *  isn't receiving messages from the reply port.
+             *  If we have a send-once right for the reply port, then
+             *  this isn't a concern because the send won't block.
+             *  If we have a send right, we need to use MACH_SEND_TIMEOUT.
+             *  To avoid falling off the kernel's fast RPC path unnecessarily,
+             *  we only supply MACH_SEND_TIMEOUT when absolutely necessary.
+             */
+			switch (mach_msg_return_t mr = mach_msg_overwrite_trap(bufReply,
+                          (MACH_MSGH_BITS_REMOTE(bufReply.bits()) ==
+                                                MACH_MSG_TYPE_MOVE_SEND_ONCE) ?
+                          MACH_SEND_MSG | mMsgOptions :
+                          MACH_SEND_MSG | MACH_SEND_TIMEOUT | mMsgOptions,
+                          bufReply.length(), 0, MACH_PORT_NULL,
+                          0, MACH_PORT_NULL, NULL, 0)) {
+			case MACH_MSG_SUCCESS:
+				break;
+			case MACH_SEND_INVALID_DEST:
+			case MACH_SEND_TIMED_OUT:
+				/* the reply can't be delivered, so destroy it */
+				mach_msg_destroy(bufRequest);
+				break;
+			default:
+				Error::throwMe(mr);
+			}
+        }
+		perThread().server = NULL;
+		debug("machsrv", "%p ending service on port %d", this, int(mServerPort));
+		
+	} catch (...) {
+		perThread().server = NULL;
+		debug("machsrv", "%p aborted by exception (port %d)", this, int(mServerPort));
+		throw;
+	}
+}
+
+
+//
+// Manage subsidiary ports
+//
+void MachServer::add(Handler &handler)
+{
+    assert(mHandlers.find(&handler) == mHandlers.end());
+    assert(handler.port() != MACH_PORT_NULL);
+    mHandlers.insert(&handler);
+    mPortSet += handler.port();
+}
+
+void MachServer::remove(Handler &handler)
+{
+    assert(mHandlers.find(&handler) != mHandlers.end());
+    mHandlers.erase(&handler);
+    mPortSet -= handler.port();
+}
+
+
+//
+// Implement a Handler that sends no reply
+//
+boolean_t MachServer::NoReplyHandler::handle(mach_msg_header_t *in, mach_msg_header_t *out)
+{
+    // set up reply message to be valid (enough) and read "do not send reply"
+    out->msgh_bits = 0;
+    out->msgh_remote_port = MACH_PORT_NULL;
+    out->msgh_size = sizeof(mig_reply_error_t);
+    ((mig_reply_error_t *)out)->RetCode = MIG_NO_REPLY;
+    
+    // call input-only handler
+    return handle(in);
+}
+
+
+//
+// Register a memory block for deferred release.
+//
+void MachServer::releaseWhenDone(CssmAllocator &alloc, void *memory)
+{
+    if (memory) {
+        set<Allocation> &releaseSet = perThread().deferredAllocations;
+        assert(releaseSet.find(Allocation(memory, alloc)) == releaseSet.end());
+        debug("machsrvmem", "%p register %p for release with %p",
+            this, memory, &alloc);
+        releaseSet.insert(Allocation(memory, alloc));
+    }
+}
+
+
+//
+// Run through the accumulated deferred allocations and release them.
+// This is done automatically on every pass through the server loop;
+// it must be called by subclasses that implement their loop in some
+// other way.
+// @@@X Needs to be thread local
+//
+void MachServer::releaseDeferredAllocations()
+{
+    set<Allocation> &releaseSet = perThread().deferredAllocations;
+	for (set<Allocation>::iterator it = releaseSet.begin(); it != releaseSet.end(); it++) {
+        debug("machsrvmem", "%p release %p with %p", this, it->addr, it->allocator);
+		it->allocator->free(it->addr);
+    }
+	releaseSet.erase(releaseSet.begin(), releaseSet.end());
+}
+
+
+//
+// The handler function calls this if it realizes that it might be blocked
+// (or doing something that takes a long time). We respond by ensuring that
+// at least one more thread is ready to serve requests.
+//
+void MachServer::longTermActivity()
+{
+	StLock<Mutex> _(managerLock);
+	if (idleCount == 0 && workerCount < maxWorkerCount) {
+		// spawn a new thread of activity that shares in the server main loop
+		(new LoadThread(*this))->run();
+	}
+}
+
+void MachServer::LoadThread::action()
+{
+	//@@@ race condition?! can server exit before helpers thread gets here?
+	
+	// register the worker thread and go
+	server.addThread(this);
+	try {
+		server.runServerThread(true);
+	} catch (...) {
+		// fell out of server loop by error. Let the thread go quietly
+	}
+	server.removeThread(this);
+}
+
+void MachServer::addThread(Thread *thread)
+{
+	StLock<Mutex> _(managerLock);
+	workerCount++;
+	idleCount++;
+	debug("machsrv", "%p adding worker thread (%ld workers, %ld idle)",
+		this, workerCount, idleCount);
+	workers.insert(thread);
+}
+
+void MachServer::removeThread(Thread *thread)
+{
+	StLock<Mutex> _(managerLock);
+	workerCount--;
+	idleCount--;
+	debug("machsrv", "%p removing worker thread (%ld workers, %ld idle)",
+		this, workerCount, idleCount);
+	workers.erase(thread);
+}
+
+
+//
+// Timer management
+//
+bool MachServer::processTimer()
+{
+	Timer *top;
+	{	StLock<Mutex> _(managerLock);	// could have multiple threads trying this
+		if (!(top = static_cast<Timer *>(timers.pop(Time::now()))))
+			return false;				// nothing (more) to be done now
+	}	// drop lock; work has been retrieved
+	debug("machsrvtime", "%p timer %p executing at %.3f",
+        this, top, Time::now().internalForm());
+	try {
+		top->action();
+		debug("machsrvtime", "%p timer %p done", this, top);
+	} catch (...) {
+		debug("machsrvtime", "%p server timer %p failed with exception", this, top);
+	}
+	return true;
+}
+
+void MachServer::setTimer(Timer *timer, Time::Absolute when)
+{
+	StLock<Mutex> _(managerLock);
+	timers.schedule(timer, when); 
+}
+	
+void MachServer::clearTimer(Timer *timer)
+{
+	StLock<Mutex> _(managerLock); 
+	if (timer->scheduled())
+		timers.unschedule(timer); 
+}
+
+
+//
+// Notification hooks and shims. Defaults do nothing.
+//
+void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port)
+{ MachServer::active().notifyDeadName(port); }
+
+void MachServer::notifyDeadName(Port) { }
+
+void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port)
+{ MachServer::active().notifyPortDeleted(port); }
+
+void MachServer::notifyPortDeleted(Port) { }
+
+void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port)
+{ MachServer::active().notifyPortDestroyed(port); }
+
+void MachServer::notifyPortDestroyed(Port) { }
+
+void cdsa_mach_notify_send_once(mach_port_t)
+{ MachServer::active().notifySendOnce(); }
+
+void MachServer::notifySendOnce() { }
+
+void cdsa_mach_notify_no_senders(mach_port_t)
+{ /* legacy handler - not used by system */ }
+
+
+} // end namespace MachPlusPlus
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/machserver.h b/cdsa/cdsa_utilities/machserver.h
new file mode 100644
index 00000000..4e6e1d99
--- /dev/null
+++ b/cdsa/cdsa_utilities/machserver.h
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+
+
+//
+// machserver - C++ shell for writing Mach 3 servers
+//
+#ifndef _H_MACHSERVER
+#define _H_MACHSERVER
+
+#include <Security/mach++.h>
+#include <Security/timeflow.h>
+#include <Security/threading.h>
+#include <Security/globalizer.h>
+#include <Security/cssmalloc.h>
+#include <Security/tqueue.h>
+
+
+namespace Security {
+namespace MachPlusPlus {
+
+
+extern "C" {
+	void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port);
+	void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port);
+	void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port);
+	void cdsa_mach_notify_send_once(mach_port_t);
+	void cdsa_mach_notify_no_senders(mach_port_t);	// legacy
+};
+
+
+//
+// Mach server object
+//
+class MachServer {
+	class LoadThread; friend class LoadThread;
+	
+protected:
+	struct Allocation {
+		void *addr;
+		CssmAllocator *allocator;
+		Allocation(void *p, CssmAllocator &alloc) : addr(p), allocator(&alloc) { }
+		bool operator < (const Allocation &other) const
+		{ return addr < other.addr || (addr == other.addr && allocator < other.allocator); }
+	};
+    
+protected:
+    struct PerThread {
+        MachServer *server;
+        set<Allocation> deferredAllocations;
+
+        PerThread() : server(NULL) { }
+    };
+    static ModuleNexus< ThreadNexus<PerThread> > thread;
+    static PerThread &perThread()	{ return thread()(); }
+    
+public:
+    MachServer(const char *name);
+	MachServer(const char *name, const Bootstrap &bootstrap);
+	virtual ~MachServer();
+	
+	void run(size_t maxSize = 4096, mach_msg_options_t options = 0);
+	
+	Time::Interval timeout() const { return workerTimeout; }
+	void timeout(Time::Interval t) { workerTimeout = t; }
+	uint32 maxThreads() const	{ return maxWorkerCount; }
+	void maxThreads(uint32 n)	{ maxWorkerCount = n; }
+
+	// the currently active server in this thread (there can only be one)
+	static MachServer &active()
+	{ assert(perThread().server); return *perThread().server; }
+	
+	// request dead-port notification if this port dies (override notifyDeadName)
+	virtual void notifyIfDead(Port port) const;
+
+	// register (CssmAllocator-derived) memory to be released after reply is sent
+	void releaseWhenDone(CssmAllocator &alloc, void *memory);
+	
+	// call if you realize that your server method will take a long time
+	void longTermActivity();
+
+public:
+	class Timer : private ScheduleQueue<Time::Absolute>::Event {
+		friend class MachServer;
+	protected:
+		virtual ~Timer() { }
+	
+	public:
+		virtual void action() = 0;
+		
+		Time::Absolute when() const	{ return Event::when(); }
+		bool scheduled() const		{ return Event::scheduled(); }
+	};
+	
+	virtual void setTimer(Timer *timer, Time::Absolute when);
+	void setTimer(Timer *timer, Time::Interval offset)
+	{ setTimer(timer, Time::now() + offset); }
+
+	virtual void clearTimer(Timer *timer);
+
+public:
+    class Handler {
+    public:
+        Handler(mach_port_t p) : mPort(p) { }
+        Handler() : mPort(MACH_PORT_NULL) { }
+        
+        mach_port_t port() const	{ return mPort; }
+        
+        virtual boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out) = 0;
+        
+    protected:
+        void port(mach_port_t p)	{ assert(mPort == MACH_PORT_NULL); mPort = p; }
+
+    private:
+        mach_port_t mPort;
+    };
+    
+    class NoReplyHandler : public Handler {
+    public:
+        virtual boolean_t handle(mach_msg_header_t *in) = 0;
+
+    private:
+        boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out);
+    };
+    
+    void add(Handler &handler);
+    void remove(Handler &handler);
+    
+protected:
+	// your server dispatch function
+	virtual boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out) = 0;
+	
+	// override these to receive Mach-style port notifications about your clients
+	virtual void notifyDeadName(Port port);
+	virtual void notifyPortDeleted(Port port);
+	virtual void notifyPortDestroyed(Port port);
+	virtual void notifySendOnce();
+
+	// don't mess with this unless you know what you're doing
+    Bootstrap bootstrap;			// bootstrap port we registered with
+	ReceivePort mServerPort;		// port to receive requests
+    PortSet mPortSet;				// joint receiver port set
+	
+	size_t mMaxSize;				// maximum message size
+	mach_msg_options_t mMsgOptions;	// kernel call options
+    
+    typedef set<Handler *> HandlerSet;
+    HandlerSet mHandlers;			// subsidiary message port handlers
+
+protected:	
+	void releaseDeferredAllocations();
+	
+protected:
+	class LoadThread : public Thread {
+	public:
+		LoadThread(MachServer &srv) : server(srv) { }
+		
+		MachServer &server;
+		
+		void action();		// code implementation
+	};
+	
+	Mutex managerLock;		// lock for thread-global management info below
+	set<Thread *> workers;	// threads running for this server
+	uint32 workerCount;		// number of worker threads (including primary)
+	uint32 maxWorkerCount;	// administrative limit to workerCount
+	uint32 highestWorkerCount; // high water mark for workerCount
+	uint32 idleCount;		// number of threads waiting for work
+	Time::Interval workerTimeout; // seconds of idle time before a worker retires
+	Time::Absolute nextCheckTime; // next time to check for excess threads
+	uint32 leastIdleWorkers; // max(idleCount) since last checkpoint
+	ScheduleQueue<Time::Absolute> timers;
+
+	void addThread(Thread *thread); // add thread to worker pool
+	void removeThread(Thread *thread); // remove thread from worker pool
+	bool processTimer();	// handle one due timer object, if any
+
+private:
+	static boolean_t handler(mach_msg_header_t *in, mach_msg_header_t *out);
+    void setup(const char *name);
+	void runServerThread(bool doTimeout = false);
+	
+	friend void cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port);
+	friend void cdsa_mach_notify_port_destroyed(mach_port_t, mach_port_name_t port);
+	friend void cdsa_mach_notify_port_deleted(mach_port_t, mach_port_name_t port);
+	friend void cdsa_mach_notify_send_once(mach_port_t);
+};
+
+
+} // end namespace MachPlusPlus
+
+} // end namespace Security
+
+#endif //_H_MACHSERVER
diff --git a/cdsa/cdsa_utilities/memutils.h b/cdsa/cdsa_utilities/memutils.h
new file mode 100644
index 00000000..aaea469d
--- /dev/null
+++ b/cdsa/cdsa_utilities/memutils.h
@@ -0,0 +1,229 @@
+/*
+ * 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.
+ */
+
+
+//
+// memutils - memory-related low-level utilities for easier living
+//
+#ifndef _H_MEMUTILS
+#define _H_MEMUTILS
+
+#include <Security/utilities.h>
+#include <stdlib.h>
+#include <algorithm>
+
+
+#ifdef _CPP_MEMUTILS
+# pragma export on
+#endif
+
+
+namespace Security
+{
+
+//
+// Encapsulate these very sharp tools in a separate namespace
+//
+namespace LowLevelMemoryUtilities
+{
+
+
+//
+// The default system alignment.
+// @@@ We should really get this from somewhere... probably from utility_config.h.
+//
+static const size_t systemAlignment = 4;
+typedef UInt32 PointerInt;
+
+
+//
+// Get the local alignment for a type.
+//
+template <class T>
+inline size_t alignof() { struct { char c; T t; } s; return sizeof(s) - sizeof(T); }
+
+
+//
+// Round up a size or pointer to an alignment boundary.
+// Alignment must be a power of two; default is default alignment.
+//
+inline size_t alignUp(size_t size, size_t alignment = systemAlignment)
+{
+	return ((size - 1) & ~(alignment - 1)) + alignment;
+}
+
+inline void *alignUp(void *p, size_t alignment = systemAlignment)
+{
+	return reinterpret_cast<void *>(alignUp(PointerInt(p), alignment));
+}
+
+inline const void *alignUp(const void *p, size_t alignment = systemAlignment)
+{
+	return reinterpret_cast<const void *>(alignUp(PointerInt(p), alignment));
+}
+
+template <class T>
+inline const T *increment(const void *p, ptrdiff_t offset)
+{ return reinterpret_cast<const T *>(PointerInt(p) + offset); }
+
+template <class T>
+inline T *increment(void *p, ptrdiff_t offset)
+{ return reinterpret_cast<T *>(PointerInt(p) + offset); }
+
+inline const void *increment(const void *p, ptrdiff_t offset)
+{ return increment<const void>(p, offset); }
+
+inline void *increment(void *p, ptrdiff_t offset)
+{ return increment<void>(p, offset); }
+
+template <class T>
+inline const T *increment(const void *p, ptrdiff_t offset, size_t alignment)
+{ return increment<const T>(alignUp(p, alignment), offset); }
+
+template <class T>
+inline T *increment(void *p, ptrdiff_t offset, size_t alignment)
+{ return increment<T>(alignUp(p, alignment), offset); }
+
+inline const void *increment(const void *p, ptrdiff_t offset, size_t alignment)
+{ return increment<const void>(p, offset, alignment); }
+
+inline void *increment(void *p, ptrdiff_t offset, size_t alignment)
+{ return increment<void>(p, offset, alignment); }
+
+inline ptrdiff_t difference(const void *p1, const void *p2)
+{ return PointerInt(p1) - PointerInt(p2); }
+
+
+//
+// A simple utility for incremental creation of a contiguous memory block.
+//
+// Note that Writer and Writer::Counter go together. They use the same alignment
+// and padding rules, so Writer::Counter will correctly calculate total buffer
+// size for Writer, *presuming* that they are called in the same order.
+//
+// WARNING: There is no check for overflow. If you write too much, you will die.
+//
+class Writer {
+private:
+	void *advance(size_t size)
+	{
+		void *here = alignUp(writePos);
+		writePos = increment(here, size);
+		return here;
+	}
+    
+public:    
+	Writer() { }
+	Writer(void *base) : writePos(base) { }
+	void operator = (void *base) { writePos = base; }
+
+	template <class T>
+	T *operator () (const T &obj)
+	{ T *here = (T *)advance(sizeof(T)); *here = obj; return here; }
+
+	void *operator () (const void *addr, size_t size)
+	{ void *here = advance(size); return memcpy(here, addr, size); }
+
+	char *operator () (const char *s)
+	{ return (char *)(*this)(s, strlen(s) + 1); }
+	
+	void countedData(const void *data, uint32 length)
+	{ (*this)(length); (*this)(data, length); }
+	
+	template <class Data>
+	void countedData(const Data &data)
+	{ countedData(data.data(), data.length()); }
+
+	class Counter;
+
+private:
+	void *writePos;			// next byte address
+};
+
+class Writer::Counter {
+private:
+	void align() { totalSoFar = alignUp(totalSoFar); }
+
+public:
+	Counter() : totalSoFar(0) { }
+	operator size_t () { return totalSoFar; }
+
+	template <class T> size_t operator () (const T &) { align(); return totalSoFar += sizeof(T); }
+	size_t insert(size_t size) { align(); return totalSoFar += size; }
+	size_t operator () (const char *s) { align(); return totalSoFar += strlen(s) + 1; }
+	
+	void countedData(const void *, uint32 length)
+	{ insert(sizeof(uint32)); insert(length); }
+	
+	template <class Data>
+	void countedData(const Data &data)
+	{ countedData(data.data(), data.length()); }
+
+private:
+	size_t totalSoFar;	// total size counted so far
+};
+
+
+//
+// The Reader counter-part for a Writer.
+// Again, Reader and Writer share alignment and representation rules, so what was
+// Written shall be Read again, just fine.
+//
+class Reader {
+private:
+    const void *advance(size_t size = 0)
+    {
+        const void *here = alignUp(readPos);
+        readPos = increment(here, size);
+        return here;
+    }
+
+public:
+    Reader() { }
+    Reader(const void *base) : readPos(base) { }
+    void operator = (const void *base) { readPos = base; }
+    
+    template <class T>
+    void operator () (T &obj) {	obj = *reinterpret_cast<const T *>(advance(sizeof(T))); }
+    void operator () (void *addr, size_t size)	{ memcpy(addr, advance(size), size); }
+    void operator () (const char * &s)
+    { s = reinterpret_cast<const char *>(advance()); advance(strlen(s) + 1); }
+    template <class T>
+    const T *get(size_t size)
+	{ return reinterpret_cast<const T *>(advance(size)); }
+	
+	void countedData(const void * &data, uint32 &length)
+	{ (*this)(length); data = advance(length); }
+
+private:
+	// Explicitly forbid some invocations that are likely to be wrong.
+	void operator () (char * &s);	// can't get writable string in-place
+    
+private:
+    const void *readPos;	// next byte address
+};
+
+
+} // end namespace LowLevelMemoryUtilities
+
+} // end namespace Security
+
+#ifdef _CPP_MEMUTILS
+# pragma export off
+#endif
+
+#endif //_H_MEMUTILS
diff --git a/cdsa/cdsa_utilities/os9utils.cpp b/cdsa/cdsa_utilities/os9utils.cpp
new file mode 100644
index 00000000..086a0558
--- /dev/null
+++ b/cdsa/cdsa_utilities/os9utils.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+
+//
+// os9utils - MacOS 9 specific utilities
+//
+#if defined(__MWERKS__)
+#define _CPP_OS9UTILS
+#endif
+#include <Security/utility_config.h>
+#if TARGET_API_MAC_OS8
+
+#include <Security/os9utils.h>
+
+
+
+
+
+#endif // OS 8/9
diff --git a/cdsa/cdsa_utilities/os9utils.h b/cdsa/cdsa_utilities/os9utils.h
new file mode 100644
index 00000000..9b729fe4
--- /dev/null
+++ b/cdsa/cdsa_utilities/os9utils.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+
+//
+// os9utils - MacOS 9 specific utilities
+//
+#ifndef _H_OS9UTILS
+#define _H_OS9UTILS
+
+#include <Security/utility_config.h>
+#if TARGET_API_MAC_OS8
+
+#include <Security/utilities.h>
+#include <string>
+
+
+namespace Security
+{
+
+namespace MacOS9Utilities
+{
+
+
+//
+// A temporary or in-place Str255 constructed from other string forms
+//
+class PString {
+public:
+        PString(const char *s) { set(s, strlen(s)); }
+        PString(string s) { set(s.data(), s.size()); }
+        operator const unsigned char * () const { return mString; }
+
+private:
+        Str255 mString;
+        void set(const char *str, int size)
+        {
+	        if (size > 255)
+	                CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+	        mString[0] = size;
+	        memcpy(mString+1, str, size);
+        }
+};
+
+
+//
+// Make an STL string from a Pascal string
+//
+inline string p2cString(StringPtr s)
+{
+        return string(reinterpret_cast<const char *>(s + 1), s[0]);
+}
+
+
+} // end namespace MacOS9Utilities
+
+} // end namespace Security
+
+#endif // OS 8/9
+#endif //_H_OS9UTILS
diff --git a/cdsa/cdsa_utilities/osxsigning.cpp b/cdsa/cdsa_utilities/osxsigning.cpp
new file mode 100644
index 00000000..25234184
--- /dev/null
+++ b/cdsa/cdsa_utilities/osxsigning.cpp
@@ -0,0 +1,247 @@
+/*
+ * 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.
+ */
+
+
+//
+// osxsigning - MacOS X's standard signable objects.
+//
+#ifdef __MWERKS__
+#define _CPP_OSXSIGNING
+#endif
+
+#include <Security/osxsigning.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <CoreFoundation/CFBundle.h>
+
+
+namespace Security
+{
+
+namespace CodeSigning
+{
+
+//
+// Enumerate a single file on disk.
+//
+void OSXCode::scanFile(const char *pathname, Signer::State &state)
+{
+	// open the file (well, try)
+	int fd = open(pathname, O_RDONLY);
+	if (fd < 0)
+		UnixError::throwMe();
+	
+	// how big is it?
+	struct stat st;
+	if (fstat(fd, &st)) {
+		close(fd);
+		UnixError::throwMe();
+	}
+#if defined(LIMITED_SIGNING)
+	if (st.st_size >= 0x4000)
+		st.st_size = 0x4000;
+#endif
+	
+	// map it
+	void *p = mmap(NULL, st.st_size, PROT_READ, MAP_FILE, fd, 0);
+	close(fd);	// done with this either way
+	if (p == MAP_FAILED)
+		UnixError::throwMe();
+	
+	// scan it
+	debug("codesign", "scanning file %s (%ld bytes)", pathname, long(st.st_size));
+	state.enumerateContents(p, st.st_size);
+	
+	// unmap it (ignore error)
+	munmap(p, st.st_size);
+}
+
+
+//
+// Use prefix encoding for externalizing OSXCode objects
+//
+OSXCode *OSXCode::decode(const char *extForm)
+{
+	if (!extForm || !extForm[0] || extForm[1] != ':')
+		return NULL;
+	switch (extForm[0]) {
+	case 't':
+		return new ExecutableTool(extForm+2);
+	case 'b':
+		return new GenericBundle(extForm+2);
+	default:
+		return NULL;
+	}
+}
+
+
+//
+// Produce a Signable for the currently running application
+//
+OSXCode *OSXCode::main()
+{
+	//@@@ cache the main bundle?
+	if (CFBundleRef mainBundle = CFBundleGetMainBundle()) {
+        CFRef<CFURLRef> base = CFBundleCopyBundleURL(mainBundle);
+        CFRef<CFURLRef> resources(CFBundleCopyResourcesDirectoryURL(mainBundle));
+        if (base && resources && !CFEqual(resources, base)) {
+			// assume this is a real bundle
+			return new ApplicationBundle(getPath(CFBundleCopyBundleURL(mainBundle)).c_str());
+        }
+
+		// too weird; assume this is a single-file "tool" executable
+		return new ExecutableTool(getPath(CFBundleCopyExecutableURL(mainBundle)).c_str());
+	}
+	// CF gives no error indications...
+	CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+}
+
+
+// Note: The public CFURLCopyFileSystemPath fails to resolve relative URLs as
+// produced by CFURL methods. We need to call an internal(!) method of CF to get
+// the full path.
+extern "C" CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator,
+	CFURLRef anURL, CFURLPathStyle fsType, Boolean resolveAgainstBase);
+
+string OSXCode::getPath(CFURLRef url)
+{
+    if (url == NULL)
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);	// source CF call failed
+
+	CFRef<CFStringRef> str(CFURLCreateStringWithFileSystemPath(NULL, 
+		url, kCFURLPOSIXPathStyle, true));
+	CFRelease(url);
+	if (str) {
+		char path[PATH_MAX];
+		if (CFStringGetCString(str, path, PATH_MAX, kCFStringEncodingUTF8))
+			return path;
+	}
+	// no error indications from CF...
+	CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+}
+
+
+//
+// Produce a Signable for whatever is at a given path.
+// This tries to guess at the type of Signable to be used.
+// If you *know*, just create the suitable subclass directly.
+//
+OSXCode *OSXCode::at(const char *path)
+{
+	struct stat st;
+	if (stat(path, &st))
+		UnixError::throwMe();
+	if ((st.st_mode & S_IFMT) == S_IFDIR) {	// directory - assume bundle
+		return new GenericBundle(path);
+	} else {								// not directory - assume tool
+		return new ExecutableTool(path);
+	}
+}
+
+
+//
+// Executable Tools
+//
+void ExecutableTool::scanContents(Signer::State &state) const
+{
+	scanFile(mPath.c_str(), state);
+}
+
+string ExecutableTool::encode() const
+{
+	return "t:" + mPath;
+}
+
+string ExecutableTool::canonicalPath() const
+{
+	return path();
+}
+
+
+//
+// Generic Bundles
+//
+GenericBundle::GenericBundle(const char *path) : mPath(path)
+{
+	CFRef<CFURLRef> url(CFURLCreateFromFileSystemRepresentation(NULL, 
+		(const UInt8 *)path, strlen(path), true));
+	if (!url || !(mBundle = CFBundleCreate(NULL, url)))
+        CssmError::throwMe(CSSMERR_CSSM_ADDIN_LOAD_FAILED);
+}
+
+GenericBundle::~GenericBundle()
+{
+    CFRelease(mBundle);
+}
+
+
+void GenericBundle::scanContents(Signer::State &state) const
+{
+	scanFile(executablePath().c_str(), state);
+}
+
+string GenericBundle::encode() const
+{
+	return "b:" + mPath;
+}
+
+void *GenericBundle::lookupSymbol(const char *name)
+{
+    CFRef<CFStringRef> cfName(CFStringCreateWithCString(NULL, name,
+                                                        kCFStringEncodingMacRoman));
+    if (!cfName)
+        CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT);
+    void *function = CFBundleGetFunctionPointerForName(mBundle, cfName);
+    if (function == NULL)
+        CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT);
+    return function;
+}
+
+string GenericBundle::canonicalPath() const
+{
+	return path();
+}
+
+
+//
+// Load management for a loadable bundle
+//
+void LoadableBundle::load()
+{
+	if (!CFBundleLoadExecutable(mBundle))
+		CssmError::throwMe(CSSMERR_CSSM_ADDIN_LOAD_FAILED);
+    IFDEBUG(debug("bundle", "%p (%s) loaded", this, path().c_str()));
+}
+
+void LoadableBundle::unload()
+{
+    IFDEBUG(debug("bundle", "%p (%s) unloaded", this, path().c_str()));
+	CFBundleUnloadExecutable(mBundle);
+}
+
+bool LoadableBundle::isLoaded() const
+{
+	return CFBundleIsExecutableLoaded(mBundle);
+}
+
+
+}; // end namespace CodeSigning
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/osxsigning.h b/cdsa/cdsa_utilities/osxsigning.h
new file mode 100644
index 00000000..e530eecd
--- /dev/null
+++ b/cdsa/cdsa_utilities/osxsigning.h
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+
+//
+// osxsigning - MacOS X's standard signable objects.
+//
+#ifndef _OSXSIGNING
+#define _OSXSIGNING
+
+#include <Security/codesigning.h>
+#include <Security/cspclient.h>
+#include <limits.h>
+#include <string>
+#include <CoreFoundation/CFBundle.h>
+
+#ifdef _CPP_OSXSIGNING
+#pragma export on
+#endif
+
+
+namespace Security
+{
+
+namespace CodeSigning
+{
+
+//
+// A Signable with OS X support calls added
+//
+class OSXCode : public Signable {
+public:
+	// encoding and decoding as a UTF-8 string
+	virtual string encode() const = 0;
+	static OSXCode *decode(const char *extForm);
+	
+public:
+	// creating OSXCode objects
+	static OSXCode *main();
+	static OSXCode *at(const char *path);
+	
+public:
+	// produce the best approximation of a path that, when handed to at(),
+	// will yield an OSXCode that's the most like this one
+	virtual string canonicalPath() const = 0;
+
+protected:
+	OSXCode() { }	// nonpublic
+	static void scanFile(const char *pathname, Signer::State &state);	// scan an entire file
+	static string getPath(CFURLRef url);
+};
+
+
+//
+// A simple executable tool.
+//
+class ExecutableTool : public OSXCode {
+public:
+	ExecutableTool(const char *path) : mPath(path) { }
+	string encode() const;
+	
+	string path() const		{ return mPath; }
+	string canonicalPath() const;
+	
+protected:
+	void scanContents(Signer::State &state) const;
+
+private:
+	string mPath;			// UTF8 pathname to executable
+};
+
+
+//
+// A generic bundle
+//
+class GenericBundle : public OSXCode {
+public:
+	GenericBundle(const char *path);
+	~GenericBundle();
+
+	string encode() const;
+	
+	string canonicalPath() const;
+	string path() const				{ return mPath; }
+	string executablePath() const	{ return getPath(CFBundleCopyExecutableURL(mBundle)); }
+	
+	virtual void *lookupSymbol(const char *name);
+	
+protected:
+	void scanContents(Signer::State &state) const;
+	
+protected:
+	string mPath;			// UTF8 path to bundle directory
+	CFBundleRef mBundle;	// CF-style bundle object
+};
+
+class ApplicationBundle : public GenericBundle {
+public:
+	ApplicationBundle(const char *pathname) : GenericBundle(pathname) { }
+};
+
+class LoadableBundle : public GenericBundle {
+public:
+	LoadableBundle(const char *pathname) : GenericBundle(pathname) { }
+	
+	virtual bool isLoaded() const;
+	virtual void load();
+	virtual void unload();
+};
+
+
+} // end namespace CodeSigning
+
+} // end namespace Security
+
+#ifdef _CPP_OSXSIGNING
+#pragma export off
+#endif
+
+
+#endif //_OSXSIGNING
diff --git a/cdsa/cdsa_utilities/powerwatch.cpp b/cdsa/cdsa_utilities/powerwatch.cpp
new file mode 100644
index 00000000..ec86288e
--- /dev/null
+++ b/cdsa/cdsa_utilities/powerwatch.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+
+//
+// powerwatch - hook into system notifications of power events
+//
+#include "powerwatch.h"
+#include <IOKit/IOMessage.h>
+
+
+namespace Security {
+namespace MachPlusPlus {
+
+
+//
+// The obligatory empty virtual destructor
+//
+PowerWatcher::PowerWatcher()
+{
+    if (!(mKernelPort = IORegisterForSystemPower(this, &mPortRef, ioCallback, &mHandle)))
+        UnixError::throwMe(EINVAL);	// no clue
+}
+
+PowerWatcher::~PowerWatcher()
+{
+    if (mKernelPort)
+        IODeregisterForSystemPower(&mHandle);
+}
+
+
+//
+// The callback dispatcher
+//
+void PowerWatcher::ioCallback(void *refCon, io_service_t service,
+    natural_t messageType, void *argument)
+{
+    PowerWatcher *me = (PowerWatcher *)refCon;
+    switch (messageType) {
+    case kIOMessageSystemWillSleep:
+        debug("powerwatch", "system will sleep");
+        me->systemWillSleep();
+        break;
+    case kIOMessageSystemHasPoweredOn:
+        debug("powerwatch", "system has powered on");
+        me->systemIsWaking();
+        break;
+    case kIOMessageSystemWillPowerOff:
+        debug("powerwatch", "system will power off");
+        me->systemWillPowerDown();
+        break;
+
+#if !defined(NDEBUG)
+    case kIOMessageSystemWillNotPowerOff:
+        debug("powerwatch", "system will not power off");
+        break;
+    case kIOMessageCanSystemSleep:
+        debug("powerwatch", "can system sleep");
+        break;
+    case kIOMessageSystemWillNotSleep:
+        debug("powerwatch", "system will not sleep");
+        break;
+    case kIOMessageCanSystemPowerOff:
+        debug("powerwatch", "can system power off");
+        break;
+    default:
+        debug("powerwatch",
+            "type 0x%x message received (ignored)", messageType);
+        break;
+#endif //NDEBUG
+    }
+    
+    // always confirm
+    IOAllowPowerChange(me->mKernelPort, long(argument));
+}
+
+
+//
+// The default NULL implementations of the callback virtuals.
+// We define these (rather than leaving them abstract) since
+// many users want only one of these events.
+//
+void PowerWatcher::systemWillSleep()
+{ }
+
+void PowerWatcher::systemIsWaking()
+{ }
+
+void PowerWatcher::systemWillPowerDown()
+{ }
+
+
+//
+// The MachServer hookup
+//
+PortPowerWatcher::PortPowerWatcher()
+{
+    port(IONotificationPortGetMachPort(mPortRef));
+}
+
+PortPowerWatcher::~PortPowerWatcher()
+{
+}
+
+boolean_t PortPowerWatcher::handle(mach_msg_header_t *in)
+{
+    IODispatchCalloutFromMessage(NULL, in, mPortRef);
+    return TRUE;
+}
+
+
+} // end namespace MachPlusPlus
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/powerwatch.h b/cdsa/cdsa_utilities/powerwatch.h
new file mode 100644
index 00000000..ecc5e5f7
--- /dev/null
+++ b/cdsa/cdsa_utilities/powerwatch.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+
+//
+// powerwatch - hook into system notifications of power events
+//
+#ifndef _H_POWERWATCH
+#define _H_POWERWATCH
+
+#include <Security/machserver.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
+
+
+namespace Security {
+namespace MachPlusPlus {
+
+
+//
+// PowerWatcher embodies the ability to respond to power events.
+// By itself, it is inert - nobody will call its virtual methods.
+// Use one of it subclasses, which take care of "hooking" into an
+// event delivery mechanism.
+//
+class PowerWatcher {
+public:
+    PowerWatcher();
+    virtual ~PowerWatcher();
+    
+protected:
+    virtual void systemWillSleep();
+    virtual void systemIsWaking();
+    virtual void systemWillPowerDown();
+    
+protected:
+    io_connect_t mKernelPort;
+    IONotificationPortRef mPortRef;
+    io_object_t mHandle;
+    
+    static void ioCallback(void *refCon, io_service_t service,
+        natural_t messageType, void *argument);
+};
+
+
+//
+// Hook into a "raw" MachServer object for event delivery
+//
+class PortPowerWatcher : public PowerWatcher, public MachServer::NoReplyHandler {
+public:
+    PortPowerWatcher();
+    ~PortPowerWatcher();
+    
+    boolean_t handle(mach_msg_header_t *in);    
+};
+
+
+//
+// Someone should add a RunLoopPowerWatcher class here, I suppose.
+// Well, if you need one: Tag, You're It!
+//
+
+
+} // end namespace MachPlusPlus
+
+} // end namespace Security
+
+#endif //_H_POWERWATCH
diff --git a/cdsa/cdsa_utilities/refcount.h b/cdsa/cdsa_utilities/refcount.h
new file mode 100644
index 00000000..5fd54da5
--- /dev/null
+++ b/cdsa/cdsa_utilities/refcount.h
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+
+/*
+
+	Based on code donated by Perry Kiehtreiber
+
+ */
+
+#ifndef _H_REFCOUNT
+#define _H_REFCOUNT
+
+#include <Security/threading.h>
+
+namespace Security
+{
+
+//
+// RefCount/RefPointer - a simple reference counting facility.
+//
+// To make an object reference-counted, derive it from RefCount. To track refcounted
+// objects, use RefPointer<TheType>, where TheType must be derived from RefCount.
+//
+// RefCount is thread safe - any number of threads can hold and manipulate references
+// in parallel. It does however NOT protect the contents of your object - just the
+// reference count itself. If you need to share your object contents, you must engage
+// in appropriate locking yourself.
+//
+// There is no (thread safe) way to determine whether you are the only thread holding
+// a pointer to a particular RefCount object.
+//
+
+
+//
+// Base class for reference counted objects
+//
+class RefCount {
+public:
+	RefCount() : mRefCount(0) { }
+
+protected:
+	template <class T> friend class RefPointer;
+
+	void ref() const			{ ++mRefCount; }
+	unsigned int unref() const	{ return --mRefCount; }
+
+private:
+    mutable AtomicCounter<unsigned int> mRefCount;
+};
+
+
+//
+// A pointer type supported by reference counts.
+// T must be derived from RefCount.
+//
+template <class T>
+class RefPointer {
+public:
+	RefPointer() : ptr(0) {}			// default to NULL pointer
+	RefPointer(const RefPointer& p) { if (p) p->ref(); ptr = p.ptr; }
+	RefPointer(T *p) { if (p) p->ref(); ptr = p; }
+    
+	~RefPointer() { release(); }
+
+	RefPointer& operator = (const RefPointer& p)	{ setPointer(p.ptr); return *this; }
+ 	RefPointer& operator = (T * p)					{ setPointer(p); return *this; }
+
+	// dereference operations
+	operator T * () const		{ return ptr; }
+	T * operator -> () const	{ return ptr; }
+	T & operator * () const		{ return *ptr; }
+
+protected:
+	void release() { if (ptr && ptr->unref() == 0) delete ptr; }
+	void setPointer(T *p) { if (p) p->ref(); release(); ptr = p; }
+
+	T *ptr;
+};
+
+} // end namespace Security
+
+
+#endif //_H_REFCOUNT
diff --git a/cdsa/cdsa_utilities/selector.cpp b/cdsa/cdsa_utilities/selector.cpp
new file mode 100644
index 00000000..4e2dbfb2
--- /dev/null
+++ b/cdsa/cdsa_utilities/selector.cpp
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+
+//
+// selector - I/O stream multiplexing
+//
+#include "selector.h"
+#include <Security/debugging.h>
+#include <algorithm>	// min/max
+
+
+namespace Security {
+namespace UnixPlusPlus {
+
+
+//
+// construct a Selector object.
+//
+Selector::Selector() : fdMin(INT_MAX), fdMax(-1)
+{
+    // initially allocate room for FD_SETSIZE file descriptors (usually good enough)
+    fdSetSize = FD_SETSIZE / NFDBITS;
+    inSet.grow(0, fdSetSize);
+    outSet.grow(0, fdSetSize);
+    errSet.grow(0, fdSetSize);
+}
+
+Selector::~Selector()
+{ }
+
+
+//
+// Add a Client to a Selector
+//
+void Selector::add(int fd, Client &client, Type type)
+{
+    // plausibility checks
+    assert(!client.isActive());		// one Selector per client, and no re-adding
+    assert(fd >= 0);
+    
+    debug("selector", "add client %p fd %d type=%d", &client, fd, type);
+    
+    // grow FDSets if needed
+    unsigned int pos = fd / NFDBITS;
+    if (pos >= fdSetSize) {
+        int newSize = (fd - 1) / NFDBITS + 2;	// as much as needed + 1 spare word
+        inSet.grow(fdSetSize, newSize);
+        outSet.grow(fdSetSize, newSize);
+        errSet.grow(fdSetSize, newSize);
+    }
+    
+    // adjust boundaries
+    if (fd < fdMin)
+        fdMin = fd;
+    if (fd > fdMax)
+        fdMax = fd;
+
+    // add client
+    Client * &slot = clientMap[fd];
+    assert(!slot);
+    slot = &client;
+    client.mFd = fd;
+    client.mSelector = this;
+    client.mEvents = type;
+    set(fd, type);
+}    
+
+
+//
+// Remove a Client from a Selector
+//
+void Selector::remove(int fd)
+{
+    // sanity checks
+    assert(fd >= 0);
+    ClientMap::iterator it = clientMap.find(fd);
+    assert(it != clientMap.end());
+    assert(it->second->mSelector == this);
+
+    debug("selector", "remove client %p fd %d", it->second, fd);
+
+    // remove from FDSets
+    set(fd, none);
+    
+    // remove client
+    it->second->mSelector = NULL;
+    clientMap.erase(it);
+    
+    // recompute fdMin/fdMax if needed
+    if (isEmpty()) {
+        fdMin = INT_MAX;
+        fdMax = -1;
+    } else if (fd == fdMin) {
+        fdMin = clientMap.begin()->first;
+    } else if (fd == fdMax) {
+        fdMax = clientMap.rbegin()->first;
+    }
+}
+
+
+//
+// Adjust the FDSets for a single given Client according to a new event Type mask.
+//
+void Selector::set(int fd, Type type)
+{
+    assert(fd >= 0);
+    inSet.set(fd, type & input);
+    outSet.set(fd, type & output);
+    errSet.set(fd, type & critical);
+    debug("selector", "fd %d notifications 0x%x", fd, type);
+}
+
+
+void Selector::operator () ()
+{
+    if (!clientMap.empty())
+        singleStep(0);
+}
+
+
+void Selector::operator () (Time::Absolute stopTime)
+{
+    if (!clientMap.empty())
+        singleStep(stopTime - Time::now());
+}
+
+
+//
+// Perform a single pass through the Selector and notify all clients
+// that have selected I/O pending at this time.
+// There is not time limit on how long this may take; if the clients
+// are well written, it won't be too long.
+//
+void Selector::singleStep(Time::Interval maxWait)
+{
+    assert(!clientMap.empty());
+    IFDEBUG(debug("selector", "select(%d) [%d-%d] for %ld clients",
+        fdMax + 1, fdMin, fdMax, clientMap.size()));
+    for (;;) {	// pseudo-loop - only retries
+        struct timeval duration = maxWait.timevalInterval();
+#if defined(__APPLE__)
+        // ad-hoc fix: MacOS X's BSD rejects times of more than 100E6 seconds
+        if (duration.tv_sec > 100000000)
+            duration.tv_sec = 100000000;
+#endif
+        const int size = FDSet::words(fdMax);		// number of active words in sets
+        switch (int hits = ::select(fdMax + 1,
+                inSet.make(size), outSet.make(size), errSet.make(size),
+                &duration)) {
+        case -1:		// error
+            if (errno == EINTR)
+                continue;
+            debug("selector", "select failed: errno=%d", errno);
+            UnixError::throwMe();
+        case 0:			// no events
+            debug("selector", "select returned nothing");
+            return;
+        default:		// some events
+            debug("selector", "%d pending descriptors", hits);
+            //@@@ This could be optimized as a word-merge scan.
+            //@@@ The typical case doesn't benefit from this though, though browsers might
+            //@@@ and integrated servers definitely would.
+            for (int fd = fdMin; fd <= fdMax && hits > 0; fd++) {
+                int types = 0;
+                if (inSet[fd])  types |= input;
+                if (outSet[fd]) types |= output;
+                if (errSet[fd]) types |= critical;
+                if (types) {
+                    debug("selector", "notify fd %d client %p type %d",
+                        fd, clientMap[fd], types);
+                    clientMap[fd]->notify(fd, types);
+                    hits--;
+                }
+            }
+            return;
+        }
+    }
+}
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/selector.h b/cdsa/cdsa_utilities/selector.h
new file mode 100644
index 00000000..d39ada01
--- /dev/null
+++ b/cdsa/cdsa_utilities/selector.h
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+
+//
+// selector - I/O stream multiplexing
+//
+#ifndef _H_SELECTOR
+#define _H_SELECTOR
+
+#include <Security/utilities.h>
+#include <Security/fdsel.h>
+#include "timeflow.h"
+#include <sys/types.h>
+#include <cstdio>
+#include <cstdarg>
+#include <map>
+#include <Security/debugging.h>
+
+
+namespace Security {
+namespace UnixPlusPlus {
+
+
+//
+// A Selector is an I/O dispatch facility that can supervise any number of "file descriptors",
+// each of which can perform I/O. Obviously this is geared towards the UNIX facility.
+//
+class Selector {
+    class Client; friend class Client;
+public:
+    Selector();
+    virtual ~Selector();
+    
+    //@@@ preliminary interface
+    void operator () ();		// run just once (now)
+    void operator () (Time::Absolute stopTime);
+    void operator () (Time::Interval duration)
+    { (*this)(Time::now() + duration); }
+    
+    typedef unsigned int Type;
+    static const Type none = 0x00;
+    static const Type input = 0x01;
+    static const Type output = 0x02;
+    static const Type critical = 0x04;
+    static const Type all = input | output | critical;
+    
+public:
+    class Client {
+        typedef Selector::Type Type;
+        friend class Selector;
+    public:
+        Client() : mSelector(NULL) { }
+        virtual void notify(int fd, Type type) = 0;
+        virtual ~Client() { }
+        
+        bool isActive() const		{ return mSelector != NULL; }
+
+        static const Type input = Selector::input;
+        static const Type output = Selector::output;
+        static const Type critical = Selector::critical;
+        
+    protected:
+        void events(Type type)	{ mSelector->set(mFd, type); mEvents = type; }
+        Type events() const		{ return mEvents; }
+
+        void enable(Type type)	{ events(events() | type); }
+        void disable(Type type)	{ events(events() & ~type); }
+
+        template <class Sel> Sel &selectorAs()
+        { assert(mSelector); return safer_cast<Sel &>(*mSelector); }
+        
+    private:
+        int mFd;
+        Selector *mSelector;
+        Type mEvents;
+    };
+    
+    void add(int fd, Client &client, Type type = all);
+    void remove(int fd);
+    bool isEmpty() const				{ return clientMap.empty(); }
+    
+private:
+    void set(int fd, Type type);		// (re)set mask for one client
+    
+    void singleStep(Time::Interval maxWait);
+    
+private:
+    unsigned int fdSetSize;				// number of fd_masks allocated in FDSets
+    int fdMin, fdMax;					// highest/lowest fds in use
+    FDSet inSet, outSet, errSet;		// current in/out/error select masks
+    
+private:
+    typedef map<int, Client *> ClientMap;
+    ClientMap clientMap;
+};
+
+
+}	// end namespace UnixPlusPlus
+}	// end namespace Security
+
+
+#endif //_H_SELECTOR
diff --git a/cdsa/cdsa_utilities/socks++.cpp b/cdsa/cdsa_utilities/socks++.cpp
new file mode 100644
index 00000000..a73a0254
--- /dev/null
+++ b/cdsa/cdsa_utilities/socks++.cpp
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+
+//
+// socks - socks version of IP sockets
+//
+// [Also see comments in header file.]
+//
+// This file contains the "generic" Socks functionality.
+// Socks4 and Socks5 implementations are in their separate files.
+//
+#include "socks++.h"
+#include "socks++4.h"
+#include "socks++5.h"
+#include "hosts.h"
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+//
+// Static objects
+//
+ModuleNexus<SocksServer::Global> SocksServer::global;
+
+
+//
+// Create a SocksServer object
+//
+SocksServer *SocksServer::make(Version version, const IPSockAddress &addr)
+{
+    switch (version) {
+    case 0:
+        return NULL;		// no socks
+    case 4:
+        return new Socks4::Server(addr);
+    case 5:
+        return new Socks5::Server(addr);
+    default:
+        UnixError::throwMe(EINVAL);
+    }
+}
+
+
+//
+// TCPClientSockets (CONNECT access)
+//    
+void SocksClientSocket::open(const IPSockAddress &peer)
+{
+    if (mServer) {
+        Support::connect(*this, peer);
+        lastConnected(mPeerAddress.address());
+    } else {
+        TCPClientSocket::open(peer);
+    }
+}
+
+void SocksClientSocket::open(const IPAddress &addr, IPPort port)
+{
+    open(IPSockAddress(addr, port));
+}
+
+void SocksClientSocket::open(const Host &host, IPPort port)
+{
+    if (mServer) {
+        Support::connect(*this, host, port);
+        lastConnected(mPeerAddress.address());
+    } else {
+        TCPClientSocket::open(host, port);
+    }
+}
+
+void SocksClientSocket::setFd(int fd, const IPSockAddress &local, const IPSockAddress &peer)
+{
+    Socket::setFd(fd);
+    mLocalAddress = local;
+    mPeerAddress = peer;
+}
+
+
+//
+// TCPServerSockets (BIND access)
+//
+void SocksServerSocket::open(const IPSockAddress &local, int)
+{
+    if (mServer) {
+#if BUG_GCC
+        if (mConnectionPeer)
+            Support::bind(*this, mConnectionPeer, local.port());
+        else
+            Support::bind(*this, lastConnected(), local.port());
+#else
+        Support::bind(*this,
+            mConnectionPeer ? mConnectionPeer : lastConnected(),
+            local.port());
+#endif
+    } else {
+        TCPServerSocket::open(local, 1);
+    }
+}
+
+void SocksServerSocket::receive(SocksClientSocket &client)
+{
+    if (mServer) {
+        Support::receive(*this, client);
+    } else {
+        TCPServerSocket::receive(client);
+    }
+}
+
+
+//
+// Address functions
+//
+IPSockAddress SocksServer::Support::localAddress(const Socket &me) const
+{
+    if (mServer)
+        return mLocalAddress;
+    else
+        return me.localAddress();
+}
+
+IPSockAddress SocksServer::Support::peerAddress(const Socket &me) const
+{
+    if (mServer)
+        return mPeerAddress;
+    else
+        return me.peerAddress();
+}
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/socks++.h b/cdsa/cdsa_utilities/socks++.h
new file mode 100644
index 00000000..b2f2c37a
--- /dev/null
+++ b/cdsa/cdsa_utilities/socks++.h
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ */
+
+
+//
+// socks - socks version of IP sockets
+//
+// This Socks implementation replaces the TCP-functional layer of the socket interface
+// (TCPClientSocket and TCPServerSocket), not the raw Socket layer. Remember what
+// Socks was invented for -- it's NOT a generic socket abstraction layer, valiant efforts
+// of the various -lsocks libraries nonwithstanding.
+// Do note that these are not virtual overrides, but textual replacements.
+//
+// This implementation supports Socks versions 4 and 5, as well as direct (un-socksed) sockets.
+// The choice is per socket object.
+//
+// API Synopsis:
+//	SocksServer *server = SocksServer::make(version, IP-address);
+//	SocksServer::defaultServer(server);	// for new sockets
+//	SocksClientSocket clientSocket(...);
+//		clientSocket.server(server);		// for this socket
+//	SocksServerSocket serverSocket(...);	// only supports .receive()
+// Otherwise, Socks{Client,Server}Socket is functionally equivalent to {Client,Server}Socket.
+// Sockets without a Server (explicit or by default) are direct.
+//
+// Minimum replacement strategy:
+//	#define TCPClientSocket SocksClientSocket
+//	#define TCPServerSocket SocksServerSocket
+//	SocksServer::defaultServer(SocksServer::make(...));
+//
+// Limitations:
+// There is no UDP Socks support.
+// @@@ Nonblocking sockets may not work quite right.
+//
+#ifndef _H_SOCKSPLUSPLUS
+#define _H_SOCKSPLUSPLUS
+
+#include "ip++.h"
+#include <Security/threading.h>
+#include <Security/globalizer.h>
+
+
+using namespace UnixPlusPlus;
+
+
+namespace Security {
+namespace IPPlusPlus {
+
+
+class SocksServerSocket;
+class SocksClientSocket;
+
+
+//
+// A particular Socks server and version. Get one by calling SocksServer::make().
+// You can express "no socks server" (direct connect) with a NULL pointer (or version==0).
+//
+class SocksServer {
+    class Support; friend class Support;
+
+private:
+    struct Global {
+        mutable Mutex lock;			// lock for mGlobalServerAddress
+        SocksServer *mServer;		// global default server
+        ThreadNexus<IPAddress> lastConnected; // last address connected to (for aux. bind)
+        
+        Global() : mServer(NULL) { }
+        
+        void server(SocksServer *srv)	{ StLock<Mutex> _(lock); mServer = srv; }
+        SocksServer *server() const		{ StLock<Mutex> _(lock); return mServer; }
+    };
+    static ModuleNexus<Global> global; // global state
+
+public:
+    typedef unsigned int Version;
+    
+    static SocksServer *make(Version version, const IPSockAddress &addr);
+
+    const IPSockAddress &address() const	{ return mServerAddress; }
+    Version version() const					{ return mVersion; }
+    
+public:
+    static SocksServer *defaultServer()		{ return global().server(); }
+    static void defaultServer(SocksServer *server) { global().server(server); }
+
+protected:
+    virtual void connect(SocksClientSocket &me, const IPSockAddress &peer) = 0;
+    virtual void connect(SocksClientSocket &me, const Host &host, IPPort port) = 0;
+    virtual void bind(SocksServerSocket &me, const IPAddress &peer, IPPort port) = 0;
+    virtual void receive(SocksServerSocket &me, SocksClientSocket &receiver) = 0;
+
+    SocksServer(Version v, const IPSockAddress &addr) : mVersion(v), mServerAddress(addr) { }
+
+protected:
+    Version mVersion;
+    IPSockAddress mServerAddress;
+
+protected:
+    class Support {
+    public:
+        SocksServer *server() const		{ return mServer; }
+        void server(SocksServer *srv)	{ mServer = srv; }
+        
+        IPSockAddress localAddress(const Socket &me) const;
+        IPSockAddress peerAddress(const Socket &me) const;
+        
+    protected:
+        Support() : mServer(defaultServer()) { }
+
+        void connect(SocksClientSocket &me, const IPSockAddress &peer)	
+        { mServer->connect(me, peer); }
+        void connect(SocksClientSocket &me, const Host &host, IPPort port) 
+        { mServer->connect(me, host, port); }
+        void bind(SocksServerSocket &me, const IPAddress &peer, IPPort port)
+        { mServer->bind(me, peer, port); }
+        void receive(SocksServerSocket &me, SocksClientSocket &receiver)
+        { mServer->receive(me, receiver); }
+        
+        void lastConnected(IPAddress addr)	{ global().lastConnected() = addr; }
+        IPAddress lastConnected() const		{ return global().lastConnected(); }
+    
+    public:
+        SocksServer *mServer;				// server for this socket
+        IPSockAddress mLocalAddress;		// my own address, as reported by server
+        IPSockAddress mPeerAddress;			// peer address
+    };
+};
+
+
+//
+// The Socks version of a TCPClientSocket
+//
+class SocksClientSocket : public TCPClientSocket, public SocksServer::Support {
+public:
+    SocksClientSocket() { }
+    SocksClientSocket(const IPSockAddress &peer)				{ open(peer); }
+    SocksClientSocket(const IPAddress &addr, IPPort port)		{ open(addr, port); }
+    SocksClientSocket(const Host &host, IPPort port)			{ open(host, port); }
+    
+    void open(const IPSockAddress &peer);
+    void open(const IPAddress &addr, IPPort port);
+    void open(const Host &host, IPPort port);
+
+    IPSockAddress localAddress() const		{ return Support::localAddress(*this); }
+    IPSockAddress peerAddress() const		{ return Support::peerAddress(*this); }
+    
+public:
+    void setFd(int fd, const IPSockAddress &local, const IPSockAddress &peer);
+};
+
+
+//
+// The Socks version of a TCPServerSocket.
+// Note that this version only supports the receive() access method.
+// By the nature of things, the queue-length argument is ignored (it's always 1).
+//
+// A note about setMainConnection: There is a structural problem
+// with the Socks protocol. When a SocksServerSocket goes active,
+// the protocol requires the IP address of the host the connection will be
+// coming from. Typical Socks library layers simply assume that this will
+// be the address of the last server connected to by another (TCP) socket.
+// We do this heuristic too, but it's unreliable: it's a per-thread global, and will
+// fail if you interleave multiple socks "sessions" in the same thread. For this
+// case (or if you just want to be safe and explicit), you can call setMainConnection to
+// explicitly link this socket to a TCPClientSocket whose peer we should use.
+// Do note that this call does not exist in the plain (non-socks) socket layer.
+//
+class SocksServerSocket : public TCPServerSocket, public SocksServer::Support {
+public:
+    SocksServerSocket() { }
+    SocksServerSocket(const IPSockAddress &local, int = 1) { open(local); }
+    SocksServerSocket(IPPort port, int = 1)					{ open(port); }
+    
+    void open(const IPSockAddress &local, int = 1);
+    void open(IPPort port = 0, int = 1)
+    { open(IPSockAddress(IPAddress::any, port)); }
+    
+    void receive(SocksClientSocket &client);		// accept incoming and close listener
+
+    IPSockAddress localAddress() const		{ return Support::localAddress(*this); }
+    IPSockAddress peerAddress() const		{ return Support::peerAddress(*this); }
+    
+    // this special call is not an overlay of TCPServerSocket - it exists only for Socks
+    void setMainConnection(TCPClientSocket &main)
+    { mConnectionPeer = main.peerAddress().address(); }
+    
+private:
+    IPAddress mConnectionPeer;						// address to say we're peered with
+    
+private:
+    void operator () (TCPClientSocket &newClient);	// not supported by Socks
+};
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
+
+
+#endif //_H_IPPLUSPLUS
diff --git a/cdsa/cdsa_utilities/socks++4.cpp b/cdsa/cdsa_utilities/socks++4.cpp
new file mode 100644
index 00000000..6d992f18
--- /dev/null
+++ b/cdsa/cdsa_utilities/socks++4.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+
+//
+// socks++int - internal Socks implementation
+//
+#include "socks++4.h"
+#include "hosts.h"
+#include <set>
+
+
+namespace Security {
+namespace IPPlusPlus {
+namespace Socks4 {
+
+
+
+//
+// Socks4 Protocol implementation
+//
+void Server::connect(SocksClientSocket &me, const IPSockAddress &peer)
+{
+    me.Socket::open(SOCK_STREAM);
+    me.Socket::connect(mServerAddress);
+    Message request(socksConnect, peer);
+    request.send(me, "nobody");
+    (Message(me));				// read and check reply message
+    me.mPeerAddress = peer;		// best guess, Mr. Sulu
+    debug("socks", "%d socks4 connected to %s", me.fd(), string(peer).c_str());
+}
+
+void Server::connect(SocksClientSocket &me, const Host &host, IPPort port)
+{
+    // Socks4 has no name resolution support. Do it here
+    //@@@ error reporting sucks here
+    set<IPAddress> addrs = host.addresses();
+    for (set<IPAddress>::const_iterator it = addrs.begin(); it != addrs.end(); it++) {
+        try {
+            IPSockAddress addr(*it, port);
+            connect(me, addr);
+            return;
+        } catch (UnixError &err) {
+            errno = err.error;
+        }
+    }
+    // exhausted
+    UnixError::throwMe();
+}
+
+
+void Server::bind(SocksServerSocket &me, const IPAddress &peer, IPPort port)
+{
+    me.Socket::open(SOCK_STREAM);
+    me.Socket::connect(mServerAddress);
+    Message request(socksBind, IPSockAddress(peer, port));
+    request.send(me, "nobody");
+    Message reply(me);
+    me.mLocalAddress = reply.address().defaults(mServerAddress.address());
+    debug("socks", "%d socks4 bound to %s", me.fd(), string(me.mLocalAddress).c_str());
+}
+
+void Server::receive(SocksServerSocket &me, SocksClientSocket &receiver)
+{
+    Message reply(me);
+    receiver.setFd(me.fd(), me.mLocalAddress, reply.address());
+    me.clear();					// clear our own (don't close on destruction)
+    debug("socks", "%d socks4 inbound connect", receiver.fd());
+}
+
+
+//
+// Message properties
+//
+Message::Message(Command cmd, const IPSockAddress &address)
+    : version(4), message(cmd), port(htons(address.port())), addr(address.address())
+{
+}
+
+
+void Message::send(Socket &s, const char *userid)
+{
+    if (s.write(this, sizeof(*this)) != sizeof(*this))
+        UnixError::throwMe();
+    // now append zero-terminated userid (what a crock)
+    size_t length = strlen(userid) + 1;
+    if (s.write(userid, length) != length) {
+        s.close();
+        UnixError::throwMe();
+    }
+}
+
+Message::Message(Socket &s)
+{
+    if (s.read(this, sizeof(*this)) != sizeof(*this)) {
+        s.close();
+        UnixError::throwMe();
+    }
+    if (version != 0) {
+        s.close();
+        UnixError::throwMe(EPROTONOSUPPORT);
+    }
+    switch (message) {
+    case requestAccepted:
+        return;
+    default:
+        UnixError::throwMe(ECONNREFUSED);	//@@@ hardly any diagnostics here
+    }
+}
+
+
+}	// end namespace Socks
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/socks++4.h b/cdsa/cdsa_utilities/socks++4.h
new file mode 100644
index 00000000..290ff699
--- /dev/null
+++ b/cdsa/cdsa_utilities/socks++4.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+
+//
+// socks++int - internal header for Socks implementation
+//
+#ifndef _H_SOCKSPLUSPLUSINT
+#define _H_SOCKSPLUSPLUSINT
+
+#include "socks++.h"
+
+
+namespace Security {
+namespace IPPlusPlus {
+namespace Socks4 {
+
+
+typedef unsigned char Byte;
+
+
+enum Command {
+    socksConnect = 1,
+    socksBind = 2
+};
+
+enum Reply {
+    requestAccepted = 90,
+    requestFailed = 91,
+    requestIdentFailed = 92,
+    requestIdentRejected = 93
+};
+
+
+class Server : public SocksServer {
+public:
+    Server(const IPSockAddress &s) : SocksServer(4, s) { }
+    
+    virtual void connect(SocksClientSocket &me, const IPSockAddress &peer);
+    virtual void connect(SocksClientSocket &me, const Host &host, IPPort port);
+    virtual void bind(SocksServerSocket &me, const IPAddress &peer, IPPort port);
+    virtual void receive(SocksServerSocket &me, SocksClientSocket &receiver);
+};
+
+
+struct Message {
+    Byte version;
+    Byte message;
+    IPPort port;
+    IPAddress addr;
+    
+    Message(Command cmd, const IPSockAddress &addr);
+    void send(Socket &s, const char *userid);
+
+    Message(Socket &s);
+    
+    IPSockAddress address() const	{ return IPSockAddress(addr, port); }
+};
+
+
+
+}	// end namespace Socks
+}	// end namespace IPPlusPlus
+}	// end namespace Security
+
+#endif //_H_SOCKSPLUSPLUSINT
\ No newline at end of file
diff --git a/cdsa/cdsa_utilities/socks++5.cpp b/cdsa/cdsa_utilities/socks++5.cpp
new file mode 100644
index 00000000..c141703f
--- /dev/null
+++ b/cdsa/cdsa_utilities/socks++5.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+
+//
+// socks++int - internal Socks implementation
+//
+#include "socks++5.h"
+#include "hosts.h"
+
+
+namespace Security {
+namespace IPPlusPlus {
+namespace Socks5 {
+
+
+//
+// Socks5 Protocol implementation
+//
+void Server::open(Socket &s, Support &my)
+{
+    s.open(SOCK_STREAM);
+    s.connect(my.mServer->address());
+    debug("socks", "%d connected to server %s", s.fd(), string(my.mServer->address()).c_str());
+    Byte request[] = { 5, 1, socksAuthPublic };
+    s.write(request, sizeof(request));
+    Byte reply[2];
+    s.read(reply, sizeof(reply));
+    if (reply[0] != 5 || reply[1] != socksAuthPublic) {
+        debug("socks", "%d server failed (v%d auth=%d)", s.fd(), reply[0], reply[1]);
+        s.close();
+        UnixError::throwMe(EPROTONOSUPPORT);
+    }
+}
+
+void Server::connect(SocksClientSocket &me, const IPSockAddress &peer)
+{
+    open(me, me);
+    Message request(socksConnect, peer.address(), peer.port());
+    request.send(me);
+    Message reply(me);
+    me.mLocalAddress = reply.address();
+    me.mPeerAddress = peer;
+    debug("socks", "%d socks connected to %s", me.fd(), string(peer).c_str());
+}
+
+void Server::connect(SocksClientSocket &me, const Host &host, IPPort port)
+{
+#if 1
+    //@@@ should be using Hostname (server resolution) mode, but this won't get us
+    //@@@ any useful peer address to use for bind relaying. Need to rethink this scenario.
+    set<IPAddress> addrs = host.addresses();
+    for (set<IPAddress>::const_iterator it = addrs.begin(); it != addrs.end(); it++) {
+        try {
+            IPSockAddress addr(*it, port);
+            connect(me, addr);
+            return;
+        } catch (UnixError &err) {
+            errno = err.error;
+        }
+    }
+    // exhausted
+    UnixError::throwMe();
+#else
+    open(me, me);
+    Message request(socksConnect, host.name().c_str(), port);
+    request.send(me);
+    Message reply(me);
+    me.mLocalAddress = reply.address();
+    //me.mPeerAddress = not provided by Socks5 protocol;
+    debug("socks", "%d socks connected to %s", me.fd(), host.name().c_str());
+#endif
+}
+
+
+void Server::bind(SocksServerSocket &me, const IPAddress &peer, IPPort port)
+{
+    open(me, me);
+    Message request(socksBind, peer, port);
+    request.send(me);
+    Message reply(me);
+    me.mLocalAddress = reply.address();
+    //me.mPeerAddress not available yet;
+    debug("socks", "%d socks bound to %s", me.fd(), string(me.mLocalAddress).c_str());
+}
+
+void Server::receive(SocksServerSocket &me, SocksClientSocket &receiver)
+{
+    Message reply(me);
+    receiver.setFd(me.fd(), me.mLocalAddress, reply.address());
+    me.clear();					// clear our own (don't close on destruction)
+    debug("socks", "%d socks received from %s", receiver.fd(), string(reply.address()).c_str());
+}
+
+
+//
+// Construct a request from an IPv4 address and port
+//
+Message::Message(Command cmd, IPAddress addr, IPPort port)
+{
+    version = 5;
+    message = cmd;
+    reserved = 0;
+    addressType = socksIPv4;
+    this->addr = addr;
+    this->port = htons(port);
+    length = 4 + sizeof(this->addr) + sizeof(this->port);
+}
+
+
+//
+// Construct a request from a hostname and port (server resolves name)
+//
+Message::Message(Command cmd, const char *hostname, IPPort port)
+{
+    version = 5;
+    message = cmd;
+    reserved = 0;
+    addressType = socksName;
+    
+    size_t nameLength = strlen(hostname);
+    if (nameLength > 255)
+        UnixError::throwMe(ENAMETOOLONG);
+    char *addrp = reinterpret_cast<char *>(&addr);
+    addrp[0] = nameLength;
+    memcpy(addrp + 1, hostname, nameLength);
+    IPPort nboPort = htons(port);
+    memcpy(addrp + 1 + nameLength, &nboPort, sizeof(nboPort));
+    length = 4 + 1 + nameLength + sizeof(nboPort);
+}
+
+
+//
+// Send a completed request message
+//
+void Message::send(Socket &s)
+{
+    if (s.write(this, length) != length) {
+        s.close();
+        UnixError::throwMe(EIO);
+    }
+}
+
+
+//
+// Construct a reply object from a socket source.
+// Throws exceptions if the reply is not successful and supported.
+//
+Message::Message(Socket &socket)
+{
+    length = 4 + sizeof(addr) + sizeof(port);	//@@@ calculate if addrType != 1 supported
+    
+    if (socket.read(this, length) != length) {
+        socket.close();
+        UnixError::throwMe(EIO);
+    }
+
+    // check error code
+    switch (message) {
+    case socksSuccess:
+        break;
+    case socksDenied:
+        UnixError::throwMe(EPERM);
+    case socksNetUnreach:
+        UnixError::throwMe(ENETUNREACH);
+    case socksHostUnreach:
+        UnixError::throwMe(EHOSTUNREACH);
+    case socksConRefused:
+        UnixError::throwMe(ECONNREFUSED);
+    case socksTTLExpired:
+        UnixError::throwMe(ETIMEDOUT);	// not really, but what's better?
+    case socksUnsupported:
+        UnixError::throwMe(EOPNOTSUPP);
+    case socksAddressNotSupported:
+        UnixError::throwMe(EADDRNOTAVAIL);
+    default:
+        UnixError::throwMe(EIO);	// what else? :-)
+    }
+    
+    // can't deal with non-IPv4 address replies
+    if (addressType != socksIPv4 || reserved != 0)
+        UnixError::throwMe(ENOTSUP);
+}
+
+
+}	// end namespace Socks
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/socks++5.h b/cdsa/cdsa_utilities/socks++5.h
new file mode 100644
index 00000000..9fd946c9
--- /dev/null
+++ b/cdsa/cdsa_utilities/socks++5.h
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+
+//
+// socks++5 - version 5 Socks protocol
+//
+#ifndef _H_SOCKSPLUSPLUS5
+#define _H_SOCKSPLUSPLUS5
+
+#include "socks++.h"
+
+
+namespace Security {
+namespace IPPlusPlus {
+namespace Socks5 {
+
+
+typedef unsigned char Byte;
+
+
+class Server : public SocksServer {
+public:
+    Server(const IPSockAddress &s) : SocksServer(5, s) { }
+    
+    virtual void connect(SocksClientSocket &me, const IPSockAddress &peer);
+    virtual void connect(SocksClientSocket &me, const Host &host, IPPort port);
+    virtual void bind(SocksServerSocket &me, const IPAddress &peer, IPPort port);
+    virtual void receive(SocksServerSocket &me, SocksClientSocket &receiver);
+    
+private:
+    void open(Socket &s, Support &me);
+};
+
+
+// request code (message field outbound)
+enum Command {
+    socksConnect = 1,					// connect (outbound)
+    socksBind = 2,						// bind (single inbound)
+    socksUDP = 3						// UDP associate (not implemented)
+};
+
+// reply code (message field inbound)
+enum SocksReply {
+    socksSuccess = 0,
+    socksFailed = 1,
+    socksDenied = 2,
+    socksNetUnreach = 3,
+    socksHostUnreach = 4,
+    socksConRefused = 5,
+    socksTTLExpired = 6,
+    socksUnsupported = 7,
+    socksAddressNotSupported = 8
+};
+
+// authentication type (in setup request)
+enum AuthenticationType {
+    socksAuthPublic = 0,				// anonymous access
+    socksAuthGSSAPI = 1,				// GSSAPI (yuk)
+    socksAuthUsername = 2,				// username/password
+    socksAuthNoneAcceptable = 0xff		// can't help you there...
+};
+
+// address types (inbound/outbound)
+enum AddressType {
+    socksIPv4 = 1,
+    socksName = 3,
+    socksIPv6 = 4
+};
+
+
+//
+// A Message object contains a single request or reply of the Socks5 protocol.
+// Since some of the data is dynamically sized, we have to fudge a bit. The static
+// layout corresponds to IPv4 addresses, the common case. The object itself is big
+// enough for all cases.
+//
+struct Message {
+    Byte version;			// Socks version
+    Byte message;			// message/reply
+    Byte reserved;			// not used (zero)
+    Byte addressType;		// address type
+    IPAddress addr;			// address starts here (IPv4 case)
+    // following fields dynamically located if (addressType != socksIPv4)
+    IPPort port;			// port field IF addr is IPv4
+    Byte pad[256-sizeof(IPAddress)-sizeof(IPPort)]; // enough room for type 3 addresses (256 bytes)
+
+    // the following fields are not part of the message data
+    size_t length;			// calculated length of message (bytes, starting at version)
+    
+    Message(Command cmd, IPAddress addr, IPPort port);	// type 1 request
+    Message(Command cmd, const char *hostname, IPPort port); // type 3 request
+    void send(Socket &s);	// send request
+
+    Message(Socket &socket); // receive (type 1 only)
+    
+    IPSockAddress address() const	{ return IPSockAddress(addr, ntohs(port)); }
+};
+
+
+}	// end namespace Socks
+}	// end namespace IPPlusPlus
+}	// end namespace Security
+
+#endif //_H_SOCKSPLUSPLUS5
\ No newline at end of file
diff --git a/cdsa/cdsa_utilities/streams.cpp b/cdsa/cdsa_utilities/streams.cpp
new file mode 100644
index 00000000..cff66697
--- /dev/null
+++ b/cdsa/cdsa_utilities/streams.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+
+//
+// streams.h - lightweight source and sink objects
+//
+#include "streams.h"
+#include <Security/memutils.h>
+
+
+namespace Security {
+
+
+//
+// Source and Sink abstract superclasses
+//
+Source::State Source::state() const
+{
+    return mState;
+}
+
+size_t Source::getSize()
+{
+    return unknownSize;
+}
+
+void Sink::setSize(size_t)
+{
+    // ignored
+}
+
+
+//
+// Null sources and sinks
+//
+void NullSource::produce(void *, size_t &length)
+{
+    length = 0;
+}
+
+Source::State NullSource::state() const
+{
+    return endOfData;
+}
+
+void NullSink::consume(const void *, size_t)
+{
+    // ignore the data
+}
+
+
+//
+// File sources and sinks
+//
+void FileSource::produce(void *data, size_t &length)
+{
+    if ((length = read(data, length)) == 0)
+        mState = endOfData;
+}
+
+size_t FileSource::getSize()
+{
+    return fileSize();
+}
+
+
+void FileSink::consume(const void *data, size_t length)
+{
+	write(data, length);
+}
+
+
+//
+// Memory sources
+//
+void MemorySource::produce(void *data, size_t &length)
+{
+    if (mRemaining < length)
+        length = mRemaining;
+    memcpy(data, mData, length);
+    mData = LowLevelMemoryUtilities::increment(mData, length);
+    mRemaining -= length;
+}
+
+size_t MemorySource::getSize()
+{
+    return mRemaining;
+}
+
+Source::State MemorySource::state() const
+{
+    return mRemaining ? producing : endOfData;
+}
+
+
+//
+// Memory sinks
+//
+void MemorySink::consume(const void *data, size_t length)
+{
+    if (mSize + length > mMax)
+        grow(mSize * 3 / 2);
+    assert(mSize + length <= mMax);
+    memcpy(((char *)mBuffer) + mSize, data, length);
+    mSize += length;
+}
+
+void MemorySink::setSize(size_t expectedSize)
+{
+    grow(expectedSize);
+}
+
+void MemorySink::grow(size_t newSize)
+{
+    if (void *p = realloc(mBuffer, newSize)) {
+        mBuffer = p;
+        mMax = newSize;
+    } else
+        UnixError::throwMe();
+}
+
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/streams.h b/cdsa/cdsa_utilities/streams.h
new file mode 100644
index 00000000..b1740b81
--- /dev/null
+++ b/cdsa/cdsa_utilities/streams.h
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+
+//
+// streams.h - lightweight source and sink objects
+//
+#ifndef _H_STREAMS
+#define _H_STREAMS
+
+#include "unix++.h"
+
+
+namespace Security {
+
+using UnixPlusPlus::FileDesc;
+
+
+//
+// An abstract Source object.
+// Source can yield data when its produce method is called. Produce can yield
+// anything between zero and length bytes and sets length accordingly.
+// If the last call to produce returned zero bytes (and only then), the state method
+// will yield an explanation:
+//	producing -> we're in business; there just no data quite yet (try again)
+//	stalled -> there may be more data coming, but not in the near future;
+//			wait a while then call state again to see
+//	endOfData -> no more data will be produced by this Source
+// When called *before* the first call to produce, getSize may return the number
+// of bytes that all calls to produce will yield together. If getSize returns unknownSize,
+// this value cannot be determined beforehand. GetSize *may* yield the number of bytes
+// yet to come when called after produce, but this is not guaranteed for all Sources.
+//
+class Source {
+public:
+    virtual void produce(void *data, size_t &length) = 0;
+    virtual ~Source() { }
+
+    static const size_t unknownSize = size_t(-1);
+    virtual size_t getSize();
+    
+    enum State {
+        producing,		// yielding data (go ahead)
+        stalled,		// no data now, perhaps more later
+        endOfData		// end of data (no more data)
+    };
+    virtual State state() const;
+    
+protected:
+    State mState;		// auto-regulated state (can be overridden)
+};
+
+
+//
+// An abstract Sink object.
+// Sinks can cansume data when their consume method is called.
+// Sinks cannot refuse data; they always consume all data given to consume.
+// There is currently no flow control/throttle mechanism (one will probably
+// be added soon).
+//
+class Sink {
+public:
+    virtual ~Sink() { }
+    virtual void consume(const void *data, size_t length) = 0;
+    virtual void setSize(size_t expectedSize);
+};
+
+
+//
+// The NullSource produces no data.
+//
+class NullSource : public Source {
+public:
+    void produce(void *addr, size_t &len);
+    State state() const;
+};
+
+
+//
+// A FileSource reads from a UNIX file or file descriptor.
+// Note that getSize will yield the size of the underlying i-node,
+// which is usually correct but may not be in the case of simultaneous
+// access.
+//
+class FileSource : public Source, public FileDesc {
+public:
+    FileSource(const char *path, int mode = O_RDONLY) : FileDesc(path, mode) { mState = producing; }
+    FileSource(int fd) : FileDesc(fd) { mState = producing; }
+    void produce(void *data, size_t &length);
+    size_t getSize();
+};
+
+
+//
+// A MemorySource yields the contents of a preset contiguous memory block.
+//
+class MemorySource : public Source {
+public:
+    MemorySource(const void *data, size_t length) : mData(data), mRemaining(length) { }
+
+    template <class Data>
+    MemorySource(const Data &data) : mData(data.data()), mRemaining(data.length()) { }
+    
+    void produce(void *data, size_t &length);
+    size_t getSize();
+    State state() const;
+    
+private:
+    const void *mData;
+    size_t mRemaining;
+};
+
+
+//
+// A NullSink eats all data and discards it quietly.
+//
+class NullSink : public Sink {
+public:
+    void consume(const void *data, size_t length);
+};
+
+
+//
+// A FileSink writes its received data to a UNIX file or file descriptor.
+//
+class FileSink : public Sink, public FileDesc {
+public:
+    FileSink(const char *path, int mode = O_WRONLY | O_CREAT | O_TRUNC)
+        : FileDesc(path, mode) { }
+    FileSink(int fd) : FileDesc(fd) { }
+    void consume(const void *data, size_t length);
+};
+
+
+//
+// MemorySinks collect output in a contiguous memory block.
+// This is not often a good idea, so if you find yourself using this,
+// consider consuming on-the-fly or streaming to secondary media,
+// or (at least) use a BufferFifo instead.
+//
+class MemorySink : public Sink {
+public:
+    MemorySink() : mBuffer(NULL), mSize(0), mMax(0) { }
+    ~MemorySink()	{ free(mBuffer); }
+    
+    void consume(const void *data, size_t length);
+    void setSize(size_t expectedSize);
+    
+    void *data() const		{ return mBuffer; }
+    size_t length() const	{ return mSize; }
+    
+    void clear()			{ free(mBuffer); mBuffer = NULL; mSize = mMax = 0; }
+    
+private:
+    void grow(size_t newSize);
+    
+private:
+    void *mBuffer;		// buffer base
+    size_t mSize;		// currently used
+    size_t mMax;		// currently allocated
+};
+
+
+}	// end namespace Security
+
+
+#endif _H_STREAMS
diff --git a/cdsa/cdsa_utilities/threading.cpp b/cdsa/cdsa_utilities/threading.cpp
new file mode 100644
index 00000000..8756095d
--- /dev/null
+++ b/cdsa/cdsa_utilities/threading.cpp
@@ -0,0 +1,310 @@
+/*
+ * 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.
+ */
+
+
+//
+// threading - generic thread support
+//
+
+
+//
+// Since we are planning to generate "stub" out of line code for threading methods,
+// we must force THREAD_NDEBUG to off while compiling our header. Trust me.
+//
+#if !defined(THREAD_CLEAN_NDEBUG)
+# define THREAD_MAKE_STUBS
+#endif
+#include <Security/threading.h>
+
+
+//
+// Thread-local storage primitive
+//
+#if _USE_THREADS == _USE_PTHREADS
+
+ThreadStoreSlot::ThreadStoreSlot(Destructor *destructor)
+{
+    if (int err = pthread_key_create(&mKey, destructor))
+        UnixError::throwMe(err);
+}
+
+ThreadStoreSlot::~ThreadStoreSlot()
+{
+    //@@@ if we wanted to dispose of pending task objects, we'd have
+    //@@@ to keep a set of them and delete them explicitly here
+    pthread_key_delete(mKey);
+}
+
+#endif
+
+
+//
+// Mutex implementation
+//
+#if _USE_THREADS == _USE_PTHREADS
+
+#if !defined(THREAD_CLEAN_NDEBUG)
+
+bool Mutex::debugHasInitialized;
+bool Mutex::loggingMutexi;
+
+Mutex::Mutex(bool log)
+{
+#if !defined(THREAD_NDEBUG)
+	// this debug-setup code isn't interlocked, but it's idempotent
+	// (don't worry, be happy)
+	if (!debugHasInitialized) {
+		loggingMutexi = Debug::debugging("mutex");
+		debugHasInitialized = true;
+	}
+	debugLog = log && loggingMutexi;
+    useCount = contentionCount = 0;
+#else
+    debugLog = false;
+#endif //THREAD_NDEBUG    
+	check(pthread_mutex_init(&me, NULL));
+}
+
+Mutex::~Mutex()
+{
+#if !defined(THREAD_NDEBUG)
+	if (debugLog && (useCount > 100 || contentionCount > 0))
+		debug("mutex", "%p destroyed after %ld/%ld locks/contentions", this, useCount, contentionCount);
+#endif //THREAD_NDEBUG
+	check(pthread_mutex_destroy(&me));
+}
+
+void Mutex::lock()
+{
+#if !defined(THREAD_NDEBUG)
+	useCount++;
+	if (debugLog) {
+		switch (int err = pthread_mutex_trylock(&me)) {
+		case 0:
+			break;
+		case EBUSY:
+			if (debugLog)
+				debug("mutex", "%p contended (%ld of %ld)", this, ++contentionCount, useCount);
+			check(pthread_mutex_lock(&me));
+			break;
+		default:
+			UnixError::throwMe(err);
+		}
+		if (useCount % 100 == 0)
+			debug("mutex", "%p locked %ld", this, useCount);
+		else
+			debug("mutex", "%p locked", this);
+        return;
+    }
+#endif //THREAD_NDEBUG
+	check(pthread_mutex_lock(&me));
+}
+
+bool Mutex::tryLock()
+{
+	useCount++;
+	if (int err = pthread_mutex_trylock(&me)) {
+		if (err != EBUSY)
+			UnixError::throwMe(err);
+#if !defined(THREAD_NDEBUG)
+		if (debugLog)
+			debug("mutex", "%p trylock contended (%ld of %ld)",
+				this, ++contentionCount, useCount);
+#endif //THREAD_NDEBUG
+		return false;
+	}
+#if !defined(THREAD_NDEBUG)
+	if (debugLog)
+		if (useCount % 100 == 0)
+			debug("mutex", "%p locked %ld", this, useCount);
+		else
+			debug("mutex", "%p locked", this);
+#endif //THREAD_NDEBUG
+	return true;
+}
+
+void Mutex::unlock()
+{
+#if !defined(MUTEX_NDEBUG)
+	if (debugLog)
+		debug("mutex", "%p unlocked", this);
+#endif //MUTEX_NDEBUG
+	check(pthread_mutex_unlock(&me));
+}
+
+#endif //!THREAD_CLEAN_NDEBUG
+#endif //PTHREADS
+
+
+//
+// CountingMutex implementation.
+// Note that this is a generic implementation based on a specific Mutex type.
+// In other words, it should work no matter how Mutex is implemented.
+// Also note that CountingMutex is expected to interlock properly with Mutex,
+// so you canNOT just use an AtomicCounter here.
+//
+void CountingMutex::enter()
+{
+    lock();
+    mCount++;
+    debug("mutex", "%p up to %d", this, mCount);
+    unlock();
+}
+
+bool CountingMutex::tryEnter()		
+{
+    if (!tryLock())
+        return false;
+    mCount++;
+    debug("mutex", "%p up to %d (was try)", this, mCount);
+    unlock();
+    return true;
+}
+
+void CountingMutex::exit()
+{
+    lock();
+    assert(mCount > 0);
+    mCount--;
+    debug("mutex", "%p down to %d", this, mCount);
+    unlock();
+}
+
+void CountingMutex::finishEnter()
+{
+    mCount++;
+    debug("mutex", "%p finish up to %d", this, mCount);
+    unlock();
+}
+
+void CountingMutex::finishExit()
+{
+    assert(mCount > 0);
+    mCount--; 
+    debug("mutex", "%p finish down to %d", this, mCount);
+    unlock();
+}
+
+
+
+//
+// Threads implementation
+//
+#if _USE_THREADS == _USE_PTHREADS
+
+Thread::~Thread()
+{
+}
+
+void Thread::run()
+{
+    if (int err = pthread_create(&self.mIdent, NULL, runner, this))
+        UnixError::throwMe(err);
+	debug("thread", "%p created", self.mIdent);
+}
+
+void *Thread::runner(void *arg)
+{
+    Thread *me = static_cast<Thread *>(arg);
+    if (int err = pthread_detach(me->self.mIdent))
+        UnixError::throwMe(err);
+	debug("thread", "%p starting", me->self.mIdent);
+    me->action();
+	debug("thread", "%p terminating", me->self.mIdent);
+    delete me;
+    return NULL;
+}
+
+void Thread::yield()
+{
+	sched_yield();
+}
+
+#if !defined(NDEBUG)
+
+#include <Security/memutils.h>
+
+void Thread::Identity::getIdString(char id[idLength])
+{
+	pthread_t current = pthread_self();
+	// We're not supposed to know what a pthread_t is. Just print the first few bytes...
+	// (On MacOS X, it's a pointer to a pthread_t internal structure, so this works fine.)
+	void *p;
+	memcpy(&p, &current, sizeof(p));
+	snprintf(id, idLength, "%lx", long(p));
+}
+
+#endif // NDEBUG
+
+#endif // PTHREADS
+
+
+//
+// ThreadRunner implementation
+//
+ThreadRunner::ThreadRunner(Action *todo)
+{
+    mAction = todo;
+    run();
+}
+
+void ThreadRunner::action()
+{
+    mAction();
+}
+
+
+//
+// Nesting Mutexi.
+// This implementation uses mWait as a "sloppy" wait blocker (only).
+// It should be a semaphore of course, but we don't have a semaphore
+// abstraction right now. The authoritative locking protocol is based on mLock.
+//
+NestingMutex::NestingMutex() : mCount(0)
+{ }
+
+void NestingMutex::lock()
+{
+    while (!tryLock()) {
+        mWait.lock();
+        mWait.unlock();
+    }
+}
+
+bool NestingMutex::tryLock()
+{
+    StLock<Mutex> _(mLock);
+    if (mCount == 0) {	// initial lock
+        mCount = 1;
+        mIdent = Thread::Identity::current();
+        mWait.lock();
+        return true;
+    } else if (mIdent == Thread::Identity::current()) {	// recursive lock
+        mCount++;
+        return true;
+    } else {	// locked by another thread
+        return false;
+    }
+}
+
+void NestingMutex::unlock()
+{
+    StLock<Mutex> _(mLock);
+    assert(mCount > 0 && mIdent == Thread::Identity::current());
+    if (--mCount == 0)	// last recursive unlock
+        mWait.unlock();
+}
diff --git a/cdsa/cdsa_utilities/threading.h b/cdsa/cdsa_utilities/threading.h
new file mode 100644
index 00000000..a2babe54
--- /dev/null
+++ b/cdsa/cdsa_utilities/threading.h
@@ -0,0 +1,418 @@
+/*
+ * 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.
+ */
+
+
+//
+// threading - generic thread support
+//
+#ifndef _H_THREADING
+#define _H_THREADING
+
+#include <Security/utilities.h>
+#include <Security/debugging.h>
+
+#if _USE_THREADS == _USE_PTHREADS
+# include <pthread.h>
+#endif
+
+#include <Security/threading_internal.h>
+
+
+namespace Security {
+
+
+//
+// Potentially, debug-logging all Mutex activity can really ruin your
+// performance day. We take some measures to reduce the impact, but if
+// you really can't stomach any overhead, define THREAD_NDEBUG to turn
+// (only) thread debug-logging off. NDEBUG will turn this on automatically.
+// On the other hand, throwing out all debug code will change the ABI of
+// Mutexi in incompatible ways. Thus, we still generate the debug-style out-of-line
+// code even with THREAD_NDEBUG, so that debug-style code will work with us.
+// If you want to ditch it completely, #define THREAD_CLEAN_NDEBUG.
+//
+#if defined(NDEBUG) || defined(THREAD_CLEAN_NDEBUG)
+# if !defined(THREAD_NDEBUG)
+#  define THREAD_NDEBUG
+# endif
+#endif
+
+
+//
+// An abstraction of a per-thread untyped storage slot of pointer size.
+// Do not use this in ordinary code; this is for implementing other primitives only.
+// Use a PerThreadPointer or ThreadNexus.
+//
+#if _USE_THREADS == _USE_PTHREADS
+
+class ThreadStoreSlot {
+public:
+	typedef void Destructor(void *);
+    ThreadStoreSlot(Destructor *destructor = NULL);
+    ~ThreadStoreSlot();
+
+    void *get() const			{ return pthread_getspecific(mKey); }
+    operator void * () const	{ return get(); }
+    void operator = (void *value) const
+    {
+        if (int err = pthread_setspecific(mKey, value))
+            UnixError::throwMe(err);
+    }
+
+private:
+    pthread_key_t mKey;
+};
+
+#endif //_USE_PTHREADS
+
+
+//
+// Per-thread pointers are patterned after the pthread TLS (thread local storage)
+// facility.
+//
+#if _USE_THREADS == _USE_PTHREADS
+
+template <class T>
+class PerThreadPointer : public ThreadStoreSlot {
+public:
+	PerThreadPointer(bool cleanup = true) : ThreadStoreSlot(cleanup ? destructor : NULL) { }
+	operator bool() const		{ return get() != NULL; }
+	operator T * () const		{ return reinterpret_cast<T *>(get()); }
+    T *operator -> () const		{ return static_cast<T *>(*this); }
+    T &operator * () const		{ return *static_cast<T *>(get()); }
+    void operator = (T *t)		{ ThreadStoreSlot::operator = (t); }
+	
+private:
+	static void destructor(void *element)
+	{ delete reinterpret_cast<T *>(element); }
+};
+
+#elif _USE_THREADS == _USE_NO_THREADS
+
+template <class T>
+class PerThreadPointer {
+public:
+	PerThreadPointer(bool cleanup = true) : mCleanup(cleanup) { }
+    ~PerThreadPointer()			{ if (mCleanup) delete mValue; }
+	operator bool() const		{ return mValue != NULL; }
+	operator T * () const		{ return mValue; }
+    T *operator -> () const		{ return mValue; }
+    T &operator * () const		{ assert(mValue); return *mValue; }
+    void operator = (T *t)		{ mValue = t; }
+
+private:
+    T *mValue;
+    bool mCleanup;
+};
+
+#else
+# error Unsupported threading model
+#endif //_USE_THREADS
+
+
+//
+// Basic Mutex operations.
+// This will be some as-cheap-as-feasible locking primitive that only
+// controls one bit (locked/unlocked), plus whatever you contractually
+// put under its control.
+//
+#if _USE_THREADS == _USE_PTHREADS
+
+class Mutex {
+    NOCOPY(Mutex)
+    
+    void check(int err)	{ if (err) UnixError::throwMe(err); }
+
+public:
+#if defined(THREAD_NDEBUG) && !defined(THREAD_MAKE_STUBS)
+	Mutex(bool = true)	{ check(pthread_mutex_init(&me, NULL)); }
+    void lock()			{ check(pthread_mutex_lock(&me)); }
+	bool tryLock() {
+		if (int err = pthread_mutex_trylock(&me))
+			if (err == EBUSY) return false; else UnixError::throwMe(err);
+		else return true;
+	}
+	void unlock()		{ check(pthread_mutex_unlock(&me)); }
+    ~Mutex()			{ check(pthread_mutex_destroy(&me)); }
+#else //THREAD_NDEBUG
+    Mutex(bool log = true);
+	~Mutex();
+    void lock();
+	bool tryLock();
+    void unlock();
+#endif //THREAD_NDEBUG
+
+private:
+    pthread_mutex_t me;
+	
+#if !defined(THREAD_CLEAN_NDEBUG)
+	bool debugLog;						// log *this* mutex
+	unsigned long useCount;				// number of locks succeeded
+	unsigned long contentionCount;		// number of contentions (valid only if debugLog)
+	static bool debugHasInitialized;	// global: debug state set up
+	static bool loggingMutexi;			// global: we are debug-logging mutexi
+#endif //THREAD_CLEAN_NDEBUG
+};
+
+#elif _USE_THREADS == _USE_NO_THREADS
+
+class Mutex {
+public:
+    void lock(bool = true) { }
+    void unlock() { }
+    bool tryLock() { return true; }
+};
+
+#else
+# error Unsupported threading model
+#endif //_USE_THREADS
+
+
+//
+// A CountingMutex adds a counter to a Mutex.
+// NOTE: This is not officially a semaphore, even if it happens to be implemented with
+//  one on some platforms.
+//
+class CountingMutex : public Mutex {
+    // note that this implementation works for any system implementing Mutex *somehow*
+public:
+    CountingMutex() : mCount(0) { }
+    ~CountingMutex() { assert(mCount == 0); }
+
+    void enter();
+    bool tryEnter();
+    void exit();
+
+    // these methods do not lock - use only while you hold the lock
+    unsigned int count() const { return mCount; }
+    bool isIdle() const { return mCount == 0; }
+
+    // convert Mutex lock to CountingMutex enter/exit. Expert use only
+    void finishEnter();
+	void finishExit();
+   
+private:
+    unsigned int mCount;
+};
+ 
+
+//
+// A guaranteed-unlocker stack-based class.
+// By default, this will use lock/unlock methods, but you can provide your own
+// alternates (to, e.g., use enter/exit, or some more specialized pair of operations).
+//
+// NOTE: StLock itself is not thread-safe. It is intended for use (usually on the stack)
+// by a single thread.
+//
+template <class Lock,
+	void (Lock::*_lock)() = &Lock::lock,
+	void (Lock::*_unlock)() = &Lock::unlock>
+class StLock {
+public:
+	StLock(Lock &lck) : me(lck)			{ (me.*_lock)(); mActive = true; }
+	StLock(Lock &lck, bool option) : me(lck), mActive(option) { }
+	~StLock()							{ if (mActive) (me.*_unlock)(); }
+
+	bool isActive() const				{ return mActive; }
+	void lock()							{ if(!mActive) { (me.*_lock)(); mActive = true; }}
+	void unlock()						{ if(mActive) { (me.*_unlock)(); mActive = false; }}
+
+	operator const Lock &() const		{ return me; }
+	
+protected:
+	Lock &me;
+	bool mActive;
+};
+
+
+//
+// Atomic increment/decrement operations.
+// The default implementation uses a Mutex. However, many architectures can do
+// much better than that.
+// Be very clear on the nature of AtomicCounter. It implies no memory barriers of
+// any kind. This means that (1) you cannot protect any other memory region with it
+// (use a Mutex for that), and (2) it may not enforce cross-processor ordering, which
+// means that you have no guarantee that you'll see modifications by other processors
+// made earlier (unless another mechanism provides the memory barrier).
+// On the other hand, if your compiler has brains, this is blindingly fast...
+//
+template <class Integer = int>
+class StaticAtomicCounter {
+protected:
+
+#if defined(_HAVE_ATOMIC_OPERATIONS)
+    AtomicWord mValue;
+public:
+    operator Integer() const	{ return mValue; }
+
+    // infix versions (primary)
+    Integer operator ++ ()		{ return atomicIncrement(mValue); }
+    Integer operator -- ()		{ return atomicDecrement(mValue); }
+    
+    // postfix versions
+    Integer operator ++ (int)	{ return atomicIncrement(mValue) - 1; }
+    Integer operator -- (int)	{ return atomicDecrement(mValue) + 1; }
+
+    // generic offset
+    Integer operator += (int delta) { return atomicOffset(mValue, delta); }
+
+#else // no atomic integers, use locks
+
+    Integer mValue;
+    mutable Mutex mLock;
+public:
+    StaticAtomicCounter(Integer init = 0) : mValue(init), mLock(false) { }
+    operator Integer() const	{ StLock<Mutex> _(mLock); return mValue; }
+    Integer operator ++ ()		{ StLock<Mutex> _(mLock); return ++mValue; }
+    Integer operator -- ()		{ StLock<Mutex> _(mLock); return --mValue; }
+    Integer operator ++ (int)	{ StLock<Mutex> _(mLock); return mValue++; }
+    Integer operator -- (int)	{ StLock<Mutex> _(mLock); return mValue--; }
+    Integer operator += (int delta) { StLock<Mutex> _(mLock); return mValue += delta; }
+#endif
+};
+
+
+template <class Integer = int>
+class AtomicCounter : public StaticAtomicCounter<Integer> {
+public:
+    AtomicCounter(Integer init = 0)	{ mValue = 0; }
+};
+
+
+//
+// A class implementing a separate thread of execution.
+// Do not expect many high-level semantics to be portable. If you can,
+// restrict yourself to expect parallel execution and little else.
+//
+#if _USE_THREADS == _USE_PTHREADS
+
+class Thread {
+    NOCOPY(Thread)
+public:
+    Thread() { }				// constructor
+    virtual ~Thread();	 		// virtual destructor
+    void run();					// begin running the thread
+    
+public:
+	static void yield();		// unstructured short-term processor yield
+    
+public:
+    class Identity {
+        friend class Thread;
+    public:
+        Identity() { }
+        
+        static Identity current()	{ return pthread_self(); }
+
+        bool operator == (const Identity &other) const
+        { return pthread_equal(mIdent, other.mIdent); }
+        
+        bool operator != (const Identity &other) const
+        { return !(*this == other); }
+        
+#if !defined(NDEBUG)
+        static const int idLength = 10;
+        static void getIdString(char id[idLength]);
+#endif //NDEBUG
+    
+    private:
+        pthread_t mIdent;
+        
+        Identity(pthread_t id) : mIdent(id) { }
+    };
+
+protected:
+    virtual void action() = 0; 	// the action to be performed
+
+private:
+    Identity self;				// my own identity (instance constant)
+
+    static void *runner(void *); // argument to pthread_create
+};
+
+#elif _USE_THREADS == _USE_NO_THREADS
+
+class Thread {
+    NOCOPY(Thread)
+public:
+	Thread() { }				// constructor
+    virtual ~Thread() { }		// virtual destructor
+    void run() { action(); }	// just synchronously run the action
+    
+public:
+    class Identity {
+    public:
+        static Identity current() { return Identity(); }
+	
+        bool operator == (const Identity &) const		{ return true; }	// all the same
+        bool operator != (const Identity &) const		{ return false; }
+
+#if !defined(NDEBUG)
+        static const idLength = 9;
+        static void getIdString(char id[idLength]) { memcpy(id, "nothread", idLength); }
+#endif
+        
+    private:
+        Identity() { }
+    };
+
+protected:
+    virtual void action() = 0;	// implement action of thread
+};
+
+#else
+# error Unsupported threading model
+#endif
+
+
+//
+// A "just run this function in a thread" variant of Thread
+//
+class ThreadRunner : public Thread {
+    typedef void Action();
+public:
+    ThreadRunner(Action *todo);
+
+private:
+    void action();
+    Action *mAction;
+};
+
+
+//
+// A NestingMutex allows recursive re-entry by the same thread.
+// Some pthread implementations support this through a mutex attribute.
+// OSX's doesn't, naturally. This implementation works on all pthread platforms.
+//
+class NestingMutex {
+public:
+    NestingMutex();
+    
+    void lock();
+    bool tryLock();
+    void unlock();
+
+private:
+    Mutex mLock;
+    Mutex mWait;
+    Thread::Identity mIdent;
+    uint32 mCount;
+};
+
+} // end namespace Security
+
+#endif //_H_THREADING
diff --git a/cdsa/cdsa_utilities/threading_internal.h b/cdsa/cdsa_utilities/threading_internal.h
new file mode 100644
index 00000000..ea39eeea
--- /dev/null
+++ b/cdsa/cdsa_utilities/threading_internal.h
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+
+//
+// threading_internal - internal support classes and functions for threading implementation
+//
+#ifndef _H_THREADING_INTERNAL
+#define _H_THREADING_INTERNAL
+
+#include <Security/utilities.h>
+
+
+namespace Security {
+
+
+//
+// Architecture-specific atomic operation primitives.
+// AtomicWord is an integer type that works with these;
+// we'll assume that a pointer fits into it (using reinterpret_cast).
+//
+#if TARGET_CPU_PPC
+
+#define _HAVE_ATOMIC_OPERATIONS
+
+typedef unsigned int AtomicWord;
+
+inline AtomicWord atomicLoad(AtomicWord &atom)
+{
+    AtomicWord result;
+    asm volatile (
+        "0:	lwarx %0,0,%1 \n"
+        "	stwcx. %0,0,%1 \n"
+        "	bne- 0b"
+        : "=&r"(result)
+        : "b"(&atom)
+        : "cc"
+    );
+    return result;
+}
+
+inline AtomicWord atomicStore(AtomicWord &atom, AtomicWord newValue, AtomicWord oldValue)
+{
+    register bool result;
+    asm volatile (
+        "0:	lwarx %0,0,%1 \n"		// load and reserve -> %0
+        "	cmpw %0,%3 \n"		// compare to old
+        "	bne 1f \n"				// fail if not equal
+        "	stwcx. %2,0,%1 \n"	// store and check
+        "	bne 0b \n"				// retry if contended
+        "1:	"
+        : "=&r"(result)
+        : "b"(&atom), "r"(newValue), "r"(oldValue)
+        : "cc"
+    );
+    return result;
+}
+
+inline AtomicWord atomicOffset(AtomicWord &atom, int offset)
+{
+    AtomicWord result;
+    asm volatile (
+        "0:	lwarx %0,0,%1 \n"
+        "	add %0,%0,%2 \n"
+        "	stwcx. %0,0,%1 \n"
+        "	bne- 0b"
+        : "=&r"(result)
+        : "b"(&atom), "r"(offset)
+        : "cc"
+    );
+    return result;
+}
+
+inline AtomicWord atomicIncrement(AtomicWord &atom)
+{ return atomicOffset(atom, +1); }
+
+inline AtomicWord atomicDecrement(AtomicWord &atom)
+{ return atomicOffset(atom, -1); }
+
+#endif //TARGET_CPU_PPC
+
+} // end namespace Security
+
+#endif //_H_THREADING_INTERNAL
diff --git a/cdsa/cdsa_utilities/timeflow.cpp b/cdsa/cdsa_utilities/timeflow.cpp
new file mode 100644
index 00000000..9814ce48
--- /dev/null
+++ b/cdsa/cdsa_utilities/timeflow.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+
+//
+// timeflow - abstract view of the flow of time
+//
+#include "timeflow.h"
+#include <sys/time.h>
+#include <math.h>
+
+
+namespace Security {
+namespace Time {
+
+
+//
+// Get "now"
+//
+Absolute now()
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec + double(tv.tv_usec) / 1E6;
+}
+
+
+//
+// OOL Conversions
+//
+Absolute::Absolute(const struct timeval &tv)
+{ mValue = tv.tv_sec + double(tv.tv_usec) / 1E6; }
+
+Absolute::operator struct timeval () const
+{
+    struct timeval tv;
+    if (mValue > LONG_MAX) {
+        tv.tv_sec = LONG_MAX;
+        tv.tv_usec = 0;
+    } else {
+        tv.tv_sec = int32_t(mValue);
+        double intPart;
+        tv.tv_usec = int32_t(modf(mValue, &intPart));
+    }
+    return tv;
+}
+
+struct timeval Interval::timevalInterval() const
+{
+    struct timeval tv;
+    if (mValue > LONG_MAX) {
+        tv.tv_sec = LONG_MAX;
+        tv.tv_usec = 0;
+    } else if (mValue < 0) {
+        tv.tv_sec = tv.tv_usec = 0;
+    } else {
+        tv.tv_sec = int32_t(mValue);
+        double intPart;
+        tv.tv_usec = int32_t(modf(mValue, &intPart));
+    }
+    return tv;
+}
+
+
+//
+// Estimate resolution at given time.
+//
+// BSD select(2) has theoretical microsecond resolution, but the underlying 
+// Mach system deals with milliseconds, so we report that conservatively.
+// Sometime in the future when the sun is near collapse, residual resolution
+// of a double will drop under 1E-3, but we won't worry about that just yet.
+//
+Interval resolution(Absolute)
+{
+    return 0.001;
+}
+
+
+}	// end namespace Time
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/timeflow.h b/cdsa/cdsa_utilities/timeflow.h
new file mode 100644
index 00000000..8dfb6202
--- /dev/null
+++ b/cdsa/cdsa_utilities/timeflow.h
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+
+
+//
+// timeflow - abstract view of the flow of time
+//
+// We happily publish both absolute and relative times as floating-point values.
+// Absolute times are off the UNIX Epoch (1/1/1970, midnight). This leaves us about
+// microsecond resolution in Modern Times.
+//
+#ifndef _H_TIMEFLOW
+#define _H_TIMEFLOW
+
+#include <sys/time.h>
+#include <math.h>	// for MAXFLOAT
+
+
+namespace Security {
+namespace Time {
+
+
+//
+// A Time::Interval is a time difference (distance).
+//
+class Interval {
+    friend class Absolute;
+public:
+    Interval() { }
+    Interval(int seconds)		{ mValue = seconds; }
+    Interval(double seconds)	{ mValue = seconds; }
+    explicit Interval(time_t seconds) { mValue = seconds; }
+    
+    Interval &operator += (Interval rel)	{ mValue += rel.mValue; return *this; }
+    Interval &operator -= (Interval rel)	{ mValue -= rel.mValue; return *this; }
+    Interval &operator *= (double f)		{ mValue *= f; return *this; }
+    Interval &operator /= (double f)		{ mValue /= f; return *this; }
+    
+    bool operator <  (Interval other) const	{ return mValue < other.mValue; }
+    bool operator <= (Interval other) const	{ return mValue <= other.mValue; }
+    bool operator >  (Interval other) const	{ return mValue > other.mValue; }
+    bool operator >= (Interval other) const	{ return mValue >= other.mValue; }
+    bool operator == (Interval other) const	{ return mValue == other.mValue; }
+    bool operator != (Interval other) const	{ return mValue != other.mValue; }
+    
+    // express as (fractions of) seconds, milliseconds, or microseconds
+    double seconds() const					{ return mValue; }
+    double mSeconds() const					{ return mValue * 1E3; }
+    double uSeconds() const					{ return mValue * 1E6; }
+    
+    // struct timeval is sometimes used for time intervals, but not often - so be explicit
+    struct timeval timevalInterval() const;
+
+private:
+    double mValue;
+};
+
+
+//
+// A Time::Absolute is a moment in time.
+//
+class Absolute {
+    friend class Interval;
+    friend Interval operator - (Absolute, Absolute);
+    friend Absolute now();
+    friend Absolute bigBang();
+    friend Absolute heatDeath();
+public:
+    Absolute() { }						// uninitialized
+    Absolute(time_t t) { mValue = t; }	// from time_t
+    Absolute(const struct timeval &tv);	// from timeval
+    
+    // *crement operators
+    Absolute &operator += (Interval rel)	{ mValue += rel.mValue; return *this; }
+    Absolute &operator -= (Interval rel)	{ mValue -= rel.mValue; return *this; }
+
+    // comparisons
+    bool operator <  (Absolute other) const	{ return mValue < other.mValue; }
+    bool operator <= (Absolute other) const	{ return mValue <= other.mValue; }
+    bool operator >  (Absolute other) const	{ return mValue > other.mValue; }
+    bool operator >= (Absolute other) const	{ return mValue >= other.mValue; }
+    bool operator == (Absolute other) const	{ return mValue == other.mValue; }
+    bool operator != (Absolute other) const	{ return mValue != other.mValue; }
+    
+    // express as conventional (absolute!) time measures
+    operator struct timeval() const;
+    operator time_t () const				{ return time_t(mValue); }
+
+    // internal form for debugging ONLY
+    double internalForm() const				{ return mValue; }
+    
+private:
+    double mValue;
+    
+    Absolute(double value) : mValue(value) { }
+};
+
+
+//
+// Time::now produces the current time
+//
+Absolute now();						// get "now"
+
+
+//
+// Time::resolution(when) gives a conservative estimate of the available resolution
+// at a given time.
+//
+Interval resolution(Absolute at);	// estimate available resolution at given time
+
+
+//
+// Some useful "constants"
+//
+inline Absolute bigBang()				{ return -MAXFLOAT; }
+inline Absolute heatDeath()				{ return +MAXFLOAT; }
+
+
+
+//
+// More inline arithmetic
+//
+inline Interval operator + (Interval r, Interval r2)	{ r += r2; return r; }
+inline Interval operator - (Interval r, Interval r2)	{ r -= r2; return r; }
+inline Interval operator * (Interval r, double f)		{ r *= f; return r; }
+inline Interval operator / (Interval r, double f)		{ r /= f; return r; }
+
+inline Absolute operator + (Absolute a, Interval r)		{ return a += r; }
+inline Absolute operator + (Interval r, Absolute a)		{ return a += r; }
+inline Absolute operator - (Absolute a, Interval r)		{ return a -= r; }
+
+inline Interval operator - (Absolute t1, Absolute t0)
+{ return t1.mValue - t0.mValue; }
+
+
+}	// end namespace Time
+}	// end namespace Security
+
+#endif //_H_TIMEFLOW
diff --git a/cdsa/cdsa_utilities/tqueue.cpp b/cdsa/cdsa_utilities/tqueue.cpp
new file mode 100644
index 00000000..c17a9d11
--- /dev/null
+++ b/cdsa/cdsa_utilities/tqueue.cpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+
+//
+// tqueue -- timer queues
+//
+#ifdef __MWERKS__
+#define _CPP_CDSA_UTILITIES_TQUEUE
+#endif
+#include <Security/tqueue.h>
diff --git a/cdsa/cdsa_utilities/tqueue.h b/cdsa/cdsa_utilities/tqueue.h
new file mode 100644
index 00000000..cc407339
--- /dev/null
+++ b/cdsa/cdsa_utilities/tqueue.h
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+
+//
+// tqueue.h -- timer queues
+//
+#ifndef _H_TQUEUE
+#define _H_TQUEUE
+
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <Security/debugging.h>
+
+#ifdef _CPP_CDSA_UTILITIES_TQUEUE
+#pragma export on
+#endif
+
+
+namespace Security
+{
+
+//
+// A TimerQueue is a container of elements that have relative "timer" positions.
+// TimerQueues are concerned with shuffling these elements around as their "times"
+// change, and with processing elements that fall off the front of the queue as
+// "time" passes.
+// We put "time" into quotes because nothing here really cares what kind of time
+// you are playing with. It could be seconds, points scored, etc. The only requirement
+// is that "time" doesn't ever flow backwards...
+//
+template <class Time>
+class ScheduleQueue {
+public:
+	ScheduleQueue()					{ first.fwd = first.back = &first; }
+	virtual ~ScheduleQueue()		{ }
+	
+public:
+	class Event {
+		friend class ScheduleQueue;
+	public:
+		Event() : mScheduled(false) { }
+		~Event() { if (scheduled()) unschedule(); }
+		
+		void unschedule();
+		
+		Time when() const			{ return fireTime; }
+		bool scheduled() const		{ return mScheduled; }
+		
+	private:
+		Time fireTime;				// when will it happen?
+		bool mScheduled;			// are we scheduled?
+		Event *back, *fwd;			// doubly-linked interior list
+		
+		void putBefore(Event *ev)
+		{ back = ev->back; fwd = ev; ev->back = back->fwd = this; mScheduled = true; }
+	};
+	
+public:
+	void schedule(Event *event, Time when);
+	void unschedule(Event *event)
+	{ event->unschedule(); }
+	
+	bool empty() const	{ return first.fwd == &first; }
+	Time next() const	{ assert(!empty()); return first.fwd->fireTime; }
+	
+	Event *pop(Time now);
+
+private:
+	Event first;					// root of active timers list
+};
+
+template <class Time>
+void ScheduleQueue<Time>::Event::unschedule()
+{
+	assert(mScheduled);
+	back->fwd = fwd; fwd->back = back; 
+	mScheduled = false;
+	debug("schedq", "event %p unscheduled", this);
+}
+
+template <class Time>
+inline void ScheduleQueue<Time>::schedule(Event *event, Time when)
+{
+	Event *ev = first.fwd;
+	if (event->scheduled()) {
+		if (when == event->fireTime)	// no change
+			return;
+		else if (when > event->fireTime)	// forward move
+			ev = event->back;
+		event->unschedule();
+	}
+	event->fireTime = when;
+	// newly schedule the event
+	for (; ev != &first; ev = ev->fwd)
+		if (ev->fireTime > when) {
+			event->putBefore(ev);
+			return;
+		}
+	// hit the end-of-queue; put at end
+	event->putBefore(&first);
+	debug("schedq", "event %p set for %.3f", event, double(when));
+}
+
+template <class Time>
+inline ScheduleQueue<Time>::Event *ScheduleQueue<Time>::pop(Time now)
+{
+	if (!empty()) {
+		Event *top = first.fwd;
+		if (top->fireTime <= now) {
+			top->unschedule();
+			debug("schedq", "event %p delivered at %.3f", top, double(now));
+			return top;
+		}
+	}
+	return NULL;
+}
+
+} // end namespace Security
+
+#ifdef _CPP_CDSA_UTILITIES_TQUEUE
+#pragma export off
+#endif
+
+#endif // _H_TQUEUE
diff --git a/cdsa/cdsa_utilities/typedvalue.cpp b/cdsa/cdsa_utilities/typedvalue.cpp
new file mode 100644
index 00000000..c3a70eb1
--- /dev/null
+++ b/cdsa/cdsa_utilities/typedvalue.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+
+//
+// typedvalue - type-safe reference transmission of arbitrary types
+//
+#include "typedvalue.h"
+
+
+namespace Security {
+
+
+GenericValue::~GenericValue()
+{ }
+
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/typedvalue.h b/cdsa/cdsa_utilities/typedvalue.h
new file mode 100644
index 00000000..b61ba4da
--- /dev/null
+++ b/cdsa/cdsa_utilities/typedvalue.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+
+//
+// typedvalue - type-safe reference transmission of arbitrary types.
+//
+// This slight-of-hand pair of classes allows arbitrary types to be passed through an API
+// without losing C++ type safety. Specifically, the type is encapsulated in C++ polymorphism,
+// and can be resolved through the C++ typeinfo/dynamic_cast system in a fairly
+// convenient way. This is intended to replace passing (void *) arguments around.
+// It is obviously not meant to replace proper class hierarchies in APIs.
+//
+#ifndef _H_TYPEDVALUE
+#define _H_TYPEDVALUE
+
+#include <Security/utilities.h>
+#include <Security/debugging.h>
+
+
+namespace Security {
+
+
+//
+// A GenericValue can represent any (one) type. Note the template assignment
+// that works *only* for the type it actually represents. Note particularly that
+// no automatic conversions are made (other than to subclass).
+//
+class GenericValue {
+public:
+    virtual ~GenericValue();
+    
+    template <class V>
+    void operator = (const V &value);
+};
+
+
+//
+// A TypedValue is a particular typed instance of a GenericValue
+//
+template <class Value>
+class TypedValue : public GenericValue {
+public:
+    TypedValue() : mValue() { }
+    TypedValue(const Value &v) : mValue(v) { }
+    Value &value()					{ return mValue; }
+    operator Value &()				{ return mValue; }
+    void operator = (const Value &value) { mValue = value; }
+    
+private:
+    Value mValue;
+};
+
+
+//
+// The polymorphic assignment access method
+//
+template <class Value>
+void GenericValue::operator = (const Value &value)
+{ safer_cast<TypedValue<Value> &>(*this) = value; }
+
+
+}	// end namespace Security
+
+
+#endif //_H_TYPEDVALUE
diff --git a/cdsa/cdsa_utilities/uniformrandom.cpp b/cdsa/cdsa_utilities/uniformrandom.cpp
new file mode 100644
index 00000000..2098d1c2
--- /dev/null
+++ b/cdsa/cdsa_utilities/uniformrandom.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+
+//
+// uniformrandom - uniformly distributed random number operators
+//
+
+#include <Security/uniformrandom.h>
+
+
+namespace Security {
+
+
+
+
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/uniformrandom.h b/cdsa/cdsa_utilities/uniformrandom.h
new file mode 100644
index 00000000..ec3cec56
--- /dev/null
+++ b/cdsa/cdsa_utilities/uniformrandom.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+
+//
+// uniformrandom - uniformly distributed random number operators
+//
+#ifndef _H_UNIFORMRANDOM
+#define _H_UNIFORMRANDOM
+
+#include <Security/utilities.h>
+
+
+namespace Security {
+
+
+//
+// Uniform binary blob generator.
+// This operator deals exclusively in byte arrays.
+//
+template <class Generator>
+class UniformRandomBlobs : public Generator {
+public:
+#if BUG_GCC
+    void random(void *data, size_t length) { Generator::random(data, length); }
+#else
+    using Generator::random;
+#endif
+
+    template <class Object>
+    void random(Object &obj)	{ random(&obj, sizeof(obj)); }
+    
+    void random(CssmData &data)	{ random(data.data(), data.length()); }
+};
+
+
+}; 	// end namespace Security
+
+
+#endif //_H_UNIFORMRANDOM
diff --git a/cdsa/cdsa_utilities/unix++.cpp b/cdsa/cdsa_utilities/unix++.cpp
new file mode 100644
index 00000000..d049fd95
--- /dev/null
+++ b/cdsa/cdsa_utilities/unix++.cpp
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+
+//
+// unix++ - C++ layer for basic UNIX facilities
+//
+#include "unix++.h"
+#include <Security/debugging.h>
+
+
+namespace Security {
+namespace UnixPlusPlus {
+
+
+//
+// Generic UNIX file descriptors
+//
+void FileDesc::open(const char *path, int flags, mode_t mode)
+{
+    checkSetFd(::open(path, flags, mode));
+    mAtEnd = false;
+    debug("unixio", "open(%s,0x%x,0x%x) = %d", path, flags, mode, mFd);
+}
+
+void FileDesc::close()
+{
+    if (mFd >= 0) {
+        checkError(::close(mFd));
+        debug("unixio", "close(%d)", mFd);
+        mFd = invalidFd;
+    }
+}
+
+
+//
+// Filedescoid operations
+//
+size_t FileDesc::read(void *addr, size_t length)
+{
+    switch (ssize_t rc = ::read(mFd, addr, length)) {
+    case 0:		// end-of-source
+        if (length == 0) { // check for errors, but don't set mAtEnd unless we have to
+            debug("unixio", "%d zero read (ignored)", mFd);
+            return 0;
+        }
+        mAtEnd = true;
+        debug("unixio", "%d end of data", mFd);
+        return 0;
+    case -1:	// error
+        if (errno == EAGAIN)
+            return 0;	// no data, unknown end-of-source status
+        UnixError::throwMe(); // throw error
+    default:	// have data
+        return rc;
+    }
+}
+
+size_t FileDesc::write(const void *addr, size_t length)
+{
+    ssize_t rc = ::write(mFd, addr, length);
+    if (rc == -1) {
+        if (errno == EAGAIN)
+            return 0;
+        UnixError::throwMe();
+    }
+    return rc;
+}
+
+
+//
+// Seeking
+//
+off_t FileDesc::seek(off_t position, int whence)
+{
+    off_t rc = ::lseek(mFd, position, whence);
+    if (rc == -1)
+        UnixError::throwMe();
+    return rc;
+}
+
+
+//
+// Mmap support
+//
+void *FileDesc::mmap(int prot, size_t length, int flags, off_t offset, void *addr)
+{
+    void *result = ::mmap(addr, length ? length : fileSize(), prot, flags, mFd, offset);
+    if (result == MAP_FAILED)
+        UnixError::throwMe();
+    return result;
+}
+
+
+int FileDesc::fcntl(int cmd, int arg) const
+{
+    int rc = ::fcntl(mFd, cmd, arg);
+    debug("unixio", "%d fcntl(%d,%d) = %d", mFd, cmd, arg, rc);
+    if (rc == -1)
+        UnixError::throwMe();
+    return rc;
+}
+
+int FileDesc::fcntl(int cmd, void *arg) const
+{
+    // The BSD UNIX headers require an int argument to fcntl.
+    // This will fail miserably if sizeof(void *) > sizeof(int). For such ports,
+    // fix the problem here.
+    assert(sizeof(void *) <= sizeof(int));
+    return fcntl(cmd, reinterpret_cast<int>(arg));
+}
+
+int FileDesc::flags() const
+{
+    int flags = fcntl(F_GETFL);
+    if (flags == -1)
+        UnixError::throwMe();
+    return flags;
+}
+
+void FileDesc::flags(int flags) const
+{
+    if (fcntl(F_SETFL, flags) == -1)
+        UnixError::throwMe();
+}
+
+void FileDesc::setFlag(int flag, bool on) const
+{
+    if (flag) {		// if there's anything at all to do...
+        int oldFlags = flags();
+        flags(on ? (oldFlags | flag) : (oldFlags & ~flag));
+    }
+}
+
+int FileDesc::ioctl(int cmd, void *arg) const
+{
+    int rc = ::ioctl(mFd, cmd, arg);
+    if (rc == -1)
+        UnixError::throwMe();
+    return rc;
+}
+
+
+void FileDesc::fstat(UnixStat &st) const
+{
+    if (::fstat(mFd, &st))
+        UnixError::throwMe();
+}
+
+size_t FileDesc::fileSize() const
+{
+    struct stat st;
+    fstat(st);
+    return st.st_size;
+}
+
+
+FILE *FileDesc::fdopen(const char *form)
+{
+    return ::fdopen(mFd, form);
+}
+
+
+}	// end namespace IPPlusPlus
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/unix++.h b/cdsa/cdsa_utilities/unix++.h
new file mode 100644
index 00000000..bd032bed
--- /dev/null
+++ b/cdsa/cdsa_utilities/unix++.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+
+//
+// unix++ - C++ layer for basic UNIX facilities
+//
+#ifndef _H_UNIXPLUSPLUS
+#define _H_UNIXPLUSPLUS
+
+#include <Security/utilities.h>
+#include "timeflow.h"
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <cstdio>
+#include <cstdarg>
+#include <map>
+
+
+namespace Security {
+namespace UnixPlusPlus {
+
+
+//
+// Generic file descriptors
+//
+class FileDesc {
+protected:
+    static const int invalidFd = -1;
+
+    void setFd(int fd)					{ mFd = fd; mAtEnd = false; }
+    static void checkError(int result)	{ if (result == -1) UnixError::throwMe(); }
+    void checkSetFd(int fd)				{ checkError(fd); mFd = fd; mAtEnd = false; }
+    
+public:
+    FileDesc() : mFd(invalidFd), mAtEnd(false) { }
+    FileDesc(int fd) : mFd(fd), mAtEnd(false) { }
+    
+    // implicit file system open() construction
+    FileDesc(const char *path, int flag = O_RDONLY, mode_t mode = 0666) : mFd(invalidFd)
+    { open(path, flag, mode); }
+    
+    // assignment
+    FileDesc &operator = (int fd)		{ mFd = fd; mAtEnd = false; return *this; }
+    FileDesc &operator = (const FileDesc &fd) { mFd = fd.mFd; mAtEnd = fd.mAtEnd; return *this; }
+    
+    bool isOpen() const			{ return mFd != invalidFd; }
+    operator bool() const 		{ return isOpen(); }
+    int fd() const				{ return mFd; }
+    operator int() const		{ return fd(); }
+    
+    void clear()				{ mFd = invalidFd; }
+    void close();				// close and clear
+    
+    void open(const char *path, int flag = O_RDONLY, mode_t mode = 0666);
+    
+    // basic I/O: this defines the "Filedescoid" pseudo-type
+    size_t read(void *addr, size_t length);
+    size_t write(const void *addr, size_t length);
+    bool atEnd() const			{ return mAtEnd; }	// valid after zero-length read only
+
+    // seeking
+    off_t seek(off_t position, int whence = SEEK_SET);
+    
+    // mapping support
+    void *mmap(int prot = PROT_READ, size_t length = 0, int flags = MAP_FILE, 
+        off_t offset = 0, void *addr = NULL);
+    
+    // fcntl support
+    int fcntl(int cmd, int arg = 0) const;
+    int fcntl(int cmd, void *arg) const;
+    int flags() const;
+    void flags(int flags) const;
+    void setFlag(int flag, bool on = true) const;
+    void clearFlag(int flag) const	{ setFlag(flag, false); }
+    
+    // ioctl support
+    int ioctl(int cmd, void *arg) const;
+    template <class Arg> Arg iocget(int cmd) const 
+        { Arg arg; ioctl(cmd, &arg); return arg; }
+    template <class Arg> void iocget(int cmd, Arg &arg) const
+        { ioctl(cmd, &arg); }
+    template <class Arg> void iocset(int cmd, const Arg &arg)
+        { ioctl(cmd, const_cast<Arg *>(&arg)); }
+        
+    // stat-related utilities. @@@ should cache??
+    typedef struct stat UnixStat;
+    void fstat(UnixStat &st) const;
+    size_t fileSize() const;
+    
+    // stdio interactions
+    FILE *fdopen(const char *mode = NULL);	// fdopen(3)
+
+private:
+    int mFd;				// UNIX file descriptor
+    
+protected:
+    bool mAtEnd;			// end-of-data indicator (after zero read)
+};
+
+
+}	// end namespace UnixPlusPlus
+}	// end namespace Security
+
+
+#endif //_H_UNIXPLUSPLUS
diff --git a/cdsa/cdsa_utilities/url.cpp b/cdsa/cdsa_utilities/url.cpp
new file mode 100644
index 00000000..ae723fee
--- /dev/null
+++ b/cdsa/cdsa_utilities/url.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+
+//
+// url - URL object with decomposition
+//
+#include "url.h"
+#include <CoreFoundation/CFURL.h>
+#include <CoreFoundation/CFString.h>
+#include <errno.h>
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// Turn a CFStringRef into an STL string and release the incoming CFStringRef
+//
+static string mkstr(CFStringRef str)
+{
+    if (!str)
+        return "";
+    char buffer[2048];
+    if (CFStringGetCString(str, buffer, sizeof(buffer), kCFStringEncodingUTF8))
+        return buffer;
+    else
+        UnixError::throwMe(EINVAL);
+}
+
+
+//
+// Construction
+//
+URL::URL()
+{
+    ref = NULL;
+}
+
+URL::URL(const char *s)
+{
+    ref = CFURLCreateWithBytes(NULL, (const UInt8 *)s, strlen(s), kCFStringEncodingUTF8, NULL);
+    if (!ref)
+        UnixError::throwMe(EINVAL);
+}
+
+URL::URL(const char *s, const URL &base)
+{
+    ref = CFURLCreateWithBytes(NULL, (const UInt8 *)s, strlen(s), kCFStringEncodingUTF8, base.ref);
+    if (!ref)
+        UnixError::throwMe(EINVAL);
+}
+
+URL::~URL()
+{
+    if (ref)
+        CFRelease(ref);
+}
+
+
+//
+// Extraction: These methods produce UTF8 strings
+//
+URL::operator string() const
+{
+    return mkstr(CFURLGetString(ref));
+}
+
+string URL::scheme() const
+{
+    return mkstr(CFURLCopyScheme(ref));
+}
+
+string URL::host() const
+{
+    return mkstr(CFURLCopyHostName(ref));
+}
+
+IPPort URL::port(IPPort defaultPort) const
+{
+    SInt32 port = CFURLGetPortNumber(ref);
+    return (port == -1) ? defaultPort : port;
+}
+
+string URL::username() const
+{
+    return mkstr(CFURLCopyUserName(ref));
+}
+
+string URL::password() const
+{
+    return mkstr(CFURLCopyPassword(ref));
+}
+
+string URL::path() const
+{
+    Boolean isAbsolute;
+    return "/" + mkstr(CFURLCopyStrictPath(ref, &isAbsolute));
+}
+
+string URL::resourceSpec() const
+{
+    Boolean isAbsolute;
+    return mkstr(CFURLCopyResourceSpecifier(ref));
+}
+
+string URL::fullPath() const
+{
+    return path() + resourceSpec();
+}
+
+string URL::basename() const
+{
+    return mkstr(CFURLCopyLastPathComponent(ref));
+}
+
+string URL::extension() const
+{
+    return mkstr(CFURLCopyPathExtension(ref));
+}
+
+void URL::recreateURL(const char* url)
+{
+    if(ref)
+        CFRelease(ref);
+    ref = CFURLCreateWithBytes(NULL, (const UInt8 *)url, strlen(url), kCFStringEncodingUTF8, NULL);
+}
+
+}	// end namespace Network
+}	// end namespace Security
diff --git a/cdsa/cdsa_utilities/url.h b/cdsa/cdsa_utilities/url.h
new file mode 100644
index 00000000..2cd55b06
--- /dev/null
+++ b/cdsa/cdsa_utilities/url.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+//
+// url - URL object with decomposition
+//
+// This is a wrapper around CoreFoundation CFURL objects,
+// without any attempt at re-interpretation (other than cleaning
+// up the obvious CFishness).
+//
+#ifndef _H_URL
+#define _H_URL
+
+#include <string>
+#include "ip++.h"
+
+
+struct __CFURL;
+using IPPlusPlus::IPPort;
+
+
+namespace Security {
+namespace Network {
+
+
+//
+// A thin encapsulation of a URL
+//
+class URL {
+public:
+    URL();
+    URL(const char *url);
+    URL(const char *url, const URL &base);
+    ~URL();
+    
+    operator string() const;
+    
+    string scheme() const;
+    string host() const;
+    IPPort port(IPPort defaultPort = 0) const;
+    string path() const;
+    string resourceSpec() const;
+    string fullPath() const;
+    
+    string username() const;
+    string password() const;
+    string basename() const;
+    string extension() const;
+    
+    void recreateURL(const char* url);
+    
+private:
+    const __CFURL *ref;
+};
+
+
+}	// end namespace Network
+}	// end namespace Security
+
+
+#endif _H_URL
diff --git a/cdsa/cdsa_utilities/utilities.cpp b/cdsa/cdsa_utilities/utilities.cpp
new file mode 100644
index 00000000..716591fc
--- /dev/null
+++ b/cdsa/cdsa_utilities/utilities.cpp
@@ -0,0 +1,233 @@
+/*
+ * 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.
+ */
+
+
+//
+// Utilities
+//
+#ifdef __MWERKS__
+#define _CPP_UTILITIES
+#endif
+
+#include <Security/utilities.h>
+#include <Security/debugging.h>
+#include <stdio.h>
+
+
+//
+// The base of the exception hierarchy
+//
+CssmCommonError::CssmCommonError()
+{
+    debug("exception", "constructing exception at %p", this);
+}
+
+CssmCommonError::CssmCommonError(const CssmCommonError &source)
+{
+    debug("exception", "constructing exception at %p from %p", this, &source);
+}
+
+CssmCommonError::~CssmCommonError()
+{
+    debug("exception", "destroying exception at %p", this);
+}
+
+OSStatus CssmCommonError::osStatus() const
+{ return cssmError(); }
+
+CSSM_RETURN CssmCommonError::cssmError(CSSM_RETURN base) const
+{ return CssmError::merge(cssmError(), base); }
+
+
+//
+// CssmError exceptions
+//
+CssmError::CssmError(CSSM_RETURN err) : error(err) { }
+
+const char *CssmError::what() const { return "CSSM exception"; }
+
+CSSM_RETURN CssmError::cssmError() const { return error; }
+
+OSStatus CssmError::osStatus() const { return error; }
+
+void CssmError::throwMe(CSSM_RETURN err) { throw CssmError(err); }
+
+
+//
+// UnixError exceptions
+//
+UnixError::UnixError() : error(errno) { }
+
+UnixError::UnixError(int err) : error(err) { }
+
+const char *UnixError::what() const
+{ return "UNIX error exception"; }
+
+CSSM_RETURN UnixError::cssmError() const
+{
+    // @@@ this is a sample - go through and map errnos better
+    switch (error) {
+#if defined(ENOMEM)
+        case ENOMEM:
+            return CSSM_ERRCODE_MEMORY_ERROR;
+#endif
+#if defined(ENOSYS)
+        case ENOSYS:
+            return CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED;
+#endif
+#if defined(ENOSPC)
+		case ENOSPC:
+			return CSSMERR_APPLEDL_DISK_FULL;
+#endif
+#if defined(EDQUOT)
+		case EDQUOT:
+			return CSSMERR_APPLEDL_QUOTA_EXCEEDED;
+#endif
+#if defined(EFBIG)
+		case EFBIG:
+			return CSSMERR_APPLEDL_FILE_TOO_BIG;
+#endif
+        default:
+            return CSSM_ERRCODE_INTERNAL_ERROR;
+    }
+}
+
+OSStatus UnixError::osStatus() const { return cssmError(); }
+
+void UnixError::throwMe(int err) { throw UnixError(err); }
+
+// @@@ This is a hack for the Network protocol state machine
+UnixError UnixError::make(int err) { return UnixError(err); }
+
+
+//
+// MacOSError exceptions
+//
+MacOSError::MacOSError(int err) : error(err) { }
+
+const char *MacOSError::what() const
+{ return "MacOS error"; }
+
+CSSM_RETURN MacOSError::cssmError() const
+{ return error; }	// @@@ eventually...
+
+OSStatus MacOSError::osStatus() const
+{ return error; }
+
+void MacOSError::throwMe(int error)
+{ throw MacOSError(error); }
+
+
+//
+// Manage CSSM errors
+//
+CSSM_RETURN CssmError::merge(CSSM_RETURN error, CSSM_RETURN base)
+{
+    if (0 < error && error < CSSM_ERRORCODE_COMMON_EXTENT) {
+        return base + error;
+    } else {
+        return error;
+    }
+}
+
+
+//
+// GUID <-> string conversions.
+// Note that we DO check for {} on input and insist on rigid formatting.
+// We don't require a terminating null byte on input, but generate it on output.
+//
+char *Guid::toString(char buffer[stringRepLength+1]) const
+{
+    sprintf(buffer, "{%8.8lx-%4.4x-%4.4x-",
+            (unsigned long)Data1, unsigned(Data2), unsigned(Data3));
+    for (int n = 0; n < 2; n++)
+        sprintf(buffer + 20 + 2*n, "%2.2x", Data4[n]);
+	buffer[24] = '-';
+    for (int n = 2; n < 8; n++)
+        sprintf(buffer + 21 + 2*n, "%2.2x", Data4[n]);
+    buffer[37] = '}';
+    buffer[38] = '\0';
+    return buffer;
+}
+
+Guid::Guid(const char *string)
+{
+	// Arguably, we should be more flexible on input. But exactly what
+	// padding rules should we follow, and how should we try to interprete
+	// "doubtful" variations? Given that GUIDs are essentially magic
+	// cookies, everybody's better off if we just cut-and-paste them
+	// around the universe...
+    unsigned long d1;
+    unsigned int d2, d3;
+    if (sscanf(string, "{%lx-%x-%x-", &d1, &d2, &d3) != 3)
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID);
+	Data1 = d1;	Data2 = d2;	Data3 = d3;
+	// once, we did not expect the - after byte 2 of Data4
+	bool newForm = string[24] == '-';
+    for (int n = 0; n < 8; n++) {
+        unsigned int dn;
+        if (sscanf(string + 20 + 2*n + (newForm && n >= 2), "%2x", &dn) != 1)
+            CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID);
+        Data4[n] = dn;
+    }
+	if (string[37 - !newForm] != '}')
+		CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID);
+}
+
+
+//
+// Methods for the CssmKey class
+//
+CssmKey::CssmKey(CSSM_KEY &key)
+{
+	KeyHeader = key.KeyHeader;
+    KeyData = key.KeyData;
+	key.KeyData.Length = 0;
+	key.KeyData.Data = NULL;
+}
+
+CssmKey::CssmKey(CSSM_DATA &keyData)
+{
+    memset(this, 0, sizeof(*this));
+    KeyData = keyData;
+	keyData.Length = 0;
+	keyData.Data = NULL;
+    KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
+    KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
+    KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_NONE;
+}
+
+CssmKey::CssmKey(uint32 length, uint8 *data)
+{
+    memset(this, 0, sizeof(*this));
+	KeyData.Length = length;
+	KeyData.Data = data;
+    KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
+    KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
+    KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_NONE;
+}
+
+CryptoDataClass::~CryptoDataClass()
+{
+}
+
+//
+// Debug support
+//
+#if !defined(NDEBUG)
+
+#endif //NDEBUG
diff --git a/cdsa/cdsa_utilities/utilities.h b/cdsa/cdsa_utilities/utilities.h
new file mode 100644
index 00000000..75b515d8
--- /dev/null
+++ b/cdsa/cdsa_utilities/utilities.h
@@ -0,0 +1,749 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * cssm utilities
+ */
+#ifndef _H_UTILITIES
+#define _H_UTILITIES
+
+#include <Security/cssm.h>
+#include <Security/utility_config.h>
+#include <exception>
+#include <new>
+#include <string>
+#include <errno.h>
+#include <string.h>
+
+#ifdef _CPP_UTILITIES
+#pragma export on
+#endif
+
+namespace Security
+{
+
+//
+// Elementary debugging support.
+// #include <debugging.h> for more debugging facilities.
+//
+#if defined(NDEBUG)
+
+# define safe_cast	static_cast
+# define safer_cast	static_cast
+
+# define IFDEBUG(it)	/* do nothing */
+# define IFNDEBUG(it)	it
+
+#else
+
+template <class Derived, class Base>
+inline Derived safer_cast(Base &base)
+{
+    return dynamic_cast<Derived>(base);
+}
+
+template <class Derived, class Base>
+inline Derived safe_cast(Base *base)
+{
+    if (base == NULL)
+        return NULL;	// okay to cast NULL to NULL
+    Derived p = dynamic_cast<Derived>(base);
+    assert(p);
+    return p;
+}
+
+# define IFDEBUG(it)	it
+# define IFNDEBUG(it)	/* do nothing */
+
+#endif //NDEBUG
+
+
+//
+// Place this into your class definition if you don't want it to be copyable
+// or asignable. This will not prohibit allocation on the stack or in static
+// memory, but it will make anything derived from it, and anything containing
+// it, fixed-once-created. A proper object, I suppose.
+//
+#define NOCOPY(Type)	private: Type(const Type &); void operator = (const Type &);
+
+
+//
+// Exception hierarchy
+//
+class CssmCommonError : public exception {
+protected:
+    CssmCommonError();
+    CssmCommonError(const CssmCommonError &source);
+public:
+    virtual ~CssmCommonError();
+
+    virtual CSSM_RETURN cssmError() const = 0;
+    virtual CSSM_RETURN cssmError(CSSM_RETURN base) const;
+    virtual OSStatus osStatus() const;
+};
+
+class CssmError : public CssmCommonError {
+protected:
+    CssmError(CSSM_RETURN err);
+public:
+    const CSSM_RETURN error;
+    virtual CSSM_RETURN cssmError() const;
+    virtual OSStatus osStatus() const;
+    virtual const char *what () const;
+
+    static CSSM_RETURN merge(CSSM_RETURN error, CSSM_RETURN base);
+    
+    static void throwMe(CSSM_RETURN error) __attribute__((noreturn));
+};
+
+class UnixError : public CssmCommonError {
+protected:
+    UnixError();
+    UnixError(int err);
+public:
+    const int error;
+    virtual CSSM_RETURN cssmError() const;
+    virtual OSStatus osStatus() const;
+    virtual const char *what () const;
+    
+    static void check(int result)		{ if (result == -1) throwMe(); }
+    static void throwMe(int err = errno) __attribute__((noreturn));
+
+    // @@@ This is a hack for the Network protocol state machine
+    static UnixError make(int err = errno);
+};
+
+class MacOSError : public CssmCommonError {
+protected:
+    MacOSError(int err);
+public:
+    const int error;
+    virtual CSSM_RETURN cssmError() const;
+    virtual OSStatus osStatus() const;
+    virtual const char *what () const;
+    
+    static void check(OSStatus status)	{ if (status != noErr) throwMe(status); }
+    static void throwMe(int err) __attribute__((noreturn));
+};
+
+
+//
+// API boilerplate macros. These provide a frame for C++ code that is impermeable to exceptions.
+// Usage:
+//	BEGIN_API
+//		... your C++ code here ...
+//  END_API(base)	// returns CSSM_RETURN on exception; complete it to 'base' (DL, etc.) class;
+//					// returns CSSM_OK on fall-through
+//	END_API0		// completely ignores exceptions; falls through in all cases
+//	END_API1(bad)	// return (bad) on exception; fall through on success
+//
+#define BEGIN_API	try {
+#define END_API(base) 	} \
+catch (const CssmCommonError &err) { return err.cssmError(CSSM_ ## base ## _BASE_ERROR); } \
+catch (std::bad_alloc) { return CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
+catch (...) { return CssmError::merge(CSSM_ERRCODE_INTERNAL_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
+    return CSSM_OK;
+#define END_API0		} catch (...) { return; }
+#define END_API1(bad)	} catch (...) { return bad; }
+
+
+//
+// Helpers for memory pointer validation
+//
+template <class T>
+inline T &Required(T *ptr, CSSM_RETURN err = CSSM_ERRCODE_INVALID_POINTER)
+{
+    if (ptr == NULL)
+        CssmError::throwMe(err);
+    return *ptr;
+}
+
+
+//
+// Tools to build POD wrapper classes
+//
+template <class Wrapper, class POD>
+class PodWrapper : public POD {
+public:
+    // pure typecasts
+    static Wrapper * &overlayVar(POD * &data)
+    { return reinterpret_cast<Wrapper * &>(data); }
+    static const Wrapper * &overlayVar(const POD * &data)
+    { return reinterpret_cast<const Wrapper * &>(data); }
+	
+    static Wrapper *overlay(POD *data)
+    { return static_cast<Wrapper *>(data); }
+    static const Wrapper *overlay(const POD *data)
+    { return static_cast<const Wrapper *>(data); }
+    static Wrapper &overlay(POD &data)
+    { return static_cast<Wrapper &>(data); }
+    static const Wrapper &overlay(const POD &data)
+    { return static_cast<const Wrapper &>(data); }
+
+    // optional/required forms
+    static Wrapper &required(POD *data)
+    { return overlay(Required(data)); }
+    static const Wrapper &required(const POD *data)
+    { return overlay(Required(data)); }
+    static Wrapper *optional(POD *data)
+    { return overlay(data); }
+    static const Wrapper *optional(const POD *data)
+    { return overlay(data); }
+};
+
+
+//
+// Template builder support
+//
+template <class T>
+struct Nonconst {
+	typedef T Type;
+};
+
+template <class U>
+struct Nonconst<const U> {
+	typedef U Type;
+};
+
+
+//
+// User-friendly GUIDs
+//
+class Guid : public PodWrapper<Guid, CSSM_GUID> {
+public:
+    Guid() { /*IFDEBUG(*/ memset(this, 0, sizeof(*this)) /*)*/ ; }
+    Guid(const CSSM_GUID &rGuid) { memcpy(this, &rGuid, sizeof(*this)); }
+
+    Guid &operator = (const CSSM_GUID &rGuid)
+    { memcpy(this, &rGuid, sizeof(CSSM_GUID)); return *this; }
+   
+    bool operator == (const CSSM_GUID &other) const
+    { return (this == &other) || !memcmp(this, &other, sizeof(CSSM_GUID)); }
+    bool operator != (const CSSM_GUID &other) const
+    { return (this != &other) && memcmp(this, &other, sizeof(CSSM_GUID)); }
+    bool operator < (const CSSM_GUID &other) const
+    { return memcmp(this, &other, sizeof(CSSM_GUID)) < 0; }
+    size_t hash() const {	//@@@ revisit this hash
+        return Data1 + Data2 << 3 + Data3 << 11 + Data4[3] + Data4[6] << 22;
+    }
+
+    static const unsigned stringRepLength = 38;	// "{x8-x4-x4-x4-x12}"
+    char *toString(char buffer[stringRepLength+1]) const;	// will append \0
+    Guid(const char *string);
+};
+
+
+//
+// User-friendly CSSM_SUBSERVICE_UIDs
+//
+class CssmSubserviceUid : public PodWrapper<CssmSubserviceUid, CSSM_SUBSERVICE_UID> {
+public:
+    CssmSubserviceUid() { /*IFDEBUG(*/ memset(this, 0, sizeof(*this)) /*)*/ ; }
+    CssmSubserviceUid(const CSSM_SUBSERVICE_UID &rSSuid) { memcpy(this, &rSSuid, sizeof(*this)); }
+
+    CssmSubserviceUid &operator = (const CSSM_SUBSERVICE_UID &rSSuid)
+    { memcpy(this, &rSSuid, sizeof(CSSM_SUBSERVICE_UID)); return *this; }
+   
+    bool operator == (const CSSM_SUBSERVICE_UID &other) const
+    { return (this == &other) || !memcmp(this, &other, sizeof(CSSM_SUBSERVICE_UID)); }
+    bool operator != (const CSSM_SUBSERVICE_UID &other) const
+    { return (this != &other) && memcmp(this, &other, sizeof(CSSM_SUBSERVICE_UID)); }
+    bool operator < (const CSSM_SUBSERVICE_UID &other) const
+    { return memcmp(this, &other, sizeof(CSSM_SUBSERVICE_UID)) < 0; }
+
+    CssmSubserviceUid(const CSSM_GUID &guid, const CSSM_VERSION *version = NULL,
+		uint32 subserviceId = 0,
+        CSSM_SERVICE_TYPE subserviceType = CSSM_SERVICE_DL)
+    {
+        Guid=guid;SubserviceId=subserviceId;SubserviceType=subserviceType;
+        if (version)
+            Version=*version;
+        else
+        { Version.Major=0; Version.Minor=0; }
+    }
+
+	const ::Guid &guid() const { return ::Guid::overlay(Guid); }
+	uint32 subserviceId() const { return SubserviceId; }
+	CSSM_SERVICE_TYPE subserviceType() const { return SubserviceType; }
+	CSSM_VERSION version() const { return Version; }
+};
+
+
+//
+// User-friendlier CSSM_DATA thingies.
+// CssmData is a PODWrapper and has no memory allocation features.
+//
+class CssmData : public PodWrapper<CssmData, CSSM_DATA> {
+public:
+    CssmData() { Data = 0; Length = 0; }
+
+    size_t length() const { return Length; }
+    void *data() const { return Data; }
+    void *end() const { return Data + Length; }
+	
+	//
+	// Create a CssmData from any pointer-to-byte-sized-object and length.
+	//
+	CssmData(void *data, size_t length)
+	{ Data = reinterpret_cast<UInt8 *>(data); Length = length; }
+	CssmData(char *data, size_t length)
+	{ Data = reinterpret_cast<UInt8 *>(data); Length = length; }
+	CssmData(unsigned char *data, size_t length)
+	{ Data = reinterpret_cast<UInt8 *>(data); Length = length; }
+	CssmData(signed char *data, size_t length)
+	{ Data = reinterpret_cast<UInt8 *>(data); Length = length; }
+	
+	// the void * form accepts too much; explicitly deny all other types
+	private: template <class T> CssmData(T *, size_t); public:
+	
+	//
+	// Do allow generic "wrapping" of any data structure, but make it conspicuous
+	// since it's not necessarily the Right Thing (alignment and byte order wise).
+	// Also note that the T & form removes const-ness, since there is no ConstCssmData.
+	//
+	template <class T>
+	static CssmData wrap(const T &it)
+	{ return CssmData(const_cast<void *>(reinterpret_cast<const void *>(&it)), sizeof(it)); }
+	
+	template <class T>
+	static CssmData wrap(T *data, size_t length)
+	{ return CssmData(static_cast<void *>(data), length); }
+
+	//
+	// Automatically convert a CssmData to any pointer-to-byte-sized-type.
+	//
+	operator signed char * () const { return reinterpret_cast<signed char *>(Data); }
+	operator unsigned char * () const { return reinterpret_cast<unsigned char *>(Data); }
+	operator char * () const { return reinterpret_cast<char *>(Data); }
+	operator void * () const { return reinterpret_cast<void *>(Data); }
+	
+	//
+	// If you want to interprete the contents of a CssmData blob as a particular
+	// type, you have to be more explicit to show that you know what you're doing.
+	// See wrap() above.
+	//
+	template <class T>
+	T *interpretedAs() const		{ return reinterpret_cast<T *>(Data); }
+	
+	template <class T>
+	T *interpretedAs(size_t len, CSSM_RETURN error = CSSM_ERRCODE_INVALID_DATA) const
+	{
+		if (length() != len) CssmError::throwMe(error);
+		return interpretedAs<T>();
+	}
+	
+public:
+    void length(size_t newLength)	// shorten only
+    { assert(newLength <= Length); Length = newLength; }
+
+	void *at(off_t offset) const
+	{ assert(offset >= 0 && offset <= Length); return Data + offset; }
+	void *at(off_t offset, size_t size) const	// length-checking version
+	{ assert(offset >= 0 && offset + size <= Length); return Data + offset; }
+	
+    unsigned char operator [] (size_t pos) const
+    { assert(pos < Length); return Data[pos]; }
+    void *use(size_t taken)			// logically remove some bytes
+    { assert(taken <= Length); void *r = Data; Length -= taken; Data += taken; return r; }
+	
+	void clear()
+	{ Data = NULL; Length = 0; }
+
+    operator string () const	// convert to string type (no trailing null)
+    { return string(reinterpret_cast<const char *>(data()), length()); }
+
+    operator bool () const { return Data != NULL; }
+    bool operator ! () const { return Data == NULL; }
+    bool operator < (const CssmData &other) const;
+	bool operator == (const CssmData &other) const
+	{ return length() == other.length() && !memcmp(data(), other.data(), length()); }
+	bool operator != (const CssmData &other) const
+	{ return !(*this == other); }
+    
+    // Extract fixed-format data from a CssmData. Fixes any alignment trouble for you.
+    template <class T>
+    void extract(T &destination, CSSM_RETURN error = CSSM_ERRCODE_INVALID_DATA) const
+    {
+        if (length() != sizeof(destination) || data() == NULL)
+            CssmError::throwMe(error);
+        memcpy(&destination, data(), sizeof(destination));
+    }
+};
+
+
+inline bool CssmData::operator < (const CssmData &other) const
+{
+    if (Length != other.Length) // If lengths are not equal the shorter data is smaller.
+        return Length < other.Length;
+    if (Length == 0) // If lengths are both zero ignore the Data.
+        return false;
+    if (Data == NULL || other.Data == NULL)	// arbitrary (but consistent) ordering
+        return Data < other.Data;
+    return memcmp(Data, other.Data, Length) < 0; // Do a lexicographic compare on equal sized Data.
+}
+
+
+//
+// User-friendler CSSM_CRYPTO_DATA objects
+//
+class CryptoCallback {
+public:
+	CryptoCallback(CSSM_CALLBACK func, void *ctx = NULL) : mFunction(func), mCtx(ctx) { }
+	CSSM_CALLBACK function() const { return mFunction; }
+	void *context() const { return mCtx; }
+
+	CssmData operator () () const
+	{
+		CssmData output;
+		if (CSSM_RETURN err = mFunction(&output, mCtx))
+			CssmError::throwMe(err);
+		return output;
+	}
+
+private:
+	CSSM_CALLBACK mFunction;
+	void *mCtx;
+};
+
+class CssmCryptoData : public PodWrapper<CssmCryptoData, CSSM_CRYPTO_DATA> {
+public:
+	CssmCryptoData() { }
+	
+	CssmCryptoData(const CssmData &param, CSSM_CALLBACK callback = NULL, void *ctx = NULL)
+	{ Param = const_cast<CssmData &>(param); Callback = callback; CallerCtx = ctx; }
+
+	CssmCryptoData(const CssmData &param, CryptoCallback &cb)
+	{ Param = const_cast<CssmData &>(param); Callback = cb.function(); CallerCtx = cb.context(); }
+	
+	CssmCryptoData(CSSM_CALLBACK callback, void *ctx = NULL)
+	{ /* ignore Param */ Callback = callback; CallerCtx = ctx; }
+	
+	explicit CssmCryptoData(CryptoCallback &cb)
+	{ /* ignore Param */ Callback = cb.function(); CallerCtx = cb.context(); }
+
+	// member access
+	CssmData &param() { return CssmData::overlay(Param); }
+	const CssmData &param() const { return CssmData::overlay(Param); }
+	bool hasCallback() const { return Callback != NULL; }
+	CryptoCallback callback() const { return CryptoCallback(Callback, CallerCtx); }
+
+	// get the value, whichever way is appropriate
+	CssmData operator () () const
+	{ return hasCallback() ? callback() () : param(); }
+};
+
+// a CssmCryptoContext whose callback is a virtual class member
+class CryptoDataClass : public CssmCryptoData {
+public:
+	CryptoDataClass() : CssmCryptoData(callbackShim, this) { }
+	virtual ~CryptoDataClass();
+	
+protected:
+	virtual CssmData yield() = 0;	// must subclass and implement this
+	
+private:
+	static CSSM_RETURN callbackShim(CSSM_DATA *output, void *ctx)
+	{
+		BEGIN_API
+		*output = reinterpret_cast<CryptoDataClass *>(ctx)->yield();
+		END_API(CSSM)
+	}
+};
+
+
+//
+// CSSM_OIDs are CSSM_DATAs but will probably have different wrapping characteristics.
+//
+typedef CssmData CssmOid;
+
+
+//
+// User-friendlier CSSM_KEY objects
+//
+class CssmKey : public PodWrapper<CssmKey, CSSM_KEY> {
+public:
+    CssmKey() { KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; }
+    CssmKey(CSSM_KEY &key);
+    CssmKey(CSSM_DATA &keyData);
+    CssmKey(uint32 length, uint8 *data);
+
+public:
+    class Header : public PodWrapper<Header, CSSM_KEYHEADER> {
+    public:
+		// access to components of the key header
+		CSSM_KEYBLOB_TYPE blobType() const { return BlobType; }
+		void blobType(CSSM_KEYBLOB_TYPE blobType) { BlobType = blobType; }
+		
+		CSSM_KEYBLOB_FORMAT blobFormat() const { return Format; }
+		void blobFormat(CSSM_KEYBLOB_FORMAT blobFormat) { Format = blobFormat; }
+		
+		CSSM_KEYCLASS keyClass() const { return KeyClass; }
+		void keyClass(CSSM_KEYCLASS keyClass) { KeyClass = keyClass; }
+		
+		CSSM_KEY_TYPE algorithm() const { return AlgorithmId; }
+		void algorithm(CSSM_KEY_TYPE algorithm) { AlgorithmId = algorithm; }
+		
+		CSSM_KEY_TYPE wrapAlgorithm() const { return WrapAlgorithmId; }
+		void wrapAlgorithm(CSSM_KEY_TYPE wrapAlgorithm) { WrapAlgorithmId = wrapAlgorithm; }
+        
+        CSSM_ENCRYPT_MODE wrapMode() const { return WrapMode; }
+        void wrapMode(CSSM_ENCRYPT_MODE mode) { WrapMode = mode; }
+		
+		bool isWrapped() const { return WrapAlgorithmId != CSSM_ALGID_NONE; }
+
+		const Guid &cspGuid() const { return Guid::overlay(CspId); }
+		void cspGuid(const Guid &guid) { Guid::overlay(CspId) = guid; }
+		
+		uint32 attributes() const { return KeyAttr; }
+		bool attribute(uint32 attr) const { return KeyAttr & attr; }
+		void setAttribute(uint32 attr) { KeyAttr |= attr; }
+		void clearAttribute(uint32 attr) { KeyAttr &= ~attr; }
+		
+		uint32 usage() const { return KeyUsage; }
+		bool useFor(uint32 u) const { return KeyUsage & u; }
+
+		void usage(uint32 u) { KeyUsage |= u; }
+		void clearUsage(uint32 u) { u &= ~u; }
+
+    };
+
+   // access to the key header
+   Header &header() { return Header::overlay(KeyHeader); }
+	const Header &header() const { return Header::overlay(KeyHeader); }
+	
+	CSSM_KEYBLOB_TYPE blobType() const	{ return header().blobType(); }
+	void blobType(CSSM_KEYBLOB_TYPE blobType) { header().blobType(blobType); }
+
+	CSSM_KEYBLOB_FORMAT blobFormat() const { return header().blobFormat(); }
+	void blobFormat(CSSM_KEYBLOB_FORMAT blobFormat) { header().blobFormat(blobFormat); }
+
+	CSSM_KEYCLASS keyClass() const		{ return header().keyClass(); }
+	void keyClass(CSSM_KEYCLASS keyClass) { header().keyClass(keyClass); }
+
+	CSSM_KEY_TYPE algorithm() const		{ return header().algorithm(); }
+	void algorithm(CSSM_KEY_TYPE algorithm) { header().algorithm(algorithm); }
+
+	CSSM_KEY_TYPE wrapAlgorithm() const	{ return header().wrapAlgorithm(); }
+	void wrapAlgorithm(CSSM_KEY_TYPE wrapAlgorithm) { header().wrapAlgorithm(wrapAlgorithm); }
+    
+    CSSM_ENCRYPT_MODE wrapMode() const	{ return header().wrapMode(); }
+    void wrapMode(CSSM_ENCRYPT_MODE mode) { header().wrapMode(mode); }
+	
+	bool isWrapped() const				{ return header().isWrapped(); }
+	const Guid &cspGuid() const			{ return header().cspGuid(); }
+	
+	uint32 attributes() const			{ return header().attributes(); }
+	bool attribute(uint32 a) const		{ return header().attribute(a); }
+	void setAttribute(uint32 attr) { header().setAttribute(attr); }
+	void clearAttribute(uint32 attr) { header().clearAttribute(attr); }
+
+	uint32 usage() const				{ return header().usage(); }
+	bool useFor(uint32 u) const			{ return header().useFor(u); }
+
+	void usage(uint32 u) { header().usage(u); }
+	void clearUsage(uint32 u) { header().clearUsage(u); }
+	
+public:
+	// access to the key data
+	size_t length() const { return KeyData.Length; }
+	void *data() const { return KeyData.Data; }
+	operator void * () const { return data(); }
+	operator CssmData & () { return CssmData::overlay(KeyData); }
+	operator const CssmData & () const { return static_cast<const CssmData &>(KeyData); }
+	operator bool () const { return KeyData.Data != NULL; }
+	void operator = (const CssmData &data) { KeyData = data; }
+};
+
+
+//
+// Wrapped keys are currently identically structured to normal keys.
+// But perhaps in the future...
+//
+typedef CssmKey CssmWrappedKey;
+
+
+//
+// Other PodWrappers for stuff that is barely useful...
+//
+class QuerySizeData : public PodWrapper<QuerySizeData, CSSM_QUERY_SIZE_DATA> {
+public:
+	QuerySizeData(uint32 in) { SizeInputBlock = in; SizeOutputBlock = 0; }
+	
+	uint32 inputSize() const { return SizeInputBlock; }
+	uint32 inputSize(uint32 size) { return SizeInputBlock = size; }
+	uint32 outputSize() const { return SizeOutputBlock; }
+};
+
+class CSPOperationalStatistics : 
+	public PodWrapper<CSPOperationalStatistics, CSSM_CSP_OPERATIONAL_STATISTICS> {
+public:
+};
+
+
+//
+// User-friendli(er) DL queries.
+// @@@ Preliminary (flesh out as needed)
+//
+class DLQuery : public PodWrapper<DLQuery, CSSM_QUERY> {
+public:
+    DLQuery() { /*IFDEBUG(*/ memset(this, 0, sizeof(*this)) /*)*/ ; }
+    DLQuery(const CSSM_QUERY &q) { memcpy(this, &q, sizeof(*this)); }
+
+    DLQuery &operator = (const CSSM_QUERY &q)
+    { memcpy(this, &q, sizeof(*this)); return *this; }
+};
+
+
+//
+// CoreFoundation support.
+// This will move into a separate file.
+//
+
+//
+// Initialize-only self-releasing CF object handler (lightweight).
+// Does not support assignment.
+//
+template <class CFType> class CFRef {
+public:
+    CFRef() : mRef(NULL) { }
+    CFRef(CFType ref) : mRef(ref) { }
+    CFRef(const CFRef &ref) : mRef(ref) { if (ref) CFRetain(ref); }
+    ~CFRef() { if (mRef) CFRelease(mRef); }
+
+    CFRef &operator = (CFType ref)
+    { if (ref) CFRetain(ref); if (mRef) CFRelease(mRef); mRef = ref; return *this; }
+
+    operator CFType () const { return mRef; }
+    operator bool () const { return mRef != NULL; }
+    bool operator ! () const { return mRef == NULL; }
+
+private:
+    CFType mRef;
+};
+
+template <class CFType> class CFCopyRef {
+public:
+    CFCopyRef() : mRef(NULL) { }
+    explicit CFCopyRef(CFType ref) : mRef(ref) { if (ref) CFRetain(ref); }
+    CFCopyRef(const CFCopyRef &ref) : mRef(ref) { if (ref) CFRetain(ref); }
+    ~CFCopyRef() { if (mRef) CFRelease(mRef); }
+
+    CFCopyRef &operator = (CFType ref)
+    { if (ref) CFRetain(ref); if (mRef) CFRelease(mRef); mRef = ref; return *this; }
+
+    operator CFType () const { return mRef; }
+    operator bool () const { return mRef != NULL; }
+    bool operator ! () const { return mRef == NULL; }
+
+private:
+    CFType mRef;
+};
+
+// Help with container of something->pointer cleanup
+template <class In>
+static inline void for_each_delete(In first, In last)
+{
+    while (first != last)
+        delete *(first++);
+}
+
+// Help with map of something->pointer cleanup
+template <class In>
+static inline void for_each_map_delete(In first, In last)
+{
+    while (first != last)
+        delete (first++)->second;
+}
+
+// Quick and dirty template for a (temporary) array of something
+// Usage example auto_array<uint32> anArray(20);
+template <class T>
+class auto_array
+{
+public:
+	auto_array() : mArray(NULL) {}
+	auto_array(size_t inSize) : mArray(new T[inSize]) {}
+	~auto_array() { if (mArray) delete[] mArray; }
+    T &operator[](size_t inIndex) { return mArray[inIndex]; }
+	void allocate(size_t inSize) { if (mArray) delete[] mArray; mArray = new T[inSize]; }
+	T *get() { return mArray; }
+	T *release() { T *anArray = mArray; mArray = NULL; return anArray; }
+private:
+	T *mArray;
+};
+
+// Template for a vector-like class that takes a c-array as it's
+// underlying storage without making a copy.
+template <class _Tp>
+class constVector
+{
+    NOCOPY(constVector<_Tp>)
+public:
+    typedef _Tp value_type;
+    typedef const value_type* const_pointer;
+    typedef const value_type* const_iterator;
+    typedef const value_type& const_reference;
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+
+    typedef reverse_iterator<const_iterator> const_reverse_iterator;
+public:
+    const_iterator begin() const { return _M_start; }
+    const_iterator end() const { return _M_finish; }
+
+    const_reverse_iterator rbegin() const
+    { return const_reverse_iterator(end()); }
+    const_reverse_iterator rend() const
+    { return const_reverse_iterator(begin()); }
+
+    size_type size() const
+    { return size_type(end() - begin()); }
+    bool empty() const
+    { return begin() == end(); }
+
+    const_reference operator[](size_type __n) const { return *(begin() + __n); }
+
+    // "at" will eventually have range checking, once we have the
+    // infrastructure to be able to throw stl range errors.
+    const_reference at(size_type n) const { return (*this)[n]; }
+
+    constVector(size_type __n, const _Tp* __value)
+    : _M_start(__value), _M_finish(__value + __n)
+    {}
+	
+	constVector() : _M_start(NULL), _M_finish(NULL) {}
+	
+	void overlay(size_type __n, const _Tp* __value) {
+		_M_start = __value;
+		_M_finish = __value + __n;
+	}
+
+    const_reference front() const { return *begin(); }
+    const_reference back() const { return *(end() - 1); }
+private:
+    const _Tp *_M_start;
+    const _Tp *_M_finish;
+};
+
+} // end namespace Security
+
+#ifdef _CPP_UTILITIES
+#pragma export off
+#endif
+
+#endif //_H_UTILITIES
diff --git a/cdsa/cdsa_utilities/utility_config.h b/cdsa/cdsa_utilities/utility_config.h
new file mode 100644
index 00000000..289fef67
--- /dev/null
+++ b/cdsa/cdsa_utilities/utility_config.h
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+
+//
+// utility_config.h - common configuration for the utility libraries
+//
+#ifndef _H_UTILITY_CONFIG
+#define _H_UTILITY_CONFIG
+
+// include public configuration
+#include <Security/cssmconfig.h>
+
+//
+// Headers of varying provenance.
+// We include these here because they're ubiquitous, and it's too much of a pain
+// to replicate this logic everywhere.
+//
+#if defined(TARGET_OS_MAC)
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+#elif defined(TARGET_OS_UNIX)
+# include <sys/types.h>
+#endif
+
+#include <assert.h>
+
+//
+// Decide what io apis we'll be using
+//
+#define _USE_IO_POSIX 0
+#define _USE_IO_MACOS 1
+
+#if !defined(_USE_IO)
+# if TARGET_API_MAC_OS8
+#  define _USE_IO _USE_IO_MACOS
+# else
+#  define _USE_IO _USE_IO_POSIX
+# endif
+#endif
+
+//
+// Decide what threading support we'll be using
+//
+#define _USE_NO_THREADS 0
+#define _USE_PTHREADS 1
+#define _USE_MPTHREADS 2
+
+#include <unistd.h>
+#if defined(_POSIX_THREADS)
+# define _USE_THREADS _USE_PTHREADS
+#endif
+#if !defined(_USE_THREADS)
+# define _USE_THREADS _USE_NO_THREADS
+#endif
+
+
+//
+// Compatibility switches
+//
+#define COMPAT_OSX_10_0		1	/* be compatible with MacOS 10.0.x formats & features */
+
+
+//
+// Bugs, buglets, and special compiler features
+//
+#define bug_private	private
+#define bug_protected protected
+#define bug_const const
+
+#define BUG_GCC 0
+
+#if defined(__GNUC__)
+# undef BUG_GCC
+# define BUG_GCC 1
+# undef bug_const
+# define bug_const
+#else
+# if !defined(__attribute__)
+#  define __attribute__(whatever)	/* don't use for non-gcc compilers */
+# endif
+#endif
+
+/*
+ld: for architecture ppc
+ld: common symbols not allowed with MH_DYLIB output format
+/Network/Servers/fivestar/homes/delaware/jhurley/AppleDev/insight/build/intermediates/KeychainLib.build/Objects/Sources/KeychainLib/KCSleep.o definition of common __7KCSleep.mKCSleepRec (size 12)
+*/
+#define BUG_COMMON_SYMBOLS
+
+// Make sure that namespace Security exists
+namespace Security
+{
+} // end namespace Security
+
+// Automatically use the Security namespace for everything that includes the utility_config header.
+using namespace Security;
+
+#endif //_H_UTILITY_CONFIG
diff --git a/cdsa/cdsa_utilities/walkers.cpp b/cdsa/cdsa_utilities/walkers.cpp
new file mode 100644
index 00000000..bba89348
--- /dev/null
+++ b/cdsa/cdsa_utilities/walkers.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+//
+// walkers - facilities for traversing and manipulating recursive data structures
+//
+// Theory of operation:
+// @@@ TBA
+//
+#ifdef __MWERKS__
+#define _CPP_WALKERS
+#endif
+#include <Security/walkers.h>
+
+
+namespace Security
+{
+
+namespace DataWalkers
+{
+
+//
+// Free all recorded storage nodes for a ChunkFreeWalker
+//
+void ChunkFreeWalker::free()
+{
+	for (set<void *>::iterator it = freeSet.begin(); it != freeSet.end(); it++)
+		allocator.free(*it);
+	freeSet.erase(freeSet.begin(), freeSet.end());
+}
+
+// Virtual destructor
+
+VirtualWalker::~VirtualWalker()
+{
+}
+
+} // end namespace DataWalkers
+
+} // end namespace Security
diff --git a/cdsa/cdsa_utilities/walkers.h b/cdsa/cdsa_utilities/walkers.h
new file mode 100644
index 00000000..f2c96a5e
--- /dev/null
+++ b/cdsa/cdsa_utilities/walkers.h
@@ -0,0 +1,328 @@
+/*
+ * 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.
+ */
+
+
+//
+// walkers - facilities for traversing and manipulating recursive data structures
+//
+// Very briefly, this facility allows for deep traversals of (potentially) recursive
+// data structures through templated structure "walkers." Standard operations include
+// deep copying to a contiguous memory buffer, size calculation, and reconstitution
+// after relocation (e.g. via IPC). You can add other operations (e.g. scattered deep
+// copy, debug dumping, etc.) by defining operations classes and applying them to the
+// existing walkers. You can also extend the reach of the facility to new data structures
+// by writing appropriate walker functions for them.
+//
+// For more detailed rules and regulations, see the accompanying documentation.
+//
+#ifndef _H_WALKERS
+#define _H_WALKERS
+
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <Security/memutils.h>
+#include <set>
+
+#ifdef _CPP_WALKERS
+# pragma export on
+#endif
+
+
+namespace Security
+{
+
+namespace DataWalkers
+{
+
+//
+// Standard operators for sizing, copying, and reinflating
+//
+class SizeWalker : public LowLevelMemoryUtilities::Writer::Counter {
+public:
+    template <class T>
+    void operator () (T *, size_t size = sizeof(T))
+    { LowLevelMemoryUtilities::Writer::Counter::insert(size); }
+    
+    void reserve(size_t space)
+    { LowLevelMemoryUtilities::Writer::Counter::insert(space); }
+    
+    static const bool needsRelinking = false;
+    static const bool needsSize = true;
+};
+
+class CopyWalker : public LowLevelMemoryUtilities::Writer {
+public:
+    CopyWalker() { }
+    CopyWalker(void *base) : LowLevelMemoryUtilities::Writer(base) { }
+    
+    template <class T>
+    void operator () (T * &addr, size_t size = sizeof(T))
+    {
+        if (addr)
+            addr = reinterpret_cast<T *>(LowLevelMemoryUtilities::Writer::operator () (addr, size));
+    }
+    
+    static const bool needsRelinking = true;
+    static const bool needsSize = true;
+};
+
+class ReconstituteWalker {
+public:
+    ReconstituteWalker(off_t offset) : mOffset(offset) { }
+    ReconstituteWalker(void *ptr, void *base)
+    : mOffset(LowLevelMemoryUtilities::difference(ptr, base)) { }
+
+    template <class T>
+    void operator () (T * &addr, size_t = 0)
+    {
+        if (addr)
+            addr = LowLevelMemoryUtilities::increment<T>(addr, mOffset);
+    }
+    
+    static const bool needsRelinking = true;
+    static const bool needsSize = false;
+    
+private:
+    off_t mOffset;
+};
+
+class ChunkCopyWalker {
+public:
+    ChunkCopyWalker(CssmAllocator &alloc = CssmAllocator::standard()) : allocator(alloc) { }
+    
+    CssmAllocator &allocator;
+    
+    template <class T>
+    void operator () (T * &addr, size_t size = sizeof(T))
+    {
+#if BUG_GCC
+        T *copy = reinterpret_cast<T *>(allocator.malloc(size));
+#else
+        T *copy = allocator.malloc<T>(size);
+#endif
+        memcpy(copy, addr, size);
+        addr = copy;
+    }
+    
+    static const bool needsRelinking = true;
+    static const bool needsSize = true;
+};
+
+class ChunkFreeWalker {
+public:
+    ChunkFreeWalker(CssmAllocator &alloc = CssmAllocator::standard()) : allocator(alloc) { }
+    
+    CssmAllocator &allocator;
+    
+    template <class T>
+    void operator () (T *addr, size_t = sizeof(T))
+    {
+        freeSet.insert(addr);
+    }
+    
+    void free();
+    ~ChunkFreeWalker() { free(); }
+    
+    static const bool needsRelinking = false;
+    static const bool needsSize = false;
+
+private:
+    set<void *> freeSet;
+};
+
+
+//
+// The VirtualWalker class is a generic walker interface
+// for dynamic passing around.
+//
+class VirtualWalker {
+public:
+    VirtualWalker(bool nrl = false) : needsRelinking(nrl) { }
+    virtual ~VirtualWalker();
+    
+    virtual void operator () (void * &addr, size_t size) = 0;
+
+    const bool needsRelinking;
+};
+
+template <class Walker>
+class VirtualWalkerFor : public VirtualWalker {
+public:
+    VirtualWalkerFor(Walker &w, bool nrl = false) : VirtualWalker(nrl), walker(w) { }
+    void operator () (void * &addr, size_t size)
+    { walker(addr, size); }
+    
+    Walker &walker;
+};
+
+
+//
+// Stand-alone operations for a single structure web
+//
+template <class T>
+size_t size(T obj)
+{
+    SizeWalker w;
+    walk(w, obj);
+    return w;
+}
+
+template <class T>
+T *copy(const T *obj, void *addr)
+{
+    if (obj == NULL)
+        return NULL;
+    CopyWalker w(addr);
+    walk(w, obj);
+    return reinterpret_cast<T *>(addr);
+}
+
+template <class T>
+T *copy(const T *obj, CssmAllocator &alloc = CssmAllocator::standard())
+{
+    return obj ? copy(obj, alloc, size(obj)) : NULL;
+}
+
+template <class T>
+T *copy(const T *obj, CssmAllocator &alloc, size_t size)
+{
+    if (obj == NULL)
+        return NULL;
+    return copy(obj, alloc.malloc(size));
+}
+
+template <class T>
+void relocate(T *obj, T *base)
+{
+	if (obj) {
+		ReconstituteWalker w(LowLevelMemoryUtilities::difference(obj, base));
+		walk(w, base);
+	}
+}
+
+template <class T>
+T *chunkCopy(const T *obj, CssmAllocator &alloc = CssmAllocator::standard())
+{
+	if (obj) {
+		ChunkCopyWalker w(alloc);
+		return walk(w, obj);
+	} else
+		return NULL;
+}
+
+template <class T>
+void chunkFree(const T *obj, CssmAllocator &alloc = CssmAllocator::standard())
+{
+    if (obj) {
+		ChunkFreeWalker w(alloc);
+		walk(w, obj);
+	}
+}
+
+template <class T>
+class Copier {
+public:
+    Copier(const T *obj, CssmAllocator &alloc = CssmAllocator::standard()) : allocator(alloc)
+    {
+        if (obj == NULL) {
+            mValue = NULL;
+            mLength = 0;
+        } else {
+            mLength = size(obj);
+#if BUG_GCC
+            mValue = reinterpret_cast<T *>(alloc.malloc(mLength));
+#else
+            mValue = alloc.malloc<T>(mLength);
+#endif
+            mValue = copy(obj, mValue);
+        }
+    }
+    
+    Copier(const T *obj, uint32 count, CssmAllocator &alloc = CssmAllocator::standard())
+		: allocator(alloc)
+    {
+        if (obj == NULL) {
+            mValue = NULL;
+            mLength = 0;
+        } else {
+            SizeWalker sizer;
+            sizer.reserve(sizeof(T) * count);	// initial vector size
+            for (uint32 n = 0; n < count; n++)
+                walk(sizer, obj[n]);	// dependent data sizes
+            mLength = sizer;
+#if BUG_GCC
+            mValue = reinterpret_cast<T *>(alloc.malloc(mLength));
+#else
+            mValue = alloc.malloc<T>(mLength);
+#endif
+            CopyWalker copier(LowLevelMemoryUtilities::increment(mValue, sizeof(T) * count));
+            for (uint32 n = 0; n < count; n++) {
+                mValue[n] = obj[n];
+                walk(copier, mValue[n]);
+            }
+        }
+    }
+
+    CssmAllocator &allocator;
+
+    ~Copier() { allocator.free(mValue); }
+    
+    operator T *() const { return mValue; }
+    size_t length() const { return mLength; }
+    
+    T *keep() { T *result = mValue; mValue = NULL; return result; }	
+    
+private:
+    T *mValue;
+    size_t mLength;
+};
+
+
+//
+// Allow const pointer input but cast the const-ness away.
+// This is valid because the walkers never directly *write* into *obj;
+// they just pass their parts along to operate(). If we are in a writing
+// pass, operate() must ensure it copies (and replaces) its argument to
+// make it writable.
+// (The alternative design calls for three walk() functions for each type,
+//  which is ugly and error prone.)
+//
+template <class Action, class T>
+T *walk(Action &operate, const T * &obj)
+{ return walk(operate, const_cast<T * &>(obj)); }
+
+
+//
+// The default walker assumes a flat data structure
+//
+template <class Action, class Type>
+Type *walk(Action &operate, Type * &obj)
+{
+    operate(obj);
+    return obj;
+}
+
+
+} // end namespace DataWalkers
+
+} // end namespace Security
+
+#ifdef _CPP_WALKERS
+# pragma export off
+#endif
+
+#endif //_H_WALKERS
diff --git a/cdsa/cssm/.cvsignore b/cdsa/cssm/.cvsignore
new file mode 100644
index 00000000..02a2add0
--- /dev/null
+++ b/cdsa/cssm/.cvsignore
@@ -0,0 +1 @@
+cdsa?Data
diff --git a/cdsa/cssm/MDS b/cdsa/cssm/MDS
new file mode 100644
index 00000000..11fd28b2
--- /dev/null
+++ b/cdsa/cssm/MDS
@@ -0,0 +1,5 @@
+{87191ca1-0fc9-11d4-849a000502b52122}	d	*AppleDL
+{87191ca2-0fc9-11d4-849a000502b52122}	c	*AppleCSP
+{87191ca3-0fc9-11d4-849a000502b52122}	cd	*AppleCSPDL
+{87191ca4-0fc9-11d4-849a000502b52122}	C	*AppleX509CL
+{87191ca5-0fc9-11d4-849a000502b52122}	t	*AppleX509TP
diff --git a/cdsa/cssm/attachfactory.cpp b/cdsa/cssm/attachfactory.cpp
new file mode 100644
index 00000000..6c4de99b
--- /dev/null
+++ b/cdsa/cssm/attachfactory.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+
+//
+// attachfactory - industrial grade production of Attachment objects
+//
+#ifdef __MWERKS__
+#define _CPP_ATTACHFACTORY
+#endif
+#include "attachfactory.h"
+
+#include "cspattachment.h"
+#include <Security/cssmdli.h>
+#include <Security/cssmcli.h>
+#include <Security/cssmaci.h>
+#include <Security/cssmtpi.h>
+#include "funcnames.gen"
+#include <map>
+
+
+//
+// A template to generate AttachmentMakers for the standard plugin types.
+//
+template <CSSM_SERVICE_TYPE type, typename Table, const char *const nameTable[]>
+class StandardAttachmentMaker : public AttachmentMaker {
+public:
+    StandardAttachmentMaker();
+
+    Attachment *make(Module *module,
+                     const CSSM_VERSION &version,
+                     uint32 subserviceId,
+                     CSSM_SERVICE_TYPE subserviceType,
+                     const CSSM_API_MEMORY_FUNCS &memoryOps,
+                     CSSM_ATTACH_FLAGS attachFlags,
+                     CSSM_KEY_HIERARCHY keyHierarchy,
+                     CSSM_FUNC_NAME_ADDR *FunctionTable,
+                     uint32 NumFunctions)
+    {
+        StandardAttachment<type, Table> *attachment =
+        new StandardAttachment<type, Table>(module,
+                                             nameMap,
+                                             version,
+                                             subserviceId,
+                                             subserviceType,
+                                             memoryOps,
+                                             attachFlags,
+                                             keyHierarchy);
+        attachment->resolveSymbols(FunctionTable, NumFunctions);
+        return attachment;
+    }
+
+private:
+    typedef StandardAttachment<type, Table>::NameMap NameMap;
+    NameMap nameMap;
+};
+
+
+//
+// The constructor of the StandardAttachmentMaker builds a dictionary
+// derived from the plugin type's function name tables.
+//
+template <CSSM_SERVICE_TYPE type, typename Table, const char *nameTable[]>
+StandardAttachmentMaker<type, Table, nameTable>::StandardAttachmentMaker()
+: AttachmentMaker(type)
+{
+    for (unsigned n = 0; n < sizeof(nameTable) / sizeof(nameTable[0]); n++)
+        nameMap.insert(NameMap::value_type(nameTable[n], n));
+}
+
+//
+// Implementation of an attachment factory
+//
+AttachmentFactory::AttachmentFactory()
+{
+    // generate explicitly known attachment types
+    factories[CSSM_SERVICE_AC] = new StandardAttachmentMaker<CSSM_SERVICE_AC, CSSM_SPI_AC_FUNCS, ACNameTable>;
+    factories[CSSM_SERVICE_CL] = new StandardAttachmentMaker<CSSM_SERVICE_CL, CSSM_SPI_CL_FUNCS, CLNameTable>;
+    factories[CSSM_SERVICE_CSP] = new StandardAttachmentMaker<CSSM_SERVICE_CSP, CSSM_SPI_CSP_FUNCS, CSPNameTable>;
+    factories[CSSM_SERVICE_DL] = new StandardAttachmentMaker<CSSM_SERVICE_DL, CSSM_SPI_DL_FUNCS, DLNameTable>;
+    factories[CSSM_SERVICE_TP] = new StandardAttachmentMaker<CSSM_SERVICE_TP, CSSM_SPI_TP_FUNCS, TPNameTable>;
+}
+
+
+AttachmentMaker *AttachmentFactory::attachmentMakerFor(CSSM_SERVICE_TYPE type) const
+{
+    AttachFactories::const_iterator it = factories.find(type);
+    if (it == factories.end())
+        CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
+    return it->second;
+}
+
+
+//
+// Manage an AttachmentMaker
+//
+AttachmentMaker::~AttachmentMaker()
+{
+}
diff --git a/cdsa/cssm/attachfactory.h b/cdsa/cssm/attachfactory.h
new file mode 100644
index 00000000..27d874df
--- /dev/null
+++ b/cdsa/cssm/attachfactory.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+
+//
+// attachfactory - industrial grade production of Attachment objects
+//
+#ifndef _H_ATTACHFACTORY
+#define _H_ATTACHFACTORY
+
+#include "cssmint.h"
+#include "attachment.h"
+
+#ifdef _CPP_ATTACHFACTORY
+# pragma export on
+#endif
+
+
+//
+// An AttachmentMaker can create an Attachment object for a particular service
+// type when asked nicely.
+// 
+class AttachmentMaker {
+public:
+    AttachmentMaker(CSSM_SERVICE_TYPE type) : mType(type) { }
+    virtual ~AttachmentMaker();
+
+    virtual Attachment *make(Module *module,
+                             const CSSM_VERSION &version,
+                             uint32 subserviceId,
+                             CSSM_SERVICE_TYPE subserviceType,
+                             const CSSM_API_MEMORY_FUNCS &memoryOps,
+                             CSSM_ATTACH_FLAGS attachFlags,
+                             CSSM_KEY_HIERARCHY keyHierarchy,
+                             CSSM_FUNC_NAME_ADDR *functionTable,
+                             uint32 functionTableSize) = 0;
+
+    CSSM_SERVICE_TYPE factoryType() const { return mType; }
+    
+private:
+    CSSM_SERVICE_TYPE mType;
+};
+
+
+//
+// An AttachmentFactory contains a registry of AttachmentMakers for different
+// service types, and produces the needed one on request.
+//
+class AttachmentFactory {
+public:
+    AttachmentFactory();
+    
+    AttachmentMaker *attachmentMakerFor(CSSM_SERVICE_TYPE type) const;
+
+private:
+    typedef map<CSSM_SERVICE_TYPE, AttachmentMaker *> AttachFactories;
+    AttachFactories factories;
+};
+
+#ifdef _CPP_ATTACHFACTORY
+# pragma export off
+#endif
+
+
+#endif //_H_ATTACHFACTORY
diff --git a/cdsa/cssm/attachment.cpp b/cdsa/cssm/attachment.cpp
new file mode 100644
index 00000000..d2f2be4f
--- /dev/null
+++ b/cdsa/cssm/attachment.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+
+//
+// attachment - CSSM module attachment objects
+//
+#ifdef __MWERKS__
+#define _CPP_ATTACHMENT
+#endif
+#include "attachment.h"
+#include "module.h"
+#include "manager.h"
+#include "cssmcontext.h"
+
+
+//
+// Construct an Attachment object.
+// This constructor does almost all the work: it initializes the Attachment
+// object, calls the plugin's attach function, and initializes everything.
+// The only job left for the subclass's constructor is to take the spiFunctionTable
+// field and extract from it the plugin's dispatch table in suitable form.
+//
+Attachment::Attachment(Module *parent,
+                       const CSSM_VERSION &version,
+                       uint32 ssId,
+                       CSSM_SERVICE_TYPE ssType,
+                       const CSSM_API_MEMORY_FUNCS &memoryOps,
+                       CSSM_ATTACH_FLAGS attachFlags,
+                       CSSM_KEY_HIERARCHY keyHierarchy)
+	: CssmMemoryFunctionsAllocator(memoryOps), module(*parent)
+{
+    // record our origins
+    mVersion = version;
+    mSubserviceId = ssId;
+    mSubserviceType = ssType;
+    mAttachFlags = attachFlags;
+    mKeyHierarchy = keyHierarchy;
+
+    // we are not (yet) attached to our plugin
+    mIsActive = false;
+    
+    // build the upcalls table
+    // (we could do this once in a static, but then we'd have to lock on it)
+    upcalls.malloc_func = upcallMalloc;
+    upcalls.free_func = upcallFree;
+    upcalls.realloc_func = upcallRealloc;
+    upcalls.calloc_func = upcallCalloc;
+    upcalls.CcToHandle_func = upcallCcToHandle;
+    upcalls.GetModuleInfo_func = upcallGetModuleInfo;
+
+    // tell the module to create an attachment
+    spiFunctionTable = NULL;	// preset invalid
+    if (CSSM_RETURN err = module.plugin->CSSM_SPI_ModuleAttach(&module.myGuid(),
+            &mVersion,
+            mSubserviceId,
+            mSubserviceType,
+            mAttachFlags,
+            handle(),
+            mKeyHierarchy,
+            &module.cssm.myGuid(),	// CSSM's Guid
+            &module.cssm.myGuid(),	// module manager Guid
+            &module.cssm.callerGuid(), // caller Guid
+            &upcalls,
+            &spiFunctionTable)) {
+        // attach rejected by module
+        CssmError::throwMe(err);
+    }
+    try {
+        if (spiFunctionTable == NULL || spiFunctionTable->ServiceType != subserviceType())
+            CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE);
+        mIsActive = true;	// now officially attached to plugin
+        // subclass is responsible for taking spiFunctionTable and build
+        // whatever dispatch is needed
+    } catch (...) {
+        module.plugin->CSSM_SPI_ModuleDetach(handle());	// with extreme prejudice
+        throw;
+    }
+}
+
+
+//
+// Detach an attachment.
+// This is the polite way to detach from the plugin. It may be refused safely
+// (though perhaps not meaningfully).
+// THREADS: mLock is locked on entry IFF isLocked, and will be unlocked on exit.
+//
+void Attachment::detach(bool isLocked)
+{
+    StLock<Mutex> locker(*this, isLocked);	// pre-state locker
+	locker.lock();	// make sure it's locked
+
+    if (mIsActive) {
+        if (!isIdle())
+            CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED);	//@#attachment busy
+        if (CSSM_RETURN error = module.plugin->CSSM_SPI_ModuleDetach(handle()))
+			CssmError::throwMe(error);	// I'm sorry Dave, ...
+        mIsActive = false;
+        module.detach(this);
+    }
+}
+
+
+//
+// Destroy the Attachment object
+//
+Attachment::~Attachment()
+{
+    try {
+        detach(false);
+    } catch (...) {
+        // too bad - you're dead
+    }
+}
+
+
+//
+// Upcall relays.
+// These do not lock the attachment object. The attachment can't go away
+// because we incremented the busy count on entry to the plugin; and these
+// fields are quite constant for the life of the Attachment.
+//
+void *Attachment::upcallMalloc(CSSM_HANDLE handle, uint32 size)
+{
+    BEGIN_API
+    return findHandle<Attachment>(handle).malloc(size);
+    END_API1(NULL)
+}
+
+void Attachment::upcallFree(CSSM_HANDLE handle, void *mem)
+{
+    BEGIN_API
+    return findHandle<Attachment>(handle).free(mem);
+    END_API0
+}
+
+void *Attachment::upcallRealloc(CSSM_HANDLE handle, void *mem, uint32 size)
+{
+    BEGIN_API
+    return findHandle<Attachment>(handle).realloc(mem, size);
+    END_API1(NULL)
+}
+
+void *Attachment::upcallCalloc(CSSM_HANDLE handle, uint32 num, uint32 size)
+{
+    BEGIN_API
+    return findHandle<Attachment>(handle).calloc(num, size);
+    END_API1(NULL)
+}
+
+CSSM_RETURN Attachment::upcallCcToHandle(CSSM_CC_HANDLE handle,
+                                         CSSM_MODULE_HANDLE *modHandle)
+{
+    BEGIN_API
+    Required(modHandle) = findHandle<HandleContext>(handle).attachment.handle();
+    END_API(CSP)
+}
+
+CSSM_RETURN Attachment::upcallGetModuleInfo(CSSM_MODULE_HANDLE handle,
+                                            CSSM_GUID_PTR guid,
+                                            CSSM_VERSION_PTR version,
+                                            uint32 *subserviceId,
+                                            CSSM_SERVICE_TYPE *subserviceType,
+                                            CSSM_ATTACH_FLAGS *attachFlags,
+                                            CSSM_KEY_HIERARCHY *keyHierarchy,
+                                            CSSM_API_MEMORY_FUNCS_PTR memoryOps,
+                                            CSSM_FUNC_NAME_ADDR_PTR FunctionTable,
+                                            uint32 NumFunctions)
+{
+    BEGIN_API
+    Attachment &attachment = findHandle<Attachment>(handle);
+    Required(guid) = attachment.myGuid();
+    Required(version) = attachment.mVersion;
+    Required(subserviceId) = attachment.mSubserviceId;
+    Required(subserviceType) = attachment.mSubserviceType;
+    Required(attachFlags) = attachment.mAttachFlags;
+    Required(keyHierarchy) = attachment.mKeyHierarchy;
+    Required(memoryOps) = attachment;
+    if (FunctionTable)
+        attachment.resolveSymbols(FunctionTable, NumFunctions);
+    END_API(CSSM)
+}
diff --git a/cdsa/cssm/attachment.h b/cdsa/cssm/attachment.h
new file mode 100644
index 00000000..44596592
--- /dev/null
+++ b/cdsa/cssm/attachment.h
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+
+
+//
+// attachment - CSSM module attachment objects
+//
+#ifndef _H_ATTACHMENT
+#define _H_ATTACHMENT
+
+#include "cssmint.h"
+#include "module.h"
+#include <Security/handleobject.h>
+#include <Security/cssmalloc.h>
+
+#ifdef _CPP_ATTACHMENT
+# pragma export on
+#endif
+
+
+//
+// This type represents a single Attachment of any kind.
+// Attachments are formed by the CSSM_ModuleAttach call and represent a "session"
+// between a caller client and a particular plugin module. Any number of attachments
+// can exist for a particular caller and a particular module.
+// Attachment is an abstract class. You must subclass it to implement a concrete
+// type of plugin. For the standard ones, see the end of this header.
+// Key recovery does not use Attachments.
+// EMMs are not Attachments, but the plugins they manage are.
+// And yes, an Attachment *is* a lock. The API transition layer functions need
+// to lock Attachments from the "outside", so there's no point in being coy about it.
+// Locking the Attachment is equivalent to locking all its members except for
+// instance-constant ones.
+//
+class Attachment : public HandleObject,						// has a handle
+				   public CssmMemoryFunctionsAllocator,		// is an allocator
+				   public CountingMutex {					// is a counting lock
+	NOCOPY(Attachment)
+public:
+	Attachment(Module *theModule,
+			const CSSM_VERSION &version,
+			uint32 subserviceId,
+			CSSM_SERVICE_TYPE subserviceType,
+			const CSSM_API_MEMORY_FUNCS &memoryOps,
+			CSSM_ATTACH_FLAGS attachFlags,
+			CSSM_KEY_HIERARCHY keyHierarchy);
+	virtual ~Attachment();
+
+	Module &module;
+
+	// feature inquiries. These features are constant for the life of the Attachment
+	const Guid &myGuid() const { return module.myGuid(); }
+	CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; }
+	uint32 subserviceId() const	{ return mSubserviceId; }
+	const CSSM_VERSION &pluginVersion() const { return mVersion; }
+	CSSM_ATTACH_FLAGS attachFlags() const { return mAttachFlags; }
+	
+	bool isThreadSafe() const	{ return module.isThreadSafe(); }
+
+	// service a symbol table inquiry against our attachment
+	virtual void resolveSymbols(CSSM_FUNC_NAME_ADDR *FunctionTable,
+								uint32 NumFunctions) = 0;
+
+	// terminate the live attachment and prepare to die
+	void detach(bool isLocked);
+
+	template <class Sub> friend Sub &enterAttachment(CSSM_HANDLE);
+
+	// need to redefine lock/trylock to implement HandleObject protocol
+	void lock() { CountingMutex::lock(); }
+	bool tryLock() { return CountingMutex::tryLock(); }
+
+private:
+	bool mIsActive;						// successfully attached to plugin
+
+	uint32 mSubserviceId;				// subservice ID in use
+	CSSM_SERVICE_TYPE mSubserviceType;	// service type
+	
+	// how we were created
+	CSSM_VERSION mVersion;				// plugin version requested
+	CSSM_ATTACH_FLAGS mAttachFlags;		// attach flags requested
+	CSSM_KEY_HIERARCHY mKeyHierarchy;	// key hierarchy verified
+
+protected:
+	CSSM_MODULE_FUNCS *spiFunctionTable; // entry table as returned by plugin on attach
+
+private:
+	CSSM_UPCALLS upcalls;				// upcall functions for our module
+
+	// upcall implementors - these are handed to the plugin in `upcalls'
+	static void *upcallMalloc(CSSM_HANDLE handle, uint32 size);
+	static void upcallFree(CSSM_HANDLE handle, void *mem);
+	static void *upcallRealloc(CSSM_HANDLE handle, void *mem,uint32 size);
+	static void *upcallCalloc(CSSM_HANDLE handle, uint32 num, uint32 size);
+	static CSSM_RETURN upcallCcToHandle(CSSM_CC_HANDLE handle, CSSM_MODULE_HANDLE *modHandle);
+	static CSSM_RETURN upcallGetModuleInfo(CSSM_MODULE_HANDLE Module,
+										CSSM_GUID_PTR Guid,
+										CSSM_VERSION_PTR Version,
+										uint32 *SubServiceId,
+										CSSM_SERVICE_TYPE *SubServiceType,
+										CSSM_ATTACH_FLAGS *AttachFlags,
+										CSSM_KEY_HIERARCHY *KeyHierarchy,
+										CSSM_API_MEMORY_FUNCS_PTR AttachedMemFuncs,
+										CSSM_FUNC_NAME_ADDR_PTR FunctionTable,
+										uint32 NumFunctions);
+};
+
+// this should be a member template, but egcs barfs on its invocation
+// @@@ pass module code in to get better "invalid handle" diag?
+// @@@ or use template specializations here?
+template <class AttachmentSubclass>
+inline AttachmentSubclass &enterAttachment(CSSM_HANDLE h)
+{
+	AttachmentSubclass &attachment = findHandleAndLock<AttachmentSubclass>(h);
+	attachment.finishEnter();
+	return attachment;
+}
+
+
+//
+// For the standard attachment types, function dispatch to the plugin
+// is done based on the CSSM_SPI_xxx_FUNCS structures describing the
+// types and ordering of entry points. The StandardAttachment class
+// implements this by holding a copy of these tables for the use of
+// the transition layer.
+// You are free to subclass from Attachment directly if that makes better
+// sense to your kind of plugin.
+//
+template <CSSM_SERVICE_TYPE type, class FunctionTable>
+class StandardAttachment : public Attachment {
+public:
+	typedef map<const char *, unsigned int> NameMap;
+
+	StandardAttachment(Module *theModule,
+					const NameMap &names,
+					const CSSM_VERSION &version,
+					uint32 subserviceId,
+					CSSM_SERVICE_TYPE subserviceType,
+					const CSSM_API_MEMORY_FUNCS &memoryOps,
+					CSSM_ATTACH_FLAGS attachFlags,
+					CSSM_KEY_HIERARCHY keyHierarchy)
+		: Attachment(theModule, version, subserviceId, subserviceType,
+					memoryOps, attachFlags, keyHierarchy),
+		nameMap(names)
+	{
+			try {
+				if (spiFunctionTable->NumberOfServiceFuncs <
+					sizeof(FunctionTable) / sizeof(CSSM_PROC_ADDR))
+					CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE);
+				// tolerate a table that's TOO large - perhaps it's a newer version
+				// @@@ with the new spec, we could just store the pointer
+				memcpy(&downcalls, spiFunctionTable->ServiceFuncs, sizeof(downcalls));
+			} catch (...) {
+				// we are attached to the plugin, so tell it the show is off
+				detach(false);
+				throw;
+			}
+	}
+
+	void resolveSymbols(CSSM_FUNC_NAME_ADDR *inFunctionTable,
+								uint32 NumFunctions)
+	{
+		for (unsigned n = 0; n < NumFunctions; n++) {
+			NameMap::const_iterator it = nameMap.find(inFunctionTable[n].Name);
+			inFunctionTable[n].Address =
+				(it == nameMap.end()) ? NULL : downcallNumber(it->second);
+		}
+	}
+
+	FunctionTable downcalls;
+
+	CSSM_PROC_ADDR downcallNumber(uint32 index) const
+	{
+		assert(index < sizeof(downcalls) / sizeof(CSSM_PROC_ADDR));
+		return reinterpret_cast<const CSSM_PROC_ADDR *>(&downcalls)[index];
+	}
+	
+private:
+	const NameMap &nameMap;
+};
+
+#ifdef _CPP_ATTACHMENT
+# pragma export off
+#endif
+
+
+#endif //_H_ATTACHMENT
diff --git a/cdsa/cssm/builtin_modules.cpp b/cdsa/cssm/builtin_modules.cpp
new file mode 100644
index 00000000..aaeccf31
--- /dev/null
+++ b/cdsa/cssm/builtin_modules.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+
+//
+//  builtin_modules.cpp
+//  Security
+//
+//  Created by michael on Tue Mar 13 2001.
+//  Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+//
+
+#include <Security/cssmspi.h>
+#include <Security/pluginspi.h>
+
+CSSM_SPI_MODULE_DECLARATION(AppleCSP);
+CSSM_SPI_MODULE_DECLARATION(AppleCSPDL);
+CSSM_SPI_MODULE_DECLARATION(AppleFileDL);
+CSSM_SPI_MODULE_DECLARATION(AppleX509CL);
+CSSM_SPI_MODULE_DECLARATION(AppleX509TP);
+
+static void reference()
+{
+    AppleCSPCSSM_SPI_ModuleLoad(NULL, NULL, NULL, NULL);
+    AppleCSPDLCSSM_SPI_ModuleLoad(NULL, NULL, NULL, NULL);
+    AppleFileDLCSSM_SPI_ModuleLoad(NULL, NULL, NULL, NULL);
+    AppleX509CLCSSM_SPI_ModuleLoad(NULL, NULL, NULL, NULL);
+    AppleX509TPCSSM_SPI_ModuleLoad(NULL, NULL, NULL, NULL);
+}
diff --git a/cdsa/cssm/cspattachment.cpp b/cdsa/cssm/cspattachment.cpp
new file mode 100644
index 00000000..46a1d63e
--- /dev/null
+++ b/cdsa/cssm/cspattachment.cpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+
+//
+// cspattachment - cryptographic plugin attachment type
+//
+#ifdef __MWERKS__
+#define _CPP_CSPATTACHMENT
+#endif
+#include "cspattachment.h"
diff --git a/cdsa/cssm/cspattachment.h b/cdsa/cssm/cspattachment.h
new file mode 100644
index 00000000..1cf24924
--- /dev/null
+++ b/cdsa/cssm/cspattachment.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+
+//
+// cspattachment - cryptographic plugin attachment type
+//
+#ifndef _H_CSPATTACHMENT
+#define _H_CSPATTACHMENT
+
+#include "attachment.h"
+#include <Security/cssmcspi.h>
+
+#ifdef _CPP_CSPATTACHMENT
+# pragma export on
+#endif
+
+
+typedef StandardAttachment<CSSM_SERVICE_CSP, CSSM_SPI_CSP_FUNCS> CSPAttachment;
+
+#ifdef _CPP_CSPATTACHMENT
+# pragma export off
+#endif
+
+#endif  //_H_CSPATTACHMENT
diff --git a/cdsa/cssm/cssm.cpp b/cdsa/cssm/cssm.cpp
new file mode 100644
index 00000000..b052225b
--- /dev/null
+++ b/cdsa/cssm/cssm.cpp
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+
+
+//
+// This file contains the core CSSM public functions.
+// Note that hardly anything happens in here; we just hand off requests
+// to the various objects representing CSSM state.
+//
+#include "manager.h"
+#include "module.h"
+#include <Security/globalizer.h>
+
+
+//
+// We currently use exactly one instance of CssmManager.
+//
+static ModuleNexus<CssmManager> gManager;
+
+
+//
+// Public API: (Re)Intiailize CSSM
+//
+CSSM_RETURN CSSMAPI
+CSSM_Init (const CSSM_VERSION *Version,
+           CSSM_PRIVILEGE_SCOPE Scope,
+           const CSSM_GUID *CallerGuid,
+           CSSM_KEY_HIERARCHY KeyHierarchy,
+           CSSM_PVC_MODE *PvcPolicy,
+           const void *)
+{
+    BEGIN_API
+    gManager().initialize(Required(Version),
+                        Scope,
+                        Guid::required(CallerGuid),
+                        KeyHierarchy,
+                        Required(PvcPolicy));
+    END_API(CSSM)
+}
+
+
+//
+// Public API: Terminate CSSM.
+//
+CSSM_RETURN CSSMAPI
+CSSM_Terminate (void)
+{
+    BEGIN_API
+    gManager().terminate();
+    END_API(CSSM)
+}
+
+
+//
+// Public API: Load a CSSM module
+//
+CSSM_RETURN CSSMAPI
+CSSM_ModuleLoad (const CSSM_GUID *ModuleGuid,
+                 CSSM_KEY_HIERARCHY KeyHierarchy,
+                 CSSM_API_ModuleEventHandler AppNotifyCallback,
+                 void *AppNotifyCallbackCtx)
+{
+    BEGIN_API
+    gManager().loadModule(Guid::required(ModuleGuid),
+                            KeyHierarchy,
+                            ModuleCallback(AppNotifyCallback, AppNotifyCallbackCtx));
+    END_API(CSSM)
+}
+
+
+//
+// Public API: Unload a module
+//
+CSSM_RETURN CSSMAPI
+CSSM_ModuleUnload (const CSSM_GUID *ModuleGuid,
+                   CSSM_API_ModuleEventHandler AppNotifyCallback,
+                   void *AppNotifyCallbackCtx)
+{
+    BEGIN_API
+    gManager().unloadModule(Guid::required(ModuleGuid),
+                              ModuleCallback(AppNotifyCallback, AppNotifyCallbackCtx));
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_Introduce (const CSSM_GUID *ModuleID,
+                CSSM_KEY_HIERARCHY KeyHierarchy)
+{
+    BEGIN_API
+    gManager().introduce(Guid::required(ModuleID), KeyHierarchy);
+    END_API(CSSM)
+}
+
+CSSM_RETURN CSSMAPI
+CSSM_Unintroduce (const CSSM_GUID *ModuleID)
+{
+    BEGIN_API
+    gManager().unIntroduce(Guid::required(ModuleID));
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_ModuleAttach (const CSSM_GUID *ModuleGuid,
+                   const CSSM_VERSION *Version,
+                   const CSSM_API_MEMORY_FUNCS *MemoryFuncs,
+                   uint32 SubserviceID,
+                   CSSM_SERVICE_TYPE SubServiceType,
+                   CSSM_ATTACH_FLAGS AttachFlags,
+                   CSSM_KEY_HIERARCHY KeyHierarchy,
+                   CSSM_FUNC_NAME_ADDR *FunctionTable,
+                   uint32 NumFunctionTable,
+                   const void *,
+                   CSSM_MODULE_HANDLE_PTR NewModuleHandle)
+{
+    BEGIN_API
+    Required(NewModuleHandle) = gManager().getModule(Guid::required(ModuleGuid))->attach(
+                                  Required(Version),
+                                  SubserviceID, SubServiceType,
+                                  Required(MemoryFuncs),
+                                  AttachFlags,
+                                  KeyHierarchy,
+                                  FunctionTable, NumFunctionTable
+                                  );
+    END_API(CSSM)
+}
+
+CSSM_RETURN CSSMAPI
+CSSM_ModuleDetach (CSSM_MODULE_HANDLE ModuleHandle)
+{
+    BEGIN_API
+    Attachment *attachment = &killHandle<Attachment>(ModuleHandle);
+    attachment->detach(true);		// expect locked, will unlock
+    // the attachment is now off the maps, known idle, and unhooked
+    delete attachment;
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_SetPrivilege (CSSM_PRIVILEGE Privilege)
+{
+    BEGIN_API
+    gManager().setPrivilege(Privilege);
+    END_API(CSSM)
+}
+
+CSSM_RETURN CSSMAPI
+CSSM_GetPrivilege (CSSM_PRIVILEGE *Privilege)
+{
+    BEGIN_API
+    Required(Privilege) = gManager().getPrivilege();
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_GetModuleGUIDFromHandle (CSSM_MODULE_HANDLE ModuleHandle,
+                              CSSM_GUID_PTR ModuleGUID)
+{
+    BEGIN_API
+    Attachment &attachment = findHandleAndLock<Attachment>(ModuleHandle);
+    StLock<Mutex> _(attachment, true);
+    Required(ModuleGUID) = attachment.module.myGuid();
+    END_API(CSSM)
+}
+
+CSSM_RETURN CSSMAPI
+CSSM_GetSubserviceUIDFromHandle (CSSM_MODULE_HANDLE ModuleHandle,
+                                 CSSM_SUBSERVICE_UID_PTR SubserviceUID)
+{
+    BEGIN_API
+    Attachment &attachment = findHandleAndLock<Attachment>(ModuleHandle);
+    StLock<Mutex> _(attachment, true);
+    CSSM_SUBSERVICE_UID &result =  Required(SubserviceUID);
+    result.Guid = attachment.module.myGuid();
+    result.Version = attachment.pluginVersion();
+    result.SubserviceId = attachment.subserviceId();
+    result.SubserviceType = attachment.subserviceType();
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_ListAttachedModuleManagers (uint32 *NumberOfModuleManagers,
+                                 CSSM_GUID_PTR)
+{
+    BEGIN_API
+    *NumberOfModuleManagers = 0;    // EMMs not implemented
+    END_API(CSSM)
+}
+
+CSSM_RETURN CSSMAPI
+CSSM_GetAPIMemoryFunctions (CSSM_MODULE_HANDLE AddInHandle,
+                            CSSM_API_MEMORY_FUNCS_PTR AppMemoryFuncs)
+{
+    BEGIN_API
+    Attachment &attachment = findHandleAndLock<Attachment>(AddInHandle);
+    StLock<Mutex> _(attachment, true);
+    Required(AppMemoryFuncs) = attachment;
+    END_API(CSSM)
+}
diff --git a/cdsa/cssm/cssmcontext.cpp b/cdsa/cssm/cssmcontext.cpp
new file mode 100644
index 00000000..3d35d4b8
--- /dev/null
+++ b/cdsa/cssm/cssmcontext.cpp
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+
+//
+// context - manage CSSM (cryptographic) contexts every which way.
+//
+// A note on memory management:
+// Context attributes are allocated from application memory in big chunks comprising
+// many attributes as well as the attribute array itself. The CSSM_CONTEXT fields
+// NumberOfAttributes and ContextAttributes are handled as a group. Context::Builder
+// and Context::copyFrom assume these fields are undefined and fill them. Context::clear
+// assumes they are valid and invalides them, freeing memory.
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMCONTEXT
+#endif
+#include "cssmcontext.h"
+
+
+//
+// Destroy a HandleContext.
+//
+HandleContext::~HandleContext()
+{
+	attachment.free(extent);
+	attachment.free(ContextAttributes);
+}
+
+
+//
+// Locking protocol for HandleContexts
+//
+void HandleContext::lock()
+{ attachment.enter(); }
+
+bool HandleContext::tryLock()
+{ return attachment.tryEnter(); }
+
+
+//
+// Merge a new set of attributes into an existing HandleContext, copying
+// the new values deeply while releasing corresponding old values.
+//
+// NOTE: This is a HandleContext method; it does not work on bare Contexts.
+//
+void HandleContext::mergeAttributes(const CSSM_CONTEXT_ATTRIBUTE *attributes, uint32 count)
+{
+	// attempt to fast-path some simple or frequent cases
+	if (count == 1) {
+		if (Attr *attr = find(attributes[0].AttributeType)) {
+			if (attr->baseType() == CSSM_ATTRIBUTE_DATA_UINT32) {
+				// try quick replacement
+				Attr oldAttr = *attr;
+				*attr = attributes[0];
+				if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
+					// roll back and fail
+					*attr = oldAttr;
+					CssmError::throwMe(err);
+				}
+				return;	// all done
+			} else {
+				// pointer value - does it fit into the space of the current value?
+				size_t oldSize = size(*attr);
+				size_t newSize = size(attributes[0]);
+                Attr oldAttr = *attr;
+				if (newSize <= oldSize) {	// give it a try...
+					*attr = attributes[0];
+					// NOTE that the CSP is getting a "temporary" pointer set to validate;
+					// If we commit, the final copy will be elsewhere. CSP writer beware!
+					if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
+						// roll back and fail
+						*attr = oldAttr;
+						CssmError::throwMe(err);
+					}
+					// commit new value
+					CopyWalker copier(oldAttr.Attribute.String);
+					walk(copier, *attr);
+					return;
+				}
+			}
+		} else {	// single change, new attribute
+			if (Attr *slot = find(CSSM_ATTRIBUTE_NONE)) {
+				const Attr *attr = static_cast<const Attr *>(&attributes[0]);
+				if (attr->baseType() == CSSM_ATTRIBUTE_DATA_UINT32) {	// trivial
+					Attr oldSlot = *slot;
+					*slot = *attr;
+					if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
+						*slot = oldSlot;
+						CssmError::throwMe(err);
+					}
+					// already ok
+					return;
+				} else if (extent == NULL) {	// pointer value, allocate into extent
+					void *data = attachment.malloc(size(*attr));
+					try {
+						Attr oldSlot = *slot;
+						*slot = attributes[0];
+						CopyWalker copier(data);
+						walk(copier, *slot);
+						if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
+							*slot = oldSlot;
+							attachment.free(data);
+							CssmError::throwMe(err);
+						}
+					} catch (...) {
+						attachment.free(data);
+						throw;
+					}
+					extent = data;
+					return;
+				}
+			}
+		}
+	}
+	
+	// slow form: build a new value table and get rid of the old one
+	Context::Builder builder(attachment);
+	for (unsigned n = 0; n < count; n++)
+		builder.setup(attributes[n]);
+	for (unsigned n = 0; n < attributesInUse(); n++)
+		if (!find(ContextAttributes[n].AttributeType, attributes, count))
+			builder.setup(ContextAttributes[n]);
+	builder.make();
+	for (unsigned n = 0; n < count; n++)
+		builder.put(attributes[n]);
+	for (unsigned n = 0; n < attributesInUse(); n++)
+		if (!find(ContextAttributes[n].AttributeType, attributes, count))
+			builder.put(ContextAttributes[n]);
+			
+	// Carefully, now! The CSP may yet tell us to back out.
+	// First, save the old values...
+	CSSM_CONTEXT_ATTRIBUTE *oldAttributes = ContextAttributes;
+	uint32 oldCount = NumberOfAttributes;
+	
+	// ...install new blob into the context...
+	builder.done(ContextAttributes, NumberOfAttributes);
+	
+	// ...and ask the CSP whether this is okay
+	if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
+		// CSP refused; put everything back where it belongs
+		attachment.free(ContextAttributes);
+		ContextAttributes = oldAttributes;
+		NumberOfAttributes = oldCount;
+		CssmError::throwMe(err);
+	}
+	
+	// we succeeded, so NOW delete the old attributes blob
+	attachment.free(oldAttributes);
+}
+
+
+//
+// Ask the CSP to validate a proposed (and already implemented) change
+//
+CSSM_RETURN HandleContext::validateChange(CSSM_CONTEXT_EVENT event)
+{
+	// lock down the module if it is not thread-safe
+	StLock<Module, &Module::safeLock, &Module::safeUnlock> _(attachment.module);
+	return attachment.downcalls.EventNotify(attachment.handle(),
+		event, handle(), this);
+}
+
+
+//
+// Wrap up a deluxe context creation operation and return the new CC handle.
+//
+CSSM_CC_HANDLE HandleContext::Maker::operator () (CSSM_CONTEXT_TYPE type,
+												CSSM_ALGORITHMS algorithm)
+{
+	// construct the HandleContext object
+	HandleContext &context = *new(attachment) HandleContext(attachment, type, algorithm);
+	context.CSPHandle = attachment.handle();
+	done(context.ContextAttributes, context.NumberOfAttributes);
+	
+	// ask the CSP for consent
+	if (CSSM_RETURN err = context.validateChange(CSSM_CONTEXT_EVENT_CREATE)) {
+		// CSP refused; clean up and fail
+		context.destroy(&context, context.attachment);
+		CssmError::throwMe(err);
+	}
+	
+	// return the new handle (we have succeeded)
+	return context.handle();
+}
diff --git a/cdsa/cssm/cssmcontext.h b/cdsa/cssm/cssmcontext.h
new file mode 100644
index 00000000..68e97d91
--- /dev/null
+++ b/cdsa/cssm/cssmcontext.h
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+
+//
+// context - manage CSSM (cryptographic) contexts every which way
+//
+#ifndef _H_CSSMCONTEXT
+#define _H_CSSMCONTEXT
+
+#include "cssmint.h"
+#include "cspattachment.h"
+#include <Security/context.h>
+
+#ifdef _CPP_CSSMCONTEXT
+# pragma export on
+#endif
+
+
+//
+// A HandleContext adds handle semantics to the Context object.
+// Note that not every Context is a HandleContext - the Contexts we hand
+// to our API customers for fondling are not. Also note that a HandleContext
+// not a PODWrapper.
+// HandleContext has an allocation method taking a CssmAllocator. To destroy
+// a HandleObject, call HandleObject::destroy(the-context, the-allocator).
+// You are responsible for picking the same allocator used on construction.
+//
+// THREADS: HandleContexts are assumed to have single-thread use. That means that
+// operations on HandleContexts are NOT interlocked automatically; two users of
+// the same context must do any arbitration themselves. A HandleContext is howerver
+// safely interlocked against other objects, in particular its CSPAttachment.
+// The upshot is that you're safe using a HandleContext unless someone else is trying
+// to use the same context in parallel.
+//
+class HandleContext : public HandleObject, public Context {
+public:
+    HandleContext(CSPAttachment &attach,
+                  CSSM_CONTEXT_TYPE type,
+                  CSSM_ALGORITHMS algorithmId)
+    : Context(type, algorithmId), attachment(attach), extent(0) { }
+    virtual ~HandleContext();
+
+    CSPAttachment &attachment;
+
+    void mergeAttributes(const CSSM_CONTEXT_ATTRIBUTE *attributes, uint32 count);
+    CSSM_RETURN validateChange(CSSM_CONTEXT_EVENT event);
+
+    void *operator new (size_t size, CssmAllocator &alloc)
+    { return alloc.malloc(size); }
+    void operator delete (void *addr, size_t, CssmAllocator &alloc)
+    { return alloc.free(addr); }
+    static void destroy(HandleContext *context, CssmAllocator &alloc)
+    { context->~HandleContext(); alloc.free(context); }
+
+    class Maker;	// deluxe builder
+
+protected:
+    // Locking protocol, courtesy of HandleObject.
+    // This locks the underlying attachment.
+    void lock();
+    bool tryLock();
+
+private:
+    void *extent;			// extra storage extent in use
+};
+
+inline HandleContext &enterContext(CSSM_CC_HANDLE h)
+{
+    return findHandleAndLock<HandleContext>(h, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+}
+
+
+//
+// A Maker is a deluxe wrapper around Builder. It creates whole HandleContext
+// objects in one swell foop, handling object locking, construction, error
+// recovery, and all that jazz. A Maker cannot create plain Context objects.
+//
+class HandleContext::Maker : public Context::Builder {
+public:
+    Maker(CSSM_CSP_HANDLE handle) 
+		: Context::Builder(findHandleAndLock<CSPAttachment>(handle, CSSM_ERRCODE_INVALID_CSP_HANDLE)),
+		attachment(static_cast<CSPAttachment &>(allocator)), // order dependency(!)
+		locker(attachment, true)
+	{ attachment.finishEnter(); }
+
+    CSPAttachment &attachment;
+
+    CSSM_CC_HANDLE operator () (CSSM_CONTEXT_TYPE type,
+                                CSSM_ALGORITHMS algorithm);
+								
+private:
+	StLock<CountingMutex, &CountingMutex::enter, &CountingMutex::exit> locker;
+};
+
+#endif //_H_CSSMCONTEXT
diff --git a/cdsa/cssm/cssmint.h b/cdsa/cssm/cssmint.h
new file mode 100644
index 00000000..faf16e67
--- /dev/null
+++ b/cdsa/cssm/cssmint.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmint - cssm combined internal headers
+//
+#ifndef _H_CSSMINT
+#define _H_CSSMINT
+
+#include <Security/cssm.h>
+#include <Security/cssmspi.h>
+#include <Security/utilities.h>
+#include <Security/cssmalloc.h>
+#include <Security/threading.h>
+
+
+//
+// Forward types
+//
+class CssmManager;
+class Module;
+class Attachment;
+
+
+//
+// Typedefs for fixed SPI entries
+//
+typedef CSSM_RETURN CSSMSPI
+CSSM_SPI_ModuleLoadFunction (const CSSM_GUID *CssmGuid,
+                             const CSSM_GUID *ModuleGuid,
+                             CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+                             void *CssmNotifyCallbackCtx);
+
+typedef CSSM_RETURN CSSMSPI
+CSSM_SPI_ModuleUnloadFunction (const CSSM_GUID *CssmGuid,
+                               const CSSM_GUID *ModuleGuid,
+                               CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+                               void *CssmNotifyCallbackCtx);
+
+typedef CSSM_RETURN CSSMSPI
+CSSM_SPI_ModuleAttachFunction (const CSSM_GUID *ModuleGuid,
+                               const CSSM_VERSION *Version,
+                               uint32 SubserviceID,
+                               CSSM_SERVICE_TYPE SubServiceType,
+                               CSSM_ATTACH_FLAGS AttachFlags,
+                               CSSM_MODULE_HANDLE ModuleHandle,
+                               CSSM_KEY_HIERARCHY KeyHierarchy,
+                               const CSSM_GUID *CssmGuid,
+                               const CSSM_GUID *ModuleManagerGuid,
+                               const CSSM_GUID *CallerGuid,
+                               const CSSM_UPCALLS *Upcalls,
+                               CSSM_MODULE_FUNCS_PTR *FuncTbl);
+
+typedef CSSM_RETURN CSSMSPI
+CSSM_SPI_ModuleDetachFunction (CSSM_MODULE_HANDLE ModuleHandle);
+
+
+
+#endif //_H_CSSMINT
diff --git a/cdsa/cssm/cssmmds.cpp b/cdsa/cssm/cssmmds.cpp
new file mode 100644
index 00000000..0b616ed0
--- /dev/null
+++ b/cdsa/cssm/cssmmds.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmmds - MDS interface for CSSM & friends  
+//
+#ifdef __MWERKS__
+#define _CPP_CSSMMDS
+#endif
+#include "cssmmds.h"
+
+
+ModuleNexus<MdsComponent::MDS> MdsComponent::mds;
+
+
+MdsComponent::MdsComponent(const Guid &guid) : mMyGuid(guid)
+{
+    mIsValid = false;
+}
+
+MdsComponent::~MdsComponent()
+{
+}
+
+
+void MdsComponent::getInfo() const
+{
+    rewind(mds().config);
+    char buffer[1024];
+    while (fgets(buffer, sizeof(buffer), mds().config)) {
+		static const char space[] = " \t\f";
+		char *p = buffer + strspn(buffer, space);
+		if (*p == '#' || *p == '\0' || *p == '\n')
+			continue;	// comment or blank line
+			
+		// field 1: guid
+		const char *guid = p; p += strcspn(p, space);
+		if (!*p) CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
+		*p++ = '\0';
+		try {
+			if (Guid(guid) != mMyGuid)
+				continue;	// no match this line
+		} catch (CssmCommonError &error) {
+			if (error.cssmError() == CSSM_ERRCODE_INVALID_GUID)
+				CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);	// invalid file guid => MDS error
+			throw;	// pass all other errors
+		}
+		
+		// field 2: flags/options
+		p += strspn(p, space);
+		mServices = 0;
+		mIsThreadSafe = false;
+		while (*p && !isspace(*p)) {
+			switch (*p) {
+			case 'a':	mServices |= CSSM_SERVICE_AC; break;
+			case 'c':	mServices |= CSSM_SERVICE_CSP; break;
+			case 'd':	mServices |= CSSM_SERVICE_DL; break;
+			case 'C':	mServices |= CSSM_SERVICE_CL; break;
+			case 't':	mServices |= CSSM_SERVICE_TP; break;
+			case 'm':	mIsThreadSafe = true; break;
+			default:
+				CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
+			}
+			p++;
+		}
+		if (!*p) CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
+		p += strspn(p, space);	// skip space
+		p[strlen(p)-1] = '\0';	// remove trailing newline
+		mPath = p;				// rest of line is pathname, uninterpreted
+        mIsValid = true;
+        return;
+    }
+    // not found in file
+    CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID);	// @@@ should have "guid not found" error
+}
+
+
+#if !defined(_MDS_PATH)
+# define _MDS_PATH "/System/Library/Frameworks/Security.framework/Resources/MDS"
+#endif
+
+MdsComponent::MDS::MDS()
+{
+    const char *path = getenv("MDSPATH");
+	if (path == NULL)
+			path = getenv("MDSFILE");
+    if (path == NULL)
+        path = _MDS_PATH;
+    if (!(config = fopen(path, "r")))
+        CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
+}
+
+MdsComponent::MDS::~MDS()
+{
+    fclose(config);
+}
diff --git a/cdsa/cssm/cssmmds.h b/cdsa/cssm/cssmmds.h
new file mode 100644
index 00000000..c4274c43
--- /dev/null
+++ b/cdsa/cssm/cssmmds.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssmmds - MDS interface for CSSM & friends
+//
+#ifndef _H_CSSMMDS
+#define _H_CSSMMDS
+
+#include "cssmint.h"
+#include <Security/globalizer.h>
+#include <string>
+#include <stdio.h>	// @@@ for temporary MDS interface only
+
+#ifdef _CPP_CSSMMDS
+# pragma export on
+#endif
+
+
+class MdsComponent {
+public:
+    MdsComponent(const Guid &guid);
+    virtual ~MdsComponent();
+
+    const Guid &myGuid() const { return mMyGuid; }
+    
+    CSSM_SERVICE_MASK services() const { update(); return mServices; }
+    bool supportsService(CSSM_SERVICE_TYPE t) const { update(); return t & mServices; }
+    bool isThreadSafe() const { update(); return mIsThreadSafe; }
+    const char *path() const { update(); return mPath.c_str(); }
+
+private:
+    const Guid mMyGuid;					// GUID of the component
+
+    // information obtained about the component
+    mutable bool mIsValid;				// information is valid
+    mutable string mPath;			// module location
+    mutable CSSM_SERVICE_TYPE mServices; // service types provided
+    mutable bool mIsThreadSafe;			// is the module thread safe?
+
+    void getInfo() const;  				// retrieve MDS information
+    void update() const { if (!mIsValid) getInfo(); }
+
+private:
+    struct MDS {
+        MDS();
+        ~MDS();
+        FILE *config;
+    };
+    static ModuleNexus<MDS> mds;
+};
+
+#ifdef _CPP_CSSMMDS
+# pragma export off
+#endif
+
+
+#endif //_H_CSSMMDS
diff --git a/cdsa/cssm/generator.cfg b/cdsa/cssm/generator.cfg
new file mode 100644
index 00000000..8ec67fa2
--- /dev/null
+++ b/cdsa/cssm/generator.cfg
@@ -0,0 +1,13 @@
+#
+# transition.cfg
+#
+# Configuration file for generating the CSSM API/SPI transition layer.
+#
+
+
+#
+# Functions with irregular operation that need hand-coded implementations
+#
+CSSM_DigestDataClone			custom
+CSSM_QueryKeySizeInBits			custom
+CSSM_GenerateAlgorithmParams 	custom
diff --git a/cdsa/cssm/generator.mk b/cdsa/cssm/generator.mk
new file mode 100644
index 00000000..ff2cfe8e
--- /dev/null
+++ b/cdsa/cssm/generator.mk
@@ -0,0 +1,26 @@
+# Makefile for generated files.
+
+PERL=/usr/bin/perl
+
+CDSA_HEADERS_DIR = Headers/cdsa
+CDSA_SOURCES_DIR = Sources/cdsa
+
+GEN_APIGLUE = $(CDSA_SOURCES_DIR)/generator.pl
+APIGLUE_GEN = $(patsubst %,$(CDSA_SOURCES_DIR)/%,transition.gen funcnames.gen generator.rpt)
+APIGLUE_DEPENDS = $(patsubst %,$(CDSA_SOURCES_DIR)/%, generator.pl generator.cfg)\
+				  $(patsubst %,$(CDSA_HEADERS_DIR)/%,cssmapi.h cssmtype.h cssmconfig.h cssmaci.h cssmcspi.h cssmdli.h cssmcli.h cssmtpi.h)
+
+build: $(APIGLUE_GEN)
+
+clean:
+	rm -f $(APIGLUE_GEN)
+
+debug: build
+
+profile: build
+
+.PHONY: build clean debug profile
+
+$(APIGLUE_GEN): $(APIGLUE_DEPENDS)
+	(cd $(CDSA_SOURCES_DIR);\
+	  $(PERL) ./generator.pl ../../$(CDSA_HEADERS_DIR) .)
diff --git a/cdsa/cssm/generator.pl b/cdsa/cssm/generator.pl
new file mode 100644
index 00000000..323a04dc
--- /dev/null
+++ b/cdsa/cssm/generator.pl
@@ -0,0 +1,228 @@
+#!/usr/bin/perl
+#
+# generator.pl - derive various and sundry C++ code from the CDSA header files
+#
+# Usage:
+#	perl generator.pl input-directory output-directory
+#
+# Perry The Cynic, Fall 1999.
+#
+@API_H=("cssmapi.h");
+%SPI_H=("AC" => "cssmaci.h", "CSP" => "cssmcspi.h", "DL" => "cssmdli.h",
+        "CL" => "cssmcli.h", "TP"  => "cssmtpi.h");
+@OIDS_H=("oidscert.h", "oidscrl.h", "oidsattr.h", "oidsalg.h");
+
+$SOURCEDIR=$ARGV[0];		# directory with inputs
+
+(${D}) = $SOURCEDIR =~ m@([/:])@;		# guess directory delimiter
+sub macintosh() { return ${D} eq ':'; }
+
+# XXX The configuration file should be passed in as a command line argument
+if( macintosh() ){
+  $TARGETDIR=$ARGV[2];					# directory for outputs
+  $APICFG=":::cdsa:cdsa:generator.cfg";				# configuration file
+}
+else{
+  $TARGETDIR=$ARGV[1];					# directory for outputs
+  $APICFG="generator.cfg";		# configuration file 
+}
+
+
+$TRANSITION="$TARGETDIR${D}transition.gen"; # C++ code for transition layer
+$TABLES="$TARGETDIR${D}funcnames.gen";		# function name tables
+$REPORT="$TARGETDIR${D}generator.rpt";		# report file
+$EXPORTS="$TARGETDIR${D}cssmexports.gen";	# Exports file
+
+$tabs = "\t\t\t";	# argument indentation (noncritical)
+$warning = "This file was automatically generated. Do not edit on penalty of futility!";
+
+
+#
+# Parse API headers and extract function names and argument lists
+#
+$/=undef;	# big gulp mode
+foreach $_ (@API_H) {
+  open(API_H, "$SOURCEDIR${D}$_") or die "Cannot open $SOURCEDIR${D}$_: $^E";
+  $_ = <API_H>;		# glglgl... aaaaah
+  tr/\012/\015/ if macintosh;
+  %formals = /CSSM_RETURN CSSMAPI\s*([A-Za-z_]+)\s+\(([^)]*)\);/gs;
+  while (($name, $args) = each %formals) {
+    $args =~ s/^.*[ *]([A-Za-z_]+,?)$/$tabs$1/gm;	# remove type declarators
+    $args =~ s/^$tabs//o;	# chop intial tabs		# so now we have...
+    $actuals{$name} = $args;						# ...an actual argument list
+  };
+};
+close(API_H);
+
+
+#
+# Slurp SPI headers into memory for future use
+#
+$/=undef;	# slurp files
+while (($key, $file) = each %SPI_H) {
+  open(SPI_H, "$SOURCEDIR${D}$file") or die "Cannot open $SOURCEDIR${D}$file: $^E";
+  $spi{$key} = <SPI_H>;
+  $spi{$key} =~ tr/\012/\015/ if macintosh;
+};
+close(SPI_H);
+
+
+#
+# Open and read the configuration file
+#
+$/=undef;	# gulp yet again
+open(APICFG, $APICFG) or die "Cannot open $APICFG: $^E";
+$_=<APICFG>;
+close(APICFG);
+tr/\012/\015/ if macintosh;
+%config = /^\s*(\w+)\s+(.*)$/gm;
+
+
+#
+# Now we will generate the API transition layer.
+# The idea here is that for each function in the API, we try to
+# figure out what type of plugin it belongs to, and then look up
+# its evil twin in that type's header. If that works, we generate
+# a function for the transition, taking care of various oddities
+# and endities in the process.
+#
+open(OUT, ">$TRANSITION") or die "Cannot write $TRANSITION: $^E";
+select OUT;
+open(REPORT, ">$REPORT") or die "Cannot write $REPORT: $^E";
+
+sub ignored {
+  my ($reason) = @_;
+  $ignored++;
+  print REPORT "$name $reason\n";
+};
+
+print "//
+// $warning
+//";
+
+for $name (sort keys %formals) {
+  $config = $config{$name};
+  do { ignored "has custom implementation"; next; } if $config =~ /custom/;
+
+  ($barename) = $name =~ /^CSSM.*_([A-Za-z]+$)/;
+  die "Can't fathom SPI name for $name" unless $barename;
+  $actuals = $actuals{$name};
+
+  # key off the type code in the first argument: CSSM_type_HANDLE
+  ($type, $handle) = $formals{$name} =~ /CSSM_([A-Z_]+)_HANDLE\s+([A-Za-z0-9_]+)/;
+  $type = "CSP" if $type eq "CC";	# CSP methods may have CC (context) handles
+  $type = "DL" if $type eq "DL_DB";	# DL methods may have DL_DB handles
+  $type = "KR" if $type eq "KRSP";	# KR methods have KRSP handles
+  $Type = $type . "Attachment";
+  do { ignored "has no module type"; next; } unless defined $SPI_H{$type};
+
+  # $prefix will hold code to be generated before the actual call
+  $prefix = "";
+
+  # match the SPI; take care of the Privilege variants of some calls
+  ($args) = $spi{$type} =~ /CSSM_RETURN \(CSSM${type}I \*$barename\)\s+\(([^)]*)\);/s
+    or $barename =~ s/P$// &&	# second chance for FooBarP() API functions
+      (($args) = $spi{$type} =~ /CSSM_RETURN \(CSSM${type}I \*$barename\)\s+\(([^)]*)\);/s)
+    or do { ignored "not in $SPI_H{$type}"; next; };
+
+  # take care of CSP calls taking context handles
+  $handletype = $type;
+  $type eq "CSP" && $actuals =~ /CCHandle/ && do {
+    $actuals =~ s/CCHandle/context.CSPHandle, CCHandle/;
+    $args =~ /CSSM_CONTEXT/ &&
+      $actuals =~ s/CCHandle/CCHandle, &context/;
+    $handletype = "CC";
+  };
+
+  # add the default privilege argument to non-P functions taking privileges
+  $args =~ /CSSM_PRIVILEGE/ && ! ($name =~ /P$/) &&			# add privilege argument (last)
+    ($actuals .= ",\n${tabs}attachment.module.cssm.getPrivilege()");
+
+  # finally translate DLDBHandles into their DL component
+  $handle =~ s/DLDBHandle/DLDBHandle.DLHandle/;
+
+  # payoff time
+  print "
+CSSM_RETURN CSSMAPI
+$name ($formals{$name})
+{
+  BEGIN_API";
+  if ($handletype eq "CC") {
+    print "
+  HandleContext &context = enterContext($handle);
+  CSPAttachment &attachment = context.attachment;";
+  } else {
+    print "
+  $Type &attachment = enterAttachment<$Type>($handle);";
+  };
+  print "
+  TransitLock _(attachment);
+  ${prefix}return attachment.downcalls.$barename($actuals);
+  END_API($type)
+}
+";
+  $written++;
+};
+close(OUT);
+select(STDOUT);
+
+
+#
+# Now peruse the SPI headers for a list of function names
+# and build in-memory translation tables for runtime.
+#
+open(OUT, ">$TABLES") or die "Cannot write $TABLES: $^E";
+select OUT;
+
+print "//
+// Standard plugin name tables
+// $warning
+//
+";
+while (($name, $_) = each %spi) {
+  print "extern const char *const ${name}NameTable[] = {";
+  s/^.*struct cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s
+    or die "bad format in $SPI_H{$name}";
+  s/CSSM_RETURN \(CSSM[A-Z]*I \*([A-Za-z_]+)\)\s+\([^)]+\);/\t"$1",/g;
+  print;
+  print "};\n\n";
+};
+close(OUT);
+select(STDOUT);
+
+#
+# Finally, generate linker export file to avoid leaking internal symbols
+#
+open(OUT, ">$EXPORTS") or die "Cannot write $EXPORTS: $^E";
+select(OUT);
+
+# entry point names (functions)
+for $name (keys %formals) {
+  $symbols{$name} = 1;
+};
+
+# OID-related data symbols
+$/=undef;
+foreach $_ (@OIDS_H) {
+  open(OIDS_H, "$SOURCEDIR${D}$_") or die "Cannot open $SOURCEDIR${D}$_: $^E";
+  $_ = <OIDS_H>;		# glglgl... aaaaah
+  tr/\012/\015/ if macintosh;
+  s/\/\*.*\*\///gm;	# remove comments
+  
+  foreach $name (/\s+(CSSMOID_[A-Za-z0-9_]+)/gs) {
+    $symbols{$name} = 1;
+  };
+};
+close(OIDS_H);
+
+foreach $name (keys %symbols) {
+  print "_$name\n";
+};
+
+close(OUT);
+select(STDOUT);
+
+
+close(EXPORTS);
+close(REPORT);
+print "$written API functions generated; $ignored ignored (see $REPORT)\n";
diff --git a/cdsa/cssm/manager.cpp b/cdsa/cssm/manager.cpp
new file mode 100644
index 00000000..7037593d
--- /dev/null
+++ b/cdsa/cssm/manager.cpp
@@ -0,0 +1,206 @@
+/*
+ * 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.
+ */
+
+
+//
+// manager - CSSM manager/supervisor objects.
+//
+#ifdef __MWERKS__
+#define _CPP_MANAGER
+#endif
+#include "manager.h"
+#include "module.h"
+#include <Security/debugging.h>
+//#include <memory>
+
+
+//
+// Constructing a CssmManager instance.
+// This does almost nothing - the actual intialization happens in the initialize() method.
+//
+CssmManager::CssmManager() : MdsComponent(gGuidCssm)
+{
+    initCount = 0;	// not yet initialized
+}
+
+CssmManager::~CssmManager()
+{
+	if (initCount > 0)
+		debug("cssm", "CSSM forcibly shutting down");
+}
+
+
+//
+// CSSM initialization.
+// THREADS: This function must run in an uncontested environment.
+//
+void CssmManager::initialize (const CSSM_VERSION &version,
+                              CSSM_PRIVILEGE_SCOPE scope,
+                              const Guid &callerGuid,
+                              CSSM_KEY_HIERARCHY keyHierarchy,
+                              CSSM_PVC_MODE &pvcPolicy)
+{
+    StLock<Mutex> _(mLock);
+    
+    // check version first
+    checkVersion(version);
+    
+    if (initCount) {
+        // re-initialization processing as per CSSM spec
+        if (pvcPolicy != mPvcPolicy) {
+            pvcPolicy = mPvcPolicy; // return old value
+            CssmError::throwMe(CSSMERR_CSSM_PVC_ALREADY_CONFIGURED);
+        }
+        initCount++;
+        debug("cssm", "re-initializing CSSM (%d levels)", initCount);
+        return;
+    }
+    
+    // we don't support thread scope privileges
+    if (scope == CSSM_PRIVILEGE_SCOPE_THREAD)
+        CssmError::throwMe(CSSMERR_CSSM_SCOPE_NOT_SUPPORTED);
+
+    // keep the init arguments for future use - these become instance constants
+    mPrivilegeScope = scope;
+    mKeyHierarchy = keyHierarchy;
+    mPvcPolicy = pvcPolicy;
+    mCallerGuid = callerGuid;
+
+    // we are ready now
+    initCount = 1;
+    debug("cssm", "CSSM initialized");
+}
+
+
+//
+// CSSM Termination processing.
+// Returns true if this was the final (true) termination, false if a nested Init was undone.
+//
+bool CssmManager::terminate()
+{
+    StLock<Mutex> _(mLock);
+    switch (initCount) {
+    case 0:
+        CssmError::throwMe(CSSMERR_CSSM_NOT_INITIALIZED);
+    case 1:
+        debug("cssm", "Terminating CSSM");
+        if (!moduleMap.empty())
+            CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED);	// @#can't terminate with modules loaded
+        initCount = 0;	// mark uninitialized
+        return true;
+    default:
+        initCount--;	// nested INIT, just count down
+        debug("cssm", "CSSM nested termination (%d remaining)", initCount);
+        return false;
+    }
+}
+
+
+#if defined(RESTRICTED_CSP_LOADING)
+static char *allowedCSPs[] = {
+	"/System/Library/Security/AppleCSP.bundle",
+	"/System/Library/Security/AppleCSPDL.bundle",
+	NULL
+};
+#endif
+
+
+//
+// Load a module (well, try).
+//
+void CssmManager::loadModule(const Guid &guid,
+                             CSSM_KEY_HIERARCHY,
+                             const ModuleCallback &callback)
+{
+    StLock<Mutex> _(mLock);
+    ModuleMap::iterator it = moduleMap.find(guid);
+    Module *module;
+    if (it == moduleMap.end()) {
+        MdsComponent info(guid);
+#if defined(RESTRICTED_CSP_LOADING)
+		// An abominable temporary hack for legal reasons. They made me do it!
+		if (info.supportsService(CSSM_SERVICE_CSP)) {
+			string loadPath = info.path();
+			for (char **pp = allowedCSPs; *pp; pp++)
+				if (loadPath == *pp)
+					goto allowed;
+			CssmError::throwMe(CSSM_ERRCODE_MODULE_MANIFEST_VERIFY_FAILED);
+		  allowed: ;
+		}
+#endif
+        module = new Module(this, info, loader(info.path()));
+        moduleMap[guid] = module;
+    } else {
+        module = it->second;
+	}
+    module->add(callback);
+    //@@@ verify against keyHierarchy
+}
+
+
+//
+// Unload a module.
+// THREADS: Locking Manager(1), Module(2).
+//
+void CssmManager::unloadModule(const Guid &guid,
+                               const ModuleCallback &callback)
+{
+    StLock<Mutex> _(mLock);
+    Module *module = getModule(guid);
+    if (module->unload(callback)) {
+        moduleMap.erase(guid);
+        delete module;
+    }
+}
+
+
+//
+// Introductions
+//
+void CssmManager::introduce(const Guid &,
+                            CSSM_KEY_HIERARCHY)
+{
+    StLock<Mutex> _(mLock);
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void CssmManager::unIntroduce(const Guid &)
+{
+    StLock<Mutex> _(mLock);
+    CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+
+//
+// Support.
+// THREADS: These utilities run under lock protection by the caller.
+//
+void CssmManager::checkVersion(const CSSM_VERSION &version)
+{
+    if (version.Major != 2)
+        CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
+    if (version.Minor != 0)
+        CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
+}
+
+Module *CssmManager::getModule(const Guid &guid)
+{
+    ModuleMap::iterator it = moduleMap.find(guid);
+    if (it == moduleMap.end())
+        CssmError::throwMe(CSSMERR_CSSM_MODULE_NOT_LOADED);
+    return it->second;
+}
diff --git a/cdsa/cssm/manager.h b/cdsa/cssm/manager.h
new file mode 100644
index 00000000..e54acab7
--- /dev/null
+++ b/cdsa/cssm/manager.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+
+//
+// manager - CSSM manager/supervisor objects.
+//
+#ifndef _H_MANAGER
+#define _H_MANAGER
+
+#include <Security/modloader.h>
+#include <Security/callback.h>
+#include "cssmmds.h"
+#include "attachfactory.h"
+
+
+//
+// The CssmManager class embodies one instance of CSSM. It can interact with multiple
+// callers in multiple threads.
+// As far as CssmManager is concerned, it doesn't mind for multiple instances of it to
+// exist. Such instances are strictly separated; they do not share anything (module info,
+// attachments, callbacks, etc.) and live their lives in splendid isolation. Of course,
+// other subsystems they deal with (e.g. the ModuleLoader) may multiplex them, but such
+// components should take pains not to "leak" information from one CssmManager instance
+// to another.
+//
+class CssmManager : public MdsComponent, public AttachmentFactory {
+    NOCOPY(CssmManager)
+    static const CSSM_GUID theGuidForCssmItself;
+public:
+    CssmManager();
+    virtual ~CssmManager();
+    
+    void initialize (const CSSM_VERSION &version,
+                     CSSM_PRIVILEGE_SCOPE scope,
+                     const Guid &callerGuid,
+                     CSSM_KEY_HIERARCHY keyHierarchy,
+                     CSSM_PVC_MODE &pvcPolicy);
+    bool terminate();
+
+    void loadModule (const Guid &guid,
+                     CSSM_KEY_HIERARCHY keyHierarchy,
+                     const ModuleCallback &callback);
+    void unloadModule (const Guid &guid,
+                       const ModuleCallback &callback);
+
+    void introduce(const Guid &guid, CSSM_KEY_HIERARCHY keyHierarchy);
+    void unIntroduce(const Guid &guid);
+
+    //
+    // Polite inquiries
+    //
+
+    // these values are constant (after init time) and need no locking
+    const Guid &callerGuid() const { return mCallerGuid; }
+    CSSM_PRIVILEGE_SCOPE privilegeScope() const { return mPrivilegeScope; }
+    CSSM_KEY_HIERARCHY keyHierarchy() const { return mKeyHierarchy; }
+    CSSM_PVC_MODE pvcMode() const { return mPvcPolicy; }
+
+    //@@@ for these two, consider locking (as of the C shims AND the transition layer use)
+    const CSSM_PRIVILEGE &getPrivilege() const { return mPrivilege; }
+    void setPrivilege(const CSSM_PRIVILEGE &priv) { mPrivilege = priv; }
+
+public:
+    Module *getModule(const Guid &guid);
+
+private:
+    typedef map<Guid, Module *> ModuleMap;
+    ModuleMap moduleMap;
+
+    Mutex mLock;					// object lock
+    unsigned int initCount;			// number of times successfully initialized
+    
+private:
+    ModuleLoader loader;			// our ticket to module land
+
+private:
+    // state acquired from initialize (instance constants - not guarded)
+    CSSM_PRIVILEGE_SCOPE mPrivilegeScope;
+    CSSM_KEY_HIERARCHY mKeyHierarchy;
+    CSSM_PVC_MODE mPvcPolicy;
+    Guid mCallerGuid;
+
+    // persistent state of the CSSM (guarded by module lock)
+    CSSM_PRIVILEGE mPrivilege;		// established privileges
+
+private:
+    void checkVersion(const CSSM_VERSION &version);
+};
+
+#ifdef _CPP_MANAGER
+# pragma export off
+#endif
+
+#endif //_H_MANAGER
diff --git a/cdsa/cssm/modload_plugin.cpp b/cdsa/cssm/modload_plugin.cpp
new file mode 100644
index 00000000..fdf704aa
--- /dev/null
+++ b/cdsa/cssm/modload_plugin.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+
+//
+// modload_plugin - loader interface for dynamically loaded plugin modules
+//
+#include <Security/modload_plugin.h>
+
+
+namespace Security {
+
+
+//
+// During construction, a LoadablePlugin loads itself into memory and locates
+// the canonical (CDSA defined) four entrypoints. If anything fails, we throw.
+//    
+LoadablePlugin::LoadablePlugin(const char *path) : LoadableBundle(path)
+{
+    load();
+    findFunction(fLoad, "CSSM_SPI_ModuleLoad");
+    findFunction(fAttach, "CSSM_SPI_ModuleAttach");
+    findFunction(fDetach, "CSSM_SPI_ModuleDetach");
+    findFunction(fUnload, "CSSM_SPI_ModuleUnload");
+}
+
+
+//
+// Loading and unloading devolves directly onto LoadableBundle
+//
+void LoadablePlugin::load()
+{
+    CodeSigning::LoadableBundle::load();
+}
+
+void LoadablePlugin::unload()
+{
+    CodeSigning::LoadableBundle::unload();
+}
+
+bool LoadablePlugin::isLoaded() const
+{
+    return CodeSigning::LoadableBundle::isLoaded();
+}
+
+
+}	// end namespace Security
diff --git a/cdsa/cssm/modload_plugin.h b/cdsa/cssm/modload_plugin.h
new file mode 100644
index 00000000..54b83eba
--- /dev/null
+++ b/cdsa/cssm/modload_plugin.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+
+//
+// modload_plugin - loader interface for dynamically loaded plugin modules
+//
+#ifndef _H_MODLOAD_PLUGIN
+#define _H_MODLOAD_PLUGIN
+
+#include "modloader.h"
+
+
+namespace Security {
+
+
+//
+// A LoadablePlugin implements itself as a LoadableBundle
+//
+class LoadablePlugin : public Plugin, public CodeSigning::LoadableBundle {
+public:
+    LoadablePlugin(const char *path);
+    
+    void load();
+    void unload();
+    bool isLoaded() const;
+    
+    CSSM_RETURN CSSM_SPI_ModuleLoad (const CSSM_GUID *CssmGuid,
+        const CSSM_GUID *ModuleGuid,
+        CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+        void *CssmNotifyCallbackCtx)
+    { return fLoad(CssmGuid, ModuleGuid, CssmNotifyCallback, CssmNotifyCallbackCtx); }
+
+	CSSM_RETURN CSSM_SPI_ModuleUnload (const CSSM_GUID *CssmGuid,
+        const CSSM_GUID *ModuleGuid,
+        CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+        void *CssmNotifyCallbackCtx)
+    { return fUnload(CssmGuid, ModuleGuid, CssmNotifyCallback, CssmNotifyCallbackCtx); }
+
+	CSSM_RETURN CSSM_SPI_ModuleAttach (const CSSM_GUID *ModuleGuid,
+        const CSSM_VERSION *Version,
+        uint32 SubserviceID,
+        CSSM_SERVICE_TYPE SubServiceType,
+        CSSM_ATTACH_FLAGS AttachFlags,
+        CSSM_MODULE_HANDLE ModuleHandle,
+        CSSM_KEY_HIERARCHY KeyHierarchy,
+        const CSSM_GUID *CssmGuid,
+        const CSSM_GUID *ModuleManagerGuid,
+        const CSSM_GUID *CallerGuid,
+        const CSSM_UPCALLS *Upcalls,
+        CSSM_MODULE_FUNCS_PTR *FuncTbl)
+    {
+        return fAttach(ModuleGuid, Version, SubserviceID, SubServiceType,
+            AttachFlags, ModuleHandle, KeyHierarchy, CssmGuid,
+            ModuleManagerGuid, CallerGuid, Upcalls, FuncTbl);
+    }
+
+	CSSM_RETURN CSSM_SPI_ModuleDetach (CSSM_MODULE_HANDLE ModuleHandle)
+    { return fDetach(ModuleHandle); }
+    
+private:
+    CSSM_SPI_ModuleLoadFunction *fLoad;
+    CSSM_SPI_ModuleAttachFunction *fAttach;
+    CSSM_SPI_ModuleDetachFunction *fDetach;
+    CSSM_SPI_ModuleUnloadFunction *fUnload;
+
+    template <class FunctionType>
+    void findFunction(FunctionType * &func, const char *name)
+    { func = (FunctionType *)lookupSymbol(name); }
+};
+
+
+} // end namespace Security
+
+
+#endif //_H_MODLOAD_PLUGIN
diff --git a/cdsa/cssm/modload_static.cpp b/cdsa/cssm/modload_static.cpp
new file mode 100644
index 00000000..1b88e014
--- /dev/null
+++ b/cdsa/cssm/modload_static.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+
+//
+// modload_static - pseudo-loading of statically linked plugins
+//
+#include <Security/modload_static.h>
+
+
+namespace Security {
+
+
+
+}	// end namespace Security
diff --git a/cdsa/cssm/modload_static.h b/cdsa/cssm/modload_static.h
new file mode 100644
index 00000000..4087b90f
--- /dev/null
+++ b/cdsa/cssm/modload_static.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+
+//
+// modload_static - pseudo-loading of statically linked plugins
+//
+#ifndef _H_MODLOAD_STATIC
+#define _H_MODLOAD_STATIC
+
+#include "modloader.h"
+#include "cssmint.h"
+#include <Security/utilities.h>
+#include <Security/callback.h>
+
+
+namespace Security {
+
+
+template <class PluginClass>
+class StaticPlugin : public Plugin {
+public:    
+    void load()				{ }
+    void unload()			{ }
+    bool isLoaded() const	{ return true; }
+    
+#define SPIPREFIX		/* empty */
+#include <Security/pluginspi.h>
+
+private:
+    PluginClass mPlugin;
+    
+    PluginClass &plugin()		{ return mPlugin; }
+};
+
+
+} // end namespace Security
+
+
+#endif //_H_MODLOAD_STATIC
diff --git a/cdsa/cssm/modloader.cpp b/cdsa/cssm/modloader.cpp
new file mode 100644
index 00000000..e2854330
--- /dev/null
+++ b/cdsa/cssm/modloader.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+
+//
+// cssm module loader interface - MACOS X (CFBundle/DYLD) version.
+//
+// This file provides a C++-style interface to CFBundles as managed by the CF-style
+// system interfaces. The implementation looks a bit, well, hybrid - but the visible
+// interfaces are pure C++.
+//
+#include "modloader.h"
+#include "modload_plugin.h"
+
+#if defined(BUILTIN_PLUGINS)
+# include "modload_static.h"
+# include "AppleCSP/AppleCSP/AppleCSP.h"
+# include "AppleCSPDL/CSPDLPlugin.h"
+# include "AppleDL/AppleFileDL.h"
+# include "AppleX509CL/AppleX509CL.h"
+# include "AppleX509TP/AppleTP.h"
+#endif //BUILTIN_PLUGINS
+
+
+namespace Security {
+
+
+//
+// Construct a ModuleLoader object.
+//
+ModuleLoader::ModuleLoader()
+{
+#if defined(BUILTIN_PLUGINS)
+    mPlugins["*AppleCSP"] = new StaticPlugin<AppleCSPPlugin>;
+    mPlugins["*AppleDL"] = new StaticPlugin<AppleFileDL>;
+    mPlugins["*AppleCSPDL"] = new StaticPlugin<CSPDLPlugin>;
+    mPlugins["*AppleX509CL"] = new StaticPlugin<AppleX509CL>;
+    mPlugins["*AppleX509TP"] = new StaticPlugin<AppleTP>;
+#endif //BUILTIN_PLUGINS
+}
+
+
+//
+// "Load" a plugin, given its MDS path. At this layer, we are performing
+// a purely physical load operation. No code in the plugin is called.
+// If "built-in plugins" are enabled, the moduleTable will come pre-initialized
+// with certain paths. Since we consult this table before going to disk, this
+// means that we'll pick these up first *as long as the paths match exactly*.
+// There is nothing magical in the path strings themselves, other than by
+// convention.
+//
+Plugin *ModuleLoader::operator () (const char *path)
+{
+    Plugin * &plugin = mPlugins[path];
+    if (!plugin)
+        plugin = new LoadablePlugin(path);
+    return plugin;
+}
+
+
+}	// end namespace Security
diff --git a/cdsa/cssm/modloader.h b/cdsa/cssm/modloader.h
new file mode 100644
index 00000000..ff15db0c
--- /dev/null
+++ b/cdsa/cssm/modloader.h
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+
+//
+// modloader.h - CSSM module loader interface
+//
+// This is a thin abstraction of plugin module loading/handling for CSSM.
+// The resulting module ("Plugin") notion is specific to CSSM plugin modules.
+// This implementation uses MacOS X bundles.
+//
+#ifndef _H_MODLOADER
+#define _H_MODLOADER
+
+#include <exception>
+#include <Security/utilities.h>
+#include <Security/osxsigning.h>
+#include <Security/cssmint.h>
+#include <map>
+#include <string>
+
+
+namespace Security {
+
+
+//
+// An abstract representation of a loadable plugin.
+// Note that "loadable" doesn't mean that actual code loading
+// is necessarily happening, but let's just assume it might.
+//
+class Plugin {
+    NOCOPY(Plugin)
+public:
+    Plugin() { }
+    virtual ~Plugin() { }
+
+    virtual void load() = 0;
+    virtual void unload() = 0;
+    virtual bool isLoaded() const = 0;
+    
+    virtual CSSM_RETURN CSSM_SPI_ModuleLoad (const CSSM_GUID *CssmGuid,
+        const CSSM_GUID *ModuleGuid,
+        CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+        void *CssmNotifyCallbackCtx) = 0;
+	virtual CSSM_RETURN CSSM_SPI_ModuleUnload (const CSSM_GUID *CssmGuid,
+        const CSSM_GUID *ModuleGuid,
+        CSSM_SPI_ModuleEventHandler CssmNotifyCallback,
+        void *CssmNotifyCallbackCtx) = 0;
+	virtual CSSM_RETURN CSSM_SPI_ModuleAttach (const CSSM_GUID *ModuleGuid,
+        const CSSM_VERSION *Version,
+        uint32 SubserviceID,
+        CSSM_SERVICE_TYPE SubServiceType,
+        CSSM_ATTACH_FLAGS AttachFlags,
+        CSSM_MODULE_HANDLE ModuleHandle,
+        CSSM_KEY_HIERARCHY KeyHierarchy,
+        const CSSM_GUID *CssmGuid,
+        const CSSM_GUID *ModuleManagerGuid,
+        const CSSM_GUID *CallerGuid,
+        const CSSM_UPCALLS *Upcalls,
+        CSSM_MODULE_FUNCS_PTR *FuncTbl) = 0;
+	virtual CSSM_RETURN CSSM_SPI_ModuleDetach (CSSM_MODULE_HANDLE ModuleHandle) = 0;
+};
+
+
+//
+// The supervisor class that manages searching and loading.
+//
+class ModuleLoader {
+    NOCOPY(ModuleLoader)
+public:
+    ModuleLoader();
+    
+    Plugin *operator () (const char *path);
+        
+private:
+    // the table of all loaded modules
+    typedef map<string, Plugin *> PluginTable;
+    PluginTable mPlugins;
+};
+
+
+
+} // end namespace Security
+
+
+#endif //_H_MODLOADER
diff --git a/cdsa/cssm/module.cpp b/cdsa/cssm/module.cpp
new file mode 100644
index 00000000..24751fe4
--- /dev/null
+++ b/cdsa/cssm/module.cpp
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+
+//
+// module - CSSM Module objects
+//
+#include "module.h"
+#include "manager.h"
+#include "attachment.h"
+
+
+//
+// Module object construction.
+//
+Module::Module(CssmManager *mgr, const MdsComponent &info, Plugin *plug)
+: MdsComponent(info), cssm(*mgr), plugin(plug)
+{
+    // invoke module's load entry (tell it it's being loaded)
+    if (CSSM_RETURN err = plugin->CSSM_SPI_ModuleLoad(&cssm.myGuid(), // CSSM's Guid
+            &myGuid(),			// module's Guid
+            spiEventRelay, this)) {
+        plugin->unload();
+        CssmError::throwMe(err);	// self-destruct this module
+    }
+}
+
+
+//
+// Destroy the module object.
+// The unload() method must have succeeded and returned true before
+// you get to delete a Module. A destructor is too precarious a place
+// to negotiate with a plugin...
+//
+Module::~Module()
+{
+}
+
+
+bool Module::unload(const ModuleCallback &callback)
+{
+    StLock<Mutex> _(mLock);
+    // locked module - no more attachment creations possible
+    if (callbackCount() == 1) {
+        // would be last callback if successful, check for actual unload
+        if (attachmentCount() > 0)
+            CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED);	// @# module is busy
+        // no attachments active - we are idle and ready to unload
+        if (CSSM_RETURN err = plugin->CSSM_SPI_ModuleUnload(&cssm.myGuid(), // CSSM's Guid
+                &myGuid(),		// module's Guid
+                spiEventRelay, this)) // our callback
+            CssmError::throwMe(err);	// tough...
+        // okay, commit
+        remove(callback);
+        plugin->unload();
+        return true;
+    } else {
+        // more callbacks - we're not going to unload
+        remove(callback);
+        return false;
+    }
+}
+
+
+//
+// Create a new attachment for this module
+//
+CSSM_HANDLE Module::attach(const CSSM_VERSION &version,
+                           uint32 subserviceId,
+                           CSSM_SERVICE_TYPE subserviceType,
+                           const CSSM_API_MEMORY_FUNCS &memoryOps,
+                           CSSM_ATTACH_FLAGS attachFlags,
+                           CSSM_KEY_HIERARCHY keyHierarchy,
+                           CSSM_FUNC_NAME_ADDR *functionTable,
+                           uint32 functionTableSize)
+{
+    StLock<Mutex> _(mLock);
+    
+    // check if the module can do this kind of service
+    if (!supportsService(subserviceType))
+        CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
+
+    Attachment *attachment = cssm.attachmentMakerFor(subserviceType)->make(this,
+                                   version,
+                                   subserviceId, subserviceType,
+                                   memoryOps,
+                                   attachFlags,
+                                   keyHierarchy,
+                                   functionTable, functionTableSize);
+
+    try {
+        // add to module's attachment map
+        attachmentMap.insert(AttachmentMap::value_type(attachment->handle(), attachment));
+    } catch (...) {
+        delete attachment;
+        throw;
+    }
+
+    // all done
+    return attachment->handle();
+}
+
+
+//
+// Detach an Attachment from this module.
+// THREADS: Requires the attachment to be idled out, i.e. caller
+//  is responsible for keeping more users from entering it.
+//
+void Module::detach(Attachment *attachment)
+{
+    StLock<Mutex> _(mLock);
+    attachmentMap.erase(attachment->handle());
+}
+
+
+//
+// Handle events sent by the loaded module.
+//
+void Module::spiEvent(CSSM_MODULE_EVENT event,
+                      const Guid &guid,
+                      uint32 subserviceId,
+                      CSSM_SERVICE_TYPE serviceType)
+{
+    StLock<Mutex> _(mLock);
+    if (guid != myGuid())
+        CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
+    callbackSet(event, guid, subserviceId, serviceType);
+}
+
+// static shim
+CSSM_RETURN Module::spiEventRelay(const CSSM_GUID *ModuleGuid,
+                                   void *Context,
+                                   uint32 SubserviceId,
+                                   CSSM_SERVICE_TYPE ServiceType,
+                                   CSSM_MODULE_EVENT EventType)
+{
+    BEGIN_API
+    static_cast<Module *>(Context)->spiEvent(EventType,
+                                             Guid::required(ModuleGuid),
+                                             SubserviceId,
+                                             ServiceType);
+    END_API(CSSM)
+}
diff --git a/cdsa/cssm/module.h b/cdsa/cssm/module.h
new file mode 100644
index 00000000..58c6e7cf
--- /dev/null
+++ b/cdsa/cssm/module.h
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+
+//
+// module - CSSM Module objects
+//
+#ifndef _H_MODULE
+#define _H_MODULE
+
+#include "cssmint.h"
+#include "cssmmds.h"
+#include <Security/callback.h>
+#include <Security/modloader.h>
+#include <hash_map>
+#include <set>
+
+
+//
+// This type represents a loaded plugin module of some kind. For each CssmManager
+// instance and each one plugin, there is only (at most) one Module object to
+// represent it.
+//
+class Module : public MdsComponent {
+    NOCOPY(Module)
+public:
+    Module(CssmManager *mgr, const MdsComponent &info, Plugin *plugin);
+    virtual ~Module();
+
+    CssmManager &cssm;
+
+    bool unload(const ModuleCallback &callback);
+
+    CSSM_HANDLE attach(const CSSM_VERSION &version,
+                       uint32 subserviceId,
+                       CSSM_SERVICE_TYPE subserviceType,
+                       const CSSM_API_MEMORY_FUNCS &memoryOps,
+                       CSSM_ATTACH_FLAGS attachFlags,
+                       CSSM_KEY_HIERARCHY keyHierarchy,
+                       CSSM_FUNC_NAME_ADDR *functionTable,
+                       uint32 functionTableSize);
+    void detach(Attachment *attachment);
+
+    void add(const ModuleCallback &cb) { callbackSet.insert(cb); }
+    void remove(const ModuleCallback &cb) { callbackSet.erase(cb); }
+
+    unsigned int callbackCount() const { return callbackSet.size(); }
+    unsigned int attachmentCount() const { return attachmentMap.size(); }
+
+	void safeLock()		{ if (!isThreadSafe()) mLock.lock(); }
+	void safeUnlock()	{ if (!isThreadSafe()) mLock.unlock(); }
+    
+public:
+    typedef hash_map<CSSM_HANDLE, Attachment *> AttachmentMap;
+    
+    Plugin *plugin;					// our loader module
+	
+private:
+    void spiEvent(CSSM_MODULE_EVENT event,
+                         const Guid &guid,
+                         uint32 subserviceId,
+                         CSSM_SERVICE_TYPE serviceType);
+
+    static CSSM_RETURN spiEventRelay(const CSSM_GUID *ModuleGuid,
+                                     void *Context,
+                                     uint32 SubserviceId,
+                                     CSSM_SERVICE_TYPE ServiceType,
+                                     CSSM_MODULE_EVENT EventType);
+
+private:
+    AttachmentMap attachmentMap;	// map of all outstanding attachment handles
+    ModuleCallbackSet callbackSet;	// set of registered callbacks
+
+    Mutex mLock;
+};
+
+#endif //_H_MODULE
diff --git a/cdsa/cssm/oidsalg.c b/cdsa/cssm/oidsalg.c
new file mode 100644
index 00000000..3adb6c5c
--- /dev/null
+++ b/cdsa/cssm/oidsalg.c
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * oidsalg.c - OIDs defining crypto algorithms
+ */
+
+#include <Security/oidsbase.h>
+#include <Security/cssmtype.h>
+
+static const uint8
+	OID_MD2[]   	       	= { OID_RSA_HASH, 2 },
+	OID_MD4[]       	   	= { OID_RSA_HASH, 4 },
+	OID_MD5[]          		= { OID_RSA_HASH, 5 },
+	OID_RSAEncryption[]		= { OID_PKCS_1, 1 },	
+	OID_MD2WithRSA[]   		= { OID_PKCS_1, 2 },
+	OID_MD4WithRSA[]   		= { OID_PKCS_1, 3 },
+	OID_MD5WithRSA[]   		= { OID_PKCS_1, 4 },
+	OID_SHA1WithRSA[]  		= { OID_PKCS_1, 5 },
+	OID_DHKeyAgreement[]    = { OID_PKCS_3, 1 },
+	OID_OIW_DSA[]     		= { OID_OIW_ALGORITHM, 12  },  
+	OID_OIW_DSAWithSHA1[] 	= { OID_OIW_ALGORITHM, 27  };
+
+const CSSM_OID
+	CSSMOID_MD2     		= {OID_RSA_HASH_LENGTH+1, (uint8 *)OID_MD2},
+	CSSMOID_MD4     		= {OID_RSA_HASH_LENGTH+1, (uint8 *)OID_MD4},
+	CSSMOID_MD5     		= {OID_RSA_HASH_LENGTH+1, (uint8 *)OID_MD5},
+	CSSMOID_RSA     		= {OID_PKCS_1_LENGTH+1, (uint8 *)OID_RSAEncryption},
+	CSSMOID_MD2WithRSA  	= {OID_PKCS_1_LENGTH+1, (uint8 *)OID_MD2WithRSA},
+	CSSMOID_MD4WithRSA  	= {OID_PKCS_1_LENGTH+1, (uint8 *)OID_MD4WithRSA},
+	CSSMOID_MD5WithRSA  	= {OID_PKCS_1_LENGTH+1, (uint8 *)OID_MD5WithRSA},
+	CSSMOID_SHA1WithRSA 	= {OID_PKCS_1_LENGTH+1, (uint8 *)OID_SHA1WithRSA},
+	CSSMOID_DH      		= {OID_PKCS_3_LENGTH+1, (uint8 *)OID_DHKeyAgreement},
+	CSSMOID_DSA     		= {OID_OIW_ALGORITHM_LENGTH+1, (uint8 *)OID_OIW_DSA},
+	CSSMOID_SHA1WithDSA 	= {OID_OIW_ALGORITHM_LENGTH+1, (uint8 *)OID_OIW_DSAWithSHA1} ;
+
+	
+/*	iSignTP OBJECT IDENTIFIER ::=
+ *		{ appleTrustPolicy 1 }
+ *      { 1 2 840 113635 100 1 1 }
+ *
+ * BER =  06 09 2A 86 48 86 F7 63 64 01 01
+ */
+static const uint8
+APPLE_TP_ISIGN[]		= {APPLE_TP_OID, 1},
+
+/*	AppleX509Basic OBJECT IDENTIFIER ::=
+ *		{ appleTrustPolicy 2 }
+ *      { 1 2 840 113635 100 1 2 }
+ *
+ * BER =  06 09 2A 86 48 86 F7 63 64 01 01
+ */
+APPLE_TP_X509_BASIC[]	= {APPLE_TP_OID, 2},
+
+/* AppleSSLPolicy := {appleTrustPolicy 3 } */
+APPLE_TP_SSL[]			= {APPLE_TP_OID, 3},
+
+/*
+ *	fee OBJECT IDENTIFIER ::=
+ *		{ appleSecurityAlgorithm 1 }
+ *      { 1 2 840 113635 100 2 1 }
+ *
+ * BER = 06 09 2A 86 48 86 F7 63 64 02 01
+ */
+APPLE_FEE[]			= {APPLE_ALG_OID, 1},
+
+/*
+ *	asc OBJECT IDENTIFIER ::=
+ *		{ appleSecurityAlgorithm 2 }
+ *      { 1 2 840 113635 100 2 2 }
+ *
+ * BER = 06 09 2A 86 48 86 F7 63 64 02 02
+ */
+APPLE_ASC[]			= {APPLE_ALG_OID, 2},
+
+/*
+ *	fee_MD5 OBJECT IDENTIFIER ::=
+ *		{ appleSecurityAlgorithm 3 }
+ *      { 1 2 840 113635 100 2 3 }
+ *
+ * BER = 06 09 2A 86 48 86 F7 63 64 02 03
+ */
+APPLE_FEE_MD5[]		= {APPLE_ALG_OID, 3},
+
+/*
+ *	fee_SHA1 OBJECT IDENTIFIER ::=
+ *		{ appleSecurityAlgorithm 4 }
+ *      { 1 2 840 113635 100 2 4 }
+ *
+ * BER = 06 09 2A 86 48 86 F7 63 64 02 04
+ */
+APPLE_FEE_SHA1[]	= {APPLE_ALG_OID, 4},
+
+/*
+ *	feed OBJECT IDENTIFIER ::=
+ *		{ appleSecurityAlgorithm 5 }
+ *      { 1 2 840 113635 100 2 5 }
+ *
+ * BER = 06 09 2A 86 48 86 F7 63 64 02 05
+ */
+APPLE_FEED[]		= {APPLE_ALG_OID, 5},
+
+/*
+ *	feedExp OBJECT IDENTIFIER ::=
+ *		{ appleSecurityAlgorithm 6 }
+ *      { 1 2 840 113635 100 2 6 }
+ *
+ * BER = 06 09 2A 86 48 86 F7 63 64 02 06
+ */
+APPLE_FEEDEXP[]		= {APPLE_ALG_OID, 6},
+
+/*
+ *	AppleECDSA OBJECT IDENTIFIER ::=
+ *		{ appleSecurityAlgorithm 7 }
+ *      { 1 2 840 113635 100 2 7 }
+ *
+ * BER = 06 09 2A 86 48 86 F7 63 64 02 07
+ */
+APPLE_ECDSA[]		= {APPLE_ALG_OID, 7};
+
+const CSSM_OID	
+
+CSSMOID_APPLE_ISIGN      = {APPLE_TP_OID_LENGTH+1,  (uint8 *)APPLE_TP_ISIGN},
+CSSMOID_APPLE_X509_BASIC = {APPLE_TP_OID_LENGTH+1,  (uint8 *)APPLE_TP_X509_BASIC},
+CSSMOID_APPLE_TP_SSL	 = {APPLE_TP_OID_LENGTH+1,  (uint8 *)APPLE_TP_SSL},
+CSSMOID_APPLE_FEE        = {APPLE_ALG_OID_LENGTH+1, (uint8 *)APPLE_FEE},
+CSSMOID_APPLE_ASC        = {APPLE_ALG_OID_LENGTH+1, (uint8 *)APPLE_ASC},
+CSSMOID_APPLE_FEE_MD5    = {APPLE_ALG_OID_LENGTH+1, (uint8 *)APPLE_FEE_MD5},
+CSSMOID_APPLE_FEE_SHA1   = {APPLE_ALG_OID_LENGTH+1, (uint8 *)APPLE_FEE_SHA1},
+CSSMOID_APPLE_FEED       = {APPLE_ALG_OID_LENGTH+1, (uint8 *)APPLE_FEED},
+CSSMOID_APPLE_FEEDEXP    = {APPLE_ALG_OID_LENGTH+1, (uint8 *)APPLE_FEEDEXP},
+CSSMOID_APPLE_ECDSA      = {APPLE_ALG_OID_LENGTH+1, (uint8 *)APPLE_ECDSA};
+
+
diff --git a/cdsa/cssm/oidsattr.c b/cdsa/cssm/oidsattr.c
new file mode 100644
index 00000000..d6b8db9c
--- /dev/null
+++ b/cdsa/cssm/oidsattr.c
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * oidsattr.c - Cert/CRL related OIDs.
+ */
+
+#include <Security/oidsattr.h>
+
+
+/* 
+ * Directory name component identifiers.
+ */
+static const uint8
+	OID_ObjectClass[]           		= { OID_ATTR_TYPE, 0 },
+	OID_AliasedEntryName[]      		= { OID_ATTR_TYPE, 1 },
+	OID_KnowledgeInformation[]  		= { OID_ATTR_TYPE, 2 },
+	OID_CommonName[]            		= { OID_ATTR_TYPE, 3 },
+	OID_Surname[]              			= { OID_ATTR_TYPE, 4 },
+	OID_SerialNumber[]         			= { OID_ATTR_TYPE, 5 },
+	OID_CountryName[]           		= { OID_ATTR_TYPE, 6 },
+	OID_LocalityName[]          		= { OID_ATTR_TYPE, 7 },
+	OID_StateProvinceName[]     		= { OID_ATTR_TYPE, 8 },
+	OID_CollectiveStateProvinceName[] 	= { OID_ATTR_TYPE, 8, 1 },
+	OID_StreetAddress[]         		= { OID_ATTR_TYPE, 9 },
+	OID_CollectiveStreetAddress[]     	= { OID_ATTR_TYPE, 9, 1 },
+	OID_OrganizationName[]      		= { OID_ATTR_TYPE, 10 },
+	OID_CollectiveOrganizationName[]  	= { OID_ATTR_TYPE, 10, 1 },
+	OID_OrganizationalUnitName[]		= { OID_ATTR_TYPE, 11 },
+	OID_CollectiveOrganizationalUnitName[]
+										= { OID_ATTR_TYPE, 11, 1 },
+	OID_Title[]                 		= { OID_ATTR_TYPE, 12 },
+	OID_Description[]           		= { OID_ATTR_TYPE, 13 },
+	OID_SearchGuide[]           		= { OID_ATTR_TYPE, 14 },
+	OID_BusinessCategory[]      		= { OID_ATTR_TYPE, 15 },
+	OID_PostalAddress[]         		= { OID_ATTR_TYPE, 16 },
+	OID_CollectivePostalAddress[]     	= { OID_ATTR_TYPE, 16, 1 },
+	OID_PostalCode[]            		= { OID_ATTR_TYPE, 17 },
+	OID_CollectivePostalCode[]  		= { OID_ATTR_TYPE, 17, 1 },
+	OID_PostOfficeBox[]         		= { OID_ATTR_TYPE, 18 },
+	OID_CollectivePostOfficeBox[]     	= { OID_ATTR_TYPE, 18, 1 },
+	OID_PhysicalDeliveryOfficeName[]  	= { OID_ATTR_TYPE, 19 },
+	OID_CollectivePhysicalDeliveryOfficeName[]
+										= { OID_ATTR_TYPE, 19, 1 },
+	OID_TelephoneNumber[]       		= { OID_ATTR_TYPE, 20 },
+	OID_CollectiveTelephoneNumber[]  	= { OID_ATTR_TYPE, 20, 1 },
+	OID_TelexNumber[]           		= { OID_ATTR_TYPE, 21 },
+	OID_CollectiveTelexNumber[] 		= { OID_ATTR_TYPE, 21, 1 },
+	OID_TelexTerminalIdentifier[]     	= { OID_ATTR_TYPE, 22 },
+	OID_CollectiveTelexTerminalIdentifier[] 
+										= { OID_ATTR_TYPE, 22, 1 },
+	OID_FacsimileTelephoneNumber[]    	= { OID_ATTR_TYPE, 23 },
+	OID_CollectiveFacsimileTelephoneNumber[]
+										= { OID_ATTR_TYPE, 23, 1 },
+	OID_X_121Address[]          		= { OID_ATTR_TYPE, 24 },
+	OID_InternationalISDNNumber[]     	= { OID_ATTR_TYPE, 25 },
+	OID_CollectiveInternationalISDNNumber[] 
+										= { OID_ATTR_TYPE, 25, 1 },
+	OID_RegisteredAddress[]     		= { OID_ATTR_TYPE, 26 },
+	OID_DestinationIndicator[]  		= { OID_ATTR_TYPE, 27 },
+	OID_PreferredDeliveryMethod[] 		= { OID_ATTR_TYPE, 28 },
+	OID_PresentationAddress[]   		= { OID_ATTR_TYPE, 29 },
+	OID_SupportedApplicationContext[] 	= { OID_ATTR_TYPE, 30 },
+	OID_Member[]                		= { OID_ATTR_TYPE, 31 },
+	OID_Owner[]                			= { OID_ATTR_TYPE, 32 },
+	OID_RoleOccupant[]          		= { OID_ATTR_TYPE, 33 },
+	OID_SeeAlso[]               		= { OID_ATTR_TYPE, 34 },
+	OID_UserPassword[]          		= { OID_ATTR_TYPE, 35 },
+	OID_UserCertificate[]       		= { OID_ATTR_TYPE, 36 },
+	OID_CACertificate[]         		= { OID_ATTR_TYPE, 37 },
+	OID_AuthorityRevocationList[] 		= { OID_ATTR_TYPE, 38 },
+	OID_CertificateRevocationList[] 	= { OID_ATTR_TYPE, 39 },
+	OID_CrossCertificatePair[]  		= { OID_ATTR_TYPE, 40 },
+	OID_Name[]                  		= { OID_ATTR_TYPE, 41 },
+	OID_GivenName[]             		= { OID_ATTR_TYPE, 42 },
+	OID_Initials[]              		= { OID_ATTR_TYPE, 43 },
+	OID_GenerationQualifier[]   		= { OID_ATTR_TYPE, 44 },
+	OID_UniqueIdentifier[]     			= { OID_ATTR_TYPE, 45 },
+	OID_DNQualifier[]           		= { OID_ATTR_TYPE, 46 },
+	OID_EnhancedSearchGuide[]   		= { OID_ATTR_TYPE, 47 },
+	OID_ProtocolInformation[]   		= { OID_ATTR_TYPE, 48 },
+	OID_DistinguishedName[]     		= { OID_ATTR_TYPE, 49 },
+	OID_UniqueMember[]          		= { OID_ATTR_TYPE, 50 },
+	OID_HouseIdentifier[]       		= { OID_ATTR_TYPE, 51 }
+;
+
+const CSSM_OID
+CSSMOID_ObjectClass        		= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_ObjectClass},
+CSSMOID_AliasedEntryName    	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_AliasedEntryName},
+CSSMOID_KnowledgeInformation	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_KnowledgeInformation},
+CSSMOID_CommonName          	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_CommonName},
+CSSMOID_Surname             	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_Surname},
+CSSMOID_SerialNumber       		= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_SerialNumber},
+CSSMOID_CountryName         	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_CountryName},
+CSSMOID_LocalityName        	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_LocalityName},
+CSSMOID_StateProvinceName   	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_StateProvinceName},
+CSSMOID_CollectiveStateProvinceName
+								= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveStateProvinceName},
+CSSMOID_StreetAddress       	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_StreetAddress},
+CSSMOID_CollectiveStreetAddress = { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveStreetAddress},
+CSSMOID_OrganizationName    	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_OrganizationName},
+CSSMOID_CollectiveOrganizationName  
+								= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveOrganizationName},
+CSSMOID_OrganizationalUnitName  = { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_OrganizationalUnitName},
+CSSMOID_CollectiveOrganizationalUnitName
+								= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveOrganizationalUnitName},
+CSSMOID_Title              		= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_Title},
+CSSMOID_Description        		= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_Description},
+CSSMOID_SearchGuide         	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_SearchGuide},
+CSSMOID_BusinessCategory    	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_BusinessCategory},
+CSSMOID_PostalAddress       	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_PostalAddress},
+CSSMOID_CollectivePostalAddress = { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectivePostalAddress},
+CSSMOID_PostalCode          	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_PostalCode},
+CSSMOID_CollectivePostalCode	= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectivePostalCode},
+CSSMOID_PostOfficeBox       	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_PostOfficeBox},
+CSSMOID_CollectivePostOfficeBox = { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectivePostOfficeBox},
+CSSMOID_PhysicalDeliveryOfficeName  
+								= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_PhysicalDeliveryOfficeName},
+CSSMOID_CollectivePhysicalDeliveryOfficeName 
+								= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectivePhysicalDeliveryOfficeName},
+CSSMOID_TelephoneNumber     	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_TelephoneNumber},
+CSSMOID_CollectiveTelephoneNumber   
+								= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveTelephoneNumber},
+CSSMOID_TelexNumber         	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_TelexNumber},
+CSSMOID_CollectiveTelexNumber   = { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveTelexNumber},
+CSSMOID_TelexTerminalIdentifier = { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_TelexTerminalIdentifier},
+CSSMOID_CollectiveTelexTerminalIdentifier 
+								= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveTelexTerminalIdentifier},
+CSSMOID_FacsimileTelephoneNumber= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_FacsimileTelephoneNumber},
+CSSMOID_CollectiveFacsimileTelephoneNumber
+								= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveFacsimileTelephoneNumber},
+CSSMOID_X_121Address        	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_X_121Address},
+CSSMOID_InternationalISDNNumber = { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_InternationalISDNNumber},
+CSSMOID_CollectiveInternationalISDNNumber 
+								= { OID_ATTR_TYPE_LENGTH+2, (uint8 *)OID_CollectiveInternationalISDNNumber},
+CSSMOID_RegisteredAddress   	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_RegisteredAddress},
+CSSMOID_DestinationIndicator	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_DestinationIndicator},
+CSSMOID_PreferredDeliveryMethod = { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_PreferredDeliveryMethod},
+CSSMOID_PresentationAddress 	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_PresentationAddress},
+CSSMOID_SupportedApplicationContext 
+								= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_SupportedApplicationContext},
+CSSMOID_Member              	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_Member},
+CSSMOID_Owner               	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_Owner},
+CSSMOID_RoleOccupant        	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_RoleOccupant},
+CSSMOID_SeeAlso             	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_SeeAlso},
+CSSMOID_UserPassword        	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_UserPassword},
+CSSMOID_UserCertificate     	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_UserCertificate},
+CSSMOID_CACertificate       	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_CACertificate},
+CSSMOID_AuthorityRevocationList = { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_AuthorityRevocationList},
+CSSMOID_CertificateRevocationList
+								= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_CertificateRevocationList},
+CSSMOID_CrossCertificatePair	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_CrossCertificatePair},
+CSSMOID_Name                	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_Name},
+CSSMOID_GivenName           	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_GivenName},
+CSSMOID_Initials            	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_Initials},
+CSSMOID_GenerationQualifier 	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_GenerationQualifier},
+CSSMOID_UniqueIdentifier    	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_UniqueIdentifier},
+CSSMOID_DNQualifier         	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_DNQualifier},
+CSSMOID_EnhancedSearchGuide 	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_EnhancedSearchGuide},
+CSSMOID_ProtocolInformation 	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_ProtocolInformation},
+CSSMOID_DistinguishedName   	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_DistinguishedName},
+CSSMOID_UniqueMember        	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_UniqueMember},
+CSSMOID_HouseIdentifier     	= { OID_ATTR_TYPE_LENGTH+1, (uint8 *)OID_HouseIdentifier}
+;
+
+
+/* From PKCS 9 */
+static const uint8
+	OID_EmailAddress[]          = { OID_PKCS_9, 1 },
+	OID_UnstructuredName[]      = { OID_PKCS_9, 2 },
+	OID_ContentType[]           = { OID_PKCS_9, 3 },
+	OID_MessageDigest[]         = { OID_PKCS_9, 4 },
+	OID_SigningTime[]           = { OID_PKCS_9, 5 },
+	OID_CounterSignature[]      = { OID_PKCS_9, 6 },
+	OID_ChallengePassword[]     = { OID_PKCS_9, 7 },
+	OID_UnstructuredAddress[]   = { OID_PKCS_9, 8 },
+	OID_ExtendedCertificateAttributes[] = { OID_PKCS_9, 9 }
+;
+
+const CSSM_OID
+CSSMOID_EmailAddress        = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_EmailAddress},
+CSSMOID_UnstructuredName    = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_UnstructuredName},
+CSSMOID_ContentType         = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_ContentType},
+CSSMOID_MessageDigest       = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_MessageDigest},
+CSSMOID_SigningTime         = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_SigningTime},
+CSSMOID_CounterSignature    = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_CounterSignature},
+CSSMOID_ChallengePassword   = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_ChallengePassword},
+CSSMOID_UnstructuredAddress = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_UnstructuredAddress},
+CSSMOID_ExtendedCertificateAttributes = {OID_PKCS_9_LENGTH+1, (uint8 *)OID_ExtendedCertificateAttributes};
+
+/* PKIX */
+static const uint8
+	OID_QT_CPS[]			= { OID_QT, 1},
+	OID_QT_UNOTICE[]		= { OID_QT, 2}
+;
+
+const CSSM_OID
+CSSMOID_QT_CPS				= {OID_QT_LENGTH+1, (uint8 *)OID_QT_CPS},
+CSSMOID_QT_UNOTICE			= {OID_QT_LENGTH+1, (uint8 *)OID_QT_UNOTICE}
+;
+
diff --git a/cdsa/cssm/oidscert.cpp b/cdsa/cssm/oidscert.cpp
new file mode 100644
index 00000000..8e5e7c21
--- /dev/null
+++ b/cdsa/cssm/oidscert.cpp
@@ -0,0 +1,198 @@
+/*
+ * 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.
+ */
+
+
+/*
+
+ File:      oidscert.cpp
+
+ Contains:  Object Identifiers for X509 Certificate Library
+
+ Copyright: (c) 1999 Apple Computer, Inc., all rights reserved.
+
+ */
+
+#include <Security/oidscert.h>
+ 
+static const uint8
+
+	/* Certificate OID Fields */
+	X509V3SignedCertificate[]					= {INTEL_X509V3_CERT_R08, 0},
+	X509V3SignedCertificateCStruct[]			= {INTEL_X509V3_CERT_R08, 0, INTEL_X509_C_DATATYPE},
+	X509V3Certificate[]							= {INTEL_X509V3_CERT_R08, 1},
+	X509V3CertificateCStruct[]					= {INTEL_X509V3_CERT_R08, 1, INTEL_X509_C_DATATYPE},
+	X509V1Version[]								= {INTEL_X509V3_CERT_R08, 2},
+	X509V1SerialNumber[]						= {INTEL_X509V3_CERT_R08, 3},
+	X509V1IssuerName[]							= {INTEL_X509V3_CERT_R08, 5},
+	X509V1IssuerNameCStruct[]					= {INTEL_X509V3_CERT_R08, 5, INTEL_X509_C_DATATYPE},
+	X509V1IssuerNameLDAP[]						= {INTEL_X509V3_CERT_R08, 5, INTEL_X509_LDAPSTRING_DATATYPE},
+	X509V1ValidityNotBefore[]					= {INTEL_X509V3_CERT_R08, 6},
+	X509V1ValidityNotAfter[]					= {INTEL_X509V3_CERT_R08, 7},
+	X509V1SubjectName[]							= {INTEL_X509V3_CERT_R08, 8},
+	X509V1SubjectNameCStruct[]					= {INTEL_X509V3_CERT_R08, 8, INTEL_X509_C_DATATYPE},
+	X509V1SubjectNameLDAP[]						= {INTEL_X509V3_CERT_R08, 8, INTEL_X509_LDAPSTRING_DATATYPE},
+	X509V1SubjectPublicKeyAlgorithm[]			= {INTEL_X509V3_CERT_R08, 9},
+	X509V1SubjectPublicKey[]					= {INTEL_X509V3_CERT_R08, 10},
+	X509V1CertificateIssuerUniqueId[]			= {INTEL_X509V3_CERT_R08, 11},
+	X509V1CertificateSubjectUniqueId[]			= {INTEL_X509V3_CERT_R08, 12},
+	X509V3CertificateExtensionStruct[]			= {INTEL_X509V3_CERT_R08, 13},
+	X509V3CertificateExtensionCStruct[]			= {INTEL_X509V3_CERT_R08, 13, INTEL_X509_C_DATATYPE},
+	X509V3CertificateNumberOfExtensions[]		= {INTEL_X509V3_CERT_R08, 14},
+	X509V3CertificateExtensionId[]				= {INTEL_X509V3_CERT_R08, 15},
+	X509V3CertificateExtensionCritical[]		= {INTEL_X509V3_CERT_R08, 16},
+	X509V3CertificateExtensionValue[]			= {INTEL_X509V3_CERT_R08, 17},
+	X509V1SubjectPublicKeyAlgorithmParameters[]	= {INTEL_X509V3_CERT_R08, 18},
+	X509V3CertificateExtensionType[]			= {INTEL_X509V3_CERT_R08, 19},
+	CSSMKeyStruct[]								= {INTEL_X509V3_CERT_R08, 20},
+	X509V1SubjectPublicKeyCStruct[]				= {INTEL_X509V3_CERT_R08, 20, INTEL_X509_C_DATATYPE},
+	X509V3CertificateExtensionsStruct[]			= {INTEL_X509V3_CERT_R08, 21},
+	X509V3CertificateExtensionsCStruct[]		= {INTEL_X509V3_CERT_R08, 21, INTEL_X509_C_DATATYPE},
+	
+	/* Signature OID Fields */
+	X509V1SignatureStruct[]						= {INTEL_X509V3_SIGN_R08, 0},
+	X509V1SignatureCStruct[]					= {INTEL_X509V3_SIGN_R08, 0, INTEL_X509_C_DATATYPE},
+	/* for the algorithm ID in the cert proper */
+	X509V1SignatureAlgorithm[]					= {INTEL_X509V3_SIGN_R08, 1},
+	/* for the one in TBSCert */
+	X509V1SignatureAlgorithmTBS[]				= {INTEL_X509V3_SIGN_R08, 10},
+	X509V1SignatureAlgorithmParameters[]		= {INTEL_X509V3_SIGN_R08, 3},
+	X509V1Signature[]							= {INTEL_X509V3_SIGN_R08, 2},
+	
+	/* Extension OID Fields */
+	SubjectSignatureBitmap[]					= {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS, 1},
+	SubjectPicture[]							= {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS, 2},
+	SubjectEmailAddress[]						= {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS, 3},
+	UseExemptions[]								= {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS, 4};
+
+
+const CSSM_OID
+
+	/* Certificate OIDS */
+	CSSMOID_X509V3SignedCertificate  						= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3SignedCertificate},
+	CSSMOID_X509V3SignedCertificateCStruct  				= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V3SignedCertificateCStruct},
+	CSSMOID_X509V3Certificate  							= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3Certificate},
+	CSSMOID_X509V3CertificateCStruct  						= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V3CertificateCStruct},
+	CSSMOID_X509V1Version  								= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1Version},
+	CSSMOID_X509V1SerialNumber  							= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1SerialNumber},
+	CSSMOID_X509V1IssuerName  							= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1IssuerName},
+	CSSMOID_X509V1IssuerNameCStruct  					= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V1IssuerNameCStruct},
+	CSSMOID_X509V1IssuerNameLDAP  						= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V1IssuerNameLDAP},
+	CSSMOID_X509V1ValidityNotBefore  						= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1ValidityNotBefore},
+	CSSMOID_X509V1ValidityNotAfter  						= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1ValidityNotAfter},
+	CSSMOID_X509V1SubjectName  							= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1SubjectName},
+	CSSMOID_X509V1SubjectNameCStruct  					= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V1SubjectNameCStruct},
+	CSSMOID_X509V1SubjectNameLDAP  						= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V1SubjectNameLDAP},
+	CSSMOID_CSSMKeyStruct  								= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)CSSMKeyStruct},
+	CSSMOID_X509V1SubjectPublicKeyCStruct  				= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V1SubjectPublicKeyCStruct},
+	CSSMOID_X509V1SubjectPublicKeyAlgorithm  				= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1SubjectPublicKeyAlgorithm},
+	CSSMOID_X509V1SubjectPublicKeyAlgorithmParameters  	= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1SubjectPublicKeyAlgorithmParameters},
+	CSSMOID_X509V1SubjectPublicKey  						= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1SubjectPublicKey},
+	CSSMOID_X509V1CertificateIssuerUniqueId  				= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1CertificateIssuerUniqueId},
+	CSSMOID_X509V1CertificateSubjectUniqueId  				= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V1CertificateSubjectUniqueId},
+	CSSMOID_X509V3CertificateExtensionsStruct  				= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3CertificateExtensionsStruct},
+	CSSMOID_X509V3CertificateExtensionsCStruct  				= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V3CertificateExtensionsCStruct},
+	CSSMOID_X509V3CertificateNumberOfExtensions  			= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3CertificateNumberOfExtensions},
+	CSSMOID_X509V3CertificateExtensionStruct  				= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3CertificateExtensionStruct},
+	CSSMOID_X509V3CertificateExtensionCStruct  				= {INTEL_X509V3_CERT_R08_LENGTH+2,  (uint8 *)X509V3CertificateExtensionCStruct},
+	CSSMOID_X509V3CertificateExtensionId  					= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3CertificateExtensionId},
+	CSSMOID_X509V3CertificateExtensionCritical  				= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3CertificateExtensionCritical},
+	CSSMOID_X509V3CertificateExtensionType  				= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3CertificateExtensionType},
+	CSSMOID_X509V3CertificateExtensionValue  				= {INTEL_X509V3_CERT_R08_LENGTH+1,  (uint8 *)X509V3CertificateExtensionValue},
+
+	/* Signature OID Fields */
+	CSSMOID_X509V1SignatureStruct  						= {INTEL_X509V3_SIGN_R08_LENGTH+1,  (uint8 *)X509V1SignatureStruct},
+	CSSMOID_X509V1SignatureCStruct  						= {INTEL_X509V3_SIGN_R08_LENGTH+2,  (uint8 *)X509V1SignatureCStruct},
+	CSSMOID_X509V1SignatureAlgorithm  					= {INTEL_X509V3_SIGN_R08_LENGTH+1,  (uint8 *)X509V1SignatureAlgorithm},
+	CSSMOID_X509V1SignatureAlgorithmTBS  					= {INTEL_X509V3_SIGN_R08_LENGTH+1,  (uint8 *)X509V1SignatureAlgorithmTBS},
+	CSSMOID_X509V1SignatureAlgorithmParameters  			= {INTEL_X509V3_SIGN_R08_LENGTH+1,  (uint8 *)X509V1SignatureAlgorithmParameters},
+	CSSMOID_X509V1Signature  							= {INTEL_X509V3_SIGN_R08_LENGTH+1,  (uint8 *)X509V1Signature},
+	
+	/* Extension OID Fields */
+	CSSMOID_SubjectSignatureBitmap  						= {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS_LENGTH+1,  (uint8 *)SubjectSignatureBitmap},
+	CSSMOID_SubjectPicture  								= {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS_LENGTH+1,  (uint8 *)SubjectPicture},
+	CSSMOID_SubjectEmailAddress 							= {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS_LENGTH+1,  (uint8 *)SubjectEmailAddress},
+	CSSMOID_UseExemptions  								= {INTEL_X509V3_CERT_PRIVATE_EXTENSIONS_LENGTH+1, (uint8 *)UseExemptions};
+
+/***
+ *** Apple addenda.
+ ***/
+ 
+/* 
+ * Standard Cert extensions.
+ */
+static const uint8
+	OID_SubjectDirectoryAttributes[]	= { OID_EXTENSION, 9 },
+	OID_SubjectKeyIdentifier[] 		 	= { OID_EXTENSION, 14 },
+	OID_KeyUsage[]             		 	= { OID_EXTENSION, 15 },
+	OID_PrivateKeyUsagePeriod[] 	 	= { OID_EXTENSION, 16 },
+	OID_SubjectAltName[]       			= { OID_EXTENSION, 17 },
+	OID_IssuerAltName[]         		= { OID_EXTENSION, 18 },
+	OID_BasicConstraints[]      		= { OID_EXTENSION, 19 },
+	OID_CrlNumber[]             		= { OID_EXTENSION, 20 },
+	OID_CrlReason[]             		= { OID_EXTENSION, 21 },
+	OID_HoldInstructionCode[]   		= { OID_EXTENSION, 23 },
+	OID_InvalidityDate[]        		= { OID_EXTENSION, 24 },
+	OID_DeltaCrlIndicator[]     		= { OID_EXTENSION, 27 },
+	OID_IssuingDistributionPoints[]     = { OID_EXTENSION, 28 },
+	OID_NameConstraints[]       		= { OID_EXTENSION, 30 },
+	OID_CrlDistributionPoints[] 		= { OID_EXTENSION, 31 },
+	OID_CertificatePolicies[]   		= { OID_EXTENSION, 32 },
+	OID_PolicyMappings[]        		= { OID_EXTENSION, 33 },
+	OID_AuthorityKeyIdentifier[]		= { OID_EXTENSION, 35 },
+	OID_PolicyConstraints[]     		= { OID_EXTENSION, 36 },
+	OID_ExtendedKeyUsage[] 				= { OID_EXTENSION, 37 },
+	OID_ExtendedUseCodeSigning[]		= { OID_EXTENSION, 37, 3 }
+;
+
+#define OID_PKCS_CE_LENGTH	OID_EXTENSION_LENGTH + 1
+
+const CSSM_OID
+CSSMOID_SubjectDirectoryAttributes = { OID_PKCS_CE_LENGTH, (uint8 *)OID_SubjectDirectoryAttributes},
+CSSMOID_SubjectKeyIdentifier 	= { OID_PKCS_CE_LENGTH, (uint8 *)OID_SubjectKeyIdentifier},
+CSSMOID_KeyUsage  				= { OID_PKCS_CE_LENGTH, (uint8 *)OID_KeyUsage},
+CSSMOID_PrivateKeyUsagePeriod  	= { OID_PKCS_CE_LENGTH, (uint8 *)OID_PrivateKeyUsagePeriod},
+CSSMOID_SubjectAltName  		= { OID_PKCS_CE_LENGTH, (uint8 *)OID_SubjectAltName},
+CSSMOID_IssuerAltName  			= { OID_PKCS_CE_LENGTH, (uint8 *)OID_IssuerAltName},
+CSSMOID_BasicConstraints  		= { OID_PKCS_CE_LENGTH, (uint8 *)OID_BasicConstraints},
+CSSMOID_CrlNumber  				= { OID_PKCS_CE_LENGTH, (uint8 *)OID_CrlNumber},
+CSSMOID_CrlReason  				= { OID_PKCS_CE_LENGTH, (uint8 *)OID_CrlReason},
+CSSMOID_HoldInstructionCode  	= { OID_PKCS_CE_LENGTH, (uint8 *)OID_HoldInstructionCode},
+CSSMOID_InvalidityDate  		= { OID_PKCS_CE_LENGTH, (uint8 *)OID_InvalidityDate},
+CSSMOID_DeltaCrlIndicator  		= { OID_PKCS_CE_LENGTH, (uint8 *)OID_DeltaCrlIndicator},
+CSSMOID_IssuingDistributionPoints = { OID_PKCS_CE_LENGTH, (uint8 *)OID_IssuingDistributionPoints},
+CSSMOID_NameConstraints  		= { OID_PKCS_CE_LENGTH, (uint8 *)OID_NameConstraints},
+CSSMOID_CrlDistributionPoints  	= { OID_PKCS_CE_LENGTH, (uint8 *)OID_CrlDistributionPoints},
+CSSMOID_CertificatePolicies  	= { OID_PKCS_CE_LENGTH, (uint8 *)OID_CertificatePolicies},
+CSSMOID_PolicyMappings  		= { OID_PKCS_CE_LENGTH, (uint8 *)OID_PolicyMappings},
+CSSMOID_PolicyConstraints  		= { OID_PKCS_CE_LENGTH, (uint8 *)OID_PolicyConstraints},
+CSSMOID_AuthorityKeyIdentifier  = { OID_PKCS_CE_LENGTH, (uint8 *)OID_AuthorityKeyIdentifier},
+CSSMOID_ExtendedKeyUsage  		= { OID_PKCS_CE_LENGTH, (uint8 *)OID_ExtendedKeyUsage},
+CSSMOID_ExtendedUseCodeSigning	= { OID_PKCS_CE_LENGTH+1, (uint8 *)OID_ExtendedUseCodeSigning};
+
+
+/*
+ * Netscape extensions.
+ *
+ *  netscape-cert-type OBJECT IDENTIFIER ::=
+ * 		{ 2 16 840 1 113730 1 1 }
+ *
+ *	BER = 06 08 60 86 48 01 86 F8 42 01 01
+ */
+static const uint8 	OID_NetscapeCertType[] 		= {NETSCAPE_CERT_EXTEN, 1};
+const CSSM_OID	CSSMOID_NetscapeCertType 	= 
+	{NETSCAPE_CERT_EXTEN_LENGTH + 1, (uint8 *)OID_NetscapeCertType};
+
diff --git a/cdsa/cssm/oidscrl.cpp b/cdsa/cssm/oidscrl.cpp
new file mode 100644
index 00000000..63fc07e0
--- /dev/null
+++ b/cdsa/cssm/oidscrl.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+
+/*
+
+ File:      oidscert.cpp
+
+ Contains:  Object Identifiers for X509 Certificate Library
+
+ Copyright: (c) 1999 Apple Computer, Inc., all rights reserved.
+
+ */
+
+#include <Security/oidscrl.h>
+ 
+static const uint8
+
+	/* CRL OIDs */
+	X509V2CRLSignedCrlStruct[]					= {INTEL_X509V2_CRL_R08, 0},
+	X509V2CRLSignedCrlCStruct	[]					= {INTEL_X509V2_CRL_R08, 0, INTEL_X509_C_DATATYPE},
+	X509V2CRLTbsCertListStruct	[]					= {INTEL_X509V2_CRL_R08, 1},
+	X509V2CRLTbsCertListCStruct[]					= {INTEL_X509V2_CRL_R08, 1, INTEL_X509_C_DATATYPE},
+	X509V2CRLVersion	[]							= {INTEL_X509V2_CRL_R08, 2},
+	X509V1CRLIssuerStruct[]						= {INTEL_X509V2_CRL_R08, 3},
+	X509V1CRLIssuerNameCStruct[]					= {INTEL_X509V2_CRL_R08, 3, INTEL_X509_C_DATATYPE},
+	X509V1CRLIssuerNameLDAP[]					= {INTEL_X509V2_CRL_R08, 3, INTEL_X509_LDAPSTRING_DATATYPE},
+	X509V1CRLThisUpdate[]							= {INTEL_X509V2_CRL_R08, 4},
+	X509V1CRLNextUpdate[]						= {INTEL_X509V2_CRL_R08, 5},
+	
+	/* CRL Entry (CRL CertList) OIDS */
+	X509V1CRLRevokedCertificatesStruct[]			= {INTEL_X509V2_CRL_R08, 7},
+	X509V1CRLRevokedCertificatesCStruct[]			= {INTEL_X509V2_CRL_R08, 7, INTEL_X509_C_DATATYPE},
+	X509V1CRLNumberOfRevokedCertEntries[]			= {INTEL_X509V2_CRL_R08, 6},
+	X509V1CRLRevokedEntryStruct[]					= {INTEL_X509V2_CRL_R08, 15},
+	X509V1CRLRevokedEntryCStruct[]				= {INTEL_X509V2_CRL_R08, 15, INTEL_X509_C_DATATYPE},
+	X509V1CRLRevokedEntrySerialNumber[]			= {INTEL_X509V2_CRL_R08, 16},
+	X509V1CRLRevokedEntryRevocationDate[]			= {INTEL_X509V2_CRL_R08, 17},
+	
+	/* CRL Entry (CRL CertList) Extension OIDs */
+	X509V2CRLRevokedEntryAllExtensionsStruct[]		= {INTEL_X509V2_CRL_R08, 18},
+	X509V2CRLRevokedEntryAllExtensionsCStruct[]		= {INTEL_X509V2_CRL_R08, 18, INTEL_X509_C_DATATYPE},
+	X509V2CRLRevokedEntryNumberOfExtensions[]		= {INTEL_X509V2_CRL_R08, 20},
+	X509V2CRLRevokedEntrySingleExtensionStruct[]	= {INTEL_X509V2_CRL_R08, 19},
+	X509V2CRLRevokedEntrySingleExtensionCStruct[]	= {INTEL_X509V2_CRL_R08, 19, INTEL_X509_C_DATATYPE},
+	X509V2CRLRevokedEntryExtensionId[]				= {INTEL_X509V2_CRL_R08, 21},
+	X509V2CRLRevokedEntryExtensionCritical[]		= {INTEL_X509V2_CRL_R08, 22},
+	X509V2CRLRevokedEntryExtensionType[]			= {INTEL_X509V2_CRL_R08, 23},
+	X509V2CRLRevokedEntryExtensionValue[]			= {INTEL_X509V2_CRL_R08, 24},
+	
+	/* CRL Extension OIDs */
+	X509V2CRLAllExtensionsStruct[]					= {INTEL_X509V2_CRL_R08, 8},
+	X509V2CRLAllExtensionsCStruct[]				= {INTEL_X509V2_CRL_R08, 8, INTEL_X509_C_DATATYPE},
+	X509V2CRLNumberOfExtensions[]					= {INTEL_X509V2_CRL_R08, 10},
+	X509V2CRLSingleExtensionStruct[]				= {INTEL_X509V2_CRL_R08, 9},
+	X509V2CRLSingleExtensionCStruct[]				= {INTEL_X509V2_CRL_R08, 9, INTEL_X509_C_DATATYPE},
+	X509V2CRLExtensionId[]						= {INTEL_X509V2_CRL_R08, 11},
+	X509V2CRLExtensionCritical[]					= {INTEL_X509V2_CRL_R08, 12},
+	X509V2CRLExtensionType[]						= {INTEL_X509V2_CRL_R08, 13};
+
+const CSSM_OID
+
+	/* CRL OIDs */
+	CSSMOID_X509V2CRLSignedCrlStruct 						= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLSignedCrlStruct},
+	CSSMOID_X509V2CRLSignedCrlCStruct 					= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V2CRLSignedCrlCStruct},
+	CSSMOID_X509V2CRLTbsCertListStruct 					= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLTbsCertListStruct},
+	CSSMOID_X509V2CRLTbsCertListCStruct 					= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V2CRLTbsCertListCStruct},
+	CSSMOID_X509V2CRLVersion 							= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLVersion},
+	CSSMOID_X509V1CRLIssuerStruct 						= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V1CRLIssuerStruct},
+	CSSMOID_X509V1CRLIssuerNameCStruct 					= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V1CRLIssuerNameCStruct},
+	CSSMOID_X509V1CRLIssuerNameLDAP 					= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V1CRLIssuerNameLDAP},
+	CSSMOID_X509V1CRLThisUpdate 							= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V1CRLThisUpdate},
+	CSSMOID_X509V1CRLNextUpdate 						= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V1CRLNextUpdate},
+
+	/* CRL Entry (CRL CertList) OIDS */
+	CSSMOID_X509V1CRLRevokedCertificatesStruct 			= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V1CRLRevokedCertificatesStruct},
+	CSSMOID_X509V1CRLRevokedCertificatesCStruct 			= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V1CRLRevokedCertificatesCStruct},
+	CSSMOID_X509V1CRLNumberOfRevokedCertEntries 			= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V1CRLNumberOfRevokedCertEntries},
+	CSSMOID_X509V1CRLRevokedEntryStruct 					= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V1CRLRevokedEntryStruct},
+	CSSMOID_X509V1CRLRevokedEntryCStruct 				= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V1CRLRevokedEntryCStruct},
+	CSSMOID_X509V1CRLRevokedEntrySerialNumber 			= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V1CRLRevokedEntrySerialNumber},
+	CSSMOID_X509V1CRLRevokedEntryRevocationDate 			= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V1CRLRevokedEntryRevocationDate},
+
+	/* CRL Entry (CRL CertList) Extension OIDs */
+	CSSMOID_X509V2CRLRevokedEntryAllExtensionsStruct 		= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLRevokedEntryAllExtensionsStruct},
+	CSSMOID_X509V2CRLRevokedEntryAllExtensionsCStruct 		= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V2CRLRevokedEntryAllExtensionsCStruct},
+	CSSMOID_X509V2CRLRevokedEntryNumberOfExtensions 		= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLRevokedEntryNumberOfExtensions},
+	CSSMOID_X509V2CRLRevokedEntrySingleExtensionStruct 	= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLRevokedEntrySingleExtensionStruct},
+	CSSMOID_X509V2CRLRevokedEntrySingleExtensionCStruct 	= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V2CRLRevokedEntrySingleExtensionCStruct},
+	CSSMOID_X509V2CRLRevokedEntryExtensionId 				= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLRevokedEntryExtensionId},
+	CSSMOID_X509V2CRLRevokedEntryExtensionCritical 		= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLRevokedEntryExtensionCritical},
+	CSSMOID_X509V2CRLRevokedEntryExtensionType 			= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLRevokedEntryExtensionType},
+	CSSMOID_X509V2CRLRevokedEntryExtensionValue 			= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLRevokedEntryExtensionValue},
+
+	/* CRL Extension OIDs */
+	CSSMOID_X509V2CRLAllExtensionsStruct 					= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLAllExtensionsStruct},
+	CSSMOID_X509V2CRLAllExtensionsCStruct 					= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V2CRLAllExtensionsCStruct},
+	CSSMOID_X509V2CRLNumberOfExtensions 					= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLNumberOfExtensions},
+	CSSMOID_X509V2CRLSingleExtensionStruct 				= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLSingleExtensionStruct},
+	CSSMOID_X509V2CRLSingleExtensionCStruct 				= {INTEL_X509V2_CRL_R08_LENGTH+2, (uint8 *)X509V2CRLSingleExtensionCStruct},
+	CSSMOID_X509V2CRLExtensionId 						= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLExtensionId},
+	CSSMOID_X509V2CRLExtensionCritical 					= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLExtensionCritical},
+	CSSMOID_X509V2CRLExtensionType 						= {INTEL_X509V2_CRL_R08_LENGTH+1, (uint8 *)X509V2CRLExtensionType};
diff --git a/cdsa/cssm/transition.cpp b/cdsa/cssm/transition.cpp
new file mode 100644
index 00000000..8a672f3f
--- /dev/null
+++ b/cdsa/cssm/transition.cpp
@@ -0,0 +1,507 @@
+/*
+ * 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.
+ */
+
+
+//
+// transition - transition layer for CSSM API/SPI calls.
+//
+// This file defines all functions that connect the CSSM API (CSSM_*)
+// to a plugin's SPI (CSSM_SPI_*) functions. The bulk of these functions
+// is automatically generated by the Perl script transition.pl (thanks, Larry!)
+// from the cssm*.h official header files, under control of the configuration
+// file transition.cfg. Those that need special magic are marked "custom" in
+// transition.cfg and are defined here.
+//
+// @@@ Reconsider CSP locking for context operations
+//
+#include "cssmint.h"
+#include "attachfactory.h"
+#include "manager.h"
+#include "cssmcontext.h"
+#include <Security/cssmcspi.h>
+#include <Security/cssmdli.h>
+#include <Security/cssmcli.h>
+#include <Security/cssmaci.h>
+#include <Security/cssmtpi.h>
+#include <Security/cssmkrapi.h>
+#include <Security/cssmkrspi.h>
+
+
+//
+// Names for the standard Attachment types
+//
+typedef StandardAttachment<CSSM_SERVICE_CSP, CSSM_SPI_CSP_FUNCS> CSPAttachment;
+typedef StandardAttachment<CSSM_SERVICE_DL, CSSM_SPI_DL_FUNCS> DLAttachment;
+typedef StandardAttachment<CSSM_SERVICE_CL, CSSM_SPI_CL_FUNCS> CLAttachment;
+typedef StandardAttachment<CSSM_SERVICE_AC, CSSM_SPI_AC_FUNCS> ACAttachment;
+typedef StandardAttachment<CSSM_SERVICE_TP, CSSM_SPI_TP_FUNCS> TPAttachment;
+
+
+//
+// A conditional locking class for always-right(TM) lock management.
+//
+class TransitLock {
+public:
+	Attachment &attachment;
+	
+	TransitLock(Attachment &att) : attachment(att)
+	{
+		attachment.module.safeLock();
+	}
+	
+	~TransitLock()
+	{
+		attachment.module.safeUnlock();
+		attachment.exit();
+	}
+};
+
+
+//
+// Context management functions
+//
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateSignatureContext (CSSM_CSP_HANDLE CSPHandle,
+                                 CSSM_ALGORITHMS AlgorithmID,
+                                 const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                                 const CSSM_KEY *Key,
+                                 CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    HandleContext::Maker maker(CSPHandle);
+    maker.setup(AccessCred);
+    maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY);
+    maker.make();
+    maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred);
+    maker.put(CSSM_ATTRIBUTE_KEY, Key);
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_SIGNATURE, AlgorithmID);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateSymmetricContext (CSSM_CSP_HANDLE CSPHandle,
+                                 CSSM_ALGORITHMS AlgorithmID,
+                                 CSSM_ENCRYPT_MODE Mode,
+                                 const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                                 const CSSM_KEY *Key,
+                                 const CSSM_DATA *InitVector,
+                                 CSSM_PADDING Padding,
+                                 void *Reserved,
+                                 CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    if (Reserved != NULL)
+        CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
+    HandleContext::Maker maker(CSPHandle);
+    maker.setup(Mode);
+    maker.setup(AccessCred);
+    maker.setup(Key);
+    maker.setup(InitVector);
+    maker.setup(Padding);
+    maker.make();
+    maker.put(CSSM_ATTRIBUTE_MODE, Mode);
+    maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred);
+    maker.put(CSSM_ATTRIBUTE_KEY, Key);
+    maker.put(CSSM_ATTRIBUTE_INIT_VECTOR, InitVector);
+    maker.put(CSSM_ATTRIBUTE_PADDING, Padding);
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_SYMMETRIC, AlgorithmID);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateDigestContext (CSSM_CSP_HANDLE CSPHandle,
+                              CSSM_ALGORITHMS AlgorithmID,
+                              CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    HandleContext::Maker maker(CSPHandle);
+    maker.make();
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_DIGEST, AlgorithmID);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateMacContext (CSSM_CSP_HANDLE CSPHandle,
+                           CSSM_ALGORITHMS AlgorithmID,
+                           const CSSM_KEY *Key,
+                           CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    HandleContext::Maker maker(CSPHandle);
+    maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY);
+    maker.make();
+    maker.put(CSSM_ATTRIBUTE_KEY, Key);
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_MAC, AlgorithmID);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateRandomGenContext (CSSM_CSP_HANDLE CSPHandle,
+                                 CSSM_ALGORITHMS AlgorithmID,
+                                 const CSSM_CRYPTO_DATA *Seed,
+                                 uint32 Length,
+                                 CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    HandleContext::Maker maker(CSPHandle);
+    maker.setup(Seed);
+    maker.setup(Length, CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE);
+    maker.make();
+    maker.put(CSSM_ATTRIBUTE_SEED, Seed);
+    maker.put(CSSM_ATTRIBUTE_OUTPUT_SIZE, Length);
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_RANDOMGEN, AlgorithmID);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateAsymmetricContext (CSSM_CSP_HANDLE CSPHandle,
+                                  CSSM_ALGORITHMS AlgorithmID,
+                                  const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                                  const CSSM_KEY *Key,
+                                  CSSM_PADDING Padding,
+                                  CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    HandleContext::Maker maker(CSPHandle);
+    maker.setup(AccessCred, CSSMERR_CSP_MISSING_ATTR_ACCESS_CREDENTIALS);
+    maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY);
+    maker.setup(Padding);
+    maker.make();
+    maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred);
+    maker.put(CSSM_ATTRIBUTE_KEY, Key);
+    maker.put(CSSM_ATTRIBUTE_PADDING, Padding);
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_ASYMMETRIC, AlgorithmID);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateDeriveKeyContext (CSSM_CSP_HANDLE CSPHandle,
+                                 CSSM_ALGORITHMS AlgorithmID,
+                                 CSSM_KEY_TYPE DeriveKeyType,
+                                 uint32 DeriveKeyLengthInBits,
+                                 const CSSM_ACCESS_CREDENTIALS *AccessCred,
+                                 const CSSM_KEY *BaseKey,
+                                 uint32 IterationCount,
+                                 const CSSM_DATA *Salt,
+                                 const CSSM_CRYPTO_DATA *Seed,
+                                 CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    HandleContext::Maker maker(CSPHandle);
+    maker.setup(DeriveKeyType, CSSMERR_CSP_INVALID_ATTR_KEY_TYPE);
+    maker.setup(DeriveKeyLengthInBits, CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH);
+    maker.setup(AccessCred);
+    maker.setup(BaseKey);
+    maker.setup(IterationCount);
+    maker.setup(Salt);
+    maker.setup(Seed);
+    maker.make();
+    maker.put(CSSM_ATTRIBUTE_KEY_TYPE, DeriveKeyType);
+    maker.put(CSSM_ATTRIBUTE_KEY_LENGTH, DeriveKeyLengthInBits);
+    maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred);
+    maker.put(CSSM_ATTRIBUTE_KEY, BaseKey);
+    maker.put(CSSM_ATTRIBUTE_ITERATION_COUNT, IterationCount);
+    maker.put(CSSM_ATTRIBUTE_SALT, Salt);
+    maker.put(CSSM_ATTRIBUTE_SEED, Seed);
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_DERIVEKEY, AlgorithmID);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreateKeyGenContext (CSSM_CSP_HANDLE CSPHandle,
+                              CSSM_ALGORITHMS AlgorithmID,
+                              uint32 KeySizeInBits,
+                              const CSSM_CRYPTO_DATA *Seed,
+                              const CSSM_DATA *Salt,
+                              const CSSM_DATE *StartDate,
+                              const CSSM_DATE *EndDate,
+                              const CSSM_DATA *Params,
+                              CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    HandleContext::Maker maker(CSPHandle);
+    maker.setup(KeySizeInBits, CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH);
+    maker.setup(Seed);
+    maker.setup(Salt);
+    maker.setup(StartDate);
+    maker.setup(EndDate);
+    maker.setup(Params);
+    maker.make();
+    maker.put(CSSM_ATTRIBUTE_KEY_LENGTH, KeySizeInBits);
+    maker.put(CSSM_ATTRIBUTE_SEED, Seed);
+    maker.put(CSSM_ATTRIBUTE_SALT, Salt);
+    maker.put(CSSM_ATTRIBUTE_START_DATE, StartDate);
+    maker.put(CSSM_ATTRIBUTE_END_DATE, EndDate);
+    maker.put(CSSM_ATTRIBUTE_ALG_PARAMS, Params);
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_KEYGEN, AlgorithmID);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_CSP_CreatePassThroughContext (CSSM_CSP_HANDLE CSPHandle,
+                                   const CSSM_KEY *Key,
+                                   CSSM_CC_HANDLE *NewContextHandle)
+{
+    BEGIN_API
+    HandleContext::Maker maker(CSPHandle);
+    maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY);
+    maker.make();
+    maker.put(CSSM_ATTRIBUTE_KEY, Key);
+    Required(NewContextHandle) = maker(CSSM_ALGCLASS_NONE, CSSM_ALGID_NONE);
+    END_API(CSSM)
+}
+
+
+//
+// CSSM_GetContext makes a deep copy of a CSP context and hands it to the
+// caller. The result is NOT a HandleContext, but a bare Context that is
+// in no dictionaries etc. User must delete it by calling CSSM_FreeContext.
+//
+CSSM_RETURN CSSMAPI
+CSSM_GetContext (CSSM_CC_HANDLE CCHandle,
+                 CSSM_CONTEXT_PTR *ContextP)
+{
+    BEGIN_API
+    HandleContext &context = findHandle<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+    Context *newContext = new(context.attachment) Context(context.type(), context.algorithm());
+    try {
+        newContext->CSPHandle = context.attachment.handle();
+        newContext->copyFrom(context, context.attachment);
+        Required(ContextP) = newContext;
+    } catch (...) {
+        context.attachment.free(newContext);
+        throw;
+    }
+    END_API(CSSM)
+}
+
+
+//
+// Since we allocated all the data in one fell heap, our FreeContext
+// function is disappointingly simple.
+//
+CSSM_RETURN CSSMAPI
+CSSM_FreeContext (CSSM_CONTEXT_PTR ContextP)
+{
+    BEGIN_API
+    Context *context = &Context::required(ContextP);
+    context->destroy(context, findHandle<CSPAttachment>(context->CSPHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE));
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_SetContext (CSSM_CC_HANDLE CCHandle,
+                 const CSSM_CONTEXT *ContextP)
+{
+    BEGIN_API
+    const Context &source = Context::required(ContextP);
+    HandleContext &context = findHandle<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+
+    CSSM_CONTEXT_ATTRIBUTE *oldAttributes = context.ContextAttributes;
+    uint32 oldCount = context.NumberOfAttributes;
+	CSSM_CONTEXT_TYPE oldType = context.ContextType;
+    CSSM_ALGORITHMS oldAlgorithm = context.AlgorithmType;
+    
+    context.copyFrom(source, context.attachment);
+	context.ContextType = source.ContextType;
+    context.AlgorithmType = source.AlgorithmType;
+    
+    if (CSSM_RETURN err = context.validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
+		context.attachment.free(context.ContextAttributes);	// free rejected attribute blob
+    	context.ContextAttributes = oldAttributes;	// restore...
+    	context.NumberOfAttributes = oldCount;		// ... old
+		context.ContextType = oldType;				//  ... values
+    	context.AlgorithmType = oldAlgorithm;		//   ... in context
+    	CssmError::throwMe(err);						// tell the caller it failed
+    }
+    
+    free(oldAttributes);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_DeleteContext (CSSM_CC_HANDLE CCHandle)
+{
+    BEGIN_API
+    HandleContext &context = enterContext(CCHandle);
+	StLock<CountingMutex, &CountingMutex::enter, &CountingMutex::exit> 
+		_(context.attachment, true);
+    
+    // ignore error return from CSP event notify (can't decline deletion)
+    context.validateChange(CSSM_CONTEXT_EVENT_DELETE);
+    	
+    context.destroy(&context, context.attachment);
+    END_API(CSSM)
+}
+
+
+//
+// The GetContextAttribute API is fatally flawed. The standard implies a deep
+// copy of the attribute value, but no release function exists. Instead, we
+// return a shallow copy (sharing structure) which you need not release, but
+// which becomes invalid when the source Context is destroyed.
+//
+CSSM_RETURN CSSMAPI
+CSSM_GetContextAttribute (const CSSM_CONTEXT *Context,
+                          uint32 AttributeType,
+                          CSSM_CONTEXT_ATTRIBUTE_PTR *ContextAttribute)
+{
+    BEGIN_API
+    CSSM_ATTRIBUTE_TYPE type = CSSM_ATTRIBUTE_TYPE(AttributeType);	// CDSA defect
+    Required(ContextAttribute) = Context::required(Context).find(type);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_UpdateContextAttributes (CSSM_CC_HANDLE CCHandle,
+                              uint32 NumberAttributes,
+                              const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes)
+{
+    BEGIN_API
+    HandleContext &context = findHandle<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+    context.mergeAttributes(ContextAttributes, NumberAttributes);
+    END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_DeleteContextAttributes (CSSM_CC_HANDLE CCHandle,
+                              uint32 NumberOfAttributes,
+                              const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes)
+{
+    BEGIN_API
+    if (NumberOfAttributes == 0)
+        return CSSM_OK;	// I suppose
+    Required(ContextAttributes); // preflight
+    HandleContext &context = findHandle<HandleContext>(CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+    for (uint32 n = 0; n < NumberOfAttributes; n++)
+        context.deleteAttribute(ContextAttributes[n].AttributeType);
+    END_API(CSSM)
+}
+
+
+//
+// Miscellaneous odds and ends - these functions just need a wee bit of
+// manual massaging to fit.
+//
+CSSM_RETURN CSSMAPI
+CSSM_DigestDataClone (CSSM_CC_HANDLE ccHandle,
+                      CSSM_CC_HANDLE *newCCHandle)
+{
+	BEGIN_API
+    HandleContext &context = findHandleAndLock<HandleContext>(ccHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
+	TransitLock _(context.attachment);
+    HandleContext *newContext =
+    	new(context.attachment) HandleContext(context.attachment, context.type(), context.algorithm());
+    try {
+        newContext->CSPHandle = context.attachment.handle();
+        newContext->copyFrom(context, context.attachment);
+		context.attachment.downcalls.DigestDataClone(context.attachment.handle(), ccHandle, newContext->handle());
+        Required(newCCHandle) = newContext->handle();
+    } catch (...) {
+    	newContext->destroy(newContext, context.attachment);
+        throw;
+    }
+	END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_QueryKeySizeInBits (CSSM_CSP_HANDLE CSPHandle,
+                         CSSM_CC_HANDLE ccHandle,
+                         const CSSM_KEY *key,
+                         CSSM_KEY_SIZE_PTR keySize)
+{
+	//@@@ could afford not to lock attachment in have-CC case
+	BEGIN_API
+	Required(keySize);
+	Context *context;
+	CSPAttachment *attachment;
+	if (ccHandle == HandleObject::invalidHandle) {
+		// key specified by CSPHandle and Key
+		attachment = &enterAttachment<CSPAttachment>(CSPHandle);
+		context = NULL;
+	} else {
+		// key specified by ccHandle
+		HandleContext *ctx = &enterContext(ccHandle);
+		try {
+			attachment = &ctx->attachment;
+            context = ctx;
+			CSPHandle = context->CSPHandle;
+			key = &context->get<CssmKey>(CSSM_ATTRIBUTE_KEY,
+										 CSSMERR_CSP_INVALID_KEY);
+		} catch (...) {
+			attachment->exit();
+			throw;
+		}
+	}
+	TransitLock _(*attachment);
+	CSSM_RETURN result = attachment->downcalls.QueryKeySizeInBits(CSPHandle,
+			ccHandle, context, key, keySize);
+	return result;
+	END_API(CSSM)
+}
+
+
+CSSM_RETURN CSSMAPI
+CSSM_GenerateAlgorithmParams (CSSM_CC_HANDLE CCHandle,
+                              uint32 ParamBits,
+                              CSSM_DATA_PTR Param)
+{
+	BEGIN_API
+    // this function has more subtle locking than usual. Pay attention:
+
+    // (1) Resolve context and ensure attachment exit
+	HandleContext &context = enterContext(CCHandle);
+    StLock<CountingMutex, &CountingMutex::enter, &CountingMutex::exit> _(context.attachment, true);
+    
+    // (2) Call CSP, acquiring module safe-lock for a moment (only)
+	CSSM_CONTEXT_ATTRIBUTE_PTR attributes;
+	uint32 count;
+    {
+        StLock<Module, &Module::safeLock, &Module::safeUnlock> _(context.attachment.module);
+        if (CSSM_RETURN err =
+                context.attachment.downcalls.GenerateAlgorithmParams(context.attachment.handle(),
+                CCHandle, &context,
+                ParamBits, Param,
+                &count, &attributes))
+            CssmError::throwMe(err);
+    }
+    
+    // (3) Merge the attributes returned into the context, which will (again) acquire the module safe-lock internally
+	if (count)
+	    context.mergeAttributes(attributes, count);
+    // the memory at (attributes, count) belongs to the CSP; don't free it here
+	END_API(CSSM)
+}
+
+
+//
+// Include the auto-generated functions
+//
+#include "transition.gen"
diff --git a/cdsa/generator.mk b/cdsa/generator.mk
new file mode 100644
index 00000000..baee2921
--- /dev/null
+++ b/cdsa/generator.mk
@@ -0,0 +1,77 @@
+# Makefile for generated files.
+
+PERL=/usr/bin/perl
+
+CDSA_HEADERS_DIR = $(SRCROOT)/cdsa/cdsa
+SECURITY_HEADERS_DIR = $(SRCROOT)/cdsa/cdsa_utilities
+CDSA_SOURCES_DIR = $(SRCROOT)/cdsa/cssm
+KEYCHAIN_SOURCES_DIR = $(SRCROOT)/Keychain
+CSPDL_SOURCES_DIR = $(SRCROOT)/AppleCSPDL
+CDSA_UTILITIES_DIR = $(SRCROOT)/cdsa/cdsa_utilities
+CDSA_PLUGINLIB_DIR = $(SRCROOT)/cdsa/cdsa_pluginlib
+GEN_SOURCE_DIR = $(SYMROOT)/derived_src
+GEN_HEADER_DIR = $(SYMROOT)/include/Security
+
+GEN_ERRORCODES = $(CDSA_UTILITIES_DIR)/generator.pl
+ERRORCODES_GEN = $(patsubst %,$(GEN_SOURCE_DIR)/%,errorcodes.gen)
+ERRORCODES_DEPENDS = $(GEN_ERRORCODES)\
+					 $(patsubst %,$(CDSA_HEADERS_DIR)/%,cssmerr.h)\
+					 $(patsubst %,$(CDSA_HEADERS_DIR)/%,cssmapple.h)
+
+GEN_APIGLUE = $(CDSA_SOURCES_DIR)/generator.pl
+APIGLUE_GEN = $(patsubst %,$(GEN_SOURCE_DIR)/%,transition.gen funcnames.gen generator.rpt)
+APIGLUE_DEPENDS = $(patsubst %,$(CDSA_SOURCES_DIR)/%, generator.pl generator.cfg)\
+				  $(patsubst %,$(CDSA_HEADERS_DIR)/%,cssmapi.h cssmtype.h cssmconfig.h cssmaci.h cssmcspi.h cssmdli.h cssmcli.h cssmtpi.h)
+
+GEN_SPIGLUE = $(CDSA_PLUGINLIB_DIR)/generator.pl
+SPIGLUE_GEN = $(patsubst %,$(GEN_HEADER_DIR)/%,ACabstractsession.h CLabstractsession.h CSPabstractsession.h DLabstractsession.h TPabstractsession.h)\
+			  $(patsubst %,$(GEN_SOURCE_DIR)/%,ACabstractsession.cpp CLabstractsession.cpp CSPabstractsession.cpp DLabstractsession.cpp TPabstractsession.cpp)
+SPIGLUE_DEPENDS = $(patsubst %,$(CDSA_PLUGINLIB_DIR)/%,generator.pl generator.cfg)\
+				  $(patsubst %,$(CDSA_HEADERS_DIR)/%,cssmapi.h cssmtype.h cssmconfig.h cssmaci.h cssmcli.h cssmcspi.h cssmdli.h cssmspi.h)
+
+SCHEMA_GEN = $(patsubst %,$(GEN_SOURCE_DIR)/%,Schema.cpp)
+SCHEMA_DEPENDS = $(patsubst %,$(KEYCHAIN_SOURCES_DIR)/%,Schema.m4)
+
+KEYSCHEMA_GEN = $(patsubst %,$(GEN_SOURCE_DIR)/%,KeySchema.cpp)
+KEYSCHEMA_DEPENDS = $(patsubst %,$(CSPDL_SOURCES_DIR)/%,KeySchema.m4)
+
+build: $(ERRORCODES_GEN) $(APIGLUE_GEN) $(SPIGLUE_GEN) $(SCHEMA_GEN) $(KEYSCHEMA_GEN)
+
+debug: build
+
+profile: build
+
+install: build
+
+installhdrs: $(SPIGLUE_GEN)
+
+installsrc:
+
+clean:
+	rm -f $(ERRORCODES_GEN) $(APIGLUE_GEN) $(SPIGLUE_GEN) $(SCHEMA_GEN) $(KEYSCHEMA_GEN)
+
+.PHONY: build clean debug profile
+
+$(ERRORCODES_GEN): $(ERRORCODES_DEPENDS)
+	mkdir -p $(GEN_SOURCE_DIR)
+	(cd $(CDSA_UTILITIES_DIR);\
+	  $(PERL) ./generator.pl $(CDSA_HEADERS_DIR) $(GEN_SOURCE_DIR))
+
+$(APIGLUE_GEN): $(APIGLUE_DEPENDS)
+	mkdir -p $(GEN_SOURCE_DIR)
+	(cd $(CDSA_SOURCES_DIR);\
+	  $(PERL) ./generator.pl $(CDSA_HEADERS_DIR) $(GEN_SOURCE_DIR))
+
+$(SPIGLUE_GEN): $(SPIGLUE_DEPENDS)
+	mkdir -p $(GEN_HEADER_DIR)
+	mkdir -p $(GEN_SOURCE_DIR)
+	(cd $(CDSA_PLUGINLIB_DIR);\
+	  $(PERL) ./generator.pl $(CDSA_HEADERS_DIR) $(GEN_HEADER_DIR) $(GEN_SOURCE_DIR))
+
+$(SCHEMA_GEN): $(SCHEMA_DEPENDS)
+	mkdir -p $(GEN_SOURCE_DIR)
+	m4 $(SCHEMA_DEPENDS) > $(SCHEMA_GEN)
+
+$(KEYSCHEMA_GEN): $(KEYSCHEMA_DEPENDS)
+	mkdir -p $(GEN_SOURCE_DIR)
+	m4 $(KEYSCHEMA_DEPENDS) > $(KEYSCHEMA_GEN)
diff --git a/cdsa/mds/.cvsignore b/cdsa/mds/.cvsignore
new file mode 100644
index 00000000..9c0531bf
--- /dev/null
+++ b/cdsa/mds/.cvsignore
@@ -0,0 +1,2 @@
+PBUserInfo
+mds?Data
diff --git a/cdsa/mds/MDSDatabase.cpp b/cdsa/mds/MDSDatabase.cpp
new file mode 100644
index 00000000..eaa3a6da
--- /dev/null
+++ b/cdsa/mds/MDSDatabase.cpp
@@ -0,0 +1,221 @@
+/*
+ * 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.
+ */
+
+
+#include "MDSDatabase.h"
+#include "MDSSchema.h"
+
+#include <Security/DbContext.h>
+#include <Security/mds_schema.h>
+#include <Security/cssmerr.h>
+
+//
+// MDSDatabaseManager
+//
+
+Database *MDSDatabaseManager::make (const DbName &inDbName)
+{
+    return new MDSDatabase(inDbName, mTableNames);
+}
+
+//
+// MDSDatabase
+//
+
+MDSDatabase::MDSDatabase (const DbName &inDbName, const AppleDatabaseTableName *tableNames)
+: AppleDatabase(inDbName, tableNames)
+{
+}
+
+MDSDatabase::~MDSDatabase ()
+{
+}
+
+DbContext *
+MDSDatabase::makeDbContext (DatabaseSession &inDatabaseSession,
+                            CSSM_DB_ACCESS_TYPE inAccessRequest,
+                            const CSSM_ACCESS_CREDENTIALS *inAccessCred,
+                            const void *inOpenParameters)
+{
+    return new DbContext (*this, inDatabaseSession, inAccessRequest,
+                          inAccessCred);
+}
+
+void
+MDSDatabase::dbOpen (DbContext &inDbContext)
+{
+    // XXX Do something more...
+}
+
+void
+MDSDatabase::dbClose ()
+{
+    // XXX Do something more...
+}
+
+// Creating and destroying relations is not exposed as part of the
+// MDS interface, so these two methods should never be called.
+
+void
+MDSDatabase::createRelation(DbContext &dbContext,
+	CSSM_DB_RECORDTYPE inRelationID,
+	const char *inRelationName,
+	uint32 inNumberOfAttributes,
+	const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
+	uint32 inNumberOfIndexes,
+	const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::destroyRelation(DbContext &dbContext,
+	CSSM_DB_RECORDTYPE inRelationID)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+char *
+MDSDatabase::getDbNameFromHandle (const DbContext &dbContext) const
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+CSSM_DB_UNIQUE_RECORD_PTR
+MDSDatabase::dataInsert (DbContext &dbContext,
+                         CSSM_DB_RECORDTYPE RecordType,
+                         const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes,
+                         const CssmData *Data)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::dataDelete (DbContext &dbContext,
+                         const CSSM_DB_UNIQUE_RECORD &UniqueRecordIdentifier)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::dataModify (DbContext &dbContext,
+                         CSSM_DB_RECORDTYPE RecordType,
+                         CSSM_DB_UNIQUE_RECORD &UniqueRecordIdentifier,
+                         const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified,
+                         const CssmData *DataToBeModified,
+                         CSSM_DB_MODIFY_MODE ModifyMode)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+CSSM_HANDLE
+MDSDatabase::dataGetFirst (DbContext &dbContext,
+                           const DLQuery *Query,
+                           CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                           CssmData *Data,
+                           CSSM_DB_UNIQUE_RECORD_PTR &UniqueRecordIdentifier)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+bool
+MDSDatabase::dataGetNext (DbContext &dbContext,
+                          CSSM_HANDLE ResultsHandle,
+                          CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                          CssmData *Data,
+                          CSSM_DB_UNIQUE_RECORD_PTR &UniqueRecordIdentifier)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+	return false;
+}
+
+void
+MDSDatabase::dataAbortQuery (DbContext &dbContext,
+                             CSSM_HANDLE ResultsHandle)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::dataGetFromUniqueRecordId (DbContext &dbContext,
+                                        const CSSM_DB_UNIQUE_RECORD &UniqueRecord,
+                                        CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+                                        CssmData *Data)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::freeUniqueRecord (DbContext &dbContext,
+                               CSSM_DB_UNIQUE_RECORD &UniqueRecord)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+// Functions that MDS does not support but we must implement to satisfy Database.
+void
+MDSDatabase::dbCreate (DbContext &inDbContext, const CSSM_DBINFO &inDBInfo,
+                       const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::dbDelete (DatabaseSession &inDatabaseSession,
+                       const CSSM_ACCESS_CREDENTIALS *inAccessCred)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::authenticate(DbContext &dbContext,
+                          CSSM_DB_ACCESS_TYPE inAccessRequest,
+                          const CSSM_ACCESS_CREDENTIALS &inAccessCred)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::getDbAcl(DbContext &dbContext,
+                      const CSSM_STRING *inSelectionTag,
+                      uint32 &outNumberOfAclInfos,
+                      CSSM_ACL_ENTRY_INFO_PTR &outAclInfos)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::changeDbAcl(DbContext &dbContext,
+                         const CSSM_ACCESS_CREDENTIALS &inAccessCred,
+                         const CSSM_ACL_EDIT &inAclEdit)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::getDbOwner(DbContext &dbContext, CSSM_ACL_OWNER_PROTOTYPE &outOwner)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+void
+MDSDatabase::changeDbOwner(DbContext &dbContext,
+                           const CSSM_ACCESS_CREDENTIALS &inAccessCred,
+                           const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner)
+{
+    CssmError ::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
diff --git a/cdsa/mds/MDSDatabase.h b/cdsa/mds/MDSDatabase.h
new file mode 100644
index 00000000..dc2b527b
--- /dev/null
+++ b/cdsa/mds/MDSDatabase.h
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+
+
+#ifndef _MDSDATABASE_H_
+#define _MDSDATABASE_H_  1
+
+#include <Security/AppleDatabase.h>
+#include <Security/threading.h>
+#include <map>
+
+/* This is the concrete DatabaseFactory subclass that creates MDSDatabase instances.
+   Specifically with MDS there are always exactly 2 databases with fixed names.  These
+   are both created whenever the first Database is requested from this factory.  The
+   contents of these databases is constructed on the fly by scanning the CSSM bundle
+   path for plugins and reading the mds segments from there. Asking
+   for a Database with a name different from the 2 allowed ones will result in an
+   exception being thrown.
+ */
+ 
+class MDSDatabaseManager: public AppleDatabaseManager
+{
+public:
+	MDSDatabaseManager(const AppleDatabaseTableName *tableNames);
+    Database *make(const DbName &inDbName);
+};
+
+/* This is the class which represents each of the two MDS databases. */
+
+class MDSDatabase: public AppleDatabase
+{
+public:
+    MDSDatabase(const DbName &inDbName, const AppleDatabaseTableName *tableNames);
+
+    virtual
+    ~MDSDatabase();
+
+    DbContext *
+    makeDbContext(DatabaseSession &inDatabaseSession,
+		CSSM_DB_ACCESS_TYPE inAccessRequest,
+		const CSSM_ACCESS_CREDENTIALS *inAccessCred,
+		const void *inOpenParameters);
+
+    virtual void
+    dbOpen(DbContext &inDbContext);
+
+    virtual void
+    dbClose();
+
+    virtual void
+    dbCreate(DbContext &inDbContext, const CSSM_DBINFO &inDBInfo,
+		const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry);
+
+    virtual void
+    dbDelete(DatabaseSession &inDatabaseSession,
+		const CSSM_ACCESS_CREDENTIALS *inAccessCred);
+
+    virtual void
+    createRelation (DbContext &dbContext,
+                    CSSM_DB_RECORDTYPE inRelationID,
+                    const char *inRelationName,
+                    uint32 inNumberOfAttributes,
+                    const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
+                    uint32 inNumberOfIndexes,
+                    const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo);
+
+    virtual void
+    destroyRelation (DbContext &dbContext, CSSM_DB_RECORDTYPE inRelationID);
+
+    virtual void
+    authenticate(DbContext &dbContext,
+                 CSSM_DB_ACCESS_TYPE inAccessRequest,
+                 const CSSM_ACCESS_CREDENTIALS &inAccessCred);
+
+    virtual void
+    getDbAcl(DbContext &dbContext,
+             const CSSM_STRING *inSelectionTag,
+             uint32 &outNumberOfAclInfos,
+             CSSM_ACL_ENTRY_INFO_PTR &outAclInfos);
+
+    virtual void
+    changeDbAcl(DbContext &dbContext,
+                const CSSM_ACCESS_CREDENTIALS &inAccessCred,
+                const CSSM_ACL_EDIT &inAclEdit);
+
+    virtual void
+    getDbOwner(DbContext &dbContext, CSSM_ACL_OWNER_PROTOTYPE &outOwner);
+
+    virtual void
+    changeDbOwner(DbContext &dbContext,
+                  const CSSM_ACCESS_CREDENTIALS &inAccessCred,
+                  const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner);
+
+    virtual char *
+    getDbNameFromHandle (const DbContext &dbContext) const;
+
+    virtual CSSM_DB_UNIQUE_RECORD_PTR
+    dataInsert (DbContext &dbContext,
+                CSSM_DB_RECORDTYPE RecordType,
+                const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
+                const CssmData *inData);
+
+    virtual void
+    dataDelete (DbContext &dbContext,
+                const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier);
+
+    virtual void
+    dataModify (DbContext &dbContext,
+                CSSM_DB_RECORDTYPE RecordType,
+                CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier,
+                const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
+                const CssmData *inDataToBeModified,
+                CSSM_DB_MODIFY_MODE ModifyMode);
+
+    virtual CSSM_HANDLE
+    dataGetFirst (DbContext &dbContext,
+                  const DLQuery *inQuery,
+                  CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                  CssmData *inoutData,
+                  CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord);
+
+    virtual bool
+    dataGetNext (DbContext &dbContext,
+                 CSSM_HANDLE inResultsHandle,
+                 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                 CssmData *inoutData,
+                 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord);
+
+    virtual void
+    dataAbortQuery (DbContext &dbContext,
+                    CSSM_HANDLE inResultsHandle);
+
+    virtual void
+    dataGetFromUniqueRecordId (DbContext &dbContext,
+                               const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
+                               CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
+                               CssmData *inoutData);
+
+    virtual void
+    freeUniqueRecord (DbContext &dbContext,
+                      CSSM_DB_UNIQUE_RECORD &inUniqueRecord);
+};
+
+#endif //_MDSDATABASE_H_
diff --git a/cdsa/mds/MDSModule.cpp b/cdsa/mds/MDSModule.cpp
new file mode 100644
index 00000000..374322f6
--- /dev/null
+++ b/cdsa/mds/MDSModule.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+
+#include "MDSModule.h"
+#include "MDSSession.h"
+#include <Security/mds_schema.h>
+#include <memory>
+
+ModuleNexus<MDSModule> MDSModule::mModuleNexus;
+
+// Names and IDs of tables used in the MDS databases
+
+#define TABLE(t) { t, #t }
+
+static const AppleDatabaseTableName kTableNames[] = {
+    // the meta-tables. the parsing module is not used by MDS, but is required
+    // by the implementation of the database
+    TABLE(MDS_CDSADIR_MDS_SCHEMA_RELATIONS),
+    TABLE(MDS_CDSADIR_MDS_SCHEMA_ATTRIBUTES),
+    TABLE(MDS_CDSADIR_MDS_SCHEMA_INDEXES),
+    TABLE(CSSM_DL_DB_SCHEMA_PARSING_MODULE),
+	
+    // the MDS-specific tables
+    TABLE(MDS_OBJECT_RECORDTYPE),
+    TABLE(MDS_CDSADIR_CSSM_RECORDTYPE),
+    TABLE(MDS_CDSADIR_KRMM_RECORDTYPE),
+    TABLE(MDS_CDSADIR_EMM_RECORDTYPE),
+    TABLE(MDS_CDSADIR_COMMON_RECORDTYPE),
+    TABLE(MDS_CDSADIR_CSP_PRIMARY_RECORDTYPE),
+    TABLE(MDS_CDSADIR_CSP_CAPABILITY_RECORDTYPE),
+    TABLE(MDS_CDSADIR_CSP_ENCAPSULATED_PRODUCT_RECORDTYPE),
+    TABLE(MDS_CDSADIR_CSP_SC_INFO_RECORDTYPE),
+    TABLE(MDS_CDSADIR_DL_PRIMARY_RECORDTYPE),
+    TABLE(MDS_CDSADIR_DL_ENCAPSULATED_PRODUCT_RECORDTYPE),
+    TABLE(MDS_CDSADIR_CL_PRIMARY_RECORDTYPE),
+    TABLE(MDS_CDSADIR_CL_ENCAPSULATED_PRODUCT_RECORDTYPE),
+    TABLE(MDS_CDSADIR_TP_PRIMARY_RECORDTYPE),
+    TABLE(MDS_CDSADIR_TP_OIDS_RECORDTYPE),
+    TABLE(MDS_CDSADIR_TP_ENCAPSULATED_PRODUCT_RECORDTYPE),
+    TABLE(MDS_CDSADIR_EMM_PRIMARY_RECORDTYPE),
+    TABLE(MDS_CDSADIR_AC_PRIMARY_RECORDTYPE),
+    TABLE(MDS_CDSADIR_KR_PRIMARY_RECORDTYPE),
+	
+    // marker for the end of the list
+    { ~0UL, NULL }
+};
+
+MDSModule &
+MDSModule::get ()
+{
+    return mModuleNexus ();
+}
+
+MDSModule::MDSModule ()
+    :	mDatabaseManager(kTableNames)
+{
+}
+
+MDSModule::~MDSModule ()
+{
+}
diff --git a/cdsa/mds/MDSModule.h b/cdsa/mds/MDSModule.h
new file mode 100644
index 00000000..e70cab58
--- /dev/null
+++ b/cdsa/mds/MDSModule.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+
+#ifndef _MDSMODULE_H_
+#define _MDSMODULE_H_  1
+
+#include <Security/AppleDatabase.h>
+#include <Security/globalizer.h>
+
+class MDSModule
+{
+public:
+    static MDSModule &get ();
+
+    MDSModule ();
+    ~MDSModule ();
+
+    DatabaseManager &databaseManager () { return mDatabaseManager; }
+
+private:
+    static ModuleNexus<MDSModule> mModuleNexus;
+
+    AppleDatabaseManager mDatabaseManager;
+};
+
+#endif // _MDSMODULE_H_
diff --git a/cdsa/mds/MDSPrefs.cpp b/cdsa/mds/MDSPrefs.cpp
new file mode 100644
index 00000000..ef0af3f8
--- /dev/null
+++ b/cdsa/mds/MDSPrefs.cpp
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+
+//
+// MDSPrefs.cpp
+//
+
+#include "MDSPrefs.h"
+#include <CoreFoundation/CFPreferences.h>
+#include <stdlib.h>
+
+// Construct the preferences object and read the current preference settings.
+
+MDSPrefs::MDSPrefs()
+    :	mPluginFolders(NULL)
+{
+    if (!readPathFromPrefs() && !readPathFromEnv())
+        useDefaultPath();
+}
+
+// Destroy the preferences object.
+
+MDSPrefs::~MDSPrefs()
+{
+    if (mPluginFolders)
+        CFRelease(mPluginFolders);
+}
+
+// Obtain the plugin path from a preferences file. Returns true on success of false
+// if no prefs could be found.
+
+bool
+MDSPrefs::readPathFromPrefs()
+{
+    static const CFStringRef kPrefsSuite = CFSTR("com.apple.mds");
+    static const CFStringRef kPluginPathKey = CFSTR("securityPluginPath");
+
+    bool result = true;
+
+    CFPreferencesAddSuitePreferencesToApp(kCFPreferencesCurrentApplication, kPrefsSuite);
+    
+    CFPropertyListRef value;
+    value = CFPreferencesCopyAppValue(kPluginPathKey, kCFPreferencesCurrentApplication);
+    
+    if (CFGetTypeID(value) != CFArrayGetTypeID())
+		// the prefs object is not an array, so fail
+		result = false;
+		
+	else {
+        // make sure that all array elements are strings
+
+		CFArrayRef array = (CFArrayRef) value;
+		int numItems = CFArrayGetCount(array);
+		for (int i = 0; i < numItems; i++)
+			if (CFGetTypeID(CFArrayGetValueAtIndex(array, i)) != CFStringGetTypeID()) {
+				result = false;
+				break;
+			}
+	}
+	
+	if (result)
+        mPluginFolders = (CFArrayRef) value;
+	else
+        CFRelease(value);
+
+    return result;
+}
+
+bool
+MDSPrefs::readPathFromEnv()
+{
+    static const char *kPluginPathEnv = "MDSPATH";
+    static const CFStringRef kSeparator = CFSTR(":");
+
+    char *envValue = getenv(kPluginPathEnv);
+    if (envValue) {
+        CFStringRef path = CFStringCreateWithCString(NULL, envValue, kCFStringEncodingUTF8);
+
+        mPluginFolders = CFStringCreateArrayBySeparatingStrings(NULL, path, kSeparator);
+        
+        CFRelease(path);
+        return true;
+    }
+    
+    return false;
+}
+
+void
+MDSPrefs::useDefaultPath()
+{
+    static const CFStringRef kDefaultPluginPath = CFSTR("/System/Library/Security");
+
+    mPluginFolders = CFArrayCreate(NULL, (const void **) &kDefaultPluginPath, 1, &kCFTypeArrayCallBacks);
+}
+
+// Retrieve the elements of the plugin path.
+
+int
+MDSPrefs::getNumberOfPluginFolders() const
+{
+    if (mPluginFolders)
+        return CFArrayGetCount(mPluginFolders);
+        
+    return 0;
+}
+
+const char *
+MDSPrefs::getPluginFolder(int index)
+{
+    if (mPluginFolders) {
+        int numValues = CFArrayGetCount(mPluginFolders);
+        if (index >= 0 && index < numValues) {
+            CFStringRef value = (CFStringRef) CFArrayGetValueAtIndex(mPluginFolders, index);
+            if (value) {
+                // we have to copy the string since it may be using a different native
+                // encoding than the one we want. the copy is put in a temporary buffer,
+                // so its lifetime is limited to the next call to getPluginFolder() or to
+                // the destruction of the MDSPrefs object. Very long paths will silently fail.
+                
+                if (CFStringGetCString(value, mTempBuffer, kTempBufferSize, kCFStringEncodingUTF8))
+                    return mTempBuffer;
+            }
+        }
+    }
+    
+    return NULL;
+}
+
diff --git a/cdsa/mds/MDSPrefs.h b/cdsa/mds/MDSPrefs.h
new file mode 100644
index 00000000..d74a2116
--- /dev/null
+++ b/cdsa/mds/MDSPrefs.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+
+//
+// MDSPrefs.h
+//
+
+#ifndef _MDS_PREFS_H
+#define _MDS_PREFS_H
+
+#include <CoreFoundation/CFArray.h>
+
+class MDSPrefs
+{
+public:
+    MDSPrefs();
+    ~MDSPrefs();
+
+    int getNumberOfPluginFolders() const;
+    const char *getPluginFolder(int index);
+    
+private:
+    bool readPathFromPrefs();
+    bool readPathFromEnv();
+    void useDefaultPath();
+
+    CFArrayRef mPluginFolders;
+    enum { kTempBufferSize = 1024 };
+    char mTempBuffer[kTempBufferSize];
+};
+
+#endif // _MDS_PREFS_H
\ No newline at end of file
diff --git a/cdsa/mds/MDSSchema.cpp b/cdsa/mds/MDSSchema.cpp
new file mode 100644
index 00000000..98f2c458
--- /dev/null
+++ b/cdsa/mds/MDSSchema.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+
+//
+// MDSSchema.cpp
+//
+// Definitions of structures which define the schema, including attributes
+// and indexes, for the standard tables that are part of the MDS database.
+//
+
+#include "MDSSchema.h"
+#include <Security/mds_schema.h>
+
+//
+// Schema for the lone table in the Object Directory Database.
+//
+
+static const CSSM_DB_SCHEMA_ATTRIBUTE_INFO kAttributesObjectRelation[] = {
+	SCHEMA_ATTRIBUTE(0, ModuleId, STRING),
+	SCHEMA_ATTRIBUTE(1, Manifest, BLOB),
+	SCHEMA_ATTRIBUTE(2, ModuleName, STRING),
+	SCHEMA_ATTRIBUTE(3, Path, STRING),
+	SCHEMA_ATTRIBUTE(4, ProductVersion, STRING)
+};
+
+static const CSSM_DB_SCHEMA_INDEX_INFO kIndexObjectRelation[] = {
+	UNIQUE_INDEX_ATTRIBUTE(0)
+};
+
+const RelationInfo kObjectRelation =
+	RELATION_INFO(MDS_OBJECT_RECORDTYPE, kAttributesObjectRelation, kIndexObjectRelation);
+
+//
+// Schema for the various tables in the CDSA Directory Database.
+//
+
+// CSSM Relation.
+
+static const CSSM_DB_SCHEMA_ATTRIBUTE_INFO kAttributesCSSMRelation[] =
+{
+	SCHEMA_ATTRIBUTE(0, ModuleID, STRING),
+	SCHEMA_ATTRIBUTE(1, CDSAVersion, STRING),
+	SCHEMA_ATTRIBUTE(2, Vendor, STRING),
+	SCHEMA_ATTRIBUTE(3, Desc, STRING),
+	SCHEMA_ATTRIBUTE(4, NativeServices, UINT32)
+};
+
+static const CSSM_DB_SCHEMA_INDEX_INFO kIndexCSSMRelation[] =
+{
+	UNIQUE_INDEX_ATTRIBUTE(0)
+};
+
+const RelationInfo kCSSMRelation =
+	RELATION_INFO(MDS_CDSADIR_CSSM_RECORDTYPE, kAttributesCSSMRelation, kIndexCSSMRelation);
+
+// KRMM Relation.
+	
+static const CSSM_DB_SCHEMA_ATTRIBUTE_INFO kAttributesKRMMRelation[] =
+{
+	SCHEMA_ATTRIBUTE(0, CSSMGuid, STRING),
+	SCHEMA_ATTRIBUTE(1, PolicyType, UINT32),
+	SCHEMA_ATTRIBUTE(2, PolicyName, STRING),
+	SCHEMA_ATTRIBUTE(3, PolicyPath, STRING),
+	SCHEMA_ATTRIBUTE(4, PolicyInfo, BLOB),
+	SCHEMA_ATTRIBUTE(5, PolicyManifest, BLOB)
+};
+
+static const CSSM_DB_SCHEMA_INDEX_INFO kIndexKRMMRelation[] =
+{
+	UNIQUE_INDEX_ATTRIBUTE(0),
+	UNIQUE_INDEX_ATTRIBUTE(1)
+};
+
+const RelationInfo kKRMMRelation =
+	RELATION_INFO(MDS_CDSADIR_KRMM_RECORDTYPE, kAttributesKRMMRelation, kIndexKRMMRelation);
+
+// Common Relation.
+
+static const CSSM_DB_SCHEMA_ATTRIBUTE_INFO kAttributesCommonRelation[] =
+{
+	SCHEMA_ATTRIBUTE(0, ModuleID, STRING),
+	SCHEMA_ATTRIBUTE(1, Manifest, BLOB),
+	SCHEMA_ATTRIBUTE(2, ModuleName, STRING),
+	SCHEMA_ATTRIBUTE(3, Path, STRING),
+	SCHEMA_ATTRIBUTE(4, CDSAVersion, STRING),
+	SCHEMA_ATTRIBUTE(5, Desc, STRING),
+	SCHEMA_ATTRIBUTE(6, DynamicFlag, UINT32),
+	SCHEMA_ATTRIBUTE(7, MultiThreadFlag, UINT32),
+	SCHEMA_ATTRIBUTE(8, ServiceMask, UINT32)
+};
+
+static const CSSM_DB_SCHEMA_INDEX_INFO kIndexCommonRelation[] =
+{
+	UNIQUE_INDEX_ATTRIBUTE(0)
+};
+
+const RelationInfo kCommonRelation =
+	RELATION_INFO(MDS_CDSADIR_COMMON_RECORDTYPE, kAttributesCommonRelation, kIndexCommonRelation);
+
diff --git a/cdsa/mds/MDSSchema.h b/cdsa/mds/MDSSchema.h
new file mode 100644
index 00000000..e8c1fff8
--- /dev/null
+++ b/cdsa/mds/MDSSchema.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+
+//
+// MDSSchema.h
+//
+// Declarations of structures which define the schema, including attributes
+// and indexes, for the standard tables that are part of the MDS database.
+//
+
+#ifndef _MDSSCHEMA_H
+#define _MDSSCHEMA_H
+
+#include <Security/cssmtype.h>
+
+// Structure used to store information which is needed to create
+// a relation with indexes.
+
+struct RelationInfo {
+	CSSM_DB_RECORDTYPE relationId;
+	const char *relationName;
+	uint32 numAttributes;
+	const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *attributes;
+	uint32 numIndexes;
+	const CSSM_DB_SCHEMA_INDEX_INFO *indexes;
+};
+
+// Macros used to simplify declarations of attributes and indexes.
+
+#define SCHEMA_ATTRIBUTE(id, name, type) \
+	{ id, #name, { 0, NULL }, CSSM_DB_ATTRIBUTE_FORMAT_ ## type }
+	
+#define UNIQUE_INDEX_ATTRIBUTE(attributeId) \
+	{ attributeId, 0, CSSM_DB_INDEX_UNIQUE, CSSM_DB_INDEX_ON_ATTRIBUTE }
+
+#define RELATION_INFO(relationId, attributes, indexes) \
+	{ relationId, \
+	  #relationId, \
+	  sizeof(attributes) / sizeof(CSSM_DB_SCHEMA_ATTRIBUTE_INFO), \
+	  attributes, \
+	  sizeof(indexes) / sizeof(CSSM_DB_SCHEMA_INDEX_INFO), \
+	  indexes }
+
+// Declarations of schema for MDS relations.
+
+extern const RelationInfo kObjectRelation;
+extern const RelationInfo kCSSMRelation;
+extern const RelationInfo kKRMMRelation;
+extern const RelationInfo kCommonRelation;
+
+#endif // _MDSSCHEMA_H
diff --git a/cdsa/mds/MDSSession.cpp b/cdsa/mds/MDSSession.cpp
new file mode 100644
index 00000000..ba9d79c0
--- /dev/null
+++ b/cdsa/mds/MDSSession.cpp
@@ -0,0 +1,402 @@
+/*
+ * 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.
+ */
+
+
+#include "MDSSession.h"
+
+#include <Security/DbContext.h>
+#include "MDSModule.h"
+
+#include <memory>
+#include <Security/cssmerr.h>
+#include <Security/utilities.h>
+#include <Security/logging.h>
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <time.h>
+
+// Location of security plugins.
+
+#define kPluginPath "/System/Library/Security/"
+
+// Location of MDS database and lock files.
+
+#define kDatabasePath "/var/tmp/"
+#define kLockFilename kDatabasePath "mds.lock"
+
+// Minimum interval, in seconds, between rescans for plugin changes.
+
+#define kScanInterval 10
+
+//
+// Get the current time in a format that matches that in which
+// a file's modification time is expressed.
+//
+
+static void
+getCurrentTime(struct timespec &now)
+{
+	struct timeval tv;
+	gettimeofday(&tv, NULL);
+	TIMEVAL_TO_TIMESPEC(&tv, &now);
+}
+
+//
+// Create an MDS session.
+//
+
+MDSSession::MDSSession (const Guid *inCallerGuid,
+                        const CSSM_MEMORY_FUNCS &inMemoryFunctions) :
+    DatabaseSession(MDSModule::get().databaseManager()),
+    mCssmMemoryFunctions (inMemoryFunctions),
+	mLockFd(-1)
+{
+	fprintf(stderr, "MDSSession::MDSSession\n");
+		
+    mCallerGuidPresent =  inCallerGuid != nil;
+    if (mCallerGuidPresent)
+        mCallerGuid = *inCallerGuid;
+		
+	// make sure the MDS databases have been created, and the required
+	// tables have been constructed
+	initializeDatabases();
+	
+	// schedule a scan for plugin changes
+	getCurrentTime(mLastScanTime);
+}
+
+MDSSession::~MDSSession ()
+{
+	fprintf(stderr, "MDSSession::~MDSSession\n");
+	releaseLock();
+}
+
+void
+MDSSession::terminate ()
+{
+	fprintf(stderr, "MDSSession::terminate\n");
+
+    closeAll();
+}
+
+//
+// In this implementation, install() does nothing, since the databases
+// are implicitly created as needed by initialize().
+//
+
+void
+MDSSession::install ()
+{
+	// this space intentionally left blank
+}
+
+//
+// In this implementation, the uninstall() call is not supported since
+// we do not allow programmatic deletion of the MDS databases.
+//
+
+void
+MDSSession::uninstall ()
+{
+	CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
+}
+
+//
+// Obtain and free a list of names of current databases.
+//
+
+void
+MDSSession::GetDbNames(CSSM_NAME_LIST_PTR &outNameList)
+{
+	outNameList = mDatabaseManager.getDbNames(*this);
+}
+
+void
+MDSSession::FreeNameList(CSSM_NAME_LIST &inNameList)
+{
+	mDatabaseManager.freeNameList(*this, inNameList);
+}
+
+//
+// Scan the plugin directory.
+//
+
+static bool intervalHasElapsed(const struct timespec &then, const struct timespec &now,
+	int intervalSeconds)
+{
+	return (now.tv_sec - then.tv_sec > intervalSeconds) ||
+		((now.tv_sec - then.tv_sec == intervalSeconds) && (now.tv_nsec >= then.tv_nsec));
+}
+
+static bool operator <=(const struct timespec &a, const struct timespec &b)
+{
+	return (a.tv_sec < b.tv_sec) || ((a.tv_sec == b.tv_sec) && (a.tv_nsec <= b.tv_nsec));
+}
+
+class PluginInfo
+{
+public:
+	PluginInfo(const char *pluginName, const struct timespec &modTime) : mModTime(modTime) {
+		mPluginName = new char[strlen(pluginName) + 1];
+		strcpy(mPluginName, pluginName);
+	}
+
+	~PluginInfo() { delete [] mPluginName; }
+	
+	const char *name() { return mPluginName; }
+	const struct timespec &modTime() { return mModTime; }
+	
+private:
+	char *mPluginName;
+	struct timespec mModTime;
+};
+
+//
+// Attempt to obtain an exclusive lock over the the MDS databases. The
+// parameter is the maximum amount of time, in milliseconds, to spend
+// trying to obtain the lock. A value of zero means to return failure
+// right away if the lock cannot be obtained.
+//
+
+bool
+MDSSession::obtainLock(int timeout /* = 0 */)
+{
+	static const int kRetryDelay = 250; // ms
+	
+	if (mLockFd >= 0)
+		// this session already holds the lock
+		return true;
+		
+	mLockFd = open(kLockFilename, O_CREAT | O_EXCL, 0544);
+	while (mLockFd == -1 && timeout >= kRetryDelay) {
+		timeout -= kRetryDelay;
+		usleep(1000 * kRetryDelay);
+		mLockFd = open(kLockFilename, O_CREAT | O_EXCL, 0544);
+	}
+	
+	return (mLockFd != -1);
+}
+
+//
+// Release the exclusive lock over the MDS databases. If this session
+// does not hold the lock, this method does nothing.
+//
+
+void
+MDSSession::releaseLock()
+{
+	if (mLockFd != -1) {
+		close(mLockFd);
+		unlink(kLockFilename);
+		mLockFd = -1;
+	}
+}
+
+//
+// If necessary, create the two MDS databases and construct the required
+// tables in each database.
+//
+
+void
+MDSSession::initializeDatabases()
+{
+	printf("MDSSession::initializeDatabases\n");
+	
+	static int kLockTimeout = 2000; // ms
+	
+	// obtain an exclusive lock. in this case we really want the lock, so
+	// if it's not immediately available we wait around for a bit
+	
+	if (!obtainLock(kLockTimeout))
+		// something is wrong; either a stale lock file is lying around or
+		// some other process is stuck updating the databases
+		CssmError::throwMe(CSSM_ERRCODE_MDS_ERROR);
+	
+	try {
+		// check for the existence of the MDS database file; if it exists,
+		// assume that the databases have already been properly created
+	
+		// look for added/removed/changed plugins
+	
+		scanPluginDirectory();
+	}
+	catch (...) {
+		releaseLock();
+		throw;
+	}
+
+	// release the exclusive lock
+	
+	releaseLock();
+}
+
+//
+// Update the databases due to added/removed/changed plugins. This obtains
+// an exclusive lock over the databases, if possible, and then scans the
+// module path. If the lock cannot be obtained, it does nothing. The intent
+// is that this will be called periodically, so a failure at any given time
+// is not a big deal and may simply imply that another process is already
+// updating the MDS databases.
+//
+
+void
+MDSSession::updateDatabases()
+{
+	// get the current time in the appropriate format
+	
+	struct timespec now;
+	getCurrentTime(now);
+	
+	if (!intervalHasElapsed(mLastScanTime, now, kScanInterval))
+		// its not yet time to rescan
+		return;
+		
+	// regardless of what happens, we don't want to scan again for a while, so reset
+	// the last scan time before proceeding
+	
+	mLastScanTime = now;
+
+	// obtain a lock to avoid having multiple processes scanning for changed plugins;
+	// if the lock cannot be obtained immediately, just return and do nothing
+	
+	if (!obtainLock())
+		return;
+
+	// we want to make sure that the lock gets released at all costs, hence
+	// this try block:
+	
+	try {
+		scanPluginDirectory();
+	}
+	catch (...) {
+		releaseLock();
+		throw;
+	}
+	
+	releaseLock();
+}
+
+//
+// Determine if a filesystem object is a bundle that should be considered
+// as a potential CDSA module by MDS.
+//
+
+static bool
+isBundle(const char *path)
+{
+	static const char *bundleSuffix = ".bundle";
+
+	int suffixLen = strlen(bundleSuffix);
+	int len = strlen(path);
+	
+	return (len >= suffixLen) && !strcmp(path + len - suffixLen, bundleSuffix);
+}
+
+//
+// Scan the module directory looking for added/removed/changed plugins, and
+// update the MDS databases accordingly. This assumes that an exclusive lock
+// has already been obtained, and that the databases and the required tables
+// already exist.
+//
+
+void
+MDSSession::scanPluginDirectory()
+{
+	printf("MDSSession::scanPluginDirectory\n");
+
+	// check the modification time on the plugin directory: if it has not changed
+	// since the last scan, we're done
+	
+	struct stat sb;
+	if (stat(kPluginPath, &sb)) {
+		// can't stat the plugin directory...
+		Syslog::warning("MDS: cannot stat plugin directory \"%s\"", kPluginPath);
+		return;
+	}
+
+	if (sb.st_mtimespec <= mLastScanTime)
+		// no changes, we're done until its time for the next scan
+		return;
+	
+	// attempt to open the plugin directory
+	
+	DIR *dir = opendir(kPluginPath);
+	if (dir == NULL) {
+		// no plugin directory, hence no modules. clear the MDS directory
+		// and log a warning
+		Syslog::warning("MDS: cannot open plugin directory \"%s\"", kPluginPath);
+		return;
+	}
+	
+	// build a list of the plugins are are currently in the directory, along with
+	// their modification times
+	
+	struct dirent *dp;
+	PluginInfoList pluginList;
+	
+	char tempPath[PATH_MAX];
+	
+	while ((dp = readdir(dir)) != NULL) {
+	
+		// stat the file to get its modification time
+		
+		strncpy(tempPath, kPluginPath, PATH_MAX);
+		strncat(tempPath, dp->d_name, PATH_MAX - strlen(kPluginPath));
+		
+		struct stat sb;
+		if (stat(tempPath, &sb) == 0) {
+			// do some checking to determine that this path refers to an
+			// actual bundle that is likely to be a module
+			if (isBundle(tempPath))
+				pluginList.push_back(new PluginInfo(tempPath, sb.st_mtimespec));
+		}
+	}
+	
+	closedir(dir);
+	
+	// step 1: for any plugin in the common relation which is no longer present,
+	// or which is present but which has been modified since the last scan, remove
+	// all its records from the MDS database
+		
+	removeOutdatedPlugins(pluginList);
+
+	// step 2: for any plugin present but not in the common relation (note it may
+	// have been removed in step 1 because it was out-of-date), insert its records
+	// into the MDS database
+
+	insertNewPlugins(pluginList);
+	
+	// free the list of current plugins
+	
+	for_each_delete(pluginList.begin(), pluginList.end());
+}
+
+void
+MDSSession::removeOutdatedPlugins(const PluginInfoList &pluginList)
+{
+	PluginInfoList::const_iterator it;
+	for (it = pluginList.begin(); it != pluginList.end(); it++)
+		fprintf(stderr, "%s\n", (*it)->name());
+}
+
+void
+MDSSession::insertNewPlugins(const PluginInfoList &pluginList)
+{
+}
+
diff --git a/cdsa/mds/MDSSession.h b/cdsa/mds/MDSSession.h
new file mode 100644
index 00000000..4bf21221
--- /dev/null
+++ b/cdsa/mds/MDSSession.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+
+#ifndef _MDSSESSION_H_
+#define _MDSSESSION_H_  1
+
+#include <Security/DatabaseSession.h>
+#include <Security/handleobject.h>
+#include <Security/mds.h>
+#include <map>
+#include <sys/stat.h>
+#include <list>
+
+typedef list<class PluginInfo *> PluginInfoList;
+
+class MDSSession: public DatabaseSession, public HandleObject
+{
+    NOCOPY(MDSSession)
+public:
+    MDSSession (const Guid *inCallerGuid,
+                const CSSM_MEMORY_FUNCS &inMemoryFunctions);
+    virtual ~MDSSession ();
+
+    void terminate ();
+    void install ();
+    void uninstall ();
+
+    void GetDbNames(CSSM_NAME_LIST_PTR &outNameList);
+    void FreeNameList(CSSM_NAME_LIST &inNameList);
+
+    // implement CssmHeap::Allocator
+    void *malloc(size_t size) { return mCssmMemoryFunctions.malloc(size); };
+    void free(void *addr) { mCssmMemoryFunctions.free(addr); }
+	void *realloc(void *addr, size_t size) { return mCssmMemoryFunctions.realloc(addr, size); }
+
+private:
+	bool obtainLock(int timeout = 0);
+	void releaseLock();
+
+	void initializeDatabases();
+	void updateDatabases();
+
+	void scanPluginDirectory();
+	void removeOutdatedPlugins(const PluginInfoList &pluginList);
+	void insertNewPlugins(const PluginInfoList &pluginList);
+
+    const CssmMemoryFunctions mCssmMemoryFunctions;
+    Guid mCallerGuid;
+    bool mCallerGuidPresent;
+	
+	struct timespec mLastScanTime;
+	int mLockFd;
+};
+
+#endif //_MDSSESSION_H_
diff --git a/cdsa/mds/NOTES b/cdsa/mds/NOTES
new file mode 100644
index 00000000..3186cb30
--- /dev/null
+++ b/cdsa/mds/NOTES
@@ -0,0 +1,85 @@
+MDS RELEASE NOTES
+
+This implementation of MDS is based on the idea that there
+is no separate module installation process. Instead, MDS
+interacts with modules as follows:
+
+-	Each module bundle contains a resource which is simply
+	an MDS database containing the records specific to that
+	module.
+	
+-	Placing a module bundle into the designated path makes
+	that module eligible to be registered with MDS.
+	
+-	Clients which utilize MDS will, when initializing MDS and
+	then periodically thereafter, scan the module path and
+	dynamically update the MDS database entries to reflect
+	added, removed, or changed modules.
+	
+The scanning of the module path is done implicitly within
+MDS API functions.
+
+DETECTING CHANGED MODULES
+
+MDS uses the following algorithm to detect added, removed,
+or changed modules:
+
+1.	stat() the directory in which modules are located. If
+	its modification time is no later than the last time
+	a scan was performed, stop.
+	
+2.	Read the contents of the module directory with readdir().
+	Build a list of the directory contents, including the
+	modification time of each bundle as returned by stat().
+	
+3.	Remove all MDS records for modules which are no longer
+	present, or which have changed since the last scan.
+	
+4.	Insert MDS records for modules which are now present but
+	not represented in the database, including those whose
+	records were deleted in step 3.
+	
+This strategy has several implications:
+
+-	Changing the contents of a module bundle will not change
+	the module directory's modification time, and so will not
+	trigger an update of the database. To cause an update when
+	modifying a module, that module must be removed from the
+	directory and then its new version must be placed into the
+	directory.
+
+-	No single process which is a client of MDS will attempt a
+	rescan more often than once per 10 seconds. This means that
+	it might take up to 10 seconds for MDS to sync after a
+	change occurs.
+	
+-	Since any MDS client process can initiate a rescan, but no
+	two processes should be updating the database at the same
+	time, we use a lock file in /var/tmp to ensure only one
+	process is scanning at any one time.
+
+DEVIATIONS FROM THE SPEC
+
+In addition to those differences noted above, this MDS
+implementation deviates from the specification in the following
+ways:
+
+MDS_Initialize()
+
+	As part of initiating a client's connection to MDS, this
+	function creates the MDS databases (if needed) and rescans
+	the module path.
+
+MDS_Install()
+
+	This call is specified to create the MDS databases. Since it
+	can only be called with an MDS_HANDLE obtained from a prior
+	call to MDS_Initialize(), which already creates the databases
+	implicitly, MDS_Install() does nothing and silently returns
+	success in this implementation.
+	
+MDS_Uninstall()
+
+	This call is specified to delete the MDS databases. In this
+	implementation, it does nothing and throws the error
+	CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED.
diff --git a/cdsa/mds/mds.mcp b/cdsa/mds/mds.mcp
new file mode 100644
index 0000000000000000000000000000000000000000..b5280072084f8f9de345dfcdb92e3c58c3404867
GIT binary patch
literal 28375
zcmeHQeQaCTb-(YClq^ejY$wfEZHJDX*o_sXi{r#$Vn-77VMU_FNOG<2OQNV}iHS%G
zB$YVrwrcCg)^<e#EJKE2Z4qqg2MP@7mZ89gq3ecWMYCbqGN5R-t{qTd?b3DoqaDyc
zGVk}h_mI4#_#P?SEj)<_IQN`;?s@0ld+xdS-TU<Tl+Nc@lu{w3oMTF5=9GH!*Odw<
zA?tHo2gE=;zvx{^6$+VrA(|}YpY+nDa?!S+*~MaSEWTDO<+IUo@7ZVag~g)M!hv+!
zD;A^4RB2fxGpWLoSBg%1rBWuhB*Kx*iWg0!R#&T{!L`iFVs!XYsgM$-A#Y)AX~`=@
zjR{jhML4yVD`m2tkv@28Jjy{C^>S6gP^OqF7QO7kidU#gM_2L-sg>yDDz47F&n}tB
z<eswg<&ibLy)S<JIO@o*qUmBTu4M>>T(ukVkpvoJs!OEOlhe_J2M53-Id8>?lc{1F
zEvU66!dhd=WW2Up6m0AkrH#AA61!W>Cx=I*9n47d>OP`$pqRCrI_15u+D_4p>cN}H
z6iYPIC=6otQ4nho1hEY<5UUS?SY@!Q5m1#`0T8Pjf1R)QlNL5|lP;)wNoOs;#LO_;
z!zChnuwvDLk2M_kSc73N%W4d9jI3CWF~6ZN6gKP&3#`5{D+8_#+5JLU&2YzRMw??h
zonI@Yz35EA^NNb5^nhUEGOlN^ST5u*wWd_RSoj&Mi5x$r`e^dgtBo)}t(vIwQ>sK_
zIqI4!O33=@*%2G0Q#0~GiW{OKNLeBzNTnPpemZrtB3P{w;J#{R+4L*kIHUYDDKF2S
zAf1-{N&_wXmC8;0N)^t=poTT`JFczHT0cWIGx;a7CFz9K9l$Q&PGC2X8>BF>2e=Ek
z8%XE?Mu6B?sT+WMfO~=afHwkf0=@%yGw>GRt-#xWF7Qs^Vc-$qUBJ76`+;`=j{>nz
zQ||)46L<(11s(+613V7w1>Otn1KtOGH}GeG_XAG=9{`>N9sr&JJ_hUu4gd#%r+|+D
z<G>-{Fz_MZqrlU^7;pqQ3OoxO13nHM2TlMJz;nO{fe!<32VN_nzv(0Tm42s>>FY*g
zV~<HIV*oROz_E(50YHvV2Dpyue`LZ!=OL=X@Y9-~L^_Wq{-NkGuhu`Qj(p(v-@0__
zC3R~2@@2*jP1A>rk@x6cGOpM|#uj_S_+sQSrsxI6l_|d<`Mr|AMMop!%9KwCP3T%U
zKCDftN$okMk~*@LdP4N3#NK|PT6-3$1H2K)qd^E521bB8fL*}-zyrXYz;0j<a2Iel
z@CM)>;9lT9;6dPFV3d`B>f!vrWilI5Ogyc@Lfr@<Xb<GoBHa=SDFQ|u0CQR^f@T}O
zVgz{>Q7%fxv#h5UT-e||3<B0l;M^|T;hbf>5;%t#w*<z486Blk;2FmRMh)Yc@S8xc
zIfPFFx%LqL7-%9vslNlywTSRdpotWvegK|v1#sAw-I`Sn<CyaS;M|FXYZJiXT;&=C
za5#S%hX5yygliVS;h~Rf7r^-#6800|`~ec$1vsxF;hF|;zJi2n8^HNTBwXVF&UcW=
zy5Rf|c&=ptmwgo<yQEyB0Pej=xW)n80VG@t0q!)CC^_(pNDgUMxtBoMH-P&IB%H4R
zmp(kAS>^r_=v~6U2Fi67;J%53V+L^l1IaPXD)((ruDgH`eRhv#RfugrE<D%SUg3v9
z*=|7Sy-4~rt3q5i?i2o3K)F5xLN6lW^?=Z4kle3X6=FNNZUaJpiG=GnAoK<juH%3Z
z{rR9~RS4^mUavvI^fA|SKzI-d#~2V^LK4%g3O@(R^&SxZ6C{jLK$w0wtyvXe{PJD_
zh_J7`X8<CM;eK-9>2r<^Ao4O2)(41u6-ivPD)N2MA;WhtrsyL;2ir2DS=B*bjSBxk
z(6hpS7IaMb*Fhf_p5roZ_|7Qkgz){K3E>$VjA=mUN0G4ITMBrZRU?@~k<T5LvR<yF
zVyV9TT1ic07NTR>)qJ58<uN^xykKVsQ!6X^d@g#{TUk|!3sJMj)ruEzEY`<%=CHj|
z*vHwInjI>4^|A-7Kk?L@Z0b)iwI`LD6G`RdAqNUpQQqK^ui3~_uwlb$HHvI`gITwM
zH`&TYU5>N$ht~SX6g3;op;RfgkScn8%W7yLp3jxMOQpW_>Z+Av$+=Y46R~C~n_S>S
zG?7Y%@+a23!m}baJf+j=WiOi&v1FF{G$OT{(bB}wv|YcIT~^3c8p_7md0m>wFRrba
z7NSgYsJ7fYUWB?-OeYobvWnIA+REy(O21Jc9S3LiyqeSc)xM*k+<CB8@2fdnVf8;|
z^_b1I^U$=rTrRfzQSElQwBm(WMUO?+biz@jI%Omy(ZU=M#}+jkpB$;o8!fL+BYly6
zv;eL=jmVb6oqSEWQ?Mc2>n<*zx5{CU;_CS+mhei2{4-wRsbX}xl*%op3X7<Dp^z#(
z8%s=2MDfrsHkiqk`956ThjO^E*@e~1tc!H-rq@=v0L4r_8Lt?VhYDpHMJ>8Uk(Vp2
zc^p$&7n(egP_gs5%+p?>m|C%FoGz^`RO?URajogq^u(O5dQPurynv65bYrH+CeP1S
z`XbJ$&DZ4W8edxn+zJZ~YJtNmR<w#=bK+ICYDZdhB&N-jm&Q};nP*qITGi%t%*XW8
z$dY;77(?(ZuBA&wGv(7*Xy(>RnUzclqt}Xq$FLR_E~e6+_Hy&~4i)mNV>#)K3Akx5
zT^{MW*nr1|CgeW9rEcR_+Zjg;L_l5PxzFPMjllh2SaW7COFaVjh#i_Ud$La9r$D(U
zC(Hx8$N;#X+Nn9EilE)Xe+aZk_!mHT3I7tPoIlhT!QUYAFN4bYL;WpyIe(~s0l!al
zz6;7e5Pl3SpFe1?eEzr%eEIxw7x?n|gL~y$fdGelQ0f63?j7k1fb+9R<ow}030}@0
z&NJW-00GXgA(8Wk^E`Mte>lGfJ_-al+@BuOta4rfy;Jx<2R$r2_rgbn|0htk72y0U
zlDjploVP%a3eU6AF~jr3T|R%f^w~WkXB)XE2k3KBukhT{%lX6QzFE#6?s@R{iOvG(
zyM@09D(4UPDe!XsaOsB=qVo|@`V`>)7Lt>iRqm%j<^17(9{fWh{}QO2Kit0p|FFnk
z2j!k0;QlibIe)m{125+f_ebDQ0|9)}P(FWz7$b822yq<xfq)SEF`!u$V)>x(-1l?r
z0imBmGNf5^4jUGpXO|J-KMXo5Jo|W7_}>Mk9|55+AYlvvLVt>6T(c_l8mO#Gp|69N
z^GAp=%ys}mZzGZOM|cPLB&C>^dyqV#Srujsa_#}b??N)ISrz7Z%?SS@D8~{IW?k>m
ztO|bz^n&p8;jG~!oQv-jo@2te2Sn0H=odhwh~(!rt0KP&`U}Fp0Q!r<Gv?=n{~OSG
z;eP;{GJHoAlx+oca9mgipo3$ws9DuPd!Fz)P{tpi<5NhMG^;w^09_XTTc8=kx6=k5
z;Jo0Pc_Z*9;5&fyy9=bx<3P@D&g&CE&f}9n&fAB8j0w(9jvL33^ON(E<1!Cq+;J>9
zKRGYY06EY4ft+_7TgL1(kYmR2Wt=ePIG!A9#v<<z5g_jYHv?}0-U{pn_5m6D2Y?5G
zcL1ZnL%=(Mhk-|ccLDDPGUhpNb^{$?2si}X3FQ1_{K{Ha^X!~!=W!s{O0JP%Am;<;
z0pq^|I1KCrjsR~1-VW>nat+{o=N#i)=Nvx=<eW|dM}eHjoZIgNa*lHDody2H0G((5
z?{}DT%!Sc8D?zb~><J$|b2Sve(3cPR=v6F2kG?zUqi5UWm_O*FXWOIS9`@0*?Qtw(
zK6<u2#=;{$dbT~r-=jWywmru0X&*h?9>@Gl3wn&*$9(kcdO2VEee~>lIUfdm^lW=v
zF9v<|Y<pZ&;y!w|J+3=LK6<u2&hG^uJ=-4FfV7XEZIA1ON4<W|Ifr3e0b4H$>5}M$
z1N6AYEVp3qP>Xt8!!9<f7dmaYIuCH*IX5+Z_2l>0E?@qg=daFW`|2&~0j>-B&zY6}
zVMPGH`0B~;eFL|PU#iI4%=YpC{$Q*lVSDv@LvMHShSd^ie^J@Gz+&}w)75D!=6Gdf
zYI2f?jS7TDr_OU{O>jEQGhwhhN5&?Galws3U7=y2JA@t(TGsE8{4Sw42;FN{<943)
zQj2(ojC#7H+z}cQ8WCD9-!J)Yp}U3d5xUQ^AMUC=5=9MViw8yXu+XUPpV;es<+oqg
z`2c&k0XjHbaZBFO&*KV$ndi7Rv^_u%Tn2#fRTd{!`@kQ63@T;Pm8fh-&31|yiHndG
z7mLHWr!$3oj_(pY9OGZliZQiOvYouN{rW0#!Od}by{M0i_NuY{!lHa1iCA&5;Sa~#
z&@J1#%iOwiz3A7E;q-bTd+7FFVp|7BH7+`=^`iDZ5+BQ@SJoEsX3%zb)wb%ttQVa;
zk;sn-%kPS9D?hY5TlIi-9|@bdn4XBKpf?uVYev<3TbHxqBEmoLoA=N0u4ehg*{$34
zcF)=#*x&(1euH19Z_wMag6cDg_StjG4svT9<Gq0|l_4aAYwfzW);93~UKWd(-@{#T
zhaUqBB$IgM&sm@Siz_x$xsdiMne)!`PM7=sN?tS0dTsuybC?`m=Hon*_+{V~LB$LF
z195n0VstkBRA!MsHM%g3A3b%NzZ*MqbD11|E0S8l2Zyexp1EQvRk*@7qQbd3{QM-F
z$)!qHR=rP~H+I-Z@fwINukJR>n(^(<^U1Nk)q;01bE$DHdI{7^p{v5@^0{CSIEh5E
z(AZGx(tfCJ_&sR-<#(9bQ!n0Jeje%rtE(%UyK190?IaQtd}%ol@CQ-*N3RWa6Uhm_
zBpe7W*|`uO3N+F};XHIE2Op0%Q?2_Qa6|RvM1G-R!6t<B(4Cr|if`hQhN`qPGdw%f
zx4?JH{h{Uu%|2?{PTHqX#5KQ#_E9x<j`KxwUufM<aD!U6v+COx7Hq;!prMxSc$Wh0
z1U6O*wV#8By=lMpz?Qbtq&4W5^|SZJtuuD;(Y^p^-A+2NXU+V)jy9O~q?dytv2{DE
zYXRM&p9B3<X-|`T3O^{&40OMWp8Oc7nYMrVVm=+%C;uy}CG%hl#X|5Tt*ZNSv{PJO
zX}Ye~eQcqjy&_)9XjotgTd_m+J~+v`Y}0H~uIS4LU)sujhZg$qi}9wN3#e*d%KENy
z&}hf(Z1l!itk#jv>uqOqUEXo8!HRH|gQ<sY9%(Bxux^YSW}7~PK6t%F#wPc?c*xkW
z<M@uuruMx4cCOK$_qvSuCM#;?p6u%#xwof-?(Ei{uBn~i2DRRv;7!yf>;xKW+0IXU
zkLly*J(wz++hh6|s@Q3DkJ-#li+fBTGwYT1w7AD?YNypbW@AH@_FRKIirHhLg8_h6
z@Jl{{z|Z^yDxh$~r+^w<@c(?T+IYaw&rR-CeeKX?KdrrLE90fxa~<tfTmGdD8{USt
z2ihLk(jMqMk^MIJCH&iH=ZUBP+g=|!Pk8IPXe%fDEnE$lKabRi+L=vyVD2jaJh#c}
z8mT+@*h6SzL5QEI+}?m+WzY*jf8pi#{I1nAkWD$;vHt4q;&VBCVMAWp*p!_urhL=U
z_~g*=(df~kftdl2<XC*>=oaf^aCe+z{MkshSgJeI?K+Fs4Avp9`-^WE^c~7`wRZP@
zwQ5Iyc1?<JgS><GVaJx=0l7;#?AY={kVjOur2o=v-7<E54hGjD=PF~#cO64Mnk^OC
zPD|cR`5x$JYUMrmB0rlgt?+rdt<TSJ9YcGdZ@1@ew8!nut`_U$$9@R;{%mQfu3z2r
zRXgA+(ES@=cVzL|=ZZ)(-Oq!(kWJP9Wxe+~G_OB7f&YEvKKEhh@RL@6@t2XD;%f-X
zeQ^<dFQxd>)jlRh{_QV<XFmZwN04-7^X!)mJ+!$)>pNdw2G38C0eU`x<aT4{@B`rK
z7r?!LkFT74*U0yN9Rhx`4AB22jPFfGeltJ8B`<}Ke-j@F_@R-<W*~or+W7hxHbqXS
zkw5w=2p-j9HTMq~_dQzfT;wOjP8<2iYxJ{`&r<h{k@tKS)YR*I=7Zqnot~aQ1HaSg
zf0Uni>IVXP{+fxAzx-+N1C&C9dev?%cOU1cs0Jy;SHu1t?d&l6U!i~ETC93+0X<{n
z=jXu7n*%-H0&na%FL7=R0|ATw20L#W{kPaJd0H{{pWqja{O$h&Pu~H0C>MY3dK3Iv
zN-?yIRnsrG?`z=4D8=yeGiTDTU*@NqSO>`@lCK&2-}o{3aZ2$;B>2a<Rm<H`+Mdv2
rwe$w)=ZyaP$H6Czyf+1^UwgsVGTE<lM!x)hjEmI!%Kt*f`qcjcq|<e{

literal 0
HcmV?d00001

diff --git a/cdsa/mds/mdsapi.cpp b/cdsa/mds/mdsapi.cpp
new file mode 100644
index 00000000..e1098f81
--- /dev/null
+++ b/cdsa/mds/mdsapi.cpp
@@ -0,0 +1,395 @@
+/*
+ * 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.
+ */
+
+
+/*
+
+   File:      mds.h
+
+   Contains:  Module Directory Services Data Types and API.
+
+   Copyright: (c) 1999 Apple Computer, Inc., all rights reserved.
+
+   This is the C API wrapper for the C++ MDS implementation.  Most of this file
+   could also be generated by the same perl script that generates the plugin
+   C wrapper code.
+
+ */
+
+#include "MDSSession.h"
+
+#include <memory>
+
+using namespace std;
+
+static CSSM_RETURN CSSMAPI cssm_DataGetFirst(CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_QUERY *Query,
+         CSSM_HANDLE_PTR ResultsHandle,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId)
+{
+  BEGIN_API
+  if (!(Required(ResultsHandle) = findHandle<MDSSession>(DLDBHandle.DLHandle).DataGetFirst(DLDBHandle.DBHandle,
+			DLQuery::optional(Query),
+			Attributes,
+			CssmData::optional(Data),
+			Required(UniqueId))))
+	return CSSMERR_DL_ENDOFDATA;
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DataModify(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_RECORDTYPE RecordType,
+         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecordIdentifier,
+         const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified,
+         const CSSM_DATA *DataToBeModified,
+         CSSM_DB_MODIFY_MODE ModifyMode)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).DataModify(DLDBHandle.DBHandle,
+			RecordType,
+			Required(UniqueRecordIdentifier),
+			AttributesToBeModified,
+			CssmData::optional(DataToBeModified),
+			ModifyMode);
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_GetDbNameFromHandle(CSSM_DL_DB_HANDLE DLDBHandle,
+         char **DbName)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).GetDbNameFromHandle(DLDBHandle.DBHandle,
+			DbName);
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DataAbortQuery(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_HANDLE ResultsHandle)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).DataAbortQuery(DLDBHandle.DBHandle,
+			ResultsHandle);
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DestroyRelation(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_RECORDTYPE RelationID)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).DestroyRelation(DLDBHandle.DBHandle,
+			RelationID);
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DataDelete(CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_DB_UNIQUE_RECORD *UniqueRecordIdentifier)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).DataDelete(DLDBHandle.DBHandle,
+			Required(UniqueRecordIdentifier));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DataInsert(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_RECORDTYPE RecordType,
+         const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes,
+         const CSSM_DATA *Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).DataInsert(DLDBHandle.DBHandle,
+			RecordType,
+			Attributes,
+			CssmData::optional(Data),
+			Required(UniqueId));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DataGetFromUniqueRecordId(CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_DB_UNIQUE_RECORD *UniqueRecord,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).DataGetFromUniqueRecordId(DLDBHandle.DBHandle,
+			Required(UniqueRecord),
+            Attributes,
+			CssmData::optional(Data));
+  END_API(MDS)
+}
+
+#if 0
+static CSSM_RETURN CSSMAPI cssm_GetDbOwner(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_ACL_OWNER_PROTOTYPE_PTR Owner)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).GetDbOwner(DLDBHandle.DBHandle,
+			Required(Owner));
+  END_API(MDS)
+}
+#endif
+
+static CSSM_RETURN CSSMAPI cssm_CreateRelation(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_RECORDTYPE RelationID,
+         const char *RelationName,
+         uint32 NumberOfAttributes,
+         const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
+         uint32 NumberOfIndexes,
+         const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).CreateRelation(DLDBHandle.DBHandle,
+			RelationID,
+			RelationName,
+			NumberOfAttributes,
+			Required(pAttributeInfo),
+			NumberOfIndexes,
+			Required(pIndexInfo));
+  END_API(MDS)
+}
+
+#if 0
+static CSSM_RETURN CSSMAPI cssm_GetDbAcl(CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_STRING *SelectionTag,
+         uint32 *NumberOfAclInfos,
+         CSSM_ACL_ENTRY_INFO_PTR *AclInfos)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).GetDbAcl(DLDBHandle.DBHandle,
+			SelectionTag,
+			Required(NumberOfAclInfos),
+			Required(AclInfos));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_ChangeDbOwner(CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_ACL_OWNER_PROTOTYPE *NewOwner)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).ChangeDbOwner(DLDBHandle.DBHandle,
+			AccessCredentials::required(AccessCred),
+			Required(NewOwner));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_PassThrough(CSSM_DL_DB_HANDLE DLDBHandle,
+         uint32 PassThroughId,
+         const void *InputParams,
+         void **OutputParams)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).PassThrough(DLDBHandle.DBHandle,
+			PassThroughId,
+			InputParams,
+			OutputParams);
+  END_API(MDS)
+}
+#endif
+
+static CSSM_RETURN CSSMAPI cssm_FreeUniqueRecord(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecord)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).FreeUniqueRecord(DLDBHandle.DBHandle,
+			Required(UniqueRecord));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DbOpen(CSSM_DL_HANDLE DLHandle,
+         const char *DbName,
+         const CSSM_NET_ADDRESS *DbLocation,
+         CSSM_DB_ACCESS_TYPE AccessRequest,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const void *OpenParameters,
+         CSSM_DB_HANDLE *DbHandle)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLHandle).DbOpen(DbName,
+			DbLocation,
+			AccessRequest,
+			AccessCredentials::optional(AccessCred),
+			OpenParameters,
+			Required(DbHandle));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DataGetNext(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_HANDLE ResultsHandle,
+         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
+         CSSM_DATA_PTR Data,
+         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId)
+{
+  BEGIN_API
+  if (!findHandle<MDSSession>(DLDBHandle.DLHandle).DataGetNext(DLDBHandle.DBHandle,
+			ResultsHandle,
+			Attributes,
+			CssmData::optional(Data),
+			Required(UniqueId)))
+	return CSSMERR_DL_ENDOFDATA;
+  END_API(MDS)
+}
+
+#if 0
+static CSSM_RETURN CSSMAPI cssm_DbDelete(CSSM_DL_HANDLE DLHandle,
+         const char *DbName,
+         const CSSM_NET_ADDRESS *DbLocation,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLHandle).DbDelete(DbName,
+			DbLocation,
+			AccessCredentials::optional(AccessCred));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DbCreate(CSSM_DL_HANDLE DLHandle,
+         const char *DbName,
+         const CSSM_NET_ADDRESS *DbLocation,
+         const CSSM_DBINFO *DBInfo,
+         CSSM_DB_ACCESS_TYPE AccessRequest,
+         const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry,
+         const void *OpenParameters,
+         CSSM_DB_HANDLE *DbHandle)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLHandle).DbCreate(DbName,
+			DbLocation,
+			Required(DBInfo),
+			AccessRequest,
+			CredAndAclEntry,
+			OpenParameters,
+			Required(DbHandle));
+  END_API(MDS)
+}
+#endif
+
+static CSSM_RETURN CSSMAPI cssm_GetDbNames(CSSM_DL_HANDLE DLHandle,
+         CSSM_NAME_LIST_PTR *NameList)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLHandle).GetDbNames(Required(NameList));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_DbClose(CSSM_DL_DB_HANDLE DLDBHandle)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).DbClose(DLDBHandle.DBHandle);
+  END_API(MDS)
+}
+
+#if 0
+static CSSM_RETURN CSSMAPI cssm_ChangeDbAcl(CSSM_DL_DB_HANDLE DLDBHandle,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred,
+         const CSSM_ACL_EDIT *AclEdit)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).ChangeDbAcl(DLDBHandle.DBHandle,
+			AccessCredentials::required(AccessCred),
+			Required(AclEdit));
+  END_API(MDS)
+}
+
+static CSSM_RETURN CSSMAPI cssm_Authenticate(CSSM_DL_DB_HANDLE DLDBHandle,
+         CSSM_DB_ACCESS_TYPE AccessRequest,
+         const CSSM_ACCESS_CREDENTIALS *AccessCred)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLDBHandle.DLHandle).Authenticate(DLDBHandle.DBHandle,
+			AccessRequest,
+			AccessCredentials::required(AccessCred));
+  END_API(MDS)
+}
+#endif
+
+static CSSM_RETURN CSSMAPI cssm_FreeNameList(CSSM_DL_HANDLE DLHandle,
+         CSSM_NAME_LIST_PTR NameList)
+{
+  BEGIN_API
+  findHandle<MDSSession>(DLHandle).FreeNameList(Required(NameList));
+  END_API(MDS)
+}
+
+static MDS_FUNCS gMDSFunctionTable =
+{
+    cssm_DbOpen,
+    cssm_DbClose,
+    cssm_GetDbNames,
+    cssm_GetDbNameFromHandle,
+    cssm_FreeNameList,
+    cssm_DataInsert,
+    cssm_DataDelete,
+    cssm_DataModify,
+    cssm_DataGetFirst,
+    cssm_DataGetNext,
+    cssm_DataAbortQuery,
+    cssm_DataGetFromUniqueRecordId,
+    cssm_FreeUniqueRecord,
+    cssm_CreateRelation,
+    cssm_DestroyRelation,
+};
+
+
+#ifdef __MWERKS__
+#pragma export on
+#endif
+
+CSSM_RETURN CSSMAPI
+MDS_Initialize (const CSSM_GUID *inCallerGuid,
+                const CSSM_MEMORY_FUNCS *inMemoryFunctions,
+                MDS_FUNCS_PTR outDlFunctions,
+                MDS_HANDLE *outMDSHandle)
+{
+    BEGIN_API
+    Required (outDlFunctions);
+    Required (outMDSHandle) = (new MDSSession (Guid::optional(inCallerGuid),
+                                               Required(inMemoryFunctions)))->handle ();
+    *outDlFunctions = gMDSFunctionTable;
+    END_API(MDS)
+}
+
+CSSM_RETURN CSSMAPI
+MDS_Terminate (MDS_HANDLE inMDSHandle)
+{
+    BEGIN_API
+    auto_ptr<MDSSession> aMDSSession (&killHandle<MDSSession> (inMDSHandle));
+    aMDSSession->terminate (); // Even if terminate throws the MDSSession object will be deleted.
+    END_API(MDS)
+}
+
+CSSM_RETURN CSSMAPI
+MDS_Install (MDS_HANDLE inMDSHandle)
+{
+    BEGIN_API
+    findHandle<MDSSession> (inMDSHandle).install ();
+    END_API(MDS)
+}
+
+CSSM_RETURN CSSMAPI
+MDS_Uninstall (MDS_HANDLE inMDSHandle)
+{
+    BEGIN_API
+    findHandle<MDSSession> (inMDSHandle).uninstall ();
+    END_API(MDS)
+}
+
+#ifdef __MWERKS__
+#pragma export off
+#endif
diff --git a/checkpw/checkpw.c b/checkpw/checkpw.c
new file mode 100644
index 00000000..ab9d56cf
--- /dev/null
+++ b/checkpw/checkpw.c
@@ -0,0 +1,252 @@
+/*
+ * 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.
+ */
+
+/*
+ *  checkpw.c
+ *  utility to authenticate users using crypt with a fallback on Directory Services
+ *
+ *    Copyright:  (c) 2000 by Apple Computer, Inc., all rights reserved
+ *
+ */
+
+#include <pwd.h>
+#include <stddef.h>		// for offsetof()
+#include <stdlib.h> // for malloc()
+#include <string.h> // for strcmp()
+#include <time.h>
+#include <unistd.h> // for crypt()
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+#include <mach/message.h>
+#include <servers/bootstrap.h>
+#include "checkpw.h"
+
+// begin copied from SharedConsts.h
+typedef struct {
+	unsigned int	msgt_name : 8,
+					msgt_size : 8,
+					msgt_number : 12,
+					msgt_inline : 1,
+					msgt_longform : 1,
+					msgt_deallocate : 1,
+					msgt_unused : 1;
+} mach_msg_type_t;
+
+typedef struct sObject
+{
+	unsigned long	type;
+	unsigned long	count;
+	unsigned long	offset;
+	unsigned long	used;
+	unsigned long	length;
+} sObject;
+
+typedef struct sComData
+{
+	mach_msg_header_t	head;
+	mach_msg_type_t		type;
+	unsigned long		fDataSize;
+	unsigned long		fDataLength;
+	unsigned long		fMsgID;
+	unsigned long		fPID;
+	unsigned long		fPort;
+	sObject				obj[ 10 ];
+	char				data[ 1 ];
+} sComData;
+
+#define kMsgBlockSize	(1024 * 4)					// Set to average of 4k
+#define kObjSize		(sizeof( sObject ) * 10)	// size of object struct
+#define kIPCMsgLen		kMsgBlockSize				// IPC message block size
+
+#define kIPCMsgSize	sizeof( sIPCMsg )
+
+typedef struct sIPCMsg
+{
+	mach_msg_header_t	fHeader;
+	unsigned long		fMsgType;
+	unsigned long		fCount;
+	unsigned long		fOf;
+	unsigned long		fMsgID;
+	unsigned long		fPID;
+	unsigned long		fPort;
+	sObject				obj[ 10 ];
+	char				fData[ kIPCMsgLen ];
+	mach_msg_security_trailer_t	fTail;
+} sIPCMsg;
+
+typedef enum {
+	kResult					= 4460,
+	ktDataBuff				= 4466,
+} eValueType;
+
+enum eDSServerCalls {
+	/*  9 */ kCheckUserNameAndPassword = 9
+};
+// end copied from SharedConsts.h
+
+int checkpw( const char* userName, const char* password )
+{
+	int siResult = CHECKPW_FAILURE;
+	struct passwd* pw = NULL;
+	kern_return_t	result = err_none;
+	mach_port_t		bsPort = 0;
+	mach_port_t		serverPort = 0;
+	mach_port_t		replyPort = 0;
+	const char *const srvrName = "DirectoryService";
+	sIPCMsg*		msg = NULL;
+	unsigned long	len = 0;
+	long			curr = 0;
+	unsigned long	i = 0;
+
+	pw = getpwnam( userName );
+	if (pw == NULL)
+	{
+		return CHECKPW_UNKNOWNUSER;
+	}
+	
+	
+	do {
+		// Special case for empty password (this explicitly denies UNIX-like behavior)
+		if (pw->pw_passwd == NULL || pw->pw_passwd[0] == '\0') {
+			if (password == NULL || password[0] == '\0')
+				siResult = CHECKPW_SUCCESS;
+			else
+				siResult = CHECKPW_BADPASSWORD;
+				
+			break;
+		}
+
+		// Correct password hash
+		if (strcmp(crypt(password, pw->pw_passwd), pw->pw_passwd) == 0) {
+			siResult = CHECKPW_SUCCESS;
+			break;
+		}
+
+		// Special marker for Directory Services 
+		if (strcmp(pw->pw_passwd,"********") != 0) {
+			siResult = CHECKPW_BADPASSWORD;
+			break;
+		}
+
+		result = mach_port_allocate( mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &replyPort );
+		if ( result != err_none ) {
+			siResult = CHECKPW_FAILURE;
+			break;
+		}
+
+		result = task_get_bootstrap_port( mach_task_self(), &bsPort );
+		if ( result != err_none ) {
+			siResult = CHECKPW_FAILURE;
+			break;
+		}
+
+		// check if DirectoryService is alive
+		result = bootstrap_look_up( bsPort, (char *)srvrName, &serverPort );
+		if ( result != err_none ) {
+			siResult = CHECKPW_FAILURE;
+			break;
+		}
+
+		// ask directory services to do auth
+		msg = calloc( sizeof( sIPCMsg ), 1 );
+		if ( msg == NULL ) {
+			siResult = CHECKPW_FAILURE; // memory error
+			break;
+		}
+
+		// put username and password into message
+		msg->obj[0].type = ktDataBuff;
+		msg->obj[0].count = 1;
+		msg->obj[0].offset = offsetof(struct sComData, data);
+
+		// User Name
+		len = strlen( userName );
+		memcpy( &(msg->fData[ curr ]), &len, sizeof( unsigned long ) );
+		curr += sizeof( unsigned long );
+		memcpy( &(msg->fData[ curr ]), userName, len );
+		curr += len;
+
+		// Password
+		len = strlen( password );
+		memcpy( &(msg->fData[ curr ]), &len, sizeof( unsigned long ) );
+		curr += sizeof ( unsigned long );
+		memcpy( &(msg->fData[ curr ]), password, len );
+		curr += len;
+		msg->obj[0].used = curr;
+		msg->obj[0].length = curr;
+		
+		msg->fHeader.msgh_bits			= MACH_MSGH_BITS( MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND );
+		msg->fHeader.msgh_size			= sizeof( sIPCMsg ) - sizeof( mach_msg_security_trailer_t );
+		msg->fHeader.msgh_id			= kCheckUserNameAndPassword;
+		msg->fHeader.msgh_remote_port	= serverPort;
+		msg->fHeader.msgh_local_port	= replyPort;
+	
+		msg->fMsgType	= kCheckUserNameAndPassword;
+		msg->fCount		= 1;
+		msg->fOf		= 1;
+		msg->fPort		= replyPort;
+		msg->fPID		= getpid();
+		msg->fMsgID		= time( NULL ) + kCheckUserNameAndPassword;
+			
+		// send the message
+		result = mach_msg_send( (mach_msg_header_t*)msg );
+		if ( result != MACH_MSG_SUCCESS ) {
+			siResult = CHECKPW_FAILURE;
+			break;
+		}
+			
+		// get reply
+		memset( msg, 0, kIPCMsgLen );
+	
+		result = mach_msg( (mach_msg_header_t *)msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT,
+							0, kIPCMsgSize, replyPort, 300 * 1000, MACH_PORT_NULL );
+
+		if ( result != MACH_MSG_SUCCESS ) {
+			siResult = CHECKPW_FAILURE;
+			break;
+		}
+
+		if ( msg->fCount != 1 ) {
+			// couldn't get reply
+			siResult = CHECKPW_FAILURE;
+			break;
+		}
+
+		for (i = 0; i < 10; i++ )
+		{
+			if ( msg->obj[ i ].type == (unsigned long)kResult )
+			{
+				siResult = msg->obj[ i ].count;
+				break;
+			}
+		}
+		
+	} while (0);
+	
+	if (msg != NULL) {
+		free(msg);
+		msg = NULL;
+	}
+	
+	if ( replyPort != 0 )
+		mach_port_deallocate( mach_task_self(), replyPort );
+	
+	if (pw)
+		endpwent();
+
+	return siResult;
+}
\ No newline at end of file
diff --git a/checkpw/checkpw.h b/checkpw/checkpw.h
new file mode 100644
index 00000000..97d34175
--- /dev/null
+++ b/checkpw/checkpw.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/*
+ *  checkpw.h
+ *  utility to authenticate users using crypt with a fallback on Directory Services
+ *
+ *    Copyright:  (c) 2000 by Apple Computer, Inc., all rights reserved
+ *
+ */
+
+#ifndef __CHKUSRNAMPASSWD_H__
+#define __CHKUSRNAMPASSWD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+	CHECKPW_SUCCESS = 0,
+	CHECKPW_UNKNOWNUSER = -1,
+	CHECKPW_BADPASSWORD = -2,
+	CHECKPW_FAILURE = -3
+};
+
+// prototypes
+int checkpw( const char* userName, const char* password );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __CHKUSRNAMPASSWD_H__
diff --git a/symbol_strip.sh b/symbol_strip.sh
new file mode 100755
index 00000000..739fbcb3
--- /dev/null
+++ b/symbol_strip.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]
+then
+	echo "Export file name required."
+	exit 1
+fi
+expfile="$1"
+expbase=`basename $expfile`
+
+# Don't rerun this unless the file has been relinked
+if [ "${SYMROOT}/${expbase}.timestamp" -nt "${SYMROOT}/${INNER_PRODUCT_SUBPATH}" ]; then
+    echo "${SYMROOT}/${INNER_PRODUCT_SUBPATH} is up to date."
+    exit 0
+fi
+
+echo "Scanning ${SYMROOT}/${INNER_PRODUCT_SUBPATH}"
+ARCHS=`lipo -info "${SYMROOT}/${INNER_PRODUCT_SUBPATH}" | awk -F : '{print $3}'`
+for arch in $ARCHS
+do
+	echo "Generating exports file ${SYMROOT}/${expbase}_$arch"
+	nm -gp -arch $arch "${SYMROOT}/${INNER_PRODUCT_SUBPATH}" \
+	| egrep -v '^/| U _' \
+	| awk '{print $3}' \
+	| egrep '_(|tf|ti|C)(|Q[2-9])8Security|^_(Sec|CSSM|Authorization)' \
+	| cat - "$expfile" \
+	| sort -u > "${SYMROOT}/${expbase}_$arch"
+	echo nmedit -s "${SYMROOT}/${expbase}_$arch" -arch $arch "${SYMROOT}/${INNER_PRODUCT_SUBPATH}"
+	nmedit -s "${SYMROOT}/${expbase}_$arch" -arch $arch "${SYMROOT}/${INNER_PRODUCT_SUBPATH}"
+done
+touch "${SYMROOT}/${expbase}.timestamp"
-- 
2.50.0

